From 11790fc53221e1d95834b5807aa5c3f0831461ad Mon Sep 17 00:00:00 2001 From: Reinhard Tartler Date: Tue, 22 Aug 2017 21:37:27 -0400 Subject: Import aspectc++_2.2+git20170823-1.debian.tar.xz [dgit import tarball aspectc++ 1:2.2+git20170823-1 aspectc++_2.2+git20170823-1.debian.tar.xz] --- NEWS | 15 +++ README.Debian | 41 ++++++ ac++.1.sgml | 178 +++++++++++++++++++++++++ ag++.1.sgml | 177 +++++++++++++++++++++++++ aspectc++.install | 2 + aspectc++.manpages | 2 + aspectc++.postinst | 40 ++++++ aspectc++.postrm | 11 ++ changelog | 350 +++++++++++++++++++++++++++++++++++++++++++++++++ cleanup-source.sh | 30 +++++ compat | 1 + control | 50 +++++++ copyright | 146 +++++++++++++++++++++ dirs | 1 + get-orig-source.sh | 109 +++++++++++++++ libpuma-dev.install | 3 + patches/auto-gitignore | 16 +++ patches/series | 2 + rules | 147 +++++++++++++++++++++ source/format | 1 + watch | 3 + 21 files changed, 1325 insertions(+) create mode 100644 NEWS create mode 100644 README.Debian create mode 100644 ac++.1.sgml create mode 100644 ag++.1.sgml create mode 100644 aspectc++.install create mode 100644 aspectc++.manpages create mode 100644 aspectc++.postinst create mode 100644 aspectc++.postrm create mode 100644 changelog create mode 100755 cleanup-source.sh create mode 100644 compat create mode 100644 control create mode 100644 copyright create mode 100644 dirs create mode 100644 get-orig-source.sh create mode 100644 libpuma-dev.install create mode 100644 patches/auto-gitignore create mode 100644 patches/series create mode 100755 rules create mode 100644 source/format create mode 100644 watch diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..fddd8e0 --- /dev/null +++ b/NEWS @@ -0,0 +1,15 @@ +aspectc++ (0.99+1.0pre2-3) unstable; urgency=low + + The script 'update-puma.config' has been removed! + To update your /etc/puma.config, please use the command + 'dpkg-reconfigure aspectc++'. + + This step is necessary after each change of your compilers system + includes, so this means every major gcc update. This shouldn't happen + that often in a stable release, but if you are running unstable, this + will happen from time to time. + + If you know some what to automate this without bugging the gcc maintainers, + please tell me, but AFAIK triggers have not been implemented in dpkg yet. + + -- Reinhard Tartler Tue, 10 Jan 2006 14:07:11 +0100 diff --git a/README.Debian b/README.Debian new file mode 100644 index 0000000..0e2d50a --- /dev/null +++ b/README.Debian @@ -0,0 +1,41 @@ +PUMA_CONFIG environment Variable +-------------------------------- + +The ac++ requires the environment variable named PUMA_CONFIG set, or will fall +back to /etc/puma.config. Without a suitable puma.config file, ac++ will fail +with irritating error messages about not finding the right includes. The +Debian package uses ag++ to create an suitable puma.config in its postinst +script. This script has to be re-run each time a new GCC version is installed +using dpkg-reconfigure. Unfortunately, there is no mechanism to register hooks +after upgrading GCC, so this is up to the local system admin. After all this +would not happen quite often in a stable release, huh? ;) + + -- Reinhard Tartler , Mon, 27 Mar 2017 20:26:38 -0400 + +Woven vs. Unwoven Sources +------------------------- + +the orig.tar.gz has been downloaded from +http://www.aspectc.org/fileadmin/downloads/ac/1.0pre2/ac-woven-1.0pre2.tar.gz + +The unwoven sources require ac++ to build. The woven sources have do have +exact the same sources, but Puma has already been woven, so that it can be +built on the buildds. + +The shell wrappers ac++ and ag++ have been removed, because puma now uses +/etc/puma.config as default config file if no environment variable PUMA_CONFIG +is set. + + -- Reinhard Tartler Fri, 23 Dec 2005 10:18:20 +0100 + +aspectc++ for Debian +-------------------- + +AspectC++ development team shipped version 0.9.1 compiling static binaries. +This was changed in this Debian package, keeping static linkage only with +libPuma, which is an AspectC++ specific library, and doesn't need to be +distributed. + + -- Antonio S. de A. Terceiro , Sat, 12 Feb 2005 21:40:50 -0200 + + diff --git a/ac++.1.sgml b/ac++.1.sgml new file mode 100644 index 0000000..853d55e --- /dev/null +++ b/ac++.1.sgml @@ -0,0 +1,178 @@ + manpage.1'. You may view + the manual page with: `docbook-to-man manpage.sgml | nroff -man | + less'. A typical entry in a Makefile or Makefile.am is: + +manpage.1: manpage.sgml + docbook-to-man $< > $@ + + + The docbook-to-man binary is found in the docbook-to-man package. + Please remember that if you create the nroff version in one of the + debian/rules file targets (such as build), you will need to include + docbook-to-man in your Build-Depends control field. + + --> + + + Antonio"> + Terceiro"> + + 10 February 2005"> + + 1"> + asaterceiro@inf.ufrgs.br"> + + AspectC++"> + + + Debian"> + GNU"> + GPL"> +]> + + + +
+ &dhemail; +
+ + &dhfirstname; + &dhsurname; + + + 2005 + &dhusername; + + &dhdate; +
+ + &dhucpackage; + + &dhsection; + + + &dhpackage; + aspect weaver for C++ + + + + ac++ + -p srcidr -d destdir + + + ac++ + -c input -o outputr + + + + DESCRIPTION + + This manual page documents briefly the + ac++ command. + + + + ac++ is the AspectC++ weaver. ac++ + does source-to-source translation. This manual page documents the minimum + needed in order to use ac++. For a better reference, + see AspectC++ documentation. + + + The first syntax form above invokes ac++ in WPT + mode, while the second one invokes it in STU mode (see OPERATION MODES + below) + + + + + OPERATION MODES + + + WPT (whole program transformation) mode does the + translation of the entire source tree into another one. This is useful to + apply all the aspects of one source tree, generating other source tree + with the aspects woven into the sources. + + +To use WPT mode, run ac++ with the first syntax form +Specify the original source tree in the srcdir +argument, and a name for the destination source tree in the +destdir argument. + + + +STU (single translation unit) mode does the +translation of one translation unit, namely a C++ single file, for +exemple. This mode applies to the translation units all aspects that +affect it. + + +To use STU mode, run ac++ with the second syntax form. +Specify the translation unit in the input argument, +and the output file in the output argument. The + works as in g++: if omitted, +you're telling to ac++ to compile the source into an +executable; if present, source will be compiled into an object (.o) file. + + + + + OPTIONS + + + Further options can be seen in AspectC++ documentation. + + + + + SEE ALSO + + ag++ (1), g++ (1). + + + Again: for full reference on AspectC++ usage, see AspectC++ + documentation. It can be obtained from + http://www.aspectc.org + + + + + AUTHOR + + +This manual page was written by &dhusername; <&dhemail;> for the &debian; +system (but may be used by others). Permission is granted to copy, +distribute and/or modify this document under the terms of the &gnu; +General Public License, Version 2 any later version published by the Free +Software Foundation. + + + On Debian systems, the complete text of the GNU General Public + License can be found in /usr/share/common-licenses/GPL. + + + +
+ + + + diff --git a/ag++.1.sgml b/ag++.1.sgml new file mode 100644 index 0000000..b96df46 --- /dev/null +++ b/ag++.1.sgml @@ -0,0 +1,177 @@ + manpage.1'. You may view + the manual page with: `docbook-to-man manpage.sgml | nroff -man | + less'. A typical entry in a Makefile or Makefile.am is: + +manpage.1: manpage.sgml + docbook-to-man $< > $@ + + + The docbook-to-man binary is found in the docbook-to-man package. + Please remember that if you create the nroff version in one of the + debian/rules file targets (such as build), you will need to include + docbook-to-man in your Build-Depends control field. + + --> + + + Antonio"> + Terceiro"> + + 10 February 2005"> + + 1"> + asaterceiro@inf.ufrgs.br"> + + AspectC++"> + + + Debian"> + GNU"> + GPL"> +]> + + + +
+ &dhemail; +
+ + &dhfirstname; + &dhsurname; + + + 2005 + &dhusername; + + &dhdate; +
+ + &dhucpackage; + + &dhsection; + + + ag++ + a frontend to ac++ and g++ + + + + + ag++ + -o output input.cpp + + + ag++ + -c -o output.o -o input.cpp + + + + + + DESCRIPTION + + This manual page documents briefly the + ag++ command. + + + ag++ is a frontend to ac++ and g++ provided by + AspectC++. For a better (and more + complete) reference, see the AspectC++ documentation. + + + + ag++ + is called much like g++ itself. Check the two syntax forms above + and follow these explanations: + + + + The first syntax form takes input.cpp and generates + an executable named output, after weaving into + input.cpp all the aspects that crosscut it. + input.cpp has restrictions as it would have if we + were compiling a regular C++ program: it must have an + main() function, and everything you already know. + + + + The second syntax form takes input.cpp and generates + an object file named output.o, after weaving into + input.cpp all the aspects that crosscut it. + + + + Note: in both cases, input.cpp + isn't actually changed. g++ weaves to temporary files. + + + + Common g++ arguments, like + -I INDCIR, + -L LIBCIR, + -l libfoo, and so on, + are recognized by ag++ and rightly passed to + g++. + + + + + + OPTIONS + + + Further options can be seen in AspectC++ documentation. + + + + + SEE ALSO + + ag++ (1), g++ (1). + + + Again: for full reference on AspectC++ usage, see AspectC++ + documentation. It can be obtained from + http://www.aspectc.org + + + + + AUTHOR + + This manual page was written by &dhusername; <&dhemail;> for + the &debian; system (but may be used by others). Permission is + granted to copy, distribute and/or modify this document under + the terms of the &gnu; General Public License, Version 2 any + later version published by the Free Software Foundation. + + + On Debian systems, the complete text of the GNU General Public + License can be found in /usr/share/common-licenses/GPL. + + + +
+ + + + diff --git a/aspectc++.install b/aspectc++.install new file mode 100644 index 0000000..3e9718b --- /dev/null +++ b/aspectc++.install @@ -0,0 +1,2 @@ +AspectC++/bin/linux-release/ac++ usr/bin +Ag++/bin/linux-release/ag++ usr/bin diff --git a/aspectc++.manpages b/aspectc++.manpages new file mode 100644 index 0000000..2901a7b --- /dev/null +++ b/aspectc++.manpages @@ -0,0 +1,2 @@ +ac++.1 +ag++.1 diff --git a/aspectc++.postinst b/aspectc++.postinst new file mode 100644 index 0000000..92b3b37 --- /dev/null +++ b/aspectc++.postinst @@ -0,0 +1,40 @@ +#!/bin/sh -e + +# summary of how this script can be called: +# * `configure' +# * `abort-upgrade' +# * `abort-remove' `in-favour' +# +# * `abort-deconfigure' `in-favour' +# `removing' +# +# for details, see http://www.debian.org/doc/debian-policy/ or +# the debian-policy package +# + +PUMA_CONFIG=/etc/puma.config + +case "$1" in + configure) + echo generating ${PUMA_CONFIG} + (cd /etc; ag++ --gen_config) + chown root:root $PUMA_CONFIG + chmod 644 $PUMA_CONFIG + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 diff --git a/aspectc++.postrm b/aspectc++.postrm new file mode 100644 index 0000000..5b4e965 --- /dev/null +++ b/aspectc++.postrm @@ -0,0 +1,11 @@ +#!/bin/sh -e + +PUMA_CONFIG=/etc/puma.config + +if [ -e $PUMA_CONFIG ] +then + rm -f $PUMA_CONFIG +fi + +#DEBHELPER# +exit 0 diff --git a/changelog b/changelog new file mode 100644 index 0000000..dbc49fc --- /dev/null +++ b/changelog @@ -0,0 +1,350 @@ +aspectc++ (1:2.2+git20170823-1) unstable; urgency=medium + + * New upstream release + * Fixes compilation with gcc-7 (Closes: #853319) + + -- Reinhard Tartler Tue, 22 Aug 2017 21:37:27 -0400 + +aspectc++ (1:2.2-1) experimental; urgency=medium + + [ Reinhard Tartler ] + * Upload to debian/experimental + + [ Radovan Birdic ] + * Compile aspectc++ with -fPIC on mipsen (Closes: #845535) + + -- Reinhard Tartler Mon, 27 Mar 2017 20:31:11 -0400 + +aspectc++ (1:2.1-2) unstable; urgency=medium + + * Team upload (collab-maint) + * Add VCS browser and fix VCS fields + * Bump std-version to 3.9.8 + * Bump compat level to 9 + * Switch to llvm 3.8 (Closes: #836606) + + -- Gianfranco Costamagna Fri, 07 Oct 2016 10:50:23 +0200 + +aspectc++ (1:2.1-1) unstable; urgency=medium + + * Import Upstream version 2.1 + + -- Reinhard Tartler Sat, 20 Aug 2016 12:27:01 -0400 + +aspectc++ (1:2.0+svn20160531-2) unstable; urgency=medium + + * Compile with -O1 on armhf to avoid FTBFS on armhf + + -- Reinhard Tartler Fri, 17 Jun 2016 22:23:23 -0400 + +aspectc++ (1:2.0+svn20160531-1) unstable; urgency=medium + + * Imported Upstream version 2.0+svn20160531 + - Fixes FTBFS on ppc64el (Closes: #824033) + - Fixes FTBFS on arm64 (Closes: #802819) + + -- Reinhard Tartler Mon, 30 May 2016 18:16:12 -0400 + +aspectc++ (1:2.0+svn20160329-1) unstable; urgency=medium + + * Imported Upstream version 2.0+svn20160329 + + -- Reinhard Tartler Mon, 28 Mar 2016 23:26:18 -0400 + +aspectc++ (1:2.0-2) unstable; urgency=medium + + * Upload to unstable. + + -- Reinhard Tartler Fri, 04 Mar 2016 09:36:24 -0500 + +aspectc++ (1:2.0-1) experimental; urgency=medium + + * Imported Upstream version 2.0 + * Bump standard version, no changes needed + + -- Reinhard Tartler Sun, 28 Feb 2016 10:27:33 -0500 + +aspectc++ (1:1.2+svn20151025-1) unstable; urgency=medium + + * New upstream version + * Enable LLVM support, Closes: #754697 + + -- Reinhard Tartler Mon, 24 Aug 2015 20:42:29 -0400 + +aspectc++ (1:1.2+svn20150823-1) unstable; urgency=medium + + * New upstream snapshot + * Compiles with GCC-5, Closes: #777781 + * Bump standard version, no changes needed + * This package is now maintained on git.debian.org + + -- Reinhard Tartler Sun, 23 Aug 2015 22:04:29 -0400 + +aspectc++ (1:1.2-1) unstable; urgency=low + + * New upstream release. + * Workaround for building with g++-4.8 - aspectc++ supports __int128 by + default only when woven on 64bits, which the upstream provided sources + don't. closes: #701244 + + -- Reinhard Tartler Sun, 13 Oct 2013 16:12:00 -0400 + +aspectc++ (1:1.1+svn20120529-2) unstable; urgency=low + + * Install missing lexertl files in libpuma-dev Puma. + Thanks to Christoph Egger for reporting + Closes: #679583 + + -- Reinhard Tartler Sat, 30 Jun 2012 09:45:17 +0200 + +aspectc++ (1:1.1+svn20120529-1) unstable; urgency=low + + * New upstream snapshot. + - Fixes with fcntl handling on kFreeBSD + - Upstream fixes in the Puma Parser + + -- Reinhard Tartler Wed, 30 May 2012 10:01:33 +0200 + +aspectc++ (1:1.1+svn742-1) unstable; urgency=low + + * New upstream snapshot. + - fixes compilation with gcc 4.7 (Closes: #672013) + * disable parallelism inside debian/rules (but not submakes) + + -- Reinhard Tartler Tue, 22 May 2012 21:12:18 +0200 + +aspectc++ (1:1.1-1) unstable; urgency=low + + * New upstream release. + * Apply patches to fix FTBFS with recent gcc versions. Closes: #667103 + * Avoid empty directory usr/sbin (found by lintian) + * Bump Standards version to 3.9.3.1 (no changes needed) + * Avoid running doxygen on the buildds. + + -- Reinhard Tartler Wed, 11 Apr 2012 21:09:34 +0200 + +aspectc++ (1:1.0-4) unstable; urgency=low + + * debian/rules: Build doxygen in binary-arch target until buildds call the + build-arch target instead of build to avoid FTBFS. + + -- Reinhard Tartler Thu, 30 Jun 2011 21:11:23 +0200 + +aspectc++ (1:1.0-3) unstable; urgency=low + + * Don't compress examples files + * Install into correct paths + * add notes for linking against libPuma.a + * Don't install non-functional Makefiles in example directories + * Drop -no-rtti and from CFLAGS + * implement build-arch and build-indep target as suggested by debian policy + * Honor 'nocheck' flag in DEB_BUILD_OPTIONS + + -- Reinhard Tartler Thu, 30 Jun 2011 17:29:15 +0200 + +aspectc++ (1:1.0-2) unstable; urgency=low + + * apply patch from upstream to fix FTBFS on kFreeBSD + * simplify Vcs-Bzr field + + -- Reinhard Tartler Tue, 19 Apr 2011 21:59:07 +0200 + +aspectc++ (1:1.0-1) unstable; urgency=low + + * New upstream version + * don't ignore errors in maintainer scripts + * aspectc++.postinst: don't call ag++ with full path + * prefer dh_prep over dh_clean -k + * Add ${misc:Depends} dependencies + * support parallel builds + * bump standards version + * bump debhelper compat level to 7 + * install all Puma samples + * switch to source format 3.0 (quilt) + + -- Reinhard Tartler Mon, 18 Apr 2011 21:40:56 +0200 + +aspectc++ (1.0pre4~svn.20080711-1) unstable; urgency=low + + * new upstream snapshot. + * include all upstream documentation. Clarifying emails regarding + licensing has been included into debian/copyright. + * reformat description following recomendations of + http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Description + (Closes: #480316) + + -- Reinhard Tartler Mon, 07 Jul 2008 14:41:02 +0200 + +aspectc++ (1.0pre4~svn.20080409+dfsg-3) unstable; urgency=low + + * Fix another missing include, this time in Ag++/StdSystem.cc + + -- Reinhard Tartler Thu, 10 Apr 2008 17:40:52 +0200 + +aspectc++ (1.0pre4~svn.20080409+dfsg-2) unstable; urgency=low + + * After another round of reviewing Bens diff, the NMU was correct after + all. Incorporating the Ppatch from + http://bugs.debian.org/cgi-bin/bugreport.cgi?msg=23;bug=417489 + Really Closes: #417489 this time. + * reweave Puma with changes from previous change. + * More cleanups in the Puma buildscripts: debian/rules honors now noopt in + the variable DEB_BUILD_OPTIONS. + * add Vcs-Bzr headers to debian/control. + + -- Reinhard Tartler Thu, 10 Apr 2008 13:37:36 +0200 + +aspectc++ (1.0pre4~svn.20080409+dfsg-1) unstable; urgency=low + + * new upstream snapshot + - now builds properly with GCC 4.3 (Closes: #417489, #424106) + - uses bash in the ag++ testsuite (Closes: #373665) + - explicitly not ACKing NMU from Ben Hutchings. Upstream has fixed + the issues with GCC 4.3 independently + - Now shipping prewoven puma sources directly in the orig.tar.gz (again) + - remove unlicensed documentation. + * bumbed standards version + * use CURDIR instead of PWD, thanks lintian + * updated maintainer record + * add script and target for retrieving a clean upstream tarball + * Incorporating and Acking NMU from Sandro Tosi. (Closes: #424106) + * compile ac++ twice: one time with prewoven Puma, then reweave a copy + of Puma, then build a new ac++ with the freshly woven Puma. This + ensures that ac++ is actually able to compile itself (Closes: #474560) + * ensure that the AspectC++ testsuite is using /bin/bash (Closes: #373665) + * compile with -O2 instead of -O3. -O2 is likely to cause problems on + non-mainstream architectures. Plus, add '-g' to compilation flags, so + that a build with DEB_BUILD_OPTIONS='noopt' actually creates a package + with debugging information. + * add dependency on gsfonts for having proper fonts in the doxygen + outputs. + * Bump Standard version to 3.7.3 (no changes needed). + * Use Homepage Field. + * Move packages into correct sections: libpuma-doc -> doc, + libpuma-dev -> libdevel. + * simplify debian/rules a bit. + * install (woven) Puma development headers into libpuma-dev. + + -- Reinhard Tartler Thu, 10 Apr 2008 09:23:51 +0200 + +aspectc++ (0.99+1.0pre3-3.1) unstable; urgency=low + + * Non-maintainer upload + + [ Sandro Tosi ] + * debian/rules + - added removal of binary not cleaned (Closes: #424106) + + [ Ben Hutchings ] + * Fixed recursive make invocations to avoid hiding failures + * Added/changed #include and using directives for g++ 4.3 + (Closes: #417489) (partly by Martin Michlmayr) + * Added missing parentheses in Puma::FilenameInfo::name() + + -- Ben Hutchings Sun, 06 Apr 2008 01:15:28 +0100 + +aspectc++ (0.99+1.0pre3-3) experimental; urgency=low + + * more cleanups in Puma/Makefile + * removed Antonio from uploaders on his request. Thank you for your work! + * bumped standards version to 3.7.2 (no changes needed) + * Introduce new package: libpuma-dev, for direct use of the + puma library (Closes: #369771) + * Introduce new package: libpuma-doc, with updated doxygen.conf + containing 2 examples (ccparser and cparser) and doxygen generated docs + * Added circular build-depend on itself, testing if the ac++ binary is + working on all architectures! + * Merge patches from upstream for ag++, fixing command line handling and + fixes in the testsuite. + + -- Reinhard Tartler Mon, 12 Jun 2006 10:53:28 +0200 + +aspectc++ (0.99+1.0pre3-2ubuntu2) gutsy; urgency=low + + * Rebuild to deal with launchpad looping. + + -- LaMont Jones Thu, 11 Oct 2007 21:28:50 -0600 + +aspectc++ (0.99+1.0pre3-2ubuntu1) feisty; urgency=low + + * Rebuild for ldbl128 change (powerpc, sparc). + * Set Ubuntu maintainer address. + + -- Matthias Klose Thu, 1 Mar 2007 22:30:19 +0000 + +aspectc++ (0.99+1.0pre3-2) unstable; urgency=low + + * Fix some more cleanup() functions, which can go frenzy on at least amd64 + (applied upstread) + * Fix description, thanks to Simon Waters (Closes: #362738) + * reweave Puma to make the patch enabling the build with gcc-4.1 actually + active (Closes: #357901, this time for real) + + -- Reinhard Tartler Sat, 3 Jun 2006 13:14:38 +0200 + +aspectc++ (0.99+1.0pre3-1) unstable; urgency=low + + * new upstream release + * Apply patch from Martin Michlmayr for g++-4.1 (Closes: #357901) + * further (simple) patches in Puma/ and AspectC++ for g++-4.1 + * note that Puma needs to be rewoven so that it can be compiled + with g++-4.1. This will be done we switch the default compiler + version. + * Patch JoinPointRepo.cc so that it doesn't loop endlessly anymore. + + -- Reinhard Tartler Fri, 7 Apr 2006 11:56:35 +0200 + +aspectc++ (0.99+1.0pre2-4) unstable; urgency=low + + * Make clean target less noisy + * Compile with -O2. This fixes many segfaults on different archs + (Closes: #349090) + * fix Puma/tools/Makefile to make tools-clean possible at all! + * do not clean examples, that's broken anyway + * some compile fixes for segfaults on 64 mode architectures. + I had to reweave Puma for these fixes, thats the reason for the + bloat in .diff.gz (Closes: #345568) + * The tests for ag++ need a working ac++ in PATH. ensure this in + debian/rules + * Install the examples from AspectC++/examples + + -- Reinhard Tartler Sun, 29 Jan 2006 18:38:54 +0100 + +aspectc++ (0.99+1.0pre2-3) unstable; urgency=low + + * polish debian/copyright + * set PUMA_CONFIG in debian/rules for running the testsuite + * take some Makefiles from upstream CVS for "optimized" linking + (suggestion as per suggestion from from upstream) + * remove the script update-puma.config. Use dpkg-reconfigure to regenerate + the puma.config file + + -- Reinhard Tartler Tue, 10 Jan 2006 14:09:14 +0100 + +aspectc++ (0.99+1.0pre2-2) unstable; urgency=low + + * Don't build shared Puma at all, we link to it statically after all, and no + shared lib is exposed anyway, since Puma is way too unstable and no other + application is using Puma at the moment. (Closes: #345542) + * Fix wrong cast in a debug function. This is quite hackish, and Puma on 64 + bit archs is experimental anyway. I'm working with upstream for real 64bit + support (Closes: #345541) + + -- Reinhard Tartler Sun, 1 Jan 2006 22:11:45 +0100 + +aspectc++ (0.99+1.0pre2-1) unstable; urgency=low + + * New upstream release. (Closes: #277538) + + -- Reinhard Tartler Fri, 23 Dec 2005 10:49:40 +0100 + +aspectc++ (0.99+1.0pre1-1) unstable; urgency=low + + * installed ac++ and ag++ shellskript wrappers + for setting PUMA_CONFIG + * introduced update-puma.config shellscript to regenerate + /etc/puma.config + * move aspectc++ binaries to /usr/lib/aspectc++ + + -- Reinhard Tartler Wed, 21 Dec 2005 11:52:30 +0100 + diff --git a/cleanup-source.sh b/cleanup-source.sh new file mode 100755 index 0000000..6286ae5 --- /dev/null +++ b/cleanup-source.sh @@ -0,0 +1,30 @@ +#!/bin/sh +# +# Script to prepare the aspectc++ package for distribution. +# Copyright (C) 2008, Reinhard Tartler +# +# 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., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# this script essentially does 2 things: +# - weave Puma (so that aspectc++ is not necessary for building) +# - strip of unlicensed material, mainly documentation + +set -e + +# executed in the root directory of the unapacked aspectc++ source tree + +# weave Puma, requires installed package aspectc++ +make -C Puma weave +make -C Puma tools-clean docs-clean examples-clean libclean diff --git a/compat b/compat new file mode 100644 index 0000000..ec63514 --- /dev/null +++ b/compat @@ -0,0 +1 @@ +9 diff --git a/control b/control new file mode 100644 index 0000000..f068b60 --- /dev/null +++ b/control @@ -0,0 +1,50 @@ +Source: aspectc++ +Section: devel +Priority: optional +Maintainer: Reinhard Tartler +Build-Depends: debhelper (>= 9), libxml2-dev, docbook-to-man, zlib1g-dev, libedit-dev, llvm-4.0-dev, libclang-4.0-dev +Build-Depends-Indep: doxygen, graphviz, gsfonts +Standards-Version: 4.0.0 +Homepage: http://www.aspectc.org +Vcs-Git: https://anonscm.debian.org/git/collab-maint/aspectc++.git +Vcs-Browser: https://anonscm.debian.org/cgit/collab-maint/aspectc++.git + +Package: aspectc++ +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, g++ +Description: aspect-oriented programming extension for C++ + AspectC++ supports Aspect-Oriented Programming with C++, by providing: + . + - an aspect language extension to C++. + - an aspect weaver that does source-to-source translation. + . + AspectC++ provides for C++ similar features like its best known + cousin, AspectJ, provides for Java. + +Package: libpuma-dev +Architecture: any +Section: libdevel +Depends: ${misc:Depends} +Suggests: libpuma-doc +Description: C/C++/AspectC++ Scanner and Parsers + libPuma is a library written in C++ for Scanning and Parsing C++ + Code. It also does some semantic analysis. + . + It was written to facilitate the development for tools, which manipulate + and/or transfor C/C++ Code. + . + This package ships a static copy of libPuma only. + +Package: libpuma-doc +Architecture: all +Section: doc +Depends: ${misc:Depends} +Description: C/C++/AspectC++ Scanner and Parsers + libPuma is a library written in C++ for Scanning and Parsing C++ + Code. It also does some semantic analysis. + . + It was written to facilitate the development for tools, which manipulate + and/or transfor C/C++ Code. + . + This package ships doxygen generated documentation for Puma. + diff --git a/copyright b/copyright new file mode 100644 index 0000000..2397507 --- /dev/null +++ b/copyright @@ -0,0 +1,146 @@ +This package was debianized by Antonio S. de A. Terceiro on +Sat, 20 Nov 2004 00:50:57 -0200. + +It was downloaded from http://www.aspectc.org + +Upstream Authors: Olaf Spinczyk, Matthias Urban, Georg Blaschke, +Contact through + +License: + +Copyright for Puma library: + Copyright (C) 1999-2011 The PUMA developer team. +Copyright for AspectC++: + Copyright (C) 2001-2011 The AspectC++ developer team. + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Both the Puma library and AspectC++ are licensed under GNU GPL, which in + Debian systems can be found at: + + /usr/share/common-licenses/GPL-2 + +The documentation is also released under GPL. This has been discussed on +the aspectc++ developers mailing list. The relevant mails are included +here for reference: + +From: Matthias Urban +Subject: Re: [Aspectc-developers] Dokumentation in Puma/AspectC++/Ag++ +To: Aspectc Developers Mailing List +Date: Sun, 20 Apr 2008 14:49:34 +0200 +Organization: pure-systems GmbH + +Hallo, + +> Kurz: Einerseits webe ich Puma vor, andererseits muss ich die meiste +> Dokumentation aus dem Paket werfen, weil keine aussagekräftigen +> Nutzungsbedingungen dabei stehen. Das finde ich sehr schade. Ich weiss +> dass ueber die Lizenz Dokumentation schon laenger nachgedacht wird, +> daher an dieser Stelle nochmal die freundlich/nervige Nachfrage: Gibts +> hier schon was neues? Welche Teile der Dokumentation entferne ich in dem +> o.g. script zu Unrecht? Habe ich evtl. etwas vergessen? + +Also meiner Meinung nach fällt die Doku ebenso unter die GPL wie die +Sourcen. Zumindestens was die Puma-Doku betrifft, sollte das so sein +(werde ich aber nochmal mit Danilo besprechen). Wo muss denn da ein +entsprechender Lizenzvermerk hin? Im Puma User's Manual gibt es schon +einen License-Abschnitt, wo steht, dass Puma unter der GPL steht (das +gleiche gibt es auf der Main Page des doxygen-generierten HTML Reference +Manuals). Muss da noch explizit erwähnt werden, dass das auch die +Dokumentation umfasst? Dieser ganze Lizenzkram ist wirklich lästig. + +Übrigens heisst das Puma-Doku Makefile Target jetzt doc anstatt +doxygen. Und die generierte Klassendoku steckt jetzt im Unterverzeichnis +Puma/doc/RefMan anstatt Puma/doc/doxygen. Nur so als Info für den Fall, +dass Du auch die Klassendoku generierst. + +_______________________________________________ +aspectc-developers mailing list +aspectc-developers@aspectc.com +https://aspectc.com/mailman/listinfo/aspectc-developers + + +From: Olaf Spinczyk +Subject: Re: [Aspectc-developers] Dokumentation in Puma/AspectC++/Ag++ +To: Aspectc Developers Mailing List +Date: Mon, 21 Apr 2008 10:24:57 +0200 + +Hi, + +von meiner Seite aus wäre GPL für die Doku auch OK. Dann bräuchten wir +noch eine Aussage von pure-systems, von Georg und jemanden, der das +überall an der richtigen Stelle einsetzt ... + +- Olaf + +From: Matthias Urban +Subject: Re: [Aspectc-developers] Dokumentation in Puma/AspectC++/Ag++ +To: Aspectc Developers Mailing List +Date: Mon, 05 May 2008 14:59:00 +0200 +Organization: pure-systems GmbH + +Hallo, + +[...] + +Laut Danilo erhebt pure-systems keine Rechte an der Doku, GPL wäre also +auch für pure-systems OK. + +[...] + + +From: +Subject: RE: [Aspectc-developers] Dokumentation in Puma/AspectC++/Ag++ +To: +Cc: +Date: Mon, 7 Jul 2008 14:08:12 +0200 + +Hi Reinhard, + +> Es geht gerade um die Frage nach der Lizenz des ag++ manuals. +> Bist du mit GPL fuer das Manual einverstanden? Das Dokument +> hat derzeit gar kein copyright vermerkt, so dass die Lizenz +> nicht ganz klar ist. + +Aus meiner Sicht ist die Doku für ag++ auch in Ordnung, solange +Olaf das auch gut findet. + + +Copyright for Puma/extern/lexertl: + Copyright: 2005-2011 Ben Hanson (http://www.benhanson.net/)] +License: + Boost Software License - Version 1.0 - August 17th, 2003 + + Permission is hereby granted, free of charge, to any person or organization + obtaining a copy of the software and accompanying documentation covered by + this license (the "Software") to use, reproduce, display, distribute, + execute, and transmit the Software, and to prepare derivative works of the + Software, and to permit third-parties to whom the Software is furnished to + do so, all subject to the following: + + The copyright notices in the Software and this entire statement, including + the above license grant, this restriction and the following disclaimer, + must be included in all copies of the Software, in whole or in part, and + all derivative works of the Software, unless such copies or derivative + works are solely in the form of machine-executable object code generated by + a source language processor. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. diff --git a/dirs b/dirs new file mode 100644 index 0000000..e772481 --- /dev/null +++ b/dirs @@ -0,0 +1 @@ +usr/bin diff --git a/get-orig-source.sh b/get-orig-source.sh new file mode 100644 index 0000000..9e4ae01 --- /dev/null +++ b/get-orig-source.sh @@ -0,0 +1,109 @@ +#!/bin/sh +# +# Script to create a 'pristine' tarball for the aspectc++ source package. +# based on a similar script for the debian ffmpeg source package. +# Copyright (C) 2008, Reinhard Tartler +# +# 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., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +set -eu + +usage() { + cat >&2 < + -h : display help + -r : svn revision + -c : path to cleanup script + -o : output tarball name + -d : date in svn compatible format (e.g. 20071224) +EOF +} + +debug () { + $DEBUG && echo "DEBUG: $*" >&2 +} + +error () { + echo "$1" >&2 + exit 1; +} + +set +e +PARAMS=`getopt hr:c:o:d: "$@"` +if test $? -ne 0; then usage; exit 1; fi; +set -e + +eval set -- "$PARAMS" + +DEBUG=false +REVISION= +CLEANUPSCRIPT= +TARBALL= +SVNDATE= + +while test $# -gt 0 +do + case $1 in + -h) usage; exit 1 ;; + -r) REVISION=$2; shift ;; + -c) CLEANUPSCRIPT=$2; shift ;; + -o) TARBALL=$2; shift ;; + -d) SVNDATE=$2; shift ;; + --) shift ; break ;; + *) echo "Internal error!" ; exit 1 ;; + esac + shift +done + +# dammit 'basic' regular expressions :/ +if [ `expr match $SVNDATE '[0-9][0-9]*$'` -eq 0 ]; then + error "svndate $SVNDATE is not a plain revision number" +fi + +REVISION="{${SVNDATE}}" +BASEDIRNAME="aspectc++.svn${SVNDATE}" +SVNURL="https://svn.aspectc.org/repos/AspectC++-Project/trunk" + +if [ -z $TARBALL ]; then + error "you need to specify a tarballname" +fi + +if [ -n $CLEANUPSCRIPT ] && [ -f $CLEANUPSCRIPT ]; then + if [ ! -x $CLEANUPSCRIPT ]; then + error "$CLEANUPSCRIPT must be executable" + fi +fi + +TMPDIR=`mktemp -d` +trap 'rm -rf ${TMPDIR}' EXIT + +svn export -r${REVISION} --ignore-externals \ + $SVNURL \ + ${TMPDIR}/${BASEDIRNAME} + +# get svn externals +svn pg svn:externals $SVNURL | \ +while read external url; do + [ -z $url ] && continue + dest="${TMPDIR}/${BASEDIRNAME}/${external}" + svn export -r${REVISION} --ignore-externals $url $dest +done + +if [ -n ${CLEANUPSCRIPT} ]; then + ( cd ${TMPDIR}/${BASEDIRNAME} && ${CLEANUPSCRIPT} ) +fi + +tar czf ${TARBALL} -C ${TMPDIR} ${BASEDIRNAME} + diff --git a/libpuma-dev.install b/libpuma-dev.install new file mode 100644 index 0000000..07afc84 --- /dev/null +++ b/libpuma-dev.install @@ -0,0 +1,3 @@ +Puma/lib/linux-release/libPuma.a usr/lib +Puma/include/* usr/include +Puma/extern/lexertl/* usr/include/lexertl diff --git a/patches/auto-gitignore b/patches/auto-gitignore new file mode 100644 index 0000000..3ea65f9 --- /dev/null +++ b/patches/auto-gitignore @@ -0,0 +1,16 @@ +Subject: Update .gitignore from Debian packaging branch + +The Debian packaging git branch contains these updates to the upstream +.gitignore file(s). This patch is autogenerated, to provide these +updates to users of the official Debian archive view of the package. + +[dgit (3.11~deb9u1) update-gitignore] +--- +diff --git a/.gitignore b/.gitignore +new file mode 100644 +index 0000000..39200f4 +--- /dev/null ++++ b/.gitignore +@@ -0,0 +1,2 @@ ++.pc ++Puma/lib diff --git a/patches/series b/patches/series new file mode 100644 index 0000000..a22980a --- /dev/null +++ b/patches/series @@ -0,0 +1,2 @@ + +auto-gitignore diff --git a/rules b/rules new file mode 100755 index 0000000..50a6b10 --- /dev/null +++ b/rules @@ -0,0 +1,147 @@ +#!/usr/bin/make -f + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +# disable parallelism inside this makefile (but not submakes) +.NOTPARALLEL: + +# Support multiple makes at once +ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) +NUMJOBS := $(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) +else +NUMJOBS := 1 +# on i386 and amd64, we query the system unless overriden by DEB_BUILD_OPTIONS +ifeq ($(DEB_HOST_ARCH),i386) +NUMJOBS := $(shell getconf _NPROCESSORS_ONLN 2>/dev/null || echo 1) +else ifeq ($(DEB_HOST_ARCH),amd64) +NUMJOBS := $(shell getconf _NPROCESSORS_ONLN 2>/dev/null || echo 1) +endif +endif + +# workaround for bug #701244 - aspectc++ supports __int128 by default +# only when woven on 64bits, which the upstream provided sources don't. +AC_OPTFLAGS = --gnu-int128 +export AC_OPTFLAGS + +# we seem to have locking issues on kFreeBSD. force single threaded +ifeq ($(DEB_HOST_ARCH_OS),kfreebsd) +NUMJOBS := 1 +endif + +ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) + CFLAGS := -O0 -g +else + CFLAGS := -O2 -g +endif + +ifeq ($(DEB_HOST_ARCH),armhf) +# fatal: Caught standard exception: deque::_M_new_elements_at_back + CFLAGS := -O1 -g +endif + +DEB_BUILD_ARCH ?= $(shell dpkg-architecture -qDEB_BUILD_ARCH) +ifneq (,$(filter $(DEB_BUILD_ARCH),mips mipsel)) + CFLAGS += -fPIC +endif + +export CFLAGS +PUMA_CONFIG=$(CURDIR)/puma.config + +test-builds: build-arch-stamp + Ag++/bin/linux-release/ag++ --gen_config +ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS))) + -$(MAKE) -C AspectC++ PUMA_CONFIG=$(PUMA_CONFIG) FRONTEND=Clang LLVMCONF=/usr/bin/llvm-config-4.0 SHARED=1 AC="$(CURDIR)/AspectC++/bin/linux-release/ac++" REGRESSIONTEST=1 examples test + PATH=$(CURDIR)/AspectC++/bin/linux-release:$(PATH) \ + $(MAKE) -C Ag++/ SHARED=1 PUMA_CONFIG=$(PUMA_CONFIG) test + +endif + +build: build-arch build-indep + +build-arch: build-arch-stamp test-builds +build-arch-stamp: + dh_testdir + $(MAKE) -C Puma/ MINI=1 -j$(NUMJOBS) all + $(MAKE) -C AspectC++/ SHARED=1 -j$(NUMJOBS) all FRONTEND=Clang LLVMCONF=/usr/bin/llvm-config-4.0 + $(MAKE) -C Ag++/ SHARED=1 -j$(NUMJOBS) all + # ok, now we have both an ac++ binary and ag++ binary now let's + # weave Puma again in the copy + $(MAKE) -C Puma clean + $(MAKE) -C Puma all AC="$(CURDIR)/AspectC++/bin/linux-release/ac++" -j$(NUMJOBS) EXTENSIONS="acppext gnuext winext" + # build manpages: + docbook-to-man debian/ac++.1.sgml > ac++.1 + docbook-to-man debian/ag++.1.sgml > ag++.1 + # mark timestamp + touch $@ + +build-indep: build-indep-stamp +build-indep-stamp: + dh_testdir + $(MAKE) -C Puma doc + touch $@ + +clean: + dh_testdir + dh_testroot + dh_clean build-*stamp binary-*stamp puma.config + # cleaning up source directories: + $(MAKE) -s -C Puma cleanall + # The clang frontend adds additional tests that need cleaning + # so far, no tests are excluded by using the Clang frontend + $(MAKE) -s -C AspectC++ cleanall FRONTEND=Clang LLVMCONF=/usr/bin/llvm-config-4.0 + $(MAKE) -s -C Ag++ clean + # remove leftovers from Upstream Makefiles + rm -rf Puma/include + rm -rf AspectC++/tests/RepoVersion/repo.use + rm -rf Ag++/DepFiles Ag++/ObjFiles Ag++/bin Ag++/tests/test_11.config + rm -rf AspectC++/DepFiles AspectC++/ObjFiles AspectC++/bin + rm -rf AspectC++/tests/*/feature.out + rm -rf AspectC++/tests/RepoVersion/feature.fil + # remove generated manpages: + rm -f ac++.1 ag++.1 + rm -rf AspectC++/bin + rm -rf Puma.copy/ + # standard cleaning: + dh_clean + +# Build architecture-independent files here. +binary-indep: build-indep + dh_testdir + dh_testroot + dh_prep + dh_installchangelogs + dh_installdocs -p libpuma-doc Puma/doc/RefMan/html + dh_installexamples -p libpuma-doc Puma/examples/* + dh_compress -X.cc -X.map + dh_fixperms + dh_installdeb -i + dh_gencontrol -i + dh_md5sums -i + dh_builddeb -i + +# Build architecture-dependent files here. +binary-arch: build-arch + dh_testdir + dh_testroot + dh_prep + dh_installdirs + dh_installchangelogs + dh_installdocs + dh_install -Xlicence_1_0.txt + dh_installexamples -p aspectc++ AspectC++/examples/* + find debian/aspectc++ -name Makefile -exec rm -v {} + + find debian/libpuma-doc -name Makefile -exec rm -v {} + + dh_installman + dh_link + dh_strip + dh_compress + dh_fixperms + dh_installdeb -a + dh_shlibdeps -a + dh_gencontrol -a + dh_md5sums -a + dh_builddeb -a + +binary: binary-indep binary-arch +.PHONY: build build-indep build-arch clean binary-indep binary-arch binary diff --git a/source/format b/source/format new file mode 100644 index 0000000..163aaf8 --- /dev/null +++ b/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/watch b/watch new file mode 100644 index 0000000..b7a727c --- /dev/null +++ b/watch @@ -0,0 +1,3 @@ +version=3 +opts=pasv,uversionmangle=s/^ac-woven/aspectc++-/ \ + ftp://akut.aspectc.org/releases/1.1/ac-woven-([\d\.]+)\.tar\.gz -- cgit v1.2.3 From 0466fe524287d81d8958b2cb09d1cfc3dced9a76 Mon Sep 17 00:00:00 2001 From: Reinhard Tartler Date: Tue, 22 Aug 2017 21:37:27 -0400 Subject: Import aspectc++_2.2+git20170823.orig.tar.bz2 [dgit import orig aspectc++_2.2+git20170823.orig.tar.bz2] --- Ag++/.cproject | 90 + Ag++/.project | 79 + Ag++/ACCompiler.cc | 127 + Ag++/ACCompiler.h | 39 + Ag++/AGxxConfig.cc | 690 + Ag++/AGxxConfig.h | 366 + Ag++/CCompiler.cc | 163 + Ag++/CCompiler.h | 46 + Ag++/Compiler.h | 47 + Ag++/Makefile | 173 + Ag++/OptionVec.cc | 82 + Ag++/OptionVec.h | 127 + Ag++/PumaConfigFile.cc | 358 + Ag++/PumaConfigFile.h | 79 + Ag++/RegExCont.cc | 56 + Ag++/RegExCont.h | 59 + Ag++/StdSystem.cc | 137 + Ag++/StdSystem.h | 84 + Ag++/System.cc | 58 + Ag++/System.h | 56 + Ag++/TODO.txt | 2 + Ag++/ag++.cc | 149 + Ag++/doc/Ag++Manual/Ag++Manual.lyx | 1971 + Ag++/doc/Ag++Manual/Ag++Manual.pdf | Bin 0 -> 95333 bytes Ag++/doc/images/ac++logo.eps | 3928 ++ Ag++/doc/images/ac++logo.pdf | Bin 0 -> 4730 bytes Ag++/doc/styles/acc.sty | 110 + Ag++/file.cc | 125 + Ag++/file.h | 42 + Ag++/gpl.txt | 19 + Ag++/regex.cc | 67 + Ag++/regex.h | 30 + Ag++/tests/additional_aspects/trace2.ah | 12 + Ag++/tests/additional_includes/test_include.h | 7 + Ag++/tests/run_tests.sh | 105 + Ag++/tests/src/Makefile | 22 + Ag++/tests/src/Test.cc | 18 + Ag++/tests/src/Test.h | 14 + Ag++/tests/src/main.cc | 8 + Ag++/tests/src/trace.ah | 12 + Ag++/tests/test_01 | 14 + Ag++/tests/test_02 | 32 + Ag++/tests/test_03 | 38 + Ag++/tests/test_04 | 20 + Ag++/tests/test_05 | 32 + Ag++/tests/test_06 | 14 + Ag++/tests/test_07 | 20 + Ag++/tests/test_08 | 30 + Ag++/tests/test_09 | 32 + Ag++/tests/test_09.ref | 3 + Ag++/tests/test_10 | 29 + Ag++/tests/test_10.in | 3 + Ag++/tests/test_10.ref | 7 + Ag++/tests/test_11 | 70 + Ag++/tests/test_12 | 20 + Ag++/tests/test_13 | 18 + Ag++/tests/test_14 | 19 + Ag++/tests/test_15 | 24 + Ag++/tests/test_16 | 39 + Ag++/tests/test_17 | 17 + Ag++/tests/test_18 | 40 + Ag++/version.h | 3 + Ag++/win-ac++.ico | Bin 0 -> 13094 bytes Ag++/win-ag++.rc | 41 + AspectC++/.cproject | 139 + AspectC++/.project | 122 + .../org.eclipse.ltk.core.refactoring.prefs | 2 + .../.settings/org.eclipse.wst.validation.prefs | 6 + AspectC++/ACConfig.cc | 480 + AspectC++/ACConfig.h | 147 + AspectC++/ACErrorStream.h | 36 + AspectC++/ACFileID.h | 57 + AspectC++/ACIntroducer.h | 36 + AspectC++/ACModel/Elements.cc | 3635 ++ AspectC++/ACModel/Elements.h | 1787 + AspectC++/ACModel/Makefile | 85 + AspectC++/ACModel/MatchExpr.cc | 1199 + AspectC++/ACModel/MatchExpr.h | 240 + AspectC++/ACModel/MatchName.cc | 320 + AspectC++/ACModel/MatchName.h | 183 + AspectC++/ACModel/MatchTemplateArg.cc | 57 + AspectC++/ACModel/MatchTemplateArg.h | 163 + AspectC++/ACModel/MatchType.cc | 78 + AspectC++/ACModel/MatchType.h | 220 + AspectC++/ACModel/MatchTypeInfos.cc | 710 + AspectC++/ACModel/MatchTypeInfos.h | 419 + AspectC++/ACModel/ModelNode.h | 309 + AspectC++/ACModel/Utils.cc | 674 + AspectC++/ACModel/Utils.h | 109 + AspectC++/ACModel/XmlModelReader.cc | 979 + AspectC++/ACModel/XmlModelReader.h | 90 + AspectC++/ACModel/XmlModelWriter.h | 52 + AspectC++/ACPreprocessor.h | 36 + AspectC++/ACProject.cc | 684 + AspectC++/ACProject.h | 122 + AspectC++/ACResultBuffer.h | 36 + AspectC++/ACToken.h | 36 + AspectC++/ACUnit.h | 30 + AspectC++/AdviceInfo.cc | 285 + AspectC++/AdviceInfo.h | 68 + AspectC++/AdviceRepo.cc | 91 + AspectC++/AdviceRepo.h | 59 + AspectC++/AspectIncludeCluster.h | 37 + AspectC++/AspectIncludes.cc | 108 + AspectC++/AspectIncludes.h | 93 + AspectC++/AspectInfo.cc | 74 + AspectC++/AspectInfo.h | 61 + AspectC++/AspectRepo.cc | 86 + AspectC++/AspectRepo.h | 58 + AspectC++/BackEndProblems.h | 34 + AspectC++/Binding.cc | 57 + AspectC++/Binding.h | 45 + AspectC++/CFlow.cc | 48 + AspectC++/CFlow.h | 48 + AspectC++/ClangASTConsumer.cc | 1361 + AspectC++/ClangASTConsumer.h | 530 + AspectC++/ClangAdjustedTypePrinter.cc | 2362 + AspectC++/ClangAdjustedTypePrinter.h | 181 + AspectC++/ClangAnnotation.cc | 42 + AspectC++/ClangAnnotation.h | 39 + AspectC++/ClangBinding.cc | 210 + AspectC++/ClangBinding.h | 135 + AspectC++/ClangErrorStream.h | 96 + AspectC++/ClangFlowAnalysis.cc | 920 + AspectC++/ClangFlowAnalysis.h | 62 + AspectC++/ClangIncludeExpander.cc | 76 + AspectC++/ClangIncludeExpander.h | 43 + AspectC++/ClangInclusionRewriter.cc | 634 + AspectC++/ClangInclusionRewriter.h | 44 + AspectC++/ClangIntroParser.cc | 139 + AspectC++/ClangIntroParser.h | 23 + AspectC++/ClangIntroSema.cc | 344 + AspectC++/ClangIntroSema.h | 107 + AspectC++/ClangIntroducer.cc | 1318 + AspectC++/ClangIntroducer.h | 194 + AspectC++/ClangModelBuilder.cc | 1609 + AspectC++/ClangModelBuilder.h | 277 + AspectC++/ClangPreprocessor.cc | 151 + AspectC++/ClangPreprocessor.h | 74 + AspectC++/ClangResultBuffer.cc | 157 + AspectC++/ClangResultBuffer.h | 78 + AspectC++/ClangSyntacticContext.cc | 69 + AspectC++/ClangSyntacticContext.h | 223 + AspectC++/ClangToken.h | 129 + AspectC++/ClangTransformInfo.h | 2479 ++ AspectC++/ClangWeaverBase.cc | 680 + AspectC++/ClangWeaverBase.h | 160 + AspectC++/CodeWeaver.cc | 3689 ++ AspectC++/CodeWeaver.h | 227 + AspectC++/Condition.cc | 135 + AspectC++/Condition.h | 279 + AspectC++/FileRepo.cc | 117 + AspectC++/FileRepo.h | 63 + AspectC++/IncludeExpander.h | 36 + AspectC++/IncludeGraph.cc | 217 + AspectC++/IncludeGraph.h | 134 + AspectC++/IntroductionInfo.h | 40 + AspectC++/IntroductionUnit.h | 175 + AspectC++/JoinPoint.cc | 34 + AspectC++/JoinPoint.h | 49 + AspectC++/JoinPointModelElement.h | 1 + AspectC++/JoinPointRepo.cc | 136 + AspectC++/JoinPointRepo.h | 66 + AspectC++/LineDirectiveMgr.cc | 113 + AspectC++/LineDirectiveMgr.h | 56 + AspectC++/Makefile | 275 + AspectC++/ModelBuilder.h | 224 + AspectC++/NamespaceAC.cc | 266 + AspectC++/NamespaceAC.h | 29 + AspectC++/Naming.cc | 400 + AspectC++/Naming.h | 78 + AspectC++/OrderInfo.h | 67 + AspectC++/OrderPlanner.h | 119 + AspectC++/Phase1.cc | 2058 + AspectC++/Phase1.h | 217 + AspectC++/Plan.cc | 526 + AspectC++/Plan.h | 148 + AspectC++/PointCut.cc | 67 + AspectC++/PointCut.h | 79 + AspectC++/PointCutContext.cc | 61 + AspectC++/PointCutContext.h | 137 + AspectC++/PointCutExpr.cc | 1573 + AspectC++/PointCutExpr.h | 597 + AspectC++/PointCutExprParser.cc | 370 + AspectC++/PointCutExprParser.h | 52 + AspectC++/PointCutSearcher.h | 35 + AspectC++/PumaIncludeExpander.cc | 242 + AspectC++/PumaIncludeExpander.h | 90 + AspectC++/PumaIntroducer.cc | 1274 + AspectC++/PumaIntroducer.h | 155 + AspectC++/PumaModelBuilder.cc | 1054 + AspectC++/PumaModelBuilder.h | 220 + AspectC++/PumaPreprocessor.cc | 156 + AspectC++/PumaPreprocessor.h | 79 + AspectC++/PumaResultBuffer.cc | 151 + AspectC++/PumaResultBuffer.h | 64 + AspectC++/PumaSyntacticContext.cc | 73 + AspectC++/PumaSyntacticContext.h | 245 + AspectC++/PumaToken.h | 119 + AspectC++/PumaTrackerDog.cc | 277 + AspectC++/PumaTrackerDog.h | 78 + AspectC++/PumaTransformInfo.h | 990 + AspectC++/PumaWeaverBase.cc | 226 + AspectC++/PumaWeaverBase.h | 155 + AspectC++/README | 84 + AspectC++/README-Puma | 36 + AspectC++/RepoIdMgr.h | 53 + AspectC++/RepoNameKey.h | 42 + AspectC++/RepoPosAspectKey.cc | 30 + AspectC++/RepoPosAspectKey.h | 39 + AspectC++/RepoPosKey.cc | 30 + AspectC++/RepoPosKey.h | 41 + AspectC++/RepoXMLDoc.h | 69 + AspectC++/RepoXMLNode.cc | 53 + AspectC++/RepoXMLNode.h | 60 + AspectC++/Repository.cc | 240 + AspectC++/Repository.h | 77 + AspectC++/SourceLoc.h | 25 + AspectC++/SyntacticContext.h | 36 + AspectC++/TODO | 141 + AspectC++/ThisJoinPoint.cc | 766 + AspectC++/ThisJoinPoint.h | 156 + AspectC++/TransformInfo.h | 35 + AspectC++/Transformer.cc | 1378 + AspectC++/Transformer.h | 114 + AspectC++/Weaver.cc | 762 + AspectC++/Weaver.h | 74 + AspectC++/WeaverBase.h | 35 + AspectC++/ac++.cc | 64 + AspectC++/akut-trigger.tmp | 1 + AspectC++/clang-3.4-disable-modules.patch | 12 + AspectC++/config/Makefile | 52 + AspectC++/config/clang-3.5.0.mk | 1 + AspectC++/config/clang-3.5.0svn.mk | 1 + AspectC++/config/clang-3.6.2.mk | 1 + AspectC++/config/clang-3.7.1.mk | 1 + AspectC++/config/clang-3.8.0.mk | 1 + AspectC++/config/clang-3.8.1.mk | 1 + AspectC++/config/clang-3.9.1.mk | 1 + AspectC++/config/clang-4.0.0.mk | 1 + AspectC++/config/clang-4.0.1.mk | 1 + AspectC++/config/clang-5.0.0svn.mk | 1 + AspectC++/config/clang.mk | 38 + AspectC++/doc/CompilerManual/ac-compilerman.lyx | 5180 +++ AspectC++/doc/CompilerManual/images | 1 + .../doc/LanguageReference/ac-languageref-ru.odt | Bin 0 -> 84162 bytes .../doc/LanguageReference/ac-languageref-ru.pdf | Bin 0 -> 249586 bytes AspectC++/doc/LanguageReference/ac-languageref.lyx | 24007 +++++++++++ AspectC++/doc/LanguageReference/images | 1 + AspectC++/doc/Makefile | 25 + .../doc/NoE_ExecModelSurvey/ac++exec-survey.lyx | 455 + .../doc/NoE_ExecModelSurvey/ac++exec-survey.pdf | Bin 0 -> 27127 bytes AspectC++/doc/NoE_ShortSurvey/ac++lang-survey.lyx | 1336 + AspectC++/doc/NoE_ShortSurvey/ac++lang-survey.pdf | Bin 0 -> 64308 bytes .../doc/ProgrammingGuide/ProgrammingGuide.lyx | 2088 + AspectC++/doc/QuickRef/ac++quickref.lyx | 5288 +++ AspectC++/doc/QuickRef/ac++quickref.pdf | Bin 0 -> 123088 bytes AspectC++/doc/Tutorial/1-intro.odp | Bin 0 -> 132141 bytes AspectC++/doc/Tutorial/1-intro.pdf | Bin 0 -> 165831 bytes AspectC++/doc/Tutorial/2-language.odp | Bin 0 -> 150571 bytes AspectC++/doc/Tutorial/2-language.pdf | Bin 0 -> 317566 bytes AspectC++/doc/Tutorial/3-tools.odp | Bin 0 -> 46003 bytes AspectC++/doc/Tutorial/3-tools.pdf | Bin 0 -> 158349 bytes AspectC++/doc/Tutorial/4-examples.odp | Bin 0 -> 73226 bytes AspectC++/doc/Tutorial/4-examples.pdf | Bin 0 -> 261249 bytes AspectC++/doc/Tutorial/5-summary.odp | Bin 0 -> 81771 bytes AspectC++/doc/Tutorial/5-summary.pdf | Bin 0 -> 90155 bytes AspectC++/doc/Tutorial/README-JOIN | 1 + AspectC++/doc/Tutorial/ac-tutorial.pdf | Bin 0 -> 887957 bytes AspectC++/doc/doxygen.conf | 1213 + AspectC++/doc/gen/ac++logo.png | Bin 0 -> 62907 bytes AspectC++/doc/gen/ac-manual.css | 116 + AspectC++/doc/gen/fixhtml.xsl | 52 + AspectC++/doc/images/JoinPointModel.eps | 544 + AspectC++/doc/images/JoinPointModel.fig | 156 + AspectC++/doc/images/JoinPointModel.pdf | Bin 0 -> 6029 bytes AspectC++/doc/images/JoinPointModelNew.eps | 42576 +++++++++++++++++++ AspectC++/doc/images/JoinPointModelNew.odg | Bin 0 -> 17343 bytes AspectC++/doc/images/JoinPointModelNew.pdf | Bin 0 -> 35994 bytes AspectC++/doc/images/ReadMe.txt | 15 + AspectC++/doc/images/ac++logo.eps | 3928 ++ AspectC++/doc/images/ac++logo.pdf | Bin 0 -> 4730 bytes AspectC++/doc/images/acmodel-rotated90.pdf | Bin 0 -> 16089 bytes AspectC++/doc/images/acmodel.dot | 121 + AspectC++/doc/images/acmodel.eps | 2785 ++ AspectC++/doc/images/acmodel.pdf | Bin 0 -> 17534 bytes AspectC++/doc/images/acmodel_inheri_only_less.dot | 53 + AspectC++/doc/images/acmodel_inheri_only_less.eps | 921 + AspectC++/doc/images/acmodel_inheri_only_less.pdf | Bin 0 -> 8563 bytes AspectC++/doc/images/include_cycle.eps | 4966 +++ AspectC++/doc/images/include_cycle.odg | Bin 0 -> 16250 bytes AspectC++/doc/images/no_include_cycle.eps | 5689 +++ AspectC++/doc/images/no_include_cycle.odg | Bin 0 -> 16876 bytes AspectC++/doc/images/peanut.png | Bin 0 -> 1001 bytes AspectC++/doc/images/peanut.xcf | Bin 0 -> 3716 bytes AspectC++/doc/images/ps-logo.eps | 1524 + AspectC++/doc/images/ps-logo.pdf | Bin 0 -> 269260 bytes AspectC++/doc/images/ps-logo.png | Bin 0 -> 30129 bytes AspectC++/doc/styles/pure-systems.sty | 129 + AspectC++/examples/Makefile.generic | 44 + AspectC++/examples/coverage/Makefile | 1 + AspectC++/examples/coverage/coverage.ah | 80 + AspectC++/examples/coverage/main.cc | 24 + AspectC++/examples/coverage/mycoverage.ah | 14 + AspectC++/examples/helloworld/Makefile | 1 + AspectC++/examples/helloworld/hello.h | 10 + AspectC++/examples/helloworld/main.cc | 6 + AspectC++/examples/helloworld/world.ah | 15 + AspectC++/examples/modules/Makefile | 1 + AspectC++/examples/modules/Module0.ah | 15 + AspectC++/examples/modules/Module0.h | 18 + AspectC++/examples/modules/Module1.ah | 15 + AspectC++/examples/modules/Module1.h | 18 + AspectC++/examples/modules/Modules.h | 18 + AspectC++/examples/modules/main.cc | 9 + AspectC++/examples/profiling/Makefile | 1 + AspectC++/examples/profiling/genericprofiler.ah | 124 + AspectC++/examples/profiling/main.cc | 24 + AspectC++/examples/profiling/profiler.ah | 42 + AspectC++/examples/singleton/Makefile | 1 + AspectC++/examples/singleton/falsefriend.h | 19 + AspectC++/examples/singleton/main.cc | 11 + AspectC++/examples/singleton/mysingletonmonitor.ah | 14 + AspectC++/examples/singleton/singleton.h | 34 + AspectC++/examples/singleton/singletonmonitor.ah | 47 + AspectC++/examples/threads/Log.h | 20 + AspectC++/examples/threads/Makefile | 2 + AspectC++/examples/threads/SynchronizedLog.ah | 27 + AspectC++/examples/threads/ThreadSafeLogging.ah | 74 + AspectC++/examples/threads/main.cc | 51 + AspectC++/infos.h | 8 + AspectC++/tests/AbstractDerivedAspect/Makefile | 1 + AspectC++/tests/AbstractDerivedAspect/feature.ref | 4 + AspectC++/tests/AbstractDerivedAspect/main.cc | 48 + AspectC++/tests/AccessControl/Makefile | 1 + AspectC++/tests/AccessControl/feature.ref | 49 + AspectC++/tests/AccessControl/main.cc | 90 + AspectC++/tests/Advice/Aspect.ah | 19 + AspectC++/tests/Advice/Makefile | 1 + AspectC++/tests/Advice/feature.ref | 38 + AspectC++/tests/Advice/main.cc | 53 + AspectC++/tests/AdviceVirtualFct/Aspect.ah | 23 + AspectC++/tests/AdviceVirtualFct/Makefile | 1 + AspectC++/tests/AdviceVirtualFct/feature.ref | 22 + AspectC++/tests/AdviceVirtualFct/main.cc | 53 + AspectC++/tests/AnonymousStuff/Makefile | 1 + AspectC++/tests/AnonymousStuff/feature.ref | 35 + AspectC++/tests/AnonymousStuff/main.cc | 83 + AspectC++/tests/ArrayAccessAdvice/Makefile | 3 + AspectC++/tests/ArrayAccessAdvice/around.ah | 22 + AspectC++/tests/ArrayAccessAdvice/feature.ref | 119 + AspectC++/tests/ArrayAccessAdvice/idx.ah | 19 + AspectC++/tests/ArrayAccessAdvice/main.cc | 232 + AspectC++/tests/ArrayAccessAdvice/namemap.cc | 35 + AspectC++/tests/ArrayAccessAdvice/namemap.h | 18 + AspectC++/tests/ArrayAccessAdvice/trace.ah | 105 + AspectC++/tests/ArrayMangling/Makefile | 1 + AspectC++/tests/ArrayMangling/feature.ref | 5 + AspectC++/tests/ArrayMangling/main.cc | 35 + AspectC++/tests/ArrayWrapper/Makefile | 1 + AspectC++/tests/ArrayWrapper/feature.ref | 7 + AspectC++/tests/ArrayWrapper/main.cc | 66 + AspectC++/tests/AspectOf/Makefile | 1 + AspectC++/tests/AspectOf/feature.ref | 8 + AspectC++/tests/AspectOf/main.cc | 46 + AspectC++/tests/AspectPrivileges/Makefile | 1 + AspectC++/tests/AspectPrivileges/feature.ref | 13 + AspectC++/tests/AspectPrivileges/main.cc | 58 + AspectC++/tests/AttribAligned/Makefile | 2 + AspectC++/tests/AttribAligned/feature.ref | 1 + AspectC++/tests/AttribAligned/main.cc | 36 + AspectC++/tests/Attribute_basic/Makefile | 3 + AspectC++/tests/Attribute_basic/feature.ref | 10 + AspectC++/tests/Attribute_basic/main.cc | 86 + AspectC++/tests/Attribute_inMacro/Makefile | 1 + AspectC++/tests/Attribute_inMacro/feature.ref | 4 + AspectC++/tests/Attribute_inMacro/main.cc | 37 + AspectC++/tests/Attribute_pointcuts/Makefile | 1 + AspectC++/tests/Attribute_pointcuts/Test.ah | 34 + AspectC++/tests/Attribute_pointcuts/feature.ref | 3 + AspectC++/tests/Attribute_pointcuts/main.cc | 34 + AspectC++/tests/Attribute_removeAttrs/Makefile | 3 + AspectC++/tests/Attribute_removeAttrs/feature.ref | 1 + AspectC++/tests/Attribute_removeAttrs/main.cc | 30 + AspectC++/tests/Base/Makefile | 1 + AspectC++/tests/Base/feature.ref | 22 + AspectC++/tests/Base/main.cc | 80 + AspectC++/tests/Bug-Typenames/Makefile | 2 + AspectC++/tests/Bug-Typenames/feature.ref | 3 + AspectC++/tests/Bug-Typenames/main.cc | 47 + AspectC++/tests/Bug179/Makefile | 1 + AspectC++/tests/Bug179/feature.ref | 4 + AspectC++/tests/Bug179/main.cc | 15 + AspectC++/tests/Bug190/Makefile | 1 + AspectC++/tests/Bug190/feature.ref | 2 + AspectC++/tests/Bug190/main.cc | 16 + AspectC++/tests/Bug191/Makefile | 1 + AspectC++/tests/Bug191/feature.ref | 1 + AspectC++/tests/Bug191/main.cc | 18 + AspectC++/tests/Bug192/Makefile | 1 + AspectC++/tests/Bug192/feature.ref | 1 + AspectC++/tests/Bug192/main.cc | 19 + AspectC++/tests/Bug207/Makefile | 1 + AspectC++/tests/Bug207/feature.ref | 4 + AspectC++/tests/Bug207/main.cc | 32 + AspectC++/tests/Bug209/AbstractTrace.ah | 22 + AspectC++/tests/Bug209/Makefile | 1 + AspectC++/tests/Bug209/feature.ref | 3 + AspectC++/tests/Bug209/main.cc | 23 + AspectC++/tests/Bug216/Makefile | 1 + AspectC++/tests/Bug216/feature.ref | 4 + AspectC++/tests/Bug216/main.cc | 43 + AspectC++/tests/Bug228/Makefile | 1 + AspectC++/tests/Bug228/feature.ref | 1 + AspectC++/tests/Bug228/main.cc | 19 + AspectC++/tests/Bug234-2/Makefile | 1 + AspectC++/tests/Bug234-2/feature.ref | 5 + AspectC++/tests/Bug234-2/introTarget.cc | 7 + AspectC++/tests/Bug234-2/introTarget.hxx | 9 + AspectC++/tests/Bug234-2/main.cc | 17 + AspectC++/tests/Bug234-2/myAspect.ah | 34 + AspectC++/tests/Bug234/Makefile | 1 + AspectC++/tests/Bug234/anotherAspect.ah | 9 + AspectC++/tests/Bug234/feature.ref | 5 + AspectC++/tests/Bug234/introTarget.cc | 7 + AspectC++/tests/Bug234/introTarget.h | 10 + AspectC++/tests/Bug234/main.cc | 17 + AspectC++/tests/Bug234/myAspect.ah | 21 + AspectC++/tests/Bug234/mySlice.ah | 13 + AspectC++/tests/Bug235/Makefile | 1 + AspectC++/tests/Bug235/abstractTrace.ah | 18 + AspectC++/tests/Bug235/classA.h | 13 + AspectC++/tests/Bug235/classB.h | 13 + AspectC++/tests/Bug235/concreteTraceA.ah | 10 + AspectC++/tests/Bug235/concreteTraceB.ah | 10 + AspectC++/tests/Bug235/feature.ref | 9 + AspectC++/tests/Bug235/main.cc | 16 + AspectC++/tests/Bug239/Makefile | 1 + AspectC++/tests/Bug239/feature.ref | 7 + AspectC++/tests/Bug239/main.cc | 31 + AspectC++/tests/Bug242/Makefile | 1 + AspectC++/tests/Bug242/OutputStream.h | 12 + AspectC++/tests/Bug242/Padding.ah | 19 + AspectC++/tests/Bug242/feature.ref | 4 + AspectC++/tests/Bug242/main.cc | 12 + AspectC++/tests/Bug267/Makefile | 1 + AspectC++/tests/Bug267/feature.ref | 6 + AspectC++/tests/Bug267/main.cc | 33 + AspectC++/tests/Bug268/Makefile | 1 + AspectC++/tests/Bug268/feature.ref | 24 + AspectC++/tests/Bug268/main.cc | 41 + AspectC++/tests/Bug271/Makefile | 1 + AspectC++/tests/Bug271/feature.ref | 7 + AspectC++/tests/Bug271/main.cc | 65 + AspectC++/tests/Bug293/ArgumentSizeCalculator.h | 41 + AspectC++/tests/Bug293/Callee.h | 12 + AspectC++/tests/Bug293/Derived.cc | 8 + AspectC++/tests/Bug293/Derived.h | 12 + AspectC++/tests/Bug293/Makefile | 1 + AspectC++/tests/Bug293/SaveStack.h | 269 + AspectC++/tests/Bug293/doMeasurement.h | 44 + AspectC++/tests/Bug293/dynamic.cc | 17 + AspectC++/tests/Bug293/measure.ah | 12 + AspectC++/tests/Bug293/measureAspect.ah | 127 + AspectC++/tests/Bug293/target.ah | 14 + AspectC++/tests/Bug316/Makefile | 1 + AspectC++/tests/Bug316/feature.ref | 8 + AspectC++/tests/Bug316/main.cc | 106 + AspectC++/tests/Bug321/Makefile | 1 + AspectC++/tests/Bug321/feature.ref | 11 + AspectC++/tests/Bug321/main.cc | 49 + AspectC++/tests/Bug323/A0.ah | 12 + AspectC++/tests/Bug323/A1.ah | 15 + AspectC++/tests/Bug323/A2.ah | 12 + AspectC++/tests/Bug323/Makefile | 1 + AspectC++/tests/Bug323/feature.ref | 6 + AspectC++/tests/Bug323/header.h | 6 + AspectC++/tests/Bug323/main.cc | 15 + AspectC++/tests/Bug336/Makefile | 1 + AspectC++/tests/Bug336/feature.ref | 5 + AspectC++/tests/Bug336/main.cc | 57 + AspectC++/tests/Bug353/Makefile | 1 + AspectC++/tests/Bug353/feature.ref | 4 + AspectC++/tests/Bug353/main.cc | 15 + AspectC++/tests/Bug368/Makefile | 1 + AspectC++/tests/Bug368/feature.ref | 9 + AspectC++/tests/Bug368/main.cc | 40 + AspectC++/tests/Bug418/Makefile | 1 + AspectC++/tests/Bug418/falsefriend.h | 19 + AspectC++/tests/Bug418/feature.ref | 0 AspectC++/tests/Bug418/main.cc | 11 + AspectC++/tests/Bug418/mysingletonmonitor.ah | 14 + AspectC++/tests/Bug418/singleton.h | 34 + AspectC++/tests/Bug418/singletonmonitor.ah | 46 + AspectC++/tests/Bug427/Makefile | 2 + AspectC++/tests/Bug427/feature.ref | 9 + AspectC++/tests/Bug427/main.cc | 59 + AspectC++/tests/Bug477/Makefile | 1 + AspectC++/tests/Bug477/feature.ref | 12 + AspectC++/tests/Bug477/main.cc | 61 + AspectC++/tests/Bug484/Makefile | 1 + AspectC++/tests/Bug484/feature.ref | 5 + AspectC++/tests/Bug484/main.cc | 23 + AspectC++/tests/Bug512/Makefile | 1 + AspectC++/tests/Bug512/feature.ref | 7 + AspectC++/tests/Bug512/main.cc | 26 + AspectC++/tests/Bug524/Makefile | 1 + AspectC++/tests/Bug524/feature.ref | 0 AspectC++/tests/Bug524/main.cc | 13 + AspectC++/tests/Bug548/Makefile | 1 + AspectC++/tests/Bug548/feature.ref | 5 + AspectC++/tests/Bug548/main.cc | 64 + AspectC++/tests/Bug549/Makefile | 1 + AspectC++/tests/Bug549/feature.ref | 5 + AspectC++/tests/Bug549/main.cc | 30 + AspectC++/tests/Bug552/Makefile | 1 + AspectC++/tests/Bug552/Mem.h | 21 + AspectC++/tests/Bug552/feature.ref | 3 + AspectC++/tests/Bug552/file1.cc | 11 + AspectC++/tests/Bug552/file2.cc | 5 + AspectC++/tests/Bug552/file3.cc | 5 + AspectC++/tests/Bug554/Makefile | 1 + AspectC++/tests/Bug554/feature.ref | 16 + AspectC++/tests/Bug554/main.cc | 62 + AspectC++/tests/Bug561/Makefile | 1 + AspectC++/tests/Bug561/feature.ref | 12 + AspectC++/tests/Bug561/main.cc | 70 + AspectC++/tests/Bug561/slice.ah | 15 + AspectC++/tests/Bug564/Makefile | 1 + AspectC++/tests/Bug564/feature.ref | 0 AspectC++/tests/Bug564/main.cc | 7 + AspectC++/tests/Bug564/random_header.h | 1 + AspectC++/tests/Bug566/Makefile | 1 + AspectC++/tests/Bug566/feature.ref | 10 + AspectC++/tests/Bug566/main.cc | 34 + AspectC++/tests/Bug567/Makefile | 2 + AspectC++/tests/Bug567/feature.ref | 15 + AspectC++/tests/Bug567/main.cc | 53 + AspectC++/tests/Bug568/Makefile | 2 + AspectC++/tests/Bug568/feature.ref | 15 + AspectC++/tests/Bug568/main.cc | 147 + AspectC++/tests/Bug570/Makefile | 4 + AspectC++/tests/Bug570/feature.ref | 1 + AspectC++/tests/Bug570/main.cc | 7 + AspectC++/tests/Bug571-1/Makefile | 1 + AspectC++/tests/Bug571-1/feature.ref | 6 + AspectC++/tests/Bug571-1/main.cc | 61 + AspectC++/tests/Bug571-2/Makefile | 1 + AspectC++/tests/Bug571-2/feature.ref | 10 + AspectC++/tests/Bug571-2/main.cc | 84 + AspectC++/tests/Bug571-3/Makefile | 1 + AspectC++/tests/Bug571-3/feature.ref | 4 + AspectC++/tests/Bug571-3/main.cc | 81 + AspectC++/tests/Bug574/Makefile | 2 + AspectC++/tests/Bug574/feature.ref | 2 + AspectC++/tests/Bug574/main.cc | 53 + AspectC++/tests/Bug575/Makefile | 1 + AspectC++/tests/Bug575/feature.ref | 4 + AspectC++/tests/Bug575/main.cc | 32 + AspectC++/tests/Bug576/Makefile | 2 + AspectC++/tests/Bug576/feature.ref | 4 + AspectC++/tests/Bug576/main.cc | 110 + AspectC++/tests/Bug577/Makefile | 1 + AspectC++/tests/Bug577/alex.ah | 8 + AspectC++/tests/Bug577/alex.h | 8 + AspectC++/tests/Bug577/feature.ref | 4 + AspectC++/tests/Bug577/macro.ah | 9 + AspectC++/tests/Bug577/main.cc | 7 + AspectC++/tests/Bug580/Makefile | 1 + AspectC++/tests/Bug580/feature.ref | 1 + AspectC++/tests/Bug580/main.cc | 31 + AspectC++/tests/Bug589/Makefile | 2 + AspectC++/tests/Bug589/feature.ref | 4 + AspectC++/tests/Bug589/main.cc | 64 + AspectC++/tests/Bug594/Makefile | 2 + AspectC++/tests/Bug594/feature.ref | 4 + AspectC++/tests/Bug594/main.cc | 20 + AspectC++/tests/Bug598/Makefile | 2 + AspectC++/tests/Bug598/feature.ref | 5 + AspectC++/tests/Bug598/main.cc | 32 + AspectC++/tests/Bug768/Makefile | 1 + AspectC++/tests/Bug768/feature.ref | 0 AspectC++/tests/Bug768/main.cc | 7 + AspectC++/tests/Bug769/Makefile | 1 + AspectC++/tests/Bug769/feature.ref | 0 AspectC++/tests/Bug769/main.cc | 8 + AspectC++/tests/Bug770/Makefile | 1 + AspectC++/tests/Bug770/feature.ref | 0 AspectC++/tests/Bug770/main.cc | 81 + AspectC++/tests/CFlowCycle/A.h | 12 + AspectC++/tests/CFlowCycle/B.h | 10 + AspectC++/tests/CFlowCycle/C.h | 10 + AspectC++/tests/CFlowCycle/CFlow.ah | 19 + AspectC++/tests/CFlowCycle/D.h | 12 + AspectC++/tests/CFlowCycle/Makefile | 1 + AspectC++/tests/CFlowCycle/feature.ref | 7 + AspectC++/tests/CFlowCycle/main.cc | 14 + AspectC++/tests/CallAccess/Makefile | 1 + AspectC++/tests/CallAccess/feature.ref | 18 + AspectC++/tests/CallAccess/main.cc | 89 + AspectC++/tests/CallAdvice/Makefile | 1 + AspectC++/tests/CallAdvice/feature.ref | 134 + AspectC++/tests/CallAdvice/main.cc | 291 + AspectC++/tests/CallBuiltinOperator/Makefile | 2 + AspectC++/tests/CallBuiltinOperator/feature.ref | 1591 + AspectC++/tests/CallBuiltinOperator/main.cc | 563 + AspectC++/tests/CallOnRef/Makefile | 1 + AspectC++/tests/CallOnRef/feature.ref | 5 + AspectC++/tests/CallOnRef/main.cc | 27 + AspectC++/tests/CallPostfixOp/Makefile | 1 + AspectC++/tests/CallPostfixOp/feature.ref | 19 + AspectC++/tests/CallPostfixOp/main.cc | 64 + AspectC++/tests/CallRef/Makefile | 1 + AspectC++/tests/CallRef/feature.ref | 0 AspectC++/tests/CallRef/main.cc | 27 + AspectC++/tests/CallViaADN/Makefile | 1 + AspectC++/tests/CallViaADN/classes.h | 49 + AspectC++/tests/CallViaADN/feature.ref | 15 + AspectC++/tests/CallViaADN/functions.cc | 12 + AspectC++/tests/CallViaADN/main.cc | 24 + AspectC++/tests/CallViaADN/trace.ah | 12 + AspectC++/tests/CompoundGetSetAdvice/Makefile | 2 + AspectC++/tests/CompoundGetSetAdvice/feature.ref | 347 + AspectC++/tests/CompoundGetSetAdvice/main.cc | 194 + AspectC++/tests/ConsDesAdvice/ConsDesTracker.ah | 57 + AspectC++/tests/ConsDesAdvice/Makefile | 1 + AspectC++/tests/ConsDesAdvice/c1.h | 80 + AspectC++/tests/ConsDesAdvice/feature.ref | 53 + AspectC++/tests/ConsDesAdvice/main.cc | 63 + AspectC++/tests/Context/Makefile | 1 + AspectC++/tests/Context/feature.ref | 7 + AspectC++/tests/Context/main.cc | 37 + AspectC++/tests/DataFlowAnalysis/Makefile | 2 + AspectC++/tests/DataFlowAnalysis/feature.ref | 133 + AspectC++/tests/DataFlowAnalysis/main.cc | 387 + AspectC++/tests/DefaultArgs/Makefile | 1 + AspectC++/tests/DefaultArgs/feature.ref | 3 + AspectC++/tests/DefaultArgs/main.cc | 40 + AspectC++/tests/DefaultArgs2/Makefile | 2 + AspectC++/tests/DefaultArgs2/feature.ref | 8 + AspectC++/tests/DefaultArgs2/main.cc | 48 + AspectC++/tests/Derived/Makefile | 1 + AspectC++/tests/Derived/feature.ref | 20 + AspectC++/tests/Derived/main.cc | 80 + AspectC++/tests/DisjointIds/Makefile | 1 + AspectC++/tests/DisjointIds/a.ah | 72 + AspectC++/tests/DisjointIds/feature.ref | 3 + AspectC++/tests/DisjointIds/main.cc | 14 + AspectC++/tests/DisjointIds/other.cc | 1 + AspectC++/tests/Empty/Makefile | 1 + AspectC++/tests/Empty/empty.cc | 0 AspectC++/tests/Empty/feature.ref | 0 AspectC++/tests/Empty/main.cc | 1 + AspectC++/tests/ExecAdviceFriend/Makefile | 1 + AspectC++/tests/ExecAdviceFriend/feature.ref | 6 + AspectC++/tests/ExecAdviceFriend/main.cc | 27 + AspectC++/tests/ExecAdviceNewDelete/Makefile | 2 + AspectC++/tests/ExecAdviceNewDelete/feature.ref | 19 + AspectC++/tests/ExecAdviceNewDelete/main.cc | 66 + AspectC++/tests/ExecAdviceRecursive/Makefile | 1 + AspectC++/tests/ExecAdviceRecursive/feature.ref | 15 + AspectC++/tests/ExecAdviceRecursive/main.cc | 47 + AspectC++/tests/ExternC/Makefile | 1 + AspectC++/tests/ExternC/feature.ref | 35 + AspectC++/tests/ExternC/main.cc | 67 + AspectC++/tests/Float128Basic/Makefile | 1 + AspectC++/tests/Float128Basic/feature.ref | 4 + AspectC++/tests/Float128Basic/main.cc | 58 + AspectC++/tests/ForcedInclude/Makefile | 2 + AspectC++/tests/ForcedInclude/config.h | 6 + AspectC++/tests/ForcedInclude/feature.ref | 4 + AspectC++/tests/ForcedInclude/main.cc | 9 + AspectC++/tests/Forward/Aspect.ah | 23 + AspectC++/tests/Forward/Forward.h | 8 + AspectC++/tests/Forward/Makefile | 1 + AspectC++/tests/Forward/feature.ref | 2 + AspectC++/tests/Forward/main.cc | 15 + AspectC++/tests/FunctionEntity/Makefile | 1 + AspectC++/tests/FunctionEntity/feature.ref | 53 + AspectC++/tests/FunctionEntity/main.cc | 91 + AspectC++/tests/GetBaseDerived/Makefile | 2 + AspectC++/tests/GetBaseDerived/feature.ref | 11 + AspectC++/tests/GetBaseDerived/main.cc | 44 + AspectC++/tests/GetConditional/Makefile | 2 + AspectC++/tests/GetConditional/feature.ref | 3 + AspectC++/tests/GetConditional/main.cc | 26 + AspectC++/tests/GlobalIds/Makefile | 1 + AspectC++/tests/GlobalIds/a.ah | 33 + AspectC++/tests/GlobalIds/another_module.cc | 14 + AspectC++/tests/GlobalIds/feature.ref | 4 + AspectC++/tests/GlobalIds/h1.h | 6 + AspectC++/tests/GlobalIds/main.cc | 10 + AspectC++/tests/Instantiation/Makefile | 2 + AspectC++/tests/Instantiation/feature.ref | 4 + AspectC++/tests/Instantiation/main.cc | 32 + AspectC++/tests/IntroInAll/Makefile | 1 + AspectC++/tests/IntroInAll/feature.ref | 4 + AspectC++/tests/IntroInAll/main.cc | 114 + AspectC++/tests/IntroInBase/Base.ah | 11 + AspectC++/tests/IntroInBase/C.h | 10 + AspectC++/tests/IntroInBase/Derived.ah | 34 + AspectC++/tests/IntroInBase/Makefile | 1 + AspectC++/tests/IntroInBase/feature.ref | 5 + AspectC++/tests/IntroInBase/main.cc | 11 + AspectC++/tests/IntroIncludes/A1.ah | 6 + AspectC++/tests/IntroIncludes/A2.ah | 11 + AspectC++/tests/IntroIncludes/A3.ah | 6 + AspectC++/tests/IntroIncludes/C.h | 6 + AspectC++/tests/IntroIncludes/Makefile | 1 + AspectC++/tests/IntroIncludes/feature.ref | 4 + AspectC++/tests/IntroIncludes/main.cc | 12 + AspectC++/tests/Introspection/Makefile | 2 + AspectC++/tests/Introspection/feature.ref | 18 + AspectC++/tests/Introspection/main.cc | 397 + AspectC++/tests/JPTL/JPTL.h | 893 + AspectC++/tests/JPTL/Makefile | 2 + AspectC++/tests/JPTL/TestAspect.ah | 88 + AspectC++/tests/JPTL/feature.ref | 13 + AspectC++/tests/JPTL/main.cc | 27 + AspectC++/tests/JPType/Makefile | 1 + AspectC++/tests/JPType/feature.ref | 11 + AspectC++/tests/JPType/main.cc | 36 + AspectC++/tests/MacroCall/Makefile | 1 + AspectC++/tests/MacroCall/external.cc | 7 + AspectC++/tests/MacroCall/feature.ref | 9 + AspectC++/tests/MacroCall/main.cc | 82 + AspectC++/tests/MacroExpansion/Makefile | 1 + AspectC++/tests/MacroExpansion/feature.ref | 4 + AspectC++/tests/MacroExpansion/main.cc | 34 + AspectC++/tests/Makefile | 266 + AspectC++/tests/Makefile.generic | 97 + AspectC++/tests/MatchExpr/Makefile | 1 + AspectC++/tests/MatchExpr/feature.ref | 168 + AspectC++/tests/MatchExpr/main.cc | 375 + AspectC++/tests/MatchScope/Makefile | 2 + AspectC++/tests/MatchScope/feature.ref | 120 + AspectC++/tests/MatchScope/main.cc | 161 + AspectC++/tests/MatchScopeWithin/Makefile | 2 + AspectC++/tests/MatchScopeWithin/feature.ref | 6 + AspectC++/tests/MatchScopeWithin/main.cc | 62 + AspectC++/tests/MatchStatic/Makefile | 1 + AspectC++/tests/MatchStatic/feature.ref | 16 + AspectC++/tests/MatchStatic/main.cc | 38 + AspectC++/tests/MatchVirtual/Makefile | 1 + AspectC++/tests/MatchVirtual/feature.ref | 13 + AspectC++/tests/MatchVirtual/main.cc | 52 + AspectC++/tests/MemberPointCut/Makefile | 1 + AspectC++/tests/MemberPointCut/feature.ref | 52 + AspectC++/tests/MemberPointCut/main.cc | 33 + AspectC++/tests/MemberPointCut/marker.ah | 52 + AspectC++/tests/MemberPointCut2/Makefile | 2 + AspectC++/tests/MemberPointCut2/feature.ref | 57 + AspectC++/tests/MemberPointCut2/main.cc | 37 + AspectC++/tests/MemberPointCut2/marker.ah | 52 + AspectC++/tests/NameMangling/Makefile | 1 + AspectC++/tests/NameMangling/NeedsMangling.ah | 12 + AspectC++/tests/NameMangling/feature.ref | 7 + AspectC++/tests/NameMangling/main.cc | 41 + AspectC++/tests/NamedPointcuts/Makefile | 1 + AspectC++/tests/NamedPointcuts/feature.ref | 14 + AspectC++/tests/NamedPointcuts/main.cc | 94 + AspectC++/tests/Namespaces/Makefile | 1 + AspectC++/tests/Namespaces/main.cc | 54 + AspectC++/tests/NestedClassFuncAdvice/Aspect.ah | 17 + AspectC++/tests/NestedClassFuncAdvice/Makefile | 1 + AspectC++/tests/NestedClassFuncAdvice/feature.ref | 7 + AspectC++/tests/NestedClassFuncAdvice/main.cc | 32 + AspectC++/tests/NonInlineIntroInclude/A.cc | 3 + AspectC++/tests/NonInlineIntroInclude/A.h | 8 + AspectC++/tests/NonInlineIntroInclude/ABDecl.ah | 19 + AspectC++/tests/NonInlineIntroInclude/ABDef.ah | 29 + AspectC++/tests/NonInlineIntroInclude/B.cc | 3 + AspectC++/tests/NonInlineIntroInclude/B.h | 8 + AspectC++/tests/NonInlineIntroInclude/C.cc | 3 + AspectC++/tests/NonInlineIntroInclude/C.h | 11 + AspectC++/tests/NonInlineIntroInclude/CDecl.ah | 9 + AspectC++/tests/NonInlineIntroInclude/CDef.ah | 13 + AspectC++/tests/NonInlineIntroInclude/Makefile | 1 + AspectC++/tests/NonInlineIntroInclude/feature.ref | 7 + AspectC++/tests/NonInlineIntroInclude/main.cc | 15 + AspectC++/tests/NonInlineIntros/C.cc | 35 + AspectC++/tests/NonInlineIntros/C.h | 15 + AspectC++/tests/NonInlineIntros/D.cc | 5 + AspectC++/tests/NonInlineIntros/D.h | 12 + AspectC++/tests/NonInlineIntros/E.h | 19 + AspectC++/tests/NonInlineIntros/F.cc | 3 + AspectC++/tests/NonInlineIntros/F.h | 22 + AspectC++/tests/NonInlineIntros/Intro.ah | 60 + AspectC++/tests/NonInlineIntros/Makefile | 1 + AspectC++/tests/NonInlineIntros/feature.ref | 22 + AspectC++/tests/NonInlineSliceInclude/A.cc | 3 + AspectC++/tests/NonInlineSliceInclude/A.h | 8 + AspectC++/tests/NonInlineSliceInclude/ABDecl.ah | 27 + AspectC++/tests/NonInlineSliceInclude/ABDef.ah | 19 + AspectC++/tests/NonInlineSliceInclude/B.cc | 3 + AspectC++/tests/NonInlineSliceInclude/B.h | 8 + AspectC++/tests/NonInlineSliceInclude/C.cc | 3 + AspectC++/tests/NonInlineSliceInclude/C.h | 11 + AspectC++/tests/NonInlineSliceInclude/CDecl.ah | 8 + AspectC++/tests/NonInlineSliceInclude/CDef.ah | 15 + AspectC++/tests/NonInlineSliceInclude/Makefile | 1 + AspectC++/tests/NonInlineSliceInclude/feature.ref | 7 + AspectC++/tests/NonInlineSliceInclude/main.cc | 15 + AspectC++/tests/Order/Makefile | 1 + AspectC++/tests/Order/feature.ref | 34 + AspectC++/tests/Order/main.cc | 82 + AspectC++/tests/PctInClass/Makefile | 1 + AspectC++/tests/PctInClass/feature.ref | 5 + AspectC++/tests/PctInClass/main.cc | 26 + AspectC++/tests/PragmaOnce/Makefile | 1 + AspectC++/tests/PragmaOnce/a.h | 5 + AspectC++/tests/PragmaOnce/b.h | 4 + AspectC++/tests/PragmaOnce/feature.ref | 4 + AspectC++/tests/PragmaOnce/main.cc | 15 + AspectC++/tests/PragmaOnceObserver/AnalogClock.cc | 20 + AspectC++/tests/PragmaOnceObserver/AnalogClock.h | 29 + .../tests/PragmaOnceObserver/ClockObserver.ah | 37 + AspectC++/tests/PragmaOnceObserver/ClockTimer.cc | 18 + AspectC++/tests/PragmaOnceObserver/ClockTimer.h | 41 + AspectC++/tests/PragmaOnceObserver/DigitalClock.cc | 20 + AspectC++/tests/PragmaOnceObserver/DigitalClock.h | 29 + AspectC++/tests/PragmaOnceObserver/Makefile | 1 + .../tests/PragmaOnceObserver/ObserverPattern.ah | 59 + AspectC++/tests/PragmaOnceObserver/feature.ref | 4 + AspectC++/tests/PragmaOnceObserver/main.cc | 40 + AspectC++/tests/PrivateResult/Aspect.ah | 45 + AspectC++/tests/PrivateResult/Makefile | 1 + AspectC++/tests/PrivateResult/Safe.h | 46 + AspectC++/tests/PrivateResult/feature.ref | 23 + AspectC++/tests/PrivateResult/main.cc | 36 + AspectC++/tests/RepoInvalid/Makefile | 3 + AspectC++/tests/RepoInvalid/feature.ref | 1 + AspectC++/tests/RepoInvalid/main.cc | 3 + AspectC++/tests/RepoInvalid/repo.inv | 1 + AspectC++/tests/RepoVersion/Makefile | 4 + AspectC++/tests/RepoVersion/feature.ref | 1 + AspectC++/tests/RepoVersion/main.cc | 3 + AspectC++/tests/RepoVersion/repo.inv | 23 + AspectC++/tests/Result/Makefile | 1 + AspectC++/tests/Result/PointerTracker.ah | 30 + AspectC++/tests/Result/feature.ref | 14 + AspectC++/tests/Result/main.cc | 32 + AspectC++/tests/RightlessCalls/Makefile | 1 + AspectC++/tests/RightlessCalls/feature.ref | 6 + AspectC++/tests/RightlessCalls/main.cc | 55 + AspectC++/tests/STLSet/Makefile | 1 + AspectC++/tests/STLSet/main.cc | 19 + AspectC++/tests/STLString/Makefile | 3 + AspectC++/tests/STLString/feature.ref | 5 + AspectC++/tests/STLString/main.cc | 22 + AspectC++/tests/SimpleAliasAccessMember/Makefile | 2 + .../tests/SimpleAliasAccessMember/feature.ref | 28 + AspectC++/tests/SimpleAliasAccessMember/main.cc | 91 + AspectC++/tests/SimpleGetAdvice/Makefile | 2 + AspectC++/tests/SimpleGetAdvice/feature.ref | 99 + AspectC++/tests/SimpleGetAdvice/main.cc | 106 + AspectC++/tests/SimpleGetSetFuncPtr/Makefile | 2 + AspectC++/tests/SimpleGetSetFuncPtr/feature.ref | 7 + AspectC++/tests/SimpleGetSetFuncPtr/main.cc | 54 + AspectC++/tests/SimpleRefAdvice/Makefile | 2 + AspectC++/tests/SimpleRefAdvice/feature.ref | 175 + AspectC++/tests/SimpleRefAdvice/main.cc | 134 + AspectC++/tests/SimpleSetAdvice/Makefile | 2 + AspectC++/tests/SimpleSetAdvice/feature.ref | 129 + AspectC++/tests/SimpleSetAdvice/main.cc | 125 + AspectC++/tests/Slice/Makefile | 1 + AspectC++/tests/Slice/feature.ref | 17 + AspectC++/tests/Slice/main.cc | 156 + AspectC++/tests/SliceJPAPI/Makefile | 2 + AspectC++/tests/SliceJPAPI/feature.ref | 19 + AspectC++/tests/SliceJPAPI/main.cc | 61 + AspectC++/tests/StandAloneCalls/Aspect.ah | 13 + AspectC++/tests/StandAloneCalls/Makefile | 1 + AspectC++/tests/StandAloneCalls/feature.ref | 18 + AspectC++/tests/StandAloneCalls/main.cc | 81 + AspectC++/tests/StaticTrace/Makefile | 1 + AspectC++/tests/StaticTrace/Trace.ah | 34 + AspectC++/tests/StaticTrace/feature.ref | 15 + AspectC++/tests/StaticTrace/main.cc | 22 + AspectC++/tests/TemplateExtCall/Makefile | 1 + AspectC++/tests/TemplateExtCall/feature.ref | 57 + AspectC++/tests/TemplateExtCall/main.cc | 116 + AspectC++/tests/That/Makefile | 1 + AspectC++/tests/That/feature.ref | 67 + AspectC++/tests/That/main.cc | 96 + AspectC++/tests/ThatConst/Makefile | 1 + AspectC++/tests/ThatConst/feature.ref | 15 + AspectC++/tests/ThatConst/main.cc | 43 + AspectC++/tests/ThatContext/Makefile | 1 + AspectC++/tests/ThatContext/feature.ref | 10 + AspectC++/tests/ThatContext/main.cc | 57 + AspectC++/tests/UnknownTypeCheck/Makefile | 1 + AspectC++/tests/UnknownTypeCheck/a.cc | 10 + AspectC++/tests/UnknownTypeCheck/a.h | 10 + AspectC++/tests/UnknownTypeCheck/b.h | 10 + AspectC++/tests/UnknownTypeCheck/check.ah | 14 + AspectC++/tests/UnknownTypeCheck/feature.ref | 13 + AspectC++/tests/UnknownTypeCheck/main.cc | 28 + AspectC++/tests/UnsizedArray/Makefile | 2 + AspectC++/tests/UnsizedArray/feature.ref | 22 + AspectC++/tests/UnsizedArray/main.cc | 92 + AspectC++/tests/VirtualPointcuts/Makefile | 1 + AspectC++/tests/VirtualPointcuts/feature.ref | 5 + AspectC++/tests/VirtualPointcuts/main.cc | 32 + AspectC++/tests/VoidArg/Makefile | 1 + AspectC++/tests/VoidArg/feature.ref | 45 + AspectC++/tests/VoidArg/main.cc | 68 + AspectC++/tests/conv_junit.py | 86 + AspectC++/tests/genvcprojs.sh | 230 + AspectC++/tests/rmvcprojs.sh | 8 + AspectC++/tools/cvs2cl | 2404 ++ AspectC++/tools/gpl | 45 + AspectC++/version.h | 51 + AspectC++/win-ac++.ico | Bin 0 -> 13094 bytes AspectC++/win-ac++.rc | 41 + Puma/.cproject | 57 + Puma/.project | 27 + Puma/COPYING | 340 + Puma/INSTALL | 87 + Puma/Makefile | 128 + Puma/README | 78 + Puma/TODO | 144 + Puma/doc/MindMaps/Puma-Parser.mm | 48 + Puma/doc/MindMaps/TemplatesParsen.mm | 20 + Puma/doc/RefMan/doxygen.conf | 2362 + Puma/doc/RefMan/layout.xml | 194 + Puma/doc/RefMan/logo.png | Bin 0 -> 6371 bytes Puma/doc/UsersManual/UsersManual.lyx | 27940 ++++++++++++ Puma/doc/UsersManual/UsersManual.pdf | 16096 +++++++ Puma/doc/lemon/lemon.html | 861 + Puma/examples/Makefile | 19 + Puma/examples/annotator/Makefile | 103 + Puma/examples/annotator/Transformer.cc | 62 + Puma/examples/annotator/Transformer.h | 47 + Puma/examples/annotator/annotator.cc | 105 + Puma/examples/annotator/example.cpp | 58 + Puma/examples/ccparser/IncludeVisitor.cc | 34 + Puma/examples/ccparser/IncludeVisitor.h | 33 + Puma/examples/ccparser/Makefile | 74 + Puma/examples/ccparser/ccparser.cc | 159 + Puma/examples/cparser/Makefile | 74 + Puma/examples/cparser/cparser.cc | 133 + Puma/examples/macronames/Makefile | 74 + Puma/examples/macronames/macronames.cc | 78 + Puma/examples/parser/Makefile | 73 + Puma/examples/parser/parser.cc | 606 + Puma/examples/sync/Makefile | 72 + Puma/examples/sync/README.txt | 134 + Puma/examples/sync/SyncBuilder.cc | 74 + Puma/examples/sync/SyncBuilder.h | 33 + Puma/examples/sync/SyncLexer.cc | 33 + Puma/examples/sync/SyncLexer.h | 36 + Puma/examples/sync/SyncParser.h | 50 + Puma/examples/sync/SyncSemantic.cc | 87 + Puma/examples/sync/SyncSemantic.h | 57 + Puma/examples/sync/SyncSyntax.cc | 102 + Puma/examples/sync/SyncSyntax.h | 51 + Puma/examples/sync/SyncTokens.h | 30 + Puma/examples/sync/SyncTransformer.cc | 146 + Puma/examples/sync/SyncTransformer.h | 56 + Puma/examples/sync/SyncTree.cc | 42 + Puma/examples/sync/SyncTree.h | 38 + Puma/examples/sync/sync.cc | 129 + Puma/extensions.mk | 166 + Puma/extern/README | 10 + Puma/extern/lexertl/bool.hpp | 22 + Puma/extern/lexertl/char_traits.hpp | 43 + Puma/extern/lexertl/compile_assert.hpp | 24 + Puma/extern/lexertl/containers/bitvector.hpp | 228 + Puma/extern/lexertl/containers/ptr_list.hpp | 69 + Puma/extern/lexertl/containers/ptr_map.hpp | 72 + Puma/extern/lexertl/containers/ptr_stack.hpp | 69 + Puma/extern/lexertl/containers/ptr_vector.hpp | 106 + Puma/extern/lexertl/debug.hpp | 324 + Puma/extern/lexertl/dot.hpp | 295 + Puma/extern/lexertl/enums.hpp | 25 + Puma/extern/lexertl/generate_cpp.hpp | 1122 + Puma/extern/lexertl/generator.hpp | 793 + Puma/extern/lexertl/internals.hpp | 80 + Puma/extern/lexertl/is_same.hpp | 28 + Puma/extern/lexertl/iterator.hpp | 123 + Puma/extern/lexertl/licence_1_0.txt | 24 + Puma/extern/lexertl/lookup.hpp | 477 + Puma/extern/lexertl/match_results.hpp | 166 + Puma/extern/lexertl/memory_file.hpp | 144 + Puma/extern/lexertl/narrow.hpp | 25 + Puma/extern/lexertl/old/fast_filebuf.hpp | 45 + Puma/extern/lexertl/old/string_token.hpp | 561 + Puma/extern/lexertl/parser/parser.hpp | 1030 + Puma/extern/lexertl/parser/tokeniser/re_token.hpp | 108 + .../lexertl/parser/tokeniser/re_tokeniser.hpp | 766 + .../parser/tokeniser/re_tokeniser_helper.hpp | 2417 ++ .../parser/tokeniser/re_tokeniser_state.hpp | 137 + Puma/extern/lexertl/parser/tree/end_node.hpp | 112 + Puma/extern/lexertl/parser/tree/iteration_node.hpp | 103 + Puma/extern/lexertl/parser/tree/leaf_node.hpp | 114 + Puma/extern/lexertl/parser/tree/node.hpp | 241 + Puma/extern/lexertl/parser/tree/selection_node.hpp | 105 + Puma/extern/lexertl/parser/tree/sequence_node.hpp | 126 + Puma/extern/lexertl/partition/charset.hpp | 73 + Puma/extern/lexertl/partition/equivset.hpp | 134 + Puma/extern/lexertl/rules.hpp | 1031 + Puma/extern/lexertl/runtime_error.hpp | 23 + Puma/extern/lexertl/serialise.hpp | 28 + Puma/extern/lexertl/size_t.hpp | 12 + Puma/extern/lexertl/sm_to_csm.hpp | 49 + Puma/extern/lexertl/sm_traits.hpp | 44 + Puma/extern/lexertl/state_machine.hpp | 532 + Puma/extern/lexertl/stream_shared_iterator.hpp | 350 + Puma/extern/lexertl/string_token.hpp | 421 + Puma/extern/lexertl/utf_iterators.hpp | 486 + Puma/files.mk | 304 + Puma/src/Makefile | 71 + Puma/src/aspects/CC1XTree.cc | 25 + Puma/src/aspects/CC1XTree.h | 79 + Puma/src/aspects/CCExprResolveCC.ah | 40 + Puma/src/aspects/CCExprResolveH.ah | 48 + Puma/src/aspects/CExprResolveCC.ah | 40 + Puma/src/aspects/CExprResolveH.ah | 48 + Puma/src/aspects/CMatchSyntax.ah | 599 + Puma/src/aspects/ExtAC.ah | 170 + Puma/src/aspects/ExtACTree.ah | 56 + Puma/src/aspects/ExtACTree.cc | 26 + Puma/src/aspects/ExtCC1X.ah | 147 + Puma/src/aspects/ExtCC1XBuilderCC.ah | 36 + Puma/src/aspects/ExtCC1XBuilderH.ah | 37 + Puma/src/aspects/ExtCC1XSemanticCC.ah | 79 + Puma/src/aspects/ExtCC1XSemanticH.ah | 36 + Puma/src/aspects/ExtCC1XSyntaxCC.ah | 40 + Puma/src/aspects/ExtCC1XSyntaxH.ah | 37 + Puma/src/aspects/ExtGnu.ah | 2820 ++ Puma/src/aspects/ExtGnuCInfos.ah | 95 + Puma/src/aspects/ExtGnuCSemDeclSpecs.ah | 32 + Puma/src/aspects/ExtGnuCSemExpr.ah | 214 + Puma/src/aspects/ExtGnuCSemantic.ah | 113 + Puma/src/aspects/ExtGnuCTree.ah | 164 + Puma/src/aspects/ExtGnuKeywords.ah | 176 + Puma/src/aspects/GenericProfiler.ah | 197 + Puma/src/aspects/PragmaOnce.ah | 98 + Puma/src/aspects/PragmaOnceUnitState.ah | 59 + Puma/src/aspects/Profiler.ah | 61 + Puma/src/aspects/TraceSyntax.ah | 174 + Puma/src/aspects/WinAsm.ah | 142 + Puma/src/aspects/WinDeclSpecs.ah | 130 + Puma/src/aspects/WinFriend.ah | 52 + Puma/src/aspects/WinIfExists.ah | 134 + Puma/src/aspects/WinImportHandler.ah | 65 + Puma/src/aspects/WinKeywords.ah | 76 + Puma/src/aspects/WinMacros.ah | 60 + Puma/src/aspects/WinMemberExplSpec.ah | 80 + Puma/src/aspects/WinTypeKeywords.ah | 42 + Puma/src/basics/Array.h | 356 + Puma/src/basics/BCList.h | 249 + Puma/src/basics/BCStack.h | 98 + Puma/src/basics/Chain.h | 69 + Puma/src/basics/ConstSizeMemPool.h | 146 + Puma/src/basics/DString.cc | 26 + Puma/src/basics/DString.h | 127 + Puma/src/basics/FdSource.h | 76 + Puma/src/basics/FileSource.h | 59 + Puma/src/basics/GPLHeader.cc | 27 + Puma/src/basics/Heap.cc | 161 + Puma/src/basics/Heap.h | 95 + Puma/src/basics/KeyboardSource.cc | 39 + Puma/src/basics/KeyboardSource.h | 43 + Puma/src/basics/Limits.h | 120 + Puma/src/basics/List.cc | 213 + Puma/src/basics/List.h | 148 + Puma/src/basics/ListElement.h | 64 + Puma/src/basics/MemPool.cc | 76 + Puma/src/basics/MemPool.h | 73 + Puma/src/basics/Pipe.cc | 75 + Puma/src/basics/Pipe.h | 69 + Puma/src/basics/PipedCmd.cc | 59 + Puma/src/basics/PipedCmd.h | 58 + Puma/src/basics/Printable.h | 71 + Puma/src/basics/PtrStack.h | 193 + Puma/src/basics/RegComp.cc | 85 + Puma/src/basics/RegComp.h | 80 + Puma/src/basics/Sink.h | 49 + Puma/src/basics/SmartPtr.h | 171 + Puma/src/basics/Source.h | 53 + Puma/src/basics/Stack.h | 70 + Puma/src/basics/StrCol.cc | 195 + Puma/src/basics/StrCol.h | 86 + Puma/src/basics/StrHashKey.h | 71 + Puma/src/basics/StrHashTable.cc | 78 + Puma/src/basics/StrHashTable.h | 69 + Puma/src/basics/StringSource.h | 84 + Puma/src/basics/SysCall.cc | 569 + Puma/src/basics/SysCall.h | 269 + Puma/src/basics/TerminalSink.cc | 29 + Puma/src/basics/TerminalSink.h | 44 + Puma/src/basics/TokenSource.h | 45 + Puma/src/basics/VerboseMgr.cc | 41 + Puma/src/basics/VerboseMgr.h | 87 + Puma/src/basics/VoidPtrArray.cc | 26 + Puma/src/basics/VoidPtrArray.h | 226 + Puma/src/basics/WChar.cc | 32 + Puma/src/basics/WChar.h | 42 + Puma/src/basics/version.h | 136 + Puma/src/common/ConfOption.h | 135 + Puma/src/common/Config.cc | 595 + Puma/src/common/Config.h | 381 + Puma/src/common/ErrorCollector.cc | 168 + Puma/src/common/ErrorCollector.h | 146 + Puma/src/common/ErrorSeverity.cc | 29 + Puma/src/common/ErrorSeverity.h | 120 + Puma/src/common/ErrorSink.cc | 27 + Puma/src/common/ErrorSink.h | 108 + Puma/src/common/ErrorStream.cc | 136 + Puma/src/common/ErrorStream.h | 134 + Puma/src/common/FileUnit.cc | 55 + Puma/src/common/FileUnit.h | 101 + Puma/src/common/Filename.h | 134 + Puma/src/common/FilenameInfo.cc | 107 + Puma/src/common/FilenameInfo.h | 78 + Puma/src/common/LanguageID.h | 60 + Puma/src/common/Location.h | 110 + Puma/src/common/MacroUnit.cc | 56 + Puma/src/common/MacroUnit.h | 102 + Puma/src/common/OptsParser.cc | 204 + Puma/src/common/OptsParser.h | 176 + Puma/src/common/ParserKey.h | 73 + Puma/src/common/PathInfo.cc | 74 + Puma/src/common/PathInfo.h | 79 + Puma/src/common/PathIterator.cc | 48 + Puma/src/common/PathIterator.h | 69 + Puma/src/common/PathManager.cc | 424 + Puma/src/common/PathManager.h | 227 + Puma/src/common/Project.cc | 462 + Puma/src/common/Project.h | 161 + Puma/src/common/ProjectFile.h | 80 + Puma/src/common/SaveMode.h | 44 + Puma/src/common/SimpleParser.cc | 98 + Puma/src/common/SimpleParser.h | 71 + Puma/src/common/Token.cc | 486 + Puma/src/common/Token.h | 314 + Puma/src/common/TokenStream.cc | 84 + Puma/src/common/TokenStream.h | 72 + Puma/src/common/Tokenizer.h | 47 + Puma/src/common/Unit.cc | 61 + Puma/src/common/Unit.h | 134 + Puma/src/common/UnitIterator.cc | 74 + Puma/src/common/UnitIterator.h | 76 + Puma/src/common/UnitManager.cc | 208 + Puma/src/common/UnitManager.h | 127 + Puma/src/common/UnitState.h | 78 + Puma/src/common/UnitTokenSrc.h | 95 + Puma/src/compile.mk | 98 + Puma/src/cpp/ImportHandler.cc | 131 + Puma/src/cpp/ImportHandler.h | 46 + Puma/src/cpp/PreAnswer.cc | 40 + Puma/src/cpp/PreAnswer.h | 45 + Puma/src/cpp/PreArgDesc.h | 54 + Puma/src/cpp/PreAssertionEvaluator.cc | 189 + Puma/src/cpp/PreAssertionEvaluator.h | 60 + Puma/src/cpp/PreExpr.h | 66 + Puma/src/cpp/PreExprLexer.h | 163 + Puma/src/cpp/PreExprParser.lem | 540 + Puma/src/cpp/PreFileIncluder.cc | 569 + Puma/src/cpp/PreFileIncluder.h | 127 + Puma/src/cpp/PreLevelState.h | 71 + Puma/src/cpp/PreMacro.cc | 133 + Puma/src/cpp/PreMacro.h | 107 + Puma/src/cpp/PreMacroExpander.cc | 944 + Puma/src/cpp/PreMacroExpander.h | 136 + Puma/src/cpp/PreMacroManager.cc | 185 + Puma/src/cpp/PreMacroManager.h | 86 + Puma/src/cpp/PreMacroOpTokens.h | 33 + Puma/src/cpp/PreParser.lem | 1726 + Puma/src/cpp/PreParserState.cc | 212 + Puma/src/cpp/PreParserState.h | 103 + Puma/src/cpp/PrePredicate.cc | 94 + Puma/src/cpp/PrePredicate.h | 60 + Puma/src/cpp/PrePredicateManager.cc | 56 + Puma/src/cpp/PrePredicateManager.h | 55 + Puma/src/cpp/PrePrintVisitor.cc | 449 + Puma/src/cpp/PrePrintVisitor.h | 135 + Puma/src/cpp/PreSemIterator.h | 48 + Puma/src/cpp/PreSonIterator.h | 48 + Puma/src/cpp/PreTree.cc | 83 + Puma/src/cpp/PreTree.h | 85 + Puma/src/cpp/PreTreeComposite.cc | 157 + Puma/src/cpp/PreTreeComposite.h | 95 + Puma/src/cpp/PreTreeIterator.h | 57 + Puma/src/cpp/PreTreeNodes.h | 767 + Puma/src/cpp/PreTreeToken.h | 63 + Puma/src/cpp/PreVisitor.h | 143 + Puma/src/cpp/PreprocessorParser.cc | 306 + Puma/src/cpp/PreprocessorParser.h | 212 + Puma/src/generate.mk | 40 + Puma/src/infos/CArgumentInfo.cc | 30 + Puma/src/infos/CArgumentInfo.h | 61 + Puma/src/infos/CAttributeInfo.cc | 66 + Puma/src/infos/CAttributeInfo.h | 112 + Puma/src/infos/CBaseClassInfo.cc | 54 + Puma/src/infos/CBaseClassInfo.h | 80 + Puma/src/infos/CCandidateInfo.h | 145 + Puma/src/infos/CClassDatabase.h | 36 + Puma/src/infos/CClassInfo.cc | 319 + Puma/src/infos/CClassInfo.h | 185 + Puma/src/infos/CClassInstance.h | 59 + Puma/src/infos/CEnumInfo.cc | 107 + Puma/src/infos/CEnumInfo.h | 115 + Puma/src/infos/CEnumeratorInfo.cc | 39 + Puma/src/infos/CEnumeratorInfo.h | 102 + Puma/src/infos/CFctInstance.cc | 37 + Puma/src/infos/CFctInstance.h | 63 + Puma/src/infos/CFileInfo.h | 96 + Puma/src/infos/CFunctionInfo.cc | 278 + Puma/src/infos/CFunctionInfo.h | 289 + Puma/src/infos/CLabelInfo.cc | 29 + Puma/src/infos/CLabelInfo.h | 49 + Puma/src/infos/CLocalScope.cc | 41 + Puma/src/infos/CLocalScope.h | 67 + Puma/src/infos/CMemberAliasInfo.cc | 29 + Puma/src/infos/CMemberAliasInfo.h | 64 + Puma/src/infos/CNamespaceInfo.cc | 28 + Puma/src/infos/CNamespaceInfo.h | 89 + Puma/src/infos/CObjectInfo.cc | 433 + Puma/src/infos/CObjectInfo.h | 825 + Puma/src/infos/CRecord.cc | 298 + Puma/src/infos/CRecord.h | 202 + Puma/src/infos/CScopeInfo.cc | 182 + Puma/src/infos/CScopeInfo.h | 218 + Puma/src/infos/CScopeRequest.h | 70 + Puma/src/infos/CSemDatabase.cc | 776 + Puma/src/infos/CSemDatabase.h | 259 + Puma/src/infos/CSourceInfo.cc | 121 + Puma/src/infos/CSourceInfo.h | 146 + Puma/src/infos/CStructure.cc | 641 + Puma/src/infos/CStructure.h | 387 + Puma/src/infos/CTemplateInfo.cc | 194 + Puma/src/infos/CTemplateInfo.h | 244 + Puma/src/infos/CTemplateInstance.cc | 48 + Puma/src/infos/CTemplateInstance.h | 236 + Puma/src/infos/CTemplateParamInfo.cc | 98 + Puma/src/infos/CTemplateParamInfo.h | 157 + Puma/src/infos/CTypedefInfo.cc | 30 + Puma/src/infos/CTypedefInfo.h | 50 + Puma/src/infos/CUnionInfo.cc | 38 + Puma/src/infos/CUnionInfo.h | 73 + Puma/src/infos/CUnionInstance.h | 59 + Puma/src/infos/CUsingInfo.cc | 29 + Puma/src/infos/CUsingInfo.h | 78 + Puma/src/infos/types/CTypeAddress.inc | 66 + Puma/src/infos/types/CTypeArray.inc | 146 + Puma/src/infos/types/CTypeBitField.inc | 77 + Puma/src/infos/types/CTypeClass.inc | 73 + Puma/src/infos/types/CTypeEnum.inc | 79 + Puma/src/infos/types/CTypeFunction.inc | 107 + Puma/src/infos/types/CTypeInfo.cc | 1143 + Puma/src/infos/types/CTypeInfo.h | 782 + Puma/src/infos/types/CTypeList.inc | 104 + Puma/src/infos/types/CTypeMemberPointer.inc | 82 + Puma/src/infos/types/CTypePointer.inc | 75 + Puma/src/infos/types/CTypePrimitive.inc | 143 + Puma/src/infos/types/CTypeQualified.inc | 124 + Puma/src/infos/types/CTypeRecord.inc | 105 + Puma/src/infos/types/CTypeTemplateParam.inc | 78 + Puma/src/infos/types/CTypeUnion.inc | 65 + Puma/src/infos/types/CTypeVarArray.inc | 61 + Puma/src/manip/CMatch.cc | 109 + Puma/src/manip/CMatch.h | 66 + Puma/src/manip/CMatchChecker.cc | 117 + Puma/src/manip/CMatchChecker.h | 54 + Puma/src/manip/CMatchParser.lem | 336 + Puma/src/manip/CSubMatch.cc | 30 + Puma/src/manip/CSubMatch.h | 50 + Puma/src/manip/CTreeMatcher.cc | 262 + Puma/src/manip/CTreeMatcher.h | 111 + Puma/src/manip/ManipCommander.cc | 376 + Puma/src/manip/ManipCommander.h | 103 + Puma/src/manip/ManipController.cc | 59 + Puma/src/manip/ManipController.h | 50 + Puma/src/manip/Manipulators.cc | 1087 + Puma/src/manip/Manipulators.h | 602 + Puma/src/manip/MatchCollector.cc | 135 + Puma/src/manip/MatchCollector.h | 62 + Puma/src/manip/Rule.h | 50 + Puma/src/manip/RuleTable.cc | 96 + Puma/src/manip/RuleTable.h | 61 + Puma/src/parser/Builder.cc | 76 + Puma/src/parser/Builder.h | 160 + Puma/src/parser/CConstant.cc | 305 + Puma/src/parser/CConstant.h | 145 + Puma/src/parser/CExprValue.h | 72 + Puma/src/parser/CSemObject.h | 50 + Puma/src/parser/CSemScope.h | 51 + Puma/src/parser/CSemValue.h | 100 + Puma/src/parser/CVisitor.cc | 63 + Puma/src/parser/CVisitor.h | 82 + Puma/src/parser/CWStrLiteral.h | 62 + Puma/src/parser/LookAhead.ah | 34 + Puma/src/parser/Parser.cc | 78 + Puma/src/parser/Parser.h | 83 + Puma/src/parser/Semantic.cc | 261 + Puma/src/parser/Semantic.h | 238 + Puma/src/parser/Syntax.cc | 309 + Puma/src/parser/Syntax.h | 606 + Puma/src/parser/SyntaxBuilder.ah | 51 + Puma/src/parser/SyntaxState.ah | 44 + Puma/src/parser/TokenProvider.h | 105 + Puma/src/parser/Tracing.cc | 64 + Puma/src/parser/Tracing.h | 84 + Puma/src/parser/acparser/ACIntroducer.h | 61 + Puma/src/parser/acparser/ACIntroducer_dummy.cc | 0 Puma/src/parser/ccparser/CCAssocScopes.cc | 206 + Puma/src/parser/ccparser/CCAssocScopes.h | 84 + Puma/src/parser/ccparser/CCBuilder.cc | 1407 + Puma/src/parser/ccparser/CCBuilder.h | 143 + Puma/src/parser/ccparser/CCBuilderExtension.ah | 690 + Puma/src/parser/ccparser/CCConvSeq.cc | 38 + Puma/src/parser/ccparser/CCConvSeq.h | 96 + Puma/src/parser/ccparser/CCConversion.cc | 129 + Puma/src/parser/ccparser/CCConversion.h | 262 + Puma/src/parser/ccparser/CCConversions.cc | 954 + Puma/src/parser/ccparser/CCConversions.h | 80 + Puma/src/parser/ccparser/CCExprResolveCC.ah | 40 + Puma/src/parser/ccparser/CCExprResolveH.ah | 50 + Puma/src/parser/ccparser/CCLookAhead.ah | 524 + Puma/src/parser/ccparser/CCNameLookup.cc | 624 + Puma/src/parser/ccparser/CCNameLookup.h | 179 + Puma/src/parser/ccparser/CCOverloading.cc | 1565 + Puma/src/parser/ccparser/CCOverloading.h | 179 + Puma/src/parser/ccparser/CCParser.h | 66 + Puma/src/parser/ccparser/CCSemBinding.ah | 328 + Puma/src/parser/ccparser/CCSemDeclarator.h | 36 + Puma/src/parser/ccparser/CCSemExpr.cc | 3825 ++ Puma/src/parser/ccparser/CCSemExpr.h | 171 + Puma/src/parser/ccparser/CCSemVisitor.cc | 662 + Puma/src/parser/ccparser/CCSemVisitor.h | 111 + Puma/src/parser/ccparser/CCSemantic.cc | 4734 +++ Puma/src/parser/ccparser/CCSemantic.h | 366 + Puma/src/parser/ccparser/CCSyntax.cc | 2475 ++ Puma/src/parser/ccparser/CCSyntax.h | 715 + Puma/src/parser/ccparser/DelayedParseTree.h | 213 + .../ccparser/instantiation/CCInstantiation.cc | 513 + .../ccparser/instantiation/CCInstantiation.h | 138 + .../ccparser/instantiation/DeducedArgument.cc | 100 + .../ccparser/instantiation/DeducedArgument.h | 89 + .../ccparser/instantiation/InstantiationBuilder.h | 35 + .../instantiation/InstantiationCandidate.cc | 1956 + .../instantiation/InstantiationCandidate.h | 190 + .../ccparser/instantiation/InstantiationParser.cc | 126 + .../ccparser/instantiation/InstantiationParser.h | 68 + .../instantiation/InstantiationSemantic.cc | 417 + .../ccparser/instantiation/InstantiationSemantic.h | 82 + .../ccparser/instantiation/InstantiationSyntax.cc | 182 + .../ccparser/instantiation/InstantiationSyntax.h | 250 + .../instantiation/InstantiationTokenProvider.cc | 37 + .../instantiation/InstantiationTokenProvider.h | 47 + .../instantiation/InstantiationTokenSource.cc | 92 + .../instantiation/InstantiationTokenSource.h | 54 + Puma/src/parser/cparser/CBuilder.cc | 1088 + Puma/src/parser/cparser/CBuilder.h | 159 + Puma/src/parser/cparser/CBuilderExtension.ah | 760 + Puma/src/parser/cparser/CExprResolveCC.ah | 40 + Puma/src/parser/cparser/CExprResolveH.ah | 50 + Puma/src/parser/cparser/CLanguage.h | 95 + Puma/src/parser/cparser/CLinkage.h | 55 + Puma/src/parser/cparser/CLookAhead.ah | 440 + Puma/src/parser/cparser/CParser.h | 59 + Puma/src/parser/cparser/CPrintVisitor.cc | 245 + Puma/src/parser/cparser/CPrintVisitor.h | 79 + Puma/src/parser/cparser/CProject.cc | 235 + Puma/src/parser/cparser/CProject.h | 96 + Puma/src/parser/cparser/CProtection.h | 51 + Puma/src/parser/cparser/CSemBinding.ah | 181 + Puma/src/parser/cparser/CSemDeclSpecs.cc | 528 + Puma/src/parser/cparser/CSemDeclSpecs.h | 128 + Puma/src/parser/cparser/CSemDeclarator.cc | 266 + Puma/src/parser/cparser/CSemDeclarator.h | 70 + Puma/src/parser/cparser/CSemExpr.cc | 2703 ++ Puma/src/parser/cparser/CSemExpr.h | 178 + Puma/src/parser/cparser/CSemVisitor.cc | 547 + Puma/src/parser/cparser/CSemVisitor.h | 98 + Puma/src/parser/cparser/CSemantic.cc | 1703 + Puma/src/parser/cparser/CSemantic.h | 178 + Puma/src/parser/cparser/CSpecifiers.h | 105 + Puma/src/parser/cparser/CStorage.h | 52 + Puma/src/parser/cparser/CStrLiteral.h | 62 + Puma/src/parser/cparser/CSyntax.cc | 1311 + Puma/src/parser/cparser/CSyntax.h | 678 + Puma/src/parser/cparser/CTokens.h | 504 + Puma/src/parser/cparser/CTranslationUnit.cc | 46 + Puma/src/parser/cparser/CTranslationUnit.h | 99 + Puma/src/parser/cparser/CTree.cc | 654 + Puma/src/parser/cparser/CTree.h | 4571 ++ Puma/src/parser/cparser/CUnit.cc | 35 + Puma/src/parser/cparser/CUnit.h | 79 + Puma/src/parser/cparser/GnuCTree.h | 408 + Puma/src/parser/cparser/Utf8.cc | 67 + Puma/src/parser/cparser/Utf8.h | 32 + Puma/src/parser/cparser/WinCTree.h | 76 + Puma/src/scanner/CCLexer.cc | 75 + Puma/src/scanner/CCLexer.h | 39 + Puma/src/scanner/CCommentTokens.h | 46 + Puma/src/scanner/CLexer.cc | 214 + Puma/src/scanner/CLexer.h | 119 + Puma/src/scanner/CLexerBuffer.h | 76 + Puma/src/scanner/CScanner.cc | 199 + Puma/src/scanner/CScanner.h | 94 + Puma/src/scanner/CWildcardTokens.h | 98 + Puma/src/scanner/Lexer.h | 81 + Puma/src/scanner/LexerBuffer.h | 73 + Puma/src/scanner/LexerMap.h | 41 + Puma/src/weave.mk | 103 + Puma/src/win32/Makefile | 19 + Puma/src/win32/ptmalloc/COPYRIGHT | 19 + Puma/src/win32/ptmalloc/ChangeLog | 227 + Puma/src/win32/ptmalloc/Makefile | 23 + Puma/src/win32/ptmalloc/README | 192 + Puma/src/win32/ptmalloc/lran2.h | 51 + Puma/src/win32/ptmalloc/ptmalloc.c | 4840 +++ Puma/src/win32/ptmalloc/ptmalloc.h | 203 + Puma/src/win32/ptmalloc/sbrk.cc | 131 + Puma/src/win32/ptmalloc/thread-m.h | 233 + Puma/src/win32/quirks/Makefile | 5 + Puma/src/win32/quirks/Win32Quirks.h | 38 + Puma/tests/Makefile | 101 + Puma/tests/Makefile.generic | 37 + Puma/tests/bug10/Makefile | 1 + Puma/tests/bug10/bug10.cc | 13 + Puma/tests/bug100/Makefile | 1 + Puma/tests/bug100/bug100.cc | 11 + Puma/tests/bug102/Makefile | 1 + Puma/tests/bug102/bug102.cc | 6 + Puma/tests/bug108/Makefile | 1 + Puma/tests/bug108/bug108.cc | 10 + Puma/tests/bug108/parse.ref | 0 Puma/tests/bug129/Makefile | 1 + Puma/tests/bug129/bug129.cc | 8 + Puma/tests/bug129/parse.ref | 0 Puma/tests/bug130/Makefile | 2 + Puma/tests/bug130/bug130.cc | 11 + Puma/tests/bug130/parse.ref | 0 Puma/tests/bug137/Makefile | 2 + Puma/tests/bug137/bug137.cc | 11 + Puma/tests/bug137/parse.ref | 0 Puma/tests/bug138/Makefile | 1 + Puma/tests/bug138/bug138.cc | 13 + Puma/tests/bug138/parse.ref | 0 Puma/tests/bug145/Makefile | 1 + Puma/tests/bug145/bug145.cc | 1 + Puma/tests/bug149/Makefile | 2 + Puma/tests/bug149/bug149.cc | 25 + Puma/tests/bug149/parse.ref | 0 Puma/tests/bug153/Makefile | 2 + Puma/tests/bug153/bug153.cc | 4 + Puma/tests/bug153/parse.ref | 0 Puma/tests/bug156/Makefile | 1 + Puma/tests/bug156/bug156.cc | 10 + Puma/tests/bug156/parse.ref | 0 Puma/tests/bug164/Makefile | 1 + Puma/tests/bug164/bug164.cc | 7 + Puma/tests/bug164/parse.ref | 0 Puma/tests/bug166/Makefile | 1 + Puma/tests/bug166/bug166.cc | 10 + Puma/tests/bug166/parse.ref | 1 + Puma/tests/bug180/Makefile | 1 + Puma/tests/bug180/bug180.cc | 19 + Puma/tests/bug180/parse.ref | 0 Puma/tests/bug182/Makefile | 1 + Puma/tests/bug182/bug182.cc | 12 + Puma/tests/bug182/parse.ref | 0 Puma/tests/bug187/Makefile | 1 + Puma/tests/bug187/bug187.cc | 10 + Puma/tests/bug188/Makefile | 1 + Puma/tests/bug188/bug188.cc | 4 + Puma/tests/bug189/Makefile | 1 + Puma/tests/bug189/bug189.cc | 5 + Puma/tests/bug2/Makefile | 1 + Puma/tests/bug2/bug2.cc | 6 + Puma/tests/bug2/parse.ref | 0 Puma/tests/bug203/Makefile | 2 + Puma/tests/bug203/bug203.cc | 17 + Puma/tests/bug203/parse.ref | 0 Puma/tests/bug218/Makefile | 1 + Puma/tests/bug218/bug218.cc | 10 + Puma/tests/bug218/parse.ref | 0 Puma/tests/bug220/Makefile | 1 + Puma/tests/bug220/bug220.cc | 2 + Puma/tests/bug232/Makefile | 2 + Puma/tests/bug232/bug232.cc | 9 + Puma/tests/bug248/Makefile | 1 + Puma/tests/bug248/bug248.cc | 18 + Puma/tests/bug248/parse.ref | 0 Puma/tests/bug249/Makefile | 1 + Puma/tests/bug249/bug249.cc | 5 + Puma/tests/bug258/Makefile | 2 + Puma/tests/bug258/bug258.cc | 13 + Puma/tests/bug259/Makefile | 1 + Puma/tests/bug259/bug259.cc | 22 + Puma/tests/bug259/parse.ref | 0 Puma/tests/bug264/Makefile | 1 + Puma/tests/bug264/bug264.cc | 5 + Puma/tests/bug269/Makefile | 1 + Puma/tests/bug269/bug269.cc | 7 + Puma/tests/bug269/parse.ref | 1 + Puma/tests/bug273/Makefile | 1 + Puma/tests/bug273/bug273.cc | 9 + Puma/tests/bug273/parse.ref | 0 Puma/tests/bug274/Makefile | 1 + Puma/tests/bug274/bug274.cc | 13 + Puma/tests/bug275/Makefile | 1 + Puma/tests/bug275/bug275.cc | 26 + Puma/tests/bug287/Makefile | 1 + Puma/tests/bug287/bug287.cc | 1 + Puma/tests/bug289/Makefile | 1 + Puma/tests/bug289/bug289.cc | 10 + Puma/tests/bug3/Makefile | 1 + Puma/tests/bug3/bug3.cc | 23 + Puma/tests/bug3/bug3_1.cc | 4 + Puma/tests/bug3/parse.ref | 1 + Puma/tests/bug303/Makefile | 2 + Puma/tests/bug303/bug303.cc | 1 + Puma/tests/bug305/Makefile | 2 + Puma/tests/bug305/bug305.cc | 5 + Puma/tests/bug307/Makefile | 1 + Puma/tests/bug307/bug307.cc | 7 + Puma/tests/bug320/Makefile | 1 + Puma/tests/bug320/bug320.cc | 7 + Puma/tests/bug320/parse.ref | 0 Puma/tests/bug325/Makefile | 1 + Puma/tests/bug325/bug325.cc | 4 + Puma/tests/bug326/Makefile | 1 + Puma/tests/bug326/bug326.cc | 4 + Puma/tests/bug326/parse.ref | 1 + Puma/tests/bug328/Makefile | 2 + Puma/tests/bug328/bug328.cc | 9 + Puma/tests/bug328/parse.ref | 0 Puma/tests/bug332/Makefile | 1 + Puma/tests/bug332/bug332.cc | 3 + Puma/tests/bug332/parse.ref | 1 + Puma/tests/bug333/Makefile | 2 + Puma/tests/bug333/bug333.cc | 10 + Puma/tests/bug333/parse.ref | 0 Puma/tests/bug337/Makefile | 2 + Puma/tests/bug337/bug337.cc | 10 + Puma/tests/bug337/parse.ref | 0 Puma/tests/bug338/Makefile | 1 + Puma/tests/bug338/bug338.cc | 6 + Puma/tests/bug339/Makefile | 2 + Puma/tests/bug339/bug339.cc | 14 + Puma/tests/bug339/parse.ref | 21 + Puma/tests/bug340/Makefile | 2 + Puma/tests/bug340/bug340-2.cc | 21 + Puma/tests/bug340/bug340-3.cc | 28 + Puma/tests/bug340/bug340-4.cc | 29 + Puma/tests/bug340/bug340-5.cc | 25 + Puma/tests/bug340/bug340.cc | 28 + Puma/tests/bug340/parse.ref | 7 + Puma/tests/bug342/Makefile | 1 + Puma/tests/bug342/bug342.cc | 5 + Puma/tests/bug343/Makefile | 2 + Puma/tests/bug343/test1.cc | 15 + Puma/tests/bug343/test2.cc | 15 + Puma/tests/bug344/Makefile | 1 + Puma/tests/bug344/bug344.cc | 1 + Puma/tests/bug344/parse.ref | 0 Puma/tests/bug345/Makefile | 2 + Puma/tests/bug345/bug345.cc | 7 + Puma/tests/bug345/parse.ref | 0 Puma/tests/bug346/Makefile | 2 + Puma/tests/bug346/bug346.cc | 8 + Puma/tests/bug346/parse.ref | 0 Puma/tests/bug347/Makefile | 2 + Puma/tests/bug347/bug347.cc | 10 + Puma/tests/bug348/Makefile | 1 + Puma/tests/bug348/bug348.cc | 15 + Puma/tests/bug350/Makefile | 2 + Puma/tests/bug350/bug350.cc | 27 + Puma/tests/bug350/parse.ref | 26 + Puma/tests/bug363/Makefile | 1 + Puma/tests/bug363/bug363.cc | 29 + Puma/tests/bug363/parse.ref | 0 Puma/tests/bug364/Makefile | 2 + Puma/tests/bug364/bug364.cc | 3 + Puma/tests/bug5/Makefile | 1 + Puma/tests/bug5/bug5.cc | 9 + Puma/tests/bug5/parse.ref | 0 Puma/tests/bug6/Makefile | 2 + Puma/tests/bug6/bug6.cc | 4 + Puma/tests/bug6/parse.ref | 0 Puma/tests/bug61/Makefile | 1 + Puma/tests/bug61/bug61.cc | 11 + Puma/tests/bug94/Makefile | 1 + Puma/tests/bug94/bug94.cc | 2 + Puma/tests/bug94/parse.ref | 0 Puma/tests/bug96/Makefile | 2 + Puma/tests/bug96/bug96.cc | 18 + Puma/tests/bug96/parse.ref | 0 Puma/tests/misc/Makefile | 1 + Puma/tests/misc/parse.ref | 5 + Puma/tests/misc/test1.cc | 18 + Puma/tests/misc/test10.cc | 20 + Puma/tests/misc/test11.cc | 18 + Puma/tests/misc/test12.cc | 18 + Puma/tests/misc/test13.cc | 18 + Puma/tests/misc/test14.cc | 20 + Puma/tests/misc/test15.cc | 15 + Puma/tests/misc/test16.cc | 16 + Puma/tests/misc/test17.cc | 12 + Puma/tests/misc/test18.cc | 23 + Puma/tests/misc/test19.cc | 27 + Puma/tests/misc/test2.cc | 12 + Puma/tests/misc/test20.cc | 13 + Puma/tests/misc/test21.cc | 15 + Puma/tests/misc/test22.cc | 31 + Puma/tests/misc/test3.cc | 15 + Puma/tests/misc/test4.cc | 13 + Puma/tests/misc/test5.cc | 17 + Puma/tests/misc/test6.cc | 14 + Puma/tests/misc/test7.cc | 20 + Puma/tests/misc/test8.cc | 19 + Puma/tests/misc/test9.cc | 19 + Puma/tools/EclipseCodeFormatterSettings.xml | 167 + Puma/tools/Makefile | 19 + Puma/tools/gen_vcpp_proj.sh | 181 + Puma/tools/lemon/Makefile | 6 + Puma/tools/lemon/README | 20 + Puma/tools/lemon/lemon.c | 5188 +++ Puma/tools/lemon/lemon.c.orig | 5179 +++ Puma/tools/lemon/lempar.c | 880 + Puma/tools/lemon/lempar.c.orig | 880 + Puma/tools/prof/Makefile | 5 + Puma/tools/prof/README | 39 + Puma/tools/prof/plot.py | 428 + Puma/vars.mk | 50 + README | 50 + 1632 files changed, 365175 insertions(+) create mode 100644 Ag++/.cproject create mode 100644 Ag++/.project create mode 100644 Ag++/ACCompiler.cc create mode 100644 Ag++/ACCompiler.h create mode 100644 Ag++/AGxxConfig.cc create mode 100644 Ag++/AGxxConfig.h create mode 100644 Ag++/CCompiler.cc create mode 100644 Ag++/CCompiler.h create mode 100644 Ag++/Compiler.h create mode 100644 Ag++/Makefile create mode 100644 Ag++/OptionVec.cc create mode 100644 Ag++/OptionVec.h create mode 100644 Ag++/PumaConfigFile.cc create mode 100644 Ag++/PumaConfigFile.h create mode 100644 Ag++/RegExCont.cc create mode 100644 Ag++/RegExCont.h create mode 100644 Ag++/StdSystem.cc create mode 100644 Ag++/StdSystem.h create mode 100644 Ag++/System.cc create mode 100644 Ag++/System.h create mode 100644 Ag++/TODO.txt create mode 100644 Ag++/ag++.cc create mode 100644 Ag++/doc/Ag++Manual/Ag++Manual.lyx create mode 100644 Ag++/doc/Ag++Manual/Ag++Manual.pdf create mode 100644 Ag++/doc/images/ac++logo.eps create mode 100644 Ag++/doc/images/ac++logo.pdf create mode 100644 Ag++/doc/styles/acc.sty create mode 100644 Ag++/file.cc create mode 100644 Ag++/file.h create mode 100644 Ag++/gpl.txt create mode 100644 Ag++/regex.cc create mode 100644 Ag++/regex.h create mode 100644 Ag++/tests/additional_aspects/trace2.ah create mode 100644 Ag++/tests/additional_includes/test_include.h create mode 100755 Ag++/tests/run_tests.sh create mode 100644 Ag++/tests/src/Makefile create mode 100644 Ag++/tests/src/Test.cc create mode 100644 Ag++/tests/src/Test.h create mode 100644 Ag++/tests/src/main.cc create mode 100644 Ag++/tests/src/trace.ah create mode 100644 Ag++/tests/test_01 create mode 100644 Ag++/tests/test_02 create mode 100644 Ag++/tests/test_03 create mode 100644 Ag++/tests/test_04 create mode 100644 Ag++/tests/test_05 create mode 100644 Ag++/tests/test_06 create mode 100644 Ag++/tests/test_07 create mode 100644 Ag++/tests/test_08 create mode 100644 Ag++/tests/test_09 create mode 100644 Ag++/tests/test_09.ref create mode 100644 Ag++/tests/test_10 create mode 100644 Ag++/tests/test_10.in create mode 100644 Ag++/tests/test_10.ref create mode 100644 Ag++/tests/test_11 create mode 100644 Ag++/tests/test_12 create mode 100644 Ag++/tests/test_13 create mode 100644 Ag++/tests/test_14 create mode 100644 Ag++/tests/test_15 create mode 100644 Ag++/tests/test_16 create mode 100644 Ag++/tests/test_17 create mode 100644 Ag++/tests/test_18 create mode 100644 Ag++/version.h create mode 100755 Ag++/win-ac++.ico create mode 100644 Ag++/win-ag++.rc create mode 100644 AspectC++/.cproject create mode 100644 AspectC++/.project create mode 100644 AspectC++/.settings/org.eclipse.ltk.core.refactoring.prefs create mode 100644 AspectC++/.settings/org.eclipse.wst.validation.prefs create mode 100644 AspectC++/ACConfig.cc create mode 100644 AspectC++/ACConfig.h create mode 100644 AspectC++/ACErrorStream.h create mode 100644 AspectC++/ACFileID.h create mode 100644 AspectC++/ACIntroducer.h create mode 100644 AspectC++/ACModel/Elements.cc create mode 100644 AspectC++/ACModel/Elements.h create mode 100644 AspectC++/ACModel/Makefile create mode 100644 AspectC++/ACModel/MatchExpr.cc create mode 100644 AspectC++/ACModel/MatchExpr.h create mode 100644 AspectC++/ACModel/MatchName.cc create mode 100644 AspectC++/ACModel/MatchName.h create mode 100644 AspectC++/ACModel/MatchTemplateArg.cc create mode 100644 AspectC++/ACModel/MatchTemplateArg.h create mode 100644 AspectC++/ACModel/MatchType.cc create mode 100644 AspectC++/ACModel/MatchType.h create mode 100644 AspectC++/ACModel/MatchTypeInfos.cc create mode 100644 AspectC++/ACModel/MatchTypeInfos.h create mode 100644 AspectC++/ACModel/ModelNode.h create mode 100644 AspectC++/ACModel/Utils.cc create mode 100644 AspectC++/ACModel/Utils.h create mode 100644 AspectC++/ACModel/XmlModelReader.cc create mode 100644 AspectC++/ACModel/XmlModelReader.h create mode 100644 AspectC++/ACModel/XmlModelWriter.h create mode 100644 AspectC++/ACPreprocessor.h create mode 100644 AspectC++/ACProject.cc create mode 100644 AspectC++/ACProject.h create mode 100644 AspectC++/ACResultBuffer.h create mode 100644 AspectC++/ACToken.h create mode 100644 AspectC++/ACUnit.h create mode 100644 AspectC++/AdviceInfo.cc create mode 100644 AspectC++/AdviceInfo.h create mode 100644 AspectC++/AdviceRepo.cc create mode 100644 AspectC++/AdviceRepo.h create mode 100644 AspectC++/AspectIncludeCluster.h create mode 100644 AspectC++/AspectIncludes.cc create mode 100644 AspectC++/AspectIncludes.h create mode 100644 AspectC++/AspectInfo.cc create mode 100644 AspectC++/AspectInfo.h create mode 100644 AspectC++/AspectRepo.cc create mode 100644 AspectC++/AspectRepo.h create mode 100644 AspectC++/BackEndProblems.h create mode 100644 AspectC++/Binding.cc create mode 100644 AspectC++/Binding.h create mode 100644 AspectC++/CFlow.cc create mode 100644 AspectC++/CFlow.h create mode 100644 AspectC++/ClangASTConsumer.cc create mode 100644 AspectC++/ClangASTConsumer.h create mode 100644 AspectC++/ClangAdjustedTypePrinter.cc create mode 100644 AspectC++/ClangAdjustedTypePrinter.h create mode 100644 AspectC++/ClangAnnotation.cc create mode 100644 AspectC++/ClangAnnotation.h create mode 100644 AspectC++/ClangBinding.cc create mode 100644 AspectC++/ClangBinding.h create mode 100644 AspectC++/ClangErrorStream.h create mode 100644 AspectC++/ClangFlowAnalysis.cc create mode 100644 AspectC++/ClangFlowAnalysis.h create mode 100644 AspectC++/ClangIncludeExpander.cc create mode 100644 AspectC++/ClangIncludeExpander.h create mode 100644 AspectC++/ClangInclusionRewriter.cc create mode 100644 AspectC++/ClangInclusionRewriter.h create mode 100644 AspectC++/ClangIntroParser.cc create mode 100644 AspectC++/ClangIntroParser.h create mode 100644 AspectC++/ClangIntroSema.cc create mode 100644 AspectC++/ClangIntroSema.h create mode 100644 AspectC++/ClangIntroducer.cc create mode 100644 AspectC++/ClangIntroducer.h create mode 100644 AspectC++/ClangModelBuilder.cc create mode 100644 AspectC++/ClangModelBuilder.h create mode 100644 AspectC++/ClangPreprocessor.cc create mode 100644 AspectC++/ClangPreprocessor.h create mode 100644 AspectC++/ClangResultBuffer.cc create mode 100644 AspectC++/ClangResultBuffer.h create mode 100644 AspectC++/ClangSyntacticContext.cc create mode 100644 AspectC++/ClangSyntacticContext.h create mode 100644 AspectC++/ClangToken.h create mode 100644 AspectC++/ClangTransformInfo.h create mode 100644 AspectC++/ClangWeaverBase.cc create mode 100644 AspectC++/ClangWeaverBase.h create mode 100644 AspectC++/CodeWeaver.cc create mode 100644 AspectC++/CodeWeaver.h create mode 100644 AspectC++/Condition.cc create mode 100644 AspectC++/Condition.h create mode 100644 AspectC++/FileRepo.cc create mode 100644 AspectC++/FileRepo.h create mode 100644 AspectC++/IncludeExpander.h create mode 100644 AspectC++/IncludeGraph.cc create mode 100644 AspectC++/IncludeGraph.h create mode 100644 AspectC++/IntroductionInfo.h create mode 100644 AspectC++/IntroductionUnit.h create mode 100644 AspectC++/JoinPoint.cc create mode 100644 AspectC++/JoinPoint.h create mode 100644 AspectC++/JoinPointModelElement.h create mode 100644 AspectC++/JoinPointRepo.cc create mode 100644 AspectC++/JoinPointRepo.h create mode 100644 AspectC++/LineDirectiveMgr.cc create mode 100644 AspectC++/LineDirectiveMgr.h create mode 100644 AspectC++/Makefile create mode 100644 AspectC++/ModelBuilder.h create mode 100644 AspectC++/NamespaceAC.cc create mode 100644 AspectC++/NamespaceAC.h create mode 100644 AspectC++/Naming.cc create mode 100644 AspectC++/Naming.h create mode 100644 AspectC++/OrderInfo.h create mode 100644 AspectC++/OrderPlanner.h create mode 100644 AspectC++/Phase1.cc create mode 100644 AspectC++/Phase1.h create mode 100644 AspectC++/Plan.cc create mode 100644 AspectC++/Plan.h create mode 100644 AspectC++/PointCut.cc create mode 100644 AspectC++/PointCut.h create mode 100644 AspectC++/PointCutContext.cc create mode 100644 AspectC++/PointCutContext.h create mode 100644 AspectC++/PointCutExpr.cc create mode 100644 AspectC++/PointCutExpr.h create mode 100644 AspectC++/PointCutExprParser.cc create mode 100644 AspectC++/PointCutExprParser.h create mode 100644 AspectC++/PointCutSearcher.h create mode 100644 AspectC++/PumaIncludeExpander.cc create mode 100644 AspectC++/PumaIncludeExpander.h create mode 100644 AspectC++/PumaIntroducer.cc create mode 100644 AspectC++/PumaIntroducer.h create mode 100644 AspectC++/PumaModelBuilder.cc create mode 100644 AspectC++/PumaModelBuilder.h create mode 100644 AspectC++/PumaPreprocessor.cc create mode 100644 AspectC++/PumaPreprocessor.h create mode 100644 AspectC++/PumaResultBuffer.cc create mode 100644 AspectC++/PumaResultBuffer.h create mode 100644 AspectC++/PumaSyntacticContext.cc create mode 100644 AspectC++/PumaSyntacticContext.h create mode 100644 AspectC++/PumaToken.h create mode 100644 AspectC++/PumaTrackerDog.cc create mode 100644 AspectC++/PumaTrackerDog.h create mode 100644 AspectC++/PumaTransformInfo.h create mode 100644 AspectC++/PumaWeaverBase.cc create mode 100644 AspectC++/PumaWeaverBase.h create mode 100644 AspectC++/README create mode 100644 AspectC++/README-Puma create mode 100644 AspectC++/RepoIdMgr.h create mode 100644 AspectC++/RepoNameKey.h create mode 100644 AspectC++/RepoPosAspectKey.cc create mode 100644 AspectC++/RepoPosAspectKey.h create mode 100644 AspectC++/RepoPosKey.cc create mode 100644 AspectC++/RepoPosKey.h create mode 100644 AspectC++/RepoXMLDoc.h create mode 100644 AspectC++/RepoXMLNode.cc create mode 100644 AspectC++/RepoXMLNode.h create mode 100644 AspectC++/Repository.cc create mode 100644 AspectC++/Repository.h create mode 100644 AspectC++/SourceLoc.h create mode 100644 AspectC++/SyntacticContext.h create mode 100644 AspectC++/TODO create mode 100644 AspectC++/ThisJoinPoint.cc create mode 100644 AspectC++/ThisJoinPoint.h create mode 100644 AspectC++/TransformInfo.h create mode 100644 AspectC++/Transformer.cc create mode 100644 AspectC++/Transformer.h create mode 100644 AspectC++/Weaver.cc create mode 100644 AspectC++/Weaver.h create mode 100644 AspectC++/WeaverBase.h create mode 100644 AspectC++/ac++.cc create mode 100644 AspectC++/akut-trigger.tmp create mode 100644 AspectC++/clang-3.4-disable-modules.patch create mode 100644 AspectC++/config/Makefile create mode 100644 AspectC++/config/clang-3.5.0.mk create mode 100644 AspectC++/config/clang-3.5.0svn.mk create mode 100644 AspectC++/config/clang-3.6.2.mk create mode 100644 AspectC++/config/clang-3.7.1.mk create mode 100644 AspectC++/config/clang-3.8.0.mk create mode 100644 AspectC++/config/clang-3.8.1.mk create mode 100644 AspectC++/config/clang-3.9.1.mk create mode 100644 AspectC++/config/clang-4.0.0.mk create mode 100644 AspectC++/config/clang-4.0.1.mk create mode 100644 AspectC++/config/clang-5.0.0svn.mk create mode 100644 AspectC++/config/clang.mk create mode 100644 AspectC++/doc/CompilerManual/ac-compilerman.lyx create mode 120000 AspectC++/doc/CompilerManual/images create mode 100644 AspectC++/doc/LanguageReference/ac-languageref-ru.odt create mode 100644 AspectC++/doc/LanguageReference/ac-languageref-ru.pdf create mode 100644 AspectC++/doc/LanguageReference/ac-languageref.lyx create mode 120000 AspectC++/doc/LanguageReference/images create mode 100644 AspectC++/doc/Makefile create mode 100644 AspectC++/doc/NoE_ExecModelSurvey/ac++exec-survey.lyx create mode 100644 AspectC++/doc/NoE_ExecModelSurvey/ac++exec-survey.pdf create mode 100644 AspectC++/doc/NoE_ShortSurvey/ac++lang-survey.lyx create mode 100644 AspectC++/doc/NoE_ShortSurvey/ac++lang-survey.pdf create mode 100644 AspectC++/doc/ProgrammingGuide/ProgrammingGuide.lyx create mode 100644 AspectC++/doc/QuickRef/ac++quickref.lyx create mode 100644 AspectC++/doc/QuickRef/ac++quickref.pdf create mode 100644 AspectC++/doc/Tutorial/1-intro.odp create mode 100644 AspectC++/doc/Tutorial/1-intro.pdf create mode 100644 AspectC++/doc/Tutorial/2-language.odp create mode 100644 AspectC++/doc/Tutorial/2-language.pdf create mode 100644 AspectC++/doc/Tutorial/3-tools.odp create mode 100644 AspectC++/doc/Tutorial/3-tools.pdf create mode 100644 AspectC++/doc/Tutorial/4-examples.odp create mode 100644 AspectC++/doc/Tutorial/4-examples.pdf create mode 100644 AspectC++/doc/Tutorial/5-summary.odp create mode 100644 AspectC++/doc/Tutorial/5-summary.pdf create mode 100644 AspectC++/doc/Tutorial/README-JOIN create mode 100644 AspectC++/doc/Tutorial/ac-tutorial.pdf create mode 100644 AspectC++/doc/doxygen.conf create mode 100644 AspectC++/doc/gen/ac++logo.png create mode 100644 AspectC++/doc/gen/ac-manual.css create mode 100644 AspectC++/doc/gen/fixhtml.xsl create mode 100644 AspectC++/doc/images/JoinPointModel.eps create mode 100644 AspectC++/doc/images/JoinPointModel.fig create mode 100644 AspectC++/doc/images/JoinPointModel.pdf create mode 100644 AspectC++/doc/images/JoinPointModelNew.eps create mode 100644 AspectC++/doc/images/JoinPointModelNew.odg create mode 100644 AspectC++/doc/images/JoinPointModelNew.pdf create mode 100644 AspectC++/doc/images/ReadMe.txt create mode 100644 AspectC++/doc/images/ac++logo.eps create mode 100644 AspectC++/doc/images/ac++logo.pdf create mode 100644 AspectC++/doc/images/acmodel-rotated90.pdf create mode 100644 AspectC++/doc/images/acmodel.dot create mode 100644 AspectC++/doc/images/acmodel.eps create mode 100644 AspectC++/doc/images/acmodel.pdf create mode 100644 AspectC++/doc/images/acmodel_inheri_only_less.dot create mode 100644 AspectC++/doc/images/acmodel_inheri_only_less.eps create mode 100644 AspectC++/doc/images/acmodel_inheri_only_less.pdf create mode 100644 AspectC++/doc/images/include_cycle.eps create mode 100644 AspectC++/doc/images/include_cycle.odg create mode 100644 AspectC++/doc/images/no_include_cycle.eps create mode 100644 AspectC++/doc/images/no_include_cycle.odg create mode 100644 AspectC++/doc/images/peanut.png create mode 100644 AspectC++/doc/images/peanut.xcf create mode 100644 AspectC++/doc/images/ps-logo.eps create mode 100644 AspectC++/doc/images/ps-logo.pdf create mode 100644 AspectC++/doc/images/ps-logo.png create mode 100644 AspectC++/doc/styles/pure-systems.sty create mode 100644 AspectC++/examples/Makefile.generic create mode 100644 AspectC++/examples/coverage/Makefile create mode 100644 AspectC++/examples/coverage/coverage.ah create mode 100644 AspectC++/examples/coverage/main.cc create mode 100644 AspectC++/examples/coverage/mycoverage.ah create mode 100644 AspectC++/examples/helloworld/Makefile create mode 100644 AspectC++/examples/helloworld/hello.h create mode 100644 AspectC++/examples/helloworld/main.cc create mode 100644 AspectC++/examples/helloworld/world.ah create mode 100644 AspectC++/examples/modules/Makefile create mode 100644 AspectC++/examples/modules/Module0.ah create mode 100644 AspectC++/examples/modules/Module0.h create mode 100644 AspectC++/examples/modules/Module1.ah create mode 100644 AspectC++/examples/modules/Module1.h create mode 100644 AspectC++/examples/modules/Modules.h create mode 100644 AspectC++/examples/modules/main.cc create mode 100644 AspectC++/examples/profiling/Makefile create mode 100644 AspectC++/examples/profiling/genericprofiler.ah create mode 100644 AspectC++/examples/profiling/main.cc create mode 100644 AspectC++/examples/profiling/profiler.ah create mode 100644 AspectC++/examples/singleton/Makefile create mode 100644 AspectC++/examples/singleton/falsefriend.h create mode 100644 AspectC++/examples/singleton/main.cc create mode 100644 AspectC++/examples/singleton/mysingletonmonitor.ah create mode 100644 AspectC++/examples/singleton/singleton.h create mode 100644 AspectC++/examples/singleton/singletonmonitor.ah create mode 100644 AspectC++/examples/threads/Log.h create mode 100644 AspectC++/examples/threads/Makefile create mode 100644 AspectC++/examples/threads/SynchronizedLog.ah create mode 100644 AspectC++/examples/threads/ThreadSafeLogging.ah create mode 100644 AspectC++/examples/threads/main.cc create mode 100644 AspectC++/infos.h create mode 100644 AspectC++/tests/AbstractDerivedAspect/Makefile create mode 100644 AspectC++/tests/AbstractDerivedAspect/feature.ref create mode 100644 AspectC++/tests/AbstractDerivedAspect/main.cc create mode 100644 AspectC++/tests/AccessControl/Makefile create mode 100644 AspectC++/tests/AccessControl/feature.ref create mode 100644 AspectC++/tests/AccessControl/main.cc create mode 100644 AspectC++/tests/Advice/Aspect.ah create mode 100644 AspectC++/tests/Advice/Makefile create mode 100644 AspectC++/tests/Advice/feature.ref create mode 100644 AspectC++/tests/Advice/main.cc create mode 100644 AspectC++/tests/AdviceVirtualFct/Aspect.ah create mode 100644 AspectC++/tests/AdviceVirtualFct/Makefile create mode 100644 AspectC++/tests/AdviceVirtualFct/feature.ref create mode 100644 AspectC++/tests/AdviceVirtualFct/main.cc create mode 100644 AspectC++/tests/AnonymousStuff/Makefile create mode 100644 AspectC++/tests/AnonymousStuff/feature.ref create mode 100644 AspectC++/tests/AnonymousStuff/main.cc create mode 100644 AspectC++/tests/ArrayAccessAdvice/Makefile create mode 100644 AspectC++/tests/ArrayAccessAdvice/around.ah create mode 100644 AspectC++/tests/ArrayAccessAdvice/feature.ref create mode 100644 AspectC++/tests/ArrayAccessAdvice/idx.ah create mode 100644 AspectC++/tests/ArrayAccessAdvice/main.cc create mode 100644 AspectC++/tests/ArrayAccessAdvice/namemap.cc create mode 100644 AspectC++/tests/ArrayAccessAdvice/namemap.h create mode 100644 AspectC++/tests/ArrayAccessAdvice/trace.ah create mode 100644 AspectC++/tests/ArrayMangling/Makefile create mode 100644 AspectC++/tests/ArrayMangling/feature.ref create mode 100644 AspectC++/tests/ArrayMangling/main.cc create mode 100644 AspectC++/tests/ArrayWrapper/Makefile create mode 100644 AspectC++/tests/ArrayWrapper/feature.ref create mode 100644 AspectC++/tests/ArrayWrapper/main.cc create mode 100644 AspectC++/tests/AspectOf/Makefile create mode 100644 AspectC++/tests/AspectOf/feature.ref create mode 100644 AspectC++/tests/AspectOf/main.cc create mode 100644 AspectC++/tests/AspectPrivileges/Makefile create mode 100644 AspectC++/tests/AspectPrivileges/feature.ref create mode 100644 AspectC++/tests/AspectPrivileges/main.cc create mode 100644 AspectC++/tests/AttribAligned/Makefile create mode 100644 AspectC++/tests/AttribAligned/feature.ref create mode 100644 AspectC++/tests/AttribAligned/main.cc create mode 100644 AspectC++/tests/Attribute_basic/Makefile create mode 100644 AspectC++/tests/Attribute_basic/feature.ref create mode 100644 AspectC++/tests/Attribute_basic/main.cc create mode 100644 AspectC++/tests/Attribute_inMacro/Makefile create mode 100644 AspectC++/tests/Attribute_inMacro/feature.ref create mode 100644 AspectC++/tests/Attribute_inMacro/main.cc create mode 100644 AspectC++/tests/Attribute_pointcuts/Makefile create mode 100644 AspectC++/tests/Attribute_pointcuts/Test.ah create mode 100644 AspectC++/tests/Attribute_pointcuts/feature.ref create mode 100644 AspectC++/tests/Attribute_pointcuts/main.cc create mode 100644 AspectC++/tests/Attribute_removeAttrs/Makefile create mode 100644 AspectC++/tests/Attribute_removeAttrs/feature.ref create mode 100644 AspectC++/tests/Attribute_removeAttrs/main.cc create mode 100644 AspectC++/tests/Base/Makefile create mode 100644 AspectC++/tests/Base/feature.ref create mode 100644 AspectC++/tests/Base/main.cc create mode 100644 AspectC++/tests/Bug-Typenames/Makefile create mode 100644 AspectC++/tests/Bug-Typenames/feature.ref create mode 100644 AspectC++/tests/Bug-Typenames/main.cc create mode 100644 AspectC++/tests/Bug179/Makefile create mode 100644 AspectC++/tests/Bug179/feature.ref create mode 100644 AspectC++/tests/Bug179/main.cc create mode 100644 AspectC++/tests/Bug190/Makefile create mode 100644 AspectC++/tests/Bug190/feature.ref create mode 100644 AspectC++/tests/Bug190/main.cc create mode 100644 AspectC++/tests/Bug191/Makefile create mode 100644 AspectC++/tests/Bug191/feature.ref create mode 100644 AspectC++/tests/Bug191/main.cc create mode 100644 AspectC++/tests/Bug192/Makefile create mode 100644 AspectC++/tests/Bug192/feature.ref create mode 100644 AspectC++/tests/Bug192/main.cc create mode 100644 AspectC++/tests/Bug207/Makefile create mode 100644 AspectC++/tests/Bug207/feature.ref create mode 100644 AspectC++/tests/Bug207/main.cc create mode 100644 AspectC++/tests/Bug209/AbstractTrace.ah create mode 100644 AspectC++/tests/Bug209/Makefile create mode 100644 AspectC++/tests/Bug209/feature.ref create mode 100644 AspectC++/tests/Bug209/main.cc create mode 100644 AspectC++/tests/Bug216/Makefile create mode 100644 AspectC++/tests/Bug216/feature.ref create mode 100644 AspectC++/tests/Bug216/main.cc create mode 100644 AspectC++/tests/Bug228/Makefile create mode 100644 AspectC++/tests/Bug228/feature.ref create mode 100644 AspectC++/tests/Bug228/main.cc create mode 100644 AspectC++/tests/Bug234-2/Makefile create mode 100644 AspectC++/tests/Bug234-2/feature.ref create mode 100644 AspectC++/tests/Bug234-2/introTarget.cc create mode 100644 AspectC++/tests/Bug234-2/introTarget.hxx create mode 100644 AspectC++/tests/Bug234-2/main.cc create mode 100644 AspectC++/tests/Bug234-2/myAspect.ah create mode 100644 AspectC++/tests/Bug234/Makefile create mode 100644 AspectC++/tests/Bug234/anotherAspect.ah create mode 100644 AspectC++/tests/Bug234/feature.ref create mode 100644 AspectC++/tests/Bug234/introTarget.cc create mode 100644 AspectC++/tests/Bug234/introTarget.h create mode 100644 AspectC++/tests/Bug234/main.cc create mode 100644 AspectC++/tests/Bug234/myAspect.ah create mode 100644 AspectC++/tests/Bug234/mySlice.ah create mode 100644 AspectC++/tests/Bug235/Makefile create mode 100644 AspectC++/tests/Bug235/abstractTrace.ah create mode 100644 AspectC++/tests/Bug235/classA.h create mode 100644 AspectC++/tests/Bug235/classB.h create mode 100644 AspectC++/tests/Bug235/concreteTraceA.ah create mode 100644 AspectC++/tests/Bug235/concreteTraceB.ah create mode 100644 AspectC++/tests/Bug235/feature.ref create mode 100644 AspectC++/tests/Bug235/main.cc create mode 100644 AspectC++/tests/Bug239/Makefile create mode 100644 AspectC++/tests/Bug239/feature.ref create mode 100644 AspectC++/tests/Bug239/main.cc create mode 100644 AspectC++/tests/Bug242/Makefile create mode 100644 AspectC++/tests/Bug242/OutputStream.h create mode 100644 AspectC++/tests/Bug242/Padding.ah create mode 100644 AspectC++/tests/Bug242/feature.ref create mode 100644 AspectC++/tests/Bug242/main.cc create mode 100644 AspectC++/tests/Bug267/Makefile create mode 100644 AspectC++/tests/Bug267/feature.ref create mode 100644 AspectC++/tests/Bug267/main.cc create mode 100644 AspectC++/tests/Bug268/Makefile create mode 100644 AspectC++/tests/Bug268/feature.ref create mode 100644 AspectC++/tests/Bug268/main.cc create mode 100644 AspectC++/tests/Bug271/Makefile create mode 100644 AspectC++/tests/Bug271/feature.ref create mode 100644 AspectC++/tests/Bug271/main.cc create mode 100644 AspectC++/tests/Bug293/ArgumentSizeCalculator.h create mode 100644 AspectC++/tests/Bug293/Callee.h create mode 100644 AspectC++/tests/Bug293/Derived.cc create mode 100644 AspectC++/tests/Bug293/Derived.h create mode 100644 AspectC++/tests/Bug293/Makefile create mode 100644 AspectC++/tests/Bug293/SaveStack.h create mode 100644 AspectC++/tests/Bug293/doMeasurement.h create mode 100644 AspectC++/tests/Bug293/dynamic.cc create mode 100644 AspectC++/tests/Bug293/measure.ah create mode 100644 AspectC++/tests/Bug293/measureAspect.ah create mode 100644 AspectC++/tests/Bug293/target.ah create mode 100644 AspectC++/tests/Bug316/Makefile create mode 100644 AspectC++/tests/Bug316/feature.ref create mode 100644 AspectC++/tests/Bug316/main.cc create mode 100644 AspectC++/tests/Bug321/Makefile create mode 100644 AspectC++/tests/Bug321/feature.ref create mode 100644 AspectC++/tests/Bug321/main.cc create mode 100644 AspectC++/tests/Bug323/A0.ah create mode 100644 AspectC++/tests/Bug323/A1.ah create mode 100644 AspectC++/tests/Bug323/A2.ah create mode 100644 AspectC++/tests/Bug323/Makefile create mode 100644 AspectC++/tests/Bug323/feature.ref create mode 100644 AspectC++/tests/Bug323/header.h create mode 100644 AspectC++/tests/Bug323/main.cc create mode 100644 AspectC++/tests/Bug336/Makefile create mode 100644 AspectC++/tests/Bug336/feature.ref create mode 100644 AspectC++/tests/Bug336/main.cc create mode 100644 AspectC++/tests/Bug353/Makefile create mode 100644 AspectC++/tests/Bug353/feature.ref create mode 100644 AspectC++/tests/Bug353/main.cc create mode 100644 AspectC++/tests/Bug368/Makefile create mode 100644 AspectC++/tests/Bug368/feature.ref create mode 100644 AspectC++/tests/Bug368/main.cc create mode 100644 AspectC++/tests/Bug418/Makefile create mode 100644 AspectC++/tests/Bug418/falsefriend.h create mode 100644 AspectC++/tests/Bug418/feature.ref create mode 100644 AspectC++/tests/Bug418/main.cc create mode 100644 AspectC++/tests/Bug418/mysingletonmonitor.ah create mode 100644 AspectC++/tests/Bug418/singleton.h create mode 100644 AspectC++/tests/Bug418/singletonmonitor.ah create mode 100644 AspectC++/tests/Bug427/Makefile create mode 100644 AspectC++/tests/Bug427/feature.ref create mode 100644 AspectC++/tests/Bug427/main.cc create mode 100644 AspectC++/tests/Bug477/Makefile create mode 100644 AspectC++/tests/Bug477/feature.ref create mode 100644 AspectC++/tests/Bug477/main.cc create mode 100644 AspectC++/tests/Bug484/Makefile create mode 100644 AspectC++/tests/Bug484/feature.ref create mode 100644 AspectC++/tests/Bug484/main.cc create mode 100644 AspectC++/tests/Bug512/Makefile create mode 100644 AspectC++/tests/Bug512/feature.ref create mode 100644 AspectC++/tests/Bug512/main.cc create mode 100644 AspectC++/tests/Bug524/Makefile create mode 100644 AspectC++/tests/Bug524/feature.ref create mode 100644 AspectC++/tests/Bug524/main.cc create mode 100644 AspectC++/tests/Bug548/Makefile create mode 100644 AspectC++/tests/Bug548/feature.ref create mode 100644 AspectC++/tests/Bug548/main.cc create mode 100644 AspectC++/tests/Bug549/Makefile create mode 100644 AspectC++/tests/Bug549/feature.ref create mode 100644 AspectC++/tests/Bug549/main.cc create mode 100644 AspectC++/tests/Bug552/Makefile create mode 100644 AspectC++/tests/Bug552/Mem.h create mode 100644 AspectC++/tests/Bug552/feature.ref create mode 100644 AspectC++/tests/Bug552/file1.cc create mode 100644 AspectC++/tests/Bug552/file2.cc create mode 100644 AspectC++/tests/Bug552/file3.cc create mode 100644 AspectC++/tests/Bug554/Makefile create mode 100644 AspectC++/tests/Bug554/feature.ref create mode 100644 AspectC++/tests/Bug554/main.cc create mode 100644 AspectC++/tests/Bug561/Makefile create mode 100644 AspectC++/tests/Bug561/feature.ref create mode 100644 AspectC++/tests/Bug561/main.cc create mode 100644 AspectC++/tests/Bug561/slice.ah create mode 100644 AspectC++/tests/Bug564/Makefile create mode 100644 AspectC++/tests/Bug564/feature.ref create mode 100644 AspectC++/tests/Bug564/main.cc create mode 100644 AspectC++/tests/Bug564/random_header.h create mode 100644 AspectC++/tests/Bug566/Makefile create mode 100644 AspectC++/tests/Bug566/feature.ref create mode 100644 AspectC++/tests/Bug566/main.cc create mode 100644 AspectC++/tests/Bug567/Makefile create mode 100644 AspectC++/tests/Bug567/feature.ref create mode 100644 AspectC++/tests/Bug567/main.cc create mode 100644 AspectC++/tests/Bug568/Makefile create mode 100644 AspectC++/tests/Bug568/feature.ref create mode 100644 AspectC++/tests/Bug568/main.cc create mode 100644 AspectC++/tests/Bug570/Makefile create mode 100644 AspectC++/tests/Bug570/feature.ref create mode 100644 AspectC++/tests/Bug570/main.cc create mode 100644 AspectC++/tests/Bug571-1/Makefile create mode 100644 AspectC++/tests/Bug571-1/feature.ref create mode 100644 AspectC++/tests/Bug571-1/main.cc create mode 100644 AspectC++/tests/Bug571-2/Makefile create mode 100644 AspectC++/tests/Bug571-2/feature.ref create mode 100644 AspectC++/tests/Bug571-2/main.cc create mode 100644 AspectC++/tests/Bug571-3/Makefile create mode 100644 AspectC++/tests/Bug571-3/feature.ref create mode 100644 AspectC++/tests/Bug571-3/main.cc create mode 100644 AspectC++/tests/Bug574/Makefile create mode 100644 AspectC++/tests/Bug574/feature.ref create mode 100644 AspectC++/tests/Bug574/main.cc create mode 100644 AspectC++/tests/Bug575/Makefile create mode 100644 AspectC++/tests/Bug575/feature.ref create mode 100644 AspectC++/tests/Bug575/main.cc create mode 100644 AspectC++/tests/Bug576/Makefile create mode 100644 AspectC++/tests/Bug576/feature.ref create mode 100644 AspectC++/tests/Bug576/main.cc create mode 100644 AspectC++/tests/Bug577/Makefile create mode 100644 AspectC++/tests/Bug577/alex.ah create mode 100644 AspectC++/tests/Bug577/alex.h create mode 100644 AspectC++/tests/Bug577/feature.ref create mode 100644 AspectC++/tests/Bug577/macro.ah create mode 100644 AspectC++/tests/Bug577/main.cc create mode 100644 AspectC++/tests/Bug580/Makefile create mode 100644 AspectC++/tests/Bug580/feature.ref create mode 100644 AspectC++/tests/Bug580/main.cc create mode 100644 AspectC++/tests/Bug589/Makefile create mode 100644 AspectC++/tests/Bug589/feature.ref create mode 100644 AspectC++/tests/Bug589/main.cc create mode 100644 AspectC++/tests/Bug594/Makefile create mode 100644 AspectC++/tests/Bug594/feature.ref create mode 100644 AspectC++/tests/Bug594/main.cc create mode 100644 AspectC++/tests/Bug598/Makefile create mode 100644 AspectC++/tests/Bug598/feature.ref create mode 100644 AspectC++/tests/Bug598/main.cc create mode 100644 AspectC++/tests/Bug768/Makefile create mode 100644 AspectC++/tests/Bug768/feature.ref create mode 100644 AspectC++/tests/Bug768/main.cc create mode 100644 AspectC++/tests/Bug769/Makefile create mode 100644 AspectC++/tests/Bug769/feature.ref create mode 100644 AspectC++/tests/Bug769/main.cc create mode 100644 AspectC++/tests/Bug770/Makefile create mode 100644 AspectC++/tests/Bug770/feature.ref create mode 100644 AspectC++/tests/Bug770/main.cc create mode 100644 AspectC++/tests/CFlowCycle/A.h create mode 100644 AspectC++/tests/CFlowCycle/B.h create mode 100644 AspectC++/tests/CFlowCycle/C.h create mode 100644 AspectC++/tests/CFlowCycle/CFlow.ah create mode 100644 AspectC++/tests/CFlowCycle/D.h create mode 100644 AspectC++/tests/CFlowCycle/Makefile create mode 100644 AspectC++/tests/CFlowCycle/feature.ref create mode 100644 AspectC++/tests/CFlowCycle/main.cc create mode 100644 AspectC++/tests/CallAccess/Makefile create mode 100644 AspectC++/tests/CallAccess/feature.ref create mode 100644 AspectC++/tests/CallAccess/main.cc create mode 100644 AspectC++/tests/CallAdvice/Makefile create mode 100644 AspectC++/tests/CallAdvice/feature.ref create mode 100644 AspectC++/tests/CallAdvice/main.cc create mode 100644 AspectC++/tests/CallBuiltinOperator/Makefile create mode 100644 AspectC++/tests/CallBuiltinOperator/feature.ref create mode 100644 AspectC++/tests/CallBuiltinOperator/main.cc create mode 100644 AspectC++/tests/CallOnRef/Makefile create mode 100644 AspectC++/tests/CallOnRef/feature.ref create mode 100644 AspectC++/tests/CallOnRef/main.cc create mode 100644 AspectC++/tests/CallPostfixOp/Makefile create mode 100644 AspectC++/tests/CallPostfixOp/feature.ref create mode 100644 AspectC++/tests/CallPostfixOp/main.cc create mode 100644 AspectC++/tests/CallRef/Makefile create mode 100644 AspectC++/tests/CallRef/feature.ref create mode 100644 AspectC++/tests/CallRef/main.cc create mode 100644 AspectC++/tests/CallViaADN/Makefile create mode 100644 AspectC++/tests/CallViaADN/classes.h create mode 100644 AspectC++/tests/CallViaADN/feature.ref create mode 100644 AspectC++/tests/CallViaADN/functions.cc create mode 100644 AspectC++/tests/CallViaADN/main.cc create mode 100644 AspectC++/tests/CallViaADN/trace.ah create mode 100644 AspectC++/tests/CompoundGetSetAdvice/Makefile create mode 100644 AspectC++/tests/CompoundGetSetAdvice/feature.ref create mode 100644 AspectC++/tests/CompoundGetSetAdvice/main.cc create mode 100644 AspectC++/tests/ConsDesAdvice/ConsDesTracker.ah create mode 100644 AspectC++/tests/ConsDesAdvice/Makefile create mode 100644 AspectC++/tests/ConsDesAdvice/c1.h create mode 100644 AspectC++/tests/ConsDesAdvice/feature.ref create mode 100644 AspectC++/tests/ConsDesAdvice/main.cc create mode 100644 AspectC++/tests/Context/Makefile create mode 100644 AspectC++/tests/Context/feature.ref create mode 100644 AspectC++/tests/Context/main.cc create mode 100644 AspectC++/tests/DataFlowAnalysis/Makefile create mode 100644 AspectC++/tests/DataFlowAnalysis/feature.ref create mode 100644 AspectC++/tests/DataFlowAnalysis/main.cc create mode 100644 AspectC++/tests/DefaultArgs/Makefile create mode 100644 AspectC++/tests/DefaultArgs/feature.ref create mode 100644 AspectC++/tests/DefaultArgs/main.cc create mode 100644 AspectC++/tests/DefaultArgs2/Makefile create mode 100644 AspectC++/tests/DefaultArgs2/feature.ref create mode 100644 AspectC++/tests/DefaultArgs2/main.cc create mode 100644 AspectC++/tests/Derived/Makefile create mode 100644 AspectC++/tests/Derived/feature.ref create mode 100644 AspectC++/tests/Derived/main.cc create mode 100644 AspectC++/tests/DisjointIds/Makefile create mode 100644 AspectC++/tests/DisjointIds/a.ah create mode 100644 AspectC++/tests/DisjointIds/feature.ref create mode 100644 AspectC++/tests/DisjointIds/main.cc create mode 100644 AspectC++/tests/DisjointIds/other.cc create mode 100644 AspectC++/tests/Empty/Makefile create mode 100644 AspectC++/tests/Empty/empty.cc create mode 100644 AspectC++/tests/Empty/feature.ref create mode 100644 AspectC++/tests/Empty/main.cc create mode 100644 AspectC++/tests/ExecAdviceFriend/Makefile create mode 100644 AspectC++/tests/ExecAdviceFriend/feature.ref create mode 100644 AspectC++/tests/ExecAdviceFriend/main.cc create mode 100644 AspectC++/tests/ExecAdviceNewDelete/Makefile create mode 100644 AspectC++/tests/ExecAdviceNewDelete/feature.ref create mode 100644 AspectC++/tests/ExecAdviceNewDelete/main.cc create mode 100644 AspectC++/tests/ExecAdviceRecursive/Makefile create mode 100644 AspectC++/tests/ExecAdviceRecursive/feature.ref create mode 100644 AspectC++/tests/ExecAdviceRecursive/main.cc create mode 100644 AspectC++/tests/ExternC/Makefile create mode 100644 AspectC++/tests/ExternC/feature.ref create mode 100644 AspectC++/tests/ExternC/main.cc create mode 100644 AspectC++/tests/Float128Basic/Makefile create mode 100644 AspectC++/tests/Float128Basic/feature.ref create mode 100644 AspectC++/tests/Float128Basic/main.cc create mode 100644 AspectC++/tests/ForcedInclude/Makefile create mode 100644 AspectC++/tests/ForcedInclude/config.h create mode 100644 AspectC++/tests/ForcedInclude/feature.ref create mode 100644 AspectC++/tests/ForcedInclude/main.cc create mode 100644 AspectC++/tests/Forward/Aspect.ah create mode 100644 AspectC++/tests/Forward/Forward.h create mode 100644 AspectC++/tests/Forward/Makefile create mode 100644 AspectC++/tests/Forward/feature.ref create mode 100644 AspectC++/tests/Forward/main.cc create mode 100644 AspectC++/tests/FunctionEntity/Makefile create mode 100644 AspectC++/tests/FunctionEntity/feature.ref create mode 100644 AspectC++/tests/FunctionEntity/main.cc create mode 100644 AspectC++/tests/GetBaseDerived/Makefile create mode 100644 AspectC++/tests/GetBaseDerived/feature.ref create mode 100644 AspectC++/tests/GetBaseDerived/main.cc create mode 100644 AspectC++/tests/GetConditional/Makefile create mode 100644 AspectC++/tests/GetConditional/feature.ref create mode 100644 AspectC++/tests/GetConditional/main.cc create mode 100644 AspectC++/tests/GlobalIds/Makefile create mode 100644 AspectC++/tests/GlobalIds/a.ah create mode 100644 AspectC++/tests/GlobalIds/another_module.cc create mode 100644 AspectC++/tests/GlobalIds/feature.ref create mode 100644 AspectC++/tests/GlobalIds/h1.h create mode 100644 AspectC++/tests/GlobalIds/main.cc create mode 100644 AspectC++/tests/Instantiation/Makefile create mode 100644 AspectC++/tests/Instantiation/feature.ref create mode 100644 AspectC++/tests/Instantiation/main.cc create mode 100644 AspectC++/tests/IntroInAll/Makefile create mode 100644 AspectC++/tests/IntroInAll/feature.ref create mode 100644 AspectC++/tests/IntroInAll/main.cc create mode 100644 AspectC++/tests/IntroInBase/Base.ah create mode 100644 AspectC++/tests/IntroInBase/C.h create mode 100644 AspectC++/tests/IntroInBase/Derived.ah create mode 100644 AspectC++/tests/IntroInBase/Makefile create mode 100644 AspectC++/tests/IntroInBase/feature.ref create mode 100644 AspectC++/tests/IntroInBase/main.cc create mode 100644 AspectC++/tests/IntroIncludes/A1.ah create mode 100644 AspectC++/tests/IntroIncludes/A2.ah create mode 100644 AspectC++/tests/IntroIncludes/A3.ah create mode 100644 AspectC++/tests/IntroIncludes/C.h create mode 100644 AspectC++/tests/IntroIncludes/Makefile create mode 100644 AspectC++/tests/IntroIncludes/feature.ref create mode 100644 AspectC++/tests/IntroIncludes/main.cc create mode 100644 AspectC++/tests/Introspection/Makefile create mode 100644 AspectC++/tests/Introspection/feature.ref create mode 100644 AspectC++/tests/Introspection/main.cc create mode 100644 AspectC++/tests/JPTL/JPTL.h create mode 100644 AspectC++/tests/JPTL/Makefile create mode 100644 AspectC++/tests/JPTL/TestAspect.ah create mode 100644 AspectC++/tests/JPTL/feature.ref create mode 100644 AspectC++/tests/JPTL/main.cc create mode 100644 AspectC++/tests/JPType/Makefile create mode 100644 AspectC++/tests/JPType/feature.ref create mode 100644 AspectC++/tests/JPType/main.cc create mode 100644 AspectC++/tests/MacroCall/Makefile create mode 100644 AspectC++/tests/MacroCall/external.cc create mode 100644 AspectC++/tests/MacroCall/feature.ref create mode 100644 AspectC++/tests/MacroCall/main.cc create mode 100644 AspectC++/tests/MacroExpansion/Makefile create mode 100644 AspectC++/tests/MacroExpansion/feature.ref create mode 100644 AspectC++/tests/MacroExpansion/main.cc create mode 100644 AspectC++/tests/Makefile create mode 100644 AspectC++/tests/Makefile.generic create mode 100644 AspectC++/tests/MatchExpr/Makefile create mode 100644 AspectC++/tests/MatchExpr/feature.ref create mode 100644 AspectC++/tests/MatchExpr/main.cc create mode 100644 AspectC++/tests/MatchScope/Makefile create mode 100644 AspectC++/tests/MatchScope/feature.ref create mode 100644 AspectC++/tests/MatchScope/main.cc create mode 100644 AspectC++/tests/MatchScopeWithin/Makefile create mode 100644 AspectC++/tests/MatchScopeWithin/feature.ref create mode 100644 AspectC++/tests/MatchScopeWithin/main.cc create mode 100644 AspectC++/tests/MatchStatic/Makefile create mode 100644 AspectC++/tests/MatchStatic/feature.ref create mode 100644 AspectC++/tests/MatchStatic/main.cc create mode 100644 AspectC++/tests/MatchVirtual/Makefile create mode 100644 AspectC++/tests/MatchVirtual/feature.ref create mode 100644 AspectC++/tests/MatchVirtual/main.cc create mode 100644 AspectC++/tests/MemberPointCut/Makefile create mode 100644 AspectC++/tests/MemberPointCut/feature.ref create mode 100644 AspectC++/tests/MemberPointCut/main.cc create mode 100644 AspectC++/tests/MemberPointCut/marker.ah create mode 100644 AspectC++/tests/MemberPointCut2/Makefile create mode 100644 AspectC++/tests/MemberPointCut2/feature.ref create mode 100644 AspectC++/tests/MemberPointCut2/main.cc create mode 100644 AspectC++/tests/MemberPointCut2/marker.ah create mode 100644 AspectC++/tests/NameMangling/Makefile create mode 100644 AspectC++/tests/NameMangling/NeedsMangling.ah create mode 100644 AspectC++/tests/NameMangling/feature.ref create mode 100644 AspectC++/tests/NameMangling/main.cc create mode 100644 AspectC++/tests/NamedPointcuts/Makefile create mode 100644 AspectC++/tests/NamedPointcuts/feature.ref create mode 100644 AspectC++/tests/NamedPointcuts/main.cc create mode 100644 AspectC++/tests/Namespaces/Makefile create mode 100644 AspectC++/tests/Namespaces/main.cc create mode 100644 AspectC++/tests/NestedClassFuncAdvice/Aspect.ah create mode 100644 AspectC++/tests/NestedClassFuncAdvice/Makefile create mode 100644 AspectC++/tests/NestedClassFuncAdvice/feature.ref create mode 100644 AspectC++/tests/NestedClassFuncAdvice/main.cc create mode 100644 AspectC++/tests/NonInlineIntroInclude/A.cc create mode 100644 AspectC++/tests/NonInlineIntroInclude/A.h create mode 100644 AspectC++/tests/NonInlineIntroInclude/ABDecl.ah create mode 100644 AspectC++/tests/NonInlineIntroInclude/ABDef.ah create mode 100644 AspectC++/tests/NonInlineIntroInclude/B.cc create mode 100644 AspectC++/tests/NonInlineIntroInclude/B.h create mode 100644 AspectC++/tests/NonInlineIntroInclude/C.cc create mode 100644 AspectC++/tests/NonInlineIntroInclude/C.h create mode 100644 AspectC++/tests/NonInlineIntroInclude/CDecl.ah create mode 100644 AspectC++/tests/NonInlineIntroInclude/CDef.ah create mode 100644 AspectC++/tests/NonInlineIntroInclude/Makefile create mode 100644 AspectC++/tests/NonInlineIntroInclude/feature.ref create mode 100644 AspectC++/tests/NonInlineIntroInclude/main.cc create mode 100644 AspectC++/tests/NonInlineIntros/C.cc create mode 100644 AspectC++/tests/NonInlineIntros/C.h create mode 100644 AspectC++/tests/NonInlineIntros/D.cc create mode 100644 AspectC++/tests/NonInlineIntros/D.h create mode 100644 AspectC++/tests/NonInlineIntros/E.h create mode 100644 AspectC++/tests/NonInlineIntros/F.cc create mode 100644 AspectC++/tests/NonInlineIntros/F.h create mode 100644 AspectC++/tests/NonInlineIntros/Intro.ah create mode 100644 AspectC++/tests/NonInlineIntros/Makefile create mode 100644 AspectC++/tests/NonInlineIntros/feature.ref create mode 100644 AspectC++/tests/NonInlineSliceInclude/A.cc create mode 100644 AspectC++/tests/NonInlineSliceInclude/A.h create mode 100644 AspectC++/tests/NonInlineSliceInclude/ABDecl.ah create mode 100644 AspectC++/tests/NonInlineSliceInclude/ABDef.ah create mode 100644 AspectC++/tests/NonInlineSliceInclude/B.cc create mode 100644 AspectC++/tests/NonInlineSliceInclude/B.h create mode 100644 AspectC++/tests/NonInlineSliceInclude/C.cc create mode 100644 AspectC++/tests/NonInlineSliceInclude/C.h create mode 100644 AspectC++/tests/NonInlineSliceInclude/CDecl.ah create mode 100644 AspectC++/tests/NonInlineSliceInclude/CDef.ah create mode 100644 AspectC++/tests/NonInlineSliceInclude/Makefile create mode 100644 AspectC++/tests/NonInlineSliceInclude/feature.ref create mode 100644 AspectC++/tests/NonInlineSliceInclude/main.cc create mode 100644 AspectC++/tests/Order/Makefile create mode 100644 AspectC++/tests/Order/feature.ref create mode 100644 AspectC++/tests/Order/main.cc create mode 100644 AspectC++/tests/PctInClass/Makefile create mode 100644 AspectC++/tests/PctInClass/feature.ref create mode 100644 AspectC++/tests/PctInClass/main.cc create mode 100644 AspectC++/tests/PragmaOnce/Makefile create mode 100644 AspectC++/tests/PragmaOnce/a.h create mode 100644 AspectC++/tests/PragmaOnce/b.h create mode 100644 AspectC++/tests/PragmaOnce/feature.ref create mode 100644 AspectC++/tests/PragmaOnce/main.cc create mode 100644 AspectC++/tests/PragmaOnceObserver/AnalogClock.cc create mode 100644 AspectC++/tests/PragmaOnceObserver/AnalogClock.h create mode 100644 AspectC++/tests/PragmaOnceObserver/ClockObserver.ah create mode 100644 AspectC++/tests/PragmaOnceObserver/ClockTimer.cc create mode 100644 AspectC++/tests/PragmaOnceObserver/ClockTimer.h create mode 100644 AspectC++/tests/PragmaOnceObserver/DigitalClock.cc create mode 100644 AspectC++/tests/PragmaOnceObserver/DigitalClock.h create mode 100644 AspectC++/tests/PragmaOnceObserver/Makefile create mode 100644 AspectC++/tests/PragmaOnceObserver/ObserverPattern.ah create mode 100644 AspectC++/tests/PragmaOnceObserver/feature.ref create mode 100644 AspectC++/tests/PragmaOnceObserver/main.cc create mode 100644 AspectC++/tests/PrivateResult/Aspect.ah create mode 100644 AspectC++/tests/PrivateResult/Makefile create mode 100644 AspectC++/tests/PrivateResult/Safe.h create mode 100644 AspectC++/tests/PrivateResult/feature.ref create mode 100644 AspectC++/tests/PrivateResult/main.cc create mode 100644 AspectC++/tests/RepoInvalid/Makefile create mode 100644 AspectC++/tests/RepoInvalid/feature.ref create mode 100644 AspectC++/tests/RepoInvalid/main.cc create mode 100644 AspectC++/tests/RepoInvalid/repo.inv create mode 100644 AspectC++/tests/RepoVersion/Makefile create mode 100644 AspectC++/tests/RepoVersion/feature.ref create mode 100644 AspectC++/tests/RepoVersion/main.cc create mode 100644 AspectC++/tests/RepoVersion/repo.inv create mode 100644 AspectC++/tests/Result/Makefile create mode 100644 AspectC++/tests/Result/PointerTracker.ah create mode 100644 AspectC++/tests/Result/feature.ref create mode 100644 AspectC++/tests/Result/main.cc create mode 100644 AspectC++/tests/RightlessCalls/Makefile create mode 100644 AspectC++/tests/RightlessCalls/feature.ref create mode 100644 AspectC++/tests/RightlessCalls/main.cc create mode 100644 AspectC++/tests/STLSet/Makefile create mode 100644 AspectC++/tests/STLSet/main.cc create mode 100644 AspectC++/tests/STLString/Makefile create mode 100644 AspectC++/tests/STLString/feature.ref create mode 100644 AspectC++/tests/STLString/main.cc create mode 100644 AspectC++/tests/SimpleAliasAccessMember/Makefile create mode 100644 AspectC++/tests/SimpleAliasAccessMember/feature.ref create mode 100644 AspectC++/tests/SimpleAliasAccessMember/main.cc create mode 100644 AspectC++/tests/SimpleGetAdvice/Makefile create mode 100644 AspectC++/tests/SimpleGetAdvice/feature.ref create mode 100644 AspectC++/tests/SimpleGetAdvice/main.cc create mode 100644 AspectC++/tests/SimpleGetSetFuncPtr/Makefile create mode 100644 AspectC++/tests/SimpleGetSetFuncPtr/feature.ref create mode 100644 AspectC++/tests/SimpleGetSetFuncPtr/main.cc create mode 100644 AspectC++/tests/SimpleRefAdvice/Makefile create mode 100644 AspectC++/tests/SimpleRefAdvice/feature.ref create mode 100644 AspectC++/tests/SimpleRefAdvice/main.cc create mode 100644 AspectC++/tests/SimpleSetAdvice/Makefile create mode 100644 AspectC++/tests/SimpleSetAdvice/feature.ref create mode 100644 AspectC++/tests/SimpleSetAdvice/main.cc create mode 100644 AspectC++/tests/Slice/Makefile create mode 100644 AspectC++/tests/Slice/feature.ref create mode 100644 AspectC++/tests/Slice/main.cc create mode 100644 AspectC++/tests/SliceJPAPI/Makefile create mode 100644 AspectC++/tests/SliceJPAPI/feature.ref create mode 100644 AspectC++/tests/SliceJPAPI/main.cc create mode 100644 AspectC++/tests/StandAloneCalls/Aspect.ah create mode 100644 AspectC++/tests/StandAloneCalls/Makefile create mode 100644 AspectC++/tests/StandAloneCalls/feature.ref create mode 100644 AspectC++/tests/StandAloneCalls/main.cc create mode 100644 AspectC++/tests/StaticTrace/Makefile create mode 100644 AspectC++/tests/StaticTrace/Trace.ah create mode 100644 AspectC++/tests/StaticTrace/feature.ref create mode 100644 AspectC++/tests/StaticTrace/main.cc create mode 100644 AspectC++/tests/TemplateExtCall/Makefile create mode 100644 AspectC++/tests/TemplateExtCall/feature.ref create mode 100644 AspectC++/tests/TemplateExtCall/main.cc create mode 100644 AspectC++/tests/That/Makefile create mode 100644 AspectC++/tests/That/feature.ref create mode 100644 AspectC++/tests/That/main.cc create mode 100644 AspectC++/tests/ThatConst/Makefile create mode 100644 AspectC++/tests/ThatConst/feature.ref create mode 100644 AspectC++/tests/ThatConst/main.cc create mode 100644 AspectC++/tests/ThatContext/Makefile create mode 100644 AspectC++/tests/ThatContext/feature.ref create mode 100644 AspectC++/tests/ThatContext/main.cc create mode 100644 AspectC++/tests/UnknownTypeCheck/Makefile create mode 100644 AspectC++/tests/UnknownTypeCheck/a.cc create mode 100644 AspectC++/tests/UnknownTypeCheck/a.h create mode 100644 AspectC++/tests/UnknownTypeCheck/b.h create mode 100644 AspectC++/tests/UnknownTypeCheck/check.ah create mode 100644 AspectC++/tests/UnknownTypeCheck/feature.ref create mode 100644 AspectC++/tests/UnknownTypeCheck/main.cc create mode 100644 AspectC++/tests/UnsizedArray/Makefile create mode 100644 AspectC++/tests/UnsizedArray/feature.ref create mode 100644 AspectC++/tests/UnsizedArray/main.cc create mode 100644 AspectC++/tests/VirtualPointcuts/Makefile create mode 100644 AspectC++/tests/VirtualPointcuts/feature.ref create mode 100644 AspectC++/tests/VirtualPointcuts/main.cc create mode 100644 AspectC++/tests/VoidArg/Makefile create mode 100644 AspectC++/tests/VoidArg/feature.ref create mode 100644 AspectC++/tests/VoidArg/main.cc create mode 100755 AspectC++/tests/conv_junit.py create mode 100755 AspectC++/tests/genvcprojs.sh create mode 100755 AspectC++/tests/rmvcprojs.sh create mode 100755 AspectC++/tools/cvs2cl create mode 100755 AspectC++/tools/gpl create mode 100644 AspectC++/version.h create mode 100755 AspectC++/win-ac++.ico create mode 100644 AspectC++/win-ac++.rc create mode 100644 Puma/.cproject create mode 100644 Puma/.project create mode 100644 Puma/COPYING create mode 100644 Puma/INSTALL create mode 100644 Puma/Makefile create mode 100644 Puma/README create mode 100644 Puma/TODO create mode 100644 Puma/doc/MindMaps/Puma-Parser.mm create mode 100644 Puma/doc/MindMaps/TemplatesParsen.mm create mode 100644 Puma/doc/RefMan/doxygen.conf create mode 100644 Puma/doc/RefMan/layout.xml create mode 100644 Puma/doc/RefMan/logo.png create mode 100644 Puma/doc/UsersManual/UsersManual.lyx create mode 100644 Puma/doc/UsersManual/UsersManual.pdf create mode 100644 Puma/doc/lemon/lemon.html create mode 100644 Puma/examples/Makefile create mode 100644 Puma/examples/annotator/Makefile create mode 100644 Puma/examples/annotator/Transformer.cc create mode 100644 Puma/examples/annotator/Transformer.h create mode 100644 Puma/examples/annotator/annotator.cc create mode 100644 Puma/examples/annotator/example.cpp create mode 100644 Puma/examples/ccparser/IncludeVisitor.cc create mode 100644 Puma/examples/ccparser/IncludeVisitor.h create mode 100644 Puma/examples/ccparser/Makefile create mode 100644 Puma/examples/ccparser/ccparser.cc create mode 100644 Puma/examples/cparser/Makefile create mode 100644 Puma/examples/cparser/cparser.cc create mode 100644 Puma/examples/macronames/Makefile create mode 100644 Puma/examples/macronames/macronames.cc create mode 100644 Puma/examples/parser/Makefile create mode 100644 Puma/examples/parser/parser.cc create mode 100644 Puma/examples/sync/Makefile create mode 100644 Puma/examples/sync/README.txt create mode 100644 Puma/examples/sync/SyncBuilder.cc create mode 100644 Puma/examples/sync/SyncBuilder.h create mode 100644 Puma/examples/sync/SyncLexer.cc create mode 100644 Puma/examples/sync/SyncLexer.h create mode 100644 Puma/examples/sync/SyncParser.h create mode 100644 Puma/examples/sync/SyncSemantic.cc create mode 100644 Puma/examples/sync/SyncSemantic.h create mode 100644 Puma/examples/sync/SyncSyntax.cc create mode 100644 Puma/examples/sync/SyncSyntax.h create mode 100644 Puma/examples/sync/SyncTokens.h create mode 100644 Puma/examples/sync/SyncTransformer.cc create mode 100644 Puma/examples/sync/SyncTransformer.h create mode 100644 Puma/examples/sync/SyncTree.cc create mode 100644 Puma/examples/sync/SyncTree.h create mode 100644 Puma/examples/sync/sync.cc create mode 100644 Puma/extensions.mk create mode 100644 Puma/extern/README create mode 100644 Puma/extern/lexertl/bool.hpp create mode 100644 Puma/extern/lexertl/char_traits.hpp create mode 100644 Puma/extern/lexertl/compile_assert.hpp create mode 100644 Puma/extern/lexertl/containers/bitvector.hpp create mode 100644 Puma/extern/lexertl/containers/ptr_list.hpp create mode 100644 Puma/extern/lexertl/containers/ptr_map.hpp create mode 100644 Puma/extern/lexertl/containers/ptr_stack.hpp create mode 100644 Puma/extern/lexertl/containers/ptr_vector.hpp create mode 100644 Puma/extern/lexertl/debug.hpp create mode 100644 Puma/extern/lexertl/dot.hpp create mode 100644 Puma/extern/lexertl/enums.hpp create mode 100644 Puma/extern/lexertl/generate_cpp.hpp create mode 100644 Puma/extern/lexertl/generator.hpp create mode 100644 Puma/extern/lexertl/internals.hpp create mode 100644 Puma/extern/lexertl/is_same.hpp create mode 100644 Puma/extern/lexertl/iterator.hpp create mode 100644 Puma/extern/lexertl/licence_1_0.txt create mode 100644 Puma/extern/lexertl/lookup.hpp create mode 100644 Puma/extern/lexertl/match_results.hpp create mode 100644 Puma/extern/lexertl/memory_file.hpp create mode 100644 Puma/extern/lexertl/narrow.hpp create mode 100644 Puma/extern/lexertl/old/fast_filebuf.hpp create mode 100644 Puma/extern/lexertl/old/string_token.hpp create mode 100644 Puma/extern/lexertl/parser/parser.hpp create mode 100644 Puma/extern/lexertl/parser/tokeniser/re_token.hpp create mode 100644 Puma/extern/lexertl/parser/tokeniser/re_tokeniser.hpp create mode 100644 Puma/extern/lexertl/parser/tokeniser/re_tokeniser_helper.hpp create mode 100644 Puma/extern/lexertl/parser/tokeniser/re_tokeniser_state.hpp create mode 100644 Puma/extern/lexertl/parser/tree/end_node.hpp create mode 100644 Puma/extern/lexertl/parser/tree/iteration_node.hpp create mode 100644 Puma/extern/lexertl/parser/tree/leaf_node.hpp create mode 100644 Puma/extern/lexertl/parser/tree/node.hpp create mode 100644 Puma/extern/lexertl/parser/tree/selection_node.hpp create mode 100644 Puma/extern/lexertl/parser/tree/sequence_node.hpp create mode 100644 Puma/extern/lexertl/partition/charset.hpp create mode 100644 Puma/extern/lexertl/partition/equivset.hpp create mode 100644 Puma/extern/lexertl/rules.hpp create mode 100644 Puma/extern/lexertl/runtime_error.hpp create mode 100644 Puma/extern/lexertl/serialise.hpp create mode 100644 Puma/extern/lexertl/size_t.hpp create mode 100644 Puma/extern/lexertl/sm_to_csm.hpp create mode 100644 Puma/extern/lexertl/sm_traits.hpp create mode 100644 Puma/extern/lexertl/state_machine.hpp create mode 100644 Puma/extern/lexertl/stream_shared_iterator.hpp create mode 100644 Puma/extern/lexertl/string_token.hpp create mode 100644 Puma/extern/lexertl/utf_iterators.hpp create mode 100644 Puma/files.mk create mode 100644 Puma/src/Makefile create mode 100644 Puma/src/aspects/CC1XTree.cc create mode 100644 Puma/src/aspects/CC1XTree.h create mode 100644 Puma/src/aspects/CCExprResolveCC.ah create mode 100644 Puma/src/aspects/CCExprResolveH.ah create mode 100644 Puma/src/aspects/CExprResolveCC.ah create mode 100644 Puma/src/aspects/CExprResolveH.ah create mode 100644 Puma/src/aspects/CMatchSyntax.ah create mode 100644 Puma/src/aspects/ExtAC.ah create mode 100644 Puma/src/aspects/ExtACTree.ah create mode 100644 Puma/src/aspects/ExtACTree.cc create mode 100644 Puma/src/aspects/ExtCC1X.ah create mode 100644 Puma/src/aspects/ExtCC1XBuilderCC.ah create mode 100644 Puma/src/aspects/ExtCC1XBuilderH.ah create mode 100644 Puma/src/aspects/ExtCC1XSemanticCC.ah create mode 100644 Puma/src/aspects/ExtCC1XSemanticH.ah create mode 100644 Puma/src/aspects/ExtCC1XSyntaxCC.ah create mode 100644 Puma/src/aspects/ExtCC1XSyntaxH.ah create mode 100644 Puma/src/aspects/ExtGnu.ah create mode 100644 Puma/src/aspects/ExtGnuCInfos.ah create mode 100644 Puma/src/aspects/ExtGnuCSemDeclSpecs.ah create mode 100644 Puma/src/aspects/ExtGnuCSemExpr.ah create mode 100644 Puma/src/aspects/ExtGnuCSemantic.ah create mode 100644 Puma/src/aspects/ExtGnuCTree.ah create mode 100644 Puma/src/aspects/ExtGnuKeywords.ah create mode 100644 Puma/src/aspects/GenericProfiler.ah create mode 100644 Puma/src/aspects/PragmaOnce.ah create mode 100644 Puma/src/aspects/PragmaOnceUnitState.ah create mode 100644 Puma/src/aspects/Profiler.ah create mode 100644 Puma/src/aspects/TraceSyntax.ah create mode 100644 Puma/src/aspects/WinAsm.ah create mode 100644 Puma/src/aspects/WinDeclSpecs.ah create mode 100644 Puma/src/aspects/WinFriend.ah create mode 100644 Puma/src/aspects/WinIfExists.ah create mode 100644 Puma/src/aspects/WinImportHandler.ah create mode 100644 Puma/src/aspects/WinKeywords.ah create mode 100644 Puma/src/aspects/WinMacros.ah create mode 100644 Puma/src/aspects/WinMemberExplSpec.ah create mode 100644 Puma/src/aspects/WinTypeKeywords.ah create mode 100644 Puma/src/basics/Array.h create mode 100644 Puma/src/basics/BCList.h create mode 100644 Puma/src/basics/BCStack.h create mode 100644 Puma/src/basics/Chain.h create mode 100644 Puma/src/basics/ConstSizeMemPool.h create mode 100644 Puma/src/basics/DString.cc create mode 100644 Puma/src/basics/DString.h create mode 100644 Puma/src/basics/FdSource.h create mode 100644 Puma/src/basics/FileSource.h create mode 100644 Puma/src/basics/GPLHeader.cc create mode 100644 Puma/src/basics/Heap.cc create mode 100644 Puma/src/basics/Heap.h create mode 100644 Puma/src/basics/KeyboardSource.cc create mode 100644 Puma/src/basics/KeyboardSource.h create mode 100644 Puma/src/basics/Limits.h create mode 100644 Puma/src/basics/List.cc create mode 100644 Puma/src/basics/List.h create mode 100644 Puma/src/basics/ListElement.h create mode 100644 Puma/src/basics/MemPool.cc create mode 100644 Puma/src/basics/MemPool.h create mode 100644 Puma/src/basics/Pipe.cc create mode 100644 Puma/src/basics/Pipe.h create mode 100644 Puma/src/basics/PipedCmd.cc create mode 100644 Puma/src/basics/PipedCmd.h create mode 100644 Puma/src/basics/Printable.h create mode 100644 Puma/src/basics/PtrStack.h create mode 100644 Puma/src/basics/RegComp.cc create mode 100644 Puma/src/basics/RegComp.h create mode 100644 Puma/src/basics/Sink.h create mode 100644 Puma/src/basics/SmartPtr.h create mode 100644 Puma/src/basics/Source.h create mode 100644 Puma/src/basics/Stack.h create mode 100644 Puma/src/basics/StrCol.cc create mode 100644 Puma/src/basics/StrCol.h create mode 100644 Puma/src/basics/StrHashKey.h create mode 100644 Puma/src/basics/StrHashTable.cc create mode 100644 Puma/src/basics/StrHashTable.h create mode 100644 Puma/src/basics/StringSource.h create mode 100644 Puma/src/basics/SysCall.cc create mode 100644 Puma/src/basics/SysCall.h create mode 100644 Puma/src/basics/TerminalSink.cc create mode 100644 Puma/src/basics/TerminalSink.h create mode 100644 Puma/src/basics/TokenSource.h create mode 100644 Puma/src/basics/VerboseMgr.cc create mode 100644 Puma/src/basics/VerboseMgr.h create mode 100644 Puma/src/basics/VoidPtrArray.cc create mode 100644 Puma/src/basics/VoidPtrArray.h create mode 100644 Puma/src/basics/WChar.cc create mode 100644 Puma/src/basics/WChar.h create mode 100644 Puma/src/basics/version.h create mode 100644 Puma/src/common/ConfOption.h create mode 100644 Puma/src/common/Config.cc create mode 100644 Puma/src/common/Config.h create mode 100644 Puma/src/common/ErrorCollector.cc create mode 100644 Puma/src/common/ErrorCollector.h create mode 100644 Puma/src/common/ErrorSeverity.cc create mode 100644 Puma/src/common/ErrorSeverity.h create mode 100644 Puma/src/common/ErrorSink.cc create mode 100644 Puma/src/common/ErrorSink.h create mode 100644 Puma/src/common/ErrorStream.cc create mode 100644 Puma/src/common/ErrorStream.h create mode 100644 Puma/src/common/FileUnit.cc create mode 100644 Puma/src/common/FileUnit.h create mode 100644 Puma/src/common/Filename.h create mode 100644 Puma/src/common/FilenameInfo.cc create mode 100644 Puma/src/common/FilenameInfo.h create mode 100644 Puma/src/common/LanguageID.h create mode 100644 Puma/src/common/Location.h create mode 100644 Puma/src/common/MacroUnit.cc create mode 100644 Puma/src/common/MacroUnit.h create mode 100644 Puma/src/common/OptsParser.cc create mode 100644 Puma/src/common/OptsParser.h create mode 100644 Puma/src/common/ParserKey.h create mode 100644 Puma/src/common/PathInfo.cc create mode 100644 Puma/src/common/PathInfo.h create mode 100644 Puma/src/common/PathIterator.cc create mode 100644 Puma/src/common/PathIterator.h create mode 100644 Puma/src/common/PathManager.cc create mode 100644 Puma/src/common/PathManager.h create mode 100644 Puma/src/common/Project.cc create mode 100644 Puma/src/common/Project.h create mode 100644 Puma/src/common/ProjectFile.h create mode 100644 Puma/src/common/SaveMode.h create mode 100644 Puma/src/common/SimpleParser.cc create mode 100644 Puma/src/common/SimpleParser.h create mode 100644 Puma/src/common/Token.cc create mode 100644 Puma/src/common/Token.h create mode 100644 Puma/src/common/TokenStream.cc create mode 100644 Puma/src/common/TokenStream.h create mode 100644 Puma/src/common/Tokenizer.h create mode 100644 Puma/src/common/Unit.cc create mode 100644 Puma/src/common/Unit.h create mode 100644 Puma/src/common/UnitIterator.cc create mode 100644 Puma/src/common/UnitIterator.h create mode 100644 Puma/src/common/UnitManager.cc create mode 100644 Puma/src/common/UnitManager.h create mode 100644 Puma/src/common/UnitState.h create mode 100644 Puma/src/common/UnitTokenSrc.h create mode 100644 Puma/src/compile.mk create mode 100644 Puma/src/cpp/ImportHandler.cc create mode 100644 Puma/src/cpp/ImportHandler.h create mode 100644 Puma/src/cpp/PreAnswer.cc create mode 100644 Puma/src/cpp/PreAnswer.h create mode 100644 Puma/src/cpp/PreArgDesc.h create mode 100644 Puma/src/cpp/PreAssertionEvaluator.cc create mode 100644 Puma/src/cpp/PreAssertionEvaluator.h create mode 100644 Puma/src/cpp/PreExpr.h create mode 100644 Puma/src/cpp/PreExprLexer.h create mode 100644 Puma/src/cpp/PreExprParser.lem create mode 100644 Puma/src/cpp/PreFileIncluder.cc create mode 100644 Puma/src/cpp/PreFileIncluder.h create mode 100644 Puma/src/cpp/PreLevelState.h create mode 100644 Puma/src/cpp/PreMacro.cc create mode 100644 Puma/src/cpp/PreMacro.h create mode 100644 Puma/src/cpp/PreMacroExpander.cc create mode 100644 Puma/src/cpp/PreMacroExpander.h create mode 100644 Puma/src/cpp/PreMacroManager.cc create mode 100644 Puma/src/cpp/PreMacroManager.h create mode 100644 Puma/src/cpp/PreMacroOpTokens.h create mode 100644 Puma/src/cpp/PreParser.lem create mode 100644 Puma/src/cpp/PreParserState.cc create mode 100644 Puma/src/cpp/PreParserState.h create mode 100644 Puma/src/cpp/PrePredicate.cc create mode 100644 Puma/src/cpp/PrePredicate.h create mode 100644 Puma/src/cpp/PrePredicateManager.cc create mode 100644 Puma/src/cpp/PrePredicateManager.h create mode 100644 Puma/src/cpp/PrePrintVisitor.cc create mode 100644 Puma/src/cpp/PrePrintVisitor.h create mode 100644 Puma/src/cpp/PreSemIterator.h create mode 100644 Puma/src/cpp/PreSonIterator.h create mode 100644 Puma/src/cpp/PreTree.cc create mode 100644 Puma/src/cpp/PreTree.h create mode 100644 Puma/src/cpp/PreTreeComposite.cc create mode 100644 Puma/src/cpp/PreTreeComposite.h create mode 100644 Puma/src/cpp/PreTreeIterator.h create mode 100644 Puma/src/cpp/PreTreeNodes.h create mode 100644 Puma/src/cpp/PreTreeToken.h create mode 100644 Puma/src/cpp/PreVisitor.h create mode 100644 Puma/src/cpp/PreprocessorParser.cc create mode 100644 Puma/src/cpp/PreprocessorParser.h create mode 100644 Puma/src/generate.mk create mode 100644 Puma/src/infos/CArgumentInfo.cc create mode 100644 Puma/src/infos/CArgumentInfo.h create mode 100644 Puma/src/infos/CAttributeInfo.cc create mode 100644 Puma/src/infos/CAttributeInfo.h create mode 100644 Puma/src/infos/CBaseClassInfo.cc create mode 100644 Puma/src/infos/CBaseClassInfo.h create mode 100644 Puma/src/infos/CCandidateInfo.h create mode 100644 Puma/src/infos/CClassDatabase.h create mode 100644 Puma/src/infos/CClassInfo.cc create mode 100644 Puma/src/infos/CClassInfo.h create mode 100644 Puma/src/infos/CClassInstance.h create mode 100644 Puma/src/infos/CEnumInfo.cc create mode 100644 Puma/src/infos/CEnumInfo.h create mode 100644 Puma/src/infos/CEnumeratorInfo.cc create mode 100644 Puma/src/infos/CEnumeratorInfo.h create mode 100644 Puma/src/infos/CFctInstance.cc create mode 100644 Puma/src/infos/CFctInstance.h create mode 100644 Puma/src/infos/CFileInfo.h create mode 100644 Puma/src/infos/CFunctionInfo.cc create mode 100644 Puma/src/infos/CFunctionInfo.h create mode 100644 Puma/src/infos/CLabelInfo.cc create mode 100644 Puma/src/infos/CLabelInfo.h create mode 100644 Puma/src/infos/CLocalScope.cc create mode 100644 Puma/src/infos/CLocalScope.h create mode 100644 Puma/src/infos/CMemberAliasInfo.cc create mode 100644 Puma/src/infos/CMemberAliasInfo.h create mode 100644 Puma/src/infos/CNamespaceInfo.cc create mode 100644 Puma/src/infos/CNamespaceInfo.h create mode 100644 Puma/src/infos/CObjectInfo.cc create mode 100644 Puma/src/infos/CObjectInfo.h create mode 100644 Puma/src/infos/CRecord.cc create mode 100644 Puma/src/infos/CRecord.h create mode 100644 Puma/src/infos/CScopeInfo.cc create mode 100644 Puma/src/infos/CScopeInfo.h create mode 100644 Puma/src/infos/CScopeRequest.h create mode 100644 Puma/src/infos/CSemDatabase.cc create mode 100644 Puma/src/infos/CSemDatabase.h create mode 100644 Puma/src/infos/CSourceInfo.cc create mode 100644 Puma/src/infos/CSourceInfo.h create mode 100644 Puma/src/infos/CStructure.cc create mode 100644 Puma/src/infos/CStructure.h create mode 100644 Puma/src/infos/CTemplateInfo.cc create mode 100644 Puma/src/infos/CTemplateInfo.h create mode 100644 Puma/src/infos/CTemplateInstance.cc create mode 100644 Puma/src/infos/CTemplateInstance.h create mode 100644 Puma/src/infos/CTemplateParamInfo.cc create mode 100644 Puma/src/infos/CTemplateParamInfo.h create mode 100644 Puma/src/infos/CTypedefInfo.cc create mode 100644 Puma/src/infos/CTypedefInfo.h create mode 100644 Puma/src/infos/CUnionInfo.cc create mode 100644 Puma/src/infos/CUnionInfo.h create mode 100644 Puma/src/infos/CUnionInstance.h create mode 100644 Puma/src/infos/CUsingInfo.cc create mode 100644 Puma/src/infos/CUsingInfo.h create mode 100644 Puma/src/infos/types/CTypeAddress.inc create mode 100644 Puma/src/infos/types/CTypeArray.inc create mode 100644 Puma/src/infos/types/CTypeBitField.inc create mode 100644 Puma/src/infos/types/CTypeClass.inc create mode 100644 Puma/src/infos/types/CTypeEnum.inc create mode 100644 Puma/src/infos/types/CTypeFunction.inc create mode 100644 Puma/src/infos/types/CTypeInfo.cc create mode 100644 Puma/src/infos/types/CTypeInfo.h create mode 100644 Puma/src/infos/types/CTypeList.inc create mode 100644 Puma/src/infos/types/CTypeMemberPointer.inc create mode 100644 Puma/src/infos/types/CTypePointer.inc create mode 100644 Puma/src/infos/types/CTypePrimitive.inc create mode 100644 Puma/src/infos/types/CTypeQualified.inc create mode 100644 Puma/src/infos/types/CTypeRecord.inc create mode 100644 Puma/src/infos/types/CTypeTemplateParam.inc create mode 100644 Puma/src/infos/types/CTypeUnion.inc create mode 100644 Puma/src/infos/types/CTypeVarArray.inc create mode 100644 Puma/src/manip/CMatch.cc create mode 100644 Puma/src/manip/CMatch.h create mode 100644 Puma/src/manip/CMatchChecker.cc create mode 100644 Puma/src/manip/CMatchChecker.h create mode 100644 Puma/src/manip/CMatchParser.lem create mode 100644 Puma/src/manip/CSubMatch.cc create mode 100644 Puma/src/manip/CSubMatch.h create mode 100644 Puma/src/manip/CTreeMatcher.cc create mode 100644 Puma/src/manip/CTreeMatcher.h create mode 100644 Puma/src/manip/ManipCommander.cc create mode 100644 Puma/src/manip/ManipCommander.h create mode 100644 Puma/src/manip/ManipController.cc create mode 100644 Puma/src/manip/ManipController.h create mode 100644 Puma/src/manip/Manipulators.cc create mode 100644 Puma/src/manip/Manipulators.h create mode 100644 Puma/src/manip/MatchCollector.cc create mode 100644 Puma/src/manip/MatchCollector.h create mode 100644 Puma/src/manip/Rule.h create mode 100644 Puma/src/manip/RuleTable.cc create mode 100644 Puma/src/manip/RuleTable.h create mode 100644 Puma/src/parser/Builder.cc create mode 100644 Puma/src/parser/Builder.h create mode 100644 Puma/src/parser/CConstant.cc create mode 100644 Puma/src/parser/CConstant.h create mode 100644 Puma/src/parser/CExprValue.h create mode 100644 Puma/src/parser/CSemObject.h create mode 100644 Puma/src/parser/CSemScope.h create mode 100644 Puma/src/parser/CSemValue.h create mode 100644 Puma/src/parser/CVisitor.cc create mode 100644 Puma/src/parser/CVisitor.h create mode 100644 Puma/src/parser/CWStrLiteral.h create mode 100644 Puma/src/parser/LookAhead.ah create mode 100644 Puma/src/parser/Parser.cc create mode 100644 Puma/src/parser/Parser.h create mode 100644 Puma/src/parser/Semantic.cc create mode 100644 Puma/src/parser/Semantic.h create mode 100644 Puma/src/parser/Syntax.cc create mode 100644 Puma/src/parser/Syntax.h create mode 100644 Puma/src/parser/SyntaxBuilder.ah create mode 100644 Puma/src/parser/SyntaxState.ah create mode 100644 Puma/src/parser/TokenProvider.h create mode 100644 Puma/src/parser/Tracing.cc create mode 100644 Puma/src/parser/Tracing.h create mode 100644 Puma/src/parser/acparser/ACIntroducer.h create mode 100644 Puma/src/parser/acparser/ACIntroducer_dummy.cc create mode 100644 Puma/src/parser/ccparser/CCAssocScopes.cc create mode 100644 Puma/src/parser/ccparser/CCAssocScopes.h create mode 100644 Puma/src/parser/ccparser/CCBuilder.cc create mode 100644 Puma/src/parser/ccparser/CCBuilder.h create mode 100644 Puma/src/parser/ccparser/CCBuilderExtension.ah create mode 100644 Puma/src/parser/ccparser/CCConvSeq.cc create mode 100644 Puma/src/parser/ccparser/CCConvSeq.h create mode 100644 Puma/src/parser/ccparser/CCConversion.cc create mode 100644 Puma/src/parser/ccparser/CCConversion.h create mode 100644 Puma/src/parser/ccparser/CCConversions.cc create mode 100644 Puma/src/parser/ccparser/CCConversions.h create mode 100644 Puma/src/parser/ccparser/CCExprResolveCC.ah create mode 100644 Puma/src/parser/ccparser/CCExprResolveH.ah create mode 100644 Puma/src/parser/ccparser/CCLookAhead.ah create mode 100644 Puma/src/parser/ccparser/CCNameLookup.cc create mode 100644 Puma/src/parser/ccparser/CCNameLookup.h create mode 100644 Puma/src/parser/ccparser/CCOverloading.cc create mode 100644 Puma/src/parser/ccparser/CCOverloading.h create mode 100644 Puma/src/parser/ccparser/CCParser.h create mode 100644 Puma/src/parser/ccparser/CCSemBinding.ah create mode 100644 Puma/src/parser/ccparser/CCSemDeclarator.h create mode 100644 Puma/src/parser/ccparser/CCSemExpr.cc create mode 100644 Puma/src/parser/ccparser/CCSemExpr.h create mode 100644 Puma/src/parser/ccparser/CCSemVisitor.cc create mode 100644 Puma/src/parser/ccparser/CCSemVisitor.h create mode 100644 Puma/src/parser/ccparser/CCSemantic.cc create mode 100644 Puma/src/parser/ccparser/CCSemantic.h create mode 100644 Puma/src/parser/ccparser/CCSyntax.cc create mode 100644 Puma/src/parser/ccparser/CCSyntax.h create mode 100644 Puma/src/parser/ccparser/DelayedParseTree.h create mode 100644 Puma/src/parser/ccparser/instantiation/CCInstantiation.cc create mode 100644 Puma/src/parser/ccparser/instantiation/CCInstantiation.h create mode 100644 Puma/src/parser/ccparser/instantiation/DeducedArgument.cc create mode 100644 Puma/src/parser/ccparser/instantiation/DeducedArgument.h create mode 100644 Puma/src/parser/ccparser/instantiation/InstantiationBuilder.h create mode 100644 Puma/src/parser/ccparser/instantiation/InstantiationCandidate.cc create mode 100644 Puma/src/parser/ccparser/instantiation/InstantiationCandidate.h create mode 100644 Puma/src/parser/ccparser/instantiation/InstantiationParser.cc create mode 100644 Puma/src/parser/ccparser/instantiation/InstantiationParser.h create mode 100644 Puma/src/parser/ccparser/instantiation/InstantiationSemantic.cc create mode 100644 Puma/src/parser/ccparser/instantiation/InstantiationSemantic.h create mode 100644 Puma/src/parser/ccparser/instantiation/InstantiationSyntax.cc create mode 100644 Puma/src/parser/ccparser/instantiation/InstantiationSyntax.h create mode 100644 Puma/src/parser/ccparser/instantiation/InstantiationTokenProvider.cc create mode 100644 Puma/src/parser/ccparser/instantiation/InstantiationTokenProvider.h create mode 100644 Puma/src/parser/ccparser/instantiation/InstantiationTokenSource.cc create mode 100644 Puma/src/parser/ccparser/instantiation/InstantiationTokenSource.h create mode 100644 Puma/src/parser/cparser/CBuilder.cc create mode 100644 Puma/src/parser/cparser/CBuilder.h create mode 100644 Puma/src/parser/cparser/CBuilderExtension.ah create mode 100644 Puma/src/parser/cparser/CExprResolveCC.ah create mode 100644 Puma/src/parser/cparser/CExprResolveH.ah create mode 100644 Puma/src/parser/cparser/CLanguage.h create mode 100644 Puma/src/parser/cparser/CLinkage.h create mode 100644 Puma/src/parser/cparser/CLookAhead.ah create mode 100644 Puma/src/parser/cparser/CParser.h create mode 100644 Puma/src/parser/cparser/CPrintVisitor.cc create mode 100644 Puma/src/parser/cparser/CPrintVisitor.h create mode 100644 Puma/src/parser/cparser/CProject.cc create mode 100644 Puma/src/parser/cparser/CProject.h create mode 100644 Puma/src/parser/cparser/CProtection.h create mode 100644 Puma/src/parser/cparser/CSemBinding.ah create mode 100644 Puma/src/parser/cparser/CSemDeclSpecs.cc create mode 100644 Puma/src/parser/cparser/CSemDeclSpecs.h create mode 100644 Puma/src/parser/cparser/CSemDeclarator.cc create mode 100644 Puma/src/parser/cparser/CSemDeclarator.h create mode 100644 Puma/src/parser/cparser/CSemExpr.cc create mode 100644 Puma/src/parser/cparser/CSemExpr.h create mode 100644 Puma/src/parser/cparser/CSemVisitor.cc create mode 100644 Puma/src/parser/cparser/CSemVisitor.h create mode 100644 Puma/src/parser/cparser/CSemantic.cc create mode 100644 Puma/src/parser/cparser/CSemantic.h create mode 100644 Puma/src/parser/cparser/CSpecifiers.h create mode 100644 Puma/src/parser/cparser/CStorage.h create mode 100644 Puma/src/parser/cparser/CStrLiteral.h create mode 100644 Puma/src/parser/cparser/CSyntax.cc create mode 100644 Puma/src/parser/cparser/CSyntax.h create mode 100644 Puma/src/parser/cparser/CTokens.h create mode 100644 Puma/src/parser/cparser/CTranslationUnit.cc create mode 100644 Puma/src/parser/cparser/CTranslationUnit.h create mode 100644 Puma/src/parser/cparser/CTree.cc create mode 100644 Puma/src/parser/cparser/CTree.h create mode 100644 Puma/src/parser/cparser/CUnit.cc create mode 100644 Puma/src/parser/cparser/CUnit.h create mode 100644 Puma/src/parser/cparser/GnuCTree.h create mode 100644 Puma/src/parser/cparser/Utf8.cc create mode 100644 Puma/src/parser/cparser/Utf8.h create mode 100644 Puma/src/parser/cparser/WinCTree.h create mode 100644 Puma/src/scanner/CCLexer.cc create mode 100644 Puma/src/scanner/CCLexer.h create mode 100644 Puma/src/scanner/CCommentTokens.h create mode 100644 Puma/src/scanner/CLexer.cc create mode 100644 Puma/src/scanner/CLexer.h create mode 100644 Puma/src/scanner/CLexerBuffer.h create mode 100644 Puma/src/scanner/CScanner.cc create mode 100644 Puma/src/scanner/CScanner.h create mode 100644 Puma/src/scanner/CWildcardTokens.h create mode 100644 Puma/src/scanner/Lexer.h create mode 100644 Puma/src/scanner/LexerBuffer.h create mode 100644 Puma/src/scanner/LexerMap.h create mode 100644 Puma/src/weave.mk create mode 100644 Puma/src/win32/Makefile create mode 100644 Puma/src/win32/ptmalloc/COPYRIGHT create mode 100644 Puma/src/win32/ptmalloc/ChangeLog create mode 100644 Puma/src/win32/ptmalloc/Makefile create mode 100644 Puma/src/win32/ptmalloc/README create mode 100644 Puma/src/win32/ptmalloc/lran2.h create mode 100644 Puma/src/win32/ptmalloc/ptmalloc.c create mode 100644 Puma/src/win32/ptmalloc/ptmalloc.h create mode 100644 Puma/src/win32/ptmalloc/sbrk.cc create mode 100644 Puma/src/win32/ptmalloc/thread-m.h create mode 100644 Puma/src/win32/quirks/Makefile create mode 100644 Puma/src/win32/quirks/Win32Quirks.h create mode 100644 Puma/tests/Makefile create mode 100644 Puma/tests/Makefile.generic create mode 100644 Puma/tests/bug10/Makefile create mode 100644 Puma/tests/bug10/bug10.cc create mode 100644 Puma/tests/bug100/Makefile create mode 100644 Puma/tests/bug100/bug100.cc create mode 100644 Puma/tests/bug102/Makefile create mode 100644 Puma/tests/bug102/bug102.cc create mode 100644 Puma/tests/bug108/Makefile create mode 100644 Puma/tests/bug108/bug108.cc create mode 100644 Puma/tests/bug108/parse.ref create mode 100644 Puma/tests/bug129/Makefile create mode 100644 Puma/tests/bug129/bug129.cc create mode 100644 Puma/tests/bug129/parse.ref create mode 100644 Puma/tests/bug130/Makefile create mode 100644 Puma/tests/bug130/bug130.cc create mode 100644 Puma/tests/bug130/parse.ref create mode 100644 Puma/tests/bug137/Makefile create mode 100644 Puma/tests/bug137/bug137.cc create mode 100644 Puma/tests/bug137/parse.ref create mode 100644 Puma/tests/bug138/Makefile create mode 100644 Puma/tests/bug138/bug138.cc create mode 100644 Puma/tests/bug138/parse.ref create mode 100644 Puma/tests/bug145/Makefile create mode 100644 Puma/tests/bug145/bug145.cc create mode 100644 Puma/tests/bug149/Makefile create mode 100644 Puma/tests/bug149/bug149.cc create mode 100644 Puma/tests/bug149/parse.ref create mode 100644 Puma/tests/bug153/Makefile create mode 100644 Puma/tests/bug153/bug153.cc create mode 100644 Puma/tests/bug153/parse.ref create mode 100644 Puma/tests/bug156/Makefile create mode 100644 Puma/tests/bug156/bug156.cc create mode 100644 Puma/tests/bug156/parse.ref create mode 100644 Puma/tests/bug164/Makefile create mode 100644 Puma/tests/bug164/bug164.cc create mode 100644 Puma/tests/bug164/parse.ref create mode 100644 Puma/tests/bug166/Makefile create mode 100644 Puma/tests/bug166/bug166.cc create mode 100644 Puma/tests/bug166/parse.ref create mode 100644 Puma/tests/bug180/Makefile create mode 100644 Puma/tests/bug180/bug180.cc create mode 100644 Puma/tests/bug180/parse.ref create mode 100644 Puma/tests/bug182/Makefile create mode 100644 Puma/tests/bug182/bug182.cc create mode 100644 Puma/tests/bug182/parse.ref create mode 100644 Puma/tests/bug187/Makefile create mode 100644 Puma/tests/bug187/bug187.cc create mode 100644 Puma/tests/bug188/Makefile create mode 100644 Puma/tests/bug188/bug188.cc create mode 100644 Puma/tests/bug189/Makefile create mode 100644 Puma/tests/bug189/bug189.cc create mode 100644 Puma/tests/bug2/Makefile create mode 100644 Puma/tests/bug2/bug2.cc create mode 100644 Puma/tests/bug2/parse.ref create mode 100644 Puma/tests/bug203/Makefile create mode 100644 Puma/tests/bug203/bug203.cc create mode 100644 Puma/tests/bug203/parse.ref create mode 100644 Puma/tests/bug218/Makefile create mode 100644 Puma/tests/bug218/bug218.cc create mode 100644 Puma/tests/bug218/parse.ref create mode 100644 Puma/tests/bug220/Makefile create mode 100644 Puma/tests/bug220/bug220.cc create mode 100644 Puma/tests/bug232/Makefile create mode 100644 Puma/tests/bug232/bug232.cc create mode 100644 Puma/tests/bug248/Makefile create mode 100644 Puma/tests/bug248/bug248.cc create mode 100644 Puma/tests/bug248/parse.ref create mode 100644 Puma/tests/bug249/Makefile create mode 100644 Puma/tests/bug249/bug249.cc create mode 100644 Puma/tests/bug258/Makefile create mode 100644 Puma/tests/bug258/bug258.cc create mode 100644 Puma/tests/bug259/Makefile create mode 100644 Puma/tests/bug259/bug259.cc create mode 100644 Puma/tests/bug259/parse.ref create mode 100644 Puma/tests/bug264/Makefile create mode 100644 Puma/tests/bug264/bug264.cc create mode 100644 Puma/tests/bug269/Makefile create mode 100644 Puma/tests/bug269/bug269.cc create mode 100644 Puma/tests/bug269/parse.ref create mode 100644 Puma/tests/bug273/Makefile create mode 100644 Puma/tests/bug273/bug273.cc create mode 100644 Puma/tests/bug273/parse.ref create mode 100644 Puma/tests/bug274/Makefile create mode 100644 Puma/tests/bug274/bug274.cc create mode 100644 Puma/tests/bug275/Makefile create mode 100644 Puma/tests/bug275/bug275.cc create mode 100644 Puma/tests/bug287/Makefile create mode 100644 Puma/tests/bug287/bug287.cc create mode 100644 Puma/tests/bug289/Makefile create mode 100644 Puma/tests/bug289/bug289.cc create mode 100644 Puma/tests/bug3/Makefile create mode 100644 Puma/tests/bug3/bug3.cc create mode 100644 Puma/tests/bug3/bug3_1.cc create mode 100644 Puma/tests/bug3/parse.ref create mode 100644 Puma/tests/bug303/Makefile create mode 100644 Puma/tests/bug303/bug303.cc create mode 100644 Puma/tests/bug305/Makefile create mode 100644 Puma/tests/bug305/bug305.cc create mode 100644 Puma/tests/bug307/Makefile create mode 100644 Puma/tests/bug307/bug307.cc create mode 100644 Puma/tests/bug320/Makefile create mode 100644 Puma/tests/bug320/bug320.cc create mode 100644 Puma/tests/bug320/parse.ref create mode 100644 Puma/tests/bug325/Makefile create mode 100644 Puma/tests/bug325/bug325.cc create mode 100644 Puma/tests/bug326/Makefile create mode 100644 Puma/tests/bug326/bug326.cc create mode 100644 Puma/tests/bug326/parse.ref create mode 100644 Puma/tests/bug328/Makefile create mode 100644 Puma/tests/bug328/bug328.cc create mode 100644 Puma/tests/bug328/parse.ref create mode 100644 Puma/tests/bug332/Makefile create mode 100644 Puma/tests/bug332/bug332.cc create mode 100644 Puma/tests/bug332/parse.ref create mode 100644 Puma/tests/bug333/Makefile create mode 100644 Puma/tests/bug333/bug333.cc create mode 100644 Puma/tests/bug333/parse.ref create mode 100644 Puma/tests/bug337/Makefile create mode 100644 Puma/tests/bug337/bug337.cc create mode 100644 Puma/tests/bug337/parse.ref create mode 100644 Puma/tests/bug338/Makefile create mode 100644 Puma/tests/bug338/bug338.cc create mode 100644 Puma/tests/bug339/Makefile create mode 100644 Puma/tests/bug339/bug339.cc create mode 100644 Puma/tests/bug339/parse.ref create mode 100644 Puma/tests/bug340/Makefile create mode 100644 Puma/tests/bug340/bug340-2.cc create mode 100644 Puma/tests/bug340/bug340-3.cc create mode 100644 Puma/tests/bug340/bug340-4.cc create mode 100644 Puma/tests/bug340/bug340-5.cc create mode 100644 Puma/tests/bug340/bug340.cc create mode 100644 Puma/tests/bug340/parse.ref create mode 100644 Puma/tests/bug342/Makefile create mode 100644 Puma/tests/bug342/bug342.cc create mode 100644 Puma/tests/bug343/Makefile create mode 100644 Puma/tests/bug343/test1.cc create mode 100644 Puma/tests/bug343/test2.cc create mode 100644 Puma/tests/bug344/Makefile create mode 100644 Puma/tests/bug344/bug344.cc create mode 100644 Puma/tests/bug344/parse.ref create mode 100644 Puma/tests/bug345/Makefile create mode 100644 Puma/tests/bug345/bug345.cc create mode 100644 Puma/tests/bug345/parse.ref create mode 100644 Puma/tests/bug346/Makefile create mode 100644 Puma/tests/bug346/bug346.cc create mode 100644 Puma/tests/bug346/parse.ref create mode 100644 Puma/tests/bug347/Makefile create mode 100644 Puma/tests/bug347/bug347.cc create mode 100644 Puma/tests/bug348/Makefile create mode 100644 Puma/tests/bug348/bug348.cc create mode 100644 Puma/tests/bug350/Makefile create mode 100644 Puma/tests/bug350/bug350.cc create mode 100644 Puma/tests/bug350/parse.ref create mode 100644 Puma/tests/bug363/Makefile create mode 100644 Puma/tests/bug363/bug363.cc create mode 100644 Puma/tests/bug363/parse.ref create mode 100644 Puma/tests/bug364/Makefile create mode 100644 Puma/tests/bug364/bug364.cc create mode 100644 Puma/tests/bug5/Makefile create mode 100644 Puma/tests/bug5/bug5.cc create mode 100644 Puma/tests/bug5/parse.ref create mode 100644 Puma/tests/bug6/Makefile create mode 100644 Puma/tests/bug6/bug6.cc create mode 100644 Puma/tests/bug6/parse.ref create mode 100644 Puma/tests/bug61/Makefile create mode 100644 Puma/tests/bug61/bug61.cc create mode 100644 Puma/tests/bug94/Makefile create mode 100644 Puma/tests/bug94/bug94.cc create mode 100644 Puma/tests/bug94/parse.ref create mode 100644 Puma/tests/bug96/Makefile create mode 100644 Puma/tests/bug96/bug96.cc create mode 100644 Puma/tests/bug96/parse.ref create mode 100644 Puma/tests/misc/Makefile create mode 100644 Puma/tests/misc/parse.ref create mode 100644 Puma/tests/misc/test1.cc create mode 100644 Puma/tests/misc/test10.cc create mode 100644 Puma/tests/misc/test11.cc create mode 100644 Puma/tests/misc/test12.cc create mode 100644 Puma/tests/misc/test13.cc create mode 100644 Puma/tests/misc/test14.cc create mode 100644 Puma/tests/misc/test15.cc create mode 100644 Puma/tests/misc/test16.cc create mode 100644 Puma/tests/misc/test17.cc create mode 100644 Puma/tests/misc/test18.cc create mode 100644 Puma/tests/misc/test19.cc create mode 100644 Puma/tests/misc/test2.cc create mode 100644 Puma/tests/misc/test20.cc create mode 100644 Puma/tests/misc/test21.cc create mode 100644 Puma/tests/misc/test22.cc create mode 100644 Puma/tests/misc/test3.cc create mode 100644 Puma/tests/misc/test4.cc create mode 100644 Puma/tests/misc/test5.cc create mode 100644 Puma/tests/misc/test6.cc create mode 100644 Puma/tests/misc/test7.cc create mode 100644 Puma/tests/misc/test8.cc create mode 100644 Puma/tests/misc/test9.cc create mode 100644 Puma/tools/EclipseCodeFormatterSettings.xml create mode 100644 Puma/tools/Makefile create mode 100644 Puma/tools/gen_vcpp_proj.sh create mode 100644 Puma/tools/lemon/Makefile create mode 100644 Puma/tools/lemon/README create mode 100644 Puma/tools/lemon/lemon.c create mode 100644 Puma/tools/lemon/lemon.c.orig create mode 100644 Puma/tools/lemon/lempar.c create mode 100644 Puma/tools/lemon/lempar.c.orig create mode 100644 Puma/tools/prof/Makefile create mode 100644 Puma/tools/prof/README create mode 100644 Puma/tools/prof/plot.py create mode 100644 Puma/vars.mk create mode 100644 README diff --git a/Ag++/.cproject b/Ag++/.cproject new file mode 100644 index 0000000..e8999ae --- /dev/null +++ b/Ag++/.cproject @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + make + + all + true + true + true + + + make + + test + true + true + true + + + + + diff --git a/Ag++/.project b/Ag++/.project new file mode 100644 index 0000000..9d00923 --- /dev/null +++ b/Ag++/.project @@ -0,0 +1,79 @@ + + + Ag++ + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + ?name? + + + + org.eclipse.cdt.make.core.append_environment + true + + + org.eclipse.cdt.make.core.autoBuildTarget + all + + + org.eclipse.cdt.make.core.buildArguments + SHARED=1 -j6 + + + org.eclipse.cdt.make.core.buildCommand + make + + + org.eclipse.cdt.make.core.cleanBuildTarget + clean + + + org.eclipse.cdt.make.core.contents + org.eclipse.cdt.make.core.activeConfigSettings + + + org.eclipse.cdt.make.core.enableAutoBuild + false + + + org.eclipse.cdt.make.core.enableCleanBuild + true + + + org.eclipse.cdt.make.core.enableFullBuild + true + + + org.eclipse.cdt.make.core.fullBuildTarget + all + + + org.eclipse.cdt.make.core.stopOnError + true + + + org.eclipse.cdt.make.core.useDefaultBuildCmd + false + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/Ag++/ACCompiler.cc b/Ag++/ACCompiler.cc new file mode 100644 index 0000000..23bcd4c --- /dev/null +++ b/Ag++/ACCompiler.cc @@ -0,0 +1,127 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2004 The 'ac++' developers (see aspectc.org) +// +// 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 "ACCompiler.h" +#include "System.h" +#include "regex.h" +#include "file.h" + +//stdc++ includes +#include +using namespace std; +using namespace file; + +//Puma includes +#include "Puma/VerboseMgr.h" +#include "Puma/SysCall.h" + +bool +ACCompiler::execute() +{ + + VerboseMgr vm(cout, _config.verbose()); + vm << "Weaving" << endvm; + + // command line string + string exec_str = "\"" + _config.acc_bin() + "\" --system-config \"" + + _config.pumaconfig_file() + "\" " + + _config.optvec().getString(OptionItem::OPT_ACC, OptionItem::OPT_FILE); + + // get output path for .acc files from -o option + string acc_output_path = _config.output_file(); + file::stripFilename(acc_output_path); + + // loop through all options searching a file + OptionVec::iterator opt = _config.optvec().begin(); + while (opt != _config.optvec().end()) + { + // skip all options that are not a file which should be processed by + // AspectC++ + if ((opt->flag() & (OptionItem::OPT_ACC | OptionItem::OPT_FILE)) + != (OptionItem::OPT_ACC | OptionItem::OPT_FILE)) + { + opt++; + continue; + } + + const string file = opt->name(); + + //construct name for output file + string out_file; + + // if an output file for the woven result is not specified on command line + // or the file(s) shall be compiled after weaving put an intermediate .acc file + // in acc_output_path + if (_config.compile() == true || _config.output_file().empty()) + { + //if we do not want to keep the intermediate acc files + //generate files in the systems temporary directory + if (_config.keep_woven() == false) + { + string prefix(file); + stripPath(prefix); + prefix.append("_agxx_"); + char* tmp_file = (char*) Puma::SysCall::mktemp(prefix.c_str(), &_err); + out_file = tmp_file; + free(tmp_file); + } + //otherwise create name of output file from name of output file + else + { + string tmp(file); + stripPath(tmp); + out_file = tmp; + int endpos = out_file.rfind('.'); + out_file.replace(endpos, string::npos, ".acc"); + out_file = acc_output_path + out_file; + } + } + else + { + out_file = _config.output_file(); + } + + // construct final command string + string local_exec_str = exec_str + " -c \"" + file + "\" -o \"" + out_file + + "\""; + + // execute AspectC++ + System acc(_err, _config, local_exec_str); + + //change filename in input_file list, so that the next steps + //get the proper filename + opt->name(out_file); + opt->flag(opt->flag() | (OptionItem::OPT_GCC)); + + if (!acc.execute()) + { + return false; + } + + opt++; + } + + // Call Aspect C++ once in case there are no input files + if ((_config.nr_files() == 0) && (_config.run_acpp_without_input() == true)) + { + System acc(_err, _config, exec_str); + return acc.execute(); + } + + return true; +} diff --git a/Ag++/ACCompiler.h b/Ag++/ACCompiler.h new file mode 100644 index 0000000..2bcf328 --- /dev/null +++ b/Ag++/ACCompiler.h @@ -0,0 +1,39 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2004 The 'ac++' developers (see aspectc.org) +// +// 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 __ACCompiler_h__ +#define __ACCompiler_h__ + +#include "Compiler.h" +#include "AGxxConfig.h" +class ACCompiler : public Compiler +{ + +public: + ACCompiler(ErrorStream& e, AGxxConfig& c) : + Compiler(e, c) + { + } + ~ACCompiler() + { + } + bool + execute(); +}; + +#endif // __ACCompiler_h__ diff --git a/Ag++/AGxxConfig.cc b/Ag++/AGxxConfig.cc new file mode 100644 index 0000000..d5e1f28 --- /dev/null +++ b/Ag++/AGxxConfig.cc @@ -0,0 +1,690 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2004 The 'ac++' developers (see aspectc.org) +// +// 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 "version.h" +#include "AGxxConfig.h" +#include "file.h" +#include "regex.h" + +// PUMA includes +#include "Puma/StrCol.h" +#include "Puma/OptsParser.h" +#include "Puma/ParserKey.h" +#include "Puma/VerboseMgr.h" +using namespace Puma; + +//stdc++ includes +#include +#include + +// standard C library includes +#include + +// get the size of an array +#define ARRAY_SIZE(array) ((sizeof (array)) / (sizeof ((array)[0]))) + +string AGxxConfig::_gcc_option_arg[] = { "-aux-info", "-print-prog-name=", + "-print-file-name=", "-idirafter", "-imacros", "-iprefix", "-iwithprefix", + "-iwithprefixbefore", "-isystem", "--gen_size_type", "-B", "-l", "-I", "-L", + "-specs=", "-MF", "-MT", "-MQ", "-x", "--param=", "--param", "-Xlinker", + "-u", "-V", "-b", "-G", }; + +string AGxxConfig::_gcc_option_info[] = { "-print","-dump", }; + +// options for AC++ Compiler +static OptsParser::Option options[] = { + { AGxxConfig::AGOPT_GEN_CFG, NULL, "gen_config", + "\t" "Only generate Puma configuration file", OptsParser::AT_NONE }, + { AGxxConfig::AGOPT_WEAVE_ONLY, NULL, "weave_only", + "\t" "Weave only", OptsParser::AT_NONE }, + { AGxxConfig::AGOPT_COMPILE_ONLY, "c", NULL, + "\t\t" "Compile only", OptsParser::AT_NONE }, + { AGxxConfig::AGOPT_KEEP_WOVEN,NULL, "keep_woven", + "\t" "Keep woven source code files", OptsParser::AT_NONE }, + { AGxxConfig::AGOPT_KEEP_WOVEN,NULL, "keep_acc", + "\t" "Deprecated. Use keep_woven instead", OptsParser::AT_NONE }, + { AGxxConfig::AGOPT_CC, NULL, "c_compiler", + "Path to C++ compiler", OptsParser::AT_MANDATORY }, + { AGxxConfig::AGOPT_ACC, NULL, "ac_compiler", + "Path to AspectC++ compiler", OptsParser::AT_MANDATORY }, + { AGxxConfig::AGOPT_OUTPUT, "o", "output", + "\t" "Name of the output file", OptsParser::AT_MANDATORY }, + { AGxxConfig::AGOPT_CONFIG_COMMAND,NULL, "config_command", + "Command which prints information about compiler", OptsParser::AT_MANDATORY }, + { AGxxConfig::AGOPT_X_COMPILER,NULL, "Xcompiler", + "\tIn case of doubt account following options as g++ options", OptsParser::AT_NONE }, + { AGxxConfig::AGOPT_X_WEAVER,NULL, "Xweaver", + "\t\tIn case of doubt account following options as ac++ options", OptsParser::AT_NONE }, + { AGxxConfig::AGOPT_HELP, "h", "help", + "\t\t" "Print this help meassage", OptsParser::AT_NONE }, + { AGxxConfig::AGOPT_VERSION, NULL, "version", + "\t" "\t" "Version information", OptsParser::AT_NONE }, + { AGxxConfig::AGOPT_VERBOSE, "v", "verbose", + "Level of verbosity (0-9)", OptsParser::AT_OPTIONAL }, + { AGxxConfig::ACOPT_INCLUDE_FILES, "i", "include_files", + "Generate manipulated header files", OptsParser::AT_NONE }, + { AGxxConfig::ACOPT_ASPECT_HEADER, "a", "aspect_header", + "Name of aspect header file or '0'", OptsParser::AT_MANDATORY }, + { AGxxConfig::ACOPT_QUOTE_ARG, "r", "repository", + "Name of the project repository", OptsParser::AT_MANDATORY }, + { AGxxConfig::ACOPT_MATCH_POINTCUT_EXPR, NULL, "expr", + "\t" "Pointcut expression to match in repository", OptsParser::AT_MANDATORY}, + { AGxxConfig::ACOPT, NULL, "problem_local_class", + "Back-end does not support local classes correctly", OptsParser::AT_NONE }, + { AGxxConfig::ACOPT, NULL, "no_problem_local_class", + "Back-end supports local classes correctly", OptsParser::AT_NONE }, + { AGxxConfig::ACOPT, NULL, "problem_spec_scope", + "Back-end does not support template specialization in non-namespace",OptsParser::AT_NONE }, + { AGxxConfig::ACOPT, NULL, "no_problem_spec_scope", + "Back-end supports template specialization in non-namespace scope",OptsParser::AT_NONE }, + { AGxxConfig::ACOPT, NULL, "problem_force_inline", + "Back-end does not support forced inlining correctly", OptsParser::AT_NONE }, + { AGxxConfig::ACOPT, NULL, "no_problem_force_inline", + "Back-end supports forced inlining correctly", OptsParser::AT_NONE }, + { AGxxConfig::ACOPT, NULL, "warn_deprecated", + "\t" "Warn if deprecated syntax is used", OptsParser::AT_NONE }, + { AGxxConfig::ACOPT, NULL, "no_warn_deprecated", + "Don't warn if deprecated syntax is used", OptsParser::AT_NONE }, + { AGxxConfig::ACOPT, NULL, "warn_macro", + "\t" "Warn if a macro transformation had to be ignored", OptsParser::AT_NONE }, + { AGxxConfig::ACOPT, NULL, "no_warn_macro", + "\t" "Don't warn if a macro transformation had to be ignored", OptsParser::AT_NONE }, + { AGxxConfig::ACOPT, NULL, "warn_limitations", + "" "Warn if a feature does not work as familiar due to limitations", OptsParser::AT_NONE }, + { AGxxConfig::ACOPT, NULL, "no_warn_limitations", + "" "Don't warn if a feature does not work as familiar due to limitations", OptsParser::AT_NONE }, + { AGxxConfig::ACOPT, NULL,"no_line", + "\t\t" "Don't generate #line directives",OptsParser::AT_NONE }, + { AGxxConfig::ACOPT_QUOTE_ARG, NULL, "gen_size_type", + "Argument type for generated new operator", OptsParser::AT_MANDATORY}, + { AGxxConfig::ACOPT, NULL,"real-instances", + "\t" "Perform full template analysis",OptsParser::AT_NONE }, + { AGxxConfig::ACOPT, NULL,"pseudo-instances", + "Simplified template instantiation scheme (deprecated)",OptsParser::AT_NONE }, + { AGxxConfig::ACOPT_PROJ_PATH, "p", "path", + "\t" "Path to project source", OptsParser::AT_MANDATORY}, + { AGxxConfig::ACOPT_PROJ_DESTINATION, "d", "dest", + "\t" "Path to destination for modified include files", OptsParser::AT_MANDATORY}, + { AGxxConfig::ACOPT_CFG_FILE, NULL, "config", + "\t" "Full path to a config file", OptsParser::AT_MANDATORY}, + { AGxxConfig::ACOPT_SYS_CFG_FILE, NULL, "system-config", + "Full path to a system config file (lower priority options)", OptsParser::AT_MANDATORY}, + { AGxxConfig::AGOPT_TARGET, NULL, "target", + "\t" "Override the compiler's target triple", OptsParser::AT_MANDATORY}, + { AGxxConfig::ACOPT_PRE_INCLUDE, "I", NULL, + "\t\t" "Add new include path", OptsParser::AT_MANDATORY}, + { AGxxConfig::ACOPT_PRE_DEFINE, "D", NULL, + "\t\t" "Define a preprocessor macro", OptsParser::AT_MANDATORY}, + { AGxxConfig::ACOPT_PRE_UNDEFINE, "U", NULL, + "\t\t" "Undefine a preprocessor macro", OptsParser::AT_MANDATORY}, + { AGxxConfig::ACOPT_ALWAYS_INCLUDE, "include", "include", + "Always include file", OptsParser::AT_MANDATORY}, + { AGxxConfig::ACOPT, "k", "keywords", + "\t" "Allow AspectC++ keywords in normal project files", OptsParser::AT_NONE}, + { AGxxConfig::ACOPT, NULL, "dynamic", + "\t\t" "Prepare generated code for dynamic weaving", OptsParser::AT_NONE }, + { AGxxConfig::ACOPT, NULL, "introspection", + "\t" "Support introspection mechanism", OptsParser::AT_NONE }, + { AGxxConfig::ACOPT, NULL, "flow_analysis", + "\t" "Support control-flow analysis and data-flow analysis", OptsParser::AT_NONE }, + { AGxxConfig::ACOPT, NULL, "builtin_operators", + "Support joinpoints on builtin operator calls", OptsParser::AT_NONE }, + { AGxxConfig::ACOPT, NULL, "data_joinpoints", + "\t" "Support data-based joinpoints like get(), set(), ...", OptsParser::AT_NONE }, + { AGxxConfig::ACOPT, NULL, "attributes", + "\t" "Support user-defined attributes", OptsParser::AT_NONE }, + { AGxxConfig::ACOPT, NULL, "no_attributes", + "\t" "Disable support user-defined attributes", OptsParser::AT_NONE }, + { AGxxConfig::ACOPT_SYS_INCLUDE, "isystem", NULL, + "\t" "Add system include path", OptsParser::AT_MANDATORY}, + { AGxxConfig::ACOPT_QUOTE_ARG, NULL, "warn_compatibility", + "Enable migration warnings for code based on major version ", OptsParser::AT_MANDATORY }, + { 0, 0, 0, 0, OptsParser::AT_NONE} +}; + +void +AGxxConfig::usage() const +{ + _err << "usage: ag++ [options] [file...]" << endMessage + << " options are ..." << endMessage; + for (int i = 0; options[i].number > 0; i++) + { + _err << " "; + if (options[i].shortName) + _err << "-" << options[i].shortName; + if (options[i].shortName && options[i].longName) + _err << "|"; + if (options[i].longName) + _err << "--" << options[i].longName; + if (options[i].argType != OptsParser::AT_NONE) + _err << " "; + if (options[i].desc) + _err << " \t" << options[i].desc; + _err << endMessage; + } +} + +bool +AGxxConfig::parseGccOpt(OptsParser &op) +{ + + // option which should be analyzed + string opt = op.getOptionName() + op.getArgument(); + + // argument for this option + string arg(""); + + //check for -M/-MM option for generating dependency information + if (opt.compare("-M") == 0 || opt.compare("-MM") == 0) + { + _make_dep = true; + _optvec.pushback(opt, OptionItem::OPT_GCC); + return true; + } + + // check if option is in list of gcc options which require an option argument + for (unsigned int i = 0U; i < ARRAY_SIZE(_gcc_option_arg); i++) + { + const string option_arg_str = _gcc_option_arg[i]; + if (opt.compare(0, option_arg_str.length(), option_arg_str) == 0) + { + + // option requires an argument + + // check if the argument is appended to the option name + if (opt.length() > option_arg_str.length()) + { + unsigned int arg_start_pos = option_arg_str.length(); + + // extract the argument out of the option name + arg = "\"" + opt.substr(arg_start_pos) + "\""; + opt = opt.substr(0, option_arg_str.length()); + } + else + { + // check if there exist another option on command line + if (op.getRawOption() != OptsParser::FINISH) + { + // append argument to string of arguments + arg = " \"" + op.getArgument() + "\" "; + } + else + { + // there is no option anymore + _err << sev_error << "G++ Option requires argument: "; + _err << "'" << opt.c_str() << "'" << endMessage; + return false; + } + } + break; + } + } + + // check if option only causes the gcc to print information + for (unsigned int i = 0U; i < ARRAY_SIZE(_gcc_option_info); i++) + { + string option_info_str = _gcc_option_info[i]; + if (opt.compare(0, option_info_str.length(), option_info_str) == 0) + { + _print_gcc_info = true; + break; + } + } + + _optvec.pushback(opt, arg, OptionItem::OPT_GCC | OptionItem::OPT_CONFIG); + return true; + +} + +bool +AGxxConfig::analyze() +{ + bool ret; + + // setup default values + _gen_pumaconfig = true; + _weave = false; + _compile = false; + _link = false; + + _verbose = 0; + _nr_files = 0; + + _pumaconfig_tmp = true; + _print_gcc_info = false; + _weave_only = false; + _keep_woven = false; + _gen_includes = false; + _cc_bin = "g++"; + _compile_only = false; + _make_dep = false; + _x_compiler = false; + _run_acpp_without_input = false; + + // parse Options received from command line + ret = parseOptions(); + + if (ret == true) + { + // analyze Options received from command line + ret = analyzeOptions(); + } + + return ret; +} + +bool +AGxxConfig::parseOptions() +{ + // use the PUMA option parser for parsing + OptsParser op(_argc, _argv, options); + + // extract options/filenames out of command line arguments + while (op.getOption() != OptsParser::FINISH) + { + + // + // first parse options which do not interfere with g++ + // options + // + switch (op.getResult()) + { + + case AGOPT_OUTPUT: + _output_file = op.getArgument(); + _optvec.pushback("-o", " \"" + op.getArgument() + "\" ", + (OptionItem::OPT_GCC)); + continue; + + case AGOPT_COMPILE_ONLY: + _compile_only = true; + _optvec.pushback("-c", OptionItem::OPT_GCC); + continue; + + case AGOPT_X_COMPILER: + _x_compiler = true; + continue; + + case AGOPT_X_WEAVER: + _x_compiler = false; + continue; + + case AGOPT_TARGET: + _command_line_target_triple = op.getArgument(); + continue; + + case ACOPT_CFG_FILE: + _optvec.pushback("--config", " \"" + op.getArgument() + "\" ", + (OptionItem::OPT_ACC)); + continue; + + case ACOPT_SYS_CFG_FILE: + _pumaconfig_file = op.getArgument(); + _pumaconfig_tmp = false; + continue; + + case ACOPT_PRE_DEFINE: + { + string tmpStr = op.getArgument(); + _optvec.pushback("-D", + " \"" + str_replace_all(tmpStr, "\"", "\\\"") + "\" ", + (OptionItem::OPT_ACC | OptionItem::OPT_GCC)); + } + continue; + + case ACOPT_PRE_UNDEFINE: + _optvec.pushback("-U", " \"" + op.getArgument() + "\" ", + (OptionItem::OPT_ACC | OptionItem::OPT_GCC)); + continue; + + case ACOPT_PRE_INCLUDE: + _optvec.pushback("-I", " \"" + op.getArgument() + "\" ", + (OptionItem::OPT_ACC | OptionItem::OPT_GCC)); + continue; + + case ACOPT_SYS_INCLUDE: + _optvec.pushback("--isystem", " \"" + op.getArgument() + "\" ", + (OptionItem::OPT_ACC )); + _optvec.pushback("-isystem", " \"" + op.getArgument() + "\" ", + (OptionItem::OPT_GCC)); + continue; + + case ACOPT_ALWAYS_INCLUDE: + _optvec.pushback("--include", " \"" + op.getArgument() + "\" ", + OptionItem::OPT_ACC); + // Weaver generates #includes, Thus, g++ does need -include only for + // dependency list generation + _optvec.pushback("-include", " \"" + op.getArgument() + "\" ", + OptionItem::OPT_DEP); + continue; + + // command line arguments which are not accepted as options + // are recognized as filenames + case OptsParser::NOOPTION: + ++_nr_files; + // if file is a c++ file weave it first. + if (regex::regExMatch( + "^.*\\.((C)|(c)|(cc)|(cp)|(cpp)|(cxx)|(c\\+\\+))$", + op.getArgument().c_str())) + { + _optvec.pushback(op.getArgument(), + (OptionItem::OPT_ACC | OptionItem::OPT_FILE)); + + // when calling we have to pass the original path of this + // source dir as include path, as the '.acc' file to be + // compiled will probably not be generated in the same + // directory + string tmpStr = op.getArgument(); + file::stripFilename(tmpStr, false); + if (tmpStr.empty()) + { + tmpStr = "."; + } + _optvec.pushback("-I", " \"" + tmpStr + "\" ", OptionItem::OPT_GCC); + } + else + { + _optvec.pushback(op.getArgument(), + (OptionItem::OPT_GCC | OptionItem::OPT_FILE)); + } + continue; + } + + // if _x_compiler is set to 'true' interprete + // options that are not handled within the previous + // 'switch-case' statement as gcc options. + if (_x_compiler == true) + { + if (parseGccOpt(op) == false) + { + return false; + } + continue; + } + + switch (op.getResult()) + { + + case AGOPT_HELP: + usage(); + return false; + + case AGOPT_VERSION: + cout << "ag++ " << _VERSION <<" built: " << __DATE__<< endl; + return false; + + case AGOPT_GEN_CFG: + _pumaconfig_tmp = false; + break; + + case AGOPT_WEAVE_ONLY: + _weave_only = true; + _keep_woven = true; + break; + + case AGOPT_ACC: + _acc_bin = op.getArgument(); + break; + + case AGOPT_CC: + _cc_bin = op.getArgument(); + break; + + case AGOPT_KEEP_WOVEN: + if (op.getOptionName() == "--keep_acc") + { + _err << sev_warning + << "Usage of --keep_acc is deprecated use --keep_woven instead" + << endMessage; + } + _keep_woven = true; + break; + + case AGOPT_CONFIG_COMMAND: + _config_command = op.getArgument(); + break; + + // default handling for Aspect C++ options + case ACOPT: + _optvec.pushback(op.getOptionName(), op.getArgument(), + OptionItem::OPT_ACC); + break; + + // default handling for Aspect C++ options + // where the argument has to be quoted + case ACOPT_QUOTE_ARG: + _optvec.pushback(op.getOptionName(), " \""+op.getArgument()+"\"", + OptionItem::OPT_ACC); + break; + + case ACOPT_WITHOUT_INPUT: + _run_acpp_without_input = true; + _weave_only = true; + _optvec.pushback(op.getOptionName(), op.getArgument(), + OptionItem::OPT_ACC); + break; + + case ACOPT_INCLUDE_FILES: + _gen_includes = true; + _run_acpp_without_input = true; + _optvec.pushback("-i","",OptionItem::OPT_ACC); + break; + + case ACOPT_MATCH_POINTCUT_EXPR: + { + string argumentStr = op.getUnstrippedArgument(); + _run_acpp_without_input = true; + _weave_only = true; + _optvec.pushback("--expr","\""+str_replace_all(argumentStr, "\"", "\\\"")+"\"", + OptionItem::OPT_ACC); + } + break; + + + case AGOPT_VERBOSE: + if (op.getArgument().empty()) + { + // -v without number + _optvec.pushback("-v", "1", OptionItem::OPT_ACC); + _verbose = 1; + } + else + { + _optvec.pushback("-v", op.getArgument(), OptionItem::OPT_ACC); + _verbose = atoi(op.getArgument().c_str()); + } + if (_verbose > 6) + { + _optvec.pushback("-v", OptionItem::OPT_GCC); + } + break; + + case ACOPT_ASPECT_HEADER: + _ah_files.push_back(op.getArgument()); + _optvec.pushback("-a", " \"" + op.getArgument() + "\" ", + OptionItem::OPT_ACC); + break; + + case ACOPT_PROJ_PATH: + _proj_path.push_back(op.getArgument()); + _optvec.pushback("-p", " \"" + op.getArgument() + "\" ", + OptionItem::OPT_ACC); + break; + + case ACOPT_PROJ_DESTINATION: + _dest_path = op.getArgument(); + _optvec.pushback("--dest","\""+_dest_path+"\"",OptionItem::OPT_ACC); + break; + + case OptsParser::NOARG: + _err << sev_error << "Option requires argument: "; + _err << "'" << op.getOptionName().c_str() << "'" << endMessage; + return false; + + case OptsParser::ERR: + _err << sev_error << " Parsing Options : "; + _err << "unspecified error at "; + _err << "'" << op.getOptionName().c_str() << " " + << op.getArgument().c_str() << "'" << endMessage; + return false; + + // unknown options are recognized as g++ options + case OptsParser::UNKNOWN: + if (parseGccOpt(op) == false) + { + return false; + } + break; + + default: + _err << sev_error << " Parsing Options : "; + _err << "option not handled by Ag++ "; + _err << "'" << op.getOptionName().c_str() << " " + << op.getArgument().c_str() << "'" << endMessage; + return false; + } + } + return true; +} + +bool +AGxxConfig::analyzeOptions() +{ + // if we are compiling for WIN32 target transform paths to dos + // format, bacause the shell(cmd.exe) can not handle unix + // paths +#if defined (WIN32) + file::MakeDosPath(_acc_bin); + file::MakeDosPath(_cc_bin); +#endif + + // if path to ac++ was not specified in options. + // get it from ARGV[0] + if (_acc_bin.empty()) + { + _acc_bin = _argv[0]; + file::stripFilename(_acc_bin); + _acc_bin.append("ac++"); + } + + // if there was no project path specified + // take local directory ('.') + if (_proj_path.empty()) + { + _proj_path.push_back("."); + _optvec.pushback("-p", ".", OptionItem::OPT_ACC); + } + + // check if puma config file shall be generated + if ((_print_gcc_info == true) || (_make_dep == true)) + { + _gen_pumaconfig = false; + _pumaconfig_tmp = false; + } + + // check if source files shall be woven + if (((_print_gcc_info == false) && (_make_dep == false) && (_nr_files > 0)) + || (_run_acpp_without_input == true)) + { + _weave = true; + } + + // check if source files shall be translated + if (((_weave_only == false) && (_gen_includes == false) && (_nr_files > 0)) + || (_print_gcc_info == true)) + { + _compile = true; + } + + // check if source files shall be linked + if ((_print_gcc_info == false) && (_weave_only == false) + && (_gen_includes == false) && (_compile_only == false) + && (_make_dep == false) && (_nr_files > 0)) + { + _link = true; + } + + // + // Check Constraints + // + + // if modified include files are NOT created and only a temporary + // puma configuration file is generated ag++ expects some input files + if ((_print_gcc_info == false) && (_pumaconfig_tmp == true) + && (_run_acpp_without_input == false) && (_nr_files == 0)) + { + _err << sev_error << "No input files" << endMessage; + return false; + } + + // If modified include files are created a destination + // path must be specified + if ((_gen_includes == true) && _dest_path.empty()) + { + _err << sev_error << "Need to specify a destination path in order " + << "to generate modified include files" << endMessage; + return false; + } + + // Check destination path is given without creating the modified include + // files + // + // Rationale: + // - destination path is only used in WTP mode + // - WTP mode is only used if --include_files is + // specified + if ((_gen_includes == false) && (! _dest_path.empty())) + { + _err << sev_error << "Destination path (-d|--dest) may only be " + << "specified when generating modified include files " + << "(-i|--include_files)" << endMessage; + return false; + } + + // If '--weave-only' and '-o' options are used with multiple files + // exit with an error + if ((_weave_only == true) && (_output_file.empty() == false) + && (_nr_files > 1)) + { + _err << sev_error + << "Cannot specify -o with --weave_only and multiple compilations" + << endMessage; + return false; + } + + return true; +} + +void +AGxxConfig::printOptions() +{ + VerboseMgr vm(cout, _verbose); + vm << endvm; + vm << endvm; + vm << "AG++ Configuration:" << endvm; + vm << " Aspect C++ weaver: " << _acc_bin << endvm; + vm << " C++ compiler: " << _cc_bin << endvm; + vm << " Files: " << _optvec.getString(OptionItem::OPT_FILE) << endvm; + vm << " Options (G++): " << _optvec.getString(OptionItem::OPT_GCC, OptionItem::OPT_FILE) << endvm; + vm << " Options (AC++): " << _optvec.getString(OptionItem::OPT_ACC, OptionItem::OPT_FILE) << endvm; + vm << " Options (total): " << _optvec.getString() << endvm; + vm << " PumaConfig: " << _gen_pumaconfig << " Weave: " << _weave << " Compile: " << _compile << " Link: " << _link << endvm; + vm << endvm; + vm << endvm; +} + diff --git a/Ag++/AGxxConfig.h b/Ag++/AGxxConfig.h new file mode 100644 index 0000000..c090cb8 --- /dev/null +++ b/Ag++/AGxxConfig.h @@ -0,0 +1,366 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2004 The 'ac++' developers (see aspectc.org) +// +// 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 __AGxxConfig_h__ +#define __AGxxConfig_h__ + +#include "OptionVec.h" + +// PUMA includes +#include "Puma/OptsParser.h" +#include "Puma/ErrorStream.h" +using namespace Puma; + +// stdc++ includes +#include +#include +using namespace std; + +class AGxxConfig +{ + +public: + typedef list FileCont; + +private: + + // parse options + bool + parseOptions(); + + // parse some special g++ options + bool + parseGccOpt(OptsParser&); + + // analyze options + bool + analyzeOptions(); + + //print a usage message + void + usage() const; + + ErrorStream &_err; + int _argc; + char** _argv; + + // list of .ah files passed with -a option + FileCont _ah_files; + + // path to project directory + FileCont _proj_path; + + // output file name + string _output_file; + + // name of puma config file + string _pumaconfig_file; + + // path to aspectc++ compiler + string _acc_bin; + + // path to c++ compiler + string _cc_bin; + + // Option Vector + OptionVec _optvec; + + // path to destination directory + string _dest_path; + + // command, which is executed to get the information about + // compiler, include paths, defines. + // default is: -E -dM -v -x c++ /dev/null + string _config_command; + + // number of files to be processed + int _nr_files; + + // verbose + int _verbose; + + // indicate wether a config file should be generated + bool _gen_pumaconfig; + + // indicate wether weaving should be done + bool _weave; + + // indicate wether linking should be done + bool _link; + + // indicate wether compiling should be done + bool _compile; + + // use temporary file for puma config file + bool _pumaconfig_tmp; + + // do weave the source files (no compiling or linking) + bool _weave_only; + + // only let gcc print information + bool _print_gcc_info; + + // generate include files + bool _gen_incl; + + // if include files are generated + bool _gen_includes; + + // do only compile not link (but weave) + bool _compile_only; + + // indicate wether dependency information should be printed out + bool _make_dep; + + // keep woven source code files + bool _keep_woven; + + // assign all following options to the compiler + bool _x_compiler; + + // list of gcc options which need a argument + static string _gcc_option_arg[]; + + // list of gcc options which only print information + static string _gcc_option_info[]; + + // run Aspect C++ without input files + bool _run_acpp_without_input; + + // target triple from the ag++ command line (overrides value from g++) + string _command_line_target_triple; + + +public: + AGxxConfig(ErrorStream &e, int argc, char **argv) : + _err(e), _argc(argc), _argv(argv) + { + } + + ~AGxxConfig() + { + } + + enum + { + AGOPT_COMPILE_ONLY = 1, + AGOPT_WEAVE_ONLY, + AGOPT_GEN_CFG, + AGOPT_OUTPUT, + AGOPT_ACC, + AGOPT_CC, + AGOPT_HELP, + AGOPT_KEEP_WOVEN, + AGOPT_CONFIG_COMMAND, + AGOPT_TARGET, + AGOPT_X_COMPILER, + AGOPT_X_WEAVER, + AGOPT_VERBOSE, + AGOPT_VERSION, + // Ac++ options + ACOPT, // default handling for AspectC++ options + ACOPT_QUOTE_ARG, // default handling for AspectC++ options where the argument has to be quoted + ACOPT_WITHOUT_INPUT, // default handling for AspectC++ options running without input files + ACOPT_MATCH_POINTCUT_EXPR, + ACOPT_INCLUDE_FILES, + ACOPT_ASPECT_HEADER, + ACOPT_PROJ_PATH, + ACOPT_PROJ_DESTINATION, + ACOPT_CFG_FILE, + ACOPT_SYS_CFG_FILE, + ACOPT_PRE_INCLUDE, + ACOPT_PRE_DEFINE, + ACOPT_PRE_UNDEFINE, + ACOPT_ALWAYS_INCLUDE, + ACOPT_SYS_INCLUDE + }; + + // anaylze the arguments + bool + analyze(); + + // print Options + void + printOptions(); + + // + // Methods for accesing private data + // + + const bool + gen_pumaconfig() + { + return _gen_pumaconfig; + } + void + gen_pumaconfig(const bool b) + { + _gen_pumaconfig = b; + } + + const bool + weave() + { + return _weave; + } + + const bool + compile() + { + return _compile; + } + + const bool + make_dep() + { + return _make_dep; + } + + const bool + link() + { + return _link; + } + + const bool + keep_woven() + { + return _keep_woven; + } + + const bool + gen_includes() + { + return _gen_includes; + } + + const int + nr_files() + { + return _nr_files; + } + + const int + verbose() + { + return _verbose; + } + + OptionVec& + optvec() + { + return _optvec; + } + + FileCont& + ah_files() + { + return _ah_files; + } + + FileCont& + proj_paths() + { + return _proj_path; + } + + const string& + pumaconfig_file() + { + return _pumaconfig_file; + } + + const string& + target_triple() + { + return _command_line_target_triple; + } + + void + pumaconfig_file(const string& s) + { + _pumaconfig_file = s; + } + + const bool& + pumaconfig_tmp() + { + return _pumaconfig_tmp; + } + + const string& + output_file() + { + return _output_file; + } + void + output_file(const string& s) + { + _output_file = s; + } + + const string& + acc_bin() + { + return _acc_bin; + } + + const string& + cc_bin() + { + return _cc_bin; + } + + const string& + dest_path() + { + return _dest_path; + } + + const bool& + run_acpp_without_input() + { + return _run_acpp_without_input; + } + + string& + config_command() + { + return _config_command; + } + + // + // Helper methods + // + + static inline string& + str_replace_all(string& input_str, const string search_str, + const string replace_str) + { + string::size_type pos = input_str.find(search_str, 0); + while (pos != string::npos) + { + input_str.replace(pos, search_str.length(), replace_str); + pos = input_str.find('"', pos + 2); + } + return input_str; + } + +}; + +#endif //__AGxxConfig_h__ diff --git a/Ag++/CCompiler.cc b/Ag++/CCompiler.cc new file mode 100644 index 0000000..1ec9ed7 --- /dev/null +++ b/Ag++/CCompiler.cc @@ -0,0 +1,163 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2004 The 'ac++' developers (see aspectc.org) +// +// 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 "CCompiler.h" +#include "System.h" +#include "regex.h" + +//Puma includes +#include "Puma/VerboseMgr.h" +#include "Puma/PathManager.h" +using namespace Puma; + +bool +CCompiler::execute() +{ + + VerboseMgr vm(cout, _config.verbose()); + bool status = true; + + if (_config.make_dep()) + { + vm++; + vm << "Creating dependencies" << endvm; + status = make_dep(); + } + else + { + vm << "Compiling" << endvm; + status = compile(); + } + + return status; +} + +bool +CCompiler::make_dep() +{ + AGxxConfig::FileCont::iterator file = _config.proj_paths().begin(); + + // if there were no aspect headers in command string + // search all aspect headers in all project paths + if (_config.ah_files().empty()) + { + + PathManager path(this->_err); + + while (file != _config.proj_paths().end()) + { + path.addPath(file->c_str()); + file++; + } + + PathIterator ah_iter(".*\\.ah$"); + while (path.iterate(ah_iter)) + { + _config.ah_files().push_back(ah_iter.file()); + } + } + + /* + * setup execution string for gcc + */ + string exec_str = "\"" + _config.cc_bin() + "\""; + + file = _config.ah_files().begin(); + + OptionVec::iterator opt = _config.optvec().begin(); + while (opt != _config.optvec().end()) + { + // find all g++ options and files + switch ((opt->flag() + & (OptionItem::OPT_GCC | OptionItem::OPT_FILE | OptionItem::OPT_DEP))) + { + case OptionItem::OPT_GCC: + exec_str.append(" " + opt->name() + opt->arg()); + break; + case OptionItem::OPT_DEP: + exec_str.append(" " + opt->name() + opt->arg()); + break; + case OptionItem::OPT_FILE: + + // explicitly include all aspect headers (for creating dependency information) + //this is only executed once, as 'file' iterator is not reseted + while (file != _config.ah_files().end()) + { + exec_str += " -include \"" + *file + "\""; + file++; + } + + exec_str.append(" \"" + opt->name() + "\""); + + // explicitly include all aspect headers (for creating dependency information) + //this is only executed once, as 'file' iterator is not reseted + while (file != _config.ah_files().end()) + { + exec_str += " -include \"" + *file + "\""; + file++; + } + break; + } + opt++; + } + + // execute gcc + System gcc(_err, _config, exec_str); + return gcc.execute(); +} + +bool +CCompiler::compile() +{ + + // construct execution string + string exec_str = "\"" + _config.cc_bin() + "\""; + + OptionVec::iterator opt = _config.optvec().begin(); + + // loop through all options in option vector + while (opt != _config.optvec().end()) + { + // g++ options + if ((opt->flag() & (OptionItem::OPT_GCC | OptionItem::OPT_FILE)) + == OptionItem::OPT_GCC) + { + exec_str.append(" " + opt->name() + opt->arg()); + } + // woven source files + else if ((opt->flag() + & (OptionItem::OPT_GCC | OptionItem::OPT_ACC | OptionItem::OPT_FILE)) + == (OptionItem::OPT_GCC | OptionItem::OPT_ACC | OptionItem::OPT_FILE)) + { + // explictly mark .acc files as c++ files + exec_str.append(" -xc++ \"" + opt->name() + "\" -xnone"); + } + // other source files + else if ((opt->flag() & (OptionItem::OPT_GCC | OptionItem::OPT_FILE)) + == (OptionItem::OPT_GCC | OptionItem::OPT_FILE)) + { + exec_str.append(" \"" + opt->name() + "\" "); + } + opt++; + } + + // execute compiler + System gcc(_err, _config, exec_str); + return gcc.execute(); +} + diff --git a/Ag++/CCompiler.h b/Ag++/CCompiler.h new file mode 100644 index 0000000..68e0780 --- /dev/null +++ b/Ag++/CCompiler.h @@ -0,0 +1,46 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2004 The 'ac++' developers (see aspectc.org) +// +// 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 __CCompiler_h__ +#define __CCompiler_h__ + +#include "Compiler.h" +#include "AGxxConfig.h" + +class CCompiler : public Compiler +{ +private: + +public: + CCompiler(ErrorStream& e, AGxxConfig& c) : + Compiler(e, c) + { + } + ~CCompiler() + { + } + bool + execute(); + bool + compile(); + bool + make_dep(); +}; + +#endif // __CCompiler_h__ + diff --git a/Ag++/Compiler.h b/Ag++/Compiler.h new file mode 100644 index 0000000..977385f --- /dev/null +++ b/Ag++/Compiler.h @@ -0,0 +1,47 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2004 The 'ac++' developers (see aspectc.org) +// +// 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 __Compiler_h__ +#define __Compiler_h__ + +#include "AGxxConfig.h" + +// PUMA includes +#include "Puma/ErrorStream.h" + +class Compiler +{ +protected: + ErrorStream &_err; + AGxxConfig &_config; +public: + Compiler(ErrorStream& e, AGxxConfig& config) : + _err(e), _config(config) + { + } + Compiler(Compiler& compiler) : + _err(compiler._err), _config(compiler._config) + { + } + ~Compiler() + { + } + void + execute(); +}; +#endif // __Compiler_h__ diff --git a/Ag++/Makefile b/Ag++/Makefile new file mode 100644 index 0000000..6b04c7b --- /dev/null +++ b/Ag++/Makefile @@ -0,0 +1,173 @@ +# ****************************** +# * S E T T I N G S * +# ****************************** + + +# PUMA root +PUMA ?= ../Puma + +# default target +TARGET ?= linux-release + +#AspectC++ source directory +AC_SRC_DIR := ../AspectC++ + +# include the PUMA configuration variables +# => set _TARGET, RELEASE, CFLAGS, CXXFLAGS, CPPFLAGS, etc. +include $(PUMA)/vars.mk + +# determine which Puma library to use: libMiniPuma is preferred +PUMA_LIBS := $(notdir $(wildcard $(PUMA)/lib/$(TARGET)/lib*Puma.a)) +ifneq ($(filter libMiniPuma.a, $(PUMA_LIBS)),) + PUMA_LIB := MiniPuma +else + PUMA_LIB := Puma +endif + +#CXX := /usr/bin/g++-3.3 +#CXX := ag++ -p. -p../aspects --Xcompiler +#CXX := ag++ -v3 -p. --Xcompiler + +# compiler settings +ifeq ($(_TARGET),win32) + CXXFLAGS += -I $(PUMA)/src/win32/regex + EXT :=.exe + RES := mingw32-windres +endif + +CXXFLAGS += $(CPPFLAGS) -I$(PUMA)/extern -I$(PUMA)/include +ifneq ($(_TARGET),macosx_x86_64) + ifeq ($(SHARED),) + LDFLAGS += -static + endif + +LDFLAGS += -Wl,-Bstatic -L$(PUMA)/lib/$(TARGET) -l$(PUMA_LIB) + +ifneq ($(SHARED),) +LDFLAGS += -Wl,-Bdynamic +endif + +else + LDFLAGS += -L$(PUMA)/lib/$(TARGET) -l$(PUMA_LIB) +endif + +ifneq ($(PROFILING),) + LDFLAGS += -lc_p -lm_p + CXXFLAGS += -pg +endif + +# ****************************** +# * S O U R C E S * +# ****************************** + +BINBASE := bin +BINDIR := $(BINBASE)/$(TARGET) +PROG := $(BINDIR)/ag++$(EXT) + +CCSOURCES := $(wildcard *.cc) + +OBJECTBASE := ObjFiles +OBJECTDIR := $(OBJECTBASE)/$(TARGET) +OBJECTS := $(addprefix $(OBJECTDIR)/,$(CCSOURCES:%.cc=%.o)) + +DEPBASE := DepFiles +DEPDIR := $(DEPBASE)/$(TARGET) +DEPS := $(addprefix $(DEPDIR)/,$(CCSOURCES:%.cc=%.d)) + +ifeq ($(_TARGET),win32) +RCFILES := win-ag++.rc +OBJECTS += $(addprefix $(OBJECTDIR)/,$(RCFILES:%.rc=%.o)) +DEPS += $(addprefix $(DEPDIR)/,$(RCFILES:%.rc=%.d)) +endif + + +DIRS := $(OBJECTDIR) $(DEPDIR) $(BINDIR) + + + +# ****************************** +# * T A R G E T S * +# ****************************** + +all: showtarget $(AC_SRC_DIR)/$(PROG) + +strip: $(AC_SRC_DIR)/$(PROG) + @$(STRIP) $< + +showtarget: + @echo "---" + @echo "Making Ag++ for TARGET=$(TARGET)" + @echo " AC++ = $(ACXX) $(ACXXFLAGS) " + @echo " Compiler = $(CXX) $(CXXFLAGS)" + @echo " Linker = $(CXX) $(CXXFLAGS) $(LDFLAGS)" + @echo "---" + +help: showtarget + @echo + @echo + @echo "Make:" + @echo " help: show this help" + @echo " all (default): compile, link and copy" + @echo " copy: copy executable into AspectC++ bin folder" + @echo " test : run tests" + @echo " test_: run test number " + @echo " clean: remove intermediate files of current TARGET" + @echo " distclean: clean all generated files and directories" + @echo "---" + +clean: + @echo -n "CLEAN " + rm -rf $(PROG) core core.* $(DIRS) + +distclean: + rm -rf $(DEPBASE) $(OBJECTBASE) $(BINBASE) + + +test: all + @export TARGET=$(TARGET);export _TARGET=$(_TARGET);export EXT=$(EXT);cd tests;./run_tests.sh + +test_%: all + @export TARGET=$(TARGET);export _TARGET=$(_TARGET);export EXT=$(EXT);cd tests; ./run_tests.sh $@ + + +.PHONY: all clean distclean showtarget + +# ****************************** +# * R U L E S * +# ****************************** + +$(PROG): $(OBJECTS) + @echo "LD $@" + @mkdir -p $(BINDIR) + @$(CXX) -o $@ $^ $(LDFLAGS) + +$(AC_SRC_DIR)/$(PROG): $(PROG) + @echo "COPY $< to $@" + @mkdir -p $(AC_SRC_DIR)/bin/$(TARGET) + @cp $< $@ + +$(OBJECTDIR)/%.o : %.cc + @echo "DEP $(DEPDIR)/$(<:%.cc=%.d)." + @mkdir -p $(DEPDIR) + @$(CXX) $(CXXFLAGS) -MM -MP -MT $@ -MT $(DEPDIR)/$(<:%.cc=%.d) -MF $(DEPDIR)/$(<:%.cc=%.d) $< + @echo "CC $@" + @mkdir -p $(OBJECTDIR) + @$(CXX) $(CXXFLAGS) -c -o $@ $< + +ifeq ($(_TARGET),win32) +$(OBJECTDIR)/%.o : %.rc + @echo "DEP $@." + @mkdir -p $(DEPDIR) + @$(CXX) $(CXXFLAGS) -MM -MP -MT $@ -MT $(DEPDIR)/$(<:%.cc=%.d) -MF $(DEPDIR)/$(<:%.cc=%.d) -xc++ $< + @echo "RES $@" + @mkdir -p $(OBJECTDIR) + @$(RES) $(filter -D%,$(CXXFLAGS)) $< $@ +endif + +ifeq (,$(findstring clean,$(MAKECMDGOALS))) +ifeq (,$(findstring help,$(MAKECMDGOALS))) +-include $(DEPS) +endif +endif + +.SUFFIXES: .cc .o .h .rc .mk $(SUFFIXES) diff --git a/Ag++/OptionVec.cc b/Ag++/OptionVec.cc new file mode 100644 index 0000000..8e25753 --- /dev/null +++ b/Ag++/OptionVec.cc @@ -0,0 +1,82 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2004 The 'ac++' developers (see aspectc.org) +// +// 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 "OptionVec.h" + +//stdc++ includes +#include + +void +OptionVec::pushback(string name, string arg, OptionItem::flag_t flag) +{ + OptionItem newItem(name, arg, flag); + this->push_back(newItem); +} + +void +OptionVec::pushback(string name, OptionItem::flag_t flag) +{ + OptionItem newItem(name, flag); + this->push_back(newItem); +} + +const string& +OptionVec::getString() +{ + string* str = new string; + for (vec_t::iterator optitem = this->begin(); optitem != this->end(); + ++optitem) + { + str->append(" " + optitem->name()); + str->append(optitem->arg()); + } + return *str; +} + +const string& +OptionVec::getString(OptionItem::flag_t flag) +{ + string* str = new string; + for (vec_t::iterator optitem = this->begin(); optitem != this->end(); + ++optitem) + { + if ((flag & optitem->flag()) == flag) + { + str->append(" " + optitem->name()); + str->append(optitem->arg()); + } + } + return *str; +} + +const string& +OptionVec::getString(OptionItem::flag_t flag, OptionItem::flag_t exclude_flag) +{ + string* str = new string; + for (vec_t::iterator optitem = this->begin(); optitem != this->end(); + ++optitem) + { + if (((flag & optitem->flag()) == flag) + && ((exclude_flag & optitem->flag()) == 0)) + { + str->append(" " + optitem->name()); + str->append(optitem->arg()); + } + } + return *str; +} diff --git a/Ag++/OptionVec.h b/Ag++/OptionVec.h new file mode 100644 index 0000000..95c8251 --- /dev/null +++ b/Ag++/OptionVec.h @@ -0,0 +1,127 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2004 The 'ac++' developers (see aspectc.org) +// +// 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 __OptionVec_h__ +#define __OptionVec_h__ + +//stdc++ includes +#include +#include +using namespace std; + +class OptionItem +{ +public: + enum + { + OPT_ACC = 0x1, + OPT_GCC = 0x2, + OPT_FILE = 0x4, + OPT_CONFIG = 0x8, + OPT_DEP = 0x10 + }; + typedef unsigned int flag_t; + +private: + string _name; + string _argument; + flag_t _flag; + +public: + OptionItem(string name, string arg, flag_t flag) : + _name(name), _argument(arg), _flag(flag) + { + } + OptionItem(string name, flag_t flag) : + _name(name), _flag(flag) + { + } + OptionItem(const OptionItem& opt) : + _name(opt._name), _argument(opt._argument), _flag(opt._flag) + { + } + + const string& + name() + { + return _name; + } + void + name(string newname) + { + _name = newname; + } + + const string& + arg() + { + return _argument; + } + void + arg(string newarg) + { + _argument = newarg; + } + + const flag_t + flag() + { + return _flag; + } + void + flag(flag_t flag) + { + _flag = flag; + } +}; + +class OptionVec : public vector +{ + +public: + typedef vector vec_t; + +private: + //vec_t _options; + +public: + //OptionVec(){} + //OptionVec(const OptionVec& optvec):_options(optvec._options){} + + // Add a new Option + void + pushback(string name, string arg, OptionItem::flag_t flag); + + // Add a new Option + void + pushback(string name, OptionItem::flag_t flag); + + const string& + getString(); + + // get a string of options which have at least the flags passed with parameter + const string& + getString(OptionItem::flag_t); + + // get a string of options which have at least the flags passed with parameter + // and not the flags pass as second argument + const string& + getString(OptionItem::flag_t, OptionItem::flag_t); +}; + +#endif //__OptionVec_h__ diff --git a/Ag++/PumaConfigFile.cc b/Ag++/PumaConfigFile.cc new file mode 100644 index 0000000..7b967a2 --- /dev/null +++ b/Ag++/PumaConfigFile.cc @@ -0,0 +1,358 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2004 The 'ac++' developers (see aspectc.org) +// +// 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 "PumaConfigFile.h" +#include "StdSystem.h" +#include "file.h" +#include "regex.h" +using namespace file; +using namespace regex; + +//stdc++ includes +#include +#include + +//Puma includes +#include "Puma/VerboseMgr.h" +#include "Puma/SysCall.h" + +bool +PumaConfigFile::searchFile() +{ + // IF the location of the puma config file is given by an command line argument + // check it exist + if (_config.pumaconfig_file().empty() == false) + { + if (fileExists(_config.pumaconfig_file().c_str())) + { + return true; + } + else + { + return false; + } + } + + // + // set filename of puma configuration file + // + if (_config.pumaconfig_tmp() == true) + { + //create temporary file + _config.pumaconfig_file(Puma::SysCall::mktemp("agxx_pcfg", &_err)); + } + else if ((_config.output_file().empty() == false) + && (_config.nr_files() == 0)) + { + // name of puma configuration file is specified using '-o' option + _config.pumaconfig_file(_config.output_file()); + } + else + { + // default name for puma configuration + _config.pumaconfig_file("puma.config"); + } + + return false; +} + +bool +PumaConfigFile::generateFile() +{ + + VerboseMgr vm(cout, _config.verbose()); + vm << "Generating Puma configuration file" << endvm; + + // first parse c++ output + vm++; + vm << "Parsing output of g++ compiler" << endvm; + if (!parseCcOutput()) + { + return false; + } + + // if parsing was successfull write puma config file + vm << "Writing puma configuration file '" << _config.pumaconfig_file() << "'" + << endvm; + return writeFile(); +} + +bool +PumaConfigFile::parseCcOutput() +{ + +#ifdef WIN32 + const char* empty_file_name=_config.pumaconfig_file().c_str(); + ofstream empty_file(empty_file_name); + + if(! empty_file) + { + _err << sev_error << "Could not create " << empty_file_name << endMessage; + return false; + } + empty_file.close(); +#else + const char* empty_file_name = "/dev/null"; +#endif + + string config_command_str(_config.config_command()); + // check if a sepcial command for generating the out is available + if (config_command_str.empty()) + { + //Construct execution string for C++ Compiler + config_command_str = "\"" + _config.cc_bin() + "\" " + + _config.optvec().getString( + (OptionItem::OPT_GCC | OptionItem::OPT_CONFIG)) + + " -E -dM -v -x c++ \"" + empty_file_name + "\""; + } + + // get c compiler output + StdSystem gcc_out(_err, _config, config_command_str); + + if (!gcc_out.execute()) + { + return false; + } + + // c compiler output string: whole output(stderr,stdout) of gcc + string output(gcc_out.stderr_str()); + output.append(gcc_out.stdout_str()); + + // stringstream of c compiler output string + istringstream iss(output); + + // parse c compiler output string + bool in_include_list = false; + string line; + while (getline(iss, line)) + { + + // start of list of include paths + if (regExMatch("#include [<\"].*:.*", line.c_str())) + { + in_include_list = true; + } + + // within a list of include paths + else if (in_include_list && regExMatch("^ .*", line.c_str())) + { + + // strip leading white space + unsigned int strpos = line.find_first_not_of(" "); + line = line.substr(strpos); + + // convert '//*' to '/' + char lastchar = '0'; + for (string::iterator c = line.begin(); c != line.end(); ++c) + { + if (lastchar == *c && *c == '/') + { + c = line.erase(c); + --c; + } + lastchar = *c; + } + + // check for mac os framework directory paths + // this is generated by clang which replaces g++ on mac os + if (line.size() > 22 && line.substr(line.size() - 22) == " (framework directory)") + // remove trailing text " (framework directory)" if necessary + line = line.substr(0, line.size() - 22); + + // save modified string with include path + _inc_paths.push_back(line); + } + + // end of list of include paths + else if (in_include_list) + { + in_include_list = false; + } + + // match a '#define ...' + else if (regExMatch("#define .*", line.c_str())) + { + + // remove '#define '(8 characters) + line = line.substr(8); + + // split option and argument. + + // find name of option => split string at whitespace + string::size_type strpos = line.find(" "); + string option = line.substr(0, strpos); + + // set empty string as default argument if no argument is defined + string value = ""; + + // find value => find a string behind the option name + if ((strpos != string::npos) + && (line.find_first_not_of(" ", strpos) != string::npos)) + { + value = line.substr(strpos + 1); + } + + _def_options.insert(opt_pair(option, value)); + } + + // match a 'Target: ...' + else if (_target_triple.empty () && regExMatch("Target: .*", line.c_str())) + { + + // remove 'Target: '(8 characters) + line = line.substr(8); + _target_triple = line; + } + } + // check if string has been processed correctly + if (!iss.eof()) + { + _err << "Error reading gcc output string " << endMessage; + } + + return true; +} + +bool +PumaConfigFile::writeFile() +{ + // include paths need specail treatment in a cygwin environment + bool is_cygwin = false; + string gcc_major, gcc_minor, gcc_patchlevel; + + ofstream puma_file(_config.pumaconfig_file().c_str()); + + if (!puma_file) + { + _err << sev_error << "Could not open " << _config.pumaconfig_file().c_str() + << endMessage; + return false; + } + + puma_file << "--skip-bodies-non-prj" << endl; + puma_file << "-D __puma" << endl; + puma_file << "-D __STDC__" << endl; + + // Print options + for (map::iterator opt = _def_options.begin(); + opt != _def_options.end(); opt++) + { + + // print line '-D = ' in puma.config + puma_file << "-D \"" << opt->first; + if (opt->second != "") + { + puma_file << "=" << _config.str_replace_all(opt->second, "\"", "\\\""); + } + puma_file << "\"" << endl; + + // Check gcc version + if (opt->first == "__GNUC__") + { + gcc_major = opt->second; + } + else if (opt->first == "__GNUC_MINOR__") + { + gcc_minor = opt->second; + } + else if (opt->first == "__GNUC_PATCHLEVEL__") + { + gcc_patchlevel = opt->second; + } + + // Check for cygwin + if ((opt->first == "__CYGWIN32__") || (opt->first == "__CYGWIN__")) + { + is_cygwin = true; + } + + // Check for the size_t macro + if (opt->first == "__SIZE_TYPE__") + { + puma_file << "--size-type \"" << opt->second << "\"" << endl; + } + + // Check for the ptrdiff_t macro + if (opt->first == "__PTRDIFF_TYPE__") + { + puma_file << "--ptrdiff-type \"" << opt->second << "\"" << endl; + } + } + + // print the target triple if we know it + if (!_target_triple.empty()) + { + puma_file << "--target " << _target_triple << endl; + } + + // print the --gnu option with the collected version number + puma_file << "--gnu"; + if (gcc_major != "") + { + puma_file << " " << gcc_major; + if (gcc_minor != "") + { + puma_file << "." << gcc_minor; + if (gcc_patchlevel != "") + { + puma_file << "." << gcc_patchlevel; + } + } + puma_file << endl; + } + + // Print include statements into puma.config file, or + // -- if we have a cygwin environment -- append it + // to the cygpath execution string which determins + // the correct location of the include files. + string cygpath_exec_str = "cygpath -w "; + for (vector::iterator file = _inc_paths.begin(); + file != _inc_paths.end(); file++) + { + + // if we have a cygwin environment use cygpath for finding the right + // include paths. + + if (is_cygwin) + { + cygpath_exec_str = cygpath_exec_str + " " + *file; + } + else + { + puma_file << "--isystem \"" << *file << "\"" << endl; + } + } + + // print cygwin include paths into file + if (is_cygwin) + { + StdSystem cygpath(_err, _config, cygpath_exec_str); + cygpath.execute(); + + istringstream iss(cygpath.stdout_str()); + string line; + while (getline(iss, line)) + { + puma_file << "--isystem \"" << line << "\"" << endl; + } + } + + puma_file.close(); + return true; +} + diff --git a/Ag++/PumaConfigFile.h b/Ag++/PumaConfigFile.h new file mode 100644 index 0000000..067098c --- /dev/null +++ b/Ag++/PumaConfigFile.h @@ -0,0 +1,79 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2004 The 'ac++' developers (see aspectc.org) +// +// 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 __PumaConfigFile_h__ +#define __PumaConfigFile_h__ + +#include "AGxxConfig.h" + +// Puma includes +#include "Puma/RegComp.h" +#include "Puma/ErrorStream.h" +using namespace Puma; + +// stdc++ includes +#include +#include +#include +#include + +/* This class provides functions, to search and to create a + * puma config file + */ + +class PumaConfigFile +{ +private: + ErrorStream &_err; + AGxxConfig &_config; + + // list of include paths + vector _inc_paths; + + // a map for options and its values + map _def_options; + + // type of option-value pair + typedef pair opt_pair; + + // the target triple used by the GCC-Compiler + string _target_triple; + + // parse the output of the GCC-Compiler + bool + parseCcOutput(); + bool + writeFile(); + +public: + PumaConfigFile(ErrorStream& e, AGxxConfig& c) : + _err(e), _config(c), _target_triple(c.target_triple()) + { + } + ~PumaConfigFile() + { + } + ; + bool + searchFile(); + bool + generateFile(); + +}; + +#endif // __PumaConfigFile_h__ diff --git a/Ag++/RegExCont.cc b/Ag++/RegExCont.cc new file mode 100644 index 0000000..9f59577 --- /dev/null +++ b/Ag++/RegExCont.cc @@ -0,0 +1,56 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2004 The 'ac++' developers (see aspectc.org) +// +// 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 "RegExCont.h" +using namespace regex; +using namespace std; + +void +RegExCont::add(string expr, RegComp* regcomp) +{ + _re_map.insert(regex_pair(expr, regcomp)); +} + +RegComp* +RegExCont::lookup(string expr) +{ + map::iterator iter = _re_map.find(expr); + if (iter != _re_map.end()) + { + return iter->second; + } + else + { + return NULL; + } +} + +RegExCont::~RegExCont() +{ + //cout << "RegExCont stored: "<< _re_map.size() << " regular expressions" <::iterator iter = _re_map.begin(); + iter != _re_map.end(); iter++) + { + if (iter->second) + { + delete (iter->second); + } + } + _re_map.clear(); +} + diff --git a/Ag++/RegExCont.h b/Ag++/RegExCont.h new file mode 100644 index 0000000..faa1d07 --- /dev/null +++ b/Ag++/RegExCont.h @@ -0,0 +1,59 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2004 The 'ac++' developers (see aspectc.org) +// +// 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 __PumaConfigFile_h__ +#define __PumaConfigFile_h__ + +// Puma includes +#include "Puma/RegComp.h" +using namespace Puma; + +// stdc++ includes +#include +#include + +/* this class encapsulates a container for regular expressions */ + +namespace regex +{ + + class RegExCont + { + private: + // a map for options and its values + std::map _re_map; + + // type of option-value pair + typedef std::pair regex_pair; + public: + + // lookup for a regular expression + RegComp* + lookup(std::string expr); + + // add a new regular expression to the container + void + add(std::string expr, RegComp* regcomp); + + ~RegExCont(); + + }; + +} // namespace regex + +#endif //RegCompCont diff --git a/Ag++/StdSystem.cc b/Ag++/StdSystem.cc new file mode 100644 index 0000000..a0d8000 --- /dev/null +++ b/Ag++/StdSystem.cc @@ -0,0 +1,137 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2004 The 'ac++' developers (see aspectc.org) +// +// 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 "StdSystem.h" +#include "file.h" +using namespace file; + +//Puma includes +#include "Puma/SysCall.h" +#include "Puma/VerboseMgr.h" + +//stdc++ includes +#include +#include +#include +#include + +StdSystem::StdSystem(ErrorStream& e, AGxxConfig& config, const string& exec_str) : + System(e, config, "") +{ + + // create temporary files + char* tmp_file; + + // tmp file for stdout + tmp_file = (char*) Puma::SysCall::mktemp("agxx_stdout", &_err); + _tmp_stdout_file = tmp_file; + free(tmp_file); + + // tmp file for stderr + tmp_file = (char*) Puma::SysCall::mktemp("agxx_stderr", &_err); + _tmp_stderr_file = tmp_file; + free(tmp_file); + + // append shell commands to execution string which + // write the output into temproray files +#if defined (WIN32) + this->_exec_str="\""+exec_str +" 2>"+_tmp_stderr_file+" 1>"+_tmp_stdout_file+"\""; +#else + this->_exec_str = exec_str + " 2>" + _tmp_stderr_file + " 1>" + + _tmp_stdout_file; +#endif +} + +bool +StdSystem::execute() +{ + VerboseMgr vm(cout, _config.verbose()); + bool ret; + + if ((ret = System::execute())) + { + //read files into strings + _stdout_str = read_file(_tmp_stdout_file.c_str()); + _stderr_str = read_file(_tmp_stderr_file.c_str()); + } + else + { + print_file(_tmp_stderr_file.c_str()); + } + + vm++; + vm << "removing temporary file: " << _tmp_stdout_file.c_str() << endvm; + if (remove(_tmp_stdout_file.c_str()) < 0) + { + _err << sev_warning << "Could not remove temporary file : " + << _tmp_stdout_file.c_str() << endMessage; + } + + vm << "removing temporary file: " << _tmp_stderr_file.c_str() << endvm; + if (remove(_tmp_stderr_file.c_str()) < 0) + { + _err << sev_warning << "Could not remove temporary file : " + << _tmp_stderr_file.c_str() << endMessage; + } + + return ret; +} + +string +StdSystem::read_file(const char* fname) +{ + string line, s; + + ifstream fs(fname); + if (fs) + { + while (getline(fs, line)) + { + s += line + '\n'; + } + fs.close(); + } + else + { + _err << sev_error << "Could not open file :" << fname << endMessage; + s = ""; + } + + return s; +} + +void +StdSystem::print_file(const char* fname) +{ + string line; + + ifstream fs(fname); + if (fs) + { + while (getline(fs, line)) + { + cerr << line << endl; + } + fs.close(); + } + else + { + _err << sev_error << "Could not open file :" << fname << endMessage; + } +} + diff --git a/Ag++/StdSystem.h b/Ag++/StdSystem.h new file mode 100644 index 0000000..707eec6 --- /dev/null +++ b/Ag++/StdSystem.h @@ -0,0 +1,84 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2004 The 'ac++' developers (see aspectc.org) +// +// 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 __StdSystem_h__ +#define __StdSystem_h__ + +#include "System.h" + +//Puma includes +#include "Puma/ErrorStream.h" +using namespace Puma; + +// stdc++ includes +#include +using namespace std; + +// fill me +class StdSystem : public System +{ + +protected: + + // temporary file which contains standard output after execution + string _tmp_stdout_file; + + // temporary file which contains standard error after execution + string _tmp_stderr_file; + + // string which contains standard error + string _stdout_str; + + // string which contains standard output + string _stderr_str; + + // read file content into string + string + read_file(const char* fname); + + // print file to stderr + void + print_file(const char* fname); + +public: + // Constructor + StdSystem(ErrorStream&, AGxxConfig&, const string&); + + // execute command specified in _exec_str + bool + execute(); + + // + //methods for accessing private data + // + + const string& + stdout_str() + { + return _stdout_str; + } + + const string& + stderr_str() + { + return _stderr_str; + } + +}; + +#endif //__StdSystem_h__ diff --git a/Ag++/System.cc b/Ag++/System.cc new file mode 100644 index 0000000..0d3e372 --- /dev/null +++ b/Ag++/System.cc @@ -0,0 +1,58 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2004 The 'ac++' developers (see aspectc.org) +// +// 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 "System.h" + +//Puma includes +#include "Puma/VerboseMgr.h" + +#include + +System::System(ErrorStream& e, AGxxConfig& c, const string& exec_str) : + _err(e), _config(c) +{ + +#if defined (WIN32) + this->_exec_str="\""+exec_str+"\""; +#else + this->_exec_str = exec_str; +#endif + +} +bool +System::execute() +{ + VerboseMgr vm(cout, _config.verbose()); + + vm++; + vm << "Executing: " << _exec_str << endvm; + + // execute command in shell + int ret; + if ((ret = system(_exec_str.c_str())) == EXIT_SUCCESS) + { + vm << "Exit: Success" << endvm; + return true; + } + + _err << sev_error << "Execution failed: " << _exec_str.c_str() << endMessage; + + vm << "Exitcode: " << ret << " (should be " << EXIT_SUCCESS<< " )" << endvm; + return false; +} + diff --git a/Ag++/System.h b/Ag++/System.h new file mode 100644 index 0000000..054363c --- /dev/null +++ b/Ag++/System.h @@ -0,0 +1,56 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2004 The 'ac++' developers (see aspectc.org) +// +// 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 __System_h__ +#define __System_h__ + +#include "AGxxConfig.h" + +//Puma includes +#include "Puma/ErrorStream.h" +using namespace Puma; + +// stdc++ includes +#include +using namespace std; + +class System +{ + +protected: + + // an error stream + ErrorStream &_err; + + // configuration + AGxxConfig &_config; + + // execution command + string _exec_str; + +public: + // Constructor + System(ErrorStream& e, AGxxConfig& c, const string& exec_str); + + // execute command specified in _exec_str + bool + execute(); + +}; + +#endif //__System_h__ diff --git a/Ag++/TODO.txt b/Ag++/TODO.txt new file mode 100644 index 0000000..139597f --- /dev/null +++ b/Ag++/TODO.txt @@ -0,0 +1,2 @@ + + diff --git a/Ag++/ag++.cc b/Ag++/ag++.cc new file mode 100644 index 0000000..a7dd481 --- /dev/null +++ b/Ag++/ag++.cc @@ -0,0 +1,149 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2004 The 'ac++' developers (see aspectc.org) +// +// 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 "CCompiler.h" +#include "ACCompiler.h" +#include "AGxxConfig.h" +#include "PumaConfigFile.h" + +#include "file.h" + +// PUMA includes +#include "Puma/ErrorStream.h" +#include "Puma/VerboseMgr.h" + +// standard library includes +#include + +using namespace Puma; + +int +main(int argc, char **argv) +{ + ErrorStream err; + bool optionsOk; + int exitstatus = EXIT_SUCCESS; + + try { + // Setup Configuration + AGxxConfig config(err, argc, argv); + + optionsOk = config.analyze(); + + if (config.verbose() > 0) + { + config.printOptions(); + } + if (!optionsOk) + { + return EXIT_FAILURE; + } + + VerboseMgr vm(cout, config.verbose()); + + // Create a Puma configuration file if it does not exist + if (config.gen_pumaconfig()) + { + PumaConfigFile pumacfg(err, config); + if (!pumacfg.searchFile()) + { + if (!pumacfg.generateFile()) + { + return EXIT_FAILURE; + } + } + else + { + config.gen_pumaconfig(false); + } + } + + // Create an AspectC++ compiler object + if (config.weave()) + { + ACCompiler acc(err, config); + if (!acc.execute()) + { + // make sure tmp files are cleaned up + exitstatus = EXIT_FAILURE; + } + } + + // Create a C compiler object + if (exitstatus == EXIT_SUCCESS && config.compile()) + { + CCompiler cc(err, config); + if (!cc.execute()) + { + // make sure tmp files are cleaned up + exitstatus = EXIT_FAILURE; + } + } + + // + // clean up temporary files + // + + vm++; + + // remove temporary puma.config + if (config.pumaconfig_tmp() == true) + { + vm << "Removing temporary puma configuration file" << endvm; + if (remove(config.pumaconfig_file().c_str()) < 0) + { + err << sev_warning << "Could not remove temporary file : " + << config.pumaconfig_file().c_str() << endMessage; + } + } + + // remove intermediate acc files remove them + if (config.keep_woven() == false) + { + vm << "Removing intermediate .acc files" << endvm; + OptionVec::iterator opt = config.optvec().begin(); + while (opt != config.optvec().end()) + { + if (opt->flag() + != (OptionItem::OPT_ACC | OptionItem::OPT_GCC | OptionItem::OPT_FILE)) + { + ++opt; + continue; + } + // check if removal succeeded + string rm_file(opt->name()); + if (remove(rm_file.c_str()) < 0) + { + err << sev_warning << "Couldn't remove " << rm_file.c_str() + << endMessage; + } + ++opt; + } + } + } + catch (const std::exception &e) { + err << sev_fatal << "Caught standard exception: " << e.what () << endMessage; + return EXIT_FAILURE; + } + catch (...) { + err << sev_fatal << "Caught unknown exception!" << endMessage; + return EXIT_FAILURE; + } + return exitstatus; +} + diff --git a/Ag++/doc/Ag++Manual/Ag++Manual.lyx b/Ag++/doc/Ag++Manual/Ag++Manual.lyx new file mode 100644 index 0000000..1ca6c1d --- /dev/null +++ b/Ag++/doc/Ag++Manual/Ag++Manual.lyx @@ -0,0 +1,1971 @@ +#LyX 2.0 created this file. For more info see http://www.lyx.org/ +\lyxformat 413 +\begin_document +\begin_header +\textclass article +\begin_preamble +\usepackage{a4} +%-------------------------------------------------------------------- +% PDF related +%-------------------------------------------------------------------- +\newif\ifmypdf +\ifx\pdfoutput\undefined + \mypdffalse % we are not running PDFLaTeX +\else + \pdfoutput=1 % we are running PDFLaTeX + \mypdftrue +\fi + +%-------------------------------------------------------------------- +% setup hyperref +%-------------------------------------------------------------------- +\ifmypdf + \usepackage{color} + \pagecolor{white} + \usepackage{hyperref} + \hypersetup{% + % + %% general document information + pdftitle = {AG++ Manual}, + pdfsubject = {Dokumentation}, + pdfkeywords = {AOP, AspectC++, ac++, pure-systems,g++}, + pdfauthor = {Georg Blaschke}, + pdfcreator = {\LaTeX\ with package \flqq hyperref\frqq}, + pdfproducer = {pdfTeX-0.\the\pdftexversion\pdftexrevision}, + % + %% document style + colorlinks=true, % colored link + urlcolor=blue, % blue URL links + bookmarks=true, % generate bookmarks + bookmarksnumbered=true, % generate section numbers + pdfpagemode=None % don't open bookmarks + } + + %% set document creation date to + \pdfinfo {/CreationDate (D:20130925000000)} +\fi + +%-------------------------------------------------------------------- +% create hyperrefs depending on the use of pdflatex +%-------------------------------------------------------------------- +\newcommand\depref[2]{% + \ifmypdf + \href{#1}{#2} + \else + {#2} + \fi +} + +%-------------------------------------------------------------------- +% setup pure-systems style +%-------------------------------------------------------------------- +%\usepackage{floatflt} +\usepackage{../styles/acc} +\version{0.9} +\doctype{Documentation:} +\credit{} +\otherlogo{ + \resizebox{4cm}{!}{\includegraphics{../images/ac++logo}}} +\sloppy +\remark{} + + +% less than one half space between lines +\setstretch{1.15} +\end_preamble +\use_default_options false +\maintain_unincluded_children false +\language english +\language_package default +\inputencoding auto +\fontencoding global +\font_roman times +\font_sans helvet +\font_typewriter courier +\font_default_family default +\use_non_tex_fonts false +\font_sc false +\font_osf false +\font_sf_scale 100 +\font_tt_scale 100 + +\graphics default +\default_output_format default +\output_sync 0 +\bibtex_command default +\index_command default +\paperfontsize 12 +\spacing onehalf +\use_hyperref false +\papersize default +\use_geometry false +\use_amsmath 1 +\use_esint 0 +\use_mhchem 0 +\use_mathdots 1 +\cite_engine basic +\use_bibtopic false +\use_indices false +\paperorientation portrait +\suppress_date false +\use_refstyle 0 +\index Index +\shortcut idx +\color #008000 +\end_index +\secnumdepth 3 +\tocdepth 3 +\paragraph_separation indent +\paragraph_indentation default +\quotes_language english +\papercolumns 1 +\papersides 2 +\paperpagestyle default +\tracking_changes false +\output_changes false +\html_math_output 0 +\html_css_as_file 0 +\html_be_strict false +\end_header + +\begin_body + +\begin_layout Title + +\emph on +Ag++ Manual: +\end_layout + +\begin_layout Author + +\size largest +Georg Blaschke +\end_layout + +\begin_layout Standard +\begin_inset CommandInset toc +LatexCommand tableofcontents + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +clearpage +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Section + +\family sans +\begin_inset CommandInset label +LatexCommand label +name "sec:Introduction" + +\end_inset + + +\family default +Introduction +\end_layout + +\begin_layout Standard +The +\family typewriter +ag++ +\family default + program provides a more intuitive frontend to the AspectC++ weaver ( +\family typewriter +ac++ +\family default +) in a GNU environment. + The only preliminaries are a working installation of GNU C++ compiler, + which also can run within a cygwin environment. + It basically wraps the functionality of the aspect weaver and the c++ compiler + into one single program. + +\end_layout + +\begin_layout Section + +\family sans +\begin_inset CommandInset label +LatexCommand label +name "sec:Invocation" + +\end_inset + + +\family default +Invocation +\end_layout + +\begin_layout Standard +The usage of +\family typewriter +ag++ +\family default + is mainly influenced by the usage of the GNU g++ compiler and the synopsis + is like: +\end_layout + +\begin_layout Standard + +\family typewriter +ag++ [options] [files...] +\family default +. +\begin_inset Newline newline +\end_inset + +Let's say, you want to +\series bold +compile +\series default + a single file (here: +\family typewriter +main.cc +\family default +) with +\family typewriter +g++, +\family default + you have to run +\end_layout + +\begin_layout Standard + +\family typewriter +g++ -c main.cc +\family default + +\begin_inset Newline newline +\end_inset + +in order to generate an object file. +\begin_inset Newline newline +\end_inset + +To +\series bold +weave +\series default + and +\series bold +compile +\series default + a single file you simply invoke +\end_layout + +\begin_layout Standard + +\family typewriter +ag++ -c main.cc +\begin_inset Newline newline +\end_inset + + +\family default +the same way like you did before with +\family typewriter +g++ +\family default +. +\begin_inset Newline newline +\end_inset + + +\end_layout + +\begin_layout Subsection +Concept +\end_layout + +\begin_layout Standard +As +\family typewriter +ag++ +\family default + is just a wrapper, it first generates the puma configuration file, then + calls +\family typewriter +ac++ +\family default + and afterwards +\family typewriter +g++ +\family default +. + The intermediate files generated by +\family typewriter +ac++ +\family default + are stored in the directory which is extracted from the +\family typewriter +-o +\family default + option or in current directory. + In some cases this may lead to a situation where the names of intermediate + files interfere with each other. +\end_layout + +\begin_layout Subsection +Options +\end_layout + +\begin_layout Standard +All available options are summed up in the options table (see table +\begin_inset CommandInset ref +LatexCommand ref +reference "tab:options" + +\end_inset + +). + The column labeled with +\emph on +AC++ +\emph default + shows if the option is taken over from +\family typewriter +ac++ +\family default + by +\family typewriter +ag++ +\family default + ('X'), not supported by +\family typewriter +ac++ +\family default + ('--') or modified by +\family typewriter +ag++ +\family default + ('!'). + All options which are taken over, are not described in this document. + Consult the AC++ Compiler Manual instead. + Options which are not listed in the option table are accounted as +\family typewriter +g++ +\family default + options. + Some +\family typewriter +g++ +\family default + options can not be automatically handled correctly by the options parser + of +\family typewriter +ag++. + +\family default + So all +\family typewriter +g++ +\family default + options starting with +\family typewriter +-p, -a, -d and -r +\family default + (e.g. + +\family typewriter +-pipe, -ansi, -dletters ,-remap +\family default + ) have to be written between +\family typewriter +--Xcompiler +\family default + (see +\begin_inset CommandInset ref +LatexCommand ref +reference "sub:--Xcompiler" + +\end_inset + +) and +\family typewriter +--Xweaver +\family default + (see +\begin_inset CommandInset ref +LatexCommand ref +reference "sub:--Xweaver" + +\end_inset + +). + If such options passed to +\family typewriter +ag++ +\family default + without using +\family typewriter +--Xcompiler +\family default + they will be interpreted a +\family typewriter +ag++/ac++ +\family default + options ; e.g. + +\family typewriter +-pipe +\family default + will be interpreted as +\family typewriter +-p +\begin_inset Quotes eld +\end_inset + +ipe +\family default + +\begin_inset Quotes erd +\end_inset + + +\family typewriter +. +\end_layout + +\begin_layout Standard +\begin_inset Float table +wide false +sideways false +status open + +\begin_layout Plain Layout +\align center +\begin_inset Tabular + + + + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +Option +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +AC++ +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +Description +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +--gen_config +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +-- +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Only generate Puma configuration file +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +--weave_only +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +-- +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family roman +\series medium +\shape up +\size normal +\emph off +\bar no +\noun off +\color none +Weave only +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +-c +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +! +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family roman +\series medium +\shape up +\size normal +\emph off +\bar no +\noun off +\color none +Compile only +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +--keep_woven +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +-- +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family roman +\series medium +\shape up +\size normal +\emph off +\bar no +\noun off +\color none +Keep woven source code files +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +--c_compiler +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +-- +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family roman +\series medium +\shape up +\size normal +\emph off +\bar no +\noun off +\color none +Path to C++ compiler +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +--ac_compiler +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +-- +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family roman +\series medium +\shape up +\size normal +\emph off +\bar no +\noun off +\color none +Path to AspectC++ compiler +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +--config_command +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +-- +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Specify command which prints information about compiler +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +--Xcompiler +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +-- +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +In case of doupt account following options as +\family typewriter +g++ +\family default + options. +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +--Xweaver +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +-- +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +In case of doupt account following options as +\family typewriter +ac++ +\family default + options. +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +-p|--path +\begin_inset space ~ +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +! +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Defines a project directory +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +-d|--dest +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Specifies a target directory for saving +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +-v|--verbose +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +! +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Level of verbosity ( +\family typewriter +0 +\family default +- +\family typewriter +9 +\family default +) +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +-o|--output +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Name of the output file +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +--include_files +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Generate manipulated header files (short version +\family typewriter +-i +\family default + is not supported) +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +-a|--aspect_header +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +! +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family roman +\series medium +\shape up +\size normal +\emph off +\bar no +\noun off +\color none +Name of aspect header file or +\family default +\series default +\shape default +\emph default +\bar default + +\family typewriter +\size default +\noun default +\color inherit +0 +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +-r|--repository +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Name of the project repository +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +--expr +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Pointcut expression to match in repository +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +--config +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +! +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Parser configuration file +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +--no_line +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Disable generation of +\family typewriter +#line +\family default + directives +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +-k|--keywords +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Allow AspectC++ keywords in normal project files +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +--real-instances +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Let +\family typewriter +ac++ +\family default + perform a full template analysis +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +--problem... +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Enable back-end compiler problem workaround +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +--no_problem... +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Disable back-end compiler problem workaround +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +--warn... +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Show a specific +\family typewriter +ac++ +\family default + warning that is suppressed by default +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +--no_warn... +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Suppress a specific +\family typewriter +ac++ +\family default + warning +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +-I +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Include file search path +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +-D [=] +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Macro definitions +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +-U +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Undefine a macro +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +--include +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Forced include +\end_layout + +\end_inset + + + + +\end_inset + + +\end_layout + +\begin_layout Plain Layout +\begin_inset Caption + +\begin_layout Plain Layout +\begin_inset CommandInset label +LatexCommand label +name "tab:options" + +\end_inset + + +\family typewriter +ag++ +\family default + Compiler Option Summary +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Subsubsection + +\family typewriter +--gen_config +\end_layout + +\begin_layout Standard +Just create a parser configuration and quit afterwards. + The argument of the +\family typewriter +-o +\family default + option specifies the name of the file. + In any other case (no +\family typewriter +--gen_config +\family default + and/or no +\family typewriter +-o +\family default + option) a configuration file with the name 'puma.config' will be generated + in the directory where +\family typewriter +ag++ +\family default + was invoked. + +\end_layout + +\begin_layout Subsubsection + +\family typewriter +--weave_only +\end_layout + +\begin_layout Standard +Generate only woven source code files. + With +\family typewriter +-o +\family default + option and one file the generated output is named after the argument of + the +\family typewriter +-o +\family default + option. + +\end_layout + +\begin_layout Subsubsection + +\family typewriter +--path +\end_layout + +\begin_layout Standard +This options differs only slightly from the +\family typewriter +--path +\family default + option of +\family typewriter +ac++ +\family default +. + In +\family typewriter +ac++ +\family default + it is mandatory to specify a project path, whereby +\family typewriter +ag++ +\family default + the current working directory is used as project path by default. + Especially for larger projects it is NOT wise to rely on the default project + path, as weaving take a lot of time. + See the AspectC++ Compiler Manual for a more detailed description of this + option. +\end_layout + +\begin_layout Subsubsection + +\family typewriter +-c +\end_layout + +\begin_layout Standard +Like the +\family typewriter +-c +\family default + option of +\family typewriter +g++ +\family default +, this options effects the creation of object files of one or more source + files. +\end_layout + +\begin_layout Subsubsection + +\family typewriter +-v|--verbose [] +\end_layout + +\begin_layout Standard +Set the level of verbosity. + +\end_layout + +\begin_layout Subsubsection + +\family typewriter +--aspect-header +\end_layout + +\begin_layout Standard +This option differs from meaning in +\family typewriter +ac++ +\family default + only if dependencies are generated ( see +\begin_inset CommandInset ref +LatexCommand ref +reference "sub:Generating-dependency-information" + +\end_inset + +). +\end_layout + +\begin_layout Subsubsection + +\family typewriter +--keep_woven +\end_layout + +\begin_layout Standard +Don't remove intermediate woven files. +\end_layout + +\begin_layout Subsubsection + +\family typewriter +--c_compiler +\end_layout + +\begin_layout Standard +Specify path to GNU C++ compiler ̇ The default is +\family typewriter +g++. +\end_layout + +\begin_layout Subsubsection + +\family typewriter +--ac_compiler +\end_layout + +\begin_layout Standard +Specify path to AspectC++ compiler ̇ By default ag++ assumes, that the ac++ + executable is located in the same directory like itself. +\end_layout + +\begin_layout Subsubsection + +\family typewriter +--config_command +\end_layout + +\begin_layout Standard +Specify the command which prints information about the compiler. + This information is necessary for generating the parser (puma) configuration + file. + The default value is +\begin_inset Quotes erd +\end_inset + + +\family typewriter + -E -dM -v -x c++ +\begin_inset Quotes erd +\end_inset + +. +\end_layout + +\begin_layout Subsubsection + +\family typewriter +--config +\end_layout + +\begin_layout Standard +Path to a puma configuration file. + If this option is available the configuration file will not be generated + automatically. +\end_layout + +\begin_layout Subsubsection + +\family typewriter +\begin_inset CommandInset label +LatexCommand label +name "sub:--Xcompiler" + +\end_inset + +--Xcompiler +\end_layout + +\begin_layout Standard + +\family typewriter +ac++ +\family default + and +\family typewriter +ag++ +\family default + options that might interfere with +\family typewriter +g++ +\family default + options are not recognized after using +\family typewriter +--Xcompiler +\family default + in the argument list of an +\family typewriter +ag++ +\family default + invocation. + +\end_layout + +\begin_layout Subsubsection + +\family typewriter +\begin_inset CommandInset label +LatexCommand label +name "sub:--Xweaver" + +\end_inset + +--Xweaver +\end_layout + +\begin_layout Standard +Enable the recognition of those +\family typewriter +ac++ +\family default + and +\family typewriter +ag++ +\family default + options which previously have been disabled by the usage of -- +\family typewriter +Xcompiler. +\end_layout + +\begin_layout Subsection +\begin_inset CommandInset label +LatexCommand label +name "sub:Generating-dependency-information" + +\end_inset + +Generating dependency information +\end_layout + +\begin_layout Standard +To produce dependency files just pass the +\family typewriter +-M +\family default + or +\family typewriter +-MM +\family default + (consult the GNU C++ Compiler Manual) to +\family typewriter +ag++ +\family default + . + Dependency files generated by +\family typewriter +ag++ +\family default + are slighty different from dependency files created by +\family typewriter +g++ +\family default +, as they contain dependencies to aspect header files. + If the +\family typewriter +--aspect-header +\family default + option is provided, only the header file specified as option argument is + considered when building the dependency file; otherwise the dependency + file will contain all aspect header files within the whole project path + . + +\end_layout + +\begin_layout Subsection +Examples +\end_layout + +\begin_layout Itemize + +\family typewriter +ag++ --help +\family default + +\begin_inset Newline newline +\end_inset + +Displays all options with a short description. +\end_layout + +\begin_layout Itemize + +\family typewriter +ag++ -o test Test.cc main.cc +\begin_inset Newline newline +\end_inset + + +\family default +Weave, compile and link the source files +\family typewriter +Test.cc +\family default + and +\family typewriter +main.cc +\family default +. + The created executable will be named ' +\family typewriter +test +\family default +'. +\end_layout + +\begin_layout Itemize + +\family typewriter +ag++ --gen_config +\begin_inset Newline newline +\end_inset + + +\family default +Create a puma configuration file named +\family typewriter +puma.config +\family default + within the current working directory. + +\end_layout + +\begin_layout Itemize + +\family typewriter +ag++ --gen_config -o my.config +\begin_inset Newline newline +\end_inset + + +\family default +Create a puma configuration file named +\family typewriter +my.config. +\end_layout + +\begin_layout Itemize + +\family typewriter +ag++ --path src --include_files --dest gen/includes +\begin_inset Newline newline +\end_inset + + +\family default +Generate modified include files out of all include files found below +\family typewriter +src +\family default + directory and store them under ' +\family typewriter +gen/includes +\family default +'. +\end_layout + +\begin_layout Itemize + +\family typewriter +ag++ -M -MFmain.dep main.cc +\begin_inset Newline newline +\end_inset + + +\family default +Generate dependency file +\family typewriter +main.dep +\family default + from source file +\family typewriter +main.cc +\family default + . +\end_layout + +\begin_layout Itemize + +\family typewriter +ag++ -p ../aspects -p . + --Xcompiler +\begin_inset Newline newline +\end_inset + + +\family default +This string could be used to substitute +\family typewriter +g++ +\family default + in a simple +\family typewriter +make +\family default + environment. +\end_layout + +\end_body +\end_document diff --git a/Ag++/doc/Ag++Manual/Ag++Manual.pdf b/Ag++/doc/Ag++Manual/Ag++Manual.pdf new file mode 100644 index 0000000..63aaae3 Binary files /dev/null and b/Ag++/doc/Ag++Manual/Ag++Manual.pdf differ diff --git a/Ag++/doc/images/ac++logo.eps b/Ag++/doc/images/ac++logo.eps new file mode 100644 index 0000000..4d1d883 --- /dev/null +++ b/Ag++/doc/images/ac++logo.eps @@ -0,0 +1,3928 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Creator: Adobe Illustrator(TM) 7.0 +%%AI8_CreatorVersion: 8.0.1 +%%For: (Peter Schultz) (pete design) +%%Title: (ac++logo.eps) +%%CreationDate: (4/4/03) (12:32 PM) +%%BoundingBox: 208 393 396 495 +%%HiResBoundingBox: 208.9492 393.2559 395.7109 494.6265 +%%DocumentProcessColors: Magenta Yellow Black +%%DocumentSuppliedResources: procset Adobe_level2_AI5 1.2 0 +%%+ procset Adobe_ColorImage_AI6 1.1 0 +%%+ procset Adobe_Illustrator_AI5 1.3 0 +%%+ procset Adobe_cshow 2.0 8 +%AI5_FileFormat 3.0 +%AI3_ColorUsage: Color +%AI3_IncludePlacedImages +%AI7_ImageSettings: 1 +%%AI6_ColorSeparationSet: 1 1 (AI6 Default Color Separation Set) +%%+ Options: 1 16 0 1 0 1 1 1 0 1 1 1 1 8.504 0 0 0 0 0 0 0 0 -1 -1 +%%+ PPD: 1 21 0 0 60 45 2 2 1 0 0 1 0 0 0 0 0 0 0 0 0 0 () +%AI3_TemplateBox: 296.5 419.5 296.5 419.5 +%AI3_TileBox: 10 15 586 831 +%AI3_DocumentPreview: PC_ColorTIFF +%AI5_ArtSize: 592 840 +%AI5_RulerUnits: 1 +%AI5_ArtFlags: 1 0 0 1 0 0 1 0 0 +%AI5_TargetResolution: 800 +%AI5_NumLayers: 1 +%AI5_OpenToView: -263.5 849.5 1 1265 912 18 0 1 7 40 0 0 +%AI5_OpenViewLayers: 7 +%%PageOrigin:10 15 +%%AI3_PaperRect:-10 833 585 -9 +%%AI3_Margin:10 -14 -9 9 +%AI7_GridSettings: 28.3465 10 28.3465 10 1 0 1 0.749 0.498 1 0.8745 0.749 +%AI7_Thumbnail: 128 72 8 +%%BeginData: 9556 Hex Bytes +%0000330000660000990000CC0033000033330033660033990033CC0033FF +%0066000066330066660066990066CC0066FF009900009933009966009999 +%0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 +%00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 +%3333663333993333CC3333FF3366003366333366663366993366CC3366FF +%3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 +%33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 +%6600666600996600CC6600FF6633006633336633666633996633CC6633FF +%6666006666336666666666996666CC6666FF669900669933669966669999 +%6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 +%66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF +%9933009933339933669933999933CC9933FF996600996633996666996699 +%9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 +%99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF +%CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 +%CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 +%CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF +%CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC +%FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 +%FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 +%FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 +%000011111111220000002200000022222222440000004400000044444444 +%550000005500000055555555770000007700000077777777880000008800 +%000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB +%DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF +%00FF0000FFFFFF0000FF00FFFFFF00FFFFFF +%524C45FD22FFCA9ABC8D938D938D9393BCA1CBFD70FFCA9A938C9368938C +%9368938C9368938C93A1FD6CFFCABC8D938C938D938C938D938C938D938C +%938D938DC3FD69FFA1936893689368936893689368936893689368936893 +%6894A8FD6BFFCA9A938D938D938D938D938D938D938D938D938D93A1FD6D +%FFC38D9368938C9368938C9368938C9368938C93A1FD6EFF93938C938D93 +%8C938D938C938D938C938D93A1FD6EFF9393689368936893689368936893 +%68936893A1FD60FF9A9A939394C3CAFD06FFCA8D938D938D938D938D938D +%938D938D938D93CAFD5CFFCA9A68938C9368938C939AFD06FF9A68938C93 +%68938C9368938C9368938C93689AFD5CFFBC8D938C938D938C938D93A1FD +%05FFC4938C938D938C938D938C94949A93938D938CCAFD08FFA1C39BCAFD +%4EFFC3689368936893689368936893FD06FF689368936893689368939AFF +%FFCA689368938DFD08FF93689393FD4EFF93938D938D938D938D938D938D +%CAFD05FF9A8D938D938D938D938DC3FFFFCA938D938D93C4FD07FF8D938D +%BCFD4DFFCA9368938C9368938C9368938C939AFD05FF939368938C936893 +%8C939AFFFFCA68938C93689AFD07FF938C9393FD4DFFCA8D938C938D938C +%938D938C938D938C938D938C938D938C938D938C938DC3FFFFCA938C938D +%938CFD07FF8C938D9AFD4DFF9A9368936893689368936893689368936893 +%6893689368936893689368939AFFFFCA689368936893A1FD06FF93689393 +%FD4DFFBC8D938D938D938D938D938D938D938D938D938D938D938D938D93 +%8D938DC3FFFFCA938D938D938DC3FD06FF8D938D9AFD4DFF93938C936893 +%8C9368938C9368938C9368938C9368938C93A1CAA8CAA1CACAFFFFFFA8CA +%A1CAA8CA9A938C9368938C9368938C9368938C9368CAFD46FF9A8C938D93 +%8C938D938C938D938C938D938C938D938C938DFD10FFC38C938D938C938D +%938C938D938C938D93A8FD46FF9393689368936893689368936893689368 +%93689368936893FD10FFA193689368936893689368936893689368CAFD46 +%FF9A8D938D938D938D938D938D938D938D938D938D938D938DFD06CAFD04 +%FFFD06CAC38D938D938D938D938D938D938D938D93CAFD46FF939368938C +%9368938C9368938C9368938C9368938C9368938C9368938C939AFFFFCA68 +%938C9368938CFD06FF938C9393FD4DFFC38D938C938D938C938D938C938D +%938C938D938C938D938C938D938C938DC3FFFFCA938C938D938CBCFD06FF +%8C938D9AFD4DFF9A93689368936893689368936893689368936893689368 +%936893689368939AFFFFCA68936893689393FD06FF93689393FD4DFFCA8D +%938D938D938D938D938D938D9AFD05FFCA8D938D938D938D938DC3FFFFCA +%938D938D938DC3FD06FF8D938D9AFD4EFF938C9368938C9368938C936893 +%9AFD05FF9A938C9368938C9368939BFFFFCA8C9368938C93A1FD06FF9368 +%9393FD4EFF9A938D938C938D938C938D938CCAFD05FF9A8C938D938C938D +%938CC3FFFFA8938D938C938DFD07FF8D938CBCFD48FFC3FD05FFCA689368 +%936893689368936893A8FD05FF689368936893689368938D9A9393689368 +%93689AFD07FFC39AA1A1FD47FFBC8DC3FD05FFCA8D938D938D938D938D93 +%A1FD05FFC3938D938D938D938D938D938D938D938D938D93C3FD50FFA893 +%68938DFD06FFCA939368938C936894A8FD06FF948C9368938C9368938C93 +%68938C9368938C938DFD4FFFCA93938D938C9393FD07FFCACA9BC3CAFD08 +%FFC38C938D938C938D938C938D938C938D938C938DC3FD4DFFA89A689368 +%93689368939AFD12FFC36893689368936893689368936893689368936894 +%FD4DFFA1938D938D938D938D938D9393FD0FFFCABC8D938D938D938D938D +%938D938D938D938D938D93CAFD4CFFA19368938C9368938C9368938C9368 +%BDA8FD0AFFCA9A9368938C9368938C9368938C9368938C9368938C93A1FD +%4CFF9A938D938C938D938C938D938C938D938C93939A9BC3CACAA1C39A93 +%8C938D938C938D938C938D938C938D938C938D938C939AFD4CFFA1936893 +%689368936893689368936893689368936893689368936893689368936893 +%689368936893689368936893689368939AFD4CFFCA938D938D938D938D93 +%8D938D938D938D938D938D938D938D938D938D938D938D938D938D938D93 +%8D938D938D938D938D93A1FD4CFFCA938C9368938C9368938C9368938C93 +%68938C9368938C9368938C9368938C9368938C9368938C9368938C936893 +%8C936893A1FD4DFFC38C938D938C938D938C938D938C938D938C938D938C +%938D938C938D938C938D938C938D938C938D938C938D938C938DBDCAFD4E +%FF6893689368936893689368936893689368936893689368936893689368 +%93689368936893689368936893689368939AFD50FF9A938D938D938D938D +%938D938D938D938D938D938D938D938D938D938D938D938D938D938D938D +%938D938D938D93CAFD50FFCA938C9368938C9368938C9368938C9368938C +%9368938D9A9AC4A8CAA1CAA8A19A938C9368938C9368938C936894CAFD4B +%FFA8A8FD04FFCA8C938D938C938D938C938D938C938D938C938D9AA1FD0D +%FF9A938C938D938C938D9ACAFD4AFFA97D7D53FD04FF9493689368936893 +%6893689368936893689368C3FD10FFA893689368936893CAFD4BFF527D52 +%7DFD04FF938D938D938D938D938D938D938D938D938DCAFD12FFCA938D93 +%8D93C4FD4CFF7D527D7DFD04FF8C9368938C9368938C9368938C9368938C +%A1FD07FFCAA1C39BA1A1FD07FFA1938C9394FD07FFA8A87DA87DA8A8FD0D +%FF7EA87DA8A8FD0CFFA87DA87DA8A8FD0CFFA87DA87DA8A8FD09FF527D52 +%7DFD04FF938D938C938D938C938D938C938D938C93CAFD05FFCA948D938C +%938D938CC3FD06FF93938DFD07FF7D7D527D537D527D7DA8FD04FF7D7D53 +%7DA8A8537D527D537D7DFD09FFA87D527D537D527D7DA8FD08FFA87D537D +%527D537D52A8FD04FF537D527D537D527D537D5268936893689368936893 +%68936893689393FD05FFCA93689368936893689368C3FD05FFA1689AFD06 +%FF537D527D527D527D527D52A8FFFFFF7D527D527D527D527D527D527D52 +%A8FD06FF7D7D527D527D527D527D527DFD06FF7D7D527D527D527D527D52 +%7DA8FFA87D527D527D527D527D527D938D938D938D938D938D938D938D93 +%8DBCFD05FFC38D938D938D938D938D9393FD05FFCA93C3FD05FFFD047D52 +%A8A8A8537D7D7D52FFFFFFFD047D527D7DA8A8A87D7D527D7DFD05FFFD04 +%7D527DA8A8FD047D52A8FD04FFA87D52FD047DA87D7D527D7DA8FFFF7D7D +%527D7D7D527D7D7D5268938C9368938C9368938C9368938C939AFD05FF9A +%9368938C9368938C936893CAFD04FFCA68FD05FFA87D527D52A8FD04FF52 +%7D527DA8FFFF7D527D527D7DFD05FF527D527D7DFFFFFFA87D527D52A8FD +%04FF7E7D527D52FFFFFFA87D527D52A8FD04FF7D7D527D52FD05FF527D52 +%7DFD04FF938C938D938C938D938C938D938C938D938C938D938C938D938C +%938D938C938D938CCAFD05FF93FD06FF537D527DFD05FFA8527D53A8FFFF +%7D7D527D7DFD07FF537D527DFFFFFFA8537D52A8FD06FF7D7D537DA8FFFF +%A8527D53A8FD06FF7D7D527DA8FD04FF7D527D53FD04FF68936893689368 +%936893689368936893689368936893689368936893689368936893A1FD05 +%FF93FD05FFA87D527D52A8FD04FFA8A8A8FFA8FFFF7D527D52A8FD07FF7D +%527D52A8FFFF537D527DA8FD06FFA8527D52A8FFFF537D527DA8FD06FFA8 +%527D52A8FD04FF527D527DFD04FF938D938D938D938D938D938D938D938D +%938D938D938D938D938D938D9393BC949A94FD06FF9AFD06FF7D7D52FD04 +%7DA8FD08FF7D7D527DA8FD07FF7D7D527DA8FFFF7D7D7D52A87D7D7DA8FD +%067DA8FFFF7D527D7DFD10FF7D527D7DFD04FF8C9368938C9368938C9368 +%938C9368938C9368938C9393C3A1CACAFD0DFF9AFD06FFA8527D527D527D +%527D7DA8A8FD04FF7D527D52FD08FFA8527D52A8FFFF527D527D527D527D +%527D527D527D52A8FFFF527D527DFD10FF527D527DFD04FFBC8D938C938D +%938C938D938C938D938C938D938DC3CAFD12FFCAFD07FFA87D7D527D537D +%527D537DA8FFFFFF7D7D537DA8FD07FF7E7D537D7EFFA87D527D537D527D +%537D527D537D527DA8FFA87D537D7DFD10FF7D537D52FD04FF9B93689368 +%9368936893689368936893689393CAFD1EFFA87D527D527D527D527DA8FF +%FF7D527D52A8FD07FFA8527D52A8FFFF527D527D7DA87DA87DA87DA87DA8 +%7DFFFFFF527D527DFD10FF527D527DFD05FF8D938D938D938D938D938D93 +%8D938D9393FD23FFA8A8FD047D52A8FFFFFD047DA8FD07FFFD047DA8FFFF +%7D527D7DFD0EFF7D7D7D52FD09FFA8FFA8FD04FF7D7D7D52FD05FF9A8C93 +%68938C9368938C9368938C9393FD07FFA8C39A9A93938C936893A8FD0BFF +%A8A87DA8A8FD05FF7D7D527D7DFFFF7D527D52A8FD07FF7D527D52A8FFFF +%527D527DA8FD06FFA87D7D7DA8FFFF527D527DA8FD06FFA8527D52A8FD04 +%FF527D527DFD05FFA8938D938C938D938C938D938C938DCAFD06FF94938C +%938D938C938D938CCAFD0BFF7E537D52A8FD06FF527D537DFFFF7D7D527D +%7DFD07FF537D527DFFFFFFA8537D52A8FD06FF7D7D537DA8FFFFA8527D53 +%A8FD06FF7D7D527DA8FD04FF7D527D53FD06FF9393689368936893689368 +%93689AFD05FFCA689368936893689368936893A1FD0BFF7D7D527D53FD05 +%FF7D7D527D7DFFFF7D527D527D7DFD05FF527D527D7DFFFFFFA87D527D52 +%FD05FFA87D527D52FFFFFFA87D527D52FD05FFA87D527D52FD05FF527D52 +%7DFD07FF93938D938D938D938D938D93C4FD05FF94938D938D938D938D93 +%8D938DFD0DFF7D7D527D7DA8A8A87D7D527D7DA8FFFF7D7D52FD047DA8A8 +%A8537D7D7D53FD05FF7D7D527D7D7DA8A87D7D527D7DA8FD04FFFD047D52 +%A8A8A8FD047D52A8FD05FF7D527D7DA8A8A87DFFFFFFC48C9368938C9368 +%938C9368FD05FFCA9368938C9368938C9368938C93FD0DFFA8527D527D52 +%7D527D527D52A8FFFFFF7D527D527D527D527D527D527D52A8FD06FF7D7D +%527D527D527D527D527DFD06FF7D7D527D527D527D527D527DA8FD05FF7D +%7D527D527D527DFD04FFC38D938C938D938C938D93FD05FFCA8D938C938D +%938C938D938C9394FD0EFFA8537D527D537D527D53A8FD04FF7D7D537D7D +%7D537D527D537D7DFD09FF7D7D527D537D527D53A8FD08FF7D7D537D527D +%537D52A8FD08FF7D7D527D537D52FD05FF9A689368936893689368FD05FF +%A8936893689368936893689368C3FD10FFA8A87D7D7DA87DFD06FF7D527D +%52A8A8A87D7D7DA8A8FD0BFFA8A8FD057DFD0BFFA8A87D7D7DA8A8FD0BFF +%A8FD047DA8FD06FFBD8D938D938D938D93CAFD05FF93938D938D938D938D +%938D93CAFD1DFFFD047DA8FD43FFC368938C9368938CC3FD05FFC38C9368 +%938C9368938C939AFD1EFF7D527D52A8FD44FFCA93938D938C9394FD06FF +%C38D938C938D938C93A1FD1FFF7D7D527DA8FD46FFA19368936893A1FD07 +%FF9A9A939A94C3A8FD20FF7D527D52FD49FFCA9A938D93FD2EFF7D7D527D +%A8FD4BFFCA9BCAFD2EFFA8A8A8FDFCFFFD40FFFF +%%EndData +%%EndComments +%%BeginProlog +%%BeginResource: procset Adobe_level2_AI5 1.2 0 +%%Title: (Adobe Illustrator (R) Version 5.0 Level 2 Emulation) +%%Version: 1.2 0 +%%CreationDate: (04/10/93) () +%%Copyright: ((C) 1987-1996 Adobe Systems Incorporated All Rights Reserved) +userdict /Adobe_level2_AI5 26 dict dup begin + put + /packedarray where not + { + userdict begin + /packedarray + { + array astore readonly + } bind def + /setpacking /pop load def + /currentpacking false def + end + 0 + } if + pop + userdict /defaultpacking currentpacking put true setpacking + /initialize + { + Adobe_level2_AI5 begin + } bind def + /terminate + { + currentdict Adobe_level2_AI5 eq + { + end + } if + } bind def + mark + /setcustomcolor where not + { + /findcmykcustomcolor + { + (AI8_CMYK_CustomColor) + 6 packedarray + } bind def + /findrgbcustomcolor + { + (AI8_RGB_CustomColor) + 5 packedarray + } bind def + /setcustomcolor + { + exch + aload pop dup + (AI8_CMYK_CustomColor) eq + { + pop pop + 4 + { + 4 index mul + 4 1 roll + } repeat + 5 -1 roll pop + setcmykcolor + } + { + dup (AI8_RGB_CustomColor) eq + { + pop pop + 3 + { + 1 exch sub + 3 index mul + 1 exch sub + 3 1 roll + } repeat + 4 -1 roll pop + setrgbcolor + } + { + pop + 4 + { + 4 index mul 4 1 roll + } repeat + 5 -1 roll pop + setcmykcolor + } ifelse + } ifelse + } + def + } if + /setAIseparationgray + { + false setoverprint + 0 setgray + /setseparationgray where{ + pop setseparationgray + }{ + /setcolorspace where{ + pop + [/Separation (All) /DeviceCMYK {dup dup dup}] setcolorspace + 1 exch sub setcolor + }{ + setgray + }ifelse + }ifelse + } def + + /gt38? mark {version cvr cvx exec} stopped {cleartomark true} {38 gt exch pop} ifelse def + userdict /deviceDPI 72 0 matrix defaultmatrix dtransform dup mul exch dup mul add sqrt put + userdict /level2? + systemdict /languagelevel known dup + { + pop systemdict /languagelevel get 2 ge + } if + put +/level2ScreenFreq +{ + begin + 60 + HalftoneType 1 eq + { + pop Frequency + } if + HalftoneType 2 eq + { + pop GrayFrequency + } if + HalftoneType 5 eq + { + pop Default level2ScreenFreq + } if + end +} bind def +userdict /currentScreenFreq + level2? {currenthalftone level2ScreenFreq} {currentscreen pop pop} ifelse put +level2? not + { + /setcmykcolor where not + { + /setcmykcolor + { + exch .11 mul add exch .59 mul add exch .3 mul add + 1 exch sub setgray + } def + } if + /currentcmykcolor where not + { + /currentcmykcolor + { + 0 0 0 1 currentgray sub + } def + } if + /setoverprint where not + { + /setoverprint /pop load def + } if + /selectfont where not + { + /selectfont + { + exch findfont exch + dup type /arraytype eq + { + makefont + } + { + scalefont + } ifelse + setfont + } bind def + } if + /cshow where not + { + /cshow + { + [ + 0 0 5 -1 roll aload pop + ] cvx bind forall + } bind def + } if + } if + cleartomark + /anyColor? + { + add add add 0 ne + } bind def + /testColor + { + gsave + setcmykcolor currentcmykcolor + grestore + } bind def + /testCMYKColorThrough + { + testColor anyColor? + } bind def + userdict /composite? + 1 0 0 0 testCMYKColorThrough + 0 1 0 0 testCMYKColorThrough + 0 0 1 0 testCMYKColorThrough + 0 0 0 1 testCMYKColorThrough + and and and + put + composite? not + { + userdict begin + gsave + /cyan? 1 0 0 0 testCMYKColorThrough def + /magenta? 0 1 0 0 testCMYKColorThrough def + /yellow? 0 0 1 0 testCMYKColorThrough def + /black? 0 0 0 1 testCMYKColorThrough def + grestore + /isCMYKSep? cyan? magenta? yellow? black? or or or def + /customColor? isCMYKSep? not def + end + } if + end defaultpacking setpacking +%%EndResource +%%BeginProcSet: Adobe_ColorImage_AI6 1.2 0 +userdict /Adobe_ColorImage_AI6 known not +{ + userdict /Adobe_ColorImage_AI6 50 dict put +} if +userdict /Adobe_ColorImage_AI6 get begin +/initialize { + Adobe_ColorImage_AI6 begin + Adobe_ColorImage_AI6 { + dup type /arraytype eq { + dup xcheck { + bind + } if + } if + pop pop + } forall +} def +/terminate { end } def +currentdict /Adobe_ColorImage_AI6_Vars known not { + /Adobe_ColorImage_AI6_Vars 40 dict def +} if +Adobe_ColorImage_AI6_Vars begin + /plateindex -1 def + /_newproc null def + /_proc1 null def + /_proc2 null def + /channelcount 0 def + /sourcecount 0 def + /sourcearray 4 array def + /_ptispace null def + /_ptiname null def + /_pti0 0 def + /_pti1 0 def + /_ptiproc null def + /_ptiscale 0 def + /_pticomps 0 def + /_ptibuf 0 string def + /_gtigray 0 def + /_cticmyk null def + /_rtirgb null def + /XIEnable true def + /XIType 0 def + /XIEncoding 0 def + /XICompression 0 def + /XIChannelCount 0 def + /XIBitsPerPixel 0 def + /XIImageHeight 0 def + /XIImageWidth 0 def + /XIImageMatrix null def + /XIRowBytes 0 def + /XIFile null def + /XIBuffer1 null def + /XIBuffer2 null def + /XIDataProc null def + /XIVersion 6 def + /XIColorSpace /DeviceGray def + /XIColorValues 0 def +end +currentdict /_colorimage known not { + /colorimage where { + /colorimage get /_colorimage exch def + }{ + /_colorimage null def + } ifelse +} if +/_image systemdict /image get def +/_currenttransfer systemdict /currenttransfer get def +/FourEqual { + 4 index ne { + pop pop pop false + }{ + 4 index ne { + pop pop false + }{ + 4 index ne { + pop false + }{ + 4 index eq + } ifelse + } ifelse + } ifelse +} def +/TestPlateIndex { + Adobe_ColorImage_AI6_Vars begin + /plateindex -1 def + /setcmykcolor where { + pop + gsave + 1 0 0 0 setcmykcolor systemdict /currentgray get exec 1 exch sub + 0 1 0 0 setcmykcolor systemdict /currentgray get exec 1 exch sub + 0 0 1 0 setcmykcolor systemdict /currentgray get exec 1 exch sub + 0 0 0 1 setcmykcolor systemdict /currentgray get exec 1 exch sub + grestore + 1 0 0 0 FourEqual { + /plateindex 0 def + }{ + 0 1 0 0 FourEqual { + /plateindex 1 def + }{ + 0 0 1 0 FourEqual { + /plateindex 2 def + }{ + 0 0 0 1 FourEqual { + /plateindex 3 def + }{ + 0 0 0 0 FourEqual { + /plateindex 5 def + } if + } ifelse + } ifelse + } ifelse + } ifelse + pop pop pop pop + } if + plateindex + end +} def +/concatprocs { + /packedarray where { + pop dup type /packedarraytype eq 2 index type + /packedarraytype eq or + }{ + false + } ifelse + { + /_proc2 exch cvlit def + /_proc1 exch cvlit def + _proc1 aload pop + _proc2 aload pop + _proc1 length + _proc2 length add + packedarray cvx + }{ + /_proc2 exch cvlit def + /_proc1 exch cvlit def + /_newproc _proc1 length _proc2 length add array def + _newproc 0 _proc1 putinterval + _newproc _proc1 length _proc2 putinterval + _newproc cvx + } ifelse +} def +/clrspaceissepn { + type /arraytype eq +} def +/clrspacegetname { + dup clrspaceissepn {dup length 2 sub get}{pop ()} ifelse +} def +/clrspacegetalt { + aload pop pop pop colormake +} def +/clrspacegetcomps { + dup /DeviceGray eq { + pop 1 + }{ + dup /DeviceRGB eq { + pop 3 + }{ + /DeviceCMYK eq { + 4 + }{ + 1 + } ifelse + } ifelse + } ifelse +} def +/clrspacemarksplate { + dup /DeviceGray eq { + pop plateindex 3 eq + }{ + dup /DeviceRGB eq { + pop plateindex 5 ne + }{ + dup /DeviceCMYK eq { + pop plateindex 5 ne + }{ + /findcmykcustomcolor where { + pop + dup length 2 sub get + 0.1 0.1 0.1 0.1 5 -1 roll + findcmykcustomcolor 1 setcustomcolor + systemdict /currentgray get exec + 1 ne + }{ + pop plateindex 5 ne + } ifelse + } ifelse + } ifelse + } ifelse +} def +/colormake { + dup clrspacegetcomps + exch 1 index 2 add 1 roll + dup 1 eq {pop}{array astore} ifelse + exch +} def +/colorexpand { + dup clrspacegetname exch + dup clrspaceissepn { + clrspacegetalt + exch 4 1 roll + }{ + 1 3 1 roll + } ifelse +} def +/colortint { + dup /DeviceGray eq { + 3 1 roll 1 exch sub mul 1 exch sub exch + }{ + dup /DeviceRGB eq { + 3 1 roll {1 exch sub 1 index mul 1 exch sub exch} forall pop 3 array astore exch + }{ + dup /DeviceCMYK eq { + 3 1 roll {1 index mul exch} forall pop 4 array astore exch + }{ + 3 1 roll mul exch + } ifelse + } ifelse + } ifelse +} def +/colortocmyk { + dup /DeviceGray eq { + pop 1 exch sub 0 0 0 4 -1 roll 4 array astore + }{ + dup /DeviceRGB eq { + pop aload pop _rgbtocmyk 4 array astore + }{ + dup /DeviceCMYK eq { + pop + }{ + clrspacegetalt colortint colortocmyk + } ifelse + } ifelse + } ifelse +} def +/makeimagedict { + 7 dict begin + /ImageType 1 def + /Decode exch def + /DataSource exch def + /ImageMatrix exch def + /BitsPerComponent exch def + /Height exch def + /Width exch def + currentdict end +} def +/stringinvert { + 0 1 2 index length 1 sub { + dup 2 index exch get 255 exch sub 2 index 3 1 roll put + } for +} def +/stringknockout { + 0 1 2 index length 1 sub { + 255 2 index 3 1 roll put + } for +} def +/stringapply { + 0 1 4 index length 1 sub { + dup + 4 index exch get + 3 index 3 1 roll + 3 index exec + } for + pop exch pop +} def +/WalkRGBString { + 0 3 index + dup length 1 sub 0 3 3 -1 roll { + 3 getinterval {} forall + 5 index exec + 3 index + } for + + 5 {pop} repeat +} def +/WalkCMYKString +{ + 0 3 index + dup length 1 sub 0 4 3 -1 roll { + 4 getinterval {} forall + + 6 index exec + + 3 index + + } for + + 5 { pop } repeat + +} def +/StuffRGBIntoGrayString +{ + .11 mul exch + + .59 mul add exch + + .3 mul add + + cvi 3 copy put + + pop 1 add +} def +/StuffCMYKIntoGrayString +{ + exch .11 mul add + + exch .59 mul add + + exch .3 mul add + + dup 255 gt { pop 255 } if + + 255 exch sub cvi 3 copy put + + pop 1 add +} def +/RGBToGrayImageProc { + Adobe_ColorImage_AI6_Vars begin + sourcearray 0 get exec + dup length 3 idiv string + dup 3 1 roll + + /StuffRGBIntoGrayString load exch + WalkRGBString + end +} def +/CMYKToGrayImageProc { + Adobe_ColorImage_AI6_Vars begin + sourcearray 0 get exec + dup length 4 idiv string + dup 3 1 roll + + /StuffCMYKIntoGrayString load exch + WalkCMYKString + end +} def +/SeparateCMYKImageProc { + Adobe_ColorImage_AI6_Vars begin + sourcecount 0 ne { + sourcearray plateindex get exec + }{ + sourcearray 0 get exec + + dup length 4 idiv string + + 0 2 index + + plateindex 4 2 index length 1 sub { + get 255 exch sub + + 3 copy put pop 1 add + + 2 index + } for + pop pop exch pop + } ifelse + end +} def + +/ColorImageCompositeEmulator { + pop true eq { + Adobe_ColorImage_AI6_Vars /sourcecount get 5 add { pop } repeat + }{ + Adobe_ColorImage_AI6_Vars /channelcount get 1 ne { + Adobe_ColorImage_AI6_Vars begin + sourcearray 0 3 -1 roll put + + channelcount 3 eq {/RGBToGrayImageProc}{/CMYKToGrayImageProc} ifelse + load + end + } if + image + } ifelse +} def +/colorimage { + Adobe_ColorImage_AI6_Vars begin + /channelcount 1 index def + /sourcecount 2 index 1 eq { channelcount 1 sub } { 0 } ifelse def + 4 sourcecount add index + end + + dup 8 eq exch 1 eq or not { + /_colorimage load null ne { + _colorimage + }{ + Adobe_ColorImage_AI6_Vars /sourcecount get + 7 add { pop } repeat + } ifelse + }{ + dup 3 eq TestPlateIndex dup -1 eq exch 5 eq or or { + /_colorimage load null eq { + ColorImageCompositeEmulator + }{ + dup 1 eq { + pop pop image + }{ + Adobe_ColorImage_AI6_Vars /plateindex get 5 eq { + gsave + + 0 _currenttransfer exec + 1 _currenttransfer exec + eq + { 0 _currenttransfer exec 0.5 lt } + { 0 _currenttransfer exec 1 _currenttransfer exec gt } ifelse + + { { pop 0 } } { { pop 1 } } ifelse + systemdict /settransfer get exec + } if + + _colorimage + + Adobe_ColorImage_AI6_Vars /plateindex get 5 eq { + grestore + } if + } ifelse + } ifelse + }{ + dup 1 eq { + pop pop + image + }{ + pop pop + Adobe_ColorImage_AI6_Vars begin + sourcecount -1 0 { + exch sourcearray 3 1 roll put + } for + /SeparateCMYKImageProc load + end + systemdict /image get exec + } ifelse + } ifelse + } ifelse +} def +/proctintimage { + /_ptispace exch store /_ptiname exch store /_pti1 exch store /_pti0 exch store /_ptiproc exch store + /_pticomps _ptispace clrspacegetcomps store + /_ptiscale _pti1 _pti0 sub store + level2? { + _ptiname length 0 gt version cvr 2012 ge and { + [/Separation _ptiname _ptispace {_ptiproc}] setcolorspace + [_pti0 _pti1] makeimagedict _image + }{ + [/Indexed _ptispace 255 {255 div _ptiscale mul _pti0 add _ptiproc}] setcolorspace + [0 255] makeimagedict _image + } ifelse + }{ + _pticomps 1 eq { + { + dup + { + 255 div _ptiscale mul _pti0 add _ptiproc 255 mul cvi put + } stringapply + } concatprocs _image + }{ + { + dup length _pticomps mul dup _ptibuf length ne {/_ptibuf exch string store}{pop} ifelse + _ptibuf { + exch _pticomps mul exch 255 div _ptiscale mul _pti0 add _ptiproc + _pticomps 2 add -2 roll + _pticomps 1 sub -1 0 { + 1 index add 2 index exch + 5 -1 roll + 255 mul cvi put + } for + pop pop + } stringapply + } concatprocs false _pticomps + /_colorimage load null eq {7 {pop} repeat}{_colorimage} ifelse + } ifelse + } ifelse +} def +/graytintimage { + /_gtigray 5 -1 roll store + {1 _gtigray sub mul 1 exch sub} 4 1 roll + /DeviceGray proctintimage +} def +/cmyktintimage { + /_cticmyk 5 -1 roll store + {_cticmyk {1 index mul exch} forall pop} 4 1 roll + /DeviceCMYK proctintimage +} def +/rgbtintimage { + /_rtirgb 5 -1 roll store + {_rtirgb {1 exch sub 1 index mul 1 exch sub exch} forall pop} 4 1 roll + /DeviceRGB proctintimage +} def +/tintimage { + TestPlateIndex -1 eq { + colorexpand + 3 -1 roll 5 -1 roll {0}{0 exch} ifelse 4 2 roll + dup /DeviceGray eq { + pop graytintimage + }{ + dup /DeviceRGB eq { + pop rgbtintimage + }{ + pop cmyktintimage + } ifelse + } ifelse + }{ + dup clrspacemarksplate { + plateindex 5 lt { + colortocmyk plateindex get 1 exch sub + exch {1 0}{0 1} ifelse () graytintimage + }{ + pop exch {0}{0 exch} ifelse 0 3 1 roll () graytintimage + } ifelse + }{ + pop pop pop + {pop 1} 0 1 () /DeviceGray proctintimage + } ifelse + } ifelse +} def +/XINullImage { +} def +/XIImageMask { + XIImageWidth XIImageHeight false + [XIImageWidth 0 0 XIImageHeight neg 0 0] + /XIDataProc load + imagemask +} def +/XIImageTint { + 0 setgray + XIImageWidth XIImageHeight XIBitsPerPixel + [XIImageWidth 0 0 XIImageHeight neg 0 0] + /XIDataProc load + XIType 3 eq XIColorValues XIColorSpace tintimage +} def +/XIImage { + 0 setgray + XIImageWidth XIImageHeight XIBitsPerPixel + [XIImageWidth 0 0 XIImageHeight neg 0 0] + /XIDataProc load + XIChannelCount 1 eq {image}{false XIChannelCount colorimage} ifelse +} def +/XG { + pop pop +} def +/XF { + 13 {pop} repeat +} def +/Xh { + Adobe_ColorImage_AI6_Vars begin + gsave + /XIType exch def + /XIImageHeight exch def + /XIImageWidth exch def + /XIImageMatrix exch def + 0 0 moveto + XIImageMatrix concat + XIImageWidth XIImageHeight scale + + XIType 1 eq { + /_lp /null ddef + _fc + /_lp /imagemask ddef + } + if + /XIVersion 7 def + end +} def +/XH { + Adobe_ColorImage_AI6_Vars begin + /XIVersion 6 def + grestore + end +} def +/XIEnable { + Adobe_ColorImage_AI6_Vars /XIEnable 3 -1 roll put +} def +/XC { + Adobe_ColorImage_AI6_Vars begin + colormake + /XIColorSpace exch def + /XIColorValues exch def + end +} def +/XI +{ + Adobe_ColorImage_AI6_Vars begin + gsave + /XIType exch def + cvi dup + 256 idiv /XICompression exch store + 256 mod /XIEncoding exch store + pop pop + /XIChannelCount exch def + /XIBitsPerPixel exch def + /XIImageHeight exch def + /XIImageWidth exch def + pop pop pop pop + /XIImageMatrix exch def + XIBitsPerPixel 1 eq { + XIImageWidth 8 div ceiling cvi + }{ + XIImageWidth XIChannelCount mul + } ifelse + /XIRowBytes exch def + XIEncoding 0 ne XIVersion 6 le and { + currentfile 128 string readline pop pop + } if + XICompression 0 eq { + /XIBuffer1 XIRowBytes string def + XIEncoding 0 eq { + {currentfile XIBuffer1 readhexstring pop} + }{ + {currentfile XIBuffer1 readstring pop} + } ifelse + }{ + /XIBuffer1 256 string def + /XIBuffer2 XIRowBytes string def + {currentfile XIBuffer1 readline pop (%) anchorsearch {pop} if} + /ASCIIHexDecode filter /DCTDecode filter + /XIFile exch def + {XIFile XIBuffer2 readstring pop} + } ifelse + /XIDataProc exch def + + XIVersion 6 le { + 0 0 moveto + XIImageMatrix concat + XIImageWidth XIImageHeight scale + XIType 1 eq { + /_lp /null ddef + _fc + /_lp /imagemask ddef + } if + } if + XIEnable { + XIType 1 eq { + XIImageMask + }{ + XIType 2 eq XIType 3 eq or { + XIImageTint + }{ + XIImage + } ifelse + } ifelse + }{ + XINullImage + } ifelse + grestore + end +} def +end +%%EndProcSet +%%BeginResource: procset Adobe_Illustrator_AI5 1.2 0 +%%Title: (Adobe Illustrator (R) Version 7.0 Full Prolog) +%%Version: 1.2 0 +%%CreationDate: (3/7/1994) () +%%Copyright: ((C) 1987-1996 Adobe Systems Incorporated All Rights Reserved) +currentpacking true setpacking +userdict /Adobe_Illustrator_AI5_vars 107 dict dup begin +put +/_eo false def +/_lp /none def +/_pf +{ +} def +/_ps +{ +} def +/_psf +{ +} def +/_pss +{ +} def +/_pjsf +{ +} def +/_pjss +{ +} def +/_pola 0 def +/_doClip 0 def +/cf currentflat def +/_lineorientation 0 def +/_charorientation 0 def +/_yokoorientation 0 def +/_tm matrix def +/_renderStart +[ +/e0 /r0 /a0 /o0 /e1 /r1 /a1 /i0 +] def +/_renderEnd +[ +null null null null /i1 /i1 /i1 /i1 +] def +/_render -1 def +/_shift [0 0] def +/_ax 0 def +/_ay 0 def +/_cx 0 def +/_cy 0 def +/_leading +[ +0 0 +] def +/_ctm matrix def +/_mtx matrix def +/_sp 16#020 def +/_hyphen (-) def +/_fontSize 0 def +/_fontAscent 0 def +/_fontDescent 0 def +/_fontHeight 0 def +/_fontRotateAdjust 0 def +/Ss 256 string def +Ss 0 (fonts/) putinterval +/_cnt 0 def +/_scale [1 1] def +/_nativeEncoding 0 def +/_useNativeEncoding 0 def +/_tempEncode 0 def +/_pntr 0 def +/_tDict 2 dict def +/_hfname 100 string def +/_hffound false def +/Tx +{ +} def +/Tj +{ +} def +/CRender +{ +} def +/_AI3_savepage +{ +} def +/_gf null def +/_cf 4 array def +/_rgbf 3 array def +/_if null def +/_of false def +/_fc +{ +} def +/_gs null def +/_cs 4 array def +/_rgbs 3 array def +/_is null def +/_os false def +/_sc +{ +} def +/_pd 1 dict def +/_ed 15 dict def +/_pm matrix def +/_fm null def +/_fd null def +/_fdd null def +/_sm null def +/_sd null def +/_sdd null def +/_i null def +/_lobyte 0 def +/_hibyte 0 def +/_cproc null def +/_cscript 0 def +/_hvax 0 def +/_hvay 0 def +/_hvwb 0 def +/_hvcx 0 def +/_hvcy 0 def +/_bitfont null def +/_bitlobyte 0 def +/_bithibyte 0 def +/_bitkey null def +/_bitdata null def +/_bitindex 0 def +/discardSave null def +/buffer 256 string def +/beginString null def +/endString null def +/endStringLength null def +/layerCnt 1 def +/layerCount 1 def +/perCent (%) 0 get def +/perCentSeen? false def +/newBuff null def +/newBuffButFirst null def +/newBuffLast null def +/clipForward? false def +end +userdict /Adobe_Illustrator_AI5 known not { + userdict /Adobe_Illustrator_AI5 95 dict put +} if +userdict /Adobe_Illustrator_AI5 get begin +/initialize +{ + Adobe_Illustrator_AI5 dup begin + Adobe_Illustrator_AI5_vars begin + discardDict + { + bind pop pop + } forall + dup /nc get begin + { + dup xcheck 1 index type /operatortype ne and + { + bind + } if + pop pop + } forall + end + newpath +} def +/terminate +{ + end + end +} def +/_ +null def +/ddef +{ + Adobe_Illustrator_AI5_vars 3 1 roll put +} def +/xput +{ + dup load dup length exch maxlength eq + { + dup dup load dup + length 2 mul dict copy def + } if + load begin + def + end +} def +/npop +{ + { + pop + } repeat +} def +/hswj +{ + dup stringwidth 3 2 roll + { + _hvwb eq { exch _hvcx add exch _hvcy add } if + exch _hvax add exch _hvay add + } cforall +} def +/vswj +{ + 0 0 3 -1 roll + { + dup 255 le + _charorientation 1 eq + and + { + dup cstring stringwidth 5 2 roll + _hvwb eq { exch _hvcy sub exch _hvcx sub } if + exch _hvay sub exch _hvax sub + 4 -1 roll sub exch + 3 -1 roll sub exch + } + { + _hvwb eq { exch _hvcy sub exch _hvcx sub } if + exch _hvay sub exch _hvax sub + _fontHeight sub + } ifelse + } cforall +} def +/swj +{ + 6 1 roll + /_hvay exch ddef + /_hvax exch ddef + /_hvwb exch ddef + /_hvcy exch ddef + /_hvcx exch ddef + _lineorientation 0 eq { hswj } { vswj } ifelse +} def +/sw +{ + 0 0 0 6 3 roll swj +} def +/vjss +{ + 4 1 roll + { + dup cstring + dup length 1 eq + _charorientation 1 eq + and + { + -90 rotate + currentpoint + _fontRotateAdjust add + moveto + gsave + false charpath currentpoint + 5 index setmatrix stroke + grestore + _fontRotateAdjust sub + moveto + _sp eq + { + 5 index 5 index rmoveto + } if + 2 copy rmoveto + 90 rotate + } + { + currentpoint + _fontHeight sub + 5 index sub + 3 index _sp eq + { + 9 index sub + } if + + currentpoint + exch 4 index stringwidth pop 2 div sub + exch _fontAscent sub + moveto + + gsave + 2 index false charpath + 6 index setmatrix stroke + grestore + + moveto pop pop + } ifelse + } cforall + 6 npop +} def +/hjss +{ + 4 1 roll + { + dup cstring + gsave + false charpath currentpoint + 5 index setmatrix stroke + grestore + moveto + _sp eq + { + 5 index 5 index rmoveto + } if + 2 copy rmoveto + } cforall + 6 npop +} def +/jss +{ + _lineorientation 0 eq { hjss } { vjss } ifelse +} def +/ss +{ + 0 0 0 7 3 roll jss +} def +/vjsp +{ + 4 1 roll + { + dup cstring + dup length 1 eq + _charorientation 1 eq + and + { + -90 rotate + currentpoint + _fontRotateAdjust add + moveto + false charpath + currentpoint + _fontRotateAdjust sub + moveto + _sp eq + { + 5 index 5 index rmoveto + } if + 2 copy rmoveto + 90 rotate + } + { + currentpoint + _fontHeight sub + 5 index sub + 3 index _sp eq + { + 9 index sub + } if + + currentpoint + exch 4 index stringwidth pop 2 div sub + exch _fontAscent sub + moveto + + 2 index false charpath + + moveto pop pop + } ifelse + } cforall + 6 npop +} def +/hjsp +{ + 4 1 roll + { + dup cstring + false charpath + _sp eq + { + 5 index 5 index rmoveto + } if + 2 copy rmoveto + } cforall + 6 npop +} def +/jsp +{ + matrix currentmatrix + _lineorientation 0 eq {hjsp} {vjsp} ifelse +} def +/sp +{ + matrix currentmatrix + 0 0 0 7 3 roll + _lineorientation 0 eq {hjsp} {vjsp} ifelse +} def +/pl +{ + transform + 0.25 sub round 0.25 add exch + 0.25 sub round 0.25 add exch + itransform +} def +/setstrokeadjust where +{ + pop true setstrokeadjust + /c + { + curveto + } def + /C + /c load def + /v + { + currentpoint 6 2 roll curveto + } def + /V + /v load def + /y + { + 2 copy curveto + } def + /Y + /y load def + /l + { + lineto + } def + /L + /l load def + /m + { + moveto + } def +} +{ + /c + { + pl curveto + } def + /C + /c load def + /v + { + currentpoint 6 2 roll pl curveto + } def + /V + /v load def + /y + { + pl 2 copy curveto + } def + /Y + /y load def + /l + { + pl lineto + } def + /L + /l load def + /m + { + pl moveto + } def +} ifelse +/d +{ + setdash +} def +/cf +{ +} def +/i +{ + dup 0 eq + { + pop cf + } if + setflat +} def +/j +{ + setlinejoin +} def +/J +{ + setlinecap +} def +/M +{ + setmiterlimit +} def +/w +{ + setlinewidth +} def +/XR +{ + 0 ne + /_eo exch ddef +} def +/H +{ +} def +/h +{ + closepath +} def +/N +{ + _pola 0 eq + { + _doClip 1 eq + { + _eo {eoclip} {clip} ifelse /_doClip 0 ddef + } if + newpath + } + { + /CRender + { + N + } ddef + } ifelse +} def +/n +{ + N +} def +/F +{ + _pola 0 eq + { + _doClip 1 eq + { + gsave _pf grestore _eo {eoclip} {clip} ifelse newpath /_lp /none ddef _fc + /_doClip 0 ddef + } + { + _pf + } ifelse + } + { + /CRender + { + F + } ddef + } ifelse +} def +/f +{ + closepath + F +} def +/S +{ + _pola 0 eq + { + _doClip 1 eq + { + gsave _ps grestore _eo {eoclip} {clip} ifelse newpath /_lp /none ddef _sc + /_doClip 0 ddef + } + { + _ps + } ifelse + } + { + /CRender + { + S + } ddef + } ifelse +} def +/s +{ + closepath + S +} def +/B +{ + _pola 0 eq + { + _doClip 1 eq + gsave F grestore + { + gsave S grestore _eo {eoclip} {clip} ifelse newpath /_lp /none ddef _sc + /_doClip 0 ddef + } + { + S + } ifelse + } + { + /CRender + { + B + } ddef + } ifelse +} def +/b +{ + closepath + B +} def +/W +{ + /_doClip 1 ddef +} def +/* +{ + count 0 ne + { + dup type /stringtype eq + { + pop + } if + } if + newpath +} def +/u +{ +} def +/U +{ +} def +/q +{ + _pola 0 eq + { + gsave + } if +} def +/Q +{ + _pola 0 eq + { + grestore + } if +} def +/*u +{ + _pola 1 add /_pola exch ddef +} def +/*U +{ + _pola 1 sub /_pola exch ddef + _pola 0 eq + { + CRender + } if +} def +/D +{ + pop +} def +/*w +{ +} def +/*W +{ +} def +/` +{ + /_i save ddef + clipForward? + { + nulldevice + } if + 6 1 roll 4 npop + concat pop + userdict begin + /showpage + { + } def + 0 setgray + 0 setlinecap + 1 setlinewidth + 0 setlinejoin + 10 setmiterlimit + [] 0 setdash + /setstrokeadjust where {pop false setstrokeadjust} if + newpath + 0 setgray + false setoverprint +} def +/~ +{ + end + _i restore +} def +/O +{ + 0 ne + /_of exch ddef + /_lp /none ddef +} def +/R +{ + 0 ne + /_os exch ddef + /_lp /none ddef +} def +/g +{ + /_gf exch ddef + /_fc + { + _lp /fill ne + { + _of setoverprint + _gf setgray + /_lp /fill ddef + } if + } ddef + /_pf + { + _fc + _eo {eofill} {fill} ifelse + } ddef + /_psf + { + _fc + hvashow + } ddef + /_pjsf + { + _fc + hvawidthshow + } ddef + /_lp /none ddef +} def +/G +{ + /_gs exch ddef + /_sc + { + _lp /stroke ne + { + _os setoverprint + _gs setgray + /_lp /stroke ddef + } if + } ddef + /_ps + { + _sc + stroke + } ddef + /_pss + { + _sc + ss + } ddef + /_pjss + { + _sc + jss + } ddef + /_lp /none ddef +} def +/k +{ + _cf astore pop + /_fc + { + _lp /fill ne + { + _of setoverprint + _cf aload pop setcmykcolor + /_lp /fill ddef + } if + } ddef + /_pf + { + _fc + _eo {eofill} {fill} ifelse + } ddef + /_psf + { + _fc + hvashow + } ddef + /_pjsf + { + _fc + hvawidthshow + } ddef + /_lp /none ddef +} def +/K +{ + _cs astore pop + /_sc + { + _lp /stroke ne + { + _os setoverprint + _cs aload pop setcmykcolor + /_lp /stroke ddef + } if + } ddef + /_ps + { + _sc + stroke + } ddef + /_pss + { + _sc + ss + } ddef + /_pjss + { + _sc + jss + } ddef + /_lp /none ddef +} def +/Xa +{ + _rgbf astore pop + /_fc + { + _lp /fill ne + { + _of setoverprint + _rgbf aload pop setrgbcolor + /_lp /fill ddef + } if + } ddef + /_pf + { + _fc + _eo {eofill} {fill} ifelse + } ddef + /_psf + { + _fc + hvashow + } ddef + /_pjsf + { + _fc + hvawidthshow + } ddef + /_lp /none ddef +} def +/XA +{ + _rgbs astore pop + /_sc + { + _lp /stroke ne + { + _os setoverprint + _rgbs aload pop setrgbcolor + /_lp /stroke ddef + } if + } ddef + /_ps + { + _sc + stroke + } ddef + /_pss + { + _sc + ss + } ddef + /_pjss + { + _sc + jss + } ddef + /_lp /none ddef +} def +/_rgbtocmyk +{ +3 + { + 1 exch sub 3 1 roll + } repeat +3 copy 1 4 1 roll +3 + { + 3 index 2 copy gt + { + exch + } if + pop 4 1 roll + } repeat +pop pop pop +4 1 roll +3 + { + 3 index sub + 3 1 roll + } repeat +4 -1 roll +} def +/Xx +{ + exch + /_gf exch ddef + 0 eq + { + findcmykcustomcolor + } + { + /findrgbcustomcolor where not { + 4 1 roll _rgbtocmyk + 5 -1 roll + findcmykcustomcolor + } + { + pop + findrgbcustomcolor + } ifelse + } ifelse + /_if exch ddef + /_fc + { + _lp /fill ne + { + _of setoverprint + _if _gf 1 exch sub setcustomcolor + /_lp /fill ddef + } if + } ddef + /_pf + { + _fc + _eo {eofill} {fill} ifelse + } ddef + /_psf + { + _fc + hvashow + } ddef + /_pjsf + { + _fc + hvawidthshow + } ddef + /_lp /none ddef +} def +/XX +{ + exch + /_gs exch ddef + 0 eq + { + findcmykcustomcolor + } + { + /findrgbcustomcolor where not { + 4 1 roll _rgbtocmyk + 5 -1 roll + findcmykcustomcolor + } + { + pop + findrgbcustomcolor + } ifelse + } ifelse + /_is exch ddef + /_sc + { + _lp /stroke ne + { + _os setoverprint + _is _gs 1 exch sub setcustomcolor + /_lp /stroke ddef + } if + } ddef + /_ps + { + _sc + stroke + } ddef + /_pss + { + _sc + ss + } ddef + /_pjss + { + _sc + jss + } ddef + /_lp /none ddef +} def +/x +{ + /_gf exch ddef + findcmykcustomcolor + /_if exch ddef + /_fc + { + _lp /fill ne + { + _of setoverprint + _if _gf 1 exch sub setcustomcolor + /_lp /fill ddef + } if + } ddef + /_pf + { + _fc + _eo {eofill} {fill} ifelse + } ddef + /_psf + { + _fc + hvashow + } ddef + /_pjsf + { + _fc + hvawidthshow + } ddef + /_lp /none ddef +} def +/X +{ + /_gs exch ddef + findcmykcustomcolor + /_is exch ddef + /_sc + { + _lp /stroke ne + { + _os setoverprint + _is _gs 1 exch sub setcustomcolor + /_lp /stroke ddef + } if + } ddef + /_ps + { + _sc + stroke + } ddef + /_pss + { + _sc + ss + } ddef + /_pjss + { + _sc + jss + } ddef + /_lp /none ddef +} def +/A +{ + pop +} def +/annotatepage +{ +userdict /annotatepage 2 copy known {get exec} {pop pop} ifelse +} def +/XT { + pop pop +} def +/discard +{ + save /discardSave exch store + discardDict begin + /endString exch store + gt38? + { + 2 add + } if + load + stopped + pop + end + discardSave restore +} bind def +userdict /discardDict 7 dict dup begin +put +/pre38Initialize +{ + /endStringLength endString length store + /newBuff buffer 0 endStringLength getinterval store + /newBuffButFirst newBuff 1 endStringLength 1 sub getinterval store + /newBuffLast newBuff endStringLength 1 sub 1 getinterval store +} def +/shiftBuffer +{ + newBuff 0 newBuffButFirst putinterval + newBuffLast 0 + currentfile read not + { + stop + } if + put +} def +0 +{ + pre38Initialize + mark + currentfile newBuff readstring exch pop + { + { + newBuff endString eq + { + cleartomark stop + } if + shiftBuffer + } loop + } + { + stop + } ifelse +} def +1 +{ + pre38Initialize + /beginString exch store + mark + currentfile newBuff readstring exch pop + { + { + newBuff beginString eq + { + /layerCount dup load 1 add store + } + { + newBuff endString eq + { + /layerCount dup load 1 sub store + layerCount 0 eq + { + cleartomark stop + } if + } if + } ifelse + shiftBuffer + } loop + } if +} def +2 +{ + mark + { + currentfile buffer readline not + { + stop + } if + endString eq + { + cleartomark stop + } if + } loop +} def +3 +{ + /beginString exch store + /layerCnt 1 store + mark + { + currentfile buffer readline not + { + stop + } if + dup beginString eq + { + pop /layerCnt dup load 1 add store + } + { + endString eq + { + layerCnt 1 eq + { + cleartomark stop + } + { + /layerCnt dup load 1 sub store + } ifelse + } if + } ifelse + } loop +} def +end +userdict /clipRenderOff 15 dict dup begin +put +{ + /n /N /s /S /f /F /b /B +} +{ + { + _doClip 1 eq + { + /_doClip 0 ddef _eo {eoclip} {clip} ifelse + } if + newpath + } def +} forall +/Tr /pop load def +/Bb {} def +/BB /pop load def +/Bg {12 npop} def +/Bm {6 npop} def +/Bc /Bm load def +/Bh {4 npop} def +end +/Lb +{ + 4 npop + 6 1 roll + pop + 4 1 roll + pop pop pop + 0 eq + { + 0 eq + { + (%AI5_BeginLayer) 1 (%AI5_EndLayer--) discard + } + { + + /clipForward? true def + + /Tx /pop load def + /Tj /pop load def + + currentdict end clipRenderOff begin begin + } ifelse + } + { + 0 eq + { + save /discardSave exch store + } if + } ifelse +} bind def +/LB +{ + discardSave dup null ne + { + restore + } + { + pop + clipForward? + { + currentdict + end + end + begin + + /clipForward? false ddef + } if + } ifelse +} bind def +/Pb +{ + pop pop + 0 (%AI5_EndPalette) discard +} bind def +/Np +{ + 0 (%AI5_End_NonPrinting--) discard +} bind def +/Ln /pop load def +/Ap +/pop load def +/Ar +{ + 72 exch div + 0 dtransform dup mul exch dup mul add sqrt + dup 1 lt + { + pop 1 + } if + setflat +} def +/Mb +{ + q +} def +/Md +{ +} def +/MB +{ + Q +} def +/nc 4 dict def +nc begin +/setgray +{ + pop +} bind def +/setcmykcolor +{ + 4 npop +} bind def +/setrgbcolor +{ + 3 npop +} bind def +/setcustomcolor +{ + 2 npop +} bind def +currentdict readonly pop +end +end +setpacking +%%EndResource +%%BeginResource: procset Adobe_cshow 2.0 8 +%%Title: (Writing System Operators) +%%Version: 2.0 8 +%%CreationDate: (1/23/89) () +%%Copyright: ((C) 1992-1996 Adobe Systems Incorporated All Rights Reserved) +currentpacking true setpacking +userdict /Adobe_cshow 14 dict dup begin put +/initialize +{ + Adobe_cshow begin + Adobe_cshow + { + dup xcheck + { + bind + } if + pop pop + } forall + end + Adobe_cshow begin +} def +/terminate +{ +currentdict Adobe_cshow eq + { + end + } if +} def +/cforall +{ + /_lobyte 0 ddef + /_hibyte 0 ddef + /_cproc exch ddef + /_cscript currentfont /FontScript known { currentfont /FontScript get } { -1 } ifelse ddef + { + /_lobyte exch ddef + _hibyte 0 eq + _cscript 1 eq + _lobyte 129 ge _lobyte 159 le and + _lobyte 224 ge _lobyte 252 le and or and + _cscript 2 eq + _lobyte 161 ge _lobyte 254 le and and + _cscript 3 eq + _lobyte 161 ge _lobyte 254 le and and + _cscript 25 eq + _lobyte 161 ge _lobyte 254 le and and + _cscript -1 eq + or or or or and + { + /_hibyte _lobyte ddef + } + { + _hibyte 256 mul _lobyte add + _cproc + /_hibyte 0 ddef + } ifelse + } forall +} def +/cstring +{ + dup 256 lt + { + (s) dup 0 4 3 roll put + } + { + dup 256 idiv exch 256 mod + (hl) dup dup 0 6 5 roll put 1 4 3 roll put + } ifelse +} def +/clength +{ + 0 exch + { 256 lt { 1 } { 2 } ifelse add } cforall +} def +/hawidthshow +{ + { + dup cstring + show + _hvax _hvay rmoveto + _hvwb eq { _hvcx _hvcy rmoveto } if + } cforall +} def +/vawidthshow +{ + { + dup 255 le + _charorientation 1 eq + and + { + -90 rotate + 0 _fontRotateAdjust rmoveto + cstring + _hvcx _hvcy _hvwb _hvax _hvay 6 -1 roll awidthshow + 0 _fontRotateAdjust neg rmoveto + 90 rotate + } + { + currentpoint + _fontHeight sub + exch _hvay sub exch _hvax sub + 2 index _hvwb eq { exch _hvcy sub exch _hvcx sub } if + 3 2 roll + cstring + dup stringwidth pop 2 div neg _fontAscent neg rmoveto + show + moveto + } ifelse + } cforall +} def +/hvawidthshow +{ + 6 1 roll + /_hvay exch ddef + /_hvax exch ddef + /_hvwb exch ddef + /_hvcy exch ddef + /_hvcx exch ddef + _lineorientation 0 eq { hawidthshow } { vawidthshow } ifelse +} def +/hvwidthshow +{ + 0 0 3 -1 roll hvawidthshow +} def +/hvashow +{ + 0 0 0 6 -3 roll hvawidthshow +} def +/hvshow +{ + 0 0 0 0 0 6 -1 roll hvawidthshow +} def +currentdict readonly pop end +setpacking +%%EndResource +%%EndProlog +%%BeginSetup +userdict /_useSmoothShade false put +Adobe_level2_AI5 /initialize get exec +Adobe_cshow /initialize get exec +Adobe_ColorImage_AI6 /initialize get exec +Adobe_Illustrator_AI5 /initialize get exec +%AI5_Begin_NonPrinting +Np +%AI3_BeginPattern: (Bl\212tter) +(Bl\212tter) 0 0 64.0781 78.9336 [ +%AI3_Tile +(0 O 0 R 0.05 0.2 1 0 k + 0.05 0.2 1 0 K +) @ +( +%AI6_BeginPatternLayer +800 Ar +0 J 0 j 1 w 4 M []0 d +%AI3_Note: +0 D +0 XR +64.0781 78.9336 m +64.0781 0 L +0 0 L +0 78.9336 L +64.0781 78.9336 L +f +%AI6_EndPatternLayer +) & +(0 O 0 R 0.83 0 1 0 k + 0.83 0 1 0 K +) @ +( +%AI6_BeginPatternLayer +800 Ar +0 J 0 j 1 w 4 M []0 d +%AI3_Note: +1 D +0 XR +29.7578 0.9902 m +30.4346 1.1914 30.7246 1.3428 V +29.2559 4.0547 33.707 8.3359 34.627 9.0762 C +35.2275 8.8506 35.3477 6.3184 34.6699 4.9805 C +35.5137 5.1035 37.7031 3.7256 38.4609 2.4365 C +38.5254 3.125 40.0957 6.0664 40.9219 6.4434 C +40.002 6.8408 39.3359 8.3135 38.5742 9.7617 C +39.5957 9.9287 40.9961 9.0078 42.4668 8.1025 C +42.9814 8.9043 44.3555 9.875 45.6143 10.3916 C +44.5264 11.0781 44.0313 11.8203 43.5352 13.2793 C +42.4922 12.7139 40.3057 12.5645 39.7764 12.8516 C +40.291 13.9648 42.5371 14.5078 43.2676 14.4551 C +43.0137 15.3164 42.8652 17.4697 43.0391 20.0625 C +41.3789 18.7461 39.834 17.4297 38.1738 17.4883 C +38.4434 16.0664 37.8076 14.2607 37.4307 13.7676 C +36.8574 14.5117 36.4463 15.3389 36.8008 17.3164 C +35.3486 17.8008 34.1113 18.3467 32.7373 19.6045 C +32.7373 17.7734 32.166 16.5723 31.2969 15.2959 C +32.5576 14.8076 33.8301 13.6045 33.8252 12.5664 C +32.9775 12.7178 31.2852 13.4619 30.793 14.4551 C +30.0742 13.707 28.3906 12.3984 26.7871 12.3945 C +27.9746 11.5391 28.8945 10.5059 28.9893 8.5938 C +30.2422 9.5645 32.6953 10.1797 34.0752 9.582 C +29.2344 5.3457 29.7031 2.3125 29.7578 0.9902 C +f +13.8525 29.9844 m +13.3281 29.5127 13.1309 29.25 V +15.623 27.4326 13.3691 21.6074 12.8555 20.5439 C +12.2168 20.4883 10.8096 23.2285 10.8457 24.7266 C +9.7129 23.9707 8.0488 24.0918 6.4463 24.3779 C +7.0186 23.2891 6.6172 21.3447 5.8164 20.5439 C +6.8184 20.5801 8.1699 19.8652 9.4785 18.8838 C +8.6436 18.0645 6.8164 18.2246 4.9004 18.8838 C +4.9004 17.5107 4.0781 15.7734 3.2412 14.5918 C +4.5576 14.6484 5.7031 13.9629 6.5605 12.9316 C +7.2256 14.5 9.2598 15.6133 10.166 15.5645 C +10.1826 14.1992 8.6094 12.1094 7.5879 11.7109 C +8.1875 11.041 9.207 9.5107 10.166 7.0947 C +10.9648 9.0205 12.1348 10.2627 13.3672 11.1953 C +12.2256 12.7578 12.3994 13.6289 12.7988 15.1074 C +13.541 14.5664 14.5723 14.1338 14.7441 12.1309 C +16.4609 12.416 17.5957 12.3447 19.0938 11.4434 C +18.6387 13.1055 18.6348 14.707 18.9551 16.4063 C +17.1055 16.2666 15.5449 16.4795 14.5156 17.9688 C +15.3457 18.1953 17.6055 18.2549 18.4795 17.3223 C +18.8066 18.3047 19.7012 19.7109 21.1475 20.4043 C +19.707 20.6641 18.7227 21.7637 17.8135 23.4492 C +17.1006 22.0332 14.873 20.3691 13.3711 20.3145 C +15.373 24.3779 15.373 27.2959 13.8525 29.9844 C +f +41.2324 26.0742 m +41.5518 26.7021 41.7549 26.959 V +44.1523 25.0176 48.958 28.3262 49.8535 29.0957 C +49.7432 29.7266 47.6182 30.8643 45.9004 29.834 C +46.3408 31.123 45.4395 33.084 44.2402 34.126 C +45.9805 34.0254 48.126 35.3867 48.6484 36.1289 C +48.8701 35.1514 50.0527 33.8809 51.3379 32.8672 C +51.6895 33.8398 50.9941 35.958 50.0781 37.5605 C +51.3125 38.0605 52.4248 38.9912 52.8828 40.25 C +53.3398 38.9336 54.3428 38.2598 55.6875 37.5039 C +54.5273 36.0762 53.7471 33.9023 54.0273 33.0391 C +55.3496 33.374 56.9209 36.0918 57.0439 37.1816 C +57.9189 36.415 59.4727 35.7285 62.0537 35.4219 C +60.3535 34.3438 59.9902 32.3516 59.4063 30.9219 C +58.2588 31.3682 56.0898 31.4277 55.1152 30.8643 C +55.8281 30.2852 57.168 29.7344 59.1777 29.7207 C +59.1777 28.1758 59.6406 27.043 60.8945 25.8281 C +59.1719 25.8418 57.0723 25.3555 55.5762 24.9629 C +55.3281 26.292 54.4844 27.8887 53.3398 28.2891 C +53.334 27.4277 53.5996 25.1797 54.4844 24.5117 C +53.6201 23.9443 52.3672 22.5674 51.9102 20.8496 C +51.2881 22.1758 50.4268 23.4805 48.5645 23.9238 C +49.749 24.9766 50.584 26.9941 50.25 28.4609 C +45.1973 24.4785 42.5215 25.7773 41.2324 26.0742 C +f +27.7578 38.7324 m +28.4346 38.9316 28.7246 39.084 V +27.2559 41.7969 31.707 46.0776 32.627 46.8169 C +33.2275 46.5918 33.3477 44.0586 32.6699 42.7227 C +33.5137 42.8457 35.7031 41.4678 36.4609 40.1787 C +36.5254 40.8652 38.0957 43.8066 38.9219 44.1846 C +38.002 44.582 37.3359 46.0547 36.5742 47.5039 C +37.5957 47.6709 38.9961 46.7485 40.4668 45.8438 C +40.9814 46.6445 42.3555 47.6177 43.6143 48.1328 C +42.5264 48.8198 42.0313 49.5615 41.5352 51.0205 C +40.4922 50.4556 38.3057 50.3057 37.7764 50.5938 C +38.291 51.7056 40.5371 52.2485 41.2676 52.1958 C +41.0137 53.0576 40.8652 55.2109 41.0391 57.8037 C +39.3789 56.4878 37.834 55.1719 36.1738 55.2285 C +36.4434 53.8076 35.8076 52.002 35.4307 51.5088 C +34.8574 52.2529 34.4463 53.0796 34.8008 55.0576 C +33.3486 55.5425 32.1113 56.0879 30.7373 57.3467 C +30.7373 55.5146 30.166 54.314 29.2969 53.0366 C +30.5576 52.5488 31.8301 51.3467 31.8252 50.3076 C +30.9775 50.46 29.2852 51.2036 28.793 52.1958 C +28.0742 51.4497 26.3906 50.1396 24.7871 50.1357 C +25.9746 49.2817 26.8945 48.2466 26.9893 46.335 C +28.2422 47.3057 30.6953 47.9209 32.0752 47.3237 C +27.2344 43.0869 27.7031 40.0547 27.7578 38.7324 C +f +13.5195 70.3916 m +12.9941 69.9209 12.7988 69.6587 V +15.2891 67.8418 13.0352 62.0146 12.5225 60.9517 C +11.8828 60.8955 10.4766 63.6367 10.5117 65.1348 C +9.3809 64.3789 7.7148 64.4995 6.1133 64.7856 C +6.6855 63.6987 6.2842 61.7529 5.4834 60.9517 C +6.4854 60.9878 7.8359 60.2729 9.1455 59.2925 C +8.3105 58.4717 6.4834 58.6338 4.5674 59.2925 C +4.5674 57.9189 3.7461 56.1816 2.9082 54.9995 C +4.2246 55.0576 5.3691 54.3706 6.2275 53.3408 C +6.8926 54.9097 8.9258 56.0215 9.832 55.9727 C +9.8496 54.6079 8.2764 52.5176 7.2539 52.1187 C +7.8545 51.4497 8.873 49.9189 9.832 47.5039 C +10.6309 49.4297 11.8008 50.6719 13.0342 51.6045 C +11.8926 53.1655 12.0664 54.0366 12.4648 55.5146 C +13.209 54.9746 14.2393 54.5415 14.4102 52.5386 C +16.127 52.8247 17.2637 52.7529 18.7598 51.8525 C +18.3057 53.5137 18.3027 55.1147 18.623 56.8149 C +16.7725 56.6748 15.2129 56.8887 14.1826 58.377 C +15.0117 58.6035 17.2725 58.6626 18.1465 57.731 C +18.4736 58.7129 19.3691 60.1187 20.8145 60.8125 C +19.375 61.0728 18.3896 62.1719 17.4805 63.8579 C +16.7676 62.4429 14.541 60.7769 13.0371 60.7227 C +15.041 64.7856 15.041 67.7046 13.5195 70.3916 C +f +41.2324 64.4824 m +41.5518 65.1113 41.7549 65.3682 V +44.1523 63.4272 48.958 66.7354 49.8535 67.5034 C +49.7432 68.1362 47.6182 69.2725 45.9004 68.2422 C +46.3408 69.5313 45.4395 71.4922 44.2402 72.5342 C +45.9805 72.4341 48.126 73.7954 48.6484 74.5371 C +48.8701 73.5601 50.0527 72.29 51.3379 71.2754 C +51.6895 72.249 50.9941 74.3662 50.0781 75.9683 C +51.3125 76.4692 52.4248 77.3994 52.8828 78.6582 C +53.3398 77.3423 54.3428 76.667 55.6875 75.9111 C +54.5273 74.4844 53.7471 72.3101 54.0273 71.4473 C +55.3496 71.7822 56.9209 74.5 57.0439 75.5903 C +57.9189 74.8232 59.4727 74.1372 62.0537 73.8311 C +60.3535 72.7534 59.9902 70.7612 59.4063 69.3301 C +58.2588 69.7773 56.0898 69.8364 55.1152 69.2725 C +55.8281 68.6934 57.168 68.1431 59.1777 68.1284 C +59.1777 66.583 59.6406 65.4512 60.8945 64.2373 C +59.1719 64.249 57.0723 63.7632 55.5762 63.3721 C +55.3281 64.7002 54.4844 66.2974 53.3398 66.6973 C +53.334 65.8364 53.5996 63.5874 54.4844 62.9214 C +53.6201 62.353 52.3672 60.9751 51.9102 59.2583 C +51.2881 60.583 50.4268 61.8882 48.5645 62.333 C +49.749 63.3862 50.584 65.4033 50.25 66.8691 C +45.1973 62.8872 42.5215 64.1851 41.2324 64.4824 C +f +%AI6_EndPatternLayer +) & +] E +%AI3_EndPattern +%AI3_BeginPattern: (Konfetti) +(Konfetti) 4.85 3.617 76.85 75.617 [ +%AI3_Tile +(0 O 0 R 1 g + 1 G +) @ +( +%AI6_BeginPatternLayer +800 Ar +0 J 0 j 1 w 4 M []0 d +%AI3_Note: +0 D +0 XR +4.85 3.617 m +4.85 75.617 L +76.85 75.617 L +76.85 3.617 L +4.85 3.617 L +f +%AI6_EndPatternLayer +) & +(0 O 0 R 0 g + 0 G +) @ +( +%AI6_BeginPatternLayer +800 Ar +0 J 0 j 0.3 w 4 M []0 d +%AI3_Note: +0 D +0 XR +10.6 64.867 m +7.85 62.867 l +S +9.1 8.617 m +6.85 6.867 l +S +78.1 68.617 m +74.85 67.867 l +S +76.85 56.867 m +74.35 55.117 l +S +79.6 51.617 m +76.6 51.617 l +S +76.35 44.117 m +73.6 45.867 l +S +78.6 35.867 m +76.6 34.367 l +S +76.1 23.867 m +73.35 26.117 l +S +78.1 12.867 m +73.85 13.617 l +S +68.35 14.617 m +66.1 12.867 l +S +76.6 30.617 m +73.6 30.617 l +S +62.85 58.117 m +60.956 60.941 l +S +32.85 59.617 m +31.196 62.181 l +S +47.891 64.061 m +49.744 66.742 l +S +72.814 2.769 m +73.928 5.729 l +S +67.976 2.633 m +67.35 5.909 l +S +61.85 27.617 m +59.956 30.441 l +S +53.504 56.053 m +51.85 58.617 l +S +52.762 1.779 m +52.876 4.776 l +S +45.391 5.311 m +47.244 7.992 l +S +37.062 3.375 m +35.639 5.43 l +S +55.165 34.828 m +57.518 37.491 l +S +20.795 3.242 m +22.12 5.193 l +S +14.097 4.747 m +15.008 8.965 l +S +9.736 1.91 m +8.073 4.225 l +S +31.891 5.573 m +32.005 8.571 l +S +12.1 70.367 m +15.6 68.867 l +S +9.35 54.867 m +9.6 58.117 l +S +12.85 31.867 m +14.35 28.117 l +S +10.1 37.367 m +12.35 41.117 l +S +34.1 71.117 m +31.85 68.617 l +S +38.35 71.117 m +41.6 68.367 l +S +55.1 71.117 m +58.35 69.117 l +S +57.35 65.117 m +55.35 61.867 l +S +64.35 66.367 m +69.35 68.617 l +S +71.85 62.867 m +69.35 61.117 l +S +23.6 70.867 m +23.6 67.867 l +S +20.6 65.867 m +17.35 65.367 l +S +24.85 61.367 m +25.35 58.117 l +S +25.85 65.867 m +29.35 66.617 l +S +14.1 54.117 m +16.85 56.117 l +S +12.35 11.617 m +12.6 15.617 l +S +12.1 19.867 m +14.35 22.367 l +S +26.1 9.867 m +23.6 13.367 l +S +34.6 47.117 m +32.1 45.367 l +S +62.6 41.867 m +59.85 43.367 l +S +31.6 35.617 m +27.85 36.367 l +S +36.35 26.117 m +34.35 24.617 l +S +33.85 14.117 m +31.1 16.367 l +S +37.1 9.867 m +35.1 11.117 l +S +34.35 20.867 m +31.35 20.867 l +S +44.6 56.617 m +42.1 54.867 l +S +47.35 51.367 m +44.35 51.367 l +S +44.1 43.867 m +41.35 45.617 l +S +43.35 33.117 m +42.6 30.617 l +S +43.85 23.617 m +41.1 25.867 l +S +44.35 15.617 m +42.35 16.867 l +S +67.823 31.1 m +64.823 31.1 l +S +27.1 32.617 m +29.6 30.867 l +S +31.85 55.117 m +34.85 55.117 l +S +19.6 40.867 m +22.1 39.117 l +S +16.85 35.617 m +19.85 35.617 l +S +20.1 28.117 m +22.85 29.867 l +S +52.1 42.617 m +54.484 44.178 l +S +52.437 50.146 m +54.821 48.325 l +S +59.572 54.133 m +59.35 51.117 l +S +50.185 10.055 m +53.234 9.928 l +S +51.187 15.896 m +53.571 14.075 l +S +58.322 19.883 m +59.445 16.823 l +S +53.1 32.117 m +50.6 30.367 l +S +52.85 24.617 m +49.6 25.617 l +S +61.85 9.117 m +59.1 10.867 l +S +69.35 34.617 m +66.6 36.367 l +S +67.1 23.617 m +65.1 22.117 l +S +24.435 46.055 m +27.484 45.928 l +S +25.437 51.896 m +27.821 50.075 l +S +62.6 47.117 m +65.321 46.575 l +S +19.85 19.867 m +20.35 16.617 l +S +21.85 21.867 m +25.35 22.617 l +S +37.6 62.867 m +41.6 62.117 l +S +38.323 42.1 m +38.823 38.6 l +S +69.35 52.617 m +66.85 53.867 l +S +14.85 62.117 m +18.1 59.367 l +S +9.6 46.117 m +7.1 44.367 l +S +20.6 51.617 m +18.6 50.117 l +S +46.141 70.811 m +47.994 73.492 l +S +69.391 40.561 m +71.244 43.242 l +S +38.641 49.311 m +39.35 52.117 l +S +25.141 16.811 m +25.85 19.617 l +S +36.6 32.867 m +34.6 31.367 l +S +6.1 68.617 m +2.85 67.867 l +S +4.85 56.867 m +2.35 55.117 l +S +7.6 51.617 m +4.6 51.617 l +S +6.6 35.867 m +4.6 34.367 l +S +6.1 12.867 m +1.85 13.617 l +S +4.6 30.617 m +1.6 30.617 l +S +72.814 74.769 m +73.928 77.729 l +S +67.976 74.633 m +67.35 77.909 l +S +52.762 73.779 m +52.876 76.776 l +S +37.062 75.375 m +35.639 77.43 l +S +20.795 75.242 m +22.12 77.193 l +S +9.736 73.91 m +8.073 76.225 l +S +10.1 23.617 m +6.35 24.367 l +S +73.217 18.276 m +71.323 21.1 l +S +28.823 39.6 m +29.505 42.389 l +S +49.6 38.617 m +47.6 37.117 l +S +60.323 73.6 m +62.323 76.6 l +S +60.323 1.6 m +62.323 4.6 l +S +%AI6_EndPatternLayer +) & +] E +%AI3_EndPattern +%AI3_BeginPattern: (Streifen) +(Streifen) 8.45 4.6001 80.45 76.6001 [ +%AI3_Tile +(0 O 0 R 1 0.07 1 0 k + 1 0.07 1 0 K +) @ +( +%AI6_BeginPatternLayer +800 Ar +0 J 0 j 3.6 w 4 M []0 d +%AI3_Note: +0 D +0 XR +8.2 8.2 m +80.7 8.2 L +S +8.2 22.6001 m +80.7 22.6001 L +S +8.2 37.0002 m +80.7 37.0002 L +S +8.2 51.4 m +80.7 51.4 L +S +8.2 65.8001 m +80.7 65.8001 L +S +8.2 15.4 m +80.7 15.4 L +S +8.2 29.8001 m +80.7 29.8001 L +S +8.2 44.2 m +80.7 44.2 L +S +8.2 58.6001 m +80.7 58.6001 L +S +8.2 73.0002 m +80.7 73.0002 L +S +%AI6_EndPatternLayer +) & +] E +%AI3_EndPattern +%AI3_BeginPattern: (Ziegel) +(Ziegel) 0 0 72 72 [ +%AI3_Tile +(0 O 0 R 0.3 0.85 0.85 0 k + 0.3 0.85 0.85 0 K +) @ +( +%AI6_BeginPatternLayer +800 Ar +0 J 0 j 1 w 4 M []0 d +%AI3_Note: +0 D +0 XR +0 0 m +0 72 L +72 72 L +72 0 L +0 0 L +f +%AI6_EndPatternLayer +) & +(0 O 0 R 1 g + 1 G +) @ +( +%AI6_BeginPatternLayer +800 Ar +0 J 0 j 0.3 w 4 M []0 d +%AI3_Note: +0 D +0 XR +0 68.4097 m +72 68.4097 l +S +0 61.209 m +72 61.209 L +S +0 54.0088 m +72 54.0088 L +S +0 46.8076 m +72 46.8076 L +S +0 39.6084 m +72 39.6084 L +S +0 32.4072 m +72 32.4072 L +S +0 25.207 m +72 25.207 L +S +0 18.0059 m +72 18.0059 L +S +0 10.8057 m +72 10.8057 L +S +0 3.6064 m +72 3.6064 L +S +68.4102 68.4097 m +68.4102 61.2217 l +S +54.0098 68.4097 m +54.0098 61.2217 L +S +39.6094 68.4097 m +39.6094 61.2217 L +S +25.21 68.4097 m +25.21 61.2217 L +S +10.8105 68.4097 m +10.8105 61.2217 L +S +68.4102 53.9717 m +68.4102 46.7842 l +S +54.0098 53.9717 m +54.0098 46.7842 L +S +39.6094 53.9717 m +39.6094 46.7842 L +S +25.21 53.9717 m +25.21 46.7842 L +S +10.8105 53.9717 m +10.8105 46.7842 L +S +68.4102 39.5967 m +68.4102 32.4092 l +S +54.0098 39.5967 m +54.0098 32.4092 L +S +39.6094 39.5967 m +39.6094 32.4092 L +S +25.21 39.5967 m +25.21 32.4092 L +S +10.8105 39.5967 m +10.8105 32.4092 L +S +68.4102 25.2217 m +68.4102 18.0342 l +S +54.0098 25.2217 m +54.0098 18.0342 L +S +39.6094 25.2217 m +39.6094 18.0342 L +S +25.21 25.2217 m +25.21 18.0342 L +S +10.8105 25.2217 m +10.8105 18.0342 L +S +68.4102 10.7842 m +68.4102 3.5967 l +S +54.0098 10.7842 m +54.0098 3.5967 L +S +39.6094 10.7842 m +39.6094 3.5967 L +S +25.21 10.7842 m +25.21 3.5967 L +S +10.8105 10.7842 m +10.8105 3.5967 L +S +61.1973 3.5967 m +61.1973 0 L +S +46.7969 3.5967 m +46.7969 0 L +S +32.3965 3.5967 m +32.3965 0 L +S +17.9971 3.5967 m +17.9971 0 L +S +3.5967 3.5967 m +3.5967 0 l +S +61.1973 18.0342 m +61.1973 10.8467 L +S +46.7969 18.0342 m +46.7969 10.8467 L +S +32.3965 18.0342 m +32.3965 10.8467 L +S +17.9971 18.0342 m +17.9971 10.8467 L +S +3.5967 18.0342 m +3.5967 10.8467 l +S +61.1973 32.4092 m +61.1973 25.2217 L +S +46.7969 32.4092 m +46.7969 25.2217 L +S +17.9971 32.4092 m +17.9971 25.2217 L +S +3.5967 32.4092 m +3.5967 25.2217 l +S +61.1973 46.7842 m +61.1973 39.5967 L +S +46.7969 46.7842 m +46.7969 39.5967 L +S +32.3965 46.7842 m +32.3965 39.5967 L +S +17.9971 46.7842 m +17.9971 39.5967 L +S +3.5967 46.7842 m +3.5967 39.5967 l +S +61.1973 61.2217 m +61.1973 54.0347 L +S +46.7969 61.2217 m +46.7969 54.0347 L +S +32.3965 61.2217 m +32.3965 54.0347 L +S +17.9971 61.2217 m +17.9971 54.0347 L +S +3.5967 61.2217 m +3.5967 54.0347 l +S +61.1973 71.959 m +61.1973 68.4717 L +S +46.7969 71.959 m +46.7969 68.4717 L +S +32.3965 71.959 m +32.3965 68.4717 L +S +17.9971 71.959 m +17.9971 68.4717 L +S +3.5967 71.959 m +3.5967 68.4717 l +S +32.3965 32.4092 m +32.3965 25.2217 L +S +%AI6_EndPatternLayer +) & +] E +%AI3_EndPattern +%AI5_End_NonPrinting-- +%AI5_Begin_NonPrinting +Np +4 Bn +%AI5_BeginGradient: (Chrom) +(Chrom) 0 6 Bd +[ +0 +< +464646454545444444444343434342424241414141404040403F3F3F3E3E3E3E3D3D3D3C3C3C3C3B +3B3B3B3A3A3A39393939383838383737373636363635353535343434333333333232323131313130 +3030302F2F2F2E2E2E2E2D2D2D2D2C2C2C2B2B2B2B2A2A2A2A292929282828282727272626262625 +2525252424242323232322222222212121202020201F1F1F1F1E1E1E1D1D1D1D1C1C1C1B1B1B1B1A +1A1A1A1919191818181817171717161616151515151414141413131312121212111111101010100F +0F0F0F0E0E0E0D0D0D0D0C0C0C0C0B0B0B0A0A0A0A09090909080808070707070606060505050504 +04040403030302020202010101010000 +> +< +FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8 +D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0 +AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988 +87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160 +5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938 +37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110 +0F0E0D0C0B0A09080706050403020100 +> +< +1F1E1E1E1E1E1E1E1E1E1D1D1D1D1D1D1D1D1C1C1C1C1C1C1C1C1B1B1B1B1B1B1B1B1B1A1A1A1A1A +1A1A1A19191919191919191818181818181818181717171717171717161616161616161615151515 +15151515151414141414141414131313131313131312121212121212121211111111111111111010 +1010101010100F0F0F0F0F0F0F0F0F0E0E0E0E0E0E0E0E0D0D0D0D0D0D0D0D0C0C0C0C0C0C0C0C0C +0B0B0B0B0B0B0B0B0A0A0A0A0A0A0A0A090909090909090909080808080808080807070707070707 +07060606060606060606050505050505050504040404040404040303030303030303030202020202 +02020201010101010101010000000000 +> +1 %_Br +0 +0.275 +1 +< +6B6A696867666564636261605F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544 +434241403F3E3D3C3B3A393837363534333231302F2E2D2C2B2A292827262524232221201F +> +1 %_Br +0 +< +00000101010102020202030303040404040505050506060607070707080808090909090A0A0A0A0B +0B0B0C0C0C0C0D0D0D0D0E0E0E0F0F0F0F1010101011111112121212131313141414141515151516 +161617171717181818181919191A1A1A1A1B1B1B1C1C1C1C1D1D1D1D1E1E1E1F1F1F1F2020202021 +212122222222232323232424242525252526262626272727282828282929292A2A2A2A2B2B2B2B2C +2C2C2D2D2D2D2E2E2E2E2F2F2F303030303131313132323233333333343434353535353636363637 +373738383838393939393A3A3A3B3B3B3B3C3C3C3D3D3D3D3E3E3E3E3F3F3F404040404141414142 +42424343434344444444454545464646 +> +< +000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627 +28292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071727374757677 +78797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F +A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7 +C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF +F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF +> +< +00000101020203030304040505050606070708080809090A0A0B0B0B0C0C0D0D0D0E0E0F0F101010 +1111121212131314141515151616171718181819191A1A1A1B1B1C1C1D1D1D1E1E1F1F1F20202121 +222222232324242525252626272727282829292A2A2A2B2B2C2C2D2D2D2E2E2F2F2F303031313232 +32333334343435353636373737383839393A3A3A3B3B3C3C3C3D3D3E3E3F3F3F4040414142424243 +434444444545464647474748484949494A4A4B4B4C4C4C4D4D4E4E4F4F4F50505151515252535354 +54545555565657575758585959595A5A5B5B5C5C5C5D5D5E5E5E5F5F606061616162626363646464 +6565666666676768686969696A6A6B6B +> +1 %_Br +1 +0 %_Br +< +FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8 +D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0 +AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988 +87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160 +5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938 +37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110 +0F0E0D0C0B0A09080706050403020100 +> +< +4D4C4C4C4B4B4B4A4A4A4A4949494848484747474746464645454544444444434343424242414141 +414040403F3F3F3E3E3E3E3D3D3D3C3C3C3B3B3B3B3A3A3A39393938383838373737363636353535 +35343434333333323232323131313030302F2F2F2E2E2E2E2D2D2D2C2C2C2B2B2B2B2A2A2A292929 +282828282727272626262525252524242423232322222222212121202020201F1F1F1E1E1E1D1D1D +1D1C1C1C1B1B1B1A1A1A1A1919191818181717171616161615151514141413131313121212111111 +101010100F0F0F0E0E0E0D0D0D0D0C0C0C0B0B0B0A0A0A0A09090908080807070707060606050505 +04040404030303020202010101010000 +> +0 +0 +1 %_Br +[ +1 0 50 92 %_Bs +0 0.275 1 0.12 1 50 59 %_Bs +0 0.275 1 0.42 1 50 50 %_Bs +1 0 50 49 %_Bs +1 0 50 41 %_Bs +1 0.3 0 0 1 50 0 %_Bs +BD +%AI5_EndGradient +%AI5_BeginGradient: (Gelb, Orange-Radial) +(Gelb, Orange-Radial) 1 2 Bd +[ +0 +< +0001010203040506060708090A0B0C0C0D0E0F10111213131415161718191A1B1C1D1D1E1F202122 +232425262728292A2B2B2C2D2E2F303132333435363738393A3B3C3D3E3E3F404142434445464748 +494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F60606162636465666768696A6B6C6D6E6F +707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C +> +< +FFFFFFFFFEFEFEFEFEFEFEFDFDFDFDFDFDFCFCFCFCFCFCFBFBFBFBFBFBFAFAFAFAFAFAF9F9F9F9F9 +F9F8F8F8F8F8F8F7F7F7F7F7F7F6F6F6F6F6F6F5F5F5F5F5F5F4F4F4F4F4F3F3F3F3F3F3F2F2F2F2 +F2F2F1F1F1F1F1F0F0F0F0F0F0EFEFEFEFEFEFEEEEEEEEEEEDEDEDEDEDEDECECECECECEBEBEBEBEB +EBEAEAEAEAEAE9E9E9E9E9E9E8E8E8E8E8E8E7E7E7E7E7E6E6E6E6E6E6 +> +0 +1 %_Br +[ +0 0 1 0 1 52 19 %_Bs +0 0.55 0.9 0 1 50 100 %_Bs +BD +%AI5_EndGradient +%AI5_BeginGradient: (Regenbogen) +(Regenbogen) 0 6 Bd +[ +< +FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8 +D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0 +AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988 +87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160 +5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938 +37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110 +0F0E0D0C0B0A09080706050403020100 +> +1 +0 +0 +1 %_Br +1 +< +0708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E +2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F50515253545556 +5758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E +7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6 +A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCE +CFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6 +F7F8F9FAFBFCFDFEFF +> +0 +0 +1 %_Br +1 +< +00000000000000000000000000000000000001010101010101010101010101010101010101010101 +01010101010101010101010101010202020202020202020202020202020202020202020202020202 +02020202020202020202030303030303030303030303030303030303030303030303030303030303 +03030303030304040404040404040404040404040404040404040404040404040404040404040404 +04040505050505050505050505050505050505050505050505050505050505050505050505050606 +06060606060606060606060606060606060606060606060606060606060606060607070707070707 +07070707070707070707070707070707 +> +< +FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8 +D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0 +AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988 +87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160 +5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938 +37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110 +0F0E0D0C0B0A09080706050403020100 +> +0 +1 %_Br +< +000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627 +28292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071727374757677 +78797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F +A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7 +C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF +F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF +> +0 +1 +0 +1 %_Br +0 +< +FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8 +D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0 +AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988 +87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160 +5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938 +37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110 +0F0E0D0C0B0A09080706050403020100 +> +1 +0 +1 %_Br +[ +0 1 0 0 1 50 100 %_Bs +1 1 0 0 1 50 80 %_Bs +1 0.0279 0 0 1 50 60 %_Bs +1 0 1 0 1 50 40 %_Bs +0 0 1 0 1 50 20 %_Bs +0 1 1 0 1 50 0 %_Bs +BD +%AI5_EndGradient +%AI5_BeginGradient: (Schwarz, Wei\247) +(Schwarz, Wei\247) 0 2 Bd +[ +< +FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8 +D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0 +AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988 +87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160 +5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938 +37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110 +0F0E0D0C0B0A09080706050403020100 +> +0 %_Br +[ +0 0 50 100 %_Bs +1 0 50 0 %_Bs +BD +%AI5_EndGradient +%AI5_End_NonPrinting-- +%AI5_BeginPalette +0 0 Pb +1 1 1 1 k +([Passermarken]) Pc +0 0 0 1 k +([Passermarken]) Pc +0 0 0 0 k +(C=0 M=0 Y=0 K=0 Kopie) Pc +0 0 0 0.2 k +(0-0-0-20 Kopie) Pc +0 0 0 0.4 k +(0-0-0-40 Kopie) Pc +0 0 0 0.6 k +(0-0-0-60 Kopie) Pc +0 0 0 0.8 k +(0-0-0-80 Kopie) Pc +0 0 0 1 k +(C=0 M=0 Y=0 K=100 Kopie) Pc +0 0 1 0 k +(0-0-100-0 Kopie) Pc +0 0.2 1 0 k +(0-20-100-0 Kopie) Pc +0 0.4 1 0 k +(0-40-100-0 Kopie) Pc +0 0.6 1 0 k +(0-60-100-0 Kopie) Pc +0 0.8 1 0 k +(0-80-100-0 Kopie) Pc +0 1 1 0 k +(0-100-100-0 Kopie) Pc +0 1 1 0.2 k +(0-100-100-20 Kopie) Pc +0 1 1 0.4 k +(0-100-100-40 Kopie) Pc +0 1 1 0.6 k +(0-100-100-60 Kopie) Pc +0 1 1 0.8 k +(0-100-100-80 Kopie) Pc +0 0.5 0 0 k +(0-50-0-0 Kopie) Pc +0 1 0 0 k +(0-100-0-0 Kopie) Pc +0.2 1 0 0 k +(20-100-0-0 Kopie) Pc +0.4 1 0 0 k +(40-100-0-0 Kopie) Pc +0.6 1 0 0 k +(60-100-0-0 Kopie) Pc +0.8 1 0 0 k +(80-100-0-0 Kopie) Pc +1 1 0 0 k +(100-100-0-0 Kopie) Pc +1 0.8 0 0 k +(100-80-0-0 Kopie) Pc +1 0.6 0 0 k +(100-60-0-0 Kopie) Pc +1 0.4 0 0 k +(100-40-0-0 Kopie) Pc +1 0.2 0 0 k +(100-20-0-0 Kopie) Pc +1 0 0 0 k +(100-0-0-0 Kopie) Pc +1 0 1 0 k +(100-0-100-0 Kopie) Pc +1 0 0.8 0 k +(100-0-80-0 Kopie) Pc +1 0 0.6 0 k +(100-0-60-0 Kopie) Pc +1 0 0.4 0 k +(100-0-40-0 Kopie) Pc +1 0 0.2 0 k +(100-0-20-0 Kopie) Pc +Bb +2 (Schwarz, Wei\247) -4023.5 4739.5 0 0 1 0 0 1 0 0 Bg +0 BB +(Schwarz, Wei\247) Pc +Bb +2 (Chrom) -4023.5 4739.5 0 0 1 0 0 1 0 0 Bg +0 BB +(Chrom) Pc +Bb +2 (Regenbogen) -4023.5 4739.5 0 0 1 0 0 1 0 0 Bg +0 BB +(Regenbogen) Pc +Bb +0 0 0 0 Bh +2 (Gelb, Orange-Radial) -4023.5 4739.5 0 0 1 0 0 1 0 0 Bg +0 BB +(Gelb, Orange-Radial) Pc +(Ziegel) 0 0 1 1 0 0 0 0 0 [1 0 0 1 0 0] p +(Ziegel) Pc +(Konfetti) 0 0 1 1 0 0 0 0 0 [1 0 0 1 0 0] p +(Konfetti) Pc +(Bl\212tter) 0 0 1 1 0 0 0 0 0 [1 0 0 1 0 0] p +(Bl\212tter) Pc +(Streifen) 0 0 1 1 0 0 0 0 0 [1 0 0 1 0 0] p +(Streifen) Pc +PB +%AI5_EndPalette +%%EndSetup +%AI5_BeginLayer +1 1 1 1 0 0 0 79 128 255 Lb +(Ebene 1) Ln +0 A +u +u +0 O +0 1 1 0 k +800 Ar +0 J 0 j 1 w 4 M []0 d +%AI3_Note: +0 D +0 XR +257.6328 402.0234 m +258.3594 404.3613 258.7319 407.4629 258.7593 411.2148 C +258.0337 411.2148 254.2314 411.2148 Y +250.3223 411.1855 247.0942 410.7734 244.6396 409.9922 c +241.2041 408.873 239.5215 406.5918 239.4956 403.0254 c +239.5215 400.6309 240.3389 398.8906 241.9937 397.7051 c +243.6646 396.5078 245.6904 395.9141 248.0195 395.9395 c +250.4595 395.9395 252.4316 396.3984 253.9873 397.2949 c +254.1299 397.3809 254.2749 397.4609 254.416 397.5488 c +255.9351 398.5586 257.0068 400.0391 257.6328 402.0234 c +f +312.0674 469.5464 m +312.0674 470.9575 312.0674 479.1089 Y +311.2168 479.1089 L +306.8037 479.1089 L +306.8037 470.9575 306.8037 469.5464 V +305.3926 469.5464 297.2451 469.5464 Y +297.2451 469.4966 L +295.9775 477.1841 291.7412 484.3765 284.8545 489.1987 c +274.2344 496.6357 260.4712 496.2334 250.4307 489.2056 C +250.4653 489.2056 250.4976 489.2104 250.5327 489.2104 c +256.6919 489.1509 261.3081 487.4976 264.2534 484.2964 c +265.9233 482.4839 267.022 480.3208 267.5239 477.8433 C +268.1069 473.8608 L +259.2446 473.8608 L +259.1934 474.2271 L +258.4194 479.811 255.3755 482.5532 249.8882 482.6099 c +248.2383 482.6099 246.6787 482.3169 245.2505 481.7378 c +243.0776 480.8745 241.563 479.5356 240.6313 477.6792 c +240.5552 477.5229 240.4785 477.3677 240.4053 477.2104 c +240.2939 476.9507 240.189 476.686 240.0986 476.4077 c +239.1475 473.6616 238.665 470.687 238.665 467.5669 c +238.665 462.2417 239.2422 458.3423 240.3818 455.9751 c +242.1797 452.1812 245.2227 450.3774 249.6929 450.4604 c +254.7617 450.4604 257.7715 452.2378 258.8979 455.9077 c +259.229 456.8745 259.4966 458.1138 259.6934 459.5913 C +259.7422 459.9604 L +268.605 459.9604 L +268.5356 459.4751 L +268.0986 456.4194 267.6001 454.2485 267.0112 452.8374 c +266.1563 450.7788 264.7139 448.9937 262.7227 447.5298 c +259.3848 445.0952 255.0283 443.8608 249.7749 443.8608 c +243.0879 443.8608 237.9868 445.9468 234.6128 450.062 c +233.4941 451.438 232.5806 452.9995 231.8516 454.7212 C +230.0942 452.8315 228.1509 451.3892 226.3052 450.4321 C +225.6938 450.1606 225.0913 449.8687 224.4985 449.5552 c +220.5317 447.6011 217.0737 444.5269 214.2974 440.7144 c +214.1841 440.5601 214.064 440.4136 213.9536 440.2554 C +213.9458 440.2456 213.9399 440.2339 213.9321 440.2241 C +213.9292 440.2183 213.9233 440.2144 213.9204 440.2085 C +204.4146 426.6333 207.7134 407.9219 221.2886 398.416 c +225.3662 395.5605 229.9072 393.8691 234.5229 393.2559 C +234.3853 393.3887 234.2378 393.5117 234.1084 393.6523 C +233.0698 394.6602 232.2593 395.9043 231.7065 397.334 C +231.0005 398.9434 230.6436 400.6836 230.6436 402.4961 c +230.6436 402.5703 230.644 402.6426 230.645 402.7168 c +230.644 402.7949 230.6431 402.8711 230.6431 402.9492 c +230.6431 404.627 230.9551 406.2578 231.5723 407.8008 c +232.2188 409.416 233.229 410.918 234.5713 412.2598 c +236.1484 413.8672 237.8276 414.9941 239.5605 415.6113 c +243.29 416.9609 247.9546 417.6602 253.4258 417.6895 C +258.04 417.6895 258.77 417.6895 V +258.7661 421.6636 258.3462 424.2632 257.5205 425.4077 c +256.2358 427.1597 253.7344 428.062 250.0928 428.0903 c +247.543 428.062 245.561 427.6411 244.2021 426.8403 c +242.8926 426.0679 242.022 424.3804 241.6152 421.8237 C +241.5581 421.4653 L +232.7188 421.4653 L +232.7729 421.939 L +233.0933 424.7397 233.5122 426.6587 234.0527 427.8062 c +234.8862 429.5737 236.3135 431.0454 238.2954 432.1772 c +241.1714 433.8149 245.0889 434.6606 249.9438 434.6899 c +255.3135 434.6606 259.4399 433.73 262.2061 431.9263 c +265.5728 429.7671 267.3105 426.0327 267.3706 420.8198 C +267.3706 414.4531 L +267.9165 416.2637 268.2632 418.1074 268.3857 419.9644 c +268.7451 425.4331 272.2939 433.2417 280.3525 437.4097 C +284.9521 439.5591 289.0713 442.8999 292.1924 447.3589 C +292.2002 447.3687 292.2061 447.3794 292.2119 447.3901 C +292.2158 447.394 292.2217 447.3999 292.2236 447.4058 C +295.8262 452.5522 297.5859 458.4351 297.6465 464.2749 C +297.1631 464.2749 289.0625 464.2749 287.6523 464.2749 C +287.6523 462.8638 287.6523 454.7124 Y +282.3892 454.7124 L +282.3892 462.8638 282.3892 464.2749 V +280.9775 464.2749 272.8267 464.2749 Y +272.8267 469.5386 L +280.9775 469.5386 282.3892 469.5386 V +282.3892 470.9497 282.3892 479.1011 Y +286.8027 479.1011 L +287.6523 479.1011 L +287.6523 470.9497 287.6523 469.5386 V +289.0645 469.5386 297.2148 469.5386 Y +297.7207 466.8696 297.6514 464.2827 V +299.3047 464.2827 305.5811 464.2827 306.8037 464.2827 C +306.8037 462.8716 306.8037 454.7202 Y +312.0674 454.7202 L +312.0674 462.8716 312.0674 464.2827 V +313.4785 464.2827 321.6299 464.2827 Y +321.6299 469.5464 L +313.4785 469.5464 312.0674 469.5464 V +f +U +u +0 0 0 0.4 k +293.3037 416.209 m +293.3008 416.209 290.0479 417.2559 Y +287.5449 417.8848 285.6484 418.418 284.4058 418.8379 C +283.2568 419.2769 282.7344 419.9937 282.7764 421.0884 C +282.7349 422.0825 283.2275 422.8276 284.2822 423.4019 c +284.9775 423.7739 286.0098 423.979 287.3496 424.0112 c +289.9414 424.0112 291.2988 422.8706 291.4902 420.5269 C +291.5215 420.1362 L +296.9824 420.1362 L +296.9639 420.5796 L +296.8955 422.1616 296.6816 423.3032 296.3105 424.0698 c +295.835 425.0415 294.9922 425.9116 293.8047 426.6567 c +292.1748 427.6636 289.8936 428.1733 287.0225 428.1733 c +285.248 428.1733 283.5664 427.8667 282.0234 427.2622 c +280.666 426.729 279.5259 425.8618 278.6348 424.6851 c +277.7324 423.4937 277.2837 422.1235 277.3013 420.6118 c +277.3013 418.7266 277.8618 417.2012 278.9668 416.0781 c +279.7866 415.2031 281.2354 414.4824 283.3882 413.8848 C +283.3896 413.8848 288.042 412.6328 Y +288.0361 412.6348 290.5898 411.791 Y +291.623 411.3301 292.127 410.6035 292.1133 409.5723 c +292.0547 407.2324 290.3662 406.0781 286.9512 406.0488 c +283.9048 406.0332 282.3135 407.418 282.0879 410.2813 C +282.0571 410.6738 L +276.583 410.6738 L +276.6147 410.2188 L +276.8013 407.5391 277.5054 405.6074 278.7065 404.4766 c +280.4707 402.7266 283.3896 401.8535 287.375 401.8867 c +290.2676 401.8535 292.6016 402.4492 294.3008 403.6563 c +296.4824 405.2031 297.5898 407.3398 297.5898 410.0059 c +297.5371 412.9961 296.0957 415.0801 293.3037 416.209 C +f +*u +1 D +318.4785 427.3315 m +317.1396 427.8901 315.7246 428.1733 314.2715 428.1733 c +311.2705 428.1567 308.8516 427.187 307.0791 425.2915 C +307.0742 425.2866 306.9922 425.187 306.8838 425.0562 C +306.8838 425.9917 306.8838 427.4858 Y +301.5957 427.4858 L +301.5957 393.6367 L +306.8838 393.6367 L +306.8838 402.7813 306.8838 404.5488 V +308.6221 402.8047 310.9805 401.9023 313.9268 401.8867 c +315.4131 401.8867 316.8398 402.1641 318.168 402.7148 c +319.502 403.2676 320.6523 404.0645 321.5889 405.0879 c +323.7734 407.375 324.8838 410.7617 324.8838 415.1523 c +324.9004 419.5239 323.7813 422.9214 321.5586 425.2485 c +320.7197 426.1206 319.6836 426.8208 318.4785 427.3315 c +f +0 D +319.4092 415.2305 m +319.3926 410.5078 318.042 407.5742 315.3945 406.5078 C +314.6729 406.1855 313.8535 406.0332 312.9453 406.0488 c +310.1943 406.0488 308.4297 407.293 307.542 409.8535 c +307.0205 411.2344 306.7588 412.8281 306.7588 414.5977 c +306.7588 414.6504 306.7588 414.7031 306.7588 414.7559 c +306.7744 417.4473 307.2002 419.561 308.0254 421.0425 c +309.1758 423.0698 310.8604 424.0415 313.1758 424.0112 c +315.8447 424.0112 317.5938 422.7563 318.5293 420.1763 c +319.1289 418.6094 319.4238 416.9473 319.4092 415.2305 c +f +*U +*u +1 D +351.1064 417.8457 m +350.6318 424.6392 346.9629 428.0991 340.2012 428.1489 c +337.8291 428.1655 335.7432 427.6421 334.002 426.5933 c +331.9873 425.4077 330.5742 423.7935 329.8086 421.7993 c +328.9766 419.7026 328.5625 417.291 328.5801 414.6348 c +328.5459 410.8301 329.4922 407.7363 331.3926 405.4453 c +333.376 403.0508 336.3418 401.8457 340.209 401.8613 c +341.9434 401.8457 343.6162 402.1348 345.1748 402.7207 c +346.7607 403.3184 348.124 404.3535 349.2285 405.8008 c +349.9951 406.8125 350.5498 408.3789 350.9238 410.5898 C +351.0078 411.0859 L +345.5137 411.0859 L +345.459 410.7246 L +344.9873 407.5918 343.2588 406.0547 340.1768 406.0234 c +339.2813 406.0078 338.4395 406.1699 337.6719 406.5039 C +336.2715 407.0566 335.3164 408.1133 334.7363 409.7422 c +334.4219 410.6211 334.2139 412.0859 334.0947 413.9863 C +334.9756 413.9863 351.1895 413.9863 Y +351.1064 417.8457 L +f +0 D +345.6709 418.0859 m +344.8555 418.0859 335.0693 418.0859 334.1504 418.0859 C +334.2607 418.6328 334.4316 419.4741 334.4346 419.4907 C +335.1387 422.5005 337 423.9712 340.126 423.9868 c +342.0811 423.9712 343.5508 423.4067 344.4883 422.3081 c +345.166 421.52 345.5547 420.0845 345.6709 418.0859 C +f +*U +371.9424 411.1172 m +371.832 410.2832 371.6816 409.5859 371.4961 409.043 c +370.8779 407.0234 369.2148 406.0488 366.4082 406.0488 c +363.9287 406.002 362.2451 406.9961 361.2529 409.0879 c +360.6133 410.4141 360.2891 412.6094 360.2891 415.6172 c +360.2891 417.373 360.5625 419.0493 361.1006 420.5972 c +361.5566 421.9927 362.4873 422.9487 363.9482 423.5259 c +364.7471 423.8481 365.6182 424.0103 366.5391 424.0103 c +369.5781 423.979 371.2637 422.4634 371.6934 419.3774 C +371.7441 419.0112 L +377.2314 419.0112 L +376.8652 421.5024 L +376.5674 422.9663 375.9199 424.2358 374.9385 425.2983 c +373.21 427.1724 370.5107 428.1392 366.915 428.1733 c +362.9492 428.1567 359.8242 426.8628 357.6211 424.3276 c +355.7412 422.1646 354.7969 418.9199 354.8145 414.6855 c +354.8145 410.8613 355.7549 407.7695 357.6104 405.498 c +359.585 403.0996 362.5615 401.8867 366.458 401.8867 c +369.5137 401.8867 372.0508 402.6055 373.999 404.0254 c +375.1719 404.8867 376.0205 405.9375 376.5225 407.1484 c +376.8662 407.9707 377.1563 409.2324 377.4102 411 C +377.4795 411.4863 L +371.9922 411.4863 L +371.9424 411.1172 L +f +395.7109 423.3862 m +395.7109 427.4858 L +390.3838 427.4858 389.6484 427.4858 V +389.6484 428.2271 389.6484 434.0688 Y +389.0625 433.8296 L +384.3613 431.9087 L +384.3613 428.1851 384.3613 427.4858 V +383.6504 427.4858 379.4238 427.4858 Y +379.4238 423.3862 L +383.6504 423.3862 384.3613 423.3862 V +384.3613 422.5854 384.3613 409.4121 Y +384.3613 409.4082 384.3857 406.9102 Y +384.5801 403.5879 386.7363 401.9043 390.7949 401.8867 c +391.9551 401.8867 393.4844 402.0137 395.3428 402.2656 C +395.7109 402.3145 L +395.7109 406.5117 L +395.2061 406.416 L +393.9287 406.1719 392.8662 406.0488 392.0459 406.0488 c +390.1982 406.0059 389.9551 406.7871 389.875 407.0449 C +389.875 407.0547 389.7148 407.8086 389.7129 407.8145 C +389.7139 407.8145 389.7139 407.8164 389.7139 407.8203 c +389.7139 407.9199 389.6484 409.291 Y +389.6484 422.5845 389.6484 423.3862 V +390.3838 423.3862 395.7109 423.3862 Y +f +U +U +LB +%AI5_EndLayer-- +%%PageTrailer +gsave annotatepage grestore showpage +%%Trailer +Adobe_Illustrator_AI5 /terminate get exec +Adobe_ColorImage_AI6 /terminate get exec +Adobe_cshow /terminate get exec +Adobe_level2_AI5 /terminate get exec +%%EOF diff --git a/Ag++/doc/images/ac++logo.pdf b/Ag++/doc/images/ac++logo.pdf new file mode 100644 index 0000000..114600a Binary files /dev/null and b/Ag++/doc/images/ac++logo.pdf differ diff --git a/Ag++/doc/styles/acc.sty b/Ag++/doc/styles/acc.sty new file mode 100644 index 0000000..4961f33 --- /dev/null +++ b/Ag++/doc/styles/acc.sty @@ -0,0 +1,110 @@ +\NeedsTeXFormat{LaTeX2e}[1994/06/01] +\ProvidesPackage{acc}[2002/12/18 v0.2 Standard LaTeX package] +\RequirePackage{ifthen} +\RequirePackage{graphics} + +% +% set font to helvetica +% +\RequirePackage{helvet} +\renewcommand{\familydefault}{phv} + +% +% setup page geometry +% the geometry package works better with pdflatex +% +\RequirePackage{geometry} +\geometry{a4paper,dvips,pdftex,textwidth=15cm,textheight=23cm,twosideshift=0pt} + +% +% setup fancyhdr +% +\RequirePackage{fancyhdr} +\fancypagestyle{plain}{% + % + % two side book class setup + % odd page - left head: chapter - left foot: page number + % even page - right head: section - right foot: page number + % no head on plain pages + % + \fancyhf{}% + \fancyhead[LE,RO]{\slshape \rightmark} + \fancyhead[LO,RE]{\slshape \leftmark} + \fancyfoot[LE,RO]{\bfseries \thepage} + % + % rules for head and foot + % also on plain pages + % + \renewcommand{\headrulewidth}{.4pt} + \renewcommand{\footrulewidth}{.4pt} + \renewcommand{\plainfootrulewidth}{.4pt} +} +\pagestyle{plain} + +% +% Variables to change some details +% +% version number for this document +% +\newcommand{\@version}{1} +\newcommand{\version}[1]{ \renewcommand{\@version}{#1} } +% +% +\newcommand\otherlogo[1]{\gdef\@otherlogo{#1}} +\otherlogo{} +% +\newcommand\remark[1]{\gdef\@remark{#1}} +\remark{} +% +\newcommand{\doctype}[1]{\gdef\@doctype{#1}} +\doctype{Studie:} +% +\newcommand\credit[1]{\gdef\@credit{#1}} + +% +% +% +\newcommand\layoutlogos{ + + \newlength{\@otherlogowidth} + \settowidth{\@otherlogowidth}{\@otherlogo} + + \noindent + \begin{minipage}{\@otherlogowidth} + {\@otherlogo} + \end{minipage} + \hspace*{\fill} +} + +% +% redefine \maketitle macro +% +\renewcommand{\maketitle}{ + \null + \thispagestyle{empty} + + {\layoutlogos} + + \vskip 3cm + \begin{center}\leavevmode + {\Huge\raggedright {\@doctype}\\ {\@title}\par} + \rule{\textwidth}{1mm} + \vskip 3mm + {\Large\raggedleft {\@author}\par} + \vskip 15mm + {\Large\raggedleft Version {\@version}\par} + \end{center} + \vfill + {\large\raggedleft {\@remark}\par} + \vskip 1cm + \null +% + \newpage +% + \null + \thispagestyle{empty} + \vfill + {\@credit} + \null + \cleardoublepage +} diff --git a/Ag++/file.cc b/Ag++/file.cc new file mode 100644 index 0000000..eb40db9 --- /dev/null +++ b/Ag++/file.cc @@ -0,0 +1,125 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2004 The 'ac++' developers (see aspectc.org) +// +// 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 "file.h" + +// Puma includes +#include "Puma/RegComp.h" +using namespace Puma; + +// stdc++ includes +#include +#include +using namespace std; + +bool +file::fileExists(const char* file) +{ + ifstream fs(file); + if (!fs) + { + return false; + } + fs.close(); + + return true; +} + +void +file::MakeUnixPath(string& path) +{ + if (path.empty()) + return; + for (string::iterator c = path.begin(); c != path.end(); c++) + { + if (*c == '\\') + *c = '/'; + } +} +void +file::MakeDosPath(string& path) +{ + if (path.empty()) + return; + for (string::iterator c = path.begin(); c != path.end(); c++) + { + if (*c == '/') + *c = '\\'; + } +} +void +file::stripFilename(string& s, bool include_delimiter) +{ + string::size_type pos, pos2; + pos = s.find_last_of('\\'); + pos2 = s.find_last_of('/'); + if (pos == string::npos) + { + if (pos2 == string::npos) + { + pos = 0; + } + else + { + pos = pos2; + if (include_delimiter) + pos++; + } + } + else + { + if (pos2 != string::npos && pos2 > pos) + { + pos = pos2; + } + if (include_delimiter) + pos++; + } + + s.erase(pos); +} + +void +file::stripPath(string& s) +{ + string::size_type pos, pos2; + pos = s.find_last_of('\\'); + pos2 = s.find_last_of('/'); + if (pos == string::npos) + { + if (pos2 == string::npos) + { + pos = 0; + } + else + { + pos = pos2; + pos++; + } + } + else + { + if (pos2 != string::npos && pos2 > pos) + { + pos = pos2; + } + pos++; + } + s.erase(0, pos); +} + diff --git a/Ag++/file.h b/Ag++/file.h new file mode 100644 index 0000000..3addcf4 --- /dev/null +++ b/Ag++/file.h @@ -0,0 +1,42 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2004 The 'ac++' developers (see aspectc.org) +// +// 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 __file_h__ +#define __file_h__ + +#include +using namespace std; + +namespace file +{ + bool + fileExists(const char* file); + + void + stripFilename(string& s, bool include_delimiter = true); + void + stripPath(string& s); + + void + MakeUnixPath(string& s); + void + MakeDosPath(string& s); + +} + +#endif //__file_h__ diff --git a/Ag++/gpl.txt b/Ag++/gpl.txt new file mode 100644 index 0000000..b416af8 --- /dev/null +++ b/Ag++/gpl.txt @@ -0,0 +1,19 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2004 The 'ac++' developers (see aspectc.org) +// +// 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 + + diff --git a/Ag++/regex.cc b/Ag++/regex.cc new file mode 100644 index 0000000..68fdd14 --- /dev/null +++ b/Ag++/regex.cc @@ -0,0 +1,67 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2004 The 'ac++' developers (see aspectc.org) +// +// 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 "regex.h" + +// Puma includes +#include "Puma/RegComp.h" +using namespace Puma; + +// stdc++ includes +#include +#include +using namespace std; + +// static instance of RegExCont(ainer) +static regex::RegExCont regex_cont; + +bool +regex::regExMatch(const string& expr, const char* str) +{ + bool ret = false; + RegComp* regcomp = 0; + + // lookup for already compiled regular expressions + regcomp = regex_cont.lookup(expr); + if (regcomp == NULL) + { + regcomp = new RegComp(expr.c_str()); + regex_cont.add(expr, regcomp); + } + + if (regcomp) + { + if (regcomp->match(str)) + { + //cout << "match for " <<" '"<< expr <<"' in '" << str << "'" <comperror(cerr); + //} + + } + else + { + cerr << "no reg ex" << endl; + + } + + return ret; +} diff --git a/Ag++/regex.h b/Ag++/regex.h new file mode 100644 index 0000000..d07ba84 --- /dev/null +++ b/Ag++/regex.h @@ -0,0 +1,30 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2004 The 'ac++' developers (see aspectc.org) +// +// 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 __regex_h__ +#define __regex_h__ + +#include "RegExCont.h" + +namespace regex +{ + bool + regExMatch(const std::string& expr, const char* str); +} + +#endif //__regex_h__ diff --git a/Ag++/tests/additional_aspects/trace2.ah b/Ag++/tests/additional_aspects/trace2.ah new file mode 100644 index 0000000..0107e87 --- /dev/null +++ b/Ag++/tests/additional_aspects/trace2.ah @@ -0,0 +1,12 @@ +#ifndef __trace2_ah__ +#define __trace2_ah__ +#include +aspect Trace2{ + pointcut func() = "% Test::%(...)"; + advice execution(func()): after() { + printf("after(Trace 2): %s \n",JoinPoint::signature()); + } +}; + +#endif //__test_ah__ + diff --git a/Ag++/tests/additional_includes/test_include.h b/Ag++/tests/additional_includes/test_include.h new file mode 100644 index 0000000..cd0351c --- /dev/null +++ b/Ag++/tests/additional_includes/test_include.h @@ -0,0 +1,7 @@ +#ifdef __TEST_INCLUDE_H__ +#define __TEST_INCLUDE_H__ + +typedef int my_int_t; + + +#endif diff --git a/Ag++/tests/run_tests.sh b/Ag++/tests/run_tests.sh new file mode 100755 index 0000000..67c7efe --- /dev/null +++ b/Ag++/tests/run_tests.sh @@ -0,0 +1,105 @@ +#!/bin/bash + +# path to ag++ +AGCC="../../AspectC++/bin/${TARGET}/ag++" + +# summary printed in case at least one testcase failed +ERR_SUM="+-----------------+\n"; +ERR_SUM="${ERR_SUM}| Error Messages: |\n"; +ERR_SUM="${ERR_SUM}+-----------------+\n"; +ERR_OCCURED=0; + +# files for storing output from stdout and stderr +STDOUT_FILE=stdout.tmp; +STDERR_FILE=stderr.tmp; + +# check if TARGET variable is set +if [ -z ${TARGET} ];then + echo -en "\n\nThis script has to be invoked by 'make test' from the toplevel directory\n\n" + exit +fi + +# check if the name of a test was passed +if [ $# -gt 0 ];then + if [ -f $1 ];then + TEST_FILES="$1"; + else + echo "Test file '$1' not found"; + exit; + fi +else + # if no test was execute all test in this folder + TEST_FILES=$(find . -maxdepth 1 -name 'test_??' | sort | sed ':a;N;$!ba;s/\n/ /g'); +fi + + +# loop through all test files +for testfile in ${TEST_FILES}; +do + rm -f puma.config; + ERR_MSG=""; + + # include testfile file + source $testfile; + + # redirect stdout and stderr + exec 6>&1; + exec 7>&2; + exec > ${STDOUT_FILE}; + exec 2> ${STDERR_FILE}; + + # execute main function of current test + main ; + RET=$?; + + # execute main function of current test + + #restore stdout and stderr + exec 1>&6 6>&-; + exec 2>&7 7>&-; + + # perform cleanup of test + cleanup ; + + # check if test succeeded + if [ $RET == 0 ]; then + # test succeded + echo -n "."; + else + # test failed + echo -n "[${testfile/*_/}:F]"; + ERR_OCCURED=1; + + # get stdout and stderr + STDOUT=`cat ${STDOUT_FILE}`; + STDERR=`cat ${STDERR_FILE}`; + + # add information to error summary + ERR_SUM="${ERR_SUM}\n\n-----------------------------------------------------------------------------------------\n"; + ERR_SUM="${ERR_SUM}TESTFILE: ${testfile}\n"; + ERR_SUM="${ERR_SUM}-----------------------------------------------------------------------------------------\n\n"; + ERR_SUM="${ERR_SUM}TEST DESCRIPTION: ${DESC//'\\'/\\\\}\n"; + ERR_SUM="${ERR_SUM}-----------------\n\n"; + ERR_SUM="${ERR_SUM}ERROR: ${ERR_MSG//'\\'/\\\\}\n"; + ERR_SUM="${ERR_SUM}------\n\n"; + ERR_SUM="${ERR_SUM}STDOUT:\n"; + ERR_SUM="${ERR_SUM}-------\n${STDOUT//'\\'/\\\\}\n"; + ERR_SUM="${ERR_SUM}STDERR:\n"; + ERR_SUM="${ERR_SUM}-------\n${STDERR//'\\'/\\\\}\n"; + fi + rm -f puma.config; + +done + +# print summery of all errors occured +echo; +echo; +if [ $ERR_OCCURED == 1 ];then + echo -e "$ERR_SUM"; +else + echo "All tests OK"; +fi + +# remove files containing output from stdout and stderr +rm $STDERR_FILE $STDOUT_FILE; + diff --git a/Ag++/tests/src/Makefile b/Ag++/tests/src/Makefile new file mode 100644 index 0000000..5ed17f2 --- /dev/null +++ b/Ag++/tests/src/Makefile @@ -0,0 +1,22 @@ + +ACXX := ../../../AspectC++/bin/linux-release/ag++ +OBJ_DIR := obj + +SRC := $(wildcard *.cc) +OBJ := $(SRC:%.cc=$(OBJ_DIR)/%.o) +AH := $(wildcard *.ah) + +PROG := test + +all: $(PROG) + + +clean: + rm -rf *.acc $(OBJ_DIR) $(PROG) puma.config + +$(PROG): $(OBJ) + $(ACXX) -v 2 -o $@ $+ + +$(OBJ_DIR)/%.o:%.cc $(AH) + @mkdir -p $(OBJ_DIR) + $(ACXX) -v 2 -o $@ -c $< diff --git a/Ag++/tests/src/Test.cc b/Ag++/tests/src/Test.cc new file mode 100644 index 0000000..7a780c8 --- /dev/null +++ b/Ag++/tests/src/Test.cc @@ -0,0 +1,18 @@ +#include "Test.h" +#include "../additional_includes/test_include.h" +Test::Test(){ + number=0; +} + +int Test::get(){ + return number; +} + +void Test::set(int i){ + number=i; +} + +template +T GetMin (T a, U b) { + return (a T GetMin (T a, U b); +}; +#endif //__Test_h__ + diff --git a/Ag++/tests/src/main.cc b/Ag++/tests/src/main.cc new file mode 100644 index 0000000..1aaff74 --- /dev/null +++ b/Ag++/tests/src/main.cc @@ -0,0 +1,8 @@ +#include "Test.h" +#include + +int main(){ + Test t; + printf("Hello %d\n",t.get()); + return 0; +} diff --git a/Ag++/tests/src/trace.ah b/Ag++/tests/src/trace.ah new file mode 100644 index 0000000..0da61d2 --- /dev/null +++ b/Ag++/tests/src/trace.ah @@ -0,0 +1,12 @@ +#ifndef __trace_ah__ +#define __trace_ah__ +#include +aspect Trace{ + pointcut func() = "% Test::%(...)"; + advice execution(func()): before() { + printf("before (Trace 1): %s \n",JoinPoint::signature()); + } +}; + +#endif //__test_ah__ + diff --git a/Ag++/tests/test_01 b/Ag++/tests/test_01 new file mode 100644 index 0000000..96b5a93 --- /dev/null +++ b/Ag++/tests/test_01 @@ -0,0 +1,14 @@ +DESC="Check if executable is at the right place" + +main() +{ + if [ ! \( \( -x ${AGCC} \) -o \( -x ${AGCC}.exe \) \) ];then + ERR_MSG="Executable '${AGCC}' not found"; + return 1; + fi; +} + +cleanup() +{ + true; +} diff --git a/Ag++/tests/test_02 b/Ag++/tests/test_02 new file mode 100644 index 0000000..351d4df --- /dev/null +++ b/Ag++/tests/test_02 @@ -0,0 +1,32 @@ +DESC="Generate puma.config (default name) and weave source file afterwards using generated config" + +main() +{ + EXEC="${AGCC} --gen_config" + if ( ${EXEC} );then true;else + ERR_MSG="Failed executing '${EXEC}'"; + return 1; + fi; + + if [ -f puma.config ];then true;else + ERR_MSG="Puma configuration file was not created"; + return 1; + fi; + + EXEC="${AGCC} --path src -o src/main.acc -v2 --weave_only --system-config puma.config src/main.cc" + if ( ${EXEC} );then true;else + ERR_MSG="Failed executing '${EXEC}'"; + return 1; + fi; + + if [ ! -f src/main.acc ];then + ERR_MSG="Acc file was not created"; + return 1; + fi; + +} + +cleanup() +{ + rm -f puma.config src/main.acc +} diff --git a/Ag++/tests/test_03 b/Ag++/tests/test_03 new file mode 100644 index 0000000..4c86db3 --- /dev/null +++ b/Ag++/tests/test_03 @@ -0,0 +1,38 @@ +DESC="Generate Object File from source file and link it afterwards" + +main() +{ + mkdir src/bin + mkdir src/obj + + OBJ="src/obj/Test03.o" + BIN="src/bin/test03${EXT}" + + EXEC="${AGCC} -v2 --path src -c -o ${OBJ} src/Test.cc" + if (${EXEC});then true;else + ERR_MSG="Failed executing '${EXEC}'"; + return 1; + fi; + + if [ ! -f ${OBJ} ];then + ERR_MSG="Object file '${OBJ}' was not created"; + return 1; + fi; + + + EXEC="${AGCC} -v2 --path src -o ${BIN} ${OBJ} src/main.cc" + if (${EXEC});then true;else + ERR_MSG="Failed executing '${EXEC}"; + fi + + if [ ! -e ${BIN} ];then + ERR_MSG="Executable '${BIN}' was not created"; + return 1; + fi; +} + +cleanup() +{ + rm -rf src/bin src/obj +} + diff --git a/Ag++/tests/test_04 b/Ag++/tests/test_04 new file mode 100644 index 0000000..ea38d04 --- /dev/null +++ b/Ag++/tests/test_04 @@ -0,0 +1,20 @@ +DESC="Compile and link source files in one step" + +main() +{ + EXEC="${AGCC} -v2 --path src src/*.cc"; + if ( ${EXEC} );then true;else + ERR_MSG="Failed executing '${EXEC}'"; + return 1; + fi; + + if [ ! \( \( -x a.out \) -o \( -x a.exe \) \) ];then + ERR_MSG="Executable file was not generated"; + return 1; + fi; +} + +cleanup() +{ + rm -f a.out a.exe; +} diff --git a/Ag++/tests/test_05 b/Ag++/tests/test_05 new file mode 100644 index 0000000..c0a7e54 --- /dev/null +++ b/Ag++/tests/test_05 @@ -0,0 +1,32 @@ +DESC="Generate puma configuration with alternate filename and use it afterwards" + +main() +{ + EXEC="${AGCC} --gen_config -o my.config" + if ( ${EXEC} );then true;else + ERR_MSG="Failed executing '${EXEC}'"; + return 1; + fi; + + if [ ! -f my.config ];then + ERR_MSG="Puma configuration file was not created"; + return 1; + fi; + + + EXEC="${AGCC} -p src -v2 --weave_only --config my.config src/main.cc" + if ( ${EXEC} );then true;else + ERR_MSG="Failed executing '${EXEC}'"; + return 1; + fi; + + if [ ! -f main.acc ];then + ERR_MSG="Weaved source file was not created"; + return 1; + fi; +} + +cleanup() +{ + rm -f my.config main.acc +} diff --git a/Ag++/tests/test_06 b/Ag++/tests/test_06 new file mode 100644 index 0000000..3f35b84 --- /dev/null +++ b/Ag++/tests/test_06 @@ -0,0 +1,14 @@ +DESC="Fail when trying to invoke ag++ with -o --weave_only and multiple files " + +main(){ + EXEC="${AGCC} -p src -o test_06.out --weave_only src/Test.cc src/main.cc" + if ( ${EXEC} );then + ERR_MSG="Succeed (should fail executing '${EXEC}')"; + return 1; + fi; +} + +cleanup() +{ + rm -f test_06.out; +} diff --git a/Ag++/tests/test_07 b/Ag++/tests/test_07 new file mode 100644 index 0000000..4def35f --- /dev/null +++ b/Ag++/tests/test_07 @@ -0,0 +1,20 @@ +DESC="Generate modified include files" + +main() +{ + EXEC="${AGCC} --path src -v2 -Isrc --include_files --dest includes" + if ( ${EXEC} );then true;else + ERR_MSG="Failed executing '${EXEC}'"; + return 1; + fi; + + if [ ! -d includes ];then + ERR_MSG="Directory with include files was not genereated"; + return 1; + fi; +} + +cleanup() +{ + rm -rf includes; +} diff --git a/Ag++/tests/test_08 b/Ag++/tests/test_08 new file mode 100644 index 0000000..66cd5c4 --- /dev/null +++ b/Ag++/tests/test_08 @@ -0,0 +1,30 @@ +DESC="Generate dependencies" +main() +{ + mkdir src/dep + + EXEC="${AGCC} --path src -v2 -MF src/dep/dep.ag -M src/*.cc" + if ( ${EXEC} );then true;else + ERR_MSG="Failed executing '${EXEC}'"; + return 1; + fi; + + if [ ! -f src/dep/dep.ag ];then + ERR_MSG="File with dependency information was not generated"; + return 1; + fi; + + g++ -include src/trace.ah -M -MF src/dep/dep.g src/*.cc; + + echo -e "\nDIFF BETWEEN FILES 'dep.g' and 'dep.ag': \n" + if ( diff src/dep/dep.g src/dep/dep.ag );then true;else + ERR_MSG="Dependency information differs between 'g++' and 'ag++' (files: 'src/dep/dep.g' and 'src/dep/dep.ag')"; + return 1; + fi; +} + +cleanup() +{ + rm -rf src/dep; +} + diff --git a/Ag++/tests/test_09 b/Ag++/tests/test_09 new file mode 100644 index 0000000..5ae59a4 --- /dev/null +++ b/Ag++/tests/test_09 @@ -0,0 +1,32 @@ +DESC="Multiple project paths" + +main() +{ + mkdir src/bin + + BIN="src/bin/test09${EXT}" + + EXEC="${AGCC} -Isrc -I additional_aspects --real-instances --path src --path additional_aspects -o ${BIN} -v2 src/*.cc" + if ( ${EXEC} );then true;else + ERR_MSG="Failed executing '${EXEC}'"; + return 1; + fi; + + if [ ! -f ${BIN} ];then + ERR_MSG="Executable '${BIN}' was not generated"; + return 1; + else + ${BIN} > test_09.out; + fi; + + echo -n "\n\nDIFF:\n" + if ( diff -w test_09.out test_09.ref );then true;else + ERR_MSG="Outputs differ: Probably the programm was not weaved correctly"; + return 1; + fi; +} + +cleanup() +{ + rm -rf src/bin test_09.out; +} diff --git a/Ag++/tests/test_09.ref b/Ag++/tests/test_09.ref new file mode 100644 index 0000000..7a7f1d6 --- /dev/null +++ b/Ag++/tests/test_09.ref @@ -0,0 +1,3 @@ +before (Trace 1): int Test::get() +after(Trace 2): int Test::get() +Hello 0 diff --git a/Ag++/tests/test_10 b/Ag++/tests/test_10 new file mode 100644 index 0000000..5371e65 --- /dev/null +++ b/Ag++/tests/test_10 @@ -0,0 +1,29 @@ +DESC="Custom Configuration Command" + +main() +{ + CONFIG_COMMAND="cat test_10.in" + + EXEC="${AGCC} -Dtest_10_file_3='\"a string\"' -v3 --gen_config -o test_10.config --config_command \"${CONFIG_COMMAND}\"" + if ( eval ${EXEC} );then true;else + ERR_MSG="Failed executing '${EXEC}'"; + return 1; + fi; + + + if [ ! -f test_10.config ];then + ERR_MSG="Puma Configuration File 'test10.config' was not generated"; + return 1; + fi; + + if ( diff -w test_10.config test_10.ref );then true;else + ERR_MSG="Outputs differ: Configuration file not correctly generated"; + return 1; + fi; +} + +cleanup() +{ + rm -f test_10.config +} + diff --git a/Ag++/tests/test_10.in b/Ag++/tests/test_10.in new file mode 100644 index 0000000..8825957 --- /dev/null +++ b/Ag++/tests/test_10.in @@ -0,0 +1,3 @@ +#define test_10_file_1 +#define test_10_file_2 a string +#define test_10_file_3 "a string" diff --git a/Ag++/tests/test_10.ref b/Ag++/tests/test_10.ref new file mode 100644 index 0000000..ddbcecf --- /dev/null +++ b/Ag++/tests/test_10.ref @@ -0,0 +1,7 @@ +--skip-bodies-non-prj +-D __puma +-D __STDC__ +-D "test_10_file_1" +-D "test_10_file_2=a string" +-D "test_10_file_3=\"a string\"" +--gnu diff --git a/Ag++/tests/test_11 b/Ag++/tests/test_11 new file mode 100644 index 0000000..bb11cee --- /dev/null +++ b/Ag++/tests/test_11 @@ -0,0 +1,70 @@ +DESC="Pass options directly to compiler" + +main() +{ + EXEC="${AGCC} -p src -v2 --Xcompiler --real-instances --Xweaver -o test_11.out src/*.cc" + if ( ${EXEC} );then + ERR_MSG="Execution should have failed as --real-instances is not a gcc option: '${EXEC}'"; + return 1; + else + true; + fi; + + OPT_COUNTER=`grep 'Options (G++):' ${STDOUT_FILE}|grep -c '\-\-real-instances'`; + if [ ${OPT_COUNTER} -eq 1 ];then true;else + ERR_MSG="The option '--real-instances' has not been passed to gcc"; + return 1; + fi; + + OPT_COUNTER=`grep 'Options (AC++)' ${STDOUT_FILE}|grep -c '\-\-real-instances'` + if [ test ${OPT_COUNTER} -eq 1 ];then + ERR_MSG="The option '--real-instances' has accidently been passed to ac++"; + return 1; + else + true; + fi; + + EXEC="${AGCC} -v2 --Xcompiler -ansi -pipe -DFOO --Xweaver --real-instances --gen_config -o test_11.config" + if ( ${EXEC} -v2 --Xcompiler -ansi -pipe -DFOO --Xweaver --real-instances --gen_config -o test_11.config );then true;else + ERR_MSG="Execution failed: '${EXEC}'"; + return 1; + fi; + + OPT_COUNTER=`grep 'Options (G++):' ${STDOUT_FILE}|grep -c '\-ansi'` + if [ ${OPT_COUNTER} -eq 1 ];then true;else + ERR_MSG="The option '-ansi' has not been passed to gcc"; + return 1; + fi; + + OPT_COUNTER=`grep 'Options (G++)' ${STDOUT_FILE}|grep -c '\-pipe'` + if [ ${OPT_COUNTER} -eq 1 ];then true;else + ERR_MSG="The option '-pipe' has not been passed to gcc"; + return 1; + fi; + + + OPT_COUNTER=`grep 'Options (AC++)' ${STDOUT_FILE}|grep -c '\-\-real-instances'` + if [ ${OPT_COUNTER} -eq 1 ];then true;else + ERR_MSG="The option '--real-instances' has not been passed to ac++"; + return 1; + fi; + + OPT_COUNTER=`grep 'Options (G++)' ${STDOUT_FILE}|grep -c '\-D "FOO"'` + if [ ${OPT_COUNTER} -eq 1 ];then true;else + ERR_MSG="The option '-D"FOO"' has not been passed to gcc"; + return 1; + fi; + + OPT_COUNTER=`grep 'Options (AC++)' ${STDOUT_FILE}|grep -c '\-D "FOO"'` + if [ ${OPT_COUNTER} -eq 1 ];then true;else + ERR_MSG="The option '-D"FOO"' has not been passed to ac++"; + return 1; + fi; + +} + +cleanup() +{ + rm -f test_11.config + rm -f test_11.out +} diff --git a/Ag++/tests/test_12 b/Ag++/tests/test_12 new file mode 100644 index 0000000..ab737af --- /dev/null +++ b/Ag++/tests/test_12 @@ -0,0 +1,20 @@ +DESC="Include paths from original location " + +main() +{ + mkdir src/bin + + BIN="src/bin/test12{EXT}" + + EXEC="${AGCC} -p src -v1 -o ${BIN} src/*.cc" + if ( ${EXEC} );then true; + else + ERR_MSG="Execution failed '${EXEC}'"; + return 1; + fi; +} + +cleanup() +{ + rm -rf puma.config src/bin +} diff --git a/Ag++/tests/test_13 b/Ag++/tests/test_13 new file mode 100644 index 0000000..f20b3dd --- /dev/null +++ b/Ag++/tests/test_13 @@ -0,0 +1,18 @@ +DESC="String including whitespace used with -D option" + +main() +{ + mkdir -p src/bin + + EXEC="${AGCC} -p src -v1 -o src/bin/test13{EXT} -DFOO=\"foo bar\" src/*.cc" + if ( eval ${EXEC} );then true; + else + ERR_MSG="Execution failed '${EXEC}'"; + return 1; + fi; +} + +cleanup() +{ + rm -rf puma.config src/bin +} diff --git a/Ag++/tests/test_14 b/Ag++/tests/test_14 new file mode 100644 index 0000000..945f984 --- /dev/null +++ b/Ag++/tests/test_14 @@ -0,0 +1,19 @@ +DESC="XLinker GCC option" + +main() +{ + mkdir -p src/bin + BIN=src/bin/test14${EXT} + + EXEC="${AGCC} -p src -v1 -o ${BIN} -Xlinker -assert -Xlinker definitions src/*.cc" + if ( ${EXEC} );then true; + else + ERR_MSG="Execution failed '${EXEC}'"; + return 1; + fi; +} + +cleanup() +{ + rm -rf puma.config src/bin +} diff --git a/Ag++/tests/test_15 b/Ag++/tests/test_15 new file mode 100644 index 0000000..02c57e7 --- /dev/null +++ b/Ag++/tests/test_15 @@ -0,0 +1,24 @@ +DESC="Check option --keep_woven" + +main() +{ + mkdir -p src/bin + BIN=src/bin/test15${EXT} + + EXEC="${AGCC} --keep_woven -p src -v1 -o ${BIN} src/*.cc" + if ( ${EXEC} );then true; + else + ERR_MSG="Execution failed '${EXEC}'"; + return 1; + fi; + + if [ -f Test.acc -a -f main.acc ];then true; + else + ERR_MSG="Woven files do not exist."; + fi; +} + +cleanup() +{ + rm -rf puma.config src/bin *.acc +} diff --git a/Ag++/tests/test_16 b/Ag++/tests/test_16 new file mode 100644 index 0000000..6b83662 --- /dev/null +++ b/Ag++/tests/test_16 @@ -0,0 +1,39 @@ +DESC="Check if option argument of a long GCC option is passed correctly to GCC if the +option argument is separated from the option by '='" + +main() +{ + + # check long option with '=' as separator + EXEC="${AGCC} -p src -v2 --param=ssp-buffer-size=4 -o test_16.out src/*.cc" + if ( ${EXEC} );then true;else + ERR_MSG="Execution failed: '${EXEC}'"; + return 1; + fi; + + OPT_COUNTER=`grep 'Options (G++):' ${STDOUT_FILE}|grep -c '\-\-param=\"ssp-buffer-size=4\"'` + if [ ${OPT_COUNTER} -eq 1 ];then true;else + ERR_MSG="The option '--param=\"ssp-buffer-size=4\"' has not been passed to gcc"; + return 1; + fi; + + # check long option with whitespace as separator + EXEC="${AGCC} -p src -v2 --param ssp-buffer-size=2 -o test_16.out src/*.cc" + if ( ${EXEC} );then true;else + ERR_MSG="Execution failed: '${EXEC}'"; + return 1; + fi; + + OPT_COUNTER=`grep 'Options (G++):' ${STDOUT_FILE}|grep -c '\-\-param \"ssp-buffer-size=2\"'` + if [ ${OPT_COUNTER} -eq 1 ];then true;else + ERR_MSG="The option '--param \"ssp-buffer-size=4\"' has not been passed to gcc"; + return 1; + fi; + +} + +cleanup() +{ + rm -f test_16.config + rm -f test_16.out +} diff --git a/Ag++/tests/test_17 b/Ag++/tests/test_17 new file mode 100644 index 0000000..5052309 --- /dev/null +++ b/Ag++/tests/test_17 @@ -0,0 +1,17 @@ +DESC="Handle gcc options which only print information" + +main() +{ + + # check long option with '=' as separator + EXEC="${AGCC} -p src -v2 --Xcompiler -print-libgcc-file-name" + if ( ${EXEC} );then true;else + ERR_MSG="Execution failed: '${EXEC}'"; + return 1; + fi; +} + +cleanup() +{ + true +} diff --git a/Ag++/tests/test_18 b/Ag++/tests/test_18 new file mode 100644 index 0000000..88155a2 --- /dev/null +++ b/Ag++/tests/test_18 @@ -0,0 +1,40 @@ +DESC="Match a pointcut from a Aspect C++ repository" + +REPOSDIR="src/repos dir" +REPOS="${REPOSDIR}/test18_repos.acp" +OBJDIR="src/obj dir" +OBJ="${OBJDIR}/Test03.o" + +main() +{ + mkdir "${OBJDIR}" + mkdir "${REPOSDIR}" + + EXEC="${AGCC} -v2 --repository \"${REPOS}\" --path src -c -o \"${OBJ}\" src/Test.cc" + if (eval ${EXEC});then true;else + ERR_MSG="Execution failed: '${EXEC}'"; + return 1; + fi; + + if [ ! -f "${OBJ}" ];then + ERR_MSG="Object file '${OBJ}' was not created"; + return 1; + fi; + + if [ ! -f "${REPOS}" ];then + return 1; + ERR_MSG="Repository file '${REPOS}' has not been created"; + fi + + EXEC="${AGCC} -v2 --repository \"${REPOS}\" --expr'\"% Test::%(...)\" && \"%\"'" + if (eval ${EXEC});then true;else + ERR_MSG="Execution failed: '${EXEC}'"; + return 1; + fi; +} + +cleanup() +{ + rm -rf "${REPOSDIR}" + rm -rf "${OBJDIR}" +} diff --git a/Ag++/version.h b/Ag++/version.h new file mode 100644 index 0000000..d154fbc --- /dev/null +++ b/Ag++/version.h @@ -0,0 +1,3 @@ +#define _VERSION "0.9" +#define COPYRIGHT "Gnu Public License (GPL)" +#define COMPANY_NAME "www.aspectc.org" diff --git a/Ag++/win-ac++.ico b/Ag++/win-ac++.ico new file mode 100755 index 0000000..80b7e32 Binary files /dev/null and b/Ag++/win-ac++.ico differ diff --git a/Ag++/win-ag++.rc b/Ag++/win-ag++.rc new file mode 100644 index 0000000..3f951fc --- /dev/null +++ b/Ag++/win-ag++.rc @@ -0,0 +1,41 @@ +///////////////////////////////////////// +// +// Version +// + +#include "version.h" + +1 ICON DISCARDABLE "win-ac++.ico" + +1 VERSIONINFO + FILEVERSION 0,0,6,0 + PRODUCTVERSION 0,0,6,0 + FILEFLAGSMASK 0x3fL + FILEFLAGS 0x0L + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040704b0" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", COMPANY_NAME + VALUE "FileDescription", "G++ Wrapper for AspectC++ Weaver\0" + VALUE "FileVersion", _VERSION + VALUE "InternalName", "ag++\0" + VALUE "LegalCopyright", COPYRIGHT + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "win-ag++.rc\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "ag++\0" + VALUE "ProductVersion", _VERSION + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x407, 1200 + END +END diff --git a/AspectC++/.cproject b/AspectC++/.cproject new file mode 100644 index 0000000..ead2249 --- /dev/null +++ b/AspectC++/.cproject @@ -0,0 +1,139 @@ + + + + + + + + + + + + + make + SHARED=1 -j4 + testclean test + false + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AspectC++/.project b/AspectC++/.project new file mode 100644 index 0000000..431b3c3 --- /dev/null +++ b/AspectC++/.project @@ -0,0 +1,122 @@ + + + AspectC++ + + + + + + org.eclipse.cdt.make.core.makeBuilder + clean,full,incremental, + + + org.eclipse.cdt.core.errorOutputParser + org.eclipse.cdt.core.GCCErrorParser;org.eclipse.cdt.core.GASErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.MakeErrorParser;org.eclipse.cdt.core.VCErrorParser; + + + org.eclipse.cdt.make.core.append_environment + true + + + org.eclipse.cdt.make.core.autoBuildTarget + + + + org.eclipse.cdt.make.core.build.arguments + make SHARED=1 FRONTEND=Clang -j6 + + + org.eclipse.cdt.make.core.build.command + nice + + + org.eclipse.cdt.make.core.build.location + + + + org.eclipse.cdt.make.core.build.target.auto + + + + org.eclipse.cdt.make.core.build.target.clean + clean + + + org.eclipse.cdt.make.core.build.target.full + clean all + + + org.eclipse.cdt.make.core.build.target.inc + all + + + org.eclipse.cdt.make.core.buildArguments + + + + org.eclipse.cdt.make.core.buildCommand + make + + + org.eclipse.cdt.make.core.buildLocation + + + + org.eclipse.cdt.make.core.cleanBuildTarget + + + + org.eclipse.cdt.make.core.enableAutoBuild + false + + + org.eclipse.cdt.make.core.enableCleanBuild + true + + + org.eclipse.cdt.make.core.enableFullBuild + true + + + org.eclipse.cdt.make.core.enabledIncrementalBuild + true + + + org.eclipse.cdt.make.core.environment + + + + org.eclipse.cdt.make.core.fullBuildTarget + clean all + + + org.eclipse.cdt.make.core.incrementalBuildTarget + all + + + org.eclipse.cdt.make.core.stopOnError + false + + + org.eclipse.cdt.make.core.useDefaultBuildCmd + false + + + + + org.eclipse.cdt.make.core.ScannerConfigBuilder + + + org.eclipse.cdt.make.core.ScannerConfigDiscoveryEnabled + false + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.make.core.makeNature + org.eclipse.cdt.make.core.ScannerConfigNature + + diff --git a/AspectC++/.settings/org.eclipse.ltk.core.refactoring.prefs b/AspectC++/.settings/org.eclipse.ltk.core.refactoring.prefs new file mode 100644 index 0000000..b196c64 --- /dev/null +++ b/AspectC++/.settings/org.eclipse.ltk.core.refactoring.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false diff --git a/AspectC++/.settings/org.eclipse.wst.validation.prefs b/AspectC++/.settings/org.eclipse.wst.validation.prefs new file mode 100644 index 0000000..dbcda5f --- /dev/null +++ b/AspectC++/.settings/org.eclipse.wst.validation.prefs @@ -0,0 +1,6 @@ +#Thu Jan 10 11:56:48 CET 2008 +DELEGATES_PREFERENCE=delegateValidatorListorg.eclipse.wst.wsdl.validation.internal.eclipse.WSDLDelegatingValidator\=org.eclipse.wst.wsdl.validation.internal.eclipse.Validator;org.eclipse.wst.xsd.core.internal.validation.eclipse.XSDDelegatingValidator\=org.eclipse.wst.xsd.core.internal.validation.eclipse.Validator; +USER_BUILD_PREFERENCE=enabledBuildValidatorListorg.eclipse.wst.xml.core.internal.validation.eclipse.Validator;org.eclipse.wst.wsi.ui.internal.WSIMessageValidator;org.eclipse.wst.dtd.core.internal.validation.eclipse.Validator;org.eclipse.wst.xsd.core.internal.validation.eclipse.XSDDelegatingValidator;org.eclipse.wst.wsdl.validation.internal.eclipse.WSDLDelegatingValidator;org.eclipse.wst.html.internal.validation.HTMLValidator; +USER_MANUAL_PREFERENCE=enabledManualValidatorListorg.eclipse.wst.xml.core.internal.validation.eclipse.Validator;org.eclipse.wst.wsi.ui.internal.WSIMessageValidator;org.eclipse.wst.dtd.core.internal.validation.eclipse.Validator;org.eclipse.wst.xsd.core.internal.validation.eclipse.XSDDelegatingValidator;org.eclipse.wst.wsdl.validation.internal.eclipse.WSDLDelegatingValidator;org.eclipse.wst.html.internal.validation.HTMLValidator; +USER_PREFERENCE=overrideGlobalPreferencesfalse +eclipse.preferences.version=1 diff --git a/AspectC++/ACConfig.cc b/AspectC++/ACConfig.cc new file mode 100644 index 0000000..a2ef9f8 --- /dev/null +++ b/AspectC++/ACConfig.cc @@ -0,0 +1,480 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 + +// C++ includes +#include +#include +using std::stringstream; +#include +using std::set; + +// PUMA includes +#include "Puma/SysCall.h" + +// Clang includes +#ifdef FRONTEND_CLANG +#include "clang/Basic/TargetInfo.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Basic/Version.h" +#else +#include "Puma/CTypeInfo.h" +#endif // FRONTEND_CLANG + +// AspectC++ includes +#include "ACConfig.h" +#include "version.h" +#include "Naming.h" + +using namespace Puma; + +static OptsParser::Option options[] = { + { ACConfig::ACOPT_VERSION, "V", "version", + "\t" "Version information", OptsParser::AT_NONE }, + { ACConfig::ACOPT_HELP, "h", "help", + "\t" "\t" "Get this help text", OptsParser::AT_NONE }, + { ACConfig::ACOPT_VERBOSE, "v", "verbose", + "\t" "Level of verbosity (0-9)", OptsParser::AT_MANDATORY }, + { ACConfig::ACOPT_COMPILE, "c", "compile", + "\t" "Name of the input file", OptsParser::AT_MANDATORY }, + { ACConfig::ACOPT_OUTPUT, "o", "output", + "\t" "Name of the output file", OptsParser::AT_MANDATORY }, + { ACConfig::ACOPT_INCLUDE_FILES, "i", "include_files", + "\t" "Generate manipulated header files", OptsParser::AT_NONE }, + { ACConfig::ACOPT_ASPECT_HEADER, "a", "aspect_header", + "Name of aspect header file or '0'", OptsParser::AT_MANDATORY }, + { ACConfig::ACOPT_REPOSITORY, "r", "repository", + "Name of the project repository", OptsParser::AT_MANDATORY }, + { ACConfig::ACOPT_EXPRESSION, "x", "expr", + "\tPointcut expression to match in repository", OptsParser::AT_MANDATORY }, + { ACConfig::ACOPT_PROBLEM_LOCAL_CLASS, NULL, "problem_local_class", + "Back-end does not support local classes correctly", OptsParser::AT_NONE }, + { ACConfig::ACOPT_NO_PROBLEM_LOCAL_CLASS, NULL, "no_problem_local_class", + "Back-end supports local classes correctly", OptsParser::AT_NONE }, + { ACConfig::ACOPT_PROBLEM_SPEC_SCOPE, NULL, + "problem_spec_scope", + "Back-end does not support template specialization in non-namespace", + OptsParser::AT_NONE }, + { ACConfig::ACOPT_NO_PROBLEM_SPEC_SCOPE, NULL, + "no_problem_spec_scope", + "Back-end supports template specialization in non-namespace scope", + OptsParser::AT_NONE }, + { ACConfig::ACOPT_PROBLEM_FORCE_INLINE, NULL, "problem_force_inline", + "Back-end does not support forced inlining correctly", OptsParser::AT_NONE }, + { ACConfig::ACOPT_NO_PROBLEM_FORCE_INLINE, NULL, "no_problem_force_inline", + "Back-end supports forced inlining correctly", OptsParser::AT_NONE }, + { ACConfig::ACOPT_NOLINE, NULL, + "no_line", + "\t" "\t" "Don't generate #line directives", + OptsParser::AT_NONE }, + { ACConfig::ACOPT_GEN_SIZE_TYPE, NULL, "gen_size_type", + "Argument type for generated new operator", OptsParser::AT_MANDATORY }, + { ACConfig::ACOPT_PROJ_FILE, NULL, "proj_file", + "\t" "Path to the project file", OptsParser::AT_MANDATORY}, + { ACConfig::ACOPT_WARN_DEPRECATED, NULL, "warn_deprecated", + "\t" "Warn if deprecated syntax is used", OptsParser::AT_NONE }, + { ACConfig::ACOPT_NO_WARN_DEPRECATED, NULL, "no_warn_deprecated", + "Don't warn if deprecated syntax is used", OptsParser::AT_NONE }, + { ACConfig::ACOPT_WARN_MACRO, NULL, "warn_macro", + "\t" "Warn if a macro transformation had to be ignored", + OptsParser::AT_NONE }, + { ACConfig::ACOPT_NO_WARN_MACRO, NULL, "no_warn_macro", + "\t" "Don't warn if a macro transformation had to be ignored", + OptsParser::AT_NONE }, + { ACConfig::ACOPT_WARN_LIMITATIONS, NULL, "warn_limitations", + "\t" "Warn if a feature does not work as familiar due to limitations", + OptsParser::AT_NONE }, + { ACConfig::ACOPT_NO_WARN_LIMITATIONS, NULL, "no_warn_limitations", + "" "Don't warn if a feature does not work as familiar due to limitations", + OptsParser::AT_NONE }, + { ACConfig::ACOPT_KEYWORDS, "k", "keywords", + "\t" "Allow AspectC++ keywords in normal project files", + OptsParser::AT_NONE }, + { ACConfig::ACOPT_DYNAMIC, 0, "dynamic", + "\t\t" "Prepare generated code for dynamic weaving", + OptsParser::AT_NONE }, + { ACConfig::ACOPT_INTROSPECTION, 0, "introspection", + "\t" "Support introspection mechanism", + OptsParser::AT_NONE }, + { ACConfig::ACOPT_FLOW_ANALYSIS, 0, "flow_analysis", + "\t" "Support control-flow analysis and data-flow analysis", + OptsParser::AT_NONE }, + { ACConfig::ACOPT_BUILTIN_OPERATORS, 0, "builtin_operators", + "Support joinpoints on builtin operator calls", + OptsParser::AT_NONE }, + { ACConfig::ACOPT_DATA_JOINPOINTS, 0, "data_joinpoints", + "\t" "Support data-based joinpoints like get(), set(), ...", + OptsParser::AT_NONE }, + { ACConfig::ACOPT_INTRODUCTION_DEPTH, 0, "introduction_depth", + "Set the maximum depth for nested introductions", OptsParser::AT_MANDATORY }, + { ACConfig::ACOPT_WARN_COMPATIBILITY, NULL, "warn_compatibility", + "Enable migration warnings for code based on major version ", + OptsParser::AT_MANDATORY }, + { ACConfig::ACOPT_ATTRIBUTES, NULL, "attributes", + "\t" "Support user-defined attributes", + OptsParser::AT_NONE }, + { ACConfig::ACOPT_NO_ATTRIBUTES, NULL, "no_attributes", + "\t" "Disable support user-defined attributes", + OptsParser::AT_NONE }, + { 0, NULL, 0, 0, OptsParser::AT_NONE } +}; + + +ACConfig::~ACConfig () { + if (_file_in) + delete[] _file_in; + if (_file_out) + delete[] _file_out; + for (int i = 0; i < _aspect_headers.length (); i++) + delete[] _aspect_headers[i]; +} + + +string ACConfig::size_type () const { + string result = _size_type; + // if the size-type string wasn't provided with the command line option + // --gen_size_type, ask the front end for its target size type. + if (result == "") { +#ifdef FRONTEND_CLANG + clang::CompilerInstance *ci = _project.get_compiler_instance (); + clang::TargetInfo &target = ci->getTarget (); + result = clang::TargetInfo::getTypeName (target.getSizeType ()); +#else + ostringstream size_type_stream; + size_type_stream << *CTypeInfo::CTYPE_SIZE_T; + result = size_type_stream.str (); +#endif + } + return result; +} + +bool ACConfig::analyze () { + + // setup defaults + _v = 0; // default verbosity without "-v" + _ifiles = false; + _file_in = (const char*)0; + _file_out = (const char*)0; + _repository = (const char*)0; + _iterate_tunits = false; + _nosave = false; + _noline = false; + _iterate_aspects = true; + + // default setting: unknown compilers have a problem with everything + _problem_local_class = true; + _problem_spec_scope = true; + _problem_force_inline = true; + if (_project.config ().Option ("--gnu") || + _project.config ().Option ("--gnu-2.95")) { + _problem_local_class = false; + _problem_force_inline = false; + } else if (_project.config ().Option ("--vc")) { + _problem_spec_scope = false; + } + _warn_deprecated = true; + _warn_macro = false; + _warn_limitations = true; + _dynamic = false; + _introspection = false; + _attributes = true; + _flow_analysis = false; + _builtin_operators = false; + _data_joinpoints = false; + _keywords = false; + _introduction_depth = 10; + _warn_compatibility = -1; + + char* tmp; + + OptsParser op (_argc, _argv, options); + + bool have_proj_file = false; + while (op.getOption () != OptsParser::FINISH) { + switch (op.getResult ()) { + case ACOPT_VERBOSE: + if (op.getArgument ().empty ()) + // -v without number + _v = 3; + else + _v = atoi (op.getArgument ().c_str ()); + break; + case ACOPT_VERSION: + cout << ac_program () << " " << ac_version () + << " (" << __DATE__; +#ifdef FRONTEND_CLANG + cout << ", clang " CLANG_VERSION_STRING; +#endif // FRONTEND_CLANG + cout << ")" << endl; + return true; + case ACOPT_HELP: + usage (_argv[0]); + return true; + case ACOPT_COMPILE: + tmp = StrCol::dup (op.getArgument ().c_str ()); +#if defined (WIN32) + SysCall::MakeUnixPath(tmp); +#endif + _file_in = tmp; + break; + case ACOPT_OUTPUT: + tmp = StrCol::dup (op.getArgument ().c_str ()); +#if defined (WIN32) + SysCall::MakeUnixPath(tmp); +#endif + _file_out = tmp; + break; + case ACOPT_INCLUDE_FILES: + _ifiles = true; + break; + case ACOPT_NOSAVE: + _nosave = true; + break; + case ACOPT_NOLINE: + _noline = true; + break; + case ACOPT_ASPECT_HEADER: + _iterate_aspects = false; + if (strcmp (op.getArgument ().c_str (), "0") != 0) { + tmp = StrCol::dup (op.getArgument ().c_str ()); +#if defined (WIN32) + SysCall::MakeUnixPath(tmp); +#endif + _aspect_headers.append (tmp); + } + break; + case ACOPT_REPOSITORY: + tmp = StrCol::dup (op.getArgument ().c_str ()); +#if defined (WIN32) + SysCall::MakeUnixPath(tmp); +#endif + _repository = tmp; + break; + case ACOPT_EXPRESSION: + _expr = op.getUnstrippedArgument (); + break; + case ACOPT_PROBLEM_LOCAL_CLASS: + _problem_local_class = true; + break; + case ACOPT_NO_PROBLEM_LOCAL_CLASS: + _problem_local_class = false; + break; + case ACOPT_PROBLEM_SPEC_SCOPE: + _problem_spec_scope = true; + break; + case ACOPT_NO_PROBLEM_SPEC_SCOPE: + _problem_spec_scope = false; + break; + case ACOPT_PROBLEM_FORCE_INLINE: + _problem_force_inline = true; + break; + case ACOPT_NO_PROBLEM_FORCE_INLINE: + _problem_force_inline = false; + break; + case ACOPT_GEN_SIZE_TYPE: + _size_type = op.getArgument ().c_str (); + break; + case ACOPT_PROJ_FILE: + have_proj_file = true; + _proj_file = op.getArgument ().c_str (); + break; + case ACOPT_WARN_DEPRECATED: + _warn_deprecated = true; + break; + case ACOPT_NO_WARN_DEPRECATED: + _warn_deprecated = false; + break; + case ACOPT_WARN_MACRO: + _warn_macro = true; + break; + case ACOPT_NO_WARN_MACRO: + _warn_macro = false; + break; + case ACOPT_WARN_LIMITATIONS: + _warn_limitations = true; + break; + case ACOPT_NO_WARN_LIMITATIONS: + _warn_limitations = false; + break; + case ACOPT_WARN_COMPATIBILITY: + _warn_compatibility = atoi (op.getArgument ().c_str ()); + break; + case ACOPT_KEYWORDS: + _keywords = true; + break; + case ACOPT_DYNAMIC: + _dynamic = true; + break; + case ACOPT_INTROSPECTION: + _introspection = true; + break; + case ACOPT_FLOW_ANALYSIS: + _flow_analysis = true; + break; +#ifdef FRONTEND_PUMA + case ACOPT_BUILTIN_OPERATORS: + case ACOPT_DATA_JOINPOINTS: + err() << sev_error << "The command line options '--builtin_operators' " + "and '--data_joinpoints' are not supported in the 'Puma' configuration." << endMessage; + return false; +#else + case ACOPT_BUILTIN_OPERATORS: + _builtin_operators = true; + break; + case ACOPT_DATA_JOINPOINTS: + _data_joinpoints = true; + break; +#endif + case ACOPT_INTRODUCTION_DEPTH: + _introduction_depth = atoi (op.getArgument ().c_str ()); + break; + case ACOPT_ATTRIBUTES: + _attributes = true; + break; + case ACOPT_NO_ATTRIBUTES: + _attributes = false; + break; + + default: + usage (_argv[0]); + err () << sev_error; + return false; + } + } + + bool have_std_prj = (_project.numPaths () > 0) && _project.src (0L); + bool have_prj = have_proj_file || have_std_prj; + bool have_dest = (_project.numPaths () > 0) && _project.dest (0L); + + // expression matching requires a repository + if (!expr().empty ()) { + if (!repository()) { + usage (_argv[0]); + err () << sev_error; + return false; + } + return true; + } + + // now check if the options make sense + if (!have_prj || (have_std_prj && have_proj_file) || + (_ifiles && (_file_in || !_project.dest (0L))) || + (_file_out && have_dest) || + (!_file_in && !_ifiles && !have_dest)) { + usage (_argv[0]); + err () << sev_error; + return false; + } + + // check option dependency + if( _data_joinpoints ) { + if( ! _builtin_operators ) { + err() << sev_warning << "--data_joinpoints internally requires --builtin_operators, please check and enable it to silence this warning!" << endMessage; + _builtin_operators = true; + } + } + + // check for the compatibility mode (iterate through the project tree) + if (!_ifiles && !_file_in && !_file_out && have_dest) + _iterate_tunits = true; + + // set reasonable default values + if (!_file_out && _file_in) + _file_out = StrCol::dup ("ac.out"); + + if (!_file_in) { + if (_file_out) + _file_in = StrCol::dup (_file_out); + else { + stringstream genfile; + if (_project.src (0L)) + genfile << _project.src (0L); + genfile << "ac_gen." << extension (); + _file_in = StrCol::dup (genfile.str ().data ()); + } + } + + // determine a string that uniquely identifies the project + if (have_std_prj) { // a normal project with one or more -p options + set paths; + for (long i = 0L; i < _project.numPaths (); i++) { + Filename canon; + SysCall::canonical (_project.src(i), canon); + ostringstream name; + Naming::mangle_file (name, canon.name ()); + paths.insert (name.str ()); + } + _project_id = *paths.begin (); + } + else { // used a project file + + // load the project file and set up the project + if (!_project.loadProject (_proj_file)) { + err () << sev_error << "failed to load project file '" + << _proj_file.c_str () << "'" << endMessage; + return false; + } + Filename canon; + SysCall::canonical (_proj_file.c_str (), canon); + ostringstream name; + Naming::mangle_file (name, canon.name ()); + _project_id = name.str (); + } + + // TODO: this should be obsolete -> check it + _project.config ().Add ("--lang-ac++"); + _project.configure (_project.config ()); + + + return true; +} + +void ACConfig::usage (const char *prog) const { + cerr << "usage: " << prog << " options" << endl + << " options are ..." << endl; + cerr << " -p|--path \t\t" << "project directory tree" << endl + << " -d|--dest \t\t" << "target directory tree" << endl + << " -e|--extension \t" << "translation unit filename ext." + << endl; + for (int o = 0; options[o].number > 0; o++) { + cerr << " "; + if (options[o].shortName) cerr << "-" << options[o].shortName; + if (options[o].shortName && options[o].longName) cerr << "|"; + if (options[o].longName) cerr << "--" << options[o].longName; + if (options[o].argType != OptsParser::AT_NONE) cerr << " "; + if (options[o].desc) cerr << "\t" << options[o].desc; + cerr << endl; + } + cerr << " further options for correct parsing are ..." << endl + << " -I \t\t\t" << "include file search path" << endl + << " -D [=]\t" << "macro definitions" << endl; +} + + +// get the extension string for cc files + +const char *ACConfig::extension () { + for (unsigned i = _project.config ().Options (); i > 0; i--) { + const ConfOption *o = _project.config ().Option (i-1); + if (! strcmp (o->Name (), "-e") || ! strcmp (o->Name (), "--extension")) { + if (! o->Arguments ()) + continue; + return o->Argument (0); + } + } + return "cc"; +} diff --git a/AspectC++/ACConfig.h b/AspectC++/ACConfig.h new file mode 100644 index 0000000..86590dc --- /dev/null +++ b/AspectC++/ACConfig.h @@ -0,0 +1,147 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __ACConfig_h__ +#define __ACConfig_h__ + +// C++ includes +#include +#include +using namespace std; + +// PUMA includes +#include "Puma/Array.h" + +// Aspect C++ includes +#include "ACProject.h" + +class ACConfig { + ACProject &_project; + int _argc; + char **_argv; + + // analysis results + int _v; + const char *_file_in; + const char *_file_out; + const char *_repository; + string _expr; + bool _ifiles; + bool _iterate_tunits; + bool _nosave; + bool _noline; + Puma::Array _aspect_headers; // TODO: get rid of Puma dependency here + bool _iterate_aspects; + bool _problem_local_class; + bool _problem_spec_scope; + bool _problem_force_inline; + string _size_type; + string _project_id; + string _proj_file; + bool _warn_deprecated; + bool _warn_macro; + bool _warn_limitations; + bool _dynamic; + bool _introspection; + bool _attributes; + bool _flow_analysis; + bool _builtin_operators; + bool _data_joinpoints; + bool _keywords; + int _introduction_depth; + int _warn_compatibility; + +public: + + enum { + ACOPT_VERBOSE=1, ACOPT_VERSION, ACOPT_HELP, + ACOPT_COMPILE, ACOPT_OUTPUT, + ACOPT_INCLUDE_FILES, ACOPT_NOSAVE, ACOPT_ASPECT_HEADER, + ACOPT_REPOSITORY, ACOPT_EXPRESSION, ACOPT_NOLINE, + ACOPT_PROBLEM_LOCAL_CLASS, ACOPT_NO_PROBLEM_LOCAL_CLASS, + ACOPT_PROBLEM_SPEC_SCOPE, ACOPT_NO_PROBLEM_SPEC_SCOPE, + ACOPT_PROBLEM_FORCE_INLINE, ACOPT_NO_PROBLEM_FORCE_INLINE, + ACOPT_GEN_SIZE_TYPE, ACOPT_PROJ_FILE, + ACOPT_WARN_DEPRECATED, ACOPT_NO_WARN_DEPRECATED, + ACOPT_WARN_MACRO, ACOPT_NO_WARN_MACRO, + ACOPT_WARN_COMPATIBILITY, + ACOPT_WARN_LIMITATIONS, ACOPT_NO_WARN_LIMITATIONS, + ACOPT_KEYWORDS, ACOPT_DYNAMIC, ACOPT_INTROSPECTION, + ACOPT_INTRODUCTION_DEPTH, ACOPT_FLOW_ANALYSIS, + ACOPT_BUILTIN_OPERATORS, ACOPT_DATA_JOINPOINTS, + ACOPT_ATTRIBUTES, ACOPT_NO_ATTRIBUTES + }; + + ACConfig (ACProject &project, int argc, char** argv) : + _project (project), _argc (argc), _argv (argv), + _file_in (0), _file_out (0), _repository (0) {} + ~ACConfig (); + + // analyze the command line arguments + // result: 'false' means that the user provided invalid arguments + bool analyze (); + + // get file default cc file extension + const char *extension (); + + // get the associated ACProject + ACProject &project () const { return _project; } + + // get the analysis results + int verbose () const { return _v; } + const char *file_in () const { return _file_in; } + const char *file_out () const { return _file_out; } + bool ifiles () const { return _ifiles; } + bool iterate () const { return _iterate_tunits; } + bool nosave () const { return _nosave; } + bool noline () const { return _noline; } + bool iterate_aspects () const { return _iterate_aspects; } + int aspect_headers () const { return _aspect_headers.length (); } + const char *aspect_header (int i) const { + return _aspect_headers.lookup (i); + } + const char *repository () const { return _repository; } + const string &expr () const { return _expr; } + bool problem_local_class () const { return _problem_local_class; } + bool problem_spec_scope () const { return _problem_spec_scope; } + bool problem_force_inline () const { return _problem_force_inline; } + string size_type () const; + string project_id () const { return _project_id; } + string proj_file () const { return _proj_file; } + bool warn_deprecated () const { return _warn_deprecated; } + bool warn_macro () const { return _warn_macro; } + int warn_compatibility () const { return _warn_compatibility; } + bool warn_limitations () const { return _warn_limitations; } + bool dynamic () const { return _dynamic; } + bool introspection () const { return _introspection; } + bool attributes () const {return _attributes; } + bool flow_analysis() const { return _flow_analysis; } + bool builtin_operators() const { return _builtin_operators; } + bool data_joinpoints() const { return _data_joinpoints; } + bool keywords () const { return _keywords; } + int introduction_depth () const { return _introduction_depth; } + +private: + // print a usage message + void usage (const char *) const; + + // get the error stream of the project + ACErrorStream &err () const { return _project.err (); } +}; + +#endif // __ACConfig_h__ diff --git a/AspectC++/ACErrorStream.h b/AspectC++/ACErrorStream.h new file mode 100644 index 0000000..e7c8a2a --- /dev/null +++ b/AspectC++/ACErrorStream.h @@ -0,0 +1,36 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __ac_error_stream_h__ +#define __ac_error_stream_h__ + +// class alias for frontend-specific include expander implementation + +#ifdef FRONTEND_PUMA + +#include "Puma/ErrorStream.h" +typedef Puma::ErrorStream ACErrorStream; + +#else // FRONTEND_CLANG + +#include "ClangErrorStream.h" +typedef ClangErrorStream ACErrorStream; + +#endif + +#endif // __ac_error_stream_h__ diff --git a/AspectC++/ACFileID.h b/AspectC++/ACFileID.h new file mode 100644 index 0000000..46c6340 --- /dev/null +++ b/AspectC++/ACFileID.h @@ -0,0 +1,57 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2013 The 'ac++' developers (see aspectc.org) +// +// 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 __ACFileID_h__ +#define __ACFileID_h__ + +#include + +#ifdef FRONTEND_PUMA +#include "Puma/Unit.h" +typedef const Puma::Unit *ACFileIDData; +#else + +#include "clang/Basic/FileManager.h" +typedef const clang::FileEntry *ACFileIDData; +#endif + +// A wrapper class that only allows to take the filename from a unit. +class ACFileID { + + ACFileIDData _entry; + +public: + + ACFileID () : _entry(0) {} + ACFileID (ACFileIDData entry) : _entry (entry) {} + + std::string name () const { +#ifdef FRONTEND_PUMA + return _entry->name (); +#else + return _entry->getName (); +#endif + } + bool is_valid () const { return _entry != 0; } + bool operator== (ACFileID rhs) const { return _entry == rhs._entry; } + bool operator!= (ACFileID rhs) const { return !operator==(rhs); } + bool operator< (ACFileID rhs) const { return _entry < rhs._entry; } + ACFileIDData file_entry() const { return _entry; } +}; + +#endif // __ACFileID_h__ diff --git a/AspectC++/ACIntroducer.h b/AspectC++/ACIntroducer.h new file mode 100644 index 0000000..fdefb5b --- /dev/null +++ b/AspectC++/ACIntroducer.h @@ -0,0 +1,36 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __ac_introducer_h__ +#define __ac_introducer_h__ + +// class alias for frontend-specific introducer implementation + +#ifdef FRONTEND_PUMA + +#include "PumaIntroducer.h" +typedef PumaIntroducer ACIntroducer; + +#else // FRONTEND_CLANG + +#include "ClangIntroducer.h" +typedef ClangIntroducer ACIntroducer; + +#endif + +#endif // __ac_introducer_h__ diff --git a/AspectC++/ACModel/Elements.cc b/AspectC++/ACModel/Elements.cc new file mode 100644 index 0000000..48cda3d --- /dev/null +++ b/AspectC++/ACModel/Elements.cc @@ -0,0 +1,3635 @@ + +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "Elements.h" +#include +using std::cout; +using std::endl; +#include +using std::ostringstream; + +std::string ACM_Node::key () const { + std::string result; + result = type_str (); + result += "|"; + return result; +} +std::string ACM_File::key () const { + std::string result; + result += ACM_Node::key (); + std::ostringstream str_filename_; + str_filename_ << filename_; + result += str_filename_.str() + "|"; + return result; +} +std::string ACM_TUnit::key () const { + std::string result; + result += ACM_File::key (); + return result; +} +std::string ACM_Header::key () const { + std::string result; + result += ACM_File::key (); + return result; +} +std::string ACM_Source::key () const { + std::string result; + result += ACM_Node::key (); + std::ostringstream str_kind_; + str_kind_ << kind_; + result += str_kind_.str() + "|"; + result += file_->key (); + std::ostringstream str_line_; + str_line_ << line_; + result += str_line_.str() + "|"; + return result; +} +std::string ACM_MemberIntro::key () const { + std::string result; + result += ACM_Node::key (); + result += intro_->key (); + return result; +} +std::string ACM_BaseIntro::key () const { + std::string result; + result += ACM_Node::key (); + result += intro_->key (); + return result; +} +std::string ACM_ClassPlan::key () const { + std::string result; + result += ACM_Node::key (); + return result; +} +std::string ACM_CodeAdvice::key () const { + std::string result; + result += ACM_Node::key (); + result += advice_->key (); + return result; +} +std::string ACM_CodePlan::key () const { + std::string result; + result += ACM_Node::key (); + return result; +} +std::string ACM_Any::key () const { + std::string result; + result += ACM_Node::key (); + return result; +} +std::string ACM_Type::key () const { + std::string result; + result += ACM_Any::key (); + std::ostringstream str_signature_; + str_signature_ << signature_; + result += str_signature_.str() + "|"; + return result; +} +std::string ACM_Arg::key () const { + std::string result; + result += ACM_Any::key (); + std::ostringstream str_name_; + str_name_ << name_; + result += str_name_.str() + "|"; + return result; +} +std::string ACM_Name::key () const { + std::string result; + result += ACM_Any::key (); + std::ostringstream str_name_; + str_name_ << name_; + result += str_name_.str() + "|"; + return result; +} +std::string ACM_Namespace::key () const { + std::string result; + result += ACM_Name::key (); + return result; +} +std::string ACM_Function::key () const { + std::string result; + result += ACM_Name::key (); + result += arg_types_.key (); + std::ostringstream str_cv_qualifiers_; + str_cv_qualifiers_ << cv_qualifiers_; + result += str_cv_qualifiers_.str() + "|"; + if (has_static_in ()) result += static_in_->key (); else result += "-|"; + return result; +} +std::string ACM_Variable::key () const { + std::string result; + result += ACM_Name::key (); + return result; +} +std::string ACM_Class::key () const { + std::string result; + result += ACM_Name::key (); + return result; +} +std::string ACM_ClassSlice::key () const { + std::string result; + result += ACM_Name::key (); + return result; +} +std::string ACM_Code::key () const { + std::string result; + result += ACM_Any::key (); + return result; +} +std::string ACM_Access::key () const { + std::string result; + result += ACM_Code::key (); + std::ostringstream str_lid_; + str_lid_ << lid_; + result += str_lid_.str() + "|"; + return result; +} +std::string ACM_Get::key () const { + std::string result; + result += ACM_Access::key (); + return result; +} +std::string ACM_Set::key () const { + std::string result; + result += ACM_Access::key (); + return result; +} +std::string ACM_Call::key () const { + std::string result; + result += ACM_Access::key (); + return result; +} +std::string ACM_Builtin::key () const { + std::string result; + result += ACM_Access::key (); + return result; +} +std::string ACM_Ref::key () const { + std::string result; + result += ACM_Access::key (); + return result; +} +std::string ACM_GetRef::key () const { + std::string result; + result += ACM_Access::key (); + return result; +} +std::string ACM_SetRef::key () const { + std::string result; + result += ACM_Access::key (); + return result; +} +std::string ACM_CallRef::key () const { + std::string result; + result += ACM_Access::key (); + return result; +} +std::string ACM_Execution::key () const { + std::string result; + result += ACM_Code::key (); + return result; +} +std::string ACM_Construction::key () const { + std::string result; + result += ACM_Code::key (); + return result; +} +std::string ACM_Destruction::key () const { + std::string result; + result += ACM_Code::key (); + return result; +} +std::string ACM_Pointcut::key () const { + std::string result; + result += ACM_Name::key (); + result += args_.key (); + return result; +} +std::string ACM_Attribute::key () const { + std::string result; + result += ACM_Name::key (); + result += args_.key (); + return result; +} +std::string ACM_Advice::key () const { + std::string result; + result += ACM_Any::key (); + std::ostringstream str_lid_; + str_lid_ << lid_; + result += str_lid_.str() + "|"; + return result; +} +std::string ACM_AdviceCode::key () const { + std::string result; + result += ACM_Advice::key (); + return result; +} +std::string ACM_Introduction::key () const { + std::string result; + result += ACM_Advice::key (); + return result; +} +std::string ACM_Order::key () const { + std::string result; + result += ACM_Advice::key (); + return result; +} +std::string ACM_Aspect::key () const { + std::string result; + result += ACM_Class::key (); + return result; +} +std::string ACM_Speculation::key () const { + std::string result; + result += ACM_Node::key (); + result += advice_->key (); + result += tunit_->key (); + return result; +} +std::string ACM_Model::key () const { + std::string result; + result += ACM_Node::key (); + return result; +} + + +void ACM_Node::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "Node (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_Node::dump_attr (std::ostream &out) const { +} + +void ACM_Node::dump_refs (std::ostream &out) const { +} + +void ACM_Node::dump_aggr (std::ostream &out, int indent) const { +} + +void ACM_File::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "File (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_File::dump_attr (std::ostream &out) const { + out << " filename=" << "\"" << filename_ << "\""; + out << " len=" << len_; + out << " time=" << time_; + ACM_Node::dump_attr (out); +} + +void ACM_File::dump_refs (std::ostream &out) const { + ACM_Node::dump_refs (out); +} + +void ACM_File::dump_aggr (std::ostream &out, int indent) const { + ACM_Node::dump_aggr (out, indent); +} + +void ACM_TUnit::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "TUnit (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_TUnit::dump_attr (std::ostream &out) const { + out << " dirty_flag=" << dirty_flag_; + ACM_File::dump_attr (out); +} + +void ACM_TUnit::dump_refs (std::ostream &out) const { + ACM_File::dump_refs (out); +} + +void ACM_TUnit::dump_aggr (std::ostream &out, int indent) const { + ACM_File::dump_aggr (out, indent); +} + +void ACM_Header::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "Header (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_Header::dump_attr (std::ostream &out) const { + ACM_File::dump_attr (out); +} + +void ACM_Header::dump_refs (std::ostream &out) const { + out << " in ="; + for (ACM_Container ::const_iterator i = in_.begin(); i != in_.end(); ++i) + out << " " << (void*)(*i); + ACM_File::dump_refs (out); +} + +void ACM_Header::dump_aggr (std::ostream &out, int indent) const { + ACM_File::dump_aggr (out, indent); +} + +void ACM_Source::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "Source (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_Source::dump_attr (std::ostream &out) const { + out << " kind=" << kind_; + out << " line=" << line_; + out << " len=" << len_; + ACM_Node::dump_attr (out); +} + +void ACM_Source::dump_refs (std::ostream &out) const { + out << " file ="; + out << " " << (void*)file_; + ACM_Node::dump_refs (out); +} + +void ACM_Source::dump_aggr (std::ostream &out, int indent) const { + ACM_Node::dump_aggr (out, indent); +} + +void ACM_MemberIntro::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "MemberIntro (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_MemberIntro::dump_attr (std::ostream &out) const { + ACM_Node::dump_attr (out); +} + +void ACM_MemberIntro::dump_refs (std::ostream &out) const { + out << " intro ="; + out << " " << (void*)intro_; + out << " members ="; + for (ACM_Container ::const_iterator i = members_.begin(); i != members_.end(); ++i) + out << " " << (void*)(*i); + ACM_Node::dump_refs (out); +} + +void ACM_MemberIntro::dump_aggr (std::ostream &out, int indent) const { + ACM_Node::dump_aggr (out, indent); +} + +void ACM_BaseIntro::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "BaseIntro (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_BaseIntro::dump_attr (std::ostream &out) const { + ACM_Node::dump_attr (out); +} + +void ACM_BaseIntro::dump_refs (std::ostream &out) const { + out << " intro ="; + out << " " << (void*)intro_; + out << " bases ="; + for (ACM_Container ::const_iterator i = bases_.begin(); i != bases_.end(); ++i) + out << " " << (void*)(*i); + ACM_Node::dump_refs (out); +} + +void ACM_BaseIntro::dump_aggr (std::ostream &out, int indent) const { + ACM_Node::dump_aggr (out, indent); +} + +void ACM_ClassPlan::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "ClassPlan (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_ClassPlan::dump_attr (std::ostream &out) const { + ACM_Node::dump_attr (out); +} + +void ACM_ClassPlan::dump_refs (std::ostream &out) const { + ACM_Node::dump_refs (out); +} + +void ACM_ClassPlan::dump_aggr (std::ostream &out, int indent) const { + for (ACM_Container ::const_iterator i = base_intros_.begin(); i != base_intros_.end(); ++i) + (*i)->dump (out, indent + 1); + for (ACM_Container ::const_iterator i = member_intros_.begin(); i != member_intros_.end(); ++i) + (*i)->dump (out, indent + 1); + ACM_Node::dump_aggr (out, indent); +} + +void ACM_CodeAdvice::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "CodeAdvice (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_CodeAdvice::dump_attr (std::ostream &out) const { + out << " conditional=" << conditional_; + ACM_Node::dump_attr (out); +} + +void ACM_CodeAdvice::dump_refs (std::ostream &out) const { + out << " advice ="; + out << " " << (void*)advice_; + ACM_Node::dump_refs (out); +} + +void ACM_CodeAdvice::dump_aggr (std::ostream &out, int indent) const { + ACM_Node::dump_aggr (out, indent); +} + +void ACM_CodePlan::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "CodePlan (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_CodePlan::dump_attr (std::ostream &out) const { + ACM_Node::dump_attr (out); +} + +void ACM_CodePlan::dump_refs (std::ostream &out) const { + ACM_Node::dump_refs (out); +} + +void ACM_CodePlan::dump_aggr (std::ostream &out, int indent) const { + for (ACM_Container ::const_iterator i = before_.begin(); i != before_.end(); ++i) + (*i)->dump (out, indent + 1); + if (has_around ()) + around_->dump (out, indent + 1); + for (ACM_Container ::const_iterator i = after_.begin(); i != after_.end(); ++i) + (*i)->dump (out, indent + 1); + if (has_next_level ()) + next_level_->dump (out, indent + 1); + ACM_Node::dump_aggr (out, indent); +} + +void ACM_Any::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "Any (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_Any::dump_attr (std::ostream &out) const { + if (has_jpid ()) + out << " jpid=" << jpid_; + ACM_Node::dump_attr (out); +} + +void ACM_Any::dump_refs (std::ostream &out) const { + out << " attributes ="; + for (ACM_Container ::const_iterator i = attributes_.begin(); i != attributes_.end(); ++i) + out << " " << (void*)(*i); + ACM_Node::dump_refs (out); +} + +void ACM_Any::dump_aggr (std::ostream &out, int indent) const { + for (ACM_Container ::const_iterator i = source_.begin(); i != source_.end(); ++i) + (*i)->dump (out, indent + 1); + ACM_Node::dump_aggr (out, indent); +} + +void ACM_Type::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "Type (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_Type::dump_attr (std::ostream &out) const { + out << " signature=" << "\"" << signature_ << "\""; + out << " match_sig=" << match_sig_; + ACM_Any::dump_attr (out); +} + +void ACM_Type::dump_refs (std::ostream &out) const { + ACM_Any::dump_refs (out); +} + +void ACM_Type::dump_aggr (std::ostream &out, int indent) const { + ACM_Any::dump_aggr (out, indent); +} + +void ACM_Arg::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "Arg (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_Arg::dump_attr (std::ostream &out) const { + out << " type=" << "\"" << type_ << "\""; + out << " name=" << "\"" << name_ << "\""; + ACM_Any::dump_attr (out); +} + +void ACM_Arg::dump_refs (std::ostream &out) const { + ACM_Any::dump_refs (out); +} + +void ACM_Arg::dump_aggr (std::ostream &out, int indent) const { + ACM_Any::dump_aggr (out, indent); +} + +void ACM_Name::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "Name (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_Name::dump_attr (std::ostream &out) const { + out << " name=" << "\"" << name_ << "\""; + out << " match_sig=" << match_sig_; + out << " name_map=" << name_map_; + out << " builtin=" << builtin_; + ACM_Any::dump_attr (out); +} + +void ACM_Name::dump_refs (std::ostream &out) const { + out << " tunits ="; + for (ACM_Container ::const_iterator i = tunits_.begin(); i != tunits_.end(); ++i) + out << " " << (void*)(*i); + ACM_Any::dump_refs (out); +} + +void ACM_Name::dump_aggr (std::ostream &out, int indent) const { + for (ACM_Container ::const_iterator i = children_.begin(); i != children_.end(); ++i) + (*i)->dump (out, indent + 1); + ACM_Any::dump_aggr (out, indent); +} + +void ACM_Namespace::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "Namespace (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_Namespace::dump_attr (std::ostream &out) const { + ACM_Name::dump_attr (out); +} + +void ACM_Namespace::dump_refs (std::ostream &out) const { + ACM_Name::dump_refs (out); +} + +void ACM_Namespace::dump_aggr (std::ostream &out, int indent) const { + ACM_Name::dump_aggr (out, indent); +} + +void ACM_Function::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "Function (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_Function::dump_attr (std::ostream &out) const { + out << " kind=" << kind_; + out << " variadic_args=" << variadic_args_; + out << " cv_qualifiers=" << cv_qualifiers_; + ACM_Name::dump_attr (out); +} + +void ACM_Function::dump_refs (std::ostream &out) const { + out << " static_in ="; + out << " " << (void*)static_in_; + out << " calls ="; + for (ACM_Container ::const_iterator i = calls_.begin(); i != calls_.end(); ++i) + out << " " << (void*)(*i); + ACM_Name::dump_refs (out); +} + +void ACM_Function::dump_aggr (std::ostream &out, int indent) const { + if (has_result_type ()) + result_type_->dump (out, indent + 1); + for (ACM_Container ::const_iterator i = arg_types_.begin(); i != arg_types_.end(); ++i) + (*i)->dump (out, indent + 1); + ACM_Name::dump_aggr (out, indent); +} + +void ACM_Variable::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "Variable (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_Variable::dump_attr (std::ostream &out) const { + out << " kind=" << kind_; + ACM_Name::dump_attr (out); +} + +void ACM_Variable::dump_refs (std::ostream &out) const { + ACM_Name::dump_refs (out); +} + +void ACM_Variable::dump_aggr (std::ostream &out, int indent) const { + type_->dump (out, indent + 1); + ACM_Name::dump_aggr (out, indent); +} + +void ACM_Class::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "Class (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_Class::dump_attr (std::ostream &out) const { + out << " intro_target=" << intro_target_; + ACM_Name::dump_attr (out); +} + +void ACM_Class::dump_refs (std::ostream &out) const { + out << " bases ="; + for (ACM_Container ::const_iterator i = bases_.begin(); i != bases_.end(); ++i) + out << " " << (void*)(*i); + out << " derived ="; + for (ACM_Container ::const_iterator i = derived_.begin(); i != derived_.end(); ++i) + out << " " << (void*)(*i); + ACM_Name::dump_refs (out); +} + +void ACM_Class::dump_aggr (std::ostream &out, int indent) const { + if (has_plan ()) + plan_->dump (out, indent + 1); + ACM_Name::dump_aggr (out, indent); +} + +void ACM_ClassSlice::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "ClassSlice (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_ClassSlice::dump_attr (std::ostream &out) const { + out << " is_struct=" << is_struct_; + ACM_Name::dump_attr (out); +} + +void ACM_ClassSlice::dump_refs (std::ostream &out) const { + ACM_Name::dump_refs (out); +} + +void ACM_ClassSlice::dump_aggr (std::ostream &out, int indent) const { + ACM_Name::dump_aggr (out, indent); +} + +void ACM_Code::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "Code (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_Code::dump_attr (std::ostream &out) const { + ACM_Any::dump_attr (out); +} + +void ACM_Code::dump_refs (std::ostream &out) const { + ACM_Any::dump_refs (out); +} + +void ACM_Code::dump_aggr (std::ostream &out, int indent) const { + if (has_plan ()) + plan_->dump (out, indent + 1); + ACM_Any::dump_aggr (out, indent); +} + +void ACM_Access::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "Access (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_Access::dump_attr (std::ostream &out) const { + out << " lid=" << lid_; + if (has_target_object_lid ()) + out << " target_object_lid=" << target_object_lid_; + if (has_cfg_block_lid ()) + out << " cfg_block_lid=" << cfg_block_lid_; + ACM_Code::dump_attr (out); +} + +void ACM_Access::dump_refs (std::ostream &out) const { + out << " target_class ="; + out << " " << (void*)target_class_; + ACM_Code::dump_refs (out); +} + +void ACM_Access::dump_aggr (std::ostream &out, int indent) const { + ACM_Code::dump_aggr (out, indent); +} + +void ACM_Get::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "Get (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_Get::dump_attr (std::ostream &out) const { + ACM_Access::dump_attr (out); +} + +void ACM_Get::dump_refs (std::ostream &out) const { + out << " variable ="; + out << " " << (void*)variable_; + ACM_Access::dump_refs (out); +} + +void ACM_Get::dump_aggr (std::ostream &out, int indent) const { + ACM_Access::dump_aggr (out, indent); +} + +void ACM_Set::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "Set (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_Set::dump_attr (std::ostream &out) const { + ACM_Access::dump_attr (out); +} + +void ACM_Set::dump_refs (std::ostream &out) const { + out << " variable ="; + out << " " << (void*)variable_; + ACM_Access::dump_refs (out); +} + +void ACM_Set::dump_aggr (std::ostream &out, int indent) const { + ACM_Access::dump_aggr (out, indent); +} + +void ACM_Call::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "Call (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_Call::dump_attr (std::ostream &out) const { + if (has_default_args ()) + out << " default_args=" << default_args_; + ACM_Access::dump_attr (out); +} + +void ACM_Call::dump_refs (std::ostream &out) const { + out << " target ="; + out << " " << (void*)target_; + ACM_Access::dump_refs (out); +} + +void ACM_Call::dump_aggr (std::ostream &out, int indent) const { + for (ACM_Container ::const_iterator i = variadic_arg_types_.begin(); i != variadic_arg_types_.end(); ++i) + (*i)->dump (out, indent + 1); + ACM_Access::dump_aggr (out, indent); +} + +void ACM_Builtin::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "Builtin (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_Builtin::dump_attr (std::ostream &out) const { + ACM_Access::dump_attr (out); +} + +void ACM_Builtin::dump_refs (std::ostream &out) const { + out << " target ="; + out << " " << (void*)target_; + ACM_Access::dump_refs (out); +} + +void ACM_Builtin::dump_aggr (std::ostream &out, int indent) const { + for (ACM_Container ::const_iterator i = implicit_access_.begin(); i != implicit_access_.end(); ++i) + (*i)->dump (out, indent + 1); + ACM_Access::dump_aggr (out, indent); +} + +void ACM_Ref::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "Ref (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_Ref::dump_attr (std::ostream &out) const { + ACM_Access::dump_attr (out); +} + +void ACM_Ref::dump_refs (std::ostream &out) const { + out << " variable ="; + out << " " << (void*)variable_; + ACM_Access::dump_refs (out); +} + +void ACM_Ref::dump_aggr (std::ostream &out, int indent) const { + type_->dump (out, indent + 1); + ACM_Access::dump_aggr (out, indent); +} + +void ACM_GetRef::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "GetRef (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_GetRef::dump_attr (std::ostream &out) const { + ACM_Access::dump_attr (out); +} + +void ACM_GetRef::dump_refs (std::ostream &out) const { + ACM_Access::dump_refs (out); +} + +void ACM_GetRef::dump_aggr (std::ostream &out, int indent) const { + type_->dump (out, indent + 1); + ACM_Access::dump_aggr (out, indent); +} + +void ACM_SetRef::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "SetRef (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_SetRef::dump_attr (std::ostream &out) const { + ACM_Access::dump_attr (out); +} + +void ACM_SetRef::dump_refs (std::ostream &out) const { + ACM_Access::dump_refs (out); +} + +void ACM_SetRef::dump_aggr (std::ostream &out, int indent) const { + type_->dump (out, indent + 1); + ACM_Access::dump_aggr (out, indent); +} + +void ACM_CallRef::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "CallRef (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_CallRef::dump_attr (std::ostream &out) const { + ACM_Access::dump_attr (out); +} + +void ACM_CallRef::dump_refs (std::ostream &out) const { + ACM_Access::dump_refs (out); +} + +void ACM_CallRef::dump_aggr (std::ostream &out, int indent) const { + type_->dump (out, indent + 1); + ACM_Access::dump_aggr (out, indent); +} + +void ACM_Execution::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "Execution (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_Execution::dump_attr (std::ostream &out) const { + ACM_Code::dump_attr (out); +} + +void ACM_Execution::dump_refs (std::ostream &out) const { + ACM_Code::dump_refs (out); +} + +void ACM_Execution::dump_aggr (std::ostream &out, int indent) const { + ACM_Code::dump_aggr (out, indent); +} + +void ACM_Construction::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "Construction (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_Construction::dump_attr (std::ostream &out) const { + ACM_Code::dump_attr (out); +} + +void ACM_Construction::dump_refs (std::ostream &out) const { + ACM_Code::dump_refs (out); +} + +void ACM_Construction::dump_aggr (std::ostream &out, int indent) const { + ACM_Code::dump_aggr (out, indent); +} + +void ACM_Destruction::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "Destruction (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_Destruction::dump_attr (std::ostream &out) const { + ACM_Code::dump_attr (out); +} + +void ACM_Destruction::dump_refs (std::ostream &out) const { + ACM_Code::dump_refs (out); +} + +void ACM_Destruction::dump_aggr (std::ostream &out, int indent) const { + ACM_Code::dump_aggr (out, indent); +} + +void ACM_Pointcut::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "Pointcut (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_Pointcut::dump_attr (std::ostream &out) const { + out << " expr=" << "\"" << expr_ << "\""; + out << " kind=" << kind_; + out << " parsed_expr=" << parsed_expr_; + ACM_Name::dump_attr (out); +} + +void ACM_Pointcut::dump_refs (std::ostream &out) const { + ACM_Name::dump_refs (out); +} + +void ACM_Pointcut::dump_aggr (std::ostream &out, int indent) const { + for (ACM_Container ::const_iterator i = args_.begin(); i != args_.end(); ++i) + (*i)->dump (out, indent + 1); + ACM_Name::dump_aggr (out, indent); +} + +void ACM_Attribute::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "Attribute (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_Attribute::dump_attr (std::ostream &out) const { + ACM_Name::dump_attr (out); +} + +void ACM_Attribute::dump_refs (std::ostream &out) const { + ACM_Name::dump_refs (out); +} + +void ACM_Attribute::dump_aggr (std::ostream &out, int indent) const { + for (ACM_Container ::const_iterator i = args_.begin(); i != args_.end(); ++i) + (*i)->dump (out, indent + 1); + ACM_Name::dump_aggr (out, indent); +} + +void ACM_Advice::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "Advice (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_Advice::dump_attr (std::ostream &out) const { + out << " lid=" << lid_; + ACM_Any::dump_attr (out); +} + +void ACM_Advice::dump_refs (std::ostream &out) const { + ACM_Any::dump_refs (out); +} + +void ACM_Advice::dump_aggr (std::ostream &out, int indent) const { + pointcut_->dump (out, indent + 1); + ACM_Any::dump_aggr (out, indent); +} + +void ACM_AdviceCode::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "AdviceCode (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_AdviceCode::dump_attr (std::ostream &out) const { + out << " kind=" << kind_; + out << " context=" << context_; + ACM_Advice::dump_attr (out); +} + +void ACM_AdviceCode::dump_refs (std::ostream &out) const { + ACM_Advice::dump_refs (out); +} + +void ACM_AdviceCode::dump_aggr (std::ostream &out, int indent) const { + ACM_Advice::dump_aggr (out, indent); +} + +void ACM_Introduction::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "Introduction (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_Introduction::dump_attr (std::ostream &out) const { + ACM_Advice::dump_attr (out); +} + +void ACM_Introduction::dump_refs (std::ostream &out) const { + out << " named_slice ="; + out << " " << (void*)named_slice_; + ACM_Advice::dump_refs (out); +} + +void ACM_Introduction::dump_aggr (std::ostream &out, int indent) const { + if (has_anon_slice ()) + anon_slice_->dump (out, indent + 1); + ACM_Advice::dump_aggr (out, indent); +} + +void ACM_Order::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "Order (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_Order::dump_attr (std::ostream &out) const { + ACM_Advice::dump_attr (out); +} + +void ACM_Order::dump_refs (std::ostream &out) const { + ACM_Advice::dump_refs (out); +} + +void ACM_Order::dump_aggr (std::ostream &out, int indent) const { + for (ACM_Container ::const_iterator i = aspect_exprs_.begin(); i != aspect_exprs_.end(); ++i) + (*i)->dump (out, indent + 1); + ACM_Advice::dump_aggr (out, indent); +} + +void ACM_Aspect::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "Aspect (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_Aspect::dump_attr (std::ostream &out) const { + ACM_Class::dump_attr (out); +} + +void ACM_Aspect::dump_refs (std::ostream &out) const { + ACM_Class::dump_refs (out); +} + +void ACM_Aspect::dump_aggr (std::ostream &out, int indent) const { + for (ACM_Container ::const_iterator i = intros_.begin(); i != intros_.end(); ++i) + (*i)->dump (out, indent + 1); + for (ACM_Container ::const_iterator i = advices_.begin(); i != advices_.end(); ++i) + (*i)->dump (out, indent + 1); + for (ACM_Container ::const_iterator i = orders_.begin(); i != orders_.end(); ++i) + (*i)->dump (out, indent + 1); + ACM_Class::dump_aggr (out, indent); +} + +void ACM_Speculation::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "Speculation (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_Speculation::dump_attr (std::ostream &out) const { + ACM_Node::dump_attr (out); +} + +void ACM_Speculation::dump_refs (std::ostream &out) const { + out << " advice ="; + out << " " << (void*)advice_; + out << " tunit ="; + out << " " << (void*)tunit_; + out << " true_jps ="; + for (ACM_Container ::const_iterator i = true_jps_.begin(); i != true_jps_.end(); ++i) + out << " " << (void*)(*i); + out << " false_jps ="; + for (ACM_Container ::const_iterator i = false_jps_.begin(); i != false_jps_.end(); ++i) + out << " " << (void*)(*i); + out << " conditional_jps ="; + for (ACM_Container ::const_iterator i = conditional_jps_.begin(); i != conditional_jps_.end(); ++i) + out << " " << (void*)(*i); + ACM_Node::dump_refs (out); +} + +void ACM_Speculation::dump_aggr (std::ostream &out, int indent) const { + ACM_Node::dump_aggr (out, indent); +} + +void ACM_Model::dump (std::ostream &out, int indent) const { + for (int i = 0; i < indent; i++) cout << " "; + out << "Model (" << this << " " << get_parent() << ")"; dump_attr (out); dump_refs (out); + out << endl; + dump_aggr (out, indent); +} + +void ACM_Model::dump_attr (std::ostream &out) const { + out << " version=" << "\"" << version_ << "\""; + ACM_Node::dump_attr (out); +} + +void ACM_Model::dump_refs (std::ostream &out) const { + ACM_Node::dump_refs (out); +} + +void ACM_Model::dump_aggr (std::ostream &out, int indent) const { + for (ACM_Container ::const_iterator i = files_.begin(); i != files_.end(); ++i) + (*i)->dump (out, indent + 1); + root_->dump (out, indent + 1); + for (ACM_Container ::const_iterator i = speculations_.begin(); i != speculations_.end(); ++i) + (*i)->dump (out, indent + 1); + ACM_Node::dump_aggr (out, indent); +} + +void ACM_Node::to_xml (SaveContext &context) { + remove_property ("id"); + if (get_id () != -1) + set_property ("id", get_id ()); +} + +void ACM_File::to_xml (SaveContext &context) { + if (get_xml_dirty ()) set_property ("filename", filename_); + if (get_xml_dirty ()) set_property ("len", len_); + if (get_xml_dirty ()) set_property ("time", time_); + ACM_Node::to_xml (context); +} + +void ACM_TUnit::to_xml (SaveContext &context) { + if (get_xml_dirty ()) set_property ("dirty_flag", dirty_flag_); + ACM_File::to_xml (context); +} + +void ACM_Header::to_xml (SaveContext &context) { + if (in_.size () > 0) { + ostringstream idrefs; bool first = true; + for (ACM_Container ::iterator i = in_.begin (); i != in_.end (); ++i) { + (*i)->assign_id (context); + if (!first) idrefs << " "; else first = false; + idrefs << (*i)->get_id (); + } + set_property ("in", idrefs.str ()); + } + else { + remove_property ("in"); + } + ACM_File::to_xml (context); +} + +void ACM_Source::to_xml (SaveContext &context) { + if (get_xml_dirty ()) set_property ("kind", kind_); + set_property ("file", file_->assign_id(context)); + if (get_xml_dirty ()) set_property ("line", line_); + if (get_xml_dirty ()) set_property ("len", len_); + ACM_Node::to_xml (context); +} + +void ACM_MemberIntro::to_xml (SaveContext &context) { + set_property ("intro", intro_->assign_id(context)); + if (members_.size () > 0) { + ostringstream idrefs; bool first = true; + for (ACM_Container ::iterator i = members_.begin (); i != members_.end (); ++i) { + (*i)->assign_id (context); + if (!first) idrefs << " "; else first = false; + idrefs << (*i)->get_id (); + } + set_property ("members", idrefs.str ()); + } + else { + remove_property ("members"); + } + ACM_Node::to_xml (context); +} + +void ACM_BaseIntro::to_xml (SaveContext &context) { + set_property ("intro", intro_->assign_id(context)); + if (bases_.size () > 0) { + ostringstream idrefs; bool first = true; + for (ACM_Container ::iterator i = bases_.begin (); i != bases_.end (); ++i) { + (*i)->assign_id (context); + if (!first) idrefs << " "; else first = false; + idrefs << (*i)->get_id (); + } + set_property ("bases", idrefs.str ()); + } + else { + remove_property ("bases"); + } + ACM_Node::to_xml (context); +} + +void ACM_ClassPlan::to_xml (SaveContext &context) { + if (base_intros_.size () > 0) { + if (!base_intros_.get_xml_node ()) { + xmlNodePtr node = xmlNewChild(get_xml_node (), NULL, (xmlChar*)"base_intros", NULL); + base_intros_.set_xml_node (node); + } + base_intros_.to_xml (context); + base_intros_.set_xml_dirty (false); + } + else { + if (base_intros_.get_xml_node ()) { + xmlUnlinkNode (base_intros_.get_xml_node ()); + xmlFreeNode (base_intros_.get_xml_node ()); + base_intros_.set_xml_node (0); + base_intros_.set_xml_dirty (); + } + } + + if (member_intros_.size () > 0) { + if (!member_intros_.get_xml_node ()) { + xmlNodePtr node = xmlNewChild(get_xml_node (), NULL, (xmlChar*)"member_intros", NULL); + member_intros_.set_xml_node (node); + } + member_intros_.to_xml (context); + member_intros_.set_xml_dirty (false); + } + else { + if (member_intros_.get_xml_node ()) { + xmlUnlinkNode (member_intros_.get_xml_node ()); + xmlFreeNode (member_intros_.get_xml_node ()); + member_intros_.set_xml_node (0); + member_intros_.set_xml_dirty (); + } + } + + ACM_Node::to_xml (context); +} + +void ACM_CodeAdvice::to_xml (SaveContext &context) { + set_property ("advice", advice_->assign_id(context)); + if (get_xml_dirty ()) set_property ("conditional", conditional_); + ACM_Node::to_xml (context); +} + +void ACM_CodePlan::to_xml (SaveContext &context) { + if (before_.size () > 0) { + if (!before_.get_xml_node ()) { + xmlNodePtr node = xmlNewChild(get_xml_node (), NULL, (xmlChar*)"before", NULL); + before_.set_xml_node (node); + } + before_.to_xml (context); + before_.set_xml_dirty (false); + } + else { + if (before_.get_xml_node ()) { + xmlUnlinkNode (before_.get_xml_node ()); + xmlFreeNode (before_.get_xml_node ()); + before_.set_xml_node (0); + before_.set_xml_dirty (); + } + } + + if (has_around ()) { + if (!around_->get_xml_node ()) { + xmlNodePtr node = xmlNewChild(get_xml_node (), NULL, (xmlChar*)"around", NULL); + node = xmlNewChild(node, NULL, (xmlChar*)around_->type_str (), NULL); + around_->set_xml_node (node); + } + around_->to_xml (context); + around_->set_xml_dirty (false); + } + if (after_.size () > 0) { + if (!after_.get_xml_node ()) { + xmlNodePtr node = xmlNewChild(get_xml_node (), NULL, (xmlChar*)"after", NULL); + after_.set_xml_node (node); + } + after_.to_xml (context); + after_.set_xml_dirty (false); + } + else { + if (after_.get_xml_node ()) { + xmlUnlinkNode (after_.get_xml_node ()); + xmlFreeNode (after_.get_xml_node ()); + after_.set_xml_node (0); + after_.set_xml_dirty (); + } + } + + if (has_next_level ()) { + if (!next_level_->get_xml_node ()) { + xmlNodePtr node = xmlNewChild(get_xml_node (), NULL, (xmlChar*)"next_level", NULL); + node = xmlNewChild(node, NULL, (xmlChar*)next_level_->type_str (), NULL); + next_level_->set_xml_node (node); + } + next_level_->to_xml (context); + next_level_->set_xml_dirty (false); + } + ACM_Node::to_xml (context); +} + +void ACM_Any::to_xml (SaveContext &context) { + if (has_jpid ()) + if (get_xml_dirty ()) set_property ("jpid", jpid_); + if (source_.size () > 0) { + if (!source_.get_xml_node ()) { + xmlNodePtr node = xmlNewChild(get_xml_node (), NULL, (xmlChar*)"source", NULL); + source_.set_xml_node (node); + } + source_.to_xml (context); + source_.set_xml_dirty (false); + } + else { + if (source_.get_xml_node ()) { + xmlUnlinkNode (source_.get_xml_node ()); + xmlFreeNode (source_.get_xml_node ()); + source_.set_xml_node (0); + source_.set_xml_dirty (); + } + } + + if (attributes_.size () > 0) { + ostringstream idrefs; bool first = true; + for (ACM_Container ::iterator i = attributes_.begin (); i != attributes_.end (); ++i) { + (*i)->assign_id (context); + if (!first) idrefs << " "; else first = false; + idrefs << (*i)->get_id (); + } + set_property ("attributes", idrefs.str ()); + } + else { + remove_property ("attributes"); + } + ACM_Node::to_xml (context); +} + +void ACM_Type::to_xml (SaveContext &context) { + if (get_xml_dirty ()) set_property ("signature", signature_); + ACM_Any::to_xml (context); +} + +void ACM_Arg::to_xml (SaveContext &context) { + if (get_xml_dirty ()) set_property ("type", type_); + if (get_xml_dirty ()) set_property ("name", name_); + ACM_Any::to_xml (context); +} + +void ACM_Name::to_xml (SaveContext &context) { + if (children_.size () > 0) { + if (!children_.get_xml_node ()) { + xmlNodePtr node = xmlNewChild(get_xml_node (), NULL, (xmlChar*)"children", NULL); + children_.set_xml_node (node); + } + children_.to_xml (context); + children_.set_xml_dirty (false); + } + else { + if (children_.get_xml_node ()) { + xmlUnlinkNode (children_.get_xml_node ()); + xmlFreeNode (children_.get_xml_node ()); + children_.set_xml_node (0); + children_.set_xml_dirty (); + } + } + + if (get_xml_dirty ()) set_property ("name", name_); + if (get_xml_dirty ()) set_property ("builtin", builtin_); + if (tunits_.size () > 0) { + ostringstream idrefs; bool first = true; + for (ACM_Container ::iterator i = tunits_.begin (); i != tunits_.end (); ++i) { + (*i)->assign_id (context); + if (!first) idrefs << " "; else first = false; + idrefs << (*i)->get_id (); + } + set_property ("tunits", idrefs.str ()); + } + else { + remove_property ("tunits"); + } + ACM_Any::to_xml (context); +} + +void ACM_Namespace::to_xml (SaveContext &context) { + ACM_Name::to_xml (context); +} + +void ACM_Function::to_xml (SaveContext &context) { + if (has_result_type ()) { + if (!result_type_->get_xml_node ()) { + xmlNodePtr node = xmlNewChild(get_xml_node (), NULL, (xmlChar*)"result_type", NULL); + node = xmlNewChild(node, NULL, (xmlChar*)result_type_->type_str (), NULL); + result_type_->set_xml_node (node); + } + result_type_->to_xml (context); + result_type_->set_xml_dirty (false); + } + if (arg_types_.size () > 0) { + if (!arg_types_.get_xml_node ()) { + xmlNodePtr node = xmlNewChild(get_xml_node (), NULL, (xmlChar*)"arg_types", NULL); + arg_types_.set_xml_node (node); + } + arg_types_.to_xml (context); + arg_types_.set_xml_dirty (false); + } + else { + if (arg_types_.get_xml_node ()) { + xmlUnlinkNode (arg_types_.get_xml_node ()); + xmlFreeNode (arg_types_.get_xml_node ()); + arg_types_.set_xml_node (0); + arg_types_.set_xml_dirty (); + } + } + + if (get_xml_dirty ()) set_property ("kind", kind_); + if (get_xml_dirty ()) set_property ("variadic_args", variadic_args_); + if (get_xml_dirty ()) set_property ("cv_qualifiers", cv_qualifiers_); + if (has_static_in ()) + set_property ("static_in", static_in_->assign_id(context)); + ACM_Name::to_xml (context); +} + +void ACM_Variable::to_xml (SaveContext &context) { + if (!type_->get_xml_node ()) { + xmlNodePtr node = xmlNewChild(get_xml_node (), NULL, (xmlChar*)"type", NULL); + node = xmlNewChild(node, NULL, (xmlChar*)type_->type_str (), NULL); + type_->set_xml_node (node); + } + type_->to_xml (context); + type_->set_xml_dirty (false); + if (get_xml_dirty ()) set_property ("kind", kind_); + ACM_Name::to_xml (context); +} + +void ACM_Class::to_xml (SaveContext &context) { + if (bases_.size () > 0) { + ostringstream idrefs; bool first = true; + for (ACM_Container ::iterator i = bases_.begin (); i != bases_.end (); ++i) { + (*i)->assign_id (context); + if (!first) idrefs << " "; else first = false; + idrefs << (*i)->get_id (); + } + set_property ("bases", idrefs.str ()); + } + else { + remove_property ("bases"); + } + if (has_plan ()) { + if (!plan_->get_xml_node ()) { + xmlNodePtr node = xmlNewChild(get_xml_node (), NULL, (xmlChar*)"plan", NULL); + node = xmlNewChild(node, NULL, (xmlChar*)plan_->type_str (), NULL); + plan_->set_xml_node (node); + } + plan_->to_xml (context); + plan_->set_xml_dirty (false); + } + ACM_Name::to_xml (context); +} + +void ACM_ClassSlice::to_xml (SaveContext &context) { + if (get_xml_dirty ()) set_property ("is_struct", is_struct_); + ACM_Name::to_xml (context); +} + +void ACM_Code::to_xml (SaveContext &context) { + if (has_plan ()) { + if (!plan_->get_xml_node ()) { + xmlNodePtr node = xmlNewChild(get_xml_node (), NULL, (xmlChar*)"plan", NULL); + node = xmlNewChild(node, NULL, (xmlChar*)plan_->type_str (), NULL); + plan_->set_xml_node (node); + } + plan_->to_xml (context); + plan_->set_xml_dirty (false); + } + ACM_Any::to_xml (context); +} + +void ACM_Access::to_xml (SaveContext &context) { + if (get_xml_dirty ()) set_property ("lid", lid_); + if (has_target_object_lid ()) + if (get_xml_dirty ()) set_property ("target_object_lid", target_object_lid_); + if (has_cfg_block_lid ()) + if (get_xml_dirty ()) set_property ("cfg_block_lid", cfg_block_lid_); + if (has_target_class ()) + set_property ("target_class", target_class_->assign_id(context)); + ACM_Code::to_xml (context); +} + +void ACM_Get::to_xml (SaveContext &context) { + if (has_variable ()) + set_property ("variable", variable_->assign_id(context)); + ACM_Access::to_xml (context); +} + +void ACM_Set::to_xml (SaveContext &context) { + if (has_variable ()) + set_property ("variable", variable_->assign_id(context)); + ACM_Access::to_xml (context); +} + +void ACM_Call::to_xml (SaveContext &context) { + set_property ("target", target_->assign_id(context)); + if (variadic_arg_types_.size () > 0) { + if (!variadic_arg_types_.get_xml_node ()) { + xmlNodePtr node = xmlNewChild(get_xml_node (), NULL, (xmlChar*)"variadic_arg_types", NULL); + variadic_arg_types_.set_xml_node (node); + } + variadic_arg_types_.to_xml (context); + variadic_arg_types_.set_xml_dirty (false); + } + else { + if (variadic_arg_types_.get_xml_node ()) { + xmlUnlinkNode (variadic_arg_types_.get_xml_node ()); + xmlFreeNode (variadic_arg_types_.get_xml_node ()); + variadic_arg_types_.set_xml_node (0); + variadic_arg_types_.set_xml_dirty (); + } + } + + if (has_default_args ()) + if (get_xml_dirty ()) set_property ("default_args", default_args_); + ACM_Access::to_xml (context); +} + +void ACM_Builtin::to_xml (SaveContext &context) { + set_property ("target", target_->assign_id(context)); + if (implicit_access_.size () > 0) { + if (!implicit_access_.get_xml_node ()) { + xmlNodePtr node = xmlNewChild(get_xml_node (), NULL, (xmlChar*)"implicit_access", NULL); + implicit_access_.set_xml_node (node); + } + implicit_access_.to_xml (context); + implicit_access_.set_xml_dirty (false); + } + else { + if (implicit_access_.get_xml_node ()) { + xmlUnlinkNode (implicit_access_.get_xml_node ()); + xmlFreeNode (implicit_access_.get_xml_node ()); + implicit_access_.set_xml_node (0); + implicit_access_.set_xml_dirty (); + } + } + + ACM_Access::to_xml (context); +} + +void ACM_Ref::to_xml (SaveContext &context) { + set_property ("variable", variable_->assign_id(context)); + if (!type_->get_xml_node ()) { + xmlNodePtr node = xmlNewChild(get_xml_node (), NULL, (xmlChar*)"type", NULL); + node = xmlNewChild(node, NULL, (xmlChar*)type_->type_str (), NULL); + type_->set_xml_node (node); + } + type_->to_xml (context); + type_->set_xml_dirty (false); + ACM_Access::to_xml (context); +} + +void ACM_GetRef::to_xml (SaveContext &context) { + if (!type_->get_xml_node ()) { + xmlNodePtr node = xmlNewChild(get_xml_node (), NULL, (xmlChar*)"type", NULL); + node = xmlNewChild(node, NULL, (xmlChar*)type_->type_str (), NULL); + type_->set_xml_node (node); + } + type_->to_xml (context); + type_->set_xml_dirty (false); + ACM_Access::to_xml (context); +} + +void ACM_SetRef::to_xml (SaveContext &context) { + if (!type_->get_xml_node ()) { + xmlNodePtr node = xmlNewChild(get_xml_node (), NULL, (xmlChar*)"type", NULL); + node = xmlNewChild(node, NULL, (xmlChar*)type_->type_str (), NULL); + type_->set_xml_node (node); + } + type_->to_xml (context); + type_->set_xml_dirty (false); + ACM_Access::to_xml (context); +} + +void ACM_CallRef::to_xml (SaveContext &context) { + if (!type_->get_xml_node ()) { + xmlNodePtr node = xmlNewChild(get_xml_node (), NULL, (xmlChar*)"type", NULL); + node = xmlNewChild(node, NULL, (xmlChar*)type_->type_str (), NULL); + type_->set_xml_node (node); + } + type_->to_xml (context); + type_->set_xml_dirty (false); + ACM_Access::to_xml (context); +} + +void ACM_Execution::to_xml (SaveContext &context) { + ACM_Code::to_xml (context); +} + +void ACM_Construction::to_xml (SaveContext &context) { + ACM_Code::to_xml (context); +} + +void ACM_Destruction::to_xml (SaveContext &context) { + ACM_Code::to_xml (context); +} + +void ACM_Pointcut::to_xml (SaveContext &context) { + if (get_xml_dirty ()) set_property ("expr", expr_); + if (args_.size () > 0) { + if (!args_.get_xml_node ()) { + xmlNodePtr node = xmlNewChild(get_xml_node (), NULL, (xmlChar*)"args", NULL); + args_.set_xml_node (node); + } + args_.to_xml (context); + args_.set_xml_dirty (false); + } + else { + if (args_.get_xml_node ()) { + xmlUnlinkNode (args_.get_xml_node ()); + xmlFreeNode (args_.get_xml_node ()); + args_.set_xml_node (0); + args_.set_xml_dirty (); + } + } + + if (get_xml_dirty ()) set_property ("kind", kind_); + ACM_Name::to_xml (context); +} + +void ACM_Attribute::to_xml (SaveContext &context) { + if (args_.size () > 0) { + if (!args_.get_xml_node ()) { + xmlNodePtr node = xmlNewChild(get_xml_node (), NULL, (xmlChar*)"args", NULL); + args_.set_xml_node (node); + } + args_.to_xml (context); + args_.set_xml_dirty (false); + } + else { + if (args_.get_xml_node ()) { + xmlUnlinkNode (args_.get_xml_node ()); + xmlFreeNode (args_.get_xml_node ()); + args_.set_xml_node (0); + args_.set_xml_dirty (); + } + } + + ACM_Name::to_xml (context); +} + +void ACM_Advice::to_xml (SaveContext &context) { + if (!pointcut_->get_xml_node ()) { + xmlNodePtr node = xmlNewChild(get_xml_node (), NULL, (xmlChar*)"pointcut", NULL); + node = xmlNewChild(node, NULL, (xmlChar*)pointcut_->type_str (), NULL); + pointcut_->set_xml_node (node); + } + pointcut_->to_xml (context); + pointcut_->set_xml_dirty (false); + if (get_xml_dirty ()) set_property ("lid", lid_); + ACM_Any::to_xml (context); +} + +void ACM_AdviceCode::to_xml (SaveContext &context) { + if (get_xml_dirty ()) set_property ("kind", kind_); + if (get_xml_dirty ()) set_property ("context", context_); + ACM_Advice::to_xml (context); +} + +void ACM_Introduction::to_xml (SaveContext &context) { + if (has_named_slice ()) + set_property ("named_slice", named_slice_->assign_id(context)); + if (has_anon_slice ()) { + if (!anon_slice_->get_xml_node ()) { + xmlNodePtr node = xmlNewChild(get_xml_node (), NULL, (xmlChar*)"anon_slice", NULL); + node = xmlNewChild(node, NULL, (xmlChar*)anon_slice_->type_str (), NULL); + anon_slice_->set_xml_node (node); + } + anon_slice_->to_xml (context); + anon_slice_->set_xml_dirty (false); + } + ACM_Advice::to_xml (context); +} + +void ACM_Order::to_xml (SaveContext &context) { + if (aspect_exprs_.size () > 0) { + if (!aspect_exprs_.get_xml_node ()) { + xmlNodePtr node = xmlNewChild(get_xml_node (), NULL, (xmlChar*)"aspect_exprs", NULL); + aspect_exprs_.set_xml_node (node); + } + aspect_exprs_.to_xml (context); + aspect_exprs_.set_xml_dirty (false); + } + else { + if (aspect_exprs_.get_xml_node ()) { + xmlUnlinkNode (aspect_exprs_.get_xml_node ()); + xmlFreeNode (aspect_exprs_.get_xml_node ()); + aspect_exprs_.set_xml_node (0); + aspect_exprs_.set_xml_dirty (); + } + } + + ACM_Advice::to_xml (context); +} + +void ACM_Aspect::to_xml (SaveContext &context) { + if (intros_.size () > 0) { + if (!intros_.get_xml_node ()) { + xmlNodePtr node = xmlNewChild(get_xml_node (), NULL, (xmlChar*)"intros", NULL); + intros_.set_xml_node (node); + } + intros_.to_xml (context); + intros_.set_xml_dirty (false); + } + else { + if (intros_.get_xml_node ()) { + xmlUnlinkNode (intros_.get_xml_node ()); + xmlFreeNode (intros_.get_xml_node ()); + intros_.set_xml_node (0); + intros_.set_xml_dirty (); + } + } + + if (advices_.size () > 0) { + if (!advices_.get_xml_node ()) { + xmlNodePtr node = xmlNewChild(get_xml_node (), NULL, (xmlChar*)"advices", NULL); + advices_.set_xml_node (node); + } + advices_.to_xml (context); + advices_.set_xml_dirty (false); + } + else { + if (advices_.get_xml_node ()) { + xmlUnlinkNode (advices_.get_xml_node ()); + xmlFreeNode (advices_.get_xml_node ()); + advices_.set_xml_node (0); + advices_.set_xml_dirty (); + } + } + + if (orders_.size () > 0) { + if (!orders_.get_xml_node ()) { + xmlNodePtr node = xmlNewChild(get_xml_node (), NULL, (xmlChar*)"orders", NULL); + orders_.set_xml_node (node); + } + orders_.to_xml (context); + orders_.set_xml_dirty (false); + } + else { + if (orders_.get_xml_node ()) { + xmlUnlinkNode (orders_.get_xml_node ()); + xmlFreeNode (orders_.get_xml_node ()); + orders_.set_xml_node (0); + orders_.set_xml_dirty (); + } + } + + ACM_Class::to_xml (context); +} + +void ACM_Speculation::to_xml (SaveContext &context) { + set_property ("advice", advice_->assign_id(context)); + set_property ("tunit", tunit_->assign_id(context)); + if (true_jps_.size () > 0) { + ostringstream idrefs; bool first = true; + for (ACM_Container ::iterator i = true_jps_.begin (); i != true_jps_.end (); ++i) { + (*i)->assign_id (context); + if (!first) idrefs << " "; else first = false; + idrefs << (*i)->get_id (); + } + set_property ("true_jps", idrefs.str ()); + } + else { + remove_property ("true_jps"); + } + if (false_jps_.size () > 0) { + ostringstream idrefs; bool first = true; + for (ACM_Container ::iterator i = false_jps_.begin (); i != false_jps_.end (); ++i) { + (*i)->assign_id (context); + if (!first) idrefs << " "; else first = false; + idrefs << (*i)->get_id (); + } + set_property ("false_jps", idrefs.str ()); + } + else { + remove_property ("false_jps"); + } + if (conditional_jps_.size () > 0) { + ostringstream idrefs; bool first = true; + for (ACM_Container ::iterator i = conditional_jps_.begin (); i != conditional_jps_.end (); ++i) { + (*i)->assign_id (context); + if (!first) idrefs << " "; else first = false; + idrefs << (*i)->get_id (); + } + set_property ("conditional_jps", idrefs.str ()); + } + else { + remove_property ("conditional_jps"); + } + ACM_Node::to_xml (context); +} + +void ACM_Model::to_xml (SaveContext &context) { + if (files_.size () > 0) { + if (!files_.get_xml_node ()) { + xmlNodePtr node = xmlNewChild(get_xml_node (), NULL, (xmlChar*)"files", NULL); + files_.set_xml_node (node); + } + files_.to_xml (context); + files_.set_xml_dirty (false); + } + else { + if (files_.get_xml_node ()) { + xmlUnlinkNode (files_.get_xml_node ()); + xmlFreeNode (files_.get_xml_node ()); + files_.set_xml_node (0); + files_.set_xml_dirty (); + } + } + + if (!root_->get_xml_node ()) { + xmlNodePtr node = xmlNewChild(get_xml_node (), NULL, (xmlChar*)"root", NULL); + node = xmlNewChild(node, NULL, (xmlChar*)root_->type_str (), NULL); + root_->set_xml_node (node); + } + root_->to_xml (context); + root_->set_xml_dirty (false); + if (speculations_.size () > 0) { + if (!speculations_.get_xml_node ()) { + xmlNodePtr node = xmlNewChild(get_xml_node (), NULL, (xmlChar*)"speculations", NULL); + speculations_.set_xml_node (node); + } + speculations_.to_xml (context); + speculations_.set_xml_dirty (false); + } + else { + if (speculations_.get_xml_node ()) { + xmlUnlinkNode (speculations_.get_xml_node ()); + xmlFreeNode (speculations_.get_xml_node ()); + speculations_.set_xml_node (0); + speculations_.set_xml_dirty (); + } + } + + if (get_xml_dirty ()) set_property ("version", version_); + ACM_Node::to_xml (context); +} + +// model facade class +// delete all model elements from a Project Model +void ProjectModel::clear () { + for (int l = 0; l < MAX_JOIN_POINT_TYPE_INDEX; l++) { + for (NodeList::iterator i = _join_points[l].begin (); + i != _join_points[l].end (); ++i) + delete *i; + _join_points[l].clear (); + } + set_root (0); + get_files ().clear (); + if (_xml_doc) { + xmlFreeDoc (_xml_doc); // delete the DOM + _xml_doc = 0; + } +} + +// allocated a new joinpoint ID +unsigned ProjectModel::alloc_jpid () { + unsigned result; + if (_jpids_freed.empty ()) { + result = _jpids_in_use; + _jpids_in_use++; + } + else { + result = *_jpids_freed.begin (); + _jpids_freed.erase (_jpids_freed.begin ()); + } + return result; +} + +// mark a join point ID as allocated (needed for loading models) +void ProjectModel::alloc_jpid (unsigned jpid) { + if (jpid >= _jpids_in_use) { + for (unsigned id = _jpids_in_use; id < jpid; id++) + _jpids_freed.insert (id); + _jpids_in_use = jpid + 1; + } + else { + _jpids_freed.erase (jpid); + } +} + +// free a joinpoint ID +void ProjectModel::free_jpid (unsigned jpid) { + _jpids_freed.insert (jpid); +} + +// select and return all join points of a given type (any of them) +void ProjectModel::select (JoinPointType jpt, Selection &result, bool prj_only) { + for (int l = 0; l < MAX_JOIN_POINT_TYPE_INDEX; l++) { + if (jpt & (1<get_tunits().empty()) // external + continue; + } + result.push_back (*i); + } + } + } +} + +// merge the elements of another model into this one +void ProjectModel::merge (ProjectModel &that) { + _merge_id++; + init_change_set (that); + sourceCleanupModel (*this); + merge_node (this, &that); + fix_refs (this); + clear_change_set (); +} + +// before merging two models find out which files have been changed +// (file in 'that' newer as in 'this') +void ProjectModel::init_change_set(ProjectModel &that) { + typedef ACM_Container Container; + Container::Set &me = get_files().get_sorted (); + Container::Set &you = that.get_files().get_sorted (); + // iterate over both sorted file lists + Container::Set::iterator curr_me = me.begin (); + Container::Set::iterator curr_you = you.begin (); + while (curr_me != me.end () && curr_you != you.end ()) { + if (**curr_me < ** curr_you) // an element in 'me', which is not present + ++curr_me; // in 'you' => simply skip + else if (**curr_you < ** curr_me) { // a new element (not in 'me' yet + ++curr_you; + } + else { // two equal elements according to their key + if ((*curr_me)->get_time() != (*curr_you)->get_time()) { + _modified_files.insert (*curr_me); + (*curr_me)->set_time((*curr_you)->get_time()); + } + ++curr_you; + ++curr_me; + } + } +} + +// cleanup list of modified files (at the end of merging) +void ProjectModel::clear_change_set() { + _modified_files.clear (); +} + +// handle attribute variations when merging models +// returns 'true' if the attribute in the project model ("me") should be +// overwritten by the attribute in the translation unit model ("that") +bool ProjectModel::merge_attr (ACM_Node &me, ACM_Node &that, const std::string &attr_name) { + // make sure that the joinpoint IDs from the translation unit model are + // overwritten by the IDs from the stored project model + if (attr_name == "jpid") { + ((ACM_Any&)that).set_jpid (((ACM_Any&)me).get_jpid ()); + return false; + } + // cout << "warning: attr " << attr_name << " differs" << endl; + return true; +} + +void ProjectModel::merge_attr_only_in_me (ACM_Node &me, ACM_Node &that, const std::string &attr_name) { + cout << "warning: attr " << attr_name << " only in project model" << endl; +} + +void ProjectModel::merge_attr_only_in_that (ACM_Node &me, ACM_Node &that, const std::string &attr_name) { + cout << "warning: attr " << attr_name << " only in translation unit model" << endl; +} + + +// delete all source entries that are referencing a modified file +// true: *all* entries (>0) have been deleted +bool ProjectModel::purgeSources(ACM_Any &me) { + ACM_Container &source_container = me.get_source(); + if (source_container.size () == 0) + return false; + bool needs_decl = (me.get_parent() && + (((ACM_Any*)me.get_parent())->type_val() & (JPT_Class|JPT_Aspect))); + bool has_decl = false; + bool removed_decl = false; + bool has_def = false; + typedef ACM_Container Container; + list found; + for (Container::iterator i = source_container.begin (); + i != source_container.end (); ++i) { + ACM_Source *src = *i; + if (_modified_files.find (src->get_file ()) != _modified_files.end ()) { + found.push_back (*i); + if (src->get_kind() == SLK_DECL) + removed_decl = true; + } + else { + if (src->get_kind() == SLK_DECL) + has_decl = true; + else if (src->get_kind() == SLK_DEF) + has_def = true; + } + } + // For members of classes or aspects (member functions, nested classes, + // member slices the following rule is checked: + // If there is a definition (in a non-modified file), there also has to + // be a declaration (within the parent class or aspect). Otherwise the + // model element has to be deleted. + if (has_def && removed_decl && needs_decl && !has_decl) + return true; + if (source_container.size () != found.size ()) { + for (list::iterator i = found.begin (); i != found.end (); ++i) { + ACM_Source *src = *i; + source_container.remove (src); + unlink_node (src); + } + return false; + } + return true; +} + +ACM_Node *ProjectModel::copyNode(ACM_Node *that_node) { + ACM_Node *result; + switch (that_node->type_val ()) { + case JPT_TUnit: + result = newTUnit(); + copyTUnit ((ACM_TUnit&)*result, (ACM_TUnit&)*that_node); + break; + case JPT_Header: + result = newHeader(); + copyHeader ((ACM_Header&)*result, (ACM_Header&)*that_node); + break; + case JPT_Source: + result = newSource(); + copySource ((ACM_Source&)*result, (ACM_Source&)*that_node); + break; + case JPT_MemberIntro: + result = newMemberIntro(); + copyMemberIntro ((ACM_MemberIntro&)*result, (ACM_MemberIntro&)*that_node); + break; + case JPT_BaseIntro: + result = newBaseIntro(); + copyBaseIntro ((ACM_BaseIntro&)*result, (ACM_BaseIntro&)*that_node); + break; + case JPT_ClassPlan: + result = newClassPlan(); + copyClassPlan ((ACM_ClassPlan&)*result, (ACM_ClassPlan&)*that_node); + break; + case JPT_CodeAdvice: + result = newCodeAdvice(); + copyCodeAdvice ((ACM_CodeAdvice&)*result, (ACM_CodeAdvice&)*that_node); + break; + case JPT_CodePlan: + result = newCodePlan(); + copyCodePlan ((ACM_CodePlan&)*result, (ACM_CodePlan&)*that_node); + break; + case JPT_Type: + result = newType(); + copyType ((ACM_Type&)*result, (ACM_Type&)*that_node); + break; + case JPT_Arg: + result = newArg(); + copyArg ((ACM_Arg&)*result, (ACM_Arg&)*that_node); + break; + case JPT_Namespace: + result = newNamespace(); + copyNamespace ((ACM_Namespace&)*result, (ACM_Namespace&)*that_node); + break; + case JPT_Function: + result = newFunction(); + copyFunction ((ACM_Function&)*result, (ACM_Function&)*that_node); + break; + case JPT_Variable: + result = newVariable(); + copyVariable ((ACM_Variable&)*result, (ACM_Variable&)*that_node); + break; + case JPT_Class: + result = newClass(); + copyClass ((ACM_Class&)*result, (ACM_Class&)*that_node); + break; + case JPT_ClassSlice: + result = newClassSlice(); + copyClassSlice ((ACM_ClassSlice&)*result, (ACM_ClassSlice&)*that_node); + break; + case JPT_Get: + result = newGet(); + copyGet ((ACM_Get&)*result, (ACM_Get&)*that_node); + break; + case JPT_Set: + result = newSet(); + copySet ((ACM_Set&)*result, (ACM_Set&)*that_node); + break; + case JPT_Call: + result = newCall(); + copyCall ((ACM_Call&)*result, (ACM_Call&)*that_node); + break; + case JPT_Builtin: + result = newBuiltin(); + copyBuiltin ((ACM_Builtin&)*result, (ACM_Builtin&)*that_node); + break; + case JPT_Ref: + result = newRef(); + copyRef ((ACM_Ref&)*result, (ACM_Ref&)*that_node); + break; + case JPT_GetRef: + result = newGetRef(); + copyGetRef ((ACM_GetRef&)*result, (ACM_GetRef&)*that_node); + break; + case JPT_SetRef: + result = newSetRef(); + copySetRef ((ACM_SetRef&)*result, (ACM_SetRef&)*that_node); + break; + case JPT_CallRef: + result = newCallRef(); + copyCallRef ((ACM_CallRef&)*result, (ACM_CallRef&)*that_node); + break; + case JPT_Execution: + result = newExecution(); + copyExecution ((ACM_Execution&)*result, (ACM_Execution&)*that_node); + break; + case JPT_Construction: + result = newConstruction(); + copyConstruction ((ACM_Construction&)*result, (ACM_Construction&)*that_node); + break; + case JPT_Destruction: + result = newDestruction(); + copyDestruction ((ACM_Destruction&)*result, (ACM_Destruction&)*that_node); + break; + case JPT_Pointcut: + result = newPointcut(); + copyPointcut ((ACM_Pointcut&)*result, (ACM_Pointcut&)*that_node); + break; + case JPT_Attribute: + result = newAttribute(); + copyAttribute ((ACM_Attribute&)*result, (ACM_Attribute&)*that_node); + break; + case JPT_AdviceCode: + result = newAdviceCode(); + copyAdviceCode ((ACM_AdviceCode&)*result, (ACM_AdviceCode&)*that_node); + break; + case JPT_Introduction: + result = newIntroduction(); + copyIntroduction ((ACM_Introduction&)*result, (ACM_Introduction&)*that_node); + break; + case JPT_Order: + result = newOrder(); + copyOrder ((ACM_Order&)*result, (ACM_Order&)*that_node); + break; + case JPT_Aspect: + result = newAspect(); + copyAspect ((ACM_Aspect&)*result, (ACM_Aspect&)*that_node); + break; + case JPT_Speculation: + result = newSpeculation(); + copySpeculation ((ACM_Speculation&)*result, (ACM_Speculation&)*that_node); + break; + case JPT_Model: + result = newModel(); + copyModel ((ACM_Model&)*result, (ACM_Model&)*that_node); + break; + default: + result = 0; + } + if (result) that_node->set_partner (result); + return result; +} + +void ProjectModel::merge_node(ACM_Node *prj_node, ACM_Node *tu_node) { + switch (prj_node->type_val ()) { + case JPT_TUnit: mergeTUnit ((ACM_TUnit&)*prj_node, (ACM_TUnit&)*tu_node); break; + case JPT_Header: mergeHeader ((ACM_Header&)*prj_node, (ACM_Header&)*tu_node); break; + case JPT_Source: mergeSource ((ACM_Source&)*prj_node, (ACM_Source&)*tu_node); break; + case JPT_MemberIntro: mergeMemberIntro ((ACM_MemberIntro&)*prj_node, (ACM_MemberIntro&)*tu_node); break; + case JPT_BaseIntro: mergeBaseIntro ((ACM_BaseIntro&)*prj_node, (ACM_BaseIntro&)*tu_node); break; + case JPT_ClassPlan: mergeClassPlan ((ACM_ClassPlan&)*prj_node, (ACM_ClassPlan&)*tu_node); break; + case JPT_CodeAdvice: mergeCodeAdvice ((ACM_CodeAdvice&)*prj_node, (ACM_CodeAdvice&)*tu_node); break; + case JPT_CodePlan: mergeCodePlan ((ACM_CodePlan&)*prj_node, (ACM_CodePlan&)*tu_node); break; + case JPT_Type: mergeType ((ACM_Type&)*prj_node, (ACM_Type&)*tu_node); break; + case JPT_Arg: mergeArg ((ACM_Arg&)*prj_node, (ACM_Arg&)*tu_node); break; + case JPT_Namespace: mergeNamespace ((ACM_Namespace&)*prj_node, (ACM_Namespace&)*tu_node); break; + case JPT_Function: mergeFunction ((ACM_Function&)*prj_node, (ACM_Function&)*tu_node); break; + case JPT_Variable: mergeVariable ((ACM_Variable&)*prj_node, (ACM_Variable&)*tu_node); break; + case JPT_Class: mergeClass ((ACM_Class&)*prj_node, (ACM_Class&)*tu_node); break; + case JPT_ClassSlice: mergeClassSlice ((ACM_ClassSlice&)*prj_node, (ACM_ClassSlice&)*tu_node); break; + case JPT_Get: mergeGet ((ACM_Get&)*prj_node, (ACM_Get&)*tu_node); break; + case JPT_Set: mergeSet ((ACM_Set&)*prj_node, (ACM_Set&)*tu_node); break; + case JPT_Call: mergeCall ((ACM_Call&)*prj_node, (ACM_Call&)*tu_node); break; + case JPT_Builtin: mergeBuiltin ((ACM_Builtin&)*prj_node, (ACM_Builtin&)*tu_node); break; + case JPT_Ref: mergeRef ((ACM_Ref&)*prj_node, (ACM_Ref&)*tu_node); break; + case JPT_GetRef: mergeGetRef ((ACM_GetRef&)*prj_node, (ACM_GetRef&)*tu_node); break; + case JPT_SetRef: mergeSetRef ((ACM_SetRef&)*prj_node, (ACM_SetRef&)*tu_node); break; + case JPT_CallRef: mergeCallRef ((ACM_CallRef&)*prj_node, (ACM_CallRef&)*tu_node); break; + case JPT_Execution: mergeExecution ((ACM_Execution&)*prj_node, (ACM_Execution&)*tu_node); break; + case JPT_Construction: mergeConstruction ((ACM_Construction&)*prj_node, (ACM_Construction&)*tu_node); break; + case JPT_Destruction: mergeDestruction ((ACM_Destruction&)*prj_node, (ACM_Destruction&)*tu_node); break; + case JPT_Pointcut: mergePointcut ((ACM_Pointcut&)*prj_node, (ACM_Pointcut&)*tu_node); break; + case JPT_Attribute: mergeAttribute ((ACM_Attribute&)*prj_node, (ACM_Attribute&)*tu_node); break; + case JPT_AdviceCode: mergeAdviceCode ((ACM_AdviceCode&)*prj_node, (ACM_AdviceCode&)*tu_node); break; + case JPT_Introduction: mergeIntroduction ((ACM_Introduction&)*prj_node, (ACM_Introduction&)*tu_node); break; + case JPT_Order: mergeOrder ((ACM_Order&)*prj_node, (ACM_Order&)*tu_node); break; + case JPT_Aspect: mergeAspect ((ACM_Aspect&)*prj_node, (ACM_Aspect&)*tu_node); break; + case JPT_Speculation: mergeSpeculation ((ACM_Speculation&)*prj_node, (ACM_Speculation&)*tu_node); break; + case JPT_Model: mergeModel ((ACM_Model&)*prj_node, (ACM_Model&)*tu_node); break; + default: + break; + } + tu_node->set_partner (prj_node); +} + +bool ProjectModel::source_cleanup(ACM_Node &node) { + switch (node.type_val ()) { + case JPT_TUnit: return sourceCleanupTUnit ((ACM_TUnit&)node); + case JPT_Header: return sourceCleanupHeader ((ACM_Header&)node); + case JPT_Source: return sourceCleanupSource ((ACM_Source&)node); + case JPT_MemberIntro: return sourceCleanupMemberIntro ((ACM_MemberIntro&)node); + case JPT_BaseIntro: return sourceCleanupBaseIntro ((ACM_BaseIntro&)node); + case JPT_ClassPlan: return sourceCleanupClassPlan ((ACM_ClassPlan&)node); + case JPT_CodeAdvice: return sourceCleanupCodeAdvice ((ACM_CodeAdvice&)node); + case JPT_CodePlan: return sourceCleanupCodePlan ((ACM_CodePlan&)node); + case JPT_Type: return sourceCleanupType ((ACM_Type&)node); + case JPT_Arg: return sourceCleanupArg ((ACM_Arg&)node); + case JPT_Namespace: return sourceCleanupNamespace ((ACM_Namespace&)node); + case JPT_Function: return sourceCleanupFunction ((ACM_Function&)node); + case JPT_Variable: return sourceCleanupVariable ((ACM_Variable&)node); + case JPT_Class: return sourceCleanupClass ((ACM_Class&)node); + case JPT_ClassSlice: return sourceCleanupClassSlice ((ACM_ClassSlice&)node); + case JPT_Get: return sourceCleanupGet ((ACM_Get&)node); + case JPT_Set: return sourceCleanupSet ((ACM_Set&)node); + case JPT_Call: return sourceCleanupCall ((ACM_Call&)node); + case JPT_Builtin: return sourceCleanupBuiltin ((ACM_Builtin&)node); + case JPT_Ref: return sourceCleanupRef ((ACM_Ref&)node); + case JPT_GetRef: return sourceCleanupGetRef ((ACM_GetRef&)node); + case JPT_SetRef: return sourceCleanupSetRef ((ACM_SetRef&)node); + case JPT_CallRef: return sourceCleanupCallRef ((ACM_CallRef&)node); + case JPT_Execution: return sourceCleanupExecution ((ACM_Execution&)node); + case JPT_Construction: return sourceCleanupConstruction ((ACM_Construction&)node); + case JPT_Destruction: return sourceCleanupDestruction ((ACM_Destruction&)node); + case JPT_Pointcut: return sourceCleanupPointcut ((ACM_Pointcut&)node); + case JPT_Attribute: return sourceCleanupAttribute ((ACM_Attribute&)node); + case JPT_AdviceCode: return sourceCleanupAdviceCode ((ACM_AdviceCode&)node); + case JPT_Introduction: return sourceCleanupIntroduction ((ACM_Introduction&)node); + case JPT_Order: return sourceCleanupOrder ((ACM_Order&)node); + case JPT_Aspect: return sourceCleanupAspect ((ACM_Aspect&)node); + case JPT_Speculation: return sourceCleanupSpeculation ((ACM_Speculation&)node); + case JPT_Model: return sourceCleanupModel ((ACM_Model&)node); + default: + return false; + } +} + +// fix all node references; this is the second phase of merging a tunit +// model into a project model. Reference still address the tunit model +// nodes. Now they have to be replaced with the corresponding project +// model node references +void ProjectModel::fix_refs(ACM_Node *me) { + switch (me->type_val ()) { + case JPT_TUnit: fix_refs_TUnit ((ACM_TUnit&)*me); break; + case JPT_Header: fix_refs_Header ((ACM_Header&)*me); break; + case JPT_Source: fix_refs_Source ((ACM_Source&)*me); break; + case JPT_MemberIntro: fix_refs_MemberIntro ((ACM_MemberIntro&)*me); break; + case JPT_BaseIntro: fix_refs_BaseIntro ((ACM_BaseIntro&)*me); break; + case JPT_ClassPlan: fix_refs_ClassPlan ((ACM_ClassPlan&)*me); break; + case JPT_CodeAdvice: fix_refs_CodeAdvice ((ACM_CodeAdvice&)*me); break; + case JPT_CodePlan: fix_refs_CodePlan ((ACM_CodePlan&)*me); break; + case JPT_Type: fix_refs_Type ((ACM_Type&)*me); break; + case JPT_Arg: fix_refs_Arg ((ACM_Arg&)*me); break; + case JPT_Namespace: fix_refs_Namespace ((ACM_Namespace&)*me); break; + case JPT_Function: fix_refs_Function ((ACM_Function&)*me); break; + case JPT_Variable: fix_refs_Variable ((ACM_Variable&)*me); break; + case JPT_Class: fix_refs_Class ((ACM_Class&)*me); break; + case JPT_ClassSlice: fix_refs_ClassSlice ((ACM_ClassSlice&)*me); break; + case JPT_Get: fix_refs_Get ((ACM_Get&)*me); break; + case JPT_Set: fix_refs_Set ((ACM_Set&)*me); break; + case JPT_Call: fix_refs_Call ((ACM_Call&)*me); break; + case JPT_Builtin: fix_refs_Builtin ((ACM_Builtin&)*me); break; + case JPT_Ref: fix_refs_Ref ((ACM_Ref&)*me); break; + case JPT_GetRef: fix_refs_GetRef ((ACM_GetRef&)*me); break; + case JPT_SetRef: fix_refs_SetRef ((ACM_SetRef&)*me); break; + case JPT_CallRef: fix_refs_CallRef ((ACM_CallRef&)*me); break; + case JPT_Execution: fix_refs_Execution ((ACM_Execution&)*me); break; + case JPT_Construction: fix_refs_Construction ((ACM_Construction&)*me); break; + case JPT_Destruction: fix_refs_Destruction ((ACM_Destruction&)*me); break; + case JPT_Pointcut: fix_refs_Pointcut ((ACM_Pointcut&)*me); break; + case JPT_Attribute: fix_refs_Attribute ((ACM_Attribute&)*me); break; + case JPT_AdviceCode: fix_refs_AdviceCode ((ACM_AdviceCode&)*me); break; + case JPT_Introduction: fix_refs_Introduction ((ACM_Introduction&)*me); break; + case JPT_Order: fix_refs_Order ((ACM_Order&)*me); break; + case JPT_Aspect: fix_refs_Aspect ((ACM_Aspect&)*me); break; + case JPT_Speculation: fix_refs_Speculation ((ACM_Speculation&)*me); break; + case JPT_Model: fix_refs_Model ((ACM_Model&)*me); break; + default: + break; + } + me->set_partner (0); +} + + +// copy methods that copy elements from other models into this one +// NOTE: the elements are only copied and registerd, but no link is set! +void ProjectModel::copyNode(ACM_Node &me, ACM_Node &that) { +} +void ProjectModel::copyFile(ACM_File &me, ACM_File &that) { + copyNode(me, that); + me.set_filename(that.get_filename()); + me.set_len(that.get_len()); + me.set_time(that.get_time()); +} +void ProjectModel::copyTUnit(ACM_TUnit &me, ACM_TUnit &that) { + copyFile(me, that); + me.set_dirty_flag(that.get_dirty_flag()); +} +void ProjectModel::copyHeader(ACM_Header &me, ACM_Header &that) { + copyFile(me, that); + + // reference attribute 'in' copied, address(es) must be adapted later + for (ACM_Container ::iterator i = that.get_in ().begin (); i != that.get_in ().end (); ++i) + me.get_in ().insert ((ACM_TUnit*)*i); +} +void ProjectModel::copySource(ACM_Source &me, ACM_Source &that) { + copyNode(me, that); + me.set_kind(that.get_kind()); + + // reference attribute 'file' copied, address(es) must be adapted later + me.set_file(that.get_file ()); + me.set_line(that.get_line()); + me.set_len(that.get_len()); +} +void ProjectModel::copyMemberIntro(ACM_MemberIntro &me, ACM_MemberIntro &that) { + copyNode(me, that); + + // reference attribute 'intro' copied, address(es) must be adapted later + me.set_intro(that.get_intro ()); + + // reference attribute 'members' copied, address(es) must be adapted later + for (ACM_Container ::iterator i = that.get_members ().begin (); i != that.get_members ().end (); ++i) + me.get_members ().insert ((ACM_Name*)*i); +} +void ProjectModel::copyBaseIntro(ACM_BaseIntro &me, ACM_BaseIntro &that) { + copyNode(me, that); + + // reference attribute 'intro' copied, address(es) must be adapted later + me.set_intro(that.get_intro ()); + + // reference attribute 'bases' copied, address(es) must be adapted later + for (ACM_Container ::iterator i = that.get_bases ().begin (); i != that.get_bases ().end (); ++i) + me.get_bases ().insert ((ACM_Class*)*i); +} +void ProjectModel::copyClassPlan(ACM_ClassPlan &me, ACM_ClassPlan &that) { + copyNode(me, that); + for (ACM_Container ::iterator i = that.get_base_intros ().begin (); i != that.get_base_intros ().end (); ++i) + me.get_base_intros ().insert ((ACM_BaseIntro*)copyNode(*i)); + for (ACM_Container ::iterator i = that.get_member_intros ().begin (); i != that.get_member_intros ().end (); ++i) + me.get_member_intros ().insert ((ACM_MemberIntro*)copyNode(*i)); +} +void ProjectModel::copyCodeAdvice(ACM_CodeAdvice &me, ACM_CodeAdvice &that) { + copyNode(me, that); + + // reference attribute 'advice' copied, address(es) must be adapted later + me.set_advice(that.get_advice ()); + me.set_conditional(that.get_conditional()); +} +void ProjectModel::copyCodePlan(ACM_CodePlan &me, ACM_CodePlan &that) { + copyNode(me, that); + for (ACM_Container ::iterator i = that.get_before ().begin (); i != that.get_before ().end (); ++i) + me.get_before ().insert ((ACM_CodeAdvice*)copyNode(*i)); + if (that.has_around()) me.set_around((ACM_CodeAdvice*)copyNode(that.get_around ())); + for (ACM_Container ::iterator i = that.get_after ().begin (); i != that.get_after ().end (); ++i) + me.get_after ().insert ((ACM_CodeAdvice*)copyNode(*i)); + if (that.has_next_level()) me.set_next_level((ACM_CodePlan*)copyNode(that.get_next_level ())); +} +void ProjectModel::copyAny(ACM_Any &me, ACM_Any &that) { + copyNode(me, that); + if (that.has_jpid()) { + // unsigned old_jpid = that.get_jpid (); + unsigned new_jpid = alloc_jpid (); + me.set_jpid (new_jpid); + that.set_jpid (new_jpid); + } + for (ACM_Container ::iterator i = that.get_source ().begin (); i != that.get_source ().end (); ++i) + me.get_source ().insert ((ACM_Source*)copyNode(*i)); + + // reference attribute 'attributes' copied, address(es) must be adapted later + for (ACM_Container ::iterator i = that.get_attributes ().begin (); i != that.get_attributes ().end (); ++i) + me.get_attributes ().insert ((ACM_Attribute*)*i); +} +void ProjectModel::copyType(ACM_Type &me, ACM_Type &that) { + copyAny(me, that); + me.set_signature(that.get_signature()); + // TODO: copy complex object match_sig here +} +void ProjectModel::copyArg(ACM_Arg &me, ACM_Arg &that) { + copyAny(me, that); + me.set_type(that.get_type()); + me.set_name(that.get_name()); +} +void ProjectModel::copyName(ACM_Name &me, ACM_Name &that) { + copyAny(me, that); + for (ACM_Container ::iterator i = that.get_children ().begin (); i != that.get_children ().end (); ++i) + me.get_children ().insert ((ACM_Any*)copyNode(*i)); + me.set_name(that.get_name()); + // TODO: copy complex object match_sig here + // TODO: copy complex object name_map here + me.set_builtin(that.get_builtin()); + + // reference attribute 'tunits' copied, address(es) must be adapted later + for (ACM_Container ::iterator i = that.get_tunits ().begin (); i != that.get_tunits ().end (); ++i) + me.get_tunits ().insert ((ACM_TUnit*)*i); +} +void ProjectModel::copyNamespace(ACM_Namespace &me, ACM_Namespace &that) { + copyName(me, that); +} +void ProjectModel::copyFunction(ACM_Function &me, ACM_Function &that) { + copyName(me, that); + if (that.has_result_type()) me.set_result_type((ACM_Type*)copyNode(that.get_result_type ())); + for (ACM_Container ::iterator i = that.get_arg_types ().begin (); i != that.get_arg_types ().end (); ++i) + me.get_arg_types ().insert ((ACM_Type*)copyNode(*i)); + me.set_kind(that.get_kind()); + me.set_variadic_args(that.get_variadic_args()); + me.set_cv_qualifiers(that.get_cv_qualifiers()); + + // reference attribute 'static_in' copied, address(es) must be adapted later + if (that.has_static_in()) me.set_static_in(that.get_static_in ()); + + // reference attribute 'calls' copied, address(es) must be adapted later + for (ACM_Container ::iterator i = that.get_calls ().begin (); i != that.get_calls ().end (); ++i) + me.get_calls ().insert ((ACM_Call*)*i); +} +void ProjectModel::copyVariable(ACM_Variable &me, ACM_Variable &that) { + copyName(me, that); + me.set_type((ACM_Type*)copyNode(that.get_type ())); + me.set_kind(that.get_kind()); +} +void ProjectModel::copyClass(ACM_Class &me, ACM_Class &that) { + copyName(me, that); + + // reference attribute 'bases' copied, address(es) must be adapted later + for (ACM_Container ::iterator i = that.get_bases ().begin (); i != that.get_bases ().end (); ++i) + me.get_bases ().insert ((ACM_Class*)*i); + + // reference attribute 'derived' copied, address(es) must be adapted later + for (ACM_Container ::iterator i = that.get_derived ().begin (); i != that.get_derived ().end (); ++i) + me.get_derived ().insert ((ACM_Class*)*i); + me.set_intro_target(that.get_intro_target()); + if (that.has_plan()) me.set_plan((ACM_ClassPlan*)copyNode(that.get_plan ())); +} +void ProjectModel::copyClassSlice(ACM_ClassSlice &me, ACM_ClassSlice &that) { + copyName(me, that); + me.set_is_struct(that.get_is_struct()); +} +void ProjectModel::copyCode(ACM_Code &me, ACM_Code &that) { + copyAny(me, that); + if (that.has_plan()) me.set_plan((ACM_CodePlan*)copyNode(that.get_plan ())); +} +void ProjectModel::copyAccess(ACM_Access &me, ACM_Access &that) { + copyCode(me, that); + me.set_lid(that.get_lid()); + if (that.has_target_object_lid()) me.set_target_object_lid(that.get_target_object_lid()); + if (that.has_cfg_block_lid()) me.set_cfg_block_lid(that.get_cfg_block_lid()); + + // reference attribute 'target_class' copied, address(es) must be adapted later + if (that.has_target_class()) me.set_target_class(that.get_target_class ()); +} +void ProjectModel::copyGet(ACM_Get &me, ACM_Get &that) { + copyAccess(me, that); + + // reference attribute 'variable' copied, address(es) must be adapted later + if (that.has_variable()) me.set_variable(that.get_variable ()); +} +void ProjectModel::copySet(ACM_Set &me, ACM_Set &that) { + copyAccess(me, that); + + // reference attribute 'variable' copied, address(es) must be adapted later + if (that.has_variable()) me.set_variable(that.get_variable ()); +} +void ProjectModel::copyCall(ACM_Call &me, ACM_Call &that) { + copyAccess(me, that); + + // reference attribute 'target' copied, address(es) must be adapted later + me.set_target(that.get_target ()); + for (ACM_Container ::iterator i = that.get_variadic_arg_types ().begin (); i != that.get_variadic_arg_types ().end (); ++i) + me.get_variadic_arg_types ().insert ((ACM_Type*)copyNode(*i)); + if (that.has_default_args()) me.set_default_args(that.get_default_args()); +} +void ProjectModel::copyBuiltin(ACM_Builtin &me, ACM_Builtin &that) { + copyAccess(me, that); + + // reference attribute 'target' copied, address(es) must be adapted later + me.set_target(that.get_target ()); + for (ACM_Container ::iterator i = that.get_implicit_access ().begin (); i != that.get_implicit_access ().end (); ++i) + me.get_implicit_access ().insert ((ACM_Access*)copyNode(*i)); +} +void ProjectModel::copyRef(ACM_Ref &me, ACM_Ref &that) { + copyAccess(me, that); + + // reference attribute 'variable' copied, address(es) must be adapted later + me.set_variable(that.get_variable ()); + me.set_type((ACM_Type*)copyNode(that.get_type ())); +} +void ProjectModel::copyGetRef(ACM_GetRef &me, ACM_GetRef &that) { + copyAccess(me, that); + me.set_type((ACM_Type*)copyNode(that.get_type ())); +} +void ProjectModel::copySetRef(ACM_SetRef &me, ACM_SetRef &that) { + copyAccess(me, that); + me.set_type((ACM_Type*)copyNode(that.get_type ())); +} +void ProjectModel::copyCallRef(ACM_CallRef &me, ACM_CallRef &that) { + copyAccess(me, that); + me.set_type((ACM_Type*)copyNode(that.get_type ())); +} +void ProjectModel::copyExecution(ACM_Execution &me, ACM_Execution &that) { + copyCode(me, that); +} +void ProjectModel::copyConstruction(ACM_Construction &me, ACM_Construction &that) { + copyCode(me, that); +} +void ProjectModel::copyDestruction(ACM_Destruction &me, ACM_Destruction &that) { + copyCode(me, that); +} +void ProjectModel::copyPointcut(ACM_Pointcut &me, ACM_Pointcut &that) { + copyName(me, that); + me.set_expr(that.get_expr()); + for (ACM_Container ::iterator i = that.get_args ().begin (); i != that.get_args ().end (); ++i) + me.get_args ().insert ((ACM_Arg*)copyNode(*i)); + me.set_kind(that.get_kind()); + // TODO: copy complex object parsed_expr here +} +void ProjectModel::copyAttribute(ACM_Attribute &me, ACM_Attribute &that) { + copyName(me, that); + for (ACM_Container ::iterator i = that.get_args ().begin (); i != that.get_args ().end (); ++i) + me.get_args ().insert ((ACM_Arg*)copyNode(*i)); +} +void ProjectModel::copyAdvice(ACM_Advice &me, ACM_Advice &that) { + copyAny(me, that); + me.set_pointcut((ACM_Pointcut*)copyNode(that.get_pointcut ())); + me.set_lid(that.get_lid()); +} +void ProjectModel::copyAdviceCode(ACM_AdviceCode &me, ACM_AdviceCode &that) { + copyAdvice(me, that); + me.set_kind(that.get_kind()); + me.set_context(that.get_context()); +} +void ProjectModel::copyIntroduction(ACM_Introduction &me, ACM_Introduction &that) { + copyAdvice(me, that); + + // reference attribute 'named_slice' copied, address(es) must be adapted later + if (that.has_named_slice()) me.set_named_slice(that.get_named_slice ()); + if (that.has_anon_slice()) me.set_anon_slice((ACM_ClassSlice*)copyNode(that.get_anon_slice ())); +} +void ProjectModel::copyOrder(ACM_Order &me, ACM_Order &that) { + copyAdvice(me, that); + for (ACM_Container ::iterator i = that.get_aspect_exprs ().begin (); i != that.get_aspect_exprs ().end (); ++i) + me.get_aspect_exprs ().insert ((ACM_Pointcut*)copyNode(*i)); +} +void ProjectModel::copyAspect(ACM_Aspect &me, ACM_Aspect &that) { + copyClass(me, that); + for (ACM_Container ::iterator i = that.get_intros ().begin (); i != that.get_intros ().end (); ++i) + me.get_intros ().insert ((ACM_Introduction*)copyNode(*i)); + for (ACM_Container ::iterator i = that.get_advices ().begin (); i != that.get_advices ().end (); ++i) + me.get_advices ().insert ((ACM_AdviceCode*)copyNode(*i)); + for (ACM_Container ::iterator i = that.get_orders ().begin (); i != that.get_orders ().end (); ++i) + me.get_orders ().insert ((ACM_Order*)copyNode(*i)); +} +void ProjectModel::copySpeculation(ACM_Speculation &me, ACM_Speculation &that) { + copyNode(me, that); + + // reference attribute 'advice' copied, address(es) must be adapted later + me.set_advice(that.get_advice ()); + + // reference attribute 'tunit' copied, address(es) must be adapted later + me.set_tunit(that.get_tunit ()); + + // reference attribute 'true_jps' copied, address(es) must be adapted later + for (ACM_Container ::iterator i = that.get_true_jps ().begin (); i != that.get_true_jps ().end (); ++i) + me.get_true_jps ().insert ((ACM_Any*)*i); + + // reference attribute 'false_jps' copied, address(es) must be adapted later + for (ACM_Container ::iterator i = that.get_false_jps ().begin (); i != that.get_false_jps ().end (); ++i) + me.get_false_jps ().insert ((ACM_Any*)*i); + + // reference attribute 'conditional_jps' copied, address(es) must be adapted later + for (ACM_Container ::iterator i = that.get_conditional_jps ().begin (); i != that.get_conditional_jps ().end (); ++i) + me.get_conditional_jps ().insert ((ACM_Any*)*i); +} +void ProjectModel::copyModel(ACM_Model &me, ACM_Model &that) { + copyNode(me, that); + for (ACM_Container ::iterator i = that.get_files ().begin (); i != that.get_files ().end (); ++i) + me.get_files ().insert ((ACM_File*)copyNode(*i)); + me.set_root((ACM_Namespace*)copyNode(that.get_root ())); + for (ACM_Container ::iterator i = that.get_speculations ().begin (); i != that.get_speculations ().end (); ++i) + me.get_speculations ().insert ((ACM_Speculation*)copyNode(*i)); + me.set_version(that.get_version()); +} + +// remove all out-dated model elements +bool ProjectModel::sourceCleanupNode(ACM_Node &me) { + return false; +} +bool ProjectModel::sourceCleanupFile(ACM_File &me) { + if (sourceCleanupNode(me)) + return true; + return false; +} +bool ProjectModel::sourceCleanupTUnit(ACM_TUnit &me) { + if (sourceCleanupFile(me)) + return true; + return false; +} +bool ProjectModel::sourceCleanupHeader(ACM_Header &me) { + if (sourceCleanupFile(me)) + return true; + sourceCleanupContainer(me.get_in ()); + return false; +} +bool ProjectModel::sourceCleanupSource(ACM_Source &me) { + if (sourceCleanupNode(me)) + return true; + int merge_count_file = me.get_file ()->get_merge_count (); + me.get_file ()->set_merge_count (_merge_id); + if ((merge_count_file == _merge_id) ? me.get_file ()->is_deleted () : sourceCleanupFile(*me.get_file ())) + return true; + return false; +} +bool ProjectModel::sourceCleanupMemberIntro(ACM_MemberIntro &me) { + if (sourceCleanupNode(me)) + return true; + int merge_count_intro = me.get_intro ()->get_merge_count (); + me.get_intro ()->set_merge_count (_merge_id); + if ((merge_count_intro == _merge_id) ? me.get_intro ()->is_deleted () : sourceCleanupIntroduction(*me.get_intro ())) + return true; + sourceCleanupContainer(me.get_members ()); + return false; +} +bool ProjectModel::sourceCleanupBaseIntro(ACM_BaseIntro &me) { + if (sourceCleanupNode(me)) + return true; + int merge_count_intro = me.get_intro ()->get_merge_count (); + me.get_intro ()->set_merge_count (_merge_id); + if ((merge_count_intro == _merge_id) ? me.get_intro ()->is_deleted () : sourceCleanupIntroduction(*me.get_intro ())) + return true; + sourceCleanupContainer(me.get_bases ()); + return false; +} +bool ProjectModel::sourceCleanupClassPlan(ACM_ClassPlan &me) { + if (sourceCleanupNode(me)) + return true; + sourceCleanupContainer(me.get_base_intros ()); + sourceCleanupContainer(me.get_member_intros ()); + return false; +} +bool ProjectModel::sourceCleanupCodeAdvice(ACM_CodeAdvice &me) { + if (sourceCleanupNode(me)) + return true; + int merge_count_advice = me.get_advice ()->get_merge_count (); + me.get_advice ()->set_merge_count (_merge_id); + if ((merge_count_advice == _merge_id) ? me.get_advice ()->is_deleted () : sourceCleanupAdviceCode(*me.get_advice ())) + return true; + return false; +} +bool ProjectModel::sourceCleanupCodePlan(ACM_CodePlan &me) { + if (sourceCleanupNode(me)) + return true; + sourceCleanupContainer(me.get_before ()); + if (me.has_around ()) { + int merge_count_around = me.get_around ()->get_merge_count (); + me.get_around ()->set_merge_count (_merge_id); + if ((merge_count_around == _merge_id) ? me.get_around ()->is_deleted () : sourceCleanupCodeAdvice(*me.get_around ())) + return true; + } + sourceCleanupContainer(me.get_after ()); + if (me.has_next_level ()) { + int merge_count_next_level = me.get_next_level ()->get_merge_count (); + me.get_next_level ()->set_merge_count (_merge_id); + if ((merge_count_next_level == _merge_id) ? me.get_next_level ()->is_deleted () : sourceCleanupCodePlan(*me.get_next_level ())) + return true; + } + return false; +} +bool ProjectModel::sourceCleanupAny(ACM_Any &me) { + if (sourceCleanupNode(me)) + return true; + if (purgeSources (me)) { + unlink_node(&me); + return true; + } + sourceCleanupContainer(me.get_attributes ()); + return false; +} +bool ProjectModel::sourceCleanupType(ACM_Type &me) { + if (sourceCleanupAny(me)) + return true; + return false; +} +bool ProjectModel::sourceCleanupArg(ACM_Arg &me) { + if (sourceCleanupAny(me)) + return true; + return false; +} +bool ProjectModel::sourceCleanupName(ACM_Name &me) { + if (sourceCleanupAny(me)) + return true; + sourceCleanupContainer(me.get_children ()); + sourceCleanupContainer(me.get_tunits ()); + return false; +} +bool ProjectModel::sourceCleanupNamespace(ACM_Namespace &me) { + if (sourceCleanupName(me)) + return true; + return false; +} +bool ProjectModel::sourceCleanupFunction(ACM_Function &me) { + if (sourceCleanupName(me)) + return true; + if (me.has_result_type ()) { + int merge_count_result_type = me.get_result_type ()->get_merge_count (); + me.get_result_type ()->set_merge_count (_merge_id); + if ((merge_count_result_type == _merge_id) ? me.get_result_type ()->is_deleted () : sourceCleanupType(*me.get_result_type ())) + return true; + } + sourceCleanupContainer(me.get_arg_types ()); + if (me.has_static_in ()) { + int merge_count_static_in = me.get_static_in ()->get_merge_count (); + me.get_static_in ()->set_merge_count (_merge_id); + if ((merge_count_static_in == _merge_id) ? me.get_static_in ()->is_deleted () : sourceCleanupTUnit(*me.get_static_in ())) + return true; + } + sourceCleanupContainer(me.get_calls ()); + return false; +} +bool ProjectModel::sourceCleanupVariable(ACM_Variable &me) { + if (sourceCleanupName(me)) + return true; + int merge_count_type = me.get_type ()->get_merge_count (); + me.get_type ()->set_merge_count (_merge_id); + if ((merge_count_type == _merge_id) ? me.get_type ()->is_deleted () : sourceCleanupType(*me.get_type ())) + return true; + return false; +} +bool ProjectModel::sourceCleanupClass(ACM_Class &me) { + if (sourceCleanupName(me)) + return true; + sourceCleanupContainer(me.get_bases ()); + sourceCleanupContainer(me.get_derived ()); + if (me.has_plan ()) { + int merge_count_plan = me.get_plan ()->get_merge_count (); + me.get_plan ()->set_merge_count (_merge_id); + if ((merge_count_plan == _merge_id) ? me.get_plan ()->is_deleted () : sourceCleanupClassPlan(*me.get_plan ())) + return true; + } + return false; +} +bool ProjectModel::sourceCleanupClassSlice(ACM_ClassSlice &me) { + if (sourceCleanupName(me)) + return true; + return false; +} +bool ProjectModel::sourceCleanupCode(ACM_Code &me) { + if (sourceCleanupAny(me)) + return true; + if (me.has_plan ()) { + int merge_count_plan = me.get_plan ()->get_merge_count (); + me.get_plan ()->set_merge_count (_merge_id); + if ((merge_count_plan == _merge_id) ? me.get_plan ()->is_deleted () : sourceCleanupCodePlan(*me.get_plan ())) + return true; + } + return false; +} +bool ProjectModel::sourceCleanupAccess(ACM_Access &me) { + if (sourceCleanupCode(me)) + return true; + if (me.has_target_class ()) { + int merge_count_target_class = me.get_target_class ()->get_merge_count (); + me.get_target_class ()->set_merge_count (_merge_id); + if ((merge_count_target_class == _merge_id) ? me.get_target_class ()->is_deleted () : sourceCleanupClass(*me.get_target_class ())) + return true; + } + return false; +} +bool ProjectModel::sourceCleanupGet(ACM_Get &me) { + if (sourceCleanupAccess(me)) + return true; + if (me.has_variable ()) { + int merge_count_variable = me.get_variable ()->get_merge_count (); + me.get_variable ()->set_merge_count (_merge_id); + if ((merge_count_variable == _merge_id) ? me.get_variable ()->is_deleted () : sourceCleanupVariable(*me.get_variable ())) + return true; + } + return false; +} +bool ProjectModel::sourceCleanupSet(ACM_Set &me) { + if (sourceCleanupAccess(me)) + return true; + if (me.has_variable ()) { + int merge_count_variable = me.get_variable ()->get_merge_count (); + me.get_variable ()->set_merge_count (_merge_id); + if ((merge_count_variable == _merge_id) ? me.get_variable ()->is_deleted () : sourceCleanupVariable(*me.get_variable ())) + return true; + } + return false; +} +bool ProjectModel::sourceCleanupCall(ACM_Call &me) { + if (sourceCleanupAccess(me)) + return true; + int merge_count_target = me.get_target ()->get_merge_count (); + me.get_target ()->set_merge_count (_merge_id); + if ((merge_count_target == _merge_id) ? me.get_target ()->is_deleted () : sourceCleanupFunction(*me.get_target ())) + return true; + sourceCleanupContainer(me.get_variadic_arg_types ()); + return false; +} +bool ProjectModel::sourceCleanupBuiltin(ACM_Builtin &me) { + if (sourceCleanupAccess(me)) + return true; + int merge_count_target = me.get_target ()->get_merge_count (); + me.get_target ()->set_merge_count (_merge_id); + if ((merge_count_target == _merge_id) ? me.get_target ()->is_deleted () : sourceCleanupFunction(*me.get_target ())) + return true; + sourceCleanupContainer(me.get_implicit_access ()); + return false; +} +bool ProjectModel::sourceCleanupRef(ACM_Ref &me) { + if (sourceCleanupAccess(me)) + return true; + int merge_count_variable = me.get_variable ()->get_merge_count (); + me.get_variable ()->set_merge_count (_merge_id); + if ((merge_count_variable == _merge_id) ? me.get_variable ()->is_deleted () : sourceCleanupVariable(*me.get_variable ())) + return true; + int merge_count_type = me.get_type ()->get_merge_count (); + me.get_type ()->set_merge_count (_merge_id); + if ((merge_count_type == _merge_id) ? me.get_type ()->is_deleted () : sourceCleanupType(*me.get_type ())) + return true; + return false; +} +bool ProjectModel::sourceCleanupGetRef(ACM_GetRef &me) { + if (sourceCleanupAccess(me)) + return true; + int merge_count_type = me.get_type ()->get_merge_count (); + me.get_type ()->set_merge_count (_merge_id); + if ((merge_count_type == _merge_id) ? me.get_type ()->is_deleted () : sourceCleanupType(*me.get_type ())) + return true; + return false; +} +bool ProjectModel::sourceCleanupSetRef(ACM_SetRef &me) { + if (sourceCleanupAccess(me)) + return true; + int merge_count_type = me.get_type ()->get_merge_count (); + me.get_type ()->set_merge_count (_merge_id); + if ((merge_count_type == _merge_id) ? me.get_type ()->is_deleted () : sourceCleanupType(*me.get_type ())) + return true; + return false; +} +bool ProjectModel::sourceCleanupCallRef(ACM_CallRef &me) { + if (sourceCleanupAccess(me)) + return true; + int merge_count_type = me.get_type ()->get_merge_count (); + me.get_type ()->set_merge_count (_merge_id); + if ((merge_count_type == _merge_id) ? me.get_type ()->is_deleted () : sourceCleanupType(*me.get_type ())) + return true; + return false; +} +bool ProjectModel::sourceCleanupExecution(ACM_Execution &me) { + if (sourceCleanupCode(me)) + return true; + return false; +} +bool ProjectModel::sourceCleanupConstruction(ACM_Construction &me) { + if (sourceCleanupCode(me)) + return true; + return false; +} +bool ProjectModel::sourceCleanupDestruction(ACM_Destruction &me) { + if (sourceCleanupCode(me)) + return true; + return false; +} +bool ProjectModel::sourceCleanupPointcut(ACM_Pointcut &me) { + if (sourceCleanupName(me)) + return true; + sourceCleanupContainer(me.get_args ()); + return false; +} +bool ProjectModel::sourceCleanupAttribute(ACM_Attribute &me) { + if (sourceCleanupName(me)) + return true; + sourceCleanupContainer(me.get_args ()); + return false; +} +bool ProjectModel::sourceCleanupAdvice(ACM_Advice &me) { + if (sourceCleanupAny(me)) + return true; + int merge_count_pointcut = me.get_pointcut ()->get_merge_count (); + me.get_pointcut ()->set_merge_count (_merge_id); + if ((merge_count_pointcut == _merge_id) ? me.get_pointcut ()->is_deleted () : sourceCleanupPointcut(*me.get_pointcut ())) + return true; + return false; +} +bool ProjectModel::sourceCleanupAdviceCode(ACM_AdviceCode &me) { + if (sourceCleanupAdvice(me)) + return true; + return false; +} +bool ProjectModel::sourceCleanupIntroduction(ACM_Introduction &me) { + if (sourceCleanupAdvice(me)) + return true; + if (me.has_named_slice ()) { + int merge_count_named_slice = me.get_named_slice ()->get_merge_count (); + me.get_named_slice ()->set_merge_count (_merge_id); + if ((merge_count_named_slice == _merge_id) ? me.get_named_slice ()->is_deleted () : sourceCleanupClassSlice(*me.get_named_slice ())) + return true; + } + if (me.has_anon_slice ()) { + int merge_count_anon_slice = me.get_anon_slice ()->get_merge_count (); + me.get_anon_slice ()->set_merge_count (_merge_id); + if ((merge_count_anon_slice == _merge_id) ? me.get_anon_slice ()->is_deleted () : sourceCleanupClassSlice(*me.get_anon_slice ())) + return true; + } + return false; +} +bool ProjectModel::sourceCleanupOrder(ACM_Order &me) { + if (sourceCleanupAdvice(me)) + return true; + sourceCleanupContainer(me.get_aspect_exprs ()); + return false; +} +bool ProjectModel::sourceCleanupAspect(ACM_Aspect &me) { + if (sourceCleanupClass(me)) + return true; + sourceCleanupContainer(me.get_intros ()); + sourceCleanupContainer(me.get_advices ()); + sourceCleanupContainer(me.get_orders ()); + return false; +} +bool ProjectModel::sourceCleanupSpeculation(ACM_Speculation &me) { + if (sourceCleanupNode(me)) + return true; + int merge_count_advice = me.get_advice ()->get_merge_count (); + me.get_advice ()->set_merge_count (_merge_id); + if ((merge_count_advice == _merge_id) ? me.get_advice ()->is_deleted () : sourceCleanupAdvice(*me.get_advice ())) + return true; + int merge_count_tunit = me.get_tunit ()->get_merge_count (); + me.get_tunit ()->set_merge_count (_merge_id); + if ((merge_count_tunit == _merge_id) ? me.get_tunit ()->is_deleted () : sourceCleanupTUnit(*me.get_tunit ())) + return true; + sourceCleanupContainer(me.get_true_jps ()); + sourceCleanupContainer(me.get_false_jps ()); + sourceCleanupContainer(me.get_conditional_jps ()); + return false; +} +bool ProjectModel::sourceCleanupModel(ACM_Model &me) { + if (sourceCleanupNode(me)) + return true; + sourceCleanupContainer(me.get_files ()); + int merge_count_root = me.get_root ()->get_merge_count (); + me.get_root ()->set_merge_count (_merge_id); + if ((merge_count_root == _merge_id) ? me.get_root ()->is_deleted () : sourceCleanupNamespace(*me.get_root ())) + return true; + sourceCleanupContainer(me.get_speculations ()); + return false; +} + +// merge methods that are called for corresponding translation unit model +// and project model nodes. The functions call merge or copy functions on +// their aggregated sub-nodes. +void ProjectModel::mergeNode(ACM_Node &me, ACM_Node &that) { +} +void ProjectModel::mergeFile(ACM_File &me, ACM_File &that) { + mergeNode(me, that); + if (that.get_len () != me.get_len ()) { + if (merge_attr (me, that, "len")) + me.set_len (that.get_len ()); + } + if (that.get_time () != me.get_time ()) { + if (merge_attr (me, that, "time")) + me.set_time (that.get_time ()); + } +} +void ProjectModel::mergeTUnit(ACM_TUnit &me, ACM_TUnit &that) { + mergeFile(me, that); + if (that.get_dirty_flag () != me.get_dirty_flag ()) { + if (merge_attr (me, that, "dirty_flag")) + me.set_dirty_flag (that.get_dirty_flag ()); + } +} +void ProjectModel::mergeHeader(ACM_Header &me, ACM_Header &that) { + mergeFile(me, that); + merge_container (that.get_in (), me.get_in (), true); +} +void ProjectModel::mergeSource(ACM_Source &me, ACM_Source &that) { + mergeNode(me, that); + // TODO: implement merging for reference member 'file' -> is that all? + me.set_file(that.get_file ()); + if (that.get_len () != me.get_len ()) { + if (merge_attr (me, that, "len")) + me.set_len (that.get_len ()); + } +} +void ProjectModel::mergeMemberIntro(ACM_MemberIntro &me, ACM_MemberIntro &that) { + mergeNode(me, that); + // TODO: implement merging for reference member 'intro' -> is that all? + me.set_intro(that.get_intro ()); + merge_container (that.get_members (), me.get_members (), true); +} +void ProjectModel::mergeBaseIntro(ACM_BaseIntro &me, ACM_BaseIntro &that) { + mergeNode(me, that); + // TODO: implement merging for reference member 'intro' -> is that all? + me.set_intro(that.get_intro ()); + merge_container (that.get_bases (), me.get_bases (), true); +} +void ProjectModel::mergeClassPlan(ACM_ClassPlan &me, ACM_ClassPlan &that) { + mergeNode(me, that); + merge_container (that.get_base_intros (), me.get_base_intros ()); + merge_container (that.get_member_intros (), me.get_member_intros ()); +} +void ProjectModel::mergeCodeAdvice(ACM_CodeAdvice &me, ACM_CodeAdvice &that) { + mergeNode(me, that); + // TODO: implement merging for reference member 'advice' -> is that all? + me.set_advice(that.get_advice ()); + if (that.get_conditional () != me.get_conditional ()) { + if (merge_attr (me, that, "conditional")) + me.set_conditional (that.get_conditional ()); + } +} +void ProjectModel::mergeCodePlan(ACM_CodePlan &me, ACM_CodePlan &that) { + mergeNode(me, that); + merge_container (that.get_before (), me.get_before ()); + // TODO: handle merging of optional attribute 'around' -> like this? + if (me.has_around () && that.has_around ()) + merge_node (me.get_around (), that.get_around ()); + else if (that.has_around ()) + me.set_around((ACM_CodeAdvice*)copyNode (that.get_around ())); + merge_container (that.get_after (), me.get_after ()); + // TODO: handle merging of optional attribute 'next_level' -> like this? + if (me.has_next_level () && that.has_next_level ()) + merge_node (me.get_next_level (), that.get_next_level ()); + else if (that.has_next_level ()) + me.set_next_level((ACM_CodePlan*)copyNode (that.get_next_level ())); +} +void ProjectModel::mergeAny(ACM_Any &me, ACM_Any &that) { + mergeNode(me, that); + if (that.has_jpid () && !me.has_jpid ()) + merge_attr_only_in_that (me, that, "jpid"); + else if (!that.has_jpid () && me.has_jpid ()) + merge_attr_only_in_me (me, that, "jpid"); + else if (that.has_jpid () && me.has_jpid () && + that.get_jpid () != me.get_jpid ()) { + if (merge_attr (me, that, "jpid")) + me.set_jpid (that.get_jpid ()); + } + merge_container (that.get_source (), me.get_source ()); + merge_container (that.get_attributes (), me.get_attributes (), true); +} +void ProjectModel::mergeType(ACM_Type &me, ACM_Type &that) { + mergeAny(me, that); +} +void ProjectModel::mergeArg(ACM_Arg &me, ACM_Arg &that) { + mergeAny(me, that); + if (that.get_type () != me.get_type ()) { + if (merge_attr (me, that, "type")) + me.set_type (that.get_type ()); + } +} +void ProjectModel::mergeName(ACM_Name &me, ACM_Name &that) { + mergeAny(me, that); + merge_container (that.get_children (), me.get_children ()); + if (that.get_builtin () != me.get_builtin ()) { + if (merge_attr (me, that, "builtin")) + me.set_builtin (that.get_builtin ()); + } + merge_container (that.get_tunits (), me.get_tunits (), true); +} +void ProjectModel::mergeNamespace(ACM_Namespace &me, ACM_Namespace &that) { + mergeName(me, that); +} +void ProjectModel::mergeFunction(ACM_Function &me, ACM_Function &that) { + mergeName(me, that); + // TODO: handle merging of optional attribute 'result_type' -> like this? + if (me.has_result_type () && that.has_result_type ()) + merge_node (me.get_result_type (), that.get_result_type ()); + else if (that.has_result_type ()) + me.set_result_type((ACM_Type*)copyNode (that.get_result_type ())); + merge_container (that.get_arg_types (), me.get_arg_types ()); + if (that.get_kind () != me.get_kind ()) { + if (merge_attr (me, that, "kind")) + me.set_kind (that.get_kind ()); + } + if (that.get_variadic_args () != me.get_variadic_args ()) { + if (merge_attr (me, that, "variadic_args")) + me.set_variadic_args (that.get_variadic_args ()); + } + // TODO: implement merging for reference member 'static_in' -> is that all? + // TODO: What if the reference named slices are different in the two models? + if (that.has_static_in ()) + me.set_static_in(that.get_static_in ()); + merge_container (that.get_calls (), me.get_calls (), true); +} +void ProjectModel::mergeVariable(ACM_Variable &me, ACM_Variable &that) { + mergeName(me, that); + merge_node (me.get_type (), that.get_type ()); + if (that.get_kind () != me.get_kind ()) { + if (merge_attr (me, that, "kind")) + me.set_kind (that.get_kind ()); + } +} +void ProjectModel::mergeClass(ACM_Class &me, ACM_Class &that) { + mergeName(me, that); + merge_container (that.get_bases (), me.get_bases (), true); + merge_container (that.get_derived (), me.get_derived (), true); + // TODO: handle merging of optional attribute 'plan' -> like this? + if (me.has_plan () && that.has_plan ()) + merge_node (me.get_plan (), that.get_plan ()); + else if (that.has_plan ()) + me.set_plan((ACM_ClassPlan*)copyNode (that.get_plan ())); +} +void ProjectModel::mergeClassSlice(ACM_ClassSlice &me, ACM_ClassSlice &that) { + mergeName(me, that); + if (that.get_is_struct () != me.get_is_struct ()) { + if (merge_attr (me, that, "is_struct")) + me.set_is_struct (that.get_is_struct ()); + } +} +void ProjectModel::mergeCode(ACM_Code &me, ACM_Code &that) { + mergeAny(me, that); + // TODO: handle merging of optional attribute 'plan' -> like this? + if (me.has_plan () && that.has_plan ()) + merge_node (me.get_plan (), that.get_plan ()); + else if (that.has_plan ()) + me.set_plan((ACM_CodePlan*)copyNode (that.get_plan ())); +} +void ProjectModel::mergeAccess(ACM_Access &me, ACM_Access &that) { + mergeCode(me, that); + if (that.has_target_object_lid () && !me.has_target_object_lid ()) + merge_attr_only_in_that (me, that, "target_object_lid"); + else if (!that.has_target_object_lid () && me.has_target_object_lid ()) + merge_attr_only_in_me (me, that, "target_object_lid"); + else if (that.has_target_object_lid () && me.has_target_object_lid () && + that.get_target_object_lid () != me.get_target_object_lid ()) { + if (merge_attr (me, that, "target_object_lid")) + me.set_target_object_lid (that.get_target_object_lid ()); + } + if (that.has_cfg_block_lid () && !me.has_cfg_block_lid ()) + merge_attr_only_in_that (me, that, "cfg_block_lid"); + else if (!that.has_cfg_block_lid () && me.has_cfg_block_lid ()) + merge_attr_only_in_me (me, that, "cfg_block_lid"); + else if (that.has_cfg_block_lid () && me.has_cfg_block_lid () && + that.get_cfg_block_lid () != me.get_cfg_block_lid ()) { + if (merge_attr (me, that, "cfg_block_lid")) + me.set_cfg_block_lid (that.get_cfg_block_lid ()); + } + // TODO: implement merging for reference member 'target_class' -> is that all? + // TODO: What if the reference named slices are different in the two models? + if (that.has_target_class ()) + me.set_target_class(that.get_target_class ()); +} +void ProjectModel::mergeGet(ACM_Get &me, ACM_Get &that) { + mergeAccess(me, that); + // TODO: implement merging for reference member 'variable' -> is that all? + // TODO: What if the reference named slices are different in the two models? + if (that.has_variable ()) + me.set_variable(that.get_variable ()); +} +void ProjectModel::mergeSet(ACM_Set &me, ACM_Set &that) { + mergeAccess(me, that); + // TODO: implement merging for reference member 'variable' -> is that all? + // TODO: What if the reference named slices are different in the two models? + if (that.has_variable ()) + me.set_variable(that.get_variable ()); +} +void ProjectModel::mergeCall(ACM_Call &me, ACM_Call &that) { + mergeAccess(me, that); + // TODO: implement merging for reference member 'target' -> is that all? + me.set_target(that.get_target ()); + merge_container (that.get_variadic_arg_types (), me.get_variadic_arg_types ()); + if (that.has_default_args () && !me.has_default_args ()) + merge_attr_only_in_that (me, that, "default_args"); + else if (!that.has_default_args () && me.has_default_args ()) + merge_attr_only_in_me (me, that, "default_args"); + else if (that.has_default_args () && me.has_default_args () && + that.get_default_args () != me.get_default_args ()) { + if (merge_attr (me, that, "default_args")) + me.set_default_args (that.get_default_args ()); + } +} +void ProjectModel::mergeBuiltin(ACM_Builtin &me, ACM_Builtin &that) { + mergeAccess(me, that); + // TODO: implement merging for reference member 'target' -> is that all? + me.set_target(that.get_target ()); + merge_container (that.get_implicit_access (), me.get_implicit_access ()); +} +void ProjectModel::mergeRef(ACM_Ref &me, ACM_Ref &that) { + mergeAccess(me, that); + // TODO: implement merging for reference member 'variable' -> is that all? + me.set_variable(that.get_variable ()); + merge_node (me.get_type (), that.get_type ()); +} +void ProjectModel::mergeGetRef(ACM_GetRef &me, ACM_GetRef &that) { + mergeAccess(me, that); + merge_node (me.get_type (), that.get_type ()); +} +void ProjectModel::mergeSetRef(ACM_SetRef &me, ACM_SetRef &that) { + mergeAccess(me, that); + merge_node (me.get_type (), that.get_type ()); +} +void ProjectModel::mergeCallRef(ACM_CallRef &me, ACM_CallRef &that) { + mergeAccess(me, that); + merge_node (me.get_type (), that.get_type ()); +} +void ProjectModel::mergeExecution(ACM_Execution &me, ACM_Execution &that) { + mergeCode(me, that); +} +void ProjectModel::mergeConstruction(ACM_Construction &me, ACM_Construction &that) { + mergeCode(me, that); +} +void ProjectModel::mergeDestruction(ACM_Destruction &me, ACM_Destruction &that) { + mergeCode(me, that); +} +void ProjectModel::mergePointcut(ACM_Pointcut &me, ACM_Pointcut &that) { + mergeName(me, that); + if (that.get_expr () != me.get_expr ()) { + if (merge_attr (me, that, "expr")) + me.set_expr (that.get_expr ()); + } + merge_container (that.get_args (), me.get_args ()); + if (that.get_kind () != me.get_kind ()) { + if (merge_attr (me, that, "kind")) + me.set_kind (that.get_kind ()); + } +} +void ProjectModel::mergeAttribute(ACM_Attribute &me, ACM_Attribute &that) { + mergeName(me, that); + merge_container (that.get_args (), me.get_args ()); +} +void ProjectModel::mergeAdvice(ACM_Advice &me, ACM_Advice &that) { + mergeAny(me, that); + merge_node (me.get_pointcut (), that.get_pointcut ()); +} +void ProjectModel::mergeAdviceCode(ACM_AdviceCode &me, ACM_AdviceCode &that) { + mergeAdvice(me, that); + if (that.get_kind () != me.get_kind ()) { + if (merge_attr (me, that, "kind")) + me.set_kind (that.get_kind ()); + } + if (that.get_context () != me.get_context ()) { + if (merge_attr (me, that, "context")) + me.set_context (that.get_context ()); + } +} +void ProjectModel::mergeIntroduction(ACM_Introduction &me, ACM_Introduction &that) { + mergeAdvice(me, that); + // TODO: implement merging for reference member 'named_slice' -> is that all? + // TODO: What if the reference named slices are different in the two models? + if (that.has_named_slice ()) + me.set_named_slice(that.get_named_slice ()); + // TODO: handle merging of optional attribute 'anon_slice' -> like this? + if (me.has_anon_slice () && that.has_anon_slice ()) + merge_node (me.get_anon_slice (), that.get_anon_slice ()); + else if (that.has_anon_slice ()) + me.set_anon_slice((ACM_ClassSlice*)copyNode (that.get_anon_slice ())); +} +void ProjectModel::mergeOrder(ACM_Order &me, ACM_Order &that) { + mergeAdvice(me, that); + merge_container (that.get_aspect_exprs (), me.get_aspect_exprs ()); +} +void ProjectModel::mergeAspect(ACM_Aspect &me, ACM_Aspect &that) { + mergeClass(me, that); + merge_container (that.get_intros (), me.get_intros ()); + merge_container (that.get_advices (), me.get_advices ()); + merge_container (that.get_orders (), me.get_orders ()); +} +void ProjectModel::mergeSpeculation(ACM_Speculation &me, ACM_Speculation &that) { + mergeNode(me, that); + // TODO: implement merging for reference member 'advice' -> is that all? + me.set_advice(that.get_advice ()); + // TODO: implement merging for reference member 'tunit' -> is that all? + me.set_tunit(that.get_tunit ()); + merge_container (that.get_true_jps (), me.get_true_jps (), true); + merge_container (that.get_false_jps (), me.get_false_jps (), true); + merge_container (that.get_conditional_jps (), me.get_conditional_jps (), true); +} +void ProjectModel::mergeModel(ACM_Model &me, ACM_Model &that) { + mergeNode(me, that); + merge_container (that.get_files (), me.get_files ()); + merge_node (me.get_root (), that.get_root ()); + merge_container (that.get_speculations (), me.get_speculations ()); + if (that.get_version () != me.get_version ()) { + if (merge_attr (me, that, "version")) + me.set_version (that.get_version ()); + } +} + +void ProjectModel::fix_refs_Node(ACM_Node &me) { +} +void ProjectModel::fix_refs_File(ACM_File &me) { + fix_refs_Node(me); +} +void ProjectModel::fix_refs_TUnit(ACM_TUnit &me) { + fix_refs_File(me); +} +void ProjectModel::fix_refs_Header(ACM_Header &me) { + fix_refs_File(me); + ACM_Container new_in; + for (ACM_Container ::iterator i = me.get_in ().begin (); i != me.get_in ().end (); ++i) + if ((*i)->get_partner ()) + new_in.insert ((ACM_TUnit*)(*i)->get_partner ()); + else + new_in.insert ((ACM_TUnit*)(*i)); + me.get_in () = new_in; +} +void ProjectModel::fix_refs_Source(ACM_Source &me) { + fix_refs_Node(me); + if (me.get_file ()->get_partner ()) + me.set_file((ACM_File*)me.get_file ()->get_partner ()); +} +void ProjectModel::fix_refs_MemberIntro(ACM_MemberIntro &me) { + fix_refs_Node(me); + if (me.get_intro ()->get_partner ()) + me.set_intro((ACM_Introduction*)me.get_intro ()->get_partner ()); + ACM_Container new_members; + for (ACM_Container ::iterator i = me.get_members ().begin (); i != me.get_members ().end (); ++i) + if ((*i)->get_partner ()) + new_members.insert ((ACM_Name*)(*i)->get_partner ()); + else + new_members.insert ((ACM_Name*)(*i)); + me.get_members () = new_members; +} +void ProjectModel::fix_refs_BaseIntro(ACM_BaseIntro &me) { + fix_refs_Node(me); + if (me.get_intro ()->get_partner ()) + me.set_intro((ACM_Introduction*)me.get_intro ()->get_partner ()); + ACM_Container new_bases; + for (ACM_Container ::iterator i = me.get_bases ().begin (); i != me.get_bases ().end (); ++i) + if ((*i)->get_partner ()) + new_bases.insert ((ACM_Class*)(*i)->get_partner ()); + else + new_bases.insert ((ACM_Class*)(*i)); + me.get_bases () = new_bases; +} +void ProjectModel::fix_refs_ClassPlan(ACM_ClassPlan &me) { + fix_refs_Node(me); + for (ACM_Container ::iterator i = me.get_base_intros ().begin (); i != me.get_base_intros ().end (); ++i) + fix_refs (*i); + for (ACM_Container ::iterator i = me.get_member_intros ().begin (); i != me.get_member_intros ().end (); ++i) + fix_refs (*i); +} +void ProjectModel::fix_refs_CodeAdvice(ACM_CodeAdvice &me) { + fix_refs_Node(me); + if (me.get_advice ()->get_partner ()) + me.set_advice((ACM_AdviceCode*)me.get_advice ()->get_partner ()); +} +void ProjectModel::fix_refs_CodePlan(ACM_CodePlan &me) { + fix_refs_Node(me); + for (ACM_Container ::iterator i = me.get_before ().begin (); i != me.get_before ().end (); ++i) + fix_refs (*i); + if (me.has_around()) fix_refs (me.get_around()); + for (ACM_Container ::iterator i = me.get_after ().begin (); i != me.get_after ().end (); ++i) + fix_refs (*i); + if (me.has_next_level()) fix_refs (me.get_next_level()); +} +void ProjectModel::fix_refs_Any(ACM_Any &me) { + fix_refs_Node(me); + for (ACM_Container ::iterator i = me.get_source ().begin (); i != me.get_source ().end (); ++i) + fix_refs (*i); + ACM_Container new_attributes; + for (ACM_Container ::iterator i = me.get_attributes ().begin (); i != me.get_attributes ().end (); ++i) + if ((*i)->get_partner ()) + new_attributes.insert ((ACM_Attribute*)(*i)->get_partner ()); + else + new_attributes.insert ((ACM_Attribute*)(*i)); + me.get_attributes () = new_attributes; +} +void ProjectModel::fix_refs_Type(ACM_Type &me) { + fix_refs_Any(me); +} +void ProjectModel::fix_refs_Arg(ACM_Arg &me) { + fix_refs_Any(me); +} +void ProjectModel::fix_refs_Name(ACM_Name &me) { + fix_refs_Any(me); + for (ACM_Container ::iterator i = me.get_children ().begin (); i != me.get_children ().end (); ++i) + fix_refs (*i); + ACM_Container new_tunits; + for (ACM_Container ::iterator i = me.get_tunits ().begin (); i != me.get_tunits ().end (); ++i) + if ((*i)->get_partner ()) + new_tunits.insert ((ACM_TUnit*)(*i)->get_partner ()); + else + new_tunits.insert ((ACM_TUnit*)(*i)); + me.get_tunits () = new_tunits; +} +void ProjectModel::fix_refs_Namespace(ACM_Namespace &me) { + fix_refs_Name(me); +} +void ProjectModel::fix_refs_Function(ACM_Function &me) { + fix_refs_Name(me); + if (me.has_result_type()) fix_refs (me.get_result_type()); + for (ACM_Container ::iterator i = me.get_arg_types ().begin (); i != me.get_arg_types ().end (); ++i) + fix_refs (*i); + if (me.has_static_in() && me.get_static_in ()->get_partner ()) + me.set_static_in((ACM_TUnit*)me.get_static_in ()->get_partner ()); + ACM_Container new_calls; + for (ACM_Container ::iterator i = me.get_calls ().begin (); i != me.get_calls ().end (); ++i) + if ((*i)->get_partner ()) + new_calls.insert ((ACM_Call*)(*i)->get_partner ()); + else + new_calls.insert ((ACM_Call*)(*i)); + me.get_calls () = new_calls; +} +void ProjectModel::fix_refs_Variable(ACM_Variable &me) { + fix_refs_Name(me); + fix_refs (me.get_type()); +} +void ProjectModel::fix_refs_Class(ACM_Class &me) { + fix_refs_Name(me); + ACM_Container new_bases; + for (ACM_Container ::iterator i = me.get_bases ().begin (); i != me.get_bases ().end (); ++i) + if ((*i)->get_partner ()) + new_bases.insert ((ACM_Class*)(*i)->get_partner ()); + else + new_bases.insert ((ACM_Class*)(*i)); + me.get_bases () = new_bases; + ACM_Container new_derived; + for (ACM_Container ::iterator i = me.get_derived ().begin (); i != me.get_derived ().end (); ++i) + if ((*i)->get_partner ()) + new_derived.insert ((ACM_Class*)(*i)->get_partner ()); + else + new_derived.insert ((ACM_Class*)(*i)); + me.get_derived () = new_derived; + if (me.has_plan()) fix_refs (me.get_plan()); +} +void ProjectModel::fix_refs_ClassSlice(ACM_ClassSlice &me) { + fix_refs_Name(me); +} +void ProjectModel::fix_refs_Code(ACM_Code &me) { + fix_refs_Any(me); + if (me.has_plan()) fix_refs (me.get_plan()); +} +void ProjectModel::fix_refs_Access(ACM_Access &me) { + fix_refs_Code(me); + if (me.has_target_class() && me.get_target_class ()->get_partner ()) + me.set_target_class((ACM_Class*)me.get_target_class ()->get_partner ()); +} +void ProjectModel::fix_refs_Get(ACM_Get &me) { + fix_refs_Access(me); + if (me.has_variable() && me.get_variable ()->get_partner ()) + me.set_variable((ACM_Variable*)me.get_variable ()->get_partner ()); +} +void ProjectModel::fix_refs_Set(ACM_Set &me) { + fix_refs_Access(me); + if (me.has_variable() && me.get_variable ()->get_partner ()) + me.set_variable((ACM_Variable*)me.get_variable ()->get_partner ()); +} +void ProjectModel::fix_refs_Call(ACM_Call &me) { + fix_refs_Access(me); + if (me.get_target ()->get_partner ()) + me.set_target((ACM_Function*)me.get_target ()->get_partner ()); + for (ACM_Container ::iterator i = me.get_variadic_arg_types ().begin (); i != me.get_variadic_arg_types ().end (); ++i) + fix_refs (*i); +} +void ProjectModel::fix_refs_Builtin(ACM_Builtin &me) { + fix_refs_Access(me); + if (me.get_target ()->get_partner ()) + me.set_target((ACM_Function*)me.get_target ()->get_partner ()); + for (ACM_Container ::iterator i = me.get_implicit_access ().begin (); i != me.get_implicit_access ().end (); ++i) + fix_refs (*i); +} +void ProjectModel::fix_refs_Ref(ACM_Ref &me) { + fix_refs_Access(me); + if (me.get_variable ()->get_partner ()) + me.set_variable((ACM_Variable*)me.get_variable ()->get_partner ()); + fix_refs (me.get_type()); +} +void ProjectModel::fix_refs_GetRef(ACM_GetRef &me) { + fix_refs_Access(me); + fix_refs (me.get_type()); +} +void ProjectModel::fix_refs_SetRef(ACM_SetRef &me) { + fix_refs_Access(me); + fix_refs (me.get_type()); +} +void ProjectModel::fix_refs_CallRef(ACM_CallRef &me) { + fix_refs_Access(me); + fix_refs (me.get_type()); +} +void ProjectModel::fix_refs_Execution(ACM_Execution &me) { + fix_refs_Code(me); +} +void ProjectModel::fix_refs_Construction(ACM_Construction &me) { + fix_refs_Code(me); +} +void ProjectModel::fix_refs_Destruction(ACM_Destruction &me) { + fix_refs_Code(me); +} +void ProjectModel::fix_refs_Pointcut(ACM_Pointcut &me) { + fix_refs_Name(me); + for (ACM_Container ::iterator i = me.get_args ().begin (); i != me.get_args ().end (); ++i) + fix_refs (*i); +} +void ProjectModel::fix_refs_Attribute(ACM_Attribute &me) { + fix_refs_Name(me); + for (ACM_Container ::iterator i = me.get_args ().begin (); i != me.get_args ().end (); ++i) + fix_refs (*i); +} +void ProjectModel::fix_refs_Advice(ACM_Advice &me) { + fix_refs_Any(me); + fix_refs (me.get_pointcut()); +} +void ProjectModel::fix_refs_AdviceCode(ACM_AdviceCode &me) { + fix_refs_Advice(me); +} +void ProjectModel::fix_refs_Introduction(ACM_Introduction &me) { + fix_refs_Advice(me); + if (me.has_named_slice() && me.get_named_slice ()->get_partner ()) + me.set_named_slice((ACM_ClassSlice*)me.get_named_slice ()->get_partner ()); + if (me.has_anon_slice()) fix_refs (me.get_anon_slice()); +} +void ProjectModel::fix_refs_Order(ACM_Order &me) { + fix_refs_Advice(me); + for (ACM_Container ::iterator i = me.get_aspect_exprs ().begin (); i != me.get_aspect_exprs ().end (); ++i) + fix_refs (*i); +} +void ProjectModel::fix_refs_Aspect(ACM_Aspect &me) { + fix_refs_Class(me); + for (ACM_Container ::iterator i = me.get_intros ().begin (); i != me.get_intros ().end (); ++i) + fix_refs (*i); + for (ACM_Container ::iterator i = me.get_advices ().begin (); i != me.get_advices ().end (); ++i) + fix_refs (*i); + for (ACM_Container ::iterator i = me.get_orders ().begin (); i != me.get_orders ().end (); ++i) + fix_refs (*i); +} +void ProjectModel::fix_refs_Speculation(ACM_Speculation &me) { + fix_refs_Node(me); + if (me.get_advice ()->get_partner ()) + me.set_advice((ACM_Advice*)me.get_advice ()->get_partner ()); + if (me.get_tunit ()->get_partner ()) + me.set_tunit((ACM_TUnit*)me.get_tunit ()->get_partner ()); + ACM_Container new_true_jps; + for (ACM_Container ::iterator i = me.get_true_jps ().begin (); i != me.get_true_jps ().end (); ++i) + if ((*i)->get_partner ()) + new_true_jps.insert ((ACM_Any*)(*i)->get_partner ()); + else + new_true_jps.insert ((ACM_Any*)(*i)); + me.get_true_jps () = new_true_jps; + ACM_Container new_false_jps; + for (ACM_Container ::iterator i = me.get_false_jps ().begin (); i != me.get_false_jps ().end (); ++i) + if ((*i)->get_partner ()) + new_false_jps.insert ((ACM_Any*)(*i)->get_partner ()); + else + new_false_jps.insert ((ACM_Any*)(*i)); + me.get_false_jps () = new_false_jps; + ACM_Container new_conditional_jps; + for (ACM_Container ::iterator i = me.get_conditional_jps ().begin (); i != me.get_conditional_jps ().end (); ++i) + if ((*i)->get_partner ()) + new_conditional_jps.insert ((ACM_Any*)(*i)->get_partner ()); + else + new_conditional_jps.insert ((ACM_Any*)(*i)); + me.get_conditional_jps () = new_conditional_jps; +} +void ProjectModel::fix_refs_Model(ACM_Model &me) { + fix_refs_Node(me); + for (ACM_Container ::iterator i = me.get_files ().begin (); i != me.get_files ().end (); ++i) + fix_refs (*i); + fix_refs (me.get_root()); + for (ACM_Container ::iterator i = me.get_speculations ().begin (); i != me.get_speculations ().end (); ++i) + fix_refs (*i); +} + diff --git a/AspectC++/ACModel/Elements.h b/AspectC++/ACModel/Elements.h new file mode 100644 index 0000000..d48cfb5 --- /dev/null +++ b/AspectC++/ACModel/Elements.h @@ -0,0 +1,1787 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __Elements_h__ +#define __Elements_h__ +#include "ModelNode.h" +#include +#include + +#include + + +// define enums +enum SourceLocKind { SLK_NONE, SLK_DEF, SLK_DECL }; +enum FunctionType { FT_UNKNOWN, FT_NON_MEMBER, FT_STATIC_NON_MEMBER, FT_MEMBER, FT_STATIC_MEMBER, FT_VIRTUAL_MEMBER, FT_PURE_VIRTUAL_MEMBER, FT_CONSTRUCTOR, FT_DESTRUCTOR, FT_VIRTUAL_DESTRUCTOR, FT_PURE_VIRTUAL_DESTRUCTOR }; +enum PointcutType { PT_NORMAL, PT_VIRTUAL, PT_PURE_VIRTUAL }; +enum VariableType { VT_UNKNOWN, VT_NON_MEMBER, VT_STATIC_NON_MEMBER, VT_MEMBER, VT_STATIC_MEMBER }; +enum AdviceCodeType { ACT_BEFORE, ACT_AFTER, ACT_AROUND }; +enum AdviceCodeContext { ACC_NONE, ACC_TYPE, ACC_OBJ, ACC_TYPE_OBJ, ACC_VARS, ACC_TYPE_VARS, ACC_OBJ_VARS, ACC_TYPE_OBJ_VARS }; +enum CVQualifiers { CVQ_NONE, CVQ_CONST, CVQ_VOLATILE, CVQ_CONST_VOLATILE }; + +// define entity IDs +typedef unsigned long long JoinPointType; +static const JoinPointType JPT_TUnit = 1ULL << 0; +static const int JPTI_TUnit = 0; +static const JoinPointType JPT_Header = 1ULL << 1; +static const int JPTI_Header = 1; +static const JoinPointType JPT_Source = 1ULL << 2; +static const int JPTI_Source = 2; +static const JoinPointType JPT_MemberIntro = 1ULL << 3; +static const int JPTI_MemberIntro = 3; +static const JoinPointType JPT_BaseIntro = 1ULL << 4; +static const int JPTI_BaseIntro = 4; +static const JoinPointType JPT_ClassPlan = 1ULL << 5; +static const int JPTI_ClassPlan = 5; +static const JoinPointType JPT_CodeAdvice = 1ULL << 6; +static const int JPTI_CodeAdvice = 6; +static const JoinPointType JPT_CodePlan = 1ULL << 7; +static const int JPTI_CodePlan = 7; +static const JoinPointType JPT_Type = 1ULL << 8; +static const int JPTI_Type = 8; +static const JoinPointType JPT_Arg = 1ULL << 9; +static const int JPTI_Arg = 9; +static const JoinPointType JPT_Namespace = 1ULL << 10; +static const int JPTI_Namespace = 10; +static const JoinPointType JPT_Function = 1ULL << 11; +static const int JPTI_Function = 11; +static const JoinPointType JPT_Variable = 1ULL << 12; +static const int JPTI_Variable = 12; +static const JoinPointType JPT_Class = 1ULL << 13; +static const int JPTI_Class = 13; +static const JoinPointType JPT_ClassSlice = 1ULL << 14; +static const int JPTI_ClassSlice = 14; +static const JoinPointType JPT_Get = 1ULL << 15; +static const int JPTI_Get = 15; +static const JoinPointType JPT_Set = 1ULL << 16; +static const int JPTI_Set = 16; +static const JoinPointType JPT_Call = 1ULL << 17; +static const int JPTI_Call = 17; +static const JoinPointType JPT_Builtin = 1ULL << 18; +static const int JPTI_Builtin = 18; +static const JoinPointType JPT_Ref = 1ULL << 19; +static const int JPTI_Ref = 19; +static const JoinPointType JPT_GetRef = 1ULL << 20; +static const int JPTI_GetRef = 20; +static const JoinPointType JPT_SetRef = 1ULL << 21; +static const int JPTI_SetRef = 21; +static const JoinPointType JPT_CallRef = 1ULL << 22; +static const int JPTI_CallRef = 22; +static const JoinPointType JPT_Execution = 1ULL << 23; +static const int JPTI_Execution = 23; +static const JoinPointType JPT_Construction = 1ULL << 24; +static const int JPTI_Construction = 24; +static const JoinPointType JPT_Destruction = 1ULL << 25; +static const int JPTI_Destruction = 25; +static const JoinPointType JPT_Pointcut = 1ULL << 26; +static const int JPTI_Pointcut = 26; +static const JoinPointType JPT_Attribute = 1ULL << 27; +static const int JPTI_Attribute = 27; +static const JoinPointType JPT_AdviceCode = 1ULL << 28; +static const int JPTI_AdviceCode = 28; +static const JoinPointType JPT_Introduction = 1ULL << 29; +static const int JPTI_Introduction = 29; +static const JoinPointType JPT_Order = 1ULL << 30; +static const int JPTI_Order = 30; +static const JoinPointType JPT_Aspect = 1ULL << 31; +static const int JPTI_Aspect = 31; +static const JoinPointType JPT_Speculation = 1ULL << 32; +static const int JPTI_Speculation = 32; +static const JoinPointType JPT_Model = 1ULL << 33; +static const int JPTI_Model = 33; +static const int MAX_JOIN_POINT_TYPE_INDEX = 34; +static const JoinPointType JPT_Node = JPT_TUnit|JPT_Header|JPT_Source|JPT_MemberIntro|JPT_BaseIntro|JPT_ClassPlan|JPT_CodeAdvice|JPT_CodePlan|JPT_Type|JPT_Arg|JPT_Namespace|JPT_Function|JPT_Variable|JPT_Class|JPT_ClassSlice|JPT_Get|JPT_Set|JPT_Call|JPT_Builtin|JPT_Ref|JPT_GetRef|JPT_SetRef|JPT_CallRef|JPT_Execution|JPT_Construction|JPT_Destruction|JPT_Pointcut|JPT_Attribute|JPT_AdviceCode|JPT_Introduction|JPT_Order|JPT_Aspect|JPT_Speculation|JPT_Model; +static const JoinPointType JPT_File = JPT_TUnit|JPT_Header; +static const JoinPointType JPT_Any = JPT_Type|JPT_Arg|JPT_Namespace|JPT_Function|JPT_Variable|JPT_Class|JPT_ClassSlice|JPT_Get|JPT_Set|JPT_Call|JPT_Builtin|JPT_Ref|JPT_GetRef|JPT_SetRef|JPT_CallRef|JPT_Execution|JPT_Construction|JPT_Destruction|JPT_Pointcut|JPT_Attribute|JPT_AdviceCode|JPT_Introduction|JPT_Order|JPT_Aspect; +static const JoinPointType JPT_Name = JPT_Namespace|JPT_Function|JPT_Variable|JPT_Class|JPT_ClassSlice|JPT_Pointcut|JPT_Attribute|JPT_Aspect; +static const JoinPointType JPT_Code = JPT_Get|JPT_Set|JPT_Call|JPT_Builtin|JPT_Ref|JPT_GetRef|JPT_SetRef|JPT_CallRef|JPT_Execution|JPT_Construction|JPT_Destruction; +static const JoinPointType JPT_Access = JPT_Get|JPT_Set|JPT_Call|JPT_Builtin|JPT_Ref|JPT_GetRef|JPT_SetRef|JPT_CallRef; +static const JoinPointType JPT_Advice = JPT_AdviceCode|JPT_Introduction|JPT_Order; + +// forward declarations of join-point model classes +class ACM_Node; +class ACM_File; +class ACM_TUnit; +class ACM_Header; +class ACM_Source; +class ACM_MemberIntro; +class ACM_BaseIntro; +class ACM_ClassPlan; +class ACM_CodeAdvice; +class ACM_CodePlan; +class ACM_Any; +class ACM_Type; +class ACM_Arg; +class ACM_Name; +class ACM_Namespace; +class ACM_Function; +class ACM_Variable; +class ACM_Class; +class ACM_ClassSlice; +class ACM_Code; +class ACM_Access; +class ACM_Get; +class ACM_Set; +class ACM_Call; +class ACM_Builtin; +class ACM_Ref; +class ACM_GetRef; +class ACM_SetRef; +class ACM_CallRef; +class ACM_Execution; +class ACM_Construction; +class ACM_Destruction; +class ACM_Pointcut; +class ACM_Attribute; +class ACM_Advice; +class ACM_AdviceCode; +class ACM_Introduction; +class ACM_Order; +class ACM_Aspect; +class ACM_Speculation; +class ACM_Model; + +// class definitions + +class ACM_Node : public ModelNode { +public: + ACM_Node () { + } + virtual ~ACM_Node () {} + virtual const char *type_str () const { return "Node"; } + virtual JoinPointType type_val () const { return JPT_Node; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + +}; + +class ACM_File : public ACM_Node { + string filename_; + int len_; + int time_; +public: + ACM_File () { + } + virtual ~ACM_File () {} + virtual const char *type_str () const { return "File"; } + virtual JoinPointType type_val () const { return JPT_File; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + void set_filename (string arg) { set_xml_dirty (true); filename_ = arg; } + string get_filename() const { return filename_; } + + void set_len (int arg) { set_xml_dirty (true); len_ = arg; } + int get_len() const { return len_; } + + void set_time (int arg) { set_xml_dirty (true); time_ = arg; } + int get_time() const { return time_; } + +}; + +class ACM_TUnit : public ACM_File { + bool dirty_flag_; +public: + ACM_TUnit () { + } + virtual ~ACM_TUnit () {} + virtual const char *type_str () const { return "TUnit"; } + virtual JoinPointType type_val () const { return JPT_TUnit; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + void set_dirty_flag (bool arg) { set_xml_dirty (true); dirty_flag_ = arg; } + bool get_dirty_flag() const { return dirty_flag_; } + +}; + +class ACM_Header : public ACM_File { + ACM_Container in_; +public: + ACM_Header () { + } + virtual ~ACM_Header () {} + virtual const char *type_str () const { return "Header"; } + virtual JoinPointType type_val () const { return JPT_Header; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + ACM_Container &get_in() { return in_; } + const ACM_Container &get_in() const { return in_; } + +}; + +class ACM_Source : public ACM_Node { + SourceLocKind kind_; + ACM_File* file_; + int line_; + int len_; +public: + ACM_Source () { + } + virtual ~ACM_Source () {} + virtual const char *type_str () const { return "Source"; } + virtual JoinPointType type_val () const { return JPT_Source; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + void set_kind (SourceLocKind arg) { set_xml_dirty (true); kind_ = arg; } + SourceLocKind get_kind() const { return kind_; } + + void set_file (ACM_File* arg) { set_xml_dirty (true); file_ = arg; } + ACM_File* get_file() { return file_; } + + void set_line (int arg) { set_xml_dirty (true); line_ = arg; } + int get_line() const { return line_; } + + void set_len (int arg) { set_xml_dirty (true); len_ = arg; } + int get_len() const { return len_; } + +}; + +class ACM_MemberIntro : public ACM_Node { + ACM_Introduction* intro_; + ACM_Container members_; +public: + ACM_MemberIntro () { + } + virtual ~ACM_MemberIntro () {} + virtual const char *type_str () const { return "MemberIntro"; } + virtual JoinPointType type_val () const { return JPT_MemberIntro; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + void set_intro (ACM_Introduction* arg) { set_xml_dirty (true); intro_ = arg; } + ACM_Introduction* get_intro() { return intro_; } + + ACM_Container &get_members() { return members_; } + const ACM_Container &get_members() const { return members_; } + +}; + +class ACM_BaseIntro : public ACM_Node { + ACM_Introduction* intro_; + ACM_Container bases_; +public: + ACM_BaseIntro () { + } + virtual ~ACM_BaseIntro () {} + virtual const char *type_str () const { return "BaseIntro"; } + virtual JoinPointType type_val () const { return JPT_BaseIntro; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + void set_intro (ACM_Introduction* arg) { set_xml_dirty (true); intro_ = arg; } + ACM_Introduction* get_intro() { return intro_; } + + ACM_Container &get_bases() { return bases_; } + const ACM_Container &get_bases() const { return bases_; } + +}; + +class ACM_ClassPlan : public ACM_Node { + ACM_Container base_intros_; + ACM_Container member_intros_; +public: + ACM_ClassPlan () { + base_intros_.set_parent (this); + member_intros_.set_parent (this); + } + virtual ~ACM_ClassPlan () {} + virtual const char *type_str () const { return "ClassPlan"; } + virtual JoinPointType type_val () const { return JPT_ClassPlan; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + ACM_Container &get_base_intros() { return base_intros_; } + const ACM_Container &get_base_intros() const { return base_intros_; } + + ACM_Container &get_member_intros() { return member_intros_; } + const ACM_Container &get_member_intros() const { return member_intros_; } + +}; + +class ACM_CodeAdvice : public ACM_Node { + ACM_AdviceCode* advice_; + bool conditional_; +public: + ACM_CodeAdvice () { + } + virtual ~ACM_CodeAdvice () {} + virtual const char *type_str () const { return "CodeAdvice"; } + virtual JoinPointType type_val () const { return JPT_CodeAdvice; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + void set_advice (ACM_AdviceCode* arg) { set_xml_dirty (true); advice_ = arg; } + ACM_AdviceCode* get_advice() { return advice_; } + + void set_conditional (bool arg) { set_xml_dirty (true); conditional_ = arg; } + bool get_conditional() const { return conditional_; } + +}; + +class ACM_CodePlan : public ACM_Node { + ACM_Container before_; + bool has_around_; + ACM_CodeAdvice* around_; + ACM_Container after_; + bool has_next_level_; + ACM_CodePlan* next_level_; +public: + ACM_CodePlan () { + before_.set_parent (this); + has_around_ = false; + after_.set_parent (this); + has_next_level_ = false; + } + virtual ~ACM_CodePlan () {} + virtual const char *type_str () const { return "CodePlan"; } + virtual JoinPointType type_val () const { return JPT_CodePlan; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + ACM_Container &get_before() { return before_; } + const ACM_Container &get_before() const { return before_; } + + bool has_around () const { return has_around_; } + void set_around (ACM_CodeAdvice* arg) { set_xml_dirty (true); around_ = arg; if (arg) arg->set_parent(this); has_around_ = true; } + ACM_CodeAdvice* get_around() { return around_; } + + ACM_Container &get_after() { return after_; } + const ACM_Container &get_after() const { return after_; } + + bool has_next_level () const { return has_next_level_; } + void set_next_level (ACM_CodePlan* arg) { set_xml_dirty (true); next_level_ = arg; if (arg) arg->set_parent(this); has_next_level_ = true; } + ACM_CodePlan* get_next_level() { return next_level_; } + +}; + +class ACM_Any : public ACM_Node { + bool has_jpid_; + int jpid_; + ACM_Container source_; + ACM_Container attributes_; +public: + ACM_Any () { + has_jpid_ = false; + source_.set_parent (this); + } + virtual ~ACM_Any () {} + virtual const char *type_str () const { return "Any"; } + virtual JoinPointType type_val () const { return JPT_Any; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + bool has_jpid () const { return has_jpid_; } + void set_jpid (int arg) { set_xml_dirty (true); jpid_ = arg; has_jpid_ = true; } + int get_jpid() const { return jpid_; } + + ACM_Container &get_source() { return source_; } + const ACM_Container &get_source() const { return source_; } + + ACM_Container &get_attributes() { return attributes_; } + const ACM_Container &get_attributes() const { return attributes_; } + +}; + +class ACM_Type : public ACM_Any { + string signature_; + MatchSignature match_sig_; +public: + ACM_Type () { + } + virtual ~ACM_Type () {} + virtual const char *type_str () const { return "Type"; } + virtual JoinPointType type_val () const { return JPT_Type; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + void set_signature (string arg) { set_xml_dirty (true); signature_ = arg; } + string get_signature() const { return signature_; } + + MatchSignature &get_match_sig() { return match_sig_; } + const MatchSignature &get_match_sig() const { return match_sig_; } + +}; + +class ACM_Arg : public ACM_Any { + string type_; + string name_; +public: + ACM_Arg () { + } + virtual ~ACM_Arg () {} + virtual const char *type_str () const { return "Arg"; } + virtual JoinPointType type_val () const { return JPT_Arg; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + void set_type (string arg) { set_xml_dirty (true); type_ = arg; } + string get_type() const { return type_; } + + void set_name (string arg) { set_xml_dirty (true); name_ = arg; } + string get_name() const { return name_; } + +}; + +class ACM_Name : public ACM_Any { + ACM_Container children_; + string name_; + MatchSignature match_sig_; + NameMap name_map_; + bool builtin_; + ACM_Container tunits_; +public: + ACM_Name () { + children_.set_parent (this); + } + virtual ~ACM_Name () {} + virtual const char *type_str () const { return "Name"; } + virtual JoinPointType type_val () const { return JPT_Name; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + ACM_Container &get_children() { return children_; } + const ACM_Container &get_children() const { return children_; } + + void set_name (string arg) { set_xml_dirty (true); name_ = arg; } + string get_name() const { return name_; } + + MatchSignature &get_match_sig() { return match_sig_; } + const MatchSignature &get_match_sig() const { return match_sig_; } + + NameMap &get_name_map() { return name_map_; } + const NameMap &get_name_map() const { return name_map_; } + + void set_builtin (bool arg) { set_xml_dirty (true); builtin_ = arg; } + bool get_builtin() const { return builtin_; } + + ACM_Container &get_tunits() { return tunits_; } + const ACM_Container &get_tunits() const { return tunits_; } + +}; + +class ACM_Namespace : public ACM_Name { +public: + ACM_Namespace () { + } + virtual ~ACM_Namespace () {} + virtual const char *type_str () const { return "Namespace"; } + virtual JoinPointType type_val () const { return JPT_Namespace; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + +}; + +class ACM_Function : public ACM_Name { + bool has_result_type_; + ACM_Type* result_type_; + ACM_Container arg_types_; + FunctionType kind_; + bool variadic_args_; + CVQualifiers cv_qualifiers_; + bool has_static_in_; + ACM_TUnit* static_in_; + ACM_Container calls_; +public: + ACM_Function () { + has_result_type_ = false; + arg_types_.set_parent (this); + has_static_in_ = false; + } + virtual ~ACM_Function () {} + virtual const char *type_str () const { return "Function"; } + virtual JoinPointType type_val () const { return JPT_Function; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + bool has_result_type () const { return has_result_type_; } + void set_result_type (ACM_Type* arg) { set_xml_dirty (true); result_type_ = arg; if (arg) arg->set_parent(this); has_result_type_ = true; } + ACM_Type* get_result_type() { return result_type_; } + + ACM_Container &get_arg_types() { return arg_types_; } + const ACM_Container &get_arg_types() const { return arg_types_; } + + void set_kind (FunctionType arg) { set_xml_dirty (true); kind_ = arg; } + FunctionType get_kind() const { return kind_; } + + void set_variadic_args (bool arg) { set_xml_dirty (true); variadic_args_ = arg; } + bool get_variadic_args() const { return variadic_args_; } + + void set_cv_qualifiers (CVQualifiers arg) { set_xml_dirty (true); cv_qualifiers_ = arg; } + CVQualifiers get_cv_qualifiers() const { return cv_qualifiers_; } + + bool has_static_in () const { return has_static_in_; } + void set_static_in (ACM_TUnit* arg) { set_xml_dirty (true); static_in_ = arg; has_static_in_ = true; } + ACM_TUnit* get_static_in() { return static_in_; } + + ACM_Container &get_calls() { return calls_; } + const ACM_Container &get_calls() const { return calls_; } + +}; + +class ACM_Variable : public ACM_Name { + ACM_Type* type_; + VariableType kind_; +public: + ACM_Variable () { + } + virtual ~ACM_Variable () {} + virtual const char *type_str () const { return "Variable"; } + virtual JoinPointType type_val () const { return JPT_Variable; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + void set_type (ACM_Type* arg) { set_xml_dirty (true); type_ = arg; if (arg) arg->set_parent(this); } + ACM_Type* get_type() { return type_; } + + void set_kind (VariableType arg) { set_xml_dirty (true); kind_ = arg; } + VariableType get_kind() const { return kind_; } + +}; + +class ACM_Class : public ACM_Name { + ACM_Container bases_; + ACM_Container derived_; + bool intro_target_; + bool has_plan_; + ACM_ClassPlan* plan_; +public: + ACM_Class () { + has_plan_ = false; + } + virtual ~ACM_Class () {} + virtual const char *type_str () const { return "Class"; } + virtual JoinPointType type_val () const { return JPT_Class; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + ACM_Container &get_bases() { return bases_; } + const ACM_Container &get_bases() const { return bases_; } + + ACM_Container &get_derived() { return derived_; } + const ACM_Container &get_derived() const { return derived_; } + + void set_intro_target (bool arg) { set_xml_dirty (true); intro_target_ = arg; } + bool get_intro_target() const { return intro_target_; } + + bool has_plan () const { return has_plan_; } + void set_plan (ACM_ClassPlan* arg) { set_xml_dirty (true); plan_ = arg; if (arg) arg->set_parent(this); has_plan_ = true; } + ACM_ClassPlan* get_plan() { return plan_; } + +}; + +class ACM_ClassSlice : public ACM_Name { + bool is_struct_; +public: + ACM_ClassSlice () { + } + virtual ~ACM_ClassSlice () {} + virtual const char *type_str () const { return "ClassSlice"; } + virtual JoinPointType type_val () const { return JPT_ClassSlice; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + void set_is_struct (bool arg) { set_xml_dirty (true); is_struct_ = arg; } + bool get_is_struct() const { return is_struct_; } + +}; + +class ACM_Code : public ACM_Any { + bool has_plan_; + ACM_CodePlan* plan_; +public: + ACM_Code () { + has_plan_ = false; + } + virtual ~ACM_Code () {} + virtual const char *type_str () const { return "Code"; } + virtual JoinPointType type_val () const { return JPT_Code; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + bool has_plan () const { return has_plan_; } + void set_plan (ACM_CodePlan* arg) { set_xml_dirty (true); plan_ = arg; if (arg) arg->set_parent(this); has_plan_ = true; } + ACM_CodePlan* get_plan() { return plan_; } + +}; + +class ACM_Access : public ACM_Code { + int lid_; + bool has_target_object_lid_; + int target_object_lid_; + bool has_cfg_block_lid_; + int cfg_block_lid_; + bool has_target_class_; + ACM_Class* target_class_; +public: + ACM_Access () { + has_target_object_lid_ = false; + has_cfg_block_lid_ = false; + has_target_class_ = false; + } + virtual ~ACM_Access () {} + virtual const char *type_str () const { return "Access"; } + virtual JoinPointType type_val () const { return JPT_Access; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + void set_lid (int arg) { set_xml_dirty (true); lid_ = arg; } + int get_lid() const { return lid_; } + + bool has_target_object_lid () const { return has_target_object_lid_; } + void set_target_object_lid (int arg) { set_xml_dirty (true); target_object_lid_ = arg; has_target_object_lid_ = true; } + int get_target_object_lid() const { return target_object_lid_; } + + bool has_cfg_block_lid () const { return has_cfg_block_lid_; } + void set_cfg_block_lid (int arg) { set_xml_dirty (true); cfg_block_lid_ = arg; has_cfg_block_lid_ = true; } + int get_cfg_block_lid() const { return cfg_block_lid_; } + + bool has_target_class () const { return has_target_class_; } + void set_target_class (ACM_Class* arg) { set_xml_dirty (true); target_class_ = arg; has_target_class_ = true; } + ACM_Class* get_target_class() { return target_class_; } + +}; + +class ACM_Get : public ACM_Access { + bool has_variable_; + ACM_Variable* variable_; +public: + ACM_Get () { + has_variable_ = false; + } + virtual ~ACM_Get () {} + virtual const char *type_str () const { return "Get"; } + virtual JoinPointType type_val () const { return JPT_Get; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + bool has_variable () const { return has_variable_; } + void set_variable (ACM_Variable* arg) { set_xml_dirty (true); variable_ = arg; has_variable_ = true; } + ACM_Variable* get_variable() { return variable_; } + +}; + +class ACM_Set : public ACM_Access { + bool has_variable_; + ACM_Variable* variable_; +public: + ACM_Set () { + has_variable_ = false; + } + virtual ~ACM_Set () {} + virtual const char *type_str () const { return "Set"; } + virtual JoinPointType type_val () const { return JPT_Set; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + bool has_variable () const { return has_variable_; } + void set_variable (ACM_Variable* arg) { set_xml_dirty (true); variable_ = arg; has_variable_ = true; } + ACM_Variable* get_variable() { return variable_; } + +}; + +class ACM_Call : public ACM_Access { + ACM_Function* target_; + ACM_Container variadic_arg_types_; + bool has_default_args_; + int default_args_; +public: + ACM_Call () { + variadic_arg_types_.set_parent (this); + has_default_args_ = false; + } + virtual ~ACM_Call () {} + virtual const char *type_str () const { return "Call"; } + virtual JoinPointType type_val () const { return JPT_Call; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + void set_target (ACM_Function* arg) { set_xml_dirty (true); target_ = arg; } + ACM_Function* get_target() { return target_; } + + ACM_Container &get_variadic_arg_types() { return variadic_arg_types_; } + const ACM_Container &get_variadic_arg_types() const { return variadic_arg_types_; } + + bool has_default_args () const { return has_default_args_; } + void set_default_args (int arg) { set_xml_dirty (true); default_args_ = arg; has_default_args_ = true; } + int get_default_args() const { return default_args_; } + +}; + +class ACM_Builtin : public ACM_Access { + ACM_Function* target_; + ACM_Container implicit_access_; +public: + ACM_Builtin () { + implicit_access_.set_parent (this); + } + virtual ~ACM_Builtin () {} + virtual const char *type_str () const { return "Builtin"; } + virtual JoinPointType type_val () const { return JPT_Builtin; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + void set_target (ACM_Function* arg) { set_xml_dirty (true); target_ = arg; } + ACM_Function* get_target() { return target_; } + + ACM_Container &get_implicit_access() { return implicit_access_; } + const ACM_Container &get_implicit_access() const { return implicit_access_; } + +}; + +class ACM_Ref : public ACM_Access { + ACM_Variable* variable_; + ACM_Type* type_; +public: + ACM_Ref () { + } + virtual ~ACM_Ref () {} + virtual const char *type_str () const { return "Ref"; } + virtual JoinPointType type_val () const { return JPT_Ref; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + void set_variable (ACM_Variable* arg) { set_xml_dirty (true); variable_ = arg; } + ACM_Variable* get_variable() { return variable_; } + + void set_type (ACM_Type* arg) { set_xml_dirty (true); type_ = arg; if (arg) arg->set_parent(this); } + ACM_Type* get_type() { return type_; } + +}; + +class ACM_GetRef : public ACM_Access { + ACM_Type* type_; +public: + ACM_GetRef () { + } + virtual ~ACM_GetRef () {} + virtual const char *type_str () const { return "GetRef"; } + virtual JoinPointType type_val () const { return JPT_GetRef; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + void set_type (ACM_Type* arg) { set_xml_dirty (true); type_ = arg; if (arg) arg->set_parent(this); } + ACM_Type* get_type() { return type_; } + +}; + +class ACM_SetRef : public ACM_Access { + ACM_Type* type_; +public: + ACM_SetRef () { + } + virtual ~ACM_SetRef () {} + virtual const char *type_str () const { return "SetRef"; } + virtual JoinPointType type_val () const { return JPT_SetRef; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + void set_type (ACM_Type* arg) { set_xml_dirty (true); type_ = arg; if (arg) arg->set_parent(this); } + ACM_Type* get_type() { return type_; } + +}; + +class ACM_CallRef : public ACM_Access { + ACM_Type* type_; +public: + ACM_CallRef () { + } + virtual ~ACM_CallRef () {} + virtual const char *type_str () const { return "CallRef"; } + virtual JoinPointType type_val () const { return JPT_CallRef; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + void set_type (ACM_Type* arg) { set_xml_dirty (true); type_ = arg; if (arg) arg->set_parent(this); } + ACM_Type* get_type() { return type_; } + +}; + +class ACM_Execution : public ACM_Code { +public: + ACM_Execution () { + } + virtual ~ACM_Execution () {} + virtual const char *type_str () const { return "Execution"; } + virtual JoinPointType type_val () const { return JPT_Execution; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + +}; + +class ACM_Construction : public ACM_Code { +public: + ACM_Construction () { + } + virtual ~ACM_Construction () {} + virtual const char *type_str () const { return "Construction"; } + virtual JoinPointType type_val () const { return JPT_Construction; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + +}; + +class ACM_Destruction : public ACM_Code { +public: + ACM_Destruction () { + } + virtual ~ACM_Destruction () {} + virtual const char *type_str () const { return "Destruction"; } + virtual JoinPointType type_val () const { return JPT_Destruction; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + +}; + +class ACM_Pointcut : public ACM_Name { + string expr_; + ACM_Container args_; + PointcutType kind_; + PointcutExpression parsed_expr_; +public: + ACM_Pointcut () { + args_.set_parent (this); + } + virtual ~ACM_Pointcut () {} + virtual const char *type_str () const { return "Pointcut"; } + virtual JoinPointType type_val () const { return JPT_Pointcut; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + void set_expr (string arg) { set_xml_dirty (true); expr_ = arg; } + string get_expr() const { return expr_; } + + ACM_Container &get_args() { return args_; } + const ACM_Container &get_args() const { return args_; } + + void set_kind (PointcutType arg) { set_xml_dirty (true); kind_ = arg; } + PointcutType get_kind() const { return kind_; } + + PointcutExpression &get_parsed_expr() { return parsed_expr_; } + const PointcutExpression &get_parsed_expr() const { return parsed_expr_; } + +}; + +class ACM_Attribute : public ACM_Name { + ACM_Container args_; +public: + ACM_Attribute () { + args_.set_parent (this); + } + virtual ~ACM_Attribute () {} + virtual const char *type_str () const { return "Attribute"; } + virtual JoinPointType type_val () const { return JPT_Attribute; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + ACM_Container &get_args() { return args_; } + const ACM_Container &get_args() const { return args_; } + +}; + +class ACM_Advice : public ACM_Any { + ACM_Pointcut* pointcut_; + int lid_; +public: + ACM_Advice () { + } + virtual ~ACM_Advice () {} + virtual const char *type_str () const { return "Advice"; } + virtual JoinPointType type_val () const { return JPT_Advice; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + void set_pointcut (ACM_Pointcut* arg) { set_xml_dirty (true); pointcut_ = arg; if (arg) arg->set_parent(this); } + ACM_Pointcut* get_pointcut() { return pointcut_; } + + void set_lid (int arg) { set_xml_dirty (true); lid_ = arg; } + int get_lid() const { return lid_; } + +}; + +class ACM_AdviceCode : public ACM_Advice { + AdviceCodeType kind_; + AdviceCodeContext context_; +public: + ACM_AdviceCode () { + } + virtual ~ACM_AdviceCode () {} + virtual const char *type_str () const { return "AdviceCode"; } + virtual JoinPointType type_val () const { return JPT_AdviceCode; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + void set_kind (AdviceCodeType arg) { set_xml_dirty (true); kind_ = arg; } + AdviceCodeType get_kind() const { return kind_; } + + void set_context (AdviceCodeContext arg) { set_xml_dirty (true); context_ = arg; } + AdviceCodeContext get_context() const { return context_; } + +}; + +class ACM_Introduction : public ACM_Advice { + bool has_named_slice_; + ACM_ClassSlice* named_slice_; + bool has_anon_slice_; + ACM_ClassSlice* anon_slice_; +public: + ACM_Introduction () { + has_named_slice_ = false; + has_anon_slice_ = false; + } + virtual ~ACM_Introduction () {} + virtual const char *type_str () const { return "Introduction"; } + virtual JoinPointType type_val () const { return JPT_Introduction; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + bool has_named_slice () const { return has_named_slice_; } + void set_named_slice (ACM_ClassSlice* arg) { set_xml_dirty (true); named_slice_ = arg; has_named_slice_ = true; } + ACM_ClassSlice* get_named_slice() { return named_slice_; } + + bool has_anon_slice () const { return has_anon_slice_; } + void set_anon_slice (ACM_ClassSlice* arg) { set_xml_dirty (true); anon_slice_ = arg; if (arg) arg->set_parent(this); has_anon_slice_ = true; } + ACM_ClassSlice* get_anon_slice() { return anon_slice_; } + +}; + +class ACM_Order : public ACM_Advice { + ACM_Container aspect_exprs_; +public: + ACM_Order () { + aspect_exprs_.set_parent (this); + } + virtual ~ACM_Order () {} + virtual const char *type_str () const { return "Order"; } + virtual JoinPointType type_val () const { return JPT_Order; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + ACM_Container &get_aspect_exprs() { return aspect_exprs_; } + const ACM_Container &get_aspect_exprs() const { return aspect_exprs_; } + +}; + +class ACM_Aspect : public ACM_Class { + ACM_Container intros_; + ACM_Container advices_; + ACM_Container orders_; +public: + ACM_Aspect () { + intros_.set_parent (this); + advices_.set_parent (this); + orders_.set_parent (this); + } + virtual ~ACM_Aspect () {} + virtual const char *type_str () const { return "Aspect"; } + virtual JoinPointType type_val () const { return JPT_Aspect; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + ACM_Container &get_intros() { return intros_; } + const ACM_Container &get_intros() const { return intros_; } + + ACM_Container &get_advices() { return advices_; } + const ACM_Container &get_advices() const { return advices_; } + + ACM_Container &get_orders() { return orders_; } + const ACM_Container &get_orders() const { return orders_; } + +}; + +class ACM_Speculation : public ACM_Node { + ACM_Advice* advice_; + ACM_TUnit* tunit_; + ACM_Container true_jps_; + ACM_Container false_jps_; + ACM_Container conditional_jps_; +public: + ACM_Speculation () { + } + virtual ~ACM_Speculation () {} + virtual const char *type_str () const { return "Speculation"; } + virtual JoinPointType type_val () const { return JPT_Speculation; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + void set_advice (ACM_Advice* arg) { set_xml_dirty (true); advice_ = arg; } + ACM_Advice* get_advice() { return advice_; } + + void set_tunit (ACM_TUnit* arg) { set_xml_dirty (true); tunit_ = arg; } + ACM_TUnit* get_tunit() { return tunit_; } + + ACM_Container &get_true_jps() { return true_jps_; } + const ACM_Container &get_true_jps() const { return true_jps_; } + + ACM_Container &get_false_jps() { return false_jps_; } + const ACM_Container &get_false_jps() const { return false_jps_; } + + ACM_Container &get_conditional_jps() { return conditional_jps_; } + const ACM_Container &get_conditional_jps() const { return conditional_jps_; } + +}; + +class ACM_Model : public ACM_Node { + ACM_Container files_; + ACM_Namespace* root_; + ACM_Container speculations_; + string version_; +public: + ACM_Model () { + files_.set_parent (this); + speculations_.set_parent (this); + } + virtual ~ACM_Model () {} + virtual const char *type_str () const { return "Model"; } + virtual JoinPointType type_val () const { return JPT_Model; } + virtual std::string key () const; + + // dump tree functions + virtual void dump (std::ostream &out = cout, int indent = 0) const; + void dump_attr (std::ostream &out = cout) const; + void dump_refs (std::ostream &out = cout) const; + void dump_aggr (std::ostream &out = cout, int indent = 0) const; + + + // XML functions + virtual void to_xml(SaveContext &); + + ACM_Container &get_files() { return files_; } + const ACM_Container &get_files() const { return files_; } + + void set_root (ACM_Namespace* arg) { set_xml_dirty (true); root_ = arg; if (arg) arg->set_parent(this); } + ACM_Namespace* get_root() { return root_; } + + ACM_Container &get_speculations() { return speculations_; } + const ACM_Container &get_speculations() const { return speculations_; } + + void set_version (string arg) { set_xml_dirty (true); version_ = arg; } + string get_version() const { return version_; } + +}; + +// model facade class +class ProjectModel : public ACM_Model { + typedef std::list NodeList; + NodeList _join_points[MAX_JOIN_POINT_TYPE_INDEX]; + xmlDocPtr _xml_doc; + + typedef std::set FileSet; + FileSet _modified_files; + int _merge_id; + unsigned _jpids_in_use; + std::set _jpids_freed; + + // delete all source entries that are referencing a modified file + // true: *all* entries have been deleted + bool purgeSources(ACM_Any &me); + + template + bool sourceCleanupContainer(Container &container) { + typedef typename Container::Type T; + list found; + for (typename Container::iterator i = container.begin (); + i != container.end (); ++i) { + int mc = (*i)->get_merge_count (); + if (mc == _merge_id) { + if ((*i)->is_deleted ()) + found.push_back (*i); + } + else { + (*i)->set_merge_count (_merge_id); + if (source_cleanup (**i)) { + found.push_back (*i); + unlink_node (*i); + } + } + } + for (typename list::iterator i = found.begin (); i != found.end (); ++i) + container.remove (*i); + return false; + } + + bool source_cleanup(ACM_Node &node); + +protected: + template T *remember (T* elem_ptr, int index) { + _join_points[index].push_back (elem_ptr); + return elem_ptr; + } + + void unlink_node (ACM_Node *node) { + if (node->get_xml_node ()) { + xmlUnlinkNode (node->get_xml_node ()); + xmlFreeNode (node->get_xml_node ()); + node->set_xml_node (0); + node->set_xml_dirty (); + } + node->is_deleted (true); + } + +public: + // constructor: initialize attributes + ProjectModel () : _xml_doc (0), _merge_id (0), _jpids_in_use (0) {} + + // destructor: delete all registered model elements and the XML DOM + ~ProjectModel () { clear (); } + // delete all model elements + void clear (); + + void xml_doc (xmlDocPtr doc_ptr) { _xml_doc = doc_ptr; } + xmlDocPtr xml_doc () const { return _xml_doc; } + + // select and return all join points of a given type (any of them) + typedef std::list Selection; + void select (JoinPointType jpt, Selection &result, bool prj_only = true); + + // allocated a new joinpoint ID + unsigned alloc_jpid (); + + // mark a join point ID as allocated (needed for loading models) + void alloc_jpid (unsigned jpid); + + // free a joinpoint ID + void free_jpid (unsigned jpid); + + // merge the elements of another model into this one + void merge (ProjectModel &that); + + // before merging two models find out which files have been changed + // (file in 'that' newer as in 'this') + void init_change_set(ProjectModel &that); + + // cleanup list of modified files (at the end of merging) + void clear_change_set(); + + // merge a tunit node into a similar project mode node + void merge_node (ACM_Node *prj_node, ACM_Node *tu_node); + + // copy a node of another model into this model (deep copy) + ACM_Node *copyNode(ACM_Node *that_node); + + // fix all node references; this is the second phase of merging a tunit + // model into a project model. Reference still address the tunit model + // nodes. Now they have to be replaced with the corresponding project + // model node references + void fix_refs(ACM_Node *me); + + // helper function for merging two models + template + void merge_container (Container &that, Container &into, bool refs = false) { + typename Container::Set &me = into.get_sorted (); + typename Container::Set &you = that.get_sorted (); + // iterate over both sorted lists + typename Container::Set::iterator curr_me = me.begin (); + typename Container::Set::iterator curr_you = you.begin (); + while (curr_me != me.end () && curr_you != you.end ()) { + if (**curr_me < ** curr_you) // an element in 'me', which is not present + ++curr_me; // in 'you' => simply skip + else if (**curr_you < ** curr_me) { // a new element (not in 'me' yet + into.insert ((typename Container::Type*)(refs ? *curr_you : copyNode (*curr_you))); + ++curr_you; + } + else { // two equal elements according to their key => merge + if (!refs) merge_node (*curr_me, *curr_you); + ++curr_you; + ++curr_me; + } + } + while (curr_you != you.end ()) { + into.insert ((typename Container::Type*)(refs ? *curr_you : copyNode (*curr_you))); + ++curr_you; + } + } + + // handle attribute variations when merging models + bool merge_attr (ACM_Node &me, ACM_Node &that, const std::string &attr_name); + void merge_attr_only_in_me (ACM_Node &me, ACM_Node &that, const std::string &attr_name); + void merge_attr_only_in_that (ACM_Node &me, ACM_Node &that, const std::string &attr_name); + + // factory methods that remember all objects of this model + virtual ACM_TUnit *newTUnit() { return remember (new ACM_TUnit, JPTI_TUnit); } + virtual ACM_Header *newHeader() { return remember (new ACM_Header, JPTI_Header); } + virtual ACM_Source *newSource() { return remember (new ACM_Source, JPTI_Source); } + virtual ACM_MemberIntro *newMemberIntro() { return remember (new ACM_MemberIntro, JPTI_MemberIntro); } + virtual ACM_BaseIntro *newBaseIntro() { return remember (new ACM_BaseIntro, JPTI_BaseIntro); } + virtual ACM_ClassPlan *newClassPlan() { return remember (new ACM_ClassPlan, JPTI_ClassPlan); } + virtual ACM_CodeAdvice *newCodeAdvice() { return remember (new ACM_CodeAdvice, JPTI_CodeAdvice); } + virtual ACM_CodePlan *newCodePlan() { return remember (new ACM_CodePlan, JPTI_CodePlan); } + virtual ACM_Type *newType() { return remember (new ACM_Type, JPTI_Type); } + virtual ACM_Arg *newArg() { return remember (new ACM_Arg, JPTI_Arg); } + virtual ACM_Namespace *newNamespace() { return remember (new ACM_Namespace, JPTI_Namespace); } + virtual ACM_Function *newFunction() { return remember (new ACM_Function, JPTI_Function); } + virtual ACM_Variable *newVariable() { return remember (new ACM_Variable, JPTI_Variable); } + virtual ACM_Class *newClass() { return remember (new ACM_Class, JPTI_Class); } + virtual ACM_ClassSlice *newClassSlice() { return remember (new ACM_ClassSlice, JPTI_ClassSlice); } + virtual ACM_Get *newGet() { return remember (new ACM_Get, JPTI_Get); } + virtual ACM_Set *newSet() { return remember (new ACM_Set, JPTI_Set); } + virtual ACM_Call *newCall() { return remember (new ACM_Call, JPTI_Call); } + virtual ACM_Builtin *newBuiltin() { return remember (new ACM_Builtin, JPTI_Builtin); } + virtual ACM_Ref *newRef() { return remember (new ACM_Ref, JPTI_Ref); } + virtual ACM_GetRef *newGetRef() { return remember (new ACM_GetRef, JPTI_GetRef); } + virtual ACM_SetRef *newSetRef() { return remember (new ACM_SetRef, JPTI_SetRef); } + virtual ACM_CallRef *newCallRef() { return remember (new ACM_CallRef, JPTI_CallRef); } + virtual ACM_Execution *newExecution() { return remember (new ACM_Execution, JPTI_Execution); } + virtual ACM_Construction *newConstruction() { return remember (new ACM_Construction, JPTI_Construction); } + virtual ACM_Destruction *newDestruction() { return remember (new ACM_Destruction, JPTI_Destruction); } + virtual ACM_Pointcut *newPointcut() { return remember (new ACM_Pointcut, JPTI_Pointcut); } + virtual ACM_Attribute *newAttribute() { return remember (new ACM_Attribute, JPTI_Attribute); } + virtual ACM_AdviceCode *newAdviceCode() { return remember (new ACM_AdviceCode, JPTI_AdviceCode); } + virtual ACM_Introduction *newIntroduction() { return remember (new ACM_Introduction, JPTI_Introduction); } + virtual ACM_Order *newOrder() { return remember (new ACM_Order, JPTI_Order); } + virtual ACM_Aspect *newAspect() { return remember (new ACM_Aspect, JPTI_Aspect); } + virtual ACM_Speculation *newSpeculation() { return remember (new ACM_Speculation, JPTI_Speculation); } + virtual ACM_Model *newModel() { return remember (new ACM_Model, JPTI_Model); } + + // copy methods that copy elements from other models into this one + // NOTE: the elements are only copied and registerd, but no link is set! + virtual void copyNode(ACM_Node &me, ACM_Node &that); + virtual void copyFile(ACM_File &me, ACM_File &that); + virtual void copyTUnit(ACM_TUnit &me, ACM_TUnit &that); + virtual void copyHeader(ACM_Header &me, ACM_Header &that); + virtual void copySource(ACM_Source &me, ACM_Source &that); + virtual void copyMemberIntro(ACM_MemberIntro &me, ACM_MemberIntro &that); + virtual void copyBaseIntro(ACM_BaseIntro &me, ACM_BaseIntro &that); + virtual void copyClassPlan(ACM_ClassPlan &me, ACM_ClassPlan &that); + virtual void copyCodeAdvice(ACM_CodeAdvice &me, ACM_CodeAdvice &that); + virtual void copyCodePlan(ACM_CodePlan &me, ACM_CodePlan &that); + virtual void copyAny(ACM_Any &me, ACM_Any &that); + virtual void copyType(ACM_Type &me, ACM_Type &that); + virtual void copyArg(ACM_Arg &me, ACM_Arg &that); + virtual void copyName(ACM_Name &me, ACM_Name &that); + virtual void copyNamespace(ACM_Namespace &me, ACM_Namespace &that); + virtual void copyFunction(ACM_Function &me, ACM_Function &that); + virtual void copyVariable(ACM_Variable &me, ACM_Variable &that); + virtual void copyClass(ACM_Class &me, ACM_Class &that); + virtual void copyClassSlice(ACM_ClassSlice &me, ACM_ClassSlice &that); + virtual void copyCode(ACM_Code &me, ACM_Code &that); + virtual void copyAccess(ACM_Access &me, ACM_Access &that); + virtual void copyGet(ACM_Get &me, ACM_Get &that); + virtual void copySet(ACM_Set &me, ACM_Set &that); + virtual void copyCall(ACM_Call &me, ACM_Call &that); + virtual void copyBuiltin(ACM_Builtin &me, ACM_Builtin &that); + virtual void copyRef(ACM_Ref &me, ACM_Ref &that); + virtual void copyGetRef(ACM_GetRef &me, ACM_GetRef &that); + virtual void copySetRef(ACM_SetRef &me, ACM_SetRef &that); + virtual void copyCallRef(ACM_CallRef &me, ACM_CallRef &that); + virtual void copyExecution(ACM_Execution &me, ACM_Execution &that); + virtual void copyConstruction(ACM_Construction &me, ACM_Construction &that); + virtual void copyDestruction(ACM_Destruction &me, ACM_Destruction &that); + virtual void copyPointcut(ACM_Pointcut &me, ACM_Pointcut &that); + virtual void copyAttribute(ACM_Attribute &me, ACM_Attribute &that); + virtual void copyAdvice(ACM_Advice &me, ACM_Advice &that); + virtual void copyAdviceCode(ACM_AdviceCode &me, ACM_AdviceCode &that); + virtual void copyIntroduction(ACM_Introduction &me, ACM_Introduction &that); + virtual void copyOrder(ACM_Order &me, ACM_Order &that); + virtual void copyAspect(ACM_Aspect &me, ACM_Aspect &that); + virtual void copySpeculation(ACM_Speculation &me, ACM_Speculation &that); + virtual void copyModel(ACM_Model &me, ACM_Model &that); + + // merge methods that are called for corresponding translation unit model + // and project model nodes. The functions call merge or copy functions on + // their aggregated sub-nodes. + virtual bool sourceCleanupNode(ACM_Node &me); + virtual bool sourceCleanupFile(ACM_File &me); + virtual bool sourceCleanupTUnit(ACM_TUnit &me); + virtual bool sourceCleanupHeader(ACM_Header &me); + virtual bool sourceCleanupSource(ACM_Source &me); + virtual bool sourceCleanupMemberIntro(ACM_MemberIntro &me); + virtual bool sourceCleanupBaseIntro(ACM_BaseIntro &me); + virtual bool sourceCleanupClassPlan(ACM_ClassPlan &me); + virtual bool sourceCleanupCodeAdvice(ACM_CodeAdvice &me); + virtual bool sourceCleanupCodePlan(ACM_CodePlan &me); + virtual bool sourceCleanupAny(ACM_Any &me); + virtual bool sourceCleanupType(ACM_Type &me); + virtual bool sourceCleanupArg(ACM_Arg &me); + virtual bool sourceCleanupName(ACM_Name &me); + virtual bool sourceCleanupNamespace(ACM_Namespace &me); + virtual bool sourceCleanupFunction(ACM_Function &me); + virtual bool sourceCleanupVariable(ACM_Variable &me); + virtual bool sourceCleanupClass(ACM_Class &me); + virtual bool sourceCleanupClassSlice(ACM_ClassSlice &me); + virtual bool sourceCleanupCode(ACM_Code &me); + virtual bool sourceCleanupAccess(ACM_Access &me); + virtual bool sourceCleanupGet(ACM_Get &me); + virtual bool sourceCleanupSet(ACM_Set &me); + virtual bool sourceCleanupCall(ACM_Call &me); + virtual bool sourceCleanupBuiltin(ACM_Builtin &me); + virtual bool sourceCleanupRef(ACM_Ref &me); + virtual bool sourceCleanupGetRef(ACM_GetRef &me); + virtual bool sourceCleanupSetRef(ACM_SetRef &me); + virtual bool sourceCleanupCallRef(ACM_CallRef &me); + virtual bool sourceCleanupExecution(ACM_Execution &me); + virtual bool sourceCleanupConstruction(ACM_Construction &me); + virtual bool sourceCleanupDestruction(ACM_Destruction &me); + virtual bool sourceCleanupPointcut(ACM_Pointcut &me); + virtual bool sourceCleanupAttribute(ACM_Attribute &me); + virtual bool sourceCleanupAdvice(ACM_Advice &me); + virtual bool sourceCleanupAdviceCode(ACM_AdviceCode &me); + virtual bool sourceCleanupIntroduction(ACM_Introduction &me); + virtual bool sourceCleanupOrder(ACM_Order &me); + virtual bool sourceCleanupAspect(ACM_Aspect &me); + virtual bool sourceCleanupSpeculation(ACM_Speculation &me); + virtual bool sourceCleanupModel(ACM_Model &me); + + virtual void mergeNode(ACM_Node &me, ACM_Node &that); + virtual void mergeFile(ACM_File &me, ACM_File &that); + virtual void mergeTUnit(ACM_TUnit &me, ACM_TUnit &that); + virtual void mergeHeader(ACM_Header &me, ACM_Header &that); + virtual void mergeSource(ACM_Source &me, ACM_Source &that); + virtual void mergeMemberIntro(ACM_MemberIntro &me, ACM_MemberIntro &that); + virtual void mergeBaseIntro(ACM_BaseIntro &me, ACM_BaseIntro &that); + virtual void mergeClassPlan(ACM_ClassPlan &me, ACM_ClassPlan &that); + virtual void mergeCodeAdvice(ACM_CodeAdvice &me, ACM_CodeAdvice &that); + virtual void mergeCodePlan(ACM_CodePlan &me, ACM_CodePlan &that); + virtual void mergeAny(ACM_Any &me, ACM_Any &that); + virtual void mergeType(ACM_Type &me, ACM_Type &that); + virtual void mergeArg(ACM_Arg &me, ACM_Arg &that); + virtual void mergeName(ACM_Name &me, ACM_Name &that); + virtual void mergeNamespace(ACM_Namespace &me, ACM_Namespace &that); + virtual void mergeFunction(ACM_Function &me, ACM_Function &that); + virtual void mergeVariable(ACM_Variable &me, ACM_Variable &that); + virtual void mergeClass(ACM_Class &me, ACM_Class &that); + virtual void mergeClassSlice(ACM_ClassSlice &me, ACM_ClassSlice &that); + virtual void mergeCode(ACM_Code &me, ACM_Code &that); + virtual void mergeAccess(ACM_Access &me, ACM_Access &that); + virtual void mergeGet(ACM_Get &me, ACM_Get &that); + virtual void mergeSet(ACM_Set &me, ACM_Set &that); + virtual void mergeCall(ACM_Call &me, ACM_Call &that); + virtual void mergeBuiltin(ACM_Builtin &me, ACM_Builtin &that); + virtual void mergeRef(ACM_Ref &me, ACM_Ref &that); + virtual void mergeGetRef(ACM_GetRef &me, ACM_GetRef &that); + virtual void mergeSetRef(ACM_SetRef &me, ACM_SetRef &that); + virtual void mergeCallRef(ACM_CallRef &me, ACM_CallRef &that); + virtual void mergeExecution(ACM_Execution &me, ACM_Execution &that); + virtual void mergeConstruction(ACM_Construction &me, ACM_Construction &that); + virtual void mergeDestruction(ACM_Destruction &me, ACM_Destruction &that); + virtual void mergePointcut(ACM_Pointcut &me, ACM_Pointcut &that); + virtual void mergeAttribute(ACM_Attribute &me, ACM_Attribute &that); + virtual void mergeAdvice(ACM_Advice &me, ACM_Advice &that); + virtual void mergeAdviceCode(ACM_AdviceCode &me, ACM_AdviceCode &that); + virtual void mergeIntroduction(ACM_Introduction &me, ACM_Introduction &that); + virtual void mergeOrder(ACM_Order &me, ACM_Order &that); + virtual void mergeAspect(ACM_Aspect &me, ACM_Aspect &that); + virtual void mergeSpeculation(ACM_Speculation &me, ACM_Speculation &that); + virtual void mergeModel(ACM_Model &me, ACM_Model &that); + + virtual void fix_refs_Node(ACM_Node &me); + virtual void fix_refs_File(ACM_File &me); + virtual void fix_refs_TUnit(ACM_TUnit &me); + virtual void fix_refs_Header(ACM_Header &me); + virtual void fix_refs_Source(ACM_Source &me); + virtual void fix_refs_MemberIntro(ACM_MemberIntro &me); + virtual void fix_refs_BaseIntro(ACM_BaseIntro &me); + virtual void fix_refs_ClassPlan(ACM_ClassPlan &me); + virtual void fix_refs_CodeAdvice(ACM_CodeAdvice &me); + virtual void fix_refs_CodePlan(ACM_CodePlan &me); + virtual void fix_refs_Any(ACM_Any &me); + virtual void fix_refs_Type(ACM_Type &me); + virtual void fix_refs_Arg(ACM_Arg &me); + virtual void fix_refs_Name(ACM_Name &me); + virtual void fix_refs_Namespace(ACM_Namespace &me); + virtual void fix_refs_Function(ACM_Function &me); + virtual void fix_refs_Variable(ACM_Variable &me); + virtual void fix_refs_Class(ACM_Class &me); + virtual void fix_refs_ClassSlice(ACM_ClassSlice &me); + virtual void fix_refs_Code(ACM_Code &me); + virtual void fix_refs_Access(ACM_Access &me); + virtual void fix_refs_Get(ACM_Get &me); + virtual void fix_refs_Set(ACM_Set &me); + virtual void fix_refs_Call(ACM_Call &me); + virtual void fix_refs_Builtin(ACM_Builtin &me); + virtual void fix_refs_Ref(ACM_Ref &me); + virtual void fix_refs_GetRef(ACM_GetRef &me); + virtual void fix_refs_SetRef(ACM_SetRef &me); + virtual void fix_refs_CallRef(ACM_CallRef &me); + virtual void fix_refs_Execution(ACM_Execution &me); + virtual void fix_refs_Construction(ACM_Construction &me); + virtual void fix_refs_Destruction(ACM_Destruction &me); + virtual void fix_refs_Pointcut(ACM_Pointcut &me); + virtual void fix_refs_Attribute(ACM_Attribute &me); + virtual void fix_refs_Advice(ACM_Advice &me); + virtual void fix_refs_AdviceCode(ACM_AdviceCode &me); + virtual void fix_refs_Introduction(ACM_Introduction &me); + virtual void fix_refs_Order(ACM_Order &me); + virtual void fix_refs_Aspect(ACM_Aspect &me); + virtual void fix_refs_Speculation(ACM_Speculation &me); + virtual void fix_refs_Model(ACM_Model &me); +}; + +#endif // __Elements_h__ diff --git a/AspectC++/ACModel/Makefile b/AspectC++/ACModel/Makefile new file mode 100644 index 0000000..8f6a160 --- /dev/null +++ b/AspectC++/ACModel/Makefile @@ -0,0 +1,85 @@ +# ****************************** +# * S E T T I N G S * +# ****************************** + +# PUMA root +PUMA ?= ../../Puma + +# default target +TARGET ?= linux-release + +# include the PUMA configuration variables +# => set _TARGET, RELEASE, CFLAGS, CXXFLAGS, CPPFLAGS, etc. +include $(PUMA)/vars.mk + +# libxml2 settings +ifeq ($(_TARGET),win32) + LIBXML2_INC := `mingw32-xml2-config --cflags` +else + LIBXML2_INC := `xml2-config --cflags` +endif + +CPPFLAGS += -I$(PUMA)/extern $(LIBXML2_INC) + +# quick hack: filter-out no-rtti +CXXFLAGS := $(filter-out -fno-rtti, $(CXXFLAGS)) + +# ****************************** +# * I N F O S * +# ****************************** + +$(info ---) +$(info Making ACModel library for TARGET=$(TARGET)) +$(info Compiler = $(CXX) $(CPPFLAGS) $(CXXFLAGS)) +$(info ---) + +# ****************************** +# * S O U R C E S * +# ****************************** + +# library file +LIBDIR := lib/$(TARGET) +LIB := $(LIBDIR)/libacmodel.a + +CCSOURCES := $(wildcard *.cc) + +OBJECTDIR := ObjFiles/$(TARGET) +OBJECTS := $(addprefix $(OBJECTDIR)/,$(CCSOURCES:.cc=.o)) + +DEPDIR := DepFiles/$(TARGET) +DEPS := $(addprefix $(DEPDIR)/,$(CCSOURCES:.cc=.d)) + +DIRS := $(OBJECTDIR) $(DEPDIR) $(LIBDIR) + +# ****************************** +# * T A R G E T S * +# ****************************** + +all: $(LIB) + +clean: + @echo Making it clean. + @rm -rf core core.* *~ lib DepFiles ObjFiles + +# ****************************** +# * R U L E S * +# ****************************** + +$(LIB): $(OBJECTS) + @echo "Creating library $@." + @mkdir -p $(LIBDIR) + @$(AR) rcs $@ $(OBJECTS) + +$(OBJECTDIR)/%.o : %.cc + @echo Making dependency file $@. + @mkdir -p $(DEPDIR) + @$(CXX) $(CPPFLAGS) $(CXXFLAGS) -MM -MP -MT $(OBJECTDIR)/$(<:%.cc=%.o) -MT $(DEPDIR)/$(<:%.cc=%.d) $< > $(DEPDIR)/$(<:%.cc=%.d) + @echo Making object file $@. + @mkdir -p $(OBJECTDIR) + @$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $< + +ifneq ($(MAKECMDGOALS),clean) +-include $(DEPS) +endif + +.phony: all clean dirs showtarget diff --git a/AspectC++/ACModel/MatchExpr.cc b/AspectC++/ACModel/MatchExpr.cc new file mode 100644 index 0000000..3bdc5c4 --- /dev/null +++ b/AspectC++/ACModel/MatchExpr.cc @@ -0,0 +1,1199 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "MatchExpr.h" +#include + +// parse a match expression string +// complain about errors => result false +bool MatchSignature::parse (const string &str) { + const char *strptr = str.c_str(); + if( str == "::" ) { // special case for root namespace + _state = NORMAL; + _expr_type = TYPE; + MatchName n; + n.name( "::" ); + _type = MatchTypeRef::make_named( n ); + return true; + } + else if (parse_match_expr (strptr)) { + // perform argument conversions, warn if any conversion are applied + bool f = false, a = false, q = false, v = false; + _type.adjust_args (f, a, q, v); + _state = NORMAL; + return true; + } + else + return false; +} + +// internal parser functions that analyse a match expr string +bool MatchSignature::parse_match_expr (const char *&str) { + // empty strings are no valid match expressions + if (*str == '\0') { + _state = ERR_EMPTY_MATCH_EXPR; + return false; + } + + // parse as a C++ declaration + MatchTypeRef type; + if (!parse_declaration (str, false, type)) + return false; + + // check for tokens after the end of the accepted input + if (*str != '\0') { + _state = ERR_TOKENS_AFTER_END; + return false; + } + + _expr_type = TYPE; + if (!_name.undefined ()) + _expr_type = (type.is_function () ? FUNCTION : ATTRIBUTE); + + _type = type; // everything is ok, the parsed type is copied + + return true; +} + +bool MatchSignature::parse_declaration (const char *&str, bool abstract, + MatchTypeRef &type) { + // decl_spec_seq_opt declarator_opt + FctSpec fct_spec; + Spec spec; + parse_decl_spec_seq( str, type, fct_spec, spec ); + if (error ()) + return false; + + skip_blanks (str); + if (*str == '\0') + return true; + + parse_declarator (str, abstract, type); + if (error ()) + return false; + + // function specifiers are only valid in conjunctions with function types + if (!type.is_function() && fct_spec) { + _state = ERR_INVALID_SPEC; + return false; + } + + // function specifier in type that appear in argument lists etc. are ignored. + // Top-level function specifiers are saved for matching functions + if (!abstract) { + _fct_spec = fct_spec; + _spec = spec; + } + + return true; +} + +bool MatchSignature::parse_decl_spec_seq (const char *&str, MatchTypeRef &type, + FctSpec &fs, Spec &s ) { + + DeclSpecs ds; // semantic knowledge about the decl spec seq + + // parse a normal sequence of declaration specifiers + bool empty = true; + while (parse_decl_spec (str, ds)) + empty = false; + + // no problem if the sequence is empty -> yields UNDEFINED + if (empty) + return true; + + // now generate the match type for this decl spec sequence + if (!ds._name.undefined ()) { + // a named type ... + + // check for the any-type wildcard first + if (ds._name.scopes () == 0 && ds._name.name () == string("%")) { + if (_wildcards_allowed) + type = MatchTypeRef::make_any (); + else { + _state = ERR_WILDCARD; + return false; + } + } + else + type = MatchTypeRef::make_named (ds._name); + } + else { + // a builtin type ... + + // if no type is given 'int' is the default + if (ds._type == PRIM_NONE) + ds._type = PRIM_INT; + + if (ds._sign < 0) { + // a signed type ... + if (ds._type == PRIM_CHAR && ds._size == 0) + type = MatchTypeRef::make_signed_char (); + else if (ds._type == PRIM_INT) { + if (ds._size == -1) + type = MatchTypeRef::make_short (); + else if (ds._size == 0) + type = MatchTypeRef::make_int (); + else if (ds._size == 1) + type = MatchTypeRef::make_long (); + else if (ds._size == 2) + type = MatchTypeRef::make_long_long (); + } + } + else if (ds._sign > 0) { + // an unsigned type + if (ds._type == PRIM_CHAR && ds._size == 0) + type = MatchTypeRef::make_unsigned_char (); + else if (ds._type == PRIM_INT) { + if (ds._size == -1) + type = MatchTypeRef::make_unsigned_short (); + else if (ds._size == 0) + type = MatchTypeRef::make_unsigned_int (); + else if (ds._size == 1) + type = MatchTypeRef::make_unsigned_long (); + else if (ds._size == 2) + type = MatchTypeRef::make_unsigned_long_long (); + } + else if (ds._type == PRIM_INT128 && ds._size == 0) + type = MatchTypeRef::make_unsigned_int128 (); + } + else { + // neither defined as signed nor unsigned + if (ds._type == PRIM_BOOL && ds._size == 0) + type = MatchTypeRef::make_bool (); + else if (ds._type == PRIM_CHAR && ds._size == 0) + type = MatchTypeRef::make_char (); + else if (ds._type == PRIM_INT) { + if (ds._size == -1) + type = MatchTypeRef::make_short (); + else if (ds._size == 0) + type = MatchTypeRef::make_int (); + else if (ds._size == 1) + type = MatchTypeRef::make_long (); + else if (ds._size == 2) + type = MatchTypeRef::make_long_long (); + } + else if (ds._type == PRIM_INT128 && ds._size == 0) + type = MatchTypeRef::make_int128 (); + else if (ds._type == PRIM_WCHAR_T && ds._size == 0) + type = MatchTypeRef::make_wchar_t (); + else if (ds._type == PRIM_FLOAT && ds._size == 0) + type = MatchTypeRef::make_float (); + else if (ds._type == PRIM_DOUBLE) { + if (ds._size == 0) + type = MatchTypeRef::make_double (); + else if (ds._size == 1) + type = MatchTypeRef::make_long_double (); + } + else if (ds._type == PRIM_VOID && ds._size == 0) + type = MatchTypeRef::make_void (); + } + + } + + // add const or volatile qualifiers to the type + if (type.is_qualifiable ()) { + if (ds._qual & QUAL_CONST) type.qualifiers ().qualify_const (); + if (ds._qual & QUAL_VOLATILE) type.qualifiers ().qualify_volatile (); + } + + if (type.is_undefined ()) { + _state = ERR_INVALID_TYPE; + return false; + } + + // also return the parsed function specifiers + fs = ds._fct_spec; + s = ds._spec; + + return true; +} + +bool MatchSignature::parse_decl_spec (const char *&str, DeclSpecs &ds) { + // remember the current value of this flag as it might be changed + bool name_allowed = ds._allow_name; + + // first skip any blank characters + skip_blanks (str); + + // check for const or volatile + CVQualifier qual = QUAL_NONE; + if (next_word ("const", str)) + qual = QUAL_CONST; + else if (next_word ("volatile", str)) + qual = QUAL_VOLATILE; + if (qual) { + if (ds._qual & qual) { + _state = ERR_DUP_CV; + return false; + } + ds._qual = (CVQualifier)(ds._qual | qual); // remember this qual + return true; + } + + // check for function specifiers; currently only virtual + FctSpec fct_spec = FCT_NONE; + Spec spec = DT_NONE; + if (next_word ("virtual", str)) + fct_spec = FCT_VIRTUAL; + else if (next_word ("static", str)) + spec = DT_STATIC; + + if( fct_spec || spec ) { + if( ( ds._fct_spec & fct_spec ) || ( ds._spec & spec ) ) { + _state = ERR_DUP_SPEC; + return false; + } + else if (((ds._spec & DT_STATIC) && fct_spec == FCT_VIRTUAL) || + ((ds._fct_spec & FCT_VIRTUAL) && spec == DT_STATIC)) { + _state = ERR_VIRT_STAT_FCT_SPEC; + return false; + } + ds._fct_spec = (FctSpec)(ds._fct_spec | fct_spec); // remember this fct spec + ds._spec = (Spec)(ds._spec | spec); // remember this spec + return true; + } + + ds._allow_name = false; // the following checked decl specs indicate a type. + // Therefore, no type name is allowed from now + + // check for C++ primitive types + bool is_prim = true; + if (next_word ("char", str)) + ds._type = PRIM_CHAR; + else if (next_word ("int", str)) + ds._type = PRIM_INT; + else if (next_word ("__int128", str)) + ds._type = PRIM_INT128; + else if (next_word ("void", str)) + ds._type = PRIM_VOID; + else if (next_word ("bool", str)) + ds._type = PRIM_BOOL; + else if (next_word ("float", str)) + ds._type = PRIM_FLOAT; + else if (next_word ("double", str)) + ds._type = PRIM_DOUBLE; + else if (next_word ("wchar_t", str)) + ds._type = PRIM_WCHAR_T; + else + is_prim = false; + if (is_prim) + return true; + + // check for 'short' and 'long' + int size = 0; + if (next_word ("short", str)) + size = -1; + else if (next_word ("long", str)) + size = 1; + if (size != 0) { + if ((ds._size < 0 && size > 0) || (ds._size > 0 && size < 0)) { + _state = ERR_CONF_SIZE; + return false; + } + ds._size += size; + return true; + } + + // check for 'signed' and 'unsigned' + int sign = 0; + if (next_word ("signed", str)) + sign = -1; + else if (next_word ("unsigned", str)) + sign = 1; + if (sign != 0) { + if (ds._sign != 0) { + _state = ERR_DUP_SIGN; + return false; + } + ds._sign = sign; + return true; + } + + // check if this is a valid (qualified) name + if (name_allowed) { + const char *saved_pos = str; + MatchName type_name; + const char *curr = str; + if (!parse_nested_name (curr, type_name)) + if (error ()) + return false; + skip_blanks (curr); + const char *name = curr; + if (strncmp (curr, "", 9) == 0) { + str = curr + 9; + type_name.name (""); + ds._name = type_name; + return true; + } + while (is_id (*curr)) + curr++; + if (curr != name) { + str = curr; + string ns (name, curr - name); + // operator names are no type names + if (ns == "operator") { + str = saved_pos; + return false; + } + else { + type_name.name (ns); + + // are there any template parameters? + MatchTemplateArgList *mtal; + if (!parse_opt_template_argument_list (str, mtal)) + if (error ()) + return false; + + type_name.template_args (mtal); + ds._name = type_name; + return true; + } + } + } + + // no valid declaration specifier + return false; +} + +bool MatchSignature::parse_nested_name (const char *&str, MatchName &match_name) { + bool have_nested_name = false; + while (parse_nested_name_elem (str, match_name)) + have_nested_name = true; + return have_nested_name; +} + +bool MatchSignature::parse_nested_name_elem (const char *&str, MatchName &match_name) { + skip_blanks (str); + // check for ellipses first + if (str[0] == '.') { + const char *curr = str; + if (str[1] != '.' || str[2] != '.') { + _state = ERR_INVALID_DOT; + return false; + } + curr += 3; + skip_blanks (curr); + if (curr[0] != ':' || curr[1] != ':') { + _state = ERR_INVALID_DOT; + return false; + } + str = curr + 2; // consume '... ::' + match_name.add_scope ("..."); + return true; + } + + const char *curr = str; + const char *str_end = 0; + MatchTemplateArgList *mtal = 0; + // an anonymous namespace? + if (strncmp (str, "", 9) == 0) { + curr += 9; + str_end = curr; + } + else { + // a class or namespace name? + while (is_id (*curr)) + curr++; + if (curr == str || (curr - str == 8 && strncmp (str, "operator", 8) == 0)) + return false; + str_end = curr; + + // are there any template parameters? + if (!parse_opt_template_argument_list (curr, mtal)) + if (error ()) + return false; + } + skip_blanks (curr); + if (curr[0] != ':' || curr[1] != ':') + return false; + string scope_name (str, str_end - str); + match_name.add_scope (scope_name, mtal); + str = curr + 2; + return true; +} + +bool MatchSignature::parse_opt_template_argument_list (const char *&str, + MatchTemplateArgList *&mtal) { + skip_blanks (str); + mtal = 0; + + // check if the list starts with '<' + if (str[0] != '<' || strncmp (str, "", 9) == 0) + return false; + str++; + + mtal = new MatchTemplateArgList; + if (!parse_template_argument_list (str, *mtal)) { + if (error ()) { + delete mtal; + return false; + } + } + if (*str != '>') { + _state = ERR_INVALID_ARG_LIST; + return false; + } + str++; + return true; +} + +bool MatchSignature::parse_template_argument_list (const char *&str, + MatchTemplateArgList &mtal) { + MatchTemplateArg *mta; + if (!parse_template_argument (str, mta)) + return !error (); + mtal.append (mta); + skip_blanks (str); + + while (str[0] == ',') { + str++; + if (!parse_template_argument (str, mta)) { + _state = ERR_INVALID_ARG_LIST; + return false; + } + mtal.append (mta); + skip_blanks (str); + } + return true; +} + +bool MatchSignature::parse_template_argument (const char *&str, + MatchTemplateArg *&mta) { + mta = 0; + skip_blanks (str); + + // check for end of list + if (str[0] == '>') + return false; + + // first check for ellipses + if (str[0] == '.') { + if (str[1] == '.' && str[2] == '.') { + str += 3; + mta = new MTA_Ellipses; + return true; + } + else { + _state = ERR_INVALID_DOT; + return false; + } + } + + // now check for 'any' + if (str[0] == '%') { + if (!_wildcards_allowed) { + _state = ERR_WILDCARD; + return false; + } + const char *curr = str; + curr++; + skip_blanks (curr); + if (*curr == ',' || *curr == '>') { + str = curr; + mta = new MTA_Any; + return true; + } + } + + // check for static function/object address as template arg + if (str[0] == '&') { + const char *curr = str; + curr++; + skip_blanks (curr); + MatchName name; + if (!parse_declarator_id (curr, name)) + return false; + skip_blanks (curr); + if (*curr == ',' || *curr == '>') { + str = curr; + mta = new MTA_Addr (name); + return true; + } + else + return false; + } + + // check for an expression + // TODO: decimal literals are not enough + long long val; + if (parse_dec_literal (str, val)) { + mta = new MTA_Value (val); + return true; + } + + // check for a type parameter + MatchTypeRef arg_type; + if (!parse_declaration (str, true, arg_type)) + return false; + + mta = new MTA_Type (arg_type); // arg type will be copied + return true; +} + +/*bool MatchSignature::parse_dec_string_literal(const char *&str, std::string &val) { + skip_blanks (str); + + const char *currStr = str; + bool strLitFound = false; + + while(*currStr == '\\' && currStr[1] == '"') { + strLitFound = true; + currStr += 2; + while(*currStr != '\\' || currStr[1] != '"') { + val += *currStr; + currStr++; + } + currStr += 2; + skip_blanks(currStr); + } + + str = currStr; + return strLitFound; +} +*/ +bool MatchSignature::parse_dec_literal (const char *&str, long long &val) { + skip_blanks (str); + long long sign = 1; + + if (*str == '-') { + sign = -1; + str++; + skip_blanks (str); + } + + if (!(*str >= '0' && *str <= '9')) + return false; + + val = 0; + while (*str >= '0' && *str <= '9') { + val = 10LL * val + (long long)(*str - '0'); + str++; + } + val *= sign; + // Skip ULL suffixes. + while (*str == 'U' || *str == 'L') + ++str; + return true; +} + +bool MatchSignature::parse_declarator (const char *&str, bool abstract, + MatchTypeRef &type) { + // first parse an optional sequence of pointer operators like '*' + // the type from the decl specs is simply extended. + while (parse_ptr_operator (str, type)) + if (error ()) + return false; + + skip_blanks (str); + bool nested_declarator = false; + const char *nested_str = str; + if (*str == '(' && (!abstract || is_abstract_nested_declarator (str))) { + // skip the nested declarator and parse it later + nested_declarator = true; + if (!skip_nested_declarator (str)) { + _state = ERR_INVALID_DECLARATOR; + return false; + } + } + else { + // parse the declarator id + if (!parse_declarator_id (str, _name)) { + if (error ()) + return false; + } + else if (abstract) { + _state = ERR_DECL_NOT_ABSTRACT; + return false; + } + } + + // now parse an optional sequence of [constant] or (...) cv + parse_declarator_post (str, type); + if (error ()) + return false; + + if (nested_declarator) { + // parse a declarator in brackets + nested_str++; + if (!parse_declarator (nested_str, abstract, type)) { + if (!error ()) + _state = ERR_INVALID_DECLARATOR; + return false; + } + skip_blanks (nested_str); + if (*nested_str != ')') { + _state = ERR_MISSING_BRACKET; + return false; + } + } + + // if we came here, everything is fine + return true; +} + +bool MatchSignature::is_abstract_nested_declarator (const char *str) { + // skip sequence of opening brackets + while (*str == '(') { + str++; + skip_blanks (str); + } + // create a type object, which is only needed temporarily + MatchTypeRef dummy_type = MatchTypeRef::make_int (); + // check whether the string starts with a pointer operator, + // which is the only reason for a *nested* abstract declarator + return parse_ptr_operator (str, dummy_type); +} + +bool MatchSignature::skip_nested_declarator (const char *&str) { + int brackets = 1; + str++; + while (*str) { + if (*str == '(') + brackets++; + else if (*str == ')') + brackets--; + str++; + if (brackets == 0) + return true; + } + return false; +} + +bool MatchSignature::parse_declarator_post (const char *&str, MatchTypeRef &type) { + skip_blanks (str); + if (*str == '(') { // analyse a function declarator + str++; + + // start with the argument list + vector arg_types; + bool var_args; + parse_fct_args (str, arg_types, var_args); + if (error ()) + return false; + + // check for the closing bracket + skip_blanks (str); + if (*str != ')') { + _state = ERR_MISSING_BRACKET; + return false; + } + str++; + + // now parse optional const or volatile qualifiers + bool is_const = false, is_volatile = false; + while (true) { + skip_blanks (str); + if (next_word ("const", str)) + is_const = true; + else if (next_word ("volatile", str)) + is_volatile = true; + else + break; + } + + // now parse other post declarators ("(...) cv" or "[ dim ]") + parse_declarator_post (str, type); + if (error ()) + return false; + + // make the current type a (qualified) function type + type.to_function (arg_types, var_args); + if (is_const) type.qualifiers ().qualify_const (); + if (is_volatile) type.qualifiers ().qualify_volatile (); + return true; + } + else if (*str == '[') { // analyse an array declarator + str++; + skip_blanks (str); + + // TODO: syntax (*foo)[] not yet implemented; however, this is no type + bool any_size = false; + unsigned long array_size = 0; + if (*str == '%') { + if (!_wildcards_allowed) { + _state = ERR_WILDCARD; + return false; + } + str++; + any_size = true; + } + else if (*str >= '0' && *str <= '9') { + while (*str >= '0' && *str <= '9') { + array_size = 10uL * array_size + (unsigned long)(*str - '0'); + str++; + } + } + else { + _state = ERR_INVALID_ARRAY; + return false; + } + + // check for the closing bracket + skip_blanks (str); + if (*str != ']') { + _state = ERR_MISSING_BRACKET; + return false; + } + str++; + + // look for further post declarators and make the type + parse_declarator_post (str, type); + if (error ()) + return false; + + // make the current type an array type + if (any_size) + type.to_array (); + else + type.to_array (array_size); + + return true; + } + return false; +} + +bool MatchSignature::parse_ptr_operator (const char *&str, MatchTypeRef &type) { + skip_blanks (str); + const char *curr = str; + MatchName memb_ptr_scope; + if (!parse_nested_name (curr, memb_ptr_scope)) + if (error ()) + return false; + + skip_blanks (curr); + if (*curr == '*') { + if (memb_ptr_scope.undefined ()) + type.to_pointer (); + else + type.to_memb_pointer (memb_ptr_scope); + str = curr + 1; + while (true) { + skip_blanks (str); + if (next_word ("const", str)) + type.qualifiers ().qualify_const (); + else if (next_word ("volatile", str)) + type.qualifiers ().qualify_volatile (); + else + break; + } + return true; + } + else if (*curr == '&') { + str = curr + 1; + type.to_reference (); + return true; + } + return false; +} + +bool MatchSignature::parse_declarator_id (const char *&str, MatchName &match_name) { + skip_blanks (str); + // first check if this is a qualified name + const char *curr = str; + if (!parse_nested_name (curr, match_name)) + if (error ()) + return false; + skip_blanks (curr); + // now check if a name follows + const char *name_start = curr; + while (is_id (*curr)) + curr++; + if (curr == name_start) + return false; + int len = curr - name_start; + // check for operator + if (len == 8 && strncmp (name_start, "operator", 8) == 0) { + // yes, an operator + skip_blanks (curr); + MatchName::Operator oper; + // check for operator +, etc. + if (parse_operator_id (curr, oper)) { + match_name.oper (oper); + } + else { + // check for operator int(), etc. + MatchTypeRef conv_type; + if (parse_conv_id (curr, conv_type)) + match_name.conv_type (conv_type); + else { + _state = ERR_INVALID_OPER; + return false; // this is an error! + } + } + } + else { + // a normal function name + string name (name_start, curr - name_start); + match_name.name (name); + } + str = curr; + + // are there any template parameters? + MatchTemplateArgList *mtal; + if (!parse_opt_template_argument_list (str, mtal)) + if (error ()) + return false; + // set the template argument list (might be 0) + match_name.template_args (mtal); + return true; +} + +bool MatchSignature::parse_conv_id (const char *&str, MatchTypeRef &type) { + // Here we allow more than the C++ grammar: + // decl_spec_seq_opt declarator_opt + // => + // abstract-declaration / with look-ahead "(" ")" + // This is because our signatures may be something like "void (*)()", which + // would not be allowed by the C++. + + // search the empty argument list of the conversion operator + int pos = (int)strlen(str); + while (pos >= 0 && str[pos] != ')') pos--; // search for last ')' + pos--; + while(pos >= 0 && str[pos] == ' ') pos--; // skip blanks + if (pos <= 0 || str [pos] != '(') { + _state = ERR_CONV_FCT_ARGS; + return false; + } + + // create a new string that contains only the abstract declarator of the + // conversion's target type + string declarator_buffer(str, pos); + const char *curr = declarator_buffer.c_str(); + + // parse an abstract declaration + if (!parse_declaration (curr, true, type)) { + if (error ()) + return false; + _state = ERR_INVALID_SPEC; + return false; + } + + str = str + pos; + return true; +} + +bool MatchSignature::parse_operator_id (const char *&str, MatchName::Operator &op) { + + // first check for new and delete + bool op_new = false, op_delete = false; + if (next_word ("new", str)) + op_new = true; + else if (next_word ("delete", str)) + op_delete = true; + + skip_blanks (str); + if (next_word ("[]", str)) { + op = (op_new ? MatchName::OP_NEW_ARRAY : + (op_delete ? MatchName::OP_DELETE_ARRAY : + MatchName::OP_INDEX)); + return true; + } + + op = (op_new ? MatchName::OP_NEW : + (op_delete ? MatchName::OP_DELETE: + MatchName::OP_UNDEFINED)); + if (op != MatchName::OP_UNDEFINED) + return true; + + // check for the rest (and increment the pointer) + const char *saved_pos = str; + char first = *str; + str++; + if (first == '+') { // +, +=, ++ + if (*str == '=') { + str++; + op = MatchName::OP_ADD_EQ; + } + else if (*str == '+') { + str++; + op = MatchName::OP_INCR; + } + else + op = MatchName::OP_PLUS; + } + else if (first == '-') { // -, -=, --, ->*, -> + if (*str == '=') { + str++; + op = MatchName::OP_SUB_EQ; + } + else if (*str == '-') { + str++; + op = MatchName::OP_DECR; + } + else if (*str == '>') { + str++; + if (*str == '*') { + str++; + op = MatchName::OP_PTS_STAR; + } + else + op = MatchName::OP_PTS; + } + else + op = MatchName::OP_MINUS; + } + else if (first == '*') { // *, *= + if (*str == '=') { + str++; + op = MatchName::OP_MUL_EQ; + } + else + op = MatchName::OP_MUL; + } + else if (first == '/') { // /, /= + if (*str == '=') { + str++; + op = MatchName::OP_DIV_EQ; + } + else + op = MatchName::OP_DIV; + } + else if (first == '%') { // %, %%, %%= ; that's ugly! %% has to be used for % + if (_wildcards_allowed) { + if (*str == '%') { + str++; + if (*str == '=') { + str++; + op = MatchName::OP_MOD_EQ; + } + else + op = MatchName::OP_MODULO; + } + else + op = MatchName::OP_ANY; + } + else { + if (*str == '=') { + str++; + op = MatchName::OP_MOD_EQ; + } + else + op = MatchName::OP_MODULO; + } + } + else if (first == '^') { // ^, ^= + if (*str == '=') { + str++; + op = MatchName::OP_XOR_EQ; + } + else + op = MatchName::OP_ROOF; + } + else if (first == '&') { // &, &=, && + if (*str == '&') { + str++; + op = MatchName::OP_AND_AND; + } + else if (*str == '=') { + str++; + op = MatchName::OP_AND_EQ; + } + else + op = MatchName::OP_AND; + } + else if (first == '|') { // |, |=, || + if (*str == '|') { + str++; + op = MatchName::OP_OR_OR; + } + else if (*str == '=') { + str++; + op = MatchName::OP_IOR_EQ; + } + else + op = MatchName::OP_OR; + } + else if (first == '~') { // ~ + op = MatchName::OP_TILDE; + } + else if (first == '!') { // !, != + if (*str == '=') { + str++; + op = MatchName::OP_NEQ; + } + else + op = MatchName::OP_NOT; + } + else if (first == '=') { // =, == + if (*str == '=') { + str++; + op = MatchName::OP_EQL; + } + else + op = MatchName::OP_ASSIGN; + } + else if (first == '<') { // <, <<, <=, <<= + if (*str == '<') { + str++; + if (*str == '=') { + str++; + op = MatchName::OP_LSH_EQ; + } + else { + op = MatchName::OP_LSH; + } + } + else if (*str == '=') { + str++; + op = MatchName::OP_LEQ; + } + else + op = MatchName::OP_LESS; + } + else if (first == '>') { // >, >>, >=, >>= + if (*str == '>') { + str++; + if (*str == '=') { + str++; + op = MatchName::OP_RSH_EQ; + } + else + op = MatchName::OP_RSH; + } + else if (*str == '=') { + str++; + op = MatchName::OP_GEQ; + } + else + op = MatchName::OP_GREATER; + } + else if (first == ',') { // , + op = MatchName::OP_COMMA; + } + else if (first == '(') { // () + if (*str == ')') { + str++; + op = MatchName::OP_CALL; + } + } + else if (first == '?') { // ?: + if (*str == ':') { + str++; + op = MatchName::OP_COND; + } + } + else if (first == '.') { // ., .* + if (*str == '*') { + str++; + op = MatchName::OP_DOT_STAR; + } + else { + op = MatchName::OP_DOT; + } + } + + if (op != MatchName::OP_UNDEFINED) + return true; + + str = saved_pos; + return false; +} + +bool MatchSignature::parse_fct_args (const char *&str, vector &args, + bool &var_args) { + int arg = 0; + bool have_ellipses = false; + var_args = false; + // parse the elements of the argument list step-by-step + while (true) { + skip_blanks (str); + // end of argument list? + if (*str == ')') + break; + // check for the ',' and consume it + if (arg > 0) { + if (*str == ',') { + if (have_ellipses) { + _state = ERR_ARG_AFTER_ELLIPSES; + return false; + } + str++; + skip_blanks (str); + } + else { + _state = ERR_INVALID_ARG_LIST; + return false; + } + } + // check for ellipses first + if (parse_ellipses (str)) { + have_ellipses = true; + // set a flag that says that this function type has a var. arg. list + var_args = true; + } + else { + if (error ()) + return false; + MatchTypeRef arg_type; + if (!parse_declaration (str, true, arg_type)) { + if (error ()) + return false; + _state = ERR_INVALID_ARG_LIST; + return false; + } + // add this type as an argument type; + args.push_back (arg_type); + } + arg++; + } + return true; +} + +bool MatchSignature::parse_ellipses (const char *&str) { + const char *curr = str; + if (*curr++ != '.') + return false; + if (*curr++ != '.') { + _state = ERR_INVALID_DOT; + return false; + } + if (*curr++ != '.') { + _state = ERR_INVALID_DOT; + return false; + } + skip_blanks (curr); + if (*curr == ':') + return false; + str = curr; + return true; +} + +inline void MatchSignature::skip_blanks (const char *&str) const { + while (*str == ' ') str++; +} + +inline bool MatchSignature::next_word (const char *word, const char *&str) const { + const char *curr = str; + while (*word != '\0' && *curr == *word) { + curr++; + word++; + } + if (*word == '\0' && !is_id (*curr)) { + str = curr; + return true; + } + else + return false; +} + +inline bool MatchSignature::is_id (char c) const { + return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || + c == '_' || (_wildcards_allowed && c == '%') || (c >= '0' && c <= '9')); +} diff --git a/AspectC++/ACModel/MatchExpr.h b/AspectC++/ACModel/MatchExpr.h new file mode 100644 index 0000000..3651f27 --- /dev/null +++ b/AspectC++/ACModel/MatchExpr.h @@ -0,0 +1,240 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __MatchExpr_h__ +#define __MatchExpr_h__ + +#include + +#include "MatchType.h" +#include "MatchTemplateArg.h" +#include "MatchName.h" + +// This class is an abstraction for a C++ object signature (function, type, +// attribute). + +class MatchSignature { + +public: + // object state + enum State { + NEW = 0, // this object is not initialized, yet + NORMAL = 1, // this is a valid match expression, ready for 'match' calls + // state of the expression ( < 0 means an error code) + ERR_NO_DECL_SPEC = -1, // no declaration specifier given + ERR_EMPTY_MATCH_EXPR = -2, // neither decl spec nor declarator given + ERR_TOKENS_AFTER_END = -3, // tokens after end of match expression + ERR_INVALID_DOT = -4, // invalid use of "..." + ERR_INVALID_DECLARATOR = -5, // invalid declarator + ERR_MISSING_BRACKET = -6, // missing bracket + ERR_MISSING_DECL_ID = -7, // missing declarator id (the name) + ERR_DECL_NOT_ABSTRACT = -8, // argument declarator not abstract + ERR_ARG_AFTER_ELLIPSES = -9, // argument after "..." + ERR_INVALID_ARG_LIST = -10, // invalid argument list + ERR_INVALID_ARRAY = -11, // array size is neither "%" nor int constant + ERR_DUP_CV = -12, // duplicated const or volatile + ERR_DUP_SIGN = -13, // duplicated signed or unsigned + ERR_CONF_SIZE = -14, // conflicting short and long + ERR_INVALID_TYPE = -15, // invalid type + ERR_INVALID_OPER = -16, // invalid operator name + ERR_TEMPLATE_ARG_LIST = -17, // error in template arguments + ERR_DUP_SPEC = -18, // duplicate virtual, inline, or explicit + ERR_INVALID_SPEC = -19, // only functions can have function specifiers + ERR_VIRT_STAT_FCT_SPEC = -20, // 'static' and 'virtual' can't be combined + ERR_WILDCARD = -21, // wildcard used in signature (not match expression) + ERR_CONV_FCT_ARGS = -22 // (empty) conversion function argument list not found + }; + +protected: + State _state; + bool _wildcards_allowed; + +private: + // primitive types + enum PrimType { + PRIM_NONE, PRIM_CHAR, PRIM_INT, PRIM_INT128, PRIM_VOID, PRIM_BOOL, PRIM_FLOAT, + PRIM_DOUBLE, PRIM_WCHAR_T + }; + + // const or volatile qualifiers + enum CVQualifier { QUAL_NONE = 0, QUAL_CONST = 1, QUAL_VOLATILE = 2 } ; + + // general declaration specifiers + enum Spec { + DT_NONE = 0, DT_STATIC + } _spec; + // function specifiers, currently only 'virtual' is supported by the parser + enum FctSpec { + FCT_NONE = 0, FCT_VIRTUAL = 1, FCT_INLINE = 2, FCT_EXPLICIT = 4 + } _fct_spec; + + // type used for parsing and analysing the declaration specifier sequence + struct DeclSpecs { + CVQualifier _qual; // bitfield with const/volatile qualifiers + Spec _spec; // bitfield with general specifiers + FctSpec _fct_spec; // bitfield with function specifiers + int _sign; // -1, 0, +1 + int _size; // -1 = short, 0 = no change, 1 = long, 2 = long long, ... + bool _allow_name; + PrimType _type; + MatchName _name; + DeclSpecs () : + _qual (QUAL_NONE), _spec (DT_NONE), _fct_spec (FCT_NONE), _sign (0), _size (0), + _allow_name (true), _type (PRIM_NONE) {} + }; + +public: + //! match expression type + enum Type { ATTRIBUTE, FUNCTION, TYPE } _expr_type; + +protected: + //! the name pattern of the match expression + MatchName _name; + //! the type pattern + MatchTypeRef _type; + +public: + // constructors/destructor + inline MatchSignature (); + inline MatchSignature (const string &str); + + // parse a match expression string + // complain about errors => result false + bool parse (const string &str); + + // check the state of this match expression + inline bool error () const; + inline bool state () const; + inline bool is_new () const; + inline bool is_function () const; + inline bool is_virtual_function () const; + inline bool is_static() const; + inline bool is_attribute () const; + inline bool is_type () const; + + // manipulate the state + inline void declare_virtual_function (); + inline void declare_static(); + + // get more detailed infos about the match expression + inline MatchName &name (); + inline MatchTypeRef &type (); + +private: + // internal parser functions that analyse a match expr string + bool parse_match_expr (const char *&str); + bool parse_declaration (const char *&str, bool abstract, MatchTypeRef &type); + bool parse_decl_spec_seq( const char *&str, MatchTypeRef &type, FctSpec &fs, Spec &s ); + bool parse_decl_spec (const char *&str, DeclSpecs &ds); + bool parse_nested_name (const char *&str, MatchName &match_name); + bool parse_nested_name_elem (const char *&str, MatchName &match_name); + bool parse_opt_template_argument_list (const char *&str, + MatchTemplateArgList *&mtal); + bool parse_template_argument_list (const char *&str, + MatchTemplateArgList &mtal); + bool parse_template_argument (const char *&str, MatchTemplateArg *&mta); +//bool parse_dec_string_literal(const char *&str, std::string &val); + bool parse_dec_literal (const char *&str, long long &val); + bool parse_declarator (const char *&str, bool abstract, MatchTypeRef &type); + bool is_abstract_nested_declarator (const char *str); + bool skip_nested_declarator (const char *&str); + bool parse_declarator_post (const char *&str, MatchTypeRef &type); + bool parse_ptr_operator (const char *&str, MatchTypeRef &type); + bool parse_declarator_id (const char *&str, MatchName &match_name); + bool parse_conv_id (const char *&str, MatchTypeRef &type); + bool parse_operator_id (const char *&str, MatchName::Operator &op); + bool parse_fct_args (const char *&str, vector &args, bool &va); + bool parse_ellipses (const char *&str); + inline void skip_blanks (const char *&str) const; + inline bool next_word (const char *word, const char *&str) const; + inline bool is_id (char c) const; +}; + +// implementations of inline constructors/destructor +inline MatchSignature::MatchSignature () : _state (NEW), _wildcards_allowed (false) {} +inline MatchSignature::MatchSignature (const string &str) : _state (NEW), _wildcards_allowed (false) { + parse (str); +} + +// check the state of this match expression +inline bool MatchSignature::error () const { return _state < 0; } +inline bool MatchSignature::state () const { return _state; } +inline bool MatchSignature::is_new () const { return _state == NEW; } +inline bool MatchSignature::is_function () const { return _expr_type == FUNCTION; } +inline bool MatchSignature::is_virtual_function () const { + return is_function () && ((_fct_spec & FCT_VIRTUAL) != 0); +} +inline bool MatchSignature::is_static() const { + return ( is_function() || is_attribute() ) && ( ( _spec & DT_STATIC ) != 0 ); +} +inline bool MatchSignature::is_attribute () const { return _expr_type == ATTRIBUTE; } +inline bool MatchSignature::is_type () const { return _expr_type == TYPE; } + +// manipulate the state +inline void MatchSignature::declare_virtual_function () { + assert (is_function ()); + _fct_spec = (FctSpec)(FCT_VIRTUAL | _fct_spec); +} +inline void MatchSignature::declare_static() { + assert( is_function () || is_attribute() ); + _spec = (Spec)(DT_STATIC | _spec); +} + +// get more detailed infos about the match expression +// TODO: const correctness +inline MatchName &MatchSignature::name () { return _name; } +inline MatchTypeRef &MatchSignature::type () { return _type; } + +// this is an abstraction for AspectC++ match expressions. These expressions +// describe signature patters, which can be matched agains the signatures +// of C++ objects. Match expressions are 'Signatures' that may contain +// special wildcard symbols ("%", "..."). + +class MatchExpr : public MatchSignature { +public: + + // constructors/destructor + inline MatchExpr (); + inline MatchExpr (const string &str); + + // check if a certain signature is matched by this expression, + // obj is passed to check the name part of the signature + // true is returned if the signature is matched + inline bool matches (MatchSignature &sig); +}; + +// implementations of inline constructors/destructor +inline MatchExpr::MatchExpr () { _wildcards_allowed = true; } +inline MatchExpr::MatchExpr (const string &str) { _wildcards_allowed = true; parse (str); } + +// check if the match expression matches a passed match signature +inline bool MatchExpr::matches (MatchSignature &sig) { + assert (_state == NORMAL && _expr_type == sig._expr_type && !_type.is_undefined ()); + + if ((is_function() || is_attribute()) && !_name.matches (sig.name ())) + return false; + if (!_type.matches (sig.type ())) + return false; + if (is_virtual_function () && !sig.is_virtual_function ()) + return false; + if( is_static() && !sig.is_static() ) + return false; + return true; +} + +#endif // __MatchExpr_h__ diff --git a/AspectC++/ACModel/MatchName.cc b/AspectC++/ACModel/MatchName.cc new file mode 100644 index 0000000..df15b21 --- /dev/null +++ b/AspectC++/ACModel/MatchName.cc @@ -0,0 +1,320 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "MatchName.h" +#include "MatchType.h" +#include "MatchTemplateArg.h" + +#include +#include +using namespace std; + +#include "lexertl/rules.hpp" +#include "lexertl/generator.hpp" +#include "lexertl/lookup.hpp" + +void MatchName::MRegComp::setup (const string &str) { + if (_compiled_used) _compiled.clear (); + + const char *sig = str.c_str(); + char *buffer = new char[3 + strlen (sig) * 2]; + char *p = buffer; + char ch; + + *p++ = '^'; + while (*sig) { + ch = *sig++; + switch (ch) { + case '%': + *p++ = '.'; + *p++ = '*'; + break; + default: + *p++ = ch; + } + } + *p++ = '$'; + *p++ = 0; + + lexertl::rules rules; + rules.push (buffer, 1); // id is '1', because it is not needed; but != 0 + try { + lexertl::generator::build(rules, _compiled); // gen. state machine representation + _compiled_used = true; + } + catch (const std::exception &e) { + _error = true; + } + delete[] buffer; +} + +bool MatchName::MRegComp::matches (const string &name) const { + if (!_compiled_used || _error) return false; + + string input (name); + string::const_iterator iter = input.begin (); + string::const_iterator end = input.end (); + lexertl::smatch results (iter, end); + try { + lexertl::lookup (_compiled, results); + } + catch (const std::exception &e) { + return false; // hm, how to handle an error here? + } + + return (results.id == 1); +} + +// this is used if a match name component is '%' => always true +bool MatchName::MTrue::matches (const string &name) const { + return true; +} + +// efficient string comparison +bool MatchName::MStrComp::matches (const string &name) const { + return _str == name; +} + + +void MatchName::Name::make_matcher () { + // TODO: make more different Matcher variants (prefix/suffix) + bool only = true; // only '%' characters in the match string + bool none = true; // no '%' character + const char *str = _str.c_str (); + while (*str != '\0') { + if (*str == '%') + none = false; + else + only = false; + str++; + } + if (only) + _matcher = new MTrue; + else if (none) + _matcher = new MStrComp (_str); + else + _matcher = new MRegComp (_str); +} + +MatchName::~MatchName () { + for (int s = 0; s < scopes (); s++) + if (_scope_template_args[s]) + delete _scope_template_args[s]; + if (_name_template_args) + delete _name_template_args; +} + +MatchName &MatchName::operator = (const MatchName ©) { + _scopes = copy._scopes; + for (int i = 0; i < copy.scopes (); i++) + if (copy._scope_template_args[i]) + _scope_template_args.push_back ( + new MatchTemplateArgList (*copy._scope_template_args[i])); + else + _scope_template_args.push_back (0); + _name = copy._name; + if (copy._name_template_args) + _name_template_args = new MatchTemplateArgList (*copy._name_template_args); + else + _name_template_args = 0; + _oper = copy._oper; + _conv_type = copy._conv_type; + return *this; +} + +void MatchName::print (ostream &out) const { + for (int s = 0; s < scopes (); s++) { + out << scope (s); + if (_scope_template_args[s]) + out << *_scope_template_args[s]; + out << "::"; + } + + if (!_conv_type.is_undefined ()) + out << "operator " << _conv_type; + else + out << name (); + + if (_name_template_args) + out << *_name_template_args; +} + +// print the 'mangled' string representation of this type +void MatchName::mangle (ostream &os) const { + // TODO: still incomplete! Template args, ... + if (scopes ()) { + os << "N"; + for (int s = 0; s < scopes (); s++) { + string sn = scope (s); + if (sn == "") + sn = "_GLOBAL__N_1"; + os << sn.length () << sn; + if (_scope_template_args[s]) + _scope_template_args[s]->mangle (os); + } + os << "E"; + } + os << name ().length() << name(); + if (_name_template_args) + _name_template_args->mangle (os); +} + +bool MatchName::scope_matches (vector &scopes, + vector &scope_template_args, + int match_pos, int sig_pos) { + + Name &name = _scopes[match_pos]; + MatchTemplateArgList *mtal = _scope_template_args[match_pos]; + match_pos--; + + static string dots ("..."); + if (name.str () == dots) { + // if '...' is the start of the qualified name match expression => match + if (match_pos == -1) + return true; + // handle ellipses (brute force :-( ) + while (sig_pos >= 0) { + if (scope_matches (scopes, scope_template_args, match_pos, sig_pos)) + return true; + sig_pos--; + } + return false; + } + + // if the argument scope is the global scope it is a mismatch + if (sig_pos == -1) + return false; + + // check template arguments of the scope + if (mtal) { + MatchTemplateArgList *sig_mtal = scope_template_args[sig_pos]; + if (!sig_mtal || !mtal->matches(*sig_mtal)) + return false; + } + + // compare the name pattern + if (!name.matches (scopes[sig_pos].str ())) + return false; + + sig_pos--; + // check the next scope + if (match_pos >= 0) + return scope_matches (scopes, scope_template_args, match_pos, sig_pos); + + // no scope to check left, 'scope' must be defined in the global scope + if (sig_pos != -1) + return false; + + // everything ok + return true; +} + +bool MatchName::oper_matches (Operator oper) { + static string any ("%"); + + // '%' as a function name also matches operators + if (!_name.str ().empty ()) + return _name.str () == any; + + // only operator signatures are considered + if (_oper == OP_UNDEFINED) + return false; + + // any operator + if (_oper == OP_ANY) + return true; + + // return true, iff the operator is the same + return _oper == oper; +} + +bool MatchName::conv_matches (MatchTypeRef type) { + static string any ("%"); + + // '%' as a function name also matches operators + if (!_name.str ().empty ()) + return _name.str () == any; + + // any operator is ok + if (_oper == OP_ANY) + return true; + + // check the conversion type of the function (if it is a conversion function) + return !type.is_undefined () && !_conv_type.is_undefined () && + _conv_type.matches (type); +} + +bool MatchName::name_matches (Name &name, + MatchTemplateArgList *name_template_args) { + if (_name_template_args) { + if (!name_template_args || + !_name_template_args->matches (*name_template_args)) + return false; + } + return _name.matches (name.str ()); +} + +bool MatchName::matches (MatchName &matched_name) { + // if the matched name is not defined in the global scope and the match + // name has no scopes, it is no match + if (scopes () == 0 && matched_name.scopes () > 0) + return false; + + // if the match name has a scope, compare it + if (scopes () > 0 && !scope_matches (matched_name._scopes, + matched_name._scope_template_args, + scopes () - 1, matched_name.scopes () - 1)) + return false; + + if (matched_name.oper () != OP_UNDEFINED) { + // this an operator name match expression + return oper_matches (matched_name.oper ()); + } + else if (!matched_name.conv_type ().is_undefined ()) { + // this is a conversion operator match expression + return conv_matches (matched_name.conv_type ()); + } + else if (_oper == OP_UNDEFINED && _conv_type.is_undefined ()) { + // normal name + return name_matches (matched_name._name, matched_name._name_template_args); + } + else + return false; +} + +// check whether the name will match only a single entity +bool MatchName::is_trivial () const { + // the name should not contain any wildcards + if (strstr (_name.str ().c_str(), "%") != 0 || + strstr (_name.str ().c_str(), "...") != 0) + return false; + // the name should not have template parameters, because + // this could be type pattern + if (_name_template_args) + return false; + // now check all scopes for the same conditions + for (int i = 0; i < scopes (); i++) { + const char *scope_name = scope (i).c_str(); + if (strstr (scope_name, "%") != 0 || + strstr (scope_name, "...") != 0) + return false; + if (_scope_template_args[i]) + return false; + } + return true; +} diff --git a/AspectC++/ACModel/MatchName.h b/AspectC++/ACModel/MatchName.h new file mode 100644 index 0000000..6ae6c4d --- /dev/null +++ b/AspectC++/ACModel/MatchName.h @@ -0,0 +1,183 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __MatchName_h__ +#define __MatchName_h__ + +#include +using std::ostream; +using std::endl; +#include +using std::string; +#include +using std::vector; +#include "lexertl/state_machine.hpp" + +#include "MatchType.h" // ugly cyclic relationship for conversion oper names + +class MatchTemplateArgList; + +class MatchName { + + class Matcher { + public: + virtual bool matches (const string &name) const = 0; + virtual ~Matcher () {} + }; + + class MRegComp : public Matcher { + string _expr; + lexertl::state_machine _compiled; // internal: lexertl compiled regular expression + bool _compiled_used; + bool _error; // true, if any operation failed + public: + MRegComp () : _compiled_used(false), _error (false) {} + MRegComp (const string &str) : + _expr(str), _compiled_used(false), _error (false) { setup(str); } + MRegComp (const MRegComp ©) : + _expr(copy._expr), _error(false) { + if (_compiled_used) { + _compiled.clear(); + _compiled_used = false; + } + } + MRegComp &operator = (const MRegComp ©) { + if (_compiled_used) _compiled.clear (); + _expr = copy._expr; + _error = false; + _compiled_used = false; + return *this; + } + void setup (const string &str); + virtual bool matches (const string &name) const; + }; + + class MTrue : public Matcher { + public: + virtual bool matches (const string &name) const; + }; + + class MStrComp : public Matcher { + string _str; + public: + MStrComp (const string &str) : _str (str) {} + virtual bool matches (const string &name) const; + }; + + class Name { + Matcher *_matcher; // not copied, but regenerated on demand + string _str; + void make_matcher (); + public: + Name () : _matcher (0) {} + Name (const string &s) : _matcher (0), _str (s) {} + Name (const Name ©) { *this = copy; } + Name &operator = (const Name ©) { + _matcher = 0; // regenerated on demand + _str = copy._str; + return *this; + } + ~Name () { if (_matcher) delete _matcher; } + bool matches (const string &name) { + if (!_matcher) + make_matcher (); + return _matcher->matches (name); + } + Name &operator = (const string &str) { + _matcher = 0; + _str = str; + return *this; + } + string str () const { return _str; } + }; + +public: + enum Operator { + OP_UNDEFINED = -1, OP_ANY = 0, + OP_PLUS, OP_MINUS, OP_MUL, OP_DIV, OP_MODULO, OP_ROOF, + OP_AND, OP_OR, OP_TILDE, OP_NOT, OP_LESS, OP_GREATER, + OP_EQL, OP_GEQ, OP_LEQ, OP_NEQ, OP_AND_AND, OP_OR_OR, + OP_LSH, OP_RSH, OP_DECR, OP_INCR, OP_ASSIGN, OP_COMMA, + OP_ADD_EQ, OP_SUB_EQ, OP_MUL_EQ, OP_DIV_EQ, OP_MOD_EQ, + OP_AND_EQ, OP_IOR_EQ, OP_LSH_EQ, OP_RSH_EQ, OP_XOR_EQ, + OP_PTS_STAR, OP_PTS, OP_NEW, OP_DELETE, OP_NEW_ARRAY, + OP_DELETE_ARRAY, OP_CALL, OP_INDEX, + OP_COND, OP_DOT, OP_DOT_STAR + }; + +private: + vector _scopes; // scope names ('X::Y::Z::') + vector _scope_template_args; + Name _name; // either name + MatchTemplateArgList *_name_template_args; + Operator _oper; // ... or operator name + MatchTypeRef _conv_type; // ... or conversion type id + + bool oper_matches (Operator oper); + bool conv_matches (MatchTypeRef type); + bool name_matches (Name &name, MatchTemplateArgList *name_template_args); + +public: + + MatchName () : _name_template_args (0), _oper (OP_UNDEFINED) {} + ~MatchName (); + MatchName (const MatchName ©) { *this = copy; } + MatchName &operator = (const MatchName ©); + + // print the contents of this match name object + void print (ostream &) const; + // print the 'mangled' string representation of this type + void mangle (ostream &os) const; + + // define a match name + void name (const string &n) { + _name = n; + } + void template_args (MatchTemplateArgList *mtal) { + _name_template_args = mtal; + } + void oper (Operator o) { _oper = o; } + void conv_type (const MatchTypeRef &ct) { _conv_type = ct; } + void add_scope (const string &s, MatchTemplateArgList *mtal = 0) { + _scopes.push_back (Name (s)); + _scope_template_args.push_back (mtal); + } + // get the object contents + int scopes () const { return _scopes.size (); } + string scope (int i) const { return _scopes[i].str (); } + string name () const { return _name.str (); } + Operator oper () const { return _oper; } + MatchTypeRef conv_type () const { return _conv_type; } + bool undefined () const { + return scopes () == 0 && _name.str ().empty () && + _oper == OP_UNDEFINED && _conv_type.is_undefined (); + } + bool scope_matches (vector &, vector &, + int match_pos, int sig_pos); + bool matches (MatchName &match_name); + + // check whether the name will match only a single entity + bool is_trivial () const; +}; + +inline ostream &operator << (ostream &os, const MatchName &mn) { + mn.print (os); + return os; +} + +#endif // __MatchName_h__ diff --git a/AspectC++/ACModel/MatchTemplateArg.cc b/AspectC++/ACModel/MatchTemplateArg.cc new file mode 100644 index 0000000..741ff4f --- /dev/null +++ b/AspectC++/ACModel/MatchTemplateArg.cc @@ -0,0 +1,57 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "MatchTemplateArg.h" + +bool MatchTemplateArgList::matches (MatchTemplateArgList &sig_mtal) const { + const_iterator iter = begin (); + const_iterator sig_iter = sig_mtal.begin (); + while (iter != end ()) { + // check if the current template match arg is '...' + if ((*iter)->is_ellipses ()) + return true; + // check if we have more match arguments than template arguments + if (sig_iter == sig_mtal.end ()) + return false; + // check if the current match argument matches the template argument + else if (!(*iter)->matches (*(*sig_iter))) + return false; + // go to the next argument + ++iter; + ++sig_iter; + } + // check if we have examined all deduced template arguments + if (sig_iter != sig_mtal.end ()) + return false; + + // everything fine, the list matches! + return true; +} + +bool MTA_Type::matches (MatchTemplateArg &arg) const { + return arg.is_type () && _match_type.matches (((MTA_Type&)arg)._match_type); +} + +bool MTA_Value::matches (MatchTemplateArg &arg) const { + return arg.is_value () && _val == ((MTA_Value&)arg)._val; +} + +bool MTA_Addr::matches (MatchTemplateArg &arg) const { + // TODO: const correctness -> don't cast _name here!!! + return arg.is_addr() && ((MatchName&)_name).matches (((MTA_Addr&)arg)._name); +} diff --git a/AspectC++/ACModel/MatchTemplateArg.h b/AspectC++/ACModel/MatchTemplateArg.h new file mode 100644 index 0000000..3b4f6e5 --- /dev/null +++ b/AspectC++/ACModel/MatchTemplateArg.h @@ -0,0 +1,163 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __MatchTemplateArg_h__ +#define __MatchTemplateArg_h__ + +#include +using std::list; + +#include "MatchType.h" +#include "MatchName.h" + +// Common interface for all class that represent match expressions +// for template arguments. + +class MatchTemplateArg { +public: + virtual ~MatchTemplateArg () {} + virtual void print (ostream &out) const = 0; + virtual void mangle (ostream &out) const = 0; + virtual bool matches (MatchTemplateArg &arg) const = 0; + virtual MatchTemplateArg *clone () const = 0; + virtual bool is_any () const { return false; } + virtual bool is_ellipses () const { return false; } + virtual bool is_type () const { return false; } + virtual bool is_value () const { return false; } + virtual bool is_addr () const { return false; } +}; + +// streamed output for template argument match expressions +inline ostream &operator << (ostream &out, const MatchTemplateArg &mta) { + mta.print (out); + return out; +} + + +// A list of template argument match expressions +class MatchTemplateArgList : private list { +public: + MatchTemplateArgList () {} + ~MatchTemplateArgList () { + for (iterator iter = begin (); iter != end (); ++iter) + delete *iter; + } + MatchTemplateArgList (const MatchTemplateArgList& mtal) { *this = mtal; } + MatchTemplateArgList &operator = (const MatchTemplateArgList& mtal) { + for (const_iterator iter = mtal.begin (); iter != mtal.end (); ++iter) + append ((*iter)->clone ()); + return *this; + } + void append (MatchTemplateArg *mta) { push_back (mta); } + void print (ostream &out) const { + out << "<"; + bool first = true; + for (const_iterator iter = begin (); iter != end (); ++iter) { + if (first) + first = false; + else + out << ","; + out << **iter; + } + out << ">"; + } + void mangle (ostream &os) const { + os << "I"; + for (const_iterator iter = begin (); iter != end (); ++iter) + (*iter)->mangle (os); + os << "E"; + } + bool matches (MatchTemplateArgList &mtal) const; +}; + +inline ostream &operator << (ostream &out, const MatchTemplateArgList &mtal) { + mtal.print (out); + return out; +} + + +// Template argument match expression that matches any template argument +class MTA_Any : public MatchTemplateArg { +public: + void print (ostream &out) const { out << "%"; } + void mangle (ostream &out) const { out << "_X_"; } + bool matches (MatchTemplateArg &arg) const { return true; } + MTA_Any *clone () const { return new MTA_Any (*this); } + bool is_any () const { return true; } +}; + + +// Template argument match expression that matches any number of +// arbitrary template argument +class MTA_Ellipses : public MatchTemplateArg { +public: + void print (ostream &out) const { out << "..."; } + void mangle (ostream &out) const {} + // TODO: not correct + bool matches (MatchTemplateArg &arg) const { return true; } + MTA_Ellipses *clone () const { return new MTA_Ellipses (*this); } + bool is_ellipses () const { return true; } +}; + + +// This class represents match expressions for types in template +// argument lists. +class MTA_Type : public MatchTemplateArg { + MatchTypeRef _match_type; +public: + MTA_Type (const MatchTypeRef mt) : _match_type (mt) {} + void print (ostream &out) const { out << _match_type; } + void mangle (ostream &out) const { _match_type.mangle (out); } + bool matches (MatchTemplateArg &arg) const; + MTA_Type *clone () const { return new MTA_Type (*this); } + bool is_type () const { return true; } +}; + + +// This class represents match expressions for value template arguments. +class MTA_Value : public MatchTemplateArg { + long long _val; +public: + MTA_Value (long long val) : _val (val) {} + void print (ostream &out) const { out << _val; } + void mangle (ostream &out) const { + if (_val < 0) + out << "n" << -_val; + else + out << _val; + } + bool matches (MatchTemplateArg &arg) const; + MTA_Value *clone () const { return new MTA_Value (*this); } + bool is_value () const { return true; } +}; + +// This class represents match expressions for value template arguments. +class MTA_Addr : public MatchTemplateArg { + MatchName _name; +public: + MTA_Addr (const MatchName &name) : _name (name) {} + void print (ostream &out) const { out << "&" << _name; } + // TODO: name mangling not correct, e.g. "_Z" missing for functions + void mangle (ostream &out) const { out << "L"; _name.mangle (out); out << "E"; } +// bool matches (DeducedArgument *arg) const; + bool matches (MatchTemplateArg &arg) const; + MTA_Addr *clone () const { return new MTA_Addr (*this); } + bool is_addr () const { return true; } +}; + +#endif // __MatchTemplateArg_h__ diff --git a/AspectC++/ACModel/MatchType.cc b/AspectC++/ACModel/MatchType.cc new file mode 100644 index 0000000..1d1b958 --- /dev/null +++ b/AspectC++/ACModel/MatchType.cc @@ -0,0 +1,78 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "MatchTypeInfos.h" + +// MatchType default constructor +MatchTypeRef::MatchTypeRef () { _type_info = new MTUndefined; } + +// functions used to instantiate built-in primitive types +MatchTypeRef MatchTypeRef::make_any () { return new MTAny; } +MatchTypeRef MatchTypeRef::make_void () { return new MTVoid; } +MatchTypeRef MatchTypeRef::make_bool () { return new MTBool; } +MatchTypeRef MatchTypeRef::make_signed_char () { return new MTSignedChar; } +MatchTypeRef MatchTypeRef::make_unsigned_char () { return new MTUnsignedChar; } +MatchTypeRef MatchTypeRef::make_char () { return new MTChar; } +MatchTypeRef MatchTypeRef::make_wchar_t () { return new MTWCharT; } +MatchTypeRef MatchTypeRef::make_unsigned_short () { return new MTUnsignedShort; } +MatchTypeRef MatchTypeRef::make_short () { return new MTShort; } +MatchTypeRef MatchTypeRef::make_unsigned_int () { return new MTUnsignedInt; } +MatchTypeRef MatchTypeRef::make_int () { return new MTInt; } +MatchTypeRef MatchTypeRef::make_unsigned_long () { return new MTUnsignedLong; } +MatchTypeRef MatchTypeRef::make_long () { return new MTLong; } +MatchTypeRef MatchTypeRef::make_unsigned_long_long () { return new MTUnsignedLongLong; } +MatchTypeRef MatchTypeRef::make_long_long () { return new MTLongLong; } +MatchTypeRef MatchTypeRef::make_unsigned_int128 () { return new MTUnsignedInt128; } +MatchTypeRef MatchTypeRef::make_int128 () { return new MTInt128; } +MatchTypeRef MatchTypeRef::make_float () { return new MTFloat; } +MatchTypeRef MatchTypeRef::make_double () { return new MTDouble; } +MatchTypeRef MatchTypeRef::make_long_double () { return new MTLongDouble; } + +// function used to instantiate a new named type +MatchTypeRef MatchTypeRef::make_named (const MatchName &mn) { + return new MTNamed (mn); +} + +// functions to construct complex types from built-in or named types +void MatchTypeRef::to_pointer () { + _type_info = new MTPointer (_type_info); +} + +void MatchTypeRef::to_memb_pointer (const MatchName &mn) { + _type_info = new MTMembPointer (mn, _type_info); +} + +void MatchTypeRef::to_reference () { + _type_info = new MTReference (_type_info); +} + +void MatchTypeRef::to_function (const vector &args, bool va) { + _type_info = new MTFunction (args, va, _type_info); +} + +void MatchTypeRef::to_array (unsigned long dim) { + _type_info = new MTArray (dim, _type_info); +} + +void MatchTypeRef::to_array () { + _type_info = new MTArray (_type_info); +} + +const MatchName &MatchTypeRef::name () const { + return ((MTNamed*)_type_info)->name(); +} diff --git a/AspectC++/ACModel/MatchType.h b/AspectC++/ACModel/MatchType.h new file mode 100644 index 0000000..792213a --- /dev/null +++ b/AspectC++/ACModel/MatchType.h @@ -0,0 +1,220 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __MatchType_h__ +#define __MatchType_h__ + +#include +using std::ostream; +using std::endl; +#include +using std::vector; + +class MatchName; // ugly cyclic relationship needed for conv type names + +// common base class for all qualified types + +class MTQual { + bool _const; + bool _volatile; + +public: + MTQual () : _const (false), _volatile (false) {} + + void qualify_const () { _const = true; } + void qualify_volatile () { _volatile = true; } + void unqualify () { _const = false; _volatile = false; } + bool is_const () const { return _const; } + bool is_volatile () const { return _volatile; } + bool is_qualified () const { return _const || _volatile; } + + // print the string representation of this type + void print_qual (ostream &) const; + + // print the 'mangled' string representation of this type + void mangle (ostream &) const; + + // perform a type match + bool qual_matches (const MTQual *qual) const; +}; + +// this is a common base class for all nodes in a tree that represents +// a match pattern for a type. Despite normal type nodes this tree might +// also contain wildcards. + +class MatchType { + +protected: + + // an id for the different kinds of types + typedef const char *TID; + + // get the kind of type, e.g. bool, int, etc. + virtual TID type () const = 0; + +public: + // virtual destructor + virtual ~MatchType () {} + + // is it the same kind of type? + virtual bool operator ==(const MatchType &) const; + inline bool operator !=(const MatchType &t) const { return !(*this == t); } + + //! print the string representation of this type + virtual void print (ostream &, const char* = 0, bool = false) const = 0; + + // print the 'mangled' string representation of this type + virtual void mangle (ostream &os) const { os << "X"; } + + //! check whether this is a function type + virtual bool is_function () const { return false; } + //! check whether this is an array type + virtual bool is_array () const { return false; } + //! check whether this type is 'void' + virtual bool is_void () const { return false; } + //! check whether this type is primitive + virtual bool is_primitive () const { return false; } + //! check whether this type is a reference + virtual bool is_reference () const { return false; } + + //! create a clone of this match type + virtual MatchType *clone () const = 0; + + //! get the base type if this is a derived type + virtual MatchType *base () const { return 0; } + + // perform a type match + virtual bool matches (const MatchType &type) const = 0; + + // check whether this type mattern can only match a single name type + virtual bool is_trivial_match () const { return false; } + + // adjust the argument types according to �8.3.5.2 and �8.3.5.3 of ISO C++ + virtual void adjust_args (bool &f, bool &a, bool &q, bool &v) {} + + // converts the type into an MTQual if it is one + virtual MTQual *qualified () { return 0; } + virtual const MTQual *qualified () const { return 0; } +}; + +// should later become "MatchType" +class MatchTypeRef { + MatchType *_type_info; +private: + // only members of this class can create instances without clear() + MatchTypeRef (MatchType *t) : _type_info (t) {} +public: + MatchTypeRef (); + MatchTypeRef (const MatchTypeRef ©) { + _type_info = copy._type_info->clone(); + } + MatchTypeRef &operator = (const MatchTypeRef ©) { + clear (); + _type_info = copy._type_info->clone(); + return *this; + } + ~MatchTypeRef () { clear (); } + void clear () { delete _type_info; } + MatchType *type_info () const { return _type_info; } + + // functions used to instantiate built-in primitive types + static MatchTypeRef make_any (); + static MatchTypeRef make_void (); + static MatchTypeRef make_bool (); + static MatchTypeRef make_signed_char (); + static MatchTypeRef make_unsigned_char (); + static MatchTypeRef make_char (); + static MatchTypeRef make_wchar_t (); + static MatchTypeRef make_unsigned_short (); + static MatchTypeRef make_short (); + static MatchTypeRef make_unsigned_int (); + static MatchTypeRef make_int (); + static MatchTypeRef make_unsigned_long (); + static MatchTypeRef make_long (); + static MatchTypeRef make_unsigned_long_long (); + static MatchTypeRef make_long_long (); + static MatchTypeRef make_unsigned_int128 (); + static MatchTypeRef make_int128 (); + static MatchTypeRef make_float (); + static MatchTypeRef make_double (); + static MatchTypeRef make_long_double (); + + // function used to instantiate a new named type + static MatchTypeRef make_named (const MatchName &mn); + + // functions to construct complex types from built-in or named types + void to_pointer (); + void to_memb_pointer (const MatchName &mps); + void to_reference (); + void to_function (const vector &args, bool var_args); + void to_array (unsigned long dim); + void to_array (); + + // common type interface + + // perform a type match + bool matches (MatchTypeRef type) const { + return _type_info->matches (*type.type_info ()); + } + + // adjust the argument types according to �8.3.5.2 and �8.3.5.3 of ISO C++ + void adjust_args (bool &f, bool &a, bool &q, bool &v) { + _type_info->adjust_args (f, a, q, v); + } + + // print the string representation of this type + void print (ostream &os, const char *prefix = 0) const { + _type_info->print (os, prefix); + } + + // print the 'mangled' string representation of this type + void mangle (ostream &os) const { + _type_info->mangle(os); + } + + // check and get specific properties of this type + + bool is_undefined () const { + return *type_info () == *MatchTypeRef ()._type_info; + } + bool is_qualifiable () const { return _type_info->qualified (); } + MTQual &qualifiers () const { return *_type_info->qualified (); } + + bool is_function () const { return _type_info->is_function (); } + bool is_array () const { return _type_info->is_array (); } + bool is_void () const { return _type_info->is_void(); } + bool is_primitive () const { return _type_info->is_primitive(); } + bool is_reference () const { return _type_info->is_reference(); } + + MatchTypeRef base () const { + MatchType *b = _type_info->base (); + return b ? MatchTypeRef (b->clone ()) : MatchTypeRef (); + } + + // check whether this type mattern can only match a single name type + bool is_trivial_match () const { return _type_info->is_trivial_match(); } + // get the associated name object + const MatchName &name () const; +}; + +inline ostream &operator << (ostream &out, const MatchTypeRef &mt) { + mt.print (out); + return out; +} + +#endif // __MatchType_h__ diff --git a/AspectC++/ACModel/MatchTypeInfos.cc b/AspectC++/ACModel/MatchTypeInfos.cc new file mode 100644 index 0000000..e121016 --- /dev/null +++ b/AspectC++/ACModel/MatchTypeInfos.cc @@ -0,0 +1,710 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 +using std::string; +#include +using std::ostringstream; + +#include "MatchTypeInfos.h" + +// comparison functions + +// is it the same kind of type? +bool MatchType::operator ==(const MatchType &other) const { + // by default two types are equal if they have the same ID + return type () == other.type (); +} + +MTUndefined *MTUndefined::clone () const { + return new MTUndefined(*this); +} + +void MTUndefined::print (ostream &out, const char *inner, bool prefix) const { + out << ""; + if (inner) + out << " " << inner; +} + +bool MTUndefined::matches (const MatchType &type) const { + // conversion operator might have an undefined result type + return type == *this; // true if both object types are equal +} + +// print the string representation of this qualified type +void MTQual::print_qual (ostream &out) const { + if (_const) out << "const"; + if (_const && _volatile) out << " "; + if (_volatile) out << "volatile"; +} + +// perform a type match +// if a type is qualified as const/volatile in a match expression, it does +// only match types which are qualified like this. However, according to +// the AspectC++ semantics a type is also matched if it is const/volatile, +// but the match expression does not require this qualifier. +bool MTQual::qual_matches (const MTQual *qual) const { + if (!qual && is_qualified ()) + return false; + if (qual) { + if (_const && !qual->is_const ()) + return false; + if (_volatile && !qual->is_volatile ()) + return false; + } + return true; +} + +// print the 'mangled' string representation of this type +void MTQual::mangle (ostream &os) const { + if (_const) + os << "K"; + if (_volatile) + os << "V"; +} + +// print the string representation of this primitive type +// inner might be a name, prefix == true means that the name has prefix +void MTPrim::print (ostream &out, const char *inner, bool prefix) const { + if (is_qualified ()) { + print_qual (out); + out << " "; + } + out << type (); + if (inner) + out << " " << inner; +} + +// print the 'mangled' string representation of this type +void MTPrim::mangle (ostream &os) const { + MTQual::mangle (os); + // default mangling: + string name (type ()); + os << name.length() << name; +} + +MTNamed *MTNamed::clone () const { + return new MTNamed (*this); +} + +// print the string representation of this names type +// inner might be a name, prefix == true means that the name has prefix +void MTNamed::print (ostream &out, const char *inner, bool prefix) const { + if (is_qualified ()) { + print_qual (out); + out << " "; + } + out << _name; + if (inner) + out << " " << inner; +} + +// print the 'mangled' string representation of this type +void MTNamed::mangle (ostream &os) const { + MTQual::mangle (os); + _name.mangle (os); +} + +bool MTNamed::matches (const MatchType &type) const { + if (type != *this) + return false; + MTNamed &matched_type = (MTNamed&)type; + return _name.matches (matched_type._name) && + qual_matches (matched_type.qualified ()); +} + + +MTPointer *MTPointer::clone () const { + return new MTPointer (*this); +} + +// print the string represenation of this pointer type +// inner might be a name, prefix == true means that the name has prefix +void MTPointer::print (ostream &out, const char *inner, bool prefix) const { + ostringstream declarator; + declarator << "*"; + if (is_qualified ()) { + declarator << " "; + print_qual (declarator); + declarator << " "; + } + if (inner) + declarator << inner; + if (base ()) + base ()->print (out, declarator.str ().c_str (), true); + else + out << " " << declarator.str (); +} + +// print the 'mangled' string representation of this type +void MTPointer::mangle (ostream &os) const { + MTQual::mangle (os); + os << "P"; + if (base ()) + base()->mangle(os); +} + +bool MTPointer::matches (const MatchType &type) const { + if (type != *this) + return false; + MTPointer &matched_type = (MTPointer&)type; + return base ()->matches (*matched_type.base ()) && + qual_matches (matched_type.qualified ()); +} + + +MTMembPointer *MTMembPointer::clone () const { + return new MTMembPointer (*this); +} + +// print the string represenation of this pointer type +// inner might be a name, prefix == true means that the name has prefix +void MTMembPointer::print (ostream &out, const char *inner, bool prefix) const { + ostringstream declarator; + declarator << _memb_ptr_scope << "*"; + if (is_qualified ()) { + declarator << " "; + print_qual (declarator); + declarator << " "; + } + if (inner) + declarator << inner; + if (base ()) + base ()->print (out, declarator.str ().c_str (), true); + else + out << " " << declarator.str (); +} + +// print the 'mangled' string representation of this type +void MTMembPointer::mangle (ostream &os) const { + MTQual::mangle (os); + os << "M"; + _memb_ptr_scope.mangle (os); + if (base ()) + base()->mangle(os); +} + +bool MTMembPointer::matches (const MatchType &type) const { + if (type != *this) + return false; + MTMembPointer &matched_type = (MTMembPointer&)type; + return base ()->matches (*matched_type.base ()) && + qual_matches (matched_type.qualified ()) && + _memb_ptr_scope.matches (matched_type._memb_ptr_scope); +} + +MTReference *MTReference::clone () const { + return new MTReference (*this); +} + +// print the string represenation of this reference type +// inner might be a name, prefix == true means that the name has prefix +void MTReference::print (ostream &out, const char *inner, bool prefix) const { + ostringstream declarator; + declarator << "&"; + if (inner) + declarator << inner; + if (base ()) + base ()->print (out, declarator.str ().c_str (), true); + else + out << " " << declarator.str (); +} + +// print the 'mangled' string representation of this type +void MTReference::mangle (ostream &os) const { + os << "R"; + if (base ()) + base()->mangle(os); +} + +bool MTReference::matches (const MatchType &type) const { + return type == *this && base ()->matches (*type.base ()); +} + +//MTFunction::~MTFunction () { +// for (int a = 0; a < args (); a++) +// delete arg (a); +//} + +MTFunction *MTFunction::clone () const { + return new MTFunction (*this); +} + +// print the string represenation of this function type +// inner might be a name, prefix == true means that the name has prefix +void MTFunction::print (ostream &out, const char *inner, bool prefix) const { + ostringstream declarator; + if (inner) + declarator << (prefix ? "(" : "") << inner << (prefix ? ")" : ""); + declarator << "("; + int a = 0; + while (a < args ()) { + if (a > 0) declarator << ","; + arg (a).type_info ()->print (declarator); + a++; + } + if (_varargs) declarator << (a > 0 ? "," : "") << "..."; + declarator << ")"; + if (is_qualified ()) { + declarator << " "; + print_qual (declarator); + declarator << " "; + } + if (base ()) + base ()->print (out, declarator.str ().c_str (), false); + else + out << " " << declarator.str (); +} + +// print the 'mangled' string representation of this type +void MTFunction::mangle (ostream &os) const { + os << "F"; + // TODO: what about the scope here? Puma prints it. + if (base ()) + base ()->mangle (os); + if (!_varargs && args () > 0) { + for (int a = 0; a < args (); ++a) + arg(a).type_info()->mangle (os); + } + else + os << "v"; + os << "E"; +} + +// perform a type match +bool MTFunction::matches (const MatchType &type) const { + // check if it's a function type + if (type != *this) + return false; + const MTFunction &matched_type = (MTFunction&)type; + // check the type qualifier + if (!qual_matches (matched_type.qualified ())) + return false; + // check the argument types + int matched_args = matched_type.args (); + // TODO: what about matched functions with varargs? + if ((!_varargs && args () != matched_args) || (args () > matched_args)) + return false; + for (int a = 0; a < args (); a++) + if (!arg (a).matches (matched_type.arg (a))) + return false; + // finally check the result type + return base ()->matches (*matched_type.base ()); +} + +// adjust the argument types according to �8.3.5.2 and �8.3.5.3 of ISO C++ +void MTFunction::adjust_args (bool &f, bool &a, bool &q, bool &v) { + // adjust all argument types according to ISO C++ + for (int i = 0; i < args (); i++) { + MatchType *curr = _arg_types[i].type_info (); + + // recursively adjust the argument + curr->adjust_args (f, a , q, v); + + // type `function returning T' is adjusted to be + // `pointer to function returning T' + if (_arg_types[i].is_function ()) { + f = true; + _arg_types[i].to_pointer (); + continue; + } + + // type `array of T' is adjusted to be `pointer to T' + if (_arg_types[i].is_array ()) { + a = true; + MatchTypeRef converted_type = _arg_types[i].base (); + converted_type.to_pointer(); + _arg_types[i] = converted_type; + continue; + } + + // any cv-qualifier modifying a parameter is deleted + if (_arg_types[i].is_qualifiable () && + _arg_types[i].qualifiers ().is_qualified ()) { + q = true; + _arg_types[i].qualifiers ().unqualify (); + } + } + + // �8.3.5.2 the parameter list `(void)' is equivalent to + // the empty parameter list + if (args () == 1 && _arg_types[0].is_void ()) { + v = true; + _arg_types.clear (); + } +} + +MTArray *MTArray::clone () const { + return new MTArray (*this); +} + +// print the string represenation of this array type +// inner might be a name, prefix == true means that the name has prefix +void MTArray::print (ostream &out, const char *inner, bool prefix) const { + ostringstream declarator; + if (inner) + declarator << (prefix ? "(" : "") << inner << (prefix ? ")" : ""); + declarator << "["; + if (_any_size) + declarator << "%"; + else + declarator << _dim; + declarator << "]"; + if (base ()) + base ()->print (out, declarator.str ().c_str (), false); + else + out << " " << declarator.str (); +} + +// print the 'mangled' string representation of this type +void MTArray::mangle (ostream &os) const { + os << "A"; + if (!_any_size) + os << dimension(); + os << "_"; + if (base ()) + base ()->mangle (os); +} + +// perform a type match +bool MTArray::matches (const MatchType &type) const { + if (type != *this) + return false; + MTArray &matched_type = (MTArray&)type; + return base ()->matches (*matched_type.base ()) && + (_any_size || _dim == matched_type._dim); +} + +MTAny *MTAny::clone () const { + return new MTAny (*this); +} +// perform a type match +bool MTAny::matches (const MatchType &type) const { + return qual_matches (type.qualified ()); +} +// print the 'mangled' string representation of this type +void MTAny::mangle (ostream &os) const { + MTQual::mangle (os); + os << "3Any"; +} + +MTBool *MTBool::clone () const { + return new MTBool (*this); +} + +// perform a type match +bool MTBool::matches (const MatchType &type) const { + return type == *this && qual_matches (type.qualified ()); +} +// print the 'mangled' string representation of this type +void MTBool::mangle (ostream &os) const { + MTQual::mangle (os); + os << "b"; +} + +MTSignedChar *MTSignedChar::clone () const { + return new MTSignedChar (*this); +} +// perform a type match +bool MTSignedChar::matches (const MatchType &type) const { + return type == *this && qual_matches (type.qualified ()); +} +// print the 'mangled' string representation of this type +void MTSignedChar::mangle (ostream &os) const { + MTQual::mangle (os); + os << "a"; +} + +MTUnsignedChar *MTUnsignedChar::clone () const { + return new MTUnsignedChar (*this); +} +// perform a type match +bool MTUnsignedChar::matches (const MatchType &type) const { + return type == *this && qual_matches (type.qualified ()); +} +// print the 'mangled' string representation of this type +void MTUnsignedChar::mangle (ostream &os) const { + MTQual::mangle (os); + os << "h"; +} + +MTChar *MTChar::clone () const { + return new MTChar (*this); +} +// perform a type match +bool MTChar::matches (const MatchType &type) const { + return type == *this && qual_matches (type.qualified ()); +} +// print the 'mangled' string representation of this type +void MTChar::mangle (ostream &os) const { + MTQual::mangle (os); + os << "c"; +} + +MTUnsignedShort *MTUnsignedShort::clone () const { + return new MTUnsignedShort (*this); +} +// perform a type match +bool MTUnsignedShort::matches (const MatchType &type) const { + return type == *this && qual_matches (type.qualified ()); +} +// print the 'mangled' string representation of this type +void MTUnsignedShort::mangle (ostream &os) const { + MTQual::mangle (os); + os << "t"; +} + +MTShort *MTShort::clone () const { + return new MTShort (*this); +} +// perform a type match +bool MTShort::matches (const MatchType &type) const { + return type == *this && qual_matches (type.qualified ()); +} +// print the 'mangled' string representation of this type +void MTShort::mangle (ostream &os) const { + MTQual::mangle (os); + os << "s"; +} + +MTUnsignedInt *MTUnsignedInt::clone () const { + return new MTUnsignedInt (*this); +} +// perform a type match +bool MTUnsignedInt::matches (const MatchType &type) const { + return type == *this && qual_matches (type.qualified ()); +} +// print the 'mangled' string representation of this type +void MTUnsignedInt::mangle (ostream &os) const { + MTQual::mangle (os); + os << "j"; +} + +MTInt *MTInt::clone () const { + return new MTInt (*this); +} +// perform a type match +bool MTInt::matches (const MatchType &type) const { + return type == *this && qual_matches (type.qualified ()); +} +// print the 'mangled' string representation of this type +void MTInt::mangle (ostream &os) const { + MTQual::mangle (os); + os << "i"; +} + +MTWCharT *MTWCharT::clone () const { + return new MTWCharT (*this); +} +// perform a type match +bool MTWCharT::matches (const MatchType &type) const { + return type == *this && qual_matches (type.qualified ()); +} +// print the 'mangled' string representation of this type +void MTWCharT::mangle (ostream &os) const { + MTQual::mangle (os); + os << "w"; +} + +MTUnsignedLong *MTUnsignedLong::clone () const { + return new MTUnsignedLong (*this); +} +// perform a type match +bool MTUnsignedLong::matches (const MatchType &type) const { + return type == *this && qual_matches (type.qualified ()); +} +// print the 'mangled' string representation of this type +void MTUnsignedLong::mangle (ostream &os) const { + MTQual::mangle (os); + os << "m"; +} + +MTLong *MTLong::clone () const { + return new MTLong (*this); +} +// perform a type match +bool MTLong::matches (const MatchType &type) const { + return type == *this && qual_matches (type.qualified ()); +} +// print the 'mangled' string representation of this type +void MTLong::mangle (ostream &os) const { + MTQual::mangle (os); + os << "l"; +} + +MTUnsignedLongLong *MTUnsignedLongLong::clone () const { + return new MTUnsignedLongLong (*this); +} +// perform a type match +bool MTUnsignedLongLong::matches (const MatchType &type) const { + return type == *this && qual_matches (type.qualified ()); +} +// print the 'mangled' string representation of this type +void MTUnsignedLongLong::mangle (ostream &os) const { + MTQual::mangle (os); + os << "y"; +} + +MTLongLong *MTLongLong::clone () const { + return new MTLongLong (*this); +} +// perform a type match +bool MTLongLong::matches (const MatchType &type) const { + return type == *this && qual_matches (type.qualified ()); +} +// print the 'mangled' string representation of this type +void MTLongLong::mangle (ostream &os) const { + MTQual::mangle (os); + os << "x"; +} + +MTUnsignedInt128 *MTUnsignedInt128::clone () const { + return new MTUnsignedInt128 (*this); +} +// perform a type match +bool MTUnsignedInt128::matches (const MatchType &type) const { + return type == *this && qual_matches (type.qualified ()); +} +// print the 'mangled' string representation of this type +void MTUnsignedInt128::mangle (ostream &os) const { + MTQual::mangle (os); + os << "o"; +} + +MTInt128 *MTInt128::clone () const { + return new MTInt128 (*this); +} +// perform a type match +bool MTInt128::matches (const MatchType &type) const { + return type == *this && qual_matches (type.qualified ()); +} +// print the 'mangled' string representation of this type +void MTInt128::mangle (ostream &os) const { + MTQual::mangle (os); + os << "n"; +} + +MTFloat *MTFloat::clone () const { + return new MTFloat (*this); +} +// perform a type match +bool MTFloat::matches (const MatchType &type) const { + return type == *this && qual_matches (type.qualified ()); +} +// print the 'mangled' string representation of this type +void MTFloat::mangle (ostream &os) const { + MTQual::mangle (os); + os << "f"; +} + +MTDouble *MTDouble::clone () const { + return new MTDouble (*this); +} +// perform a type match +bool MTDouble::matches (const MatchType &type) const { + return type == *this && qual_matches (type.qualified ()); +} +// print the 'mangled' string representation of this type +void MTDouble::mangle (ostream &os) const { + MTQual::mangle (os); + os << "d"; +} + +MTLongDouble *MTLongDouble::clone () const { + return new MTLongDouble (*this); +} +// perform a type match +bool MTLongDouble::matches (const MatchType &type) const { + return type == *this && qual_matches (type.qualified ()); +} +// print the 'mangled' string representation of this type +void MTLongDouble::mangle (ostream &os) const { + MTQual::mangle (os); + os << "e"; +} + +MTVoid *MTVoid::clone () const { + return new MTVoid (*this); +} +// perform a type match +bool MTVoid::matches (const MatchType &type) const { + return type == *this && qual_matches (type.qualified ()); +} +// print the 'mangled' string representation of this type +void MTVoid::mangle (ostream &os) const { + MTQual::mangle (os); + os << "v"; +} + +// type ids +MatchType::TID MTUndefined::_tid = ""; +MatchType::TID MTUndefined::type () const { return _tid; } +MatchType::TID MTDeclarator::_tid = ""; +MatchType::TID MTDeclarator::type () const { return _tid; } +MatchType::TID MTReference::_tid = "&"; +MatchType::TID MTReference::type () const { return _tid; } +MatchType::TID MTPointer::_tid = "*"; +MatchType::TID MTPointer::type () const { return _tid; } +MatchType::TID MTMembPointer::_tid = "::*"; +MatchType::TID MTMembPointer::type () const { return _tid; } +MatchType::TID MTFunction::_tid = "()"; +MatchType::TID MTFunction::type () const { return _tid; } +MatchType::TID MTArray::_tid = "[]"; +MatchType::TID MTArray::type () const { return _tid; } +MatchType::TID MTAny::_tid = "%"; +MatchType::TID MTAny::type () const { return _tid; } +MatchType::TID MTNamed::_tid = ""; +MatchType::TID MTNamed::type () const { return _tid; } +MatchType::TID MTBool::_tid = "bool"; +MatchType::TID MTBool::type () const { return _tid; } +MatchType::TID MTSignedChar::_tid = "signed char"; +MatchType::TID MTSignedChar::type () const { return _tid; } +MatchType::TID MTUnsignedChar::_tid = "unsigned char"; +MatchType::TID MTUnsignedChar::type () const { return _tid; } +MatchType::TID MTChar::_tid = "char"; +MatchType::TID MTChar::type () const { return _tid; } +MatchType::TID MTUnsignedShort::_tid = "unsigned short"; +MatchType::TID MTUnsignedShort::type () const { return _tid; } +MatchType::TID MTShort::_tid = "short"; +MatchType::TID MTShort::type () const { return _tid; } +MatchType::TID MTUnsignedInt::_tid = "unsigned int"; +MatchType::TID MTUnsignedInt::type () const { return _tid; } +MatchType::TID MTInt::_tid = "int"; +MatchType::TID MTInt::type () const { return _tid; } +MatchType::TID MTWCharT::_tid = "wchar_t"; +MatchType::TID MTWCharT::type () const { return _tid; } +MatchType::TID MTUnsignedLong::_tid = "unsigned long"; +MatchType::TID MTUnsignedLong::type () const { return _tid; } +MatchType::TID MTLong::_tid = "long"; +MatchType::TID MTLong::type () const { return _tid; } +MatchType::TID MTUnsignedLongLong::_tid = "unsigned long long"; +MatchType::TID MTUnsignedLongLong::type () const { return _tid; } +MatchType::TID MTLongLong::_tid = "long long"; +MatchType::TID MTLongLong::type () const { return _tid; } +MatchType::TID MTUnsignedInt128::_tid = "unsigned __int128"; +MatchType::TID MTUnsignedInt128::type () const { return _tid; } +MatchType::TID MTInt128::_tid = "__int128"; +MatchType::TID MTInt128::type () const { return _tid; } +MatchType::TID MTFloat::_tid = "float"; +MatchType::TID MTFloat::type () const { return _tid; } +MatchType::TID MTDouble::_tid = "double"; +MatchType::TID MTDouble::type () const { return _tid; } +MatchType::TID MTLongDouble::_tid = "long double"; +MatchType::TID MTLongDouble::type () const { return _tid; } +MatchType::TID MTVoid::_tid = "void"; +MatchType::TID MTVoid::type () const { return _tid; } diff --git a/AspectC++/ACModel/MatchTypeInfos.h b/AspectC++/ACModel/MatchTypeInfos.h new file mode 100644 index 0000000..c3d2b11 --- /dev/null +++ b/AspectC++/ACModel/MatchTypeInfos.h @@ -0,0 +1,419 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __MatchTypeInfos_h__ +#define __MatchTypeInfos_h__ + +#include +using std::ostream; +using std::endl; +#include +using std::vector; + +#include "MatchType.h" +#include "MatchName.h" + +// functions without result type (conversion operators) have this type +class MTUndefined : public MatchType { + static TID _tid; + +protected: + virtual TID type () const; +public: + virtual MTUndefined *clone () const; + virtual void print (ostream &, const char* = 0, bool = false) const; + virtual bool matches (const MatchType &type) const; +}; + +// commonalities of all types made by declarators +class MTDeclarator : public MatchType { + MatchType *_base; + static TID _tid; + +protected: + virtual TID type () const; + // only derived types may construct/destruct a declarator type + MTDeclarator (MatchType *b) : _base (b) {} + MTDeclarator (const MTDeclarator ©) { *this = copy; } + MTDeclarator &operator = (const MTDeclarator ©) { + _base = copy._base->clone (); + return *this; + } + ~MTDeclarator () { delete _base; } + +public: + // set and get the base type + virtual MatchType *base () const { return _base; } + // adjust the argument types according to �8.3.5.2 and �8.3.5.3 of ISO C++ + virtual void adjust_args (bool &f, bool &a, bool &q, bool &v) { + _base->adjust_args (f, a, q, v); + } +}; + +// pointer types +class MTPointer : public MTDeclarator, public MTQual { + static TID _tid; + +protected: + virtual TID type () const; + +public: + MTPointer (MatchType *b = 0) : MTDeclarator (b) {} + // print the string representation of this type + virtual MTPointer *clone () const; + virtual void print (ostream &, const char* = 0, bool = false) const; + virtual void mangle (ostream &) const; + virtual bool matches (const MatchType &type) const; + virtual MTQual *qualified () { return this; } + virtual const MTQual *qualified () const { return this; } +}; + +// member pointer types +class MTMembPointer : public MTPointer { + static TID _tid; + mutable MatchName _memb_ptr_scope; + +protected: + virtual TID type () const; + +public: + MTMembPointer (const MatchName &mps, MatchType *b = 0) : + MTPointer (b), _memb_ptr_scope (mps) {} + virtual MTMembPointer *clone () const; + // print the string representation of this type + virtual void print (ostream &, const char* = 0, bool = false) const; + virtual void mangle (ostream &) const; + virtual bool matches (const MatchType &type) const; +}; + + +// reference types +class MTReference : public MTDeclarator { + static TID _tid; + +protected: + virtual TID type () const; + +public: + MTReference (MatchType *b = 0) : MTDeclarator (b) {} + virtual MTReference *clone () const; + // print the string representation of this type + virtual void print (ostream &, const char* = 0, bool = false) const; + virtual void mangle (ostream &) const; + virtual bool matches (const MatchType &type) const; + virtual bool is_reference () const { return true; } +}; + +// function types +class MTFunction : public MTDeclarator, public MTQual { + static TID _tid; + vector _arg_types; + bool _varargs; + +protected: + virtual TID type () const; + +public: + MTFunction (MatchType *b = 0) : MTDeclarator (b), _varargs (false) {} + MTFunction (const vector &args, bool va, MatchType *b) : + MTDeclarator (b), _arg_types (args), _varargs (va) {} +// virtual ~MTFunction (); + virtual MTFunction *clone () const; + // print the string representation of this type + virtual void print (ostream &, const char* = 0, bool = false) const; + // print the 'mangled' string representation of this type + virtual void mangle (ostream &os) const; + virtual bool is_function () const { return true; } + void varargs () { _varargs = true; } + bool varargs () const { return _varargs; } + int args () const { return (int)_arg_types.size (); } + void arg (MatchTypeRef a) { _arg_types.push_back (a); } + const MatchTypeRef &arg (int index) const { return _arg_types[index]; } + // perform a type match + virtual bool matches (const MatchType &type) const; + // adjust the argument types according to �8.3.5.2 and �8.3.5.3 of ISO C++ + virtual void adjust_args (bool &f, bool &a, bool &q, bool &v); + virtual MTQual *qualified () { return this; } + virtual const MTQual *qualified () const { return this; } +}; + +// array types +class MTArray : public MTDeclarator { + static TID _tid; + unsigned long _dim; + bool _any_size; + +protected: + virtual TID type () const; + +public: + MTArray (MatchType *b) : MTDeclarator (b), _dim (0uL), + _any_size (true) {} + MTArray (unsigned long dim, MatchType *b) : MTDeclarator (b), _dim (dim), + _any_size (false) {} + virtual MTArray *clone () const; + // print the string representation of this type + virtual void print (ostream &, const char* = 0, bool = false) const; + // print the 'mangled' string representation of this type + virtual void mangle (ostream &os) const; + void dimension (unsigned long d) { _dim = d; } + unsigned long dimension () const { return _dim; } + void any_size () { _any_size = true; } + bool any_size () const { return _any_size; } + virtual bool matches (const MatchType &type) const; + virtual bool is_array () const { return true; } +}; + +// user-defined names types +class MTNamed : public MatchType, public MTQual { + mutable MatchName _name; + static TID _tid; +protected: + virtual TID type () const; +public: + MTNamed (const MatchName &mn) : _name (mn) {} + virtual MTNamed *clone () const; + // print the string representation of this type + virtual void print (ostream &, const char* = 0, bool = false) const; + // print the 'mangled' string representation of this type + virtual void mangle (ostream &os) const; + const MatchName &name () const { return _name; } + // perform a type match + virtual bool matches (const MatchType &type) const; + virtual MTQual *qualified () { return this; } + virtual const MTQual *qualified () const { return this; } + // check whether this type mattern can only match a single name type + virtual bool is_trivial_match () const { return _name.is_trivial(); } +}; + +//! commonalities of all primitive types +class MTPrim : public MatchType, public MTQual { +public: + //! print the string representation of this type + virtual void print (ostream &, const char* = 0, bool = false) const; + virtual MTQual *qualified () { return this; } + virtual const MTQual *qualified () const { return this; } + virtual bool is_primitive () const { return true; } + // print the 'mangled' string representation of this type + virtual void mangle (ostream &os) const; +}; + +// type (used for matching types> +class MTAny : public MTPrim { + static TID _tid; +protected: + virtual TID type () const; +public: + virtual MTAny *clone () const; + // perform a type match + virtual bool matches (const MatchType &type) const; + virtual void mangle (ostream &os) const; +}; + +// type bool +class MTBool : public MTPrim { + static TID _tid; +protected: + virtual MTBool *clone () const; + virtual TID type () const; + virtual bool matches (const MatchType &type) const; + virtual void mangle (ostream &os) const; +}; + +// type signed char +class MTSignedChar : public MTPrim { + static TID _tid; +protected: + virtual MTSignedChar *clone () const; + virtual TID type () const; + virtual bool matches (const MatchType &type) const; + virtual void mangle (ostream &os) const; +}; + +// type ungined char +class MTUnsignedChar : public MTPrim { + static TID _tid; +protected: + virtual MTUnsignedChar *clone () const; + virtual TID type () const; + virtual bool matches (const MatchType &type) const; + virtual void mangle (ostream &os) const; +}; + +// type char +class MTChar : public MTPrim { + static TID _tid; +protected: + virtual MTChar *clone () const; + virtual TID type () const; + virtual bool matches (const MatchType &type) const; + virtual void mangle (ostream &os) const; +}; + +// type unsigned short +class MTUnsignedShort : public MTPrim { + static TID _tid; +protected: + virtual MTUnsignedShort *clone () const; + virtual TID type () const; + virtual bool matches (const MatchType &type) const; + virtual void mangle (ostream &os) const; +}; + +// type short +class MTShort : public MTPrim { + static TID _tid; +protected: + virtual MTShort *clone () const; + virtual TID type () const; + virtual bool matches (const MatchType &type) const; + virtual void mangle (ostream &os) const; +}; + +// type unsigned int +class MTUnsignedInt : public MTPrim { + static TID _tid; +protected: + virtual MTUnsignedInt *clone () const; + virtual TID type () const; + virtual bool matches (const MatchType &type) const; + virtual void mangle (ostream &os) const; +}; + +// type int +class MTInt : public MTPrim { + static TID _tid; +protected: + virtual MTInt *clone () const; + virtual TID type () const; + virtual bool matches (const MatchType &type) const; + virtual void mangle (ostream &os) const; +}; + +// type wchar_t +class MTWCharT : public MTPrim { + static TID _tid; +protected: + virtual MTWCharT *clone () const; + virtual TID type () const; + virtual bool matches (const MatchType &type) const; + virtual void mangle (ostream &os) const; +}; + +// type unsigned long +class MTUnsignedLong : public MTPrim { + static TID _tid; +protected: + virtual MTUnsignedLong *clone () const; + virtual TID type () const; + virtual bool matches (const MatchType &type) const; + virtual void mangle (ostream &os) const; +}; + +// type long +class MTLong : public MTPrim { + static TID _tid; +protected: + virtual MTLong *clone () const; + virtual TID type () const; + virtual bool matches (const MatchType &type) const; + virtual void mangle (ostream &os) const; +}; + +// type unsigned long long +class MTUnsignedLongLong : public MTPrim { + static TID _tid; +protected: + virtual MTUnsignedLongLong *clone () const; + virtual TID type () const; + virtual bool matches (const MatchType &type) const; + virtual void mangle (ostream &os) const; +}; + +// type long long +class MTLongLong : public MTPrim { + static TID _tid; +protected: + virtual MTLongLong *clone () const; + virtual TID type () const; + virtual bool matches (const MatchType &type) const; + virtual void mangle (ostream &os) const; +}; + +// type unsigned __int128 +class MTUnsignedInt128 : public MTPrim { + static TID _tid; +protected: + virtual MTUnsignedInt128 *clone () const; + virtual TID type () const; + virtual bool matches (const MatchType &type) const; + virtual void mangle (ostream &os) const; +}; + +// type __int128 +class MTInt128 : public MTPrim { + static TID _tid; +protected: + virtual MTInt128 *clone () const; + virtual TID type () const; + virtual bool matches (const MatchType &type) const; + virtual void mangle (ostream &os) const; +}; + +// type float +class MTFloat : public MTPrim { + static TID _tid; +protected: + virtual MTFloat *clone () const; + virtual TID type () const; + virtual bool matches (const MatchType &type) const; + virtual void mangle (ostream &os) const; +}; + +// type double +class MTDouble : public MTPrim { + static TID _tid; +protected: + virtual MTDouble *clone () const; + virtual TID type () const; + virtual bool matches (const MatchType &type) const; + virtual void mangle (ostream &os) const; +}; + +// type long double +class MTLongDouble : public MTPrim { + static TID _tid; +protected: + virtual MTLongDouble *clone () const; + virtual TID type () const; + virtual bool matches (const MatchType &type) const; + virtual void mangle (ostream &os) const; +}; + +// type void +class MTVoid : public MTPrim { + static TID _tid; +protected: + virtual MTVoid *clone () const; + virtual TID type () const; + virtual bool matches (const MatchType &type) const; + virtual bool is_void () const { return true; } + virtual void mangle (ostream &os) const; +}; + +#endif // __MatchTypeInfos_h__ diff --git a/AspectC++/ACModel/ModelNode.h b/AspectC++/ACModel/ModelNode.h new file mode 100644 index 0000000..0c6b209 --- /dev/null +++ b/AspectC++/ACModel/ModelNode.h @@ -0,0 +1,309 @@ +#ifndef __ModelNode_h__ +#define __ModelNode_h__ + +#include "MatchExpr.h" + +#include +using std::cout; +using std::endl; +#include +#include +#include +using std::string; +#include +#include +#include + +class ModelTransformInfo { +public: + virtual ~ModelTransformInfo () {} +}; + +class SaveContext { + int _stage; + int _last_id; +public: + SaveContext () : _last_id(0) { + static int stage = 0; + _stage = stage++; + } + int next_id () { return _last_id++; } + int stage () { return _stage; } +}; + +inline std::ostream &operator << (std::ostream &os, const MatchSignature &ms) { + os << (ms.is_new() ? "" : ""); + return os; +} + +class ACM_Name; +typedef std::map NameMap; +typedef NameMap::value_type NameMapPair; +inline std::ostream &operator << (std::ostream &os, const NameMap &nm) { + os << "\"name map\""; + return os; +} + +class PointcutExpressionNode { + int _ref_count; +public: + PointcutExpressionNode () : _ref_count (1) {} + virtual ~PointcutExpressionNode () {} + + // get/modify the reference count + int get_ref () const { return _ref_count; } + void ref(int delta = 1) { _ref_count += delta; } + + // set and get the corresponding syntax tree and expression child nodes + virtual int args () const = 0; + virtual PointcutExpressionNode *arg (int) const = 0; + + // duplicate the whole pointcut expression tree -- at least logically + virtual PointcutExpressionNode* duplicate () = 0; +}; + +class PointcutExpression { + PointcutExpressionNode *_node; +public: + PointcutExpression () : _node (0) {} + PointcutExpression (const PointcutExpression &to_copy) { + _node = to_copy.get(); + if (_node != 0) + _node = _node->duplicate(); + } + PointcutExpression &operator = (const PointcutExpression &to_copy) { + destroy(_node); + _node = to_copy.get(); + if (_node != 0) + _node = _node->duplicate(); + return *this; + } + ~PointcutExpression () { destroy (_node); } + + // destroy a pointcut expression tree + void set (PointcutExpressionNode *expr) { _node = expr; } + PointcutExpressionNode *get () const { return _node; } + + static void destroy (PointcutExpressionNode *expr) { + if (!expr) return; + expr->ref(-1); + if (expr->get_ref () == 0) { + for (int i = 0; i < expr->args (); i++) + destroy (expr->arg (i)); + delete expr; + } + } +}; + +inline std::ostream &operator << (std::ostream &os, const PointcutExpression &e) { + os << "parsed pointcut expression"; + return os; +} + +class Code { + string text_; +public: + operator string () const { return text_; } + void set (const string &s) { text_ = s; } +}; + +inline std::ostream &operator << (std::ostream &os, const Code &u) { + os << "\"" << string (u) << "\""; + return os; +} + +// common base class of all join point model node types +class ModelNode { + xmlNodePtr _xml_node; + bool _xml_dirty; + ModelNode *_parent; + ModelNode *_partner; + int _stage; + int _id; + /// parser-provided info for code transformation + ModelTransformInfo *_trans; + /// key for sorting this node + mutable string _key; + mutable bool _key_dirty; + bool _deleted; + int _merge_count; + + string &get_key () const { + if (_key_dirty) { + _key = key(); + _key_dirty = false; + } + return _key; + } + + public: + ModelNode() : _xml_node(0), _xml_dirty(true), _parent(0), _partner(0), + _stage (-1), _id (-1), _trans(0), _key_dirty (true), + _deleted (false), _merge_count (0) {} + virtual ~ModelNode () {} + + bool is_deleted () const { return _deleted; } + void is_deleted (bool d) { _deleted = d; } + + void set_merge_count (int mc) { _merge_count = mc; } + int get_merge_count () { + int pmc = (_parent ? _parent->get_merge_count() : 0); + if (pmc > _merge_count && _parent->is_deleted()) { + _merge_count = pmc; + _deleted = true; + _xml_node = 0; + _xml_dirty = true; + } + return _merge_count; + } + + bool operator == (const ModelNode& that) const { return !(*this < that || that < *this); } + bool operator != (const ModelNode& that) const { return !(*this == that); } + bool operator < (const ModelNode& that) const { return get_key() < that.get_key(); } + + virtual string key() const = 0; + + ModelTransformInfo *transform_info () const { return _trans; } + void transform_info (ModelTransformInfo *trans) { _trans = trans; } + + // set and get XML node pointer + xmlNodePtr get_xml_node () const { return _xml_node; } + void set_xml_node (xmlNodePtr n) { _xml_node = n; } + + // remember if the associated XML node is up-to-date + bool get_xml_dirty () const { return _xml_dirty; } + void set_xml_dirty (bool d = true) { _xml_dirty = d; if (d) _key_dirty = true; } + + // set and get the parent node + void set_parent (ModelNode *n) { _parent = n; } + ModelNode *get_parent () const { return _parent; } + + // update the XML representation of this object. Attributes might have + // changed or the node is new. + virtual void to_xml(SaveContext &) = 0; + + // set a string property + void set_property(const string &prop, const string &val) { + xmlSetProp (_xml_node, (xmlChar*)prop.c_str (), (xmlChar*)val.c_str ()); + } + // set an int property + void set_property(const string &prop, int val) { + char buffer[12]; + sprintf (buffer, "%d", val); + xmlSetProp (_xml_node, (xmlChar*)prop.c_str (), (xmlChar*)buffer); + } + // set a bool property + void set_property(const string &prop, bool val) { + if (val) + set_property (prop, string ("true")); + else + remove_property (prop); + } + + // store string as text child node + void set_text_child(const string &childname, const string &text) { + xmlNewTextChild (_xml_node, NULL, (xmlChar*)childname.c_str (), + (xmlChar*)text.c_str ()); + } + // check if the XML node has a specific property + bool has_property (const string &prop) { + return xmlHasProp (_xml_node, (xmlChar*)prop.c_str ()) != NULL; + } + + // get a string property + void get_property (const string &prop, string &val) { + char *str = (char*)xmlGetProp (_xml_node, (xmlChar*)prop.c_str ()); + val = str; + free (str); + } + + // get an int property + void get_property (const string &prop, int &val) { + char *str = (char*)xmlGetProp (_xml_node, (xmlChar*)prop.c_str ()); + val = atoi (str); + free (str); + } + + // delete a property + bool remove_property (const string &prop) { + xmlAttrPtr attr = xmlHasProp (_xml_node, (xmlChar*)prop.c_str ()); + if (attr) + xmlRemoveProp (attr); + return attr != NULL; + } + + // set and get the element's id, which is used by idrefs of other elements + int get_id () const { return _id; } + int assign_id (SaveContext &context) { + if (_stage != context.stage ()) { + _stage = context.stage (); + _id = context.next_id (); + if (_xml_node) + set_property ("id", _id); + } + return _id; + } + + ModelNode *get_partner () const { return _partner; } + void set_partner (ModelNode *p) { _partner = p; } +}; + +template +class ACM_Container : public std::list, public ModelNode { + template + struct LessPtr { + bool operator()(T_PTR e1, T_PTR e2) const { return *e1 < * e2; } + }; +public: + typedef std::set > Set; + typedef std::list Base; + typedef T Type; +private: + bool _sorted; + Set _sorted_elems; +public: + ACM_Container () : _sorted(false) {} + + string key () const { + string result = ""; + for (typename Base::const_iterator i = Base::begin (); i != Base::end (); ++i) + result += (*i)->key (); + if (result == "") result = "-|"; + return result; + } + + void clear () { + Base::clear (); + _sorted_elems.clear (); + _sorted = false; + } + void insert (T *n) { + Base::push_back (n); + if (_sorted) _sorted_elems.insert(n); + if (AGGR) n->set_parent (get_parent ()); + } + void remove (T *n) { + Base::remove (n); + if (_sorted) _sorted_elems.erase (n); + } + Set &get_sorted () { + if (!_sorted) { + for (typename Base::iterator i = Base::begin (); i != Base::end (); ++i) + _sorted_elems.insert (*i); + _sorted = true; + } + return _sorted_elems; + } + void to_xml (SaveContext &context) { + for (typename Base::iterator i = Base::begin (); i != Base::end (); ++i) { + if (!(*i)->get_xml_node ()) { + xmlNodePtr node = xmlNewChild(get_xml_node (), NULL, (xmlChar*)(*i)->type_str (), NULL); + (*i)->set_xml_node (node); + } + (*i)->to_xml (context); + (*i)->set_xml_dirty (false); + } + } +}; + +#endif // __ModelNode_h__ diff --git a/AspectC++/ACModel/Utils.cc b/AspectC++/ACModel/Utils.cc new file mode 100644 index 0000000..9bfc31c --- /dev/null +++ b/AspectC++/ACModel/Utils.cc @@ -0,0 +1,674 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "Utils.h" + +// return various string representations + +string signature(const ACM_Name &name_param) { + ACM_Name &name = (ACM_Name&)name_param; + ACM_Name *parent = (ACM_Name*)name.get_parent(); + if (!parent) + return "::"; + string result = signature (*parent); + if (result == "::") + result = ""; + else { + result += "::"; + // ignore the anonymous namespace as parent + if (result[0] == '%') + result = ""; + } + result += name.get_name(); + + // the result so far seems to be a sane default so no explicit error handling neccesary, if below checks fall through + if( name.type_val() == JPT_Attribute ) { + result = "[[" + result + "]]"; + + return result; + } + + if( name.type_val() == JPT_Function ) { + ACM_Function &func = (ACM_Function&)name; + list types; + get_arg_types (func, types); + result += "("; + for (list::iterator i = types.begin(); i != types.end(); ++i) { + if (i != types.begin()) + result +=","; + result += format_type(**i); + } + if (func.get_variadic_args()) + result += ",..."; + result += ")"; + if (func.get_cv_qualifiers() & CVQ_CONST) + result += " const"; + if (func.get_cv_qualifiers() & CVQ_VOLATILE) + result += " volatile"; + if (func.has_result_type()) { + ACM_Type &result_type = *func.get_result_type(); + if (func.get_name().find("operator ") != 0) + result = format_type (result_type, result); + else { + string result_str = format_type(result_type); + if (func.get_name().find(string("operator ") + result_str) != 0) + result = format_type (result_type, result); + } + } + } + else if( name.type_val() == JPT_Variable ) { + ACM_Variable &var = (ACM_Variable &)name; + + ACM_Type &type = *( var.get_type() ); + result = format_type( type, result ); + } + return result; +} + +string signature( const ACM_Code &code ) { + // signature of a code joinpoint is defined as signature of the matching entity + if( has_entity( code ) ) + return signature( *get_entity( code ) ); + else + return format_type( *get_entity_type( code ), "" ); +} + +string format_type(ACM_Type &type) { + string sig = type.get_signature(); + string::size_type pos = sig.find(" ?)"); + if (pos != string::npos) { + sig.erase(pos, 2); + } + else { + pos = sig.find("?"); + if (pos != string::npos) { + sig.erase(pos, 1); + } + } + return sig; +} + +string format_type(ACM_Type &type, const string &name) { + string sig = type.get_signature(); + string::size_type pos = sig.find("?"); + if (pos != string::npos) { + sig.replace(pos, 1, name); + } + else { + char last = sig[sig.length () -1]; + if (last != '*' && last != '&') + sig += " "; + sig += name; + } + return sig; +} + +// functions that return the entity for certain join-points +bool has_entity( const ACM_Code &jpl ) { + return ( has_entity_func( jpl ) || has_entity_var( jpl ) ); +} + +ACM_Name *get_entity( const ACM_Code &jpl ) { + if( has_entity_func( jpl ) ) // Code joinpoints that have a function as entity + return get_entity_func( jpl ); + else if ( has_entity_var( jpl ) ) // Code joinpoints that have a variable as entity + return get_entity_var( jpl ); + else { // illegal or new JPType -> make noise + assert( false && "illegal and thus unhandled JPType" ); + return 0; // we need to return something if compiled without asserts + } +} + +bool has_entity_func( const ACM_Code &jpl ) { + // Code joinpoints that have a function as entity: + // JPT_Call + // JPT_Builtin + // JPT_Execution + // JPT_Construction + // JPT_Destruction + return ( jpl.type_val() & ( JPT_Call | JPT_Builtin | JPT_Execution | JPT_Construction | JPT_Destruction ) ); +} + +ACM_Function *get_entity_func( const ACM_Code &jpl ) { + switch( jpl.type_val() ) { + case JPT_Call: + return const_cast( static_cast( jpl ) ).get_target(); // for some reason the getter is not defined const, but should be + case JPT_Builtin: + return const_cast( static_cast( jpl ) ).get_target(); + case JPT_Execution: // inner joinpoints have there entity as parent + case JPT_Construction: + case JPT_Destruction: + return static_cast( jpl.get_parent() ); + default: // illegal or new JPType -> make noise + assert( false && "illegal and thus unhandled JPType" ); + return 0; // we need to return something if compiled without asserts + } +} + +bool has_entity_var( const ACM_Code &jpl ) { + // Code joinpoints that have a variable as entity: + // JPT_Get + // JPT_Set + // JPT_Ref + return ( jpl.type_val() & ( JPT_Get | JPT_Set | JPT_Ref ) ); +}; + +ACM_Variable *get_entity_var( const ACM_Code &jpl ) { + switch( jpl.type_val() ) { + case JPT_Get: + return const_cast( static_cast( jpl ) ).get_variable(); // for some reason the getter is not defined const, but should be + case JPT_Set: + return const_cast( static_cast( jpl ) ).get_variable(); // for some reason the getter is not defined const, but should be + case JPT_Ref: + return const_cast( static_cast( jpl ) ).get_variable(); // for some reason the getter is not defined const, but should be + default: // illegal or new JPType -> make noise + assert( false && "illegal and thus unhandled JPType" ); + return 0; // we need to return something if compiled without asserts + } +} + +ACM_Type *get_entity_type( const ACM_Code &jpl ) { + switch( jpl.type_val() ) { + case JPT_Get: + // FIXME: if the get join point accesses an array, the entity type must be the element type (and not the array type) + return const_cast( static_cast( jpl ) ).get_variable()->get_type(); // for some reason the getter is not defined const, but should be + case JPT_Set: + // FIXME: if the set join point accesses an array, the entity type must be the element type (and not the array type) + return const_cast( static_cast( jpl ) ).get_variable()->get_type(); // for some reason the getter is not defined const, but should be + case JPT_Ref: + return const_cast( static_cast( jpl ) ).get_variable()->get_type(); // for some reason the getter is not defined const, but should be + case JPT_GetRef: + return const_cast( static_cast( jpl ) ).get_type(); + case JPT_SetRef: + return const_cast( static_cast( jpl ) ).get_type(); + case JPT_CallRef: + return const_cast( static_cast( jpl ) ).get_type(); + default: // illegal or new JPType -> make noise + assert( false && "illegal and thus unhandled JPType" ); + return 0; // we need to return something if compiled without asserts + } +} + +// functions that return the number of argument types + +int get_arg_count (ACM_Function &func) { + return func.get_arg_types().size(); +} + +int get_arg_count (ACM_Call &call) { + ACM_Function *func = call.get_target(); + if (call.has_default_args()) + return get_arg_count (*func) - call.get_default_args(); + else + return get_arg_count (*func) + call.get_variadic_arg_types().size(); +} + +int get_arg_count (ACM_Code &code) { + switch( code.type_val() ) { + // first cases which have an associated function + case JPT_Call: // handle seperately as adjustments are needed + return get_arg_count( static_cast( code ) ); + case JPT_Builtin: + case JPT_Execution: + case JPT_Construction: + case JPT_Destruction: + return get_arg_count( *get_entity_func( code ) ); + // cases that behave like a call but are none + // currently these values need to be hard coded + // JPT_Get( T x ) -> T get() + case JPT_Get: + case JPT_GetRef: + return 0; + // JPT_Set( T x ) -> void set( T val ) + case JPT_Set: + case JPT_SetRef: + return 1; + // JPT_Ref( T x ) -> T(&|*) ref() + case JPT_Ref: + return 0; + case JPT_CallRef: + return 0; // FIXME: not implemented, yet. Needs handling similar to JPT_Call. + default: // illegal or new JPType -> make noise + assert( false && "illegal and thus unhandled JPType" ); + return 0; // we need to return something if compiled without asserts + } +} + +// functions that return the argument/result types of certain join-points + +void add_arg_types (ACM_Function &func, list &type_list) { + typedef ACM_Container Container; + Container &types = func.get_arg_types(); + for (Container::iterator i = types.begin (); i != types.end(); ++i) + type_list.push_back (*i); +} + +void get_arg_types (ACM_Function &func, list &type_list) { + type_list.clear(); + add_arg_types (func, type_list); +} + + +void add_arg_types (ACM_Call &jpl, list &type_list) { + typedef ACM_Container Container; + + int args = get_arg_count (jpl); + Container &types = jpl.get_target()->get_arg_types(); + int arg = 0; + for (Container::iterator i = types.begin (); i != types.end() && arg < args; + ++i, ++arg) + type_list.push_back (*i); + if (arg < args) { + Container &var_types = jpl.get_variadic_arg_types(); + for (Container::iterator i = var_types.begin (); i != var_types.end(); ++i) + type_list.push_back (*i); + } +} + +void get_arg_types (ACM_Call &jpl, list &type_list) { + type_list.clear(); + add_arg_types (jpl, type_list); +} + + +void add_arg_types( ACM_Code &jpl, list &type_list ) { + switch( jpl.type_val() ) { + // first cases which have an associated function + case JPT_Call: // handle seperately as adjustments are needed + add_arg_types( static_cast( jpl ), type_list ); + return; + case JPT_Builtin: + case JPT_Execution: + case JPT_Construction: + case JPT_Destruction: + add_arg_types( *get_entity_func( jpl ), type_list ); + return; + // cases that behave like a call but are none + // currently these values need to be hard coded + // JPT_Get( T x ) -> T get() + case JPT_Get: + case JPT_GetRef: + return; // no args + // JPT_Set( T x ) -> void set( T val ) + case JPT_Set: + case JPT_SetRef: + type_list.push_back( get_entity_type( jpl ) ); // only arg has type of variable + return; + // JPT_Ref( T x ) -> T(&|*) ref() + case JPT_Ref: + return; // no args + default: // illegal or new JPType -> make noise + assert( false && "illegal and thus unhandled JPType" ); + } +} + +void get_arg_types (ACM_Code &jpl, list &type_list) { + type_list.clear(); + add_arg_types (jpl, type_list); +} + +bool has_result_type( ACM_Code &jpl ) { + switch( jpl.type_val() ) { + // first cases which have an associated function + case JPT_Call: + case JPT_Builtin: + case JPT_Execution: + case JPT_Construction: + case JPT_Destruction: + return get_entity_func( jpl )->has_result_type(); + // cases which operate on data + // currently these values need to be hard coded + // JPT_Get( T x ) -> T get() + case JPT_Get: + case JPT_GetRef: + return true; + // JPT_Set( T x ) -> void set( T val ) + case JPT_Set: + case JPT_SetRef: + return false; + // JPT_Ref( T x ) -> T(&|*) ref() + case JPT_Ref: + return true; + default: // illegal or new JPType -> make noise + assert( false && "illegal and thus unhandled JPType" ); + return false; // something needs to be returned for builds without asserts + } +} + +ACM_Type *get_result_type( ACM_Code &jpl ) { + switch( jpl.type_val() ) { + // first cases which have an associated function + case JPT_Call: + case JPT_Builtin: + case JPT_Execution: + case JPT_Construction: + case JPT_Destruction: + return get_entity_func( jpl )->get_result_type(); + // cases which operate on data + // currently these values need to be hard coded + // JPT_Get( T x ) -> T get() + case JPT_Get: + case JPT_GetRef: + return get_entity_type( jpl ); + // JPT_Set( T x ) -> void set( T val ) + case JPT_Set: + case JPT_SetRef: + return 0; + // JPT_Ref( T x ) -> T(&|*) ref() + case JPT_Ref: + return const_cast( static_cast( jpl ) ).get_type(); // for some reason the getter is not defined const, but should be + default: // illegal or new JPType -> make noise + assert( false && "illegal and thus unhandled JPType" ); + return 0; // something needs to be returned for builds without asserts + } +} + +// check whether two functions have the same name and argument types +bool have_same_name_and_args (ACM_Function &l, ACM_Function &r) { + if (get_arg_count (l) != get_arg_count (r) || + l.get_variadic_args() != r.get_variadic_args() || + l.get_name() != r.get_name()) + return false; + typedef ACM_Container Container; + Container <ypes = l.get_arg_types(); + Container &rtypes = r.get_arg_types(); + for (Container::const_iterator liter = ltypes.begin(), riter = rtypes.begin(); + liter != ltypes.end(); ++liter, ++riter) + if ((*liter)->get_signature() != (*riter)->get_signature()) + return false; + return true; +} + +// check whether a join-point location is only a pseudo join-point location +bool is_pseudo(ACM_Any &jpl) { + if (jpl.type_val() == JPT_Call && !jpl.get_parent ()) + return true; + return false; +} + +// check if the given joinpoint is an implicit one +bool is_implicit( ACM_Code &jpl ) { + ACM_Node *parent = static_cast( jpl.get_parent() ); + return parent && ( parent->type_val() & JPT_Code ); +} + +// get the parent of the explit joinpoint in code +ACM_Name *get_explicit_parent( ACM_Code &jpl ) { + ACM_Code *code = &jpl; + while( code && is_implicit( *code ) ) + code = static_cast( code->get_parent() ); + + assert( ! code || ( static_cast( code->get_parent() )->type_val() & JPT_Name ) ); + return code ? static_cast( code->get_parent() ) : 0; +} + +// get the lexical scope of a code join-point as needed by 'within' +ACM_Name *lexical_scope (ACM_Code &jpl) { + ACM_Name *parent = get_explicit_parent( jpl ); + assert( parent ); + if (jpl.type_val() & JPT_Access) { + if (parent->type_val() == JPT_Variable) + parent = (ACM_Name*)parent->get_parent(); + } + else + parent = (ACM_Name*)parent->get_parent(); + return parent; +} + +// check whether a given program entity needs an object to be meaningful +bool needs_this( ACM_Name &entity ) { + if( entity.type_val() == JPT_Function ) + return needs_this( static_cast( entity ) ); + else if( entity.type_val() == JPT_Variable ) + return needs_this( static_cast( entity ) ); + else { + assert( false && "Unknown and/or not supported entity type !" ); + return false; // something needs to be returned for builds without asserts + } +} + +// check whether a function needs an object to be invoked ("this pointer") +bool needs_this (ACM_Function &func) { + switch (func.get_kind()) { + case FT_NON_MEMBER: + case FT_STATIC_NON_MEMBER: + case FT_STATIC_MEMBER: + return false; + case FT_CONSTRUCTOR: + case FT_DESTRUCTOR: + case FT_VIRTUAL_DESTRUCTOR: + case FT_PURE_VIRTUAL_DESTRUCTOR: + return true; + case FT_MEMBER: + case FT_VIRTUAL_MEMBER: + case FT_PURE_VIRTUAL_MEMBER: + { + if( ! is_operator( &func ) ) + return true; + + string name = func.get_name().substr(9); + return name != "new" && name != "new[]" && name != "delete" && name != "delete[]"; + } + default: // illegal or new FType -> make noise + assert( false && "illegal and thus unhandled FType" ); + return false; // something needs to be returned for builds without asserts + } +} + +// check whether a variable is part of an object, thus needs a this pointer for an access +bool needs_this( ACM_Variable &var ) { + switch( var.get_kind() ) { + case VT_NON_MEMBER: + case VT_STATIC_NON_MEMBER: + case VT_STATIC_MEMBER: + return false; + case VT_MEMBER: + return true; + default: // illegal or new VType -> make noise + assert( false && "illegal and thus unhandled VType" ); + return false; // something needs to be returned for builds without asserts + } +} + +// check whether a name joinpoint is defined in the project +bool in_project (ACM_Name &name) { + return name.get_tunits().empty(); +} + +// describe the proceed code requirements for code join-points +bool proceed_needs_args(ACM_Code &jpl) { + return get_arg_count (jpl) > 0; +} + +bool proceed_needs_result (ACM_Code &jpl) { + return has_result_type (jpl); +} + +bool proceed_needs_that (ACM_Code &jpl) { + if( jpl.type_val() & JPT_Access ) // outer joinoints ... + return false; // ... never need it + else // inner joinpoints ... + return needs_this( *get_entity( jpl ) ); // determine by entity +} + +bool proceed_needs_target (ACM_Code &jpl) { + if( jpl.type_val() & JPT_Access ) // outer joinoints ... + return needs_this( *get_entity( jpl ) ); // determine by entity + else // inner joinpoints ... + return false; // ... never need it +} + +// manage child name map of ACM_Name nodes + +static string map_key (ACM_Name &name) { + string result = name.get_name(); + if (name.type_val() & JPT_Function) { + list types; + get_arg_types ((ACM_Function &)name, types); + result += "("; + for (list::iterator i = types.begin(); i != types.end(); ++i) { + if (i != types.begin()) + result +=", "; + result += (*i)->get_signature(); + } + result += ")"; + } + return result; +} + +void map_refresh(ACM_Name &name) { + typedef ACM_Container Container; + NameMap &map = name.get_name_map(); + Container &children = name.get_children(); + map.clear(); + for (Container::iterator i = children.begin(); i != children.end(); ++i) { + if ((*i)->type_val() & JPT_Name) { + ACM_Name *child = (ACM_Name*)*i; + map.insert(NameMapPair(map_key(*child), child)); + } + } +} + +ACM_Name *map_lookup(ACM_Name &parent, const string &key) { + NameMap &map = parent.get_name_map(); + if (map.size() == 0 && parent.get_children().size() > 0) + map_refresh(parent); + NameMap::iterator i = map.find(key); + if (i != map.end()) + return i->second; + return 0; +} + +void map_insert(ACM_Name &parent, ACM_Name &child, const string &key) { + NameMap &map = parent.get_name_map(); + map.insert(NameMapPair(key, &child)); +} + +// context information of a join-point + +string filename (ACM_Any &jpl) { + typedef ACM_Container Container; + Container &source = (jpl.type_val() & + (JPT_Construction|JPT_Destruction|JPT_Execution)) ? + ((ACM_Code*)jpl.get_parent())->get_source() : jpl.get_source(); + if (source.size() == 0) + return ""; + + Container::iterator last; + for (Container::iterator i = source.begin (); i != source.end (); ++i) { + last = i; + if ((*i)->get_kind () == SLK_DEF) + break; + } + return (*last)->get_file()->get_filename(); +} + +int line (ACM_Any &jpl) { + typedef ACM_Container Container; + Container &source = (jpl.type_val() & + (JPT_Construction|JPT_Destruction|JPT_Execution)) ? + ((ACM_Code*)jpl.get_parent())->get_source() : jpl.get_source(); + if (source.size() == 0) + return -1; + + Container::iterator last; + for (Container::iterator i = source.begin (); i != source.end (); ++i) { + last = i; + if ((*i)->get_kind () == SLK_DEF) + break; + } + return (*last)->get_line(); +} + +// get the slice that is associated with on introduction +ACM_ClassSlice *get_slice (ACM_Introduction &intro) { + ACM_ClassSlice *cs = 0; + if (intro.has_named_slice ()) + cs = intro.get_named_slice (); + else if (intro.has_anon_slice ()) + cs = intro.get_anon_slice (); + return cs; +} + +// collect the set of abstract member functions and pointcuts of a class or aspect +void get_abstract_members (ACM_Class &cls, set &abstract_members) { + // iterate over all base classes and get the inherited abstract members + typedef ACM_Container Container; + Container &bases = cls.get_bases(); + for (Container::iterator i = bases.begin (); i != bases.end (); ++i) { + set base_members; // key strings + get_abstract_members (**i, base_members); + // now check each abstract base class member in the current class + for (set::const_iterator ki = base_members.begin (); + ki != base_members.end (); ++ki) { + ACM_Any *elem = map_lookup(cls, *ki); + bool redefined = false; + if ((*ki)[0] == '~') + redefined = true; // pure virtual destructor are defined implicitly + else if (elem) { + // check the found member + if (elem->type_val() == JPT_Pointcut && + ((ACM_Pointcut*)elem)->get_kind() != PT_PURE_VIRTUAL) + redefined = true; + else if (elem->type_val() == JPT_Function && + ((ACM_Function*)elem)->get_kind() == FT_VIRTUAL_MEMBER) + redefined = true; + } + // if it is not redefined here as non-abstract, keep it + if (!redefined) + abstract_members.insert (*ki); + } + } + + // non check all member functions and pointcuts of this class + NameMap &name_map = cls.get_name_map(); + for (NameMap::const_iterator i = name_map.begin (); i != name_map.end (); ++i) { + string key = i->first; + ACM_Any *elem = i->second; + if ((elem->type_val() == JPT_Pointcut && + ((ACM_Pointcut*)elem)->get_kind() == PT_PURE_VIRTUAL) || + (elem->type_val() == JPT_Function && + (((ACM_Function*)elem)->get_kind() == FT_PURE_VIRTUAL_MEMBER || + ((ACM_Function*)elem)->get_kind() == FT_PURE_VIRTUAL_DESTRUCTOR))) + abstract_members.insert (key); + } + +// cout << "result for " << cls.get_name() << endl; +// for (set::const_iterator ki = abstract_members.begin (); +// ki != abstract_members.end (); ++ki) { +// cout << " " << *ki << endl; +// } +} + +// check whether a class or aspect is abstract +bool is_abstract (ACM_Class &cls) { + set abstract_members; + get_abstract_members (cls, abstract_members); + return abstract_members.size () != 0; +} + +// calculate number of nested advice levels below the given code plan +int depth (ACM_CodePlan &plan) { + return plan.has_next_level() ? depth (*plan.get_next_level()) + 1 : 0; +} + +// This function takes an AspectC++-Model-Function as ACM_Function and +// returns whether this function is an operator. +bool is_operator(ACM_Function* acm_function) { + return acm_function->get_name().substr(0,9) == "operator "; +} diff --git a/AspectC++/ACModel/Utils.h b/AspectC++/ACModel/Utils.h new file mode 100644 index 0000000..7a2ffaa --- /dev/null +++ b/AspectC++/ACModel/Utils.h @@ -0,0 +1,109 @@ +#ifndef __Utils_h__ +#define __Utils_h__ + +#include "Elements.h" +#include +using std::string; +#include +using std::list; +#include +using std::set; + +// return various string representations + +string signature(const ACM_Name &name); +string signature(const ACM_Code &code); + +string format_type(ACM_Type &type); +string format_type(ACM_Type &type, const string &name); + +// functions that return the entity for certain join-points +bool has_entity( const ACM_Code &jpl ); +ACM_Name *get_entity( const ACM_Code &jpl ); + +bool has_entity_func( const ACM_Code &jpl ); +ACM_Function *get_entity_func( const ACM_Code &jpl ); + +bool has_entity_var( const ACM_Code &jpl ); +ACM_Variable *get_entity_var( const ACM_Code &jpl ); + +ACM_Type *get_entity_type( const ACM_Code &jpl ); + +// functions that return the number of argument types +int get_arg_count (ACM_Function &func); +int get_arg_count (ACM_Call &code); +int get_arg_count (ACM_Code &code); + +// functions that return the argument/result types of certain join-points + +void add_arg_types (ACM_Function &func, list &type_list); +void get_arg_types (ACM_Function &func, list &type_list); + +void add_arg_types (ACM_Call &jpl, list &type_list); +void get_arg_types (ACM_Call &jpl, list &type_list); + +void add_arg_types (ACM_Code &jpl, list &type_list); +void get_arg_types (ACM_Code &jpl, list &type_list); + +bool has_result_type (ACM_Code &jpl); +ACM_Type *get_result_type (ACM_Code &jpl); + +// check whether two functions have the same name and argument types +bool have_same_name_and_args (ACM_Function &l, ACM_Function &r); + +// check whether a join-point location is only a pseudo join-point location +bool is_pseudo(ACM_Any &jpl); + +// check if the given joinpoint is an implicit one +bool is_implicit( ACM_Code &jpl ); + +// get the parent of the explit joinpoint in code +ACM_Name *get_explicit_parent( ACM_Code &jpl ); + +// get the lexical scope of a code join-point as needed by 'within' +ACM_Name *lexical_scope (ACM_Code &jpl); + +// check whether a given program entity needs an object to be meaningful +bool needs_this( ACM_Name &entity ); + +// check whether a function needs an object to be invoked ("this pointer") +bool needs_this (ACM_Function &func); + +// check whether a variable is part of an object, thus needs a this pointer for an access +bool needs_this( ACM_Variable &var ); + +// check whether a name joinpoint is defined in the project +bool in_project (ACM_Name &name); + +// describe the proceed code requirements for code join-points +bool proceed_needs_args(ACM_Code &jpl); +bool proceed_needs_result (ACM_Code &jpl); +bool proceed_needs_that (ACM_Code &jpl); +bool proceed_needs_target (ACM_Code &jpl); + +// manage child name map of ACM_Name nodes +void map_refresh(ACM_Name &name); +ACM_Name *map_lookup(ACM_Name &parent, const string &key); +void map_insert(ACM_Name &parent, ACM_Name &child, const string &key); + +// context information of a join-point +string filename (ACM_Any &jpl); +int line (ACM_Any &jpl); + +// get the slice that is associated with on introduction +ACM_ClassSlice *get_slice (ACM_Introduction &intro); + +// collect the set of abstract member functions and pointcuts of a class or aspect +void get_abstract_members (ACM_Class &cls, set &abstract_members); + +// check whether a class or aspect is abstract +bool is_abstract (ACM_Class &cls); + +// calculate number of nested advice levels below the given code plan +int depth (ACM_CodePlan &plan); + +// This function takes an AspectC++-Model-Function as ACM_Function and +// returns whether this function is an operator. +bool is_operator(ACM_Function*); + +#endif // __Utils_h__ diff --git a/AspectC++/ACModel/XmlModelReader.cc b/AspectC++/ACModel/XmlModelReader.cc new file mode 100644 index 0000000..fef2bf5 --- /dev/null +++ b/AspectC++/ACModel/XmlModelReader.cc @@ -0,0 +1,979 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 +#include +using std::istringstream; +#include + +#include "XmlModelReader.h" + + +ModelNode *XmlModelReader::from_xml (ACM_Node &node) { + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_File &node) { + char *str_filename = (char*)xmlGetProp (curr_, (xmlChar*)"filename"); + if (str_filename) { + node.set_filename (str_filename); + xmlFree (str_filename); + } + char *str_len = (char*)xmlGetProp (curr_, (xmlChar*)"len"); + if (str_len) { + int int_len = atoi (str_len); + node.set_len ((int)int_len); + xmlFree (str_len); + } + char *str_time = (char*)xmlGetProp (curr_, (xmlChar*)"time"); + if (str_time) { + int int_time = atoi (str_time); + node.set_time ((int)int_time); + xmlFree (str_time); + } + from_xml ((ACM_Node&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_TUnit &node) { + node.set_dirty_flag (false); + char *str_dirty_flag = (char*)xmlGetProp (curr_, (xmlChar*)"dirty_flag"); + if (str_dirty_flag) { + node.set_dirty_flag (strcmp (str_dirty_flag, "true") == 0); + xmlFree (str_dirty_flag); + } + from_xml ((ACM_File&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_Header &node) { + char *str_in = (char*)xmlGetProp (curr_, (xmlChar*)"in"); + if (str_in) { + istringstream in (str_in, istringstream::in); + int id; + while (!in.eof ()) { + in >> id; + if (in.fail ()) + break; + node.get_in ().insert ((ACM_TUnit*)node_map_[id]); + } + xmlFree (str_in); + } + from_xml ((ACM_File&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_Source &node) { + char *str_kind = (char*)xmlGetProp (curr_, (xmlChar*)"kind"); + if (str_kind) { + int int_kind = atoi (str_kind); + node.set_kind ((SourceLocKind)int_kind); + xmlFree (str_kind); + } + char *str_file = (char*)xmlGetProp (curr_, (xmlChar*)"file"); + if (str_file) { + int file_id = atoi (str_file); + node.set_file ((ACM_File*)node_map_[file_id]); + xmlFree (str_file); + } + char *str_line = (char*)xmlGetProp (curr_, (xmlChar*)"line"); + if (str_line) { + int int_line = atoi (str_line); + node.set_line ((int)int_line); + xmlFree (str_line); + } + char *str_len = (char*)xmlGetProp (curr_, (xmlChar*)"len"); + if (str_len) { + int int_len = atoi (str_len); + node.set_len ((int)int_len); + xmlFree (str_len); + } + from_xml ((ACM_Node&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_MemberIntro &node) { + char *str_intro = (char*)xmlGetProp (curr_, (xmlChar*)"intro"); + if (str_intro) { + int intro_id = atoi (str_intro); + node.set_intro ((ACM_Introduction*)node_map_[intro_id]); + xmlFree (str_intro); + } + char *str_members = (char*)xmlGetProp (curr_, (xmlChar*)"members"); + if (str_members) { + istringstream in (str_members, istringstream::in); + int id; + while (!in.eof ()) { + in >> id; + if (in.fail ()) + break; + node.get_members ().insert ((ACM_Name*)node_map_[id]); + } + xmlFree (str_members); + } + from_xml ((ACM_Node&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_BaseIntro &node) { + char *str_intro = (char*)xmlGetProp (curr_, (xmlChar*)"intro"); + if (str_intro) { + int intro_id = atoi (str_intro); + node.set_intro ((ACM_Introduction*)node_map_[intro_id]); + xmlFree (str_intro); + } + char *str_bases = (char*)xmlGetProp (curr_, (xmlChar*)"bases"); + if (str_bases) { + istringstream in (str_bases, istringstream::in); + int id; + while (!in.eof ()) { + in >> id; + if (in.fail ()) + break; + node.get_bases ().insert ((ACM_Class*)node_map_[id]); + } + xmlFree (str_bases); + } + from_xml ((ACM_Node&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_ClassPlan &node) { + xmlNodePtr child_base_intros = find_child ("base_intros"); + if (child_base_intros) { + node.get_base_intros ().set_xml_node (child_base_intros); + for (xmlNodePtr curr = child_base_intros->children; curr; curr = curr->next) + node.get_base_intros ().insert ((ACM_BaseIntro*)initialize_node (curr)); + } + xmlNodePtr child_member_intros = find_child ("member_intros"); + if (child_member_intros) { + node.get_member_intros ().set_xml_node (child_member_intros); + for (xmlNodePtr curr = child_member_intros->children; curr; curr = curr->next) + node.get_member_intros ().insert ((ACM_MemberIntro*)initialize_node (curr)); + } + from_xml ((ACM_Node&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_CodeAdvice &node) { + char *str_advice = (char*)xmlGetProp (curr_, (xmlChar*)"advice"); + if (str_advice) { + int advice_id = atoi (str_advice); + node.set_advice ((ACM_AdviceCode*)node_map_[advice_id]); + xmlFree (str_advice); + } + node.set_conditional (false); + char *str_conditional = (char*)xmlGetProp (curr_, (xmlChar*)"conditional"); + if (str_conditional) { + node.set_conditional (strcmp (str_conditional, "true") == 0); + xmlFree (str_conditional); + } + from_xml ((ACM_Node&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_CodePlan &node) { + xmlNodePtr child_before = find_child ("before"); + if (child_before) { + node.get_before ().set_xml_node (child_before); + for (xmlNodePtr curr = child_before->children; curr; curr = curr->next) + node.get_before ().insert ((ACM_CodeAdvice*)initialize_node (curr)); + } + xmlNodePtr child_around = find_child ("around"); + if (child_around) + node.set_around ((ACM_CodeAdvice*)initialize_node (child_around->children)); + xmlNodePtr child_after = find_child ("after"); + if (child_after) { + node.get_after ().set_xml_node (child_after); + for (xmlNodePtr curr = child_after->children; curr; curr = curr->next) + node.get_after ().insert ((ACM_CodeAdvice*)initialize_node (curr)); + } + xmlNodePtr child_next_level = find_child ("next_level"); + if (child_next_level) + node.set_next_level ((ACM_CodePlan*)initialize_node (child_next_level->children)); + from_xml ((ACM_Node&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_Any &node) { + char *str_jpid = (char*)xmlGetProp (curr_, (xmlChar*)"jpid"); + if (str_jpid) { + int int_jpid = atoi (str_jpid); + node.set_jpid ((int)int_jpid); + xmlFree (str_jpid); + } + xmlNodePtr child_source = find_child ("source"); + if (child_source) { + node.get_source ().set_xml_node (child_source); + for (xmlNodePtr curr = child_source->children; curr; curr = curr->next) + node.get_source ().insert ((ACM_Source*)initialize_node (curr)); + } + char *str_attributes = (char*)xmlGetProp (curr_, (xmlChar*)"attributes"); + if (str_attributes) { + istringstream in (str_attributes, istringstream::in); + int id; + while (!in.eof ()) { + in >> id; + if (in.fail ()) + break; + node.get_attributes ().insert ((ACM_Attribute*)node_map_[id]); + } + xmlFree (str_attributes); + } + from_xml ((ACM_Node&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_Type &node) { + char *str_signature = (char*)xmlGetProp (curr_, (xmlChar*)"signature"); + if (str_signature) { + node.set_signature (str_signature); + xmlFree (str_signature); + } + from_xml ((ACM_Any&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_Arg &node) { + char *str_type = (char*)xmlGetProp (curr_, (xmlChar*)"type"); + if (str_type) { + node.set_type (str_type); + xmlFree (str_type); + } + char *str_name = (char*)xmlGetProp (curr_, (xmlChar*)"name"); + if (str_name) { + node.set_name (str_name); + xmlFree (str_name); + } + from_xml ((ACM_Any&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_Name &node) { + xmlNodePtr child_children = find_child ("children"); + if (child_children) { + node.get_children ().set_xml_node (child_children); + for (xmlNodePtr curr = child_children->children; curr; curr = curr->next) + node.get_children ().insert ((ACM_Any*)initialize_node (curr)); + } + char *str_name = (char*)xmlGetProp (curr_, (xmlChar*)"name"); + if (str_name) { + node.set_name (str_name); + xmlFree (str_name); + } + node.set_builtin (false); + char *str_builtin = (char*)xmlGetProp (curr_, (xmlChar*)"builtin"); + if (str_builtin) { + node.set_builtin (strcmp (str_builtin, "true") == 0); + xmlFree (str_builtin); + } + char *str_tunits = (char*)xmlGetProp (curr_, (xmlChar*)"tunits"); + if (str_tunits) { + istringstream in (str_tunits, istringstream::in); + int id; + while (!in.eof ()) { + in >> id; + if (in.fail ()) + break; + node.get_tunits ().insert ((ACM_TUnit*)node_map_[id]); + } + xmlFree (str_tunits); + } + from_xml ((ACM_Any&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_Namespace &node) { + from_xml ((ACM_Name&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_Function &node) { + xmlNodePtr child_result_type = find_child ("result_type"); + if (child_result_type) + node.set_result_type ((ACM_Type*)initialize_node (child_result_type->children)); + xmlNodePtr child_arg_types = find_child ("arg_types"); + if (child_arg_types) { + node.get_arg_types ().set_xml_node (child_arg_types); + for (xmlNodePtr curr = child_arg_types->children; curr; curr = curr->next) + node.get_arg_types ().insert ((ACM_Type*)initialize_node (curr)); + } + char *str_kind = (char*)xmlGetProp (curr_, (xmlChar*)"kind"); + if (str_kind) { + int int_kind = atoi (str_kind); + node.set_kind ((FunctionType)int_kind); + xmlFree (str_kind); + } + node.set_variadic_args (false); + char *str_variadic_args = (char*)xmlGetProp (curr_, (xmlChar*)"variadic_args"); + if (str_variadic_args) { + node.set_variadic_args (strcmp (str_variadic_args, "true") == 0); + xmlFree (str_variadic_args); + } + char *str_cv_qualifiers = (char*)xmlGetProp (curr_, (xmlChar*)"cv_qualifiers"); + if (str_cv_qualifiers) { + int int_cv_qualifiers = atoi (str_cv_qualifiers); + node.set_cv_qualifiers ((CVQualifiers)int_cv_qualifiers); + xmlFree (str_cv_qualifiers); + } + char *str_static_in = (char*)xmlGetProp (curr_, (xmlChar*)"static_in"); + if (str_static_in) { + int static_in_id = atoi (str_static_in); + node.set_static_in ((ACM_TUnit*)node_map_[static_in_id]); + xmlFree (str_static_in); + } + from_xml ((ACM_Name&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_Variable &node) { + xmlNodePtr child_type = find_child ("type"); + if (child_type) + node.set_type ((ACM_Type*)initialize_node (child_type->children)); + char *str_kind = (char*)xmlGetProp (curr_, (xmlChar*)"kind"); + if (str_kind) { + int int_kind = atoi (str_kind); + node.set_kind ((VariableType)int_kind); + xmlFree (str_kind); + } + from_xml ((ACM_Name&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_Class &node) { + char *str_bases = (char*)xmlGetProp (curr_, (xmlChar*)"bases"); + if (str_bases) { + istringstream in (str_bases, istringstream::in); + int id; + while (!in.eof ()) { + in >> id; + if (in.fail ()) + break; + node.get_bases ().insert ((ACM_Class*)node_map_[id]); + } + xmlFree (str_bases); + } + xmlNodePtr child_plan = find_child ("plan"); + if (child_plan) + node.set_plan ((ACM_ClassPlan*)initialize_node (child_plan->children)); + from_xml ((ACM_Name&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_ClassSlice &node) { + node.set_is_struct (false); + char *str_is_struct = (char*)xmlGetProp (curr_, (xmlChar*)"is_struct"); + if (str_is_struct) { + node.set_is_struct (strcmp (str_is_struct, "true") == 0); + xmlFree (str_is_struct); + } + from_xml ((ACM_Name&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_Code &node) { + xmlNodePtr child_plan = find_child ("plan"); + if (child_plan) + node.set_plan ((ACM_CodePlan*)initialize_node (child_plan->children)); + from_xml ((ACM_Any&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_Access &node) { + char *str_lid = (char*)xmlGetProp (curr_, (xmlChar*)"lid"); + if (str_lid) { + int int_lid = atoi (str_lid); + node.set_lid ((int)int_lid); + xmlFree (str_lid); + } + char *str_target_object_lid = (char*)xmlGetProp (curr_, (xmlChar*)"target_object_lid"); + if (str_target_object_lid) { + int int_target_object_lid = atoi (str_target_object_lid); + node.set_target_object_lid ((int)int_target_object_lid); + xmlFree (str_target_object_lid); + } + char *str_cfg_block_lid = (char*)xmlGetProp (curr_, (xmlChar*)"cfg_block_lid"); + if (str_cfg_block_lid) { + int int_cfg_block_lid = atoi (str_cfg_block_lid); + node.set_cfg_block_lid ((int)int_cfg_block_lid); + xmlFree (str_cfg_block_lid); + } + char *str_target_class = (char*)xmlGetProp (curr_, (xmlChar*)"target_class"); + if (str_target_class) { + int target_class_id = atoi (str_target_class); + node.set_target_class ((ACM_Class*)node_map_[target_class_id]); + xmlFree (str_target_class); + } + from_xml ((ACM_Code&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_Get &node) { + char *str_variable = (char*)xmlGetProp (curr_, (xmlChar*)"variable"); + if (str_variable) { + int variable_id = atoi (str_variable); + node.set_variable ((ACM_Variable*)node_map_[variable_id]); + xmlFree (str_variable); + } + from_xml ((ACM_Access&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_Set &node) { + char *str_variable = (char*)xmlGetProp (curr_, (xmlChar*)"variable"); + if (str_variable) { + int variable_id = atoi (str_variable); + node.set_variable ((ACM_Variable*)node_map_[variable_id]); + xmlFree (str_variable); + } + from_xml ((ACM_Access&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_Call &node) { + char *str_target = (char*)xmlGetProp (curr_, (xmlChar*)"target"); + if (str_target) { + int target_id = atoi (str_target); + node.set_target ((ACM_Function*)node_map_[target_id]); + xmlFree (str_target); + } + xmlNodePtr child_variadic_arg_types = find_child ("variadic_arg_types"); + if (child_variadic_arg_types) { + node.get_variadic_arg_types ().set_xml_node (child_variadic_arg_types); + for (xmlNodePtr curr = child_variadic_arg_types->children; curr; curr = curr->next) + node.get_variadic_arg_types ().insert ((ACM_Type*)initialize_node (curr)); + } + char *str_default_args = (char*)xmlGetProp (curr_, (xmlChar*)"default_args"); + if (str_default_args) { + int int_default_args = atoi (str_default_args); + node.set_default_args ((int)int_default_args); + xmlFree (str_default_args); + } + from_xml ((ACM_Access&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_Builtin &node) { + char *str_target = (char*)xmlGetProp (curr_, (xmlChar*)"target"); + if (str_target) { + int target_id = atoi (str_target); + node.set_target ((ACM_Function*)node_map_[target_id]); + xmlFree (str_target); + } + xmlNodePtr child_implicit_access = find_child ("implicit_access"); + if (child_implicit_access) { + node.get_implicit_access ().set_xml_node (child_implicit_access); + for (xmlNodePtr curr = child_implicit_access->children; curr; curr = curr->next) + node.get_implicit_access ().insert ((ACM_Access*)initialize_node (curr)); + } + from_xml ((ACM_Access&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_Ref &node) { + char *str_variable = (char*)xmlGetProp (curr_, (xmlChar*)"variable"); + if (str_variable) { + int variable_id = atoi (str_variable); + node.set_variable ((ACM_Variable*)node_map_[variable_id]); + xmlFree (str_variable); + } + xmlNodePtr child_type = find_child ("type"); + if (child_type) + node.set_type ((ACM_Type*)initialize_node (child_type->children)); + from_xml ((ACM_Access&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_GetRef &node) { + xmlNodePtr child_type = find_child ("type"); + if (child_type) + node.set_type ((ACM_Type*)initialize_node (child_type->children)); + from_xml ((ACM_Access&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_SetRef &node) { + xmlNodePtr child_type = find_child ("type"); + if (child_type) + node.set_type ((ACM_Type*)initialize_node (child_type->children)); + from_xml ((ACM_Access&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_CallRef &node) { + xmlNodePtr child_type = find_child ("type"); + if (child_type) + node.set_type ((ACM_Type*)initialize_node (child_type->children)); + from_xml ((ACM_Access&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_Execution &node) { + from_xml ((ACM_Code&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_Construction &node) { + from_xml ((ACM_Code&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_Destruction &node) { + from_xml ((ACM_Code&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_Pointcut &node) { + char *str_expr = (char*)xmlGetProp (curr_, (xmlChar*)"expr"); + if (str_expr) { + node.set_expr (str_expr); + xmlFree (str_expr); + } + xmlNodePtr child_args = find_child ("args"); + if (child_args) { + node.get_args ().set_xml_node (child_args); + for (xmlNodePtr curr = child_args->children; curr; curr = curr->next) + node.get_args ().insert ((ACM_Arg*)initialize_node (curr)); + } + char *str_kind = (char*)xmlGetProp (curr_, (xmlChar*)"kind"); + if (str_kind) { + int int_kind = atoi (str_kind); + node.set_kind ((PointcutType)int_kind); + xmlFree (str_kind); + } + from_xml ((ACM_Name&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_Attribute &node) { + xmlNodePtr child_args = find_child ("args"); + if (child_args) { + node.get_args ().set_xml_node (child_args); + for (xmlNodePtr curr = child_args->children; curr; curr = curr->next) + node.get_args ().insert ((ACM_Arg*)initialize_node (curr)); + } + from_xml ((ACM_Name&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_Advice &node) { + xmlNodePtr child_pointcut = find_child ("pointcut"); + if (child_pointcut) + node.set_pointcut ((ACM_Pointcut*)initialize_node (child_pointcut->children)); + char *str_lid = (char*)xmlGetProp (curr_, (xmlChar*)"lid"); + if (str_lid) { + int int_lid = atoi (str_lid); + node.set_lid ((int)int_lid); + xmlFree (str_lid); + } + from_xml ((ACM_Any&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_AdviceCode &node) { + char *str_kind = (char*)xmlGetProp (curr_, (xmlChar*)"kind"); + if (str_kind) { + int int_kind = atoi (str_kind); + node.set_kind ((AdviceCodeType)int_kind); + xmlFree (str_kind); + } + char *str_context = (char*)xmlGetProp (curr_, (xmlChar*)"context"); + if (str_context) { + int int_context = atoi (str_context); + node.set_context ((AdviceCodeContext)int_context); + xmlFree (str_context); + } + from_xml ((ACM_Advice&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_Introduction &node) { + char *str_named_slice = (char*)xmlGetProp (curr_, (xmlChar*)"named_slice"); + if (str_named_slice) { + int named_slice_id = atoi (str_named_slice); + node.set_named_slice ((ACM_ClassSlice*)node_map_[named_slice_id]); + xmlFree (str_named_slice); + } + xmlNodePtr child_anon_slice = find_child ("anon_slice"); + if (child_anon_slice) + node.set_anon_slice ((ACM_ClassSlice*)initialize_node (child_anon_slice->children)); + from_xml ((ACM_Advice&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_Order &node) { + xmlNodePtr child_aspect_exprs = find_child ("aspect_exprs"); + if (child_aspect_exprs) { + node.get_aspect_exprs ().set_xml_node (child_aspect_exprs); + for (xmlNodePtr curr = child_aspect_exprs->children; curr; curr = curr->next) + node.get_aspect_exprs ().insert ((ACM_Pointcut*)initialize_node (curr)); + } + from_xml ((ACM_Advice&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_Aspect &node) { + xmlNodePtr child_intros = find_child ("intros"); + if (child_intros) { + node.get_intros ().set_xml_node (child_intros); + for (xmlNodePtr curr = child_intros->children; curr; curr = curr->next) + node.get_intros ().insert ((ACM_Introduction*)initialize_node (curr)); + } + xmlNodePtr child_advices = find_child ("advices"); + if (child_advices) { + node.get_advices ().set_xml_node (child_advices); + for (xmlNodePtr curr = child_advices->children; curr; curr = curr->next) + node.get_advices ().insert ((ACM_AdviceCode*)initialize_node (curr)); + } + xmlNodePtr child_orders = find_child ("orders"); + if (child_orders) { + node.get_orders ().set_xml_node (child_orders); + for (xmlNodePtr curr = child_orders->children; curr; curr = curr->next) + node.get_orders ().insert ((ACM_Order*)initialize_node (curr)); + } + from_xml ((ACM_Class&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_Speculation &node) { + char *str_advice = (char*)xmlGetProp (curr_, (xmlChar*)"advice"); + if (str_advice) { + int advice_id = atoi (str_advice); + node.set_advice ((ACM_Advice*)node_map_[advice_id]); + xmlFree (str_advice); + } + char *str_tunit = (char*)xmlGetProp (curr_, (xmlChar*)"tunit"); + if (str_tunit) { + int tunit_id = atoi (str_tunit); + node.set_tunit ((ACM_TUnit*)node_map_[tunit_id]); + xmlFree (str_tunit); + } + char *str_true_jps = (char*)xmlGetProp (curr_, (xmlChar*)"true_jps"); + if (str_true_jps) { + istringstream in (str_true_jps, istringstream::in); + int id; + while (!in.eof ()) { + in >> id; + if (in.fail ()) + break; + node.get_true_jps ().insert ((ACM_Any*)node_map_[id]); + } + xmlFree (str_true_jps); + } + char *str_false_jps = (char*)xmlGetProp (curr_, (xmlChar*)"false_jps"); + if (str_false_jps) { + istringstream in (str_false_jps, istringstream::in); + int id; + while (!in.eof ()) { + in >> id; + if (in.fail ()) + break; + node.get_false_jps ().insert ((ACM_Any*)node_map_[id]); + } + xmlFree (str_false_jps); + } + char *str_conditional_jps = (char*)xmlGetProp (curr_, (xmlChar*)"conditional_jps"); + if (str_conditional_jps) { + istringstream in (str_conditional_jps, istringstream::in); + int id; + while (!in.eof ()) { + in >> id; + if (in.fail ()) + break; + node.get_conditional_jps ().insert ((ACM_Any*)node_map_[id]); + } + xmlFree (str_conditional_jps); + } + from_xml ((ACM_Node&)node); + return &node; +} + +ModelNode *XmlModelReader::from_xml (ACM_Model &node) { + xmlNodePtr child_files = find_child ("files"); + if (child_files) { + node.get_files ().set_xml_node (child_files); + for (xmlNodePtr curr = child_files->children; curr; curr = curr->next) + node.get_files ().insert ((ACM_File*)initialize_node (curr)); + } + xmlNodePtr child_root = find_child ("root"); + if (child_root) + node.set_root ((ACM_Namespace*)initialize_node (child_root->children)); + xmlNodePtr child_speculations = find_child ("speculations"); + if (child_speculations) { + node.get_speculations ().set_xml_node (child_speculations); + for (xmlNodePtr curr = child_speculations->children; curr; curr = curr->next) + node.get_speculations ().insert ((ACM_Speculation*)initialize_node (curr)); + } + char *str_version = (char*)xmlGetProp (curr_, (xmlChar*)"version"); + if (str_version) { + node.set_version (str_version); + xmlFree (str_version); + } + from_xml ((ACM_Node&)node); + return &node; +} + + +bool XmlModelReader::alloc_nodes_with_id (xmlNodePtr node) { + char *str_id = (char*)xmlGetProp (node, (xmlChar*)"id"); + if (str_id) { + int id = atoi (str_id); + free (str_id); + if (id < 0 || id >= ids_ || node_map_[id] != 0) { + std::cout << "invalid or duplicate id " << id << " in project file." << std::endl; + return false; + } + node_map_[id] = alloc_node (node); + } + for (xmlNodePtr curr = node->children; curr; curr = curr->next) + if (!alloc_nodes_with_id (curr)) + return false; + return true; +} + +ModelNode *XmlModelReader::alloc_node (xmlNodePtr node) { + const char *name = (const char*)node->name; + if (strcmp (name, "TUnit") == 0) + return model_->newTUnit (); +else if (strcmp (name, "Header") == 0) + return model_->newHeader (); +else if (strcmp (name, "Source") == 0) + return model_->newSource (); +else if (strcmp (name, "MemberIntro") == 0) + return model_->newMemberIntro (); +else if (strcmp (name, "BaseIntro") == 0) + return model_->newBaseIntro (); +else if (strcmp (name, "ClassPlan") == 0) + return model_->newClassPlan (); +else if (strcmp (name, "CodeAdvice") == 0) + return model_->newCodeAdvice (); +else if (strcmp (name, "CodePlan") == 0) + return model_->newCodePlan (); +else if (strcmp (name, "Type") == 0) + return model_->newType (); +else if (strcmp (name, "Arg") == 0) + return model_->newArg (); +else if (strcmp (name, "Namespace") == 0) + return model_->newNamespace (); +else if (strcmp (name, "Function") == 0) + return model_->newFunction (); +else if (strcmp (name, "Variable") == 0) + return model_->newVariable (); +else if (strcmp (name, "Class") == 0) + return model_->newClass (); +else if (strcmp (name, "ClassSlice") == 0) + return model_->newClassSlice (); +else if (strcmp (name, "Get") == 0) + return model_->newGet (); +else if (strcmp (name, "Set") == 0) + return model_->newSet (); +else if (strcmp (name, "Call") == 0) + return model_->newCall (); +else if (strcmp (name, "Builtin") == 0) + return model_->newBuiltin (); +else if (strcmp (name, "Ref") == 0) + return model_->newRef (); +else if (strcmp (name, "GetRef") == 0) + return model_->newGetRef (); +else if (strcmp (name, "SetRef") == 0) + return model_->newSetRef (); +else if (strcmp (name, "CallRef") == 0) + return model_->newCallRef (); +else if (strcmp (name, "Execution") == 0) + return model_->newExecution (); +else if (strcmp (name, "Construction") == 0) + return model_->newConstruction (); +else if (strcmp (name, "Destruction") == 0) + return model_->newDestruction (); +else if (strcmp (name, "Pointcut") == 0) + return model_->newPointcut (); +else if (strcmp (name, "Attribute") == 0) + return model_->newAttribute (); +else if (strcmp (name, "AdviceCode") == 0) + return model_->newAdviceCode (); +else if (strcmp (name, "Introduction") == 0) + return model_->newIntroduction (); +else if (strcmp (name, "Order") == 0) + return model_->newOrder (); +else if (strcmp (name, "Aspect") == 0) + return model_->newAspect (); +else if (strcmp (name, "Speculation") == 0) + return model_->newSpeculation (); +else if (strcmp (name, "Model") == 0) + return model_->newModel (); + + return 0; +} + +ModelNode *XmlModelReader::initialize_node (xmlNodePtr node) { + ModelNode *result = 0; + char *str_id = (char*)xmlGetProp (node, (xmlChar*)"id"); + if (str_id) { + result = node_map_[atoi (str_id)]; + free (str_id); + } + const char *name = (const char*)node->name; + xmlNodePtr old_curr = curr_; + curr_ = node; + ChildMap child_map; + ChildMap *old_child_map = set_child_map (child_map, node); + + if (strcmp (name, "TUnit") == 0) + result = from_xml (result ? *(ACM_TUnit*)result : *model_->newTUnit ()); + else if (strcmp (name, "Header") == 0) + result = from_xml (result ? *(ACM_Header*)result : *model_->newHeader ()); + else if (strcmp (name, "Source") == 0) + result = from_xml (result ? *(ACM_Source*)result : *model_->newSource ()); + else if (strcmp (name, "MemberIntro") == 0) + result = from_xml (result ? *(ACM_MemberIntro*)result : *model_->newMemberIntro ()); + else if (strcmp (name, "BaseIntro") == 0) + result = from_xml (result ? *(ACM_BaseIntro*)result : *model_->newBaseIntro ()); + else if (strcmp (name, "ClassPlan") == 0) + result = from_xml (result ? *(ACM_ClassPlan*)result : *model_->newClassPlan ()); + else if (strcmp (name, "CodeAdvice") == 0) + result = from_xml (result ? *(ACM_CodeAdvice*)result : *model_->newCodeAdvice ()); + else if (strcmp (name, "CodePlan") == 0) + result = from_xml (result ? *(ACM_CodePlan*)result : *model_->newCodePlan ()); + else if (strcmp (name, "Type") == 0) + result = from_xml (result ? *(ACM_Type*)result : *model_->newType ()); + else if (strcmp (name, "Arg") == 0) + result = from_xml (result ? *(ACM_Arg*)result : *model_->newArg ()); + else if (strcmp (name, "Namespace") == 0) + result = from_xml (result ? *(ACM_Namespace*)result : *model_->newNamespace ()); + else if (strcmp (name, "Function") == 0) + result = from_xml (result ? *(ACM_Function*)result : *model_->newFunction ()); + else if (strcmp (name, "Variable") == 0) + result = from_xml (result ? *(ACM_Variable*)result : *model_->newVariable ()); + else if (strcmp (name, "Class") == 0) + result = from_xml (result ? *(ACM_Class*)result : *model_->newClass ()); + else if (strcmp (name, "ClassSlice") == 0) + result = from_xml (result ? *(ACM_ClassSlice*)result : *model_->newClassSlice ()); + else if (strcmp (name, "Get") == 0) + result = from_xml (result ? *(ACM_Get*)result : *model_->newGet ()); + else if (strcmp (name, "Set") == 0) + result = from_xml (result ? *(ACM_Set*)result : *model_->newSet ()); + else if (strcmp (name, "Call") == 0) + result = from_xml (result ? *(ACM_Call*)result : *model_->newCall ()); + else if (strcmp (name, "Builtin") == 0) + result = from_xml (result ? *(ACM_Builtin*)result : *model_->newBuiltin ()); + else if (strcmp (name, "Ref") == 0) + result = from_xml (result ? *(ACM_Ref*)result : *model_->newRef ()); + else if (strcmp (name, "GetRef") == 0) + result = from_xml (result ? *(ACM_GetRef*)result : *model_->newGetRef ()); + else if (strcmp (name, "SetRef") == 0) + result = from_xml (result ? *(ACM_SetRef*)result : *model_->newSetRef ()); + else if (strcmp (name, "CallRef") == 0) + result = from_xml (result ? *(ACM_CallRef*)result : *model_->newCallRef ()); + else if (strcmp (name, "Execution") == 0) + result = from_xml (result ? *(ACM_Execution*)result : *model_->newExecution ()); + else if (strcmp (name, "Construction") == 0) + result = from_xml (result ? *(ACM_Construction*)result : *model_->newConstruction ()); + else if (strcmp (name, "Destruction") == 0) + result = from_xml (result ? *(ACM_Destruction*)result : *model_->newDestruction ()); + else if (strcmp (name, "Pointcut") == 0) + result = from_xml (result ? *(ACM_Pointcut*)result : *model_->newPointcut ()); + else if (strcmp (name, "Attribute") == 0) + result = from_xml (result ? *(ACM_Attribute*)result : *model_->newAttribute ()); + else if (strcmp (name, "AdviceCode") == 0) + result = from_xml (result ? *(ACM_AdviceCode*)result : *model_->newAdviceCode ()); + else if (strcmp (name, "Introduction") == 0) + result = from_xml (result ? *(ACM_Introduction*)result : *model_->newIntroduction ()); + else if (strcmp (name, "Order") == 0) + result = from_xml (result ? *(ACM_Order*)result : *model_->newOrder ()); + else if (strcmp (name, "Aspect") == 0) + result = from_xml (result ? *(ACM_Aspect*)result : *model_->newAspect ()); + else if (strcmp (name, "Speculation") == 0) + result = from_xml (result ? *(ACM_Speculation*)result : *model_->newSpeculation ()); + else if (strcmp (name, "Model") == 0) + result = from_xml (result ? *(ACM_Model*)result : *model_->newModel ()); + + if (result) { + result->set_xml_node (node); + result->set_xml_dirty (false); + } + curr_ = old_curr; + unset_child_map (old_child_map); + return result; +} + +XmlModelReader::ChildMap *XmlModelReader::set_child_map (ChildMap &cm, xmlNodePtr node) { + ChildMap *old = child_map_; + child_map_ = &cm; + for (xmlNodePtr c = node->children; c; c = c->next) + child_map_->insert (ChildMap::value_type ((const char*)c->name, c)); + return old; +} + +void XmlModelReader::unset_child_map (ChildMap *cm) { + child_map_ = cm; +} + +xmlNodePtr XmlModelReader::find_child (string name) { + ChildMap::iterator i = child_map_->find (name); + return (i == child_map_->end () ? (xmlNodePtr)0 : (*i).second); +} + +// load the contents of an XML project file into the model +bool XmlModelReader::read (ProjectModel &model, const char *filename, int fd) { + model_ = &model; + model.clear (); + + xmlDocPtr doc; + if (fd >= 0) + doc = xmlReadFd (fd, filename, 0, + XML_PARSE_NODICT | XML_PARSE_NOERROR | + XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS); + else + doc = xmlReadFile (filename, 0, XML_PARSE_NODICT | + XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS); + if (!doc) + return false; + + model.xml_doc (doc); + curr_ = doc->children; + if (!curr_) + return false; + model.set_xml_node(curr_); + ChildMap child_map; + ChildMap *old_child_map = set_child_map (child_map, curr_); + char *str_ids = (char*)xmlGetProp (curr_, (xmlChar*)"ids"); + if (!str_ids) return false; + ids_ = atoi (str_ids); + free (str_ids); + node_map_ = new ModelNode*[ids_]; + memset (node_map_, 0, sizeof (ModelNode*) * ids_); + bool result = alloc_nodes_with_id (curr_); + if (result) { + from_xml (model); + model.set_xml_dirty (false); + } + delete[] node_map_; + unset_child_map (old_child_map); + + // fix jpid management data in the project model + ProjectModel::Selection all; + model.select (JPT_Any, all); + for (ProjectModel::Selection::iterator iter = all.begin (); + iter != all.end (); ++iter) { + ACM_Any &jpl = (ACM_Any&)**iter; + if (jpl.has_jpid ()) + model.alloc_jpid (jpl.get_jpid ()); + } + return result; +} + diff --git a/AspectC++/ACModel/XmlModelReader.h b/AspectC++/ACModel/XmlModelReader.h new file mode 100644 index 0000000..a71c40a --- /dev/null +++ b/AspectC++/ACModel/XmlModelReader.h @@ -0,0 +1,90 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __XmlModelReader_h__ +#define __XmlModelReader_h__ + +#include +#include "Elements.h" + +class XmlModelReader { + + ProjectModel *model_; + xmlNodePtr curr_; + ModelNode **node_map_; + int ids_; + typedef std::map ChildMap; + ChildMap *child_map_; + + // initialize a node and its children from an XML node (tree) + ModelNode *from_xml (ACM_Node &node); + ModelNode *from_xml (ACM_File &node); + ModelNode *from_xml (ACM_TUnit &node); + ModelNode *from_xml (ACM_Header &node); + ModelNode *from_xml (ACM_Source &node); + ModelNode *from_xml (ACM_MemberIntro &node); + ModelNode *from_xml (ACM_BaseIntro &node); + ModelNode *from_xml (ACM_ClassPlan &node); + ModelNode *from_xml (ACM_CodeAdvice &node); + ModelNode *from_xml (ACM_CodePlan &node); + ModelNode *from_xml (ACM_Any &node); + ModelNode *from_xml (ACM_Type &node); + ModelNode *from_xml (ACM_Arg &node); + ModelNode *from_xml (ACM_Name &node); + ModelNode *from_xml (ACM_Namespace &node); + ModelNode *from_xml (ACM_Function &node); + ModelNode *from_xml (ACM_Variable &node); + ModelNode *from_xml (ACM_Class &node); + ModelNode *from_xml (ACM_ClassSlice &node); + ModelNode *from_xml (ACM_Code &node); + ModelNode *from_xml (ACM_Access &node); + ModelNode *from_xml (ACM_Get &node); + ModelNode *from_xml (ACM_Set &node); + ModelNode *from_xml (ACM_Call &node); + ModelNode *from_xml (ACM_Builtin &node); + ModelNode *from_xml (ACM_Ref &node); + ModelNode *from_xml (ACM_GetRef &node); + ModelNode *from_xml (ACM_SetRef &node); + ModelNode *from_xml (ACM_CallRef &node); + ModelNode *from_xml (ACM_Execution &node); + ModelNode *from_xml (ACM_Construction &node); + ModelNode *from_xml (ACM_Destruction &node); + ModelNode *from_xml (ACM_Pointcut &node); + ModelNode *from_xml (ACM_Attribute &node); + ModelNode *from_xml (ACM_Advice &node); + ModelNode *from_xml (ACM_AdviceCode &node); + ModelNode *from_xml (ACM_Introduction &node); + ModelNode *from_xml (ACM_Order &node); + ModelNode *from_xml (ACM_Aspect &node); + ModelNode *from_xml (ACM_Speculation &node); + ModelNode *from_xml (ACM_Model &node); + + // helper functions + bool alloc_nodes_with_id (xmlNodePtr node); + ModelNode *alloc_node (xmlNodePtr node); + ModelNode *initialize_node (xmlNodePtr node); + ChildMap *set_child_map (ChildMap &cm, xmlNodePtr node); + void unset_child_map (ChildMap *cm); + xmlNodePtr find_child (string name); + +public: + // clear model and load the contents of an XML project file into it + bool read (ProjectModel &model, const char *filename, int fd = -1); +}; + +#endif // __XmlModelReader_h__ diff --git a/AspectC++/ACModel/XmlModelWriter.h b/AspectC++/ACModel/XmlModelWriter.h new file mode 100644 index 0000000..fe49ba3 --- /dev/null +++ b/AspectC++/ACModel/XmlModelWriter.h @@ -0,0 +1,52 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __XmlModelWriter_h__ +#define __XmlModelWriter_h__ + +#include "Elements.h" +#include + +class XmlModelWriter { +public: + // save project model as an XML file + bool write (ProjectModel &model, const char *filename, int fd = -1) { + SaveContext context; + xmlDocPtr doc = model.xml_doc (); + if (!doc) { + doc = xmlNewDoc((const xmlChar*)"1.0"); + doc->children = xmlNewDocNode(doc, NULL, (const xmlChar*)"ac-model", NULL); + model.xml_doc (doc); + model.set_xml_node (doc->children); + } + model.to_xml (context); + model.set_xml_dirty (false); + model.set_property ("ids", context.next_id ()); // also save the number of used IDs + if (fd >= 0) { + xmlSaveCtxtPtr ctx = xmlSaveToFd (fd, 0, XML_SAVE_FORMAT); + if (xmlSaveDoc (ctx, doc) == -1) + return false; + return (xmlSaveClose (ctx) != -1); + } + else { + return (xmlSaveFormatFile (filename, doc, 1) != -1); + } + } +}; + +#endif // __XmlModelWriter_h__ diff --git a/AspectC++/ACPreprocessor.h b/AspectC++/ACPreprocessor.h new file mode 100644 index 0000000..5a17c52 --- /dev/null +++ b/AspectC++/ACPreprocessor.h @@ -0,0 +1,36 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __ac_preprocessor_h__ +#define __ac_preprocessor_h__ + +// class alias for frontend-specific preprocessor implementation + +#ifdef FRONTEND_PUMA + +#include "PumaPreprocessor.h" +typedef PumaPreprocessor ACPreprocessor; + +#else // FRONTEND_CLANG + +#include "ClangPreprocessor.h" +typedef ClangPreprocessor ACPreprocessor; + +#endif + +#endif // __ac_preprocessor_h__ diff --git a/AspectC++/ACProject.cc b/AspectC++/ACProject.cc new file mode 100644 index 0000000..0eeccdb --- /dev/null +++ b/AspectC++/ACProject.cc @@ -0,0 +1,684 @@ +#include "ACProject.h" +#include "ACConfig.h" +#include "version.h" +#include "Puma/SysCall.h" +using namespace Puma; + +#ifdef FRONTEND_CLANG +#include "llvm/Support/Host.h" +#include "clang/Basic/Version.h" +#include "clang/Basic/TargetInfo.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/TextDiagnosticPrinter.h" +#include "clang/Rewrite/Core/Rewriter.h" +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_4_0_0 +#include "clang/Lex/PreprocessorOptions.h" +#endif +// for diagnostics +#include "ClangTransformInfo.h" +#include "IntroductionUnit.h" +using namespace clang; +#endif + +#include +#include +#include + +#ifdef FRONTEND_CLANG +ACProject::ACProject (ACErrorStream &err, int &argc, char **&argv) + : PathManager (err), _ci (0), _puma_config (err) { + + if (!_puma_config.CustomSystemConfigFile (argc, argv)) + _puma_config.Read (); // read global config file, e.g. $PUMA_CONFIG + + _puma_config.Read (argc, argv); // read command line config arguments + + // read command line arguments + config ().Add ("-D", "__acweaving", ""); // only defined during weaving phase + + // configure path manager + configure (_puma_config); +} +#else +ACProject::ACProject (ACErrorStream &err, int &argc, char **&argv) + : CProject (err, argc, argv) +{ + config ().Add ("-D", "__acweaving", ""); // only defined during weaving phase +} +#endif + +#ifdef FRONTEND_CLANG +ACProject::~ACProject() { + delete _ci; +} +#endif + +void ACProject::addFiles (xmlDocPtr doc, xmlNodePtr node, const string& xpath) { + xmlXPathContextPtr m_Context = xmlXPathNewContext(doc); + xmlXPathCompExprPtr m_Expr = xmlXPathCompile((const xmlChar*)xpath.c_str());; + xmlXPathObjectPtr m_Result = 0; + if( m_Context != 0 && m_Expr != 0 ) { + m_Result = xmlXPathCompiledEval(m_Expr,m_Context); + if( m_Result != 0 && m_Result->nodesetval != 0 ) { + for( int i=0; inodesetval->nodeNr; ++i ) { + xmlChar* path = xmlGetProp(m_Result->nodesetval->nodeTab[i], + (xmlChar*)"path"); + xmlChar* relpath = xmlGetProp(m_Result->nodesetval->nodeTab[i], + (xmlChar*)"relpath"); + if (path) { + + string destname; + if (numPaths () && dest (0)) { + // make the destination path + destname = dest (0); + char last = destname[destname.length () - 1]; + if (last != '/' && last != '\\') + destname += '/'; +#ifdef WIN32 + SysCall::MakeUnixPath ((char*)relpath); +#endif + destname += (const char*)relpath; + } + else + destname = ""; + + // add the file to the project + PathManager::addFile ((const char*)path, destname.c_str ()); + } + else { + assert (false); + } + if (path != 0) xmlFree(path); + if (relpath != 0) xmlFree(relpath); + } + xmlXPathFreeObject(m_Result); + } + } + if( m_Context ) xmlXPathFreeContext(m_Context); + if( m_Expr ) xmlXPathFreeCompExpr(m_Expr); +} + +// Add a new *virtual* file to the project. +ACFileID ACProject::addVirtualFile (const string &filename, const string &contents) { +#ifdef FRONTEND_PUMA + Unit *unit = Project::addFile (Filename (filename.c_str()), ""); + if (contents != "") { + CScanner scanner (err ()); + scanner.fill_unit (contents.c_str (), *unit); + } + _virtual_files.insert(unit); + return unit; +#else + // Create the ac_gen file to keep clang-based phase1 from crashing. + // FIXME: Hack +// fclose (fopen (filename.c_str (), "w+")); + clang::FileManager &fm = _ci->getFileManager (); + const clang::FileEntry *fe = fm.getVirtualFile (filename, 0, 0); + _ci->getSourceManager().overrideFileContents(fe, + llvm::MemoryBuffer::getMemBufferCopy(contents)); + _virtual_files.insert(ACFileID(fe)); + return fe; +#endif +} + + +// Remove a virtual file +void ACProject::removeVirtualFile (ACFileID fid) { + string filename = fid.name(); +#ifdef FRONTEND_CLANG + // Remove the ac_gen file again. + // FIXME: Hack +// remove (filename.c_str ()); + close (fid); +#else + close (filename.c_str (), true); +#endif +} + +bool ACProject::loadProject (string acprj) { + //std::cout << "try to find project" << std::endl; + if( acprj.empty() == false ) { + //std::cout << "proj file " << acprj << std::endl; + xmlDocPtr doc = xmlParseFile(acprj.c_str()); + if( doc != 0 ) { + xmlNodePtr root = xmlDocGetRootElement(doc); + if( root != 0 ) { + addFiles(doc,root,"/project/source/file"); + addFiles(doc,root,"/project/aspect/file[@active='true']"); + return true; + } + } + } + return false; +} + +#ifdef FRONTEND_CLANG +class Diag : public TextDiagnosticPrinter { + string _msg; + llvm::raw_string_ostream _str_stream; + llvm::raw_ostream &_orig_stream; +public: + Diag(raw_ostream &os, DiagnosticOptions *diags) : + TextDiagnosticPrinter(_str_stream, diags), _str_stream(_msg), + _orig_stream (os) {} + void HandleDiagnostic (DiagnosticsEngine::Level DiagLevel, + const Diagnostic &Info) { + // call Clang's HandleDiagnostic function. Output will be written into _msg. + TextDiagnosticPrinter::HandleDiagnostic(DiagLevel, Info); + + // search for in _msg and replace it with a proper filename + for (unsigned pos = 0; pos < _msg.size(); pos++) { + if (_msg.substr(pos, 7) == "intro(); + if(!intro) { + // No linked AspectC++ model introduction available. This happens when + // Clang emits errors or warning inside code that was *generated* and + // injected by AspectC++ and which therefore has no associated file and + // thus is not inside the model. An example for such code is the struct + // "__TI" which is generated and injected into each class for + // introspection ("--introspection"). + // Output "there is no file and line info": + _orig_stream << ":1:"; + continue; + } + + TI_ClassSlice *slice = 0; + if(intro->has_named_slice()) + slice = TI_ClassSlice::of(*intro->get_named_slice()); + else + slice = TI_ClassSlice::of(*intro->get_anon_slice()); + + // generate the new file and line information + if (unit->is_members_intro()) { + const TI_ClassSlice::SliceBody &body = slice->get_tokens(); + _orig_stream << body.file.name() << ":" << body.line + (line - 1) << ":"; + } + else if (unit->is_base_intro()) { + const TI_ClassSlice::SliceBody &body = slice->get_base_tokens(); + _orig_stream << body.file.name() << ":" << body.line + (line - 1) << ":"; + } + else if (unit->non_inline_member_no() >= 0) { + int no = unit->non_inline_member_no(); + const TI_ClassSlice::SliceBody &body = slice->non_inline_members()[no]; + _orig_stream << body.file.name() << ":" << body.line + (line - 1) << ":"; + } + else + _orig_stream << ":1:"; + continue; + } + _orig_stream << _msg[pos]; + } + _msg.clear(); + } +}; + +void ACProject::create_compiler_instance (ACConfig &conf) { + std::list StringBuf; + SmallVector Args; + Args.push_back("-fsyntax-only"); // Just a dummy action. + + // TODO: this hard-coded stuff should be replaced by a mechanism that + // fetches these settings from the command line + Args.push_back("-disable-free"); + Args.push_back("-fcxx-exceptions"); + Args.push_back("-fexceptions"); + Args.push_back("-pic-level"); + Args.push_back("2"); + Args.push_back("-ftemplate-depth"); + Args.push_back("65536"); + Args.push_back("-fblocks"); + + // Translate Puma's built-in config file into clang arguments. + // Puma already sorts the options and gives system options a lower + // priority than user-provided options. + Config &c = _puma_config; + + // Start with all system options that are not include paths + for (unsigned i = 0; i < c.Options (); i++) { + const ConfOption *o = c.Option (i); + const char *Name = o->Name(); + + // For things like --isystem. + if (strncmp(Name, "--i", 3) == 0) + Name += 1; // Skip first '-'. + + if (!strcmp(Name, "-D")) { + // Enable C++11/14 support if __cplusplus is defined and has the right value + if (strcmp (o->Argument(0), "__cplusplus") == 0) { + if (strcmp (o->Argument(1), "201103L") == 0) // is it C++11? + Args.push_back("-std=c++11"); + else if (strcmp (o->Argument(1), "201300L") == 0 || + strcmp (o->Argument(1), "201402L") == 0) // is it C++14? +#if CLANG_VERSION_NUMBER <= VERSION_NUMBER_3_5_2 + Args.push_back("-std=c++1y"); +#else + Args.push_back("-std=c++14"); +#endif + continue; // no need to copy this macro, clang defines it anyway + } + // Disable definition of macros that Clang will define anyway -- even with "UsePredefines = false". + if (strcmp (o->Argument(0), "__STDC__") == 0 || + strcmp (o->Argument(0), "__STDC_HOSTED__") == 0 || + strcmp (o->Argument(0), "__STDC_VERSION__") == 0 || + strcmp (o->Argument(0), "__STDC_UTF_16__") == 0 || + strcmp (o->Argument(0), "__STDC_UTF_32__") == 0 || + strcmp (o->Argument(0), "__has_include(STR)") == 0 || + strcmp (o->Argument(0), "__has_include_next(STR)") == 0) + continue; + // Don't define the __puma macro when Clang parses the code + if (strcmp (o->Argument(0), "__puma") == 0) + continue; + // otherwise define the macro from the config file/command line in Clang + Args.push_back(Name); + StringBuf.push_back(o->Argument(0) + std::string("=") + o->Argument (1)); + Args.push_back(StringBuf.back().c_str()); + } + // replace the --target option by -triple + else if (!strcmp(Name,"--target")) { + Args.push_back("-triple"); + Args.push_back(o->Argument(0)); + } + // if gnu extensions shall be supported, enable the necessary clang parser options + else if (!strcmp(Name,"--gnu")) { + Args.push_back("-fheinous-gnu-extensions"); // see bug 766 (ignore strange casts of LValues) + } + + // Pass macro definitions and include paths to clang. Everything else is + // Puma-specific and dropped. + if ((strncmp(Name, "-I", 2) && strncmp(Name, "-i", 2))) + continue; + + Args.push_back(Name); + for (unsigned j = 0; j < o->Arguments (); j++) + Args.push_back(o->Argument (j)); + } + + // Add the main TU. + Args.push_back("-x"); + Args.push_back("c++"); + Args.push_back(conf.file_in()); + + // Now create a -cc1 invocation out of the config. + CompilerInstance *new_ci = new CompilerInstance; + // Create diagnostic (= diagnostics engine) (which is used for emitting errors, warnings + // and so on): We use the adapted diagnostic "Diag" (the class "Diag" is defined above) + // which replaces file names and line numbers of code that was injected by AspectC++ + // before outputting it to the console / before showing it to the user. + new_ci->createDiagnostics(new Diag(llvm::errs(), &new_ci->getDiagnosticOpts())); +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_4_0_0 + auto CI = llvm::make_unique(); + CompilerInvocation::CreateFromArgs( *CI, Args.data(), + Args.data() + Args.size(), new_ci->getDiagnostics()); + new_ci->setInvocation(std::move(CI)); +#else + CompilerInvocation *CI = new CompilerInvocation; + CompilerInvocation::CreateFromArgs( *CI, Args.data(), + Args.data() + Args.size(), new_ci->getDiagnostics()); + new_ci->setInvocation(CI); +#endif + + // Create the diagnostics engine again (see above) + // Note: it is important to do this *after* calling 'setInvocation', because otherwise + // the diagnostics options are uninitialized / all false + new_ci->createDiagnostics(new Diag(llvm::errs(), &new_ci->getDiagnosticOpts())); + + // Create vital components. + if (_ci) { + new_ci->setFileManager (&_ci->getFileManager ()); // reference in _ci must be set to 0 later! + // forced includes shall not be modified + new_ci->getInvocation ().getPreprocessorOpts ().Includes = + _ci->getInvocation ().getPreprocessorOpts ().Includes; + } + else + new_ci->createFileManager(); + new_ci->createSourceManager(new_ci->getFileManager()); +// new_ci->setTarget(clang::TargetInfo::CreateTargetInfo(new_ci->getDiagnostics(), +// &new_ci->getTargetOpts())); + const std::shared_ptr targetOptions = std::make_shared(new_ci->getTargetOpts()); +// targetOptions->Triple = llvm::sys::getDefaultTargetTriple(); + clang::TargetInfo *pTargetInfo = clang::TargetInfo::CreateTargetInfo(new_ci->getDiagnostics(), targetOptions); + new_ci->setTarget (pTargetInfo); + + new_ci->getPreprocessorOpts().UsePredefines = false; + + if (_ci) { + // refreshing compiler instance + clang::SourceManager &new_SM = new_ci->getSourceManager (); + clang::SourceManager &SM = _ci->getSourceManager (); + for (clang::SourceManager::fileinfo_iterator fi = SM.fileinfo_begin(), + fe = SM.fileinfo_end(); + fi != fe; ++fi) { + const clang::FileEntry *file_entry = fi->first; + if (_closed_files.find (ACFileID (file_entry)) == _closed_files.end ()) { + if (SM.isFileOverridden(file_entry) && + !new_SM.isFileOverridden(file_entry)) { + // save changes in 'file_entry->getName ()' in the new source manager + const llvm::MemoryBuffer *buf = fi->second->getRawBuffer(); +#if CLANG_VERSION_NUMBER <= VERSION_NUMBER_3_5_2 + llvm::MemoryBuffer *bcopy = llvm::MemoryBuffer::getMemBufferCopy( + buf->getBuffer(), buf->getBufferIdentifier()); + new_SM.overrideFileContents(fi->first, bcopy); +#else // C++ 11 interface + std::unique_ptr bcopy (llvm::MemoryBuffer::getMemBufferCopy( + buf->getBuffer(), buf->getBufferIdentifier())); + new_SM.overrideFileContents(fi->first, std::move(bcopy)); +#endif + } + } + } + _closed_files.clear (); + string main_file = SM.getFileEntryForID (SM.getMainFileID ())->getName (); +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_5_0_0 + new_ci->InitializeSourceManager(clang::FrontendInputFile(main_file, clang::InputKind::CXX)); +#else + new_ci->InitializeSourceManager(clang::FrontendInputFile(main_file, clang::IK_CXX)); +#endif + _ci->setFileManager (0); + } + + // store the new compiler instance, potentially replacing an old one + delete _ci; + _ci = new_ci; +} +#endif + +// Add a forced include to the front end +void ACProject::add_forced_include (const string &file) { + Filename incname; + if (!SysCall::canonical (Filename(file.c_str()), incname)) + return; // error, shouldn't happen +#ifdef FRONTEND_PUMA + config ().Add ("--include", incname.name ()); +#else + std::vector &incs = _ci->getInvocation ().getPreprocessorOpts ().Includes; + incs.push_back (incname.name ()); +#endif +} + +//Remove a forced include from the front end +void ACProject::remove_forced_include (const string &file) { + Filename incname; + if (!SysCall::canonical (Filename(file.c_str()), incname)) + return; // error, shouldn't happen +#ifdef FRONTEND_PUMA + for (unsigned int i = 0; i < config ().Options (); i++) { + const ConfOption *o = config().Option (i); + if (string (o->Name ()) != "--include" || o->Arguments () != 1) + continue; + if (string(incname.name()) == o->Argument (0)) { + config().Remove (o); + break; + } + } +#else + vector &incs = _ci->getInvocation ().getPreprocessorOpts ().Includes; + for (vector::iterator i = incs.begin (); i != incs.end (); ++i) { + if (string(incname.name()) == *i) { + incs.erase (i); + break; + } + } +#endif +} + +// Remove all forced includes +void ACProject::remove_forced_includes () { +#ifdef FRONTEND_PUMA + list delete_opts; + for (unsigned int i = 0; i < config ().Options (); i++) { + const ConfOption *o = config().Option (i); + if (string (o->Name ()) != "--include" || o->Arguments () != 1) + continue; + delete_opts.push_back (o); + } + for (list::iterator i = delete_opts.begin (); + i != delete_opts.end (); ++i) + config().Remove(*i); +#else + _ci->getInvocation ().getPreprocessorOpts ().Includes.clear (); +#endif +} + +// Get the list of forced includes from the front end as a vector of filenames +void ACProject::get_forced_includes (vector &forced_includes) { +#ifdef FRONTEND_PUMA + forced_includes.clear (); + for (unsigned int i = 0; i < config ().Options (); i++) { + const ConfOption *o = config().Option (i); + if (string (o->Name ()) != "--include" || o->Arguments () != 1) + continue; + forced_includes.push_back (o->Argument (0)); + } +#else + forced_includes = _ci->getInvocation ().getPreprocessorOpts ().Includes; +#endif +} + + +Puma::Filename ACProject::getRelInclString (Puma::Filename from, Puma::Filename to) { + + // start be calculating absolute canonical paths for 'to' + Filename to_abs; + if (!SysCall::canonical (to, to_abs)) + return to; + +// cout << "to: " << to_abs.name() << endl; +// cout << "from: " << from_abs.name() << endl; + + // as a first strategy try to find an include path relative to a + // search path (-I option) + for (unsigned i = config ().Options (); i > 0; i--) { + const ConfOption *o = config ().Option (i-1); + if (! strcmp (o->Name (), "-I")) { + if (! o->Arguments ()) + continue; + Filename canon_inc_dir; + if (!SysCall::canonical (o->Argument (0), canon_inc_dir)) + continue; + + int len = strlen (canon_inc_dir.name ()); + if (strncmp (canon_inc_dir.name (), to_abs.name (), len) == 0) + if (*(to_abs.name () + len) == '/') + return to_abs.name () + len + 1; + } + } + + // alternatively generate a path from 'from' to 'to'. + Filename from_abs; + if (!SysCall::canonical (from, from_abs)) + return to_abs; + + // first find the point where the two absolute paths differ, e.g. + // "/foo/bar/abcdef/file.h" + // "/foo/bar/abcxyz/uvw/inc.cc" + // ^-- differ here: last_delim_to + const char *from_pos = from_abs.name(); + const char *to_pos = to_abs.name(); + const char *last_delim_to = 0; + while (*from_pos == *to_pos && *from_pos != '\0' && *to_pos != '\0') { + if (*from_pos == '/') + last_delim_to = to_pos; + from_pos++; + to_pos++; + } + last_delim_to++; + + // now count the number of remaining delimiters in the 'from' path + string buffer; + while (*from_pos != '\0') { + if (*from_pos == '/') + buffer += "../"; + from_pos++; + } + + buffer += last_delim_to; +// cout << "result: " << buffer << endl; + return Puma::Filename(buffer.c_str()); +} + +#ifdef FRONTEND_CLANG +bool ACProject::isNewer (const char *file) const { + + FileInfo fileinfo; + if (! SysCall::stat (file, fileinfo)) + return false; // File does not exists. + long last_modified = fileinfo.modi_time (); + + // determine the destination path of the file + ProjectFile::MapConstIter iter; + if (!PathManager::isBelow (file, iter)) { + assert (false); // if we came here, the file should be registered + return false; + } + + ProjectFile &project_file = (ProjectFile&)iter->second; + Filename dest = project_file.dest (); + if (!dest.is_defined ()) { + // determine the destination path + std::ostringstream path; + if (!getDestinationPath (file, path)) + return false; + string dest_path = path.str (); + project_file.dest (dest_path.c_str ()); + dest = project_file.dest (); + } + + bool newer = true; + if (SysCall::stat (dest.name (), fileinfo)) + if (last_modified <= fileinfo.modi_time ()) + newer = false; + + return newer; +} + +// Save all files that have been opened +void ACProject::save () const { + clang::SourceManager &SM = _ci->getSourceManager(); + for (clang::SourceManager::fileinfo_iterator fi = SM.fileinfo_begin(), + fe = SM.fileinfo_end(); + fi != fe; ++fi) { + const clang::FileEntry *file_entry = fi->first; + if (_closed_files.find(ACFileID(file_entry)) == _closed_files.end()) + save (file_entry, SM.isFileOverridden (file_entry)); + } +} + +bool ACProject::is_protected (clang::FileEntry *file_entry) { + // TODO: implement this function + return false; +} + + +bool ACProject::make_dir_hierarchy (Filename path) const { + + // Remember where we are. + char cwd[PATH_MAX]; + if (SysCall::getcwd (cwd, PATH_MAX, &err ()) == 0) + return false; + + // Change into the directory and create every missing one + char *path_copy = StrCol::dup (path.name ()); + char *p = path_copy; + + // TODO: here is a problem with different drives on Windows!!! + if (path.is_absolute ()) { + SysCall::chdir (path.root (), &err ()); + p += strlen (path.root ()); + } + + char *curr = p; + while (*p != '\0') { + if (*p == '/') { + *p = '\0'; + if (strlen (curr) && ! make_dir (curr)) { + delete[] path_copy; + return false; + } + curr = p + 1; + } + p++; + } + + delete[] path_copy; + + // Go back + SysCall::chdir (cwd, &err ()); + + return true; +} + +bool ACProject::make_dir (const char *directory) const { + while (!SysCall::chdir (directory)) + if (! SysCall::mkdir (directory, &err ())) { + err () << sev_error << "unable to create directory \"" + << directory << "\"." << endMessage; + return false; + } + return true; +} + +// save an opened file to its destination +void ACProject::save (const clang::FileEntry *file_entry, bool is_modified) const { + clang::SourceManager &SM = _ci->getSourceManager(); +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_4_0_0 + const char *name = file_entry->getName ().data(); +#else + const char *name = file_entry->getName (); +#endif + assert (name); + + // Do not write files to protected paths or files from outside the + // source directories. + if (isProtected (name)) + return; + + // determine the destination path of the file + ProjectFile::MapConstIter iter; + if (!PathManager::isBelow (name, iter)) { + assert (false); // if we came here, the file should be registered + return; + } + + ProjectFile &project_file = (ProjectFile&)iter->second; + Filename dest = project_file.dest (); + if (!dest.is_defined ()) { + // determine the destination path + std::ostringstream path; + if (!getDestinationPath (name, path)) + return; + string dest_path = path.str (); + project_file.dest (dest_path.c_str ()); + dest = project_file.dest (); + } + + // make sure that the directory for the file exists + if (!make_dir_hierarchy (dest)) + return; + + // Check whether the file has to be updated. + if (isNewer(name) || is_modified) { + // Write the file to disk. + char *file = (char*)dest.name (); + ofstream out (file, ios::out); + const llvm::MemoryBuffer *mb = SM.getMemoryBufferForFile (file_entry); + out << mb->getBufferStart (); + } + +} + +#endif diff --git a/AspectC++/ACProject.h b/AspectC++/ACProject.h new file mode 100644 index 0000000..6c59817 --- /dev/null +++ b/AspectC++/ACProject.h @@ -0,0 +1,122 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __ACProject_h__ +#define __ACProject_h__ + +// CProject specialization for ac++ project files + +#include +using std::string; +#include +using std::set; + + +#ifdef FRONTEND_CLANG +class ACConfig; +namespace clang { + class CompilerInstance; + class Rewriter; +} +#include "Puma/PathManager.h" +#include "Puma/Config.h" +#else +#include "Puma/CProject.h" +#endif + +#include + +#include "ACErrorStream.h" +#include "ACFileID.h" + +class ACProject : +#ifdef FRONTEND_CLANG + public Puma::PathManager +#else + public Puma::CProject +#endif + { +#ifdef FRONTEND_CLANG + clang::CompilerInstance *_ci; + Puma::Config _puma_config; + set _closed_files; +#endif + set _virtual_files; + + // Add all files from the XML project description to the project + void addFiles (xmlDocPtr doc, xmlNodePtr node, const string& xpath); + +public: + ACProject (ACErrorStream &, int &argc, char **&argv); +#ifdef FRONTEND_CLANG + ~ACProject (); + Puma::Config &config () { return _puma_config; } +#endif + + // load the project file + bool loadProject (string acprj); + + // Add a new *virtual* file to the project. + ACFileID addVirtualFile (const string &filename, const string &contents = ""); + + // Remove a virtual file + void removeVirtualFile (ACFileID fid); + + bool isVirtualFile (ACFileID fid) { + return _virtual_files.find(fid) != _virtual_files.end(); + } + +#ifdef FRONTEND_CLANG + // Create an instance of the clang compiler frontend. + void create_compiler_instance (ACConfig &conf); + clang::CompilerInstance *get_compiler_instance () const { return _ci; } +#endif + +#ifdef FRONTEND_CLANG + ACErrorStream &err () const { return static_cast(Puma::PathManager::err ()); } +#else + ACErrorStream &err () const { return static_cast(Puma::CProject::err ()); } +#endif + + // Add a forced include to the front end + void add_forced_include (const string &file); + + //Remove a forced include from the front end + void remove_forced_include (const string &file); + + // Remove all forced includes + void remove_forced_includes (); + + // Get the list of forced includes from the front end as a vector of filenames + void get_forced_includes (std::vector &forced_includes); + + // Generate a path for including 'to' from within the file 'from' + Puma::Filename getRelInclString (Puma::Filename from, Puma::Filename to); + + #ifdef FRONTEND_CLANG + bool isNewer (const char *) const; + void save () const; + bool is_protected (clang::FileEntry *file_entry); + bool make_dir_hierarchy (Puma::Filename path) const; + bool make_dir (const char *directory) const; + void save (const clang::FileEntry *file_entry, bool is_modified) const; + void close (ACFileID fid) { _closed_files.insert (fid); } +#endif +}; + +#endif /* __ACProject_h__ */ diff --git a/AspectC++/ACResultBuffer.h b/AspectC++/ACResultBuffer.h new file mode 100644 index 0000000..a4d590e --- /dev/null +++ b/AspectC++/ACResultBuffer.h @@ -0,0 +1,36 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __ACResultBuffer_h__ +#define __ACResultBuffer_h__ + +// class alias for frontend-specific preprocessor implementation + +#ifdef FRONTEND_PUMA + +#include "PumaResultBuffer.h" +typedef PumaResultBuffer ACResultBuffer; + +#else // FRONTEND_CLANG + +#include "ClangResultBuffer.h" +typedef ClangResultBuffer ACResultBuffer; + +#endif + +#endif // __ACResultBuffer_h__ diff --git a/AspectC++/ACToken.h b/AspectC++/ACToken.h new file mode 100644 index 0000000..be54e62 --- /dev/null +++ b/AspectC++/ACToken.h @@ -0,0 +1,36 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __ACToken_h__ +#define __ACToken_h__ + +// class alias for frontend-specific token implementation + +#ifdef FRONTEND_PUMA + +#include "PumaToken.h" +typedef PumaToken ACToken; + +#else // FRONTEND_CLANG + +#include "ClangToken.h" +typedef ClangToken ACToken; + +#endif + +#endif // __ACToken_h__ diff --git a/AspectC++/ACUnit.h b/AspectC++/ACUnit.h new file mode 100644 index 0000000..e8bb02a --- /dev/null +++ b/AspectC++/ACUnit.h @@ -0,0 +1,30 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __ACUnit_h__ +#define __ACUnit_h__ + +#include "Puma/CUnit.h" +#include "ACErrorStream.h" + +class ACUnit : public Puma::CUnit { + public: + ACUnit (ACErrorStream &err) : CUnit (err) {} +}; + +#endif // __ACUnit_h__ diff --git a/AspectC++/AdviceInfo.cc b/AspectC++/AdviceInfo.cc new file mode 100644 index 0000000..a65ff0c --- /dev/null +++ b/AspectC++/AdviceInfo.cc @@ -0,0 +1,285 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "AdviceInfo.h" +#include "AspectInfo.h" +#include "Binding.h" +#include "BackEndProblems.h" +#include "TransformInfo.h" + +#include +#include +using std::ostringstream; + +#ifdef FRONTEND_PUMA +#include "Puma/CSemDatabase.h" +#include "Puma/CArgumentInfo.h" +#endif + +using namespace Puma; + +AdviceInfo::AdviceInfo (AspectInfo &ai, ACM_AdviceCode &c) : + _aspect_info (ai), _aspect (ai.loc ()), _code (c) {} + +void AdviceInfo::gen_invocation_func (ostream &out, bool def, + const BackEndProblems &bep) { + +#ifdef FRONTEND_PUMA + CFunctionInfo *ad_func = TI_AdviceCode::of (_code)->function (); + CStructure *ad_cls = ad_func->ClassScope (); +#else + clang::FunctionDecl *ad_func = TI_AdviceCode::of (_code)->decl (); + clang::NamedDecl *ad_cls = llvm::cast(ad_func->getParent ()); +#endif + + const ThisJoinPoint &tjp = TI_AdviceCode::of (_code)->this_join_point (); + const ThisJoinPoint &aspectof_tjp = _aspect_info.aspectof_this_join_point (); + + // determine whether the invocation functions needs JoinPoint, tjp, or Bind. + int first_context_arg = ((_code.get_context() & ACC_OBJ) ? 1 : 0); + bool has_context_var = (_code.get_context() & ACC_VARS); + bool type_needed = tjp.type_advice_needed () || aspectof_tjp.type_advice_needed () || + has_context_var; + bool pointer_needed = tjp.pointer_advice_needed () || has_context_var || + aspectof_tjp.pointer_advice_needed (); + + if (type_needed) + out << " template " << endl; + + out << " "; + if (bep._use_always_inline) + out << "__attribute((always_inline)) "; + + ostringstream suffix; + suffix << signature(_aspect) << "_" << scope_name () << name (); + out << "inline void invoke_" << suffix.str () << " ("; + + if (pointer_needed) + out << "JoinPoint *tjp"; + out << ")" << (def ? " {" : ";") << endl; + + // the declaration ends here + if (!def) + return; + + // generate typedefs + // new implementation might have one argument (tjp) +#ifdef FRONTEND_PUMA + for (int a = first_context_arg; a < (int)ad_func->Arguments (); a++) +#else + for (int a = first_context_arg; a < (int)ad_func->getNumParams (); a++) +#endif +// out << " typedef typename Binding::template Arg<" << a << "> Arg" << a +// << ";" << endl; + out << " typedef typename JoinPoint::Binding_" << suffix.str () + << "::template Arg<" << (a - first_context_arg) << "> Arg" + << (a - first_context_arg) << ";" << endl; + + // generate advice call + out << " "; +#ifdef FRONTEND_PUMA + CClassInfo *aspect_cls = TI_Aspect::of (aspect ())->class_info(); + if (ad_cls != aspect_cls) + out << "((::" << ad_cls->QualName () << "*)"; +#else + clang::Decl *aspect_cls = TI_Aspect::of (aspect ())->decl(); + if (ad_cls != aspect_cls) + out << "((::" << ad_cls->getNameAsString () << "*)"; +#endif + // aspectof function + out << "::" << signature (aspect ()) << "::aspectof"; + // generate if necessary + if (aspectof_tjp.type_advice_needed () && !aspectof_tjp.pointer_advice_needed ()) + out << ""; + out << "("; + if (aspectof_tjp.pointer_advice_needed ()) + out << "tjp"; + out << ")"; + + if (ad_cls != aspect_cls) + out << ")"; + out << "->"; + if (tjp.type_advice_needed () && !tjp.pointer_advice_needed()) + out << "template "; + out << name (); + + // generate if necessary + if (tjp.type_advice_needed () && !tjp.pointer_advice_needed()) + out << ""; + out << " ("; + + int nargs = 0; + + if (tjp.pointer_advice_needed()) { + out << "tjp"; + nargs++; + } + + // new implementation might have one argument (tjp) +#ifdef FRONTEND_PUMA + for (int a = first_context_arg; a < (int)ad_func->Arguments (); a++) { +#else + for (int a = first_context_arg; a < (int)ad_func->getNumParams (); a++) { +#endif + if (nargs > 0) + out << ", "; +#ifdef FRONTEND_PUMA + out << "(" << *ad_func->Argument (a)->TypeInfo () << ")"; +#else + out << "(" << TI_Type::get_type_text(ad_func->getParamDecl(a)->getType(), + &ad_func->getASTContext(), + 0, + TSEF_ENABLE, + false, + TSEF_DONOTCHANGE, + false, + true, + false); + out << ")"; +#endif + out << "Arg" << (a - first_context_arg) << "::val (tjp)"; + nargs++; + } + + out << ");" << endl; + + out << " }" << endl; +} + + +void AdviceInfo::gen_invocation_func_call (ostream &stmt, const char* tjp_tp, + const char *tjp_obj) { + const ThisJoinPoint &tjp = TI_AdviceCode::of (_code)->this_join_point (); + const ThisJoinPoint &aspectof_tjp = _aspect_info.aspectof_this_join_point (); + + // determine whether the invocation functions needs JoinPoint or tjp + // new implementation has at least one argument + int first_context_arg = ((_code.get_context() & ACC_OBJ) ? 1 : 0); +#ifdef FRONTEND_PUMA + bool has_context = ((int) TI_AdviceCode::of (_code)->function ()->Arguments () > first_context_arg); +#else + bool has_context = ((int) TI_AdviceCode::of (_code)->decl ()->getNumParams() > first_context_arg); +#endif + bool type_needed = tjp.type_advice_needed () || aspectof_tjp.type_advice_needed () || + has_context; + bool pointer_needed = tjp.pointer_advice_needed () || has_context || + aspectof_tjp.pointer_advice_needed (); + + stmt << "AC::invoke_" << signature (_aspect) << "_" + << scope_name () << name (); + + if (type_needed) { + stmt << "<" << tjp_tp; +// if (has_context) { +// string tp (tjp_tp); +// tp.erase (tp.length () - 2, tp.length ()); +// stmt << ", Binding_" << tp << "_0_" << _aspect->name () << "_" +// << Scope ()->Name () << "_" << (name () + 1); +// } + stmt << ">"; + } + + stmt << " ("; + if (pointer_needed) + stmt << tjp_obj; + stmt << ");"; +} + + +void AdviceInfo::gen_binding_template (ostream &out, const char *jpname, + const BackEndProblems &bep) { + // later this will be passed as an argument + Binding &bind = binding (); + + // no code generation if no context variables are expected + if (!bind._used) + return; + + // generate the mapping of context variables to advice function arguments + out << "struct Binding_" /* << jpname << "_" */ << signature(_aspect) << "_" + << scope_name () << "_" << (name ().c_str() + 1) << " {" << endl; + out << " typedef " /* << jpname*/ << "__TJP" << " TJP;" << endl; + out << " template struct Arg {" << endl; + out << " void val (TJP *tjp) {} // for VC7" << endl; + out << " };" << endl; + + typedef ACM_Container Container; + Container &arguments = _code.get_pointcut()->get_args(); + int a = 0; + for (Container::iterator i = arguments.begin (); i != arguments.end (); ++i, ++a) { +#ifdef FRONTEND_PUMA + const Puma::CTypeInfo * curr_type = TI_Arg::of(*(*i))->type_info(); + const bool is_pointer = curr_type->isPointer(); + // Determine whether the current type is a reference type: + const bool is_reference = curr_type->isAddress(); +#else + // Buffer the current clang::QualType: + const clang::QualType curr_type = TI_Arg::of(*(*i))->type(); + const bool is_pointer = curr_type->isPointerType (); + // Determine whether the current type is a reference type: + const bool is_reference = curr_type->isReferenceType(); +#endif + int bind_index = bind.bound_to (*i); + assert (bind_index != Binding::BIND_NOT_FOUND); + out << " template <"; + if (bep._spec_scope) + out << "int DUMMY"; + out << "> struct Arg<" << a; + if (bep._spec_scope) + out << ", DUMMY"; + out << "> {" << endl + << " static typename TJP::"; + switch (bind_index) { + case Binding::BIND_THAT: + out << "That " << (is_pointer ? "*" : "&") + << "val (TJP *tjp) { return " << (is_pointer ? "" : "*") + << "tjp->that (); }" << endl; + break; + case Binding::BIND_TARGET: + out << "Target " << (is_pointer ? "*" : "&") + << "val (TJP *tjp) { return " << (is_pointer ? "" : "*") + << "tjp->target (); }" << endl; + break; + case Binding::BIND_RESULT: + out << "Res::ReferredType &val (TJP *tjp) { return " << (is_reference ? "*" : "") << "*tjp->result (); }" << endl; + break; + case Binding::BIND_NOT_FOUND: // already handled by assertion + break; + default: // argument + out << "template Arg<" << bind_index << ">::ReferredType &val (TJP *tjp) {" + << " return *tjp->template arg<" << bind_index << "> (); }" << endl; + } + out << " };" << endl; + } + + out << "};" << endl; +} +std::string AdviceInfo::name () { return TI_AdviceCode::of (_code)->name (); } + +void AdviceInfo::addTJPFlags(ThisJoinPoint &tjp) { + tjp.merge (TI_AdviceCode::of (code ())->this_join_point ()); + tjp.merge (aspect_info().aspectof_this_join_point()); + + ThisJoinPoint context_vars; + context_vars.setup (binding ()); + tjp.merge (context_vars); +} + diff --git a/AspectC++/AdviceInfo.h b/AspectC++/AdviceInfo.h new file mode 100644 index 0000000..917f924 --- /dev/null +++ b/AspectC++/AdviceInfo.h @@ -0,0 +1,68 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __AdviceInfo_h__ +#define __AdviceInfo_h__ + +#include +using namespace std; + +#include "PointCut.h" +#include "Binding.h" +#include "BackEndProblems.h" +#include "PointCutExpr.h" +#include "ACModel/Elements.h" + +class AspectInfo; +class ThisJoinPoint; + +class AdviceInfo { + + AspectInfo &_aspect_info; + ACM_Aspect &_aspect; + PointCut _pointcut; + Binding _binding; + PointcutExpression _pointcut_expr; + ACM_AdviceCode &_code; + +public: + AdviceInfo (AspectInfo &ai, ACM_AdviceCode &c); + + ACM_Aspect &aspect () const { return _aspect; } + ACM_AdviceCode &code () const { return _code; } + AspectInfo &aspect_info () const { return _aspect_info; } + PointCut &pointcut () { return _pointcut; } + Binding &binding () { return _binding; } + PointcutExpression &pointcut_expr () { return _pointcut_expr; } + + void gen_invocation_func (ostream &out, bool def, const BackEndProblems &bep); + void gen_invocation_func_call (ostream &stmt, const char* tjp_tp, + const char *tjp_obj); + + void gen_binding_template (ostream &out, const char *jpname, + const BackEndProblems &bep); + + std::string scope_name() { return signature(*(ACM_Aspect*)_code.get_parent()); } + std::string name (); + AdviceCodeType type() { return _code.get_kind(); } + + // add the TJP-flags of this advice to the given tjp object + void addTJPFlags(ThisJoinPoint &tjp); +}; + +#endif // __AdviceInfo_h__ diff --git a/AspectC++/AdviceRepo.cc b/AspectC++/AdviceRepo.cc new file mode 100644 index 0000000..6a5e5be --- /dev/null +++ b/AspectC++/AdviceRepo.cc @@ -0,0 +1,91 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 +#include +#include "AdviceRepo.h" +#include "RepoXMLNode.h" + +int AdviceRepo::insert (int file_id, int line, const string &type, int asp, + int lines) { + Map::iterator entry = _map.find (RepoPosAspectKey (file_id, line, asp)); + if (entry != _map.end ()) { + Data &data = (*entry).second; + data._ref = true; + return data._id; + } + int id = new_id (); + _map.insert (MapPair (RepoPosAspectKey (file_id, line, asp), + Data (id, type, lines))); + return id; +} + +void AdviceRepo::noref () { + for (Map::iterator curr = _map.begin (); curr != _map.end (); ++curr) { + Data &data = (*curr).second; + data._ref = false; + } +} + +void AdviceRepo::cleanup (set files) { + std::list to_delete; + for (Map::iterator curr = _map.begin (); curr != _map.end (); ++curr) { + Data &data = (*curr).second; + const RepoPosAspectKey &key = (*curr).first; + if (!data._ref && files.count (key.file_id ()) == 1) { + to_delete.push_back(key); + } + } + list::iterator c; + for (c = to_delete.begin(); c != to_delete.end(); ++c) { + _map.erase(*c); + } +} + +void AdviceRepo::make_xml (RepoXMLNode parent) { + + RepoXMLNode aspects = parent.make_child ("advice-list"); + + for (Map::iterator curr = _map.begin (); curr != _map.end (); ++curr) { + RepoXMLNode an = aspects.make_child ("advice"); + const RepoPosAspectKey &key = (*curr).first; + key.make_xml (an); + + const Data &data = (*curr).second; + an.set_int_prop ("id", data._id); + an.set_str_prop ("type", data._type.c_str ()); + an.set_int_prop ("lines", data._lines); + } +} + +void AdviceRepo::get_xml (RepoXMLNode parent) { + reset_id (); + for (RepoXMLNode::iter curr = parent.first_child (); + curr != parent.end_child (); ++curr) { + RepoXMLNode an = *curr; + if (an.has_name ("advice")) { + int id = an.get_int_prop ("id"); + string type = an.get_str_prop ("type"); + int lines = an.get_int_prop ("lines"); + + _map.insert (MapPair (RepoPosAspectKey (an), + Data (id, type.c_str (), lines))); + update (id); + } + } +} diff --git a/AspectC++/AdviceRepo.h b/AspectC++/AdviceRepo.h new file mode 100644 index 0000000..8d4c3dd --- /dev/null +++ b/AspectC++/AdviceRepo.h @@ -0,0 +1,59 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __AdviceRepo_h__ +#define __AdviceRepo_h__ + +#include +#include +#include +using namespace std; + +#include +#include "RepoPosAspectKey.h" +#include "RepoIdMgr.h" +#include "RepoXMLNode.h" + +class AdviceRepo : public RepoIdMgr { + + struct Data { + int _id; + string _type; + int _lines; + bool _ref; + Data (int id, const string &type, int lines) : + _id (id), _type (type), _lines (lines), _ref (true) {} + }; + typedef map Map; + typedef Map::value_type MapPair; + Map _map; + +public: + + int insert (int file_id, int line, const string &type, int asp, int lines); + + void noref (); + + void cleanup (set files); + + void make_xml (RepoXMLNode parent); + + void get_xml (RepoXMLNode parent); +}; + +#endif // __AdviceRepo_h__ diff --git a/AspectC++/AspectIncludeCluster.h b/AspectC++/AspectIncludeCluster.h new file mode 100644 index 0000000..8db3a53 --- /dev/null +++ b/AspectC++/AspectIncludeCluster.h @@ -0,0 +1,37 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __AspectIncludeCluster_h__ +#define __AspectIncludeCluster_h__ + +#include + +#include "ACFileID.h" + +// This is a simple container for storing a reference to an aspect header file +// and the set of aspect headers that are also needed for the respective aspect +// header, because they affect files that are included by it. + +struct AspectIncludeCluster { + ACFileID _aspect; + std::set _cluster; // including '_aspect' + AspectIncludeCluster(ACFileID aspect_fid) : _aspect(aspect_fid) {} + void set_cluster(const std::set &cluster) { _cluster = cluster; } +}; + +#endif // __AspectIncludeCluster_h__ diff --git a/AspectC++/AspectIncludes.cc b/AspectC++/AspectIncludes.cc new file mode 100644 index 0000000..897c022 --- /dev/null +++ b/AspectC++/AspectIncludes.cc @@ -0,0 +1,108 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "AspectIncludes.h" +#include "AspectInfo.h" +#include "Naming.h" +#include "TransformInfo.h" +#include "ACProject.h" + +#ifdef FRONTEND_CLANG +#include "clang/Frontend/CompilerInstance.h" +#else +#include "Puma/Unit.h" +#include "Puma/CTree.h" +#include "Puma/CProject.h" +#include "Puma/Filename.h" +#endif + +// helper function that find the unit in which an advice code is defined +ACFileID AspectIncludes::aspect_unit (ACM_Aspect *a) const { +#ifdef FRONTEND_CLANG + clang::SourceManager &sm = _project.get_compiler_instance ()->getSourceManager (); + clang::FileID fid = sm.getFileID(TransformInfo::decl(*a)->getLocation()); + return sm.getFileEntryForID (fid); +} +#else + return TI_Aspect::unit (*a); +} +#endif + +// this function declares that a unit 'iu' depends on the aspect 'ai' +void AspectIncludes::insert (ACFileID iu, AspectInfo *a, AspectRef::Kind kind) { + assert (iu.is_valid()); + + // check if there is already an entry for this unit + iterator entry = find (iu); + if (entry == end ()) { + // there is no entry for the unit 'iu' yet => make a new one + AspectRefSet new_set; + new_set.insert (AspectRef (a, kind)); + UnitAspectRefMap::insert (value_type (iu, new_set)); + } + else { + // entry found add the aspect reference to the stored set + AspectRefSet &set = (*entry).second; + AspectRefSet::iterator ref_entry = + set.find (AspectRef (a, AspectRef::AR_UNKNOWN)); + if (ref_entry == set.end ()) { + // simply insert a new entry if the aspect has not been found + set.insert (AspectRef (a, kind)); + } + else { + // a definition request dominates a declaration request... + AspectRef &ref = (AspectRef&)(*ref_entry); + if (kind > ref._kind) + ref._kind = kind; + } + } +} + +// generate the #include directives for a given unit +string AspectIncludes::generate (const_iterator entry, + const BackEndProblems &bep) const { + string includes; + const AspectRefSet &set = (*entry).second; + for (AspectRefSet::const_iterator iter = set.begin (); + iter != set.end (); ++iter) { + + switch ((*iter)._kind) { + case AspectRef::AR_DECL: + includes += "class "; + includes += (*iter)._aspect->name (); + includes += ";\n"; + break; + case AspectRef::AR_ADVICE: + { + includes += (*iter)._aspect->ifct_decls (bep); + ACFileID unit = aspect_unit (&(*iter)._aspect->loc ()); + stringstream define; + define << "#ifndef __ac_need_"; + Naming::mangle_file (define, /*(Puma::FileUnit*)*/unit); + define << endl << "#define __ac_need_"; + Naming::mangle_file (define, /*(Puma::FileUnit*)*/unit); + define << endl << "#endif" << endl; + includes += define.str (); + } + break; + default: + cout << "aspect ref type not yet implemented" << endl; + } + } + return includes; +} diff --git a/AspectC++/AspectIncludes.h b/AspectC++/AspectIncludes.h new file mode 100644 index 0000000..3b22408 --- /dev/null +++ b/AspectC++/AspectIncludes.h @@ -0,0 +1,93 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __AspectIncludes_h__ +#define __AspectIncludes_h__ + +#include +using std::set; +#include +using std::map; +#include +using std::string; + +#ifdef FRONTEND_CLANG +#include "clang/Basic/SourceManager.h" +#endif + +namespace Puma { + class Unit; + class CProject; +} // namespace Puma + +#include "ACFileID.h" + +class AspectInfo; +class ACM_Aspect; +struct BackEndProblems; +class ACProject; + +// this class manages all #includes and forward declarations, which have to be +// generated in order to make the aspects visible at the join points they affect + +struct AspectRef { + AspectInfo *_aspect; + // Kind of dependency: the value defines the importance + enum Kind { AR_UNKNOWN = 0, AR_DECL = 1, AR_ADVICE = 2 } _kind; + bool operator < (const AspectRef &cmp) const { + return _aspect < cmp._aspect; + } + bool operator == (const AspectRef &cmp) const { + return _aspect == cmp._aspect; + } + AspectRef (AspectInfo *a, Kind k) : _aspect (a), _kind (k) {} +}; + +typedef set AspectRefSet; +typedef map UnitAspectRefMap; + +class AspectIncludes : private UnitAspectRefMap { + + ACProject &_project; + + // helper function that find the file (id) in which an aspect 'ai' is defined + ACFileID aspect_unit (ACM_Aspect *a) const; + +public: + + AspectIncludes (ACProject &prj) : _project (prj) {} + + // this function declares that a unit 'iu' depends on the aspect 'a' + // ('kind' specifies the kind of dependency, i.e. class def, decl, or advice) + void insert (ACFileID iu, AspectInfo *a, AspectRef::Kind kind); + + // iterator type and functions to access the elements (only const access) + typedef UnitAspectRefMap::const_iterator const_iterator; + const_iterator begin () const { return UnitAspectRefMap::begin (); } + const_iterator end () const { return UnitAspectRefMap::end (); } + + // searching ... + using UnitAspectRefMap::find; + // get the target unit associated with an entry + ACFileID unit (const_iterator entry) const { return (*entry).first; } + + // generate the #include directives for a given unit + string generate (const_iterator entry, const BackEndProblems &bep) const; +}; + +#endif // __AspectIncludes_h__ diff --git a/AspectC++/AspectInfo.cc b/AspectC++/AspectInfo.cc new file mode 100644 index 0000000..e2a172f --- /dev/null +++ b/AspectC++/AspectInfo.cc @@ -0,0 +1,74 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "AspectInfo.h" +#include "AdviceInfo.h" +// +//#include "Puma/CFunctionInfo.h" +// +//// for workaround +//#include "Puma/CSemDatabase.h" +//#include "Puma/CTree.h" +// +//CFunctionInfo *AspectInfo::aspectof () { +// // make this better! +// CFunctionInfo *aof = ClassInfo ()->Function ("aspectof"); +// if (!aof) +// aof = ClassInfo ()->Function ("aspectOf"); +// return aof ? aof->DefObject () : (CFunctionInfo*)0; +// +//} +// +// generate the invocation function forward declarations +string AspectInfo::ifct_decls (const BackEndProblems &bep) const { + + // name of this aspect + string me (name ()); + + string decls = string ("\n") + + "#ifndef __ac_fwd_" + me + "__\n" + "#define __ac_fwd_" + me + "__\n" + "class " + me + ";\n" + "namespace AC {\n"; + + stringstream ifct_decls; + for (list::const_iterator iter = _advice_infos.begin (); + iter != _advice_infos.end (); ++iter) { + (*iter)->gen_invocation_func (ifct_decls, false, bep); + } + decls += ifct_decls.str (); + + decls += "}\n"; + decls += "#endif\n\n"; + + return decls; +} + +// generate the invocation function definitions +string AspectInfo::ifct_defs (const BackEndProblems &bep) const { + + stringstream defs; + defs << endl; + defs << "namespace AC {" << endl; + for (list::const_iterator iter = _advice_infos.begin (); + iter != _advice_infos.end (); ++iter) { + (*iter)->gen_invocation_func (defs, true, bep); + } + defs << "} " << endl; + return defs.str (); +} diff --git a/AspectC++/AspectInfo.h b/AspectC++/AspectInfo.h new file mode 100644 index 0000000..c9c6e86 --- /dev/null +++ b/AspectC++/AspectInfo.h @@ -0,0 +1,61 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __AspectInfo_h__ +#define __AspectInfo_h__ + +#include +using std::list; +#include +using std::set; +#include +using std::string; + +#include "ACModel/Utils.h" +#include "ThisJoinPoint.h" + +struct BackEndProblems; +class AdviceInfo; + +class AspectInfo { + ACM_Aspect &_aspect; + ThisJoinPoint _aspectof_tjp; + list _advice_infos; + + public: + + AspectInfo (ACM_Aspect &a) : _aspect (a) {} + bool operator < (const AspectInfo &right) const { + return name() < right.name(); + } + ACM_Aspect &loc () const { return _aspect; } + string name () const { return signature (_aspect); } + const ThisJoinPoint &aspectof_this_join_point () const { return _aspectof_tjp; } + ThisJoinPoint &aspectof_this_join_point () { return _aspectof_tjp; } + + // the list of associated code advice nodes + list &advice_infos () { return _advice_infos; } + + // generate the invocation function forward declarations + string ifct_decls (const BackEndProblems &) const; + + // generate the invocation function definitions + string ifct_defs (const BackEndProblems &) const; +}; + +#endif // __AspectInfo_h__ diff --git a/AspectC++/AspectRepo.cc b/AspectC++/AspectRepo.cc new file mode 100644 index 0000000..1970856 --- /dev/null +++ b/AspectC++/AspectRepo.cc @@ -0,0 +1,86 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 +#include "AspectRepo.h" +#include "RepoXMLNode.h" + +int AspectRepo::insert (int file_id, int line, const string &name) { + Map::iterator entry = _map.find (RepoPosKey (file_id, line)); + if (entry != _map.end ()) { + Data &data = (*entry).second; + data._ref = true; + return data._id; + } + + int id = new_id (); + _map.insert (MapPair (RepoPosKey (file_id, line), Data (id, name))); + return id; +} + +void AspectRepo::noref () { + for (Map::iterator curr = _map.begin (); curr != _map.end (); ++curr) { + Data &data = (*curr).second; + data._ref = false; + } +} + +void AspectRepo::cleanup (set files) { + list to_delete; + for (Map::iterator curr = _map.begin (); curr != _map.end (); ++curr) { + Data &data = (*curr).second; + const RepoPosKey &key = (*curr).first; + if (!data._ref && files.count (key.file_id ()) == 1) { + to_delete.push_back(key); + } + } + list::iterator c; + for (c = to_delete.begin(); c != to_delete.end(); ++c) { + _map.erase(*c); + } +} + +void AspectRepo::make_xml (RepoXMLNode parent) { + + RepoXMLNode aspects = parent.make_child ("aspect-list"); + + for (Map::iterator curr = _map.begin (); curr != _map.end (); ++curr) { + RepoXMLNode an = aspects.make_child ("aspect"); + const RepoPosKey &key = (*curr).first; + key.make_xml (an); + + const Data &data = (*curr).second; + an.set_int_prop ("id", data._id); + an.set_str_prop ("name", data._name.c_str ()); + } +} + +void AspectRepo::get_xml (RepoXMLNode parent) { + reset_id (); + for (RepoXMLNode::iter curr = parent.first_child (); + curr != parent.end_child (); ++curr) { + RepoXMLNode an = *curr; + if (an.has_name ("aspect")) { + int id = an.get_int_prop ("id"); + string name = an.get_str_prop ("name"); + + _map.insert (MapPair (RepoPosKey (an), Data (id, name.c_str ()))); + update (id); + } + } +} diff --git a/AspectC++/AspectRepo.h b/AspectC++/AspectRepo.h new file mode 100644 index 0000000..46f29c6 --- /dev/null +++ b/AspectC++/AspectRepo.h @@ -0,0 +1,58 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __AspectRepo_h__ +#define __AspectRepo_h__ + +#include + +#include +#include +#include +using namespace std; + +#include "RepoPosKey.h" +#include "RepoIdMgr.h" +#include "RepoXMLNode.h" + +class AspectRepo : public RepoIdMgr { + + struct Data { + int _id; + string _name; + bool _ref; + Data (int id, const string &name) : _id (id), _name (name), _ref (true) {} + }; + typedef map Map; + typedef Map::value_type MapPair; + Map _map; + +public: + + int insert (int file_id, int line, const string &name); + + void noref (); + + void cleanup (set files); + + void make_xml (RepoXMLNode parent); + + void get_xml (RepoXMLNode parent); +}; + +#endif // __AspectRepo_h__ diff --git a/AspectC++/BackEndProblems.h b/AspectC++/BackEndProblems.h new file mode 100644 index 0000000..b0d03a8 --- /dev/null +++ b/AspectC++/BackEndProblems.h @@ -0,0 +1,34 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __BackEndProblems_h__ +#define __BackEndProblems_h__ + +#include +using std::string; + +// this structure describes the problems of the back-end compiler +struct BackEndProblems { + bool _local_class; + bool _spec_scope; + bool _use_always_inline; + bool _warn_macro; + bool _warn_deprecated; +}; + +#endif // __BackEndProblems_h__ diff --git a/AspectC++/Binding.cc b/AspectC++/Binding.cc new file mode 100644 index 0000000..ef99475 --- /dev/null +++ b/AspectC++/Binding.cc @@ -0,0 +1,57 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "Binding.h" + +void Binding::clear () { + _used = false; + _this = 0; + _target = 0; + _args.reset (); + _result = 0; +} + +bool Binding::operator == (const Binding &other) const { + if (!_used && !other._used) + return true; + if (_this != other._this || _target != other._target || + _args.length () != other._args.length () || _result != other._result) + return false; + for (int i = 0; i < _args.length (); i++) { + if (_args.lookup (i) != other._args.lookup (i)) + return false; + } + return true; +} + +int Binding::bound_to (ACM_Arg *arg) const { + if (_used) { + if (arg == _this) + return BIND_THAT; + else if (arg == _target) + return BIND_TARGET; + else if (arg == _result) + return BIND_RESULT; + else { + for (int a = 0; a < _args.length (); a++) + if (arg == _args.lookup (a)) + return a; + } + } + return BIND_NOT_FOUND; +} diff --git a/AspectC++/Binding.h b/AspectC++/Binding.h new file mode 100644 index 0000000..8e16ccc --- /dev/null +++ b/AspectC++/Binding.h @@ -0,0 +1,45 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __Binding_h__ +#define __Binding_h__ + +#include "Puma/Array.h" + +class ACM_Arg; + +class Binding { +public: + enum { BIND_THAT = -1, BIND_TARGET = -2, BIND_RESULT = -3, + BIND_NOT_FOUND = -4 }; + bool _used; + ACM_Arg* _this; + ACM_Arg* _target; + Puma::Array _args; + ACM_Arg *_result; + + Binding () { clear (); } + void clear (); + bool operator == (const Binding &other) const; + bool operator != (const Binding &other) const { + return !(*this == other); + } + int bound_to (ACM_Arg*) const; +}; + +#endif // __Binding_h__ diff --git a/AspectC++/CFlow.cc b/AspectC++/CFlow.cc new file mode 100644 index 0000000..747b0ff --- /dev/null +++ b/AspectC++/CFlow.cc @@ -0,0 +1,48 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "CFlow.h" +#include "AdviceInfo.h" +#include "Naming.h" + +void CFlowList::gen_trigger_obj (ostream &out) const { + int i = 0; + for (const_iterator iter = begin (); iter != end (); ++iter) { + out << " "; + Naming::cflow (out, (*iter).advice_info ()->aspect (), (*iter).index ()); + out << " trigger" << i << ";" << endl; + i++; + } +} + +const string &CFlow::ac_namespace_contributions () { + static const string cflow_template = + " template \n" + " struct CFlow {\n" + " static int &instance () {\n" + " static int counter = 0;\n" + " return counter;\n" + " }\n" + " CFlow () { instance ()++; }\n" + " ~CFlow () { instance ()--; }\n" + " static bool active () { return instance () > 0; }\n" + " };\n"; + return cflow_template; +} + + diff --git a/AspectC++/CFlow.h b/AspectC++/CFlow.h new file mode 100644 index 0000000..10de9d0 --- /dev/null +++ b/AspectC++/CFlow.h @@ -0,0 +1,48 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __CFlow_h__ +#define __CFlow_h__ + +#include +#include +#include +using namespace std; + +class AdviceInfo; + +class CFlow { + + AdviceInfo *_advice; + int _index; + +public: + CFlow (AdviceInfo *ai, int i) : _advice (ai), _index (i) {} + AdviceInfo *advice_info () const { return _advice; } + int index () const { return _index; } + static const string &ac_namespace_contributions (); +}; + +class CFlowList : public list { + public: + void gen_trigger_obj (ostream&) const; +}; + +#endif // __CFlow_h__ + + diff --git a/AspectC++/ClangASTConsumer.cc b/AspectC++/ClangASTConsumer.cc new file mode 100644 index 0000000..b1ece72 --- /dev/null +++ b/AspectC++/ClangASTConsumer.cc @@ -0,0 +1,1361 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2013 The 'ac++' developers (see aspectc.org) +// +// 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 "ClangASTConsumer.h" +#include "clang/Basic/Version.h" +#include "clang/AST/ASTContext.h" +#include +#include "ClangAnnotation.h" +#include "version.h" + +using namespace clang; + + +bool ClangASTConsumer::isInProject(clang::Decl *D) { + PresumedLoc PL = _sm->getPresumedLoc(D->getLocation()); + StringRef Name = PL.getFilename(); + StringRef BufferName = _sm->getBufferName(D->getLocation()); + assert(!Name.startswith("( decl ) ) + _outer._parent_map[ dc ] = element; + } +} + +bool ClangASTConsumer::DeclContextStack::isCurrentContextValid() { + // current decl context does not exist inside of project + if( _outer._decl_stack.empty() || ! _outer.isInProject( _outer._decl_stack.back().first ) ) + return false; + + return true; +} + +ClangASTConsumer::JPContext ClangASTConsumer::DeclContextStack::getJPContext() { + assert( ! _outer._decl_stack.empty() ); + ClangASTConsumer::JPContext ctx; + + clang::Decl *decl = _outer._decl_stack.back().first; + ctx.parent_decl = decl; + + if( FunctionDecl *fd = dyn_cast( decl ) ) + ctx.parent = _outer._parent_map[fd]; + else if( RecordDecl *rd = dyn_cast( decl ) ) + ctx.parent = _outer._parent_map[rd]; + else if( VarDecl *vd = dyn_cast( decl ) ) + ctx.parent = _decl_map[vd]; + else // should not happen => abort + assert( false && "This should not happen: programming error !" ); + + ctx.local_id = _outer._last_fn_local_id++; + return ctx; +} + +clang::Decl *ClangASTConsumer::DeclContextStack::getCurrentDecl() { + assert( ! _outer._decl_stack.empty() ); + return _outer._decl_stack.back().first; +} + +bool ClangASTConsumer::VisitType(clang::Type *Ty) { + // Revisit template instances, there may be new ones we didn't see the first + // time. + if (CXXRecordDecl *RD = Ty->getAsCXXRecordDecl()) + if (ClassTemplateSpecializationDecl *CTSD = + dyn_cast(RD)) +#if CLANG_VERSION_NUMBER <= VERSION_NUMBER_3_5_2 + if (!_parent_map.count(CTSD) && _seen_specs.insert(CTSD)) +#else // C++ 11 interface + if (!_parent_map.count(CTSD) && _seen_specs.insert(CTSD).second) +#endif + return TraverseCXXRecordDecl(CTSD); + + return true; +} + +bool ClangASTConsumer::VisitNamespaceDecl(NamespaceDecl *D) { + ACM_Name *parent = _parent_map[D->getDeclContext()]; + TU_Namespace *nameSp = _model.register_namespace(D, parent); + _parent_map[D] = nameSp; + + if (nameSp && _model.conf().attributes()) + _model.handle_attributes(nameSp, D); + + return true; +} + +bool ClangASTConsumer::VisitCXXRecordDecl(CXXRecordDecl *D) { + if (!isInProject(D) || D->isLocalClass ()) + return true; + +// D = D->getDefinition(); +// if (!D) +// return true; +// + ACM_Name *parent = _parent_map[D->getDeclContext()]; + + ACM_Class *jpl_class = _model.register_aspect(D, parent); + if (!jpl_class) + jpl_class = _model.register_class(D, parent); + + if (!jpl_class) + return true; + + _parent_map[D] = jpl_class; + + // for class definitions attribute handling is done by the introducer + if(_model.conf().attributes() && !D->isThisDeclarationADefinition()) + _model.handle_attributes(jpl_class, D); + + if (D->isThisDeclarationADefinition() && jpl_class->type_val () == JPT_Aspect) { + ACM_Aspect *jpl_aspect = (ACM_Aspect*)jpl_class; + //_vm << (is_abstract (*jpl_aspect) ? "Abstract" : "Concrete") + // << " aspect " << signature (*jpl_aspect) << endvm; + //_vm++; + _model.advice_infos (jpl_aspect); + //_vm--; + } + + return true; +} + +bool ClangASTConsumer::VisitFunctionDecl(FunctionDecl *D) { + if (!isInProject(D)) + return true; + + // functions defined in local classes must be ignored + clang::CXXRecordDecl *cd = clang::dyn_cast(D->getDeclContext()); + if (cd && cd->isLocalClass ()) + return true; + + // ignore local function declarations + if (D->getLexicalParent ()->isFunctionOrMethod ()) + return true; + + // functions that are template instances or members of template instances + // must be ignored + // strange: an instance node should not be visited anyway! + if (D->getInstantiatedFromMemberFunction ()) + return true; + +// cout << "VisitFunctionDecl " << D->getQualifiedNameAsString() << endl; + ACM_Name *parent = _parent_map[D->getDeclContext()]; + _parent_map[D] = _model.register_pointcut(D, parent); + if (!_parent_map[D]) { + if (TU_Function *func = _model.register_function(D, parent)) { + // There may be a new redeclaration, add it. + + if(_model.conf().attributes()) + _model.handle_attributes(func, D); + + func->add_decl(D); + _parent_map[D] = func; + } + } + + return true; +} + +bool ClangASTConsumer::VisitVarDecl( VarDecl *VD ) { + if( ! isInProject( VD ) ) + return true; + + if( VD->getType()->isReferenceType() && ! VD->isFileVarDecl() ) + return true; // skip references for now, but only if they are not on the top level as we need these as context for joinpoints + +#if 0 + const clang::Expr *init_expr = VD->getInit(); + if (init_expr && VD->getInitStyle() == clang::VarDecl::CInit) { + if (dyn_cast(init_expr)) + cout << "initialized var" << VD->getNameAsString () << endl; + } +#endif + + ACM_Name *parent = _parent_map[VD->getDeclContext()]; + if( parent && parent->type_val() == JPT_Function ) + return true;// skip local variables for now + if( TU_Variable *var = _model.register_variable( VD, parent ) ) { + // remember model object, we might need it as context + _context_stack.updateContextWithCurrentElement( VD, var ); + + if (_model.conf().attributes()) + _model.handle_attributes(var, VD); + } + return true; +} + +bool ClangASTConsumer::VisitFieldDecl( clang::FieldDecl *FD ) { + if( ! isInProject( FD ) ) + return true; + + if( FD->getType()->isReferenceType() ) + return true; // skip references for now + + ACM_Name *parent = _parent_map[FD->getDeclContext()]; + TU_Variable *var = _model.register_variable( FD, parent ); + + if (var && _model.conf().attributes()) + _model.handle_attributes(var, FD); + + return true; +} + +bool ClangASTConsumer::VisitDeclRefExpr( clang::DeclRefExpr *RE ) { + if( ! _model.conf().data_joinpoints() ) // only data joinpoints need this information so far, so supress handling if not required + return true; + + if( !_expr_stack.considerSubtree() || _expr_stack.empty() || ! _expr_stack.peek().isValidSubExpr() ) + return true; // skip as nobody is interested in the information + + // ignore invalid scope + if( ! _context_stack.isCurrentContextValid() ) + return true; + + clang::VarDecl *VD = clang::dyn_cast_or_null( RE->getDecl() ); + clang::FunctionDecl *FD = clang::dyn_cast_or_null( RE->getDecl() ); + + if( VD ) { + if( ! isInProject( VD ) ) + return true; + + bool is_ref = VD->getType()->isReferenceType(); + + TU_Variable *var = 0; + if( ! is_ref ) { + var = _model.register_variable( VD ); + if( !var ) + return true; + } + + // push collected information to expr traversal stack to be processed when all informations there + if( ! _expr_stack.empty() && _expr_stack.peek().isValidSubExpr() ) { + _expr_stack.peek().pushEntityRefNode( RE ); + if( ! is_ref ) + _expr_stack.peek().pushEntityInfo( var, VD ); + } + } + else if( FD ) { + // currently we need only the RefNode for some check in call context + // full handling has to be added later + + // push collected information to expr traversal stack to be processed when all informations there + if( ! _expr_stack.empty() && _expr_stack.peek().isValidSubExpr() ) { + _expr_stack.peek().pushEntityRefNode( RE ); + } + } + + return true; +} + +// find member entities +// further we need to act as context for the base expr traversal +// we dont care for information from it yet, +// but else other data is corrupted +bool ClangASTConsumer::TraverseMemberExpr( clang::MemberExpr *ME ) { + // only consider evaluated subtrees and additionally: only data joinpoints need this information so far, so supress handling if not required + if( ! _expr_stack.considerSubtree() || ! _model.conf().data_joinpoints() ) + return RecursiveASTVisitor::TraverseMemberExpr( ME ); + + DummyContext ctx( *this ); + _expr_stack.push( ctx ); + + bool result = RecursiveASTVisitor::TraverseMemberExpr( ME ); + + assert( &_expr_stack.peek() == &ctx ); + _expr_stack.drop(); + + // ignore invalid scope + if( ! _context_stack.isCurrentContextValid() ) + return result; + + clang::DeclaratorDecl *DD = clang::dyn_cast_or_null( ME->getMemberDecl() ); // maybe refine because IndirectFieldDecl / EnumConstant + if( ! DD ) + return result; + + if( llvm::isa( DD ) || llvm::isa( DD ) ) { + if( ! isInProject( DD ) ) + return result; + + bool is_ref = DD->getType()->isReferenceType(); + + TU_Variable *var = 0; + if( ! is_ref ) { + var = _model.register_variable( DD ); + if( !var ) + return result; + } + + // push collected information to expr traversal stack to be processed when all informations are collected + if( ! _expr_stack.empty() && _expr_stack.peek().isValidSubExpr() ) { + _expr_stack.peek().pushEntityRefNode( ME ); + if( ! is_ref ) + _expr_stack.peek().pushEntityInfo( var, DD ); + } + } + else if( llvm::isa( DD ) ) { + // currently we need only the RefNode for some check in call context + // full handling has to be added later + + // push collected information to expr traversal stack to be processed when all informations there + if( ! _expr_stack.empty() && _expr_stack.peek().isValidSubExpr() ) { + _expr_stack.peek().pushEntityRefNode( ME ); + } + } + + return result; +} + +// on traversing an array access we need to find the var reference in base +bool ClangASTConsumer::TraverseArraySubscriptExpr( clang::ArraySubscriptExpr *ASE ) { + if( !_expr_stack.considerSubtree() ) + return RecursiveASTVisitor::TraverseArraySubscriptExpr( ASE ); + + if( ! _model.conf().data_joinpoints() ) { + bool result = RecursiveASTVisitor::TraverseArraySubscriptExpr( ASE ); + handle_built_in_operator_traverse( ASE ); + return result; + } + + ArrayAccessContext ctx( *this, ASE ); + _expr_stack.push( ctx ); + + bool result = RecursiveASTVisitor::TraverseArraySubscriptExpr( ASE ); + TU_Builtin *op = handle_built_in_operator_traverse( ASE ); + + if( op ) + ctx.updateOperator( op ); + + assert( &_expr_stack.peek() == &ctx ); + _expr_stack.drop(); + + if( ! op ) // return early if the element where not registered + return result; + + // push info about forwarder onto stack + if( ! _expr_stack.empty() && _expr_stack.peek().isValidSubExpr() ) { + _expr_stack.peek().pushEntityForwardingJP( op ); + } + + return result; +} + +// Override Traverse functions to build an expression stack for EntityReference classification +// checking which subExpr we are in, normally we could use TraverseExpr(...) but that does not exists +bool ClangASTConsumer::TraverseStmt( clang::Stmt* S ) { + clang::Expr *E = 0; + if( _model.conf().data_joinpoints() && _expr_stack.considerSubtree() && ! _expr_stack.empty() && _expr_stack.peek().isSearching() ) { + if( ( E = dyn_cast_or_null( S ) ) ) { + _expr_stack.peek().enterSubExpr( E ); + } + } + + bool result = RecursiveASTVisitor::TraverseStmt( S ); + + if( E ) { + assert( ! _expr_stack.empty() ); + _expr_stack.peek().registerJPforSubExpr(); + _expr_stack.peek().leaveSubExpr( E ); + } + + return result; +} + +// build the context handlers on the traversal stack as place to collect information about EntityReferences +bool ClangASTConsumer::TraverseImplicitCastExpr( clang::ImplicitCastExpr *ICE ) { + if( ! _model.conf().data_joinpoints() || ! _expr_stack.considerSubtree() ) + return RecursiveASTVisitor::TraverseImplicitCastExpr( ICE ); + + bool result; + if( ICE->getCastKind() == clang::CK_LValueToRValue ) { + SingleGetContext ctx( *this, ICE, ICE->getSubExpr() ); + _expr_stack.push( ctx ); + + result = RecursiveASTVisitor::TraverseImplicitCastExpr( ICE ); + + assert( &_expr_stack.peek() == &ctx ); + _expr_stack.drop(); + ctx.registerJPforContext(); + } + else if( ICE->getCastKind() == clang::CK_ArrayToPointerDecay && ! ( ! _expr_stack.empty() && _expr_stack.peek().suppressDecayJPs() ) ) { + SingleRefContext ctx( *this, ICE, ICE->getSubExpr() ); + _expr_stack.push( ctx ); + + result = RecursiveASTVisitor::TraverseImplicitCastExpr( ICE ); + + assert( &_expr_stack.peek() == &ctx ); + _expr_stack.drop(); + ctx.registerJPforContext(); + } + else + result = RecursiveASTVisitor::TraverseImplicitCastExpr( ICE ); + + return result; +} + +bool ClangASTConsumer::TraverseUnaryAddrOf( clang::UnaryOperator *UO ) { + if( !_expr_stack.considerSubtree() ) + return RecursiveASTVisitor::TraverseUnaryAddrOf( UO ); + + if( ! _model.conf().data_joinpoints() ) { + bool result = RecursiveASTVisitor::TraverseUnaryAddrOf( UO ); + handle_built_in_operator_traverse( UO ); + return result; + } + + SingleRefContext ctx( *this, UO, UO->getSubExpr() ); + _expr_stack.push( ctx ); + + bool result = RecursiveASTVisitor::TraverseUnaryAddrOf( UO ); + TU_Builtin *op = handle_built_in_operator_traverse( UO ); + + if( op ) + ctx.updateOperator( op ); + + assert( &_expr_stack.peek() == &ctx ); + _expr_stack.drop(); + ctx.registerJPforContext(); + + return result; +} + +bool ClangASTConsumer::TraverseReturnStmt( clang::ReturnStmt *RS ) { + clang::FunctionDecl *FD = llvm::dyn_cast( _context_stack.getCurrentDecl() ); + if( ! _model.conf().data_joinpoints() || ! _expr_stack.considerSubtree() || + ! FD->getReturnType().getTypePtr()->isReferenceType() ) + return RecursiveASTVisitor::TraverseReturnStmt( RS ); + + SingleRefContext ctx( *this, RS->getRetValue(), RS->getRetValue() ); + _expr_stack.push( ctx ); + + bool result = RecursiveASTVisitor::TraverseReturnStmt( RS ); + + assert( &_expr_stack.peek() == &ctx ); + _expr_stack.drop(); + ctx.registerJPforContext(); + + return result; +} + +bool ClangASTConsumer::TraverseUnaryDeref( clang::UnaryOperator *UO ) { + if( !_expr_stack.considerSubtree() ) + return RecursiveASTVisitor::TraverseUnaryDeref( UO ); + + if( ! _model.conf().data_joinpoints() ) { + bool result = RecursiveASTVisitor::TraverseUnaryDeref( UO ); + handle_built_in_operator_traverse( UO ); + return result; + } + + DummyContext ctx( *this ); + _expr_stack.push( ctx ); + + bool result = RecursiveASTVisitor::TraverseUnaryDeref( UO ); + handle_built_in_operator_traverse( UO ); + + assert( &_expr_stack.peek() == &ctx ); + _expr_stack.drop(); + + // ignore invalid scope + if( ! _context_stack.isCurrentContextValid() ) + return result; + + // push collected information to expr traversal stack to be processed when all informations are collected + if( ! _expr_stack.empty() && _expr_stack.peek().isValidSubExpr() ) { + _expr_stack.peek().pushEntityRefNode( UO ); + } + + return result; +} + +bool ClangASTConsumer::TraverseBinComma( clang::BinaryOperator *BO ) { + if( !_expr_stack.considerSubtree() ) + return RecursiveASTVisitor::TraverseBinComma( BO ); + + if( ! _model.conf().data_joinpoints() ) { + bool result = RecursiveASTVisitor::TraverseBinComma( BO ); + // disable short-circuit evalaluating operator + // handle_built_in_operator_traverse( BO ); + return result; + } + + BinaryForwardContext ctx( *this, BO->getLHS(), BO->getRHS(), BinaryForwardContext::SEI_RHS ); + _expr_stack.push( ctx ); + + bool result = RecursiveASTVisitor::TraverseBinComma( BO ); +// disable left-to-right evalaluating operator +// handle_built_in_operator_traverse( BO ); + + assert( &_expr_stack.peek() == &ctx ); + _expr_stack.drop(); + + return result; +} + +bool ClangASTConsumer::TraverseBinAssign( clang::BinaryOperator *BO ) { + if( !_expr_stack.considerSubtree() ) + return RecursiveASTVisitor::TraverseBinAssign( BO ); + + if( ! _model.conf().data_joinpoints() ) { + bool result = RecursiveASTVisitor::TraverseBinAssign( BO ); + handle_built_in_operator_traverse( BO ); + return result; + } + + AssignmentContext ctx( *this, BO ); + _expr_stack.push( ctx ); + + bool result = RecursiveASTVisitor::TraverseBinAssign( BO ); + TU_Builtin *op = handle_built_in_operator_traverse( BO ); + + if( op ) + ctx.updateOperator( op ); + + assert( &_expr_stack.peek() == &ctx ); + _expr_stack.drop(); + ctx.registerJPforContext(); + + return result; +} + +#if FRONTEND_CLANG < 38 +bool ClangASTConsumer::hookTraverseCompoundAssign( FwdCall_CAssign fwd, clang::CompoundAssignOperator *CAO ) { +#else +bool ClangASTConsumer::hookTraverseCompoundAssign( FwdCall_CAssign fwd, clang::CompoundAssignOperator *CAO, DataRecursionQueue *Q ) { +#endif + if( !_expr_stack.considerSubtree() ) +#if FRONTEND_CLANG < 38 + return (this->*fwd)( CAO ); +#else + return (this->*fwd)( CAO, Q ); +#endif + + if( ! _model.conf().data_joinpoints() ) { +#if FRONTEND_CLANG < 38 + bool result = (this->*fwd)( CAO ); +#else + bool result = (this->*fwd)( CAO, Q ); +#endif + handle_built_in_operator_traverse( CAO ); + return result; + } + + AssignmentContext ctx( *this, CAO ); + _expr_stack.push( ctx ); + +#if FRONTEND_CLANG < 38 + bool result = (this->*fwd)( CAO ); +#else + bool result = (this->*fwd)( CAO, Q ); +#endif + TU_Builtin *op = handle_built_in_operator_traverse( CAO ); + + if( op ) + ctx.updateOperator( op ); + + assert( &_expr_stack.peek() == &ctx ); + _expr_stack.drop(); + ctx.registerJPforContext(); + + return result; +} + +#if FRONTEND_CLANG < 38 +bool ClangASTConsumer::hookTraversePrePost( FwdCall_PrePost fwd, clang::UnaryOperator *UO ) { +#else +bool ClangASTConsumer::hookTraversePrePost( FwdCall_PrePost fwd, clang::UnaryOperator *UO, DataRecursionQueue *Q ) { +#endif + if( !_expr_stack.considerSubtree() ) +#if FRONTEND_CLANG < 38 + return (this->*fwd)( UO ); +#else + return (this->*fwd)( UO, Q ); +#endif + + if( ! _model.conf().data_joinpoints() ) { +#if FRONTEND_CLANG < 38 + bool result = (this->*fwd)( UO ); +#else + bool result = (this->*fwd)( UO, Q ); +#endif + handle_built_in_operator_traverse( UO ); + return result; + } + + AssignmentContext ctx( *this, UO ); + _expr_stack.push( ctx ); + +#if FRONTEND_CLANG < 38 + bool result = (this->*fwd)( UO ); +#else + bool result = (this->*fwd)( UO, Q ); +#endif + TU_Builtin *op = handle_built_in_operator_traverse( UO ); + + if( op ) + ctx.updateOperator( op ); + + assert( &_expr_stack.peek() == &ctx ); + _expr_stack.drop(); + ctx.registerJPforContext(); + + return result; +} + +bool ClangASTConsumer::TraverseConditionalOperator( clang::ConditionalOperator* CO ) { + if( !_expr_stack.considerSubtree() ) + return RecursiveASTVisitor::TraverseConditionalOperator( CO ); + + if( ! _model.conf().data_joinpoints() ) { + bool result = RecursiveASTVisitor::TraverseConditionalOperator( CO ); + handle_built_in_operator_traverse( CO ); + return result; + } + + DummyContext ctx( *this ); + _expr_stack.push( ctx ); + + bool result = RecursiveASTVisitor::TraverseConditionalOperator( CO ); + + handle_built_in_operator_traverse( CO ); + + assert( &_expr_stack.peek() == &ctx ); + _expr_stack.drop(); + + return result; +} + +bool ClangASTConsumer::TraverseBinPtrMemD( clang::BinaryOperator *BO ) { + if( !_expr_stack.considerSubtree() ) + return RecursiveASTVisitor::TraverseBinPtrMemD( BO ); + + if( ! _model.conf().data_joinpoints() ) { + bool result = RecursiveASTVisitor::TraverseBinPtrMemD( BO ); + handle_built_in_operator_traverse( BO ); + return result; + } + + DummyContext ctx( *this ); + _expr_stack.push( ctx ); + + bool result = RecursiveASTVisitor::TraverseBinPtrMemD( BO ); + handle_built_in_operator_traverse( BO ); + + assert( &_expr_stack.peek() == &ctx ); + _expr_stack.drop(); + + return result; +} + +bool ClangASTConsumer::TraverseBinPtrMemI( clang::BinaryOperator *BO ) { + if( !_expr_stack.considerSubtree() ) + return RecursiveASTVisitor::TraverseBinPtrMemI( BO ); + + if( ! _model.conf().data_joinpoints() ) { + bool result = RecursiveASTVisitor::TraverseBinPtrMemI( BO ); + handle_built_in_operator_traverse( BO ); + return result; + } + + DummyContext ctx( *this ); + _expr_stack.push( ctx ); + + bool result = RecursiveASTVisitor::TraverseBinPtrMemI( BO ); + handle_built_in_operator_traverse( BO ); + + assert( &_expr_stack.peek() == &ctx ); + _expr_stack.drop(); + + return result; +} + +bool ClangASTConsumer::TraverseUnaryExprOrTypeTraitExpr( clang::UnaryExprOrTypeTraitExpr *subtree ) { + _expr_stack.beginIgnoreTree(); + + bool result = RecursiveASTVisitor::TraverseUnaryExprOrTypeTraitExpr( subtree ); + + _expr_stack.endIgnoreTree(); + + return result; +} + +// enable dummy mode if ParmVar is assosiated with already handled function tree +bool ClangASTConsumer::TraverseParmVarDecl( clang::ParmVarDecl *VD ) { + // check if the current (function-)declaration is a redeclaration + // if so we enable dummymode as we have already processed the default argument tree + bool enable_DM = ! _dummy_mode && ( ! _decl_stack.empty() && _decl_stack.back().first->getPreviousDecl() != 0 ); + + if( enable_DM ) + _dummy_mode = true; + + bool result; + if( _model.conf().data_joinpoints() && _expr_stack.considerSubtree() && VD->hasInit() && VD->getType().getTypePtr()->isReferenceType() ) { + SingleRefContext ctx( *this, VD->getDefaultArg(), VD->getDefaultArg() ); + ctx.ignoreTypeInfo( VD->getTypeSourceInfo() ); + _expr_stack.push( ctx ); + + result = RecursiveASTVisitor::TraverseParmVarDecl( VD ); + + assert( &_expr_stack.peek() == &ctx ); + _expr_stack.drop(); + ctx.registerJPforContext(); + } + else { + result = RecursiveASTVisitor::TraverseParmVarDecl( VD ); + } + + if( enable_DM ) // disable dummymode again if we enabled it + _dummy_mode = false; + + return result; +} + +// TraverseDeclaratorHelper is private, so we need to catch the cases here +bool ClangASTConsumer::TraverseTypeLoc( clang::TypeLoc TL ) { + // check if we have to ignore the whole tree as parts of type references are off limits for weaving + bool ignore = _expr_stack.considerSubtree() && ! _expr_stack.empty() && _expr_stack.peek().shouldIgnoreTypeInfo( TL ); + if( ignore ) + _expr_stack.beginIgnoreTree(); + + bool result = RecursiveASTVisitor::TraverseTypeLoc( TL ); + + if( ignore ) + _expr_stack.endIgnoreTree(); + + return result; +} + +// Override traverse functions so we can build up a stack of scopes. +bool ClangASTConsumer::TraverseVarDecl( clang::VarDecl *VD ) { + // Only remember the scope for stand alone vardecls. + if( VD->isFileVarDecl() ) + _decl_stack.push_back( std::make_pair( VD, _last_fn_local_id ) ); + + bool result; + if( _model.conf().data_joinpoints() && _expr_stack.considerSubtree() && VD->hasInit() && VD->getType().getTypePtr()->isReferenceType() ) { + SingleRefContext ctx( *this, VD->getInit(), VD->getInit() ); + ctx.ignoreTypeInfo( VD->getTypeSourceInfo() ); + _expr_stack.push( ctx ); + + result = RecursiveASTVisitor::TraverseVarDecl( VD ); + + assert( &_expr_stack.peek() == &ctx ); + _expr_stack.drop(); + ctx.registerJPforContext(); + } + else { + result = RecursiveASTVisitor::TraverseVarDecl( VD ); + } + + if( VD->isFileVarDecl() ) + _decl_stack.pop_back(); + return result; +} + +bool ClangASTConsumer::TraverseFunctionDecl(clang::FunctionDecl *FD) { + _decl_stack.push_back(std::make_pair(FD, _last_fn_local_id)); + _last_fn_local_id = 0; + bool result = RecursiveASTVisitor::TraverseFunctionDecl(FD); + _last_fn_local_id = _decl_stack.pop_back_val().second; + return result; +} + +bool ClangASTConsumer::TraverseCXXMethodDecl(clang::CXXMethodDecl *FD) { + _decl_stack.push_back(std::make_pair(FD, _last_fn_local_id)); + _last_fn_local_id = 0; + bool result = RecursiveASTVisitor::TraverseCXXMethodDecl(FD); + _last_fn_local_id = _decl_stack.pop_back_val().second; + return result; +} + +bool ClangASTConsumer::TraverseCXXConstructorDecl(clang::CXXConstructorDecl *FD) { + _decl_stack.push_back(std::make_pair(FD, _last_fn_local_id)); + _last_fn_local_id = 0; + bool result = RecursiveASTVisitor::TraverseCXXConstructorDecl(FD); + _last_fn_local_id = _decl_stack.pop_back_val().second; + return result; +} + +bool ClangASTConsumer::TraverseCXXConversionDecl(clang::CXXConversionDecl *FD) { + _decl_stack.push_back(std::make_pair(FD, _last_fn_local_id)); + _last_fn_local_id = 0; + bool result = RecursiveASTVisitor::TraverseCXXConversionDecl(FD); + _last_fn_local_id = _decl_stack.pop_back_val().second; + return result; +} + +bool ClangASTConsumer::TraverseCXXDestructorDecl(clang::CXXDestructorDecl *FD) { + _decl_stack.push_back(std::make_pair(FD, _last_fn_local_id)); + _last_fn_local_id = 0; + bool result = RecursiveASTVisitor::TraverseCXXDestructorDecl(FD); + _last_fn_local_id = _decl_stack.pop_back_val().second; + return result; +} + +bool ClangASTConsumer::TraverseRecordDecl(clang::RecordDecl *RD) { + _decl_stack.push_back(std::make_pair(RD, _last_fn_local_id)); + bool result = RecursiveASTVisitor::TraverseRecordDecl(RD); + _decl_stack.pop_back(); + return result; +} + +bool ClangASTConsumer::TraverseCXXRecordDecl(clang::CXXRecordDecl *RD) { + _decl_stack.push_back(std::make_pair(RD, _last_fn_local_id)); + bool result = RecursiveASTVisitor::TraverseCXXRecordDecl(RD); + _decl_stack.pop_back(); + return result; +} + +// defining Traverse... instead of VisitCallExpr guarantees that calls nested +// in argument lists, e.g. foo(nested()) are registered first. +bool ClangASTConsumer::TraverseCallExpr(clang::CallExpr *CE) { + if( !_expr_stack.considerSubtree() ) + return RecursiveASTVisitor::TraverseCallExpr( CE ); + + if( ! _model.conf().data_joinpoints() ) { + bool result = RecursiveASTVisitor::TraverseCallExpr(CE); + if (CE->getCallee()->IgnoreParenImpCasts()->getType()->isFunctionPointerType()) + handle_built_in_operator_traverse(CE); // handle as built-in dereference + RegisterCallExpr(CE); + return result; + } + + CallContext ctx( *this, CE ); + _expr_stack.push( ctx ); + + bool result = RecursiveASTVisitor::TraverseCallExpr(CE); + if (CE->getCallee()->IgnoreParenImpCasts()->getType()->isFunctionPointerType()) + handle_built_in_operator_traverse(CE); // handle as built-in dereference + RegisterCallExpr(CE); + + assert( &_expr_stack.peek() == &ctx ); + _expr_stack.drop(); + ctx.registerJPforContext(); + + return result; +} + +bool ClangASTConsumer::TraverseCXXMemberCallExpr(clang::CXXMemberCallExpr *CE) { + if( !_expr_stack.considerSubtree() ) + return RecursiveASTVisitor::TraverseCXXMemberCallExpr( CE ); + + if( ! _model.conf().data_joinpoints() ) { + bool result = RecursiveASTVisitor::TraverseCXXMemberCallExpr(CE); + RegisterCallExpr(CE); + return result; + } + + CallContext ctx( *this, CE ); + _expr_stack.push( ctx ); + + bool result = RecursiveASTVisitor::TraverseCXXMemberCallExpr(CE); + RegisterCallExpr(CE); + + assert( &_expr_stack.peek() == &ctx ); + _expr_stack.drop(); + ctx.registerJPforContext(); + + return result; +} + +bool ClangASTConsumer::TraverseCXXOperatorCallExpr(clang::CXXOperatorCallExpr *CE) { + if( !_expr_stack.considerSubtree() ) + return RecursiveASTVisitor::TraverseCXXOperatorCallExpr( CE ); + + if( ! _model.conf().data_joinpoints() ) { + bool result = RecursiveASTVisitor::TraverseCXXOperatorCallExpr(CE); + RegisterCallExpr(CE); + return result; + } + + CallContext ctx( *this, CE ); + _expr_stack.push( ctx ); + + bool result = RecursiveASTVisitor::TraverseCXXOperatorCallExpr(CE); + RegisterCallExpr(CE); + + assert( &_expr_stack.peek() == &ctx ); + _expr_stack.drop(); + ctx.registerJPforContext(); + + return result; +} + +bool ClangASTConsumer::TraverseCXXTemporaryObjectExpr( clang::CXXTemporaryObjectExpr *TOE ) { + if( ! _model.conf().data_joinpoints() || !_expr_stack.considerSubtree() ) + return RecursiveASTVisitor::TraverseCXXTemporaryObjectExpr( TOE ); + + CallContext ctx( *this, TOE ); + _expr_stack.push( ctx ); + + bool result = RecursiveASTVisitor::TraverseCXXTemporaryObjectExpr( TOE ); + + assert( &_expr_stack.peek() == &ctx ); + _expr_stack.drop(); + ctx.registerJPforContext(); + + return result; +} + +void ClangASTConsumer::RegisterCallExpr(CallExpr *CE) { + // Ignore CallExprs in (inline) functions outside of the project. + if (_decl_stack.empty() || !isInProject(_decl_stack.back().first)) + return; + + clang::FunctionDecl *Callee = dyn_cast_or_null(CE->getCalleeDecl()); + if (Callee) { + // Ignore explicit destructor calls + // TODO: Is that really what the user wants? + if (dyn_cast (Callee)) + return; + + // Ignore calls to functions with a local forward decl only. + bool only_local_decls = true; + for (clang::FunctionDecl::redecl_iterator ri = Callee->redecls_begin(), + re = Callee->redecls_end(); + ri != re; ++ri) { + if (!ri->getLexicalParent()->isFunctionOrMethod()) + only_local_decls = false; + } + if (only_local_decls) + return; + } + + if( ! _dummy_mode ) { + DeclaratorDecl *DD = dyn_cast(_decl_stack.back().first); + if (DD) // ignore calls without proper context, e.g. typedef decltype(somecall()) T; + _model.register_call(Callee, CE, DD, _last_fn_local_id++); + } + else + _last_fn_local_id++; +} + +// This method handles a traverse over a built-in operator. +TU_Builtin * ClangASTConsumer::handle_built_in_operator_traverse(Expr* built_in_operator) { + // Is the current scope valid? + if( _decl_stack.empty() || ! isInProject(_decl_stack.back().first) ) + return 0; + + // Try to cast the clang::Decl to a clang::DeclaratorDecl ... + clang::DeclaratorDecl* lexical_parent_decl = dyn_cast(_decl_stack.back().first); + // ... and only consider the declaration, if it came out of a declarator: + if( ! lexical_parent_decl ) + return 0; + + // Registers the built-in-operator-call in the AspectC++-model + if( ! _dummy_mode ) + return _model.register_builtin_operator_call(built_in_operator, lexical_parent_decl, _last_fn_local_id++); + else { + _last_fn_local_id++; + return 0; + } +} + +void ClangASTConsumer::SingleAccessContext::enterSubExpr( clang::Expr *sub ) { + assert( sub == _child ); + assert( getMode() == Mode_Search ); + + setCurSubExprIndex( 0 ); +} + +void ClangASTConsumer::SingleAccessContext::leaveSubExpr( clang::Expr *sub ) { + assert( sub == _child ); + assert( getCurSubExprIndex() == 0 ); + + setMode( Mode_Done ); +} + +void ClangASTConsumer::SingleAccessContext::pushEntityRefNode( clang::Expr *RE ) { + assert( isValidSubExpr() ); + + // null values are not allowed, skip calling in that case + assert( RE ); + + // double calling is not allowed, it indicates some error in the AST traversal + assert( ! _var_info.ref_node ); + + _var_info.ref_node = RE; +} + +void ClangASTConsumer::SingleAccessContext::pushEntityInfo( ACM_Variable *var, clang::DeclaratorDecl *VD ) { + assert( isValidSubExpr() ); + + // null values are not allowed, skip calling in that case + assert( var ); + assert( VD ); + + // double calling is not allowed, it indicates some error in the AST traversal + assert( ! _var_info.element ); + assert( ! _var_info.decl ); + + _var_info.element = var; + _var_info.decl = VD; +} + +void ClangASTConsumer::SingleAccessContext::pushEntityForwardingJP( TU_Builtin *JP ) { + assert( isValidSubExpr() ); + + // null values are not allowed, skip calling in that case + assert( JP ); + + // double calling is not allowed, it indicates some error in the AST traversal + assert( ! _var_src ); + + _var_src = JP; +} + +void ClangASTConsumer::SingleGetContext::registerJPforContext() { + if( _var_info.ref_node ) { // check if we found some reference ... + ClangModelBuilder::JoinpointContext ctx = _consumer._context_stack.getJPContext(); + if( ! _consumer._dummy_mode ) + _consumer._model.register_get( _var_info, ctx, _var_src ); // ... and register + } +} + +void ClangASTConsumer::SingleRefContext::registerJPforContext() { + if( _var_info.element && _var_info.decl && _var_info.ref_node ) { // check if we found some reference ... + ClangModelBuilder::JoinpointContext ctx = _consumer._context_stack.getJPContext(); + if( _op_call ) // on implicit joinpoints + ctx.parent = _op_call; // change parent element to call node + + if( ! _consumer._dummy_mode ) + _consumer._model.register_ref( _var_info, ctx, _op_call ? _op_call : _var_src ); // ... and register + } +} + +void ClangASTConsumer::SingleRefContext::updateOperator( TU_Builtin *op ) { + _op_call = op; // remember for implicit joinpoints + + op->forwarded_src( _var_src ); // remeber the dependency chain +} + +void ClangASTConsumer::BinaryClassificationContext::enterSubExpr( clang::Expr *sub ) { + assert( sub == _lhs || sub == _rhs ); + + if( isSearching() ) { + if( sub == _lhs ) + setCurSubExprIndex( SEI_LHS ); + else if( sub == _rhs ) + setCurSubExprIndex( SEI_RHS ); + } +} + +void ClangASTConsumer::BinaryClassificationContext::leaveSubExpr( clang::Expr *sub ) { + assert( getMode() == Mode_Done || ( sub == _lhs && getCurSubExprIndex() == SEI_LHS ) || ( sub == _rhs && getCurSubExprIndex() == SEI_RHS ) ); + + setMode( Mode_Search ); +} + +void ClangASTConsumer::BinaryForwardContext::enterSubExpr( clang::Expr *sub ) { + if( getParent() == 0 ) + setMode( Mode_Done ); // with nothing to forward to, we're done already + else + BinaryClassificationContext::enterSubExpr( sub ); +} + +void ClangASTConsumer::BinaryForwardContext::leaveSubExpr( clang::Expr *sub ) { + bool done = ( getCurSubExprIndex() == _forward ); + + BinaryClassificationContext::leaveSubExpr( sub ); + + if( done ) + setMode( Mode_Done ); +} + +void ClangASTConsumer::BinaryForwardContext::pushEntityRefNode( clang::Expr *RE ) { + // if already done just ignore new data + if( getMode() == Mode_Done ) + return; + + assert( isValidSubExpr() ); + + if( getCurSubExprIndex() == _forward ) { // only forward data from chosen subexpr + getParent()->pushEntityRefNode( RE ); + } +} + +void ClangASTConsumer::BinaryForwardContext::pushEntityInfo( ACM_Variable *var, clang::DeclaratorDecl *VD ) { + // if already done just ignore new data + if( getMode() == Mode_Done ) + return; + + assert( isValidSubExpr() ); + + if( getCurSubExprIndex() == _forward ) { // only forward data from chosen subexpr + getParent()->pushEntityInfo( var, VD ); + } +} + +void ClangASTConsumer::BinaryForwardContext::pushEntityForwardingJP( TU_Builtin *JP ) { + // if already done just ignore new data + if( getMode() == Mode_Done ) + return; + + assert( isValidSubExpr() ); + + if( getCurSubExprIndex() == _forward ) { // only forward data from chosen subexpr + getParent()->pushEntityForwardingJP( JP ); + } +} + +void ClangASTConsumer::ArrayAccessContext::pushEntityForwardingJP( TU_Builtin *JP ) { + // if already done just ignore new data + if( getMode() == Mode_Done ) + return; + + assert( isValidSubExpr() ); + + assert( ! _var_src ); + assert( JP ); + + if( getCurSubExprIndex() == SEI_LHS ) { // only remember data from base expr + _var_src = JP; + } +} + +void ClangASTConsumer::ArrayAccessContext::updateOperator( TU_Builtin *op ) { + op->forwarded_src( _var_src ); // remeber the dependency chain +} + +void ClangASTConsumer::AssignmentContext::leaveSubExpr( clang::Expr *sub ) { + bool done = ( getCurSubExprIndex() == SEI_LHS ); + + BinaryClassificationContext::leaveSubExpr( sub ); + + if( done ) + setMode( Mode_Done ); +} + +void ClangASTConsumer::AssignmentContext::pushEntityRefNode( clang::Expr *RE ) { + // we only collect data for the assigned value + if( getCurSubExprIndex() != SEI_LHS ) + return; + + // null values are not allowed, skip calling in that case + assert( RE ); + + // double calling is not allowed, it indicates some error in the AST traversal + assert( ! _var_info.ref_node ); + + _var_info.ref_node = RE; +} + +void ClangASTConsumer::AssignmentContext::pushEntityInfo( ACM_Variable *var, clang::DeclaratorDecl *VD ) { + // we only collect data for the assigned value + if( getCurSubExprIndex() != SEI_LHS ) + return; + + // null values are not allowed, skip calling in that case + assert( var ); + assert( VD ); + + // double calling is not allowed, it indicates some error in the AST traversal + assert( ! _var_info.element ); + assert( ! _var_info.decl ); + + _var_info.element = var; + _var_info.decl = VD; +} + +void ClangASTConsumer::AssignmentContext::pushEntityForwardingJP( TU_Builtin *JP ) { + // we only collect data for the assigned value + if( getCurSubExprIndex() != SEI_LHS ) + return; + + // null values are not allowed, skip calling in that case + assert( JP ); + + // double calling is not allowed, it indicates some error in the AST traversal + assert( ! _var_src ); + + _var_src = JP; +} + +void ClangASTConsumer::AssignmentContext::registerJPforContext() { + if( _var_info.ref_node ) { // check if we found some reference ... + ClangModelBuilder::JoinpointContext ctx = _consumer._context_stack.getJPContext(); + if( _op_call ) // on implicit joinpoints + ctx.parent = _op_call; // change parent element to call node + + // ... check for compound assignment and add a get joinpoint before ... + if( _is_compound ) { + if( ! _consumer._dummy_mode ) + _consumer._model.register_get( _var_info, ctx, _op_call ); + + // create new context (old one can't be reused + ctx = _consumer._context_stack.getJPContext(); + if( _op_call ) // on implicit joinpoints + ctx.parent = _op_call; // change parent element to call node + } + + if( ! _consumer._dummy_mode ) + _consumer._model.register_set( _var_info, ctx, _op_call ); // ... and register + } + + // forward findings down the stack, as other joinpoints need the info too + if( getParent() != 0 ) { // seems we have somebody interested in the information + if( _var_info.ref_node ) + getParent()->pushEntityRefNode( _var_info.ref_node ); + if( _var_info.decl ) + getParent()->pushEntityInfo( _var_info.element, _var_info.decl ); + if( _op_call ) + getParent()->pushEntityForwardingJP( _op_call ); + } +} + +void ClangASTConsumer::AssignmentContext::updateOperator( TU_Builtin *op ) { + _op_call = op; // remember for implicit joinpoints + + op->forwarded_src( _var_src ); // remeber the dependency chain +} + +void ClangASTConsumer::CallContext::enterSubExpr( clang::Expr *sub ) { + if( isSearching() ) { + if( _next_arg == 0 ) { + if( _call->getCallee() == sub ) + setCurSubExprIndex( 0 ); + } + else { + unsigned int a; + for( a = _next_arg - 1; a < getNumArgs(); a++ ) { + if( getArg( a ) == sub ) + setCurSubExprIndex( a + 1 ); + } + if( a >= getNumArgs() && _next_arg <= getNumArgs() ) + for( a = 0; a < _next_arg - 1; a++ ) { + if( getArg( a ) == sub ) + setCurSubExprIndex( a + 1 ); + } + + _curarg_is_ref = false; + if( _func_decl && ( a < _func_decl->getNumParams() ) ) + _curarg_is_ref = _func_decl->getParamDecl( a )->getType().getTypePtr()->isReferenceType(); + _var_info.tree_node = sub; + } + } +} + +void ClangASTConsumer::CallContext::leaveSubExpr( clang::Expr *sub ) { + _next_arg++; + setMode( Mode_Search ); + clearVarInfo(); +} + +void ClangASTConsumer::CallContext::pushEntityRefNode( clang::Expr *RE ) { + assert( getCurSubExprIndex() >= 0 ); + + // null values are not allowed, skip calling in that case + assert( RE ); + + // check if we see the callee or an arg + if( getCurSubExprIndex() == 0 ) { + if( clang::DeclRefExpr *dre = llvm::dyn_cast( RE ) ) + _func_decl = llvm::dyn_cast( dre->getDecl() ); // remember callee decl for type checking + else if( clang::MemberExpr *me = llvm::dyn_cast( RE ) ) + _func_decl = llvm::dyn_cast( me->getMemberDecl() ); // remember callee decl for type checking + } + else { + if( _curarg_is_ref ) { + // double calling is not allowed, it indicates some error in the AST traversal + assert( ! _var_info.ref_node ); + + _var_info.ref_node = RE; + } + } +} + +void ClangASTConsumer::CallContext::pushEntityInfo( ACM_Variable *var, clang::DeclaratorDecl *DD ) { + assert( getCurSubExprIndex() >= 0 ); + + // we only collect data for ref args + if( getCurSubExprIndex() == 0 || ! _curarg_is_ref ) + return; + + // null values are not allowed, skip calling in that case + assert( var ); + assert( DD ); + + // double calling is not allowed, it indicates some error in the AST traversal + assert( ! _var_info.element ); + assert( ! _var_info.decl ); + + _var_info.element = var; + _var_info.decl = DD; +} + +void ClangASTConsumer::CallContext::pushEntityForwardingJP( TU_Builtin *JP ) { + assert( getCurSubExprIndex() >= 0 ); + + // we only collect data for ref args + if( getCurSubExprIndex() == 0 || ! _curarg_is_ref ) + return; + + // null values are not allowed, skip calling in that case + assert( JP ); + + // double calling is not allowed, it indicates some error in the AST traversal + assert( ! _var_src ); + + _var_src = JP; +} + +void ClangASTConsumer::CallContext::registerJPforContext() { + // no joinpoint registration yet + + // ignore invalid scope + if( ! _consumer._context_stack.isCurrentContextValid() ) + return; + + assert( _call || _constr ); + // only pushing info to parent + if( getParent() && getParent()->isValidSubExpr() && _func_decl && + _func_decl->getReturnType().getTypePtr()->isReferenceType() ) + getParent()->pushEntityRefNode( _call ? + llvm::dyn_cast( _call ) : + llvm::dyn_cast(_constr) ); +} + +void ClangASTConsumer::CallContext::registerJPforSubExpr() { + if( _var_info.element && _var_info.decl && _var_info.ref_node && _curarg_is_ref ) { // check if we found some reference ... + ClangModelBuilder::JoinpointContext ctx = _consumer._context_stack.getJPContext(); + + if( ! _consumer._dummy_mode ) + _consumer._model.register_ref( _var_info, ctx, _var_src ); // ... and register + } +} diff --git a/AspectC++/ClangASTConsumer.h b/AspectC++/ClangASTConsumer.h new file mode 100644 index 0000000..413b9dd --- /dev/null +++ b/AspectC++/ClangASTConsumer.h @@ -0,0 +1,530 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2013 The 'ac++' developers (see aspectc.org) +// +// 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 __ClangASTConsumer_h__ +#define __ClangASTConsumer_h__ + +#include "ACConfig.h" + +#include "ModelBuilder.h" +#include "clang/AST/ASTConsumer.h" +#include "clang/AST/RecursiveASTVisitor.h" + +#include "ClangAnnotation.h" + +class ClangASTConsumer : public clang::ASTConsumer, + public clang::RecursiveASTVisitor { + ModelBuilder &_model; + clang::SourceManager *_sm; + + llvm::DenseMap _parent_map; + llvm::SmallPtrSet _seen_specs; + llvm::SmallVector, 4> _decl_stack; + unsigned _last_fn_local_id; + + bool _dummy_mode; // if enabled, do anything but register_* calls to model + + // shortening the type name + typedef ClangModelBuilder::JoinpointContext JPContext; + // wrapper around the existing context stack + // later we hold the information in this object + class DeclContextStack { + ClangASTConsumer &_outer; + + llvm::DenseMap _decl_map; + public: + DeclContextStack( ClangASTConsumer &o ) + : _outer ( o ) {}; + + void updateContextWithCurrentElement( clang::Decl *decl, ACM_Name *element ); + + bool isCurrentContextValid(); + JPContext getJPContext(); // don't reuse for multiple joinpoints, as it contains a local_id + clang::Decl *getCurrentDecl(); + } _context_stack; + + // objects of this class contain the state when searching for data joinpoints + class ExprClassificationContext { + ExprClassificationContext *_parent; + int _cur_subexpr_index; // either positive index or negative mode + clang::TypeSourceInfo *_ignoredTypeInfo; // we need to ignore some trees below type decl, but not the whole decl tree + protected: + ClangASTConsumer &_consumer; + enum Mode { + Mode_Search = -1, + Mode_Done = -2 + }; + + inline int getCurSubExprIndex() { return _cur_subexpr_index; }; + inline void setCurSubExprIndex( int i ) { assert( i >= 0 ); _cur_subexpr_index = i; }; + inline int getMode() { return _cur_subexpr_index; }; + inline void setMode( int m ) { assert( m < 0 ); _cur_subexpr_index = m; }; + public: + ExprClassificationContext( ClangASTConsumer &con ) : _parent( 0 ), _cur_subexpr_index( Mode_Search ), _ignoredTypeInfo( 0 ), _consumer( con ) {}; + virtual ~ExprClassificationContext() {}; + + inline void setParent( ExprClassificationContext *parent ) { assert( _parent == 0 ); _parent = parent; }; + inline ExprClassificationContext *getParent() { return _parent; }; + + inline void ignoreTypeInfo( clang::TypeSourceInfo* tsi ) { assert( _ignoredTypeInfo == 0 ); _ignoredTypeInfo = tsi; } + inline void unignoreTypeInfo( clang::TypeSourceInfo* tsi ) { assert( _ignoredTypeInfo == tsi ); _ignoredTypeInfo = 0; } + inline bool shouldIgnoreTypeInfo( clang::TypeLoc &TL ) { + if( _ignoredTypeInfo == 0 ) return false; + else return _ignoredTypeInfo->getTypeLoc() == TL; + } + + inline bool isSearching() { return ( getMode() == Mode_Search ); }; + inline bool isValidSubExpr() { return ( getCurSubExprIndex() >= 0 ); }; + + virtual void enterSubExpr( clang::Expr *sub ) = 0; + virtual void leaveSubExpr( clang::Expr *sub ) = 0; + + virtual void pushEntityRefNode( clang::Expr *RE ) = 0; + virtual void pushEntityInfo( ACM_Variable *var, clang::DeclaratorDecl *DD ) = 0; + virtual void pushEntityForwardingJP( TU_Builtin *JP ) = 0; + + virtual void registerJPforContext() {}; + virtual void registerJPforSubExpr() {}; + + virtual bool suppressDecayJPs() { return false; }; + }; + + // wrapper class around the stack integrated into the elements + class ExprContextStack { + ExprClassificationContext *_top; + + unsigned int _ignoreTreeGuard; + public: + ExprContextStack() : _top( 0 ), _ignoreTreeGuard( 0 ) {}; + + inline void beginIgnoreTree() { _ignoreTreeGuard++; }; + inline void endIgnoreTree() { _ignoreTreeGuard--; }; + + inline bool empty() { return ( _top == 0 ); }; + inline void clear() { _top = 0; _ignoreTreeGuard = 0; }; + inline ExprClassificationContext &peek() { assert( ! empty() ); return *_top; }; + + inline bool considerSubtree() { return ( _ignoreTreeGuard == 0 ); }; + inline void push( ExprClassificationContext &e ) { assert( considerSubtree() ); e.setParent( _top ); _top = &e; }; + + inline void drop() { _top = _top->getParent(); }; + inline ExprClassificationContext &pop() { ExprClassificationContext &res = peek(); drop(); return res; }; + } _expr_stack; + + bool isInProject(clang::Decl *D); +public: + ClangASTConsumer(ModelBuilder &model) + : _model( model ), _last_fn_local_id( 0 ), _dummy_mode( false ), _context_stack( *this ) {} + + virtual void Initialize(clang::ASTContext &Context); + virtual bool HandleTopLevelDecl(clang::DeclGroupRef DG); + + // handlers for simple model node creation + bool VisitType(clang::Type *Ty); + bool VisitNamespaceDecl(clang::NamespaceDecl *D); + bool VisitCXXRecordDecl(clang::CXXRecordDecl *D); + bool VisitFunctionDecl(clang::FunctionDecl *D); + bool VisitVarDecl(clang::VarDecl *VD); + bool VisitFieldDecl( clang::FieldDecl *FD ); + + // handlers for access joinpoint node creation + + // recognizing the referenced entities + bool VisitDeclRefExpr(clang::DeclRefExpr *RE); // find referenced entities + bool TraverseMemberExpr(clang::MemberExpr *ME); // find references to member entities, additional handle traversesal of base expr + bool TraverseArraySubscriptExpr(clang::ArraySubscriptExpr *ASE); // we need to forward data from base and remember info about base itself + + // subexpr determination + bool TraverseStmt(clang::Stmt* S); // needed to determinate current subexpr + + // context handling + bool TraverseImplicitCastExpr(clang::ImplicitCastExpr *ICE); // simple Get + bool TraverseUnaryAddrOf(clang::UnaryOperator *UO); // simple Ref + bool TraverseReturnStmt(clang::ReturnStmt *RS); // maybe an Ref depending on expr and return type + + bool TraverseUnaryDeref(clang::UnaryOperator *UO); // pass the reference info + bool TraverseBinComma(clang::BinaryOperator *BO); // forward the RHS + + // handling of assign nodes + bool TraverseBinAssign(clang::BinaryOperator *BO); // set on LHS + + // we work with hook functions for the compound and increment/decrement as they are handled similar in each case +private: +#if FRONTEND_CLANG < 38 + typedef bool (clang::RecursiveASTVisitor::* const FwdCall_CAssign)(clang::CompoundAssignOperator *CAO); + bool hookTraverseCompoundAssign( FwdCall_CAssign fwd, clang::CompoundAssignOperator *CAO ); + typedef bool (clang::RecursiveASTVisitor::* const FwdCall_PrePost)(clang::UnaryOperator *UO); + bool hookTraversePrePost( FwdCall_PrePost fwd, clang::UnaryOperator *UO ); +public: +#define GEN_CompoundAssignTraverse(NAME) \ + bool TraverseBin##NAME##Assign(clang::CompoundAssignOperator *CAO) { \ + return hookTraverseCompoundAssign( &clang::RecursiveASTVisitor::TraverseBin##NAME##Assign, CAO ); \ + }; +#else + typedef bool (clang::RecursiveASTVisitor::* const FwdCall_CAssign)(clang::CompoundAssignOperator *CAO, DataRecursionQueue *Q); + bool hookTraverseCompoundAssign( FwdCall_CAssign fwd, clang::CompoundAssignOperator *CAO, DataRecursionQueue *Q ); + typedef bool (clang::RecursiveASTVisitor::* const FwdCall_PrePost)(clang::UnaryOperator *UO, DataRecursionQueue *Q); + bool hookTraversePrePost( FwdCall_PrePost fwd, clang::UnaryOperator *UO, DataRecursionQueue *Q ); +public: +#define GEN_CompoundAssignTraverse(NAME) \ + bool TraverseBin##NAME##Assign(clang::CompoundAssignOperator *CAO, DataRecursionQueue *Q = nullptr) { \ + return hookTraverseCompoundAssign( &clang::RecursiveASTVisitor::TraverseBin##NAME##Assign, CAO, Q ); \ + }; +#endif + GEN_CompoundAssignTraverse( Mul ); + GEN_CompoundAssignTraverse( Div ); + GEN_CompoundAssignTraverse( Rem ); + GEN_CompoundAssignTraverse( Add ); + GEN_CompoundAssignTraverse( Sub ); + GEN_CompoundAssignTraverse( Shl ); + GEN_CompoundAssignTraverse( Shr ); + GEN_CompoundAssignTraverse( And ); + GEN_CompoundAssignTraverse( Or ); + GEN_CompoundAssignTraverse( Xor ); +#undef GEN_CompoundAssignTraverse +#if FRONTEND_CLANG < 38 +#define GEN_PrePostTraverse(NAME) \ + bool TraverseUnary##NAME(clang::UnaryOperator *UO) { \ + return hookTraversePrePost( &clang::RecursiveASTVisitor::TraverseUnary##NAME, UO ); \ + }; +#else +#define GEN_PrePostTraverse(NAME) \ + bool TraverseUnary##NAME(clang::UnaryOperator *UO, DataRecursionQueue *Q = nullptr) { \ + return hookTraversePrePost( &clang::RecursiveASTVisitor::TraverseUnary##NAME, UO, Q ); \ + }; +#endif + GEN_PrePostTraverse( PostInc ); + GEN_PrePostTraverse( PostDec ); + GEN_PrePostTraverse( PreInc ); + GEN_PrePostTraverse( PreDec ); +#undef GEN_PrePostTraverse + + // dummy handlers to block off wrong search path + // most will be replaced later on with real handlers for the cases + // but the will still define borders for the DeclRef search + + // this is particulary difficult + bool TraverseConditionalOperator(clang::ConditionalOperator *CO); + + bool TraverseBinPtrMemD(clang::BinaryOperator *BO); + bool TraverseBinPtrMemI(clang::BinaryOperator *BO); + + // ignore this subtrees completely they are never evaluated + bool TraverseUnaryExprOrTypeTraitExpr(clang::UnaryExprOrTypeTraitExpr *subtree); + + // building decl stack + bool TraverseVarDecl(clang::VarDecl *VD); + bool TraverseFunctionDecl(clang::FunctionDecl *FD); + bool TraverseCXXMethodDecl(clang::CXXMethodDecl *FD); + bool TraverseCXXConstructorDecl(clang::CXXConstructorDecl *FD); + bool TraverseCXXConversionDecl(clang::CXXConversionDecl *FD); + bool TraverseCXXDestructorDecl(clang::CXXDestructorDecl *FD); + bool TraverseRecordDecl(clang::RecordDecl *RD); + bool TraverseCXXRecordDecl(clang::CXXRecordDecl *RD); + + // enable dummy mode if ParmVar is assosiated with already handled function tree + bool TraverseParmVarDecl( clang::ParmVarDecl *VD ); + + // ignore exprs that are part of a type decl + bool TraverseTypeLoc( clang::TypeLoc TL ); + + // handling call joinpoints + void RegisterCallExpr(clang::CallExpr *CE); + bool TraverseCallExpr(clang::CallExpr *CE); + bool TraverseCXXMemberCallExpr(clang::CXXMemberCallExpr *CE); + bool TraverseCXXOperatorCallExpr(clang::CXXOperatorCallExpr *CE); + bool TraverseCXXTemporaryObjectExpr(clang::CXXTemporaryObjectExpr *TOE); + + // Built-in operators: + // Using Traverse- instead of Visit-Methods guarantees that nested calls are registered in their + // binding-precedence-order. Thus the advice are woven in the correct order. + + // Define Traverse-methods for each built-in-operator separately, because + // TraverseUnaryOperator-/TraverseBinaryOperator-methods do not get called and the + // TraverseStmt-method does not work for every built-in operator (e.g. binary plus; Clang bug?). + // TODO: ->, ., new, new[], delete, delete[], implicit conversion and , + +// Define the macro function, that creates the traverse-unary-built-in-operator-method: +#define GEN_UnaryOP_Traverse(NAME) \ + bool TraverseUnary##NAME(clang::UnaryOperator *UO) { \ + bool base_class_result = clang::RecursiveASTVisitor::TraverseUnary##NAME( UO ); \ + handle_built_in_operator_traverse( UO ); \ + return base_class_result; \ + }; + + // Create Traverse-Method for each unary built-in operator: + GEN_UnaryOP_Traverse(Plus) // integer promotion: +a + GEN_UnaryOP_Traverse(Minus) // additive inverse: -a + GEN_UnaryOP_Traverse(Not) // bitwise negation: ~a + GEN_UnaryOP_Traverse(LNot) // logical(bool) negation: !a + //GEN_UnaryOP_Traverse(Real) + //GEN_UnaryOP_Traverse(Imag) + //GEN_UnaryOP_Traverse(Extension) + +// Define the macro function, that creates the traverse-binary-built-in-operator-method: +#define GEN_BinOP_Traverse(NAME) \ + bool TraverseBin##NAME(clang::BinaryOperator *BO) { \ + bool base_class_result = clang::RecursiveASTVisitor::TraverseBin##NAME( BO ); \ + handle_built_in_operator_traverse( BO ); \ + return base_class_result; \ + }; + + // Create Traverse-Method for each binary built-in operator: + GEN_BinOP_Traverse(Mul) // a * b + GEN_BinOP_Traverse(Div) // a / b + GEN_BinOP_Traverse(Rem) // a % b + GEN_BinOP_Traverse(Add) // a + b + GEN_BinOP_Traverse(Sub) // a - b + GEN_BinOP_Traverse(Shl) // a << b + GEN_BinOP_Traverse(Shr) // a >> b + GEN_BinOP_Traverse(LT) // a < b + GEN_BinOP_Traverse(GT) // a > b + GEN_BinOP_Traverse(LE) // a <= b + GEN_BinOP_Traverse(GE) // a >= b + GEN_BinOP_Traverse(EQ) // a == b + GEN_BinOP_Traverse(NE) // a != b + GEN_BinOP_Traverse(And) // a & b + GEN_BinOP_Traverse(Xor) // a ^ b + GEN_BinOP_Traverse(Or) // a | b + // Short-circuit-operators: + GEN_BinOP_Traverse(LAnd) // a && b + GEN_BinOP_Traverse(LOr) // a || b + +// Undefine the functions: +#undef GEN_UnaryOP_Traverse +#undef GEN_BinOP_Traverse + + // This method handles a traverse over a built-in operator. + TU_Builtin *handle_built_in_operator_traverse(clang::Expr*); + + // code selection callbacks + bool shouldVisitImplicitCode() const { return false; } + bool shouldVisitTemplateInstantiations() const { return false; } + +private: + // specialized classes to handle the different cases while searching for data joinpoints + + // dummy context for ignoring data from subtrees + class DummyContext : public ExprClassificationContext { + public: + DummyContext( ClangASTConsumer &con ) : ExprClassificationContext( con ) { + setMode( Mode_Done ); + }; + + virtual void enterSubExpr( clang::Expr *sub ) {}; + virtual void leaveSubExpr( clang::Expr *sub ) {}; + virtual void pushEntityRefNode( clang::Expr *RE ) {}; + virtual void pushEntityInfo( ACM_Variable *var, clang::DeclaratorDecl *DD ) {}; + virtual void pushEntityForwardingJP( TU_Builtin *JP ) {}; + }; + + // base to classify the given child as a single Access Type + class SingleAccessContext : public ExprClassificationContext { + protected: + ClangModelBuilder::VarAccessInfo _var_info; + TU_Builtin *_var_src; + private: + clang::Expr *_child; + public: + SingleAccessContext( ClangASTConsumer &con, clang::Expr *tree, clang::Expr *child ) : ExprClassificationContext( con ), _var_src( 0 ), _child( child ) { + _var_info.element = 0; + _var_info.decl = 0; + _var_info.tree_node = tree; + _var_info.ref_node = 0; + } + + virtual void enterSubExpr( clang::Expr *sub ); + virtual void leaveSubExpr( clang::Expr *sub ); + + virtual void pushEntityRefNode( clang::Expr *RE ); + virtual void pushEntityInfo( ACM_Variable *var, clang::DeclaratorDecl *DD ); + virtual void pushEntityForwardingJP( TU_Builtin *JP ); + }; + + // classify the given child as Get + class SingleGetContext : public SingleAccessContext { + public: + SingleGetContext( ClangASTConsumer &con, clang::Expr *tree, clang::Expr *child ) : SingleAccessContext( con, tree, child ) {} + + virtual void registerJPforContext(); + }; + + // classify the given child as Ref + class SingleRefContext : public SingleAccessContext { + private: + TU_Builtin *_op_call; + public: + SingleRefContext( ClangASTConsumer &con, clang::Expr *tree, clang::Expr *child ) : SingleAccessContext( con, tree, child ), _op_call( 0 ) {} + + virtual void registerJPforContext(); + + void updateOperator( TU_Builtin *op ); + }; + + class BinaryClassificationContext : public ExprClassificationContext { + public: + enum SubExpressionIndex { + SEI_LHS, + SEI_RHS + }; + private: + clang::Expr *_lhs; + clang::Expr *_rhs; + public: + BinaryClassificationContext( ClangASTConsumer &con, clang::Expr *lhs, clang::Expr *rhs ) : ExprClassificationContext( con ), _lhs( lhs ), _rhs( rhs ) {}; + + virtual void enterSubExpr( clang::Expr *sub ); + virtual void leaveSubExpr( clang::Expr *sub ); + }; + + // Forward the data from the chosen subexpr to the parent (used for BinComma for example) + class BinaryForwardContext : public BinaryClassificationContext { + private: + SubExpressionIndex _forward; + public: + BinaryForwardContext( ClangASTConsumer &con, clang::Expr *lhs, clang::Expr *rhs, SubExpressionIndex forward ) : BinaryClassificationContext( con, lhs, rhs ), _forward( forward ) {}; + + // setting Mode_Done if nothing to do (anymore) + virtual void enterSubExpr( clang::Expr *sub ); + virtual void leaveSubExpr( clang::Expr *sub ); + + virtual void pushEntityRefNode( clang::Expr *RE ); + virtual void pushEntityInfo( ACM_Variable *var, clang::DeclaratorDecl *DD ); + virtual void pushEntityForwardingJP( TU_Builtin *JP ); + }; + + // forward the data from the base of the array access and remember the forwarding + class ArrayAccessContext : public BinaryForwardContext { + private: + TU_Builtin *_var_src; + public: + ArrayAccessContext( ClangASTConsumer &con, clang::ArraySubscriptExpr *ref ) : BinaryForwardContext( con, ref->getBase(), ref->getIdx(), BinaryForwardContext::SEI_LHS ), _var_src( 0 ) {}; + + virtual void pushEntityForwardingJP( TU_Builtin *JP ); + + void updateOperator( TU_Builtin *op ); + virtual bool suppressDecayJPs() { return true; }; + }; + + // adds implicit joinpoints on any operator with assignment meaning ( =, +=, ++, ...) + class AssignmentContext : public BinaryClassificationContext { + private: + ClangModelBuilder::VarAccessInfo _var_info; + TU_Builtin *_var_src; + bool _is_compound; + + TU_Builtin *_op_call; + + void commonInit( clang::Expr *tree ) { + _var_info.element = 0; + _var_info.decl = 0; + _var_info.tree_node = tree; + _var_info.ref_node = 0; + + _var_src = 0; + _op_call = 0; + }; + public: + AssignmentContext( ClangASTConsumer &con, clang::BinaryOperator *AO ) : BinaryClassificationContext( con, AO->getLHS(), 0 ), _is_compound( AO->isCompoundAssignmentOp() ) { // we don't need information about the rhs + commonInit( AO ); + } + + AssignmentContext( ClangASTConsumer &con, clang::UnaryOperator *PPO ) : BinaryClassificationContext( con, PPO->getSubExpr(), 0 ), _is_compound( true ) { // there is no rhs in this case + assert( PPO->isIncrementDecrementOp() ); + commonInit( PPO ); + } + + // setting Mode_Done if nothing to do anymore + virtual void leaveSubExpr( clang::Expr *sub ); + + virtual void pushEntityRefNode( clang::Expr *RE ); + virtual void pushEntityInfo( ACM_Variable *var, clang::DeclaratorDecl *DD ); + virtual void pushEntityForwardingJP( TU_Builtin *JP ); + + virtual void registerJPforContext(); + + void updateOperator( TU_Builtin *op ); + }; + + // adds ref joinpoints for reference arguments and pushes information to parent on ref return type + class CallContext : public ExprClassificationContext { + private: + clang::CallExpr *_call; + clang::CXXConstructExpr *_constr; + clang::FunctionDecl *_func_decl; + ClangModelBuilder::VarAccessInfo _var_info; + TU_Builtin *_var_src; + + bool _curarg_is_ref; + unsigned int _next_arg; + + void clearVarInfo() { + _var_info.element = 0; + _var_info.decl = 0; + _var_info.tree_node = 0; + _var_info.ref_node = 0; + + _var_src = 0; + } + public: + CallContext( ClangASTConsumer &con, clang::CallExpr *call ) : ExprClassificationContext( con ), _call( call ), _constr( 0 ), _func_decl( 0 ), _curarg_is_ref( false ), _next_arg( 0 ) { + clearVarInfo(); + } + + CallContext( ClangASTConsumer &con, clang::CXXConstructExpr *constr ) : ExprClassificationContext( con ), _call( 0 ), _constr( constr ), _func_decl( 0 ), _curarg_is_ref( false ), _next_arg( 1 ) { + clearVarInfo(); + _func_decl = constr->getConstructor(); + } + + unsigned int getNumArgs() { + if( _call ) + return _call->getNumArgs(); + else if( _constr ) + return _constr->getNumArgs(); + else { + assert( false && "Programming error, inconsistent code" ); + return 0; + } + } + + clang::Expr *getArg( unsigned int a ) { + if( _call ) + return _call->getArg( a ); + else if( _constr ) + return _constr->getArg( a ); + else { + assert( false && "Programming error, inconsistent code" ); + return 0; + } + } + + // checking which subexpr we are in + virtual void enterSubExpr( clang::Expr *sub ); + virtual void leaveSubExpr( clang::Expr *sub ); + + // collect info + virtual void pushEntityRefNode( clang::Expr *RE ); + virtual void pushEntityInfo( ACM_Variable *var, clang::DeclaratorDecl *DD ); + virtual void pushEntityForwardingJP( TU_Builtin *JP ); + + virtual void registerJPforContext(); + virtual void registerJPforSubExpr(); + }; +}; + +#endif // __ClangASTConsumer_h__ diff --git a/AspectC++/ClangAdjustedTypePrinter.cc b/AspectC++/ClangAdjustedTypePrinter.cc new file mode 100644 index 0000000..9fb50d9 --- /dev/null +++ b/AspectC++/ClangAdjustedTypePrinter.cc @@ -0,0 +1,2362 @@ +//===--- TypePrinter.cpp - Pretty-Print Clang Types -----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This contains code to print types from Clang's type system. +// +//===----------------------------------------------------------------------===// + +// Adjusted by AspectC++ to support printing of absolute types, printing of elaborated type specifier and removing of attributes. +// The file TypePrinter.cpp was taken from clang version 3.6.2 and split into a header file and a file containing the implementations. +// Changes are marked with //AC++. + +//AC++: +// How to add support for a new Clang version +// ****************************************** +// 1) Determine the versions: +// - "OLD": The most recent version of Clang that is currently supported by AspectC++ +// - "NEW": The version of Clang that should be supported by AspectC++ +// 2) Add a version-number-#define for the NEW version ("#define VERSION_NUMBER_X_Y_Z GET_VERSION_NUMBER(X, Y, Z)") below. +// 3) Determine all changes between the OLD version of .../lib/AST/TypePrinter.cpp and the NEW version of this file. +// - Use kdiff3, kompare, an online diff viewer, ... to see the differences between the two versions of the file. +// 4) Merge the changes that were determined in 3) into this file (ClangAdjustedTypePrinter.cpp) and also into +// ClangAdjustedTypePrinter.h if necessary. +// - Preprocessor directives could/ should be used to apply the merged changes only if +// a corresponding Clang version is used (e.g. +// //Ac++: added if +// #if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_8_0 +// // Clang 3.8.0 changes that break the compilation if a lower Clang version is used. +// #endif +// ). +// - Changes that would apply to commented out code (e.g. ObjC related code) can be ignored. +// 5) Repeat steps 3) and 4) for all of the adjusted (member) functions located at the bottom of this file: +// - File .../lib/AST/Decl.cpp +// - Merge changes that were made to NamedDecl::printQualifiedName(...) into adjusted_NamedDecl_printQualifiedName(...) +// - File .../lib/AST/TemplateBase.cpp +// - Merge changes that were made to printIntegral(...) into adjusted_printIntegral(...) +// - Merge changes that were made to TemplateArgument::print(...) into adjusted_TemplateArgument_print(...) +// - File .../lib/AST/TemplateName.cpp +// - Merge changes that were made to TemplateName::print(...) into adjusted_TemplateName_print(...) +// - File .../lib/AST/NestedNameSpecifier.cpp +// - Merge changes that were made to NestedNameSpecifier::print(...) into adjusted_NestedNameSpecifier_print(...) +// 6) Test with every supported Clang version. +// 7) Add changelog entry below. + +//AC++: +// Changelog +// ********* +// 23.02.2016: - Commented out ObjC related things. +// - Merged changes from 3.7.1 version. ObjC related changes were not merged. +// 28.03.2016: - Made AdjustedTypePrinter compatible with Clang 3.4 and 3.4.2 +// 29.06.2016: - Made AdjustedTypePrinter compatible with Clang 3.8.0 (not all changes are merged yet) +// 24.07.2016: - Adopted remaining Clang 3.8.0 changes +// - Added "How to add support for a new Clang version". +// 14.01.2017: - Made AdjustedTypePrinter compatible with Clang 3.9.1 +// 14.03.2017: - Made AdjustedTypePrinter compatible with Clang 4.0.0 + + +//AC++: beginning of TypePrinter.cpp is located in ClangAdjustedTypePrinter.h + +//AC++: includes added: +#include "ClangTransformInfo.h" +#include "ClangAdjustedTypePrinter.h" +#include "clang/AST/TemplateBase.h" +#include "version.h" +#if CLANG_VERSION_NUMBER < VERSION_NUMBER_5_0_0 +using namespace clang; + +//AC++: Changed name of parameter from "C99" to "HasRestrictKeyword" +static void AppendTypeQualList(raw_ostream &OS, unsigned TypeQuals, bool HasRestrictKeyword) { + bool appendSpace = false; + if (TypeQuals & Qualifiers::Const) { + OS << "const"; + appendSpace = true; + } + if (TypeQuals & Qualifiers::Volatile) { + if (appendSpace) OS << ' '; + OS << "volatile"; + appendSpace = true; + } + if (TypeQuals & Qualifiers::Restrict) { + if (appendSpace) OS << ' '; + if (HasRestrictKeyword) { + OS << "restrict"; + } else { + OS << "__restrict"; + } + } +} + +void AdjustedTypePrinter::spaceBeforePlaceHolder(raw_ostream &OS) { + if (!HasEmptyPlaceHolder) + OS << ' '; +} + +void AdjustedTypePrinter::print(QualType t, raw_ostream &OS, StringRef PlaceHolder) { + + //AC++: Adjust the type according to given flags: + if(keep_typedef == false) { + // while(clang::isa(type)) { + // type = clang::dyn_cast(type)->desugar(); + // } + // Doing type = type.desugar() in a loop until we do not have a TypedefType anymore does not + // work always. Counterexample: array type with typedef'd element type. + + t = t.getCanonicalType(); + } + if(as_parameter_signature_type) { + t = ctx->getSignatureParameterType(t); + } + + SplitQualType split = t.split(); + print(split.Ty, split.Quals, OS, PlaceHolder); +} + +void AdjustedTypePrinter::print(const Type *T, Qualifiers Quals, raw_ostream &OS, + StringRef PlaceHolder) { + if (!T) { + OS << "NULL TYPE"; + return; + } + + SaveAndRestore PHVal(HasEmptyPlaceHolder, PlaceHolder.empty()); + + printBefore(T, Quals, OS); + OS << PlaceHolder; + printAfter(T, Quals, OS); +} + +bool AdjustedTypePrinter::canPrefixQualifiers(const Type *T, + bool &NeedARCStrongQualifier) { + // CanPrefixQualifiers - We prefer to print type qualifiers before the type, + // so that we get "const int" instead of "int const", but we can't do this if + // the type is complex. For example if the type is "int*", we *must* print + // "int * const", printing "const int *" is different. Only do this when the + // type expands to a simple string. + bool CanPrefixQualifiers = false; + NeedARCStrongQualifier = false; + Type::TypeClass TC = T->getTypeClass(); + if (const AutoType *AT = dyn_cast(T)) + TC = AT->desugar()->getTypeClass(); + if (const SubstTemplateTypeParmType *Subst + = dyn_cast(T)) + TC = Subst->getReplacementType()->getTypeClass(); + + switch (TC) { + case Type::Auto: + case Type::Builtin: + case Type::Complex: + case Type::UnresolvedUsing: + case Type::Typedef: + case Type::TypeOfExpr: + case Type::TypeOf: + case Type::Decltype: + case Type::UnaryTransform: + case Type::Record: + case Type::Enum: + case Type::Elaborated: + case Type::TemplateTypeParm: + case Type::SubstTemplateTypeParmPack: + case Type::TemplateSpecialization: + case Type::InjectedClassName: + case Type::DependentName: + case Type::DependentTemplateSpecialization: + case Type::ObjCObject: +//Ac++: added if +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_4_0_0 + case Type::ObjCTypeParam: +#endif + case Type::ObjCInterface: + case Type::Atomic: +//Ac++: added if +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_8_0 + case Type::Pipe: +#endif + CanPrefixQualifiers = true; + break; + + case Type::ObjCObjectPointer: + CanPrefixQualifiers = T->isObjCIdType() || T->isObjCClassType() || + T->isObjCQualifiedIdType() || T->isObjCQualifiedClassType(); + break; + + case Type::ConstantArray: + case Type::IncompleteArray: + case Type::VariableArray: + case Type::DependentSizedArray: + NeedARCStrongQualifier = true; + // Fall through + case Type::Adjusted: + case Type::Decayed: + case Type::Pointer: + case Type::BlockPointer: + case Type::LValueReference: + case Type::RValueReference: + case Type::MemberPointer: + case Type::DependentSizedExtVector: + case Type::Vector: + case Type::ExtVector: + case Type::FunctionProto: + case Type::FunctionNoProto: + case Type::Paren: + case Type::Attributed: + case Type::PackExpansion: + case Type::SubstTemplateTypeParm: + CanPrefixQualifiers = false; + break; + } + + return CanPrefixQualifiers; +} + +void AdjustedTypePrinter::printBefore(QualType T, raw_ostream &OS) { + SplitQualType Split = T.split(); + + // If we have cv1 T, where T is substituted for cv2 U, only print cv1 - cv2 + // at this level. + Qualifiers Quals = Split.Quals; + if (const SubstTemplateTypeParmType *Subst = + dyn_cast(Split.Ty)) + Quals -= QualType(Subst, 0).getQualifiers(); + + printBefore(Split.Ty, Quals, OS); +} + +/// \brief Prints the part of the type string before an identifier, e.g. for +/// "int foo[10]" it prints "int ". +void AdjustedTypePrinter::printBefore(const Type *T,Qualifiers Quals, raw_ostream &OS) { + //AC++: Debug: + //OS << "/*" << T->getTypeClassName() << "*/"; + + if (Policy.SuppressSpecifiers && T->isSpecifierType()) + return; + + SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder); + + // Print qualifiers as appropriate. + + bool CanPrefixQualifiers = false; + bool NeedARCStrongQualifier = false; + CanPrefixQualifiers = canPrefixQualifiers(T, NeedARCStrongQualifier); + + if (CanPrefixQualifiers && !Quals.empty()) { + if (NeedARCStrongQualifier) { + IncludeStrongLifetimeRAII Strong(Policy); + Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/true); + } else { + Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/true); + } + } + + bool hasAfterQuals = false; + if (!CanPrefixQualifiers && !Quals.empty()) { + hasAfterQuals = !Quals.isEmptyWhenPrinted(Policy); + if (hasAfterQuals) + HasEmptyPlaceHolder = false; + } + + switch (T->getTypeClass()) { +#define ABSTRACT_TYPE(CLASS, PARENT) +#define TYPE(CLASS, PARENT) case Type::CLASS: \ + print##CLASS##Before(cast(T), OS); \ + break; +#include "clang/AST/TypeNodes.def" + } + + if (hasAfterQuals) { + if (NeedARCStrongQualifier) { + IncludeStrongLifetimeRAII Strong(Policy); + Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/!PrevPHIsEmpty.get()); + } else { + Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/!PrevPHIsEmpty.get()); + } + } +} + +void AdjustedTypePrinter::printAfter(QualType t, raw_ostream &OS) { + SplitQualType split = t.split(); + printAfter(split.Ty, split.Quals, OS); +} + +/// \brief Prints the part of the type string after an identifier, e.g. for +/// "int foo[10]" it prints "[10]". +void AdjustedTypePrinter::printAfter(const Type *T, Qualifiers Quals, raw_ostream &OS) { + switch (T->getTypeClass()) { +#define ABSTRACT_TYPE(CLASS, PARENT) +#define TYPE(CLASS, PARENT) case Type::CLASS: \ + print##CLASS##After(cast(T), OS); \ + break; +#include "clang/AST/TypeNodes.def" + } +} + + void AdjustedTypePrinter::printBuiltinBefore(const BuiltinType *T, raw_ostream &OS) { + OS << T->getName(Policy); + spaceBeforePlaceHolder(OS); +} +void AdjustedTypePrinter::printBuiltinAfter(const BuiltinType *T, raw_ostream &OS) { } + +void AdjustedTypePrinter::printComplexBefore(const ComplexType *T, raw_ostream &OS) { + OS << "_Complex "; + printBefore(T->getElementType(), OS); +} +void AdjustedTypePrinter::printComplexAfter(const ComplexType *T, raw_ostream &OS) { + printAfter(T->getElementType(), OS); +} + +void AdjustedTypePrinter::printPointerBefore(const PointerType *T, raw_ostream &OS) { + IncludeStrongLifetimeRAII Strong(Policy); + SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false); + printBefore(T->getPointeeType(), OS); + // Handle things like 'int (*A)[4];' correctly. + // FIXME: this should include vectors, but vectors use attributes I guess. + if (isa(T->getPointeeType())) + OS << '('; + OS << '*'; +} +void AdjustedTypePrinter::printPointerAfter(const PointerType *T, raw_ostream &OS) { + IncludeStrongLifetimeRAII Strong(Policy); + SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false); + // Handle things like 'int (*A)[4];' correctly. + // FIXME: this should include vectors, but vectors use attributes I guess. + if (isa(T->getPointeeType())) + OS << ')'; + printAfter(T->getPointeeType(), OS); +} + +void AdjustedTypePrinter::printBlockPointerBefore(const BlockPointerType *T, + raw_ostream &OS) { + SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false); + printBefore(T->getPointeeType(), OS); + OS << '^'; +} +void AdjustedTypePrinter::printBlockPointerAfter(const BlockPointerType *T, + raw_ostream &OS) { + SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false); + printAfter(T->getPointeeType(), OS); +} + +void AdjustedTypePrinter::printLValueReferenceBefore(const LValueReferenceType *T, + raw_ostream &OS) { + IncludeStrongLifetimeRAII Strong(Policy); + SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false); + printBefore(T->getPointeeTypeAsWritten(), OS); + // Handle things like 'int (&A)[4];' correctly. + // FIXME: this should include vectors, but vectors use attributes I guess. + if (isa(T->getPointeeTypeAsWritten())) + OS << '('; + OS << '&'; +} +void AdjustedTypePrinter::printLValueReferenceAfter(const LValueReferenceType *T, + raw_ostream &OS) { + IncludeStrongLifetimeRAII Strong(Policy); + SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false); + // Handle things like 'int (&A)[4];' correctly. + // FIXME: this should include vectors, but vectors use attributes I guess. + if (isa(T->getPointeeTypeAsWritten())) + OS << ')'; + printAfter(T->getPointeeTypeAsWritten(), OS); +} + +void AdjustedTypePrinter::printRValueReferenceBefore(const RValueReferenceType *T, + raw_ostream &OS) { + IncludeStrongLifetimeRAII Strong(Policy); + SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false); + printBefore(T->getPointeeTypeAsWritten(), OS); + // Handle things like 'int (&&A)[4];' correctly. + // FIXME: this should include vectors, but vectors use attributes I guess. + if (isa(T->getPointeeTypeAsWritten())) + OS << '('; + OS << "&&"; +} +void AdjustedTypePrinter::printRValueReferenceAfter(const RValueReferenceType *T, + raw_ostream &OS) { + IncludeStrongLifetimeRAII Strong(Policy); + SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false); + // Handle things like 'int (&&A)[4];' correctly. + // FIXME: this should include vectors, but vectors use attributes I guess. + if (isa(T->getPointeeTypeAsWritten())) + OS << ')'; + printAfter(T->getPointeeTypeAsWritten(), OS); +} + +void AdjustedTypePrinter::printMemberPointerBefore(const MemberPointerType *T, + raw_ostream &OS) { + IncludeStrongLifetimeRAII Strong(Policy); + SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false); + printBefore(T->getPointeeType(), OS); + // Handle things like 'int (Cls::*A)[4];' correctly. + // FIXME: this should include vectors, but vectors use attributes I guess. + if (isa(T->getPointeeType())) + OS << '('; + + //AC++: commented out: + //PrintingPolicy InnerPolicy(Policy); + //InnerPolicy.SuppressTag = false; + //AC++: elaborated not allowed + // inside/in front of member pointer + // TODO: RAII + TriStateEnableFeature old_elab = elaborated_keyword; + elaborated_keyword = TSEF_DISABLE; + //AC++: before: TypePrinter(InnerPolicy).print(QualType(T->getClass(), 0), OS, StringRef()); + print(QualType(T->getClass(), 0), OS, StringRef()); + elaborated_keyword = old_elab; + + OS << "::*"; +} +void AdjustedTypePrinter::printMemberPointerAfter(const MemberPointerType *T, + raw_ostream &OS) { + IncludeStrongLifetimeRAII Strong(Policy); + SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false); + // Handle things like 'int (Cls::*A)[4];' correctly. + // FIXME: this should include vectors, but vectors use attributes I guess. + if (isa(T->getPointeeType())) + OS << ')'; + printAfter(T->getPointeeType(), OS); +} + +void AdjustedTypePrinter::printConstantArrayBefore(const ConstantArrayType *T, + raw_ostream &OS) { + IncludeStrongLifetimeRAII Strong(Policy); + SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false); + printBefore(T->getElementType(), OS); +} +void AdjustedTypePrinter::printConstantArrayAfter(const ConstantArrayType *T, + raw_ostream &OS) { + OS << '['; + if (T->getIndexTypeQualifiers().hasQualifiers()) { +//AC++: added #if for backward compatibility +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_9_1 + AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(), Policy.Restrict); +#else + AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(), Policy.LangOpts.C99); +#endif + OS << ' '; + } + + if (T->getSizeModifier() == ArrayType::Static) + OS << "static "; + + OS << T->getSize().getZExtValue() << ']'; + printAfter(T->getElementType(), OS); +} + +void AdjustedTypePrinter::printIncompleteArrayBefore(const IncompleteArrayType *T, + raw_ostream &OS) { + IncludeStrongLifetimeRAII Strong(Policy); + SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false); + printBefore(T->getElementType(), OS); +} +void AdjustedTypePrinter::printIncompleteArrayAfter(const IncompleteArrayType *T, + raw_ostream &OS) { + OS << "[]"; + printAfter(T->getElementType(), OS); +} + +void AdjustedTypePrinter::printVariableArrayBefore(const VariableArrayType *T, + raw_ostream &OS) { + IncludeStrongLifetimeRAII Strong(Policy); + SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false); + printBefore(T->getElementType(), OS); +} +void AdjustedTypePrinter::printVariableArrayAfter(const VariableArrayType *T, + raw_ostream &OS) { + OS << '['; + if (T->getIndexTypeQualifiers().hasQualifiers()) { +//AC++: added #if for backward compatibility +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_9_1 + AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(), Policy.Restrict); +#else + AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(), Policy.LangOpts.C99); +#endif + OS << ' '; + } + + if (T->getSizeModifier() == VariableArrayType::Static) + OS << "static "; + else if (T->getSizeModifier() == VariableArrayType::Star) + OS << '*'; + + if (T->getSizeExpr()) + T->getSizeExpr()->printPretty(OS, nullptr, Policy); + OS << ']'; + + printAfter(T->getElementType(), OS); +} + +void AdjustedTypePrinter::printAdjustedBefore(const AdjustedType *T, raw_ostream &OS) { + // Print the adjusted representation, otherwise the adjustment will be + // invisible. + printBefore(T->getAdjustedType(), OS); +} +void AdjustedTypePrinter::printAdjustedAfter(const AdjustedType *T, raw_ostream &OS) { + printAfter(T->getAdjustedType(), OS); +} + +void AdjustedTypePrinter::printDecayedBefore(const DecayedType *T, raw_ostream &OS) { + // Print as though it's a pointer. + printAdjustedBefore(T, OS); +} +void AdjustedTypePrinter::printDecayedAfter(const DecayedType *T, raw_ostream &OS) { + printAdjustedAfter(T, OS); +} + +void AdjustedTypePrinter::printDependentSizedArrayBefore( + const DependentSizedArrayType *T, + raw_ostream &OS) { + IncludeStrongLifetimeRAII Strong(Policy); + SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false); + printBefore(T->getElementType(), OS); +} +void AdjustedTypePrinter::printDependentSizedArrayAfter( + const DependentSizedArrayType *T, + raw_ostream &OS) { + OS << '['; + if (T->getSizeExpr()) + T->getSizeExpr()->printPretty(OS, nullptr, Policy); + OS << ']'; + printAfter(T->getElementType(), OS); +} + +void AdjustedTypePrinter::printDependentSizedExtVectorBefore( + const DependentSizedExtVectorType *T, + raw_ostream &OS) { + printBefore(T->getElementType(), OS); +} +void AdjustedTypePrinter::printDependentSizedExtVectorAfter( + const DependentSizedExtVectorType *T, + raw_ostream &OS) { + //AC++: added if: + if(!remove_attributes) { + OS << " __attribute__((ext_vector_type("; + if (T->getSizeExpr()) + T->getSizeExpr()->printPretty(OS, nullptr, Policy); + OS << ")))"; + } + printAfter(T->getElementType(), OS); +} + +void AdjustedTypePrinter::printVectorBefore(const VectorType *T, raw_ostream &OS) { + //AC++: added if: + if(!remove_attributes) { + switch (T->getVectorKind()) { + case VectorType::AltiVecPixel: + OS << "__vector __pixel "; + break; + case VectorType::AltiVecBool: + OS << "__vector __bool "; + printBefore(T->getElementType(), OS); + break; + case VectorType::AltiVecVector: + OS << "__vector "; + printBefore(T->getElementType(), OS); + break; + case VectorType::NeonVector: + OS << "__attribute__((neon_vector_type(" + << T->getNumElements() << "))) "; + printBefore(T->getElementType(), OS); + break; + case VectorType::NeonPolyVector: + OS << "__attribute__((neon_polyvector_type(" << + T->getNumElements() << "))) "; + printBefore(T->getElementType(), OS); + break; + case VectorType::GenericVector: { + // FIXME: We prefer to print the size directly here, but have no way + // to get the size of the type. + OS << "__attribute__((__vector_size__(" + << T->getNumElements() + << " * sizeof("; + print(T->getElementType(), OS, StringRef()); + OS << ")))) "; + printBefore(T->getElementType(), OS); + break; + } + } + } +} +void AdjustedTypePrinter::printVectorAfter(const VectorType *T, raw_ostream &OS) { + printAfter(T->getElementType(), OS); +} + +void AdjustedTypePrinter::printExtVectorBefore(const ExtVectorType *T, + raw_ostream &OS) { + printBefore(T->getElementType(), OS); +} +void AdjustedTypePrinter::printExtVectorAfter(const ExtVectorType *T, raw_ostream &OS) { + printAfter(T->getElementType(), OS); + //AC++: added if: + if(!remove_attributes) { + OS << " __attribute__((ext_vector_type("; + OS << T->getNumElements(); + OS << ")))"; + } +} + +/*AC++: commented out: +void +FunctionProtoType::printExceptionSpecification(raw_ostream &OS, + const PrintingPolicy &Policy) + const { + + if (hasDynamicExceptionSpec()) { + OS << " throw("; + if (getExceptionSpecType() == EST_MSAny) + OS << "..."; + else + for (unsigned I = 0, N = getNumExceptions(); I != N; ++I) { + if (I) + OS << ", "; + + OS << getExceptionType(I).stream(Policy); + } + OS << ')'; + } else if (isNoexceptExceptionSpec(getExceptionSpecType())) { + OS << " noexcept"; + if (getExceptionSpecType() == EST_ComputedNoexcept) { + OS << '('; + if (getNoexceptExpr()) + getNoexceptExpr()->printPretty(OS, nullptr, Policy); + OS << ')'; + } + } +} +*/ +void AdjustedTypePrinter::printFunctionProtoBefore(const FunctionProtoType *T, + raw_ostream &OS) { + if (T->hasTrailingReturn()) { + OS << "auto "; + if (!HasEmptyPlaceHolder) + OS << '('; + } else { + // If needed for precedence reasons, wrap the inner part in grouping parens. + SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder, false); + printBefore(T->getReturnType(), OS); + if (!PrevPHIsEmpty.get()) + OS << '('; + } +} + +//Ac++: commented out: +//llvm::StringRef clang::getParameterABISpelling(ParameterABI ABI) { +// switch (ABI) { +// case ParameterABI::Ordinary: +// llvm_unreachable("asking for spelling of ordinary parameter ABI"); +// case ParameterABI::SwiftContext: +// return "swift_context"; +// case ParameterABI::SwiftErrorResult: +// return "swift_error_result"; +// case ParameterABI::SwiftIndirectResult: +// return "swift_indirect_result"; +// } +// llvm_unreachable("bad parameter ABI kind"); +//} + +void AdjustedTypePrinter::printFunctionProtoAfter(const FunctionProtoType *T, + raw_ostream &OS) { + // If needed for precedence reasons, wrap the inner part in grouping parens. + if (!HasEmptyPlaceHolder) + OS << ')'; + SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false); + OS << '('; + { + ParamPolicyRAII ParamPolicy(Policy); + for (unsigned i = 0, e = T->getNumParams(); i != e; ++i) { + if (i) OS << ", "; + +//AC++: added #if for backward compatibility +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_9_1 + auto EPI = T->getExtParameterInfo(i); + if (EPI.isConsumed()) OS << "__attribute__((ns_consumed)) "; + auto ABI = EPI.getABI(); + if (ABI != ParameterABI::Ordinary) + OS << "__attribute__((" << getParameterABISpelling(ABI) << ")) "; +#endif + + print(T->getParamType(i), OS, StringRef()); + } + } + + if (T->isVariadic()) { + if (T->getNumParams()) + OS << ", "; + OS << "..."; +//AC++: added #if for backward compatibility +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_9_1 + } else if (T->getNumParams() == 0 && Policy.UseVoidForZeroParams) { +#else + } else if (T->getNumParams() == 0 && !Policy.LangOpts.CPlusPlus) { +#endif + // Do not emit int() if we have a proto, emit 'int(void)'. + OS << "void"; + } + + OS << ')'; + + //AC++: added if: + if(!remove_attributes) { + //AC++: FunctionType -> clang::FuntionType + clang::FunctionType::ExtInfo Info = T->getExtInfo(); + + if (!InsideCCAttribute) { + switch (Info.getCC()) { + case CC_C: + // The C calling convention is the default on the vast majority of platforms + // we support. If the user wrote it explicitly, it will usually be printed + // while traversing the AttributedType. If the type has been desugared, let + // the canonical spelling be the implicit calling convention. + // FIXME: It would be better to be explicit in certain contexts, such as a + // cdecl function typedef used to declare a member function with the + // Microsoft C++ ABI. + break; + case CC_X86StdCall: + OS << " __attribute__((stdcall))"; + break; + case CC_X86FastCall: + OS << " __attribute__((fastcall))"; + break; + case CC_X86ThisCall: + OS << " __attribute__((thiscall))"; + break; +//AC++: added if +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_6_2 + case CC_X86VectorCall: + OS << " __attribute__((vectorcall))"; + break; +#endif + case CC_X86Pascal: + OS << " __attribute__((pascal))"; + break; + case CC_AAPCS: + OS << " __attribute__((pcs(\"aapcs\")))"; + break; + case CC_AAPCS_VFP: + OS << " __attribute__((pcs(\"aapcs-vfp\")))"; + break; + //AC++: kept case for backward compatibility +#if CLANG_VERSION_NUMBER <= VERSION_NUMBER_3_6_2 + case CC_PnaclCall: + OS << " __attribute__((pnaclcall))"; + break; +#endif + case CC_IntelOclBicc: + OS << " __attribute__((intel_ocl_bicc))"; + break; + case CC_X86_64Win64: + OS << " __attribute__((ms_abi))"; + break; + case CC_X86_64SysV: + OS << " __attribute__((sysv_abi))"; + break; +//AC++: added if +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_4_0_0 + case CC_X86RegCall: + OS << " __attribute__((regcall))"; + break; +#endif + //AC++: added two #if for backward compatibility +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_7_1 + case CC_SpirFunction: +#if CLANG_VERSION_NUMBER < VERSION_NUMBER_3_9_1 + case CC_SpirKernel: +#else + case CC_OpenCLKernel: +#endif + // Do nothing. These CCs are not available as attributes. + break; +#endif +//AC++: added #if for backward compatibility +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_9_1 + case CC_Swift: + OS << " __attribute__((swiftcall))"; + break; + case CC_PreserveMost: + OS << " __attribute__((preserve_most))"; + break; + case CC_PreserveAll: + OS << " __attribute__((preserve_all))"; + break; +#endif + } + } + + if (Info.getNoReturn()) + OS << " __attribute__((noreturn))"; + if (Info.getRegParm()) + OS << " __attribute__((regparm (" + << Info.getRegParm() << ")))"; + } + + if (unsigned quals = T->getTypeQuals()) { + OS << ' '; +//AC++: added #if for backward compatibility +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_9_1 + AppendTypeQualList(OS, quals, Policy.Restrict); +#else + AppendTypeQualList(OS, quals, Policy.LangOpts.C99); +#endif + } + + switch (T->getRefQualifier()) { + case RQ_None: + break; + + case RQ_LValue: + OS << " &"; + break; + + case RQ_RValue: + OS << " &&"; + break; + } + T->printExceptionSpecification(OS, Policy); + + if (T->hasTrailingReturn()) { + OS << " -> "; + print(T->getReturnType(), OS, StringRef()); + } else + printAfter(T->getReturnType(), OS); +} + +void AdjustedTypePrinter::printFunctionNoProtoBefore(const FunctionNoProtoType *T, + raw_ostream &OS) { + // If needed for precedence reasons, wrap the inner part in grouping parens. + SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder, false); + printBefore(T->getReturnType(), OS); + if (!PrevPHIsEmpty.get()) + OS << '('; +} +void AdjustedTypePrinter::printFunctionNoProtoAfter(const FunctionNoProtoType *T, + raw_ostream &OS) { + // If needed for precedence reasons, wrap the inner part in grouping parens. + if (!HasEmptyPlaceHolder) + OS << ')'; + SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false); + + OS << "()"; + //AC++: before if (T->getNoReturnAttr()) + if (T->getNoReturnAttr() && !remove_attributes) + OS << " __attribute__((noreturn))"; + printAfter(T->getReturnType(), OS); +} +void AdjustedTypePrinter::printTypeSpec(const NamedDecl *D, raw_ostream &OS) { + //AC++: commented out: +// IdentifierInfo *II = D->getIdentifier(); +// OS << II->getName(); + //AC++: added: + adjusted_NamedDecl_printQualifiedName(D, OS); + + spaceBeforePlaceHolder(OS); +} +void AdjustedTypePrinter::printUnresolvedUsingBefore(const UnresolvedUsingType *T, + raw_ostream &OS) { + printTypeSpec(T->getDecl(), OS); +} +void AdjustedTypePrinter::printUnresolvedUsingAfter(const UnresolvedUsingType *T, + raw_ostream &OS) { } + +void AdjustedTypePrinter::printTypedefBefore(const TypedefType *T, raw_ostream &OS) { + printTypeSpec(T->getDecl(), OS); +} +void AdjustedTypePrinter::printTypedefAfter(const TypedefType *T, raw_ostream &OS) { } +//AC++: TODO: adjust expression? +void AdjustedTypePrinter::printTypeOfExprBefore(const TypeOfExprType *T, + raw_ostream &OS) { + OS << "typeof "; + if (T->getUnderlyingExpr()) + T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy); + spaceBeforePlaceHolder(OS); +} +void AdjustedTypePrinter::printTypeOfExprAfter(const TypeOfExprType *T, + raw_ostream &OS) { } + +void AdjustedTypePrinter::printTypeOfBefore(const TypeOfType *T, raw_ostream &OS) { + OS << "typeof("; + print(T->getUnderlyingType(), OS, StringRef()); + OS << ')'; + spaceBeforePlaceHolder(OS); +} +void AdjustedTypePrinter::printTypeOfAfter(const TypeOfType *T, raw_ostream &OS) { } + +void AdjustedTypePrinter::printDecltypeBefore(const DecltypeType *T, raw_ostream &OS) { + OS << "decltype("; + if (T->getUnderlyingExpr()) + T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy); + OS << ')'; + spaceBeforePlaceHolder(OS); +} +void AdjustedTypePrinter::printDecltypeAfter(const DecltypeType *T, raw_ostream &OS) { } + +void AdjustedTypePrinter::printUnaryTransformBefore(const UnaryTransformType *T, + raw_ostream &OS) { + IncludeStrongLifetimeRAII Strong(Policy); + + switch (T->getUTTKind()) { + case UnaryTransformType::EnumUnderlyingType: + OS << "__underlying_type("; + print(T->getBaseType(), OS, StringRef()); + OS << ')'; + spaceBeforePlaceHolder(OS); + return; + } + + printBefore(T->getBaseType(), OS); +} +void AdjustedTypePrinter::printUnaryTransformAfter(const UnaryTransformType *T, + raw_ostream &OS) { + IncludeStrongLifetimeRAII Strong(Policy); + + switch (T->getUTTKind()) { + case UnaryTransformType::EnumUnderlyingType: + return; + } + + printAfter(T->getBaseType(), OS); +} + +void AdjustedTypePrinter::printAutoBefore(const AutoType *T, raw_ostream &OS) { + // If the type has been deduced, do not print 'auto'. + if (!T->getDeducedType().isNull()) { + printBefore(T->getDeducedType(), OS); + } else { +//Ac++: added if else +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_8_0 + switch (T->getKeyword()) { + case AutoTypeKeyword::Auto: OS << "auto"; break; + case AutoTypeKeyword::DecltypeAuto: OS << "decltype(auto)"; break; + case AutoTypeKeyword::GNUAutoType: OS << "__auto_type"; break; + } +#else + OS << (T->isDecltypeAuto() ? "decltype(auto)" : "auto"); +#endif + spaceBeforePlaceHolder(OS); + } +} +void AdjustedTypePrinter::printAutoAfter(const AutoType *T, raw_ostream &OS) { + // If the type has been deduced, do not print 'auto'. + if (!T->getDeducedType().isNull()) + printAfter(T->getDeducedType(), OS); +} + +void AdjustedTypePrinter::printAtomicBefore(const AtomicType *T, raw_ostream &OS) { + IncludeStrongLifetimeRAII Strong(Policy); + + OS << "_Atomic("; + print(T->getValueType(), OS, StringRef()); + OS << ')'; + spaceBeforePlaceHolder(OS); +} +void AdjustedTypePrinter::printAtomicAfter(const AtomicType *T, raw_ostream &OS) { } + +//Ac++: added if else +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_8_0 +void AdjustedTypePrinter::printPipeBefore(const PipeType *T, raw_ostream &OS) { + IncludeStrongLifetimeRAII Strong(Policy); + +//AC++: added if +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_4_0_0 + if (T->isReadOnly()) + OS << "read_only "; + else + OS << "write_only "; +#endif + OS << "pipe "; + print(T->getElementType(), OS, StringRef()); + spaceBeforePlaceHolder(OS); +} + +void AdjustedTypePrinter::printPipeAfter(const PipeType *T, raw_ostream &OS) { +} +#endif + +/// Appends the given scope to the end of a string. +void AdjustedTypePrinter::AppendScope(DeclContext *DC, raw_ostream &OS) { + if (DC->isTranslationUnit()) return; + if (DC->isFunctionOrMethod()) return; + AppendScope(DC->getParent(), OS); + + if (NamespaceDecl *NS = dyn_cast(DC)) { + if (Policy.SuppressUnwrittenScope && + (NS->isAnonymousNamespace() || NS->isInline())) + return; + if (NS->getIdentifier()) + OS << NS->getName() << "::"; + else +//Ac++: added if else +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_6_2 + OS << "(anonymous namespace)::"; +#else + OS << "::"; +#endif + } else if (ClassTemplateSpecializationDecl *Spec + = dyn_cast(DC)) { + IncludeStrongLifetimeRAII Strong(Policy); + OS << Spec->getIdentifier()->getName(); + const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); + //AC++: TemplateSpecializationType::PrintTemplateArgumentList(OS, + adjusted_PrintTemplateArgumentList(OS, + TemplateArgs.data(), + TemplateArgs.size()/*AC++: commented out:, + Policy*/); + OS << "::"; + } else if (TagDecl *Tag = dyn_cast(DC)) { + //AC++: added curly braces + if (TypedefNameDecl *Typedef = Tag->getTypedefNameForAnonDecl()){ + //AC++: added if block: + if(!keep_typedef) { + Typedef = Typedef->getCanonicalDecl(); + } + OS << Typedef->getIdentifier()->getName() << "::"; + } + else if (Tag->getIdentifier()) + OS << Tag->getIdentifier()->getName() << "::"; + else + return; + } +} + +void AdjustedTypePrinter::printTag(TagDecl *D, raw_ostream &OS) { +//AC++: added #if for backward compatibility +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_9_1 + if (Policy.IncludeTagDefinition) { + PrintingPolicy SubPolicy = Policy; + SubPolicy.IncludeTagDefinition = false; + D->print(OS, SubPolicy, Indentation); + spaceBeforePlaceHolder(OS); + return; + } +#else + if (Policy.SuppressTag) + return; +#endif + + + bool HasKindDecoration = false; + + // bool SuppressTagKeyword + // = Policy.LangOpts.CPlusPlus || Policy.SuppressTagKeyword; + + // We don't print tags unless this is an elaborated type. + // In C, we just assume every RecordType is an elaborated type. + + //AC++: before: + // if (!(Policy.LangOpts.CPlusPlus || Policy.SuppressTagKeyword || + // D->getTypedefNameForAnonDecl())) { + //AC++: if we have something like "union {} type_name;" then there is + // no non-typedef'd declaration available. Therefore we can not print the + // elaborated keyword in such cases: + if (elaborated_keyword == TSEF_ENABLE && !D->getTypedefNameForAnonDecl()) { + HasKindDecoration = true; + OS << D->getKindName(); + OS << ' '; + } + + // Compute the full nested-name-specifier for this type. + // In C, this will always be empty except when the type + // being printed is anonymous within other Record. + //AC++: before: if (!Policy.SuppressScope) { + if (absolute_qualified != TSEF_DISABLE) { + //AC++: + if(absolute_qualified == TSEF_ENABLE) { + OS << "::"; + } + + AppendScope(D->getDeclContext(), OS); + } + + if (const IdentifierInfo *II = D->getIdentifier()) + OS << II->getName(); + else if (TypedefNameDecl *Typedef = D->getTypedefNameForAnonDecl()) { + //AC++: added if block: + if(!keep_typedef) { + Typedef = Typedef->getCanonicalDecl(); + } + assert(Typedef->getIdentifier() && "Typedef without identifier?"); + OS << Typedef->getIdentifier()->getName(); + } else { + // Make an unambiguous representation for anonymous types, e.g. + // (anonymous enum at /usr/include/string.h:120:9) + +//Ac++: added if else and moved prefix printing out of the if-else +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_8_0 + OS << (Policy.MSVCFormatting ? '`' : '('); +#elif CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_6_2 + OS << "("; +#else + OS << "<"; +#endif + if (isa(D) && cast(D)->isLambda()) { + OS << "lambda"; + HasKindDecoration = true; + } else { + OS << "anonymous"; + } + + if (Policy.AnonymousTagLocations) { + // Suppress the redundant tag keyword if we just printed one. + // We don't have to worry about ElaboratedTypes here because you can't + // refer to an anonymous type with one. + if (!HasKindDecoration) + OS << " " << D->getKindName(); + + PresumedLoc PLoc = D->getASTContext().getSourceManager().getPresumedLoc( + D->getLocation()); + if (PLoc.isValid()) { + OS << " at " << PLoc.getFilename() + << ':' << PLoc.getLine() + << ':' << PLoc.getColumn(); + } + } +//Ac++: added if else +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_8_0 + OS << (Policy.MSVCFormatting ? '\'' : ')'); +#elif CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_6_2 + OS << ')'; +#else + OS << '>'; +#endif + } + + // If this is a class template specialization, print the template + // arguments. + if (ClassTemplateSpecializationDecl *Spec + = dyn_cast(D)) { + const TemplateArgument *Args; + unsigned NumArgs; + if (TypeSourceInfo *TAW = Spec->getTypeAsWritten()) { + const TemplateSpecializationType *TST = + cast(TAW->getType()); + Args = TST->getArgs(); + NumArgs = TST->getNumArgs(); + } else { + const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); + Args = TemplateArgs.data(); + NumArgs = TemplateArgs.size(); + } + IncludeStrongLifetimeRAII Strong(Policy); + //AC++: before: TemplateSpecializationType::PrintTemplateArgumentList(OS, + adjusted_PrintTemplateArgumentList(OS, + Args, NumArgs/*AC++: commented out:, + Policy*/); + } + + spaceBeforePlaceHolder(OS); +} + +void AdjustedTypePrinter::printRecordBefore(const RecordType *T, raw_ostream &OS) { + printTag(T->getDecl(), OS); +} +void AdjustedTypePrinter::printRecordAfter(const RecordType *T, raw_ostream &OS) { } + +void AdjustedTypePrinter::printEnumBefore(const EnumType *T, raw_ostream &OS) { + printTag(T->getDecl(), OS); +} +void AdjustedTypePrinter::printEnumAfter(const EnumType *T, raw_ostream &OS) { } + +void AdjustedTypePrinter::printTemplateTypeParmBefore(const TemplateTypeParmType *T, + raw_ostream &OS) { + if (IdentifierInfo *Id = T->getIdentifier()) + OS << Id->getName(); + else + OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex(); + spaceBeforePlaceHolder(OS); +} +void AdjustedTypePrinter::printTemplateTypeParmAfter(const TemplateTypeParmType *T, + raw_ostream &OS) { } + +void AdjustedTypePrinter::printSubstTemplateTypeParmBefore( + const SubstTemplateTypeParmType *T, + raw_ostream &OS) { + IncludeStrongLifetimeRAII Strong(Policy); + printBefore(T->getReplacementType(), OS); +} +void AdjustedTypePrinter::printSubstTemplateTypeParmAfter( + const SubstTemplateTypeParmType *T, + raw_ostream &OS) { + IncludeStrongLifetimeRAII Strong(Policy); + printAfter(T->getReplacementType(), OS); +} + +void AdjustedTypePrinter::printSubstTemplateTypeParmPackBefore( + const SubstTemplateTypeParmPackType *T, + raw_ostream &OS) { + IncludeStrongLifetimeRAII Strong(Policy); + printTemplateTypeParmBefore(T->getReplacedParameter(), OS); +} +void AdjustedTypePrinter::printSubstTemplateTypeParmPackAfter( + const SubstTemplateTypeParmPackType *T, + raw_ostream &OS) { + IncludeStrongLifetimeRAII Strong(Policy); + printTemplateTypeParmAfter(T->getReplacedParameter(), OS); +} + +void AdjustedTypePrinter::printTemplateSpecializationBefore( + const TemplateSpecializationType *T, + raw_ostream &OS) { + IncludeStrongLifetimeRAII Strong(Policy); + //AC++: before: T->getTemplateName().print(OS, Policy); + adjusted_TemplateName_print(T->getTemplateName(), OS); + + //AC++: before: TemplateSpecializationType::PrintTemplateArgumentList(OS, + adjusted_PrintTemplateArgumentList(OS, + T->getArgs(), + T->getNumArgs()/*AC++: commented out:, + Policy*/); + spaceBeforePlaceHolder(OS); +} +void AdjustedTypePrinter::printTemplateSpecializationAfter( + const TemplateSpecializationType *T, + raw_ostream &OS) { } + +void AdjustedTypePrinter::printInjectedClassNameBefore(const InjectedClassNameType *T, + raw_ostream &OS) { + printTemplateSpecializationBefore(T->getInjectedTST(), OS); +} +void AdjustedTypePrinter::printInjectedClassNameAfter(const InjectedClassNameType *T, + raw_ostream &OS) { } + +void AdjustedTypePrinter::printElaboratedBefore(const ElaboratedType *T, + raw_ostream &OS) { +//AC++: added #if for backward compatibility +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_9_1 + if (Policy.IncludeTagDefinition && isa(T->getNamedType())) +#else + if (Policy.SuppressTag && isa(T->getNamedType())) +#endif + return; + + //AC++: added if: + if(elaborated_keyword != TSEF_DISABLE) { + OS << TypeWithKeyword::getKeywordName(T->getKeyword()); + if (T->getKeyword() != ETK_None) + OS << " "; + } + + //AC++: commented out:We ignore the qualifiers here and print it in printTagDecl + // if necessary. +// NestedNameSpecifier* Qualifier = T->getQualifier(); +// if (Qualifier) +// Qualifier->print(OS, Policy); +// +// ElaboratedTypePolicyRAII PolicyRAII(Policy); + printBefore(T->getNamedType(), OS); +} +void AdjustedTypePrinter::printElaboratedAfter(const ElaboratedType *T, + raw_ostream &OS) { + //AC++: commented out: + //ElaboratedTypePolicyRAII PolicyRAII(Policy); + printAfter(T->getNamedType(), OS); +} + +void AdjustedTypePrinter::printParenBefore(const ParenType *T, raw_ostream &OS) { + //AC++: FunctionType -> clang::FunctionType + if (!HasEmptyPlaceHolder && !isa(T->getInnerType())) { + printBefore(T->getInnerType(), OS); + OS << '('; + } else + printBefore(T->getInnerType(), OS); +} +void AdjustedTypePrinter::printParenAfter(const ParenType *T, raw_ostream &OS) { + //AC++: FunctionType -> clang::FunctionType + if (!HasEmptyPlaceHolder && !isa(T->getInnerType())) { + OS << ')'; + printAfter(T->getInnerType(), OS); + } else + printAfter(T->getInnerType(), OS); +} + +void AdjustedTypePrinter::printDependentNameBefore(const DependentNameType *T, + raw_ostream &OS) { + OS << TypeWithKeyword::getKeywordName(T->getKeyword()); + if (T->getKeyword() != ETK_None) + OS << " "; + + T->getQualifier()->print(OS, Policy); + + OS << T->getIdentifier()->getName(); + spaceBeforePlaceHolder(OS); +} +void AdjustedTypePrinter::printDependentNameAfter(const DependentNameType *T, + raw_ostream &OS) { } + +void AdjustedTypePrinter::printDependentTemplateSpecializationBefore( + const DependentTemplateSpecializationType *T, raw_ostream &OS) { + IncludeStrongLifetimeRAII Strong(Policy); + + OS << TypeWithKeyword::getKeywordName(T->getKeyword()); + if (T->getKeyword() != ETK_None) + OS << " "; + + if (T->getQualifier()) + T->getQualifier()->print(OS, Policy); + OS << T->getIdentifier()->getName(); + //AC++: before: TemplateSpecializationType::PrintTemplateArgumentList(OS, + adjusted_PrintTemplateArgumentList(OS, + T->getArgs(), + T->getNumArgs()/*AC++: commented out: , + Policy*/); + spaceBeforePlaceHolder(OS); +} +void AdjustedTypePrinter::printDependentTemplateSpecializationAfter( + const DependentTemplateSpecializationType *T, raw_ostream &OS) { } + +void AdjustedTypePrinter::printPackExpansionBefore(const PackExpansionType *T, + raw_ostream &OS) { + printBefore(T->getPattern(), OS); +} +void AdjustedTypePrinter::printPackExpansionAfter(const PackExpansionType *T, + raw_ostream &OS) { + printAfter(T->getPattern(), OS); + OS << "..."; +} + +void AdjustedTypePrinter::printAttributedBefore(const AttributedType *T, + raw_ostream &OS) { + // Prefer the macro forms of the GC and ownership qualifiers. + if (T->getAttrKind() == AttributedType::attr_objc_gc || + T->getAttrKind() == AttributedType::attr_objc_ownership) + return printBefore(T->getEquivalentType(), OS); + + printBefore(T->getModifiedType(), OS); + + if (T->isMSTypeSpec()) { + switch (T->getAttrKind()) { + default: return; + case AttributedType::attr_ptr32: OS << " __ptr32"; break; + case AttributedType::attr_ptr64: OS << " __ptr64"; break; + case AttributedType::attr_sptr: OS << " __sptr"; break; + case AttributedType::attr_uptr: OS << " __uptr"; break; + } + spaceBeforePlaceHolder(OS); + } + + //AC++: added #if for backward compatibility +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_7_1 + // Print nullability type specifiers. + if (T->getAttrKind() == AttributedType::attr_nonnull || + T->getAttrKind() == AttributedType::attr_nullable || + T->getAttrKind() == AttributedType::attr_null_unspecified) { + if (T->getAttrKind() == AttributedType::attr_nonnull) + OS << " _Nonnull"; + else if (T->getAttrKind() == AttributedType::attr_nullable) + OS << " _Nullable"; + else if (T->getAttrKind() == AttributedType::attr_null_unspecified) + OS << " _Null_unspecified"; + else + llvm_unreachable("unhandled nullability"); + spaceBeforePlaceHolder(OS); + } +#endif +} + +void AdjustedTypePrinter::printAttributedAfter(const AttributedType *T, + raw_ostream &OS) { + // Prefer the macro forms of the GC and ownership qualifiers. + if (T->getAttrKind() == AttributedType::attr_objc_gc || + T->getAttrKind() == AttributedType::attr_objc_ownership) + return printAfter(T->getEquivalentType(), OS); + + // TODO: not all attributes are GCC-style attributes. + if (T->isMSTypeSpec()) + return; + + //AC++: added #if for backward compatibility +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_7_1 + // Nothing to print after. + if (T->getAttrKind() == AttributedType::attr_nonnull || + T->getAttrKind() == AttributedType::attr_nullable || + T->getAttrKind() == AttributedType::attr_null_unspecified) + return printAfter(T->getModifiedType(), OS); +#endif + + // If this is a calling convention attribute, don't print the implicit CC from + // the modified type. + SaveAndRestore MaybeSuppressCC(InsideCCAttribute, T->isCallingConv()); + + printAfter(T->getModifiedType(), OS); + +//AC++: added #if +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_8_0 + // Don't print the inert __unsafe_unretained attribute at all. + if (T->getAttrKind() == AttributedType::attr_objc_inert_unsafe_unretained) + return; +#endif + + //AC++: added #if for backward compatibility +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_7_1 + // Print nullability type specifiers that occur after + if (T->getAttrKind() == AttributedType::attr_nonnull || + T->getAttrKind() == AttributedType::attr_nullable || + T->getAttrKind() == AttributedType::attr_null_unspecified) { + if (T->getAttrKind() == AttributedType::attr_nonnull) + OS << " _Nonnull"; + else if (T->getAttrKind() == AttributedType::attr_nullable) + OS << " _Nullable"; + else if (T->getAttrKind() == AttributedType::attr_null_unspecified) + OS << " _Null_unspecified"; + else + llvm_unreachable("unhandled nullability"); + + return; + } +#endif + + //AC++: added if: + if(!remove_attributes) { + OS << " __attribute__(("; + switch (T->getAttrKind()) { + default: llvm_unreachable("This attribute should have been handled already"); + case AttributedType::attr_address_space: + OS << "address_space("; + OS << T->getEquivalentType().getAddressSpace(); + OS << ')'; + break; + + case AttributedType::attr_vector_size: { + OS << "__vector_size__("; + if (const VectorType *vector =T->getEquivalentType()->getAs()) { + OS << vector->getNumElements(); + OS << " * sizeof("; + print(vector->getElementType(), OS, StringRef()); + OS << ')'; + } + OS << ')'; + break; + } + + case AttributedType::attr_neon_vector_type: + case AttributedType::attr_neon_polyvector_type: { + if (T->getAttrKind() == AttributedType::attr_neon_vector_type) + OS << "neon_vector_type("; + else + OS << "neon_polyvector_type("; + const VectorType *vector = T->getEquivalentType()->getAs(); + OS << vector->getNumElements(); + OS << ')'; + break; + } + + case AttributedType::attr_regparm: { + // FIXME: When Sema learns to form this AttributedType, avoid printing the + // attribute again in printFunctionProtoAfter. + OS << "regparm("; + QualType t = T->getEquivalentType(); + while (!t->isFunctionType()) + t = t->getPointeeType(); + //AC++: FunctionType -> clang::FunctionType + OS << t->getAs()->getRegParmType(); + OS << ')'; + break; + } + + case AttributedType::attr_objc_gc: { + OS << "objc_gc("; + + QualType tmp = T->getEquivalentType(); + while (tmp.getObjCGCAttr() == Qualifiers::GCNone) { + QualType next = tmp->getPointeeType(); + if (next == tmp) break; + tmp = next; + } + + if (tmp.isObjCGCWeak()) + OS << "weak"; + else + OS << "strong"; + OS << ')'; + break; + } + + case AttributedType::attr_objc_ownership: + OS << "objc_ownership("; + switch (T->getEquivalentType().getObjCLifetime()) { + case Qualifiers::OCL_None: llvm_unreachable("no ownership!"); + case Qualifiers::OCL_ExplicitNone: OS << "none"; break; + case Qualifiers::OCL_Strong: OS << "strong"; break; + case Qualifiers::OCL_Weak: OS << "weak"; break; + case Qualifiers::OCL_Autoreleasing: OS << "autoreleasing"; break; + } + OS << ')'; + break; + + // FIXME: When Sema learns to form this AttributedType, avoid printing the + // attribute again in printFunctionProtoAfter. + case AttributedType::attr_noreturn: OS << "noreturn"; break; + + case AttributedType::attr_cdecl: OS << "cdecl"; break; + case AttributedType::attr_fastcall: OS << "fastcall"; break; + case AttributedType::attr_stdcall: OS << "stdcall"; break; + case AttributedType::attr_thiscall: OS << "thiscall"; break; +//AC++: added if +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_6_2 + case AttributedType::attr_vectorcall: OS << "vectorcall"; break; +#endif + case AttributedType::attr_pascal: OS << "pascal"; break; + case AttributedType::attr_ms_abi: OS << "ms_abi"; break; + case AttributedType::attr_sysv_abi: OS << "sysv_abi"; break; +//AC++: added if +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_4_0_0 + case AttributedType::attr_regcall: OS << "regcall"; break; +#endif + case AttributedType::attr_pcs: + case AttributedType::attr_pcs_vfp: { + OS << "pcs("; + QualType t = T->getEquivalentType(); + while (!t->isFunctionType()) + t = t->getPointeeType(); + //AC++: FunctionType -> clang::FunctionType + OS << (t->getAs()->getCallConv() == CC_AAPCS ? + "\"aapcs\"" : "\"aapcs-vfp\""); + OS << ')'; + break; + } + //AC++: kept case for backward compatibility +#if CLANG_VERSION_NUMBER <= VERSION_NUMBER_3_6_2 + case AttributedType::attr_pnaclcall: OS << "pnaclcall"; break; +#endif + case AttributedType::attr_inteloclbicc: OS << "inteloclbicc"; break; + } + OS << "))"; + } +} + +void AdjustedTypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T, + raw_ostream &OS) { + //AC++: added assert: + assert(false && "ObjC not supported."); + /*AC++: commented out: + OS << T->getDecl()->getName(); + spaceBeforePlaceHolder(OS); + */ +} +void AdjustedTypePrinter::printObjCInterfaceAfter(const ObjCInterfaceType *T, + raw_ostream &OS) { } + +//AC++: added if +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_4_0_0 +void AdjustedTypePrinter::printObjCTypeParamBefore(const ObjCTypeParamType *T, + raw_ostream &OS) { + OS << T->getDecl()->getName(); + if (!T->qual_empty()) { + bool isFirst = true; + OS << '<'; + for (const auto *I : T->quals()) { + if (isFirst) + isFirst = false; + else + OS << ','; + OS << I->getName(); + } + OS << '>'; + } + + spaceBeforePlaceHolder(OS); +} + +void AdjustedTypePrinter::printObjCTypeParamAfter(const ObjCTypeParamType *T, + raw_ostream &OS) { } +#endif + +void AdjustedTypePrinter::printObjCObjectBefore(const ObjCObjectType *T, + raw_ostream &OS) { + //AC++: added assert: + assert(false && "ObjC not supported."); + /*AC++: commented out: + if (T->qual_empty()) + return printBefore(T->getBaseType(), OS); + + print(T->getBaseType(), OS, StringRef()); + OS << '<'; + bool isFirst = true; + for (const auto *I : T->quals()) { + if (isFirst) + isFirst = false; + else + OS << ','; + OS << I->getName(); + } + OS << '>'; + spaceBeforePlaceHolder(OS); + + */ +} +void AdjustedTypePrinter::printObjCObjectAfter(const ObjCObjectType *T, + raw_ostream &OS) { + //AC++: added assert: + assert(false && "ObjC not supported."); + /*AC++: commented out: + if (T->qual_empty()) + return printAfter(T->getBaseType(), OS); + */ +} + + +void AdjustedTypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T, + raw_ostream &OS) { + //AC++: added assert: + assert(false && "ObjC not supported."); + //AC++: commented out: + //T->getPointeeType().getLocalQualifiers().print(OS, Policy, + // /*appendSpaceIfNonEmpty=*/true); + /* + assert(!T->isObjCSelType()); + + if (T->isObjCIdType() || T->isObjCQualifiedIdType()) + OS << "id"; + else if (T->isObjCClassType() || T->isObjCQualifiedClassType()) + OS << "Class"; + else + OS << T->getInterfaceDecl()->getName(); + + if (!T->qual_empty()) { + OS << '<'; + for (ObjCObjectPointerType::qual_iterator I = T->qual_begin(), + E = T->qual_end(); + I != E; ++I) { + OS << (*I)->getName(); + if (I+1 != E) + OS << ','; + } + OS << '>'; + } + + if (!T->isObjCIdType() && !T->isObjCQualifiedIdType() && + !T->isObjCClassType() && !T->isObjCQualifiedClassType()) { + OS << " *"; // Don't forget the implicit pointer. + } else { + spaceBeforePlaceHolder(OS); + } + */ +} + +void AdjustedTypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T, + raw_ostream &OS) { } + + +/* AC++: commented out: +void TemplateSpecializationType:: + PrintTemplateArgumentList(raw_ostream &OS, + const TemplateArgumentListInfo &Args, + const PrintingPolicy &Policy) { + return PrintTemplateArgumentList(OS, + Args.getArgumentArray(), + Args.size(), + Policy); +} +*/ + +//AC++: adjusted version of PrintTemplateArgumentList(...) +void AdjustedTypePrinter::adjusted_PrintTemplateArgumentList( + raw_ostream &OS, const TemplateArgument *Args, unsigned NumArgs, + /*AC++: commented out: const PrintingPolicy &Policy,*/ bool SkipBrackets) { + //Ac++: added if else +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_8_0 + const char *Comma = Policy.MSVCFormatting ? "," : ", "; +#else + const char *Comma = ", "; +#endif + + if (!SkipBrackets) + OS << '<'; + + bool needSpace = false; + for (unsigned Arg = 0; Arg < NumArgs; ++Arg) { + // Print the argument into a string. + SmallString<128> Buf; + llvm::raw_svector_ostream ArgOS(Buf); + if (Args[Arg].getKind() == TemplateArgument::Pack) { + if (Args[Arg].pack_size() && Arg > 0) + OS << Comma; + //AC++: before: PrintTemplateArgumentList(ArgOS, + adjusted_PrintTemplateArgumentList(ArgOS, + Args[Arg].pack_begin(), + Args[Arg].pack_size(), + /*AC++: commented out: Policy,*/ true); + } else { + if (Arg > 0) + OS << Comma; + //AC++: before: Args[Arg].print(Policy, ArgOS); + adjusted_TemplateArgument_print(Args[Arg], ArgOS); + } + StringRef ArgString = ArgOS.str(); + + // If this is the first argument and its string representation + // begins with the global scope specifier ('::foo'), add a space + // to avoid printing the diagraph '<:'. + if (!Arg && !ArgString.empty() && ArgString[0] == ':') + OS << ' '; + + OS << ArgString; + + needSpace = (!ArgString.empty() && ArgString.back() == '>'); + } + + // If the last character of our string is '>', add another space to + // keep the two '>''s separate tokens. We don't *have* to do this in + // C++0x, but it's still good hygiene. + if (needSpace) + OS << ' '; + + if (!SkipBrackets) + OS << '>'; +} + +/* AC++: commented out: +// Sadly, repeat all that with TemplateArgLoc. +void TemplateSpecializationType:: +PrintTemplateArgumentList(raw_ostream &OS, + const TemplateArgumentLoc *Args, unsigned NumArgs, + const PrintingPolicy &Policy) { + OS << '<'; + + bool needSpace = false; + for (unsigned Arg = 0; Arg < NumArgs; ++Arg) { + if (Arg > 0) + OS << ", "; + + // Print the argument into a string. + SmallString<128> Buf; + llvm::raw_svector_ostream ArgOS(Buf); + if (Args[Arg].getArgument().getKind() == TemplateArgument::Pack) { + PrintTemplateArgumentList(ArgOS, + Args[Arg].getArgument().pack_begin(), + Args[Arg].getArgument().pack_size(), + Policy, true); + } else { + Args[Arg].getArgument().print(Policy, ArgOS); + } + StringRef ArgString = ArgOS.str(); + + // If this is the first argument and its string representation + // begins with the global scope specifier ('::foo'), add a space + // to avoid printing the diagraph '<:'. + if (!Arg && !ArgString.empty() && ArgString[0] == ':') + OS << ' '; + + OS << ArgString; + + needSpace = (!ArgString.empty() && ArgString.back() == '>'); + } + + // If the last character of our string is '>', add another space to + // keep the two '>''s separate tokens. We don't *have* to do this in + // C++0x, but it's still good hygiene. + if (needSpace) + OS << ' '; + + OS << '>'; +} +*/ + + +/*AC++: commented out: +std::string Qualifiers::getAsString() const { + LangOptions LO; + return getAsString(PrintingPolicy(LO)); +} + +// Appends qualifiers to the given string, separated by spaces. Will +// prefix a space if the string is non-empty. Will not append a final +// space. +std::string Qualifiers::getAsString(const PrintingPolicy &Policy) const { + SmallString<64> Buf; + llvm::raw_svector_ostream StrOS(Buf); + print(StrOS, Policy); + return StrOS.str(); +} + +bool Qualifiers::isEmptyWhenPrinted(const PrintingPolicy &Policy) const { + if (getCVRQualifiers()) + return false; + + if (getAddressSpace()) + return false; + + if (getObjCGCAttr()) + return false; + + if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) + if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)) + return false; + + return true; +} + +// Appends qualifiers to the given string, separated by spaces. Will +// prefix a space if the string is non-empty. Will not append a final +// space. +void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy, + bool appendSpaceIfNonEmpty) const { + bool addSpace = false; + + unsigned quals = getCVRQualifiers(); + if (quals) { + AppendTypeQualList(OS, quals); + addSpace = true; + } + if (unsigned addrspace = getAddressSpace()) { + if (addSpace) + OS << ' '; + addSpace = true; + switch (addrspace) { + case LangAS::opencl_global: + OS << "__global"; + break; + case LangAS::opencl_local: + OS << "__local"; + break; + case LangAS::opencl_constant: + OS << "__constant"; + break; + case LangAS::opencl_generic: + OS << "__generic"; + break; + default: + OS << "__attribute__((address_space("; + OS << addrspace; + OS << ")))"; + } + } + if (Qualifiers::GC gc = getObjCGCAttr()) { + if (addSpace) + OS << ' '; + addSpace = true; + if (gc == Qualifiers::Weak) + OS << "__weak"; + else + OS << "__strong"; + } + if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) { + if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)){ + if (addSpace) + OS << ' '; + addSpace = true; + } + + switch (lifetime) { + case Qualifiers::OCL_None: llvm_unreachable("none but true"); + case Qualifiers::OCL_ExplicitNone: OS << "__unsafe_unretained"; break; + case Qualifiers::OCL_Strong: + if (!Policy.SuppressStrongLifetime) + OS << "__strong"; + break; + + case Qualifiers::OCL_Weak: OS << "__weak"; break; + case Qualifiers::OCL_Autoreleasing: OS << "__autoreleasing"; break; + } + } + + if (appendSpaceIfNonEmpty && addSpace) + OS << ' '; +} + +std::string QualType::getAsString(const PrintingPolicy &Policy) const { + std::string S; + getAsStringInternal(S, Policy); + return S; +} + +std::string QualType::getAsString(const Type *ty, Qualifiers qs) { + std::string buffer; + LangOptions options; + getAsStringInternal(ty, qs, buffer, PrintingPolicy(options)); + return buffer; +} + +void QualType::print(const Type *ty, Qualifiers qs, + raw_ostream &OS, const PrintingPolicy &policy, + const Twine &PlaceHolder) { + SmallString<128> PHBuf; + StringRef PH = PlaceHolder.toStringRef(PHBuf); + + TypePrinter(policy).print(ty, qs, OS, PH); +} + +void QualType::getAsStringInternal(const Type *ty, Qualifiers qs, + std::string &buffer, + const PrintingPolicy &policy) { + SmallString<256> Buf; + llvm::raw_svector_ostream StrOS(Buf); + TypePrinter(policy).print(ty, qs, StrOS, buffer); + std::string str = StrOS.str(); + buffer.swap(str); +} +*/ + +//AC++: commented out: } //AC++: belongs to anonymous namespace commented out in header file + +//AC++: end of TypePrinter.cpp +//AC++: ######################################################################## + + +//AC++: additional member functions: + +//AC++: adjusted version of NamedDecl::printQualifiedName(...) (from Decl.cpp) +//AC++: added first argument as replacement of this +void AdjustedTypePrinter::adjusted_NamedDecl_printQualifiedName(const NamedDecl* named_decl, raw_ostream &OS/*AC++: removed:, + const PrintingPolicy &P*/) { + const DeclContext *Ctx = named_decl->getDeclContext(); + + + if (Ctx->isFunctionOrMethod()) { + //AC++: before: printName(OS); + named_decl->printName(OS); + return; + } + + typedef SmallVector ContextsTy; + ContextsTy Contexts; + + //AC++: If the decl-to-print is a TagDecl, then handle the decl + // itself like its contexts. Thus e.g. template arguments of the decl + // are printed. + bool decl_is_handled = false; + if(isa(named_decl)) { + Contexts.push_back(cast(named_decl)); + decl_is_handled = true; + } + + // AC++: + bool has_global_namespace = false; + + //AC++: do not collect contexts if we should not print qualifiers/nested name specifiers/contexts + if(!(absolute_qualified == TSEF_DISABLE)) { + // Collect contexts. + while (Ctx && isa(Ctx)) { + // AC++: + if (absolute_qualified == TSEF_ENABLE && Ctx->isNamespace() && cast(Ctx)->getName() == "::") { + has_global_namespace = true; + } + + Contexts.push_back(Ctx); + Ctx = Ctx->getParent(); + } + } + + // AC++: + if (elaborated_keyword == TSEF_ENABLE && isa(named_decl)) { + OS << cast(named_decl)->getKindName(); + OS << ' '; + } + + // AC++: + if(absolute_qualified == TSEF_ENABLE && !has_global_namespace) { + OS << "::"; + } + + //AC++: The following code uses + // inline raw_ostream &operator<<(raw_ostream &OS, const NamedDecl &ND) { + // ND.printName(OS); + // return OS; + // } + + + for (ContextsTy::reverse_iterator I = Contexts.rbegin(), E = Contexts.rend(); + I != E; ++I) { + //AC++: added if block: + if(!keep_typedef && isa(*I)){ + const TypedefNameDecl* typedefdecl = cast(*I); + QualType underlying_type = typedefdecl->getCanonicalDecl()->getTypeSourceInfo()->getType(); + // TODO: RAII + TriStateEnableFeature old_abs = absolute_qualified; + absolute_qualified = TSEF_DISABLE; + print(underlying_type, OS, StringRef()); + absolute_qualified = old_abs; + } + else if (const ClassTemplateSpecializationDecl *Spec + = dyn_cast(*I)) { + OS << Spec->getName(); + const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); + //AC++: before: TemplateSpecializationType::PrintTemplateArgumentList(OS, + adjusted_PrintTemplateArgumentList(OS, + TemplateArgs.data(), + TemplateArgs.size()/*AC++: commented out: , + P*/); + } else if (const NamespaceDecl *ND = dyn_cast(*I)) { + //AC++: P -> Policy + if (Policy.SuppressUnwrittenScope && + (ND->isAnonymousNamespace() || ND->isInline())) + continue; + if (ND->isAnonymousNamespace()) +//Ac++: added if else +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_8_0 + OS << (Policy.MSVCFormatting ? "`anonymous namespace\'" + : "(anonymous namespace)"); +#elif CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_6_2 + OS << "(anonymous namespace)"; +#else + OS << ""; +#endif + + else + OS << *ND; // see above + } else if (const RecordDecl *RD = dyn_cast(*I)) { + if (!RD->getIdentifier()) +//Ac++: added if else +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_6_2 + OS << "(anonymous " << RD->getKindName() << ')'; +#else + OS << "getKindName() << '>'; +#endif + else + OS << *RD; + } else if (const FunctionDecl *FD = dyn_cast(*I)) { + const FunctionProtoType *FT = 0; + if (FD->hasWrittenPrototype()) + //AC++: FunctionType -> clang::FunctionType + FT = dyn_cast(FD->getType()->castAs()); + + OS << *FD << '('; + if (FT) { + unsigned NumParams = FD->getNumParams(); + for (unsigned i = 0; i < NumParams; ++i) { + if (i) + OS << ", "; + //AC++: before: OS << FD->getParamDecl(i)->getType().stream(P); + print(FD->getParamDecl(i)->getType(), OS, StringRef()); + } + + if (FT->isVariadic()) { + if (NumParams > 0) + OS << ", "; + OS << "..."; + } + } + OS << ')'; + } else if (const auto *ED = dyn_cast(*I)) { + // C++ [dcl.enum]p10: Each enum-name and each unscoped + // enumerator is declared in the scope that immediately contains + // the enum-specifier. Each scoped enumerator is declared in the + // scope of the enumeration. + if (ED->isScoped() || ED->getIdentifier()) + OS << *ED; + else + continue; + } else { + OS << *cast(*I); + } + //AC++: added if: + // If we handled the decl-to-print and this is the last iteration, + // do not add the "::". + if(!(decl_is_handled && *I == cast(named_decl))) { + OS << "::"; + } + } + + //AC++: added first if: + // If we already handled the decl to print (like its contexts) + // we do not need handle it here anymore. + if(!decl_is_handled){ + if (named_decl->getDeclName() +//Ac++: added if +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_4_0_0 + || isa(named_decl) +#endif + ) + //AC++: before: OS << *this; + OS << *named_decl; + else +//Ac++: added if else +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_6_2 + OS << "(anonymous)"; +#else + OS << ""; +#endif + } +} + +//AC++: adjusted version of printIntegral (from TemplateBase.cpp) used by adjusted_TemplateArgument_print(...) +/// \brief Print a template integral argument value. +/// +/// \param TemplArg the TemplateArgument instance to print. +/// +/// \param Out the raw_ostream instance to use for printing. +/// +/// \param Policy the printing policy for EnumConstantDecl printing. +void AdjustedTypePrinter::adjusted_printIntegral(const TemplateArgument &TemplArg, + raw_ostream &Out/*AC++: commented out: , const PrintingPolicy& Policy*/) { + const ::clang::Type *T = TemplArg.getIntegralType().getTypePtr(); + const llvm::APSInt &Val = TemplArg.getAsIntegral(); + +//AC++: added if +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_6_2 + if (const EnumType *ET = T->getAs()) { + for (const EnumConstantDecl* ECD : ET->getDecl()->enumerators()) { + // In Sema::CheckTemplateArugment, enum template arguments value are + // extended to the size of the integer underlying the enum type. This + // may create a size difference between the enum value and template + // argument value, requiring isSameValue here instead of operator==. + if (llvm::APSInt::isSameValue(ECD->getInitVal(), Val)) { + // AC++: Before: ECD->printQualifiedName(Out, Policy); + adjusted_NamedDecl_printQualifiedName(cast(ECD), Out); + return; + } + } + } +#endif + + if (T->isBooleanType() +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_8_0 + && !Policy.MSVCFormatting +#endif + ) { + Out << (Val.getBoolValue() ? "true" : "false"); + } else if (T->isCharType()) { + const char Ch = Val.getZExtValue(); + Out << ((Ch == '\'') ? "'\\" : "'"); + Out.write_escaped(StringRef(&Ch, 1), /*UseHexEscapes=*/ true); + Out << "'"; + } else { + Out << Val; + } +} + +//AC++: adjusted version of TemplateArgument::print(...) (from TemplateBase.cpp) +//AC++: added first argument as replacement of *this +void AdjustedTypePrinter::adjusted_TemplateArgument_print(const TemplateArgument& temp_arg, /*AC++: commented out:const PrintingPolicy &Policy,*/ + raw_ostream &Out) { + //AC++: added nested name specifier "TemplateArgument::" at every case. + //AC++: before: switch (getKind()) { + switch (temp_arg.getKind()) { + case TemplateArgument::Null: +//Ac++: added if else +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_6_2 + Out << "(no value)"; +#else + Out << ""; +#endif + break; + + case TemplateArgument::Type: { + //AC++: commented out: + //PrintingPolicy SubPolicy(Policy); + //SubPolicy.SuppressStrongLifetime = true; + + //AC++: Before: getAsType().print(Out, SubPolicy); + print(temp_arg.getAsType(), Out, StringRef()); + break; + } + + case TemplateArgument::Declaration: { + //AC++: before: NamedDecl *ND = cast(getAsDecl()); + NamedDecl *ND = cast(temp_arg.getAsDecl()); + Out << '&'; + if (ND->getDeclName()) { + // FIXME: distinguish between pointer and reference args? + // AC++: Before: ND->printQualifiedName(Out); + adjusted_NamedDecl_printQualifiedName(ND, Out); + } else { +//Ac++: added if else +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_6_2 + Out << "(anonymous)"; +#else + Out << ""; +#endif + } + break; + } + + case TemplateArgument::NullPtr: + Out << "nullptr"; + break; + + case TemplateArgument::Template: + //AC++: before: getAsTemplate().print(Out, Policy); + adjusted_TemplateName_print(temp_arg.getAsTemplate(), Out); + break; + + case TemplateArgument::TemplateExpansion: + //AC++: before: getAsTemplateOrTemplatePattern().print(Out, Policy); + adjusted_TemplateName_print(temp_arg.getAsTemplateOrTemplatePattern(), Out); + Out << "..."; + break; + + case TemplateArgument::Integral: { + //AC++: before: printIntegral(*this, Out, Policy); + adjusted_printIntegral(temp_arg, Out); + break; + } + + case TemplateArgument::Expression: + //AC++: before: getAsExpr()->printPretty(Out, nullptr, Policy); + //AC++: TODO: make adjusted version! + temp_arg.getAsExpr()->printPretty(Out, nullptr, Policy); + break; + + case TemplateArgument::Pack: + Out << "<"; + bool First = true; +//Ac++: added if else +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_6_2 + //AC++: before: for (const auto &P : pack_elements()) { + for (const auto &P : temp_arg.pack_elements()) { +#else + for (TemplateArgument::pack_iterator P_p = temp_arg.pack_begin(), PEnd = temp_arg.pack_end(); + P_p != PEnd; ++P_p) { + const auto &P = *P_p; +#endif + if (First) + First = false; + else + Out << ", "; + + //AC++: before: P.print(Policy, Out); + adjusted_TemplateArgument_print(P, Out); + } + Out << ">"; + break; + } +} + +//AC++: adjusted version of TemplateName::print(...) (from TemplateName.cpp) +//AC++: added first argument as replacement of *this +void AdjustedTypePrinter::adjusted_TemplateName_print(const TemplateName& templ_name, raw_ostream &OS/*AC++: commented out:, + const PrintingPolicy &Policy, bool SuppressNNS*/) { + //AC++: replaced implicit *this by templ_name + + //AC++: before: if (TemplateDecl *Template = Storage.dyn_cast()) + //AC++: Storage is private, so take an indirection to emulate Storage.dyn_cast() + TemplateDecl* Template = 0; + if (templ_name.getKind() == TemplateName::Template && (Template = templ_name.getAsTemplateDecl())) + //AC++: before: OS << *Template; + adjusted_NamedDecl_printQualifiedName(Template, OS); + else if (QualifiedTemplateName *QTN = templ_name.getAsQualifiedTemplateName()) { + //AC++: removed: if(!suppressNNS) + //AC++: before: QTN->getQualifier()->print(OS, Policy); + adjusted_NestedNameSpecifier_print(QTN->getQualifier(), OS); + + if (QTN->hasTemplateKeyword()) + OS << "template "; + //AC++: OS << *QTN->getDecl(); + //AC++: only print the decl (without nested name specifier): + TriStateEnableFeature old_abs = absolute_qualified; + absolute_qualified = TSEF_DISABLE; + adjusted_NamedDecl_printQualifiedName(QTN->getDecl(), OS); + absolute_qualified = old_abs; + } else if (DependentTemplateName *DTN = templ_name.getAsDependentTemplateName()) { + //AC++: before: if (!SuppressNNS && DTN->getQualifier()) + if (DTN->getQualifier()) + //AC++: before: DTN->getQualifier()->print(OS, Policy); + adjusted_NestedNameSpecifier_print(DTN->getQualifier(), OS); + OS << "template "; + + if (DTN->isIdentifier()) + //AC++: TODO: Use adjusted printing? + OS << DTN->getIdentifier()->getName(); + else + OS << "operator " << getOperatorSpelling(DTN->getOperator()); + } else if (SubstTemplateTemplateParmStorage *subst + = templ_name.getAsSubstTemplateTemplateParm()) { + //AC++: before: subst->getReplacement().print(OS, Policy, SuppressNNS); + adjusted_TemplateArgument_print(subst->getReplacement(), OS); + } else if (SubstTemplateTemplateParmPackStorage *SubstPack + = templ_name.getAsSubstTemplateTemplateParmPack()) + OS << *SubstPack->getParameterPack(); + else { + OverloadedTemplateStorage *OTS = templ_name.getAsOverloadedTemplate(); + //AC++: TODO: Use adjusted printing? + (*OTS->begin())->printName(OS); + } +} + +//AC++: adjusted version of NestedNameSpecifier::print(...) (from NestedNameSpecifier.cpp) +//AC++: added first argument as replacement of this +void AdjustedTypePrinter::adjusted_NestedNameSpecifier_print(const NestedNameSpecifier* nns, raw_ostream &OS/*AC++: commented out:, + const PrintingPolicy &Policy*/) { + //AC++: replaced implicit this by nns + + //AC++: + if(absolute_qualified == TSEF_DISABLE) { + return; + } + + if (nns->getPrefix()) { + //AC++: before getPrefix()->print(OS, Policy); + adjusted_NestedNameSpecifier_print(nns->getPrefix(), OS); + } + else { + //AC++: Add root qualifier if it does not exist + if(absolute_qualified == TSEF_ENABLE && nns->getKind() != NestedNameSpecifier::Global) { + OS << "::"; + } + } + + //AC++: added qualifier to constants used in cases of switch + switch (nns->getKind()) { + case NestedNameSpecifier::Identifier: + OS << nns->getAsIdentifier()->getName(); + break; + + case NestedNameSpecifier::Namespace: + if (nns->getAsNamespace()->isAnonymousNamespace()) + return; + + OS << nns->getAsNamespace()->getName(); + break; + + case NestedNameSpecifier::NamespaceAlias: + OS << nns->getAsNamespaceAlias()->getName(); + break; + + case NestedNameSpecifier::Global: + break; + +//Ac++: added if +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_6_2 + case NestedNameSpecifier::Super: + OS << "__super"; + break; +#endif + + case NestedNameSpecifier::TypeSpecWithTemplate: + OS << "template "; + // Fall through to print the type. + + case NestedNameSpecifier::TypeSpec: { + const Type *T = nns->getAsType(); + + //AC++: commented out: +// PrintingPolicy InnerPolicy(Policy); +// InnerPolicy.SuppressScope = true; + + TriStateEnableFeature old_abs = absolute_qualified; + absolute_qualified = TSEF_DISABLE; + + // Nested-name-specifiers are intended to contain minimally-qualified + // types. An actual ElaboratedType will not occur, since we'll store + // just the type that is referred to in the nested-name-specifier (e.g., + // a TypedefType, TagType, etc.). However, when we are dealing with + // dependent template-id types (e.g., Outer::template Inner), + // the type requires its own nested-name-specifier for uniqueness, so we + // suppress that nested-name-specifier during printing. + assert(!isa(T) && + "Elaborated type in nested-name-specifier"); + if (const TemplateSpecializationType *SpecType + = dyn_cast(T)) { + // Print the template name without its corresponding + // nested-name-specifier. + //AC++: before: SpecType->getTemplateName().print(OS, InnerPolicy, true); + adjusted_TemplateName_print(SpecType->getTemplateName(), OS); + + // Print the template argument list. + //AC++: before: TemplateSpecializationType::PrintTemplateArgumentList( + // OS, SpecType->getArgs(), SpecType->getNumArgs(), InnerPolicy); + adjusted_PrintTemplateArgumentList(OS, SpecType->getArgs(), SpecType->getNumArgs()); + } else { + // Print the type normally + //AC++: before: QualType(T, 0).print(OS, InnerPolicy); + print(QualType(T, 0), OS, StringRef()); + } + absolute_qualified = old_abs; + break; + } + } + + OS << "::"; +} +#endif \ No newline at end of file diff --git a/AspectC++/ClangAdjustedTypePrinter.h b/AspectC++/ClangAdjustedTypePrinter.h new file mode 100644 index 0000000..0d9115a --- /dev/null +++ b/AspectC++/ClangAdjustedTypePrinter.h @@ -0,0 +1,181 @@ +//===--- TypePrinter.cpp - Pretty-Print Clang Types -----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This contains code to print types from Clang's type system. +// +//===----------------------------------------------------------------------===// + +// Adjusted by AspectC++ to support printing of absolute types, printing of elaborated type specifier and removing of attributes. +// The file TypePrinter.cpp was taken from clang version 3.6.2 and split into a header file and a file containing the implementations. +// Changes are marked with //AC++. +// See the ClangAdjustedTypePrinter.cpp file for more information. + +//AC++: added include guard: +#ifndef __ClangAdjustedTypePrinter_h__ +#define __ClangAdjustedTypePrinter_h__ +#include "version.h" +#if CLANG_VERSION_NUMBER < VERSION_NUMBER_5_0_0 +#include "clang/AST/PrettyPrinter.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclObjC.h" +#include "clang/AST/DeclTemplate.h" +#include "clang/AST/Expr.h" +#include "clang/AST/Type.h" +#include "clang/Basic/LangOptions.h" +#include "clang/Basic/SourceManager.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/Support/SaveAndRestore.h" +#include "llvm/Support/raw_ostream.h" +//AC++: commented out: using namespace clang; + +//AC++: commented out: namespace { +#endif +//AC++: enum added: +enum TriStateEnableFeature { + TSEF_ENABLE = true, + TSEF_DISABLE = false, + TSEF_DONOTCHANGE = 2, +}; +#if CLANG_VERSION_NUMBER < VERSION_NUMBER_5_0_0 +//AC++: added "clang::" nested name specifier to every clang type + + /// \brief RAII object that enables printing of the ARC __strong lifetime + /// qualifier. + class IncludeStrongLifetimeRAII { + clang::PrintingPolicy &Policy; + bool Old; + + public: + explicit IncludeStrongLifetimeRAII(clang::PrintingPolicy &Policy) + : Policy(Policy), Old(Policy.SuppressStrongLifetime) { + if (!Policy.SuppressLifetimeQualifiers) + Policy.SuppressStrongLifetime = false; + } + + ~IncludeStrongLifetimeRAII() { + Policy.SuppressStrongLifetime = Old; + } + }; + + class ParamPolicyRAII { + clang::PrintingPolicy &Policy; + bool Old; + + public: + explicit ParamPolicyRAII(clang::PrintingPolicy &Policy) + : Policy(Policy), Old(Policy.SuppressSpecifiers) { + Policy.SuppressSpecifiers = false; + } + + ~ParamPolicyRAII() { + Policy.SuppressSpecifiers = Old; + } + }; +/*AC++: commented out: + class ElaboratedTypePolicyRAII { + clang::PrintingPolicy &Policy; + bool SuppressTagKeyword; + bool SuppressScope; + + public: + explicit ElaboratedTypePolicyRAII(clang::PrintingPolicy &Policy) : Policy(Policy) { + SuppressTagKeyword = Policy.SuppressTagKeyword; + SuppressScope = Policy.SuppressScope; + Policy.SuppressTagKeyword = true; + Policy.SuppressScope = true; + } + + ~ElaboratedTypePolicyRAII() { + Policy.SuppressTagKeyword = SuppressTagKeyword; + Policy.SuppressScope = SuppressScope; + } + }; +*/ + //AC++: renamed TypePrinter to AdjustedTypePrinter + class AdjustedTypePrinter { + clang::PrintingPolicy Policy; + unsigned Indentation; + bool HasEmptyPlaceHolder; + bool InsideCCAttribute; + //AC++: added members: + TriStateEnableFeature absolute_qualified; + bool keep_typedef; + TriStateEnableFeature elaborated_keyword; + bool remove_attributes; + bool as_parameter_signature_type; + const clang::ASTContext* ctx; + + public: + //AC++: adjusted constructor: + explicit AdjustedTypePrinter(const clang::PrintingPolicy &Policy, + TriStateEnableFeature absolute_qualfied, + bool keep_typedef, + TriStateEnableFeature elaborated_keyword, + bool remove_attributes, + bool as_parameter_signature_type, + const clang::ASTContext* ctx, + unsigned Indentation = 0) + : Policy(Policy), Indentation(Indentation), HasEmptyPlaceHolder(false), + InsideCCAttribute(false), + absolute_qualified(absolute_qualfied), keep_typedef(keep_typedef), + elaborated_keyword(elaborated_keyword), remove_attributes(remove_attributes), + as_parameter_signature_type(as_parameter_signature_type), ctx(ctx){ } + + //AC++: commented out: + //explicit AdjustedTypePrinter(const PrintingPolicy &Policy) + // : AdjustedTypePrinter(Policy, false, false) { } + + //AC++: added private: + private: + void print(const clang::Type *ty, clang::Qualifiers qs, clang::raw_ostream &OS, + clang::StringRef PlaceHolder); + //AC++: added public: + public: + void print(clang::QualType T, clang::raw_ostream &OS, clang::StringRef PlaceHolder); + //AC++: added private: + private: + static bool canPrefixQualifiers(const clang::Type *T, bool &NeedARCStrongQualifier); + void spaceBeforePlaceHolder(clang::raw_ostream &OS); + void printTypeSpec(const clang::NamedDecl *D, clang::raw_ostream &OS); + + void printBefore(const clang::Type *ty, clang::Qualifiers qs, clang::raw_ostream &OS); + void printBefore(clang::QualType T, clang::raw_ostream &OS); + void printAfter(const clang::Type *ty, clang::Qualifiers qs, clang::raw_ostream &OS); + void printAfter(clang::QualType T, clang::raw_ostream &OS); + void AppendScope(clang::DeclContext *DC, clang::raw_ostream &OS); + void printTag(clang::TagDecl *T, clang::raw_ostream &OS); +#define ABSTRACT_TYPE(CLASS, PARENT) +#define TYPE(CLASS, PARENT) \ + void print##CLASS##Before(const clang::CLASS##Type *T, clang::raw_ostream &OS); \ + void print##CLASS##After(const clang::CLASS##Type *T, clang::raw_ostream &OS); +#include "clang/AST/TypeNodes.def" + //AC++: added public: + public: + //AC++: added member functions. For more information see implementation. + void adjusted_PrintTemplateArgumentList(clang::raw_ostream &OS, const clang::TemplateArgument *Args, + unsigned NumArgs, /*AC++: commented out: const clang::PrintingPolicy &Policy,*/ bool SkipBrackets = false); + void adjusted_TemplateArgument_print(const clang::TemplateArgument& temp_arg, /*AC++: commented out:const clang::PrintingPolicy &Policy,*/ + clang::raw_ostream &Out); + void adjusted_NamedDecl_printQualifiedName(const clang::NamedDecl* named_decl, clang::raw_ostream &OS /*AC++: removed:, + const clang::PrintingPolicy &P*/); + void adjusted_printIntegral(const clang::TemplateArgument &TemplArg, + clang::raw_ostream &Out/*AC++: commented out: , const clang::PrintingPolicy& Policy*/); + void adjusted_TemplateName_print(const clang::TemplateName& templ_name, clang::raw_ostream &OS/*AC++: commented out: , + const PrintingPolicy &Policy, bool SuppressNNS*/); + void adjusted_NestedNameSpecifier_print(const clang::NestedNameSpecifier* nns, clang::raw_ostream &OS/*AC++: commented out:, + const PrintingPolicy &Policy*/); + }; + +//AC++: continuation in ClangAdjustedTypePrinter.cc + +//AC++: Added include guard: +#endif +#endif // __ClangAdjustedTypePrinter_h__ diff --git a/AspectC++/ClangAnnotation.cc b/AspectC++/ClangAnnotation.cc new file mode 100644 index 0000000..75d2b4d --- /dev/null +++ b/AspectC++/ClangAnnotation.cc @@ -0,0 +1,42 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "ClangAnnotation.h" + +std::string Annotation::get_name() const { + return attrNames[attrNames.size() - 1]; +} + +std::string Annotation::get_qualified_name() const { + std::string result = attrNames[0]; + for (unsigned i = 1; i < attrNames.size(); i++) + result += std::string("::") + attrNames[i]; + return result; +} + +std::string Annotation::to_string() const { + std::string result = "[["; + result += get_qualified_name(); + if (!params.empty()) { + result += "("; + result += params; + result += ")"; + } + result += "]]"; + return result; +} diff --git a/AspectC++/ClangAnnotation.h b/AspectC++/ClangAnnotation.h new file mode 100644 index 0000000..647fa7f --- /dev/null +++ b/AspectC++/ClangAnnotation.h @@ -0,0 +1,39 @@ +#ifndef ANNOTATION_H +#define ANNOTATION_H + +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 +#include +#include +#include "clang/Basic/SourceLocation.h" + +struct Annotation { + clang::SourceLocation tokBegin, tokEnd, seqBegin, seqEnd; + std::vector attrNames; + std::string params; + bool is_user_defined; + std::string get_name() const; + std::string get_qualified_name() const; + std::string to_string() const; +}; + +typedef std::map AnnotationMap; + +#endif // ANNOTATION_H diff --git a/AspectC++/ClangBinding.cc b/AspectC++/ClangBinding.cc new file mode 100644 index 0000000..6aa7c12 --- /dev/null +++ b/AspectC++/ClangBinding.cc @@ -0,0 +1,210 @@ +#include "clang/Basic/Version.h" + +#if CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR == 5 && CLANG_VERSION_PATCHLEVEL == 0 +#elif CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR == 6 && CLANG_VERSION_PATCHLEVEL == 2 +#elif CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR == 7 && CLANG_VERSION_PATCHLEVEL == 1 +#elif CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR == 8 && CLANG_VERSION_PATCHLEVEL == 0 +#elif CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR == 8 && CLANG_VERSION_PATCHLEVEL == 1 +#elif CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR == 9 && CLANG_VERSION_PATCHLEVEL == 1 +#elif CLANG_VERSION_MAJOR == 4 && CLANG_VERSION_MINOR == 0 && CLANG_VERSION_PATCHLEVEL == 0 +#elif CLANG_VERSION_MAJOR == 4 && CLANG_VERSION_MINOR == 0 && CLANG_VERSION_PATCHLEVEL == 1 +#elif CLANG_VERSION_MAJOR == 5 && CLANG_VERSION_MINOR == 0 && CLANG_VERSION_PATCHLEVEL == 0 +#else +#warning "Invalid clang version used! Only 3.5.0, 3.6.2, 3.7.1, 3.8.0, 3.8.1, 3.9.1, 4.0.0, 4.0.1, and 5.0.0 are supported by this code." +#endif + +#include "ClangIntroSema.h" +#include "ClangWeaverBase.h" +using namespace clang; + +// first define some helper macros to avoid code duplication + +#ifdef __APPLE__ +#define WRAP(x) x +#else +#define WRAP(x) __wrap_##x +#endif + +#define GEN_SEMA_WRAPPER_WITH_RESULT(result_type, func_name, mangled, param_list, ...) \ + extern "C" result_type WRAP(mangled) param_list; \ + result_type WRAP(mangled) param_list { \ + ClangIntroSema &sema = (ClangIntroSema&)that; \ + return sema.func_name(__VA_ARGS__); \ + } \ + extern "C" result_type __real_##mangled param_list; \ + result_type Real##func_name param_list { \ + return __real_##mangled(that, __VA_ARGS__); \ + } + +#define GEN_SEMA_WRAPPER_NO_RESULT(func_name, mangled, param_list, ...) \ + extern "C" void WRAP(mangled) param_list; \ + void WRAP(mangled) param_list { \ + ClangIntroSema &sema = (ClangIntroSema&)that; \ + sema.func_name(__VA_ARGS__); \ + } \ + extern "C" void __real_##mangled param_list; \ + void Real##func_name param_list { \ + __real_##mangled(that, __VA_ARGS__); \ + } + +#define GEN_SEMA_WRAPPER_NO_RESULT_NO_ARG(func_name, mangled) \ + extern "C" void WRAP(mangled) (Sema &that); \ + void WRAP(mangled) (Sema &that) { \ + ClangIntroSema &sema = (ClangIntroSema&)that; \ + sema.func_name(); \ + } \ + extern "C" void __real_##mangled (Sema &that); \ + void Real##func_name (Sema &that) { \ + __real_##mangled(that); \ + } + +// wrapper for Sema::ActOnStartCXXMemberDeclarations +GEN_SEMA_WRAPPER_NO_RESULT(ActOnStartCXXMemberDeclarations, _ZN5clang4Sema31ActOnStartCXXMemberDeclarationsEPNS_5ScopeEPNS_4DeclENS_14SourceLocationEbS5_, \ + (Sema &that, Scope *S, Decl *TagDecl, SourceLocation FinalLoc, bool IsFinalSpelledSealed, SourceLocation LBraceLoc), \ + S, TagDecl, FinalLoc, IsFinalSpelledSealed, LBraceLoc) + +// wrapper for Sema::ActOnBaseSpecifiers +#if FRONTEND_CLANG >= 38 +GEN_SEMA_WRAPPER_NO_RESULT(ActOnBaseSpecifiers, _ZN5clang4Sema19ActOnBaseSpecifiersEPNS_4DeclEN4llvm15MutableArrayRefIPNS_16CXXBaseSpecifierEEE, \ + (clang::Sema &that, clang::Decl *ClassDecl, clang::MutableArrayRef Bases), \ + ClassDecl, Bases) +#else +GEN_SEMA_WRAPPER_NO_RESULT(ActOnBaseSpecifiers, _ZN5clang4Sema19ActOnBaseSpecifiersEPNS_4DeclEPPNS_16CXXBaseSpecifierEj, \ + (clang::Sema &that, clang::Decl *ClassDecl, clang::CXXBaseSpecifier **Bases, unsigned NumBases), \ + ClassDecl, Bases, NumBases) +#endif + +// wrapper for Sema::ActOnStartOfFunctionDef +#if FRONTEND_CLANG >= 38 +GEN_SEMA_WRAPPER_WITH_RESULT(clang::Decl*, ActOnStartOfFunctionDef, _ZN5clang4Sema23ActOnStartOfFunctionDefEPNS_5ScopeERNS_10DeclaratorEN4llvm15MutableArrayRefIPNS_21TemplateParameterListEEEPNS0_12SkipBodyInfoE, \ + (clang::Sema &that, clang::Scope *S, clang::Declarator &D, clang::MultiTemplateParamsArg TemplateParamLists, clang::Sema::SkipBodyInfo *SkipBody), S, D, TemplateParamLists, SkipBody) +#else +GEN_SEMA_WRAPPER_WITH_RESULT(clang::Decl*, ActOnStartOfFunctionDef, _ZN5clang4Sema23ActOnStartOfFunctionDefEPNS_5ScopeERNS_10DeclaratorE, \ + (clang::Sema &that, clang::Scope *S, clang::Declarator &D), S, D) +#endif + +// wrapper for Sema::ActOnStartNamespaceDef +#if FRONTEND_CLANG >= 38 +GEN_SEMA_WRAPPER_WITH_RESULT(clang::Decl*, ActOnStartNamespaceDef, _ZN5clang4Sema22ActOnStartNamespaceDefEPNS_5ScopeENS_14SourceLocationES3_S3_PNS_14IdentifierInfoES3_PNS_13AttributeListERPNS_18UsingDirectiveDeclE, \ + (clang::Sema &that, clang::Scope *S, clang::SourceLocation InlineLoc, clang::SourceLocation NamespaceLoc, + clang::SourceLocation IdentLoc, clang::IdentifierInfo *Ident, clang::SourceLocation LBrace, clang::AttributeList *AttrList, clang::UsingDirectiveDecl * &UsingDecl), \ + S, InlineLoc, NamespaceLoc, IdentLoc, Ident, LBrace, AttrList, UsingDecl) +#else +GEN_SEMA_WRAPPER_WITH_RESULT(clang::Decl*, ActOnStartNamespaceDef, _ZN5clang4Sema22ActOnStartNamespaceDefEPNS_5ScopeENS_14SourceLocationES3_S3_PNS_14IdentifierInfoES3_PNS_13AttributeListE, \ + (clang::Sema &that, clang::Scope *S, clang::SourceLocation InlineLoc, clang::SourceLocation NamespaceLoc, + clang::SourceLocation IdentLoc, clang::IdentifierInfo *Ident, clang::SourceLocation LBrace, clang::AttributeList *AttrList), \ + S, InlineLoc, NamespaceLoc, IdentLoc, Ident, LBrace, AttrList) +#endif + +// wrapper for Decl *Sema::ActOnTag +#if FRONTEND_CLANG >= 50 +GEN_SEMA_WRAPPER_WITH_RESULT(clang::Decl*, ActOnTag, \ + _ZN5clang4Sema8ActOnTagEPNS_5ScopeEjNS0_10TagUseKindENS_14SourceLocationERNS_12CXXScopeSpecEPNS_14IdentifierInfoES4_PNS_13AttributeListENS_15AccessSpecifierES4_N4llvm15MutableArrayRefIPNS_21TemplateParameterListEEERbSH_S4_bNS_12ActionResultINS_9OpaquePtrINS_8QualTypeEEELb0EEEbbPNS0_12SkipBodyInfoE, \ + (clang::Sema &that, clang::Scope *S, unsigned TagSpec, clang::Sema::TagUseKind TUK, clang::SourceLocation KWLoc, clang::CXXScopeSpec &SS, \ + clang::IdentifierInfo *Name, clang::SourceLocation NameLoc, clang::AttributeList *Attr, clang::AccessSpecifier AS, \ + clang::SourceLocation ModulePrivateLoc, clang::MultiTemplateParamsArg TemplateParameterLists, \ + bool &OwnedDecl, bool &IsDependent, clang::SourceLocation ScopedEnumKWLoc, \ + bool ScopedEnumUsesClassTag, clang::TypeResult UnderlyingType, bool IsTypeSpecifier, bool IsTemplateParamOrArg, clang::Sema::SkipBodyInfo *SkipBody), \ + S, TagSpec, TUK, KWLoc, SS, Name, NameLoc, Attr, AS, ModulePrivateLoc, TemplateParameterLists, \ + OwnedDecl, IsDependent, ScopedEnumKWLoc, ScopedEnumUsesClassTag, UnderlyingType, IsTypeSpecifier, IsTemplateParamOrArg, SkipBody) +#elif FRONTEND_CLANG >= 37 +GEN_SEMA_WRAPPER_WITH_RESULT(clang::Decl*, ActOnTag, \ + _ZN5clang4Sema8ActOnTagEPNS_5ScopeEjNS0_10TagUseKindENS_14SourceLocationERNS_12CXXScopeSpecEPNS_14IdentifierInfoES4_PNS_13AttributeListENS_15AccessSpecifierES4_N4llvm15MutableArrayRefIPNS_21TemplateParameterListEEERbSH_S4_bNS_12ActionResultINS_9OpaquePtrINS_8QualTypeEEELb0EEEbPNS0_12SkipBodyInfoE, \ + (clang::Sema &that, clang::Scope *S, unsigned TagSpec, clang::Sema::TagUseKind TUK, clang::SourceLocation KWLoc, clang::CXXScopeSpec &SS, \ + clang::IdentifierInfo *Name, clang::SourceLocation NameLoc, clang::AttributeList *Attr, clang::AccessSpecifier AS, \ + clang::SourceLocation ModulePrivateLoc, clang::MultiTemplateParamsArg TemplateParameterLists, \ + bool &OwnedDecl, bool &IsDependent, clang::SourceLocation ScopedEnumKWLoc, \ + bool ScopedEnumUsesClassTag, clang::TypeResult UnderlyingType, bool IsTypeSpecifier, clang::Sema::SkipBodyInfo *SkipBody), \ + S, TagSpec, TUK, KWLoc, SS, Name, NameLoc, Attr, AS, ModulePrivateLoc, TemplateParameterLists, \ + OwnedDecl, IsDependent, ScopedEnumKWLoc, ScopedEnumUsesClassTag, UnderlyingType, IsTypeSpecifier, SkipBody) +#elif FRONTEND_CLANG >= 35 +GEN_SEMA_WRAPPER_WITH_RESULT(clang::Decl*, ActOnTag, \ + _ZN5clang4Sema8ActOnTagEPNS_5ScopeEjNS0_10TagUseKindENS_14SourceLocationERNS_12CXXScopeSpecEPNS_14IdentifierInfoES4_PNS_13AttributeListENS_15AccessSpecifierES4_N4llvm15MutableArrayRefIPNS_21TemplateParameterListEEERbSH_S4_bNS_12ActionResultINS_9OpaquePtrINS_8QualTypeEEELb0EEEb, \ + (clang::Sema &that, clang::Scope *S, unsigned TagSpec, clang::Sema::TagUseKind TUK, clang::SourceLocation KWLoc, clang::CXXScopeSpec &SS, \ + clang::IdentifierInfo *Name, clang::SourceLocation NameLoc, clang::AttributeList *Attr, clang::AccessSpecifier AS, \ + clang::SourceLocation ModulePrivateLoc, clang::MultiTemplateParamsArg TemplateParameterLists, \ + bool &OwnedDecl, bool &IsDependent, clang::SourceLocation ScopedEnumKWLoc, \ + bool ScopedEnumUsesClassTag, clang::TypeResult UnderlyingType, bool IsTypeSpecifier), \ + S, TagSpec, TUK, KWLoc, SS, Name, NameLoc, Attr, AS, ModulePrivateLoc, TemplateParameterLists, \ + OwnedDecl, IsDependent, ScopedEnumKWLoc, ScopedEnumUsesClassTag, UnderlyingType, IsTypeSpecifier) +#else +GEN_SEMA_WRAPPER_WITH_RESULT(clang::Decl*, ActOnTag, \ + _ZN5clang4Sema8ActOnTagEPNS_5ScopeEjNS0_10TagUseKindENS_14SourceLocationERNS_12CXXScopeSpecEPNS_14IdentifierInfoES4_PNS_13AttributeListENS_15AccessSpecifierES4_N4llvm15MutableArrayRefIPNS_21TemplateParameterListEEERbSH_S4_bNS_12ActionResultINS_9OpaquePtrINS_8QualTypeEEELb0EEE, \ + (clang::Sema &that, clang::Scope *S, unsigned TagSpec, clang::Sema::TagUseKind TUK, clang::SourceLocation KWLoc, clang::CXXScopeSpec &SS, \ + clang::IdentifierInfo *Name, clang::SourceLocation NameLoc, clang::AttributeList *Attr, clang::AccessSpecifier AS, \ + clang::SourceLocation ModulePrivateLoc, clang::MultiTemplateParamsArg TemplateParameterLists, \ + bool &OwnedDecl, bool &IsDependent, clang::SourceLocation ScopedEnumKWLoc, \ + bool ScopedEnumUsesClassTag, clang::TypeResult UnderlyingType), \ + S, TagSpec, TUK, KWLoc, SS, Name, NameLoc, Attr, AS, ModulePrivateLoc, TemplateParameterLists, \ + OwnedDecl, IsDependent, ScopedEnumKWLoc, ScopedEnumUsesClassTag, UnderlyingType) +#endif + +// wrapper for Sema::ActOnFinishCXXMemberSpecification +GEN_SEMA_WRAPPER_NO_RESULT(ActOnFinishCXXMemberSpecification, \ + _ZN5clang4Sema33ActOnFinishCXXMemberSpecificationEPNS_5ScopeENS_14SourceLocationEPNS_4DeclES3_S3_PNS_13AttributeListE, \ + (clang::Sema &that, clang::Scope* S, clang::SourceLocation RLoc, Decl *TagDecl, \ + clang::SourceLocation LBrac, clang::SourceLocation RBrac, clang::AttributeList *AttrList), \ + S, RLoc, TagDecl, LBrac, RBrac, AttrList) + +// wrapper for Sema::ActOnEndOfTranslationUnit +GEN_SEMA_WRAPPER_NO_RESULT_NO_ARG(ActOnEndOfTranslationUnit, _ZN5clang4Sema25ActOnEndOfTranslationUnitEv) + +// wrapper for Sema::canSkipFunctionBody +GEN_SEMA_WRAPPER_WITH_RESULT(bool, canSkipFunctionBody, _ZN5clang4Sema19canSkipFunctionBodyEPNS_4DeclE, \ + (clang::Sema &that, clang::Decl *D), D) + +#if 0 // these wrapper are hopefully not needed +// wrapper for Sema::ActOnFunctionDeclarator +GEN_SEMA_WRAPPER_WITH_RESULT(clang::NamedDecl*, ActOnFunctionDeclarator, \ + _ZN5clang4Sema23ActOnFunctionDeclaratorEPNS_5ScopeERNS_10DeclaratorEPNS_11DeclContextEPNS_14TypeSourceInfoERNS_12LookupResultEN4llvm15MutableArrayRefIPNS_21TemplateParameterListEEERb, \ + (clang::Sema &that, clang::Scope* S, clang::Declarator& D, \ + clang::DeclContext* DC, clang::TypeSourceInfo *TInfo, clang::LookupResult &Previous, \ + clang::MultiTemplateParamsArg TemplateParamLists, bool &AddToScope), \ + S, D, DC, TInfo, Previous, TemplateParamLists, AddToScope) + +// wrapper for void Sema::ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AL, bool IncludeCXX11Attributes = true); +GEN_SEMA_WRAPPER_NO_RESULT(ProcessDeclAttributeList, _ZN5clang4Sema24ProcessDeclAttributeListEPNS_5ScopeEPNS_4DeclEPKNS_13AttributeListEb, \ + (clang::Sema &that, clang::Scope *S, clang::Decl *D, const clang::AttributeList *AL, bool IncludeCXX11Attributes), \ + S, D, AL, IncludeCXX11Attributes) +#endif + +// wrapper for NamedDecl *Sema::ActOnCXXMemberDeclarator +GEN_SEMA_WRAPPER_WITH_RESULT(clang::NamedDecl*, ActOnCXXMemberDeclarator, \ + _ZN5clang4Sema24ActOnCXXMemberDeclaratorEPNS_5ScopeENS_15AccessSpecifierERNS_10DeclaratorEN4llvm15MutableArrayRefIPNS_21TemplateParameterListEEEPNS_4ExprERKNS_14VirtSpecifiersENS_16InClassInitStyleE, \ + (clang::Sema &that, clang::Scope *S, clang::AccessSpecifier AS, clang::Declarator &D, \ + clang::MultiTemplateParamsArg TemplateParameterLists, clang::Expr *BitfieldWidth, const clang::VirtSpecifiers &VS, \ + clang::InClassInitStyle InitStyle), S, AS, D, TemplateParameterLists, BitfieldWidth, VS, InitStyle) + +// wrapper for Sema::ActOnDeclarator +GEN_SEMA_WRAPPER_WITH_RESULT(clang::Decl*, ActOnDeclarator, _ZN5clang4Sema15ActOnDeclaratorEPNS_5ScopeERNS_10DeclaratorE, \ + (clang::Sema &that, clang::Scope *S, clang::Declarator &D), S, D) + + +// Special wrapper for Preprocessor::Lex +WeaverBase *macro_recorder = 0; +int in_peek_ahead = 0; +extern "C" void __real__ZN5clang12Preprocessor3LexERNS_5TokenE(clang::Preprocessor &that, clang::Token &Result); +extern "C" void WRAP(_ZN5clang12Preprocessor3LexERNS_5TokenE)(clang::Preprocessor &that, clang::Token &Result); +void WRAP(_ZN5clang12Preprocessor3LexERNS_5TokenE)(clang::Preprocessor &that, clang::Token &Result) { + static int lex_nested = 0; + lex_nested++; + if (macro_recorder && in_peek_ahead == 0 && lex_nested == 1) + macro_recorder->lex_and_filter_attr(that, Result); + else + __real__ZN5clang12Preprocessor3LexERNS_5TokenE(that, Result); + lex_nested--; + if (!lex_nested && macro_recorder) { + macro_recorder->collect_macro_token (that, Result); + } +} + +extern "C" const clang::Token &__real__ZN5clang12Preprocessor9PeekAheadEj(clang::Preprocessor &that, unsigned N); +extern "C" const clang::Token & WRAP(_ZN5clang12Preprocessor9PeekAheadEj)(clang::Preprocessor &that, unsigned N); +const clang::Token & WRAP(_ZN5clang12Preprocessor9PeekAheadEj)(clang::Preprocessor &that, unsigned N) { + in_peek_ahead++; +// cout << "peek " << N << endl; + const clang::Token &result = __real__ZN5clang12Preprocessor9PeekAheadEj(that, N); +// cout << "peek end " << N << endl; + in_peek_ahead--; + return result; +} diff --git a/AspectC++/ClangBinding.h b/AspectC++/ClangBinding.h new file mode 100644 index 0000000..1d9e136 --- /dev/null +++ b/AspectC++/ClangBinding.h @@ -0,0 +1,135 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __ClangBinding_h__ +#define __ClangBinding_h__ + +// This module is needed to hook into the internal behavior of the Clang C++ +// parser. Calls to a number of Sema::ActOn... functions are wrapped by means +// of the linker option --wrap=. This method has a number restrictions: +// - only works with gnu ld +// - it does not work on MacOS X +// - it only works if calls cannot be resolved by the compiler (an undefined +// symbol references is needed by the linker) +// All that wouldn't be need if the ActOn...-functions of clang::Sema were +// virtual. We hope that this will be changed in the future. +// The implementation hooks into calls from clang::Parser to clang::Sema::ActOn*, +// cast the Sema-object reference to a ClangIntroSema-reference and calls the +// respective ActOn...-function. For ClangIntroSema this looks like the execution +// of a normal virtual function. +// In order to call the original ActOn-function, ClangIntroSema functions call +// Real..., which is provided by this module for all wrapped functions. Calling +// the respective base class method is not possible here, because due to the +// wrapping we would end up with an infinite loop. + +namespace clang { + class Sema; + class Scope; + class Decl; +} + +#include "clang/Basic/SourceLocation.h" + +// The following functions will be needed by the extended Sema class +void RealActOnStartCXXMemberDeclarations (clang::Sema &that, clang::Scope *S, + clang::Decl *TagDecl, clang::SourceLocation FinalLoc, + bool IsFinalSpelledSealed, clang::SourceLocation LBraceLoc); + +#if FRONTEND_CLANG >= 38 +void RealActOnBaseSpecifiers (clang::Sema &that, clang::Decl *ClassDecl, + clang::MutableArrayRef Bases); + +#else +void RealActOnBaseSpecifiers (clang::Sema &that, clang::Decl *ClassDecl, + clang::CXXBaseSpecifier **Bases, unsigned NumBases); +#endif + +#if FRONTEND_CLANG >= 38 +clang::Decl* RealActOnStartOfFunctionDef(clang::Sema &that, clang::Scope *S, + clang::Declarator &D, clang::MultiTemplateParamsArg TemplateParamLists, + clang::Sema::SkipBodyInfo *SkipBody); +#else +clang::Decl* RealActOnStartOfFunctionDef(clang::Sema &that, clang::Scope *S, + clang::Declarator &D); +#endif + +#if FRONTEND_CLANG >= 38 +clang::Decl* RealActOnStartNamespaceDef ( + clang::Sema &that, clang::Scope *S, clang::SourceLocation InlineLoc, clang::SourceLocation NamespaceLoc, + clang::SourceLocation IdentLoc, clang::IdentifierInfo *Ident, clang::SourceLocation LBrace, + clang::AttributeList *AttrList, clang::UsingDirectiveDecl * &UsingDecl); +#else +clang::Decl* RealActOnStartNamespaceDef ( + clang::Sema &that, clang::Scope *S, clang::SourceLocation InlineLoc, clang::SourceLocation NamespaceLoc, + clang::SourceLocation IdentLoc, clang::IdentifierInfo *Ident, clang::SourceLocation LBrace, + clang::AttributeList *AttrList); +#endif + +#if FRONTEND_CLANG >= 50 +clang::Decl* RealActOnTag( + clang::Sema &that, clang::Scope *S, unsigned TagSpec, clang::Sema::TagUseKind TUK, clang::SourceLocation KWLoc, clang::CXXScopeSpec &SS, + clang::IdentifierInfo *Name, clang::SourceLocation NameLoc, clang::AttributeList *Attr, clang::AccessSpecifier AS, + clang::SourceLocation ModulePrivateLoc, clang::MultiTemplateParamsArg TemplateParameterLists, + bool &OwnedDecl, bool &IsDependent, clang::SourceLocation ScopedEnumKWLoc, + bool ScopedEnumUsesClassTag, clang::TypeResult UnderlyingType, bool IsTypeSpecifier, bool IsTemplateParamOrArg, + clang::Sema::SkipBodyInfo *SkipBody); +#elif FRONTEND_CLANG >= 37 +clang::Decl* RealActOnTag( + clang::Sema &that, clang::Scope *S, unsigned TagSpec, clang::Sema::TagUseKind TUK, clang::SourceLocation KWLoc, clang::CXXScopeSpec &SS, + clang::IdentifierInfo *Name, clang::SourceLocation NameLoc, clang::AttributeList *Attr, clang::AccessSpecifier AS, + clang::SourceLocation ModulePrivateLoc, clang::MultiTemplateParamsArg TemplateParameterLists, + bool &OwnedDecl, bool &IsDependent, clang::SourceLocation ScopedEnumKWLoc, + bool ScopedEnumUsesClassTag, clang::TypeResult UnderlyingType, bool IsTypeSpecifier, clang::Sema::SkipBodyInfo *SkipBody); +#elif FRONTEND_CLANG >= 35 +clang::Decl* RealActOnTag( + clang::Sema &that, clang::Scope *S, unsigned TagSpec, clang::Sema::TagUseKind TUK, clang::SourceLocation KWLoc, clang::CXXScopeSpec &SS, + clang::IdentifierInfo *Name, clang::SourceLocation NameLoc, clang::AttributeList *Attr, clang::AccessSpecifier AS, + clang::SourceLocation ModulePrivateLoc, clang::MultiTemplateParamsArg TemplateParameterLists, + bool &OwnedDecl, bool &IsDependent, clang::SourceLocation ScopedEnumKWLoc, + bool ScopedEnumUsesClassTag, clang::TypeResult UnderlyingType, bool IsTypeSpecifier); +#else +clang::Decl* RealActOnTag( + clang::Sema &that, clang::Scope *S, unsigned TagSpec, clang::Sema::TagUseKind TUK, clang::SourceLocation KWLoc, clang::CXXScopeSpec &SS, + clang::IdentifierInfo *Name, clang::SourceLocation NameLoc, clang::AttributeList *Attr, clang::AccessSpecifier AS, + clang::SourceLocation ModulePrivateLoc, clang::MultiTemplateParamsArg TemplateParameterLists, + bool &OwnedDecl, bool &IsDependent, clang::SourceLocation ScopedEnumKWLoc, + bool ScopedEnumUsesClassTag, clang::TypeResult UnderlyingType); +#endif + +void RealActOnFinishCXXMemberSpecification (clang::Sema &that, clang::Scope* S, + clang::SourceLocation RLoc, clang::Decl *TagDecl, clang::SourceLocation LBrac, + clang::SourceLocation RBrac, clang::AttributeList *AttrList); + +void RealActOnEndOfTranslationUnit(clang::Sema &that); + +bool RealcanSkipFunctionBody(clang::Sema &that, clang::Decl *D); + +clang::NamedDecl* RealActOnCXXMemberDeclarator(clang::Sema &that, clang::Scope *S, + clang::AccessSpecifier AS, clang::Declarator &D, + clang::MultiTemplateParamsArg TemplateParameterLists, + clang::Expr *BitfieldWidth, const clang::VirtSpecifiers &VS, + clang::InClassInitStyle InitStyle); + +clang::Decl* RealActOnDeclarator(clang::Sema &that, clang::Scope *S, clang::Declarator &D); + +// if macro_recorder points to a WeaverBase instance, each token that is +// return by clang::Preprocessor::Lex will also be passed to the recorder. +class WeaverBase; +extern WeaverBase *macro_recorder; + +#endif // __ClangBinding_h__ diff --git a/AspectC++/ClangErrorStream.h b/AspectC++/ClangErrorStream.h new file mode 100644 index 0000000..15d8042 --- /dev/null +++ b/AspectC++/ClangErrorStream.h @@ -0,0 +1,96 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2013 The 'ac++' developers (see aspectc.org) +// +// 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, + + +#ifndef __ClangErrorStream_h__ +#define __ClangErrorStream_h__ + +#include "clang/Basic/SourceManager.h" +#include "Puma/ErrorStream.h" + +// FIXME: Decouple from Puma. +class ClangErrorStream : public Puma::ErrorStream { + clang::SourceManager *_sm; +public: + ClangErrorStream (clang::SourceManager *sm = 0, + std::ostream &s = std::cerr) : ErrorStream(s), _sm(sm) {} + void set_source_manager (clang::SourceManager *sm) { _sm = sm; } + clang::SourceManager &get_source_manager () const { return *_sm; } + + ClangErrorStream &operator << (clang::SourceLocation l) { + assert (_sm && "No SourceManager!"); + clang::PresumedLoc PL = _sm->getPresumedLoc(l); + *this << PL.getFilename() << ':' << PL.getLine() << ':' << PL.getColumn() + << ": "; + + return *this; + } + + ClangErrorStream &operator << (clang::FullSourceLoc fl) { + clang::PresumedLoc PL = fl.getManager ().getPresumedLoc(fl); + *this << PL.getFilename() << ':' << PL.getLine() << ':' << PL.getColumn() + << ": "; + + return *this; + } + ClangErrorStream &operator << (const char *x) { + ErrorStream::operator << (x); + return *this; + } + ClangErrorStream &operator << (long x) { + ErrorStream::operator << (x); + return *this; + } + ClangErrorStream &operator << (unsigned x) { + ErrorStream::operator << (x); + return *this; + } + ClangErrorStream &operator << (int x) { + ErrorStream::operator << (x); + return *this; + } + ClangErrorStream &operator << (short x) { + ErrorStream::operator << (x); + return *this; + } + ClangErrorStream &operator << (char x) { + ErrorStream::operator << (x); + return *this; + } + ClangErrorStream &operator << (double x) { + ErrorStream::operator << (x); + return *this; + } + ClangErrorStream &operator << (const Puma::ErrorSeverity & x) { + ErrorStream::operator << (x); + return *this; + } + ClangErrorStream &operator << (Puma::Location x) { + ErrorStream::operator << (x); + return *this; + } + ClangErrorStream &operator << (const Puma::Printable &x) { + ErrorStream::operator << (x); + return *this; + } + ClangErrorStream &operator << (void (*f)(Puma::ErrorSink &)) { + ErrorStream::operator << (f); + return *this; + } +}; + +#endif // __ClangErrorStream_h__ diff --git a/AspectC++/ClangFlowAnalysis.cc b/AspectC++/ClangFlowAnalysis.cc new file mode 100644 index 0000000..476dd7e --- /dev/null +++ b/AspectC++/ClangFlowAnalysis.cc @@ -0,0 +1,920 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2015 The 'ac++' developers (see aspectc.org) +// +// 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 "ClangFlowAnalysis.h" + +#include "clang/Analysis/CFG.h" +#include "clang/Analysis/CFGStmtMap.h" +//#include "clang/Analysis/Analyses/Dominators.h" +#include "clang/Analysis/Analyses/PostOrderCFGView.h" +#include "clang/AST/Stmt.h" +#include "clang/AST/RecursiveASTVisitor.h" + +#include +#include + +#include + +using namespace clang; + +//------------------------------------------------------------------------====// +// Worklist: worklist for dataflow analysis. +//====------------------------------------------------------------------------// + +namespace { + +class DataflowWorklist { + SmallVector worklist; + llvm::BitVector enqueuedBlocks; + PostOrderCFGView *POV; +public: + DataflowWorklist(const CFG &cfg, AnalysisDeclContext &Ctx) + : enqueuedBlocks(cfg.getNumBlockIDs()), + POV(Ctx.getAnalysis()) {} + + void enqueueBlock(const CFGBlock *block); + void enqueueSuccessors(const CFGBlock *block); + void enqueuePredecessors(const CFGBlock *block); + + const CFGBlock *dequeue(); + + void sortWorklist(); +}; + +} + +void DataflowWorklist::enqueueBlock(const clang::CFGBlock *block) { + if (block && !enqueuedBlocks[block->getBlockID()]) { + enqueuedBlocks[block->getBlockID()] = true; + worklist.push_back(block); + } +} + +void DataflowWorklist::enqueueSuccessors(const clang::CFGBlock *block) { + const unsigned OldWorklistSize = worklist.size(); + for (CFGBlock::const_succ_iterator I = block->succ_begin(), + E = block->succ_end(); I != E; ++I) { + enqueueBlock(*I); + } + + if (OldWorklistSize == 0 || OldWorklistSize == worklist.size()) + return; + + sortWorklist(); +} + +void DataflowWorklist::enqueuePredecessors(const clang::CFGBlock *block) { + const unsigned OldWorklistSize = worklist.size(); + for (CFGBlock::const_pred_iterator I = block->pred_begin(), + E = block->pred_end(); I != E; ++I) { + enqueueBlock(*I); + } + + if (OldWorklistSize == 0 || OldWorklistSize == worklist.size()) + return; + + sortWorklist(); +} + +void DataflowWorklist::sortWorklist() { + // sort in reverse order //FIXME: howto sort in pre-order ?? + //std::sort(worklist.rbegin(), worklist.rend(), POV->getComparator()); +} + +const CFGBlock *DataflowWorklist::dequeue() { + if (worklist.empty()) + return 0; + const CFGBlock *b = worklist.pop_back_val(); + enqueuedBlocks[b->getBlockID()] = false; + return b; +} + + +//------------------------------------------------------------------------====// +// Helper functions: decide whether a variable can be tracked by the analysis +//====------------------------------------------------------------------------// + +namespace { + +static bool is_trackable(clang::VarDecl* VD) { + clang::QualType type = VD->getType(); + + if ( VD->hasGlobalStorage() ) { + if (type->isPointerType() && !type.isConstQualified()) { + return false; // pointer with global storage must be const qualified + } + } + + // two levels of indirection are not trackable (i.e., pointers to pointers) + if (type->isPointerType() || type->isReferenceType()) { + return type->getPointeeType()->isClassType(); + } + + return type->isClassType(); +} + +static bool is_trackable(clang::MemberExpr* ME) { + clang::FieldDecl* field = dyn_cast_or_null(ME->getMemberDecl()); + if (field) { + clang::QualType type = field->getType(); + + // remove reference/pointer attribute from type + if ( (type->isPointerType() && type.isConstQualified()) || type->isReferenceType()) { + type = type->getPointeeType(); // 1st dereference + while ( type->isPointerType() ) { + if ( !type.isConstQualified() ) { + return false; // pointer to pointer must be const qualified + } + type = type->getPointeeType(); + } + } + if (!type->isClassType()) { + return false; + } + + clang::Expr* base = ME->getBase()->IgnoreImplicit(); + if( dyn_cast_or_null(base) ) { + return true; + } + else if (clang::MemberExpr* ME_base = dyn_cast_or_null(base)) { + return is_trackable(ME_base); + } + else if (clang::DeclRefExpr* DRF = dyn_cast_or_null(base)) { + clang::VarDecl* VD = dyn_cast_or_null(DRF->getDecl()); + if (VD == 0) { + return false; + } + if (VD->getType()->isPointerType() && !VD->getType().isConstQualified() ) { + return false; // do not allow non-const pointers, yet. (TODO) + } + return is_trackable(VD); + } + } + return false; +} + +// determine wheter two member expressions refer to the same object +static bool referencesSameObject(clang::Stmt* stmt1, clang::Stmt* stmt2) { + if ( clang::DeclRefExpr* decl_ref1 = dyn_cast_or_null(stmt1) ) { + if ( clang::DeclRefExpr* decl_ref2 = dyn_cast_or_null(stmt2) ) { + if ( clang::VarDecl* var_decl1 = dyn_cast_or_null(decl_ref1->getDecl()) ) { + if ( clang::VarDecl* var_decl2 = dyn_cast_or_null(decl_ref2->getDecl()) ) { + // Note: The pointer (var_decl) must not have been changed in between. + // Thus, we only allow const pointers, yet (TODO) + // See: is_trackable(clang::MemberExpr* ME) + if ( (decl_ref1->child_begin() == decl_ref1->child_end()) && + (decl_ref2->child_begin() == decl_ref2->child_end()) ) { + // there must not exist any children, hence, we can return: + return var_decl1 == var_decl2; + } + } + } + } + return false; + } + else if ( clang::MemberExpr* member_expr1 = dyn_cast_or_null(stmt1) ) { + if ( clang::MemberExpr* member_expr2 = dyn_cast_or_null(stmt2) ) { + if ( clang::FieldDecl* field1 = dyn_cast_or_null(member_expr1->getMemberDecl()) ) { + if ( clang::FieldDecl* field2 = dyn_cast_or_null(member_expr2->getMemberDecl()) ) { + if ( field1 == field2 ) { + return referencesSameObject( member_expr1->getBase()->IgnoreImplicit(), + member_expr2->getBase()->IgnoreImplicit() ); + } + } + } + } + return false; + } + else if ( dyn_cast_or_null(stmt1) && dyn_cast_or_null(stmt2) ) { + return true; + } + else if ( /*clang::ArraySubscriptExpr* array_expr1 =*/ dyn_cast_or_null(stmt1) ) { + // TODO + /* + if ( clang::ArraySubscriptExpr* array_expr2 = dyn_cast_or_null(stmt2) ) { + if ( clang::IntegerLiteral* literal1 = dyn_cast_or_null(array_expr1->getIdx()) ) { + if ( clang::IntegerLiteral* literal2 = dyn_cast_or_null(array_expr2->getIdx()) ) { + if( literal1->getValue() == literal2->getValue() ) { + return referencesSameObject( array_expr1->getBase()->IgnoreImplicit(), + array_expr2->getBase()->IgnoreImplicit() ); + } + } + } + } + */ + return false; + } + else if ( dyn_cast_or_null(stmt1) || dyn_cast_or_null(stmt2) ) { + return false; + } + else if ( dyn_cast_or_null(stmt1) || dyn_cast_or_null(stmt2) ) { + return false; + } + + // recurse to all children + Stmt::child_iterator it1 = stmt1->child_begin(); + Stmt::child_iterator it2 = stmt2->child_begin(); + for( ; (it1 != stmt1->child_end()) && (it2 != stmt2->child_end()); it1++, it2++) { + if ( referencesSameObject((*it1)->IgnoreImplicit(), (*it2)->IgnoreImplicit()) == false ) { + return false; + } + } + return true; +} + +} + + +//------------------------------------------------------------------------====// +// DataFlowValues: Keep track of variables in each basic block +//====------------------------------------------------------------------------// + +namespace { + +class DataFlowValues { +private: + static unsigned int next_free_id; + + typedef std::map Variable_Map_t; + Variable_Map_t _local_variables; + Variable_Map_t _global_variables; + + // record updates of local variables (i.e. assignments), in order to + // replay the same updates in each iteration (do not use new ids) + typedef std::pair Update_Location_t; + typedef std::map Variable_Updates_t; + Variable_Updates_t _updates; + + // record merge conflicts of local variables and their resolution + Variable_Map_t _conflicts; + + // store member expressions that have already been used as target object + // TODO: allow non-const pointers as base for a member expression + //typedef std::pair Member_ID_t; + //typedef std::map Member_Expr_Map_t; + typedef std::map Member_Expr_Map_t; + Member_Expr_Map_t _member_expr_map; + + // TODO + // store array expressions that have already been used as target object + //typedef std::map Array_Expr_Map_t; + //Array_Expr_Map_t _array_expr_map; + +public: + static const unsigned int NO_ID = ClangFlowAnalysis::NO_ID; + static const unsigned int THIS_ID = ClangFlowAnalysis::THIS_ID; + + unsigned int get_next_free_id() const { return next_free_id; } + static void reset_next_free_id() { next_free_id = 2; } + + bool equals(const DataFlowValues& other) const { + return (_local_variables == other._local_variables) && + (_global_variables == other._global_variables) && + (_member_expr_map == other._member_expr_map); + } + + void copyHistory(const DataFlowValues& other) { + _conflicts = other._conflicts; + _updates = other._updates; + } + + void add_variable(clang::VarDecl* VD) { + add_variable(VD, get_next_free_id()); + } + + void add_variable(clang::VarDecl* VD, unsigned int new_id) { + if (!is_trackable(VD)) { + return; + } + if( VD->hasLocalStorage() ) { + _local_variables[VD] = new_id; + if (new_id == next_free_id) { next_free_id++; } + } + else { // hasGlobalStorage + _global_variables[VD] = new_id; + if (new_id == next_free_id) { next_free_id++; } + } + } + + // VD is the variable to update, location the statement in the source code + // that triggers the update (e.g., a DeclRefExpr) + void update_variable(clang::VarDecl* VD, clang::Stmt* location, unsigned int new_id) { + if (VD == 0 || VD->hasGlobalStorage() || !is_trackable(VD)) { + return; // only track updates of 'trackable' local variables + } + + // do not allow 'kill' updates on objects (class-type variables) + if ( (new_id == NO_ID) && (VD->getType()->isClassType()) ) { + return; + } + + // do not allow any updates on killed variables (with ID == 0) + Variable_Map_t::iterator found = _local_variables.find(VD); + if (found != _local_variables.end()) { + if (found->second == NO_ID) { + return; + } + } + + if ( new_id == next_free_id ) { + // try to replay an existing update instead of a new_id + Variable_Updates_t::iterator update = _updates.find(std::make_pair(VD, location)); + if ( update != _updates.end() ) { + add_variable(VD, update->second); + return; + } + } + + add_variable(VD, new_id); + if ( new_id != NO_ID ) { // no need to remember NO_ID updates (won't merge) + _updates[std::make_pair(VD, location)] = new_id; + } + } + + bool is_tracked(clang::VarDecl* VD) const { + if( VD->hasLocalStorage() ) { + Variable_Map_t::const_iterator found = _local_variables.find(VD); + return found != _local_variables.end(); + } + else { // hasGlobalStorage + Variable_Map_t::const_iterator found = _global_variables.find(VD); + return found != _global_variables.end(); + } + } + + unsigned int get_id(clang::VarDecl* VD) const { + if( VD->hasLocalStorage() ) { + Variable_Map_t::const_iterator found = _local_variables.find(VD); + if (found != _local_variables.end()) { + return found->second; + } + } + else { // hasGlobalStorage + Variable_Map_t::const_iterator found = _global_variables.find(VD); + if (found != _global_variables.end()) { + return found->second; + } + } + return NO_ID; + } + + unsigned int get_id(clang::MemberExpr* ME) const { + for(Member_Expr_Map_t::const_iterator it = _member_expr_map.begin(); + it != _member_expr_map.end(); ++it) { + if( it->first == ME ) { + return it->second; // same member-expression pointer found + } + else if( referencesSameObject(it->first, ME) ) { + return it->second; + } + } + // no match found + return NO_ID; + } + + unsigned int add_member_expr(clang::MemberExpr* ME) { + _member_expr_map[ME] = next_free_id; + return next_free_id++; + } + + void merge(const DataFlowValues& src) { + // merge local variables + for ( Variable_Map_t::const_iterator it = src._local_variables.begin(); + it != src._local_variables.end(); it++) { + unsigned int src_id = it->second; + + Variable_Map_t::iterator found = _local_variables.find(it->first); + if( found != _local_variables.end() ) { + unsigned int dst_id = found->second; + if ( src_id != dst_id ) { + // a merge with a killed variable always yields a 'killed' result + if ( (src_id == NO_ID) || (dst_id == NO_ID) ) { + found->second = NO_ID; + } + else { + // did we solve that conflict before? + Variable_Map_t::iterator conflict = _conflicts.find(it->first); + if (conflict != _conflicts.end() ) { + found->second = conflict->second; // adopt previous resolution + } + else { + // multiple sources but different values: assign new id + unsigned int new_id = next_free_id++; + _conflicts[it->first] = new_id; // remember this resolution + found->second = new_id; + } + } + } + } + else { + _local_variables[it->first] = src_id; // just copy + } + } + + // fix loops (use new ids for overwritten variables) + for ( Variable_Updates_t::iterator it = _updates.begin(); + it != _updates.end(); it++) { + // if we find an update, we've already visited this basic block before + clang::VarDecl* updated_var = it->first.first; + + // look if we already solved a merge-conflict on 'updated'var' + Variable_Map_t::iterator conflict = _conflicts.find(updated_var); + if (conflict == _conflicts.end()) { + // use a new id and remember this as a conflict resolution + unsigned int new_id = next_free_id++; + _local_variables[updated_var] = new_id; + _conflicts[updated_var] = new_id; + } + } + + // merge global variables + for ( Variable_Map_t::const_iterator it = src._global_variables.begin(); + it != src._global_variables.end(); it++) { + unsigned int src_id = it->second; + + Variable_Map_t::iterator found = _global_variables.find(it->first); + if( found != _global_variables.end() ) { + unsigned int dst_id = found->second; + found->second = std::min(src_id, dst_id); // use smaller one + } + else { + _global_variables[it->first] = src_id; // just copy + } + } + + // merge member expressions + for(Member_Expr_Map_t::const_iterator it_src = src._member_expr_map.begin(); + it_src != src._member_expr_map.end(); ++it_src) { + clang::MemberExpr* ME_src = it_src->first; + + bool found = false; + for(Member_Expr_Map_t::iterator it_dst = _member_expr_map.begin(); + it_dst != _member_expr_map.end(); ++it_dst) { + clang::MemberExpr* ME_dst = it_dst->first; + if ( (ME_src == ME_dst) || referencesSameObject(ME_src, ME_dst) ) { + it_dst->second = std::min(it_dst->second, it_src->second); + found = true; + break; + } + } + if (found == false) { + _member_expr_map[ME_src] = it_src->second; // just copy + } + } + } + + void dump() const { + for ( Variable_Map_t::const_iterator it = _local_variables.begin(); + it != _local_variables.end(); it++) { + std::cout << it->first->getNameAsString() << " = " << it->second << " (local)" << std::endl; + } + for ( Variable_Map_t::const_iterator it = _global_variables.begin(); + it != _global_variables.end(); it++) { + std::cout << it->first->getNameAsString() << " = " << it->second << " (global)" << std::endl; + } + } +}; + +} + +unsigned int DataFlowValues::next_free_id = 2; + + +//------------------------------------------------------------------------====// +// TransferFunctions: Perform the dataflow analysis for one basic block +//====------------------------------------------------------------------------// + +namespace { + +class TransferFunctions : public clang::RecursiveASTVisitor { +private: + DataFlowValues& _dfvals; + ClangFlowAnalysis::call_target_obj_lid_map_t& _target_obj_lids; + const clang::ASTContext& _context; + + void update(clang::Stmt* stmt, unsigned int new_id); + unsigned int lookup_target_obj_lid(clang::Expr* expr); + +public: + TransferFunctions(DataFlowValues& dfvals, + ClangFlowAnalysis::call_target_obj_lid_map_t& lids, + clang::ASTContext& ctx) + : _dfvals(dfvals), _target_obj_lids(lids), _context(ctx) {} + + bool VisitDeclStmt(DeclStmt *DS); // variable initialization + bool VisitCallExpr(CallExpr *CE); + bool VisitBinaryOperator(BinaryOperator *BO); // assignment + bool VisitUnaryOperator(UnaryOperator *UO); // ++, --, & operators + //VisitCastExpr(CastExpr *CE) + //void VisitDeclRefExpr(DeclRefExpr *DR); + + static const unsigned int NO_ID = ClangFlowAnalysis::NO_ID; + static const unsigned int THIS_ID = ClangFlowAnalysis::THIS_ID; +}; + +} + +bool TransferFunctions::VisitDeclStmt(DeclStmt* DS) { + for (clang::DeclStmt::decl_iterator I = DS->decl_begin(); + I != DS->decl_end(); ++I) { + clang::VarDecl* VD = dyn_cast(*I); + if (VD) { + clang::Expr* init_value = VD->getInit(); // initialization expression + + // handle references to a pointer + if (VD->getType()->isReferenceType()) { // reference ... + if (VD->getType()->getPointeeType()->isPointerType()) { // to pointer + // example: Foo*& ref = foo_ptr; + if (init_value) { + update(init_value, NO_ID); // kill the aliased pointer variable + } + return true; // no need update the reference to a pointer + } + } + + // add the new variable; try to copy existing ID from initialization + unsigned int new_id = lookup_target_obj_lid(init_value); + if (new_id == NO_ID) { + new_id = _dfvals.get_next_free_id(); + } + _dfvals.update_variable(VD, DS, new_id); + } + } + return true; +} + +bool TransferFunctions::VisitCallExpr(clang::CallExpr *CE) { + clang::MemberExpr* target = dyn_cast_or_null(CE->getCallee()); + if (target) { + // dive into the member expression to find the callee object + _target_obj_lids[CE] = lookup_target_obj_lid(target->getBase()); + } + else { + _target_obj_lids[CE] = NO_ID; // lookup failed + } + + // Variables passed as reference arguments: + // If a value is passed by non-const reference to a function, we must assume + // that it can be changed silently. Moreoever, the reference could be stored + // somewhere and the value could change at arbitrary points in time. + // Thus, kill that variable: + for (CallExpr::arg_iterator I = CE->arg_begin(), E = CE->arg_end(); + I != E; ++I) { + if ( (!(*I)->getType().isConstQualified()) && (*I)->isGLValue() ) { + // TODO: isGLValue seems to do what it is expected to, but it is correct? + // see: http://stackoverflow.com/questions/3601602 + update(*I, NO_ID); // kill + } + } + return true; +} + +bool TransferFunctions::VisitBinaryOperator(BinaryOperator *BO) { + if (BO->isAssignmentOp()) { + unsigned int new_id; + if (BO->getOpcode() == BO_Assign) { + // extract rhs' id + new_id = lookup_target_obj_lid( BO->getRHS() ); + if (new_id == NO_ID) { + new_id = _dfvals.get_next_free_id(); + } + } + else { + new_id = _dfvals.get_next_free_id(); + } + update( BO->getLHS(), new_id ); + } + return true; +} + +bool TransferFunctions::VisitUnaryOperator(UnaryOperator* UO) { + if (UO->isIncrementDecrementOp()) { + update(UO->getSubExpr(), _dfvals.get_next_free_id()); // assign a new id + } + else if (UO->getOpcode() == UO_AddrOf) { + update(UO->getSubExpr(), NO_ID); // kill + } + return true; +} + + +unsigned int TransferFunctions::lookup_target_obj_lid(clang::Expr* expr) { + clang::Stmt* stmt = expr; + while (stmt) { + stmt = stmt->IgnoreImplicit(); + if( clang::DeclRefExpr* DRF = dyn_cast(stmt) ) { + // non-member variable + clang::VarDecl* VD = dyn_cast_or_null(DRF->getDecl()); + if (VD == 0) { + return NO_ID; + } + if (!_dfvals.is_tracked(VD)) { + _dfvals.add_variable(VD); + } + return _dfvals.get_id(VD); + } + else if ( clang::MemberExpr* ME = dyn_cast(stmt) ) { + // member variable + if ( is_trackable(ME) ) { + unsigned int id = _dfvals.get_id(ME); + if ( id == NO_ID ) { + return _dfvals.add_member_expr(ME); + } + else { + return id; + } + } + return NO_ID; + } + else if ( dyn_cast(stmt) ) { + // this pointer + return THIS_ID; + } + else if ( /*clang::ArraySubscriptExpr* ASE =*/ dyn_cast(stmt) ) { + // array access + //return lookup_or_insert(ASE); //FIXME + return NO_ID; + } + else if ( dyn_cast(stmt) ) { + // if the callee is a CallExpr, stop the static analysis, + // as we cannot guarantee that a call yields always the same object. + return NO_ID; + } + else if ( clang::ConditionalOperator* CO = dyn_cast(stmt) ) { + // try constant folding + bool res; + if ( CO->getCond()->EvaluateAsBooleanCondition(res, _context) ) { + // condition result known at compile time: proceed with that + stmt = res ? CO->getTrueExpr() : CO->getFalseExpr(); + } + else { + // condition not evaluable + return NO_ID; + } + } + else if ( BinaryOperator* BO = dyn_cast(stmt) ) { + switch(BO->getOpcode()) { + case clang::BO_Comma: { + // comma operator: proceed with rhs (lhs is dropped) + stmt = BO->getRHS(); + break; + } + case clang::BO_Assign: + case clang::BO_MulAssign: + case clang::BO_DivAssign: + case clang::BO_RemAssign: + case clang::BO_AddAssign: + case clang::BO_SubAssign: + case clang::BO_ShlAssign: + case clang::BO_ShrAssign: + case clang::BO_AndAssign: + case clang::BO_XorAssign: + case clang::BO_OrAssign: { + // some assignment operator: proceed with rhs + stmt = BO->getRHS(); + break; + } + default: + return NO_ID; + } + } + else if ( UnaryOperator* UO = dyn_cast(stmt) ) { + if (UO->isIncrementDecrementOp()) { + return NO_ID; // cannot determine where it will point to + } + else { + stmt = UO->getSubExpr(); + } + } + else if ( stmt->child_begin() == stmt->child_end() ) { + return NO_ID; // no more children to search for + } + else { + if( (++(stmt->child_begin())) != (stmt->child_end()) ) { + // more than one child found + return NO_ID; + } + + // proceed with next child + stmt = *(stmt->child_begin()); + } + } + return NO_ID; // lookup failed +} + + +void TransferFunctions::update(clang::Stmt* stmt, unsigned int new_id) { + stmt = stmt->IgnoreImplicit(); + + if( clang::DeclRefExpr* DRF = dyn_cast(stmt) ) { + clang::VarDecl* VD = dyn_cast_or_null(DRF->getDecl()); + _dfvals.update_variable(VD, DRF, new_id); + // we are only interested in changes of local-storage variables: + } + else if ( dyn_cast(stmt) ) { + // no need to update any member expressions, as we only consider constant + // member expressions + return; + } + else if ( dyn_cast(stmt) ) { + //_array_expr_map.clear(); //TODO: do not remove all items + return; + } + else if ( dyn_cast(stmt) ) { + // call expressions cannot yield a local-storage pointer whose address was + // not taken before (and which was thus blacklisted) + return; + } + else if ( clang::ConditionalOperator* CO = dyn_cast(stmt) ) { + // try constant folding + bool res; + if ( CO->getCond()->EvaluateAsBooleanCondition(res, _context) ) { + // condition result known at compile time: proceed with that + update(res ? CO->getTrueExpr() : CO->getFalseExpr(), new_id); + } + else { + // condition not evaluable + // recurse to both subexpressions + update(CO->getTrueExpr(), new_id); + update(CO->getFalseExpr(), new_id); + } + } + else { + // recurse to all children + for(Stmt::child_iterator it = stmt->child_begin(); + it != stmt->child_end(); it++) { + update(*it, new_id); + } + } +} + + +//------------------------------------------------------------------------====// +// ClangBasicBlockMap: Interface to the static analyses +//====------------------------------------------------------------------------// + +ClangFlowAnalysis::~ClangFlowAnalysis() { + //_adcm.clear(); //needed? useful? + if (_analysis_decl_ctx) { + delete _analysis_decl_ctx; // drop cache + _analysis_decl_ctx = 0; + } +} + +void ClangFlowAnalysis::analyze(clang::DeclaratorDecl* func) { + if ( func && func->hasBody() ) { + // check if the AnalysisDeclContext cache is valid for the given function + if ((_analysis_decl_ctx == 0) || (_analysis_decl_ctx->getDecl() != func)){ + // AnalysisDeclContext is invalid => construct a new one + if (_analysis_decl_ctx) { + delete _analysis_decl_ctx; // drop cache + } + _analysis_decl_ctx = new clang::AnalysisDeclContext(&_adcm, func); + _target_obj_lids.clear(); + do_target_object_analysis(func); // dataflow analysis + } + } + else { + // invalid function given => clean up old analysis result + if (_analysis_decl_ctx) { + delete _analysis_decl_ctx; // drop cache + } + _analysis_decl_ctx = 0; + _target_obj_lids.clear(); + } +} + +bool ClangFlowAnalysis::valid() const { + return (_analysis_decl_ctx) && + (_analysis_decl_ctx->getCFG()) && + (_analysis_decl_ctx->getCFGStmtMap()); +} + +void ClangFlowAnalysis::do_target_object_analysis(clang::DeclaratorDecl* func) { + if ( !valid() ) { + return; // CFG construction failed + } + + clang::CFG* cfg = _analysis_decl_ctx->getCFG(); + + DataflowWorklist worklist(*_analysis_decl_ctx->getCFG(), *_analysis_decl_ctx); + + // enqueue (each CFG block): + for (CFG::const_iterator it = cfg->begin(), ei = cfg->end(); it != ei; ++it) { + const CFGBlock *block = *it; + worklist.enqueueBlock(block); + } + worklist.sortWorklist(); + + DataFlowValues::reset_next_free_id(); + + // allocate the to-be-computed DataFlowValues for each basic block + std::vector perBlockValues; // indexed by CFG-Block IDs + perBlockValues.resize(cfg->getNumBlockIDs()); + + // dequeue: + while (const CFGBlock *block = worklist.dequeue()) { + + // FIXME: make sure that we've already visited at least one predecessor + + // variable values at the end of this basic block (after applying TF) + DataFlowValues &vals_end = perBlockValues[block->getBlockID()]; + + // variables values at the beginning of this basic block (computed by merge) + DataFlowValues vals_begin; + vals_begin.copyHistory(vals_end); // remember merge-conflict resolutions + + // merge the values of all predecessor blocks to compute 'vals_begin' + for (CFGBlock::const_pred_iterator it = block->pred_begin(), ei = block->pred_end(); it != ei; ++it) { + if (const CFGBlock *pred = *it) { + vals_begin.merge(perBlockValues[pred->getBlockID()]); + } + } + + // if there are no predecessors, this must be the entry block: + if ( block->pred_empty() ) { + if (clang::FunctionDecl* func_decl = dyn_cast(func)) { + // initialize the entry block with the function parameters + DeclContext::specific_decl_iterator I(func_decl->decls_begin()), + E(func_decl->decls_end()); + for ( ; I != E; ++I) { + vals_begin.add_variable(*I); + } + } + } + + // call RecursiveASTVisitor and apply the TransferFunctions + TransferFunctions TF(vals_begin, _target_obj_lids, _analysis_decl_ctx->getASTContext()); + + for (CFGBlock::const_iterator BI=block->begin(), BE=block->end(); BI != BE; ++BI) { + if (Optional stmt = BI->getAs()) { + TF.TraverseStmt(const_cast(stmt->getStmt())); + } + } + + // did the variable values change (compared to last iteration)? + if (vals_begin.equals(vals_end)) { + continue; // fix point reached + } + + // update the variable values after applying the TF + vals_end = vals_begin; + + // enqueue the successors, which consume the updated variable values + worklist.enqueueSuccessors(block); + } + + /* + // debug: + for (CFG::const_reverse_iterator it = cfg->rbegin(), ei = cfg->rend(); it != ei; ++it) { + const CFGBlock *block = *it; + std::cout << "================ [" << block->getBlockID() << "] ===================" << std::endl; + perBlockValues[block->getBlockID()].dump(); + std::cout << "========================================" << std::endl << std::endl; + } + */ +} + +unsigned int ClangFlowAnalysis::get_block_lid(clang::DeclaratorDecl* func, + clang::Stmt* stmt) { + + analyze(func); // do the hard work + if ( valid() ) { + // lookup the basic block id for the given stmt + clang::CFGStmtMap* stmt_map = _analysis_decl_ctx->getCFGStmtMap(); + clang::CFGBlock* cfg_block = stmt_map->getBlock(stmt); + if (cfg_block) { + // building a DominatorTree segfaults :-( + //clang::DominatorTree dt; + //dt.buildDominatorTree(*_analysis_decl_ctx); + return cfg_block->getBlockID(); + } + } + return 0; // cannot calculate a block id (e.g., no function body found) +} + +unsigned int ClangFlowAnalysis::get_target_obj_lid(clang::DeclaratorDecl* func, + clang::CallExpr* CE) { + + analyze(func); // do the hard work + call_target_obj_lid_map_t::iterator found = _target_obj_lids.find(CE); + if( found != _target_obj_lids.end() ) { + return found->second; + } + return NO_ID; // lookup failed +} diff --git a/AspectC++/ClangFlowAnalysis.h b/AspectC++/ClangFlowAnalysis.h new file mode 100644 index 0000000..ec04926 --- /dev/null +++ b/AspectC++/ClangFlowAnalysis.h @@ -0,0 +1,62 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2015 The 'ac++' developers (see aspectc.org) +// +// 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 __ClangFlowAnalysis_h__ +#define __ClangFlowAnalysis_h__ + +#include "clang/Analysis/AnalysisContext.h" +#include "clang/AST/Stmt.h" +#include "clang/AST/Expr.h" +#include + +class ClangFlowAnalysis { +private: + // interface to clang's CFG + clang::AnalysisDeclContextManager _adcm; + clang::AnalysisDeclContext* _analysis_decl_ctx; // last-used cache + + void analyze(clang::DeclaratorDecl* func); + void do_target_object_analysis(clang::DeclaratorDecl* func); + +public: + typedef std::map call_target_obj_lid_map_t; + +private: + call_target_obj_lid_map_t _target_obj_lids; + +public: + // reserved ID for get_target_obj_lid(...) + static const unsigned int NO_ID = 0; + static const unsigned int THIS_ID = 1; + + ClangFlowAnalysis() : _analysis_decl_ctx(0) {} + ~ClangFlowAnalysis(); + + // Calculate the basic-block id for a 'stmt' within a 'func'tion + unsigned int get_block_lid(clang::DeclaratorDecl* func, clang::Stmt* stmt); + + // Calculate an ID for the target object used in a call expression. + // If the same ID is calculated for two different call expressions, + // both call expression refer to the same target object. + unsigned int get_target_obj_lid(clang::DeclaratorDecl* func, clang::CallExpr* CE); + + // Determine whether the current analysis succeeds/succeeded + bool valid() const; +}; + +#endif // __ClangFlowAnalysis_h__ diff --git a/AspectC++/ClangIncludeExpander.cc b/AspectC++/ClangIncludeExpander.cc new file mode 100644 index 0000000..ed0fba1 --- /dev/null +++ b/AspectC++/ClangIncludeExpander.cc @@ -0,0 +1,76 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "ClangIncludeExpander.h" +#include "LineDirectiveMgr.h" +#include "version.h" + +#include "clang/Basic/Version.h" +#include "clang/Frontend/CompilerInstance.h" +#include "ClangInclusionRewriter.h" +#include "llvm/Support/raw_os_ostream.h" + +void ClangIncludeExpander::expand(std::ostream &out) { + // Setup the strategy object that decides whether an include should be + // expanded. + struct ProjectStrategy : public clang::FileExpansionStrategy { + ClangIncludeExpander &_ie; + ProjectStrategy(ClangIncludeExpander &ie) : _ie(ie) {} + + virtual bool should_expand_file(clang::FileID From, clang::FileID To) { + clang::SourceManager &sm = + _ie._project.get_compiler_instance()->getSourceManager(); + + // Check if From and To are coming from this project. +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_4_0_0 + const char *from_name = sm.getFileEntryForID(From)->getName().data(); + const char *to_name = sm.getFileEntryForID(To)->getName().data(); +#else + const char *from_name = sm.getFileEntryForID(From)->getName(); + const char *to_name = sm.getFileEntryForID(To)->getName(); +#endif + bool from_below = _ie._project.isBelow(from_name); + bool to_below = _ie._project.isBelow(to_name); + +// cout << "include '" << to_name +// << "' from '" << from_name << "'" << endl; + if (!from_below && to_below) { + // oops, an external file includes an internal => error! + _ie._err << Puma::sev_error //<< this_token.location () + << "internal file '" << to_name + << "' is included by external '" << from_name << "'" + << Puma::endMessage; + } + + return to_below; + } + }; + + clang::CompilerInstance *ci = _project.get_compiler_instance(); + if (!ci) + return; // No compiler, nothing to do! + // Create a new PP to get rid of old state. + ci->createPreprocessor(clang::TU_Complete); + ci->getDiagnosticClient().BeginSourceFile(ci->getLangOpts(), &ci->getPreprocessor()); + // Now call Clang's include rewriter to do the heavy lifting. + llvm::raw_os_ostream osos(out); + ProjectStrategy s(*this); + clang::PreprocessorOutputOptions opts = ci->getPreprocessorOutputOpts(); + opts.ShowLineMarkers = (_line_mgr.noline () ? 0 : 1); + clang::RewriteIncludesInInput(ci->getPreprocessor(), &osos, opts, &s); +} diff --git a/AspectC++/ClangIncludeExpander.h b/AspectC++/ClangIncludeExpander.h new file mode 100644 index 0000000..35ed3f3 --- /dev/null +++ b/AspectC++/ClangIncludeExpander.h @@ -0,0 +1,43 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __clang_include_expander_h__ +#define __clang_include_expander_h__ + +// Visitor, which expands all project-local includes + +#include "ACProject.h" +#include "ACErrorStream.h" +class LineDirectiveMgr; + +class ClangIncludeExpander { + + ACErrorStream &_err; + ACProject &_project; + LineDirectiveMgr &_line_mgr; + +public: + + ClangIncludeExpander (ACErrorStream &err, ACProject &project, + LineDirectiveMgr &ldm) : + _err (err), _project (project), _line_mgr (ldm) {} + + void expand (std::ostream &out); +}; + +#endif // __clang_include_expander_h__ diff --git a/AspectC++/ClangInclusionRewriter.cc b/AspectC++/ClangInclusionRewriter.cc new file mode 100644 index 0000000..a37c848 --- /dev/null +++ b/AspectC++/ClangInclusionRewriter.cc @@ -0,0 +1,634 @@ +//===--- InclusionRewriter.cpp - Rewrite includes into their expansions ---===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This code rewrites include invocations into their expansions. This gives you +// a file with all included files merged into it. +// +//===----------------------------------------------------------------------===// + +#include "ClangInclusionRewriter.h" +#include "version.h" +#include "clang/Basic/Version.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Frontend/PreprocessorOutputOptions.h" +#include "clang/Lex/HeaderSearch.h" +#include "clang/Lex/Pragma.h" +#include "clang/Lex/Preprocessor.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/Support/raw_ostream.h" + +#include +using namespace std; + +using namespace clang; +using namespace llvm; + +namespace { + +class InclusionRewriter : public PPCallbacks { + /// Information about which #includes were actually performed, + /// created by preprocessor callbacks. + struct FileChange { + const Module *Mod; + SourceLocation From; + FileID Id; + SrcMgr::CharacteristicKind FileType; + FileChange(SourceLocation From, const Module *Mod) : Mod(Mod), From(From) { + } + }; + Preprocessor &PP; ///< Used to find inclusion directives. + SourceManager &SM; ///< Used to read and manage source files. + raw_ostream &OS; ///< The destination stream for rewritten contents. + const llvm::MemoryBuffer *PredefinesBuffer; ///< The preprocessor predefines. + bool ShowLineMarkers; ///< Show #line markers. + bool UseLineDirective; ///< Use of line directives or line markers. + typedef std::map FileChangeMap; + FileChangeMap FileChanges; ///< Tracks which files were included where. + /// Used transitively for building up the FileChanges mapping over the + /// various \c PPCallbacks callbacks. + FileChangeMap::iterator LastInsertedFileChange; +public: + InclusionRewriter(Preprocessor &PP, raw_ostream &OS, bool ShowLineMarkers, + FileExpansionStrategy *strategy = 0); + bool Process(FileID FileId, SrcMgr::CharacteristicKind FileType); + void setPredefinesBuffer(const llvm::MemoryBuffer *Buf) { + PredefinesBuffer = Buf; + } +private: + virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason, + SrcMgr::CharacteristicKind FileType, + FileID PrevFID); + virtual void FileSkipped(const FileEntry &ParentFile, + const Token &FilenameTok, + SrcMgr::CharacteristicKind FileType); + virtual void InclusionDirective(SourceLocation HashLoc, + const Token &IncludeTok, + StringRef FileName, + bool IsAngled, + CharSourceRange FilenameRange, + const FileEntry *File, + StringRef SearchPath, + StringRef RelativePath, + const Module *Imported); + void WriteLineInfo(const char *Filename, int Line, + SrcMgr::CharacteristicKind FileType, + StringRef EOL, StringRef Extra = StringRef()); + void WriteImplicitModuleImport(const Module *Mod, StringRef EOL); + void OutputContentUpTo(const MemoryBuffer &FromFile, + unsigned &WriteFrom, unsigned WriteTo, + StringRef EOL, int &lines, + bool EnsureNewline = false); + void CommentOutDirective(Lexer &DirectivesLex, const Token &StartToken, + const MemoryBuffer &FromFile, StringRef EOL, + unsigned &NextToWrite, int &Lines); + bool HandleHasInclude(FileID FileId, Lexer &RawLex, + const DirectoryLookup *Lookup, Token &Tok, + bool &FileExists); + const FileChange *FindFileChangeLocation(SourceLocation Loc) const; + StringRef NextIdentifierName(Lexer &RawLex, Token &RawToken); + + FileExpansionStrategy *aspect; +}; + +} // end anonymous namespace + +/// Initializes an InclusionRewriter with a \p PP source and \p OS destination. +InclusionRewriter::InclusionRewriter(Preprocessor &PP, raw_ostream &OS, + bool ShowLineMarkers, + FileExpansionStrategy *strategy) + : PP(PP), SM(PP.getSourceManager()), OS(OS), PredefinesBuffer(0), + ShowLineMarkers(ShowLineMarkers), + LastInsertedFileChange(FileChanges.end()), + aspect(strategy) { + // If we're in microsoft mode, use normal #line instead of line markers. + UseLineDirective = true; // We always want #line in AspectC++. +} + +/// Write appropriate line information as either #line directives or GNU line +/// markers depending on what mode we're in, including the \p Filename and +/// \p Line we are located at, using the specified \p EOL line separator, and +/// any \p Extra context specifiers in GNU line directives. +void InclusionRewriter::WriteLineInfo(const char *Filename, int Line, + SrcMgr::CharacteristicKind FileType, + StringRef EOL, StringRef Extra) { + if (!ShowLineMarkers) + return; + if (UseLineDirective) { + OS << "#line" << ' ' << Line << ' ' << '"'; + OS.write_escaped(Filename); + OS << '"'; + } else { + // Use GNU linemarkers as described here: + // http://gcc.gnu.org/onlinedocs/cpp/Preprocessor-Output.html + OS << '#' << ' ' << Line << ' ' << '"'; + OS.write_escaped(Filename); + OS << '"'; + if (!Extra.empty()) + OS << Extra; + if (FileType == SrcMgr::C_System) + // "`3' This indicates that the following text comes from a system header + // file, so certain warnings should be suppressed." + OS << " 3"; + else if (FileType == SrcMgr::C_ExternCSystem) + // as above for `3', plus "`4' This indicates that the following text + // should be treated as being wrapped in an implicit extern "C" block." + OS << " 3 4"; + } + OS << EOL; +} + +void InclusionRewriter::WriteImplicitModuleImport(const Module *Mod, + StringRef EOL) { + OS << "@import " << Mod->getFullModuleName() << ";" + << " /* clang -frewrite-includes: implicit import */" << EOL; +} + +/// FileChanged - Whenever the preprocessor enters or exits a #include file +/// it invokes this handler. +void InclusionRewriter::FileChanged(SourceLocation Loc, + FileChangeReason Reason, + SrcMgr::CharacteristicKind NewFileType, + FileID) { + if (Reason != EnterFile) + return; + if (LastInsertedFileChange == FileChanges.end()) + // we didn't reach this file (eg: the main file) via an inclusion directive + return; + LastInsertedFileChange->second.Id = FullSourceLoc(Loc, SM).getFileID(); + LastInsertedFileChange->second.FileType = NewFileType; + LastInsertedFileChange = FileChanges.end(); +} + +/// Called whenever an inclusion is skipped due to canonical header protection +/// macros. +void InclusionRewriter::FileSkipped(const FileEntry &/*ParentFile*/, + const Token &/*FilenameTok*/, + SrcMgr::CharacteristicKind /*FileType*/) { + assert(LastInsertedFileChange != FileChanges.end() && "A file, that wasn't " + "found via an inclusion directive, was skipped"); + FileChanges.erase(LastInsertedFileChange); + LastInsertedFileChange = FileChanges.end(); +} + +/// This should be called whenever the preprocessor encounters include +/// directives. It does not say whether the file has been included, but it +/// provides more information about the directive (hash location instead +/// of location inside the included file). It is assumed that the matching +/// FileChanged() or FileSkipped() is called after this. +void InclusionRewriter::InclusionDirective(SourceLocation HashLoc, + const Token &/*IncludeTok*/, + StringRef /*FileName*/, + bool /*IsAngled*/, + CharSourceRange /*FilenameRange*/, + const FileEntry * /*File*/, + StringRef /*SearchPath*/, + StringRef /*RelativePath*/, + const Module *Imported) { + assert(LastInsertedFileChange == FileChanges.end() && "Another inclusion " + "directive was found before the previous one was processed"); + std::pair p = FileChanges.insert( + std::make_pair(HashLoc.getRawEncoding(), FileChange(HashLoc, Imported))); + assert(p.second && "Unexpected revisitation of the same include directive"); + if (!Imported) + LastInsertedFileChange = p.first; +} + +/// Simple lookup for a SourceLocation (specifically one denoting the hash in +/// an inclusion directive) in the map of inclusion information, FileChanges. +const InclusionRewriter::FileChange * +InclusionRewriter::FindFileChangeLocation(SourceLocation Loc) const { + FileChangeMap::const_iterator I = FileChanges.find(Loc.getRawEncoding()); + if (I != FileChanges.end()) + return &I->second; + return NULL; +} + +/// Detect the likely line ending style of \p FromFile by examining the first +/// newline found within it. +static StringRef DetectEOL(const MemoryBuffer &FromFile) { + // detect what line endings the file uses, so that added content does not mix + // the style + const char *Pos = strchr(FromFile.getBufferStart(), '\n'); + if (Pos == NULL) + return "\n"; + if (Pos + 1 < FromFile.getBufferEnd() && Pos[1] == '\r') + return "\n\r"; + if (Pos - 1 >= FromFile.getBufferStart() && Pos[-1] == '\r') + return "\r\n"; + return "\n"; +} + +/// Writes out bytes from \p FromFile, starting at \p NextToWrite and ending at +/// \p WriteTo - 1. +void InclusionRewriter::OutputContentUpTo(const MemoryBuffer &FromFile, + unsigned &WriteFrom, unsigned WriteTo, + StringRef EOL, int &Line, + bool EnsureNewline) { + if (WriteTo <= WriteFrom) + return; + if (&FromFile == PredefinesBuffer) { + // Ignore the #defines of the predefines buffer. + WriteFrom = WriteTo; + return; + } + OS.write(FromFile.getBufferStart() + WriteFrom, WriteTo - WriteFrom); + // count lines manually, it's faster than getPresumedLoc() + Line += std::count(FromFile.getBufferStart() + WriteFrom, + FromFile.getBufferStart() + WriteTo, '\n'); + if (EnsureNewline) { + char LastChar = FromFile.getBufferStart()[WriteTo - 1]; + if (LastChar != '\n' && LastChar != '\r') + OS << EOL; + } + WriteFrom = WriteTo; +} + +/// Print characters from \p FromFile starting at \p NextToWrite up until the +/// inclusion directive at \p StartToken, then print out the inclusion +/// inclusion directive disabled by a #if directive, updating \p NextToWrite +/// and \p Line to track the number of source lines visited and the progress +/// through the \p FromFile buffer. +void InclusionRewriter::CommentOutDirective(Lexer &DirectiveLex, + const Token &StartToken, + const MemoryBuffer &FromFile, + StringRef EOL, + unsigned &NextToWrite, int &Line) { + OutputContentUpTo(FromFile, NextToWrite, + SM.getFileOffset(StartToken.getLocation()), EOL, Line); + // The eod-token can contain a multi-line comment. Therefore we end + // our "commented-out" comment after the token, that is in front of the + // eod-token. Afterwards we write the eod-token. + Token DirectiveToken; + Token prev_directive_token; + int token_count = 0; + do { + prev_directive_token = DirectiveToken; + DirectiveLex.LexFromRawLexer(DirectiveToken); + ++token_count; + } while (!DirectiveToken.is(tok::eod) && DirectiveToken.isNot(tok::eof)); +// OS << "#if 0 /* expanded by -frewrite-includes */" << EOL; + if(token_count <= 1) { + // If DirectiveToken is still the first token, then we have no previous token. + // Set prev_directive_token to the first token: + prev_directive_token = DirectiveToken; + } + OS << " /* commented-out by ac++ include expander: "; + OutputContentUpTo(FromFile, NextToWrite, + SM.getFileOffset(prev_directive_token.getLocation()) + prev_directive_token.getLength(), + EOL, Line); + OS << " */ "; + OutputContentUpTo(FromFile, NextToWrite, + SM.getFileOffset(DirectiveToken.getLocation()) + DirectiveToken.getLength(), + EOL, Line); +// OS << "#endif /* expanded by -frewrite-includes */" << EOL; +} + +/// Find the next identifier in the pragma directive specified by \p RawToken. +StringRef InclusionRewriter::NextIdentifierName(Lexer &RawLex, + Token &RawToken) { + RawLex.LexFromRawLexer(RawToken); + if (RawToken.is(tok::raw_identifier)) + PP.LookUpIdentifierInfo(RawToken); + if (RawToken.is(tok::identifier)) + return RawToken.getIdentifierInfo()->getName(); + return StringRef(); +} + +// Expand __has_include and __has_include_next if possible. If there's no +// definitive answer return false. +bool InclusionRewriter::HandleHasInclude( + FileID FileId, Lexer &RawLex, const DirectoryLookup *Lookup, Token &Tok, + bool &FileExists) { + // Lex the opening paren. + RawLex.LexFromRawLexer(Tok); + if (Tok.isNot(tok::l_paren)) + return false; + + RawLex.LexFromRawLexer(Tok); + + SmallString<128> FilenameBuffer; + StringRef Filename; + // Since the raw lexer doesn't give us angle_literals we have to parse them + // ourselves. + // FIXME: What to do if the file name is a macro? + if (Tok.is(tok::less)) { + RawLex.LexFromRawLexer(Tok); + + FilenameBuffer += '<'; + do { + if (Tok.is(tok::eod)) // Sanity check. + return false; + + if (Tok.is(tok::raw_identifier)) + PP.LookUpIdentifierInfo(Tok); + + // Get the string piece. + SmallVector TmpBuffer; + bool Invalid = false; + StringRef TmpName = PP.getSpelling(Tok, TmpBuffer, &Invalid); + if (Invalid) + return false; + + FilenameBuffer += TmpName; + + RawLex.LexFromRawLexer(Tok); + } while (Tok.isNot(tok::greater)); + + FilenameBuffer += '>'; + Filename = FilenameBuffer; + } else { + if (Tok.isNot(tok::string_literal)) + return false; + + bool Invalid = false; + Filename = PP.getSpelling(Tok, FilenameBuffer, &Invalid); + if (Invalid) + return false; + } + + // Lex the closing paren. + RawLex.LexFromRawLexer(Tok); + if (Tok.isNot(tok::r_paren)) + return false; + + // Now ask HeaderInfo if it knows about the header. + // FIXME: Subframeworks aren't handled here. Do we care? + bool isAngled = PP.GetIncludeFilenameSpelling(Tok.getLocation(), Filename); + const DirectoryLookup *CurDir; + const FileEntry *FileEnt = PP.getSourceManager().getFileEntryForID(FileId); + +// Create "Includers" for the following call of LookupFile depending on Clang version: +#if CLANG_VERSION_NUMBER <= VERSION_NUMBER_3_5_2 + ArrayRef Includers = llvm::makeArrayRef(FileEnt); +#else // Clang > 3.5.2: + SmallVector, 1> + Includers; + Includers.push_back(std::make_pair(FileEnt, FileEnt->getDir())); +#endif // Clang 3.5.2 + + // Call LookupFile: + // FIXME: Why don't we call PP.LookupFile here? + const FileEntry *File = PP.getHeaderSearchInfo().LookupFile( + // StringRef Filename, SourceLocation IncludeLoc, bool isAngled, + Filename, SourceLocation(), isAngled, + // const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir, + nullptr, CurDir, + // ArrayRef> Includers, + // *or* (depending on Clang version (see above)) + // ArrayRef Includers, + Includers, + // SmallVectorImpl *SearchPath, SmallVectorImpl *RelativePath, + nullptr, nullptr, +// Clang > 3.7.1 has an additional argument: +#if CLANG_VERSION_NUMBER > VERSION_NUMBER_3_7_1 + // Module *RequestingModule, + nullptr, +#endif // Clang 3.7.1 + // ModuleMap::KnownHeader *SuggestedModule + nullptr +// Clang >= 5.0.0 has another additional argument: +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_5_0_0 + // , bool *IsMapped, + , nullptr +#endif // Clang 5.0.0 + ); + FileExists = File != 0; + return true; +} + +/// Use a raw lexer to analyze \p FileId, incrementally copying parts of it +/// and including content of included files recursively. +bool InclusionRewriter::Process(FileID FileId, + SrcMgr::CharacteristicKind FileType) +{ + bool Invalid; + const MemoryBuffer &FromFile = *SM.getBuffer(FileId, &Invalid); + if (Invalid) // invalid inclusion + return false; +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_4_0_0 + const char *FileName = FromFile.getBufferIdentifier().data(); +#else + const char *FileName = FromFile.getBufferIdentifier(); +#endif + Lexer RawLex(FileId, &FromFile, PP.getSourceManager(), PP.getLangOpts()); + RawLex.SetCommentRetentionState(false); + + StringRef EOL = DetectEOL(FromFile); + + // Per the GNU docs: "1" indicates the start of a new file. + WriteLineInfo(FileName, 1, FileType, EOL, " 1"); + + if (SM.getFileIDSize(FileId) == 0) + return false; + + // The next byte to be copied from the source file + unsigned NextToWrite = 0; + int Line = 1; // The current input file line number. + + // Ignore UTF-8 BOM, otherwise it'd end up somewhere else than the start + // of the resulting file. + if (FromFile.getBuffer().startswith("\xEF\xBB\xBF")) + NextToWrite = 3; + + Token RawToken; + RawLex.LexFromRawLexer(RawToken); + + // TODO: Consider adding a switch that strips possibly unimportant content, + // such as comments, to reduce the size of repro files. + while (RawToken.isNot(tok::eof)) { + if (RawToken.is(tok::hash) && RawToken.isAtStartOfLine()) { + RawLex.setParsingPreprocessorDirective(true); + Token HashToken = RawToken; + RawLex.LexFromRawLexer(RawToken); + if (RawToken.is(tok::raw_identifier)) + PP.LookUpIdentifierInfo(RawToken); + if (RawToken.getIdentifierInfo() != NULL) { + switch (RawToken.getIdentifierInfo()->getPPKeywordID()) { + case tok::pp_include: + case tok::pp_include_next: + case tok::pp_import: { + const FileChange *Change = FindFileChangeLocation( + HashToken.getLocation()); + if (aspect && Change && !aspect->should_expand_file(FileId, + Change->Id)) + break; + + CommentOutDirective(RawLex, HashToken, FromFile, EOL, NextToWrite, + Line); + StringRef LineInfoExtra; + if (Change) { + if (Change->Mod) { + WriteImplicitModuleImport(Change->Mod, EOL); + + // else now include and recursively process the file + } else if (Process(Change->Id, Change->FileType)) { + // and set lineinfo back to this file, if the nested one was + // actually included + // `2' indicates returning to a file (after having included + // another file. + LineInfoExtra = " 2"; + } + // new for AspectC++ + PresumedLoc PLoc = SM.getPresumedLoc(HashToken.getLocation()); + WriteLineInfo(PLoc.getFilename (), PLoc.getLine() + 1, FileType, EOL, LineInfoExtra); + // end new + } + // fix up lineinfo (since commented out directive changed line + // numbers) for inclusions that were skipped due to header guards + // not needed for AspectC++ + // WriteLineInfo(FileName, Line, FileType, EOL, LineInfoExtra); + break; + } + case tok::pp_pragma: { + StringRef Identifier = NextIdentifierName(RawLex, RawToken); + if (Identifier == "clang" || Identifier == "GCC") { + if (NextIdentifierName(RawLex, RawToken) == "system_header") { + // keep the directive in, commented out + CommentOutDirective(RawLex, HashToken, FromFile, EOL, + NextToWrite, Line); + // update our own type + FileType = SM.getFileCharacteristic(RawToken.getLocation()); + // not needed for AspectC++ +// WriteLineInfo(FileName, Line, FileType, EOL); + } + } else if (Identifier == "once") { + // keep the directive in, commented out + CommentOutDirective(RawLex, HashToken, FromFile, EOL, + NextToWrite, Line); + // not needed for AspectC++ +// WriteLineInfo(FileName, Line, FileType, EOL); + } + break; + } + case tok::pp_if: + case tok::pp_elif: { + bool elif = (RawToken.getIdentifierInfo()->getPPKeywordID() == + tok::pp_elif); + // Rewrite special builtin macros to avoid pulling in host details. + do { + // Walk over the directive. + RawLex.LexFromRawLexer(RawToken); + if (RawToken.is(tok::raw_identifier)) + PP.LookUpIdentifierInfo(RawToken); + + if (RawToken.is(tok::identifier)) { + bool HasFile; + SourceLocation Loc = RawToken.getLocation(); + + // Rewrite __has_include(x) + if (RawToken.getIdentifierInfo()->isStr("__has_include")) { + if (!HandleHasInclude(FileId, RawLex, 0, RawToken, HasFile)) + continue; + // Rewrite __has_include_next(x) + } else if (RawToken.getIdentifierInfo()->isStr( + "__has_include_next")) { + const DirectoryLookup *Lookup = PP.GetCurDirLookup(); + if (Lookup) + ++Lookup; + + if (!HandleHasInclude(FileId, RawLex, Lookup, RawToken, + HasFile)) + continue; + } else { + continue; + } + // Replace the macro with (0) or (1), followed by the commented + // out macro for reference. + OutputContentUpTo(FromFile, NextToWrite, SM.getFileOffset(Loc), + EOL, Line); + OS << '(' << (int) HasFile << ")/*"; + OutputContentUpTo(FromFile, NextToWrite, + SM.getFileOffset(RawToken.getLocation()) + + RawToken.getLength(), + EOL, Line); + OS << "*/"; + } + } while (RawToken.isNot(tok::eod)); + if (elif) { + OutputContentUpTo(FromFile, NextToWrite, + SM.getFileOffset(RawToken.getLocation()) + + RawToken.getLength(), + EOL, Line, /*EnsureNewLine*/ true); + // not needed for AspectC++ +// WriteLineInfo(FileName, Line, FileType, EOL); + } + break; + } + case tok::pp_endif: + case tok::pp_else: { + // We surround every #include by #if 0 to comment it out, but that + // changes line numbers. These are fixed up right after that, but + // the whole #include could be inside a preprocessor conditional + // that is not processed. So it is necessary to fix the line + // numbers one the next line after each #else/#endif as well. + RawLex.SetKeepWhitespaceMode(true); + do { + RawLex.LexFromRawLexer(RawToken); + } while (RawToken.isNot(tok::eod) && RawToken.isNot(tok::eof)); + OutputContentUpTo( + FromFile, NextToWrite, + SM.getFileOffset(RawToken.getLocation()) + RawToken.getLength(), + EOL, Line, /*EnsureNewLine*/ true); + // not needed for AspectC++ +// WriteLineInfo(FileName, Line, FileType, EOL); + RawLex.SetKeepWhitespaceMode(false); + } + default: + break; + } + } + RawLex.setParsingPreprocessorDirective(false); + } + RawLex.LexFromRawLexer(RawToken); + } + OutputContentUpTo(FromFile, NextToWrite, + SM.getFileOffset(SM.getLocForEndOfFile(FileId)), EOL, Line, + /*EnsureNewline*/true); + return true; +} + +/// InclusionRewriterInInput - Implement -frewrite-includes mode. +void clang::RewriteIncludesInInput(Preprocessor &PP, raw_ostream *OS, + const PreprocessorOutputOptions &Opts, + FileExpansionStrategy *strategy) { + SourceManager &SM = PP.getSourceManager(); + InclusionRewriter *Rewrite = new InclusionRewriter(PP, *OS, + Opts.ShowLineMarkers, + strategy); +#if CLANG_VERSION_NUMBER <= VERSION_NUMBER_3_5_2 + PP.addPPCallbacks(Rewrite); +#else // C++ 11 interface + PP.addPPCallbacks(std::unique_ptr(Rewrite)); +#endif + // Ignore all pragmas, otherwise there will be warnings about unknown pragmas + // (because there's nothing to handle them). + PP.AddPragmaHandler(new EmptyPragmaHandler()); + // Ignore also all pragma in all namespaces created + // in Preprocessor::RegisterBuiltinPragmas(). + PP.AddPragmaHandler("GCC", new EmptyPragmaHandler()); + PP.AddPragmaHandler("clang", new EmptyPragmaHandler()); + + // First let the preprocessor process the entire file and call callbacks. + // Callbacks will record which #include's were actually performed. + PP.EnterMainSourceFile(); + Token Tok; + // Only preprocessor directives matter here, so disable macro expansion + // everywhere else as an optimization. + // TODO: It would be even faster if the preprocessor could be switched + // to a mode where it would parse only preprocessor directives and comments, + // nothing else matters for parsing or processing. + PP.SetMacroExpansionOnlyInDirectives(); + do { + PP.Lex(Tok); + } while (Tok.isNot(tok::eof)); + Rewrite->setPredefinesBuffer(SM.getBuffer(PP.getPredefinesFileID())); + Rewrite->Process(PP.getPredefinesFileID(), SrcMgr::C_User); + Rewrite->Process(SM.getMainFileID(), SrcMgr::C_User); + OS->flush(); +} diff --git a/AspectC++/ClangInclusionRewriter.h b/AspectC++/ClangInclusionRewriter.h new file mode 100644 index 0000000..aa21486 --- /dev/null +++ b/AspectC++/ClangInclusionRewriter.h @@ -0,0 +1,44 @@ +//===--- Rewriters.h - Rewriter implementations -------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This header contains miscellaneous utilities for various front-end actions. +// +//===----------------------------------------------------------------------===// + +#ifndef __ClangInclusionRewriter_h__ +#define __ClangInclusionRewriter_h__ + +#include "clang/Basic/LLVM.h" + +namespace clang { +class Preprocessor; +class PreprocessorOutputOptions; +class FileID; + +// AspectClang LOCAL +struct FileExpansionStrategy { + virtual ~FileExpansionStrategy() {} + virtual bool should_expand_file(FileID From, FileID To) = 0; +}; +// AspectClang LOCAL + +/// RewriteMacrosInInput - Implement -rewrite-macros mode. +void RewriteMacrosInInput(Preprocessor &PP, raw_ostream *OS); + +/// DoRewriteTest - A simple test for the TokenRewriter class. +void DoRewriteTest(Preprocessor &PP, raw_ostream *OS); + +/// RewriteIncludesInInput - Implement -frewrite-includes mode. +void RewriteIncludesInInput(Preprocessor &PP, raw_ostream *OS, + const PreprocessorOutputOptions &Opts, + FileExpansionStrategy *strategy = 0); + +} // end namespace clang + +#endif // __ClangInclusionRewriter_h__ diff --git a/AspectC++/ClangIntroParser.cc b/AspectC++/ClangIntroParser.cc new file mode 100644 index 0000000..f221aa7 --- /dev/null +++ b/AspectC++/ClangIntroParser.cc @@ -0,0 +1,139 @@ + +// FIXME: This is a hack to give ClangIntroParser access rights to the current scope +// This has to be included FIRST! +#define private protected +#include "clang/Parse/Parser.h" +#undef private + +#include "version.h" + +#include "ClangIntroParser.h" +#include "clang/Basic/Version.h" +#include "clang/Parse/ParseDiagnostic.h" +using namespace clang; + +// FIXME: duplicated loop! +// TODO: try to make Clang developers integrate this refactoring +void ClangIntroParser::ParseCXXClassBody(Decl *TagDecl) { + // ----------------AspectC++ modified + unsigned TagType = DeclSpec::TST_struct; + AccessSpecifier CurAS = AS_private; // doesn't really matter; introduced code contains private/... +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_9_1 + ParsedAttributesWithRange AccessAttrs(getAttrFactory()); +#else + ParsedAttributes AccessAttrs(getAttrFactory()); +#endif + // the following two reference definitions are needed, because + // our trick (private->protected)does not make all attributes protected :-( + Token &Tok = (Token&)getCurToken(); + Sema &Actions = getActions(); + // ----------------up to here + + while (Tok.isNot(tok::eof)) { + if (Tok.is(tok::r_brace)) { + break; + } + + // Each iteration of this loop reads one member-declaration. + + if (getLangOpts().MicrosoftExt && (Tok.is(tok::kw___if_exists) || + Tok.is(tok::kw___if_not_exists))) { + ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType, CurAS); + continue; + } + + // Check for extraneous top-level semicolon. + if (Tok.is(tok::semi)) { + ConsumeExtraSemi(InsideStruct, TagType); + continue; + } + + if (Tok.is(tok::annot_pragma_vis)) { + HandlePragmaVisibility(); + continue; + } + + if (Tok.is(tok::annot_pragma_pack)) { + HandlePragmaPack(); + continue; + } + + if (Tok.is(tok::annot_pragma_align)) { + HandlePragmaAlign(); + continue; + } + + if (Tok.is(tok::annot_pragma_openmp)) { +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_9_1 + ParseOpenMPDeclarativeDirectiveWithExtDecl(CurAS, AccessAttrs); +#else + ParseOpenMPDeclarativeDirective(); +#endif + continue; + } + + // If we see a namespace here, a close brace was missing somewhere. + if (Tok.is(tok::kw_namespace)) { + DiagnoseUnexpectedNamespace(cast(TagDecl)); + break; + } + + AccessSpecifier AS = getAccessSpecifierIfPresent(); + if (AS != AS_none) { + // Current token is a C++ access specifier. + CurAS = AS; + SourceLocation ASLoc = Tok.getLocation(); + unsigned TokLength = Tok.getLength(); + ConsumeToken(); + AccessAttrs.clear(); + MaybeParseGNUAttributes(AccessAttrs); + + SourceLocation EndLoc; + if (Tok.is(tok::colon)) { + EndLoc = Tok.getLocation(); + ConsumeToken(); + } else if (Tok.is(tok::semi)) { + EndLoc = Tok.getLocation(); + ConsumeToken(); +#if CLANG_VERSION_NUMBER <= VERSION_NUMBER_3_5_2 + Diag(EndLoc, diag::err_expected) << tok::colon + << FixItHint::CreateReplacement(EndLoc, ":"); +#else // C++ 11 interface + Diag(EndLoc, diag::err_expected) + << tok::colon << FixItHint::CreateReplacement(EndLoc, ":"); +#endif + } else { + EndLoc = ASLoc.getLocWithOffset(TokLength); +#if CLANG_VERSION_NUMBER <= VERSION_NUMBER_3_5_2 + Diag(EndLoc, diag::err_expected) << tok::colon + << FixItHint::CreateInsertion(EndLoc, ":"); +#else // C++ 11 interface + Diag(EndLoc, diag::err_expected) + << tok::colon << FixItHint::CreateInsertion(EndLoc, ":"); +#endif + } + + // The Microsoft extension __interface does not permit non-public + // access specifiers. + if (TagType == DeclSpec::TST_interface && CurAS != AS_public) { + Diag(ASLoc, diag::err_access_specifier_interface) + << (CurAS == AS_protected); + } + + if (Actions.ActOnAccessSpecifier(AS, ASLoc, EndLoc, + AccessAttrs.getList())) { + // found another attribute than only annotations + AccessAttrs.clear(); + } + + continue; + } + + // Parse all the comma separated declarators. + ParseCXXClassMemberDeclaration(CurAS, AccessAttrs.getList()); + } +} + +void ClangIntroParser::ParseBaseClause(clang::Decl *TagDecl) { + clang::Parser::ParseBaseClause(TagDecl); +} diff --git a/AspectC++/ClangIntroParser.h b/AspectC++/ClangIntroParser.h new file mode 100644 index 0000000..2a0538e --- /dev/null +++ b/AspectC++/ClangIntroParser.h @@ -0,0 +1,23 @@ +#ifndef __ClangIntroParser_h__ +#define __ClangIntroParser_h__ + +#include "clang/Parse/Parser.h" + +class ClangIntroParser : public clang::Parser { + +public: + + ClangIntroParser(clang::Preprocessor &PP, clang::Sema &Actions, + bool SkipFunctionBodies) : + clang::Parser(PP, Actions, SkipFunctionBodies) {} + + // New parser function: Clang parses the whole class definition in one + // function. For the introduction mechanism we need to parse a class body + // separately. + void ParseCXXClassBody(clang::Decl *TagDecl); + + // Hack: We make this parser method 'public' + void ParseBaseClause(clang::Decl *TagDecl); +}; + +#endif // __ClangIntroParser_h__ diff --git a/AspectC++/ClangIntroSema.cc b/AspectC++/ClangIntroSema.cc new file mode 100644 index 0000000..10cf3a2 --- /dev/null +++ b/AspectC++/ClangIntroSema.cc @@ -0,0 +1,344 @@ + +// FIXME: This is a hack to give ClangIntroSema access rights to the current scope +// This has to be included FIRST! +#define private protected +#include "clang/Sema/Sema.h" +#undef private +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Sema/SemaDiagnostic.h" + +#include "ClangIntroSema.h" +#include "ClangIntroducer.h" +#include "ClangBinding.h" +#include "ACProject.h" +#include "ModelBuilder.h" + +using namespace clang; + +// remove all attributes that have namespace "AC::" in its name from the +// attribute list 'in' and put them into 'hidden' +void hideACAttrs(clang::AttributeList * &in, clang::AttributeList *&hidden) { + clang::AttributeList *prev = 0, *al = in; + while (al) { + clang::AttributeList * next = al->getNext(); + if (al->hasScope() && al->getScopeName()->getName() != "gnu" && + al->getScopeName()->getName() != "clang") { +// std::cout << " hide " << al->getName()->getNameStart() << std::endl; + if (prev) + prev->setNext(al->getNext()); + else + in = al->getNext(); + al->setNext(hidden); + hidden = al; + } + else + prev = al; + al = next; + } +} + +// add all attributes from 'hidden' into 'out'. 'hidden' is empty afterwards +void restoreACAttrs(clang::AttributeList * &out, clang::AttributeList *&hidden) { + clang::AttributeList *al = out; + // special handling of empty list first + if (!al) { + out = hidden; + } + else { + // find the end of the list + while (al->getNext()) { + al = al->getNext(); + } + // append the hidden list + al->setNext(hidden); + } + // make sure the hidden list is empty after this shifting of attributes + hidden = 0; +} + +void injectAttrs(clang::Decl *decl, clang::ASTContext &context, const clang::AttributeList * al) { + while (al) { +// std::cout << " injecting " << al->getName()->getNameStart() << std::endl; + clang::AnnotateAttr *attr = ::new (context) clang::AnnotateAttr(al->getRange(), context, + al->getName()->getName(), 0 /* spelling list index of AnnotateAttr is always 0 */); + decl->addAttr(attr); + al = al->getNext(); + } +} + +ClangIntroSema::ClangIntroSema(ClangIntroducer &introducer, + Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, + TranslationUnitKind TUKind, CodeCompleteConsumer *CompletionConsumer) : + Sema (pp, ctxt, consumer, TUKind, CompletionConsumer), + _introducer (&introducer), _nested_tu_end(0) /*, _nested_base_specifiers (0)*/ { +} + +ClangIntroSema::~ClangIntroSema() { +} + +Scope *ClangIntroSema::setCurScope(Scope *new_scope) { + Scope *old_scope = CurScope; + CurScope = new_scope; + return old_scope; +} + +void ClangIntroSema::ActOnStartCXXMemberDeclarations(Scope *S, Decl *TagDecl, + SourceLocation FinalLoc, bool IsFinalSpelledSealed, + SourceLocation LBraceLoc) { + _introducer->class_start(TagDecl, LBraceLoc); + RealActOnStartCXXMemberDeclarations(*this, S, TagDecl, FinalLoc, + IsFinalSpelledSealed, LBraceLoc); +} + +#if FRONTEND_CLANG >= 38 +void ClangIntroSema::ActOnBaseSpecifiers (Decl *ClassDecl, + clang::MutableArrayRef Bases) { + for (unsigned n = 0; n < Bases.size(); n++) + _BaseInfo[ClassDecl].push_back(Bases[n]); + if (_nested_base_specifiers[ClassDecl] == 0) { + _nested_base_specifiers[ClassDecl]++; + _introducer->base_specs_end(ClassDecl); + _nested_base_specifiers[ClassDecl]--; + RealActOnBaseSpecifiers(*this, ClassDecl, _BaseInfo[ClassDecl]); +// _BaseInfo.clear (); + _BaseInfo.erase (ClassDecl); + } +} +#else +void ClangIntroSema::ActOnBaseSpecifiers (Decl *ClassDecl, + CXXBaseSpecifier **Bases, unsigned NumBases) { + for (unsigned n = 0; n < NumBases; n++) + _BaseInfo[ClassDecl].push_back(Bases[n]); + if (_nested_base_specifiers[ClassDecl] == 0) { + _nested_base_specifiers[ClassDecl]++; + _introducer->base_specs_end(ClassDecl); + _nested_base_specifiers[ClassDecl]--; + RealActOnBaseSpecifiers(*this, ClassDecl, _BaseInfo[ClassDecl].data (), _BaseInfo[ClassDecl].size ()); +// _BaseInfo.clear (); + _BaseInfo.erase (ClassDecl); + } +} +#endif + +#if FRONTEND_CLANG >= 38 +clang::Decl* ClangIntroSema::ActOnStartOfFunctionDef( + clang::Scope *S, clang::Declarator &D, + clang::MultiTemplateParamsArg TemplateParamLists, + clang::Sema::SkipBodyInfo *SkipBody) { +// std::cout << "ActOnStartOfFunctionDef!" << std::endl; + clang::AttributeList *declspec_attrs = 0, *declarator_attrs = 0; + hideACAttrs (D.getMutableDeclSpec().getAttributes().getListRef(), declspec_attrs); + hideACAttrs (D.getAttrListRef(), declarator_attrs); + clang::Decl *decl = RealActOnStartOfFunctionDef(*this, S, D, TemplateParamLists, SkipBody); + injectAttrs(decl, this->getASTContext(), declspec_attrs); + injectAttrs(decl, this->getASTContext(), declarator_attrs); +// decl->dump(); + clang::FunctionDecl *fdecl = clang::dyn_cast(decl); + if (fdecl) + _introducer->function_start(fdecl); + restoreACAttrs(D.getMutableDeclSpec().getAttributes().getListRef(), declspec_attrs); + restoreACAttrs(D.getAttrListRef(), declarator_attrs); + return decl; +} +#else +clang::Decl* ClangIntroSema::ActOnStartOfFunctionDef( + clang::Scope *S, clang::Declarator &D) { +// std::cout << "ActOnStartOfFunctionDef!" << std::endl; + clang::AttributeList *declspec_attrs = 0, *declarator_attrs = 0; + hideACAttrs (D.getMutableDeclSpec().getAttributes().getListRef(), declspec_attrs); + hideACAttrs (D.getAttrListRef(), declarator_attrs); + clang::Decl *decl = RealActOnStartOfFunctionDef(*this, S, D); + injectAttrs(decl, this->getASTContext(), declspec_attrs); + injectAttrs(decl, this->getASTContext(), declarator_attrs); +// decl->dump(); + clang::FunctionDecl *fdecl = clang::dyn_cast(decl); + if (fdecl) + _introducer->function_start(fdecl); + restoreACAttrs(D.getMutableDeclSpec().getAttributes().getListRef(), declspec_attrs); + restoreACAttrs(D.getAttrListRef(), declarator_attrs); + return decl; +} +#endif + +#if FRONTEND_CLANG >= 38 +clang::Decl* ClangIntroSema::ActOnStartNamespaceDef ( + clang::Scope *S, clang::SourceLocation InlineLoc, clang::SourceLocation NamespaceLoc, + clang::SourceLocation IdentLoc, clang::IdentifierInfo *Ident, clang::SourceLocation LBrace, + clang::AttributeList *AttrList, clang::UsingDirectiveDecl * &UsingDecl) { +// std::cout << "ActOnNamespaceDef!" << std::endl; + clang::AttributeList *hidden_attrs = 0; + hideACAttrs (AttrList, hidden_attrs); + clang::Decl *decl = RealActOnStartNamespaceDef(*this, S, InlineLoc, NamespaceLoc, IdentLoc, Ident, LBrace, AttrList, UsingDecl); + injectAttrs(decl, this->getASTContext(), hidden_attrs); + // decl->dump(); + restoreACAttrs(AttrList, hidden_attrs); + return decl; +} +#else +clang::Decl* ClangIntroSema::ActOnStartNamespaceDef ( + clang::Scope *S, clang::SourceLocation InlineLoc, clang::SourceLocation NamespaceLoc, + clang::SourceLocation IdentLoc, clang::IdentifierInfo *Ident, clang::SourceLocation LBrace, + clang::AttributeList *AttrList) { +// std::cout << "ActOnNamespaceDef!" << std::endl; + clang::AttributeList *hidden_attrs = 0; + hideACAttrs (AttrList, hidden_attrs); + clang::Decl *decl = RealActOnStartNamespaceDef(*this, S, InlineLoc, NamespaceLoc, IdentLoc, Ident, LBrace, AttrList); + injectAttrs(decl, this->getASTContext(), hidden_attrs); + // decl->dump(); + restoreACAttrs(AttrList, hidden_attrs); + return decl; +} +#endif + +#if FRONTEND_CLANG >= 50 +clang::Decl* ClangIntroSema::ActOnTag ( + clang::Scope *S, unsigned TagSpec, clang::Sema::TagUseKind TUK, clang::SourceLocation KWLoc, clang::CXXScopeSpec &SS, + clang::IdentifierInfo *Name, clang::SourceLocation NameLoc, clang::AttributeList *Attr, clang::AccessSpecifier AS, + clang::SourceLocation ModulePrivateLoc, clang::MultiTemplateParamsArg TemplateParameterLists, + bool &OwnedDecl, bool &IsDependent, clang::SourceLocation ScopedEnumKWLoc, + bool ScopedEnumUsesClassTag, clang::TypeResult UnderlyingType, bool IsTypeSpecifier, bool IsTemplateParamOrArg, clang::Sema::SkipBodyInfo *SkipBody) { +// std::cout << "ActOnTag!" << std::endl; + clang::AttributeList *hidden_attrs = 0; + hideACAttrs (Attr, hidden_attrs); + clang::Decl *decl = RealActOnTag(*this, S, TagSpec, TUK, KWLoc, SS, Name, NameLoc, Attr, AS, ModulePrivateLoc, TemplateParameterLists, + OwnedDecl, IsDependent, ScopedEnumKWLoc, ScopedEnumUsesClassTag, UnderlyingType, IsTypeSpecifier, IsTemplateParamOrArg, SkipBody); + injectAttrs(decl, this->getASTContext(), hidden_attrs); +// decl->dump(); + restoreACAttrs(Attr, hidden_attrs); + return decl; +} +#elif FRONTEND_CLANG >= 37 +clang::Decl* ClangIntroSema::ActOnTag ( + clang::Scope *S, unsigned TagSpec, clang::Sema::TagUseKind TUK, clang::SourceLocation KWLoc, clang::CXXScopeSpec &SS, + clang::IdentifierInfo *Name, clang::SourceLocation NameLoc, clang::AttributeList *Attr, clang::AccessSpecifier AS, + clang::SourceLocation ModulePrivateLoc, clang::MultiTemplateParamsArg TemplateParameterLists, + bool &OwnedDecl, bool &IsDependent, clang::SourceLocation ScopedEnumKWLoc, + bool ScopedEnumUsesClassTag, clang::TypeResult UnderlyingType, bool IsTypeSpecifier, clang::Sema::SkipBodyInfo *SkipBody) { +// std::cout << "ActOnTag!" << std::endl; + clang::AttributeList *hidden_attrs = 0; + hideACAttrs (Attr, hidden_attrs); + clang::Decl *decl = RealActOnTag(*this, S, TagSpec, TUK, KWLoc, SS, Name, NameLoc, Attr, AS, ModulePrivateLoc, TemplateParameterLists, + OwnedDecl, IsDependent, ScopedEnumKWLoc, ScopedEnumUsesClassTag, UnderlyingType, IsTypeSpecifier, SkipBody); + injectAttrs(decl, this->getASTContext(), hidden_attrs); +// decl->dump(); + restoreACAttrs(Attr, hidden_attrs); + return decl; +} +#elif FRONTEND_CLANG >= 35 +clang::Decl* ClangIntroSema::ActOnTag ( + clang::Scope *S, unsigned TagSpec, clang::Sema::TagUseKind TUK, clang::SourceLocation KWLoc, clang::CXXScopeSpec &SS, + clang::IdentifierInfo *Name, clang::SourceLocation NameLoc, clang::AttributeList *Attr, clang::AccessSpecifier AS, + clang::SourceLocation ModulePrivateLoc, clang::MultiTemplateParamsArg TemplateParameterLists, + bool &OwnedDecl, bool &IsDependent, clang::SourceLocation ScopedEnumKWLoc, + bool ScopedEnumUsesClassTag, clang::TypeResult UnderlyingType, bool IsTypeSpecifier) { +// std::cout << "ActOnTag!" << std::endl; + clang::AttributeList *hidden_attrs = 0; + hideACAttrs (Attr, hidden_attrs); + clang::Decl *decl = RealActOnTag(*this, S, TagSpec, TUK, KWLoc, SS, Name, NameLoc, Attr, AS, ModulePrivateLoc, TemplateParameterLists, + OwnedDecl, IsDependent, ScopedEnumKWLoc, ScopedEnumUsesClassTag, UnderlyingType, IsTypeSpecifier); + injectAttrs(decl, this->getASTContext(), hidden_attrs); +// decl->dump(); + restoreACAttrs(Attr, hidden_attrs); + return decl; +} +#else +clang::Decl* ClangIntroSema::ActOnTag ( + clang::Scope *S, unsigned TagSpec, clang::Sema::TagUseKind TUK, clang::SourceLocation KWLoc, clang::CXXScopeSpec &SS, + clang::IdentifierInfo *Name, clang::SourceLocation NameLoc, clang::AttributeList *Attr, clang::AccessSpecifier AS, + clang::SourceLocation ModulePrivateLoc, clang::MultiTemplateParamsArg TemplateParameterLists, + bool &OwnedDecl, bool &IsDependent, clang::SourceLocation ScopedEnumKWLoc, + bool ScopedEnumUsesClassTag, clang::TypeResult UnderlyingType) { +// std::cout << "ActOnTag!" << std::endl; + clang::AttributeList *hidden_attrs = 0; + hideACAttrs (Attr, hidden_attrs); + clang::Decl *decl = RealActOnTag(*this, S, TagSpec, TUK, KWLoc, SS, Name, NameLoc, Attr, AS, ModulePrivateLoc, TemplateParameterLists, + OwnedDecl, IsDependent, ScopedEnumKWLoc, ScopedEnumUsesClassTag, UnderlyingType); + injectAttrs(decl, this->getASTContext(), hidden_attrs); +// decl->dump(); + restoreACAttrs(Attr, hidden_attrs); + return decl; +} +#endif + +void ClangIntroSema::ActOnFinishCXXMemberSpecification (Scope* S, + SourceLocation RLoc, Decl *TagDecl, SourceLocation LBrac, + SourceLocation RBrac, AttributeList *AttrList) { + _introducer->class_end (TagDecl, RBrac); + RealActOnFinishCXXMemberSpecification(*this, S, RLoc, TagDecl, LBrac, RBrac, + AttrList); +} + +void ClangIntroSema::ActOnEndOfTranslationUnit () { + if (_nested_tu_end == 0) { + _nested_tu_end++; + _introducer->tunit_end (); + _nested_tu_end--; + // workaround: clang warns if skipped inline functions are used. In our case + // this happens with inline functions that are not part of the project. + // To avoid annoying messages they are suppressed here. +#if FRONTEND_CLANG >= 35 + getDiagnostics().setSeverity(diag::warn_undefined_inline, diag::Severity::Ignored, SourceLocation()); +#endif + RealActOnEndOfTranslationUnit(*this); +// getASTContext().getTranslationUnitDecl ()->dump(); + + } +} + +bool ClangIntroSema::canSkipFunctionBody(Decl *FctDecl) { + clang::SourceManager &sm = _introducer->_ci->getSourceManager(); + clang::PresumedLoc PL = sm.getPresumedLoc(FctDecl->getLocation()); + llvm::StringRef Name = PL.getFilename(); + llvm::StringRef BufferName = sm.getBufferName(FctDecl->getLocation()); + ACProject &project = _introducer->get_model_builder().get_project(); + bool in_project = (BufferName.startswith("") || project.isBelow(Name.str().c_str())))); +// cout << Name.str() << " " << BufferName.str() << " " << in_project << endl; + return !in_project && RealcanSkipFunctionBody(*this, FctDecl); +} + + +clang::NamedDecl *ClangIntroSema::ActOnCXXMemberDeclarator(clang::Scope *S, clang::AccessSpecifier AS, + clang::Declarator &D, clang::MultiTemplateParamsArg TemplateParameterLists, + clang::Expr *BitfieldWidth, const clang::VirtSpecifiers &VS, + clang::InClassInitStyle InitStyle){ +// std::cout << "ActOnCXXMemberDeclarator!" << std::endl; + clang::AttributeList *declspec_attrs = 0, *declarator_attrs = 0; + hideACAttrs (D.getMutableDeclSpec().getAttributes().getListRef(), declspec_attrs); + hideACAttrs (D.getAttrListRef(), declarator_attrs); + clang::NamedDecl *ndecl = RealActOnCXXMemberDeclarator(*this, S, AS, D, TemplateParameterLists, + BitfieldWidth, VS, InitStyle); +// std::cout << " name " << ndecl->getNameAsString() << std::endl; + injectAttrs(ndecl, this->getASTContext(), declspec_attrs); + injectAttrs(ndecl, this->getASTContext(), declarator_attrs); + clang::DeclaratorDecl *ddecl = clang::dyn_cast(ndecl); + clang::FunctionDecl *fdecl = clang::dyn_cast(ndecl); + if (fdecl) + _introducer->function_start(fdecl); + else if (ddecl) + _introducer->declarator_start(ddecl); + // ndecl->dump(); + restoreACAttrs(D.getMutableDeclSpec().getAttributes().getListRef(), declspec_attrs); + restoreACAttrs(D.getAttrListRef(), declarator_attrs); + return ndecl; +} + +clang::Decl *ClangIntroSema::ActOnDeclarator(clang::Scope *S, clang::Declarator &D) { +// std::cout << "ActOnDeclarator!" << std::endl; + clang::AttributeList *declspec_attrs = 0, *declarator_attrs = 0; + hideACAttrs (D.getMutableDeclSpec().getAttributes().getListRef(), declspec_attrs); + hideACAttrs (D.getAttrListRef(), declarator_attrs); + clang::Decl *decl = RealActOnDeclarator(*this, S, D); + injectAttrs(decl, this->getASTContext(), declspec_attrs); + injectAttrs(decl, this->getASTContext(), declarator_attrs); + clang::DeclaratorDecl *ddecl = clang::dyn_cast(decl); + clang::FunctionDecl *fdecl = clang::dyn_cast(decl); + if (fdecl) // must be check first, because a FunctionDecl is also a DeclaratorDecl + _introducer->function_start(fdecl); + else if (ddecl) + _introducer->declarator_start(ddecl); + restoreACAttrs(D.getMutableDeclSpec().getAttributes().getListRef(), declspec_attrs); + restoreACAttrs(D.getAttrListRef(), declarator_attrs); + return decl; +} + diff --git a/AspectC++/ClangIntroSema.h b/AspectC++/ClangIntroSema.h new file mode 100644 index 0000000..a12f4ce --- /dev/null +++ b/AspectC++/ClangIntroSema.h @@ -0,0 +1,107 @@ +#ifndef __ClangIntroSema_h__ +#define __ClangIntroSema_h__ + +#include "clang/Sema/Sema.h" +#include + +class ClangIntroducer; + +class ClangIntroSema : public clang::Sema { + ClangIntroducer *_introducer; + int _nested_tu_end; + std::map _nested_base_specifiers; + std::map > _BaseInfo; + +public: + ClangIntroSema(ClangIntroducer &introducer, + clang::Preprocessor &pp, clang::ASTContext &ctxt, + clang::ASTConsumer &consumer, + clang::TranslationUnitKind TUKind = clang::TU_Complete, + clang::CodeCompleteConsumer *CompletionConsumer = 0); + ~ClangIntroSema (); + + clang::Scope *setCurScope(clang::Scope *new_scope); + + void ActOnStartCXXMemberDeclarations(clang::Scope *S, clang::Decl *TagDecl, + clang::SourceLocation FinalLoc, bool IsFinalSpelledSealed, + clang::SourceLocation LBraceLoc); + +#if FRONTEND_CLANG >= 38 + void ActOnBaseSpecifiers (clang::Decl *ClassDecl, + clang::MutableArrayRef Bases); +#else + void ActOnBaseSpecifiers (clang::Decl *ClassDecl, + clang::CXXBaseSpecifier **Bases, unsigned NumBases); +#endif + +#if FRONTEND_CLANG >= 38 + clang::Decl* ActOnStartOfFunctionDef( + clang::Scope *S, clang::Declarator &D, + clang::MultiTemplateParamsArg TemplateParamLists, + clang::Sema::SkipBodyInfo *SkipBody); +#else + clang::Decl* ActOnStartOfFunctionDef( + clang::Scope *S, clang::Declarator &D); +#endif + +#if FRONTEND_CLANG >= 38 + clang::Decl* ActOnStartNamespaceDef ( + clang::Scope *S, clang::SourceLocation InlineLoc, clang::SourceLocation NamespaceLoc, + clang::SourceLocation IdentLoc, clang::IdentifierInfo *Ident, clang::SourceLocation LBrace, + clang::AttributeList *AttrList, clang::UsingDirectiveDecl * &UsingDecl); +#else + clang::Decl* ActOnStartNamespaceDef ( + clang::Scope *S, clang::SourceLocation InlineLoc, clang::SourceLocation NamespaceLoc, + clang::SourceLocation IdentLoc, clang::IdentifierInfo *Ident, clang::SourceLocation LBrace, + clang::AttributeList *AttrList); +#endif + +#if FRONTEND_CLANG >= 50 +clang::Decl* ActOnTag ( + clang::Scope *S, unsigned TagSpec, clang::Sema::TagUseKind TUK, clang::SourceLocation KWLoc, clang::CXXScopeSpec &SS, + clang::IdentifierInfo *Name, clang::SourceLocation NameLoc, clang::AttributeList *Attr, clang::AccessSpecifier AS, + clang::SourceLocation ModulePrivateLoc, clang::MultiTemplateParamsArg TemplateParameterLists, + bool &OwnedDecl, bool &IsDependent, clang::SourceLocation ScopedEnumKWLoc, + bool ScopedEnumUsesClassTag, clang::TypeResult UnderlyingType, bool IsTypeSpecifier, bool IsTemplateParamOrArg, + clang::Sema::SkipBodyInfo *SkipBody); +#elif FRONTEND_CLANG >= 37 + clang::Decl* ActOnTag ( + clang::Scope *S, unsigned TagSpec, clang::Sema::TagUseKind TUK, clang::SourceLocation KWLoc, clang::CXXScopeSpec &SS, + clang::IdentifierInfo *Name, clang::SourceLocation NameLoc, clang::AttributeList *Attr, clang::AccessSpecifier AS, + clang::SourceLocation ModulePrivateLoc, clang::MultiTemplateParamsArg TemplateParameterLists, + bool &OwnedDecl, bool &IsDependent, clang::SourceLocation ScopedEnumKWLoc, + bool ScopedEnumUsesClassTag, clang::TypeResult UnderlyingType, bool IsTypeSpecifier, clang::Sema::SkipBodyInfo *SkipBody); +#elif FRONTEND_CLANG >= 35 + clang::Decl* ActOnTag ( + clang::Scope *S, unsigned TagSpec, clang::Sema::TagUseKind TUK, clang::SourceLocation KWLoc, clang::CXXScopeSpec &SS, + clang::IdentifierInfo *Name, clang::SourceLocation NameLoc, clang::AttributeList *Attr, clang::AccessSpecifier AS, + clang::SourceLocation ModulePrivateLoc, clang::MultiTemplateParamsArg TemplateParameterLists, + bool &OwnedDecl, bool &IsDependent, clang::SourceLocation ScopedEnumKWLoc, + bool ScopedEnumUsesClassTag, clang::TypeResult UnderlyingType, bool IsTypeSpecifier); +#else + clang::Decl* ActOnTag ( + clang::Scope *S, unsigned TagSpec, clang::Sema::TagUseKind TUK, clang::SourceLocation KWLoc, clang::CXXScopeSpec &SS, + clang::IdentifierInfo *Name, clang::SourceLocation NameLoc, clang::AttributeList *Attr, clang::AccessSpecifier AS, + clang::SourceLocation ModulePrivateLoc, clang::MultiTemplateParamsArg TemplateParameterLists, + bool &OwnedDecl, bool &IsDependent, clang::SourceLocation ScopedEnumKWLoc, + bool ScopedEnumUsesClassTag, clang::TypeResult UnderlyingType); +#endif + + void ActOnFinishCXXMemberSpecification (clang::Scope* S, + clang::SourceLocation RLoc, clang::Decl *TagDecl, clang::SourceLocation LBrac, + clang::SourceLocation RBrac, clang::AttributeList *AttrList); + + void ActOnEndOfTranslationUnit (); + + bool canSkipFunctionBody(clang::Decl *FctDecl); + + clang::NamedDecl *ActOnCXXMemberDeclarator(clang::Scope *S, clang::AccessSpecifier AS, + clang::Declarator &D, clang::MultiTemplateParamsArg TemplateParameterLists, + clang::Expr *BitfieldWidth, const clang::VirtSpecifiers &VS, + clang::InClassInitStyle InitStyle); + + clang::Decl *ActOnDeclarator(clang::Scope *S, clang::Declarator &D); + +}; + +#endif // __ClangIntroSema_h__ diff --git a/AspectC++/ClangIntroducer.cc b/AspectC++/ClangIntroducer.cc new file mode 100644 index 0000000..c8d7d9a --- /dev/null +++ b/AspectC++/ClangIntroducer.cc @@ -0,0 +1,1318 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 +using std::cout; +using std::endl; +#include +using std::set; + +#include "clang/AST/ASTContext.h" +#include "clang/AST/ASTConsumer.h" +#include "clang/AST/DeclTemplate.h" +#include "clang/Sema/Template.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Parse/Parser.h" +#include "clang/AST/Attr.h" +#include "llvm/ADT/StringExtras.h" + +#include "ClangIntroducer.h" +#include "ACFileID.h" +#include "Plan.h" +#include "CodeWeaver.h" +#include "LineDirectiveMgr.h" +#include "IncludeGraph.h" +#include "Naming.h" +#include "AspectInfo.h" +#include "OrderInfo.h" +#include "IntroductionInfo.h" +#include "ModelBuilder.h" +#include "ACModel/Utils.h" +#include "PointCutContext.h" +#include "PointCutExpr.h" +#include "IntroductionUnit.h" +#include "TransformInfo.h" +#include "ClangIntroParser.h" +#include "ClangIntroSema.h" +#include "ClangAnnotation.h" + +using namespace Puma; + +// Destructor: release all allocated resources +ClangIntroducer::~ClangIntroducer () { +} + +static const char *prot_str (clang::AccessSpecifier prot) { + switch (prot) { + case clang::AS_private: return "AC::PROT_PRIVATE"; + case clang::AS_protected: return "AC::PROT_PROTECTED"; + case clang::AS_public: return "AC::PROT_PUBLIC"; + case clang::AS_none: return "AC::PROT_NONE"; + } + return 0; +} + +static string spec_str (bool is_static, bool is_mutable, bool is_virtual) { + int pos = 0; + string result; + if (is_static) { + if (pos++) result += "|"; + result += "AC::SPEC_STATIC"; + } + if (is_mutable) { + if (pos++) result += "|"; + result += "AC::SPEC_MUTABLE"; + } + if (is_virtual) { + if (pos++) result += "|"; + result += "AC::SPEC_VIRTUAL"; + } + if (!pos) + result = "AC::SPEC_NONE"; + return result; +} + +// insert friend declarations for all aspects +bool ClangIntroducer::insert_aspectof_function(std::string &str, + clang::CXXRecordDecl *ci) { + if (!ci) + return false; + + ACM_Aspect *jpl_aspect = _jpm.register_aspect (ci); + if (!jpl_aspect) + return false; + + // iterate over all member functions and find any definitions of + // 'aspectof' or 'aspectOf' + clang::NamedDecl *aspectOf_func = 0; + clang::NamedDecl *aspectof_func = 0; + for (clang::CXXRecordDecl::decl_iterator di = ci->decls_begin(), + de = ci->decls_end(); + di != de; ++di) { + clang::NamedDecl *nd = llvm::dyn_cast (*di); + if (!nd) + continue; + if (nd->getKind () == clang::Decl::FunctionTemplate || + nd->getKind () == clang::Decl::CXXMethod) { + if (nd->getNameAsString() == "aspectof") + aspectof_func = nd; + else if (nd->getNameAsString() == "aspectOf") + aspectOf_func = nd; + } + + // Register all members now. Some may not be in the model yet because we're + // in the middle of parsing classes. + clang::CXXMethodDecl *md = llvm::dyn_cast (nd); + if (md) { + if (!_jpm.register_pointcut(md, jpl_aspect)) + _jpm.register_function(md, jpl_aspect); + } + } + + // Don't create instances of abstract aspects. + if (::is_abstract(*jpl_aspect)) + return false; + +#if 0 + if (aspectOf_func && !aspectof_func) { + // rename the function to 'aspectof' + CT_FctDef *fctdef = (CT_FctDef*)aspectOf_func->Tree (); + CT_SimpleName *name = ((CT_Declarator*)fctdef->Declarator ())->Name (); + name = name->Name (); // if it is qualified + const WeavePos &name_start = + _code_weaver.weave_pos (ACToken (name->token ()), WeavePos::WP_BEFORE); + const WeavePos &name_end = + _code_weaver.weave_pos (ACToken (name->end_token ()), WeavePos::WP_AFTER); + _code_weaver.replace (name_start, name_end, "aspectof"); + return false; // nothing to introduce + } +#endif + + if (!aspectOf_func && !aspectof_func) { + llvm::raw_string_ostream unit(str); + unit << '\n' + << "public:" << '\n' + << " static " << ci->getName () << " *aspectof () {" << '\n' + << " static " << ci->getName () << " __instance;" << '\n' + << " return &__instance;" << '\n' + << " }" << '\n' + << " static " << ci->getName () << " *aspectOf () {" << '\n' + << " return aspectof ();" << '\n' + << " }" << '\n' + << "private:" << '\n'; + return true; + } + return false; +} + +bool ClangIntroducer::insert_aspect_friend_decls(std::string &str, + clang::Decl *decl) { + if (!decl) + return false; + + clang::TagDecl *td = llvm::dyn_cast(decl); + // introductions into unions require some extra effort (not implemented yet) + if (td && td->isUnion()) + return false; + + // check whether the insertion is indicated for this class or union + clang::SourceManager &sm = _code_weaver.getRewriter().getSourceMgr(); + + // no need for template instances; the templates already get the friend injection + if (clang::CXXRecordDecl *r = llvm::dyn_cast(decl)) + if (r->getTemplateSpecializationKind() == + clang::TSK_ImplicitInstantiation || + r->getTemplateSpecializationKind() == + clang::TSK_ExplicitInstantiationDefinition) + return false; + + clang::NamedDecl* nd = llvm::dyn_cast(decl); + if (nd) { + std::string qual_name(nd->getQualifiedNameAsString()); + llvm::StringRef name(nd->getName()); + + // code introduced by phase 1 (in special namespace AC) is not modified here + if (llvm::StringRef(qual_name).startswith("AC::")) + return false; + + // introspection code is also not modified + else if ( ((name == "BaseClass") || + (name == "Member") || + (name == "Function") || + (name == "Constructor") || + (name == "Destructor")) && + (llvm::StringRef(qual_name).count("::__TI::") || + llvm::StringRef(qual_name).count("::__TJP_"))) + return false; + } + + // nested classes in template instances should also not be modified to avoid double injection + //if (_jpm.inside_template_instance(decl)) + //return false; + // the class has to belong to the project + llvm::StringRef name = sm.getPresumedLoc(decl->getLocation()).getFilename(); + llvm::StringRef buffer_name = sm.getBufferName(decl->getLocation()); + if (!buffer_name.startswith("getQualifiedNameAsString() == jpl.get_name())) { + str += " friend class ::"; + str += jpl.get_name(); + str += ";\n"; + result = true; + } + } + + return result; +} + +static bool is_attribute(clang::DeclaratorDecl *dd) { + if (clang::FieldDecl *fd = llvm::dyn_cast(dd)) + return !fd->isBitField(); + return true; +} + +// insert introspection code +// * at the end of class definitions, after AspectC++ introductions +std::string ClangIntroducer::insert_introspection_code(clang::CXXRecordDecl *cd, + int precedence) { + std::string str; + llvm::raw_string_ostream unit(str); + + if (!cd /*|| !cd->Object ()->DefObject ()->ClassInfo()*/) + return ""; + + // return if this class is not an introduction target or has C linkage + if (!_jpm.is_valid_model_class (cd) || !_jpm.is_intro_target (cd)) + return ""; + + // introspection templates cannot be declared inside of a local class + if (cd->isLocalClass()) // integrate check into _jpm.is_valid_model_class ? + return ""; + + // Return if this class is defined in an extern "C" context + if (TI_Class::is_extern_c(cd)) + return ""; +// if (clang::LinkageSpecDecl *SD = +// llvm::dyn_cast(cd->getDeclContext())) +// if (SD->getLanguage() == clang::LinkageSpecDecl::lang_c) +// return ""; + + unit << "public:\n"; + unit << " struct "; + if (precedence == -1) + unit << "__TI"; + else + unit << "__TJP_" << precedence; + unit << " {\n"; + + // generate the signature (fully qualified target class name) + unit << " static const char *signature () { return \""; + unit << cd->getQualifiedNameAsString(); + unit << "\"; }\n"; + + // generate a 32-bit hash code from the fully qualified target class name + unit << " enum { HASHCODE = " + << StrCol::hash(cd->getQualifiedNameAsString().c_str()) << "U };\n"; + + // generate a typedef for the target type + unit << " typedef " << *cd << " That;\n"; + + // generate a list with all base classes + unit << " template struct BaseClass {};\n"; + unsigned b = 0; + for (clang::CXXRecordDecl::base_class_iterator I = cd->bases_begin(), + E = cd->bases_end(); + I != E; ++I) { + unit << " template struct BaseClass<" << b + << ", __D> { typedef "; + unit << TI_Type::get_type_text(I->getType(), &cd->getASTContext(), "Type", TSEF_ENABLE, true, TSEF_DONOTCHANGE, false, true, false); + unit << "; "; + unit << "static const AC::Protection prot = " + << prot_str(I->getAccessSpecifierAsWritten()) << "; "; + unit << "static const AC::Specifiers spec = (AC::Specifiers)(" + << spec_str (false, false, I->isVirtual()) << "); "; + unit << "};\n"; + b++; + } + unit << " enum { BASECLASSES = " << b << " };\n"; + + llvm::StringRef clsname = cd->getName(); + // generate Member => a list with all attribute types + unit << " template struct Member {};\n"; + unsigned e = 0; + for (clang::DeclContext::decl_iterator I = cd->decls_begin(), + E = cd->decls_end(); + I != E; ++I) { + clang::DeclaratorDecl *dd = llvm::dyn_cast(*I); + if (!dd || !is_attribute(dd)) + continue; + + // Here anonymous struct/class/union members are ignored + // TODO: Handle all members of these anonymous constructs. They are visible + // in the enclosing scope, i.e. here! + string name = dd->getNameAsString (); + if (name.empty ()) + continue; + + // static members are represented as VarDecls, the rest is FieldDecl. + clang::VarDecl *vd = llvm::dyn_cast(dd); + clang::FieldDecl *fd = llvm::dyn_cast(dd); + if (!vd && !fd) + continue; + + unit << " template struct Member<" << e << ", __D> { typedef "; + unit << TI_Type::get_type_text(dd->getType(), &dd->getASTContext(), "Type", TSEF_ENABLE, true, TSEF_DONOTCHANGE, false, true, false); + unit << "; typedef AC::Referred::type ReferredType; "; + unit << "static const AC::Protection prot = " << prot_str(dd->getAccess()) + << "; "; + unit << "static const AC::Specifiers spec = (AC::Specifiers)(" + << spec_str(vd, fd && fd->isMutable(), false) << "); "; + + // generate pointer => the typed pointer to attribute I + unit << "static ReferredType *pointer (" << clsname + << " *obj = 0) { return (ReferredType*)&"; + if (vd) + unit << clsname << "::" << *dd; + else + unit << "obj->" << *dd; + unit << "; } "; + // generate member_name => the name of attribute i + unit << "static const char *name () { return \"" << *dd << "\"; }\n"; + unit << " };\n"; + e++; + } + unit << " enum { MEMBERS = " << e << " };\n"; + + // generate a list with all member functions + unit << " template struct Function {};\n"; + unit << " template struct Constructor {};\n"; + unit << " template struct Destructor {};\n"; + unsigned int functions=0, constructors=0, destructors=0; + for (clang::CXXRecordDecl::method_iterator I = cd->method_begin(), + E = cd->method_end(); + I != E; ++I) { + clang::CXXMethodDecl *fi = *I; + + if (!fi || !_jpm.is_valid_model_function(fi) || !fi->isUserProvided()) + continue; + + if (llvm::dyn_cast(fi)) { + unit << " template struct Constructor<" << constructors << ", __D> { "; + constructors++; + } + else if (llvm::dyn_cast(fi)) { + unit << " template struct Destructor<" << destructors << ", __D> { "; + destructors++; + } + else { + unit << " template struct Function<" << functions << ", __D> { "; + functions++; + } + + unit << "static const AC::Protection prot = " << prot_str (fi->getAccess ()) << "; "; + unit << "static const AC::Specifiers spec = (AC::Specifiers)(" + << spec_str (false, false, fi->isVirtual()) << "); "; + + unit << "};\n"; + } + unit << " enum { FUNCTIONS = " << functions << " };\n"; + unit << " enum { CONSTRUCTORS = " << constructors << " };\n"; + unit << " enum { DESTRUCTORS = " << destructors << " };\n"; + + unit << " };\n"; +#if 0 + // paste a #line directive + LineDirectiveMgr &lmgr = _code_weaver.line_directive_mgr (); + ACUnit *dunit = new ACUnit (err); + lmgr.directive (*dunit, inspos.unit (), inspos); + *dunit << endu; + if (dunit->empty ()) delete dunit; else _code_weaver.insert (pos, dunit); +#endif + return unit.str(); +} + + +ACM_Class *ClangIntroducer::create_plan (clang::Decl *decl) { + + clang::RecordDecl *ci = llvm::dyn_cast(decl); + if (!ci) + return 0; + + // return if this class is not an introduction target + if (!_jpm.is_intro_target (ci)) + return 0; + + // try to register this class (might be a newly introduced class) + ACM_Class *jpl = _jpm.register_aspect (ci); + if (!jpl) jpl = _jpm.register_class (ci); + + // return if this is either not a valid model class or no valid intro target + if (!jpl || !jpl->get_intro_target ()) + return 0; + + // iterate through all introduction advice in the plan + PointCutContext context (_jpm, _conf); + const list &intros = _plan.introduction_infos (); + for (list::const_iterator i = intros.begin (); + i != intros.end (); ++i) { + IntroductionInfo *intro = *i; + // TODO: consider stand-alone advice here as well in the future (C-mode) + // something like ... if (!intro->is_activated ()) continue; + context.concrete_aspect (intro->aspect ()); + Binding binding; // binding and condition not used for intros + Condition condition; + PointCutExpr *pce = (PointCutExpr*)intro->pointcut_expr ().get (); + if (pce->match (*jpl, context, binding, condition)) + _plan.consider (*jpl, &intro->intro ()); + } + + if (jpl->has_plan ()) { + // order the advice & check + _plan.order (jpl); + + // remember the class info and join point location + _clangtargets.insert (ClangTargetMap::value_type (ci, jpl)); + } + return jpl; +} + + +ACM_Class *ClangIntroducer::plan_lookup (clang::Decl *ci) { + // Lazily create the plan. + if (_seen_classes.insert(ci).second) + create_plan (ci); + + ClangTargetMap::iterator i = _clangtargets.find (ci); + if (i != _clangtargets.end () && i->second->has_plan()) + return i->second; + return 0; +} + +const clang::Decl *ClangIntroducer::link_once_object (clang::CXXRecordDecl *ci) { + clang::SourceManager &sm = _code_weaver.getRewriter().getSourceMgr(); + // Functions before fields. + for (clang::CXXRecordDecl::decl_iterator DI = ci->decls_begin(), + DE = ci->decls_end(); + DI != DE; ++DI) { + // Skip generated code. + llvm::StringRef name = sm.getBufferName((*DI)->getLocation()); + if (name.startswith("(*DI)) { + // skip template functions and built-in functions + // they don't need link-once code + if (!MD->isUserProvided()) + continue; + // if a member function is undefined it is link-once code! + if (!MD->isDefined()) + return MD; + // if the function is defined, outside the class scope, and is not inline, + // we found the implementation + const clang::FunctionDecl *def; + if (MD->getBody(def) && def->getLexicalParent() != ci && + !def->isInlineSpecified()) + return def; + } + } + + for (clang::CXXRecordDecl::decl_iterator DI = ci->decls_begin(), + DE = ci->decls_end(); + DI != DE; ++DI) { + // Skip generated code. + llvm::StringRef name = sm.getBufferName((*DI)->getLocation()); + if (name.startswith("(*DI)) + if (VD->isStaticDataMember() && !VD->getInit() && +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_9_1 + VD->getDefinition()) +#else + VD->getOutOfLineDefinition()) +#endif + return VD; + } + return 0; +} + +void ClangIntroducer::parse (clang::Parser *parser, llvm::StringRef include, + clang::SourceLocation loc, clang::DeclContext *context) { +// cout << "parsing '" << include.data() << "'" << endl; + // if not demanded otherwise, parse the string in the global scope + if (context == 0) + context = _ci->getASTContext().getTranslationUnitDecl (); + clang::Token &token = (clang::Token &)parser->getCurToken(); + clang::Token saved_token = token; + string fname = _ci->getSourceManager().getFilename(_ci->getSourceManager().getExpansionLoc(loc)); + static int num = 0; + ostringstream name; + name << fname << "_virt" << num++; + ACFileID vfid = _conf.project().addVirtualFile(name.str(), include); + clang::FileID fid = _ci->getSourceManager().createFileID(vfid.file_entry(), loc, clang::SrcMgr::C_User); + _ci->getPreprocessor ().EnterSourceFile(fid, _ci->getPreprocessor().GetCurDirLookup(), loc); + _ci->getPreprocessor ().Lex (token); + ClangIntroSema &sema = (ClangIntroSema&)_ci->getSema(); + clang::Scope *old_scope = sema.setCurScope(sema.TUScope); + clang::DeclContext *old_context = sema.CurContext; + clang::DeclContext *old_lex_context = sema.OriginalLexicalContext; + _ci->getSema().CurContext = context; + clang::Parser::DeclGroupPtrTy Result; + while (token.isNot(clang::tok::r_brace) && + !parser->ParseTopLevelDecl(Result)) { + // Tell the ModelBuilder about the new declarations. + sema.getASTConsumer().HandleTopLevelDecl(Result.get()); + } + sema.CurContext = old_context; + sema.OriginalLexicalContext = old_lex_context; + sema.setCurScope(old_scope); + token = saved_token; + _conf.project().removeVirtualFile(vfid); +// cout << "parsing done" << endl; +} + +#if CLANG_VERSION_NUMBER <= VERSION_NUMBER_3_5_2 + clang::FileID ClangIntroducer::inject(llvm::MemoryBuffer *mb, clang::SourceLocation loc, + bool add_eof) { + clang::FileID fid = _ci->getSourceManager() + .createFileID(mb, clang::SrcMgr::C_User, 0, 0, loc); +#else // C++ 11 interface + clang::FileID ClangIntroducer::inject(std::unique_ptr mb, + clang::SourceLocation loc, bool add_eof) { + clang::FileID fid = _ci->getSourceManager() + .createFileID(std::move (mb), clang::SrcMgr::C_User, 0, 0, loc); +#endif +// _ci->getPreprocessor() +// .EnterSourceFile(fid, _ci->getPreprocessor().GetCurDirLookup(), loc); + clang::Preprocessor &PP = _ci->getPreprocessor(); + bool Invalid; + const llvm::MemoryBuffer *buff = _ci->getSourceManager().getBuffer(fid, &Invalid); + if (!Invalid) { // invalid inclusion +// if (string(buff->getBufferIdentifier ()) == "") +// return fid; +// cout << "entered:" << endl; +// cout << buff->getBufferStart() << endl; +// cout << "--- Tokens ..." << endl; + clang::Lexer RawLex(fid, buff, PP.getSourceManager(), PP.getLangOpts()); + RawLex.SetCommentRetentionState(false); + RawLex.setParsingPreprocessorDirective(false); + list tokens; + clang::Token RawToken; + RawLex.LexFromRawLexer(RawToken); + while (RawToken.isNot(clang::tok::eof)) { + if (RawToken.is(clang::tok::hash) && RawToken.isAtStartOfLine()) { + RawLex.setParsingPreprocessorDirective(true); + } + else if (RawToken.is(clang::tok::eod)) { + RawLex.setParsingPreprocessorDirective(false); + } + else if (RawToken.is(clang::tok::raw_identifier)) { + clang::IdentifierInfo *II = PP.getIdentifierInfo(RawToken.getRawIdentifier()); + if (II) { + RawToken.setIdentifierInfo(II); + RawToken.setKind(II->getTokenID()); + } + } + tokens.push_back(RawToken); + RawLex.LexFromRawLexer(RawToken); + } + if (add_eof) { + tokens.push_back(RawToken); + } +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_9_1 + llvm::MutableArrayRef input(new clang::Token[tokens.size()], tokens.size()); + int pos = 0; + for (list::const_iterator i = tokens.begin(); i != tokens.end(); ++i) + input[pos++] = *i; + PP.EnterTokenStream(input, true); +#else + clang::Token *input = new clang::Token[tokens.size()]; + int pos = 0; + for (list::const_iterator i = tokens.begin(); i != tokens.end(); ++i) + input[pos++] = *i; + PP.EnterTokenStream(input, tokens.size(), true, true); +#endif + } +// cout << "--- End" << endl; + return fid; +} + +void ClangIntroducer::class_end (clang::Decl *decl, clang::SourceLocation rbrac) { + clang::TagDecl *td = llvm::dyn_cast(decl); + clang::CXXRecordDecl *record_decl = + llvm::dyn_cast(decl); + clang::SourceManager &sm = _parser->getPreprocessor().getSourceManager(); + clang::SourceLocation CurLoc = rbrac; + ACErrorStream &err = _conf.project().err(); + bool needs_introspection = _conf.introspection(); // --introspection given? + + if (td) { + if (td->getName () == "__TI" || td->getName ().startswith("__TJP")) + return; + + update_base_classes (decl); + + std::deque bufs; + // first check with the plan if there are intros for this class + ACM_Class *jpl = plan_lookup(decl); + if (jpl && jpl->has_plan()) + gen_intros(jpl, bufs, err, td, _conf.introduction_depth()); + + // When we reach here, we're done with this decl. + _classes_with_introduced_members.insert(decl); + + if (!bufs.empty()) { + // Fill in the IntroductionUnit structure. + clang::FileID fid = sm.getFileID(CurLoc); + const llvm::MemoryBuffer *this_unit = sm.getBuffer(fid); + std::vector &intro_units = + get_intros_for(IntroductionUnit::cast(this_unit)); + for (std::deque::iterator i = bufs.begin(), + e = bufs.end(); + i != e; ++i) { + (*i)->target_unit(this_unit); + (*i)->location(CurLoc); + intro_units.push_back(*i); + } + + // Includes may be handled when introducing bases, don't do it twice. + // We add all includes even if we don't add the member for it just yet. + if (!_classes_with_introduced_bases.count(decl)) { + // determine the units that should be included in front of the class + set units; + ACM_ClassPlan *plan = plan_lookup(decl)->get_plan(); + typedef ACM_Container MContainer; + for (MContainer::iterator i = plan->get_member_intros().begin(); + i != plan->get_member_intros().end(); ++i) { + ACM_ClassSlice *cs = get_slice(*(*i)->get_intro()); + units.insert(TI_ClassSlice::of(*cs)->slice_unit()); + } + typedef ACM_Container BContainer; + for (BContainer::iterator i = plan->get_base_intros().begin(); + i != plan->get_base_intros().end(); ++i) { + ACM_ClassSlice *cs = get_slice(*(*i)->get_intro()); + units.insert(TI_ClassSlice::of(*cs)->slice_unit()); + } + + handle_includes(units, sm, _parser, decl, CurLoc, err); + } + } + + for (std::deque::iterator i = bufs.begin(); + i != bufs.end (); i++) { + IntroductionUnit *iu = *i; + + // if needed, generate the introspection code for this introduction + if (iu->jp_needed()) { + std::string introspection = + insert_introspection_code(record_decl, iu->precedence()); + if (!introspection.empty()) { + iu->content (introspection + iu->content ()); + needs_introspection = true; // also generate the final introspection + } + } + + clang::Token &token = (clang::Token &)_parser->getCurToken(); + clang::Token saved_token = token; + + // The closing brace is swallowed by Clang. +#if CLANG_VERSION_NUMBER <= VERSION_NUMBER_3_5_2 + inject(llvm::MemoryBuffer::getMemBuffer(" }", ""), CurLoc); +#else // C++ 11 interface + inject(std::move (llvm::MemoryBuffer::getMemBuffer(" }", "")), CurLoc); +#endif + + // Do the actual injection. + iu->file_id(inject(iu->buffer(), CurLoc)); + + _ci->getPreprocessor ().Lex (token); + _parser->ParseCXXClassBody(decl); + token = saved_token; + } + } + + // insert introspection code for this class if the configuration option + // --introspection was given or the Joinpoint type was used in an introduction + // -> inserted at the end of the class -> all intros are visible + std::string intro_text; + if (needs_introspection) + intro_text = insert_introspection_code(record_decl); + + // If this is the last insertion of a member (or there were no member intros) + // introduce aspectof functions and friend decls. + bool has_aspectof = insert_aspectof_function(intro_text, record_decl); + std::string friends = "\n"; + bool has_friends = insert_aspect_friend_decls(friends, decl); + + if (has_friends) + intro_text += friends; + + if (!intro_text.empty() || has_aspectof || has_friends) { + + clang::FileID fid = sm.getFileID(CurLoc); + const llvm::MemoryBuffer *this_unit = sm.getBuffer(fid); + + // create the new unit for all this stuff + IntroductionUnit *unit = new IntroductionUnit(IntroductionUnit::IU_OTHER); + unit->target_unit(this_unit); + unit->location(CurLoc); + unit->intro (0); // there is no specific introduction that triggered this + unit->content(intro_text); + + // store a pointer to the new intro unit + std::vector &intro_units = + get_intros_for(IntroductionUnit::cast(this_unit)); + intro_units.push_back(unit); + + clang::Token &token = (clang::Token &)_parser->getCurToken(); + clang::Token saved_token = token; + + // The closing brace is swallowed by Clang. + inject(llvm::MemoryBuffer::getMemBuffer(" }", ""), CurLoc); + + // Do the actual injection. + unit->file_id(inject(unit->buffer(), CurLoc)); + + _ci->getPreprocessor ().Lex (token); + _parser->ParseCXXClassBody(decl); + token = saved_token; + } +} + +void ClangIntroducer::introduce_base_classes(clang::Decl *decl, + clang::SourceLocation CurLoc, bool first) { + + // first check with the plan if there are intros for this class + ACM_Class *jpl = plan_lookup (decl); + if (!jpl || !jpl->has_plan ()) { + return; + } + + std::deque bufs; + gen_base_intros (jpl, bufs, !first); + + if (bufs.empty()) + return; + + // Introduce bases only once. + if (!_classes_with_introduced_bases.insert(decl).second) + return; + + string signature = ((clang::TagDecl*)decl)->getNameAsString (); + clang::SourceManager &sm = _parser->getPreprocessor().getSourceManager(); + + set units; + ACM_ClassPlan *plan = jpl->get_plan (); + typedef ACM_Container MContainer; + for (MContainer::iterator i = plan->get_member_intros().begin(); + i != plan->get_member_intros().end(); ++i) { + ACM_ClassSlice *cs = get_slice (*(*i)->get_intro()); + units.insert (TI_ClassSlice::of (*cs)->slice_unit ()); + } + typedef ACM_Container BContainer; + for (BContainer::iterator i = plan->get_base_intros().begin(); + i != plan->get_base_intros().end(); ++i) { + ACM_ClassSlice *cs = get_slice (*(*i)->get_intro()); + units.insert (TI_ClassSlice::of (*cs)->slice_unit ()); + } + + ACErrorStream &err = _conf.project ().err (); + handle_includes(units, sm, _parser, decl, CurLoc, err); + + clang::Token &token = (clang::Token &)_parser->getCurToken(); + clang::Token saved_token = token; + + inject(llvm::MemoryBuffer::getMemBuffer(" {", ""), CurLoc); + + const llvm::MemoryBuffer *target = sm.getBuffer(sm.getFileID(CurLoc)); + for (std::deque::reverse_iterator ui = + bufs.rbegin (); ui != bufs.rend (); ++ui) { + (*ui)->target_unit(target); + (*ui)->location(CurLoc); + (*ui)->file_id (inject ((*ui)->buffer(), CurLoc)); + } + std::vector &intro_units = + get_intros_for(IntroductionUnit::cast(target)); + intro_units.insert(intro_units.end(), bufs.begin(), bufs.end()); + + if (!first) { + // read the comma into the current 'token'. It will be overwritten by ':' + // after the following code injection and 'Lex' call. -> a bit tricky :-) + _ci->getPreprocessor ().Lex (token); + // satisfy ParseBaseClause function: code has to start with ':' + inject(llvm::MemoryBuffer::getMemBuffer(" :", ""), CurLoc); + } + + _ci->getPreprocessor ().Lex (token); + _parser->ParseBaseClause(decl); + + token = saved_token; + return; +} + +void ClangIntroducer::base_specs_end (clang::Decl *decl) { + clang::SourceLocation CurLoc = _parser->getCurToken().getLocation(); + introduce_base_classes(decl, CurLoc, false); +} + +void ClangIntroducer::class_start (clang::Decl *decl, clang::SourceLocation lbrac) { + // first check with the plan if there are intros for this class + clang::RecordDecl *ci = llvm::dyn_cast(decl); + if (!ci) + return; + + // return if this class is not an introduction target + if (!_jpm.is_intro_target (ci)) + return; + + // try to register this class (might be a newly introduced class) + ACM_Class *jpl = _jpm.register_aspect (ci); + if (!jpl) jpl = _jpm.register_class (ci); + if (!jpl) return; + + // store the lbrace location for later; Clang has no method to get it. + TI_Class::of(*jpl)->set_lbrace_loc(lbrac); + + // check and register attributes in the project model + if(_conf.attributes()) + _jpm.handle_attributes(jpl, decl); + + introduce_base_classes(decl, lbrac, true); +} + + +// update the base classes in the project model for a class that had +// base class introductions +void ClangIntroducer::update_base_classes (clang::Decl *decl) { + clang::CXXRecordDecl *rd = llvm::cast(decl); + if (!rd || !_jpm.is_intro_target (decl)) return; + ACM_Class *jpl = _jpm.register_aspect (rd); + if (!jpl) jpl = _jpm.register_class (rd); + if (!jpl) return; + // FIXME: what about the derived-class relation? Will there be duplicates? + jpl->get_bases().clear(); + for (clang::CXXRecordDecl::base_class_iterator I = rd->bases_begin(), + E = rd->bases_end(); + I != E; ++I) { + clang::CXXRecordDecl *base_decl = I->getType ()->getAsCXXRecordDecl (); + assert (base_decl); + // re-register the base class in order to find the model element + ACM_Class *base_jpl = _jpm.register_aspect (base_decl); + if (!base_jpl) base_jpl = _jpm.register_class (base_decl); + if (!base_jpl) continue; + // insert the class into the model + jpl->get_bases().insert(base_jpl); + base_jpl->get_derived().insert(jpl); + // handle this base class recursively + update_base_classes(base_decl); + } +} + +void ClangIntroducer::handle_includes(set &units, + clang::SourceManager &sm, + clang::Parser *parser, clang::Decl *decl, + clang::SourceLocation CurLoc, + ACErrorStream &err) { + clang::FileID fid = sm.getFileID(CurLoc); + const llvm::MemoryBuffer *this_unit = sm.getBuffer(fid); + + // TODO: this_unit might be a macro unit! + // handle introductions into introduced classes (nested introductions) + const IntroductionUnit *intro_unit = IntroductionUnit::cast (this_unit); + if (intro_unit) this_unit = intro_unit->final_target_unit (); + +// cout << "included units for " << ci->QualName () << " in " +// << this_unit->name () << " :" << endl; + for (set::iterator iter = units.begin (); + iter != units.end (); ++iter) { + ACFileID slice_unit = *iter; + if (ACFileID(sm.getFileEntryForID(sm.getMainFileID())) == slice_unit) { +#if 0 + if (this_unit != primary) + err << sev_error << decl->getLocation() + << "affected by aspect in '" << slice_unit.name ().c_str () + << "'. Move the aspect into a separate aspect header." << endMessage; +#endif + } + else if (sm.getFileEntryForID(fid) && + _ig.includes (slice_unit, sm.getFileEntryForID(fid))) { + err << sev_warning << decl->getLocation() + << "can't include '" << slice_unit.name ().c_str () + << "' to avoid include cycle" << endMessage; + } + else { +// cout << "new edge from " << this_unit->name () << " to " +// << slice_unit->name () << endl; + + // handling of nested classes -> search the outermost class + clang::RecordDecl *inscls = llvm::cast(decl); + while (inscls->getLexicalParent()->isRecord()) + inscls = llvm::cast(inscls->getLexicalParent()); + + ACFileID insfile = sm.getFileEntryForID(sm.getFileID(sm.getExpansionLoc(inscls->getLocation()))); + _ig.add_edge (insfile, slice_unit); + + // namespace should be closed and re-opened + ostringstream inc; + _code_weaver.close_namespace (inc, inscls); + + // inspos should be infront of the class + clang::SourceLocation inspos = inscls->getLocStart(); + + // This is what gets parsed. We don't care about namespaces here. + ostringstream includes; + Filename incname = _conf.project ().getRelInclString (insfile.name ().c_str(), slice_unit.name ().c_str()); + includes << endl << "#ifndef "; + Naming::guard (includes, slice_unit); + includes << endl << "#define "; + Naming::guard (includes, slice_unit); + includes << endl; + includes << "#include \"" << incname << "\"" << endl; + includes << "#endif" << endl; + + // re-open the namespace + inc << includes.str(); + _code_weaver.open_namespace (inc, inscls); + + _code_weaver.insert (_code_weaver.weave_pos (inspos, WeavePos::WP_BEFORE), inc.str ()); + + // FIXME: stupid hack. + includes << "}" << endl; + + if (_included_aspect_headers.find (slice_unit) == + _included_aspect_headers.end ()) { + _included_aspect_headers.insert (slice_unit); + + parse(parser, includes.str (), CurLoc); + } +// else +// cout << "'" << slice_unit->name () << "' not included again!" << endl; + } + } +} + +bool ClangIntroducer::end_translation_unit(clang::Parser *parser) { + + bool injection_done = false; + for (std::set::iterator + i = _classes_with_introduced_members.begin(), + e = _classes_with_introduced_members.end(); + i != e; ++i) { + clang::Decl *decl = *i; + + // Introduce members only once. + if (!_classes_with_introduced_non_inlines.insert(decl).second) + continue; + + // first check with the plan if there are intros for this class + ACM_Class *jpl = plan_lookup (decl); + if (!jpl || !jpl->has_plan ()) { + continue; + } + + clang::TagDecl *tag_decl = (clang::TagDecl*)decl; + //const clang::Type* tag_type = tag_decl->getTypeForDecl(); + //string signature = tag_decl->getNameAsString (); + //cout << "END_TU " << signature << " " + // << tag_type->getCanonicalTypeInternal().getAsString() << endl; + + std::deque bufs; + ACErrorStream &err = _conf.project ().err (); + gen_intros (jpl, bufs, err, tag_decl, _conf.introduction_depth (), true); + + if (bufs.empty()) + continue; + + clang::SourceLocation CurLoc = parser->getCurToken().getLocation(); + clang::SourceManager &sm = parser->getPreprocessor().getSourceManager(); + + if (sm.getFileID(tag_decl->getLocation()) != sm.getMainFileID()) { + const clang::Decl *loo = + link_once_object(llvm::dyn_cast(tag_decl)); + if (!loo) + continue; + else if (const clang::DeclContext *dc = + llvm::dyn_cast(loo)) + if (dc->getLexicalParent() == tag_decl) + continue; + // Returned fields are always link once objects. + } + + // determine the units that should be included in front of the intros + set units; + ACM_ClassPlan *plan = jpl->get_plan (); + typedef ACM_Container MContainer; + for (MContainer::iterator i = plan->get_member_intros().begin(); + i != plan->get_member_intros().end(); ++i) { + ACM_ClassSlice *cs = get_slice (*(*i)->get_intro()); + std::vector &member_units = TI_ClassSlice::of(*cs)->non_inline_member_units(); + for (std::vector::iterator i = member_units.begin (); + i != member_units.end (); ++i) + units.insert (*i); + } + + // parse the aspect headers that are needed by this intro + for (set::iterator iter = units.begin (); + iter != units.end (); ++iter) { + ACFileID slice_unit = *iter; + ACFileID primary_unit = ACFileID(sm.getFileEntryForID(sm.getMainFileID())); + if (primary_unit != slice_unit) { +// cout << "new edge from " << primary->name () << " to " +// << slice_unit->name () << endl; + _ig.add_edge (primary_unit, slice_unit); + // generate a unit with the include + ostringstream includes; + Filename incname = _conf.project().getRelInclString(primary_unit.name().c_str (), slice_unit.name().c_str ()); + includes << endl << "#ifndef "; + Naming::guard (includes, slice_unit); + includes << endl << "#define "; + Naming::guard (includes, slice_unit); + includes << endl; + includes << "#include \"" << incname << "\"" << endl; + includes << "#endif" << endl; + string inc (includes.str ()); + _code_weaver.insert( + _code_weaver.weave_pos(CurLoc, WeavePos::WP_BEFORE), inc, true); + + if (_included_aspect_headers.find (slice_unit) == + _included_aspect_headers.end ()) { + _included_aspect_headers.insert (slice_unit); + parse(parser, inc, CurLoc); + } +// else +// cout << "'" << slice_unit->name () << "' not included again!" << endl; + } + } + + clang::FileID fid = sm.getFileID(CurLoc); + const llvm::MemoryBuffer *this_unit = sm.getBuffer(fid); + for (std::deque::reverse_iterator ui = + bufs.rbegin(); + ui != bufs.rend(); ++ui) { + (*ui)->target_unit(this_unit); + (*ui)->location(CurLoc); + (*ui)->file_id(inject((*ui)->buffer(), CurLoc, !injection_done)); + injection_done = true; + } + std::vector &intro_units = + get_intros_for(IntroductionUnit::cast(this_unit)); + intro_units.insert(intro_units.end(), bufs.begin(), bufs.end()); + } + return injection_done; +} + +void ClangIntroducer::tunit_start () { + // handle Clang parser quirks +// Clang < 3.9.1 does not support __float128 type ... +#if CLANG_VERSION_NUMBER < VERSION_NUMBER_3_9_1 + // ... therefore we define the __float128 type by ourself. + // TODO: This does not behave like the real __float128 + string quirks = + "namespace AC { struct __float128 {\n" + " union {\n" + " char _data[128/8];\n" + " double _val;\n" + " };\n" + " __float128 () {}\n" + " __float128 (double d) : _val (d) {}\n" + " operator double () const { return _val; }\n" + " __float128 &operator += (double d) { _val += d; return *this; }\n" + " __float128 &operator -= (double d) { _val -= d; return *this; }\n" + " __float128 &operator *= (double d) { _val *= d; return *this; }\n" + " __float128 &operator /= (double d) { _val /= d; return *this; }\n" + "}; }\ntypedef AC::__float128 __float128;\n}"; + + // parse and inject the code + clang::SourceManager &SM = _ci->getSourceManager (); + clang::SourceLocation quirks_loc = SM.getLocForStartOfFile (SM.getMainFileID()); + parse (_parser, quirks, quirks_loc); +#endif +} + +void ClangIntroducer::tunit_end () { + clang::Token &token = (clang::Token &)_parser->getCurToken(); + clang::Token saved_token = token; + + if (!end_translation_unit(_parser)) { // inject code and parse required headers + return; + } + + _ci->getPreprocessor ().Lex (token); + clang::Parser::DeclGroupPtrTy ADecl; + while (!_parser->ParseTopLevelDecl(ADecl)) { + if (ADecl && !_ci->getASTConsumer().HandleTopLevelDecl(ADecl.get())) + break; + } + token = saved_token; +} + +string substitute_names(const string &text, clang::TagDecl *target, int precedence, + const std::vector > &positions, + bool &jp_needed) { + string result; + typedef TI_ClassSlice::SliceBody member_t; + + // generate names to be inserted at the appropriate positions + std::string target_name = target->getNameAsString(); + std::string target_qual_name = target->getQualifiedNameAsString(); + std::string jp_name = "__TJP_" + llvm::itostr(precedence); + + jp_needed = false; + size_t last_pos = 0; + // The positions are sorted ascending. + for (int pi = 0, pe = positions.size(); pi != pe; ++pi) { + size_t pos = positions[pi].first; + member_t::InsertType type = positions[pi].second; + + result += text.substr(last_pos, pos - last_pos); + switch (type) { + case member_t::TARGET_NAME: + result += target_name; + break; + case member_t::TARGET_QUAL_NAME: + result += target_qual_name; + break; + case member_t::JP_NAME: + result += jp_name; + jp_needed = true; + break; + } + + last_pos = pos; + } + result += text.substr (last_pos); + + return result; +} + +void ClangIntroducer::gen_intros (ACM_Class *jpl, + std::deque &units, + ACErrorStream &err, + clang::TagDecl *target, int introduction_depth, + bool non_inline) const { + typedef TI_ClassSlice::SliceBody member_t; + + // handle all intros + typedef ACM_Container Container; + Container &intros = jpl->get_plan()->get_member_intros(); + int i = 0; + for (Container::iterator iter = intros.begin(); iter != intros.end(); ++iter, ++i) { + ACM_Introduction *ii = (*iter)->get_intro(); + + // TODO: clean up; a lot of duplicated code here + TI_ClassSlice *ti = TI_ClassSlice::of (*get_slice (*ii)); + + // generate non-inline introduction instance + if (ti->non_inline_members ().size () > 0 && non_inline) { + // Format the non-inline members. Everything is tokenized with the required + // elements inserted in the given positions. + std::vector &bodies = ti->non_inline_members (); + for (unsigned body_no = 0; body_no < bodies.size(); ++body_no) { + const member_t &body = bodies[body_no]; + std::string str; // = "\n"; + + // create the new unit + IntroductionUnit *unit = new IntroductionUnit(body_no); + unit->intro (ii); + unit->precedence (i); + + bool jp_needed; + str += substitute_names(body.text, target, i, body.positions, jp_needed); + unit->jp_needed(jp_needed); + + // if there was no introduction, delete the unit -> no result + if (str.empty() || str.find_first_not_of(" \n") == std::string::npos) + delete unit; + // check whether this is a deeply nested introduction + else if (unit->nesting_level () > introduction_depth) { + err << sev_error << target->getLocation() + << "maximum level of nested introductions (" << introduction_depth + << ") for class '" + << target->getQualifiedNameAsString().c_str() << "' exceeded" << endMessage; + err << sev_error + << Location (Filename (filename (*ii).c_str ()), line (*ii)) + << "invalid introduction defined here" << endMessage; + delete unit; + } + else { + unit->content (str); + units.push_back (unit); + } + } + continue; + } + + // create the new unit + IntroductionUnit *unit = new IntroductionUnit(IntroductionUnit::IU_MEMBERS); + //new IntroductionUnit (err, (Unit*)target->Tree ()->token ()->belonging_to ()); + unit->intro (ii); + unit->precedence (i); + std::string str; // = "\n"; + + // generate inline introduction instance + if (!ti->get_tokens().text.empty() && !non_inline) { + // create a unit with the target class name + std::string target_name = target->getNameAsString(); + + std::string slice_start; + if (get_slice(*ii)->get_is_struct()) + slice_start += " public: "; + else + slice_start += " private: "; + // add " typedef ;\n" + if (get_slice(*ii)->get_name()[0] != '<') { + slice_start += "typedef " + target_name + " " + + get_slice(*ii)->get_name() + "; "; + } + str += slice_start; + + const member_t &body = ti->get_tokens (); + bool jp_needed; + str += substitute_names(body.text, target, i, body.positions, jp_needed); + unit->jp_needed(jp_needed); + } + + // if there was no introduction, delete the unit -> no result + if (str.empty() || str.find_first_not_of(" \n") == std::string::npos) + delete unit; + // check whether this is a deeply nested introduction + else if (unit->nesting_level () > introduction_depth) { + err << sev_error << target->getLocation() + << "maximum level of nested introductions (" << introduction_depth + << ") for class '" + << target->getQualifiedNameAsString().c_str() << "' exceeded" << endMessage; + err << sev_error + << Location (Filename (filename (*ii).c_str ()), line (*ii)) + << "invalid introduction defined here" << endMessage; + delete unit; + } + else { + unit->content (str); + units.push_back (unit); + } + } +} + +void ClangIntroducer::gen_base_intros (ACM_Class *jpl, + std::deque &units, + bool commas_only) const { + typedef ACM_Container Container; + Container &bases = jpl->get_plan()->get_base_intros(); + + for (Container::iterator i = bases.begin(); i != bases.end (); ++i) { + // get the current introduction + ACM_Introduction *ii = (*i)->get_intro(); + + // create the new unit + IntroductionUnit *unit = new IntroductionUnit(IntroductionUnit::IU_BASE); + //new IntroductionUnit (err, (Unit*)target->Tree ()->token ()->belonging_to ()); + unit->intro (ii); + + // generate the code for this base class introduction + // FIXME: Line directives. + std::string str; + gen_base_intro (str, ii, (i == bases.begin()) && !commas_only); + + unit->content (str); + + // store the result for the caller + units.push_back (unit); + } +} + +void ClangIntroducer::gen_base_intro (std::string &unit, + ACM_Introduction *ii, bool first) const { + TI_ClassSlice *ti = TI_ClassSlice::of (*get_slice(*ii)); + // generate the code for this entry + unit += (first ? ": " : ", "); + unit += ti->base_intro(); +} + +void ClangIntroducer::function_start (clang::FunctionDecl *decl) { + + // introduce code in front of the function definition +// ClangSyntacticContext fcontext(decl); +// _code_weaver.insert(fcontext.wrapper_pos(_code_weaver), "/* some generated stuff */"); + + // if (decl->getNameAsString() == "f") { +// parse(_parser, "int fparam = 42; }", +// decl->getLocStart(), decl->getLexicalDeclContext()); +// } +} + +void ClangIntroducer::declarator_start (clang::DeclaratorDecl *decl) { + + // introduce code in front of the function definition +// ClangSyntacticContext fcontext(decl); +// _code_weaver.insert(fcontext.wrapper_pos(_code_weaver), "/* some generated stuff */"); +} diff --git a/AspectC++/ClangIntroducer.h b/AspectC++/ClangIntroducer.h new file mode 100644 index 0000000..3721800 --- /dev/null +++ b/AspectC++/ClangIntroducer.h @@ -0,0 +1,194 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __ClangIntroducer_h__ +#define __ClangIntroducer_h__ + +// Class that is used for introductions during a parser run. +// The semantics object has a reference to an Introducer and uses +// the interface at some well defined (join) points. + +//#include "clang/Sema/Sema.h" +#include "ACFileID.h" +#include "ACErrorStream.h" +#include "ACToken.h" +#include "version.h" + +#include "clang/Basic/Version.h" + +#include + +#include "ClangAnnotation.h" +using std::set; +#include +using std::map; +#include + +namespace clang { + class CompilerInstance; + class Parser; + class Decl; + class RecordDecl; + class FunctionDecl; + class TagDecl; + class TemplateDecl; + class TemplateArgument; + class CXXRecordDecl; + class ClassTemplatePartialSpecializationDecl; + class TemplateDecl; + class DeclaratorDecl; +} + +class ACConfig; +class IncludeGraph; +class CodeWeaver; +class ACM_Class; +class ACM_Introduction; +class Plan; +class ModelBuilder; +class ACUnit; +class LineDirectiveMgr; +class IntroductionUnit; +class ClangIntroParser; +class WeavePos; + +class ClangIntroducer { + Plan &_plan; + CodeWeaver &_code_weaver; + ModelBuilder &_jpm; + IncludeGraph &_ig; + ACConfig &_conf; + set _included_aspect_headers; + typedef map ClangTargetMap; + ClangTargetMap _clangtargets; + + // find a member that is/must be link-once (global) code + const clang::Decl *link_once_object (clang::CXXRecordDecl *ci); + + // Various sets used to avoid duplicated intros. + std::set _seen_classes; + std::set _classes_with_introduced_bases; + std::set _classes_with_introduced_members; + std::map > _members_to_introduce; + std::set _classes_with_introduced_non_inlines; + + std::map _original_class_endings; + + // A map of all generated IntroductionUnits. To be used to resolve intros at + // the end. + std::map > _intros; + +public: + // Contructor: every Introducer knows the parser + ClangIntroducer(Plan &pl, CodeWeaver &ccw, ModelBuilder &jpm, + IncludeGraph &ig, ACConfig &c) + : _plan(pl), _code_weaver(ccw), _jpm(jpm), _ig(ig), _conf(c) {} + + // Destructor: release all allocated resources + ~ClangIntroducer (); + + clang::CompilerInstance *_ci; + ClangIntroParser *_parser; + + ModelBuilder &get_model_builder () const { return _jpm; } + + // Parse an include. + void parse (clang::Parser *parser, llvm::StringRef include, + clang::SourceLocation loc, clang::DeclContext *context = 0); + // Inject a buffer into the parser. +#if CLANG_VERSION_NUMBER <= VERSION_NUMBER_3_5_2 + clang::FileID inject(llvm::MemoryBuffer *mb, clang::SourceLocation loc, + bool add_eof = false); +#else // C++ 11 interface + clang::FileID inject(std::unique_ptr mb, + clang::SourceLocation loc, bool add_eof = false); +#endif + + // Clang introducer methods + void tunit_start (); + void base_specs_end (clang::Decl *decl); + void class_start (clang::Decl *decl, clang::SourceLocation lbrac); + void class_end (clang::Decl *decl, clang::SourceLocation rbrac); + void function_start (clang::FunctionDecl *decl); + void declarator_start (clang::DeclaratorDecl *decl); + void tunit_end (); + + virtual bool end_translation_unit(clang::Parser *parser); + + std::vector & + get_intros_for(IntroductionUnit *unit) { + return _intros[unit]; + } + +private: + + // introduce base class into the class referenced by 'decl' + // 'lbrac' is the position of the opening brace of the class body + // iff 'first' is true, the injected code will start with ":" + void introduce_base_classes (clang::Decl *decl, clang::SourceLocation lbrac, + bool first); + + // check in the plan if the current class needs an introduction + ACM_Class *plan_lookup (clang::Decl *ci); + + // create the weaving plan for a given class + ACM_Class *create_plan (clang::Decl *ci); + + // insert introspection code + // * at the end of class definitions, after AspectC++ introductions + // * before a slice, if "precedence" is given + //void insert_introspection_code (Puma::CT_ClassDef *cd, int precedence = -1); + + // insert friend declarations for all aspects + bool insert_aspect_friend_decls (std::string &str, clang::Decl *ci); + + // insert friend declarations for all aspects + bool insert_aspectof_function (std::string &str, clang::CXXRecordDecl *ci); + + // insert introspection code + // * at the end of class definitions, after AspectC++ introductions + // * before a slice, if "precedence" is given + std::string insert_introspection_code(clang::CXXRecordDecl *cd, + int precedence = -1); + + // insert include files from units into the parser + void handle_includes(set &units, clang::SourceManager &sm, + clang::Parser *parser, clang::Decl *decl, + clang::SourceLocation CurLoc, ACErrorStream &err); + + // generate member intros for a given class + void gen_intros (ACM_Class *jpl, + std::deque &units, + ACErrorStream &err, + clang::TagDecl *target, int introduction_depth, + bool non_inline = false) const; + + // generate base class intros for a given class + void gen_base_intros (ACM_Class *jpl, + std::deque &units, + bool commas_only = false) const; + + void gen_base_intro (std::string &unit, + ACM_Introduction *ii, bool first) const; + + // update the base classes in the project model for a class that had + // base class introductions + void update_base_classes (clang::Decl *decl); +}; + +#endif /* __ClangIntroducer_h__ */ diff --git a/AspectC++/ClangModelBuilder.cc b/AspectC++/ClangModelBuilder.cc new file mode 100644 index 0000000..addc346 --- /dev/null +++ b/AspectC++/ClangModelBuilder.cc @@ -0,0 +1,1609 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "ModelBuilder.h" +#include "IntroductionUnit.h" +#include "PointCutContext.h" +#include "PointCutExpr.h" +#include "ACConfig.h" +#include "ACPreprocessor.h" +#include "ACModel/Utils.h" + +// Puma library includes +#include "Puma/SysCall.h" + +#include "clang/AST/Decl.h" +#include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclTemplate.h" +#include "clang/AST/Type.h" +#include +#include "clang/Frontend/CompilerInstance.h" +#include "ClangAnnotation.h" + +// start phase 1 +void ClangModelBuilder::setup_phase1 (const string &tunit_name, int tunit_len) { + _tunit_file = newTUnit(); + _tunit_file->set_filename(model_filename (tunit_name.c_str())); + _tunit_file->set_len(tunit_len); + _tunit_file->set_time(modification_time (tunit_name)); + get_files().insert(_tunit_file); + file_map().insert( + ClangModelBuilder::FileMapPair(model_filename(tunit_name.c_str()), _tunit_file)); + set_root(0); // TODO: to be done by libacmodel + + register_namespace1(0, "::"); + +} + + +void ClangModelBuilder::advice_infos (ACM_Aspect *jpl_aspect) { + // collect the advice nodes + // TODO: change of semantics: the previous version created entries + // for the advice code in both phases. What does that mean? + clang::CXXRecordDecl *cls = + llvm::cast(TI_Aspect::of(*jpl_aspect)->decl()); + + clang::CXXRecordDecl::decl_iterator DI = cls->decls_begin(), + DE = cls->decls_end(); + typedef ACM_Container Container; + Container &advices = jpl_aspect->get_advices(); + for (Container::iterator i = advices.begin (); i != advices.end (); ++i) { + ACM_AdviceCode *advice_code = *i; + + while (DI != DE) { + if (clang::NamedDecl *ND = llvm::dyn_cast(*DI)) + if (llvm::StringRef(ND->getNameAsString()).startswith("__a")) + break; + ++DI; + } + + if (DI == DE) { + // TODO: this should be a fatal error message + cout << "advice cannot be associated with advice function in aspect " << cls->getQualifiedNameAsString() << endl; + return; + } + + clang::Decl *D = *DI++; + // Look through templates. + if (clang::FunctionTemplateDecl *FTD = + llvm::dyn_cast(D)) + D = FTD->getTemplatedDecl(); + + clang::FunctionDecl *FD = llvm::cast(D); + unsigned first_context_arg = 0; + if (FD->getNumParams() > 0 && FD->getParamDecl(0)->getName() == "tjp") + first_context_arg = 1; + + for (unsigned a = first_context_arg; a < FD->getNumParams(); a++) { + advice_code->get_pointcut()->get_args().insert(register_arg( + FD->getParamDecl(a)->getType(), FD->getParamDecl(a)->getName())); + } + + // tree is the tree of the function definition + TI_AdviceCode::of(*advice_code)->decl (FD); + } +} + +static string absolutePath (const char *name) { + Puma::Filename result; + if (!Puma::SysCall::canonical (name, result)) + return string(); + + return result.name (); +} + +string ClangModelBuilder::model_filename (const char *name) { + string fname = absolutePath (name); + if (fname.empty ()) + return fname; + ACProject &prj = _conf.project (); + // if the file does not belong to the project return the absolute path + if (!prj.isBelow (fname.c_str ())) + return fname; + // iterate over all project paths + for (long p = 0; p < prj.numPaths (); p++) { + Puma::Filename dir_abs; + if (!Puma::SysCall::canonical (prj.src (p), dir_abs)) { + assert (false); + return fname; + } + int dir_len = strlen (dir_abs.name ()); + if (strncmp (dir_abs.name (), fname.c_str (), dir_len) == 0) { + return fname.substr(dir_len + 1); + } + } + // the file has to be below any of the directories => fatal error here + // assert (false); acgen.c does not belong to the project with this test + return fname; +} + + +// get the modification time of a file (UNIX Epoch value) +long ClangModelBuilder::modification_time (const string &filename) { + string abs_name = absolutePath (filename.c_str ()); + if (abs_name.empty ()) + return -1; // File does not exists or other error + Puma::FileInfo fileinfo; + if (! Puma::SysCall::stat (abs_name.c_str (), fileinfo)) + return -1; // File does not exists. + return fileinfo.modi_time (); +} + + +bool ClangModelBuilder::inside_template (clang::DeclContext *scope) const { + if (llvm::isa(scope)) + return false; + + if (clang::FunctionDecl *FD = llvm::dyn_cast(scope)) + if (FD->getTemplatedKind() != clang::FunctionDecl::TK_NonTemplate) + return true; + + //if (clang::VarDecl *VD = llvm::dyn_cast(scope)) + // if (VD->getTemplatedKind() != clang::TK_NonTemplate) + // return true; + + if (clang::CXXRecordDecl *RD = llvm::dyn_cast(scope)) + if (RD->getDescribedClassTemplate() || + RD->getTemplateSpecializationKind() == + clang::TSK_ExplicitSpecialization) + return true; + + return inside_template(scope->getParent()); +} + +template +static bool isTemplateInstantiation(T node) { + return (node->getTemplateSpecializationKind() == + clang::TSK_ImplicitInstantiation || + node->getTemplateSpecializationKind() == + clang::TSK_ExplicitInstantiationDefinition); +} + +bool ClangModelBuilder::inside_template_instance (clang::DeclContext *scope) { + if (llvm::isa(scope)) + return false; + + if (clang::FunctionDecl *FD = llvm::dyn_cast(scope)) + if (isTemplateInstantiation(FD)) + return true; + + if (clang::VarDecl *VD = llvm::dyn_cast(scope)) + if (isTemplateInstantiation(VD)) + return true; + + if (clang::CXXRecordDecl *RD = llvm::dyn_cast(scope)) + if (isTemplateInstantiation(RD)) + return true; + + return inside_template_instance(scope->getParent()); +} + +bool ClangModelBuilder::is_valid_model_class (clang::RecordDecl *ci) const { + // Don't consider + // * anonymous classes like template instances(?) + // * the generated class JoinPoint + // * classes defined in the special namespace AC + llvm::StringRef Name = ci->getName(); + std::string QualName = ci->getQualifiedNameAsString(); + if (Name.empty() || + Name.startswith("%") || Name == "JoinPoint" || + Name.startswith("__TJP") || Name == "__TI" || + llvm::StringRef(QualName).startswith("AC::")) + return false; + + // Templates and classes nested in template class are not considered for + // matching, only instances + if (inside_template (ci)) + return false; + + return true; +} + +bool ClangModelBuilder::is_valid_model_function (clang::FunctionDecl *fi) const { + // Don't consider + // * member functions of an invalid class + // * ac++ generated functions + // * pointcuts + + clang::DeclContext *cls = fi->getDeclContext(); + clang::RecordDecl *RD = llvm::dyn_cast(cls); + if (RD && !is_valid_model_class(RD)) + return false; + + if (!fi->isTemplateInstantiation () && inside_template (fi)) + return false; + + std::string S = fi->getNameAsString(); + llvm::StringRef Name = S; + if (Name.startswith("%a") || Name.startswith("__a") || Name == "aspectof" || + Name == "aspectOf" || Name.startswith("__builtin_")) + return false; + + // Explicitly filter the operators added by phase 1. + if ((Name == "operator new" || Name == "operator delete") && + fi->getNumParams() == 2) { + std::string arg_ty = TI_Type::get_type_sig_text(fi->getParamDecl(1)->getType(), &fi->getASTContext(), 0, false); + if (arg_ty == "AC::AnyResultBuffer *") + return false; + } + + // filter-out built-in functions that are neither constructor nor destructor + // + // (We filter out the copy-assignment-operators, because we + // currently do not get all calls of these. Example: + // + // class A {}; + // class B : public A {}; + // + // B b1, b2; + // b1 = b2; // Internally A::operator= gets called here, but currently there + // // is no join-point and therefore no advice for that call.) + // + clang::CXXMethodDecl *method = llvm::dyn_cast(fi); + if (method && !method->isUserProvided() && + /*!method->isCopyAssignmentOperator() &&*/ + !llvm::dyn_cast(fi) && + !llvm::dyn_cast(fi)) + return false; + + return true; +} + +bool ClangModelBuilder::is_valid_model_variable( clang::DeclaratorDecl *vi ) const { + // Don't consider + // * variables in invalid places + // * template instantiations + // * dummy declarations with empty identifier + + clang::DeclContext *ctx = vi->getDeclContext(); + clang::NamespaceDecl *ND = llvm::dyn_cast( ctx ); + clang::RecordDecl *RD = llvm::dyn_cast( ctx ); + clang::FunctionDecl *FD = llvm::dyn_cast( ctx ); + if( ( ND && ! is_valid_model_namespace( ND ) ) + || ( RD && ! is_valid_model_class( RD ) ) + || ( FD && ! is_valid_model_function( FD ) ) + ) + return false; + + if( inside_template( ctx ) ) + return false; + + // dummy declaration + llvm::StringRef Name = vi->getName(); + if( Name.empty() || Name == "" ) //TODO: is "" still correct in clang >= 3.6.2? + return false; + + return true; +} + +bool ClangModelBuilder::is_valid_model_namespace (clang::NamespaceDecl *ni) const { + llvm::StringRef Name = ni->getName(); + // no template instance namespace, but anonymous namespaces! + if ((ni->isAnonymousNamespace() || Name.find('<') == llvm::StringRef::npos) && + Name != "AC" && !Name.startswith("__puma")) + return true; + return false; +} + +bool ClangModelBuilder::is_valid_model_type( const clang::QualType& qual_type ) const { + // Don't consider + // * anonymous/unnamed types + // * local types + // * types with no linkage + // because the C++ Standard (2003) states in chapter 14.3 point 1 and 2: + // "A local type, a type with no linkage, an unnamed type or a type compounded from any of + // these types shall not be used as a template-argument for a template type-parameter." + + return !qual_type->hasUnnamedOrLocalType() + && qual_type->getLinkage() != clang::Linkage::NoLinkage + && qual_type->getLinkage() != clang::Linkage::VisibleNoLinkage; // TODO: really? + + // TODO: An enum type could be treated as a suitable integer type like the following: + // Get the suitable integer type from the operator expression and the argument expressions with: + // clang::QualType qual_type = expression->getType().getCanonicalType(); + // if (const clang::EnumType* enum_type = clang::dyn_cast(qual_type)) { + // clang::QualType promotion_type = enum_type->getDecl()->getPromotionType(); + // if(!promotion_type.isNull()) { + // assert(promotion_type->isIntegerType()); + // if(qual_type->isPointerType()) { + // promotion_type = context.getPointerType(promotion_type); + // } + // // reference type? + // Set the type as the new type of the respective expression: + // expression->setType(promotion_type); + // } + // } + // Make sure that the result type is not deduced and that the non reference version of the + // result type will be inserted in the code +} + +TU_Type *ClangModelBuilder::register_type (clang::QualType ti) { + TU_Type *new_elem = newType(); + new_elem->set_signature( + TI_Type::name(_project.get_compiler_instance()->getASTContext(), ti)); + new_elem->type (ti); + return new_elem; +} + + +TU_Arg *ClangModelBuilder::register_arg (clang::QualType ti, llvm::StringRef name) { + TU_Arg *new_elem = newArg(); + new_elem->set_type( + TI_Type::name(_project.get_compiler_instance()->getASTContext(), ti)); + new_elem->set_name(name); + new_elem->type (ti); + return new_elem; +} + +TU_Attribute *ClangModelBuilder::register_attrdecl1 (ACM_Namespace *parent, const std::string &name) +{ + TU_Attribute *elem = 0; + if (parent) + elem = (TU_Attribute*)map_lookup(*parent, name); + if (!elem || elem->type_val() != JPT_Attribute) { + elem = newAttribute(); + elem->set_name(name); + if(parent->get_name() == "clang" || parent->get_name() == "gnu") + elem->set_builtin(true); + else + elem->set_builtin(false); + if (parent) { + map_insert(*parent, *elem, name); + parent->get_children().insert(elem); + } + } + else { + //for already registered attributes? + elem = 0; + } + + return elem; +} + +// find an attribute declaration +TU_Attribute *ClangModelBuilder::find_attrdecl (const std::vector &qual_name) { + ACM_Name *scope = get_root(); + ACM_Name *found = nullptr; + for (string name : qual_name) { + found = map_lookup(*scope, name); + if (!found) + return nullptr; + scope = found; + } + if (found->type_val() != JPT_Attribute) + return nullptr; + return (TU_Attribute*)found; +} + +ACM_Pointcut *ClangModelBuilder::register_pointcut1 (ACM_Name *parent, const string &name, + bool is_virtual, const string& expr) { + + TU_Pointcut *elem = 0; + if (parent) + elem = (TU_Pointcut*)map_lookup(*parent, name); + if (!elem || elem->type_val() != JPT_Pointcut) { + elem = newPointcut(); + elem->set_name(name); + elem->set_expr (expr); + elem->set_builtin(false); + elem->set_kind(PT_NORMAL); + if (parent) { + if (is_virtual && expr == "0") + elem->set_kind(PT_PURE_VIRTUAL); + else if (is_virtual || overrides_virtual_pointcut(parent, name)) + elem->set_kind(PT_VIRTUAL); + map_insert(*parent, *elem, name); + parent->get_children().insert(elem); + } + } + else { + elem = 0; + } + + return elem; +} + +bool ClangModelBuilder::overrides_virtual_pointcut (ACM_Name *parent, const string &name) { + if (parent->type_val() != JPT_Class && parent->type_val() != JPT_Aspect) + return false; + ACM_Class *cls = (ACM_Class*)parent; + typedef ACM_Container BList; + const BList &blist = cls->get_bases(); + for (BList::const_iterator i = blist.begin (); i != blist.end(); ++i) { + ACM_Class *base = (ACM_Class*)*i; + ACM_Name *elem = map_lookup(*base, name); + if (!elem || elem->type_val() != JPT_Pointcut) + continue; + ACM_Pointcut *base_pct = (ACM_Pointcut*)elem; + if (base_pct->get_kind() == PT_PURE_VIRTUAL || + base_pct->get_kind() == PT_VIRTUAL || + overrides_virtual_pointcut (base, name)) + return true; + } + return false; +} + + +TU_Pointcut *ClangModelBuilder::register_pointcut (clang::FunctionDecl *fi, + ACM_Name *parent) { + + clang::FunctionDecl *def = fi; + + // find the parent model element + if (!parent) + return 0; + + // build the name of the function + string name = fi->getNameAsString(); + + TU_Pointcut *elem = (TU_Pointcut*)map_lookup(*parent, name); + if (!elem || elem->type_val() != JPT_Pointcut) + return 0; + + elem->get_args().clear(); + // argument types are the types of the function declaration + for (clang::FunctionDecl::param_iterator i = fi->param_begin(), + e = fi->param_end(); i != e; ++i) { + elem->get_args().insert(register_arg((*i)->getType(), (*i)->getName())); + } + elem->decl (def); + add_source_loc (elem, def); + + return elem; +} + +TU_Function *ClangModelBuilder::register_function (clang::FunctionDecl *fi, + ACM_Name *parent) { + if (!is_valid_model_function (fi)) + return 0; + + clang::FunctionDecl *def = fi; + + // find the parent model element + if( !parent && ! ( parent = register_scope( static_cast( def ) ) ) ) // explicit cast necessary to chose function (both should be equivalent, using old codepath) + return 0; + + // build the name of the function for lookup + std::string sig = TI_Function::signature(def); + + clang::CXXMethodDecl *method = llvm::dyn_cast(def); + bool isStatic = fi->getStorageClass() == clang::SC_Static; + bool isStaticMethod = method && method->isStatic(); + + // register the element + TU_Function *elem = (TU_Function*)map_lookup(*parent, sig); + bool hidden_function = (elem && elem->type_val() == JPT_Function && + ((isStatic && !isStaticMethod) && + (!elem->has_static_in () || elem->get_static_in () != _tunit_file))); + if (!elem || hidden_function) { + elem = newFunction(); + elem->set_name(TI_Function::name(fi)); + if (isStatic && !isStaticMethod) + elem->set_static_in (_tunit_file); + map_insert(*parent, *elem, sig); + parent->get_children().insert(elem); + FunctionType ft = FT_NON_MEMBER; + if (llvm::isa(fi)) + ft = FT_CONSTRUCTOR; + else if (llvm::isa(fi)) { + if (method->isVirtual() && method->isPure()) + ft = FT_PURE_VIRTUAL_DESTRUCTOR; + else if (method->isVirtual()) + ft = FT_VIRTUAL_DESTRUCTOR; + else + ft = FT_DESTRUCTOR; + } + else if (method) { + if (isStaticMethod) + ft = FT_STATIC_MEMBER; + else if (method->isVirtual() && method->isPure()) + ft = FT_PURE_VIRTUAL_MEMBER; + else if (method->isVirtual()) + ft = FT_VIRTUAL_MEMBER; + else + ft = FT_MEMBER; + } + else { + if (isStatic) + ft = FT_STATIC_NON_MEMBER; + } + elem->set_kind (ft); + elem->set_builtin (method && !method->isUserProvided()); + CVQualifiers cvq = CVQ_NONE; + if (method && method->isConst()) + cvq = (CVQualifiers)(cvq | CVQ_CONST); + if (method && method->isVolatile()) + cvq = (CVQualifiers)(cvq | CVQ_VOLATILE); + elem->set_cv_qualifiers(cvq); + elem->decl (def); + + // TODO: We forget the arg type from arg 0. They will be deleted by jpm. + elem->get_arg_types().clear(); + if (!llvm::isa(def) && + !llvm::isa(def)) { + clang::QualType rtype = fi->getReturnType(); + elem->set_result_type(register_type(rtype)); + } + elem->set_variadic_args(fi->isVariadic()); + for (clang::FunctionDecl::param_iterator i = fi->param_begin(), + e = fi->param_end(); i != e; ++i) { + clang::QualType ty = + fi->getASTContext().getSignatureParameterType((*i)->getType()); + elem->get_arg_types().insert(register_type(ty)); + } + clang::SourceManager &sm = _project.get_compiler_instance()->getSourceManager(); + clang::PresumedLoc PL = sm.getPresumedLoc(fi->getLocation()); + llvm::StringRef Name = PL.getFilename(); + llvm::StringRef BufferName = sm.getBufferName(fi->getLocation()); + if (!elem->get_builtin() && + (!method || !(method->isVirtual() && method->isPure())) && + !(inside_template_instance (fi)) && + (BufferName.startswith("(def)) + register_construction (elem); + else if (llvm::isa(def)) + register_destruction (elem); + else + register_execution (elem); + + // constructors and and destructors cannot be called + if (!llvm::isa(def) && + !llvm::isa(def)) { + // register a 'pseudo call join point' + register_call (def, 0, 0, 0); + } + } + } + else { + // make sure that elem->func_info() will be the DefObject + //if (fi == def) + //elem->func_info(def); + } + + // update the list of source locations + add_source_loc (elem, fi, + fi->isThisDeclarationADefinition () ? SLK_DEF : SLK_DECL); + return elem; +} + +TU_Variable *ClangModelBuilder::register_variable( clang::DeclaratorDecl *oi, ACM_Name *parent ) { + if( ! is_valid_model_variable( oi ) ) + return 0; + + clang::DeclaratorDecl *def = oi; + clang::VarDecl *VD = llvm::dyn_cast( oi ); + clang::FieldDecl * FD = llvm::dyn_cast( oi ); + + // check if we have a valid definition, might be another type of entity used in member exprs + if( ! VD && ! FD ) + return 0; + + // find the parent model element + if (!parent && !(parent = register_scope (def))) + return 0; + + // ignore bitfields + if( FD && FD->isBitField() ) + return 0; + + // ignore incomplete arrays + if ( oi->getType().getTypePtr()->isIncompleteArrayType() ) + return 0; + + // get the name of the variable + string sig = def->getNameAsString();//TI_Variable::name (def); + + // register the element + // TODO: classes and variables in the same scope may have the same name! + // This might lead to invalid results here. + TU_Variable *elem = (TU_Variable*)map_lookup(*parent, sig); + if (!elem || elem->type_val() != JPT_Variable) { + elem = newVariable (); + + elem->set_name(sig); + elem->set_builtin(false); + + TU_Type *var_type = register_type(oi->getType ()); + elem->set_type(var_type); + + bool isGlobal = VD && ( VD->isFileVarDecl() && ! VD->isStaticDataMember() ); + bool isMember = FD || ( VD && VD->isStaticDataMember() ); + bool isStatic = VD && ( VD->getStorageClass() == clang::SC_Static ); + if( isGlobal ) { + if( isStatic ) + elem->set_kind( VT_STATIC_NON_MEMBER ); + else + elem->set_kind( VT_NON_MEMBER ); + } + else if( isMember ) + if( isStatic ) + elem->set_kind( VT_STATIC_MEMBER ); + else + elem->set_kind( VT_MEMBER ); + else + elem->set_kind( VT_UNKNOWN ); + + elem->decl(def); + map_insert(*parent, *elem, sig); + parent->get_children().insert(elem); + } + + bool isDef = ( VD && VD->isThisDeclarationADefinition() ) || FD; + add_source_loc( elem, oi, isDef ? SLK_DEF : SLK_DECL ); + + return elem; +} + +ACM_ClassSlice *ClangModelBuilder::register_class_slice (ACM_Name *scope, string name, + bool is_struct) { + + ACM_Name *found = map_lookup(*scope, name); + if (found && found->type_val() == JPT_ClassSlice) + return (ACM_ClassSlice*)found; + + ACM_ClassSlice *new_elem = (ACM_ClassSlice*)newClassSlice(); + new_elem->set_name(name); + new_elem->set_builtin(false); + new_elem->set_is_struct(is_struct); + map_insert(*scope, *new_elem, name); + scope->get_children().insert(new_elem); + return new_elem; +} + + +ACM_Class * ClangModelBuilder::register_class1 (ACM_Name *scope, string name, bool in_project) { + ACM_Name *found = map_lookup(*scope, name); + if (found && found->type_val() == JPT_Class) + return (TU_Class*)found; + ACM_Class *new_elem = newClass(); + new_elem->set_name(name); + new_elem->set_builtin(false); + if (!in_project) new_elem->get_tunits().insert (_tunit_file); + new_elem->set_intro_target(in_project); + scope->get_children().insert(new_elem); + map_insert(*scope, *new_elem, name); + return new_elem; +} + +void ClangModelBuilder::register_constructor_and_destructor (clang::RecordDecl *ci, + ACM_Class *elem) { + + if (!ci->isThisDeclarationADefinition()) + return; + + // For Clang we create fake constructor and destructor decls in case they + // aren't already there. Clang only adds implicitly defined members to the AST + // but we need all implicitly declared ones in the model + if (clang::CXXRecordDecl *rec = llvm::dyn_cast(ci)) { + std::string name = rec->getNameAsString(); + if (rec->hasSimpleDestructor()) { + std::string full_name = '~' + name + "()"; + if (!map_lookup(*elem, full_name)) { + TU_Function *new_func = newFunction(); + new_func->set_name('~' + name); + map_insert(*elem, *new_func, full_name); + elem->get_children().insert(new_func); + new_func->set_variadic_args(false); + new_func->set_kind(FT_DESTRUCTOR); + new_func->set_builtin(true); + new_func->set_cv_qualifiers(CVQ_NONE); + new_func->decl(0); + if (!isTemplateInstantiation(rec)) + register_destruction(new_func); + } + } + if (!rec->hasUserDeclaredConstructor()) { + std::string full_name = name + "()"; + if (!map_lookup(*elem, full_name)) { + TU_Function *new_func = newFunction(); + new_func->set_name(name); + map_insert(*elem, *new_func, full_name); + elem->get_children().insert(new_func); + new_func->set_variadic_args(false); + new_func->set_kind(FT_CONSTRUCTOR); + new_func->set_builtin(true); + new_func->set_cv_qualifiers(CVQ_NONE); + new_func->decl(0); + if (!isTemplateInstantiation(rec)) + register_construction(new_func); + } + } + if (!rec->hasUserDeclaredCopyConstructor()) { + clang::ASTContext &Context = ci->getASTContext(); + clang::QualType ClassType = Context.getTypeDeclType(rec); + clang::QualType ArgType = ClassType; + if (rec->hasCopyConstructorWithConstParam()) + ArgType = ArgType.withConst(); + ArgType = Context.getLValueReferenceType(ArgType); + std::string full_name = + name + "(" + TI_Type::get_type_sig_text(ArgType, &Context, 0, true) + ")"; + if (!map_lookup(*elem, full_name)) { + TU_Function *new_func = newFunction(); + new_func->set_name(name); + map_insert(*elem, *new_func, full_name); + elem->get_children().insert(new_func); + new_func->get_arg_types().insert(register_type(ArgType)); + new_func->set_variadic_args(false); + new_func->set_kind(FT_CONSTRUCTOR); + new_func->set_builtin(true); + new_func->set_cv_qualifiers(CVQ_NONE); + new_func->decl(0); + if (!isTemplateInstantiation(rec)) + register_construction(new_func); + } + } + } +} + + +TU_Class *ClangModelBuilder::register_class (clang::RecordDecl *ci, + ACM_Name *parent, bool set_source) { + + // only classes are relevant + if (!is_valid_model_class (ci)) + return 0; + + // find the parent model element + if (!parent && !(parent = register_scope (ci))) + return 0; + + string name_with_template_args = TI_Class::name (ci); + assert(!name_with_template_args.empty()); + + TU_Class *elem = 0; + ACM_Name *found = map_lookup(*parent, name_with_template_args); + if (!found || found->type_val() != JPT_Class) { + elem = (TU_Class*)newClass(); + elem->set_name(name_with_template_args); + elem->set_builtin(false); + parent->get_children().insert(elem); + map_insert(*parent, *elem, name_with_template_args); + bool intro_target = is_intro_target (ci); + elem->set_intro_target (intro_target); + if (!intro_target) elem->get_tunits().insert (_tunit_file); + } + else + elem = (TU_Class*)found; + // set the class attributes + if (ci->isThisDeclarationADefinition ()) + elem->decl (ci); + if (set_source && elem->type_val () != JPT_Aspect) { + // FIXME: Is this right? + if (!inside_template_instance(ci)) + add_source_loc (elem, ci, + ci->isThisDeclarationADefinition () ? SLK_DEF : SLK_DECL); + } + + register_constructor_and_destructor (ci, elem); + return elem; +} + +ACM_Aspect * ClangModelBuilder::register_aspect1 (ACM_Name *scope, string name, bool in_project) { + ACM_Name *found = map_lookup(*scope, name); + if (found && found->type_val() == JPT_Aspect) + return (TU_Aspect*)found; + ACM_Aspect *new_elem = newAspect(); + new_elem->set_name(name); + new_elem->set_builtin(false); + if (!in_project) new_elem->get_tunits().insert (_tunit_file); + new_elem->set_intro_target(in_project); + scope->get_children().insert(new_elem); + map_insert(*scope, *new_elem, name); + return new_elem; +} + + +TU_Aspect *ClangModelBuilder::register_aspect (clang::RecordDecl *ci, ACM_Name *parent) { + // only classes are relevant + if (!is_valid_model_class (ci)) + return 0; + + // find the parent model element + if (!parent && !(parent = register_scope (ci))) + return 0; + + string name = ci->getName(); + TU_Aspect *elem = 0; + ACM_Name *found = map_lookup(*parent, name); + if (!found || found->type_val() != JPT_Aspect) + return 0; + elem = (TU_Aspect*)found; + + // set the aspect attributes + elem->decl (ci); + + register_constructor_and_destructor (ci, elem); + return elem; +} + + +bool ClangModelBuilder::is_intro_target (clang::Decl *decl) const { + clang::SourceManager &SM = _project.get_compiler_instance()->getSourceManager(); + const llvm::MemoryBuffer *buf = SM.getBuffer(SM.getFileID(decl->getLocation())); + if (IntroductionUnit::cast(buf)) + return true; + + // FIXME: Templates. + clang::PresumedLoc PL = SM.getPresumedLoc(decl->getLocation()); + llvm::StringRef Name = PL.getFilename(); + return !Name.empty() && get_project().isBelow(Name.str().c_str()); +} + + +ACM_Namespace * ClangModelBuilder::register_namespace1 (ACM_Name *scope, string name, bool in_project) { + ACM_Namespace *result = 0; + assert(scope || name == "::"); + ACM_Name *found = (scope ? map_lookup(*scope, name) : get_root()); + if (!found || found->type_val() != JPT_Namespace) { + result = newNamespace(); + result->set_name(name); + result->set_builtin(false); + if (!in_project) result->get_tunits().insert (_tunit_file); + if (scope) { + scope->get_children().insert(result); + map_insert(*scope, *result, name); + } + else { + set_root(result); + } + } + else + result = (TU_Namespace*)found; + return result; +} + + +TU_Namespace *ClangModelBuilder::register_namespace (clang::NamespaceDecl *n, + ACM_Name *parent) { + // not all Puma namespaces should be registered + if (!is_valid_model_namespace (n)) + return 0; + + // find the parent model element + if (!parent && /*!n->GlobalScope () &&*/ !(parent = register_scope (n))) + return 0; + + TU_Namespace *new_elem = 0; + if (!parent) { + if (get_root()) + return (TU_Namespace*)get_root(); + new_elem = newNamespace(); + new_elem->set_name("::"); + new_elem->set_builtin(true); + set_root(new_elem); + } + else { + // Use for Puma compatibility. + string name = + n->isAnonymousNamespace() ? "" : n->getNameAsString(); + ACM_Name *found = map_lookup(*parent, name); + if (found && found->type_val() == JPT_Namespace) + return (TU_Namespace*)found; + new_elem = newNamespace(); + new_elem->set_name(name); + new_elem->set_builtin(false); + parent->get_children().insert(new_elem); + map_insert(*parent, *new_elem, name); + } + + // set namespace attributes + new_elem->decl (n); + if (new_elem != get_root ()) + add_source_loc (new_elem, n); + return new_elem; +} + +// This method creates a new built-in operator-"pseudo"-function and a call +// of this function and registers both in the AspectC++-join-point-model. +TU_Builtin* ClangModelBuilder::register_builtin_operator_call(clang::Expr* built_in_operator, clang::DeclaratorDecl* lexical_parent_decl, const int local_id) { + // This should not get called with a null-pointer: + assert(built_in_operator > 0 && lexical_parent_decl > 0); + + // check if joinpoints for builtin-operators are wanted + if( ! _conf.builtin_operators() ) + return 0; + + // Check for a built-in operator expression type: + if( ! TI_Builtin::is_builtin_operator( built_in_operator ) ) + return 0; + + // Check if this is an attempt to insert an operator multiple times. + // TODO: This check only works, if this member function is called with the same operator consecutively. + // Maybe something like a SmallPtrSet is necessary. + static clang::Expr* last_inserted_operator = 0; + if(last_inserted_operator == built_in_operator) { + return 0; + } + else { + last_inserted_operator = built_in_operator; + } + + + // Analyze the lexical-parent-decl. If it is valid, then get the appropriate AspectC++-model-element: + ACM_Name* lexical_model_parent = 0; + clang::FunctionDecl* lexical_parent_function_decl = clang::dyn_cast(lexical_parent_decl); + clang::VarDecl* lexical_parent_var_decl = clang::dyn_cast(lexical_parent_decl); + if( lexical_parent_function_decl ) { + // Is this function no template-function(TODO: see TODO in register_call)? + if( lexical_parent_function_decl->isTemplateInstantiation() ) + return 0; + + lexical_model_parent = register_function( lexical_parent_function_decl ); // register_function checks for valid model function + } + else if( lexical_parent_var_decl ) + lexical_model_parent = register_variable( lexical_parent_var_decl ); + + // Is there a valid lexical parent? + if( ! lexical_model_parent ) + return 0; + + // Cache the AST-context: + clang::ASTContext& AST_context = _project.get_compiler_instance()->getASTContext(); // can not have "const"-qualifier, because of + // Expr::isConstantInitializer(...) (but it seems + // that there is no reason why the ASTContext-argument + // does not have the "const"-qualifier) + // Cache the operator-kind as std::string: + const std::string operator_kind_string = TI_Builtin::operator_kind_string( built_in_operator ); + + // If the operator is in a constant expression (e.g. "2 + 5" in "static char foo[2 + 5];"), we can not weave because we would destroy the + // constancy. Do not consider this joinpoint in this case: + // (This is no big disadvantage, because normally the constant expression will be folded by the compiler and therefore the operator is + // not available at runtime anyway.) + // (See C++-standard chapter 5.19 (Constant expressions [expr.const]) and http://lists.cs.uiuc.edu/pipermail/cfe-dev/2012-May/021549.html + // (Clang Front End for LLVM Developers' List)) + // TODO: In some cases there is no problem with destroying the constancy. + // TODO: If C++1y or later is used, we could analyze the advice-Code to determine whether the call-wrapper could get the constexpr specifier. + if( built_in_operator->isConstantInitializer( AST_context, false ) ) + return 0; + + // If the operator refers to a bit-field (e.g. if the first argument of an assignment- or increment-/decrement-operator is a bit-field), we can + // not get a reference to this bit-field, because the C++-standard forbids it: "The address-of operator & shall not be applied to a bit-field, + // so there are no pointers to bit-fields. A non-const reference shall not be bound to a bit-field (8.5.3)." (see C++-standard chapter + // 9.6 (Bit-fields [class.bit]) point 3 for more information) + // The implementation of Expr::getSourceBitfield in Clang 3.4 misses the case of the unary prefix increment/decrement operator (see + // https://web.archive.org/web/20140819102610/http://clang.llvm.org/doxygen/Expr_8cpp_source.html#l03247 vs. + // http://clang.llvm.org/doxygen/Expr_8cpp_source.html#l03351). Therefore we handle this case below together with the other special + // cases of the unary operator. Additionally Expr::getSourceBitfield in Clang 3.5 misses the case of the unary postfix increment/decrement operator. + // Only consider this join-point if there are no references to a bitfield: + if( built_in_operator->getSourceBitField() ) + return 0; + + // Name of the operators as string: + const std::string operator_name = "operator " + operator_kind_string; + + // Debug-output: + //cout << "operator-name: " << operator_name << endl; + + // Determine the suitable return-type: + clang::QualType operator_result_type = TI_Builtin::result_type(built_in_operator, AST_context); + + // Check if the result type is valid (e.g. unnamed types are not valid) + if(!is_valid_model_type(operator_result_type)) { + return 0; + } + + // Special cases: + if( clang::UnaryOperator* unary_operator = llvm::dyn_cast( built_in_operator ) ) { + // Unary operator: + + // Because Expr::getSourceBitField() misses min. one of this cases, we check for it here. (see above for more information) + if(unary_operator->isIncrementDecrementOp() == true && unary_operator->getSubExpr()->getSourceBitField() > 0) + return 0; // Do not consider this join-point + + // Check whether the operator-kind is address-of and the return-type is a member-(function-)-pointer-type: + if( operator_kind_string == "&" && operator_result_type->isMemberPointerType() ) + // We can not weave at unary address-of-operators on member-(function-)pointers, because these types do not exist as a + // non-pointer-type (as type of a variable) + return 0; // Do not consider this join-point + } + + // Check whether this is a pointer-to-member-operator that works on member-functions (instead of "normal" data members): + if( ( operator_kind_string == ".*" || operator_kind_string == "->*" ) && + TI_Builtin::arg_type( built_in_operator, AST_context, 1 )->isMemberFunctionPointerType() ) + // or: if(... && result_type_as_string == "") + // The C++-standard states in chapter 5.5 (Pointer-to-member operators [expr.mptr.oper]) point 6: + // "If the result of .* or ->* is a function, then that result can be used only as the operand for the function call operator ()." + // Because of that we can not cache the result of the ".*"- oder "->*"-Operator ==> we can not weave at this join-point: + return 0; // Do not consider this join-point + + // Operator-signature (the resulttype is not necessary): + std::string operator_signature = operator_name + "("; + // Check the argument types and if they are valid, then add them to the operator-signature: + unsigned argnum = TI_Builtin::arg_count( built_in_operator ); + for( unsigned a = 0; a < argnum; a++ ) { + clang::QualType curr_arg_type = TI_Builtin::arg_type( built_in_operator, AST_context, a ); + if(!is_valid_model_type(curr_arg_type)){ + return 0; + } + operator_signature += ( ( a != 0 ) ? "," : "" ) + TI_Type::get_type_sig_text(curr_arg_type, &AST_context, 0, true); + } + operator_signature += ")"; + + // Debug-output: + //cout << "operator-full-signature: " << operator_result_type.getAsString(AST_context.getPrintingPolicy()) << " " << operator_signature << endl; + + // Root-namespace: + ACM_Namespace* root_namespace = get_root(); + + // Does the pseudo-operator-function already exist in the AspectC++-model? + TU_Function* model_operator_function = (TU_Function*)map_lookup(*root_namespace, operator_signature); + if( ! model_operator_function ) { + // Create the pseudo-operator-function: + model_operator_function = newFunction(); + + // Name of the function: + model_operator_function->set_name(operator_name); + + // Insert the function into the lookup-map: + map_insert(*root_namespace, *model_operator_function, operator_signature); + + // Set attributes of the function: + model_operator_function->set_variadic_args(false); // No variable argument-count + model_operator_function->set_kind(FT_NON_MEMBER); // No member, because in global scope + model_operator_function->set_builtin(true); // Built-in + model_operator_function->set_cv_qualifiers(CVQ_NONE); // Neither const nor volatile, because built-in operators are no member-functions + + // Add operator-arguments: + ACM_Container& model_operator_function_arg_types = model_operator_function->get_arg_types(); // Caching + model_operator_function_arg_types.clear(); // Delete arguments + for( unsigned a = 0; a < argnum; a++ ) + model_operator_function_arg_types.insert( register_type( TI_Builtin::arg_type( built_in_operator, AST_context, a ).getCanonicalType() ) ); + + model_operator_function->set_result_type(register_type(operator_result_type)); // Set return-type + model_operator_function->decl(0); // No pointer to operator-declaration, because the operator is built-in + + // Insert the function into the model as children of the root-namespace-node: + root_namespace->get_children().insert(model_operator_function); + + // Mark the function as 'used' by this translation unit, + // to (hopefully) avoid garbage collection on xml-model merge + model_operator_function->get_tunits ().insert (_tunit_file); + } + + // Create the operator-call: + TU_Builtin *model_operator_call = newBuiltin(); + model_operator_call->set_target(model_operator_function); + model_operator_call->set_lid(local_id); + model_operator_call->tree_node(built_in_operator); + model_operator_call->origin(lexical_parent_decl); + + // Add the source-location: + add_source_loc(model_operator_call, built_in_operator->getLocStart(), built_in_operator->getLocEnd(), SLK_NONE); + + // Insert the operator-call into the model as children of the lexical-model-parent-node: + lexical_model_parent->get_children().insert(model_operator_call); + + // Return the new operator-call: + return model_operator_call; +} + +ACM_Access *ClangModelBuilder::register_call (clang::FunctionDecl *called, + clang::CallExpr *call_node, clang::DeclaratorDecl *caller, int local_id) { + + clang::FunctionDecl *fd_caller = 0; + clang::VarDecl *vd_caller = 0; + + if (caller) { + fd_caller = clang::dyn_cast(caller); + if (fd_caller && fd_caller->isTemplateInstantiation ()) + // TODO: call joinpoint located in template instance silently ignored here + return 0; + vd_caller = clang::dyn_cast(caller); + } + + // what is the lexical scope of this call? + ACM_Name *lexical = 0; + if (!caller) { + lexical = 0; // a pseudo call join point + } + else if (fd_caller) { + // TODO: better cache the JPL object of the current function + ACM_Any *loc = register_function (fd_caller, 0); + if (!loc) { + // TODO: calls in advice code are silently ignored here at the moment +// _err << sev_error << call_node->token ()->location () +// << "location of function call invalid" << endMessage; + return 0; + } + lexical = (ACM_Name*)loc; + } + else { + lexical = register_variable (vd_caller); + if (!lexical) { + _err << Puma::sev_warning << call_node->getLocStart () + << "location of function call invalid" << Puma::endMessage; + return 0; + } + } + + // call using function pointer or function reference: add callref node + if (!called) { + assert (call_node); + + if (llvm::dyn_cast(call_node)) { + // In a C++ template, this expression node kind will be used whenever any + // of the arguments are type-dependent. + // Thus, this expression does not represent a callref node. + return 0; + } + + ACM_CallRef *new_elem = newCallRef(); + new_elem->set_lid(local_id); + + add_source_loc (new_elem, call_node); + // set the parent in the join point model structure + if (lexical) { // pseudo-calls are invisible + lexical->get_children().insert(new_elem); + } + + clang::QualType type( call_node->getCallee()->IgnoreParenImpCasts()->getType().getCanonicalType() ); + if (type->isFunctionPointerType()) + type = type->getPointeeType(); + + //TODO: get correct type for member-function pointers, + // e.g., by clang::Expr::findBoundMemberType( ... ) or similar + //TODO: new_elem->set_target_class( ... ) for member member-function pointers + + // additionally set the reference type + TU_Type *ref_type = register_type( type ); + new_elem->set_type( ref_type ); + + return new_elem; + } + + // find the called function in the join point model + ACM_Function *called_func = register_function (called); + if (!called_func) { +// if a called function is, for instance, a member of a local class, it is +// perfectly valid that we don't find it in the model -> ignore call join-point +// _err << sev_error << "called function \'" << called->QualName () +// << "\' not found in join point model" << endMessage; + return 0; + } + + TU_MethodCall *new_elem = newCall(); + new_elem->set_target(called_func); + called_func->get_calls().insert(new_elem); + new_elem->set_lid(local_id); + new_elem->called (called); + new_elem->origin (caller); + new_elem->tree_node( call_node ); + + // perform static analyses + if ( _conf.flow_analysis() ) { + unsigned int basic_block_id = _flow_analysis.get_block_lid(caller, call_node); + if (_flow_analysis.valid()) { + new_elem->set_cfg_block_lid(basic_block_id); + } + unsigned int target_obj_lid = _flow_analysis.get_target_obj_lid(caller, call_node); + if (_flow_analysis.valid() && target_obj_lid != ClangFlowAnalysis::NO_ID) { + new_elem->set_target_object_lid(target_obj_lid); + } + } + + if (call_node) + add_source_loc (new_elem, call_node); + // set the parent in the join point model structure + if (lexical) { // pseudo-calls are invisible + lexical->get_children().insert(new_elem); + } + + // For functions with default arguments, not more than the number of args + // in the call expression is used. + if (call_node && (new_elem->is_call_op() || + !clang::dyn_cast (call_node))) { + // argument types are the types from the target function declaration + unsigned args = called->getNumParams (); + unsigned call_args = call_node->getNumArgs (); + unsigned given; + for (given = 0; given < call_args; given++) { + clang::Expr *arg = call_node->getArg (given); + if (clang::dyn_cast (arg)) + break; + } + // call operator calls always have the object as argument 0 => substract one + if (new_elem->is_call_op()) + given--; + if (called->isVariadic ()) { + for (unsigned a = args; a < call_args; a++) { + clang::QualType arg_type = call_node->getArg (a)->getType (); + new_elem->get_variadic_arg_types().insert(register_type (arg_type)); + } + } + else if (given < args) { + new_elem->set_default_args(args - given); + } + } + + // analyze the target object type of this call + if (call_node) { + clang::RecordDecl *rd = (clang::RecordDecl *)new_elem->target_class(); + if (rd) { + ACM_Class *target_class = register_aspect(rd); + if (!target_class) target_class = register_class (rd); + assert (target_class); + new_elem->set_target_class(target_class); + } + } + + return new_elem; +} + +ACM_Access *ClangModelBuilder::register_get( VarAccessInfo &var, JoinpointContext& context, TU_Builtin *var_src ) { + // check if data-based joinpoints are wanted + if( ! _conf.data_joinpoints() ) + return 0; + + // regen model information if not given + if( ! var.element && var.decl ) + var.element = register_variable( var.decl ); + + // dont create joinpoint in functions that where left out of the model + if( ! context.parent ) + return 0; + + // generate node + if( var.element ) { + TU_Get *new_elem = newGet(); + fillAccessNode( new_elem, var, context, var_src ); + + return new_elem; + } + else { + TU_GetRef *new_elem = newGetRef(); + fillRefAccessNode( new_elem, var, context ); + + return new_elem; + } +} + +ACM_Access *ClangModelBuilder::register_set( VarAccessInfo &var, JoinpointContext& context, TU_Builtin *var_src ) { + // check if data-based joinpoints are wanted + if( ! _conf.data_joinpoints() ) + return 0; + + // regen model information if not given + if( ! var.element && var.decl ) + var.element = register_variable( var.decl ); + + // dont create joinpoint in functions that where left out of the model + if( ! context.parent ) + return 0; + + // generate node + if( var.element ) { + TU_Set *new_elem = newSet(); + fillAccessNode( new_elem, var, context, var_src ); + + return new_elem; + } + else { + TU_SetRef *new_elem = newSetRef(); + fillRefAccessNode( new_elem, var, context ); + + return new_elem; + } +} + +TU_Ref *ClangModelBuilder::register_ref( VarAccessInfo &var, JoinpointContext& context, TU_Builtin *var_src ) { + // check if data-based joinpoints are wanted + if( ! _conf.data_joinpoints() ) + return 0; + + // regen model information if not given + if( ! var.element ) + var.element = register_variable( var.decl ); + + // dont create joinpoint in functions that where left out of the model + if( ! context.parent ) + return 0; + + // generate node + TU_Ref *new_elem = newRef(); + fillAccessNode( new_elem, var, context, var_src ); + // addtionally set the reference type + TU_Type *ref_type = register_type( new_elem->result_type() ); + new_elem->set_type( ref_type ); + + return new_elem; +} + +template void ClangModelBuilder::fillAccessNode( NODE *new_elem, VarAccessInfo &var, JoinpointContext& context, TU_Builtin *var_src ) { + // fill ACModel information + new_elem->set_variable( var.element ); + new_elem->set_lid( context.local_id ); + if( var.tree_node ) + add_source_loc( new_elem, var.tree_node ); + + assert( context.parent ); + if( context.parent->type_val() == JPT_Builtin ) + static_cast( context.parent )->get_implicit_access().insert( new_elem ); + else if( context.parent->type_val() & JPT_Name ) + static_cast( context.parent )->get_children().insert( new_elem ); + else + assert( false && "Unknown parent type for joinpoint" ); + + // fill Transform information + new_elem->variable( var.decl ); + new_elem->tree_node( var.tree_node ); + new_elem->ref_node( var.ref_node ); + new_elem->origin( context.parent_decl ); + + // remember dependency chain + if( var_src ) + new_elem->entity_src( var_src ); + + // analyze the target object type of this call + if( var.tree_node ) { + if( clang::RecordDecl *rd = const_cast( new_elem->target_class() ) ) { // FIXME: cast should not be necessary, but most place use non const pointers to AST Elements + ACM_Class *target_class = register_aspect( rd ); // try aspect first ... + if( ! target_class ) // ... if not successful, try class + target_class = register_class( rd ); + assert( target_class ); + new_elem->set_target_class( target_class ); + } + } +} + +template void ClangModelBuilder::fillRefAccessNode( NODE *new_elem, VarAccessInfo &var, JoinpointContext& context ) { + // fill ACModel information + new_elem->set_lid( context.local_id ); + if( var.tree_node ) + add_source_loc( new_elem, var.tree_node ); + + assert( context.parent ); + if( context.parent->type_val() == JPT_Builtin ) + static_cast( context.parent )->get_implicit_access().insert( new_elem ); + else if( context.parent->type_val() & JPT_Name ) + static_cast( context.parent )->get_children().insert( new_elem ); + else + assert( false && "Unknown parent type for joinpoint" ); + + // fill Transform information + new_elem->tree_node( var.tree_node ); + new_elem->ref_node( var.ref_node ); + new_elem->origin( context.parent_decl ); + + // this need the transform infos to avoid duplication + TU_Type *ent_type = register_type( new_elem->entity_type() ); + new_elem->set_type( ent_type ); +} + +// create a new execution join point +TU_Method *ClangModelBuilder::register_execution (ACM_Function *ef) { + clang::FunctionDecl *func = ((TI_Function*)ef->transform_info ())->decl (); + TU_Method *new_elem = newExecution(); + ef->get_children().insert(new_elem); + new_elem->decl (func); + return new_elem; +} + +// create a new construction join point +TU_Construction *ClangModelBuilder::register_construction (ACM_Function *cf) { + assert (cf); + clang::FunctionDecl *func = ((TI_Function*)cf->transform_info ())->decl (); + TU_Construction *new_elem = newConstruction(); + cf->get_children().insert(new_elem); + new_elem->decl (func); + clang::CXXRecordDecl *d = + llvm::cast(TI_Class::of (*((ACM_Class*)cf->get_parent()))->decl ()); + new_elem->that_decl(d); + return new_elem; +} + +// create a new construction join point +TU_Destruction *ClangModelBuilder::register_destruction (ACM_Function *df) { + assert (df); + clang::FunctionDecl *func = ((TI_Function*)df->transform_info ())->decl (); + TU_Destruction *new_elem = newDestruction(); + df->get_children().insert(new_elem); + new_elem->decl (func); + clang::CXXRecordDecl *d = + llvm::cast(TI_Class::of (*((ACM_Class*)df->get_parent()))->decl ()); + new_elem->that_decl(d); + return new_elem; +} + +ACM_Name *ClangModelBuilder::register_scope( clang::DeclaratorDecl *obj ) { + return register_scope (obj->getDeclContext (), false); +} + +ACM_Name *ClangModelBuilder::register_scope (clang::DeclContext *obj, bool parent) { + ACM_Name *result = 0; + clang::DeclContext *scope = (parent ? obj->getParent() : obj); + if (scope) { + if (clang::NamespaceDecl *ND = llvm::dyn_cast(scope)) + result = register_namespace (ND); + else if (clang::CXXRecordDecl *RD = + llvm::dyn_cast(scope)) { + result = register_aspect (RD); + if (!result) + result = register_class (RD); + } else if (llvm::isa(scope)) { + result = register_namespace1(0, "::"); + } else if (clang::LinkageSpecDecl *LSD = + llvm::dyn_cast(scope)) + result = register_scope(LSD); + } + +// in some cases, e.g. join-points within local classes it can happen that +// the scope of a join-point is not known in the model -> no error! +// if (!result) { +// _err << sev_error << "parent '" << scope_name (obj).c_str () +// << "' of model element " << obj->QualName () << " not found" +// << endMessage; +// } + + return result; +} + + +// add the source location to a model element by using the syntax tree node +void ClangModelBuilder::add_source_loc (ACM_Any *name, ClangToken token, ClangToken end_token, SourceLocKind kind) { + add_source_loc(name, token.location(), end_token.location(), kind); +} + +void ClangModelBuilder::add_source_loc (ACM_Any *name, clang::Decl *tree, + SourceLocKind kind) { + add_source_loc(name, tree->getLocStart(), tree->getLocEnd(), kind); +} + +void ClangModelBuilder::add_source_loc (ACM_Any *name, clang::Stmt *tree, + SourceLocKind kind) { + add_source_loc(name, tree->getLocStart(), tree->getLocEnd(), kind); +} + +void ClangModelBuilder::add_source_loc(ACM_Any *name, clang::SourceLocation location, + clang::SourceLocation endlocation, + SourceLocKind kind) { + assert(name); + clang::SourceManager &SM = _project.get_compiler_instance()->getSourceManager(); + + // check if this file belong to our project + //ACFileID funit = ACPreprocessor::source_unit (token); + //if (!funit) + //return; + + clang::PresumedLoc PL = SM.getPresumedLoc(location); + clang::PresumedLoc PLEnd = SM.getPresumedLoc(endlocation); +// here the presumed loc must ignore #line directives! => param false + clang::PresumedLoc PL_no_line = SM.getPresumedLoc(location, false); +// clang::PresumedLoc PLEnd = SM.getPresumedLoc(endlocation, false); + + if (PL.isInvalid() || PLEnd.isInvalid()) + return; + + if (!get_project ().isBelow (PL_no_line.getFilename())) { + if (name->type_val () & JPT_Name) { + ACM_Name *jpl_name = (ACM_Name*)name; + // TODO: really use linear search here? + typedef ACM_Container Container; + const Container &tunits = jpl_name->get_tunits (); + bool found = false; + for (Container::const_iterator i = tunits.begin(); i != tunits.end(); ++i) { + if (*i == _tunit_file) { + found = true; + break; + } + } + if (!found) + jpl_name->get_tunits ().insert (_tunit_file); + } + return; + } + + clang::FileID ID = SM.getFileID(location); + ClangModelBuilder::FileMap::iterator i = + file_map().find(model_filename(PL.getFilename())); + ACM_File *file = 0; + if (i != file_map ().end ()) + file = i->second; + else { + // TODO: temporary hack + int len = SM.getSpellingLineNumber(SM.getLocForEndOfFile(ID)); + // TODO: in the future, handle aspect headers differently + ACM_Header *new_file = newHeader(); + get_files().insert(new_file); + new_file->set_filename(model_filename(PL.getFilename())); + new_file->set_len(len); + new_file->get_in().insert(_tunit_file); + if (const clang::FileEntry *fe = SM.getFileEntryForID(ID)) + new_file->set_time(fe->getModificationTime()); + else + new_file->set_time(0); + file = new_file; + file_map().insert( + ClangModelBuilder::FileMapPair(model_filename(PL.getFilename()), file)); + } + int line = PL.getLine(); + int len = PLEnd.getLine() - line + 1; + // TODO: really use linear search here? + typedef ACM_Container Container; + const Container &sources = name->get_source (); + bool found = false; + for (Container::const_iterator i = sources.begin(); i != sources.end(); ++i) { + if ((*i)->get_line () == line && + (*i)->get_file () == file && + (*i)->get_kind () == kind && + (*i)->get_len () == len) { +// if ((*i)->get_len () != len) +// _err << sev_warning << "Internal problem: Length differs for source at same location (file='" << file->get_filename().c_str () << "', line=" +// << line << ")" << endMessage; + found = true; + break; + } + } + if (!found) { + ACM_Source *source = newSource(); + assert(file); + source->set_file(file); + source->set_line(line); + source->set_len(len); + source->set_kind(kind); + name->get_source().insert(source); + } +} + + +// Analyze a declaration and add found attributes to the model element 'name' +void ClangModelBuilder::handle_attributes (ACM_Name *name, clang::Decl *decl) { + + if (!decl->hasAttrs()) + return; + const clang::AttrVec &attrs = decl->getAttrs(); + vector attrStructNames; + for(const clang::Attr *attr_use : attrs) { + AnnotationMap::const_iterator iter = annotation_map().find(attr_use->getLocation()); + if (iter == annotation_map().end()) + continue; + const Annotation &annotation = iter->second; +// cout << signature(*name) << ": " << annotation.to_string() << std::endl; + if (!annotation.params.empty()) + _err << Puma::sev_warning << attr_use->getLocation() << "attribute parameters of '" + << annotation.get_qualified_name().c_str() << "' ignored" << Puma::endMessage; + TU_Attribute *attr = find_attrdecl(annotation.attrNames); + if (!attr && annotation.is_user_defined) + _err << Puma::sev_error << attr_use->getLocation() << "undeclared attribute '" + << annotation.get_qualified_name().c_str() << "' used" << Puma::endMessage; + if (!attr) + continue; + if (decl->isFirstDecl()) { + // in the first declaration of an entity all attributes must be present + if (name->get_attributes().get_sorted().find(attr) != + name->get_attributes().get_sorted().end()) { + // the same attribute use more than once! => error + _err << Puma::sev_warning << attr_use->getLocation() << "attribute '" + << annotation.get_qualified_name().c_str() + << "' used more than once on the same entity" << Puma::endMessage; + } + else + name->get_attributes().insert(attr); + } + else { + if (name->get_attributes().get_sorted().find(attr) == + name->get_attributes().get_sorted().end()) { + _err << Puma::sev_error << attr_use->getLocation() << "attribute '" + << annotation.get_qualified_name().c_str() + << "' added after first declaration" << Puma::endMessage; + } + } + } +} + + diff --git a/AspectC++/ClangModelBuilder.h b/AspectC++/ClangModelBuilder.h new file mode 100644 index 0000000..265e148 --- /dev/null +++ b/AspectC++/ClangModelBuilder.h @@ -0,0 +1,277 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __ClangModelBuilder_h__ +#define __ClangModelBuilder_h__ + +#include "ACModel/Elements.h" +#include "ACToken.h" +#include "ACProject.h" +#include "ClangToken.h" +#include "TransformInfo.h" +#include "ACErrorStream.h" +#include "ClangAnnotation.h" +#include "ClangFlowAnalysis.h" + +namespace Puma { + class VerboseMgr; +} + +namespace clang { + class Decl; + class DeclContext; + class Stmt; + class CallExpr; + class FunctionDecl; + class NamespaceDecl; + class RecordDecl; + class SourceLocation; + class QualType; +} + +namespace llvm { + class StringRef; +} + +class ACConfig; + +// FIXME: needs to be ported to clang +//struct AccessInfo { +// Puma::CAttributeInfo *_info; +// Puma::CTree *_tree; +// AccessInfo () {} +// AccessInfo (Puma::CAttributeInfo *info, Puma::CTree *tree) : +// _info (info), _tree (tree) {} +// +//}; +// + +class ClangModelBuilder : public ProjectModel { + + Puma::VerboseMgr &_vm; + ACErrorStream &_err; + ACConfig &_conf; + ACProject &_project; + ACM_TUnit *_tunit_file; + ClangFlowAnalysis _flow_analysis; + AnnotationMap _annotation_map; + +public: + // map needed to check if a file is already known + typedef map FileMap; + typedef FileMap::value_type FileMapPair; + FileMap _file_map; + FileMap &file_map() { return _file_map; } + + // config is needed for decisions in ASTConsumer + ACConfig &conf() { return _conf; } + + const AnnotationMap &annotation_map() const { return _annotation_map; } + AnnotationMap &annotation_map() { return _annotation_map; } + +private: + + int _tunit_len; + + // FIXME: needs to be ported to clang + // TODO: temporary solution +// list _access_infos; + + int _time; + +public: + void advice_infos (ACM_Aspect *jpl_aspect); + + // determine a model element filename for a unit + string model_filename (const char *fname); + + // get the modification time of a file (UNIX Epoch value) + long modification_time (const string &name); + + ClangModelBuilder (Puma::VerboseMgr &vm, ACErrorStream &err, ACConfig &conf, ACProject &project) : + _vm (vm), _err (err), _conf (conf), _project(project) {} + ACProject &get_project () const { return _project; } + void setup_phase1 (const string &tunit_name, int tunit_len); + + bool is_valid_model_class (clang::RecordDecl *ci) const; + bool is_intro_target (clang::Decl *ci) const; + bool is_valid_model_function (clang::FunctionDecl *fi) const; + bool is_valid_model_variable( clang::DeclaratorDecl *vi ) const; + bool is_valid_model_namespace (clang::NamespaceDecl *ni) const; + bool is_valid_model_type( const clang::QualType& ) const; + + bool inside_template (clang::DeclContext *scope) const; + static bool inside_template_instance (clang::DeclContext *scope); + + // create a type in the join point model from a Puma node + TU_Type *register_type (clang::QualType ti); + + // create a (pointcut) argument in the join point model from a Puma node + TU_Arg *register_arg (clang::QualType ti, llvm::StringRef name); + + // get the translation unit as a model object + ACM_TUnit *tunit_file () const { return _tunit_file; } + + // create a named pointcut in the join point model (phase 1) + ACM_Pointcut *register_pointcut1 (ACM_Name *parent, const std::string &name, + bool is_virtual, const std::string& expr); + bool overrides_virtual_pointcut (ACM_Name *parent, const string &name); // helper function + + // create an attribute in the join point model (phase 1) + TU_Attribute *register_attrdecl1(ACM_Namespace *parent, const std::string &name); + + // find an attribute declaration + TU_Attribute *find_attrdecl (const std::vector &qual_name); + + // create a named pointcut in the join point model from a Puma node + TU_Pointcut *register_pointcut (clang::FunctionDecl *fi, ACM_Name *parent); + + // create a function in the join point model from a Puma node + TU_Function *register_function (clang::FunctionDecl *fi, + ACM_Name *parent = 0); + + // create a global variable or member variable in the join point model + TU_Variable *register_variable( clang::DeclaratorDecl *oi, ACM_Name *parent = 0 ); + + // create a class slice in the join point model (phase 1) + ACM_ClassSlice *register_class_slice (ACM_Name *scope, string name, bool is_struct); + + // create a class in the join point model (phase 1) + ACM_Class *register_class1 (ACM_Name *scope, std::string name, bool in_project = true); + + //create a reference to the Attribute in the join point model +// TU_Attribute *register_attribute(clang::RecordDecl *ci, ACM_Name *parent = 0, bool set_source = true); + + // create a class in the join point model from a Puma node + TU_Class *register_class (clang::RecordDecl *ci, ACM_Name *parent = 0, bool set_source = true); + + // register the implicitly defined constructor/destructor for a class or aspect + void register_constructor_and_destructor (clang::RecordDecl *ci, ACM_Class *elem); + + // create an aspect in the join point model (phase 1) + ACM_Aspect *register_aspect1 (ACM_Name *scope, std::string name, + bool in_project = true); + + // create an aspect in the join point model from a Puma node + TU_Aspect *register_aspect (clang::RecordDecl *ci, ACM_Name *parent = 0); + + // create a Namespace in the join point model (phase 1) + ACM_Namespace *register_namespace1 (ACM_Name *scope, std::string name, + bool in_project = true); + + // create a Namespace in the join point model from a Puma node (phase 2) + TU_Namespace *register_namespace (clang::NamespaceDecl *ni, + ACM_Name *parent = 0); + + // classes to hold parameters when registering access joinpoints + struct JoinpointContext { + ACM_Any *parent; + clang::Decl *parent_decl; + unsigned local_id; + }; + + template struct EntityAccessInfo { + ElementType *element; + DeclType *decl; + clang::Expr *tree_node; + clang::Expr *ref_node; + }; + typedef EntityAccessInfo VarAccessInfo; + + // This method creates a new built-in operator-"pseudo"-function and a call + // of this function and registers both in the AspectC++-join-point-model. + TU_Builtin* register_builtin_operator_call(clang::Expr*, clang::DeclaratorDecl*, int); + + // create a new call join point in the join point model + ACM_Access *register_call (clang::FunctionDecl *called, clang::CallExpr + *call_node, clang::DeclaratorDecl *caller, + int local_id); + + // create a new get join point + ACM_Access *register_get( VarAccessInfo &var, JoinpointContext& context, TU_Builtin *var_src = 0 ); + + // create a new set join point + ACM_Access *register_set( VarAccessInfo &var, JoinpointContext& context, TU_Builtin *var_src = 0 ); + + // create a new ref join point + TU_Ref *register_ref( VarAccessInfo &var, JoinpointContext& context, TU_Builtin *var_src = 0 ); + + // fill common information in Access node + template void fillAccessNode( NODE *new_elem, VarAccessInfo &var, JoinpointContext& context, TU_Builtin *var_src ); + + // fill common information in Access nodes using ref only + template void fillRefAccessNode( NODE *new_elem, VarAccessInfo &var, JoinpointContext& context ); + + // create a new execution join point + TU_Method *register_execution (ACM_Function *ef); + + // create a new construction join point + TU_Construction *register_construction (ACM_Function *cf); + + // create a new construction join point + TU_Destruction *register_destruction (ACM_Function *df); + + // TODO: temporary solution for dac++ + // FIXME: needs to be ported to clang +// void register_attr_access (Puma::CAttributeInfo *attr, Puma::CTree *node); + + // register the scope of a given element + ACM_Name *register_scope( clang::DeclaratorDecl *obj ); + ACM_Name *register_scope (clang::DeclContext *obj, bool parent = true); + + // extended types... + // factory methods that remember all objects of this model + virtual TU_CodeAdvice *newCodeAdvice() { return remember (new TU_CodeAdvice, JPTI_CodeAdvice); } + virtual TU_Type *newType() { return remember (new TU_Type, JPTI_Type); } + virtual TU_Arg *newArg() { return remember (new TU_Arg, JPTI_Arg); } + virtual TU_Namespace *newNamespace() { return remember (new TU_Namespace, JPTI_Namespace); } + virtual TU_Variable *newVariable() { return remember (new TU_Variable, JPTI_Variable); } + virtual TU_Function *newFunction() { return remember (new TU_Function, JPTI_Function); } + virtual TU_Class *newClass() { return remember (new TU_Class, JPTI_Class); } + virtual TU_ClassSlice *newClassSlice() { return remember (new TU_ClassSlice, JPTI_ClassSlice); } + virtual TU_MethodCall *newCall() { return remember (new TU_MethodCall, JPTI_Call); } + virtual TU_Builtin *newBuiltin() { return remember (new TU_Builtin, JPTI_Builtin); } + virtual TU_Get *newGet() { return remember( new TU_Get(), JPTI_Get ); } + virtual TU_Set *newSet() { return remember( new TU_Set(), JPTI_Set ); } + virtual TU_Ref *newRef() { return remember( new TU_Ref(), JPTI_Ref ); } + virtual TU_GetRef *newGetRef() { return remember( new TU_GetRef(), JPTI_GetRef ); } + virtual TU_SetRef *newSetRef() { return remember( new TU_SetRef(), JPTI_SetRef ); } + virtual TU_Method *newExecution() { return remember (new TU_Method, JPTI_Execution); } + virtual TU_Construction *newConstruction() { return remember (new TU_Construction, JPTI_Construction); } + virtual TU_Destruction *newDestruction() { return remember (new TU_Destruction, JPTI_Destruction); } + virtual TU_Pointcut *newPointcut() { return remember (new TU_Pointcut, JPTI_Pointcut); } + virtual TU_Attribute *newAttribute() { return remember (new TU_Attribute, JPTI_Attribute); } + virtual TU_AdviceCode *newAdviceCode() { return remember (new TU_AdviceCode, JPTI_AdviceCode); } + virtual TU_Introduction *newIntroduction() { return remember (new TU_Introduction, JPTI_Introduction); } + virtual TU_Order *newOrder() { return remember (new TU_Order, JPTI_Order); } + virtual TU_Aspect *newAspect() { return remember (new TU_Aspect, JPTI_Aspect); } + + void add_source_loc (ACM_Any *name, clang::SourceLocation location, clang::SourceLocation endlocation, SourceLocKind kind = SLK_NONE); + void add_source_loc (ACM_Any *name, clang::Decl *tree, SourceLocKind kind = SLK_NONE); + void add_source_loc (ACM_Any *name, clang::Stmt *tree, SourceLocKind kind = SLK_NONE); + void add_source_loc (ACM_Any *name, ClangToken token, ClangToken end_token, SourceLocKind kind = SLK_NONE); + + // Analyze a declaration and add found attributes to the model element 'name' + void handle_attributes (ACM_Name *name, clang::Decl *decl); + + // TODO: temporary solution + // FIXME: needs to be ported to clang +// const list &access_infos () const { return _access_infos; } +}; + +#endif diff --git a/AspectC++/ClangPreprocessor.cc b/AspectC++/ClangPreprocessor.cc new file mode 100644 index 0000000..607515c --- /dev/null +++ b/AspectC++/ClangPreprocessor.cc @@ -0,0 +1,151 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "ClangPreprocessor.h" +#include "IncludeGraph.h" +#include "IntroductionUnit.h" +#include "version.h" + +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Lex/Preprocessor.h" + +using namespace clang; + +ClangPreprocessor::ClangPreprocessor (const string &tunit_name, + ACConfig &conf, IncludeGraph &include_graph, ACProject &project) : + _conf(conf), _project(project), _tunit_name(tunit_name) { + + CompilerInstance &CI = *_project.get_compiler_instance(); + + CI.createPreprocessor(clang::TU_Complete); + Preprocessor &PP = CI.getPreprocessor(); + + CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), &PP); + +#if FRONTEND_CLANG < 38 + PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(), + PP.getLangOpts()); +#else + // new interface (lowercase 'I') + PP.getBuiltinInfo().initializeBuiltins(PP.getIdentifierTable(), + PP.getLangOpts()); +#endif + +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_5_0_0 + CI.InitializeSourceManager(FrontendInputFile(tunit_name, InputKind::CXX)); +#else + CI.InitializeSourceManager(FrontendInputFile(tunit_name, IK_CXX)); +#endif + PP.EnterMainSourceFile(); +#if CLANG_VERSION_NUMBER <= VERSION_NUMBER_3_5_2 + PP.addPPCallbacks(new IncludeGraph::IncludeGraphCallback(include_graph)); +#else // C++ 11 interface + PP.addPPCallbacks(std::unique_ptr(new IncludeGraph::IncludeGraphCallback(include_graph))); +#endif + next_token(); +} + +ClangPreprocessor::~ClangPreprocessor () { + CompilerInstance &CI = *_project.get_compiler_instance(); + + CI.getDiagnosticClient().EndSourceFile(); + CI.getPreprocessor().EndSourceFile(); +} + +unsigned ClangPreprocessor::tunit_len() const { + CompilerInstance &CI = *_project.get_compiler_instance(); + clang::SourceManager &manager = CI.getSourceManager(); + clang::FileID main_fid = manager.getMainFileID(); + clang::SourceLocation last = manager.getLocForEndOfFile(main_fid); + return manager.getPresumedLoc(last).getLine(); +} + +bool ClangPreprocessor::keywords_enabled (clang::SourceLocation loc) const { + + SourceManager &SM = _project.get_compiler_instance()->getSourceManager(); + ACFileID funit = SM.getFileEntryForID(SM.getFileID(SM.getExpansionLoc (loc))); + + if (!funit.is_valid() || !_project.isBelow(funit.name().c_str ())) + return false; + + string name = funit.name (); + size_t len = name.length(); + if (len > 2 && strcmp (name.c_str () + (len - 3), ".ah") == 0) + return true; + + return _conf.keywords(); +} + +ACErrorStream &ClangPreprocessor::err () const { + return _project.err (); +} + +ACToken ClangPreprocessor::next_token () { + Preprocessor &PP = _project.get_compiler_instance()->getPreprocessor(); + clang::Token tok; + PP.Lex(tok); + _current_token = ACToken(tok, keywords_enabled(tok.getLocation())); + if (!_recorded_tokens.empty()) + _recorded_tokens.push_back(_current_token); + + return _current_token; +} + +ACToken ClangPreprocessor::curr_token () { + return _current_token; +} + +ACToken ClangPreprocessor::look_ahead (int n) { + Preprocessor &PP = _project.get_compiler_instance()->getPreprocessor(); + clang::Token Tok(PP.LookAhead(n - 1)); + return ACToken(Tok, keywords_enabled(Tok.getLocation())); +} + +// functions to record the token stream + +void ClangPreprocessor::start_recording () { + if (_recorded_tokens.empty()) + _recorded_tokens.push_back(curr_token()); +} + +ClangPreprocessor::TokenVector ClangPreprocessor::stop_recording () { + TokenVector result; + std::swap(result, _recorded_tokens); + return result; +} + +ACFileID ClangPreprocessor::source_unit (ACToken token) const { + SourceManager &SM = _project.get_compiler_instance()->getSourceManager(); + return SM.getFileEntryForID(SM.getFileID(SM.getExpansionLoc (token.location ()))); +} + +// check whether a token is located within the files of the project +bool ClangPreprocessor::is_in_project(ACToken token) const { + ACFileID funit = source_unit(token); + return funit.is_valid() && _project.isBelow(funit.name().c_str ()); +} + +std::string ClangPreprocessor::token_text (ACToken tok) const { + Preprocessor &PP = _project.get_compiler_instance()->getPreprocessor(); + return PP.getSpelling(tok.get()); +} + +unsigned ClangPreprocessor::token_line_number (ACToken tok) const { + SourceManager &SM = _project.get_compiler_instance()->getSourceManager(); + return SM.getPresumedLineNumber(tok.location()); +} diff --git a/AspectC++/ClangPreprocessor.h b/AspectC++/ClangPreprocessor.h new file mode 100644 index 0000000..68ef5ff --- /dev/null +++ b/AspectC++/ClangPreprocessor.h @@ -0,0 +1,74 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __ClangPreprocessor_h__ +#define __ClangPreprocessor_h__ + +#include "ACConfig.h" +#include "ACProject.h" +#include "ACToken.h" +#include "ACErrorStream.h" +#include "IncludeGraph.h" + +// This class performs preprocesses a translation unit and returns its +// content token by token. Upon request, it can also record the returned +// tokens. + +class ClangPreprocessor { +public: + typedef std::vector TokenVector; + +private: + ACConfig &_conf; + ACProject &_project; + TokenVector _recorded_tokens; + ACToken _current_token; + string _tunit_name; + + bool keywords_enabled (clang::SourceLocation loc) const; + +public: + ClangPreprocessor (const string& tunit_name, ACConfig &conf, + IncludeGraph &include_graph, ACProject &project); + ~ClangPreprocessor (); + + // functions to access the token stream + ACToken next_token (); + ACToken curr_token (); + ACToken look_ahead (int n = 1); + + // functions to record the token stream + void start_recording (); + TokenVector stop_recording (); + + ACErrorStream &err () const; + + // get the file unit in which a token is located + // (if necessary follow macro expansions and intros) + ACFileID source_unit (ACToken token) const; + + // check whether a token is located within the files of the project + bool is_in_project (ACToken token) const; + + std::string token_text (ACToken) const; + unsigned token_line_number (ACToken) const; + + unsigned tunit_len() const; +}; + +#endif // __ClangPreprocessor_h__ diff --git a/AspectC++/ClangResultBuffer.cc b/AspectC++/ClangResultBuffer.cc new file mode 100644 index 0000000..2b853b2 --- /dev/null +++ b/AspectC++/ClangResultBuffer.cc @@ -0,0 +1,157 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "ClangResultBuffer.h" +#include "clang/AST/ASTContext.h" +#include +using std::stringstream; + +bool ClangResultBuffer::has_constructor_problem () const { + return _type->isRecordType() && !_type->isReferenceType(); +} + +string ClangResultBuffer::tjp_result_type () const { + stringstream out; + clang::QualType type = _type; + if (_type->isVoidType()/* || _type->isUndefined ()*/) + out << "void"; + else if (type->isReferenceType ()) { + if (_use_typedef) { + const clang::ReferenceType *ref_type = clang::dyn_cast(type); + if (ref_type->getPointeeType ().isConstQualified ()) + out << "const "; + out << "TResult"; + } + else { + out << TI_Type::get_type_code_text(type.getNonReferenceType(), &_ast_ctx, 0); + } + } + else + if (_use_typedef) { + if (type.isConstQualified ()) + out << "const "; + out << "TResult"; + } + else + out << TI_Type::get_type_code_text(type, &_ast_ctx, 0); + return out.str (); +} + +string ClangResultBuffer::result_type (const string &name, bool unqual) const { + stringstream out; + clang::QualType type = _type; + if (unqual) + type = type.getLocalUnqualifiedType (); + if (_type->isVoidType()/* || _type->isUndefined ()*/) + out << "void"; + else if (type->isReferenceType ()) { + string ptrname = string ("*") + name; + if (_use_typedef) { + const clang::ReferenceType *ref_type = clang::dyn_cast(type); + if (ref_type->getPointeeType ().isConstQualified ()) + out << "const "; + out << "TResult " << ptrname; + } + else { + out << TI_Type::get_type_code_text(_ast_ctx.getPointerType(type.getNonReferenceType()), + &_ast_ctx, + name.c_str()); + } + } + else { + if (_use_typedef) { + if (type.isConstQualified()) + out << "const "; + out << "TResult " << name; + } + else { + out << TI_Type::get_type_code_text(type.getNonReferenceType(), &_ast_ctx, name.c_str()); + } + } + return out.str (); +} + +string ClangResultBuffer::result_declaration() const { + stringstream out; + if (!(_type->isVoidType()/* || _type->isUndefined ()*/)) { + if (_problem) + out << "AC::ResultBuffer< " << result_type ("", false) << " > " << result_name(); + else + out << result_type (result_name(), true); + out << ";" << endl; + } + return out.str (); +} + +string ClangResultBuffer::result_assignment(const string &result) const { + stringstream out; + if (!(_type->isVoidType()/* || _type->isUndefined ()*/)) { + if (_problem) { + out << "::new (&" << result_name() << ") "; + out << result_type ("", true); + out << " ("; + } + else + out << result_name() << " = "; + if (_type->isReferenceType ()) + out << "&"; + } + out << result; + if (!(_type->isVoidType()/* || _type->isUndefined ()*/)) + if (_problem) + out << ")"; + return out.str (); +} + +string ClangResultBuffer::action_result_assignment(const string &result) const { + stringstream out; + if (!(_type->isVoidType()/* || _type->isUndefined ()*/)) { + if (_problem) { + out << "::new ((AC::ResultBuffer< "; + out << result_type ("", false); + out << " >*)__TJP::result ()) "; + out << result_type ("", false); + out << " ("; + } + else { + if( workaround_const_result() ) + out << "const_cast<" << result_type( "", false ) << " & >( "; + out << "*__TJP::result()" << ( workaround_const_result() ? " )" : "" ) << " = (" << result_type( "", false ) << ")"; + } + if (_type->isReferenceType ()) + out << "&"; + } + out << result; + if (!(_type->isVoidType()/* || _type->isUndefined ()*/)) + if (_problem) + out << ")"; + return out.str (); +} + +string ClangResultBuffer::result_return() const { + stringstream out; + if (!(_type->isVoidType ()/* || _type->isUndefined ()*/)) { + out << "return "; + if (_type->isReferenceType ()) + out << "*"; + out << "("; + out << result_type ("&"); + out << ")" << result_name() << ";" << endl; + } + return out.str (); +} diff --git a/AspectC++/ClangResultBuffer.h b/AspectC++/ClangResultBuffer.h new file mode 100644 index 0000000..bd043d7 --- /dev/null +++ b/AspectC++/ClangResultBuffer.h @@ -0,0 +1,78 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __ClangResultBuffer_h__ +#define __ClangResultBuffer_h__ + +#include "ACModel/Elements.h" +#include "TransformInfo.h" +#include "ACProject.h" +#include "ACModel/Utils.h" + +#include +using std::string; + +namespace Puma { + class CTypeInfo; +} + +class ClangResultBuffer { + clang::QualType _type; + ACProject &_project; + clang::ASTContext& _ast_ctx; + bool _problem; + bool _use_typedef; + bool _const_result; + bool has_constructor_problem () const; + bool workaround_const_result() const { return _const_result; } +public: + ClangResultBuffer (ACProject &project, ACM_Code *jpl, bool use_typedef = false) : + _project (project), + _ast_ctx(project.get_compiler_instance ()->getASTContext ()), + _use_typedef( use_typedef ), _const_result( false ) { + //_policy.SuppressUnwrittenScope = true; // Suppress printing of + // builtin constructors/destructors have no decl -> result type is 'void' + if ( jpl->type_val() == JPT_Get ) + // FIXME: If the get join point accesses an array, the function + // get_result_type( *jpl ) returns the type of the array + // instead of the actual element type. + // As a workaround, use TI_GET::entity_type() here. + // Once get_result_type( *jpl ) yields the correct type, + // this special case can be removed. + _type = TI_Get::of(*static_cast(jpl))->entity_type(); + else if( has_result_type( *jpl ) ) + _type = TI_Type::of( *get_result_type( *jpl ) )->type(); + else + _type = _ast_ctx.VoidTy; + _problem = has_constructor_problem (); + } + string tjp_result_type () const; + string result_type (const string &name, bool unqual = false) const; + string result_declaration() const; + string result_assignment(const string &result) const; + string action_result_assignment(const string &result) const; + string result_return() const; + + void has_const_result() { _const_result = true; } + + // the name of the result buffer allocated in each wrapper function. + // must not shadow the functions' arguments + static const string result_name() { return "__result_buffer"; } +}; + +#endif // __ClangResultBuffer_h__ diff --git a/AspectC++/ClangSyntacticContext.cc b/AspectC++/ClangSyntacticContext.cc new file mode 100644 index 0000000..ce8574d --- /dev/null +++ b/AspectC++/ClangSyntacticContext.cc @@ -0,0 +1,69 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "ClangSyntacticContext.h" +#include "ClangTransformInfo.h" + +#include "version.h" + +string ClangSyntacticContext::type() const { + clang::ASTContext &ctx = _decl->getASTContext(); + return TI_Type::get_type_text(ctx.getTypeDeclType(llvm::cast(_decl)), &ctx, + 0, TSEF_ENABLE, true, TSEF_DONOTCHANGE, false, true, false); +} + +int ClangSyntacticContext::is_in_extern_c_block() const { + int depth = 0; + const clang::DeclContext* decl_context = _decl->getDeclContext(); + while (decl_context->getDeclKind() != clang::Decl::TranslationUnit) { + if (decl_context->getDeclKind() == clang::Decl::LinkageSpec) { + const clang::LinkageSpecDecl* linkage_spec_decl = clang::cast(decl_context); + if(linkage_spec_decl->getLanguage() == clang::LinkageSpecDecl::lang_c && linkage_spec_decl->hasBraces()) { // only blocks have braces + depth++; + } + } + decl_context = decl_context->getLexicalParent(); + } + return depth; +} + +string ClangSyntacticContext::result_type(const string &name) const { + const clang::FunctionDecl *fd = llvm::cast(_decl); + clang::PrintingPolicy pp(fd->getASTContext().getPrintingPolicy()); + pp.SuppressUnwrittenScope = true; // Suppress +// string ts = name; +//#if CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR == 4 && !defined(CLANG_VERSION_PATCHLEVEL) +// fd->getResultType().getAsStringInternal(ts, pp); +//#else // C++ 11 interface +// fd->getReturnType().getAsStringInternal(ts, pp); +//#endif +// return ts; + clang::QualType returnType = fd->getReturnType(); + return TI_Type::get_type_code_text(returnType, &_decl->getASTContext(), name.c_str()); +} + +string ClangSyntacticContext::arg_type(unsigned int no, + const string &name) const { + const clang::FunctionDecl *fd = llvm::cast(_decl); + clang::PrintingPolicy pp(fd->getASTContext().getPrintingPolicy()); + pp.SuppressUnwrittenScope = true; // Suppress +// string ts = name; +// fd->getParamDecl(no)->getType().getAsStringInternal(ts, pp); +// return ts; + return TI_Type::get_type_code_text(fd->getParamDecl(no)->getType(), &_decl->getASTContext(), name.c_str()); +} diff --git a/AspectC++/ClangSyntacticContext.h b/AspectC++/ClangSyntacticContext.h new file mode 100644 index 0000000..902297c --- /dev/null +++ b/AspectC++/ClangSyntacticContext.h @@ -0,0 +1,223 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __ClangSyntacticContext_h__ +#define __ClangSyntacticContext_h__ + +// STL includes +#include +#include +using namespace std; + +// clang includes +#include "clang/Basic/Version.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/Decl.h" +#include "clang/AST/Stmt.h" +#include "clang/Lex/Lexer.h" +#include "clang/Parse/Parser.h" + +// AspectC++ includes +#include "WeaverBase.h" + +class ClangSyntacticContext { + const clang::Decl *_decl; + +public: + ClangSyntacticContext(const clang::Decl *d = 0) : _decl(d) {} + bool operator < (const ClangSyntacticContext &that) const { return _decl < that._decl; } + + bool is_anon_union_member () const { + if (const clang::FieldDecl *fd = llvm::dyn_cast(_decl)) + return fd->getParent ()->isAnonymousStructOrUnion (); + return false; + } + + ClangSyntacticContext get_anon_union_context () const { + assert (is_anon_union_member ()); + return ClangSyntacticContext (llvm::cast(_decl)->getParent ()); + } + + bool is_array () const { + if (const clang::ValueDecl *vd = llvm::dyn_cast(_decl)) + return vd->getType ().getTypePtr ()->isArrayType (); + return false; + } + + string name () const { + if (const clang::NamedDecl *nd = llvm::dyn_cast(_decl)) + return nd->getNameAsString (); + return ""; + } + + string get_as_string (int indentation = 0) const { + std::string s; + llvm::raw_string_ostream os(s); + _decl->print(os, indentation); + return s; + } + + string type () const; + + bool is_definition () const { + if (const clang::FunctionDecl *fd = llvm::dyn_cast(_decl)) + return fd->isThisDeclarationADefinition(); + return false; + } + + bool has_assigned_scope () const { + return _decl->isOutOfLine (); + } + + // returns 0 if not in an extern "C" { ... } block, otherwise (result >= 1) the + // result is the depth of nested extern "C" blocks + int is_in_extern_c_block () const; + + bool is_in_class_scope () const { + return _decl->getLexicalDeclContext ()->isRecord(); + } + + bool is_in_namespace () const { + return _decl->getLexicalDeclContext ()->isNamespace(); + } + + bool is_in_project () const { + return true; // FIXME! + } + + string protection () const { + string result; + switch (_decl->getAccess()) { + case clang::AS_public: result = "public"; break; + case clang::AS_private: result = "private"; break; + case clang::AS_protected: result = "protected"; break; + case clang::AS_none: result = ""; + } + return result; + } + + const WeavePos &wrapper_pos (WeaverBase &wb) const { + // First case: this is a call in a variable declaration: + const clang::VarDecl *vd = clang::dyn_cast(_decl); + if (vd) + return wb.weave_pos(vd->getLocStart (), WeavePos::WP_BEFORE); + // Second case: a function ... + clang::SourceLocation loc = llvm::cast(_decl)->getLocStart(); + const clang::LinkageSpecDecl *lsd = + llvm::dyn_cast(llvm::cast(_decl)->getDeclContext ()); + if (lsd && !lsd->hasBraces ()) + loc = lsd->getLocStart (); + + if (_decl->hasAttrs()) { + clang::SourceManager &source_manager = wb.getRewriter ().getSourceMgr(); + const clang::AttrVec &attrs = _decl->getAttrs(); + + for(const clang::Attr *attr : attrs) { + AnnotationMap::const_iterator i = wb.get_annotation_map().find(attr->getLocation()); + if (i != wb.get_annotation_map().end() && + source_manager.isBeforeInTranslationUnit(i->second.seqBegin, loc)) + loc = i->second.seqBegin; + } + } + + return wb.weave_pos(loc, WeavePos::WP_BEFORE); + } + + const WeavePos &fct_body_start_pos (WeaverBase &wb) const { + clang::SourceLocation loc = llvm::cast(_decl)->getBody()->getLocStart(); + return wb.weave_pos(loc, WeavePos::WP_BEFORE); + } + + const WeavePos &fct_body_end_pos (WeaverBase &wb) const { + clang::SourceLocation loc = llvm::cast(_decl)->getLocEnd(); + return wb.weave_pos(loc, WeavePos::WP_BEFORE); + } + + const WeavePos &objdecl_start_pos (WeaverBase &wb) const { + clang::SourceLocation loc = _decl->getLocStart(); + return wb.weave_pos(loc, WeavePos::WP_BEFORE); + } + + const WeavePos &objdecl_end_pos (WeaverBase &wb) const { + clang::SourceLocation loc = _decl->getLocEnd(); + if (llvm::isa(_decl)) { + const clang::LangOptions &options = wb.getRewriter ().getLangOpts (); + clang::SourceManager &source_manager = wb.getRewriter ().getSourceMgr(); + loc = clang::Lexer::getLocForEndOfToken (loc, 0, source_manager, options); + } + + return wb.weave_pos(loc, WeavePos::WP_AFTER); + } + + bool ends_with_return () const { + const clang::FunctionDecl *fd = llvm::cast(_decl); + if (clang::Stmt *body = fd->getBody()) { + clang::Stmt::child_iterator child = body->child_begin(); + clang::Stmt::child_iterator end = body->child_end(); + if (child == end) + return false; // no children + + // Iterate to the last Stmt. + while (std::next(child) != end) + ++child; + + // Check if it's a return. + return llvm::isa(*child); + } + return false; + } + + string result_type (const string &name = "") const; + + unsigned int args () const { + return llvm::cast(_decl)->getNumParams(); + } + + string arg_name (unsigned int no) const { + const clang::FunctionDecl *fd = llvm::cast(_decl); + const clang::ParmVarDecl *pd = fd->getParamDecl(no); + return pd->getNameAsString (); + } + + string arg_type (unsigned int no, const string &name = "") const; + + string qualified_scope () const { + string result; + if (_decl->isOutOfLine ()) { + const clang::NamedDecl *ND = + llvm::dyn_cast(_decl->getDeclContext ()); + if (ND) result = ND->getQualifiedNameAsString(); + } + return result; + } + + string syntactical_scope () const { + string result; + const clang::NamedDecl *ND = + llvm::dyn_cast(_decl->getLexicalDeclContext ()); + if (ND) ND->getQualifiedNameAsString(); + return result; + } + + // TODO: still needed? yes, in CodeWeaver + const clang::Decl *decl () const { return _decl; } +}; + +#endif // __ClangSyntacticContext_h__ + + diff --git a/AspectC++/ClangToken.h b/AspectC++/ClangToken.h new file mode 100644 index 0000000..aba5a17 --- /dev/null +++ b/AspectC++/ClangToken.h @@ -0,0 +1,129 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2013 The 'ac++' developers (see aspectc.org) +// +// 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 __ClangToken_h__ +#define __ClangToken_h__ + +#include "clang/Lex/Token.h" +#include "clang/Basic/IdentifierTable.h" + +// ClangToken - Provides a uniform wrapper for a Token object. +class ClangToken { +public: + enum Kind { + // Translate from clang token kinds into our subset of Puma ones. + TOK_INVALID = clang::tok::unknown, + TOK_EOF = clang::tok::eof, + TOK_ALIGNAS = clang::tok::kw_alignas, + TOK_ASSIGN = clang::tok::equal, + TOK_ATTRIBUTE = clang::tok::kw___attribute, + TOK_CLASS = clang::tok::kw_class, + TOK_CLOSE_CURLY = clang::tok::r_brace, + TOK_CLOSE_ROUND = clang::tok::r_paren, + TOK_CLOSE_SQUARE = clang::tok::r_square, + TOK_COLON = clang::tok::colon, + TOK_COLON_COLON = clang::tok::coloncolon, + TOK_COMMA = clang::tok::comma, + TOK_CONST = clang::tok::kw_const, + TOK_ENUM = clang::tok::kw_enum, + TOK_FRIEND = clang::tok::kw_friend, + TOK_GREATER = clang::tok::greater, + TOK_ID = clang::tok::identifier, + TOK_LESS = clang::tok::less, + TOK_NAMESPACE = clang::tok::kw_namespace, + TOK_MUL = clang::tok::star, + TOK_OPEN_CURLY = clang::tok::l_brace, + TOK_OPEN_ROUND = clang::tok::l_paren, + TOK_OPEN_SQUARE = clang::tok::l_square, + TOK_PRIVATE = clang::tok::kw_private, + TOK_PROTECTED = clang::tok::kw_protected, + TOK_PTS = clang::tok::arrow, + TOK_PUBLIC = clang::tok::kw_public, + TOK_SEMI_COLON = clang::tok::semi, + TOK_STATIC = clang::tok::kw_static, + TOK_STRUCT = clang::tok::kw_struct, + TOK_TEMPLATE = clang::tok::kw_template, + TOK_TILDE = clang::tok::tilde, + TOK_TYPEDEF = clang::tok::kw_typedef, + TOK_UNION = clang::tok::kw_union, + TOK_USING = clang::tok::kw_using, + TOK_VIRTUAL = clang::tok::kw_virtual, + TOK_VOLATILE = clang::tok::kw_volatile, + // Attention: we assume that clang token are enumerated from 0 to a number smaller than 0x10000 + TOK_ASPECT = 0x10000, + TOK_ADVICE, + TOK_POINTCUT, + TOK_SLICE, + TOK_ATTRDECL, + TOK_UNKNOWN + }; + +private: + clang::Token _token; + Kind _kind; + +public: + ClangToken () : _token (), _kind (TOK_INVALID) {} + explicit ClangToken(clang::Token token, bool acxx_keyword = false) + : _token (token), _kind(Kind (token.getKind ())) { + + if (acxx_keyword && _kind == TOK_ID) { + const char *text = this->text (); + if (!strcmp(text, "aspect")) + _kind = TOK_ASPECT; + else if (!strcmp(text, "advice")) + _kind = TOK_ADVICE; + else if (!strcmp(text, "pointcut")) + _kind = TOK_POINTCUT; + else if (!strcmp(text, "slice")) + _kind = TOK_SLICE; + else if (!strcmp(text, "attribute")) + _kind = TOK_ATTRDECL; + } + + } + bool is_core() const { return true; } + bool is_directive () const { return false; /* FIXME! */ } + bool is_macro_generated () const { return location ().isMacroID (); } + clang::SourceLocation location () const { return _token.getLocation (); } + int type () const { return _kind; } + + const char *text () const { + if (clang::IdentifierInfo *II = _token.getIdentifierInfo ()) + return II->getNameStart (); + + // No identifier, must be a literal. + assert (_token.isLiteral()); + return _token.getLiteralData (); + } + + // Interface to get the underlying token. + clang::Token get() const { return _token; } +#if 0 // Not useful with clang + operator bool () const { return _token != 0; } + bool operator== (const ACToken &rhs) const { return _token == rhs._token; } + bool operator!= (const ACToken &rhs) const { return _token != rhs._token; } + // FIXME: Are those actually useful? + bool operator< (const ACToken &rhs) const { return _token < rhs._token; } + bool operator> (const ACToken &rhs) const { return _token > rhs._token; } + bool operator<= (const ACToken &rhs) const { return _token <= rhs._token; } + bool operator>= (const ACToken &rhs) const { return _token <= rhs._token; } +#endif +}; + +#endif /* __ClangToken_h__ */ diff --git a/AspectC++/ClangTransformInfo.h b/AspectC++/ClangTransformInfo.h new file mode 100644 index 0000000..266da10 --- /dev/null +++ b/AspectC++/ClangTransformInfo.h @@ -0,0 +1,2479 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __ClangTransformInfo_h__ +#define __ClangTransformInfo_h__ + +#include "ACModel/Elements.h" +#include "ACToken.h" +#include "ACFileID.h" +#include "ThisJoinPoint.h" +#include "PointCutExpr.h" +#include "SyntacticContext.h" +#include "CFlow.h" +#include "WeaverBase.h" +#include "ClangAdjustedTypePrinter.h" +#include "version.h" + +#include "clang/Basic/Version.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclTemplate.h" +#include "clang/AST/Type.h" +#include "clang/AST/ExprCXX.h" +#include "llvm/Support/raw_ostream.h" +#include "clang/AST/CXXInheritance.h" + + +class TI_CodeAdvice : public ModelTransformInfo { + // Condition is located here instead of in the AdviceInfo object because + // there are cases where the conditions differ but the advice info + // is the same. + const Condition *_condition; + AdviceInfo *_advice_info; +public: + void set_condition (const Condition *c) { _condition = c; } + const Condition *get_condition () const { return _condition; } + void set_advice_info (AdviceInfo *ai) { _advice_info = ai; } + AdviceInfo *get_advice_info () const { return _advice_info; } + + static TI_CodeAdvice *of (const ACM_CodeAdvice &loc) { + return static_cast(loc.transform_info ()); + } +}; + +class TransformInfo : public ModelTransformInfo { +public: + virtual ModelNode &jpl () = 0; + virtual clang::Decl *decl () const = 0; + + static inline const TransformInfo *of (const ModelNode &loc); + static inline clang::Decl *decl (const ModelNode &loc); + static inline Puma::Location location (const ModelNode &loc); + + static const WeavePos &get_pos_after_token (clang::SourceLocation loc, + WeaverBase &wb, WeavePos::Pos pos = WeavePos::WP_AFTER) { + return wb.get_pos_after_loc(loc, pos); + } + + // parameter 'is_id': if true, the searched string is only replaced if the + // character before and after the matching substring is + // not in an identifier. + // (example: don't replace 'shortcut' by 'short intcut') + static void replace_in_string(std::string& subject, const std::string& search, + const std::string& replace, bool is_id = false) { + size_t pos = 0; + while ((pos = subject.find(search, pos)) != std::string::npos) { + bool id_before = (pos > 0 && (subject[pos - 1] == '_' || std::isalpha(subject[pos - 1]))); + bool id_after = ((pos + search.length () < subject.length()) && + (subject[pos + search.length()] == '_' || std::isalnum(subject[pos + search.length()]))); + if (!is_id || (!id_before && !id_after)) { + subject.replace(pos, search.length(), replace); + pos += replace.length(); + } + else + pos += search.length(); + } + } + + static bool needs_this (clang::FunctionDecl *func) { + if (clang::CXXMethodDecl *m = llvm::dyn_cast(func)) + if (!m->isStatic()) + return true; + + return false; + } + + // TODO: duplicate of function in ClangModelBuilder.cc + template + static bool isTemplateInstantiation(T node) { + return (node->getTemplateSpecializationKind() == + clang::TSK_ImplicitInstantiation || + node->getTemplateSpecializationKind() == + clang::TSK_ExplicitInstantiationDefinition); + } + + // TODO: duplicate of function in ClangModelBuilder.cc + static bool inside_template_instance (clang::DeclContext *scope) { + if (llvm::isa(scope)) + return false; + + if (clang::FunctionDecl *FD = llvm::dyn_cast(scope)) + if (isTemplateInstantiation(FD)) + return true; + + if (clang::VarDecl *VD = llvm::dyn_cast(scope)) + if (isTemplateInstantiation(VD)) + return true; + + if (clang::CXXRecordDecl *RD = llvm::dyn_cast(scope)) + if (isTemplateInstantiation(RD)) + return true; + + return inside_template_instance(scope->getParent()); + } + +}; + +inline const TransformInfo *TransformInfo::of (const ModelNode &loc) { + return loc.transform_info () ? (TransformInfo*)loc.transform_info () : 0; +} +//inline CTree *TransformInfo::tree (const ModelNode &loc) { +// return loc.transform_info () ? +// ((TransformInfo*)loc.transform_info ())->tree () : 0; +//} +//inline Unit *TransformInfo::unit (const ModelNode &loc) { +// return loc.transform_info () ? +// ((TransformInfo*)loc.transform_info ())->unit () : 0; +//} +inline clang::Decl *TransformInfo::decl (const ModelNode &loc) { + return loc.transform_info () ? + ((TransformInfo*)loc.transform_info ())->decl () : 0; +} +inline Puma::Location TransformInfo::location (const ModelNode &loc) { + return Puma::Location (); // FIXME: implement for Clang +} + + +class TI_Type : public TransformInfo { + clang::QualType _type; +public: + void type (clang::QualType ti) { _type = ti; } + clang::QualType type () const { return _type; } + + virtual clang::Decl *decl () const { return 0; } + + bool is_const () const { return _type.isConstQualified (); } + bool is_reference () const { return _type.getTypePtr ()->isReferenceType (); } + + // Called from ClangModelBuilder::register_type(...) and ClangModelBuilder::register_arg(...) + // and used for signature. + static string name (clang::ASTContext &ctx, clang::QualType type_info) { + // Get the type as a string, looking through template parameters + // and typedefs and printing anonymous as unnamed: + string type_str = TI_Type::get_type_text(type_info, &ctx, "?", TSEF_DONOTCHANGE, false, TSEF_DISABLE, true, true, false); + + int last = type_str.length() - 1; + if (type_str[last] == '?') last--; + while(type_str[last] == ' ') last--; + + return type_str.substr (0, last + 1); + } + +private: + // Returns a printing policy setup according to given flags for adjusted type printing + static inline clang::PrintingPolicy get_preset_printing_policy(const clang::ASTContext* ctx, + bool unnamed, + TriStateEnableFeature absolute_qualified) { + // TODO: always create, setup and use own printing policy? + clang::PrintingPolicy policy = ctx + ? ctx->getPrintingPolicy() + : clang::PrintingPolicy(clang::LangOptions()); + + // Ensure some policy properties: + policy.SuppressSpecifiers = false; +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_9_1 + policy.IncludeTagDefinition = false; +#else + policy.SuppressTag = false; +#endif + // Suppress only if we do not want to replace it with + // later + policy.SuppressUnwrittenScope = !unnamed; + policy.AnonymousTagLocations = unnamed; +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_5_0_0 + policy.Scope = (absolute_qualified == TSEF_ENABLE + ? clang::ScopePrintingKind::FullScope : + absolute_qualified == TSEF_DISABLE + ? clang::ScopePrintingKind::SuppressScope : + clang::ScopePrintingKind::DefaultScope); +#endif + return policy; + } + + // Unifies the types in the given string according to the given flags. + static inline string& get_with_unified_types(string& input, bool unnamed) { + if(unnamed) { + // If requested, replace occurences of anonymous-variants with "": + const char* unnamed_namespace_str = +#if CLANG_VERSION_NUMBER <= VERSION_NUMBER_3_5_2 + "" +#else // C++ 11 interface + "(anonymous namespace)" +#endif + ; + replace_in_string(input, unnamed_namespace_str, ""); + } + + // Unify some types: (taken from fix_type_in_signature(...) + // and fixed "long int" -> "long int int" bug) + replace_in_string(input, "long", "long int", true); + replace_in_string(input, "long int long int", "long long int", true); + replace_in_string(input, "long int int", "long int", true); + replace_in_string(input, "long int double", "long double", true); + replace_in_string(input, "short", "short int", true); + replace_in_string(input, "short int int", "short int", true); + // TODO: Is the following line necessary? + replace_in_string(input, "::", unnamed ? "::" : ""); + replace_in_string(input, ", ", ","); + replace_in_string(input, "*restrict", "*"); + replace_in_string(input, " restrict", " "); + replace_in_string(input, "*__restrict", "*"); + replace_in_string(input, " __restrict", " "); + + return input; + } + +public: + + /** Returns the textual representation of a declaration name. + * \param decl The declaration + * \param ctx The ASTContext + * \param absolute_qualified Add all nested name specifiers as well as the + * root qualifier (ENABLE), do not change nested name specifiers (DONOTCHANGE) + * or remove all nested name specifiers (DISABLE). + * \param keep_typedef If the type is typedef'd, keep the typedef and return + * the typedef'd type (and not the underlying type) + * \param elaborated_type_spec Add elaborated type specifier before + * class, union, and enumeration types. + * \param unnamed Do not suppress printing of unwritten scope and convert printed + * namespaces to '' + * \param remove_attributes Removes occurrences of attributes + * */ + static string get_decl_name_text(const clang::NamedDecl* decl, + TriStateEnableFeature absolute_qualified = TSEF_DONOTCHANGE, + bool keep_typedef = true, // TODO: Currently ignored if Clang >= 5.0.0 + TriStateEnableFeature elaborated_type_spec = TSEF_DONOTCHANGE, + bool unnamed = false, + bool remove_attributes = false + ) { + clang::PrintingPolicy policy = get_preset_printing_policy(&decl->getASTContext(), unnamed, absolute_qualified); + string string_buffer; + llvm::raw_string_ostream stream(string_buffer); +#if CLANG_VERSION_NUMBER < VERSION_NUMBER_5_0_0 + AdjustedTypePrinter(policy, absolute_qualified, keep_typedef, elaborated_type_spec, + remove_attributes, false, 0) + .adjusted_NamedDecl_printQualifiedName(decl, stream); +#else + // Set qualified to true to force the use of printQualifiedName which will handle the suppression of + // scope if necessary. + decl->getNameForDiagnostic(stream, policy, /*qualified=*/true); +#endif + return get_with_unified_types(stream.str(), unnamed); + } + + /** Returns the textual representation of a list of template arguments. + * \param template_args The list of template arguments + * \param ctx The ASTContext + * \param absolute_qualified Add all nested name specifiers as well as the + * root qualifier (ENABLE), do not change nested name specifiers (DONOTCHANGE) + * or remove all nested name specifiers (DISABLE). + * \param keep_typedef If the type is typedef'd, keep the typedef and return + * the typedef'd type (and not the underlying type) + * \param elaborated_type_spec Add elaborated type specifier before + * class, union, and enumeration types. + * \param unnamed Do not suppress printing of unwritten scope and convert printed + * namespaces to '' + * \param remove_attributes Removes occurrences of attributes + * */ + static string get_templ_arg_list_text(const clang::TemplateArgumentList& template_args, + const clang::ASTContext* ctx, + TriStateEnableFeature absolute_qualified = TSEF_ENABLE, + bool keep_typedef = true, + TriStateEnableFeature elaborated_type_spec = TSEF_DONOTCHANGE, + bool unnamed = false, + bool remove_attributes = false + ) { + clang::PrintingPolicy policy = get_preset_printing_policy(ctx, unnamed, absolute_qualified); + string string_buffer; + llvm::raw_string_ostream stream(string_buffer); +#if CLANG_VERSION_NUMBER < VERSION_NUMBER_5_0_0 + AdjustedTypePrinter(policy, absolute_qualified, keep_typedef, elaborated_type_spec, + remove_attributes, false, ctx) + .adjusted_PrintTemplateArgumentList(stream, + template_args.data(), + template_args.size()); +#else + clang::TemplateSpecializationType::PrintTemplateArgumentList(stream, template_args.asArray(), policy); +#endif + return get_with_unified_types(stream.str(), unnamed); + } + + /** Returns the textual representation of template argument. + * \param temp_arg The template argument + * \param ctx The ASTContext + * \param absolute_qualified Add all nested name specifiers as well as the + * root qualifier (ENABLE), do not change nested name specifiers (DONOTCHANGE) + * or remove all nested name specifiers (DISABLE). + * \param keep_typedef If the type is typedef'd, keep the typedef and return + * the typedef'd type (and not the underlying type) + * \param elaborated_type_spec Add elaborated type specifier before + * class, union, and enumeration types. + * \param unnamed Do not suppress printing of unwritten scope and convert printed + * namespaces to '' + * \param remove_attributes Remove occurrences of attributes + * */ + static string get_templ_arg_text(const clang::TemplateArgument& temp_arg, + const clang::ASTContext* ctx, + TriStateEnableFeature absolute_qualified = TSEF_ENABLE, + bool keep_typedef = true, + TriStateEnableFeature elaborated_type_spec = TSEF_DONOTCHANGE, + bool unnamed = false, + bool remove_attributes = false + ) { + clang::PrintingPolicy policy = get_preset_printing_policy(ctx, unnamed, absolute_qualified); + + string temp_arg_string_buffer; + llvm::raw_string_ostream temp_arg_stream(temp_arg_string_buffer); +#if CLANG_VERSION_NUMBER < VERSION_NUMBER_5_0_0 + AdjustedTypePrinter(policy, absolute_qualified, keep_typedef, elaborated_type_spec, + remove_attributes, false, ctx) + .adjusted_TemplateArgument_print(temp_arg, temp_arg_stream); +#else + temp_arg.print(policy, temp_arg_stream); +#endif + return get_with_unified_types(temp_arg_stream.str(), unnamed); + } + + /** Returns the textual representation of a type for the use in woven code. + * \param type The type + * \param ctx The ASTContext + * \param var_name If this is unequal zero, the type is returned + * together with the given variable name + * (e.g. void(*)(int) is returned as void(*example)(int) if "example" is + * provided as variable name.) + * */ + static string get_type_code_text(clang::QualType type, const clang::ASTContext* ctx, + const char *var_name = (const char*)0 + ) { + return get_type_text(type, + ctx, + var_name, + TSEF_ENABLE, // make type absolute + true, // keep typedef if possible (to keep woven code portable) + TSEF_DONOTCHANGE, + false, // No unwritten scopes + true, // Remove __attribute__s (TODO: There are cases where we can keep them?) + false); // Do not make signature parameter type adjustments (because the result is not used for signatures) + } + + /** Returns the textual representation of a type for the use in AspectC++ signatures. + * \param type The type + * \param ctx The ASTContext + * \param var_name If this is unequal zero, the type is returned + * together with the given variable name + * (e.g. void(*)(int) is returned as void(*example)(int) if "example" is + * provided as variable name.) + * \param as_parameter_signature_type Return the type as adjusted for use in the + * signature of a function, decaying array and function types and removing top-level + * cv-qualifiers. This should be true if the type is associated to a parameter of a function. + * */ + static string get_type_sig_text(clang::QualType type, const clang::ASTContext* ctx, + const char *var_name = (const char*)0, + bool as_parameter_signature_type = false + ) { + // TODO: Common question: Always remove elaborated in signature? + return get_type_text(type, + ctx, + var_name, + TSEF_DONOTCHANGE, // Do not change nested name specifiers + false, // Remove typedefs to make matching independent of typedefs + TSEF_DISABLE, // AspectC++ signatures do not contain elaborated specifiers. TODO: Is this always true? + false, // Do not add unwritten scopes + true, // remove __attribute__s + as_parameter_signature_type); + } + + /** Returns the textual representation of a type. + * \param type The type + * \param ctx The ASTContext + * \param var_name If this is unequal zero, the type is returned + * together with the given variable name + * (e.g. void(*)(int) is returned as void(*example)(int) if "example" is + * provided as variable name.) + * \param absolute_qualified Add all nested name specifiers as well as the + * root qualifier (ENABLE), do not change nested name specifiers (DONOTCHANGE) + * or remove all nested name specifiers (DISABLE). + * \param keep_typedef If the type is typedef'd, keep the typedef and return + * the typedef'd type (and not the underlying type) + * \param elaborated_type_spec Add elaborated type specifier before + * class, union, and enumeration types. + * \param unnamed Do not suppress printing of unwritten scope and convert printed + * namespaces to '' + * \param remove_attributes Remove occurrences of attributes + * \param as_parameter_signature_type Return the type as adjusted for use in the + * signature of a function, decaying array and function types and removing top-level + * cv-qualifiers. + * */ + static string get_type_text(clang::QualType type, const clang::ASTContext* ctx, + const char *var_name = (const char*)0, + TriStateEnableFeature absolute_qualified = TSEF_ENABLE, + bool keep_typedef = true, + TriStateEnableFeature elaborated_type_spec = TSEF_DONOTCHANGE, + bool unnamed = false, + bool remove_attributes = false, + bool as_parameter_signature_type = false + ) { + + // Check invalid combinations: + assert(!(keep_typedef && elaborated_type_spec == TSEF_ENABLE) && "A typedef type can not be " + "printed together with an elaborated type specifier."); + assert(!(as_parameter_signature_type && !ctx) && "as_parameter_signature_type flag needs an ASTContext"); + // TODO: more!? + + clang::PrintingPolicy policy = get_preset_printing_policy(ctx, unnamed, absolute_qualified); + + + // Start printing: + string resulting_type_text = var_name ? var_name : ""; + + string type_string_buffer; + llvm::raw_string_ostream type_stream(type_string_buffer); +#if CLANG_VERSION_NUMBER < VERSION_NUMBER_5_0_0 + AdjustedTypePrinter(policy, absolute_qualified, keep_typedef, elaborated_type_spec, + remove_attributes, as_parameter_signature_type, ctx) + .print(type, type_stream, resulting_type_text); +#else + if(keep_typedef == false) { + // while(clang::isa(type)) { + // type = clang::dyn_cast(type)->desugar(); + // } + // Doing type = type.desugar() in a loop until we do not have a TypedefType anymore does not + // work always. Counterexample: array type with typedef'd element type. + + type = type.getCanonicalType(); + } + if(as_parameter_signature_type) { + type = ctx->getSignatureParameterType(type); + } + + type.print(type_stream, policy, resulting_type_text); +#endif + resulting_type_text = type_stream.str(); + + return get_with_unified_types(resulting_type_text, unnamed); + } + + // This static member-function checks whether the expression is a lvalue or + // xvalue and if yes returns a appropriate reference-QualType while using + // the given QualType as guideline. If not it returns a copy of the given type. + static inline clang::QualType get_reference_type_if_necessary(const clang::QualType& type, + const clang::Expr* const expression, const clang::ASTContext& context) { + if(expression->isLValue() == true) { + return context.getLValueReferenceType(type); + } + else if(expression->isXValue() == true) { + return context.getRValueReferenceType(type); + } + else { + return type; + } + } + + + static const TI_Type *of (const ACM_Type &loc) { + return static_cast(loc.transform_info ()); + } +}; + +class TI_Namespace : public TransformInfo { + // pointer to the Clang namespace object (for transformation) + clang::NamespaceDecl *_decl; +public: + void decl (clang::NamespaceDecl *n) { _decl = n; } + virtual clang::NamespaceDecl *decl () const { return _decl; } +}; + +class TI_Class : public TransformInfo { + clang::RecordDecl *_decl; + clang::SourceLocation _lbrace_loc; + bool _has_replaced_arrays; + + static void get_member_contexts (const clang::RecordDecl *decl, + list &member_contexts) { + + for (clang::RecordDecl::field_iterator i = decl->field_begin (); + i != decl->field_end (); ++i) { + + // Only certain members are delivered. + // If this is not the right choice for all use case, add filter flags to + // the argument list of this function + clang::FieldDecl *attr = *i; + if (attr->getNameAsString ().empty ()) { + const clang::RecordType *UT = attr->getType ()->getAsUnionType (); + if (UT) { // members of anonymous unions in a record are also record members + get_member_contexts (UT->getDecl (), member_contexts); + } + continue; + } +// if (attr->isStatic () || attr->isAnonymous () || attr->EnumeratorInfo ()) +// continue; + + member_contexts.push_back (ClangSyntacticContext (attr)); + } + } + +public: + TI_Class () : _decl (0), _has_replaced_arrays( false ) {} + + bool valid () const { return _decl != 0; } + + void decl (clang::RecordDecl *c) { _decl = c; } + virtual clang::RecordDecl *decl () const { return _decl; } + + void set_lbrace_loc(clang::SourceLocation loc) { _lbrace_loc = loc; } + + SyntacticContext get_def_context () const { return SyntacticContext (_decl); } + + void get_member_contexts (list &member_contexts) const { + get_member_contexts (_decl, member_contexts); + } + + enum SMKind { CONSTRUCTOR, COPY_CONSTRUCTOR, DESTRUCTOR }; + bool may_have_implicit (SMKind kind) { + return may_have_implicit (kind, _decl); + } + + bool may_have_implicit (SMKind kind, const clang::RecordDecl *decl) { + const clang::CXXRecordDecl *d = llvm::cast(decl); + if (!d) + return false; + if (kind == CONSTRUCTOR || kind == COPY_CONSTRUCTOR) { + for (clang::CXXRecordDecl::ctor_iterator i = d->ctor_begin (); + i != d->ctor_end (); ++i) { + clang::CXXConstructorDecl *cd = *i; + if (kind == CONSTRUCTOR && cd->isDefaultConstructor () && + cd->getAccess () == clang::AS_private) + return false; + if (kind == COPY_CONSTRUCTOR && cd->isCopyConstructor () && + cd->getAccess () == clang::AS_private) + return false; + } + } + else { // destructor + const clang::CXXDestructorDecl *dd = d->getDestructor (); + if (dd && kind == DESTRUCTOR && dd->getAccess () == clang::AS_private) + return false; + } + + for (clang::CXXRecordDecl::base_class_const_iterator i = d->bases_begin (); + i != d->bases_end (); ++i) { + const clang::CXXRecordDecl *bd = (*i).getType ()->getAsCXXRecordDecl (); + if (bd && !may_have_implicit (kind, bd)) + return false; + } + + for (clang::CXXRecordDecl::field_iterator i = d->field_begin (); + i != d->field_end (); ++i) { + const clang::FieldDecl *attr = *i; + const clang::CXXRecordDecl *rd = attr->getType ()->getAsCXXRecordDecl (); + if (rd && !may_have_implicit (kind, rd)) + return false; + } + return true; + } + + // remember if planing found advice for the builtin_copy constructor + void remember_builtin_copyconstructor_advice() { + // if the constructor advice can be woven (parallel check to begining of CodeWeaver::gen_special_member_function) + if( may_have_implicit( TI_Class::COPY_CONSTRUCTOR ) ) + _has_replaced_arrays = true; // remember that replacement will be done, to assure it is considerd when weaving on other joinpoints (array access) + } + bool has_replaced_arrays() const { return _has_replaced_arrays; } + + // return the position behind the opening bracket of the class body + const WeavePos &body_start_pos (WeaverBase &wb) const { + // TODO: iterating over all decls and finding the one with the smallest + // location is a terribly comlicated solution. However, I haven't found + // a way to get the location of the opening bracket. +#if 0 + clang::SourceLocation min_loc; + for (clang::DeclContext::decl_iterator i = _decl->decls_begin (); + i != _decl->decls_end (); ++i) { + clang::SourceLocation cur_loc = (*i)->getLocStart(); + if ((*i)->isImplicit () || !cur_loc.isValid ()) + continue; + if (!min_loc.isValid () || (cur_loc < min_loc)) + min_loc = (*i)->getLocStart(); + } + if (min_loc.isValid ()) + return wb.weave_pos(min_loc, WeavePos::WP_BEFORE); + else + return wb.weave_pos(_decl->getRBraceLoc(), WeavePos::WP_BEFORE); +#endif + assert (_lbrace_loc.isValid()); + return wb.weave_pos(_lbrace_loc.getLocWithOffset(1), WeavePos::WP_AFTER); + } + + // return the position in front of the closing bracket of the class body + const WeavePos &body_end_pos (WeaverBase &wb) const { +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_3_9_1 + return wb.weave_pos(_decl->getBraceRange().getEnd(), WeavePos::WP_BEFORE); +#else + return wb.weave_pos(_decl->getRBraceLoc(), WeavePos::WP_BEFORE); +#endif + } + + // return the position of the first token of the class definition + const WeavePos &objdecl_start_pos (WeaverBase &wb) const { + return wb.weave_pos (_decl->getLocStart(), WeavePos::WP_BEFORE); + } + + // return the position after the ";" of the class definition + const WeavePos &objdecl_end_pos (WeaverBase &wb) const { + // FIXME: This relies on the lack of spaces between the closing '}' and ';'. + return wb.weave_pos (_decl->getLocEnd().getLocWithOffset(1), WeavePos::WP_AFTER); + } + + // check whether this is a class and not a struct + bool is_class () const { return _decl->isClass(); } + + // check whether this is a struct (more restrictive than 'is_class') + bool is_struct () const { return _decl->isStruct(); } + + // check whether the class is defined (=has a body) and not only declared + bool is_defined () const { return _decl->isCompleteDefinition (); } + + // checks whether this class is a template *instance* + bool is_template_instance () const { + const clang::CXXRecordDecl *d = llvm::cast(_decl); + return d && isTemplateInstantiation (d); + } + + // check whether the class is defined in a extern "C" block + bool is_extern_c () const { + return is_extern_c (_decl); + } + + static bool is_extern_c (clang::RecordDecl *d) { + clang::DeclContext *dc = d; + while (dc->getDeclKind() != clang::Decl::TranslationUnit) { + if (dc->getDeclKind() == clang::Decl::LinkageSpec) + return clang::cast(dc)->getLanguage() == + clang::LinkageSpecDecl::lang_c; + dc = dc->getParent(); + } + return false; + // Future clang versions will support this: return _decl->isExternCContext (); + // TODO: current version support now: return d->isExternCContext(); + } + + // checks whther the class is defined within a template instance + bool is_in_template_instance () const { return inside_template_instance(_decl); } + + static string name(clang::RecordDecl *ci) { + return TI_Type::get_decl_name_text(ci, TSEF_DISABLE, false, TSEF_DISABLE, false, true); + } + + static TI_Class *of (const ACM_Class &loc) { + return static_cast(loc.transform_info ()); + } +}; + +class TI_Aspect : public TI_Class { +public: + + clang::FunctionDecl *aspectof () const { + + clang::CXXRecordDecl *d = llvm::cast(decl()); + for (clang::CXXRecordDecl::decl_iterator di = d->decls_begin(), + de = d->decls_end(); + di != de; ++di) { + clang::NamedDecl *nd = llvm::dyn_cast (*di); + if (!nd) + continue; + std::string name = nd->getNameAsString(); + if (name != "aspectof" && name != "aspectOf") + continue; + if (nd->getKind () == clang::Decl::FunctionTemplate) + return llvm::dyn_cast(nd)->getTemplatedDecl (); + else if (nd->getKind () == clang::Decl::CXXMethod) + return llvm::dyn_cast(nd); + } + return 0; + } + + static const TI_Aspect *of (const ACM_Aspect &loc) { + return static_cast(loc.transform_info ()); + } + +}; + +class TI_Function : public TransformInfo { + mutable vector _contexts; + clang::FunctionDecl *_decl; +public: + + const vector &syntactic_contexts () const { + if (_contexts.size() == 0) { + // Store a pointer to each declaration and the definition (if one exists) + for (clang::FunctionDecl::redecl_iterator ri = _decl->redecls_begin(), + re = _decl->redecls_end(); + ri != re; ++ri) + _contexts.push_back(ClangSyntacticContext(*ri)); + } + return _contexts; + } + + void decl (clang::FunctionDecl *c) { _decl = c; } + virtual clang::FunctionDecl *decl () const { return _decl; } + void add_decl (clang::FunctionDecl *c) { + _contexts.push_back(ClangSyntacticContext(c)); + } + + static string name(clang::FunctionDecl *func_info) { + string out; + + clang::CXXConversionDecl *conv = + llvm::dyn_cast_or_null(func_info); + if (conv) { + clang::ASTContext &ctx = func_info->getASTContext(); + clang::QualType t = conv->getConversionType (); + out = "operator "; + out += TI_Type::get_type_sig_text(t, &ctx, 0, true); + return out; + } + + out = func_info->getNameAsString(); + // Add a space after "operator" for Puma compatibility. + if (out.size() > 8 && llvm::StringRef(out).startswith("operator") && + out[8] != ' ' && out[8] != '_' && !isalnum(out[8])) + out.insert(out.begin() + 8, ' '); + + clang::FunctionTemplateSpecializationInfo *ftsi = + func_info->getTemplateSpecializationInfo (); + if (ftsi) { + if (out[out.length() - 1] == '<') // e.g. operator << + out += " "; + out += TI_Type::get_templ_arg_list_text(*ftsi->TemplateArguments, + &func_info->getASTContext(), + TSEF_DONOTCHANGE, + false, + TSEF_DISABLE, + false, + true); + } + return out; + } + + static string signature(clang::FunctionDecl *func_info) { + std::string str; + llvm::raw_string_ostream out(str); + clang::ASTContext &ctx = func_info->getASTContext(); + + out << '('; + for (clang::FunctionDecl::param_iterator i = func_info->param_begin(), + e = func_info->param_end(); + i != e; ++i) { + if (i != func_info->param_begin()) + out << ','; + out << TI_Type::get_type_sig_text((*i)->getType(), &ctx, 0, true); + } + out << ')'; + + // add CV qualifiers + if (clang::CXXMethodDecl *m = + llvm::dyn_cast(func_info)) { + if (m->isConst()) + out << " const"; + if (m->isVolatile()) + out << " volatile"; + } + + return name(func_info) + out.str (); + } + + bool is_const () const { + clang::CXXMethodDecl *m = llvm::dyn_cast(_decl); + return m && m->isConst (); + } + + bool is_conversion_operator () const { + return (llvm::dyn_cast_or_null(_decl) != 0); + } + + static const TI_Function *of (const ACM_Function &loc) { + return static_cast(loc.transform_info ()); + } +}; + +class TI_Variable : public TransformInfo { + clang::DeclaratorDecl *_decl; +public: + TI_Variable () : _decl (0) {} + + void decl (clang::DeclaratorDecl *oi) { _decl = oi; } + virtual clang::DeclaratorDecl *decl () const { return _decl; } +public: + static const TI_Variable *of (const ACM_Variable &loc) { + return static_cast(loc.transform_info ()); + } +}; + + +class TI_Arg : public TransformInfo { + clang::QualType _type; +public: + void type (clang::QualType ti) { _type = ti; } + clang::QualType type () const { return _type; } + + virtual clang::Decl *decl () const { return 0; } + + static const TI_Arg *of (const ACM_Arg &loc) { + return static_cast(loc.transform_info ()); + } +}; + +class TI_Code : public TransformInfo { + bool _is_planned; + bool _has_implicit; + CFlowList _triggers; +public: + TI_Code() : _is_planned( false ), _has_implicit( false ) {}; + + // remember if this joinpoint is planned for weaving + // ( decisions for other joinpoints depend on this info ) + void remember_planned() { _is_planned = true; } + bool is_planned() { return _is_planned; } + + // remember implicit joinpoints needing to be considered + void remember_implicit() { _has_implicit = true; } + bool has_implicit_joinpoints() { return _has_implicit; } + + // consider a necessary cflow trigger at this join point + bool consider (const CFlow &cflow) { + _triggers.push_back (cflow); + return true; + } + + // return the list of cflows that must be entered/left here + const CFlowList &cflows () const { return _triggers; } + + // that types (for the JoinPoint-API) + virtual std::string that_type_string () const { return "void"; } + + // target type (for the JoinPoint-API) + virtual std::string target_type_string () const { return "void"; } + + // argument type (for the JoinPoint-API) + virtual std::string arg_type_string (unsigned no) const { return "void"; } + + // entity type (for the JoinPoint-API) + virtual std::string entity_type_string() const { + return format_type( decl() ); + } + + // helper functions for derived classes + static std::string get_type_string (const clang::NamedDecl *obj, bool normalise = false) { + + // if the 'obj' refers to a record or member function, we have to print a record 'r' + const clang::CXXRecordDecl *r = llvm::dyn_cast(obj); + const clang::CXXMethodDecl *m = llvm::dyn_cast(obj); + if (m) + r = m->getParent (); + + if (!r) + if (const clang::ParmVarDecl *pd = llvm::dyn_cast(obj)) + r = pd->getType()->getAsCXXRecordDecl(); + + if (r) { + string qualifiers; + if (m) { + // preserve const volatile qualifiers of member functions + // we could also print m->getThisType(obj->getASTContext()) + if(m->isConst()) + qualifiers = "const "; + if (m->isVolatile()) + qualifiers = "volatile "; + } + return qualifiers + TI_Type::get_decl_name_text(r, TSEF_ENABLE, true, TSEF_DONOTCHANGE, false, true); + } + else if (const clang::ParmVarDecl *pd = llvm::dyn_cast(obj)) { + return TI_Type::get_type_code_text(pd->getType(), &obj->getASTContext(), 0); + } + else + return "void"; + } + + static std::string format_type( clang::Decl *obj ) { + clang::ValueDecl *typed_obj = llvm::dyn_cast_or_null( obj ); + if( ! typed_obj ) + return "void"; + + return format_type( typed_obj->getType(), obj->getASTContext() ); + } + + static std::string format_type( clang::QualType type, clang::ASTContext& ctx ) { + return TI_Type::get_type_code_text(type, &ctx, 0); + } + + static TI_Code *of (const ACM_Code &loc) { + return static_cast(loc.transform_info ()); + } +}; + +class TI_Method : public TI_Code { + clang::FunctionDecl *_decl; + +public: + TI_Method () : _decl (0) {} + + void decl (clang::FunctionDecl *f) { _decl = f; } + virtual clang::Decl *decl () const { return _decl; } + + // that type (for the JoinPoint-API) + virtual std::string that_type_string() const { + return get_type_string(_decl); + } + + // target type (for the JoinPoint-API) + virtual std::string target_type_string() const { + return get_type_string(_decl); + } + + virtual std::string arg_type_string (unsigned no) const { + return get_type_string (_decl->getParamDecl (no), true); + } +}; + +// forward declaring child class, as we need to reference the pointer type already +// class TI_Builtin : public TI_Access +class TI_Builtin; + +class TI_Access : public TI_Code { +private: + clang::DeclaratorDecl *_entity; + + clang::Expr *_node; + clang::Expr *_ref_node; + + clang::Decl *_origin; + + clang::Expr *_target_expr; +public: + TI_Access() : _entity(0), _node(0), _ref_node(0), _origin(0), _target_expr(0) {} + +protected: // make setter protected as derived class might need one with different signature + void entity( clang::DeclaratorDecl *ent ) { _entity = ent; } +public: + clang::DeclaratorDecl *entity() const { return _entity; } + virtual clang::Decl *decl() const { return _entity; } // defined in TransformInfo + + bool entity_is_const() const { return false; } + +protected: // make setter protected as derived class might need one with different signature + void tree_node( clang::Expr *n ) { _node = n; }; +public: + clang::Expr *tree_node() const { return _node; }; + + void ref_node( clang::Expr *ref ) { + _ref_node = ref; + + _target_expr = find_target_expr(); // init caching var + }; + clang::Expr *ref_node() const { return _ref_node; }; + + // checks if the original access uses a qualified target entity name + bool is_qualified () const { + clang::MemberExpr *me = clang::dyn_cast_or_null( _ref_node ); + if (me && me->hasQualifier()) + return true; + clang::DeclRefExpr *dre = clang::dyn_cast_or_null( _ref_node ); + if (dre && dre->hasQualifier()) + return true; + return false; + } + + void origin( clang::Decl *o ) { _origin = o; } + clang::Decl *origin() const { return _origin; } + + bool target_is_ptr() const { return _target_expr && _target_expr->getType().getTypePtr()->isPointerType(); } + bool target_is_implicit() const { return _target_expr && _target_expr->isImplicitCXXThis(); } + bool target_is_const() const { + if (!_target_expr) + return false; + // in case of calls to const member functions Clang adds an implicit cast that turn the object + // into a const object even if it was non-const. So we have to ignore implicit casts here. + clang::Expr *real_target = _target_expr->IgnoreImpCasts (); + // now check whether the object type was const before any implicit casts + clang::QualType t = real_target->getType(); + // if the target is a pointer we need check the object's const-ness and ignore the pointer. + if (t.getTypePtr()->isPointerType()) + t = t.getTypePtr()->getPointeeType(); + return t.isConstQualified (); + } + bool has_target_expr() const { return _target_expr && ! target_is_implicit(); } + clang::Expr *target_expr() const { + if( ! target_is_implicit() ) // by convention only explicit expr are returned + return _target_expr; + else + return 0; + } + // no setter as it is done internally + virtual clang::Expr *find_target_expr() const { + // analog to clang::CXXMemberCallExpr::getImplicitObjectArgument() + if( const clang::MemberExpr *member = llvm::dyn_cast( _ref_node ) ) + return member->getBase()->IgnoreImpCasts(); + else if( const clang::BinaryOperator *op = llvm::dyn_cast( _ref_node ) ) + if( op->getOpcode() == clang::BO_PtrMemD || op->getOpcode() == clang::BO_PtrMemI ) + return op->getLHS(); + + return 0; + } + + // target type (for the JoinPoint-API) + virtual const clang::RecordDecl *target_class () const = 0; + // type of target expr (for qualifing names, might differ from target_class) + virtual const clang::RecordDecl *targetexpr_class() const = 0; + const clang::RecordDecl *defining_class() const { return clang::dyn_cast( _entity->getDeclContext() ); } + + const bool entity_from_baseclass() const { + const clang::CXXRecordDecl *defining = llvm::dyn_cast_or_null( defining_class() ); + const clang::CXXRecordDecl *target = llvm::dyn_cast_or_null( target_class() ); + return defining && target && target->isDerivedFrom( defining ); + } + + static TI_Access *of( const ACM_Access &loc ) { + return static_cast( loc.transform_info() ); + } + + const SyntacticContext access_context () const { return SyntacticContext( _origin ); } + const SyntacticContext entity_context () const { return SyntacticContext( _entity ); } + + // that type (for the JoinPoint-API) + virtual std::string that_type_string() const { + if( clang::CXXMethodDecl *m = llvm::dyn_cast( _origin ) ) + return get_type_string( m->getParent() ); + else if( clang::VarDecl *vd = llvm::dyn_cast( _origin ) ) + if( clang::CXXRecordDecl *r = llvm::dyn_cast( vd->getDeclContext() ) ) + return get_type_string( r ); + return "void"; + } + + // target type (for the JoinPoint-API) + virtual std::string target_type_string() const { + const clang::NamedDecl *tc = target_class(); + return ( tc ? get_type_string( tc ) : string( "void" )); + } + + // type of target expr (for qualifing names, might differ from target_class) + virtual std::string targetexpr_type_string() const { + const clang::NamedDecl *tc = targetexpr_class(); + return ( tc ? get_type_string( tc ) : string( "void" )); + } + + virtual bool has_result() const = 0; + virtual clang::QualType result_type() const = 0; + virtual std::string result_type_string() const { return format_type( result_type(), _origin->getASTContext() ); } + + virtual unsigned int entity_index_count() const { return 0; } // derived override if they have indices + virtual unsigned long int entity_index_dimension( unsigned int i ) const { return 0; } // derived override if they have indices + virtual std::string entity_index_type( unsigned int i ) const { return "void"; } // derived override if they have indices + virtual TI_Builtin *entity_src() const { return 0; } + enum SpliceMode { SpliceMode_None, SpliceMode_Packed, SpliceMode_Pack, SpliceMode_FullSplice }; + virtual SpliceMode entity_src_splice_mode() const { return SpliceMode_None; } + + static const clang::Expr * skipTransparent( const clang::Expr * start ) { + const clang::Expr *oldE = start; + const clang::Expr *newE = start->IgnoreImplicit()->IgnoreParens(); + while( oldE != newE ) { + oldE = newE; + if( const clang::BinaryOperator *bo = llvm::dyn_cast( newE ) ) { + if( bo->getOpcode() == clang::BO_Comma ) // jump inside right part as this is the relevant part for the joinpoint in the parent + newE = bo->getRHS(); + } + newE = newE->IgnoreImplicit()->IgnoreParens(); + } + return newE; + } + + virtual const WeavePos &before_pos (WeaverBase &wb) { + // jump into parenthesis and ignore exprs that don't change anything + // cant do this early (or _node in general as ImplicitCast can be skipped here but not for type compuatations) + return wb.weave_pos( skipTransparent( _node )->getLocStart(), WeavePos::WP_BEFORE ); + } + virtual const WeavePos &after_pos (WeaverBase &wb) { + // jump into parenthesis and ignore exprs that don't change anything + // cant do this early (or _node in general as ImplicitCast can be skipped here but not for type compuatations) + return get_pos_after_token( skipTransparent( _node )->getLocEnd(), wb ); + } + const WeavePos &entity_before_pos( WeaverBase &wb ) { + return wb.weave_pos( ref_node()->getLocStart(), WeavePos::WP_BEFORE ); + } + const WeavePos &entity_after_pos( WeaverBase &wb ) { + return get_pos_after_token( ref_node()->getLocEnd(), wb, WeavePos::WP_AFTER ); + } + const WeavePos &entity_op_before_pos( WeaverBase &wb ) { + assert( clang::isa( ref_node() ) ); + clang::MemberExpr *me = clang::dyn_cast( ref_node() ); + // clang3.4 seems to miss getOperatorLoc() + //return wb.weave_pos( me->getOperatorLoc(), WeavePos::WP_BEFORE ); + return get_pos_after_token( me->getBase()->getLocEnd(), wb, WeavePos::WP_BEFORE ); + } + const WeavePos &entity_op_after_pos( WeaverBase &wb ) { + assert( clang::isa( ref_node() ) ); + clang::MemberExpr *me = clang::dyn_cast( ref_node() ); + if( me->hasQualifier() ) + return wb.weave_pos( me->getQualifierLoc().getBeginLoc(), WeavePos::WP_AFTER ); + else + return wb.weave_pos( me->getMemberLoc(), WeavePos::WP_AFTER ); + } + + struct PH : public clang::PrinterHelper { + virtual bool handledStmt (clang::Stmt *node, llvm::raw_ostream &os) { + clang::CXXOperatorCallExpr *ce = clang::dyn_cast (node); + clang::FunctionDecl *fd = (ce ? ce->getDirectCallee () : 0); + if (ce && ce->getNumArgs () == 1 && + fd->getNameAsString () == "operator->") { + clang::ASTContext &ctx = fd->getASTContext(); + os << "("; + ce->getArg (0)->printPretty(os, this, ctx.getPrintingPolicy(), 0); + os << ").operator->()"; + return true; + } + // WORKAROUND for Clang 3.4 problem: + // Implicit calls to conversion operators are printed explicitly, but + // the object argument is not put into brackets. For example: + // "a & b" might become "a & b.operator int()" + // This fix generates the brackets: "(a & b).operator int()" + clang::CXXMemberCallExpr *mce = clang::dyn_cast (node); + fd = (mce ? mce->getDirectCallee () : 0); + if (fd && clang::dyn_cast(fd)) { + clang::MemberExpr *me = clang::dyn_cast(mce->getCallee ()); + if (me) { + os << "("; + clang::ASTContext &ctx = fd->getASTContext(); + me->getBase ()->printPretty(os, this, ctx.getPrintingPolicy(), 0); + os << ")" << (me->isArrow () ? "->" : "."); + os << TI_Function::name(fd) << "()"; + return true; + } + } + return false; + } + }; + + virtual string code () const { + PH ph; + clang::ASTContext &ctx = _origin->getASTContext(); + std::string buf; + llvm::raw_string_ostream out (buf); + _node->printPretty(out, &ph, ctx.getPrintingPolicy(), 0); + return buf; + } + + // returns true if the access needs special rights + bool needs_rights () const { + // no member function => no accessibility problem + if( ! target_class() ) + return false; + + // static member => no problem only if public + clang::CXXMethodDecl *md = clang::dyn_cast(_entity); + clang::VarDecl *vd = clang::dyn_cast(_entity); + if ((md && md->isStatic ()) || (vd && vd->isStaticDataMember ())) + return (_entity->getAccess () != clang::AS_public); + + // normal member function => look up the accessibility + const clang::CXXRecordDecl *base = clang::dyn_cast( defining_class() ); + const clang::CXXRecordDecl *target = clang::dyn_cast(target_class ()); + clang::CXXBasePaths paths; + if (target->isDerivedFrom (base, paths)) { + for (clang::CXXBasePaths::const_paths_iterator i = paths.begin (); i != paths.end (); ++i) + if (i->Access != clang::AS_public) + return true; + } + + if( _entity->getAccess () == clang::AS_public ) + return false; + + return true; + } +}; + +// This abstract class represents a call in general and exists just as interface for +// actions that are (mostly) the same between calls of user-defined (member-)functions +// and calls of built-in operators. +class TI_CommonCall : public TI_Access { +protected: + TI_CommonCall () {} +public: + virtual string operator_kind_string() const = 0; + + virtual const clang::Expr* arg(unsigned int index) const = 0; + virtual unsigned int arg_count() const = 0; + + virtual bool is_unary_expr() const = 0; + virtual bool is_binary_expr() const = 0; + virtual bool is_ternary_expr() const = 0; + virtual bool is_postfix_expr() const = 0; + virtual bool is_index_expr() const = 0; + virtual bool is_arrow_class_member_access_expr() const = 0; + virtual bool is_implicit_conversion() const = 0; + virtual bool is_implicit_dereference() const = 0; + + virtual clang::SourceLocation get_operator_location() const = 0; + + // returns the position directly in front of the operator + virtual const WeavePos &op_before_pos (WeaverBase &wb) { + return wb.weave_pos(get_operator_location(), WeavePos::WP_BEFORE); + } + + // returns the position directly behind the operator + virtual const WeavePos &op_after_pos (WeaverBase &wb) { + return get_pos_after_token(get_operator_location(), wb); + } + + // The following member-functions may be called if is_index_expr() is true + // returns the position directly in front of the opening bracket [ + virtual const WeavePos &index_open_before_pos (WeaverBase &wb) { + assert (is_index_expr ()); + return get_pos_after_token(arg(0)->getLocEnd(), wb, WeavePos::WP_BEFORE); + } + // returns the position directly behind the opening bracket [ + virtual const WeavePos &index_open_after_pos (WeaverBase &wb) { + assert (is_index_expr ()); + return wb.weave_pos(arg(1)->getLocStart (), WeavePos::WP_AFTER); + } + // returns the position directly in front of the closing bracket ] + virtual const WeavePos &index_close_before_pos (WeaverBase &wb) { + assert (is_index_expr ()); + return get_pos_after_token(arg(1)->getLocEnd (), wb, WeavePos::WP_BEFORE); + } + // returns the position directly behind the closing bracket ] + virtual const WeavePos &index_close_after_pos (WeaverBase &wb) { + assert (is_index_expr ()); + return get_pos_after_token(TI_Access::tree_node()->getLocEnd (), wb, WeavePos::WP_AFTER); + } + + // The following member-functions return the corresponding weave-positions of ternary operators + // (first delimiter = "?", second delimiter = ":") + virtual const WeavePos& ternary_op_first_delim_before_pos(WeaverBase &wb) { + assert (is_ternary_expr()); + return get_pos_after_token(arg(0)->getLocEnd(), wb, WeavePos::WP_BEFORE); + } + virtual const WeavePos& ternary_op_first_delim_after_pos(WeaverBase &wb) { + assert (is_ternary_expr()); + return wb.weave_pos(arg(1)->getLocStart(), WeavePos::WP_AFTER); + } + virtual const WeavePos& ternary_op_second_delim_before_pos(WeaverBase &wb) { + assert (is_ternary_expr()); + return get_pos_after_token(arg(1)->getLocEnd(), wb, WeavePos::WP_BEFORE); + } + virtual const WeavePos& ternary_op_second_delim_after_pos(WeaverBase &wb) { + assert (is_ternary_expr()); + return wb.weave_pos(arg(2)->getLocStart(), WeavePos::WP_AFTER); + } +}; + +class TI_MethodCall : public TI_CommonCall { + clang::FunctionDecl *_called_func; +public: + TI_MethodCall() : _called_func( 0 ) {} + + void called (clang::FunctionDecl *f) { _called_func = f; entity( f ); } + clang::FunctionDecl *called () const { return _called_func; } + + void tree_node( clang::Expr *n ) { + // In this class the node-object always has the type clang::CallExpr* + assert(!n || llvm::isa(n)); + TI_Access::tree_node( n ); + if( n ) { + ref_node( static_cast(n)->getCallee()->IgnoreParenImpCasts() ); + } + } + + // In this class the node-object always has the type clang::CallExpr* + const clang::CallExpr* tree_node() const { + assert(llvm::isa(TI_Access::tree_node())); + return static_cast(TI_Access::tree_node()); + } + + static TI_MethodCall *of (const ACM_Call &loc) { + return static_cast(loc.transform_info ()); + } + + bool uses_ADN_lookup () const { + return (_called_func && + _called_func->getLexicalDeclContext () != _called_func->getDeclContext () && + _called_func->getFriendObjectKind () != clang::Decl::FOK_None); + } + + virtual string operator_kind_string() const { + if( clang::CXXOperatorCallExpr *oc =llvm::dyn_cast( TI_Access::tree_node() ) ) + return oc->getDirectCallee ()->getNameAsString ().substr (8); + + assert( false && "Unknown expr type" ); + return ""; // dummy + } + + static unsigned int arg_count( const clang::CallExpr *node ) { + unsigned int args = node->getNumArgs(); + // for calls to % T::operator() (...) on an object t of type T, + // e.g t(42), Clang says that the number of args is 2. In AspectC++ we + // regard t is the target pointer and only 42 as an argument. + if (is_call_op(node)) + args--; + return args; + } + + virtual unsigned int arg_count() const { + return arg_count( tree_node() ); + } + + // This method takes an argument-index as unsigned int and returns the correspondent argument-clang::Expr-pointer. + static const clang::Expr* arg( const clang::CallExpr *node, unsigned int index ) { + // for calls to % T::operator() (...) on an object t of type T, + // e.g t(42), Clang says that the number of args is 2. In AspectC++ we + // regard t is the target pointer and only 42 as an argument. + if (is_call_op(node)) + index++; + return node->getArg(index); + } + + // This method takes an argument-index as unsigned int and returns the correspondent argument-clang::Expr-pointer. + virtual const clang::Expr* arg(unsigned int index) const { + return arg( tree_node(), index ); + } + + static std::string arg_type_string( const clang::CallExpr *node, clang::ASTContext &ctx, unsigned no ) { + return TI_Type::get_type_code_text(arg( node, no )->getType(), &ctx, 0); + } + + virtual std::string arg_type_string (unsigned no) const { + // If the requested argument is no variadic argument we take it + // from the function declaration: + if( no < _called_func->getNumParams () ) + return get_type_string (_called_func->getParamDecl (no), true); + + assert(_called_func->isVariadic()); + // Otherwise we take it from the call expression: + clang::ASTContext &ctx = origin()->getASTContext(); + return arg_type_string( tree_node(), ctx, no ); + } + + bool is_operator_call() const { + return llvm::isa( TI_Access::tree_node() ); + } + + virtual bool is_unary_expr () const { + clang::CXXOperatorCallExpr *ce = clang::dyn_cast (TI_Access::tree_node()); + return (ce && ce->getNumArgs () == 1 && !is_call_op()); + } + + virtual bool is_binary_expr () const { + clang::CXXOperatorCallExpr *ce = clang::dyn_cast (TI_Access::tree_node()); + return (ce && ce->getNumArgs () == 2 && !is_index_expr () && !is_postfix_expr () && !is_call_op()); + } + + virtual bool is_index_expr () const { + clang::CXXOperatorCallExpr *ce = clang::dyn_cast (TI_Access::tree_node()); + return (ce && ce->getNumArgs () == 2 && _called_func->getNameAsString () == "operator[]"); + } + + virtual bool is_postfix_expr () const { + clang::CXXOperatorCallExpr *ce = clang::dyn_cast (TI_Access::tree_node()); + return (ce && ce->getNumArgs () == 2 && + (_called_func->getNameAsString () == "operator++" || + _called_func->getNameAsString () == "operator--")); + } + + virtual bool is_arrow_class_member_access_expr() const { + return _called_func->getNameAsString () == "operator->"; + } + + virtual bool is_ternary_expr() const { + return false; + } + + virtual bool is_implicit_conversion () const { + if (!llvm::isa (_called_func)) + return false; + clang::CXXMemberCallExpr *mce = clang::dyn_cast( TI_Access::tree_node() ); + if (!mce) + return false; + // TODO: is there a better way to distinguish 'c' from 'c.operator int*()'? + return (mce->getCallee ()->getLocEnd () == TI_Access::tree_node()->getLocEnd ()); + } + + virtual bool is_implicit_dereference() const { + return false; + } + + static bool is_call_op (const clang::CallExpr *node) { + return (clang::dyn_cast(node) && + node->getDirectCallee ()->getNameAsString () == "operator()"); + } + + bool is_call_op () const { + return is_call_op (tree_node()); + } + + // This method returns the clang::SourceLocation of the operator according to the operator-type. + virtual clang::SourceLocation get_operator_location() const { + if( clang::CXXOperatorCallExpr *ce = clang::dyn_cast ( TI_Access::tree_node() ) ) + return ce->getOperatorLoc (); + + assert( false && "This is no operator." ); + return TI_Access::tree_node()->getLocStart(); // dummy + } + + const WeavePos &args_open_before_pos (WeaverBase &wb) { + if (is_call_op ()) + return wb.weave_pos (tree_node()->getCallee ()->getLocStart (), WeavePos::WP_BEFORE); + else + return get_pos_after_token(tree_node()->getCallee ()->getLocEnd (), wb, WeavePos::WP_BEFORE); + } + + const WeavePos &args_open_after_pos (WeaverBase &wb) { + if (call_args () > 0) + return wb.weave_pos (arg (0)->getLocStart (), WeavePos::WP_AFTER); + else + return wb.weave_pos (TI_Access::tree_node()->getLocEnd (), WeavePos::WP_AFTER); + } + + const WeavePos &args_close_before_pos (WeaverBase &wb) { + return wb.weave_pos(TI_Access::tree_node()->getLocEnd (), WeavePos::WP_BEFORE); + } + + const WeavePos &args_close_after_pos (WeaverBase &wb) { + return get_pos_after_token(TI_Access::tree_node()->getLocEnd (), wb, WeavePos::WP_AFTER); + } + + const WeavePos &callee_before_pos (WeaverBase &wb) { + if (has_target_expr()) { + const clang::Expr *callee = tree_node()->getCallee (); + while (clang::dyn_cast (callee)) + callee = clang::dyn_cast (callee)->getSubExpr (); + while (clang::dyn_cast (callee)) + callee = clang::dyn_cast (callee)->getSubExpr (); + const clang::MemberExpr *me = clang::dyn_cast (callee); + assert (me); + return get_pos_after_token(me->getBase ()->getLocEnd (), wb, WeavePos::WP_BEFORE); + } + else { + if (is_call_op ()) + return wb.weave_pos (TI_Access::tree_node()->getLocStart (), WeavePos::WP_BEFORE); + else + return wb.weave_pos (tree_node()->getCallee ()->getLocStart (), WeavePos::WP_BEFORE); + } + } + + const WeavePos &callee_after_pos (WeaverBase &wb) { + if (is_call_op ()) + return wb.weave_pos (tree_node()->getCallee ()->getLocStart (), WeavePos::WP_AFTER); + else { + const clang::Expr *callee = tree_node()->getCallee (); + while (clang::dyn_cast (callee)) + callee = clang::dyn_cast (callee)->getSubExpr (); + return get_pos_after_token(callee->getLocEnd (), wb, WeavePos::WP_AFTER); + } + } + + // return the number of arguments, not including the object in case of + // member function calls and not including implicitly passed default arguments + unsigned call_args () const { + unsigned args = 0; + const clang::CallExpr* call_node = tree_node(); + while (args < call_node->getNumArgs ()) { + if( clang::dyn_cast( call_node->getArg( args ) ) ) + break; + args++; + } + // in case of calls to operator() the number has to be decremented once + if (is_call_op()) + args--; + return args; + } + + virtual bool has_result () const { + return !_called_func->getReturnType()->isVoidType (); + } + + virtual clang::QualType result_type() const { + return _called_func->getReturnType (); + } + + // target type (for the JoinPoint-API) + virtual const clang::RecordDecl *target_class () const { + return targetexpr_class(); + } + + virtual const clang::RecordDecl *targetexpr_class () const { + const clang::RecordDecl *result = 0; + + const clang::CXXMethodDecl *md = clang::dyn_cast_or_null (_called_func); + if( has_target_expr() ) { + const clang::Type *type = target_expr()->getType ().getTypePtr (); + result = type->getPointeeCXXRecordDecl(); + if (!result) + result = type->getAsCXXRecordDecl (); + } + else if (md) { + result = md->getParent(); + if (clang::CXXMethodDecl *caller = llvm::dyn_cast(origin())) { + if (!md->isStatic()) + result = caller->getParent (); + } + } + return result; + } + + // the target object of the call or NULL + virtual clang::Expr *find_target_expr() const { + + // check if this call has a target object + clang::CXXMethodDecl *md = clang::dyn_cast_or_null (_called_func); + if (!md /* || md->isStatic ()*/) + return 0; + + clang::Expr *result = 0; + + // an ordinary member function call, e.g. foo->bar() + clang::CXXMemberCallExpr *mce = + clang::dyn_cast (TI_Access::tree_node()); + // .. or an operator call, e.g. !foo or foo+bar + clang::CXXOperatorCallExpr *oce = + clang::dyn_cast (TI_Access::tree_node()); + if (mce) + result = mce->getImplicitObjectArgument (); + else if (oce && md->getParent ()) + result = oce->getArg (0); + else { + // it might still be a static member function call with unused target expr, + // e.g. foo->static_bar() + const clang::Expr *callee = tree_node()->getCallee(); + if (clang::dyn_cast (callee)) { + callee = clang::dyn_cast (callee)->getSubExpr (); + if (clang::dyn_cast (callee)) { + result = clang::dyn_cast (callee)->getBase(); + } + } + } + + // TODO: check if implicit calls are handled correctly here + return result; + } + + // checks whether the call uses explicit template parameters + bool has_explicit_template_params () const { + if( clang::DeclRefExpr *dre = llvm::dyn_cast( ref_node() ) ) + return dre->hasExplicitTemplateArgs(); + else if( clang::MemberExpr *me = llvm::dyn_cast( ref_node() ) ) + return me->hasExplicitTemplateArgs(); + else + return false; + } + + const clang::TemplateArgumentLoc *get_explicit_template_params() const { + if( clang::DeclRefExpr *dre = llvm::dyn_cast( ref_node() ) ) + return dre->getTemplateArgs(); + else if( clang::MemberExpr *me = llvm::dyn_cast( ref_node() ) ) + return me->getTemplateArgs(); + else + return 0; + } + + unsigned int num_explicit_template_params() const { + if( clang::DeclRefExpr *dre = llvm::dyn_cast( ref_node() ) ) + return dre->getNumTemplateArgs(); + else if( clang::MemberExpr *me = llvm::dyn_cast( ref_node() ) ) + return me->getNumTemplateArgs(); + else + return 0; + } +}; + +// This class represents a call of a built-in operator. +class TI_Builtin : public TI_CommonCall { + TI_Builtin *_forwarded_src; + ACM_Access *_packed_forward_requester; +public: + TI_Builtin() : _forwarded_src( 0 ), _packed_forward_requester( 0 ) {} + + void tree_node( clang::Expr *n ) { + assert(is_builtin_operator(n)); + TI_Access::tree_node( n ); + } + + virtual string code () const { + if( TI_Builtin::is_implicit_dereference() ) { + clang::ASTContext &ctx = TI_Access::origin()->getASTContext(); + std::string buf("*"); // add explicit built-in operator* + llvm::raw_string_ostream out (buf); + arg(0)->printPretty(out, 0, ctx.getPrintingPolicy(), 0); + out.flush(); + return buf; + } + return TI_CommonCall::code(); + } + + virtual const WeavePos &after_pos (WeaverBase &wb) { + if( TI_Builtin::is_implicit_dereference() ) { + return get_pos_after_token( skipTransparent( arg(0) )->getLocEnd(), wb ); + } + return TI_CommonCall::after_pos(wb); + } + + virtual const WeavePos &before_pos (WeaverBase &wb) { + if( TI_Builtin::is_implicit_dereference() ) { + return wb.weave_pos( skipTransparent( arg(0) )->getLocStart(), WeavePos::WP_BEFORE ); + } + return TI_CommonCall::before_pos(wb); + } + + static TI_Builtin *of (const ACM_Builtin &loc) { + return static_cast(loc.transform_info ()); + } + + static bool is_builtin_operator(clang::Expr* node) { + return llvm::isa( node ) + || llvm::isa( node ) + || llvm::isa( node ) + || llvm::isa( node ) + || is_implicit_dereference( node ); + } + + static string operator_kind_string( clang::Expr *node ) { + assert( is_builtin_operator( node ) ); + if( clang::UnaryOperator *uo = llvm::dyn_cast( node ) ) + return clang::UnaryOperator::getOpcodeStr( uo->getOpcode() ).str(); + else if( clang::BinaryOperator * bo = llvm::dyn_cast( node ) ) + return clang::BinaryOperator::getOpcodeStr( bo->getOpcode() ).str(); + else if( llvm::isa( node ) ) + return "[]"; + else if( llvm::isa( node ) ) + return "?:"; + else if( is_implicit_dereference( node ) ) + return "*"; + + assert( false && "Unknown expr type" ); + return ""; // dummy + } + + virtual string operator_kind_string() const { + return( operator_kind_string( TI_Access::tree_node() ) ); + } + + static unsigned int arg_count( const clang::Expr *node ) { + if( const clang::UnaryOperator *uo = llvm::dyn_cast( node ) ) { + if( uo->isPostfix() ) + return 2; + else + return 1; + } + else if( llvm::isa( node ) ) + return 2; + else if( llvm::isa( node ) ) + return 2; + else if( llvm::isa( node ) ) + return 3; + else if( is_implicit_dereference( node ) ) + return 1; + + assert( false && "Unknown expr type" ); + return 0; // dummy + } + + virtual unsigned int arg_count() const { + return arg_count( TI_Access::tree_node() ); + } + + // This method takes an argument-index as unsigned int and returns the correspondent argument-clang::Expr-pointer. + static const clang::Expr* arg( const clang::Expr *node, unsigned int index ) { + // Valid index? + assert( index < arg_count( node ) ); + if( const clang::UnaryOperator *uo = llvm::dyn_cast( node ) ) { + if( uo->isPostfix() && index == 1 ) + return 0; + else + return uo->getSubExpr(); + } + else if( const clang::BinaryOperator * bo = llvm::dyn_cast( node ) ) + return index == 0 ? bo->getLHS() : bo->getRHS(); + else if( const clang::ArraySubscriptExpr *ase = llvm::dyn_cast( node ) ) + return ( index == 0 ) ? ase->getLHS() : ase->getRHS(); + else if( const clang::ConditionalOperator *co = llvm::dyn_cast( node ) ) + return ( index == 0 ) ? co->getCond() : ( ( index == 1 ) ? co->getTrueExpr() : co->getFalseExpr() ); + else if( is_implicit_dereference( node ) ) + return llvm::dyn_cast( node )->getCallee(); + + assert( false && "Unknown expr type" ); + return 0; // dummy + } + + // This method takes an argument-index as unsigned int and returns the correspondent argument-clang::Expr-pointer. + virtual const clang::Expr* arg(unsigned int index) const { + return arg( TI_Access::tree_node(), index ); + } + + static clang::QualType arg_type( const clang::Expr *node, clang::ASTContext &ctx, unsigned no ) { + if( const clang::UnaryOperator * uo = llvm::dyn_cast( node ) ) { + if( uo->isPostfix() && ( no == 1 ) ) + return ctx.IntTy; // Dummy argument of postfix ops + } + const clang::Expr *argument = arg( node, no ); + if( is_implicit_dereference( node ) ) + return argument->getType().getCanonicalType(); + return TI_Type::get_reference_type_if_necessary(argument->getType().getCanonicalType(), argument, ctx); + } + + static std::string arg_type_string( const clang::Expr *node, clang::ASTContext &ctx, unsigned no ) { + return TI_Type::get_type_code_text(arg_type( node, ctx, no ), &ctx, 0); + } + + virtual std::string arg_type_string (unsigned no) const { + return arg_type_string( TI_Access::tree_node(), origin()->getASTContext(), no ); + } + + // returns whether the type of the argument with the given number is a reference-type + bool arg_is_ref( unsigned no ) const { + return arg_type( TI_Access::tree_node(), origin()->getASTContext(), no )->isReferenceType(); + } + + // returns whether the argument with the given number is NOT available in the call-wrapper + // (e.g. due to short-circuit-evaluation) + bool arg_is_unavailable( unsigned no, int wrapper ) { + // First argument is always available + if(no == 0) { + return false; + } + // Second argument of && and || + if( clang::BinaryOperator *bo = llvm::dyn_cast( TI_Access::tree_node() ) ) { + if( bo->getOpcode() == clang::BO_LAnd ) + return wrapper == 1 && no == 1; + else if( bo->getOpcode() == clang::BO_LOr ) + return wrapper == 0 && no == 1; + else + return false; + } + // second or third argument of ?: + else if( llvm::isa( TI_Access::tree_node() ) ) + return no == static_cast( 2 - wrapper ); + else + return false; + } + + // returns whether this is a unary operator + virtual bool is_unary_expr () const { + return (llvm::isa( TI_Access::tree_node() ) && ! is_postfix_expr() ) || + is_implicit_dereference( TI_Access::tree_node() ); + } + + // returns whether this is a postfix operator (increment oder decrement) + virtual bool is_postfix_expr () const { + if( clang::UnaryOperator *uo = llvm::dyn_cast( TI_Access::tree_node() ) ) + return uo->isPostfix(); + return false; + } + + // returns whether this a binary operator ( but no array subscript operator + virtual bool is_binary_expr () const { + return llvm::isa( TI_Access::tree_node() ); + } + + // returns whether this is the binary array subscript operator + virtual bool is_index_expr () const { + return llvm::isa( TI_Access::tree_node() ); + } + + // returns whether this is a operator that changes and assigns a value + bool is_compound_assignment() const { + if( llvm::isa( TI_Access::tree_node() ) ) + return true; + else if( clang::UnaryOperator *uo = llvm::dyn_cast( TI_Access::tree_node() ) ) + return uo->isIncrementDecrementOp(); + else + return false; + } + + // returns whether this is the arrow class member access operator "->" + virtual bool is_arrow_class_member_access_expr() const { + // built-in operator "->" is currently not supported: + return false; + } + + // returns whether this a ternary operator (currently only conditional operator) + virtual bool is_ternary_expr() const { + return llvm::isa( TI_Access::tree_node() ); + } + + virtual bool is_implicit_conversion () const { + // built-in conversion operators are currently not supported + return false; + } + + static bool is_implicit_dereference(const clang::Expr* node) { + return llvm::isa( node ); + } + + virtual bool is_implicit_dereference() const { + return is_implicit_dereference( TI_Access::tree_node() ); + } + + // This member-function returns whether this call uses the short-circuit evaluation. Currently only + // the built-in operators "&&", "||" and "?:". + bool is_short_circuiting() const { + if( clang::BinaryOperator * bo = llvm::dyn_cast( TI_Access::tree_node() ) ) { + return bo->getOpcode() == clang::BO_LAnd || bo->getOpcode() == clang::BO_LOr; + } + else { + return llvm::isa( TI_Access::tree_node() ); + } + } + + // check if operator is normally forwarding the first arg as result (usually references) + bool is_forwarding() const { + if( llvm::isa( TI_Access::tree_node() ) ) + return true; + else if( clang::BinaryOperator * bo = llvm::dyn_cast( TI_Access::tree_node() ) ) + return bo->getOpcode() == clang::BO_Assign; + else if( clang::UnaryOperator *uo = llvm::dyn_cast( TI_Access::tree_node() ) ) + return uo->isIncrementDecrementOp() && uo->isPrefix(); + else if( llvm::isa( TI_Access::tree_node() ) ) + return true; + else + return false; + } + + // This method returns the clang::SourceLocation of the operator according to the operator-type. + virtual clang::SourceLocation get_operator_location() const { + clang::Expr *node = TI_Access::tree_node(); + if( clang::UnaryOperator *uo = clang::dyn_cast( node ) ) { + return uo->getOperatorLoc(); + } + else if( clang::BinaryOperator *bo = clang::dyn_cast( node ) ) { + return bo->getOperatorLoc(); + } + else if( is_implicit_dereference( node ) ) { + assert( false && "An implicit dereference has no operator location." ); + return clang::SourceLocation(); // invalid location + } + + assert( false && "The expr does not have THE ONE operator-location." ); + return node->getLocStart(); // dummy + } + + // returns whether the current operator returns something + virtual bool has_result () const { + // All currently supported operators have a return value: + return true; + } + + // returns the type of the return value of the operator + static clang::QualType result_type(clang::Expr *node, clang::ASTContext& ctx) { + if( is_implicit_dereference( node ) ) { + // Set the result-type manually, because we have no explicit expression, from which we could take the result-type. + // On dereference operator, if the argument-type is T*, the result-type is T&, so first take the non-pointer-type and + // get it as reference type: + return ctx.getLValueReferenceType(arg(node, 0)->getType().getCanonicalType().getNonReferenceType()->getPointeeType()); + } + return TI_Type::get_reference_type_if_necessary(node->getType().getCanonicalType(), node, ctx); + } + + virtual clang::QualType result_type() const { + return result_type(TI_Access::tree_node(), origin()->getASTContext()); + } + + // Built-in operators are global functions and therefore have no object/target on + // which they are called. Hence we have no target expression and thus there + // is no class of the type of this expression. + virtual clang::Expr *find_target_expr() const { + return 0; + } + virtual const clang::RecordDecl *target_class () const { + return 0; + } + virtual const clang::RecordDecl *targetexpr_class () const { + return 0; + } + + void forwarded_src( TI_Builtin *src ) { + _forwarded_src = src; + } + + TI_Builtin *forwarded_src() { + return _forwarded_src; + } + + void request_packed_forward( ACM_Access *requester ) { + if( _packed_forward_requester == 0 ) { + if( _forwarded_src ) + _forwarded_src->request_packed_forward( requester ); + + _packed_forward_requester = requester; + } + } + + bool forwarded_is_packed() const { + return _packed_forward_requester != 0; + } + + ACM_Access * packed_forward_requester() const { + return _packed_forward_requester; + } + + bool forwarded_needs_packing() { + // check src for planned advice, which already packed it + TI_Builtin *check = _forwarded_src; + while( check ) { + if( check->is_planned() ) + return false; + check = check->_forwarded_src; + } + + return true; + } + + unsigned int forwarded_index_count() const { + unsigned int result = 0; + if( _forwarded_src ) + result = _forwarded_src->forwarded_index_count(); + + if( is_index_expr() ) + result++; + + return result; + } + + std::string forwarded_index_type( unsigned int i ) const { + assert( forwarded_index_count() > i ); + if( is_index_expr() ) { + if( i == 0 ) + return arg_type_string( 1 ); + else + i--; + } + + assert( _forwarded_src ); + return _forwarded_src->forwarded_index_type( i ); + } +}; + + +class TI_VariableAccess : public TI_Access { +private: + TI_Builtin *_entity_src; +public: + TI_VariableAccess() : _entity_src( 0 ) {} + + // unprotect function by forwarding (we need no special sig) + void entity( clang::DeclaratorDecl *v ) { TI_Access::entity( v ); } + void variable( clang::DeclaratorDecl *v ) { entity( v ); } + clang::DeclaratorDecl *variable() const { return TI_Access::entity(); } + + virtual clang::QualType entity_type() const { + clang::QualType type = TI_Access::entity()->getType(); + unsigned int unwrap = entity_index_count(); + while( unwrap > 0 && type->isArrayType() ) { + type = clang::dyn_cast( type.getCanonicalType().getTypePtr() )->getElementType(); + unwrap--; + } + assert( unwrap == 0 ); // we should not meet any non array types above + + return type; + } + + virtual std::string entity_type_string() const { + return format_type( entity_type(), TI_Access::entity()->getASTContext() ); + } + + void entity_src( TI_Builtin *src ) { _entity_src = src; } + virtual TI_Builtin *entity_src() const { return _entity_src; } + + virtual SpliceMode entity_src_splice_mode() const { + TI_Builtin *src = _entity_src; + while( src ) { + if( src->is_planned() ) + return SpliceMode_Packed; // already done while weaving of src + if( ( src->is_binary_expr() && ( src->operator_kind_string() == "=" ) ) || src->is_compound_assignment() ) + return SpliceMode_Pack; // this forwarding operators have side effects we cant splice, so we need to pack + src = src->forwarded_src(); + } + + return SpliceMode_FullSplice; // no reasons to not do it, at least none found here + } + + bool entity_is_const() const { + clang::DeclaratorDecl *var = variable(); + return var && var->getType().isConstQualified(); + } + + virtual unsigned int entity_index_count() const { + if( _entity_src ) + return _entity_src->forwarded_index_count(); + else + return 0; + } + virtual unsigned long int entity_index_dimension( unsigned int i ) const { + const clang::ConstantArrayType *type = llvm::dyn_cast( variable()->getType().getCanonicalType().getTypePtr() ); + while( i > 0 ) + type = clang::dyn_cast( type->getElementType().getTypePtr() ), i--; + + return type->getSize().getZExtValue(); + } + virtual std::string entity_index_type( unsigned int i ) const { + if( _entity_src ) + return _entity_src->forwarded_index_type( i ); + else + return "void"; + } + + // unprotect function by forwarding (we need no special sig) + void tree_node( clang::Expr* n ) { TI_Access::tree_node( n ); } + + // target type (for the JoinPoint-API) + virtual const clang::RecordDecl *target_class () const { + const clang::RecordDecl *result = targetexpr_class(); + + // if variable is from a virtual base, we need to "downgrade" the target as member pointers cant represent that + if( llvm::isa( variable() ) ) { + const clang::CXXRecordDecl *defining = llvm::dyn_cast_or_null( defining_class() ); + const clang::CXXRecordDecl *target = llvm::dyn_cast_or_null( result ); + if( defining && target && target->isVirtuallyDerivedFrom( defining ) ) + result = defining_class(); + } + + return result; + } + + virtual const clang::RecordDecl *targetexpr_class() const { + const clang::RecordDecl *result = 0; + + if( target_is_implicit() ) { + clang::CXXMethodDecl *origin = llvm::dyn_cast( this->origin() ); + assert( origin ); + + result = origin->getParent(); + } + else if( has_target_expr() ) { + const clang::Type *type = target_expr()->getType ().getTypePtr(); + result = type->getPointeeCXXRecordDecl(); + if( !result ) + result = type->getAsCXXRecordDecl(); + } + else if( const clang::VarDecl *vd = llvm::dyn_cast( variable() ) ) { + if( vd->isStaticDataMember() ) { + const clang::DeclContext *dc = vd->getDeclContext(); + assert( dc->isRecord() ); + + result = llvm::dyn_cast( dc ); + } + else + result = 0; + } + + return result; + } +}; + +class TI_Get : public TI_VariableAccess { +public: + TI_Get() {} + + static TI_Get *of( const ACM_Get &loc ) { + return static_cast(loc.transform_info()); + } + + virtual bool has_result() const { + return true; + } + + virtual clang::QualType result_type() const { + return entity_type(); + } +}; + +class TI_Set : public TI_VariableAccess { +public: + TI_Set() {} + + static TI_Set *of( const ACM_Set &loc ) { + return static_cast(loc.transform_info()); + } + + virtual std::string arg_type_string (unsigned no) const { + assert( no == 0 ); + + return entity_type_string(); + } + + virtual bool has_result() const { + return false; + } + + virtual clang::QualType result_type() const { + clang::ASTContext& ctx = origin()->getASTContext(); + return ctx.VoidTy; + } +}; + +class TI_Ref : public TI_VariableAccess { +public: + TI_Ref() {} + + static TI_Ref *of( const ACM_Ref &loc ) { + return static_cast(loc.transform_info()); + } + + // emulate index on ArrayToPointerDecay + virtual unsigned int entity_index_count() const { + unsigned int result = TI_VariableAccess::entity_index_count(); + if( is_implicit_arraydecay() ) + result++; + + return result; + } + virtual std::string entity_index_type( unsigned int i ) const { + if( is_implicit_arraydecay() && i == ( entity_index_count() - 1 ) ) + return "unsigned int"; + else + return TI_VariableAccess::entity_index_type( i ); + } + + virtual bool has_result() const { + return true; + } + + virtual clang::QualType result_type() const { + clang::Expr *node = TI_Access::tree_node(); + return TI_Type::get_reference_type_if_necessary(node->getType(), node, origin()->getASTContext()); + } + + bool result_is_ptr() const { + return result_type().getTypePtr()->isPointerType(); + } + + const bool is_explicit_operator() const { + if( clang::UnaryOperator *uo = clang::dyn_cast( TI_Access::tree_node() ) ) + if( uo->getOpcode() == clang::UO_AddrOf ) + return true; + + return false; + } + + bool is_implicit_arraydecay() const { + if( clang::ImplicitCastExpr *ice = clang::dyn_cast( TI_Access::tree_node() ) ) + if( ice->getCastKind() == clang::CK_ArrayToPointerDecay ) + return true; + + return false; + } + + const WeavePos &op_before_pos( WeaverBase &wb ) const { + assert( clang::isa( TI_Access::tree_node() ) ); + return wb.weave_pos( clang::dyn_cast( TI_Access::tree_node() )->getOperatorLoc(), WeavePos::WP_BEFORE ); + } + + const WeavePos &op_after_pos( WeaverBase &wb ) const { + assert( clang::isa( TI_Access::tree_node() ) ); + return get_pos_after_token( clang::dyn_cast( TI_Access::tree_node() )->getOperatorLoc(), wb ); + } +}; + +class TI_RefAccess : public TI_Access { +public: + TI_RefAccess() {} + + bool entity_is_const() const { + return entity_type().isConstQualified(); + } + + // unprotect function by forwarding (we need no special sig) + void tree_node( clang::Expr* n ) { TI_Access::tree_node( n ); } + + // target type (for the JoinPoint-API) + virtual const clang::RecordDecl *target_class () const { + return 0; // refs dont have a target type currently, it has to be recovered from runtime info + } + virtual const clang::RecordDecl *targetexpr_class () const { + return 0; // accesses by reference dont have a target expr + } + + // common function to determine entity type + clang::QualType entity_type() const { + return TI_Access::ref_node()->getType().getNonReferenceType(); + } + + // entity type (for the JoinPoint-API) + virtual std::string entity_type_string() const { + return format_type( entity_type(), TI_Access::origin()->getASTContext() ); + } +}; + +class TI_GetRef : public TI_RefAccess { +public: + TI_GetRef() {} + + static const TI_GetRef *of( const ACM_GetRef &loc ) { + return static_cast(loc.transform_info()); + } + + virtual bool has_result() const { + return true; + } + + virtual clang::QualType result_type() const { + return entity_type(); + } +}; + +class TI_SetRef : public TI_RefAccess { +public: + TI_SetRef() {} + + static const TI_SetRef *of( const ACM_SetRef &loc ) { + return static_cast(loc.transform_info()); + } + + virtual std::string arg_type_string (unsigned no) const { + assert( no == 0 ); + + return entity_type_string(); + } + + virtual bool has_result() const { + return false; + } + + virtual clang::QualType result_type() const { + clang::ASTContext& ctx = origin()->getASTContext(); + return ctx.VoidTy; + } +}; + +class TI_Construction : public TI_Code { + clang::FunctionDecl *_decl; + clang::CXXRecordDecl *_that_decl; + +public: + TI_Construction () : _decl (0), _that_decl (0) {} + + void decl (clang::FunctionDecl *f) { _decl = f; } + virtual clang::Decl *decl () const { return _that_decl; } + void that_decl (clang::CXXRecordDecl *r) { _that_decl = r; } + virtual clang::CXXRecordDecl *that_decl () const { return _that_decl; } + + // that type (for the JoinPoint-API) + virtual std::string that_type_string() const { + return get_type_string(_that_decl); + } + + // target type (for the JoinPoint-API) + virtual std::string target_type_string() const { + return get_type_string(_that_decl); + } + + virtual std::string arg_type_string (unsigned no) const { + if (_decl) { // user-defined constructor + return get_type_string (_decl->getParamDecl (no), true); + } + else { // built-in constructor + assert (no == 0); // may have at most one argument + string result; + if (_that_decl->hasCopyConstructorWithConstParam ()) + result += "const "; + result += get_type_string(_that_decl); + result += "&"; + return result; + } + } + + // entity type (for the JoinPoint-API) + virtual std::string entity_type_string() const { + return format_type( _decl ); + } +}; + +class TI_Destruction : public TI_Code { + clang::FunctionDecl *_decl; + clang::CXXRecordDecl *_that_decl; + +public: + TI_Destruction () : _decl (0), _that_decl (0) {} + + void decl (clang::FunctionDecl *f) { _decl = f; } + virtual clang::Decl *decl () const { return _that_decl; } + void that_decl (clang::CXXRecordDecl *r) { _that_decl = r; } + virtual clang::CXXRecordDecl *that_decl () const { return _that_decl; } + + // that type (for the JoinPoint-API) + virtual std::string that_type_string() const { + return get_type_string(_that_decl); + } + + // target type (for the JoinPoint-API) + virtual std::string target_type_string() const { + return get_type_string(_that_decl); + } + + // entity type (for the JoinPoint-API) + virtual std::string entity_type_string() const { + return format_type( _decl ); + } +}; + +class TI_AdviceCode : public TransformInfo { + clang::FunctionDecl *_decl; + ThisJoinPoint _this_join_point; + +public: + TI_AdviceCode () : _decl (0) {} + + void decl(clang::FunctionDecl *f) { _decl = f; } + virtual clang::FunctionDecl *decl () const { return _decl; } + + clang::DeclContext *Scope () const { + return _decl ? _decl->getParent() : 0; + } + string name () const { + return _decl ? _decl->getNameAsString() : ""; + } + string qual_name () { + return _decl ? _decl->getQualifiedNameAsString() : ""; + } + + ThisJoinPoint &this_join_point () { return _this_join_point; } + const ThisJoinPoint &this_join_point () const { return _this_join_point; } + + static TI_AdviceCode *of (const ACM_AdviceCode &loc) { + return static_cast(loc.transform_info ()); + } +}; + +class TI_Introduction : public TransformInfo { +public: + virtual clang::Decl *decl () const { return 0; } + + static TI_Introduction *of (const ACM_Introduction &loc) { + return static_cast(loc.transform_info ()); + } +}; + +class TI_Order : public TransformInfo { +public: + virtual clang::Decl *decl () const { return 0; } + + static TI_Order *of (const ACM_Order &loc) { + return static_cast(loc.transform_info ()); + } +}; + +class TI_Pointcut : public TransformInfo { + clang::FunctionDecl *_decl; + int _phase; + clang::FullSourceLoc _loc; +public: + TI_Pointcut () : _decl(0), _phase (0) {} + + void decl (clang::FunctionDecl *c) { _decl = c; } + virtual clang::Decl *decl () const { return _decl; } + + void phase (int p) { _phase = p; } + int phase () const { return _phase; } + void set_location (clang::FullSourceLoc loc) { _loc = loc; } + clang::FullSourceLoc get_location () const { return _loc; } + + static TI_Pointcut *of (const ACM_Pointcut &loc) { + return static_cast(loc.transform_info ()); + } +}; + +class TI_Attribute : public TransformInfo { + clang::Decl *_decl; + int _phase; +// ACM_Attribute *_attr; + clang::FullSourceLoc _loc; + string _params; +public: + TI_Attribute () : _decl(0), _phase (0)/*, _pce (0)*/ {} + ~TI_Attribute () {} + void decl (clang::RecordDecl *c) { _decl = c; } + void decl (clang::FunctionDecl *c) { _decl = c; } + virtual clang::Decl *decl () const { return _decl; } + + void setParamStr(string params) {_params = params;} + const string& getParamStr() {return _params;} + void phase (int p) { _phase = p; } + int phase () const { return _phase; } +// void set_attr (ACM_Attribute *attr) { _attr = attr; } +// ACM_Attribute *get_attr () const { return _attr; } + void set_location (clang::FullSourceLoc loc) { _loc = loc; } + clang::FullSourceLoc get_location () const { return _loc; } + + static TI_Attribute *of (const ACM_Attribute &loc) { + return static_cast(loc.transform_info ()); + } +}; + +class TI_ClassSlice : public TransformInfo { +public: + struct SliceBody { + std::string text; // the pattern itself + ACFileID file; // file in which the slice (part) is implemented + unsigned line; // line in 'file' + enum InsertType { TARGET_NAME, TARGET_QUAL_NAME, JP_NAME }; // kinds of replacements + std::vector > positions; // replacement positions + }; + +private: + ACFileID _slice_unit; + + // new phase 1 implementation: + SliceBody _member_intro; // class slice body + SliceBody _base_intro; // introduce base classes + bool _has_base_intro, _has_member_intro; + std::vector _non_inline_members; // members defined outside of body + std::vector _non_inline_member_units; // corresponding source units + +public: + + TI_ClassSlice () : _slice_unit (0), _has_base_intro (false), + _has_member_intro (false) {} + + // new phase 1 implementation: + void set_tokens (const SliceBody &member_intro, const SliceBody &base_intro, + bool has_base_intro, bool has_member_intro) { + _member_intro = member_intro; + _base_intro = base_intro; + _has_base_intro = has_base_intro; + _has_member_intro = has_member_intro; + } + const SliceBody &get_tokens () const { return _member_intro; } + const SliceBody &get_base_tokens () const { return _base_intro; } + std::vector &non_inline_members () { return _non_inline_members; } + std::vector &non_inline_member_units () { return _non_inline_member_units; } + void analyze_tokens (bool &has_base_intro, bool &has_member_intro) { + has_base_intro = _has_base_intro; + has_member_intro = _has_member_intro; + } + const std::string &base_intro () const { + return _base_intro.text; + } + // end - new phase 1 implementation + + virtual clang::Decl *decl () const { return 0; } + void slice_unit (ACFileID su) { _slice_unit = su; } + ACFileID slice_unit () const { return _slice_unit; } + + static TI_ClassSlice *of (const ACM_ClassSlice &loc) { + return static_cast(loc.transform_info ()); + } +}; + +#endif // __ClangTransformInfo_h__ diff --git a/AspectC++/ClangWeaverBase.cc b/AspectC++/ClangWeaverBase.cc new file mode 100644 index 0000000..a7aba65 --- /dev/null +++ b/AspectC++/ClangWeaverBase.cc @@ -0,0 +1,680 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2013 The 'ac++' developers (see aspectc.org) +// +// 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 "ClangWeaverBase.h" +#include "ACIntroducer.h" +#include "IntroductionUnit.h" +#include "LineDirectiveMgr.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Lex/Lexer.h" +#include "clang/Lex/Preprocessor.h" +#include "llvm/Support/MemoryBuffer.h" +#include "ACModel/Utils.h" +#include "version.h" + +// Returns the location one past the end of the token. +static clang::SourceLocation getLocAfterToken(ClangToken tok) { + unsigned len = tok.get ().getLength (); + return tok.location ().getLocWithOffset (len); +} + +const WeavePos &WeaverBase::get_pos_after_loc (clang::SourceLocation loc, + WeavePos::Pos pos) { + clang::SourceLocation result; + if (loc.isValid() && loc.isMacroID ()) { + clang::SourceLocation macro_end_loc; + // See if we're at the end of a macro and get the location for the last + // token if we are. + bool is_at_end = clang::Lexer::isAtEndOfMacroExpansion(loc, + getRewriter().getSourceMgr(), getRewriter().getLangOpts (), ¯o_end_loc); + if (is_at_end) { + loc = macro_end_loc; + // Now go on and get the location after this token. + } + clang::SourceLocation spell_loc = getRewriter().getSourceMgr().getSpellingLoc(loc); + unsigned len = clang::Lexer::MeasureTokenLength(spell_loc, getRewriter().getSourceMgr(), + getRewriter().getLangOpts ()); + result = loc.getLocWithOffset(len); + } + else { + result = clang::Lexer::getLocForEndOfToken (loc, 0, + getRewriter().getSourceMgr(), getRewriter().getLangOpts ()); + } + + assert (!result.isInvalid ()); + return weave_pos (result, pos); +} + +const WeavePos &WeaverBase::weave_pos (ClangToken t, int p) { + if (p == (int)WeavePos::WP_AFTER) + return weave_pos (getLocAfterToken(t), p); + else + return weave_pos (t.location(), p); +} + +const WeavePos &WeaverBase::weave_pos (clang::SourceLocation loc, int p) { + assert(loc.isValid() && "Invalid SourceLocation!"); + + // Optimization: If a location is directly before or after a macro we can turn + // it into a non-macro location and avoid the extra work for macro expansion. + // TODO: This is currently disabled because clang returns wrong locations for + // some macro arguments. + /*if (loc.isValid() && loc.isMacroID()) { + clang::SourceManager &SM = _rewriter->getSourceMgr(); + clang::SourceLocation fixed_loc; + if (SM.isAtStartOfImmediateMacroExpansion (loc, &fixed_loc)) + loc = fixed_loc; + else if (SM.isAtEndOfImmediateMacroExpansion (loc, &fixed_loc)) + loc = fixed_loc; + }*/ + + // check whether the weaving position has already been created + WPSet::iterator i = _positions.find (WeavePos (loc, (WeavePos::Pos)p)); + if (i != _positions.end ()) + return *i; + + // insert the position as a new one + pair result = + _positions.insert (WeavePos (loc, (WeavePos::Pos)p)); + + // the resulting iterator points to the new entry + return *result.first; +} + +const WeavePos &WeaverBase::header_pos () { + clang::FileID main_fid = _rewriter->getSourceMgr().getMainFileID(); + return header_pos (_rewriter->getSourceMgr().getFileEntryForID (main_fid)); +} + +const WeavePos &WeaverBase::header_pos (ACFileID acfid) { + const clang::FileEntry *fentry = acfid.file_entry (); + clang::FileID fid = _rewriter->getSourceMgr().translateFile (fentry); + clang::SourceLocation first = + _rewriter->getSourceMgr().getLocForStartOfFile(fid); + return weave_pos (first, WeavePos::WP_HEADER); +} + +const WeavePos &WeaverBase::footer_pos () { + clang::FileID main_fid = _rewriter->getSourceMgr().getMainFileID(); + return footer_pos (_rewriter->getSourceMgr().getFileEntryForID (main_fid)); +} + +const WeavePos &WeaverBase::footer_pos (ACFileID acfid) { + const clang::FileEntry *fentry = acfid.file_entry (); + clang::FileID fid = _rewriter->getSourceMgr().translateFile (fentry); + clang::SourceLocation last = + _rewriter->getSourceMgr().getLocForEndOfFile(fid); + return weave_pos (last, WeavePos::WP_FOOTER); +} + +// insert a generated string a given position +void WeaverBase::insert (const WeavePos &pos, const string &str, + bool before) { + // return immediately if the string to paste is empty + if (str == "") + return; + + // If this is a bulk code insert wrap it in line directives. + if (str.find('\n') != string::npos) { + clang::PresumedLoc loc = _rewriter->getSourceMgr().getPresumedLoc(pos._loc); + + // directives are fixed up later on. + std::ostringstream os; + _line_mgr.directive (os, clang::PresumedLoc ()); + os << str; + _line_mgr.directive (os, loc); + + if (before) + pos._strings.push_front(os.str()); + else + pos._strings.push_back(os.str()); + return; + } + + // FIXME: handle before + + // store the unit in the right order for insertion (later when committing) + if (before) + pos._strings.push_front(str); + else + pos._strings.push_back(str); +} + +// replace the text between two positions with some new text +void WeaverBase::replace (const WeavePos &from, const WeavePos &to, + const string &str) { + insert (from, str); + kill (from, to); +} + +extern "C" void __real__ZN5clang12Preprocessor3LexERNS_5TokenE(clang::Preprocessor &that, clang::Token &Result); + +// make sure that Clang parses attributes, even if we are not in C++11-mode +void WeaverBase::lex_and_filter_attr(clang::Preprocessor &PP, clang::Token &result) { + + static clang::LangOptions &lang_options = _project.get_compiler_instance()->getLangOpts (); + static clang::LangOptions original_lang_options = lang_options; + static clang::SourceLocation prev_location; + static std::set hidden; + static bool in_attr = false; + + do { + __real__ZN5clang12Preprocessor3LexERNS_5TokenE(PP, result); + if (result.is(clang::tok::eof) || !_annotation_map) + return; + } while (hidden.find(result.getLocation()) != hidden.end()); + +// cout << "Got token: " << PP.getSpelling(result) << endl; + clang::SourceManager &SM = _rewriter->getSourceMgr(); + if (prev_location.isValid() && !SM.isBeforeInTranslationUnit (prev_location, result.getLocation())) + return; + prev_location = result.getLocation(); + +// cout << "New token: " << PP.getSpelling(result) << result.getLocation().printToString(SM) << endl; + if ((!in_attr && result.isNot(clang::tok::l_square)) || (in_attr && result.isNot(clang::tok::r_square))) + return; + + PP.EnableBacktrackAtThisPos(); + clang::Token tok; + __real__ZN5clang12Preprocessor3LexERNS_5TokenE(PP, tok); + if (!in_attr && tok.is(clang::tok::l_square)) { + // here we have seen "[[": an attribute sequence starts + lang_options.CPlusPlus11 = 1; + in_attr = true; + hidden.clear(); + // parse the attribute list + std::list annotation_iters; + bool in_seq = true; + bool is_user_defined_seq = true; + while (in_seq) { + // create an initialize an attribute object + Annotation attr; + attr.seqBegin = prev_location; + // parse an attribute, start with the qualified name + std::vector tokens; + while (true) { + __real__ZN5clang12Preprocessor3LexERNS_5TokenE(PP, tok); + if (tok.isNot(clang::tok::identifier)) + break; + tokens.push_back(tok); + attr.attrNames.push_back(PP.getSpelling(tok)); + __real__ZN5clang12Preprocessor3LexERNS_5TokenE(PP, tok); + if (tok.isNot(clang::tok::coloncolon)) + break; + tokens.push_back(tok); + }; + bool is_user_defined = (attr.attrNames.size() > 1 && + attr.attrNames[0] != "gnu" && attr.attrNames[0] != "clang"); + attr.is_user_defined = is_user_defined; + if (is_user_defined) { + for (unsigned int i = 1; i < tokens.size() - 2; i++) { + hidden.insert(tokens[i].getLocation()); // hide the middle part so that clang can parse it + } + } + else + is_user_defined_seq = false; + attr.tokBegin = tokens[0].getLocation(); + if (tok.is(clang::tok::l_paren)) { + unsigned paren_count = 1; + do { + __real__ZN5clang12Preprocessor3LexERNS_5TokenE(PP, tok); + if (tok.is(clang::tok::l_paren)) + paren_count++; + else if (tok.is(clang::tok::r_paren)) + paren_count--; + else { + if (!attr.params.empty()) + attr.params += " "; + attr.params += PP.getSpelling(tok); + } + // TODO: error handling + } while (paren_count > 0); + __real__ZN5clang12Preprocessor3LexERNS_5TokenE(PP, tok); + } + if (tok.isNot(clang::tok::comma)) + in_seq = false; + attr.tokEnd = tok.getLocation(); // end is begin of next token => better for deleting the attribute + std::pair ret = + _annotation_map->insert(std::pair(attr.tokBegin, attr)); + annotation_iters.push_back (ret.first); + } + + if (tok.is(clang::tok::r_square)) { + clang::SourceLocation end = tok.getLocation(); + __real__ZN5clang12Preprocessor3LexERNS_5TokenE(PP, tok); + if (tok.is(clang::tok::r_square)) { + if (is_user_defined_seq) { + kill(weave_pos(prev_location, WeavePos::WP_BEFORE), + weave_pos(tok.getLocation().getLocWithOffset(1), WeavePos::WP_AFTER)); + } + else { + clang::SourceLocation begin = end; + bool have_builtin = false; + for (std::list::reverse_iterator i = annotation_iters.rbegin(); + i != annotation_iters.rend(); ++i) { + if ((*i)->second.is_user_defined) { + begin = (*i)->second.tokBegin; + } + else { + if (!have_builtin) + begin = (*i)->second.tokEnd; // remove trailing ',' + if (begin != end) + kill(weave_pos(begin, WeavePos::WP_BEFORE), weave_pos(end, WeavePos::WP_AFTER)); + begin = end = (*i)->second.tokBegin; + have_builtin = true; + } + } + if (begin != end) + kill(weave_pos(begin, WeavePos::WP_BEFORE), weave_pos(end, WeavePos::WP_AFTER)); + } + } + } + } + else if (in_attr && tok.is(clang::tok::r_square)) { + lang_options = original_lang_options; + in_attr = false; +// cout << "in_attr " << in_attr << " at " << tok.getLocation().printToString(SM) << endl; + } + PP.Backtrack(); + return; +} + + +void WeaverBase::collect_macro_token (clang::Preprocessor &PP, clang::Token &Result) { + + clang::SourceLocation loc = Result.getLocation(); + // ignore annotation (getSpelling fails for them!) and non-macro tokens + if (Result.isAnnotation() || !loc.isMacroID()) + return; + + // TODO: ignore macros that are expand in a file, which does not belong to the project + // => improved efficiency; make sure the cache the last check's result + + bool invalid; + std::string text = PP.getSpelling(Result, &invalid); + if (invalid) + return; + +// cout << "tok: " << Result.getName() << " "<< text << endl; + + clang::SourceManager &SM = _rewriter->getSourceMgr(); + clang::SourceLocation expansion_loc = SM.getExpansionLoc(Result.getLocation()); + clang::SourceLocation end_loc = loc.getLocWithOffset (text.size ()); + MacroMap::iterator mm_iter = _macros.find (expansion_loc); + if (mm_iter == _macros.end ()) { + MacroExpansion macro_expansion; + macro_expansion._token_loc_map.insert (std::pair (loc, 0u)); + macro_expansion._token_end_loc_map.insert (std::pair (end_loc, text.size ())); + macro_expansion._somewhere_inside = loc; + macro_expansion._expanded_macro_text = text; + _macros.insert (std::pair (expansion_loc, macro_expansion)); +// cout << "new: " << text << endl; + } + else { + std::pair ret; + unsigned int pos = mm_iter->second._expanded_macro_text.size () + 1u; + ret = mm_iter->second._token_loc_map.insert (std::pair (loc, pos)); + if (ret.second) { + mm_iter->second._token_end_loc_map.insert (std::pair (end_loc, pos + text.size ())); + mm_iter->second._expanded_macro_text += " "; + mm_iter->second._expanded_macro_text += text; +// cout << "ext: " << mm_iter->second._expanded_macro_text << endl; + } + } +} + +bool WeaverBase::lookup_macro_token (clang::SourceLocation loc, clang::SourceLocation &mapped_loc) { + clang::SourceManager &SM = _rewriter->getSourceMgr(); + + // find the expansion information stored for 'loc' or return false + clang::SourceLocation expansion_loc = SM.getExpansionLoc(loc); + MacroMap::iterator mm_iter = _macros.find (expansion_loc); + if (mm_iter == _macros.end ()) { + cout << "fatal: macro not found" << endl; + return false; + } + + // generate a memory buffer for the expansion if not done yet + clang::FileID &fid = mm_iter->second._fid; + if (fid.isInvalid ()) { +#if CLANG_VERSION_NUMBER <= VERSION_NUMBER_3_5_2 + llvm::MemoryBuffer *mb = + llvm::MemoryBuffer::getMemBufferCopy(mm_iter->second._expanded_macro_text + " ", ""); + fid = SM.createFileID(mb, clang::SrcMgr::C_User, 0, 0, expansion_loc); +#else // C++ 11 interface + std::unique_ptr mb (llvm::MemoryBuffer::getMemBufferCopy(mm_iter->second._expanded_macro_text + " ", "")); + fid = SM.createFileID(std::move (mb), clang::SrcMgr::C_User, 0, 0, expansion_loc); +#endif + } + + clang::SourceLocation start = SM.getLocForStartOfFile(fid); + TokenLocMap::iterator tl_iter = mm_iter->second._token_loc_map.find (loc); + if (tl_iter == mm_iter->second._token_loc_map.end ()) { + tl_iter = mm_iter->second._token_end_loc_map.find (loc); + if (tl_iter == mm_iter->second._token_end_loc_map.end ()) { + cout << "fatal: token not found" << endl; + return false; + } + } + unsigned int offset = tl_iter->second; + mapped_loc = start.getLocWithOffset(offset); + + return true; +} + + +// kill the text between two positions +void WeaverBase::kill (const WeavePos &from, const WeavePos &to) { + // TODO: this should not matter, the code shoud be able to deal with it + assert (from._pos == WeavePos::WP_BEFORE); + assert (to._pos == WeavePos::WP_AFTER); + + _deletions.push_back(LocPair(from._loc, to._loc)); +} + + +void WeaverBase::commit_kills() { + for (LocPairList::iterator i = _deletions.begin(); i != _deletions.end(); ++i) + commit_kill (i->first, i->second); +} + + +// kill the text between two positions +void WeaverBase::commit_kill (clang::SourceLocation from, clang::SourceLocation to) { + + /*if (macro_problem (from) || macro_problem (to)) + return; + + bool has_nl = (strstr (from._token.text (), "\n") != NULL); + if ((to._token && from._token != to._token) || has_nl) + _line_mgr.insert ((Unit*)to._token.unit (), to._token, true);*/ + + clang::Rewriter::RewriteOptions opts; + opts.IncludeInsertsAtBeginOfRange = false; + opts.IncludeInsertsAtEndOfRange = false; + clang::SourceManager &SM = _rewriter->getSourceMgr(); + + // Handle kills inside a macro. + + if (from.isMacroID() || to.isMacroID()) { + + clang::SourceLocation loc1 = from; + clang::SourceLocation expansion_loc1 = SM.getExpansionLoc(loc1); + + if (from.isMacroID() && !lookup_macro_token(from, loc1)) { + cout << "fatal: 'from' location not found during kill" << endl; + return; + } + + clang::SourceLocation loc2 = to; + clang::SourceLocation expansion_loc2 = SM.getExpansionLoc(loc2); + if (to.isMacroID() && !lookup_macro_token(to, loc2)) { + cout << "fatal: 'to' location not found during kill" << endl; + return; + } + + if (from.isMacroID() && !to.isMacroID()) { + MacroMap::iterator macro_info = _macros.find (expansion_loc1); + if (macro_info == _macros.end ()) { + cout << "fatal: macro info not found in kill" << endl; + return; + } + clang::SourceLocation macro_end = macro_info->second.endLoc (SM); + _rewriter->RemoveText(clang::CharSourceRange::getCharRange(loc1, macro_end)); + + clang::SourceLocation somewhere_inside = macro_info->second._somewhere_inside; + std::pair range = + SM.getExpansionRange(somewhere_inside); + unsigned len = _rewriter->getRangeSize(clang::SourceRange(range.second, range.second)); + _rewriter->RemoveText(clang::CharSourceRange::getCharRange( + range.second.getLocWithOffset(len), loc2), opts); + } + else if (!from.isMacroID() && to.isMacroID()) { + MacroMap::iterator macro_info = _macros.find (expansion_loc2); + if (macro_info == _macros.end ()) { + cout << "fatal: macro info not found in kill" << endl; + return; + } + clang::SourceLocation macro_start = macro_info->second.startLoc (SM); + _rewriter->RemoveText(clang::CharSourceRange::getCharRange(macro_start, loc2)); + + clang::SourceLocation somewhere_inside = macro_info->second._somewhere_inside; + std::pair range = + SM.getExpansionRange(somewhere_inside); + _rewriter->RemoveText(clang::CharSourceRange::getCharRange( + loc1, range.first), opts); + } + else { + // both locations are in a macro instance + + // remove from 'from' to the macro end + MacroMap::iterator macro_info1 = _macros.find (expansion_loc1); + if (macro_info1 == _macros.end ()) { + cout << "fatal: macro info not found in kill" << endl; + return; + } + clang::SourceLocation macro_end = macro_info1->second.endLoc (SM); + + // remove from macro start to 'end' + MacroMap::iterator macro_info2 = _macros.find (expansion_loc2); + if (macro_info2 == _macros.end ()) { + cout << "fatal: macro info not found in kill" << endl; + return; + } + clang::SourceLocation macro_start = macro_info2->second.startLoc (SM); + + if (macro_info1 != macro_info2) { + _rewriter->RemoveText(clang::CharSourceRange::getCharRange(loc1, macro_end)); + _rewriter->RemoveText(clang::CharSourceRange::getCharRange(macro_start, loc2)); + + // remove from first macro expansion end to second macro expansion begin + clang::SourceLocation somewhere_inside1 = macro_info1->second._somewhere_inside; + std::pair range1 = + SM.getExpansionRange(somewhere_inside1); + unsigned len = _rewriter->getRangeSize(clang::SourceRange(range1.second, range1.second)); + + clang::SourceLocation somewhere_inside2 = macro_info2->second._somewhere_inside; + std::pair range2 = + SM.getExpansionRange(somewhere_inside2); + + _rewriter->RemoveText(clang::CharSourceRange::getCharRange( + range1.second.getLocWithOffset(len), range2.first), opts); + } + else { + _rewriter->RemoveText(clang::CharSourceRange::getCharRange(loc1, loc2)); + } + } + return; + } + + if (!from.isValid () || from.isMacroID ()|| + !to.isValid () || to.isMacroID ()) { + cout << "Invalid or macro source loc in kill" << endl; + return; + } + _rewriter->RemoveText (clang::CharSourceRange::getCharRange (from, to), opts); +} + +void WeaverBase::commit_internal () { + + // commit all code deletions and clear the operations + commit_kills(); + _deletions.clear(); + + // commit code insertions + clang::SourceManager &SM = _rewriter->getSourceMgr(); + // handle code that has to be inserted at weaving positions + for (WPSet::iterator i = _positions.begin (); i != _positions.end (); ++i) { + const WeavePos &wp = *i; + if (wp._loc.isInvalid ()) { + cout << "Invalid source loc" << endl; + continue; + } + bool nl = false; + bool last_nl = false; + + clang::SourceLocation loc; + if (wp._loc.isMacroID()) { + // find the location in the genrated memory buffer + if (!lookup_macro_token (wp._loc, loc)) { + cout << "fatal: location not found during commit" << endl; + continue; + } + // mark this macro instance for expansion + clang::SourceLocation expansion_loc = SM.getExpansionLoc(wp._loc); + _macro_expansions.insert (expansion_loc); + } + else + loc = wp._loc; + + // perform the code insertion + for (list::iterator si = wp._strings.begin(); + si != wp._strings.end(); ++si) { + const string &str = *si; + _rewriter->InsertTextAfter(loc, str); + nl |= (str.find("\n") != string::npos); + last_nl = (str[str.size() - 1] == '\n'); + } + if (nl) { // at least one new line character was inserted here + // generate and insert a #line directive to make sure that debuggers will + // be able to show the original source locations + const llvm::MemoryBuffer *u = SM.getBuffer(SM.getFileID(wp._loc)); + if (IntroductionUnit::cast(u)) { + // TODO: Why don't we insert the #line directive into introduced code? Check! + } + else { + clang::PresumedLoc ploc = SM.getPresumedLoc(wp._loc); + ostringstream directive; + // TODO: this seems to be unnecessary as the line mgr issues \n + if (!last_nl) directive << endl; + _line_mgr.directive (directive, ploc); + // TODO: Why wp._loc and not 'loc'? ... + _rewriter->InsertTextAfter (wp._loc, directive.str ()); + } + } + + } + + // clear the list of weaving positions used for this transaction + _positions.clear(); +} + +void WeaverBase::resolve_macros() { + clang::SourceManager &SM = _rewriter->getSourceMgr(); + + for (set::iterator i = _macro_expansions.begin (); + i != _macro_expansions.end (); ++i) { + MacroMap::iterator mm_iter = _macros.find (*i); + if (mm_iter == _macros.end ()) { + cout << "fatal: macro info not found in resolve_macros" << endl; + continue; + } + clang::FileID fid = mm_iter->second._fid; + clang::SourceLocation somewhere_inside = mm_iter->second._somewhere_inside; +// cout << mm_iter->second._expanded_macro_text << endl; + + // expand macro + std::pair range = + SM.getExpansionRange(somewhere_inside); + const clang::RewriteBuffer *RB = _rewriter->getRewriteBufferFor(fid); + if (!RB) { + cout << "fatal: Rewrite buffer not found" << endl; + continue; + } + string str(RB->begin(), RB->end()); +// cout << "Replace macro " << range.first.printToString(SM) << ": " << str << endl; + _rewriter->ReplaceText(clang::SourceRange(range.first, range.second), str); + } + + _macros.clear (); + _macro_expansions.clear (); +} + +bool WeaverBase::commit (clang::SourceManager &Target) { + clang::SourceManager &SM = _rewriter->getSourceMgr(); + + // Resolve weaving positions. + commit_internal(); + + // Put all macros back into the source. + resolve_macros(); + + for (clang::Rewriter::buffer_iterator i = _rewriter->buffer_begin(), + e = _rewriter->buffer_end(); + i != e; ++i) { + if (const clang::FileEntry *FE = SM.getFileEntryForID(i->first)) { + std::string data(i->second.begin(), i->second.end()); +#if CLANG_VERSION_NUMBER <= VERSION_NUMBER_3_5_2 + llvm::MemoryBuffer *Buf = + llvm::MemoryBuffer::getMemBufferCopy(data, FE->getName()); + Target.overrideFileContents(FE, Buf); +#else // C++ 11 interface + Target.overrideFileContents(FE, llvm::MemoryBuffer::getMemBufferCopy(data, FE->getName())); +#endif + } + } + + // renew rewrite + const clang::LangOptions &LO = _rewriter->getLangOpts (); + delete _rewriter; + _rewriter = new clang::Rewriter (Target, LO); + + return true; +} + +// postorder traversal of IntroductionUnits, inserting into their parents. +static void po_intros(WeaverBase &wb, ::ACIntroducer &intro, + IntroductionUnit *unit, unsigned depth = 0) { + std::vector &units = intro.get_intros_for(unit); + + for (unsigned i = 0, e = units.size(); i != e; ++i) + po_intros(wb, intro, units[i], unit ? depth + 1 : depth); + + if (!unit) + return; + + if (const clang::RewriteBuffer *RB = + wb.getRewriter().getRewriteBufferFor(unit->file_id())) { + std::string str(RB->begin(), RB->end()); + if (depth == 0) // Insert the last unit via weave_pos, there may be macros. + wb.insert(wb.weave_pos(unit->location(), WeavePos::WP_AFTER), str); + else + wb.getRewriter().InsertText(unit->location(), str); + } else { +#if CLANG_VERSION_NUMBER <= VERSION_NUMBER_3_5_2 + llvm::StringRef str(unit->buffer()->getBuffer()); +#else // C++ 11 interface + std::unique_ptr buf (unit->buffer()); + llvm::StringRef str(buf->getBuffer()); +#endif + if (depth == 0) // Insert the last unit via weave_pos, there may be macros. + wb.insert(wb.weave_pos(unit->location(), WeavePos::WP_AFTER), str); + else + wb.getRewriter().InsertText(unit->location(), str); + } +} + +bool WeaverBase::resolve_introduction_units(::ACIntroducer &intro) { + // Resolve weaving positions. + commit_internal(); + // Insert introduction units. + po_intros(*this, intro, NULL); + commit_internal(); + resolve_macros(); + return true; +} diff --git a/AspectC++/ClangWeaverBase.h b/AspectC++/ClangWeaverBase.h new file mode 100644 index 0000000..e739ffb --- /dev/null +++ b/AspectC++/ClangWeaverBase.h @@ -0,0 +1,160 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __ClangWeaverBase_h__ +#define __ClangWeaverBase_h__ + +// This class encapsulates all code manipulation or analysis functions +// that are needed by AspectC++, but which do not depend on AspectC++ +// specific classes. They can be seen as a general purpose PUMA extension. + +#include "clang/Rewrite/Core/Rewriter.h" +#include "clang/Frontend/CompilerInstance.h" + +#include "ACModel/Elements.h" + +#include "ACToken.h" +#include "ACIntroducer.h" +#include "ACProject.h" +#include +#include +#include +#include +#include "ClangAnnotation.h" + +class LineDirectiveMgr; + +class WeavePos { +public: + // Attention: the enumerator order is important here ... + enum Pos { WP_HEADER, WP_AFTER, WP_BEFORE, WP_FOOTER }; + int operator < (const WeavePos& key) const { + return _loc == key._loc ? (_pos < key._pos) : (_loc < key._loc); + } + int operator == (const WeavePos& key) const { + return _loc == key._loc && _pos == key._pos; + } +private: + friend class WeaverBase; + WeavePos (clang::SourceLocation loc, Pos p) : _loc (loc), _pos (p) {} + clang::SourceLocation _loc; + Pos _pos; + mutable std::list _strings; +}; + + +class WeaverBase { + + LineDirectiveMgr &_line_mgr; + // These data structures are needed to store and find weaving positions that + // were already used. + typedef std::set WPSet; + WPSet _positions; + + // we need to store all delete (="kill") operations until we reached the commit. + // Otherwise it wouldn't be possible to expand macros in which code was deleted. + typedef std::pair LocPair; + typedef std::list LocPairList; + LocPairList _deletions; + + // macro expansions that are transformed and therefore must be expanded in the woven code: + std::set _macro_expansions; + + // data structure for collecting macro instance information on-the-fly + typedef std::map TokenLocMap; // old location -> new location + struct MacroExpansion { + TokenLocMap _token_loc_map; + TokenLocMap _token_end_loc_map; + string _expanded_macro_text; + clang::SourceLocation _somewhere_inside; + clang::FileID _fid; + clang::SourceLocation startLoc (clang::SourceManager &SM) const { return SM.getLocForStartOfFile(_fid); } + clang::SourceLocation endLoc (clang::SourceManager &SM) const { return startLoc (SM).getLocWithOffset (_expanded_macro_text.size ()); } + }; + + // map for expansion location -> expansion info + typedef std::map MacroMap; + MacroMap _macros; + + clang::Rewriter *_rewriter; + ACProject &_project; + AnnotationMap *_annotation_map; + + void commit_internal (); + void resolve_macros (); + void commit_kills(); + void commit_kill (clang::SourceLocation from, clang::SourceLocation to); + + +public: + WeaverBase (ACProject &prj, LineDirectiveMgr &ldm) : + _line_mgr (ldm), _project (prj), _annotation_map(0) { + clang::SourceManager &SM = prj.get_compiler_instance ()->getSourceManager (); + const clang::LangOptions &LO = prj.get_compiler_instance ()->getLangOpts(); + _rewriter = new clang::Rewriter (SM, LO); + } + + ACProject &project () { return _project; } + clang::Rewriter &getRewriter() { return *_rewriter; } + LineDirectiveMgr &line_directive_mgr () const { return _line_mgr; } + + // deal with C++11-style attributes in the token sequence + // => store location information in a map + // => transform AspectC++-attributes so that they can be parsed by clang + // => make sure user-defined attributes are delete on 'commit' + void set_annotation_map(AnnotationMap *annotation_map) { _annotation_map = annotation_map; } + AnnotationMap &get_annotation_map() { return *_annotation_map; } + void lex_and_filter_attr(clang::Preprocessor &PP, clang::Token &tok); + + // collect and lookup the mapped location of macro tokens + void collect_macro_token (clang::Preprocessor &PP, clang::Token &Result); + bool lookup_macro_token (clang::SourceLocation loc, clang::SourceLocation &mapped_loc); + + const WeavePos &get_pos_after_loc (clang::SourceLocation loc, + WeavePos::Pos pos = WeavePos::WP_AFTER); + + const WeavePos &weave_pos (ClangToken t, int p); + + const WeavePos &weave_pos (clang::SourceLocation loc, int p); + + const WeavePos &header_pos (); + const WeavePos &header_pos (ACFileID fid); + + const WeavePos &footer_pos (); + const WeavePos &footer_pos (ACFileID fid); + + // insert a string at the specified weaving position + // 'before' decides whether the new text is inserted either before (true) + // or after (false) any text that has been inserted earlier at this position. + void insert (const WeavePos &pos, const std::string &str, bool before = false); + + // replace the text between two positions with some new text + void replace (const WeavePos &from, const WeavePos &to, + const std::string &str); + + // kill the text between two positions + void kill (const WeavePos &from, const WeavePos &to); + + // commit a transformation transaction + bool commit (clang::SourceManager &Target); + + // commit introductionunits into their buffers + bool resolve_introduction_units(::ACIntroducer &intro); +}; + +#endif // __ClangWeaverBase_h__ diff --git a/AspectC++/CodeWeaver.cc b/AspectC++/CodeWeaver.cc new file mode 100644 index 0000000..d7e9945 --- /dev/null +++ b/AspectC++/CodeWeaver.cc @@ -0,0 +1,3689 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "CodeWeaver.h" +#include "AspectInfo.h" +#include "AdviceInfo.h" +#include "ACModel/Utils.h" +#include "Naming.h" +#include "IntroductionUnit.h" +#include "NamespaceAC.h" +#include "ACResultBuffer.h" +#include "ModelBuilder.h" + +#ifdef FRONTEND_CLANG +#include "clang/AST/DeclCXX.h" +#include "clang/AST/Expr.h" +#include "clang/AST/RecursiveASTVisitor.h" +#include "llvm/Support/raw_ostream.h" +using namespace clang; +#else +#include "Puma/ErrorSink.h" +#include "Puma/CProtection.h" +#include "Puma/CTemplateInfo.h" +#include "Puma/CClassInfo.h" +#include "Puma/CUnionInfo.h" +#include "Puma/CAttributeInfo.h" +#include "Puma/CFileInfo.h" +#include "Puma/CArgumentInfo.h" +#include "Puma/CFunctionInfo.h" +#include "Puma/CProject.h" +#include "Puma/FileUnit.h" +#include "Puma/CSemDatabase.h" +using namespace Puma; +#endif + +#ifdef FRONTEND_PUMA +void CodeWeaver::setup_tjp (ThisJoinPoint &tjp, CFunctionInfo* func) { + assert (func->Tree ()->NodeName () == CT_FctDef::NodeId ()); + + CT_CmpdStmt *body = ((CT_FctDef*)func->Tree ())->Body (); + for (int i = 0; i < body->Entries (); i++) + setup_tjp (tjp, body->Entry (i)); +} + +void CodeWeaver::setup_tjp (ThisJoinPoint &tjp, CTree *node) { + + const char *nodename = node->NodeName (); + + if (nodename == CT_QualName::NodeId () || + nodename == CT_RootQualName::NodeId()) { + CT_QualName *qual_name = (CT_QualName*)node; + CT_SimpleName *first_name = (CT_SimpleName*)qual_name->Entry (0); + if (first_name->NodeName () == CT_SimpleName::NodeId () && + tjp.check_type (first_name->Text ())) { + if (qual_name->Entries () == 2) { + const char *text = qual_name->Text (); + tjp.check_field (text); + } + } + } + else if (nodename == CT_SimpleName::NodeId ()) { + CT_SimpleName *simple_name = (CT_SimpleName*)node; + if (!tjp.check_obj (simple_name->Text ())) + tjp.check_type (simple_name->Text ()); + } + else if (nodename == CT_MembPtrExpr::NodeId () && + node->Son (0)->NodeName() == CT_SimpleName::NodeId () && + tjp.check_obj (node->Son (0)->token ()->text ())) { + if (node->Son (2)->IsSimpleName ()) + tjp.check_field (node->Son (2)->IsSimpleName ()->Text (), true); + } + + for (int s = 0; s < node->Sons (); s++) + setup_tjp (tjp, node->Son (s)); +} +#else +namespace { +// Visitor to find and register references to the TJP struct. +class TJPVisitor : public RecursiveASTVisitor { + typedef RecursiveASTVisitor Base; + ThisJoinPoint &_tjp; + +public: + explicit TJPVisitor(ThisJoinPoint &tjp) : _tjp(tjp) {} + + bool VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) { + // for typedef C<&JoinPoint::signature> Foo + if (const Type *ty = E->getQualifier()->getAsType()) { + if (_tjp.check_type(TI_Type::get_type_text(QualType(ty, 0), 0, 0, TSEF_DONOTCHANGE, true, TSEF_DONOTCHANGE, false, true, false))) { + _tjp.check_field(E->getDeclName().getAsString().c_str(), true); + } + } + return true; + } + + bool VisitType(Type *T) { + // JoinPoint::Foo + if (const DependentNameType *DNT = T->getAs()) { + if (const Type *ty = DNT->getQualifier()->getAsType()) { + if (_tjp.check_type(TI_Type::get_type_text(QualType(ty, 0), 0, 0, TSEF_DONOTCHANGE, true, TSEF_DONOTCHANGE, false, true, false))) + _tjp.check_field(DNT->getIdentifier()->getNameStart(), true); + } + } + return true; + } + + bool TraverseCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *DSME) { + // tjp->foo + if (!DSME->isImplicitAccess()) { + if (DeclRefExpr *DRE = dyn_cast(DSME->getBase())) + if (_tjp.check_obj(DRE->getDecl()->getNameAsString())) + _tjp.check_field(DSME->getMember().getAsString().c_str()); + } + + // JoinPoint::foo + if (DSME->getQualifier()) { + if (const Type *ty = DSME->getQualifier()->getAsType()) { + if (_tjp.check_type(TI_Type::get_type_text(QualType(ty, 0), 0, 0, TSEF_DONOTCHANGE, true, TSEF_DONOTCHANGE, false, true, false))) + _tjp.check_field(DSME->getMember().getAsString().c_str()); + } + } + + return Base::TraverseCXXDependentScopeMemberExpr(DSME); + } +}; +} + +void CodeWeaver::setup_tjp(ThisJoinPoint &tjp, clang::FunctionDecl *func) { + Stmt *body = func->getBody(); + setup_tjp(tjp, body); +} + +void CodeWeaver::setup_tjp(ThisJoinPoint &tjp, clang::Stmt *node) { + TJPVisitor(tjp).TraverseStmt(node); +} +#endif + +void CodeWeaver::type_check (const ACM_Class *cls, const string &name, bool result) { + + // TODO: type checks in unions might be necessary for call advice - not handled + // TODO: aggregate initialization might be broken by adding virtual functions + const TI_Class *ti = TI_Class::of(*cls); + + // create the code + ostringstream code; + code << endl; + if (ti->is_class ()) + code << "public:" << endl; + code << " virtual bool " << name << " () const { return " + << (result ? "true" : "false") << "; }" << endl; + if (ti->is_class ()) + code << "private:" << endl; + + // paste the function after "{" of the class/struct definition + insert (ti->body_start_pos(*this), code.str (), true); +} + +void CodeWeaver::add_aspect_include (ACM_Any *jpl, AspectInfo &aspect_info, + AspectRef::Kind kind) { + if (jpl && is_pseudo(*jpl)) + return; + + // find the unit (file, macro, or intro) in which the joinpoint is located +#ifdef FRONTEND_PUMA + Unit *iu = TransformInfo::unit (*jpl); + + // if the 'insert unit' is an 'introduction unit', find the intro target unit + IntroductionUnit *intro_unit = 0; + while ((intro_unit = IntroductionUnit::cast (iu)) != 0) + iu = intro_unit->target_unit (); + + _aspect_includes.insert (iu, &aspect_info, kind); +#else + clang::Decl *decl = TransformInfo::decl (*jpl); + // TODO: define a real interface for both, Puma and Clang variant -> ugly code here + if( jpl->type_val() & JPT_Access ) + decl = TI_Access::of( *( static_cast( jpl ) ) )->origin(); + + if (!decl) + return; + + // if the 'insert unit' is an 'introduction unit', find the intro target unit + clang::SourceManager &sm = getRewriter().getSourceMgr(); + SourceLocation result_loc = sm.getExpansionLoc(decl->getLocation()); + const llvm::MemoryBuffer *iu = sm.getBuffer(sm.getFileID(result_loc)); + while (IntroductionUnit *intro_unit = IntroductionUnit::cast(iu)) { + iu = intro_unit->target_unit (); + result_loc = intro_unit->location (); + } + + result_loc = sm.getExpansionLoc(result_loc); + +// _aspect_includes.insert(sm.getFileID(result_loc), &aspect_info, kind); + _aspect_includes.insert(sm.getFileEntryForID (sm.getFileID (result_loc)), + &aspect_info, kind); +#endif +} + +void CodeWeaver::insert_aspect_includes () { + + // weave the aspect includes in all registered unit + for (AspectIncludes::const_iterator iter = _aspect_includes.begin (); + iter != _aspect_includes.end (); ++iter) { + + // generate the includes for the current unit + string includes = _aspect_includes.generate (iter, problems ()); + + // TODO: why do we use clang::FileID here? Shouldn't ACFileID do it? + // determine the insertion position for the current unit + ACFileID unit = _aspect_includes.unit (iter); + + // paste the includes (and optional guard head) at the beginning of the unit + insert (header_pos (unit), includes); + } +} + + +void CodeWeaver::insert_invocation_functions (ACM_Aspect *jpl_aspect, + const string &defs) { + + const TI_Aspect *ti = TI_Aspect::of(*jpl_aspect); +#ifdef FRONTEND_CLANG + // FIXME: This is a hack. In the Clang configuration objdecl_end_pos returns + // the position behind die closing bracket, not the semi colon, + // because Clang doesn't store the SourceLocation in the AST. + string hack_defs = string (";") + defs; + insert (ti->objdecl_end_pos(*this), hack_defs); +#else + // insert the code after the ";" after the aspect definition + insert (ti->objdecl_end_pos(*this), defs); +#endif +} + + +#ifdef FRONTEND_PUMA +void CodeWeaver::open_namespace (ostream &out, const SyntacticContext &ctxt) { + CObjectInfo *obj = ctxt.object (); + CClassInfo *cls = obj->ClassInfo(); + if (cls && cls->TemplateInfo ()) + obj = (CObjectInfo*)cls->TemplateInfo (); + + Array namespaces; + while (!obj->Scope ()->GlobalScope () && obj->Scope ()->NamespaceInfo ()) { + obj = obj->Scope (); + namespaces.append (obj); + } + + for (int i = namespaces.length () - 1; i >= 0; i--) { + if (namespaces[i]->isAnonymous ()) + out << "namespace {" << endl; + else + out << "namespace " << namespaces[i]->Name () << " {" << endl; + } +} +#else +void CodeWeaver::open_namespace (ostream &out, const SyntacticContext &ctxt) { + const DeclContext *obj = cast (ctxt.decl ()); + std::vector namespaces; + while (!obj->getParent()->isTranslationUnit()) { + obj = obj->getParent(); + if (obj->isNamespace()) + namespaces.push_back(cast(obj)); + } + + for (int i = namespaces.size () - 1; i >= 0; i--) { + if (namespaces[i]->isAnonymousNamespace()) + out << "namespace {" << endl; + else + out << "namespace " << namespaces[i]->getNameAsString() << " {" << endl; + } +} +#endif + +#ifdef FRONTEND_PUMA +void CodeWeaver::close_namespace (ostream &out, const SyntacticContext &ctxt) { + CObjectInfo *obj = ctxt.object (); + CClassInfo *cls = obj->ClassInfo(); + if (cls && cls->TemplateInfo ()) + obj = (CObjectInfo*)cls->TemplateInfo (); + + ostringstream ns_close; + while (!obj->Scope ()->GlobalScope () && obj->Scope ()->NamespaceInfo ()) { + obj = obj->Scope (); + out << "} // closed " << (obj->isAnonymous () ? "" : obj->QualName ()) << endl; + } +} +#else +void CodeWeaver::close_namespace (ostream &out, const SyntacticContext &ctxt) { + const DeclContext *obj = ctxt.decl ()->getLexicalDeclContext (); + ostringstream ns_close; + while (obj->isNamespace()) { + const NamespaceDecl *nd = cast(obj); + out << "} // closed " << (nd->isAnonymousNamespace () ? "" : nd->getNameAsString()) + << endl; + obj = obj->getParent(); + } +} +#endif + + +// generate the code, which proceeds an intercepted flow of control, e.g. +// continues a call or execution +void CodeWeaver::make_proceed_code (ostream &out, ACM_Code *loc, + bool action, vector *arg_names) { + TI_Code &ti = *TI_Code::of( *loc ); + TI_Code &cast_ti = ti; + + // find out which entity has to be used for proceeding + ACM_Name *entity = 0; + if( has_entity( *loc ) ) + entity = get_entity( *loc ); + ACM_Function *func = 0; + if( has_entity_func( *loc ) ) + func = get_entity_func( *loc ); + + // set flags that describe the kind of join point + enum { + PM_NONE, + PM_DIRECT, + PM_INDIRECT_ENTITY, + PM_INDIRECT_MEMBER, + PM_BYPASS, + PM_ARGS_ONLY, + PM_OLD + } mode = PM_NONE; + bool wrap = false; + std::string wrap_begin, wrap_end; + bool use_obj = entity && needs_this( *entity ); + bool expr_is_dependent = false; + bool is_obj_const = false; + bool is_inner = false, is_outer = false; + bool need_FQN = ! use_obj; +#ifdef FRONTEND_CLANG + // only used for clang-only features + bool need_idx = false; +#endif + enum { + AM_NONE, + AM_FUNCTION, + AM_OPERATORCALL, + AM_ASSIGN + } args_mode = AM_FUNCTION; + + JoinPointType jpType = loc->type_val(); + if( jpType & JPT_Access ) { +#ifdef FRONTEND_CLANG + TI_Access &ti = static_cast(cast_ti); +#else + // the generalisation were only done for the clang variant + // so fall back to original call API + TI_MethodCall &ti = static_cast(cast_ti); +#endif + + is_outer = true; + mode = PM_DIRECT; + + is_obj_const = ti.target_is_const(); + + if( ti.needs_rights() ) + mode = PM_INDIRECT_ENTITY; + + if( jpType == JPT_Call ) { + TI_MethodCall &ti = static_cast(cast_ti); + + if( ti.needs_rights() ) + mode = PM_BYPASS; + +#ifdef FRONTEND_CLANG + // TODO: implement this check for Puma as well + if (ti.uses_ADN_lookup ()) { + need_FQN = false; + if (ti.is_operator_call ()) { + mode = PM_ARGS_ONLY; + args_mode = AM_OPERATORCALL; + } + } +#endif + } +#ifdef FRONTEND_CLANG + // only supported in Clang variant + else if( jpType == JPT_Builtin ) { + mode = PM_ARGS_ONLY; + args_mode = AM_OPERATORCALL; + } + else if( jpType == JPT_Get ) { + args_mode = AM_NONE; + need_idx = true; + } + else if( jpType == JPT_Set ) { + args_mode = AM_ASSIGN; + need_idx = true; + } + else if( jpType == JPT_GetRef ) { + args_mode = AM_NONE; + mode = PM_INDIRECT_ENTITY; + } + else if( jpType == JPT_SetRef ) { + args_mode = AM_ASSIGN; + mode = PM_INDIRECT_ENTITY; + } + else if( jpType == JPT_Ref ) { + TI_Ref &ti = static_cast(cast_ti); + + args_mode = AM_NONE; + need_idx = true; + if( ti.result_is_ptr() ) { + wrap = true; + wrap_begin = "&( "; + wrap_end = " )"; + } + } +#endif + else { + assert( false && "Unknown JPType !" ); + return; + } + + if( ti.has_target_expr() && ! action && mode != PM_BYPASS ) + use_obj = true; // use obj if we can and have an expression even if not strictly necessary + if( ti.is_qualified() ) + need_FQN = true; // keep existing qualification +#ifdef FRONTEND_CLANG + if( need_idx && ti.entity_index_count() == 0 ) + need_idx = false; // suppress handling if there are no indices +#endif + } + else if ( jpType & ( JPT_Execution | JPT_Construction | JPT_Destruction ) ) { + is_inner = true; + mode = PM_OLD; + + // nothing is done to proceed implicitly defined special member functions + if( ( jpType & ( JPT_Construction | JPT_Destruction ) ) && func->get_builtin() ) + mode = PM_NONE; + } + else { + assert( false && "Unknown JPType !" ); + return; + } + // some consistency checks + assert( is_inner || is_outer ); + if( mode == PM_INDIRECT_ENTITY ) { + need_FQN = false; + use_obj = false; +#ifdef FRONTEND_CLANG + need_idx = false; +#endif + } + else if( mode == PM_INDIRECT_MEMBER ) { + need_FQN = false; + } + else if( mode == PM_BYPASS ) { + need_FQN = false; + } + else if( mode == PM_ARGS_ONLY ) { + need_FQN = false; + } + + // if nothing to do return + if( mode == PM_NONE ) + return; + + // find out if the entity is a member of a class + ACM_Class *dst_cls = entity ? cscope( entity ) : 0; + + // create a local class that enters/leaves the cflow triggers + const CFlowList &cflows = ti.cflows(); + if (cflows.size () > 0) { + out << "{" << endl; + cflows.gen_trigger_obj (out); + } + + // generate the expression that calculates the result + stringstream res; + int args = 0; + + if( wrap ) + res << wrap_begin; + + if( mode == PM_BYPASS ) { + // check privileged calls to external functions + if (!in_project(*func)) { + // calls to "private" externals are not supported, thus the + // target function is "protected" + // => we have to use the target object's class bypass + assert( loc->type_val() == JPT_Call ); + if (((ACM_Call*)loc)->has_target_class()) + dst_cls = ((ACM_Call*)loc)->get_target_class(); + else + dst_cls = (ACM_Class*)lexical_scope(*loc); + } + + res << "::" << signature(*dst_cls) << "::" + << Naming::bypass_caller_class(dst_cls) << "<"; + Naming::bypass_id_class (res, (ACM_Call*)loc); + res << ">::call"; + if (use_obj) { + res << "((::" << signature(*dst_cls) << "*)"; + args++; + } + } + + // if an object is needed for the call, issue 'obj[->]' + if( use_obj ) { + if( is_outer ) { + if (action) + res << "__TJP::target ()"; + else { + res << "(("; + if( is_obj_const ) + res << "const "; + res << "TTarget*)&dst)"; + expr_is_dependent = true; + } + } + else if( is_inner ) { + if (action) + res << "__TJP::that ()"; + else + res << "this"; + } + + if( args == 0 ) { // check if we already have args, which means obj is passed on, else emit member access + res << "->"; + if( expr_is_dependent && mode == PM_DIRECT && jpType == JPT_Call ) { + TI_MethodCall &ti = static_cast( cast_ti ); + if (ti.has_explicit_template_params()) + res << "template "; + } + } + } + + // Generate the name and arguments of the destination function or built-in operator + + // print the namespace names if needed + if( need_FQN ) { + res << name_qualifier( entity ); + } + + // generate the entity name + if( mode == PM_OLD ) { + // use __old_ for execution join points + Naming::exec_inner (res, loc); + } + else if ( mode == PM_DIRECT ) { + // destination entity name + if (func && TI_Function::of(*func)->is_conversion_operator ()) + res << entity->get_name (); + else + res << strip_template_parameters( entity->get_name () ); + } + else if( mode == PM_INDIRECT_ENTITY ) { + if( action ) + res << "*(__TJP::entity())"; + else + res << "ent"; + } + else if( mode == PM_INDIRECT_MEMBER ) { + if( action ) + res << "__TJP::memberptr()"; + else + res << "member"; + } + + if( mode == PM_DIRECT && jpType == JPT_Call ) { + TI_MethodCall &ti = static_cast( cast_ti ); + // add the template arguments if it is a function template instance + bool call_uses_template_params = ti.has_explicit_template_params(); +#ifdef FRONTEND_PUMA + CFunctionInfo *dstfunc = ((TI_Function*)func->transform_info())->func_info (); + CTemplateInstance *instance = dstfunc->TemplateInstance (); + if (instance && call_uses_template_params) { + res << "< "; + for (unsigned a = 0; a < instance->DeducedArgs (); a++) { + if (a > 0) res << ","; + DeducedArgument *arg = instance->DeducedArg (a); + if (arg->Type ()) + arg->Type ()->TypeText (res, "", true, true); + else if (arg->Value ()) { + if (arg->Value ()->isSigned ()) + res << arg->Value ()->convert_to_int (); + else if (arg->Value ()->isUnsigned ()) + res << arg->Value ()->convert_to_uint (); + else if (arg->Value ()->isFloat ()) + res << arg->Value ()->convert_to_float (); + } + else + res << "*invalid template arg*"; + } + res << " >"; + } +#else + if (call_uses_template_params) { + clang::ASTContext &ctx = ti.called()->getASTContext(); + res << "< "; + const TemplateArgumentLoc *template_args = ti.get_explicit_template_params(); + unsigned num_args = ti.num_explicit_template_params(); + for (unsigned a = 0; a < num_args; a++) { + if (a > 0) res << ","; + res << TI_Type::get_templ_arg_text(template_args[a].getArgument (), &ctx, TSEF_ENABLE, true, TSEF_DONOTCHANGE, false, false); + } + res << " >"; + } +#endif + } + + // necessary indices (only supported in clang variant) +#ifdef FRONTEND_CLANG + if( need_idx ) { + assert( jpType & JPT_Access ); + TI_Access &ti = static_cast( cast_ti ); + + unsigned int idx_count = ti.entity_index_count(); + for( unsigned int i = 0 ; i < idx_count; i++ ) { + res << "["; + // Insert current idx: + if( action ) + res << "__TJP::template idx<" << i << ">()"; + else + res << "idx" << i; + res << "]"; + } + } +#endif + + // destination argument expression + if( args_mode != AM_NONE ) { + // Because the built-in-operator-syntax (e.g. arg0 = arg1) differs from + // function-/method-call-syntax (()), we need a new way to handle all + // these different cases as identically as possible. For that purpose we determine + // delimiter-strings, which will be located between the argument-string, for every + // case. After that we can handle all cases the same way. + + int arg_count = get_arg_count(*loc); + std::vector arg_delimiters; + // Determine the delimiters depending on the current case: + if( args_mode == AM_FUNCTION ) { + // if no built-in operator: + + // Generate delimiters: + // Case: "normal" function/method call + // Schema: (arg0, arg1, ..., argN) + // differentiate, depending on weather arguments are already inside "res": + if( args == 0 ) + arg_delimiters.push_back( "(" ); + else if( arg_count > 0 ) + arg_delimiters.push_back( "," ); + else + arg_delimiters.push_back( "" ); + for(int i = 1; i < arg_count; i++) { + arg_delimiters.push_back(", "); + } + arg_delimiters.push_back(")"); + } + // features only supported in Clang variant +#ifdef FRONTEND_CLANG + else if( args_mode == AM_OPERATORCALL ) { + // Case: built-in operator or user-defined operator with ADN-lookup + assert( loc->type_val() == JPT_Builtin || loc->type_val() == JPT_Call); + TI_CommonCall &ti = static_cast( cast_ti ); + // Operator-kind as std::string: + std::string operator_kind = ti.operator_kind_string(); + + // Surround the args with parentheses to preserve the correct operator precedence + // even if a arg will equate to a string like "a, b" (theoretically possible + // because of parameter "arg_names[]"). + if( ti.is_postfix_expr() ) { + // Special case: increment- or decrement-POSTFIX-operator + // Schema: "(arg0)" + arg_delimiters.push_back("(("); + arg_delimiters.push_back(")" + operator_kind + ")"); + arg_count--; // ignore the dummy argument + } + else if( ti.is_unary_expr() ) { + // Unary built-in operator (*, &, +, -, !, ~, ...) + // Schema: "(arg0)" + arg_delimiters.push_back("(" + operator_kind + "(" ); + arg_delimiters.push_back("))"); + } + else if( ti.is_binary_expr() ) { + // Binary built-in operator + // Schema: "(arg0 arg1)" + arg_delimiters.push_back("(("); + arg_delimiters.push_back(") " + operator_kind + " ("); + arg_delimiters.push_back("))"); + } + else if( ti.is_index_expr() ) { + // Special case: array subscript + // Schema: "(arg0[arg1])" + arg_delimiters.push_back("(("); + arg_delimiters.push_back(")["); + arg_delimiters.push_back("])"); + } + else if( ti.is_ternary_expr() ) { + // Special case: conditional operator + // Schema: "(arg0 ? arg1 : arg2)" + arg_delimiters.push_back("(("); + arg_delimiters.push_back(") ? ("); + arg_delimiters.push_back(") : ("); + arg_delimiters.push_back("))"); + } + else + assert( false && "unknow built-in operator type in proceed_code" ); + } + else if( args_mode == AM_ASSIGN ) { + arg_delimiters.push_back( " = (" ); // entity is already inside + arg_delimiters.push_back( ")" ); + } +#endif // FRONTEND_CLANG + + // Add the delimiter- and arg-strings: + // Insert first delimiter (necessary due to the case where argument-count equals + // zero or bypass is needed) + res << arg_delimiters.front(); + for (int a = 0 ; a < arg_count; a++, args++) { + // Insert current delimiter: + if(a > 0) { // Since the first delimiter was inserted already + res << arg_delimiters.at(a); + } + // Insert current arg: + if (action) { + // make sure that if the argument type was a reference we use the + // referred type here + res << "*(typename __TJP::template Arg<" << a + << ">::ReferredType*)__TJP::arg(" << a << ")"; + } + else { + if (arg_names) + res << (*arg_names)[a]; + else + res << "arg" << a; + } + } + // Insert last delimiter (generally the closing parenthesis): + res << arg_delimiters.back(); + } + + if( wrap ) + res << wrap_end; + + // generate the 'result =' code + // TODO: better pass result_buffer as parameter + ACResultBuffer result_buffer (project (), loc, is_outer); +#ifdef FRONTEND_CLANG + // inform buffer about const forced resulttype + if( loc->type_val() == JPT_Builtin && static_cast( ti ).is_forwarding() ) + result_buffer.has_const_result(); +#endif + + out << " "; + if (action) + out << result_buffer.action_result_assignment(res.str ()); + else + out << result_buffer.result_assignment(res.str ()); + out << ";" << endl; + + if (cflows.size () > 0) + out << "}" << endl; +} + +#ifdef FRONTEND_CLANG +// only required for features of the Clang variant +void CodeWeaver::make_proceed_to_implicit( ostream &out, ACM_Code *loc, bool action, vector *arg_names ) { + out << " /* Implicit joinpoint calls */" << endl; + + assert( loc->type_val() == JPT_Builtin ); + ACM_Builtin &parent_jpl = *( static_cast( loc ) ); + TI_Builtin &parent_ti = *TI_Builtin::of( parent_jpl ); + std::string op_string = parent_ti.operator_kind_string(); + + typedef ACM_Container Container; + Container &implicit = parent_jpl.get_implicit_access(); + Container::const_iterator it = implicit.begin(); + + bool packed_entity = has_complex_entity( *it ); + + string ent; + string new_val; + string that; + string packed; + if( action ) { + // make sure that if the argument type was a reference we use the + // referred type here + ent = "*(typename __TJP::template Arg<0>::ReferredType*)__TJP::arg(0)"; + new_val = "*(typename __TJP::template Arg<0>::ReferredType*)__TJP::arg(1)"; + that = "__TJP::that ()"; + packed = "*__TJP::__wormhole"; + } + else { + if( arg_names ) { + ent = (*arg_names)[0]; + new_val = (*arg_names)[1]; + } + else { + ent = "arg0"; + new_val = "arg1"; + } + that = "srcthis"; + packed = "__packed"; + } + + // make the nested wrapper calls + if( parent_ti.is_compound_assignment() ) { + assert( *it && ( *it )->type_val() & ( JPT_Get | JPT_GetRef ) ); + ACM_Access *jpl = static_cast( *it++ ); + TI_Access *ti = TI_Access::of( *jpl ); + + out << " "; + out << ti->result_type_string() << " __new_value = "; + + if( jpl->has_plan() ) { + stringstream close; + bool args = generate_access_wrapper( jpl, out, close, that.c_str() ); + + if( args ) + out << ", "; + out << ( packed_entity ? packed : ent ); + + out << close.str(); + } + else { + // no advice to weave for this joinpoint + // fallback to direct eval + out << ent; + } + out << ";" << endl; + + if( parent_ti.is_postfix_expr() ) { + // generate the 'result =' code + // TODO: better pass result_buffer as parameter + ACResultBuffer result_buffer( project(), loc, true ); + // inform buffer about const forced resulttype + if( parent_ti.is_forwarding() ) + result_buffer.has_const_result(); + + out << " "; + if( action ) + out << result_buffer.action_result_assignment( "__new_value" ); + else + out << result_buffer.result_assignment( "__new_value" ); + out << ";" << endl; + } + + // perform the compound operation + assert( parent_ti.is_binary_expr() || parent_ti.is_unary_expr() || parent_ti.is_postfix_expr() ); + if( parent_ti.is_binary_expr() ) + out << " __new_value " << op_string << " " << new_val << ";" << endl; + else if( parent_ti.is_unary_expr() ) + out << " " << op_string << "__new_value;" << endl; + else if( parent_ti.is_postfix_expr() ) + out << " __new_value" << op_string << ";" << endl; + new_val = "__new_value"; // use the computed value for set + } + + if( ( op_string == "=" ) || parent_ti.is_compound_assignment() ) { + assert( *it && ( *it )->type_val() & ( JPT_Set | JPT_SetRef ) ); + ACM_Access *jpl = static_cast( *it++ ); + + if( jpl->has_plan() ) { + out << " "; + + stringstream close; + bool args = generate_access_wrapper( jpl, out, close, that.c_str() ); + + if( args ) + out << ", "; + out << ( packed_entity ? packed : ent ); + out << ", "; + out << new_val; + + out << close.str() << ";" << endl; + } + else { + // no advice to weave for this joinpoint + // fallback to direct eval + out << " " << ent << " = " << new_val << ";" << endl; + } + + if( ! parent_ti.is_postfix_expr() ) { + // generate the 'result =' code + // TODO: better pass result_buffer as parameter + ACResultBuffer result_buffer( project(), loc, true ); + // inform buffer about const forced resulttype + if( parent_ti.is_forwarding() ) + result_buffer.has_const_result(); + + out << " "; + if( action ) + out << result_buffer.action_result_assignment( ent ); + else + out << result_buffer.result_assignment( ent ); + out << ";" << endl; + } + } + else if( op_string == "&" ) { + assert( *it && ( *it )->type_val() == JPT_Ref ); + ACM_Ref *jpl = static_cast( *it++ ); + + stringstream wrapper; + stringstream close; + bool args = generate_access_wrapper( jpl, wrapper, close, that.c_str() ); + + if( args ) + wrapper << ", "; + wrapper << ( packed_entity ? packed : ent ); + + wrapper << close.str(); + + // generate the 'result =' code + // TODO: better pass result_buffer as parameter + ACResultBuffer result_buffer( project(), loc, true ); + // inform buffer about const forced resulttype + if( parent_ti.is_forwarding() ) + result_buffer.has_const_result(); + + out << " "; + if( action ) + out << result_buffer.action_result_assignment( wrapper.str() ); + else + out << result_buffer.result_assignment( wrapper.str() ); + out << ";" << endl; + } +} +#endif + +// create an action wrapper function, which may be invoked by 'proceed()' +void CodeWeaver::make_action_wrapper(ostream &impl, ACM_Code *loc, int depth) { + // generate the action function, which is used to obtain an action object + impl << " AC::Action &action() {" << endl; + impl << " this->__TJP::_wrapper = &"; + Naming::action_wrapper (impl, loc, depth); + impl << ";" << endl; + impl << " return *this;" << endl; + impl << " }" << endl; + + // make the function static if it is defined in class scope + impl << " static void "; + Naming::action_wrapper (impl, loc, depth); + impl << " (AC::Action &action) {" << endl; + // convert the action object ref into a TJP_... object ref and call proceed + impl << " ((__TJP&)action).proceed ();" << endl; + + impl << " }" << endl; +} + +// create the 'proceed()' function for the current level +void CodeWeaver::make_proceed_func( ostream &impl, ACM_Code *loc, ACM_CodePlan *plan, bool has_wormhole ) { + + const ThisJoinPoint &tjp = + TI_AdviceCode::of (*plan->get_around()->get_advice())->this_join_point (); + + // the signature + impl << " "; + if (tjp.proceed_calls() == 1 && _problems._use_always_inline) + impl << "__attribute__((always_inline)) "; + impl << "void proceed () {" << endl; + + if (depth(*plan) == 0) { + // this is a proceed function for the last around advice + // the implicit joinpoints are only supported in the clang variant +#ifdef FRONTEND_CLANG + if( TI_Code::of( *( static_cast( loc ) ) )->has_implicit_joinpoints() ) + make_proceed_to_implicit( impl, loc, true ); + else +#endif + make_proceed_code( impl, loc, true ); + } + else { + // generate __TJP type (for the next level) + impl << " typedef "; + Naming::tjp_struct (impl, (ACM_Code*)loc, depth (*plan) - 1); + impl << "type_val() & ( JPT_Access & ~ ( JPT_Call | JPT_Builtin ) ) ) { + impl << "TDims, "; + } +#endif + impl << "TArgs"; + if( has_wormhole ) + impl << ", TWORMHOLE"; + impl << "> __TJP;" << endl; + + // generate advice calls + make_advice_calls (impl, plan->get_next_level(), loc, true); + } + impl << " }" << endl; +} + +// generate the name of the joinpoint-specific TJP type +void CodeWeaver::make_tjp_typename( ostream &out, ACM_Code *loc, int depth, ACResultBuffer &rb, const char *wormhole_type ) { + TI_Code *ti = (TI_Code*)TransformInfo::of (*loc); + Naming::tjp_struct (out, loc, depth); + out << "< " << rb.tjp_result_type() << ", "; +#ifdef FRONTEND_PUMA + ti->that_type ()->TypeText (out, "", true, true); +#else + out << ti->that_type_string(); +#endif + out << ", "; +#ifdef FRONTEND_PUMA + if( loc->type_val() == JPT_Call && static_cast( ti )->has_target_expr() ) { + // TODO: is this case needed at all? + if (((TI_MethodCall*)ti)->target_is_const()) +#else + if( ( loc->type_val() & JPT_Access ) && static_cast( ti )->has_target_expr() ) { + // TODO: is this case needed at all? + if( static_cast( ti )->target_is_const() ) +#endif + out << "const "; + out << "TTarget"; + } + else +#ifdef FRONTEND_PUMA + ti->target_type ()->TypeText (out, "", true, true); +#else + out << ti->target_type_string(); + + // entity functionallity is only supported in Clang variant + out << ", "; + // TODO: check get/set stuff + if (loc->type_val() & JPT_Call) { + out << rb.tjp_result_type() << " ("; + list arg_types; + get_arg_types (*loc, arg_types); + unsigned a = 0; + for (list::iterator i = arg_types.begin(); i != arg_types.end(); ++i) { + if (a > 0) + out << ","; + out << "TArg" << a; + a++; + } + out << ")"; + ACM_Function *function = (static_cast(loc))->get_target(); + switch (function->get_cv_qualifiers()) { + case CVQ_CONST: out << " const"; break; + case CVQ_VOLATILE: out << " volatile"; break; + case CVQ_CONST_VOLATILE: out << " const volatile"; break; + default: break; + } + } + else + out << ti->entity_type_string(); + + if (loc->type_val() & ( JPT_Access & ~ ( JPT_Call | JPT_Builtin ) ) ) { + TI_Access *tiA = static_cast( ti ); + const unsigned int idx_count = tiA->entity_index_count(); + + out << ", "; + for( unsigned int i = 0; i < idx_count; i++ ) + out << "AC::DIL< " << tiA->entity_index_dimension( i ) << ", " << tiA->entity_index_type( i ) << ", "; + out << "AC::DILE"; + for( unsigned int i = 0; i < idx_count; i++ ) + out << " >"; + } +#endif + // argument types + unsigned arg_count = get_arg_count (*loc); + out << ", "; + list arg_types; + get_arg_types (*loc, arg_types); + unsigned a = 0; + for (list::iterator i = arg_types.begin(); i != arg_types.end(); ++i) { + out << " AC::TL< "; +#ifdef FRONTEND_PUMA + if( loc->type_val() != JPT_Call ) { + CTypeInfo *argtype = TI_Type::of (**i)->type_info (); + argtype->TypeText (out, "", true, true); + } +#else + if( (loc->type_val() & JPT_Access) == 0 ) + out << ti->arg_type_string( a ); +#endif + else + out << "TArg" << a; + out << ","; + a++; + } + out << " AC::TLE"; + for (unsigned a = 0; a < arg_count; a++) + out << " >"; + + if( wormhole_type ) + out << ", " << wormhole_type; + + out << " >"; + } + +// insert TJP class definition before join point +void CodeWeaver::make_tjp_struct(ostream &out, ACM_Code *loc, + ACM_CodePlan *plan, const ThisJoinPoint &tjp) { + + int depth = ::depth (*plan); + // recursively call the function for the previous TJP classes + if (depth > 0) { + make_tjp_struct (out, loc, plan->get_next_level(), tjp); + } + + // generate the definition + out << endl; + tjp.gen_tjp_struct (out, loc, _problems, depth); + + // generate the proceed function for the current structure + if (plan->has_around()) { + const ThisJoinPoint &curr_tjp = + TI_AdviceCode::of (*plan->get_around()->get_advice())->this_join_point (); + if (curr_tjp.proceed () || curr_tjp.action() || + !TI_CodeAdvice::of(*plan->get_around())->get_advice_info()->pointcut().cflow_triggers ().empty ()) + make_proceed_func( out, loc, plan, tjp.has_wormhole() ); + + // generate action wrapper if needed + if (curr_tjp.action()) + make_action_wrapper (out, loc, depth); + } + + if (depth == 0) { + stringstream jpname; + Naming::tjp_struct(jpname, loc, 0); + gen_binding_templates (out, loc->get_plan(), jpname.str ().c_str ()); + } + + // closing bracket of the TJP class! Opened in gen_tjp_struct. + out << "};" << endl; + + out << endl; +} + + +// generates the signature of a wrapper function for exec/cons/dest join pts +string CodeWeaver::wrapper_function_signature (ACM_Code *loc, + const SyntacticContext &sctxt, bool def) { + + ACM_Function *function = (ACM_Function*)loc->get_parent (); + + // TODO: implement for Clang variant +#ifdef FRONTEND_PUMA + set used_args; + bool search_args = (def && function->get_kind() == FT_CONSTRUCTOR); + if (search_args) + sctxt.search_used_args (used_args); +#endif // FRONTEND_PUMA + + stringstream name_args; + if (sctxt.qualified_scope() != "" && + sctxt.syntactical_scope() != sctxt.qualified_scope()) + name_args << sctxt.qualified_scope() << "::"; + Naming::exec_inner (name_args, loc); + name_args << "("; + for (unsigned a = 0; a < sctxt.args(); a++) { + if (sctxt.arg_type(a) == "void") + break; + if (a > 0) name_args << ","; + string name = sctxt.arg_name(a); +#ifdef FRONTEND_PUMA + if (name != "" && search_args && used_args.find (name) == used_args.end ()) + name = ""; +#endif // FRONTEND_PUMA + name_args << sctxt.arg_type(a, name); + } + name_args << ")"; + + ostringstream wrapped; + + if (_problems._use_always_inline) // GNU extension + wrapped << "__attribute__((always_inline)) "; + wrapped << "inline "; // the wrapped function should always be inlined + if (function->get_kind() == FT_STATIC_MEMBER && sctxt.is_in_class_scope()) + wrapped << "static "; + + if (function->get_kind() == FT_CONSTRUCTOR || + function->get_kind() == FT_DESTRUCTOR || + function->get_kind() == FT_VIRTUAL_DESTRUCTOR || + function->get_kind() == FT_PURE_VIRTUAL_DESTRUCTOR) + wrapped << "void " << name_args.str ().c_str (); + else { + wrapped << sctxt.result_type (name_args.str ()); + switch (function->get_cv_qualifiers()) { + case CVQ_CONST: wrapped << " const"; break; + case CVQ_VOLATILE: wrapped << " volatile"; break; + case CVQ_CONST_VOLATILE: wrapped << " const volatile"; break; + default: break; + } + } + + return wrapped.str (); +} + +void CodeWeaver::cons_join_point (ACM_Construction *loc) { + // if you change this check, please update Transformer::join_points too + if (((ACM_Name*)loc->get_parent ())->get_builtin()) + gen_special_member_function (loc); + else + wrap_function (loc); +} + +void CodeWeaver::dest_join_point (ACM_Destruction *loc) { + if (((ACM_Name*)loc->get_parent ())->get_builtin()) + gen_special_member_function (loc); + else + wrap_function (loc); +} + +void CodeWeaver::gen_special_member_function (ACM_Code *loc) { + + assert (((ACM_Name*)loc->get_parent ())->type_val () == JPT_Function); + ACM_Function *func = (ACM_Function*)loc->get_parent (); + assert (((ACM_Name*)func->get_parent ())->type_val () & (JPT_Class|JPT_Aspect)); + ACM_Class *cls = (ACM_Class*)func->get_parent (); + + // check if the special member would have to call a private member + if (func->get_kind () == FT_CONSTRUCTOR && get_arg_count (*func) == 0) { + if (!TI_Class::of (*cls)->may_have_implicit (TI_Class::CONSTRUCTOR)) + return; + } + else if (func->get_kind () == FT_CONSTRUCTOR && get_arg_count (*func) == 1) { + // if you change this check, please update TI_Class::remember_builtin_copyconstructor_advice too + if (!TI_Class::of (*cls)->may_have_implicit (TI_Class::COPY_CONSTRUCTOR)) + return; + } + else if (func->get_kind () == FT_DESTRUCTOR || + func->get_kind () == FT_VIRTUAL_DESTRUCTOR || + func->get_kind () == FT_PURE_VIRTUAL_DESTRUCTOR) { + if (!TI_Class::of (*cls)->may_have_implicit (TI_Class::DESTRUCTOR)) + return; + } + + ostringstream code; + // create thisJoinPoint class + ThisJoinPoint tjp; + tjp.merge_flags(*loc->get_plan()); +#ifdef FRONTEND_CLANG + // only required for features in the Clang variant + tjp.enable_entity(); +#endif + if (tjp.type_needed ()) { + ostringstream wrappers; + make_tjp_struct(wrappers, loc, loc->get_plan(), tjp); + insert (TI_Class::of (*cls)->body_end_pos(*this), wrappers.str ()); + } + + // generate the function itself + code << endl << "public:" << endl << "inline " << func->get_name(); + + // constructors or destructors don't have more than one argument + assert (get_arg_count(*func) <= 1); + + if (get_arg_count(*func) == 0) { + // default constructor or destructor + code << " () {" << endl; + } + // if you change this check, please update Transformer::join_points too + else { + // get information on all attributes of this class + list attrs; + TI_Class::of (*cls)->get_member_contexts (attrs); + + // generate a unique wrapper class for all attributes that are arrays + for (list::iterator i = attrs.begin (); i != attrs.end (); ++i) { + // if you change this check, please update CodeWeaver::is_wrapped_array too + if ((*i).is_array () && !(*i).is_anon_union_member ()) + wrap_attribute_array (*i, attrs); + } + + // generate the copy constructor + ostringstream copy_cons; + bool arg_needed = tjp.arg_needed ((ACM_Code*)loc); + // copy the baseclass members + bool first_initializer = true; + typedef ACM_Container Bases; + Bases &bases = cls->get_bases(); + for (Bases::iterator b = bases.begin (); b != bases.end (); ++b) { + if (first_initializer) { + first_initializer = false; + copy_cons << ": "; + } + else + copy_cons << ", "; + copy_cons << signature (**b) << " (arg0)"; + arg_needed = true; + } + + for (list::iterator i = attrs.begin (); i != attrs.end (); ++i) { + + // make sure members of anonymous unions in this class are handled differently + if ((*i).is_anon_union_member ()) + continue; + + // write ':' or ',' + if (first_initializer) { + first_initializer = false; + copy_cons << ": "; + } + else + copy_cons << ", "; + // initialize the member by copy-constructor + copy_cons << (*i).name () << " (arg0." << (*i).name () << ")"; + arg_needed = true; + } + copy_cons << " {" << endl; + + // copy anonymous unions + set unions; // to remembers unions that are already handled + for (list::iterator i = attrs.begin (); i != attrs.end (); ++i) { + + // only members of anonymous unions are handled here + if (!(*i).is_anon_union_member ()) + continue; + + SyntacticContext union_context = (*i).get_anon_union_context (); + if (unions.find (union_context) == unions.end ()) { + // create a named local copy of the union definition + const int count = unions.size (); + copy_cons << " union __ac_union_" << count << " "; + string u = union_context.get_as_string (1); + copy_cons << u.substr (u.find ("{")); + copy_cons << ";" << endl; + copy_cons << " *(union __ac_union_" << count << "*)&" << (*i).name () + << " = *(union __ac_union_" << count << "*)&arg0." + << (*i).name () << ";" << endl; + arg_needed = true; + unions.insert (union_context); + } + } + + list arg_types; + get_arg_types (*func, arg_types); + code << " ("; +#ifdef FRONTEND_PUMA + // TODO: Fix Puma-variant: better use a TransformInfo function for printing + // e.g. "::classname& arg0" must be avoided! + if (arg_needed) + code << format_type (*arg_types.front (), "arg0"); + else + code << format_type (*arg_types.front ()); +#else + code << TI_Code::of(*loc)->arg_type_string(0); + if (arg_needed) + code << " arg0"; +#endif + code << ") " << copy_cons.str (); + } + + ACResultBuffer result_buffer (project (), loc); + // generate __TJP type (for this level) + if (tjp.type_needed ()) { + code << " typedef "; + make_tjp_typename (code, loc, depth (*loc->get_plan()), result_buffer); + code << " __TJP;" << endl; + } + + // generate common JoinPoint initialization + tjp.gen_tjp_init(code, loc, _problems, depth (*loc->get_plan()), false, 0); + + // generate calls to advice code or original function + make_advice_calls(code, loc->get_plan(), loc); + + code << endl << "}" << endl; + + // insert the definition + insert (TI_Class::of (*cls)->body_end_pos(*this), code.str ()); +} + +void CodeWeaver::wrap_attribute_array (const SyntacticContext &attr_ctxt, + list &attrs) { + bool first = true; + list::iterator last = attrs.end (); + for (list::iterator i = attrs.begin (); i != attrs.end (); ++i) { + if (attr_ctxt.objdecl_start_pos (*this) == (*i).objdecl_start_pos (*this)) { + if (!first) + insert ((*i).objdecl_start_pos (*this), "; "); + else + first = false; + if (attr_ctxt.name () == (*i).name ()) + insert ((*i).objdecl_start_pos (*this), gen_wrapped_array(*i)); + else + insert ((*i).objdecl_start_pos (*this), (*i).get_as_string ()); + last = i; + } + } + if (last != attrs.end ()) + kill ((*last).objdecl_start_pos (*this), (*last).objdecl_end_pos (*this)); +} + +string CodeWeaver::gen_wrapped_array (const SyntacticContext &attr_ctxt) { + ostringstream out; + out << endl; + out << " struct __ac_wrapper_" << attr_ctxt.name () << " {" << endl; + out << " struct __ac_P { typedef " << attr_ctxt.get_as_string () << "; };" << endl; + out << " template struct __ac_T {};" << endl; + out << " template struct __ac_T { typedef T Type; };" << endl; + out << " typedef __ac_P::"<< attr_ctxt.name () << " __ac_A;" << endl; + out << " typedef __ac_T<__ac_P::" << attr_ctxt.name () << ">::Type __ac_E;" << endl; + // the offset of _data inside the wrapper struct has to be 0, else many things break + // ( especially passing of member pointers on array access, but it is more on the line ) + out << " __ac_A _data;" << endl; + out << " operator __ac_A& () const { return (__ac_A&)_data; }" << endl; + out << " operator const __ac_A& () const { return (const __ac_A&)_data; }" << endl; + out << " __ac_A* operator &() { return &_data; }" << endl; + out << " const __ac_A * operator &() const { return &_data; }" << endl; + out << " operator void* () const { return (void*)&_data; }" << endl; + out << " operator const void* () const { return (const void*)&_data; }" << endl; + out << " template __ac_E& operator [] (I i) " + << "{ return _data[i]; } // for VC++ 2003" << endl; + out << " template const __ac_E& operator [] (I i) const " + << "{ return _data[i]; } // for VC++ 2003" << endl; + out << " } " << attr_ctxt.name (); + return out.str (); +} + +void CodeWeaver::exec_join_point (ACM_Execution *loc) { + wrap_function (loc); +} + +void CodeWeaver::wrap_function (ACM_Code *loc) { + + ACM_Function *function = (ACM_Function*)loc->get_parent (); + + const vector &decl_contexts = + TI_Function::of(*function)->syntactic_contexts(); + if (function->get_variadic_args ()) { +#ifdef FRONTEND_PUMA + _err << sev_warning << decl_contexts.begin()->error_pos()->location () + << "can't weave execution advice for function '" + << signature(*function).c_str() << "' with variable arguments" + << endMessage; +#endif + return; + /* + * Functions with variable arguments require a dedicated code + * transformation. This could be implemented via function-template + * wrappers. + * + * Example: + * + * void printf(char*, ...); + * + * || + * \/ + * + * template + * void printf(char* s, T1 t1) { + * [...]; __exec_old_printf(s, t1); } + * + * template + * void printf(char* s, T1 t1, T2 t2) { + * [...]; __exec_old_printf(s, t1, t2); } + * + * + * These template wrappers need to be generated for a fixed amount + * of parameters, which could be made configurable via a command + * line option. For C++11, a single variadic template would be + * sufficient. + * + * However, this code transformation does not fit so well into the + * current transformation scheme. As opposed to it, these template + * wrapper have to be generated at each function declaration (a + * preprocessor guard could be used to avoid multiple definitions). + * Additionally, separate JoinPoint structures have to be generated + * for each number of template parameters, since the proceed() + * function needs to know the amount of arguments to pass to + * __exec_old_printf. + * + * At the functions definition, these wrappers have to be generated + * as well, for instance if no declaration was found before. The + * body of these template wrappers needs to be generated in both + * cases (at each function declaration and its definition). The + * original function just has to be renamed (__exec_old_printf). + * + * Finally, the generation of the separate JoinPoint structures, + * for each number of template parameters, would require to extend + * the current (already complicatad) JoinPoint-structure generation. + * + * Caveats: + * - C linkage of the the function is lost (template wrappers) + * - it has be ensured that no similar function template exists + * in the same scope (as the wrapper), which would otherwise lead + * to multiple definitions + * - gcc won't inline the __exec_old vararg function, + * see: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=10980 + * -> __attribute__((always_inline)) must not be used here + * + */ + } + + // handle each declaration and the optional definition separately + // the transform info object yield the necessary syntactic context + bool wrapped_decl = false; + const SyntacticContext *def_context = 0; + for (vector::const_iterator i = decl_contexts.begin (); + i != decl_contexts.end (); ++i) { + if ((*i).is_definition ()) + def_context = &(*i); + else { + if (wrap_function_decl (loc, *i)) + // friend declarations have an assigned scope. They are no real + // declarations. Another declaration has to be generated. + if (!(*i).has_assigned_scope ()) + wrapped_decl = true; + } + } + // if a definition has been found, wrap it + if (def_context) + wrap_function_def (loc, *def_context, wrapped_decl); + +} + +static string close_extern_c_block (int extern_c_depth) { + ostringstream result; + for (int i = 0; i < extern_c_depth; i++) + result << "} "; + result << endl << endl; + return result.str (); +} + +static string reopen_extern_c_block (int extern_c_depth) { + ostringstream result; + result << endl; + for (int i = 0; i < extern_c_depth; i++) + result << "extern \"C\" { "; + result << endl; + return result.str (); +} + +// create a new function implementation and paste it behind the original +void CodeWeaver::wrap_function_def (ACM_Code *loc, const SyntacticContext &sctxt, + bool wrapped_decl) { + + ACM_Function *function = (ACM_Function*)loc->get_parent (); + ostringstream pre_sig, pre_body; + + bool have_pre_sig = false; + pre_sig << endl; + + // the first is the declaration of the inner function (the original) + // not necessary for methods and if there is a declaration anyway + if (!wrapped_decl && + (function->get_kind() == FT_NON_MEMBER || + function->get_kind() == FT_STATIC_NON_MEMBER)) { + have_pre_sig = true; + pre_sig << wrapper_function_signature (loc, sctxt, true) << ";" << endl; + } + + // generate the JoinPoint class + ThisJoinPoint tjp; + tjp.merge_flags(*loc->get_plan()); +#ifdef FRONTEND_CLANG + // only required for features in the Clang variant + tjp.enable_entity(); +#endif + + if (tjp.type_needed ()) { + have_pre_sig = true; + int extern_c_depth = sctxt.is_in_extern_c_block(); + if (extern_c_depth > 0) + pre_sig << close_extern_c_block(extern_c_depth); + make_tjp_struct(pre_sig, loc, loc->get_plan(), tjp); + if (extern_c_depth > 0) + pre_sig << reopen_extern_c_block(extern_c_depth); + } + + // paste pre-signature code in front of the old function signature + if (have_pre_sig) // check only for better readability + insert (sctxt.wrapper_pos(*this), pre_sig.str ()); + + // rename the arguments of the original declaration + vector arg_names; + rename_args (sctxt, "arg", arg_names); + + // if the function is the "main()" function and if it does not contain a + // return statement at the end, generate one ("return 0;") + if (function->get_name() == "main" && + signature(*(ACM_Name*)function->get_parent()) == "::" && + !sctxt.ends_with_return()) + insert (sctxt.fct_body_end_pos (*this), "return 0;\n"); + // generate the body of the wrapper function + ACResultBuffer result_buffer (project (), loc); + + pre_body << "{" << endl; + +#ifdef FRONTEND_CLANG + bool have_Member = needs_this( *function ); + // feature is supported in Clang only + // compute/generate missing parameters + // typedefs for missing types first ... + if (tjp.entity_needed(loc) || tjp.memberptr_needed(loc)) { + ostringstream out; + out << "TEntity ("; + for( int a = 0; a < get_arg_count(*function); a++ ) { + if( a > 0 ) + out << ","; + out << sctxt.arg_type (a); + } + out << ")"; + pre_body << " typedef " << sctxt.result_type (out.str()) << ";" << endl; + + bool init_needed = false; + if (have_Member) { + if (tjp.memberptr_needed(loc)) { + pre_body << " TEntity " << name_qualifier( function ) << "*member = &"; + init_needed = true; + } + } + else { + if (tjp.entity_needed(loc)) { + pre_body << " TEntity &ent = "; + init_needed = true; + } + } + if (init_needed) + pre_body << name_qualifier( function ) << function->get_name() << ";" << endl; + } +#endif + + // generate __TJP type (for this level) + if (tjp.type_needed ()) { + pre_body << " typedef "; + make_tjp_typename (pre_body, loc, depth (*loc->get_plan()), result_buffer); + pre_body << " __TJP;" << endl; + } + + // declare the result object + pre_body << " " << result_buffer.result_declaration (); + + // generate common JoinPoint initialization + tjp.gen_tjp_init(pre_body, loc, _problems, depth (*loc->get_plan()), + false, &arg_names); + + // generate calls to advice code or original function + make_advice_calls (pre_body, loc->get_plan(), loc, false, &arg_names); + + pre_body << " " << result_buffer.result_return (); + pre_body << endl << "}" << endl; + + // generate the signature of the inner function (the original) + // special treatment for operator new/delete/new[]/delete[] + if (function->get_kind () == FT_MEMBER && !needs_this(*function) && !wrapped_decl) + pre_body << "static "; + // add a wrapper function declaration + pre_body << wrapper_function_signature (loc, sctxt, true); + + // insert the new body and new signature in front of the old body + insert(sctxt.fct_body_start_pos (*this), pre_body.str ()); +} + + +// create a new declaration for a wrapped function +bool CodeWeaver::wrap_function_decl (ACM_Code *loc, const SyntacticContext &sctxt) { + + ACM_Function *function = (ACM_Function*)loc->get_parent (); + + // check if the function declaration belongs to the project and is not built-in + // if it does not, we cannot insert the wrapper declaration + if (!sctxt.is_in_project()) + return false; + + string inner_decl; + if (sctxt.is_in_class_scope ()) + inner_decl += "public: "; + // special treatment for friend declarations + if (sctxt.has_assigned_scope ()) + inner_decl += "friend "; + // special treatment for operator new/delete/new[]/delete[] => implicitly static + if (function->get_kind () == FT_MEMBER && !needs_this(*function)) + inner_decl += "static "; + // add the wrapper function declaration + inner_decl += wrapper_function_signature (loc, sctxt, false); + inner_decl += ";"; + // switch to the right protection if needed + inner_decl += "\n"; + if (sctxt.protection() != "" && sctxt.protection() != "public") + inner_decl += sctxt.protection() + ":\n"; + + // move the generated declaration in front of the original declaration + insert (sctxt.wrapper_pos(*this), inner_decl); + + return true; +} + + +void CodeWeaver::make_advice_call(ostream &out, ACM_Code *loc, + AdviceInfo *ai, bool inter, int depth) { + assert((loc->type_val () & JPT_Access) || loc->type_val () == JPT_Execution || + loc->type_val () == JPT_Construction || loc->type_val () == JPT_Destruction ); + + // Get the correct JoinPoint object: + PointCut &pc = ai->pointcut (); + PointCut::iterator jp_iter = pc.find (loc); + assert (jp_iter != pc.end ()); + const JoinPoint &jp = *jp_iter; + + // Name of the TJP-instance: + ostringstream tjp_instance_name; + Naming::tjp_instance(tjp_instance_name, loc); + + // Determine helper strings: + string tjp_tp = "__TJP"; + string tjp_obj = inter ? "this" : "&" + tjp_instance_name.str(); + + // If there should be a condition, then insert the check: + string this_name; + string tjp_access_prefix; + if (jp.condition ()) { + // Determine helper strings: + if(inter) { + tjp_access_prefix = tjp_tp + "::"; + + this_name = tjp_access_prefix + "_that"; + } + else { + tjp_access_prefix = tjp_instance_name.str() + "."; + + if (loc->type_val () & JPT_Access) { + this_name = "srcthis"; + } + else { // Execution, Construction or Destruction + this_name = "this"; + } + } + // Insert check: + out << " if("; + jp.condition ().gen_check (out, ai, this_name.c_str(), &tjp_access_prefix); + out << ") {" << endl << " "; + } + + // Generate the call that invokes the advice code + out << " "; + ai->gen_invocation_func_call (out, tjp_tp.c_str(), tjp_obj.c_str()); + out << endl; + + // Insert end of condition check + if (jp.condition ()) { + out << " }" << endl; + if (ai->type () == ACT_AROUND) { + // Make sure the following advice get invoked even if + // the condition is not fulfilled + out << " else {" << endl; + out << " " << tjp_access_prefix << "proceed ();" << endl; + out << " }" << endl; + } + } +} + + +void CodeWeaver::make_advice_calls (ostream &out, ACM_CodePlan *plan, + ACM_Code *loc, bool inter, vector *arg_names) { + + typedef ACM_Container Container; + Container &before = plan->get_before(); + for (Container::iterator i = before.begin (); i != before.end (); ++i) + make_advice_call (out, loc, TI_CodeAdvice::of(**i)->get_advice_info(), inter, depth (*plan)); + + if (plan->has_around()) + make_advice_call (out, loc, TI_CodeAdvice::of(*plan->get_around())->get_advice_info(), inter, depth (*plan)); +#ifdef FRONTEND_CLANG + // this feature is only supported in the Clang variant + else if( TI_Code::of( *( static_cast( loc ) ) )->has_implicit_joinpoints() ) + make_proceed_to_implicit( out, loc, inter, arg_names ); +#endif + else + make_proceed_code (out, loc, inter, arg_names); + + Container &after = plan->get_after(); + for (Container::iterator i = after.begin (); i != after.end (); ++i) + make_advice_call (out, loc, TI_CodeAdvice::of(**i)->get_advice_info(), inter, depth (*plan)); +} + + +// this function weaves the invocation code for a tree of advice functions +// at a access join point +void CodeWeaver::access_join_point( ACM_Access *loc ) { +#ifdef FRONTEND_CLANG + TI_Access &ti = *( TI_Access::of( *loc ) ); + const SyntacticContext &sctxt = ti.access_context(); +#else + // fall back to call API as generalisation is not done for Puma + assert( loc->type_val() == JPT_Call ); + TI_MethodCall &ti = *( TI_MethodCall::of( *( static_cast( loc ) ) ) ); + const SyntacticContext &sctxt = ti.call_context(); +#endif + + typedef const WeavePos WP; + + // determine the weaving position for wrapper code + int extern_c_depth = sctxt.is_in_extern_c_block(); + const WeavePos &pos = sctxt.wrapper_pos( *this ); + + // close extern "C" block if we are in any + if( extern_c_depth > 0 ) { + ostringstream cblock; + cblock << close_extern_c_block( extern_c_depth ); + insert( pos, cblock.str() ); + } + +#ifdef FRONTEND_CLANG + // Weaving on operators with short-circuit-evaluation only available with Clang-frontend. + if( loc->type_val() == JPT_Builtin && static_cast( ti ).is_short_circuiting() ) { + // Special handling for short-circuit-evaluating operators: + splice_shortcircuit_expr( static_cast( loc ) ); + + if( extern_c_depth > 0 ) { + ostringstream cblock; + cblock << reopen_extern_c_block( extern_c_depth ); + insert( pos, cblock.str() ); + } + return; // we are done + } +#endif // FRONTEND_CLANG + + // create the wrapper + stringstream new_call; + stringstream trail_call; + bool generated_args = CodeWeaver::generate_access_wrapper( loc, new_call, trail_call ); + + if( extern_c_depth > 0 ) { + ostringstream cblock; + cblock << reopen_extern_c_block( extern_c_depth ); + insert( pos, cblock.str() ); + } + + // replace call with call to replacement function + WP &before_pos = ti.before_pos(*this); + WP &after_pos = ti.after_pos(*this); + + // provide wrapper call arguments by transforming the expression + bool provided_args = splice_access_expr( loc ); + + if( generated_args && provided_args ) + new_call << ", "; + + // paste the trailing part of the wrapper call (in back) + insert (after_pos, trail_call.str ()); + + // paste the first (generated) part of the call (in front) + insert (before_pos, new_call.str (), true); +} + +#ifdef FRONTEND_CLANG +void CodeWeaver::splice_shortcircuit_expr( ACM_Builtin *loc ) { + // Weaving on operators with short-circuit-evaluation only available with Clang-frontend. + TI_Builtin &ti = *( TI_Builtin::of( *loc ) ); + assert( ti.is_short_circuiting() ); + + // Transform the original expr + // "a X1 b X2 c" (X1 and X2 are placeholders for operators) will be transformed to: + // (( a ) ? call_0(, true, ( b ) , ) : call_1(, false, ( c ), )) + // ^1^ ^--------------2---------------^ ^--------------------3----------------------^ ^-----4-----^ + // with 1 = new_call, 2 and 3 = replacements for operators X1 and X2, 4 = trail_call, + // = args for target, that,..., = dummy argument for result type deduction + + // Different cases and how they match to "a X1 b X2 c": + // "d && e": a = d, b = e, c = false /*dummy*/ + // "d || e": a = d, b = true /*dummy*/, c = e + // "a ? b : c": ... + + // If the second argument is not available, we will set the dummy to the value of a, so we can + // return arg0 inside the wrapper in every case. + + // Parenthesis around the second argument (b) are necessary in the case of the ternary operator, + // because most(?) compilers ignore the operator precedence while scanning for the ":". + // Thus e.g. "a ? 1, 2 : 3" otherwise would lead to wrong code ("call_0(, 1, 2, )"). + + // TODO: + // If the user changes the first argument in an advice, the generation of the result will lead to the + // dereference of a null-pointer, because a not available argument will be accessed. To reduce + // this problem, we plan to add the "const"-qualifier to the type of the first argument, if it is + // accessed inside the advice. + + // Determine the parts 1 to 4 and create the wrappers + ostringstream first_part, second_part, third_part, fourth_part; + first_part << "(("; + second_part << ") ? "; + third_part << ")"; + + // create the frist wrapper + bool generated_args = CodeWeaver::generate_access_wrapper( loc, second_part, third_part, "this", 0 ); + + second_part << ( generated_args ? ", " : "" ) << "true, ("; + third_part << " : "; + fourth_part << ")"; + + // Generate second wrapper: + generated_args = CodeWeaver::generate_access_wrapper( loc, third_part, fourth_part, "this", 1 ); + + third_part<< ( generated_args ? ", " : "" ) << "false, ("; + fourth_part << ")"; + + // provide wrapper call arguments by transforming the expression + if( clang::BinaryOperator * bo = llvm::dyn_cast( ti.TI_Access::tree_node() ) ) { + if( bo->getOpcode() == BO_LAnd ) { + // Set fourth part to third + dummy + fourth: + third_part << "(false /* dummy */)" << fourth_part.str(); + // move content to fourth_part + fourth_part.clear(); + fourth_part.str( third_part.str() ); + fourth_part.seekp( 0, std::ios_base::end ); + } + else if( bo->getOpcode() == BO_LOr ) { + // Set second_part to second + dummy + third: + second_part << "(true /* dummy */)" << third_part.str(); + } + else { + assert(false && "Unknown short-circuit-operator"); + return; + } + // Use second part as replacement for && or || + replace( ti.op_before_pos( *this ), ti.op_after_pos( *this ), second_part.str() ); + } + else if( llvm::isa( ti.TI_Access::tree_node() ) ) { + replace( ti.ternary_op_first_delim_before_pos( *this ), ti.ternary_op_first_delim_after_pos( *this ), second_part.str() ); + replace( ti.ternary_op_second_delim_before_pos( *this ), ti.ternary_op_second_delim_after_pos( *this ), third_part.str() ); + } + else { + assert(false && "Unknown short-circuit-operator"); + return; + } + + // paste the trailing part of the wrapper call (in back) + insert( ti.after_pos(*this), fourth_part.str() ); + + // paste the first (generated) part of the call (in front) + insert( ti.before_pos(*this), first_part.str(), true ); +} +#endif // FRONTEND_CLANG + +// generate wrapper body and call +// +// wrapper_number: Number of the wrapper this member-function will generate. Currently only +// needed for short-circuit-evaluation. This argument is optional and defaults +// to -1, which indicates that the wrapper-number should not be used. +bool CodeWeaver::generate_access_wrapper( ACM_Access *loc, ostream &new_call, ostream &trail_call, + const char *name_that, int wrapper_number) { + // determine the weaving parameters + ACM_CodePlan &plan = *( loc->get_plan() ); + +#ifdef FRONTEND_CLANG + TI_Access &ti = *( TI_Access::of( *loc ) ); + const SyntacticContext &sctxt = ti.access_context(); + ACM_Name *src_obj = get_explicit_parent( *loc ); +#else + assert( loc->type_val() == JPT_Call ); + TI_MethodCall &ti = *( TI_MethodCall::of( *( static_cast( loc ) ) ) ); + const SyntacticContext &sctxt = ti.call_context(); + ACM_Name *src_obj = static_cast( loc->get_parent() ); +#endif + ACM_Function *src_func = ((src_obj->type_val() == JPT_Function) ? + (ACM_Function*)src_obj : (ACM_Function*)0); + ACM_Name *dst_entity = 0; + if( has_entity( *loc ) ) + dst_entity = get_entity( *loc ); + ACM_Function *dst_func = 0; + if( has_entity_func( *loc ) ) + dst_func = get_entity_func( *loc ); +#ifdef FRONTEND_CLANG + // only required for features in the Clang variant + ACM_Variable *dst_var = 0; + if( has_entity_var( *loc ) ) + dst_var = get_entity_var( *loc ); +#endif + bool deduce_result_type = ti.has_result() && ! is_implicit( *loc ); // TODO: don't do it always, Markus: for implicit joinpoint don't do it, as codecopy is not reliable there + bool override_isdep = is_implicit( *loc ); +#ifdef FRONTEND_CLANG + if( loc->type_val() == JPT_Ref && static_cast( ti ).is_implicit_arraydecay() ) { + deduce_result_type = false; // for JPs on implicit AST nodes, codecopy does not work as the do not exist in the copied code + override_isdep = true; + } +#endif + + // determine the weaving position for wrapper code + const WeavePos &pos = sctxt.wrapper_pos(*this); + + ostringstream code; + + // generate and insert a forward declaration for the target function if needed: + // direct recursive call of a non-member function that has no forward declaration + if (src_func && src_func == dst_func && + (dst_func->get_kind() == FT_NON_MEMBER || + dst_func->get_kind() == FT_STATIC_NON_MEMBER) && + dst_func->get_source().size() == 1) { + // TODO: a forward declaration has to be generated and default argument + // initializers have to be moved into the forward declaration +// cout << "FORWARD" << endl; + } + + ThisJoinPoint tjp; + tjp.merge_flags( plan ); +#ifdef FRONTEND_CLANG + // only required for features in the Clang variant + tjp.enable_entity(); + + if( ti.has_implicit_joinpoints() ) + tjp.merge_implicit( *loc ); +#endif + + bool proceed_generated = tjp.proceed() || tjp.action(); + + // assure prerequisites are meet if non direct proceed code is used + if( ti.needs_rights() ) { + // generate JoinPoint-ID-Class and caller function of necessary + if( loc->type_val() == JPT_Call ) + insert_id_class( static_cast( loc ), src_obj, pos, *dst_func ); + else { + if( proceed_generated ) // only request the entity() function when a proceed() func exists where we need it + tjp.require_entity(); + } + } + + bool pass_That = src_func && needs_this(*src_func) && tjp.that_needed( loc ); + +#ifdef FRONTEND_CLANG + // Clang Variant only features + bool proceed_uses_entity = dst_var && ti.needs_rights(); + + bool wormhole = false; + bool pack_Arg0 = false; + bool pack_Result = false; + int skip_Arg = -1; + + if( loc->type_val() == JPT_Builtin ) { + TI_Builtin &tiC = static_cast( ti ); + + // guarding against manipulation of return value on forwarding operators, as this would break various assumptions in the weaver + if( tiC.is_forwarding() ) + tjp.force_const_result(); + // guard the first arg of array subscript too, as it ight be a pointer to an array + if( tiC.is_index_expr() ) + tjp.force_const_arg( 0 ); + // guard the first arg of short-circuit operators, as it decides which args are valid + if( tiC.is_short_circuiting() ) + tjp.force_const_arg( 0 ); + + // pack arg0 and result if needed + if( tiC.forwarded_is_packed() ) { + pack_Arg0 = true; + pack_Result = true; + + if( tiC.forwarded_needs_packing() ) + pack_entity_expr( tiC.packed_forward_requester() ); + } + + // skip the unevaluated arg for conditional operators + if( llvm::isa( tiC.TI_Access::tree_node() ) ) { + assert( tiC.is_short_circuiting() ); + assert( wrapper_number == 0 || wrapper_number == 1 ); + skip_Arg = 2 - wrapper_number; + } + } + + if( ti.has_implicit_joinpoints() ) { + // it is suffient to consider only the first, as all share the same entity + assert( loc->type_val() == JPT_Builtin ); + ACM_Access *implicit = *( static_cast( loc )->get_implicit_access().begin() ); + if( has_complex_entity( implicit ) ) { + if( ! pack_Arg0 ) { // it might be already packed + pack_Arg0 = true; + + if( static_cast( ti ).forwarded_needs_packing() ) + pack_entity_expr( implicit ); + } + + // if we have implicit joinpoint calls inside a proceed function + // that have a complex entity, we need to tunnel the information in + if( proceed_generated ) { + tjp.request_wormhole(); + wormhole = true; + } + } + } +#endif + + bool have_Member = dst_entity && needs_this( *dst_entity ); + bool this_Target = have_Member && ! ti.has_target_expr(); + bool have_Target = ti.has_target_expr() || this_Target; +#ifdef FRONTEND_CLANG + // Clang Variant only features + bool have_Entity = ! ( + ( dst_func && needs_this( *dst_func ) ) // member functions are not representable as simple function pointers + || ( loc->type_val() == JPT_Builtin ) // for builtin operators there is no function to point to + ); + bool have_Idx = ti.entity_index_count() > 0; + bool have_Base = have_Idx; + + if( have_Idx && proceed_generated && ! proceed_uses_entity ) // request api generation for use in proceed + tjp.require_idx(); + + bool need_Entity = have_Entity && ( proceed_uses_entity || tjp.entity_needed( loc ) ); +#endif + // proceed needs Target if it reuses the target_expr or to access member entities + // Exception: it is not used to access private data members (entity is used then) + // tjp needs it only if entity is a member +#ifdef FRONTEND_CLANG + bool need_Target = have_Target && ( ! proceed_uses_entity || tjp.target_needed( loc ) ); + bool need_Member = have_Member && tjp.memberptr_needed( loc ); + bool need_Base = have_Base && tjp.array_needed( loc ); + bool need_Idx = have_Idx && ( ! proceed_uses_entity || tjp.idx_needed( loc ) ); +#else + bool need_Target = have_Target && tjp.target_needed( loc ); +#endif + +#ifdef FRONTEND_CLANG + // Clang Variant only features + bool pack_Entity = false; + if( has_complex_entity( loc ) ) { + if( is_implicit( *loc ) ) + pack_Entity = true; + else { + TI_Access::SpliceMode mode = ti.entity_src_splice_mode(); + if( mode == TI_Access::SpliceMode_Packed || mode == TI_Access::SpliceMode_Pack ) + pack_Entity = true; + } + } +#endif + + bool pass_Target = false; +#ifdef FRONTEND_CLANG + // Clang Variant only features + bool pass_Entity = false; + bool comp_Entity = false; + bool genr_Entity = false; + bool pass_Member = false; + bool genr_Member = false; + bool pass_Base = false; + bool comp_Base = false; + bool pass_Idx = false; + + if( dst_func ) { // For historical reasons and some specifics functions are handled a bit differently + pass_Target = have_Target; // we need to pass it, even if we don't need it, as the expr exists already + if( have_Member ) // for member functions ... + genr_Member = need_Member; // .. generate the member info as needed, there is no entity defineable + else // .. for normal functions + genr_Entity = need_Entity; // .. generate the entity info as needed, there is no member + } + else if( ! pack_Entity ) { + // decide from where to get Entity: + if( have_Base && have_Idx ) { + comp_Entity = need_Entity; // compute as needed + if( comp_Entity ) { // request deps + need_Base = true; + need_Idx = true; + } + } + else if( have_Target && have_Member ) { + comp_Entity = need_Entity; // compute as needed + if( comp_Entity ) { // request deps + need_Target = true; + need_Member = true; + } + } + else + pass_Entity = have_Entity; // we need to pass it, even if we don't need it, as the expr exists already + + // decide from where to get Base: + if( have_Target && have_Member ) { + comp_Base = need_Base; // compute as needed + if( comp_Entity ) { // request deps + need_Target = true; + need_Member = true; + } + } + else + pass_Base = have_Base; // we need to pass it, even if we don't need it, as the expr exists already + // Idx: + pass_Idx = have_Idx; // we need to pass it, even if we don't need it, as the expr exists already + + pass_Target = have_Target; // we need to pass it, even if we don't need it, as the expr exists already + pass_Member = have_Member; // we need to pass it, even if we don't need it, as the expr exists already + } + // packed entities contain all, we don't need to pass, compute or generate anything +#else // PUMA is simple ... + pass_Target = have_Target; // we need to pass it, even if we don't need it, as the expr exists already +#endif + + // consistency checks +#ifdef FRONTEND_CLANG + // Clang Variant only features + if( ! pack_Entity ) { + assert( ! need_Entity || ( pass_Entity || comp_Entity || genr_Entity ) ); + assert( 1 >= ( pass_Entity + comp_Entity + genr_Entity ) ); // allow maximum one of the options +#endif + assert( ! need_Target || pass_Target ); +#ifdef FRONTEND_CLANG + // Clang Variant only features + assert( ! need_Member || ( pass_Member || genr_Member ) ); + assert( 1 >= ( pass_Member + genr_Member ) ); // allow maximum one of the options + assert( ! need_Base || ( pass_Base || comp_Base ) ); + assert( 1 >= ( pass_Base + comp_Base ) ); // allow maximum one of the options + assert( ! need_Idx || pass_Idx ); + } + else { + assert( ! ( pass_Entity || comp_Entity || genr_Entity ) ); + assert( ! pass_Target ); + assert( ! ( pass_Member || genr_Member ) ); + assert( ! ( pass_Base || comp_Base ) ); + assert( ! pass_Idx ); + } + + bool entity_is_const = have_Entity && ti.entity_is_const(); +#endif + + // generate and insert the JoinPoint class + // If this is the generation of the second wrapper, the struct was already inserted. + if( tjp.type_needed() && wrapper_number < 1 ) { + // insert the definition + code << string ("/* ") + signature (*src_obj) + " -> " + signature (*loc) + " */\n"; + make_tjp_struct (code, loc, &plan, tjp); + } + + // generate replacement function for dstfunc + code << endl; + + // argument list + int arg_count = get_arg_count (*loc); +#ifdef FRONTEND_CLANG + unsigned int idx_count = ti.entity_index_count(); +#endif + bool generated_args = false; + +#ifdef FRONTEND_CLANG + bool wrapper_is_template = ( ti.has_result() || pass_That || pass_Target || pass_Entity || pass_Base || pass_Idx || pack_Entity || arg_count > 0 ); +#else + bool wrapper_is_template = ( ti.has_result() || pass_That || pass_Target || arg_count > 0 ); +#endif + if (wrapper_is_template) { + code << "template <"; + int targs = 0; + if( pass_That ) { + if (targs > 0) + code << ", "; + code << "typename TSrc"; + targs++; + } + if (arg_count > 0) { + for (int a = 0; a < arg_count; a++, targs++) { + if (targs > 0) + code << ", "; + code << "typename TArg" << a; + } + } + if (ti.has_result ()) { + if (targs > 0) + code << ", "; + code << "typename TResult"; + targs++; + } + if( pass_Target ) { + if (targs > 0) + code << ", "; + code << "typename TTarget"; + targs++; + } +#ifdef FRONTEND_CLANG + // this feature is only available in the Clang variant + if( pass_Entity || pass_Member || pass_Base ) { + if( targs > 0 ) + code << ", "; + code << "typename TEntity"; + targs++; + } + if( pass_Idx ) { + for( unsigned int i = 0; i < idx_count; i++, targs += 2 ) { + if( targs > 0 ) + code << ", "; + code << "unsigned int TDim" << i; + code << ", typename TIdx" << i; + } + } + if( pack_Entity || pack_Arg0 ) { + if( targs > 0 ) + code << ", "; + code << "typename TPacked"; + targs++; + } +#endif + code << ">" << endl; + } + + // if the lexical scope in which the associated object of the call was + // defined is a class scope (not global or namespace) the function definition + // has to be preceded by a 'static' keyword to avoid an implicit 'this'. + if (sctxt.is_in_class_scope()) + code << "static "; + if (_problems._use_always_inline) // GNU extension + code << "__attribute__((always_inline)) "; + code << "inline "; + + // add result type +#ifdef FRONTEND_CLANG + // this feature is only available in the Clang variant + if( pack_Result ) + gen_packed_resulttype( code, loc ); + else { +#endif + code << (ti.has_result() ? "TResult " : "void "); +#ifdef FRONTEND_PUMA + CTypeInfo *result_type = ti.result_type_info (); + if (result_type->isAddress()) { + if (result_type->BaseType ()->isConst()) +#else + const clang::Type *type = ti.result_type().getTypePtr(); + if (type->isReferenceType ()) { + const clang::ReferenceType *ref_type = clang::dyn_cast(type); + if (ref_type->getPointeeType ().isConstQualified ()) +#endif + code << "const "; + code << "&"; + } +#ifdef FRONTEND_CLANG + } +#endif + + // add function name + Naming::access_wrapper (code, loc, depth (plan), wrapper_number); + code << " ("; + Naming::access_wrapper (new_call, loc, depth (plan), wrapper_number); + + if (wrapper_is_template) { + new_call << "< "; + int targs = 0; + if( pass_That ) { + if (targs++ > 0) + new_call << ", "; + string scope = string("::") + signature(*cscope (src_func)); + new_call << cleanup_name (scope) << "*"; + } + if (arg_count > 0) { + // argument types + list arg_types; + get_arg_types (*loc, arg_types); + int a = 0; + for( list::iterator i = arg_types.begin(); i != arg_types.end(); ++i, ++a ) { + if (targs++ > 0) + new_call << ", "; +#ifdef FRONTEND_PUMA + CTypeInfo *type = TI_Type::of (**i)->type_info (); + type->TypeText (new_call, "", true, true); +#else + //new_call << format_type (**i); + new_call << ti.arg_type_string( a ); +#endif + } + } + if (ti.has_result () && !deduce_result_type) { + if (targs++ > 0) + new_call << ", "; +#ifdef FRONTEND_PUMA + CTypeInfo *t = result_type; + if (t->isAddress()) t = t->BaseType (); + bool is_const = false; + if (t->TypeQualified() && t->TypeQualified()->isConst()) { + is_const = true; + t->TypeQualified()->isConst(false); + } + t->TypeText(new_call, "", true, true); + if (is_const) + t->TypeQualified()->isConst(true); +#else + // use function in TI + new_call << ti.result_type_string(); +#endif + } + new_call << " >"; + } + new_call << " ("; + + unsigned argnum = 0; + + // source and destination this pointer arguments (if needed) + if( pass_That ) { + string scope = string("::") + signature(*cscope (src_func)); +// string scope = string("::") + cscope (srcfunc)->QualName(); + code << "TSrc srcthis"; + new_call << "(" << cleanup_name (scope) << "*)" << name_that; + generated_args = true; + argnum++; + } + + if( pass_Target ) { + if (argnum > 0) + code << ", "; + code << "const TTarget &dst"; + + // move/paste the target object pointer + if( this_Target && dst_func ) { // FIXME this should be done in entity splicing or other central stage + if( argnum > 0 ) + new_call << ", "; + new_call << "*this"; + generated_args = true; + } + + argnum++; + } + +#ifdef FRONTEND_CLANG + // feature is supported in Clang only + if( pack_Entity ) { + if( argnum > 0 ) + code << ", "; + code << "TPacked __packed"; + argnum++; + } + + if( pass_Entity || pass_Member || pass_Base ) { + if( argnum > 0 ) + code << ", "; + if( entity_is_const ) + code << "const "; + code << "TEntity "; + if( pass_Entity ) + code << "&ent"; + else { + if( pass_Member ) + code << "(TTarget::* member)"; + else // pass_Base + code << "(&base)"; + + for( unsigned int i = 0; i < idx_count; i++ ) + code << "[TDim" << i << "]"; + } + argnum++; + } + + if( pass_Idx ) + for( unsigned int i = 0; i < idx_count; i++ ) { + if( argnum > 0 ) + code << ", "; + code << "TIdx" << i << " idx" << i; + argnum++; + } +#endif + + // argument list + for (int a = 0 ; a < arg_count; a++) { +#ifdef FRONTEND_CLANG + if( a == skip_Arg ) { + code << " /* Skipped: TArg" << a << " arg" << a << " */ "; + continue; + } +#endif + if (argnum > 0) + code << ", "; +#ifdef FRONTEND_CLANG + // feature is supported in Clang only + if( a == 0 && pack_Arg0 ) + code << "TPacked __packed"; + else +#endif + code << "TArg" << a << " arg" << a; + argnum++; + } + + if (deduce_result_type) { + if (argnum > 0) + code << ", "; + code << "AC::RT"; + argnum++; + } + code << ")"; + + ACResultBuffer result_buffer (project (), loc, wrapper_is_template); + + // replacement function body + code << "{" << endl; + + // --- wrapper-body-begin --- + +#ifdef FRONTEND_CLANG + // feature is supported in Clang only + // compute/generate missing parameters + // typedefs for missing types first ... + if( genr_Entity || genr_Member ) { + code << " typedef " << ( ti.has_result() ? "TResult" : "void " ) << " TEntity"; + if( dst_func ) { + code << "("; + for( int a = 0; a < arg_count; a++ ) { + if( a > 0 ) + code << ","; + code << "TArg" << a; + } + code << ")"; + } + code << ";" << endl; + } + + // ... parameter emulation second + if( genr_Entity || genr_Member ) { + if( genr_Entity ) + code << " TEntity &ent = "; + else { // genr_Member + code << " "; + if( entity_is_const ) + code << "const "; + code << "TEntity TTarget::*member = &"; + } + code << name_qualifier( dst_entity ) << dst_entity->get_name() << ";" << endl; + } + if( comp_Base ) { + assert( ! pass_Base ); // Be sure it is not already there + code << " TEntity (&base)"; + for( unsigned int i = 0; i < idx_count; i++ ) + code << "[TDim" << i << "]"; + code << " = const_cast( dst ).*member;" << endl; + } + if( comp_Entity ) { + assert( ! pass_Entity ); // Be sure it is not already there + assert( have_Member || have_Base ); // Be sure one of the src options exists + code << " TEntity &ent = "; + if( have_Base ) { + code << "base"; + for( unsigned int i = 0; i < idx_count; i++ ) + code << "[idx" << i << "]"; + } + else // have_Member + code << "const_cast( dst ).*member"; + code << ";" << endl; + } + + // ... or do on block unpacking + if( pack_Entity ) { + assert( ! ( pass_Entity || comp_Entity || genr_Entity ) ); // Be sure it is not already there + if( have_Entity ) + code << " typedef typename TPacked::Entity TEntity;" << endl; + if( need_Entity ) + code << " TEntity &ent = __packed.entity();" << endl; + assert( ! pass_Target ); // Be sure it is not already there + if( have_Target ) + code << " typedef typename TPacked::BI::Target TTarget;" << endl; + if( need_Target ) { + code << " TTarget &dst = __packed._base._target;" << endl; + } + assert( ! ( pass_Member || genr_Member ) ); // Be sure it is not already there + if( need_Member ) + code << " " << ( have_Base ? "typename TPacked::Base" : "TEntity" ) << " TTarget::*member = __packed._base._member;" << endl; + assert( ! ( pass_Base || comp_Base ) ); // Be sure it is not already there + if( need_Base ) + code << " typename TPacked::Base &base = __packed.base();" << endl; + assert( ! pass_Idx ); // Be sure it is not already there + if( have_Idx ) + for( unsigned int i = 0; i < idx_count; i++ ) + code << " typedef typename TPacked::template Dim<" << i << ">::Idx TIdx" << i << ";" << endl; + if( need_Idx ) + for( unsigned int i = 0; i < idx_count; i++ ) + code << " TIdx" << i << " &idx" << i << " = __packed.template idx<" << i << ">();" << endl; + } + + // unpacking of packed operator argument + if( pack_Arg0 ) + code << " TArg0 arg0 = __packed.entity();" << endl; + + // emulate unevaluated param for ?: + if( loc->type_val() == JPT_Builtin ) { + TI_Builtin& tiB = static_cast( ti ); + if( llvm::isa( tiB.TI_Access::tree_node() ) ) { + assert( tiB.is_short_circuiting() ); + assert( skip_Arg == 1 || skip_Arg == 2 ); + if( skip_Arg == 1 ) + code << " TArg1 " << ( tiB.arg_is_ref( 1 ) ? "" : "&" ) << "arg1 = arg2;"; + else + code << " TArg2 " << ( tiB.arg_is_ref( 2 ) ? "" : "&" ) << "arg2 = arg1;"; + code << "\n"; + } + } +#endif + + // generate __TJP type (for the next level) + if (tjp.type_needed ()) { + code << " typedef "; + const char *wormhole_type = 0; +#ifdef FRONTEND_CLANG + // feature is supported in Clang only + if( wormhole ) { + if( pack_Arg0 ) + wormhole_type = "TPacked"; + } +#endif + make_tjp_typename( code, loc, depth( plan ), result_buffer, wormhole_type ); + code << " __TJP;" << endl; + } + + // declare the result store + code << " " << result_buffer.result_declaration(); + + // generate common JoinPoint initialization + tjp.gen_tjp_init(code, loc, _problems, depth (plan), + ti.has_target_expr() || (arg_count > 0) || deduce_result_type || override_isdep, 0, wrapper_number ); +#ifdef FRONTEND_CLANG + // feature is supported in Clang only + if( wormhole ) { + if( pack_Arg0 ) + code << " tjp.__wormhole = &__packed;" << endl; + } +#endif + + // add calls to advice code + make_advice_calls(code, &plan, loc); + + // return the results +#ifdef FRONTEND_CLANG + // this feature is only available in the Clang variant + if( pack_Result ) + gen_packed_result_return( code, loc ); + else +#endif + code << " " << result_buffer.result_return(); + + // --- wrapper-body-end --- + + code << "}" << endl; + + // now we perform the code manipulation + // insert the call wrapper body + insert (pos, code.str ()); + + // TODO: make Puma check for macro problems and warn if requested + + // if the result type needs to be deduced, add expression copy here + if( deduce_result_type ) { + if (argnum > 1) + trail_call << ", "; + trail_call << "__AC_TYPEOF(("; // the two brackets are needed, because the call might contain a ',' + // e.g. func() => ACTYPEOF(func()) would be regarded a + // macro call with *two* arguments => use ACTYPEOF((...))! +#ifdef FRONTEND_CLANG + trail_call << ti.code (); // TODO: what about implicit calls here; print_tree had special handling +#else + print_tree (trail_call, ti.CallNode(), true); +#endif // FRONTEND_PUMA + trail_call << "))"; + } + + // paste a closing bracket behind the call + trail_call << " )"; + + return generated_args; +} + + +// expand implicit calls to operator->() until we are done or hit an AST node with advice +#ifdef FRONTEND_CLANG +void CodeWeaver::expand_arrow_operator_chain(TI_CommonCall &ti, const WeavePos &before_pos, const WeavePos &after_pos) { + if (!ti.has_target_expr()) + return; + clang::Expr *expr = ti.target_expr(); + while (true) { + expr = expr->IgnoreImpCasts(); + + // check if this an unseen operator->() call + clang::CXXOperatorCallExpr *call_expr = clang::dyn_cast_or_null(expr); + if (!call_expr || call_expr->getNumArgs() < 1) + break; + clang::FunctionDecl *fdecl = call_expr->getDirectCallee (); + if (!fdecl || fdecl->getNameAsString() != "operator->") + break; + if (_handled_access_nodes.find(call_expr) != _handled_access_nodes.end()) + break; + + // expand the call in the source code + insert( before_pos, "(", true ); + insert( after_pos, ").operator->()" ); + + // go to the next nested call + expr = call_expr->getArg(0); + } +} +#endif + + +// transform the existing expression to provide the wrapper call arguments +bool CodeWeaver::splice_access_expr( ACM_Access *loc ) { + bool provides_args = true; // most cases provide arguments for the wrapper +#ifdef FRONTEND_CLANG + if( loc->type_val() == JPT_Call || loc->type_val() == JPT_Builtin) { + TI_CommonCall &ti = static_cast(*TI_Access::of( *loc )); + + // insert (ti.callee_before_pos (*this), "/*CALLEE-BEFORE*/"); + // insert (ti.callee_after_pos (*this), "/*CALLEE-AFTER*/"); + // insert (ti.args_open_before_pos (*this), "/*ARGS-BEFORE1*/"); + // insert (ti.args_open_after_pos (*this), "/*ARGS-BEFORE2*/"); + // insert (ti.args_close_before_pos (*this), "/*ARGS-AFTER1*/"); + // insert (ti.args_close_after_pos (*this), "/*ARGS-AFTER2*/"); + + if( ti.is_binary_expr () ) + replace( ti.op_before_pos( *this ), ti.op_after_pos( *this ), "," ); + else if( ti.is_unary_expr () ) { + if (ti.is_arrow_class_member_access_expr()) { + // in case this is a chain of operator->() calls, expand nested (invisible) calls + expand_arrow_operator_chain(ti, ti.before_pos( *this ), ti.after_pos( *this )); + } + else if ( ! ti.is_implicit_dereference() ) + kill( ti.op_before_pos( *this ), ti.op_after_pos( *this ) ); + } + else if( ti.is_ternary_expr() ) { + assert(false && "There are no user-defined ternary expressions and " + "the built-in ternary operator is handled differently."); + } + else if( ti.is_postfix_expr () ) { + // replace operator with the dummy argument + replace( ti.op_before_pos( *this ), ti.op_after_pos( *this ), ", 0" ); + } + else if( ti.is_index_expr () ) { + // replace the opening '[' with ',' and remove the closing ']' + replace( ti.index_open_before_pos( *this ), ti.index_open_after_pos( *this ), "," ); + kill( ti.index_close_before_pos( *this ), ti.index_close_after_pos( *this ) ); + } + // the destination function is a conversion function + else if( ti.is_implicit_conversion () ) { + } + else { + // here we should have C-style function call, such as 'foo(1, 2)' + assert(loc->type_val() == JPT_Call); + TI_MethodCall& tiC = static_cast(ti); + + provides_args = ( tiC.call_args() > 0 ); + if( tiC.target_expr() ) { + // in case is target object expression is a chain of operator->() calls, + // expand nested (invisible) calls + expand_arrow_operator_chain(ti, tiC.before_pos( *this ), tiC.args_open_before_pos (*this)); + if( tiC.target_is_ptr() ) { // deref the target ptr as we pass an reference + insert( tiC.before_pos( *this ), "*(", true ); + insert( tiC.args_open_before_pos (*this), ")" ); + } + if( provides_args ) // provide argument seperator if necessary + insert( tiC.args_open_before_pos (*this), ", " ); + provides_args = true; + } + if (!tiC.is_call_op()) + kill (tiC.callee_before_pos (*this), tiC.callee_after_pos (*this)); + kill (tiC.args_open_before_pos (*this), tiC.args_open_after_pos (*this)); + kill (tiC.args_close_before_pos (*this), tiC.args_close_after_pos (*this)); + } + + // remember that this AST node has been handle + _handled_access_nodes.insert(ti.tree_node()); + } + else if( loc->type_val() == JPT_Get ) { + TI_Get &ti = *TI_Get::of( *( static_cast( loc ) ) ); + + // splice or pack the entity expr as it might contain indices or target parts + if( has_complex_entity( loc ) ) { // only pack/splice if necessary + switch( ti.entity_src_splice_mode() ) { + case TI_Access::SpliceMode_None: + case TI_Access::SpliceMode_Packed: + break; // nothing to do + case TI_Access::SpliceMode_Pack: + pack_entity_expr( loc ); + break; + case TI_Access::SpliceMode_FullSplice: + splice_entity_expr( loc ); + break; + default: + assert( false && "Unknown expr splice mode" ); + } + } + } + else if( loc->type_val() == JPT_Ref ) { + TI_Ref &ti = *TI_Ref::of( *( static_cast( loc ) ) ); + // check if we have to remove an explicit operator + // (this can happen when we weave for an explicit JP that is not child of the operator because the operator JP is suppressed) + if( ti.is_explicit_operator() ) + kill( ti.op_before_pos( *this ), ti.op_after_pos( *this ) ); + + // splice or pack the entity expr as it might contain indices or target parts + if( has_complex_entity( loc ) ) // only pack/splice if necessary + switch( ti.entity_src_splice_mode() ) { + case TI_Access::SpliceMode_None: + case TI_Access::SpliceMode_Packed: + break; // nothing to do + case TI_Access::SpliceMode_Pack: + pack_entity_expr( loc ); + break; + case TI_Access::SpliceMode_FullSplice: + splice_entity_expr( loc ); + break; + default: + assert( false && "Unknown expr splice mode" ); + } + + // paste the implicit argument for ArrayToPointerDecay + if( ti.is_implicit_arraydecay() ) + insert( ti.after_pos( *this ), ", 0 " ); + } + else if( loc->type_val() == JPT_GetRef ) { + // nothing to do, as the expr is just the passed entity + } + else { + assert( false && "Unsupported joinpoint type while weaving an access joinpoint !" ); + } + +#else + assert( loc->type_val() == JPT_Call ); + ACM_Function *dst_func = static_cast( loc )->get_target (); + TI_MethodCall &ti = *( TI_MethodCall::of( *( static_cast( loc ) ) ) ); + const char *calltype = ti.CallNode ()->NodeName (); + CTree *node; + // call was a binary operator call + if (calltype == CT_BinaryExpr::NodeId ()) { + node = ((CT_BinaryExpr*)ti.CallNode ())->Son (1); + insert (weave_pos (node->end_token (), WeavePos::WP_AFTER), ","); + kill (node); + } + // call was a unary operator call + else if (calltype == CT_UnaryExpr::NodeId () || + calltype == CT_DerefExpr::NodeId ()) { + node = ((CT_UnaryExpr*)ti.CallNode ())->Son (0); + kill (node); + } + // call was a postfix operator call + else if (calltype == CT_PostfixExpr::NodeId ()) { + if (dst_func->get_name() == "operator ++" || + dst_func->get_name() == "operator --") + insert( ti.after_pos(*this), ", 0"); + node = ((CT_BinaryExpr*)ti.CallNode ())->Son (1); + kill (node); + } + // call was an index operator call + else if (calltype == CT_IndexExpr::NodeId ()) { + // replace the opening '[' with ',' + node = ((CT_BinaryExpr*)ti.CallNode ())->Son (1); + insert (weave_pos (node->end_token (), WeavePos::WP_AFTER), ","); + kill (node); + // delete the closing ']' + node = ((CT_BinaryExpr*)ti.CallNode ())->Son (3); + kill (node); + } + // the destination function is a conversion function + else if (calltype == CT_ImplicitCall::NodeId ()) { + } + // call was an ordinary function call + else { + bool target_is_ptr = ti.target_is_ptr(); + bool target_expr = ti.has_target_expr(); + bool havedstthis = needs_this( *dst_func ) || target_expr; + CT_ExprList *args = ((CT_CallExpr*)ti.CallNode ())->Arguments (); + provides_args = ( args->Entries() > 0 ); + CTree *fctnode = ti.CallNode()->Son (0); + // if the function is given in parenthesis, remove it + while (fctnode->NodeName () == CT_BracedExpr::NodeId ()) { + kill (fctnode->Son (0)); + kill (fctnode->Son (2)); + fctnode = fctnode->Son (1); + } + const char *fctnodetype = fctnode->NodeName (); + // now perform the transformation + if( target_expr ) { + if( target_is_ptr && + (fctnodetype == CT_MembRefExpr::NodeId () || + fctnodetype == CT_MembPtrExpr::NodeId ())) { + insert( weave_pos( fctnode->token(), WeavePos::WP_BEFORE), "*(", true); + insert( weave_pos( args->token(), WeavePos::WP_BEFORE), ")" ); + } + if( provides_args ) + insert( weave_pos( args->token(), WeavePos::WP_BEFORE), ", " ); + provides_args = true; + } + if (fctnodetype == CT_MembRefExpr::NodeId () && havedstthis) { + kill (((CT_MembRefExpr*)fctnode)->Son (1)); + kill (((CT_MembRefExpr*)fctnode)->Son (2)); + } + else if (fctnodetype == CT_MembPtrExpr::NodeId () && havedstthis) { + kill (((CT_MembPtrExpr*)fctnode)->Son (1)); + kill (((CT_MembPtrExpr*)fctnode)->Son (2)); + } + else { + if (!ti.is_call_op()) + kill (fctnode); + } + kill (args->Son (0)); + kill (args->Son (args->Sons () - 1)); + } +#endif // FRONTEND_PUMA + + return provides_args; +} + +#ifdef FRONTEND_CLANG +void CodeWeaver::gen_packed_resulttype( ostream &code, ACM_Access *loc ) { + assert( loc->type_val() == JPT_Builtin ); + TI_Builtin &ti = *TI_Builtin::of( *static_cast( loc ) ); + + if( ti.is_index_expr() ) + code << "typename TPacked::template Extend::NewPacked "; + else if( ( ti.is_binary_expr() && ( ti.operator_kind_string() == "=" ) ) || ti.is_compound_assignment() ) + code << "TPacked "; + else + assert( false && "unhandled nodetype in packed result type generation" ); +} + +void CodeWeaver::gen_packed_result_return( ostream &code, ACM_Access *loc ) { + assert( loc->type_val() == JPT_Builtin ); + TI_Builtin &ti = *TI_Builtin::of( *static_cast( loc ) ); + + if( ti.is_index_expr() ) + code << " return __packed[ arg1 ];" << endl; + else if( ( ti.is_binary_expr() && ( ti.operator_kind_string() == "=" ) ) || ti.is_compound_assignment() ) + code << " return __packed;" << endl; + else + assert( false && "unhandled nodetype in packed result return generation" ); +} + +void CodeWeaver::splice_entity_expr( ACM_Access *loc ) { + TI_Access &ti = *( TI_Access::of( *loc ) ); + + TI_Builtin *src = ti.entity_src(); + string sep = ", "; + while( src ) { + const clang::Expr *check_expr = 0; + if( src->is_index_expr() ) { + // replace the opening '[' with ',' and wrap the index in brackets as it might contain a , operator + if( sep.size() == 2 ) { + replace( src->index_open_before_pos( *this ), src->index_open_after_pos( *this ), ", (" ); + replace( src->index_close_before_pos( *this ), src->index_close_after_pos( *this ), ")" ); + } + else { + replace( src->index_open_before_pos( *this ), src->index_open_after_pos( *this ), sep.c_str() ); + kill( src->index_close_before_pos( *this ), src->index_close_after_pos( *this ) ); // already wrapped + } + + check_expr = src->arg( 0 )->IgnoreImplicit(); + } + else + assert( false && "unexpected expr while splicing joinpoint entity" ); + + src = src->forwarded_src(); + + const clang::Expr *end_search = ( src ? src->TI_Access::tree_node() : ti.ref_node() ); + while( check_expr && check_expr != end_search ) { + if( const clang::ParenExpr *p = llvm::dyn_cast( check_expr ) ) { + sep = ")" + sep + "("; + check_expr = p->getSubExpr()->IgnoreImplicit(); + } + else if( const clang::BinaryOperator *bo = llvm::dyn_cast( check_expr ) ) { + if( bo->getOpcode() == clang::BO_Comma ) + check_expr = bo->getRHS()->IgnoreImplicit(); + else { + assert( false && "unexpected expr while splicing joinpoint entity" ); + break; + } + } + else { + assert( false && "unexpected expr while splicing joinpoint entity" ); + break; + } + } + } + + splice_member_expr( loc, sep.c_str() ); +} + +void CodeWeaver::pack_entity_expr( ACM_Access *loc ) { + TI_Access &ti = *( TI_Access::of( *loc ) ); + + splice_member_expr( loc ); + + insert( ti.entity_before_pos( *this ), "AC::PEInit<>( ", true ); + insert( ti.entity_after_pos( *this ), " )" ); +} + +// an Entity is complex if it needs more information than the primary entity symbol/source +// to be meaningful. This is either a class obj or indices to access an array +// access to static member are special for historical reasons: +// if an target_expr is used, it is used in proceed too, +// so they are handled like others that need a class obj +bool CodeWeaver::has_complex_entity( ACM_Access *loc ) { + TI_Access &ti = *( TI_Access::of( *loc ) ); + ACM_Name *entity = has_entity( *loc ) ? get_entity( *loc ) : 0; + + bool have_Target = ti.has_target_expr() || ( entity && needs_this( *entity ) ); + bool have_Idx = ti.entity_index_count() > 0; + return have_Target || have_Idx; +} + +void CodeWeaver::splice_member_expr( ACM_Access *loc, const char *separator ) { + TI_Access &ti = *( TI_Access::of( *loc ) ); + ACM_Name *entity = get_entity( *loc ); + if( ! needs_this( *entity ) && ! ti.has_target_expr() ) + return; // nothing to do, as we have no targetclass + + string before, replacement, after; + + bool has_dst = false; + if( ti.has_target_expr() ) { + if( ti.target_is_ptr() ) { + before += "*("; + replacement = ")" + replacement; + } + has_dst = true; + } + else if( needs_this( *entity ) ) { // only option is implicit this + replacement = "*this" + replacement; + has_dst = true; + } + + if( has_dst ) { + if( ti.target_class() != ti.targetexpr_class() ) { + before = "static_cast< " + ti.target_type_string() + " & >( " + before; + replacement += " )"; + } + replacement += separator; + } + + if( needs_this( *entity ) ) { + if( ti.entity_from_baseclass() ) { + replacement += "AC::mptr_castT< " + ti.target_type_string() +" >( "; + after = " )" + after; + } + if( is_wrapped_array( entity ) ) { + replacement += "reinterpret_cast< " + name_qualifier( entity ) + "__ac_wrapper_" + entity->get_name() + "::__ac_A"; + replacement += " (" + name_qualifier( entity ) + "*) >( "; + after = " )" + after; + } + replacement += "&"; + } + if( ! ti.is_qualified() ) { + if( needs_this( *entity ) ) + replacement += ti.targetexpr_type_string() + "::"; + else + replacement += name_qualifier( entity ); + } + + if( ! before.empty() ) + insert( ti.entity_before_pos( *this ), before.c_str(), true ); + replace( ( ti.has_target_expr() ? ti.entity_op_before_pos( *this ) : ti.entity_before_pos( *this ) ), ti.entity_op_after_pos( *this ), replacement.c_str() ); + if( ! after.empty() ) + insert( ti.entity_after_pos( *this ), after.c_str() ); +} + +bool CodeWeaver::is_wrapped_array( ACM_Name *ent ) { + if( ent->type_val() != JPT_Variable ) + return false; + + assert( static_cast( ent->get_parent() )->type_val() & ( JPT_Class | JPT_Aspect ) ); + ACM_Class *cls = static_cast( ent->get_parent() ); + // check if the class has a woven builtin copy constructor + // only in gen_special_member_function called for these the wrapping is done + // so the class has replaced array types + if( ! TI_Class::of( *cls )->has_replaced_arrays() ) + return false; + + SyntacticContext var( TI_Variable::of( static_cast( *ent ) )->decl() ); + // check parallel to CodeWeaver::gen_special_member_function + if( var.is_array() && ! var.is_anon_union_member() ) + return true; + else + return false; +} + +void CodeWeaver::preplanTransform( ACM_Code &code_jpl ) { + if( ! ( code_jpl.type_val() & ( JPT_Get | JPT_Set | JPT_Ref ) ) ) + return; // nothing to do + + ACM_Access &jpl = static_cast( code_jpl ); + if( has_complex_entity( &jpl ) ) { + TI_Builtin *entity_src = TI_Access::of( jpl )->entity_src(); + + if( is_implicit( jpl ) ) // for implicit joinpoint, skip the parent as it is handled differently + entity_src = entity_src->forwarded_src(); + + if( entity_src ) + entity_src->request_packed_forward( &jpl ); // the method itself is recursive, so no need to do it here + } +} +#endif + +void CodeWeaver::insert_id_class (ACM_Call *loc, ACM_Name *src_obj, + const WeavePos &pos, ACM_Function &dst_func) { + + TI_MethodCall &ti = *(TI_MethodCall*)TransformInfo::of (*loc); +#ifdef FRONTEND_CLANG + const SyntacticContext &sctxt = ti.access_context(); + const SyntacticContext &dfctxt = ti.entity_context(); +#else + // fall back to old functions in TI_MethodCall if using Puma and thus the new ones on TI_Access do not exist + const SyntacticContext &sctxt = ti.call_context(); + const SyntacticContext &dfctxt = ti.dest_func_context(); +#endif + ostringstream bypass; + const WeavePos *bypass_pos = &pos; + ACM_Class *src_class = (sctxt.is_in_class_scope () ? cscope (src_obj) : 0); + ACM_Class *dst_class = cscope (&dst_func); + + ACM_Class *target_class = dst_class; + if (!in_project (dst_func)) { + // calls to private externals are not supported + if (dfctxt.protection() == "private") { +#ifdef FRONTEND_PUMA + _err << sev_error << ti.tree()->token ()->location () + << "can't weave call advice for private external function '" + << signature(dst_func).c_str () << "'" << endMessage; +#endif + return; + } + // target function is protected + if (ti.has_target_expr ()) + target_class = loc->get_target_class (); + else + target_class = cscope (src_obj); + dst_class = target_class; + } + +// cout << "---" << endl; +// cout << (src_class ? signature(*src_class) : string("no source")) << endl; +// cout << (dst_class ? signature(*dst_class) : string("no destination")) << endl; +// cout << (target_class ? signature(*target_class) : string("no target")) << endl; + + bool before_class = (src_class && src_class != dst_class); + if (before_class) { + bypass_pos = &TI_Class::of (*src_class)->objdecl_start_pos (*this); + close_namespace (bypass, TI_Class::of (*src_class)->get_def_context ()); + } + else if (sctxt.is_in_namespace ()) + close_namespace (bypass, sctxt); + + string ns_open, ns_close, classname = Naming::bypass_caller_class(target_class); + + if ((src_class && src_class != dst_class) || + (!src_class && sctxt.syntactical_scope () != signature(*dst_class))) { + ACM_Name *curr = target_class; + while (curr->type_val () & (JPT_Class|JPT_Aspect)) { + classname = curr->get_name () + "::" + classname; + curr = (ACM_Name *)curr->get_parent (); + } + while (curr->get_name () != "::") { + ns_open = string ("namespace ") + curr->get_name () + " { " + ns_open; + ns_close += "} "; + curr = (ACM_Name *)curr->get_parent (); + } + } + if (ns_open != "") + bypass << ns_open << endl; + if (src_class && !before_class) + bypass << "public:" << endl; + bypass << "// unique ID-class, just a type" << endl; + bypass << "struct "; + Naming::bypass_id_class (bypass, loc); + bypass << ";" << endl; + bypass << "template struct " << classname << "<"; + Naming::bypass_id_class (bypass, loc); + bypass << ", X> {" << endl; + bypass << " static "; + if (_problems._use_always_inline) // GNU extension + bypass << "__attribute__((always_inline)) "; + bypass << "inline "; + stringstream sig, impl; + sig << "call ("; + int argnum = 0; + bool dstthis_needed = needs_this (dst_func); + // pass object pointer if needed + if (dstthis_needed) { + if (TI_Function::of (dst_func)->is_const ()) + sig << "const "; + sig << cleanup_name (signature (*target_class)) << " *dstthis"; + argnum++; + } + // argument list + unsigned call_args = get_arg_count(*loc); // IMPORTANT: get_arg_count does neither count default args nor "..."! + for (unsigned a = 0; a < call_args; a++) { + if (argnum > 0) + sig << ", "; + stringstream arg_name; + arg_name << "arg" << a; + sig << dfctxt.arg_type (a, arg_name.str ()); + argnum++; + } + sig << ")"; + // add result type + bypass << dfctxt.result_type (sig.str ()); + bypass << "{" << endl; + bypass << " "; + if (dfctxt.result_type () != "void") + bypass << "return "; + if (dstthis_needed) + bypass << "dstthis->"; + if (ti.is_qualified()) + bypass << signature (*(ACM_Name*)dst_func.get_parent ()) << "::" << dst_func.get_name () << " ("; + else + bypass << dst_func.get_name () << " ("; + for (unsigned a = 0; a < call_args; a++) { + if (a > 0) + bypass << ", "; + bypass << "arg" << a; + } + bypass << ");" << endl; + bypass << " }" << endl; + bypass << "};"; + if (ns_close != "") + bypass << ns_close << endl; + if (before_class) { + open_namespace (bypass, TI_Class::of (*src_class)->get_def_context ()); + } else if (sctxt.is_in_namespace()) + open_namespace (bypass, sctxt); + // switch to the right protection if needed + if (src_class && !before_class && !TI_Class::of (*src_class)->is_struct() && + sctxt.protection() != "" && sctxt.protection() != "public") + bypass << "\n" << sctxt.protection() << ":\n"; + + // finally insert the generated code at the appropriate position + insert (*bypass_pos, bypass.str ()); +} + +void CodeWeaver::bypass_info_clear () { + _bypass_blacklist.clear (); +} + +bool CodeWeaver::bypass_in_blacklist (ACM_Class *cls) { + const TI_Class *ti = TI_Class::of (*cls); + return !ti->valid() || !ti->is_defined() || ti->is_template_instance() || ti->is_extern_c() || + _bypass_blacklist.find (&ti->objdecl_start_pos(*this)) != _bypass_blacklist.end (); +} + +void CodeWeaver::bypass_insert (ACM_Class *acm_cls) { + const TI_Class *ti = TI_Class::of (*acm_cls); + + if (!ti->is_defined() || ti->is_template_instance() || ti->is_extern_c()) + return; + + string bypass = + string("\n template struct ") + + Naming::bypass_caller_class (acm_cls) + + " {};\n template friend struct " + + Naming::bypass_caller_class (acm_cls) + ";"; + if (ti->is_class() && !ti->is_struct()) // don't weave this into structs + bypass = string ("public:") + bypass + "\nprivate:"; + + insert (ti->body_start_pos(*this), bypass, true); + + // put a class in the backlist if is defined inside a template instance + // -> it can appear more than once in the model! + if (ti->is_in_template_instance()) + _bypass_blacklist.insert (&ti->objdecl_start_pos(*this)); +} + +// Transform aspect declarations: Simply replace the keyword 'aspect' by 'class' +void CodeWeaver::transform_aspect(ACToken start) { + const WeavePos &from = weave_pos (start, WeavePos::WP_BEFORE); + const WeavePos &to = weave_pos (start, WeavePos::WP_AFTER); + replace(from, to, "class"); +} + +// Transform the definition of a named pointcut: +// +// pointcut [virtual] foo(int i) = call("C") && args(i); +// ==> +// void foo(int i); +void CodeWeaver::transform_pointcut_def(ACToken start, ACToken virtual_token, + ACToken assignment_token, ACToken pct_end_token) { + // TODO: at the moment the Puma parser checks whether base classes of aspects + // are abstract. Therefore, a pure virtual pointcut has to become a pure virtual + // function. Later this will not be necessary. + insert (weave_pos(start, WeavePos::WP_BEFORE), "void"); +// transform_delete(start, virtual_token ? virtual_token : start); + transform_delete(start, start); + // FIXME: Don't use frontend internals. +#ifdef FRONTEND_PUMA + if (string(pct_end_token.text()) != "0") +#else + if (!pct_end_token.get().isLiteral() || string(pct_end_token.text()) != "0") +#endif + transform_delete(assignment_token, pct_end_token); +} + +// Transform the advice code into an ordinary C++ template function: +// +// advice call("C") && args(i) : before(int i) { ... } +// ==> +// template void __a42_before (int i) { ... } +// template void __a42_before (JoinPoint *tjp, int i) { ... } +void CodeWeaver::transform_advice_code( int no, string kind, AdviceCodeContext context, bool has_args, TypeUse &uses_type, + ACToken arg_begin, ACToken body_begin, ACToken body_end, const string &prot) { + + // create and insert the function name + ostringstream func_decl; + func_decl << endl << "public: "; + if (context & ACC_TYPE) + func_decl << "template "; + func_decl << "void __a" << no << "_" << kind << " "; + insert (weave_pos(arg_begin, WeavePos::WP_BEFORE), func_decl.str ()); + if (context & ACC_OBJ) { + string tjp_param = "JoinPoint *tjp"; + if (has_args) tjp_param += ", "; + insert (weave_pos(arg_begin, WeavePos::WP_AFTER), tjp_param); + } + if( uses_type.any() ) { + // also generate some typedefs for That, Target, and Result + // the corresponding typedef must replace each JoinPoint::(That|Target|Result) + ostringstream typedefs; + typedefs << endl; + if( uses_type.that ) { + typedefs << " typedef typename JoinPoint::That "; + Naming::tjp_typedef (typedefs, "That"); + typedefs << ";" << endl; + } + if( uses_type.target ) { + typedefs << " typedef typename JoinPoint::Target "; + Naming::tjp_typedef (typedefs, "Target"); + typedefs << ";" << endl; + } + if( uses_type.result ) { + typedefs << " typedef typename JoinPoint::Result "; + Naming::tjp_typedef (typedefs, "Result"); + typedefs << ";" << endl; + } + if( uses_type.entity ) { + typedefs << " typedef typename JoinPoint::Entity "; + Naming::tjp_typedef (typedefs, "Entity"); + typedefs << ";" << endl; + } + if( uses_type.memberptr ) { + typedefs << " typedef typename JoinPoint::MemberPtr "; + Naming::tjp_typedef (typedefs, "MemberPtr"); + typedefs << ";" << endl; + } + if( uses_type.array ) { + typedefs << " typedef typename JoinPoint::Array "; + Naming::tjp_typedef (typedefs, "Array"); + typedefs << ";" << endl; + } + insert (weave_pos (body_begin, WeavePos::WP_AFTER), typedefs.str ()); + } + + if (prot != "public" && prot != "") + insert (weave_pos (body_end, WeavePos::WP_AFTER), string ("\n") + prot + ":\n"); +} + +// Transform the aspect function into an ordinary C++ template function: +// +// static Foo *aspectof () { ... } +// ==> +// [template ] static Foo *aspectof ([JoinPoint *tjp]) { ... } +void CodeWeaver::transform_aspectof( AdviceCodeContext context, TypeUse &uses_type, + ACToken start, ACToken name, ACToken arg_begin, ACToken body_begin, ACToken body_end, + const string &prot) { + + // create and insert the function name + ostringstream func_decl; + func_decl << endl << "public: "; + if (context & ACC_TYPE) + func_decl << "template "; + insert (weave_pos(start, WeavePos::WP_BEFORE), func_decl.str ()); + // TODO: issue warning saying that deprecated name "aspectOf" is used + if (string(name.text ()) == "aspectOf") + replace (weave_pos(name, WeavePos::WP_BEFORE), + weave_pos (name, WeavePos::WP_AFTER), "aspectof"); + if (context & ACC_OBJ) { + string tjp_param = "JoinPoint *tjp"; + insert (weave_pos(arg_begin, WeavePos::WP_AFTER), tjp_param); + } + if( uses_type.any() ) { + // also generate some typedefs for That, Target, and Result + // the corresponding typedef must replace each JoinPoint::(That|Target|Result) + ostringstream typedefs; + typedefs << endl; + if( uses_type.that ) { + typedefs << " typedef typename JoinPoint::That "; + Naming::tjp_typedef (typedefs, "That"); + typedefs << ";" << endl; + } + if( uses_type.target ) { + typedefs << " typedef typename JoinPoint::Target "; + Naming::tjp_typedef (typedefs, "Target"); + typedefs << ";" << endl; + } + if( uses_type.result ) { + typedefs << " typedef typename JoinPoint::Result "; + Naming::tjp_typedef (typedefs, "Result"); + typedefs << ";" << endl; + } + if( uses_type.entity ) { + typedefs << " typedef typename JoinPoint::Entity "; + Naming::tjp_typedef (typedefs, "Entity"); + typedefs << ";" << endl; + } + if( uses_type.memberptr ) { + typedefs << " typedef typename JoinPoint::MemberPtr "; + Naming::tjp_typedef (typedefs, "MemberPtr"); + typedefs << ";" << endl; + } + if( uses_type.array ) { + typedefs << " typedef typename JoinPoint::Array "; + Naming::tjp_typedef (typedefs, "Array"); + typedefs << ";" << endl; + } + insert (weave_pos (body_begin, WeavePos::WP_AFTER), typedefs.str ()); + } + + if (prot != "public" && prot != "") + insert (weave_pos (body_end, WeavePos::WP_AFTER), string ("\n") + prot + ":\n"); +} + +void CodeWeaver::transform_delete (ACToken from, ACToken to) { + const WeavePos &from_pos = weave_pos (from, WeavePos::WP_BEFORE); + const WeavePos &to_pos = weave_pos (to, WeavePos::WP_AFTER); + kill(from_pos, to_pos); +} + +void CodeWeaver::transform_anon_class (ACToken name_pos, const string &name) { + // 'name_pos' is either ':' or '{' + insert (weave_pos (name_pos, WeavePos::WP_BEFORE), string (" ") + name + " "); +} + +void CodeWeaver::transform_anon_member_class (ACToken end_token, + const string &anon_members) { + string code = ""; + code += anon_members; + code += "\n"; + insert (weave_pos (end_token, WeavePos::WP_AFTER), code); +} + +ACM_Class *CodeWeaver::cscope (ACM_Name *obj) { + ACM_Name *parent = (ACM_Name*)obj->get_parent(); + return (parent->type_val() == JPT_Class ? (ACM_Class*)parent : (ACM_Class*)0); +} + +#ifdef FRONTEND_PUMA +CClassInfo *CodeWeaver::cscope(CObjectInfo *obj) { + CRecord *crec = obj->ClassScope (); + return crec ? crec->ClassInfo () : (CClassInfo*)0; +} +#else +clang::CXXRecordDecl *CodeWeaver::cscope(clang::DeclContext *obj) { + return llvm::dyn_cast(obj->getParent()); +} +#endif + +ACM_Name *CodeWeaver::nscope (ACM_Function *func) { + ACM_Name *result = (ACM_Name*)func->get_parent (); + if (result->get_name() == "::" || result->get_name () == "") + return 0; + return result; +} + +string CodeWeaver::name_qualifier( ACM_Name *entity ) { + assert( entity->get_parent() && ( static_cast( entity->get_parent() )->type_val() & JPT_Name ) ); + string scope_name = cleanup_name( signature( *static_cast( entity->get_parent() ) ) ); + if( scope_name.size() == 0 ) + scope_name = "::"; + else if( scope_name.substr( 0, 2 ) != "::" ) + scope_name = "::" + scope_name + "::"; + else if( scope_name.size() > 2 ) + scope_name += "::"; + + return scope_name; +} + +string CodeWeaver::cleanup_name(const string& in) { + string result = in; + string::size_type pos = result.length (); + while ((pos = result.rfind ("::", pos)) != string::npos) + result = result.erase (pos, 11); + if (result.find ("") == 0) + result = result.erase (0, 9); + return result; +} + +string CodeWeaver::strip_template_parameters (const string &in) { + int pos = in.size () - 1; + if (in[pos] == '>') { + int level = 0; + do { + if (in[pos] == '>') + level++; + else if (in[pos] == '<') + level--; + pos--; + } + while (pos >= 0 && level > 0); + } + return (pos >= 0 ? in.substr (0, pos + 1) : in); +} + +#ifdef FRONTEND_PUMA +void CodeWeaver::print_tree (ostream &out, CTree *node, bool expand_implicit_calls) { + + if (expand_implicit_calls && node->NodeName () == CT_ImplicitCall::NodeId() && + !((CT_ImplicitCall*)node)->Object()->FunctionInfo()->isConstructor()) { + out << "("; + print_tree (out, node->Son (0), expand_implicit_calls); + out << ")." << ((CT_ImplicitCall*)node)->Object()->Name().c_str () << "()"; + } + else if (node->NodeName () == CT_Token::NodeId ()) + out << node->token ()->text () << " "; + else + for (int s = 0; s < node->Sons (); s++) + print_tree (out, node->Son (s), expand_implicit_calls); +} +#endif // FRONTEND_PUMA + +void CodeWeaver::rename_args (const SyntacticContext &sctxt, const char * new_name, + vector &arg_names) { +#ifdef FRONTEND_PUMA + CFunctionInfo *func = (CFunctionInfo*)sctxt.object(); + + // first rename the arguments in the argument list + for (unsigned arg = 0; arg < func->Arguments (); arg++) { + if (func->Argument (arg)->isAnonymous()) { + // create a new name + ostringstream name; + name << new_name << arg; + // insert the generated name + rename (func->Argument (arg), name.str ()); + arg_names.push_back (name.str ()); + } + else { + arg_names.push_back (func->Argument (arg)->Name ().c_str()); + } + } +#else + const clang::FunctionDecl *decl = + llvm::cast(sctxt.decl()); + + for (unsigned i = 0, e = sctxt.args(); i != e; ++i) { + std::string arg_name = sctxt.arg_name(i); + if (arg_name.empty()) { + // create a new name + ostringstream name; + name << new_name << i; + // insert the generated name + rename(decl->getParamDecl(i), name.str()); + arg_names.push_back(name.str()); + } else { + arg_names.push_back(sctxt.arg_name(i)); + } + } +#endif +} + +#ifdef FRONTEND_PUMA +void CodeWeaver::rename (CArgumentInfo *arg, const string &new_name) { + // don't change anything with void arguments + if (arg->TypeInfo ()->is_void ()) + return; + + // find the syntax tree node of the argument name + CT_ArgDecl *arg_decl = (CT_ArgDecl*)arg->Tree (); + CT_Declarator *declarator = (CT_Declarator*)arg_decl->Declarator (); + CT_SimpleName *arg_name = name (declarator); + + if (arg_name->NodeName () != CT_PrivateName::NodeId ()) { + const WeavePos &lpos = weave_pos (arg_name->token (), WeavePos::WP_BEFORE); + const WeavePos &rpos = weave_pos (arg_name->end_token (), WeavePos::WP_AFTER); + replace (lpos, rpos, new_name); + } + else { + // in the case of an anonymous argument I have to find an insert pos + CTree *left = 0, *right = 0; + if (declarator) { + if (declarator->NodeName () == CT_InitDeclarator::NodeId ()) + right = ((CT_InitDeclarator*)declarator)->Initializer (); + else if (declarator->NodeName () == CT_BracedDeclarator::NodeId ()) + right = declarator->Son (declarator->Sons () - 1); + else if (declarator->NodeName () == CT_ArrayDeclarator::NodeId ()) + right = declarator->Son (1); + else if (declarator->NodeName () == CT_FctDeclarator::NodeId ()) + right = declarator->Son (1); + else if (declarator->NodeName () == CT_RefDeclarator::NodeId ()) + left = declarator->Son (0); + else if (declarator->NodeName () == CT_PtrDeclarator::NodeId ()) + left = declarator->Son (declarator->Sons () - 2); + else if (declarator->NodeName () == CT_MembPtrDeclarator::NodeId ()) + left = declarator->Son (declarator->Sons () - 2); + else if (declarator->NodeName () == CT_BitFieldDeclarator::NodeId ()) + right = declarator->Son (1); + else { + _err << sev_fatal << declarator->token ()->location () + << "unknown declarator type" << endMessage; + return; + } + } + if (!left && !right) { + // no declarator + anonymous => there must be at least a decl spec seq! + left = arg_decl->DeclSpecs (); + } + if (left) { + const WeavePos &lp = weave_pos (left->end_token (), WeavePos::WP_AFTER); + insert (lp, " "); + insert (lp, new_name); + } + else if (right) { + const WeavePos &rp = weave_pos (right->token (), WeavePos::WP_BEFORE); + insert (rp, " "); + insert (rp, new_name); + } + else + _err << sev_fatal << declarator->token ()->location () + << "found no hook to replace ananymous arg name" << endMessage; + } +} +#else +void CodeWeaver::rename(const clang::ParmVarDecl *arg, const string &new_name) { + // Get a string with the new name in the right place. It's important that this + // is the same typedef'd type as the original. + std::string s; + llvm::raw_string_ostream os(s); + clang::QualType ty = arg->getTypeSourceInfo()->getType(); + os << TI_Type::get_type_code_text(ty, &arg->getASTContext(), new_name.c_str()); + + if (!arg->hasInit() || arg->hasInheritedDefaultArg()) { + // No default argument. Replace the entire argument with the new type and + // name. + + // ... we would like to use this ... + // replace(weave_pos(arg->getLocStart(), WeavePos::WP_BEFORE), + // get_pos_after_loc(arg->getLocEnd()), os.str()); + // ... but the result of getLocEnd with the current Clang version is nonsense + // workaround: + replace(weave_pos(arg->getLocStart(), WeavePos::WP_BEFORE), + get_pos_after_loc(arg->getTypeSourceInfo()->getTypeLoc().getSourceRange().getEnd()), + os.str ()); + } else { + // Default argument. Kill from the beginning of the argument until the start + // of the default parameter. Then insert the new type and argument. Since we + // kill the equals sign, generate a new one. + os << " = "; + replace(weave_pos(arg->getLocStart(), WeavePos::WP_BEFORE), + weave_pos(arg->getInit()->getLocStart(), WeavePos::WP_AFTER), + os.str()); + } +} +#endif + +#ifdef FRONTEND_PUMA +CT_SimpleName *CodeWeaver::is_name (CTree *node) { + if (node->NodeName () == CT_QualName::NodeId () || + node->NodeName () == CT_SimpleName::NodeId () || + node->NodeName () == CT_OperatorName::NodeId () || + node->NodeName () == CT_ConversionName::NodeId () || + node->NodeName () == CT_RootQualName::NodeId () || + node->NodeName () == CT_PrivateName::NodeId ()) + return (CT_SimpleName*)node; + else + return (CT_SimpleName*)0; +} + +CT_FctDeclarator *CodeWeaver::fct_declarator (CT_Declarator *declarator) { + do { + CT_Declarator *next = (CT_Declarator*)declarator->Declarator (); + if (declarator->NodeName () == CT_FctDeclarator::NodeId () && + is_name (next)) + return (CT_FctDeclarator*)declarator; + declarator = next; + } while (!is_name (declarator)); + return (CT_FctDeclarator*)0; +} + +CT_SimpleName *CodeWeaver::name (CT_Declarator *&declarator) { + CTree *node = declarator; + declarator = (CT_Declarator*)0; + while (!is_name (node)) { + declarator = (CT_Declarator*)node; + node = declarator->Declarator (); + } + + return (CT_SimpleName*)node; +} + +// return LinkageSpec node for extern "C" like declarations +CTree *CodeWeaver::linkage_adjust (CT_Decl *decl) { + CT_LinkageSpec *linkage = decl->Linkage (); + return (!linkage || linkage->isList ()) ? decl : linkage; +} +#endif // FRONTEND_PUMA + +void CodeWeaver::gen_binding_templates (ostream &out, ACM_CodePlan *plan, + const char *jpname) { + // later the individual bindings have to be passed from here, too. + typedef ACM_Container Container; + Container &before = plan->get_before(); + for (Container::iterator i = before.begin (); i != before.end (); ++i) + TI_CodeAdvice::of(*(*i))->get_advice_info()->gen_binding_template (out, jpname, _problems); + if (plan->has_around()) + TI_CodeAdvice::of(*plan->get_around())->get_advice_info()->gen_binding_template (out, jpname, _problems); + if (plan->has_next_level()) + gen_binding_templates (out, plan->get_next_level(), jpname); + Container &after = plan->get_after(); + for (Container::iterator i = after.begin (); i != after.end (); ++i) + TI_CodeAdvice::of(*(*i))->get_advice_info()->gen_binding_template (out, jpname, _problems); +} diff --git a/AspectC++/CodeWeaver.h b/AspectC++/CodeWeaver.h new file mode 100644 index 0000000..8edced8 --- /dev/null +++ b/AspectC++/CodeWeaver.h @@ -0,0 +1,227 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __CodeWeaver_h__ +#define __CodeWeaver_h__ + +// The code weaver allows AspectC++ specific code manipulation transactions. +// All access to the syntax tree nodes for the transformation is +// encapsulated here. +// The class does not know about class JoinPoint. It only knows join point +// locations (JPL_*). + +#include +#include +#include +using namespace std; + +#include "ACToken.h" +#include "ACErrorStream.h" +#include "ACProject.h" +#include "ACConfig.h" +#include "ACResultBuffer.h" +#include "WeaverBase.h" +#include "AspectIncludes.h" +#include "SyntacticContext.h" + +namespace Puma { + class CTree; + class CClassInfo; + class CRecord; + class CProject; +} // namespace Puma + +#ifdef FRONTEND_CLANG +namespace clang { + class DeclContext; +} +#endif + +class ACM_Any; +class ACM_Class; +class ACM_Execution; +class ACM_Call; +class ACM_Code; +class ACM_CodePlan; + +class AspectInfo; +class AdviceInfo; +class ThisJoinPoint; +class TI_MethodCall; + +class CodeWeaver : public WeaverBase { + + AspectIncludes _aspect_includes; + BackEndProblems _problems; + ACConfig &_conf; + std::set _handled_access_nodes; + + set _bypass_blacklist; + + void make_check_function (bool in_checked, + Puma::CRecord *in, Puma::CRecord *check_for); + void make_tjp_typename( ostream &out, ACM_Code *loc, int depth, ACResultBuffer &rb, const char *wormhole_type = 0 ); + + void make_proceed_code (ostream &out, ACM_Code *loc, bool action, + vector *arg_names = 0); + void make_proceed_to_implicit( ostream &out, ACM_Code *loc, bool action, vector *arg_names = 0 ); + void make_advice_call(ostream &out, ACM_Code *loc, AdviceInfo *ad, + bool inter, int depth); + void make_advice_calls (ostream &out, ACM_CodePlan *plan, + ACM_Code *loc, bool inter = false, vector *arg_names = 0); + void make_action_wrapper(ostream &impl, ACM_Code *jpl, int depth); + void make_proceed_func( ostream &impl, ACM_Code *loc, ACM_CodePlan *plan, bool has_wormhole = false ); + string wrapper_function_signature (ACM_Code *loc, + const SyntacticContext &sctxt, bool def); + void gen_special_member_function (ACM_Code *loc); + void wrap_function (ACM_Code *loc); + void wrap_function_def (ACM_Code *loc, const SyntacticContext &sctxt, + bool wrapped_decl); + bool wrap_function_decl (ACM_Code *loc, const SyntacticContext &sctxt); + void wrap_attribute_array (const SyntacticContext &attr_ctxt, list &attrs); + string gen_wrapped_array (const SyntacticContext &attr_ctxt); + void gen_binding_templates (ostream &out, ACM_CodePlan *plan, const char *jpname); + +#ifdef FRONTEND_PUMA + void setup_tjp (ThisJoinPoint &tjp, Puma::CTree *node); +#else + void setup_tjp (ThisJoinPoint &tjp, clang::Stmt* node); +#endif + void insert_id_class (ACM_Call *loc, ACM_Name *src_obj, const WeavePos &pos, + ACM_Function &dst_func); + + // scope functions +#ifdef FRONTEND_PUMA + Puma::CClassInfo *cscope (Puma::CObjectInfo *obj); +#else + clang::CXXRecordDecl *cscope(clang::DeclContext *obj); +#endif + ACM_Class *cscope (ACM_Name *obj); + ACM_Name *nscope (ACM_Function *func); + string name_qualifier( ACM_Name *entity ); + string cleanup_name(const string& in); + string strip_template_parameters (const string &in); + + +#ifdef FRONTEND_PUMA + // not a very good function + void print_tree (ostream &out, Puma::CTree *node, bool expand_implicit_calls = false); + + void rename_args (const SyntacticContext &sctxt, const char * new_name, + vector &arg_names); + void rename (Puma::CArgumentInfo *arg, const string &new_name); + Puma::CT_SimpleName *is_name (Puma::CTree *node); + Puma::CT_FctDeclarator *fct_declarator (Puma::CT_Declarator *declarator); + Puma::CT_SimpleName *name (Puma::CT_Declarator *&declarator); + + // return LinkageSpec node for extern "C" like declarations + Puma::CTree *linkage_adjust (Puma::CT_Decl *decl); +#else + void rename_args (const SyntacticContext &sctxt, const char * new_name, + vector &arg_names); + void rename (const clang::ParmVarDecl *arg, const string &new_name); +#endif + +public: + + CodeWeaver( ACProject& prj, LineDirectiveMgr &ldm, ACConfig &c ) : + WeaverBase( prj, ldm ), _aspect_includes( prj ), _conf( c ) {} + + // set weaver parameters + void problems (const BackEndProblems &problems) { + _problems = problems; +#ifdef FRONTEND_PUMA + _warn_macro_expansion = problems._warn_macro; +#endif // FRONTEND_PUMA + } + + // get weaver parameters + const BackEndProblems &problems () const { return _problems; } + + void open_namespace (ostream &out, const SyntacticContext &ctxt); + void close_namespace (ostream &out, const SyntacticContext &ctxt); +#ifdef FRONTEND_PUMA + void setup_tjp (ThisJoinPoint &tjp, Puma::CFunctionInfo* func); +#else + void setup_tjp (ThisJoinPoint &tjp, clang::FunctionDecl *func); +#endif + void insert_invocation_functions (ACM_Aspect *jpl_aspect, const string &defs); + + void make_tjp_struct(ostream &out, ACM_Code *loc, + ACM_CodePlan *plan, const ThisJoinPoint &tjp); + void access_join_point (ACM_Access *loc); +#ifdef FRONTEND_CLANG + void splice_shortcircuit_expr( ACM_Builtin *loc ); + void expand_arrow_operator_chain(TI_CommonCall &ti, const WeavePos &before_pos, const WeavePos &after_pos); +#endif + bool generate_access_wrapper( ACM_Access *loc, ostream &new_call, ostream &trail_call, const char *name_that = "this", + int wrapper_number = -1); + bool splice_access_expr( ACM_Access *loc ); +#ifdef FRONTEND_CLANG + void gen_packed_resulttype( ostream &code, ACM_Access *loc ); + void gen_packed_result_return( ostream &code, ACM_Access *loc ); + + void splice_entity_expr( ACM_Access *loc ); + void pack_entity_expr( ACM_Access *loc ); + static bool has_complex_entity( ACM_Access *loc ); + void splice_member_expr( ACM_Access *loc, const char *separator = ", " ); + bool is_wrapped_array( ACM_Name *ent ); + + void preplanTransform( ACM_Code &code_jpl ); +#endif + + void exec_join_point (ACM_Execution *loc); + void cons_join_point (ACM_Construction *loc); + void dest_join_point (ACM_Destruction *loc); + void add_aspect_include (ACM_Any *jpl, AspectInfo &aspect_info, + AspectRef::Kind kind); + void insert_aspect_includes (); + AspectIncludes &aspect_includes () { return _aspect_includes; } + void type_check (const ACM_Class *in, const string &name, bool result); + + void bypass_info_clear (); + bool bypass_in_blacklist (ACM_Class *cls); + void bypass_insert (ACM_Class *cls); + + // code transformation functions need for phase 1: + struct TypeUse { + bool that; + bool target; + bool result; + bool entity; + bool memberptr; + bool array; + + inline TypeUse() : that( false ), target( false ), result( false ), entity( false ), memberptr( false ), array( false ) {}; + inline bool any() { return that || target || result || entity || memberptr || array; } + }; + + void transform_aspect(ACToken start); + void transform_pointcut_def(ACToken start, ACToken virtual_token, + ACToken assignment_token, ACToken pct_end_token); + void transform_advice_code (int no, std::string kind, AdviceCodeContext context, bool has_args, TypeUse &uses_type, + ACToken arg_begin, ACToken body_begin, ACToken body_end, const string &prot); + void transform_aspectof (AdviceCodeContext context, TypeUse &uses_type, + ACToken start, ACToken name, ACToken arg_begin, + ACToken body_begin, ACToken body_end, const string &prot); + void transform_delete (ACToken from, ACToken to); + void transform_anon_class (ACToken name_pos, const string &name); + void transform_anon_member_class (ACToken end_token, const string &anon_members); +}; + +#endif // __CodeWeaver_h__ diff --git a/AspectC++/Condition.cc b/AspectC++/Condition.cc new file mode 100644 index 0000000..f1459e8 --- /dev/null +++ b/AspectC++/Condition.cc @@ -0,0 +1,135 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 +using namespace std; + +#include "Condition.h" +#include "AdviceInfo.h" +#include "TransformInfo.h" + +void Condition::That::print (ostream &out) const { + out << "that(\"" << name () << "\")"; +} + +void Condition::That::gen_check (ostream &out, AdviceInfo *ai, + const char *srcthis, + const string*) const { + out << srcthis << "->" << name () << " ()"; +} + +void Condition::Target::print (ostream &out) const { + out << "target(\"" << name () << "\")"; +} + +void Condition::Target::gen_check (ostream &out, AdviceInfo *ai, + const char*, + const string*) const { + out << "dst." << name () << " ()"; +} + +void Condition::CFlow::print (ostream &out) const { + out << "cflow[" << _index << "]"; +} + +void Condition::CFlow::gen_check (ostream &out, AdviceInfo *ai, + const char*, + const string*) const { + Naming::cflow (out, ai->aspect (), _index); + out << "::active ()"; +} + +void Condition::And::print (ostream &out) const { + out << "("; + _left->print (out); + out << " && "; + _right->print (out); + out << ")"; +} + +void Condition::And::gen_check (ostream &out, AdviceInfo *ai, + const char *srcthis, + const string*) const { + out << "("; + _left->gen_check (out, ai, srcthis); + out << "&&"; + _right->gen_check (out, ai, srcthis); + out << ")"; +} + +void Condition::Or::print (ostream &out) const { + out << "("; + _left->print (out); + out << " || "; + _right->print (out); + out << ")"; +} + +void Condition::Or::gen_check (ostream &out, AdviceInfo *ai, + const char *srcthis, + const string*) const { + out << "("; + _left->gen_check (out, ai, srcthis); + out << "||"; + _right->gen_check (out, ai, srcthis); + out << ")"; +} + +void Condition::Not::print (ostream &out) const { + out << "!"; + _arg->print (out); +} + +void Condition::Not::gen_check (ostream &out, AdviceInfo *ai, + const char *srcthis, + const string*) const { + out << "!"; + _arg->gen_check (out, ai, srcthis); +} + +void Condition::NeededShortCircuitArg::print (ostream &out) const { + out << "{" << _index_of_needed_sc_arg << "th argument is needed}"; +} + +void Condition::NeededShortCircuitArg::gen_check (ostream &out, AdviceInfo *ai, + const char*, + const string* tjp_prefix) const { + out << "(" << *tjp_prefix << "_args[" + << _index_of_needed_sc_arg << "] > 0)"; +} + +// create a 'that' condition, i.e. the current object is an instance +// of a specific class that matches the argument of 'that' +void Condition::that (ACM_Class *in_class, const string &mangled_check) { + stringstream cond_name; + Naming::type_check_func (cond_name, *in_class, mangled_check.c_str ()); + _cond = new That (cond_name.str ()); +} + +// the target object is an instance of a specific class +void Condition::target (ACM_Class *in_class, const string &mangled_check) { + stringstream cond_name; + Naming::type_check_func (cond_name, *in_class, mangled_check.c_str ()); + _cond = new Target (cond_name.str ()); +} + +void Condition::matches (const ACM_Class &cls_loc) { + // this is a hack! I assume that the top-level node is a TypeCond. + if (_cond) + ((TypeCond*)_cond)->matches (&cls_loc); +} diff --git a/AspectC++/Condition.h b/AspectC++/Condition.h new file mode 100644 index 0000000..9e4e584 --- /dev/null +++ b/AspectC++/Condition.h @@ -0,0 +1,279 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __Condition_h__ +#define __Condition_h__ + +#include +#include +#include +using namespace std; + +#include "ACModel/Elements.h" +#include "Naming.h" + +class PointCutExpr; +class AdviceInfo; +class ACM_Class; + +typedef pair TypeCheck; +typedef set TypeCheckSet; +typedef set RecordSet; +typedef set StringSet; + +// this is the class, which users should apply to manage runtime conditions +// for joinpoints. It is responsible for the memory management. + +class Condition { + + class Base { + public: + virtual ~Base () {} + virtual void print (ostream&) const = 0; + virtual void gen_check (ostream &, AdviceInfo*, const char*, + const std::string* = 0) const = 0; + virtual void checks_for_that (TypeCheckSet &checks) const {} + virtual void checks_for_target (TypeCheckSet &checks) const {} + virtual void names_for_that (StringSet &names) const {} + virtual void names_for_target (StringSet &names) const {} + }; + + class TypeCond : public Base { + RecordSet _matching; + string _name; + public: + TypeCond (const string &name) : _name (name) {} + virtual ~TypeCond () {} + void matches (const ACM_Class *cls) { _matching.insert (cls); } + const RecordSet &matching () const { return _matching; } + const string &name () const { return _name; } + void type_checks (TypeCheckSet &checks) const { + for (RecordSet::const_iterator iter = _matching.begin (); + iter != _matching.end (); ++iter) + checks.insert (TypeCheck (*iter, _name)); + } + }; + + class That : public TypeCond { + public: + That (const string &name) : TypeCond (name) {} + virtual void print (ostream&) const; + virtual void gen_check (ostream &, AdviceInfo*, const char*, + const std::string* = 0) const; + virtual void checks_for_that (TypeCheckSet &checks) const { + type_checks (checks); + } + virtual void names_for_that (StringSet &names) const { + names.insert (name ()); + } + }; + + class Target : public TypeCond { + public: + Target (const string &name) : TypeCond (name) {} + virtual void print (ostream&) const; + virtual void gen_check (ostream &, AdviceInfo*, const char*, + const std::string* = 0) const; + virtual void checks_for_target (TypeCheckSet &checks) const { + type_checks (checks); + } + virtual void names_for_target (StringSet &names) const { + names.insert (name ()); + } + }; + + class CFlow : public Base { + int _index; + public: + CFlow (int i) : _index (i) {} + virtual void print (ostream&) const; + virtual void gen_check (ostream &, AdviceInfo*, const char*, + const std::string* = 0) const; + }; + + class Binary : public Base { + protected: + Base *_left; + Base *_right; + public: + Binary (Base *left, Base *right) : _left (left), _right (right) {} + virtual void checks_for_that (TypeCheckSet &result) const { + _left->checks_for_that (result); + _right->checks_for_that (result); + } + virtual void checks_for_target (TypeCheckSet &result) const { + _left->checks_for_target (result); + _right->checks_for_target (result); + } + virtual void names_for_that (StringSet &names) const { + _left->names_for_that (names); + _right->names_for_that (names); + } + virtual void names_for_target (StringSet &names) const { + _left->names_for_that (names); + _right->names_for_that (names); + } + }; + + class And : public Binary { + public: + And (Base *left, Base *right) : Binary (left, right) {} + virtual void print (ostream&) const; + virtual void gen_check (ostream &, AdviceInfo*, const char*, + const std::string* = 0) const; + }; + + class Or : public Binary { + public: + Or (Base *left, Base *right) : Binary (left, right) {} + virtual void print (ostream&) const; + virtual void gen_check (ostream &, AdviceInfo*, const char*, + const std::string* = 0) const; + }; + + class Not : public Base { + Base *_arg; + public: + Not (Base *arg) : _arg (arg) {} + virtual void print (ostream&) const; + virtual void gen_check (ostream &, AdviceInfo*, const char*, + const std::string* = 0) const; + virtual void checks_for_that (TypeCheckSet &result) const { + _arg->checks_for_that (result); + } + virtual void checks_for_target (TypeCheckSet &result) const { + _arg->checks_for_target (result); + } + virtual void names_for_that (StringSet &names) const { + _arg->names_for_that (names); + } + virtual void names_for_target (StringSet &names) const { + _arg->names_for_target (names); + } + }; + + class NeededShortCircuitArg : public Base { + int _index_of_needed_sc_arg; + public: + NeededShortCircuitArg (int index_of_needed_sc_arg) + : _index_of_needed_sc_arg(index_of_needed_sc_arg) {} + virtual void print (ostream&) const; + virtual void gen_check (ostream &, AdviceInfo*, const char*, + const std::string* = 0) const; + }; + + Base *_cond; + + Condition (Base *cond) : _cond (cond) {} + +public: + // create an unused condition + Condition () : _cond (0) {} + + // delete a condition + ~Condition () { + // heap cleanup + if (_cond) + delete _cond; + } + + // operator bool returns whether a condition is used + operator bool () const { return _cond != 0; } + + // print the condition in a human readable way + void print (ostream &out) { + if (_cond) + _cond->print (out); + else + out << "no condition"; + } + + void gen_check (ostream &out, AdviceInfo* ai, const char *srcthis, + const std::string* tjp_prefix) const { + if (_cond) + _cond->gen_check (out, ai, srcthis, tjp_prefix); + else + out << "true"; + } + + // return the set of checks needed for 'that' and target + void checks_for_that (TypeCheckSet &result) const { + if (_cond) _cond->checks_for_that (result); + } + void checks_for_target (TypeCheckSet &result) const { + if (_cond) _cond->checks_for_target (result); + } + + // return the names of all 'that' and 'target' checks in this condition + void names_for_that (StringSet &names) const { + if (_cond) _cond->names_for_that (names); + } + void names_for_target (StringSet &names) const { + if (_cond) _cond->names_for_target (names); + } + + // create a 'that' condition, i.e. the current object is an instance + // of a specific class that matches the argument of 'that' + void that (ACM_Class *in_class, const string &mangled_check); + + // the target object is an instance of a specific class + void target (ACM_Class *in_class, const string &mangled_check); + + // we are currently running in a control flow from ... + void cflow (int index) { + _cond = new CFlow (index); + } + + // assgin a condition + void assign (Condition &other) { + _cond = other._cond; + other._cond = 0; + } + + // combine two conditions with && + void op_and (Condition &other) { + _cond = new And (_cond, other._cond); + other._cond = 0; + } + + // combine two conditions with || + void op_or (Condition &other) { + _cond = new Or (_cond, other._cond); + other._cond = 0; + } + + // check if a condition is *not* true + void op_not () { + _cond = new Not (_cond); + } + + // Create condition that checks, whether a short-circuit argument, that + // is needed by an args pointcut function, is available at runtime + void needed_short_circuit_arg (int arg_index) { + _cond = new NeededShortCircuitArg(arg_index); + } + + void matches (const ACM_Class &cls_loc); +}; + +inline ostream& operator<< (ostream& o, Condition &cond) { + cond.print (o); + return o; +} + +#endif // __Condition_h__ diff --git a/AspectC++/FileRepo.cc b/AspectC++/FileRepo.cc new file mode 100644 index 0000000..5d0502a --- /dev/null +++ b/AspectC++/FileRepo.cc @@ -0,0 +1,117 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 +#include "FileRepo.h" +#include "RepoXMLNode.h" +#include "Puma/StrCol.h" +using namespace Puma; + +int FileRepo::insert (const string &name, int lines, int tunit) { + Map::iterator entry = _map.find (RepoNameKey (name)); + if (entry != _map.end ()) { + Data &data = (*entry).second; + if (tunit == -1) + tunit = data._id; + data.bind_tunit (tunit); + data._ref = true; + return data._id; + } + + set tunits; + int id = new_id (); + // tunit == -1 means that the primary unit itself is inserted, which has no + // id yet. Therefore, we use the new id. + tunits.insert (tunit == -1 ? id : tunit); + + _map.insert (MapPair (RepoNameKey (name), Data (id, lines, tunits))); + + return id; +} + +void FileRepo::noref () { + for (Map::iterator curr = _map.begin (); curr != _map.end (); ++curr) { + Data &data = (*curr).second; + data._ref = false; + } +} + +void FileRepo::cleanup (int primary) { + std::list to_delete; + for (Map::iterator curr = _map.begin (); curr != _map.end (); ++curr) { + Data &data = (*curr).second; + if (!data._ref) { + data._tunits.erase (primary); + if (data._tunits.size () == 0) { + to_delete.push_back((*curr).first); + } + } + } + list::iterator c; + for (c = to_delete.begin(); c != to_delete.end(); ++c) { + _map.erase(*c); + } +} + +void FileRepo::dependent (int primary, set &deps) { + for (Map::iterator curr = _map.begin (); curr != _map.end (); ++curr) { + Data &data = (*curr).second; + if (data._tunits.count (primary) == 1) + deps.insert (data._id); + } +} + +void FileRepo::make_xml (RepoXMLNode parent) { + RepoXMLNode files = parent.make_child ("file-list"); + for (Map::iterator curr = _map.begin (); curr != _map.end (); ++curr) { + RepoXMLNode fn = files.make_child ("file"); + const RepoNameKey &key = (*curr).first; + key.make_xml (fn); + + const Data &data = (*curr).second; + string tunits; + for (set::const_iterator curr = data._tunits.begin (); + curr != data._tunits.end (); ++curr) { + if (curr != data._tunits.begin ()) + tunits += ","; + tunits += idstr (*curr); + } + + fn.set_int_prop ("id", data._id); + fn.set_str_prop ("tunits", tunits.c_str ()); + fn.set_int_prop ("lines", data._lines); + } +} + +void FileRepo::get_xml (RepoXMLNode parent) { + reset_id (); + for (RepoXMLNode::iter curr = parent.first_child (); + curr != parent.end_child (); ++curr) { + RepoXMLNode fn = *curr; + if (fn.has_name ("file")) { + int id = fn.get_int_prop ("id"); + int lines = fn.get_int_prop ("lines"); + string tunit_str = fn.get_str_prop ("tunits"); + set tunits; + get_id_set (tunit_str, tunits); + + _map.insert (MapPair (RepoNameKey (fn), Data (id, lines, tunits))); + update (id); + } + } +} diff --git a/AspectC++/FileRepo.h b/AspectC++/FileRepo.h new file mode 100644 index 0000000..67476c5 --- /dev/null +++ b/AspectC++/FileRepo.h @@ -0,0 +1,63 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __FileRepo_h__ +#define __FileRepo_h__ + +#include + +#include +#include +#include +using namespace std; + +#include "RepoNameKey.h" +#include "RepoIdMgr.h" +#include "RepoXMLNode.h" + +class FileRepo : public RepoIdMgr { + + struct Data { + int _id; + int _lines; + set _tunits; + bool _ref; + Data (int id, int lines, set &tunits) : _id (id), _lines (lines), + _tunits (tunits), _ref (true) {} + void bind_tunit (int u) { _tunits.insert (u); } + }; + typedef map Map; + typedef Map::value_type MapPair; + Map _map; + +public: + + int insert (const string &name, int lines, int tunit); + + void noref (); + + void dependent (int primary, set &deps); + + void cleanup (int primary); + + void make_xml (RepoXMLNode parent); + + void get_xml (RepoXMLNode parent); +}; + +#endif // __FileRepo_h__ diff --git a/AspectC++/IncludeExpander.h b/AspectC++/IncludeExpander.h new file mode 100644 index 0000000..a428612 --- /dev/null +++ b/AspectC++/IncludeExpander.h @@ -0,0 +1,36 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __include_expander_h__ +#define __include_expander_h__ + +// class alias for frontend-specific include expander implementation + +#ifdef FRONTEND_PUMA + +#include "PumaIncludeExpander.h" +typedef PumaIncludeExpander IncludeExpander; + +#else // FRONTEND_CLANG + +#include "ClangIncludeExpander.h" +typedef ClangIncludeExpander IncludeExpander; + +#endif + +#endif // __include_expander_h__ diff --git a/AspectC++/IncludeGraph.cc b/AspectC++/IncludeGraph.cc new file mode 100644 index 0000000..6180d58 --- /dev/null +++ b/AspectC++/IncludeGraph.cc @@ -0,0 +1,217 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "IncludeGraph.h" +#include "ACFileID.h" + +#ifdef FRONTEND_PUMA +#include "Puma/PreTreeNodes.h" +#include "Puma/PreSonIterator.h" +#include "Puma/CTranslationUnit.h" +using namespace Puma; +#else +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Lex/Preprocessor.h" +using namespace clang; +#endif + +#ifdef FRONTEND_PUMA +void IncludeGraph::init (CTranslationUnit &tunit) { + + // search for #includes + iterateNodes (tunit.cpp_tree ()); +} + +// Go through the nodes. +void IncludeGraph::iterateNodes (PreTree* node) { + PreSonIterator i (node); // the order is important! + + for (i.first (); ! i.isDone (); i.next ()) + i.currentItem ()->accept (*this); +} + +// handle include directive node +void IncludeGraph::visitPreIncludeDirective_Pre (PreIncludeDirective* node) { + + // this_unit is the unit where the include directive is located + Token *this_token = node->startToken (); + Unit *this_unit = (Unit*)this_token->belonging_to (); + +// cout << "in " << this_unit->name () << " " << this_token->location () << " " +// << _project.isBelow (this_unit) << endl; + + // include if expanded by preprocessor + if (node->daughters () == 1) { + + Unit *included_unit = ((PreInclSemNode*)node->daughter (0))->unit (); + +// cout << " included: " << included_unit->name () << " " << +// _project.isBelow (included_unit) << endl; + + add_edge (this_unit, included_unit); + } +} + +#else + +void IncludeGraph::IncludeGraphCallback::InclusionDirective(SourceLocation HashLoc, + const clang::Token &IncludeTok, + StringRef FileName, + bool IsAngled, + CharSourceRange FilenameRange, + const FileEntry *File, + StringRef SearchPath, + StringRef RelativePath, + const Module *Imported) { + if (!File) + return; + + Preprocessor &PP = _ig._project.get_compiler_instance()->getPreprocessor(); + SourceManager &SM = PP.getSourceManager(); + const FileEntry *FromFile = + SM.getFileEntryForID(SM.getFileID(SM.getExpansionLoc(HashLoc))); + if (FromFile == 0) + return; + + _ig.add_edge (FromFile, File); +} +#endif + +// Add an edge to the include graph from 'a' to 'b' +void IncludeGraph::add_edge (ACFileID a, ACFileID b) { + Node &this_node = find (a); + Node &included_node = find (b); + this_node._includes.insert (&included_node); +} + +// find/create an entry in '_nodes' +IncludeGraph::Node &IncludeGraph::find (ACFileID unit) { + std::pair p = + _nodes.insert (Map::value_type (unit, Node (unit))); + return p.first->second; +} + +// Checks whether on unit 'a' directly or indirecly includes another unit 'b' +bool IncludeGraph::includes (ACFileID a, ACFileID b) const { + Map::const_iterator a_iter = _nodes.find (a); + Map::const_iterator b_iter = _nodes.find (b); + if (a_iter == _nodes.end () || b_iter == _nodes.end ()) + return false; + bool result = includes (a_iter->second, b_iter->second); + + // reset 'visited' flags + reset_visited (); + + return result; +} + +void IncludeGraph::reset_visited () const { + // reset 'visited' flags + Map::const_iterator iter = _nodes.begin (); + while (iter != _nodes.end ()) { + const IncludeGraph::Node &node = iter->second; + node._visited = false; + ++iter; + } +} + +// Checks whether there is a path from node 'a' to 'b' in the include graph +bool IncludeGraph::includes (const Node &a, const Node &b) const { + // cycle detection + if (a._visited) + return false; + + set::iterator iter = a._includes.begin (); + a._visited = true; + bool found = false; + while (iter != a._includes.end ()) { + if (*iter == &b || includes (**iter, b)) { + found = true; + break; + } + ++iter; + } + return found; +} + +void IncludeGraph::included_files (const Node &node, + set &units, bool only_project) const { + + // cycle detection + if (node._visited) + return; + + set::iterator iter = node._includes.begin (); + node._visited = true; + while (iter != node._includes.end ()) { + ACFileID unit = (*iter)->_unit; + if (!only_project || _project.isBelow ( +//#ifdef FRONTEND_PUMA +// (Puma::Unit*)unit // TODO: why isn't the argument const? +//#else + unit.name ().c_str () // TODO: using the name might be inefficient +//#endif + )) + units.insert (unit); + included_files (**iter, units); + ++iter; + } +} + +// Get all files the are directly or indirectly included +bool IncludeGraph::included_files (ACFileID unit, + set &units, bool only_project) const { + Map::const_iterator iter = _nodes.find (unit); + if (iter == _nodes.end ()) + return false; + + // collect the included file for this node + included_files (iter->second, units, only_project); + + // reset 'visited' flags + reset_visited (); + + return true; +} + +void IncludeGraph::Node::dump () const { +//#ifdef FRONTEND_PUMA +// cout << "unit " /*<< _unit.get_unit ()*/ << " '" << _unit->name () << "' includes:" << endl; +// set::iterator iter = _includes.begin (); +// while (iter != _includes.end ()) { +// cout << " " << (*iter)->_unit->name () << endl; +// ++iter; +// } +//#else + std::cout << "unit " /*<< _unit.get_unit ()*/ << " '" << _unit.name () << "' includes:" << std::endl; + std::set::iterator iter = _includes.begin (); + while (iter != _includes.end ()) { + std::cout << " " << (*iter)->_unit.name () << std::endl; + ++iter; + } +//#endif +} + +void IncludeGraph::dump () const { + Map::const_iterator iter = _nodes.begin (); + while (iter != _nodes.end ()) { + const IncludeGraph::Node &node = iter->second; + node.dump (); + ++iter; + } +} diff --git a/AspectC++/IncludeGraph.h b/AspectC++/IncludeGraph.h new file mode 100644 index 0000000..eb82c8e --- /dev/null +++ b/AspectC++/IncludeGraph.h @@ -0,0 +1,134 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __include_graph_h__ +#define __include_graph_h__ + +// Visitor, which expands all project-local includes + +#ifdef FRONTEND_PUMA +#include "Puma/PreVisitor.h" +namespace Puma { + class CTranslationUnit; + class Unit; + class CProject; +} +#else +#include "clang/Lex/PPCallbacks.h" +#endif + +#include +using std::map; +#include +using std::set; +#include +using std::ostream; +using std::endl; + +#include "ACFileID.h" +#include "ACProject.h" + +class IncludeGraph +#ifdef FRONTEND_PUMA +: public Puma::PreVisitor +#endif +{ + + struct Node { + ACFileID _unit; + mutable bool _visited; // for cycle detection + set _includes; + Node (ACFileID u) : _unit (u), _visited (false) {} + void dump () const; + }; + + // associates a node object to each unit + typedef map Map; + Map _nodes; + + // the project to which all this belongs + ACProject &_project; + +#ifdef FRONTEND_PUMA + // Go through the nodes of the syntax tree. + void iterateNodes (Puma::PreTree*); + + // Visiting the parts of the preprocessor syntax tree. + void visitPreIncludeDirective_Pre (Puma::PreIncludeDirective*); +#endif + + // find/create an entry in '_nodes' + Node &find (ACFileID); + + // Checks whether there is a path from node 'a' to 'b' in the include graph + bool includes (const Node &a, const Node &b) const; + + // collect all units included by some node + void included_files (const Node &node, set &units, + bool only_project = true) const; + + // Reset the 'visited' flag of all nodes in the DAG + void reset_visited () const; + +public: + IncludeGraph (ACProject &p) : _project (p) {} +#ifdef FRONTEND_PUMA + IncludeGraph (ACProject &p, Puma::CTranslationUnit &tunit) : _project (p) { + init (tunit); + } + virtual ~IncludeGraph () {} + + // Fills the include graph + void init (Puma::CTranslationUnit &tunit); + void init (Puma::PreTree *tree) { iterateNodes (tree); } // for new phase 1 +#else + // Callback object to add includes to the graph during a preprocessor run. + class IncludeGraphCallback : public clang::PPCallbacks { + IncludeGraph &_ig; + + // Callback from clang when it sees an inclusion directive. + virtual void InclusionDirective (clang::SourceLocation HashLoc, + const clang::Token &IncludeTok, + llvm::StringRef FileName, + bool IsAngled, + clang::CharSourceRange FilenameRange, + const clang::FileEntry *File, + llvm::StringRef SearchPath, + llvm::StringRef RelativePath, + const clang::Module *Imported); + + public: + IncludeGraphCallback (IncludeGraph &ig) : _ig(ig) {} + }; +#endif + + // Checks whether on unit 'a' directly or indirecly includes another unit 'b' + bool includes (ACFileID a, ACFileID b) const; + + // Get all files the are directly or indirectly included + bool included_files (ACFileID unit, set &units, + bool only_project = true) const; + + // Add an edge to the include graph from 'a' to 'b' + void add_edge (ACFileID a, ACFileID b); + + // print all nodes + void dump () const; +}; + +#endif // __include_graph_h__ diff --git a/AspectC++/IntroductionInfo.h b/AspectC++/IntroductionInfo.h new file mode 100644 index 0000000..d4bfc15 --- /dev/null +++ b/AspectC++/IntroductionInfo.h @@ -0,0 +1,40 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __IntroductionInfo_h__ +#define __IntroductionInfo_h__ + +#include "ACModel/Elements.h" +#include "PointCut.h" +#include "PointCutExpr.h" + +class IntroductionInfo { + + ACM_Aspect &_aspect; + ACM_Introduction &_intro; + PointcutExpression _pce; + +public: + IntroductionInfo (ACM_Aspect &a, ACM_Introduction &i) : + _aspect (a), _intro (i) {} + ACM_Aspect &aspect () const { return _aspect; } + ACM_Introduction &intro () const { return _intro; } + PointcutExpression &pointcut_expr () { return _pce; } +}; + +#endif // __IntroductionInfo_h__ diff --git a/AspectC++/IntroductionUnit.h b/AspectC++/IntroductionUnit.h new file mode 100644 index 0000000..cf3510f --- /dev/null +++ b/AspectC++/IntroductionUnit.h @@ -0,0 +1,175 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __IntroductionUnit_h__ +#define __IntroductionUnit_h__ + +#include +#include "version.h" + +class ACM_Introduction; + +#ifdef FRONTEND_PUMA +#include "ACUnit.h" + +class IntroductionUnit : public ACUnit { + Unit *_target_unit; + int _nesting_level; + int _precedence; + bool _jp_needed; + ACM_Introduction *_intro; + + void update_nesting_level () { + IntroductionUnit *outer = cast (_target_unit); + if (outer) + _nesting_level = outer->_nesting_level + 1; + } +public: + IntroductionUnit (ACErrorStream &e, Unit *t = 0) : ACUnit (e), _target_unit (t), + _nesting_level (0), _precedence (0), _jp_needed (false) { + name ("intro"); + update_nesting_level (); + } + void target_unit (Unit *t) { _target_unit = t; update_nesting_level (); } + Unit *target_unit () const { return _target_unit; } + Unit *final_target_unit () const { + Unit *result = _target_unit; + const IntroductionUnit *intro_unit = 0; + do { + intro_unit = IntroductionUnit::cast (result); + if (intro_unit) + result = intro_unit->target_unit (); + } while (intro_unit); + return result; + } + int nesting_level () const { return _nesting_level; } + int precedence () const { return _precedence; } + void precedence (int p) { _precedence = p; } + bool jp_needed () const { return _jp_needed; } + void jp_needed (bool jpn) { _jp_needed = jpn; } + void intro (ACM_Introduction *i) { _intro = i; } + ACM_Introduction *intro () const { return _intro; } + static IntroductionUnit *cast (const Unit* u) { + return (u->name () && strcmp (u->name (), "intro") == 0) ? (IntroductionUnit*)u : 0; + } +}; + +#else + +#include "llvm/Support/MemoryBuffer.h" +#include "clang/Basic/Version.h" +#include "clang/Basic/SourceLocation.h" + +class IntroductionUnit { + const llvm::MemoryBuffer *_target_unit; // FIXME: Could get this from _loc. + clang::SourceLocation _target_loc; +#if CLANG_VERSION_NUMBER <= VERSION_NUMBER_3_5_2 + llvm::MemoryBuffer *_buffer; +#endif + clang::FileID _fid; + int _nesting_level; + int _precedence; + bool _jp_needed; + ACM_Introduction *_intro; + string _content; + int _kind; // IU_OTHER, IU_BASE, IU_MEMBERS, or 0-N for non-inline member 'kind' + + void update_nesting_level () { + IntroductionUnit *outer = cast (_target_unit); + if (outer) + _nesting_level = outer->_nesting_level + 1; + } +public: + enum { IU_OTHER = -3, IU_BASE = -2, IU_MEMBERS = -1 }; + IntroductionUnit (int kind) : + _target_unit (0), +#if CLANG_VERSION_NUMBER <= VERSION_NUMBER_3_5_2 + _buffer (0), +#endif + _nesting_level (0), _precedence (0), + _jp_needed (false), _intro (0), _kind(kind) { + } + bool is_base_intro () const { return _kind == IU_BASE; } + bool is_members_intro () const { return _kind == IU_MEMBERS; } + bool is_other_intro () const { return _kind == IU_OTHER; } + int non_inline_member_no () const { return _kind; } // < 0: error + void target_unit(const llvm::MemoryBuffer *t) { + _target_unit = t; + update_nesting_level(); + } + const llvm::MemoryBuffer *target_unit () const { return _target_unit; } + const llvm::MemoryBuffer *final_target_unit () const { + const llvm::MemoryBuffer *result = _target_unit; + const IntroductionUnit *intro_unit = 0; + do { + intro_unit = IntroductionUnit::cast (result); + if (intro_unit) + result = intro_unit->target_unit (); + } while (intro_unit); + return result; + } + void location (clang::SourceLocation t) { _target_loc = t; } + clang::SourceLocation location () const { return _target_loc; } + void content (const string &str) { _content = str; } + const string &content () const { return _content; } + // create memory buffer on demand from _content string +#if CLANG_VERSION_NUMBER <= VERSION_NUMBER_3_5_2 + llvm::MemoryBuffer *buffer () { + if (!_buffer) { + std::ostringstream name; + name << "'; + _buffer = llvm::MemoryBuffer::getMemBufferCopy(_content, name.str()); + } + return _buffer; +#else // C++ 11 interface + std::unique_ptr buffer () { + std::ostringstream name; + name << "'; +// cout << "name: " << name.str () << endl << _content << endl << "--" << endl; + return llvm::MemoryBuffer::getMemBufferCopy(_content, name.str()); +#endif + } + void file_id(clang::FileID t) { _fid = t; } + clang::FileID file_id () const { return _fid; } + int nesting_level () const { return _nesting_level; } + int precedence () const { return _precedence; } + void precedence (int p) { _precedence = p; } + bool jp_needed () const { return _jp_needed; } + void jp_needed (bool jpn) { _jp_needed = jpn; } + void intro (ACM_Introduction *i) { _intro = i; } + ACM_Introduction *intro () const { return _intro; } + static IntroductionUnit *cast (const llvm::MemoryBuffer *buf) { +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_4_0_0 + const char *name = buf->getBufferIdentifier().data(); +#else + const char *name = buf->getBufferIdentifier(); +#endif + if (!strncmp(name, " +using namespace std; + +#include "Puma/ListElement.h" +#include "ACModel/Elements.h" +#include "Condition.h" + +class JoinPoint : public Puma::ListElement { + ACM_Any* _location; + Condition _cond; +public: + + JoinPoint (ACM_Any *location, Condition &cond) : _location (location) { + _cond.assign (cond); + } + ACM_Any* location() const { return _location; } + +// join_point_type type() const { return location()->type (); } + const Condition &condition () const { return _cond; } + + virtual Puma::ListElement* duplicate(); + + friend ostream& operator<< (ostream&, JoinPoint&); +}; + +#endif diff --git a/AspectC++/JoinPointModelElement.h b/AspectC++/JoinPointModelElement.h new file mode 100644 index 0000000..aa77cb5 --- /dev/null +++ b/AspectC++/JoinPointModelElement.h @@ -0,0 +1 @@ +/* empty: delete me ASAP */ diff --git a/AspectC++/JoinPointRepo.cc b/AspectC++/JoinPointRepo.cc new file mode 100644 index 0000000..f9e8e04 --- /dev/null +++ b/AspectC++/JoinPointRepo.cc @@ -0,0 +1,136 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 +#include "JoinPointRepo.h" +#include "RepoXMLNode.h" +#include "Puma/StrCol.h" +// Reinhard +// #include "MatchExpr.h" +// End Reinhard +using namespace Puma; + +int JoinPointRepo::insert (int file_id, int line, const string &signature, + const string &type, int adv, int lines) { + Map::iterator entry = _map.find (RepoPosKey (file_id, line)); + if (entry != _map.end ()) { + Data &data = (*entry).second; + if (!data._ref) { + data._ref = true; + data._advice.clear (); + } + data._advice.insert (adv); + return data._id; + } + + set advice_set; + advice_set.insert (adv); + int id = new_id (); + _map.insert (MapPair (RepoPosKey (file_id, line), + Data (id, signature, type, advice_set, lines))); + return id; +} + +void JoinPointRepo::noref () { + for (Map::iterator curr = _map.begin (); curr != _map.end (); ++curr) { + Data &data = (*curr).second; + data._ref = false; + } +} + +void JoinPointRepo::cleanup (set files) { + std::list to_delete; + for (Map::iterator curr = _map.begin (); curr != _map.end (); ++curr) { + Data &data = (*curr).second; + const RepoPosKey &key = (*curr).first; + if (!data._ref && files.count (key.file_id ()) == 1) { + to_delete.push_back(key); + } + } + list::iterator c; + for (c = to_delete.begin(); c != to_delete.end(); ++c) { + _map.erase(*c); + } +} + +void JoinPointRepo::make_xml (RepoXMLNode parent) { + + RepoXMLNode joinpoints = parent.make_child ("joinpoint-list"); + + for (Map::iterator curr = _map.begin (); curr != _map.end (); ++curr) { + RepoXMLNode jpn = joinpoints.make_child ("joinpoint"); + + const RepoPosKey &key = (*curr).first; + key.make_xml (jpn); + + const Data &data = (*curr).second; + string adv; + for (set::const_iterator curr = data._advice.begin (); + curr != data._advice.end (); ++curr) { + if (curr != data._advice.begin ()) + adv += ","; + adv += idstr (*curr); + } + + jpn.set_int_prop ("id", data._id); + jpn.set_str_prop ("type", data._type.c_str ()); + jpn.set_str_prop ("signature", data._signature.c_str ()); + jpn.set_str_prop ("advice", adv.c_str ()); + jpn.set_int_prop ("lines", data._lines); + } +} + +void JoinPointRepo::get_xml (RepoXMLNode parent) { + reset_id (); + for (RepoXMLNode::iter curr = parent.first_child (); + curr != parent.end_child (); ++curr) { + RepoXMLNode jpn = *curr; + if (jpn.has_name ("joinpoint")) { + int id = jpn.get_int_prop ("id"); + string signature = jpn.get_str_prop ("signature"); + string type = jpn.get_str_prop ("type"); + string adv_str = jpn.get_str_prop ("advice"); + set adv; + get_id_set (adv_str, adv); + int lines = jpn.get_int_prop ("lines"); + + _map.insert (MapPair (RepoPosKey (jpn), + Data (id, signature.c_str (), type.c_str (), + adv, lines))); + update (id); + +// Reinhard +// if (type == "exec") { +// ErrorStream err; // beides kann erstmal ignoriert werden +// Location loc; +// MatchExpr expr (err, loc, "% ...::member%(...)"); +// +// cout << "SIGNATURE: " << signature.c_str () << endl; +// MatchSignature sig (err, loc, signature.c_str ()); +// cout << "- parsed" << endl; +// if (expr.error ()) +// cout << "error in match" << endl; +// else if (sig.error ()) +// cout << "error in sig" << endl; +// else if (expr.matches(sig)) +// cout << "MATCHED signature " << signature.c_str () << " -> ID: " << id << endl; +// } +// End Reinhard + } + } +} diff --git a/AspectC++/JoinPointRepo.h b/AspectC++/JoinPointRepo.h new file mode 100644 index 0000000..1b40ea2 --- /dev/null +++ b/AspectC++/JoinPointRepo.h @@ -0,0 +1,66 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __JoinPointRepo_h__ +#define __JoinPointRepo_h__ + +#include + +#include +#include +#include +using namespace std; + +#include "RepoPosKey.h" +#include "RepoIdMgr.h" +#include "RepoXMLNode.h" + +class JoinPointRepo : public RepoIdMgr { + + struct Data { + int _id; + string _signature; + string _type; + set _advice; + int _lines; + bool _ref; + Data (int id, const string &signature, const string &type, set &adv, + int lines) : + _id (id), _signature (signature), _type (type), _advice (adv), + _lines (lines), _ref (true) {} + void bind_advice (int a) { _advice.insert (a); } + }; + typedef map Map; + typedef Map::value_type MapPair; + Map _map; + +public: + + int insert (int file_id, int line, const string &signature, + const string &type, int adv, int lines); + + void noref (); + + void cleanup (set files); + + void make_xml (RepoXMLNode parent); + + void get_xml (RepoXMLNode parent); +}; + +#endif // __JoinPointRepo_h__ diff --git a/AspectC++/LineDirectiveMgr.cc b/AspectC++/LineDirectiveMgr.cc new file mode 100644 index 0000000..caac528 --- /dev/null +++ b/AspectC++/LineDirectiveMgr.cc @@ -0,0 +1,113 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "LineDirectiveMgr.h" + +#ifdef FRONTEND_PUMA +#include "Puma/Token.h" +#include "Puma/CUnit.h" +#include "Puma/MacroUnit.h" +using namespace Puma; +#else +#include "clang/Basic/SourceLocation.h" +#endif + +#ifdef FRONTEND_PUMA +bool LineDirectiveMgr::insert (Unit *unit, PumaToken token, bool after) { + if (_config.noline ()) + return false; + if (unit && token && unit->isMacroExp ()) { + if (after) + token = PumaToken (((MacroUnit*)unit)->ExpansionEnd (token.get())); + else + token = PumaToken (((MacroUnit*)unit)->ExpansionBegin (token.get())); + unit = token ? token.unit () : (Unit*)0; + } + if (!unit || unit->isMacroExp ()) { + return false; // no chance :-( + } + CUnit line_directive (_err); + directive (line_directive, unit, token); + line_directive << endu; + Unit *ins_unit = token.unit (); + if (after) + ins_unit->move (token.get(), line_directive); + else + ins_unit->move_before (token.get(), line_directive); + return true; +} + +bool LineDirectiveMgr::directive (ostream &out, Unit *unit, PumaToken token) { + if (_config.noline ()) + return false; + if (unit && token && unit->isMacroExp ()) { + token = PumaToken (((MacroUnit*)unit)->ExpansionBegin (token.get())); + unit = token ? token.unit () : 0; + } + if (unit && unit->isMacroExp ()) { + return false; // no chance :-( + } + // work around broken debug information resulting from #line directives with + // an empty filename, e.g., #line 42 "" + if (unit && (unit->name() == 0 || *(unit->name()) == 0)) { + return false; + } + out << endl << "#line " << (token ? token.location ().line () : 1) + << " \""; + if (unit) { + // path names in line directives always contain '/' and not '\' + const char *curr = unit->name (); + while (curr && *curr != '\0') { + if (*curr == '\\') + out << '/'; + else + out << *curr; + curr++; + } + } + else { + out << ""; + } + out << "\"" << endl; + return true; +} + +#else + +bool LineDirectiveMgr::directive (ostream &out, const clang::PresumedLoc &loc) { + // clang needs #line directives to get the token locations right! (even with --no_line) +// if (_config.noline ()) +// return false; + if (!loc.isValid ()) + out << "\n#line 1 \"\"\n"; + else { + out << "\n#line " << loc.getLine() << " \""; + const char *curr = loc.getFilename(); + while (curr && *curr != '\0') { + if (*curr == '\\') + out << '/'; + else + out << *curr; + curr++; + } + out << "\"\n"; + } + return true; +} + +#endif diff --git a/AspectC++/LineDirectiveMgr.h b/AspectC++/LineDirectiveMgr.h new file mode 100644 index 0000000..ec6aa8f --- /dev/null +++ b/AspectC++/LineDirectiveMgr.h @@ -0,0 +1,56 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __LineDirectiveMgr_h__ +#define __LineDirectiveMgr_h__ + +#include +using namespace std; + +#include "ACErrorStream.h" + +#ifdef FRONTEND_PUMA +namespace Puma { + class Unit; +} // namespace Puma +#else +namespace clang { + class PresumedLoc; +} +#endif + +#include "ACConfig.h" +#include "ACToken.h" + +class LineDirectiveMgr { + ACErrorStream &_err; + ACConfig &_config; + +public: + LineDirectiveMgr (ACErrorStream &e, ACConfig &config) : + _err (e), _config (config) {} +#ifdef FRONTEND_PUMA + bool insert (Puma::Unit *unit, PumaToken token, bool after = false); + bool directive (ostream &out, Puma::Unit *unit = 0, PumaToken token = PumaToken ()); +#else + bool directive (ostream &out, const clang::PresumedLoc &loc); +#endif + bool noline() const { return _config.noline (); } +}; + +#endif // __LineDirectiveMgr_h__ diff --git a/AspectC++/Makefile b/AspectC++/Makefile new file mode 100644 index 0000000..9f674e3 --- /dev/null +++ b/AspectC++/Makefile @@ -0,0 +1,275 @@ +# ****************************** +# * S E T T I N G S * +# ****************************** + +# AspectC++ supports alternative frontends: Puma or Clang +# It can be configured the 'make FRONTEND=...'. Default is Clang. +export FRONTEND ?= Clang + +# PUMA root +PUMA ?= ../Puma + +# LLVM config command +LLVMCONF ?= llvm-config + +# default target +TARGET ?= linux-release + +# include the PUMA configuration variables +# => set _TARGET, RELEASE, CFLAGS, CXXFLAGS, CPPFLAGS, etc. +include $(PUMA)/vars.mk + +# check whether we compile for Windows: TARGET-Variable starts with 'win' +ifneq ($(filter win%,$(TARGET)),) + WIN := yes + EXT := .exe +endif + +# libxml2 settings +LIBXML2_INC := `xml2-config --cflags` +LIBXML2_LIB := `xml2-config --libs` + +# Check Clang version and define all necessary symbols (LLVM_*) +ifneq ($(MAKECMDGOALS),clean) + ifeq ($(FRONTEND),Clang) + include config/clang.mk + endif +endif + +# linker settings +ifneq ($(_TARGET),macosx_x86_64) +ifeq ($(SHARED),) + LDFLAGS += -static +endif +ifeq ($(FRONTEND),Puma) + LDFLAGS += -Wl,-Bstatic -L$(PUMA)/lib/$(TARGET) -lPuma +ifneq ($(SHARED),) + LDFLAGS += -Wl,-Bdynamic +endif +else # FRONTEND is Clang + LDFLAGS += -L$(PUMA)/lib/$(TARGET) -lMiniPuma +ifneq ($(SHARED),) + LDFLAGS += #-Wl,-Bdynamic +endif +endif +else +ifeq ($(FRONTEND),Puma) + LDFLAGS += -L$(PUMA)/lib/$(TARGET) -lPuma +else # FRONTEND is Clang + LDFLAGS += -L$(PUMA)/lib/$(TARGET) -lMiniPuma +endif +endif + +LDFLAGS += $(LIBXML2_LIB) +ifneq ($(FRONTEND),Puma) +ifneq ($(_TARGET),macosx_x86_64) + LDFLAGS += -lclangRewriteFrontend -lclangRewrite -lclangFrontend -lclangSerialization -lclangDriver -lclangParse -lclangSema -lclangAnalysis -lclangEdit -lclangAST -lclangLex -lclangBasic -lLLVMAsmParser -lLLVMMCParser -lLLVMBitReader -lLLVMTransformUtils -lLLVMCore -lLLVMMC -lLLVMOption -lLLVMSupport + LDFLAGS += $(patsubst %,-Xlinker --wrap=%,$(LLVM_SYMBOLS)) +else +# Mac OS X is special, we patch the clang libraries below. + LDFLAGS += libclangSema.o libclangLex.o -lclangRewriteFrontend -lclangRewrite -lclangFrontend -lclangSerialization -lclangDriver -lclangParse -lclangAnalysis -lclangEdit -lclangAST -lclangBasic -lLLVMAsmParser -lLLVMMCParser -lLLVMBitReader -lLLVMTransformUtils -lLLVMCore -lLLVMMC -lLLVMOption -lLLVMSupport +endif +LDFLAGS += `$(LLVMCONF) --ldflags` +ifeq ($(filter 3.9%, $(LLVM_VERSION))$(filter 4.0%, $(LLVM_VERSION))$(filter 5.0%, $(LLVM_VERSION)),) +# if clang < 3.9: +LDFLAGS += `$(LLVMCONF) --system-libs` # in 3.6 ldflags doesn't contain the system libs anymore +else +# if clang >= 3.9: +# - Additional libraries ("--libs") needed +# - Starting with 4.0 "--system-libs" returns nothing if the debian clang package is used. "--link-static" forces +# "--system-libs" to return the system libs in all cases +LDFLAGS += `$(LLVMCONF) --libs --system-libs --link-static` +endif +endif + +# compiler settings +ifeq ($(WIN),yes) + RES := windres + RCFILES := win-ac++.rc +endif + +CPPFLAGS += -I$(PUMA)/extern -I$(PUMA)/include $(LIBXML2_INC) +ifeq ($(FRONTEND),Puma) + CPPFLAGS += -DFRONTEND_PUMA +else + FILTEROUT := +ifeq ($(RELEASE),debug) + # filter-out "-DNDEBUG" added by LLVMCONF, if LLVM is in built in release-mode + FILTEROUT := -DNDEBUG +endif + LLVM_CPPFLAGS := $(shell $(LLVMCONF) --cppflags) + ifeq ($(WIN),yes) + # llvm-config on Windows generates path name with '\' that mingw g++ can't handle properly + LLVM_CPPFLAGS := $(subst \,/,$(LLVM_CPPFLAGS)) + endif + CPPFLAGS += $(filter-out $(FILTEROUT),$(LLVM_CPPFLAGS)) + CPPFLAGS += -DFRONTEND_CLANG=$(LLVM_INTERFACE) + CXXFLAGS += -fno-rtti -Wno-strict-aliasing # hide annoying warning in Clang header + CXXFLAGS += -std=gnu++11 # Clang uses C++11 features; "c++11" does not work -> WIN32 not defined on Windows! +endif + +# profiling +ifneq ($(GPROF),) + LDFLAGS := $(LDFLAGS) -lc_p -lm_p + CXXFLAGS += -pg +endif + +ifneq ($(PROFILING),) + CPPFLAGS += -DPROFILING +endif + +# use libacmodel +LDFLAGS += -LACModel/lib/$(TARGET) -lacmodel + + +# ****************************** +# * S O U R C E S * +# ****************************** + +BINDIR := bin/$(TARGET) + +#programm to compile +PROG := $(BINDIR)/ac++$(EXT) + +# sources; front-end specific files for the wrong frontend are filtered out +CCSOURCES := $(wildcard *.cc) +ifeq ($(FRONTEND),Puma) +CCSOURCES := $(filter-out Clang%.cc, $(CCSOURCES)) +else +CCSOURCES := $(filter-out Puma%.cc, $(CCSOURCES)) +endif + +OBJECTDIR := ObjFiles/$(TARGET) +OBJECTS := $(addprefix $(OBJECTDIR)/,$(CCSOURCES:.cc=.o) $(RCFILES:.rc=.o)) + +DEPDIR := DepFiles/$(TARGET) +DEPS := $(addprefix $(DEPDIR)/,$(CCSOURCES:.cc=.d)) + +CONFIGDIR := config + +DIRS := $(OBJECTDIR) $(DEPDIR) $(BINDIR) + +# ****************************** +# * E X A M P L E / T E S T * +# ****************************** + +# tool selection +export AC := $(shell pwd)/$(PROG) +MAKE ?= make + +# ac++ settings for tests +ACFLAGS := -k -v 9 + +ACEXAMPLES = coverage helloworld modules profiling singleton threads + + +.PHONY: $(ACEXAMPLES) + + +# ****************************** +# * T A R G E T S * +# ****************************** + +all: libacmodel showtarget $(PROG) +#.NOTPARALLEL: all + +strip: $(PROG) + @$(STRIP) $< + +showtarget: + @echo "---" + @echo "Making AspectC++ for TARGET=$(TARGET)" + @echo " Compiler = $(CXX) $(CPPFLAGS) $(CXXFLAGS)" + @echo " Linker = $(CXX) $(CXXFLAGS) $(LDFLAGS)" + @echo "---" + + +clean: testclean exampleclean + @echo Making it clean. + @$(MAKE) -C ACModel clean + @rm -rf core core.* *~ $(PROG) $(OBJECTDIR) $(DEPDIR) $(ERROR_FILE) + +cleanall: doxygen-clean clean + +test: $(PROG)$(EXT) testall + +example: $(PROG)$(EXT) $(addsuffix .example_make, $(ACEXAMPLES)) + +examplerun: example $(addsuffix .example_run, $(ACEXAMPLES)) + +exampleclean: + @rm -rf examples/*-out + @rm -rf examples/*.acp + +doxygen: + @echo "Making AspectC++ documentation with doxygen" + @doxygen doc/doxygen.conf && echo "=> see doc/doxygen/html/index.html" + +doxygen-clean: + @rm -rf doc/doxygen + +.PHONY: all test clean cleanall example examplerun exampleclean \ + showtarget doxygen doxygen-clean libacmodel + +# ****************************** +# * R U L E S * +# ****************************** + +$(DIRS) : + @mkdir -p $@ + +libacmodel : + @$(MAKE) -C ACModel + +$(PROG): $(OBJECTS) | libacmodel +# For clang on macosx_x86_64 we create relinked objects with the patched symbols. +ifneq ($(FRONTEND),Puma) +ifeq ($(_TARGET),macosx_x86_64) + @echo "Creating patched clang libraries ..." + @$(LD) -r `$(LLVMCONF) --libdir`/libclangSema.a -o libclangSema.o -all_load \ + $(foreach SYM, $(LLVM_SYMBOLS_SEMA), -alias $(SYM) ___real$(SYM) -unexported_symbol $(SYM)) + @$(LD) -r `$(LLVMCONF) --libdir`/libclangLex.a -o libclangLex.o -all_load \ + $(foreach SYM, $(LLVM_SYMBOLS_LEX), -alias $(SYM) ___real$(SYM) -unexported_symbol $(SYM)) +endif +endif + @echo "Linking $@." + @mkdir -p $(BINDIR) + @$(CXX) -o $@ $(CXXFLAGS) $^ $(LDFLAGS) + + +$(OBJECTDIR)/%.o : %.cc + @echo Making dependency file $(DEPDIR)/$(<:%.cc=%.d). + @mkdir -p $(DEPDIR) + @$(CXX) $(CPPFLAGS) $(CXXFLAGS) -MM -MP -MT $(OBJECTDIR)/$(<:%.cc=%.o) -MT $(DEPDIR)/$(<:%.cc=%.d) $< > $(DEPDIR)/$(<:%.cc=%.d) + @echo Making object file $@. + @mkdir -p $(OBJECTDIR) + @$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $< + +# -Wold-style-cast to find classic C casts "a = (A*)b;" + +ifeq ($(WIN),yes) +$(OBJECTDIR)/%.o : %.rc + @echo Compiling Windows resource file + @mkdir -p $(OBJECTDIR) + @$(RES) $(filter -D%,$(CPPFLAGS)) $< $@ + +endif + +test%: + $(MAKE) -C tests -s $* + +%.example_make: % + cd examples/$< ; \ + $(AC) $(ACFLAGS) -I. -p . -d ../$<-out \ + -r ../$<.acp ; \ + cp Makefile ../$<-out/Makefile; \ + cd ../$<-out; g++ -o $< *.cc -lpthread + +%.example_run: %.example_make + @echo "" + @echo ---- Running $* ---- + @cd examples/$*-out; `find . -type f -perm -700` + +ifneq ($(MAKECMDGOALS),clean) +-include $(DEPS) +endif diff --git a/AspectC++/ModelBuilder.h b/AspectC++/ModelBuilder.h new file mode 100644 index 0000000..d584ee9 --- /dev/null +++ b/AspectC++/ModelBuilder.h @@ -0,0 +1,224 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __ModelBuilder_h__ +#define __ModelBuilder_h__ + +// class alias for frontend-specific model builder implementation + +#include "ACModel/Elements.h" +#include "TransformInfo.h" + +/* helper classes to merge the TI_ classes into the ACM_ classes, i.e. to + * extend the join point model elements by transformation infos + */ + +class TU_CodeAdvice : public ACM_CodeAdvice, public TI_CodeAdvice { +public: + TU_CodeAdvice () : ACM_CodeAdvice () { transform_info (this); } + ~TU_CodeAdvice () { transform_info (0); } + virtual ModelNode &jpl () { return *this; } +}; + +class TU_Type : public ACM_Type, public TI_Type { +public: + TU_Type () : ACM_Type () { transform_info (this); } + ~TU_Type () { transform_info (0); } + virtual ModelNode &jpl () { return *this; } +}; + +class TU_Arg : public ACM_Arg, public TI_Arg { +public: + TU_Arg () : ACM_Arg () { transform_info (this); } + ~TU_Arg () { transform_info (0); } + virtual ModelNode &jpl () { return *this; } +}; + +class TU_Namespace : public ACM_Namespace, public TI_Namespace { +public: + TU_Namespace () : ACM_Namespace () { transform_info (this); } + ~TU_Namespace () { transform_info (0); } + virtual ModelNode &jpl () { return *this; } +}; + +class TU_Class : public ACM_Class, public TI_Class { +public: + TU_Class () : ACM_Class () { transform_info (this); } + ~TU_Class () { transform_info (0); } + virtual ModelNode &jpl () { return *this; } +}; + +class TU_Aspect : public ACM_Aspect, public TI_Aspect { +public: + TU_Aspect () : ACM_Aspect () { transform_info (this); } + ~TU_Aspect () { transform_info (0); } + virtual ModelNode &jpl () { return *this; } +}; + +class TU_Function : public ACM_Function, public TI_Function { +public: + TU_Function () : ACM_Function () { transform_info (this); } + ~TU_Function () { transform_info (0); } + virtual ModelNode &jpl () { return *this; } +}; + +class TU_Variable : public ACM_Variable, public TI_Variable { +public: + TU_Variable () : ACM_Variable () { transform_info (this); } + ~TU_Variable () { transform_info (0); } + virtual ModelNode &jpl () { return *this; } +}; + +class TU_AdviceCode : public ACM_AdviceCode, public TI_AdviceCode { +public: + TU_AdviceCode () : ACM_AdviceCode () { transform_info (this); } + ~TU_AdviceCode () { transform_info (0); } + virtual ModelNode &jpl () { return *this; } +}; + +class TU_ClassSlice : public ACM_ClassSlice, public TI_ClassSlice { +public: + TU_ClassSlice () : ACM_ClassSlice () { transform_info (this); } + ~TU_ClassSlice () { transform_info (0); } + virtual ModelNode &jpl () { return *this; } +}; + +class TU_MethodCall : public ACM_Call, public TI_MethodCall { +public: + TU_MethodCall () { transform_info (this); } + ~TU_MethodCall () { transform_info (0); } + virtual ModelNode &jpl () { return *this; } +}; + +// only define the classes for new feature for clang frontend, as there is no implementation for puma +#ifdef FRONTEND_CLANG + +class TU_Get : public ACM_Get, public TI_Get { +public: + TU_Get() { transform_info( this ); } + ~TU_Get() { transform_info( 0 ); } + virtual ModelNode &jpl() { return *this; } +}; + +class TU_Set : public ACM_Set, public TI_Set { +public: + TU_Set() { transform_info( this ); } + ~TU_Set() { transform_info( 0 ); } + virtual ModelNode &jpl() { return *this; } +}; + +class TU_Ref : public ACM_Ref, public TI_Ref { +public: + TU_Ref() { transform_info( this ); } + ~TU_Ref() { transform_info( 0 ); } + virtual ModelNode &jpl() { return *this; } +}; + +class TU_GetRef : public ACM_GetRef, public TI_GetRef { +public: + TU_GetRef() { transform_info( this ); } + ~TU_GetRef() { transform_info( 0 ); } + virtual ModelNode &jpl() { return *this; } +}; + +class TU_SetRef : public ACM_SetRef, public TI_SetRef { +public: + TU_SetRef() { transform_info( this ); } + ~TU_SetRef() { transform_info( 0 ); } + virtual ModelNode &jpl() { return *this; } +}; + +class TU_Builtin : public ACM_Builtin, public TI_Builtin { +public: + TU_Builtin() { transform_info( this ); } + ~TU_Builtin() { transform_info( 0 ); } + virtual ModelNode &jpl() { return *this; } +}; + +#endif + +class TU_Method : public ACM_Execution, public TI_Method { +public: + TU_Method () { transform_info (this); } + ~TU_Method () { transform_info (0); } + virtual ModelNode &jpl () { return *this; } +}; + +class TU_Construction : public ACM_Construction, public TI_Construction { +public: + TU_Construction () { transform_info (this); } + ~TU_Construction () { transform_info (0); } + virtual ModelNode &jpl () { return *this; } +}; + +class TU_Destruction : public ACM_Destruction, public TI_Destruction { +public: + TU_Destruction () { transform_info (this); } + ~TU_Destruction () { transform_info (0); } + virtual ModelNode &jpl () { return *this; } +}; + +class TU_Introduction : public ACM_Introduction, public TI_Introduction { +public: + TU_Introduction () { transform_info (this); } + ~TU_Introduction () { transform_info (0); } + virtual ModelNode &jpl () { return *this; } +}; + +class TU_Order : public ACM_Order, public TI_Order { +public: + TU_Order () { transform_info (this); } + ~TU_Order () { transform_info (0); } + virtual ModelNode &jpl () { return *this; } +}; + +class TU_Pointcut : public ACM_Pointcut, public TI_Pointcut { +public: + TU_Pointcut () { transform_info (this); } + ~TU_Pointcut () { transform_info (0); } + virtual ModelNode &jpl () { return *this; } +}; + +class TU_Attribute : public ACM_Attribute, public TI_Attribute { +public: + TU_Attribute () { transform_info (this); } + ~TU_Attribute () { transform_info (0); } + virtual ModelNode &jpl () { return *this; } +}; + +#ifdef FRONTEND_PUMA + +#include "PumaModelBuilder.h" +class ModelBuilder : public PumaModelBuilder { +public: + ModelBuilder (Puma::VerboseMgr &vm, ACErrorStream &err, ACConfig &conf, + ACProject &project) : PumaModelBuilder (vm, err, conf, project) {} +}; + +#else // FRONTEND_CLANG + +#include "ClangModelBuilder.h" +class ModelBuilder : public ClangModelBuilder { +public: + ModelBuilder (Puma::VerboseMgr &vm, ACErrorStream &err, ACConfig &conf, + ACProject &project) : ClangModelBuilder (vm, err, conf, project) {} +}; + +#endif + +#endif // __ModelBuilder_h__ diff --git a/AspectC++/NamespaceAC.cc b/AspectC++/NamespaceAC.cc new file mode 100644 index 0000000..a07d4eb --- /dev/null +++ b/AspectC++/NamespaceAC.cc @@ -0,0 +1,266 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "NamespaceAC.h" +#include "CFlow.h" +#include "version.h" + +// ACModel library includes +#include "ACModel/Elements.h" + +// C++ includes +#include + +using std::ostringstream; +using std::endl; + + +string NamespaceAC::def( ACConfig &config ) { + string acdef; + ostringstream jptype_ids; + + if( config.data_joinpoints() ) + jptype_ids + << "GET = " << JPT_Get << ", " + << "SET = " << JPT_Set << ", " + << "REF = " << JPT_Ref << ", "; + if( config.builtin_operators() ) + jptype_ids + << "BUILTIN = " << JPT_Builtin << ", "; + jptype_ids + << "CALL = " << JPT_Call << ", " + << "EXECUTION = " << JPT_Execution << ", " + << "CONSTRUCTION = " << JPT_Construction << ", " + << "DESTRUCTION = " << JPT_Destruction; + + acdef += + "\n" + "#ifndef __ac_h_\n" + "#define __ac_h_\n" + "#ifdef __cplusplus\n" + "namespace AC {\n" + " typedef const char* Type;\n" + " enum JPType { " + jptype_ids.str() + " };\n" + " enum Protection { PROT_NONE, PROT_PRIVATE, PROT_PROTECTED, PROT_PUBLIC };\n" + " enum Specifiers { SPEC_NONE = 0x0 , SPEC_STATIC = 0x1, SPEC_MUTABLE = 0x2, SPEC_VIRTUAL = 0x4 };\n" + " struct Action {\n" + " void **_args; void *_result;"; + acdef += " void *_entity;"; + if( config.data_joinpoints() ) + acdef += " void *_array; void **_indices;"; + acdef += " void *_target; void *_that; void *_fptr;\n" + " void (*_wrapper)(Action &);\n" + " inline void trigger () { _wrapper (*this); }\n" + " };\n" + " struct AnyResultBuffer {};\n" + " template struct ResultBuffer : public AnyResultBuffer {\n" + " struct { char _array[sizeof (T)]; } _data;\n" + " ~ResultBuffer () { ((T&)_data).T::~T(); }\n" + " operator T& () const { return (T&)_data; }\n" + " };\n" + " template struct TL {\n" + " typedef T type; typedef N next; enum { ARGS = next::ARGS + 1 };\n" + " };\n" + " struct TLE { enum { ARGS = 0 }; };\n" + " template struct Referred { typedef T type; };\n" + " template struct Referred { typedef T type; };\n" + " template struct Arg {\n" + " typedef typename Arg::Type Type;\n" + " typedef typename Referred::type ReferredType;\n" + " };\n" + " template struct Arg {\n" + " typedef typename TL::type Type;\n" + " typedef typename Referred::type ReferredType;\n" + " };\n"; + if( config.builtin_operators() ) + acdef += + " template struct ConstQualify {};\n" + " template struct ConstQualify { typedef T type; };\n" + " template struct ConstQualify { typedef const T type; };\n" + " template struct ConstQualify { typedef const T type; };\n" + " template struct ArgCQ {\n" + " typedef typename ConstQualify::Type, ( FC >> I ) & 1>::type Type;\n" + " typedef typename Referred::type ReferredType;\n" + " };\n"; + acdef += + " template int ttest(...);\n" + " template char ttest(typename T::__TI const volatile *);\n" + " template struct HasTypeInfo {\n" + " enum { RET=((sizeof(ttest(0))==1)?1:0) };\n" + " };\n" + " template::RET> struct TypeInfo {\n" + " enum { AVAILABLE = 0, BASECLASSES = 0, MEMBERS = 0, FUNCTIONS = 0,\n" + " CONSTRUCTORS = 0, DESTRUCTORS = 0 };\n" + " typedef T That;\n" + " };\n" + " template struct TypeInfo : T::__TI {\n" + " enum { AVAILABLE = 1 };\n" + " };\n" + " template struct RT {};\n" + " template RT rt_deduce (const T&) { return RT(); }\n" + " struct Cnv { template operator RT() const { return RT(); }};\n" + " #define __AC_TYPEOF(expr) (1?AC::Cnv():AC::rt_deduce(expr))\n"; + + // class(es) needed to implement CFlows + acdef += CFlow::ac_namespace_contributions (); + +#ifdef FRONTEND_CLANG + // Clang Variant only features + + // definitions for packed Entity handling + if( config.data_joinpoints() ) + acdef += + " template inline E T::* mptr_castT( E O::*mptr ) { return static_cast< E T::* >( mptr ); }\n" + " template struct SpliceT {};\n" + " template struct SpliceT< B[D] > {\n" + " typedef B Base;\n" + " enum { Dim = D };\n" + " };\n" + " template struct DIL : N {\n" + " typedef N Next;\n" + " enum { Count = Next::Count + 1 };\n" + " enum { Size = TSize };\n" + " typedef TIdx Idx;\n" + " Idx idx;\n" + " template struct Entity { typedef typename SpliceT< typename Next::template Entity::Type >::Base Type; };\n" + " template struct Array { typedef typename Next::template Array::Type Type[Size]; };\n" + " template inline E& apply( typename Array::Type &base ) { return Next::template apply( base[idx] ); }\n" + " template struct Append { typedef DIL::NewList > NewList; };\n" + " template inline void copyTo( DIL *target ) {\n" + " target->idx = idx;\n" + " Next::copyTo( static_cast( target ) );\n" + " };\n" + " };\n" + " struct DILE {\n" + " enum { Count = 0 };\n" + " template struct Entity { typedef B Type; };\n" + " template struct Array { typedef E Type; };\n" + " template inline E& apply( typename Array::Type &base ) { return base; }\n" + " template struct Append { typedef A NewList; };\n" + " template inline void copyTo( O * ) {};\n" + " };\n" + " template struct DIL_Op {\n" + " enum { Size = DIL_Op::Size };\n" + " typedef typename DIL_Op::Idx Idx;\n" + " inline static Idx &idx( L *di ) { return DIL_Op::idx( di ); }\n" + " };\n" + " template struct DIL_Op {\n" + " enum { Size = L::Size };\n" + " typedef typename L::Idx Idx;\n" + " inline static Idx &idx( L *di ) { return di->idx; }\n" + " };\n" + " template struct BI_Entity {\n" + " typedef TEntity Entity;\n" + " Entity &_ent;\n" + " inline BI_Entity( Entity &ent ) : _ent( ent ) {}\n" + " inline Entity &entity() { return _ent; }\n" + " };\n" + " template struct BI_Member {\n" + " typedef TEntity Entity;\n" + " typedef TTarget Target;\n" + " typedef Entity Target::*Member;\n" + " Target &_target;\n" + " Member _member;\n" + " inline BI_Member( Target &target, Member mem ) : _target( target ), _member( mem ) {}\n" + " inline Entity &entity() { return _target.*_member; }\n" + " };\n" + " template struct BI_Static {\n" + " typedef TEntity Entity;\n" + " typedef TTarget Target;\n" + " Entity &_ent;\n" + " Target &_target;\n" + " inline BI_Static( Target &target, Entity &ent ) : _ent( ent ), _target( target ) {}\n" + " inline Entity &entity() { return _ent; }\n" + " };\n" + " template struct PackedEntity {\n" + " typedef PackedEntity SELF;\n" + " typedef TBI BI;\n" + " typedef TDI DI;\n" + " BI _base;\n" + " DI _indices;\n" + " inline PackedEntity( BI base ) : _base( base ) {}\n" + " typedef typename BI::Entity Base;\n" + " typedef typename DI::template Entity::Type Entity;\n" + " inline Base &base() { return _base.entity(); };\n" + " inline Entity &entity() { return _indices.template apply( base() ); }\n" + " enum { DIMS = DI::Count };\n" + " template struct Dim : DIL_Op {};\n" + " template inline typename Dim::Idx &idx() { return Dim::idx( &_indices ); }\n" + " template struct Extend {\n" + " typedef typename SpliceT::Base NewEnt;\n" + " enum { NextDim = SpliceT::Dim };\n" + " typedef typename DI::template Append< DIL< NextDim, NextIdx, DILE > >::NewList NewDI;\n" + " typedef PackedEntity< BI, NewDI > NewPacked;\n" + " };\n" + " template inline typename Extend::NewPacked operator []( TIdxN idxN ) {\n" + " typedef typename Extend::NewPacked __PE;\n" + " __PE res( _base );\n" + " _indices.copyTo( &res._indices );\n" + " __PE::template Dim<__PE::DIMS - 1>::idx( &res._indices ) = idxN;\n" + " return res;\n" + " }\n" + " inline SELF operator =( Entity arg ) { entity() = arg; return *this; }\n" + " template inline SELF operator +=( ARG arg ) { entity() += arg; return *this; }\n" + " template inline SELF operator -=( ARG arg ) { entity() -= arg; return *this; }\n" + " template inline SELF operator *=( ARG arg ) { entity() *= arg; return *this; }\n" + " template inline SELF operator /=( ARG arg ) { entity() /= arg; return *this; }\n" + " template inline SELF operator %=( ARG arg ) { entity() %= arg; return *this; }\n" + " template inline SELF operator |=( ARG arg ) { entity() |= arg; return *this; }\n" + " template inline SELF operator ^=( ARG arg ) { entity() ^= arg; return *this; }\n" + " template inline SELF operator &=( ARG arg ) { entity() &= arg; return *this; }\n" + " template inline SELF operator <<=( ARG arg ) { entity() <<= arg; return *this; }\n" + " template inline SELF operator >>=( ARG arg ) { entity() >>= arg; return *this; }\n" + " inline SELF operator ++() { ++entity(); return *this; }\n" + " inline SELF operator --() { --entity(); return *this; }\n" + " };\n" + " template \n" + " inline PackedEntity< BI_Entity, DILE > PEInit( TEntity &ent ) {\n" + " return PackedEntity< BI_Entity, DILE >( BI_Entity( ent ) );\n" + " }\n" + " template \n" + " inline PackedEntity, DILE> PEInit( const TTarget &target, TEntity TTarget::*member ) {\n" + " return PackedEntity< BI_Member, DILE >( BI_Member( const_cast( target ), member ) );\n" + " }\n" + " template \n" + " inline PackedEntity, DILE> PEInit( const TTarget &target, TEntity &ent ) {\n" + " return PackedEntity< BI_Static, DILE >( BI_Static( const_cast( target ), ent ) );\n" + " }\n"; + +#if CLANG_VERSION_NUMBER < VERSION_NUMBER_3_9_1 + // Clang < 3.9.1 does not support the __float128 type and we defined the __float128 type by ourself inside + // namespace AC during parsing to avoid parse errors (see ClangIntroducer::tunit_start(...)). The woven code + // may reference our imitated __float128 type with ::AC::__float128. Later, when compiling the woven + // code (e.g. by using g++) __float128 is natively supported and we just forward ::AC::__float128 to the + // global/built-in __float128: + // TODO: Add this typedef only if the source already contains __float128 (and if we use __float128 inside + // woven code)! + // acdef += " typedef __float128 __float128;\n"; +#endif + +#endif // FRONTEND_CLANG + + acdef += + "}\n" + "inline void * operator new (" + config.size_type() + ", AC::AnyResultBuffer *p) { return p; }\n" + "inline void operator delete " + "(void *, AC::AnyResultBuffer *) { } // for VC++\n" + "#endif // __cplusplus\n" + "#endif // __ac_h_\n"; + + return acdef; +} diff --git a/AspectC++/NamespaceAC.h b/AspectC++/NamespaceAC.h new file mode 100644 index 0000000..24d86aa --- /dev/null +++ b/AspectC++/NamespaceAC.h @@ -0,0 +1,29 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __NamespaceAC_h__ +#define __NamespaceAC_h__ + +#include "ACConfig.h" + +class NamespaceAC { +public: + static string def( ACConfig &config ); +}; + +#endif diff --git a/AspectC++/Naming.cc b/AspectC++/Naming.cc new file mode 100644 index 0000000..4a8bafc --- /dev/null +++ b/AspectC++/Naming.cc @@ -0,0 +1,400 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 +#include + +#include "Naming.h" +#include "ACFileID.h" +#include "ACModel/Utils.h" +#include "AdviceInfo.h" +#include "JoinPoint.h" +#include "AspectInfo.h" + +#include "Puma/SysCall.h" + +void Naming::scope_name (ostream &out, ACM_Name &scope) { + // check if we reached the global scope + if (scope.get_name() == "::") + return; + + // print the parent scope first + if (scope.get_parent()) + scope_name (out, *(ACM_Name*)scope.get_parent()); + + string name = scope.get_name(); + // print the scope name, preceeded by the length of the string + if (name.substr(0, 5) == "") + out << "12_GLOBAL__N_1"; // same symbol as used by g++ + else if (name.rfind ('>') != string::npos) + out << "4ANON"; // TODO: this is a hack - template parameters should be mangled! + else + out << scope.get_name().length() << scope.get_name(); +} + +bool Naming::is_unary_op (ACM_Function *func) { + assert (func->get_name().substr(0,9) == "operator "); + bool is_method = (func->get_kind () != FT_NON_MEMBER && + func->get_kind () != FT_STATIC_NON_MEMBER); + return (is_method && func->get_arg_types ().size () == 0) || + (!is_method && func->get_arg_types ().size () == 1); +} + +void Naming::op_name (ostream &out, ACM_Function *func) { + string name = func->get_name ().substr (9); + + if (name == "new") + out << "nw"; + else if (name == "new[]") + out << "na"; + else if (name == "delete") + out << "dl"; + else if (name == "delete[]") + out << "da"; + else if (name == "-" && is_unary_op (func)) + out << "ng"; + else if (name == "&" && is_unary_op (func)) + out << "ad"; + else if (name == "*" && is_unary_op (func)) + out << "de"; + else if (name == "~") + out << "co"; + else if (name == "+") + out << "pl"; + else if (name == "-" && !is_unary_op (func)) + out << "mi"; + else if (name == "*" && !is_unary_op (func)) + out << "ml"; + else if (name == "/") + out << "dv"; + else if (name == "%") + out << "rm"; + else if (name == "&" && !is_unary_op (func)) + out << "an"; + else if (name == "|") + out << "or"; + else if (name == "^") + out << "eo"; + else if (name == "=") + out << "aS"; + else if (name == "+=") + out << "pL"; + else if (name == "-=") + out << "mI"; + else if (name == "*=") + out << "mL"; + else if (name == "/=") + out << "dV"; + else if (name == "%=") + out << "rM"; + else if (name == "&=") + out << "aN"; + else if (name == "|=") + out << "oR"; + else if (name == "^=") + out << "eO"; + else if (name == "<<") + out << "ls"; + else if (name == ">>") + out << "rs"; + else if (name == "<<=") + out << "lS"; + else if (name == ">>=") + out << "rS"; + else if (name == "==") + out << "eq"; + else if (name == "!=") + out << "ne"; + else if (name == "<") + out << "lt"; + else if (name == ">") + out << "gt"; + else if (name == "<=") + out << "le"; + else if (name == ">=") + out << "ge"; + else if (name == "!") + out << "nt"; + else if (name == "&&") + out << "aa"; + else if (name == "||") + out << "oo"; + else if (name == "++") + out << "pp"; + else if (name == "--") + out << "mm"; + else if (name == ",") + out << "cm"; + else if (name == "->*") + out << "pm"; + else if (name == "->") + out << "pt"; + else if (name == "()") + out << "cl"; + else if (name == "[]") + out << "ix"; + else if (name == "?") + out << "qu"; + else { + // handle a conversion function + out << "cv"; + mangle (out, func->get_result_type()); + } +} + +void Naming::constr_name (ostream &out, ACM_Function *func) { + out << "C1"; +} + +void Naming::destr_name (ostream &out, ACM_Function *func) { + out << "D1"; +} + +// name mangling for variables and functions +void Naming::mangle (ostream &out, ACM_Name *obj) { + + // check if this object is a function: + ACM_Function *func = (obj->type_val() == JPT_Function ? (ACM_Function*)obj : 0); + + // determine the scope + ACM_Name *scope = (ACM_Name*)obj->get_parent(); + +// // objects with C linkage and global namespace variables are not mangled +// if (obj->Language () == CLanguage::LANG_C || +// (scope->GlobalScope () && !obj->FunctionInfo ())) { +// out << obj->Name (); +// return; +// } + // global namespace variables are not mangled (why not?) + if (obj->type_val () != JPT_Function && scope->get_name () == "::") { + out << obj->get_name (); + return; + } + + // mangle the function name + out << "_Z"; + + // print the (possibly nested) scope of the function + if (scope->get_name () != "::") { + out << "N"; + // possible CV qualifier of member functions must be printed here + if (func) { + if (func->get_cv_qualifiers () & CVQ_CONST) + out << "K"; + if (func->get_cv_qualifiers () & CVQ_VOLATILE) + out << "V"; + } + scope_name (out, *scope); + } + + if (func) { + // print the function name (special handling) + if (func->get_kind () == FT_CONSTRUCTOR) + constr_name (out, func); + else if (func->get_kind () == FT_DESTRUCTOR || + func->get_kind () == FT_VIRTUAL_DESTRUCTOR || + func->get_kind () == FT_PURE_VIRTUAL_DESTRUCTOR) + destr_name (out, func); + else if (func->get_name ().substr (0, 9) == "operator ") { + op_name (out, func); + } + else + out << func->get_name ().length () << func->get_name (); + } + else { + out << obj->get_name ().length () << obj->get_name (); + } + + // if this was a nested name, add the 'E' + if (scope->get_name () != "::") + out << "E"; + + if (func) { + // print the argument types (also mangled) + if (get_arg_count (*func) == 0) + out << "v"; + else { + typedef ACM_Container C; + C &arg_types = func->get_arg_types (); + for (C::iterator i = arg_types.begin (); i != arg_types.end (); ++i) + mangle (out, *i); +// TI_Type::of (**i)->type_info ()->Mangled (out); + } + } +} + +void Naming::mangle (ostream &out, ACM_Type *type) { + MatchSignature &match_sig = type->get_match_sig(); + if (match_sig.is_new()) + match_sig.parse(format_type (*type)); + match_sig.type().mangle(out); +} + +void Naming::mangle (ostream &out, const ACM_Arg *arg) { + // we only mangle the type of the argument, not its name + MatchSignature match_sig; + match_sig.parse(arg->get_type()); + match_sig.type().mangle(out); +} + +void Naming::bypass_id_class (ostream& out, ACM_Call *jpl) { + out << "__ID"; + mangle (out, (ACM_Name*)jpl->get_parent ()); + if (jpl->get_lid () >= 0) + out << "_" << jpl->get_lid (); +} + +string Naming::bypass_caller_class (ACM_Class *cls) { + ostringstream out; + out << "__BYPASS"; + mangle (out, cls); + return out.str (); +} + +void Naming::access_wrapper (ostream& out, ACM_Access *jpl, unsigned depth, int wrapper_number) { + out << "__" << jpl->type_str() << "_"; + + ACM_Name *parent = get_explicit_parent( *jpl ); + mangle( out, parent ); + + if (jpl->get_lid () >= 0) + out << "_" << jpl->get_lid (); + out << "_" << depth; + if(wrapper_number >= 0) { + out << "_" << wrapper_number; + } +} + +void Naming::exec_inner (ostream& out, ACM_Code *jpl) { + ACM_Function *func = (ACM_Function*)jpl->get_parent (); + assert (func && (func->type_val () == JPT_Function)); + + out << "__exec_old_"; + if (func->get_kind () == FT_CONSTRUCTOR) + constr_name (out, func); + else if (func->get_kind () == FT_DESTRUCTOR || + func->get_kind () == FT_VIRTUAL_DESTRUCTOR || + func->get_kind () == FT_PURE_VIRTUAL_DESTRUCTOR) + destr_name (out, func); + else if (func->get_name ().substr (0, 9) == "operator ") { + op_name (out, func); + } + else + out << func->get_name (); +} + +void Naming::action_wrapper (ostream &out, ACM_Any *loc, unsigned depth) { + out << "__action_func"; +} + +void Naming::exec_advice (ostream& out, ACM_Execution *jpl, AdviceInfo *adv) { + out << "__" << (adv->name ().c_str() + 1); +} + +void Naming::call_advice (ostream& out, ACM_Call *jpl, AdviceInfo *adv) { + out << "__" << (adv->name ().c_str() + 1); +} + +void Naming::local_id (ostream& out, ACM_Code *jpl) { + if (jpl->type_val () & JPT_Access) { + ACM_Access *jpl_code = (ACM_Access*)jpl; + if (jpl_code->get_lid () >= 0) + out << "_" << jpl_code->get_lid(); + } +} + +void Naming::tjp_struct(ostream& out, ACM_Code *loc, int depth) { + out << "TJP_"; + + ACM_Name *parent = get_explicit_parent( *loc ); + mangle( out, parent ); + + local_id (out, loc); + out << "_" << depth; +} + +void Naming::tjp_instance(ostream& out, ACM_Code *loc) { + out << "tjp"; +} + +void Naming::tjp_args_array(ostream& out, ACM_Code *loc) { + out << "args_"; + + ACM_Name *parent = get_explicit_parent( *loc ); + mangle( out, parent ); + + local_id (out, loc); +} + +void Naming::tjp_argtypes(ostream& out, ACM_Code *loc) { + out << "argtypes_"; + + ACM_Name *parent = get_explicit_parent( *loc ); + mangle( out, parent ); + + local_id (out, loc); +} + +void Naming::cflow (ostream& out, ACM_Aspect &jpl_aspect, int index) { + out << "::AC::CFlow<" << signature(jpl_aspect) << "," << index << ">"; +} + +bool Naming::is_tjp_object (const char *candidate) { + return strcmp (candidate, "tjp") == 0 || + strcmp (candidate, "thisJoinPoint") == 0; +} + +void Naming::tjp_typedef (ostream& out, const char *name) { + out << "__JP_" << name; +} + +void Naming::type_check_func (ostream &out, ACM_Class &in, const string &name) { + out << "__ac_"; + scope_name (out, in); + out << "is_" << name; +} + +void Naming::guard (ostream &out, ACFileID unit) { + out << "__ac_guard_"; + mangle_file (out, unit); +} + +void Naming::mangle_file (ostream &out, ACFileID file_id) { + // TODO: better is unit->absolutePath() but the implementation is strange and + // has to be changed. + Puma::Filename name; + if (Puma::SysCall::canonical (file_id.name ().c_str (), name)) + mangle_file (out, name.name ()); +} + +void Naming::mangle_file (ostream &out, const char *name) { + const char *curr = name; + while (*curr) { + if (*curr == '_' || isalnum (*curr)) + out << *curr; + else if (*curr == '/' || *curr == '\\' || *curr == ':' || *curr == '.') + out << "_"; + else + out << 'X' << (unsigned int)*(unsigned char*)curr; + curr++; + } + out << "__"; +} + diff --git a/AspectC++/Naming.h b/AspectC++/Naming.h new file mode 100644 index 0000000..8832fda --- /dev/null +++ b/AspectC++/Naming.h @@ -0,0 +1,78 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __Naming_h__ +#define __Naming_h__ + +#include +#include +using namespace std; +// This class encapsulates the naming scheme for generated functions etc. + +class ACM_Any; +class ACM_Code; +class ACM_Access; +class ACM_Call; +class ACM_Execution; +class ACM_Aspect; +class ACM_Class; +class ACM_Function; +class ACM_Name; +class ACM_Type; +class ACM_Arg; + +#include "ACFileID.h" + +class AdviceInfo; +class AspectInfo; + +class Naming { + static bool is_unary_op (ACM_Function *func); + static void scope_name (ostream &out, ACM_Name &scope); + +public: + static void op_name (ostream &out, ACM_Function *func); + static void constr_name (ostream &out, ACM_Function *func); + static void destr_name (ostream &out, ACM_Function *func); + static void mangle (ostream &out, ACM_Name *obj); + static void mangle (ostream &out, ACM_Type *type); + static void mangle (ostream &out, const ACM_Arg *arg); + static void bypass_id_class (ostream& out, ACM_Call *jpl); + static void access_wrapper (ostream& out, ACM_Access *jpl, unsigned depth, int wrapper_number = -1); + static void exec_inner (ostream& out, ACM_Code *jpl); + static void action_wrapper (ostream& out, ACM_Any *loc, unsigned depth); + static void exec_advice (ostream& out, ACM_Execution *jpl, AdviceInfo *ad); + static void call_advice (ostream& out, ACM_Call *jpl, AdviceInfo *ad); + static void local_id (ostream& out, ACM_Code *jpl); + static void tjp_struct(ostream& out, ACM_Code *loc, int depth); + static void tjp_instance(ostream& out, ACM_Code *loc); + static void tjp_args_array(ostream& out, ACM_Code *loc); + static void tjp_argtypes(ostream& out, ACM_Code *loc); + static void cflow (ostream& out, ACM_Aspect &jpl_aspect, int index); + static string bypass_caller_class (ACM_Class *cls); + static void tjp_typedef (ostream& out, const char *name); + static void type_check_func (ostream &out, ACM_Class &in, const string &name); + static void guard (ostream &out, ACFileID unit); + static void mangle_file (ostream &out, ACFileID file_id); + static void mangle_file (ostream &out, const char *name); + + // checks + static bool is_tjp_object (const char *candidate); +}; + +#endif // __Naming_h__ diff --git a/AspectC++/OrderInfo.h b/AspectC++/OrderInfo.h new file mode 100644 index 0000000..1a62c06 --- /dev/null +++ b/AspectC++/OrderInfo.h @@ -0,0 +1,67 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __OrderInfo_h__ +#define __OrderInfo_h__ + +#include "ACErrorStream.h" +#include "PointCutContext.h" +#include "PointCutExpr.h" +#include "TransformInfo.h" +#include "ACModel/Elements.h" + +class OrderInfo { + + ACM_Aspect &_aspect; + ACM_Order &_order; + list _pces; + PointcutExpression _jp_pce; + + PointCutExpr *add_pce (PointcutExpression &pce) { + _pces.push_back (pce); + return (PointCutExpr*)_pces.back().get(); + } + + public: + + OrderInfo (ACM_Aspect &a, ACM_Order &o) : _aspect (a), _order (o) {} + + ACM_Aspect &aspect () const { return _aspect; } + ACM_Order &order () const { return _order; } + const list &pces () const { return _pces; } + PointcutExpression &jp_pce () { return _jp_pce; } + void analyze_exprs (ACErrorStream &err, PointCutContext &context, int warn_compat) { + _jp_pce = _order.get_pointcut()->get_parsed_expr(); + ((PointCutExpr*)_jp_pce.get())->semantics(err, context, warn_compat); + typedef ACM_Container Container; + const Container &exprs = _order.get_aspect_exprs(); + for (Container::const_iterator i = exprs.begin (); i != exprs.end (); ++i) { + PointCutExpr *pce = add_pce ((*i)->get_parsed_expr ()); + pce->semantics(err, context, warn_compat); + if (!(pce->possible_types() & JPT_Class)) { + err << Puma::sev_warning + << TI_Pointcut::of(*_order.get_pointcut ())->get_location() + << "pointcut expression in order advice can't match aspect" + << Puma::endMessage; + } + + } + } +}; + +#endif // __OrderInfo_h__ diff --git a/AspectC++/OrderPlanner.h b/AspectC++/OrderPlanner.h new file mode 100644 index 0000000..6c2ba10 --- /dev/null +++ b/AspectC++/OrderPlanner.h @@ -0,0 +1,119 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __OrderPlanner_h__ +#define __OrderPlanner_h__ + +#include +#include +#include + +using namespace std; + +template > +class OrderPlanner { + + struct Links; + + typedef map NodeMap; + typedef typename NodeMap::value_type Node; + + struct Links { + set _in; + set _out; + }; + + NodeMap _node_map; + vector _total_order; + +public: + // consider an order relation of two nodes + void precedence (Item &first, Item &later); + + // calculate the total order => false if there is a cycle + bool plan (); + + // get the result + int items () const { return _total_order.size (); } + Item &item (int i) const { return *_total_order[i]; } + +}; + + +template +bool OrderPlanner::plan () { + + // loop until all node have been moved to the total order vector + while (_node_map.size () > 0) { + + // loop over all remaining nodes and count number of shifted nodes + int moved = 0; + typename NodeMap::iterator curr = _node_map.begin (); + while (curr != _node_map.end ()) { + // shift the current node if it has no incoming edge + // (no left node has a higher precedence) + if ((*curr).second._in.size () == 0) { + moved++; + + // add this node to the total order + _total_order.push_back ((*curr).first); + + // remove the edges of this node to other nodes with lower precedence + for (typename set::iterator edge = (*curr).second._out.begin (); + edge != (*curr).second._out.end (); ++edge) + (*edge)->second._in.erase (&*curr); + + // remove the node + typename NodeMap::iterator rem = curr; + ++curr; + _node_map.erase (rem); + } + else { + ++curr; + } + } + // if no node was moved there must be a cycle in the graph! + if (moved == 0) + return false; + } + return true; +} + +template +void OrderPlanner::precedence (Item &first, Item &later) { + + // find/insert the 'first' node + typename NodeMap::iterator f = _node_map.find (&first); + if (f == _node_map.end ()) { + _node_map.insert (Node (&first, Links ())); + f = _node_map.find (&first); + } + + // find/insert the 'later' node + typename NodeMap::iterator l = _node_map.find (&later); + if (l == _node_map.end ()) { + _node_map.insert (Node (&later, Links ())); + l = _node_map.find (&later); + } + + // insert the incoming and outgoing edges + (*f).second._out.insert (&*l); + (*l).second._in.insert (&*f); +} + +#endif // __OrderPlanner_h__ diff --git a/AspectC++/Phase1.cc b/AspectC++/Phase1.cc new file mode 100644 index 0000000..b857ce8 --- /dev/null +++ b/AspectC++/Phase1.cc @@ -0,0 +1,2058 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "Phase1.h" +#include "ModelBuilder.h" +#include "PointCutExprParser.h" +#include "ACModel/Utils.h" +#include "PointCutContext.h" +#include "PointCutExpr.h" + +using namespace std; +using namespace Puma; + +#ifdef FRONTEND_PUMA +int Phase1::run (IncludeGraph &include_graph) { +#else +int Phase1::run () { +#endif + + // set the start and end token of the unit +#ifdef FRONTEND_PUMA + if (!unit ()) { + err() << sev_error << "can't scan file \"" << _tunit_name.c_str () << "\"" + << endMessage; + return -1; + } + + Token *file_first = unit()->first (); + Token *file_last = unit()->last (); + if (!file_first) + return 0; + assert (file_last); + + _code_weaver.init ((Token*)file_first, (Token*)file_last); +#endif + + // prepare the project model +#ifdef FRONTEND_PUMA + _jpm.setup_phase1((FileUnit*)unit (), _code_weaver.primary_len()); +#else + _jpm.setup_phase1(_tunit_name, tunit_len()); +#endif + + // prepare the parser's scope hierarchy + _root_scope._kind = Scope::SCOPE_NAMESPACE; + _root_scope._name = "::"; + _root_scope._is_slice = false; + _root_scope._parent_scope = 0; + _root_scope._jpm_link = _jpm.get_root(); + + // parse the elements of the global scope + try { + parse_scope (_root_scope); + } + catch (ParseError) { + // we simply return an error code if there was a parse error, indicated by an exception + // the message has been printed on the error stream where the error was detected + return -1; + } + +#ifdef FRONTEND_PUMA // TODO: check this for Clang as well + // special check for tokens after eoi + PumaToken after_program = curr_token(); + if (after_program) { // error, e.g. too many closing brackets + err() << sev_error << after_program.location() + << "tokens after end of program (too many closing brackets?)" + << endMessage; + } + +// _root_scope.dump (); + + // finally parse the preprocessor syntax tree in order to create an + // include graph of the original source code + get_include_graph(include_graph); +#endif + + return (err().severity () < sev_error) ? 1 : -1; +} + +void Phase1::skip_block (int open, int close, bool inclusive) { + int token; + int depth = 0; + ACToken open_token = curr_token (); + + while (curr_token ().type () != ACToken::TOK_EOF) { + token = curr_token ().type (); + + if (token == open) + depth++; + else if (token == close) + depth--; + else if (depth > 0 && token == ACToken::TOK_OPEN_ROUND) { + skip_round_block (); + continue; + } + + if (depth == 0 && !inclusive) + break; + + next_token (); + + if (depth == 0) + break; + } + + if (curr_token ().type () == ACToken::TOK_EOF) { + err() << sev_error << open_token.location() << "missing closing bracket" << endMessage; + throw ParseError(); + } +} + +void Phase1::skip_round_block (bool inclusive) { + skip_block (ACToken::TOK_OPEN_ROUND, ACToken::TOK_CLOSE_ROUND, inclusive); +} + +void Phase1::skip_curly_block (bool inclusive) { + skip_block (ACToken::TOK_OPEN_CURLY, ACToken::TOK_CLOSE_CURLY, inclusive); +} + +void Phase1::skip_square_block (bool inclusive) { + skip_block (ACToken::TOK_OPEN_SQUARE, ACToken::TOK_CLOSE_SQUARE, inclusive); +} + +void Phase1::skip_template_params () { + int depth = 0; + next_token (); + + bool stop = false; + while (!stop && curr_token ().type () != ACToken::TOK_EOF) { + int token = curr_token ().type (); + + switch (token) { + case ACToken::TOK_SEMI_COLON: + case ACToken::TOK_CLOSE_ROUND: + case ACToken::TOK_CLOSE_SQUARE: + case ACToken::TOK_CLOSE_CURLY: + stop = true; + break; + case ACToken::TOK_OPEN_ROUND: + skip_round_block (); + continue; + case ACToken::TOK_OPEN_CURLY: + skip_curly_block (); + continue; + case ACToken::TOK_OPEN_SQUARE: + skip_block (ACToken::TOK_OPEN_SQUARE, ACToken::TOK_CLOSE_SQUARE); + continue; + case ACToken::TOK_LESS: + depth++; + break; + case ACToken::TOK_GREATER: + if (depth == 0) { + next_token (); + stop = true; + } else { + depth--; + } + break; + default: + break; + } + + if (!stop) + next_token (); + } +} + +bool Phase1::is_attribute_token (const ACToken &token, const ACToken &next) const { + return is_gnu_attribute_token(token) || is_cxx11_attribute_token(token, next); +} + +bool Phase1::is_cxx11_attribute_token (const ACToken &token, const ACToken &next) const { + return token.type() == ACToken::TOK_OPEN_SQUARE && + next.type() == ACToken::TOK_OPEN_SQUARE; +} + +bool Phase1::is_gnu_attribute_token (const ACToken &token) const { + return token.type () == ACToken::TOK_ATTRIBUTE || + token.type () == ACToken::TOK_ALIGNAS; +} + +void Phase1::skip_cxx11_attributes (bool inclusive) { + while (is_cxx11_attribute_token(curr_token (), look_ahead ())) { + skip_square_block(false); + if (!is_cxx11_attribute_token(look_ahead (), look_ahead(2))) + break; + next_token (); + } + if (inclusive) + next_token (); +} + +void Phase1::skip_attributes (bool inclusive) { + while (true) { + if (is_gnu_attribute_token(curr_token())) + skip_gnu_attributes(false); + else if (is_cxx11_attribute_token(curr_token(), look_ahead())) + skip_cxx11_attributes(false); + else + return; + if (!is_attribute_token(look_ahead(1), look_ahead(2))) { + if (inclusive) + next_token(); + return; + } + next_token(); + } +} + +void Phase1::skip_gnu_attributes (bool inclusive) { + while (is_gnu_attribute_token(curr_token ())) { + next_token(); + skip_round_block(false); + if (!is_gnu_attribute_token(look_ahead ())) + break; + next_token (); + } + if (inclusive) + next_token (); +} + +ACM_Name *Phase1::register_scope (Scope &scope) { + if (!scope._jpm_link) { + ACM_Name *parent_scope = register_scope (*scope._parent_scope); + if (scope.is_namespace()) { + scope._jpm_link = _jpm.register_namespace1(parent_scope, scope._name, false); + } + else if (scope.is_aspect()) { + scope._jpm_link = _jpm.register_aspect1(parent_scope, scope._name, false); + register_base_classes (scope); + } + else if (scope.is_class_or_struct()) { + scope._jpm_link = _jpm.register_class1(parent_scope, scope._name, false); + register_base_classes (scope); + } + } + return scope._jpm_link; +} + +void Phase1::register_base_classes (Scope &cls) { + ACM_Class *elem = (ACM_Class*)cls._jpm_link; + for (list::iterator i = cls._search_scopes.begin (); + i != cls._search_scopes.end (); ++i) { + ACM_Class *base_class = (ACM_Class*)register_scope (*(*i)); + elem->get_bases().insert (base_class); + base_class->get_derived().insert(elem); + } +} + +bool Phase1::is_visible_scope (Scope &scope, const string &name) { + if (scope._name == "::") + return (name != "AC" && name != "JoinPoint"); + return is_visible_scope (*scope._parent_scope, scope._name); +} + +string Phase1::full_anon_class_name (Scope &scope) const { + if (scope._parent_scope && scope._parent_scope->_name.substr (0, 9) == "__ac_anon") + return full_anon_class_name (*scope._parent_scope) + "::" + scope._name; + else + return scope._name; +} + +#ifdef FRONTEND_CLANG +void Phase1::set_slice_tokens (TU_ClassSlice *slice, + ACPreprocessor::TokenVector &pattern) { + + // Analyze the tokens. + bool has_base_intro = false; + bool has_member_intro = false; + for (unsigned j = 0; j != pattern.size(); ++j) { + if (pattern[j].type () == ACToken::TOK_SEMI_COLON) + break; + if (pattern[j].type () == ACToken::TOK_COLON) + has_base_intro = true; + else if (pattern[j].type () == ACToken::TOK_OPEN_CURLY) { + has_member_intro = true; + break; + } + } + + // Generate the base intro. + // TODO: What about replacements in base intros? + // Example: ": public SomeBase" + TU_ClassSlice::SliceBody base_intro; + if (has_base_intro) { + unsigned i = 1; + while (i < pattern.size() && pattern[i].type () != ACToken::TOK_COLON) + ++i; + ++i; // skip ':' + while (i < pattern.size() && + pattern[i].type () != ACToken::TOK_SEMI_COLON && + pattern[i].type () != ACToken::TOK_OPEN_CURLY) { + base_intro.text += ' '; + base_intro.text += token_text (pattern[i]); + if (!base_intro.file.is_valid()) { + base_intro.file = source_unit(pattern[i]); + base_intro.line = token_line_number(pattern[i]); + } + ++i; + } + } + + // Generate the (inline) member intro + TU_ClassSlice::SliceBody member_intro; + if (has_member_intro) { + unsigned i = 0; + while (pattern[i].type () != ACToken::TOK_OPEN_CURLY) + ++i; + ++i; + member_intro.file = source_unit(pattern[i]); + member_intro.line = token_line_number(pattern[i]); + unsigned line = member_intro.line; + int level = 1; + while (true) { + if (pattern[i].type () == ACToken::TOK_CLOSE_CURLY) { + level--; + if (level == 0) + break; + } + else if (pattern[i].type () == ACToken::TOK_OPEN_CURLY) + level++; + + // insert whitespace or newline for proper formatting + whitespace (line, pattern[i], member_intro.text); + + // TODO: this is a hack - make sure not to replace too often! + if (level == 1 && pattern[i].type () == ACToken::TOK_ID && + slice->get_name() == pattern[i].text ()) + member_intro.positions.push_back( + std::make_pair(member_intro.text.size(), + TU_ClassSlice::SliceBody::TARGET_NAME)); + else if (pattern[i].type () == ACToken::TOK_ID && + string ("JoinPoint") == pattern[i].text ()) { + member_intro.positions.push_back( + std::make_pair(member_intro.text.size(), + TU_ClassSlice::SliceBody::JP_NAME)); + } + else + member_intro.text += token_text (pattern[i]); + ++i; + } + + // Sort positions so we can easily do the insertions later. + // TODO: Aren't those always sorted anyways? + std::sort(member_intro.positions.begin(), member_intro.positions.end()); + } + + slice->set_tokens (member_intro, base_intro, has_base_intro, has_member_intro); +} +#endif // FRONTEND_CLANG + +void replace_string_in_place (string& subject, const string& search, const string& replace) { + size_t pos = 0; + while ((pos = subject.find(search, pos)) != std::string::npos) { + subject.replace(pos, search.length(), replace); + pos += replace.length(); + } +} + +void Phase1::parse_scope (Scope &scope, string *anon_member_class_copy) { + static string prot_none(""); + static string prot_private("private"); + static string prot_protected("protected"); + static string prot_public("public"); + + Scope *old_scope = _curr_scope; + _curr_scope = &scope; + bool old_in_template = _in_template; + bool in_friend = false; + bool in_slice = false; + bool in_slice_initializer = false; + enum { TD_FLOATING, TD_GOT_ID, TD_GOT_TYPEDEF, TD_GOT_ALL } _td_state = TD_FLOATING; + Scope *class_alias_target = 0; + string *prot = &prot_none; + if (scope.is_class() || scope.is_aspect()) + prot = &prot_private; + else if (scope.is_struct()) + prot = &prot_public; + int advice_no = 0; + int intro_no = 0; + int order_no = 0; + int anon_slice_no = 0; + bool is_anon_class = false; + // Whether the construct we are currently parsing (union, ...) has static/internal + // linkage + bool has_static_linkage = false; + // The static/internal linkage storage class specifier token (necessary, because + // the token may get removed later) + ACToken static_linkage_token; + // Does the current construct creates a variable inside the current scope? (e.g. + // "class { int i; } c;" creates variable c and "union { int i; };" does not + // create a variable) + bool is_creating_variable = false; + ACToken anon_class_def_token; + string anon_class_name; // generated name for anon class + string anon_class_alias; // as in "typedef struct { ... } alias_name;" + ACToken start_token; + + // if we are in the definition of an anonymous class/struct/union it might be + // that we are parsing the definition of an anonymous member. In this case we + // need to create a modified copy of the code and thus start recording here. + if (anon_member_class_copy) + start_recording (); + + ACToken token = curr_token (); + while (token.type () != ACToken::TOK_EOF && + token.type () != ACToken::TOK_CLOSE_CURLY) { + + int tt = token.type (); + // handle sub-scope + if (tt == ACToken::TOK_TEMPLATE) { + // A declaration of a template class or function + token = next_token (); + if (token.type () != ACToken::TOK_EOF && token.type () == ACToken::TOK_LESS) { + skip_template_params(); + token = curr_token(); + _in_template = true; + } + } + else if (tt == ACToken::TOK_ENUM) { // handle C++ 11 enum classes + token = next_token(); + if (token.type () == ACToken::TOK_CLASS) + token = next_token(); // simply skip the class keyword if there is one + } + else if (tt == ACToken::TOK_PUBLIC) { + token = next_token(); + if (token.type () == ACToken::TOK_COLON) + prot = &prot_public; + token = next_token(); + } + else if (tt == ACToken::TOK_PROTECTED) { + token = next_token(); + if (token.type () == ACToken::TOK_COLON) + prot = &prot_protected; + token = next_token(); + } + else if (tt == ACToken::TOK_PRIVATE) { + token = next_token(); + if (token.type () == ACToken::TOK_COLON) + prot = &prot_private; + token = next_token(); + } + else if (scope.is_aspect() && + ((tt == ACToken::TOK_STATIC && + look_ahead ().type () == ACToken::TOK_ID && + scope._name == look_ahead().text ()) || + (tt == ACToken::TOK_ID && scope._name == token.text () && + look_ahead().type () == ACToken::TOK_STATIC))) { + parse_aspectof_function (*prot); + token = next_token (); + } + else if (tt == ACToken::TOK_STATIC) { + // If the scope, we are in, is a namespace, and the current token + // is "static" then the following construct has static/internal + // linkage. + if(scope.is_namespace()) { + int type_of_next_token = look_ahead().type(); + // Ignore functions, normal variables (without a class/... definition inside + // the variable declaration), ... because they are not considered/changed + // during phase1 anyway. This makes resetting has_static_linkage easier. + if (type_of_next_token == ACToken::TOK_CLASS || + type_of_next_token == ACToken::TOK_UNION || + type_of_next_token == ACToken::TOK_STRUCT) { + has_static_linkage = true; + // Remeber the "static" token, because we will maybe remove it later. + static_linkage_token = token; + } + } + token = next_token(); + } + else if (tt == ACToken::TOK_TYPEDEF) { + switch (_td_state) { + case TD_GOT_TYPEDEF: + case TD_GOT_ALL: + err () << sev_error << token.location() + << "'typedef' specifier used twice." << endMessage; + break; + case TD_GOT_ID: + _td_state = TD_GOT_ALL; + break; + case TD_FLOATING: + _td_state = TD_GOT_TYPEDEF; + break; + } + token = next_token(); + } + else if (_td_state == TD_GOT_ALL && tt == ACToken::TOK_ID) { + if (look_ahead(1).type () == ACToken::TOK_SEMI_COLON) { + if (class_alias_target) { + Element alias; + alias._kind = Element::ELEMENT_CLASS_ALIAS; + alias._jpm_link = 0; + alias._name = token.text(); + alias._referred = class_alias_target; + scope._elements.insert(alias); + } + } + token = next_token(); + } + else if (tt == ACToken::TOK_FRIEND) { + in_friend = true; + token = next_token(); + } + else if (tt == ACToken::TOK_POINTCUT) { + parse_pointcut_def (scope); + token = next_token (); + } + else if (tt == ACToken::TOK_ATTRDECL && _conf.attributes()) { +#ifdef FRONTEND_CLANG + parse_attribute_decl(scope); +#else + err() << sev_warning << "attributes are not supported for puma-frontend, yet! Use clang-frontend instead!" << endMessage; +#endif + token = next_token(); + } + else if (scope.is_namespace() && tt == ACToken::TOK_USING) { + parse_using_directive (scope); + token = next_token (); + } + else if (tt == ACToken::TOK_ADVICE) { + parse_advice_def (scope, advice_no, intro_no, order_no, anon_slice_no, *prot); + token = next_token (); + } + else if (tt == ACToken::TOK_SLICE) { + in_slice = true; + start_token = token; + start_recording (); + token = next_token (); + } + else if (!_in_template && !in_friend && + (tt == ACToken::TOK_NAMESPACE || + (tt == ACToken::TOK_ASPECT) || + tt == ACToken::TOK_CLASS || + tt == ACToken::TOK_UNION || + tt == ACToken::TOK_STRUCT)) { + bool is_struct = (tt == ACToken::TOK_STRUCT); + bool is_class = (tt == ACToken::TOK_CLASS); + bool is_aspect = (tt == ACToken::TOK_ASPECT); + bool is_union = (tt == ACToken::TOK_UNION); + anon_class_alias.clear(); + string pre_attr; + // A namespace sub-scope? + ACToken start = token; + if (is_aspect) + _code_weaver.transform_aspect(start); + token = next_token (); + + // skip __attribute(...) + if (is_attribute_token(token, look_ahead())) { + // stop recording + if (anon_member_class_copy) { +#ifdef FRONTEND_PUMA + Puma::Unit *rec = stop_recording (); + string result = recording_to_string (rec); + delete rec; +#else + ACPreprocessor::TokenVector rec = stop_recording (); + string result = recording_to_string (rec); +#endif + *anon_member_class_copy += result; + } + start_recording(); + skip_attributes(false); +#ifdef FRONTEND_PUMA + Puma::Unit *rec = stop_recording (); + pre_attr = recording_to_string (rec); + delete rec; +#else + ACPreprocessor::TokenVector rec = stop_recording (); + pre_attr = recording_to_string (rec); +#endif + if (anon_member_class_copy) { + *anon_member_class_copy += pre_attr; + start_recording(); + } + token = next_token(); + } + + bool root_qualified, contains_template_id; + vector names; + parse_qual_name (names, root_qualified, contains_template_id); + token = curr_token (); + bool is_qualified = (root_qualified || names.size () > 1); + string name; + if (names.size () > 0) + name = names[names.size () - 1]; + else { + if (tt == ACToken::TOK_NAMESPACE) { + name = ""; + } + else if (is_struct || is_class || is_union || is_aspect) { + is_anon_class = false; + ostringstream name_str; + if (in_slice) { + name_str << ""; + anon_slice_no++; + err () << sev_error << start.location() + << "Anonymous slice definition only allowed in advice." << endMessage; + } + else { + if (_curr_scope->_name == "::") + name_str << "__ac_anon" << _anon_class_no; + else { + if (_curr_scope->_name.substr (0, 9) != "__ac_anon") + name_str << "__ac_anon"; + // "" + name_str << (_curr_scope->_name == "" ? "_unnamed_" : _curr_scope->_name) + << "_" << _anon_class_no; + } + _anon_class_no++; + if (is_aspect) + err () << sev_error << start.location() + << "Anonymous aspects are not allowed." << endMessage; + else { + if (is_in_project(start)) { + is_anon_class = true; + anon_class_def_token = token; + anon_class_name = name_str.str (); + } + } + } + name = name_str.str (); + } + } + Node *found_scope = 0; + if (is_qualified) + found_scope = lookup_name(scope, root_qualified, names); + Scope *qual_scope = lookup_scope(scope, root_qualified, names); + // TODO: handle other cases here (errors!) + + // check if this scope belongs to our project + bool skip = (is_qualified && !found_scope && in_slice); + bool in_model = true; + bool is_declaration = (token.type () == ACToken::TOK_SEMI_COLON); + Scope *inserted_scope = 0; + if (!skip && (token.type () == ACToken::TOK_OPEN_CURLY || token.type () == ACToken::TOK_COLON || + is_declaration)) { + if (!is_in_project(start) || !is_visible_scope(scope, name) || + !scope._jpm_link || name.substr(0,6) == "_jpm_link : scope._jpm_link, name, is_struct); + else + new_scope._jpm_link = (in_model ? + _jpm.register_class1 (qual_scope ? qual_scope->_jpm_link : scope._jpm_link, name) : 0); + } + else if (start.type () == ACToken::TOK_UNION) { + new_scope._kind = Scope::SCOPE_UNION; + new_scope._jpm_link = 0; + } + pair::const_iterator, bool> res = + new_scope._parent_scope->_sub_scopes.insert (new_scope); + inserted_scope = &(Scope&)*res.first; + // A namespace first introduced as external, might now become part of the project. + // Therefore, add the project model link here. + if (!inserted_scope->_jpm_link && new_scope._jpm_link) + inserted_scope->_jpm_link = new_scope._jpm_link; + } + + // handle class alias typedef state machine + if (!qual_scope && inserted_scope && + (_td_state == TD_FLOATING || _td_state == TD_GOT_TYPEDEF)) { + _td_state = (_td_state == TD_FLOATING ? TD_GOT_ID : TD_GOT_ALL); + class_alias_target = inserted_scope; + } + + // stop recording after the classname + if (anon_member_class_copy && + (token.type () == ACToken::TOK_COLON || token.type () == ACToken::TOK_OPEN_CURLY)) { +#ifdef FRONTEND_PUMA + Puma::Unit *rec = stop_recording (); + string result = recording_to_string (rec); + delete rec; +#else + ACPreprocessor::TokenVector rec = stop_recording (); + string result = recording_to_string (rec); +#endif + *anon_member_class_copy += result; + } + + bool is_definition = false; + if (token.type () != ACToken::TOK_EOF && token.type () == ACToken::TOK_COLON) { + is_definition = true; + if (in_slice) { + // consume tokens until we find '{' or syntax error + do { + token = next_token(); + } while (token.type () != ACToken::TOK_EOF && token.type () != ACToken::TOK_OPEN_CURLY + && token.type () != ACToken::TOK_SEMI_COLON); + } + else if (inserted_scope && + (inserted_scope->is_class_or_struct() || inserted_scope->is_aspect())) { + // list of base classes + parse_base_clause (*inserted_scope); + if (in_model) register_base_classes (*inserted_scope); + token = curr_token(); + } + } + + if (token.type () != ACToken::TOK_EOF && token.type () == ACToken::TOK_OPEN_CURLY) { + is_definition = true; + if (in_slice) { + skip_curly_block (); + token = curr_token (); + } + else { + // parse the nested scope + next_token (); + if (is_anon_class) { + string nested_anon_member_class_copy; + parse_scope (*inserted_scope, &nested_anon_member_class_copy); + + if (curr_token().type () != ACToken::TOK_EOF && (is_struct || is_class || is_union)) { + // skip __attribute(...) + string post_attr; + if (is_gnu_attribute_token(look_ahead ())) { + next_token (); + start_recording (); // record attribute while being lexed + skip_gnu_attributes(false); +#ifdef FRONTEND_PUMA + Puma::Unit *rec = stop_recording (); + post_attr = recording_to_string (rec); + delete rec; +#else + ACPreprocessor::TokenVector rec = stop_recording (); + post_attr = recording_to_string (rec); +#endif + } + + // Check whether we have found the definition of an unnamed strcut/union field, such as in + // class C { struct { int i; }; } c; <-- here 'i' is visible in 'C'! + // => check whether ';' follows '}' ... + if (look_ahead().type () == ACToken::TOK_SEMI_COLON) { + if (anon_member_class_copy) + *anon_member_class_copy += nested_anon_member_class_copy; + + // Transform the code: insert a copy of the original anonymous class behind the + // de-anonymized class + string tag; + if (is_struct) + tag = "struct"; + else if (is_union) + tag = "union"; + else if (is_class) + tag = "class"; + + string storage_class_specifier; + if(has_static_linkage) { + storage_class_specifier = "static "; + } + + replace_string_in_place (nested_anon_member_class_copy, + full_anon_class_name(scope) + "::", ""); + // Insert copy: + _code_weaver.transform_anon_member_class (look_ahead(), + storage_class_specifier + tag + pre_attr + + " { " + nested_anon_member_class_copy + " }" + + post_attr + ";"); + } + else { + // Check for an id and a semicolon +// cout << _td_state << ":" << token_text(look_ahead()) << ":" << token_text(look_ahead(2)) << endl; + // TODO: handle more (exotic) cases + if (look_ahead().type() == ACToken::TOK_ID && + look_ahead(2).type() == ACToken::TOK_SEMI_COLON) { + if(_td_state == TD_GOT_ALL) { + // Found definition of class alias + anon_class_alias = look_ahead().text(); + } + else { + // Found variable creation + is_creating_variable = true; + } + } + if (anon_member_class_copy) { + anon_member_class_copy->resize (anon_member_class_copy->size () - 1); + *anon_member_class_copy += full_anon_class_name(*inserted_scope); + next_token (); + } + } + } + } + else + parse_scope (*inserted_scope); + // and start recording again + if (anon_member_class_copy) + start_recording (); + } + if (!skip && (in_model || in_slice)) { + if (curr_token ().type() == ACToken::TOK_EOF) + err () << sev_error << start.location() + << "Scope '" << inserted_scope->_name.c_str() << "' not closed properly" << endMessage; + else { + if (inserted_scope->_jpm_link) + _jpm.add_source_loc(inserted_scope->_jpm_link, start, curr_token (), + (inserted_scope->is_namespace() ? SLK_NONE : SLK_DEF)); + } + } + } + else { + if (inserted_scope && inserted_scope->_jpm_link && (in_model || in_slice)) { + _jpm.add_source_loc(inserted_scope->_jpm_link, start, curr_token (), SLK_DECL); + } + } + + if (!skip && is_definition && qual_scope && !found_scope) + err () << sev_error << start.location() + << "Definition of undeclared scope '" << name.c_str() << "'." << endMessage; + +#ifdef FRONTEND_PUMA + Puma::Unit *rec = 0; +#else + ACPreprocessor::TokenVector rec; +#endif + if (in_slice) { + in_slice = false; + rec = stop_recording (); + } + if (inserted_scope && inserted_scope->_is_slice) { + if (is_definition) { + TU_ClassSlice *cs = (TU_ClassSlice*)inserted_scope->_jpm_link; + cs->slice_unit(source_unit(start)); +#ifdef FRONTEND_PUMA + if (cs->get_tokens ()) + cout << "tokens OVERWRITTEN" << endl; + cs->set_tokens(rec); +#else + if (!cs->get_tokens ().text.empty()) + cout << "tokens OVERWRITTEN" << endl; + set_slice_tokens(cs, rec); +#endif + } + _code_weaver.transform_delete(start_token, curr_token ()); + } +#ifdef FRONTEND_PUMA + else if (rec) { +#else + else if (!rec.empty ()) { +#endif + handle_slice_member(scope, rec, start_token, curr_token()); + } + token = next_token (); + } + else if (in_slice && tt == ACToken::TOK_ASSIGN) { + in_slice_initializer = true; + token = next_token (); + } + else if (tt == ACToken::TOK_OPEN_CURLY) { + skip_curly_block (false); + if (in_slice && !in_slice_initializer) { + in_slice = false; +#ifdef FRONTEND_PUMA + Puma::Unit *rec = stop_recording (); + if (rec) +#else + ACPreprocessor::TokenVector rec = stop_recording (); + if (!rec.empty ()) +#endif + handle_slice_member(scope, rec, start_token, curr_token()); + } + _in_template = old_in_template; + in_friend = false; + token = next_token (); + } + else if (tt == ACToken::TOK_SEMI_COLON) { + if (in_slice) { +#ifdef FRONTEND_PUMA + Puma::Unit *rec = stop_recording (); + if (rec) +#else + ACPreprocessor::TokenVector rec = stop_recording (); + if (!rec.empty ()) +#endif + handle_slice_member(scope, rec, start_token, curr_token()); + in_slice = false; + in_slice_initializer = false; + } + _in_template = old_in_template; + token = next_token (); + in_friend = false; + if (is_anon_class) { + // We finished parsing an anonymous class/union/struct. De-anonymize it: + if (anon_class_alias.empty()) + _code_weaver.transform_anon_class(anon_class_def_token, anon_class_name); + else + _code_weaver.transform_anon_class(anon_class_def_token, anon_class_alias); + anon_class_alias.clear(); + + if(has_static_linkage && !is_creating_variable) { + // Because the anonymous class/union/struct was de-anonymized (by adding a + // name), and because there is no variable created, the static/internal linkage + // specifier is no longer allowed. Remove it: + _code_weaver.kill(_code_weaver.weave_pos(static_linkage_token, WeavePos::WP_BEFORE), + _code_weaver.weave_pos(static_linkage_token, WeavePos::WP_AFTER)); + } + } + // Finished parsing of construct. Reset state (because beginning with the next token we + // will look at the next construct inside the current scope): + is_anon_class = false; + has_static_linkage = false; + is_creating_variable = false; + _td_state = TD_FLOATING; + } + else if (tt == ACToken::TOK_COLON_COLON || tt == ACToken::TOK_ID) { + bool root_qualified, contains_template_id; + vector names; + parse_qual_name (names, root_qualified, contains_template_id); + token = curr_token(); + if (_td_state == TD_GOT_ID || _td_state == TD_GOT_ALL || + contains_template_id || names.size () == 0) + _td_state = TD_FLOATING; + else { + Node *found = lookup_name(scope, root_qualified, names); + if (found && (found->is_class_or_struct() || found->is_aspect())) { + _td_state = (_td_state == TD_FLOATING ? TD_GOT_ID : TD_GOT_ALL); + class_alias_target = (Scope*)found; + } + else + _td_state = TD_FLOATING; + } + } + else { + if (_td_state != TD_FLOATING && tt != ACToken::TOK_CONST && tt != ACToken::TOK_VOLATILE) + _td_state = TD_FLOATING; + token = next_token (); + } + } + + if (anon_member_class_copy) { +#ifdef FRONTEND_PUMA + Puma::Unit *rec = stop_recording (); + string result = recording_to_string (rec); + delete rec; +#else + ACPreprocessor::TokenVector rec = stop_recording (); + string result = recording_to_string (rec); +#endif + result.resize (result.size () - 1); // delete trailing '}' + *anon_member_class_copy += result; + + } + _curr_scope = old_scope; +} + +#ifdef FRONTEND_CLANG +string Phase1::recording_to_string (const ACPreprocessor::TokenVector &vec) { + string result; + if (vec.size () > 0) { + unsigned last_line = token_line_number(vec[0]); + for (unsigned i = 0; i < vec.size(); i++) { + unsigned line = token_line_number(vec[i]); + bool new_line = false; + while (line > last_line) { + result += "\n"; + last_line++; + new_line = true; + } + if (!new_line) result += " "; + result += token_text (vec[i]); + } + } + return result; +} +#else +string Phase1::recording_to_string (Puma::Unit *rec) { + string result; + Token *curr = (Token*)rec->first (); + if (curr) { + int last_line = curr->location ().line (); + while (curr) { + int line = curr->location ().line (); + bool new_line = false; + while (line > last_line) { + result += "\n"; + last_line++; + new_line = true; + } + if (!new_line) result += " "; + result += curr->text (); + curr = (Token*)rec->next (curr); + } + } + return result; +} +#endif + +#ifdef FRONTEND_CLANG +// Create a SliceBody structure out of the tokens in pattern. +TU_ClassSlice::SliceBody +Phase1::format_non_inline_member (ACPreprocessor::TokenVector &pattern, + const std::string &name) { + TU_ClassSlice::SliceBody res; + + int name_tokens = 0; + unsigned line = token_line_number(pattern[0]); + res.line = line; + res.file = source_unit(pattern[0]); + // skip 'slice' keyword + for (unsigned i = 1; i < pattern.size(); ) { + ACToken token = pattern[i]; + unsigned next = i+1; + if (name_tokens == 0 && next < pattern.size() && + pattern[next].type() == ACToken::TOK_INVALID) { + name_tokens = 1; + next = i+2; + } + else if (name_tokens > 0 && token.type() == ACToken::TOK_INVALID) { + if (res.text.size () > 0) + res.text += ' '; // don't change the line number here + res.positions.push_back(std::make_pair(res.text.size(), + TU_ClassSlice::SliceBody::TARGET_QUAL_NAME)); + name_tokens = 0; + if (next < pattern.size() && pattern[next].type () == ACToken::TOK_COLON_COLON) { + token = pattern[next]; + ++next; + res.text += token_text (token); + if (next < pattern.size() && pattern[next].type () == ACToken::TOK_TILDE) { + token = pattern[next]; + ++next; + res.text += token_text (token); + } + if (next < pattern.size() && pattern[next].type () == ACToken::TOK_ID) { + token = pattern[next]; + ++next; + if (name == token.text()) { + res.positions.push_back(std::make_pair(res.text.size(), + TU_ClassSlice::SliceBody::TARGET_NAME)); + } + else + res.text += token_text (token); + } + } + } + else { + if (name_tokens == 0) { + // insert whitespace or newline for proper formatting + whitespace (line, token, res.text); + if (token.type () == ACToken::TOK_ID && + string ("JoinPoint") == token.text ()) { + res.positions.push_back(std::make_pair(res.text.size(), + TU_ClassSlice::SliceBody::JP_NAME)); + } + else { + res.text += token_text (token); + } + } + else + name_tokens++; + } + i = next; + } + res.text += "\n"; + + // Sort positions so we can easily do the insertions later. + // TODO: Aren't those always sorted anyways? + std::sort(res.positions.begin(), res.positions.end()); + return res; +} + +// insert whitespace or newline for proper formatting +void Phase1::whitespace (unsigned &line, const ACToken &token, string &str) { + unsigned new_line = token_line_number(token); + if (!token.is_macro_generated () && line != new_line) { + if (new_line > line) + str.append(new_line - line, '\n'); + line = new_line; + } + else { + if (str.size () > 0) + str += ' '; + } +} +#endif // FRONTEND_CLANG + +#ifdef FRONTEND_PUMA + void Phase1::handle_slice_member (Scope &scope, Puma::Unit *rec, ACToken from, ACToken to) { +#else + void Phase1::handle_slice_member (Scope &scope, ACPreprocessor::TokenVector &rec, ACToken from, ACToken to) { +#endif + Scope *slice_scope = find_slice(scope, rec); + if (slice_scope && slice_scope->_jpm_link) { + TU_ClassSlice *s = (TU_ClassSlice*)slice_scope->_jpm_link; + s->non_inline_members().push_back ( +#ifdef FRONTEND_PUMA + rec +#else + format_non_inline_member (rec, s->get_name ()) +#endif + ); + s->non_inline_member_units().push_back (source_unit(from)); + } + else { + err () << sev_error << from.location() + << "Slice member definition cannot be associated with slice definition" << endMessage; + } + _code_weaver.transform_delete(from, to); +} + +void Phase1::parse_aspectof_function (const string &prot) { + ACToken start = curr_token (); + next_token (); + next_token (); + if (curr_token ().type() != ACToken::TOK_MUL) + return; + next_token (); + if (curr_token ().type() != ACToken::TOK_ID) + return; + ACToken name = curr_token (); + string text = name.text (); + if (text != "aspectOf" && text != "aspectof") + return; + ACToken arg_begin = next_token (); + skip_round_block(false); + next_token (); + ACToken body_begin = curr_token (); + AdviceCodeContext context = ACC_NONE; + CodeWeaver::TypeUse uses_type; + parse_advice_body( context, ACToken::TOK_OPEN_CURLY, ACToken::TOK_CLOSE_CURLY, uses_type ); + ACToken body_end = curr_token (); + _code_weaver.transform_aspectof( context, uses_type, start, name, arg_begin, body_begin, body_end, prot ); +} + +void Phase1::parse_using_directive(Scope &scope) { + ACToken token = next_token (); + if (token.type() != ACToken::TOK_NAMESPACE) + return; + token = next_token (); + ACToken name_start = token; + bool root_qualified, contains_template_id; + vector names; + parse_qual_name (names, root_qualified, contains_template_id); + if (names.size () == 0) { + err() << sev_error << name_start.location() + << "Invalid name in 'using directive'." << endMessage; + return; + } + string name = names[names.size () - 1]; + Node *found_scope = lookup_name(scope, root_qualified, names); + token = curr_token (); + if (token.type () != ACToken::TOK_SEMI_COLON) { + err() << sev_error << token.location() + << "Expected ';' after namespace name in 'using directive." << endMessage; + return; + } + if (!found_scope || !found_scope->is_namespace()) { + err() << sev_error << name_start.location() + << "'" << name.c_str() << "' is not a known namespace." << endMessage; + return; + } + scope._search_scopes.push_back ((Scope*)found_scope); +} + +void Phase1::parse_pointcut_def (Scope &scope) { + ACToken start = curr_token (); + ACToken token = next_token (); + bool is_virtual = false; // neither virtual nor pure virtual + ACToken virtual_token; + if (token.type () == ACToken::TOK_VIRTUAL) { + is_virtual = true; // either virtual or pure virtual + virtual_token = token; + token = next_token(); + } + if (!(token.type () == ACToken::TOK_ID)) + return; // TODO: handle syntax error in pointcut definition + string name = token.text (); + token = next_token (); + if (!(token.type () == ACToken::TOK_OPEN_ROUND)) + return; // TODO: handle syntax error in pointcut definition + skip_round_block(); + token = curr_token(); + if (!(token.type () == ACToken::TOK_ASSIGN)) + return; // TODO: handle syntax error in pointcut definition + ACToken assignment_token = token; + token = next_token(); + string expr; + ACToken pct_end_token = token; + while (token.type () != ACToken::TOK_EOF && token.type () != ACToken::TOK_SEMI_COLON) { +#ifdef FRONTEND_PUMA + expr += token.text (); +#else + expr += token_text (token); +#endif + pct_end_token = token; + token = next_token(); + } + // check whether the definition is semantically correct + if (expr == "0" && !is_virtual) { + err () << sev_error << start.location() + << "Pure virtual pointcut defined without 'virtual' keyword." << endMessage; + is_virtual = true; + } + // register the scope of the named pointcut; should normally not be necessary + ACM_Name *parent = scope._jpm_link; + if (!parent) + parent = register_scope(scope); + // register the named pointcut itself + TU_Pointcut *pct = (TU_Pointcut*)_jpm.register_pointcut1 (parent, name, is_virtual, expr); + if (!pct) { + err () << sev_error << start.location() + << "Pointcut '" << name.c_str() << "' already defined." << endMessage; + return; + } + PointCutExpr *pce = 0; + if (expr != "0") + pce = create_pct_expr_tree(expr, parent, start); + pct->get_parsed_expr().set (pce); +#ifdef FRONTEND_PUMA + pct->set_location(start.location()); +#else + pct->set_location(clang::FullSourceLoc (start.location(), err().get_source_manager ())); +#endif + _jpm.add_source_loc(pct, start, curr_token ()); + Element pct_elem; + pct_elem._kind = Element::ELEMENT_POINTCUT; + pct_elem._name = name; + pct_elem._jpm_link = pct; + scope._elements.insert(pct_elem); + // finally transform the named pointcut definition into a function declaration (for phase 2) + _code_weaver.transform_pointcut_def(start, virtual_token, assignment_token, pct_end_token); +} + +#ifdef FRONTEND_CLANG +void Phase1::parse_attribute_decl(Scope &scope) +{ + ACToken start = curr_token (); + + if(!scope.is_namespace() && !scope.is_class() && !scope.is_aspect()) { + err() << sev_error << curr_token().location() + << "attribute declaration not allowed in this scope - daclare in namespace or class" << endMessage; + return; + } + + ACToken nameToken = next_token (); + + if (nameToken.type () != ACToken::TOK_ID) { + err() << sev_error << curr_token().location() + << "attribute keyword used without identifier." << endMessage; + return; + } + + string name = nameToken.text(); + + ACToken token = next_token(); + + if (token.type() != ACToken::TOK_OPEN_ROUND) { + err() << sev_error << curr_token().location() + << "expected '(' after attribute-identifier" << endMessage; + return; + } + + token = next_token(); + start_recording(); + + int openBracket = 1; + + while (true) { + if(token.type() == ACToken::TOK_OPEN_ROUND) + openBracket++; + else if(token.type() == ACToken::TOK_CLOSE_ROUND) { + openBracket--; + if(openBracket == 0) + break; + } + else if(token.type() == ACToken::TOK_EOF) { + err() << sev_error << curr_token().location() + << "Missing ';' after attribute-identifier" << endMessage; + return; + } + + token = next_token(); + } + +#ifdef FRONTEND_PUMA + Puma::Unit *rec = stop_recording (); + string attrParams = recording_to_string (rec); + rec->remove(rec->last()); +#else + ACPreprocessor::TokenVector paramTokens = stop_recording (); + paramTokens.pop_back(); + string attrParams = recording_to_string(paramTokens); +#endif + + //check if any params are declared for attribute - this is not allowed in first stage of implementation! + if(!attrParams.empty()) { + err() << sev_error << curr_token().location() << "attributes with parameters are not supported, yet" << endMessage; + } + + token = next_token(); + + if (token.type() != ACToken::TOK_SEMI_COLON) { + err() << sev_error << curr_token().location() + << "expected ';' after attribute-declaration" << endMessage; + return; + } + + ACM_Namespace *parent = (ACM_Namespace*) scope._jpm_link; + if (!parent) + parent = (ACM_Namespace*) register_scope(scope); + + TU_Attribute *attr = _jpm.register_attrdecl1(parent, name); + + if(attr == nullptr) { + // err() << sev_error << curr_token().location() + // << "redeclaration of attribute '" << name.c_str() << "'" << endMessage; + + //TODO:check whether Arguments fit! + return; + } + + attr->setParamStr(attrParams); + +#ifdef FRONTEND_PUMA + attr->set_location(start.location()); +#else + attr->set_location(clang::FullSourceLoc (start.location(), err().get_source_manager ())); +#endif + + _jpm.add_source_loc(attr, start, curr_token ()); + Element attr_elem; + attr_elem._kind = Element::ELEMENT_CXX11Attr; + attr_elem._name = name; + attr_elem._jpm_link = attr; + scope._elements.insert(attr_elem); + + // finally transform the attribute definition for phase 2: + // for now we delete it + _code_weaver.transform_delete(start, token); + + // _code_weaver.transform_attribute_def(start, token, attr->get_name(), attr->getParamStr()); +} +#endif //FRONTEND_CLANG + +void Phase1::parse_advice_def (Scope &scope, int &advice_no, int &intro_no, int &order_no, int &anon_slice_no, + const string &prot) { + if (!scope.is_aspect()) { + err() << sev_error << curr_token ().location() + << "'advice' keyword used outside an aspect." << endMessage; + return; + } + + ACToken start = curr_token (); + ACToken token = next_token (); + ACToken pct_start = token, pct_end = token; + string expr; + while (token.type () != ACToken::TOK_EOF && token.type () != ACToken::TOK_COLON) { + // TODO: handle errors, e.g. ';' or '}' token +#ifdef FRONTEND_PUMA + expr += token.text (); +#else + expr += token_text(token); +#endif + pct_end = token; + token = next_token(); + } + // create an anonymous pointcut object, ignore arguments for now + TU_Pointcut *pct = (TU_Pointcut*)_jpm.register_pointcut1(0, "%anon", false, expr); + pct->get_parsed_expr().set (create_pct_expr_tree(expr, scope._jpm_link, pct_start)); +#ifdef FRONTEND_PUMA + pct->set_location(pct_start.location()); +#else + pct->set_location(clang::FullSourceLoc (pct_start.location(), err().get_source_manager ())); +#endif + _jpm.add_source_loc(pct, pct_start, pct_end); + +// cout << "advice on " << expr << endl; + token = next_token (); + if (token.type() == ACToken::TOK_EOF) return; + string text = token.text (); + if (token.type () == ACToken::TOK_ID && + (text == "before" || text == "after" || text == "around")) { + ACToken advice_kind_token = token; + next_token (); + ACToken arg_begin = curr_token(); + ACToken next = look_ahead (); + if (next.type () == ACToken::TOK_EOF) return; // TODO: error handling + bool has_args = (next.type() != ACToken::TOK_CLOSE_ROUND); + skip_round_block(false); + next_token (); + ACToken body_begin = curr_token (); + AdviceCodeContext context = ACC_NONE; + CodeWeaver::TypeUse uses_type; + parse_advice_body (context, ACToken::TOK_OPEN_CURLY, ACToken::TOK_CLOSE_CURLY, uses_type ); + if (has_args) + context = (AdviceCodeContext)(context | ACC_VARS); + TU_AdviceCode *new_elem = _jpm.newAdviceCode(); + ((ACM_Aspect*)scope._jpm_link)->get_advices().insert(new_elem); + new_elem->set_kind(text == "before" ? ACT_BEFORE: text == "after" ? ACT_AFTER:ACT_AROUND); + new_elem->set_pointcut(pct); + new_elem->set_context(context); + new_elem->set_lid(advice_no); + ACToken body_end = curr_token(); + _jpm.add_source_loc(new_elem, start, body_end); + _code_weaver.transform_delete(start, advice_kind_token); + _code_weaver.transform_advice_code( advice_no, text, context, has_args, uses_type, arg_begin, body_begin, body_end, prot ); + advice_no++; // increment number of code advice block per aspect + } + else if (token.type () == ACToken::TOK_ID && text == "order") { + ACToken order_start = token; + token = next_token (); + if (token.type() != ACToken::TOK_OPEN_ROUND) { + err() << sev_error << order_start.location () + << "Syntax error in order advice, expected '(' after 'order'" << endMessage; + return; + } + TU_Order *order = (TU_Order*)_jpm.newOrder(); + order->set_pointcut(pct); + order->set_lid(advice_no); +//#ifdef FRONTEND_PUMA +// order->tree (0); +//#endif + while (true) { + token = next_token (); + ACToken pct_start = token, pct_end = token; + string expr; + int bracket_depth = 0; + while (token.type () != ACToken::TOK_EOF && token.type () != ACToken::TOK_COMMA && + !(token.type() == ACToken::TOK_CLOSE_ROUND && bracket_depth == 0)) { + // TODO: handle errors, e.g. ';' or '}' token + if (token.type () == ACToken::TOK_OPEN_ROUND) + bracket_depth++; + else if (token.type () == ACToken::TOK_CLOSE_ROUND) + bracket_depth--; +#ifdef FRONTEND_PUMA + expr += token.text (); +#else + expr += token_text (token); +#endif + pct_end = token; + token = next_token(); + } + TU_Pointcut *pct = (TU_Pointcut*)_jpm.register_pointcut1(0, "%anon", false, expr); + pct->get_parsed_expr().set (create_pct_expr_tree(expr, scope._jpm_link, pct_start)); +#ifdef FRONTEND_PUMA + pct->set_location(pct_start.location()); +#else + pct->set_location(clang::FullSourceLoc (pct_start.location(), err().get_source_manager ())); +#endif + _jpm.add_source_loc (pct, pct_start, pct_end); + order->get_aspect_exprs().insert(pct); + if (token.type () == ACToken::TOK_CLOSE_ROUND) + break; + } + token = next_token(); + if (token.type () != ACToken::TOK_SEMI_COLON) + return; + ((ACM_Aspect*)scope._jpm_link)->get_orders().insert(order); + _jpm.add_source_loc(order, start, token); + _code_weaver.transform_delete(start, token); + order_no++; // increment number of order advice per aspect + } + else if (token.type () == ACToken::TOK_SLICE) { + ACToken slice_start = token; + TU_ClassSlice *slice_obj = 0; + ACToken next = look_ahead (); + if (token.type () == ACToken::TOK_EOF) return; // TODO: error handling + TU_Introduction *intro = _jpm.newIntroduction(); + intro->set_pointcut(pct); + intro->set_lid(intro_no); + intro_no++; + if (next.type () == ACToken::TOK_CLASS || next.type () == ACToken::TOK_STRUCT) { + bool is_struct = (next.type () == ACToken::TOK_STRUCT); + start_recording (); + token = next_token (); + token = next_token (); + bool root_qualified, contains_template_id; + vector names; + parse_qual_name (names, root_qualified, contains_template_id); + token = curr_token (); + Node *found_scope = 0; + Scope *qual_scope = 0; + bool is_qualified = (root_qualified || names.size () > 1); + if (is_qualified) { + found_scope = lookup_name(scope, root_qualified, names); + qual_scope = lookup_scope(scope, root_qualified, names); + } + string name; + if (names.size () > 0) { + name = names[names.size () - 1]; + } + else { + ostringstream name_str; + name_str << ""; + name = name_str.str (); + anon_slice_no++; + } + if (token.type () == ACToken::TOK_SEMI_COLON) { +#ifdef FRONTEND_PUMA + Puma::Unit *rec = stop_recording (); + delete rec; +#else + ACPreprocessor::TokenVector rec = stop_recording (); +#endif + slice_obj = (TU_ClassSlice*)_jpm.register_class_slice( + (qual_scope ? qual_scope->_jpm_link : scope._jpm_link), name, is_struct); + _jpm.add_source_loc(slice_obj, slice_start, curr_token(), SLK_DECL); + } + else { + while (token.type () != ACToken::TOK_EOF && token.type () != ACToken::TOK_SEMI_COLON) { + if (token.type () == ACToken::TOK_OPEN_CURLY) { + skip_curly_block (false); + if (look_ahead(1).type() != ACToken::TOK_SEMI_COLON) + err() << sev_error << curr_token().location() + << "Semicolon after class slice introduction missing." << endMessage; + break; + } + token = next_token (); + } +#ifdef FRONTEND_PUMA + Puma::Unit *rec = stop_recording (); +#else + ACPreprocessor::TokenVector rec = stop_recording (); +#endif + if (token.type () == ACToken::TOK_EOF) return; // TODO: error handling + if (qual_scope && !found_scope) { + err () << sev_warning << slice_start.location() + << "Definition of undeclared slice" << endMessage; + } + slice_obj = (TU_ClassSlice*)_jpm.register_class_slice(qual_scope ? qual_scope->_jpm_link : scope._jpm_link, name, is_struct); + slice_obj->slice_unit(source_unit(slice_start)); + _jpm.add_source_loc(slice_obj, slice_start, curr_token()); +#ifdef FRONTEND_PUMA + if (slice_obj->get_tokens ()) +#else + if (!slice_obj->get_tokens ().text.empty()) +#endif + err() << sev_error << slice_start.location() + << "Slice '" << name.c_str () << "' was already defined." << endMessage; +#ifdef FRONTEND_PUMA + slice_obj->set_tokens (rec); +#else + set_slice_tokens(slice_obj, rec); +#endif + } + // create new scope object + Scope new_scope; + new_scope._name = name; + new_scope._is_slice = true; + new_scope._parent_scope = (qual_scope ? qual_scope : &scope); + new_scope._kind = (is_struct ? Scope::SCOPE_STRUCT : Scope::SCOPE_CLASS); + new_scope._jpm_link = slice_obj; + new_scope._parent_scope->_sub_scopes.insert (new_scope); + } + else { + token = next_token (); + ACToken name_start = token; + bool root_qualified, contains_template_id; + vector names; + parse_qual_name (names, root_qualified, contains_template_id); + if (names.size () == 0) { + err() << sev_error << name_start.location() + << "expected slice name instead of '" +#ifdef FRONTEND_PUMA + << name_start.text() +#else + << token_text(name_start).c_str() +#endif + << "' token." << endMessage; + return; + } + Node *found_scope = lookup_name(scope, root_qualified, names); + // TODO: handle error here + string name (""); + if (names.size () > 0) + name = names[names.size () - 1]; + token = curr_token (); + if (token.type () != ACToken::TOK_SEMI_COLON) return; // TODO: handle syntax errors + if (!found_scope || !found_scope->is_class_or_struct() || + !((Scope*)found_scope)->_is_slice || + !found_scope->_jpm_link) { + err() << sev_error << name_start.location() + << "'" << name.c_str() << "' is not a known class slice." << endMessage; + } + else + slice_obj = (TU_ClassSlice*)found_scope->_jpm_link; + } + if (slice_obj) + intro->set_named_slice(slice_obj); + // intro->intro_info(acii); + ((ACM_Aspect*)scope._jpm_link)->get_intros().insert(intro); + _jpm.add_source_loc(intro, start, curr_token(), SLK_NONE); + _code_weaver.transform_delete(start, curr_token ()); + order_no++; // increment number of order advice per aspect + } + else if (token.type () == ACToken::TOK_ID && text == "baseclass") { + err() << sev_error << token.location() + << "Deprecated introduction syntax used in aspect, use slice instead." << endMessage; + while (token.type () != ACToken::TOK_EOF && token.type () != ACToken::TOK_SEMI_COLON) + token = next_token(); + } + else { + err() << sev_error << token.location() + << "Deprecated introduction syntax used in aspect, use slice instead." << endMessage; + // skip the code; + bool objdecl = false; + while (token.type () != ACToken::TOK_EOF) { + if (token.type () == ACToken::TOK_SEMI_COLON) + break; + if (token.type () == ACToken::TOK_CLASS || + token.type () == ACToken::TOK_STRUCT || + token.type () == ACToken::TOK_UNION || + token.type () == ACToken::TOK_ENUM) { + token = next_token(); + if (token.type () == ACToken::TOK_ID) + token = next_token(); + if (token.type () == ACToken::TOK_OPEN_CURLY) + objdecl = true; + } + if (token.type () == ACToken::TOK_OPEN_ROUND) { + skip_round_block(true); + token = curr_token(); + continue; + } + if (token.type () == ACToken::TOK_OPEN_CURLY) { + skip_curly_block(false); + if (!objdecl) + break; + token = next_token(); + } + if (token.type () == ACToken::TOK_ASSIGN) + objdecl = true; + token = next_token(); + } + } +} + +void Phase1::parse_advice_body( AdviceCodeContext &context, int open, int close, CodeWeaver::TypeUse &uses_type ) { + ACToken current; + int token; + int depth = 0; + + while (curr_token ().type () != ACToken::TOK_EOF) { + current = curr_token (); + token = current.type (); + + if (token == open) + depth++; + else if (token == close) + depth--; + else if (depth > 0 && token == ACToken::TOK_OPEN_ROUND) { + parse_advice_body (context, ACToken::TOK_OPEN_ROUND, ACToken::TOK_CLOSE_ROUND, uses_type ); + next_token (); + continue; + } + + if (depth == 0) + break; + + if (current.type () == ACToken::TOK_ID) { + string text = current.text (); + if (text == "JoinPoint") { + context = (AdviceCodeContext)(context | ACC_TYPE); + ACToken qualname_start = current; + if (look_ahead ().type () == ACToken::TOK_COLON_COLON) { + next_token (); // skip "::" + current = next_token (); + bool have_template_kw = false; + if (current.type () == ACToken::TOK_TEMPLATE) { + current = next_token (); + have_template_kw = true; + } + if (current.type() == ACToken::TOK_ID) { + string name = current.text (); + if( name == "That" || name == "Result" || name == "Target" || + name == "Entity" || name == "MemberPtr" || name == "Array" ) { + ostringstream tn; + Naming::tjp_typedef(tn, name.c_str ()); + _code_weaver.replace (_code_weaver.weave_pos(qualname_start, WeavePos::WP_BEFORE), + _code_weaver.weave_pos(current, WeavePos::WP_AFTER), tn.str ()); + if (name == "That") + uses_type.that = true; + else if (name == "Target") + uses_type.target = true; + else if (name == "Result") + uses_type.result = true; + else if (name == "Entity") + uses_type.entity = true; + else if (name == "MemberPtr") + uses_type.memberptr = true; + else if( name == "Array" ) + uses_type.array = true; + } + else if( name == "Arg" || name == "Dim" ) { + // generate "template" keyword in front of Arg or Dim if the user hasn't provided it + if (!have_template_kw) + _code_weaver.insert (_code_weaver.weave_pos(current, WeavePos::WP_BEFORE), + "template "); + current = next_token (); + skip_template_params(); + current = curr_token (); + if (current.type () == ACToken::TOK_COLON_COLON) { + current = next_token (); + if (current.type () == ACToken::TOK_ID) { + current = next_token (); + if (current.type () != ACToken::TOK_COLON_COLON) + _code_weaver.insert (_code_weaver.weave_pos(qualname_start, WeavePos::WP_BEFORE), + "typename "); + } + } + } + } + } + } + else if (text == "tjp" || text == "thisJoinPoint") { + context = (AdviceCodeContext)(context | ACC_TYPE_OBJ); + if (text == "thisJoinPoint") { + // replace every occurrence of "thisJoinPoint" with "tjp" + _code_weaver.replace(_code_weaver.weave_pos(current, WeavePos::WP_BEFORE), + _code_weaver.weave_pos(current, WeavePos::WP_AFTER), "tjp"); + } + if (look_ahead().type() == ACToken::TOK_PTS) { + next_token (); // skip "->" + current = next_token (); + if (current.type() == ACToken::TOK_ID && + ( string( current.text() ) == "arg" || ( string( current.text() ) == "idx" ) ) && + look_ahead ().type () == ACToken::TOK_LESS) { + _code_weaver.insert(_code_weaver.weave_pos(current, WeavePos::WP_BEFORE), "template "); + } + } + } + } + next_token (); + } +} + +PointCutExpr *Phase1::create_pct_expr_tree(const string &pct, + ACM_Name *scope, ACToken pos) { + // don't call the parser if the input is empty + if (pct == "") { + err() << sev_error << pos.location() + << "Empty pointcut expression." << endMessage; + return 0; + } + PointCutExprParser *pce_parser = PointCutExprParser::instance( _conf ); + try { + return pce_parser->parse(pct, *this); + } + catch (const std::exception &e) { + err () << sev_error << pos.location() + << "Invalid pointcut expression: " << e.what() << "." << endMessage; + } + return 0; +} + +void Phase1::parse_base_clause (Scope &class_scope) { + ACToken token = curr_token(); + int count = 0; + while (token.type () != ACToken::TOK_EOF && + ((count == 0 && token.type () == ACToken::TOK_COLON) || + (count > 0 && token.type () == ACToken::TOK_COMMA))) { + parse_base_spec (class_scope); + token = curr_token(); + count++; + } +} + +void Phase1::parse_qual_name (vector &names, + bool &root_qualified, bool &contains_template_id) { + contains_template_id = false; + root_qualified = (curr_token ().type () == ACToken::TOK_COLON_COLON); + if (root_qualified) next_token(); + + while (curr_token ().type () == ACToken::TOK_ID) { + string name = curr_token().text (); + names.push_back (name); + next_token (); + if (curr_token().type () == ACToken::TOK_LESS) { + contains_template_id = true; + skip_template_params (); + } + if (curr_token().type() == ACToken::TOK_COLON_COLON) + next_token (); + else + break; + } +} + +void Phase1::parse_base_spec (Scope &class_scope) { + // skip ':' or ',' + next_token(); + int count_public = 0, count_private = 0, count_protected = 0, count_virtual = 0; + while (true) { + int token = curr_token().type(); + if (token == ACToken::TOK_PUBLIC) count_public++; + else if (token == ACToken::TOK_PRIVATE) count_private++; + else if (token == ACToken::TOK_PROTECTED) count_protected++; + else if (token == ACToken::TOK_VIRTUAL) count_virtual++; + else if (token == ACToken::TOK_ID || token == ACToken::TOK_COLON_COLON) break; + else return; + next_token (); + } + + bool contains_template_id, root_qualified; + vector names; + parse_qual_name (names, root_qualified, contains_template_id); + +// cout << "base of " << class_scope._name << "(" << root_qualified << " " << contains_template_id << "):"; +// for (vector::const_iterator i = names.begin(); i != names.end(); ++i) +// cout << " " << *i; +// cout << endl; + + if (!contains_template_id && names.size () > 0) { + Node *base = lookup_name (*class_scope._parent_scope, root_qualified, names); + if (base && (base->is_class_or_struct() || base->is_aspect())) + class_scope._search_scopes.push_back ((Scope*)base); + } +} + + +Phase1::Node *Phase1::lookup_name (Scope &scope, bool root_qualified, const vector &names) { + if (root_qualified) + return lookup_name(_root_scope, false, names); + Scope *search_scope = &scope; + while (search_scope) { + set new_visited_scopes; + Node *result = lookup_name_in_scope (*search_scope, names, new_visited_scopes); + if (result) + return result; + search_scope = search_scope->_parent_scope; + } + return 0; +} + +Phase1::Node *Phase1::lookup_name_in_scope (Scope &scope, const vector &names, + std::set &visited_scopes, int depth) { + Node *result = 0; + Scope search; + search._name = names[depth]; + set::iterator i = scope._sub_scopes.find (search); + if (i != scope._sub_scopes.end ()) + result = (Node*)&(*i); + + if (!result) { + Element search_elem; + search_elem._name = names[depth]; + set::iterator i = scope._elements.find (search_elem); + if (i != scope._elements.end ()) { + if (i->_kind == Element::ELEMENT_POINTCUT) + result = (Node*)&(*i); + else if (i->_kind == Element::ELEMENT_CLASS_ALIAS) + result = (*i)._referred; + else if (i->_kind == Element::ELEMENT_CXX11Attr) + result = (Node*)&(*i); + } + } + + // for classes and aspects also lookup the name in base classes/aspects + // for namespaces search in other namespaces mentioned in using directives + if (!result) { + visited_scopes.insert (&scope); + for (std::list::const_iterator i = scope._search_scopes.begin (); + i != scope._search_scopes.end (); ++i) { + // if a search scope was searched alread, skip it silently + if (visited_scopes.find (*i) != visited_scopes.end()) { + continue; + } + // search the search scope + if ((result = lookup_name_in_scope(**i, names, visited_scopes, depth)) != 0) + break; + } + } + if (result && result->_kind == Node::ELEMENT_POINTCUT) + return (depth == (int)(names.size() - 1)) ? result : 0; + // if we found the scope, check the remaining parts of the qualified name + if (result && (depth + 1 < (int)names.size ())) { + set new_visited_scopes; + return lookup_name_in_scope(*(Scope*)result, names, new_visited_scopes, depth + 1); + } + return result; +} + +Phase1::Scope *Phase1::lookup_scope (Scope &scope, bool root_qualified, vector &names) { + if (names.size () <= 1) + return 0; + vector scope_names; + for (unsigned i = 0; i < names.size () - 1; i++) + scope_names.push_back (names[i]); + Node *result = lookup_name (scope, root_qualified, scope_names); + return (result->is_scope() ? (Scope*)result : 0); +} + +ACM_Pointcut *Phase1::lookup_pct_func (bool root_qualified, vector &qual_name) { + Node *lookup_result = lookup_name (*_curr_scope, root_qualified, qual_name); + if (lookup_result && lookup_result->_kind == Element::ELEMENT_POINTCUT && + lookup_result->_jpm_link && + lookup_result->_jpm_link->type_val() == JPT_Pointcut) { + return (ACM_Pointcut*)lookup_result->_jpm_link; + } + return 0; +} + +ACM_Attribute *Phase1::lookup_pct_attr(bool root_qualified, std::vector &qual_name) +{ + Node *lookup_result = lookup_name (*_curr_scope, root_qualified, qual_name); + if (lookup_result && lookup_result->_kind == Element::ELEMENT_CXX11Attr && + lookup_result->_jpm_link && + lookup_result->_jpm_link->type_val() == JPT_Attribute) { + return (ACM_Attribute*)lookup_result->_jpm_link; + } + return 0; +} + +#ifdef FRONTEND_PUMA +Phase1::Scope *Phase1::find_slice (Scope &scope, Puma::Unit *rec) { + enum { EXP_SEP, EXP_ID, FLOATING } state = FLOATING; + vector names; + bool root_qualified = false; + Token *name_start = 0; + Scope *result = 0; + Token *token = rec->first (); + while (token) { + if (state == FLOATING && token->type() == TOK_COLON_COLON) { + root_qualified = true; + name_start = token; + state = EXP_ID; + } + else if (state == EXP_SEP && token->type() == TOK_COLON_COLON) { + state = EXP_ID; + } + else if (state != EXP_SEP && token->type() == TOK_ID) { + if (state == FLOATING) + name_start = token; + names.push_back (token->text ()); + Scope *lookup_result = 0; + Node *lr = lookup_name(scope, root_qualified, names); + if (lr && lr->is_class_or_struct()) + lookup_result = (Scope*)lr; + if (lookup_result) { + if (lookup_result->_is_slice) { + if (result && lookup_result != result) { + // TODO: generate real error message + cout << "ERROR conflicting slice names referenced" << endl; + cout << result->_name << " <--> " << lookup_result->_name << endl; + cout << "SLICE: " << *rec << endl; + cout << "SCOPE: " << scope._name << endl; + scope.dump(); + } + else { + result = lookup_result; + Token *marker = new Token; + rec->insert(name_start, *marker); + marker = new Token; + rec->insert(token, *marker); + // TODO: continue to consume tokens while we are in a qualified name + } + } + } + state = EXP_SEP; + } + else { + state = FLOATING; + names.clear (); + root_qualified = false; + name_start = 0; + if (token->type () == TOK_ID) + continue; // this ID could be the start of the (qualified) slice name + } + token = rec->next (token); + } + return result; +} +#else +Phase1::Scope *Phase1::find_slice (Scope &scope, ACPreprocessor::TokenVector &rec) { + enum { EXP_SEP, EXP_ID, FLOATING } state = FLOATING; + vector names; + bool root_qualified = false; + unsigned name_start = -1U; + Scope *result = 0; + for (unsigned i = 1; i != rec.size(); ) { + ACToken token = rec[i]; + if (state == FLOATING && token.type() == ACToken::TOK_COLON_COLON) { + root_qualified = true; + name_start = i; + state = EXP_ID; + } + else if (state == EXP_SEP && token.type() == ACToken::TOK_COLON_COLON) { + state = EXP_ID; + } + else if (state != EXP_SEP && token.type() == ACToken::TOK_ID) { + if (state == FLOATING) + name_start = i; + names.push_back (token.text ()); + Scope *lookup_result = 0; + Node *lr = lookup_name(scope, root_qualified, names); + if (lr && lr->is_class_or_struct()) + lookup_result = (Scope*)lr; + if (lookup_result) { + if (lookup_result->_is_slice) { + if (result && lookup_result != result) { + // TODO: generate real error message + cout << "ERROR conflicting slice names referenced" << endl; + cout << result->_name << " <--> " << lookup_result->_name << endl; + //cout << "SLICE: " << *rec << endl; + cout << "SCOPE: " << scope._name << endl; + scope.dump(); + } + else { + result = lookup_result; + clang::Token tok; + tok.startToken (); + ACToken marker(tok); + rec.insert(rec.begin() + name_start + 1, marker); + i++; + rec.insert(rec.begin() + i + 1, marker); + i++; + // TODO: continue to consume tokens while we are in a qualified name + } + } + } + state = EXP_SEP; + } + else { + state = FLOATING; + names.clear (); + root_qualified = false; + name_start = -1U; + if (token.type () == ACToken::TOK_ID) + continue; // this ID could be the start of the (qualified) slice name + } + ++i; + } + return result; +} +#endif diff --git a/AspectC++/Phase1.h b/AspectC++/Phase1.h new file mode 100644 index 0000000..b474366 --- /dev/null +++ b/AspectC++/Phase1.h @@ -0,0 +1,217 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __Phase1_h__ +#define __Phase1_h__ + +#include +#include +#include + +#include "ACModel/Elements.h" + +#include "IncludeGraph.h" +#include "ModelBuilder.h" +#include "CodeWeaver.h" +#include "PointCutSearcher.h" +#include "ACPreprocessor.h" + +class CodeWeaver; + +namespace Puma { + class CProject; + class Unit; + class FileUnit; + class TokenProvider; + class Token; +} + +// This class performs preliminary parsing of a translation unit. Its +// purpose is to find all aspect-oriented constructs in the code, +// store information about it in the translation unit's model, and +// remove or replace the aspect-oriented code. Thereby, the main +// parsing can be performed by an ordinary C++ parser without +// token and grammar extensions. + +class Phase1 : public PointCutSearcher, private ACPreprocessor { + + // Exception type + struct ParseError {}; + + // Helper classes to create a simple syntax tree while parsing + struct Node { + enum { ELEMENT_POINTCUT, ELEMENT_CLASS_ALIAS, ELEMENT_CXX11Attr, + SCOPE_NAMESPACE, SCOPE_CLASS, SCOPE_STRUCT, SCOPE_ASPECT, + SCOPE_UNION } _kind; + bool is_scope() const { return _kind >= SCOPE_NAMESPACE; } + bool is_aspect() const { return _kind == SCOPE_ASPECT; } + bool is_class() const { return _kind == SCOPE_CLASS; } + bool is_struct() const { return _kind == SCOPE_STRUCT; } + bool is_union() const { return _kind == SCOPE_UNION; } + bool is_namespace() const { return _kind == SCOPE_NAMESPACE; } + bool is_class_or_struct() const { return is_class() || is_struct(); } + bool is_cxx11attr() const { return _kind == ELEMENT_CXX11Attr; } + std::string _name; + ACM_Name *_jpm_link; + bool operator < (const Node &compared) const { return _name < compared._name; } + }; + struct Element : Node { + Node *_referred; // for class aliases + }; + struct Scope : Node { + Scope *_parent_scope; + bool _is_slice; + std::set _sub_scopes; + std::set _elements; + std::list _search_scopes; // base classes for classes/aspects + // namespaces for namespaces + void dump (int indent = 0) const { + for (int i = indent; i >= 0; i--) { cout << " "; } + if (_is_slice) + cout << "slice "; + switch (_kind) { + case SCOPE_NAMESPACE: cout << "namespace"; break; + case SCOPE_CLASS: cout << "class"; break; + case SCOPE_ASPECT: cout << "aspect"; break; + case SCOPE_UNION: cout << "union"; break; + default: cout << "unknown"; break; + } + cout << " " << _name << ": "; + for (std::list::const_iterator i = _search_scopes.begin (); + i != _search_scopes.end (); ++i) + cout << " " << (*i)->_name; + for (std::set::const_iterator i = _elements.begin (); + i != _elements.end (); ++i) + cout << " elem " << (*i)._name; + cout << endl; + for (std::set::const_iterator i = _sub_scopes.begin (); + i != _sub_scopes.end (); ++i) + (*i).dump (indent + 1); + } + }; + + Scope _root_scope; + Scope *_curr_scope; + ModelBuilder &_jpm; + CodeWeaver &_code_weaver; + bool _in_template; + string _tunit_name; + + // ID of deanonymized class, union or struct. This must be shared + // across all parse_scope calls. Otherwise, generated code may violate + // ODR rule. E.g., if the anon class number is *not* shared, then + // namespace N { static union { int i; } } + // namespace N { static union { int i2; } } + // will become + // namespace N { union __ac_anonN_0 { int i; } static union { int i; } } + // namespace N { union __ac_anonN_0 { int i2; } static union { int i2; } } + // which defines N::__ac_anonN_0 twice. + unsigned int _anon_class_no; + + ACConfig &_conf; + + void skip_block (int open, int close, bool inclusive = true); + void skip_round_block (bool inclusive = true); + void skip_curly_block (bool inclusive = true); + void skip_square_block (bool inclusive = true); + void skip_template_params (); + bool is_attribute_token (const ACToken &token, const ACToken &next) const; + bool is_cxx11_attribute_token (const ACToken &token, const ACToken &next) const; + bool is_gnu_attribute_token (const ACToken &token) const; + void skip_attributes (bool inclusive = true); + void skip_cxx11_attributes (bool inclusive = true); + void skip_gnu_attributes (bool inclusive = true); + + // internal registration functions + ACM_Name *register_scope (Scope &scope); + void register_base_classes (Scope &cls); + + // internal parse functions + void parse_scope (Scope &scope, std::string *anon_member_class_copy = 0); + void parse_qual_name (std::vector &names, + bool &root_qualified, bool &contains_template_id); + void parse_base_clause (Scope &class_scope); + void parse_base_spec (Scope &class_scope); + void parse_aspectof_function (const string &prot); + void parse_using_directive (Scope &scope); + void parse_pointcut_def (Scope &scope); +#ifdef FRONTEND_CLANG + void parse_attribute_decl (Scope &scope); +#endif + void parse_advice_def (Scope &scope, int &advice_no, int &intro_no, int &order_no, + int &anon_slice_no, const std::string &prot); + void parse_advice_body (AdviceCodeContext &context, int open, int close, CodeWeaver::TypeUse &uses_type ); + + // internal name lookup functions + Node *lookup_name (Scope &scope, bool root_qualified, const std::vector &names); + Node *lookup_name_in_scope (Scope &scope, const std::vector &names, + std::set &visited_scopes, int depth = 0); + Scope *lookup_scope (Scope &scope, bool root_qualified, std::vector &names); +#ifdef FRONTEND_PUMA + Scope *find_slice (Scope &scope, Puma::Unit *rec); +#else + Scope *find_slice (Scope &scope, ACPreprocessor::TokenVector &rec); +#endif + ACM_Pointcut *lookup_pct_func (bool root_qualified, std::vector &qual_name); + ACM_Attribute *lookup_pct_attr(bool root_qualified, std::vector &qual_name); + + // internal helper functions + PointCutExpr *create_pct_expr_tree(const string &pct, ACM_Name *scope, ACToken pos); +#ifdef FRONTEND_PUMA + void handle_slice_member (Scope &scope, Puma::Unit *rec, ACToken from, ACToken to); + std::string recording_to_string (Puma::Unit *); +#else + void handle_slice_member (Scope &scope, ACPreprocessor::TokenVector &rec, ACToken from, ACToken to); + std::string recording_to_string (const ACPreprocessor::TokenVector &); +#endif + bool is_visible_scope (Scope &scope, const std::string &name); + std::string full_anon_class_name (Scope &scope) const; + +#ifdef FRONTEND_CLANG + TU_ClassSlice::SliceBody + format_non_inline_member(ACPreprocessor::TokenVector &, const std::string &); + void whitespace (unsigned &line, const ACToken &token, std::string &); + void set_slice_tokens (TU_ClassSlice *, ACPreprocessor::TokenVector &); +#endif + +public: +#ifdef FRONTEND_PUMA + Phase1 (ModelBuilder &jpm, const string &tunit_name, Puma::CProject &project, ACConfig &conf, + CodeWeaver &code_weaver) : + ACPreprocessor(tunit_name, conf, project), _curr_scope (0), _jpm (jpm), + _code_weaver (code_weaver), _in_template (false), _tunit_name (tunit_name), + _conf( conf ) {} + // run the analysis and transformation + // result: -1 error; 0 empty file; 1 OK + int run (IncludeGraph &include_graph); + Puma::Unit *unit() const { return ACPreprocessor::unit (); } + +#else + Phase1 (ModelBuilder &jpm, const string &tunit_name, ACProject &project, ACConfig &conf, + CodeWeaver &code_weaver, IncludeGraph &include_graph) : + ACPreprocessor(tunit_name, conf, include_graph, project), _curr_scope (0), + _jpm (jpm), _code_weaver (code_weaver), _in_template (false), + _tunit_name (tunit_name), _anon_class_no(0), _conf( conf ) { + } + // run the analysis and transformation + // result: -1 error; 0 empty file; 1 OK + int run (); +#endif +}; + +#endif // __Phase1_h__ diff --git a/AspectC++/Plan.cc b/AspectC++/Plan.cc new file mode 100644 index 0000000..046bfbb --- /dev/null +++ b/AspectC++/Plan.cc @@ -0,0 +1,526 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "Plan.h" +#include "AspectInfo.h" +#include "AdviceInfo.h" +#include "OrderInfo.h" +#include "IntroductionInfo.h" +#include "PointCutContext.h" +#include "PointCutExpr.h" +#include "ModelBuilder.h" +#include "ACModel/Utils.h" + +using namespace Puma; + +Plan::Plan (ACErrorStream &e, ProjectModel &jpm, ACConfig& config) + : _conf(config), _err (e), _jpm (jpm) { + + // get all aspects from the join point model + ProjectModel::Selection all_aspects; + _jpm.select (JPT_Aspect, all_aspects); + + // sort them by inserting them into a set + for (ProjectModel::Selection::iterator iter = all_aspects.begin (); + iter != all_aspects.end (); ++iter) { + ACM_Aspect &jpl_aspect = (ACM_Aspect&)**iter; + _sorted_aspects.insert (&jpl_aspect); + } + + for (set::iterator iter = _sorted_aspects.begin (); + iter != _sorted_aspects.end (); ++iter) { + ACM_Aspect &jpl_aspect = (ACM_Aspect&)**iter; + + if (jpl_aspect.get_derived().size () > 0) +// if (is_abstract(jpl_aspect)) + continue; + + AspectInfo *aspect_info = addAspect (jpl_aspect); + + // collect and register all introductions, advice code, and order advice + // triggered by a concrete aspect or any of its base aspects + collect_advice (aspect_info, jpl_aspect); + } +} + +Plan::~Plan () { + for (int i = 0; i < (int)_advice_infos.length (); i++) + delete _advice_infos[i]; + for (list::iterator i = _introduction_infos.begin (); + i != _introduction_infos.end (); ++i) + delete *i; + for (list::iterator i = _order_infos.begin (); + i != _order_infos.end (); ++i) + delete *i; + for (AdviceMap::iterator i = _advice_map.begin (); i != _advice_map.end(); ++i) + delete i->second; + for (IntroMap::iterator i = _intro_map.begin (); i != _intro_map.end(); ++i) + delete i->second; +} + +// collect and register all introductions, advice code, and order advice +// triggered by a concrete aspect or any of its base aspects +void Plan::collect_advice (AspectInfo *aspect_info, ACM_Aspect &checked_aspect) { + ACM_Aspect &concrete_aspect = aspect_info->loc(); + typedef ACM_Container IContainer; + IContainer &intros = checked_aspect.get_intros(); + for (IContainer::const_iterator i = intros.begin ();i != intros.end (); ++i) { + IntroductionInfo *intro_info = addIntroduction (concrete_aspect, **i); + intro_info->pointcut_expr() = (*i)->get_pointcut ()->get_parsed_expr (); + } + + typedef ACM_Container AContainer; + AContainer &advices = checked_aspect.get_advices(); + for (AContainer::const_iterator i = advices.begin ();i != advices.end (); ++i) { + AdviceInfo *ai = addAdvice(*aspect_info, **i); + aspect_info->advice_infos().push_back (ai); + } + + typedef ACM_Container OContainer; + OContainer &orders = checked_aspect.get_orders(); + for (OContainer::const_iterator i = orders.begin ();i != orders.end (); ++i) { + addOrder(concrete_aspect, **i); + } + + typedef ACM_Container BaseContainer; + BaseContainer &bases = checked_aspect.get_bases(); + for (BaseContainer::const_iterator i = bases.begin (); i != bases.end (); ++i) { + ACM_Class *cls = (ACM_Class*)(*i); + if (cls->type_val () == JPT_Aspect) + collect_advice (aspect_info, *(ACM_Aspect*)cls); + } +} + +AspectInfo *Plan::addAspect (ACM_Aspect &a) { + pair res = _aspect_infos.insert (AspectInfo (a)); + return (AspectInfo*)&*res.first; +} + +AdviceInfo *Plan::addAdvice (AspectInfo &ai, ACM_AdviceCode &code) { + AdviceInfo *result = new AdviceInfo (ai, code); + _advice_infos.append (result); + return result; +} + +IntroductionInfo *Plan::addIntroduction (ACM_Aspect &jpl_aspect, ACM_Introduction &intro) { + IntroductionInfo *result = new IntroductionInfo (jpl_aspect, intro); + _introduction_infos.push_back (result); + return result; +} + +OrderInfo *Plan::addOrder (ACM_Aspect &a, ACM_Order &o) { + OrderInfo *result = new OrderInfo (a, o); + _order_infos.push_back (result); + return result; +} + +// consider a join point and advice in the plan +void Plan::consider( ACM_Code *jpl, const Condition &cond, AdviceInfo *ai ) { + if (!is_pseudo(*jpl)) { + bool has_plan = jpl->has_plan (); + if (!has_plan) + jpl->set_plan (_jpm.newCodePlan()); + if (!has_plan) { + if( jpl->type_val () & JPT_Access ) + _access_jpls.append( jpl ); + else + switch (jpl->type_val ()) { + case JPT_Execution: _exec_jpls.append (jpl); break; + case JPT_Construction: _cons_jpls.append (jpl); break; + case JPT_Destruction: _dest_jpls.append (jpl); break; + default: + _err << sev_error + << "internal problem, invalid join point type in plan" + << endMessage; + return; + } + } + ACM_CodeAdvice *code_advice = _jpm.newCodeAdvice(); + ACM_AdviceCode* advice_code = &ai->code(); + code_advice->set_advice(advice_code); + code_advice->set_conditional(cond); + TI_CodeAdvice::of(*code_advice)->set_condition(&cond); + TI_CodeAdvice::of(*code_advice)->set_advice_info(ai); + + // TODO: + // It looks like the advice info object of an advice A is the same for some/all(?) + // join points that are in the pointcut of A when weaving these join points for the + // advice A. Therefore the ThisJoinPoint object is the same and e.g. arguments for + // runtime checks are inserted at each of these join points even if an individual + // join point does not need them (because it need no runtime check). + // Thus a ThisJoinPoint object should be linked to the combination of advice info + // and join point. + // This problem yields unnecessary code (e.g. in case of "that") but apart from + // that is no real problem. + ThisJoinPoint& tjp = TI_AdviceCode::of(*advice_code)->this_join_point (); + tjp.check_condition(cond); + if(code_advice->get_conditional() && advice_code->get_kind() == ACT_AROUND) { + tjp.conditional(); + } + + AdviceMap::iterator i = _advice_map.find( jpl ); + vector *jp_advice = 0; + if (i == _advice_map.end ()) { + jp_advice = new vector; + _advice_map.insert( AdviceMap::value_type( jpl, jp_advice ) ); + } + else + jp_advice = i->second; + // remember this advice; unsorted for now + jp_advice->push_back(code_advice); + } + + if (cond) { + ACM_Function *that_func = 0; + if (jpl->get_parent () && ((ACM_Any*)jpl->get_parent())->type_val() == JPT_Function) + that_func = (ACM_Function*)jpl->get_parent(); + ACM_Name *target_name = 0; + if (jpl->type_val () == JPT_Call) + target_name = ((ACM_Call*)jpl)->get_target(); + else if (jpl->type_val () == JPT_Builtin) + target_name = ((ACM_Builtin*)jpl)->get_target(); + else if (jpl->type_val () == JPT_Get) + target_name = ((ACM_Get*)jpl)->get_variable(); + else if (jpl->type_val () == JPT_Set) + target_name = ((ACM_Set*)jpl)->get_variable(); + else if (jpl->type_val () == JPT_Ref) + target_name = ((ACM_Ref*)jpl)->get_variable(); + cond.checks_for_that (_type_checks_true); + cond.checks_for_target (_type_checks_true); + + StringSet check_names_that, check_names_target; + + if (that_func) { + cond.names_for_that (check_names_that); + for (StringSet::iterator iter = check_names_that.begin (); + iter != check_names_that.end (); ++iter) { + if (((ACM_Any*)that_func->get_parent())->type_val() & (JPT_Class|JPT_Aspect)) + _type_checks_false.insert (TypeCheck ((ACM_Class*)that_func->get_parent(), + *iter)); + } + } + + if (target_name) { + cond.names_for_target (check_names_target); + for (StringSet::iterator iter = check_names_target.begin (); + iter != check_names_target.end (); ++iter) { + if (((ACM_Any*)target_name->get_parent())->type_val() & (JPT_Class|JPT_Aspect)) + _type_checks_false.insert (TypeCheck ((ACM_Class*)target_name->get_parent(), + *iter)); + } + } + } +} + +void Plan::consider (ACM_Code *jpl, const CFlow &cflow) { + if (is_pseudo(*jpl)) + return; + + bool has_plan = jpl->has_plan (); + if (!has_plan) + jpl->set_plan (_jpm.newCodePlan()); + if (!has_plan) { + switch (jpl->type_val ()) { + case JPT_Execution: _exec_jpls.append (jpl); break; + case JPT_Call: + case JPT_Builtin: _access_jpls.append (jpl); break; + case JPT_Construction: _cons_jpls.append (jpl); break; + case JPT_Destruction: _dest_jpls.append (jpl); break; + default: + _err << sev_error + << "internal problem, invalid join point type in plan" + << endMessage; + return; + } + } + TI_Code::of(*jpl)->consider (cflow); +} + +void Plan::consider( ACM_Code *jpl ) { + if( is_pseudo( *jpl ) ) + return; + + bool has_plan = jpl->has_plan(); + if( ! has_plan ) { + jpl->set_plan( _jpm.newCodePlan() ); + + if( jpl->type_val () & JPT_Access ) + _access_jpls.append( jpl ); + else + switch( jpl->type_val() ) { + case JPT_Execution: + _exec_jpls.append( jpl ); + break; + case JPT_Construction: + _cons_jpls.append( jpl ); + break; + case JPT_Destruction: + _dest_jpls.append( jpl ); + break; + default: + _err << sev_error + << "internal problem, invalid join point type in plan" + << endMessage; + return; + } + } +} + +// consider a join point for an introduction in the plan +void Plan::consider (ACM_Class &jpl, ACM_Introduction *intro) { + + bool has_plan = jpl.has_plan(); + if (!has_plan) { + jpl.set_plan (_jpm.newClassPlan ()); + _class_jpls.append (&jpl); // TODO: still needed? we have the intro_map + } + IntroMap::iterator i = _intro_map.find(&jpl); + vector *cls_intros = 0; + if (i == _intro_map.end ()) { + cls_intros = new vector; + _intro_map.insert(IntroMap::value_type(&jpl, cls_intros)); + } + else + cls_intros = i->second; + // remember this intro; unsorted for now + cls_intros->push_back(intro); +} + +// calculate the order for a single join point +void Plan::order (ACM_Any *jpl) { + // use an OrderPlanner for this purpose + OrderPlanner order_planner; + + PointCutContext context (_jpm, _conf); + + const list &orders = order_infos (); + for (list::const_iterator i = orders.begin (); + i != orders.end (); ++i) { + OrderInfo *order = *i; + + // check if the current join point location is matched by the pointcut + // expression of the order advice + context.concrete_aspect (order->aspect ()); + Binding binding; // binding and condition not used for intros + Condition condition; + PointCutExpr *jp_pce = (PointCutExpr*)order->jp_pce ().get (); + if (!jp_pce->evaluate (*jpl, context, binding, condition)) + continue; + // remember order relations in the plan for this join point + const list &pces = order->pces (); + list *hi = 0; + list *lo = 0; + bool start = true; + for (list::const_iterator i2 = pces.begin (); + i2 != pces.end (); ++i2) { + PointCutExpr *pce = (PointCutExpr*)((*i2).get ()); + + // match all relevant aspects with the current match expression + list *matched = new list; + // TODO: this is inefficient. Not all aspects are relevant for each jp + // get all aspects from the join point model + for (set::iterator iter = _sorted_aspects.begin (); + iter != _sorted_aspects.end (); ++iter) { + ACM_Aspect &jpl_aspect = (ACM_Aspect&)**iter; + if (pce->evaluate (jpl_aspect, context, binding, condition)) + matched->push_back (&jpl_aspect); + } + if (matched->size () == 0) { + delete matched; + } + else if (start) { + lo = matched; // will become high in the next loop + start = false; + } + else { + if (hi) delete hi; + hi = lo; + lo = matched; + + // now we can consider the ordering info in the plan + for (list::iterator ihi = hi->begin (); + ihi != hi->end (); ++ihi) { + for (list::iterator ilo = lo->begin (); + ilo != lo->end (); ++ilo) { +// cout << signature(**ihi) << " -> " << signature (**ilo) << endl; + order_planner.precedence (**ihi, **ilo); + } + } + } + } + if (lo) delete lo; + } + + if (jpl->type_val() & JPT_Code) + check (*(ACM_Code*)jpl, order_planner); + else + check (*(ACM_Class*)jpl, order_planner); +} + +void Plan::sort_access_joinpoints() { + // TODO use better sorting algorithm + for( int i = 0; i < _access_jpls.length(); i++ ) { + assert( _access_jpls[ i ]->type_val() & JPT_Access ); + ACM_Access *min_ptr = static_cast( _access_jpls[ i ] ); + unsigned int min_id = min_ptr->get_lid(); + int min_index = i; + + for( int j = i + 1; j < _access_jpls.length(); j++ ) { + assert( _access_jpls[ j ]->type_val() & JPT_Access ); + ACM_Access *cmp_ptr = static_cast( _access_jpls[ j ] ); + unsigned int cmp_id = cmp_ptr->get_lid(); + + if( cmp_id < min_id ) { + min_index = j; + min_ptr = cmp_ptr; + min_id = cmp_id; + } + } + + if( min_index != i ) { + _access_jpls[ min_index ] = _access_jpls[ i ]; + _access_jpls[ i ] = min_ptr; + } + } +} + +// calculate the order for all join points +void Plan::order_code_joinpoints() { + // recreate the order of access joinpoints (it gets destroyed by Transformer) + sort_access_joinpoints(); + + for (int i = 0; i < (int)_exec_jpls.length (); i++) + order (_exec_jpls[i]); + for (int i = 0; i < (int)_access_jpls.length (); i++) + order (_access_jpls[i]); + for (int i = 0; i < (int)_cons_jpls.length (); i++) + order (_cons_jpls[i]); + for (int i = 0; i < (int)_dest_jpls.length (); i++) + order (_dest_jpls[i]); +} + +// issue an advice in the plan for this code join point +void Plan::issue (ACM_Code &jpl, ACM_CodeAdvice *ca) { + AdviceInfo *ai = TI_CodeAdvice::of(*ca)->get_advice_info(); + + // find latest around advice level + ACM_CodePlan *last_plan = jpl.get_plan(); + while (last_plan->has_next_level()) + last_plan = last_plan->get_next_level(); + + if (last_plan->has_around()) { + ACM_CodePlan *new_plan = _jpm.newCodePlan(); + last_plan->set_next_level(new_plan); + last_plan = new_plan; + } + + switch (ai->type()) { + case ACT_BEFORE: + last_plan->get_before().insert(ca); + break; + case ACT_AROUND: + last_plan->set_around(ca); + break; + case ACT_AFTER: + last_plan->get_after().push_front(ca); + break; + } +} + + +// check the plan for a specific join point +void Plan::check (ACM_Code &jpl, OrderPlanner &order_planner) { + if (!jpl.has_plan ()) + return; + + if (!order_planner.plan()) { + _err << sev_error << "order directives not resolvable for " + << jpl.type_str () << "(\"" << signature(jpl).c_str () + << "\")" << TransformInfo::location (jpl) << endMessage; + return; + } + + AdviceMap::iterator iter = _advice_map.find(&jpl); + if (iter == _advice_map.end ()) + return; // maybe only cflow triggers + vector &advices = *iter->second; + + for (int i = 0; i < order_planner.items (); i++) { + ACM_Aspect* ai = &order_planner.item (i); + for (unsigned int j = 0; j < advices.size(); j++) { + ACM_CodeAdvice *code_advice = advices[j]; + if (code_advice && + &TI_CodeAdvice::of (*code_advice)->get_advice_info()->aspect() == ai) { + issue(jpl, code_advice); + advices[j] = 0; + } + } + } + for (unsigned int j = 0; j < advices.size(); j++) + if (advices[j] != 0) + issue(jpl, advices[j]); +} + +// issue an introduction in the plan for this class join point +void Plan::issue (ACM_Class &jpl, ACM_Introduction *ii) { + TU_ClassSlice *slice = (TU_ClassSlice*)get_slice(*ii); + bool base, members; + slice->analyze_tokens(base, members); + if (base) { + ACM_BaseIntro *intro_ref = _jpm.newBaseIntro(); + intro_ref->set_intro(ii); + jpl.get_plan()->get_base_intros().insert (intro_ref); + } + if (members) { + ACM_MemberIntro *intro_ref = _jpm.newMemberIntro(); + intro_ref->set_intro(ii); + jpl.get_plan()->get_member_intros().insert (intro_ref); + } +} + +// check the plan for a specific join point +// TODO: a lot of code duplication with "check(ACM_Code&)" +void Plan::check (ACM_Class &jpl, OrderPlanner &order_planner) { + if (!jpl.has_plan ()) + return; + + if (!order_planner.plan ()) { + _err << sev_error << "order directives not resolvable for " + << jpl.type_str () << "(\"" << signature(jpl).c_str () + << "\")" << TransformInfo::location (jpl) << endMessage; + return; + } + + IntroMap::iterator iter = _intro_map.find(&jpl); + assert (iter != _intro_map.end ()); + vector &intros = *iter->second; + + for (int i = 0; i < order_planner.items (); i++) { + ACM_Aspect* ai = &order_planner.item (i); + for (unsigned int j = 0; j < intros.size(); j++) { + if (intros[j] && ((ACM_Aspect*)intros[j]->get_parent() == ai)) { + issue(jpl, intros[j]); + intros[j] = 0; + } + } + } + for (unsigned int j = 0; j < intros.size(); j++) + if (intros[j] != 0) + issue(jpl, intros[j]); +} + diff --git a/AspectC++/Plan.h b/AspectC++/Plan.h new file mode 100644 index 0000000..d787148 --- /dev/null +++ b/AspectC++/Plan.h @@ -0,0 +1,148 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __Plan_h__ +#define __Plan_h__ + +#include +#include +#include +#include +using namespace std; + +#include "ACModel/Elements.h" +#include "OrderPlanner.h" +#include "Condition.h" +#include "ACErrorStream.h" +#include "Puma/Array.h" +#include "ACConfig.h" + +class AdviceInfo; +class OrderInfo; +class IntroductionInfo; +class AspectInfo; +class CFlow; +class ProjectModel; + +class Plan { +public: + typedef set AspectContainer; + + ACConfig &_conf; + ACErrorStream &_err; + ProjectModel &_jpm; + Puma::Array _advice_infos; + list _introduction_infos; + list _order_infos; + set _aspect_infos; + Puma::Array _access_jpls; + Puma::Array _exec_jpls; + Puma::Array _cons_jpls; + Puma::Array _dest_jpls; + Puma::Array _class_jpls; + TypeCheckSet _type_checks_false; + TypeCheckSet _type_checks_true; + + typedef map*> IntroMap; + IntroMap _intro_map; // unsorted intros per class + + typedef map*> AdviceMap; + AdviceMap _advice_map; // unsorted advice per code joinpoint + + struct LessAspectPtr : public std::binary_function { + bool operator() (const ACM_Aspect * a1, const ACM_Aspect* a2) const { return *a1 < *a2; } + }; + + set _sorted_aspects; + + void issue (ACM_Code &jpl, ACM_CodeAdvice *ca); + void issue (ACM_Class &jpl, ACM_Introduction *ii); + + // collect and register all introductions, advice code, and order advice + // triggered by a concrete aspect or any of its base aspects + void collect_advice (AspectInfo *aspect_info, ACM_Aspect &checked_aspect); + + // check the plan for a specific join point + void check (ACM_Code &jpl, OrderPlanner &order_planner); + + // check the plan for a specific join point + void check (ACM_Class &jpl, OrderPlanner &order_planner); + +public: + + Plan (ACErrorStream &e, ProjectModel &jpm, ACConfig&); + ~Plan (); + + // manage advice and aspect ressources + AspectInfo *addAspect (ACM_Aspect &); + AspectContainer &aspect_infos () { return _aspect_infos; } + AdviceInfo *addAdvice (AspectInfo &ai, ACM_AdviceCode &code); + IntroductionInfo *addIntroduction (ACM_Aspect &jpl_aspect, ACM_Introduction &intro); + OrderInfo *addOrder (ACM_Aspect &a, ACM_Order &o); + const list &order_infos () const { return _order_infos; } + const list &introduction_infos () const { return _introduction_infos; } + + // consider a join point and advice/intro in the plan + void consider( ACM_Code *jpl, const Condition &cond, AdviceInfo *ai ); + void consider (ACM_Class &jpl, ACM_Introduction *intro); + void consider (ACM_Code *jpl, const CFlow& cflow); + void consider( ACM_Code *jpl ); // simple version for including parents of implicit joinpoints + + // calculate the order for a single join points + void order (ACM_Any *jpl); + + // calculate the order for all code join points + void sort_access_joinpoints(); + void order_code_joinpoints (); + + // read the accumulated plans + int access_jp_plans () const { return _access_jpls.length (); } + ACM_Access &access_jp_loc (int i) const { + return *(ACM_Access*)_access_jpls.lookup (i); + } + + int exec_jp_plans () const { return _exec_jpls.length (); } + ACM_Execution &exec_jp_loc (int i) const { + return *(ACM_Execution*)_exec_jpls.lookup (i); + } + + int cons_jp_plans () const { return _cons_jpls.length (); } + ACM_Construction &cons_jp_loc (int i) const { + return *(ACM_Construction*)_cons_jpls.lookup (i); + } + + int dest_jp_plans () const { return _dest_jpls.length (); } + ACM_Destruction &dest_jp_loc (int i) const { + return *(ACM_Destruction*)_dest_jpls.lookup (i); + } + + int class_jp_plans () const { return _class_jpls.length (); } + ACM_Class &class_jp_loc (int i) const { + return *(ACM_Class*)_class_jpls.lookup (i); + } + + const TypeCheckSet &type_checks_false () const { + return _type_checks_false; + } + + const TypeCheckSet &type_checks_true () const { + return _type_checks_true; + } +}; + +#endif // __Plan_h__ diff --git a/AspectC++/PointCut.cc b/AspectC++/PointCut.cc new file mode 100644 index 0000000..43eb295 --- /dev/null +++ b/AspectC++/PointCut.cc @@ -0,0 +1,67 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 + +/* $Id: PointCut.cc,v 1.6 2004/01/15 13:20:04 olaf.spinczyk Exp $ */ + +#include "PointCut.h" + +using namespace Puma; + +PointCut::PointCut() { + _type = PCT_UNKNOWN; +// _contents = (pccontents)0; +} + +PointCut::~PointCut () { + for (list::iterator iter = _cflow_triggers.begin (); + iter != _cflow_triggers.end (); ++iter) + delete *iter; +} + +void PointCut::cflow_triggers(PointCut &pc) { + PointCut *triggers = new PointCut(); + *triggers = pc; + _cflow_triggers.push_back (triggers); +} + +const list &PointCut::cflow_triggers() { + return _cflow_triggers; +} + +PointCut& PointCut::operator = (const PointCut& pc) { + clear (); + _type = pc.type (); +// _contents = pc.contents (); + return (PointCut&)(*this += pc); +} + +PointCut::iterator PointCut::find (ACM_Any *jpl) { + iterator iter = begin (); + while (iter != end () && (*iter).location () != jpl) + ++iter; + return iter; +} + +ostream& operator<< (ostream& o, PointCut& p) +{ + for (const ListElement* e = p.first(); e; e = p.next(e)) { + JoinPoint& jp = ((JoinPoint&)*e); + o << jp; + } + return o; +} diff --git a/AspectC++/PointCut.h b/AspectC++/PointCut.h new file mode 100644 index 0000000..d2b8d22 --- /dev/null +++ b/AspectC++/PointCut.h @@ -0,0 +1,79 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 + +/* $Id: PointCut.h,v 1.7 2004/09/07 10:57:16 olaf.spinczyk Exp $ */ + +#ifndef __PointCut_h__ +#define __PointCut_h__ + +#include +using namespace std; + +#include "Puma/List.h" +#include "JoinPoint.h" + +class PointCut : private Puma::List + { + public: +// enum operation { PC_NOT, PC_AND, PC_OR }; + enum pctype { PCT_CODE, PCT_CLASS, PCT_UNKNOWN }; + + private: + pctype _type; +// pccontents _contents; // shall replace _type someday + list _cflow_triggers; + + public: + PointCut(); + ~PointCut (); + PointCut& operator = (const PointCut& pc); + + // set and get the pointcut type + void type (pctype t) { _type = t; } + pctype type () const { return _type; } + + // set and get for cflow trigger pointcut + void cflow_triggers (PointCut& pc); + const list &cflow_triggers(); + + friend ostream& operator<< (ostream&, PointCut&); + + class iterator { + const Puma::ListElement *_curr; + Puma::List *_list; + public: + iterator (const Puma::ListElement *e, Puma::List *l) : _curr (e), _list (l) {} + void operator ++ () { if (_curr) _curr = _list->next (_curr); } + int operator == (const iterator &iter) const { + return _curr == iter._curr && _list == iter._list; + } + int operator != (const iterator &iter) const { + return !(*this == iter); + } + const JoinPoint &operator * () { return (const JoinPoint&)*_curr; } + }; + + iterator begin () { return iterator (Puma::List::first (), this); } + iterator end () { return iterator (0, this); } + iterator find (ACM_Any *jpl); + + void append (Puma::ListElement& element) { Puma::List::append (element); } + void clear () { Puma::List::clear (); } + }; + +#endif diff --git a/AspectC++/PointCutContext.cc b/AspectC++/PointCutContext.cc new file mode 100644 index 0000000..6884b09 --- /dev/null +++ b/AspectC++/PointCutContext.cc @@ -0,0 +1,61 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "PointCutContext.h" +#include "JoinPoint.h" +#include "IntroductionUnit.h" +#include "TransformInfo.h" +#include "ACModel/Utils.h" + + +bool is_derived_from (ACM_Class *base, ACM_Class *derived) { + typedef ACM_Container Container; + for (Container::iterator i = base->get_derived().begin (); + i != base->get_derived().end (); ++i) { + if (*i == derived || is_derived_from(*i, derived)) + return true; + } + return false; +} + +PointCutExpr *PointCutContext::lookup_virtual_pct_func (ACM_Class *scope, ACM_Pointcut *pct_func) { + // check whether the virtual pointcut is defined in the concrete aspect + ACM_Name *result = map_lookup(*scope, pct_func->get_name ()); + if (result && result->type_val() == JPT_Pointcut) + return (PointCutExpr*)((ACM_Pointcut*)result)->get_parsed_expr().get (); + + // get the scope of the virtual pointcut + ACM_Any *fct_scope = (ACM_Any*)pct_func->get_parent(); + if (!fct_scope || !(fct_scope->type_val() & (JPT_Class|JPT_Aspect))) + return 0; + ACM_Class *fct_class = (ACM_Class*)fct_scope; + + // lookup the pointcut in the base classes/aspects + typedef ACM_Container Container; + for (Container::iterator i = scope->get_bases().begin (); + i != scope->get_bases().end (); ++i) { + if (*i != fct_class && !is_derived_from (fct_class, *i)) { + continue; + } + PointCutExpr *pce = lookup_virtual_pct_func(*i, pct_func); + if (pce) { + return pce; + } + } + return 0; +} diff --git a/AspectC++/PointCutContext.h b/AspectC++/PointCutContext.h new file mode 100644 index 0000000..50d0d25 --- /dev/null +++ b/AspectC++/PointCutContext.h @@ -0,0 +1,137 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __PointCutContext_h__ +#define __PointCutContext_h__ + +#include +using namespace std; + +#include "Puma/Array.h" +#include "Puma/Stack.h" + +#include "Binding.h" +#include "ACModel/Elements.h" +#include "TransformInfo.h" +#include "ACConfig.h" + +class PointCutExpr; + +typedef Puma::Array ArgSet; + +class PointCutContext { + ACConfig& _config; + ProjectModel &_jpm; + ACM_Aspect *_aspect; + ACM_Pointcut *_pct_func; + int _per_aspect_cflows; + + // new pointcut evaluation data members + Puma::Stack _arg_bindings; + int _in_arg; + bool _in_result; + bool _in_that; + bool _in_target; + bool _pseudo_true; + bool _in_old_style_scopematch; + set _cflow_exprs; + // Messages that will be output to the AC++ error stream + vector> _messages; + +public: + + PointCutContext (ProjectModel &jpm, ACConfig& config) : + _config(config), _jpm (jpm), _aspect (0), _pct_func (0), _per_aspect_cflows (0), + _in_arg (-1), _in_result (false), _in_that (false), _in_target (false), + _pseudo_true (false), _in_old_style_scopematch( false ) { + } + + PointCutExpr *lookup_virtual_pct_func (ACM_Class *scope, ACM_Pointcut *pct_func); + PointCutExpr *lookup_virtual_pct_func (ACM_Pointcut *pct_func) { + return lookup_virtual_pct_func(_aspect, pct_func); + } + + ProjectModel &jpm () { return _jpm; } + + ACConfig& config() { return _config;} + + ACM_Pointcut *pct_func (ACM_Pointcut *new_pct_func) { + ACM_Pointcut *result = _pct_func; + _pct_func = new_pct_func; + return result; + } + ACM_Pointcut *pct_func () const { return _pct_func; } + void concrete_aspect (ACM_Aspect &ai) { _aspect = &ai; _per_aspect_cflows = 0; } + + // return the location of the current pointcut function (for error messages) +#ifdef FRONTEND_PUMA + Puma::Location location () const { + static Puma::Location loc; + if (!_pct_func) return loc; +#else + clang::FullSourceLoc location () const { + if (!_pct_func) return clang::FullSourceLoc(); +#endif + return TI_Pointcut::of(*_pct_func)->get_location(); + } + + // used for semantic analysis of pointcut expressions + Puma::Stack &arg_bindings () { return _arg_bindings; } + + // used for context binding in args() + bool in_arg () const { return _in_arg >= 0; } + void set_arg (int a) { _in_arg = a; } + int get_arg () const { return _in_arg; } + + // used for context binding in result() + bool in_result () const { return _in_result; } + void enter_result () { _in_result = true; } + void leave_result () { _in_result = false; } + + // used for context binding in that() + bool in_that () const { return _in_that; } + void enter_that () { _in_that = true; } + void leave_that () { _in_that = false; } + + // used for context binding in target() + bool in_target () const { return _in_target; } + void enter_target () { _in_target = true; } + void leave_target () { _in_target = false; } + + // that or within was evaluated as true, because we have a pseudo call + void pseudo_true (bool val) { _pseudo_true = val; } + bool is_pseudo_true () const { return _pseudo_true; } + + // needed to suppress matching of PCE_Member if doing it the old way + bool in_old_style_scopematch() const { return _in_old_style_scopematch; } + void enter_old_style_scopematch() { _in_old_style_scopematch = true; } + void leave_old_style_scopematch() { _in_old_style_scopematch = false; } + + // cflow trigger management + int cflow (PointCutExpr *pce) { + _cflow_exprs.insert (pce); + return _per_aspect_cflows++; + } + const set &cflows () { return _cflow_exprs; } + void cflow_reset () { _cflow_exprs.clear (); } + + // This is used in PCE_X::evaluate as there is no AC++ error stream available. + vector>& messages() { return _messages; } +}; + +#endif // __PointCutContext_h__ diff --git a/AspectC++/PointCutExpr.cc b/AspectC++/PointCutExpr.cc new file mode 100644 index 0000000..fe387c4 --- /dev/null +++ b/AspectC++/PointCutExpr.cc @@ -0,0 +1,1573 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 + +// AspectC++ includes +#include "PointCutExpr.h" +#include "PointCutContext.h" +#include "ACErrorStream.h" +#include "Binding.h" +#include "TransformInfo.h" + +// ACModel library includes +#include "ACModel/Utils.h" + +#include +#include +using std::stringstream; +using std::endl; + +using namespace Puma; + +void PointCutExpr::sem_args (ACErrorStream &err, PointCutContext &context, int warn_compat) { + // recursively do a semantic analysis of child nodes + for (int i = 0; i < args (); i++) + if (arg (i)) + arg (i)->semantics (err, context, warn_compat); +} + +void PointCutExpr::check_arg_types (ACErrorStream &err, const char *func, + PCE_Type expected, PointCutContext &context) { + // it is an error if something is provided, which was not expected + for (int i = 0; i < args (); i++) { + if (arg (i) && arg (i)->type () != expected) { + err << sev_error << context.location() + << "'" << func << "' expects a " + << (expected == PCE_NAME ? "name" : "code") << " pointcut" + << " as argument"; + if (args () > 1) + err << " " << (i + 1); + err << endMessage; + } + } +} + +void PointCutExpr::check_arg_types_equal (ACErrorStream &err, const char *func, + PointCutContext &context) { + if (!arg (0)) return; + // it is an error if the types of all arguments are not equal + PCE_Type first_type = arg (0)->type (); + for (int i = 1; i < args (); i++) { + if (arg (i) && arg (i)->type () != first_type) { + err << sev_error << context.location() + << "'" << func << "' expects that all argument types are equal" + << endMessage; + } + } +} + +const ACM_Arg *PointCutExpr::get_binding (const char *name, + ACErrorStream &err, + PointCutContext &context) { + if (!context.pct_func ()) { + err << sev_error << context.location() + << "context variable '" << name + << "' is not support in this kind of pointcut expression" + << endMessage; + return 0; + } + ArgSet &curr_arg_bindings = *context.arg_bindings ().top (); + ACM_Arg *arginfo = (ACM_Arg*)0; + typedef ACM_Container Container; + Container &arguments = context.pct_func()->get_args(); + int a = 0; + for (Container::iterator i = arguments.begin (); i != arguments.end (); ++i) { + if ((*i)->get_name() == name) { + arginfo = *i; + break; + } + a++; + } + if (!arginfo) { + err << sev_error << context.location() + << "'" << name << "' is not in argument list" << endMessage; + return 0; + } + return curr_arg_bindings.lookup (a); +} + +bool PCE_SingleArg::check_derived_class (ACM_Class &cls, + PointCutContext &context, Binding &binding, Condition &cond) { + + Condition unused; + bool do_subclasses = true; + typedef ACM_Container Container; + Container &derived = cls.get_derived(); + for (Container::const_iterator i = derived.begin (); i != derived.end (); ++i) { + if (arg (0)->match (**i, context, binding, unused)) { + if (context.in_that () || context.in_target ()) { + cond.matches (**i); + do_subclasses = false; // don't check subclasses, but + // siblings + } + else + return true; + } + if (do_subclasses && check_derived_class (**i, context, + binding, cond)) + return true; + } + return !do_subclasses; +} + +bool PCE_SingleArg::check_derived_func (ACM_Class &cls, ACM_Function &func, + PointCutContext &context, Binding &binding, Condition &cond) { + Condition unused; + bool do_subclasses = true; + typedef ACM_Container Container; + Container &derived = cls.get_derived(); + for (Container::const_iterator i = derived.begin (); i != derived.end (); ++i) { + typedef ACM_Container Container; + Container &children = (*i)->get_children(); + for (Container::const_iterator j = children.begin (); j != children.end (); ++j) { + if ((*j)->type_val () != JPT_Function) + continue; + ACM_Function &curr = *(ACM_Function*)*j; + if (!have_same_name_and_args (func, curr)) + continue; + if (arg (0)->match (curr, context, binding, cond)) + return true; + } + + if (do_subclasses && check_derived_func (**i, func, context, + binding, cond)) + return true; + } + return !do_subclasses; +} + +bool PCE_SingleArg::check_derived_var (ACM_Class &cls, ACM_Variable &var, + PointCutContext &context, Binding &binding, Condition &cond) { + Condition unused; + bool do_subclasses = true; + typedef ACM_Container Container; + Container &derived = cls.get_derived(); + for (Container::const_iterator i = derived.begin (); i != derived.end (); ++i) { + typedef ACM_Container Container; + Container &children = (*i)->get_children(); + for (Container::const_iterator j = children.begin (); j != children.end (); ++j) { + if ((*j)->type_val () != JPT_Variable) + continue; + ACM_Variable &curr = *(ACM_Variable*)*j; + if (var.get_name () != curr.get_name ()) + continue; + if (arg (0)->match (curr, context, binding, cond)) + return true; + } + + if (do_subclasses && check_derived_var (**i, var, context, + binding, cond)) + return true; + } + return !do_subclasses; +} + + +bool PCE_SingleArg::check_base_class (ACM_Class &cls, + PointCutContext &context, Binding &binding, Condition &cond) { + if (arg (0)->match (cls, context, binding, cond)) { + return true; + } + typedef ACM_Container Container; + Container &bases = cls.get_bases(); + for (Container::const_iterator i = bases.begin (); i != bases.end (); ++i) { + if (check_base_class(**i, context, binding, cond)) + return true; + } + return false; +} + +bool PCE_SingleArg::check_base_func (ACM_Class &cls, ACM_Function &func, + PointCutContext &context, Binding &binding, Condition &cond) { + typedef ACM_Container Container; + Container &children = cls.get_children (); + for (Container::const_iterator i = children.begin (); i != children.end (); ++i) { + if ((*i)->type_val () != JPT_Function) + continue; + ACM_Function &curr = *(ACM_Function*)*i; + if (!have_same_name_and_args (func, curr)) + continue; + if (arg (0)->match (curr, context, binding, cond)) + return true; + } + + typedef ACM_Container BContainer; + BContainer &bases = cls.get_bases(); + for (BContainer::const_iterator i = bases.begin (); i != bases.end (); ++i) { + if (check_base_func(**i, func, context, binding, cond)) + return true; + } + return false; +} + +bool PCE_SingleArg::check_base_var (ACM_Class &cls, ACM_Variable &var, + PointCutContext &context, Binding &binding, Condition &cond) { + typedef ACM_Container Container; + Container &children = cls.get_children (); + for (Container::const_iterator i = children.begin (); i != children.end (); ++i) { + if ((*i)->type_val () != JPT_Variable) + continue; + ACM_Variable &curr = *(ACM_Variable*)*i; + if (var.get_name () != curr.get_name ()) + continue; + if (arg (0)->match (curr, context, binding, cond)) + return true; + } + + typedef ACM_Container BContainer; + BContainer &bases = cls.get_bases(); + for (BContainer::const_iterator i = bases.begin (); i != bases.end (); ++i) { + if (check_base_var(**i, var, context, binding, cond)) + return true; + } + return false; +} + +bool PCE_SingleArg::check_scopes (ACM_Name *scope, + PointCutContext &context, Binding &binding, Condition &cond) { + do { + // check whether the argument of the pointcut function matches 'scope' + if (arg (0)->match (*scope, context, binding, cond)) + return true; + // go to the next scope level + scope = (ACM_Name*)scope->get_parent (); + } while (scope); + + return false; +} + +PCE_Type PCE_Classes::type () const { + return PCE_NAME; +} + +void PCE_Classes::semantics (ACErrorStream &err, PointCutContext &context, int warn_compat) { + sem_args (err, context, warn_compat); + check_arg_types (err, "classes", PCE_NAME, context); + _possible_types = JPT_Class; +} + +bool PCE_Classes::evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond) { +// cout << "classes: " << jpl.type_val () << " "; +// if (jpl.type_val() & JPT_Code) +// cout << signature((ACM_Code&)jpl); +// else +// cout << signature((ACM_Name&)jpl); +// cout << endl; + return jpl.type_val () == JPT_Class && + arg (0)->match (jpl, context, binding, cond); +} + +PCE_Type PCE_Base::type () const { + return PCE_NAME; +} + +void PCE_Base::semantics (ACErrorStream &err, PointCutContext &context, int warn_compat) { + sem_args (err, context, warn_compat); + check_arg_types (err, "base", PCE_NAME, context); + _possible_types = (JoinPointType)arg (0)->possible_types (); +} + +bool PCE_Base::evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond) { + if (!(jpl.type_val () & (int)_possible_types)) + return false; + + if (jpl.type_val () & (JPT_Class | JPT_Aspect)) { + // the class is a base of the argument class(es) if one of its derived + // classes is described by the argument + return check_derived_class ((ACM_Class&)jpl, context, binding, cond); + } + else if ((jpl.type_val () == JPT_Function)) { + ACM_Function &func = (ACM_Function&)jpl; + if (((ACM_Any*)func.get_parent ())->type_val () & (JPT_Class | JPT_Aspect)) { + ACM_Class &cls = *(ACM_Class*)func.get_parent (); + return check_derived_class (cls, context, binding, cond) || + check_derived_func (cls, func, context, binding, cond); + } + } + else if ((jpl.type_val () == JPT_Variable)) { + ACM_Variable &var = (ACM_Variable&)jpl; + if (((ACM_Any*)var.get_parent ())->type_val () & (JPT_Class | JPT_Aspect)) { + ACM_Class &cls = *(ACM_Class*)var.get_parent (); + return check_derived_class (cls, context, binding, cond) || + check_derived_var (cls, var, context, binding, cond); + } + } + return false; +} + +PCE_Type PCE_Derived::type () const { + return PCE_NAME; +} + +void PCE_Derived::semantics (ACErrorStream &err, PointCutContext &context, int warn_compat) { + sem_args (err, context, warn_compat); + check_arg_types (err, "derived", PCE_NAME, context); + _possible_types = (JoinPointType)arg (0)->possible_types (); +} + +bool PCE_Derived::evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond) { + if (!(jpl.type_val () & (int)_possible_types)) + return false; + + if (jpl.type_val () & (JPT_Class | JPT_Aspect)) { + // the class is derived of the argument class(es) if the class itself or + // one of its base classes is described by the argument + return check_base_class ((ACM_Class&)jpl, context, binding, cond); + } + else if ((jpl.type_val () == JPT_Function)) { + ACM_Function &func = (ACM_Function&)jpl; + if (((ACM_Any*)func.get_parent ())->type_val () & (JPT_Class | JPT_Aspect)) { + ACM_Class &cls = *(ACM_Class*)func.get_parent (); + return check_base_class (cls, context, binding, cond) || + check_base_func (cls, func, context, binding, cond); + } + } + else if ((jpl.type_val () == JPT_Variable)) { + ACM_Variable &var = (ACM_Variable&)jpl; + if (((ACM_Any*)var.get_parent ())->type_val () & (JPT_Class | JPT_Aspect)) { + ACM_Class &cls = *(ACM_Class*)var.get_parent (); + return check_base_class (cls, context, binding, cond) || + check_base_var (cls, var, context, binding, cond); + } + } + return false; +} + +PCE_Type PCE_Within::type () const { + return PCE_CODE; +} + +void PCE_Within::semantics (ACErrorStream &err, PointCutContext &context, int warn_compat) { + sem_args (err, context, warn_compat); + check_arg_types (err, "within", PCE_NAME, context); + _possible_types = JPT_Code; +} + +bool PCE_Within::evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond) { + + // 'within' matches only code join points + if (!(jpl.type_val () & (int)JPT_Code)) + return false; + ACM_Code &jpl_code = (ACM_Code&)jpl; + + // accept pseudo method calls + if (is_pseudo (jpl_code)) { + context.pseudo_true (true); + return true; + } + + ACM_Name *scope = lexical_scope (jpl_code); + if (scope->type_val () == JPT_Function) { + ACM_Function *func = (ACM_Function*)scope; + if (func->get_kind() == FT_CONSTRUCTOR || + func->get_kind() == FT_DESTRUCTOR || + func->get_kind() == FT_VIRTUAL_DESTRUCTOR || + func->get_kind() == FT_PURE_VIRTUAL_DESTRUCTOR) + scope = (ACM_Name*)func->get_parent (); + } + return arg(0)->match (*scope, context, binding, cond); +} + +PCE_Type PCE_Member::type() const { + return PCE_NAME; +} + +void PCE_Member::semantics( ACErrorStream &err, PointCutContext &context, int warn_compat) { + sem_args( err, context, warn_compat); + check_arg_types( err, "member", PCE_NAME, context ); + _possible_types = JPT_Name; +} + +bool PCE_Member::evaluate( ACM_Any &jpl, PointCutContext &context, Binding &binding, Condition &cond ) { + + // 'member' matches only name join points + if( ! ( jpl.type_val() & JPT_Name ) ) + return false; + + // avoid conflict with old style scope checks + if( context.in_old_style_scopematch() ) + return false; + + ACM_Name &named = static_cast( jpl ); + JoinPointType pt = (JoinPointType) arg(0)->possible_types(); + + // check the scope of the named program entity and all its parent scopes + if( pt & ( JPT_Aspect | JPT_Class | JPT_Namespace ) ) { + ACM_Any *scope = static_cast( named.get_parent() ); + if( scope == 0 || ! ( scope->type_val() & JPT_Name ) ) + return false; + + return check_scopes( static_cast( scope ), context, binding, cond ); + } + + return false; +} + +PCE_Type PCE_Execution::type () const { + return PCE_CODE; +} + +void PCE_Execution::semantics (ACErrorStream &err, + PointCutContext &context, int warn_compat) { + sem_args (err, context, warn_compat); + check_arg_types (err, "execution", PCE_NAME, context); + _possible_types = JPT_Execution; +} + +bool PCE_Execution::evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond) { + // consider execution join point only + if (jpl.type_val () != JPT_Execution) + return false; + + JoinPointType pt = (JoinPointType)arg (0)->possible_types (); + + // check if the executed function's name matches the argument + if (pt & JPT_Function) { + ACM_Function *function = (ACM_Function*)jpl.get_parent(); + assert(!function->get_builtin()); + return arg (0)->match (*function, context, binding, cond); + } + return false; +} + +PCE_Type PCE_Call::type () const { + return PCE_CODE; +} + +void PCE_Call::semantics (ACErrorStream &err, PointCutContext &context, int warn_compat) { + sem_args (err, context, warn_compat); + check_arg_types (err, "call", PCE_NAME, context); + _possible_types = JPT_Call; +} + +bool PCE_Call::evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond) { + if (jpl.type_val () != JPT_Call) + return false; + + JoinPointType pt = (JoinPointType)arg (0)->possible_types (); + + // check if the called function's name matches the argument + if (pt & JPT_Function) { + ACM_Function *target_function = ((ACM_Call&)jpl).get_target(); + assert(!target_function->get_builtin()); + return arg (0)->match (*target_function, context, binding, cond); + } + return false; +} + +PCE_Type PCE_Builtin::type () const { + return PCE_CODE; +} + +void PCE_Builtin::semantics (ACErrorStream &err, PointCutContext &context, int warn_compat) { + sem_args (err, context, warn_compat); + check_arg_types (err, "builtin", PCE_NAME, context); + _possible_types = JPT_Builtin; +} + +bool PCE_Builtin::evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond) { + if (jpl.type_val () != JPT_Builtin) + return false; + + JoinPointType pt = (JoinPointType)arg (0)->possible_types (); + + // check if the called operator's name matches the argument + if (pt & JPT_Function) { + ACM_Function *target_function = ((ACM_Builtin&)jpl).get_target(); + assert(target_function->get_builtin()); + return arg (0)->match (*target_function, context, binding, cond); + } + return false; +} + +PCE_Type PCE_Get::type () const { + return PCE_CODE; +} + +void PCE_Get::semantics( ACErrorStream &err, PointCutContext &context, int warn_compat) { + sem_args( err, context, warn_compat); + check_arg_types( err, "get", PCE_NAME, context ); + _possible_types = static_cast( JPT_Get | JPT_GetRef ); +} + +bool PCE_Get::evaluate( ACM_Any &jpl, PointCutContext &context, Binding &binding, Condition &cond ) { + if( ! ( jpl.type_val() & _possible_types ) ) + return false; + + JoinPointType pt = (JoinPointType)arg(0)->possible_types(); + + if( jpl.type_val() == JPT_Get ) { + // check if the accessed variables's name matches the argument + ACM_Variable *target_variable = ((ACM_Get&)jpl).get_variable(); + if( pt & JPT_Variable ) + if( arg(0)->match( *target_variable, context, binding, cond ) ) + return true; + } + else if( jpl.type_val() == JPT_GetRef ) { + // check alias-based joinpoints + ACM_Type *var_type = static_cast( jpl ).get_type(); + if( pt == JPT_Variable ) // match only vars as alias is for nothing else here, especially exclude types + if( arg(0)->match( *var_type, context, binding, cond ) ) + return true; + } + + return false; +} + +PCE_Type PCE_Set::type () const { + return PCE_CODE; +} + +void PCE_Set::semantics( ACErrorStream &err, PointCutContext &context, int warn_compat) { + sem_args( err, context, warn_compat); + check_arg_types( err, "set", PCE_NAME, context ); + _possible_types = static_cast( JPT_Set | JPT_SetRef ); +} + +bool PCE_Set::evaluate( ACM_Any &jpl, PointCutContext &context, Binding &binding, Condition &cond ) { + if( ! ( jpl.type_val() & _possible_types ) ) + return false; + + JoinPointType pt = (JoinPointType)arg(0)->possible_types(); + + if( jpl.type_val() == JPT_Set ) { + // check if the called function's name matches the argument + ACM_Variable *target_variable = ((ACM_Set&)jpl).get_variable(); + if( pt & JPT_Variable ) + if( arg(0)->match( *target_variable, context, binding, cond ) ) + return true; + } + else if( jpl.type_val() == JPT_SetRef ) { + // check alias-based joinpoints + ACM_Type *var_type = static_cast( jpl ).get_type(); + if( pt == JPT_Variable ) // match only vars as alias is for nothing else here, especially exclude types + if( arg(0)->match( *var_type, context, binding, cond ) ) + return true; + } + + return false; +} + +PCE_Type PCE_Ref::type () const { + return PCE_CODE; +} + +void PCE_Ref::semantics( ACErrorStream &err, PointCutContext &context, int warn_compat) { + sem_args( err, context, warn_compat); + check_arg_types( err, "ref", PCE_NAME, context ); + _possible_types = JPT_Ref; +} + +bool PCE_Ref::evaluate( ACM_Any &jpl, PointCutContext &context, Binding &binding, Condition &cond ) { + if( jpl.type_val () != JPT_Ref ) + return false; + + JoinPointType pt = (JoinPointType)arg(0)->possible_types(); + + // check if the called function's name matches the argument + ACM_Variable *target_variable = ((ACM_Ref&)jpl).get_variable(); + if( pt & JPT_Variable ) + if( arg(0)->match( *target_variable, context, binding, cond ) ) + return true; + + return false; +} + +PCE_Type PCE_Alias::type () const { + return PCE_NAME; +} + +void PCE_Alias::semantics( ACErrorStream &err, PointCutContext &context, int warn_compat) { + sem_args( err, context, warn_compat); + check_arg_types( err, "alias", PCE_NAME, context ); + _possible_types = JPT_Variable; +} + +bool PCE_Alias::evaluate( ACM_Any &jpl, PointCutContext &context, Binding &binding, Condition &cond ) { + if( jpl.type_val () != JPT_Type ) // only type based matching yet + return false; + + JoinPointType pt = (JoinPointType)arg(0)->possible_types(); + + if( pt & JPT_Variable ) { + ACM_Type &type = static_cast( jpl ); + ProjectModel::Selection refs; + context.jpm().select( JPT_Ref, refs ); + + for( ProjectModel::Selection::iterator iter = refs.begin(); iter != refs.end(); ++iter ) { // check all possible variables + ACM_Variable &var = *( static_cast( **iter ).get_variable() ); + if( ( type.get_signature() == var.get_type()->get_signature() ) && arg(0)->match( var, context, binding, cond ) ) + return true; + } + } + + return false; +} + +PCE_Type PCE_Construction::type () const { + return PCE_CODE; +} + +void PCE_Construction::semantics (ACErrorStream &err, PointCutContext &context, int warn_compat) { + sem_args (err, context, warn_compat); + check_arg_types (err, "construction", PCE_NAME, context); + _possible_types = JPT_Construction; +} + +bool PCE_Construction::evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond) { + if (jpl.type_val () != JPT_Construction) + return false; + ACM_Name *scope = lexical_scope ((ACM_Construction&)jpl); + return arg (0)->match (*scope, context, binding, cond); +} + +PCE_Type PCE_Destruction::type () const { + return PCE_CODE; +} + +void PCE_Destruction::semantics (ACErrorStream &err, PointCutContext &context, int warn_compat) { + sem_args (err, context, warn_compat); + check_arg_types (err, "destruction", PCE_NAME, context); + _possible_types = JPT_Destruction; +} + +bool PCE_Destruction::evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond) { + if (jpl.type_val () != JPT_Destruction) + return false; + ACM_Name *scope = lexical_scope ((ACM_Destruction&)jpl); + return arg (0)->match (*scope, context, binding, cond); +} + + +PCE_Type PCE_That::type () const { + return PCE_CODE; +} + +void PCE_That::semantics (ACErrorStream &err, PointCutContext &context, int warn_compat) { + context.enter_that (); + sem_args (err, context, warn_compat); + context.leave_that (); + check_arg_types (err, "that", PCE_NAME, context); + _possible_types = JPT_Code; +} + +bool PCE_That::evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond) { + // 'that' matches only code join points + if (!(jpl.type_val () & (int)JPT_Code)) + return false; + ACM_Code &jpl_code = (ACM_Code&)jpl; + if (is_pseudo(jpl)) { + context.pseudo_true (true); + return true; + } + + // get the function that is executed when the join point is reached + ACM_Name *parent = (ACM_Name*)jpl_code.get_parent (); + if (parent && parent->type_val() == JPT_Builtin) + parent = (ACM_Name*)parent->get_parent(); + if (parent->type_val () != JPT_Function) + return false; + ACM_Function *jpl_function = (ACM_Function*)parent; + + // static (member) functions and non-member functions don't have a 'this' pointer + if (jpl_function->get_kind() == FT_NON_MEMBER || + jpl_function->get_kind() == FT_STATIC_NON_MEMBER || + jpl_function->get_kind() == FT_STATIC_MEMBER) + return false; + + // get the class of which the function is a member + ACM_Class *class_loc = (ACM_Class*)jpl_function->get_parent (); + + context.enter_that (); + binding._this = (ACM_Arg*)0; + + // if any of the class' base classes matches the argument the current class + // is definitely an object of the required type + if (!check_base_class (*class_loc, context, binding, cond)) { + // in a construction or destruction the object has exactly the type + // of the constructor/destructor scope => no run-time check + + if (jpl_function->get_kind() == FT_CONSTRUCTOR || + jpl_function->get_kind() == FT_DESTRUCTOR || + jpl_function->get_kind() == FT_VIRTUAL_DESTRUCTOR || + jpl_function->get_kind() == FT_PURE_VIRTUAL_DESTRUCTOR) { + context.leave_that (); + return false; + } + + // create a 'that' condition with a mangled name + stringstream mangled_check; + arg (0)->mangle_type_check (mangled_check); + cond.that (class_loc, mangled_check.str ()); + + // find the derived classes that match the argument + check_derived_class (*class_loc, context, binding, cond); + } + context.leave_that (); + return true; +} + +PCE_Type PCE_Target::type () const { + return PCE_CODE; +} + +void PCE_Target::semantics (ACErrorStream &err, PointCutContext &context, int warn_compat) { + context.enter_target (); + sem_args (err, context, warn_compat); + context.leave_target (); + check_arg_types (err, "target", PCE_NAME, context); + _possible_types = JPT_Call|JPT_Set|JPT_Get|JPT_Ref; +} + +bool PCE_Target::evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond) { + ACM_Class *class_loc = 0; + + if (jpl.type_val () == JPT_Call) { + ACM_Call &jpl_call = (ACM_Call&)jpl; + + ACM_Function *target_function = jpl_call.get_target(); + + // only non-static member functions are relevant here + // TODO: how to handle explicit destructor calls? + if (target_function->get_kind() != FT_MEMBER && + target_function->get_kind() != FT_VIRTUAL_MEMBER && + target_function->get_kind() != FT_PURE_VIRTUAL_MEMBER) + return false; + + // get the class of which the function is a member + class_loc = (ACM_Class*)target_function->get_parent (); + } + else if (jpl.type_val() & (JPT_Set|JPT_Get|JPT_Ref)) { + ACM_Variable *target_var = 0; + if (jpl.type_val () == JPT_Set) { + ACM_Set &jpl_set = (ACM_Set&)jpl; + target_var = jpl_set.get_variable(); + } + else if (jpl.type_val () == JPT_Get) { + ACM_Get &jpl_get = (ACM_Get&)jpl; + target_var = jpl_get.get_variable(); + } + else if (jpl.type_val () == JPT_Ref) { + ACM_Ref &jpl_ref = (ACM_Ref&)jpl; + target_var = jpl_ref.get_variable(); + } + if (!target_var || target_var->get_kind() != VT_MEMBER) + return false; + + // get the class of which the variable is a member + class_loc = (ACM_Class*)target_var->get_parent (); + } + + if (!class_loc) + return false; // shouldn't happen + + context.enter_target (); + binding._target = (ACM_Arg*)0; + // if any of the class' base classes matches the argument the current class + // is definitely an object of the required type + if (!check_base_class (*class_loc, context, binding, cond)) { + // create a 'that' condition with a mangled name + stringstream mangled_check; + arg (0)->mangle_type_check (mangled_check); + cond.target (class_loc, mangled_check.str ()); + + // find the derived classes that match the argument + check_derived_class (*class_loc, context, binding, cond); + } + context.leave_target (); + return true; +} + +PCE_Type PCE_CFlow::type () const { + return PCE_CODE; +} + +void PCE_CFlow::semantics (ACErrorStream &err, PointCutContext &context, int warn_compat) { + sem_args (err, context, warn_compat); + check_arg_types (err, "cflow", PCE_CODE, context); + // evaluate the argument pointcut + ProjectModel::Selection all; + context.jpm ().select (JPT_Code, all); + for (ProjectModel::Selection::iterator iter = all.begin (); + iter != all.end (); ++iter) { + ACM_Any &jpl = *(ACM_Any*)*iter; + Binding cflow_binding; + Condition cflow_condition; + context.pseudo_true (false); // todo sichern! + if (arg (0)->match (jpl, context, cflow_binding, cflow_condition)) { + if (cflow_binding._used) { + err << sev_error << context.location() + << "context variables not supported in cflows" << endMessage; + break; + } + if (cflow_condition) { + err << sev_error << context.location() + << "runtime conditions not supported in cflows" << endMessage; + break; + } + _arg_pointcut.append (*new JoinPoint (&jpl, cflow_condition)); + } + } + _index = context.cflow (this); // remember this node in the context + _possible_types = JPT_Code; +} + +bool PCE_CFlow::evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond) { + // check if this join point is one of the cflow starting points + if (_arg_pointcut.find (&jpl) != _arg_pointcut.end ()) + return true; // no runtime condition check! + + // every other joinpoint might be in the cflow (space for improvement) + cond.cflow (_index); + return true; +} + +PCE_Type PCE_Args::type () const { + return PCE_CODE; +} + +void PCE_Args::semantics (ACErrorStream &err, PointCutContext &context, int warn_compat) { + check_arg_types (err, "args", PCE_NAME, context); + + // recursively do a semantic analysis of child nodes + int saved_arg = context.get_arg (); + for (int i = 0; i < args (); i++) { + context.set_arg (i); + if (arg (i)) + arg (i)->semantics (err, context,warn_compat); + } + context.set_arg (saved_arg); + _possible_types = JPT_Code; +} + +bool PCE_Args::evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond) { + + // ignore all non-code join points + if (!(jpl.type_val () & (int)JPT_Code)) + return false; + ACM_Code *jpl_code = (ACM_Code*)&jpl; + + // check if the number of arguments is ok -> not compatible ("...") + if (args () != get_arg_count(*jpl_code)) + return false; + + // check if all argument types match + int saved_arg = context.get_arg (); + list type_list; + get_arg_types (*jpl_code, type_list); + unsigned a = 0; + for (list::iterator i = type_list.begin(); i != type_list.end(); ++i) { + context.set_arg (a); + binding._args[a] = (ACM_Arg*)0; + ACM_Type &type_loc = (ACM_Type&)**i; + if (!arg (a)->match (type_loc, context, binding, cond)) { + context.set_arg (saved_arg); + return false; + } + a++; + } + context.set_arg (saved_arg); + + // args should not produce runtime checks until here + assert(!cond); + +#ifdef FRONTEND_CLANG + // Check whether the join-point uses short-circuit-evaluation: + if(jpl_code->type_val() == JPT_Builtin){ + const TI_Builtin* transform_info = TI_Builtin::of(*static_cast(jpl_code)); + // Check whether this is no pseudo-call-join-point and a short-circuiting-join-point: + if(transform_info->TI_Access::tree_node() > 0 && transform_info->is_short_circuiting()) { + // On join-points with short-circuit evaluation it is not guaranteed + // that the second (or third in case of "?:"-operator) argument is available. Because the + // decision about the evaluation of the second (or third) argument + // comes at runtime, we first determine the short-circuit argument, that is bound by the + // current args pointcut function, and afterwards we create a condition that compares the + // available short-circuit argument with the needed argument at runtime. + + int needed_arg = -1; + if(transform_info->is_ternary_expr()) { + // Operator "?:" + if(binding._args[1] > 0 && binding._args[2] > 0) { + // Both short-circuiting arguments are bound, but it is not possible that + // both short-circuiting arguments are available at the same time. We need + // no runtime check and generate a warning if wanted. The warning will be + // created only once per args pointcut function. + if(context.config().warn_limitations() && !_both_sc_args_bound_warning_created) { + context.messages().push_back(pair( + sev_warning, string("args pointcut function: join points at calls to the " + "short-circuiting operator '?:' do not match (reason: both short-circuit " + "arguments were bound, but they are never available at the same time)."))); + _both_sc_args_bound_warning_created = true; + } + return false; + } + else if(binding._args[1] == 0 && binding._args[2] == 0) { + // Both short-circuiting arguments are *not* bound: We do not need a runtime check + return true; + } + // Otherwise determine the needed/bound argument: + needed_arg = binding._args[1] > 0 ? 1 : 2; + } + else { + // Operator "&&" or "||": Check for first argument: + if(binding._args[1] > 0) { + needed_arg = 1; + } + } + + // Check if an short-circuit argument was bound and we therefore need an argument at + // runtime: + if(needed_arg != -1) { + // We need an argument: create condition: + cond.needed_short_circuit_arg(needed_arg); + // If wanted we create a warning. This warning will be created only once per + // args pointcut function. + if(context.config().warn_limitations() && !_sc_arg_bound_warning_created) { + context.messages().push_back(pair( + sev_warning, string("args pointcut function: matching of join points at calls " + "to short-circuiting operators '&&', '||' and '?:' is runtime dependent " + "(reason: a short-circuit argument is bound by the args pointcut function and " + "a match only occurs if the bound argument is available at runtime)."))); + _sc_arg_bound_warning_created = true; + } + } + } + } +#endif // FRONTEND_CLANG + + return true; +} + +PCE_Type PCE_Result::type () const { + return PCE_CODE; +} + +void PCE_Result::semantics (ACErrorStream &err, PointCutContext &context, int warn_compat) { + context.enter_result (); + sem_args (err, context, warn_compat); + context.leave_result (); + check_arg_types (err, "result", PCE_NAME, context); + _possible_types = (JoinPointType)(JPT_Execution|JPT_Call|JPT_Builtin|JPT_Get); +} + +bool PCE_Result::evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond) { + + // only execution, call and builtin join points have a result + if (jpl.type_val () != JPT_Execution && + jpl.type_val () != JPT_Call && + jpl.type_val () != JPT_Builtin && + jpl.type_val () != JPT_Get) + return false; + + ACM_Code *jpl_code = (ACM_Code*)&jpl; + assert (has_result_type(*jpl_code)); + + ACM_Type &type_loc = *get_result_type(*jpl_code); + + context.enter_result (); + binding._result = (ACM_Arg*)0; + bool result = arg (0)->match (type_loc, context, binding, cond); + context.leave_result (); + return result; +} + + +PCE_Type PCE_Or::type () const { + return arg (0)->type (); +} + +void PCE_Or::semantics (ACErrorStream &err, PointCutContext &context, int warn_compat) { + sem_args (err, context, warn_compat); + check_arg_types_equal (err, "||", context); + _possible_types = (JoinPointType) + (arg(0)->possible_types () | arg(1)->possible_types ()); +} + +bool PCE_Or::evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond) { + Condition subcond0, subcond1; + bool subresult0, subresult1; + subresult0 = arg (0)->match (jpl, context, binding, subcond0); + subresult1 = arg (1)->match (jpl, context, binding, subcond1); + // if both subresults are false the disjunction is false, too + if (!(subresult0 || subresult1)) + return false; + + // if any of the subresults was an unconditional true the result is true + if ((subresult0 && !subcond0) || (subresult1 && !subcond1)) + return true; + + // at least one subresult was true, now we consider possible conditions + if (subcond0) { + cond.assign (subcond0); + if (subcond1) + cond.op_or (subcond1); + } + else if (subcond1) { + cond.assign (subcond1); + } + return true; +} + +PCE_Type PCE_And::type () const { + return arg (0)->type (); +} + +void PCE_And::semantics (ACErrorStream &err, PointCutContext &context, int warn_compat) { + sem_args (err, context, warn_compat); + check_arg_types_equal (err, "&&", context); + _possible_types = (JoinPointType) + (arg(0)->possible_types () & arg(1)->possible_types ()); + if (_possible_types == (JoinPointType)0) { + err << sev_warning << context.location() + << "Result of '&&' always false! Check the types of the argument pointcut expressions." + << endMessage; + return; + } +} + +bool PCE_And::evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond) { + Condition subcond0, subcond1; + bool subresult0, subresult1; + subresult0 = arg (0)->match (jpl, context, binding, subcond0); + bool pseudo_true0 = context.is_pseudo_true (); + context.pseudo_true (false); + subresult1 = arg (1)->match (jpl, context, binding, subcond1); + bool pseudo_true1 = context.is_pseudo_true (); + context.pseudo_true (pseudo_true0 && pseudo_true1); + + // if any subresult was false the conjunction is false, too + if (!(subresult0 && subresult1)) + return false; + // both subresult were true, now we consider possible conditions + if (subcond0) { + cond.assign (subcond0); + if (subcond1) + cond.op_and (subcond1); + } + else if (subcond1) { + cond.assign (subcond1); + } + return true; +} + +PCE_Type PCE_Not::type () const { + return arg (0)->type (); +} + +void PCE_Not::semantics (ACErrorStream &err, PointCutContext &context, int warn_compat) { + sem_args (err, context, warn_compat); + check_arg_types (err, "!", type (), context); + if (type () == PCE_NAME) + _possible_types = JPT_Name; + else if (type () == PCE_CODE) + _possible_types = JPT_Code; + else + _possible_types = (JoinPointType)0; +} + +bool PCE_Not::evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond) { + Condition subcond; + bool subresult = arg (0)->match (jpl, context, binding, subcond); + // if the argument was true because we evaluate a pseudo call return true + if (context.is_pseudo_true ()) + return true; + // if the subexpression evaluates to an unconditional 'true' or false the + // result must be inverted + if (!subcond) + return !subresult; + // otherwise the result is 'true' but the condition must be negated + else { + cond.assign (subcond); + cond.op_not (); + return true; + } +} + +PCE_Type PCE_Named::type () const { + assert(_expr.get ()); + return ((PointCutExpr*)_expr.get ())->type (); +} + +void PCE_Named::semantics (ACErrorStream &err, PointCutContext &context, int warn_compat) { + + // link invocations of virtual pointcut functions to the right implementation + if (_pct_func->get_kind() == PT_VIRTUAL || + _pct_func->get_kind() == PT_PURE_VIRTUAL) { + PointCutExpr *late_bound_pct = context.lookup_virtual_pct_func(_pct_func); + if (!late_bound_pct) { // TODO: error handling + err << sev_fatal << context.location() << "Virtual named pointcut '" + << _pct_func->get_name().c_str() << "' not found." << endMessage; + return; + } + // TODO: better let 'lookup...' return the pointcut function and use the + // copy operator of 'PointcutExpression' here. + _expr.set(late_bound_pct->duplicate()); + } + else + _expr = _pct_func->get_parsed_expr(); + + ArgSet new_arg_bindings; + for (std::list::iterator i = params().begin (); + i != params().end(); ++i) { + // Argument must be a formal paramete in the current context, lookup it up + ACM_Arg *argument = (ACM_Arg*)get_binding((*i).c_str (), err, context); + if (!argument) { + err << sev_error << context.location() << "Argument '" << (*i).c_str() + << "' undefined." << endMessage; + } + new_arg_bindings.append(argument); + } + + // set the current function pointer for context var lookups + ACM_Pointcut *saved_pct_func = context.pct_func (_pct_func); + + // push the argument binding + context.arg_bindings ().push (&new_arg_bindings); + + // analyze referenced expression tree + ((PointCutExpr*)_expr.get ())->semantics(err, context, warn_compat); + + // pop the argument binding from the stack again + context.arg_bindings ().pop (); + + context.pct_func (saved_pct_func); // restore old function pointer + + check_arg_types (err, "pointcut", type (), context); + + _possible_types = ((PointCutExpr*)_expr.get ())->possible_types (); +} + +bool PCE_Named::evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond) { + assert(_expr.get ()); + return ((PointCutExpr*)_expr.get ())->match (jpl, context, binding, cond); +} + +PCE_Type PCE_ContextVar::type () const { + return PCE_NAME; +} + +bool PCE_CXX11Attr::evaluate(ACM_Any &jpl, PointCutContext &context, Binding &binding, Condition &cond) +{ + // check whether this is a name join point. Only name joinpoints can have attributes! + if ((jpl.type_val() & JPT_Name) == 0) + return false; + + ACM_Name *jpl_name = (ACM_Name*)&jpl; + while (true) { + + // test if this attributes was annotated at the join point + for (ACM_Attribute *attr :jpl_name->get_attributes()) + if(*attr == *_pct_attr) + return true; + + // otherwise check the parent scope of the current name join point, + // but omit the parent classes of nested classes + ACM_Name *parent = (ACM_Name*)jpl_name->get_parent(); + if (jpl_name->type_val () == JPT_Class || jpl_name->type_val () == JPT_Aspect) { + while (parent && (parent->type_val () == JPT_Class || parent->type_val () == JPT_Aspect)) + parent = (ACM_Name*)parent->get_parent(); + } + // root scope detected -> stop here + if (!parent || parent == context.jpm().get_root()) + break; + + // continue by matching the parent scope + jpl_name = parent; + } + + // not found, even in any parent scope + return false; +} + +void PCE_CXX11Attr::semantics(ACErrorStream &err, PointCutContext &context, int warn_compat) +{ + _possible_types = JPT_Any; +} + +void PCE_ContextVar::semantics (ACErrorStream &err, + PointCutContext &context, int warn_compat) { + if (!(_bound_arg = get_binding (_name.c_str (), err, context))) + return; + // TODO: can we get rid of the Puma/parser dependency? +#ifdef FRONTEND_PUMA + _check_type = TI_Arg::of(*_bound_arg)->type_info(); + + if (context.in_that () || context.in_target ()) { + if (_check_type->isPointer () && _check_type->BaseType ()->is_void ()) { + // "void*" matches any class! + _check_type = 0; + } + else { + if (_check_type->isPointer () || _check_type->isAddress ()) + _check_type = _check_type->BaseType (); + if (!_check_type->isClass ()) { +#else // FRONTEND_CLANG + _check_type = TI_Arg::of(*_bound_arg)->type(); + + if (context.in_that () || context.in_target ()) { + if (_check_type->isPointerType() && _check_type->isVoidPointerType()) { + // "void*" matches any class! + _check_type = clang::QualType(); + } + else { + if (_check_type->isPointerType() || _check_type->isReferenceType()) + _check_type = _check_type->getPointeeType().getCanonicalType (); + if (!_check_type->isRecordType ()) { +#endif + err << sev_error << context.location() + << "argument of 'that' or 'target' must be a class, pointer to " + << "class, or reference to class" << endMessage; + } + } + _bound_to = context.in_that () ? CV_THAT : CV_TARGET; + } + else if (context.in_result ()) { + _bound_to = CV_RESULT; + } + else { + _bound_to = CV_ARG; + _arg = context.get_arg (); + } + if (_bound_to == CV_ARG || _bound_to == CV_RESULT) + _possible_types = JPT_Type; + else if (_bound_to == CV_TARGET || _bound_to == CV_THAT) + _possible_types = (JoinPointType) + (JPT_Class|JPT_Aspect); + else + _possible_types = (JoinPointType)0; +} + +bool PCE_ContextVar::evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond) { + + assert (((_bound_to == CV_ARG || _bound_to == CV_RESULT) && + jpl.type_val () == JPT_Type) || + ((_bound_to == CV_TARGET || _bound_to == CV_THAT) && + (jpl.type_val () & (JPT_Class | JPT_Aspect)))); + + // determine the current type +#ifdef FRONTEND_PUMA + CTypeInfo *curr_type = 0; + if (jpl.type_val () == JPT_Type) + curr_type = TI_Type::of ((ACM_Type&)jpl)->type_info (); + else if (jpl.type_val () == JPT_Class || + jpl.type_val () == JPT_Aspect) { + curr_type = ((TI_Class*)((ACM_Class&)jpl).transform_info ())->class_info ()->TypeInfo (); + } + + assert (curr_type); + if (!curr_type) + return false; + + // check if the current type matches + if (_check_type && *_check_type != *curr_type) { + return false; + } +#else // FRONTEND_CLANG + clang::QualType curr_type; + if (jpl.type_val () == JPT_Type) + curr_type = TI_Type::of ((ACM_Type&)jpl)->type (); + else if (jpl.type_val () == JPT_Class || + jpl.type_val () == JPT_Aspect) { + curr_type = + clang::QualType(((TI_Class *)((ACM_Class &)jpl).transform_info()) + ->decl()->getTypeForDecl(), + 0); + } + + assert (!curr_type.isNull()); + if (curr_type.isNull()) + return false; + + // check if the current type matches + if (!_check_type.isNull() && + _check_type.getCanonicalType () != curr_type.getCanonicalType ()) { + return false; + } +#endif + + // do the binding + binding._used = true; + switch (_bound_to) { + case CV_THAT: + binding._this = (ACM_Arg*)_bound_arg; + break; + case CV_TARGET: + binding._target = (ACM_Arg*)_bound_arg; + break; + case CV_RESULT: + binding._result = (ACM_Arg*)_bound_arg; + break; + case CV_ARG: + binding._args[_arg] = (ACM_Arg*)_bound_arg; + break; + } + return true; +} + +void PCE_ContextVar::mangle_type_check (ostream &out) { + Naming::mangle(out, _bound_arg); +} + + +PCE_Type PCE_Match::type () const { + return PCE_NAME; +} + +bool PCE_Match::parse () { + return _match_expr.parse (_str); +} + +void PCE_Match::semantics (ACErrorStream &err, PointCutContext &context, int warn_compat) { + if (_match_expr.is_new() && !_match_expr.parse (_str)) + return; // TODO: What about error handling here? + if (_match_expr.is_function ()) { +// if (_match_expr.name ().is_trivial()) { +// _pre_evaluate = PRE_EVAL_ON; +// } + _possible_types = JPT_Function; + } + else if( _match_expr.is_attribute() ) { +// if( _match_expr.name().is_trivial() ) { +// _pre_evaluate = PRE_EVAL_ON; +// } + _possible_types = JPT_Variable; + } + else if (_match_expr.is_type ()) { +// if (_match_expr.type().is_trivial_match()) +// _pre_evaluate = PRE_EVAL_ON; + _possible_types = (JoinPointType)( JPT_Class | JPT_Aspect | JPT_Namespace | JPT_Variable | JPT_Function); + } + else + _possible_types = (JoinPointType)0; +} + +void PCE_Match::pre_evaluate (PointCutContext &context) { + if (_match_expr.is_function ()) + pre_evaluate (_match_expr.name (), context); + else if( _match_expr.is_attribute() ) + pre_evaluate( _match_expr.name(), context ); + else if (_match_expr.is_type ()) + pre_evaluate (_match_expr.type().name (), context); +} + +void PCE_Match::pre_evaluate (const MatchName &name, PointCutContext &context) { + ACM_Name *scope = context.jpm().get_root(); + + if( name.scopes() == 0 && name.name() == "::" ) { + _pre_evaluate = PRE_EVAL_DONE; + _jpl = scope; + return; + } + + for (int i = 0; scope && i < name.scopes (); i++) { + scope = map_lookup (*scope, name.scope (i)); + } + _pre_evaluate = PRE_EVAL_OFF; + if (scope) { + if (_match_expr.is_type()) { + _pre_evaluate = PRE_EVAL_DONE; + _jpl = map_lookup (*scope, name.name ()); + } + else if (_match_expr.is_function()) { + _pre_evaluate = PRE_EVAL_DONE; + _jpl = 0; + typedef ACM_Container CList; + const CList &clist = scope->get_children(); + for (CList::const_iterator i = clist.begin (); i != clist.end(); ++i) { + if ((*i)->type_val () != JPT_Function) + continue; + ACM_Function *func = (ACM_Function*)(*i); + if (func->get_kind() == FT_CONSTRUCTOR || + func->get_kind() == FT_DESTRUCTOR || + func->get_kind() == FT_VIRTUAL_DESTRUCTOR || + func->get_kind() == FT_PURE_VIRTUAL_DESTRUCTOR) + continue; + MatchSignature &sig = ((ACM_Function*)(*i))->get_match_sig(); + if (sig.is_new ()) { + if (!sig.parse (signature (*func))) { + continue; + } + if (func->get_kind() == FT_VIRTUAL_MEMBER || + func->get_kind() == FT_PURE_VIRTUAL_MEMBER) + sig.declare_virtual_function(); + else if (func->get_kind() == FT_STATIC_MEMBER || + func->get_kind() == FT_STATIC_NON_MEMBER) { + sig.declare_static(); + } + } + if (_match_expr.matches(sig)) { + if (_jpl) { + _pre_evaluate = PRE_EVAL_OFF; // more than one match :-( + break; + } + _jpl = *i; + } + } + } + else if( _match_expr.is_attribute() ) { + _pre_evaluate = PRE_EVAL_DONE; + _jpl = 0; + + typedef ACM_Container CList; + const CList &clist = scope->get_children(); + for( CList::const_iterator i = clist.begin(); i != clist.end(); i++ ) { + if( (*i)->type_val() != JPT_Variable ) + continue; + ACM_Variable *var = (ACM_Variable*)(*i); + + MatchSignature &sig = var->get_match_sig(); + if( sig.is_new () ) { + if( !sig.parse( signature( *var ) ) ) { + continue; + } + if( var->get_kind() == VT_STATIC_MEMBER || + var->get_kind() == VT_STATIC_NON_MEMBER ) { + sig.declare_static(); + } + } + + if( _match_expr.matches( sig ) ) { + if( _jpl ) { + _pre_evaluate = PRE_EVAL_OFF; // more than one match :-( + break; + } + _jpl = *i; + } + } + } + } + // no match possible at this point + else { + _pre_evaluate = PRE_EVAL_DONE; + _jpl = 0; + } +} + + +bool PCE_Match::evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond) { + assert (!_match_expr.error ()); + + // in case "::" we can immediately return 'true', because it matches the + // global scope and all its potentially nested contents + if (_str == "::") + return true; + + if( &jpl == context.jpm().get_root() ) + return false; // root namespace is already handled in preeval completely + + bool result = false; + if (jpl.type_val () == JPT_Type) { + if (_match_expr.is_type ()) { + ACM_Type &jpl_type = (ACM_Type&)jpl; + MatchSignature &match_sig = jpl_type.get_match_sig(); + if (match_sig.is_new()) + match_sig.parse(format_type (jpl_type)); + result = _match_expr.matches (match_sig); + } + } + else if ((jpl.type_val () & JPT_Name) != 0) { + ACM_Name *jpl_name = (ACM_Name*)&jpl; + while (true) { + if( ( jpl_name->type_val() == JPT_Function && _match_expr.is_function() ) + || ( jpl_name->type_val() == JPT_Variable && _match_expr.is_attribute() ) + || ( ( jpl_name->type_val () & (JPT_Class | JPT_Aspect | JPT_Namespace) ) && _match_expr.is_type () ) + ) { + MatchSignature &match_sig = jpl_name->get_match_sig(); + if (match_sig.is_new()) { + if (!match_sig.parse(signature (*jpl_name))) { + cout << "problematic signature: " << signature(*jpl_name) << endl; + assert(false && "Parsing of signature failed. Maybe because of anonymous types? Signature was printed above."); + return false; + } + if (jpl_name->type_val () == JPT_Function) { + ACM_Function& jpl_func = static_cast( *jpl_name ); + if( jpl_func.get_kind() == FT_VIRTUAL_MEMBER || + jpl_func.get_kind() == FT_PURE_VIRTUAL_MEMBER ) + match_sig.declare_virtual_function(); + else if( jpl_func.get_kind() == FT_STATIC_MEMBER || + jpl_func.get_kind() == FT_STATIC_NON_MEMBER ) { + match_sig.declare_static(); + } + } + else if( jpl_name->type_val () == JPT_Variable ) { + ACM_Variable &jpl_var = static_cast( *jpl_name ); + if( jpl_var.get_kind() == VT_STATIC_MEMBER || + jpl_var.get_kind() == VT_STATIC_NON_MEMBER ) { + match_sig.declare_static(); + } + } + } + result = _match_expr.matches (match_sig); + + // if we have a match, leave the loop + if (result) + break; + } + + // otherwise check the parent scope of the current name join point, + // but omit the parent classes of nested classes + ACM_Name *parent = (ACM_Name*)jpl_name->get_parent(); + if (jpl_name->type_val () == JPT_Class || jpl_name->type_val () == JPT_Aspect) { + while (parent && (parent->type_val () == JPT_Class || parent->type_val () == JPT_Aspect)) + parent = (ACM_Name*)parent->get_parent(); + } + // root scope detected -> stop here + if (!parent || parent == context.jpm().get_root()) + break; + + // continue by matching the parent scope + jpl_name = parent; + } + } + return result; +} + +void PCE_Match::mangle_type_check (ostream &out) { + const char *str = _str.c_str (); + while (*str) { + switch (*str) { + case ':' : out << "___S___"; break; + case '%' : out << "___A___"; break; + case '(' : out << "___L___"; break; + case ')' : out << "___R___"; break; + case ',': out << "___C___"; break; + default: out << *str; + } + str++; + } +} + diff --git a/AspectC++/PointCutExpr.h b/AspectC++/PointCutExpr.h new file mode 100644 index 0000000..39467cc --- /dev/null +++ b/AspectC++/PointCutExpr.h @@ -0,0 +1,597 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __PointCutExpr_h__ +#define __PointCutExpr_h__ + +#ifdef FRONTEND_PUMA +namespace Puma { + class CTypeInfo; +} +#else // FRONTEND_CLANG +#include "clang/AST/Type.h" +#endif + +#include "Condition.h" +#include "PointCut.h" +#include "ACErrorStream.h" + +#include "ACModel/MatchExpr.h" +#include "ACModel/Elements.h" +#include "ACModel/Utils.h" + +#include +#include +#include "Puma/Array.h" // TODO: replace by STL container + +class Binding; +class PointCutContext; + +// Pointcut expression types are evaluated in a context-independant manner. +// For every pointcut expression a type can always be determined. +enum PCE_Type { + PCE_NAME, // NAME represents a name pointcut + PCE_CODE // CODE represents a code pointcut +}; + +class PointCutExpr : public PointcutExpressionNode { + +protected: + + enum { PRE_EVAL_OFF, PRE_EVAL_ON, PRE_EVAL_DONE } _pre_evaluate; + ACM_Any *_jpl; + JoinPointType _possible_types; + + // do a semantic analysis of the child nodes + void sem_args (ACErrorStream &err, PointCutContext &context, int warn_compat); + + // check if the argument pointcut types are as expected + void check_arg_types (ACErrorStream &err, const char *func, PCE_Type expected, + PointCutContext &context); + + // check if all argument types are equal + void check_arg_types_equal (ACErrorStream &err, const char *func, + PointCutContext &context); + + // get the real argument binding of a context variable + const ACM_Arg *get_binding (const char *name, ACErrorStream &err, + PointCutContext &context); +public: + + PointCutExpr () : _pre_evaluate (PRE_EVAL_OFF), _jpl (0), + _possible_types((JoinPointType)0) {} + virtual ~PointCutExpr () {} + + // Return the type of pointcut described by this expression. This function + // does not check any argument types etc. -> semantics! + virtual PCE_Type type () const = 0; + + // return a bit mask of join point types that could match; others can't! + int possible_types () const { return (int)_possible_types; } + + // run a semantic analysis (e.g. check types) + virtual void semantics (ACErrorStream &err, PointCutContext &context, + int warn_compat) = 0; + + // evaluate an expression, i.e. check if the expression evaluates as 'true' + // for a particular join point + virtual bool evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond) = 0; + + // if the expression supports pre-evaluation, do it in this function + virtual void pre_evaluate (PointCutContext &context) {} + + bool match (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond) { + if (_pre_evaluate == PRE_EVAL_ON) + pre_evaluate(context); + if (_pre_evaluate == PRE_EVAL_OFF) + return evaluate (jpl, context, binding, cond); + return (&jpl == _jpl); + } + + // mangle a string that represents a type check (for that/target arguments) + virtual void mangle_type_check (ostream &) = 0; + + // helper functions to get the right result type + virtual PointCutExpr* duplicate () = 0; + virtual PointCutExpr *arg (int i) const = 0; +}; + +class PCE_SingleArg : public PointCutExpr { + PointCutExpr *_arg; +public: + PCE_SingleArg (PointCutExpr *arg) : _arg (arg) {} + + virtual int args () const { return 1; } + virtual PointCutExpr *arg (int i) const { return (i == 0) ? _arg : 0; } + void replace_arg (PointCutExpr *expr) { if (_arg) _arg->ref(-1); _arg = expr; } + + bool check_derived_class (ACM_Class &cls, + PointCutContext &context, Binding &binding, Condition &cond); + bool check_derived_func (ACM_Class &cls, ACM_Function &func, + PointCutContext &context, Binding &binding, Condition &cond); + bool check_derived_var (ACM_Class &cls, ACM_Variable &var, + PointCutContext &context, Binding &binding, Condition &cond); + bool check_base_class (ACM_Class &cls, PointCutContext &context, + Binding &binding, Condition &cond); + bool check_base_func (ACM_Class &cls, ACM_Function &func, + PointCutContext &context, Binding &binding, Condition &cond); + bool check_base_var (ACM_Class &cls, ACM_Variable &var, + PointCutContext &context, Binding &binding, Condition &cond); + bool check_scopes (ACM_Name *scope, + PointCutContext &context, Binding &binding, Condition &cond); + + virtual void mangle_type_check (ostream &out) { + out << 1; + _arg->mangle_type_check (out); + } +}; + +class PCE_DoubleArg : public PointCutExpr { + PointCutExpr *_args[2]; +public: + PCE_DoubleArg (PointCutExpr *arg0, PointCutExpr *arg1) { + _args[0] = arg0; _args[1] = arg1; + } + virtual int args () const { return 2; } + virtual PointCutExpr *arg (int i) const { + return (i >= 0 && i < 2) ? _args[i] : 0; + } + virtual void mangle_type_check (ostream &out) { + out << 2; + _args[0]->mangle_type_check (out); + _args[1]->mangle_type_check (out); + } +}; + +class PCE_VarArgs : public PointCutExpr { + Puma::Array _args; // TODO: replace by STL container +public: + virtual ~PCE_VarArgs () {} + void add_arg (PointCutExpr *arg) { _args.append (arg); } + virtual int args () const { return _args.length (); } + virtual PointCutExpr *arg (int i) const { return _args.lookup (i); } + virtual void mangle_type_check (ostream &out) { + out << args (); + for (int i = 0; i < args (); i++) + arg (i)->mangle_type_check (out); + } +}; + +class PCE_Classes : public PCE_SingleArg { +public: + PCE_Classes (PointCutExpr *arg) : PCE_SingleArg (arg) {} + virtual PCE_Type type () const; + virtual void semantics (ACErrorStream &err, PointCutContext &context, int warn_compat); + virtual bool evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond); + virtual void mangle_type_check (ostream &out) { + out << "classes_"; + PCE_SingleArg::mangle_type_check (out); + } + virtual PCE_Classes* duplicate () { return new PCE_Classes(arg(0)->duplicate ()); } +}; + +class PCE_Base : public PCE_SingleArg { +public: + PCE_Base (PointCutExpr *arg) : PCE_SingleArg (arg) {} + virtual PCE_Type type () const; + virtual void semantics (ACErrorStream &err, PointCutContext &context, int warn_compat); + virtual bool evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond); + virtual void mangle_type_check (ostream &out) { + out << "base_"; + PCE_SingleArg::mangle_type_check (out); + } + virtual PCE_Base* duplicate () { return new PCE_Base(arg(0)->duplicate ()); } +}; + +class PCE_Derived : public PCE_SingleArg { +public: + PCE_Derived (PointCutExpr *arg) : PCE_SingleArg (arg) {} + virtual PCE_Type type () const; + virtual void semantics (ACErrorStream &err, PointCutContext &context, int warn_compat); + virtual bool evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond); + virtual void mangle_type_check (ostream &out) { + out << "derived_"; + PCE_SingleArg::mangle_type_check (out); + } + virtual PCE_Derived* duplicate () { return new PCE_Derived(arg(0)->duplicate ()); } +}; + +class PCE_Within : public PCE_SingleArg { +public: + PCE_Within (PointCutExpr *arg) : PCE_SingleArg (arg) {} + virtual PCE_Type type () const; + virtual void semantics (ACErrorStream &err, PointCutContext &context, int warn_compat); + virtual bool evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond); + virtual void mangle_type_check (ostream &out) { + out << "within_"; + PCE_SingleArg::mangle_type_check (out); + } + virtual PCE_Within* duplicate () { return new PCE_Within(arg(0)->duplicate ()); } +}; + +class PCE_Member : public PCE_SingleArg { +public: + PCE_Member( PointCutExpr *arg ) : PCE_SingleArg( arg ) {} + virtual PCE_Type type() const; + virtual void semantics( ACErrorStream &err, PointCutContext &context, int warn_compat); + virtual bool evaluate( ACM_Any &jpl, PointCutContext &context, Binding &binding, Condition &cond ); + virtual void mangle_type_check( ostream &out ) { + out << "member_"; + PCE_SingleArg::mangle_type_check( out ); + } + virtual PCE_Member* duplicate () { return new PCE_Member( arg(0)->duplicate () ); } +}; + +class PCE_Execution : public PCE_SingleArg { +public: + PCE_Execution (PointCutExpr *arg) : PCE_SingleArg (arg) {} + virtual PCE_Type type () const; + virtual void semantics (ACErrorStream &err, PointCutContext &context, int warn_compat); + virtual bool evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond); + virtual void mangle_type_check (ostream &out) { + out << "execution_"; + PCE_SingleArg::mangle_type_check (out); + } + virtual PCE_Execution* duplicate () { return new PCE_Execution(arg(0)->duplicate ()); } +}; + +class PCE_Call : public PCE_SingleArg { +public: + PCE_Call (PointCutExpr *arg) : PCE_SingleArg (arg) {} + virtual PCE_Type type () const; + virtual void semantics (ACErrorStream &err, PointCutContext &context, int warn_compat); + virtual bool evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond); + virtual void mangle_type_check (ostream &out) { + out << "call_"; + PCE_SingleArg::mangle_type_check (out); + } + virtual PCE_Call* duplicate () { return new PCE_Call(arg(0)->duplicate ()); } +}; + +class PCE_Builtin : public PCE_SingleArg { +public: + PCE_Builtin (PointCutExpr *arg) : PCE_SingleArg (arg) {} + virtual PCE_Type type () const; + virtual void semantics (ACErrorStream &err, PointCutContext &context, int warn_compat); + virtual bool evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond); + virtual void mangle_type_check (ostream &out) { + out << "builtin"; + PCE_SingleArg::mangle_type_check (out); + } + virtual PCE_Builtin* duplicate () { return new PCE_Builtin(arg(0)->duplicate ()); } +}; + +class PCE_Get : public PCE_SingleArg { +public: + PCE_Get( PointCutExpr *arg ) : PCE_SingleArg( arg ) {} + virtual PCE_Type type () const; + virtual void semantics( ACErrorStream &err, PointCutContext &context, int warn_compat); + virtual bool evaluate( ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond ); + virtual void mangle_type_check( ostream &out ) { + out << "get_"; + PCE_SingleArg::mangle_type_check( out ); + } + virtual PCE_Get* duplicate() { return new PCE_Get( arg(0)->duplicate() ); } +}; + +class PCE_Set : public PCE_SingleArg { +public: + PCE_Set( PointCutExpr *arg ) : PCE_SingleArg( arg ) {} + virtual PCE_Type type () const; + virtual void semantics( ACErrorStream &err, PointCutContext &context, int warn_compat); + virtual bool evaluate( ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond ); + virtual void mangle_type_check( ostream &out ) { + out << "set_"; + PCE_SingleArg::mangle_type_check( out ); + } + virtual PCE_Set* duplicate() { return new PCE_Set( arg(0)->duplicate() ); } +}; + +class PCE_Ref : public PCE_SingleArg { +public: + PCE_Ref( PointCutExpr *arg ) : PCE_SingleArg( arg ) {} + virtual PCE_Type type () const; + virtual void semantics( ACErrorStream &err, PointCutContext &context, int warn_compat); + virtual bool evaluate( ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond ); + virtual void mangle_type_check( ostream &out ) { + out << "ref_"; + PCE_SingleArg::mangle_type_check( out ); + } + virtual PCE_Ref* duplicate() { return new PCE_Ref( arg(0)->duplicate() ); } +}; + +class PCE_Alias : public PCE_SingleArg { +public: + PCE_Alias( PointCutExpr *arg ) : PCE_SingleArg( arg ) {} + virtual PCE_Type type () const; + virtual void semantics( ACErrorStream &err, PointCutContext &context, int warn_compat); + virtual bool evaluate( ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond ); + virtual void mangle_type_check( ostream &out ) { + out << "alias_"; + PCE_SingleArg::mangle_type_check( out ); + } + virtual PCE_Alias* duplicate() { return new PCE_Alias( arg(0)->duplicate() ); } +}; + +class PCE_Construction : public PCE_SingleArg { +public: + PCE_Construction (PointCutExpr *arg) : PCE_SingleArg (arg) {} + virtual PCE_Type type () const; + virtual void semantics (ACErrorStream &err, PointCutContext &context, int warn_compat); + virtual bool evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond); + virtual void mangle_type_check (ostream &out) { + out << "construction_"; + PCE_SingleArg::mangle_type_check (out); + } + virtual PCE_Construction* duplicate () { return new PCE_Construction(arg(0)->duplicate ()); } +}; + +class PCE_Destruction : public PCE_SingleArg { +public: + PCE_Destruction (PointCutExpr *arg) : PCE_SingleArg (arg) {} + virtual PCE_Type type () const; + virtual void semantics (ACErrorStream &err, PointCutContext &context, int warn_compat); + virtual bool evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond); + virtual void mangle_type_check (ostream &out) { + out << "destruction_"; + PCE_SingleArg::mangle_type_check (out); + } + virtual PCE_Destruction* duplicate () { return new PCE_Destruction(arg(0)->duplicate ()); } +}; + +class PCE_That : public PCE_SingleArg { +public: + PCE_That (PointCutExpr *arg) : PCE_SingleArg (arg) {} + virtual PCE_Type type () const; + virtual void semantics (ACErrorStream &err, PointCutContext &context, int warn_compat); + virtual bool evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond); + virtual void mangle_type_check (ostream &out) { + out << "that_"; + PCE_SingleArg::mangle_type_check (out); + } + virtual PCE_That* duplicate () { return new PCE_That(arg(0)->duplicate ()); } +}; + +class PCE_Target : public PCE_SingleArg { +public: + PCE_Target (PointCutExpr *arg) : PCE_SingleArg (arg) {} + virtual PCE_Type type () const; + virtual void semantics (ACErrorStream &err, PointCutContext &context, int warn_compat); + virtual bool evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond); + virtual void mangle_type_check (ostream &out) { + out << "target_"; + PCE_SingleArg::mangle_type_check (out); + } + virtual PCE_Target* duplicate () { return new PCE_Target(arg(0)->duplicate ()); } +}; + +class PCE_CFlow : public PCE_SingleArg { + int _index; + PointCut _arg_pointcut; +public: + PCE_CFlow (PointCutExpr *arg) : PCE_SingleArg (arg) {} + virtual ~PCE_CFlow () {} + virtual PCE_Type type () const; + PointCut &arg_pointcut () { return _arg_pointcut; } + virtual void semantics (ACErrorStream &err, PointCutContext &context, int warn_compat); + virtual bool evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond); + virtual void mangle_type_check (ostream &out) { + out << "cflow_"; + PCE_SingleArg::mangle_type_check (out); + } + virtual PCE_CFlow* duplicate () { return new PCE_CFlow(arg(0)->duplicate ()); } +}; + +class PCE_Args : public PCE_VarArgs { + bool _both_sc_args_bound_warning_created; + bool _sc_arg_bound_warning_created; +public: + PCE_Args () : _both_sc_args_bound_warning_created(false), + _sc_arg_bound_warning_created(false) {} + PCE_Args (bool both_sc_args_bound_warning_created, + bool sc_arg_bound_warning_created) : + _both_sc_args_bound_warning_created(both_sc_args_bound_warning_created), + _sc_arg_bound_warning_created(sc_arg_bound_warning_created){} + virtual ~PCE_Args () {} + virtual PCE_Type type () const; + virtual void semantics (ACErrorStream &err, PointCutContext &context, int warn_compat); + virtual bool evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond); + virtual void mangle_type_check (ostream &out) { + out << "args_"; + PCE_VarArgs::mangle_type_check (out); + } + virtual PCE_Args* duplicate () { + PCE_Args *result = new PCE_Args(_both_sc_args_bound_warning_created, + _sc_arg_bound_warning_created); + for (int i = 0; i < args(); i++) + result->add_arg(arg(i)->duplicate ()); + return result; + } +}; + +class PCE_Result : public PCE_SingleArg { +public: + PCE_Result (PointCutExpr *arg) : PCE_SingleArg (arg) {} + virtual PCE_Type type () const; + virtual void semantics (ACErrorStream &err, PointCutContext &context, int warn_compat); + virtual bool evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond); + virtual void mangle_type_check (ostream &out) { + out << "result_"; + PCE_SingleArg::mangle_type_check (out); + } + virtual PCE_Result* duplicate () { return new PCE_Result(arg(0)->duplicate ()); } +}; + +class PCE_Or : public PCE_DoubleArg { +public: + PCE_Or (PointCutExpr *arg0, PointCutExpr *arg1) : + PCE_DoubleArg (arg0, arg1) {} + virtual PCE_Type type () const; + virtual void semantics (ACErrorStream &err, PointCutContext &context, int warn_compat); + virtual bool evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond); + virtual void mangle_type_check (ostream &out) { + out << "or_"; + PCE_DoubleArg::mangle_type_check (out); + } + virtual PCE_Or* duplicate () { return new PCE_Or(arg(0)->duplicate (), arg(1)->duplicate()); } +}; + +class PCE_And : public PCE_DoubleArg { +public: + PCE_And (PointCutExpr *arg0, PointCutExpr *arg1) : + PCE_DoubleArg (arg0, arg1) {} + virtual PCE_Type type () const; + virtual void semantics (ACErrorStream &err, PointCutContext &context, int warn_compat); + virtual bool evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond); + virtual void mangle_type_check (ostream &out) { + out << "and_"; + PCE_DoubleArg::mangle_type_check (out); + } + virtual PCE_And* duplicate () { return new PCE_And(arg(0)->duplicate (), arg(1)->duplicate()); } +}; + +class PCE_Not : public PCE_SingleArg { +public: + PCE_Not (PointCutExpr *arg) : PCE_SingleArg (arg) {} + virtual PCE_Type type () const; + virtual void semantics (ACErrorStream &err, PointCutContext &context, int warn_compat); + virtual bool evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond); + virtual void mangle_type_check (ostream &out) { + out << "not_"; + PCE_SingleArg::mangle_type_check (out); + } + virtual PCE_Not* duplicate () { return new PCE_Not(arg(0)->duplicate ()); } +}; + +class PCE_Named : public PointCutExpr { + ACM_Pointcut *_pct_func; + PointcutExpression _expr; + std::list _params; +public: + PCE_Named (ACM_Pointcut *pct_func) : _pct_func (pct_func) {} + virtual PCE_Type type () const; + std::list ¶ms () { return _params; } + PointcutExpression &expr () { return _expr; } + virtual int args () const { return 0; } + virtual PointCutExpr *arg (int) const { return 0; } + virtual void semantics (ACErrorStream &err, PointCutContext &context, int warn_compat); + virtual bool evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond); + virtual void mangle_type_check (ostream &out) { + out << "named_"; + ((PointCutExpr*)_expr.get())->mangle_type_check (out); + } + virtual PCE_Named* duplicate () { + PCE_Named *result = new PCE_Named(_pct_func); + result->_expr = _expr; + result->_params = _params; + return result; + } +}; + +class PCE_CXX11Attr : public PointCutExpr { + ACM_Attribute *_pct_attr; + std::list _params; +public: + PCE_CXX11Attr ( ACM_Attribute *pct_attr ) : _pct_attr(pct_attr) {} + + virtual PCE_Type type () const {return PCE_NAME;} + std::list ¶ms () { return _params; } + virtual int args() const {return 0;} //Is this right? + virtual PointCutExpr *arg(int) const {return 0;} //Is this right? + virtual void semantics (ACErrorStream &err, PointCutContext &context, int warn_compat); + virtual bool evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond); + virtual void mangle_type_check (ostream &out) { + out << "named_"; + arg(0)->mangle_type_check (out); + } + virtual PCE_CXX11Attr* duplicate () { + PCE_CXX11Attr *result = new PCE_CXX11Attr(_pct_attr); + result->_params = _params; + return result; + } +}; + +class PCE_ContextVar : public PointCutExpr { + string _name; + const ACM_Arg *_bound_arg; +#ifdef FRONTEND_PUMA // TODO: get rid of frontend types here + const Puma::CTypeInfo *_check_type; +#else // FRONTEND_CLANG + clang::QualType _check_type; +#endif + enum { CV_THAT, CV_TARGET, CV_ARG, CV_RESULT } _bound_to; + int _arg; +public: + PCE_ContextVar (const string &name) : _name (name) {} + virtual int args () const { return 0; } + virtual PointCutExpr *arg (int) const { return 0; } + virtual PCE_Type type () const; + virtual void semantics (ACErrorStream &err, PointCutContext &context, int warn_compat); + virtual bool evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond); + virtual void mangle_type_check (ostream &out); + virtual PCE_ContextVar* duplicate () { return new PCE_ContextVar(_name); } +}; + +class PCE_Match : public PointCutExpr { + MatchExpr _match_expr; + string _str; +public: + PCE_Match (const string &str) : _str (str) {} + virtual ~PCE_Match () {} + virtual int args () const { return 0; } + virtual PointCutExpr *arg (int) const { return 0; } + virtual PCE_Type type () const; + virtual void semantics (ACErrorStream &err, PointCutContext &context, int warn_compat); + bool parse (); + + // if the expression supports pre-evaluation, do it in this function + virtual void pre_evaluate (PointCutContext &context); + void pre_evaluate (const MatchName &name, PointCutContext &context); + virtual bool evaluate (ACM_Any &jpl, PointCutContext &context, + Binding &binding, Condition &cond); + virtual void mangle_type_check (ostream &out); + virtual PCE_Match* duplicate () { ref(1); return this; } +}; + +#endif // __PointCutExpr_h__ diff --git a/AspectC++/PointCutExprParser.cc b/AspectC++/PointCutExprParser.cc new file mode 100644 index 0000000..bf96bef --- /dev/null +++ b/AspectC++/PointCutExprParser.cc @@ -0,0 +1,370 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "PointCutExprParser.h" +#include "PointCutExpr.h" +#include "PointCutSearcher.h" +#include "TransformInfo.h" + +#include +using namespace std; + +// TODO: exceptions cause memory leak; objects on the heap are not freed +struct PCEParserException : exception { + string _what; + PCEParserException(const string &s) : _what(s) {} + ~PCEParserException() throw() {} + const char* what() const throw() { return _what.c_str (); } +}; + +enum PctTokType { + PCTTOK_EXEC = 1, + PCTTOK_CALL, + PCTTOK_BUILTIN, + PCTTOK_GET, + PCTTOK_SET, + PCTTOK_REF, + PCTTOK_ALIAS, + PCTTOK_CONSTRUCTION, + PCTTOK_DESTRUCTION, + PCTTOK_CLASSES, + PCTTOK_WITHIN, + PCTTOK_MEMBER, + PCTTOK_BASE, + PCTTOK_DERIVED, + PCTTOK_THAT, + PCTTOK_TARGET, + PCTTOK_ARGS, + PCTTOK_RESULT, + PCTTOK_CFLOW, + PCTTOK_MATCHEXPR, + PCTTOK_OPEN, + PCTTOK_CLOSE, + PCTTOK_OR, + PCTTOK_AND, + PCTTOK_NOT, + PCTTOK_COMMA, + PCTTOK_COLON_COLON, + PCTTOK_ID +}; + +PointCutExprParser::PointCutExprParser( ACConfig &config ) : config_(config) { + lexertl::rules rules; + rules.push ("execution", PCTTOK_EXEC); + rules.push ("call", PCTTOK_CALL); + if( config.data_joinpoints() ) { + rules.push( "get", PCTTOK_GET ); + rules.push( "set", PCTTOK_SET ); + rules.push( "ref", PCTTOK_REF ); + rules.push( "alias", PCTTOK_ALIAS ); + } + if( config.builtin_operators() ) { + rules.push( "builtin", PCTTOK_BUILTIN ); + } + rules.push ("construction", PCTTOK_CONSTRUCTION); + rules.push ("destruction", PCTTOK_DESTRUCTION); + rules.push ("classes", PCTTOK_CLASSES); + rules.push ("within", PCTTOK_WITHIN); + rules.push( "member", PCTTOK_MEMBER ); + rules.push ("base", PCTTOK_BASE); + rules.push ("derived", PCTTOK_DERIVED); + rules.push ("that", PCTTOK_THAT); + rules.push ("target", PCTTOK_TARGET); + rules.push ("args", PCTTOK_ARGS); + rules.push ("result", PCTTOK_RESULT); + rules.push ("cflow", PCTTOK_CFLOW); + rules.push ("\\\"([^\\\\\\\"]|\\\\.)*\\\"", PCTTOK_MATCHEXPR); + rules.push ("\\(", PCTTOK_OPEN); + rules.push ("\\)", PCTTOK_CLOSE); + rules.push ("\\|\\|", PCTTOK_OR); + rules.push ("&&", PCTTOK_AND); + rules.push ("!", PCTTOK_NOT); + rules.push (",", PCTTOK_COMMA); + rules.push ("::", PCTTOK_COLON_COLON); + rules.insert_macro("Hex", "[0-9a-fA-F]"); + rules.insert_macro ("UniversalChar", "\\\\(u{Hex}{4}|U{Hex}{8})"); + rules.insert_macro ("Alpha", "[a-zA-Z_\\$]|{UniversalChar}"); + rules.push ("{Alpha}({Alpha}|\\d)*", PCTTOK_ID); + + lexertl::generator::build (rules, state_machine_); +} + +PointCutExpr *PointCutExprParser::parse (const string &input, + PointCutSearcher &searcher) { + string::const_iterator iter = input.begin (); + string::const_iterator end = input.end (); + lexertl::smatch results (iter, end); + + lexertl::lookup (state_machine_, results); + PointCutExpr *result = parse_or_expr (results, searcher); + if (!result) + throw PCEParserException("Pointcut expression parser failed"); + if (results.id != 0) + throw PCEParserException("Input after end of pointcut expression"); + return result; +} + +PointCutExpr *PointCutExprParser::parse_or_expr (lexertl::smatch &results, + PointCutSearcher &searcher) { + + PointCutExpr *result = parse_and_expr (results, searcher); + while (results.id == PCTTOK_OR) { + lexertl::lookup (state_machine_, results); + PointCutExpr *r = parse_and_expr (results, searcher); + if (!r) return 0; + result = new PCE_Or(result, r); + } + return result; +} + +PointCutExpr *PointCutExprParser::parse_and_expr (lexertl::smatch &results, + PointCutSearcher &searcher) { + + PointCutExpr *result = parse_unary_expr (results, searcher); + while (results.id == PCTTOK_AND) { + lexertl::lookup (state_machine_, results); + PointCutExpr *r = parse_unary_expr (results, searcher); + if (!r) return 0; + result = new PCE_And(result, r); + } + return result; +} + +PointCutExpr *PointCutExprParser::parse_unary_expr (lexertl::smatch &results, + PointCutSearcher &searcher) { + + PointCutExpr *result = parse_primary_expr (results, searcher); + if (result) return result; + + PointCutExpr *r = 0; + switch (results.id) { + case PCTTOK_NOT: + lexertl::lookup (state_machine_, results); + r = parse_unary_expr (results, searcher); + if (!r) return 0; + result = new PCE_Not (r); + break; + case PCTTOK_EXEC: + case PCTTOK_CALL: + case PCTTOK_BUILTIN: + case PCTTOK_GET: + case PCTTOK_SET: + case PCTTOK_REF: + case PCTTOK_ALIAS: + case PCTTOK_CONSTRUCTION: + case PCTTOK_DESTRUCTION: + case PCTTOK_BASE: + case PCTTOK_DERIVED: + case PCTTOK_THAT: + case PCTTOK_TARGET: + case PCTTOK_CLASSES: + case PCTTOK_WITHIN: + case PCTTOK_MEMBER: + case PCTTOK_ARGS: + case PCTTOK_RESULT: + case PCTTOK_CFLOW: + string pct_func = string (results.start, results.end); + unsigned long tt = results.id; + lexertl::lookup (state_machine_, results); + if (results.id != PCTTOK_OPEN) + throw PCEParserException(string("Pointcut function '") + pct_func + + "' requires opening bracket"); + lexertl::lookup (state_machine_, results); + vector arguments; + while (true) { + PointCutExpr *r = parse_or_expr (results, searcher); + if (!r) break; + arguments.push_back (r); + if (results.id != PCTTOK_COMMA) + break; + lexertl::lookup (state_machine_, results); + } + if (tt != PCTTOK_ARGS && arguments.size () != 1) return 0; + if (tt == PCTTOK_CALL) + result = new PCE_Call (arguments[0]); + else if (tt == PCTTOK_BUILTIN) + result = new PCE_Builtin(arguments[0]); + else if( tt == PCTTOK_GET ) + result = new PCE_Get( arguments[0] ); + else if( tt == PCTTOK_SET ) + result = new PCE_Set( arguments[0] ); + else if( tt == PCTTOK_REF ) + result = new PCE_Ref( arguments[0] ); + else if( tt == PCTTOK_ALIAS ) + result = new PCE_Alias( arguments[0] ); + else if (tt == PCTTOK_EXEC) + result = new PCE_Execution (arguments[0]); + else if (tt == PCTTOK_CONSTRUCTION) + result = new PCE_Construction (arguments[0]); + else if (tt == PCTTOK_DESTRUCTION) + result = new PCE_Destruction (arguments[0]); + else if (tt == PCTTOK_BASE) + result = new PCE_Base (arguments[0]); + else if (tt == PCTTOK_DERIVED) + result = new PCE_Derived (arguments[0]); + else if (tt == PCTTOK_THAT) + result = new PCE_That (arguments[0]); + else if (tt == PCTTOK_TARGET) + result = new PCE_Target (arguments[0]); + else if (tt == PCTTOK_CLASSES) + result = new PCE_Classes (arguments[0]); + else if (tt == PCTTOK_WITHIN) + result = new PCE_Within (arguments[0]); + else if( tt == PCTTOK_MEMBER ) + result = new PCE_Member( arguments[0] ); + else if (tt == PCTTOK_RESULT) + result = new PCE_Result (arguments[0]); + else if (tt == PCTTOK_CFLOW) + result = new PCE_CFlow (arguments[0]); + else if (tt == PCTTOK_ARGS) { + PCE_Args *pce_args = new PCE_Args; + for (vector::iterator i = arguments.begin (); + i != arguments.end(); ++i) + pce_args->add_arg(*i); + result = pce_args; + } + + if (results.id != PCTTOK_CLOSE) + throw PCEParserException("Closing bracket missing"); + lexertl::lookup (state_machine_, results); + break; + } + return result; +} + +PointCutExpr *PointCutExprParser::parse_primary_expr (lexertl::smatch &results, + PointCutSearcher &searcher) { + + PointCutExpr *result = 0; + string match_expr; + switch (results.id) { + case PCTTOK_MATCHEXPR: + do { + match_expr += string (results.start+1, results.end-1); + lexertl::lookup (state_machine_, results); + } while (results.id == PCTTOK_MATCHEXPR); + result = new PCE_Match(match_expr); + if (!((PCE_Match*)result)->parse ()) + throw PCEParserException("Invalid match expression"); + break; + case PCTTOK_OPEN: + lexertl::lookup (state_machine_, results); + result = parse_or_expr (results, searcher); + if (!result) return 0; + if (results.id != PCTTOK_CLOSE) + throw PCEParserException("Closing bracket missing"); + lexertl::lookup (state_machine_, results); + break; + case PCTTOK_ID: + case PCTTOK_COLON_COLON: + vector qual_name; + bool root_qualified = false; + if (results.id == PCTTOK_COLON_COLON) { + root_qualified = true; + lexertl::lookup (state_machine_, results); + } + if (results.id != PCTTOK_ID) + return 0; + string id (results.start, results.end); + qual_name.push_back (id); + lexertl::lookup (state_machine_, results); + while (results.id == PCTTOK_COLON_COLON) { + lexertl::lookup (state_machine_, results); + if (results.id != PCTTOK_ID) + return 0; + id = string(results.start, results.end); + qual_name.push_back (id); + lexertl::lookup (state_machine_, results); + } + if (results.id == PCTTOK_OPEN) { + lexertl::lookup (state_machine_, results); + ACM_Pointcut *pct_func = searcher.lookup_pct_func(root_qualified, qual_name); + ACM_Attribute *pct_attr = searcher.lookup_pct_attr(root_qualified, qual_name); + + if(pct_func && pct_attr && config_.attributes()) { + string msg = "Declarations of named pointcut and attribute'"; + msg += id; + msg += "' are ambigous! "; + + throw PCEParserException(msg); + } + else if (!pct_func && (!pct_attr || !config_.attributes())) { + string msg = "Named pointcut or attribute '"; + msg += id; + msg += "' not found"; +#ifdef FRONTEND_CLANG + if(id == "builtin" || id == "get" || id == "set" || id == "ref" || id == "alias") { + msg += ". If you meant the "; + msg += id; + msg += " pointcut function, then enable it by adding the '"; + if(id == "builtin") { + msg += "--builtin_operators"; + } + else { + msg += "--data_joinpoints"; + } + msg += "' command-line argument"; + } +#endif // FRONTEND_CLANG + throw PCEParserException(msg); + } +#ifdef FRONTEND_CLANG + else if(config_.warn_deprecated() && + (id == "builtin" || id == "get" || id == "set" || id == "ref" || id == "alias") + ) { + config_.project().err() << Puma::sev_warning << "named pointcuts with one of the " + "names 'alias', 'builtin', 'get', 'ref' or 'set' are deprecated as they " + "name new predefined pointcut functions. These new poincut functions are " + "currently disabled by default but this will change with one of the next " + "releases." << Puma::endMessage; + } +#endif // FRONTEND_CLANG + + if(pct_attr && config_.attributes()) { + result = new PCE_CXX11Attr(pct_attr); + lexertl::lookup (state_machine_, results); // consume ')' + } + else { + PCE_Named *call = new PCE_Named(pct_func); // just needed for the right type + bool first = true; + while (results.id != 0 && results.id != PCTTOK_CLOSE) { + if (!first) { + if (results.id != PCTTOK_COMMA) + throw PCEParserException("Invalid argument list, comma expected"); + lexertl::lookup (state_machine_, results); + } + if (results.id != PCTTOK_ID) + throw PCEParserException("Invalid argument list, argument name expected"); + string varname (results.start, results.end); + call->params().push_back(varname); + first = false; + lexertl::lookup (state_machine_, results); + } + if (results.id == 0) + return 0; + lexertl::lookup (state_machine_, results); // consume ')' + result = call; + } + } + else { + result = new PCE_ContextVar(id); + } + break; + } + return result; +} diff --git a/AspectC++/PointCutExprParser.h b/AspectC++/PointCutExprParser.h new file mode 100644 index 0000000..937380d --- /dev/null +++ b/AspectC++/PointCutExprParser.h @@ -0,0 +1,52 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __point_cut_expr_parser_h__ +#define __point_cut_expr_parser_h__ + +#include +#include "ACConfig.h" + +#include "lexertl/generator.hpp" +#include "lexertl/lookup.hpp" +#include "lexertl/rules.hpp" +#include "lexertl/state_machine.hpp" + +class PointCutExpr; +class PointCutSearcher; + +class PointCutExprParser { + lexertl::state_machine state_machine_; + ACConfig &config_; + + // private constructor; this is a singleton + PointCutExprParser( ACConfig &config ); + PointCutExpr *parse_or_expr (lexertl::smatch &, PointCutSearcher &searcher); + PointCutExpr *parse_and_expr (lexertl::smatch &, PointCutSearcher &searcher); + PointCutExpr *parse_unary_expr (lexertl::smatch &, PointCutSearcher &searcher); + PointCutExpr *parse_primary_expr (lexertl::smatch &, PointCutSearcher &searcher); + +public: + static PointCutExprParser *instance( ACConfig &config ) { + static PointCutExprParser inst( config ); + return &inst; + } + PointCutExpr *parse (const std::string &input, PointCutSearcher &searcher); +}; + +#endif // __point_cut_expr_parser_h__ diff --git a/AspectC++/PointCutSearcher.h b/AspectC++/PointCutSearcher.h new file mode 100644 index 0000000..689283f --- /dev/null +++ b/AspectC++/PointCutSearcher.h @@ -0,0 +1,35 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __point_cut_searcher_h__ +#define __point_cut_searcher_h__ + +#include +#include +class ACM_Pointcut; +class ACM_Attribute; + +class PointCutSearcher { +public: + virtual ACM_Pointcut *lookup_pct_func (bool root_qualified, std::vector &qual_name) = 0; + virtual ACM_Attribute *lookup_pct_attr (bool root_qualified, std::vector &qual_name) = 0; +// virtual bool lookup_context_var(const std::string &name) = 0; + virtual ~PointCutSearcher() {} +}; + +#endif // __point_cut_searcher_h__ diff --git a/AspectC++/PumaIncludeExpander.cc b/AspectC++/PumaIncludeExpander.cc new file mode 100644 index 0000000..797933c --- /dev/null +++ b/AspectC++/PumaIncludeExpander.cc @@ -0,0 +1,242 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "PumaIncludeExpander.h" +#include "LineDirectiveMgr.h" + +#include "Puma/PreTreeNodes.h" +#include "Puma/PreSonIterator.h" +#include "Puma/MacroUnit.h" +#include "Puma/FileUnit.h" +#include "Puma/CProject.h" +#include "Puma/UnitManager.h" +#include "Puma/CCParser.h" +#include "Puma/CTranslationUnit.h" +#include "Puma/Token.h" +#include "Puma/Location.h" +using namespace Puma; + +void PumaIncludeExpander::expand (const char *file) { + + // clear the resulting unit + _unit.List::clear (); + + // preprocess the translation unit + Unit *unit = _project.unitManager ().get (file, true); + + // return if the unit is empty (strange property of the UnitManager!) + if (!unit || !unit->first ()) + return; + + // ok, we have a unit to expand + _root = unit; + + // silently run the preprocessor + CCParser parser; + CTranslationUnit *tunit = parser.parse (*_root , _project, 2); + + _depth = 0; + _ext_depth = 0; + _files.push (File (_root)); + + // search for include and manipulate them -> fills _tree and _nodes + iterateNodes (tunit->cpp_tree ()); + + // cleanup + delete tunit; + + // rewind the include stack until we are back at the input file + rewind (0); + + // write the rest of the main unit + finish (); +} + +// Go through the nodes. +void PumaIncludeExpander::iterateNodes (PreTree* node) { + PreSonIterator i (node); // the order is important! + + for (i.first (); ! i.isDone (); i.next ()) + i.currentItem ()->accept (*this); +} + +// expand tokens from a unit (write them into the result unit) +void PumaIncludeExpander::write (Unit *unit, ACToken first, ACToken last) { + ACUnit linedir (_err); + if (_line_mgr.directive (linedir, unit, first)) { + linedir << endu; + linedir.cut (_unit, (Token*)linedir.first (), (Token*)linedir.last ()); + } + // copy the tokens + ACToken curr = first; + while (curr) { + // filter out #pragma once + if (curr.is_directive () && strcmp ("#pragma", curr.text ()) == 0) { + ACToken dir ((Token*)unit->next (curr.get())); + bool have_pragma_once = false; + while (dir && dir.is_directive () && strcmp ("#pragma", dir.text ()) != 0) { + if (strcmp ("once", dir.text ()) == 0) { + have_pragma_once = true; + break; + } + dir = ACToken ((Token*)unit->next (dir.get())); + } + if (have_pragma_once && dir) + curr = ACToken ((Token*)unit->next (dir.get())); + } + if (!curr) + break; + _unit.append (*(Token*)curr.get()->duplicate ()); + if (curr == last) + break; + curr = ACToken ((Token*)unit->next (curr.get())); + } +// List *copy = unit->copy (first, last); +// copy->cut (_unit, (Token*)copy->first (), (Token*)copy->last ()); +// delete copy; +} + +// write a string into the unit +void PumaIncludeExpander::write (const char *str) { + ACUnit str_unit (_err); + str_unit << str << endu; + str_unit.cut (_unit, (Token*)str_unit.first (), (Token*)str_unit.last ()); +} + +// print the rest of the topmost unit +void PumaIncludeExpander::finish () { + ACToken first = _files.top ()._next; + ACToken last (_files.top ()._unit->last ()); + if (first) { + write (_files.top ()._unit, first, last); + if (!last.get ()->is_whitespace ()) { + const char *text = last.text (); + if (text[strlen (text) - 1] != '\n' && text[strlen (text) - 1] != '\r') + write ("\n"); // TODO: use Windows or Mac line endings on these platforms? Or guess? + } + } +} + +// pop elements from the include stack until 'up_to' is the top +void PumaIncludeExpander::rewind (int up_to) { + while (_depth > up_to) { + finish (); + _files.pop (); + _depth--; + } +} + +// handle include directive node +void PumaIncludeExpander::visitPreIncludeDirective_Pre (PreIncludeDirective* node) +{ + // this_unit is the unit where the include directive is located + ACToken this_token (node->startToken ()); + Unit *this_unit = this_token.unit (); +// cout << "in " << this_unit->name () << " " << this_token->location () << " " +// << _project.isBelow (this_unit) << endl; + + // manipulate project files only (and forced includes) + if (_project.isBelow (this_unit) || this_unit == _root) { + + // include if expanded by preprocessor + if (node->daughters () == 1) { + + Unit *included_unit = ((PreInclSemNode*)node->daughter (0))->unit (); + bool included_below = _project.isBelow (included_unit); + + // a guarded unit is treaded as if it was not included + // however, system headers are *always* included! + // otherwise varying include relations in system headers on different + // systems could break the ability to compile woven code on another + // platform (e.g. woven Puma sources) + if (included_below && ((PreInclSemNode*)node->daughter (0))->guarded ()) { + included_unit = 0; + } + +// cout << "included: " << included_unit->name () << " " << +// _project.isBelow (included_unit) << endl; + + if (_ext_depth) { +// cout << "node depth = " << node->depth () << endl; +// cout << "ext depth = " << _ext_depth << endl; + if (node->depth () < _ext_depth) { + // we are back! + _ext_depth = 0; +// cout << "cleared last" << endl; + } + else { + // problem: we are in a project file, which was included by an external + return; + } + } + + // expand includes of project files only + if (!included_unit || included_below) { + + if (_depth > node->depth ()) + rewind (node->depth ()); + + // advance the current position up the include + ACToken first = _files.top ()._next; + if (first && first != this_token) { + ACToken last ((Token*)this_unit->prev (this_token.get())); + write (this_unit, first, last); + } + ACToken last = ACToken (node->endToken ()); + // this might be a macro-generated include -> find the correct next tok + if (last.is_macro_generated ()) { + last = ACToken (((MacroUnit*)last.unit ())->ExpansionEnd (last.get())); + assert (last && last.unit () == this_unit); + } + _files.top ()._next = ACToken ((Token*)this_unit->next (last.get())); + + if (included_unit) { + // enter the next include file + _files.push (File (included_unit)); + _depth++; + } + } + else { + // remember that we leave the project now +// cout << "_last = " << this_unit->name () << endl; + if (!_ext_depth) { + _ext_depth = node->depth () + 1; // depth of external includes +// cout << "ext_depth = " << _ext_depth << endl; + } + } + } + // include was e.g. in false ifdef branch + else { +// cout << "no daughter" << endl; + } + } + else { + // in external file! + if (node->daughters () == 1) { + Unit *included_unit = ((PreInclSemNode*)node->daughter (0))->unit (); + if (included_unit && _project.isBelow (included_unit)) { + // oops, an external file includes an internal => error! + _err << sev_error << this_token.location () + << "internal file '" << included_unit->name () + << "' is included by external '" << this_unit->name () << "'" + << endMessage; + return; + } + } + } +} diff --git a/AspectC++/PumaIncludeExpander.h b/AspectC++/PumaIncludeExpander.h new file mode 100644 index 0000000..ecc7ffb --- /dev/null +++ b/AspectC++/PumaIncludeExpander.h @@ -0,0 +1,90 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __puma_include_expander_h__ +#define __puma_include_expander_h__ + +// Visitor, which expands all project-local includes + +#include "Puma/PreVisitor.h" +#include "Puma/BCStack.h" +#include "Puma/Token.h" +#include "Puma/Unit.h" +#include "ACUnit.h" +#include "ACToken.h" +#include "ACErrorStream.h" + +namespace Puma { + class CProject; + class Token; +} // namespace Puma + +class LineDirectiveMgr; + +class PumaIncludeExpander : public Puma::PreVisitor { + + struct File { + Puma::Unit *_unit; + ACToken _next; + File (Puma::Unit *u = 0) : _unit (u), _next (0) { + if (_unit) + _next = ACToken ((Puma::Token*)_unit->first ()); + } + }; + + ACErrorStream &_err; + Puma::CProject &_project; + LineDirectiveMgr &_line_mgr; + ACUnit _unit; + Puma::BCStack _files; + int _depth; + int _ext_depth; + Puma::Unit *_root; + + // Go through the nodes of the syntax tree. + void iterateNodes (Puma::PreTree*); + + // expand tokens from a unit (write them into the result unit) + void write (Puma::Unit *unit, ACToken first, ACToken last); + + // write a string into the unit + void write (const char *str); + + // print the rest of the topmost unit + void finish (); + + // pop elements from the include stack until depth 'up_to' + void rewind (int up_to); + + // Visiting the parts of the preprocessor syntax tree. + + void visitPreIncludeDirective_Pre (Puma::PreIncludeDirective*); + +public: + + PumaIncludeExpander (ACErrorStream &err, Puma::CProject &project, + LineDirectiveMgr &ldm) : + _err (err), _project (project), _line_mgr (ldm), _unit (err), _root (0) {} + + virtual ~PumaIncludeExpander () {} + + void expand (const char *file); + ACUnit &unit () { return _unit; } +}; + +#endif // __puma_include_expander_h__ diff --git a/AspectC++/PumaIntroducer.cc b/AspectC++/PumaIntroducer.cc new file mode 100644 index 0000000..495327a --- /dev/null +++ b/AspectC++/PumaIntroducer.cc @@ -0,0 +1,1274 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 +using std::cout; +using std::endl; +#include +using std::set; + +#include "Puma/CTree.h" +#include "Puma/CObjectInfo.h" +#include "Puma/CFileInfo.h" +#include "Puma/CEnumInfo.h" +#include "Puma/TokenStream.h" +#include "Puma/TokenProvider.h" +#include "Puma/CCSyntax.h" +#include "Puma/CCParser.h" +#include "Puma/PreprocessorParser.h" +#include "Puma/PreMacroManager.h" +#include "Puma/PreFileIncluder.h" +#include "Puma/CPrintVisitor.h" +#include "Puma/StrCol.h" + +#include "PumaIntroducer.h" +#include "ACUnit.h" +#include "Plan.h" +#include "CodeWeaver.h" +#include "LineDirectiveMgr.h" +#include "IncludeGraph.h" +#include "Naming.h" +#include "AspectInfo.h" +#include "OrderInfo.h" +#include "IntroductionInfo.h" +#include "ModelBuilder.h" +#include "ACModel/Utils.h" +#include "PointCutContext.h" +#include "PointCutExpr.h" +#include "IntroductionUnit.h" +#include "TransformInfo.h" + +using namespace Puma; + +// Destructor: release all allocated resources +PumaIntroducer::~PumaIntroducer () { + for (list::iterator i = _token_providers.begin (); + i != _token_providers.end (); ++i) + delete *i; + for (list::iterator i = _token_streams.begin (); + i != _token_streams.end (); ++i) + delete *i; +} + +// called when a new class/union/struct/aspect is created, current scope +// is the global scope +void PumaIntroducer::class_before (CT_ClassDef *cd) { + enter (); + assert (cd); + + // get the semantic object of the class/struct/aspect definition. + // unions are filtered out, as they are of incompatible type CUnionInfo. + // introductions into unions require some extra effort (not implemented yet). + CClassInfo *ci = cd->Object ()->DefObject ()-> ClassInfo (); + if (!ci) { + leave (); + return; + } + + ACProject &project = (ACProject&)*ci->SemDB ()->Project (); + ACErrorStream &err = project.err (); + const Unit *primary = ci->SourceInfo ()->FileInfo ()->Primary (); + + // create the weaving plan for this class + ACM_Class *jpl = create_plan (ci); + if (!jpl || !jpl->has_plan ()) { + // this class is not the target of an introduction + leave (); + return; + } + ACM_ClassPlan *plan = jpl->get_plan (); + + // determine the units that should be included in front of the class + set units; + typedef ACM_Container MContainer; + for (MContainer::iterator i = plan->get_member_intros().begin(); + i != plan->get_member_intros().end(); ++i) { + ACM_ClassSlice *cs = get_slice (*(*i)->get_intro()); + units.insert (&TI_ClassSlice::of (*cs)->slice_unit ()); + } + typedef ACM_Container BContainer; + for (BContainer::iterator i = plan->get_base_intros().begin(); + i != plan->get_base_intros().end(); ++i) { + ACM_ClassSlice *cs = get_slice (*(*i)->get_intro()); + units.insert (&TI_ClassSlice::of (*cs)->slice_unit ()); + } + + const Unit *this_unit = (Unit*)cd->token ()->belonging_to (); + // TODO: this_unit might be a macro unit! + + // handle introductions into introduced classes (nested introductions) + const IntroductionUnit *intro_unit = IntroductionUnit::cast (this_unit); + if (intro_unit) this_unit = intro_unit->final_target_unit (); + +// cout << "included units for " << ci->QualName () << " in " +// << this_unit->name () << " :" << endl; + for (set::iterator iter = units.begin (); + iter != units.end (); ++iter) { + const Unit *slice_unit = *iter; + if (slice_unit == primary) { + if (this_unit != primary) + err << sev_error << cd->token ()->location () + << "affected by aspect in '" << slice_unit->name () + << "'. Move the aspect into a separate aspect header." << endMessage; + } + else if (_ig.includes (slice_unit, this_unit)) { + err << sev_warning << cd->token ()->location () + << "can't include '" << slice_unit->name () + << "' to avoid include cycle" << endMessage; + } + else { +// cout << "new edge from " << this_unit->name () << " to " +// << slice_unit->name () << endl; + _ig.add_edge (this_unit, slice_unit); + + // handling of nested classes -> search the outermost class + CClassInfo *inscls = ci; + while (inscls->Parent ()->ClassInfo ()) + inscls = inscls->Parent ()->ClassInfo (); + + // namespace should be closed and re-opened + ostringstream includes; + _code_weaver.close_namespace (includes, inscls); + + // inspos should be infront of the class + Token *inspos = (Token*)inscls->Tree ()->token (); + + Filename incname = project.getRelInclString (this_unit->name (), slice_unit->name ()); + includes << endl << "#ifndef "; + Naming::guard (includes, (FileUnit*)slice_unit); + includes << endl << "#define "; + Naming::guard (includes, (FileUnit*)slice_unit); + includes << endl; + includes << "#include \"" << incname << "\"" << endl; + includes << "#endif" << endl; + + // re-open the namespace + _code_weaver.open_namespace (includes, inscls); + + string inc (includes.str ()); + _code_weaver.insert (_code_weaver.weave_pos (inspos, WeavePos::WP_BEFORE), + inc); + + if (_included_aspect_headers.find (slice_unit) == + _included_aspect_headers.end ()) { + _included_aspect_headers.insert (slice_unit); + + CCParser *prev_parser = _parser; + _parser = new CCParser; + _parser->introducer (this); + _parser->configure (project.config ()); + // setup the preprocessor + TokenStream stream; + stream.push ((Unit*)slice_unit); + PreprocessorParser *prev_cpp = _cpp; + _cpp = new PreprocessorParser (&project.err (), + &project.unitManager (), prev_cpp->locals()); + _cpp->cscanner ().configure (project.config ()); + // cpp.macroManager ()->init (unit->name ()); + PreMacroManager *old_mm = _cpp->macroManager (); + PreFileIncluder *old_fi = _cpp->fileIncluder (); + PrePredicateManager *old_pm = _cpp->predicateManager (); + _cpp->macroManager (prev_cpp->macroManager ()); + _cpp->fileIncluder (prev_cpp->fileIncluder ()); + _cpp->predicateManager (prev_cpp->predicateManager ()); + _cpp->fileIncluder ()->preprocessor (_cpp); + _cpp->stream (&stream); +// _cpp->configure (project.config (), false); // do not process --include option + + // initialize semantic analyzer + _parser->semantic ().init (*ci->SemDB (), + *ci->SourceInfo ()->FileInfo ()->Primary ()); + ((ErrorCollector&)_parser->builder ().err ()).index (0); + _parser->semantic ().error_sink (_parser->builder ().err ()); + + TokenProvider provider (*_cpp); // look ahead token buffer + CTree *tree = _parser->syntax ().run (provider, &CCSyntax::trans_unit); + if (!tree) + ; +// err << sev_error << cd->token ()->location () +// << "Parsing auto-included header failed." << endMessage; + else + // TODO: tree should later be freed! + _ah_trees.push_back (tree); + + // print all error messages + _parser->builder ().errors (err); +// cout << "--------" << endl; +// CPrintVisitor printer; +// cout << "Printing syntax tree..." << endl; +// printer.print (tree, cout); + + _cpp->macroManager (old_mm); + _cpp->fileIncluder (old_fi); + _cpp->predicateManager (old_pm); + delete _cpp; + _cpp = prev_cpp; + _cpp->fileIncluder ()->preprocessor (_cpp); + delete _parser; + _parser = prev_parser; + } +// else +// cout << "'" << slice_unit->name () << "' not included again!" << endl; + } + } + +// cd->add_intro (tree); + + leave (); +} + +// called when a new class/union/struct/aspect is created +void PumaIntroducer::class_begin (CT_ClassDef *cd) { + enter (); + assert (cd); + leave (); +} + +// parse code that shall be introduced +CTree *PumaIntroducer::parse (list units, bool (CCSyntax::*rule)(), + const char *expected_id, ACErrorStream &err) { + + // create a token stream and push all units onto it + TokenStream *stream = new TokenStream; + _token_streams.push_back (stream); + for (list::reverse_iterator ui = units.rbegin (); + ui != units.rend (); ++ui) + stream->push (*ui); + + // parse it + TokenProvider *provider = new TokenProvider (*stream); // look ahead buffer + _token_providers.push_back (provider); + CTree *tree = _parser->syntax ().run (*provider, rule); + + // print all error messages => does that really work? + _parser->builder ().errors (err); + if (tree && tree->NodeName () != expected_id) + tree = 0; // TODO: tree should be deleted! + return tree; +} + +// called when a new class/union/struct/aspect definition ends +// (still in the class scope) +void PumaIntroducer::class_end (CT_ClassDef *cd) { + enter (); + assert (cd); + bool needs_introspection = _conf.introspection(); // --introspection given? + + // get the semantic object of the class/struct/aspect definition. + // unions are filtered out, as they are of incompatible type CUnionInfo. + // introductions into unions require some extra effort (not implemented yet). + CClassInfo *ci = cd->Object ()->DefObject ()-> ClassInfo (); + if (!ci) { + leave (); + return; + } + + ACErrorStream &err = ci->SemDB ()->Project ()->err (); + // manipulate the code (will be effective after commit), + // paste declaration before "}" of the class definition + Token *inspos = cd->Members ()->end_token (); + const WeavePos &pos = _code_weaver.weave_pos (inspos, WeavePos::WP_BEFORE); + + // first check with the plan if there are intros for this class + ACM_Class *jpl = plan_lookup (ci); + if (jpl) { + // collect the intros + list units; + LineDirectiveMgr &lmgr = _code_weaver.line_directive_mgr (); + gen_intros (jpl, units, err, ci, lmgr, _conf.introduction_depth ()); + for (list::iterator ui = units.begin (); ui != units.end (); ++ui) { + // generate introspection code ("JoinPoint") for this intro + if (IntroductionUnit::cast (*ui)->jp_needed ()) { + insert_introspection_code (cd, IntroductionUnit::cast (*ui)->precedence ()); + needs_introspection = true; // also generate the final introspection + } + + // parse the intro + list tmp_units; + tmp_units.push_back (*ui); + CTree *tree = parse (tmp_units, &CCSyntax::member_spec, CT_MembList::NodeId (), err); + if (tree) { + // move the introduced members into the normal member list + CT_MembList *memb_list = (CT_MembList*)tree; + for (int e = 0; e < memb_list->Entries (); e++) { + CTree *entry = memb_list->Entry (e); + cd->Members ()->InsertSon (cd->Members ()->Sons () - 1, entry); + } + delete memb_list; + + // paste the generated code and add the units to the manipulator's unit mgr. + _code_weaver.insert (pos, *ui); + } + else { + err << sev_error << inspos->location() + << "class member introduction into '" << ci->QualName() << "' failed" + << endMessage; + + // delete all intro units + delete *ui; + } + } + } + + // register all member functions + jpl = 0; + if (_jpm.is_intro_target (ci->DefObject ())) { + // TODO: this condition is not complete correct here: abstract base classes + // that are defined outside the project shall be handled here as well. + // Better check if the current class is in the project model and then add + // its functions. + // return if this class is not an introduction target + // try to register this class (might be a newly introduced class) + jpl = _jpm.register_aspect (ci); + if (!jpl) jpl = _jpm.register_class (ci, 0, false); + + // return if this is either not a valid model class or no valid intro target + if (jpl && jpl->get_intro_target ()) { + for (unsigned f = 0; f < ci->Functions (); f++) { + CFunctionInfo *fi = ci->Function (f)->DefObject (); + if (!_jpm.register_pointcut (fi, jpl)) + _jpm.register_function(fi, jpl); + } + } + } + + // insert introspection code for this class if the configuration option + // --introspection was given or the Joinpoint type was used in an introduction + // -> inserted at the end of the class -> all intros are visible + if (needs_introspection) + insert_introspection_code (cd); + + // handle further generated injections for this class + bool have_injections = false; + ACUnit *unit = new ACUnit (err); + *unit << endl; + + // insert friend declarations for all aspects + have_injections |= insert_aspect_friend_decls (*unit, (CRecord*)ci); + + // insert an 'aspectof' function if this is a non-abstract aspect + // with no user-defined aspectof function + have_injections |= insert_aspectof_function (*unit, ci, err); + + // finalize the unit + *unit << endu; + + // now parse the generated code + if (have_injections) { + ACToken inspos = ACToken (cd->Members ()->end_token ()); + const WeavePos &pos = _code_weaver.weave_pos (inspos, WeavePos::WP_BEFORE); + + list units; + units.push_back (unit); + CTree *tree = parse (units, &CCSyntax::member_spec, CT_MembList::NodeId (), err); + if (tree) { + // move the introduced members into the normal member list + CT_MembList *memb_list = (CT_MembList*)tree; + for (int e = 0; e < memb_list->Entries (); e++) { + CTree *entry = memb_list->Entry (e); + cd->Members ()->InsertSon (cd->Members ()->Sons () - 1, entry); + } + _code_weaver.insert (pos, unit); + delete memb_list; + } + else { + err << sev_error << inspos.location() + << "parsing weaver-injected code for class '" << ci->QualName() + << "' failed" << endMessage; + delete unit; + } + // paste a #line directive + LineDirectiveMgr &lmgr = _code_weaver.line_directive_mgr (); + ACUnit *dunit = new ACUnit (err); + lmgr.directive (*dunit, inspos.unit (), inspos); + *dunit << endu; + if (dunit->empty ()) delete dunit; else _code_weaver.insert (pos, dunit); + } + + // done + leave (); +} + +// insert an 'aspectof' function if this is a non-abstract aspect +// with no user-defined aspectof function +// helper functions +static string prot_str (CProtection::Type prot) { + switch (prot) { + case CProtection::PROT_PRIVATE: return "AC::PROT_PRIVATE"; + case CProtection::PROT_PROTECTED: return "AC::PROT_PROTECTED"; + case CProtection::PROT_PUBLIC: return "AC::PROT_PUBLIC"; + case CProtection::PROT_NONE: return "AC::PROT_NONE"; + } + return 0; +} + +static string spec_str (bool is_static, bool is_mutable, bool is_virtual) { + int pos = 0; + string result; + if (is_static) { + if (pos++) result += "|"; + result += "AC::SPEC_STATIC"; + } + if (is_mutable) { + if (pos++) result += "|"; + result += "AC::SPEC_MUTABLE"; + } + if (is_virtual) { + if (pos++) result += "|"; + result += "AC::SPEC_VIRTUAL"; + } + if (!pos) + result = "AC::SPEC_NONE"; + return result; +} + +// insert friend declarations for all aspects +bool PumaIntroducer::insert_aspectof_function (ACUnit &unit, CClassInfo *ci, + ACErrorStream &err) { + + ACM_Aspect *jpl_aspect = _jpm.register_aspect (ci); + if (!jpl_aspect || ::is_abstract(*jpl_aspect)) { + return false; + } + + // iterate over all member functions and find any definitions of + // 'aspectof' or 'aspectOf' + CFunctionInfo *aspectOf_func = 0; + CFunctionInfo *aspectof_func = 0; + for (unsigned i = 0; i < ci->Functions(); i++) { + CFunctionInfo *fi = ci->Function(i); + if (strcmp (fi->Name (), "aspectof") == 0) + aspectof_func = fi; + if (strcmp (fi->Name (), "aspectOf") == 0) + aspectOf_func = fi; + } + + if (aspectOf_func && !aspectof_func) { + // rename the function to 'aspectof' + CT_FctDef *fctdef = (CT_FctDef*)aspectOf_func->Tree (); + CT_SimpleName *name = ((CT_Declarator*)fctdef->Declarator ())->Name (); + name = name->Name (); // if it is qualified + const WeavePos &name_start = + _code_weaver.weave_pos (name->token (), WeavePos::WP_BEFORE); + const WeavePos &name_end = + _code_weaver.weave_pos (name->end_token (), WeavePos::WP_AFTER); + _code_weaver.replace (name_start, name_end, "aspectof"); + return false; // nothing to introduce + } + + if (!aspectOf_func && !aspectof_func) { + unit << endl + << "public:" << endl + << " static " << ci->Name () << " *aspectof () {" << endl + << " static " << ci->Name () << " __instance;" << endl + << " return &__instance;" << endl + << " }" << endl + << " static " << ci->Name () << " *aspectOf () {" << endl + << " return aspectof ();" << endl + << " }" << endl + << "private:" << endl; + return true; + } + return false; +} + +bool PumaIntroducer::insert_aspect_friend_decls (ACUnit &unit, CRecord *rec) { + // check whether the insertion is indicated for this class or union + + // no need for template instances; the templates already get the friend injection + if (rec->isTemplateInstance()) + return false; + // code introduced by phase 1 (in special namespace AC) is not modified here + if (strncmp (rec->QualName (), "AC::", 4) == 0) + return false; + // nested classes in template instances should also not be modified to avoid double injection + if (_jpm.inside_template_instance(rec)) + return false; + // the class has to belong to the project + Unit *rec_unit = (Unit*)rec->Tree ()->token ()->belonging_to (); + if (!is_intro (rec) && !_jpm.get_project().isBelow (rec_unit)) + return false; + + // OK, perform the insertion ... + + // get all aspects from the join point model + ProjectModel::Selection all_aspects; + _jpm.select (JPT_Aspect, all_aspects); + + // generate the list of aspects + // also make sure that an aspect is not friend of itself! + bool result = false; + for (ProjectModel::Selection::iterator iter = all_aspects.begin (); + iter != all_aspects.end (); ++iter) { + ACM_Aspect &jpl = (ACM_Aspect&)**iter; + if (string (rec->QualName ()) != jpl.get_name()) { + unit << " friend class ::" << jpl.get_name() << ";" << endl; + result = true; + } + } + + return result; +} + +// insert introspection code +// * at the end of class definitions, after AspectC++ introductions +void PumaIntroducer::insert_introspection_code (CT_ClassDef *cd, int precedence) { + if (!cd->Object ()->DefObject ()->ClassInfo()) + return; + + CClassInfo *ci = (CClassInfo*)cd->Object ()->DefObject (); + ACErrorStream &err = ci->SemDB ()->Project ()->err (); + + // return if this class is not an introduction target or has C linkage + if (!_jpm.is_valid_model_class (ci) || !_jpm.is_intro_target (ci) || + ci->Language () == CLanguage::LANG_C) + return; + + // introspection templates cannot be declared inside of a local class + if (ci->isLocalClass()) // integrate check into _jpm.is_valid_model_class ? + return; + + // manipulate the code (will be effective after commit), + // paste declaration before "}" of the class definition + ACToken inspos = ACToken (cd->Members ()->end_token ()); + const WeavePos &pos = _code_weaver.weave_pos (inspos, WeavePos::WP_BEFORE); + + list units; + ACUnit *unit = new ACUnit (err); + unit->name (""); + + *unit << "public:" << endl; + *unit << " struct "; + if (precedence == -1) + *unit << "__TI"; + else + *unit << "__TJP_" << precedence; + *unit << " {" << endl; + + // generate the signature (fully qualified target class name) + *unit << " static const char *signature () { return \""; + ci->TypeInfo ()->TypeText (*unit); + *unit << "\"; }" << endl; + + // generate a 32-bit hash code from the fully qualified target class name + *unit << " enum { HASHCODE = " << StrCol::hash(ci->QualName()) << "U };" << endl; + + // generate a typedef for the target type + *unit << " typedef " << ci->Name () << " That;" << endl; + + // generate a list with all base classes + *unit << " template struct BaseClass {};" << endl; + unsigned b = 0; + for (; b < ci->BaseClasses(); b++) { + *unit << " template struct BaseClass<" << b << ", __D> { typedef "; + ci->BaseClass (b)->Class ()->TypeInfo ()->TypeText (*unit, "Type", true, true, true); + *unit << "; "; + *unit << "static const AC::Protection prot = " << prot_str (ci->BaseClass(b)->Protection ()) << "; "; + *unit << "static const AC::Specifiers spec = (AC::Specifiers)(" + << spec_str (false, false, ci->BaseClass(b)->isVirtual ()) << "); "; + *unit << "};" << endl; + } + *unit << " enum { BASECLASSES = " << b << " };" << endl; + + const char *clsname = ci->Name().c_str(); + // generate Member => a list with all attribute types + *unit << " template struct Member {};" << endl; + unsigned e = 0; + for (unsigned a = 0; a < ci->Attributes (); a++) { + CAttributeInfo *attr = ci->Attribute (a); + if (!is_attribute (attr)) + continue; + *unit << " template struct Member<" << e << ", __D> { typedef "; + attr->TypeInfo ()->TypeText (*unit, "Type", true, true, true); + *unit << "; typedef AC::Referred::type ReferredType; "; + *unit << "static const AC::Protection prot = " << prot_str (attr->Protection ()) << "; "; + *unit << "static const AC::Specifiers spec = (AC::Specifiers)(" + << spec_str (attr->isStatic(), attr->isMutable(), false) << "); "; + // generate pointer => the typed pointer to attribute I + *unit << "static ReferredType *pointer (" << clsname << " *obj = 0) { return (ReferredType*)&"; + if (attr->isStatic()) + *unit << clsname << "::" << attr->Name (); + else + *unit << "obj->" << attr->Name (); + *unit << "; } "; + // generate member_name => the name of attribute i + *unit << "static const char *name () { return \"" << attr->Name () << "\"; }" << endl; + *unit << " }; " << endl; + e++; + } +// *unit << " enum { ELEMENTS = " << e << " };" << endl; + *unit << " enum { MEMBERS = " << e << " };" << endl; + +// // generate member_name => the name of attribute i +// *unit << " static const char *member_name (unsigned i) {"; +// if (ci->Attributes () == 0) { +// *unit << " return 0; }"; +// } +// else { +// *unit << endl << " static const char *names[] = { "; +// bool first = true; +// for (unsigned a = 0; a < ci->Attributes (); a++) { +// if (!is_attribute (ci->Attribute (a))) +// continue; +// if (!first) *unit << ", "; +// *unit << "\"" << ci->Attribute (a)->Name () << "\""; +// first = false; +// } +// *unit << " }; return names[i];" << endl +// << " }"; +// } +// *unit << endl; +// +// // generate member_pointer => the untyped pointer to attribute i +// *unit << " static void *member_pointer (unsigned __i, const " << clsname << " *obj) {"; +// if (ci->Attributes () == 0) { +// *unit << " return 0; }"; +// } +// else { +// *unit << endl +// << " switch (__i) { "; +// e = 0; +// for (unsigned a = 0; a < ci->Attributes (); a++) { +// CAttributeInfo *attr = ci->Attribute (a); +// if (!is_attribute (attr)) +// continue; +// *unit << "case " << e << ": return (void*)&"; +// if (attr->isStatic()) +// *unit << clsname << "::" << attr->Name (); +// else +// *unit << "obj->" << attr->Name (); +// *unit << "; "; +// e++; +// } +// *unit << "default: return 0; }" << endl +// << " }"; +// } +// *unit << endl; + + // generate a list with all member functions + *unit << " template struct Function {};" << endl; + *unit << " template struct Constructor {};" << endl; + *unit << " template struct Destructor {};" << endl; + unsigned int functions=0, constructors=0, destructors=0; + for (unsigned f = 0; f < ci->Functions(); f++) { + CFunctionInfo *fi = ci->Function (f); + if (!_jpm.is_valid_model_function(fi)) + continue; + + if (fi->isConstructor ()) { + *unit << " template struct Constructor<" << constructors << ", __D> { "; + constructors++; + } + else if (fi->isDestructor ()) { + *unit << " template struct Destructor<" << destructors << ", __D> { "; + destructors++; + } + else { + *unit << " template struct Function<" << functions << ", __D> { "; + functions++; + } + + *unit << "static const AC::Protection prot = " << prot_str (fi->Protection ()) << "; "; + *unit << "static const AC::Specifiers spec = (AC::Specifiers)(" + << spec_str (false, false, fi->isVirtual () || fi->overridesVirtual ()) << "); "; + *unit << "};" << endl; + e++; + } + *unit << " enum { FUNCTIONS = " << functions << " };" << endl; + *unit << " enum { CONSTRUCTORS = " << constructors << " };" << endl; + *unit << " enum { DESTRUCTORS = " << destructors << " };" << endl; + + *unit << " };" << endl; + *unit << endu; + +// if (ci->Name()) cout << "Class: " << ci->Name() << endl; +// cout << "Unit:" << endl << *unit << endl; + units.push_back (unit); + CTree *tree = parse (units, &CCSyntax::member_spec, CT_MembList::NodeId (), err); + if (tree) { + // move the introduced members into the normal member list + CT_MembList *memb_list = (CT_MembList*)tree; + for (int e = 0; e < memb_list->Entries (); e++) { + CTree *entry = memb_list->Entry (e); + cd->Members ()->InsertSon (cd->Members ()->Sons () - 1, entry); + } + _code_weaver.insert (pos, unit); + delete memb_list; + } + else { + err << sev_error << inspos.location() + << "parsing introspection code for class '" << ci->QualName() + << "' failed" << endMessage; + delete unit; + } + // paste a #line directive + LineDirectiveMgr &lmgr = _code_weaver.line_directive_mgr (); + ACUnit *dunit = new ACUnit (err); + lmgr.directive (*dunit, inspos.unit (), inspos); + *dunit << endu; + if (dunit->empty ()) delete dunit; else _code_weaver.insert (pos, dunit); +} + + +// checks if an attribute that us returned by the parser is an attribute +// in the sense of the AspectC++ introspection mechnism +bool PumaIntroducer::is_attribute (CAttributeInfo *obj) { + if (obj->isAnonymous () || + obj->EnumeratorInfo () || + // TODO: temporary hack - attributes that have an anonymous type + // shall no be ignored in the type list! + (obj->TypeInfo () && + (obj->TypeInfo ()->isBitField() || + (obj->TypeInfo ()->Record () && obj->TypeInfo ()->Record ()->isAnonymous ()) || + (obj->TypeInfo ()->EnumInfo () && obj->TypeInfo ()->EnumInfo ()->isAnonymous ())))) + return false; + return true; +} + + +// called after the parser tried to parse a base clause +void PumaIntroducer::base_clause_end (CT_ClassDef *cd, Token *open) { + enter (); + assert (cd); + CClassInfo *ci = (CClassInfo*)cd->Object ()->DefObject (); + ACErrorStream &err = ci->SemDB ()->Project ()->err (); + ACToken inspos = ACToken (open); + + // first check with the plan if there are intros for this class + ACM_Class *jpl = plan_lookup (ci); + if (!jpl) { + leave (); + return; + } + + // create a unit with the code that shall be introduced + LineDirectiveMgr &lmgr = _code_weaver.line_directive_mgr (); + + // collect the intros + list units; + gen_base_intros (jpl, units, err, ci, lmgr); + + if (units.size () > 0) { + // parse the introduced code as a base clause + CTree *tree = parse (units, &CCSyntax::base_clause, + CT_BaseSpecList::NodeId (), err); + if (tree) { + cd->BaseIntros (tree); + // manipulate the code (will be effective after commit), + // paste declaration before "{" of the class definition + const WeavePos &pos = _code_weaver.weave_pos (inspos, WeavePos::WP_BEFORE); + // paste the generated code and add the unit to the manipulator's unit mgr. + if (cd->BaseClasses () != 0) { + // get the first introduced base class unit + Unit *first_unit = units.front (); + // delete the ":" token at the beginning of the unit + first_unit->remove ((ListElement*)first_unit->first ()); + // insert "," instead + ACUnit comma (err); + comma << "," << endu; + first_unit->move_before ((ListElement*)first_unit->first (), comma); + } + // now paste all units + for (list::iterator ui = units.begin (); + ui != units.end (); ++ui) + _code_weaver.insert (pos, *ui); + // paste a #line directive + ACUnit *dunit = new ACUnit (err); + lmgr.directive (*dunit, inspos.unit (), inspos); + *dunit << endu; + if (dunit->empty ()) delete dunit; else _code_weaver.insert (pos, dunit); + } + else { + err << sev_error << inspos.location() + << "base class introduction into '" << ci->QualName() << "' failed" + << endMessage; + // delete all base into units + for (list::iterator ui = units.begin (); ui != units.end (); ++ui) + delete *ui; + } + } + leave (); +} + + +// called after the program has been parsed completely +void PumaIntroducer::trans_unit_end (CT_Program *pr) { + // ignore this translation unit, if it is a nested parser run + if (_intro_level != 0) + return; + enter (); + + CFileInfo *fi = pr->Scope ()->FileInfo (); + assert (fi); + CSemDatabase &db = *fi->SemDB (); + ACProject &project = (ACProject&)*db.Project (); + ACErrorStream &err = project.err (); + const Unit *primary = fi->Primary (); + LineDirectiveMgr &lmgr = _code_weaver.line_directive_mgr (); + + // ... some unit for formatting + ACUnit ws (err); ws << " " << endu; + + // loop until there are no more entries in the target map + while (!_targets.empty ()) { + + // get the information from the first entry and delete it + TargetMap::iterator i = _targets.begin (); + CClassInfo *ci = i->first; + ACM_Class &jp_loc = *i->second; + _targets.erase (i); + + // create units with the code that shall be introduced + list intros; + gen_intros (&jp_loc, intros, err, ci, lmgr, _conf.introduction_depth (), true); + // ignore this class if there are no non-inline intros for it + if (intros.size () == 0) + continue; + + CSourceInfo *si = ci->SourceInfo (); + bool in_header = (strcmp (si->FileName (), + si->FileInfo ()->Primary ()->name ()) != 0); + + if (in_header) { + // check if there is a link-once code element in the class + CObjectInfo *loo = link_once_object (ci); + + // TODO: for now loo has to != 0, later we can exploit the proj. repo + if (!loo) { + err << sev_warning << TransformInfo::location (jp_loc) + << "cannot introduce non-inline function or static attribute" + << " into \"class " << signature (jp_loc).c_str () + << "\". It has to contain link-once code." << endMessage; + for (list::iterator i = intros.begin (); i != intros.end (); ++i) + delete *i; + continue; + } + + // continue silently if this is only a declaration + if (loo->Scope () == ci) { + for (list::iterator i = intros.begin (); i != intros.end (); ++i) + delete *i; + continue; + } + } + + // parse the introduced code + CTree *tree = parse (intros, &CCSyntax::decl_seq, + Builder::Container::NodeId (), err); + if (!tree) { + err << sev_error << "parsing non-inline introduction code for class '" + << ci->QualName() << "' failed" << endMessage; + for (list::iterator i = intros.begin (); i != intros.end (); ++i) + delete *i; + leave (); + return; + } + + // move the introduced members into the normal program node + Builder::Container *decls = (Builder::Container*)tree; + for (int e = 0; e < decls->Entries (); e++) { + CTree *entry = decls->Entry (e); + pr->AddSon (entry); + } + delete decls; + + // paste the generated code and add the unit to the manipulator's unit mgr. + for (list::iterator i = intros.begin (); i != intros.end (); ++i) + _code_weaver.insert (_code_weaver.footer_pos (), *i, true); + + // determine the units that should be included in front of the intros + ACM_ClassPlan *plan = jp_loc.get_plan (); + set units; + typedef ACM_Container MContainer; + for (MContainer::iterator i = plan->get_member_intros().begin(); + i != plan->get_member_intros().end(); ++i) { + ACM_ClassSlice *cs = get_slice (*(*i)->get_intro()); + list &member_units = TI_ClassSlice::of(*cs)->non_inline_member_units(); + for (list::iterator i = member_units.begin (); + i != member_units.end (); ++i) + units.insert (*i); + } + + // parse the aspect headers that are needed by this intro + for (set::iterator iter = units.begin (); + iter != units.end (); ++iter) { + const Unit *slice_unit = *iter; + if (slice_unit != primary) { +// cout << "new edge from " << primary->name () << " to " +// << slice_unit->name () << endl; + _ig.add_edge (primary, slice_unit); + // generate a unit with the include + ostringstream includes; + Filename incname = project.getRelInclString (primary->name (), slice_unit->name ()); + includes << endl << "#ifndef "; + Naming::guard (includes, (FileUnit*)slice_unit); + includes << endl << "#define "; + Naming::guard (includes, (FileUnit*)slice_unit); + includes << endl; + includes << "#include \"" << incname << "\"" << endl; + includes << "#endif" << endl; + string inc (includes.str ()); + _code_weaver.insert (_code_weaver.footer_pos (), inc, true); + + if (_included_aspect_headers.find (slice_unit) == + _included_aspect_headers.end ()) { + _included_aspect_headers.insert (slice_unit); + // prepare a new C preprocessor + TokenStream stream; // linearize tokens from several files + stream.push ((Unit*)slice_unit); + PreprocessorParser cpp (&project.err (), &project.unitManager (), + _cpp->locals ()); + PreMacroManager *old_mm = cpp.macroManager (); + cpp.macroManager (_cpp->macroManager ()); + cpp.stream (&stream); + cpp.configure (project.config ()); + + TokenProvider provider (cpp); // look ahead token buffer + CTree *tree = _parser->syntax ().run (provider, &CCSyntax::trans_unit); + // TODO: tree should later be freed! + _ah_trees.push_back (tree); + + // print all error messages + _parser->builder ().errors (err); + cpp.macroManager (old_mm); + } +// else +// cout << "'" << slice_unit->name () << "' not included again!" << endl; + } + } + } + leave (); +} + + +// manage the intro nesting level and the _cpp pointer +void PumaIntroducer::enter () { + if (_intro_level == 0) + _cpp = &(PreprocessorParser&)_parser->syntax ().provider ()->source (); + _intro_level++; +} +void PumaIntroducer::leave () { + _intro_level--; + if (_intro_level == 0) + _cpp = 0; +} + +// create the weaving plan for a given class +ACM_Class *PumaIntroducer::create_plan (CClassInfo *ci) { + + // return if this class is not an introduction target + if (!_jpm.is_intro_target (ci->DefObject ())) + return 0; + + // try to register this class (might be a newly introduced class) + ACM_Class *jpl = _jpm.register_aspect (ci); + if (!jpl) jpl = _jpm.register_class (ci, 0, false); + + // return if this is either not a valid model class or no valid intro target + if (!jpl || !jpl->get_intro_target ()) + return 0; + + // iterate through all introduction advice in the plan + PointCutContext context (_jpm, _conf); + const list &intros = _plan.introduction_infos (); + for (list::const_iterator i = intros.begin (); + i != intros.end (); ++i) { + IntroductionInfo *intro = *i; + // TODO: consider stand-alone advice here as well in the future (C-mode) + // something like ... if (!intro->is_activated ()) continue; + context.concrete_aspect (intro->aspect ()); + Binding binding; // binding and condition not used for intros + Condition condition; + PointCutExpr *pce = (PointCutExpr*)intro->pointcut_expr().get(); + if (pce->match (*jpl, context, binding, condition)) + _plan.consider (*jpl, &intro->intro ()); + } + + if (jpl->has_plan ()) { + + // order the advice & check + _plan.order (jpl); + + // remember the class info and join point location + _targets.insert (TargetMap::value_type (ci, jpl)); + } + return jpl; +} + + +ACM_Class *PumaIntroducer::plan_lookup (CClassInfo *ci) { + TargetMap::iterator i = _targets.find (ci); + if (i != _targets.end () && i->second->has_plan()) + return i->second; + return 0; +} + + +CObjectInfo *PumaIntroducer::link_once_object (CClassInfo *ci) { + for (unsigned i = 0; i < ci->Functions (); i++) { + CFunctionInfo *fi = ci->Function (i)->DefObject (); + // skip template functions and built-in functions + // they don't need link-once code + if (fi->isBuiltin () || fi->isTemplate () || is_intro (fi)) { + continue; + } + // if a member function is undefined it is link-once code! + if (!fi->isDefined ()) { + return fi; + } + // if the function is defined, outside the class scope, and is not inline, + // we found the implementation + if (fi->Scope () != ci && !fi->isInline ()) { + return fi; + } + } + for (unsigned i = 0; i < ci->Attributes (); i++) { + CAttributeInfo *ai = ci->Attribute (i)->DefObject (); + // ignore introduced attributes + if (is_intro (ai)) + continue; + // if the scope is outside the class, we or definition + if (ai->Scope () != ci) { + return ai; + } + // initialized, we can us this object + if (ai->isStatic () && !ai->Init ()) { + return ai; + } + } + return 0; +} + +bool PumaIntroducer::is_intro (CObjectInfo *obj) { + Unit *unit = obj->SourceInfo ()->SrcUnit (); + return (IntroductionUnit::cast (unit) != 0); +} + +void PumaIntroducer::gen_intros (ACM_Class *jpl, list &units, + ACErrorStream &err, CStructure *target, LineDirectiveMgr &lmgr, int introduction_depth, + bool non_inline) const { + + // ... some unit for formatting + ACUnit nl (err); + nl << endl << endu; + ACUnit ws (err); + ws << " " << endu; + + // handle all intros + typedef ACM_Container Container; + Container &intros = jpl->get_plan()->get_member_intros(); + int i = 0; + for (Container::iterator iter = intros.begin(); iter != intros.end(); ++iter, ++i) { + ACM_Introduction *ii = (*iter)->get_intro(); + + // create the new unit + IntroductionUnit *unit = + new IntroductionUnit (err, (Unit*)target->Tree ()->token ()->belonging_to ()); + unit->intro (ii); + unit->precedence (i); + + // at least on token is needed in the unit for 'move' (see below) + unit->append (*((Token*)ws.first ())->duplicate ()); + + // TODO: clean up; a lot of duplicated code here + TI_ClassSlice *ti = TI_ClassSlice::of (*get_slice (*ii)); + + // generate non-inline introduction instance + if (ti->non_inline_members ().size () > 0 && non_inline) { + // create a unit with the target class name + ACUnit target_name (err); + target_name << target->Name () << endu; + ACUnit target_qual_name (err); + target_qual_name << target->QualName () << endu; + // generate a token with the name of the JoinPoint class for this slice + ACUnit jp_name (err); + jp_name << "__TJP_" << unit->precedence() << endu; + + std::list &units = ti->non_inline_members (); + for (std::list::iterator i = units.begin (); i != units.end(); ++i) { + Unit *pattern = *i; + int name_tokens = 0; + Token *token = pattern->first(); + token = pattern->next (token); // skip 'slice' keyword + while (token) { + Token *next = pattern->next (token); + if (name_tokens == 0 && next && next->type() == 0) { + name_tokens = 1; + next = pattern->next (next); + } + else if (name_tokens > 0 && token->type() == 0) { + unit->append (*((Token*)ws.first ())->duplicate ()); + *unit += target_qual_name; + name_tokens = 0; + if (next && next->type () == TOK_COLON_COLON) { + token = next; + next = pattern->next (token); + unit->append (*token->duplicate()); + if (next && next->type () == TOK_TILDE) { + token = next; + next = pattern->next (token); + unit->append (*token->duplicate()); + } + if (next && next->type () == TOK_ID) { + token = next; + next = pattern->next (token); + if (get_slice (*ii)->get_name() == token->text()) { + *unit += target_name; + } + else + unit->append (*token->duplicate()); + } + } + } + else { + if (name_tokens == 0) { + unit->append (*((Token*)ws.first ())->duplicate ()); + if (token->type () == TOK_ID && + string ("JoinPoint") == token->text ()) { + unit->append (*jp_name.first ()->duplicate()); + unit->jp_needed (true); + } + else { + unit->append (*token->duplicate()); + } + } + else + name_tokens++; + } + token = next; + } + } +// cout << "Generated intro instance " << *unit << endl; + } + // generate inline introduction instance + if (ti->get_tokens() && !non_inline) { + // create a unit with the target class name + ACUnit target_name (err); + target_name << target->Name () << endu; + // generate a token with the name of the JoinPoint class for this slice + ACUnit jp_name (err); + jp_name << "__TJP_" << unit->precedence() << endu; + + ACUnit slice_start (err); + if (get_slice(*ii)->get_is_struct()) + slice_start << " public:" << endl; + else + slice_start << " private:" << endl; + // add " typedef ;\n" + if (get_slice(*ii)->get_name()[0] != '<') { + slice_start << " typedef " << target->Name () << " " + << get_slice(*ii)->get_name() << ";" << endl; + } + slice_start << endu; + unit->List::move ((Token*)unit->last (), slice_start); + + Unit *pattern = ti->get_tokens(); + Token *token = pattern->first(); + while (token->type () != TOK_OPEN_CURLY) + token = pattern->next (token); + token = pattern->next (token); + ACUnit dir (err); + lmgr.directive (dir, pattern, ACToken (token)); + dir << endu; + if (!dir.empty ()) + unit->List::move ((Token*)unit->last (), dir); + Location loc = token->location (); + int level = 1; + while (true) { + if (token->type () == TOK_CLOSE_CURLY) { + level--; + if (level == 0) + break; + } + else if (token->type () == TOK_OPEN_CURLY) + level++; + + // insert whitespace or newline for proper formatting + if (token->location ().line () != loc.line ()) { + for (int l = loc.line (); l < token->location ().line (); l++) + unit->append (*((Token*)nl.first ())->duplicate ()); + loc = token->location (); + } + else + unit->append (*((Token*)ws.first ())->duplicate ()); + + // TODO: this is a hack - make sure not to replace too often! + if (level == 1 && token->type () == TOK_ID && + get_slice (*ii)->get_name() == token->text ()) + unit->append (*target_name.first ()->duplicate()); + else if (token->type () == TOK_ID && + string ("JoinPoint") == token->text ()) { + unit->append (*jp_name.first ()->duplicate()); + unit->jp_needed (true); + } + else + unit->append (*token->duplicate()); + token = pattern->next (token); + } +// cout << "Generated intro instance " << *unit << endl; + } + + // if there was no introduction, delete the unit -> no result + if (unit->first () == unit->last ()) + delete unit; + // check whether this is a deeply nested introduction + else if (unit->nesting_level () > introduction_depth) { + err << sev_error << target->DefObject()->Tree ()->token ()->location () + << "maximum level of nested introductions (" << introduction_depth + << ") for class '" + << target->QualName () << "' exceeded" << endMessage; + err << sev_error + << Location (Filename (filename (*ii).c_str ()), line (*ii)) + << "invalid introduction defined here" << endMessage; + delete unit; + } + else + units.push_back (unit); + } +} + +void PumaIntroducer::gen_base_intros (ACM_Class *jpl, list &units, + ACErrorStream &err, CClassInfo *target, LineDirectiveMgr &lmgr) const { + + typedef ACM_Container Container; + Container &bases = jpl->get_plan()->get_base_intros(); + bool first = true; + for (Container::iterator i = bases.begin(); i != bases.end (); ++i) { + // get the current introduction + ACM_Introduction *ii = (*i)->get_intro(); + + // create the new unit + IntroductionUnit *unit = + new IntroductionUnit (err, (Unit*)target->Tree ()->token ()->belonging_to ()); + unit->intro (ii); + + // generate the code for this base class introduction + gen_base_intro (*unit, ii, first); + first = false; + + // store the result for the caller + units.push_back (unit); + } +} + +void PumaIntroducer::gen_base_intro (IntroductionUnit &intro_unit, + ACM_Introduction *ii, bool first) const { + TI_ClassSlice *ti = TI_ClassSlice::of (*get_slice(*ii)); + // generate the code for this entry + intro_unit << (first ? ": " : ", ") << ti->base_intro() << endu; +} diff --git a/AspectC++/PumaIntroducer.h b/AspectC++/PumaIntroducer.h new file mode 100644 index 0000000..c6d38ef --- /dev/null +++ b/AspectC++/PumaIntroducer.h @@ -0,0 +1,155 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __PumaIntroducer_h__ +#define __PumaIntroducer_h__ + +// Class that is used for introductions during a parser run. +// The semantics object has a reference to an Introducer and uses +// the interface at some well defined (join) points. + +#include "Puma/ACIntroducer.h" + +#include +using std::set; +#include +using std::list; +#include +using std::map; + +namespace Puma { + class CT_ClassDef; + class CT_Program; + class CCParser; + class PreprocessorParser; + class CClassInfo; + class TokenProvider; + class TokenStream; +} + +#include "ACErrorStream.h" + +class ACConfig; +class IncludeGraph; +class CodeWeaver; +class JPP_Class; +class ACM_Class; +class ACM_Introduction; +class Plan; +class ModelBuilder; +class ACUnit; +class LineDirectiveMgr; +class IntroductionUnit; + +class PumaIntroducer : public Puma::ACIntroducer { + Plan &_plan; + CodeWeaver &_code_weaver; + Puma::CCParser *_parser; + ModelBuilder &_jpm; + int _intro_level; + Puma::PreprocessorParser *_cpp; + IncludeGraph &_ig; + ACConfig &_conf; + set _included_aspect_headers; + list _ah_trees; + typedef map TargetMap; + TargetMap _targets; + list _token_providers; + list _token_streams; + + // find a member that is/must be link-once (global) code + static Puma::CObjectInfo *link_once_object (Puma::CClassInfo *ci); + + // check whether an object was introduced + static bool is_intro (Puma::CObjectInfo *obj); + + // parse code that shall be introduced + Puma::CTree *parse (list units, bool (Puma::CCSyntax::*rule)(), + const char *expected_id, ACErrorStream &err); + + // checks if an attribute that us returned by the parser is an attribute + // in the sense of the AspectC++ introspection mechnism + bool is_attribute (Puma::CAttributeInfo *obj); + +public: + // Contructor: every Introducer knows the parser + PumaIntroducer (Plan &pl, CodeWeaver &cw, Puma::CCParser &p, ModelBuilder &jpm, + IncludeGraph &ig, ACConfig &c) : _plan (pl), _code_weaver (cw), + _parser (&p), _jpm (jpm), _intro_level (0), _cpp (0), _ig (ig), _conf(c) {} + + // Destructor: release all allocated resources + ~PumaIntroducer (); + + // called when a new class/union/struct/aspect is created, current scope + // is the global scope + virtual void class_before (Puma::CT_ClassDef*); + + // called when a new class/union/struct/aspect is created + virtual void class_begin (Puma::CT_ClassDef*); + + // called when a new class/union/struct/aspect definition ends + // (still in the class scope) + virtual void class_end (Puma::CT_ClassDef*); + + // called after the parser tried to parse a base clause + virtual void base_clause_end (Puma::CT_ClassDef*, Puma::Token*); + + // called after the program has been parsed completely + virtual void trans_unit_end (Puma::CT_Program *); + + // get the list of aspect header syntax trees + list &ah_trees () { return _ah_trees; } + +private: + + // check in the plan if the current class needs an introduction + ACM_Class *plan_lookup (Puma::CClassInfo *ci); + + // create the weaving plan for a given class and return the class object + ACM_Class *create_plan (Puma::CClassInfo *ci); + + // insert introspection code + // * at the end of class definitions, after AspectC++ introductions + // * before a slice, if "precedence" is given + void insert_introspection_code (Puma::CT_ClassDef *cd, int precedence = -1); + + // insert friend declarations for all aspects + bool insert_aspect_friend_decls (ACUnit &unit, Puma::CRecord *rec); + + // insert friend declarations for all aspects + bool insert_aspectof_function (ACUnit &unit, Puma::CClassInfo *ci, + ACErrorStream &err); + + // manage the intro nesting level and the _cpp pointer + void enter (); + void leave (); + + // generate member intros for a given class + void gen_intros (ACM_Class *jpl, list &units, ACErrorStream &err, + Puma::CStructure *target, LineDirectiveMgr &lmgr, int introduction_depth, + bool non_inline = false) const; + + // generate base class intros for a given class + void gen_base_intros (ACM_Class *jpl, list &units, ACErrorStream &err, + Puma::CClassInfo *target, LineDirectiveMgr &lmgr) const; + + void gen_base_intro (IntroductionUnit &intro_unit, + ACM_Introduction *ii, bool first) const; +}; + +#endif /* __PumaIntroducer_h__ */ diff --git a/AspectC++/PumaModelBuilder.cc b/AspectC++/PumaModelBuilder.cc new file mode 100644 index 0000000..2b084d1 --- /dev/null +++ b/AspectC++/PumaModelBuilder.cc @@ -0,0 +1,1054 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "ModelBuilder.h" +#include "PumaTrackerDog.h" +#include "IntroductionUnit.h" +#include "PointCutContext.h" +#include "PointCutExpr.h" +#include "ACConfig.h" +#include "ACPreprocessor.h" + +// ACModel library includes +#include "ACModel/Utils.h" + +// Puma library includes +#include "Puma/CFileInfo.h" +#include "Puma/CSemDatabase.h" +#include "Puma/VerboseMgr.h" +#include "Puma/SysCall.h" + +using namespace Puma; + +static string objname (CObjectInfo *info) { + string result; + CTemplateInstance *instance; + DeducedArgument *arg; + + if (! info->Name ()/* || info->isAnonymous ()*/) + result = ""; + else + result = info->Name (); + + instance = info->TemplateInstance (); + if (instance) { + result += "<"; + for (unsigned i = 0; i < instance->InstantiationArgs (); i++) { + arg = instance->InstantiationArg (i); + // do not list default arguments + if (arg->isDefaultArg ()) + break; + + if (i) + result += ","; + ostringstream out; + arg->print(out, false); + result += out.str (); + } + + if (result[result.length () -1] == '>') + result += " "; + result += ">"; + } + return result; +} + +// start phase 1 +void PumaModelBuilder::setup_phase1 (FileUnit *unit, int tunit_len) { + _tunit_file = newTUnit(); + _tunit_file->set_filename(model_filename (unit)); + _tunit_file->set_len(tunit_len); + _tunit_file->set_time(modification_time (unit)); + get_files().insert(_tunit_file); + file_map().insert (PumaModelBuilder::FileMapPair (unit, _tunit_file)); + set_root(0); // TODO: to be done by libacmodel + + register_namespace1(0, "::"); +} + +// start phase 2 +void PumaModelBuilder::setup_phase2 (CTranslationUnit& tunit, list &ah_trees) { + + // use Puma's semantic information of this translation unit + // to fill/update the project model + build (tunit); + + // run the tracker dog to find function calls in the syntax tree + PumaTrackerDog tracker (tunit, *this, _conf.dynamic()); + tracker.run (); +} + +void PumaModelBuilder::build (CStructure &scope, ACM_Name *jpl) { + // iterate through all namespace in this scope + for (unsigned int n = 0; n < scope.Namespaces (); n++) { + CNamespaceInfo *ni = scope.Namespace (n); + + // check if this namespace belongs to our project + FileUnit *funit = source_unit (ni->Tree ()); + if (!funit || !get_project ().isBelow (funit)) + continue; + + ACM_Namespace *jpl_namespace = register_namespace (ni, jpl); + build (*ni, jpl_namespace); + } + + // first collect all classes and class template instances in this scope + list classes; + for (unsigned int c = 0; c < scope.Types (); c++) { + CClassInfo *ci = scope.Type (c)->ClassInfo (); + if (!ci) + continue; + if (ci->isTemplate()) { + // insert all class template instances + CTemplateInfo *ti = ci->TemplateInfo(); + for (unsigned int tii = 0; tii < ti->Instances(); tii++) + classes.push_back (ti->Instance(tii)->ClassInfo()); + } + else + // an ordinary class -> handle as well + classes.push_back (ci); + } + + // now handle all collected classes (and class template instances) + for (list::const_iterator iter = classes.begin(); + iter != classes.end (); ++iter) { + CClassInfo *ci = *iter; + + // check if this class belongs to our project + FileUnit *funit = source_unit (ci->DefObject()->Tree ()); + + if (!funit || !get_project ().isBelow (funit)) + continue; // found no class declaration or definition that belongs to the project! + + // it is an ordinary class (or aspect) + ACM_Class *jpl_class = register_aspect (ci->DefObject(), + !ci->CObjectInfo::QualifiedScope () && ci->Scope () == &scope ? jpl : 0); + if (!jpl_class) + jpl_class = register_class (ci, !ci->CObjectInfo::QualifiedScope () && + ci->Scope () == &scope ? jpl : 0); + if (!jpl_class) continue; + + if (ci->isDefined ()) { + + // setup the base class relations + jpl_class->get_bases().clear(); + for (unsigned b = 0; b < ci->BaseClasses (); b++) { + CClassInfo *base = ci->BaseClass (b)->Class (); + ACM_Class *base_loc = register_aspect (base); + if (!base_loc) + base_loc = register_class (base); + // ignore base classes that are not part of the model + if (base_loc && (base_loc->type_val () & (JPT_Class|JPT_Aspect))) { + jpl_class->get_bases().insert(base_loc); + base_loc->get_derived().insert(jpl_class); + } +// else +// cout << "*** base not found: " << ci->QualName () << " " << base->QualName () << endl; + } + + // recursively go down one step + build (*ci, jpl_class); + + // setup the built-in member functions + if (!ci->isStruct () && + (get_project ().isBelow (ci->SourceInfo ()->SrcUnit ()) || + IntroductionUnit::cast (ci->SourceInfo ()->SrcUnit ()))) { + for (unsigned f = 0; f < ci->Functions (); f++) { + CFunctionInfo *fi = ci->Function (f)->DefObject (); + if (!fi->isBuiltin ()) + continue; + if (fi->isConstructor ()) { + if (ci->isTemplateInstance()) + register_function (fi, jpl_class); + else + register_construction (register_function (fi, jpl_class)); + } + else if (fi->isDestructor ()) { + if (ci->isTemplateInstance()) + register_function (fi, jpl_class); + else + register_destruction (register_function (fi, jpl_class)); + + } + } + } + + // is it a definition? + if (jpl_class->type_val () == JPT_Aspect) { + ACM_Aspect *jpl_aspect = (ACM_Aspect*)jpl_class; + _vm << (::is_abstract (*jpl_aspect) ? "Abstract" : "Concrete") + << " aspect " << signature (*jpl_aspect) << endvm; + _vm++; + advice_infos (jpl_aspect); + _vm--; + } + } + } + + // insert all functions and pointcuts + for (unsigned f = 0; f < scope.Functions (); f++) { + CFunctionInfo *fi = scope.Function (f); + + if (register_pointcut (fi, jpl)) + continue; + + if (fi->isBuiltin ()) + continue; + + // check if this function belongs to our project + FileUnit *funit = source_unit (fi->Tree ()); + if (!funit || !get_project ().isBelow (funit)) + continue; + + // only functions that belong to the project are registered here + // other functions might be register later if they are referenced + register_function (fi, + !fi->CObjectInfo::QualifiedScope () && fi->Scope () == &scope ? jpl : 0); + } +} + +void PumaModelBuilder::advice_infos (ACM_Aspect *jpl_aspect) { + // add type information to advice nodes (phase 2) + CClassInfo *cls = TI_Aspect::of(*jpl_aspect)->class_info(); + unsigned f = 0; + typedef ACM_Container Container; + Container &advices = jpl_aspect->get_advices(); + for (Container::iterator i = advices.begin (); i != advices.end (); ++i) { + ACM_AdviceCode *advice_code = *i; + while (f < cls->Functions()) { + if (strncmp (cls->Function(f)->Name(), "__a", 3) == 0) + break; + f++; + } + if (f == cls->Functions()) { + _err << sev_fatal << cls->Tree()->token()->location() + << "internal problem: advice cannot be associated with advice function in aspect " + << cls->QualName() << endMessage; + return; + } + CFunctionInfo *fi = cls->Function(f); + // argument types are the types of the function declaration + CTypeList *arg_types = fi->TypeInfo ()->ArgTypes (); + f++; + unsigned first_context_arg = 0; + if (fi->Arguments() > 0 && strcmp (fi->Argument(0u)->Name ().c_str(), "tjp") == 0) + first_context_arg = 1; + for (unsigned a = first_context_arg; a < arg_types->Entries (); a++) { + advice_code->get_pointcut()->get_args().insert (register_arg (arg_types->Entry (a), + fi->Argument(a)->Name().c_str())); + } + // tree is the tree of the function definition + TI_AdviceCode::of(*advice_code)->function (fi); + } +} + + +string PumaModelBuilder::model_filename (FileUnit *unit) { + const char *fname = unit->absolutePath (); + ACProject &prj = _conf.project (); + // if the file does not belong to the project return the absolute path + if (!unit->belongsTo (prj)) + return fname; + // iterate over all project paths + for (long p = 0; p < prj.numPaths (); p++) { + Filename dir_abs; + if (!SysCall::canonical (prj.src (p), dir_abs)) { + assert (false); + return fname; + } + int dir_len = strlen (dir_abs.name ()); + if (strncmp (dir_abs.name (), fname, dir_len) == 0) { + return fname + dir_len + 1; + } + } + // the file has to be below any of the directories => fatal error here + // assert (false); acgen.c does not belong to the project with this test + return fname; +} + + +// get the modification time of a file (UNIX Epoch value) +long PumaModelBuilder::modification_time (FileUnit *unit) { + FileInfo fileinfo; + if (! SysCall::stat (unit->absolutePath(), fileinfo)) + return -1; // File does not exists. + return fileinfo.modi_time (); +} + + +void PumaModelBuilder::build (CTranslationUnit& tunit) { + CFileInfo *fi = tunit.db ().FileInfo (0); + ACM_Namespace *jpl_namespace = register_namespace (fi); + build (*fi, jpl_namespace); +} + +bool PumaModelBuilder::inside_template (CScopeInfo *scope) const { + if (scope->isTemplate () || + (scope->isTemplateInstance () && + scope->TemplateInstance ()->isPseudoInstance ())) + return true; + if (scope->QualifiedScope ()) + return inside_template (scope->QualifiedScope ()); + if (scope->Parent () != scope) + return inside_template (scope->Parent ()); + return false; +} + +bool PumaModelBuilder::inside_template_instance (CScopeInfo *scope) { + if (scope->isTemplateInstance ()) + return true; + if (scope->QualifiedScope ()) + return inside_template_instance (scope->QualifiedScope ()); + if (scope->Parent () != scope) + return inside_template_instance (scope->Parent ()); + return false; +} + +bool PumaModelBuilder::is_valid_model_class (CClassInfo *ci) const { + // Don't consider + // * anonymous classes like template instances(?) + // * the generated class JoinPoint + // * classes defined in the special namespace AC + if (strncmp (ci->Name (), "%", 1) == 0 || + strcmp (ci->QualName (), "JoinPoint") == 0 || + strncmp (ci->QualName (), "AC::", 4) == 0) + return false; + + // Templates and classes nested in template class are not considered for + // matching, only instances + if (inside_template (ci)) + return false; + + return true; +} + +bool PumaModelBuilder::is_valid_model_function (CFunctionInfo* fi) const { + // Don't consider + // * member functions of an invalid class + // * ac++ generated functions + // * pointcuts + + CRecord *cls = fi->ClassScope (); + if (cls && !is_valid_model_class ((CClassInfo*)cls->DefObject ())) + return false; + + CFunctionInfo *def = fi->DefObject (); + if (inside_template (def)) + return false; + + if (strncmp (fi->Name (), "__ac_anon", 9) != 0) { + if (strncmp (fi->Name (), "%a", 2) == 0 || + strncmp (fi->Name (), "__a", 3) == 0 || + strcmp (fi->Name (), "aspectof") == 0 || + strcmp (fi->Name (), "aspectOf") == 0) + return false; + } + + if (!fi->isBuiltin () && !IntroductionUnit::cast (def->SourceInfo ()->SrcUnit ()) && + strcmp (def->SourceInfo ()->FileName (), "") == 0) + return false; + + return true; +} + +bool PumaModelBuilder::is_valid_model_namespace (CNamespaceInfo *ni) const { + // no template instance namespace, but anonymous namespaces! + if ((strcmp(ni->Name (), "") == 0 || + strstr (ni->Name (), "<") == 0) && + strcmp (ni->QualName (), "AC") != 0 && + strncmp (ni->Name (), "__puma", 6) != 0) + return true; + return false; +} + +TU_Type *PumaModelBuilder::register_type (CTypeInfo *ti) { + TU_Type *new_elem = newType(); + new_elem->set_signature(TI_Type::name (ti)); + new_elem->type_info (ti); + return new_elem; +} + +TU_Arg *PumaModelBuilder::register_arg (CTypeInfo *ti, const string &name) { + TU_Arg *new_elem = newArg(); + new_elem->set_type(TI_Type::name (ti)); + new_elem->set_name(name); + new_elem->type_info (ti); + return new_elem; +} + +ACM_Pointcut *PumaModelBuilder::register_pointcut1 (ACM_Name *parent, const string &name, + bool is_virtual, const string& expr) { + + TU_Pointcut *elem = 0; + if (parent) + elem = (TU_Pointcut*)map_lookup(*parent, name); + if (!elem || elem->type_val() != JPT_Pointcut) { + elem = newPointcut(); + elem->set_name(name); + elem->set_expr (expr); + elem->set_builtin(false); + elem->set_kind(PT_NORMAL); + if (parent) { + if (is_virtual && expr == "0") + elem->set_kind(PT_PURE_VIRTUAL); + else if (is_virtual || overrides_virtual_pointcut(parent, name)) + elem->set_kind(PT_VIRTUAL); + map_insert(*parent, *elem, name); + parent->get_children().insert(elem); + } + } + else { + elem = 0; + } + + return elem; +} + +bool PumaModelBuilder::overrides_virtual_pointcut (ACM_Name *parent, const string &name) { + if (parent->type_val() != JPT_Class && parent->type_val() != JPT_Aspect) + return false; + ACM_Class *cls = (ACM_Class*)parent; + typedef ACM_Container BList; + const BList &blist = cls->get_bases(); + for (BList::const_iterator i = blist.begin (); i != blist.end(); ++i) { + ACM_Class *base = (ACM_Class*)*i; + ACM_Name *elem = map_lookup(*base, name); + if (!elem || elem->type_val() != JPT_Pointcut) + continue; + ACM_Pointcut *base_pct = (ACM_Pointcut*)elem; + if (base_pct->get_kind() == PT_PURE_VIRTUAL || + base_pct->get_kind() == PT_VIRTUAL || + overrides_virtual_pointcut (base, name)) + return true; + } + return false; +} + + +TU_Pointcut *PumaModelBuilder::register_pointcut (CFunctionInfo *fi, + ACM_Name *parent) { + + CFunctionInfo *def = fi->DefObject (); + + // find the parent model element + if (!parent) + return 0; + + // build the name of the function + string name = fi->Name ().c_str (); + + TU_Pointcut *elem = (TU_Pointcut*)map_lookup(*parent, name); + if (!elem || elem->type_val() != JPT_Pointcut) + return 0; + + elem->get_args().clear(); + // argument types are the types of the function declaration + CTypeList *arg_types = fi->TypeInfo ()->ArgTypes (); + for (unsigned a = 0; a < arg_types->Entries (); a++) { + // TODO: still needed to handle "..." in build-in pointcuts + if (arg_types->Entry(a)->is_ellipsis()) + break; + elem->get_args().insert (register_arg (arg_types->Entry (a), + fi->Argument(a)->Name().c_str())); + } + elem->func_info(def); + add_source_loc (elem, def); + + return elem; +} + +TU_Function *PumaModelBuilder::register_function (CFunctionInfo *fi, + ACM_Name *parent) { + if (!is_valid_model_function (fi)) + return 0; + + CFunctionInfo *def = fi->DefObject (); + + // find the parent model element + if (!parent && !(parent = register_scope (def))) + return 0; + + // build the name of the function for lookup + string sig = TI_Function::signature (def); + + // register the element + TU_Function *elem = (TU_Function*)map_lookup(*parent, sig); + bool hidden_function = (elem && elem->type_val() == JPT_Function && + ((fi->isStatic () && !fi->isStaticMethod ()) && + (!elem->has_static_in () || elem->get_static_in () != _tunit_file))); + if (!elem || hidden_function) { + elem = newFunction(); + elem->set_name(objname(fi)); + if (fi->isStatic () && !fi->isStaticMethod ()) + elem->set_static_in (_tunit_file); + map_insert(*parent, *elem, sig); + parent->get_children().insert(elem); + FunctionType ft = FT_NON_MEMBER; + if (fi->isConstructor ()) + ft = FT_CONSTRUCTOR; + else if (fi->isDestructor ()) { + if (fi->isPureVirtual ()) + ft = FT_PURE_VIRTUAL_DESTRUCTOR; + else if (fi->isVirtual () || fi->overridesVirtual ()) + ft = FT_VIRTUAL_DESTRUCTOR; + else + ft = FT_DESTRUCTOR; + } + else if (fi->isMethod ()) { + if (fi->isStaticMethod ()) + ft = FT_STATIC_MEMBER; + else if (fi->isPureVirtual ()) + ft = FT_PURE_VIRTUAL_MEMBER; + else if (fi->isVirtual () || fi->overridesVirtual ()) + ft = FT_VIRTUAL_MEMBER; + else + ft = FT_MEMBER; + } + else { + if (fi->isStatic()) + ft = FT_STATIC_NON_MEMBER; + } + elem->set_kind (ft); + elem->set_builtin (fi->isBuiltin ()); + CVQualifiers cvq = CVQ_NONE; + if (fi->TypeInfo()->isConst()) + cvq = (CVQualifiers)(cvq | CVQ_CONST); + if (fi->TypeInfo()->isVolatile()) + cvq = (CVQualifiers)(cvq | CVQ_VOLATILE); + elem->set_cv_qualifiers(cvq); + elem->func_info (def); + + // TODO: We forget the arg type from arg 0. They will be deleted by jpm. + elem->get_arg_types().clear(); + CTypeInfo *rtype = (fi->isConversion ()) ? + fi->ConversionType() : fi->TypeInfo ()->BaseType (); + if (!rtype->is_undefined()) + elem->set_result_type (register_type (rtype)); + // argument types are the types of the function declaration + CTypeList *arg_types = fi->TypeInfo ()->ArgTypes (); + elem->set_variadic_args(false); + for (unsigned a = 0; a < arg_types->Entries (); a++) + if (arg_types->Entry(a)->is_ellipsis()) + elem->set_variadic_args(true); + else + elem->get_arg_types().insert (register_type (arg_types->Entry (a))); + + if (!fi->isBuiltin () && !fi->isPureVirtual () && + !(inside_template_instance (fi)) && + (fi->SemDB ()->Project ()->isBelow (fi->SourceInfo ()->SrcUnit ()) || + IntroductionUnit::cast (fi->SourceInfo ()->SrcUnit ()))) { + if (fi->isConstructor ()) + register_construction (elem); + else if (fi->isDestructor ()) + register_destruction (elem); + else + register_execution (elem); + + // constructors and and destructors cannot be called + if (!(fi->isConstructor () || fi->isDestructor ())) { + // register a 'pseudo call join point' + register_call (def, 0, 0, 0); + } + } + } + else { + // make sure that elem->func_info() will be the DefObject + if (fi == def) + elem->func_info(def); + } + add_source_loc (elem, fi, fi->isFctDef () ? SLK_DEF : SLK_DECL); + return elem; +} + +TU_Variable *PumaModelBuilder::register_variable (CObjectInfo *oi, ACM_Name *parent) { + CObjectInfo *def = oi->DefObject (); + + // find the parent model element + if (!parent && !(parent = register_scope (def))) + return 0; + + // get the name of the variable + string sig = TI_Variable::name (def); + + // register the element + // TODO: classes and variables in the same scope may have the same name! + // This might lead to invalid results here. + TU_Variable *elem = (TU_Variable*)map_lookup(*parent, sig); + if (!elem || elem->type_val() != JPT_Variable) { + elem = newVariable (); + elem->set_name(sig); + elem->set_kind(VT_UNKNOWN); + elem->set_builtin(false); + TU_Type *var_type = register_type(oi->TypeInfo()); + elem->set_type(var_type); + elem->obj_info(def); + map_insert(*parent, *elem, sig); + parent->get_children().insert(elem); + } + return elem; +} + +ACM_ClassSlice *PumaModelBuilder::register_class_slice (ACM_Name *scope, string name, + bool is_struct) { + + ACM_Name *found = map_lookup(*scope, name); + if (found && found->type_val() == JPT_ClassSlice) + return (ACM_ClassSlice*)found; + + ACM_ClassSlice *new_elem = (ACM_ClassSlice*)newClassSlice(); + new_elem->set_name(name); + new_elem->set_builtin(false); + new_elem->set_is_struct(is_struct); + map_insert(*scope, *new_elem, name); + scope->get_children().insert(new_elem); + return new_elem; +} + + +ACM_Class * PumaModelBuilder::register_class1 (ACM_Name *scope, string name, bool in_project) { + ACM_Name *found = map_lookup(*scope, name); + if (found && found->type_val() == JPT_Class) + return (TU_Class*)found; + ACM_Class *new_elem = newClass(); + new_elem->set_name(name); + new_elem->set_builtin(false); + if (!in_project) new_elem->get_tunits().insert (_tunit_file); + new_elem->set_intro_target(in_project); + scope->get_children().insert(new_elem); + map_insert(*scope, *new_elem, name); + return new_elem; +} + + +TU_Class *PumaModelBuilder::register_class (CClassInfo *ci, ACM_Name *parent, bool set_source) { + + // only classes are relevant + if (!is_valid_model_class (ci)) + return 0; + + // find the parent model element + if (!parent && !(parent = register_scope (ci))) + return 0; + + string name = objname(ci); + TU_Class *elem = 0; + ACM_Name *found = map_lookup(*parent, name); + if (!found || !(found->type_val() & (JPT_Class|JPT_Aspect))) { + elem = (TU_Class*)newClass(); + elem->set_name(name); + elem->set_builtin(false); + parent->get_children().insert(elem); + map_insert(*parent, *elem, name); + bool intro_target = is_intro_target (ci->DefObject ()); + elem->set_intro_target (intro_target); + if (!intro_target) elem->get_tunits().insert (_tunit_file); + } + else + elem = (TU_Class*)found; + // set the class attributes + elem->class_info (ci); + if (set_source && elem->type_val () != JPT_Aspect) + add_source_loc (elem, ci, ci->isDefined () ? SLK_DEF : SLK_DECL); + return elem; +} + +ACM_Aspect * PumaModelBuilder::register_aspect1 (ACM_Name *scope, string name, bool in_project) { + ACM_Name *found = map_lookup(*scope, name); + if (found && found->type_val() == JPT_Aspect) + return (TU_Aspect*)found; + ACM_Aspect *new_elem = newAspect(); + new_elem->set_name(name); + new_elem->set_builtin(false); + if (!in_project) new_elem->get_tunits().insert (_tunit_file); + new_elem->set_intro_target(in_project); + scope->get_children().insert(new_elem); + map_insert(*scope, *new_elem, name); + return new_elem; +} + + +TU_Aspect *PumaModelBuilder::register_aspect (CClassInfo *ci, ACM_Name *parent) { + // only classes are relevant + if (!is_valid_model_class (ci)) + return 0; + + // find the parent model element + if (!parent && !(parent = register_scope (ci))) + return 0; + + string name = ci->Name().c_str(); + TU_Aspect *elem = 0; + ACM_Name *found = map_lookup(*parent, name); + if (!found || found->type_val() != JPT_Aspect) + return 0; + elem = (TU_Aspect*)found; + + // set the aspect attributes + elem->class_info(ci); + return elem; +} + +bool PumaModelBuilder::is_intro_target (CClassInfo *def) const { + return IntroductionUnit::cast (def->SourceInfo ()->SrcUnit ()) || + !(!get_project ().isBelow (def->SourceInfo ()->SrcUnit ()) || + def->isTemplateInstance () || + !def->isDefined ()); +} + +ACM_Namespace * PumaModelBuilder::register_namespace1 (ACM_Name *scope, string name, bool in_project) { + ACM_Namespace *result = 0; + assert(scope || name == "::"); + ACM_Name *found = (scope ? map_lookup(*scope, name) : get_root()); + if (!found || found->type_val() != JPT_Namespace) { + result = newNamespace(); + result->set_name(name); + result->set_builtin(false); + if (!in_project) result->get_tunits().insert (_tunit_file); + if (scope) { + scope->get_children().insert(result); + map_insert(*scope, *result, name); + } + else { + set_root(result); + } + } + else + result = (TU_Namespace*)found; + return result; +} + + +TU_Namespace *PumaModelBuilder::register_namespace (CNamespaceInfo *n, + ACM_Name *parent) { + // not all Puma namespaces should be registered + if (!is_valid_model_namespace (n)) + return 0; + + // find the parent model element + if (!parent && !n->GlobalScope () && !(parent = register_scope (n))) + return 0; + + TU_Namespace *new_elem = 0; + if (!parent) { + if (get_root()) + return (TU_Namespace*)get_root(); + new_elem = newNamespace(); + new_elem->set_name("::"); + new_elem->set_builtin(true); + set_root(new_elem); + } + else { + string name = n->Name().c_str(); + ACM_Name *found = map_lookup(*parent, name); + if (found && found->type_val() == JPT_Namespace) + return (TU_Namespace*)found; + new_elem = newNamespace(); + new_elem->set_name(name); + new_elem->set_builtin(false); + parent->get_children().insert(new_elem); + map_insert(*parent, *new_elem, name); + } + + // set namespace attributes + new_elem->namespace_info (n); + if (new_elem != get_root ()) + add_source_loc (new_elem, n); + return new_elem; +} + + +// create a new call join point in the join point model +TU_MethodCall *PumaModelBuilder::register_call (CFunctionInfo *called, CT_Call *call_node, + CObjectInfo *caller, int local_id) { + + // find the called function in the join point model + ACM_Function *called_func = register_function (called); + if (!called_func) { +// if a called function is, for instance, a member of a local class, it is +// perfectly valid that we don't find it in the model -> ignore call join-point +// _err << sev_error << "called function \'" << called->QualName () +// << "\' not found in join point model" << endMessage; + return 0; + } + + // what is the lexical scope of this call? + ACM_Name *lexical = 0; + if (!caller) { + lexical = 0; // a pseudo call join point + } + else if (caller->FunctionInfo ()) { + // TODO: better cache the JPL object of the current function + ACM_Any *loc = register_function (caller->FunctionInfo (), 0); + if (!loc) { + // TODO: calls in advice code are silently ignored here at the moment +// _err << sev_error << call_node->token ()->location () +// << "location of function call invalid" << endMessage; + return 0; + } + lexical = (ACM_Name*)loc; + } + else { + lexical = register_variable (caller); + if (!lexical) { + _err << sev_error << call_node->token ()->location () + << "location of function call invalid" << endMessage; + return 0; + } + } + + TU_MethodCall *new_elem = newCall(); + new_elem->set_target(called_func); + called_func->get_calls().insert(new_elem); + new_elem->set_lid(local_id); + new_elem->called (called); + new_elem->caller (caller); + new_elem->tree (call_node); + if (call_node) + add_source_loc (new_elem, call_node); + // set the parent in the join point model structure + if (lexical) { // pseudo-calls are invisible + lexical->get_children().insert(new_elem); + } + + // For functions with default arguments, not more than the number of args + // in the call expression is used. + bool no_operator = (call_node && + call_node->NodeName () == CT_CallExpr::NodeId () && + ((CT_CallExpr *)call_node)->Arguments ()); + if (no_operator) { + // argument types are the types from the target function declaration + CTypeList *formal_arg_types = called->TypeInfo ()->ArgTypes (); + int args = (int)formal_arg_types->Entries (); + CT_ExprList *current_arg_list = ((CT_CallExpr *)call_node)->Arguments (); + int call_args = current_arg_list->Entries (); + if (called_func->get_variadic_args()) { + args--; // ignore the ellipsis + for (int a = args; a < current_arg_list->Entries (); a++) { + CTypeInfo *arg_type = + ((CT_Expression*)current_arg_list->Entry (a))->Type (); + new_elem->get_variadic_arg_types().insert(register_type (arg_type)); + } + } + else if (call_args < args) { + new_elem->set_default_args(args - call_args); + } + } + + // analyze the target object type of this call + if (call_node) { + CTypeInfo *target_type = new_elem->target_type (); + if (target_type != &CTYPE_VOID && target_type->Record () && + target_type->Record ()->ClassInfo()) { + CClassInfo *ci = target_type->Record()->ClassInfo ()->DefObject (); + ACM_Class *target_class = register_aspect(ci); + if (!target_class) target_class = register_class(ci); + assert (target_class); + new_elem->set_target_class(target_class); + } + } + + return new_elem; +} + +// create a new execution join point +TU_Method *PumaModelBuilder::register_execution (ACM_Function *ef) { + CFunctionInfo *func = ((TI_Function*)ef->transform_info ())->func_info (); + TU_Method *new_elem = newExecution(); + ef->get_children().insert(new_elem); + new_elem->func_info (func); + return new_elem; +} + +// create a new construction join point +TU_Construction *PumaModelBuilder::register_construction (ACM_Function *cf) { + assert (cf); + CFunctionInfo *func = ((TI_Function*)cf->transform_info ())->func_info (); + TU_Construction *new_elem = newConstruction(); + cf->get_children().insert(new_elem); + new_elem->func_info (func); + return new_elem; +} + +// create a new construction join point +TU_Destruction *PumaModelBuilder::register_destruction (ACM_Function *df) { + assert (df); + CFunctionInfo *func = ((TI_Function*)df->transform_info ())->func_info (); + TU_Destruction *new_elem = newDestruction(); + df->get_children().insert(new_elem); + new_elem->func_info (func); + return new_elem; +} + +// TODO: temporary solution for dac++ +void PumaModelBuilder::register_attr_access (CAttributeInfo *attr, CTree *node) { + _access_infos.push_back (AccessInfo (attr, node)); +} + +ACM_Name *PumaModelBuilder::register_scope (CObjectInfo *obj) { + ACM_Name *result = 0; + CScopeInfo *scope = scope_obj (obj); + if (scope) { + if (scope->NamespaceInfo ()) + result = register_namespace (scope->NamespaceInfo ()); + else if (scope->ClassInfo ()) { + result = register_aspect (scope->ClassInfo ()); + if (!result) + result = register_class (scope->ClassInfo ()); + } + } + +// in some cases, e.g. join-points within local classes it can happen that +// the scope of a join-point is not known in the model -> no error! +// if (!result) { +// _err << sev_error << "parent '" << scope_name (obj).c_str () +// << "' of model element " << obj->QualName () << " not found" +// << endMessage; +// } + + return result; +} + +CScopeInfo *PumaModelBuilder::scope_obj (CObjectInfo *oi) { + CScopeInfo *scope = 0; + if (oi->TemplateInstance ()) { + scope = oi->TemplateInstance ()->Template ()->CObjectInfo::QualifiedScope (); + if (!scope) scope = oi->TemplateInstance ()->Template ()->Scope (); + } + else { + scope = oi->QualifiedScope (); + if (!scope) scope = oi->Scope (); + } + // if this is a template instance scope, go to the parent + if (!(strcmp (scope->Name(), "") == 0)) { + while (scope->isAnonymous () && strstr (scope->Name (), "<")) { + scope = scope->Parent (); + } + } + return scope; +} + +string PumaModelBuilder::scope_name (CObjectInfo *oi) { + CScopeInfo *scope = scope_obj (oi); + assert (scope); + // is it the globale scope + if (scope->GlobalScope ()) + return "::"; + ostringstream scope_name; + if (scope->TypeInfo () && !scope->TypeInfo ()->isUndefined ()) + scope_name << *scope->TypeInfo (); + else if (scope->isAnonymous ()) + scope_name << ""; + else + scope_name << scope->QualName (); + return scope_name.str (); +} + + +// add the source location to a model element by using the syntax tree node +void PumaModelBuilder::add_source_loc (ACM_Any *name, ACToken token, ACToken end_token, SourceLocKind kind) { + + assert(name); + + // check if this file belong to our project + FileUnit *funit = ACPreprocessor::source_unit (token); + if (!funit) + return; + + if (!get_project ().isBelow (funit)) { + if (name->type_val () & JPT_Name) { + ACM_Name *jpl_name = (ACM_Name*)name; + // TODO: really use linear search here? + typedef ACM_Container Container; + const Container &tunits = jpl_name->get_tunits (); + bool found = false; + for (Container::const_iterator i = tunits.begin(); i != tunits.end(); ++i) { + if (*i == _tunit_file) { + found = true; + break; + } + } + if (!found) + jpl_name->get_tunits ().insert (_tunit_file); + } + return; + } + + PumaModelBuilder::FileMap::iterator i = file_map ().find (funit); + ACM_File *file = 0; + if (i != file_map ().end ()) + file = i->second; + else { + // TODO: temporary hack + int len = ((Token*)funit->last ())->location ().line (); + // TODO: in the future, handle aspect headers differently + ACM_Header *new_file = newHeader(); + get_files().insert(new_file); + new_file->set_filename(model_filename (funit)); + new_file->set_len(len); + new_file->get_in().insert(_tunit_file); + new_file->set_time (modification_time (funit)); + file = new_file; + file_map ().insert (PumaModelBuilder::FileMapPair (funit, file)); + } + int line = token.location ().line (); + int len = end_token.location ().line () - line + 1; + // TODO: really use linear search here? + typedef ACM_Container Container; + const Container &sources = name->get_source (); + bool found = false; + for (Container::const_iterator i = sources.begin(); i != sources.end(); ++i) { + if ((*i)->get_line () == line && + (*i)->get_file () == file && + (*i)->get_kind () == kind && + (*i)->get_len () == len) { +// if ((*i)->get_len () != len) +// _err << sev_warning << "Internal problem: Length differs for source at same location (file='" << file->get_filename().c_str () << "', line=" +// << line << ")" << endMessage; + found = true; + break; + } + } + if (!found) { + ACM_Source *source = newSource(); + source->set_file(file); + source->set_line(line); + source->set_len(len); + source->set_kind(kind); + name->get_source().insert(source); + } +} + + +FileUnit *PumaModelBuilder::source_unit (CTree *tree) const { + if (!tree || !tree->token ()) + return 0; + return ACPreprocessor::source_unit (ACToken (tree->token())); +} + +string PumaModelBuilder::tree_to_string (CTree *node) { + string result; + if (node->NodeName () == CT_Token::NodeId ()) + result = node->token ()->text (); + else { + for (int s = 0; s < node->Sons (); s++) { + if (s > 0) result += " "; + result += tree_to_string (node->Son (s)); + } + } + return result; +} diff --git a/AspectC++/PumaModelBuilder.h b/AspectC++/PumaModelBuilder.h new file mode 100644 index 0000000..87ce816 --- /dev/null +++ b/AspectC++/PumaModelBuilder.h @@ -0,0 +1,220 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __PumaModelBuilder_h__ +#define __PumaModelBuilder_h__ + +#include "ACModel/Elements.h" +#include "ACToken.h" +#include "TransformInfo.h" +#include "ACProject.h" +#include "ACErrorStream.h" + +namespace Puma { + class CTranslationUnit; + class CSemDatabase; + class CStructure; + class CScopeInfo; + class ACSliceInfo; + class VerboseMgr; + class FileUnit; +} + +class ACConfig; + +struct AccessInfo { + Puma::CAttributeInfo *_info; + Puma::CTree *_tree; + AccessInfo () {} + AccessInfo (Puma::CAttributeInfo *info, Puma::CTree *tree) : + _info (info), _tree (tree) {} + +}; + + +class PumaModelBuilder : public ProjectModel { + + Puma::VerboseMgr &_vm; + ACErrorStream &_err; + ACConfig &_conf; + ACProject &_project; + ACM_TUnit *_tunit_file; + +public: + // map needed to check if a file is already known + typedef map FileMap; + typedef FileMap::value_type FileMapPair; + FileMap _file_map; + FileMap &file_map() { return _file_map; } + +private: + + int _tunit_len; + + // TODO: temporary solution + list _access_infos; + + int _time; + + void build (Puma::CTranslationUnit& tunit); + void build (Puma::CStructure &structure, ACM_Name *jpl = 0); + void advice_infos (ACM_Aspect *jpl_aspect); +// void check (ACM_Aspect *jpl_aspect, ACIntroductionInfo *acii, ACM_Introduction *intro); + + // transform a syntax tree into a string + static string tree_to_string (Puma::CTree *node); + +public: + + // determine a model element filename for a unit + string model_filename (Puma::FileUnit *unit); + + // get the modification time of a file (UNIX Epoch value) + long modification_time (Puma::FileUnit *unit); + + PumaModelBuilder (Puma::VerboseMgr &vm, ACErrorStream &err, ACConfig &conf, ACProject &project) : + _vm (vm), _err (err), _conf (conf), _project(project) {} + ACProject &get_project () const { return _project; } + void setup_phase1 (Puma::FileUnit *unit, int tunit_len); + void setup_phase2 (Puma::CTranslationUnit& tunit, list &ah_trees); + + bool is_valid_model_class (Puma::CClassInfo *ci) const; + bool is_intro_target (Puma::CClassInfo *ci) const; + bool is_valid_model_function (Puma::CFunctionInfo *fi) const; + bool is_valid_model_namespace (Puma::CNamespaceInfo *ni) const; + + bool inside_template (Puma::CScopeInfo *scope) const; + static bool inside_template_instance (Puma::CScopeInfo *scope); + + // create a type in the join point model from a Puma node + TU_Type *register_type (Puma::CTypeInfo *ti); + + // create a (pointcut) argument in the join point model from a Puma node + TU_Arg *register_arg (Puma::CTypeInfo *ti, const string &name); + + // get the translation unit as a model object + ACM_TUnit *tunit_file () const { return _tunit_file; } + + // create a named pointcut in the join point model (phase 1) + ACM_Pointcut *register_pointcut1 (ACM_Name *parent, const std::string &name, + bool is_virtual, const std::string& expr); + bool overrides_virtual_pointcut (ACM_Name *parent, const string &name); // helper function + + + // create a named pointcut in the join point model from a Puma node + TU_Pointcut *register_pointcut (Puma::CFunctionInfo *fi, ACM_Name *parent); + + // create a function in the join point model from a Puma node + TU_Function *register_function (Puma::CFunctionInfo *fi, ACM_Name *parent = 0); + + // create a global variable or member variable in the join point model + TU_Variable *register_variable (Puma::CObjectInfo *oi, ACM_Name *parent = 0); + + // create a class slice in the join point model (phase 1) + ACM_ClassSlice *register_class_slice (ACM_Name *scope, string name, bool is_struct); + +// // create a class slice in the join point model from a Puma node +// TU_ClassSlice *register_class_slice (ACSliceInfo *acsi, ACM_Name *parent = 0); + + // create a class in the join point model (phase 1) + ACM_Class *register_class1 (ACM_Name *scope, std::string name, bool in_project = true); + + // create a class in the join point model from a Puma node + TU_Class *register_class (Puma::CClassInfo *ci, ACM_Name *parent = 0, bool set_source = true); + + // create an aspect in the join point model (phase 1) + ACM_Aspect *register_aspect1 (ACM_Name *scope, std::string name, + bool in_project = true); + + // create an aspect in the join point model from a Puma node + TU_Aspect *register_aspect (Puma::CClassInfo *ci, ACM_Name *parent = 0); + + // create a Namespace in the join point model (phase 1) + ACM_Namespace *register_namespace1 (ACM_Name *scope, std::string name, + bool in_project = true); + + // create a Namespace in the join point model from a Puma node (phase 2) + TU_Namespace *register_namespace (Puma::CNamespaceInfo *ni, ACM_Name *parent = 0); + + // create a new call join point in the join point model + TU_MethodCall *register_call (Puma::CFunctionInfo *called, Puma::CT_Call *call_node, + Puma::CObjectInfo *caller, int local_id); + + // create a new execution join point + TU_Method *register_execution (ACM_Function *ef); + + // create a new construction join point + TU_Construction *register_construction (ACM_Function *cf); + + // create a new construction join point + TU_Destruction *register_destruction (ACM_Function *df); + + // TODO: temporary solution for dac++ + void register_attr_access (Puma::CAttributeInfo *attr, Puma::CTree *node); + + // register the scope of a given element + ACM_Name *register_scope (Puma::CObjectInfo *obj); + + // extended types... + // factory methods that remember all objects of this model + virtual TU_CodeAdvice *newCodeAdvice() { return remember (new TU_CodeAdvice, JPTI_CodeAdvice); } + virtual TU_Type *newType() { return remember (new TU_Type, JPTI_Type); } + virtual TU_Arg *newArg() { return remember (new TU_Arg, JPTI_Arg); } + virtual TU_Namespace *newNamespace() { return remember (new TU_Namespace, JPTI_Namespace); } + virtual TU_Variable *newVariable() { return remember (new TU_Variable, JPTI_Variable); } + virtual TU_Function *newFunction() { return remember (new TU_Function, JPTI_Function); } + virtual TU_Class *newClass() { return remember (new TU_Class, JPTI_Class); } + virtual TU_ClassSlice *newClassSlice() { return remember (new TU_ClassSlice, JPTI_ClassSlice); } + virtual TU_MethodCall *newCall() { return remember (new TU_MethodCall, JPTI_Call); } + virtual TU_Method *newExecution() { return remember (new TU_Method, JPTI_Execution); } + virtual TU_Construction *newConstruction() { return remember (new TU_Construction, JPTI_Construction); } + virtual TU_Destruction *newDestruction() { return remember (new TU_Destruction, JPTI_Destruction); } + virtual TU_Pointcut *newPointcut() { return remember (new TU_Pointcut, JPTI_Pointcut); } + virtual TU_AdviceCode *newAdviceCode() { return remember (new TU_AdviceCode, JPTI_AdviceCode); } + virtual TU_Introduction *newIntroduction() { return remember (new TU_Introduction, JPTI_Introduction); } + virtual TU_Order *newOrder() { return remember (new TU_Order, JPTI_Order); } + virtual TU_Aspect *newAspect() { return remember (new TU_Aspect, JPTI_Aspect); } + + // return the name of the scope of an object + static string scope_name (Puma::CObjectInfo *oi); + + // return the scope of an object + static Puma::CScopeInfo *scope_obj (Puma::CObjectInfo *oi); + + // add the source location to a model element by using a given CObjectInfo + void add_source_loc (ACM_Any *name, Puma::CObjectInfo *obj, SourceLocKind kind = SLK_NONE) { + add_source_loc (name, obj->Tree (), kind); + } + // add the source location to a model element by using the syntax tree node + void add_source_loc (ACM_Any *name, Puma::CTree *tree, SourceLocKind kind = SLK_NONE) { + if (tree) + add_source_loc (name, ACToken (tree->token ()), ACToken (tree->end_token()), kind); + } + // add the source location to a model element by using the token information + void add_source_loc (ACM_Any *name, ACToken token, ACToken end_token, SourceLocKind kind = SLK_NONE); + + // determine the file unit, which contains a specific token (macro expansions and introdutions are followed) + Puma::FileUnit *source_unit (ACToken token) const; + // determine the file unit, which contains a specific syntax (sub-)tree + Puma::FileUnit *source_unit (Puma::CTree *tree) const; + + // TODO: temporary solution + const list &access_infos () const { return _access_infos; } +}; + +#endif diff --git a/AspectC++/PumaPreprocessor.cc b/AspectC++/PumaPreprocessor.cc new file mode 100644 index 0000000..a99a1e1 --- /dev/null +++ b/AspectC++/PumaPreprocessor.cc @@ -0,0 +1,156 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "PumaPreprocessor.h" +#include "IncludeGraph.h" +#include "IntroductionUnit.h" + +using namespace Puma; +using namespace std; + + +PumaPreprocessor::PumaPreprocessor (const string &tunit_name, ACConfig &conf, CProject &project) : + _tunit_name (tunit_name), _conf (conf), _project (project), _local_units(_project.err ()), + _cpp (&_project.err (), &_project.unitManager (), &_local_units, cout), + _provider(_cpp), _recorded_tokens (0) { + + // scan file + _unit = _project.scanFile (tunit_name.c_str()); + if (!_unit) + return; + + // prepare C preprocessor + _stream.push (_unit); + _project.unitManager ().init (); + _cpp.macroManager ()->init (_unit->name ()); + _cpp.stream (&_stream); + _cpp.configure (_project.config ()); + _provider.init (); + + // fetch the first token + locate_token (); + +} + +// return the include graph *after* preprocessing the translation unit +void PumaPreprocessor::get_include_graph (IncludeGraph &include_graph) { + // finally parse the preprocessor syntax tree in order to create an + // include graph of the original source code + include_graph.init (_cpp.syntaxTree()); +} + +Puma::ErrorStream &PumaPreprocessor::err () const { + return _project.err (); +} + +bool PumaPreprocessor::keywords_enabled (Puma::Token *tok) const { + if (!tok) + return false; + + Unit *unit = tok->unit (); + while (unit && unit->isMacroExp ()) { + unit = ((MacroUnit*)unit)->CallingUnit (); + } + + if (!unit->isFile ()) // TODO: is that case possible? + return false; + + if (!_project.isBelow(unit)) + return false; + + size_t len = strlen (unit->name ()); + if (len > 2 && strcmp (unit->name () + (len - 3), ".ah") == 0) + return true; + + return _conf.keywords(); +} + +ACToken PumaPreprocessor::next_token () { + _provider.next (); + ACToken result = locate_token (); + if (_recorded_tokens && result != ACToken::TOK_EOF) + _recorded_tokens->append(*result.get ()->duplicate()); + return result; +} + +ACToken PumaPreprocessor::curr_token () { + Token *token = _provider.current (); + return ACToken (token, keywords_enabled (token)); +} + +ACToken PumaPreprocessor::look_ahead (int n) { + TokenProvider::State state = _provider.get_state (); + while (n > 0) { + _provider.next (); + locate_token (); + n--; + } + Token *token = _provider.current (); + _provider.set_state (state); + return ACToken (token, keywords_enabled(token)); +} + +ACToken PumaPreprocessor::locate_token () { + Token *token; + while ((token = _provider.current ()) && ! token->is_core ()) { +// TODO: handle directives here? +// if (token->is_directive ()) +// handle_directive (); +// else + _provider.next (); + } + return ACToken (token, keywords_enabled(token)); +} + +// functions to record the token stream + +void PumaPreprocessor::start_recording () { + if (!_recorded_tokens) { + _recorded_tokens = new Unit; +// _recorded_tokens->name(((Unit*)_jpm.source_unit(curr_token()))->name ()); + _recorded_tokens->append(*curr_token().get ()->duplicate()); + } +} + +Unit *PumaPreprocessor::stop_recording () { + Unit *result = _recorded_tokens; + _recorded_tokens = 0; + return result; +} + +FileUnit *PumaPreprocessor::source_unit (ACToken token) { + Unit *unit = token.unit (); + while (unit && unit->isMacroExp ()) { + unit = ((MacroUnit*)unit)->CallingUnit (); + } + // if the 'insert unit' is an 'introduction unit', find the intro target unit + IntroductionUnit *intro_unit = IntroductionUnit::cast (unit); + if (intro_unit) unit = intro_unit->final_target_unit (); + + // at this point we must have reached a file unit + if (!unit->isFile ()) + return 0; + + return (FileUnit*)unit; +} + +// check whether a token is located within the files of the project +bool PumaPreprocessor::is_in_project(ACToken token) const { + FileUnit *funit = source_unit(token); + return funit && _project.isBelow(funit); +} diff --git a/AspectC++/PumaPreprocessor.h b/AspectC++/PumaPreprocessor.h new file mode 100644 index 0000000..91df73a --- /dev/null +++ b/AspectC++/PumaPreprocessor.h @@ -0,0 +1,79 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __PumaPreprocessor_h__ +#define __PumaPreprocessor_h__ + +#include "ACConfig.h" +#include "ACToken.h" +#include "IncludeGraph.h" +#include "CodeWeaver.h" + +#include "Puma/TokenStream.h" +#include "Puma/PreprocessorParser.h" +#include "Puma/CProject.h" + +// This class performs preprocesses a translation unit and returns its +// content token by token. Upon request, it can also record the returned +// tokens. + +class PumaPreprocessor { + + string _tunit_name; + Puma::Unit *_unit; + ACConfig &_conf; + Puma::CProject &_project; + Puma::TokenStream _stream; + Puma::UnitManager _local_units; + Puma::PreprocessorParser _cpp; + Puma::TokenProvider _provider; + Puma::Unit *_recorded_tokens; + ACToken _record_start; + ACToken _record_end; + + bool keywords_enabled (Puma::Token *tok) const; + +public: + PumaPreprocessor (const string &tunit_name, ACConfig &conf, Puma::CProject &project); + + Puma::Unit *unit () const { return _unit; } + + // functions to access the token stream + ACToken next_token (); + ACToken curr_token (); + ACToken look_ahead (int n = 1); + ACToken locate_token (); + + // functions to record the token stream + void start_recording (); + Puma::Unit *stop_recording (); + + Puma::ErrorStream &err () const; + + // return the include graph *after* preprocessing the translation unit + void get_include_graph (IncludeGraph &include_graph); + + // get the file unit in which a token is located + // (if necessary follow macro expansions and intros) + static Puma::FileUnit *source_unit (ACToken token); + + // check whether a token is located within the files of the project + bool is_in_project(ACToken token) const; +}; + +#endif // __PumaPreprocessor_h__ diff --git a/AspectC++/PumaResultBuffer.cc b/AspectC++/PumaResultBuffer.cc new file mode 100644 index 0000000..983311a --- /dev/null +++ b/AspectC++/PumaResultBuffer.cc @@ -0,0 +1,151 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "PumaResultBuffer.h" +#include "Puma/CTypeInfo.h" +#include +using std::stringstream; +using namespace Puma; + +bool PumaResultBuffer::has_constructor_problem () const { + return _type->isRecord () && !_type->isAddress (); +} + +string PumaResultBuffer::tjp_result_type () const { + stringstream out; + CTypeInfo *type = _type; + if (type->isVoid () || type->isUndefined ()) + out << "void"; + else if (type->isAddress ()) { + if (_use_typedef) { + if (type->BaseType()->isConst()) + out << "const "; + out << "TResult"; + } + else + type->BaseType ()->TypeText (out, "", true, true); + } + else + if (_use_typedef) { + if (type->isConst()) + out << "const "; + out << "TResult"; + } + else + type->TypeText (out, "", true, true); + return out.str (); +} + +string PumaResultBuffer::result_type (const string &name, bool unqual) const { + stringstream out; + CTypeInfo *type = _type; + if (unqual) + type = type->UnqualType (); + if (type->isVoid () || type->isUndefined ()) + out << "void"; + else if (type->isAddress ()) { + string ptrname = string ("*") + name; + if (_use_typedef) { + if (type->BaseType()->isConst()) + out << "const "; + out << "TResult " << ptrname; + } + else { + if (type->BaseType ()->TypeFunction () || type->BaseType ()->TypeArray ()) + ptrname = string("(") + ptrname + ")"; + type->BaseType ()->TypeText (out, ptrname.c_str (), true, true); + } + } + else + if (_use_typedef) { + if (type->isConst()) + out << "const "; + out << "TResult " << name; + } + else + type->TypeText (out, name.c_str (), true, true); + return out.str (); +} + +string PumaResultBuffer::result_declaration() const { + stringstream out; + if (!(_type->isVoid () || _type->isUndefined ())) { + if (_problem) + out << "AC::ResultBuffer< " << result_type ("", false) << " > " << result_name(); + else + out << result_type (result_name(), true); + out << ";" << endl; + } + return out.str (); +} + +string PumaResultBuffer::result_assignment(const string &result) const { + stringstream out; + if (!(_type->isVoid() || _type->isUndefined ())) { + if (_problem) { + out << "::new (&" << result_name() << ") "; + out << result_type ("", true); + out << " ("; + } + else + out << result_name() << " = "; + if (_type->isAddress ()) + out << "&"; + } + out << result; + if (!(_type->isVoid() || _type->isUndefined ())) + if (_problem) + out << ")"; + return out.str (); +} + +string PumaResultBuffer::action_result_assignment(const string &result) const { + stringstream out; + if (!(_type->isVoid() || _type->isUndefined ())) { + if (_problem) { + out << "::new ((AC::ResultBuffer< "; + out << result_type ("", false); + out << " >*)__TJP::result ()) "; + out << result_type ("", false); + out << " ("; + } + else { + out << "*__TJP::result () = (" << result_type ("", false) << ")"; + } + if (_type->isAddress ()) + out << "&"; + } + out << result; + if (!(_type->isVoid() || _type->isUndefined ())) + if (_problem) + out << ")"; + return out.str (); +} + +string PumaResultBuffer::result_return() const { + stringstream out; + if (!(_type->isVoid () || _type->isUndefined ())) { + out << "return "; + if (_type->isAddress ()) + out << "*"; + out << "("; + out << result_type ("&"); + out << ")" << result_name() << ";" << endl; + } + return out.str (); +} diff --git a/AspectC++/PumaResultBuffer.h b/AspectC++/PumaResultBuffer.h new file mode 100644 index 0000000..b47872e --- /dev/null +++ b/AspectC++/PumaResultBuffer.h @@ -0,0 +1,64 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __PumaResultBuffer_h__ +#define __PumaResultBuffer_h__ + +#include "ACModel/Elements.h" +#include "TransformInfo.h" +#include "ACProject.h" + +#include +using std::string; + +namespace Puma { + class CTypeInfo; +} + +class PumaResultBuffer { + Puma::CTypeInfo *_type; + bool _problem; + bool _use_typedef; + bool has_constructor_problem () const; +public: + PumaResultBuffer (Puma::CTypeInfo *t, bool use_typedef = false) : + _type (t), _use_typedef (use_typedef) { + _problem = has_constructor_problem (); + } + PumaResultBuffer (ACProject &project, ACM_Code *jpl, bool use_typedef = false) : + _use_typedef (use_typedef) { + assert( has_entity_func( *jpl ) ); + ACM_Function *func = get_entity_func( *jpl ); + Puma::CFunctionInfo *fi = TI_Function::of (*func)->func_info(); + Puma::CTypeFunction *ftype = fi->TypeInfo ()->TypeFunction (); + _type = fi->isConversion () ? fi->ConversionType () : ftype->BaseType (); + _problem = has_constructor_problem (); + } + string tjp_result_type () const; + string result_type (const string &name, bool unqual = false) const; + string result_declaration() const; + string result_assignment(const string &result) const; + string action_result_assignment(const string &result) const; + string result_return() const; + + // the name of the result buffer allocated in each wrapper function. + // must not shadow the functions' arguments + static const string result_name() { return "__result_buffer"; } +}; + +#endif // __PumaResultBuffer_h__ diff --git a/AspectC++/PumaSyntacticContext.cc b/AspectC++/PumaSyntacticContext.cc new file mode 100644 index 0000000..f0f6def --- /dev/null +++ b/AspectC++/PumaSyntacticContext.cc @@ -0,0 +1,73 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "PumaSyntacticContext.h" + +using namespace Puma; + +// search the set of actually *used* arguments (needed only for constructor +// wrapper functions). +void PumaSyntacticContext::search_used_args (set &args, CTree *tree) const { + if (!tree) { + assert (_obj->FunctionInfo() && _obj->Tree()->NodeName() == CT_FctDef::NodeId ()); + tree = ((CT_FctDef*)_obj->Tree ())->Body(); + } + + CObjectInfo *obj; + const char *nodename = tree->NodeName (); + + if (nodename == CT_SimpleName::NodeId () && + (obj = ((CT_SimpleName*)tree)->Object ()) && + obj->ArgumentInfo() && + obj->ArgumentInfo()->Scope () && + obj->ArgumentInfo()->Scope () == _obj) { + args.insert (obj->Name ().c_str ()); + } + + for (int s = 0; s < tree->Sons (); s++) + if (tree->Son(s)) + search_used_args (args, tree->Son (s)); +} + +void PumaSyntacticContext::print_tree (ostream &out, CTree *node, bool expand_implicit_calls) { + + if (expand_implicit_calls && node->NodeName () == CT_ImplicitCall::NodeId() && + !((CT_ImplicitCall*)node)->Object()->FunctionInfo()->isConstructor()) { + out << "("; + print_tree (out, node->Son (0), expand_implicit_calls); + out << ")." << ((CT_ImplicitCall*)node)->Object()->Name().c_str () << "()"; + } + else if (node->NodeName () == CT_Token::NodeId ()) + out << node->token ()->text () << " "; + else + for (int s = 0; s < node->Sons (); s++) + print_tree (out, node->Son (s), expand_implicit_calls); +} + +int PumaSyntacticContext::is_in_extern_c_block () const { + Puma::CTree *tree = _obj->Tree (); + assert (tree); + int depth = 0; + while (tree->NodeName () != Puma::CT_Program::NodeId ()) { + if (tree->NodeName() == Puma::CT_LinkageSpec::NodeId () && + ((Puma::CT_LinkageSpec*)tree)->isList()) + depth++; + tree = tree->Parent(); + } + return depth; +} diff --git a/AspectC++/PumaSyntacticContext.h b/AspectC++/PumaSyntacticContext.h new file mode 100644 index 0000000..6a9df1d --- /dev/null +++ b/AspectC++/PumaSyntacticContext.h @@ -0,0 +1,245 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __PumaSyntacticContext_h__ +#define __PumaSyntacticContext_h__ + +// Puma includes +#include "Puma/CAttributeInfo.h" +#include "Puma/CArgumentInfo.h" +#include "Puma/CClassInfo.h" +#include "Puma/CFunctionInfo.h" +#include "Puma/CTree.h" +#include "Puma/CProject.h" +#include "Puma/CSemDatabase.h" + +// AspectC++ includes +#include "WeaverBase.h" +#include "IntroductionUnit.h" + +class PumaSyntacticContext { + Puma::CObjectInfo *_obj; + + // return LinkageSpec node for extern "C" like declarations + static Puma::CTree *linkage_adjust (Puma::CT_Decl *decl) { + Puma::CT_LinkageSpec *linkage = decl->Linkage (); + return (!linkage || linkage->isList ()) ? decl : linkage; + } + + Puma::Token *wrapper_token () const { + Puma::CTree *tree = _obj->Tree (); + assert (tree); + Puma::CTree *pos = 0; + if (tree->NodeName() == Puma::CT_InitDeclarator::NodeId()) { + // move the generated declaration in front of the original declaration + Puma::CT_ObjDecl *objdecl = ((Puma::CT_InitDeclarator*)tree)->ObjDecl (); + // handle extern "C" declarations + pos = linkage_adjust (objdecl); + } + if (tree->NodeName() == Puma::CT_FctDef::NodeId()) { + pos = linkage_adjust((Puma::CT_FctDef*)tree); + } + assert (pos); + return pos->token (); + } + + static void print_tree (ostream &out, Puma::CTree *node, bool expand_implicit_calls = false); + +public: + PumaSyntacticContext (Puma::CObjectInfo *o = 0) : _obj (o) {} + bool operator < (const PumaSyntacticContext &that) const { return _obj < that._obj; } + + void set_object (Puma::CObjectInfo *o) { _obj = o; } + + string name () const { return _obj->Name ().c_str (); } + + string get_as_string (int indentation = 0) const { + ostringstream os; + while (indentation-- >= 0) + os << " "; + Puma::CTree *tree = _obj->Tree (); + if (tree->NodeName() == Puma::CT_InitDeclarator::NodeId()) { + print_tree (os, ((Puma::CT_InitDeclarator*)tree)->ObjDecl ()->DeclSpecs ()); + os << " "; + } + print_tree (os, tree); + return os.str (); + } + + string type () const { + stringstream str; + _obj->TypeInfo()->TypeText(str, "", true, true); + return str.str(); + } + + bool is_anon_union_member () const { + return _obj->Scope ()->isUnion (); + } + + bool is_array () const { + return _obj->TypeInfo ()->TypeArray (); + } + + PumaSyntacticContext get_anon_union_context () const { + assert (is_anon_union_member ()); + return PumaSyntacticContext (_obj->Scope ()); + } + + bool is_definition () const { + if (_obj->FunctionInfo ()) + return _obj->FunctionInfo ()->isFctDef (); + return false; + } + + bool has_assigned_scope () const { + return _obj->AssignedScope (); + } + + // returns 0 if not in an extern "C" { ... } block, otherwise (result >= 1) the + // result is the depth of nested extern "C" blocks + int is_in_extern_c_block () const; + + bool is_in_class_scope () const { + return _obj->ClassScope () && (_obj->Scope() == _obj->ClassScope()); + } + + bool is_in_namespace () const { + return _obj->Scope ()->isNamespace(); + } + + bool is_in_project () const { + if (_obj->isBuiltin()) + return false; + Puma::Unit *unit = _obj->SourceInfo ()->SrcUnit (); + if (!_obj->SemDB ()->Project ()->isBelow (unit) && + !IntroductionUnit::cast (unit)) + return false; + return true; + } + + string protection () const { + string result; + switch (_obj->Protection()) { + case Puma::CProtection::PROT_PUBLIC: result = "public"; break; + case Puma::CProtection::PROT_PRIVATE: result = "private"; break; + case Puma::CProtection::PROT_PROTECTED: result = "protected"; break; + case Puma::CProtection::PROT_NONE: result = ""; + } + return result; + } + + const WeavePos &wrapper_pos (WeaverBase &wb) const { + Puma::Token *tok = wrapper_token (); + return wb.weave_pos(tok, WeavePos::WP_BEFORE); + } + + Puma::Token *error_pos () const { + return _obj->Tree()->token(); + } + + const WeavePos &fct_body_start_pos (WeaverBase &wb) const { + Puma::CTree *tree = _obj->Tree (); + assert (tree && tree->NodeName() == Puma::CT_FctDef::NodeId()); + Puma::Token *tok = ((Puma::CT_FctDef*)tree)->Body()->token (); + return wb.weave_pos(tok, WeavePos::WP_BEFORE); + } + + const WeavePos &fct_body_end_pos (WeaverBase &wb) const { + Puma::CTree *tree = _obj->Tree (); + assert (tree && tree->NodeName() == Puma::CT_FctDef::NodeId()); + Puma::Token *tok = ((Puma::CT_FctDef*)tree)->Body()->end_token (); + return wb.weave_pos(tok, WeavePos::WP_BEFORE); + } + + const WeavePos &objdecl_start_pos (WeaverBase &wb) const { + Puma::CTree *tree = _obj->Tree (); + if (tree->NodeName() == Puma::CT_InitDeclarator::NodeId()) + tree = ((Puma::CT_InitDeclarator*)tree)->ObjDecl (); + Puma::Token *tok = tree->token (); + return wb.weave_pos(tok, WeavePos::WP_BEFORE); + } + + const WeavePos &objdecl_end_pos (WeaverBase &wb) const { + Puma::CTree *tree = _obj->Tree (); + Puma::Token *tok = tree->end_token (); + return wb.weave_pos(tok, WeavePos::WP_AFTER); + } + + bool ends_with_return () const { + assert (_obj->FunctionInfo() && _obj->Tree ()->NodeName () == Puma::CT_FctDef::NodeId()); + Puma::CT_FctDef *fctdef = (Puma::CT_FctDef*)_obj->Tree (); + Puma::CTree *last_stmt = 0; + int entries = fctdef->Body()->Entries(); + if (entries > 0) + last_stmt = fctdef->Body()->Entry (entries - 1); + return (last_stmt && last_stmt->NodeName() == Puma::CT_ReturnStmt::NodeId()); + } + + // search the set of actually *used* arguments (needed only for constructor + // wrapper functions). + void search_used_args (set &args, Puma::CTree *tree = 0) const; + + string result_type (const string &name = "") const { + Puma::CFunctionInfo *func = _obj->FunctionInfo(); + assert(func); + Puma::CTypeInfo *type = func->isConversion () ? func->ConversionType () : + func->TypeInfo ()->BaseType (); + ostringstream type_str; + type->TypeText (type_str, name.c_str (), true, true); + return type_str.str (); + } + + unsigned int args () const { + Puma::CFunctionInfo *func = _obj->FunctionInfo(); + assert(func); + return func->Arguments(); + } + + string arg_name (unsigned int no) const { + Puma::CFunctionInfo *func = _obj->FunctionInfo(); + assert(func); + Puma::CArgumentInfo *arg = func->Argument(no); + return arg->isAnonymous() ? "" : arg->Name ().c_str(); + } + + string arg_type (unsigned int no, const string &name = "") const { + Puma::CFunctionInfo *func = _obj->FunctionInfo(); + assert(func); + ostringstream type_str; + Puma::CTypeInfo *type = func->Argument(no)->TypeInfo(); + type->TypeText(type_str, name.c_str (), true, true); + return type_str.str (); + } + + string qualified_scope () const { + if (_obj->QualifiedScope()) + return _obj->QualifiedScope()->QualName(); + return ""; + } + + string syntactical_scope () const { + return _obj->Scope()->QualName(); + } + + // TODO: still needed? + Puma::CObjectInfo *object () const { return _obj; } +}; + +#endif // __PumaSyntacticContext_h__ + + diff --git a/AspectC++/PumaToken.h b/AspectC++/PumaToken.h new file mode 100644 index 0000000..de6bf71 --- /dev/null +++ b/AspectC++/PumaToken.h @@ -0,0 +1,119 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2013 The 'ac++' developers (see aspectc.org) +// +// 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 __PumaToken_h__ +#define __PumaToken_h__ + +#include "Puma/Token.h" +#include "Puma/CTokens.h" + +// PumaToken - Provides a uniform wrapper for a Token object. +class PumaToken { +public: + enum Kind { + // Translate from Puma token kinds into our subset of Puma ones. + TOK_ASSIGN = Puma::TOK_ASSIGN, + TOK_ALIGNAS = -1, // FIXME: not defined in Puma yet + TOK_ATTRIBUTE = Puma::TOK_ATTRIBUTE, + TOK_CLASS = Puma::TOK_CLASS, + TOK_CLOSE_CURLY = Puma::TOK_CLOSE_CURLY, + TOK_CLOSE_ROUND = Puma::TOK_CLOSE_ROUND, + TOK_CLOSE_SQUARE = Puma::TOK_CLOSE_SQUARE, + TOK_COLON = Puma::TOK_COLON, + TOK_COLON_COLON = Puma::TOK_COLON_COLON, + TOK_COMMA = Puma::TOK_COMMA, + TOK_CONST = Puma::TOK_CONST, + TOK_ENUM = Puma::TOK_ENUM, + TOK_FRIEND = Puma::TOK_FRIEND, + TOK_GREATER = Puma::TOK_GREATER, + TOK_ID = Puma::TOK_ID, + TOK_LESS = Puma::TOK_LESS, + TOK_NAMESPACE = Puma::TOK_NAMESPACE, + TOK_MUL = Puma::TOK_MUL, + TOK_OPEN_CURLY = Puma::TOK_OPEN_CURLY, + TOK_OPEN_ROUND = Puma::TOK_OPEN_ROUND, + TOK_OPEN_SQUARE = Puma::TOK_OPEN_SQUARE, + TOK_PRIVATE = Puma::TOK_PRIVATE, + TOK_PROTECTED = Puma::TOK_PROTECTED, + TOK_PTS = Puma::TOK_PTS, + TOK_PUBLIC = Puma::TOK_PUBLIC, + TOK_SEMI_COLON = Puma::TOK_SEMI_COLON, + TOK_STATIC = Puma::TOK_STATIC, + TOK_STRUCT = Puma::TOK_STRUCT, + TOK_TEMPLATE = Puma::TOK_TEMPLATE, + TOK_TILDE = Puma::TOK_TILDE, + TOK_TYPEDEF = Puma::TOK_TYPEDEF, + TOK_UNION = Puma::TOK_UNION, + TOK_USING = Puma::TOK_USING, + TOK_VIRTUAL = Puma::TOK_VIRTUAL, + TOK_VOLATILE = Puma::TOK_VOLATILE, + TOK_ASPECT = Puma::TOK_ASPECT, + TOK_ADVICE = Puma::TOK_ADVICE, + TOK_POINTCUT = Puma::TOK_POINTCUT, + TOK_SLICE = Puma::TOK_SLICE, + // Attention: we assume that Puma tokens are enumerated from 0 to a number smaller than 0x10000 + TOK_EOF = 0x10000, + TOK_ATTRDECL, + TOK_INVALID, + TOK_UNKNOWN + }; + +private: + Puma::Token *_token; + Kind _kind; + +public: + PumaToken () : _token(0), _kind (TOK_INVALID) {} + explicit PumaToken (Puma::Token *token, bool acxx_keyword = false) : + _token(token), _kind (token ? Kind (token->type ()) : TOK_EOF) { + if (acxx_keyword && _kind == TOK_ID) { + const char *text = this->text (); + if (!strcmp(text, "aspect")) + _kind = TOK_ASPECT; + else if (!strcmp(text, "advice")) + _kind = TOK_ADVICE; + else if (!strcmp(text, "pointcut")) + _kind = TOK_POINTCUT; + else if (!strcmp(text, "slice")) + _kind = TOK_SLICE; + else if (!strcmp(text, "attribute")) + _kind = TOK_ATTRDECL; + } + } + + bool is_core () const { return _token->is_core (); } + bool is_directive () const { return _token->is_directive (); } + bool is_macro_generated () const { return _token->is_macro_generated (); } + Puma::Unit *unit () const { return _token->unit (); } + Puma::Location location () const { return _token->location (); } + int type () const { return _kind; } + const char *text () const { return _token ? _token->text () : (const char*)0; } + + // Interface to get the underlying token. + Puma::Token *get() const { return _token; } + operator bool () const { return _token != 0; } + bool operator== (const PumaToken &rhs) const { return _token == rhs._token; } + bool operator!= (const PumaToken &rhs) const { return _token != rhs._token; } + // FIXME: Are those actually useful? + bool operator< (const PumaToken &rhs) const { return _token < rhs._token; } + bool operator> (const PumaToken &rhs) const { return _token > rhs._token; } + bool operator<= (const PumaToken &rhs) const { return _token <= rhs._token; } + bool operator>= (const PumaToken &rhs) const { return _token <= rhs._token; } +}; + +#endif /* __PumaToken_h__ */ diff --git a/AspectC++/PumaTrackerDog.cc b/AspectC++/PumaTrackerDog.cc new file mode 100644 index 0000000..a22aad6 --- /dev/null +++ b/AspectC++/PumaTrackerDog.cc @@ -0,0 +1,277 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "PumaTrackerDog.h" +#include "IntroductionUnit.h" +#include "ModelBuilder.h" + +#include "Puma/CFunctionInfo.h" +#include "Puma/CClassInfo.h" +#include "Puma/CRecord.h" +#include "Puma/CTree.h" + +using namespace Puma; + +CObjectInfo *PumaTrackerDog::unique_object (CObjectInfo *obj) { + unsigned long fpos = 0L; + CObjectInfo *first = 0; + CObjectInfo *curr = obj; + do { + // builtin objects might have a declaration, but the generated obj is ret. + if (curr->isBuiltin ()) + return curr; + CTree *tree = curr->Tree (); + unsigned long cpos = tree->token_node ()->Number (); + // if the current node is not a forward declaration, it will be returned + if (tree->NodeName () == CT_ClassDef::NodeId () || + tree->NodeName () == CT_FctDef::NodeId ()) + return curr; + // check if the current forward declaration was the first + if (!first || cpos < fpos) { + fpos = cpos; + first = curr; + } + curr = curr->NextObject (); + } while (curr != obj); + // if there were only forward declarations, return the first + return first; +} + + +CFunctionInfo *PumaTrackerDog::filter_func (CFunctionInfo* fi) { + CRecord *cls = fi->ClassScope (); + + if (fi->isBuiltin () || fi->isTemplate () || + (cls && cls->isTemplate ()) || + strncmp (fi->Name (), "%a", 2) == 0 || + strncmp (fi->Name (), "__a", 3) == 0 || + strcmp (fi->Name (), "aspectof") == 0 || + strcmp (fi->Name (), "aspectOf") == 0 || + fi != unique_object (fi)) + return 0; + + if (strcmp (fi->SourceInfo ()->FileName (), "") == 0) + return 0; + + if (cls && + (strcmp (cls->QualName (), "__JoinPoint") == 0 || + strcmp (cls->QualName (), "AC::Action") == 0)) + return 0; + +// CSemDatabase &db = *(CSemDatabase*)fi->SemDB(); +// if (db.PointcutInfo (fi)) +// return 0; + + return fi; +} + +void PumaTrackerDog::pre_visit (CTree *node) { + const char *id = node->NodeName (); + + if (id == CT_Token::NodeId ()) + return; + + if (id == CT_FctDef::NodeId ()) + pre_FctDef ((CT_FctDef *)node); + else if (id == CT_InitDeclarator::NodeId ()) + pre_InitDeclarator ((CT_InitDeclarator*)node); + else if (id == CT_MembInitList::NodeId ()) + in_memb_init = true; + else if (id == CT_MembPtrExpr::NodeId () || + id == CT_MembRefExpr::NodeId ()) + pre_MembPtrExpr ((CT_MembPtrExpr*)node); + else if (node->IsSimpleName ()) + pre_SimpleName (node->IsSimpleName ()); + else if (id == CT_NamespaceDef::NodeId ()) + pre_NamespaceDef ((CT_NamespaceDef*)node); + else if (id == CT_ClassDef::NodeId ()) + pre_ClassDef ((CT_ClassDef*)node); +} + +void PumaTrackerDog::post_visit (CTree *node) { + const char *id = node->NodeName (); + CT_Call *call; + if ((call = node->IsCall ()) != 0) + pre_Call (call); + else if (id == CT_FctDef::NodeId ()) + post_FctDef ((CT_FctDef *)node); + else if (id == CT_InitDeclarator::NodeId ()) + post_InitDeclarator ((CT_InitDeclarator *)node); + else if (id == CT_MembInitList::NodeId ()) + in_memb_init = false; + else if (id == CT_ClassDef::NodeId ()) + post_ClassDef ((CT_ClassDef*)node); +} + +void PumaTrackerDog::pre_ClassDef (CT_ClassDef *node) { + if (node->Object () && + strcmp (node->Object ()->QualName (), "JoinPoint") == 0) + prune (); + + if (node->BaseIntros ()) + visit (node->BaseIntros ()); +} + +void PumaTrackerDog::post_ClassDef (CT_ClassDef *node) { + if (node->IntroMembers ()) + visit (node->IntroMembers ()); +} + +void PumaTrackerDog::pre_Call (CT_Call *node) { + // ignore calls via function pointer, which cannot be resolved + if (!node->Object ()) + return; + + CFunctionInfo *called = node->Object ()->FunctionInfo (); + called = (CFunctionInfo*)unique_object (called); + + // conditions to ignore this call (join point): + // - constructor/destructor calls (not yet implemented) + // - calls to generated or special ac++ code + if (called->isConstructor () || called->isDestructor () || + !filter_func (called)) + return; + + // for introduced code check the target file + Unit *unit = (Unit*)node->token ()->belonging_to (); + IntroductionUnit *intro_unit = IntroductionUnit::cast (unit); + if (intro_unit) unit = intro_unit->final_target_unit (); + + // conditions to ignore this call (join point) ... continued: + // - the calling code is not part of the project + if (!db ().Project ()->isBelow (unit)) + return; + + CObjectInfo *caller = func_stack.top (); + if (caller) { + // call inside a function + // TODO: in_member_init no longer used here. Was is really useless? + _jpm.register_call (called, node, caller->DefObject (), local_id); + local_id++; + } + else if (last_init_declarator) { + // call outside a function: this must be a declaration in global scope with initializer + caller = last_init_declarator->Object (); + _jpm.register_call (called, node, caller->DefObject (), -1); + } + else { + // here we must have a caller, otherwise there is a strange kind of call + assert(false); + } +} + +void PumaTrackerDog::pre_FctDef (CT_FctDef *node) { + CObjectInfo *func = node->Object (); + + if (func && func->FunctionInfo ()) { + func_stack.push (func->FunctionInfo ()); + local_id = 0; + } + else + prune (); +} + +void PumaTrackerDog::post_FctDef (CT_FctDef *node) { + func_stack.pop (); +} + +void PumaTrackerDog::pre_InitDeclarator (CT_InitDeclarator *node) { + last_init_declarator = node; +} + +void PumaTrackerDog::post_InitDeclarator (CT_InitDeclarator *node) { + last_init_declarator = 0; +} + +bool PumaTrackerDog::register_access (CObjectInfo *obj, CTree *node) { + // only track attributes if the tracker dog is configured to do it. + if (!_track_attrs) + return false; + + // is a relevent attribute accessed? + if (!obj || !obj->AttributeInfo () || !obj->Scope () || + obj->Scope ()->isLocalScope () || obj->isAnonymous () || + (strncmp (obj->QualName (), "JoinPoint::", 11) == 0 || + strcmp (obj->Name (), "this") == 0) || + strcmp (obj->QualName (), "tjp") == 0) + return false; + + if (last_init_declarator && last_init_declarator->Object () == obj) + return false; + + Unit *unit = (Unit*)node->token ()->belonging_to (); + while (unit->isMacroExp ()) + unit = ((MacroUnit*)unit)->CallingUnit (); + + if (!(IntroductionUnit::cast (unit) || + db ().Project ()->isBelow (unit))) + return false; + + // register the accessing syntax tree +//#ifndef ACMODEL +// // TODO: has to be implemented +// _jpm.register_attr_access (obj->AttributeInfo (), node); +//#endif + + return true; +} + +void PumaTrackerDog::pre_MembPtrExpr (CT_MembPtrExpr *node) { + CObjectInfo *obj = node->Object (); + + // register the object if it is relevant + if (!register_access (obj, node)) + return; + + // foo.x -> visit foo here + visit (node->Son (0)); + + CTree *name = node->Son (2); + const char *id = name->NodeName (); + if (id == CT_QualName::NodeId () || + id == CT_RootQualName::NodeId ()) { + CT_QualName *qual_name = (CT_QualName*)name; + for (int i = 0; i < qual_name->Entries () - 1; i++) + visit (qual_name->Entry (i)); + } + + // don't visit all the children again + prune (); +} + +void PumaTrackerDog::pre_SimpleName (CT_SimpleName *node) { + + // register this access if it is relevant + if (!register_access (node->Object (), node)) + return; + + const char *id = node->NodeName (); + if (id == CT_QualName::NodeId () || + id == CT_RootQualName::NodeId ()) { + CT_QualName *qual_name = (CT_QualName*)node; + for (int i = 0; i < qual_name->Entries () - 1; i++) + visit (qual_name->Entry (i)); + prune (); + } +} + +void PumaTrackerDog::pre_NamespaceDef (CT_NamespaceDef *node) { + CObjectInfo *obj = node->Object (); + if (obj && strcmp (obj->QualName (), "AC") == 0) + prune (); +} diff --git a/AspectC++/PumaTrackerDog.h b/AspectC++/PumaTrackerDog.h new file mode 100644 index 0000000..fa8da51 --- /dev/null +++ b/AspectC++/PumaTrackerDog.h @@ -0,0 +1,78 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __PumaTrackerDog_h__ +#define __PumaTrackerDog_h__ + +#include "Puma/CVisitor.h" +#include "Puma/CTranslationUnit.h" +#include "Puma/Stack.h" + +namespace Puma { + class CAttributeInfo; + class CFunctionInfo; +} // namespace Puma + +class PumaModelBuilder; + +class PumaTrackerDog : public Puma::CVisitor { + Puma::CTranslationUnit &_tunit; + PumaModelBuilder &_jpm; + Puma::CT_BinaryExpr *assignment; + Puma::CT_InitDeclarator *last_init_declarator; + Puma::Stack func_stack; + bool in_memb_init; + int local_id; + bool _track_attrs; + + Puma::CSemDatabase &db () { return _tunit.db (); } + + virtual void pre_visit (Puma::CTree *node); + virtual void post_visit (Puma::CTree *node); + + void pre_Call (Puma::CT_Call *node); + void pre_FctDef (Puma::CT_FctDef *node); + void post_FctDef (Puma::CT_FctDef *node); + void pre_InitDeclarator (Puma::CT_InitDeclarator *node); + void post_InitDeclarator (Puma::CT_InitDeclarator *node); + void pre_MembPtrExpr (Puma::CT_MembPtrExpr *node); + void pre_SimpleName (Puma::CT_SimpleName *node); + void pre_NamespaceDef (Puma::CT_NamespaceDef *node); + void pre_ClassDef (Puma::CT_ClassDef *node); + void post_ClassDef (Puma::CT_ClassDef *node); + bool register_access (Puma::CObjectInfo *obj, Puma::CTree *node); + +public: + + PumaTrackerDog (Puma::CTranslationUnit &tunit, PumaModelBuilder &jpm, bool track_attrs = false): + _tunit (tunit), _jpm (jpm), assignment (0), last_init_declarator (0), + in_memb_init (false), _track_attrs (track_attrs) { + func_stack.push ((Puma::CFunctionInfo*)0); + } + virtual ~PumaTrackerDog() {} + + // search all code join points + void run () { visit (_tunit.tree ()); } + void run (Puma::CTree *tree) { visit (tree); } + + // check if a function should be considered by ac++ + static Puma::CFunctionInfo *filter_func (Puma::CFunctionInfo* fi); + static Puma::CObjectInfo *unique_object (Puma::CObjectInfo *obj); +}; + +#endif // __PumaTrackerDog_h__ diff --git a/AspectC++/PumaTransformInfo.h b/AspectC++/PumaTransformInfo.h new file mode 100644 index 0000000..29b809b --- /dev/null +++ b/AspectC++/PumaTransformInfo.h @@ -0,0 +1,990 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __PumaTransformInfo_h__ +#define __PumaTransformInfo__ + +#include "ACModel/Elements.h" +#include "ThisJoinPoint.h" +#include "PointCutExpr.h" +#include "SyntacticContext.h" +#include "CFlow.h" +#include "WeaverBase.h" + + +#include "Puma/CSemDatabase.h" +#include "Puma/CNamespaceInfo.h" +#include "Puma/DeducedArgument.h" +#include "Puma/CTemplateInstance.h" +#include "Puma/CFctInstance.h" +#include "Puma/MacroUnit.h" +#include "Puma/FileUnit.h" + +class TI_CodeAdvice : public ModelTransformInfo { + const Condition *_condition; + AdviceInfo *_advice_info; +public: + void set_condition (const Condition *c) { _condition = c; } + const Condition *get_condition () const { return _condition; } + void set_advice_info (AdviceInfo *ai) { _advice_info = ai; } + AdviceInfo *get_advice_info () const { return _advice_info; } + + static TI_CodeAdvice *of (const ACM_CodeAdvice &loc) { + return (TI_CodeAdvice*)loc.transform_info (); + } +}; + +class TransformInfo : public ModelTransformInfo { +public: + virtual ModelNode &jpl () = 0; + virtual Puma::CTree *tree () const = 0; + virtual Puma::CObjectInfo *obj_info () const = 0; + // associated unique parser object (e.g. for name mangling) + virtual Puma::CObjectInfo *assoc_obj () const = 0; + // find the unit (non-macro) in which a join point is located + Puma::Unit *unit () const { + Puma::CTree *node = tree (); + if (!node) + return 0; + Puma::Token *token = node->token (); + Puma::Unit *unit = (Puma::Unit*)token->belonging_to (); + while (unit && unit->isMacroExp ()) { + unit = ((Puma::MacroUnit*)unit)->CallingUnit (); + } + return unit; + } + + static inline const TransformInfo *of (const ModelNode &loc); + static inline Puma::CTree *tree (const ModelNode &loc); + static inline Puma::Unit *unit (const ModelNode &loc); + static inline Puma::Location location (const ModelNode &loc); + + // helper function: check if a function is a method (needs a 'this' pointer) + static bool needs_this (Puma::CFunctionInfo *func) { + if (func->isMethod () && !func->isStaticMethod ()) { + return !(func->isOperator () && + (strcmp (func->Name (), "operator new") == 0 || + strcmp (func->Name (), "operator new[]") == 0 || + strcmp (func->Name (), "operator delete") == 0 || + strcmp (func->Name (), "operator delete[]") == 0)); + } + return false; + } +}; + +inline const TransformInfo *TransformInfo::of (const ModelNode &loc) { + return loc.transform_info () ? (TransformInfo*)loc.transform_info () : 0; +} +inline Puma::CTree *TransformInfo::tree (const ModelNode &loc) { + return loc.transform_info () ? + ((TransformInfo*)loc.transform_info ())->tree () : 0; +} +inline Puma::Unit *TransformInfo::unit (const ModelNode &loc) { + return loc.transform_info () ? + ((TransformInfo*)loc.transform_info ())->unit () : 0; +} +inline Puma::Location TransformInfo::location (const ModelNode &loc) { + return loc.transform_info () ? + tree (loc)->token ()->location () : Puma::Location (); +} + +class TI_Namespace : public TransformInfo { + // pointer to the Puma namespace object (for transformation) + Puma::CNamespaceInfo *_namespace_obj; +public: + TI_Namespace () : _namespace_obj (0) {} + + void namespace_info (Puma::CNamespaceInfo *n) { _namespace_obj = n; } + Puma::CNamespaceInfo *namespace_info () const { return _namespace_obj; } + virtual Puma::CObjectInfo *obj_info () const { return _namespace_obj; } + virtual Puma::CObjectInfo *assoc_obj () const { return _namespace_obj; } + virtual Puma::CTree *tree () const { return _namespace_obj->Tree (); } + + static string name (Puma::CNamespaceInfo *n) { + if (n->GlobalScope ()) + return "::"; + else + return n->QualName (false, false, true); // the last 'true' means: + // we want to see ' + } +}; + +class TI_Class : public TransformInfo { + Puma::CClassInfo *_class_obj; + + // internal function that checks whether a given scope is located within + // a template instance. + // TODO: this is a duplicate of a ModelBuilder function! + static bool is_in_template_instance (Puma::CScopeInfo *scope) { + if (scope->isTemplateInstance ()) + return true; + if (scope->QualifiedScope ()) + return is_in_template_instance (scope->QualifiedScope ()); + if (scope->Parent () != scope) + return is_in_template_instance (scope->Parent ()); + return false; + } + +public: + TI_Class () : _class_obj (0) {} + + bool valid () const { return _class_obj != 0; } // probably the *definition* is external; only phase 1 found a declaration + + void class_info (Puma::CClassInfo *c) { + _class_obj = c->DefObject (); + } + Puma::CClassInfo *class_info () const { return _class_obj; } + + SyntacticContext get_def_context () const { return SyntacticContext (_class_obj); } + + void get_member_contexts (list &member_contexts) const { + + for (unsigned a = 0; a < _class_obj->Attributes (); a++) { + Puma::CAttributeInfo *attr = _class_obj->Attribute (a); + + // Only certain members are delivered. + // If this is not the right choice for all use case, add filter flags to + // the argument list of this function + if (attr->isStatic () || attr->isAnonymous () || attr->EnumeratorInfo ()) + continue; + + member_contexts.push_back (PumaSyntacticContext (attr)); + } + } + + enum SMKind { CONSTRUCTOR, COPY_CONSTRUCTOR, DESTRUCTOR }; + bool may_have_implicit (SMKind kind) { + return may_have_implicit (kind, _class_obj); + } + + bool may_have_implicit (SMKind kind, Puma::CClassInfo *cls) { + + for (unsigned f = 0; f < cls->Functions (); f++) { + Puma::CFunctionInfo *curr = cls->Function (f); + // TODO: checking for one argument is not sufficient to detect a copy constructor! + if ((curr->isConstructor () && curr->Arguments () == 0 && kind == CONSTRUCTOR) || + (curr->isConstructor () && curr->Arguments () == 1 && kind == COPY_CONSTRUCTOR) || + (curr->isDestructor () && kind == DESTRUCTOR)) { + if (curr->Protection () == Puma::CProtection::PROT_PRIVATE) + return false; // function is private -> problem! + } + } + + // check if any base class has a private constructor/copy constructor/destr. + for (unsigned b = 0; b < cls->BaseClasses (); b++) { + Puma::CClassInfo *base = cls->BaseClass (b)->Class (); + if (!may_have_implicit(kind, base)) + return false; + } + + // check the types of non-static attributes (or array thereof) for private constructor/copy constructor/destr. + for (unsigned a = 0; a < cls->Attributes (); a++) { + Puma::CObjectInfo *attr = cls->Attribute(a); + if (attr->isStatic() || attr->isAnonymous()) + continue; + Puma::CTypeInfo *type = attr->TypeInfo(); + while (type->isArray()) + type = type->BaseType(); + Puma::CRecord *base = type->Record(); + if (!base || // no problem if the attribute is no class/struct/union instance + base->isAnonymous()) // anonymous structs/classes/unions cannot have a private constrcutor/destructor + continue; + if (!base->ClassInfo ()) + continue; + if (!may_have_implicit(kind, base->ClassInfo ())) + return false; + } + + return true; // seems that there is no problem + } + + virtual Puma::CObjectInfo *obj_info () const { return _class_obj; } + virtual Puma::CObjectInfo *assoc_obj () const { return _class_obj; } + virtual Puma::CTree *tree () const { return _class_obj->Tree (); } + + // return the position behind the opening bracket of the class body + const WeavePos &body_start_pos (WeaverBase &wb) const { + return wb.weave_pos(((Puma::CT_ClassDef*)_class_obj->Tree ())->Members ()->token (), + WeavePos::WP_AFTER); + } + + // return the position in front of the closing bracket of the class body + const WeavePos &body_end_pos (WeaverBase &wb) const { + return wb.weave_pos(((Puma::CT_ClassDef*)_class_obj->Tree ())->Members ()->end_token (), + WeavePos::WP_BEFORE); + } + + // return the position of the first token of the class definition + const WeavePos &objdecl_start_pos (WeaverBase &wb) const { + assert (valid ()); + Puma::CT_ClassDef *cd = (Puma::CT_ClassDef*)_class_obj->Tree(); + return wb.weave_pos (cd->ObjDecl ()->token (), WeavePos::WP_BEFORE); + } + + // return the position after the ";" of the class definition + const WeavePos &objdecl_end_pos (WeaverBase &wb) const { + Puma::CT_ClassDef *cd = (Puma::CT_ClassDef*)_class_obj->Tree(); + return wb.weave_pos (cd->ObjDecl ()->end_token (), WeavePos::WP_AFTER); + } + + // check whether this is a class or struct + bool is_class () const { return _class_obj->isClass(); } + + // check whether this is a struct (more restrictive than 'is_class') + bool is_struct () const { return _class_obj->isStruct(); } + + // check whether the class is defined (=has a body) and not only declared + bool is_defined () const { return _class_obj->isDefined(); } + + // checks whether this class is a template *instance* + bool is_template_instance () const { return _class_obj->isTemplateInstance(); } + + // check whether the class is defined in a extern "C" block + bool is_extern_c () const { + if (!is_defined()) + return false; + Puma::CT_ClassDef *cd = (Puma::CT_ClassDef*)_class_obj->DefObject ()->Tree (); + // TODO: ugly workaround needed to check whether a class is defined in + // an extern "C" block -> extended Puma, SemDB doesn't contain this info! + for (Puma::CTree *curr = cd; curr; curr = curr->Parent()) + if (curr->NodeName() == Puma::CT_LinkageSpec::NodeId()) + return true; + return false; + } + + // checks whther the class is defined within a template instance + bool is_in_template_instance () const { + return is_in_template_instance(_class_obj); + } + + static string name (Puma::CClassInfo *c) { + ostringstream class_name; + c->TypeInfo ()->TypeText (class_name, 0, false, false, false, true); + return class_name.str ().c_str (); + } + + static TI_Class *of (const ACM_Class &loc) { + return (TI_Class*)loc.transform_info (); + } +}; + +class TI_Aspect : public TI_Class { +public: + + Puma::CFunctionInfo *aspectof () const { + // TODO: make this better! + Puma::CFunctionInfo *aof = class_info()->Function ("aspectof"); + if (!aof) + aof = class_info()->Function ("aspectOf"); + return aof ? aof->DefObject () : (Puma::CFunctionInfo*)0; + } + + static const TI_Aspect *of (const ACM_Aspect &loc) { + return (TI_Aspect*)loc.transform_info (); + } + +}; + +class TI_Function : public TransformInfo { + Puma::CFunctionInfo *_func_obj; + mutable vector _contexts; + +public: + TI_Function () : _func_obj (0) {} + + void func_info (Puma::CFunctionInfo *fi) { _func_obj = fi->DefObject (); } + const vector &syntactic_contexts () const { + if (_contexts.size() == 0) { + // Store a pointer to each declaration and the definition (if one exists) + Puma::CFunctionInfo *curr = _func_obj; + do { + _contexts.push_back (SyntacticContext (curr)); + curr = curr->NextObject ()->FunctionInfo (); + } + while (curr != _func_obj); + } + return _contexts; + } + + Puma::CFunctionInfo *func_info () const { return _func_obj; } + virtual Puma::CObjectInfo *obj_info () const { return _func_obj; } + virtual Puma::CObjectInfo *assoc_obj () const { return _func_obj; } + virtual Puma::CTree *tree () const { return _func_obj->Tree (); } + + static string signature (Puma::CFunctionInfo *func_info) { + ostringstream name; + // the unique name in a scope start with the function name + name << func_info->Name (); + + // add the template arguments if it is a function template instance + Puma::CTemplateInstance *instance = func_info->TemplateInstance (); + if (instance) { + name << "<"; + for (unsigned a = 0; a < instance->DeducedArgs (); a++) { + if (a > 0) name << ","; + Puma::DeducedArgument *arg = instance->DeducedArg (a); + if (arg->Type ()) + name << *arg->Type (); + else if (arg->Value ()) { + if (arg->Value ()->isSigned ()) + // TODO: cast needed here as stdc++ lib can't print __int128! Problems! + name << (long long)arg->Value ()->convert_to_int (); + else if (arg->Value ()->isUnsigned ()) + name << (unsigned long long)arg->Value ()->convert_to_uint (); + else if (arg->Value ()->isFloat ()) + name << arg->Value ()->convert_to_float (); + } + else + name << "*invalid template arg*"; + } + string name_str = name.str (); + if (name_str[name_str.length () - 1] == '>') + name << " "; + name << ">"; + } + + // add the argument types + Puma::CTypeFunction *this_type = func_info->TypeInfo (); + name << "("; + Puma::CTypeList *argtypes = this_type->ArgTypes (); + for (unsigned i = 0; i < argtypes->Entries (); i++) { + if (i > 0) name << ","; + Puma::CTypeInfo *argtype = argtypes->Entry (i); + argtype->TypeText (name, "", false, false, false, true); + } + name << ")"; + + // add CV qualifiers + if (this_type->isConst ()) + name << " const"; + if (this_type->isVolatile ()) + name << " volatile"; + + return name.str (); + } + + bool is_const () const { + return _func_obj->TypeInfo()->isConst(); + } + + bool is_conversion_operator () const { + return _func_obj->isConversion(); + } + + + static const TI_Function *of (const ACM_Function &loc) { + return (TI_Function*)loc.transform_info (); + } +}; + +class TI_Variable : public TransformInfo { + Puma::CObjectInfo *_obj; +public: + TI_Variable () : _obj (0) {} + + void obj_info (Puma::CObjectInfo *oi) { _obj = oi->DefObject (); } + virtual Puma::CObjectInfo *obj_info () const { return _obj; } + virtual Puma::CObjectInfo *assoc_obj () const { return _obj; } + virtual Puma::CTree *tree () const { return _obj->Tree (); } +public: + static string name (Puma::CObjectInfo *obj_info) { + return obj_info->Name ().c_str (); + } + static const TI_Variable *of (const ACM_Variable &loc) { + return (TI_Variable*)loc.transform_info (); + } +}; + +class TI_Type : public TransformInfo { + Puma::CTypeInfo *_type_info; +public: + TI_Type () : _type_info (0) {} + + void type_info (Puma::CTypeInfo *ti) { _type_info = ti; } + Puma::CTypeInfo *type_info () const { return _type_info; } + + virtual Puma::CObjectInfo *obj_info () const { return 0; } + virtual Puma::CObjectInfo *assoc_obj () const { return 0; } + virtual Puma::CTree *tree () const { return 0; } + + static string name (Puma::CTypeInfo *type_info) { + ostringstream out; + type_info->TypeText(out,"?", false, false, false, true); + string result = out.str(); + int last = result.length() - 1; + if (result[last] == '?') last--; + while(result[last] == ' ') last--; + return result.substr(0, last + 1); + } + + static const TI_Type *of (const ACM_Type &loc) { + return (TI_Type*)loc.transform_info (); + } +}; + +class TI_Arg : public TransformInfo { + Puma::CTypeInfo *_type_info; +public: + TI_Arg () : _type_info (0) {} + + void type_info (Puma::CTypeInfo *ti) { _type_info = ti; } + Puma::CTypeInfo *type_info () const { return _type_info; } + + virtual Puma::CObjectInfo *obj_info () const { return 0; } + virtual Puma::CObjectInfo *assoc_obj () const { return 0; } + virtual Puma::CTree *tree () const { return 0; } + + static string signature (Puma::CTypeInfo *type_info, const string &name) { + ostringstream out; + type_info->TypeText(out, name.c_str(), false, false, false, true); + return out.str(); + } + + static const TI_Arg *of (const ACM_Arg &loc) { + return (TI_Arg*)loc.transform_info (); + } +}; + +class TI_Code : public TransformInfo { + + CFlowList _triggers; + +public: + + // consider a necessary cflow trigger at this join point + bool consider (const CFlow &cflow) { + _triggers.push_back (cflow); + return true; + } + + // return the list of cflows that must be entered/left here + const CFlowList &cflows () const { return _triggers; } + + // that types (for the JoinPoint-API) + virtual Puma::CTypeInfo *that_type () const = 0; + virtual std::string that_type_string () const { return "void"; } + + // target type (for the JoinPoint-API) + virtual Puma::CTypeInfo *target_type () const = 0; + virtual std::string target_type_string () const { return "void"; } + + // helper functions for derived classes + static Puma::CTypeInfo *get_that_type (Puma::CObjectInfo *obj) { + Puma::CFunctionInfo *func = obj->FunctionInfo (); + if (func) { + Puma::CObjectInfo *this_obj = func->Attribute ("this"); + if (this_obj) { + Puma::CTypeInfo *type = this_obj->TypeInfo (); + // find the type which is referenced by 'this' + while (type && !type->isRecord ()) + type = type->BaseType (); + assert (type); + return type; + } + } + if (obj->ClassScope ()) + return obj->ClassScope ()->TypeInfo (); + return &Puma::CTYPE_VOID; + } + + static TI_Code *of (const ACM_Code &loc) { + return (TI_Code*)loc.transform_info (); + } + +}; + +class TI_Method : public TI_Code { + Puma::CFunctionInfo *_func_info; +public: + TI_Method () : _func_info (0) {} + + void func_info (Puma::CFunctionInfo *f) { _func_info = f; } + virtual Puma::CObjectInfo *obj_info () const { return _func_info; } + virtual Puma::CObjectInfo *assoc_obj () const { return _func_info; } + virtual Puma::CTree *tree () const { return _func_info->Tree (); } + + // that type (for the JoinPoint-API) + virtual Puma::CTypeInfo *that_type () const { return get_that_type (_func_info); } + + // target type (for the JoinPoint-API) + virtual Puma::CTypeInfo *target_type () const { + Puma::CRecord *scope = _func_info->ClassScope (); + return scope ? scope->TypeInfo () : &Puma::CTYPE_VOID; + } +}; + +class TI_MethodCall : public TI_Code { + Puma::CFunctionInfo *called_func; + Puma::CObjectInfo *caller_obj; + Puma::CT_Call *node; + SyntacticContext _call_context; + SyntacticContext _dest_func_context; + Puma::CT_Expression *_target_expr; + bool _target_is_ptr; +public: + TI_MethodCall () : called_func (0), caller_obj (0), node (0), + _target_expr (0), _target_is_ptr (false) {} + + void called (Puma::CFunctionInfo *c) { called_func = c; _dest_func_context.set_object(c); } +// CFunctionInfo *called () const { return called_func; } + void caller (Puma::CObjectInfo *c) { caller_obj = c; _call_context.set_object(c); } + Puma::CFunctionInfo *caller () { + return caller_obj ? caller_obj->FunctionInfo () : 0; + } + void tree (Puma::CT_Call *n) { node = n; if (n) _target_expr = target_expr (_target_is_ptr); } + bool has_target_expr () const { return _target_expr; } + bool target_is_ptr () const { return _target_is_ptr; } + virtual Puma::CTree *tree () const { return node; } + virtual Puma::CObjectInfo *obj_info () const { return called_func; } + virtual Puma::CObjectInfo *assoc_obj () const { return caller_obj; } + + static TI_MethodCall *of( const ACM_Call &loc ) { + return (TI_MethodCall*)loc.transform_info (); + } + + const SyntacticContext &call_context () const { return _call_context; } + const SyntacticContext &dest_func_context () const { return _dest_func_context; } + + const WeavePos &before_pos (WeaverBase &wb) { + return wb.weave_pos(CallNode()->token(), WeavePos::WP_BEFORE); + } + const WeavePos &after_pos (WeaverBase &wb) { + return wb.weave_pos(CallNode()->end_token(), WeavePos::WP_AFTER); + } + + // the result type + Puma::CTypeInfo *result_type_info () const { + return called_func->isConversion () ? + called_func->ConversionType () : + called_func->TypeInfo()->TypeFunction()->BaseType (); + } + + bool has_result () const { + return !result_type_info ()->isVoid (); + } + + // that type (for the JoinPoint-API) + virtual Puma::CTypeInfo *that_type () const { return get_that_type (caller_obj); } + + Puma::CClassInfo *target_class () const { + Puma::CTypeInfo *type = target_type (); + if (type) { + type = type->UnqualType (); + if (type->TypePointer ()) + type = type->BaseType (); + if (type != &Puma::CTYPE_VOID && type->Record () && + type->Record ()->ClassInfo()) { + Puma::CClassInfo *ci = type->Record()->ClassInfo ()->DefObject (); + return ci; + } + } + return 0; + } + + bool target_is_const() const { + return target_type ()->isConst (); + } + + // target type (for the JoinPoint-API) + virtual Puma::CTypeInfo *target_type () const { + bool is_ptr; + Puma::CTree *expr = target_expr (is_ptr); + if (expr) { + Puma::CTypeInfo *type = expr->Type (); + // if this is a pointer or reference, take the base type + while (type && (type->TypeAddress () || !type->isRecord ())) + type = type->BaseType (); + assert (type); + return type; + } + else if (called_func->isMethod ()) { + if (called_func->isStaticMethod ()) { + return called_func->ClassScope ()->TypeInfo (); + } + else { + if (caller_obj->FunctionInfo ()) { + assert (caller_obj->ClassScope ()); + return caller_obj->ClassScope ()->TypeInfo (); + } + else + return &Puma::CTYPE_VOID; + } + } + else + return &Puma::CTYPE_VOID; + } + + bool is_call_op () const { + return strcmp (called_func->Name().c_str (), "operator ()") == 0; + } + + // the target object of the call or NULL + Puma::CT_Expression *target_expr (bool &is_ptr) const { + + // check if this call has a target object + if (!called_func->isMethod ()) + return 0; + + Puma::CTree *result = 0; + + // what kind of node was used for the call? + const char *calltype = node->NodeName (); + + // in most case we have no pointer + is_ptr = false; + + if (calltype == Puma::CT_CallExpr::NodeId ()) { + Puma::CTree *expr = ((Puma::CT_CallExpr*)node)->Expr (); + // if the target function is given in parenthesis, skip it: + // e.g. (foo->bar)(42); + while (expr->NodeName () == Puma::CT_BracedExpr::NodeId ()) + expr = ((Puma::CT_BracedExpr*)expr)->Expr (); + // find the target object if there is any + const char *fctcalltype = expr->NodeName (); + if (fctcalltype == Puma::CT_MembRefExpr::NodeId ()) { + // .method() + result = expr->Son (0); + } else if (fctcalltype == Puma::CT_MembPtrExpr::NodeId ()) { + // ->method() + is_ptr = true; + result = expr->Son (0); + } else { + if (is_call_op ()) { + // () + result = expr; + } + else { + // method() + is_ptr = true; // here 'this' is passed implicitly + } + } + } + else if (calltype == Puma::CT_BinaryExpr::NodeId ()) { + // + result = node->Son (0); + } + else if (calltype == Puma::CT_UnaryExpr::NodeId () || + calltype == Puma::CT_DerefExpr::NodeId ()) { + // + result = node->Son (1); + } + else if (calltype == Puma::CT_PostfixExpr::NodeId ()) { + // + result = node->Son (0); + } + else if (calltype == Puma::CT_IndexExpr::NodeId ()) { + // [ ] + result = node->Son (0); + } + else if (calltype == Puma::CT_ImplicitCall::NodeId ()) { + // + result = node->Son (0); + } + else { + cout << "unexpected node type " << node->NodeName () << " in " + << "JPL_MethodCall::target_expr()" << endl; + } + return (Puma::CT_Expression*)result; + } + + // the call expression node in the syntax tree + Puma::CT_Call *CallNode() const { return node;} + + // checks if the original call uses a qualified target function name + bool is_qualified () const { + if (node->NodeName () != Puma::CT_CallExpr::NodeId ()) + return false; + Puma::CTree *expr = ((Puma::CT_CallExpr*)node)->Expr (); + const char *nodename = expr->NodeName (); + if (nodename == Puma::CT_MembPtrExpr::NodeId () || + nodename == Puma::CT_MembRefExpr::NodeId ()) { + expr = expr->Son (2); // some access function in PUMA missing! + nodename = expr->NodeName (); + } + return nodename == Puma::CT_QualName::NodeId () || + nodename == Puma::CT_RootQualName::NodeId (); + } + + // checks whether the call uses explicit template parameters + bool has_explicit_template_params () const { + if (node->NodeName () != Puma::CT_CallExpr::NodeId ()) + return false; + Puma::CTree *expr = ((Puma::CT_CallExpr*)node)->Expr (); + const char *nodename = expr->NodeName (); + if (nodename == Puma::CT_MembPtrExpr::NodeId () || + nodename == Puma::CT_MembRefExpr::NodeId ()) { + expr = expr->Son (2); // some access function in PUMA missing! + nodename = expr->NodeName (); + } + return expr->IsSimpleName() && + expr->IsSimpleName()->Name()->NodeName() == Puma::CT_TemplateName::NodeId(); + } + + // returns true if the call needs special access rights + bool needs_rights () const { + // get the target object type + Puma::CTypeInfo *type = target_type ()->UnqualType (); + + // no member function => no accessibility problem + if (type->isVoid ()) + return false; + + // static member => no problem only if public + if (called_func->isStaticMethod ()) + return (called_func->Protection () != Puma::CProtection::PROT_PUBLIC); + + // normal member function => look up the accessibility + if (type->ClassInfo () && + type->ClassInfo ()->Accessibility (called_func) == Puma::CProtection::PROT_PUBLIC) + return false; + + return true; + } +}; + +class TI_Construction : public TI_Code { + Puma::CFunctionInfo *_func_info; +public: + TI_Construction () : _func_info (0) {} + + void func_info (Puma::CFunctionInfo *f) { _func_info = f; } + virtual Puma::CObjectInfo *obj_info () const { return _func_info; } + virtual Puma::CObjectInfo *assoc_obj () const { return _func_info; } + virtual Puma::CTree *tree () const { return _func_info->ClassScope ()->Tree (); } + + // that type (for the JoinPoint-API) + virtual Puma::CTypeInfo *that_type () const { return get_that_type (_func_info); } + + // target type (for the JoinPoint-API) + virtual Puma::CTypeInfo *target_type () const { + Puma::CRecord *scope = _func_info->ClassScope (); + return scope ? scope->TypeInfo () : &Puma::CTYPE_VOID; + } +}; + +class TI_Destruction : public TI_Code { + Puma::CFunctionInfo *_func_info; +public: + TI_Destruction () : _func_info (0) {} + + void func_info (Puma::CFunctionInfo *f) { _func_info = f; } + virtual Puma::CObjectInfo *obj_info () const { return _func_info; } + virtual Puma::CObjectInfo *assoc_obj () const { return _func_info; } + virtual Puma::CTree *tree () const { return _func_info->ClassScope ()->Tree (); } + + // that type (for the JoinPoint-API) + virtual Puma::CTypeInfo *that_type () const { return get_that_type (_func_info); } + + // target type (for the JoinPoint-API) + virtual Puma::CTypeInfo *target_type () const { + Puma::CRecord *scope = _func_info->ClassScope (); + return scope ? scope->TypeInfo () : &Puma::CTYPE_VOID; + } +}; + +class TI_AdviceCode : public TransformInfo { + // CT_AdviceDecl *_tree; + Puma::CFunctionInfo *_func; + ThisJoinPoint _this_join_point; + +public: + TI_AdviceCode () : _func (0) {} + + void function(Puma::CFunctionInfo *f) { _func = f; } + virtual Puma::CTree *tree () const { return _func ? _func->Tree() : 0; } + + virtual Puma::CObjectInfo *obj_info () const { + return _func; + } + virtual Puma::CObjectInfo *assoc_obj () const { return obj_info (); } + + Puma::CScopeInfo *Scope () const { + return _func ? _func->Puma::CObjectInfo::QualifiedScope () : 0; + } + const char *name () const { + return _func ? _func->Name () : 0; + } + string qual_name () { + return _func ? _func->QualName () : ""; + } + + Puma::CFunctionInfo *function() const { + return _func; + } + + ThisJoinPoint &this_join_point () { return _this_join_point; } + const ThisJoinPoint &this_join_point () const { return _this_join_point; } + + static TI_AdviceCode *of (const ACM_AdviceCode &loc) { + return (TI_AdviceCode*)loc.transform_info (); + } +}; + +class TI_Introduction : public TransformInfo { +public: + virtual Puma::CObjectInfo *obj_info () const { return 0; } + virtual Puma::CObjectInfo *assoc_obj () const { return 0; } + // virtual Puma::CT_AdviceDecl *tree () const { return 0; } + virtual Puma::CTree *tree () const { return 0; } + + static TI_Introduction *of (const ACM_Introduction &loc) { + return (TI_Introduction*)loc.transform_info (); + } +}; + +class TI_Order : public TransformInfo { +// Puma::CT_AdviceDecl *_tree; +public: +// TI_Order () : _tree (0) {} +// void tree (Puma::CT_AdviceDecl *ad) { _tree = ad; } +// virtual Puma::CObjectInfo *obj_info () const { +// return ((Puma::CT_FctDef*)_tree->Decl ())->Object (); +// } + virtual Puma::CObjectInfo *obj_info () const { return 0; } +// virtual Puma::CObjectInfo *assoc_obj () const { return obj_info (); } + virtual Puma::CObjectInfo *assoc_obj () const { return 0; } +// virtual Puma::CTree *tree () const { return _tree; } + virtual Puma::CTree *tree () const { return 0; } + + static TI_Order *of (const ACM_Order &loc) { + return (TI_Order*)loc.transform_info (); + } +}; + +class TI_Pointcut : public TransformInfo { + Puma::CFunctionInfo *_func_obj; + Puma::Location _loc; +public: + TI_Pointcut () : _func_obj(0) {} + + void func_info (Puma::CFunctionInfo *fi) { _func_obj = fi->DefObject (); } + Puma::CFunctionInfo *func_info () const { return _func_obj; } + virtual Puma::CObjectInfo *obj_info () const { return _func_obj; } + virtual Puma::CObjectInfo *assoc_obj () const { return _func_obj; } + virtual Puma::CTree *tree () const { return _func_obj->Tree (); } + + void set_location (const Puma::Location &loc) { _loc = loc; } + const Puma::Location &get_location () const { return _loc; } + + static TI_Pointcut *of (const ACM_Pointcut &loc) { + return (TI_Pointcut*)loc.transform_info (); + } +}; + +class TI_Attribute : public TransformInfo { + Puma::CObjectInfo *_obj; + int _phase; + Puma::Location _loc; + string _params; +public: + TI_Attribute () : _obj(0), _phase (0)/*, _pce (0)*/ {} + ~TI_Attribute () {} + void obj_info (Puma::CObjectInfo *fi) { _obj = fi->DefObject (); } + virtual Puma::CObjectInfo *obj_info () const { return _obj; } + virtual Puma::CObjectInfo *assoc_obj () const { return _obj; } + +// void setParamStr(string params) {_params = params;} +// const string& getParamStr() {return _params;} +// void set_attr (ACM_Attribute *attr) { _attr = attr; } +// ACM_Attribute *get_attr () const { return _attr; } + void set_location (const Puma::Location &loc) { _loc = loc; } + const Puma::Location &get_location () const { return _loc; } + + static TI_Attribute *of (const ACM_Attribute &loc) { + return static_cast(loc.transform_info ()); + } +}; + + +class TI_ClassSlice : public TransformInfo { + Puma::CObjectInfo *_obj; + const Puma::Unit *_slice_unit; + Puma::Unit _pattern; + + // new phase 1 implementation: + Puma::Unit *_tokens; // class slice body + std::list _non_inline_members; // members defined outside of body + std::list _non_inline_member_units; // corresponding source units + +public: + TI_ClassSlice () : _obj (0), _slice_unit (0), _tokens (0) {} + + // new phase 1 implementation: + ~TI_ClassSlice () { + delete _tokens; + for (std::list::const_iterator i = _non_inline_members.begin (); + i != _non_inline_members.end (); ++i) + delete *i; + } + void set_tokens (Puma::Unit *unit) { _tokens = unit; } + Puma::Unit *get_tokens () const { return _tokens; } + std::list &non_inline_members () { return _non_inline_members; } + std::list &non_inline_member_units () { return _non_inline_member_units; } + void analyze_tokens (bool &has_base_intro, bool &has_member_intro) { + has_base_intro = false; + has_member_intro = false; + Puma::Token *token = _tokens->first(); + while (token && token->type () != Puma::TOK_SEMI_COLON) { + if (token->type () == Puma::TOK_COLON) + has_base_intro = true; + else if (token->type () == Puma::TOK_OPEN_CURLY) { + has_member_intro = true; + break; + } + token = _tokens->next(token); + } + } + std::string base_intro () const { + std::string result = ""; + Puma::Token *token = _tokens->first(); + token = _tokens->next(token); + while (token && token->type () != Puma::TOK_COLON) + token = _tokens->next(token); + token = _tokens->next(token); // skip ':' + while (token && token->type () != Puma::TOK_SEMI_COLON && + token->type () != Puma::TOK_OPEN_CURLY) { + result += " "; + result += token->text (); + token = _tokens->next(token); + } + return result; + } + // end - new phase 1 implementation + + void obj_info (Puma::CObjectInfo *obj) { _obj = obj; } + virtual Puma::CObjectInfo *obj_info () const { return _obj; } + void slice_unit (const Puma::Unit *su) { _slice_unit = su; } + const Puma::Unit &slice_unit () const { return *_slice_unit; } + + virtual Puma::CObjectInfo *assoc_obj () const { return obj_info (); } +// virtual CTree *tree () const { return _acsi->def_node (); } + virtual Puma::CTree *tree () const { return _obj->Tree (); } + + + const Puma::Unit &pattern () const { return _pattern; } + Puma::Unit &pattern () { return _pattern; } + static TI_ClassSlice *of (const ACM_ClassSlice &loc) { + return (TI_ClassSlice*)loc.transform_info (); + } + +// static string name (Puma::ACSliceInfo *acsi) { +// return acsi->object ()->QualName (); +// } +}; + +#endif // __PumaTransformInfo_h__ diff --git a/AspectC++/PumaWeaverBase.cc b/AspectC++/PumaWeaverBase.cc new file mode 100644 index 0000000..8c488e1 --- /dev/null +++ b/AspectC++/PumaWeaverBase.cc @@ -0,0 +1,226 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 + +// AspectC++ includes +#include "WeaverBase.h" +#include "ACUnit.h" +#include "LineDirectiveMgr.h" + +// PUMA includes +#include "Puma/ErrorSink.h" +#include "Puma/CTree.h" +#include "Puma/MacroUnit.h" + +using namespace Puma; + +const WeavePos &WeaverBase::weave_pos (Token *t, WeavePos::Pos p) { + + // check whether the weaving position has already been created + WPSet::iterator i = _positions.find (WeavePos (t, p)); + if (i != _positions.end ()) + return *i; + + // create an insert a marker token + Token *marker_token = new Token; // just a marker token without text etc. + marker_token->location (t->location ()); + Unit *marker_unit = new Unit; + marker_unit->append (*marker_token); + _commander.addBuffer (marker_unit); + if (p == WeavePos::WP_HEADER) { + // check whether there is already a marker token in front of the first token + Token *marker_inspos = t; + WPSet::iterator i = _positions.find (WeavePos (t, WeavePos::WP_BEFORE)); + if (i != _positions.end ()) + marker_inspos = (*i)._marker; + _commander.move_before (marker_token, marker_token, marker_inspos); + } + else if (p == WeavePos::WP_BEFORE) + _commander.move_before (marker_token, marker_token, t); + else if (p == WeavePos::WP_FOOTER) { + // check whether there is already a marker token behind the last token + Token *marker_inspos = t; + WPSet::iterator i = _positions.find (WeavePos (t, WeavePos::WP_AFTER)); + if (i != _positions.end ()) + marker_inspos = (*i)._marker; + _commander.move (marker_token, marker_token, marker_inspos); + } + else + _commander.move (marker_token, marker_token, t); + + // insert the position as a new one + pair result = + _positions.insert (WeavePos (t, p, marker_token)); + + // the resulting iterator points to the new entry + return *result.first; +} + +// get the 'header' weaving position in front of a unit +const WeavePos &WeaverBase::header_pos (ACFileID fid) { + const Unit *unit = fid.file_entry (); + Token *first = (Token*)unit->first (); + if (unit == (Unit*)_primary_start->belonging_to ()) + first = _primary_start; + return weave_pos (first, WeavePos::WP_HEADER); +} + +// get the 'header' weaving position in front of the primary unit +const WeavePos &WeaverBase::header_pos () { + return weave_pos (_primary_start, WeavePos::WP_HEADER); +} + +// get the 'footer' weaving position at the end of an arbitrary unit +const WeavePos &WeaverBase::footer_pos (ACFileID fid) { + const Unit *unit = fid.file_entry (); + Token *last = (Token*)unit->last (); + if (unit == (Unit*)_primary_end->belonging_to ()) + last = _primary_end; + return weave_pos (last, WeavePos::WP_FOOTER); +} + +// get the 'footer' weaving position at the end of the primary unit +const WeavePos &WeaverBase::footer_pos () { + return weave_pos (_primary_end, WeavePos::WP_FOOTER); +} + +// insert a unit at the specified weaving position +// 'before' selects whether the new text is inserted either before (true) +// or after (false) any text that has been inserted earlier at this position. +void WeaverBase::insert (const WeavePos &pos, Unit *unit, bool before) { + // return immediately if the there is a problem with macro manipulation + if (macro_problem (pos)) + return; + + // store the unit in the right order for insertion (later when committing) + if (before) + pos._units.push_front(unit); + else + pos._units.push_back(unit); +} + +// the same as the other 'insert' method (above), but converts string to unit +void WeaverBase::insert (const WeavePos &pos, const string &str, bool before) { + // return immediately if the string to paste is empty + if (str == "") + return; + + ACUnit *unit = new ACUnit (_err); + bool has_nl = (str.find('\n') != string::npos); + if (has_nl) + _line_mgr.directive (*unit); + *unit << str.c_str (); + if (has_nl) + _line_mgr.directive (*unit, (Unit*)pos._token->belonging_to (), PumaToken(pos._token)); + *unit << endu; + insert (pos, unit, before); +} + + +// replace the text between two positions with some new text +void WeaverBase::replace (const WeavePos &from, const WeavePos &to, + const string &str) { + insert (from, str); + kill (from, to); +} + + +// check whether two tokens are on the same line of the same unit +bool same_line (Token *t1, Token *t2, bool check_end_of_t1) { + if (t1->belonging_to() != t2->belonging_to()) + return false; + int l1 = t1->location().line(); + if (check_end_of_t1) + l1 += t1->line_breaks(); + int l2 = t2->location().line(); + return (l1 == l2); +} + + +// kill the text between two positions +void WeaverBase::kill (const WeavePos &from, const WeavePos &to) { + // TODO: this should not matter, the code shoud be able to deal with it + assert (from._pos == WeavePos::WP_BEFORE); + assert (to._pos == WeavePos::WP_AFTER); + if (macro_problem (from) || macro_problem (to)) + return; + + // TODO: why is only the first token checked? + bool has_nl = (string (from._token->text ()).find('\n') != string::npos); + if ((to._token && from._token != to._token) || has_nl) + _line_mgr.insert ((Unit*)to._token->belonging_to (), PumaToken(to._token), true); + _commander.kill (from._token, to._token); +} + +// kill the text of a syntax tree +void WeaverBase::kill (CTree *node) { + const WeavePos &from = weave_pos (node->token (), WeavePos::WP_BEFORE); + const WeavePos &to = weave_pos (node->end_token (), WeavePos::WP_AFTER); + kill (from, to); +} + +bool WeaverBase::commit () { + // handle code that has to be inserted at weaving positions + for (WPSet::iterator i = _positions.begin (); i != _positions.end (); ++i) { + const WeavePos &wp = *i; + for (list::iterator ui = wp._units.begin (); ui != wp._units.end (); ++ui) { + Unit *unit = *ui; + // TODO: handle line directives here (to avoid too many of them) + _commander.addBuffer (unit); + Token *first = (Token*)unit->first (); + Token *last = (Token*)unit->last (); + // "move_before" preserves the order + _commander.move_before (first, last, wp._marker); + } + } + + ManipError terror = _commander.valid (); + if (!terror) + _commander.commit (); + else + _err << terror << endMessage; + + // clear the list of weaving positions used for this transaction + _positions.clear(); + + return (bool)terror; +} + +bool WeaverBase::macro_problem (const WeavePos &pos) { + Token *token = pos._token; + Unit *unit = (Unit*)token->belonging_to (); + assert (unit); + if (unit->isMacroExp () && + ((pos._pos == WeavePos::WP_BEFORE && + unit->isMacroExp () && !((MacroUnit*)unit)->ExpansionBegin (token)) || + (pos._pos == WeavePos::WP_AFTER && + unit->isMacroExp () && !((MacroUnit*)unit)->ExpansionEnd (token)))) { + if (_warn_macro_expansion) { + _err << sev_warning << token->location () + << "transformation within macro '" + << ((MacroUnit*)unit)->MacroBegin ()->text () << "'" << endMessage; + } +// return true; + return false; + } + return false; +} + +int WeaverBase::primary_len() const { + return _primary_end->location().line() - _primary_start->location().line() + 1; +} + diff --git a/AspectC++/PumaWeaverBase.h b/AspectC++/PumaWeaverBase.h new file mode 100644 index 0000000..c013fb3 --- /dev/null +++ b/AspectC++/PumaWeaverBase.h @@ -0,0 +1,155 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __PumaWeaverBase_h__ +#define __PumaWeaverBase_h__ + +// This class encapsulates all code manipulation or analysis functions +// that are needed by AspectC++, but which do not depend on AspectC++ +// specific classes. They can be seen as a general purpose PUMA extension. + +#include +#include +using namespace std; + +#include "Puma/ManipCommander.h" + +#include "ACToken.h" +#include "ACUnit.h" +#include "ACFileID.h" +#include "ACErrorStream.h" +#include "ACProject.h" +#include "BackEndProblems.h" + +namespace Puma { + class CTree; +} // namespace Puma + +class WeaverBase; +class LineDirectiveMgr; + +class WeavePos { +public: + enum Pos { WP_HEADER, WP_AFTER, WP_BEFORE, WP_FOOTER }; + int operator < (const WeavePos& key) const { + return _token == key._token ? + (_pos < key._pos) : (_token < key._token); + } + int operator == (const WeavePos& key) const { + return _token == key._token && _pos == key._pos; + } +private: + friend class WeaverBase; + WeavePos (Puma::Token *t, Pos p, Puma::Token *m = 0) : _token (t), _pos (p), _marker (m) {} + Puma::Token *_token; + Pos _pos; + Puma::Token *_marker; + mutable list _units; +}; + +class WeaverBase { + + // These data structures are needed to store and find weaving positions that + // were already used. + typedef set WPSet; + WPSet _positions; + + // This Puma class/object is needed to perform the actual transformations + Puma::ManipCommander _commander; + + ACProject &_project; + +protected: + ACErrorStream &_err; + LineDirectiveMgr &_line_mgr; + bool _warn_macro_expansion; + Puma::Token *_primary_start; + Puma::Token *_primary_end; + + // check if a code manipulation at the given position would lead to an + // automatic macro expansion; warn if configured to do so + bool macro_problem (const WeavePos &pos); + +public: + WeaverBase (ACProject &prj, LineDirectiveMgr &ldm) : + _project (prj), _err (prj.err ()), _line_mgr (ldm), + _warn_macro_expansion(false), _primary_start(0), _primary_end(0) { + _commander.manip_mode (Puma::MM_EXPAND_MACROS); + } + + ACProject &project () { return _project; } + + // setup first and last token of the translation unit + void init (Puma::Token *s, Puma::Token *e) { + _primary_start = s; _primary_end = e; + } + + // return the length of the primary translation unit file as defined + // by the start and end tokens passed to 'init' + int primary_len () const; + + // get the associate line directive manager + LineDirectiveMgr &line_directive_mgr () const { return _line_mgr; } + + // functions to retrieve weaving positions: + + // get a weaving position before or after a specific token + const WeavePos &weave_pos (Puma::Token *t, WeavePos::Pos p); + const WeavePos &weave_pos (PumaToken t, WeavePos::Pos p) { + return weave_pos(t.get(), p); + } + // get the 'header' weaving position in front of an arbitrary unit + const WeavePos &header_pos (ACFileID fid); + // get the 'header' weaving position in front of the primary unit + const WeavePos &header_pos (); + // get the 'footer' weaving position at the end of an arbitrary unit + const WeavePos &footer_pos (ACFileID fid); + // get the 'footer' weaving position at the end of the primary unit + const WeavePos &footer_pos (); + + // code manipulation functions: + + // check/ignore manipulations for unbalanced preprocessor directives + void ignore_unbalanced () { _commander.ignore_mask (Puma::MIM_UNBALANCED); } + void check_unbalanced () { _commander.ignore_mask (Puma::MIM_NONE); } + + // insert a unit at the specified weaving position + // 'before' decides whether the new text is inserted either before (true) + // or after (false) any text that has been inserted earlier at this position. + void insert (const WeavePos &pos, Puma::Unit *unit, bool before = false); + + // the same as the other 'insert' method (above), but converts string to unit + void insert (const WeavePos &pos, const string &str, bool before = false); + + // replace the text between two positions with some new text + void replace (const WeavePos &from, const WeavePos &to, const string &str); + +// // replace the text of a syntax tree with some new text +// void replace (CTree *node, const string &str); + + // kill the text between two positions + void kill (const WeavePos &from, const WeavePos &to); + + // kill the text of a syntax tree + void kill (Puma::CTree *node); + + // commit a transformation transaction + bool commit (); +}; + +#endif // __PumaWeaverBase_h__ diff --git a/AspectC++/README b/AspectC++/README new file mode 100644 index 0000000..c446db6 --- /dev/null +++ b/AspectC++/README @@ -0,0 +1,84 @@ +Installation on Linux +===================== + +1. Get the Clang development package, which contains Clang and LLVM header + files as well as the static LLVM and Clang libraries. There are three ways + to achieve this: + + I On Debian and Ubuntu you can use the package libclang-3.5-dev or + higher. The installation path is typically /usr/lib/llvm-3.5. + + II On other Linux systems you can download binary packages from llvm.org + (http://releases.llvm.org/download.html). The tarballs can be extracted + anywhere. + + III If there is no binary package for your system you can build Clang by + yourself: + a) Download LLVM and Clang sources from + http://releases.llvm.org/download.html + b) Follow http://clang.llvm.org/get_started.html to build LLVM and + Clang. + c) Install Clang with "make install" or by invoking the following + command inside the Clang build directory (see + http://llvm.org/docs/CMake.html for more information): + cmake -DCMAKE_INSTALL_PREFIX=~/llvm-3.5 -P cmake_install.cmake + + In all cases: Locate llvm-config which is located inside /bin + and remember its path. + +2. Please note that the Puma library is still needed for compiling + AspectC++. In the Clang configuration we no longer need the Puma C++ + parser, but some other Puma functions are still referenced. + Therefore, the "mini" configuration of the Puma library is sufficient. You + can build the "mini" configuration by invoking the following command inside + the Puma directory: + + make MINI=1 + + In this configuration Puma needs no aspect weaver for compilation. + +3. Compile AspectC++ and set the make variable LLVMCONF to the path of + llvm-config: + + make LLVMCONF= + + In most cases you also want to add SHARED=1, -j, and a TARGET. For + example: + + make LLVMCONF=~/llvm-3.5/bin/llvm-config SHARED=1 TARGET=linux-debug -j4 + +4. Verify the AspectC++ installation by running the tests. For example: + + make testall LLVMCONF=~/llvm-3.5/bin/llvm-config TARGET=linux-debug + + Note: Missing includes may cause the tests to fail. In this case, ag++ can + be used to generate it: + + ag++ --gen_config + export PUMA_CONFIG="$(pwd)/puma.config" + + ag++ can be built by invoking "make" inside the Ag++ directory or can + be downloaded from http://aspectc.org/Download.php. + + + + +Installation on Mac OS X +======================== +TODO: Still up-to-date? +Currently it is not possible to use AspectC++ with an unpatched version of clang +3.4 on OS X due to a problem parsing system headers. We provide a patch to the +source distribution of clang to work around this issue. + + - Download and unpack the clang 3.4 tarball from llvm.org + + - cd tools/clang + patch -p0 < /path/to/aspectc++/clang-3.4-disable-modules.patch + cd ../.. + ./configure --prefix=/some/path + make && make install + + - Now AspectC++ can be built as described in step #2 and linked against the + patched clang. + + make LLVMCONF=/some/path/bin/llvm-config FRONTEND=Clang TARGET=macosx-release diff --git a/AspectC++/README-Puma b/AspectC++/README-Puma new file mode 100644 index 0000000..da68f4d --- /dev/null +++ b/AspectC++/README-Puma @@ -0,0 +1,36 @@ +Preparations: +============= + +Install libxml2 sources from libxml.org. The versions we have used for ac++ +are 2.6.17, 2.7.2, and 2.9.2. Configure the sources with... + +./configure --prefix= --disable-shared --with-minimum --with-xpath --with-output --with-sax1 --with-tree + +For cross compiling a windows version on Linux you might add... + +--host=i586-mingw32msvc +(or similar) + +Then run "make" and "make install". To make sure that the AspectC++ +Makefile find the right libxml2-config command put the bin directory +from in your command search path. + +Build the Puma library with your desired TARGET, e.g. "make +TARGET=linux-release". + + +Build AspectC++: +================ + +Set the PUMA environment variable to PUMA root directory (if Puma is +not located in ../Puma). + +Execute "make" with the right TARGET setting from your Puma build, +e.g. "make TARGET=linux-release". + +To weave and compile, use "make". + +To run the test programs, use "make testclean testall". +You need to set the environment variable PUMA_CONFIG to your local puma.cfg, eg. ../Puma/gen-release/puma.cfg + +The examples can be tested with "make exampleclean examplerun". diff --git a/AspectC++/RepoIdMgr.h b/AspectC++/RepoIdMgr.h new file mode 100644 index 0000000..b8db672 --- /dev/null +++ b/AspectC++/RepoIdMgr.h @@ -0,0 +1,53 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __RepoIdMgr_h__ +#define __RepoIdMgr_h__ + +#include +#include + +class RepoIdMgr { + int _last; + char _idstr[11]; + +public: + RepoIdMgr () { reset_id (); } + int new_id () { return _last++; } + void reset_id () { _last = 0; } + void update (int id ) { + if (id >= _last) + _last = id + 1; + } + const char *idstr (int id) { + sprintf (_idstr, "%d", id); + return _idstr; + } + static void get_id_set (const string &id_list_string, set &ids) { + std::stringstream ss(id_list_string); + int i; + + while (ss >> i) { + ids.insert (i); + if (ss.peek() == ',') + ss.ignore(); + } + } +}; + +#endif // __RepoIdMgr_h__ diff --git a/AspectC++/RepoNameKey.h b/AspectC++/RepoNameKey.h new file mode 100644 index 0000000..2bd8c87 --- /dev/null +++ b/AspectC++/RepoNameKey.h @@ -0,0 +1,42 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __RepoNameKey_h__ +#define __RepoNameKey_h__ + +#include +using namespace std; + +#include +#include "RepoXMLNode.h" + +class RepoNameKey { + string _name; +public: + RepoNameKey (const string &name) : _name (name) {} + RepoNameKey (RepoXMLNode node) { get_xml (node); } + int operator < (const RepoNameKey& key) const { return _name < key._name; } + void get_xml (RepoXMLNode node) { + _name = node.get_str_prop ("name"); + } + void make_xml (RepoXMLNode node) const { + node.set_str_prop ("name", _name.c_str ()); + } +}; + +#endif // __RepoNameKey_h__ diff --git a/AspectC++/RepoPosAspectKey.cc b/AspectC++/RepoPosAspectKey.cc new file mode 100644 index 0000000..885e9ff --- /dev/null +++ b/AspectC++/RepoPosAspectKey.cc @@ -0,0 +1,30 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "RepoPosAspectKey.h" + +void RepoPosAspectKey::get_xml (RepoXMLNode node) { + _aspect_id = node.get_int_prop ("aspect"); + RepoPosKey::get_xml (node); +} + +void RepoPosAspectKey::make_xml (RepoXMLNode node) const { + node.set_int_prop ("aspect", aspect_id ()); + RepoPosKey::make_xml (node); +} + diff --git a/AspectC++/RepoPosAspectKey.h b/AspectC++/RepoPosAspectKey.h new file mode 100644 index 0000000..5875648 --- /dev/null +++ b/AspectC++/RepoPosAspectKey.h @@ -0,0 +1,39 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __RepoPosAspectKey_h__ +#define __RepoPosAspectKey_h__ + +#include "RepoPosKey.h" + +class RepoPosAspectKey : public RepoPosKey { + int _aspect_id; +public: + RepoPosAspectKey (int file_id, int line, int aspect_id) : + RepoPosKey (file_id, line), _aspect_id (aspect_id) {} + RepoPosAspectKey (RepoXMLNode node) : RepoPosKey (node) { get_xml (node); } + int operator < (const RepoPosAspectKey& key) const { + return _aspect_id == key._aspect_id ? + (*(const RepoPosKey *)this < key) : (_aspect_id < key._aspect_id); + } + int aspect_id () const { return _aspect_id; } + void get_xml (RepoXMLNode node); + void make_xml (RepoXMLNode node) const; +}; + +#endif // __RepoPosAspectKey_h__ diff --git a/AspectC++/RepoPosKey.cc b/AspectC++/RepoPosKey.cc new file mode 100644 index 0000000..5362cac --- /dev/null +++ b/AspectC++/RepoPosKey.cc @@ -0,0 +1,30 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "RepoPosKey.h" + +void RepoPosKey::get_xml (RepoXMLNode node) { + _file_id = node.get_int_prop ("file"); + _line = node.get_int_prop ("line"); +} + +void RepoPosKey::make_xml (RepoXMLNode node) const { + node.set_int_prop ("file", file_id ()); + node.set_int_prop ("line", line ()); +} + diff --git a/AspectC++/RepoPosKey.h b/AspectC++/RepoPosKey.h new file mode 100644 index 0000000..e0dce03 --- /dev/null +++ b/AspectC++/RepoPosKey.h @@ -0,0 +1,41 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __RepoPosKey_h__ +#define __RepoPosKey_h__ + +#include +#include "RepoXMLNode.h" + +class RepoPosKey { + int _file_id; + int _line; +public: + RepoPosKey (int file_id, int line) : _file_id (file_id), _line (line) {} + RepoPosKey (RepoXMLNode node) { get_xml (node); } + int operator < (const RepoPosKey& key) const { + return _file_id == key._file_id ? + (_line < key._line) : (_file_id < key._file_id); + } + int file_id () const { return _file_id; } + int line () const { return _line; } + void get_xml (RepoXMLNode node); + void make_xml (RepoXMLNode node) const; +}; + +#endif // __RepoPosKey_h__ diff --git a/AspectC++/RepoXMLDoc.h b/AspectC++/RepoXMLDoc.h new file mode 100644 index 0000000..eec509e --- /dev/null +++ b/AspectC++/RepoXMLDoc.h @@ -0,0 +1,69 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __RepoXMLDoc_h__ +#define __RepoXMLDoc_h__ + +#include "RepoXMLNode.h" + +#include +#include + +#include + +class RepoXMLDoc { + xmlDocPtr _doc; + int fd; +public: + RepoXMLDoc () : _doc (0) {} + ~RepoXMLDoc () { + if (!_doc) { + // delete the DOM + xmlFreeDoc (_doc); + } + } + void create (const char *root_name) { + _doc = xmlNewDoc((const xmlChar*)"1.0"); + _doc->children = xmlNewDocNode(_doc, NULL, + (const xmlChar*)root_name, NULL); + } + RepoXMLNode root () const { return _doc->children; } + bool load_fd (int fd, const char *name) { + _doc = xmlReadFd (fd, name, 0, + XML_PARSE_NODICT | XML_PARSE_NOERROR | + XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS); + return (_doc != 0); + } + bool load (const char *name) { + _doc = xmlReadFile (name, 0, + XML_PARSE_NODICT | XML_PARSE_NOERROR | + XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS); + return (_doc != 0); + } + bool save_fd (int fd) { + xmlSaveCtxtPtr ctx = xmlSaveToFd (fd, 0, XML_SAVE_FORMAT); + if (xmlSaveDoc (ctx, _doc) == -1) + return false; + return (xmlSaveClose (ctx) != -1); + } + bool save (const char *name) { + return (xmlSaveFormatFile (name, _doc, 1) != -1); + } +}; + +#endif // __RepoXMLDoc_h__ diff --git a/AspectC++/RepoXMLNode.cc b/AspectC++/RepoXMLNode.cc new file mode 100644 index 0000000..8356aa6 --- /dev/null +++ b/AspectC++/RepoXMLNode.cc @@ -0,0 +1,53 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "RepoXMLNode.h" + +bool RepoXMLNode::has_prop (const char* prop) { + return xmlHasProp (_node, (xmlChar*)prop) != NULL; +} + +void RepoXMLNode::set_str_prop (const char* prop, const char* val) { + xmlSetProp (_node, (xmlChar*)prop, (xmlChar*)val); +} + +void RepoXMLNode::set_int_prop (const char* prop, int val) { + char buffer[12]; + sprintf (buffer, "%d", val); + xmlSetProp (_node, (xmlChar*)prop, (xmlChar*)buffer); +} + +string RepoXMLNode::get_str_prop (const char* prop) { + char *str = (char*)xmlGetProp (_node, (xmlChar*)prop); + string result (str); + free (str); + return result; +} + +int RepoXMLNode::get_int_prop (const char* prop) { + char *str = (char*)xmlGetProp (_node, (xmlChar*)prop); + int val = atoi (str); + free (str); + return val; +} + +RepoXMLNode RepoXMLNode::make_child (const char *name) { + return xmlNewChild(_node, NULL, (xmlChar*)name, NULL); +} + + diff --git a/AspectC++/RepoXMLNode.h b/AspectC++/RepoXMLNode.h new file mode 100644 index 0000000..9d51d6a --- /dev/null +++ b/AspectC++/RepoXMLNode.h @@ -0,0 +1,60 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __RepoXMLNode_h__ +#define __RepoXMLNode_h__ + +#include +#include +#include +#include + +using namespace std; + +class RepoXMLNode { + xmlNodePtr _node; +public: + class Iter { + xmlNodePtr _node; + public: + Iter (xmlNodePtr n) : _node (n) {} + RepoXMLNode operator * () { return RepoXMLNode (_node); } + void operator ++ () { _node = _node->next; } + int operator == (const Iter &iter) const { return _node == iter._node; } + int operator != (const Iter &iter) const { return _node != iter._node; } + }; + typedef Iter iter; + + RepoXMLNode () : _node (0) {} + RepoXMLNode (xmlNodePtr n) : _node (n) {} + xmlNodePtr node () const { return _node; } + int operator ! () const { return (_node == 0); } + bool has_prop (const char* prop); + void set_str_prop (const char* prop, const char* val); + void set_int_prop (const char* prop, int val); + string get_str_prop (const char* prop); + int get_int_prop (const char* prop); + RepoXMLNode make_child (const char *name); + iter first_child () const { return Iter (_node->children); } + iter end_child () const { return Iter ((xmlNodePtr)0); } + bool has_name (const char *name) const { + return (strcmp (name, (const char*)_node->name) == 0); + } +}; + +#endif // __RepoXML_h__ diff --git a/AspectC++/Repository.cc b/AspectC++/Repository.cc new file mode 100644 index 0000000..03ea47b --- /dev/null +++ b/AspectC++/Repository.cc @@ -0,0 +1,240 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 +#include + +#include "Repository.h" +#include "version.h" +#include "PointCut.h" +#include "TransformInfo.h" +#include "OrderInfo.h" +#include "AdviceInfo.h" +#include "AspectInfo.h" +#include "RepoXMLDoc.h" + +using namespace Puma; + +void Repository::open (const char *name, ACErrorStream &err) { + + RepoXMLDoc doc; + + create (name); + + if (!doc.load (name) || !doc.root ().has_name ("ac-project")) { + err << sev_error << "project repository '" << name << "' cannot be opened" + " or is invalid" << endMessage; + return; + } + + string version = doc.root ().get_str_prop ("version"); + if (version != ac_version ()) { + err << sev_warning << "project file version '" + << version.c_str () << "' differs from ac++ version" << endMessage; + } + + RepoXMLNode joinpoints, files, aspects, adv; + + // iterate the top-level project elements + for (RepoXMLNode::iter curr = doc.root ().first_child (); + curr != doc.root ().end_child (); ++curr) { + if ((*curr).has_name ("joinpoint-list")) + joinpoints = *curr; + else if ((*curr).has_name ("file-list")) + files = *curr; + else if ((*curr).has_name ("aspect-list")) + aspects = *curr; + else if ((*curr).has_name ("advice-list")) + adv = *curr; + } + + if (!joinpoints || !files || !aspects || !adv) { + err << sev_error << "invalid project file, missing list" << endMessage; + return; + } + + // now read all join points, files, and aspects + _jprepo.get_xml (joinpoints); + _advrepo.get_xml (adv); + _asprepo.get_xml (aspects); + _frepo.get_xml (files); +} + +void Repository::create (const char *name) { + _name = name; +} + +void Repository::save (ACErrorStream &err) { + + // create an XML DOM + RepoXMLDoc doc; + doc.create ("ac-project"); + doc.root ().set_str_prop ("version", ac_version ()); + + // handle join points, files, and aspects + _jprepo.make_xml (doc.root ()); + _advrepo.make_xml (doc.root ()); + _asprepo.make_xml (doc.root ()); + _frepo.make_xml (doc.root ()); + + // save the file + if (!doc.save (_name)) { + err << sev_error << "Saving repository '" << _name << "' failed" + << endMessage; + } +} + +void Repository::close () { + _name = (const char *)0; +} + +ACM_Source *Repository::source_loc (ACM_Any &jpl) { + ACM_Source *src = 0; + typedef ACM_Container Container; + Container &locs = (jpl.type_val () & + (JPT_Execution|JPT_Construction|JPT_Destruction)) ? + ((ACM_Any*)jpl.get_parent ())->get_source() : jpl.get_source(); + for (Container::iterator i = locs.begin (); i != locs.end (); ++i) { + if ((*i)->get_kind () != SLK_DECL) { + src = *i; + break; + } + } + return src; +} + +Repository::REPO_ID Repository::consider (ACM_File &file) { + return _frepo.insert (file.get_filename ().c_str (), file.get_len (), _primary); +} + +Repository::REPO_ID Repository::consider (ACM_Any &jpl, int adv) { + ACM_Source *src = source_loc (jpl); + if (!src) + return -1; + REPO_ID file_id = consider (*src->get_file()); + string sig = "**unknown**"; + if (jpl.type_val () & JPT_Code) + sig = signature ((ACM_Code&)jpl); + else if (jpl.type_val () & JPT_Name) + sig = signature ((ACM_Name&)jpl); + // TODO: deal with 'else' here -> fatal error? + // map type string to old-style + string type_str = "unsupported"; + if (string(jpl.type_str ()) == "Execution") + type_str = "exec"; + else if (string(jpl.type_str ()) == "Call") + type_str = "call"; + else if (string(jpl.type_str ()) == "Construction") + type_str = "construction"; + else if (string(jpl.type_str ()) == "Destruction") + type_str = "destruction"; + else if (string(jpl.type_str ()) == "Class") + type_str = "class"; + else if (string(jpl.type_str ()) == "Aspect") + type_str = "class"; + + REPO_ID jp_id = _jprepo.insert (file_id, src->get_line (), sig, + type_str, adv, src->get_len ()); + return jp_id; +} + +Repository::REPO_ID Repository::consider (ACM_Aspect &jpl) { + ACM_Source *src = source_loc (jpl); + if (!src) + return -1; + REPO_ID file_id = consider (*src->get_file()); + return _asprepo.insert (file_id, src->get_line (), signature (jpl).c_str()); +} + +Repository::REPO_ID Repository::consider (ACM_Introduction &intro) { + ACM_Source *src = source_loc (intro); + if (!src) + return -1; + // remember aspect and advice information in the project repository + REPO_ID aspect_id = consider (*(ACM_Aspect*)intro.get_parent ()); + REPO_ID file_id = consider (*src->get_file()); + REPO_ID advice_id = _advrepo.insert (file_id, src->get_line (), + intro.type_str (), aspect_id, src->get_len ()); + return advice_id; +} + +void Repository::setup (ACM_TUnit* prim_unit) { + _frepo.noref (); + _jprepo.noref (); + _advrepo.noref (); + _asprepo.noref (); + _primary = -1; + _primary = consider (*prim_unit); +} + +void Repository::cleanup () { + set dep_files; + _frepo.dependent (_primary, dep_files); + _jprepo.cleanup (dep_files); + _advrepo.cleanup (dep_files); + _asprepo.cleanup (dep_files); + _frepo.cleanup (_primary); +} + +void Repository::update (ACM_Introduction &intro, ACM_Class &cls) { + // remember aspect information in the project repository + REPO_ID advice_id = consider (intro); + REPO_ID jp_id = consider (cls, advice_id); + if (_set_jpid) + cls.set_jpid (jp_id); // TODO: set JPID not what we really need here +} + +void Repository::update (AdviceInfo &ai, PointCut &target) { + // remember aspect information in the project repository + REPO_ID aspect_id = consider (ai.aspect ()); + ACM_Source *src = source_loc (ai.code ()); + if (!src) + return; + REPO_ID file_id = consider (*src->get_file()); + // determine advice type (before/after/around) as string + string type_str = "unsupported"; + switch (ai.code ().get_kind ()) { + case ACT_BEFORE: type_str = "before"; break; + case ACT_AFTER: type_str = "after"; break; + case ACT_AROUND: type_str = "around"; break; + } + REPO_ID advice_id = _advrepo.insert (file_id, src->get_line (), + type_str, aspect_id, src->get_len ()); + + for (PointCut::iterator iter = target.begin (); + iter != target.end (); ++iter) { + ACM_Any &jpl = *((*iter).location ()); + ACM_Source *src = source_loc (jpl); + if (!src) + continue; + REPO_ID jp_id = consider (jpl, advice_id); + if (_set_jpid) + jpl.set_jpid (jp_id); // TODO: set JPID not what we really need here + } +} + +void Repository::update (OrderInfo &oi) { + // remember order advice information in the project repository + REPO_ID aspect_id = consider (oi.aspect ()); + ACM_Source *src = source_loc (oi.order ()); + if (!src) + return; + REPO_ID file_id = consider (*src->get_file()); + /* REPO_ID advice_id = */ _advrepo.insert (file_id, src->get_line (), + "order", aspect_id, src->get_len ()); +} diff --git a/AspectC++/Repository.h b/AspectC++/Repository.h new file mode 100644 index 0000000..96e9201 --- /dev/null +++ b/AspectC++/Repository.h @@ -0,0 +1,77 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __Repository_h__ +#define __Repository_h__ + +#include +#include +using namespace std; +#include + +#include "FileRepo.h" +#include "AspectRepo.h" +#include "AdviceRepo.h" +#include "JoinPointRepo.h" +#include "TransformInfo.h" +#include "ACErrorStream.h" + +class PointCut; +class AspectInfo; +class OrderInfo; +class AdviceInfo; +class ACM_Any; +class ACM_Introduction; +class ACM_Aspect; +class ACM_Class; +class ACM_Advice; + +class Repository { + typedef int REPO_ID; + + bool _set_jpid; + const char *_name; + REPO_ID _primary; + + FileRepo _frepo; + AspectRepo _asprepo; + AdviceRepo _advrepo; + JoinPointRepo _jprepo; + + ACM_Source *source_loc (ACM_Any &jpl); + +public: + Repository (bool set_jpid) : _set_jpid (set_jpid) { _name = (const char *)0; } + ~Repository () { close (); } + bool initialized () const { return _name != (const char*)0; } + void open (const char *name, ACErrorStream &err); + void create (const char *name); + void save (ACErrorStream &err); + void close (); + void setup (ACM_TUnit* prim_unit); + REPO_ID consider (ACM_File &file); + REPO_ID consider (ACM_Any &jpl, int adv); + REPO_ID consider (ACM_Introduction &intro); + REPO_ID consider (ACM_Aspect &ai); + void update (ACM_Introduction &intro, ACM_Class &cls); + void cleanup (); + void update (AdviceInfo &ii, PointCut &target); + void update (OrderInfo &oi); +}; + +#endif // __Repository_h__ diff --git a/AspectC++/SourceLoc.h b/AspectC++/SourceLoc.h new file mode 100644 index 0000000..c278af9 --- /dev/null +++ b/AspectC++/SourceLoc.h @@ -0,0 +1,25 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __source_loc_h__ +#define __source_loc_h__ + +#include "ACModel/Elements.h" +typedef ACM_Source SourceLoc; + +#endif // __source_loc_h__ diff --git a/AspectC++/SyntacticContext.h b/AspectC++/SyntacticContext.h new file mode 100644 index 0000000..61a43e0 --- /dev/null +++ b/AspectC++/SyntacticContext.h @@ -0,0 +1,36 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __SyntacticContext_h__ +#define __SyntacticContext_h__ + +// class alias for frontend-specific preprocessor implementation + +#ifdef FRONTEND_PUMA + +#include "PumaSyntacticContext.h" +typedef PumaSyntacticContext SyntacticContext; + +#else // FRONTEND_CLANG + +#include "ClangSyntacticContext.h" +typedef ClangSyntacticContext SyntacticContext; + +#endif + +#endif // __ac_preprocessor_h__ diff --git a/AspectC++/TODO b/AspectC++/TODO new file mode 100644 index 0000000..37cf8e1 --- /dev/null +++ b/AspectC++/TODO @@ -0,0 +1,141 @@ +Änderungen bis zum HEAD +======================= + +Aufräumen: Olaf + +[ * Call-Advice umstellen ] + +* ACFileID aufräumen (FileID vs. FileEntry) + +* ACToken konsequent in Phase 1 nutzen + +* WeavePos konsequent in Phase 2 nutzen + +* PP::token_text(token) vs. token.text() => kein token.text() mehr + +* Clang-Klassen von Puma-Code befreien + +[* TJP nicht generiert; Bindings? (PragmaOnceObserver)] + +[* using namespace Puma/clang nicht in *.h] + +[* zu viele dynamische Tests (__ac_..._is) z.B. in PragmaOnceObserver und That] + +[* CodeWeaver mergen] + +[* Mehr Tests mit Puma-Frontend] + +[* ClangWeaverBase verbessert] + +[* Codemanipulation in Weaver vor Transformer-Aufruf vermieden] + +Bugs: Olaf + +[* Warum funktioniert das mit AspectClang gebaute ac++ nicht? ] + + - Problembbeschreibung ggf. an Benjamin übergeben + + +Bugs: Benjamin + +[* komischer Fehler (AspectPrivileges, ArrayWrapper, PrivateResult)] + +[* Doppelte Einfügungen vom Introducer (Puma/CTree.h)] + +[* rename_args für Clang (ArrayMangling, MatchExpr)] + +[* Automatische Expansion von Makros bei der Codetransformation] + + - ## Operator + +[* ClangASTVisitor korrigieren (Nested functions, local classes, ...)] + + - Umstellung auf Nutzung von Traverse*Decl() + +[* Unbekannte Datentypen bei Intros (Markus Buschhoff)] + +[* Lokal deklarierte Funktionen nicht zu ernst nehmen] + +[* BYPASS-Klassen für externe Basisklassen] + +[* Qt-Examples] + + - Assertion-Problem + +Tests: Benjamin + +[* Qt-Examples] + + +Implementieren: + +* Line-Direktiven (Bug209) + + - Testen mit Debugger + - update_line_directives für Clang implementieren + (ggf. in ClangIncludeExpander integrieren) + - richtige Direktiven in ClangWeaverBase einfügen (Olaf?) + - ClangIncludeExpander erzeugt falsche #line Direktiven: Sie beziehen + sich auf die Zeilennummern in Phase 2 und haben wegen der Code- + Manipulationen in Phase (AC-Namespace) einen Versatz zu den echten + Zeilennummern in der ursprünglichen Quelltextdatei. + +[* Introspection-Mechanismus] + + +Änderungen bis zum Release +========================== + +[ * IncludeExpander abschließen ] + +[ * Makro-Expansion (Test MacroCall + Qt Examples) ] + +[ * AspectC++-Tests => Bugs fixen. ] + +* Code-Weaver enthält keine frontend-spezifischen Teile mehr: Advice-Typen + +[ * Transformation in Weaver schöner machen => Clang-Implementierung ] + +[ * Puma-Abhängigkeiten: Project ] + +* aclang++ Frontend + + - puma.config Anbindung vereinfachen/vermeiden + + +Nice to have +============ + +* Korrekte Target-Definition für Clang -> Größenbestimming beim Cross-Compiling + +* Besserung Umgang mit -W... + +* Build-Server für MacOS + + +Wichtige Arbeiten bis zum Release +================================= + +* AspectC++ in Clang-Konfiguration mit libminipuma.a übersetzen können + + - #includes aufräumen + + - README aktualisieren + +* Line-Direktiven in Clang-Konfiguration implementieren (siehe oben) + + - Line-Direktiven überprüfen/reparieren + +* Code nochmal durchsehen und aufräumen + + - Puma/Clang vereinheitlichen, ... + +* Windows-Build per Cross-Compiler ermöglichen (Clang!) oder + notfalls VM für natives Build aufsetzen + +* Build-Hosts auf Clang-Konfiguration umstellen + +* Testen + + - wichtige Bugs fixen + diff --git a/AspectC++/ThisJoinPoint.cc b/AspectC++/ThisJoinPoint.cc new file mode 100644 index 0000000..e1cbdbe --- /dev/null +++ b/AspectC++/ThisJoinPoint.cc @@ -0,0 +1,766 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 "ThisJoinPoint.h" +#include "Naming.h" +#include "Binding.h" +#include "ACModel/Utils.h" +#include "ACResultBuffer.h" +#include "AdviceInfo.h" + +#include +using std::stringstream; +using std::endl; + +// special setup function for bindings +void ThisJoinPoint::setup (const Binding &binding) { + if (binding._used) { + _used |= (binding._this != 0) ? THAT : 0; + _used |= (binding._target != 0) ? TARGET : 0; + _used |= (binding._result != 0) ? RESULT : 0; + _used |= (binding._args.length () > 0) ? ARG : 0; + _used |= (PTR_INTERNAL_NEEDED|TYPE_INTERNAL_NEEDED); + } +} + +void ThisJoinPoint::check_field (const char* field, bool dyn_only) { + if (strcmp (field, "signature") == 0) + _used |= SIGNATURE; + else if (strcmp (field, "filename") == 0) + _used |= FILENAME; + else if (strcmp (field, "line") == 0) + _used |= LINE; + else if (strcmp (field, "args") == 0) + _used |= ARGS; + else if (strcmp (field, "arg") == 0) + _used |= ARG; + else if (strcmp (field, "argtype") == 0) + _used |= ARG_TYPE; + else if (strcmp (field, "type") == 0) + _used |= TYPE; + else if (strcmp (field, "id") == 0 || (!dyn_only && strcmp (field, "JPID") == 0)) + _used |= ID; + else if (strcmp (field, "resulttype") == 0) + _used |= RESULT_TYPE; + else if (strcmp (field, "that") == 0) + _used |= THAT; + else if (strcmp (field, "target") == 0) + _used |= TARGET; + else if (strcmp (field, "result") == 0) + _used |= RESULT; + else if (strcmp (field, "entity") == 0) + _used |= ENTITY; + else if (strcmp (field, "memberptr") == 0) + _used |= MEMBERPTR; + else if (strcmp (field, "array") == 0) + _used |= ARRAY; + else if (strcmp (field, "idx") == 0) + _used |= IDX; + else if (strcmp (field, "jptype") == 0) + _used |= JP_TYPE; + else if (strcmp (field, "action") == 0) + _used |= ACTION; + else if (strcmp (field, "wrapper") == 0) + _used |= WRAPPER; + else if (strcmp (field, "proceed") == 0) { + _used |= PROCEED_ADVICE; + _proceed_calls++; + } +} + +bool ThisJoinPoint::check_type (const string &name) { + if (name == "JoinPoint" || name.substr(0, 11) == "JoinPoint::") { + _used |= TYPE_ADVICE_NEEDED; + return true; + } + return false; +} + +bool ThisJoinPoint::check_obj (const string &name) { + if (name == "tjp") { + _used |= (PTR_ADVICE_NEEDED | TYPE_ADVICE_NEEDED); + return true; + } + else if (name == "thisJoinPoint") { + _used |= (PTR_ADVICE_NEEDED | PTR_ALIAS_NEEDED | TYPE_ADVICE_NEEDED); + return true; + } + return false; +} + +// Checks if it is necessary to weave additionally things like call wrapper +// arguments to ensure correct runtime checks +void ThisJoinPoint::check_condition(const Condition& condition) { + if (condition) { + // that needed? + TypeCheckSet tcs; + condition.checks_for_that(tcs); + if(!tcs.empty()) { + _used |= THAT; + } + } +} + +void ThisJoinPoint::gen_tjp_struct (ostream &code, ACM_Code *loc, + BackEndProblems &bep, int depth) const { + // the level 0 struct -> contains all the data and types + code << "template type_val() & ( JPT_Access & ~ ( JPT_Call | JPT_Builtin ) ) ) + code << "typename TDims, "; + } +#endif + code << "typename TArgs"; + if( _need_wormhole ) + code << ", typename TWORMHOLE"; + code << "> struct "; + Naming::tjp_struct (code, loc, depth); + if (depth > 0) { + // the level N > 0 structs -> are derived from level N - 1 + code << " : "; + Naming::tjp_struct (code, loc, depth - 1); + code << "type_val() & ( JPT_Access & ~ ( JPT_Call | JPT_Builtin ) ) ) + code << "TDims, "; + } +#endif + code << "TArgs"; + if( _need_wormhole ) + code << ", TWORMHOLE"; + code << ">"; + } + else { + // the level N == 0 structs are derived from AC::Action, if action() used + if (useAction()) + code << " : AC::Action"; + } + code << " {" << endl; + code << " typedef "; + Naming::tjp_struct (code, loc, depth); + code << " __TJP;" << endl; // internal type definition + + if( depth != 0 ) + return; // nothing to do, skip generation of lvl 0 parts + + stringstream types, data, fct; + + // start: type definitions -------------------------------------------------- + bool res_is_undef = !has_result_type(*loc); + bool res_is_ref = false; + if (!res_is_undef) { + ACM_Type *rtype = get_result_type (*loc); + MatchSignature &match_sig = rtype->get_match_sig(); + if (match_sig.is_new()) + match_sig.parse(format_type (*rtype)); + if (match_sig.type ().is_reference()) + res_is_ref = true; + } + types << " typedef TResult" << ( res_is_ref ? "*" : "" ) << ( forced_const_result() ? " const" : "" ) << " Result;" << endl; + types << " typedef TThat That;" << endl; + types << " typedef TTarget Target;" << endl; +#ifdef FRONTEND_CLANG + // this feature is only available in Clang and if enabled on cmdline + if( _enable_entity ) { + types << " typedef TEntity Entity;" << endl; + if( loc->type_val() & ( JPT_Access & ~ ( JPT_Call | JPT_Builtin ) ) ) { + types << " enum { DIMS = TDims::Count };" << endl; + types << " typedef typename TDims::template Array::Type Array;" << endl; + types << " template struct Dim : AC::DIL_Op {};" << endl; + } + else + types << " enum { DIMS = 0 };" << endl; + if( memberptr_defined( loc ) ) + types << " typedef " << ( array_defined( loc ) ? "Array" : "TEntity" ) << " TTarget::* MemberPtr;" << endl; + else // use void * for non member entities (function returns 0) + types << " typedef void * MemberPtr;" << endl; + } +#endif + + // argument count and types + unsigned arg_count = get_arg_count( *loc ); + types << " enum { ARGS = TArgs::ARGS };" << endl; + if( forced_const_args() ) { + types << " template struct Arg : AC::ArgCQ {};" << endl; + } + else + types << " template struct Arg : AC::Arg {};" << endl; + + // join point id and type; + // TODO: handle join-point ID in TJP + if (id()) { + int jpid = loc->get_jpid(); //(loc->assigned_id () == -1 ? loc->id () : loc->assigned_id ()); + types << " static const int JPID = " << jpid << ";" << endl; + } + types << " static const AC::JPType JPTYPE = (AC::JPType)"; + switch( loc->type_val() ) { // map to real ids if necessary + case JPT_GetRef: + types << JPT_Get; break; + case JPT_SetRef: + types << JPT_Set; break; + default: + types << loc->type_val(); break; + } + types << ";" << endl; + + // result type + types << " struct Res {" << endl; + types << " typedef " << (res_is_undef ? "void" : "TResult") << " " + << (res_is_ref ? "&" : "") << "Type;" << endl; + types << " typedef " << (res_is_undef ? "void" : "TResult") << " ReferredType;" << endl; + types << " };" << endl; + + if( _need_wormhole ) + types << " typedef TWORMHOLE __WORMHOLE;" << endl; + + // begin of static data ----------------------------------------------------- + if (signature ()) { + fct << " inline static const char *signature () { return \""; + fct << ::signature (*loc) << "\";}" << endl; + } + if (filename ()) { + fct << " inline static const char *filename () { return \""; + fct << ::filename (*loc) << "\";}" << endl; + } + if (line ()) { + fct << " inline static int line () { return "; + fct << ::line(*loc) << ";}" << endl; + } + if (args ()) { + fct << " inline static const int args () { return "; + fct << arg_count << ";"; + fct << " }" << endl; + } + if (type()) { + fct << " inline static AC::Type type() { return "; + fct << "\""; + if (has_result_type(*loc)) + Naming::mangle (fct, get_result_type(*loc)); + list tlist; + get_arg_types (*loc, tlist); + for (list::iterator iter = tlist.begin(); iter != tlist.end(); + ++iter) + Naming::mangle (fct, *iter); + fct << "\"; }" << endl; + } + if (id()) { + fct << " inline static unsigned int id() { return JPID; }" << endl; + } + + if (resulttype()) { + fct << " inline static AC::Type resulttype() {return "; + if (has_result_type(*loc)) { + fct << "\""; + Naming::mangle (fct, get_result_type(*loc)); + fct << "\";"; + } else fct << "\"\";"; + fct << "}" << endl; + } + + if (jptype()) { + fct << " inline static AC::JPType jptype() { return JPTYPE; }" << endl; + } + + if (argtype()) { + fct << " inline static AC::Type const argtype(unsigned i) {" << endl; + if (arg_count > 0) { + fct << " static AC::Type const type[" << arg_count << "] = {"; + list tlist; + get_arg_types (*loc, tlist); + unsigned i = 0; + for (list::iterator iter = tlist.begin(); iter != tlist.end(); + ++iter, ++i) { + if (i > 0) fct << ", "; + fct << "\""; + Naming::mangle (fct, *iter); + fct << "\""; + } + fct << "};" << endl; + fct << " return type[i];" << endl; + fct << " }" << endl; + } else { + fct << " return \"\";" << endl; + fct << " }" << endl; + } + } + + // begin of dynamic data ---------------------------------------------------- + if( arg_needed( loc ) ) { + if (!useAction () && arg_count > 0) + data << " void *_args[ARGS];" << endl; + fct << " inline " << ( forced_const_args() ? "const " : "" ) << "void * arg (int n) {return " + << (arg_count > 0 ? "_args[n]" : "0") << ";}" << endl; + fct << " template typename Arg::ReferredType *arg () {" + << endl; + fct << " return (typename Arg::ReferredType*)arg (I);" << endl; + fct << " }" << endl; + } + + if( result_needed( loc ) ) { + if (!useAction ()) + data << " Result *_result;" << endl; + fct << " inline Result *result() {return (Result*)_result;}" << endl; + } + + if( target_needed( loc ) ) { + if (!useAction ()) + data << " Target *_target;" << endl; + fct << " inline Target *target() {return (Target*)_target;}" << endl; + } + +#ifdef FRONTEND_CLANG + // this feature is only available in Clang and if enabled on cmdline + if( entity_needed( loc ) ) { + if( !useAction() ) + data << " Entity *_entity;" << endl; + fct << " inline Entity *entity() {return (Entity *)_entity;}" << endl; + } + + // member pointers cant be represented as void * so they are not available in action + if( memberptr_needed( loc ) ) { + if( memberptr_defined( loc ) ) { + data << " MemberPtr _memberptr;" << endl; + fct << " inline MemberPtr memberptr() {return _memberptr;}" << endl; + } + else // return void *0 for non member entities + fct << " inline MemberPtr memberptr() {return 0;}" << endl; + } + if( loc->type_val() & ( JPT_Access & ~ ( JPT_Call | JPT_Builtin ) ) ) { + if( ! useAction() && array_defined( loc ) ) { + if( array_needed( loc ) ) + data << " Array *_array;" << endl; + if( idx_needed( loc ) ) + data << " void *_indices[DIMS];" << endl; + } + if( array_needed( loc ) ) + fct << " inline Array *array() {return (Array*)" << ( array_defined( loc ) ? "_array" : "0" ) << ";}" << endl; + if( idx_needed( loc ) ) { + if( array_defined( loc ) ) { + fct << " template typename Dim::Idx idx() {" << endl; + fct << " return *((typename Dim::Idx*)_indices[D]);" << endl; + fct << " }" << endl; + } + else + fct << " template void idx() { return; }" << endl; + } + } +#endif + + if( that_needed( loc ) ) { + if (!useAction ()) + data << " That *_that;" << endl; + fct << " inline That *that() {return (That*)_that;}" << endl; + } + + if (wrapper() || useAction ()) { + if (!useAction ()) + data << " void (*_wrapper)(AC::Action &);" << endl; + fct << " inline void (*wrapper ())(AC::Action &) {return _wrapper;}" << endl; + } + + if( _need_wormhole ) + data << " __WORMHOLE *__wormhole;" << endl; + + // terminate all the strings + types << endl; + data << endl; + fct << endl; + + // add all types, attributes, and functions (on level 0) + assert( depth == 0 ); // the functions returns early if not on level 0 + code << types.rdbuf(); + code << data.rdbuf(); + code << fct.rdbuf(); + + // the closing bracket is *NOT* generated here -> for external extensions +} + +ACM_Function *ThisJoinPoint::that_func (ACM_Code *loc) { + ACM_Name *parent = get_explicit_parent( *loc ); + return ( parent && ( parent->type_val() == JPT_Function ) ) ? static_cast( parent ) : 0; +} + +void ThisJoinPoint::gen_tjp_init (ostream &code, ACM_Code *loc, + BackEndProblems &bep, int depth, bool is_dep, + vector *arg_names, int wrapper_number ) const { + const ThisJoinPoint &tjp = *this; // TODO: not necessary! + JoinPointType jptype = loc->type_val (); + + if (tjp.pointer_needed ()) { + + code << " __TJP "; + Naming::tjp_instance(code, loc); + code << ";" << endl; + +#ifdef FRONTEND_CLANG + TI_Builtin *builtin = 0; + if( loc->type_val() == JPT_Builtin ) + builtin = TI_Builtin::of( static_cast( *loc ) ); +#endif + + int args = get_arg_count(*loc); + if (arg_needed (loc)) { + if (args) { + if (tjp.useAction ()) { + code << " void *"; + Naming::tjp_args_array(code, loc); + code << "[] = { "; + for (int i = 0; i < args; i++) { + if (i > 0) + code << ", "; + code << "(void*)"; +#ifdef FRONTEND_CLANG + if( builtin && builtin->arg_is_unavailable( i, wrapper_number ) ) { + code << "0"; + continue; + } + else +#endif + code << "&"; + if (arg_names) + code << (*arg_names)[i]; + else + code << "arg" << i; + } + code << " };" << endl; + } + } + + if (tjp.useAction ()) { + code << " "; + Naming::tjp_instance(code, loc); + code << "._args = "; + if (args) + Naming::tjp_args_array(code, loc); + else + code << "0"; + code << ";" << endl; + } + else { + for (int i = 0; i < args; i++) { + code << " "; + Naming::tjp_instance(code, loc); + code << "._args[" << i << "] = (void*)"; +#ifdef FRONTEND_CLANG + if( builtin && builtin->arg_is_unavailable( i, wrapper_number ) ) { + code << "0;" << endl; + continue; + } + else +#endif + code << "&"; + if (arg_names) + code << (*arg_names)[i]; + else + code << "arg" << i; + code << ";" << endl; + } + } + } + + if( result_needed( loc ) ) { + code << " "; + Naming::tjp_instance(code, loc); + code << "._result = "; + if (!has_result_type(*loc) || get_result_type(*loc)->get_signature() == "void") { + code << "0"; + } else { + if (tjp.useAction ()) + code << "(void*)"; + code << "&(" << (is_dep ? "typename " : "") << "__TJP::Result&)" << ACResultBuffer::result_name(); + } + code << ";" << endl; + } + +#ifdef FRONTEND_CLANG + // this feature is only available in Clang and if enabled on cmdline + if( entity_needed( loc ) ) { + code << " "; + Naming::tjp_instance(code, loc); + code << "._entity = "; + if( loc->type_val() & ( JPT_Code & ~ JPT_Builtin ) ) { + code << " ("; + if (tjp.useAction ()) + code << "void*)"; + else + code << (is_dep ? "typename " : "") << "__TJP::Entity *)"; + if( has_entity_func( *loc ) && needs_this( *get_entity_func( *loc ) ) ) + code << "0"; // for member function we can't aquire a normal function pointer + else + code << "&ent"; + } + else { + code << " 0"; + } + code << ";" << endl; + } + + // this feature is only available in Clang and if enabled on cmdline + if( memberptr_defined( loc ) && memberptr_needed( loc ) ) { + code << " "; + Naming::tjp_instance(code, loc); + code << "._memberptr = " << "(" << (is_dep ? "typename " : "") << "__TJP::MemberPtr)" << "member;" << endl; + } + + if( loc->type_val() & ( JPT_Access & ~ ( JPT_Call | JPT_Builtin ) ) ) { + if( array_needed( loc ) && array_defined( loc ) ) { + code << " "; + Naming::tjp_instance( code, loc ); + code << "._array = ("; + if( tjp.useAction() ) + code << "void*)"; + else + code << (is_dep ? "typename " : "") << "__TJP::Array*)"; + code << "&base;" << endl; + } + else if( useAction() ) { // useAction() => array_needed() , thus array_defined() == false here + code << " "; + Naming::tjp_instance( code, loc ); + code << "._array = 0;" << endl; + } + + const unsigned int idx_count = TI_Access::of( *static_cast( loc ) )->entity_index_count(); + if( useAction() ) { + code << " void *__idx_array[] = { "; + for( unsigned int i = 0; i < idx_count; i++ ) { + if( i > 0 ) + code << ", "; + code << "(void*)&idx" << i; + } + code << " };" << endl; + + code << " "; + Naming::tjp_instance( code, loc ); + code << "._indices = " << ( array_defined( loc ) ? "__idx_array" : "0" ) << ";" << endl; + } + else if( idx_needed( loc ) && array_defined( loc ) ) { + for( unsigned int i = 0; i < idx_count; i++ ) { + code << " "; + Naming::tjp_instance( code, loc ); + code << "._indices[" << i << "] = (void *)&idx" << i << ";" << endl; + } + } + } +#endif + + if( target_needed( loc ) ) { + code << " "; + Naming::tjp_instance(code, loc); + code << "._target = "; + if( has_entity( *loc ) && needs_this( *get_entity( *loc ) ) ) { + assert(jptype != JPT_Builtin); + code << " ("; + if (tjp.useAction ()) + code << "void*)"; + else { + code << (is_dep ? "typename " : "") << "__TJP::Target*)"; + } + switch (jptype) { + // inner joinpoints + case JPT_Construction: + case JPT_Destruction: + case JPT_Execution: + code << "this"; + break; + // outer joinpoints + case JPT_Call: + case JPT_Get: + case JPT_Set: + case JPT_Ref: + code << "&dst"; + break; + default: + code << " 0"; + } + } else { + code << " 0"; + } + code << ";" << endl; + } + + if( that_needed( loc ) ) { + code << " "; + Naming::tjp_instance(code, loc); + code << "._that = "; + if (that_func (loc) && needs_this (*that_func (loc))) { + code << " ("; + if (tjp.useAction ()) + code << "void*)"; + else { + code << (is_dep ? "typename " : "")<< "__TJP::That*)"; + } + switch (jptype) { + // inner joinpoints + case JPT_Construction: + case JPT_Destruction: + case JPT_Execution: + code << "this"; + break; + // outer joinpoints + case JPT_Call: + case JPT_Builtin: + case JPT_Get: + case JPT_Set: + case JPT_Ref: + case JPT_GetRef: + case JPT_SetRef: + code << "srcthis"; + break; + default: + code << " 0"; + } + } else { + code << " 0"; + } + code << ";" << endl; + } + + if (tjp.useAction ()) { + code << " "; + Naming::tjp_instance(code, loc); + code << "._fptr = "; + code << "0"; + code << ";" << endl; + } + } +} + +void ThisJoinPoint::merge_flags (ACM_CodePlan &plan) { + if (plan.has_next_level()) + merge_flags(*plan.get_next_level()); + typedef ACM_Container Container; + Container &before = plan.get_before(); + for (Container::iterator i = before.begin(); i != before.end(); ++i) + TI_CodeAdvice::of(*(*i))->get_advice_info()->addTJPFlags(*this); + if (plan.has_around()) { + TI_CodeAdvice::of(*plan.get_around())->get_advice_info()->addTJPFlags(*this); + if (*TI_CodeAdvice::of(*plan.get_around())->get_condition()) + conditional(); + } + Container &after = plan.get_after(); + for (Container::iterator i = after.begin(); i != after.end(); ++i) + TI_CodeAdvice::of(*(*i))->get_advice_info()->addTJPFlags(*this); +} + +#ifdef FRONTEND_CLANG +// only required for features of the Clang variant +void ThisJoinPoint::merge_implicit( ACM_Code &loc ) { + assert( loc.type_val() == JPT_Builtin ); // currently only builtin operator calls can have implicit joinpoints + ACM_Builtin &node = static_cast( loc ); + + ThisJoinPoint collect; + + typedef ACM_Container Container; + Container &implicit = node.get_implicit_access(); + for( Container::const_iterator it = implicit.begin(); it != implicit.end(); it++ ) { + if( ( *it )->has_plan() ) + collect.merge_flags( *( ( *it )->get_plan() ) ); + if( TI_Code::of( **it )->has_implicit_joinpoints() ) + collect.merge_implicit( **it ); + } + + if( collect.useAction() ) { // if we use an action, make sure we have all we need + collect._used |= THAT; + } + + unsigned int mask = 0; // only forward a selection, as not all are shared + mask |= THAT; + + // merge + _used |= ( collect._used & mask ); +} +#endif + +bool ThisJoinPoint::arg_needed( ACM_Code *loc ) const { + return arg() || useAction() || ( proceed() && proceed_needs_args( *loc ) ); +} + +bool ThisJoinPoint::that_needed( ACM_Code *loc ) const { + return that() || useAction() || ( proceed() && proceed_needs_that( *loc ) ); +} + +bool ThisJoinPoint::target_needed( ACM_Code *loc ) const { + return target() || useAction() || ( proceed() && proceed_needs_target( *loc ) ); +} + +bool ThisJoinPoint::result_needed( ACM_Code *loc ) const { + return result() || useAction() || ( proceed() && proceed_needs_result( *loc ) ); +} + +bool ThisJoinPoint::entity_needed( ACM_Code *loc ) const { + return _enable_entity && ( entity() || useAction() ); +} + +bool ThisJoinPoint::memberptr_needed( ACM_Code *loc ) const { + return _enable_entity && memberptr(); +} + +bool ThisJoinPoint::memberptr_defined( ACM_Code *loc ) const { + return has_entity( *loc ) && needs_this( *get_entity( *loc ) ) && ! ( loc->type_val() == JPT_Construction || loc->type_val() == JPT_Destruction ); +} + +bool ThisJoinPoint::array_needed( ACM_Code *loc ) const { + return _enable_entity && ( array() || useAction() ); +} + +bool ThisJoinPoint::array_defined( ACM_Code *loc ) const { +#ifdef FRONTEND_CLANG + // arrays are only supported in the clang variant + if( ! ( loc->type_val() & ( JPT_Access & ~ ( JPT_Call | JPT_Builtin ) ) ) ) +#endif + return false; + +#ifdef FRONTEND_CLANG + TI_Access *ti = TI_Access::of( *static_cast( loc ) ); + return ti->entity_index_count() > 0; +#endif +} + +bool ThisJoinPoint::idx_needed( ACM_Code *loc ) const { + return _enable_entity && ( idx() || useAction() ); +} + +void ThisJoinPoint::dump (ostream &out) const { + out << "ThisJoinPoint ("; + out << "signature=" << (signature () ? "true" : "false"); + out << ", filename=" << (filename () ? "true" : "false"); + out << ", line=" << (line () ? "true" : "false"); + out << ", args=" << (args () ? "true" : "false"); + out << ", arg=" << (arg() ? "true" : "false"); + out << ", argtype=" << (argtype() ? "true" : "false"); + out << ", type=" << (type() ? "true" : "false"); + out << ", id=" << (id() ? "true" : "false"); + out << ", resulttype=" << (resulttype() ? "true" : "false"); + out << ", that=" << (that() ? "true" : "false"); + out << ", target=" << (target() ? "true" : "false"); + out << ", result=" << (result() ? "true" : "false"); + out << ", entity=" << (entity() ? "true" : "false"); + out << ", memberptr=" << (memberptr() ? "true" : "false"); + out << ", array=" << (array() ? "true" : "false"); + out << ", idx=" << (idx() ? "true" : "false"); + out << ", jptype=" << (jptype() ? "true" : "false"); + out << ", action=" << (action() ? "true" : "false"); + out << ", proceed=" << (proceed() ? "true" : "false"); + out << ")" << endl; +} diff --git a/AspectC++/ThisJoinPoint.h b/AspectC++/ThisJoinPoint.h new file mode 100644 index 0000000..24e5f8c --- /dev/null +++ b/AspectC++/ThisJoinPoint.h @@ -0,0 +1,156 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __ThisJoinPoint_h__ +#define __ThisJoinPoint_h__ + +#include +#include +#include +using namespace std; + +#include "BackEndProblems.h" + +class Binding; +class ACM_Code; +class ACM_Function; +class ACM_CodePlan; +class Condition; + +class ThisJoinPoint { + enum + { + // these values define required information + SIGNATURE=0x1, ARGS=0x2, ARG=0x4, ARG_TYPE=0x8, + TYPE=0x10, ID=0x20, RESULT_TYPE=0x40, RESULT=0x80, + THAT=0x100, TARGET=0x200, JP_TYPE=0x400, ACTION=0x800, + WRAPPER=0x1000, PROCEED_ADVICE=0x2000, FILENAME=0x4000, LINE=0x8000, + // does the advice need a pointer 'tjp' + PTR_ADVICE_NEEDED=0x10000, + // does the advice need an alias 'thisJoinPoint' for 'tjp' + PTR_ALIAS_NEEDED=0x20000, + // does the advice need the type JoinPoint + TYPE_ADVICE_NEEDED=0x40000, + ENTITY=0x80000, MEMBERPTR=0x100000, ARRAY=0x200000, IDX=0x400000, + // does the internal code needs a pointer 'tjp' + PTR_INTERNAL_NEEDED=0x800000, + // does the internal code needs the type JoinPoint + TYPE_INTERNAL_NEEDED=0x1000000, + // does the internal code needs the proceed function + PROCEED_INTERNAL_NEEDED=0x2000000 + }; + + unsigned int _used; + unsigned int _proceed_calls; + unsigned int _force_const; + unsigned int _force_const_args; + + bool _enable_entity; + bool _need_wormhole; + + static ACM_Function *that_func (ACM_Code *loc); + +public: + ThisJoinPoint () : _used (0), _proceed_calls (0), _force_const( 0 ), _force_const_args( 0 ), _enable_entity( false ), _need_wormhole( false ) {} + + void setup (const Binding &binding); + void check_field (const char* field, bool dyn_only = false); + bool check_type (const string &name); + bool check_obj (const string &name); + void check_condition(const Condition&); + + void conditional () { _used |= (PROCEED_INTERNAL_NEEDED|TYPE_INTERNAL_NEEDED|PTR_INTERNAL_NEEDED); } + + bool signature () const { return (_used & SIGNATURE); } + bool filename () const { return (_used & FILENAME); } + bool line () const { return (_used & LINE); } + bool args () const { return (_used & ARGS); } + bool arg () const { return (_used & ARG); } + bool argtype() const { return (_used & ARG_TYPE); } + bool type() const { return (_used & TYPE); } + bool id() const { return (_used & ID); } + bool resulttype() const { return (_used & RESULT_TYPE); } + bool that() const { return (_used & THAT); } + bool target() const { return (_used & TARGET); } + bool result() const { return (_used & RESULT); } + bool entity() const { return (_used & ENTITY); } + bool memberptr() const { return (_used & MEMBERPTR); } + bool array() const { return ( _used & ARRAY ); } + bool idx() const { return ( _used & IDX ); } + bool jptype() const { return (_used & JP_TYPE); } + bool action() const { return (_used & ACTION); } + bool wrapper() const { return (_used & WRAPPER); } + + bool proceed() const { return proceed_advice() || proceed_internal(); } + bool proceed_internal() const { return (_used & PROCEED_INTERNAL_NEEDED); } + bool proceed_advice() const { return (_used & PROCEED_ADVICE); } + + unsigned int proceed_calls () const { return _proceed_calls; } + + void require_entity() { _used |= ENTITY; } + void require_idx() { _used |= IDX; } + + void gen_tjp_struct (ostream &code, ACM_Code *loc, + BackEndProblems &bep, int depth) const; + void gen_tjp_init (ostream &code, ACM_Code *loc, + BackEndProblems &bep, int depth, bool is_dep = false, + vector *arg_names = 0, int wrapper_number = -1 ) const; + void merge_flags (ACM_CodePlan &plan); + void merge_implicit( ACM_Code &jpl ); + void dump (ostream &os) const; + + bool pointer_needed () const { return pointer_advice_needed() || pointer_internal_needed(); } + bool pointer_internal_needed () const { return (_used & PTR_INTERNAL_NEEDED); } + bool pointer_advice_needed () const { return (_used & PTR_ADVICE_NEEDED); } + + bool pointer_alias_needed () const { return (_used & PTR_ALIAS_NEEDED); } + + bool type_needed () const { return type_advice_needed() || type_internal_needed(); } + bool type_internal_needed () const { return (_used & TYPE_INTERNAL_NEEDED); } + bool type_advice_needed () const { return (_used & TYPE_ADVICE_NEEDED); } + + bool arg_needed (ACM_Code *loc) const; + bool that_needed( ACM_Code *loc ) const; + bool target_needed( ACM_Code *loc ) const; + bool result_needed( ACM_Code *loc ) const; + bool entity_needed( ACM_Code *loc ) const; + bool memberptr_needed( ACM_Code *loc ) const; + bool memberptr_defined( ACM_Code *loc ) const; + bool array_needed( ACM_Code *loc ) const; + bool array_defined( ACM_Code *loc ) const; + bool idx_needed( ACM_Code *loc ) const; + + bool forced_const_arg( unsigned int i ) const { assert( i < 32 ); return ( _force_const_args & ( 1 << i ) ); } + bool forced_const_args() const { return _force_const_args; } + void force_const_arg( unsigned int i ) { _force_const_args |= ( 1 << i ); } + bool forced_const_result() const { return (_force_const & RESULT ); } + void force_const_result() { _force_const |= RESULT; } + + bool useAction() const { return action(); } + + void merge (const ThisJoinPoint &from) { _used |= from._used; } + void clear () { _used = 0; } + +#ifdef FRONTEND_CLANG + void enable_entity() { _enable_entity = true; } +#endif + void request_wormhole() { _need_wormhole = true; } + bool has_wormhole() const { return _need_wormhole; } +}; + +#endif // __ThisJoinPoint_h__ diff --git a/AspectC++/TransformInfo.h b/AspectC++/TransformInfo.h new file mode 100644 index 0000000..9171821 --- /dev/null +++ b/AspectC++/TransformInfo.h @@ -0,0 +1,35 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __TransformInfo_h__ +#define __TransformInfo_h__ + +// This header file includes the right TransformInfo class implementations +// depending on the configured frontend + +#ifdef FRONTEND_PUMA + +#include "PumaTransformInfo.h" + +#else // FRONTEND_CLANG + +#include "ClangTransformInfo.h" + +#endif + +#endif // __TransformInfo_h__ diff --git a/AspectC++/Transformer.cc b/AspectC++/Transformer.cc new file mode 100644 index 0000000..ed783b1 --- /dev/null +++ b/AspectC++/Transformer.cc @@ -0,0 +1,1378 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 + +#ifdef FRONTEND_CLANG +#include "ClangIntroSema.h" +#include "ClangIntroParser.h" +#include "clang/Parse/ParseDiagnostic.h" +#endif + +// AspectC++ includes +#include "Transformer.h" +#include "PointCut.h" +#include "PointCutContext.h" +#include "OrderInfo.h" +#include "AdviceInfo.h" +#include "AspectInfo.h" +#include "IntroductionInfo.h" +#include "Plan.h" +#include "Repository.h" +#include "PointCutContext.h" +#include "CFlow.h" +#include "BackEndProblems.h" +#include "ACConfig.h" +#include "ACIntroducer.h" +#include "IncludeGraph.h" +#include "PointCutExpr.h" +#include "ModelBuilder.h" +#include "IntroductionUnit.h" +#include "version.h" +#include "ACModel/XmlModelWriter.h" +#include "ACModel/XmlModelReader.h" +#include "Phase1.h" +#include "NamespaceAC.h" +#ifdef FRONTEND_CLANG +#include "ClangASTConsumer.h" +#include "ClangBinding.h" +#endif + +// PUMA includes +#include "Puma/VerboseMgr.h" +#include "Puma/SysCall.h" +#ifdef FRONTEND_PUMA +#include "Puma/CProject.h" +#include "Puma/CCSemVisitor.h" +#include "Puma/CFunctionInfo.h" +#include "Puma/CUnionInfo.h" +#include "Puma/CArgumentInfo.h" +#include "Puma/CTranslationUnit.h" +#include "Puma/CSemDatabase.h" +#include "Puma/CPrintVisitor.h" +#ifdef PROFILING +#include "Puma/GenericProfiler.ah" +#endif +#endif + +#ifdef FRONTEND_CLANG +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Lex/Preprocessor.h" +#include "clang/Parse/ParseAST.h" +#include "clang/AST/ASTContext.h" +#endif + +// C++ includes +#include +using std::stringstream; +using std::endl; +#include // for getenv +#ifdef _MSC_VER +#include +#else +#include // for access()! +#endif // _MSC_VER +#include + +using namespace Puma; + +ACFileID Transformer::work (const string &tunit_name) { + + // determine back-end compiler problems and setup code weaver + BackEndProblems back_end_problems; + back_end_problems._local_class = _conf.problem_local_class (); + back_end_problems._spec_scope = _conf.problem_spec_scope (); + back_end_problems._use_always_inline = !_conf.problem_force_inline (); + back_end_problems._warn_macro = _conf.warn_macro(); + back_end_problems._warn_deprecated = _conf.warn_deprecated(); + _code_weaver.problems (back_end_problems); + + _vm << "Path \"" << tunit_name << "\"" << endvm; + + ModelBuilder jpm (_vm, _err, _conf, _project); + jpm.set_version(ac_version ()); + IncludeGraph ig (_project); + + // perform the transformation + Unit *unit = 0; + bool ok = (phase1 (unit, tunit_name, jpm, ig) && + phase2 (unit, tunit_name, jpm, ig)); + + if (!ok) + _vm << "Aborting" << endvm; +#ifdef FRONTEND_CLANG + if (ok) { + clang::CompilerInstance *ci = _project.get_compiler_instance(); + clang::FileManager &fm = ci->getFileManager (); + const clang::FileEntry *fe = fm.getFile (tunit_name); + return fe; + } + return ACFileID(0); +#else + return unit; +#endif +} + +#ifdef FRONTEND_CLANG +void Transformer::reinitializeSourceManager(clang::CompilerInstance *ci, + CodeWeaver &cwb, const char *name) { + clang::SourceManager *NewSM = new clang::SourceManager(ci->getDiagnostics(), + ci->getFileManager()); + // Fetch code weaver changes into the new source manager. + cwb.commit(*NewSM); + clang::SourceManager &OldSM = ci->getSourceManager(); + // Transplant files that were changed in phase 1 but not rewritten in phase 2 + // into the new SourceManager. + for (clang::SourceManager::fileinfo_iterator fi = OldSM.fileinfo_begin(), + fe = OldSM.fileinfo_end(); + fi != fe; ++fi) { + if (!_project.isVirtualFile(ACFileID(fi->first))) + _touched_files.insert (fi->first); + if (OldSM.isFileOverridden(fi->first) && + !NewSM->isFileOverridden(fi->first)) { + const llvm::MemoryBuffer *buf = fi->second->getRawBuffer(); +#if CLANG_VERSION_NUMBER <= VERSION_NUMBER_3_5_2 + llvm::MemoryBuffer *bcopy = llvm::MemoryBuffer::getMemBufferCopy( + buf->getBuffer(), buf->getBufferIdentifier()); + NewSM->overrideFileContents(fi->first, bcopy); +#else // C++ 11 interface + NewSM->overrideFileContents(fi->first, + llvm::MemoryBuffer::getMemBufferCopy(buf->getBuffer(), buf->getBufferIdentifier())); +#endif + } + } + +// // print all buffers (for debugging code transformations, especially in phase 1) +// for (clang::SourceManager::fileinfo_iterator fi = NewSM->fileinfo_begin(), +// fe = NewSM->fileinfo_end(); +// fi != fe; ++fi) { +// const llvm::MemoryBuffer *buf = fi->second->getRawBuffer(); +// cout << "BUF: " << buf->getBuffer().str() << endl; +// } + + // Now insert the new source manager and initialize it. + ci->resetAndLeakSourceManager (); + ci->setSourceManager(NewSM); +#if CLANG_VERSION_NUMBER >= VERSION_NUMBER_5_0_0 + ci->InitializeSourceManager(clang::FrontendInputFile(name, clang::InputKind::CXX)); +#else + ci->InitializeSourceManager(clang::FrontendInputFile(name, clang::IK_CXX)); +#endif + + // Make sure the diagnostics engine doesn't have references to source + // locations from the old source manager: + ci->getDiagnostics().Reset(); +} +#else +void Transformer::update_touched_files () { + UnitManager::UMap &umap = _project.unitManager ().getTable (); + for (UnitManager::UMapIter iter = umap.begin (); + iter != umap.end (); ++iter) { + Unit *unit = (*iter).second; + if (unit->isFile ()) + _touched_files.insert (unit); + } +} +#endif + + +bool Transformer::phase1 (Unit *&unit, const string &tunit_name, + ModelBuilder &jpm, IncludeGraph &ig) { + +#ifdef PROFILING + static Profiler::Data data (__PRETTY_FUNCTION__, NULL); + Profiler::ClockTicks start = Profiler::rdtsc (); +#endif + +#ifdef FRONTEND_CLANG + clang::CompilerInstance *ci = _project.get_compiler_instance(); + _err.set_source_manager(&ci->getSourceManager()); +#endif + + // Create a forced include for each aspect header file that should be + // considered in this translation unit. Without this the phase 1 parser + // would not be able to analyse aspect headers! + if (_conf.iterate_aspects ()) { + // collect the names of aspect header files, + // generate a forced include for each of them + PathIterator ah_iter (".*\\.ah$"); + while (_project.iterate (ah_iter)) + _project.add_forced_include(ah_iter.file ()); + } + else { + // Get the names from the configuration object (-a options) + for (int i = 0; i < _conf.aspect_headers (); i++) + _project.add_forced_include(_conf.aspect_header (i)); + } + + // fill the model while parsing the AOP elements of the language in phase 1 + _vm << "Parsing ..." << endvm; +#ifdef FRONTEND_PUMA + Phase1 phase1 (jpm, tunit_name, _project, _conf, _code_weaver); + int result = phase1.run (ig); + unit = phase1.unit (); +#else + macro_recorder = &_code_weaver; + Phase1 phase1 (jpm, tunit_name, _project, _conf, _code_weaver, ig); + int result = phase1.run (); + macro_recorder = 0; +#endif + if (result == 0) { + _vm << "file is empty" << endvm; + unit = 0; + } + if (result != 1) + return false; + +// cout << "Project Model after Phase1" << endl; +// jpm.dump(); + + // set up the project repository + _repo.setup (jpm.tunit_file()); + + // now remove the forced includes of aspect headers from the parser configuration + // and generate includes at the end of the source code + string aspect_includes = ""; + vector incs; + _project.get_forced_includes(incs); + for (vector::iterator i = incs.begin (); i != incs.end (); ++i) { + if ((*i).rfind(".ah") == ((*i).size()-3)) {// aspect header! + _project.remove_forced_include (*i); + aspect_includes += "#include \""; + Filename incname = _project.getRelInclString (tunit_name.c_str(), (*i).c_str()); + aspect_includes += incname.name(); + aspect_includes += "\"\n"; + } + } + if (aspect_includes != "") { + _vm << "Inserting aspect header includes" << endvm; + aspect_includes = + string ("\n#ifndef __ac_have_predefined_includes__\n" + "/*** begin of aspect includes ***/\n") + + aspect_includes + + "/*** end of aspect includes ***/\n" + + "#endif"; + + _code_weaver.insert (_code_weaver.footer_pos (), aspect_includes); + } + + // generate a string with aspect forward declarations + _vm << "Weaving Aspects Forward Declarations ..." << endvm; + determine_aspect_fwd_decls (jpm); + _code_weaver.insert (_code_weaver.header_pos (), _aspect_fwd_decls); + + _vm << "Inserting namespace AC" << endvm; + _code_weaver.insert( _code_weaver.header_pos(), NamespaceAC::def( _conf ) ); + + // STU mode and not generating transformed headers! + if (!_conf.iterate () && !_conf.ifiles () && _conf.file_in ()) { + // expand forced includes in source code + string forced_includes = ""; + vector incs; + _project.get_forced_includes(incs); + for (vector::iterator i = incs.begin (); i != incs.end (); ++i) { + const string &filename = *i; + forced_includes += "#include "; + if (filename[0] == '\"' || filename[0] == '<') + forced_includes += filename; + else { + forced_includes += "\""; + forced_includes += filename; + forced_includes += "\""; + } + forced_includes += "\n"; + } + _project.remove_forced_includes(); + if (forced_includes != "") { + _vm << "Inserting forced includes" << endvm; + _code_weaver.insert (_code_weaver.header_pos (), forced_includes); + } + } + +//#ifdef FRONTEND_CLANG +// phase1.attrManipulation(); +//#endif + + _vm << "Committing" << endvm; + + +#ifdef FRONTEND_PUMA + update_touched_files (); + _code_weaver.commit (); +#else + // Reinitialize the source manager for phase 2. Commit changes into the new + // SourceManager. + _phase1_sm = &ci->getSourceManager(); + reinitializeSourceManager(ci, _code_weaver, tunit_name.c_str ()); +// reinitializeSourceManager(ci, _code_weaver, unit->name()); + _err.set_source_manager(&ci->getSourceManager()); +#endif + + // Some debugging code: +// unit->print(cout); + +// _vm << "Stage1 save!" << endvm; +// _project.save(); +// _vm << " done." << endvm; +// exit(1); + +#ifdef PROFILING + Profiler::ClockTicks end = Profiler::rdtsc (); + data._time += Profiler::duration (start, end); + data._calls = 1; +#endif + + return (_err.severity () < sev_error); +} + + +bool Transformer::phase2 (Unit *unit, const string &tunit_name, ModelBuilder &jpm, IncludeGraph &ig) { + +#ifdef PROFILING + static Profiler::Data data (__PRETTY_FUNCTION__, NULL); + Profiler::ClockTicks start = Profiler::rdtsc (); +#endif + + Plan plan (_err, jpm, _conf); + + _vm << "Preparing introductions ..." << endvm; + PointCutContext context (jpm, _conf); + + // perform semantic analysis of all pointcut expressions used for introductions + const list &intros = plan.introduction_infos (); + for (list::const_iterator i = intros.begin (); + i != intros.end (); ++i) { + IntroductionInfo *intro_info = *i; + ACM_Introduction &intro = intro_info->intro(); + context.concrete_aspect(intro_info->aspect()); + context.pct_func (intro.get_pointcut()); + PointCutExpr *pce = (PointCutExpr*)intro_info->pointcut_expr().get(); + pce->semantics(_err, context, _conf.warn_compatibility()); + if (!(pce->possible_types() & JPT_Class)) { + _err << sev_warning + << Location (Filename (filename (intro).c_str ()), line (intro)) + << "pointcut expression for introduction can't match class" + << endMessage; + } + } + + // ... and also for the pointcut expressions in order advice + const list &orders = plan.order_infos (); + for (list::const_iterator i = orders.begin (); + i != orders.end (); ++i) { + OrderInfo *oi = *i; + context.concrete_aspect (oi->aspect()); + oi->analyze_exprs (_err, context, _conf.warn_compatibility()); + if (getenv ("ACOLDREPO")) { + _repo.update (*oi); + } + } + + _vm << "Parsing again ..." << endvm; + +#ifdef FRONTEND_PUMA + // parse the translation unit, but ignore function bodies + ::ACIntroducer introducer (plan, _code_weaver, _parser, jpm, ig, _conf); + _parser.introducer (&introducer); + CTranslationUnit *tunit = _parser.parse (*unit, _project); + _parser.introducer (0); + + // do semantic analysis of expressions + _sem_visitor.run (tunit->tree ()); + list &ah_trees = introducer.ah_trees (); + for (list::iterator i = ah_trees.begin (); i != ah_trees.end (); ++i) + if (*i) + _sem_visitor.run (*i); + + if (_err.severity () >= sev_error) { + // TODO: delete takes too much time and has no real use for ac++ + // so we skip it for now + // delete tunit; + return false; + } +#else + clang::CompilerInstance *ci = _project.get_compiler_instance(); +#if CLANG_VERSION_NUMBER <= VERSION_NUMBER_3_5_2 + ClangASTConsumer *Consumer = new ClangASTConsumer(jpm); + ci->createPreprocessor(clang::TU_Complete); + ci->createASTContext(); + ci->setASTConsumer(Consumer); + clang::Preprocessor &PP = ci->getPreprocessor(); + ::ACIntroducer introducer (plan, _code_weaver, jpm, ig, _conf); + ClangIntroSema *intro_sema = + new ClangIntroSema(introducer, PP, ci->getASTContext (), + *Consumer, clang::TU_Complete, NULL); +#else // C++ 11 interface + std::unique_ptr Consumer (new ClangASTConsumer(jpm)); + ci->createPreprocessor(clang::TU_Complete); + ci->createASTContext(); + ci->setASTConsumer(std::move (Consumer)); + clang::Preprocessor &PP = ci->getPreprocessor(); + ::ACIntroducer introducer (plan, _code_weaver, jpm, ig, _conf); + ClangIntroSema *intro_sema = + new ClangIntroSema(introducer, PP, ci->getASTContext (), + ci->getASTConsumer (), clang::TU_Complete, NULL); +#endif + ci->setSema (intro_sema); + macro_recorder = &_code_weaver; +// PP.enableIncrementalProcessing(); + introducer._ci = ci; + + // make sure that attributes can be handled properly by ClangWeaverBase + _code_weaver.set_annotation_map(&jpm.annotation_map()); + + ci->getDiagnosticClient().BeginSourceFile(ci->getLangOpts(), &PP); +#if FRONTEND_CLANG < 38 + PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(), + PP.getLangOpts()); +#else + PP.getBuiltinInfo().initializeBuiltins(PP.getIdentifierTable(), + PP.getLangOpts()); +#endif + ClangIntroParser P(PP, *intro_sema, true); + introducer._parser = &P; + PP.EnterMainSourceFile(); + P.Initialize(); + clang::Parser::DeclGroupPtrTy ADecl; + clang::ExternalASTSource *External = ci->getASTContext().getExternalSource(); + if (External) + External->StartTranslationUnit(&ci->getASTConsumer ()); + + // handle code injections at the beginning of the translation unit + introducer.tunit_start(); + + // parse all top-level declarations + if (P.ParseTopLevelDecl(ADecl)) { + if (!External && !intro_sema->getLangOpts().CPlusPlus) + P.Diag(clang::diag::ext_empty_translation_unit); + } else { + do { + // If we got a null return and something *was* parsed, ignore it. This + // is due to a top-level semicolon, an action override, or a parse error + // skipping something. +#if CLANG_VERSION_NUMBER <= VERSION_NUMBER_3_5_2 + if (ADecl && !Consumer->HandleTopLevelDecl(ADecl.get())) +#else // C++ 11 interface + if (ADecl && !ci->getASTConsumer ().HandleTopLevelDecl(ADecl.get())) +#endif + break; + } while (!P.ParseTopLevelDecl(ADecl)); + } + + // Process any TopLevelDecls generated by #pragma weak. + for (clang::SmallVectorImpl::iterator + I = intro_sema->WeakTopLevelDecls().begin(), + E = intro_sema->WeakTopLevelDecls().end(); I != E; ++I) +#if CLANG_VERSION_NUMBER <= VERSION_NUMBER_3_5_2 + Consumer->HandleTopLevelDecl(clang::DeclGroupRef(*I)); + + Consumer->HandleTranslationUnit(intro_sema->getASTContext()); +#else // C++ 11 interface + ci->getASTConsumer().HandleTopLevelDecl(clang::DeclGroupRef(*I)); + + ci->getASTConsumer().HandleTranslationUnit(intro_sema->getASTContext()); +#endif + + //ci->getASTContext().getTranslationUnitDecl()->dump(); + + ci->getDiagnosticClient().EndSourceFile(); + // Abort in case of error. + if (ci->getDiagnosticClient().getNumErrors() > 0) { + // Indicate errors to Weaver. + _err.severity(const_cast(sev_error)); + return false; + } + + CTranslationUnit *tunit = 0; + macro_recorder = 0; +#endif + + //#ifdef TRY_INTRODUCER +// cout << "Printing semantic database..." << endl; +// tunit->db ().Dump (cout, 10); +//#endif // TRY_INTRODUCER + + // CPrintVisitor printer; + // printer.print (tunit->tree (), cout); + + if (getenv ("ACOLDREPO")) { + _vm << "Updating (old) repository intro part" << endvm; + update_intros_in_repo (jpm); + } + +#ifdef FRONTEND_PUMA + jpm.setup_phase2 (*tunit, ah_trees); +#endif + + // get all class from the join point model + ProjectModel::Selection all_classes; + jpm.select ((JoinPointType)(JPT_Class|JPT_Aspect), all_classes); + // update the plan for intros + for (ProjectModel::Selection::iterator iter = all_classes.begin (); + iter != all_classes.end (); ++iter) { + ACM_Class &jpl = (ACM_Class&)**iter; + link_members (jpl); + link_bases (jpl); + } + + _vm << "Weaving access control bypass classes ..." << endvm; + insert_bypass_class (jpm); + + _vm << "Weaving Join Points ..." << endvm; + join_points (*tunit, jpm, plan); + if (_err.severity () >= sev_error) + return false; + + _vm << "Final cleanup" << endvm; + cleanup (jpm); + + if (_conf.dynamic ()) { + _vm << "Preparing for dynamic weaving" << endvm; + prepare_dynamic_weaving (jpm); + } + + // generate a string with aspect header include directives + determine_aspect_includes (ig); + + _vm << "Committing" << endvm; +#ifdef FRONTEND_PUMA + update_touched_files (); + _code_weaver.commit (); +#else + // Now insert all IntroductionUnits back into the original files. After this + // it's no longer legal to use the CodeWeaver. + _code_weaver.resolve_introduction_units(introducer); + + // Reinitialize the source manager for the include expander step in Weaver. + // Commit changes into the new SourceManager. + clang::SourceManager *phase2_sm = &ci->getSourceManager(); + reinitializeSourceManager(ci, _code_weaver, tunit_name.c_str ()); + _err.set_source_manager(&ci->getSourceManager()); + delete _phase1_sm; + delete phase2_sm; +#endif + + // TODO: delete takes too much time and has no real use for ac++ + // so we skip it for now + // delete tunit; + + _repo.cleanup (); + +#ifdef PROFILING + Profiler::ClockTicks end = Profiler::rdtsc (); + data._time += Profiler::duration (start, end); + data._calls = 1; +#endif + + return (_err.severity () < sev_error); +} + + +void Transformer::determine_aspect_fwd_decls (ModelBuilder &jpm) { + // get all aspects from the join point model + ProjectModel::Selection all_aspects; + jpm.select (JPT_Aspect, all_aspects); + + // remember that these aspects should become friend of all classes + _aspect_fwd_decls = ""; + for (ProjectModel::Selection::iterator iter = all_aspects.begin (); + iter != all_aspects.end (); ++iter) { + ACM_Aspect &jpl = (ACM_Aspect&)**iter; + _aspect_fwd_decls += "class "; + _aspect_fwd_decls += jpl.get_name(); + _aspect_fwd_decls += ";\n"; + } +} + +void Transformer::determine_aspect_includes (const IncludeGraph &ig) { + // find all files that are included by aspect headers + if (_conf.iterate_aspects ()) { + // collect the names of aspect header files, + // generate a unit with include statements for these files, + PathIterator ah_iter (".*\\.ah$"); + while (_project.iterate (ah_iter)) + aspect_include_cluster (ah_iter.file (), ig); + } + else { + // Get the names from the configuration object (-a options) + for (int i = 0; i < _conf.aspect_headers (); i++) + aspect_include_cluster (_conf.aspect_header (i), ig); + } +} + +void Transformer::aspect_include_cluster (const char* ah_file, + const IncludeGraph &ig) { + + // find the corresponding unit object for the aspect header file name +#ifdef FRONTEND_PUMA + ACFileID fid = _project.unitManager ().get (ah_file, true); +// if (!fid) { +#else + ACFileID fid = _project.get_compiler_instance()->getFileManager().getFile(ah_file); +#endif + if (!fid.is_valid()) { + _err << sev_fatal << "Unit for \"" << ah_file << "\" not found or no file." + << endMessage; + return; + } + + // determine the aspect header cluster for this aspect header unit + set cluster_units; + determine_aspect_cluster (fid, ig, cluster_units); + + AspectIncludeCluster aic(fid); + aic.set_cluster(cluster_units); + _aspect_include_clusters.push_back(aic); +} + + +void Transformer::determine_aspect_cluster (ACFileID ah_unit, + const IncludeGraph &ig, set &cluster) { + + // if the ah file is already a cluster member, we return immediately + if (cluster.find (ah_unit) != cluster.end ()) + return; + + // otherwise the unit will be inserted + cluster.insert (ah_unit); + + // find all header files that are included by this aspect header + set inc_units; + ig.included_files (ah_unit, inc_units); + + // include all aspect headers that affect join points in these headers + // and also aspect headers that affect the aspect header itself + inc_units.insert (ah_unit); + AspectIncludes &ais = _code_weaver.aspect_includes (); +#ifdef FRONTEND_CLANG + clang::SourceManager &sm = + _project.get_compiler_instance()->getSourceManager(); +#endif + for (set::iterator i = inc_units.begin (); + i != inc_units.end (); ++i) { + ACFileID inc_unit = *i; + AspectIncludes::const_iterator aii = ais.find (inc_unit); + if (aii != ais.end ()) { + const set &aspect_refs = aii->second; + for (set::const_iterator ari = aspect_refs.begin (); + ari != aspect_refs.end (); ++ari) { + ACM_Aspect &jpl_aspect = ari->_aspect->loc (); +#ifdef FRONTEND_PUMA + Unit *aspect_unit = TI_Aspect::of (jpl_aspect)->unit (); +#else + clang::Decl *aspect_decl = TI_Aspect::of(jpl_aspect)->decl(); + const clang::FileEntry *aspect_unit = + sm.getFileEntryForID(sm.getFileID(aspect_decl->getLocation())); +#endif + // recursively analyze the cluster of this aspect header unit + determine_aspect_cluster (aspect_unit, ig, cluster); + } + } + } +} + +void Transformer::prepare_dynamic_weaving (ModelBuilder &jpm) { + +#ifdef FRONTEND_PUMA + // mark all operations that access introduced attributes + const list &access_infos = jpm.access_infos (); + for (list::const_iterator i = access_infos.begin (); + i != access_infos.end (); ++i) { + if (i->_info->isStatic () || i->_info->isAnonymous ()) + continue; + Unit *unit = (Unit*)i->_info->Tree ()->token ()->belonging_to (); + while (unit->isMacroExp ()) + unit = ((MacroUnit*)unit)->CallingUnit (); + if (IntroductionUnit::cast (unit)) { + ACToken tok_before (i->_tree->token ()); + const WeavePos &before = _code_weaver.weave_pos (tok_before, WeavePos::WP_BEFORE); + _code_weaver.insert (before, string ("/*** +access ") + + string (i->_info->QualName ()) + string (" ***/\n")); + ACToken tok_after (i->_tree->end_token ()); + const WeavePos &after = _code_weaver.weave_pos (tok_after, WeavePos::WP_AFTER); + _code_weaver.insert (after, string ("/*** -access ") + + string (i->_info->QualName ()) + string (" ***/\n")); + if (i->_tree->NodeName () == CT_MembPtrExpr::NodeId () || + i->_tree->NodeName () == CT_MembRefExpr::NodeId ()) { + CTree *op = i->_tree->Son (1); + ACToken tok_before (op->token ()); + const WeavePos &before = _code_weaver.weave_pos (tok_before, WeavePos::WP_BEFORE); + _code_weaver.insert (before, string ("/*** op ") + + string (i->_info->QualName ()) + string (" ***/\n")); + } + } + } + + // mark all classes that contain dynamically introduced attributes + ProjectModel::Selection classes; + jpm.select ((JoinPointType)(JPT_Class|JPT_Aspect), classes); + for (ProjectModel::Selection::iterator i = classes.begin (); + i != classes.end (); ++i) { + ACM_Class *cls = (ACM_Class*)*i; + if (!cls->get_intro_target ()) + continue; + bool mark_class = false; + const TI_Class *ti = TI_Class::of (*cls); + CClassInfo *ci = ti->class_info (); + for (unsigned i = 0; i < ci->Attributes (); i++) { + CAttributeInfo *attr = ci->Attribute (i); + if (attr->isStatic () || attr->isAnonymous ()) + continue; + Unit *unit = (Unit*)attr->Tree ()->token ()->belonging_to (); + IntroductionUnit *iunit = IntroductionUnit::cast (unit); + if (iunit) { + mark_class = true; + ACM_Name *jpl_aspect = (ACM_Name*)iunit->intro ()->get_parent (); + ACToken tok_before (attr->Tree ()->ObjDecl ()->token ()); + const WeavePos &before = _code_weaver.weave_pos (tok_before, WeavePos::WP_BEFORE); + _code_weaver.insert (before, string ("/*** +intro ") + + signature (*jpl_aspect) + string (" ***/\n")); + ACToken tok_after (attr->Tree ()->ObjDecl ()->end_token ()); + const WeavePos &after = _code_weaver.weave_pos (tok_after, WeavePos::WP_AFTER); + _code_weaver.insert (after, string ("/*** -intro ") + + signature (*jpl_aspect) + string (" ***/\n")); + } + } + if (mark_class) { + ACToken tok_before (((CT_ClassDef*)ci->Tree ())->ObjDecl ()->token ()); + const WeavePos &before = _code_weaver.weave_pos (tok_before, WeavePos::WP_BEFORE); + _code_weaver.insert (before, string ("/*** +class ") + + signature (*cls) + string (" ***/\n")); + + ACToken tok_after (((CT_ClassDef*)ci->Tree ())->Members ()->end_token ()); + const WeavePos &after = _code_weaver.weave_pos (tok_after, WeavePos::WP_BEFORE); + _code_weaver.insert (after, string ("/*** -class ") + + signature (*cls) + string (" ***/\n")); + } + } +#endif // FRONTEND_PUMA +} + + +void Transformer::update_intros_in_repo (ModelBuilder &jpm1) { + ProjectModel::Selection intros; + jpm1.select (JPT_Introduction, intros); + for (ProjectModel::Selection::iterator i = intros.begin (); + i != intros.end (); ++i) { + ACM_Introduction &intro = *(ACM_Introduction*)*i; + _repo.consider (intro); + } + ProjectModel::Selection classes; + jpm1.select ((JoinPointType)(JPT_Class|JPT_Aspect), classes); + for (ProjectModel::Selection::iterator i = classes.begin (); + i != classes.end (); ++i) { + ACM_Class &cls = *(ACM_Class*)*i; + // skip this class if it has no plan yet + if (!cls.has_plan ()) + continue; + // collect the intros into this class + set intros; // a 'set', because the same intro might add a base class and a member + typedef ACM_Container BContainer; + BContainer bintros = cls.get_plan()->get_base_intros(); + for (BContainer::iterator i = bintros.begin (); i != bintros.end (); ++i) + intros.insert ((*i)->get_intro()); + typedef ACM_Container MContainer; + MContainer mintros = cls.get_plan()->get_member_intros(); + for (MContainer::iterator i = mintros.begin (); i != mintros.end (); ++i) + intros.insert ((*i)->get_intro()); + // now update the repository with the intro information + for (set::iterator intro_iter = intros.begin (); + intro_iter != intros.end (); ++intro_iter) { + _repo.update (**intro_iter, cls); + } + } +} + + +void Transformer::cleanup (ModelBuilder &jpm) { + + // delete all pointcut definitions that are left + ProjectModel::Selection pointcuts; + jpm.select (JPT_Pointcut, pointcuts); + for (ProjectModel::Selection::iterator i = pointcuts.begin (); + i != pointcuts.end (); ++i) { + ACM_Pointcut &pct = *(ACM_Pointcut*)*i; + // delete all non-anonymous pointcut definitions +#ifdef FRONTEND_PUMA + if (TI_Pointcut::of (pct)->func_info()) + _code_weaver.kill (((CT_InitDeclarator*)TI_Pointcut::of (pct)->tree())->ObjDecl()); +#else + if (clang::Decl *decl = TI_Pointcut::of (pct)->decl()) + _code_weaver.kill( + _code_weaver.weave_pos(decl->getLocStart(), WeavePos::WP_BEFORE), + _code_weaver.weave_pos(decl->getLocEnd().getLocWithOffset(1), + WeavePos::WP_AFTER)); +#endif + } +} + + +void Transformer::insert_bypass_class (ModelBuilder &jpm) { + _code_weaver.bypass_info_clear(); + + // Iterate over classes and structs, what about unions? + ProjectModel::Selection all_classes; + jpm.select ((JoinPointType)(JPT_Class|JPT_Aspect), all_classes); + for (ProjectModel::Selection::iterator i = all_classes.begin (); + i != all_classes.end (); ++i) { + ACM_Class *cls = (ACM_Class*)*i; + + // handle all classes that are not on the blacklist + if (!_code_weaver.bypass_in_blacklist(cls)) { + _code_weaver.bypass_insert (cls); + } + } +} + + +void Transformer::join_points (CTranslationUnit &tunit, + ModelBuilder &jpm, Plan &plan) { + +#ifdef PROFILING + static Profiler::Data data (__PRETTY_FUNCTION__, NULL); + Profiler::ClockTicks start = Profiler::rdtsc (); +#endif + _vm++; + + _vm << "Advicecode manipulation" << endvm; + // Iterate through advice + ProjectModel::Selection advice_codes; + jpm.select (JPT_AdviceCode, advice_codes); + for (ProjectModel::Selection::iterator i = advice_codes.begin (); + i != advice_codes.end (); ++i) { + ACM_AdviceCode &code = *(ACM_AdviceCode*)*i; + TI_AdviceCode &ti = *TI_AdviceCode::of (code); + // setup ThisJoinPoint object of this advice code +#ifdef FRONTEND_PUMA + _code_weaver.setup_tjp(ti.this_join_point (), ti.function ()); +#else + _code_weaver.setup_tjp(ti.this_join_point (), ti.decl ()); +#endif + } + + _vm << "Collecting Advice" << endvm; + // Iterate through advice + _vm++; + + PointCutContext context (jpm, _conf); + + // Create a data structure for collecting advice per join point type + typedef list AdviceInfoList; + typedef JoinPointType JPT; + typedef map TypeAdviceMap; + TypeAdviceMap advice_map; + + Plan::AspectContainer &aspects = plan.aspect_infos (); + for (Plan::AspectContainer::iterator i = aspects.begin (); + i != aspects.end (); ++i) { + AspectInfo &aspect_info = (AspectInfo&)*i; + ACM_Aspect &jpl_aspect = aspect_info.loc (); + context.concrete_aspect (jpl_aspect); + + // setup thisJoinPoint for aspectOf function, if there is one +#ifdef FRONTEND_PUMA + CFunctionInfo *aspect_of_func = TI_Aspect::of (jpl_aspect)->aspectof(); +#else + clang::FunctionDecl *aspect_of_func = TI_Aspect::of (jpl_aspect)->aspectof(); +#endif + if (aspect_of_func) { + _vm << "Setting up thisJoinPoint for aspectof" << endvm; + _code_weaver.setup_tjp(aspect_info.aspectof_this_join_point (), + aspect_of_func); + } + + // handle the advice for the current aspect + list &advices = aspect_info.advice_infos (); + for (list::const_iterator i = advices.begin (); + i != advices.end (); ++i) { + AdviceInfo *advice_info = *i; + ACM_AdviceCode *code = &advice_info->code (); + +#ifdef FRONTEND_PUMA + CFunctionInfo *adfunc = TI_AdviceCode::of (*code)->function (); + _vm << signature (jpl_aspect) << ": " << adfunc->Name () << endvm; +#else + //_vm << signature (jpl_aspect) << ": " << adfunc->Name () << endvm; // TODO: clang +#endif + _vm++; + + // let the pointcut evaluator create the pointcut expression object + _vm << "Create pointcut expression tree" << endvm; + advice_info->pointcut_expr() = code->get_pointcut ()->get_parsed_expr(); + PointCutExpr *pce = (PointCutExpr*)advice_info->pointcut_expr().get (); + context.pct_func (code->get_pointcut ()); + if (pce) { + ArgSet new_arg_bindings; + typedef ACM_Container Container; + Container &arguments = context.pct_func()->get_args(); + for (Container::iterator i = arguments.begin (); i != arguments.end (); ++i) + new_arg_bindings.append (*i); + context.arg_bindings ().push (&new_arg_bindings); + pce->semantics(_err, context, _conf.warn_compatibility()); + context.arg_bindings ().pop (); + + // set the pointcut type before destroy the expression(!) + advice_info->pointcut().type (pce->type() == PCE_CODE ? PointCut::PCT_CODE : PointCut::PCT_CLASS); + + // remember the advice for each joinpoint type that might match + int mask = 1; + while (mask) { + if (mask & JPT_Code) { + pair result = + advice_map.insert (TypeAdviceMap::value_type ((TypeAdviceMap::key_type)mask, AdviceInfoList())); + result.first->second.push_back (advice_info); + } + mask <<= 1; + } + } + + // copy the cflow trigger pointcut from the expressions to the pointcut + for (set::const_iterator iter = context.cflows ().begin (); + iter != context.cflows ().end (); ++iter) { + advice_info->pointcut().cflow_triggers(((PCE_CFlow*)*iter)->arg_pointcut ()); + } + _vm--; + } + context.cflow_reset (); + } + _vm--; + + // now iterate over all join points and check whether they match the + // pointcut expressions + _vm << "Matching joinpoints" << endvm; + _vm++; + + for (TypeAdviceMap::iterator mi = advice_map.begin (); mi != advice_map.end (); + ++mi) { + JPT jp_type = mi->first; + if( ! _conf.data_joinpoints() && ( jp_type & ( JPT_Get | JPT_Set | JPT_Ref | JPT_GetRef | JPT_SetRef ) ) ) + continue; // skip non enabled (cmdline) joinpoints + + AdviceInfoList &advice_info_list = mi->second; + ProjectModel::Selection all; + jpm.select (jp_type, all); + for (ProjectModel::Selection::iterator iter = all.begin (); + iter != all.end (); ++iter) { + assert( static_cast( *iter )->type_val() & JPT_Code ); + ACM_Code &jpl = (ACM_Code&)**iter; + if( ! _conf.builtin_operators() && ( jpl.type_val() == JPT_Builtin ) ) // suppress joinpoints of builtin_operators + continue; + bool has_advice = false; + + for (AdviceInfoList::iterator li = advice_info_list.begin (); + li != advice_info_list.end (); ++li) { + AdviceInfo *advice_info = *li; + context.pseudo_true (false); + + // Current pointcut function: + ACM_Pointcut* pointcut_func = advice_info->code().get_pointcut(); + context.pct_func(pointcut_func); + + // now match + Binding binding; + Condition condition; + PointCutExpr *expr = (PointCutExpr*)advice_info->pointcut_expr().get(); + + // Does the pointcut expression match the join point? + bool match_result = expr->match (jpl, context, binding, condition); + + // Output eventually created warnings: + for(vector>::const_iterator sev_msg_pair_iter + = context.messages().begin(); + sev_msg_pair_iter != context.messages().end(); ++sev_msg_pair_iter + ) { + _err << sev_msg_pair_iter->first + << TI_Pointcut::of(*pointcut_func)->get_location() + << sev_msg_pair_iter->second.c_str() << endMessage; + } + context.messages().clear(); + + // Handle match result: + if (match_result) { + JoinPoint &jp = *new JoinPoint (&jpl, condition); + advice_info->pointcut().append (jp); + + // consider this joinpoint in the big plan + plan.consider( &jpl, jp.condition(), advice_info ); + has_advice = true; + + // remember units for inclusion of aspect headers + _code_weaver.add_aspect_include (jp.location (), advice_info->aspect_info(), + AspectRef::AR_ADVICE); + + // if the advice uses a joinpoint ID, make sure that one is allocated + // for the matched joinpoint + if (TI_AdviceCode::of (advice_info->code())->this_join_point().id() && + !jpl.has_jpid()) + jpl.set_jpid(jpm.alloc_jpid()); + + if (jpl.type_val () == JPT_Call && !jpl.get_parent()) // TODO: pseudo + continue; + + // check if the context variable binding is the same for all + // non-pseudo join points + if (advice_info->binding () != binding) { + if (!advice_info->binding ()._used) { + advice_info->binding () = binding; + } + else { + _err << sev_error + << TI_Pointcut::of(*pointcut_func)->get_location() + << "incompatible argument bindings in pointcut expression" + << endMessage; + // remove this erroneous advice from all lists + for (TypeAdviceMap::iterator i = advice_map.begin (); i != advice_map.end (); + ++i) { + i->second.remove (advice_info); + } + break; + } + } + } + } + +#ifdef FRONTEND_CLANG + // only required for features of the Clang variant + if( has_advice ) { + // do some preplanning that might influence other joinpoints + _code_weaver.preplanTransform( jpl ); + + // remember we have a plan ( and thus weave at this jpl ) + TI_Code::of( jpl )->remember_planned(); + + // for implicit joinpoints: make sure the parent is considered so we can weave calling code there + ACM_Code *node = &jpl; + while( node && is_implicit( *node ) ) { + assert( static_cast( node->get_parent() )->type_val() & JPT_Code ); + node = static_cast( node->get_parent() ); + plan.consider( node ); + TI_Code::of( *node )->remember_planned(); + TI_Code::of( *node )->remember_implicit(); + } + + // if we weave for a builtin copy constructor, we replace array types in the class (see CodeWeaver::gen_special_member_function) + // give the class a chance to know that + if( jpl.type_val() == JPT_Construction ) { + assert( static_cast( jpl.get_parent() )->type_val() == JPT_Function ); + ACM_Function *func = static_cast( jpl.get_parent() ); + assert( static_cast( func->get_parent() )->type_val() & ( JPT_Class | JPT_Aspect ) ); + ACM_Class *cls = static_cast( func->get_parent() ); + + if( func->get_builtin() && get_arg_count( *func ) == 1 ) // parallel to check in CodeWeaver::cons_join_point + TI_Class::of( *cls )->remember_builtin_copyconstructor_advice(); + } + } +#endif + } + } + + // again iterate over all aspects + for (Plan::AspectContainer::iterator i = aspects.begin (); + i != aspects.end (); ++i) { + AspectInfo &aspect_info = (AspectInfo&)*i; + ACM_Aspect &jpl_aspect = aspect_info.loc (); + context.concrete_aspect (jpl_aspect); + int index = 0; // CFlow index (each CFlow has a unique index per aspect) + + // and now over all advice + list advices = aspect_info.advice_infos (); + for (list::const_iterator i = advices.begin (); + i != advices.end (); ++i) { + AdviceInfo *advice_info = *i; + PointCut &pc = advice_info->pointcut(); + // consider the cflow trigger needed for this advice in the plan + const list &trigger_pcs = pc.cflow_triggers(); + for (list::const_iterator iter = trigger_pcs.begin (); + iter != trigger_pcs.end (); ++iter, ++index) { + PointCut *trigger_pc = *iter; + // Consider a cflow trigger for every joinpoint is pointcut + for (PointCut::iterator iter = trigger_pc->begin (); + iter != trigger_pc->end (); ++iter) { + const JoinPoint &jp = *iter; + + // consider this joinpoint in the big plan + plan.consider ((ACM_Code*)jp.location (), CFlow (advice_info, index)); + + // remember units for inclusion of aspect headers + _code_weaver.add_aspect_include (jp.location (), aspect_info, + AspectRef::AR_DECL); + } + } + + // update the project repository + if (getenv ("ACOLDREPO")) + _repo.update (*advice_info, pc); + } + + _code_weaver.insert_invocation_functions (&jpl_aspect, + aspect_info.ifct_defs (_code_weaver.problems ())); + } + _vm--; + + _vm << "Aspect ordering ..." << endvm; + plan.order_code_joinpoints (); + + // now do the final checks on the accumulated plan +// _vm << "Final checks before weaving code join points" << endvm; +// plan.check_code_joinpoints (); + + // Don't weave if there were errors in the planning phase + if (_err.severity () >= sev_error) + return; + + bool use_old_repo = (_conf.repository() && getenv ("ACOLDREPO") != NULL); + const char *repo_file = _conf.repository(); + if (!use_old_repo && repo_file) { +#ifdef _MSC_VER + if (!_access (repo_file, 04)) { +#else + if (!access (repo_file, R_OK)) { +#endif // _MSC_VER + + _vm << "Updating project repository '" << repo_file << "'" << endvm; + int fd = SysCall::open_excl (repo_file, O_RDWR, &_err); + ProjectModel project_model; + XmlModelReader reader; + if (!reader.read (project_model, repo_file, fd)) { + _err << sev_error << "project repository '" << repo_file << "' cannot be opened" + " or is invalid" << endMessage; + return; + } + if (project_model.get_version () != ac_version ()) + _err << sev_warning << "project file version '" << project_model.get_version().c_str () + << "' differs from ac++ version" << endMessage; + + // merge jpm and project_mode here + project_model.merge (jpm); + + // make project model file empty + lseek (fd, 0, SEEK_SET); + if (ftruncate (fd, 0) != 0) + perror ("truncate"); + + // save the merged model + XmlModelWriter writer; + if (!writer.write (project_model, repo_file, fd)) { + _err << sev_error << "saving merged project file '" << repo_file << + "'failed" << endMessage; + return; + } + SysCall::close_excl (fd, &_err); + } + else { + _vm << "Creating project repository '" << repo_file << "'" << endvm; + int fd = SysCall::create_excl (repo_file, 0600, &_err); + XmlModelWriter writer; + if (!writer.write (jpm, repo_file, fd)) { + _err << sev_error << "saving new project file '" << repo_file << + "'failed" << endMessage; + return; + } + SysCall::close_excl (fd, &_err); + } + } + + _vm << "Type Check Functions" << endvm; + _vm++; + const TypeCheckSet &checks_false = plan.type_checks_false (); + for (TypeCheckSet::const_iterator iter = checks_false.begin (); + iter != checks_false.end (); ++iter) { + _vm << "check for " << iter->second << " in " + << signature(*iter->first) << " is false" << endvm; + _code_weaver.type_check (iter->first, iter->second, false); + } + const TypeCheckSet &checks_true = plan.type_checks_true (); + for (TypeCheckSet::const_iterator iter = checks_true.begin (); + iter != checks_true.end (); ++iter) { + _vm << "check for " << iter->second << " in " + << signature (*iter->first) << " is true" << endvm; + _code_weaver.type_check (iter->first, iter->second, true); + } + _vm--; + + _vm << "Access Join Points" << endvm; + _vm++; + for (int i = 0; i < plan.access_jp_plans (); i++) { + ACM_Access &jp_loc = plan.access_jp_loc (i); + + if( is_implicit( jp_loc ) ) // check for implicit joinpoints + continue; // skip here, they are handled internally by the weaver + + _vm << jp_loc.type_str() << ": " << signature (jp_loc) << endvm; + if( jp_loc.type_val() == JPT_Builtin ) { // print implicit too + ACM_Builtin &jp_builtin = static_cast( jp_loc ); + typedef const ACM_Container SubList; + SubList &implicit = jp_builtin.get_implicit_access(); + + _vm++; + for( SubList::const_iterator it = implicit.begin(); it != implicit.end(); it++ ) { // TODO iterate over all nesting level (not yet neccessary as no deep nesting) + if( (*it)->has_plan() ) // only print jpls for which we weave + _vm << (*it)->type_str() << ": " << signature( **it ) << endvm; + } + _vm--; + } + + // handle access joinpoint itself + _code_weaver.access_join_point (&jp_loc); + } + _vm--; + + _vm << "Execution Join Points" << endvm; + _vm++; + for (int i = 0; i < plan.exec_jp_plans (); i++) { + ACM_Execution &jp_loc = plan.exec_jp_loc (i); + _vm << signature (jp_loc) << endvm; + + // handle exec joinpoint itself + _code_weaver.exec_join_point (&jp_loc); + } + _vm--; + + _vm << "Construction Join Points" << endvm; + _vm++; + for (int i = 0; i < plan.cons_jp_plans (); i++) { + ACM_Construction &jp_loc = plan.cons_jp_loc (i); + _vm << signature (jp_loc) << endvm; + + // handle construction joinpoint itself + _code_weaver.cons_join_point (&jp_loc); + } + _vm--; + + _vm << "Destruction Join Points" << endvm; + _vm++; + for (int i = 0; i < plan.dest_jp_plans (); i++) { + ACM_Destruction &jp_loc = plan.dest_jp_loc (i); + _vm << signature (jp_loc) << endvm; + + // handle destruction joinpoint itself + _code_weaver.dest_join_point (&jp_loc); + } + _vm--; + + _vm--; + + _vm << "Aspect Includes ..." << endvm; + _code_weaver.insert_aspect_includes (); + +#ifdef PROFILING + Profiler::ClockTicks end = Profiler::rdtsc (); + data._time += Profiler::duration (start, end); + data._calls = 1; +#endif +} + +// add references to the introduced elements to the plan +void Transformer::link_members (ACM_Class &jpl) { + if (!jpl.has_plan ()) + return; + + ACM_ClassPlan *plan = jpl.get_plan (); + + typedef ACM_Container Container; + Container &children = jpl.get_children(); + typedef ACM_Container Container2; + Container2 &member_intros = plan->get_member_intros(); +#ifdef FRONTEND_CLANG + clang::SourceManager &sm = _project.get_compiler_instance()->getSourceManager(); +#endif + for (Container::iterator i = children.begin (); i != children.end (); ++i) { + ACM_Any *any = *i; + if (any->type_val() == JPT_Class) { + ACM_Class *cls = (ACM_Class*)any; +#ifdef FRONTEND_PUMA + Unit *u = (Unit*)TI_Class::of(*cls)->obj_info()->Tree()->token()->belonging_to(); +#else + clang::FileID fid = sm.getFileID(TI_Class::of(*cls)->decl()->getLocation()); + const llvm::MemoryBuffer *u = sm.getBuffer(fid); +#endif + if (IntroductionUnit::cast(u)) { + ACM_Introduction *intro = IntroductionUnit::cast(u)->intro(); + for (Container2::iterator mi = member_intros.begin (); + mi != member_intros.end(); ++mi) + if ((*mi)->get_intro() == intro) + (*mi)->get_members().insert(cls); + } + } + else if (any->type_val() == JPT_Function) { + ACM_Function *func = (ACM_Function*)any; + if (func->get_builtin()) + continue; +#ifdef FRONTEND_PUMA + Unit *u = (Unit*)TI_Function::of(*func)->obj_info()->Tree()->token()->belonging_to(); +#else + clang::FileID fid = sm.getFileID(TI_Function::of(*func)->decl()->getLocation()); + const llvm::MemoryBuffer *u = sm.getBuffer(fid); +#endif + if (IntroductionUnit::cast(u)) { + ACM_Introduction *intro = IntroductionUnit::cast(u)->intro(); + for (Container2::iterator mi = member_intros.begin (); + mi != member_intros.end(); ++mi) + if ((*mi)->get_intro() == intro) + (*mi)->get_members().insert(func); + } + } + } +} + +// add references to the introduced elements to the plan +void Transformer::link_bases (ACM_Class &jpl) { + if (!jpl.has_plan ()) + return; + + ACM_ClassPlan *plan = jpl.get_plan (); +#ifdef FRONTEND_PUMA + CClassInfo *ci = TI_Class::of(jpl)->class_info(); +#else + clang::CXXRecordDecl *ci = llvm::cast(TI_Class::of(jpl)->decl()); +#endif + + typedef ACM_Container Container; + Container &bases = jpl.get_bases(); + typedef ACM_Container Container2; + Container2 &base_intros = plan->get_base_intros(); +#ifdef FRONTEND_CLANG + clang::SourceManager &sm = _project.get_compiler_instance()->getSourceManager(); +#endif + for (Container::iterator i = bases.begin (); i != bases.end (); ++i) { + ACM_Class *cls = *i; + // find the base class info in Puma's semantic data structure +#ifdef FRONTEND_PUMA + for (unsigned b = 0; b < ci->BaseClasses(); b++) { + if (ci->BaseClass(b)->Class() != TI_Class::of (*cls)->class_info()) + continue; + Unit *u = (Unit*)ci->BaseClass(b)->Tree()->token()->belonging_to(); +#else + for (clang::CXXRecordDecl::base_class_iterator bi = ci->bases_begin(), + be = ci->bases_end(); + bi != be; ++bi) { + if (bi->getType()->getAsCXXRecordDecl() != TI_Class::of (*cls)->decl()) + continue; + clang::FileID fid = sm.getFileID(bi->getType()->getAsCXXRecordDecl()->getLocation()); + const llvm::MemoryBuffer *u = sm.getBuffer(fid); +#endif + if (IntroductionUnit::cast(u)) { + ACM_Introduction *intro = IntroductionUnit::cast(u)->intro(); + for (Container2::iterator bi = base_intros.begin (); + bi != base_intros.end(); ++bi) { + if ((*bi)->get_intro () == intro) { + (*bi)->get_bases().insert(cls); + } + } + } + } + } +} diff --git a/AspectC++/Transformer.h b/AspectC++/Transformer.h new file mode 100644 index 0000000..ca8be8f --- /dev/null +++ b/AspectC++/Transformer.h @@ -0,0 +1,114 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __Transformer_h__ +#define __Transformer_h__ + +#include "CodeWeaver.h" +#ifdef FRONTEND_PUMA +#include "Puma/CCParser.h" +#include "Puma/CCSemVisitor.h" +#else +#include "clang/Basic/SourceManager.h" +#endif +#include "ACErrorStream.h" +#include "ACToken.h" +#include "AspectIncludeCluster.h" + + +#include +using std::list; + +namespace Puma { + class VerboseMgr; + class CTranslationUnit; +} // namespace Puma + +class PointCut; +class Repository; +class Plan; +class ModelBuilder; +class ACConfig; +class ACProject; +class IncludeGraph; + +class Transformer + { + Puma::VerboseMgr &_vm; + ACErrorStream &_err; + ACProject &_project; + Repository &_repo; + CodeWeaver _code_weaver; +#ifdef FRONTEND_PUMA + Puma::CCParser _parser; + Puma::CCSemVisitor _sem_visitor; +#else + clang::SourceManager *_phase1_sm; +#endif + ACConfig &_conf; + list _aspect_include_clusters; + string _aspect_includes; + string _aspect_fwd_decls; + set _touched_files; + set _virtual_files; + + bool phase1 (Puma::Unit *&unit, const string &tunit_name, + ModelBuilder &, IncludeGraph&); + bool phase2 (Puma::Unit *unit, const string &tunit_name, + ModelBuilder &, IncludeGraph&); + void include_aspect (const char *name); + void determine_aspect_includes (const IncludeGraph &ig); + void determine_aspect_fwd_decls (ModelBuilder &); + void aspect_include_cluster (const char *ah_file, const IncludeGraph &ig); + void determine_aspect_cluster (ACFileID ah_unit, + const IncludeGraph &ig, set &cluster); + void prepare_dynamic_weaving (ModelBuilder &jpm); + void update_intros_in_repo (ModelBuilder &); + void cleanup (ModelBuilder &jpm); + void insert_bypass_class (ModelBuilder &); + void join_points (Puma::CTranslationUnit &, ModelBuilder &, Plan &); + + // add references to the introduced elements to the plan + void link_members (ACM_Class &jpl); + // add references to the introduced base classes to the plan + void link_bases (ACM_Class &jpl); +#ifdef FRONTEND_CLANG + void reinitializeSourceManager(clang::CompilerInstance *ci, + CodeWeaver &cwb, const char *name); +#else + void update_touched_files (); +#endif + + public: + + Transformer (Puma::VerboseMgr &vm, ACErrorStream &e, ACProject &p, Repository &r, + ACConfig &c, LineDirectiveMgr &ldm): + _vm (vm), _err (e), _project (p), _repo (r), + _code_weaver (p, ldm, c), +#ifdef FRONTEND_PUMA + _sem_visitor (e), +#endif + _conf (c) {} + ACFileID work (const string &tunit_name); + list aspect_include_clusters () const { return _aspect_include_clusters; } + const string &aspect_includes () const { return _aspect_includes; } + const string &aspect_fwd_decls () const { return _aspect_fwd_decls; } + const set &touched_files () const { return _touched_files; } + }; + +#endif // __Transformer_h__ diff --git a/AspectC++/Weaver.cc b/AspectC++/Weaver.cc new file mode 100644 index 0000000..9e4921c --- /dev/null +++ b/AspectC++/Weaver.cc @@ -0,0 +1,762 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 + +// C++ includes +#include +#include +#include +using namespace std; +#include +#include +#include +#include +#ifdef _MSC_VER +#include +#else +#include // for access()! +#endif // _MSC_VER + +// AspectC++ includes +#include "Weaver.h" +#include "ACConfig.h" +#include "ACFileID.h" +#include "Transformer.h" +#ifdef FRONTEND_PUMA +#include "ACUnit.h" +#endif +#include "IncludeExpander.h" +#include "ClangIncludeExpander.h" +#include "Repository.h" +#include "Naming.h" +#include "NamespaceAC.h" +#include "ACModel/XmlModelReader.h" +#include "PointCutExprParser.h" +#include "PointCutSearcher.h" +#include "PointCutContext.h" + +// PUMA includes +#include "Puma/VerboseMgr.h" +#include "Puma/SysCall.h" +#ifdef FRONTEND_PUMA +#include "Puma/CProject.h" +#include "Puma/ErrorStream.h" +#include "Puma/FileUnit.h" +#include "Puma/CScanner.h" +#include "Puma/PreParser.h" +#include "Puma/CPrintVisitor.h" +#endif + +// Some macro-like functions that define the application name and version +#include "version.h" + +using namespace Puma; + +Weaver::Weaver (ACProject& project, ACConfig &conf) : + _project (project), _conf (conf), + _line_mgr (err (), _conf) + { + } + + +#ifdef FRONTEND_CLANG +// helper function for checking whether the current line is a #line directive +static bool is_line_dir (const char *start, const char *eof) { + const char *i = start; + // skip whitespace at the beginning of the line + while (isspace (*i) && i < eof) + i++; + if (!(i < eof && *i == '#')) + return false; + // skip whitespace again + while (isspace (*i) && i < eof) + i++; + if (isdigit(*i) || (strncmp(i+1, "line ", 5) == 0)) + return true; + return false; +} + +// Token line number handling works different in the clang configuration. If #line directives +// are not generated (as in the Puma configuration), the line numbers in the project model and +// the joinpoint-API are wrong, because Phase 1 transformations will affect the loctions. +// To avoid this effect, the --no_line option has to be implemented at the end of all +// transformations steps (here) by removing all #line directives from the code instead of +// not generating the in the first place. +string update_line_directives_clang (llvm::StringRef buf, const char *filename, LineDirectiveMgr &line_mgr) { + std::ostringstream os; + unsigned lineno = 1; + bool start_of_line = true; + for (const char *i = buf.begin(), *e = buf.end(); i < e; ++i) { + // check for \s*#\s*(line|[0-9]) + if (start_of_line && is_line_dir (i, e)) { + bool skip_line = false; + if (line_mgr.noline ()) { + skip_line = true; + } + else { + const char *p = strchr(i, '#'); // note: 'i' remains were it was (beginning of line + if (strncmp(p+1, "line ", 5) == 0) { + p = i + 6; + // Skip over the line number. + while (isspace(*p) || isdigit(*p)) + ++p; + + // Replace " shall be removed from output + if (strncmp (p, "\"\"", 12) == 0) + skip_line = true; + else if (strncmp (p, "\"= sev_error) + return; + + if (!_conf.expr().empty()) { + match_expr_in_repo (vm); + return; + } + + bool header_changed = false; + if (_conf.iterate ()) { + vm << "Simple Dependency Check" << endvm; + PathIterator dep_iter (".*\\.a?h$"); + vm++; + while (_project.iterate (dep_iter)) { + + if (_project.isNewer (dep_iter.file ())) { + header_changed = true; + vm << "new or modified: " << dep_iter.file() << endvm; + } + } + vm--; + } + + // set of manipulated (and saved) units + set h_units; + set cc_units; + string aspect_includes; + string aspect_fwd_decls; + + if (!_conf.iterate () && !_conf.ifiles () && _conf.file_in ()) { + +#ifdef FRONTEND_CLANG + _project.create_compiler_instance (_conf); +#endif + + Transformer transformer (vm, err (), _project, repo, _conf, _line_mgr); + + // Transform a single translation unit + ACFileID fid = translate (vm, _conf.file_in (), transformer); + + // remember this unit + if (fid.is_valid()) + cc_units.insert (fid); + + // remember the aspect includes and forward declarations +// aspect_includes = transformer.aspect_includes (); + _aspect_include_clusters = transformer.aspect_include_clusters(); + aspect_fwd_decls = transformer.aspect_fwd_decls (); + + // break in case of errors + if (err ().severity () >= sev_error) + return; + } + else if (_conf.iterate ()) { + + // Transform all translation units in the project directory tree + stringstream extpat; + extpat << ".*\\." << _conf.extension () << "$"; + + bool first = true; + PathIterator iter (extpat.str ().data ()); + while (_project.iterate (iter)) { + if (!(_project.isNewer (iter.file ()) || header_changed)) { + continue; + } + +#ifdef FRONTEND_CLANG + _project.create_compiler_instance (_conf); +#endif + // it seems that creating the transformer for every file is essential + // to avoid very strange parse errors! + Transformer transformer (vm, err (), _project, repo, _conf, _line_mgr); + ACFileID fid = translate (vm, iter.file (), transformer); + + // remember that we need this file + if (fid.is_valid()) + cc_units.insert (fid); + + // remember the aspect units for inclusion and their forward declarations + if (first) { + // aspect_includes = transformer.aspect_includes (); + _aspect_include_clusters = transformer.aspect_include_clusters(); + aspect_fwd_decls = transformer.aspect_fwd_decls (); + first = false; + } + +#ifdef FRONTEND_CLANG + clang::SourceManager &SM = _project.get_compiler_instance ()->getSourceManager(); + for (clang::SourceManager::fileinfo_iterator fi = SM.fileinfo_begin(), + fe = SM.fileinfo_end(); + fi != fe; ++fi) { + const clang::FileEntry *file_entry = fi->first; + if (cc_units.find (ACFileID (file_entry)) == cc_units.end ()) { + SM.disableFileContentsOverride (file_entry); + _project.close (file_entry); + } + } +#else + // discard changes in header files + UnitManager::UMap &umap = _project.unitManager ().getTable (); + for (UnitManager::UMapIter iter = umap.begin (); + iter != umap.end (); ++iter) { + Unit *curr = (*iter).second; + if (cc_units.find (curr) == cc_units.end ()) + _project.close (curr->name (), true, false); + } + _project.unitManager ().discardNonames (); +#endif + + // break in case of errors + if (err ().severity () >= sev_error) + return; + } + } + + if (_conf.ifiles () || header_changed) { + vm << "Handling include files" << endvm; + vm++; + +#ifdef FRONTEND_CLANG + _project.create_compiler_instance (_conf); +#endif + + stringstream str; + str << "// This file is generated by AspectC++ \n\n"; + PathIterator h_iter (".*\\.h$"); + str << "#ifndef __ac_have_predefined_includes__\n" + "/*** begin of includes ***/" << endl; + while (_project.iterate (h_iter)) { + Filename incname = _project.getRelInclString (_conf.file_in (), h_iter.file ()); + str << "#include \"" << incname << "\"" << endl; + } + str << "/*** end of includes ***/\n#endif" << endl; + + ACFileID vfid = _project.addVirtualFile(_conf.file_in (), str.str ()); + + Transformer transformer (vm, err (), _project, repo, _conf, _line_mgr); + + translate (vm, _conf.file_in (), transformer); + + // remember the aspect units for inclusion and forward declarations + // aspect_includes = transformer.aspect_includes (); + _aspect_include_clusters = transformer.aspect_include_clusters(); + aspect_fwd_decls = transformer.aspect_fwd_decls (); + + // add header files to the list of manipulated units + h_units.clear (); + for (set::iterator tf_iter = transformer.touched_files ().begin (); + tf_iter != transformer.touched_files ().end (); ++tf_iter) { + if (ACFileID(*tf_iter) != vfid && + _project.isBelow ((*tf_iter).name ().c_str ()) && + cc_units.find (ACFileID (*tf_iter)) == cc_units.end ()) + h_units.insert (*tf_iter); + } + + // discard the generated translation unit + _project.removeVirtualFile(vfid); + + vm--; + } + + // break in case of errors + if (err ().severity () >= sev_error) + return; + +#ifdef FRONTEND_CLANG + // this make sure all closed file will no longer be seen + _project.create_compiler_instance (_conf); +#endif + + vm << "Inserting unit pro- and epilogues" << endvm; + insert_aspect_includes (vm, cc_units, h_units, aspect_includes, aspect_fwd_decls); + + vm << "Updating #line directives of generated code fragments" << endvm; + update_line_directives (cc_units, h_units); + +#ifdef FRONTEND_CLANG + // this make sure all closed file will no longer be seen + _project.create_compiler_instance (_conf); +#endif + + if (_conf.nosave ()) { + vm << "Don't save" << endvm; + } + else { + vm << "Saving" << endvm; + vm++; + + if (_project.numPaths () > 0 && _project.dest (0L)) { + vm << "Project tree" << endvm; + +#if 0 + // discard the generated cc file if only headers should be produced + if ((_conf.ifiles ())) + _project.close (_conf.file_in (), true); +#endif // 0 + + _project.save (); + } + + if (_conf.file_out ()) { + + // expand project includes + vm << "Expanding project includes" << endvm; +#ifdef FRONTEND_PUMA + IncludeExpander ie (err (), _project, _line_mgr); + ie.expand (_conf.file_in ()); +#else + ClangIncludeExpander cie (err (), _project, _line_mgr); + std::ostringstream buf; + cie.expand(buf); +#endif + + // update generated #line " directives for debuggers + vm << "Fixing #line directives" << endvm; +#ifdef FRONTEND_PUMA + update_line_directives (&(ie.unit ()), _conf.file_out ()); +#else + string code = update_line_directives_clang (buf.str(), _conf.file_out (), _line_mgr); +#endif + + // now save + vm << "Path \"" << _conf.file_out () << "\"" << endvm; + ofstream out (_conf.file_out (), ios::out|ios::binary); + if (out.is_open ()) { +#ifdef FRONTEND_PUMA + out << ie.unit (); +#else + out << code; +#endif + } else + err () << sev_error << "can't open file \"" + << _conf.file_out () << "\"" << endMessage; + } + + if (use_old_repo && repo.initialized ()) { +// vm << "Saving project repository" << endvm; + repo.save (err ()); + } + + vm--; + } + vm << "Done" << endvm; + } + + +// update #line directives in all project files +void Weaver::update_line_directives (set &cc_units, + set &h_units) { + for (set::iterator iter = cc_units.begin (); + iter != cc_units.end (); ++iter) { + ostringstream out; + if (_project.getDestinationPath ((*iter).name ().c_str (), out)) { + update_line_directives (*iter, out.str ().c_str ()); + } + } + for (set::iterator iter = h_units.begin (); + iter != h_units.end (); ++iter) { + ostringstream out; + if (_project.getDestinationPath ((*iter).name ().c_str (), out)) { + update_line_directives (*iter, out.str ().c_str ()); + } + } +} + +// insert a pro- and epilogue into all saved units to make sure that in +// any case the relevant aspect headers will be defined +void Weaver::insert_aspect_includes (VerboseMgr &vm, set &cc_units, + set &h_units, const string &aspect_includes, const string &aspect_fwd_decls) { + vm++; + for (set::iterator iter = cc_units.begin (); + iter != cc_units.end (); ++iter) { + vm << "Manipulating translation unit file " << (*iter).name () << endvm; +// insert_aspect_includes (vm, *iter, false, aspect_includes, aspect_fwd_decls); + insert_aspect_includes (vm, *iter, false, gen_aspect_includes(*iter), aspect_fwd_decls); + } + for (set::iterator iter = h_units.begin (); + iter != h_units.end (); ++iter) { + vm << "Manipulating header file " << (*iter).name () << endvm; +// insert_aspect_includes (vm, *iter, true, aspect_includes, aspect_fwd_decls); + insert_aspect_includes (vm, *iter, true, gen_aspect_includes(*iter), aspect_fwd_decls); + } + vm--; +} + +void Weaver::insert_aspect_includes (VerboseMgr &vm, ACFileID fid, + bool header, const string &aspect_includes, const string &aspect_fwd_decls) { + +#ifdef FRONTEND_PUMA + Unit *u = (Unit*)fid.file_entry (); // TODO: what about 'const' here? + assert (u->isFile ()); + FileUnit *unit = (FileUnit*)u; + + ListElement *file_first = (ListElement*)unit->first (); + ListElement *file_last = (ListElement*)unit->last (); + if (!file_first) { + // file is empty + vm++; vm << "File is empty" << endvm; vm--; + return; + } + assert (file_last); + + // create the file prologue + ACUnit prologue (err ()); + ACUnit epilogue (err ()); + prologue.name (""); + epilogue.name (""); +#else + clang::SourceManager &SM = _project.get_compiler_instance ()->getSourceManager (); + const llvm::MemoryBuffer *mb = SM.getMemoryBufferForFile (fid.file_entry()); + if (mb->getBuffer () == "") { + // file is empty + vm++; vm << "File is empty" << endvm; vm--; + return; + } + ostringstream prologue; + ostringstream epilogue; +#endif // FRONTEND_PUMA + + // determine the name of the ac_FIRST... macro + string first_macro = "__ac_FIRST_"; + first_macro += _conf.project_id (); + + // generate the preprocessor directives + prologue << "#ifndef " << first_macro.c_str () << endl; + prologue << "#define " << first_macro.c_str () << endl; + prologue << "#define __ac_FIRST_FILE_"; + Naming::mangle_file (prologue, fid); + prologue << endl; + prologue << "#ifndef __ac_have_predefined_includes__" << endl; + prologue << "#define __ac_have_predefined_includes__" << endl; + prologue << "#endif // __ac_have_predefined_includes__" << endl; + // insert AC only in header files, in cc files is has already been done + if (header) { + prologue << NamespaceAC::def( _conf ); + prologue << aspect_fwd_decls; + } + prologue << "#endif // " << first_macro.c_str () << endl; + + epilogue << endl << "#ifdef __ac_FIRST_FILE_"; + Naming::mangle_file (epilogue, fid); + epilogue << endl; + epilogue << aspect_includes; + epilogue << "#undef " << first_macro.c_str () << endl; + epilogue << "#undef __ac_FIRST_FILE_"; + Naming::mangle_file (epilogue, fid); + epilogue << endl; + epilogue << "#endif // __ac_FIRST_FILE_"; + Naming::mangle_file (epilogue, fid); + epilogue << endl; + +#ifdef FRONTEND_PUMA + prologue << endu; + unit->move_before (file_first, prologue); + // insert a #line directive at this point + _line_mgr.insert (unit, PumaToken ((Token*)file_first)); + + epilogue << endu; + // insert a #line directive at this point + _line_mgr.insert (&epilogue, PumaToken ((Token*)epilogue.first ())); + unit->move (file_last, epilogue); +#else + string new_stuff = prologue.str (); + new_stuff += mb->getBuffer(); + new_stuff += epilogue.str (); + SM.overrideFileContents(fid.file_entry(), + llvm::MemoryBuffer::getMemBufferCopy(new_stuff, fid.file_entry()->getName())); +#endif // FRONTEND_PUMA +} + +// transform all #line " "". This is necessary for +// debuggers to find generated code. +void Weaver::update_line_directives (ACFileID fid, const char *filename) { +#ifdef FRONTEND_PUMA + Unit *unit = (Unit*)fid.file_entry (); // TODO: what about 'const' here? + int line = 1; + bool in_dir = false; + int have_line = 0; + Token *start = 0; + Token *end = 0; + for (Token *token = (Token*)unit->first (); token; + token = (Token*)unit->next (token)) { + if (token->is_directive ()) { + if (!in_dir) { + in_dir = true; + start = token; + } + if (strncmp ("\"text (), 4) == 0 || + strcmp ("\"intro\"", token->text ()) == 0) + have_line = line; + } + else if (in_dir) { + in_dir = false; + if (have_line != 0) { + end = (Token*)unit->prev (unit->prev (token)); + CUnit new_dir (err ()); + new_dir << "#line " << (have_line + 1) << " \"" << filename + << "\"" << endu; + assert (start && end); + unit->move_before (start, new_dir); + unit->kill (start, end); + have_line = 0; + } + } + line += token->line_breaks (); + } +#else + clang::SourceManager &sm = _project.get_compiler_instance ()->getSourceManager (); + + const llvm::MemoryBuffer *mb = sm.getMemoryBufferForFile(fid.file_entry ()); + string buf = update_line_directives_clang (mb->getBuffer(), filename, _line_mgr); + sm.overrideFileContents(fid.file_entry(), llvm::MemoryBuffer::getMemBufferCopy(buf, fid.file_entry()->getName())); +#endif +} + + +ACFileID Weaver::translate (VerboseMgr &vm, const char *file, + Transformer &transformer) + { + vm << "Handling Translation Unit `"; + const char *fname = strrchr (file, (int)'/'); + vm << (fname ? ++fname : file) << "'." << endvm; + + vm++; + ACFileID fid = transformer.work (file); + vm--; + + return fid; // return the created unit + } + +class Searcher : public PointCutSearcher { +public: + ACM_Pointcut *lookup_pct_func (bool root_qualified, std::vector &qual_name) { + return 0; + } + + ACM_Attribute *lookup_pct_attr(bool root_qualified, std::vector &qual_name) { + return 0; + } +}; + +void Weaver::match_expr_in_repo(VerboseMgr &vm) { + const char *repo_file = _conf.repository(); + + if (getenv("ACOLDREPO") != NULL) { + err() << sev_error << "matching not supported with old repository format" + << endMessage; + return; + } + + vm << "Reading project repository '" << repo_file << "'" << endvm; + // TODO: O_RDONLY doesn't work. -> fix + int fd = SysCall::open_excl (repo_file, O_RDWR, &err()); + ProjectModel project_model; + XmlModelReader reader; + if (!reader.read (project_model, repo_file, fd)) { + err() << sev_error << "project repository '" << repo_file << "' cannot be opened" + " or is invalid" << endMessage; + return; + } + SysCall::close_excl (fd, &err ()); + if (project_model.get_version () != ac_version ()) + err() << sev_warning << "project file version '" << project_model.get_version().c_str () + << "' differs from ac++ version" << endMessage; + + string pct = _conf.expr(); + if (pct == "") { + err() << sev_error << "Empty pointcut expression." << endMessage; + return; + } + + vm << "Fixing non-persistent element relations" << endvm; + ProjectModel::Selection all_classes; + project_model.select ((JoinPointType)(JPT_Class|JPT_Aspect), all_classes); + // set derived relation for all base relations + for (ProjectModel::Selection::iterator iter = all_classes.begin (); + iter != all_classes.end (); ++iter) { + ACM_Class &cls = (ACM_Class&)**iter; + typedef ACM_Container BC; + BC &bases = cls.get_bases(); + for (BC::iterator bi = bases.begin (); bi != bases.end (); ++bi) + (*bi)->get_derived().insert(&cls); + } + + ProjectModel::Selection all_calls; + project_model.select (JPT_Call, all_calls); + // set backward links from all functions to calls of it + for (ProjectModel::Selection::iterator iter = all_calls.begin (); + iter != all_calls.end (); ++iter) { + ACM_Call &call = (ACM_Call&)**iter; + call.get_target()->get_calls().insert(&call); + } + + vm << "Matching pointcut expression " << pct << endvm; + // remove blanks (not handled by parser correctly); blanks in match expression must remain + string tmp; + bool in_quotes = false; + for (string::iterator i = pct.begin (); i != pct.end(); ++i) { + if (!in_quotes && *i == ' ') + continue; + tmp += *i; + if (*i == '\"') + in_quotes = !in_quotes; + } + pct = tmp; + + PointCutExprParser *pce_parser = PointCutExprParser::instance( _conf ); + Searcher searcher; + PointCutContext context (project_model, _conf); + PointCutExpr *pce = 0; + try { + pce = pce_parser->parse(pct, searcher); + pce->semantics(err (), context, _conf.warn_compatibility()); + + } + catch (const std::exception &e) { + err () << sev_error + << "Invalid pointcut expression: " << e.what() << "." << endMessage; + return; + } + + // match all joinpoints + // iterate through all introduction advice in the plan + ProjectModel::Selection all; + project_model.select ((JoinPointType)(JPT_Class|JPT_Aspect|JPT_Function|JPT_Variable|JPT_Code), all); + // update the plan for intros + for (ProjectModel::Selection::iterator iter = all.begin (); + iter != all.end (); ++iter) { + ACM_Any &jpl = (ACM_Any&)**iter; + if (is_pseudo(jpl)) + continue; + Binding binding; // binding and condition not used for intros + Condition condition; + if (pce->match (jpl, context, binding, condition)) { + cout << filename (jpl) << ":" << line(jpl) << ":\t" << jpl.type_str() << " \""; + if (jpl.type_val() & JPT_Code) + cout << signature((ACM_Code&)jpl); + else + cout << signature((ACM_Name&)jpl); + cout << "\""; + if (condition) + cout << " ; condition: " << condition; + cout << endl; + } + } +} + +string Weaver::gen_aspect_includes (ACFileID target_unit) { + // generate the code + stringstream cluster; + for (list::const_iterator c = _aspect_include_clusters.begin(); + c != _aspect_include_clusters.end(); ++c) { + cluster << "#ifdef __ac_need_"; + Naming::mangle_file (cluster, c->_aspect); + cluster << endl; + + const set &cluster_units = c->_cluster; + for (set::const_iterator i = cluster_units.begin (); + i != cluster_units.end (); ++i) { + ACFileID aspect_unit = *i; + Filename incname = _project.getRelInclString (target_unit.name ().c_str (), aspect_unit.name ().c_str ()); + cluster << "#ifndef __ac_have_"; + Naming::mangle_file (cluster, aspect_unit); + cluster << endl; + cluster << "#define __ac_have_"; + Naming::mangle_file (cluster, aspect_unit); + cluster << endl; + cluster << "#include \"" << incname << "\"" << endl; + cluster << "#endif" << endl; + } + + cluster << "#endif" << endl; + } + return cluster.str (); +} + diff --git a/AspectC++/Weaver.h b/AspectC++/Weaver.h new file mode 100644 index 0000000..efdac28 --- /dev/null +++ b/AspectC++/Weaver.h @@ -0,0 +1,74 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __Weaver_h__ +#define __Weaver_h__ + +// C++ includes +#include +using std::stringstream; +#include +using std::set; +#include +using std::list; + +// PUMA includes +#include "Puma/VerboseMgr.h" + +// AspectC++ includes +#include "ACConfig.h" +#include "ACErrorStream.h" +#include "LineDirectiveMgr.h" +#include "ACFileID.h" +#include "AspectIncludeCluster.h" + +class Transformer; + +namespace Puma { + class VerboseMgr; +} // namespace Puma + +class Weaver { + ACProject &_project; + ACConfig &_conf; + LineDirectiveMgr _line_mgr; + list _aspect_include_clusters; + + ACFileID translate (Puma::VerboseMgr &vm, const char *file, Transformer &transformer); + void aspect_includes (ostream &includes); + void aspect_include (ostream &includes, const char *name); + void insert_aspect_includes (Puma::VerboseMgr &vm, ACFileID fid, bool header, + const string &aspect_includes, const string &aspect_fwd_decls); + void insert_aspect_includes (Puma::VerboseMgr &vm, set &cc_units, + set &h_units, const string &aspect_includes, const string &aspect_fwd_decls); + void update_line_directives (set &cc_units, set &h_units); + void update_line_directives (ACFileID fid, const char *filename); + ACErrorStream &err () const { return static_cast(_project.err ()); } + void match_expr_in_repo (Puma::VerboseMgr &vm); + string gen_aspect_includes (ACFileID target_unit); + +public: + + // Initialize the weaver + Weaver (ACProject& project, ACConfig &conf); + + // Do the AspectC++ -> C++ tranformation on the project + void weave (); +}; + +#endif // __Weaver_h__ diff --git a/AspectC++/WeaverBase.h b/AspectC++/WeaverBase.h new file mode 100644 index 0000000..3c706a3 --- /dev/null +++ b/AspectC++/WeaverBase.h @@ -0,0 +1,35 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __WeaverBase_h__ +#define __WeaverBase_h__ + +// This header file includes the right WeaverBase class implementations +// depending on the configured frontend + +#ifdef FRONTEND_PUMA + +#include "PumaWeaverBase.h" + +#else // FRONTEND_CLANG + +#include "ClangWeaverBase.h" + +#endif + +#endif // __WeaverBase_h__ diff --git a/AspectC++/ac++.cc b/AspectC++/ac++.cc new file mode 100644 index 0000000..1a7c48c --- /dev/null +++ b/AspectC++/ac++.cc @@ -0,0 +1,64 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 + +// AC++ includes +#include "ACProject.h" +#include "Weaver.h" +#include "ACErrorStream.h" + +using namespace Puma; + +int main (int argc, char **argv) { + + // the error stream for all warnings, error messages, etc. + ACErrorStream err; + + try { + // Create a project that can either accept the project description with + // the standard Puma options or by a 'project file' + ACProject project(err, argc, argv); + + // Create the configuration object for the weaver + ACConfig config (project, argc, argv); + + // analyze the command line arguments + if (config.analyze ()) { + + // check if code has to be woven + // or a pointcut expression shall be matched against the repository + if (config.file_out () || config.ifiles () || config.iterate () || + !config.expr().empty()) { + // Create an AspectC++ weaver, which manipulates (parts of) the project + Weaver ac (project, config); + // do the necessary weaving + ac.weave (); + } + } + } + catch (const std::bad_alloc &e) { + err << sev_fatal << "Caught memory allocation error: " << e.what () << endMessage; + } + catch (const std::exception &e) { + err << sev_fatal << "Caught standard exception: " << e.what () << endMessage; + } + catch (...) { + err << sev_fatal << "Caught unknown exception!" << endMessage; + } + return (err.severity () <= sev_warning) ? 0 : 1; +} + diff --git a/AspectC++/akut-trigger.tmp b/AspectC++/akut-trigger.tmp new file mode 100644 index 0000000..8bef023 --- /dev/null +++ b/AspectC++/akut-trigger.tmp @@ -0,0 +1 @@ +Sa 4. Okt 21:51:47 CEST 2014 diff --git a/AspectC++/clang-3.4-disable-modules.patch b/AspectC++/clang-3.4-disable-modules.patch new file mode 100644 index 0000000..c2cda82 --- /dev/null +++ b/AspectC++/clang-3.4-disable-modules.patch @@ -0,0 +1,12 @@ +Index: lib/Lex/HeaderSearch.cpp +=================================================================== +--- lib/Lex/HeaderSearch.cpp (revision 222625) ++++ lib/Lex/HeaderSearch.cpp (working copy) +@@ -954,6 +954,7 @@ + const DirectoryEntry *Root, + bool IsSystem) { + SmallVector FixUpDirectories; ++ return false; + + StringRef DirName = FileName; + do { diff --git a/AspectC++/config/Makefile b/AspectC++/config/Makefile new file mode 100644 index 0000000..5007223 --- /dev/null +++ b/AspectC++/config/Makefile @@ -0,0 +1,52 @@ +# +# makefile for generating a config file for the installed Clang version +# + +# ****************************** +# * S E T T I N G S * +# ****************************** + +# check whether llvm-config is available +ifeq ($(shell which $(LLVMCONF)),) + $(error LLVMCONF ($(LLVMCONF)) is not found) +endif + +LLVM_VERSION := $(shell $(LLVMCONF) --version) + +LLVM_LIBDIR := $(shell $(LLVMCONF) --libdir) +ifeq ($(_TARGET),win_x86_64) # handle '\' in path name + LLVM_LIBDIR := $(subst \,/,$(LLVM_LIBDIR)) +endif +LLVM_LIBS := $(LLVM_LIBDIR)/libclang*.a +# These functions need to be wrapped: parameters omitted to be more version independent +LLVM_KEY_COUNT := 12 +LLVM_KEYS := _ZN5clang4Sema31ActOnStartCXXMemberDeclarations \ + _ZN5clang4Sema33ActOnFinishCXXMemberSpecification \ + _ZN5clang4Sema25ActOnEndOfTranslationUnit \ + _ZN5clang4Sema19canSkipFunctionBody \ + _ZN5clang4Sema24ActOnCXXMemberDeclarator \ + _ZN5clang4Sema15ActOnDeclarator \ + _ZN5clang12Preprocessor3Lex \ + _ZN5clang12Preprocessor9PeekAhead \ + _ZN5clang4Sema19ActOnBaseSpecifiers \ + _ZN5clang4Sema8ActOnTag \ + _ZN5clang4Sema22ActOnStartNamespaceDef \ + _ZN5clang4Sema23ActOnStartOfFunctionDefEPNS_5ScopeERNS_10Declarator +ifeq ($(_TARGET),macosx_x86_64) # on macOS the symbols have an additional '_' + LLVM_KEYS := $(patsubst %, _%, $(LLVM_KEYS)) +endif + +# command to generate LLVM_SYMBOLS (a recursive variable!) +LLVM_SYMBOLS_GEN = $(foreach LLVM_KEY, $(LLVM_KEYS), $(filter _%, $(shell nm --defined-only $(LLVM_LIBS) | grep "T $(LLVM_KEY)"))) + +# ****************************** +# * R U L E S * +# ****************************** + +clang: clang-$(LLVM_VERSION).mk + +# find the exact symbols using the keys in the clang libraries +clang-$(LLVM_VERSION).mk: + @echo Generating config file for Clang $(LLVM_VERSION) + @echo LLVM_SYMBOLS := $(LLVM_SYMBOLS_GEN) > $@ + diff --git a/AspectC++/config/clang-3.5.0.mk b/AspectC++/config/clang-3.5.0.mk new file mode 100644 index 0000000..dd3bb07 --- /dev/null +++ b/AspectC++/config/clang-3.5.0.mk @@ -0,0 +1 @@ +LLVM_SYMBOLS := _ZN5clang4Sema31ActOnStartCXXMemberDeclarationsEPNS_5ScopeEPNS_4DeclENS_14SourceLocationEbS5_ _ZN5clang4Sema33ActOnFinishCXXMemberSpecificationEPNS_5ScopeENS_14SourceLocationEPNS_4DeclES3_S3_PNS_13AttributeListE _ZN5clang4Sema25ActOnEndOfTranslationUnitEv _ZN5clang4Sema19canSkipFunctionBodyEPNS_4DeclE _ZN5clang4Sema24ActOnCXXMemberDeclaratorEPNS_5ScopeENS_15AccessSpecifierERNS_10DeclaratorEN4llvm15MutableArrayRefIPNS_21TemplateParameterListEEEPNS_4ExprERKNS_14VirtSpecifiersENS_16InClassInitStyleE _ZN5clang4Sema15ActOnDeclaratorEPNS_5ScopeERNS_10DeclaratorE _ZN5clang12Preprocessor3LexERNS_5TokenE _ZN5clang12Preprocessor9PeekAheadEj _ZN5clang4Sema19ActOnBaseSpecifiersEPNS_4DeclEPPNS_16CXXBaseSpecifierEj _ZN5clang4Sema8ActOnTagEPNS_5ScopeEjNS0_10TagUseKindENS_14SourceLocationERNS_12CXXScopeSpecEPNS_14IdentifierInfoES4_PNS_13AttributeListENS_15AccessSpecifierES4_N4llvm15MutableArrayRefIPNS_21TemplateParameterListEEERbSH_S4_bNS_12ActionResultINS_9OpaquePtrINS_8QualTypeEEELb0EEEb _ZN5clang4Sema22ActOnStartNamespaceDefEPNS_5ScopeENS_14SourceLocationES3_S3_PNS_14IdentifierInfoES3_PNS_13AttributeListE _ZN5clang4Sema23ActOnStartOfFunctionDefEPNS_5ScopeERNS_10DeclaratorE diff --git a/AspectC++/config/clang-3.5.0svn.mk b/AspectC++/config/clang-3.5.0svn.mk new file mode 100644 index 0000000..dd3bb07 --- /dev/null +++ b/AspectC++/config/clang-3.5.0svn.mk @@ -0,0 +1 @@ +LLVM_SYMBOLS := _ZN5clang4Sema31ActOnStartCXXMemberDeclarationsEPNS_5ScopeEPNS_4DeclENS_14SourceLocationEbS5_ _ZN5clang4Sema33ActOnFinishCXXMemberSpecificationEPNS_5ScopeENS_14SourceLocationEPNS_4DeclES3_S3_PNS_13AttributeListE _ZN5clang4Sema25ActOnEndOfTranslationUnitEv _ZN5clang4Sema19canSkipFunctionBodyEPNS_4DeclE _ZN5clang4Sema24ActOnCXXMemberDeclaratorEPNS_5ScopeENS_15AccessSpecifierERNS_10DeclaratorEN4llvm15MutableArrayRefIPNS_21TemplateParameterListEEEPNS_4ExprERKNS_14VirtSpecifiersENS_16InClassInitStyleE _ZN5clang4Sema15ActOnDeclaratorEPNS_5ScopeERNS_10DeclaratorE _ZN5clang12Preprocessor3LexERNS_5TokenE _ZN5clang12Preprocessor9PeekAheadEj _ZN5clang4Sema19ActOnBaseSpecifiersEPNS_4DeclEPPNS_16CXXBaseSpecifierEj _ZN5clang4Sema8ActOnTagEPNS_5ScopeEjNS0_10TagUseKindENS_14SourceLocationERNS_12CXXScopeSpecEPNS_14IdentifierInfoES4_PNS_13AttributeListENS_15AccessSpecifierES4_N4llvm15MutableArrayRefIPNS_21TemplateParameterListEEERbSH_S4_bNS_12ActionResultINS_9OpaquePtrINS_8QualTypeEEELb0EEEb _ZN5clang4Sema22ActOnStartNamespaceDefEPNS_5ScopeENS_14SourceLocationES3_S3_PNS_14IdentifierInfoES3_PNS_13AttributeListE _ZN5clang4Sema23ActOnStartOfFunctionDefEPNS_5ScopeERNS_10DeclaratorE diff --git a/AspectC++/config/clang-3.6.2.mk b/AspectC++/config/clang-3.6.2.mk new file mode 100644 index 0000000..dd3bb07 --- /dev/null +++ b/AspectC++/config/clang-3.6.2.mk @@ -0,0 +1 @@ +LLVM_SYMBOLS := _ZN5clang4Sema31ActOnStartCXXMemberDeclarationsEPNS_5ScopeEPNS_4DeclENS_14SourceLocationEbS5_ _ZN5clang4Sema33ActOnFinishCXXMemberSpecificationEPNS_5ScopeENS_14SourceLocationEPNS_4DeclES3_S3_PNS_13AttributeListE _ZN5clang4Sema25ActOnEndOfTranslationUnitEv _ZN5clang4Sema19canSkipFunctionBodyEPNS_4DeclE _ZN5clang4Sema24ActOnCXXMemberDeclaratorEPNS_5ScopeENS_15AccessSpecifierERNS_10DeclaratorEN4llvm15MutableArrayRefIPNS_21TemplateParameterListEEEPNS_4ExprERKNS_14VirtSpecifiersENS_16InClassInitStyleE _ZN5clang4Sema15ActOnDeclaratorEPNS_5ScopeERNS_10DeclaratorE _ZN5clang12Preprocessor3LexERNS_5TokenE _ZN5clang12Preprocessor9PeekAheadEj _ZN5clang4Sema19ActOnBaseSpecifiersEPNS_4DeclEPPNS_16CXXBaseSpecifierEj _ZN5clang4Sema8ActOnTagEPNS_5ScopeEjNS0_10TagUseKindENS_14SourceLocationERNS_12CXXScopeSpecEPNS_14IdentifierInfoES4_PNS_13AttributeListENS_15AccessSpecifierES4_N4llvm15MutableArrayRefIPNS_21TemplateParameterListEEERbSH_S4_bNS_12ActionResultINS_9OpaquePtrINS_8QualTypeEEELb0EEEb _ZN5clang4Sema22ActOnStartNamespaceDefEPNS_5ScopeENS_14SourceLocationES3_S3_PNS_14IdentifierInfoES3_PNS_13AttributeListE _ZN5clang4Sema23ActOnStartOfFunctionDefEPNS_5ScopeERNS_10DeclaratorE diff --git a/AspectC++/config/clang-3.7.1.mk b/AspectC++/config/clang-3.7.1.mk new file mode 100644 index 0000000..0d8588f --- /dev/null +++ b/AspectC++/config/clang-3.7.1.mk @@ -0,0 +1 @@ +LLVM_SYMBOLS := _ZN5clang4Sema31ActOnStartCXXMemberDeclarationsEPNS_5ScopeEPNS_4DeclENS_14SourceLocationEbS5_ _ZN5clang4Sema33ActOnFinishCXXMemberSpecificationEPNS_5ScopeENS_14SourceLocationEPNS_4DeclES3_S3_PNS_13AttributeListE _ZN5clang4Sema25ActOnEndOfTranslationUnitEv _ZN5clang4Sema19canSkipFunctionBodyEPNS_4DeclE _ZN5clang4Sema24ActOnCXXMemberDeclaratorEPNS_5ScopeENS_15AccessSpecifierERNS_10DeclaratorEN4llvm15MutableArrayRefIPNS_21TemplateParameterListEEEPNS_4ExprERKNS_14VirtSpecifiersENS_16InClassInitStyleE _ZN5clang4Sema15ActOnDeclaratorEPNS_5ScopeERNS_10DeclaratorE _ZN5clang12Preprocessor3LexERNS_5TokenE _ZN5clang12Preprocessor9PeekAheadEj _ZN5clang4Sema19ActOnBaseSpecifiersEPNS_4DeclEPPNS_16CXXBaseSpecifierEj _ZN5clang4Sema8ActOnTagEPNS_5ScopeEjNS0_10TagUseKindENS_14SourceLocationERNS_12CXXScopeSpecEPNS_14IdentifierInfoES4_PNS_13AttributeListENS_15AccessSpecifierES4_N4llvm15MutableArrayRefIPNS_21TemplateParameterListEEERbSH_S4_bNS_12ActionResultINS_9OpaquePtrINS_8QualTypeEEELb0EEEbPNS0_12SkipBodyInfoE _ZN5clang4Sema22ActOnStartNamespaceDefEPNS_5ScopeENS_14SourceLocationES3_S3_PNS_14IdentifierInfoES3_PNS_13AttributeListE _ZN5clang4Sema23ActOnStartOfFunctionDefEPNS_5ScopeERNS_10DeclaratorE diff --git a/AspectC++/config/clang-3.8.0.mk b/AspectC++/config/clang-3.8.0.mk new file mode 100644 index 0000000..cf237b6 --- /dev/null +++ b/AspectC++/config/clang-3.8.0.mk @@ -0,0 +1 @@ +LLVM_SYMBOLS := _ZN5clang4Sema31ActOnStartCXXMemberDeclarationsEPNS_5ScopeEPNS_4DeclENS_14SourceLocationEbS5_ _ZN5clang4Sema33ActOnFinishCXXMemberSpecificationEPNS_5ScopeENS_14SourceLocationEPNS_4DeclES3_S3_PNS_13AttributeListE _ZN5clang4Sema25ActOnEndOfTranslationUnitEv _ZN5clang4Sema19canSkipFunctionBodyEPNS_4DeclE _ZN5clang4Sema24ActOnCXXMemberDeclaratorEPNS_5ScopeENS_15AccessSpecifierERNS_10DeclaratorEN4llvm15MutableArrayRefIPNS_21TemplateParameterListEEEPNS_4ExprERKNS_14VirtSpecifiersENS_16InClassInitStyleE _ZN5clang4Sema15ActOnDeclaratorEPNS_5ScopeERNS_10DeclaratorE _ZN5clang12Preprocessor3LexERNS_5TokenE _ZN5clang12Preprocessor9PeekAheadEj _ZN5clang4Sema19ActOnBaseSpecifiersEPNS_4DeclEN4llvm15MutableArrayRefIPNS_16CXXBaseSpecifierEEE _ZN5clang4Sema8ActOnTagEPNS_5ScopeEjNS0_10TagUseKindENS_14SourceLocationERNS_12CXXScopeSpecEPNS_14IdentifierInfoES4_PNS_13AttributeListENS_15AccessSpecifierES4_N4llvm15MutableArrayRefIPNS_21TemplateParameterListEEERbSH_S4_bNS_12ActionResultINS_9OpaquePtrINS_8QualTypeEEELb0EEEbPNS0_12SkipBodyInfoE _ZN5clang4Sema22ActOnStartNamespaceDefEPNS_5ScopeENS_14SourceLocationES3_S3_PNS_14IdentifierInfoES3_PNS_13AttributeListERPNS_18UsingDirectiveDeclE _ZN5clang4Sema23ActOnStartOfFunctionDefEPNS_5ScopeERNS_10DeclaratorEN4llvm15MutableArrayRefIPNS_21TemplateParameterListEEEPNS0_12SkipBodyInfoE diff --git a/AspectC++/config/clang-3.8.1.mk b/AspectC++/config/clang-3.8.1.mk new file mode 100644 index 0000000..cf237b6 --- /dev/null +++ b/AspectC++/config/clang-3.8.1.mk @@ -0,0 +1 @@ +LLVM_SYMBOLS := _ZN5clang4Sema31ActOnStartCXXMemberDeclarationsEPNS_5ScopeEPNS_4DeclENS_14SourceLocationEbS5_ _ZN5clang4Sema33ActOnFinishCXXMemberSpecificationEPNS_5ScopeENS_14SourceLocationEPNS_4DeclES3_S3_PNS_13AttributeListE _ZN5clang4Sema25ActOnEndOfTranslationUnitEv _ZN5clang4Sema19canSkipFunctionBodyEPNS_4DeclE _ZN5clang4Sema24ActOnCXXMemberDeclaratorEPNS_5ScopeENS_15AccessSpecifierERNS_10DeclaratorEN4llvm15MutableArrayRefIPNS_21TemplateParameterListEEEPNS_4ExprERKNS_14VirtSpecifiersENS_16InClassInitStyleE _ZN5clang4Sema15ActOnDeclaratorEPNS_5ScopeERNS_10DeclaratorE _ZN5clang12Preprocessor3LexERNS_5TokenE _ZN5clang12Preprocessor9PeekAheadEj _ZN5clang4Sema19ActOnBaseSpecifiersEPNS_4DeclEN4llvm15MutableArrayRefIPNS_16CXXBaseSpecifierEEE _ZN5clang4Sema8ActOnTagEPNS_5ScopeEjNS0_10TagUseKindENS_14SourceLocationERNS_12CXXScopeSpecEPNS_14IdentifierInfoES4_PNS_13AttributeListENS_15AccessSpecifierES4_N4llvm15MutableArrayRefIPNS_21TemplateParameterListEEERbSH_S4_bNS_12ActionResultINS_9OpaquePtrINS_8QualTypeEEELb0EEEbPNS0_12SkipBodyInfoE _ZN5clang4Sema22ActOnStartNamespaceDefEPNS_5ScopeENS_14SourceLocationES3_S3_PNS_14IdentifierInfoES3_PNS_13AttributeListERPNS_18UsingDirectiveDeclE _ZN5clang4Sema23ActOnStartOfFunctionDefEPNS_5ScopeERNS_10DeclaratorEN4llvm15MutableArrayRefIPNS_21TemplateParameterListEEEPNS0_12SkipBodyInfoE diff --git a/AspectC++/config/clang-3.9.1.mk b/AspectC++/config/clang-3.9.1.mk new file mode 100644 index 0000000..cf237b6 --- /dev/null +++ b/AspectC++/config/clang-3.9.1.mk @@ -0,0 +1 @@ +LLVM_SYMBOLS := _ZN5clang4Sema31ActOnStartCXXMemberDeclarationsEPNS_5ScopeEPNS_4DeclENS_14SourceLocationEbS5_ _ZN5clang4Sema33ActOnFinishCXXMemberSpecificationEPNS_5ScopeENS_14SourceLocationEPNS_4DeclES3_S3_PNS_13AttributeListE _ZN5clang4Sema25ActOnEndOfTranslationUnitEv _ZN5clang4Sema19canSkipFunctionBodyEPNS_4DeclE _ZN5clang4Sema24ActOnCXXMemberDeclaratorEPNS_5ScopeENS_15AccessSpecifierERNS_10DeclaratorEN4llvm15MutableArrayRefIPNS_21TemplateParameterListEEEPNS_4ExprERKNS_14VirtSpecifiersENS_16InClassInitStyleE _ZN5clang4Sema15ActOnDeclaratorEPNS_5ScopeERNS_10DeclaratorE _ZN5clang12Preprocessor3LexERNS_5TokenE _ZN5clang12Preprocessor9PeekAheadEj _ZN5clang4Sema19ActOnBaseSpecifiersEPNS_4DeclEN4llvm15MutableArrayRefIPNS_16CXXBaseSpecifierEEE _ZN5clang4Sema8ActOnTagEPNS_5ScopeEjNS0_10TagUseKindENS_14SourceLocationERNS_12CXXScopeSpecEPNS_14IdentifierInfoES4_PNS_13AttributeListENS_15AccessSpecifierES4_N4llvm15MutableArrayRefIPNS_21TemplateParameterListEEERbSH_S4_bNS_12ActionResultINS_9OpaquePtrINS_8QualTypeEEELb0EEEbPNS0_12SkipBodyInfoE _ZN5clang4Sema22ActOnStartNamespaceDefEPNS_5ScopeENS_14SourceLocationES3_S3_PNS_14IdentifierInfoES3_PNS_13AttributeListERPNS_18UsingDirectiveDeclE _ZN5clang4Sema23ActOnStartOfFunctionDefEPNS_5ScopeERNS_10DeclaratorEN4llvm15MutableArrayRefIPNS_21TemplateParameterListEEEPNS0_12SkipBodyInfoE diff --git a/AspectC++/config/clang-4.0.0.mk b/AspectC++/config/clang-4.0.0.mk new file mode 100644 index 0000000..cf237b6 --- /dev/null +++ b/AspectC++/config/clang-4.0.0.mk @@ -0,0 +1 @@ +LLVM_SYMBOLS := _ZN5clang4Sema31ActOnStartCXXMemberDeclarationsEPNS_5ScopeEPNS_4DeclENS_14SourceLocationEbS5_ _ZN5clang4Sema33ActOnFinishCXXMemberSpecificationEPNS_5ScopeENS_14SourceLocationEPNS_4DeclES3_S3_PNS_13AttributeListE _ZN5clang4Sema25ActOnEndOfTranslationUnitEv _ZN5clang4Sema19canSkipFunctionBodyEPNS_4DeclE _ZN5clang4Sema24ActOnCXXMemberDeclaratorEPNS_5ScopeENS_15AccessSpecifierERNS_10DeclaratorEN4llvm15MutableArrayRefIPNS_21TemplateParameterListEEEPNS_4ExprERKNS_14VirtSpecifiersENS_16InClassInitStyleE _ZN5clang4Sema15ActOnDeclaratorEPNS_5ScopeERNS_10DeclaratorE _ZN5clang12Preprocessor3LexERNS_5TokenE _ZN5clang12Preprocessor9PeekAheadEj _ZN5clang4Sema19ActOnBaseSpecifiersEPNS_4DeclEN4llvm15MutableArrayRefIPNS_16CXXBaseSpecifierEEE _ZN5clang4Sema8ActOnTagEPNS_5ScopeEjNS0_10TagUseKindENS_14SourceLocationERNS_12CXXScopeSpecEPNS_14IdentifierInfoES4_PNS_13AttributeListENS_15AccessSpecifierES4_N4llvm15MutableArrayRefIPNS_21TemplateParameterListEEERbSH_S4_bNS_12ActionResultINS_9OpaquePtrINS_8QualTypeEEELb0EEEbPNS0_12SkipBodyInfoE _ZN5clang4Sema22ActOnStartNamespaceDefEPNS_5ScopeENS_14SourceLocationES3_S3_PNS_14IdentifierInfoES3_PNS_13AttributeListERPNS_18UsingDirectiveDeclE _ZN5clang4Sema23ActOnStartOfFunctionDefEPNS_5ScopeERNS_10DeclaratorEN4llvm15MutableArrayRefIPNS_21TemplateParameterListEEEPNS0_12SkipBodyInfoE diff --git a/AspectC++/config/clang-4.0.1.mk b/AspectC++/config/clang-4.0.1.mk new file mode 100644 index 0000000..cf237b6 --- /dev/null +++ b/AspectC++/config/clang-4.0.1.mk @@ -0,0 +1 @@ +LLVM_SYMBOLS := _ZN5clang4Sema31ActOnStartCXXMemberDeclarationsEPNS_5ScopeEPNS_4DeclENS_14SourceLocationEbS5_ _ZN5clang4Sema33ActOnFinishCXXMemberSpecificationEPNS_5ScopeENS_14SourceLocationEPNS_4DeclES3_S3_PNS_13AttributeListE _ZN5clang4Sema25ActOnEndOfTranslationUnitEv _ZN5clang4Sema19canSkipFunctionBodyEPNS_4DeclE _ZN5clang4Sema24ActOnCXXMemberDeclaratorEPNS_5ScopeENS_15AccessSpecifierERNS_10DeclaratorEN4llvm15MutableArrayRefIPNS_21TemplateParameterListEEEPNS_4ExprERKNS_14VirtSpecifiersENS_16InClassInitStyleE _ZN5clang4Sema15ActOnDeclaratorEPNS_5ScopeERNS_10DeclaratorE _ZN5clang12Preprocessor3LexERNS_5TokenE _ZN5clang12Preprocessor9PeekAheadEj _ZN5clang4Sema19ActOnBaseSpecifiersEPNS_4DeclEN4llvm15MutableArrayRefIPNS_16CXXBaseSpecifierEEE _ZN5clang4Sema8ActOnTagEPNS_5ScopeEjNS0_10TagUseKindENS_14SourceLocationERNS_12CXXScopeSpecEPNS_14IdentifierInfoES4_PNS_13AttributeListENS_15AccessSpecifierES4_N4llvm15MutableArrayRefIPNS_21TemplateParameterListEEERbSH_S4_bNS_12ActionResultINS_9OpaquePtrINS_8QualTypeEEELb0EEEbPNS0_12SkipBodyInfoE _ZN5clang4Sema22ActOnStartNamespaceDefEPNS_5ScopeENS_14SourceLocationES3_S3_PNS_14IdentifierInfoES3_PNS_13AttributeListERPNS_18UsingDirectiveDeclE _ZN5clang4Sema23ActOnStartOfFunctionDefEPNS_5ScopeERNS_10DeclaratorEN4llvm15MutableArrayRefIPNS_21TemplateParameterListEEEPNS0_12SkipBodyInfoE diff --git a/AspectC++/config/clang-5.0.0svn.mk b/AspectC++/config/clang-5.0.0svn.mk new file mode 100644 index 0000000..b65b794 --- /dev/null +++ b/AspectC++/config/clang-5.0.0svn.mk @@ -0,0 +1 @@ +LLVM_SYMBOLS := _ZN5clang4Sema31ActOnStartCXXMemberDeclarationsEPNS_5ScopeEPNS_4DeclENS_14SourceLocationEbS5_ _ZN5clang4Sema33ActOnFinishCXXMemberSpecificationEPNS_5ScopeENS_14SourceLocationEPNS_4DeclES3_S3_PNS_13AttributeListE _ZN5clang4Sema25ActOnEndOfTranslationUnitEv _ZN5clang4Sema19canSkipFunctionBodyEPNS_4DeclE _ZN5clang4Sema24ActOnCXXMemberDeclaratorEPNS_5ScopeENS_15AccessSpecifierERNS_10DeclaratorEN4llvm15MutableArrayRefIPNS_21TemplateParameterListEEEPNS_4ExprERKNS_14VirtSpecifiersENS_16InClassInitStyleE _ZN5clang4Sema15ActOnDeclaratorEPNS_5ScopeERNS_10DeclaratorE _ZN5clang12Preprocessor3LexERNS_5TokenE _ZN5clang12Preprocessor9PeekAheadEj _ZN5clang4Sema19ActOnBaseSpecifiersEPNS_4DeclEN4llvm15MutableArrayRefIPNS_16CXXBaseSpecifierEEE _ZN5clang4Sema8ActOnTagEPNS_5ScopeEjNS0_10TagUseKindENS_14SourceLocationERNS_12CXXScopeSpecEPNS_14IdentifierInfoES4_PNS_13AttributeListENS_15AccessSpecifierES4_N4llvm15MutableArrayRefIPNS_21TemplateParameterListEEERbSH_S4_bNS_12ActionResultINS_9OpaquePtrINS_8QualTypeEEELb0EEEbbPNS0_12SkipBodyInfoE _ZN5clang4Sema22ActOnStartNamespaceDefEPNS_5ScopeENS_14SourceLocationES3_S3_PNS_14IdentifierInfoES3_PNS_13AttributeListERPNS_18UsingDirectiveDeclE _ZN5clang4Sema23ActOnStartOfFunctionDefEPNS_5ScopeERNS_10DeclaratorEN4llvm15MutableArrayRefIPNS_21TemplateParameterListEEEPNS0_12SkipBodyInfoE diff --git a/AspectC++/config/clang.mk b/AspectC++/config/clang.mk new file mode 100644 index 0000000..69ada4a --- /dev/null +++ b/AspectC++/config/clang.mk @@ -0,0 +1,38 @@ +# set makefile variables according to the installed Clang version + +# check whether llvm-config is available +ifeq ($(shell which $(LLVMCONF)),) + $(error FRONTEND is 'Clang', but LLVMCONF ($(LLVMCONF)) is not found) +endif + +LLVM_VERSION := $(shell $(LLVMCONF) --version) + +# check if the config file for this version exists +ifeq ($(wildcard config/clang-$(LLVM_VERSION).mk),) + $(error UNSUPPORTED Clang version '$(LLVM_VERSION)' used -- try 'make -C config clang LLVMCONF=') +endif + +include config/clang-$(LLVM_VERSION).mk + +# determine relevant interface variants +LLVM_INTERFACE := 38 # latest is default +ifneq ($(filter 3.5%, $(LLVM_VERSION))$(filter 3.6%, $(LLVM_VERSION)),) + LLVM_INTERFACE := 35 +else +ifneq ($(filter 3.7%, $(LLVM_VERSION)),) + LLVM_INTERFACE := 37 +else +ifneq ($(filter 3.8%, $(LLVM_VERSION))$(filter 3.9%, $(LLVM_VERSION))$(filter 4.0%, $(LLVM_VERSION)),) + LLVM_INTERFACE := 38 +endif +ifneq ($(filter 5.0%, $(LLVM_VERSION)),) + LLVM_INTERFACE := 50 +endif +endif +endif + +ifeq ($(_TARGET),macosx_x86_64) # on macOS the symbols have an additional '_' + LLVM_SYMBOLS := $(patsubst %, _%, $(LLVM_SYMBOLS)) + LLVM_SYMBOLS_SEMA := $(filter-out __ZN5clang12Preprocessor3LexERNS_5TokenE __ZN5clang12Preprocessor9PeekAheadEj, $(LLVM_SYMBOLS)) + LLVM_SYMBOLS_LEX := $(filter __ZN5clang12Preprocessor3LexERNS_5TokenE __ZN5clang12Preprocessor9PeekAheadEj, $(LLVM_SYMBOLS)) +endif diff --git a/AspectC++/doc/CompilerManual/ac-compilerman.lyx b/AspectC++/doc/CompilerManual/ac-compilerman.lyx new file mode 100644 index 0000000..33368c4 --- /dev/null +++ b/AspectC++/doc/CompilerManual/ac-compilerman.lyx @@ -0,0 +1,5180 @@ +#LyX 2.2 created this file. For more info see http://www.lyx.org/ +\lyxformat 508 +\begin_document +\begin_header +\save_transient_properties true +\origin unavailable +\textclass article +\begin_preamble +% +% setup fancyhdr +% +\RequirePackage{fancyhdr} +\fancypagestyle{plain}{% + % + % two side book class setup + % odd page - left head: chapter - left foot: page number + % even page - right head: section - right foot: page number + % no head on plain pages + % + \fancyhf{}% + \fancyhead[LE,RO]{\slshape \rightmark} + \fancyhead[LO,RE]{\slshape \leftmark} + \fancyfoot[LE,RO]{\bfseries \thepage} + % + % rules for head and foot + % also on plain pages + % + \renewcommand{\headrulewidth}{.4pt} + \renewcommand{\footrulewidth}{.4pt} + \renewcommand{\plainfootrulewidth}{.4pt} +} +% +% Variables to change some details +% +% version number for this document +% +\newcommand{\@version}{1} +\newcommand{\version}[1]{ \renewcommand{\@version}{#1} } +% +% +\newcommand\pslogo[1]{\gdef\@pslogo{#1}} +\pslogo{} +% +\newcommand\otherlogo[1]{\gdef\@otherlogo{#1}} +\otherlogo{} +% +\newcommand\remark[1]{\gdef\@remark{#1}} +\remark{} +% +\newcommand{\doctype}[1]{\gdef\@doctype{#1}} +\doctype{Studie:} +% +\newcommand\credit[1]{\gdef\@credit{#1}} +\credit{Diese Studie wurde durch die\par +\vskip .3cm +pure-systems GmbH\par +Agnetenstr. 14\par +39106 Magdeburg\par +http://www.pure-systems.com\par +\vskip .3cm +erstellt.} +% +% +% +\newcommand\layoutlogos{ + + \newlength{\@pslogowidth} + \newlength{\@otherlogowidth} + \settowidth{\@otherlogowidth}{\@otherlogo} + \settowidth{\@pslogowidth}{\@pslogo} + + \noindent + \begin{minipage}{\@otherlogowidth} + {\@otherlogo} + \end{minipage} + \hspace*{\fill} + \begin{minipage}{\@pslogowidth} + {\@pslogo} + \end{minipage} +} + +% +% redefine \maketitle macro +% +\renewcommand{\maketitle}{ + \null + \thispagestyle{empty} + + {\layoutlogos} + + \vskip 3cm + \begin{center}\leavevmode + {\Huge\raggedright {\@doctype}\\ {\@title}\par} + \rule{\textwidth}{1mm} + \vskip 3mm + {\Large\raggedleft {\@author}\par} + \vskip 15mm + {\Large\raggedleft {\@date}\par} + \end{center} + \vfill + {\large\raggedleft {\@remark}\par} + \vskip 1cm + \null +% + \newpage +% + \null + \thispagestyle{empty} + \vfill + {\@credit} + \null + \cleardoublepage +} + +%-------------------------------------------------------------------- +% setup pure-systems style +%-------------------------------------------------------------------- +\doctype{Documentation:} +\credit{ + \noindent\small{(c) 2017 Olaf Spinczyk and pure-systems GmbH\\All rights reserved.}} +\pslogo{ + \resizebox{6cm}{!}{\includegraphics{images/ps-logo}}} +\otherlogo{ + \resizebox{4cm}{!}{\includegraphics{images/ac++logo}}} +\sloppy +\remark{ + \small{(c) 2017 Olaf Spinczyk$^1$ and pure-systems GmbH$^2$\\~\\ +$^1$os@aspectc.org\\ +http://www.aspectc.org\\~\\ +$^2$aspectc@pure-systems.com\\ +http://www.pure-systems.com\\ +Agnetenstr. 14\\ +39106 Magdeburg\\ +Germany +}} + +% less than one half space between lines +\setstretch{1.15} +\end_preamble +\use_default_options false +\maintain_unincluded_children false +\language english +\language_package default +\inputencoding auto +\fontencoding global +\font_roman "times" "default" +\font_sans "helvet" "default" +\font_typewriter "courier" "default" +\font_math "auto" "auto" +\font_default_family sfdefault +\use_non_tex_fonts false +\font_sc false +\font_osf false +\font_sf_scale 100 100 +\font_tt_scale 100 100 +\graphics default +\default_output_format default +\output_sync 0 +\bibtex_command default +\index_command default +\paperfontsize 12 +\spacing onehalf +\use_hyperref true +\pdf_title "AC++ Compiler Manual" +\pdf_author "\\textcopyright\\ Olaf Spinczyk and pure-systems GmbH" +\pdf_subject "Documentation" +\pdf_keywords "AOP, AspectC++, ac++, pure-systems" +\pdf_bookmarks true +\pdf_bookmarksnumbered false +\pdf_bookmarksopen false +\pdf_bookmarksopenlevel 1 +\pdf_breaklinks false +\pdf_pdfborder false +\pdf_colorlinks true +\pdf_backref false +\pdf_pdfusetitle true +\pdf_quoted_options "urlcolor=blue" +\papersize a4paper +\use_geometry true +\use_package amsmath 1 +\use_package amssymb 1 +\use_package cancel 1 +\use_package esint 0 +\use_package mathdots 1 +\use_package mathtools 1 +\use_package mhchem 1 +\use_package stackrel 1 +\use_package stmaryrd 1 +\use_package undertilde 1 +\cite_engine basic +\cite_engine_type default +\biblio_style plain +\use_bibtopic false +\use_indices false +\paperorientation portrait +\suppress_date false +\justification true +\use_refstyle 0 +\index Index +\shortcut idx +\color #008000 +\end_index +\leftmargin 2.5cm +\topmargin 3cm +\rightmargin 3.5cm +\bottommargin 4cm +\secnumdepth 3 +\tocdepth 3 +\paragraph_separation indent +\paragraph_indentation default +\quotes_language english +\papercolumns 1 +\papersides 2 +\paperpagestyle fancy +\tracking_changes false +\output_changes false +\html_math_output 0 +\html_css_as_file 0 +\html_be_strict false +\end_header + +\begin_body + +\begin_layout Title + +\emph on +AC++ Compiler Manual +\end_layout + +\begin_layout Author + +\size largest +Olaf Spinczyk +\begin_inset VSpace 3mm +\end_inset + + +\begin_inset Newline newline +\end_inset + +and pure-systems GmbH +\end_layout + +\begin_layout Date +Version 2.2, March 10, 2017 +\end_layout + +\begin_layout Standard +\begin_inset CommandInset toc +LatexCommand tableofcontents + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +clearpage +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Section + +\family sans +\begin_inset CommandInset label +LatexCommand label +name "sec:Introduction" + +\end_inset + + +\family default +Introduction +\end_layout + +\begin_layout Standard +The program +\family typewriter +ac++ +\family default + is a compiler for the AspectC++ programming language. + It is implemented as a preprocessor that transforms AspectC++ code into + ordinary C++ code. + During this transformation aspect code, which is defined by aspects, is + woven statically into the component code. + Aspects are a special AspectC++ language element, which can be used to + implement crosscutting concerns in separate modules. + Aspect definitions have to be implemented in special +\begin_inset Quotes eld +\end_inset + +aspect header files +\begin_inset Quotes erd +\end_inset + +, which normally have the filename extension +\begin_inset Quotes eld +\end_inset + +.ah +\begin_inset Quotes erd +\end_inset + +. + After the code transformation the output of +\family typewriter +ac++ +\family default + can be compiled to executable code with ordinary C++ compilers like GNU + +\family typewriter +g++ +\family default +, or Microsoft VisualC++. +\end_layout + +\begin_layout Standard +More details about the features of AspectC++ can be found in the quick reference + sheet and the publications about the language and its application. + Everything is available on the AspectC++ homepage +\begin_inset Flex URL +status collapsed + +\begin_layout Plain Layout + +http://www.aspectc.org +\end_layout + +\end_inset + +, which is also a source for updates of this manual. +\end_layout + +\begin_layout Standard +The compiler's source code is freely available from the project's web site + and covered by the GPL. + For your convenience there are also binary versions of the open source + implementation available. + Besides the free GPL version, commercial licenses for +\family typewriter +ac++ +\family default +, the underlying parser and code manipulator library and the +\family typewriter +ac++ +\family default + integration into the MS Visual Studio IDE as well as commercial support + are available from pure-systems GmbH +\begin_inset Foot +status open + +\begin_layout Plain Layout +\begin_inset Flex URL +status collapsed + +\begin_layout Plain Layout + +http://www.pure-systems.com/ +\end_layout + +\end_inset + + +\end_layout + +\end_inset + +. +\end_layout + +\begin_layout Standard +This document focuses on how the +\family typewriter +ac++ +\family default + compiler works and how it is used. + The following sections are structured as follows: Section +\begin_inset CommandInset ref +LatexCommand ref +reference "sec:install" + +\end_inset + + describes how to get and install the compiler. + It is followed by section +\begin_inset CommandInset ref +LatexCommand ref +reference "sec:Invocation" + +\end_inset + +, which describes the two transformation modes of +\family typewriter +ac++ +\family default + and the meaning of the command line arguments. + Platform-specific notes are given in section +\begin_inset CommandInset ref +LatexCommand ref +reference "sec:Platform-Notes" + +\end_inset + +. + It describes the specifics of the ac++ ports and which non-standard features + of the back-end C++ compiler are supported. + Section +\begin_inset CommandInset ref +LatexCommand ref +reference "sec:Problems" + +\end_inset + + lists some known problems, common pitfalls, and unimplemented language + features. +\end_layout + +\begin_layout Section +\begin_inset CommandInset label +LatexCommand label +name "sec:install" + +\end_inset + +Download and Installation +\end_layout + +\begin_layout Standard +Binaries of +\family typewriter +ac++ +\family default + for various platforms are available for free download from the AspectC++ + homepage (see section +\begin_inset CommandInset ref +LatexCommand ref +reference "sec:Platform-Notes" + +\end_inset + + for the list and state of the +\family typewriter +ac++ +\family default + ports). + The versioning scheme is shown in table +\begin_inset CommandInset ref +LatexCommand vref +reference "tab:versioning" + +\end_inset + +. +\end_layout + +\begin_layout Standard +\begin_inset Float table +placement H +wide false +sideways false +status open + +\begin_layout Plain Layout +\align center +\begin_inset Tabular + + + + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +Scheme +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +Example +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +Kind of Release/Meaning +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +. +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +0.7 +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +A regular release 0.7. +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +.. +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +0.7.3 +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Bug fix release number 3 of 0.7 +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +.pre +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +0.8pre1 +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Pre-Release number 1 for 0.8 +\end_layout + +\end_inset + + + + +\end_inset + + +\end_layout + +\begin_layout Plain Layout +\begin_inset Caption Standard + +\begin_layout Plain Layout +\begin_inset CommandInset label +LatexCommand label +name "tab:versioning" + +\end_inset + +Versioning scheme +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +Besides the archive file with the compiler there is a README file and a + CHANGELOG file available for each release. + The README file explains the necessary steps for the installation, while + the CHANGELOG documents the changes in the corresponding release as well + as the history of changes. +\end_layout + +\begin_layout Standard +The following subsections explain how the current version of the +\family typewriter +ac++ +\family default + compiler is unpacked, installed, and configured. + This process depends on the development platform. + Skip to the appropriate part from here. +\end_layout + +\begin_layout Subsection +\begin_inset CommandInset label +LatexCommand label +name "sec:unix_install" + +\end_inset + +Linux and MacOS X +\end_layout + +\begin_layout Standard +The Linux and MacOS X installation procedures are very similar, because + all of them belong to the UNIX system family. + The +\family typewriter +ac++ +\family default + compiler and the example code is provided in a +\family typewriter +gzip +\family default +-ed +\family typewriter +tar +\family default + archive (tgz file). + It can be unpacked with the following command in any directory: +\end_layout + +\begin_layout LyX-Code +tar xzvf +\end_layout + +\begin_layout Standard +The command creates a directory aspectc++-, which contains the + +\family typewriter +ac++ +\family default + binary, the +\family typewriter +ag++ +\family default + front-end, the example code, and everything else that is needed to run + the examples like a Makefile. + To transform the examples (in the +\family typewriter +examples +\family default + directory) simply execute +\family typewriter +make +\family default + in the installation directory. + Each example is then transformed from AspectC++ code into C++ code by weaving + aspects and saved in +\family typewriter +examples/-out +\family default +. + To run the example, enter the created directory, call +\family typewriter +make +\family default + and start the executable. +\end_layout + +\begin_layout Standard +The +\family typewriter +Makefile +\family default +, which is used to compile the examples uses the command +\family typewriter +ag++ +\family default +, which is a wrapper for calling +\family typewriter +ac++ +\family default +, +\family typewriter +g++ +\family default +, and for the generation of the parser configuration file, which is needed + for +\family typewriter +ac++ +\family default +. + A separate manual for +\family typewriter +ag++ +\family default + is available from the AspectC++ web site. +\end_layout + +\begin_layout Subsection +Windows +\end_layout + +\begin_layout Standard +The Windows port of +\family typewriter +ac++ +\family default + supports the freely available Cygwin/GNU +\family typewriter +g++ +\family default + and MinGW +\family typewriter +g++ +\family default + compiler as back-end compilers. +\end_layout + +\begin_layout Standard +The installation of +\family typewriter +ac++ +\family default + in an environment with GNU +\family typewriter +g++ +\family default + and +\family typewriter +make +\family default + is similar to the UNIX-like installation described in section +\begin_inset CommandInset ref +LatexCommand ref +reference "sec:unix_install" + +\end_inset + +. + Additionally refer to section +\begin_inset CommandInset ref +LatexCommand vref +reference "sec:cygwin_back_end" + +\end_inset + +, which provides some specific information about path names in the Cygwin + environment. +\end_layout + +\begin_layout Standard +The following procedure outlines the installation for non-g++ windows command + line compilers: The +\family typewriter +ac++ +\family default + compiler and the examples are provided in a ZIP archive. + Unpack +\family typewriter +ac++ +\family default + in a directory of your choice, for instance into +\family typewriter +C: +\backslash +AC +\family default +. + The next step is to create a parser configuration file that describes predefine +d macros and standard include file paths of your back-end compiler. + The files +\family typewriter +pumabc55.cfg +\family default + and +\family typewriter +pumavc7.cfg +\family default + can be taken as examples. + An automatic generation of the config file as under UNIX systems is not + available at the moment in the free +\family typewriter +ac++ +\family default + version. +\end_layout + +\begin_layout Standard +The examples directory contains various examples that show how to write + aspects in AspectC++. + You can use the +\family typewriter +examples.bat +\family default + batch file to weave all the examples at once. + After this step the transformed example files can compiled. +\end_layout + +\begin_layout Section + +\family sans +\begin_inset CommandInset label +LatexCommand label +name "sec:Invocation" + +\end_inset + + +\family default +Invocation +\end_layout + +\begin_layout Subsection +Modes +\end_layout + +\begin_layout Standard +The +\family typewriter +ac++ +\family default + compiler supports two major transformation modes: +\end_layout + +\begin_layout Subsubsection +Whole ProgramTransformation (WPT) +\end_layout + +\begin_layout Standard +WPT mode was the first transformation mode of +\family typewriter +ac++ +\family default +. + However, it is not obsolete, because it may be useful in many cases. + In this mode +\family typewriter +ac++ +\family default + transforms all files in a project directory tree (or set of directories) + and saves the result in a different directory tree. + For each translation unit and header file a new file is generated in the + target tree with the same name. + If further transformations of the source code have to be done, either with + +\family typewriter +ac++ +\family default + or other tools, this is the mode to choose. + Even comments and whitespace remain untouched. +\end_layout + +\begin_layout Standard +The compiler performs a simple dependency check in WPT mode. + A translation unit is recompiled if either the translation unit itself + or any header file of the project has been changed. + This is not very precise but makes sure that after changing an aspect header + file all translation units are recompiled. +\end_layout + +\begin_layout Subsubsection +Single Translation Unit (STU) +\end_layout + +\begin_layout Standard +In the STU mode +\family typewriter +ac++ +\family default + must be called once for each translation unit like a normal C++ compiler. + This makes it easier to integrate +\family typewriter +ac++ +\family default + into Makefiles or IDEs. + As +\family typewriter +ac++ +\family default + can't save manipulated header files in this mode, because the unchanged + header files are needed for the next translation units, all #include directives + in the translation unit that refer to header files of the project directory + tree are expanded and, thus, saved together with the manipulated translation + unit. + The resulting files can be fed directly into a C++ compiler. + They do not depend on any other files of the project anymore. +\end_layout + +\begin_layout Standard +In the STU mode the user is responsible for checking the dependencies of + changed files and for calling the right +\family typewriter +ac++ +\family default + to transform all translation units that depend on a changed file. + The general dependency rule is that a translation unit depends on every + header file that is directly or indirectly included and every aspect header + that might affect the translation unit (normally all!) and the files they + depend on. + If you are using +\family typewriter +g++ +\family default + and +\family typewriter +make +\family default +, checking of this rule can be automized: +\end_layout + +\begin_layout LyX-Code +g++ -E -I -MM -include "*.ah" +\end_layout + +\begin_layout Standard +This call of the +\family typewriter +g++ +\family default + preprocessor prints a makefile dependency rule, which is suitable to determine + when +\family typewriter +ac++ +\family default + must be run to rebuild a tranlsation unit. +\end_layout + +\begin_layout Subsection +\begin_inset CommandInset label +LatexCommand label +name "sec:library" + +\end_inset + +Weaving in Library Code +\end_layout + +\begin_layout Standard +A C++ library consists of header files that have to be included by the client + code and an archive file that contains the object code. + If the library is implemented in AspectC++ and the client code should not + be compiled with +\family typewriter +ac++ +\family default + it is necessary to generate manipulated header files. + In the WPT mode this is done anyway. + In the STU a directory tree with all manipulated headers can be generated + with the +\family typewriter +-i +\family default + option (see +\begin_inset CommandInset ref +LatexCommand vref +reference "sec:option_i" + +\end_inset + +). +\end_layout + +\begin_layout Subsection +The Project Repository +\end_layout + +\begin_layout Standard +The +\family typewriter +ac++ +\family default + weaver internally creates a translation unit model, which contains a descriptio +n of all name and code join points as well as the weaving plan, while it + processes a C++ input file. + By using the command line option +\family typewriter +-r +\family default + (or +\family typewriter +--repository +\family default +) it is possible to save this model in a file called the +\begin_inset Quotes eld +\end_inset + +project repository +\begin_inset Quotes erd +\end_inset + +. + If the project repository already exists, ac++ will +\emph on +merge +\emph default + its translation unit model into the existing project repository. + Eventually, after translation of all C++ input files of the project, the + repository will contain a description of +\emph on +all +\emph default + potential and affected join points in the project. + When an input file is modified and re-translated, +\family typewriter +ac++ +\family default + will update the repository accordingly. +\end_layout + +\begin_layout Standard +The project model can be used for various purposes, e.g. + as input for join point visualization tools. + It can also be used for checking pointcut expressions or even their interactive + development. + This is supported by the +\family typewriter +-x +\family default + (or +\family typewriter +--expr +\family default +) command line option, which can be used to evaluate a given pointcut expression + by matching it against the join points in the the repository. + The internal structure of the project repository might be subject to future + changes. +\end_layout + +\begin_layout Subsection +Options +\end_layout + +\begin_layout Standard +Table +\begin_inset CommandInset ref +LatexCommand vref +reference "tab:options" + +\end_inset + + summarizes the platform-independent options supported by +\family typewriter +ac++ +\family default +. + Platform specific options will be explained in section +\begin_inset CommandInset ref +LatexCommand ref +reference "sec:Platform-Notes" + +\end_inset + +. + All options can either be passed as command line arguments or by the configurat +ion file +\begin_inset Foot +status open + +\begin_layout Plain Layout +In the current ac++ version some of these options are not allowed in the + config file, namely all between +\family typewriter +-v +\family default + and +\family typewriter +--no_problem... +\family default +. + +\end_layout + +\end_inset + +, which is referenced by the environment variable PUMA_CONFIG (see section + +\begin_inset CommandInset ref +LatexCommand ref +reference "sec:install" + +\end_inset + +). + '–' in any of the columns WPT or STU means that this option has no meaning + in the corresponding translation mode. +\end_layout + +\begin_layout Standard +The upper part of the table lists +\family typewriter +ac++ +\family default +-specific options, while the options in the lower part are widely-known + from other compilers like +\family typewriter +g++ +\family default +. +\end_layout + +\begin_layout Standard +\begin_inset Float table +wide false +sideways false +status open + +\begin_layout Plain Layout +\align center +\begin_inset Tabular + + + + + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +Option +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +WPT +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +STU +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +Description +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +\size small +-p|--path +\begin_inset space ~ +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Defines a project directory +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +\size small +-e|--extension +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +– +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Filename extension of translation units +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +\size small +-v|--verbose +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Level of verbosity ( +\family typewriter +0 +\family default +- +\family typewriter +9 +\family default +) +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +\size small +-c|--compile +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +– +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Name of the input file +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +\size small +-o|--output +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +– +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Name of the output file +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +\size small +-g|--generate +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +– +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Generate link-once code +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +\size small +-i|--include_files +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +– +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Generate manipulated header files +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +\size small +-a|--aspect_header +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family roman +\series medium +\shape up +\size normal +\emph off +\bar no +\noun off +\color none +Name of aspect header file or +\family default +\series default +\shape default +\emph default +\bar default + +\family typewriter +\size default +\noun default +0 +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +\size small +-r|--repository +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Name of the project repository +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +\size small +-x|--expr +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +– +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +– +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Match a pointcut expression (arg) agaist the project repository +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +\size small +--config +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Parser configuration file +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +\size small +-k|--keywords +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Allow AspectC++ keywords in normal project files +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +\size small +--introduction_depth +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Set the maximum depth for nested introductions +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +\size small +--no_line +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Disable generation of +\family typewriter +#line +\family default + directives +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +\size small +--gen_size_type +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +use a specific string as size_t +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +\size small +--warn... +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +enable a weaver warning that is suppressed by default +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +\size small +--no_warn... +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +suppress a specific weaver warning +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +\size small +--problem... +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +enable back-end compiler problem workaround (see +\begin_inset CommandInset ref +LatexCommand ref +reference "sec:back-end" + +\end_inset + +) +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +\size small +--no_problem... +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +disable back-end compiler problem workaround +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +\size small +--builtin_operators +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Support advice on built-in operator calls +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +\size small +--data_joinpoints +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Support data-based join points, e.g. + get(), set(), ... +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +\size small +--attributes +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Support C++11-attribute-based join points +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +\size small +--no_attributes +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Disable support user-defined attributes +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +\size small +-I +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Include file search path +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +\size small +-D [=] +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Macro definitions +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +\size small +-U +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Undefine a macro +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +\size small +--include +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +X +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Forced include +\end_layout + +\end_inset + + + + +\end_inset + + +\end_layout + +\begin_layout Plain Layout +\begin_inset Caption Standard + +\begin_layout Plain Layout +\begin_inset CommandInset label +LatexCommand label +name "tab:options" + +\end_inset + + +\family typewriter +ac++ +\family default + Compiler Option Summary +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Subsubsection + +\family typewriter +-p|--path +\begin_inset space ~ +\end_inset + + +\end_layout + +\begin_layout Standard +This option defines the name of a project directory tree +\family typewriter + +\family default +. + The option can be used more than once if several directories belong to + the project. + At least one +\family typewriter +-p +\family default + options is always needed when +\family typewriter +ac++ +\family default + has to transform code, even in STU mode. +\end_layout + +\begin_layout Subsubsection + +\family typewriter +-d|--dest +\end_layout + +\begin_layout Standard +With +\family typewriter +-d +\family default + a target directory for saving is selected. + It corresponds to the last +\family typewriter +-p +\family default + option. + For example, if two directories belong to a project they would be described + in STU mode with +\end_layout + +\begin_layout LyX-Code +-p dir1 -p dir2 +\end_layout + +\begin_layout Standard +and in WPT with two source/target pairs: +\end_layout + +\begin_layout LyX-Code +-p source1 -d target1 -p source2 -d target2 +\end_layout + +\begin_layout Standard +In STU mode +\family typewriter +-d +\family default + makes only sense in combination with +\family typewriter +-i +\family default + to generate header files for a library (see +\begin_inset CommandInset ref +LatexCommand vref +reference "sec:option_i" + +\end_inset + +). +\end_layout + +\begin_layout Subsubsection + +\family typewriter +-e|--extension +\end_layout + +\begin_layout Standard +In WPT mode +\family typewriter +ac++ +\family default + searches in all project directories for translation units to transform. + Translation units are identified by their filename extension. + The default is +\begin_inset Quotes eld +\end_inset + +cc +\begin_inset Quotes erd +\end_inset + +, which means that all files ending with +\begin_inset Quotes eld +\end_inset + +.cc +\begin_inset Quotes erd +\end_inset + + are handled. + By using the option +\family typewriter +-e cpp +\family default + or +\family typewriter +-e cxx +\family default + you can select other frequently used filename extensions. + The option can be used more than once, but only the last one is effective. +\end_layout + +\begin_layout Standard +In WPT mode +\family typewriter +ac++ +\family default + generates a file called +\family typewriter +ac_gen. +\family default +. + This extension is also taken from the +\family typewriter +-e +\family default + option, if one is provided. +\end_layout + +\begin_layout Subsubsection + +\family typewriter +-v|--verbose [] +\end_layout + +\begin_layout Standard +The compiler can print message on the standard output device, which describe + what it is currently doing. + These message can be printed with different levels of details. + You can select this level with the parameter +\family typewriter + +\family default +. + The range is from +\family typewriter +0 +\family default +, which means no output, to +\family typewriter +9 +\family default +, which means all details. + The option +\family typewriter +-v0 +\family default + is the same as having no +\family typewriter +-v +\family default + option at all. + +\family typewriter +-v +\family default + without +\family typewriter + +\family default + is the same as +\family typewriter +-v3 +\family default +. +\end_layout + +\begin_layout Standard +The +\family typewriter +-v +\family default + option can be used more than once but only the last one is effective. +\end_layout + +\begin_layout Subsubsection + +\family typewriter +-c|--compile +\end_layout + +\begin_layout Standard +The +\family typewriter +-c +\family default + option is used to select an input file for +\family typewriter +ac++ +\family default + in the STU mode. + Using it more than once is possible, but only one is effective. + There are no restrictions on the filename extension. + +\family typewriter +ac++ +\family default + expects that the file contains AspectC++ source code. +\end_layout + +\begin_layout Subsubsection + +\family typewriter +-o|--output +\end_layout + +\begin_layout Standard +With the -o option one can select the name of the output file, i.e. + the name of the target of the code transformation, in STU mode. + If this option is not used, the default output filename is +\family typewriter +ac.out +\family default +. + Note that the output filename is +\emph on +not +\emph default + derived from the input file name as it is done by other compilers. +\end_layout + +\begin_layout Subsubsection + +\family typewriter +\begin_inset CommandInset label +LatexCommand label +name "sec:option_i" + +\end_inset + +-i|--include_files +\end_layout + +\begin_layout Standard +The +\family typewriter +-i +\family default + option has to be used if the source code of the project should be compiled + into a library and +\family typewriter +ac++ +\family default + should run in STU mode (see +\begin_inset CommandInset ref +LatexCommand vref +reference "sec:library" + +\end_inset + +). + When a translation unit is transformed by using +\family typewriter +-c +\family default + and +\family typewriter +-o +\family default + in STU mode no manipulated header files are generated. + All include files are expanded within the generated source code. + This is fully sufficient if the translation units will then be compiled + and linked directly. + However, if a library should be provided the client needs a library file + (an archive) +\emph on +and +\emph default + manipulated header files. + These can be generated with +\family typewriter +-i +\family default +. + The generation results in a directory tree with the same structure as the + input directory tree specified by +\family typewriter +-p +\family default + exhibits. + Use the +\family typewriter +-d +\family default + option to select the target directory name(s). +\end_layout + +\begin_layout Standard +Note that at the moment only and all files with the extension +\family typewriter +.h +\family default + are considered to be include files. + This is rather inflexible and will be improved in future releases. +\end_layout + +\begin_layout Subsubsection + +\family typewriter +-a|--aspect_header +\end_layout + +\begin_layout Standard +By default +\family typewriter +ac++ +\family default + searches all files with the filename extension +\family typewriter +.ah +\family default + in the project directory tree(s) and allows all aspects defined in these + files to affect the current translation unit. + If you are looking for a simple mechanism to deactivate aspects at compile-time +, or if +\family typewriter +.ah +\family default + does not conform to your local conventions, or if not all aspects should + affect all translation units (be careful! See +\begin_inset CommandInset ref +LatexCommand vref +reference "sec:pitfalls" + +\end_inset + +), the +\family typewriter +-a +\family default + option might help. +\end_layout + +\begin_layout Standard +The option may be used more than once and each of them selects one aspect + header that has to be considered for the current translation unit in STU + mode or all translation units in WPT mode. + If no aspect header should be considered use +\family typewriter +-a0 +\family default +. +\end_layout + +\begin_layout Subsubsection + +\family typewriter +-r|--repository +\end_layout + +\begin_layout Standard +The +\begin_inset Quotes eld +\end_inset + +project repository +\begin_inset Quotes erd +\end_inset + + is an XML-based description of global information about an AspectC++ developmen +t project that is compiled with +\family typewriter +ac++ +\family default +. + It fulfills two purposes: +\end_layout + +\begin_layout Enumerate +It is a vehicle to transport information from one compiler run to another +\end_layout + +\begin_layout Enumerate +It might be used by integrated development environments to visualize the + join points where aspects affect the component code. +\begin_inset Foot +status open + +\begin_layout Plain Layout +In fact, the AspectC++ Development Tools for Eclipse (ACDT) already use + the repository to visualize matched join points. + See the ACDT homepage +\begin_inset Flex URL +status collapsed + +\begin_layout Plain Layout + +http://acdt.aspectc.org/ +\end_layout + +\end_inset + + for information on the ACDT project. +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +The +\family typewriter +-r +\family default + option is used to define the name of the project repository file. + However, this is an experimental feature. + The file format might be subject to future changes. + The uniqueness of join point IDs is only guaranteed if the project is compiled + with a project repository. + If a file with the given name does not exist, +\family typewriter +ac++ +\family default + will create a new repository file. + If the file exists, but is empty or does not contain valid data, +\family typewriter +ac++ +\family default + terminates with an error message. + A warning messages will be printed if the version of the weaver, which + created the project repository, differs from the current +\family typewriter +ac++ +\family default + version. +\end_layout + +\begin_layout Subsubsection + +\family typewriter +-x|--expr +\end_layout + +\begin_layout Standard +This option is used to match a pointcut expression, given as argument , + against a project repository file. + The project repository filename has to be provided with the +\family typewriter +-r +\family default + option. + For example the following command prints all nested class known in the + +\begin_inset Quotes eld +\end_inset + +PragmaOnceObserver +\begin_inset Quotes erd +\end_inset + + test program in the AspectC++ development tree. +\end_layout + +\begin_layout Standard +\begin_inset listings +lstparams "basicstyle={\small}" +inline false +status open + +\begin_layout Plain Layout + +prompt> ac++ -x '"%::%"' -r PragmaOnceObserver/repo.acp +\end_layout + +\begin_layout Plain Layout + +ObserverPattern.ah:12: Class "ObserverPattern::Subject" +\end_layout + +\begin_layout Plain Layout + +ObserverPattern.ah:13: Class "ObserverPattern::Observer" +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +This example illustrates the mechanism with a more complicated pointcut + expression: +\end_layout + +\begin_layout Standard +\begin_inset listings +lstparams "basicstyle={\footnotesize}" +inline false +status open + +\begin_layout Plain Layout + +prompt> ac++ -x 'call("%") && within("% main()")' -r ... +\end_layout + +\begin_layout Plain Layout + +main.cc:29: Call "void ObserverPattern::addObserver( ... +\end_layout + +\begin_layout Plain Layout + +main.cc:32: Call "void ObserverPattern::addObserver( ... +\end_layout + +\begin_layout Plain Layout + +main.cc:34: Call "void ClockTimer::Tick()" +\end_layout + +\begin_layout Plain Layout + +main.cc:37: Call "void ClockTimer::Tick()" +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +Note that pointcut expression contain quotes ( +\family typewriter + +\begin_inset Quotes eld +\end_inset + + +\family default +). + Make sure that quotes are not removed by the command shell. + On Linux systems it is a convenient solution to enclose the pointcut expression + in single quotes, e.g. + +\family typewriter +' +\begin_inset Quotes erd +\end_inset + +% +\begin_inset Quotes erd +\end_inset + +' +\family default +. +\end_layout + +\begin_layout Subsubsection + +\family typewriter +--config +\end_layout + +\begin_layout Standard +Besides setting the environment variable +\family typewriter +PUMA_CONFIG +\family default + this options can be used to set the path to the parser configuration file. +\end_layout + +\begin_layout Subsubsection + +\family typewriter +-k|--keywords +\end_layout + +\begin_layout Standard +By default the AspectC++ keywords +\family typewriter +aspect +\family default +, +\family typewriter +pointcut +\family default +, +\family typewriter +advice +\family default +, and +\family typewriter +slice +\family default + are only treated as keywords in aspect header files. + If they are used in normal project files, +\family typewriter +ac++ +\family default + interprets them as normal identifiers. + By this design decision aspects can be woven into legacy code even if the + code uses the AspectC++ keywords as normal identifiers. +\end_layout + +\begin_layout Standard +If the AspectC++ keywords should be interpreted as keywords in normal project + files as well, the command line option +\family typewriter +-k +\family default + or +\family typewriter +--keywords +\family default + has to be used. +\end_layout + +\begin_layout Standard +In files that do +\emph on +not +\emph default + belong to the project, e.g. + standard library header files, the AspectC++ keywords are always regarded + as normal identifiers, even if +\family typewriter +-k +\family default + or +\family typewriter +--keywords +\family default + is used. +\end_layout + +\begin_layout Standard +If any of the AspectC++ keywords is generated by a macro, the classification + as keyword or identifier is based on the file in which the macro expansion + takes place. + It does not depend on the location of the macro definition. +\end_layout + +\begin_layout Subsubsection + +\family typewriter +--introduction_depth +\end_layout + +\begin_layout Standard +AspectC++ introductions may affect introduced code. + This is called a +\begin_inset Quotes eld +\end_inset + +nested introduction +\begin_inset Quotes erd +\end_inset + +. + In order to avoid problems with infinitely nested introductions, +\family typewriter +ac++ +\family default + checks the +\begin_inset Quotes eld +\end_inset + +depth +\begin_inset Quotes erd +\end_inset + + of a nested introduction and does not allow a depth that exceeds the given + maximum +\family typewriter + +\family default +. + The default value for +\family typewriter + +\family default + is 10. + +\end_layout + +\begin_layout Subsubsection + +\family typewriter +--no_line +\end_layout + +\begin_layout Standard +When +\family typewriter +ac++ +\family default + manipulates files, e.g. + by inserting generated code, it also inserts +\family typewriter +#line +\family default + directives. + Inserting these directives can be disabled with the +\family typewriter +--no_line +\family default + option. + Normally, +\family typewriter +#line +\family default + directives are only generated by C preprocessors. + The directives are important for back-end compiler error messages and source + code debuggers. + Without the +\family typewriter +#line +\family default + generation these numbers correspond to the lines in the generated code, + while they correspond to the source code written by the programmer otherwise. +\end_layout + +\begin_layout Subsubsection + +\family typewriter +--gen_size_type +\end_layout + +\begin_layout Standard + +\family typewriter +ac++ +\family default + generates a +\family typewriter +new +\family default + operator, which has +\family typewriter +size_t +\family default + in its argument type list. + As the generated code shall not include the respective header file (to + avoid portability problems), the weaver normally generates the name of + the right type. + However, in case of cross-compilation the type on the target platform might + differ. + Then it is possible to provide a string with this option, which is directly + used in the constructor's argument list. +\end_layout + +\begin_layout Subsubsection + +\family typewriter +--problem... +\end_layout + +\begin_layout Standard +An option like this is used to enable a back-end compiler-specific code + generation workaround. + This is sometimes needed, because the C++ compilers differ in their degree + of standard conformance. + For details about the workarounds needed for each back-end refer to section + +\begin_inset CommandInset ref +LatexCommand ref +reference "sec:back-end" + +\end_inset + +. +\end_layout + +\begin_layout Subsubsection + +\family typewriter +--no_problem... +\end_layout + +\begin_layout Standard +This option can be used to disable a back-end compiler-specific code generation + workaround which is enabled by default. +\end_layout + +\begin_layout Subsubsection + +\family typewriter +--warn_... +\end_layout + +\begin_layout Standard +With this option the weaver is instructed to print specific warnings that + are otherwise suppressed. + Table +\begin_inset CommandInset ref +LatexCommand ref +reference "tab:warnings" + +\end_inset + + lists the names of warnings currently supported by the weaver. +\end_layout + +\begin_layout Subsubsection + +\family typewriter +--no_warn_... +\end_layout + +\begin_layout Standard +The warnings listed in table +\begin_inset CommandInset ref +LatexCommand ref +reference "tab:warnings" + +\end_inset + + can be suppressed with +\family typewriter +--no_warn_ +\family default +< +\emph on +Name +\emph default +>. +\end_layout + +\begin_layout Standard +\begin_inset Float table +wide false +sideways false +status open + +\begin_layout Plain Layout +\align center +\begin_inset Tabular + + + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +Warning Name +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +Condition +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +deprecated +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +a deprecated syntax is being used +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +macro +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +macro-generated code would have to be transformed +\end_layout + +\end_inset + + + + +\end_inset + + +\end_layout + +\begin_layout Plain Layout +\begin_inset Caption Standard + +\begin_layout Plain Layout + +\family typewriter +\begin_inset CommandInset label +LatexCommand label +name "tab:warnings" + +\end_inset + +ac++ +\family default + Warnings +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Subsubsection + +\family typewriter +--builtin_operators +\end_layout + +\begin_layout Standard +This option is needed if you want to use the pointcut function builtin(). + For more information on this feature consult the language reference manual. +\end_layout + +\begin_layout Subsubsection + +\family typewriter +--data_joinpoints +\end_layout + +\begin_layout Standard +This option is needed if you want to use the pointcut functions get(), set(), + and ref(). + For more information on this feature consult the language reference manual. +\end_layout + +\begin_layout Subsubsection + +\family typewriter +--attributes/--no_attributes +\end_layout + +\begin_layout Standard +This option is needed if you want to use attributes in C++11-Style (e.g. + [[noreturn]]). + It is enabled by default and can be disabled with +\family typewriter + --no_attributes +\family default +. + For more information on this feature consult the language reference. +\end_layout + +\begin_layout Subsubsection + +\family typewriter +-I +\end_layout + +\begin_layout Standard +The option +\family typewriter +-I +\family default + adds the directory +\family typewriter + +\family default + to the list of directories to be searched for header files. + It can be used more than once. + The compiler +\family typewriter +ac++ +\family default + needs to know all directories, where header files for the current translation + unit might be located. +\end_layout + +\begin_layout Standard +In case of system headers there are often a lot of these directories. + To make the setup of +\family typewriter +ac++ +\family default + more convenient we provide the +\family typewriter +ag++ --gen_config +\family default + command. + The command calls the +\family typewriter +g++ +\family default + compiler to get all these paths. + Users of non-supported back-end compilers have to find out this list on + their own. +\end_layout + +\begin_layout Subsubsection + +\family typewriter +-D [=] +\end_layout + +\begin_layout Standard +With +\family typewriter +-D +\family default + a preprocessor macro +\family typewriter + +\family default + will be defined. + Without the optional value assignment the macro will get the value +\family typewriter +1 +\family default +. + The option can be used more than once. +\end_layout + +\begin_layout Standard +In most cases your source code expects some standard macros to be defined + like +\family typewriter +win32 +\family default +, +\family typewriter +linux +\family default +, or +\family typewriter +i386 +\family default +. + And even if your code doesn't use them directly, they are often required + to be set correctly by system header files. + Thus, for the +\family typewriter +ac++ +\family default + parser a correct set of these macros has to be defined. + For +\family typewriter +g++ +\family default + users we provide a command called +\family typewriter +ag++ +\family default + that calls the compiler to get the list of these macros. + Users of non-supported back-end compilers have to find out this list on + their own. +\end_layout + +\begin_layout Subsubsection + +\family typewriter +-U +\end_layout + +\begin_layout Standard +This option can be used to undefine a previously defined macro. + +\end_layout + +\begin_layout Subsubsection + +\family typewriter +\begin_inset CommandInset label +LatexCommand label +name "sec:option_include" + +\end_inset + +-include +\end_layout + +\begin_layout Standard +The +\family typewriter +-include +\family default + option can be used to include a file +\family typewriter + +\family default + into the compiled translation unit(s) even though there is no explicit + +\family typewriter +#include +\family default + directive given in the source code. + If multiple +\family typewriter +-include +\family default + options are given on the command line, the files are included in the same + order (from left to right). + If you use the option in STU mode make sure that the back-end compiler + is not forced to include the same files again (read details in +\begin_inset CommandInset ref +LatexCommand vref +reference "sec:dup-forced-includes" + +\end_inset + +). +\end_layout + +\begin_layout Subsection +Examples +\end_layout + +\begin_layout Itemize + +\family typewriter +ac++ +\family default + +\begin_inset Newline newline +\end_inset + +Displays all options with a short description. +\end_layout + +\begin_layout Itemize + +\family typewriter +ac++ -I examples/Trace -p examples/Trace -d examples/Trace-out +\family default + +\begin_inset Newline newline +\end_inset + +Transforms the complete project from directory +\begin_inset Quotes eld +\end_inset + +examples/Trace +\begin_inset Quotes erd +\end_inset + + into the directory +\begin_inset Quotes eld +\end_inset + +examples/Trace-out +\begin_inset Quotes erd +\end_inset + +. + This is the whole program transformation (WPT) mode, which also performs + a simple dependency check. +\end_layout + +\begin_layout Standard +The following examples describe the compiler like interface (STU Mode). + All dependency handling has to be done by the user. +\end_layout + +\begin_layout Itemize + +\family typewriter +ac++ -c main.cc -p. + +\family default + +\begin_inset Newline newline +\end_inset + +Transforms only the translation unit +\family typewriter +main.cc +\family default +. + The default name for the output file is +\family typewriter +ac.out +\family default +. +\end_layout + +\begin_layout Itemize + +\family typewriter +ac++ -c main.cc -o main.acc -p. +\family default + +\begin_inset Newline newline +\end_inset + +Transforms the file +\family typewriter +main.cc +\family default + into the new file +\family typewriter +main.acc +\family default +. +\end_layout + +\begin_layout Itemize + +\family typewriter +ac++ -c main.cc -o main.acc -p. + -a trace.ah +\family default + +\begin_inset Newline newline +\end_inset + +Transforms the file +\family typewriter +main +\family default +. +\family typewriter +cc +\family default + into the new file +\family typewriter +main.acc +\family default + with the aspect located in +\family typewriter +trace.ah +\family default +. +\end_layout + +\begin_layout Itemize + +\family typewriter +ac++ -i -v9 -p. + -d includes +\family default + +\begin_inset Newline newline +\end_inset + +Creates the manipulated project header files and stores them into the directory + +\family typewriter +includes +\family default +. + ATTENTION: This works only once, because the +\family typewriter +includes +\family default + directory is located inside the project directory tree and the aspect header + files exists twice then. +\end_layout + +\begin_layout Section + +\family sans +\begin_inset CommandInset label +LatexCommand label +name "sec:Platform-Notes" + +\end_inset + + +\family default +Platform Notes +\end_layout + +\begin_layout Subsection +Ports +\end_layout + +\begin_layout Standard +The +\family typewriter +ac++ +\family default + compiler was originally developed on RedHat Linux systems.Today most of + the development is still done under Linux (Debian and OpenSuse), but Windows + has become a second development platform. + This means that the Windows and Linux ports are the most tested. + The MacOS X ports were compiled, because they were demanded by users, but + they are far less tested than our development platform ports. +\end_layout + +\begin_layout Subsubsection +Linux +\end_layout + +\begin_layout Standard +The +\family typewriter +ac++ +\family default + binary was tested on\SpecialChar ldots + +\end_layout + +\begin_layout Itemize +Debian 3.0, \SpecialChar ldots +, 8.0 and various Ubuntu versions. + Note that Debian and Ubuntu packages of AspectC++ are integrated into the + distributions. + They can be easily installed with +\family typewriter +\size small +apt-get install aspectc++ +\family default +\size default +. +\end_layout + +\begin_layout Itemize +OpenSuse 8.2, ..., 13.2 +\end_layout + +\begin_layout Subsubsection +Windows +\end_layout + +\begin_layout Standard +Windows systems have different filename conventions than UNIX systems. + Although ac++ was originally developed on Linux and does not use or need + the Cygwin environment, path names are allowed to contain ' +\family typewriter + +\backslash + +\family default +' characters and drive names like ' +\family typewriter +C: +\family default +'. + The UNIX filename delimiters ' +\family typewriter +/ +\family default +' are also accepted. +\end_layout + +\begin_layout Standard +\begin_inset Note Comment +status collapsed + +\begin_layout Plain Layout +The +\family typewriter +ac++ +\family default + compiler saves files always conforming to the Windows newline conventions, + i.e. + lines always end with a CR and a LF character. + As input files the UNIX and Windows conventions are accepted. +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Subsubsection +MacOS X +\end_layout + +\begin_layout Standard +No specific information available, yet. +\end_layout + +\begin_layout Subsection +\begin_inset CommandInset label +LatexCommand label +name "sec:back-end" + +\end_inset + +Back-End Compiler Support +\end_layout + +\begin_layout Standard +The C++ compiler that should be used to compile the output of +\family typewriter +ac++ +\family default + (back-end compiler) plays a very important role for +\family typewriter +ac++ +\family default +, because compilers normally come with header files, which +\family typewriter +ac++ +\family default + must be able to parse. + None of the back-end compilers listed here has totally standard conforming + header files, which makes it very hard for +\family typewriter +ac++ +\family default + to parse all this code. +\end_layout + +\begin_layout Standard +GNU +\family typewriter +g++ +\family default + (including Cygwin/GNU +\family typewriter +g++ +\family default + under Windows) and +\family typewriter +clang++ +\family default + are our best supported compilers. + Users of +\family typewriter +clang++ +\family default + can invoke it via +\family typewriter +ag++ +\family default + by using the +\family typewriter +ag++ +\family default + option +\family typewriter +--c_compiler clang++ +\family default +. +\end_layout + +\begin_layout Subsubsection +GNU g++ +\end_layout + +\begin_layout Standard +There are a lot of GNU g++ specific C++ extensions as well as several builtin + functions and types. + To enable all these extensions the option +\family typewriter +--gnu +\family default + (or +\family typewriter +--gnu-2.95 +\family default + if g++ 2.9x header files should be parsed) has to be used. + If a configuration file is generated with +\family typewriter +ag++ --gen_config +\family default +, this option will be automatically inserted (either +\family typewriter +--gnu +\family default + or +\family typewriter +--gnu-2.95 +\family default + depending on your compiler). +\end_layout + +\begin_layout Standard +The +\family typewriter +ac++ +\family default + parser aims at being compatible with g++ and nearly all of the header files + that come with g++ 3.x and 2.9x can be parsed. + The workaround to install the old g++ 2.95 header and to modify your +\family typewriter +puma.config +\family default + file so that +\family typewriter +ac++ +\family default + finds these old files while parsing your code is no longer needed starting + from version 0.8pre2. +\end_layout + +\begin_layout Standard +Compilers from the g++ family do not support explicit template specialization + in a non-namespace scope. + However, this feature is needed by ac++ in the code generation process. + A workaround for this problem is automatically enabled when you use the + +\family typewriter +--gnu +\family default + or +\family typewriter +--gnu-2.95 +\family default + option. + To explictly enable or disable the workaround use +\family typewriter +--problem_spec_scope +\family default + or +\family typewriter +--no_problem_spec_scope +\family default +. +\end_layout + +\begin_layout Subsubsection +\begin_inset CommandInset label +LatexCommand label +name "sec:cygwin_back_end" + +\end_inset + +Cygwin/GNU g++ +\end_layout + +\begin_layout Standard +The +\family typewriter +ac++ +\family default + compiler can also be used with the Cygwin/GNU g++ compiler under Windows. + Note, that +\family typewriter +ac++ +\family default + itself is not a Cygwin application and, thus, does not support Cygwin-specific + path names like +\family typewriter +/home/olaf +\family default +, which is relative to the cygwin installation directory. + If you generate your parser configuration file automatically with +\family typewriter +ag++ --gen_config +\family default + the contained include paths will automatically be converted from Cygwin + paths names to Windows path names using the +\family typewriter +cygpath +\family default + command. + However, be careful when you set the +\family typewriter +PUMA_CONFIG +\family default + environment variable or when you pass any other path name to +\family typewriter +ac++ +\family default +. + Furthermore, +\family typewriter +ac++ +\family default + and +\family typewriter +ag++ +\family default + don't support Cygwin file links. + This might also cause compilation problems. + A known problem is that in some Cygwin versions +\family typewriter +g++ +\family default + itself is a link to +\family typewriter +g++-4 +\family default +. + This means that it will not be found by +\family typewriter +ag++ +\family default +. + It helps to provide the proper compiler name with the +\family typewriter +--c_compiler g++-4 +\family default + option. +\end_layout + +\begin_layout Subsubsection +MS VC++ +\end_layout + +\begin_layout Standard +The +\family typewriter +ac++ +\family default + parser aims at being compatible with Microsoft Visual C++ 7 and later. + This compiler comes with a large number of non-standard language extensions. + To enable support for these extensions in the +\family typewriter +ac++ +\family default + parser the command line option +\family typewriter +--vc +\family default + must be provided either on the command line or in your configuration file. +\end_layout + +\begin_layout Standard +It is not recommended to use +\family typewriter +ac++ +\family default + with Visual C++ 6 as this compiler has some problems with the generated + code, even though the generated code is standard complient. +\end_layout + +\begin_layout Standard +We recently found a bug in Visual C++ 6 and 7, which is related to local + classes defined in header files. + As +\family typewriter +ac++ +\family default + sometimes generates such classes a workaround has to be enabled until Microsoft + fixes the problem. + The workaround can be enabled with the command line option +\family typewriter +--problem_local_class +\family default + and disabled with +\family typewriter +--no_problem_local_class +\family default +. + In the current +\family typewriter +ac++ +\family default + version the workaround is enabled by default if the executable was compiled + for the Windows platform. +\end_layout + +\begin_layout Section + +\family sans +\begin_inset CommandInset label +LatexCommand label +name "sec:Problems" + +\end_inset + + +\family default +Problems & Workarounds +\end_layout + +\begin_layout Subsection +\begin_inset CommandInset label +LatexCommand label +name "sec:pitfalls" + +\end_inset + +Common Pifalls +\end_layout + +\begin_layout Subsubsection +\begin_inset CommandInset label +LatexCommand label +name "sec:Include-Cycles" + +\end_inset + +Include Cycles +\end_layout + +\begin_layout Standard +In versions prior to 1.0pre1 include cycles could occur in many situations + and workarounds could not always be found. + In version 1.0pre1 include cycles can only occur in the case of aspect code + with introductions. + Advice for code join points cannot produce cycles. +\end_layout + +\begin_layout Standard +The reason for the remaining possible cycles is that +\family typewriter +ac++ +\family default + generates +\family typewriter +#include +\family default + in every file that contains the definition of a target class of an introduction. + Without this generation pattern definitions from the aspect header would + not be accessible by introduced code. + However, if the aspect header directly or indirectly includes the target + file, there is a cycle, which might cause parse errors. +\end_layout + +\begin_layout Standard +\begin_inset Float figure +wide false +sideways false +status open + +\begin_layout Plain Layout +\align center +\begin_inset Graphics + filename images/include_cycle.eps + lyxscale 50 + width 9cm + +\end_inset + + +\end_layout + +\begin_layout Plain Layout +\begin_inset Caption Standard + +\begin_layout Plain Layout +\begin_inset CommandInset label +LatexCommand label +name "fig:inc_cycle" + +\end_inset + +Include cycle problem +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +Figure +\begin_inset CommandInset ref +LatexCommand ref +reference "fig:inc_cycle" + +\end_inset + + illustrates the include cycle problem by giving an example. + Here an aspect +\family typewriter +\size small +Problem +\family default +\size default + uses the type +\family typewriter +\size small +Target +\family default +\size default + and therefore includes +\family typewriter +\size small +Target.h +\family default +\size default +. + At the same time the aspect introduces a slice into the class +\family typewriter +\size small +Target +\family default +\size default +. + As the slice might depend on definitions or +\family typewriter +\size small +#include +\family default +\size default +s in +\family typewriter +\size small +Problem.ah +\family default +\size default +, the weaver generates the +\family typewriter +\size small +#include +\begin_inset space ~ +\end_inset + +"Problem.ah +\family default +\size default +" in +\family typewriter +\size small +Target.h +\family default +\size default +. + This causes the include cycle. + Include guards (which should always be used!) avoid duplicate definitions, + but do not solve the problem. + It might still be the case that the parser complains about undefined types. +\end_layout + +\begin_layout Standard +To avoid these cycles introductions can always be separated from the aspect + by means of slices. + Slice declarations and slice member definitions can be located in arbitrary + aspect header files. + The aspect weaver will only include these aspect headers in the target + classes' header/implementation files and thereby avoid the cycle. + For a slice reference within an advice declaration even a forward declaration + of the slice is sufficient. +\end_layout + +\begin_layout Standard +\begin_inset Float figure +wide false +sideways false +status open + +\begin_layout Plain Layout +\align center +\begin_inset Graphics + filename images/no_include_cycle.eps + lyxscale 50 + width 9cm + +\end_inset + + +\end_layout + +\begin_layout Plain Layout +\begin_inset Caption Standard + +\begin_layout Plain Layout +\begin_inset CommandInset label +LatexCommand label +name "fig:no_inc_cycle" + +\end_inset + +Include cycle avoidance +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +Figure +\begin_inset CommandInset ref +LatexCommand ref +reference "fig:no_inc_cycle" + +\end_inset + + shows how the include cycle from the example in Figure +\begin_inset CommandInset ref +LatexCommand ref +reference "fig:inc_cycle" + +\end_inset + + can be avoided. + Here the function +\family typewriter +\size small +dump +\family default +\size default + is implemented in a separate slice class +\family typewriter +\size small +Dump +\family default +\size default + that is stored in an aspect header file +\family typewriter +\size small +Dump.ah +\family default +\size default +. + The implementation of +\family typewriter +\size small +Dump +\family default +\size default + could rely on defintions and +\family typewriter +\size small +#include +\family default +\size default +s in +\family typewriter +\size small +Dump.ah +\family default +\size default + ( +\family typewriter +\size small +stdio.h +\family default +\size default + in this example), but not on defintions in +\family typewriter +\size small +Problem.ah +\family default +\size default +. + Therefore, the aspect weaver generates +\family typewriter +\size small +#include +\begin_inset space ~ +\end_inset + +"Dump.ah" +\family default +\size default + and not +\family typewriter +\size small +#include +\begin_inset space ~ +\end_inset + +"Problem.ah" +\family default +\size default + in +\family typewriter +\size small +Target.h +\family default +\size default +. +\end_layout + +\begin_layout Standard +Note that in the case of +\series bold +non-inline +\series default + introductions the #include directive is generated in the file that contains + the +\begin_inset Quotes eld +\end_inset + +link-once element +\begin_inset Quotes erd +\end_inset + + of the target class, which is never a header file. + You can, for example, exploit this feature to produce cyclic class relationshi +ps. + The included file will be the aspect header file that contains the definition + of the non-inline slice member. +\end_layout + +\begin_layout Subsubsection +\begin_inset CommandInset label +LatexCommand label +name "sec:dup-forced-includes" + +\end_inset + +Duplicate Forced Includes in STU Mode +\end_layout + +\begin_layout Standard +In the Single Translation Unit (STU) mode +\family typewriter +ac++ +\family default + handles forced includes (see +\family typewriter +-include +\family default + option in section +\begin_inset CommandInset ref +LatexCommand vref +reference "sec:option_include" + +\end_inset + +) in the following way: +\end_layout + +\begin_layout Description +internal +\begin_inset space ~ +\end_inset + +includes: If the included file is part of your project, the file content + will be expanded in the compiled translation unit. +\end_layout + +\begin_layout Description +external +\begin_inset space ~ +\end_inset + +includes: If the included file is +\emph on +not +\emph default + part of the project, ac++ generates an #include directive with the absolute + path name of the file. +\end_layout + +\begin_layout Standard +In both cases the back-end compiler should not be forced to include the + same file again. + For example, +\family typewriter +g++ +\family default + users should not use the +\family typewriter +\size small +-include +\family default +\size default + option with +\family typewriter +\size small +ac++ +\family default +\size default + and with +\family typewriter +g++ +\family default +, because otherwise symbols might be defined twice. +\end_layout + +\begin_layout Subsubsection +Compiling libraries +\end_layout + +\begin_layout Standard +There are certain restrictions on the code structure if +\family typewriter +\size small +ac++ +\family default +\size default + should generate transformed header files for an aspect-oriented C++ +\emph on +library +\emph default +. + For instance, all header files need "include guards" and should not depend + on the context by which they are included. + Furthermore all headers must have the extension +\family typewriter +\size small +.h +\family default +\size default +. +\end_layout + +\begin_layout Standard +Furthermore, users have to be careful +\emph on +not +\emph default + to generate transformed headers into the project directory tree ( +\family typewriter +\size small +-p +\family default +\size default + option). + Otherwise, the +\emph on +next +\emph default + compilation of the library is likely to fail, because +\family typewriter +\size small +ac++ +\family default +\size default + would search aspect header files in the generated directory tree. +\end_layout + +\begin_layout Subsubsection +Project structure +\end_layout + +\begin_layout Standard +The AspectC++ weaver +\family typewriter +\size small +ac++ +\family default +\size default + expects that "projects" do not overlap, have no cyclic dependencies, and + can be described by a list of directory names ( +\family typewriter +\size small +-p +\family default +\size default + option). + AspectC++ needs the notion of a "project" in order to restrict the set + files that are affected by the aspects. + Sometimes big applications are organized in multiple projects within the + same workspace and have arbitrary dependencies (include relations) to each + other. + For these applications selecting the +\family typewriter +\size small +-p +\family default +\size default + option is sometimes difficult. + Often treating the whole workspace as one AspectC++ project is the best + solution. +\end_layout + +\begin_layout Subsubsection +The +\family typewriter +\size small +--aspect_header +\family default +\size default + option +\end_layout + +\begin_layout Standard +This option can be used to avoid that +\family typewriter +\size small +ac++ +\family default +\size default + automatically searches all aspect header files in the project directory + tree. + It is to be made sure by the user that each aspect header file is included + +\emph on +only once +\emph default +. + If no aspect headers should be taken into account, the option +\begin_inset Quotes eld +\end_inset + + +\family typewriter +\size small +-a 0 +\family default +\size default + +\begin_inset Quotes erd +\end_inset + + has to be used. +\end_layout + +\begin_layout Subsection +Unimplemented Features +\end_layout + +\begin_layout Subsubsection +Multi-Threading Support +\end_layout + +\begin_layout Standard +C++ has no integrated thread model like Java. + Therefore, the woven AspectC++ code cannot rely on any available thread + synchronization mechanism. + As a result the implementation of the +\family typewriter +\size small +cflow +\family default +\size default + pointcut functions is currently +\emph on +not thread-safe +\emph default +. +\end_layout + +\begin_layout Standard +We are urgently investigating how thread synchronization and thread local + storage can be integrated into AspectC++. +\end_layout + +\begin_layout Subsubsection +C++ 11/14/... +\begin_inset CommandInset label +LatexCommand label +name "subsec:C++-11" + +\end_inset + + +\end_layout + +\begin_layout Standard + +\family typewriter +ac++ +\family default + does not fully support the latest language features introduced with the + C++ 11 standard. + These features, such as lambda functions or move constructors, are accepted + by the underlying parser (the Clang framework, which is used in +\family typewriter +ac++ +\family default + 2.x), but the weaver can't deal with these features, yet. + Therefore, it is safe to use C++ 11 code as long as the code affected by + advice conforms to C++ 2003. +\end_layout + +\begin_layout Subsubsection +Parse Errors +\end_layout + +\begin_layout Standard +If +\family typewriter +\size small +ac++ +\family default +\size default + stops processing because of parse errors this might be due to an incompatibilit +y or missing feature in the underlying C++ parser. +\end_layout + +\begin_layout Standard +In the case that the error is found in your own code, i.e. + code you are able to modify, you could use the following workaround: +\end_layout + +\begin_layout LyX-Code + +\size small +#ifdef __acweaving +\end_layout + +\begin_layout LyX-Code + +\size small +// ... + simplified version of the code for ac++ +\end_layout + +\begin_layout LyX-Code + +\size small +#else +\end_layout + +\begin_layout LyX-Code + +\size small +// ... + original code +\end_layout + +\begin_layout LyX-Code + +\size small +#endif +\end_layout + +\begin_layout Standard +Even if your own AspectC++ code contains only harmless C++ code you might + experience parsing problems due to header files from libraries which your + application code includes, especially in the case of template libraries. + In this situation it might help to copy the file with the parse error into + a different directory. + Then you have to change the code in this file to avoid the error message + by simplifying it. + The final step is to extend the +\family typewriter +\size small +puma.config +\family default +\size default + file by a +\family typewriter +\size small + +\begin_inset Quotes eld +\end_inset + +-I +\family default +\size default + +\begin_inset Quotes erd +\end_inset + + entry for the directory where you placed the copy. + As the result +\family typewriter +\size small +ac++ +\family default +\size default + will now parse the simplified version while the original file is untouched + and used while the C++ compiler runs. +\end_layout + +\begin_layout Subsubsection +Templates +\end_layout + +\begin_layout Standard +Currently +\family typewriter +\size small +ac++ +\family default +\size default + is able to parse a lot of the (really highly complicated) C++ templates, + but weaving is restricted to non-templated code only. + That means you can not weave in templates or even affect calls to template + functions or members of template classes. + However, template instances can be matched by match expressions in the + pointcut language and calls to members of class templates or template functions + can be affected by advice. +\end_layout + +\begin_layout Subsubsection +Macros +\end_layout + +\begin_layout Standard +In versions prior to 1.0 the weaver was not able at all to transform code + that was generated by macro expansion. + It simply printed a warning and continued without transforming the code. + To turn this warning off the command line option +\family typewriter +\size small +--no_warn_macro +\family default +\size default + could be used (see Table +\begin_inset CommandInset ref +LatexCommand vref +reference "tab:warnings" + +\end_inset + +). +\end_layout + +\begin_layout Standard +The current solution is to expand a macro whenever it is affected by aspects + and do the weaving afterwards. + While this works fine for most cases, problems may occur if the macro definitio +n used by the (cross-)compiler differs from the one used by ac++. + Future releases will thus distinguish between macros definitions that belong + to the project and can safely be expanded and macros that were defined + outside the project. +\end_layout + +\begin_layout Subsubsection +Unimplemented Language Elements +\end_layout + +\begin_layout Description + +\family typewriter +cflow +\family default + does not yet support exposure of context information. +\end_layout + +\begin_layout Description + +\family typewriter +base +\family default + only works as expected if all classes that should be matched by the pointcut + function's argument are known in the translation unit. + Therefore, the aspect header file has to contain the right set of include + directives. +\end_layout + +\begin_layout Subsubsection +Support for Plain C Code +\end_layout + +\begin_layout Standard +Currently +\family typewriter +\size small +ac++ +\family default +\size default + generates C++ code, which cannot be compiled by a C compiler. + As for many hardware platforms in the embedded domain no C++ compiler is + available we are actively looking for a solution. +\end_layout + +\begin_layout Subsubsection +Support for C++ language extensions +\end_layout + +\begin_layout Standard +The parser does not yet fully support the language features of C++ 11 and + more recent standards (see +\begin_inset CommandInset ref +LatexCommand ref +reference "subsec:C++-11" + +\end_inset + +). + Furthermore, most but not all g++ specific language extensions are implemented. +\end_layout + +\begin_layout Subsubsection +Constructor/Destructor Generation +\end_layout + +\begin_layout Standard +If advice for construction/destruction joinpoints is given and no constructor/de +structor is defined explicitly, +\family typewriter +\size small +ac++ +\family default +\size default + will generate it. + However, currently +\family typewriter +\size small +ac++ +\family default +\size default + assumes that the copy constructor has one argument of type +\begin_inset Quotes eld +\end_inset + + +\family typewriter +\size small +const & +\family default +\size default + +\begin_inset Quotes erd +\end_inset + +. + This leads to problems if the implicitly declared copy constructor has + an argument of type +\begin_inset Quotes eld +\end_inset + + +\family typewriter +\size small +& +\family default +\size default + +\begin_inset Quotes erd +\end_inset + +. + Therefore, you should not define construction/destruction advice for classes + with this copy constructor signature. +\end_layout + +\begin_layout Subsubsection +Functions with variable argument lists +\end_layout + +\begin_layout Standard +There is no support for execution advice on functions with variable argument + lists. + A warning will be issued. + There is no portable way to generate a wrapper function for this class + of functions. +\end_layout + +\begin_layout Subsubsection +Restrictions on calling +\family typewriter +\size small +tjp->proceed() +\end_layout + +\begin_layout Standard +Due to a problem with result object construction/destruction of intercepted + functions, the +\family typewriter +\size small +tjp->proceed() +\family default +\size default + function may only be called +\emph on +once +\emph default + during around advice. +\end_layout + +\begin_layout Subsubsection +Advice on advice +\end_layout + +\begin_layout Standard +Join points within advice code are not matched by pointcut expressions. +\end_layout + +\begin_layout Subsubsection +JoinPoint-API for slices +\end_layout + +\begin_layout Standard +There is a joinpoint-API for slices introduced into a target class. + It provides static type information about the target's baseclasses and + members as well as dynamic information, such as a pointer to each member. + However, the baseclass part of the slice may not access the JoinPoint-API. + This is partly natural, as, for instance, member types might depend on + the introduced baseclass. + Yet, not even the target's classname is available. + Future versions might make this possible. +\end_layout + +\begin_layout Standard +The identifier 'JoinPoint' is only to be used to access the joinpoint-API. + Even though it would conceptually make sense to allow, for instance, a + local variable to be called 'JoinPoint', it is not supported, yet. +\end_layout + +\begin_layout Standard +\begin_inset Newpage newpage +\end_inset + + +\end_layout + +\begin_layout Section +Code Transformation Patterns +\end_layout + +\begin_layout Standard +This appendix documents some internals of the +\family typewriter +ac++ +\family default + weaver implementation. +\end_layout + +\begin_layout Subsection +Inclusion of Aspect Header Files +\end_layout + +\begin_layout Standard +The weaver has to guarantee that aspect header files are only compiled in + a translation unit if they are affecting the shadows of code join point + that are located within the translation unit. + If an aspect header has to be included because of this reason, the same + check has to be performed again, because the aspect header might contain + code join points that are affected by other aspects. +\end_layout + +\begin_layout Standard +In order to implement this behavior a forward declaration of the advice + invocation function is generated and a macro +\family typewriter +__ac_need_< +\emph on +mangled_ah_filename +\emph default +> +\family default + is defined in each file that contains a join point shadow, which is affected + by an aspect that is defined in an aspect header whose mangled files name + is +\family typewriter +< +\emph on +mangled_ah_filename +\emph default +> +\family default +. + Multiple inclusions shall be avoided. + Therefore, another macro +\family typewriter +__ac_have_< +\emph on +mangled_ah_filename +\emph default +> +\family default + is set wherever an aspect header is included by generated code. + The following code is an example that shows the code which is generated + at the end of each translation unit for each known aspect header of the + project: +\end_layout + +\begin_layout LyX-Code +#ifdef __ac_need_< +\family typewriter +\emph on +mangled_ah_ +\family default +1 +\emph default +> +\end_layout + +\begin_layout LyX-Code +#ifndef __ac_have_< +\family typewriter +\emph on +mangled_ah_ +\family default +1 +\emph default +> +\end_layout + +\begin_layout LyX-Code +#define __ac_have_< +\family typewriter +\emph on +mangled_ah_ +\family default +1 +\emph default +> +\end_layout + +\begin_layout LyX-Code +#include " +\emph on +ah_1 +\emph default +" +\end_layout + +\begin_layout LyX-Code +#endif +\end_layout + +\begin_layout LyX-Code +// other aspect headers that are needed if ah_1 is needed +\end_layout + +\begin_layout LyX-Code +#ifndef __ac_have_< +\family typewriter +\emph on +mangled_ah_ +\family default +\emph default +4> +\end_layout + +\begin_layout LyX-Code +#define __ac_have_< +\family typewriter +\emph on +mangled_ah_ +\family default +\emph default +4> +\end_layout + +\begin_layout LyX-Code +#include " +\emph on +ah_ +\emph default +4" +\end_layout + +\begin_layout LyX-Code +#endif +\end_layout + +\begin_layout LyX-Code +#endif // __ac_need_< +\family typewriter +\emph on +mangled_ah_ +\family default +1 +\emph default +> +\end_layout + +\begin_layout Standard +This code transformation pattern might result in multiple +\family typewriter +#include +\family default + directives for the same aspect header files. + This is correct, as there might be cyclic dependencies between the aspect + headers. +\end_layout + +\begin_layout LyX-Code + +\end_layout + +\end_body +\end_document diff --git a/AspectC++/doc/CompilerManual/images b/AspectC++/doc/CompilerManual/images new file mode 120000 index 0000000..5e67573 --- /dev/null +++ b/AspectC++/doc/CompilerManual/images @@ -0,0 +1 @@ +../images \ No newline at end of file diff --git a/AspectC++/doc/LanguageReference/ac-languageref-ru.odt b/AspectC++/doc/LanguageReference/ac-languageref-ru.odt new file mode 100644 index 0000000..11cbd84 Binary files /dev/null and b/AspectC++/doc/LanguageReference/ac-languageref-ru.odt differ diff --git a/AspectC++/doc/LanguageReference/ac-languageref-ru.pdf b/AspectC++/doc/LanguageReference/ac-languageref-ru.pdf new file mode 100644 index 0000000..21acc14 Binary files /dev/null and b/AspectC++/doc/LanguageReference/ac-languageref-ru.pdf differ diff --git a/AspectC++/doc/LanguageReference/ac-languageref.lyx b/AspectC++/doc/LanguageReference/ac-languageref.lyx new file mode 100644 index 0000000..0010cfc --- /dev/null +++ b/AspectC++/doc/LanguageReference/ac-languageref.lyx @@ -0,0 +1,24007 @@ +#LyX 2.2 created this file. For more info see http://www.lyx.org/ +\lyxformat 508 +\begin_document +\begin_header +\save_transient_properties true +\origin unavailable +\textclass article +\begin_preamble +% +% setup fancyhdr +% +\RequirePackage{fancyhdr} +\fancypagestyle{plain}{% + % + % two side book class setup + % odd page - left head: chapter - left foot: page number + % even page - right head: section - right foot: page number + % no head on plain pages + % + \fancyhf{}% + \fancyhead[LE,RO]{\slshape \rightmark} + \fancyhead[LO,RE]{\slshape \leftmark} + \fancyfoot[LE,RO]{\bfseries \thepage} + % + % rules for head and foot + % also on plain pages + % + \renewcommand{\headrulewidth}{.4pt} + \renewcommand{\footrulewidth}{.4pt} + \renewcommand{\plainfootrulewidth}{.4pt} +} +% +% Variables to change some details +% +% version number for this document +% +\newcommand{\@version}{1} +\newcommand{\version}[1]{ \renewcommand{\@version}{#1} } +% +% +\newcommand\pslogo[1]{\gdef\@pslogo{#1}} +\pslogo{} +% +\newcommand\otherlogo[1]{\gdef\@otherlogo{#1}} +\otherlogo{} +% +\newcommand\remark[1]{\gdef\@remark{#1}} +\remark{} +% +\newcommand{\doctype}[1]{\gdef\@doctype{#1}} +\doctype{Studie:} +% +\newcommand\credit[1]{\gdef\@credit{#1}} +\credit{Diese Studie wurde durch die\par +\vskip .3cm +pure-systems GmbH\par +Agnetenstr. 14\par +39106 Magdeburg\par +http://www.pure-systems.com\par +\vskip .3cm +erstellt.} +% +% +% +\newcommand\layoutlogos{ + + \newlength{\@pslogowidth} + \newlength{\@otherlogowidth} + \settowidth{\@otherlogowidth}{\@otherlogo} + \settowidth{\@pslogowidth}{\@pslogo} + + \noindent + \begin{minipage}{\@otherlogowidth} + {\@otherlogo} + \end{minipage} + \hspace*{\fill} + \begin{minipage}{\@pslogowidth} + {\@pslogo} + \end{minipage} +} + +% +% redefine \maketitle macro +% +\renewcommand{\maketitle}{ + \null + \thispagestyle{empty} + + {\layoutlogos} + + \vskip 3cm + \begin{center}\leavevmode + {\Huge\raggedright {\@doctype}\\ {\@title}\par} + \rule{\textwidth}{1mm} + \vskip 3mm + {\Large\raggedleft {\@author}\par} + \vskip 15mm + {\Large\raggedleft {\@date}\par} + \end{center} + \vfill + {\large\raggedleft {\@remark}\par} + \vskip 1cm + \null +% + \newpage +% + \null + \thispagestyle{empty} + \vfill + {\@credit} + \null + \cleardoublepage +} + +%-------------------------------------------------------------------- +% setup pure-systems style +%-------------------------------------------------------------------- +\doctype{Documentation:} +\credit{ + \noindent\small{(c) 2017 Olaf Spinczyk and pure-systems GmbH\\All rights reserved.}} +\pslogo{ + \resizebox{6cm}{!}{\includegraphics{images/ps-logo}}} +\otherlogo{ + \resizebox{4cm}{!}{\includegraphics{images/ac++logo}}} +\sloppy +\remark{ + \small{(c) 2017 Olaf Spinczyk$^1$ and pure-systems GmbH$^2$\\~\\ +$^1$\href{mailto:os@aspectc.org}{os@aspectc.org}\\ +\href{http://www.aspectc.org}{www.aspectc.org}\\~\\ +$^2$\href{mailto:aspectc@pure-systems.com}{aspectc@pure-systems.com}\\ +\href{http://www.pure-systems.com}{www.pure-systems.com}\\ +Agnetenstr. 14\\ +39106 Magdeburg\\ +Germany +}} + +%-------------------------------------------------------------------- +% place footnotes at the bottom of the page +%-------------------------------------------------------------------- +\renewcommand\footnoterule{% + \vfill + \kern-3\p@ + \hrule\@width.3\columnwidth + \kern2.6\p@} + +%-------------------------------------------------------------------- +% leave less than one and a half space between lines +%-------------------------------------------------------------------- +\setstretch{1.15} + +%-------------------------------------------------------------------- +% 'list of examples' environment +%-------------------------------------------------------------------- +\newcommand\examplesname{List of Examples} +\newenvironment{examples} + {\section*{\examplesname}% + \@mkboth{\MakeUppercase\examplesname}% + {\MakeUppercase\examplesname}% + \thispagestyle{plain} + \parindent\z@ \parskip\z@ \@plus .3\p@\relax} % + {\clearpage} + +%-------------------------------------------------------------------- +% environment 'comment' +%-------------------------------------------------------------------- +\usepackage{comment} + +%-------------------------------------------------------------------- +% add 'Index' to table of contents +%-------------------------------------------------------------------- +\let\old@theindex\theindex +\def\theindex{ + \old@theindex + \addcontentsline{toc}{section}{\indexname}} + +%-------------------------------------------------------------------- +% landscape mode +%-------------------------------------------------------------------- +\usepackage{pdflscape} + +%-------------------------------------------------------------------- +% caption of longtables +%-------------------------------------------------------------------- +\usepackage{capt-of} +\end_preamble +\use_default_options false +\maintain_unincluded_children false +\language english +\language_package default +\inputencoding auto +\fontencoding global +\font_roman "times" "default" +\font_sans "helvet" "default" +\font_typewriter "courier" "default" +\font_math "auto" "auto" +\font_default_family sfdefault +\use_non_tex_fonts false +\font_sc false +\font_osf false +\font_sf_scale 100 100 +\font_tt_scale 100 100 +\graphics default +\default_output_format default +\output_sync 0 +\bibtex_command default +\index_command default +\paperfontsize 12 +\spacing onehalf +\use_hyperref true +\pdf_title "AspectC++ Language Reference" +\pdf_author "\\textcopyright\\ Olaf Spinczyk and pure-systems GmbH" +\pdf_subject "Documentation" +\pdf_keywords "AOP, AspectC++, ac++, pure-systems" +\pdf_bookmarks true +\pdf_bookmarksnumbered false +\pdf_bookmarksopen false +\pdf_bookmarksopenlevel 1 +\pdf_breaklinks false +\pdf_pdfborder false +\pdf_colorlinks true +\pdf_backref false +\pdf_pdfusetitle true +\pdf_quoted_options "urlcolor=blue" +\papersize default +\use_geometry true +\use_package amsmath 1 +\use_package amssymb 1 +\use_package cancel 1 +\use_package esint 0 +\use_package mathdots 1 +\use_package mathtools 1 +\use_package mhchem 1 +\use_package stackrel 1 +\use_package stmaryrd 1 +\use_package undertilde 1 +\cite_engine basic +\cite_engine_type default +\biblio_style plain +\use_bibtopic false +\use_indices false +\paperorientation portrait +\suppress_date false +\justification true +\use_refstyle 0 +\index Index +\shortcut idx +\color #008000 +\end_index +\leftmargin 2.5cm +\topmargin 3cm +\rightmargin 3.5cm +\bottommargin 4cm +\secnumdepth 3 +\tocdepth 3 +\paragraph_separation indent +\paragraph_indentation default +\quotes_language english +\papercolumns 1 +\papersides 2 +\paperpagestyle fancy +\tracking_changes false +\output_changes false +\html_math_output 0 +\html_css_as_file 0 +\html_be_strict false +\end_header + +\begin_body + +\begin_layout Title + +\emph on +AspectC++ Language Reference +\end_layout + +\begin_layout Author + +\size largest +Olaf Spinczyk and +\begin_inset VSpace 3mm +\end_inset + + +\begin_inset Newline newline +\end_inset + +pure-systems GmbH +\end_layout + +\begin_layout Date +Version 2.2, March 10, 2017 +\end_layout + +\begin_layout Standard +\begin_inset CommandInset toc +LatexCommand tableofcontents + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +clearpage +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Section +About +\end_layout + +\begin_layout Standard +This document is intended to be used as a reference book for the AspectC++ + language elements. + It describes in-depth the use and meaning of each element providing examples. + For experienced users the contents of this document are summarized in the + +\begin_inset CommandInset href +LatexCommand href +name "AspectC++ Quick Reference" +target "http://www.aspectc.org/doc/ac-quickref.pdf" + +\end_inset + +. + +\begin_inset Note Note +status open + +\begin_layout Plain Layout +A step-by-step introduction how to program with AspectC++ is given in the + +\begin_inset CommandInset href +LatexCommand href +name "AspectC++ Programming Guide" +target "http://www.aspectc.org/Documentation.5.0.html" + +\end_inset + + +\begin_inset Foot +status collapsed + +\begin_layout Plain Layout +Sorry, but the Programming Guide is not written yet +\family typewriter +:-( +\end_layout + +\end_inset + +. + +\end_layout + +\end_inset + +Detailed information about the AspectC++ compiler +\family typewriter +\series bold +ac++ +\family default +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +ac++@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{ac++} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + can be looked up in the +\begin_inset CommandInset href +LatexCommand href +name "AspectC++ Compiler Manual" +target "http://www.aspectc.org/doc/ac-compilerman.pdf" + +\end_inset + +. + +\end_layout + +\begin_layout Standard +AspectC++ is an aspect-oriented extension to the C++ language +\begin_inset Foot +status open + +\begin_layout Plain Layout +defined in the ISO/IEC 14882:1998(E) standard +\end_layout + +\end_inset + +. + It is similar to AspectJ +\begin_inset Foot +status open + +\begin_layout Plain Layout +\begin_inset CommandInset href +LatexCommand href +name "http://www.eclipse.org/aspectj/" +target "http://www.eclipse.org/aspectj/" + +\end_inset + + +\end_layout + +\end_inset + + but, due to the nature of C++, in some points completely different. + The first part of this document introduces the basic concepts of the AspectC++ + language. + The in-depth description of each language element is subject of the second + part. +\end_layout + +\begin_layout Section +Basic Concepts +\end_layout + +\begin_layout Subsection +Pointcuts +\begin_inset Index idx +status open + +\begin_layout Plain Layout +pointcut +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +Aspects in AspectC++ implement crosscutting concerns +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +crosscutting concern +\end_layout + +\end_inset + + in a modular way. + With this in mind the most important element of the AspectC++ language + is the pointcut. + Pointcuts describe a set of join points +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +join point +\end_layout + +\end_inset + + by determining on which condition an aspect shall take effect. + Thereby each join point can either refer to a function, a type/class, a + variable, or a point from which a join point is accessed so that this condition + can be for instance the event of reaching a designated code position or + the allocation of a variable with a certain value. + Depending on the kind of pointcuts, they are evaluated at compile time + or at runtime. +\end_layout + +\begin_layout Subsubsection +Match Expressions +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +match expression +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +search pattern!match expression +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +There are two types of pointcuts in AspectC++: +\emph on +code pointcuts +\emph default + and +\emph on +name pointcuts +\emph default +. + Name pointcuts +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +name pointcut +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut!name +\end_layout + +\end_inset + + describe a set of (statically) known program entities like types/classes, + variables, functions, or namespaces. + All name pointcuts are based on match expressions. + A match expression can be understood as a search pattern +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +search pattern +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +match expression!search pattern +\end_layout + +\end_inset + +. + In such a search pattern the special character +\begin_inset Quotes eld +\end_inset + +% +\begin_inset Quotes erd +\end_inset + + is interpreted as a wildcard for names or parts of a signature. + The special character sequence +\begin_inset Quotes eld +\end_inset + +… +\begin_inset Quotes erd +\end_inset + + matches any number of parameters in a function signature or any number + of scopes in a qualified name. + A match expression is a quoted string. +\end_layout + +\begin_layout Subsubsection* +Example: match expressions (name pointcuts) +\begin_inset CommandInset label +LatexCommand label +name "exa:match-expressions" + +\end_inset + + +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +"int +\series default + +\begin_inset space ~ +\end_inset + + +\series medium +C::%(...)" +\family default +\series default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +matches all member functions of the class C that return an +\family typewriter +int +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +"%List" +\family default +\series default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +matches any namespace, class, struct, union, or enum whose name ends with + +\family typewriter +List +\family default +. + In case of a matched namespace or class the match expression also matches + entities inside the namespace resp. + class. + For more information see section +\begin_inset CommandInset ref +LatexCommand ref +reference "subsec:Namspace-and-Class" + +\end_inset + +. +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +"% +\family default +\series default + +\family typewriter +printf(const char *, ...)" +\family default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +matches the function +\family typewriter +printf +\family default + (defined in the global scope) having at least one parameter of type +\family typewriter +const +\begin_inset space ~ +\end_inset + +char +\begin_inset space ~ +\end_inset + +* +\family default + and returning any type +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +"const +\series default + +\begin_inset space ~ +\end_inset + + +\series medium +%& +\begin_inset space ~ +\end_inset + +...::%(...)" +\family default +\series default + +\family typewriter + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\family default +matches all functions that return a reference to a constant object +\end_layout + +\begin_layout Standard +Match expressions select program entities with respect to their definition + scope, their type, and their name. + A detailed description of the match expression semantics follows in section + +\begin_inset CommandInset ref +LatexCommand vref +reference "sec:Match-Expressions" + +\end_inset + +. + The grammar which defines syntactically valid match expressions is shown + in appendix +\begin_inset CommandInset ref +LatexCommand vref +reference "sec:Match-Expression-Grammar" + +\end_inset + +. + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +match expression +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +search pattern!match expression +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Subsubsection +Pointcut Expressions +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut!expression +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +The other type of pointcuts, the code pointcuts +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +code pointcut +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut!code +\end_layout + +\end_inset + +, describe an intersection through the set of the points in the control + flow +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +control flow +\end_layout + +\end_inset + + of a program. + A code pointcut can refer to a call or execution point of a function, to + a call of a built-in operator or and to write and read points of member + variables and global variables. + They can only be created with the help of name pointcuts because all join + points supported by AspectC++ require at least one name to be defined. + This is done by calling predefined pointcut functions +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut function +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut!function +\end_layout + +\end_inset + + in a pointcut expression that expect a pointcut as argument. + Such a pointcut function is for instance +\series bold +within +\series default +( +\emph on +pointcut +\emph default +), which filters all join points that are within the functions or classes + in the given pointcut. +\end_layout + +\begin_layout Standard +Name and code pointcuts can be combined in pointcut expressions by using + the algebraic operators +\begin_inset Quotes eld +\end_inset + +&& +\begin_inset Quotes erd +\end_inset + +, +\begin_inset Quotes eld +\end_inset + +|| +\begin_inset Quotes erd +\end_inset + +, and +\begin_inset Quotes eld +\end_inset + +! +\begin_inset Quotes erd +\end_inset + +. +\end_layout + +\begin_layout Subsubsection* +Example: pointcut expressions +\begin_inset CommandInset label +LatexCommand label +name "exa:pointcut-expressions" + +\end_inset + + +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +"%List" +\begin_inset space ~ +\end_inset + +&& +\begin_inset space ~ +\end_inset + +!derived("Queue") +\family default +\series default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +describes the set of classes with names that end with +\begin_inset Quotes eld +\end_inset + +List +\begin_inset Quotes erd +\end_inset + + and that are not derived from the class +\family typewriter +Queue +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +call("void +\family default +\series default + +\family typewriter +draw() +\series medium +") +\begin_inset space ~ +\end_inset + + +\series default +&& +\begin_inset space ~ +\end_inset + +within +\series medium +(" +\series default +Shape +\series medium +") +\family default +\series default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +describes the set of calls to the function +\family typewriter +draw +\family default + that are within methods of the class +\family typewriter +Shape +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut!expression +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Subsubsection +Types of Join Points +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +join point +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +According to the two types of pointcuts supported by AspectC++ there are + also two coarse types of join points: name join points and code join points. + As diagramed in figure +\begin_inset CommandInset ref +LatexCommand ref +reference "fig:acpp_model_inheri_only_less" + +\end_inset + + both of these have sub join point types. + The types +\family typewriter +Any +\family default +, +\family typewriter +Name +\family default +, +\family typewriter +Code +\family default + and +\family typewriter +Access +\family default + are abstract types and exist just for categorizing the other join point + types. +\begin_inset Newline newline +\end_inset + + +\begin_inset Float figure +placement h +wide false +sideways false +status open + +\begin_layout Plain Layout +\align center +\begin_inset Graphics + filename images/acmodel_inheri_only_less.eps + width 15cm + +\end_inset + + +\end_layout + +\begin_layout Plain Layout +\begin_inset Caption Standard + +\begin_layout Plain Layout +\begin_inset CommandInset label +LatexCommand label +name "fig:acpp_model_inheri_only_less" + +\end_inset + +join point type hierarchy +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Newline newline +\end_inset + +Figure +\begin_inset CommandInset ref +LatexCommand ref +reference "fig:acpp_model_inheri_only_less" + +\end_inset + + is extracted from the AspectC++ project repository hierarchy, that can + be found in appendix +\begin_inset CommandInset ref +LatexCommand ref +reference "sec:appendix:projectmodel_structure" + +\end_inset + +. +\end_layout + +\begin_layout Standard +Based on a short code fragment the differences and relations between the + types of join points shall be clarified. +\end_layout + +\begin_layout Standard +\begin_inset CommandInset label +LatexCommand label +name "exa:shape_example_code" + +\end_inset + + +\begin_inset listings +lstparams "numbers=left,numberstyle={\footnotesize},basicstyle={\ttfamily},breaklines=true,showstringspaces=false,tabsize=2" +inline false +status open + +\begin_layout Plain Layout + +class Shape { /*...*/ }; +\end_layout + +\begin_layout Plain Layout + +void draw(Shape& shape) { /*...*/ } +\end_layout + +\begin_layout Plain Layout + +\end_layout + +\begin_layout Plain Layout + +namespace Circle { +\end_layout + +\begin_layout Plain Layout + + typedef int PRECISION; +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + class S_Circle : public Shape { +\end_layout + +\begin_layout Plain Layout + + PRECISION m_radius; +\end_layout + +\begin_layout Plain Layout + + public: +\end_layout + +\begin_layout Plain Layout + + void radius(PRECISION r) { +\end_layout + +\begin_layout Plain Layout + + m_radius = r; +\end_layout + +\begin_layout Plain Layout + + } +\end_layout + +\begin_layout Plain Layout + + ~S_Circle() { /*...*/ } +\end_layout + +\begin_layout Plain Layout + + }; +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + void draw(PRECISION r) { +\end_layout + +\begin_layout Plain Layout + + S_Circle circle; +\end_layout + +\begin_layout Plain Layout + + circle.radius(r); +\end_layout + +\begin_layout Plain Layout + + draw(circle); +\end_layout + +\begin_layout Plain Layout + + } +\end_layout + +\begin_layout Plain Layout + +} +\end_layout + +\begin_layout Plain Layout + +\end_layout + +\begin_layout Plain Layout + +int main() { +\end_layout + +\begin_layout Plain Layout + + Circle::draw(10); +\end_layout + +\begin_layout Plain Layout + + return 0; +\end_layout + +\begin_layout Plain Layout + +} +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +Code join points +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +code join point +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +join point!code +\end_layout + +\end_inset + + are used to form code pointcuts and name join points (i.e. +\begin_inset space ~ +\end_inset + +names) are used to form name pointcuts. + Figure +\begin_inset CommandInset ref +LatexCommand vref +reference "fig:join-points-new" + +\end_inset + + shows join points of the code fragment above and how they correlate. + Built-in constructors, destructors and uncalled operators are not shown. + Additionally appendix +\begin_inset CommandInset ref +LatexCommand ref +reference "sec:Project-Repository-File" + +\end_inset + + shows the contents of the project repository +\begin_inset Foot +status open + +\begin_layout Plain Layout +The AspectC++ project repository is a file, that contains the internal AspectC++ + model as xml-tree. + The actual style and format of the content may change at any time. + For more information see the AspectC++ Compiler Manual. +\end_layout + +\end_inset + + for the code fragment. +\end_layout + +\begin_layout Standard +\begin_inset Float figure +placement H +wide false +sideways false +status open + +\begin_layout Plain Layout +\align center +\begin_inset Graphics + filename images/JoinPointModelNew.eps + width 15cm + +\end_inset + + +\end_layout + +\begin_layout Plain Layout +\begin_inset Caption Standard + +\begin_layout Plain Layout +\begin_inset CommandInset label +LatexCommand label +name "fig:join-points-new" + +\end_inset + +join points and their relations +\end_layout + +\end_inset + + +\end_layout + +\end_inset + +Every +\series bold +execution +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +execution join point +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +join point!execution +\end_layout + +\end_inset + + join point is associated with the name of an executable function. + Pure virtual functions +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pure virtual!functions +\end_layout + +\end_inset + + are not executable. + Thus, advice code for execution join points would never be triggered for + this kind of function. + However, the call of such a function, i.e. +\begin_inset space ~ +\end_inset + +a +\series bold +call +\series default + join point with this function as target, is absolutely possible. + Furthermore there are no execution join points for built-in operator functions. +\end_layout + +\begin_layout Standard +Every +\series bold +call +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +call join point +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +join point!call +\end_layout + +\end_inset + + or +\series bold +builtin +\series default + +\begin_inset Index idx +status open + +\begin_layout Plain Layout +builtin join point +\end_layout + +\end_inset + + +\begin_inset Index idx +status open + +\begin_layout Plain Layout +join point!builtin +\end_layout + +\end_inset + + join point is associated with two names: the name of the source and the + target function (in case of builtin this is the global built-in operator + function) of a function call. + As there can be multiple function calls within the same function, each + function name can be associated with a list of +\series bold +call +\series default + join points +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +join point +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + and +\series bold + builtin +\series default + join points +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +join point +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + +. + The same holds for +\series bold +set +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +set join point +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +join point!set +\end_layout + +\end_inset + + and +\series bold +get +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +get join point +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +join point!get +\end_layout + +\end_inset + + join points, which represent write resp. +\begin_inset space ~ +\end_inset + +read operations on data members or global variables. + Each of these join points is associated with the name of the function that + contains the join point and the name of the accessed member variable or + global variable. + A +\series bold +construction +\series default + join point means the class specific instruction sequence executed when + an instance is created. + In analogy, a +\series bold +destruction +\series default + join point means the object destruction. +\end_layout + +\begin_layout Subsubsection +Pointcut declarations +\series bold + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut!declaration +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +AspectC++ provides the possibility to name pointcut +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +name pointcut +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut!name +\end_layout + +\end_inset + + expressions with the help of pointcut declarations. + This makes it possible to reuse pointcut expressions in different parts + of a program. + They are allowed where C++ declarations are allowed. + Thereby the usual C++ name lookup and inheritance rules are also applicable + for pointcut declarations. +\end_layout + +\begin_layout Standard +A pointcut declaration is introduced by the keyword +\family typewriter +pointcut +\family default +. + +\end_layout + +\begin_layout Subsubsection* +Example: pointcut declaration +\begin_inset CommandInset label +LatexCommand label +name "exa:pointcut-declaration" + +\end_inset + + +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +pointcut +\series default + +\begin_inset space ~ +\end_inset + + +\series medium +lists() +\begin_inset space ~ +\end_inset + += +\series default + +\begin_inset space ~ +\end_inset + + +\series medium +derived("List"); +\family default +\series default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\family typewriter +lists +\family default + can now be used everywhere in a program where a pointcut expression can + be used to refer to +\family typewriter +derived("List") +\end_layout + +\begin_layout Standard +Furthermore pointcut declarations can be used to define pure virtual pointcuts +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pure virtual!pointcut +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut!pure virtual +\end_layout + +\end_inset + +. + This enables the possibility of having re-usable abstract aspects +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +aspect +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +abstract aspect +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +aspect!abstract +\end_layout + +\end_inset + + that are discussed in section +\begin_inset CommandInset ref +LatexCommand ref +reference "subsec:Aspects" + +\end_inset + +. + The syntax of pure virtual pointcut declarations is the same as for usual + pointcut declarations except the keyword +\family typewriter +virtual +\family default + following +\family typewriter +pointcut +\family default + and that the pointcut expression is +\begin_inset Quotes eld +\end_inset + +0 +\begin_inset Quotes erd +\end_inset + +. +\end_layout + +\begin_layout Subsubsection* +Example: pure virtual pointcut declaration +\begin_inset CommandInset label +LatexCommand label +name "exa:pure-virtual" + +\end_inset + + +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +pointcut +\series default + +\begin_inset space ~ +\end_inset + + +\series medium +virtual +\begin_inset space ~ +\end_inset + +methods() +\begin_inset space ~ +\end_inset + += +\series default + +\begin_inset space ~ +\end_inset + + +\series medium +0; +\family default +\series default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\family typewriter +methods +\family default + is a pure virtual pointcut that has to be redefined in a derived aspect + to refer to the actual pointcut +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + expression +\series bold + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut!declaration +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Subsection +Attributes +\end_layout + +\begin_layout Standard +Based on the C++11 attribute syntax AspectC++ provides an annotation mechanism + for join points +\begin_inset Foot +status collapsed + +\begin_layout Plain Layout +In other languages this mechanism is known as +\begin_inset Quotes eld +\end_inset + +annotations +\begin_inset Quotes erd +\end_inset + +. +\end_layout + +\end_inset + +. + All join points annotated with the same attribute +\begin_inset Quotes eld +\end_inset + +a +\begin_inset Quotes erd +\end_inset + +, e.g. + +\family typewriter +class [[a]] C {…} +\family default +, can be referred to in a pointcut expression as a(). + Further information can be found in section +\begin_inset CommandInset ref +LatexCommand ref +reference "sec:attributes" + +\end_inset + +. +\end_layout + +\begin_layout Subsection +Slices +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +slice +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +A +\emph on +slice +\emph default + is a fragment of a C++ language element that defines a scope. + It can be used by advice to extend the static structure of the program. + For example, the elements of a class slice can be merged into one or more + target classes by introduction advice. + The following example shows a simple class slice declaration. +\end_layout + +\begin_layout Subsubsection* +Example: class slice declaration +\begin_inset CommandInset label +LatexCommand label +name "exa:class-slice-declaration" + +\end_inset + + +\end_layout + +\begin_layout LyX-Code +slice class Chain { +\end_layout + +\begin_layout LyX-Code + Chain *_next; +\end_layout + +\begin_layout LyX-Code +public: +\end_layout + +\begin_layout LyX-Code + Chain *next () const { return _next; } +\end_layout + +\begin_layout LyX-Code +}; +\end_layout + +\begin_layout Standard +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +slice +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Subsection +Advice Code +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +advice +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +advice!code +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +To a code join point +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +code join point +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +join point!code +\end_layout + +\end_inset + + so-called advice code can be bound. + Advice code can be understood as an action +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +action +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +runtime support!action +\end_layout + +\end_inset + + activated by an aspect when a corresponding code join point in a program + is reached. + The activation of the advice code can happen before +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +before +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +advice!before +\end_layout + +\end_inset + +, after +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +after +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +advice!after +\end_layout + +\end_inset + +, or before and after the code join point is reached. + The AspectC++ language element to specify advice code is the advice declaration +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +advice!declaration +\end_layout + +\end_inset + +. + It is introduced by the keyword +\family typewriter +advice +\family default + followed by a pointcut expression defining where and under which conditions + the advice code shall be activated. + +\end_layout + +\begin_layout Subsubsection* +Example: advice declaration +\begin_inset CommandInset label +LatexCommand label +name "exa:advice-declaration" + +\end_inset + + +\end_layout + +\begin_layout LyX-Code +advice execution("void login(...)") : before() { +\end_layout + +\begin_layout LyX-Code + cout << "Logging in." << endl; +\end_layout + +\begin_layout LyX-Code +} +\end_layout + +\begin_layout Standard +The code fragment +\family typewriter +:before() +\family default + following the pointcut expression determines that the advice code shall + be activated directly +\series bold +before +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +before +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +advice!before +\end_layout + +\end_inset + + the code join point is reached. + It is also possible here to use +\family typewriter +:after() +\family default + which means +\series bold +after +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +after +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +advice!after +\end_layout + +\end_inset + + reaching the code join point respectively +\family typewriter +:around() +\family default + which means that the advice code shall be executed instead of the code + described by the code join point. + In an +\series bold +around +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +around +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +advice!around +\end_layout + +\end_inset + + advice the advice code can explicitly trigger the execution of the program + code at the join point so that advice code can be executed +\series bold +before +\series default + and +\series bold +after +\series default + the join point. + There are no special access rights of advice code regarding to program + code at a join point. +\end_layout + +\begin_layout Standard +Beside the pure description of join points pointcuts can also bind variables + to context +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +context variables +\end_layout + +\end_inset + + information of a join point. + Thus for instance the actual argument values of a function call can be + made accessible to the advice code. +\end_layout + +\begin_layout Subsubsection* +Example: advice declaration with access to context information +\begin_inset CommandInset label +LatexCommand label +name "exa:advice-declaration-with" + +\end_inset + + +\end_layout + +\begin_layout LyX-Code +pointcut new_user(const char *name) = +\end_layout + +\begin_layout LyX-Code + execution("void login(...)") && args(name); +\end_layout + +\begin_layout LyX-Code +advice new_user(name) : before(const char *name) { +\end_layout + +\begin_layout LyX-Code + cout << "User " << name << " is logging in." << endl; +\end_layout + +\begin_layout LyX-Code +} +\end_layout + +\begin_layout Standard +In the example above at first the pointcut +\family typewriter +new_user +\family default + is defined including a context variable +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +context variables +\end_layout + +\end_inset + + +\family typewriter +name +\family default + that is bound to it. + This means that a value of type +\family typewriter +const char* +\family default + is supplied every time the join point described by the pointcut +\family typewriter +new_user +\family default + is reached. + The pointcut function +\family typewriter +args +\family default + used in the pointcut expression delivers all join points in the program + where an argument of type +\family typewriter +const char* +\family default + is used. + Therefore +\family typewriter +args(name) +\family default + in touch with the +\series bold +execution +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +execution join point +\end_layout + +\end_inset + + +\begin_inset Index idx +status open + +\begin_layout Plain Layout +join point!execution +\end_layout + +\end_inset + + join point binds +\family typewriter +name +\family default + to the first and only parameter of the function +\family typewriter +login +\family default +. + +\end_layout + +\begin_layout Standard +The advice declaration in the example above following the pointcut declaration + binds the execution of advice code to the event when a join point described + in +\family typewriter +new_user +\family default + is reached. + The context variable +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +context variables +\end_layout + +\end_inset + + that holds the actual value of the parameter of the reached join point + has to be declared as a formal parameter of +\family typewriter +before +\family default +, +\family typewriter +after +\family default +, or +\family typewriter +around +\family default +. + This parameter can be used in the advice code like an oridinary function + parameter. +\end_layout + +\begin_layout Standard +Beside the pointcut function +\family typewriter +args +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +args@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{args()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut function!args@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{args()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + the binding of context variables is performed by +\family typewriter +that +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +that@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{that()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut function!that@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{that()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + +, +\family typewriter +target +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +target@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{target()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut function!target@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{target()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + +, and +\family typewriter +result +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +result@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{result()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut function!base@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{base()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + +. + At the same time these pointcut functions act as filters corresponding + to the type of the context variable. + For instance +\family typewriter +args +\family default + in the example above filters all join points having an argument of type + +\family typewriter +const char* +\family default +. +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +advice!code +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Subsubsection +Introductions +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +introduction +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +advice!introduction +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +The second type of advice supported by AspectC++ are the introductions. + Introductions are used to extend program code and data structures in particular. + The following example extends two classes each by a member variable and + a member function. +\end_layout + +\begin_layout Subsubsection* +Example: introductions +\begin_inset CommandInset label +LatexCommand label +name "exa:introductions" + +\end_inset + + +\end_layout + +\begin_layout LyX-Code +pointcut shapes() = "Circle" || "Polygon"; +\end_layout + +\begin_layout LyX-Code + +\end_layout + +\begin_layout LyX-Code +advice shapes() : slice class { +\end_layout + +\begin_layout LyX-Code + bool m_shaded; +\end_layout + +\begin_layout LyX-Code + void shaded(bool state) { +\end_layout + +\begin_layout LyX-Code + m_shaded = state; +\end_layout + +\begin_layout LyX-Code + } +\end_layout + +\begin_layout LyX-Code +}; +\end_layout + +\begin_layout Standard +Like an ordinary advice declaration an introduction is introduced by the + keyword +\family typewriter +advice +\family default +. + If the following pointcut is a name pointcut +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +name pointcut +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut!name +\end_layout + +\end_inset + + the slice declaration following the token +\begin_inset Quotes eld +\end_inset + +: +\begin_inset Quotes erd +\end_inset + + is introduced in the classes and aspects described by the pointcut. + Introduced code can then be used in normal program code like any other + member function, member variable, etc. + Advice code in introductions has full access rights +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +introduction!access rights +\end_layout + +\end_inset + + regarding to program code at a join point, i.e. +\begin_inset space ~ +\end_inset + +a method introduced in a class has access even to private members of that + class. +\end_layout + +\begin_layout Standard +Slices can also be used to introduce new base classes. + In the first line of the following example it is made sure that every class + with a name that ends with +\begin_inset Quotes eld +\end_inset + +Object +\begin_inset Quotes erd +\end_inset + + is derived from a class +\family typewriter +MemoryPool +\family default +. + This class may implement an own memory management by overloading the +\family typewriter +new +\family default + and +\family typewriter +delete +\family default + operators. + Classes that inherit from +\family typewriter +MemoryPool +\family default + must redefine the pure virtual method +\family typewriter +release +\family default + that is part of the implemented memory management. + This is done in the second line for all classes in the pointcut +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +advice +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +introduction +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +advice!introduction +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + +. +\end_layout + +\begin_layout Subsubsection* +Example: base class introduction +\begin_inset CommandInset label +LatexCommand label +name "exa:base-class-intro" + +\end_inset + + +\end_layout + +\begin_layout LyX-Code +advice "%Object" : slice class : public MemoryPool { +\end_layout + +\begin_layout LyX-Code + virtual void release() = 0; +\end_layout + +\begin_layout LyX-Code +} +\end_layout + +\begin_layout Subsubsection +Advice Ordering +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +ordering +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +If more than one advice affects the same join point it might be necessary + to define an order of advice execution if there is a dependency between + the advice codes ( +\begin_inset Quotes eld +\end_inset + +aspect interaction +\begin_inset Quotes erd +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +aspect interaction +\end_layout + +\end_inset + +). + The following example shows how the precedence of advice code can be defined + in AspectC++. +\end_layout + +\begin_layout Subsubsection* +Example: advice ordering +\begin_inset CommandInset label +LatexCommand label +name "exa:order" + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +order +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +advice!order +\end_layout + +\end_inset + + +\end_layout + +\begin_layout LyX-Code +advice call("% send(...)") : order("Encrypt", "Log"); +\end_layout + +\begin_layout Standard +If advice of both aspects (see +\begin_inset CommandInset ref +LatexCommand ref +reference "subsec:Aspects" + +\end_inset + +) +\family typewriter +Encrypt +\family default + and +\family typewriter +Log +\family default + should be run when the function +\family typewriter +send(...) +\family default + is called this order declaration defines that the advice of +\family typewriter +Encrypt +\family default + has a higher precedence. + More details on advice ordering and precedence +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +precedence +\end_layout + +\end_inset + + can be found in section +\begin_inset CommandInset ref +LatexCommand vref +reference "sec:ordering" + +\end_inset + +. +\end_layout + +\begin_layout Subsection +Aspects +\begin_inset CommandInset label +LatexCommand label +name "subsec:Aspects" + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +aspect +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +The aspect is the language element of AspectC++ to collect introductions + and advice code implementing a common crosscutting concern +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +crosscutting concern +\end_layout + +\end_inset + + in a modular way. + This put aspects in a position to manage common state information. + They are formulated by means of aspect declarations +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +aspect!declaration +\end_layout + +\end_inset + + as a extension to the class concept of C++. + The basic structure of an aspect declaration is exactly the same as an + usual C++ class definition, except for the keyword +\family typewriter +aspect +\family default + instead of +\family typewriter +class +\family default +, +\family typewriter +struct +\family default + or +\family typewriter +union +\family default +. + According to that, aspects can have member variables and member functions + and can inherit from classes and even other aspects. +\end_layout + +\begin_layout Subsubsection* +Example: aspect declaration +\begin_inset CommandInset label +LatexCommand label +name "exa:aspect-decl" + +\end_inset + + +\end_layout + +\begin_layout LyX-Code +aspect Counter { +\end_layout + +\begin_layout LyX-Code + static int m_count; +\end_layout + +\begin_layout LyX-Code + +\end_layout + +\begin_layout LyX-Code + pointcut counted() = "Circle" || "Polygon"; +\end_layout + +\begin_layout LyX-Code + +\end_layout + +\begin_layout LyX-Code + advice counted() : slice struct { +\end_layout + +\begin_layout LyX-Code + class Helper { +\end_layout + +\begin_layout LyX-Code + Helper() { Counter::m_count++; } +\end_layout + +\begin_layout LyX-Code + } m_counter; +\end_layout + +\begin_layout LyX-Code + }; +\end_layout + +\begin_layout LyX-Code + +\end_layout + +\begin_layout LyX-Code + advice execution("% main(...)") : after() { +\end_layout + +\begin_layout LyX-Code + cout << "Final count: " << m_count << " objects" +\end_layout + +\begin_layout LyX-Code + << endl; +\end_layout + +\begin_layout LyX-Code + } +\end_layout + +\begin_layout LyX-Code +}; +\end_layout + +\begin_layout LyX-Code + +\emph on +... + and at an appropriate place +\end_layout + +\begin_layout LyX-Code +#include "Counter.ah" +\end_layout + +\begin_layout LyX-Code +int Counter::m_count = 0; +\end_layout + +\begin_layout Standard +In this example the count of object instantiations for a set of classes + is determined. + Therefore, a member variable +\family typewriter +m_counter +\family default + is introduced into the classes described by the pointcut incrementing a + global counter on construction time. + By applying advice code for the function +\family typewriter +main +\family default + the final count of object instantiations is displayed when the program + terminates. + +\end_layout + +\begin_layout Standard +This example can also be rewritten as an abstract aspect +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +abstract aspect +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +aspect!abstract +\end_layout + +\end_inset + + that can for instance be archived in an aspect library for the purpose + of reuse. + It only require to reimplement the pointcut declaration to be pure virtual +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pure virtual!pointcut +\end_layout + +\end_inset + +. +\end_layout + +\begin_layout Subsubsection* +Example: abstract aspect +\begin_inset CommandInset label +LatexCommand label +name "exa:abstract-aspect" + +\end_inset + + +\end_layout + +\begin_layout LyX-Code +aspect Counter { +\end_layout + +\begin_layout LyX-Code + static int m_count; +\end_layout + +\begin_layout LyX-Code + Counter() : m_count(0) {} +\end_layout + +\begin_layout LyX-Code + +\end_layout + +\begin_layout LyX-Code + pointcut virtual counted() = 0; +\end_layout + +\begin_layout LyX-Code + ... +\end_layout + +\begin_layout LyX-Code +}; +\end_layout + +\begin_layout Standard +It is now possible to inherit from +\family typewriter +Counter +\family default + to reuse its functionality by reimplementing +\family typewriter +counted +\family default + to refer to the actual pointcut expression. +\end_layout + +\begin_layout Subsubsection* +Example: reused abstract aspect +\begin_inset CommandInset label +LatexCommand label +name "exa:reused-abstract" + +\end_inset + + +\end_layout + +\begin_layout LyX-Code +aspect MyCounter : public Counter { +\end_layout + +\begin_layout LyX-Code + pointcut counted() = derived("Shape"); +\end_layout + +\begin_layout LyX-Code +}; +\end_layout + +\begin_layout Subsubsection +Aspect Instantiation +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +aspect!instantiation +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +By default aspects in AspectC++ are automatically instantiated as global + objects. + The idea behind it is that aspects can also provide global program properties + and therefore have to be always accessible. + However in some special cases it may be desired to change this behavior, + e.g. +\begin_inset space ~ +\end_inset + +in the context of operating systems when an aspect shall be instantiated + per process or per thread. + +\end_layout + +\begin_layout Standard +The default instantiation scheme can be changed by defining the static method + +\family typewriter +aspectof +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +aspectof@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{aspectof()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + resp. +\begin_inset space ~ +\end_inset + + +\family typewriter +aspectOf +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +aspectOf@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{aspectOf()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + that is otherwise generated for an aspect. + This method is intended to be always able to return an instance of the + appropriate aspect. +\end_layout + +\begin_layout Subsubsection* +Example: aspect instantiation using +\family typewriter +aspectof +\begin_inset CommandInset label +LatexCommand label +name "exa:aspect-aspectof" + +\end_inset + + +\end_layout + +\begin_layout LyX-Code +aspect ThreadCounter : public Counter { +\end_layout + +\begin_layout LyX-Code + pointcut counted() = "Thread"; +\end_layout + +\begin_layout LyX-Code + +\end_layout + +\begin_layout LyX-Code + advice counted() : ThreadCounter m_instance; +\end_layout + +\begin_layout LyX-Code + +\end_layout + +\begin_layout LyX-Code + static ThreadCounter *aspectof() { +\end_layout + +\begin_layout LyX-Code + return tjp->target()->m_instance; +\end_layout + +\begin_layout LyX-Code + } +\end_layout + +\begin_layout LyX-Code +}; +\end_layout + +\begin_layout Standard +The introduction of +\family typewriter +m_instance +\family default + into +\family typewriter +Thread +\family default + guarantees that every thread object has an instance of the aspect. + By calling +\family typewriter +aspectof +\family default + it is possible to get this instance at any join point which is essential + for accessing advice code and members of the aspect. + For this purpose code in +\family typewriter +aspectof +\family default + has full access to the actual join point in a way described in the next + section. +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +aspect +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +aspect!instantiation +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Subsection +Runtime Support +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +runtime support +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Subsubsection +Support for Advice Code +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +runtime support!for advice code +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +advice!runtime support +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +For many aspects access to context variables +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +context variables +\end_layout + +\end_inset + + may not be sufficient to get enough information about the join point where + advice code was activated. + For instance a control flow +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +control flow +\end_layout + +\end_inset + + aspect for a complete logging of function calls in a program would need + information about function arguments and its types on runtime to be able + to produce a type-compatible output. + +\end_layout + +\begin_layout Standard +In AspectC++ this information is provided by the members of the class +\family typewriter +JoinPoint +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +runtime support!JoinPoint@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +begin{comment} +\end_layout + +\end_inset + +available both in advice code and introductions +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +\end_layout + +\begin_layout Plain Layout + +\end_layout + +\begin_layout Plain Layout + + +\backslash +end{comment} +\end_layout + +\begin_layout Plain Layout + +\end_layout + +\end_inset + +(see table below). + +\end_layout + +\begin_layout Standard +\begin_inset Tabular + + + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +types: +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +Result +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +result type +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +That +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +object type +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +Target +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +target type +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +AC::Type +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +encoded type of an object +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +AC::JPType +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +join point types +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +static methods: +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +int args() +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +number of arguments +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +AC::Type type() +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +typ of the function or attribute +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +AC::Type argtype(int) +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +types of the arguments +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +const char *signature() +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +signature of the function or variable +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +unsigned id() +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +identification of the join point +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +AC::Type resulttype() +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +result type +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +AC::JPType jptype() +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +type of join point +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +non-static methods: +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +void *arg(int) +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +actual argument +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +Result *result() +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +result value +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +That *that() +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +object referred to by +\family typewriter +\size small +this +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +Target *target() +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +target object of a call +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +void proceed() +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +execute join point code +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +AC::Action &action() +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +Action +\family default + structure +\end_layout + +\end_inset + + + + +\end_inset + + +\begin_inset Separator latexpar +\end_inset + + +\end_layout + +\begin_layout Standard +\align center +Table 1: API of class +\family typewriter +JoinPoint +\family default + available in advice code +\end_layout + +\begin_layout Standard +Types and static methods of the +\family typewriter +JoinPoint +\family default + API deliver information that is the same for every advice code activation. + The non-static methods deliver information that differ from one activation + to another. + These methods are accessed by the object +\family typewriter +tjp +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +tjp@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{tjp} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +runtime support!thisJoinPoint@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{thisJoinPoint} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + resp. +\begin_inset space ~ +\end_inset + + +\family typewriter +thisJoinPoint +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +thisJoinPoint@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{thisJoinPoint} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +runtime support!thisJoinPoint@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{thisJoinPoint} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + which is of type +\family typewriter +JoinPoint +\family default + and is always available in advice code +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +begin{comment} +\end_layout + +\end_inset + + and introductions +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +\end_layout + +\begin_layout Plain Layout + +\end_layout + +\begin_layout Plain Layout + + +\backslash +end{comment} +\end_layout + +\begin_layout Plain Layout + +\end_layout + +\end_inset + +, too. +\end_layout + +\begin_layout Standard +The following example illustrates how to implement a re-usable control flow +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +control flow +\end_layout + +\end_inset + + aspect using the +\family typewriter +JoinPoint +\family default + API. + +\end_layout + +\begin_layout Subsubsection* +Example: re-usable trace aspect +\begin_inset CommandInset label +LatexCommand label +name "exa:re-usable-trace" + +\end_inset + + +\end_layout + +\begin_layout LyX-Code +aspect Trace { +\end_layout + +\begin_layout LyX-Code + pointcut virtual methods() = 0; +\end_layout + +\begin_layout LyX-Code + +\end_layout + +\begin_layout LyX-Code + advice execution(methods()) : around() { +\end_layout + +\begin_layout LyX-Code + cout << "before " << JoinPoint::signature() << "("; +\end_layout + +\begin_layout LyX-Code + for (unsigned i = 0; i < JoinPoint::args(); i++) +\end_layout + +\begin_layout LyX-Code + printvalue(tjp->arg(i), JoinPoint::argtype(i)); +\end_layout + +\begin_layout LyX-Code + cout << ")" << endl; +\end_layout + +\begin_layout LyX-Code + tjp->proceed() +\series bold +; +\end_layout + +\begin_layout LyX-Code + cout << "after" << endl; +\end_layout + +\begin_layout LyX-Code + } +\end_layout + +\begin_layout LyX-Code +}; +\end_layout + +\begin_layout Standard +This aspect weaves tracing code into every function specified by the virtual + pointcut +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pure virtual!pointcut +\end_layout + +\end_inset + + redefined in a derived aspect. + The helper function +\family typewriter +printvalue +\family default + is responsible for the formatted output of the arguments given at the function + call. + After calling +\family typewriter +printvalue +\family default + for every argument the program code of the actual join point is executed + by calling +\family typewriter +proceed +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +proceed@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{proceed()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!proceed()@ +\backslash +texttt{proceed()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + on the +\family typewriter +JoinPoint +\family default + object. + The functionality of +\family typewriter +proceed +\family default + is achieved by making use of the so-called actions. +\end_layout + +\begin_layout Subsubsection +Actions +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +action +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +runtime support!action +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +In AspectC++ an action is the statement sequence that would follow a reached + join point in a running program if advice code would not have been activated. + Thus +\family typewriter +tjp->proceed() +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +proceed@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{proceed()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!proceed()@ +\backslash +texttt{proceed()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + triggers the execution of the program code of a join point. + This can be the call or execution of a function as well as the writing + or reading of member variables or global variables. + The actions concept is realized in the +\family typewriter +AC::Action +\family default + structure. + In fact, +\family typewriter +proceed +\family default + is equivalent to +\family typewriter +action().trigger() +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +trigger@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{trigger()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +action!trigger@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{trigger()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + so that +\family typewriter +tjp->proceed() +\family default + may also be replaced by +\family typewriter +tjp->action().trigger() +\family default +. + Thereby the method +\family typewriter +action() +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +action@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{action()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!action@ +\backslash +texttt{action()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + of the +\family typewriter +JoinPoint +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +runtime support!JoinPoint@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + API returns the actual action object for a join point. +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +runtime support!for advice code +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +advice!runtime support +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +action +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +runtime support!action +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +begin{comment} +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Subsubsection +Support for Introductions +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +runtime support!for introductions +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +introduction!runtime support +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +The +\family typewriter +JoinPoint +\family default + API available in code introduced by an introduction is listed in the following + table. +\end_layout + +\begin_layout Standard +\begin_inset Float table +placement H +wide false +sideways false +status open + +\begin_layout Plain Layout +\align center +\begin_inset Tabular + + + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +static methods: +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +const char *signature() +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +signature of the function or member variable +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +unsigned id() +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +identification of the join point +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +AC::JPType jptype() +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +type of join point +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +types: +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +Aspect +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +type of the aspect +\end_layout + +\end_inset + + + + +\end_inset + + +\end_layout + +\begin_layout Plain Layout +\begin_inset Caption Standard + +\begin_layout Plain Layout + +\family typewriter +JoinPoint +\family default + API for introductions +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +In difference to the API available for advice code the API for introduction + only provides static information about a join point. + A nice demonstration of this API is shown in the following example. +\end_layout + +\begin_layout Subsubsection* +Example: static type identification using introductions +\begin_inset CommandInset label +LatexCommand label +name "exa:static-type-id" + +\end_inset + + +\end_layout + +\begin_layout LyX-Code +aspect TypeInfo { +\end_layout + +\begin_layout LyX-Code + pointcut virtual typed() = 0; +\end_layout + +\begin_layout LyX-Code + +\end_layout + +\begin_layout LyX-Code + advice typed() : static unsigned type_id() { +\end_layout + +\begin_layout LyX-Code + return JoinPoint::id(); +\end_layout + +\begin_layout LyX-Code + } +\end_layout + +\begin_layout LyX-Code + +\end_layout + +\begin_layout LyX-Code + advice typed() : virtual unsigned type() { +\end_layout + +\begin_layout LyX-Code + return type_id(); +\end_layout + +\begin_layout LyX-Code + } +\end_layout + +\begin_layout LyX-Code +}; +\end_layout + +\begin_layout Standard +The first introduction of this aspect introduces a static method +\family typewriter +type_id +\family default + into a set of classes returning an unique integer value. + By introducing a second non-static but virtual method type into these classes + also returning the unique integer value a type identification can be realized + like this: +\end_layout + +\begin_layout LyX-Code +if (obj->type() == AClass::type_id()) +\end_layout + +\begin_layout LyX-Code + ... +\end_layout + +\begin_layout LyX-Code +else if (obj->type() == AnotherClass::type_id()) +\end_layout + +\begin_layout LyX-Code + ... +\end_layout + +\begin_layout Standard +This implements a nice alternative to the C++ RTTI mechanism especially + when the RTTI support of a compiler is switched off. + +\end_layout + +\begin_layout Standard +Code of introductions have to use the type +\family typewriter +Aspect +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +Aspect@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{Aspect} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!Aspect@ +\backslash +texttt{Aspect} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + to get access to the methods and member variables of an aspect, e.g. +\begin_inset space ~ +\end_inset + +by calling +\family typewriter +Aspect::aspectof() +\family default +. + Because the static function +\family typewriter +aspectof +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +aspectof@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{aspectof()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + is always generated for an aspect, except when it is already explicitly + defined, +\family typewriter +aspectof +\family default + always returns the actual aspect instance. + By courtesy of this technique the example +\begin_inset CommandInset ref +LatexCommand vpageref +reference "exa:aspect-decl" + +\end_inset + + can be changed to provide not only the count of all threads but to provide + a count for every thread. +\end_layout + +\begin_layout Subsubsection* +Example: +\begin_inset CommandInset label +LatexCommand label +name "exa:extended-thread" + +\end_inset + +extended thread counting +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +runtime support +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +runtime support!for introductions +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +introduction!runtime support +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + +\end_layout + +\begin_layout LyX-Code +aspect Counter { +\end_layout + +\begin_layout LyX-Code + int m_count; +\end_layout + +\begin_layout LyX-Code + ... +\end_layout + +\begin_layout LyX-Code + advice counted() : class Helper { +\end_layout + +\begin_layout LyX-Code + Helper() { Aspect::aspectof()->m_count++; } +\end_layout + +\begin_layout LyX-Code + } m_counter; +\end_layout + +\begin_layout LyX-Code + ... +\end_layout + +\begin_layout LyX-Code +}; +\end_layout + +\begin_layout Standard +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +\end_layout + +\begin_layout Plain Layout + +\end_layout + +\begin_layout Plain Layout + + +\backslash +end{comment} +\end_layout + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Section +\begin_inset CommandInset label +LatexCommand label +name "sec:Match-Expressions" + +\end_inset + +Match Expressions +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +match expression +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +search pattern!match expression +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +Match expressions are a used to describe a set of statically known program + entities in a C++ source code. + These program entities correspond to name join points. + Therefore a match expression always returns a name pointcut. + There can be match expressions for namespaces, classes, functions or variables. +\end_layout + +\begin_layout Subsection +Commonly Used Matching Mechanisms +\begin_inset CommandInset label +LatexCommand label +name "subsec:Commonly-Used-Matchings" + +\end_inset + + +\end_layout + +\begin_layout Standard +This section describes matching mechanisms that are used in match expressions + listed in sections +\begin_inset CommandInset ref +LatexCommand ref +reference "subsec:Namspace-and-Class" + +\end_inset + + to +\begin_inset CommandInset ref +LatexCommand ref +reference "subsec:Variable-Matching" + +\end_inset + +. +\end_layout + +\begin_layout Standard +The grammar used for match expression parsing is shown in appendix +\begin_inset CommandInset ref +LatexCommand vref +reference "sec:Match-Expression-Grammar" + +\end_inset + +. + The following subsections separately describe the name, scope, and type + matching mechanisms. + All of them are used in match expressions of functions and variables, while + match expressions of namespaces and classes only uses name and scope matching. +\end_layout + +\begin_layout Subsubsection +\begin_inset CommandInset label +LatexCommand label +name "subsec:Name-Matching" + +\end_inset + +Name Matching +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +match expression!name matching +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +name matching +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +Name matching is trivial as long as the compared name is a normal C++ identifier. + If the +\emph on +name pattern +\emph default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +name pattern +\end_layout + +\end_inset + + does +\emph on +not +\emph default + contain the special wildcard character % +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +% +\end_layout + +\end_inset + + +\end_layout + +\end_inset + +, it matches a name only if it is exactly the same. + Otherwise each wildcard character matches an arbitrary sequence of characters + in the compared name. + The wildcard character also matches an empty sequence. +\end_layout + +\begin_layout Paragraph* +Example: simple name patterns +\family typewriter + +\begin_inset CommandInset label +LatexCommand label +name "exa:match-name-patterns" + +\end_inset + + +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +match expression!simple name pattern +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +simple name pattern +\end_layout + +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\end_layout + +\begin_layout Standard +\begin_inset Tabular + + + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +Token +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +only matches +\family typewriter +Token +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +% +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +matches any name +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +parse_% +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +matches any name beginning with +\family typewriter +parse_ +\family default + like +\family typewriter +parse_declarator +\family default + or +\family typewriter +parse_ +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +parse_%_id% +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +matches names like +\family typewriter +parse_type_id +\family default +, +\family typewriter +parse_private_identifier +\family default +, etc. +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +%_token +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +matches all names that end with +\family typewriter +_token +\family default + like +\family typewriter +start_token +\family default +, +\family typewriter +end_token +\family default +, and +\family typewriter +_token +\end_layout + +\end_inset + + + + +\end_inset + + +\end_layout + +\begin_layout Subsubsection +\begin_inset CommandInset label +LatexCommand label +name "subsec:Scope-Matching" + +\end_inset + +Scope Matching +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +match expression!scope matching +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +scope matching +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +Restrictions on definition scopes can be described by +\emph on +scope patterns +\emph default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +scope pattern +\end_layout + +\end_inset + +. + This is a sequence of name patterns (or the special +\emph on +any scope sequence +\emph default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +any scope sequence +\end_layout + +\end_inset + +pattern +\family typewriter +... +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +... +\end_layout + +\end_inset + +), which are separated by +\family typewriter +:: +\family default +, like in +\family typewriter +Puma::...:: +\family default +. + A scope pattern always ends with +\family typewriter +:: +\family default + and should never start with +\family typewriter +:: +\family default +, because scope patterns are interpreted relative to the global scope anyway +\begin_inset Foot +status collapsed + +\begin_layout Plain Layout +This restriction is also needed to avoid ambiguities in the match expression + grammar: Does +\begin_inset Quotes eld +\end_inset + + +\family typewriter +A +\begin_inset space ~ +\end_inset + +:: +\begin_inset space ~ +\end_inset + +B +\begin_inset space ~ +\end_inset + +:: +\begin_inset space ~ +\end_inset + +C(int) +\family default + +\begin_inset Quotes erd +\end_inset + + mean +\begin_inset Quotes eld +\end_inset + + +\family typewriter +A +\begin_inset space ~ +\end_inset + +::B::C(int) +\family default + +\begin_inset Quotes erd +\end_inset + + or +\begin_inset Quotes eld +\end_inset + + +\family typewriter +A::B +\begin_inset space ~ +\end_inset + +::C(int) +\family default + +\begin_inset Quotes erd +\end_inset + +? +\end_layout + +\end_inset + +. + The definition scope can either be a namespace or a class. +\end_layout + +\begin_layout Standard +A scope pattern matches the definition scope of a compared function or type + if every part can successfully be matched with a corresponding part in + the qualified name of the definition scope. + The compared qualified name has to be relative to the global scope and + should not start with +\family typewriter +:: +\family default +, which is optional in a C++ nested-name-specifier. + The special +\family typewriter +... + +\family default + pattern matches any (even empty) sequence of scope names. + If no scope pattern is given, a compared namespace, class, function or + variable has to be defined in the global scope to be matched. +\end_layout + +\begin_layout Paragraph* +Example: scope patterns +\family typewriter + +\begin_inset CommandInset label +LatexCommand label +name "exa:match-scope-patterns" + +\end_inset + + +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +match expression!scope pattern +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +scope pattern +\end_layout + +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\end_layout + +\begin_layout Standard +\begin_inset Tabular + + + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +...:: +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +matches any definition scope, even the global scope +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +Puma::CCParser:: +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +matches the scope +\family typewriter +Puma::CCParser +\family default + exactly +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +...::%Compiler%:: +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +matches any class or namespace, which matches the name pattern +\family typewriter +%Compiler% +\family default +, in any scope +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +Puma::...:: +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +matches any scope defined within the class or namespace +\family typewriter +Puma +\family default + and +\family typewriter +Puma +\family default + itself +\end_layout + +\end_inset + + + + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +scope matching +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +match expression!scope matching +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Subsubsection +\begin_inset CommandInset label +LatexCommand label +name "subsec:Type-Matching" + +\end_inset + +Type Matching +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +match expression!type matching +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +type matching +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +C++ types can be represented as a tree. + For example, the function type +\family typewriter +int(double) +\family default + is a function type node with two children, one is an +\family typewriter +int +\family default + node, the other a +\family typewriter +double +\family default + node. + Both children are leaves of the tree. +\end_layout + +\begin_layout Standard +The types used in match expressions can also be interpreted as trees. + As an addition to normal C++ types they can also contain the % +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +% +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + wildcard character, name patterns, and scope patterns. + A single wildcard character in a type pattern becomes a special +\emph on +any type node +\emph default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +any type node +\end_layout + +\end_inset + + in the tree representation. +\end_layout + +\begin_layout Standard +For comparing a type pattern with a specific type the tree representation + is used and the +\emph on +any type node +\emph default + matches an arbitrary type (sub-)tree. + +\end_layout + +\begin_layout Paragraph* +Example: type patterns with the wildcard character +\family typewriter + +\begin_inset CommandInset label +LatexCommand label +name "exa:match-type-patterns-wildcard" + +\end_inset + + +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +match expression!type pattern with +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +% +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +type pattern with +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +% +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\end_layout + +\begin_layout Standard +\begin_inset Tabular + + + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +% +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +matches any type +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +void (*)(%) +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +matches any pointer type that points to functions with a single argument + and a +\family typewriter +void +\family default + result type +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +%* +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +matches any pointer type +\end_layout + +\end_inset + + + + +\end_inset + + +\begin_inset VSpace bigskip +\end_inset + + +\end_layout + +\begin_layout Paragraph +Matching of Named Types +\begin_inset Newline newline +\end_inset + + +\end_layout + +\begin_layout Standard +Type patterns may also contain name and scope patterns. + They become a +\emph on +named type node +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +named type +\end_layout + +\end_inset + + +\emph default + in the tree representation and match any union, struct, class, or enumeration + type if its name and scope match the given pattern (see section +\begin_inset CommandInset ref +LatexCommand ref +reference "subsec:Name-Matching" + +\end_inset + + and +\begin_inset CommandInset ref +LatexCommand ref +reference "subsec:Scope-Matching" + +\end_inset + +). +\end_layout + +\begin_layout Paragraph +Matching of +\begin_inset Quotes eld +\end_inset + +Pointer to Member +\begin_inset Quotes erd +\end_inset + + Types +\begin_inset Newline newline +\end_inset + + +\end_layout + +\begin_layout Standard +Patterns for pointers to members +\begin_inset Index idx +status open + +\begin_layout Plain Layout +pointer to member +\end_layout + +\end_inset + + also contain a scope pattern, e.g. + +\family typewriter +% +\begin_inset space ~ +\end_inset + +(Puma::CSyntax::*)() +\family default +. + In this context the scope pattern is mandatory. + The pattern is used for matching the class associated with a pointer to + member type. +\end_layout + +\begin_layout Paragraph +Matching of Qualified Types ( +\family typewriter +const +\family default +/ +\family typewriter +volatile +\family default +) +\begin_inset Newline newline +\end_inset + + +\end_layout + +\begin_layout Standard +Many C++ types can be qualified as +\family typewriter +const +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +const +\end_layout + +\end_inset + +or +\family typewriter +volatile +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +volatile +\end_layout + +\end_inset + +. + In a type pattern these qualifier can also be used, but they are interpreted + restrictions. + If no +\family typewriter +const +\family default + or +\family typewriter +volatile +\family default + qualifier is given in a type pattern, the pattern also matches qualified + types +\begin_inset Foot +status open + +\begin_layout Plain Layout +Matching only non-constant or non-volatile types can be achieved by using + the operators explained in section +\begin_inset CommandInset ref +LatexCommand vref +reference "subsec:Algebraic-Operators" + +\end_inset + +. + For example, +\family typewriter +!"const +\begin_inset space ~ +\end_inset + +%" +\family default + describes all types which are not constant. +\end_layout + +\end_inset + +. +\end_layout + +\begin_layout Paragraph* +Example: type patterns with +\family typewriter +const +\family default + and +\family typewriter +volatile +\family default + +\family typewriter + +\begin_inset CommandInset label +LatexCommand label +name "exa:match-type-patterns-cv" + +\end_inset + + +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +match expression!type pattern with cv qualifier +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +type pattern with cv qualifier +\end_layout + +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\end_layout + +\begin_layout Standard +\begin_inset Tabular + + + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +% +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +matches any type, even types qualified with +\family typewriter +const +\family default + or +\family typewriter +volatile +\family default + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +const % +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +matches only types qualified by +\family typewriter +const +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +% (*)() const volatile +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +matches the type of all pointers to functions that are qualified by +\family typewriter +const +\family default + and +\family typewriter +volatile +\end_layout + +\end_inset + + + + +\end_inset + + +\begin_inset VSpace bigskip +\end_inset + + +\end_layout + +\begin_layout Paragraph +Handling of Conversion Function Types +\begin_inset Newline newline +\end_inset + + +\end_layout + +\begin_layout Standard +The result type of conversion functions is interpreted as a special +\emph on +undefined +\emph default + type in type patterns as well as in compared types. + The +\emph on +undefined +\emph default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +undefined type +\end_layout + +\end_inset + + type is only matched by the +\emph on +any type +\emph default + node and the +\emph on +undefined type +\emph default + node. +\end_layout + +\begin_layout Paragraph +Ellipses in Function Type Patterns +\begin_inset Newline newline +\end_inset + + +\end_layout + +\begin_layout Standard +In the list of function argument types the type pattern +\family typewriter +... + +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +... +\end_layout + +\end_inset + +can be used to match an arbitrary (even empty) list of types. + The +\family typewriter +... + +\family default + pattern should not be followed by other argument type patterns in the list + of argument types. +\end_layout + +\begin_layout Paragraph +Matching Virtual Functions +\begin_inset Newline newline +\end_inset + + +\end_layout + +\begin_layout Standard +The +\emph on +decl-specifier-seq +\emph default + of a function type match expression may include the keyword +\family typewriter +\size small +virtual +\family default +\size default +. + In this case the function type match expression only matches virtual or + pure virtual member functions. + As +\family typewriter +\size small +const +\family default +\size default + and +\family typewriter +\size small +volatile +\family default +\size default +, the +\family typewriter +\size small +virtual +\family default +\size default + keyword is regarded as a restriction. + This means that a function type match expression without +\family typewriter +\size small +virtual +\family default +\size default + matches virtual and non-virtual functions. +\end_layout + +\begin_layout Paragraph* +Example: type patterns with +\family typewriter +virtual +\family default + +\family typewriter + +\begin_inset CommandInset label +LatexCommand label +name "exa:match-type-patterns-virtual" + +\end_inset + + +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +match expression!type pattern with virtual keyword +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +type pattern with virtual keyword +\end_layout + +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\end_layout + +\begin_layout Standard +\begin_inset Tabular + + + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +virtual % ...::%(...) +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +matches all virtual or pure virtual functions in any scope +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +% C::%(...) +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +matches all member functions of C, even if they are virtual +\end_layout + +\end_inset + + + + +\end_inset + + +\begin_inset VSpace bigskip +\end_inset + + +\end_layout + +\begin_layout Paragraph +Matching Static Functions +\begin_inset Newline newline +\end_inset + + +\end_layout + +\begin_layout Standard +Matching static functions works similar as matching virtual functions. + The +\emph on +decl-specifier-seq +\emph default + of a function type match expression may include the keyword +\family typewriter +\size small +static +\family default +\size default +. + In this case the function type match expression only matches static functions + in global or namespace scope and static member functions of classes. + As +\family typewriter +\size small +const +\family default +\size default + and +\family typewriter +\size small +volatile +\family default +\size default +, the +\family typewriter +\size small +static +\family default +\size default + keyword is regarded as a restriction. + This means that a function type match expression without +\family typewriter +\size small +static +\family default +\size default + matches static and non-static functions. +\end_layout + +\begin_layout Paragraph* +Example: type patterns with +\family typewriter +static +\family default + +\family typewriter + +\begin_inset CommandInset label +LatexCommand label +name "exa:match-type-patterns-static" + +\end_inset + + +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +match expression!type pattern with static keyword +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +type pattern with static keyword +\end_layout + +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\end_layout + +\begin_layout Standard +\begin_inset Tabular + + + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +static % ...::%(...) +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +matches all static member and non-member functions in any scope +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +% C::%(...) +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +matches all member functions of C, even if they are static +\end_layout + +\end_inset + + + + +\end_inset + + +\begin_inset VSpace bigskip +\end_inset + + +\end_layout + +\begin_layout Paragraph +Argument Type Adjustment +\begin_inset Newline newline +\end_inset + + +\end_layout + +\begin_layout Standard +Argument types +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +argument types +\end_layout + +\end_inset + + in type patterns are adjusted according to the usual C++ rules, i.e. + array and function types are converted to pointers to the given type and + +\family typewriter +const +\family default +/ +\family typewriter +volatile +\family default + qualifiers are removed. + Furthermore, argument type lists containing a single +\family typewriter +void +\family default + type are converted into an empty argument type list. +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +type matching +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +match expression!type matching +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Description +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +match expression +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +search pattern!match expression +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Subsection +Namespace and Class Match Expressions +\begin_inset CommandInset label +LatexCommand label +name "subsec:Namspace-and-Class" + +\end_inset + + +\end_layout + +\begin_layout Standard +For namespaces and classes the matching process is special because it consists + of two steps. +\end_layout + +\begin_layout Standard +First, each namespace and class is compared with a given match expression. + A match expression that matches a namespace or class begins with the optional + scope part and ends with the required name part. + In course of this step the matching name join points are collected in a + temporary pointcut. + +\end_layout + +\begin_layout Subsubsection* +Example: scope and name parts of a namespace or class match expression +\family typewriter + +\begin_inset CommandInset label +LatexCommand label +name "exa:match-expr-parts-namespaces-classes" + +\end_inset + + +\end_layout + +\begin_layout LyX-Code +"Puma::...::Parser%" +\end_layout + +\begin_layout Standard +This match expression describes the following requirements on a compared + namespace or class: +\end_layout + +\begin_layout Description +scope: the scope in which the namespace or class is defined has to match + +\family typewriter +Puma::...:: +\end_layout + +\begin_layout Description +name: the name of the namespace or class has to match the name pattern +\family typewriter +Parser% +\end_layout + +\begin_layout Standard +For more information about these parts see sections +\begin_inset CommandInset ref +LatexCommand nameref +reference "subsec:Scope-Matching" + +\end_inset + + +\begin_inset CommandInset ref +LatexCommand eqref +reference "subsec:Scope-Matching" + +\end_inset + + and +\begin_inset CommandInset ref +LatexCommand nameref +reference "subsec:Name-Matching" + +\end_inset + + +\begin_inset CommandInset ref +LatexCommand eqref +reference "subsec:Name-Matching" + +\end_inset + +. + +\end_layout + +\begin_layout Standard +In the second step the temporary pointcut will be extended by contained + name join points yielding the result pointcut. + The extension rules are as follows: +\end_layout + +\begin_layout Itemize +If a namespace +\emph on +N +\emph default + is matched, the resulting pointcut additionally contains the following + name join points: +\begin_inset Newline newline +\end_inset + +all functions, variables, (nested) classes, member functions, data members, + constructors and destructors that are anywhere and arbitrary nested inside + +\emph on +N +\emph default +. + +\end_layout + +\begin_layout Itemize +If a class +\emph on +C +\emph default + is matched, the resulting pointcut additionally contains the following + name join points: +\begin_inset Newline newline +\end_inset + +all member functions, data members and constructors of +\emph on +C +\emph default + as well as the destructor of +\emph on +C +\emph default + that are directly located inside +\emph on +C +\emph default +. + So name join points that are nested inside a member function, a data member + or a nested class are +\series bold +not +\series default + added to the pointcut. +\end_layout + +\begin_layout Standard +The following list contains example match expressions and the results after + the first as well as after the second step. +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +newcommand{ +\backslash +steptwodescribedabove}{ +\backslash +textit{step one extended as described in step two}} +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +\begin_inset Tabular + + + + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +centering +\end_layout + +\end_inset + + +\series bold +after step one +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +centering +\end_layout + +\end_inset + + +\series bold +result +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +Token +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +only matches namespaces or classes with the name +\family typewriter +Token +\family default +that are directly inside the global namespace +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +steptwodescribedabove +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +...::Token +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +matches +\family typewriter +Token +\family default + at arbitrary location +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +steptwodescribedabove +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +% +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +matches any namespace or class that is directly located in the global namespace + but not the global namespace itself +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +matches any namespace except the global namespace, any class that is arbitrary + nested in a non-global namespace, any class directly located in the global + namespace and all functions, member functions, variables, data members, + constructors and destructors that are contained in one of the just mentioned + entities +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family roman +\series medium +\shape up +\size normal +\emph off +\bar no +\strikeout off +\uuline off +\uwave off +\noun off +\color none +:: +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family roman +\series medium +\shape up +\size normal +\emph off +\bar no +\strikeout off +\uuline off +\uwave off +\noun off +\color none +matches the global namespace +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +matches any function, variable, (nested) class, member function, data member, + constructor or destructor +\end_layout + +\end_inset + + + + +\end_inset + + +\end_layout + +\begin_layout Standard +\begin_inset Tabular + + + + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +centering +\end_layout + +\end_inset + + +\series bold +after step one +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +centering +\end_layout + +\end_inset + + +\series bold +result +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +OOStuBS::CGA% +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +matches any namespace or class inside +\family typewriter +OOStuBS +\family default + beginning with +\family typewriter +CGA +\family default + like +\family typewriter +OOStuBS::CGA, OOStuBS::CGA_Screen +\family default + or +\family typewriter +OOStuBS::CGA_Stream +\family default +. + Note that this matches +\family typewriter +OOStuBS +\family default +only inside the global namespace. +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +steptwodescribedabove +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +%::Smtp%Bldr% +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +matches namespaces and classes like +\family typewriter +SmtpBldr, SmtpClientBldr +\family default + or +\family typewriter + SmtpServerBldrCreator +\family default +, that are nested in exact one namespace or class. +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +steptwodescribedabove +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +%Node +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +matches any namespace or class ending with +\family typewriter +Node +\family default + like +\family typewriter +ModelNode, GraphNode +\family default + and +\family typewriter +Node +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +steptwodescribedabove +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + + + +\end_inset + + +\begin_inset VSpace bigskip +\end_inset + +Please note that local classes inside functions or member functions are + never matched. +\end_layout + +\begin_layout Subsection +Function Match Expressions +\end_layout + +\begin_layout Standard +For function (or member function) matching a match expression is internally + decomposed into the function type pattern +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +type pattern +\end_layout + +\end_inset + +, the scope pattern +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +scope pattern +\end_layout + +\end_inset + +, and the name pattern +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +name pattern +\end_layout + +\end_inset + +. +\end_layout + +\begin_layout Subsubsection* +Example: type, scope, and name parts of a function match expression +\family typewriter + +\begin_inset CommandInset label +LatexCommand label +name "exa:match-expr-parts-functions" + +\end_inset + + +\end_layout + +\begin_layout LyX-Code +"const % Puma::...::parse_% (Token *)" +\end_layout + +\begin_layout Standard +This match expression describes the following requirements on a compared + function name: +\end_layout + +\begin_layout Description +name: the function name has to match the name pattern +\family typewriter +parse_% +\end_layout + +\begin_layout Description +scope: the scope in which the function is defined has to match +\family typewriter +Puma::...:: +\end_layout + +\begin_layout Description +type: the function type has to match +\family typewriter +const %(Token *) +\end_layout + +\begin_layout Standard +\begin_inset Note Note +status open + +\begin_layout Plain Layout +For classes and other types this decomposion is not necessary. + For example, the type name +\begin_inset Quotes eld +\end_inset + + +\family typewriter +Puma::CCParser +\family default + +\begin_inset Quotes erd +\end_inset + + is sufficient to describe a class, because this is the same as the class + name. +\end_layout + +\end_inset + +If an entity matches all parts of the match expression, it becomes an element + of the pointcut, which is defined and returned by the match expression. +\end_layout + +\begin_layout Standard +Common descriptions of name, scope and type matching can be found in section + +\begin_inset CommandInset ref +LatexCommand ref +reference "subsec:Commonly-Used-Matchings" + +\end_inset + +. + The following sections additionally describe the name matching of special + functions. +\end_layout + +\begin_layout Subsubsection +Operator Function and Conversion Function Name Matching +\end_layout + +\begin_layout Standard +The name matching mechanism is more complicated if the pattern is compared + with the name of a conversion function or an operator function. + Both are matched by the name pattern +\family typewriter +% +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +% +\end_layout + +\end_inset + + +\end_layout + +\end_inset + +. + However, with a different name pattern than +\family typewriter +% +\family default + they are only matched if the pattern begins with " +\family typewriter +operator +\family default + +\begin_inset space ~ +\end_inset + +". + The pattern " +\family typewriter +operator +\begin_inset space ~ +\end_inset + +% +\family default +" matches any operator function or conversion function name. +\end_layout + +\begin_layout Standard +C++ defines a fixed set of operators which are allowed to be overloaded. + In a name pattern the same operators may be used after the " +\family typewriter +operator +\family default + +\begin_inset space ~ +\end_inset + +" prefix to match a specific operator function name. + Operator names in name patterns are not allowed to contain the wildcard + character. + For ambiguity resolution the operators +\family typewriter +% +\family default + and +\family typewriter +%= +\family default + are matched by +\family typewriter +%% +\family default + and +\family typewriter +%%= +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +% +\end_layout + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +% +\end_layout + +\end_inset + + +\end_layout + +\end_inset + +in a name pattern. +\end_layout + +\begin_layout Paragraph* +Example: operator name patterns +\begin_inset Index idx +status open + +\begin_layout Plain Layout +match expression!operator name pattern +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +operator name pattern +\end_layout + +\end_inset + + +\family typewriter + +\begin_inset CommandInset label +LatexCommand label +name "exa:match-operator-name-patterns" + +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\end_layout + +\begin_layout Standard +\begin_inset Tabular + + + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +operator +\begin_inset space ~ +\end_inset + +% +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +matches any operator function name (as well as any conversion function name) +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +operator +\begin_inset space ~ +\end_inset + ++= +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +matches only the name of a +\family typewriter ++= +\family default + operator +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +operator +\begin_inset space ~ +\end_inset + +%% +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +matches the name of an +\family typewriter +operator +\begin_inset space ~ +\end_inset + +% +\end_layout + +\end_inset + + + + +\end_inset + + +\begin_inset VSpace bigskip +\end_inset + + +\end_layout + +\begin_layout Standard +Conversion functions don't have a real name. + For example, the conversion function +\family typewriter +operator int*() +\family default + defined in a class +\family typewriter +C +\family default + defines a conversion from a +\family typewriter +C +\family default + instance into an object of type +\family typewriter +int* +\family default +. + To match conversion functions the name pattern may contain a type pattern + after the prefix " +\family typewriter +operator +\family default + ". + The type matching mechanism is explained in section +\begin_inset CommandInset ref +LatexCommand ref +reference "subsec:Type-Matching" + +\end_inset + +. +\end_layout + +\begin_layout Paragraph* +Example: conversion function name patterns +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +match expression!conversion function name pattern +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +conversion function name pattern +\end_layout + +\end_inset + + +\family typewriter + +\begin_inset CommandInset label +LatexCommand label +name "exa:match-conversion-function-name-patterns" + +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\end_layout + +\begin_layout Standard +\begin_inset Tabular + + + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +operator +\begin_inset space ~ +\end_inset + +% +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +matches any conversion function name +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +operator +\begin_inset space ~ +\end_inset + +int* +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +matches any name of a conversion that converts something into an +\family typewriter +int* +\family default + object +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +operator +\begin_inset space ~ +\end_inset + +%* +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +matches any conversion function name if that function converts something + into a pointer +\end_layout + +\end_inset + + + + +\end_inset + + +\begin_inset VSpace bigskip +\end_inset + + +\end_layout + +\begin_layout Subsubsection +Constructors and Destructors +\end_layout + +\begin_layout Standard +Name patterns cannot be used to match constructor or destructor names. +\end_layout + +\begin_layout Subsection +Variable Match Expressions +\begin_inset CommandInset label +LatexCommand label +name "subsec:Variable-Matching" + +\end_inset + + +\end_layout + +\begin_layout Standard +For variable (or member) matching a match expression is internally decomposed + into the variable type pattern +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +type pattern +\end_layout + +\end_inset + +, the scope pattern +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +scope pattern +\end_layout + +\end_inset + +, and the name pattern +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +name pattern +\end_layout + +\end_inset + +. +\end_layout + +\begin_layout Subsubsection* +Example: type, scope, and name parts of a variable match expression +\family typewriter + +\begin_inset CommandInset label +LatexCommand label +name "exa:match-expr-parts-variable" + +\end_inset + + +\end_layout + +\begin_layout LyX-Code +"const % Puma::...::parsed_%" +\end_layout + +\begin_layout Standard +This match expression describes the following requirements on a compared + variable name: +\end_layout + +\begin_layout Description +name: the variable name has to match the name pattern +\family typewriter +parsed_% +\end_layout + +\begin_layout Description +scope: the scope in which the variable is defined has to match +\family typewriter +Puma::...:: +\end_layout + +\begin_layout Description +type: the variable type has to match +\family typewriter +const % +\end_layout + +\begin_layout Standard +If an entity matches all parts of the match expression, it becomes an element + of the pointcut, which is defined and returned by the match expression. +\end_layout + +\begin_layout Standard +Descriptions of name, scope and type matching can be found in section +\begin_inset CommandInset ref +LatexCommand ref +reference "subsec:Commonly-Used-Matchings" + +\end_inset + +. + +\begin_inset Note Note +status open + +\begin_layout Plain Layout +TODO?: The following sections additionally describe the name matching of + special variables. +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Section +Predefined Pointcut Functions +\begin_inset CommandInset label +LatexCommand label +name "sec:Predefined" + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut function +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut!function +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +On the following pages a complete list of the pointcut functions supported + by AspectC++ is presented. + For every pointcut function it is indicated which type of pointcut is expected + as argument(s) and of which type the result pointcut is. + Thereby +\begin_inset Quotes eld +\end_inset + +N +\begin_inset Quotes erd +\end_inset + + stands for name pointcut and +\begin_inset Quotes eld +\end_inset + +C +\begin_inset Quotes erd +\end_inset + + for code pointcut. + The optionally given index is an assurance about the type of join point(s) + described by the result pointcut +\begin_inset Foot +status open + +\begin_layout Plain Layout +C, C +\begin_inset Formula $_{\textrm{C}}$ +\end_inset + +, C +\begin_inset Formula $_{\textrm{E}}$ +\end_inset + +, C +\begin_inset Formula $_{\textrm{B}}$ +\end_inset + +, C +\begin_inset Formula $_{\textrm{S}}$ +\end_inset + +, C +\begin_inset Formula $_{\textrm{G}}$ +\end_inset + +: Code (any, only +\emph on +\bar under +C +\bar default +all +\emph default + (without Builtin), only +\emph on +\bar under +E +\bar default +xecution +\emph default +, only +\emph on +\bar under +B +\bar default +uiltin +\emph default +, only +\emph on +\bar under +S +\bar default +et +\emph default +, only +\emph on +\bar under +G +\bar default +et +\emph default +); N, N +\begin_inset Formula $_{N}$ +\end_inset + +, N +\begin_inset Formula $_{C}$ +\end_inset + +, N +\begin_inset Formula $_{F}$ +\end_inset + +, N +\begin_inset Formula $_{T}$ +\end_inset + +N +\begin_inset Formula $_{V}$ +\end_inset + +: Names (any, only +\emph on +\bar under +N +\bar default +amespace +\emph default +, only +\emph on +\bar under +C +\bar default +lass +\emph default +, only +\emph on +\bar under +F +\bar default +unction +\emph default +, only +\emph on +\bar under +T +\bar default +ype +\emph default +, only +\emph on +\bar under +V +\bar default +ariable +\emph default +) +\end_layout + +\end_inset + +. + If a pointcut is used as argument of a pointcut function and the type of + some join points in argument pointcut does not match one of the expected + argument types of the pointcut function, these non-matching join points + are silently ignored. +\end_layout + +\begin_layout Subsection +Types +\end_layout + +\begin_layout Description +base +\series medium +( +\emph on +pointcut +\emph default +) +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +base@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{base()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut function!base@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{base()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + +N +\begin_inset Formula $_{C,F,V}$ +\end_inset + + +\begin_inset Formula $\rightarrow$ +\end_inset + +N +\begin_inset Formula $_{C,F,V}$ +\end_inset + + +\begin_inset Newline newline +\end_inset + +returns a pointcut +\shape italic + +\begin_inset Formula $p_{b}$ +\end_inset + + +\shape default + of name join points created as follows +\begin_inset Newline newline +\end_inset + + +\shape italic + +\begin_inset Formula $p_{b}\leftarrow\{$ +\end_inset + + +\shape default +all base classes of classes in +\shape italic +pointcut +\shape default + but not the classes in +\shape italic +pointcut +\shape default + +\begin_inset Formula $\}$ +\end_inset + +, +\begin_inset Newline newline +\end_inset + + +\shape italic + +\begin_inset Formula $p_{b}\leftarrow p{}_{b}\,||\,\{$ +\end_inset + + +\shape default +all member functions and data members of classes in +\begin_inset Formula $p_{b}$ +\end_inset + + +\begin_inset Formula $\}$ +\end_inset + +, +\begin_inset Newline newline +\end_inset + + +\shape italic + +\begin_inset Formula $p_{b}\leftarrow p{}_{b}\,||\,\{$ +\end_inset + + +\shape default +all previous definitions of member functions in +\shape italic +pointcut +\shape default + but not the member functions in +\shape italic +pointcut +\shape default + +\begin_inset Formula $\}$ +\end_inset + +, +\begin_inset Newline newline +\end_inset + + +\shape italic + +\begin_inset Formula $p_{b}\leftarrow p{}_{b}\,||\,\{$ +\end_inset + + +\shape default +all previous definitions of data members in +\shape italic +pointcut +\shape default + but not the data members in +\shape italic +pointcut +\shape default + +\begin_inset Formula $\}$ +\end_inset + + +\end_layout + +\begin_layout Description + +\shape italic +\begin_inset Note Note +status open + +\begin_layout Description +base +\series medium +( +\emph on +pointcut +\emph default +) +\series default + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + +N +\begin_inset Formula $_{F}$ +\end_inset + + +\begin_inset Formula $\rightarrow$ +\end_inset + +N +\begin_inset Formula $_{F}$ +\end_inset + + +\begin_inset Newline newline +\end_inset + +returns all previous definitions of member-functions in +\shape italic +pointcut +\shape default + but not the member-functions in +\shape italic +pointcut +\end_layout + +\begin_layout Description +base +\series medium +( +\emph on +pointcut +\emph default +) +\series default + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + +N +\begin_inset Formula $_{V}$ +\end_inset + + +\begin_inset Formula $\rightarrow$ +\end_inset + +N +\begin_inset Formula $_{V}$ +\end_inset + + +\begin_inset Newline newline +\end_inset + +returns all previous definitions of members in +\shape italic +pointcut +\shape default + but not the members in +\shape italic +pointcut +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Description +derived +\series medium +( +\emph on +pointcut +\emph default +) +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +derived@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{derived()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut function!derived@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{derived()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + +N +\begin_inset Formula $_{C,F,V}$ +\end_inset + + +\begin_inset Formula $\rightarrow$ +\end_inset + +N +\begin_inset Formula $_{C,F,V}$ +\end_inset + + +\begin_inset Newline newline +\end_inset + +returns a pointcut +\shape italic + +\begin_inset Formula $p_{d}$ +\end_inset + + +\shape default + of name join points created as follows +\begin_inset Newline newline +\end_inset + + +\shape italic + +\begin_inset Formula $p_{d}\leftarrow\{$ +\end_inset + + +\shape default +all classes in +\shape italic +pointcut +\shape default + and all classes derived from them +\begin_inset Formula $\}$ +\end_inset + +, +\begin_inset Newline newline +\end_inset + + +\shape italic + +\begin_inset Formula $p_{d}\leftarrow p{}_{d}\,||\,\{$ +\end_inset + + +\shape default +all member functions and data members of classes in +\begin_inset Formula $p_{d}$ +\end_inset + + +\begin_inset Formula $\}$ +\end_inset + +, +\begin_inset Newline newline +\end_inset + + +\shape italic + +\begin_inset Formula $p_{d}\leftarrow p{}_{d}\,||\,\{$ +\end_inset + + +\shape default +all member functions in +\shape italic + +\begin_inset Formula $pointcut$ +\end_inset + + +\shape default + and all redefinitions of these member functions in derived classes +\begin_inset Formula $\}$ +\end_inset + +, +\begin_inset Newline newline +\end_inset + + +\shape italic + +\begin_inset Formula $p_{d}\leftarrow p{}_{d}\,||\,\{$ +\end_inset + + +\shape default +all data members in +\shape italic + +\begin_inset Formula $pointcut$ +\end_inset + + +\shape default + and all redefinitions of these data members in derived classes +\begin_inset Formula $\}$ +\end_inset + + +\end_layout + +\begin_layout Subsubsection* +Example: derived function matching +\begin_inset CommandInset label +LatexCommand label +name "exa:derived_function_matching" + +\end_inset + + +\end_layout + +\begin_layout LyX-Code +struct A {}; +\end_layout + +\begin_layout LyX-Code + +\family typewriter +struct B : public A { void f(); }; +\end_layout + +\begin_layout LyX-Code + +\family typewriter +struct C : public B { void f(); }; +\end_layout + +\begin_layout LyX-Code + +\family typewriter +aspect Z { +\end_layout + +\begin_layout LyX-Code + +\family typewriter + advice execution(derived("A")) : before() { +\end_layout + +\begin_layout LyX-Code + +\family typewriter + // before execution of B::f() or C::f() +\end_layout + +\begin_layout LyX-Code + +\family typewriter + } +\end_layout + +\begin_layout LyX-Code + +\family typewriter +}; +\end_layout + +\begin_layout Subsubsection* +Example: type matching +\begin_inset CommandInset label +LatexCommand label +name "exa:type-matching" + +\end_inset + + +\end_layout + +\begin_layout Standard +A software may contain the following class hierarchy. + +\end_layout + +\begin_layout LyX-Code +class Shape { ... + }; +\end_layout + +\begin_layout LyX-Code +class Scalable { ... + }; +\end_layout + +\begin_layout LyX-Code +class Point : public Shape { ... + }; +\end_layout + +\begin_layout LyX-Code +... +\end_layout + +\begin_layout LyX-Code +class Rectangle : public Line, public Rotatable { ... + }; +\end_layout + +\begin_layout Standard +With the following aspect a special feature is added to a designated set + of classes of this class hierarchy. +\end_layout + +\begin_layout LyX-Code +aspect Scale { +\end_layout + +\begin_layout LyX-Code + pointcut scalable() = "Rectangle" || +\end_layout + +\begin_layout LyX-Code + (base("Rectangle") && derived("Point")); +\end_layout + +\begin_layout LyX-Code + +\end_layout + +\begin_layout LyX-Code + advice "Point" : slice class : public Scalable; +\end_layout + +\begin_layout LyX-Code + advice scalable() : slice class { +\end_layout + +\begin_layout LyX-Code + void scale(int value) { ... + } +\end_layout + +\begin_layout LyX-Code + }; +\end_layout + +\begin_layout LyX-Code +}; +\end_layout + +\begin_layout Standard +The pointcut describes the classes +\family typewriter +Point +\family default + and +\family typewriter +Rectangle +\family default + and all classes derived from +\family typewriter +Point +\family default + that are direct or indirect base classes of +\family typewriter +Rectangle +\family default +. + With the first advice +\family typewriter +Point +\family default + gets a new base class. + The second advice adds a corresponding method to all classes in the pointcut. +\end_layout + +\begin_layout Subsection +Control Flow +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +control flow +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Description +cflow +\series medium +( +\emph on +pointcut +\emph default +) +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +cflow@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{cflow()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut function!cflow@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{cflow()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + +C +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\begin_inset Newline newline +\end_inset + +captures join points occurring in the dynamic execution context of join + points in +\shape italic +pointcut +\shape default +. + Currently the language features being used in the argument pointcut are + restricted. + The argument is not allowed to contain any context variable bindings (see + +\begin_inset CommandInset ref +LatexCommand ref +reference "subsec:context" + +\end_inset + +) or other pointcut functions which have to be evaluated at runtime like + +\series bold +cflow +\series default +( +\emph on +pointcut +\emph default +) itself. +\end_layout + +\begin_layout Subsubsection* +Example: control flow dependant advice activation +\begin_inset CommandInset label +LatexCommand label +name "exa:control-flow" + +\end_inset + + +\end_layout + +\begin_layout Standard +The following example demonstrates the use of the +\series bold +cflow +\series default + pointcut function. +\end_layout + +\begin_layout LyX-Code +class Bus { +\end_layout + +\begin_layout LyX-Code + void out (unsigned char); +\end_layout + +\begin_layout LyX-Code + unsigned char in (); +\end_layout + +\begin_layout LyX-Code +}; +\end_layout + +\begin_layout Standard +Consider the class +\family typewriter +Bus +\family default + shown above. + It might be part of an operating system kernel and is used there to access + peripheral devices via a special I/O bus. + The execution of the member functions +\family typewriter +in() +\family default + and +\family typewriter +out() +\family default + should not be interrupted, because this would break the timing of the bus + communication. + Therefore, we decide to implement an interrupt synchronization aspect that + disables interrupts during the execution of in() and out(): +\end_layout + +\begin_layout Standard +\begin_inset listings +lstparams "basicstyle={\ttfamily},breaklines=true,showstringspaces=false" +inline false +status open + +\begin_layout Plain Layout + +aspect BusIntSync { +\end_layout + +\begin_layout Plain Layout + + pointcut critical() = execution("% Bus::%(...)"); +\end_layout + +\begin_layout Plain Layout + + advice critical() && !cflow(execution("% os::int_handler()")) : around() + { +\end_layout + +\begin_layout Plain Layout + + os::disable_ints(); +\end_layout + +\begin_layout Plain Layout + + tjp->proceed(); +\end_layout + +\begin_layout Plain Layout + + os::enable_ints(); +\end_layout + +\begin_layout Plain Layout + + } +\end_layout + +\begin_layout Plain Layout + +}; +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +As the bus driver code might also be called from an interrupt handler, the + interrupts should not be disabled in any case. + Therefore, the pointcut expression exploits the +\series bold +cflow() +\series default + pointcut function to add a runtime condition for the advice activation. + The advice body should only be executed if the control flow did not come + from the interrupt handler +\family typewriter +os::int_handler() +\family default +, because it is not interruptable by definition and +\family typewriter +os::enable_ints() +\family default + in the advice body would turn on the interrupts too early. +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +control flow +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Subsection +Scope +\end_layout + +\begin_layout Description +within +\series medium +( +\emph on +pointcut +\emph default +) +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +within@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{within()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut function!within@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{within()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + +N +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\begin_inset Newline newline +\end_inset + +returns all code join points that are located directly inside or at a name + join point in +\shape italic +pointcut +\end_layout + +\begin_layout Description +member +\series medium +( +\emph on +pointcut +\emph default +) +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +member@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{member()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut function!member@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{member()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + +N +\begin_inset Formula $\rightarrow$ +\end_inset + +N +\begin_inset Newline newline +\end_inset + +maps the scopes given in +\emph on +pointcut +\emph default + to any contained named entities. + Thus a class name for example is mapped to all contained member functions, + variables and nested types. +\end_layout + +\begin_layout Subsubsection* +Example: matching in scopes +\begin_inset CommandInset label +LatexCommand label +name "exa:matching-in-scopes" + +\end_inset + + +\end_layout + +\begin_layout LyX-Code +aspect Logger { +\end_layout + +\begin_layout LyX-Code + pointcut calls() = +\end_layout + +\begin_layout LyX-Code + call("void transmit()") && within("Transmitter"); +\end_layout + +\begin_layout LyX-Code + +\end_layout + +\begin_layout LyX-Code + advice calls() : around() { +\end_layout + +\begin_layout LyX-Code + cout << "transmitting ... + " << flush; +\end_layout + +\begin_layout LyX-Code + tjp->proceed(); +\end_layout + +\begin_layout LyX-Code + cout << "finished." << endl; +\end_layout + +\begin_layout LyX-Code + } +\end_layout + +\begin_layout LyX-Code +}; +\end_layout + +\begin_layout Standard +This aspect inserts code logging all calls to +\family typewriter +transmit +\family default + that are within the methods of class +\family typewriter +Transmitter +\family default +. + +\end_layout + +\begin_layout Subsection +Functions +\begin_inset CommandInset label +LatexCommand label +name "subsec:Functions" + +\end_inset + + +\end_layout + +\begin_layout Description +call +\series medium +( +\emph on +pointcut +\emph default +) +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +call@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{call()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut function!call@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{call()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + +N +\begin_inset Formula $_{F}$ +\end_inset + + +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\begin_inset Formula $_{C}$ +\end_inset + + +\begin_inset Newline newline +\end_inset + +returns all code join points where a user provided function or member function + in +\shape italic +pointcut +\shape default + is called. + The resulting join points are located in the scope of the resp. + caller meaning where the function or member functions is called. + The pointcut does not include join points at calls to built-in operators. + +\end_layout + +\begin_layout Description +execution +\series medium +( +\emph on +pointcut +\emph default +) +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +execution@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{execution()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status open + +\begin_layout Plain Layout +pointcut function!execution@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{execution()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + +N +\begin_inset Formula $_{F}$ +\end_inset + + +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\begin_inset Formula $_{E}$ +\end_inset + + +\begin_inset Newline newline +\end_inset + +returns all code join points where a function or member function in +\shape italic +pointcut +\shape default + is executed. + The resulting join points are located in the scope of the callee meaning + where the function or member function is defined/implemented. +\end_layout + +\begin_layout Subsubsection* +Example: function matching +\begin_inset CommandInset label +LatexCommand label +name "exa:function-matching" + +\end_inset + + +\end_layout + +\begin_layout Standard +The following aspect weaves debugging code into a program that checks whether + a method is called on a null pointer and whether the argument of the call + is null. +\end_layout + +\begin_layout Standard +\begin_inset listings +lstparams "basicstyle={\ttfamily},breaklines=true,showstringspaces=false" +inline false +status open + +\begin_layout Plain Layout + +aspect Debug { +\end_layout + +\begin_layout Plain Layout + + pointcut fct() = "% MemPool::dealloc(void*)"; +\end_layout + +\begin_layout Plain Layout + + pointcut exec() = execution(fct()); +\end_layout + +\begin_layout Plain Layout + + pointcut calls() = call(fct()); +\end_layout + +\begin_layout Plain Layout + +\end_layout + +\begin_layout Plain Layout + + advice exec() && args(ptr) : before(void *ptr) { +\end_layout + +\begin_layout Plain Layout + + assert(ptr && "argument is NULL"); +\end_layout + +\begin_layout Plain Layout + + } +\end_layout + +\begin_layout Plain Layout + + advice calls() : before() { +\end_layout + +\begin_layout Plain Layout + + assert(tjp->target() && "'this' is NULL"); +\end_layout + +\begin_layout Plain Layout + + } +\end_layout + +\begin_layout Plain Layout + +}; +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +The first advice provides code to check the argument of the function +\family typewriter +dealloc +\family default + before the function is executed. + A check whether +\family typewriter +dealloc +\family default + is called on a null object is provided by the second advice. + This is realized by checking the target of the call. +\end_layout + +\begin_layout Subsection +Built-in Operators +\begin_inset CommandInset label +LatexCommand label +name "subsec:builtin_operators" + +\end_inset + + +\end_layout + +\begin_layout Description +builtin +\series medium +( +\emph on +pointcut +\emph default +) +\series default + +\begin_inset Index idx +status open + +\begin_layout Plain Layout +builtin@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{builtin()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status open + +\begin_layout Plain Layout +pointcut function!builtin@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{builtin()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status open + +\begin_layout Plain Layout +built-in operators!builtin@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{builtin()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + +N +\begin_inset Formula $_{F}$ +\end_inset + + +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\begin_inset Formula $_{B}$ +\end_inset + + +\begin_inset Newline newline +\end_inset + +returns all code join points where a built-in operator in +\shape italic +pointcut +\shape default + is called. +\begin_inset Newline newline +\end_inset + +This pointcut function does not return join points at constructor or destructor + calls. + See section +\begin_inset CommandInset ref +LatexCommand nameref +reference "subsec:Object-Construction-and" + +\end_inset + + ( +\begin_inset CommandInset ref +LatexCommand ref +reference "subsec:Object-Construction-and" + +\end_inset + +) to find out how to describe these join points. +\begin_inset Newline newline +\end_inset + +The builtin pointcut function is a new feature that was introduced in version + 2.0 and is therefore not enabled by default to avoid compatibility issues + (e.g., if someone named a pointcut +\begin_inset Quotes eld +\end_inset + +builtin +\begin_inset Quotes erd +\end_inset + +). + The +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{{-}{-}builtin +\backslash +_operators} +\end_layout + +\end_inset + + command-line argument enables the described functionality. +\end_layout + +\begin_layout Standard +The intersection of the results of +\series bold +call +\series default + and +\series bold +builtin +\series default + always yields the empty pointcut: +\begin_inset Newline newline +\end_inset + +call( +\emph on +pointcut +\emph default +) +\begin_inset space ~ +\end_inset + +&& +\series medium +\emph on + +\begin_inset space ~ +\end_inset + + +\series default +\emph default +builtin( +\series medium +\emph on +pointcut +\series default +\emph default +) +\series medium +\emph on + +\series default +\emph default += +\begin_inset Formula $\varnothing\quad\forall$ +\end_inset + + +\emph on +pointcut +\end_layout + +\begin_layout Subsubsection* +Example: operator matching +\begin_inset CommandInset label +LatexCommand label +name "exa:builtin-matching" + +\end_inset + + +\end_layout + +\begin_layout Standard +The following aspect weaves code into a program that checks whether a null-point +er will be dereferenced. + If this occurs, the advice will provide the code position on the error + stream. +\end_layout + +\begin_layout Standard +\begin_inset listings +lstparams "basicstyle={\ttfamily},breaklines=true,showstringspaces=false" +inline false +status open + +\begin_layout Plain Layout + +aspect ProblemReporter { +\end_layout + +\begin_layout Plain Layout + + advice builtin("% operator *(%)") : before() { +\end_layout + +\begin_layout Plain Layout + + if(*tjp->arg<0>() == 0) { +\end_layout + +\begin_layout Plain Layout + + cerr << tjp->filename() << " (Line " << tjp->line() << "): dereferencing + of null-pointer!" << endl; +\end_layout + +\begin_layout Plain Layout + + } +\end_layout + +\begin_layout Plain Layout + + } +\end_layout + +\begin_layout Plain Layout + +}; +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Subsubsection +Limitations +\begin_inset CommandInset label +LatexCommand label +name "subsec:builtin_limitations" + +\end_inset + + +\begin_inset Index CommandInset label +status open + +\begin_layout Plain Layout +builtin!limitations +\end_layout + +\end_inset + + +\begin_inset Index idx +status open + +\begin_layout Plain Layout +built-in operators!limitations +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +Some built-in operators could not be fully supported. + For example, weaving advice code for built-in operators in +\series bold +constant expressions +\series default + would destroy the constancy of the expressions and inhibit evaluation at + compile time. + Therefore, operators in constant expressions are not matched. + The following code listing gives some examples for operators in constant + expressions. +\begin_inset listings +lstparams "basicstyle={\ttfamily},breaklines=true,tabsize=2" +inline false +status open + +\begin_layout Plain Layout + +class ExampleClass { +\end_layout + +\begin_layout Plain Layout + + static const int const_member = 5 * 2; +\end_layout + +\begin_layout Plain Layout + + unsigned int bitfield : 4 / 2; +\end_layout + +\begin_layout Plain Layout + +}; +\end_layout + +\begin_layout Plain Layout + +const int const_two = 3 - 1; +\end_layout + +\begin_layout Plain Layout + +static char char_array[const_two + 5]; +\end_layout + +\begin_layout Plain Layout + +enum ExampleEnum { +\end_layout + +\begin_layout Plain Layout + + ENUM_VALUE = const_two + 1 +\end_layout + +\begin_layout Plain Layout + +}; +\end_layout + +\begin_layout Plain Layout + +switch(const int const_temp = 1) { +\end_layout + +\begin_layout Plain Layout + + case const_temp + 1: { +\end_layout + +\begin_layout Plain Layout + + // ... +\end_layout + +\begin_layout Plain Layout + + break; +\end_layout + +\begin_layout Plain Layout + + } +\end_layout + +\begin_layout Plain Layout + +} +\end_layout + +\end_inset + +A further limitation results from the fact, that the C++-standard forbids + +\series bold +pointers and references to bit-fields +\series default +. + Thus all operators that refer to a bit-field (e.g. + the assignment- or increment-/decrement-operator needs a reference as first + argument) are not supported. +\begin_inset Newline newline +\end_inset + + +\begin_inset Newline newline +\end_inset + +Moreover any operator that has an +\series bold +anonymous/unnamed or local type or a type with no linkage +\series default + as argument or result is not supported (because these types shall not be + used as a template argument which makes weaving impossible in most cases). +\begin_inset Newline newline +\end_inset + + +\begin_inset Newline newline +\end_inset + +Additionally +\series bold +postfix increment/decrement operators +\series default + have a second implicit argument of type +\family typewriter +int +\family default + to distinguish between pre- and postfix operators. + So e.g. + +\family typewriter + +\begin_inset Quotes eld +\end_inset + +% operator ++(%, int) +\begin_inset Quotes erd +\end_inset + + +\family default + matches the postfix increment operator and +\family typewriter + +\begin_inset Quotes eld +\end_inset + +% operator ++(%) +\begin_inset Quotes erd +\end_inset + + +\family default + matches the prefix increment operator. +\begin_inset Newline newline +\end_inset + + +\begin_inset Newline newline +\end_inset + +Also the +\series bold +address-of operator +\family typewriter +& +\family default +\series default + is not supported, if the argument is a data member or member function, + because these types do not exist as type of a variable. +\begin_inset Newline newline +\end_inset + + +\begin_inset Newline newline +\end_inset + +Furthermore the C++-standard states that if the result of .* or ->* is a + function, that result can be used only as the operand for the function + call operator +\family typewriter +() +\family default +. + Therefore the +\series bold +pointer to member operators +\family typewriter +.* +\family default + and +\family typewriter +->* +\family default +\series default + +\begin_inset Index idx +status open + +\begin_layout Plain Layout +pointer to member +\end_layout + +\end_inset + + that get a member function pointer as second argument are not supported, + because a caching of the result is not possible. +\begin_inset Newline newline +\end_inset + + +\begin_inset Newline newline +\end_inset + +At last there are some limitations with the +\series bold +short-circuiting +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +short circuit evaluation +\end_layout + +\end_inset + + operators +\family typewriter +&& +\family default +, +\family typewriter +|| +\family default + and +\family typewriter +?: +\family default +\series default +. + If the second or third argument is not evaluated, tjp->args() will return + a null-pointer for the corresponding argument. + Additionally the result of the args pointcut function (see +\begin_inset CommandInset ref +LatexCommand ref +reference "subsec:context" + +\end_inset + +) is determined at runtime, if an short-circuit argument is bound with the + args pointcut function . + Thus the advice code in the following example is only executed, if the + first argument evaluates to +\family typewriter +true +\family default + so that the second argument is available. + In case of +\family typewriter +|| +\family default + the first argument have to be +\family typewriter +false +\family default + to make the second argument available and in case of +\family typewriter +?: +\family default + the first argument makes the decision about the availability of the second + resp. + third argument. + +\begin_inset listings +lstparams "basicstyle={\ttfamily},breaklines=true,showstringspaces=false,tabsize=2" +inline false +status open + +\begin_layout Plain Layout + +advice builtin("% operator &&(bool, bool)") && args("%", b2) : before(bool + b2) { +\end_layout + +\begin_layout Plain Layout + + // advice code +\end_layout + +\begin_layout Plain Layout + +} +\end_layout + +\end_inset + +A +\series bold +complete list with all limitations and not supported operators +\series default + can be found in the next section +\begin_inset CommandInset ref +LatexCommand ref +reference "subsec:builtin_supported_operators" + +\end_inset + +. +\end_layout + +\begin_layout Subsubsection +Supported And Not Supported Operators +\begin_inset CommandInset label +LatexCommand label +name "subsec:builtin_supported_operators" + +\end_inset + + +\begin_inset Index idx +status open + +\begin_layout Plain Layout +builtin!supported operators +\end_layout + +\end_inset + + +\begin_inset Index idx +status open + +\begin_layout Plain Layout +built-in operators!supported operators +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +This section contains information about the builtin pointcut function in + terms of supported operators. +\begin_inset Newline newline +\end_inset + +Table +\begin_inset CommandInset ref +LatexCommand ref +reference "tab:builtin_supported_operators" + +\end_inset + + shows all operators that are fully or partly supported and indicates the + special characteristics of these operators, if available. + For more information see section +\begin_inset CommandInset ref +LatexCommand ref +reference "subsec:builtin_limitations" + +\end_inset + +. +\begin_inset Newline newline +\end_inset + +Table +\begin_inset CommandInset ref +LatexCommand ref +reference "tab:builtin_not_supported_operators" + +\end_inset + + shows not supported operators. +\begin_inset Separator latexpar +\end_inset + + +\end_layout + +\begin_layout Standard +\align center +\begin_inset Tabular + + + + + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +operator and example +\begin_inset CommandInset label +LatexCommand label +name "tab:builtin_supported_operators" + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +special characteristics +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +unary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter ++ +\begin_inset ERT +status open + +\begin_layout Plain Layout + +{} +\end_layout + +\end_inset + ++ +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a+ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +{} +\end_layout + +\end_inset + ++ +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +postfix operator (second argument of type +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{int} +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +unary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +- +\begin_inset ERT +status open + +\begin_layout Plain Layout + +{} +\end_layout + +\end_inset + +- +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a- +\begin_inset ERT +status open + +\begin_layout Plain Layout + +{} +\end_layout + +\end_inset + +- +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +postfix operator (second argument of type +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{int} +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +unary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter ++ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +{} +\end_layout + +\end_inset + ++ +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter ++ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +{} +\end_layout + +\end_inset + ++a +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +prefix operator; not supported if +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{a} +\end_layout + +\end_inset + + is a bit-field +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +unary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +- +\begin_inset ERT +status open + +\begin_layout Plain Layout + +{} +\end_layout + +\end_inset + +- +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +- +\begin_inset ERT +status open + +\begin_layout Plain Layout + +{} +\end_layout + +\end_inset + +-a +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +prefix operator; not supported if +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{a} +\end_layout + +\end_inset + + is a bit-field +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +unary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +& +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +&a +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +not supported if +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{a} +\end_layout + +\end_inset + + is a member +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +unary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +* +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +*a +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +unary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter ++ +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter ++a +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +unary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +- +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +-a +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +unary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +\begin_inset Formula $\sim$ +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +\begin_inset Formula $\sim$ +\end_inset + +a +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +unary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +! +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +!a +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +.* +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a.*b +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +not supported if +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{b} +\end_layout + +\end_inset + + is a member function pointer +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +->* +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a->*b +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +not supported if +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{b} +\end_layout + +\end_inset + + is a member function pointer +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +* +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a*b +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +/ +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a/b +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +% +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a%b +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +in match expressions: escape +\family typewriter +% +\family default + with +\family typewriter +%% +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter ++ +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a+b +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +- +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a-b +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +< +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +{} +\end_layout + +\end_inset + +< +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a< +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +{} +\end_layout + +\end_inset + + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +> +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +{} +\end_layout + +\end_inset + +> +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a> +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +{} +\end_layout + +\end_inset + +>b +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +< +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +> +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a>b +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +<= +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a<=b +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +>= +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a>=b +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +== +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a==b +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +!= +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a!=b +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +& +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a&b +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +‸ +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a‸b +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +| +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a|b +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +&& +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a&&b +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +limitations due to short-circuit evaluation +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +short circuit evaluation +\end_layout + +\end_inset + + (see +\begin_inset CommandInset ref +LatexCommand ref +reference "subsec:builtin_limitations" + +\end_inset + +) +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +|| +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a||b +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +limitations due to short-circuit evaluation (see +\begin_inset CommandInset ref +LatexCommand ref +reference "subsec:builtin_limitations" + +\end_inset + +) +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter += +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a=b +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +copy-assignment not supported; +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +not supported if +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{a} +\end_layout + +\end_inset + + is a bit-field +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +*= +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a*=b +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +not supported if +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{a} +\end_layout + +\end_inset + + is a bit-field +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +/= +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a/=b +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +not supported if +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{a} +\end_layout + +\end_inset + + is a bit-field +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +%= +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a%=b +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +in match expressions: escape +\family typewriter +%= +\family default + with +\family typewriter +%%=; +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +not supported if +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{a} +\end_layout + +\end_inset + + is a bit-field +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter ++= +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a+=b +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +not supported if +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{a} +\end_layout + +\end_inset + + is a bit-field +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +-= +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a-=b +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +not supported if +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{a} +\end_layout + +\end_inset + + is a bit-field +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +< +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +{} +\end_layout + +\end_inset + +<= +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a< +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +{} +\end_layout + +\end_inset + +<=b +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +not supported if +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{a} +\end_layout + +\end_inset + + is a bit-field +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +> +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +{} +\end_layout + +\end_inset + +>= +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a> +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +{} +\end_layout + +\end_inset + +>=b +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +not supported if +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{a} +\end_layout + +\end_inset + + is a bit-field +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +&= +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a&=b +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +not supported if +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{a} +\end_layout + +\end_inset + + is a bit-field +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +|= +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a|=b +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +not supported if +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{a} +\end_layout + +\end_inset + + is a bit-field +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +‸= +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a‸=b +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +not supported if +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{a} +\end_layout + +\end_inset + + is a bit-field +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +[] +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a[b] +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +ternary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +?: +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a?b:c +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +limitations due to short-circuit evaluation (see +\begin_inset CommandInset ref +LatexCommand ref +reference "subsec:builtin_limitations" + +\end_inset + +) +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +continuation on next page... +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\end_inset + + +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +addtocounter{table}{-1}%because longtable did a +1 +\end_layout + +\begin_layout Plain Layout + + +\backslash +captionof{table}{operators that are (partly) supported by the builtin pointcut + function} +\backslash +vfill +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +\align center +\begin_inset ERT +status open + +\begin_layout Plain Layout + +$ +\backslash +,$ +\backslash + +\backslash +$ +\backslash +,$ +\backslash + +\backslash +$ +\backslash +,$ +\end_layout + +\end_inset + + +\begin_inset Tabular + + + + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +operator and example +\begin_inset CommandInset label +LatexCommand label +name "tab:builtin_not_supported_operators" + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +, +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a,b +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +-> +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a->b +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +binary +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +. +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +a.b +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +new +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +new a +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +delete +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +delete a +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +new[] +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +new[] a +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +delete[] +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +delete[] a +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family sans +implicit conversions +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +operators in constant expressions (see +\begin_inset CommandInset ref +LatexCommand ref +reference "subsec:builtin_limitations" + +\end_inset + +) +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +operators with an anonymous/unnamed or local type (see +\begin_inset CommandInset ref +LatexCommand ref +reference "subsec:builtin_limitations" + +\end_inset + +) +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +operators that have a type with no linkage (see +\begin_inset CommandInset ref +LatexCommand ref +reference "subsec:builtin_limitations" + +\end_inset + +) +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\end_inset + + +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +addtocounter{table}{-1}%because longtable did a +1 +\end_layout + +\begin_layout Plain Layout + + +\backslash +captionof{table}{operators that are not supported by the builtin pointcut + function} +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Subsection +Object Construction and Destruction +\begin_inset CommandInset label +LatexCommand label +name "subsec:Object-Construction-and" + +\end_inset + + +\end_layout + +\begin_layout Description +construction +\series medium +( +\emph on +pointcut +\emph default +) +\series default + +\begin_inset Index idx +status open + +\begin_layout Plain Layout +construction@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{construction()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status open + +\begin_layout Plain Layout +pointcut function!construction@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{construction()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + +N +\begin_inset Formula $_{C}$ +\end_inset + + +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\begin_inset Formula $_{Cons}$ +\end_inset + + +\begin_inset Newline newline +\end_inset + +returns all code join points where an instance of a class in +\shape italic +pointcut +\shape default + is constructed. + The construction join point begins after all base class and member construction + join points. + It can be imagined as the execution of the constructor. + However, advice for construction join points work, even if there is no + constructor defined explicitly. + A construction join point has arguments and argument types, which can be + exposed or filtered, e.g. + by using the +\series bold +args +\series default + pointcut function. +\end_layout + +\begin_layout Description +destruction +\series medium +( +\emph on +pointcut +\emph default +) +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +destruction@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{destruction()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut function!destruction@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{destruction()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + +N +\begin_inset Formula $_{C}$ +\end_inset + + +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\begin_inset Formula $_{Des}$ +\end_inset + + +\begin_inset Newline newline +\end_inset + +returns all code join points where an instance of a class in +\shape italic +pointcut +\shape default + is destructed. + The destruction join point ends before the destruction join point of all + members and base classes. + It can be imagined as the execution of the destructor, although a destructor + does not to be defined explicitly. + A destruction join point has an empty argument list. +\end_layout + +\begin_layout Subsubsection* +Example: instance counting +\begin_inset CommandInset label +LatexCommand label +name "exa:instance-counting" + +\end_inset + + +\end_layout + +\begin_layout Standard +The following aspect counts how many instances of the class +\family typewriter +ClassOfInterest +\family default + are created and destroyed. +\end_layout + +\begin_layout LyX-Code +aspect InstanceCounting { +\end_layout + +\begin_layout LyX-Code + // the class for which instances should be counted +\end_layout + +\begin_layout LyX-Code + pointcut observed() = "ClassOfInterest"; +\end_layout + +\begin_layout LyX-Code + // count constructions and destructions +\end_layout + +\begin_layout LyX-Code + advice construction (observed ()) : before () { +\end_layout + +\begin_layout LyX-Code + _created++; } +\end_layout + +\begin_layout LyX-Code + advice destruction (observed ()) : after () { +\end_layout + +\begin_layout LyX-Code + _destroyed++; } +\end_layout + +\begin_layout LyX-Code + // counters +\end_layout + +\begin_layout LyX-Code + int _created, _destroyed; +\end_layout + +\begin_layout LyX-Code +public: +\end_layout + +\begin_layout LyX-Code + // Singleton aspects can have a default constructor +\end_layout + +\begin_layout LyX-Code + InstanceCounting () { _created = _destroyed = 0; } +\end_layout + +\begin_layout LyX-Code +}; +\end_layout + +\begin_layout Standard +The implementation of this aspect is straightforward. + Two counters are initialized by the aspect constructor and incremented + by the construction/destruction advice. + By defining +\family typewriter +observed() +\family default + as a pure virtual pointcut the aspect can easily be transformed into a + reusable abstract aspect. +\end_layout + +\begin_layout Subsection +Variables +\end_layout + +\begin_layout Description +get +\series medium +( +\emph on +pointcut +\emph default +) +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +get@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{get()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut function!get@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{get()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + +N +\begin_inset Formula $_{V}$ +\end_inset + + +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\begin_inset Formula $_{G}$ +\end_inset + + +\begin_inset Newline newline +\end_inset + +returns all code join points where a global variable or data member in +\shape italic +pointcut +\shape default + is read. + The get join points are located at implicit lvalue-to-rvalue conversions + according to the C++ standard. + In addition, the get join points are located within all built-in compound-assig +nment operators, and within the built-in increment and decrement operators. +\end_layout + +\begin_layout Description +set +\series medium +( +\emph on +pointcut +\emph default +) +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +set@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{set()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut function!set@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{set()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + +N +\begin_inset Formula $_{V}$ +\end_inset + + +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\begin_inset Formula $_{S}$ +\end_inset + + +\begin_inset Newline newline +\end_inset + +returns all code join points where a global variable or data member in +\shape italic +pointcut +\shape default + is modified. + The set join points are located within all built-in assignment operators, + and within the built-in increment and decrement operators. + The initialization of a global variable or data member provides no set + join point. +\end_layout + +\begin_layout Description +ref +\series medium +( +\emph on +pointcut +\emph default +) +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +ref@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{ref()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut function!ref@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{ref()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + +N +\begin_inset Formula $_{V}$ +\end_inset + + +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\begin_inset Formula $_{R}$ +\end_inset + + +\begin_inset Newline newline +\end_inset + +provides all join points where a reference (reference type or pointer) to + a global variable or data member in the +\emph on +pointcut +\emph default + is created. + The ref join points are located within the built-in address-of operator + +\family typewriter +& +\family default +, if the operand is a global variable or data member. + In addition, the ref join points are located before the initialization + of a variable of reference type, including return values. + Moreover, the binding of a reference parameter of a function, including + default values, provides ref join points. + The ref join points are also located within implicit array-to-pointer conversio +ns according to the C++ standard. +\end_layout + +\begin_layout Subsubsection* +Example: variable matching +\begin_inset CommandInset label +LatexCommand label +name "exa:variable-matching" + +\end_inset + + +\end_layout + +\begin_layout Standard +The following aspect observes the modification of all variables (in any + scope) of the type +\family typewriter +int +\family default +. + When such an integer variable is modified, the aspect reports the name + of the variable and its new value, obtained by +\family typewriter +*tjp->entity() +\family default +. +\end_layout + +\begin_layout Standard +\begin_inset listings +lstparams "basicstyle={\ttfamily},breaklines=true,showstringspaces=false" +inline false +status open + +\begin_layout Plain Layout + +aspect IntegerModification { +\end_layout + +\begin_layout Plain Layout + + advice set("int ...::%") : after() { +\end_layout + +\begin_layout Plain Layout + + cout << "Setting variable " +\end_layout + +\begin_layout Plain Layout + + << tjp->signature() << " to " +\end_layout + +\begin_layout Plain Layout + + << *tjp->entity() << endl; +\end_layout + +\begin_layout Plain Layout + + } +\end_layout + +\begin_layout Plain Layout + +}; +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Subsubsection +Limitations +\end_layout + +\begin_layout Standard +The get and set pointcut functions cover variables of fundamental type, + such as integer and floating-point types, and arrays thereof. + Variables of any pointer type and arrays of pointers are also supported. + The get and set pointcut functions do not support +\series bold +variables of class type, unions, enumerations, bitfields, and references +\series default +. +\begin_inset Newline newline +\end_inset + + +\begin_inset Newline newline +\end_inset + +The get, set, and ref pointcut functions match only if the variable is accessed + directly by its name. + +\series bold +Indirect variable access via pointer or reference +\series default + does not match. +\begin_inset Newline newline +\end_inset + + +\begin_inset Newline newline +\end_inset + +The get, set, and ref pointcut functions do not match for +\series bold +local variables +\series default +. +\begin_inset Newline newline +\end_inset + + +\begin_inset Newline newline +\end_inset + +The get, set, and ref joinpoints are not located within +\series bold +constant expressions +\series default +, such as the built-in operator +\family typewriter +sizeof +\family default +. +\end_layout + +\begin_layout Subsubsection +Compatibility +\end_layout + +\begin_layout Standard +The get, set, and ref pointcut functions are new features that were introduced + in version 2.0 and are therefore not enabled by default to avoid compatibility + issues (e.g., if someone named a pointcut +\begin_inset Quotes eld +\end_inset + +get +\begin_inset Quotes erd +\end_inset + +). + The +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{{-}{-}data +\backslash +_joinpoints} +\end_layout + +\end_inset + + command-line argument enables the described functionality. +\end_layout + +\begin_layout Subsection +\begin_inset CommandInset label +LatexCommand label +name "subsec:context" + +\end_inset + +Context +\end_layout + +\begin_layout Description +that +\series medium +( +\emph on +type +\begin_inset space ~ +\end_inset + +pattern +\emph default +) +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +that@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{that()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut function!that@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{that()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + +N +\begin_inset Formula $_{T}$ +\end_inset + + +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\begin_inset Newline newline +\end_inset + +returns all code join points where the current C++ +\family typewriter +this +\family default + pointer refers to an object which is an instance of a type that is compatible + to the type described by +\shape italic +type pattern +\end_layout + +\begin_layout Description +target +\series medium +( +\emph on +type +\begin_inset space ~ +\end_inset + +pattern +\emph default +) +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +target@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{target()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut function!target@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{target()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + +N +\begin_inset Formula $_{T}$ +\end_inset + + +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\begin_inset Newline newline +\end_inset + +returns all code join points where the target object of a call/set/get is + an instance of a type that is compatible to the type described by +\shape italic +type pattern +\end_layout + +\begin_layout Description +result +\series medium +( +\emph on +type +\begin_inset space ~ +\end_inset + +pattern +\emph default +) +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +result@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{result()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut function!base@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{base()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + +N +\begin_inset Formula $_{T}$ +\end_inset + + +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\begin_inset Newline newline +\end_inset + +returns all code join points where the type of the return value of a call/builti +n/execution/get is matched by +\shape italic +type pattern +\end_layout + +\begin_layout Description +args +\series medium +( +\emph on +type +\begin_inset space ~ +\end_inset + +pattern +\emph default +, +\begin_inset space ~ +\end_inset + +...) +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +args@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{args()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut function!args@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{args()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + +(N +\begin_inset Formula $_{T}$ +\end_inset + +,...) +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\begin_inset Newline newline +\end_inset + +returns all code join points where the types of the arguments of a call/builtin/ +execution/set are matched by the corresponding +\shape italic +type pattern +\shape default +s. + +\begin_inset Note Comment +status open + +\begin_layout Plain Layout +The argument list of +\series bold +args +\series default + contains type patterns that are used to filter all join points, e.g. + calls to functions or function executions, with a matching signature. + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +Instead of the type pattern it is also possible here to pass the name of + a variable to which the context information is bound (a +\series bold +context variable +\series default +). + In this case the type of the variable is used for the type matching. + Context variables must be declared in the argument list of +\series bold +before() +\series default +, +\series bold +after() +\series default +, or +\series bold +around() +\series default + and can be used like a function parameter in the advice body. +\end_layout + +\begin_layout Standard +The +\series bold +that() +\series default + and +\series bold +target() +\series default + pointcut functions are special, because they might cause a runtime type + check. + The +\series bold +args() +\series default + and +\series bold +result() +\series default + functions are evaluated at compile time. + Exception: If a short-circuit argument is bound with the args pointcut + function, then the result of args depends on the runtime availability of + the bound argument. +\end_layout + +\begin_layout Subsubsection* +Example: context matching +\begin_inset CommandInset label +LatexCommand label +name "exa:context-matching" + +\end_inset + + +\end_layout + +\begin_layout Subsection +\begin_inset CommandInset label +LatexCommand label +name "subsec:Algebraic-Operators" + +\end_inset + +Algebraic Operators +\end_layout + +\begin_layout Description + +\series medium +\emph on +pointcut +\series default +\emph default + +\begin_inset space ~ +\end_inset + +&& +\series medium +\emph on + +\begin_inset space ~ +\end_inset + +pointcut +\series default +\emph default + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + +(N,N) +\begin_inset Formula $\rightarrow$ +\end_inset + +N, (C,C) +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\begin_inset Newline newline +\end_inset + +returns the intersection of the join points in the +\shape italic +pointcut +\shape default +s +\end_layout + +\begin_layout Description + +\series medium +\emph on +pointcut +\series default +\emph default + +\begin_inset space ~ +\end_inset + +|| +\series medium +\emph on + +\begin_inset space ~ +\end_inset + +pointcut +\series default +\emph default + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + +(N,N) +\begin_inset Formula $\rightarrow$ +\end_inset + +N, (C,C) +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\begin_inset Newline newline +\end_inset + +returns the union of the join points in the +\shape italic +pointcut +\shape default +s +\end_layout + +\begin_layout Description +! +\series medium +\emph on + +\begin_inset space ~ +\end_inset + +pointcut +\series default +\emph default + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + +N +\begin_inset Formula $\rightarrow$ +\end_inset + +N, C +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\begin_inset Newline newline +\end_inset + +returns all name resp. + code join points that are not included in +\shape italic +pointcut +\shape default + +\begin_inset Note Comment +status open + +\begin_layout Plain Layout + exclusion of the join points in the pointcut +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Subsubsection* +Example: +\begin_inset CommandInset label +LatexCommand label +name "exa:combining-pointcut" + +\end_inset + +combining pointcut expressions +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut function +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut!function +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Section +Attributes +\begin_inset CommandInset label +LatexCommand label +name "sec:attributes" + +\end_inset + + +\end_layout + +\begin_layout Standard +Attributes are a language element, which AspectC++ developers can use for + user-defined annotations. + An attribute provides additional information about a join point that aspects + can exploit for collecting or filtering pointcuts. + The attribute syntax is based on the attribute syntax of C++11 (and following + standards). + However, AspectC++ provides this mechanism even if the selected language + standard is older than C++11. + In this case no attributes from the namespaces +\family typewriter +gnu +\family default + or +\family typewriter +clang +\family default + or the global scope must be used. +\end_layout + +\begin_layout Subsection +Attribute declarations +\end_layout + +\begin_layout Standard +Attributes must be declared +\emph on +before +\emph default + being used in a pointcut expression. + An attribute that is used for annotating a join point must be declared, + but it is +\emph on +not +\emph default + required that the declaration is seen by the parser +\emph on +before +\emph default + the annotation location. + The following example shows such a declaration using the keyword +\family typewriter +attribute +\family default +. +\end_layout + +\begin_layout Subsubsection* +Example: attribute declaration +\begin_inset CommandInset label +LatexCommand label +name "exa:attribute-declaration" + +\end_inset + + +\end_layout + +\begin_layout LyX-Code +attribute myAttr(); +\end_layout + +\begin_layout Standard +To avoid naming conflicts, attributes can be declared inside of namespaces, + classes, or aspects. + User-defined attributes shall neither be declared in the global scope nor + in the scope of backend compiler attributes, such as +\family typewriter +gnu +\family default + or +\family typewriter +clang +\family default +. + The current version of AspectC++ supports only empty argument lists. + To annotate an element of the program code, the attribute has to be referenced + by its fully-qualified name. + The following example illustrates this: +\end_layout + +\begin_layout Subsubsection* +Example: using attributes to annotate program elements +\begin_inset CommandInset label +LatexCommand label +name "exa:attribute-qualified" + +\end_inset + + +\end_layout + +\begin_layout LyX-Code +namespace attrib { +\end_layout + +\begin_layout LyX-Code + attribute myFuncAttr(); +\end_layout + +\begin_layout LyX-Code + attribute otherAttr(); +\end_layout + +\begin_layout LyX-Code +} +\end_layout + +\begin_layout LyX-Code +[[attrib::myFuncAttr, attrib::otherAttr()]] void myFunc(); +\end_layout + +\begin_layout Standard +To be compatible with C++11 attributes, it is not necessary to specify parameter +s if the argument list of an attribute is empty. + Furthermore, it is possible to use several attributes in a pair of brackets + separated by commas or several pairs of brackets behind each other. + For more information about attribute-syntax in C++11 consult the C++11 + standard. +\end_layout + +\begin_layout Standard +Attributes from the namespaces +\family typewriter +gnu +\family default + and +\family typewriter +clang +\family default + and the global scope are evaluated by AspectC++ and passed through to the + backend compiler. + All other attributes are only evaluated by AspectC++ and hidden from the + backend compiler. +\end_layout + +\begin_layout Subsection +Supported code-elements +\end_layout + +\begin_layout Standard +Table +\begin_inset CommandInset ref +LatexCommand ref +reference "tab:attributes-code-elements" + +\end_inset + + shows the code elements, for which annotations with attributes are supported, + and the possible attribute locations. + Positions of attributes are marked by +\family typewriter +[[..]]. +\end_layout + +\begin_layout Standard +\begin_inset Float table +placement h +wide false +sideways false +status open + +\begin_layout Plain Layout +\begin_inset Tabular + + + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +Code-Element +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +Positions +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +namespaces +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +namespace [[...]] myNamespace {} +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +classes +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +class [[...]] myClass {}; +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +functions +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +[[...]] void myFunc [[...]] (); +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +variables +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +[[...]] int myVar [[...]]; +\end_layout + +\end_inset + + + + +\end_inset + + +\end_layout + +\begin_layout Plain Layout +\begin_inset Caption Standard + +\begin_layout Plain Layout +\begin_inset CommandInset label +LatexCommand label +name "tab:attributes-code-elements" + +\end_inset + +attributes - code-elements and positions +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +If a namespace is opened more than once, all enclosed elements belong semantical +ly to the same namespace. + In this case, all attributes of that namespace must be present at its +\emph on +first +\emph default + definition. + In subsequent definitions they can be present as well, but don't have to. + It is forbidden to add an attribute in a subsequent definition, which was + not present in the first. + A similar rule is applied for classes, functions, and variables, which + can have multiple forward declarations. + In this case, all attributes must be present at the +\emph on +first +\emph default + declaration and can be omitted later on. +\end_layout + +\begin_layout Subsection +Attributes and pointcut expressions +\end_layout + +\begin_layout Standard +Attributes can be used in pointcut expressions where they are interpreted + similar to named pointcuts. + They can be combined with logical operators like other pointcut expressions + and can be used in pointcut declarations. + Thereby, the usual C++ name lookup rules are also applicable for attributes. + The following example shows how to use attributes in pointcut expressions. +\end_layout + +\begin_layout Subsubsection* +Example: using attributes in pointcut expressions +\begin_inset CommandInset label +LatexCommand label +name "exa:attribute-pointcut-expression" + +\end_inset + + +\end_layout + +\begin_layout LyX-Code +struct [[output::myAttr]] myStruct { +\end_layout + +\begin_layout LyX-Code + [[output::myAttr]] void myFunc() {}; +\end_layout + +\begin_layout LyX-Code +}; +\end_layout + +\begin_layout LyX-Code +aspect output { +\end_layout + +\begin_layout LyX-Code + attribute myAttr(); +\end_layout + +\begin_layout LyX-Code + pointcut all() = myAttr(); +\end_layout + +\begin_layout LyX-Code +}; +\end_layout + +\begin_layout Standard +If multiple name joinpoints, such as the namespace N and the class C, are + annotated by an attribute A, the meaning of A() in a pointcut expression + is equivalent to +\begin_inset Quotes eld +\end_inset + +N +\begin_inset Quotes erd +\end_inset + +|| +\begin_inset Quotes erd +\end_inset + +C +\begin_inset Quotes erd +\end_inset + +. + This means that also nested entities within N and C are matched. +\end_layout + +\begin_layout Section +Slices +\end_layout + +\begin_layout Standard +This section defines the syntax and semantics of slice declarations. + The next section will describe how slices can be used by advice in order + to introduce code. + Currently, only class slices are defined in AspectC++. +\end_layout + +\begin_layout Subsection +Class Slice Declarations +\end_layout + +\begin_layout Standard +Class slices may be declared in any class or namespace scope. + They may be defined only once, but there may be an arbitrary number of + forward declarations. + A qualified name may be used if a class slice that is already declared + in a certain scope is redeclared or defined as shown in the following example: +\end_layout + +\begin_layout LyX-Code +slice class ASlice; +\end_layout + +\begin_layout LyX-Code +namespace N { +\end_layout + +\begin_layout LyX-Code + slice class ASlice; // a different slice! +\end_layout + +\begin_layout LyX-Code +} +\end_layout + +\begin_layout LyX-Code +slice class ASlice { // definition of the ::ASlice +\end_layout + +\begin_layout LyX-Code + int elem; +\end_layout + +\begin_layout LyX-Code +}; +\end_layout + +\begin_layout LyX-Code +slice class N::ASlice { // definition of the N::ASlice +\end_layout + +\begin_layout LyX-Code + long elem; +\end_layout + +\begin_layout LyX-Code +}; +\end_layout + +\begin_layout Standard +If a class slice only defines a base class, an abbreviated syntax may be + used: +\end_layout + +\begin_layout LyX-Code +slice class Chained : public Chain; +\end_layout + +\begin_layout Standard +Class slices may be anonymous. + However, this only makes sense as part of an advice declaration. + A class slice may also be declared with the +\family typewriter +aspect +\family default + or +\family typewriter +struct +\family default + keyword instead of +\family typewriter +class +\family default +. + While there is no difference between class and aspect slices, the default + access rights to the elements of a struct slice in the target classes are + public instead of private. + It is forbidden to declare aspects, pointcuts, advice, or slices as members + of a class slice. +\end_layout + +\begin_layout Standard +Class slices may have members that are not defined within the body of a + class slice declaration, e.g. + static member variable or non-inline functions: +\end_layout + +\begin_layout LyX-Code +slice class SL { +\end_layout + +\begin_layout LyX-Code + static int answer; +\end_layout + +\begin_layout LyX-Code + void f(); +\end_layout + +\begin_layout LyX-Code +}; +\end_layout + +\begin_layout LyX-Code +//... +\end_layout + +\begin_layout LyX-Code +slice int SL::answer = 42; +\end_layout + +\begin_layout LyX-Code +slice void SL::f() { ... + } +\end_layout + +\begin_layout Standard +These external member declarations have to appear after the corresponding + slice declaration in the source code. +\end_layout + +\begin_layout Section +Advice +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +advice!declaration +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +This section describes the different types of advice offered by AspectC++. + Advice are categorized in advice for join points in the dynamic control + flow of the running program, e. + g. + function call or executions, and advice for static join points like introductio +ns into classes. +\end_layout + +\begin_layout Standard +In either case the compiler makes sure that the code of the aspect header + file, which contains the advice definition (if this is the case), is compiled + prior to the affected join point location. +\end_layout + +\begin_layout Subsection +Advice for Dynamic Join Points +\end_layout + +\begin_layout Description +before +\series medium +(...) +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +before +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +advice!before +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +the advice code is executed before the join points in the pointcut +\end_layout + +\begin_layout Description +after +\series medium +(...) +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +after +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +advice!after +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +the advice code is executed after the join points in the pointcut +\end_layout + +\begin_layout Description +around +\series medium +(...) +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +around +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +advice!around +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +the advice code is executed in place of the join points in the pointcut +\end_layout + +\begin_layout Subsection +Advice for Static Join Points +\end_layout + +\begin_layout Standard +Static join points in AspectC++ are classes or aspects. + Advice for classes or aspects can introduce new members or add a base class. + Whether the new member or base class becomes +\series bold +private +\series default +, +\series bold +protected +\series default +, or +\series bold +public +\series default + in the target class depends on the protection in the advice declaration + in the aspect. +\end_layout + +\begin_layout Description +baseclass +\series medium +( +\emph on +classname +\emph default +) +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +baseclass +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +advice!baseclass +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +a new base class is introduced to the classes in the pointcut +\end_layout + +\begin_layout Description + +\emph on +introduction +\begin_inset space ~ +\end_inset + +declaration +\emph default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +introduction declaration +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +advice!introduction declaration +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +a new member variable, member function, or type is introduced +\end_layout + +\begin_layout Standard +Introduction declarations are only semantically analyzed in the context + of the target. + Therefore, the declaration may refer, for instance, to types or constants, + which are not known in the aspect definition, but only in the target class + or classes. + To introduce a constructor or destructor the name of the aspect, to which + the introduction belongs, has to be taken as the constructor/destructor + name. +\end_layout + +\begin_layout Standard + +\emph on +Non-inline introductions +\emph default + can be used for introductions of static member variables or member function + introduction with separate declaration an definition. + The name of the introduced member has to be a qualified name in which the + nested name specifier is the name of the aspect to which the introduction + belongs. +\end_layout + +\begin_layout Subsubsection* +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +advice!declaration +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Section + +\family typewriter +JoinPoint +\family default + API +\family typewriter + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}|( +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +runtime support!JoinPoint@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}|( +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +The following sections provide a complete description of the +\family typewriter +JoinPoint +\family default + API. + +\end_layout + +\begin_layout Subsection +API for Dynamic Join Points +\end_layout + +\begin_layout Standard +The JoinPoint-API for dynamic join points can be used within the body of + advice code. + +\end_layout + +\begin_layout Subsubsection +Types and Constants +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +Result +\family default +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +Result@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{Result} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!Result@ +\backslash +texttt{Result} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +result type of a function +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +Res::Type, Res::ReferredType +\family default +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +Res::Type@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{Res::Type} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!Res::Type@ +\backslash +texttt{Res::Type} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +Res::ReferredType@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{Res::ReferredType} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!Res::ReferredType@ +\backslash +texttt{Res::ReferredType} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +result type of the affected function or entity access +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +Arg::Type, Arg::ReferredType +\family default +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +Arg::Type@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{Arg::Type} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!arg::Type@ +\backslash +texttt{Arg::Type} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +Arg::ReferredType@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{Arg::ReferredType} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!Arg::ReferredType@ +\backslash +texttt{Arg::ReferredType} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +type of the +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +$i^{ +\backslash +,th}$ +\end_layout + +\end_inset + + argument of the affected join point (with +\begin_inset ERT +status open + +\begin_layout Plain Layout + +$0 +\backslash +leq i < ARGS$ +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +ARGS +\family default +\series default + +\begin_inset space ~ +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +ARGS@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{ARGS} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!ARGS@ +\backslash +texttt{ARGS} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +number of arguments +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +That +\family default +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +That@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{That} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!That@ +\backslash +texttt{That} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +object type (object initiating a call) +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +Target +\family default +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +Target@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{Target} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!Target@ +\backslash +texttt{Target} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +target object type (target object of a call) +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +Entity +\family default +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +Entity@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{Entity} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!Entity@ +\backslash +texttt{Entity} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +type of the primary referenced entity (function or variable) +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +MemberPtr +\family default +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +MemberPtr@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{MemberPtr} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!MemberPtr@ +\backslash +texttt{MemberPtr} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +type of the member pointer for entity or +\family typewriter +void * +\family default + for nonmembers +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +Array +\family default +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +MemberPtr@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{Array} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!Array@ +\backslash +texttt{Array} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +type of the accessed array +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +Dim::Idx +\family default +\series default + +\begin_inset Index idx +status open + +\begin_layout Plain Layout +Idx@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{Idx} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status open + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!Idx@ +\backslash +texttt{Idx} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +type of the +\emph on +i +\emph default +th dimension of the accessed array (with +\begin_inset ERT +status open + +\begin_layout Plain Layout + +$0 +\backslash +leq i < DIMS$ +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +Dim::Size +\family default +\series default + +\begin_inset Index idx +status open + +\begin_layout Plain Layout +Size@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{Size} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status open + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!Size@ +\backslash +texttt{Size} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +size of the +\emph on +i +\emph default +th dimension of the accessed array (with +\begin_inset ERT +status open + +\begin_layout Plain Layout + +$0 +\backslash +leq i < DIMS$ +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +DIMS +\family default +\series default + +\begin_inset space ~ +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +DIMS@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{DIMS} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!DIMS@ +\backslash +texttt{DIMS} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +number of dimensions of an accessed array or 0 otherwise +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +begin{comment} +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +Aspect +\family default +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +Aspect@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{Aspect} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!Aspect@ +\backslash +texttt{Aspect} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +type of the aspect (only available in introductions) +\begin_inset ERT +status open + +\begin_layout Plain Layout + +\end_layout + +\begin_layout Plain Layout + +\end_layout + +\begin_layout Plain Layout + + +\backslash +end{comment} +\end_layout + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Subsubsection* +Example: type usage +\begin_inset CommandInset label +LatexCommand label +name "exa:type-usage" + +\end_inset + + +\end_layout + +\begin_layout Subsubsection +Functions +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +static +\begin_inset space ~ +\end_inset + +AC::Type +\emph on + +\begin_inset space ~ +\end_inset + + +\emph default +type() +\family default +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +type@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{type()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!type@ +\backslash +texttt{type()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +returns the encoded type for the join point conforming with the C++ ABI + V3 specification +\begin_inset Foot +status collapsed + +\begin_layout Plain Layout +\begin_inset CommandInset href +LatexCommand href +name "http://www.codesourcery.com/cxx-abi/abi.html\\#mangling" +target "http://www.codesourcery.com/cxx-abi/abi.html\\#mangling" + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +static +\begin_inset space ~ +\end_inset + +int +\emph on + +\begin_inset space ~ +\end_inset + + +\emph default +args() +\family default +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +args@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{args()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!args@ +\backslash +texttt{args()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +returns the number of arguments of a function for call and execution join + points +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +static +\begin_inset space ~ +\end_inset + +AC::Type +\emph on + +\begin_inset space ~ +\end_inset + + +\emph default +argtype(int +\series default + +\begin_inset space ~ +\end_inset + + +\series medium +number) +\family default +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +argtype@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{argtype()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!argtype@ +\backslash +texttt{argtype()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +returns the encoded type of an argument conforming with the C++ ABI V3 specifica +tion +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +static +\begin_inset space ~ +\end_inset + +const +\begin_inset space ~ +\end_inset + +char +\series default +\emph on + +\begin_inset space ~ +\end_inset + + +\series medium +\emph default +*signature() +\family default +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +signature@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{signature()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!signature@ +\backslash +texttt{signature()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +gives a textual description of the join point (function name, class name, + ...) +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +static +\begin_inset space ~ +\end_inset + +unsigned +\begin_inset space ~ +\end_inset + +int +\series default +\emph on + +\begin_inset space ~ +\end_inset + + +\series medium +\emph default +id() +\family default +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +id@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{id()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!id@ +\backslash +texttt{id()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +returns a unique numeric identifier for this join point +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +static +\begin_inset space ~ +\end_inset + +const +\begin_inset space ~ +\end_inset + +char +\series default +\emph on + +\begin_inset space ~ +\end_inset + + +\series medium +\emph default +*filename() +\family default +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +filename@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{filename()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!filename@ +\backslash +texttt{filename()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +returns the name of the file in which the join point (shadow) is located +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +static +\begin_inset space ~ +\end_inset + +int +\series default +\emph on + +\begin_inset space ~ +\end_inset + + +\series medium +\emph default +line() +\family default +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +line@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{line()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!line@ +\backslash +texttt{line()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +the number of the line in which the join point (shadow) is located +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +static +\begin_inset space ~ +\end_inset + +AC::Type +\emph on + +\begin_inset space ~ +\end_inset + + +\emph default +resulttype() +\family default +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +resulttype@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{resulttype()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!resulttype@ +\backslash +texttt{resulttype()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +returns the encoded type of the result type conforming with the C++ ABI + V3 specification +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +static +\begin_inset space ~ +\end_inset + +AC::JPType +\emph on + +\begin_inset space ~ +\end_inset + + +\emph default +jptype() +\family default +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +jptype@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{jptype()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!jptype@ +\backslash +texttt{jptype()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +returns a unique identifier describing the type of the join point +\end_layout + +\begin_layout Subsubsection* +Example: static function usage +\begin_inset CommandInset label +LatexCommand label +name "exa:static-function-usage" + +\end_inset + + +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +void +\begin_inset space ~ +\end_inset + +*arg(int +\series default + +\begin_inset space ~ +\end_inset + + +\series medium +number) +\family default +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +arg@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{arg()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!arg@ +\backslash +texttt{arg()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +returns a pointer to the memory position holding the argument value with + index +\family typewriter +number +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +Result +\emph on + +\begin_inset space ~ +\end_inset + + +\emph default +*result() +\family default +\series default + +\family typewriter + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +result@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{result()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!result@ +\backslash +texttt{result()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +returns a pointer to the memory location designated for the result value + or 0 if the function has no result value +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +That +\begin_inset space ~ +\end_inset + +*that() +\family default +\series default + +\family typewriter + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +that@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{that()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!that@ +\backslash +texttt{that()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +returns a pointer to the object initiating a call or 0 if it is a static + method or a global function +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +Target +\begin_inset space ~ +\end_inset + +*target() +\family default +\series default + +\family typewriter + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +target@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{target()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!target@ +\backslash +texttt{target()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +returns a pointer to the object that is the target of a call or 0 if it + is a static method or a global function +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +Entity +\begin_inset space ~ +\end_inset + +*entity() +\family default +\series default + +\family typewriter + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +entity@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{entity()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!entity@ +\backslash +texttt{entity()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +returns a pointer to the accessed entity (function or variable) or 0 for + member functions or builtin operators +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +MemberPtr +\begin_inset space ~ +\end_inset + +*memberptr() +\family default +\series default + +\family typewriter + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +memberptr@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{memberptr()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!memberptr@ +\backslash +texttt{memberptr()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +returns a member pointer to entity or 0 for nonmembers +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +Array +\begin_inset space ~ +\end_inset + +*array() +\family default +\series default + +\family typewriter + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +array@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{array()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!array@ +\backslash +texttt{array()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +returns a typed pointer to the accessed array +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +Dim::Idx +\begin_inset space ~ +\end_inset + +idx() +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +idc@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{idx()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\family default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!idx@ +\backslash +texttt{idx()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +returns the value of the +\emph on +i +\emph default +th index used for the array access +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +void +\begin_inset space ~ +\end_inset + +proceed() +\family default +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +proceed@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{proceed()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!proceed()@ +\backslash +texttt{proceed()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +executes the original join point code in an around advice by calling +\family typewriter +action().trigger() +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +AC::Action +\begin_inset space ~ +\end_inset + +&action() +\family default +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +action@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{action()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!action@ +\backslash +texttt{action()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +returns the runtime action object containing the execution environment to + execute the original functionality encapsulated by an around advice +\end_layout + +\begin_layout Subsubsection* +Example: +\begin_inset CommandInset label +LatexCommand label +name "exa:non-static-function-usage" + +\end_inset + +non-static function usage +\family typewriter + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}|) +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +runtime support!JoinPoint@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}|) +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Subsection +API for Static Join Points +\end_layout + +\begin_layout Standard +The JoinPoint-API for static join points can be used within the definition + of a slice and describes the state of target class +\emph on +before +\emph default + the introduction took place. + It is accessed through the built-in type +\family typewriter +JoinPoint +\family default + (e.g. + +\family typewriter +JoinPoint::signature() +\family default +) and provides the following functions, types, and constants: +\begin_inset Note Note +status open + +\begin_layout Plain Layout +index entries missing here +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +static +\begin_inset space ~ +\end_inset + +const +\begin_inset space ~ +\end_inset + +char +\begin_inset space ~ +\end_inset + +*signature() +\family default +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +signature@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{signature()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!signature@ +\backslash +texttt{signature()} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +returns the target class name as a string +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +That +\family default +\series default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +The (incomplete) target type of the introduction +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +HASHCODE +\family default +\series default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +integer hash value of the target type +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +BASECLASSES +\family default +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +BASECLASSES@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{BASECLASSES} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +JoinPoint@ +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +texttt{JoinPoint}!BASECLASSES@ +\backslash +texttt{BASECLASSES} +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +number of base classes of the target class +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +BaseClass::Type +\family default +\series default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +type of the +\begin_inset ERT +status open + +\begin_layout Plain Layout + +$I^{ +\backslash +,th}$ +\end_layout + +\end_inset + + base class +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +BaseClass::prot, +\begin_inset space ~ +\end_inset + +BaseClass::spec +\family default +\series default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +Protection level (AC::PROT_NONE /PRIVATE /PROTECTED /PUBLIC) and additional + specifiers (AC::SPEC_NONE /VIRTUAL) of the +\begin_inset ERT +status open + +\begin_layout Plain Layout + +$I^{ +\backslash +,th}$ +\end_layout + +\end_inset + + base class +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +MEMBERS +\family default +\series default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +number of data members of the target class +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +Member::Type, +\series default + +\begin_inset space ~ +\end_inset + + +\series medium +Member::ReferredType +\family default +\series default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +type of the +\begin_inset ERT +status open + +\begin_layout Plain Layout + +$I^{ +\backslash +,th}$ +\end_layout + +\end_inset + + member variable of the target class +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +Member::prot, +\begin_inset space ~ +\end_inset + +Member::spec +\family default +\series default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +Protection level (see BaseClass::prot) and additional member variable + specifiers (AC::SPEC_NONE /STATIC /MUTABLE) +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +static +\begin_inset space ~ +\end_inset + +ReferredType +\begin_inset space ~ +\end_inset + +*Member:: +\emph on +pointer( +\emph default +T +\begin_inset space ~ +\end_inset + +*obj=0 +\emph on +) +\family default +\series default +\emph default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +returns a typed pointer to the +\begin_inset ERT +status open + +\begin_layout Plain Layout + +$I^{ +\backslash +,th}$ +\end_layout + +\end_inset + + member variable (obj is needed for non-static member variables) +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +static +\begin_inset space ~ +\end_inset + +const +\begin_inset space ~ +\end_inset + +char +\begin_inset space ~ +\end_inset + +*Member:: +\emph on +name +\emph default +() +\family default +\series default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +returns the name of the +\begin_inset ERT +status open + +\begin_layout Plain Layout + +$I^{ +\backslash +,th}$ +\end_layout + +\end_inset + + member variable +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +FUNCTIONS +\family default +\series default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +number of member functions of the target class +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +Function::prot, +\begin_inset space ~ +\end_inset + +Function::spec +\family default +\series default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +Protection level (see BaseClass::prot) and additional member variable + specifiers (AC::SPEC_NONE /STATIC /VIRTUAL) +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +CONSTRUCTORS +\family default +\series default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +number of user-defined constructors of the target class +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +Constructor::prot, +\begin_inset space ~ +\end_inset + +Constructor::spec +\family default +\series default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +Protection level (see BaseClass::prot) and additional member variable + specifiers (AC::SPEC_NONE) +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +DESTRUCTORS +\family default +\series default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +number (zero or one) of user-defined destructors of the target class +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +Destructor::prot, +\begin_inset space ~ +\end_inset + +Destructor::spec +\family default +\series default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +Protection level (see BaseClass::prot) and additional member variable + specifiers (AC::SPEC_NONE /VIRTUAL) +\end_layout + +\begin_layout Section +\begin_inset CommandInset label +LatexCommand label +name "sec:ordering" + +\end_inset + +Advice Ordering +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +advice!ordering +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Subsection +\begin_inset CommandInset label +LatexCommand label +name "subsec:aspect-precedence" + +\end_inset + +Aspect Precedence +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +precedence!of aspects +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +AspectC++ provides a very flexible mechanism to define aspect precedence. + The precedence is used to determine the execution order of advice code + if more than one aspect affects the same join point. + The precedence in AspectC++ is a member of a join point. + This means that the precedence relationship between two aspects might vary + in different parts of the system. + The compiler checks the following conditions to determine the precedence + of aspects: +\end_layout + +\begin_layout Description +order +\begin_inset space ~ +\end_inset + +declaration: if the programmer provides an order declaration, which defines + the precedence relationship between two aspects for a join point, the compiler + will obey this definition or abort with a compile-time error if there is + a cycle in the precedence graph. + Order declarations have the following syntax: +\family typewriter +\series bold + +\begin_inset Newline newline +\end_inset + +advice +\family default +\series default + +\emph on +pointcut-expr +\emph default + : +\family typewriter +\series bold +order +\family default +\series default + +\family typewriter +\series bold +( +\family default +\series default + +\emph on +high +\family typewriter +\series bold +\emph default +, +\family default +\series default + ... +\emph on +low +\emph default + +\family typewriter +\series bold +) +\begin_inset Newline newline +\end_inset + + +\family default +\series default +The argument list of +\family typewriter +order +\family default + has to contain at least two elements. + Each element is a pointcut expression, which describes a set of aspects. + Each aspect in a certain set has a higher precedence than all aspects, + which are part of a set following later in the list (on the right hand + side). + For example ' +\family typewriter +("A1"||"A2","A3"||"A4") +\family default +' means that +\family typewriter +A1 +\family default + has precedence over +\family typewriter +A3 +\family default + and +\family typewriter +A4 +\family default + and that +\family typewriter +A2 +\family default + has precedence over +\family typewriter +A3 +\family default + and +\family typewriter +A4 +\family default +. + This order directive does +\emph on +not +\emph default + define the relation between +\family typewriter +A1 +\family default + and +\family typewriter +A2 +\family default + or +\family typewriter +A3 +\family default + and +\family typewriter +A4 +\family default +. + Of course, the pointcut expressions in the argument list of +\family typewriter +order +\family default + may contain named pointcuts and even pure virtual pointcuts. +\end_layout + +\begin_layout Description +inheritance +\begin_inset space ~ +\end_inset + +relation: if there is no order declaration given and one aspect has a base + aspect the derived aspect has a higher precedence than the base aspect. +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +precedence!of aspects +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Subsection +\begin_inset CommandInset label +LatexCommand label +name "subsec:advice-precedence" + +\end_inset + +Advice Precedence +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +precedence!of advice +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +The precedence of advice is determined with a very simple scheme: +\end_layout + +\begin_layout Itemize +if two advice declarations belong to different aspects and there is a precedence + relation between these aspects (see section +\begin_inset CommandInset ref +LatexCommand vref +reference "subsec:aspect-precedence" + +\end_inset + +) the same relation will be assumed for the advice. +\end_layout + +\begin_layout Itemize +if two advice declarations belong to the same aspect the one that is declared + first has the higher precedence. +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +precedence!of advice +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Subsection +Effects of Advice Precedence +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +precedence!effects +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +( +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +Only advice precedence has an effect on the generated code. + The effect depends on the kind of join point, which is affected by two + advice declarations. +\end_layout + +\begin_layout Subsubsection* +Class Join Points +\end_layout + +\begin_layout Standard +Advice on class join points can extend the member variable list or base + class list. + If advice has a higher precedence than another it will be handled first. + For example, an introduced new base class of advice with a high precedence + will appear in the base class list on the left side of a base class, which + was inserted by advice with lower precedence. + This means that the execution order of the constructors of introduced base + classes can be influenced, for instance, by order declarations. +\end_layout + +\begin_layout Standard +The order of introduced member variables also has an impact on the constructor/d +estructor execution order as well as the object layout. +\end_layout + +\begin_layout Subsubsection* +Code Join Points +\end_layout + +\begin_layout Standard +Advice on code join points can be +\family typewriter +before +\family default +, +\family typewriter +after +\family default +, or +\family typewriter +around +\family default + advice. + For +\family typewriter +before +\family default + and +\family typewriter +around +\family default + advice a higher precedence means that the corresponding advice code will + be run first. + For +\family typewriter +after +\family default + advice a higher precedence means that the advice code will be run later. +\end_layout + +\begin_layout Standard +If +\family typewriter +around +\family default + advice code does not call +\family typewriter +tjp->proceed() +\family default + or +\family typewriter +trigger() +\family default + on the action object no advice code with lower precedence will be run. + The execution of advice with higher precedence is not affected by +\family typewriter +around +\family default + advice with lower precedence. +\end_layout + +\begin_layout Standard +For example, consider an aspect that defines advice +\begin_inset Foot +status collapsed + +\begin_layout Plain Layout +BE is +\family typewriter +before +\family default + advice, AF +\family typewriter +after +\family default + advice, and AR +\family typewriter +around +\family default + advice +\end_layout + +\end_inset + + in the following order: BE1, AF1, AF2, AR1, BE2, AR2, AF3. + As described in section +\begin_inset CommandInset ref +LatexCommand vref +reference "subsec:advice-precedence" + +\end_inset + + the declaration order also defines the precedence: BE1 has the highest + and AF3 the lowest. + The result is the following advice code execution sequence: +\end_layout + +\begin_layout Enumerate +BE1 (highest precedence) +\end_layout + +\begin_layout Enumerate +AR1 (the indented advice will only be executed if +\family typewriter +proceed() +\family default + is called!) +\begin_inset Separator latexpar +\end_inset + + +\end_layout + +\begin_deeper +\begin_layout Enumerate +BE2 (before AR2, buts depends on AR1) +\end_layout + +\begin_layout Enumerate +AR2 (the indented code will only be executed if +\family typewriter +proceed() +\family default + is called!) +\begin_inset Separator latexpar +\end_inset + + +\end_layout + +\begin_deeper +\begin_layout Enumerate +original code under the join point +\end_layout + +\begin_layout Enumerate +AF3 +\end_layout + +\end_deeper +\end_deeper +\begin_layout Enumerate +AF2 (does not depend on AR1 and AR2, because of higher precedence) +\end_layout + +\begin_layout Enumerate +AF1 (run after AF2, because it has a higher precedence) +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +precedence!effects +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +advice!ordering +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +| +\end_layout + +\end_inset + +) +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Section +List of Examples +\end_layout + +\begin_layout Standard +\noindent +match expressions (name pointcuts), +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:match-expressions" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +pointcut expressions, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:pointcut-expressions" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +pointcut declaration, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:pointcut-declaration" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +pure virtual pointcut declaration, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:pure-virtual" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +class slice declaration, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:class-slice-declaration" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +advice declaration, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:advice-declaration" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +advice declaration with access to context information, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:advice-declaration-with" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +introductions, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:introductions" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +base class introduction, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:base-class-intro" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +advice ordering, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:order" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +aspect declaration, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:aspect-decl" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +abstract aspect, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:abstract-aspect" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +reused abstract aspect, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:reused-abstract" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +aspect instantiation using +\family typewriter +aspectof +\family default +, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:aspect-aspectof" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +re-usable trace aspect, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:re-usable-trace" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +begin{comment} +\end_layout + +\end_inset + +static type identification using introductions, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:static-type-id" + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +\end_layout + +\begin_layout Plain Layout + +\end_layout + +\begin_layout Plain Layout + + +\backslash +end{comment} +\end_layout + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +begin{comment} +\end_layout + +\end_inset + +extended thread counting, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:extended-thread" + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +\end_layout + +\begin_layout Plain Layout + +\end_layout + +\begin_layout Plain Layout + + +\backslash +end{comment} +\end_layout + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +type, scope, and name parts of a function match expression, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:match-expr-parts-functions" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +simple name patterns, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:match-name-patterns" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +operator name patterns, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:match-operator-name-patterns" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +conversion function name patterns, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:match-conversion-function-name-patterns" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +scope patterns, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:match-scope-patterns" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +type patterns with the wildcard character, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:match-type-patterns-wildcard" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +type patterns with +\family typewriter +const +\family default + and +\family typewriter +volatile +\family default +, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:match-type-patterns-cv" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +type patterns with +\family typewriter +virtual +\family default +, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:match-type-patterns-virtual" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +type matching, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:type-matching" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +control flow dependant advice activation, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:control-flow" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +matching in scopes, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:matching-in-scopes" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +function matching, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:function-matching" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +instance counting +\begin_inset CommandInset label +LatexCommand label +name "exa:instance-counting-1" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +begin{comment} +\end_layout + +\end_inset + +member variable matching, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:variable-matching" + +\end_inset + + +\begin_inset ERT +status open + +\begin_layout Plain Layout + +\end_layout + +\begin_layout Plain Layout + +\end_layout + +\begin_layout Plain Layout + + +\backslash +end{comment} +\end_layout + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +context matching, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:context-matching" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +combining pointcut expressions, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:combining-pointcut" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +attribute declaration, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:attribute-declaration" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +using attributes to annotate program elements, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:attribute-qualified" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +using attributes in pointcut expressions, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:attribute-pointcut-expression" + +\end_inset + + +\begin_inset Note Note +status collapsed + +\begin_layout Plain Layout +\noindent +advice placement, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:advice-placement" + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +type usage, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:type-usage" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +static function usage, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:static-function-usage" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +non-static function usage, +\begin_inset CommandInset ref +LatexCommand pageref +reference "exa:non-static-function-usage" + +\end_inset + + +\end_layout + +\begin_layout Section +\start_of_appendix +Grammar +\begin_inset Index idx +status open + +\begin_layout Plain Layout +grammar +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +The AspectC++ syntax is an extension to the C++ syntax. + It adds five new keywords to the C++ language: +\family typewriter +aspect +\family default +, +\family typewriter +advice +\family default +, +\family typewriter +slice +\family default +, +\family typewriter +pointcut +\family default +, and +\family typewriter +attribute +\family default +. + Additionally it extends the C++ language by advice and pointcut declarations. + In contrast to pointcut declarations, advice declarations may only occur + in aspect declarations. + +\end_layout + +\begin_layout Description + +\series medium +\shape italic +class-key: +\series default +\shape default + +\series bold + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\family typewriter +\series default +aspect +\end_layout + +\begin_layout Description + +\series medium +\shape italic +declaration: +\series default +\shape default + +\shape italic + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +pointcut-declaration +\begin_inset Newline newline +\end_inset + +slice-declaration +\begin_inset Newline newline +\end_inset + +advice-declaration +\begin_inset Newline newline +\end_inset + +attribute-declaration +\end_layout + +\begin_layout Description + +\series medium +\shape italic +member-declaration: +\series default +\shape default + +\shape italic + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +pointcut-declaration +\begin_inset Newline newline +\end_inset + +slice-declaration +\begin_inset Newline newline +\end_inset + +advice-declaration +\begin_inset Newline newline +\end_inset + +attribute-declaration +\end_layout + +\begin_layout Description + +\series medium +\shape italic +pointcut-declaration: +\series default +\shape default + +\shape italic +\emph on + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut!declaration +\end_layout + +\end_inset + + +\emph default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\family typewriter +\shape default +pointcut +\family default + +\shape italic + +\begin_inset space ~ +\end_inset + +declaration +\end_layout + +\begin_layout Description + +\series medium +\shape italic +pointcut-expression: +\series default +\shape default + +\series medium +\shape italic + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +pointcut!expression +\end_layout + +\end_inset + + +\series default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +constant-expression +\end_layout + +\begin_layout Description + +\series medium +\shape italic +advice-declaration: +\series default +\shape default + +\shape italic + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +advice!declaration +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\family typewriter +\shape default +advice +\family default + +\shape italic + +\begin_inset space ~ +\end_inset + +pointcut-expression +\begin_inset space ~ +\end_inset + + +\shape default + +\series bold +: +\series default + +\shape italic + +\begin_inset space ~ +\end_inset + +order-declaration +\begin_inset Newline newline +\end_inset + + +\family typewriter +\shape default +advice +\family default + +\shape italic + +\begin_inset space ~ +\end_inset + +pointcut-expression +\begin_inset space ~ +\end_inset + + +\shape default + +\series bold +: +\series default + +\shape italic + +\begin_inset space ~ +\end_inset + +slice-reference +\begin_inset Newline newline +\end_inset + + +\family typewriter +\shape default +advice +\family default + +\shape italic + +\begin_inset space ~ +\end_inset + +pointcut-expression +\begin_inset space ~ +\end_inset + + +\shape default + +\series bold +: +\series default + +\shape italic + +\begin_inset space ~ +\end_inset + +declaration +\end_layout + +\begin_layout Description + +\series medium +\shape italic +order-declaration: +\series default +\shape default + +\shape italic + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +order!declaration +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\family typewriter +\shape default +order ( +\family default + +\shape italic + +\begin_inset space ~ +\end_inset + +pointcur-expression-seq +\begin_inset space ~ +\end_inset + + +\family typewriter +\shape default +) +\end_layout + +\begin_layout Description + +\series medium +\shape italic +slice-reference: +\series default +\shape default + +\shape italic + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +slice!reference +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\family typewriter +\shape default +slice +\begin_inset space ~ +\end_inset + +:: +\family default +\shape italic + +\begin_inset Formula $_{\textrm{opt}}$ +\end_inset + + +\begin_inset space ~ +\end_inset + +nested-name-specifier +\begin_inset Formula $_{\textrm{opt}}$ +\end_inset + + unqualified-id +\begin_inset space ~ +\end_inset + + +\family typewriter +\series bold +\emph on +; +\end_layout + +\begin_layout Description + +\series medium +\shape italic +slice-declaration: +\series default + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +slice!declaration +\end_layout + +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\family typewriter +\emph on +slice +\family default +\shape default +\emph default + +\series medium +\shape italic +declaration +\end_layout + +\begin_layout Description + +\series medium +\shape italic +attribute-declaration: +\series default +\shape default + +\shape italic +\emph on + +\begin_inset Index idx +status collapsed + +\begin_layout Plain Layout +attribute!declaration +\end_layout + +\end_inset + + +\emph default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\family typewriter +\shape default +attribute +\family default + +\shape italic + +\begin_inset space ~ +\end_inset + +unqualified-id +\emph on + +\begin_inset space ~ +\end_inset + + +\family typewriter +( +\begin_inset space ~ +\end_inset + +) +\begin_inset space ~ +\end_inset + +; +\end_layout + +\begin_layout Section +\begin_inset CommandInset label +LatexCommand label +name "sec:Match-Expression-Grammar" + +\end_inset + +Match Expression Grammar +\begin_inset Index idx +status open + +\begin_layout Plain Layout +match expression!grammar +\end_layout + +\end_inset + + +\begin_inset Index idx +status open + +\begin_layout Plain Layout +match expression grammar +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +Match expression in AspectC++ are used to define a type pattern and an optional + object name pattern to select a subset of the known program entities like + functions, member variables, or argument/result types. + The grammar is very similar to the grammar of C++ declarations. + Any rules, which are referenced here but not defined, should be looked + up in the ISO C++ standard. +\end_layout + +\begin_layout Description + +\series medium +\shape italic +match-expression: +\series default +\shape default + +\series bold + +\begin_inset space ~ +\end_inset + + +\series default + +\family typewriter + +\begin_inset Newline newline +\end_inset + + +\family default +\shape italic +match-declaration +\end_layout + +\begin_layout Description + +\series medium +\emph on +match-id: +\series default +\emph default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\family typewriter +% +\family default + +\begin_inset Newline newline +\end_inset + + +\emph on +nondigit +\emph default + +\begin_inset Newline newline +\end_inset + + +\emph on +match-id +\emph default + +\family typewriter +% +\family default + +\begin_inset Newline newline +\end_inset + + +\emph on +match-id nondigit +\emph default + +\begin_inset Newline newline +\end_inset + + +\emph on +match-id digit +\end_layout + +\begin_layout Description + +\series medium +\emph on +match-declaration: +\series default +\emph default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\emph on +match-decl-specifier-seq +\begin_inset Formula $_{\textrm{opt}}$ +\end_inset + + match-declarator +\end_layout + +\begin_layout Description + +\series medium +\emph on +match-decl-specifier-seq: +\series default +\emph default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\emph on +match-decl-specifier-seq +\begin_inset Formula $_{\textrm{opt}}$ +\end_inset + + match-decl-specifier +\end_layout + +\begin_layout Description + +\series medium +\emph on +match-decl-specifier: +\series default +\emph default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\emph on +nested-match-name-specifier +\begin_inset Formula $_{\textrm{opt}}$ +\end_inset + + match-id +\begin_inset Newline newline +\end_inset + +cv-qualifier +\begin_inset Newline newline +\end_inset + +match-function-specifier +\begin_inset Newline newline +\end_inset + + +\family typewriter +\emph default +char +\begin_inset Newline newline +\end_inset + +wchar_t +\begin_inset Newline newline +\end_inset + +bool +\begin_inset Newline newline +\end_inset + +short +\begin_inset Newline newline +\end_inset + +int +\begin_inset Newline newline +\end_inset + +long +\begin_inset Newline newline +\end_inset + +signed +\begin_inset Newline newline +\end_inset + +unsigned +\begin_inset Newline newline +\end_inset + +float +\begin_inset Newline newline +\end_inset + +double +\begin_inset Newline newline +\end_inset + +void +\end_layout + +\begin_layout Description + +\series medium +\emph on +match-function-specifier: +\series default +\emph default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\family typewriter +virtual +\begin_inset Newline newline +\end_inset + +static +\end_layout + +\begin_layout Description + +\series medium +\emph on +nested-match-name-specifier: +\series default +\emph default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\emph on +match-id +\family typewriter +\emph default + +\begin_inset space ~ +\end_inset + +:: +\begin_inset space ~ +\end_inset + + +\family default +\emph on +nested-match-name-specifier +\begin_inset Formula $_{\textrm{opt}}$ +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\family typewriter +\emph default +... +\begin_inset space ~ +\end_inset + +:: +\begin_inset space ~ +\end_inset + + +\family default +\emph on +nested-match-name-specifier +\begin_inset Formula $_{\textrm{opt}}$ +\end_inset + + +\end_layout + +\begin_layout Description + +\series medium +\emph on +match-declarator +\series default +\emph default +: +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\emph on +direct-match-declarator +\begin_inset Newline newline +\end_inset + +match-ptr-declarator match-declarator +\end_layout + +\begin_layout Description + +\series medium +\emph on +abstract-match-declarator +\series default +\emph default +: +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\emph on +direct-abstract-match-declarator +\begin_inset Newline newline +\end_inset + +match-ptr-declarator abstract-match-declarator +\end_layout + +\begin_layout Description + +\series medium +\emph on +direct-match-declarator: +\series default +\emph default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\emph on +match-declarator-id +\begin_inset Newline newline +\end_inset + +direct-match-declarator +\emph default + +\family typewriter +( +\family default + +\emph on +match-parameter-declaration-clause +\emph default + +\family typewriter +) +\family default + +\emph on +cv-qualifier-seq +\begin_inset Formula $_{\textrm{opt}}$ +\end_inset + + +\begin_inset Newline newline +\end_inset + +direct-match-declarator +\emph default + +\family typewriter +[ +\family default + +\emph on +match-array-size +\emph default + +\family typewriter +] +\end_layout + +\begin_layout Description + +\series medium +\emph on +direct-abstract-match-declarator: +\series default +\emph default + +\begin_inset space ~ +\end_inset + + +\emph on + +\begin_inset Newline newline +\end_inset + +direct-abstract-match-declarator +\emph default + +\family typewriter +( +\family default + +\emph on +match-parameter-declaration-clause +\emph default + +\family typewriter +) +\family default + +\emph on +cv-qualifier-seq +\begin_inset Formula $_{\textrm{opt}}$ +\end_inset + + +\begin_inset Newline newline +\end_inset + +direct-abstract-match-declarator +\emph default + +\family typewriter +[ +\family default + +\emph on +match-array-size +\emph default + +\family typewriter +] +\end_layout + +\begin_layout Description + +\series medium +\emph on +match-array-size: +\series default +\emph default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\family typewriter +% +\family default + +\begin_inset Newline newline +\end_inset + + +\emph on +decimal-literal +\end_layout + +\begin_layout Description + +\series medium +\emph on +match-ptr-operator: +\series default +\emph default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\family typewriter +* +\family default + +\emph on +cv-qualifier-seq +\begin_inset Formula $_{\textrm{opt}}$ +\end_inset + + +\emph default + +\begin_inset Newline newline +\end_inset + + +\family typewriter +& +\family default + +\begin_inset Newline newline +\end_inset + + +\emph on +nested-match-name-specifier +\emph default + +\family typewriter +* +\family default + +\emph on +cv-qualifier-seq +\begin_inset Formula $_{\textrm{opt}}$ +\end_inset + + +\end_layout + +\begin_layout Description + +\series medium +\emph on +match-parameter-declaration-clause: +\series default +\emph default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\family typewriter +\emph on +... +\family default + +\begin_inset Newline newline +\end_inset + +match-parameter-declaration-list +\begin_inset Formula $_{\textrm{opt}}$ +\end_inset + + +\begin_inset Newline newline +\end_inset + +match-parameter-declaration-list +\emph default + +\family typewriter +\emph on +, ... +\end_layout + +\begin_layout Description + +\series medium +\emph on +match-parameter-declaration-list: +\series default +\emph default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\emph on +match-parameter-declaration +\begin_inset Newline newline +\end_inset + +match-parameter-declaration-list +\emph default + +\family typewriter +\emph on +, +\family default +\emph default + +\emph on +match-parameter-declaration +\end_layout + +\begin_layout Description + +\series medium +\emph on +match-parameter-declaration: +\series default +\emph default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\emph on +matct-decl-specifier-seq match-abstract-declarator +\begin_inset Formula $_{\textrm{opt}}$ +\end_inset + + +\end_layout + +\begin_layout Description + +\series medium +\emph on +match-declarator-id: +\series default +\emph default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\emph on +nested-match-name-specifier +\begin_inset Formula $_{\textrm{opt}}$ +\end_inset + + match-id +\begin_inset Newline newline +\end_inset + +nested-match-name-specifier +\begin_inset Formula $_{\textrm{opt}}$ +\end_inset + + match-operator-function-id +\begin_inset Newline newline +\end_inset + +nested-match-name-specifier +\begin_inset Formula $_{\textrm{opt}}$ +\end_inset + + match-conversion-function-id +\end_layout + +\begin_layout Description + +\series medium +\emph on +match-operator-function-id: +\series default +\emph default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\family typewriter +operator % +\family default + +\begin_inset Newline newline +\end_inset + + +\family typewriter +operator +\family default + +\emph on +match-operator +\end_layout + +\begin_layout Description + +\series medium +\emph on +match-operator: +\series default +\emph default + one of +\begin_inset Newline newline +\end_inset + + +\begin_inset Tabular + + + + + + + + + + + + + + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +new +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +delete +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +new[] +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +delete[] +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter ++ +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +- +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +* +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +/ +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +%% +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +^ +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +& +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +| +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +~ +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +! +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter += +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +< +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +> +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter ++= +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +-= +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +*= +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +/= +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +%%= +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +^= +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +&= +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +|= +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +<< +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +>> +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +>>= +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +<<= +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +== +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +!= +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +<= +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +>= +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +&& +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +|| +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +++ +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +-- +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +, +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +.* +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +->* +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +-> +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +() +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +[] +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\family typewriter +?: +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\end_inset + + +\end_layout + +\begin_layout Description + +\series medium +\emph on +match-conversion-function-id: +\series default +\emph default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\family typewriter +operator +\family default + +\emph on +match-conversion-type-id +\end_layout + +\begin_layout Description + +\series medium +\emph on +match-conversion-type-id: +\series default +\emph default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\emph on +match-type-specifier-seq match-conversion-declarator +\begin_inset Formula $_{\textrm{opt}}$ +\end_inset + + +\end_layout + +\begin_layout Description + +\series medium +\emph on +match-conversion-declarator: +\series default +\emph default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\emph on +match-ptr-operator match-conversion-declarator +\begin_inset Formula $_{\textrm{opt}}$ +\end_inset + + +\end_layout + +\begin_layout Standard +\begin_inset Newpage pagebreak +\end_inset + + +\end_layout + +\begin_layout Section +\begin_inset CommandInset label +LatexCommand label +name "sec:appendix:projectmodel_structure" + +\end_inset + +Structure Of The Project Repository +\begin_inset Index idx +status open + +\begin_layout Plain Layout +project repository +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +Figure +\begin_inset CommandInset ref +LatexCommand ref +reference "fig:acpp_structure_big" + +\end_inset + + shows the internal structure of the AspectC++ model and the AspectC++ project + repository. + The distinction between name and code join points and also the inheritance + hierarchy is visible. +\end_layout + +\begin_layout Standard +\begin_inset Float figure +placement H +wide false +sideways false +status open + +\begin_layout Plain Layout +\noindent +\align center +\begin_inset Graphics + filename images/acmodel-rotated90.pdf + width 9.6cm + scaleBeforeRotation + rotateOrigin leftTop + +\end_inset + + +\end_layout + +\begin_layout Plain Layout +\begin_inset Caption Standard + +\begin_layout Plain Layout +\begin_inset CommandInset label +LatexCommand label +name "fig:acpp_structure_big" + +\end_inset + +Structure of the AspectC++ project repository +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Section +\begin_inset CommandInset label +LatexCommand label +name "sec:Project-Repository-File" + +\end_inset + +Project Repository File For Example +\begin_inset CommandInset ref +LatexCommand vpageref +reference "exa:shape_example_code" + +\end_inset + + +\begin_inset Index idx +status open + +\begin_layout Plain Layout +project repository +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +\begin_inset listings +lstparams "basicstyle={\scriptsize\ttfamily},breaklines=true,showstringspaces=false,tabsize=2" +inline false +status open + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\begin_layout Plain Layout + + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +\begin_inset CommandInset index_print +LatexCommand printindex +type "idx" + +\end_inset + + +\end_layout + +\end_body +\end_document diff --git a/AspectC++/doc/LanguageReference/images b/AspectC++/doc/LanguageReference/images new file mode 120000 index 0000000..5e67573 --- /dev/null +++ b/AspectC++/doc/LanguageReference/images @@ -0,0 +1 @@ +../images \ No newline at end of file diff --git a/AspectC++/doc/Makefile b/AspectC++/doc/Makefile new file mode 100644 index 0000000..01a16c3 --- /dev/null +++ b/AspectC++/doc/Makefile @@ -0,0 +1,25 @@ +LYXFILES := ac-compilerman.lyx ac-languageref.lyx +DIRS := CompilerManual LanguageReference +PDFFILES := $(patsubst %.lyx,gen/%.pdf,$(LYXFILES)) +XHTMLFILES := $(patsubst %.lyx,gen/%.xhtml,$(LYXFILES)) + +VPATH = CompilerManual:LanguageReference + +all: $(PDFFILES) $(XHTMLFILES) + +gen/%.pdf: %.lyx + @echo Exporting $@ + @lyx -E pdf2 $@ $< > gen/logpdf.txt + +gen/%.xhtml: %.lyx + @echo Exporting $@ + @lyx -E xhtml $@ $< > gen/logxhtml.txt + @echo Transforming export file + @mv $@ $@.trans + @xsltproc gen/fixhtml.xsl $@.trans > $@ + @rm $@.trans + @echo Renaming PNGs + @for f in gen/*_doc_*.png; do mv $$f gen/$${f#*_doc_}; done + +clean: + @rm -rf $(PDFFILES) $(XHTMLFILES) gen/log*.txt gen/*~ $(patsubst %, gen/%_*.png, $(DIRS)) diff --git a/AspectC++/doc/NoE_ExecModelSurvey/ac++exec-survey.lyx b/AspectC++/doc/NoE_ExecModelSurvey/ac++exec-survey.lyx new file mode 100644 index 0000000..ed32ef4 --- /dev/null +++ b/AspectC++/doc/NoE_ExecModelSurvey/ac++exec-survey.lyx @@ -0,0 +1,455 @@ +#LyX 1.3 created this file. For more info see http://www.lyx.org/ +\lyxformat 221 +\textclass article +\begin_preamble + +%-------------------------------------------------------------------- +% PDF related +%-------------------------------------------------------------------- +\newif\ifpdf +\ifx\pdfoutput\undefined + \pdffalse % we are not running PDFLaTeX +\else + \pdfoutput=1 % we are running PDFLaTeX + \pdftrue +\fi + +%-------------------------------------------------------------------- +% setup hyperref +%-------------------------------------------------------------------- +\ifpdf + \usepackage{color} + \pagecolor{white} + \usepackage{hyperref} + \hypersetup{% + % + %% general document information + pdftitle = {AspectC++ Language Reference}, + pdfsubject = {Dokumentation}, + pdfkeywords = {AOP, AspectC++, pure-systems}, + pdfauthor = {\textcopyright\ pure-systems GmbH and Olaf Spinczyk}, + pdfcreator = {\LaTeX\ with package \flqq hyperref\frqq}, + pdfproducer = {pdfTeX-0.\the\pdftexversion\pdftexrevision}, + % + %% document style + colorlinks=true, % colored link + urlcolor=blue, % blue URL links + bookmarks=true, % generate bookmarks + bookmarksnumbered=true, % generate section numbers + pdfpagemode=None % don't open bookmarks + } + + %% set document creation date to 10.7.2003 00:00 + \pdfinfo {/CreationDate (D:20040628000000)} +\fi + +%-------------------------------------------------------------------- +% create hyperrefs depending on the use of pdflatex +%-------------------------------------------------------------------- +\newcommand\depref[2]{% + \ifpdf + \href{#1}{#2} + \else + {#2} + \fi +} + +\rhead{AspectC++ Execution Model Overview} +\lfoot{\copyright 2005 Olaf Spinczyk} +\end_preamble +\language english +\inputencoding auto +\fontscheme pslatex +\graphics default +\paperfontsize default +\spacing single +\papersize a4paper +\paperpackage a4 +\use_geometry 0 +\use_amsmath 0 +\use_natbib 0 +\use_numerical_citations 0 +\paperorientation portrait +\leftmargin 1cm +\topmargin 0.7cm +\rightmargin 2.5cm +\bottommargin 0.7cm +\secnumdepth 3 +\tocdepth 3 +\paragraph_separation indent +\defskip medskip +\quotes_language english +\quotes_times 2 +\papercolumns 1 +\papersides 1 +\paperpagestyle fancy + +\layout Title +\noindent + +\series bold +\emph on +AspectC++ -- Execution Model Overview +\layout Author + + +\begin_inset ERT +status Collapsed + +\layout Standard + +\backslash +copyright +\end_inset + + 2005 Olaf Spinczyk +\newline +Friedrich-Alexander University Erlangen-Nuremberg +\newline +Computer Science 4 +\layout Standard + +This is an overview about the AspectC++ execution model prepared for the + European AOSD Network of Excellence. + Detailed information on AspectC++ including manuals and tutorial slides + with lots of examples is available from +\begin_inset ERT +status Collapsed + +\layout Standard + +\backslash +depref{http://www.aspectc.org/}{ +\backslash +emph{the AspectC++ Project Homepage}} +\backslash +hspace{-4pt} +\end_inset + +. +\layout Standard + +The overview is based on the documentation for AspectC++ 0.9.3. + The execution model is still +\begin_inset Quotes eld +\end_inset + +work in progress +\begin_inset Quotes erd +\end_inset + +. +\layout Standard +\added_space_top bigskip \line_bottom \noindent + +\size largest +Models +\layout Section* + +Architectural Characteristics +\layout Standard + +The following objectives of the AspectC++ development effort are responsible + for the design of the AspectC++ execution model: +\layout Itemize + +The resource consumption of AspectC++ applications should be minimal. + Compared to a tangled implementation of the same functionality there should + be +\emph on +no overhead +\emph default +. +\layout Itemize + +AspectC++ should fit into the +\begin_inset Quotes eld +\end_inset + +philosophy +\begin_inset Quotes erd +\end_inset + + of C++, i.e. + as much as possible is done at compile-time. +\layout Itemize + +AspectC++ should not rely on any runtime infrastructure provided by C++ + such as a heap or RTTI. + These features are often not available in embedded systems projects or + system software. +\layout Standard + +AspectC++ is implemented by a static source to source transformation from + AspectC++ to C++. + A version that is able to generate pure C code if the component code language + is C will be available in the near future. +\layout Standard + +A separate AOP run-time infrastructure is not needed by the generated applicatio +ns. + A small number of helper functions, classes, and templates is woven directly + into the application code modules. +\layout Section* + +Aspect Model +\layout Standard + +The AspectC++ weaver transforms aspects into ordinary C++ classes. + The generated aspect classes do not inherited from a specific (common) + base class. + Therefore, the object layout is not affected by the tranformation. +\layout Section* + +Advice Model +\layout Standard + +After the transformation, advice becomes an aspect (class) member function. + If the system is compiled with optimizations enabled, the advice code will + typically be inlined into the component code. + The argument list of the advice (function) contains the context variables + that are passed from the join point to the advice and an optional +\family typewriter +\size small +JoinPoint *tjp +\family default +\size default + pointer. + This pointer is only passed if the advice code actually uses +\family typewriter +\size small +tjp +\family default +\size default +. +\layout Standard + +In the case that the advice uses +\family typewriter +\size small +tjp +\family default +\size default +, static members, or types defined in +\family typewriter +\size small +JoinPoint +\family default +\size default + the advice is transformed into a template function with +\family typewriter +\size small +JoinPoint +\family default +\size default + as a template parameter type. + Due to the template instantiation mechanism of C++, multiple instances + of the advice code might exist at runtime. +\layout Section* + +Pointcut Model +\layout Standard + +Pointcuts have no runtime representation. +\layout Standard +\added_space_top bigskip \line_bottom \noindent + +\size largest +Functionality +\layout Section* + +Joinpoint Shadow Retrieval +\layout Standard + +In the static AspectC++ weaver +\family typewriter +\size small + ac++ +\family default +\size default + , joinpoints are retrieved only at compile time. + A complete syntactical and semantical analysis has to be performed on the + AspectC++ code. + The result is a syntax tree representation with links to symbol tables, + which in include the results of the semantic analysis, and links to tokens + in the input file. + The token links are needed for the code transformation. + Based on the symbol tables the set of static joinpoints (see language descripti +on), execution joinpoints, construction joinpoints, and destruction joinpoints + is constructed. + A visitor is used to find all call joinpoint shadows in the syntax tree. +\layout Section* + +Weaving Approach +\layout Standard + +Our weaver +\family typewriter +\size small +ac++ +\family default +\size default + is usually applied directly before calling the C++ compiler. + With the +\family typewriter +\size small +ag++ +\family default +\size default + front-end both steps are even integrated into one tool. + Depending on the advice defined in the program, the weaver performs the + following manipulations: +\layout Itemize + +function calls are replaced with calls to wrapper functions that call the + advice chain +\layout Itemize + +function implementations are replaced with wrapper functions +\layout Itemize + +new members are inserted into classes +\layout Itemize + + +\family typewriter +\size small +#include +\family default +\size default + directives are generated +\layout Itemize + + +\family typewriter +\size small +#include +\family default +\size default + directives are expanded (only in the so-called "single translation unit" + mode) +\layout Itemize + +aspects are transformed into classes +\layout Itemize + +the +\family typewriter +\size small +aspectof() +\family default +\size default + function is generated if there is no user defined one +\layout Itemize + +code for the instantiation of singleton aspects is generated +\layout Itemize + +code for cflow management is generated (enter, exit, check, state instance) +\layout Itemize + +helper functions for runtime type condition checks on objects are generated + (for +\family typewriter +\size small +that +\family default +\size default +, +\family typewriter +\size small +target +\family default +\size default +, and combinations) +\layout Standard + +Currently, all aspects of the project become +\begin_inset Quotes eld +\end_inset + +friends +\begin_inset Quotes erd +\end_inset + + of all classes and other aspects of the project. + A more sophisticated access control mechanism is future work. +\layout Standard + +Introduced members become ordinary members. + Their visibility (private, public, or protected) is taken from the visibility + of the advice declaration in the aspect body. +\layout Standard + +Advice code and the generated wrapper functions, which call the advice, + can normally be inlined. + Only in case of around advice the +\family typewriter +\size small +tjp->proceed() +\family default +\size default + is implemented by an indirect call using a function pointer. + Therefore, this operation is currently not inlined, which leads to a noticeably + higher resource consumption than for a combined before and after advice. + We are currently working on a better code transformation pattern to avoid + this problem. +\layout Section* + +Special Treatment of Dynamic Pointcuts +\layout Standard + +Currently, the cflow in AspectC++ does not support pointcuts with context + variables in the cflow argument. + Therefore, a cflow can easily be implemented by a counter that is incremented + when the cflow is entered and decremented when the cflow is left. + An improved cflow implementation that allows context variables is under + development. + Here the context will be stored on the call stack. +\layout Standard + +For the +\family typewriter +\size small +that() +\family default +\size default + and +\family typewriter +\size small +target() +\family default +\size default + pointcut functions it is sometimes necessary to generate runtime type checks. + As we do not require the application code to be compiled with enabled runtime + type information, +\family typewriter +\size small +ac++ +\family default +\size default + generates virtual type condition check functions wherever needed. + This operation might change the object layout if the corresponding class + had no associated virtual function table before. +\layout Section* + +Advice Instance Management +\layout Standard + +Advice code is instantiated at compile time. + If the advice depends on the type +\family typewriter +\size small +JoinPoint +\family default +\size default +, a join point specific class that implements the required types and functions + is generated and used as a template parameter for the advice code. +\layout Section* + +Deployment and Undeployment +\layout Standard + +There is no dynamic deployment or undeployment of aspects. + +\the_end diff --git a/AspectC++/doc/NoE_ExecModelSurvey/ac++exec-survey.pdf b/AspectC++/doc/NoE_ExecModelSurvey/ac++exec-survey.pdf new file mode 100644 index 0000000..81f6a1c Binary files /dev/null and b/AspectC++/doc/NoE_ExecModelSurvey/ac++exec-survey.pdf differ diff --git a/AspectC++/doc/NoE_ShortSurvey/ac++lang-survey.lyx b/AspectC++/doc/NoE_ShortSurvey/ac++lang-survey.lyx new file mode 100644 index 0000000..284b6fb --- /dev/null +++ b/AspectC++/doc/NoE_ShortSurvey/ac++lang-survey.lyx @@ -0,0 +1,1336 @@ +#LyX 1.3 created this file. For more info see http://www.lyx.org/ +\lyxformat 221 +\textclass article +\begin_preamble + +%-------------------------------------------------------------------- +% PDF related +%-------------------------------------------------------------------- +\newif\ifpdf +\ifx\pdfoutput\undefined + \pdffalse % we are not running PDFLaTeX +\else + \pdfoutput=1 % we are running PDFLaTeX + \pdftrue +\fi + +%-------------------------------------------------------------------- +% setup hyperref +%-------------------------------------------------------------------- +\ifpdf + \usepackage{color} + \pagecolor{white} + \usepackage{hyperref} + \hypersetup{% + % + %% general document information + pdftitle = {AspectC++ Language Reference}, + pdfsubject = {Dokumentation}, + pdfkeywords = {AOP, AspectC++, pure-systems}, + pdfauthor = {\textcopyright\ pure-systems GmbH and Olaf Spinczyk}, + pdfcreator = {\LaTeX\ with package \flqq hyperref\frqq}, + pdfproducer = {pdfTeX-0.\the\pdftexversion\pdftexrevision}, + % + %% document style + colorlinks=true, % colored link + urlcolor=blue, % blue URL links + bookmarks=true, % generate bookmarks + bookmarksnumbered=true, % generate section numbers + pdfpagemode=None % don't open bookmarks + } + + %% set document creation date to 10.7.2003 00:00 + \pdfinfo {/CreationDate (D:20040628000000)} +\fi + +%-------------------------------------------------------------------- +% create hyperrefs depending on the use of pdflatex +%-------------------------------------------------------------------- +\newcommand\depref[2]{% + \ifpdf + \href{#1}{#2} + \else + {#2} + \fi +} + +\usepackage{listings} +\usepackage{color} +\definecolor{darkgrey}{rgb}{.4, .4, .4} +\definecolor{lightgrey}{rgb}{.95, .95, .95} +\definecolor{lightyellow}{rgb}{.99, .97, .90} + +\lstloadlanguages{C++} +\lstdefinelanguage[Aspect]{C++}[ISO]{C++}{ + morekeywords={aspect, advice, pointcut, tjp}, + morekeywords=[2]{call, execution, within, + cflow, before, around, after, baseclass + } +} + +\lstdefinestyle{acstyle}{ + basicstyle=\footnotesize\ttfamily, + keywordstyle=[2]\bfseries\emph, + showstringspaces=false, + language=[Aspect]{C++}, + escapechar={@}, +} +\lstdefinestyle{ac}{ + style=acstyle, + xleftmargin=6mm, + lineskip=-5.5pt +} +\lstdefinestyle{aclisting}{ + style=acstyle, + backgroundcolor=\color{lightyellow}, + frame=single, + %frameround=tttt, + rulecolor=\color{yellow} +} +\lstset{style=ac} +\rhead{AspectC++ Language Overview} +\lfoot{\copyright 2005 Olaf Spinczyk} +\end_preamble +\language english +\inputencoding auto +\fontscheme pslatex +\graphics default +\paperfontsize default +\spacing single +\papersize a4paper +\paperpackage a4 +\use_geometry 0 +\use_amsmath 0 +\use_natbib 0 +\use_numerical_citations 0 +\paperorientation portrait +\leftmargin 1cm +\topmargin 0.7cm +\rightmargin 2.5cm +\bottommargin 0.7cm +\secnumdepth 3 +\tocdepth 3 +\paragraph_separation skip +\defskip smallskip +\quotes_language english +\quotes_times 2 +\papercolumns 1 +\papersides 1 +\paperpagestyle fancy + +\layout Title +\noindent + +\series bold +\emph on +AspectC++ -- A Language Overview +\layout Author + + +\begin_inset ERT +status Collapsed + +\layout Standard + +\backslash +copyright +\end_inset + + 2005 Olaf Spinczyk +\newline +Friedrich-Alexander University Erlangen-Nuremberg +\newline +Computer Science 4 +\layout Standard + +This is an overview about the AspectC++ language, an aspect-oriented extension + for C/C++, prepared for the European AOSD Network of Excellence. + Detailed information on AspectC++ including manuals and tutorial slides + with lots of examples is available from +\begin_inset ERT +status Open + +\layout Standard + +\backslash +depref{http://www.aspectc.org/}{ +\backslash +emph{the AspectC++ Project Homepage}} +\backslash +hspace{-4pt} +\end_inset + +. +\layout Standard + +The overview is based on the documentation for AspectC++ 0.9.3. + The language is still +\begin_inset Quotes eld +\end_inset + +work in progress +\begin_inset Quotes erd +\end_inset + +. +\layout Section* + +Joinpoint Model and Pointcut Language +\layout Standard + +AspectC++ supports +\emph on +static +\emph default + joinpoints as well as +\emph on +dynamic +\emph default + joinpoints. + While static joinpoints are named entities in the static program structure, + dynamic joinpoints are events that happen during the program execution. +\layout Subsection* + +Static Joinpoints +\layout Standard + +The following kinds of C++ program entities are considered as static joinpoints: +\layout Itemize + +classes, structs, and unions +\layout Itemize + +namespaces +\layout Itemize + +all kinds of functions (member, non-member, operator, conversion, etc.) +\layout Standard + +Static joinpoints are described by +\emph on +match expressions +\emph default +. + For example, +\family typewriter +\size small +"% ...::foo(...)" +\family default +\size default + is a match expression that describes all functions called +\family typewriter +\size small +foo +\family default +\size default + (in any scope, with any argument list, and any result type). + More information on match expressions is given below. + Note that not all of these static joinpoint types are currently supported + as a target of advice (see section 'Advice for Static Joinpoints'). + +\layout Subsection* + +Dynamic Joinpoints +\layout Standard + +The following kinds of events that might happen during the execution of + a program are considered as dynamic joinpoints: +\layout Itemize + +function call +\layout Itemize + +function execution +\layout Itemize + +object construction +\layout Itemize + +object destruction +\layout Standard + +The description of dynamic joinpoints is based upon the description mechanism + for static joinpoints in conjunction with joinpoint type specific +\emph on +pointcut functions +\emph default +. + For example: +\layout Itemize + + +\family typewriter +\series bold +\size small +\emph on +call +\series default +\emph default +("% ...::foo(...)") +\layout Itemize + + +\family typewriter +\series bold +\size small +\emph on +execution +\series default +\emph default +("float MathFuncs::%(float)") +\layout Itemize + + +\family typewriter +\series bold +\size small +\emph on +construction +\series default +\emph default +("SomeClassName") +\layout Itemize + + +\family typewriter +\series bold +\size small +\emph on +destruction +\series default +\emph default +("A"||"B") +\layout Standard + +While +\family typewriter +\size small +"% ...::foo(...)" +\family default +\size default + represents a set of static joinpoints, i.e. + all functions called +\family typewriter +\size small +foo +\family default +\size default +, the expression +\family typewriter +\size small +call("% ...::foo(...)") +\family default +\size default + describes all calls to these functions. + A similar mapping from static to dynamic joinpoints is done by the +\family typewriter +\size small +execution() +\family default +\size default +, +\family typewriter +\size small +construction() +\family default +\size default +, and +\family typewriter +\size small +destruction() +\family default +\size default + pointcut functions. +\layout Subsection* + +Pointcut Functions +\layout Standard + +Further pointcut functions are used to filter or select joinpoints with + specific properties. + Some of them can be evaluated at compile time while others yield conditions + that have to be checked at run time: +\layout Itemize + + +\family typewriter +\series bold +\size small +\emph on +cflow +\series default +\emph default +( +\emph on +pointcut +\emph default +) +\family default +\size default + -- captures all joinpoints in the dynamic execution context of the joinpoints + in +\emph on +pointcut +\emph default +. +\layout Itemize + + +\family typewriter +\series bold +\size small +\emph on +base +\series default +\emph default +( +\emph on +pointcut +\emph default +) +\family default +\size default + and +\family typewriter +\series bold +\size small +\emph on +derived +\series default +\emph default +( +\emph on +pointcut +\emph default +) +\family default +\size default + -- yield classes based on queries in the class hierarchy +\layout Itemize + + +\family typewriter +\series bold +\size small +\emph on +within +\series default +\emph default +( +\emph on +pointcut +\emph default +) +\family default +\size default + -- filters joinpoints depending on their lexical scope +\layout Itemize + + +\family typewriter +\series bold +\size small +\emph on +that +\series default +\emph default +( +\emph on +type\SpecialChar ~ +pattern +\emph default +) +\family default +\size default +, +\family typewriter +\series bold +\size small +\emph on +target +\series default +\emph default +( +\emph on +type\SpecialChar ~ +pattern +\emph default +) +\family default +\size default +, +\family typewriter +\series bold +\size small +\emph on +result +\series default +\emph default +( +\emph on +type\SpecialChar ~ +pattern +\emph default +) +\family default +\size default +, and +\family typewriter +\series bold +\size small +\emph on +args +\series default +\emph default +( +\emph on +type\SpecialChar ~ +pattern +\emph default +) +\family default +\size default + -- filters joinpoints depending on the current object type, the target + object type in a call, and the result and arguments types of a dynamic + joinpoint. +\layout Itemize + + +\family typewriter +\series bold +\size small +&& +\family default +\series default +\size default +, +\family typewriter +\series bold +\size small +|| +\family default +\series default +\size default +, +\family typewriter +\series bold +\size small +! +\family default +\series default +\size default + -- intersection, union, and exclusion of joinpoints in pointcuts +\layout Standard + +Instead of the +\emph on +type pattern +\emph default + it is also possible to pass the name of a +\emph on +context variable +\emph default + to which context information from the joinpoint shall be bound. + In this case the type of the context variable is used for the type matching. +\layout Subsection* + +Match Mechanism Capabilities +\layout Standard + +The match mechanism provides +\family typewriter +\size small +% +\family default +\size default + and +\family typewriter +\size small +... + +\family default +\size default + as wildcard symbols. + Thereby the following features are supported: +\layout Itemize + +pattern based name matching, e.g. + +\family typewriter +\size small +"%X%" +\family default +\size default + matches all names that contain an uppercase +\family typewriter +\size small +X +\layout Itemize + +flexible scope matching, e.g. + +\family typewriter +\size small +"Foo::...::Bar" +\family default +\size default + matches Bar in the scope +\family typewriter +\size small +Foo +\family default +\size default + or any of its nested scopes +\layout Itemize + +flexible matching of function argument type lists, e.g. + +\family typewriter +\size small +"% foo(...,int)" +\family default +\size default + matches +\family typewriter +\size small +foo +\family default +\size default + with an +\family typewriter +\size small +int +\family default +\size default + as its last argument type +\layout Itemize + +matching template argument lists, e.g. + +\family typewriter +\size small +"C" +\family default +\size default + matches an instance of the class template +\family typewriter +\size small +C +\family default +\size default + with a first template argument type +\family typewriter +\size small +T +\layout Itemize + +type patterns, e.g. + +\family typewriter +\size small +"const % *" +\family default +\size default + matches all pointer types that reference objects of a constant type +\layout Subsection* + +Named Pointcuts +\layout Standard + +Pointcut expressions can be given a name. + The definition of a named pointcut can be placed in any aspect, class, + or namespace. + The mechanism can be used for dynamic as well as static joinpoints. + For example: +\layout Standard + + +\begin_inset ERT +status Inlined + +\layout Standard + +\backslash +begin{lstlisting}[style=ac] +\layout Standard +class OStream { +\layout Standard + // ... +\layout Standard + pointcut manipulator_types() = "hex"||"oct"||"bin"||"endl"; +\layout Standard +}; +\layout Standard + +\backslash +end{lstlisting} +\end_inset + + +\layout Standard + +In the context of an aspect, named pointcuts can also be defined as virtual + or pure virtual, which allows refinement/definition in a derived aspect + (see example at the end of this overview). +\layout Section* + +Advice Model and Language +\layout Subsection* + +Advice for Static Joinpoints +\layout Standard + +The only kind of advice for static joinpoints that is currently supported + by AspectC++ is the +\emph on +introduction +\emph default +. + By using this kind of advice the aspect code is able to add new elements + to classes, structures, or unions. + Everything that is syntactically permitted in the body of a C++ class can + be introduced by advice: +\layout Itemize + +attribute introduction, e.g. + +\family typewriter +\size small +advice "AClass" : int _introduced_attribute; +\layout Itemize + +type introduction, e.g. + +\family typewriter +\size small +advice "AClass" : typedef int INT; +\layout Itemize + +member function introduction, e.g. + +\family typewriter +\size small +advice "AClass" : void f(); +\layout Itemize + +nested type introduction, e.g. + +\family typewriter +\size small +advice "AClass" : class Inner { ... + }; +\layout Itemize + +constructor introduction, e.g. + +\family typewriter +\size small +advice "AClass" : AspectName(int, double); +\layout Itemize + +destructor introduction, e.g. + +\family typewriter +\size small +advice "AClass" : ~AspectName() { ... + } +\layout Itemize + +base class introduction, e.g. + +\family typewriter +\size small +advice "AClass" : baseclass(ANewBaseclass); +\layout Standard + +The syntax +\family typewriter +\size small +advice < +\emph on +target +\emph default +- +\emph on +pointcut +\emph default +> : < +\emph on +introduction +\emph default +> +\family default +\size default + supports the introduction of an element into an arbitrary set of target + classes with a single advice. +\layout Subsection* + +Advice for Dynamic Joinpoints +\layout Standard + +Advice for dynamic joinpoints is used to affect the flow of control, when + the joinpoint is reached. + The following kinds of advice are supported: +\layout Itemize + +before advice +\layout Itemize + +after advice +\layout Itemize + +around advice +\layout Standard + +These advice types can orthogonally be combined with all dynamic joinpoint + types. + Advice for dynamic joinpoints is defined with the following syntax: +\layout LyX-Code + + +\series bold +\size small +advice +\series default + < +\emph on +target-pointcut +\emph default +> : ( +\series bold +before +\series default +| +\series bold +after +\series default +| +\series bold +around +\series default +) (< +\emph on +arguments +\emph default +>) { +\layout LyX-Code + + +\size small + < +\emph on +advice-body +\emph default +> +\layout LyX-Code + + +\size small +} +\layout Standard + +While the before and after advice bodies are executed before or after the + event described by +\family typewriter +\size small +\emph on + +\family default +\size default +\emph default +, an around advice body is executed instead of the event. +\layout Subsubsection* + +Advice Language and Joinpoint API +\layout Standard + +The advice body is implemented in standard C++. + Additionally, the +\emph on +joinpoint API +\emph default + can be used to access (read and write) +\emph on +context information +\emph default + (e.g. + function argument and result values) as well as +\emph on +static type information +\emph default + about the current joinpoint. + To access the joinpoint API the object +\family typewriter +\size small +JoinPoint *tjp +\family default +\size default + can be used, which is implicitly available in advice code. + Advice that uses the static type information provided by the joinpoint + API is called +\emph on +generic advice +\emph default +. + This concept is the key for generic, type-safe, +\emph on +and +\emph default + efficient advice in AspectC++. + The static type information from the joinpoint API can even be used to + instantiate template metaprograms, which is a technique for joinpoint specific + code generation at compile time. +\layout Standard + +The joinpoint API is also used to proceed the execution from within around + advice ( +\family typewriter +\size small +tjp->proceed() +\family default +\size default +). + Alternatively, +\family typewriter +\size small +tjp->action() +\family default +\size default + may be called to retrieve and store the +\emph on +proceed context +\emph default +as an +\family typewriter +\size small +AC::Action +\family default +\size default + object. + Later, +\family typewriter +\size small +action.trigger() +\family default +\size default + may be called to proceed the intercepted flow of control. +\layout Standard + +Catching and changing exceptions can be done by standard C++ features in + around advice (try, catch, throw). +\layout Subsubsection* + +Example +\layout Standard + +The following advice is +\emph on +generic advice +\emph default +, because its implementation can deal with multiple overloaded +\family typewriter +\size small +C::foo(...) +\family default +\size default + implementations that have different result types: +\layout Standard + + +\begin_inset ERT +status Open + +\layout Standard + +\backslash +begin{lstlisting}[style=ac] +\layout Standard +advice execution("% C::foo(...)") : around() { +\layout Standard + cout << "executing " << JoinPoint::signature() +\layout Standard + << " on " << *tjp->that() << endl; +\layout Standard + tjp->proceed (); +\layout Standard + cout << "the result was " << *tjp->result() << endl; +\layout Standard +} +\layout Standard + +\backslash +end{lstlisting} +\end_inset + + +\layout Section* + +Aspect Module Model +\layout Standard + +The following example code shows an aspect +\family typewriter +\size small +Logging +\family default +\size default + defined in AspectC++: +\layout Standard + + +\begin_inset ERT +status Inlined + +\layout Standard + +\backslash +begin{lstlisting}[style=ac] +\layout Standard +aspect Logging { +\layout Standard + ostream *_out; // ordinary attributes +\layout Standard +public: +\layout Standard + void bind_stream(ostream *o) { _out = o; } // member function +\layout Standard + pointcut virtual logged_classes() = 0; // pure virtual pointcut +\layout Standard + // some advice +\layout Standard + advice execution("% ...::%(...)") && within(logged_classes()) : +\layout Standard + before () { +\layout Standard + *_out << "executing " << JoinPoint::signature () << endl; +\layout Standard + } +\layout Standard +}; +\layout Standard + +\backslash +end{lstlisting} +\end_inset + + +\layout Standard + +Aspects are the language element that is used to group all the definitions + that are needed to implement a crosscutting concern. + An aspect definition is allowed to contain member functions, attributes, + nested classes, named pointcuts, etc. + as ordinary classes. + Additionally, aspects normally contain advice definitions. +\layout Standard + +Aspects that contain pure virtual member functions or pure virtual pointcuts + are called +\emph on +abstract aspects +\emph default +. + These aspects only affect the system if a (concrete) aspect is derived, + which defines an implementation for the pure virtual functions and the + pure virtual pointcuts. + Abstract aspects are the AspectC++ mechanism to implement reusable aspect + code. +\layout Standard + +Aspect inheritance is slighly restricted. + Aspects can inherit from ordinary classes and abstract aspects but not + from concrete aspects. + Derived aspects can redefine virtual pointcuts and virtual functions defined + by base aspects. +\layout Section* + +Aspect Instantiation Model +\layout Standard + +By default, aspects are singletons, i.e. + there is one global instance automatically created for each non-abstract + aspect in the program. + However, by defining the +\family typewriter +\size small +aspectof() +\family default +\size default + static member function of an aspect the user can implement arbitrary instantiat +ion schemes, such as +\emph on +per-target +\emph default +, +\emph on +per-thread +\emph default +, or +\emph on +per-joinpoint +\emph default +. + For each dynamic joinpoint that is affected by the aspect the +\family typewriter +\size small +aspectof() +\family default +\size default + function has to return the right aspect instance on which the advice bodies + are invoked. + The instances themselfs are usually created with the introduction mechanism. + The +\family typewriter +\size small +aspectof() +\family default +\size default + function has access to the joinpoint API in order to find the right aspect + instance for the current joinpoint. + Here is an example: +\layout Standard + + +\begin_inset ERT +status Inlined + +\layout Standard + +\backslash +begin{lstlisting}[style=ac] +\layout Standard +aspect InstancePerTargetAspect { +\layout Standard + pointcut target_class() = "TargetName"; +\layout Standard + // an attribute of the aspect (stored per target) +\layout Standard + int _calls; +\layout Standard + // aspect instance created by introduction: +\layout Standard + advice target_class() : InstancePerTargetAspect _instance; +\layout Standard + // definition of the instantiation scheme in aspectof(): +\layout Standard + static InstancePerTargetAspect *aspectof() { +\layout Standard + return tjp->target()->_instance; +\layout Standard + } +\layout Standard + // the advice +\layout Standard + advice call("% ...::%(...)") && target(target_class()) : before () { +\layout Standard + _calls++; +\layout Standard + } +\layout Standard + // attribute initialization in the aspect constructor +\layout Standard + InstancePerTargetAspect () : _calls (0) {} +\layout Standard +}; +\layout Standard + +\backslash +end{lstlisting} +\end_inset + + +\layout Section* + +Aspect Composition Model +\layout Standard + +In AspectC++ any number of aspects can be used in the same application. + Aspect composition is currently restricted to inheritance from abstract + aspects. + Concrete aspects cannot be used for the implementation of new aspects. +\layout Standard + +Aspect interactions can be handled by the developer on a per joinpoint basis + with +\emph on +order advice +\emph default +, e.g. + +\family typewriter +\size small +advice execution("void f%(...)") : order("Me", !"Me") +\family default +\size default + gives the aspect +\family typewriter +\size small +Me +\family default +\size default + the highest precedence at all joinpoint described by the pointcut expression. + Order advice can be given by any aspect for any aspect, thus can be separated + from the affected aspects. + Aspect names in order advice declarations are match expressions and may + contain wildcards, e.g. + +\family typewriter +\size small +order("kernel::%", !"kernel::%") +\family default +\size default + gives every aspect declared in the namespace +\family typewriter +\size small +kernel +\family default +\size default + precedence over all other aspects. + Besides this partial order in the precedence of aspects, the precedence + of advice within one aspect is determined according to its position in + the aspect definition. + As long as it does not conflict with order advice AspectC++ aims to give + aspects the same precedence at all joinpoints. +\layout Section* + +Aspect Weaving Model +\layout Standard + +The only implementation of AspectC++ is based on static source to source + transformation. + Nevertheless, the language could also be used for dynamic weavers if some + really hard technical challenges like runtime introductions were solved. +\layout Section* + +Example +\layout Standard + +A reusable observer pattern implementation in AspectC++: +\layout Standard + + +\begin_inset ERT +status Inlined + +\layout Standard + +\backslash +begin{lstlisting}[style=ac] +\layout Standard +aspect ObserverPattern { +\layout Standard + // Data structures to manage subjects and observers +\layout Standard + ... +\layout Standard + public: +\layout Standard + // Interfaces for each role +\layout Standard + struct ISubject {}; +\layout Standard + struct IObserver { +\layout Standard + virtual void update(ISubject *) = 0; +\layout Standard + }; +\layout Standard + +\layout Standard + // To be defined by the concrete derived aspect +\layout Standard + pointcut virtual observers() = 0; +\layout Standard + pointcut virtual subjects() = 0; +\layout Standard + // subjectChange() matches all non-const methods by default +\layout Standard + pointcut virtual subjectChange() = +\layout Standard + execution("% ...::%(...)" && !"% ...::%(...) const") +\layout Standard + && within(subjects()); +\layout Standard + +\layout Standard + // Add new baseclass to each subject/observer class +\layout Standard + // and insert code to inform observers +\layout Standard + advice observers() : baseclass(IObserver); +\layout Standard + advice subjects() : baseclass(ISubject); +\layout Standard + advice subjectChange() : after() { +\layout Standard + ISubject* subject = tjp->that(); +\layout Standard + updateObservers(subject); +\layout Standard + } +\layout Standard + +\layout Standard + // Operations to add, remove and notify observers +\layout Standard + void updateObservers(ISubject* sub) { ... } +\layout Standard + void addObserver(ISubject* sub, IObserver* ob) { ... } +\layout Standard + void remObserver(ISubject* sub, IObserver* ob) { ... } +\layout Standard +}; +\layout Standard + +\backslash +end{lstlisting} +\end_inset + + +\layout Standard + +Concrete aspect, which applies the pattern: +\layout Standard + + +\begin_inset ERT +status Open + +\layout Standard + +\backslash +begin{lstlisting}[style=ac] +\layout Standard +#include "ObserverPattern.ah" +\layout Standard +#include "ClockTimer.h" +\layout Standard + +\layout Standard +aspect ClockObserver : public ObserverPattern { +\layout Standard + // define the pointcuts +\layout Standard + pointcut subjects() = "ClockTimer"; +\layout Standard + pointcut observers() = "DigitalClock"||"AnalogClock"; +\layout Standard +public: +\layout Standard + advice observers() : +\layout Standard + void update( ObserverPattern::ISubject* sub ) { +\layout Standard + Draw(); +\layout Standard + } +\layout Standard +}; +\layout Standard + +\backslash +end{lstlisting} +\end_inset + + +\the_end diff --git a/AspectC++/doc/NoE_ShortSurvey/ac++lang-survey.pdf b/AspectC++/doc/NoE_ShortSurvey/ac++lang-survey.pdf new file mode 100644 index 0000000..53f061d Binary files /dev/null and b/AspectC++/doc/NoE_ShortSurvey/ac++lang-survey.pdf differ diff --git a/AspectC++/doc/ProgrammingGuide/ProgrammingGuide.lyx b/AspectC++/doc/ProgrammingGuide/ProgrammingGuide.lyx new file mode 100644 index 0000000..799ffae --- /dev/null +++ b/AspectC++/doc/ProgrammingGuide/ProgrammingGuide.lyx @@ -0,0 +1,2088 @@ +#LyX 1.3 created this file. For more info see http://www.lyx.org/ +\lyxformat 221 +\textclass article +\begin_preamble +\usepackage{floatflt} +\usepackage{../styles/pure-systems} +\doctype{Documentation:} +\titleback{ + \null\thispagestyle{empty}\vfill + \noindent\small{(c) 2002-2003 pure-systems GmbH\\All rights reserved.} + \null\cleardoublepage} +\pslogo{ + \resizebox{6cm}{!}{\includegraphics{../images/ps-logo.eps}}} +\otherlogo{ + \resizebox{4cm}{!}{\includegraphics{../images/ac++logo.eps}}} +\sloppy +\remark{ + \small{(c) 2002-2003 pure-systems GmbH\\Agnetenstr. 14\\39106 Magdeburg\\http://www.pure-systems.com}} +\end_preamble +\language english +\inputencoding auto +\fontscheme pslatex +\graphics default +\float_placement hbt +\paperfontsize 11 +\spacing single +\papersize Default +\paperpackage a4 +\use_geometry 0 +\use_amsmath 0 +\use_natbib 0 +\use_numerical_citations 0 +\paperorientation portrait +\secnumdepth 3 +\tocdepth 3 +\paragraph_separation indent +\defskip medskip +\quotes_language english +\quotes_times 2 +\papercolumns 1 +\papersides 1 +\paperpagestyle default + +\layout Title + +AspectC++ Programming Guide +\begin_inset Note +collapsed false + +\layout Standard + +!!!NOCH NICHT BEGONNEN!!! (=> EHEMALIGES Manual.sgml) +\end_inset + + +\layout Author + +Danilo Beuche +\newline +Daniel Mahrenholz +\layout Standard + + +\begin_inset LatexCommand \tableofcontents{} + +\end_inset + + +\begin_inset ERT +status Collapsed + +\layout Standard + +\backslash +clearpage +\end_inset + + +\layout Comment + + +\begin_inset ERT +status Collapsed + +\layout Standard + +\backslash +twocolumn +\end_inset + + +\layout Section + +Introduction +\layout Standard + +AspectC++ is an aspect-oriented extension to the C++ language. + It is similar to AspectJ +\begin_inset Foot +collapsed true + +\layout Standard + + +\family typewriter +www.aspectj.org +\end_inset + + but, due to the nature of C++, in some points completely different. + AspectC++ works as a C/C++ to C++ compiler and so can be used as a front-end + to any C++-compliant compiler. + AspectC++ does not require a special runtime system. + This enables AspectC++ to be used in areas where e.g. + Java/AspectJ are not suitable. + +\layout Section + +Getting Started +\layout Subsection + +Installation +\layout Standard + +Currently AspectC++ is available as precompiled binary only. + To install AspectC++, follow these steps: +\layout Enumerate + +Download the archive appropriate for your platform/system from the download + section of +\family typewriter +AspectC.org +\family default + +\begin_inset Foot +collapsed true + +\layout Standard + + +\family typewriter +www.aspectc.org +\end_inset + +. +\layout Enumerate + +Unpack the archive. +\layout Itemize + +Linux/Solaris/MacOS X version: using +\series bold +tar +\series default + and +\series bold +gzip +\series default +: +\series bold +tar xzf +\series default + +\series bold +aspectc++-{version}.tar.gz +\series default +. + All files will be placed under +\family typewriter +aspectc++-{version} +\family default +. +\layout Itemize + +Win32 version: using e.g. + +\series bold +Winzip +\series default +. + Extract the archive to +\family typewriter +C: +\backslash + +\family default +. + All files will than be placed under +\family typewriter +C: +\backslash +AC +\family default +. +\layout Subsection + +Configuration: Linux/Solaris/MacOS X version +\layout Standard + +Before AspectC++ can run correctly some environment variables need to be + set up and a configuration file for the PUMA parser has to be created. +\layout Itemize + + +\family typewriter +CC +\family default + (optional) should be set to your preferred C compiler. +\layout Itemize + + +\family typewriter +CXX +\family default + (optional) should be set to your preferred C++ compiler. +\layout Itemize + + +\family typewriter +PUMA +\family default + (mandatory) should point to your PUMA directory. + In most cases this variable should be set to +\family typewriter +/PUMA +\family default +. +\layout Itemize + + +\family typewriter +PUMA_CONFIG +\family default + (mandatory) should point to your PUMA configuration file. + If you follow this installation instructions this variable should be set + to +\family typewriter +/puma.config +\family default +. +\layout Standard + +After setting up all the environment variables the creation of the PUMA + configuration file can be done by running +\series bold +$PUMA/Runtime/Binaries/pumag++conf.pl $PUMA_CONFIG +\series default +. + You need a functioning PERL installation to use this configuration script. +\layout Quote + + +\series bold +Important: +\series default + In most cases the generated configuration file can be used only with the + selected ( +\family typewriter +CC +\family default +, +\family typewriter +CXX +\family default +) compiler. + So you have to create a new configuration every time you choose another + compiler. + +\layout Subsection + +Configuration: Win32 version +\layout Standard + +See the +\family typewriter +README.win32 +\family default + file included in the Win32 archive. +\layout Subsection + +Running the Examples +\layout Standard + +The AspectC++ package comes with a set of working examples (subdirectory + +\family typewriter +examples +\family default +). + To run +\series bold +ac++ +\series default + on these examples you can simply type +\series bold +make test +\series default +. + The transformed source code of each example will be stored under +\series bold +examples/-out +\series default +. + To compile and run a single example simply change to the output directory + and type +\series bold +make +\series default +. + To compile and run all examples at once you can also type +\series bold +make testrun +\series default + from the main directory. +\layout Section + +Quick Reference +\layout Subsection + +ac++: Command Line Options +\layout Standard + +The main AspectC++ binary is +\series bold +ac++ +\series default +. + It has the command line options listed in table +\begin_inset LatexCommand \ref{tab:ac++-command-line} + +\end_inset + +. +\layout Standard + + +\begin_inset Float table +placement H +wide false +collapsed true + +\layout Standard + + +\begin_inset Tabular + + + + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +-p +\end_inset + + +\begin_inset Text + +\layout Standard + +mandatory +\end_inset + + +\begin_inset Text + +\layout Standard + +This option specifies the input directory. + It denotes the root directory that contains the C++ input files (in both + modes) and aspect definitions (dir mode only). + +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +-d +\end_inset + + +\begin_inset Text + +\layout Standard + +mandatory (dir mode) +\end_inset + + +\begin_inset Text + +\layout Standard + +This option specifies the directory where the manipulated files will be + stored. + It implicitly defines the directory mode. +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +-v +\end_inset + + +\begin_inset Text + +\layout Standard + +optional +\end_inset + + +\begin_inset Text + +\layout Standard + +This option specifies the verbosity level. + Values from 0 to 9 can be used here. + A higher number produces a more detailed output. + +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +-I +\end_inset + + +\begin_inset Text + +\layout Standard + +optional +\end_inset + + +\begin_inset Text + +\layout Standard + +This option specifies additional include directories. + It can be given multiple times. + +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +-D +\end_inset + + +\begin_inset Text + +\layout Standard + +optional +\end_inset + + +\begin_inset Text + +\layout Standard + +This option can be used to define additional preprocessor macros. + It can be given multiple times. +\end_inset + + + + +\end_inset + + +\layout Caption + + +\series bold + +\begin_inset LatexCommand \label{tab:ac++-command-line} + +\end_inset + +ac++ +\series default + command line options +\end_inset + + +\layout Quote + + +\series bold +Important: +\series default + If you use include files that lie inside the +\family typewriter +input-dir +\family default + tree you have to specify the root directory for those include files with + the +\family typewriter +-I +\family default + option. + This is necessary because +\series bold +ac++ +\series default + might manipulate the contents of these header files and otherwise would + translate the include path to point to the original and not to the manipulated + version. + +\layout Subsubsection* + +Example 1. + Common ac++ invocation (directory mode) +\layout Standard + +Suppose you have a C++ project in the directory +\family typewriter +Project +\family default + using include files from +\family typewriter +Project/include +\family default + and want a detailed process report, then you would invoke the +\series bold +ac++ +\series default + in directory mode like: +\layout LyX-Code + + +\family typewriter +ac++ -p Project -d +\family default + +\family typewriter +Project-out -I +\family default + +\family typewriter +Project/include -v9 +\layout Subsubsection* + +Example 2. + Common ac++ invocation (single file mode) +\layout Standard + +Suppose you have two files containing C++ code ( +\family typewriter +foo.cc +\family default +, +\family typewriter +bar.cc +\family default +) in the current directory using include files from the +\family typewriter +include +\family default + subdirectory, the aspect code is in +\family typewriter +important.ah +\family default +. + Generated and manipulated files should be stored in directory +\family typewriter +../generated +\family default +. + The transformation requires three invocations of +\series bold +ac++ +\series default +: +\layout LyX-Code + + +\family typewriter +ac++ -p . + -c foo.cc -o ../generated/foo.cc -a important.ah -I include +\family default + +\newline + +\family typewriter +ac++ -p . + -c bar.cc -o ../generated/foo.cc -a important.ah -I include +\family default + +\newline + +\family typewriter +ac++ -p . + -g -a important.ah -I include +\layout Subsection + +Tutorial: Writing Simple Aspects +\layout Standard + +Writing aspects works very similar to writing C++ class definitions. + They can be placed in separate include files (extension +\family typewriter +.ah +\family default +) or together with a class implementation. + The first method should be preferred to support a later splitting into + an aspect declaration and an aspect definition file. + Include files used for aspect definitions should be protected agains multiple + inclusion like any other include file. + Example 3 shows how to achieve this. +\layout Subsubsection* + +Example 3. + Tutorial 01: +\layout LyX-Code + +#ifndef __Tutorial_01_ah +\newline +#define __Tutorial_01_ah +\newline + +\newline +aspect Tutorial01 { +\newline + // aspect code +\newline +}; +\newline + +\newline +#endif // __Tutorial_01_ah +\layout Subsubsection + +Syntax Overview +\layout Standard + +The AspectC++ syntax is an extension to the syntax defined in the ANSI C++ + standard. + It adds three new keywords to the C++ language: +\family typewriter +aspect +\family default +, +\family typewriter +advice +\family default +, and +\family typewriter +pointcut +\family default +. +\layout Subsubsection* + + +\family typewriter +aspect +\family default + Declaration +\layout Standard + +The basic structure of an aspect declaration is exactly the same as a normal + C++ class definition, except for the keyword +\family typewriter +aspect +\family default +. + According to that aspects can have attributes and methods or can inherit + from classes or other aspects. +\layout Subsubsection* + +Example 4. + Tutorial 02: +\layout LyX-Code + +#ifndef __Tutorial_02_ah +\newline +#define __Tutorial_02_ah +\newline + +\newline +aspect Tutorial02 : public BaseClassOrAspect { +\newline + // counter to store the number +\newline + // of activations of this aspect +\layout LyX-Code + + int m_countRuns; +\newline + +\newline +public: +\newline + Tutorial02() : m_countRuns(0) {} +\newline + +\newline + int runs() const { return m_countRuns; } +\newline +}; +\newline + +\newline +#endif // __Tutorial_02_ah +\layout Subsubsection* + +advice Declaration +\layout Standard + +An advice declaration is used either to specify code that should run when + the join points specified by a pointcut expression are reached or to introduce + a new method, attribute, or type to all join points specified by a pointcut + expression. + +\layout Standard + +The keyword +\family typewriter +advice +\family default + is followed by a pointcut expression describing all join points where the + advice should be applied. + The actual advice follows the colon. +\layout Standard + +The simple aspect in example 5 specifies all main functions with an arbitrary + list of parameters and any return type as target of the aspect. + The special advice declaration +\family typewriter +before +\family default + causes the following advice code to be executed before the code of the + matched function. +\layout Subsubsection* + +Example 5. + A simple aspect modifying a program's main function: +\layout LyX-Code + +#ifndef __Tutorial_03_ah +\newline +#define __Tutorial_03_ah +\newline + +\newline +#include +\newline + +\newline +aspect Tutorial03 { +\newline + advice "% main(...)" : before() { +\newline + printf("Aspects first! +\backslash +n"); +\newline + } +\newline +}; +\newline + +\newline +#endif // __Tutorial_03_ah +\layout Subsubsection + +Match Expressions +\layout Standard + + +\begin_inset Float table +placement H +wide false +collapsed true + +\layout Standard + + +\begin_inset Tabular + + + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +int +\end_inset + + +\begin_inset Text + +\layout Standard + +matches the built-in scalar type +\family typewriter +int +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +Chain +\end_inset + + +\begin_inset Text + +\layout Standard + +matches the class, struct or union +\family typewriter +Chain +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +Memory% +\end_inset + + +\begin_inset Text + +\layout Standard + +matches all classes, structs or unions having a name starting with +\family typewriter +Memory +\end_inset + + + + +\end_inset + + +\layout Caption + + +\begin_inset LatexCommand \label{tab:Examples-matching-types} + +\end_inset + +Examples for match expressions matching types +\end_inset + + +\layout Standard + + +\begin_inset Float table +placement H +wide false +collapsed true + +\layout Standard + + +\begin_inset Tabular + + + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +Chain *Chain::next +\end_inset + + +\begin_inset Text + +\layout Standard + +matches the attribute +\family typewriter +next +\family default + of the class or struct +\family typewriter +Chain +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +% State::% +\end_inset + + +\begin_inset Text + +\layout Standard + +matches all attributes of any type of the class or struct +\family typewriter +State +\end_inset + + + + +\end_inset + + +\layout Caption + + +\begin_inset LatexCommand \label{tab:Examples-matching-attributes} + +\end_inset + +Examples for match expressions matching attributes +\end_inset + + +\layout Standard + + +\begin_inset Float table +placement H +wide false +collapsed true + +\layout Standard + + +\begin_inset Tabular + + + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +void reset() +\end_inset + + +\begin_inset Text + +\layout Standard + +matches the function +\family typewriter +reset +\family default + having no return value and no parameters +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +int main(int, char**) +\end_inset + + +\begin_inset Text + +\layout Standard + +matches the function having exact the given signature +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +% printf(...) +\end_inset + + +\begin_inset Text + +\layout Standard + +matches any function with the name +\family typewriter +printf +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +void %(int, %) +\end_inset + + +\begin_inset Text + +\layout Standard + +matches functions with any name, taking an +\family typewriter +int +\family default + as the first argument, and having a second argument of any type +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +void %::clear(...) +\end_inset + + +\begin_inset Text + +\layout Standard + +matches any method +\family typewriter +clear +\family default + of any class +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +% Mode::get%() +\end_inset + + +\begin_inset Text + +\layout Standard + +matches all methods of class +\family typewriter +Mode +\family default + whose name start with +\family typewriter +get +\family default +, having any return type and no parameters +\end_inset + + + + +\end_inset + + +\layout Caption + + +\begin_inset LatexCommand \label{tab:Examples-matching-methods} + +\end_inset + +Examples for match expressions matching methods +\end_inset + + +\layout Subsubsection + +Pointcut functions +\layout Standard + + +\begin_inset Float table +placement H +wide false +collapsed true + +\layout Standard + + +\begin_inset Tabular + + + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +call(pointcut) +\end_inset + + +\begin_inset Text + +\layout Standard + + +\family typewriter +call +\family default + filters all join points from the pointcut that are method calls +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +execution(pointcut) +\end_inset + + +\begin_inset Text + +\layout Standard + + +\family typewriter +execution +\family default + filters all join points referring to method implementations (the execution + of the method body) +\end_inset + + + + +\end_inset + + +\layout Caption + + +\begin_inset LatexCommand \label{tab:Pointcut-types} + +\end_inset + +Pointcut functions: methods +\end_inset + + +\layout Standard + + +\begin_inset Float table +placement H +wide false +collapsed true + +\layout Standard + + +\begin_inset Tabular + + + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +classes(pointcut) +\end_inset + + +\begin_inset Text + +\layout Standard + + +\family typewriter +classes +\family default + delivers only the classes, structs and unions from a pointcut +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +derived(pointcut) +\end_inset + + +\begin_inset Text + +\layout Standard + + +\family typewriter +derived +\family default + delivers all types in the pointcut and all classes derived from them +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +base(pointcut) +\end_inset + + +\begin_inset Text + +\layout Standard + + +\family typewriter +base +\family default + can be used to find all base types of classes in the pointcut +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +instanceof(pointcut) +\end_inset + + +\begin_inset Text + +\layout Standard + + +\family typewriter +instanceof +\family default + can be used to locate objects of certain types +\end_inset + + + + +\end_inset + + +\layout Caption + + +\begin_inset LatexCommand \label{tab:Pointcut-types} + +\end_inset + +Pointcut functions: types +\end_inset + + +\layout Standard + + +\begin_inset Float table +placement H +wide false +collapsed true + +\layout Standard + + +\begin_inset Tabular + + + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +within(pointcut) +\end_inset + + +\begin_inset Text + +\layout Standard + + +\family typewriter +within +\family default + delivers all join points declared in methods of types in the pointcut +\end_inset + + + + +\end_inset + + +\layout Caption + + +\begin_inset LatexCommand \label{tab:Pointcut-scopes} + +\end_inset + +Pointcut functions: scopes +\end_inset + + +\layout Standard + + +\begin_inset Float table +placement H +wide false +collapsed true + +\layout Standard + + +\begin_inset Tabular + + + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +cflow(pointcut) +\end_inset + + +\begin_inset Text + +\layout Standard + + +\family typewriter +cflow +\family default + captures join points occuring in the dynamic execution context of join + points in the pointcut +\end_inset + + + + +\end_inset + + +\layout Caption + + +\begin_inset LatexCommand \label{tab:Pointcut-control} + +\end_inset + +Pointcut functions: control flow +\end_inset + + +\layout Standard + + +\begin_inset Float table +placement H +wide false +collapsed true + +\layout Standard + + +\begin_inset Tabular + + + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +that(type pattern) +\end_inset + + +\begin_inset Text + +\layout Standard + + +\family typewriter +that +\family default + returns all join points where the current C++ +\family typewriter +this +\family default + pointer refers to an object which is an instance of the type described + by the type pattern +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +target(type pattern) +\end_inset + + +\begin_inset Text + +\layout Standard + + +\family typewriter +target +\family default + returns all join points where the target object of a call is an instance + of a type in the type pattern +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +args(type pattern, ...) +\end_inset + + +\begin_inset Text + +\layout Standard + + +\family typewriter +args +\family default + receives a list of type patterns and filters all methods or attributes + with a matching signature +\end_inset + + + + +\end_inset + + +\layout Caption + + +\begin_inset LatexCommand \label{tab:Pointcut-context} + +\end_inset + +Pointcut functions: context +\end_inset + + +\layout Subsection + + +\family typewriter +ThisJoinPoint +\family default +-API +\layout Standard + + +\begin_inset Float table +placement H +wide false +collapsed true + +\layout Standard + + +\begin_inset Tabular + + + + + + +\begin_inset Text + +\layout Standard + + +\series bold +Type +\end_inset + + +\begin_inset Text + +\layout Standard + + +\series bold +Description +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +Result +\end_inset + + +\begin_inset Text + +\layout Standard + +result type of a function +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +That +\end_inset + + +\begin_inset Text + +\layout Standard + +object type (object initiating a call) +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +Target +\end_inset + + +\begin_inset Text + +\layout Standard + +target object type (target object of a call) +\end_inset + + + + +\end_inset + + +\layout Caption + + +\begin_inset LatexCommand \label{tab:type-definitions} + +\end_inset + + +\family typewriter +ThisJoinPoint +\family default +-API: type definitions +\end_inset + + +\layout Standard + + +\begin_inset Float table +placement H +wide false +collapsed true + +\layout Standard + + +\begin_inset Tabular + + + + + + +\begin_inset Text + +\layout Standard + + +\series bold +Function +\end_inset + + +\begin_inset Text + +\layout Standard + + +\series bold +Description +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +AC::Type type() +\end_inset + + +\begin_inset Text + +\layout Standard + +returns the encoded type for the join point conforming with the C++ ABI + V3 specification +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +int args() +\end_inset + + +\begin_inset Text + +\layout Standard + +returns the number of arguments of a method for call and execution join + points +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +AC::Type argtype(int number) +\end_inset + + +\begin_inset Text + +\layout Standard + +returns the encoded type of an argument conforming with the C++ ABI V3 specifica +tion +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +const char *signature() +\end_inset + + +\begin_inset Text + +\layout Standard + +gives a textual description of the join point (method name, class name, + ...) +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +unsigned int id() +\end_inset + + +\begin_inset Text + +\layout Standard + +returns a unique numeric identifier for this join point +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +AC::Type resulttype() +\end_inset + + +\begin_inset Text + +\layout Standard + +returns the encoded type of the result type conforming with the C++ ABI + V3 specification +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +AC::JPType jptype() +\end_inset + + +\begin_inset Text + +\layout Standard + +returns a unique identifier describing the type of the join point +\end_inset + + + + +\end_inset + + +\layout Caption + + +\begin_inset LatexCommand \label{tab:static-functions} + +\end_inset + + +\family typewriter +ThisJoinPoint +\family default +-API: static functions +\end_inset + + +\layout Standard + + +\begin_inset Float table +placement H +wide false +collapsed true + +\layout Standard + + +\begin_inset Tabular + + + + + + +\begin_inset Text + +\layout Standard + + +\series bold +Method +\end_inset + + +\begin_inset Text + +\layout Standard + + +\series bold +Description +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +void *arg(int number) +\end_inset + + +\begin_inset Text + +\layout Standard + +returns a pointer to the memory position holding the argument value with + index +\family typewriter +number +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +Result *result() +\end_inset + + +\begin_inset Text + +\layout Standard + +returns a pointer to the memory location designated for the result value + or 0 if the function has no result value +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +That *that() +\end_inset + + +\begin_inset Text + +\layout Standard + +returns a pointer to the object initiating a call or 0 if it is a static + method or a global function +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +Target *target() +\end_inset + + +\begin_inset Text + +\layout Standard + +returns a pointer to the object that is the target of a call or 0 of it + is a static method or a global function +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family typewriter +ACAction &action() +\end_inset + + +\begin_inset Text + +\layout Standard + +returns the runtime action object containing the execution environment to + execute ( +\family typewriter +trigger() +\family default +) the original functionality encapsulated by an around advice +\end_inset + + + + +\end_inset + + +\layout Caption + + +\begin_inset LatexCommand \label{tab:non-static-functions} + +\end_inset + + +\family typewriter +ThisJoinPoint +\family default +-API: non-static functions +\end_inset + + +\the_end diff --git a/AspectC++/doc/QuickRef/ac++quickref.lyx b/AspectC++/doc/QuickRef/ac++quickref.lyx new file mode 100644 index 0000000..a4c8093 --- /dev/null +++ b/AspectC++/doc/QuickRef/ac++quickref.lyx @@ -0,0 +1,5288 @@ +#LyX 2.2 created this file. For more info see http://www.lyx.org/ +\lyxformat 508 +\begin_document +\begin_header +\save_transient_properties true +\origin unavailable +\textclass article +\begin_preamble + +%% multi column support +\usepackage{multicol} + +%% width of vertical lines between columns +\setlength{\columnseprule}{0.5pt} + +%% separation between columns +\setlength{\columnsep}{0.5cm} + +%% 7 mm space before grammar rules +\def\ruleind{\hspace{14pt}} + +%% special footnote symbols +\renewcommand{\thefootnote}{\fnsymbol{footnote}} + +%% space between description lines halved +\def\myskip{10pt} +\renewenvironment{description} + {\list{}{ + \labelwidth\z@ \itemindent-\leftmargin + \addtolength\itemindent{\myskip} + \let\makelabel\descriptionlabel} + \itemsep=-4pt\leftskip-\myskip}% + {\endlist} + +%% horizontal line over section name +%\renewcommand\section{% +% {\vspace*{\medskipamount}\hrule height 2pt}% +% {\vspace*{-10pt}}% +% \@startsection {section}{1}{\z@}% +% {-3.5ex \@plus -1ex \@minus -.2ex}% +% {2.3ex \@plus.2ex}% +% {\normalfont\Large\bfseries}} + +%% less vertical space before subsubsections +\renewcommand\subsubsection{% + {\vspace*{-15pt}}% + \@startsection{subsubsection}{3}{\z@}% + {-3.25ex\@plus -1ex \@minus -.2ex}% + {1.5ex \@plus .2ex}% + {\normalfont\normalsize\bfseries}} +\end_preamble +\use_default_options false +\maintain_unincluded_children false +\language english +\language_package default +\inputencoding auto +\fontencoding global +\font_roman "times" "default" +\font_sans "helvet" "default" +\font_typewriter "courier" "default" +\font_math "auto" "auto" +\font_default_family default +\use_non_tex_fonts false +\font_sc false +\font_osf false +\font_sf_scale 100 100 +\font_tt_scale 100 100 +\graphics default +\default_output_format default +\output_sync 0 +\bibtex_command default +\index_command default +\paperfontsize 10 +\spacing other 0.90000000000000002 +\use_hyperref false +\papersize a4paper +\use_geometry true +\use_package amsmath 1 +\use_package amssymb 1 +\use_package cancel 1 +\use_package esint 0 +\use_package mathdots 1 +\use_package mathtools 1 +\use_package mhchem 1 +\use_package stackrel 1 +\use_package stmaryrd 1 +\use_package undertilde 1 +\cite_engine basic +\cite_engine_type default +\biblio_style plain +\use_bibtopic false +\use_indices false +\paperorientation landscape +\suppress_date false +\justification true +\use_refstyle 0 +\index Index +\shortcut idx +\color #008000 +\end_index +\leftmargin 0.5cm +\topmargin 0.5cm +\rightmargin 0.5cm +\bottommargin 0.5cm +\secnumdepth 3 +\tocdepth 3 +\paragraph_separation indent +\paragraph_indentation default +\quotes_language english +\papercolumns 1 +\papersides 2 +\paperpagestyle empty +\tracking_changes false +\output_changes false +\html_math_output 0 +\html_css_as_file 0 +\html_be_strict false +\end_header + +\begin_body + +\begin_layout Standard +\noindent +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +begin{multicols*}{3} +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent + +\series bold +\size huge +\emph on +AspectC++ Quick Reference +\end_layout + +\begin_layout Subsection* +\noindent + +\family sans +Concepts +\end_layout + +\begin_layout Standard +\noindent + +\size small +\emph on +Aspects +\emph default + are modular implementations of crosscutting concerns. + They can affect +\emph on +join points +\emph default + in the component code, e.g. + class definitions, or in the dynamic control flow, e.g. + function calls, by +\emph on +advice +\emph default +. + A set of related join points is called +\emph on +pointcut +\emph default + and defined by a +\emph on +pointcut expression +\emph default +. +\end_layout + +\begin_layout Subsection* + +\family sans +Aspects +\end_layout + +\begin_layout Standard +\noindent + +\size small +Aspects extend the concept of C++ classes. + They may define ordinary class members as well as +\emph on +advice +\emph default +. +\end_layout + +\begin_layout Description + +\family sans +\size small +aspect +\begin_inset space ~ +\end_inset + + +\series medium +\emph on +A +\series default +\emph default + +\begin_inset space ~ +\end_inset + +: +\begin_inset space ~ +\end_inset + + +\series medium +\emph on +public +\begin_inset space ~ +\end_inset + +B +\series default +\emph default + +\begin_inset space ~ +\end_inset + +{ +\begin_inset space ~ +\end_inset + +... +\begin_inset space ~ +\end_inset + +}; +\family default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +defines the aspect +\emph on +A +\emph default +, which inherits from class or aspect +\emph on +B +\end_layout + +\begin_layout Subsection* + +\family sans +Slices +\end_layout + +\begin_layout Standard + +\size small +A slice is a fragment of a C++ element like a class. + It may be used by introduction +\emph on +advice +\emph default + to implemented static extensions of the program. +\end_layout + +\begin_layout Description + +\family sans +\size small +slice +\begin_inset space ~ +\end_inset + +class +\begin_inset space ~ +\end_inset + + +\emph on +ASlice +\emph default + +\begin_inset space ~ +\end_inset + +{ +\begin_inset space ~ +\end_inset + +... +\begin_inset space ~ +\end_inset + +void +\begin_inset space ~ +\end_inset + + +\emph on +f +\emph default +(); +\begin_inset space ~ +\end_inset + +... +\begin_inset space ~ +\end_inset + +}; +\begin_inset space ~ +\end_inset + + +\family default + +\begin_inset Newline newline +\end_inset + +defines a class slice called +\emph on +ASlice +\end_layout + +\begin_layout Description + +\family sans +\size small +slice +\begin_inset space ~ +\end_inset + +void +\begin_inset space ~ +\end_inset + + +\emph on +ASlice::f +\emph default +() +\begin_inset space ~ +\end_inset + +{ +\begin_inset space ~ +\end_inset + +... +\begin_inset space ~ +\end_inset + +} +\begin_inset space ~ +\end_inset + + +\family default + +\begin_inset Newline newline +\end_inset + +defines a non-inline member function f() of slice ASlice +\end_layout + +\begin_layout Subsection* + +\family sans +Advice +\end_layout + +\begin_layout Standard + +\size small +An advice declaration specifies +\emph on +how +\emph default + an aspect affects a set of join points. +\end_layout + +\begin_layout Description + +\family sans +\size small +advice +\series medium + +\begin_inset space ~ +\end_inset + + +\emph on +pointcut +\emph default + +\begin_inset space ~ +\end_inset + +: +\begin_inset space ~ +\end_inset + + +\series default +around +\series medium +(...) +\begin_inset space ~ +\end_inset + +{...} +\family default +\series default + +\family sans + +\begin_inset space ~ +\end_inset + + +\family default + +\begin_inset Newline newline +\end_inset + +the advice code is executed in place of the join points in the pointcut +\end_layout + +\begin_layout Description + +\family sans +\size small +advice +\series medium + +\begin_inset space ~ +\end_inset + + +\emph on +pointcut +\emph default + +\begin_inset space ~ +\end_inset + +: +\begin_inset space ~ +\end_inset + + +\series default +before +\series medium +/ +\series default +after +\series medium +(...) +\begin_inset space ~ +\end_inset + +{...} +\family default +\series default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +the advice code is executed before/after the join points in the pointcut +\end_layout + +\begin_layout Description + +\family sans +\size small +advice +\series medium + +\begin_inset space ~ +\end_inset + + +\emph on +pointcut +\emph default + +\begin_inset space ~ +\end_inset + +: +\begin_inset space ~ +\end_inset + + +\series default +order +\series medium +( +\emph on +high +\emph default +, +\family default +\series default + +\family sans +... +\emph on +low +\emph default +) +\series bold +; +\family default +\series default + +\begin_inset Newline newline +\end_inset + + +\emph on +high +\emph default + and +\emph on +low +\emph default + are pointcuts, which describe sets of aspects. + Aspects on the left side of the argument list always have a higher precedence + than aspects on the right hand side at the join points, where the order + declaration is applied. +\end_layout + +\begin_layout Description + +\family sans +\size small +advice +\series medium + +\begin_inset space ~ +\end_inset + + +\emph on +pointcut +\emph default + +\begin_inset space ~ +\end_inset + +: +\begin_inset space ~ +\end_inset + + +\series default +slice +\series medium + +\begin_inset space ~ +\end_inset + + +\series default +class +\series medium + +\begin_inset space ~ +\end_inset + +: +\begin_inset space ~ +\end_inset + + +\series default +public +\series medium + +\begin_inset space ~ +\end_inset + + +\emph on +Base +\emph default + +\begin_inset space ~ +\end_inset + +{...} +\family default +\series default + +\family sans + +\begin_inset space ~ +\end_inset + + +\family default + +\begin_inset Newline newline +\end_inset + +introduces a new base class +\emph on +Base +\emph default + and members into the target classes matched by +\emph on +pointcut +\emph default +. +\end_layout + +\begin_layout Description + +\family sans +\size small +advice +\series medium + +\begin_inset space ~ +\end_inset + + +\emph on +pointcut +\emph default + +\begin_inset space ~ +\end_inset + +: +\begin_inset space ~ +\end_inset + + +\series default +slice +\series medium + +\begin_inset space ~ +\end_inset + + +\emph on +ASlice +\begin_inset space ~ +\end_inset + + +\series default +\emph default +; +\begin_inset space ~ +\end_inset + + +\family default + +\begin_inset Newline newline +\end_inset + +introduces the slice +\emph on +ASlice +\emph default + into the target classes matched by +\emph on +pointcut +\emph default +. +\end_layout + +\begin_layout Subsection* + +\family sans +Match Expressions +\end_layout + +\begin_layout Standard + +\size small +\emph on +Match expressions +\emph default + are primitive pointcut expressions. + They filter program entities based on their signature. +\begin_inset VSpace 15pt* +\end_inset + + +\end_layout + +\begin_layout Subsubsection* + +\family sans +\emph on +Type Matching +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +\size small +"int" +\family default +\series default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +matches the C++ built-in scalar type +\family typewriter +int +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +\size small +"% +\begin_inset space ~ +\end_inset + +*" +\family default +\series default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +matches any pointer type +\end_layout + +\begin_layout Subsubsection* + +\family sans +\emph on +Namespace and Class Matching +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +\size small +"Chain" +\family default +\series default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +matches the class, struct or union +\emph on +Chain +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +\size small +"Memory%" +\family default +\series default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +matches any class, struct or union whose name starts with +\begin_inset Quotes eld +\end_inset + +Memory +\begin_inset Quotes erd +\end_inset + + +\end_layout + +\begin_layout Subsubsection* + +\family sans +\emph on +Function Matching +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +\size small +"void +\family default +\series default + +\family typewriter +reset()" +\family default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +matches the function +\emph on +reset +\emph default + having no parameters and returning +\family typewriter +void +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +\size small +"% +\family default +\series default + +\family typewriter +printf(...)" +\family default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +matches the function +\emph on +printf +\emph default + having any number of parameters and returning any type +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +\size small +"% +\family default +\series default + +\family typewriter +...::%(...)" +\family default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +matches any function, operator function, or type conversion function (in + any class or namespace) +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +\size small +"% +\family default +\series default + +\family typewriter +...::Service::%(...) const" +\family default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +matches any const member-function of the class +\family typewriter +Service +\family default + defined in any scope +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +\size small +"% +\family default +\series default + +\family typewriter +...::operator %(...)" +\family default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +matches any type conversion function +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +\size small +"virtual % +\family default +\series default + +\family typewriter +C::%(...)" +\family default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +matches any virtual member function of +\family typewriter +C +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +\size small +"static % +\series default +...::%(...)" +\family default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +matches any static member or non-member function +\end_layout + +\begin_layout Subsubsection* + +\family sans +\emph on +Variable Matching +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +\size small +"int +\family default +\series default + +\family typewriter +counter" +\family default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +matches the variable +\emph on +counter +\emph default + of type +\family typewriter +int +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +\size small +"% +\family default +\series default + +\family typewriter +guard" +\family default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +matches the global variable +\emph on +guard +\emph default + of any type +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +\size small +"% +\family default +\series default + +\family typewriter +...::%" +\family default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +matches any variable (in any class or namespace) +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +\size small +"static +\series default +% ...::%" +\family default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +matches any static member or non-member variable +\end_layout + +\begin_layout Subsubsection* + +\family sans +\emph on +Template Matching +\family default +\series medium +\emph default + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +footnotemark[2] +\end_layout + +\end_inset + + +\series default + +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +\size small +"std::set<...>" +\family default +\series default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +matches all template instances of the class +\emph on +std::set +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +\size small +"std::set" +\family default +\series default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +matches only the template instance +\emph on +std::set +\emph default + +\end_layout + +\begin_layout Description + +\family typewriter +\series medium +\size small +"% +\family default +\series default + +\family typewriter +...::%<...>::%(...)" +\family default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +matches any member function from any template class instance in any scope +\end_layout + +\begin_layout Subsection* + +\family sans +Predefined Pointcut Functions +\end_layout + +\begin_layout Standard + +\size small +Predefined pointcut functions are used to filter, map, join, or intersect + pointcuts. +\begin_inset VSpace 15pt* +\end_inset + + +\end_layout + +\begin_layout Subsubsection* + +\family sans +\emph on +Functions / Variables +\end_layout + +\begin_layout Description + +\family sans +\size small +call +\series medium +( +\emph on +pointcut +\emph default +) +\family default +\series default + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\size scriptsize +N +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\begin_inset Formula $_{C}$ +\end_inset + + +\size small + +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +footnotemark[9] +\end_layout + +\end_inset + + +\begin_inset Newline newline +\end_inset + +provides all join points where a named and user provided entity in the +\emph on +pointcut +\emph default + is called. +\end_layout + +\begin_layout Description + +\family sans +\size small +builtin +\series medium +( +\emph on +pointcut +\emph default +) +\family default +\series default + +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +footnotemark[3] +\end_layout + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\size scriptsize +N +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\begin_inset Formula $_{B}$ +\end_inset + + +\size small + +\begin_inset Newline newline +\end_inset + +provides all join points where a named built-in operator in the +\emph on +pointcut +\emph default + is called. +\end_layout + +\begin_layout Description + +\family sans +\size small +execution +\series medium +( +\emph on +pointcut +\emph default +) +\family default +\series default + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\size scriptsize +N +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\begin_inset Formula $_{E}$ +\end_inset + + +\size small + +\begin_inset Newline newline +\end_inset + +provides all join points referring to the implementation of a named entity + in the +\emph on +pointcut +\emph default +. +\end_layout + +\begin_layout Description + +\family sans +\size small +construction +\series medium +( +\emph on +pointcut +\emph default +) +\family default +\series default + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\size scriptsize +N +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\begin_inset Formula $_{Cons}$ +\end_inset + + +\size small + +\begin_inset Newline newline +\end_inset + +all join points where an instance of the given class(es) is constructed. +\end_layout + +\begin_layout Description + +\family sans +\size small +destruction +\series medium +( +\emph on +pointcut +\emph default +) +\family default +\series default + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\size scriptsize +N +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\begin_inset Formula $_{Des}$ +\end_inset + + +\size small + +\begin_inset Newline newline +\end_inset + +all join points where an instance of the given class(es) is destructed. +\end_layout + +\begin_layout Description + +\family sans +\size small +get +\series medium +( +\emph on +pointcut +\emph default +) +\family default +\series default + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\size scriptsize +N +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\begin_inset Formula $_{G}$ +\end_inset + + +\size small + +\begin_inset Newline newline +\end_inset + +provides all join points where a global variable or data member in the +\emph on +pointcut +\emph default + is read. + +\end_layout + +\begin_layout Description + +\family sans +\size small +set +\series medium +( +\emph on +pointcut +\emph default +) +\family default +\series default + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\size scriptsize +N +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\begin_inset Formula $_{S}$ +\end_inset + + +\size small + +\begin_inset Newline newline +\end_inset + +provides all join points where a global variable or data member in the +\emph on +pointcut +\emph default + is written. +\end_layout + +\begin_layout Description + +\family sans +\size small +ref +\series medium +( +\emph on +pointcut +\emph default +) +\family default +\series default + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\size scriptsize +N +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\begin_inset Formula $_{R}$ +\end_inset + + +\size small + +\begin_inset Newline newline +\end_inset + +provides all join points where a reference (reference type or pointer) to + a global variable or data member in the +\emph on +pointcut +\emph default + is created. +\end_layout + +\begin_layout Standard + +\size small +\emph on +pointcut +\emph default + may contain function, variable, namespace or class names. + A namespace or class name is equivalent to the names of all functions and + variables defined within its scope combined with the +\series bold +|| +\series default + operator (see below). +\begin_inset VSpace 8pt +\end_inset + + +\end_layout + +\begin_layout Subsubsection* + +\family sans +\emph on +Control Flow +\end_layout + +\begin_layout Description + +\family sans +\size small +cflow +\series medium +( +\emph on +pointcut +\emph default +) +\family default +\series default + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\size scriptsize +C +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\size small + +\begin_inset Newline newline +\end_inset + +captures join points occuring in the dynamic execution context of join points + in the +\emph on +pointcut +\emph default +. + The argument +\emph on +pointcut +\emph default + is forbidden to contain context variables or join points with runtime condition +s (currently cflow, that, or target). +\end_layout + +\begin_layout Subsubsection* + +\family sans +\emph on +Types +\end_layout + +\begin_layout Description + +\family sans +\size small +base +\series medium +( +\emph on +pointcut +\emph default +) +\family default +\series default + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\size scriptsize +N +\begin_inset Formula $\rightarrow$ +\end_inset + +N +\begin_inset Formula $_{C,F}$ +\end_inset + + +\size small + +\begin_inset Newline newline +\end_inset + +returns all base classes resp. +\begin_inset space ~ +\end_inset + +redefined functions of classes in the +\emph on +pointcut +\emph default + +\end_layout + +\begin_layout Description + +\family sans +\size small +derived +\series medium +( +\emph on +pointcut +\emph default +) +\family default +\series default + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\size scriptsize +N +\begin_inset Formula $\rightarrow$ +\end_inset + +N +\begin_inset Formula $_{C,F}$ +\end_inset + + +\size small + +\begin_inset Newline newline +\end_inset + +returns all classes in the +\emph on +pointcut +\emph default + and all classes derived from them resp. +\begin_inset space ~ +\end_inset + +all redefined functions of derived classes +\end_layout + +\begin_layout Subsubsection* + +\family sans +\emph on +Scope +\end_layout + +\begin_layout Description + +\family sans +\size small +within +\series medium +( +\emph on +pointcut +\emph default +) +\family default +\series default + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\size scriptsize +N +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\size small + +\begin_inset Newline newline +\end_inset + +filters all join points that are within the functions or classes in the + +\emph on +pointcut +\end_layout + +\begin_layout Description + +\family sans +\size small +member +\series medium +( +\emph on +pointcut +\emph default +) +\family default +\series default + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\size scriptsize +N +\begin_inset Formula $\rightarrow$ +\end_inset + +N +\size small + +\begin_inset Newline newline +\end_inset + +maps the scopes given in +\emph on +pointcut +\emph default + to any contained named entities. + Thus a class name for example is mapped to all contained member functions, + variables and nested types. +\end_layout + +\begin_layout Subsubsection* + +\family sans +\emph on +Context +\end_layout + +\begin_layout Description + +\family sans +\size small +that +\series medium +( +\emph on +type +\begin_inset space ~ +\end_inset + +pattern +\emph default +) +\family default +\series default + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\size scriptsize +N +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\size small + +\begin_inset Newline newline +\end_inset + +returns all join points where the current C++ +\family typewriter +this +\family default + pointer refers to an object which is an instance of a type that is compatible + to the type described by the +\emph on +type pattern +\end_layout + +\begin_layout Description + +\family sans +\size small +target +\series medium +( +\emph on +type +\begin_inset space ~ +\end_inset + +pattern +\emph default +) +\family default +\series default + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\size scriptsize +N +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\size small + +\begin_inset Newline newline +\end_inset + +returns all join points where the target object of a call or other access + is an instance of a type that is compatible to the type described by the + +\emph on +type pattern +\end_layout + +\begin_layout Description + +\family sans +\size small +result +\series medium +( +\emph on +type +\begin_inset space ~ +\end_inset + +pattern +\emph default +) +\family default +\series default + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\size scriptsize +N +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\size small + +\begin_inset Newline newline +\end_inset + +returns all join points where the result object of a call/execution or other + access join point is an instance of a type described by the +\emph on +type pattern +\end_layout + +\begin_layout Description + +\family sans +\size small +args +\series medium +( +\emph on +type +\begin_inset space ~ +\end_inset + +pattern +\emph default +, +\begin_inset space ~ +\end_inset + +...) +\family default +\series default + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\size scriptsize +(N,...) +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\size small + +\begin_inset Newline newline +\end_inset + +a list of +\emph on +type patterns +\emph default + is used to provide all joinpoints with matching argument signatures +\end_layout + +\begin_layout Standard + +\size small +Instead of the +\emph on +type pattern +\emph default + it is possible here to pass the name of a +\series bold +context variable +\series default + to which the context information is bound. + In this case the type of the variable is used for the type matching. +\end_layout + +\begin_layout Standard +\begin_inset VSpace 15pt* +\end_inset + + +\end_layout + +\begin_layout Subsubsection* + +\family sans +\emph on +Algebraic Operators +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +pointcut +\series default +\emph default + +\begin_inset space ~ +\end_inset + +&& +\series medium +\emph on + +\begin_inset space ~ +\end_inset + +pointcut +\family default +\series default +\emph default + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\size scriptsize +(N,N) +\begin_inset Formula $\rightarrow$ +\end_inset + +N, (C,C) +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\size small + +\begin_inset Newline newline +\end_inset + +intersection of the join points in the +\emph on +pointcuts +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +pointcut +\series default +\emph default + +\begin_inset space ~ +\end_inset + +|| +\series medium +\emph on + +\begin_inset space ~ +\end_inset + +pointcut +\family default +\series default +\emph default + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\size scriptsize +(N,N) +\begin_inset Formula $\rightarrow$ +\end_inset + +N, (C,C) +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\size small + +\begin_inset Newline newline +\end_inset + +union of the join points in the +\emph on +pointcuts +\end_layout + +\begin_layout Description + +\family sans +\size small +! +\series medium +\emph on + +\begin_inset space ~ +\end_inset + +pointcut +\family default +\series default +\emph default + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\size scriptsize +N +\begin_inset Formula $\rightarrow$ +\end_inset + +N, C +\begin_inset Formula $\rightarrow$ +\end_inset + +C +\size small + +\begin_inset Newline newline +\end_inset + +exclusion of the join points in the +\emph on +pointcut +\end_layout + +\begin_layout Subsection* + +\family sans +Named Pointcuts and Attributes +\end_layout + +\begin_layout Standard +Pointcut expressions can also refer to user-defined pointcuts. +\end_layout + +\begin_layout Description + +\family sans +\size small +class +\series medium + +\begin_inset space ~ +\end_inset + + +\emph on +[[myns::myattr]] +\emph default + +\begin_inset space ~ +\end_inset + +C +\begin_inset space ~ +\end_inset + +{...} +\family default +\series default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +annotates class C with the attribute +\emph on +myattr +\emph default + from the namespace +\emph on +myns +\emph default +. +\end_layout + +\begin_layout Description + +\family sans +\size small +pointcut +\series medium + +\begin_inset space ~ +\end_inset + + +\emph on +mypct +\emph default +() +\begin_inset space ~ +\end_inset + += +\begin_inset space ~ +\end_inset + + +\begin_inset Quotes eld +\end_inset + +C +\begin_inset Quotes erd +\end_inset + +; +\family default +\series default + +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +defines a +\begin_inset Quotes eld +\end_inset + +named pointcut +\begin_inset Quotes erd +\end_inset + + +\emph on +my +\emph default +pct(), which represents the class +\begin_inset Quotes eld +\end_inset + +C +\begin_inset Quotes erd +\end_inset + + +\end_layout + +\begin_layout Description + +\family sans +\size small +attribute +\series medium + +\begin_inset space ~ +\end_inset + + +\emph on +myattr +\emph default +(); +\family default +\series default + // in +\emph on +myns +\emph default + +\begin_inset Newline newline +\end_inset + +declares a user-defined attribute +\emph on +myattr +\emph default +(), which also represents +\begin_inset Quotes eld +\end_inset + +C +\begin_inset Quotes erd +\end_inset + + +\end_layout + +\begin_layout Subsection* + +\family sans +JoinPoint-API for Advice Code +\end_layout + +\begin_layout Standard + +\size small +The JoinPoint-API is provided within every advice code body by the built-in + object +\series bold +tjp +\series default + of class +\series bold +JoinPoint +\series default +. +\begin_inset VSpace 15pt +\end_inset + + +\end_layout + +\begin_layout Subsubsection* + +\family sans +\emph on +Compile-time Types and Constants +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +That +\series default +\size scriptsize +\emph default + +\begin_inset space ~ +\end_inset + + +\family default +\size small + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\family sans +\size scriptsize +[type] +\family default +\size small + +\begin_inset Newline newline +\end_inset + +object type (object initiating a call or entity access) +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +Target +\family default +\series default +\emph default + +\family sans +\size scriptsize + +\begin_inset space ~ +\end_inset + + +\family default +\size small + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\family sans +\size scriptsize +[type] +\family default +\size small + +\begin_inset Newline newline +\end_inset + +target object type (target object of a call or entity access) +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +Entity +\family default +\series default +\emph default + +\family sans +\size scriptsize + +\begin_inset space ~ +\end_inset + + +\family default +\size small + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\family sans +\size scriptsize +[type] +\family default +\size small + +\begin_inset Newline newline +\end_inset + +type of the primary referenced entity (function or variable) +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +MemberPtr +\family default +\series default +\emph default + +\family sans +\size scriptsize + +\begin_inset space ~ +\end_inset + + +\family default +\size small + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\family sans +\size scriptsize +[type] +\family default +\size small + +\begin_inset Newline newline +\end_inset + +type of the member pointer for entity or +\begin_inset Quotes eld +\end_inset + +void * +\begin_inset Quotes erd +\end_inset + + for nonmembers. +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +Result +\family default +\series default +\emph default + +\family sans +\size scriptsize + +\begin_inset space ~ +\end_inset + + +\family default +\size small + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\family sans +\size scriptsize +[type] +\family default +\size small + +\begin_inset Newline newline +\end_inset + +type of the object, used to +\emph on +store +\emph default + the result of the join point +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +Res::Type, +\series default + Res::ReferredType +\size scriptsize +\emph default + +\begin_inset space ~ +\end_inset + + +\family default +\size small + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\family sans +\size scriptsize +[type] +\family default +\size small + +\begin_inset Newline newline +\end_inset + +result type of the affected function or entity access +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +Arg::Type, +\family default +\series default +\emph default + +\family sans +\emph on +Arg::ReferredType +\family default +\emph default + +\family sans +\size scriptsize + +\begin_inset space ~ +\end_inset + + +\family default +\size small + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\family sans +\size scriptsize +[type] +\family default +\size small + +\begin_inset Newline newline +\end_inset + +type of the +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +$i^{ +\backslash +,th}$ +\end_layout + +\end_inset + + argument of the affected join point (with +\begin_inset ERT +status open + +\begin_layout Plain Layout + +$0 +\backslash +leq i < ARGS$ +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +ARGS +\family default +\series default +\emph default + +\family sans +\size scriptsize + +\begin_inset space ~ +\end_inset + + +\family default +\size small + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\family sans +\size scriptsize +[const] +\family default +\size small + +\begin_inset Newline newline +\end_inset + +number of arguments +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +Array +\family default +\series default +\emph default + +\family sans +\size scriptsize + +\begin_inset space ~ +\end_inset + + +\family default +\size small + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\family sans +\size scriptsize +[type] +\family default +\size small + +\begin_inset Newline newline +\end_inset + +type of an accessed array +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +Dim::Idx, Dim::Size +\family default +\series default +\emph default + +\family sans +\size scriptsize + +\begin_inset space ~ +\end_inset + + +\family default +\size small + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\family sans +\size scriptsize +[type] +\family default +\size small +, +\family sans +\size scriptsize +[const] +\family default +\size small + +\begin_inset Newline newline +\end_inset + +type of used index and size of the +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +$i^{ +\backslash +,th}$ +\end_layout + +\end_inset + + dimension (with +\begin_inset ERT +status open + +\begin_layout Plain Layout + +$0 +\backslash +leq i < DIMS$ +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +DIMS +\family default +\series default +\emph default + +\family sans +\size scriptsize + +\begin_inset space ~ +\end_inset + + +\family default +\size small + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\family sans +\size scriptsize +[const] +\family default +\size small + +\begin_inset Newline newline +\end_inset + +number of dimensions of an accessed array or 0 otherwise +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +JPID +\family default +\series default +\emph default + +\family sans +\size scriptsize + +\begin_inset space ~ +\end_inset + + +\family default +\size small + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\family sans +\size scriptsize +[const] +\family default +\size small + +\begin_inset Newline newline +\end_inset + +unique numeric identifier for this join point +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +JPTYPE +\family default +\series default +\emph default + +\family sans +\size scriptsize + +\begin_inset space ~ +\end_inset + + +\family default +\size small + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\family sans +\size scriptsize +[const] +\family default +\size small + +\begin_inset Newline newline +\end_inset + +numeric identifier describing the type of this join point +\family sans + +\family default +( +\family sans +\emph on +AC::CALL +\family default +, +\family sans +AC::BUILTIN, AC::EXECUTION +\family default +\emph default +, +\family sans +\emph on +AC:: +\emph default +CONSTRUCTION +\family default +, +\family sans +\emph on +AC:: +\emph default +DESTRUCTION +\family default +, +\family sans +\emph on +AC::GET +\family default +\emph default +, +\family sans +\emph on +AC::SET +\family default +\emph default + or +\family sans +\emph on +AC::REF +\family default +\emph default +) +\end_layout + +\begin_layout Standard +\begin_inset VSpace 6pt* +\end_inset + + +\end_layout + +\begin_layout Subsubsection* + +\family sans +\emph on +Runtime Functions and State +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +static +\begin_inset space ~ +\end_inset + +const +\begin_inset space ~ +\end_inset + +char +\series default + +\begin_inset space ~ +\end_inset + + +\series medium +* +\series default +\emph default +signature +\series medium +() +\family default +\series default + +\size scriptsize + +\begin_inset space ~ +\end_inset + + +\size small + +\begin_inset Newline newline +\end_inset + +gives a textual description of the join point (type + name) +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +static +\begin_inset space ~ +\end_inset + +const +\begin_inset space ~ +\end_inset + +char +\series default + +\begin_inset space ~ +\end_inset + + +\series medium +* +\series default +\emph default +filename +\series medium +() +\family default +\series default + +\size scriptsize + +\begin_inset space ~ +\end_inset + + +\size small + +\begin_inset Newline newline +\end_inset + +returns the name of the file in which the joinpoint shadow is located +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +static +\begin_inset space ~ +\end_inset + +int +\series default + +\begin_inset space ~ +\end_inset + + +\emph default +line +\series medium +() +\family default +\series default + +\size scriptsize + +\begin_inset space ~ +\end_inset + + +\size small + +\begin_inset Newline newline +\end_inset + +the source code line number in which the joinpoint shadow is located +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +That +\begin_inset space ~ +\end_inset + +* +\series default +\emph default +that +\series medium +() +\family default +\series default + +\family sans +\size scriptsize + +\begin_inset space ~ +\end_inset + + +\family default +\size small + +\begin_inset Newline newline +\end_inset + +returns a pointer to the object initiating a call or 0 if it is a static + method or a global function +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +Target +\begin_inset space ~ +\end_inset + +* +\series default +\emph default +target +\series medium +() +\family default +\series default + +\family sans +\size scriptsize + +\begin_inset space ~ +\end_inset + + +\family default +\size small + +\begin_inset Newline newline +\end_inset + +returns a pointer to the object that is the target of a call or 0 if it + is a static method or a global function +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +Entity +\begin_inset space ~ +\end_inset + +* +\series default +\emph default +entity +\series medium +() +\family default +\series default + +\family sans +\size scriptsize + +\begin_inset space ~ +\end_inset + + +\family default +\size small + +\begin_inset Newline newline +\end_inset + +returns a pointer to the accessed entity (function or variable) or 0 for + member functions or builtin operators +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +MemberPtr +\begin_inset space ~ +\end_inset + + +\series default +\emph default +memberptr +\series medium +() +\family default +\series default + +\family sans +\size scriptsize + +\begin_inset space ~ +\end_inset + + +\family default +\size small + +\begin_inset Newline newline +\end_inset + +returns a member pointer to entity or 0 for nonmembers +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +Result +\emph default + +\begin_inset space ~ +\end_inset + + +\emph on +* +\series default +\emph default +result +\series medium +() +\family default +\series default + +\family sans +\size scriptsize + +\begin_inset space ~ +\end_inset + + +\family default +\size small + +\begin_inset Newline newline +\end_inset + +returns a typed pointer to the result value or 0 if there is none +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +Arg::ReferredType +\begin_inset space ~ +\end_inset + +* +\series default +\emph default +arg +\series medium +\emph on + +\emph default +() +\family default +\series default + +\family sans +\size scriptsize + +\begin_inset space ~ +\end_inset + + +\family default +\size small + +\begin_inset Newline newline +\end_inset + +returns a typed pointer to the +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +$i^{ +\backslash +,th}$ +\end_layout + +\end_inset + + argument value (with +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +$0 +\backslash +leq i < ARGS$ +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +void +\begin_inset space ~ +\end_inset + +* +\series default +\emph default +arg +\series medium +( +\emph on +int +\series default + +\begin_inset space ~ +\end_inset + + +\series medium +\emph default +i) +\family default +\series default + +\family sans +\size scriptsize + +\begin_inset space ~ +\end_inset + + +\family default +\size small + +\begin_inset Newline newline +\end_inset + +returns a pointer to the +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +$i^{ +\backslash +,th}$ +\end_layout + +\end_inset + + argument memory location +\emph on + +\emph default +( +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +$0 +\backslash +leq i < ARGS$ +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +void +\begin_inset space ~ +\end_inset + + +\series default +\emph default +proceed +\series medium +() +\family default +\series default + +\family sans +\size scriptsize + +\begin_inset space ~ +\end_inset + + +\family default +\size small + +\begin_inset Newline newline +\end_inset + +executes the original code in an around advice (should be called at most + once in around advice) +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +AC::Action +\begin_inset space ~ +\end_inset + +& +\series default +\emph default +action +\series medium +() +\family default +\series default + +\family sans +\size scriptsize + +\begin_inset space ~ +\end_inset + + +\family default +\size small + +\begin_inset Newline newline +\end_inset + +returns the runtime action object containing the execution environment to + execute ( +\emph on +trigger() +\emph default + ) the original code encapsulated by an around advice +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +Array +\begin_inset space ~ +\end_inset + +* +\series default +\emph default +array +\series medium +() +\family default +\series default + +\family sans +\size scriptsize + +\begin_inset space ~ +\end_inset + + +\family default +\size small + +\begin_inset Newline newline +\end_inset + +returns a typed pointer to the accessed array +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +Dim::Idx +\begin_inset space ~ +\end_inset + + +\series default +\emph default +idx +\series medium +\emph on + +\emph default +() +\family default +\series default + +\family sans +\size scriptsize + +\begin_inset space ~ +\end_inset + + +\family default +\size small + +\begin_inset Newline newline +\end_inset + +returns the value of the +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + +$i^{ +\backslash +,th}$ +\end_layout + +\end_inset + + used index +\family sans +\series medium +\emph on + +\begin_inset Note Note +status open + +\begin_layout Plain Layout + +\family sans +\series medium +\size small +\emph on +TODO?: int args() +\end_layout + +\begin_layout Plain Layout +returns the number of arguments +\end_layout + +\begin_layout Plain Layout + +\family sans +\series medium +\size small +\emph on +unsigned int id() +\end_layout + +\begin_layout Plain Layout +returns +\size small +the unique numeric identifier of the join point +\end_layout + +\begin_layout Plain Layout +... +\end_layout + +\end_inset + + +\family default +\series default +\size default +\emph default + +\begin_inset VSpace 6pt* +\end_inset + + +\end_layout + +\begin_layout Subsubsection* + +\family sans +\emph on +Runtime Type Information +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +static +\begin_inset space ~ +\end_inset + +AC::Type +\begin_inset space ~ +\end_inset + + +\series default +\emph default +resulttype +\series medium +() +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +static +\begin_inset space ~ +\end_inset + +AC::Type +\begin_inset space ~ +\end_inset + + +\series default +\emph default +argtype +\series medium +( +\emph on +int +\series default + +\begin_inset space ~ +\end_inset + + +\series medium +\emph default +i) +\family default +\series default + +\size scriptsize + +\begin_inset space ~ +\end_inset + + +\size small + +\begin_inset Newline newline +\end_inset + +return a C++ ABI V3 +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +footnotemark[8] +\end_layout + +\end_inset + + conforming string representation of the result type / argument type of + the affected function +\end_layout + +\begin_layout Subsection* + +\family sans +JoinPoint-API for Slices +\end_layout + +\begin_layout Standard + +\size small +The JoinPoint-API is provided within introduced slices by the built-in class + +\series bold +JoinPoint +\series default + (state of target class +\emph on +before +\emph default + introduction). +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +static +\begin_inset space ~ +\end_inset + +const +\begin_inset space ~ +\end_inset + +char +\series default + +\begin_inset space ~ +\end_inset + + +\series medium +* +\series default +\emph default +signature +\series medium +() +\family default +\series default + +\size scriptsize + +\begin_inset space ~ +\end_inset + + +\size small + +\begin_inset Newline newline +\end_inset + +returns the target class name as a string +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +That +\series default +\size scriptsize +\emph default + +\begin_inset space ~ +\end_inset + + +\family default +\size small + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\family sans +\size scriptsize +[type] +\family default +\size small + +\begin_inset Newline newline +\end_inset + +The (incomplete) target type of the introduction +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +BASECLASSES +\family default +\series default +\emph default + +\family sans +\size scriptsize + +\begin_inset space ~ +\end_inset + + +\family default +\size small + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\family sans +\size scriptsize +[const] +\family default +\size small + +\begin_inset Newline newline +\end_inset + +number of baseclasses of the target class +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +BaseClass::Type +\family default +\series default +\emph default + +\family sans +\size scriptsize + +\begin_inset space ~ +\end_inset + + +\family default +\size small + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\family sans +\size scriptsize +[type] +\family default +\size small + +\begin_inset Newline newline +\end_inset + +type of the +\begin_inset ERT +status open + +\begin_layout Plain Layout + +$I^{ +\backslash +,th}$ +\end_layout + +\end_inset + + baseclass +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +BaseClass::prot, +\begin_inset space ~ +\end_inset + +BaseClass::spec +\family default +\series default +\emph default + +\family sans +\size scriptsize + +\begin_inset space ~ +\end_inset + + +\family default +\size small + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\family sans +\size scriptsize +[const] +\family default +\size small + +\begin_inset Newline newline +\end_inset + +Protection level (AC::PROT_NONE /PRIVATE /PROTECTED /PUBLIC) and additional + specifiers (AC::SPEC_NONE /VIRTUAL) of the +\begin_inset ERT +status open + +\begin_layout Plain Layout + +$I^{ +\backslash +,th}$ +\end_layout + +\end_inset + + baseclass +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +MEMBERS +\series default +\size scriptsize +\emph default + +\begin_inset space ~ +\end_inset + + +\family default +\size small + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\family sans +\size scriptsize +[const] +\family default +\size small + +\begin_inset Newline newline +\end_inset + +number of member variables of the target class +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +Member::Type, +\family default +\series default +\emph default + +\family sans +\emph on +Member::ReferredType +\size scriptsize +\emph default + +\begin_inset space ~ +\end_inset + + +\family default +\size small + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\family sans +\size scriptsize +[type] +\family default +\size small + +\begin_inset Newline newline +\end_inset + +type of the +\begin_inset ERT +status open + +\begin_layout Plain Layout + +$I^{ +\backslash +,th}$ +\end_layout + +\end_inset + + member variable of the target class +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +Member::prot, +\begin_inset space ~ +\end_inset + +Member::spec +\family default +\series default +\emph default + +\family sans +\size scriptsize + +\begin_inset space ~ +\end_inset + + +\family default +\size small + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hfill +\end_layout + +\end_inset + + +\family sans +\size scriptsize +[const] +\family default +\size small + +\begin_inset Newline newline +\end_inset + +Protection level (see BaseClass::prot) and additional member variable + specifiers (AC::SPEC_NONE /STATIC /MUTABLE) +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +static +\begin_inset space ~ +\end_inset + +ReferredType +\begin_inset space ~ +\end_inset + +*Member:: +\series default +\emph default +pointer +\series medium +( +\emph on +T +\begin_inset space ~ +\end_inset + +*obj=0 +\emph default +) +\family default +\series default + +\family sans +\size scriptsize + +\begin_inset space ~ +\end_inset + + +\family default +\size small + +\begin_inset Newline newline +\end_inset + +returns a typed pointer to the +\begin_inset ERT +status open + +\begin_layout Plain Layout + +$I^{ +\backslash +,th}$ +\end_layout + +\end_inset + + member variable (obj is needed for non-static members) +\end_layout + +\begin_layout Description + +\family sans +\series medium +\size small +\emph on +static +\begin_inset space ~ +\end_inset + +const +\begin_inset space ~ +\end_inset + +char +\begin_inset space ~ +\end_inset + +*Member:: +\series default +\emph default +name +\series medium +\emph on +() +\family default +\series default +\emph default + +\family sans +\size scriptsize + +\begin_inset space ~ +\end_inset + + +\family default +\size small + +\begin_inset Newline newline +\end_inset + +returns the name of the +\begin_inset ERT +status open + +\begin_layout Plain Layout + +$I^{ +\backslash +,th}$ +\end_layout + +\end_inset + + member variable +\end_layout + +\begin_layout Subsection* + +\family sans +Example (simple tracing aspect) +\end_layout + +\begin_layout Standard +\noindent +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hspace{-24pt} +\end_layout + +\end_inset + + +\begin_inset Box Frameless +position "t" +hor_pos "c" +has_inner_box 1 +inner_pos "t" +use_parbox 0 +use_makebox 0 +width "100text%" +special "none" +height "1pt" +height_special "totalheight" +thickness "0.4pt" +separation "3pt" +shadowsize "4pt" +framecolor "black" +backgroundcolor "none" +status open + +\begin_layout LyX-Code +\noindent + +\family sans +\series bold +aspect +\series default + Tracing { +\end_layout + +\begin_layout LyX-Code + +\family sans +\series bold +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hspace{10pt} +\end_layout + +\end_inset + +advice +\series default + +\series bold +execution +\series default +( +\begin_inset Quotes eld +\end_inset + +% Business::%(...) +\begin_inset Quotes erd +\end_inset + +) : +\series bold +before +\series default +() { +\end_layout + +\begin_layout LyX-Code + +\family sans +\series bold +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hspace{20pt} +\end_layout + +\end_inset + + +\series default +cout < +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hspace{-1pt} +\end_layout + +\end_inset + +< "before " < +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hspace{-1pt} +\end_layout + +\end_inset + +< +\series bold +JoinPoint +\series default +:: +\series bold +signature +\series default +() < +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +hspace{-1pt} +\end_layout + +\end_inset + +< endl; +\end_layout + +\begin_layout LyX-Code + +\family sans +} }; +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +\begin_inset VSpace medskip* +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent + +\size small +Reference sheet corresponding to AspectC++ 2.2, +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +today +\end_layout + +\end_inset + +. + For more information visit +\begin_inset Flex URL +status open + +\begin_layout Plain Layout + +http://www.aspectc.org +\end_layout + +\end_inset + +. +\end_layout + +\begin_layout Standard + +\size small +\begin_inset space ~ +\end_inset + + +\begin_inset Newline newline +\end_inset + +(c) Copyright 2017, AspectC++ developers. + All rights reserved. +\end_layout + +\begin_layout Standard +\begin_inset VSpace medskip +\end_inset + + +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +hrule width 4.6cm +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +\begin_inset VSpace 2pt* +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent + +\series medium +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +footnotemark[2] +\end_layout + +\end_inset + + +\series default +\size scriptsize +support for template instance matching is an experimental feature +\size default + +\begin_inset VSpace -1pt* +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent + +\series medium +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +footnotemark[3] +\end_layout + +\end_inset + + +\series default +\size scriptsize +This feature has limitations. + Please see the AspectC++ Language Reference. +\size default + +\begin_inset VSpace -1pt* +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent + +\series medium +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +footnotemark[8] +\end_layout + +\end_inset + + +\series default +\size scriptsize + +\begin_inset Flex URL +status open + +\begin_layout Plain Layout + +https://mentorembedded.github.io/cxx-abi/abi.html#mangling +\end_layout + +\end_inset + + +\size default + +\begin_inset VSpace -2pt* +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent + +\series medium +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +footnotemark[9] +\end_layout + +\end_inset + + +\series default +\size scriptsize +C, C +\shape italic + +\begin_inset Formula $_{\textrm{C}}$ +\end_inset + + +\shape default +, C +\shape italic + +\begin_inset Formula $_{\textrm{B}}$ +\end_inset + + +\shape default +, C +\shape italic + +\begin_inset Formula $_{\textrm{E}}$ +\end_inset + + +\shape default +, C +\begin_inset Formula $_{Cons}$ +\end_inset + +, C +\begin_inset Formula $_{Des}$ +\end_inset + +, C +\shape italic + +\begin_inset Formula $_{\textrm{G}}$ +\end_inset + + +\shape default +, C +\shape italic + +\begin_inset Formula $_{\textrm{S}}$ +\end_inset + + +\shape default +, C +\shape italic + +\begin_inset Formula $_{\textrm{R}}$ +\end_inset + + +\shape default +: Code (any, only +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +underline{ +\backslash +smash{ +\backslash +textit{C}}} +\end_layout + +\end_inset + + +\emph on +all +\emph default +, only +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +underline{ +\backslash +smash{ +\backslash +textit{B}}} +\end_layout + +\end_inset + + +\emph on +uiltin +\emph default +, only +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +underline{ +\backslash +smash{ +\backslash +textit{E}}} +\end_layout + +\end_inset + + +\emph on +xecution +\emph default +, only object +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +underline{ +\backslash +smash{ +\backslash +textit{Cons}}} +\end_layout + +\end_inset + + +\emph on +truction +\emph default +, only object +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +underline{ +\backslash +smash{ +\backslash +textit{Des}}} +\end_layout + +\end_inset + + +\emph on +truction +\emph default +, only +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +underline{ +\backslash +smash{ +\backslash +textit{G}}} +\end_layout + +\end_inset + +et, only +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +underline{ +\backslash +smash{ +\backslash +textit{S}}} +\end_layout + +\end_inset + +et, only +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +underline{ +\backslash +smash{ +\backslash +textit{R}}} +\end_layout + +\end_inset + +ef) +\size default + +\begin_inset VSpace 2pt* +\end_inset + + +\begin_inset Newline newline +\end_inset + + +\size scriptsize +N, N +\begin_inset Formula $_{N}$ +\end_inset + +, N +\begin_inset Formula $_{C}$ +\end_inset + +, N +\begin_inset Formula $_{F}$ +\end_inset + +, N +\begin_inset Formula $_{V}$ +\end_inset + +, N +\begin_inset Formula $_{T}$ +\end_inset + +: Names (any, only +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +underline{ +\backslash +smash{ +\backslash +textit{N}}} +\end_layout + +\end_inset + + +\emph on +amespace +\emph default +, only +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +underline{ +\backslash +smash{ +\backslash +textit{C}}} +\end_layout + +\end_inset + + +\emph on +lass +\emph default +, only +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +underline{ +\backslash +smash{ +\backslash +textit{F}}} +\end_layout + +\end_inset + + +\emph on +unction +\emph default +, only +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +underline{ +\backslash +smash{ +\backslash +textit{V}}} +\end_layout + +\end_inset + +ariables, only +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +underline{ +\backslash +smash{ +\backslash +textit{T}}} +\end_layout + +\end_inset + + +\emph on +ype +\emph default +) +\end_layout + +\begin_layout Standard +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +end{multicols*} +\end_layout + +\end_inset + + +\end_layout + +\end_body +\end_document diff --git a/AspectC++/doc/QuickRef/ac++quickref.pdf b/AspectC++/doc/QuickRef/ac++quickref.pdf new file mode 100644 index 0000000..bcf89a5 Binary files /dev/null and b/AspectC++/doc/QuickRef/ac++quickref.pdf differ diff --git a/AspectC++/doc/Tutorial/1-intro.odp b/AspectC++/doc/Tutorial/1-intro.odp new file mode 100644 index 0000000..bb8dc38 Binary files /dev/null and b/AspectC++/doc/Tutorial/1-intro.odp differ diff --git a/AspectC++/doc/Tutorial/1-intro.pdf b/AspectC++/doc/Tutorial/1-intro.pdf new file mode 100644 index 0000000..6d6916e Binary files /dev/null and b/AspectC++/doc/Tutorial/1-intro.pdf differ diff --git a/AspectC++/doc/Tutorial/2-language.odp b/AspectC++/doc/Tutorial/2-language.odp new file mode 100644 index 0000000..1b2c6c2 Binary files /dev/null and b/AspectC++/doc/Tutorial/2-language.odp differ diff --git a/AspectC++/doc/Tutorial/2-language.pdf b/AspectC++/doc/Tutorial/2-language.pdf new file mode 100644 index 0000000..2ae2e9f Binary files /dev/null and b/AspectC++/doc/Tutorial/2-language.pdf differ diff --git a/AspectC++/doc/Tutorial/3-tools.odp b/AspectC++/doc/Tutorial/3-tools.odp new file mode 100644 index 0000000..7b6035d Binary files /dev/null and b/AspectC++/doc/Tutorial/3-tools.odp differ diff --git a/AspectC++/doc/Tutorial/3-tools.pdf b/AspectC++/doc/Tutorial/3-tools.pdf new file mode 100644 index 0000000..9fd2a17 Binary files /dev/null and b/AspectC++/doc/Tutorial/3-tools.pdf differ diff --git a/AspectC++/doc/Tutorial/4-examples.odp b/AspectC++/doc/Tutorial/4-examples.odp new file mode 100644 index 0000000..e24102d Binary files /dev/null and b/AspectC++/doc/Tutorial/4-examples.odp differ diff --git a/AspectC++/doc/Tutorial/4-examples.pdf b/AspectC++/doc/Tutorial/4-examples.pdf new file mode 100644 index 0000000..f5fa041 Binary files /dev/null and b/AspectC++/doc/Tutorial/4-examples.pdf differ diff --git a/AspectC++/doc/Tutorial/5-summary.odp b/AspectC++/doc/Tutorial/5-summary.odp new file mode 100644 index 0000000..34c4c33 Binary files /dev/null and b/AspectC++/doc/Tutorial/5-summary.odp differ diff --git a/AspectC++/doc/Tutorial/5-summary.pdf b/AspectC++/doc/Tutorial/5-summary.pdf new file mode 100644 index 0000000..f588c8d Binary files /dev/null and b/AspectC++/doc/Tutorial/5-summary.pdf differ diff --git a/AspectC++/doc/Tutorial/README-JOIN b/AspectC++/doc/Tutorial/README-JOIN new file mode 100644 index 0000000..08f81be --- /dev/null +++ b/AspectC++/doc/Tutorial/README-JOIN @@ -0,0 +1 @@ +pdfjoin --pdfauthor "Olaf Spinczyk" --pdftitle "AspectC++ Tutorial" -o ac-tutorial.pdf ?-*.pdf diff --git a/AspectC++/doc/Tutorial/ac-tutorial.pdf b/AspectC++/doc/Tutorial/ac-tutorial.pdf new file mode 100644 index 0000000..2cd07d4 Binary files /dev/null and b/AspectC++/doc/Tutorial/ac-tutorial.pdf differ diff --git a/AspectC++/doc/doxygen.conf b/AspectC++/doc/doxygen.conf new file mode 100644 index 0000000..35f26cb --- /dev/null +++ b/AspectC++/doc/doxygen.conf @@ -0,0 +1,1213 @@ +# Doxyfile 1.4.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = AspectC++ + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doc/doxygen + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, +# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, +# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, +# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, +# Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources +# only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. + +SHOW_DIRECTORIES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the progam writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = . + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm + +FILE_PATTERNS = *.cc \ + *.h + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that a graph may be further truncated if the graph's +# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH +# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), +# the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/AspectC++/doc/gen/ac++logo.png b/AspectC++/doc/gen/ac++logo.png new file mode 100644 index 0000000..cee0d61 Binary files /dev/null and b/AspectC++/doc/gen/ac++logo.png differ diff --git a/AspectC++/doc/gen/ac-manual.css b/AspectC++/doc/gen/ac-manual.css new file mode 100644 index 0000000..70ec8b0 --- /dev/null +++ b/AspectC++/doc/gen/ac-manual.css @@ -0,0 +1,116 @@ +/* some adjustments to the LxY-generated style */ + +/* include aspectc++ logo */ +body { + background-image: url("ac++logo.png"); + background-repeat: no-repeat; + background-size: 12em; + font-family: Arial, Helvetica, sans-serif; +} + +/* links shall be red */ +a:link { + color: red; +} +a:visited { + color: red; +} +a:active { + color: red; +} +a.tocentry:visited { color: red; } +a[href]:hover { + color: black; + background-color : red; +} + +/* floats and their captions shall have no border */ +div.float { +border: none; +text-align: center; +} + +div.float-caption { +text-align: center; +border: none; +padding: 1ex; +margin: 1ex; +} + +/* lyx code shall have equal space on top and below */ +/* also preserve whitespace */ +div.lyx_code { + font-family: monospace; + margin-top: 1ex; + margin-bottom: 1ex; + margin-left: 3ex; + margin-right: 0ex; + text-align: left; +} +div.lyx_code_item { + white-space: pre; +} + +/* same formatting for listing environments */ +pre.listings { + font-family: monospace; + margin-top: 1ex; + margin-bottom: 1ex; + margin-left: 3ex; + margin-right: 0ex; + text-align: left; +} + +/* 'standard' shall also have equal space */ +/* use 'justify' as text alignment */ +div.standard { +margin-top: 1ex; +margin-bottom: 1ex; +text-align: justify; +} + +/* fix indentation of toc entries */ + div.toc { + margin: 0em 0em; + border-style: solid; + border-width: 2px 0px; + padding: 1em 0em; + } +div.lyxtoc-0 { + margin: 0em 0em 0em 2em; + font-size: xx-large; + font-weight: bold; +} +div.lyxtoc-1 { + margin: 0em 0em 0em 0em; + font-size: x-large; + font-weight: bold; +} +div.lyxtoc-2 { + margin: 0em 0em 0em 0em; + font-size: large; + font-weight: normal; +} +div.lyxtoc-3 { margin: 0em 0em 0em 2em; font-size: medium; } +div.lyxtoc-4 { margin: 0em 0em 0em 0em; } +div.lyxtoc-5 { margin: 0em 0em 0em 0em; } +div.lyxtoc-6 { margin: 0em 0em 0em 0em; } + +/* fix descriptions */ +dl.description { + margin-left:3em; +} +dt.description_label { + display: inline-block; + margin: 0.5em 1em 0em 0em; + text-indent: -3em; +} +dd.description_item { + margin: 0em 0em 0em 0em; + display: inline; +} +dd.description_item:after{ + display: block; + content: ''; +} + diff --git a/AspectC++/doc/gen/fixhtml.xsl b/AspectC++/doc/gen/fixhtml.xsl new file mode 100644 index 0000000..43a2e9a --- /dev/null +++ b/AspectC++/doc/gen/fixhtml.xsl @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AspectC++/doc/images/JoinPointModel.eps b/AspectC++/doc/images/JoinPointModel.eps new file mode 100644 index 0000000..bc28901 --- /dev/null +++ b/AspectC++/doc/images/JoinPointModel.eps @@ -0,0 +1,544 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: JoinPointModel.eps +%%Creator: fig2dev Version 3.2 Patchlevel 3c +%%CreationDate: Fri May 23 01:04:15 2003 +%%For: matthias@mobile (Matthias Urban) +%%BoundingBox: 0 0 628 340 +%%Magnification: 1.0000 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def +/col32 {0.937 0.937 0.937 srgb} bind def + +end +save +newpath 0 340 moveto 0 0 lineto 628 0 lineto 628 340 lineto closepath clip newpath +-3.0 420.0 translate +1 -1 scale + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def + /DrawEllipse { + /endangle exch def + /startangle exch def + /yrad exch def + /xrad exch def + /y exch def + /x exch def + /savematrix mtrx currentmatrix def + x y tr xrad yrad sc 0 0 1 startangle endangle arc + closepath + savematrix setmatrix + } def + +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +$F2psBegin +%%Page: 1 1 +10 setmiterlimit + 0.06000 0.06000 sc +% +% Fig objects follow +% +% Polyline +7.500 slw +n 2250 1350 m 2250 3225 l 4650 3225 l 4650 4275 l 8925 4275 l 8925 2250 l + 7350 2250 l 7350 1350 l + cp gs col32 1.00 shd ef gr gs col32 s gr +% Polyline +n 4800 4125 m 8850 4125 l 8850 3225 l 7575 3225 l 7575 2400 l 6000 2400 l + 6000 3225 l 4800 3225 l + cp gs col32 0.50 tnt ef gr gs col32 s gr +% Polyline +n 975 5850 m 9600 5850 l 9600 6980 l 975 6980 l + cp gs col11 0.50 tnt ef gr gs col0 s gr +% Polyline +n 8136 6150 m 8031 6150 8031 6495 105 arcto 4 {pop} repeat + 8031 6600 9201 6600 105 arcto 4 {pop} repeat + 9306 6600 9306 6255 105 arcto 4 {pop} repeat + 9306 6150 8136 6150 105 arcto 4 {pop} repeat + cp gs col7 1.00 shd ef gr gs col0 s gr +% Polyline +n 5280 4500 m 5175 4500 5175 4845 105 arcto 4 {pop} repeat + 5175 4950 6345 4950 105 arcto 4 {pop} repeat + 6450 4950 6450 4605 105 arcto 4 {pop} repeat + 6450 4500 5280 4500 105 arcto 4 {pop} repeat + cp gs col7 1.00 shd ef gr gs col0 s gr +% Polyline +n 5280 4950 m 5175 4950 5175 5295 105 arcto 4 {pop} repeat + 5175 5400 6345 5400 105 arcto 4 {pop} repeat + 6450 5400 6450 5055 105 arcto 4 {pop} repeat + 6450 4950 5280 4950 105 arcto 4 {pop} repeat + cp gs col7 1.00 shd ef gr gs col0 s gr +% Polyline +n 255 3000 m 150 3000 150 3345 105 arcto 4 {pop} repeat + 150 3450 1320 3450 105 arcto 4 {pop} repeat + 1425 3450 1425 3105 105 arcto 4 {pop} repeat + 1425 3000 255 3000 105 arcto 4 {pop} repeat + cp gs col7 1.00 shd ef gr gs col0 s gr +% Polyline +n 4350 1575 m 5850 1575 l 5850 2025 l 4350 2025 l + cp gs col7 1.00 shd ef gr gs col0 s gr +% Polyline +n 9075 1575 m 10500 1575 l 10500 2025 l 9075 2025 l + cp gs col7 1.00 shd ef gr gs col0 s gr +% Polyline +n 6150 2550 m 7425 2550 l 7425 3000 l 6150 3000 l + cp gs col7 1.00 shd ef gr gs col0 s gr +% Polyline +n 6975 3525 m 8700 3525 l 8700 3975 l 6975 3975 l + cp gs col7 1.00 shd ef gr gs col0 s gr +% Polyline +n 4950 3525 m 6675 3525 l 6675 3975 l 4950 3975 l + cp gs col7 1.00 shd ef gr gs col0 s gr +% Polyline +n 4275 2550 m 5850 2550 l 5850 3000 l 4275 3000 l + cp gs col7 1.00 shd ef gr gs col0 s gr +% Polyline +n 2475 2550 m 3975 2550 l 3975 3000 l 2475 3000 l + cp gs col7 1.00 shd ef gr gs col0 s gr +% Polyline +n 75 1575 m 1575 1575 l 1575 2025 l 75 2025 l + cp gs col7 1.00 shd ef gr gs col0 s gr +% Polyline +n 7575 1575 m 8700 1575 l 8700 2025 l 7575 2025 l + cp gs col7 1.00 shd ef gr gs col0 s gr +% Polyline +n 255 2550 m 150 2550 150 2895 105 arcto 4 {pop} repeat + 150 3000 1320 3000 105 arcto 4 {pop} repeat + 1425 3000 1425 2655 105 arcto 4 {pop} repeat + 1425 2550 255 2550 105 arcto 4 {pop} repeat + cp gs col7 1.00 shd ef gr gs col0 s gr +% Polyline +n 2655 3525 m 2550 3525 2550 3870 105 arcto 4 {pop} repeat + 2550 3975 3720 3975 105 arcto 4 {pop} repeat + 3825 3975 3825 3630 105 arcto 4 {pop} repeat + 3825 3525 2655 3525 105 arcto 4 {pop} repeat + cp gs col7 1.00 shd ef gr gs col0 s gr +% Polyline +n 2655 3975 m 2550 3975 2550 4320 105 arcto 4 {pop} repeat + 2550 4425 3720 4425 105 arcto 4 {pop} repeat + 3825 4425 3825 4080 105 arcto 4 {pop} repeat + 3825 3975 2655 3975 105 arcto 4 {pop} repeat + cp gs col7 1.00 shd ef gr gs col0 s gr +% Polyline +n 2655 4425 m 2550 4425 2550 4770 105 arcto 4 {pop} repeat + 2550 4875 3720 4875 105 arcto 4 {pop} repeat + 3825 4875 3825 4530 105 arcto 4 {pop} repeat + 3825 4425 2655 4425 105 arcto 4 {pop} repeat + cp gs col7 1.00 shd ef gr gs col0 s gr +% Polyline +n 9255 2550 m 9150 2550 9150 2895 105 arcto 4 {pop} repeat + 9150 3000 10320 3000 105 arcto 4 {pop} repeat + 10425 3000 10425 2655 105 arcto 4 {pop} repeat + 10425 2550 9255 2550 105 arcto 4 {pop} repeat + cp gs col7 1.00 shd ef gr gs col0 s gr +% Polyline +n 6606 6150 m 7506 6150 l 7506 6600 l 6606 6600 l + cp gs col7 1.00 shd ef gr gs col0 s gr +/Helvetica ff 180.00 scf sf +6816 6450 m +gs 1 -1 sc (Name) col0 sh gr +% Ellipse +n 8181 6375 75 75 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +/Helvetica ff 180.00 scf sf +8406 6450 m +gs 1 -1 sc (Name) col0 sh gr +% Polyline +gs clippath +6090 6405 m 6090 6345 l 5939 6345 l 6059 6375 l 5939 6405 l cp +eoclip +n 4500 6375 m + 6075 6375 l gs col0 s gr gr + +% arrowhead +n 5939 6405 m 6059 6375 l 5939 6345 l 5939 6405 l cp gs 0.00 setgray ef gr col0 s +% Polyline + [60] 0 sd +n 2475 6375 m + 3975 6375 l gs col0 s gr [] 0 sd +/Helvetica ff 150.00 scf sf +4500 6675 m +gs 1 -1 sc (relation between names) col0 sh gr +/Helvetica ff 150.00 scf sf +2475 6825 m +gs 1 -1 sc (and names) col0 sh gr +/Helvetica ff 150.00 scf sf +2475 6675 m +gs 1 -1 sc (relation between code) col0 sh gr +/Helvetica ff 150.00 scf sf +8175 6825 m +gs 1 -1 sc (code join point) col0 sh gr +/Helvetica ff 150.00 scf sf +6525 6825 m +gs 1 -1 sc (name join point) col0 sh gr +/Helvetica-Bold ff 180.00 scf sf +1200 6450 m +gs 1 -1 sc (Legend) col0 sh gr +% Ellipse +n 5325 4725 75 75 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 5325 5175 75 75 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 300 3225 75 75 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 300 2775 75 75 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 2700 3750 75 75 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 2700 4200 75 75 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 2700 4650 75 75 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 9300 2775 75 75 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Polyline +gs clippath +5070 2565 m 5130 2565 l 5130 2414 l 5100 2534 l 5070 2414 l cp +eoclip +n 5100 2025 m + 5100 2550 l gs col0 s gr gr + +% arrowhead +n 5070 2414 m 5100 2534 l 5130 2414 l 5070 2414 l cp gs 0.00 setgray ef gr col0 s +% Polyline +gs clippath +3721 2532 m 3753 2583 l 3881 2501 l 3764 2541 l 3849 2451 l cp +eoclip +n 4575 2025 m + 3750 2550 l gs col0 s gr gr + +% arrowhead +n 3849 2451 m 3764 2541 l 3881 2501 l 3849 2451 l cp gs 0.00 setgray ef gr col0 s +% Polyline +gs clippath +6370 2583 m 6404 2534 l 6280 2447 l 6362 2541 l 6246 2496 l cp +eoclip +n 5625 2025 m + 6375 2550 l gs col0 s gr gr + +% arrowhead +n 6246 2496 m 6362 2541 l 6280 2447 l 6246 2496 l cp gs 0.00 setgray ef gr col0 s +% Polyline +gs clippath +7831 2037 m 7791 1992 l 7677 2092 l 7788 2036 l 7717 2137 l cp +eoclip +n 7800 2025 m + 7200 2550 l gs col0 s gr gr + +% arrowhead +n 7717 2137 m 7788 2036 l 7677 2092 l 7717 2137 l cp gs 0.00 setgray ef gr col0 s +% Polyline +gs clippath +5819 3510 m 5856 3557 l 5976 3465 l 5863 3515 l 5939 3417 l cp +eoclip +n 6525 3000 m + 5850 3525 l gs col0 s gr gr + +% arrowhead +n 5939 3417 m 5863 3515 l 5976 3465 l 5939 3417 l cp gs 0.00 setgray ef gr col0 s +% Polyline +gs clippath +7870 3558 m 7904 3509 l 7780 3422 l 7862 3516 l 7746 3471 l cp +eoclip +n 7125 3000 m + 7875 3525 l gs col0 s gr gr + +% arrowhead +n 7746 3471 m 7862 3516 l 7780 3422 l 7746 3471 l cp gs 0.00 setgray ef gr col0 s +% Polyline + [60] 0 sd +n 3225 3000 m + 3225 3525 l gs col7 1.00 shd ef gr gs col0 s gr [] 0 sd +% Polyline + [60] 0 sd +n 825 2025 m + 825 2550 l gs col7 1.00 shd ef gr gs col0 s gr [] 0 sd +% Polyline + [60] 0 sd +n 5850 3975 m + 5850 4500 l gs col7 1.00 shd ef gr gs col0 s gr [] 0 sd +% Polyline + [60] 0 sd +n 9750 2025 m + 9750 2550 l gs col7 1.00 shd ef gr gs col0 s gr [] 0 sd +% Polyline +2 slj + [60] 0 sd +n 3825 4200 m 3828 4200 l 3834 4200 l 3845 4199 l 3861 4198 l 3882 4197 l + 3907 4195 l 3935 4193 l 3964 4190 l 3993 4187 l 4021 4184 l + 4048 4180 l 4074 4175 l 4098 4170 l 4121 4165 l 4143 4158 l + 4164 4151 l 4184 4144 l 4205 4135 l 4225 4125 l 4244 4115 l + 4263 4105 l 4283 4093 l 4303 4081 l 4324 4067 l 4346 4053 l + 4368 4039 l 4390 4023 l 4413 4007 l 4436 3991 l 4459 3975 l + 4482 3959 l 4504 3943 l 4526 3927 l 4547 3911 l 4568 3897 l + 4588 3883 l 4607 3869 l 4625 3857 l 4642 3845 l 4659 3835 l + 4675 3825 l 4696 3813 l 4716 3802 l 4736 3793 l 4756 3785 l + 4776 3779 l 4798 3773 l 4820 3767 l 4843 3763 l 4867 3759 l + 4890 3756 l 4910 3754 l 4927 3752 l 4940 3751 l 4947 3750 l + + 4950 3750 l gs col0 s gr [] 0 sd +% Polyline + [60] 0 sd +n 6450 5175 m 6451 5175 l 6454 5175 l 6462 5174 l 6477 5174 l 6498 5173 l + 6525 5171 l 6557 5168 l 6592 5165 l 6628 5162 l 6664 5158 l + 6698 5153 l 6729 5148 l 6758 5142 l 6784 5135 l 6807 5128 l + 6827 5120 l 6845 5110 l 6861 5100 l 6875 5088 l 6888 5075 l + 6899 5061 l 6909 5045 l 6919 5027 l 6927 5008 l 6935 4988 l + 6942 4966 l 6948 4942 l 6952 4917 l 6956 4891 l 6959 4865 l + 6962 4837 l 6963 4810 l 6963 4782 l 6963 4754 l 6962 4727 l + 6961 4700 l 6959 4674 l 6956 4649 l 6953 4624 l 6950 4600 l + 6946 4576 l 6942 4552 l 6938 4528 l 6933 4504 l 6928 4480 l + 6923 4455 l 6918 4431 l 6912 4406 l 6906 4381 l 6900 4357 l + 6894 4333 l 6888 4309 l 6882 4287 l 6877 4265 l 6872 4244 l + 6867 4223 l 6862 4204 l 6858 4185 l 6854 4167 l 6850 4150 l + 6846 4129 l 6842 4108 l 6839 4087 l 6837 4066 l 6835 4045 l + 6833 4024 l 6832 4004 l 6832 3984 l 6832 3965 l 6833 3946 l + 6835 3929 l 6837 3914 l 6839 3899 l 6842 3886 l 6846 3874 l + 6850 3863 l 6856 3849 l 6864 3836 l 6873 3825 l 6884 3813 l + 6898 3801 l 6914 3789 l 6931 3777 l 6948 3767 l 6961 3758 l + 6970 3753 l 6974 3750 l + 6975 3750 l gs col0 s gr [] 0 sd +% Polyline + [60] 0 sd +n 3825 4650 m 3826 4650 l 3829 4650 l 3837 4650 l 3851 4651 l 3871 4652 l + 3896 4653 l 3925 4654 l 3956 4656 l 3986 4659 l 4016 4661 l + 4043 4664 l 4069 4668 l 4092 4671 l 4114 4676 l 4134 4681 l + 4152 4686 l 4170 4693 l 4188 4700 l 4205 4708 l 4222 4717 l + 4239 4727 l 4256 4738 l 4274 4751 l 4291 4764 l 4309 4779 l + 4326 4795 l 4343 4812 l 4360 4830 l 4375 4848 l 4391 4867 l + 4405 4887 l 4418 4906 l 4431 4926 l 4442 4946 l 4453 4967 l + 4463 4988 l 4471 5007 l 4479 5027 l 4487 5047 l 4494 5068 l + 4501 5091 l 4509 5113 l 4516 5137 l 4523 5161 l 4530 5185 l + 4538 5209 l 4545 5233 l 4552 5257 l 4559 5279 l 4566 5302 l + 4574 5323 l 4581 5343 l 4588 5362 l 4596 5380 l 4604 5397 l + 4613 5413 l 4618 5423 l 4625 5432 l 4631 5442 l 4639 5451 l + 4647 5460 l 4656 5469 l 4666 5478 l 4678 5486 l 4691 5494 l + 4705 5502 l 4721 5510 l 4739 5517 l 4758 5524 l 4780 5531 l + 4803 5538 l 4828 5544 l 4855 5550 l 4885 5556 l 4916 5561 l + 4949 5566 l 4985 5571 l 5022 5575 l 5062 5579 l 5103 5583 l + 5147 5586 l 5193 5589 l 5241 5592 l 5291 5595 l 5344 5598 l + 5400 5600 l 5436 5601 l 5474 5603 l 5513 5604 l 5553 5605 l + 5595 5606 l 5638 5607 l 5682 5608 l 5728 5609 l 5775 5610 l + 5824 5611 l 5873 5611 l 5924 5612 l 5977 5612 l 6030 5612 l + 6085 5612 l 6140 5612 l 6197 5612 l 6254 5612 l 6313 5611 l + 6372 5611 l 6431 5610 l 6491 5609 l 6552 5607 l 6612 5606 l + 6673 5604 l 6734 5603 l 6794 5601 l 6855 5598 l 6915 5596 l + 6974 5593 l 7033 5591 l 7091 5588 l 7149 5584 l 7206 5581 l + 7262 5577 l 7317 5574 l 7370 5570 l 7423 5566 l 7475 5561 l + 7525 5557 l 7575 5552 l 7623 5547 l 7670 5542 l 7716 5536 l + 7760 5531 l 7804 5525 l 7846 5519 l 7888 5513 l 7938 5504 l + 7988 5495 l 8036 5486 l 8082 5476 l 8128 5466 l 8173 5455 l + 8216 5443 l 8259 5431 l 8300 5418 l 8341 5405 l 8380 5391 l + 8419 5376 l 8456 5361 l 8492 5344 l 8527 5328 l 8561 5310 l + 8594 5292 l 8626 5274 l 8656 5255 l 8685 5235 l 8713 5215 l + 8739 5194 l 8764 5173 l 8788 5152 l 8810 5130 l 8832 5108 l + 8851 5086 l 8870 5063 l 8887 5040 l 8904 5017 l 8919 4994 l + 8933 4971 l 8946 4947 l 8959 4923 l 8970 4899 l 8981 4875 l + 8991 4850 l 9000 4825 l 9010 4795 l 9020 4763 l 9029 4731 l + 9037 4699 l 9045 4665 l 9052 4630 l 9058 4594 l 9064 4558 l + 9068 4521 l 9073 4483 l 9076 4444 l 9079 4405 l 9082 4365 l + 9083 4325 l 9084 4285 l 9085 4244 l 9085 4204 l 9084 4165 l + 9082 4125 l 9080 4087 l 9078 4049 l 9075 4012 l 9072 3976 l + 9068 3940 l 9063 3906 l 9059 3874 l 9054 3842 l 9049 3811 l + 9043 3782 l 9037 3754 l 9031 3726 l 9025 3700 l 9017 3669 l + 9008 3639 l 8999 3610 l 8990 3581 l 8980 3554 l 8970 3526 l + 8959 3499 l 8949 3473 l 8938 3446 l 8926 3420 l 8915 3394 l + 8904 3368 l 8893 3343 l 8882 3317 l 8871 3292 l 8861 3267 l + 8851 3242 l 8841 3217 l 8832 3192 l 8824 3167 l 8816 3142 l + 8809 3117 l 8803 3092 l 8797 3066 l 8792 3040 l 8788 3013 l + 8784 2986 l 8781 2959 l 8779 2931 l 8777 2901 l 8776 2870 l + 8776 2839 l 8775 2806 l 8776 2772 l 8777 2737 l 8778 2702 l + 8780 2665 l 8783 2629 l 8786 2592 l 8789 2555 l 8793 2518 l + 8797 2482 l 8801 2446 l 8806 2411 l 8811 2377 l 8816 2344 l + 8821 2312 l 8827 2281 l 8833 2252 l 8839 2224 l 8844 2197 l + 8850 2172 l 8856 2148 l 8863 2125 l 8872 2092 l 8882 2062 l + 8893 2034 l 8904 2009 l 8917 1984 l 8930 1961 l 8945 1939 l + 8962 1917 l 8979 1896 l 8997 1875 l 9015 1856 l 9032 1839 l + 9048 1825 l 9059 1814 l 9068 1806 l 9073 1802 l + 9075 1800 l gs col0 s gr [] 0 sd +% Polyline + [60] 0 sd +n 1425 3225 m 1428 3225 l 1435 3224 l 1446 3224 l 1463 3222 l 1484 3221 l + 1508 3218 l 1534 3215 l 1560 3212 l 1586 3208 l 1610 3204 l + 1633 3199 l 1654 3193 l 1674 3186 l 1694 3179 l 1712 3170 l + 1731 3161 l 1750 3150 l 1766 3140 l 1782 3130 l 1799 3118 l + 1816 3106 l 1834 3092 l 1852 3078 l 1871 3064 l 1890 3048 l + 1910 3032 l 1930 3016 l 1950 3000 l 1970 2984 l 1990 2968 l + 2010 2952 l 2029 2936 l 2048 2922 l 2066 2908 l 2084 2894 l + 2101 2882 l 2118 2870 l 2134 2860 l 2150 2850 l 2169 2839 l + 2188 2830 l 2206 2821 l 2226 2814 l 2246 2807 l 2267 2801 l + 2290 2796 l 2314 2792 l 2340 2788 l 2366 2785 l 2392 2782 l + 2416 2779 l 2437 2778 l 2454 2776 l 2465 2776 l 2472 2775 l + + 2475 2775 l gs col0 s gr [] 0 sd +/Helvetica ff 135.00 scf sf +6225 2400 m +gs 1 -1 sc (contained) col0 sh gr +/Helvetica ff 135.00 scf sf +5175 2400 m +gs 1 -1 sc (contained) col0 sh gr +/Helvetica ff 150.00 scf sf +7800 3375 m +gs 1 -1 sc (attribute) col0 sh gr +/Helvetica ff 135.00 scf sf +4200 2400 m +gs 1 -1 sc (contained) col0 sh gr +/Helvetica ff 135.00 scf sf +7575 2400 m +gs 1 -1 sc (base class) col0 sh gr +/Helvetica ff 150.00 scf sf +6300 3375 m +gs 1 -1 sc (method) col0 sh gr +/Helvetica ff 150.00 scf sf +4725 1725 m +gs 1 -1 sc (namespace) col0 sh gr +/Helvetica ff 150.00 scf sf +6600 2700 m +gs 1 -1 sc (class) col0 sh gr +/Helvetica ff 150.00 scf sf +7950 1725 m +gs 1 -1 sc (class) col0 sh gr +/Helvetica ff 150.00 scf sf +5550 3675 m +gs 1 -1 sc (function) col0 sh gr +/Helvetica ff 150.00 scf sf +7575 3675 m +gs 1 -1 sc (attribute) col0 sh gr +/Helvetica ff 150.00 scf sf +525 1725 m +gs 1 -1 sc (function) col0 sh gr +/Helvetica ff 150.00 scf sf +9525 1725 m +gs 1 -1 sc (function) col0 sh gr +/Helvetica ff 150.00 scf sf +3000 2700 m +gs 1 -1 sc (function) col0 sh gr +/Helvetica ff 150.00 scf sf +4950 2700 m +gs 1 -1 sc (type) col0 sh gr +/Helvetica ff 180.00 scf sf +2925 4725 m +gs 1 -1 sc (Call) col0 sh gr +/Helvetica ff 180.00 scf sf +2925 4275 m +gs 1 -1 sc (Call) col0 sh gr +/Helvetica ff 180.00 scf sf +2925 3825 m +gs 1 -1 sc (Execution) col0 sh gr +/Helvetica ff 180.00 scf sf +525 3300 m +gs 1 -1 sc (Call) col0 sh gr +/Helvetica ff 180.00 scf sf +525 2850 m +gs 1 -1 sc (Execution) col0 sh gr +/Helvetica ff 180.00 scf sf +5550 4800 m +gs 1 -1 sc (Execution) col0 sh gr +/Helvetica ff 180.00 scf sf +5550 5250 m +gs 1 -1 sc (Set) col0 sh gr +/Helvetica ff 180.00 scf sf +9525 2850 m +gs 1 -1 sc (Execution) col0 sh gr +/Helvetica ff 180.00 scf sf +525 1950 m +gs 1 -1 sc ("main") col0 sh gr +/Helvetica ff 180.00 scf sf +3000 2925 m +gs 1 -1 sc ("draw") col0 sh gr +/Helvetica ff 180.00 scf sf +4500 2925 m +gs 1 -1 sc ("PRECISION") col0 sh gr +/Helvetica ff 180.00 scf sf +4800 1950 m +gs 1 -1 sc ("Circle") col0 sh gr +/Helvetica ff 180.00 scf sf +6375 2925 m +gs 1 -1 sc ("S_Circle") col0 sh gr +/Helvetica ff 180.00 scf sf +5475 3900 m +gs 1 -1 sc ("radius") col0 sh gr +/Helvetica ff 180.00 scf sf +7425 3900 m +gs 1 -1 sc ("m_radius") col0 sh gr +/Helvetica ff 180.00 scf sf +9525 1950 m +gs 1 -1 sc ("draw") col0 sh gr +/Helvetica ff 180.00 scf sf +7800 1950 m +gs 1 -1 sc ("Shape") col0 sh gr +$F2psEnd +rs diff --git a/AspectC++/doc/images/JoinPointModel.fig b/AspectC++/doc/images/JoinPointModel.fig new file mode 100644 index 0000000..c3d573d --- /dev/null +++ b/AspectC++/doc/images/JoinPointModel.fig @@ -0,0 +1,156 @@ +#FIG 3.2 +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +0 32 #efefef +6 975 5850 9600 7050 +6 6600 6150 7575 6600 +2 2 0 1 0 7 50 0 20 4.000 0 0 -1 0 0 5 + 6606 6150 7506 6150 7506 6600 6606 6600 6606 6150 +4 0 0 50 0 16 12 0.0000 4 135 480 6816 6450 Name\001 +-6 +6 8031 6150 9306 6600 +1 3 0 1 0 0 50 0 20 0.000 1 0.0000 8181 6375 75 75 8181 6375 8256 6375 +2 4 0 1 0 7 55 0 20 0.000 0 0 7 0 0 5 + 9306 6600 9306 6150 8031 6150 8031 6600 9306 6600 +4 0 0 50 0 16 12 0.0000 4 135 480 8406 6450 Name\001 +-6 +2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 4500 6375 6075 6375 +2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2 + 2475 6375 3975 6375 +2 2 0 1 0 11 60 0 30 0.000 0 0 -1 0 0 5 + 975 5850 9600 5850 9600 6980 975 6980 975 5850 +4 0 0 50 0 16 10 0.0000 4 120 1620 4500 6675 relation between names\001 +4 0 0 50 0 16 10 0.0000 4 120 735 2475 6825 and names\001 +4 0 0 50 0 16 10 0.0000 4 120 1515 2475 6675 relation between code\001 +4 0 0 50 0 16 10 0.0000 4 150 1020 8175 6825 code join point\001 +4 0 0 50 0 16 10 0.0000 4 150 1050 6525 6825 name join point\001 +4 0 0 50 0 18 12 0.0000 4 180 630 1200 6450 Legend\001 +-6 +1 3 0 1 0 0 50 0 20 0.000 1 0.0000 5325 4725 75 75 5325 4725 5400 4725 +1 3 0 1 0 0 50 0 20 0.000 1 0.0000 5325 5175 75 75 5325 5175 5400 5175 +1 3 0 1 0 0 50 0 20 0.000 1 0.0000 300 3225 75 75 300 3225 375 3225 +1 3 0 1 0 0 50 0 20 0.000 1 0.0000 300 2775 75 75 300 2775 375 2775 +1 3 0 1 0 0 50 0 20 0.000 1 0.0000 2700 3750 75 75 2700 3750 2775 3750 +1 3 0 1 0 0 50 0 20 0.000 1 0.0000 2700 4200 75 75 2700 4200 2775 4200 +1 3 0 1 0 0 50 0 20 0.000 1 0.0000 2700 4650 75 75 2700 4650 2775 4650 +1 3 0 1 0 0 50 0 20 0.000 1 0.0000 9300 2775 75 75 9300 2775 9375 2775 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 5100 2025 5100 2550 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 4575 2025 3750 2550 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 5625 2025 6375 2550 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 1 2 + 1 1 1.00 60.00 120.00 + 7800 2025 7200 2550 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 6525 3000 5850 3525 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 7125 3000 7875 3525 +2 1 1 1 0 7 50 0 20 4.000 0 0 -1 0 0 2 + 3225 3000 3225 3525 +2 1 1 1 0 7 50 0 20 4.000 0 0 -1 0 0 2 + 825 2025 825 2550 +2 1 1 1 0 7 50 0 20 4.000 0 0 -1 0 0 2 + 5850 3975 5850 4500 +2 1 1 1 0 7 50 0 20 4.000 0 0 -1 0 0 2 + 9750 2025 9750 2550 +2 4 0 1 0 7 55 0 20 0.000 0 0 7 0 0 5 + 6450 4950 6450 4500 5175 4500 5175 4950 6450 4950 +2 4 0 1 0 7 55 0 20 0.000 0 0 7 0 0 5 + 6450 5400 6450 4950 5175 4950 5175 5400 6450 5400 +2 4 0 1 0 7 55 0 20 0.000 0 0 7 0 0 5 + 1425 3450 1425 3000 150 3000 150 3450 1425 3450 +2 2 0 1 0 7 55 0 20 0.000 0 0 -1 0 0 5 + 4350 1575 5850 1575 5850 2025 4350 2025 4350 1575 +2 2 0 1 0 7 55 0 20 0.000 0 0 -1 0 0 5 + 9075 1575 10500 1575 10500 2025 9075 2025 9075 1575 +2 2 0 1 0 7 55 0 20 0.000 0 0 -1 0 0 5 + 6150 2550 7425 2550 7425 3000 6150 3000 6150 2550 +2 2 0 1 0 7 55 0 20 0.000 0 0 -1 0 0 5 + 6975 3525 8700 3525 8700 3975 6975 3975 6975 3525 +2 2 0 1 0 7 55 0 20 0.000 0 0 -1 0 0 5 + 4950 3525 6675 3525 6675 3975 4950 3975 4950 3525 +2 2 0 1 0 7 55 0 20 0.000 0 0 -1 0 0 5 + 4275 2550 5850 2550 5850 3000 4275 3000 4275 2550 +2 2 0 1 0 7 55 0 20 0.000 0 0 -1 0 0 5 + 2475 2550 3975 2550 3975 3000 2475 3000 2475 2550 +2 2 0 1 0 7 55 0 20 0.000 0 0 -1 0 0 5 + 75 1575 1575 1575 1575 2025 75 2025 75 1575 +2 3 0 1 32 32 65 0 30 0.000 0 0 -1 0 0 9 + 4800 4125 8850 4125 8850 3225 7575 3225 7575 2400 6000 2400 + 6000 3225 4800 3225 4800 4125 +2 3 0 1 32 32 70 0 20 0.000 0 0 -1 0 0 9 + 2250 1350 2250 3225 4650 3225 4650 4275 8925 4275 8925 2250 + 7350 2250 7350 1350 2250 1350 +2 2 0 1 0 7 55 0 20 0.000 0 0 -1 0 0 5 + 7575 1575 8700 1575 8700 2025 7575 2025 7575 1575 +2 4 0 1 0 7 55 0 20 0.000 0 0 7 0 0 5 + 1425 3000 1425 2550 150 2550 150 3000 1425 3000 +2 4 0 1 0 7 55 0 20 0.000 0 0 7 0 0 5 + 3825 3975 3825 3525 2550 3525 2550 3975 3825 3975 +2 4 0 1 0 7 55 0 20 0.000 0 0 7 0 0 5 + 3825 4425 3825 3975 2550 3975 2550 4425 3825 4425 +2 4 0 1 0 7 55 0 20 0.000 0 0 7 0 0 5 + 3825 4875 3825 4425 2550 4425 2550 4875 3825 4875 +2 4 0 1 0 7 55 0 20 0.000 0 0 7 0 0 5 + 10425 3000 10425 2550 9150 2550 9150 3000 10425 3000 +3 0 1 1 0 7 50 0 -1 4.000 0 0 0 4 + 3825 4200 4200 4200 4725 3750 4950 3750 + 0.000 1.000 1.000 0.000 +3 0 1 1 0 7 50 0 -1 4.000 0 0 0 6 + 6450 5175 6975 5175 6975 4575 6825 4125 6825 3825 6975 3750 + 0.000 1.000 1.000 1.000 1.000 0.000 +3 0 1 1 0 7 50 0 -1 4.000 0 0 0 11 + 3825 4650 4200 4650 4500 4950 4575 5475 4875 5625 8325 5625 + 9150 4950 9075 3525 8700 3150 8850 1950 9075 1800 + 0.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000 + 1.000 1.000 0.000 +3 0 1 1 0 7 50 0 -1 4.000 0 0 0 4 + 1425 3225 1725 3225 2175 2775 2475 2775 + 0.000 1.000 1.000 0.000 +4 0 0 50 0 16 9 0.0000 4 120 675 6225 2400 contained\001 +4 0 0 50 0 16 9 0.0000 4 120 675 5175 2400 contained\001 +4 0 0 50 0 16 10 0.0000 4 120 585 7800 3375 attribute\001 +4 0 0 50 0 16 9 0.0000 4 120 675 4200 2400 contained\001 +4 0 0 50 0 16 9 0.0000 4 120 690 7575 2400 base class\001 +4 0 0 50 0 16 10 0.0000 4 120 525 6300 3375 method\001 +4 0 0 50 0 16 10 0.0000 4 120 750 4725 1725 namespace\001 +4 0 0 50 0 16 10 0.0000 4 120 330 6600 2700 class\001 +4 0 0 50 0 16 10 0.0000 4 120 330 7950 1725 class\001 +4 0 0 50 0 16 10 0.0000 4 120 570 5550 3675 function\001 +4 0 0 50 0 16 10 0.0000 4 120 585 7575 3675 attribute\001 +4 0 0 50 0 16 10 0.0000 4 120 570 525 1725 function\001 +4 0 0 50 0 16 10 0.0000 4 120 570 9525 1725 function\001 +4 0 0 50 0 16 10 0.0000 4 120 570 3000 2700 function\001 +4 0 0 50 0 16 10 0.0000 4 150 300 4950 2700 type\001 +4 0 0 50 0 16 12 0.0000 4 135 330 2925 4725 Call\001 +4 0 0 50 0 16 12 0.0000 4 135 330 2925 4275 Call\001 +4 0 0 50 0 16 12 0.0000 4 135 825 2925 3825 Execution\001 +4 0 0 50 0 16 12 0.0000 4 135 330 525 3300 Call\001 +4 0 0 50 0 16 12 0.0000 4 135 825 525 2850 Execution\001 +4 0 0 50 0 16 12 0.0000 4 135 825 5550 4800 Execution\001 +4 0 0 50 0 16 12 0.0000 4 135 270 5550 5250 Set\001 +4 0 0 50 0 16 12 0.0000 4 135 825 9525 2850 Execution\001 +4 0 0 50 0 16 12 0.0000 4 135 540 525 1950 "main"\001 +4 0 0 50 0 16 12 0.0000 4 135 555 3000 2925 "draw"\001 +4 0 0 50 0 16 12 0.0000 4 135 1140 4500 2925 "PRECISION"\001 +4 0 0 50 0 16 12 0.0000 4 135 645 4800 1950 "Circle"\001 +4 0 0 50 0 16 12 0.0000 4 165 870 6375 2925 "S_Circle"\001 +4 0 0 50 0 16 12 0.0000 4 135 660 5475 3900 "radius"\001 +4 0 0 50 0 16 12 0.0000 4 165 900 7425 3900 "m_radius"\001 +4 0 0 50 0 16 12 0.0000 4 135 555 9525 1950 "draw"\001 +4 0 0 50 0 16 12 0.0000 4 180 690 7800 1950 "Shape"\001 diff --git a/AspectC++/doc/images/JoinPointModel.pdf b/AspectC++/doc/images/JoinPointModel.pdf new file mode 100644 index 0000000..1265862 Binary files /dev/null and b/AspectC++/doc/images/JoinPointModel.pdf differ diff --git a/AspectC++/doc/images/JoinPointModelNew.eps b/AspectC++/doc/images/JoinPointModelNew.eps new file mode 100644 index 0000000..a48281f --- /dev/null +++ b/AspectC++/doc/images/JoinPointModelNew.eps @@ -0,0 +1,42576 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 901 473 +%%Pages: 0 +%%Creator: LibreOffice 5.0 +%%Title: none +%%CreationDate: none +%%LanguageLevel: 2 +%%EndComments +%%BeginProlog +%%BeginResource: procset SDRes-Prolog 1.0 0 +/b4_inc_state save def +/dict_count countdictstack def +/op_count count 1 sub def +userdict begin +0 setgray 0 setlinecap 1 setlinewidth 0 setlinejoin 10 setmiterlimit[] 0 setdash newpath +/languagelevel where {pop languagelevel 1 ne {false setstrokeadjust false setoverprint} if} if +/bdef {bind def} bind def +/c {setrgbcolor} bdef +/l {neg lineto} bdef +/rl {neg rlineto} bdef +/lc {setlinecap} bdef +/lj {setlinejoin} bdef +/lw {setlinewidth} bdef +/ml {setmiterlimit} bdef +/ld {setdash} bdef +/m {neg moveto} bdef +/ct {6 2 roll neg 6 2 roll neg 6 2 roll neg curveto} bdef +/r {rotate} bdef +/t {neg translate} bdef +/s {scale} bdef +/sw {show} bdef +/gs {gsave} bdef +/gr {grestore} bdef +/f {findfont dup length dict begin +{1 index /FID ne {def} {pop pop} ifelse} forall /Encoding ISOLatin1Encoding def +currentdict end /NFont exch definefont pop /NFont findfont} bdef +/p {closepath} bdef +/sf {scalefont setfont} bdef +/ef {eofill}bdef +/pc {closepath stroke}bdef +/ps {stroke}bdef +/pum {matrix currentmatrix}bdef +/pom {setmatrix}bdef +/bs {/aString exch def /nXOfs exch def /nWidth exch def currentpoint nXOfs 0 rmoveto pum nWidth aString stringwidth pop div 1 scale aString show pom moveto} bdef +%%EndResource +%%EndProlog +%%BeginSetup +%%EndSetup +%%Page: 1 1 +%%BeginPageSetup +%%EndPageSetup +pum +0.02834 0.02832 s +0 -16697 t +/tm matrix currentmatrix def +tm setmatrix +-1084 -1137 t +1 1 s +0.933 0.933 0.933 c 17472 9323 m 6995 9323 l 6995 1323 l 27948 1323 l +27948 9323 l 17472 9323 l p ef +1.000 1.000 1.000 c 9535 9831 m 6615 9831 l 6615 6586 l 12456 6586 l +12456 9831 l 9535 9831 l p ef +0 lw 1 lj 9535 9830 m 6614 9830 l 6614 6586 l 12456 6586 l 12456 9830 l +9535 9830 l pc +0.867 0.867 0.867 c 20203 8943 m 12837 8943 l 12837 6657 l 27568 6657 l +27568 8943 l 20203 8943 l p ef +1.000 1.000 1.000 c 22930 3243 m 17656 3243 l 17656 1264 l 28203 1264 l +28203 3243 l 22930 3243 l p ef +22929 3242 m 17655 3242 l 17655 1263 l 28203 1263 l 28203 3242 l 22929 3242 l +pc +[ 152 152 ] 0 ld +0.003 0.003 0.003 c 9881 7165 m 9881 5768 l ps +0.867 0.867 0.867 c 19723 6784 m 17246 6784 l 17246 3991 l 22199 3991 l +22199 6784 l 19723 6784 l p ef +1.000 1.000 1.000 c 25328 6275 m 22581 6275 l 22581 2847 l 28076 2847 l +28076 6275 l 25328 6275 l p ef +[ ] 0 ld +25328 6275 m 22580 6275 l 22580 2846 l 28076 2846 l 28076 6275 l 25328 6275 l +pc +8956 3540 m 5591 3540 l 5591 1138 l 12321 1138 l 12321 3540 l 8956 3540 l +p ef +8956 3539 m 5590 3539 l 5590 1137 l 12321 1137 l 12321 3539 l 8956 3539 l +pc +26 lw 0.003 0.003 0.003 c 11948 9127 m 12007 9127 12061 9123 12109 9115 ct ps +12250 9076 m 12300 9055 12343 9030 12380 9000 ct ps +12482 8889 m 12511 8848 12535 8803 12555 8756 ct ps +12609 8613 m 12625 8565 12639 8516 12654 8467 ct ps +12700 8323 m 12718 8274 12737 8226 12759 8182 ct ps +12841 8055 m 12873 8017 12909 7984 12952 7955 ct ps +13093 7891 m 13135 7878 13182 7868 13234 7863 ct ps +5056 6403 m 5114 6403 5169 6401 5222 6398 ct ps +5372 6385 m 5421 6379 5468 6371 5513 6363 ct ps +5667 6324 m 5715 6309 5760 6292 5802 6274 ct ps +5941 6202 m 5984 6176 6025 6148 6062 6118 ct ps +6176 6015 m 6212 5979 6246 5942 6278 5904 ct ps +6374 5787 m 6406 5748 6437 5708 6470 5669 ct ps +6570 5555 m 6604 5519 6640 5484 6679 5450 ct ps +6798 5359 m 6839 5332 6883 5307 6931 5283 ct ps +7067 5227 m 7113 5211 7162 5197 7214 5185 ct ps +7362 5157 m 7408 5150 7457 5145 7508 5141 ct ps +7668 5133 m 7686 5133 7704 5133 7723 5133 ct ps +17536 11667 m 17600 11667 17657 11661 17709 11650 ct ps +17847 11600 m 17890 11577 17927 11549 17959 11516 ct ps +18044 11392 m 18065 11346 18082 11296 18095 11241 ct ps +18116 11101 m 18120 11052 18122 11000 18122 10947 ct ps +18114 10786 m 18111 10739 18106 10691 18100 10642 ct ps +18079 10491 m 18071 10440 18062 10388 18052 10335 ct ps +18023 10185 m 18013 10136 18003 10087 17992 10037 ct ps +17960 9888 m 17948 9838 17937 9788 17926 9738 ct ps +17892 9587 m 17881 9537 17869 9487 17859 9437 ct ps +17827 9288 m 17816 9239 17806 9190 17797 9142 ct ps +17769 8987 m 17760 8935 17751 8883 17744 8833 ct ps +17726 8685 m 17721 8634 17717 8584 17715 8536 ct ps +17713 8374 m 17715 8323 17719 8273 17726 8226 ct ps +17760 8082 m 17777 8030 17799 7983 17827 7942 ct ps +17927 7835 m 17963 7808 18003 7786 18049 7769 ct ps +18204 7735 m 18233 7732 18265 7730 18298 7730 ct ps +17536 12936 m 17583 12936 17630 12936 17678 12936 ct ps +17823 12936 m 17872 12937 17922 12937 17972 12937 ct ps +18124 12938 m 18175 12938 18227 12938 18279 12938 ct ps +18436 12939 m 18489 12939 18543 12940 18597 12940 ct ps +18748 12940 m 18796 12941 18845 12941 18895 12941 ct ps +19044 12941 m 19094 12941 19144 12941 19195 12941 ct ps +19347 12941 m 19398 12941 19449 12941 19501 12941 ct ps +19656 12940 m 19708 12940 19760 12939 19813 12939 ct ps +19967 12937 m 20016 12937 20066 12936 20116 12936 ct ps +20266 12933 m 20316 12933 20367 12932 20417 12931 ct ps +20569 12928 m 20620 12927 20671 12926 20722 12924 ct ps +20875 12920 m 20926 12919 20977 12917 21029 12916 ct ps +21183 12910 m 21234 12909 21284 12907 21335 12905 ct ps +21487 12898 m 21538 12896 21588 12894 21639 12891 ct ps +21791 12884 m 21841 12881 21892 12878 21943 12875 ct ps +22095 12866 m 22145 12863 22196 12859 22247 12856 ct ps +22398 12845 m 22449 12841 22499 12838 22550 12834 ct ps +22703 12821 m 22754 12817 22805 12812 22856 12807 ct ps +23009 12793 m 23059 12788 23110 12782 23161 12777 ct ps +23312 12761 m 23362 12755 23413 12749 23463 12743 ct ps +23613 12724 m 23662 12718 23712 12711 23761 12704 ct ps +23908 12683 m 23960 12676 24012 12668 24063 12660 ct ps +24216 12635 m 24267 12627 24318 12618 24368 12609 ct ps +24519 12581 m 24569 12572 24619 12562 24668 12552 ct ps +24816 12523 m 24864 12512 24913 12502 24961 12491 ct ps +25105 12457 m 25155 12445 25205 12432 25255 12420 ct ps +25407 12379 m 25457 12365 25507 12351 25557 12337 ct ps +25704 12292 m 25753 12277 25801 12261 25848 12245 ct ps +25990 12197 m 26036 12180 26082 12163 26128 12146 ct ps +26263 12092 m 26313 12072 26362 12051 26410 12030 ct ps +26553 11964 m 26601 11942 26647 11919 26692 11896 ct ps +26826 11824 m 26870 11800 26913 11775 26956 11749 ct ps +27080 11671 m 27121 11644 27162 11617 27201 11588 ct ps +27328 11493 m 27369 11461 27409 11428 27447 11394 ct ps +27560 11290 m 27596 11254 27631 11218 27664 11181 ct ps +27762 11068 m 27793 11030 27822 10990 27851 10950 ct ps +27934 10824 m 27960 10781 27985 10737 28008 10692 ct ps +28073 10555 m 28093 10508 28112 10461 28129 10412 ct ps +28174 10264 m 28185 10224 28194 10184 28203 10143 ct 28205 10132 28208 10121 28210 10109 ct +ps +28243 9951 m 28253 9898 28263 9847 28274 9796 ct ps +28303 9647 m 28312 9598 28321 9549 28330 9502 ct ps +28356 9361 m 28365 9310 28374 9259 28383 9209 ct ps +28409 9052 m 28418 9001 28426 8950 28433 8900 ct ps +28455 8754 m 28461 8706 28468 8660 28474 8614 ct ps +28493 8455 m 28499 8402 28504 8350 28509 8300 ct ps +28522 8151 m 28525 8103 28528 8055 28531 8009 ct ps +28536 7849 m 28538 7797 28538 7746 28537 7696 ct ps +28533 7550 m 28530 7498 28527 7447 28522 7397 ct ps +28503 7244 m 28496 7195 28487 7147 28477 7100 ct ps +28441 6950 m 28427 6901 28411 6853 28394 6806 ct ps +28338 6667 m 28318 6621 28295 6576 28271 6531 ct ps +28194 6400 m 28168 6358 28140 6317 28111 6276 ct ps +28018 6155 m 27987 6116 27954 6078 27920 6039 ct ps +27820 5929 m 27785 5892 27749 5855 27712 5818 ct ps +27604 5713 m 27569 5679 27533 5645 27496 5611 ct ps +27382 5506 m 27360 5485 27337 5465 27314 5444 ct 27297 5429 27280 5413 27263 5398 ct +ps +27144 5298 m 27104 5266 27065 5235 27026 5205 ct ps +26905 5118 m 26862 5088 26819 5059 26776 5031 ct ps +26648 4953 m 26604 4927 26560 4903 26516 4880 ct ps +26379 4811 m 26333 4789 26288 4768 26243 4749 ct ps +26101 4691 m 26053 4673 26005 4656 25958 4640 ct ps +25814 4594 m 25765 4579 25716 4565 25668 4552 ct ps +25522 4514 m 25472 4502 25422 4490 25373 4478 ct ps +25225 4445 m 25176 4435 25126 4424 25077 4413 ct ps +24928 4381 m 24879 4370 24830 4359 24780 4348 ct ps +24633 4312 m 24584 4299 24535 4286 24486 4272 ct ps +24341 4229 m 24293 4213 24245 4197 24197 4179 ct ps +24057 4126 m 24010 4106 23963 4085 23917 4063 ct ps +23779 3993 m 23734 3969 23690 3944 23647 3919 ct ps +23517 3838 m 23474 3810 23432 3781 23392 3751 ct ps +23272 3659 m 23232 3625 23193 3591 23157 3557 ct ps +23050 3450 m 23015 3411 22982 3372 22953 3333 ct ps +22869 3204 m 22844 3157 22824 3111 22809 3066 ct ps +22785 2918 m 22785 2866 22795 2816 22817 2770 ct ps +22909 2652 m 22942 2623 22984 2596 23032 2572 ct ps +23180 2517 m 23223 2505 23270 2495 23321 2486 ct ps +12075 10397 m 12123 10431 12166 10466 12202 10503 ct ps +12297 10619 m 12324 10660 12346 10703 12363 10748 ct ps +12404 10894 m 12412 10944 12416 10995 12416 11048 ct ps +12408 11195 m 12403 11245 12395 11295 12385 11347 ct ps +12350 11497 m 12338 11545 12325 11593 12311 11642 ct ps +12267 11790 m 12252 11838 12237 11887 12222 11936 ct ps +12178 12082 m 12163 12131 12150 12180 12137 12229 ct ps +12101 12378 m 12091 12429 12081 12479 12074 12528 ct ps +12058 12677 m 12055 12729 12055 12780 12057 12830 ct ps +12075 12981 m 12084 13031 12097 13080 12114 13128 ct ps +12173 13261 m 12197 13304 12224 13347 12256 13389 ct ps +12361 13507 m 12392 13537 12427 13567 12464 13597 ct ps +12585 13684 m 12628 13712 12675 13740 12725 13767 ct ps +12865 13836 m 12905 13854 12946 13872 12989 13889 ct ps +13123 13940 m 13170 13957 13218 13973 13269 13989 ct ps +13426 14035 m 13481 14050 13537 14064 13596 14078 ct ps +13724 14107 m 13767 14117 13812 14126 13858 14134 ct ps +13999 14160 m 14047 14168 14097 14176 14147 14184 ct ps +14302 14206 m 14355 14213 14409 14219 14463 14226 ct ps +14631 14244 m 14685 14250 14739 14255 14794 14260 ct ps +14933 14272 m 14980 14276 15027 14280 15075 14283 ct ps +15220 14293 m 15269 14296 15319 14299 15369 14301 ct ps +15520 14309 m 15571 14311 15623 14314 15675 14316 ct ps +15833 14321 m 15885 14323 15939 14324 15993 14325 ct ps +16156 14328 m 16208 14329 16261 14330 16314 14330 ct ps +16458 14331 m 16506 14331 16555 14331 16604 14331 ct ps +16752 14331 m 16801 14330 16851 14330 16901 14329 ct ps +17052 14327 m 17102 14326 17153 14324 17204 14323 ct ps +17358 14319 m 17409 14317 17461 14316 17513 14314 ct ps +17670 14308 m 17722 14306 17775 14304 17827 14301 ct ps +17986 14294 m 18036 14291 18086 14288 18137 14286 ct ps +18285 14277 m 18334 14274 18384 14271 18434 14268 ct ps +18584 14258 m 18634 14254 18684 14251 18734 14247 ct ps +18885 14235 m 18936 14231 18986 14227 19037 14223 ct ps +19189 14210 m 19240 14206 19291 14201 19342 14196 ct ps +19496 14182 m 19547 14177 19598 14171 19650 14166 ct ps +19804 14150 m 19855 14144 19906 14139 19958 14133 ct ps +20108 14116 m 20158 14110 20208 14104 20258 14098 ct ps +20409 14079 m 20459 14073 20509 14067 20559 14060 ct ps +20710 14040 m 20760 14033 20811 14026 20861 14019 ct ps +21012 13997 m 21062 13990 21112 13983 21162 13975 ct ps +21313 13952 m 21363 13944 21413 13936 21463 13928 ct ps +21614 13903 m 21664 13895 21714 13887 21764 13878 ct ps +21914 13852 m 21965 13843 22015 13834 22066 13824 ct ps +22217 13796 m 22268 13787 22318 13777 22368 13767 ct ps +22519 13737 m 22569 13727 22619 13717 22669 13707 ct ps +22818 13676 m 22868 13665 22917 13654 22967 13643 ct ps +23115 13610 m 23164 13599 23213 13588 23262 13577 ct ps +23409 13542 m 23457 13530 23506 13518 23554 13506 ct ps +23699 13470 m 23749 13458 23798 13445 23846 13432 ct ps +23998 13392 m 24048 13378 24099 13364 24149 13350 ct ps +24298 13308 m 24348 13294 24397 13279 24446 13265 ct ps +24593 13221 m 24642 13206 24691 13191 24739 13176 ct ps +24883 13130 m 24931 13114 24979 13098 25026 13083 ct ps +25167 13035 m 25214 13018 25260 13002 25307 12986 ct ps +25445 12936 m 25492 12918 25539 12900 25586 12882 ct ps +25736 12825 m 25785 12805 25834 12785 25883 12765 ct ps +26028 12705 m 26076 12685 26123 12664 26170 12643 ct ps +26310 12581 m 26356 12559 26402 12538 26447 12517 ct ps +26582 12452 m 26626 12430 26670 12408 26714 12386 ct ps +26843 12318 m 26885 12295 26927 12272 26969 12249 ct ps +27103 12171 m 27150 12144 27196 12116 27242 12088 ct ps +27377 12002 m 27421 11974 27464 11945 27507 11915 ct ps +27632 11826 m 27674 11796 27714 11766 27753 11736 ct ps +27869 11643 m 27907 11612 27944 11581 27981 11549 ct ps +28087 11453 m 28123 11419 28158 11385 28193 11350 ct ps +28304 11233 m 28340 11193 28374 11153 28408 11113 ct ps +28503 10991 m 28534 10949 28563 10908 28591 10866 ct ps +28671 10739 m 28696 10696 28720 10652 28742 10609 ct ps +28805 10476 m 28817 10450 28828 10424 28838 10397 ct 28846 10376 28854 10356 28862 10335 ct +ps +28916 10185 m 28932 10135 28948 10085 28963 10036 ct ps +29005 9888 m 29017 9839 29029 9790 29040 9741 ct ps +29071 9596 m 29080 9548 29088 9500 29096 9452 ct ps +29116 9304 m 29122 9252 29127 9200 29132 9149 ct ps +29142 8995 m 29144 8944 29146 8893 29146 8842 ct ps +29146 8691 m 29145 8641 29143 8591 29140 8542 ct ps +29130 8393 m 29126 8342 29121 8291 29115 8240 ct ps +29095 8088 m 29088 8037 29080 7987 29071 7937 ct ps +29044 7788 m 29034 7738 29023 7689 29012 7640 ct ps +28978 7494 m 28965 7444 28952 7395 28939 7346 ct ps +28897 7198 m 28883 7149 28868 7100 28853 7052 ct ps +28807 6907 m 28791 6859 28775 6812 28758 6764 ct ps +28709 6623 m 28691 6574 28674 6526 28656 6478 ct ps +28602 6333 m 28584 6285 28565 6238 28547 6190 ct ps +28492 6049 m 28474 6002 28456 5956 28438 5910 ct ps +28383 5770 m 28364 5721 28345 5673 28326 5624 ct ps +28271 5480 m 28252 5432 28235 5384 28217 5337 ct ps +28166 5196 m 28150 5150 28134 5103 28118 5057 ct ps +28070 4909 m 28055 4858 28040 4809 28026 4759 ct ps +27987 4612 m 27975 4563 27964 4514 27954 4466 ct ps +27927 4323 m 27919 4270 27912 4219 27907 4168 ct ps +27896 4014 m 27894 3964 27893 3913 27895 3863 ct ps +27906 3714 m 27912 3665 27919 3616 27929 3567 ct ps +27966 3422 m 27981 3374 27998 3326 28017 3279 ct ps +28083 3139 m 28106 3094 28132 3051 28161 3007 ct ps +28242 2893 m 28271 2855 28302 2818 28335 2781 ct ps +28441 2670 m 28478 2634 28518 2597 28560 2561 ct ps +20422 4498 m 20422 3555 l ps +20422 3102 m 20264 3576 l 20580 3576 l 20422 3102 l p ef +14961 2975 m 14961 4046 l ps +14961 4498 m 15119 4025 l 14803 4025 l 14961 4498 l p ef +13691 3102 m 11302 4295 l ps +10897 4498 m 11392 4427 l 11250 4146 l 10897 4498 l p ef +16612 3102 m 18391 4252 l ps +18771 4498 m 18459 4109 l 18287 4373 l 18771 4498 l p ef +20357 5825 m 20357 6769 l ps +20357 7222 m 20515 6748 l 20199 6748 l 20357 7222 l p ef +18825 5768 m 16833 6986 l ps +16447 7222 m 16934 7110 l 16769 6840 l 16447 7222 l p ef +pum +12344 4123 t +62 -123 m 62 -109 63 -96 65 -85 ct 67 -73 70 -63 75 -54 ct 80 -46 86 -39 94 -35 ct +102 -30 111 -28 123 -28 ct 137 -28 149 -32 159 -39 ct 168 -47 174 -58 177 -74 ct +217 -74 l 216 -64 213 -54 209 -45 ct 204 -35 198 -27 190 -20 ct 183 -13 173 -7 162 -3 ct +151 2 138 4 124 4 ct 105 4 89 1 76 -6 ct 62 -12 51 -21 43 -32 ct 35 -44 29 -57 25 -72 ct +21 -87 20 -104 20 -122 ct 20 -138 21 -153 24 -165 ct 26 -178 30 -189 35 -198 ct +40 -207 45 -215 52 -221 ct 59 -228 66 -233 73 -237 ct 81 -241 89 -243 98 -245 ct +106 -247 115 -248 123 -248 ct 137 -248 149 -246 160 -242 ct 170 -238 180 -233 187 -227 ct +195 -220 201 -213 206 -204 ct 211 -195 214 -185 216 -175 ct 175 -172 l 173 -186 167 -196 159 -204 ct +150 -212 138 -216 122 -216 ct 111 -216 101 -214 94 -210 ct 86 -206 80 -201 75 -193 ct +70 -185 67 -176 65 -164 ct 63 -152 62 -139 62 -123 ct p ef +465 -122 m 465 -80 456 -48 437 -27 ct 418 -6 391 4 356 4 ct 339 4 324 1 310 -4 ct +297 -9 286 -17 277 -27 ct 267 -37 260 -51 256 -66 ct 251 -82 248 -101 248 -122 ct +248 -206 285 -248 357 -248 ct 376 -248 392 -245 406 -240 ct 419 -235 431 -227 439 -216 ct +448 -206 455 -193 459 -177 ct 463 -161 465 -143 465 -122 ct p +423 -122 m 423 -141 421 -157 418 -169 ct 415 -181 411 -191 406 -198 ct 400 -206 393 -211 385 -214 ct +377 -217 368 -218 358 -218 ct 347 -218 338 -216 330 -213 ct 321 -210 314 -205 309 -198 ct +303 -190 298 -180 295 -168 ct 292 -156 291 -141 291 -122 ct 291 -103 292 -88 296 -75 ct +299 -63 303 -53 309 -46 ct 315 -38 322 -33 330 -30 ct 337 -27 346 -26 355 -26 ct +365 -26 375 -27 383 -30 ct 392 -33 399 -38 404 -46 ct 410 -53 415 -63 418 -75 ct +421 -88 423 -103 423 -122 ct p ef +668 0 m 668 -154 l 668 -166 667 -175 665 -183 ct 664 -191 661 -198 657 -203 ct +653 -207 648 -211 642 -213 ct 635 -215 627 -216 618 -216 ct 608 -216 600 -214 592 -211 ct +584 -207 578 -203 572 -196 ct 567 -190 563 -182 560 -173 ct 557 -163 555 -153 555 -141 ct +555 0 l 515 0 l 515 -191 l 515 -196 515 -201 515 -207 ct 515 -212 515 -218 514 -223 ct +514 -228 514 -232 514 -236 ct 514 -239 514 -241 513 -243 ct 552 -243 l 552 -242 552 -240 552 -236 ct +552 -233 552 -229 553 -225 ct 553 -221 553 -217 553 -212 ct 553 -208 553 -204 553 -201 ct +554 -201 l 558 -208 562 -214 567 -220 ct 571 -226 577 -231 583 -235 ct 589 -239 596 -242 604 -244 ct +612 -246 621 -247 632 -247 ct 645 -247 657 -245 666 -242 ct 676 -239 684 -234 690 -227 ct +697 -220 701 -211 704 -200 ct 707 -189 708 -177 708 -162 ct 708 0 l 668 0 l +p ef +861 -1 m 855 0 849 2 842 3 ct 836 4 829 4 820 4 ct 788 4 772 -14 772 -51 ct 772 -213 l +744 -213 l 744 -242 l 774 -242 l 785 -297 l 812 -297 l 812 -242 l +857 -242 l 857 -213 l 812 -213 l 812 -60 l 812 -48 814 -40 818 -35 ct +822 -30 828 -28 838 -28 ct 842 -28 846 -28 849 -29 ct 853 -30 857 -30 861 -31 ct +861 -1 l p ef +957 4 m 932 4 914 -2 902 -15 ct 890 -28 884 -46 884 -69 ct 884 -85 887 -98 893 -108 ct +899 -118 907 -127 916 -132 ct 926 -138 937 -142 950 -145 ct 962 -147 975 -148 988 -148 ct +1043 -148 l 1043 -161 l 1043 -171 1042 -180 1039 -187 ct 1037 -194 1034 -200 1030 -204 ct +1026 -209 1020 -212 1014 -214 ct 1007 -216 999 -217 991 -217 ct 983 -217 976 -216 970 -215 ct +963 -214 958 -212 953 -209 ct 949 -206 945 -202 942 -197 ct 939 -192 937 -186 936 -178 ct +894 -182 l 896 -192 899 -201 903 -209 ct 907 -217 913 -224 921 -229 ct 928 -235 938 -240 950 -243 ct +961 -246 975 -248 992 -248 ct 1022 -248 1045 -241 1060 -227 ct 1076 -213 1083 -192 1083 -166 ct +1083 -61 l 1083 -49 1085 -40 1088 -34 ct 1091 -28 1097 -25 1106 -25 ct 1108 -25 1111 -25 1113 -26 ct +1115 -26 1117 -26 1119 -27 ct 1119 -2 l 1114 0 1109 1 1104 1 ct 1099 2 1094 2 1088 2 ct +1081 2 1074 1 1069 -1 ct 1063 -3 1059 -6 1055 -10 ct 1052 -14 1049 -20 1047 -26 ct +1046 -32 1044 -39 1044 -47 ct 1043 -47 l 1038 -39 1034 -32 1028 -26 ct 1023 -20 1017 -14 1010 -10 ct +1003 -5 996 -2 987 0 ct 978 3 968 4 957 4 ct p +966 -26 m 979 -26 990 -29 1000 -33 ct 1009 -38 1017 -44 1024 -51 ct 1030 -59 1035 -67 1038 -75 ct +1041 -84 1043 -92 1043 -100 ct 1043 -120 l 998 -120 l 989 -120 979 -119 970 -118 ct +961 -117 954 -114 947 -110 ct 940 -107 935 -101 931 -94 ct 927 -88 925 -79 925 -68 ct +925 -55 929 -44 936 -37 ct 943 -30 953 -26 966 -26 ct p ef +1149 -293 m 1149 -332 l 1189 -332 l 1189 -293 l 1149 -293 l p +1149 1 m 1149 -242 l 1189 -242 l 1189 1 l 1149 1 l p ef +1404 0 m 1404 -154 l 1404 -166 1403 -175 1401 -183 ct 1400 -191 1397 -198 1393 -203 ct +1389 -207 1384 -211 1378 -213 ct 1371 -215 1363 -216 1354 -216 ct 1344 -216 1336 -214 1328 -211 ct +1320 -207 1314 -203 1308 -196 ct 1303 -190 1299 -182 1296 -173 ct 1293 -163 1291 -153 1291 -141 ct +1291 0 l 1251 0 l 1251 -191 l 1251 -196 1251 -201 1251 -207 ct 1251 -212 1251 -218 1250 -223 ct +1250 -228 1250 -232 1250 -236 ct 1250 -239 1250 -241 1249 -243 ct 1288 -243 l +1288 -242 1288 -240 1288 -236 ct 1288 -233 1288 -229 1289 -225 ct 1289 -221 1289 -217 1289 -212 ct +1289 -208 1289 -204 1289 -201 ct 1290 -201 l 1294 -208 1298 -214 1303 -220 ct +1307 -226 1313 -231 1319 -235 ct 1325 -239 1332 -242 1340 -244 ct 1348 -246 1357 -247 1368 -247 ct +1381 -247 1393 -245 1402 -242 ct 1412 -239 1420 -234 1426 -227 ct 1433 -220 1437 -211 1440 -200 ct +1443 -189 1444 -177 1444 -162 ct 1444 0 l 1404 0 l p ef +1535 -113 m 1535 -100 1536 -89 1539 -78 ct 1541 -67 1545 -58 1551 -51 ct 1556 -43 1563 -37 1572 -33 ct +1580 -28 1591 -26 1603 -26 ct 1620 -26 1634 -30 1645 -37 ct 1655 -44 1662 -53 1666 -63 ct +1701 -53 l 1699 -47 1695 -40 1691 -33 ct 1686 -26 1680 -20 1672 -15 ct 1665 -9 1655 -5 1644 -1 ct +1632 2 1619 4 1603 4 ct 1567 4 1539 -7 1521 -28 ct 1502 -49 1493 -81 1493 -123 ct +1493 -146 1495 -165 1501 -181 ct 1507 -197 1514 -210 1524 -220 ct 1534 -230 1546 -237 1559 -241 ct +1572 -246 1586 -248 1601 -248 ct 1621 -248 1638 -245 1652 -238 ct 1666 -231 1677 -222 1685 -211 ct +1693 -199 1699 -185 1703 -170 ct 1706 -154 1708 -137 1708 -118 ct 1708 -113 l +1535 -113 l p +1666 -144 m 1664 -170 1657 -188 1647 -200 ct 1636 -212 1620 -218 1600 -218 ct +1594 -218 1587 -217 1579 -215 ct 1572 -213 1565 -209 1559 -203 ct 1552 -198 1547 -190 1543 -180 ct +1538 -171 1536 -159 1535 -144 ct 1666 -144 l p ef +1911 -38 m 1904 -23 1894 -12 1881 -5 ct 1869 2 1854 5 1835 5 ct 1805 5 1782 -5 1768 -26 ct +1753 -46 1746 -78 1746 -119 ct 1746 -204 1776 -246 1835 -246 ct 1854 -246 1869 -243 1881 -236 ct +1894 -229 1904 -219 1911 -204 ct 1911 -204 l 1911 -205 1911 -208 1911 -211 ct +1911 -214 1911 -218 1911 -221 ct 1911 -225 1911 -228 1911 -231 ct 1911 -234 1911 -236 1911 -238 ct +1911 -332 l 1951 -332 l 1951 -49 l 1951 -44 1951 -38 1951 -33 ct 1952 -27 1952 -22 1952 -18 ct +1952 -13 1952 -9 1952 -6 ct 1952 -3 1953 -1 1953 1 ct 1914 1 l 1914 -1 1914 -3 1913 -6 ct +1913 -9 1913 -12 1913 -15 ct 1912 -19 1912 -23 1912 -27 ct 1912 -31 1912 -34 1912 -38 ct +1911 -38 l p +1789 -121 m 1789 -104 1790 -90 1792 -78 ct 1794 -66 1797 -56 1802 -48 ct 1806 -41 1812 -35 1820 -31 ct +1827 -28 1835 -26 1846 -26 ct 1856 -26 1866 -28 1874 -31 ct 1882 -35 1889 -40 1894 -48 ct +1900 -55 1904 -66 1907 -78 ct 1910 -90 1911 -105 1911 -123 ct 1911 -140 1910 -155 1907 -167 ct +1904 -179 1900 -188 1894 -196 ct 1889 -203 1882 -208 1874 -211 ct 1866 -215 1857 -216 1846 -216 ct +1836 -216 1828 -214 1821 -211 ct 1814 -208 1808 -202 1803 -194 ct 1798 -187 1794 -177 1792 -165 ct +1790 -153 1789 -138 1789 -121 ct p ef +pom +pum +15064 3982 t +62 -123 m 62 -109 63 -96 65 -85 ct 67 -73 70 -63 75 -54 ct 80 -46 86 -39 94 -35 ct +102 -30 111 -28 123 -28 ct 137 -28 149 -32 159 -39 ct 168 -47 174 -58 177 -74 ct +217 -74 l 216 -64 213 -54 209 -45 ct 204 -35 198 -27 190 -20 ct 183 -13 173 -7 162 -3 ct +151 2 138 4 124 4 ct 105 4 89 1 76 -6 ct 62 -12 51 -21 43 -32 ct 35 -44 29 -57 25 -72 ct +21 -87 20 -104 20 -122 ct 20 -138 21 -153 24 -165 ct 26 -178 30 -189 35 -198 ct +40 -207 45 -215 52 -221 ct 59 -228 66 -233 73 -237 ct 81 -241 89 -243 98 -245 ct +106 -247 115 -248 123 -248 ct 137 -248 149 -246 160 -242 ct 170 -238 180 -233 187 -227 ct +195 -220 201 -213 206 -204 ct 211 -195 214 -185 216 -175 ct 175 -172 l 173 -186 167 -196 159 -204 ct +150 -212 138 -216 122 -216 ct 111 -216 101 -214 94 -210 ct 86 -206 80 -201 75 -193 ct +70 -185 67 -176 65 -164 ct 63 -152 62 -139 62 -123 ct p ef +465 -122 m 465 -80 456 -48 437 -27 ct 418 -6 391 4 356 4 ct 339 4 324 1 310 -4 ct +297 -9 286 -17 277 -27 ct 267 -37 260 -51 256 -66 ct 251 -82 248 -101 248 -122 ct +248 -206 285 -248 357 -248 ct 376 -248 392 -245 406 -240 ct 419 -235 431 -227 439 -216 ct +448 -206 455 -193 459 -177 ct 463 -161 465 -143 465 -122 ct p +423 -122 m 423 -141 421 -157 418 -169 ct 415 -181 411 -191 406 -198 ct 400 -206 393 -211 385 -214 ct +377 -217 368 -218 358 -218 ct 347 -218 338 -216 330 -213 ct 321 -210 314 -205 309 -198 ct +303 -190 298 -180 295 -168 ct 292 -156 291 -141 291 -122 ct 291 -103 292 -88 296 -75 ct +299 -63 303 -53 309 -46 ct 315 -38 322 -33 330 -30 ct 337 -27 346 -26 355 -26 ct +365 -26 375 -27 383 -30 ct 392 -33 399 -38 404 -46 ct 410 -53 415 -63 418 -75 ct +421 -88 423 -103 423 -122 ct p ef +668 0 m 668 -154 l 668 -166 667 -175 665 -183 ct 664 -191 661 -198 657 -203 ct +653 -207 648 -211 642 -213 ct 635 -215 627 -216 618 -216 ct 608 -216 600 -214 592 -211 ct +584 -207 578 -203 572 -196 ct 567 -190 563 -182 560 -173 ct 557 -163 555 -153 555 -141 ct +555 0 l 515 0 l 515 -191 l 515 -196 515 -201 515 -207 ct 515 -212 515 -218 514 -223 ct +514 -228 514 -232 514 -236 ct 514 -239 514 -241 513 -243 ct 552 -243 l 552 -242 552 -240 552 -236 ct +552 -233 552 -229 553 -225 ct 553 -221 553 -217 553 -212 ct 553 -208 553 -204 553 -201 ct +554 -201 l 558 -208 562 -214 567 -220 ct 571 -226 577 -231 583 -235 ct 589 -239 596 -242 604 -244 ct +612 -246 621 -247 632 -247 ct 645 -247 657 -245 666 -242 ct 676 -239 684 -234 690 -227 ct +697 -220 701 -211 704 -200 ct 707 -189 708 -177 708 -162 ct 708 0 l 668 0 l +p ef +861 -1 m 855 0 849 2 842 3 ct 836 4 829 4 820 4 ct 788 4 772 -14 772 -51 ct 772 -213 l +744 -213 l 744 -242 l 774 -242 l 785 -297 l 812 -297 l 812 -242 l +857 -242 l 857 -213 l 812 -213 l 812 -60 l 812 -48 814 -40 818 -35 ct +822 -30 828 -28 838 -28 ct 842 -28 846 -28 849 -29 ct 853 -30 857 -30 861 -31 ct +861 -1 l p ef +957 4 m 932 4 914 -2 902 -15 ct 890 -28 884 -46 884 -69 ct 884 -85 887 -98 893 -108 ct +899 -118 907 -127 916 -132 ct 926 -138 937 -142 950 -145 ct 962 -147 975 -148 988 -148 ct +1043 -148 l 1043 -161 l 1043 -171 1042 -180 1039 -187 ct 1037 -194 1034 -200 1030 -204 ct +1026 -209 1020 -212 1014 -214 ct 1007 -216 999 -217 991 -217 ct 983 -217 976 -216 970 -215 ct +963 -214 958 -212 953 -209 ct 949 -206 945 -202 942 -197 ct 939 -192 937 -186 936 -178 ct +894 -182 l 896 -192 899 -201 903 -209 ct 907 -217 913 -224 921 -229 ct 928 -235 938 -240 950 -243 ct +961 -246 975 -248 992 -248 ct 1022 -248 1045 -241 1060 -227 ct 1076 -213 1083 -192 1083 -166 ct +1083 -61 l 1083 -49 1085 -40 1088 -34 ct 1091 -28 1097 -25 1106 -25 ct 1108 -25 1111 -25 1113 -26 ct +1115 -26 1117 -26 1119 -27 ct 1119 -2 l 1114 0 1109 1 1104 1 ct 1099 2 1094 2 1088 2 ct +1081 2 1074 1 1069 -1 ct 1063 -3 1059 -6 1055 -10 ct 1052 -14 1049 -20 1047 -26 ct +1046 -32 1044 -39 1044 -47 ct 1043 -47 l 1038 -39 1034 -32 1028 -26 ct 1023 -20 1017 -14 1010 -10 ct +1003 -5 996 -2 987 0 ct 978 3 968 4 957 4 ct p +966 -26 m 979 -26 990 -29 1000 -33 ct 1009 -38 1017 -44 1024 -51 ct 1030 -59 1035 -67 1038 -75 ct +1041 -84 1043 -92 1043 -100 ct 1043 -120 l 998 -120 l 989 -120 979 -119 970 -118 ct +961 -117 954 -114 947 -110 ct 940 -107 935 -101 931 -94 ct 927 -88 925 -79 925 -68 ct +925 -55 929 -44 936 -37 ct 943 -30 953 -26 966 -26 ct p ef +1149 -293 m 1149 -332 l 1189 -332 l 1189 -293 l 1149 -293 l p +1149 1 m 1149 -242 l 1189 -242 l 1189 1 l 1149 1 l p ef +1404 0 m 1404 -154 l 1404 -166 1403 -175 1401 -183 ct 1400 -191 1397 -198 1393 -203 ct +1389 -207 1384 -211 1378 -213 ct 1371 -215 1363 -216 1354 -216 ct 1344 -216 1336 -214 1328 -211 ct +1320 -207 1314 -203 1308 -196 ct 1303 -190 1299 -182 1296 -173 ct 1293 -163 1291 -153 1291 -141 ct +1291 0 l 1251 0 l 1251 -191 l 1251 -196 1251 -201 1251 -207 ct 1251 -212 1251 -218 1250 -223 ct +1250 -228 1250 -232 1250 -236 ct 1250 -239 1250 -241 1249 -243 ct 1288 -243 l +1288 -242 1288 -240 1288 -236 ct 1288 -233 1288 -229 1289 -225 ct 1289 -221 1289 -217 1289 -212 ct +1289 -208 1289 -204 1289 -201 ct 1290 -201 l 1294 -208 1298 -214 1303 -220 ct +1307 -226 1313 -231 1319 -235 ct 1325 -239 1332 -242 1340 -244 ct 1348 -246 1357 -247 1368 -247 ct +1381 -247 1393 -245 1402 -242 ct 1412 -239 1420 -234 1426 -227 ct 1433 -220 1437 -211 1440 -200 ct +1443 -189 1444 -177 1444 -162 ct 1444 0 l 1404 0 l p ef +1535 -113 m 1535 -100 1536 -89 1539 -78 ct 1541 -67 1545 -58 1551 -51 ct 1556 -43 1563 -37 1572 -33 ct +1580 -28 1591 -26 1603 -26 ct 1620 -26 1634 -30 1645 -37 ct 1655 -44 1662 -53 1666 -63 ct +1701 -53 l 1699 -47 1695 -40 1691 -33 ct 1686 -26 1680 -20 1672 -15 ct 1665 -9 1655 -5 1644 -1 ct +1632 2 1619 4 1603 4 ct 1567 4 1539 -7 1521 -28 ct 1502 -49 1493 -81 1493 -123 ct +1493 -146 1495 -165 1501 -181 ct 1507 -197 1514 -210 1524 -220 ct 1534 -230 1546 -237 1559 -241 ct +1572 -246 1586 -248 1601 -248 ct 1621 -248 1638 -245 1652 -238 ct 1666 -231 1677 -222 1685 -211 ct +1693 -199 1699 -185 1703 -170 ct 1706 -154 1708 -137 1708 -118 ct 1708 -113 l +1535 -113 l p +1666 -144 m 1664 -170 1657 -188 1647 -200 ct 1636 -212 1620 -218 1600 -218 ct +1594 -218 1587 -217 1579 -215 ct 1572 -213 1565 -209 1559 -203 ct 1552 -198 1547 -190 1543 -180 ct +1538 -171 1536 -159 1535 -144 ct 1666 -144 l p ef +1911 -38 m 1904 -23 1894 -12 1881 -5 ct 1869 2 1854 5 1835 5 ct 1805 5 1782 -5 1768 -26 ct +1753 -46 1746 -78 1746 -119 ct 1746 -204 1776 -246 1835 -246 ct 1854 -246 1869 -243 1881 -236 ct +1894 -229 1904 -219 1911 -204 ct 1911 -204 l 1911 -205 1911 -208 1911 -211 ct +1911 -214 1911 -218 1911 -221 ct 1911 -225 1911 -228 1911 -231 ct 1911 -234 1911 -236 1911 -238 ct +1911 -332 l 1951 -332 l 1951 -49 l 1951 -44 1951 -38 1951 -33 ct 1952 -27 1952 -22 1952 -18 ct +1952 -13 1952 -9 1952 -6 ct 1952 -3 1953 -1 1953 1 ct 1914 1 l 1914 -1 1914 -3 1913 -6 ct +1913 -9 1913 -12 1913 -15 ct 1912 -19 1912 -23 1912 -27 ct 1912 -31 1912 -34 1912 -38 ct +1911 -38 l p +1789 -121 m 1789 -104 1790 -90 1792 -78 ct 1794 -66 1797 -56 1802 -48 ct 1806 -41 1812 -35 1820 -31 ct +1827 -28 1835 -26 1846 -26 ct 1856 -26 1866 -28 1874 -31 ct 1882 -35 1889 -40 1894 -48 ct +1900 -55 1904 -66 1907 -78 ct 1910 -90 1911 -105 1911 -123 ct 1911 -140 1910 -155 1907 -167 ct +1904 -179 1900 -188 1894 -196 ct 1889 -203 1882 -208 1874 -211 ct 1866 -215 1857 -216 1846 -216 ct +1836 -216 1828 -214 1821 -211 ct 1814 -208 1808 -202 1803 -194 ct 1798 -187 1794 -177 1792 -165 ct +1790 -153 1789 -138 1789 -121 ct p ef +pom +pum +17651 3769 t +62 -123 m 62 -109 63 -96 65 -85 ct 67 -73 70 -63 75 -54 ct 80 -46 86 -39 94 -35 ct +102 -30 111 -28 123 -28 ct 137 -28 149 -32 159 -39 ct 168 -47 174 -58 177 -74 ct +217 -74 l 216 -64 213 -54 209 -45 ct 204 -35 198 -27 190 -20 ct 183 -13 173 -7 162 -3 ct +151 2 138 4 124 4 ct 105 4 89 1 76 -6 ct 62 -12 51 -21 43 -32 ct 35 -44 29 -57 25 -72 ct +21 -87 20 -104 20 -122 ct 20 -138 21 -153 24 -165 ct 26 -178 30 -189 35 -198 ct +40 -207 45 -215 52 -221 ct 59 -228 66 -233 73 -237 ct 81 -241 89 -243 98 -245 ct +106 -247 115 -248 123 -248 ct 137 -248 149 -246 160 -242 ct 170 -238 180 -233 187 -227 ct +195 -220 201 -213 206 -204 ct 211 -195 214 -185 216 -175 ct 175 -172 l 173 -186 167 -196 159 -204 ct +150 -212 138 -216 122 -216 ct 111 -216 101 -214 94 -210 ct 86 -206 80 -201 75 -193 ct +70 -185 67 -176 65 -164 ct 63 -152 62 -139 62 -123 ct p ef +465 -122 m 465 -80 456 -48 437 -27 ct 418 -6 391 4 356 4 ct 339 4 324 1 310 -4 ct +297 -9 286 -17 277 -27 ct 267 -37 260 -51 256 -66 ct 251 -82 248 -101 248 -122 ct +248 -206 285 -248 357 -248 ct 376 -248 392 -245 406 -240 ct 419 -235 431 -227 439 -216 ct +448 -206 455 -193 459 -177 ct 463 -161 465 -143 465 -122 ct p +423 -122 m 423 -141 421 -157 418 -169 ct 415 -181 411 -191 406 -198 ct 400 -206 393 -211 385 -214 ct +377 -217 368 -218 358 -218 ct 347 -218 338 -216 330 -213 ct 321 -210 314 -205 309 -198 ct +303 -190 298 -180 295 -168 ct 292 -156 291 -141 291 -122 ct 291 -103 292 -88 296 -75 ct +299 -63 303 -53 309 -46 ct 315 -38 322 -33 330 -30 ct 337 -27 346 -26 355 -26 ct +365 -26 375 -27 383 -30 ct 392 -33 399 -38 404 -46 ct 410 -53 415 -63 418 -75 ct +421 -88 423 -103 423 -122 ct p ef +668 0 m 668 -154 l 668 -166 667 -175 665 -183 ct 664 -191 661 -198 657 -203 ct +653 -207 648 -211 642 -213 ct 635 -215 627 -216 618 -216 ct 608 -216 600 -214 592 -211 ct +584 -207 578 -203 572 -196 ct 567 -190 563 -182 560 -173 ct 557 -163 555 -153 555 -141 ct +555 0 l 515 0 l 515 -191 l 515 -196 515 -201 515 -207 ct 515 -212 515 -218 514 -223 ct +514 -228 514 -232 514 -236 ct 514 -239 514 -241 513 -243 ct 552 -243 l 552 -242 552 -240 552 -236 ct +552 -233 552 -229 553 -225 ct 553 -221 553 -217 553 -212 ct 553 -208 553 -204 553 -201 ct +554 -201 l 558 -208 562 -214 567 -220 ct 571 -226 577 -231 583 -235 ct 589 -239 596 -242 604 -244 ct +612 -246 621 -247 632 -247 ct 645 -247 657 -245 666 -242 ct 676 -239 684 -234 690 -227 ct +697 -220 701 -211 704 -200 ct 707 -189 708 -177 708 -162 ct 708 0 l 668 0 l +p ef +861 -1 m 855 0 849 2 842 3 ct 836 4 829 4 820 4 ct 788 4 772 -14 772 -51 ct 772 -213 l +744 -213 l 744 -242 l 774 -242 l 785 -297 l 812 -297 l 812 -242 l +857 -242 l 857 -213 l 812 -213 l 812 -60 l 812 -48 814 -40 818 -35 ct +822 -30 828 -28 838 -28 ct 842 -28 846 -28 849 -29 ct 853 -30 857 -30 861 -31 ct +861 -1 l p ef +957 4 m 932 4 914 -2 902 -15 ct 890 -28 884 -46 884 -69 ct 884 -85 887 -98 893 -108 ct +899 -118 907 -127 916 -132 ct 926 -138 937 -142 950 -145 ct 962 -147 975 -148 988 -148 ct +1043 -148 l 1043 -161 l 1043 -171 1042 -180 1039 -187 ct 1037 -194 1034 -200 1030 -204 ct +1026 -209 1020 -212 1014 -214 ct 1007 -216 999 -217 991 -217 ct 983 -217 976 -216 970 -215 ct +963 -214 958 -212 953 -209 ct 949 -206 945 -202 942 -197 ct 939 -192 937 -186 936 -178 ct +894 -182 l 896 -192 899 -201 903 -209 ct 907 -217 913 -224 921 -229 ct 928 -235 938 -240 950 -243 ct +961 -246 975 -248 992 -248 ct 1022 -248 1045 -241 1060 -227 ct 1076 -213 1083 -192 1083 -166 ct +1083 -61 l 1083 -49 1085 -40 1088 -34 ct 1091 -28 1097 -25 1106 -25 ct 1108 -25 1111 -25 1113 -26 ct +1115 -26 1117 -26 1119 -27 ct 1119 -2 l 1114 0 1109 1 1104 1 ct 1099 2 1094 2 1088 2 ct +1081 2 1074 1 1069 -1 ct 1063 -3 1059 -6 1055 -10 ct 1052 -14 1049 -20 1047 -26 ct +1046 -32 1044 -39 1044 -47 ct 1043 -47 l 1038 -39 1034 -32 1028 -26 ct 1023 -20 1017 -14 1010 -10 ct +1003 -5 996 -2 987 0 ct 978 3 968 4 957 4 ct p +966 -26 m 979 -26 990 -29 1000 -33 ct 1009 -38 1017 -44 1024 -51 ct 1030 -59 1035 -67 1038 -75 ct +1041 -84 1043 -92 1043 -100 ct 1043 -120 l 998 -120 l 989 -120 979 -119 970 -118 ct +961 -117 954 -114 947 -110 ct 940 -107 935 -101 931 -94 ct 927 -88 925 -79 925 -68 ct +925 -55 929 -44 936 -37 ct 943 -30 953 -26 966 -26 ct p ef +1149 -293 m 1149 -332 l 1189 -332 l 1189 -293 l 1149 -293 l p +1149 1 m 1149 -242 l 1189 -242 l 1189 1 l 1149 1 l p ef +1404 0 m 1404 -154 l 1404 -166 1403 -175 1401 -183 ct 1400 -191 1397 -198 1393 -203 ct +1389 -207 1384 -211 1378 -213 ct 1371 -215 1363 -216 1354 -216 ct 1344 -216 1336 -214 1328 -211 ct +1320 -207 1314 -203 1308 -196 ct 1303 -190 1299 -182 1296 -173 ct 1293 -163 1291 -153 1291 -141 ct +1291 0 l 1251 0 l 1251 -191 l 1251 -196 1251 -201 1251 -207 ct 1251 -212 1251 -218 1250 -223 ct +1250 -228 1250 -232 1250 -236 ct 1250 -239 1250 -241 1249 -243 ct 1288 -243 l +1288 -242 1288 -240 1288 -236 ct 1288 -233 1288 -229 1289 -225 ct 1289 -221 1289 -217 1289 -212 ct +1289 -208 1289 -204 1289 -201 ct 1290 -201 l 1294 -208 1298 -214 1303 -220 ct +1307 -226 1313 -231 1319 -235 ct 1325 -239 1332 -242 1340 -244 ct 1348 -246 1357 -247 1368 -247 ct +1381 -247 1393 -245 1402 -242 ct 1412 -239 1420 -234 1426 -227 ct 1433 -220 1437 -211 1440 -200 ct +1443 -189 1444 -177 1444 -162 ct 1444 0 l 1404 0 l p ef +1535 -113 m 1535 -100 1536 -89 1539 -78 ct 1541 -67 1545 -58 1551 -51 ct 1556 -43 1563 -37 1572 -33 ct +1580 -28 1591 -26 1603 -26 ct 1620 -26 1634 -30 1645 -37 ct 1655 -44 1662 -53 1666 -63 ct +1701 -53 l 1699 -47 1695 -40 1691 -33 ct 1686 -26 1680 -20 1672 -15 ct 1665 -9 1655 -5 1644 -1 ct +1632 2 1619 4 1603 4 ct 1567 4 1539 -7 1521 -28 ct 1502 -49 1493 -81 1493 -123 ct +1493 -146 1495 -165 1501 -181 ct 1507 -197 1514 -210 1524 -220 ct 1534 -230 1546 -237 1559 -241 ct +1572 -246 1586 -248 1601 -248 ct 1621 -248 1638 -245 1652 -238 ct 1666 -231 1677 -222 1685 -211 ct +1693 -199 1699 -185 1703 -170 ct 1706 -154 1708 -137 1708 -118 ct 1708 -113 l +1535 -113 l p +1666 -144 m 1664 -170 1657 -188 1647 -200 ct 1636 -212 1620 -218 1600 -218 ct +1594 -218 1587 -217 1579 -215 ct 1572 -213 1565 -209 1559 -203 ct 1552 -198 1547 -190 1543 -180 ct +1538 -171 1536 -159 1535 -144 ct 1666 -144 l p ef +1911 -38 m 1904 -23 1894 -12 1881 -5 ct 1869 2 1854 5 1835 5 ct 1805 5 1782 -5 1768 -26 ct +1753 -46 1746 -78 1746 -119 ct 1746 -204 1776 -246 1835 -246 ct 1854 -246 1869 -243 1881 -236 ct +1894 -229 1904 -219 1911 -204 ct 1911 -204 l 1911 -205 1911 -208 1911 -211 ct +1911 -214 1911 -218 1911 -221 ct 1911 -225 1911 -228 1911 -231 ct 1911 -234 1911 -236 1911 -238 ct +1911 -332 l 1951 -332 l 1951 -49 l 1951 -44 1951 -38 1951 -33 ct 1952 -27 1952 -22 1952 -18 ct +1952 -13 1952 -9 1952 -6 ct 1952 -3 1953 -1 1953 1 ct 1914 1 l 1914 -1 1914 -3 1913 -6 ct +1913 -9 1913 -12 1913 -15 ct 1912 -19 1912 -23 1912 -27 ct 1912 -31 1912 -34 1912 -38 ct +1911 -38 l p +1789 -121 m 1789 -104 1790 -90 1792 -78 ct 1794 -66 1797 -56 1802 -48 ct 1806 -41 1812 -35 1820 -31 ct +1827 -28 1835 -26 1846 -26 ct 1856 -26 1866 -28 1874 -31 ct 1882 -35 1889 -40 1894 -48 ct +1900 -55 1904 -66 1907 -78 ct 1910 -90 1911 -105 1911 -123 ct 1911 -140 1910 -155 1907 -167 ct +1904 -179 1900 -188 1894 -196 ct 1889 -203 1882 -208 1874 -211 ct 1866 -215 1857 -216 1846 -216 ct +1836 -216 1828 -214 1821 -211 ct 1814 -208 1808 -202 1803 -194 ct 1798 -187 1794 -177 1792 -165 ct +1790 -153 1789 -138 1789 -121 ct p ef +pom +pum +20545 4150 t +236 -122 m 236 -37 206 5 147 5 ct 128 5 113 2 101 -5 ct 89 -12 79 -22 71 -37 ct +71 -37 l 71 -33 71 -29 70 -25 ct 70 -21 70 -17 70 -13 ct 70 -10 69 -7 69 -4 ct +69 -2 69 0 69 1 ct 30 1 l 30 -1 30 -3 30 -6 ct 30 -9 30 -13 30 -18 ct 31 -22 31 -27 31 -33 ct +31 -38 31 -44 31 -49 ct 31 -332 l 71 -332 l 71 -237 l 71 -233 71 -228 71 -224 ct +71 -220 71 -216 71 -213 ct 71 -210 71 -206 70 -203 ct 71 -203 l 79 -218 89 -229 101 -236 ct +113 -243 129 -246 147 -246 ct 177 -246 200 -236 214 -215 ct 229 -195 236 -163 236 -122 ct +p +194 -120 m 194 -137 193 -151 191 -163 ct 188 -175 185 -185 180 -193 ct 176 -200 170 -206 163 -210 ct +156 -213 147 -215 136 -215 ct 126 -215 117 -213 108 -210 ct 100 -206 93 -201 88 -193 ct +83 -186 78 -176 76 -163 ct 73 -151 71 -136 71 -118 ct 71 -101 73 -86 76 -74 ct +78 -62 83 -53 88 -46 ct 93 -38 100 -33 108 -30 ct 116 -26 126 -25 136 -25 ct 146 -25 154 -27 162 -30 ct +169 -33 175 -39 180 -47 ct 184 -54 188 -64 190 -76 ct 192 -88 194 -103 194 -120 ct +p ef +347 4 m 322 4 304 -2 292 -15 ct 280 -28 274 -46 274 -69 ct 274 -85 277 -98 283 -108 ct +289 -118 297 -127 306 -132 ct 316 -138 327 -142 340 -145 ct 352 -147 365 -148 378 -148 ct +433 -148 l 433 -161 l 433 -171 432 -180 429 -187 ct 427 -194 424 -200 420 -204 ct +416 -209 410 -212 404 -214 ct 397 -216 389 -217 381 -217 ct 373 -217 366 -216 360 -215 ct +353 -214 348 -212 343 -209 ct 339 -206 335 -202 332 -197 ct 329 -192 327 -186 326 -178 ct +284 -182 l 286 -192 289 -201 293 -209 ct 297 -217 303 -224 311 -229 ct 318 -235 328 -240 340 -243 ct +351 -246 365 -248 382 -248 ct 412 -248 435 -241 450 -227 ct 466 -213 473 -192 473 -166 ct +473 -61 l 473 -49 475 -40 478 -34 ct 481 -28 487 -25 496 -25 ct 498 -25 501 -25 503 -26 ct +505 -26 507 -26 509 -27 ct 509 -2 l 504 0 499 1 494 1 ct 489 2 484 2 478 2 ct +471 2 464 1 459 -1 ct 453 -3 449 -6 445 -10 ct 442 -14 439 -20 437 -26 ct 436 -32 434 -39 434 -47 ct +433 -47 l 428 -39 424 -32 418 -26 ct 413 -20 407 -14 400 -10 ct 393 -5 386 -2 377 0 ct +368 3 358 4 347 4 ct p +356 -26 m 369 -26 380 -29 390 -33 ct 399 -38 407 -44 414 -51 ct 420 -59 425 -67 428 -75 ct +431 -84 433 -92 433 -100 ct 433 -120 l 388 -120 l 379 -120 369 -119 360 -118 ct +351 -117 344 -114 337 -110 ct 330 -107 325 -101 321 -94 ct 317 -88 315 -79 315 -68 ct +315 -55 319 -44 326 -37 ct 333 -30 343 -26 356 -26 ct p ef +721 -68 m 721 -56 719 -46 714 -37 ct 710 -28 704 -21 695 -15 ct 687 -9 677 -4 664 -1 ct +652 2 638 4 623 4 ct 608 4 596 3 585 1 ct 573 -1 563 -5 555 -10 ct 546 -14 539 -21 533 -29 ct +528 -36 523 -46 521 -57 ct 556 -64 l 560 -51 567 -42 578 -36 ct 588 -30 603 -27 623 -27 ct +631 -27 639 -27 646 -29 ct 654 -30 660 -32 665 -35 ct 670 -38 674 -41 677 -46 ct +680 -51 682 -57 682 -64 ct 682 -72 680 -78 677 -82 ct 673 -87 668 -91 662 -94 ct +656 -97 649 -100 640 -102 ct 631 -105 622 -107 611 -110 ct 601 -113 592 -116 582 -119 ct +573 -122 564 -126 556 -131 ct 549 -136 542 -143 538 -150 ct 533 -158 530 -168 530 -179 ct +530 -201 538 -218 554 -230 ct 570 -241 593 -247 623 -247 ct 650 -247 671 -242 687 -233 ct +703 -223 712 -208 717 -188 ct 680 -183 l 679 -189 677 -195 673 -199 ct 669 -203 665 -207 660 -209 ct +655 -212 649 -214 643 -215 ct 636 -216 630 -217 623 -217 ct 605 -217 591 -214 583 -208 ct +574 -203 570 -194 570 -183 ct 570 -177 571 -171 574 -167 ct 578 -163 582 -159 588 -156 ct +594 -153 601 -151 609 -148 ct 617 -146 626 -144 635 -142 ct 642 -140 648 -138 655 -136 ct +662 -134 668 -132 675 -130 ct 681 -127 687 -124 693 -120 ct 698 -117 703 -113 707 -108 ct +711 -103 715 -97 717 -90 ct 720 -84 721 -76 721 -68 ct p ef +799 -113 m 799 -100 800 -89 803 -78 ct 805 -67 809 -58 815 -51 ct 820 -43 827 -37 836 -33 ct +844 -28 855 -26 867 -26 ct 884 -26 898 -30 909 -37 ct 919 -44 926 -53 930 -63 ct +965 -53 l 963 -47 959 -40 955 -33 ct 950 -26 944 -20 936 -15 ct 929 -9 919 -5 908 -1 ct +896 2 883 4 867 4 ct 831 4 803 -7 785 -28 ct 766 -49 757 -81 757 -123 ct 757 -146 759 -165 765 -181 ct +771 -197 778 -210 788 -220 ct 798 -230 810 -237 823 -241 ct 836 -246 850 -248 865 -248 ct +885 -248 902 -245 916 -238 ct 930 -231 941 -222 949 -211 ct 957 -199 963 -185 967 -170 ct +970 -154 972 -137 972 -118 ct 972 -113 l 799 -113 l p +930 -144 m 928 -170 921 -188 911 -200 ct 900 -212 884 -218 864 -218 ct 858 -218 851 -217 843 -215 ct +836 -213 829 -209 823 -203 ct 816 -198 811 -190 807 -180 ct 802 -171 800 -159 799 -144 ct +930 -144 l p ef +1180 -123 m 1180 -109 1181 -96 1183 -85 ct 1185 -73 1188 -63 1193 -54 ct 1198 -46 1204 -39 1212 -35 ct +1220 -30 1229 -28 1241 -28 ct 1255 -28 1267 -32 1277 -39 ct 1286 -47 1292 -58 1295 -74 ct +1335 -74 l 1334 -64 1331 -54 1327 -45 ct 1322 -35 1316 -27 1308 -20 ct 1301 -13 1291 -7 1280 -3 ct +1269 2 1256 4 1242 4 ct 1223 4 1207 1 1194 -6 ct 1180 -12 1169 -21 1161 -32 ct +1153 -44 1147 -57 1143 -72 ct 1139 -87 1138 -104 1138 -122 ct 1138 -138 1139 -153 1142 -165 ct +1144 -178 1148 -189 1153 -198 ct 1158 -207 1163 -215 1170 -221 ct 1177 -228 1184 -233 1191 -237 ct +1199 -241 1207 -243 1216 -245 ct 1224 -247 1233 -248 1241 -248 ct 1255 -248 1267 -246 1278 -242 ct +1288 -238 1298 -233 1305 -227 ct 1313 -220 1319 -213 1324 -204 ct 1329 -195 1332 -185 1334 -175 ct +1293 -172 l 1291 -186 1285 -196 1277 -204 ct 1268 -212 1256 -216 1240 -216 ct +1229 -216 1219 -214 1212 -210 ct 1204 -206 1198 -201 1193 -193 ct 1188 -185 1185 -176 1183 -164 ct +1181 -152 1180 -139 1180 -123 ct p ef +1377 1 m 1377 -332 l 1417 -332 l 1417 1 l 1377 1 l p ef +1541 4 m 1516 4 1498 -2 1486 -15 ct 1474 -28 1468 -46 1468 -69 ct 1468 -85 1471 -98 1477 -108 ct +1483 -118 1491 -127 1500 -132 ct 1510 -138 1521 -142 1534 -145 ct 1546 -147 1559 -148 1572 -148 ct +1627 -148 l 1627 -161 l 1627 -171 1626 -180 1623 -187 ct 1621 -194 1618 -200 1614 -204 ct +1610 -209 1604 -212 1598 -214 ct 1591 -216 1583 -217 1575 -217 ct 1567 -217 1560 -216 1554 -215 ct +1547 -214 1542 -212 1537 -209 ct 1533 -206 1529 -202 1526 -197 ct 1523 -192 1521 -186 1520 -178 ct +1478 -182 l 1480 -192 1483 -201 1487 -209 ct 1491 -217 1497 -224 1505 -229 ct +1512 -235 1522 -240 1534 -243 ct 1545 -246 1559 -248 1576 -248 ct 1606 -248 1629 -241 1644 -227 ct +1660 -213 1667 -192 1667 -166 ct 1667 -61 l 1667 -49 1669 -40 1672 -34 ct 1675 -28 1681 -25 1690 -25 ct +1692 -25 1695 -25 1697 -26 ct 1699 -26 1701 -26 1703 -27 ct 1703 -2 l 1698 0 1693 1 1688 1 ct +1683 2 1678 2 1672 2 ct 1665 2 1658 1 1653 -1 ct 1647 -3 1643 -6 1639 -10 ct 1636 -14 1633 -20 1631 -26 ct +1630 -32 1628 -39 1628 -47 ct 1627 -47 l 1622 -39 1618 -32 1612 -26 ct 1607 -20 1601 -14 1594 -10 ct +1587 -5 1580 -2 1571 0 ct 1562 3 1552 4 1541 4 ct p +1550 -26 m 1563 -26 1574 -29 1584 -33 ct 1593 -38 1601 -44 1608 -51 ct 1614 -59 1619 -67 1622 -75 ct +1625 -84 1627 -92 1627 -100 ct 1627 -120 l 1582 -120 l 1573 -120 1563 -119 1554 -118 ct +1545 -117 1538 -114 1531 -110 ct 1524 -107 1519 -101 1515 -94 ct 1511 -88 1509 -79 1509 -68 ct +1509 -55 1513 -44 1520 -37 ct 1527 -30 1537 -26 1550 -26 ct p ef +1915 -68 m 1915 -56 1913 -46 1908 -37 ct 1904 -28 1898 -21 1889 -15 ct 1881 -9 1871 -4 1858 -1 ct +1846 2 1832 4 1817 4 ct 1802 4 1790 3 1779 1 ct 1767 -1 1757 -5 1749 -10 ct 1740 -14 1733 -21 1727 -29 ct +1722 -36 1717 -46 1715 -57 ct 1750 -64 l 1754 -51 1761 -42 1772 -36 ct 1782 -30 1797 -27 1817 -27 ct +1825 -27 1833 -27 1840 -29 ct 1848 -30 1854 -32 1859 -35 ct 1864 -38 1868 -41 1871 -46 ct +1874 -51 1876 -57 1876 -64 ct 1876 -72 1874 -78 1871 -82 ct 1867 -87 1862 -91 1856 -94 ct +1850 -97 1843 -100 1834 -102 ct 1825 -105 1816 -107 1805 -110 ct 1795 -113 1786 -116 1776 -119 ct +1767 -122 1758 -126 1750 -131 ct 1743 -136 1736 -143 1732 -150 ct 1727 -158 1724 -168 1724 -179 ct +1724 -201 1732 -218 1748 -230 ct 1764 -241 1787 -247 1817 -247 ct 1844 -247 1865 -242 1881 -233 ct +1897 -223 1906 -208 1911 -188 ct 1874 -183 l 1873 -189 1871 -195 1867 -199 ct +1863 -203 1859 -207 1854 -209 ct 1849 -212 1843 -214 1837 -215 ct 1830 -216 1824 -217 1817 -217 ct +1799 -217 1785 -214 1777 -208 ct 1768 -203 1764 -194 1764 -183 ct 1764 -177 1765 -171 1768 -167 ct +1772 -163 1776 -159 1782 -156 ct 1788 -153 1795 -151 1803 -148 ct 1811 -146 1820 -144 1829 -142 ct +1836 -140 1842 -138 1849 -136 ct 1856 -134 1862 -132 1869 -130 ct 1875 -127 1881 -124 1887 -120 ct +1892 -117 1897 -113 1901 -108 ct 1905 -103 1909 -97 1911 -90 ct 1914 -84 1915 -76 1915 -68 ct +p ef +2143 -68 m 2143 -56 2141 -46 2136 -37 ct 2132 -28 2126 -21 2117 -15 ct 2109 -9 2099 -4 2086 -1 ct +2074 2 2060 4 2045 4 ct 2030 4 2018 3 2007 1 ct 1995 -1 1985 -5 1977 -10 ct 1968 -14 1961 -21 1955 -29 ct +1950 -36 1945 -46 1943 -57 ct 1978 -64 l 1982 -51 1989 -42 2000 -36 ct 2010 -30 2025 -27 2045 -27 ct +2053 -27 2061 -27 2068 -29 ct 2076 -30 2082 -32 2087 -35 ct 2092 -38 2096 -41 2099 -46 ct +2102 -51 2104 -57 2104 -64 ct 2104 -72 2102 -78 2099 -82 ct 2095 -87 2090 -91 2084 -94 ct +2078 -97 2071 -100 2062 -102 ct 2053 -105 2044 -107 2033 -110 ct 2023 -113 2014 -116 2004 -119 ct +1995 -122 1986 -126 1978 -131 ct 1971 -136 1964 -143 1960 -150 ct 1955 -158 1952 -168 1952 -179 ct +1952 -201 1960 -218 1976 -230 ct 1992 -241 2015 -247 2045 -247 ct 2072 -247 2093 -242 2109 -233 ct +2125 -223 2134 -208 2139 -188 ct 2102 -183 l 2101 -189 2099 -195 2095 -199 ct +2091 -203 2087 -207 2082 -209 ct 2077 -212 2071 -214 2065 -215 ct 2058 -216 2052 -217 2045 -217 ct +2027 -217 2013 -214 2005 -208 ct 1996 -203 1992 -194 1992 -183 ct 1992 -177 1993 -171 1996 -167 ct +2000 -163 2004 -159 2010 -156 ct 2016 -153 2023 -151 2031 -148 ct 2039 -146 2048 -144 2057 -142 ct +2064 -140 2070 -138 2077 -136 ct 2084 -134 2090 -132 2097 -130 ct 2103 -127 2109 -124 2115 -120 ct +2120 -117 2125 -113 2129 -108 ct 2133 -103 2137 -97 2139 -90 ct 2142 -84 2143 -76 2143 -68 ct +p ef +pom +pum +18324 6421 t +172 0 m 172 -154 l 172 -166 171 -175 170 -183 ct 168 -191 166 -198 162 -203 ct +159 -207 154 -211 149 -213 ct 143 -215 136 -216 128 -216 ct 119 -216 112 -214 105 -211 ct +98 -207 92 -203 87 -196 ct 82 -190 78 -182 76 -173 ct 73 -163 72 -153 72 -141 ct +72 0 l 32 0 l 32 -191 l 32 -196 32 -201 32 -207 ct 32 -212 32 -218 31 -223 ct +31 -228 31 -232 31 -236 ct 31 -239 31 -241 30 -243 ct 69 -243 l 69 -242 69 -240 69 -236 ct +69 -233 69 -229 70 -225 ct 70 -221 70 -217 70 -212 ct 70 -208 70 -204 70 -201 ct +71 -201 l 75 -208 79 -214 83 -220 ct 87 -226 92 -231 97 -235 ct 103 -239 109 -242 117 -244 ct +124 -246 132 -247 142 -247 ct 160 -247 175 -243 185 -236 ct 196 -229 204 -217 208 -201 ct +208 -201 l 212 -208 216 -214 221 -220 ct 225 -226 230 -231 236 -235 ct 242 -239 249 -242 256 -244 ct +264 -246 272 -247 282 -247 ct 294 -247 305 -245 314 -242 ct 323 -239 330 -234 336 -227 ct +341 -220 345 -211 348 -200 ct 351 -189 352 -177 352 -162 ct 352 0 l 312 0 l +312 -154 l 312 -166 311 -175 310 -183 ct 308 -191 306 -198 302 -203 ct 299 -207 294 -211 289 -213 ct +283 -215 276 -216 268 -216 ct 259 -216 252 -214 245 -211 ct 238 -208 232 -203 227 -197 ct +222 -191 219 -183 216 -173 ct 213 -164 212 -153 212 -141 ct 212 0 l 172 0 l +p ef +443 -113 m 443 -100 444 -89 447 -78 ct 449 -67 453 -58 459 -51 ct 464 -43 471 -37 480 -33 ct +488 -28 499 -26 511 -26 ct 528 -26 542 -30 553 -37 ct 563 -44 570 -53 574 -63 ct +609 -53 l 607 -47 603 -40 599 -33 ct 594 -26 588 -20 580 -15 ct 573 -9 563 -5 552 -1 ct +540 2 527 4 511 4 ct 475 4 447 -7 429 -28 ct 410 -49 401 -81 401 -123 ct 401 -146 403 -165 409 -181 ct +415 -197 422 -210 432 -220 ct 442 -230 454 -237 467 -241 ct 480 -246 494 -248 509 -248 ct +529 -248 546 -245 560 -238 ct 574 -231 585 -222 593 -211 ct 601 -199 607 -185 611 -170 ct +614 -154 616 -137 616 -118 ct 616 -113 l 443 -113 l p +574 -144 m 572 -170 565 -188 555 -200 ct 544 -212 528 -218 508 -218 ct 502 -218 495 -217 487 -215 ct +480 -213 473 -209 467 -203 ct 460 -198 455 -190 451 -180 ct 446 -171 444 -159 443 -144 ct +574 -144 l p ef +807 0 m 807 -154 l 807 -166 806 -175 805 -183 ct 803 -191 801 -198 797 -203 ct +794 -207 789 -211 784 -213 ct 778 -215 771 -216 763 -216 ct 754 -216 747 -214 740 -211 ct +733 -207 727 -203 722 -196 ct 717 -190 713 -182 711 -173 ct 708 -163 707 -153 707 -141 ct +707 0 l 667 0 l 667 -191 l 667 -196 667 -201 667 -207 ct 667 -212 667 -218 666 -223 ct +666 -228 666 -232 666 -236 ct 666 -239 666 -241 665 -243 ct 704 -243 l 704 -242 704 -240 704 -236 ct +704 -233 704 -229 705 -225 ct 705 -221 705 -217 705 -212 ct 705 -208 705 -204 705 -201 ct +706 -201 l 710 -208 714 -214 718 -220 ct 722 -226 727 -231 732 -235 ct 738 -239 744 -242 752 -244 ct +759 -246 767 -247 777 -247 ct 795 -247 810 -243 820 -236 ct 831 -229 839 -217 843 -201 ct +843 -201 l 847 -208 851 -214 856 -220 ct 860 -226 865 -231 871 -235 ct 877 -239 884 -242 891 -244 ct +899 -246 907 -247 917 -247 ct 929 -247 940 -245 949 -242 ct 958 -239 965 -234 971 -227 ct +976 -220 980 -211 983 -200 ct 986 -189 987 -177 987 -162 ct 987 0 l 947 0 l +947 -154 l 947 -166 946 -175 945 -183 ct 943 -191 941 -198 937 -203 ct 934 -207 929 -211 924 -213 ct +918 -215 911 -216 903 -216 ct 894 -216 887 -214 880 -211 ct 873 -208 867 -203 862 -197 ct +857 -191 854 -183 851 -173 ct 848 -164 847 -153 847 -141 ct 847 0 l 807 0 l +p ef +1252 -122 m 1252 -37 1222 5 1163 5 ct 1144 5 1129 2 1117 -5 ct 1105 -12 1095 -22 1087 -37 ct +1087 -37 l 1087 -33 1087 -29 1086 -25 ct 1086 -21 1086 -17 1086 -13 ct 1086 -10 1085 -7 1085 -4 ct +1085 -2 1085 0 1085 1 ct 1046 1 l 1046 -1 1046 -3 1046 -6 ct 1046 -9 1046 -13 1046 -18 ct +1047 -22 1047 -27 1047 -33 ct 1047 -38 1047 -44 1047 -49 ct 1047 -332 l 1087 -332 l +1087 -237 l 1087 -233 1087 -228 1087 -224 ct 1087 -220 1087 -216 1087 -213 ct +1087 -210 1087 -206 1086 -203 ct 1087 -203 l 1095 -218 1105 -229 1117 -236 ct +1129 -243 1145 -246 1163 -246 ct 1193 -246 1216 -236 1230 -215 ct 1245 -195 1252 -163 1252 -122 ct +p +1210 -120 m 1210 -137 1209 -151 1207 -163 ct 1204 -175 1201 -185 1196 -193 ct +1192 -200 1186 -206 1179 -210 ct 1172 -213 1163 -215 1152 -215 ct 1142 -215 1133 -213 1124 -210 ct +1116 -206 1109 -201 1104 -193 ct 1099 -186 1094 -176 1092 -163 ct 1089 -151 1087 -136 1087 -118 ct +1087 -101 1089 -86 1092 -74 ct 1094 -62 1099 -53 1104 -46 ct 1109 -38 1116 -33 1124 -30 ct +1132 -26 1142 -25 1152 -25 ct 1162 -25 1170 -27 1178 -30 ct 1185 -33 1191 -39 1196 -47 ct +1200 -54 1204 -64 1206 -76 ct 1208 -88 1210 -103 1210 -120 ct p ef +1332 -113 m 1332 -100 1333 -89 1336 -78 ct 1338 -67 1342 -58 1348 -51 ct 1353 -43 1360 -37 1369 -33 ct +1377 -28 1388 -26 1400 -26 ct 1417 -26 1431 -30 1442 -37 ct 1452 -44 1459 -53 1463 -63 ct +1498 -53 l 1496 -47 1492 -40 1488 -33 ct 1483 -26 1477 -20 1469 -15 ct 1462 -9 1452 -5 1441 -1 ct +1429 2 1416 4 1400 4 ct 1364 4 1336 -7 1318 -28 ct 1299 -49 1290 -81 1290 -123 ct +1290 -146 1292 -165 1298 -181 ct 1304 -197 1311 -210 1321 -220 ct 1331 -230 1343 -237 1356 -241 ct +1369 -246 1383 -248 1398 -248 ct 1418 -248 1435 -245 1449 -238 ct 1463 -231 1474 -222 1482 -211 ct +1490 -199 1496 -185 1500 -170 ct 1503 -154 1505 -137 1505 -118 ct 1505 -113 l +1332 -113 l p +1463 -144 m 1461 -170 1454 -188 1444 -200 ct 1433 -212 1417 -218 1397 -218 ct +1391 -218 1384 -217 1376 -215 ct 1369 -213 1362 -209 1356 -203 ct 1349 -198 1344 -190 1340 -180 ct +1335 -171 1333 -159 1332 -144 ct 1463 -144 l p ef +1556 0 m 1556 -186 l 1556 -191 1556 -196 1556 -202 ct 1556 -207 1556 -212 1555 -217 ct +1555 -222 1555 -227 1555 -231 ct 1555 -235 1555 -239 1554 -243 ct 1593 -243 l +1593 -239 1593 -235 1593 -231 ct 1593 -226 1594 -222 1594 -217 ct 1594 -213 1594 -208 1594 -204 ct +1594 -200 1594 -196 1594 -193 ct 1595 -193 l 1598 -202 1601 -210 1604 -217 ct +1608 -224 1611 -229 1616 -234 ct 1620 -238 1625 -242 1631 -244 ct 1637 -246 1644 -247 1653 -247 ct +1656 -247 1659 -247 1662 -246 ct 1665 -246 1668 -245 1669 -245 ct 1669 -208 l +1667 -209 1663 -209 1660 -209 ct 1656 -210 1652 -210 1648 -210 ct 1638 -210 1631 -208 1624 -204 ct +1618 -200 1612 -194 1608 -186 ct 1604 -179 1601 -170 1599 -160 ct 1597 -150 1596 -139 1596 -126 ct +1596 0 l 1556 0 l p ef +1696 -104 m 1696 -140 l 1808 -140 l 1808 -104 l 1696 -104 l p ef +pom +pum +18324 6933 t +81 -213 m 81 0 l 41 0 l 41 -213 l 7 -213 l 7 -242 l 41 -242 l 41 -270 l +41 -279 41 -287 43 -294 ct 45 -302 48 -308 52 -314 ct 57 -320 63 -324 70 -327 ct +78 -330 88 -332 100 -332 ct 105 -332 109 -332 115 -331 ct 120 -331 124 -330 128 -329 ct +128 -299 l 126 -299 123 -299 119 -300 ct 116 -300 113 -300 110 -300 ct 104 -300 99 -300 96 -298 ct +92 -296 89 -294 87 -291 ct 84 -288 83 -284 82 -280 ct 81 -275 81 -270 81 -264 ct +81 -242 l 128 -242 l 128 -213 l 81 -213 l p ef +197 -243 m 197 -89 l 197 -77 198 -68 200 -60 ct 202 -52 204 -45 208 -40 ct +212 -36 217 -32 224 -30 ct 230 -28 238 -27 247 -27 ct 257 -27 266 -29 273 -32 ct +281 -36 288 -40 293 -47 ct 298 -53 303 -61 306 -70 ct 309 -80 310 -90 310 -102 ct +310 -243 l 350 -243 l 350 -52 l 350 -47 350 -42 351 -36 ct 351 -31 351 -25 351 -20 ct +351 -15 351 -11 351 -7 ct 351 -4 352 -2 352 0 ct 314 0 l 314 -1 313 -3 313 -7 ct +313 -10 313 -14 313 -18 ct 312 -22 312 -26 312 -31 ct 312 -35 312 -39 312 -42 ct +311 -42 l 307 -35 303 -29 298 -23 ct 294 -17 288 -12 282 -8 ct 276 -4 269 -1 261 1 ct +253 3 244 4 234 4 ct 220 4 209 2 199 -1 ct 189 -4 181 -9 175 -16 ct 169 -23 164 -32 161 -43 ct +158 -53 157 -66 157 -81 ct 157 -243 l 197 -243 l p ef +566 0 m 566 -154 l 566 -166 565 -175 563 -183 ct 562 -191 559 -198 555 -203 ct +551 -207 546 -211 540 -213 ct 533 -215 525 -216 516 -216 ct 506 -216 498 -214 490 -211 ct +482 -207 476 -203 470 -196 ct 465 -190 461 -182 458 -173 ct 455 -163 453 -153 453 -141 ct +453 0 l 413 0 l 413 -191 l 413 -196 413 -201 413 -207 ct 413 -212 413 -218 412 -223 ct +412 -228 412 -232 412 -236 ct 412 -239 412 -241 411 -243 ct 450 -243 l 450 -242 450 -240 450 -236 ct +450 -233 450 -229 451 -225 ct 451 -221 451 -217 451 -212 ct 451 -208 451 -204 451 -201 ct +452 -201 l 456 -208 460 -214 465 -220 ct 469 -226 475 -231 481 -235 ct 487 -239 494 -242 502 -244 ct +510 -246 519 -247 530 -247 ct 543 -247 555 -245 564 -242 ct 574 -239 582 -234 588 -227 ct +595 -220 599 -211 602 -200 ct 605 -189 606 -177 606 -162 ct 606 0 l 566 0 l +p ef +697 -123 m 697 -109 698 -96 700 -85 ct 702 -73 705 -63 710 -54 ct 715 -46 721 -39 729 -35 ct +737 -30 746 -28 758 -28 ct 772 -28 784 -32 794 -39 ct 803 -47 809 -58 812 -74 ct +852 -74 l 851 -64 848 -54 844 -45 ct 839 -35 833 -27 825 -20 ct 818 -13 808 -7 797 -3 ct +786 2 773 4 759 4 ct 740 4 724 1 711 -6 ct 697 -12 686 -21 678 -32 ct 670 -44 664 -57 660 -72 ct +656 -87 655 -104 655 -122 ct 655 -138 656 -153 659 -165 ct 661 -178 665 -189 670 -198 ct +675 -207 680 -215 687 -221 ct 694 -228 701 -233 708 -237 ct 716 -241 724 -243 733 -245 ct +741 -247 750 -248 758 -248 ct 772 -248 784 -246 795 -242 ct 805 -238 815 -233 822 -227 ct +830 -220 836 -213 841 -204 ct 846 -195 849 -185 851 -175 ct 810 -172 l 808 -186 802 -196 794 -204 ct +785 -212 773 -216 757 -216 ct 746 -216 736 -214 729 -210 ct 721 -206 715 -201 710 -193 ct +705 -185 702 -176 700 -164 ct 698 -152 697 -139 697 -123 ct p ef +988 -1 m 982 0 976 2 969 3 ct 963 4 956 4 947 4 ct 915 4 899 -14 899 -51 ct 899 -213 l +871 -213 l 871 -242 l 901 -242 l 912 -297 l 939 -297 l 939 -242 l +984 -242 l 984 -213 l 939 -213 l 939 -60 l 939 -48 941 -40 945 -35 ct +949 -30 955 -28 965 -28 ct 969 -28 973 -28 976 -29 ct 980 -30 984 -30 988 -31 ct +988 -1 l p ef +1022 -293 m 1022 -332 l 1062 -332 l 1062 -293 l 1022 -293 l p +1022 1 m 1022 -242 l 1062 -242 l 1062 1 l 1022 1 l p ef +1328 -122 m 1328 -80 1319 -48 1300 -27 ct 1281 -6 1254 4 1219 4 ct 1202 4 1187 1 1173 -4 ct +1160 -9 1149 -17 1140 -27 ct 1130 -37 1123 -51 1119 -66 ct 1114 -82 1111 -101 1111 -122 ct +1111 -206 1148 -248 1220 -248 ct 1239 -248 1255 -245 1269 -240 ct 1282 -235 1294 -227 1302 -216 ct +1311 -206 1318 -193 1322 -177 ct 1326 -161 1328 -143 1328 -122 ct p +1286 -122 m 1286 -141 1284 -157 1281 -169 ct 1278 -181 1274 -191 1269 -198 ct +1263 -206 1256 -211 1248 -214 ct 1240 -217 1231 -218 1221 -218 ct 1210 -218 1201 -216 1193 -213 ct +1184 -210 1177 -205 1172 -198 ct 1166 -190 1161 -180 1158 -168 ct 1155 -156 1154 -141 1154 -122 ct +1154 -103 1155 -88 1159 -75 ct 1162 -63 1166 -53 1172 -46 ct 1178 -38 1185 -33 1193 -30 ct +1200 -27 1209 -26 1218 -26 ct 1228 -26 1238 -27 1246 -30 ct 1255 -33 1262 -38 1267 -46 ct +1273 -53 1278 -63 1281 -75 ct 1284 -88 1286 -103 1286 -122 ct p ef +1531 0 m 1531 -154 l 1531 -166 1530 -175 1528 -183 ct 1527 -191 1524 -198 1520 -203 ct +1516 -207 1511 -211 1505 -213 ct 1498 -215 1490 -216 1481 -216 ct 1471 -216 1463 -214 1455 -211 ct +1447 -207 1441 -203 1435 -196 ct 1430 -190 1426 -182 1423 -173 ct 1420 -163 1418 -153 1418 -141 ct +1418 0 l 1378 0 l 1378 -191 l 1378 -196 1378 -201 1378 -207 ct 1378 -212 1378 -218 1377 -223 ct +1377 -228 1377 -232 1377 -236 ct 1377 -239 1377 -241 1376 -243 ct 1415 -243 l +1415 -242 1415 -240 1415 -236 ct 1415 -233 1415 -229 1416 -225 ct 1416 -221 1416 -217 1416 -212 ct +1416 -208 1416 -204 1416 -201 ct 1417 -201 l 1421 -208 1425 -214 1430 -220 ct +1434 -226 1440 -231 1446 -235 ct 1452 -239 1459 -242 1467 -244 ct 1475 -246 1484 -247 1495 -247 ct +1508 -247 1520 -245 1529 -242 ct 1539 -239 1547 -234 1553 -227 ct 1560 -220 1564 -211 1567 -200 ct +1570 -189 1571 -177 1571 -162 ct 1571 0 l 1531 0 l p ef +pom +pum +20480 6635 t +93 4 m 68 4 50 -2 38 -15 ct 26 -28 20 -46 20 -69 ct 20 -85 23 -98 29 -108 ct 35 -118 43 -127 52 -132 ct +62 -138 73 -142 86 -145 ct 98 -147 111 -148 124 -148 ct 179 -148 l 179 -161 l +179 -171 178 -180 175 -187 ct 173 -194 170 -200 166 -204 ct 162 -209 156 -212 150 -214 ct +143 -216 135 -217 127 -217 ct 119 -217 112 -216 106 -215 ct 99 -214 94 -212 89 -209 ct +85 -206 81 -202 78 -197 ct 75 -192 73 -186 72 -178 ct 30 -182 l 32 -192 35 -201 39 -209 ct +43 -217 49 -224 57 -229 ct 64 -235 74 -240 86 -243 ct 97 -246 111 -248 128 -248 ct +158 -248 181 -241 196 -227 ct 212 -213 219 -192 219 -166 ct 219 -61 l 219 -49 221 -40 224 -34 ct +227 -28 233 -25 242 -25 ct 244 -25 247 -25 249 -26 ct 251 -26 253 -26 255 -27 ct +255 -2 l 250 0 245 1 240 1 ct 235 2 230 2 224 2 ct 217 2 210 1 205 -1 ct 199 -3 195 -6 191 -10 ct +188 -14 185 -20 183 -26 ct 182 -32 180 -39 180 -47 ct 179 -47 l 174 -39 170 -32 164 -26 ct +159 -20 153 -14 146 -10 ct 139 -5 132 -2 123 0 ct 114 3 104 4 93 4 ct p +102 -26 m 115 -26 126 -29 136 -33 ct 145 -38 153 -44 160 -51 ct 166 -59 171 -67 174 -75 ct +177 -84 179 -92 179 -100 ct 179 -120 l 134 -120 l 125 -120 115 -119 106 -118 ct +97 -117 90 -114 83 -110 ct 76 -107 71 -101 67 -94 ct 63 -88 61 -79 61 -68 ct 61 -55 65 -44 72 -37 ct +79 -30 89 -26 102 -26 ct p ef +378 -1 m 372 0 366 2 359 3 ct 353 4 346 4 337 4 ct 305 4 289 -14 289 -51 ct 289 -213 l +261 -213 l 261 -242 l 291 -242 l 302 -297 l 329 -297 l 329 -242 l +374 -242 l 374 -213 l 329 -213 l 329 -60 l 329 -48 331 -40 335 -35 ct +339 -30 345 -28 355 -28 ct 359 -28 363 -28 366 -29 ct 370 -30 374 -30 378 -31 ct +378 -1 l p ef +505 -1 m 499 0 493 2 486 3 ct 480 4 473 4 464 4 ct 432 4 416 -14 416 -51 ct 416 -213 l +388 -213 l 388 -242 l 418 -242 l 429 -297 l 456 -297 l 456 -242 l +501 -242 l 501 -213 l 456 -213 l 456 -60 l 456 -48 458 -40 462 -35 ct +466 -30 472 -28 482 -28 ct 486 -28 490 -28 493 -29 ct 497 -30 501 -30 505 -31 ct +505 -1 l p ef +540 0 m 540 -186 l 540 -191 540 -196 540 -202 ct 540 -207 540 -212 539 -217 ct +539 -222 539 -227 539 -231 ct 539 -235 539 -239 538 -243 ct 577 -243 l 577 -239 577 -235 577 -231 ct +577 -226 578 -222 578 -217 ct 578 -213 578 -208 578 -204 ct 578 -200 578 -196 578 -193 ct +579 -193 l 582 -202 585 -210 588 -217 ct 592 -224 595 -229 600 -234 ct 604 -238 609 -242 615 -244 ct +621 -246 628 -247 637 -247 ct 640 -247 643 -247 646 -246 ct 649 -246 652 -245 653 -245 ct +653 -208 l 651 -209 647 -209 644 -209 ct 640 -210 636 -210 632 -210 ct 622 -210 615 -208 608 -204 ct +602 -200 596 -194 592 -186 ct 588 -179 585 -170 583 -160 ct 581 -150 580 -139 580 -126 ct +580 0 l 540 0 l p ef +691 -293 m 691 -332 l 731 -332 l 731 -293 l 691 -293 l p +691 1 m 691 -242 l 731 -242 l 731 1 l 691 1 l p ef +998 -122 m 998 -37 968 5 909 5 ct 890 5 875 2 863 -5 ct 851 -12 841 -22 833 -37 ct +833 -37 l 833 -33 833 -29 832 -25 ct 832 -21 832 -17 832 -13 ct 832 -10 831 -7 831 -4 ct +831 -2 831 0 831 1 ct 792 1 l 792 -1 792 -3 792 -6 ct 792 -9 792 -13 792 -18 ct +793 -22 793 -27 793 -33 ct 793 -38 793 -44 793 -49 ct 793 -332 l 833 -332 l +833 -237 l 833 -233 833 -228 833 -224 ct 833 -220 833 -216 833 -213 ct 833 -210 833 -206 832 -203 ct +833 -203 l 841 -218 851 -229 863 -236 ct 875 -243 891 -246 909 -246 ct 939 -246 962 -236 976 -215 ct +991 -195 998 -163 998 -122 ct p +956 -120 m 956 -137 955 -151 953 -163 ct 950 -175 947 -185 942 -193 ct 938 -200 932 -206 925 -210 ct +918 -213 909 -215 898 -215 ct 888 -215 879 -213 870 -210 ct 862 -206 855 -201 850 -193 ct +845 -186 840 -176 838 -163 ct 835 -151 833 -136 833 -118 ct 833 -101 835 -86 838 -74 ct +840 -62 845 -53 850 -46 ct 855 -38 862 -33 870 -30 ct 878 -26 888 -25 898 -25 ct +908 -25 916 -27 924 -30 ct 931 -33 937 -39 942 -47 ct 946 -54 950 -64 952 -76 ct +954 -88 956 -103 956 -120 ct p ef +1086 -243 m 1086 -89 l 1086 -77 1087 -68 1089 -60 ct 1091 -52 1093 -45 1097 -40 ct +1101 -36 1106 -32 1113 -30 ct 1119 -28 1127 -27 1136 -27 ct 1146 -27 1155 -29 1162 -32 ct +1170 -36 1177 -40 1182 -47 ct 1187 -53 1192 -61 1195 -70 ct 1198 -80 1199 -90 1199 -102 ct +1199 -243 l 1239 -243 l 1239 -52 l 1239 -47 1239 -42 1240 -36 ct 1240 -31 1240 -25 1240 -20 ct +1240 -15 1240 -11 1240 -7 ct 1240 -4 1241 -2 1241 0 ct 1203 0 l 1203 -1 1202 -3 1202 -7 ct +1202 -10 1202 -14 1202 -18 ct 1201 -22 1201 -26 1201 -31 ct 1201 -35 1201 -39 1201 -42 ct +1200 -42 l 1196 -35 1192 -29 1187 -23 ct 1183 -17 1177 -12 1171 -8 ct 1165 -4 1158 -1 1150 1 ct +1142 3 1133 4 1123 4 ct 1109 4 1098 2 1088 -1 ct 1078 -4 1070 -9 1064 -16 ct 1058 -23 1053 -32 1050 -43 ct +1047 -53 1046 -66 1046 -81 ct 1046 -243 l 1086 -243 l p ef +1394 -1 m 1388 0 1382 2 1375 3 ct 1369 4 1362 4 1353 4 ct 1321 4 1305 -14 1305 -51 ct +1305 -213 l 1277 -213 l 1277 -242 l 1307 -242 l 1318 -297 l 1345 -297 l +1345 -242 l 1390 -242 l 1390 -213 l 1345 -213 l 1345 -60 l 1345 -48 1347 -40 1351 -35 ct +1355 -30 1361 -28 1371 -28 ct 1375 -28 1379 -28 1382 -29 ct 1386 -30 1390 -30 1394 -31 ct +1394 -1 l p ef +1459 -113 m 1459 -100 1460 -89 1463 -78 ct 1465 -67 1469 -58 1475 -51 ct 1480 -43 1487 -37 1496 -33 ct +1504 -28 1515 -26 1527 -26 ct 1544 -26 1558 -30 1569 -37 ct 1579 -44 1586 -53 1590 -63 ct +1625 -53 l 1623 -47 1619 -40 1615 -33 ct 1610 -26 1604 -20 1596 -15 ct 1589 -9 1579 -5 1568 -1 ct +1556 2 1543 4 1527 4 ct 1491 4 1463 -7 1445 -28 ct 1426 -49 1417 -81 1417 -123 ct +1417 -146 1419 -165 1425 -181 ct 1431 -197 1438 -210 1448 -220 ct 1458 -230 1470 -237 1483 -241 ct +1496 -246 1510 -248 1525 -248 ct 1545 -248 1562 -245 1576 -238 ct 1590 -231 1601 -222 1609 -211 ct +1617 -199 1623 -185 1627 -170 ct 1630 -154 1632 -137 1632 -118 ct 1632 -113 l +1459 -113 l p +1590 -144 m 1588 -170 1581 -188 1571 -200 ct 1560 -212 1544 -218 1524 -218 ct +1518 -218 1511 -217 1503 -215 ct 1496 -213 1489 -209 1483 -203 ct 1476 -198 1471 -190 1467 -180 ct +1462 -171 1460 -159 1459 -144 ct 1590 -144 l p ef +pom +0.812 0.906 0.960 c 16675 17832 m 4547 17832 l 4547 14844 l 28802 14844 l +28802 17832 l 16675 17832 l p ef +0 lw 0.207 0.398 0.644 c 16674 17831 m 4546 17831 l 4546 14844 l 28802 14844 l +28802 17831 l 16674 17831 l pc +pum +8777 16580 t +0.003 0.003 0.003 c 32 0 m 32 -186 l 32 -191 32 -196 32 -202 ct 32 -207 32 -212 31 -217 ct +31 -222 31 -227 31 -231 ct 31 -235 31 -239 30 -243 ct 69 -243 l 69 -239 69 -235 69 -231 ct +69 -226 70 -222 70 -217 ct 70 -213 70 -208 70 -204 ct 70 -200 70 -196 70 -193 ct +71 -193 l 74 -202 77 -210 80 -217 ct 84 -224 87 -229 92 -234 ct 96 -238 101 -242 107 -244 ct +113 -246 120 -247 129 -247 ct 132 -247 135 -247 138 -246 ct 141 -246 144 -245 145 -245 ct +145 -208 l 143 -209 139 -209 136 -209 ct 132 -210 128 -210 124 -210 ct 114 -210 107 -208 100 -204 ct +94 -200 88 -194 84 -186 ct 80 -179 77 -170 75 -160 ct 73 -150 72 -139 72 -126 ct +72 0 l 32 0 l p ef +214 -113 m 214 -100 215 -89 218 -78 ct 220 -67 224 -58 230 -51 ct 235 -43 242 -37 251 -33 ct +259 -28 270 -26 282 -26 ct 299 -26 313 -30 324 -37 ct 334 -44 341 -53 345 -63 ct +380 -53 l 378 -47 374 -40 370 -33 ct 365 -26 359 -20 351 -15 ct 344 -9 334 -5 323 -1 ct +311 2 298 4 282 4 ct 246 4 218 -7 200 -28 ct 181 -49 172 -81 172 -123 ct 172 -146 174 -165 180 -181 ct +186 -197 193 -210 203 -220 ct 213 -230 225 -237 238 -241 ct 251 -246 265 -248 280 -248 ct +300 -248 317 -245 331 -238 ct 345 -231 356 -222 364 -211 ct 372 -199 378 -185 382 -170 ct +385 -154 387 -137 387 -118 ct 387 -113 l 214 -113 l p +345 -144 m 343 -170 336 -188 326 -200 ct 315 -212 299 -218 279 -218 ct 273 -218 266 -217 258 -215 ct +251 -213 244 -209 238 -203 ct 231 -198 226 -190 222 -180 ct 217 -171 215 -159 214 -144 ct +345 -144 l p ef +437 1 m 437 -332 l 477 -332 l 477 1 l 437 1 l p ef +601 4 m 576 4 558 -2 546 -15 ct 534 -28 528 -46 528 -69 ct 528 -85 531 -98 537 -108 ct +543 -118 551 -127 560 -132 ct 570 -138 581 -142 594 -145 ct 606 -147 619 -148 632 -148 ct +687 -148 l 687 -161 l 687 -171 686 -180 683 -187 ct 681 -194 678 -200 674 -204 ct +670 -209 664 -212 658 -214 ct 651 -216 643 -217 635 -217 ct 627 -217 620 -216 614 -215 ct +607 -214 602 -212 597 -209 ct 593 -206 589 -202 586 -197 ct 583 -192 581 -186 580 -178 ct +538 -182 l 540 -192 543 -201 547 -209 ct 551 -217 557 -224 565 -229 ct 572 -235 582 -240 594 -243 ct +605 -246 619 -248 636 -248 ct 666 -248 689 -241 704 -227 ct 720 -213 727 -192 727 -166 ct +727 -61 l 727 -49 729 -40 732 -34 ct 735 -28 741 -25 750 -25 ct 752 -25 755 -25 757 -26 ct +759 -26 761 -26 763 -27 ct 763 -2 l 758 0 753 1 748 1 ct 743 2 738 2 732 2 ct +725 2 718 1 713 -1 ct 707 -3 703 -6 699 -10 ct 696 -14 693 -20 691 -26 ct 690 -32 688 -39 688 -47 ct +687 -47 l 682 -39 678 -32 672 -26 ct 667 -20 661 -14 654 -10 ct 647 -5 640 -2 631 0 ct +622 3 612 4 601 4 ct p +610 -26 m 623 -26 634 -29 644 -33 ct 653 -38 661 -44 668 -51 ct 674 -59 679 -67 682 -75 ct +685 -84 687 -92 687 -100 ct 687 -120 l 642 -120 l 633 -120 623 -119 614 -118 ct +605 -117 598 -114 591 -110 ct 584 -107 579 -101 575 -94 ct 571 -88 569 -79 569 -68 ct +569 -55 573 -44 580 -37 ct 587 -30 597 -26 610 -26 ct p ef +886 -1 m 880 0 874 2 867 3 ct 861 4 854 4 845 4 ct 813 4 797 -14 797 -51 ct 797 -213 l +769 -213 l 769 -242 l 799 -242 l 810 -297 l 837 -297 l 837 -242 l +882 -242 l 882 -213 l 837 -213 l 837 -60 l 837 -48 839 -40 843 -35 ct +847 -30 853 -28 863 -28 ct 867 -28 871 -28 874 -29 ct 878 -30 882 -30 886 -31 ct +886 -1 l p ef +920 -293 m 920 -332 l 960 -332 l 960 -293 l 920 -293 l p +920 1 m 920 -242 l 960 -242 l 960 1 l 920 1 l p ef +1227 -122 m 1227 -80 1218 -48 1199 -27 ct 1180 -6 1153 4 1118 4 ct 1101 4 1086 1 1072 -4 ct +1059 -9 1048 -17 1039 -27 ct 1029 -37 1022 -51 1018 -66 ct 1013 -82 1010 -101 1010 -122 ct +1010 -206 1047 -248 1119 -248 ct 1138 -248 1154 -245 1168 -240 ct 1181 -235 1193 -227 1201 -216 ct +1210 -206 1217 -193 1221 -177 ct 1225 -161 1227 -143 1227 -122 ct p +1185 -122 m 1185 -141 1183 -157 1180 -169 ct 1177 -181 1173 -191 1168 -198 ct +1162 -206 1155 -211 1147 -214 ct 1139 -217 1130 -218 1120 -218 ct 1109 -218 1100 -216 1092 -213 ct +1083 -210 1076 -205 1071 -198 ct 1065 -190 1060 -180 1057 -168 ct 1054 -156 1053 -141 1053 -122 ct +1053 -103 1054 -88 1058 -75 ct 1061 -63 1065 -53 1071 -46 ct 1077 -38 1084 -33 1092 -30 ct +1099 -27 1108 -26 1117 -26 ct 1127 -26 1137 -27 1145 -30 ct 1154 -33 1161 -38 1166 -46 ct +1172 -53 1177 -63 1180 -75 ct 1183 -88 1185 -103 1185 -122 ct p ef +1430 0 m 1430 -154 l 1430 -166 1429 -175 1427 -183 ct 1426 -191 1423 -198 1419 -203 ct +1415 -207 1410 -211 1404 -213 ct 1397 -215 1389 -216 1380 -216 ct 1370 -216 1362 -214 1354 -211 ct +1346 -207 1340 -203 1334 -196 ct 1329 -190 1325 -182 1322 -173 ct 1319 -163 1317 -153 1317 -141 ct +1317 0 l 1277 0 l 1277 -191 l 1277 -196 1277 -201 1277 -207 ct 1277 -212 1277 -218 1276 -223 ct +1276 -228 1276 -232 1276 -236 ct 1276 -239 1276 -241 1275 -243 ct 1314 -243 l +1314 -242 1314 -240 1314 -236 ct 1314 -233 1314 -229 1315 -225 ct 1315 -221 1315 -217 1315 -212 ct +1315 -208 1315 -204 1315 -201 ct 1316 -201 l 1320 -208 1324 -214 1329 -220 ct +1333 -226 1339 -231 1345 -235 ct 1351 -239 1358 -242 1366 -244 ct 1374 -246 1383 -247 1394 -247 ct +1407 -247 1419 -245 1428 -242 ct 1438 -239 1446 -234 1452 -227 ct 1459 -220 1463 -211 1466 -200 ct +1469 -189 1470 -177 1470 -162 ct 1470 0 l 1430 0 l p ef +1862 -122 m 1862 -37 1832 5 1773 5 ct 1754 5 1739 2 1727 -5 ct 1715 -12 1705 -22 1697 -37 ct +1697 -37 l 1697 -33 1697 -29 1696 -25 ct 1696 -21 1696 -17 1696 -13 ct 1696 -10 1695 -7 1695 -4 ct +1695 -2 1695 0 1695 1 ct 1656 1 l 1656 -1 1656 -3 1656 -6 ct 1656 -9 1656 -13 1656 -18 ct +1657 -22 1657 -27 1657 -33 ct 1657 -38 1657 -44 1657 -49 ct 1657 -332 l 1697 -332 l +1697 -237 l 1697 -233 1697 -228 1697 -224 ct 1697 -220 1697 -216 1697 -213 ct +1697 -210 1697 -206 1696 -203 ct 1697 -203 l 1705 -218 1715 -229 1727 -236 ct +1739 -243 1755 -246 1773 -246 ct 1803 -246 1826 -236 1840 -215 ct 1855 -195 1862 -163 1862 -122 ct +p +1820 -120 m 1820 -137 1819 -151 1817 -163 ct 1814 -175 1811 -185 1806 -193 ct +1802 -200 1796 -206 1789 -210 ct 1782 -213 1773 -215 1762 -215 ct 1752 -215 1743 -213 1734 -210 ct +1726 -206 1719 -201 1714 -193 ct 1709 -186 1704 -176 1702 -163 ct 1699 -151 1697 -136 1697 -118 ct +1697 -101 1699 -86 1702 -74 ct 1704 -62 1709 -53 1714 -46 ct 1719 -38 1726 -33 1734 -30 ct +1742 -26 1752 -25 1762 -25 ct 1772 -25 1780 -27 1788 -30 ct 1795 -33 1801 -39 1806 -47 ct +1810 -54 1814 -64 1816 -76 ct 1818 -88 1820 -103 1820 -120 ct p ef +1942 -113 m 1942 -100 1943 -89 1946 -78 ct 1948 -67 1952 -58 1958 -51 ct 1963 -43 1970 -37 1979 -33 ct +1987 -28 1998 -26 2010 -26 ct 2027 -26 2041 -30 2052 -37 ct 2062 -44 2069 -53 2073 -63 ct +2108 -53 l 2106 -47 2102 -40 2098 -33 ct 2093 -26 2087 -20 2079 -15 ct 2072 -9 2062 -5 2051 -1 ct +2039 2 2026 4 2010 4 ct 1974 4 1946 -7 1928 -28 ct 1909 -49 1900 -81 1900 -123 ct +1900 -146 1902 -165 1908 -181 ct 1914 -197 1921 -210 1931 -220 ct 1941 -230 1953 -237 1966 -241 ct +1979 -246 1993 -248 2008 -248 ct 2028 -248 2045 -245 2059 -238 ct 2073 -231 2084 -222 2092 -211 ct +2100 -199 2106 -185 2110 -170 ct 2113 -154 2115 -137 2115 -118 ct 2115 -113 l +1942 -113 l p +2073 -144 m 2071 -170 2064 -188 2054 -200 ct 2043 -212 2027 -218 2007 -218 ct +2001 -218 1994 -217 1986 -215 ct 1979 -213 1972 -209 1966 -203 ct 1959 -198 1954 -190 1950 -180 ct +1945 -171 1943 -159 1942 -144 ct 2073 -144 l p ef +2258 -1 m 2252 0 2246 2 2239 3 ct 2233 4 2226 4 2217 4 ct 2185 4 2169 -14 2169 -51 ct +2169 -213 l 2141 -213 l 2141 -242 l 2171 -242 l 2182 -297 l 2209 -297 l +2209 -242 l 2254 -242 l 2254 -213 l 2209 -213 l 2209 -60 l 2209 -48 2211 -40 2215 -35 ct +2219 -30 2225 -28 2235 -28 ct 2239 -28 2243 -28 2246 -29 ct 2250 -30 2254 -30 2258 -31 ct +2258 -1 l p ef +2524 0 m 2477 0 l 2439 -156 l 2437 -160 2436 -165 2435 -171 ct 2434 -177 2432 -183 2431 -189 ct +2430 -196 2428 -202 2427 -209 ct 2426 -203 2424 -196 2423 -189 ct 2421 -184 2420 -178 2419 -172 ct +2417 -166 2416 -160 2415 -156 ct 2375 0 l 2328 0 l 2260 -243 l 2300 -243 l +2341 -78 l 2342 -74 2343 -70 2344 -65 ct 2345 -60 2346 -55 2348 -50 ct 2349 -45 2350 -39 2351 -33 ct +2352 -39 2353 -45 2355 -50 ct 2356 -55 2357 -59 2358 -64 ct 2359 -69 2361 -73 2361 -76 ct +2405 -243 l 2449 -243 l 2491 -76 l 2492 -72 2493 -68 2494 -63 ct 2496 -58 2497 -53 2498 -49 ct +2499 -44 2500 -39 2501 -33 ct 2502 -39 2504 -45 2505 -50 ct 2506 -55 2507 -59 2508 -64 ct +2509 -69 2510 -74 2511 -78 ct 2554 -243 l 2594 -243 l 2524 0 l p ef +2649 -113 m 2649 -100 2650 -89 2653 -78 ct 2655 -67 2659 -58 2665 -51 ct 2670 -43 2677 -37 2686 -33 ct +2694 -28 2705 -26 2717 -26 ct 2734 -26 2748 -30 2759 -37 ct 2769 -44 2776 -53 2780 -63 ct +2815 -53 l 2813 -47 2809 -40 2805 -33 ct 2800 -26 2794 -20 2786 -15 ct 2779 -9 2769 -5 2758 -1 ct +2746 2 2733 4 2717 4 ct 2681 4 2653 -7 2635 -28 ct 2616 -49 2607 -81 2607 -123 ct +2607 -146 2609 -165 2615 -181 ct 2621 -197 2628 -210 2638 -220 ct 2648 -230 2660 -237 2673 -241 ct +2686 -246 2700 -248 2715 -248 ct 2735 -248 2752 -245 2766 -238 ct 2780 -231 2791 -222 2799 -211 ct +2807 -199 2813 -185 2817 -170 ct 2820 -154 2822 -137 2822 -118 ct 2822 -113 l +2649 -113 l p +2780 -144 m 2778 -170 2771 -188 2761 -200 ct 2750 -212 2734 -218 2714 -218 ct +2708 -218 2701 -217 2693 -215 ct 2686 -213 2679 -209 2673 -203 ct 2666 -198 2661 -190 2657 -180 ct +2652 -171 2650 -159 2649 -144 ct 2780 -144 l p ef +2903 -113 m 2903 -100 2904 -89 2907 -78 ct 2909 -67 2913 -58 2919 -51 ct 2924 -43 2931 -37 2940 -33 ct +2948 -28 2959 -26 2971 -26 ct 2988 -26 3002 -30 3013 -37 ct 3023 -44 3030 -53 3034 -63 ct +3069 -53 l 3067 -47 3063 -40 3059 -33 ct 3054 -26 3048 -20 3040 -15 ct 3033 -9 3023 -5 3012 -1 ct +3000 2 2987 4 2971 4 ct 2935 4 2907 -7 2889 -28 ct 2870 -49 2861 -81 2861 -123 ct +2861 -146 2863 -165 2869 -181 ct 2875 -197 2882 -210 2892 -220 ct 2902 -230 2914 -237 2927 -241 ct +2940 -246 2954 -248 2969 -248 ct 2989 -248 3006 -245 3020 -238 ct 3034 -231 3045 -222 3053 -211 ct +3061 -199 3067 -185 3071 -170 ct 3074 -154 3076 -137 3076 -118 ct 3076 -113 l +2903 -113 l p +3034 -144 m 3032 -170 3025 -188 3015 -200 ct 3004 -212 2988 -218 2968 -218 ct +2962 -218 2955 -217 2947 -215 ct 2940 -213 2933 -209 2927 -203 ct 2920 -198 2915 -190 2911 -180 ct +2906 -171 2904 -159 2903 -144 ct 3034 -144 l p ef +3280 0 m 3280 -154 l 3280 -166 3279 -175 3277 -183 ct 3276 -191 3273 -198 3269 -203 ct +3265 -207 3260 -211 3254 -213 ct 3247 -215 3239 -216 3230 -216 ct 3220 -216 3212 -214 3204 -211 ct +3196 -207 3190 -203 3184 -196 ct 3179 -190 3175 -182 3172 -173 ct 3169 -163 3167 -153 3167 -141 ct +3167 0 l 3127 0 l 3127 -191 l 3127 -196 3127 -201 3127 -207 ct 3127 -212 3127 -218 3126 -223 ct +3126 -228 3126 -232 3126 -236 ct 3126 -239 3126 -241 3125 -243 ct 3164 -243 l +3164 -242 3164 -240 3164 -236 ct 3164 -233 3164 -229 3165 -225 ct 3165 -221 3165 -217 3165 -212 ct +3165 -208 3165 -204 3165 -201 ct 3166 -201 l 3170 -208 3174 -214 3179 -220 ct +3183 -226 3189 -231 3195 -235 ct 3201 -239 3208 -242 3216 -244 ct 3224 -246 3233 -247 3244 -247 ct +3257 -247 3269 -245 3278 -242 ct 3288 -239 3296 -234 3302 -227 ct 3309 -220 3313 -211 3316 -200 ct +3319 -189 3320 -177 3320 -162 ct 3320 0 l 3280 0 l p ef +3538 -123 m 3538 -109 3539 -96 3541 -85 ct 3543 -73 3546 -63 3551 -54 ct 3556 -46 3562 -39 3570 -35 ct +3578 -30 3587 -28 3599 -28 ct 3613 -28 3625 -32 3635 -39 ct 3644 -47 3650 -58 3653 -74 ct +3693 -74 l 3692 -64 3689 -54 3685 -45 ct 3680 -35 3674 -27 3666 -20 ct 3659 -13 3649 -7 3638 -3 ct +3627 2 3614 4 3600 4 ct 3581 4 3565 1 3552 -6 ct 3538 -12 3527 -21 3519 -32 ct +3511 -44 3505 -57 3501 -72 ct 3497 -87 3496 -104 3496 -122 ct 3496 -138 3497 -153 3500 -165 ct +3502 -178 3506 -189 3511 -198 ct 3516 -207 3521 -215 3528 -221 ct 3535 -228 3542 -233 3549 -237 ct +3557 -241 3565 -243 3574 -245 ct 3582 -247 3591 -248 3599 -248 ct 3613 -248 3625 -246 3636 -242 ct +3646 -238 3656 -233 3663 -227 ct 3671 -220 3677 -213 3682 -204 ct 3687 -195 3690 -185 3692 -175 ct +3651 -172 l 3649 -186 3643 -196 3635 -204 ct 3626 -212 3614 -216 3598 -216 ct +3587 -216 3577 -214 3570 -210 ct 3562 -206 3556 -201 3551 -193 ct 3546 -185 3543 -176 3541 -164 ct +3539 -152 3538 -139 3538 -123 ct p ef +3940 -122 m 3940 -80 3931 -48 3912 -27 ct 3893 -6 3866 4 3831 4 ct 3814 4 3799 1 3785 -4 ct +3772 -9 3761 -17 3752 -27 ct 3742 -37 3735 -51 3731 -66 ct 3726 -82 3723 -101 3723 -122 ct +3723 -206 3760 -248 3832 -248 ct 3851 -248 3867 -245 3881 -240 ct 3894 -235 3906 -227 3914 -216 ct +3923 -206 3930 -193 3934 -177 ct 3938 -161 3940 -143 3940 -122 ct p +3898 -122 m 3898 -141 3896 -157 3893 -169 ct 3890 -181 3886 -191 3881 -198 ct +3875 -206 3868 -211 3860 -214 ct 3852 -217 3843 -218 3833 -218 ct 3822 -218 3813 -216 3805 -213 ct +3796 -210 3789 -205 3784 -198 ct 3778 -190 3773 -180 3770 -168 ct 3767 -156 3766 -141 3766 -122 ct +3766 -103 3767 -88 3771 -75 ct 3774 -63 3778 -53 3784 -46 ct 3790 -38 3797 -33 3805 -30 ct +3812 -27 3821 -26 3830 -26 ct 3840 -26 3850 -27 3858 -30 ct 3867 -33 3874 -38 3879 -46 ct +3885 -53 3890 -63 3893 -75 ct 3896 -88 3898 -103 3898 -122 ct p ef +4142 -38 m 4135 -23 4125 -12 4112 -5 ct 4100 2 4085 5 4066 5 ct 4036 5 4013 -5 3999 -26 ct +3984 -46 3977 -78 3977 -119 ct 3977 -204 4007 -246 4066 -246 ct 4085 -246 4100 -243 4112 -236 ct +4125 -229 4135 -219 4142 -204 ct 4142 -204 l 4142 -205 4142 -208 4142 -211 ct +4142 -214 4142 -218 4142 -221 ct 4142 -225 4142 -228 4142 -231 ct 4142 -234 4142 -236 4142 -238 ct +4142 -332 l 4182 -332 l 4182 -49 l 4182 -44 4182 -38 4182 -33 ct 4183 -27 4183 -22 4183 -18 ct +4183 -13 4183 -9 4183 -6 ct 4183 -3 4184 -1 4184 1 ct 4145 1 l 4145 -1 4145 -3 4144 -6 ct +4144 -9 4144 -12 4144 -15 ct 4143 -19 4143 -23 4143 -27 ct 4143 -31 4143 -34 4143 -38 ct +4142 -38 l p +4020 -121 m 4020 -104 4021 -90 4023 -78 ct 4025 -66 4028 -56 4033 -48 ct 4037 -41 4043 -35 4051 -31 ct +4058 -28 4066 -26 4077 -26 ct 4087 -26 4097 -28 4105 -31 ct 4113 -35 4120 -40 4125 -48 ct +4131 -55 4135 -66 4138 -78 ct 4141 -90 4142 -105 4142 -123 ct 4142 -140 4141 -155 4138 -167 ct +4135 -179 4131 -188 4125 -196 ct 4120 -203 4113 -208 4105 -211 ct 4097 -215 4088 -216 4077 -216 ct +4067 -216 4059 -214 4052 -211 ct 4045 -208 4039 -202 4034 -194 ct 4029 -187 4025 -177 4023 -165 ct +4021 -153 4020 -138 4020 -121 ct p ef +4274 -113 m 4274 -100 4275 -89 4278 -78 ct 4280 -67 4284 -58 4290 -51 ct 4295 -43 4302 -37 4311 -33 ct +4319 -28 4330 -26 4342 -26 ct 4359 -26 4373 -30 4384 -37 ct 4394 -44 4401 -53 4405 -63 ct +4440 -53 l 4438 -47 4434 -40 4430 -33 ct 4425 -26 4419 -20 4411 -15 ct 4404 -9 4394 -5 4383 -1 ct +4371 2 4358 4 4342 4 ct 4306 4 4278 -7 4260 -28 ct 4241 -49 4232 -81 4232 -123 ct +4232 -146 4234 -165 4240 -181 ct 4246 -197 4253 -210 4263 -220 ct 4273 -230 4285 -237 4298 -241 ct +4311 -246 4325 -248 4340 -248 ct 4360 -248 4377 -245 4391 -238 ct 4405 -231 4416 -222 4424 -211 ct +4432 -199 4438 -185 4442 -170 ct 4445 -154 4447 -137 4447 -118 ct 4447 -113 l +4274 -113 l p +4405 -144 m 4403 -170 4396 -188 4386 -200 ct 4375 -212 4359 -218 4339 -218 ct +4333 -218 4326 -217 4318 -215 ct 4311 -213 4304 -209 4298 -203 ct 4291 -198 4286 -190 4282 -180 ct +4277 -171 4275 -159 4274 -144 ct 4405 -144 l p ef +pom +pum +8777 17092 t +93 4 m 68 4 50 -2 38 -15 ct 26 -28 20 -46 20 -69 ct 20 -85 23 -98 29 -108 ct 35 -118 43 -127 52 -132 ct +62 -138 73 -142 86 -145 ct 98 -147 111 -148 124 -148 ct 179 -148 l 179 -161 l +179 -171 178 -180 175 -187 ct 173 -194 170 -200 166 -204 ct 162 -209 156 -212 150 -214 ct +143 -216 135 -217 127 -217 ct 119 -217 112 -216 106 -215 ct 99 -214 94 -212 89 -209 ct +85 -206 81 -202 78 -197 ct 75 -192 73 -186 72 -178 ct 30 -182 l 32 -192 35 -201 39 -209 ct +43 -217 49 -224 57 -229 ct 64 -235 74 -240 86 -243 ct 97 -246 111 -248 128 -248 ct +158 -248 181 -241 196 -227 ct 212 -213 219 -192 219 -166 ct 219 -61 l 219 -49 221 -40 224 -34 ct +227 -28 233 -25 242 -25 ct 244 -25 247 -25 249 -26 ct 251 -26 253 -26 255 -27 ct +255 -2 l 250 0 245 1 240 1 ct 235 2 230 2 224 2 ct 217 2 210 1 205 -1 ct 199 -3 195 -6 191 -10 ct +188 -14 185 -20 183 -26 ct 182 -32 180 -39 180 -47 ct 179 -47 l 174 -39 170 -32 164 -26 ct +159 -20 153 -14 146 -10 ct 139 -5 132 -2 123 0 ct 114 3 104 4 93 4 ct p +102 -26 m 115 -26 126 -29 136 -33 ct 145 -38 153 -44 160 -51 ct 166 -59 171 -67 174 -75 ct +177 -84 179 -92 179 -100 ct 179 -120 l 134 -120 l 125 -120 115 -119 106 -118 ct +97 -117 90 -114 83 -110 ct 76 -107 71 -101 67 -94 ct 63 -88 61 -79 61 -68 ct 61 -55 65 -44 72 -37 ct +79 -30 89 -26 102 -26 ct p ef +439 0 m 439 -154 l 439 -166 438 -175 436 -183 ct 435 -191 432 -198 428 -203 ct +424 -207 419 -211 413 -213 ct 406 -215 398 -216 389 -216 ct 379 -216 371 -214 363 -211 ct +355 -207 349 -203 343 -196 ct 338 -190 334 -182 331 -173 ct 328 -163 326 -153 326 -141 ct +326 0 l 286 0 l 286 -191 l 286 -196 286 -201 286 -207 ct 286 -212 286 -218 285 -223 ct +285 -228 285 -232 285 -236 ct 285 -239 285 -241 284 -243 ct 323 -243 l 323 -242 323 -240 323 -236 ct +323 -233 323 -229 324 -225 ct 324 -221 324 -217 324 -212 ct 324 -208 324 -204 324 -201 ct +325 -201 l 329 -208 333 -214 338 -220 ct 342 -226 348 -231 354 -235 ct 360 -239 367 -242 375 -244 ct +383 -246 392 -247 403 -247 ct 416 -247 428 -245 437 -242 ct 447 -239 455 -234 461 -227 ct +468 -220 472 -211 475 -200 ct 478 -189 479 -177 479 -162 ct 479 0 l 439 0 l +p ef +692 -38 m 685 -23 675 -12 662 -5 ct 650 2 635 5 616 5 ct 586 5 563 -5 549 -26 ct +534 -46 527 -78 527 -119 ct 527 -204 557 -246 616 -246 ct 635 -246 650 -243 662 -236 ct +675 -229 685 -219 692 -204 ct 692 -204 l 692 -205 692 -208 692 -211 ct 692 -214 692 -218 692 -221 ct +692 -225 692 -228 692 -231 ct 692 -234 692 -236 692 -238 ct 692 -332 l 732 -332 l +732 -49 l 732 -44 732 -38 732 -33 ct 733 -27 733 -22 733 -18 ct 733 -13 733 -9 733 -6 ct +733 -3 734 -1 734 1 ct 695 1 l 695 -1 695 -3 694 -6 ct 694 -9 694 -12 694 -15 ct +693 -19 693 -23 693 -27 ct 693 -31 693 -34 693 -38 ct 692 -38 l p +570 -121 m 570 -104 571 -90 573 -78 ct 575 -66 578 -56 583 -48 ct 587 -41 593 -35 601 -31 ct +608 -28 616 -26 627 -26 ct 637 -26 647 -28 655 -31 ct 663 -35 670 -40 675 -48 ct +681 -55 685 -66 688 -78 ct 691 -90 692 -105 692 -123 ct 692 -140 691 -155 688 -167 ct +685 -179 681 -188 675 -196 ct 670 -203 663 -208 655 -211 ct 647 -215 638 -216 627 -216 ct +617 -216 609 -214 602 -211 ct 595 -208 589 -202 584 -194 ct 579 -187 575 -177 573 -165 ct +571 -153 570 -138 570 -121 ct p ef +1074 0 m 1074 -154 l 1074 -166 1073 -175 1071 -183 ct 1070 -191 1067 -198 1063 -203 ct +1059 -207 1054 -211 1048 -213 ct 1041 -215 1033 -216 1024 -216 ct 1014 -216 1006 -214 998 -211 ct +990 -207 984 -203 978 -196 ct 973 -190 969 -182 966 -173 ct 963 -163 961 -153 961 -141 ct +961 0 l 921 0 l 921 -191 l 921 -196 921 -201 921 -207 ct 921 -212 921 -218 920 -223 ct +920 -228 920 -232 920 -236 ct 920 -239 920 -241 919 -243 ct 958 -243 l 958 -242 958 -240 958 -236 ct +958 -233 958 -229 959 -225 ct 959 -221 959 -217 959 -212 ct 959 -208 959 -204 959 -201 ct +960 -201 l 964 -208 968 -214 973 -220 ct 977 -226 983 -231 989 -235 ct 995 -239 1002 -242 1010 -244 ct +1018 -246 1027 -247 1038 -247 ct 1051 -247 1063 -245 1072 -242 ct 1082 -239 1090 -234 1096 -227 ct +1103 -220 1107 -211 1110 -200 ct 1113 -189 1114 -177 1114 -162 ct 1114 0 l 1074 0 l +p ef +1236 4 m 1211 4 1193 -2 1181 -15 ct 1169 -28 1163 -46 1163 -69 ct 1163 -85 1166 -98 1172 -108 ct +1178 -118 1186 -127 1195 -132 ct 1205 -138 1216 -142 1229 -145 ct 1241 -147 1254 -148 1267 -148 ct +1322 -148 l 1322 -161 l 1322 -171 1321 -180 1318 -187 ct 1316 -194 1313 -200 1309 -204 ct +1305 -209 1299 -212 1293 -214 ct 1286 -216 1278 -217 1270 -217 ct 1262 -217 1255 -216 1249 -215 ct +1242 -214 1237 -212 1232 -209 ct 1228 -206 1224 -202 1221 -197 ct 1218 -192 1216 -186 1215 -178 ct +1173 -182 l 1175 -192 1178 -201 1182 -209 ct 1186 -217 1192 -224 1200 -229 ct +1207 -235 1217 -240 1229 -243 ct 1240 -246 1254 -248 1271 -248 ct 1301 -248 1324 -241 1339 -227 ct +1355 -213 1362 -192 1362 -166 ct 1362 -61 l 1362 -49 1364 -40 1367 -34 ct 1370 -28 1376 -25 1385 -25 ct +1387 -25 1390 -25 1392 -26 ct 1394 -26 1396 -26 1398 -27 ct 1398 -2 l 1393 0 1388 1 1383 1 ct +1378 2 1373 2 1367 2 ct 1360 2 1353 1 1348 -1 ct 1342 -3 1338 -6 1334 -10 ct 1331 -14 1328 -20 1326 -26 ct +1325 -32 1323 -39 1323 -47 ct 1322 -47 l 1317 -39 1313 -32 1307 -26 ct 1302 -20 1296 -14 1289 -10 ct +1282 -5 1275 -2 1266 0 ct 1257 3 1247 4 1236 4 ct p +1245 -26 m 1258 -26 1269 -29 1279 -33 ct 1288 -38 1296 -44 1303 -51 ct 1309 -59 1314 -67 1317 -75 ct +1320 -84 1322 -92 1322 -100 ct 1322 -120 l 1277 -120 l 1268 -120 1258 -119 1249 -118 ct +1240 -117 1233 -114 1226 -110 ct 1219 -107 1214 -101 1210 -94 ct 1206 -88 1204 -79 1204 -68 ct +1204 -55 1208 -44 1215 -37 ct 1222 -30 1232 -26 1245 -26 ct p ef +1569 0 m 1569 -154 l 1569 -166 1568 -175 1567 -183 ct 1565 -191 1563 -198 1559 -203 ct +1556 -207 1551 -211 1546 -213 ct 1540 -215 1533 -216 1525 -216 ct 1516 -216 1509 -214 1502 -211 ct +1495 -207 1489 -203 1484 -196 ct 1479 -190 1475 -182 1473 -173 ct 1470 -163 1469 -153 1469 -141 ct +1469 0 l 1429 0 l 1429 -191 l 1429 -196 1429 -201 1429 -207 ct 1429 -212 1429 -218 1428 -223 ct +1428 -228 1428 -232 1428 -236 ct 1428 -239 1428 -241 1427 -243 ct 1466 -243 l +1466 -242 1466 -240 1466 -236 ct 1466 -233 1466 -229 1467 -225 ct 1467 -221 1467 -217 1467 -212 ct +1467 -208 1467 -204 1467 -201 ct 1468 -201 l 1472 -208 1476 -214 1480 -220 ct +1484 -226 1489 -231 1494 -235 ct 1500 -239 1506 -242 1514 -244 ct 1521 -246 1529 -247 1539 -247 ct +1557 -247 1572 -243 1582 -236 ct 1593 -229 1601 -217 1605 -201 ct 1605 -201 l +1609 -208 1613 -214 1618 -220 ct 1622 -226 1627 -231 1633 -235 ct 1639 -239 1646 -242 1653 -244 ct +1661 -246 1669 -247 1679 -247 ct 1691 -247 1702 -245 1711 -242 ct 1720 -239 1727 -234 1733 -227 ct +1738 -220 1742 -211 1745 -200 ct 1748 -189 1749 -177 1749 -162 ct 1749 0 l 1709 0 l +1709 -154 l 1709 -166 1708 -175 1707 -183 ct 1705 -191 1703 -198 1699 -203 ct +1696 -207 1691 -211 1686 -213 ct 1680 -215 1673 -216 1665 -216 ct 1656 -216 1649 -214 1642 -211 ct +1635 -208 1629 -203 1624 -197 ct 1619 -191 1616 -183 1613 -173 ct 1610 -164 1609 -153 1609 -141 ct +1609 0 l 1569 0 l p ef +1840 -113 m 1840 -100 1841 -89 1844 -78 ct 1846 -67 1850 -58 1856 -51 ct 1861 -43 1868 -37 1877 -33 ct +1885 -28 1896 -26 1908 -26 ct 1925 -26 1939 -30 1950 -37 ct 1960 -44 1967 -53 1971 -63 ct +2006 -53 l 2004 -47 2000 -40 1996 -33 ct 1991 -26 1985 -20 1977 -15 ct 1970 -9 1960 -5 1949 -1 ct +1937 2 1924 4 1908 4 ct 1872 4 1844 -7 1826 -28 ct 1807 -49 1798 -81 1798 -123 ct +1798 -146 1800 -165 1806 -181 ct 1812 -197 1819 -210 1829 -220 ct 1839 -230 1851 -237 1864 -241 ct +1877 -246 1891 -248 1906 -248 ct 1926 -248 1943 -245 1957 -238 ct 1971 -231 1982 -222 1990 -211 ct +1998 -199 2004 -185 2008 -170 ct 2011 -154 2013 -137 2013 -118 ct 2013 -113 l +1840 -113 l p +1971 -144 m 1969 -170 1962 -188 1952 -200 ct 1941 -212 1925 -218 1905 -218 ct +1899 -218 1892 -217 1884 -215 ct 1877 -213 1870 -209 1864 -203 ct 1857 -198 1852 -190 1848 -180 ct +1843 -171 1841 -159 1840 -144 ct 1971 -144 l p ef +2190 -293 m 2190 -332 l 2230 -332 l 2230 -293 l 2190 -293 l p +2230 30 m 2230 39 2229 48 2228 56 ct 2226 64 2223 70 2219 76 ct 2215 82 2210 87 2203 90 ct +2196 93 2187 95 2176 95 ct 2171 95 2166 95 2161 95 ct 2157 95 2152 94 2148 93 ct +2148 62 l 2150 63 2152 63 2155 63 ct 2157 63 2160 64 2162 64 ct 2167 64 2172 63 2176 61 ct +2179 60 2182 58 2184 54 ct 2186 51 2188 47 2189 42 ct 2189 37 2190 31 2190 24 ct +2190 -242 l 2230 -242 l 2230 30 l p ef +2497 -122 m 2497 -80 2488 -48 2469 -27 ct 2450 -6 2423 4 2388 4 ct 2371 4 2356 1 2342 -4 ct +2329 -9 2318 -17 2309 -27 ct 2299 -37 2292 -51 2288 -66 ct 2283 -82 2280 -101 2280 -122 ct +2280 -206 2317 -248 2389 -248 ct 2408 -248 2424 -245 2438 -240 ct 2451 -235 2463 -227 2471 -216 ct +2480 -206 2487 -193 2491 -177 ct 2495 -161 2497 -143 2497 -122 ct p +2455 -122 m 2455 -141 2453 -157 2450 -169 ct 2447 -181 2443 -191 2438 -198 ct +2432 -206 2425 -211 2417 -214 ct 2409 -217 2400 -218 2390 -218 ct 2379 -218 2370 -216 2362 -213 ct +2353 -210 2346 -205 2341 -198 ct 2335 -190 2330 -180 2327 -168 ct 2324 -156 2323 -141 2323 -122 ct +2323 -103 2324 -88 2328 -75 ct 2331 -63 2335 -53 2341 -46 ct 2347 -38 2354 -33 2362 -30 ct +2369 -27 2378 -26 2387 -26 ct 2397 -26 2407 -27 2415 -30 ct 2424 -33 2431 -38 2436 -46 ct +2442 -53 2447 -63 2450 -75 ct 2453 -88 2455 -103 2455 -122 ct p ef +2546 -293 m 2546 -332 l 2586 -332 l 2586 -293 l 2546 -293 l p +2546 1 m 2546 -242 l 2586 -242 l 2586 1 l 2546 1 l p ef +2801 0 m 2801 -154 l 2801 -166 2800 -175 2798 -183 ct 2797 -191 2794 -198 2790 -203 ct +2786 -207 2781 -211 2775 -213 ct 2768 -215 2760 -216 2751 -216 ct 2741 -216 2733 -214 2725 -211 ct +2717 -207 2711 -203 2705 -196 ct 2700 -190 2696 -182 2693 -173 ct 2690 -163 2688 -153 2688 -141 ct +2688 0 l 2648 0 l 2648 -191 l 2648 -196 2648 -201 2648 -207 ct 2648 -212 2648 -218 2647 -223 ct +2647 -228 2647 -232 2647 -236 ct 2647 -239 2647 -241 2646 -243 ct 2685 -243 l +2685 -242 2685 -240 2685 -236 ct 2685 -233 2685 -229 2686 -225 ct 2686 -221 2686 -217 2686 -212 ct +2686 -208 2686 -204 2686 -201 ct 2687 -201 l 2691 -208 2695 -214 2700 -220 ct +2704 -226 2710 -231 2716 -235 ct 2722 -239 2729 -242 2737 -244 ct 2745 -246 2754 -247 2765 -247 ct +2778 -247 2790 -245 2799 -242 ct 2809 -239 2817 -234 2823 -227 ct 2830 -220 2834 -211 2837 -200 ct +2840 -189 2841 -177 2841 -162 ct 2841 0 l 2801 0 l p ef +3233 -123 m 3233 -104 3232 -87 3229 -72 ct 3226 -56 3221 -43 3214 -32 ct 3207 -21 3197 -12 3186 -6 ct +3175 1 3161 4 3144 4 ct 3126 4 3111 1 3098 -6 ct 3085 -12 3075 -23 3069 -38 ct +3067 -38 l 3068 -38 3068 -36 3068 -34 ct 3068 -32 3068 -29 3068 -25 ct 3068 -22 3068 -18 3068 -13 ct +3068 -9 3068 -4 3068 0 ct 3068 95 l 3028 95 l 3028 -193 l 3028 -199 3028 -205 3028 -210 ct +3028 -215 3028 -220 3027 -225 ct 3027 -229 3027 -233 3027 -236 ct 3027 -239 3027 -241 3027 -243 ct +3066 -243 l 3066 -242 3066 -241 3066 -238 ct 3066 -235 3067 -232 3067 -228 ct +3067 -225 3067 -220 3067 -216 ct 3068 -212 3068 -208 3068 -204 ct 3069 -204 l +3072 -212 3077 -218 3082 -224 ct 3086 -229 3092 -234 3098 -237 ct 3104 -241 3111 -243 3118 -245 ct +3126 -246 3134 -247 3144 -247 ct 3161 -247 3175 -244 3186 -238 ct 3197 -232 3207 -224 3214 -213 ct +3221 -202 3226 -189 3229 -174 ct 3232 -158 3233 -141 3233 -123 ct p +3191 -122 m 3191 -137 3190 -150 3188 -162 ct 3186 -173 3183 -183 3179 -191 ct +3174 -199 3168 -205 3161 -210 ct 3154 -214 3145 -216 3133 -216 ct 3125 -216 3116 -215 3108 -212 ct +3100 -210 3093 -205 3087 -198 ct 3082 -190 3077 -180 3073 -168 ct 3070 -155 3068 -139 3068 -119 ct +3068 -102 3070 -87 3073 -75 ct 3075 -63 3080 -54 3085 -46 ct 3090 -39 3097 -34 3105 -31 ct +3113 -27 3123 -26 3133 -26 ct 3144 -26 3154 -28 3161 -32 ct 3168 -37 3174 -43 3179 -51 ct +3183 -59 3186 -69 3188 -81 ct 3190 -93 3191 -107 3191 -122 ct p ef +3487 -122 m 3487 -80 3478 -48 3459 -27 ct 3440 -6 3413 4 3378 4 ct 3361 4 3346 1 3332 -4 ct +3319 -9 3308 -17 3299 -27 ct 3289 -37 3282 -51 3278 -66 ct 3273 -82 3270 -101 3270 -122 ct +3270 -206 3307 -248 3379 -248 ct 3398 -248 3414 -245 3428 -240 ct 3441 -235 3453 -227 3461 -216 ct +3470 -206 3477 -193 3481 -177 ct 3485 -161 3487 -143 3487 -122 ct p +3445 -122 m 3445 -141 3443 -157 3440 -169 ct 3437 -181 3433 -191 3428 -198 ct +3422 -206 3415 -211 3407 -214 ct 3399 -217 3390 -218 3380 -218 ct 3369 -218 3360 -216 3352 -213 ct +3343 -210 3336 -205 3331 -198 ct 3325 -190 3320 -180 3317 -168 ct 3314 -156 3313 -141 3313 -122 ct +3313 -103 3314 -88 3318 -75 ct 3321 -63 3325 -53 3331 -46 ct 3337 -38 3344 -33 3352 -30 ct +3359 -27 3368 -26 3377 -26 ct 3387 -26 3397 -27 3405 -30 ct 3414 -33 3421 -38 3426 -46 ct +3432 -53 3437 -63 3440 -75 ct 3443 -88 3445 -103 3445 -122 ct p ef +3536 -293 m 3536 -332 l 3576 -332 l 3576 -293 l 3536 -293 l p +3536 1 m 3536 -242 l 3576 -242 l 3576 1 l 3536 1 l p ef +3792 0 m 3792 -154 l 3792 -166 3791 -175 3789 -183 ct 3788 -191 3785 -198 3781 -203 ct +3777 -207 3772 -211 3766 -213 ct 3759 -215 3751 -216 3742 -216 ct 3732 -216 3724 -214 3716 -211 ct +3708 -207 3702 -203 3696 -196 ct 3691 -190 3687 -182 3684 -173 ct 3681 -163 3679 -153 3679 -141 ct +3679 0 l 3639 0 l 3639 -191 l 3639 -196 3639 -201 3639 -207 ct 3639 -212 3639 -218 3638 -223 ct +3638 -228 3638 -232 3638 -236 ct 3638 -239 3638 -241 3637 -243 ct 3676 -243 l +3676 -242 3676 -240 3676 -236 ct 3676 -233 3676 -229 3677 -225 ct 3677 -221 3677 -217 3677 -212 ct +3677 -208 3677 -204 3677 -201 ct 3678 -201 l 3682 -208 3686 -214 3691 -220 ct +3695 -226 3701 -231 3707 -235 ct 3713 -239 3720 -242 3728 -244 ct 3736 -246 3745 -247 3756 -247 ct +3769 -247 3781 -245 3790 -242 ct 3800 -239 3808 -234 3814 -227 ct 3821 -220 3825 -211 3828 -200 ct +3831 -189 3832 -177 3832 -162 ct 3832 0 l 3792 0 l p ef +3985 -1 m 3979 0 3973 2 3966 3 ct 3960 4 3953 4 3944 4 ct 3912 4 3896 -14 3896 -51 ct +3896 -213 l 3868 -213 l 3868 -242 l 3898 -242 l 3909 -297 l 3936 -297 l +3936 -242 l 3981 -242 l 3981 -213 l 3936 -213 l 3936 -60 l 3936 -48 3938 -40 3942 -35 ct +3946 -30 3952 -28 3962 -28 ct 3966 -28 3970 -28 3973 -29 ct 3977 -30 3981 -30 3985 -31 ct +3985 -1 l p ef +4201 -68 m 4201 -56 4199 -46 4194 -37 ct 4190 -28 4184 -21 4175 -15 ct 4167 -9 4157 -4 4144 -1 ct +4132 2 4118 4 4103 4 ct 4088 4 4076 3 4065 1 ct 4053 -1 4043 -5 4035 -10 ct 4026 -14 4019 -21 4013 -29 ct +4008 -36 4003 -46 4001 -57 ct 4036 -64 l 4040 -51 4047 -42 4058 -36 ct 4068 -30 4083 -27 4103 -27 ct +4111 -27 4119 -27 4126 -29 ct 4134 -30 4140 -32 4145 -35 ct 4150 -38 4154 -41 4157 -46 ct +4160 -51 4162 -57 4162 -64 ct 4162 -72 4160 -78 4157 -82 ct 4153 -87 4148 -91 4142 -94 ct +4136 -97 4129 -100 4120 -102 ct 4111 -105 4102 -107 4091 -110 ct 4081 -113 4072 -116 4062 -119 ct +4053 -122 4044 -126 4036 -131 ct 4029 -136 4022 -143 4018 -150 ct 4013 -158 4010 -168 4010 -179 ct +4010 -201 4018 -218 4034 -230 ct 4050 -241 4073 -247 4103 -247 ct 4130 -247 4151 -242 4167 -233 ct +4183 -223 4192 -208 4197 -188 ct 4160 -183 l 4159 -189 4157 -195 4153 -199 ct +4149 -203 4145 -207 4140 -209 ct 4135 -212 4129 -214 4123 -215 ct 4116 -216 4110 -217 4103 -217 ct +4085 -217 4071 -214 4063 -208 ct 4054 -203 4050 -194 4050 -183 ct 4050 -177 4051 -171 4054 -167 ct +4058 -163 4062 -159 4068 -156 ct 4074 -153 4081 -151 4089 -148 ct 4097 -146 4106 -144 4115 -142 ct +4122 -140 4128 -138 4135 -136 ct 4142 -134 4148 -132 4155 -130 ct 4161 -127 4167 -124 4173 -120 ct +4178 -117 4183 -113 4187 -108 ct 4191 -103 4195 -97 4197 -90 ct 4200 -84 4201 -76 4201 -68 ct +p ef +pom +pum +14565 16562 t +32 0 m 32 -186 l 32 -191 32 -196 32 -202 ct 32 -207 32 -212 31 -217 ct 31 -222 31 -227 31 -231 ct +31 -235 31 -239 30 -243 ct 69 -243 l 69 -239 69 -235 69 -231 ct 69 -226 70 -222 70 -217 ct +70 -213 70 -208 70 -204 ct 70 -200 70 -196 70 -193 ct 71 -193 l 74 -202 77 -210 80 -217 ct +84 -224 87 -229 92 -234 ct 96 -238 101 -242 107 -244 ct 113 -246 120 -247 129 -247 ct +132 -247 135 -247 138 -246 ct 141 -246 144 -245 145 -245 ct 145 -208 l 143 -209 139 -209 136 -209 ct +132 -210 128 -210 124 -210 ct 114 -210 107 -208 100 -204 ct 94 -200 88 -194 84 -186 ct +80 -179 77 -170 75 -160 ct 73 -150 72 -139 72 -126 ct 72 0 l 32 0 l p ef +214 -113 m 214 -100 215 -89 218 -78 ct 220 -67 224 -58 230 -51 ct 235 -43 242 -37 251 -33 ct +259 -28 270 -26 282 -26 ct 299 -26 313 -30 324 -37 ct 334 -44 341 -53 345 -63 ct +380 -53 l 378 -47 374 -40 370 -33 ct 365 -26 359 -20 351 -15 ct 344 -9 334 -5 323 -1 ct +311 2 298 4 282 4 ct 246 4 218 -7 200 -28 ct 181 -49 172 -81 172 -123 ct 172 -146 174 -165 180 -181 ct +186 -197 193 -210 203 -220 ct 213 -230 225 -237 238 -241 ct 251 -246 265 -248 280 -248 ct +300 -248 317 -245 331 -238 ct 345 -231 356 -222 364 -211 ct 372 -199 378 -185 382 -170 ct +385 -154 387 -137 387 -118 ct 387 -113 l 214 -113 l p +345 -144 m 343 -170 336 -188 326 -200 ct 315 -212 299 -218 279 -218 ct 273 -218 266 -217 258 -215 ct +251 -213 244 -209 238 -203 ct 231 -198 226 -190 222 -180 ct 217 -171 215 -159 214 -144 ct +345 -144 l p ef +437 1 m 437 -332 l 477 -332 l 477 1 l 437 1 l p ef +601 4 m 576 4 558 -2 546 -15 ct 534 -28 528 -46 528 -69 ct 528 -85 531 -98 537 -108 ct +543 -118 551 -127 560 -132 ct 570 -138 581 -142 594 -145 ct 606 -147 619 -148 632 -148 ct +687 -148 l 687 -161 l 687 -171 686 -180 683 -187 ct 681 -194 678 -200 674 -204 ct +670 -209 664 -212 658 -214 ct 651 -216 643 -217 635 -217 ct 627 -217 620 -216 614 -215 ct +607 -214 602 -212 597 -209 ct 593 -206 589 -202 586 -197 ct 583 -192 581 -186 580 -178 ct +538 -182 l 540 -192 543 -201 547 -209 ct 551 -217 557 -224 565 -229 ct 572 -235 582 -240 594 -243 ct +605 -246 619 -248 636 -248 ct 666 -248 689 -241 704 -227 ct 720 -213 727 -192 727 -166 ct +727 -61 l 727 -49 729 -40 732 -34 ct 735 -28 741 -25 750 -25 ct 752 -25 755 -25 757 -26 ct +759 -26 761 -26 763 -27 ct 763 -2 l 758 0 753 1 748 1 ct 743 2 738 2 732 2 ct +725 2 718 1 713 -1 ct 707 -3 703 -6 699 -10 ct 696 -14 693 -20 691 -26 ct 690 -32 688 -39 688 -47 ct +687 -47 l 682 -39 678 -32 672 -26 ct 667 -20 661 -14 654 -10 ct 647 -5 640 -2 631 0 ct +622 3 612 4 601 4 ct p +610 -26 m 623 -26 634 -29 644 -33 ct 653 -38 661 -44 668 -51 ct 674 -59 679 -67 682 -75 ct +685 -84 687 -92 687 -100 ct 687 -120 l 642 -120 l 633 -120 623 -119 614 -118 ct +605 -117 598 -114 591 -110 ct 584 -107 579 -101 575 -94 ct 571 -88 569 -79 569 -68 ct +569 -55 573 -44 580 -37 ct 587 -30 597 -26 610 -26 ct p ef +886 -1 m 880 0 874 2 867 3 ct 861 4 854 4 845 4 ct 813 4 797 -14 797 -51 ct 797 -213 l +769 -213 l 769 -242 l 799 -242 l 810 -297 l 837 -297 l 837 -242 l +882 -242 l 882 -213 l 837 -213 l 837 -60 l 837 -48 839 -40 843 -35 ct +847 -30 853 -28 863 -28 ct 867 -28 871 -28 874 -29 ct 878 -30 882 -30 886 -31 ct +886 -1 l p ef +920 -293 m 920 -332 l 960 -332 l 960 -293 l 920 -293 l p +920 1 m 920 -242 l 960 -242 l 960 1 l 920 1 l p ef +1227 -122 m 1227 -80 1218 -48 1199 -27 ct 1180 -6 1153 4 1118 4 ct 1101 4 1086 1 1072 -4 ct +1059 -9 1048 -17 1039 -27 ct 1029 -37 1022 -51 1018 -66 ct 1013 -82 1010 -101 1010 -122 ct +1010 -206 1047 -248 1119 -248 ct 1138 -248 1154 -245 1168 -240 ct 1181 -235 1193 -227 1201 -216 ct +1210 -206 1217 -193 1221 -177 ct 1225 -161 1227 -143 1227 -122 ct p +1185 -122 m 1185 -141 1183 -157 1180 -169 ct 1177 -181 1173 -191 1168 -198 ct +1162 -206 1155 -211 1147 -214 ct 1139 -217 1130 -218 1120 -218 ct 1109 -218 1100 -216 1092 -213 ct +1083 -210 1076 -205 1071 -198 ct 1065 -190 1060 -180 1057 -168 ct 1054 -156 1053 -141 1053 -122 ct +1053 -103 1054 -88 1058 -75 ct 1061 -63 1065 -53 1071 -46 ct 1077 -38 1084 -33 1092 -30 ct +1099 -27 1108 -26 1117 -26 ct 1127 -26 1137 -27 1145 -30 ct 1154 -33 1161 -38 1166 -46 ct +1172 -53 1177 -63 1180 -75 ct 1183 -88 1185 -103 1185 -122 ct p ef +1430 0 m 1430 -154 l 1430 -166 1429 -175 1427 -183 ct 1426 -191 1423 -198 1419 -203 ct +1415 -207 1410 -211 1404 -213 ct 1397 -215 1389 -216 1380 -216 ct 1370 -216 1362 -214 1354 -211 ct +1346 -207 1340 -203 1334 -196 ct 1329 -190 1325 -182 1322 -173 ct 1319 -163 1317 -153 1317 -141 ct +1317 0 l 1277 0 l 1277 -191 l 1277 -196 1277 -201 1277 -207 ct 1277 -212 1277 -218 1276 -223 ct +1276 -228 1276 -232 1276 -236 ct 1276 -239 1276 -241 1275 -243 ct 1314 -243 l +1314 -242 1314 -240 1314 -236 ct 1314 -233 1314 -229 1315 -225 ct 1315 -221 1315 -217 1315 -212 ct +1315 -208 1315 -204 1315 -201 ct 1316 -201 l 1320 -208 1324 -214 1329 -220 ct +1333 -226 1339 -231 1345 -235 ct 1351 -239 1358 -242 1366 -244 ct 1374 -246 1383 -247 1394 -247 ct +1407 -247 1419 -245 1428 -242 ct 1438 -239 1446 -234 1452 -227 ct 1459 -220 1463 -211 1466 -200 ct +1469 -189 1470 -177 1470 -162 ct 1470 0 l 1430 0 l p ef +1862 -122 m 1862 -37 1832 5 1773 5 ct 1754 5 1739 2 1727 -5 ct 1715 -12 1705 -22 1697 -37 ct +1697 -37 l 1697 -33 1697 -29 1696 -25 ct 1696 -21 1696 -17 1696 -13 ct 1696 -10 1695 -7 1695 -4 ct +1695 -2 1695 0 1695 1 ct 1656 1 l 1656 -1 1656 -3 1656 -6 ct 1656 -9 1656 -13 1656 -18 ct +1657 -22 1657 -27 1657 -33 ct 1657 -38 1657 -44 1657 -49 ct 1657 -332 l 1697 -332 l +1697 -237 l 1697 -233 1697 -228 1697 -224 ct 1697 -220 1697 -216 1697 -213 ct +1697 -210 1697 -206 1696 -203 ct 1697 -203 l 1705 -218 1715 -229 1727 -236 ct +1739 -243 1755 -246 1773 -246 ct 1803 -246 1826 -236 1840 -215 ct 1855 -195 1862 -163 1862 -122 ct +p +1820 -120 m 1820 -137 1819 -151 1817 -163 ct 1814 -175 1811 -185 1806 -193 ct +1802 -200 1796 -206 1789 -210 ct 1782 -213 1773 -215 1762 -215 ct 1752 -215 1743 -213 1734 -210 ct +1726 -206 1719 -201 1714 -193 ct 1709 -186 1704 -176 1702 -163 ct 1699 -151 1697 -136 1697 -118 ct +1697 -101 1699 -86 1702 -74 ct 1704 -62 1709 -53 1714 -46 ct 1719 -38 1726 -33 1734 -30 ct +1742 -26 1752 -25 1762 -25 ct 1772 -25 1780 -27 1788 -30 ct 1795 -33 1801 -39 1806 -47 ct +1810 -54 1814 -64 1816 -76 ct 1818 -88 1820 -103 1820 -120 ct p ef +1942 -113 m 1942 -100 1943 -89 1946 -78 ct 1948 -67 1952 -58 1958 -51 ct 1963 -43 1970 -37 1979 -33 ct +1987 -28 1998 -26 2010 -26 ct 2027 -26 2041 -30 2052 -37 ct 2062 -44 2069 -53 2073 -63 ct +2108 -53 l 2106 -47 2102 -40 2098 -33 ct 2093 -26 2087 -20 2079 -15 ct 2072 -9 2062 -5 2051 -1 ct +2039 2 2026 4 2010 4 ct 1974 4 1946 -7 1928 -28 ct 1909 -49 1900 -81 1900 -123 ct +1900 -146 1902 -165 1908 -181 ct 1914 -197 1921 -210 1931 -220 ct 1941 -230 1953 -237 1966 -241 ct +1979 -246 1993 -248 2008 -248 ct 2028 -248 2045 -245 2059 -238 ct 2073 -231 2084 -222 2092 -211 ct +2100 -199 2106 -185 2110 -170 ct 2113 -154 2115 -137 2115 -118 ct 2115 -113 l +1942 -113 l p +2073 -144 m 2071 -170 2064 -188 2054 -200 ct 2043 -212 2027 -218 2007 -218 ct +2001 -218 1994 -217 1986 -215 ct 1979 -213 1972 -209 1966 -203 ct 1959 -198 1954 -190 1950 -180 ct +1945 -171 1943 -159 1942 -144 ct 2073 -144 l p ef +2258 -1 m 2252 0 2246 2 2239 3 ct 2233 4 2226 4 2217 4 ct 2185 4 2169 -14 2169 -51 ct +2169 -213 l 2141 -213 l 2141 -242 l 2171 -242 l 2182 -297 l 2209 -297 l +2209 -242 l 2254 -242 l 2254 -213 l 2209 -213 l 2209 -60 l 2209 -48 2211 -40 2215 -35 ct +2219 -30 2225 -28 2235 -28 ct 2239 -28 2243 -28 2246 -29 ct 2250 -30 2254 -30 2258 -31 ct +2258 -1 l p ef +2524 0 m 2477 0 l 2439 -156 l 2437 -160 2436 -165 2435 -171 ct 2434 -177 2432 -183 2431 -189 ct +2430 -196 2428 -202 2427 -209 ct 2426 -203 2424 -196 2423 -189 ct 2421 -184 2420 -178 2419 -172 ct +2417 -166 2416 -160 2415 -156 ct 2375 0 l 2328 0 l 2260 -243 l 2300 -243 l +2341 -78 l 2342 -74 2343 -70 2344 -65 ct 2345 -60 2346 -55 2348 -50 ct 2349 -45 2350 -39 2351 -33 ct +2352 -39 2353 -45 2355 -50 ct 2356 -55 2357 -59 2358 -64 ct 2359 -69 2361 -73 2361 -76 ct +2405 -243 l 2449 -243 l 2491 -76 l 2492 -72 2493 -68 2494 -63 ct 2496 -58 2497 -53 2498 -49 ct +2499 -44 2500 -39 2501 -33 ct 2502 -39 2504 -45 2505 -50 ct 2506 -55 2507 -59 2508 -64 ct +2509 -69 2510 -74 2511 -78 ct 2554 -243 l 2594 -243 l 2524 0 l p ef +2649 -113 m 2649 -100 2650 -89 2653 -78 ct 2655 -67 2659 -58 2665 -51 ct 2670 -43 2677 -37 2686 -33 ct +2694 -28 2705 -26 2717 -26 ct 2734 -26 2748 -30 2759 -37 ct 2769 -44 2776 -53 2780 -63 ct +2815 -53 l 2813 -47 2809 -40 2805 -33 ct 2800 -26 2794 -20 2786 -15 ct 2779 -9 2769 -5 2758 -1 ct +2746 2 2733 4 2717 4 ct 2681 4 2653 -7 2635 -28 ct 2616 -49 2607 -81 2607 -123 ct +2607 -146 2609 -165 2615 -181 ct 2621 -197 2628 -210 2638 -220 ct 2648 -230 2660 -237 2673 -241 ct +2686 -246 2700 -248 2715 -248 ct 2735 -248 2752 -245 2766 -238 ct 2780 -231 2791 -222 2799 -211 ct +2807 -199 2813 -185 2817 -170 ct 2820 -154 2822 -137 2822 -118 ct 2822 -113 l +2649 -113 l p +2780 -144 m 2778 -170 2771 -188 2761 -200 ct 2750 -212 2734 -218 2714 -218 ct +2708 -218 2701 -217 2693 -215 ct 2686 -213 2679 -209 2673 -203 ct 2666 -198 2661 -190 2657 -180 ct +2652 -171 2650 -159 2649 -144 ct 2780 -144 l p ef +2903 -113 m 2903 -100 2904 -89 2907 -78 ct 2909 -67 2913 -58 2919 -51 ct 2924 -43 2931 -37 2940 -33 ct +2948 -28 2959 -26 2971 -26 ct 2988 -26 3002 -30 3013 -37 ct 3023 -44 3030 -53 3034 -63 ct +3069 -53 l 3067 -47 3063 -40 3059 -33 ct 3054 -26 3048 -20 3040 -15 ct 3033 -9 3023 -5 3012 -1 ct +3000 2 2987 4 2971 4 ct 2935 4 2907 -7 2889 -28 ct 2870 -49 2861 -81 2861 -123 ct +2861 -146 2863 -165 2869 -181 ct 2875 -197 2882 -210 2892 -220 ct 2902 -230 2914 -237 2927 -241 ct +2940 -246 2954 -248 2969 -248 ct 2989 -248 3006 -245 3020 -238 ct 3034 -231 3045 -222 3053 -211 ct +3061 -199 3067 -185 3071 -170 ct 3074 -154 3076 -137 3076 -118 ct 3076 -113 l +2903 -113 l p +3034 -144 m 3032 -170 3025 -188 3015 -200 ct 3004 -212 2988 -218 2968 -218 ct +2962 -218 2955 -217 2947 -215 ct 2940 -213 2933 -209 2927 -203 ct 2920 -198 2915 -190 2911 -180 ct +2906 -171 2904 -159 2903 -144 ct 3034 -144 l p ef +3280 0 m 3280 -154 l 3280 -166 3279 -175 3277 -183 ct 3276 -191 3273 -198 3269 -203 ct +3265 -207 3260 -211 3254 -213 ct 3247 -215 3239 -216 3230 -216 ct 3220 -216 3212 -214 3204 -211 ct +3196 -207 3190 -203 3184 -196 ct 3179 -190 3175 -182 3172 -173 ct 3169 -163 3167 -153 3167 -141 ct +3167 0 l 3127 0 l 3127 -191 l 3127 -196 3127 -201 3127 -207 ct 3127 -212 3127 -218 3126 -223 ct +3126 -228 3126 -232 3126 -236 ct 3126 -239 3126 -241 3125 -243 ct 3164 -243 l +3164 -242 3164 -240 3164 -236 ct 3164 -233 3164 -229 3165 -225 ct 3165 -221 3165 -217 3165 -212 ct +3165 -208 3165 -204 3165 -201 ct 3166 -201 l 3170 -208 3174 -214 3179 -220 ct +3183 -226 3189 -231 3195 -235 ct 3201 -239 3208 -242 3216 -244 ct 3224 -246 3233 -247 3244 -247 ct +3257 -247 3269 -245 3278 -242 ct 3288 -239 3296 -234 3302 -227 ct 3309 -220 3313 -211 3316 -200 ct +3319 -189 3320 -177 3320 -162 ct 3320 0 l 3280 0 l p ef +pom +pum +14565 17074 t +185 0 m 185 -154 l 185 -166 184 -175 182 -183 ct 181 -191 178 -198 174 -203 ct +170 -207 165 -211 159 -213 ct 152 -215 144 -216 135 -216 ct 125 -216 117 -214 109 -211 ct +101 -207 95 -203 89 -196 ct 84 -190 80 -182 77 -173 ct 74 -163 72 -153 72 -141 ct +72 0 l 32 0 l 32 -191 l 32 -196 32 -201 32 -207 ct 32 -212 32 -218 31 -223 ct +31 -228 31 -232 31 -236 ct 31 -239 31 -241 30 -243 ct 69 -243 l 69 -242 69 -240 69 -236 ct +69 -233 69 -229 70 -225 ct 70 -221 70 -217 70 -212 ct 70 -208 70 -204 70 -201 ct +71 -201 l 75 -208 79 -214 84 -220 ct 88 -226 94 -231 100 -235 ct 106 -239 113 -242 121 -244 ct +129 -246 138 -247 149 -247 ct 162 -247 174 -245 183 -242 ct 193 -239 201 -234 207 -227 ct +214 -220 218 -211 221 -200 ct 224 -189 225 -177 225 -162 ct 225 0 l 185 0 l +p ef +347 4 m 322 4 304 -2 292 -15 ct 280 -28 274 -46 274 -69 ct 274 -85 277 -98 283 -108 ct +289 -118 297 -127 306 -132 ct 316 -138 327 -142 340 -145 ct 352 -147 365 -148 378 -148 ct +433 -148 l 433 -161 l 433 -171 432 -180 429 -187 ct 427 -194 424 -200 420 -204 ct +416 -209 410 -212 404 -214 ct 397 -216 389 -217 381 -217 ct 373 -217 366 -216 360 -215 ct +353 -214 348 -212 343 -209 ct 339 -206 335 -202 332 -197 ct 329 -192 327 -186 326 -178 ct +284 -182 l 286 -192 289 -201 293 -209 ct 297 -217 303 -224 311 -229 ct 318 -235 328 -240 340 -243 ct +351 -246 365 -248 382 -248 ct 412 -248 435 -241 450 -227 ct 466 -213 473 -192 473 -166 ct +473 -61 l 473 -49 475 -40 478 -34 ct 481 -28 487 -25 496 -25 ct 498 -25 501 -25 503 -26 ct +505 -26 507 -26 509 -27 ct 509 -2 l 504 0 499 1 494 1 ct 489 2 484 2 478 2 ct +471 2 464 1 459 -1 ct 453 -3 449 -6 445 -10 ct 442 -14 439 -20 437 -26 ct 436 -32 434 -39 434 -47 ct +433 -47 l 428 -39 424 -32 418 -26 ct 413 -20 407 -14 400 -10 ct 393 -5 386 -2 377 0 ct +368 3 358 4 347 4 ct p +356 -26 m 369 -26 380 -29 390 -33 ct 399 -38 407 -44 414 -51 ct 420 -59 425 -67 428 -75 ct +431 -84 433 -92 433 -100 ct 433 -120 l 388 -120 l 379 -120 369 -119 360 -118 ct +351 -117 344 -114 337 -110 ct 330 -107 325 -101 321 -94 ct 317 -88 315 -79 315 -68 ct +315 -55 319 -44 326 -37 ct 333 -30 343 -26 356 -26 ct p ef +680 0 m 680 -154 l 680 -166 679 -175 678 -183 ct 676 -191 674 -198 670 -203 ct +667 -207 662 -211 657 -213 ct 651 -215 644 -216 636 -216 ct 627 -216 620 -214 613 -211 ct +606 -207 600 -203 595 -196 ct 590 -190 586 -182 584 -173 ct 581 -163 580 -153 580 -141 ct +580 0 l 540 0 l 540 -191 l 540 -196 540 -201 540 -207 ct 540 -212 540 -218 539 -223 ct +539 -228 539 -232 539 -236 ct 539 -239 539 -241 538 -243 ct 577 -243 l 577 -242 577 -240 577 -236 ct +577 -233 577 -229 578 -225 ct 578 -221 578 -217 578 -212 ct 578 -208 578 -204 578 -201 ct +579 -201 l 583 -208 587 -214 591 -220 ct 595 -226 600 -231 605 -235 ct 611 -239 617 -242 625 -244 ct +632 -246 640 -247 650 -247 ct 668 -247 683 -243 693 -236 ct 704 -229 712 -217 716 -201 ct +716 -201 l 720 -208 724 -214 729 -220 ct 733 -226 738 -231 744 -235 ct 750 -239 757 -242 764 -244 ct +772 -246 780 -247 790 -247 ct 802 -247 813 -245 822 -242 ct 831 -239 838 -234 844 -227 ct +849 -220 853 -211 856 -200 ct 859 -189 860 -177 860 -162 ct 860 0 l 820 0 l +820 -154 l 820 -166 819 -175 818 -183 ct 816 -191 814 -198 810 -203 ct 807 -207 802 -211 797 -213 ct +791 -215 784 -216 776 -216 ct 767 -216 760 -214 753 -211 ct 746 -208 740 -203 735 -197 ct +730 -191 727 -183 724 -173 ct 721 -164 720 -153 720 -141 ct 720 0 l 680 0 l +p ef +951 -113 m 951 -100 952 -89 955 -78 ct 957 -67 961 -58 967 -51 ct 972 -43 979 -37 988 -33 ct +996 -28 1007 -26 1019 -26 ct 1036 -26 1050 -30 1061 -37 ct 1071 -44 1078 -53 1082 -63 ct +1117 -53 l 1115 -47 1111 -40 1107 -33 ct 1102 -26 1096 -20 1088 -15 ct 1081 -9 1071 -5 1060 -1 ct +1048 2 1035 4 1019 4 ct 983 4 955 -7 937 -28 ct 918 -49 909 -81 909 -123 ct 909 -146 911 -165 917 -181 ct +923 -197 930 -210 940 -220 ct 950 -230 962 -237 975 -241 ct 988 -246 1002 -248 1017 -248 ct +1037 -248 1054 -245 1068 -238 ct 1082 -231 1093 -222 1101 -211 ct 1109 -199 1115 -185 1119 -170 ct +1122 -154 1124 -137 1124 -118 ct 1124 -113 l 951 -113 l p +1082 -144 m 1080 -170 1073 -188 1063 -200 ct 1052 -212 1036 -218 1016 -218 ct +1010 -218 1003 -217 995 -215 ct 988 -213 981 -209 975 -203 ct 968 -198 963 -190 959 -180 ct +954 -171 952 -159 951 -144 ct 1082 -144 l p ef +1301 -293 m 1301 -332 l 1341 -332 l 1341 -293 l 1301 -293 l p +1341 30 m 1341 39 1340 48 1339 56 ct 1337 64 1334 70 1330 76 ct 1326 82 1321 87 1314 90 ct +1307 93 1298 95 1287 95 ct 1282 95 1277 95 1272 95 ct 1268 95 1263 94 1259 93 ct +1259 62 l 1261 63 1263 63 1266 63 ct 1268 63 1271 64 1273 64 ct 1278 64 1283 63 1287 61 ct +1290 60 1293 58 1295 54 ct 1297 51 1299 47 1300 42 ct 1300 37 1301 31 1301 24 ct +1301 -242 l 1341 -242 l 1341 30 l p ef +1608 -122 m 1608 -80 1599 -48 1580 -27 ct 1561 -6 1534 4 1499 4 ct 1482 4 1467 1 1453 -4 ct +1440 -9 1429 -17 1420 -27 ct 1410 -37 1403 -51 1399 -66 ct 1394 -82 1391 -101 1391 -122 ct +1391 -206 1428 -248 1500 -248 ct 1519 -248 1535 -245 1549 -240 ct 1562 -235 1574 -227 1582 -216 ct +1591 -206 1598 -193 1602 -177 ct 1606 -161 1608 -143 1608 -122 ct p +1566 -122 m 1566 -141 1564 -157 1561 -169 ct 1558 -181 1554 -191 1549 -198 ct +1543 -206 1536 -211 1528 -214 ct 1520 -217 1511 -218 1501 -218 ct 1490 -218 1481 -216 1473 -213 ct +1464 -210 1457 -205 1452 -198 ct 1446 -190 1441 -180 1438 -168 ct 1435 -156 1434 -141 1434 -122 ct +1434 -103 1435 -88 1439 -75 ct 1442 -63 1446 -53 1452 -46 ct 1458 -38 1465 -33 1473 -30 ct +1480 -27 1489 -26 1498 -26 ct 1508 -26 1518 -27 1526 -30 ct 1535 -33 1542 -38 1547 -46 ct +1553 -53 1558 -63 1561 -75 ct 1564 -88 1566 -103 1566 -122 ct p ef +1657 -293 m 1657 -332 l 1697 -332 l 1697 -293 l 1657 -293 l p +1657 1 m 1657 -242 l 1697 -242 l 1697 1 l 1657 1 l p ef +1912 0 m 1912 -154 l 1912 -166 1911 -175 1909 -183 ct 1908 -191 1905 -198 1901 -203 ct +1897 -207 1892 -211 1886 -213 ct 1879 -215 1871 -216 1862 -216 ct 1852 -216 1844 -214 1836 -211 ct +1828 -207 1822 -203 1816 -196 ct 1811 -190 1807 -182 1804 -173 ct 1801 -163 1799 -153 1799 -141 ct +1799 0 l 1759 0 l 1759 -191 l 1759 -196 1759 -201 1759 -207 ct 1759 -212 1759 -218 1758 -223 ct +1758 -228 1758 -232 1758 -236 ct 1758 -239 1758 -241 1757 -243 ct 1796 -243 l +1796 -242 1796 -240 1796 -236 ct 1796 -233 1796 -229 1797 -225 ct 1797 -221 1797 -217 1797 -212 ct +1797 -208 1797 -204 1797 -201 ct 1798 -201 l 1802 -208 1806 -214 1811 -220 ct +1815 -226 1821 -231 1827 -235 ct 1833 -239 1840 -242 1848 -244 ct 1856 -246 1865 -247 1876 -247 ct +1889 -247 1901 -245 1910 -242 ct 1920 -239 1928 -234 1934 -227 ct 1941 -220 1945 -211 1948 -200 ct +1951 -189 1952 -177 1952 -162 ct 1952 0 l 1912 0 l p ef +2344 -123 m 2344 -104 2343 -87 2340 -72 ct 2337 -56 2332 -43 2325 -32 ct 2318 -21 2308 -12 2297 -6 ct +2286 1 2272 4 2255 4 ct 2237 4 2222 1 2209 -6 ct 2196 -12 2186 -23 2180 -38 ct +2178 -38 l 2179 -38 2179 -36 2179 -34 ct 2179 -32 2179 -29 2179 -25 ct 2179 -22 2179 -18 2179 -13 ct +2179 -9 2179 -4 2179 0 ct 2179 95 l 2139 95 l 2139 -193 l 2139 -199 2139 -205 2139 -210 ct +2139 -215 2139 -220 2138 -225 ct 2138 -229 2138 -233 2138 -236 ct 2138 -239 2138 -241 2138 -243 ct +2177 -243 l 2177 -242 2177 -241 2177 -238 ct 2177 -235 2178 -232 2178 -228 ct +2178 -225 2178 -220 2178 -216 ct 2179 -212 2179 -208 2179 -204 ct 2180 -204 l +2183 -212 2188 -218 2193 -224 ct 2197 -229 2203 -234 2209 -237 ct 2215 -241 2222 -243 2229 -245 ct +2237 -246 2245 -247 2255 -247 ct 2272 -247 2286 -244 2297 -238 ct 2308 -232 2318 -224 2325 -213 ct +2332 -202 2337 -189 2340 -174 ct 2343 -158 2344 -141 2344 -123 ct p +2302 -122 m 2302 -137 2301 -150 2299 -162 ct 2297 -173 2294 -183 2290 -191 ct +2285 -199 2279 -205 2272 -210 ct 2265 -214 2256 -216 2244 -216 ct 2236 -216 2227 -215 2219 -212 ct +2211 -210 2204 -205 2198 -198 ct 2193 -190 2188 -180 2184 -168 ct 2181 -155 2179 -139 2179 -119 ct +2179 -102 2181 -87 2184 -75 ct 2186 -63 2191 -54 2196 -46 ct 2201 -39 2208 -34 2216 -31 ct +2224 -27 2234 -26 2244 -26 ct 2255 -26 2265 -28 2272 -32 ct 2279 -37 2285 -43 2290 -51 ct +2294 -59 2297 -69 2299 -81 ct 2301 -93 2302 -107 2302 -122 ct p ef +2598 -122 m 2598 -80 2589 -48 2570 -27 ct 2551 -6 2524 4 2489 4 ct 2472 4 2457 1 2443 -4 ct +2430 -9 2419 -17 2410 -27 ct 2400 -37 2393 -51 2389 -66 ct 2384 -82 2381 -101 2381 -122 ct +2381 -206 2418 -248 2490 -248 ct 2509 -248 2525 -245 2539 -240 ct 2552 -235 2564 -227 2572 -216 ct +2581 -206 2588 -193 2592 -177 ct 2596 -161 2598 -143 2598 -122 ct p +2556 -122 m 2556 -141 2554 -157 2551 -169 ct 2548 -181 2544 -191 2539 -198 ct +2533 -206 2526 -211 2518 -214 ct 2510 -217 2501 -218 2491 -218 ct 2480 -218 2471 -216 2463 -213 ct +2454 -210 2447 -205 2442 -198 ct 2436 -190 2431 -180 2428 -168 ct 2425 -156 2424 -141 2424 -122 ct +2424 -103 2425 -88 2429 -75 ct 2432 -63 2436 -53 2442 -46 ct 2448 -38 2455 -33 2463 -30 ct +2470 -27 2479 -26 2488 -26 ct 2498 -26 2508 -27 2516 -30 ct 2525 -33 2532 -38 2537 -46 ct +2543 -53 2548 -63 2551 -75 ct 2554 -88 2556 -103 2556 -122 ct p ef +2647 -293 m 2647 -332 l 2687 -332 l 2687 -293 l 2647 -293 l p +2647 1 m 2647 -242 l 2687 -242 l 2687 1 l 2647 1 l p ef +2903 0 m 2903 -154 l 2903 -166 2902 -175 2900 -183 ct 2899 -191 2896 -198 2892 -203 ct +2888 -207 2883 -211 2877 -213 ct 2870 -215 2862 -216 2853 -216 ct 2843 -216 2835 -214 2827 -211 ct +2819 -207 2813 -203 2807 -196 ct 2802 -190 2798 -182 2795 -173 ct 2792 -163 2790 -153 2790 -141 ct +2790 0 l 2750 0 l 2750 -191 l 2750 -196 2750 -201 2750 -207 ct 2750 -212 2750 -218 2749 -223 ct +2749 -228 2749 -232 2749 -236 ct 2749 -239 2749 -241 2748 -243 ct 2787 -243 l +2787 -242 2787 -240 2787 -236 ct 2787 -233 2787 -229 2788 -225 ct 2788 -221 2788 -217 2788 -212 ct +2788 -208 2788 -204 2788 -201 ct 2789 -201 l 2793 -208 2797 -214 2802 -220 ct +2806 -226 2812 -231 2818 -235 ct 2824 -239 2831 -242 2839 -244 ct 2847 -246 2856 -247 2867 -247 ct +2880 -247 2892 -245 2901 -242 ct 2911 -239 2919 -234 2925 -227 ct 2932 -220 2936 -211 2939 -200 ct +2942 -189 2943 -177 2943 -162 ct 2943 0 l 2903 0 l p ef +3096 -1 m 3090 0 3084 2 3077 3 ct 3071 4 3064 4 3055 4 ct 3023 4 3007 -14 3007 -51 ct +3007 -213 l 2979 -213 l 2979 -242 l 3009 -242 l 3020 -297 l 3047 -297 l +3047 -242 l 3092 -242 l 3092 -213 l 3047 -213 l 3047 -60 l 3047 -48 3049 -40 3053 -35 ct +3057 -30 3063 -28 3073 -28 ct 3077 -28 3081 -28 3084 -29 ct 3088 -30 3092 -30 3096 -31 ct +3096 -1 l p ef +3312 -68 m 3312 -56 3310 -46 3305 -37 ct 3301 -28 3295 -21 3286 -15 ct 3278 -9 3268 -4 3255 -1 ct +3243 2 3229 4 3214 4 ct 3199 4 3187 3 3176 1 ct 3164 -1 3154 -5 3146 -10 ct 3137 -14 3130 -21 3124 -29 ct +3119 -36 3114 -46 3112 -57 ct 3147 -64 l 3151 -51 3158 -42 3169 -36 ct 3179 -30 3194 -27 3214 -27 ct +3222 -27 3230 -27 3237 -29 ct 3245 -30 3251 -32 3256 -35 ct 3261 -38 3265 -41 3268 -46 ct +3271 -51 3273 -57 3273 -64 ct 3273 -72 3271 -78 3268 -82 ct 3264 -87 3259 -91 3253 -94 ct +3247 -97 3240 -100 3231 -102 ct 3222 -105 3213 -107 3202 -110 ct 3192 -113 3183 -116 3173 -119 ct +3164 -122 3155 -126 3147 -131 ct 3140 -136 3133 -143 3129 -150 ct 3124 -158 3121 -168 3121 -179 ct +3121 -201 3129 -218 3145 -230 ct 3161 -241 3184 -247 3214 -247 ct 3241 -247 3262 -242 3278 -233 ct +3294 -223 3303 -208 3308 -188 ct 3271 -183 l 3270 -189 3268 -195 3264 -199 ct +3260 -203 3256 -207 3251 -209 ct 3246 -212 3240 -214 3234 -215 ct 3227 -216 3221 -217 3214 -217 ct +3196 -217 3182 -214 3174 -208 ct 3165 -203 3161 -194 3161 -183 ct 3161 -177 3162 -171 3165 -167 ct +3169 -163 3173 -159 3179 -156 ct 3185 -153 3192 -151 3200 -148 ct 3208 -146 3217 -144 3226 -142 ct +3233 -140 3239 -138 3246 -136 ct 3253 -134 3259 -132 3266 -130 ct 3272 -127 3278 -124 3284 -120 ct +3289 -117 3294 -113 3298 -108 ct 3302 -103 3306 -97 3308 -90 ct 3311 -84 3312 -76 3312 -68 ct +p ef +pom +26 lw 14369 15895 m 17726 15895 l ps +18179 15895 m 17705 15737 l 17705 16053 l 18179 15895 l p ef +8627 15935 m 8779 15935 l ps +8931 15935 m 9083 15935 l ps +9235 15935 m 9387 15935 l ps +9539 15935 m 9691 15935 l ps +9843 15935 m 9995 15935 l ps +10147 15935 m 10299 15935 l ps +10451 15935 m 10603 15935 l ps +10755 15935 m 10907 15935 l ps +11059 15935 m 11211 15935 l ps +11363 15935 m 11515 15935 l ps +11667 15935 m 11819 15935 l ps +11971 15935 m 12123 15935 l ps +12275 15935 m 12427 15935 l ps +12579 15935 m 12731 15935 l ps +12883 15935 m 13035 15935 l ps +13187 15935 m 13339 15935 l ps +pum +5179 16493 t +38 0 m 38 -389 l 119 -389 l 119 -63 l 327 -63 l 327 0 l 38 0 l p ef +504 6 m 483 6 464 3 446 -4 ct 429 -10 415 -20 402 -33 ct 390 -46 381 -62 375 -81 ct +368 -101 365 -124 365 -150 ct 365 -179 369 -203 376 -222 ct 384 -242 394 -258 407 -270 ct +420 -282 435 -290 452 -296 ct 469 -301 487 -304 505 -304 ct 529 -304 549 -300 566 -292 ct +582 -283 596 -272 607 -257 ct 617 -242 625 -225 630 -204 ct 635 -184 637 -161 637 -136 ct +637 -134 l 446 -134 l 446 -121 447 -110 450 -99 ct 452 -88 455 -79 460 -71 ct +465 -63 472 -57 480 -53 ct 487 -48 497 -46 508 -46 ct 522 -46 533 -49 542 -55 ct +550 -60 556 -69 560 -82 ct 633 -75 l 630 -67 625 -58 619 -48 ct 613 -39 605 -30 595 -22 ct +585 -14 573 -7 558 -2 ct 543 3 525 6 504 6 ct p +504 -255 m 496 -255 489 -254 482 -251 ct 475 -248 469 -244 464 -238 ct 459 -232 455 -225 452 -216 ct +449 -207 447 -195 447 -183 ct 562 -183 l 561 -207 555 -225 545 -237 ct 535 -249 521 -255 504 -255 ct +p ef +820 120 m 801 120 783 118 768 114 ct 753 110 741 105 730 98 ct 719 90 711 82 705 72 ct +698 62 694 52 692 40 ct 769 31 l 772 43 778 52 787 59 ct 796 66 808 69 822 69 ct +832 69 840 68 848 65 ct 855 63 862 58 867 52 ct 873 46 877 38 880 28 ct 883 17 884 5 884 -10 ct +884 -15 884 -20 884 -26 ct 884 -31 884 -36 885 -40 ct 885 -45 885 -50 885 -55 ct +884 -55 l 875 -36 863 -22 846 -13 ct 830 -5 811 0 788 0 ct 770 0 753 -4 740 -11 ct +726 -19 715 -29 706 -43 ct 697 -56 690 -72 686 -90 ct 681 -109 679 -129 679 -151 ct +679 -174 681 -195 686 -214 ct 691 -233 698 -249 707 -262 ct 717 -276 728 -286 743 -293 ct +757 -300 774 -304 794 -304 ct 814 -304 832 -300 848 -291 ct 863 -283 875 -269 884 -250 ct +886 -250 l 886 -254 886 -259 886 -264 ct 886 -269 887 -274 887 -278 ct 887 -283 888 -287 888 -291 ct +889 -294 889 -297 890 -298 ct 963 -298 l 962 -292 962 -282 962 -270 ct 961 -258 961 -245 961 -229 ct +961 -9 l 961 13 958 32 952 48 ct 946 64 936 77 924 88 ct 912 99 898 107 880 112 ct +863 117 843 120 820 120 ct p +885 -153 m 885 -172 883 -187 879 -200 ct 876 -213 871 -223 865 -230 ct 859 -238 852 -243 845 -246 ct +837 -249 830 -251 822 -251 ct 812 -251 803 -249 795 -245 ct 788 -241 781 -235 776 -227 ct +771 -219 767 -209 764 -196 ct 761 -184 760 -169 760 -151 ct 760 -119 765 -95 775 -79 ct +786 -62 801 -54 821 -54 ct 829 -54 837 -56 844 -59 ct 852 -62 859 -67 865 -75 ct +871 -82 876 -92 879 -105 ct 883 -118 885 -134 885 -153 ct p ef +1160 6 m 1139 6 1120 3 1102 -4 ct 1085 -10 1071 -20 1058 -33 ct 1046 -46 1037 -62 1031 -81 ct +1024 -101 1021 -124 1021 -150 ct 1021 -179 1025 -203 1032 -222 ct 1040 -242 1050 -258 1063 -270 ct +1076 -282 1091 -290 1108 -296 ct 1125 -301 1143 -304 1161 -304 ct 1185 -304 1205 -300 1222 -292 ct +1238 -283 1252 -272 1263 -257 ct 1273 -242 1281 -225 1286 -204 ct 1291 -184 1293 -161 1293 -136 ct +1293 -134 l 1102 -134 l 1102 -121 1103 -110 1106 -99 ct 1108 -88 1111 -79 1116 -71 ct +1121 -63 1128 -57 1136 -53 ct 1143 -48 1153 -46 1164 -46 ct 1178 -46 1189 -49 1198 -55 ct +1206 -60 1212 -69 1216 -82 ct 1289 -75 l 1286 -67 1281 -58 1275 -48 ct 1269 -39 1261 -30 1251 -22 ct +1241 -14 1229 -7 1214 -2 ct 1199 3 1181 6 1160 6 ct p +1160 -255 m 1152 -255 1145 -254 1138 -251 ct 1131 -248 1125 -244 1120 -238 ct +1115 -232 1111 -225 1108 -216 ct 1105 -207 1103 -195 1103 -183 ct 1218 -183 l +1217 -207 1211 -225 1201 -237 ct 1191 -249 1177 -255 1160 -255 ct p ef +1544 0 m 1544 -167 l 1544 -179 1544 -190 1542 -199 ct 1540 -209 1537 -217 1533 -224 ct +1528 -231 1523 -236 1516 -240 ct 1509 -244 1501 -246 1491 -246 ct 1482 -246 1473 -244 1466 -240 ct +1458 -236 1452 -230 1446 -222 ct 1441 -215 1436 -205 1433 -195 ct 1430 -184 1429 -173 1429 -160 ct +1429 0 l 1351 0 l 1351 -232 l 1351 -238 1351 -245 1351 -252 ct 1351 -258 1351 -265 1351 -271 ct +1350 -277 1350 -283 1350 -288 ct 1350 -292 1350 -296 1349 -298 ct 1423 -298 l +1423 -296 1424 -293 1424 -288 ct 1424 -283 1425 -278 1425 -272 ct 1426 -266 1426 -260 1426 -254 ct +1426 -248 1427 -243 1427 -239 ct 1428 -239 l 1438 -262 1451 -278 1467 -289 ct +1483 -299 1502 -304 1524 -304 ct 1541 -304 1557 -301 1569 -295 ct 1581 -289 1592 -281 1599 -271 ct +1607 -261 1613 -249 1616 -235 ct 1620 -221 1622 -206 1622 -189 ct 1622 0 l 1544 0 l +p ef +1887 0 m 1887 -1 1887 -4 1886 -7 ct 1886 -11 1885 -16 1885 -20 ct 1884 -25 1884 -30 1884 -35 ct +1883 -40 1883 -44 1883 -48 ct 1882 -48 l 1873 -29 1861 -15 1845 -7 ct 1829 2 1809 6 1787 6 ct +1768 6 1752 2 1738 -6 ct 1725 -13 1713 -24 1704 -38 ct 1696 -52 1689 -68 1685 -87 ct +1680 -106 1678 -126 1678 -149 ct 1678 -171 1680 -192 1685 -211 ct 1689 -230 1696 -246 1706 -260 ct +1715 -274 1727 -284 1741 -292 ct 1756 -300 1773 -304 1793 -304 ct 1802 -304 1812 -303 1821 -301 ct +1830 -299 1838 -295 1846 -291 ct 1854 -287 1861 -282 1867 -275 ct 1873 -268 1878 -260 1883 -251 ct +1883 -251 l 1883 -253 1883 -255 1883 -259 ct 1883 -263 1883 -267 1883 -271 ct +1883 -276 1883 -281 1883 -286 ct 1883 -291 1883 -295 1883 -300 ct 1883 -409 l +1960 -409 l 1960 -65 l 1960 -50 1960 -37 1961 -26 ct 1962 -15 1962 -6 1962 0 ct +1887 0 l p +1884 -150 m 1884 -170 1882 -186 1878 -199 ct 1875 -212 1870 -223 1864 -230 ct +1858 -238 1851 -243 1844 -246 ct 1836 -249 1828 -251 1820 -251 ct 1810 -251 1802 -249 1794 -245 ct +1786 -241 1780 -235 1775 -227 ct 1769 -219 1765 -208 1763 -195 ct 1760 -182 1759 -167 1759 -149 ct +1759 -81 1779 -47 1820 -47 ct 1827 -47 1835 -49 1843 -52 ct 1851 -55 1857 -61 1863 -69 ct +1870 -77 1874 -87 1878 -101 ct 1882 -114 1884 -131 1884 -150 ct p ef +pom +gs +21373 16748 m 19277 16748 l 19277 15479 l 23468 15479 l 23468 16748 l +21373 16748 l eoclip newpath +19278 15479 m 23469 15479 l 23469 16749 l 19278 16749 l 19278 15479 l eoclip newpath +pum +18936 15584 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19148 15584 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19360 15584 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19572 15584 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19784 15584 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19996 15584 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20208 15584 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20420 15584 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20632 15584 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20844 15584 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21056 15584 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21268 15584 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21480 15584 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21692 15584 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21904 15584 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22116 15584 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22328 15584 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22540 15584 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22751 15584 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22963 15584 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23175 15584 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23387 15584 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19148 15796 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19360 15796 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19572 15796 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19784 15796 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19996 15796 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20208 15796 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20420 15796 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20632 15796 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20844 15796 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21056 15796 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21268 15796 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21480 15796 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21692 15796 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21904 15796 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22116 15796 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22328 15796 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22540 15796 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22751 15796 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22963 15796 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23175 15796 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23387 15796 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18936 16008 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19148 16008 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19360 16008 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19572 16008 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19784 16008 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19996 16008 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20208 16008 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20420 16008 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20632 16008 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20844 16008 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21056 16008 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21268 16008 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21480 16008 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21692 16008 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21904 16008 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22116 16008 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22328 16008 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22540 16008 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22751 16008 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22963 16008 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23175 16008 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23387 16008 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19148 16220 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19360 16220 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19572 16220 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19784 16220 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19996 16220 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20208 16220 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20420 16220 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20632 16220 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20844 16220 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21056 16220 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21268 16220 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21480 16220 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21692 16220 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21904 16220 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22116 16220 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22328 16220 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22540 16220 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22751 16220 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22963 16220 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23175 16220 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23387 16220 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18936 16432 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19148 16432 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19360 16432 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19572 16432 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19784 16432 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19996 16432 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20208 16432 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20420 16432 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20632 16432 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20844 16432 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21056 16432 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21268 16432 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21480 16432 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21692 16432 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21904 16432 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22116 16432 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22328 16432 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22540 16432 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22751 16432 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22963 16432 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23175 16432 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23387 16432 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19148 16644 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19360 16644 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19572 16644 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19784 16644 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19996 16644 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20208 16644 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20420 16644 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20632 16644 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20844 16644 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21056 16644 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21268 16644 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21480 16644 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21692 16644 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21904 16644 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22116 16644 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22328 16644 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22540 16644 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22751 16644 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22963 16644 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23175 16644 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23387 16644 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18936 16856 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19148 16856 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19360 16856 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19572 16856 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19784 16856 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19996 16856 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20208 16856 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20420 16856 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20632 16856 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20844 16856 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21056 16856 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21268 16856 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21480 16856 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21692 16856 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21904 16856 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22116 16856 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22328 16856 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22540 16856 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22751 16856 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22963 16856 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23175 16856 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23387 16856 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +gr +0 lw 21373 16748 m 19277 16748 l 19277 15479 l 23468 15479 l 23468 16748 l +21373 16748 l pc +pum +19874 17372 t +185 0 m 185 -154 l 185 -166 184 -175 182 -183 ct 181 -191 178 -198 174 -203 ct +170 -207 165 -211 159 -213 ct 152 -215 144 -216 135 -216 ct 125 -216 117 -214 109 -211 ct +101 -207 95 -203 89 -196 ct 84 -190 80 -182 77 -173 ct 74 -163 72 -153 72 -141 ct +72 0 l 32 0 l 32 -191 l 32 -196 32 -201 32 -207 ct 32 -212 32 -218 31 -223 ct +31 -228 31 -232 31 -236 ct 31 -239 31 -241 30 -243 ct 69 -243 l 69 -242 69 -240 69 -236 ct +69 -233 69 -229 70 -225 ct 70 -221 70 -217 70 -212 ct 70 -208 70 -204 70 -201 ct +71 -201 l 75 -208 79 -214 84 -220 ct 88 -226 94 -231 100 -235 ct 106 -239 113 -242 121 -244 ct +129 -246 138 -247 149 -247 ct 162 -247 174 -245 183 -242 ct 193 -239 201 -234 207 -227 ct +214 -220 218 -211 221 -200 ct 224 -189 225 -177 225 -162 ct 225 0 l 185 0 l +p ef +347 4 m 322 4 304 -2 292 -15 ct 280 -28 274 -46 274 -69 ct 274 -85 277 -98 283 -108 ct +289 -118 297 -127 306 -132 ct 316 -138 327 -142 340 -145 ct 352 -147 365 -148 378 -148 ct +433 -148 l 433 -161 l 433 -171 432 -180 429 -187 ct 427 -194 424 -200 420 -204 ct +416 -209 410 -212 404 -214 ct 397 -216 389 -217 381 -217 ct 373 -217 366 -216 360 -215 ct +353 -214 348 -212 343 -209 ct 339 -206 335 -202 332 -197 ct 329 -192 327 -186 326 -178 ct +284 -182 l 286 -192 289 -201 293 -209 ct 297 -217 303 -224 311 -229 ct 318 -235 328 -240 340 -243 ct +351 -246 365 -248 382 -248 ct 412 -248 435 -241 450 -227 ct 466 -213 473 -192 473 -166 ct +473 -61 l 473 -49 475 -40 478 -34 ct 481 -28 487 -25 496 -25 ct 498 -25 501 -25 503 -26 ct +505 -26 507 -26 509 -27 ct 509 -2 l 504 0 499 1 494 1 ct 489 2 484 2 478 2 ct +471 2 464 1 459 -1 ct 453 -3 449 -6 445 -10 ct 442 -14 439 -20 437 -26 ct 436 -32 434 -39 434 -47 ct +433 -47 l 428 -39 424 -32 418 -26 ct 413 -20 407 -14 400 -10 ct 393 -5 386 -2 377 0 ct +368 3 358 4 347 4 ct p +356 -26 m 369 -26 380 -29 390 -33 ct 399 -38 407 -44 414 -51 ct 420 -59 425 -67 428 -75 ct +431 -84 433 -92 433 -100 ct 433 -120 l 388 -120 l 379 -120 369 -119 360 -118 ct +351 -117 344 -114 337 -110 ct 330 -107 325 -101 321 -94 ct 317 -88 315 -79 315 -68 ct +315 -55 319 -44 326 -37 ct 333 -30 343 -26 356 -26 ct p ef +680 0 m 680 -154 l 680 -166 679 -175 678 -183 ct 676 -191 674 -198 670 -203 ct +667 -207 662 -211 657 -213 ct 651 -215 644 -216 636 -216 ct 627 -216 620 -214 613 -211 ct +606 -207 600 -203 595 -196 ct 590 -190 586 -182 584 -173 ct 581 -163 580 -153 580 -141 ct +580 0 l 540 0 l 540 -191 l 540 -196 540 -201 540 -207 ct 540 -212 540 -218 539 -223 ct +539 -228 539 -232 539 -236 ct 539 -239 539 -241 538 -243 ct 577 -243 l 577 -242 577 -240 577 -236 ct +577 -233 577 -229 578 -225 ct 578 -221 578 -217 578 -212 ct 578 -208 578 -204 578 -201 ct +579 -201 l 583 -208 587 -214 591 -220 ct 595 -226 600 -231 605 -235 ct 611 -239 617 -242 625 -244 ct +632 -246 640 -247 650 -247 ct 668 -247 683 -243 693 -236 ct 704 -229 712 -217 716 -201 ct +716 -201 l 720 -208 724 -214 729 -220 ct 733 -226 738 -231 744 -235 ct 750 -239 757 -242 764 -244 ct +772 -246 780 -247 790 -247 ct 802 -247 813 -245 822 -242 ct 831 -239 838 -234 844 -227 ct +849 -220 853 -211 856 -200 ct 859 -189 860 -177 860 -162 ct 860 0 l 820 0 l +820 -154 l 820 -166 819 -175 818 -183 ct 816 -191 814 -198 810 -203 ct 807 -207 802 -211 797 -213 ct +791 -215 784 -216 776 -216 ct 767 -216 760 -214 753 -211 ct 746 -208 740 -203 735 -197 ct +730 -191 727 -183 724 -173 ct 721 -164 720 -153 720 -141 ct 720 0 l 680 0 l +p ef +951 -113 m 951 -100 952 -89 955 -78 ct 957 -67 961 -58 967 -51 ct 972 -43 979 -37 988 -33 ct +996 -28 1007 -26 1019 -26 ct 1036 -26 1050 -30 1061 -37 ct 1071 -44 1078 -53 1082 -63 ct +1117 -53 l 1115 -47 1111 -40 1107 -33 ct 1102 -26 1096 -20 1088 -15 ct 1081 -9 1071 -5 1060 -1 ct +1048 2 1035 4 1019 4 ct 983 4 955 -7 937 -28 ct 918 -49 909 -81 909 -123 ct 909 -146 911 -165 917 -181 ct +923 -197 930 -210 940 -220 ct 950 -230 962 -237 975 -241 ct 988 -246 1002 -248 1017 -248 ct +1037 -248 1054 -245 1068 -238 ct 1082 -231 1093 -222 1101 -211 ct 1109 -199 1115 -185 1119 -170 ct +1122 -154 1124 -137 1124 -118 ct 1124 -113 l 951 -113 l p +1082 -144 m 1080 -170 1073 -188 1063 -200 ct 1052 -212 1036 -218 1016 -218 ct +1010 -218 1003 -217 995 -215 ct 988 -213 981 -209 975 -203 ct 968 -198 963 -190 959 -180 ct +954 -171 952 -159 951 -144 ct 1082 -144 l p ef +1301 -293 m 1301 -332 l 1341 -332 l 1341 -293 l 1301 -293 l p +1341 30 m 1341 39 1340 48 1339 56 ct 1337 64 1334 70 1330 76 ct 1326 82 1321 87 1314 90 ct +1307 93 1298 95 1287 95 ct 1282 95 1277 95 1272 95 ct 1268 95 1263 94 1259 93 ct +1259 62 l 1261 63 1263 63 1266 63 ct 1268 63 1271 64 1273 64 ct 1278 64 1283 63 1287 61 ct +1290 60 1293 58 1295 54 ct 1297 51 1299 47 1300 42 ct 1300 37 1301 31 1301 24 ct +1301 -242 l 1341 -242 l 1341 30 l p ef +1608 -122 m 1608 -80 1599 -48 1580 -27 ct 1561 -6 1534 4 1499 4 ct 1482 4 1467 1 1453 -4 ct +1440 -9 1429 -17 1420 -27 ct 1410 -37 1403 -51 1399 -66 ct 1394 -82 1391 -101 1391 -122 ct +1391 -206 1428 -248 1500 -248 ct 1519 -248 1535 -245 1549 -240 ct 1562 -235 1574 -227 1582 -216 ct +1591 -206 1598 -193 1602 -177 ct 1606 -161 1608 -143 1608 -122 ct p +1566 -122 m 1566 -141 1564 -157 1561 -169 ct 1558 -181 1554 -191 1549 -198 ct +1543 -206 1536 -211 1528 -214 ct 1520 -217 1511 -218 1501 -218 ct 1490 -218 1481 -216 1473 -213 ct +1464 -210 1457 -205 1452 -198 ct 1446 -190 1441 -180 1438 -168 ct 1435 -156 1434 -141 1434 -122 ct +1434 -103 1435 -88 1439 -75 ct 1442 -63 1446 -53 1452 -46 ct 1458 -38 1465 -33 1473 -30 ct +1480 -27 1489 -26 1498 -26 ct 1508 -26 1518 -27 1526 -30 ct 1535 -33 1542 -38 1547 -46 ct +1553 -53 1558 -63 1561 -75 ct 1564 -88 1566 -103 1566 -122 ct p ef +1657 -293 m 1657 -332 l 1697 -332 l 1697 -293 l 1657 -293 l p +1657 1 m 1657 -242 l 1697 -242 l 1697 1 l 1657 1 l p ef +1912 0 m 1912 -154 l 1912 -166 1911 -175 1909 -183 ct 1908 -191 1905 -198 1901 -203 ct +1897 -207 1892 -211 1886 -213 ct 1879 -215 1871 -216 1862 -216 ct 1852 -216 1844 -214 1836 -211 ct +1828 -207 1822 -203 1816 -196 ct 1811 -190 1807 -182 1804 -173 ct 1801 -163 1799 -153 1799 -141 ct +1799 0 l 1759 0 l 1759 -191 l 1759 -196 1759 -201 1759 -207 ct 1759 -212 1759 -218 1758 -223 ct +1758 -228 1758 -232 1758 -236 ct 1758 -239 1758 -241 1757 -243 ct 1796 -243 l +1796 -242 1796 -240 1796 -236 ct 1796 -233 1796 -229 1797 -225 ct 1797 -221 1797 -217 1797 -212 ct +1797 -208 1797 -204 1797 -201 ct 1798 -201 l 1802 -208 1806 -214 1811 -220 ct +1815 -226 1821 -231 1827 -235 ct 1833 -239 1840 -242 1848 -244 ct 1856 -246 1865 -247 1876 -247 ct +1889 -247 1901 -245 1910 -242 ct 1920 -239 1928 -234 1934 -227 ct 1941 -220 1945 -211 1948 -200 ct +1951 -189 1952 -177 1952 -162 ct 1952 0 l 1912 0 l p ef +2344 -123 m 2344 -104 2343 -87 2340 -72 ct 2337 -56 2332 -43 2325 -32 ct 2318 -21 2308 -12 2297 -6 ct +2286 1 2272 4 2255 4 ct 2237 4 2222 1 2209 -6 ct 2196 -12 2186 -23 2180 -38 ct +2178 -38 l 2179 -38 2179 -36 2179 -34 ct 2179 -32 2179 -29 2179 -25 ct 2179 -22 2179 -18 2179 -13 ct +2179 -9 2179 -4 2179 0 ct 2179 95 l 2139 95 l 2139 -193 l 2139 -199 2139 -205 2139 -210 ct +2139 -215 2139 -220 2138 -225 ct 2138 -229 2138 -233 2138 -236 ct 2138 -239 2138 -241 2138 -243 ct +2177 -243 l 2177 -242 2177 -241 2177 -238 ct 2177 -235 2178 -232 2178 -228 ct +2178 -225 2178 -220 2178 -216 ct 2179 -212 2179 -208 2179 -204 ct 2180 -204 l +2183 -212 2188 -218 2193 -224 ct 2197 -229 2203 -234 2209 -237 ct 2215 -241 2222 -243 2229 -245 ct +2237 -246 2245 -247 2255 -247 ct 2272 -247 2286 -244 2297 -238 ct 2308 -232 2318 -224 2325 -213 ct +2332 -202 2337 -189 2340 -174 ct 2343 -158 2344 -141 2344 -123 ct p +2302 -122 m 2302 -137 2301 -150 2299 -162 ct 2297 -173 2294 -183 2290 -191 ct +2285 -199 2279 -205 2272 -210 ct 2265 -214 2256 -216 2244 -216 ct 2236 -216 2227 -215 2219 -212 ct +2211 -210 2204 -205 2198 -198 ct 2193 -190 2188 -180 2184 -168 ct 2181 -155 2179 -139 2179 -119 ct +2179 -102 2181 -87 2184 -75 ct 2186 -63 2191 -54 2196 -46 ct 2201 -39 2208 -34 2216 -31 ct +2224 -27 2234 -26 2244 -26 ct 2255 -26 2265 -28 2272 -32 ct 2279 -37 2285 -43 2290 -51 ct +2294 -59 2297 -69 2299 -81 ct 2301 -93 2302 -107 2302 -122 ct p ef +2598 -122 m 2598 -80 2589 -48 2570 -27 ct 2551 -6 2524 4 2489 4 ct 2472 4 2457 1 2443 -4 ct +2430 -9 2419 -17 2410 -27 ct 2400 -37 2393 -51 2389 -66 ct 2384 -82 2381 -101 2381 -122 ct +2381 -206 2418 -248 2490 -248 ct 2509 -248 2525 -245 2539 -240 ct 2552 -235 2564 -227 2572 -216 ct +2581 -206 2588 -193 2592 -177 ct 2596 -161 2598 -143 2598 -122 ct p +2556 -122 m 2556 -141 2554 -157 2551 -169 ct 2548 -181 2544 -191 2539 -198 ct +2533 -206 2526 -211 2518 -214 ct 2510 -217 2501 -218 2491 -218 ct 2480 -218 2471 -216 2463 -213 ct +2454 -210 2447 -205 2442 -198 ct 2436 -190 2431 -180 2428 -168 ct 2425 -156 2424 -141 2424 -122 ct +2424 -103 2425 -88 2429 -75 ct 2432 -63 2436 -53 2442 -46 ct 2448 -38 2455 -33 2463 -30 ct +2470 -27 2479 -26 2488 -26 ct 2498 -26 2508 -27 2516 -30 ct 2525 -33 2532 -38 2537 -46 ct +2543 -53 2548 -63 2551 -75 ct 2554 -88 2556 -103 2556 -122 ct p ef +2647 -293 m 2647 -332 l 2687 -332 l 2687 -293 l 2647 -293 l p +2647 1 m 2647 -242 l 2687 -242 l 2687 1 l 2647 1 l p ef +2903 0 m 2903 -154 l 2903 -166 2902 -175 2900 -183 ct 2899 -191 2896 -198 2892 -203 ct +2888 -207 2883 -211 2877 -213 ct 2870 -215 2862 -216 2853 -216 ct 2843 -216 2835 -214 2827 -211 ct +2819 -207 2813 -203 2807 -196 ct 2802 -190 2798 -182 2795 -173 ct 2792 -163 2790 -153 2790 -141 ct +2790 0 l 2750 0 l 2750 -191 l 2750 -196 2750 -201 2750 -207 ct 2750 -212 2750 -218 2749 -223 ct +2749 -228 2749 -232 2749 -236 ct 2749 -239 2749 -241 2748 -243 ct 2787 -243 l +2787 -242 2787 -240 2787 -236 ct 2787 -233 2787 -229 2788 -225 ct 2788 -221 2788 -217 2788 -212 ct +2788 -208 2788 -204 2788 -201 ct 2789 -201 l 2793 -208 2797 -214 2802 -220 ct +2806 -226 2812 -231 2818 -235 ct 2824 -239 2831 -242 2839 -244 ct 2847 -246 2856 -247 2867 -247 ct +2880 -247 2892 -245 2901 -242 ct 2911 -239 2919 -234 2925 -227 ct 2932 -220 2936 -211 2939 -200 ct +2942 -189 2943 -177 2943 -162 ct 2943 0 l 2903 0 l p ef +3096 -1 m 3090 0 3084 2 3077 3 ct 3071 4 3064 4 3055 4 ct 3023 4 3007 -14 3007 -51 ct +3007 -213 l 2979 -213 l 2979 -242 l 3009 -242 l 3020 -297 l 3047 -297 l +3047 -242 l 3092 -242 l 3092 -213 l 3047 -213 l 3047 -60 l 3047 -48 3049 -40 3053 -35 ct +3057 -30 3063 -28 3073 -28 ct 3077 -28 3081 -28 3084 -29 ct 3088 -30 3092 -30 3096 -31 ct +3096 -1 l p ef +pom +pum +25045 17372 t +62 -123 m 62 -109 63 -96 65 -85 ct 67 -73 70 -63 75 -54 ct 80 -46 86 -39 94 -35 ct +102 -30 111 -28 123 -28 ct 137 -28 149 -32 159 -39 ct 168 -47 174 -58 177 -74 ct +217 -74 l 216 -64 213 -54 209 -45 ct 204 -35 198 -27 190 -20 ct 183 -13 173 -7 162 -3 ct +151 2 138 4 124 4 ct 105 4 89 1 76 -6 ct 62 -12 51 -21 43 -32 ct 35 -44 29 -57 25 -72 ct +21 -87 20 -104 20 -122 ct 20 -138 21 -153 24 -165 ct 26 -178 30 -189 35 -198 ct +40 -207 45 -215 52 -221 ct 59 -228 66 -233 73 -237 ct 81 -241 89 -243 98 -245 ct +106 -247 115 -248 123 -248 ct 137 -248 149 -246 160 -242 ct 170 -238 180 -233 187 -227 ct +195 -220 201 -213 206 -204 ct 211 -195 214 -185 216 -175 ct 175 -172 l 173 -186 167 -196 159 -204 ct +150 -212 138 -216 122 -216 ct 111 -216 101 -214 94 -210 ct 86 -206 80 -201 75 -193 ct +70 -185 67 -176 65 -164 ct 63 -152 62 -139 62 -123 ct p ef +465 -122 m 465 -80 456 -48 437 -27 ct 418 -6 391 4 356 4 ct 339 4 324 1 310 -4 ct +297 -9 286 -17 277 -27 ct 267 -37 260 -51 256 -66 ct 251 -82 248 -101 248 -122 ct +248 -206 285 -248 357 -248 ct 376 -248 392 -245 406 -240 ct 419 -235 431 -227 439 -216 ct +448 -206 455 -193 459 -177 ct 463 -161 465 -143 465 -122 ct p +423 -122 m 423 -141 421 -157 418 -169 ct 415 -181 411 -191 406 -198 ct 400 -206 393 -211 385 -214 ct +377 -217 368 -218 358 -218 ct 347 -218 338 -216 330 -213 ct 321 -210 314 -205 309 -198 ct +303 -190 298 -180 295 -168 ct 292 -156 291 -141 291 -122 ct 291 -103 292 -88 296 -75 ct +299 -63 303 -53 309 -46 ct 315 -38 322 -33 330 -30 ct 337 -27 346 -26 355 -26 ct +365 -26 375 -27 383 -30 ct 392 -33 399 -38 404 -46 ct 410 -53 415 -63 418 -75 ct +421 -88 423 -103 423 -122 ct p ef +667 -38 m 660 -23 650 -12 637 -5 ct 625 2 610 5 591 5 ct 561 5 538 -5 524 -26 ct +509 -46 502 -78 502 -119 ct 502 -204 532 -246 591 -246 ct 610 -246 625 -243 637 -236 ct +650 -229 660 -219 667 -204 ct 667 -204 l 667 -205 667 -208 667 -211 ct 667 -214 667 -218 667 -221 ct +667 -225 667 -228 667 -231 ct 667 -234 667 -236 667 -238 ct 667 -332 l 707 -332 l +707 -49 l 707 -44 707 -38 707 -33 ct 708 -27 708 -22 708 -18 ct 708 -13 708 -9 708 -6 ct +708 -3 709 -1 709 1 ct 670 1 l 670 -1 670 -3 669 -6 ct 669 -9 669 -12 669 -15 ct +668 -19 668 -23 668 -27 ct 668 -31 668 -34 668 -38 ct 667 -38 l p +545 -121 m 545 -104 546 -90 548 -78 ct 550 -66 553 -56 558 -48 ct 562 -41 568 -35 576 -31 ct +583 -28 591 -26 602 -26 ct 612 -26 622 -28 630 -31 ct 638 -35 645 -40 650 -48 ct +656 -55 660 -66 663 -78 ct 666 -90 667 -105 667 -123 ct 667 -140 666 -155 663 -167 ct +660 -179 656 -188 650 -196 ct 645 -203 638 -208 630 -211 ct 622 -215 613 -216 602 -216 ct +592 -216 584 -214 577 -211 ct 570 -208 564 -202 559 -194 ct 554 -187 550 -177 548 -165 ct +546 -153 545 -138 545 -121 ct p ef +799 -113 m 799 -100 800 -89 803 -78 ct 805 -67 809 -58 815 -51 ct 820 -43 827 -37 836 -33 ct +844 -28 855 -26 867 -26 ct 884 -26 898 -30 909 -37 ct 919 -44 926 -53 930 -63 ct +965 -53 l 963 -47 959 -40 955 -33 ct 950 -26 944 -20 936 -15 ct 929 -9 919 -5 908 -1 ct +896 2 883 4 867 4 ct 831 4 803 -7 785 -28 ct 766 -49 757 -81 757 -123 ct 757 -146 759 -165 765 -181 ct +771 -197 778 -210 788 -220 ct 798 -230 810 -237 823 -241 ct 836 -246 850 -248 865 -248 ct +885 -248 902 -245 916 -238 ct 930 -231 941 -222 949 -211 ct 957 -199 963 -185 967 -170 ct +970 -154 972 -137 972 -118 ct 972 -113 l 799 -113 l p +930 -144 m 928 -170 921 -188 911 -200 ct 900 -212 884 -218 864 -218 ct 858 -218 851 -217 843 -215 ct +836 -213 829 -209 823 -203 ct 816 -198 811 -190 807 -180 ct 802 -171 800 -159 799 -144 ct +930 -144 l p ef +1149 -293 m 1149 -332 l 1189 -332 l 1189 -293 l 1149 -293 l p +1189 30 m 1189 39 1188 48 1187 56 ct 1185 64 1182 70 1178 76 ct 1174 82 1169 87 1162 90 ct +1155 93 1146 95 1135 95 ct 1130 95 1125 95 1120 95 ct 1116 95 1111 94 1107 93 ct +1107 62 l 1109 63 1111 63 1114 63 ct 1116 63 1119 64 1121 64 ct 1126 64 1131 63 1135 61 ct +1138 60 1141 58 1143 54 ct 1145 51 1147 47 1148 42 ct 1148 37 1149 31 1149 24 ct +1149 -242 l 1189 -242 l 1189 30 l p ef +1455 -122 m 1455 -80 1446 -48 1427 -27 ct 1408 -6 1381 4 1346 4 ct 1329 4 1314 1 1300 -4 ct +1287 -9 1276 -17 1267 -27 ct 1257 -37 1250 -51 1246 -66 ct 1241 -82 1238 -101 1238 -122 ct +1238 -206 1275 -248 1347 -248 ct 1366 -248 1382 -245 1396 -240 ct 1409 -235 1421 -227 1429 -216 ct +1438 -206 1445 -193 1449 -177 ct 1453 -161 1455 -143 1455 -122 ct p +1413 -122 m 1413 -141 1411 -157 1408 -169 ct 1405 -181 1401 -191 1396 -198 ct +1390 -206 1383 -211 1375 -214 ct 1367 -217 1358 -218 1348 -218 ct 1337 -218 1328 -216 1320 -213 ct +1311 -210 1304 -205 1299 -198 ct 1293 -190 1288 -180 1285 -168 ct 1282 -156 1281 -141 1281 -122 ct +1281 -103 1282 -88 1286 -75 ct 1289 -63 1293 -53 1299 -46 ct 1305 -38 1312 -33 1320 -30 ct +1327 -27 1336 -26 1345 -26 ct 1355 -26 1365 -27 1373 -30 ct 1382 -33 1389 -38 1394 -46 ct +1400 -53 1405 -63 1408 -75 ct 1411 -88 1413 -103 1413 -122 ct p ef +1504 -293 m 1504 -332 l 1544 -332 l 1544 -293 l 1504 -293 l p +1504 1 m 1504 -242 l 1544 -242 l 1544 1 l 1504 1 l p ef +1760 0 m 1760 -154 l 1760 -166 1759 -175 1757 -183 ct 1756 -191 1753 -198 1749 -203 ct +1745 -207 1740 -211 1734 -213 ct 1727 -215 1719 -216 1710 -216 ct 1700 -216 1692 -214 1684 -211 ct +1676 -207 1670 -203 1664 -196 ct 1659 -190 1655 -182 1652 -173 ct 1649 -163 1647 -153 1647 -141 ct +1647 0 l 1607 0 l 1607 -191 l 1607 -196 1607 -201 1607 -207 ct 1607 -212 1607 -218 1606 -223 ct +1606 -228 1606 -232 1606 -236 ct 1606 -239 1606 -241 1605 -243 ct 1644 -243 l +1644 -242 1644 -240 1644 -236 ct 1644 -233 1644 -229 1645 -225 ct 1645 -221 1645 -217 1645 -212 ct +1645 -208 1645 -204 1645 -201 ct 1646 -201 l 1650 -208 1654 -214 1659 -220 ct +1663 -226 1669 -231 1675 -235 ct 1681 -239 1688 -242 1696 -244 ct 1704 -246 1713 -247 1724 -247 ct +1737 -247 1749 -245 1758 -242 ct 1768 -239 1776 -234 1782 -227 ct 1789 -220 1793 -211 1796 -200 ct +1799 -189 1800 -177 1800 -162 ct 1800 0 l 1760 0 l p ef +2192 -123 m 2192 -104 2191 -87 2188 -72 ct 2185 -56 2180 -43 2173 -32 ct 2166 -21 2156 -12 2145 -6 ct +2134 1 2120 4 2103 4 ct 2085 4 2070 1 2057 -6 ct 2044 -12 2034 -23 2028 -38 ct +2026 -38 l 2027 -38 2027 -36 2027 -34 ct 2027 -32 2027 -29 2027 -25 ct 2027 -22 2027 -18 2027 -13 ct +2027 -9 2027 -4 2027 0 ct 2027 95 l 1987 95 l 1987 -193 l 1987 -199 1987 -205 1987 -210 ct +1987 -215 1987 -220 1986 -225 ct 1986 -229 1986 -233 1986 -236 ct 1986 -239 1986 -241 1986 -243 ct +2025 -243 l 2025 -242 2025 -241 2025 -238 ct 2025 -235 2026 -232 2026 -228 ct +2026 -225 2026 -220 2026 -216 ct 2027 -212 2027 -208 2027 -204 ct 2028 -204 l +2031 -212 2036 -218 2041 -224 ct 2045 -229 2051 -234 2057 -237 ct 2063 -241 2070 -243 2077 -245 ct +2085 -246 2093 -247 2103 -247 ct 2120 -247 2134 -244 2145 -238 ct 2156 -232 2166 -224 2173 -213 ct +2180 -202 2185 -189 2188 -174 ct 2191 -158 2192 -141 2192 -123 ct p +2150 -122 m 2150 -137 2149 -150 2147 -162 ct 2145 -173 2142 -183 2138 -191 ct +2133 -199 2127 -205 2120 -210 ct 2113 -214 2104 -216 2092 -216 ct 2084 -216 2075 -215 2067 -212 ct +2059 -210 2052 -205 2046 -198 ct 2041 -190 2036 -180 2032 -168 ct 2029 -155 2027 -139 2027 -119 ct +2027 -102 2029 -87 2032 -75 ct 2034 -63 2039 -54 2044 -46 ct 2049 -39 2056 -34 2064 -31 ct +2072 -27 2082 -26 2092 -26 ct 2103 -26 2113 -28 2120 -32 ct 2127 -37 2133 -43 2138 -51 ct +2142 -59 2145 -69 2147 -81 ct 2149 -93 2150 -107 2150 -122 ct p ef +2446 -122 m 2446 -80 2437 -48 2418 -27 ct 2399 -6 2372 4 2337 4 ct 2320 4 2305 1 2291 -4 ct +2278 -9 2267 -17 2258 -27 ct 2248 -37 2241 -51 2237 -66 ct 2232 -82 2229 -101 2229 -122 ct +2229 -206 2266 -248 2338 -248 ct 2357 -248 2373 -245 2387 -240 ct 2400 -235 2412 -227 2420 -216 ct +2429 -206 2436 -193 2440 -177 ct 2444 -161 2446 -143 2446 -122 ct p +2404 -122 m 2404 -141 2402 -157 2399 -169 ct 2396 -181 2392 -191 2387 -198 ct +2381 -206 2374 -211 2366 -214 ct 2358 -217 2349 -218 2339 -218 ct 2328 -218 2319 -216 2311 -213 ct +2302 -210 2295 -205 2290 -198 ct 2284 -190 2279 -180 2276 -168 ct 2273 -156 2272 -141 2272 -122 ct +2272 -103 2273 -88 2277 -75 ct 2280 -63 2284 -53 2290 -46 ct 2296 -38 2303 -33 2311 -30 ct +2318 -27 2327 -26 2336 -26 ct 2346 -26 2356 -27 2364 -30 ct 2373 -33 2380 -38 2385 -46 ct +2391 -53 2396 -63 2399 -75 ct 2402 -88 2404 -103 2404 -122 ct p ef +2495 -293 m 2495 -332 l 2535 -332 l 2535 -293 l 2495 -293 l p +2495 1 m 2495 -242 l 2535 -242 l 2535 1 l 2495 1 l p ef +2750 0 m 2750 -154 l 2750 -166 2749 -175 2747 -183 ct 2746 -191 2743 -198 2739 -203 ct +2735 -207 2730 -211 2724 -213 ct 2717 -215 2709 -216 2700 -216 ct 2690 -216 2682 -214 2674 -211 ct +2666 -207 2660 -203 2654 -196 ct 2649 -190 2645 -182 2642 -173 ct 2639 -163 2637 -153 2637 -141 ct +2637 0 l 2597 0 l 2597 -191 l 2597 -196 2597 -201 2597 -207 ct 2597 -212 2597 -218 2596 -223 ct +2596 -228 2596 -232 2596 -236 ct 2596 -239 2596 -241 2595 -243 ct 2634 -243 l +2634 -242 2634 -240 2634 -236 ct 2634 -233 2634 -229 2635 -225 ct 2635 -221 2635 -217 2635 -212 ct +2635 -208 2635 -204 2635 -201 ct 2636 -201 l 2640 -208 2644 -214 2649 -220 ct +2653 -226 2659 -231 2665 -235 ct 2671 -239 2678 -242 2686 -244 ct 2694 -246 2703 -247 2714 -247 ct +2727 -247 2739 -245 2748 -242 ct 2758 -239 2766 -234 2772 -227 ct 2779 -220 2783 -211 2786 -200 ct +2789 -189 2790 -177 2790 -162 ct 2790 0 l 2750 0 l p ef +2943 -1 m 2937 0 2931 2 2924 3 ct 2918 4 2911 4 2902 4 ct 2870 4 2854 -14 2854 -51 ct +2854 -213 l 2826 -213 l 2826 -242 l 2856 -242 l 2867 -297 l 2894 -297 l +2894 -242 l 2939 -242 l 2939 -213 l 2894 -213 l 2894 -60 l 2894 -48 2896 -40 2900 -35 ct +2904 -30 2910 -28 2920 -28 ct 2924 -28 2928 -28 2931 -29 ct 2935 -30 2939 -30 2943 -31 ct +2943 -1 l p ef +pom +1.000 1.000 1.000 c 25023 15476 m 24834 15476 24646 15664 24646 15853 ct +24646 16369 l 24646 16558 24834 16747 25023 16747 ct 27953 16747 l 28141 16747 28330 16558 28330 16369 ct +28330 15853 l 28330 15664 28141 15476 27953 15476 ct 25023 15476 l p +24646 15476 m 24646 15476 l p +28330 16747 m 28330 16747 l p ef +0.003 0.003 0.003 c 25023 15476 m 24834 15476 24646 15664 24646 15853 ct 24646 16369 l +24646 16558 24834 16746 25023 16746 ct 27953 16746 l 28141 16746 28330 16558 28330 16369 ct +28330 15853 l 28330 15664 28141 15476 27953 15476 ct 25023 15476 l pc +24646 15476 m 24646 15476 l pc +28330 16746 m 28330 16746 l pc +pum +25006 16318 t +274 0 m 213 0 165 -18 129 -54 ct 93 -90 75 -139 75 -200 ct 75 -261 93 -309 129 -345 ct +165 -381 213 -399 274 -399 ct 335 -399 383 -381 420 -345 ct 457 -309 475 -260 475 -200 ct +475 -139 457 -91 420 -54 ct 383 -18 335 0 274 0 ct p ef +pom +pum +25768 16283 t +pom +[ 152 152 ] 0 ld +30708 4371 m 30708 2974 l ps +25114 9761 m 25114 8364 l ps +26 lw [ ] 0 ld +21132 5762 m 23363 7002 l ps +23759 7222 m 23421 6854 l 23268 7130 l 23759 7222 l p ef +pum +22781 6636 t +184 -38 m 177 -23 167 -12 154 -5 ct 142 2 127 5 108 5 ct 78 5 55 -5 41 -26 ct +26 -46 19 -78 19 -119 ct 19 -204 49 -246 108 -246 ct 127 -246 142 -243 154 -236 ct +167 -229 177 -219 184 -204 ct 184 -204 l 184 -205 184 -208 184 -211 ct 184 -214 184 -218 184 -221 ct +184 -225 184 -228 184 -231 ct 184 -234 184 -236 184 -238 ct 184 -332 l 224 -332 l +224 -49 l 224 -44 224 -38 224 -33 ct 225 -27 225 -22 225 -18 ct 225 -13 225 -9 225 -6 ct +225 -3 226 -1 226 1 ct 187 1 l 187 -1 187 -3 186 -6 ct 186 -9 186 -12 186 -15 ct +185 -19 185 -23 185 -27 ct 185 -31 185 -34 185 -38 ct 184 -38 l p +62 -121 m 62 -104 63 -90 65 -78 ct 67 -66 70 -56 75 -48 ct 79 -41 85 -35 93 -31 ct +100 -28 108 -26 119 -26 ct 129 -26 139 -28 147 -31 ct 155 -35 162 -40 167 -48 ct +173 -55 177 -66 180 -78 ct 183 -90 184 -105 184 -123 ct 184 -140 183 -155 180 -167 ct +177 -179 173 -188 167 -196 ct 162 -203 155 -208 147 -211 ct 139 -215 130 -216 119 -216 ct +109 -216 101 -214 94 -211 ct 87 -208 81 -202 76 -194 ct 71 -187 67 -177 65 -165 ct +63 -153 62 -138 62 -121 ct p ef +316 -113 m 316 -100 317 -89 320 -78 ct 322 -67 326 -58 332 -51 ct 337 -43 344 -37 353 -33 ct +361 -28 372 -26 384 -26 ct 401 -26 415 -30 426 -37 ct 436 -44 443 -53 447 -63 ct +482 -53 l 480 -47 476 -40 472 -33 ct 467 -26 461 -20 453 -15 ct 446 -9 436 -5 425 -1 ct +413 2 400 4 384 4 ct 348 4 320 -7 302 -28 ct 283 -49 274 -81 274 -123 ct 274 -146 276 -165 282 -181 ct +288 -197 295 -210 305 -220 ct 315 -230 327 -237 340 -241 ct 353 -246 367 -248 382 -248 ct +402 -248 419 -245 433 -238 ct 447 -231 458 -222 466 -211 ct 474 -199 480 -185 484 -170 ct +487 -154 489 -137 489 -118 ct 489 -113 l 316 -113 l p +447 -144 m 445 -170 438 -188 428 -200 ct 417 -212 401 -218 381 -218 ct 375 -218 368 -217 360 -215 ct +353 -213 346 -209 340 -203 ct 333 -198 328 -190 324 -180 ct 319 -171 317 -159 316 -144 ct +447 -144 l p ef +721 -68 m 721 -56 719 -46 714 -37 ct 710 -28 704 -21 695 -15 ct 687 -9 677 -4 664 -1 ct +652 2 638 4 623 4 ct 608 4 596 3 585 1 ct 573 -1 563 -5 555 -10 ct 546 -14 539 -21 533 -29 ct +528 -36 523 -46 521 -57 ct 556 -64 l 560 -51 567 -42 578 -36 ct 588 -30 603 -27 623 -27 ct +631 -27 639 -27 646 -29 ct 654 -30 660 -32 665 -35 ct 670 -38 674 -41 677 -46 ct +680 -51 682 -57 682 -64 ct 682 -72 680 -78 677 -82 ct 673 -87 668 -91 662 -94 ct +656 -97 649 -100 640 -102 ct 631 -105 622 -107 611 -110 ct 601 -113 592 -116 582 -119 ct +573 -122 564 -126 556 -131 ct 549 -136 542 -143 538 -150 ct 533 -158 530 -168 530 -179 ct +530 -201 538 -218 554 -230 ct 570 -241 593 -247 623 -247 ct 650 -247 671 -242 687 -233 ct +703 -223 712 -208 717 -188 ct 680 -183 l 679 -189 677 -195 673 -199 ct 669 -203 665 -207 660 -209 ct +655 -212 649 -214 643 -215 ct 636 -216 630 -217 623 -217 ct 605 -217 591 -214 583 -208 ct +574 -203 570 -194 570 -183 ct 570 -177 571 -171 574 -167 ct 578 -163 582 -159 588 -156 ct +594 -153 601 -151 609 -148 ct 617 -146 626 -144 635 -142 ct 642 -140 648 -138 655 -136 ct +662 -134 668 -132 675 -130 ct 681 -127 687 -124 693 -120 ct 698 -117 703 -113 707 -108 ct +711 -103 715 -97 717 -90 ct 720 -84 721 -76 721 -68 ct p ef +861 -1 m 855 0 849 2 842 3 ct 836 4 829 4 820 4 ct 788 4 772 -14 772 -51 ct 772 -213 l +744 -213 l 744 -242 l 774 -242 l 785 -297 l 812 -297 l 812 -242 l +857 -242 l 857 -213 l 812 -213 l 812 -60 l 812 -48 814 -40 818 -35 ct +822 -30 828 -28 838 -28 ct 842 -28 846 -28 849 -29 ct 853 -30 857 -30 861 -31 ct +861 -1 l p ef +896 0 m 896 -186 l 896 -191 896 -196 896 -202 ct 896 -207 896 -212 895 -217 ct +895 -222 895 -227 895 -231 ct 895 -235 895 -239 894 -243 ct 933 -243 l 933 -239 933 -235 933 -231 ct +933 -226 934 -222 934 -217 ct 934 -213 934 -208 934 -204 ct 934 -200 934 -196 934 -193 ct +935 -193 l 938 -202 941 -210 944 -217 ct 948 -224 951 -229 956 -234 ct 960 -238 965 -242 971 -244 ct +977 -246 984 -247 993 -247 ct 996 -247 999 -247 1002 -246 ct 1005 -246 1008 -245 1009 -245 ct +1009 -208 l 1007 -209 1003 -209 1000 -209 ct 996 -210 992 -210 988 -210 ct +978 -210 971 -208 964 -204 ct 958 -200 952 -194 948 -186 ct 944 -179 941 -170 939 -160 ct +937 -150 936 -139 936 -126 ct 936 0 l 896 0 l p ef +1086 -243 m 1086 -89 l 1086 -77 1087 -68 1089 -60 ct 1091 -52 1093 -45 1097 -40 ct +1101 -36 1106 -32 1113 -30 ct 1119 -28 1127 -27 1136 -27 ct 1146 -27 1155 -29 1162 -32 ct +1170 -36 1177 -40 1182 -47 ct 1187 -53 1192 -61 1195 -70 ct 1198 -80 1199 -90 1199 -102 ct +1199 -243 l 1239 -243 l 1239 -52 l 1239 -47 1239 -42 1240 -36 ct 1240 -31 1240 -25 1240 -20 ct +1240 -15 1240 -11 1240 -7 ct 1240 -4 1241 -2 1241 0 ct 1203 0 l 1203 -1 1202 -3 1202 -7 ct +1202 -10 1202 -14 1202 -18 ct 1201 -22 1201 -26 1201 -31 ct 1201 -35 1201 -39 1201 -42 ct +1200 -42 l 1196 -35 1192 -29 1187 -23 ct 1183 -17 1177 -12 1171 -8 ct 1165 -4 1158 -1 1150 1 ct +1142 3 1133 4 1123 4 ct 1109 4 1098 2 1088 -1 ct 1078 -4 1070 -9 1064 -16 ct 1058 -23 1053 -32 1050 -43 ct +1047 -53 1046 -66 1046 -81 ct 1046 -243 l 1086 -243 l p ef +1332 -123 m 1332 -109 1333 -96 1335 -85 ct 1337 -73 1340 -63 1345 -54 ct 1350 -46 1356 -39 1364 -35 ct +1372 -30 1381 -28 1393 -28 ct 1407 -28 1419 -32 1429 -39 ct 1438 -47 1444 -58 1447 -74 ct +1487 -74 l 1486 -64 1483 -54 1479 -45 ct 1474 -35 1468 -27 1460 -20 ct 1453 -13 1443 -7 1432 -3 ct +1421 2 1408 4 1394 4 ct 1375 4 1359 1 1346 -6 ct 1332 -12 1321 -21 1313 -32 ct +1305 -44 1299 -57 1295 -72 ct 1291 -87 1290 -104 1290 -122 ct 1290 -138 1291 -153 1294 -165 ct +1296 -178 1300 -189 1305 -198 ct 1310 -207 1315 -215 1322 -221 ct 1329 -228 1336 -233 1343 -237 ct +1351 -241 1359 -243 1368 -245 ct 1376 -247 1385 -248 1393 -248 ct 1407 -248 1419 -246 1430 -242 ct +1440 -238 1450 -233 1457 -227 ct 1465 -220 1471 -213 1476 -204 ct 1481 -195 1484 -185 1486 -175 ct +1445 -172 l 1443 -186 1437 -196 1429 -204 ct 1420 -212 1408 -216 1392 -216 ct +1381 -216 1371 -214 1364 -210 ct 1356 -206 1350 -201 1345 -193 ct 1340 -185 1337 -176 1335 -164 ct +1333 -152 1332 -139 1332 -123 ct p ef +1623 -1 m 1617 0 1611 2 1604 3 ct 1598 4 1591 4 1582 4 ct 1550 4 1534 -14 1534 -51 ct +1534 -213 l 1506 -213 l 1506 -242 l 1536 -242 l 1547 -297 l 1574 -297 l +1574 -242 l 1619 -242 l 1619 -213 l 1574 -213 l 1574 -60 l 1574 -48 1576 -40 1580 -35 ct +1584 -30 1590 -28 1600 -28 ct 1604 -28 1608 -28 1611 -29 ct 1615 -30 1619 -30 1623 -31 ct +1623 -1 l p ef +1862 -122 m 1862 -80 1853 -48 1834 -27 ct 1815 -6 1788 4 1753 4 ct 1736 4 1721 1 1707 -4 ct +1694 -9 1683 -17 1674 -27 ct 1664 -37 1657 -51 1653 -66 ct 1648 -82 1645 -101 1645 -122 ct +1645 -206 1682 -248 1754 -248 ct 1773 -248 1789 -245 1803 -240 ct 1816 -235 1828 -227 1836 -216 ct +1845 -206 1852 -193 1856 -177 ct 1860 -161 1862 -143 1862 -122 ct p +1820 -122 m 1820 -141 1818 -157 1815 -169 ct 1812 -181 1808 -191 1803 -198 ct +1797 -206 1790 -211 1782 -214 ct 1774 -217 1765 -218 1755 -218 ct 1744 -218 1735 -216 1727 -213 ct +1718 -210 1711 -205 1706 -198 ct 1700 -190 1695 -180 1692 -168 ct 1689 -156 1688 -141 1688 -122 ct +1688 -103 1689 -88 1693 -75 ct 1696 -63 1700 -53 1706 -46 ct 1712 -38 1719 -33 1727 -30 ct +1734 -27 1743 -26 1752 -26 ct 1762 -26 1772 -27 1780 -30 ct 1789 -33 1796 -38 1801 -46 ct +1807 -53 1812 -63 1815 -75 ct 1818 -88 1820 -103 1820 -122 ct p ef +1912 0 m 1912 -186 l 1912 -191 1912 -196 1912 -202 ct 1912 -207 1912 -212 1911 -217 ct +1911 -222 1911 -227 1911 -231 ct 1911 -235 1911 -239 1910 -243 ct 1949 -243 l +1949 -239 1949 -235 1949 -231 ct 1949 -226 1950 -222 1950 -217 ct 1950 -213 1950 -208 1950 -204 ct +1950 -200 1950 -196 1950 -193 ct 1951 -193 l 1954 -202 1957 -210 1960 -217 ct +1964 -224 1967 -229 1972 -234 ct 1976 -238 1981 -242 1987 -244 ct 1993 -246 2000 -247 2009 -247 ct +2012 -247 2015 -247 2018 -246 ct 2021 -246 2024 -245 2025 -245 ct 2025 -208 l +2023 -209 2019 -209 2016 -209 ct 2012 -210 2008 -210 2004 -210 ct 1994 -210 1987 -208 1980 -204 ct +1974 -200 1968 -194 1964 -186 ct 1960 -179 1957 -170 1955 -160 ct 1953 -150 1952 -139 1952 -126 ct +1952 0 l 1912 0 l p ef +pom +gs +25437 3101 m 23341 3101 l 23341 1831 l 27532 1831 l 27532 3101 l 25437 3101 l +eoclip newpath +23342 1832 m 27532 1832 l 27532 3102 l 23342 3102 l 23342 1832 l eoclip newpath +pum +23000 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23212 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23424 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23636 1937 t +211 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23847 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24059 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24271 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24483 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24695 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24907 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25119 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25331 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25543 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25755 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25967 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26179 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26391 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26603 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26814 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +27026 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +27238 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +27450 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23212 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23424 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23636 2149 t +211 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23847 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24059 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24271 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24483 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24695 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24907 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25119 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25331 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25543 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25755 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25967 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26179 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26391 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26603 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26814 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +27026 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +27238 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +27450 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23000 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23212 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23424 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23636 2361 t +211 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23847 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24059 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24271 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24483 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24695 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24907 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25119 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25331 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25543 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25755 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25967 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26179 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26391 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26603 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26814 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +27026 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +27238 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +27450 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23212 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23424 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23636 2573 t +211 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23847 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24059 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24271 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24483 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24695 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24907 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25119 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25331 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25543 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25755 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25967 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26179 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26391 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26603 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26814 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +27026 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +27238 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +27450 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23000 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23212 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23424 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23636 2785 t +211 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23847 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24059 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24271 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24483 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24695 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24907 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25119 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25331 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25543 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25755 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25967 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26179 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26391 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26603 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26814 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +27026 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +27238 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +27450 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23212 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23424 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23636 2997 t +211 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23847 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24059 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24271 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24483 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24695 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24907 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25119 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25331 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25543 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25755 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25967 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26179 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26391 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26603 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26814 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +27026 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +27238 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +27450 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23000 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23212 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23424 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23636 3209 t +211 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23847 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24059 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24271 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24483 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24695 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24907 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25119 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25331 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25543 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25755 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25967 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26179 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26391 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26603 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26814 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +27026 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +27238 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +27450 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +gr +0 lw 25437 3101 m 23341 3101 l 23341 1831 l 27532 1831 l 27532 3101 l +25437 3101 l pc +pum +23479 2348 t +290 -150 m 290 -46 253 6 180 6 ct 158 6 139 2 124 -6 ct 109 -14 97 -28 88 -46 ct +87 -46 l 87 -41 87 -36 87 -31 ct 86 -26 86 -21 86 -17 ct 86 -12 85 -9 85 -5 ct +85 -2 84 0 84 0 ct 36 0 l 37 -1 37 -4 37 -8 ct 37 -12 37 -17 37 -22 ct 38 -28 38 -34 38 -40 ct +38 -47 38 -54 38 -61 ct 38 -409 l 88 -409 l 88 -292 l 88 -287 88 -281 87 -276 ct +87 -271 87 -267 87 -263 ct 87 -258 87 -254 86 -250 ct 88 -250 l 97 -269 109 -283 124 -291 ct +139 -299 158 -303 180 -303 ct 218 -303 246 -291 263 -265 ct 281 -240 290 -202 290 -150 ct +p +238 -148 m 238 -169 237 -187 234 -201 ct 232 -216 227 -228 222 -238 ct 216 -247 209 -254 200 -258 ct +191 -263 180 -265 168 -265 ct 155 -265 143 -263 133 -259 ct 123 -254 115 -248 108 -238 ct +101 -229 96 -217 93 -201 ct 89 -186 88 -167 88 -145 ct 88 -124 89 -106 93 -92 ct +96 -77 101 -65 108 -56 ct 115 -47 123 -41 133 -37 ct 143 -33 154 -31 167 -31 ct +179 -31 190 -33 199 -37 ct 207 -41 215 -48 221 -57 ct 226 -67 231 -79 234 -94 ct +237 -109 238 -127 238 -148 ct p ef +399 -298 m 399 -109 l 399 -94 401 -82 403 -72 ct 405 -63 408 -55 413 -49 ct +418 -43 424 -39 432 -36 ct 440 -34 449 -32 461 -32 ct 473 -32 483 -34 493 -39 ct +502 -43 510 -49 517 -56 ct 524 -64 529 -74 532 -85 ct 536 -97 538 -110 538 -125 ct +538 -298 l 588 -298 l 588 -63 l 588 -57 588 -50 588 -44 ct 588 -37 588 -30 588 -24 ct +588 -18 588 -12 589 -8 ct 589 -4 589 -1 589 0 ct 542 0 l 542 0 542 -3 542 -7 ct +542 -11 541 -16 541 -21 ct 541 -26 541 -31 540 -37 ct 540 -42 540 -47 540 -51 ct +539 -51 l 535 -42 529 -34 524 -27 ct 518 -20 511 -14 504 -9 ct 496 -4 488 -1 478 2 ct +468 5 457 6 444 6 ct 428 6 413 4 401 0 ct 389 -4 380 -10 372 -19 ct 364 -27 359 -38 355 -51 ct +351 -65 350 -81 350 -99 ct 350 -298 l 399 -298 l p ef +665 -362 m 665 -409 l 714 -409 l 714 -362 l 665 -362 l p +665 0 m 665 -298 l 714 -298 l 714 0 l 665 0 l p ef +792 0 m 792 -409 l 842 -409 l 842 0 l 792 0 l p ef +1034 -3 m 1026 -1 1018 1 1011 2 ct 1003 3 994 4 983 4 ct 944 4 924 -19 924 -64 ct +924 -263 l 890 -263 l 890 -299 l 926 -299 l 940 -366 l 974 -366 l +974 -299 l 1029 -299 l 1029 -263 l 974 -263 l 974 -74 l 974 -60 976 -50 981 -44 ct +985 -38 993 -35 1005 -35 ct 1010 -35 1014 -36 1019 -37 ct 1023 -37 1028 -38 1034 -39 ct +1034 -3 l p ef +1062 -128 m 1062 -172 l 1200 -172 l 1200 -128 l 1062 -128 l p ef +1261 -362 m 1261 -409 l 1310 -409 l 1310 -362 l 1261 -362 l p +1261 0 m 1261 -298 l 1310 -298 l 1310 0 l 1261 0 l p ef +1577 0 m 1577 -189 l 1577 -204 1576 -216 1574 -226 ct 1572 -235 1568 -243 1564 -249 ct +1559 -255 1553 -259 1545 -262 ct 1537 -264 1527 -266 1516 -266 ct 1504 -266 1493 -264 1484 -259 ct +1475 -255 1466 -249 1460 -242 ct 1453 -234 1448 -224 1444 -213 ct 1441 -201 1439 -188 1439 -173 ct +1439 0 l 1389 0 l 1389 -235 l 1389 -241 1389 -248 1389 -254 ct 1389 -261 1389 -268 1389 -274 ct +1388 -280 1388 -286 1388 -290 ct 1388 -294 1388 -297 1387 -298 ct 1434 -298 l +1434 -298 1435 -295 1435 -291 ct 1435 -287 1435 -282 1436 -277 ct 1436 -272 1436 -267 1436 -261 ct +1436 -256 1436 -251 1436 -247 ct 1437 -247 l 1442 -256 1447 -264 1453 -271 ct +1459 -278 1465 -284 1473 -289 ct 1480 -294 1489 -297 1499 -300 ct 1508 -303 1520 -304 1533 -304 ct +1549 -304 1563 -302 1575 -298 ct 1587 -294 1597 -288 1605 -279 ct 1612 -271 1618 -260 1622 -246 ct +1625 -233 1627 -217 1627 -199 ct 1627 0 l 1577 0 l p ef +2110 -149 m 2110 -97 2099 -58 2076 -32 ct 2053 -7 2019 6 1976 6 ct 1955 6 1936 3 1920 -3 ct +1904 -10 1890 -19 1879 -32 ct 1867 -45 1859 -61 1853 -81 ct 1847 -100 1844 -123 1844 -149 ct +1844 -252 1888 -304 1977 -304 ct 2000 -304 2020 -300 2037 -294 ct 2054 -288 2068 -278 2078 -265 ct +2089 -252 2097 -236 2102 -217 ct 2107 -197 2110 -175 2110 -149 ct p +2058 -149 m 2058 -172 2056 -191 2053 -207 ct 2049 -222 2044 -234 2037 -243 ct +2030 -252 2022 -258 2012 -262 ct 2002 -265 1991 -267 1978 -267 ct 1965 -267 1954 -265 1944 -261 ct +1934 -258 1925 -251 1918 -242 ct 1911 -233 1905 -221 1901 -206 ct 1898 -191 1896 -172 1896 -149 ct +1896 -126 1898 -107 1902 -92 ct 1906 -76 1911 -64 1918 -55 ct 1926 -46 1934 -40 1944 -36 ct +1953 -33 1964 -31 1975 -31 ct 1988 -31 1999 -32 2009 -36 ct 2020 -40 2028 -46 2036 -55 ct +2043 -64 2048 -76 2052 -91 ct 2056 -107 2058 -126 2058 -149 ct p ef +2424 -151 m 2424 -128 2422 -108 2418 -88 ct 2415 -69 2409 -53 2400 -39 ct 2392 -25 2380 -15 2366 -7 ct +2352 1 2335 5 2314 5 ct 2293 5 2274 1 2258 -7 ct 2243 -15 2230 -28 2222 -47 ct +2220 -47 l 2221 -46 2221 -45 2221 -42 ct 2221 -39 2221 -35 2221 -31 ct 2221 -26 2221 -21 2221 -16 ct +2222 -11 2222 -5 2222 0 ct 2222 117 l 2172 117 l 2172 -238 l 2172 -245 2172 -252 2172 -258 ct +2172 -265 2172 -271 2171 -277 ct 2171 -282 2171 -287 2171 -290 ct 2171 -294 2171 -297 2170 -299 ct +2218 -299 l 2218 -298 2219 -296 2219 -293 ct 2219 -290 2220 -286 2220 -281 ct +2220 -276 2220 -271 2221 -266 ct 2221 -261 2221 -256 2221 -251 ct 2222 -251 l +2227 -260 2232 -268 2238 -275 ct 2244 -282 2250 -287 2258 -292 ct 2265 -296 2274 -299 2283 -301 ct +2292 -303 2303 -304 2314 -304 ct 2335 -304 2352 -300 2366 -293 ct 2380 -286 2392 -275 2400 -262 ct +2409 -249 2415 -233 2418 -214 ct 2422 -195 2424 -174 2424 -151 ct p +2372 -150 m 2372 -168 2371 -185 2369 -199 ct 2366 -213 2363 -225 2357 -235 ct +2352 -245 2345 -253 2336 -258 ct 2327 -263 2315 -266 2302 -266 ct 2291 -266 2280 -264 2271 -261 ct +2261 -258 2252 -252 2245 -243 ct 2238 -234 2232 -222 2228 -207 ct 2224 -191 2222 -171 2222 -146 ct +2222 -125 2223 -107 2227 -92 ct 2230 -78 2235 -66 2242 -57 ct 2249 -48 2257 -42 2267 -38 ct +2277 -34 2288 -32 2301 -32 ct 2315 -32 2326 -34 2335 -40 ct 2345 -45 2352 -53 2357 -63 ct +2363 -73 2366 -85 2369 -100 ct 2371 -115 2372 -131 2372 -150 ct p ef +2523 -138 m 2523 -122 2525 -108 2528 -95 ct 2531 -82 2536 -71 2543 -61 ct 2549 -52 2558 -44 2568 -39 ct +2579 -34 2591 -31 2606 -31 ct 2628 -31 2645 -36 2658 -44 ct 2671 -53 2680 -64 2684 -77 ct +2728 -65 l 2725 -56 2720 -48 2715 -40 ct 2709 -31 2701 -24 2692 -17 ct 2683 -10 2671 -5 2657 0 ct +2643 4 2626 6 2606 6 ct 2562 6 2529 -7 2506 -33 ct 2482 -60 2471 -99 2471 -151 ct +2471 -179 2474 -202 2481 -222 ct 2488 -241 2498 -257 2510 -269 ct 2522 -281 2536 -290 2552 -296 ct +2569 -301 2586 -304 2604 -304 ct 2629 -304 2650 -300 2667 -292 ct 2684 -283 2697 -272 2707 -258 ct +2718 -244 2725 -227 2729 -207 ct 2733 -188 2736 -167 2736 -145 ct 2736 -138 l +2523 -138 l p +2684 -176 m 2682 -208 2674 -231 2660 -245 ct 2647 -260 2628 -267 2603 -267 ct +2595 -267 2586 -266 2577 -263 ct 2568 -260 2560 -256 2552 -249 ct 2545 -242 2538 -233 2533 -221 ct +2527 -209 2524 -194 2524 -176 ct 2684 -176 l p ef +2799 0 m 2799 -229 l 2799 -235 2799 -242 2799 -248 ct 2799 -255 2799 -261 2799 -267 ct +2798 -273 2798 -279 2798 -284 ct 2798 -289 2798 -294 2797 -298 ct 2844 -298 l +2844 -294 2845 -289 2845 -284 ct 2845 -279 2846 -273 2846 -267 ct 2846 -262 2846 -256 2846 -251 ct +2846 -246 2846 -241 2846 -238 ct 2848 -238 l 2851 -249 2855 -259 2859 -267 ct +2863 -276 2867 -282 2873 -288 ct 2878 -293 2884 -297 2892 -300 ct 2899 -303 2908 -304 2918 -304 ct +2922 -304 2926 -304 2930 -303 ct 2934 -302 2936 -302 2938 -301 ct 2938 -256 l +2935 -257 2931 -257 2927 -258 ct 2922 -258 2918 -258 2912 -258 ct 2901 -258 2891 -256 2883 -251 ct +2875 -246 2868 -238 2863 -229 ct 2858 -220 2855 -209 2852 -197 ct 2850 -184 2849 -170 2849 -156 ct +2849 0 l 2799 0 l p ef +3060 6 m 3030 6 3008 -2 2993 -18 ct 2977 -34 2970 -56 2970 -83 ct 2970 -103 2974 -119 2981 -132 ct +2989 -145 2998 -154 3010 -162 ct 3022 -169 3036 -174 3051 -177 ct 3067 -179 3083 -181 3099 -181 ct +3165 -181 l 3165 -197 l 3165 -210 3164 -220 3162 -229 ct 3159 -238 3155 -245 3150 -250 ct +3144 -256 3138 -260 3130 -262 ct 3122 -265 3112 -266 3102 -266 ct 3092 -266 3083 -265 3076 -264 ct +3068 -263 3061 -260 3056 -256 ct 3050 -253 3045 -248 3042 -242 ct 3038 -236 3036 -228 3035 -218 ct +2983 -223 l 2985 -235 2989 -246 2994 -256 ct 2999 -265 3006 -274 3016 -281 ct +3025 -288 3037 -294 3051 -298 ct 3065 -302 3083 -304 3103 -304 ct 3140 -304 3168 -295 3187 -278 ct +3206 -261 3216 -236 3216 -203 ct 3216 -74 l 3216 -60 3218 -49 3221 -41 ct 3225 -34 3233 -30 3243 -30 ct +3246 -30 3249 -30 3252 -31 ct 3254 -31 3257 -31 3260 -32 ct 3260 -1 l 3253 0 3247 2 3241 2 ct +3235 3 3228 3 3221 3 ct 3212 3 3204 2 3197 0 ct 3191 -3 3185 -7 3181 -12 ct 3177 -17 3173 -23 3171 -30 ct +3169 -38 3168 -47 3167 -57 ct 3165 -57 l 3160 -47 3154 -38 3148 -31 ct 3142 -23 3134 -16 3126 -11 ct +3117 -6 3108 -1 3097 2 ct 3086 5 3074 6 3060 6 ct p +3071 -31 m 3087 -31 3101 -34 3113 -40 ct 3125 -46 3134 -53 3142 -62 ct 3150 -71 3156 -81 3160 -91 ct +3164 -102 3165 -112 3165 -122 ct 3165 -146 l 3111 -146 l 3099 -146 3088 -145 3077 -144 ct +3066 -142 3056 -139 3048 -134 ct 3040 -130 3033 -123 3028 -115 ct 3023 -107 3021 -96 3021 -82 ct +3021 -66 3025 -53 3034 -45 ct 3043 -36 3055 -31 3071 -31 ct p ef +3413 -3 m 3405 -1 3397 1 3390 2 ct 3382 3 3373 4 3362 4 ct 3323 4 3303 -19 3303 -64 ct +3303 -263 l 3269 -263 l 3269 -299 l 3305 -299 l 3319 -366 l 3353 -366 l +3353 -299 l 3408 -299 l 3408 -263 l 3353 -263 l 3353 -74 l 3353 -60 3355 -50 3360 -44 ct +3364 -38 3372 -35 3384 -35 ct 3389 -35 3393 -36 3398 -37 ct 3402 -37 3407 -38 3413 -39 ct +3413 -3 l p ef +3706 -149 m 3706 -97 3695 -58 3672 -32 ct 3649 -7 3615 6 3572 6 ct 3551 6 3532 3 3516 -3 ct +3500 -10 3486 -19 3475 -32 ct 3463 -45 3455 -61 3449 -81 ct 3443 -100 3440 -123 3440 -149 ct +3440 -252 3484 -304 3573 -304 ct 3596 -304 3616 -300 3633 -294 ct 3650 -288 3664 -278 3674 -265 ct +3685 -252 3693 -236 3698 -217 ct 3703 -197 3706 -175 3706 -149 ct p +3654 -149 m 3654 -172 3652 -191 3649 -207 ct 3645 -222 3640 -234 3633 -243 ct +3626 -252 3618 -258 3608 -262 ct 3598 -265 3587 -267 3574 -267 ct 3561 -267 3550 -265 3540 -261 ct +3530 -258 3521 -251 3514 -242 ct 3507 -233 3501 -221 3497 -206 ct 3494 -191 3492 -172 3492 -149 ct +3492 -126 3494 -107 3498 -92 ct 3502 -76 3507 -64 3514 -55 ct 3522 -46 3530 -40 3540 -36 ct +3549 -33 3560 -31 3571 -31 ct 3584 -31 3595 -32 3605 -36 ct 3616 -40 3624 -46 3632 -55 ct +3639 -64 3644 -76 3648 -91 ct 3652 -107 3654 -126 3654 -149 ct p ef +3769 0 m 3769 -229 l 3769 -235 3769 -242 3769 -248 ct 3769 -255 3769 -261 3769 -267 ct +3768 -273 3768 -279 3768 -284 ct 3768 -289 3768 -294 3767 -298 ct 3814 -298 l +3814 -294 3815 -289 3815 -284 ct 3815 -279 3816 -273 3816 -267 ct 3816 -262 3816 -256 3816 -251 ct +3816 -246 3816 -241 3816 -238 ct 3818 -238 l 3821 -249 3825 -259 3829 -267 ct +3833 -276 3837 -282 3843 -288 ct 3848 -293 3854 -297 3862 -300 ct 3869 -303 3878 -304 3888 -304 ct +3892 -304 3896 -304 3900 -303 ct 3904 -302 3906 -302 3908 -301 ct 3908 -256 l +3905 -257 3901 -257 3897 -258 ct 3892 -258 3888 -258 3882 -258 ct 3871 -258 3861 -256 3853 -251 ct +3845 -246 3838 -238 3833 -229 ct 3828 -220 3825 -209 3822 -197 ct 3820 -184 3819 -170 3819 -156 ct +3819 0 l 3769 0 l p ef +pom +pum +23959 2975 t +112 -263 m 112 -303 l 112 -313 113 -322 113 -329 ct 114 -337 116 -345 117 -352 ct +119 -359 121 -365 124 -371 ct 127 -377 130 -383 134 -389 ct 167 -389 l 159 -377 153 -365 148 -353 ct +144 -341 141 -329 141 -317 ct 166 -317 l 166 -263 l 112 -263 l p +21 -263 m 21 -303 l 21 -313 21 -322 22 -329 ct 23 -337 24 -345 26 -352 ct +28 -359 30 -365 33 -371 ct 36 -377 39 -383 43 -389 ct 76 -389 l 68 -377 61 -365 57 -353 ct +52 -341 50 -329 50 -317 ct 74 -317 l 74 -263 l 21 -263 l p ef +pom +pum +24145 2975 t +290 -149 m 290 -97 279 -58 256 -32 ct 233 -7 199 6 156 6 ct 135 6 116 3 100 -3 ct +84 -10 70 -19 59 -32 ct 47 -45 39 -61 33 -81 ct 27 -100 24 -123 24 -149 ct 24 -252 68 -304 157 -304 ct +180 -304 200 -300 217 -294 ct 234 -288 248 -278 258 -265 ct 269 -252 277 -236 282 -217 ct +287 -197 290 -175 290 -149 ct p +238 -149 m 238 -172 236 -191 233 -207 ct 229 -222 224 -234 217 -243 ct 210 -252 202 -258 192 -262 ct +182 -265 171 -267 158 -267 ct 145 -267 134 -265 124 -261 ct 114 -258 105 -251 98 -242 ct +91 -233 85 -221 81 -206 ct 78 -191 76 -172 76 -149 ct 76 -126 78 -107 82 -92 ct +86 -76 91 -64 98 -55 ct 106 -46 114 -40 124 -36 ct 133 -33 144 -31 155 -31 ct 168 -31 179 -32 189 -36 ct +200 -40 208 -46 216 -55 ct 223 -64 228 -76 232 -91 ct 236 -107 238 -126 238 -149 ct +p ef +603 -151 m 603 -128 601 -108 597 -88 ct 594 -69 588 -53 579 -39 ct 571 -25 559 -15 545 -7 ct +531 1 514 5 493 5 ct 472 5 453 1 437 -7 ct 422 -15 409 -28 401 -47 ct 399 -47 l +400 -46 400 -45 400 -42 ct 400 -39 400 -35 400 -31 ct 400 -26 400 -21 400 -16 ct +401 -11 401 -5 401 0 ct 401 117 l 351 117 l 351 -238 l 351 -245 351 -252 351 -258 ct +351 -265 351 -271 350 -277 ct 350 -282 350 -287 350 -290 ct 350 -294 350 -297 349 -299 ct +397 -299 l 397 -298 398 -296 398 -293 ct 398 -290 399 -286 399 -281 ct 399 -276 399 -271 400 -266 ct +400 -261 400 -256 400 -251 ct 401 -251 l 406 -260 411 -268 417 -275 ct 423 -282 429 -287 437 -292 ct +444 -296 453 -299 462 -301 ct 471 -303 482 -304 493 -304 ct 514 -304 531 -300 545 -293 ct +559 -286 571 -275 579 -262 ct 588 -249 594 -233 597 -214 ct 601 -195 603 -174 603 -151 ct +p +551 -150 m 551 -168 550 -185 548 -199 ct 545 -213 542 -225 536 -235 ct 531 -245 524 -253 515 -258 ct +506 -263 494 -266 481 -266 ct 470 -266 459 -264 450 -261 ct 440 -258 431 -252 424 -243 ct +417 -234 411 -222 407 -207 ct 403 -191 401 -171 401 -146 ct 401 -125 402 -107 406 -92 ct +409 -78 414 -66 421 -57 ct 428 -48 436 -42 446 -38 ct 456 -34 467 -32 480 -32 ct +494 -32 505 -34 514 -40 ct 524 -45 531 -53 536 -63 ct 542 -73 545 -85 548 -100 ct +550 -115 551 -131 551 -150 ct p ef +703 -138 m 703 -122 705 -108 708 -95 ct 711 -82 716 -71 723 -61 ct 729 -52 738 -44 748 -39 ct +759 -34 771 -31 786 -31 ct 808 -31 825 -36 838 -44 ct 851 -53 860 -64 864 -77 ct +908 -65 l 905 -56 900 -48 895 -40 ct 889 -31 881 -24 872 -17 ct 863 -10 851 -5 837 0 ct +823 4 806 6 786 6 ct 742 6 709 -7 686 -33 ct 662 -60 651 -99 651 -151 ct 651 -179 654 -202 661 -222 ct +668 -241 678 -257 690 -269 ct 702 -281 716 -290 732 -296 ct 749 -301 766 -304 784 -304 ct +809 -304 830 -300 847 -292 ct 864 -283 877 -272 887 -258 ct 898 -244 905 -227 909 -207 ct +913 -188 916 -167 916 -145 ct 916 -138 l 703 -138 l p +864 -176 m 862 -208 854 -231 840 -245 ct 827 -260 808 -267 783 -267 ct 775 -267 766 -266 757 -263 ct +748 -260 740 -256 732 -249 ct 725 -242 718 -233 713 -221 ct 707 -209 704 -194 704 -176 ct +864 -176 l p ef +979 0 m 979 -229 l 979 -235 979 -242 979 -248 ct 979 -255 979 -261 979 -267 ct +978 -273 978 -279 978 -284 ct 978 -289 978 -294 977 -298 ct 1024 -298 l 1024 -294 1025 -289 1025 -284 ct +1025 -279 1026 -273 1026 -267 ct 1026 -262 1026 -256 1026 -251 ct 1026 -246 1026 -241 1026 -238 ct +1028 -238 l 1031 -249 1035 -259 1039 -267 ct 1043 -276 1047 -282 1053 -288 ct +1058 -293 1064 -297 1072 -300 ct 1079 -303 1088 -304 1098 -304 ct 1102 -304 1106 -304 1110 -303 ct +1114 -302 1116 -302 1118 -301 ct 1118 -256 l 1115 -257 1111 -257 1107 -258 ct +1102 -258 1098 -258 1092 -258 ct 1081 -258 1071 -256 1063 -251 ct 1055 -246 1048 -238 1043 -229 ct +1038 -220 1035 -209 1032 -197 ct 1030 -184 1029 -170 1029 -156 ct 1029 0 l 979 0 l +p ef +1240 6 m 1210 6 1188 -2 1173 -18 ct 1157 -34 1150 -56 1150 -83 ct 1150 -103 1154 -119 1161 -132 ct +1169 -145 1178 -154 1190 -162 ct 1202 -169 1216 -174 1231 -177 ct 1247 -179 1263 -181 1279 -181 ct +1345 -181 l 1345 -197 l 1345 -210 1344 -220 1342 -229 ct 1339 -238 1335 -245 1330 -250 ct +1324 -256 1318 -260 1310 -262 ct 1302 -265 1292 -266 1282 -266 ct 1272 -266 1263 -265 1256 -264 ct +1248 -263 1241 -260 1236 -256 ct 1230 -253 1225 -248 1222 -242 ct 1218 -236 1216 -228 1215 -218 ct +1163 -223 l 1165 -235 1169 -246 1174 -256 ct 1179 -265 1186 -274 1196 -281 ct +1205 -288 1217 -294 1231 -298 ct 1245 -302 1263 -304 1283 -304 ct 1320 -304 1348 -295 1367 -278 ct +1386 -261 1396 -236 1396 -203 ct 1396 -74 l 1396 -60 1398 -49 1401 -41 ct 1405 -34 1413 -30 1423 -30 ct +1426 -30 1429 -30 1432 -31 ct 1434 -31 1437 -31 1440 -32 ct 1440 -1 l 1433 0 1427 2 1421 2 ct +1415 3 1408 3 1401 3 ct 1392 3 1384 2 1377 0 ct 1371 -3 1365 -7 1361 -12 ct 1357 -17 1353 -23 1351 -30 ct +1349 -38 1348 -47 1347 -57 ct 1345 -57 l 1340 -47 1334 -38 1328 -31 ct 1322 -23 1314 -16 1306 -11 ct +1297 -6 1288 -1 1277 2 ct 1266 5 1254 6 1240 6 ct p +1251 -31 m 1267 -31 1281 -34 1293 -40 ct 1305 -46 1314 -53 1322 -62 ct 1330 -71 1336 -81 1340 -91 ct +1344 -102 1345 -112 1345 -122 ct 1345 -146 l 1291 -146 l 1279 -146 1268 -145 1257 -144 ct +1246 -142 1236 -139 1228 -134 ct 1220 -130 1213 -123 1208 -115 ct 1203 -107 1201 -96 1201 -82 ct +1201 -66 1205 -53 1214 -45 ct 1223 -36 1235 -31 1251 -31 ct p ef +1592 -3 m 1584 -1 1576 1 1569 2 ct 1561 3 1552 4 1541 4 ct 1502 4 1482 -19 1482 -64 ct +1482 -263 l 1448 -263 l 1448 -299 l 1484 -299 l 1498 -366 l 1532 -366 l +1532 -299 l 1587 -299 l 1587 -263 l 1532 -263 l 1532 -74 l 1532 -60 1534 -50 1539 -44 ct +1543 -38 1551 -35 1563 -35 ct 1568 -35 1572 -36 1577 -37 ct 1581 -37 1586 -38 1592 -39 ct +1592 -3 l p ef +1886 -149 m 1886 -97 1875 -58 1852 -32 ct 1829 -7 1795 6 1752 6 ct 1731 6 1712 3 1696 -3 ct +1680 -10 1666 -19 1655 -32 ct 1643 -45 1635 -61 1629 -81 ct 1623 -100 1620 -123 1620 -149 ct +1620 -252 1664 -304 1753 -304 ct 1776 -304 1796 -300 1813 -294 ct 1830 -288 1844 -278 1854 -265 ct +1865 -252 1873 -236 1878 -217 ct 1883 -197 1886 -175 1886 -149 ct p +1834 -149 m 1834 -172 1832 -191 1829 -207 ct 1825 -222 1820 -234 1813 -243 ct +1806 -252 1798 -258 1788 -262 ct 1778 -265 1767 -267 1754 -267 ct 1741 -267 1730 -265 1720 -261 ct +1710 -258 1701 -251 1694 -242 ct 1687 -233 1681 -221 1677 -206 ct 1674 -191 1672 -172 1672 -149 ct +1672 -126 1674 -107 1678 -92 ct 1682 -76 1687 -64 1694 -55 ct 1702 -46 1710 -40 1720 -36 ct +1729 -33 1740 -31 1751 -31 ct 1764 -31 1775 -32 1785 -36 ct 1796 -40 1804 -46 1812 -55 ct +1819 -64 1824 -76 1828 -91 ct 1832 -107 1834 -126 1834 -149 ct p ef +1948 0 m 1948 -229 l 1948 -235 1948 -242 1948 -248 ct 1948 -255 1948 -261 1948 -267 ct +1947 -273 1947 -279 1947 -284 ct 1947 -289 1947 -294 1946 -298 ct 1993 -298 l +1993 -294 1994 -289 1994 -284 ct 1994 -279 1995 -273 1995 -267 ct 1995 -262 1995 -256 1995 -251 ct +1995 -246 1995 -241 1995 -238 ct 1997 -238 l 2000 -249 2004 -259 2008 -267 ct +2012 -276 2016 -282 2022 -288 ct 2027 -293 2033 -297 2041 -300 ct 2048 -303 2057 -304 2067 -304 ct +2071 -304 2075 -304 2079 -303 ct 2083 -302 2085 -302 2087 -301 ct 2087 -256 l +2084 -257 2080 -257 2076 -258 ct 2071 -258 2067 -258 2061 -258 ct 2050 -258 2040 -256 2032 -251 ct +2024 -246 2017 -238 2012 -229 ct 2007 -220 2004 -209 2001 -197 ct 1999 -184 1998 -170 1998 -156 ct +1998 0 l 1948 0 l p ef +2280 -236 m 2280 -277 l 2554 -277 l 2554 -236 l 2280 -236 l p +2280 -95 m 2280 -136 l 2554 -136 l 2554 -95 l 2280 -95 l p ef +2749 -349 m 2749 -339 2749 -330 2748 -322 ct 2747 -314 2746 -307 2744 -300 ct +2742 -293 2740 -287 2737 -280 ct 2734 -274 2731 -268 2727 -263 ct 2694 -263 l +2702 -274 2709 -287 2713 -299 ct 2718 -311 2720 -323 2720 -335 ct 2696 -335 l +2696 -389 l 2749 -389 l 2749 -349 l p +2658 -349 m 2658 -339 2658 -330 2657 -322 ct 2656 -314 2655 -307 2653 -300 ct +2651 -293 2649 -287 2646 -280 ct 2643 -274 2640 -268 2637 -263 ct 2603 -263 l +2611 -274 2617 -287 2622 -299 ct 2626 -311 2629 -323 2629 -335 ct 2604 -335 l +2604 -389 l 2658 -389 l 2658 -349 l p ef +pom +gs +15024 3101 m 12928 3101 l 12928 1831 l 17118 1831 l 17118 3101 l 15024 3101 l +eoclip newpath +12928 1832 m 17119 1832 l 17119 3102 l 12928 3102 l 12928 1832 l eoclip newpath +pum +12586 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +12798 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13010 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13222 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13434 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13646 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13858 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14070 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14282 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14494 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14706 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14918 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15130 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15342 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15554 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15766 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15977 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16189 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16401 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16613 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16825 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17037 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +12798 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13010 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13222 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13434 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13646 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13858 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14070 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14282 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14494 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14706 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14918 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15130 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15342 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15554 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15766 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15977 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16189 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16401 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16613 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16825 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17037 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +12586 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +12798 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13010 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13222 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13434 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13646 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13858 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14070 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14282 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14494 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14706 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14918 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15130 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15342 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15554 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15766 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15977 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16189 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16401 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16613 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16825 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17037 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +12798 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13010 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13222 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13434 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13646 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13858 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14070 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14282 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14494 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14706 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14918 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15130 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15342 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15554 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15766 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15977 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16189 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16401 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16613 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16825 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17037 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +12586 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +12798 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13010 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13222 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13434 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13646 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13858 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14070 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14282 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14494 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14706 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14918 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15130 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15342 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15554 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15766 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15977 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16189 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16401 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16613 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16825 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17037 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +12798 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13010 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13222 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13434 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13646 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13858 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14070 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14282 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14494 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14706 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14918 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15130 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15342 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15554 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15766 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15977 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16189 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16401 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16613 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16825 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17037 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +12586 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +12798 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13010 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13222 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13434 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13646 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13858 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14070 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14282 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14494 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14706 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14918 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15130 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15342 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15554 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15766 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15977 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16189 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16401 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16613 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16825 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17037 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +gr +15024 3101 m 12928 3101 l 12928 1831 l 17118 1831 l 17118 3101 l 15024 3101 l +pc +pum +13563 2348 t +227 0 m 227 -189 l 227 -204 226 -216 224 -226 ct 222 -235 218 -243 214 -249 ct +209 -255 203 -259 195 -262 ct 187 -264 177 -266 166 -266 ct 154 -266 143 -264 134 -259 ct +125 -255 116 -249 110 -242 ct 103 -234 98 -224 94 -213 ct 91 -201 89 -188 89 -173 ct +89 0 l 39 0 l 39 -235 l 39 -241 39 -248 39 -254 ct 39 -261 39 -268 39 -274 ct +38 -280 38 -286 38 -290 ct 38 -294 38 -297 37 -298 ct 84 -298 l 84 -298 85 -295 85 -291 ct +85 -287 85 -282 86 -277 ct 86 -272 86 -267 86 -261 ct 86 -256 86 -251 86 -247 ct +87 -247 l 92 -256 97 -264 103 -271 ct 109 -278 115 -284 123 -289 ct 130 -294 139 -297 149 -300 ct +158 -303 170 -304 183 -304 ct 199 -304 213 -302 225 -298 ct 237 -294 247 -288 255 -279 ct +262 -271 268 -260 272 -246 ct 275 -233 277 -217 277 -199 ct 277 0 l 227 0 l +p ef +427 6 m 397 6 375 -2 360 -18 ct 344 -34 337 -56 337 -83 ct 337 -103 341 -119 348 -132 ct +356 -145 365 -154 377 -162 ct 389 -169 403 -174 418 -177 ct 434 -179 450 -181 466 -181 ct +532 -181 l 532 -197 l 532 -210 531 -220 529 -229 ct 526 -238 522 -245 517 -250 ct +511 -256 505 -260 497 -262 ct 489 -265 479 -266 469 -266 ct 459 -266 450 -265 443 -264 ct +435 -263 428 -260 423 -256 ct 417 -253 412 -248 409 -242 ct 405 -236 403 -228 402 -218 ct +350 -223 l 352 -235 356 -246 361 -256 ct 366 -265 373 -274 383 -281 ct 392 -288 404 -294 418 -298 ct +432 -302 450 -304 470 -304 ct 507 -304 535 -295 554 -278 ct 573 -261 583 -236 583 -203 ct +583 -74 l 583 -60 585 -49 588 -41 ct 592 -34 600 -30 610 -30 ct 613 -30 616 -30 619 -31 ct +621 -31 624 -31 627 -32 ct 627 -1 l 620 0 614 2 608 2 ct 602 3 595 3 588 3 ct +579 3 571 2 564 0 ct 558 -3 552 -7 548 -12 ct 544 -17 540 -23 538 -30 ct 536 -38 535 -47 534 -57 ct +532 -57 l 527 -47 521 -38 515 -31 ct 509 -23 501 -16 493 -11 ct 484 -6 475 -1 464 2 ct +453 5 441 6 427 6 ct p +438 -31 m 454 -31 468 -34 480 -40 ct 492 -46 501 -53 509 -62 ct 517 -71 523 -81 527 -91 ct +531 -102 532 -112 532 -122 ct 532 -146 l 478 -146 l 466 -146 455 -145 444 -144 ct +433 -142 423 -139 415 -134 ct 407 -130 400 -123 395 -115 ct 390 -107 388 -96 388 -82 ct +388 -66 392 -53 401 -45 ct 410 -36 422 -31 438 -31 ct p ef +839 0 m 839 -189 l 839 -204 838 -216 836 -226 ct 834 -235 831 -243 827 -249 ct +822 -255 817 -259 810 -262 ct 803 -264 794 -266 784 -266 ct 774 -266 764 -264 756 -259 ct +747 -255 740 -249 734 -242 ct 728 -234 723 -224 720 -213 ct 717 -201 715 -188 715 -173 ct +715 0 l 666 0 l 666 -235 l 666 -241 666 -248 666 -254 ct 666 -261 666 -268 666 -274 ct +665 -280 665 -286 665 -290 ct 665 -294 665 -297 664 -298 ct 711 -298 l 711 -298 712 -295 712 -291 ct +712 -287 712 -282 713 -277 ct 713 -272 713 -267 713 -261 ct 713 -256 713 -251 713 -247 ct +714 -247 l 719 -256 723 -264 729 -271 ct 734 -278 740 -284 747 -289 ct 754 -294 761 -297 770 -300 ct +779 -303 790 -304 801 -304 ct 824 -304 842 -300 855 -290 ct 868 -281 877 -267 882 -247 ct +883 -247 l 888 -256 892 -264 898 -271 ct 904 -278 910 -284 917 -289 ct 925 -294 933 -297 942 -300 ct +951 -303 962 -304 973 -304 ct 989 -304 1001 -302 1012 -298 ct 1023 -294 1032 -288 1039 -279 ct +1046 -271 1051 -260 1055 -246 ct 1058 -233 1060 -217 1060 -199 ct 1060 0 l 1011 0 l +1011 -189 l 1011 -204 1010 -216 1008 -226 ct 1006 -235 1003 -243 999 -249 ct +994 -255 989 -259 982 -262 ct 975 -264 966 -266 956 -266 ct 946 -266 936 -264 928 -260 ct +919 -256 912 -250 906 -242 ct 900 -234 896 -225 892 -213 ct 889 -202 888 -188 888 -173 ct +888 0 l 839 0 l p ef +1177 -138 m 1177 -122 1179 -108 1182 -95 ct 1185 -82 1190 -71 1197 -61 ct 1203 -52 1212 -44 1222 -39 ct +1233 -34 1245 -31 1260 -31 ct 1282 -31 1299 -36 1312 -44 ct 1325 -53 1334 -64 1338 -77 ct +1382 -65 l 1379 -56 1374 -48 1369 -40 ct 1363 -31 1355 -24 1346 -17 ct 1337 -10 1325 -5 1311 0 ct +1297 4 1280 6 1260 6 ct 1216 6 1183 -7 1160 -33 ct 1136 -60 1125 -99 1125 -151 ct +1125 -179 1128 -202 1135 -222 ct 1142 -241 1152 -257 1164 -269 ct 1176 -281 1190 -290 1206 -296 ct +1223 -301 1240 -304 1258 -304 ct 1283 -304 1304 -300 1321 -292 ct 1338 -283 1351 -272 1361 -258 ct +1372 -244 1379 -227 1383 -207 ct 1387 -188 1390 -167 1390 -145 ct 1390 -138 l +1177 -138 l p +1338 -176 m 1336 -208 1328 -231 1314 -245 ct 1301 -260 1282 -267 1257 -267 ct +1249 -267 1240 -266 1231 -263 ct 1222 -260 1214 -256 1206 -249 ct 1199 -242 1192 -233 1187 -221 ct +1181 -209 1178 -194 1178 -176 ct 1338 -176 l p ef +1676 -82 m 1676 -68 1673 -56 1668 -45 ct 1662 -34 1654 -24 1644 -17 ct 1634 -10 1621 -4 1606 0 ct +1591 4 1574 6 1555 6 ct 1537 6 1522 5 1508 2 ct 1494 -1 1482 -5 1472 -11 ct 1461 -17 1452 -24 1445 -34 ct +1438 -44 1433 -56 1430 -70 ct 1473 -78 l 1478 -62 1486 -50 1500 -43 ct 1513 -36 1531 -32 1555 -32 ct +1565 -32 1575 -33 1584 -34 ct 1593 -35 1601 -38 1607 -42 ct 1613 -45 1618 -50 1622 -56 ct +1626 -62 1627 -69 1627 -78 ct 1627 -87 1625 -95 1621 -100 ct 1617 -106 1611 -111 1603 -115 ct +1596 -119 1587 -122 1576 -125 ct 1565 -128 1554 -131 1541 -134 ct 1529 -137 1517 -141 1505 -145 ct +1493 -149 1483 -154 1473 -160 ct 1464 -166 1456 -174 1450 -184 ct 1444 -193 1442 -205 1442 -219 ct +1442 -246 1451 -267 1471 -281 ct 1490 -295 1518 -303 1555 -303 ct 1588 -303 1614 -297 1634 -285 ct +1653 -274 1665 -255 1670 -229 ct 1626 -224 l 1624 -232 1621 -238 1617 -243 ct +1612 -249 1607 -253 1601 -256 ct 1594 -259 1587 -262 1580 -263 ct 1572 -264 1564 -265 1555 -265 ct +1533 -265 1516 -262 1506 -255 ct 1495 -248 1490 -238 1490 -224 ct 1490 -216 1492 -209 1496 -204 ct +1500 -199 1505 -194 1512 -191 ct 1519 -187 1528 -184 1538 -181 ct 1548 -179 1558 -176 1570 -173 ct +1578 -171 1586 -169 1595 -166 ct 1603 -164 1611 -161 1619 -158 ct 1627 -155 1634 -151 1641 -147 ct +1648 -143 1654 -137 1659 -131 ct 1664 -125 1668 -118 1671 -110 ct 1674 -102 1676 -93 1676 -82 ct +p ef +1988 -151 m 1988 -128 1986 -108 1982 -88 ct 1979 -69 1973 -53 1964 -39 ct 1956 -25 1944 -15 1930 -7 ct +1916 1 1899 5 1878 5 ct 1857 5 1838 1 1822 -7 ct 1807 -15 1794 -28 1786 -47 ct +1784 -47 l 1785 -46 1785 -45 1785 -42 ct 1785 -39 1785 -35 1785 -31 ct 1785 -26 1785 -21 1785 -16 ct +1786 -11 1786 -5 1786 0 ct 1786 117 l 1736 117 l 1736 -238 l 1736 -245 1736 -252 1736 -258 ct +1736 -265 1736 -271 1735 -277 ct 1735 -282 1735 -287 1735 -290 ct 1735 -294 1735 -297 1734 -299 ct +1782 -299 l 1782 -298 1783 -296 1783 -293 ct 1783 -290 1784 -286 1784 -281 ct +1784 -276 1784 -271 1785 -266 ct 1785 -261 1785 -256 1785 -251 ct 1786 -251 l +1791 -260 1796 -268 1802 -275 ct 1808 -282 1814 -287 1822 -292 ct 1829 -296 1838 -299 1847 -301 ct +1856 -303 1867 -304 1878 -304 ct 1899 -304 1916 -300 1930 -293 ct 1944 -286 1956 -275 1964 -262 ct +1973 -249 1979 -233 1982 -214 ct 1986 -195 1988 -174 1988 -151 ct p +1936 -150 m 1936 -168 1935 -185 1933 -199 ct 1930 -213 1927 -225 1921 -235 ct +1916 -245 1909 -253 1900 -258 ct 1891 -263 1879 -266 1866 -266 ct 1855 -266 1844 -264 1835 -261 ct +1825 -258 1816 -252 1809 -243 ct 1802 -234 1796 -222 1792 -207 ct 1788 -191 1786 -171 1786 -146 ct +1786 -125 1787 -107 1791 -92 ct 1794 -78 1799 -66 1806 -57 ct 1813 -48 1821 -42 1831 -38 ct +1841 -34 1852 -32 1865 -32 ct 1879 -32 1890 -34 1899 -40 ct 1909 -45 1916 -53 1921 -63 ct +1927 -73 1930 -85 1933 -100 ct 1935 -115 1936 -131 1936 -150 ct p ef +2125 6 m 2095 6 2073 -2 2058 -18 ct 2042 -34 2035 -56 2035 -83 ct 2035 -103 2039 -119 2046 -132 ct +2054 -145 2063 -154 2075 -162 ct 2087 -169 2101 -174 2116 -177 ct 2132 -179 2148 -181 2164 -181 ct +2230 -181 l 2230 -197 l 2230 -210 2229 -220 2227 -229 ct 2224 -238 2220 -245 2215 -250 ct +2209 -256 2203 -260 2195 -262 ct 2187 -265 2177 -266 2167 -266 ct 2157 -266 2148 -265 2141 -264 ct +2133 -263 2126 -260 2121 -256 ct 2115 -253 2110 -248 2107 -242 ct 2103 -236 2101 -228 2100 -218 ct +2048 -223 l 2050 -235 2054 -246 2059 -256 ct 2064 -265 2071 -274 2081 -281 ct +2090 -288 2102 -294 2116 -298 ct 2130 -302 2148 -304 2168 -304 ct 2205 -304 2233 -295 2252 -278 ct +2271 -261 2281 -236 2281 -203 ct 2281 -74 l 2281 -60 2283 -49 2286 -41 ct 2290 -34 2298 -30 2308 -30 ct +2311 -30 2314 -30 2317 -31 ct 2319 -31 2322 -31 2325 -32 ct 2325 -1 l 2318 0 2312 2 2306 2 ct +2300 3 2293 3 2286 3 ct 2277 3 2269 2 2262 0 ct 2256 -3 2250 -7 2246 -12 ct 2242 -17 2238 -23 2236 -30 ct +2234 -38 2233 -47 2232 -57 ct 2230 -57 l 2225 -47 2219 -38 2213 -31 ct 2207 -23 2199 -16 2191 -11 ct +2182 -6 2173 -1 2162 2 ct 2151 5 2139 6 2125 6 ct p +2136 -31 m 2152 -31 2166 -34 2178 -40 ct 2190 -46 2199 -53 2207 -62 ct 2215 -71 2221 -81 2225 -91 ct +2229 -102 2230 -112 2230 -122 ct 2230 -146 l 2176 -146 l 2164 -146 2153 -145 2142 -144 ct +2131 -142 2121 -139 2113 -134 ct 2105 -130 2098 -123 2093 -115 ct 2088 -107 2086 -96 2086 -82 ct +2086 -66 2090 -53 2099 -45 ct 2108 -36 2120 -31 2136 -31 ct p ef +2400 -150 m 2400 -133 2401 -117 2403 -103 ct 2406 -89 2410 -76 2416 -66 ct +2422 -56 2430 -47 2439 -42 ct 2449 -36 2461 -33 2475 -33 ct 2493 -33 2507 -38 2519 -47 ct +2531 -56 2538 -71 2541 -90 ct 2591 -90 l 2589 -78 2586 -65 2580 -54 ct 2575 -42 2567 -32 2558 -23 ct +2548 -14 2537 -7 2523 -2 ct 2510 3 2494 6 2476 6 ct 2453 6 2433 2 2417 -6 ct 2400 -14 2387 -25 2377 -39 ct +2367 -53 2359 -69 2355 -88 ct 2350 -107 2348 -127 2348 -149 ct 2348 -169 2350 -187 2353 -202 ct +2356 -218 2361 -231 2367 -243 ct 2373 -254 2380 -264 2388 -272 ct 2396 -280 2405 -286 2414 -291 ct +2424 -295 2434 -299 2444 -301 ct 2455 -303 2465 -304 2476 -304 ct 2492 -304 2507 -302 2520 -297 ct +2533 -292 2545 -286 2554 -278 ct 2564 -270 2571 -261 2577 -250 ct 2583 -239 2587 -227 2589 -215 ct +2539 -211 l 2536 -227 2529 -241 2519 -250 ct 2509 -260 2494 -265 2474 -265 ct +2460 -265 2448 -263 2439 -258 ct 2430 -253 2422 -246 2416 -237 ct 2410 -227 2406 -215 2403 -201 ct +2401 -187 2400 -170 2400 -150 ct p ef +2684 -138 m 2684 -122 2686 -108 2689 -95 ct 2692 -82 2697 -71 2704 -61 ct 2710 -52 2719 -44 2729 -39 ct +2740 -34 2752 -31 2767 -31 ct 2789 -31 2806 -36 2819 -44 ct 2832 -53 2841 -64 2845 -77 ct +2889 -65 l 2886 -56 2881 -48 2876 -40 ct 2870 -31 2862 -24 2853 -17 ct 2844 -10 2832 -5 2818 0 ct +2804 4 2787 6 2767 6 ct 2723 6 2690 -7 2667 -33 ct 2643 -60 2632 -99 2632 -151 ct +2632 -179 2635 -202 2642 -222 ct 2649 -241 2659 -257 2671 -269 ct 2683 -281 2697 -290 2713 -296 ct +2730 -301 2747 -304 2765 -304 ct 2790 -304 2811 -300 2828 -292 ct 2845 -283 2858 -272 2868 -258 ct +2879 -244 2886 -227 2890 -207 ct 2894 -188 2897 -167 2897 -145 ct 2897 -138 l +2684 -138 l p +2845 -176 m 2843 -208 2835 -231 2821 -245 ct 2808 -260 2789 -267 2764 -267 ct +2756 -267 2747 -266 2738 -263 ct 2729 -260 2721 -256 2713 -249 ct 2706 -242 2699 -233 2694 -221 ct +2688 -209 2685 -194 2685 -176 ct 2845 -176 l p ef +pom +pum +14116 2975 t +167 -349 m 167 -339 167 -330 166 -322 ct 165 -314 164 -307 162 -300 ct 160 -293 158 -287 155 -280 ct +152 -274 149 -268 145 -263 ct 112 -263 l 120 -274 127 -287 131 -299 ct 136 -311 138 -323 138 -335 ct +114 -335 l 114 -389 l 167 -389 l 167 -349 l p +76 -349 m 76 -339 76 -330 75 -322 ct 74 -314 73 -307 71 -300 ct 69 -293 67 -287 64 -280 ct +61 -274 58 -268 55 -263 ct 21 -263 l 29 -274 35 -287 40 -299 ct 44 -311 47 -323 47 -335 ct +22 -335 l 22 -389 l 76 -389 l 76 -349 l p ef +pom +pum +14302 2975 t +218 -351 m 196 -351 177 -347 160 -340 ct 143 -333 128 -322 117 -308 ct 105 -295 97 -279 91 -259 ct +85 -240 82 -219 82 -196 ct 82 -172 85 -151 92 -132 ct 98 -112 107 -95 119 -81 ct +131 -67 145 -57 162 -49 ct 180 -41 199 -37 220 -37 ct 235 -37 249 -39 261 -43 ct +274 -47 285 -53 295 -60 ct 305 -67 314 -76 322 -85 ct 330 -95 337 -106 343 -118 ct +386 -97 l 379 -82 370 -69 360 -56 ct 350 -44 338 -33 324 -24 ct 310 -14 294 -7 277 -2 ct +259 3 240 6 218 6 ct 186 6 159 1 135 -9 ct 112 -19 92 -33 76 -51 ct 60 -69 48 -90 40 -115 ct +33 -139 29 -166 29 -196 ct 29 -226 33 -253 41 -278 ct 50 -302 62 -323 78 -340 ct +94 -358 114 -371 137 -380 ct 161 -389 187 -394 218 -394 ct 259 -394 293 -386 321 -370 ct +349 -354 369 -330 382 -298 ct 332 -281 l 329 -290 324 -299 318 -308 ct 311 -316 303 -323 294 -330 ct +285 -336 274 -341 261 -345 ct 249 -349 234 -351 218 -351 ct p ef +444 -362 m 444 -409 l 493 -409 l 493 -362 l 444 -362 l p +444 0 m 444 -298 l 493 -298 l 493 0 l 444 0 l p ef +572 0 m 572 -229 l 572 -235 572 -242 572 -248 ct 572 -255 572 -261 572 -267 ct +571 -273 571 -279 571 -284 ct 571 -289 571 -294 570 -298 ct 617 -298 l 617 -294 618 -289 618 -284 ct +618 -279 619 -273 619 -267 ct 619 -262 619 -256 619 -251 ct 619 -246 619 -241 619 -238 ct +621 -238 l 624 -249 628 -259 632 -267 ct 636 -276 640 -282 646 -288 ct 651 -293 657 -297 665 -300 ct +672 -303 681 -304 691 -304 ct 695 -304 699 -304 703 -303 ct 707 -302 709 -302 711 -301 ct +711 -256 l 708 -257 704 -257 700 -258 ct 695 -258 691 -258 685 -258 ct 674 -258 664 -256 656 -251 ct +648 -246 641 -238 636 -229 ct 631 -220 628 -209 625 -197 ct 623 -184 622 -170 622 -156 ct +622 0 l 572 0 l p ef +796 -150 m 796 -133 797 -117 799 -103 ct 802 -89 806 -76 812 -66 ct 818 -56 826 -47 835 -42 ct +845 -36 857 -33 871 -33 ct 889 -33 903 -38 915 -47 ct 927 -56 934 -71 937 -90 ct +987 -90 l 985 -78 982 -65 976 -54 ct 971 -42 963 -32 954 -23 ct 944 -14 933 -7 919 -2 ct +906 3 890 6 872 6 ct 849 6 829 2 813 -6 ct 796 -14 783 -25 773 -39 ct 763 -53 755 -69 751 -88 ct +746 -107 744 -127 744 -149 ct 744 -169 746 -187 749 -202 ct 752 -218 757 -231 763 -243 ct +769 -254 776 -264 784 -272 ct 792 -280 801 -286 810 -291 ct 820 -295 830 -299 840 -301 ct +851 -303 861 -304 872 -304 ct 888 -304 903 -302 916 -297 ct 929 -292 941 -286 950 -278 ct +960 -270 967 -261 973 -250 ct 979 -239 983 -227 985 -215 ct 935 -211 l 932 -227 925 -241 915 -250 ct +905 -260 890 -265 870 -265 ct 856 -265 844 -263 835 -258 ct 826 -253 818 -246 812 -237 ct +806 -227 802 -215 799 -201 ct 797 -187 796 -170 796 -150 ct p ef +1041 0 m 1041 -409 l 1091 -409 l 1091 0 l 1041 0 l p ef +1206 -138 m 1206 -122 1208 -108 1211 -95 ct 1214 -82 1219 -71 1226 -61 ct 1232 -52 1241 -44 1251 -39 ct +1262 -34 1274 -31 1289 -31 ct 1311 -31 1328 -36 1341 -44 ct 1354 -53 1363 -64 1367 -77 ct +1411 -65 l 1408 -56 1403 -48 1398 -40 ct 1392 -31 1384 -24 1375 -17 ct 1366 -10 1354 -5 1340 0 ct +1326 4 1309 6 1289 6 ct 1245 6 1212 -7 1189 -33 ct 1165 -60 1154 -99 1154 -151 ct +1154 -179 1157 -202 1164 -222 ct 1171 -241 1181 -257 1193 -269 ct 1205 -281 1219 -290 1235 -296 ct +1252 -301 1269 -304 1287 -304 ct 1312 -304 1333 -300 1350 -292 ct 1367 -283 1380 -272 1390 -258 ct +1401 -244 1408 -227 1412 -207 ct 1416 -188 1419 -167 1419 -145 ct 1419 -138 l +1206 -138 l p +1367 -176 m 1365 -208 1357 -231 1343 -245 ct 1330 -260 1311 -267 1286 -267 ct +1278 -267 1269 -266 1260 -263 ct 1251 -260 1243 -256 1235 -249 ct 1228 -242 1221 -233 1216 -221 ct +1210 -209 1207 -194 1207 -176 ct 1367 -176 l p ef +1611 -349 m 1611 -339 1611 -330 1610 -322 ct 1609 -314 1608 -307 1606 -300 ct +1604 -293 1602 -287 1599 -280 ct 1596 -274 1593 -268 1589 -263 ct 1556 -263 l +1564 -274 1571 -287 1575 -299 ct 1580 -311 1582 -323 1582 -335 ct 1558 -335 l +1558 -389 l 1611 -389 l 1611 -349 l p +1520 -349 m 1520 -339 1520 -330 1519 -322 ct 1518 -314 1517 -307 1515 -300 ct +1513 -293 1511 -287 1508 -280 ct 1505 -274 1502 -268 1499 -263 ct 1465 -263 l +1473 -274 1479 -287 1484 -299 ct 1488 -311 1491 -323 1491 -335 ct 1466 -335 l +1466 -389 l 1520 -389 l 1520 -349 l p ef +pom +gs +30644 3101 m 28548 3101 l 28548 1831 l 32738 1831 l 32738 3101 l 30644 3101 l +eoclip newpath +28548 1832 m 32739 1832 l 32739 3102 l 28548 3102 l 28548 1832 l eoclip newpath +pum +28206 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +28418 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +28630 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +28842 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29054 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29266 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29478 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29690 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29902 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30114 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30326 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30538 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30750 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30962 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +31174 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +31386 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +31598 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +31810 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +32021 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +32233 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +32445 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +32657 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +28418 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +28630 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +28842 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29054 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29266 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29478 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29690 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29902 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30114 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30326 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30538 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30750 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30962 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +31174 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +31386 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +31598 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +31810 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +32021 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +32233 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +32445 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +32657 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +28206 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +28418 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +28630 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +28842 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29054 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29266 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29478 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29690 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29902 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30114 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30326 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30538 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30750 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30962 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +31174 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +31386 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +31598 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +31810 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +32021 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +32233 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +32445 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +32657 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +28418 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +28630 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +28842 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29054 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29266 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29478 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29690 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29902 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30114 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30326 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30538 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30750 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30962 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +31174 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +31386 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +31598 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +31810 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +32021 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +32233 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +32445 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +32657 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +28206 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +28418 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +28630 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +28842 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29054 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29266 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29478 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29690 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29902 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30114 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30326 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30538 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30750 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30962 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +31174 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +31386 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +31598 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +31810 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +32021 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +32233 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +32445 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +32657 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +28418 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +28630 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +28842 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29054 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29266 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29478 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29690 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29902 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30114 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30326 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30538 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30750 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30962 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +31174 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +31386 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +31598 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +31810 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +32021 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +32233 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +32445 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +32657 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +28206 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +28418 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +28630 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +28842 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29054 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29266 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29478 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29690 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +29902 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30114 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30326 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30538 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30750 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +30962 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +31174 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +31386 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +31598 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +31810 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +32021 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +32233 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +32445 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +32657 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +gr +30644 3101 m 28548 3101 l 28548 1831 l 32738 1831 l 32738 3101 l 30644 3101 l +pc +pum +29655 2348 t +99 -263 m 99 0 l 50 0 l 50 -263 l 8 -263 l 8 -299 l 50 -299 l 50 -333 l +50 -343 51 -353 53 -363 ct 55 -372 59 -380 64 -387 ct 69 -394 77 -399 86 -403 ct +96 -407 108 -409 123 -409 ct 128 -409 135 -409 141 -408 ct 147 -408 153 -407 158 -406 ct +158 -368 l 154 -368 151 -369 147 -369 ct 143 -370 139 -370 136 -370 ct 128 -370 122 -369 117 -367 ct +113 -365 109 -362 106 -358 ct 104 -355 102 -350 101 -345 ct 100 -339 99 -333 99 -326 ct +99 -299 l 158 -299 l 158 -263 l 99 -263 l p ef +243 -298 m 243 -109 l 243 -94 245 -82 247 -72 ct 249 -63 252 -55 257 -49 ct +262 -43 268 -39 276 -36 ct 284 -34 293 -32 305 -32 ct 317 -32 327 -34 337 -39 ct +346 -43 354 -49 361 -56 ct 368 -64 373 -74 376 -85 ct 380 -97 382 -110 382 -125 ct +382 -298 l 432 -298 l 432 -63 l 432 -57 432 -50 432 -44 ct 432 -37 432 -30 432 -24 ct +432 -18 432 -12 433 -8 ct 433 -4 433 -1 433 0 ct 386 0 l 386 0 386 -3 386 -7 ct +386 -11 385 -16 385 -21 ct 385 -26 385 -31 384 -37 ct 384 -42 384 -47 384 -51 ct +383 -51 l 379 -42 373 -34 368 -27 ct 362 -20 355 -14 348 -9 ct 340 -4 332 -1 322 2 ct +312 5 301 6 288 6 ct 272 6 257 4 245 0 ct 233 -4 224 -10 216 -19 ct 208 -27 203 -38 199 -51 ct +195 -65 194 -81 194 -99 ct 194 -298 l 243 -298 l p ef +697 0 m 697 -189 l 697 -204 696 -216 694 -226 ct 692 -235 688 -243 684 -249 ct +679 -255 673 -259 665 -262 ct 657 -264 647 -266 636 -266 ct 624 -266 613 -264 604 -259 ct +595 -255 586 -249 580 -242 ct 573 -234 568 -224 564 -213 ct 561 -201 559 -188 559 -173 ct +559 0 l 509 0 l 509 -235 l 509 -241 509 -248 509 -254 ct 509 -261 509 -268 509 -274 ct +508 -280 508 -286 508 -290 ct 508 -294 508 -297 507 -298 ct 554 -298 l 554 -298 555 -295 555 -291 ct +555 -287 555 -282 556 -277 ct 556 -272 556 -267 556 -261 ct 556 -256 556 -251 556 -247 ct +557 -247 l 562 -256 567 -264 573 -271 ct 579 -278 585 -284 593 -289 ct 600 -294 609 -297 619 -300 ct +628 -303 640 -304 653 -304 ct 669 -304 683 -302 695 -298 ct 707 -294 717 -288 725 -279 ct +732 -271 738 -260 742 -246 ct 745 -233 747 -217 747 -199 ct 747 0 l 697 0 l +p ef +859 -150 m 859 -133 860 -117 862 -103 ct 865 -89 869 -76 875 -66 ct 881 -56 889 -47 898 -42 ct +908 -36 920 -33 934 -33 ct 952 -33 966 -38 978 -47 ct 990 -56 997 -71 1000 -90 ct +1050 -90 l 1048 -78 1045 -65 1039 -54 ct 1034 -42 1026 -32 1017 -23 ct 1007 -14 996 -7 982 -2 ct +969 3 953 6 935 6 ct 912 6 892 2 876 -6 ct 859 -14 846 -25 836 -39 ct 826 -53 818 -69 814 -88 ct +809 -107 807 -127 807 -149 ct 807 -169 809 -187 812 -202 ct 815 -218 820 -231 826 -243 ct +832 -254 839 -264 847 -272 ct 855 -280 864 -286 873 -291 ct 883 -295 893 -299 903 -301 ct +914 -303 924 -304 935 -304 ct 951 -304 966 -302 979 -297 ct 992 -292 1004 -286 1013 -278 ct +1023 -270 1030 -261 1036 -250 ct 1042 -239 1046 -227 1048 -215 ct 998 -211 l +995 -227 988 -241 978 -250 ct 968 -260 953 -265 933 -265 ct 919 -265 907 -263 898 -258 ct +889 -253 881 -246 875 -237 ct 869 -227 865 -215 862 -201 ct 860 -187 859 -170 859 -150 ct +p ef +1220 -3 m 1212 -1 1204 1 1197 2 ct 1189 3 1180 4 1169 4 ct 1130 4 1110 -19 1110 -64 ct +1110 -263 l 1076 -263 l 1076 -299 l 1112 -299 l 1126 -366 l 1160 -366 l +1160 -299 l 1215 -299 l 1215 -263 l 1160 -263 l 1160 -74 l 1160 -60 1162 -50 1167 -44 ct +1171 -38 1179 -35 1191 -35 ct 1196 -35 1200 -36 1205 -37 ct 1209 -37 1214 -38 1220 -39 ct +1220 -3 l p ef +1261 -362 m 1261 -409 l 1310 -409 l 1310 -362 l 1261 -362 l p +1261 0 m 1261 -298 l 1310 -298 l 1310 0 l 1261 0 l p ef +1640 -149 m 1640 -97 1629 -58 1606 -32 ct 1583 -7 1549 6 1506 6 ct 1485 6 1466 3 1450 -3 ct +1434 -10 1420 -19 1409 -32 ct 1397 -45 1389 -61 1383 -81 ct 1377 -100 1374 -123 1374 -149 ct +1374 -252 1418 -304 1507 -304 ct 1530 -304 1550 -300 1567 -294 ct 1584 -288 1598 -278 1608 -265 ct +1619 -252 1627 -236 1632 -217 ct 1637 -197 1640 -175 1640 -149 ct p +1588 -149 m 1588 -172 1586 -191 1583 -207 ct 1579 -222 1574 -234 1567 -243 ct +1560 -252 1552 -258 1542 -262 ct 1532 -265 1521 -267 1508 -267 ct 1495 -267 1484 -265 1474 -261 ct +1464 -258 1455 -251 1448 -242 ct 1441 -233 1435 -221 1431 -206 ct 1428 -191 1426 -172 1426 -149 ct +1426 -126 1428 -107 1432 -92 ct 1436 -76 1441 -64 1448 -55 ct 1456 -46 1464 -40 1474 -36 ct +1483 -33 1494 -31 1505 -31 ct 1518 -31 1529 -32 1539 -36 ct 1550 -40 1558 -46 1566 -55 ct +1573 -64 1578 -76 1582 -91 ct 1586 -107 1588 -126 1588 -149 ct p ef +1891 0 m 1891 -189 l 1891 -204 1890 -216 1888 -226 ct 1886 -235 1882 -243 1878 -249 ct +1873 -255 1867 -259 1859 -262 ct 1851 -264 1841 -266 1830 -266 ct 1818 -266 1807 -264 1798 -259 ct +1789 -255 1780 -249 1774 -242 ct 1767 -234 1762 -224 1758 -213 ct 1755 -201 1753 -188 1753 -173 ct +1753 0 l 1703 0 l 1703 -235 l 1703 -241 1703 -248 1703 -254 ct 1703 -261 1703 -268 1703 -274 ct +1702 -280 1702 -286 1702 -290 ct 1702 -294 1702 -297 1701 -298 ct 1748 -298 l +1748 -298 1749 -295 1749 -291 ct 1749 -287 1749 -282 1750 -277 ct 1750 -272 1750 -267 1750 -261 ct +1750 -256 1750 -251 1750 -247 ct 1751 -247 l 1756 -256 1761 -264 1767 -271 ct +1773 -278 1779 -284 1787 -289 ct 1794 -294 1803 -297 1813 -300 ct 1822 -303 1834 -304 1847 -304 ct +1863 -304 1877 -302 1889 -298 ct 1901 -294 1911 -288 1919 -279 ct 1926 -271 1932 -260 1936 -246 ct +1939 -233 1941 -217 1941 -199 ct 1941 0 l 1891 0 l p ef +pom +pum +29850 2975 t +112 -263 m 112 -303 l 112 -313 113 -322 113 -329 ct 114 -337 116 -345 117 -352 ct +119 -359 121 -365 124 -371 ct 127 -377 130 -383 134 -389 ct 167 -389 l 159 -377 153 -365 148 -353 ct +144 -341 141 -329 141 -317 ct 166 -317 l 166 -263 l 112 -263 l p +21 -263 m 21 -303 l 21 -313 21 -322 22 -329 ct 23 -337 24 -345 26 -352 ct +28 -359 30 -365 33 -371 ct 36 -377 39 -383 43 -389 ct 76 -389 l 68 -377 61 -365 57 -353 ct +52 -341 50 -329 50 -317 ct 74 -317 l 74 -263 l 21 -263 l p ef +pom +pum +30036 2975 t +226 -48 m 217 -28 205 -15 190 -6 ct 174 2 156 6 133 6 ct 96 6 68 -7 50 -32 ct +33 -57 24 -96 24 -147 ct 24 -252 60 -304 133 -304 ct 156 -304 175 -300 190 -291 ct +205 -283 217 -270 226 -252 ct 227 -252 l 227 -254 227 -257 227 -260 ct 226 -264 226 -269 226 -273 ct +226 -277 226 -281 226 -285 ct 226 -289 226 -292 226 -293 ct 226 -409 l 276 -409 l +276 -61 l 276 -54 276 -47 276 -40 ct 276 -34 276 -28 276 -22 ct 276 -17 277 -12 277 -8 ct +277 -4 277 -1 277 0 ct 230 0 l 230 -1 229 -4 229 -7 ct 229 -11 228 -15 228 -19 ct +228 -24 228 -28 227 -33 ct 227 -38 227 -43 227 -48 ct 226 -48 l p +76 -149 m 76 -129 77 -111 80 -96 ct 82 -81 86 -69 92 -60 ct 98 -50 105 -43 114 -39 ct +123 -35 133 -32 146 -32 ct 159 -32 171 -34 181 -39 ct 191 -43 199 -50 206 -59 ct +212 -69 217 -81 221 -96 ct 224 -112 226 -130 226 -152 ct 226 -174 224 -191 221 -206 ct +217 -221 212 -233 205 -242 ct 199 -251 190 -257 181 -261 ct 171 -265 159 -267 147 -267 ct +134 -267 124 -265 115 -261 ct 106 -256 99 -250 93 -240 ct 87 -231 83 -219 80 -204 ct +77 -189 76 -170 76 -149 ct p ef +352 0 m 352 -229 l 352 -235 352 -242 352 -248 ct 352 -255 352 -261 352 -267 ct +351 -273 351 -279 351 -284 ct 351 -289 351 -294 350 -298 ct 397 -298 l 397 -294 398 -289 398 -284 ct +398 -279 399 -273 399 -267 ct 399 -262 399 -256 399 -251 ct 399 -246 399 -241 399 -238 ct +401 -238 l 404 -249 408 -259 412 -267 ct 416 -276 420 -282 426 -288 ct 431 -293 437 -297 445 -300 ct +452 -303 461 -304 471 -304 ct 475 -304 479 -304 483 -303 ct 487 -302 489 -302 491 -301 ct +491 -256 l 488 -257 484 -257 480 -258 ct 475 -258 471 -258 465 -258 ct 454 -258 444 -256 436 -251 ct +428 -246 421 -238 416 -229 ct 411 -220 408 -209 405 -197 ct 403 -184 402 -170 402 -156 ct +402 0 l 352 0 l p ef +614 6 m 584 6 562 -2 547 -18 ct 531 -34 524 -56 524 -83 ct 524 -103 528 -119 535 -132 ct +543 -145 552 -154 564 -162 ct 576 -169 590 -174 605 -177 ct 621 -179 637 -181 653 -181 ct +719 -181 l 719 -197 l 719 -210 718 -220 716 -229 ct 713 -238 709 -245 704 -250 ct +698 -256 692 -260 684 -262 ct 676 -265 666 -266 656 -266 ct 646 -266 637 -265 630 -264 ct +622 -263 615 -260 610 -256 ct 604 -253 599 -248 596 -242 ct 592 -236 590 -228 589 -218 ct +537 -223 l 539 -235 543 -246 548 -256 ct 553 -265 560 -274 570 -281 ct 579 -288 591 -294 605 -298 ct +619 -302 637 -304 657 -304 ct 694 -304 722 -295 741 -278 ct 760 -261 770 -236 770 -203 ct +770 -74 l 770 -60 772 -49 775 -41 ct 779 -34 787 -30 797 -30 ct 800 -30 803 -30 806 -31 ct +808 -31 811 -31 814 -32 ct 814 -1 l 807 0 801 2 795 2 ct 789 3 782 3 775 3 ct +766 3 758 2 751 0 ct 745 -3 739 -7 735 -12 ct 731 -17 727 -23 725 -30 ct 723 -38 722 -47 721 -57 ct +719 -57 l 714 -47 708 -38 702 -31 ct 696 -23 688 -16 680 -11 ct 671 -6 662 -1 651 2 ct +640 5 628 6 614 6 ct p +625 -31 m 641 -31 655 -34 667 -40 ct 679 -46 688 -53 696 -62 ct 704 -71 710 -81 714 -91 ct +718 -102 719 -112 719 -122 ct 719 -146 l 665 -146 l 653 -146 642 -145 631 -144 ct +620 -142 610 -139 602 -134 ct 594 -130 587 -123 582 -115 ct 577 -107 575 -96 575 -82 ct +575 -66 579 -53 588 -45 ct 597 -36 609 -31 625 -31 ct p ef +1136 0 m 1079 0 l 1031 -193 l 1030 -198 1028 -204 1027 -211 ct 1025 -218 1023 -226 1022 -233 ct +1020 -241 1018 -249 1017 -258 ct 1015 -249 1013 -241 1012 -233 ct 1010 -226 1008 -219 1007 -211 ct +1005 -204 1003 -197 1002 -191 ct 953 0 l 896 0 l 812 -299 l 861 -299 l +912 -96 l 913 -91 914 -86 915 -80 ct 917 -74 918 -68 919 -62 ct 921 -55 922 -48 923 -41 ct +925 -48 926 -55 928 -62 ct 930 -67 931 -73 933 -79 ct 934 -85 935 -90 936 -94 ct +990 -299 l 1044 -299 l 1096 -94 l 1097 -89 1098 -83 1100 -77 ct 1101 -71 1103 -65 1104 -60 ct +1105 -54 1107 -48 1108 -41 ct 1110 -48 1111 -55 1113 -62 ct 1114 -67 1115 -73 1117 -79 ct +1118 -85 1119 -91 1121 -96 ct 1173 -299 l 1222 -299 l 1136 0 l p ef +1382 -349 m 1382 -339 1382 -330 1381 -322 ct 1380 -314 1379 -307 1377 -300 ct +1375 -293 1373 -287 1370 -280 ct 1367 -274 1364 -268 1360 -263 ct 1327 -263 l +1335 -274 1342 -287 1346 -299 ct 1351 -311 1353 -323 1353 -335 ct 1329 -335 l +1329 -389 l 1382 -389 l 1382 -349 l p +1291 -349 m 1291 -339 1291 -330 1290 -322 ct 1289 -314 1288 -307 1286 -300 ct +1284 -293 1282 -287 1279 -280 ct 1276 -274 1273 -268 1270 -263 ct 1236 -263 l +1244 -274 1250 -287 1255 -299 ct 1259 -311 1262 -323 1262 -335 ct 1237 -335 l +1237 -389 l 1291 -389 l 1291 -349 l p ef +pom +gs +20230 3101 m 18134 3101 l 18134 1831 l 22325 1831 l 22325 3101 l 20230 3101 l +eoclip newpath +18135 1832 m 22326 1832 l 22326 3102 l 18135 3102 l 18135 1832 l eoclip newpath +pum +17793 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18005 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18217 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18429 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18641 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18853 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19065 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19277 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19489 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19701 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19913 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20125 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20337 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20549 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20761 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20973 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21185 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21397 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21608 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21820 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22032 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22244 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18005 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18217 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18429 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18641 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18853 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19065 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19277 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19489 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19701 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19913 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20125 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20337 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20549 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20761 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20973 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21185 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21397 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21608 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21820 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22032 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22244 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17793 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18005 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18217 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18429 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18641 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18853 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19065 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19277 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19489 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19701 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19913 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20125 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20337 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20549 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20761 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20973 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21185 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21397 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21608 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21820 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22032 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22244 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18005 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18217 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18429 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18641 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18853 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19065 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19277 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19489 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19701 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19913 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20125 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20337 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20549 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20761 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20973 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21185 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21397 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21608 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21820 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22032 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22244 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17793 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18005 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18217 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18429 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18641 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18853 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19065 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19277 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19489 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19701 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19913 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20125 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20337 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20549 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20761 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20973 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21185 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21397 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21608 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21820 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22032 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22244 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18005 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18217 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18429 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18641 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18853 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19065 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19277 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19489 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19701 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19913 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20125 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20337 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20549 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20761 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20973 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21185 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21397 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21608 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21820 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22032 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22244 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17793 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18005 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18217 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18429 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18641 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18853 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19065 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19277 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19489 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19701 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19913 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20125 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20337 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20549 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20761 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20973 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21185 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21397 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21608 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21820 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22032 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22244 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +gr +20230 3101 m 18134 3101 l 18134 1831 l 22325 1831 l 22325 3101 l 20230 3101 l +pc +pum +19585 2348 t +76 -150 m 76 -133 77 -117 79 -103 ct 82 -89 86 -76 92 -66 ct 98 -56 106 -47 115 -42 ct +125 -36 137 -33 151 -33 ct 169 -33 183 -38 195 -47 ct 207 -56 214 -71 217 -90 ct +267 -90 l 265 -78 262 -65 256 -54 ct 251 -42 243 -32 234 -23 ct 224 -14 213 -7 199 -2 ct +186 3 170 6 152 6 ct 129 6 109 2 93 -6 ct 76 -14 63 -25 53 -39 ct 43 -53 35 -69 31 -88 ct +26 -107 24 -127 24 -149 ct 24 -169 26 -187 29 -202 ct 32 -218 37 -231 43 -243 ct +49 -254 56 -264 64 -272 ct 72 -280 81 -286 90 -291 ct 100 -295 110 -299 120 -301 ct +131 -303 141 -304 152 -304 ct 168 -304 183 -302 196 -297 ct 209 -292 221 -286 230 -278 ct +240 -270 247 -261 253 -250 ct 259 -239 263 -227 265 -215 ct 215 -211 l 212 -227 205 -241 195 -250 ct +185 -260 170 -265 150 -265 ct 136 -265 124 -263 115 -258 ct 106 -253 98 -246 92 -237 ct +86 -227 82 -215 79 -201 ct 77 -187 76 -170 76 -150 ct p ef +322 0 m 322 -409 l 372 -409 l 372 0 l 322 0 l p ef +525 6 m 495 6 473 -2 458 -18 ct 442 -34 435 -56 435 -83 ct 435 -103 439 -119 446 -132 ct +454 -145 463 -154 475 -162 ct 487 -169 501 -174 516 -177 ct 532 -179 548 -181 564 -181 ct +630 -181 l 630 -197 l 630 -210 629 -220 627 -229 ct 624 -238 620 -245 615 -250 ct +609 -256 603 -260 595 -262 ct 587 -265 577 -266 567 -266 ct 557 -266 548 -265 541 -264 ct +533 -263 526 -260 521 -256 ct 515 -253 510 -248 507 -242 ct 503 -236 501 -228 500 -218 ct +448 -223 l 450 -235 454 -246 459 -256 ct 464 -265 471 -274 481 -281 ct 490 -288 502 -294 516 -298 ct +530 -302 548 -304 568 -304 ct 605 -304 633 -295 652 -278 ct 671 -261 681 -236 681 -203 ct +681 -74 l 681 -60 683 -49 686 -41 ct 690 -34 698 -30 708 -30 ct 711 -30 714 -30 717 -31 ct +719 -31 722 -31 725 -32 ct 725 -1 l 718 0 712 2 706 2 ct 700 3 693 3 686 3 ct +677 3 669 2 662 0 ct 656 -3 650 -7 646 -12 ct 642 -17 638 -23 636 -30 ct 634 -38 633 -47 632 -57 ct +630 -57 l 625 -47 619 -38 613 -31 ct 607 -23 599 -16 591 -11 ct 582 -6 573 -1 562 2 ct +551 5 539 6 525 6 ct p +536 -31 m 552 -31 566 -34 578 -40 ct 590 -46 599 -53 607 -62 ct 615 -71 621 -81 625 -91 ct +629 -102 630 -112 630 -122 ct 630 -146 l 576 -146 l 564 -146 553 -145 542 -144 ct +531 -142 521 -139 513 -134 ct 505 -130 498 -123 493 -115 ct 488 -107 486 -96 486 -82 ct +486 -66 490 -53 499 -45 ct 508 -36 520 -31 536 -31 ct p ef +986 -82 m 986 -68 983 -56 978 -45 ct 972 -34 964 -24 954 -17 ct 944 -10 931 -4 916 0 ct +901 4 884 6 865 6 ct 847 6 832 5 818 2 ct 804 -1 792 -5 782 -11 ct 771 -17 762 -24 755 -34 ct +748 -44 743 -56 740 -70 ct 783 -78 l 788 -62 796 -50 810 -43 ct 823 -36 841 -32 865 -32 ct +875 -32 885 -33 894 -34 ct 903 -35 911 -38 917 -42 ct 923 -45 928 -50 932 -56 ct +936 -62 937 -69 937 -78 ct 937 -87 935 -95 931 -100 ct 927 -106 921 -111 913 -115 ct +906 -119 897 -122 886 -125 ct 875 -128 864 -131 851 -134 ct 839 -137 827 -141 815 -145 ct +803 -149 793 -154 783 -160 ct 774 -166 766 -174 760 -184 ct 754 -193 752 -205 752 -219 ct +752 -246 761 -267 781 -281 ct 800 -295 828 -303 865 -303 ct 898 -303 924 -297 944 -285 ct +963 -274 975 -255 980 -229 ct 936 -224 l 934 -232 931 -238 927 -243 ct 922 -249 917 -253 911 -256 ct +904 -259 897 -262 890 -263 ct 882 -264 874 -265 865 -265 ct 843 -265 826 -262 816 -255 ct +805 -248 800 -238 800 -224 ct 800 -216 802 -209 806 -204 ct 810 -199 815 -194 822 -191 ct +829 -187 838 -184 848 -181 ct 858 -179 868 -176 880 -173 ct 888 -171 896 -169 905 -166 ct +913 -164 921 -161 929 -158 ct 937 -155 944 -151 951 -147 ct 958 -143 964 -137 969 -131 ct +974 -125 978 -118 981 -110 ct 984 -102 986 -93 986 -82 ct p ef +1270 -82 m 1270 -68 1267 -56 1262 -45 ct 1256 -34 1248 -24 1238 -17 ct 1228 -10 1215 -4 1200 0 ct +1185 4 1168 6 1149 6 ct 1131 6 1116 5 1102 2 ct 1088 -1 1076 -5 1066 -11 ct 1055 -17 1046 -24 1039 -34 ct +1032 -44 1027 -56 1024 -70 ct 1067 -78 l 1072 -62 1080 -50 1094 -43 ct 1107 -36 1125 -32 1149 -32 ct +1159 -32 1169 -33 1178 -34 ct 1187 -35 1195 -38 1201 -42 ct 1207 -45 1212 -50 1216 -56 ct +1220 -62 1221 -69 1221 -78 ct 1221 -87 1219 -95 1215 -100 ct 1211 -106 1205 -111 1197 -115 ct +1190 -119 1181 -122 1170 -125 ct 1159 -128 1148 -131 1135 -134 ct 1123 -137 1111 -141 1099 -145 ct +1087 -149 1077 -154 1067 -160 ct 1058 -166 1050 -174 1044 -184 ct 1038 -193 1036 -205 1036 -219 ct +1036 -246 1045 -267 1065 -281 ct 1084 -295 1112 -303 1149 -303 ct 1182 -303 1208 -297 1228 -285 ct +1247 -274 1259 -255 1264 -229 ct 1220 -224 l 1218 -232 1215 -238 1211 -243 ct +1206 -249 1201 -253 1195 -256 ct 1188 -259 1181 -262 1174 -263 ct 1166 -264 1158 -265 1149 -265 ct +1127 -265 1110 -262 1100 -255 ct 1089 -248 1084 -238 1084 -224 ct 1084 -216 1086 -209 1090 -204 ct +1094 -199 1099 -194 1106 -191 ct 1113 -187 1122 -184 1132 -181 ct 1142 -179 1152 -176 1164 -173 ct +1172 -171 1180 -169 1189 -166 ct 1197 -164 1205 -161 1213 -158 ct 1221 -155 1228 -151 1235 -147 ct +1242 -143 1248 -137 1253 -131 ct 1258 -125 1262 -118 1265 -110 ct 1268 -102 1270 -93 1270 -82 ct +p ef +pom +pum +19230 2975 t +112 -263 m 112 -303 l 112 -313 113 -322 113 -329 ct 114 -337 116 -345 117 -352 ct +119 -359 121 -365 124 -371 ct 127 -377 130 -383 134 -389 ct 167 -389 l 159 -377 153 -365 148 -353 ct +144 -341 141 -329 141 -317 ct 166 -317 l 166 -263 l 112 -263 l p +21 -263 m 21 -303 l 21 -313 21 -322 22 -329 ct 23 -337 24 -345 26 -352 ct +28 -359 30 -365 33 -371 ct 36 -377 39 -383 43 -389 ct 76 -389 l 68 -377 61 -365 57 -353 ct +52 -341 50 -329 50 -317 ct 74 -317 l 74 -263 l 21 -263 l p ef +pom +pum +19416 2975 t +350 -107 m 350 -90 347 -75 341 -62 ct 334 -48 325 -36 311 -26 ct 298 -16 282 -8 261 -2 ct +241 3 218 6 190 6 ct 142 6 104 -2 77 -19 ct 50 -36 33 -61 26 -93 ct 77 -103 l 79 -93 83 -84 88 -75 ct +94 -67 101 -60 110 -54 ct 119 -48 130 -43 144 -40 ct 157 -37 173 -35 192 -35 ct +208 -35 222 -36 235 -39 ct 248 -42 259 -46 269 -51 ct 278 -57 285 -64 290 -73 ct +296 -81 298 -92 298 -104 ct 298 -117 295 -127 290 -135 ct 284 -143 276 -149 265 -155 ct +255 -160 242 -164 228 -168 ct 213 -171 197 -175 180 -179 ct 169 -181 158 -184 147 -187 ct +136 -190 126 -193 116 -197 ct 106 -201 96 -206 87 -211 ct 78 -216 71 -223 64 -230 ct +58 -237 53 -246 49 -256 ct 46 -266 44 -277 44 -290 ct 44 -308 48 -324 55 -337 ct +62 -350 73 -361 86 -370 ct 99 -378 115 -384 133 -388 ct 151 -392 170 -394 191 -394 ct +215 -394 236 -392 253 -388 ct 270 -385 284 -379 296 -371 ct 308 -364 317 -355 324 -343 ct +331 -332 337 -319 341 -305 ct 289 -296 l 287 -305 283 -313 278 -321 ct 273 -328 267 -334 259 -339 ct +251 -344 242 -348 230 -350 ct 219 -353 206 -354 191 -354 ct 173 -354 157 -353 145 -349 ct +133 -346 123 -342 116 -336 ct 108 -331 103 -324 100 -317 ct 97 -309 95 -301 95 -293 ct +95 -281 98 -272 104 -264 ct 109 -257 117 -251 127 -246 ct 137 -241 149 -236 162 -233 ct +175 -230 189 -227 203 -223 ct 215 -220 227 -218 239 -215 ct 251 -212 262 -209 273 -205 ct +284 -201 294 -196 303 -191 ct 313 -185 321 -179 328 -171 ct 335 -163 340 -154 344 -144 ct +348 -133 350 -121 350 -107 ct p ef +464 -247 m 470 -257 476 -266 482 -273 ct 489 -280 496 -286 503 -290 ct 511 -295 520 -298 529 -300 ct +538 -302 548 -303 560 -303 ct 579 -303 594 -301 607 -296 ct 619 -290 628 -283 635 -274 ct +643 -265 647 -254 650 -241 ct 653 -228 654 -214 654 -198 ct 654 0 l 604 0 l +604 -189 l 604 -201 603 -212 602 -222 ct 600 -232 597 -240 593 -246 ct 589 -252 582 -257 574 -260 ct +566 -263 556 -265 543 -265 ct 531 -265 520 -263 511 -259 ct 502 -254 493 -248 487 -241 ct +480 -233 475 -224 471 -213 ct 468 -202 466 -189 466 -175 ct 466 0 l 416 0 l +416 -409 l 466 -409 l 466 -302 l 466 -296 466 -290 465 -284 ct 465 -278 465 -272 465 -267 ct +464 -262 464 -258 464 -254 ct 464 -251 464 -248 463 -247 ct 464 -247 l p ef +804 6 m 774 6 752 -2 737 -18 ct 721 -34 714 -56 714 -83 ct 714 -103 718 -119 725 -132 ct +733 -145 742 -154 754 -162 ct 766 -169 780 -174 795 -177 ct 811 -179 827 -181 843 -181 ct +909 -181 l 909 -197 l 909 -210 908 -220 906 -229 ct 903 -238 899 -245 894 -250 ct +888 -256 882 -260 874 -262 ct 866 -265 856 -266 846 -266 ct 836 -266 827 -265 820 -264 ct +812 -263 805 -260 800 -256 ct 794 -253 789 -248 786 -242 ct 782 -236 780 -228 779 -218 ct +727 -223 l 729 -235 733 -246 738 -256 ct 743 -265 750 -274 760 -281 ct 769 -288 781 -294 795 -298 ct +809 -302 827 -304 847 -304 ct 884 -304 912 -295 931 -278 ct 950 -261 960 -236 960 -203 ct +960 -74 l 960 -60 962 -49 965 -41 ct 969 -34 977 -30 987 -30 ct 990 -30 993 -30 996 -31 ct +998 -31 1001 -31 1004 -32 ct 1004 -1 l 997 0 991 2 985 2 ct 979 3 972 3 965 3 ct +956 3 948 2 941 0 ct 935 -3 929 -7 925 -12 ct 921 -17 917 -23 915 -30 ct 913 -38 912 -47 911 -57 ct +909 -57 l 904 -47 898 -38 892 -31 ct 886 -23 878 -16 870 -11 ct 861 -6 852 -1 841 2 ct +830 5 818 6 804 6 ct p +815 -31 m 831 -31 845 -34 857 -40 ct 869 -46 878 -53 886 -62 ct 894 -71 900 -81 904 -91 ct +908 -102 909 -112 909 -122 ct 909 -146 l 855 -146 l 843 -146 832 -145 821 -144 ct +810 -142 800 -139 792 -134 ct 784 -130 777 -123 772 -115 ct 767 -107 765 -96 765 -82 ct +765 -66 769 -53 778 -45 ct 787 -36 799 -31 815 -31 ct p ef +1293 -151 m 1293 -128 1291 -108 1287 -88 ct 1284 -69 1278 -53 1269 -39 ct 1261 -25 1249 -15 1235 -7 ct +1221 1 1204 5 1183 5 ct 1162 5 1143 1 1127 -7 ct 1112 -15 1099 -28 1091 -47 ct +1089 -47 l 1090 -46 1090 -45 1090 -42 ct 1090 -39 1090 -35 1090 -31 ct 1090 -26 1090 -21 1090 -16 ct +1091 -11 1091 -5 1091 0 ct 1091 117 l 1041 117 l 1041 -238 l 1041 -245 1041 -252 1041 -258 ct +1041 -265 1041 -271 1040 -277 ct 1040 -282 1040 -287 1040 -290 ct 1040 -294 1040 -297 1039 -299 ct +1087 -299 l 1087 -298 1088 -296 1088 -293 ct 1088 -290 1089 -286 1089 -281 ct +1089 -276 1089 -271 1090 -266 ct 1090 -261 1090 -256 1090 -251 ct 1091 -251 l +1096 -260 1101 -268 1107 -275 ct 1113 -282 1119 -287 1127 -292 ct 1134 -296 1143 -299 1152 -301 ct +1161 -303 1172 -304 1183 -304 ct 1204 -304 1221 -300 1235 -293 ct 1249 -286 1261 -275 1269 -262 ct +1278 -249 1284 -233 1287 -214 ct 1291 -195 1293 -174 1293 -151 ct p +1241 -150 m 1241 -168 1240 -185 1238 -199 ct 1235 -213 1232 -225 1226 -235 ct +1221 -245 1214 -253 1205 -258 ct 1196 -263 1184 -266 1171 -266 ct 1160 -266 1149 -264 1140 -261 ct +1130 -258 1121 -252 1114 -243 ct 1107 -234 1101 -222 1097 -207 ct 1093 -191 1091 -171 1091 -146 ct +1091 -125 1092 -107 1096 -92 ct 1099 -78 1104 -66 1111 -57 ct 1118 -48 1126 -42 1136 -38 ct +1146 -34 1157 -32 1170 -32 ct 1184 -32 1195 -34 1204 -40 ct 1214 -45 1221 -53 1226 -63 ct +1232 -73 1235 -85 1238 -100 ct 1240 -115 1241 -131 1241 -150 ct p ef +1393 -138 m 1393 -122 1395 -108 1398 -95 ct 1401 -82 1406 -71 1413 -61 ct 1419 -52 1428 -44 1438 -39 ct +1449 -34 1461 -31 1476 -31 ct 1498 -31 1515 -36 1528 -44 ct 1541 -53 1550 -64 1554 -77 ct +1598 -65 l 1595 -56 1590 -48 1585 -40 ct 1579 -31 1571 -24 1562 -17 ct 1553 -10 1541 -5 1527 0 ct +1513 4 1496 6 1476 6 ct 1432 6 1399 -7 1376 -33 ct 1352 -60 1341 -99 1341 -151 ct +1341 -179 1344 -202 1351 -222 ct 1358 -241 1368 -257 1380 -269 ct 1392 -281 1406 -290 1422 -296 ct +1439 -301 1456 -304 1474 -304 ct 1499 -304 1520 -300 1537 -292 ct 1554 -283 1567 -272 1577 -258 ct +1588 -244 1595 -227 1599 -207 ct 1603 -188 1606 -167 1606 -145 ct 1606 -138 l +1393 -138 l p +1554 -176 m 1552 -208 1544 -231 1530 -245 ct 1517 -260 1498 -267 1473 -267 ct +1465 -267 1456 -266 1447 -263 ct 1438 -260 1430 -256 1422 -249 ct 1415 -242 1408 -233 1403 -221 ct +1397 -209 1394 -194 1394 -176 ct 1554 -176 l p ef +1797 -349 m 1797 -339 1797 -330 1796 -322 ct 1795 -314 1794 -307 1792 -300 ct +1790 -293 1788 -287 1785 -280 ct 1782 -274 1779 -268 1775 -263 ct 1742 -263 l +1750 -274 1757 -287 1761 -299 ct 1766 -311 1768 -323 1768 -335 ct 1744 -335 l +1744 -389 l 1797 -389 l 1797 -349 l p +1706 -349 m 1706 -339 1706 -330 1705 -322 ct 1704 -314 1703 -307 1701 -300 ct +1699 -293 1697 -287 1694 -280 ct 1691 -274 1688 -268 1685 -263 ct 1651 -263 l +1659 -274 1665 -287 1670 -299 ct 1674 -311 1677 -323 1677 -335 ct 1652 -335 l +1652 -389 l 1706 -389 l 1706 -349 l p ef +pom +1.000 1.000 1.000 c 28932 4371 m 28743 4371 28555 4559 28555 4748 ct 28555 5264 l +28555 5453 28743 5642 28932 5642 ct 32496 5642 l 32685 5642 32874 5453 32874 5264 ct +32874 4748 l 32874 4559 32685 4371 32496 4371 ct 28932 4371 l p +28555 4371 m 28555 4371 l p +32874 5642 m 32874 5642 l p ef +0.003 0.003 0.003 c 28932 4371 m 28743 4371 28555 4559 28555 4748 ct 28555 5264 l +28555 5453 28743 5642 28932 5642 ct 32495 5642 l 32684 5642 32873 5453 32873 5264 ct +32873 4748 l 32873 4559 32684 4371 32495 4371 ct 28932 4371 l pc +28555 4371 m 28555 4371 l pc +32873 5642 m 32873 5642 l pc +pum +28915 5213 t +274 0 m 213 0 165 -18 129 -54 ct 93 -90 75 -139 75 -200 ct 75 -261 93 -309 129 -345 ct +165 -381 213 -399 274 -399 ct 335 -399 383 -381 420 -345 ct 457 -309 475 -260 475 -200 ct +475 -139 457 -91 420 -54 ct 383 -18 335 0 274 0 ct p ef +pom +pum +29677 5178 t +41 0 m 41 -340 l 298 -340 l 298 -302 l 87 -302 l 87 -193 l 284 -193 l +284 -156 l 87 -156 l 87 -38 l 308 -38 l 308 0 l 41 0 l p ef +523 0 m 453 -107 l 382 0 l 336 0 l 428 -134 l 340 -261 l 388 -261 l +453 -160 l 518 -261 l 566 -261 l 478 -135 l 572 0 l 523 0 l p ef +639 -121 m 639 -107 640 -95 643 -83 ct 646 -72 650 -62 656 -54 ct 662 -45 669 -39 678 -34 ct +688 -30 699 -28 711 -28 ct 730 -28 745 -31 757 -39 ct 768 -46 776 -56 780 -68 ct +818 -57 l 815 -49 811 -42 806 -35 ct 801 -28 795 -21 787 -15 ct 778 -9 768 -4 756 -1 ct +744 3 729 5 711 5 ct 673 5 643 -7 623 -30 ct 603 -53 593 -87 593 -132 ct 593 -157 596 -177 602 -194 ct +608 -211 617 -225 627 -236 ct 638 -246 650 -254 664 -259 ct 679 -264 694 -266 710 -266 ct +732 -266 750 -262 765 -255 ct 779 -248 791 -238 800 -226 ct 809 -213 815 -199 819 -182 ct +823 -165 825 -147 825 -127 ct 825 -121 l 639 -121 l p +780 -154 m 778 -182 771 -202 759 -215 ct 747 -228 731 -234 709 -234 ct 702 -234 694 -233 686 -230 ct +678 -228 671 -224 664 -218 ct 657 -212 652 -204 647 -193 ct 642 -183 640 -170 639 -154 ct +780 -154 l p ef +913 -132 m 913 -117 914 -103 917 -90 ct 919 -78 922 -67 928 -58 ct 933 -49 940 -42 948 -37 ct +956 -32 967 -29 979 -29 ct 995 -29 1008 -33 1018 -41 ct 1028 -50 1035 -62 1037 -79 ct +1081 -79 l 1080 -68 1076 -58 1072 -47 ct 1067 -37 1060 -28 1052 -21 ct 1044 -13 1034 -7 1022 -2 ct +1010 3 996 5 980 5 ct 960 5 943 2 928 -5 ct 914 -12 902 -22 893 -34 ct 885 -46 878 -60 874 -77 ct +870 -94 868 -111 868 -131 ct 868 -148 869 -164 872 -177 ct 875 -191 879 -202 885 -213 ct +890 -223 896 -231 903 -238 ct 910 -245 918 -250 926 -254 ct 934 -258 943 -261 952 -263 ct +961 -265 971 -266 980 -266 ct 995 -266 1008 -264 1019 -260 ct 1030 -256 1040 -250 1049 -243 ct +1057 -236 1064 -228 1069 -219 ct 1074 -209 1077 -199 1080 -188 ct 1035 -185 l +1033 -199 1027 -211 1018 -219 ct 1009 -228 996 -232 979 -232 ct 966 -232 956 -230 948 -226 ct +939 -222 933 -216 928 -207 ct 922 -199 919 -188 917 -176 ct 914 -163 913 -149 913 -132 ct +p ef +1172 -261 m 1172 -95 l 1172 -83 1173 -72 1175 -64 ct 1176 -55 1179 -48 1184 -43 ct +1188 -38 1193 -34 1200 -32 ct 1207 -30 1215 -29 1226 -29 ct 1236 -29 1245 -30 1253 -34 ct +1262 -38 1269 -43 1275 -50 ct 1280 -57 1285 -65 1288 -75 ct 1291 -85 1293 -97 1293 -110 ct +1293 -261 l 1336 -261 l 1336 -56 l 1336 -50 1337 -44 1337 -38 ct 1337 -32 1337 -27 1337 -21 ct +1337 -16 1337 -11 1337 -7 ct 1338 -3 1338 -1 1338 0 ct 1297 0 l 1297 -1 1297 -3 1296 -6 ct +1296 -10 1296 -14 1296 -19 ct 1296 -23 1295 -28 1295 -33 ct 1295 -37 1295 -41 1295 -44 ct +1294 -44 l 1290 -37 1286 -30 1281 -24 ct 1276 -18 1270 -13 1263 -8 ct 1257 -4 1249 -1 1240 2 ct +1232 4 1222 5 1211 5 ct 1196 5 1184 3 1173 0 ct 1163 -4 1154 -9 1148 -17 ct 1141 -24 1136 -34 1133 -45 ct +1130 -57 1128 -71 1128 -87 ct 1128 -261 l 1172 -261 l p ef +1506 -2 m 1499 0 1492 1 1485 2 ct 1479 3 1471 4 1462 4 ct 1427 4 1410 -16 1410 -55 ct +1410 -229 l 1379 -229 l 1379 -261 l 1411 -261 l 1424 -320 l 1453 -320 l +1453 -261 l 1501 -261 l 1501 -229 l 1453 -229 l 1453 -65 l 1453 -52 1455 -43 1459 -38 ct +1463 -33 1470 -31 1481 -31 ct 1485 -31 1489 -31 1493 -31 ct 1497 -32 1501 -33 1506 -34 ct +1506 -2 l p ef +1544 -316 m 1544 -358 l 1587 -358 l 1587 -316 l 1544 -316 l p +1544 0 m 1544 -261 l 1587 -261 l 1587 0 l 1544 0 l p ef +1875 -131 m 1875 -85 1865 -51 1845 -29 ct 1825 -6 1796 5 1757 5 ct 1739 5 1723 2 1709 -3 ct +1694 -9 1682 -17 1672 -28 ct 1662 -40 1655 -54 1650 -71 ct 1644 -88 1642 -108 1642 -131 ct +1642 -221 1681 -266 1759 -266 ct 1779 -266 1796 -263 1811 -258 ct 1826 -252 1838 -243 1847 -232 ct +1857 -221 1864 -207 1868 -190 ct 1873 -173 1875 -153 1875 -131 ct p +1829 -131 m 1829 -151 1828 -168 1825 -181 ct 1822 -194 1817 -205 1811 -213 ct +1805 -221 1798 -226 1789 -229 ct 1780 -232 1770 -234 1759 -234 ct 1748 -234 1738 -232 1729 -229 ct +1721 -226 1713 -220 1707 -212 ct 1700 -204 1696 -193 1692 -180 ct 1689 -167 1687 -151 1687 -131 ct +1687 -110 1689 -94 1693 -80 ct 1696 -67 1701 -57 1707 -49 ct 1713 -41 1721 -35 1729 -32 ct +1738 -29 1747 -27 1757 -27 ct 1768 -27 1778 -29 1787 -32 ct 1796 -35 1804 -40 1810 -48 ct +1816 -56 1821 -67 1824 -80 ct 1828 -94 1829 -110 1829 -131 ct p ef +2096 0 m 2096 -166 l 2096 -178 2095 -189 2093 -197 ct 2091 -206 2088 -213 2084 -218 ct +2080 -223 2074 -227 2068 -229 ct 2061 -231 2052 -232 2042 -232 ct 2032 -232 2023 -231 2014 -227 ct +2006 -223 1999 -218 1993 -211 ct 1987 -205 1983 -196 1979 -186 ct 1976 -176 1975 -164 1975 -151 ct +1975 0 l 1931 0 l 1931 -205 l 1931 -211 1931 -217 1931 -223 ct 1931 -229 1931 -234 1931 -240 ct +1931 -245 1930 -250 1930 -254 ct 1930 -258 1930 -260 1930 -261 ct 1971 -261 l +1971 -260 1971 -258 1971 -255 ct 1971 -251 1972 -247 1972 -242 ct 1972 -238 1972 -233 1973 -228 ct +1973 -224 1973 -220 1973 -217 ct 1973 -217 l 1978 -224 1982 -231 1987 -237 ct +1992 -243 1998 -248 2005 -253 ct 2011 -257 2019 -260 2027 -263 ct 2036 -265 2046 -266 2057 -266 ct +2071 -266 2084 -264 2094 -261 ct 2105 -257 2113 -252 2120 -244 ct 2127 -237 2132 -227 2135 -216 ct +2138 -204 2140 -190 2140 -174 ct 2140 0 l 2096 0 l p ef +pom +gs +9817 5768 m 7721 5768 l 7721 4498 l 11912 4498 l 11912 5768 l 9817 5768 l +eoclip newpath +7722 4498 m 11912 4498 l 11912 5768 l 7722 5768 l 7722 4498 l eoclip newpath +pum +7380 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +7592 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +7804 4603 t +211 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8015 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8227 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8439 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8651 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8863 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9075 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9287 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9499 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9711 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9923 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10135 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10347 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10559 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10770 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10982 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +11194 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +11406 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +11618 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +11830 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +7592 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +7804 4815 t +211 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8015 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8227 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8439 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8651 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8863 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9075 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9287 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9499 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9711 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9923 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10135 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10347 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10559 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10770 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10982 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +11194 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +11406 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +11618 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +11830 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +7380 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +7592 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +7804 5027 t +211 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8015 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8227 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8439 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8651 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8863 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9075 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9287 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9499 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9711 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9923 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10135 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10347 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10559 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10770 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10982 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +11194 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +11406 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +11618 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +11830 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +7592 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +7804 5239 t +211 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8015 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8227 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8439 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8651 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8863 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9075 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9287 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9499 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9711 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9923 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10135 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10347 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10559 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10770 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10982 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +11194 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +11406 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +11618 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +11830 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +7380 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +7592 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +7804 5451 t +211 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8015 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8227 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8439 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8651 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8863 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9075 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9287 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9499 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9711 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9923 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10135 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10347 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10559 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10770 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10982 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +11194 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +11406 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +11618 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +11830 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +7592 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +7804 5663 t +211 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8015 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8227 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8439 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8651 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8863 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9075 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9287 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9499 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9711 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9923 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10135 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10347 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10559 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10770 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10982 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +11194 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +11406 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +11618 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +11830 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +7380 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +7592 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +7804 5875 t +211 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8015 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8227 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8439 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8651 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +8863 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9075 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9287 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9499 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9711 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +9923 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10135 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10347 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10559 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10770 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +10982 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +11194 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +11406 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +11618 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +11830 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +gr +9817 5768 m 7721 5768 l 7721 4498 l 11912 4498 l 11912 5768 l 9817 5768 l +pc +pum +8828 5014 t +99 -263 m 99 0 l 50 0 l 50 -263 l 8 -263 l 8 -299 l 50 -299 l 50 -333 l +50 -343 51 -353 53 -363 ct 55 -372 59 -380 64 -387 ct 69 -394 77 -399 86 -403 ct +96 -407 108 -409 123 -409 ct 128 -409 135 -409 141 -408 ct 147 -408 153 -407 158 -406 ct +158 -368 l 154 -368 151 -369 147 -369 ct 143 -370 139 -370 136 -370 ct 128 -370 122 -369 117 -367 ct +113 -365 109 -362 106 -358 ct 104 -355 102 -350 101 -345 ct 100 -339 99 -333 99 -326 ct +99 -299 l 158 -299 l 158 -263 l 99 -263 l p ef +243 -298 m 243 -109 l 243 -94 245 -82 247 -72 ct 249 -63 252 -55 257 -49 ct +262 -43 268 -39 276 -36 ct 284 -34 293 -32 305 -32 ct 317 -32 327 -34 337 -39 ct +346 -43 354 -49 361 -56 ct 368 -64 373 -74 376 -85 ct 380 -97 382 -110 382 -125 ct +382 -298 l 432 -298 l 432 -63 l 432 -57 432 -50 432 -44 ct 432 -37 432 -30 432 -24 ct +432 -18 432 -12 433 -8 ct 433 -4 433 -1 433 0 ct 386 0 l 386 0 386 -3 386 -7 ct +386 -11 385 -16 385 -21 ct 385 -26 385 -31 384 -37 ct 384 -42 384 -47 384 -51 ct +383 -51 l 379 -42 373 -34 368 -27 ct 362 -20 355 -14 348 -9 ct 340 -4 332 -1 322 2 ct +312 5 301 6 288 6 ct 272 6 257 4 245 0 ct 233 -4 224 -10 216 -19 ct 208 -27 203 -38 199 -51 ct +195 -65 194 -81 194 -99 ct 194 -298 l 243 -298 l p ef +697 0 m 697 -189 l 697 -204 696 -216 694 -226 ct 692 -235 688 -243 684 -249 ct +679 -255 673 -259 665 -262 ct 657 -264 647 -266 636 -266 ct 624 -266 613 -264 604 -259 ct +595 -255 586 -249 580 -242 ct 573 -234 568 -224 564 -213 ct 561 -201 559 -188 559 -173 ct +559 0 l 509 0 l 509 -235 l 509 -241 509 -248 509 -254 ct 509 -261 509 -268 509 -274 ct +508 -280 508 -286 508 -290 ct 508 -294 508 -297 507 -298 ct 554 -298 l 554 -298 555 -295 555 -291 ct +555 -287 555 -282 556 -277 ct 556 -272 556 -267 556 -261 ct 556 -256 556 -251 556 -247 ct +557 -247 l 562 -256 567 -264 573 -271 ct 579 -278 585 -284 593 -289 ct 600 -294 609 -297 619 -300 ct +628 -303 640 -304 653 -304 ct 669 -304 683 -302 695 -298 ct 707 -294 717 -288 725 -279 ct +732 -271 738 -260 742 -246 ct 745 -233 747 -217 747 -199 ct 747 0 l 697 0 l +p ef +859 -150 m 859 -133 860 -117 862 -103 ct 865 -89 869 -76 875 -66 ct 881 -56 889 -47 898 -42 ct +908 -36 920 -33 934 -33 ct 952 -33 966 -38 978 -47 ct 990 -56 997 -71 1000 -90 ct +1050 -90 l 1048 -78 1045 -65 1039 -54 ct 1034 -42 1026 -32 1017 -23 ct 1007 -14 996 -7 982 -2 ct +969 3 953 6 935 6 ct 912 6 892 2 876 -6 ct 859 -14 846 -25 836 -39 ct 826 -53 818 -69 814 -88 ct +809 -107 807 -127 807 -149 ct 807 -169 809 -187 812 -202 ct 815 -218 820 -231 826 -243 ct +832 -254 839 -264 847 -272 ct 855 -280 864 -286 873 -291 ct 883 -295 893 -299 903 -301 ct +914 -303 924 -304 935 -304 ct 951 -304 966 -302 979 -297 ct 992 -292 1004 -286 1013 -278 ct +1023 -270 1030 -261 1036 -250 ct 1042 -239 1046 -227 1048 -215 ct 998 -211 l +995 -227 988 -241 978 -250 ct 968 -260 953 -265 933 -265 ct 919 -265 907 -263 898 -258 ct +889 -253 881 -246 875 -237 ct 869 -227 865 -215 862 -201 ct 860 -187 859 -170 859 -150 ct +p ef +1220 -3 m 1212 -1 1204 1 1197 2 ct 1189 3 1180 4 1169 4 ct 1130 4 1110 -19 1110 -64 ct +1110 -263 l 1076 -263 l 1076 -299 l 1112 -299 l 1126 -366 l 1160 -366 l +1160 -299 l 1215 -299 l 1215 -263 l 1160 -263 l 1160 -74 l 1160 -60 1162 -50 1167 -44 ct +1171 -38 1179 -35 1191 -35 ct 1196 -35 1200 -36 1205 -37 ct 1209 -37 1214 -38 1220 -39 ct +1220 -3 l p ef +1261 -362 m 1261 -409 l 1310 -409 l 1310 -362 l 1261 -362 l p +1261 0 m 1261 -298 l 1310 -298 l 1310 0 l 1261 0 l p ef +1640 -149 m 1640 -97 1629 -58 1606 -32 ct 1583 -7 1549 6 1506 6 ct 1485 6 1466 3 1450 -3 ct +1434 -10 1420 -19 1409 -32 ct 1397 -45 1389 -61 1383 -81 ct 1377 -100 1374 -123 1374 -149 ct +1374 -252 1418 -304 1507 -304 ct 1530 -304 1550 -300 1567 -294 ct 1584 -288 1598 -278 1608 -265 ct +1619 -252 1627 -236 1632 -217 ct 1637 -197 1640 -175 1640 -149 ct p +1588 -149 m 1588 -172 1586 -191 1583 -207 ct 1579 -222 1574 -234 1567 -243 ct +1560 -252 1552 -258 1542 -262 ct 1532 -265 1521 -267 1508 -267 ct 1495 -267 1484 -265 1474 -261 ct +1464 -258 1455 -251 1448 -242 ct 1441 -233 1435 -221 1431 -206 ct 1428 -191 1426 -172 1426 -149 ct +1426 -126 1428 -107 1432 -92 ct 1436 -76 1441 -64 1448 -55 ct 1456 -46 1464 -40 1474 -36 ct +1483 -33 1494 -31 1505 -31 ct 1518 -31 1529 -32 1539 -36 ct 1550 -40 1558 -46 1566 -55 ct +1573 -64 1578 -76 1582 -91 ct 1586 -107 1588 -126 1588 -149 ct p ef +1891 0 m 1891 -189 l 1891 -204 1890 -216 1888 -226 ct 1886 -235 1882 -243 1878 -249 ct +1873 -255 1867 -259 1859 -262 ct 1851 -264 1841 -266 1830 -266 ct 1818 -266 1807 -264 1798 -259 ct +1789 -255 1780 -249 1774 -242 ct 1767 -234 1762 -224 1758 -213 ct 1755 -201 1753 -188 1753 -173 ct +1753 0 l 1703 0 l 1703 -235 l 1703 -241 1703 -248 1703 -254 ct 1703 -261 1703 -268 1703 -274 ct +1702 -280 1702 -286 1702 -290 ct 1702 -294 1702 -297 1701 -298 ct 1748 -298 l +1748 -298 1749 -295 1749 -291 ct 1749 -287 1749 -282 1750 -277 ct 1750 -272 1750 -267 1750 -261 ct +1750 -256 1750 -251 1750 -247 ct 1751 -247 l 1756 -256 1761 -264 1767 -271 ct +1773 -278 1779 -284 1787 -289 ct 1794 -294 1803 -297 1813 -300 ct 1822 -303 1834 -304 1847 -304 ct +1863 -304 1877 -302 1889 -298 ct 1901 -294 1911 -288 1919 -279 ct 1926 -271 1932 -260 1936 -246 ct +1939 -233 1941 -217 1941 -199 ct 1941 0 l 1891 0 l p ef +pom +pum +9023 5641 t +112 -263 m 112 -303 l 112 -313 113 -322 113 -329 ct 114 -337 116 -345 117 -352 ct +119 -359 121 -365 124 -371 ct 127 -377 130 -383 134 -389 ct 167 -389 l 159 -377 153 -365 148 -353 ct +144 -341 141 -329 141 -317 ct 166 -317 l 166 -263 l 112 -263 l p +21 -263 m 21 -303 l 21 -313 21 -322 22 -329 ct 23 -337 24 -345 26 -352 ct +28 -359 30 -365 33 -371 ct 36 -377 39 -383 43 -389 ct 76 -389 l 68 -377 61 -365 57 -353 ct +52 -341 50 -329 50 -317 ct 74 -317 l 74 -263 l 21 -263 l p ef +412 -48 m 403 -28 391 -15 376 -6 ct 360 2 342 6 319 6 ct 282 6 254 -7 236 -32 ct +219 -57 210 -96 210 -147 ct 210 -252 246 -304 319 -304 ct 342 -304 361 -300 376 -291 ct +391 -283 403 -270 412 -252 ct 413 -252 l 413 -254 413 -257 413 -260 ct 412 -264 412 -269 412 -273 ct +412 -277 412 -281 412 -285 ct 412 -289 412 -292 412 -293 ct 412 -409 l 462 -409 l +462 -61 l 462 -54 462 -47 462 -40 ct 462 -34 462 -28 462 -22 ct 462 -17 463 -12 463 -8 ct +463 -4 463 -1 463 0 ct 416 0 l 416 -1 415 -4 415 -7 ct 415 -11 414 -15 414 -19 ct +414 -24 414 -28 413 -33 ct 413 -38 413 -43 413 -48 ct 412 -48 l p +262 -149 m 262 -129 263 -111 266 -96 ct 268 -81 272 -69 278 -60 ct 284 -50 291 -43 300 -39 ct +309 -35 319 -32 332 -32 ct 345 -32 357 -34 367 -39 ct 377 -43 385 -50 392 -59 ct +398 -69 403 -81 407 -96 ct 410 -112 412 -130 412 -152 ct 412 -174 410 -191 407 -206 ct +403 -221 398 -233 391 -242 ct 385 -251 376 -257 367 -261 ct 357 -265 345 -267 333 -267 ct +320 -267 310 -265 301 -261 ct 292 -256 285 -250 279 -240 ct 273 -231 269 -219 266 -204 ct +263 -189 262 -170 262 -149 ct p ef +539 0 m 539 -229 l 539 -235 539 -242 539 -248 ct 539 -255 539 -261 539 -267 ct +538 -273 538 -279 538 -284 ct 538 -289 538 -294 537 -298 ct 584 -298 l 584 -294 585 -289 585 -284 ct +585 -279 586 -273 586 -267 ct 586 -262 586 -256 586 -251 ct 586 -246 586 -241 586 -238 ct +588 -238 l 591 -249 595 -259 599 -267 ct 603 -276 607 -282 613 -288 ct 618 -293 624 -297 632 -300 ct +639 -303 648 -304 658 -304 ct 662 -304 666 -304 670 -303 ct 674 -302 676 -302 678 -301 ct +678 -256 l 675 -257 671 -257 667 -258 ct 662 -258 658 -258 652 -258 ct 641 -258 631 -256 623 -251 ct +615 -246 608 -238 603 -229 ct 598 -220 595 -209 592 -197 ct 590 -184 589 -170 589 -156 ct +589 0 l 539 0 l p ef +800 6 m 770 6 748 -2 733 -18 ct 717 -34 710 -56 710 -83 ct 710 -103 714 -119 721 -132 ct +729 -145 738 -154 750 -162 ct 762 -169 776 -174 791 -177 ct 807 -179 823 -181 839 -181 ct +905 -181 l 905 -197 l 905 -210 904 -220 902 -229 ct 899 -238 895 -245 890 -250 ct +884 -256 878 -260 870 -262 ct 862 -265 852 -266 842 -266 ct 832 -266 823 -265 816 -264 ct +808 -263 801 -260 796 -256 ct 790 -253 785 -248 782 -242 ct 778 -236 776 -228 775 -218 ct +723 -223 l 725 -235 729 -246 734 -256 ct 739 -265 746 -274 756 -281 ct 765 -288 777 -294 791 -298 ct +805 -302 823 -304 843 -304 ct 880 -304 908 -295 927 -278 ct 946 -261 956 -236 956 -203 ct +956 -74 l 956 -60 958 -49 961 -41 ct 965 -34 973 -30 983 -30 ct 986 -30 989 -30 992 -31 ct +994 -31 997 -31 1000 -32 ct 1000 -1 l 993 0 987 2 981 2 ct 975 3 968 3 961 3 ct +952 3 944 2 937 0 ct 931 -3 925 -7 921 -12 ct 917 -17 913 -23 911 -30 ct 909 -38 908 -47 907 -57 ct +905 -57 l 900 -47 894 -38 888 -31 ct 882 -23 874 -16 866 -11 ct 857 -6 848 -1 837 2 ct +826 5 814 6 800 6 ct p +811 -31 m 827 -31 841 -34 853 -40 ct 865 -46 874 -53 882 -62 ct 890 -71 896 -81 900 -91 ct +904 -102 905 -112 905 -122 ct 905 -146 l 851 -146 l 839 -146 828 -145 817 -144 ct +806 -142 796 -139 788 -134 ct 780 -130 773 -123 768 -115 ct 763 -107 761 -96 761 -82 ct +761 -66 765 -53 774 -45 ct 783 -36 795 -31 811 -31 ct p ef +1322 0 m 1265 0 l 1217 -193 l 1216 -198 1214 -204 1213 -211 ct 1211 -218 1209 -226 1208 -233 ct +1206 -241 1204 -249 1203 -258 ct 1201 -249 1199 -241 1198 -233 ct 1196 -226 1194 -219 1193 -211 ct +1191 -204 1189 -197 1188 -191 ct 1139 0 l 1082 0 l 998 -299 l 1047 -299 l +1098 -96 l 1099 -91 1100 -86 1101 -80 ct 1103 -74 1104 -68 1105 -62 ct 1107 -55 1108 -48 1109 -41 ct +1111 -48 1112 -55 1114 -62 ct 1116 -67 1117 -73 1119 -79 ct 1120 -85 1121 -90 1122 -94 ct +1176 -299 l 1230 -299 l 1282 -94 l 1283 -89 1284 -83 1286 -77 ct 1287 -71 1289 -65 1290 -60 ct +1291 -54 1293 -48 1294 -41 ct 1296 -48 1297 -55 1299 -62 ct 1300 -67 1301 -73 1303 -79 ct +1304 -85 1305 -91 1307 -96 ct 1359 -299 l 1408 -299 l 1322 0 l p ef +1568 -349 m 1568 -339 1568 -330 1567 -322 ct 1566 -314 1565 -307 1563 -300 ct +1561 -293 1559 -287 1556 -280 ct 1553 -274 1550 -268 1546 -263 ct 1513 -263 l +1521 -274 1528 -287 1532 -299 ct 1537 -311 1539 -323 1539 -335 ct 1515 -335 l +1515 -389 l 1568 -389 l 1568 -349 l p +1477 -349 m 1477 -339 1477 -330 1476 -322 ct 1475 -314 1474 -307 1472 -300 ct +1470 -293 1468 -287 1465 -280 ct 1462 -274 1459 -268 1456 -263 ct 1422 -263 l +1430 -274 1436 -287 1441 -299 ct 1445 -311 1448 -323 1448 -335 ct 1423 -335 l +1423 -389 l 1477 -389 l 1477 -349 l p ef +pom +gs +14897 5768 m 12801 5768 l 12801 4498 l 16991 4498 l 16991 5768 l 14897 5768 l +eoclip newpath +12801 4498 m 16992 4498 l 16992 5768 l 12801 5768 l 12801 4498 l eoclip newpath +pum +12459 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +12671 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +12883 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13095 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13307 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13519 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13731 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13943 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14155 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14367 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14579 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14791 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15003 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15215 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15427 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15639 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15850 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16062 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16274 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16486 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16698 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16910 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +12671 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +12883 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13095 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13307 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13519 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13731 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13943 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14155 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14367 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14579 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14791 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15003 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15215 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15427 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15639 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15850 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16062 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16274 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16486 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16698 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16910 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +12459 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +12671 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +12883 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13095 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13307 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13519 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13731 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13943 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14155 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14367 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14579 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14791 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15003 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15215 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15427 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15639 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15850 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16062 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16274 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16486 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16698 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16910 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +12671 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +12883 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13095 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13307 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13519 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13731 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13943 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14155 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14367 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14579 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14791 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15003 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15215 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15427 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15639 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15850 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16062 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16274 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16486 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16698 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16910 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +12459 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +12671 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +12883 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13095 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13307 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13519 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13731 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13943 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14155 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14367 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14579 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14791 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15003 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15215 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15427 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15639 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15850 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16062 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16274 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16486 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16698 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16910 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +12671 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +12883 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13095 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13307 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13519 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13731 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13943 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14155 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14367 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14579 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14791 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15003 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15215 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15427 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15639 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15850 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16062 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16274 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16486 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16698 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16910 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +12459 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +12671 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +12883 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13095 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13307 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13519 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13731 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13943 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14155 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14367 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14579 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14791 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15003 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15215 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15427 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15639 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15850 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16062 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16274 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16486 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16698 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16910 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +gr +14897 5768 m 12801 5768 l 12801 4498 l 16991 4498 l 16991 5768 l 14897 5768 l +pc +pum +14368 5014 t +153 -3 m 145 -1 137 1 130 2 ct 122 3 113 4 102 4 ct 63 4 43 -19 43 -64 ct 43 -263 l +9 -263 l 9 -299 l 45 -299 l 59 -366 l 93 -366 l 93 -299 l 148 -299 l +148 -263 l 93 -263 l 93 -74 l 93 -60 95 -50 100 -44 ct 104 -38 112 -35 124 -35 ct +129 -35 133 -36 138 -37 ct 142 -37 147 -38 153 -39 ct 153 -3 l p ef +323 0 m 316 18 309 34 302 49 ct 295 63 287 75 278 85 ct 269 96 259 103 248 109 ct +237 114 224 117 210 117 ct 203 117 198 117 192 117 ct 187 117 181 116 175 115 ct +175 77 l 179 78 183 79 187 79 ct 192 79 195 79 199 79 ct 213 79 227 73 239 62 ct +252 52 262 34 272 11 ct 277 -1 l 158 -298 l 211 -298 l 274 -133 l 276 -128 278 -122 281 -113 ct +284 -105 287 -97 290 -88 ct 292 -80 295 -73 297 -66 ct 299 -60 301 -55 301 -54 ct +302 -56 303 -60 305 -66 ct 307 -72 310 -78 312 -86 ct 315 -93 318 -101 320 -108 ct +323 -116 325 -122 327 -128 ct 386 -298 l 438 -298 l 323 0 l p ef +722 -151 m 722 -128 720 -108 716 -88 ct 713 -69 707 -53 698 -39 ct 690 -25 678 -15 664 -7 ct +650 1 633 5 612 5 ct 591 5 572 1 556 -7 ct 541 -15 528 -28 520 -47 ct 518 -47 l +519 -46 519 -45 519 -42 ct 519 -39 519 -35 519 -31 ct 519 -26 519 -21 519 -16 ct +520 -11 520 -5 520 0 ct 520 117 l 470 117 l 470 -238 l 470 -245 470 -252 470 -258 ct +470 -265 470 -271 469 -277 ct 469 -282 469 -287 469 -290 ct 469 -294 469 -297 468 -299 ct +516 -299 l 516 -298 517 -296 517 -293 ct 517 -290 518 -286 518 -281 ct 518 -276 518 -271 519 -266 ct +519 -261 519 -256 519 -251 ct 520 -251 l 525 -260 530 -268 536 -275 ct 542 -282 548 -287 556 -292 ct +563 -296 572 -299 581 -301 ct 590 -303 601 -304 612 -304 ct 633 -304 650 -300 664 -293 ct +678 -286 690 -275 698 -262 ct 707 -249 713 -233 716 -214 ct 720 -195 722 -174 722 -151 ct +p +670 -150 m 670 -168 669 -185 667 -199 ct 664 -213 661 -225 655 -235 ct 650 -245 643 -253 634 -258 ct +625 -263 613 -266 600 -266 ct 589 -266 578 -264 569 -261 ct 559 -258 550 -252 543 -243 ct +536 -234 530 -222 526 -207 ct 522 -191 520 -171 520 -146 ct 520 -125 521 -107 525 -92 ct +528 -78 533 -66 540 -57 ct 547 -48 555 -42 565 -38 ct 575 -34 586 -32 599 -32 ct +613 -32 624 -34 633 -40 ct 643 -45 650 -53 655 -63 ct 661 -73 664 -85 667 -100 ct +669 -115 670 -131 670 -150 ct p ef +821 -138 m 821 -122 823 -108 826 -95 ct 829 -82 834 -71 841 -61 ct 847 -52 856 -44 866 -39 ct +877 -34 889 -31 904 -31 ct 926 -31 943 -36 956 -44 ct 969 -53 978 -64 982 -77 ct +1026 -65 l 1023 -56 1018 -48 1013 -40 ct 1007 -31 999 -24 990 -17 ct 981 -10 969 -5 955 0 ct +941 4 924 6 904 6 ct 860 6 827 -7 804 -33 ct 780 -60 769 -99 769 -151 ct 769 -179 772 -202 779 -222 ct +786 -241 796 -257 808 -269 ct 820 -281 834 -290 850 -296 ct 867 -301 884 -304 902 -304 ct +927 -304 948 -300 965 -292 ct 982 -283 995 -272 1005 -258 ct 1016 -244 1023 -227 1027 -207 ct +1031 -188 1034 -167 1034 -145 ct 1034 -138 l 821 -138 l p +982 -176 m 980 -208 972 -231 958 -245 ct 945 -260 926 -267 901 -267 ct 893 -267 884 -266 875 -263 ct +866 -260 858 -256 850 -249 ct 843 -242 836 -233 831 -221 ct 825 -209 822 -194 822 -176 ct +982 -176 l p ef +pom +pum +13161 5641 t +112 -263 m 112 -303 l 112 -313 113 -322 113 -329 ct 114 -337 116 -345 117 -352 ct +119 -359 121 -365 124 -371 ct 127 -377 130 -383 134 -389 ct 167 -389 l 159 -377 153 -365 148 -353 ct +144 -341 141 -329 141 -317 ct 166 -317 l 166 -263 l 112 -263 l p +21 -263 m 21 -303 l 21 -313 21 -322 22 -329 ct 23 -337 24 -345 26 -352 ct +28 -359 30 -365 33 -371 ct 36 -377 39 -383 43 -389 ct 76 -389 l 68 -377 61 -365 57 -353 ct +52 -341 50 -329 50 -317 ct 74 -317 l 74 -263 l 21 -263 l p ef +532 -271 m 532 -254 530 -239 524 -224 ct 518 -209 510 -197 499 -186 ct 488 -175 474 -167 457 -160 ct +441 -154 421 -151 399 -151 ct 285 -151 l 285 1 l 232 1 l 232 -388 l 396 -388 l +419 -388 439 -385 456 -380 ct 473 -374 487 -366 498 -356 ct 510 -346 518 -334 524 -319 ct +530 -305 532 -289 532 -271 ct p +480 -271 m 480 -295 472 -314 457 -327 ct 442 -340 419 -346 389 -346 ct 285 -346 l +285 -193 l 391 -193 l 422 -193 444 -199 458 -213 ct 472 -226 480 -246 480 -271 ct +p ef +884 1 m 783 -161 l 662 -161 l 662 1 l 609 1 l 609 -388 l 792 -388 l +814 -388 833 -386 850 -381 ct 867 -376 882 -368 893 -359 ct 905 -349 914 -337 920 -324 ct +926 -310 929 -294 929 -277 ct 929 -265 927 -253 923 -241 ct 920 -229 914 -218 906 -208 ct +899 -198 889 -189 877 -182 ct 865 -175 851 -170 834 -167 ct 944 1 l 884 1 l +p +876 -277 m 876 -288 874 -298 870 -307 ct 866 -316 860 -323 852 -329 ct 844 -335 835 -339 824 -342 ct +813 -345 801 -346 787 -346 ct 662 -346 l 662 -203 l 789 -203 l 804 -203 817 -205 828 -208 ct +839 -212 848 -217 855 -224 ct 862 -230 867 -238 871 -247 ct 874 -256 876 -266 876 -277 ct +p ef +1015 0 m 1015 -389 l 1310 -389 l 1310 -346 l 1068 -346 l 1068 -221 l +1293 -221 l 1293 -179 l 1068 -179 l 1068 -43 l 1321 -43 l 1321 0 l +1015 0 l p ef +1564 -351 m 1542 -351 1523 -347 1506 -340 ct 1489 -333 1474 -322 1463 -308 ct +1451 -295 1443 -279 1437 -259 ct 1431 -240 1428 -219 1428 -196 ct 1428 -172 1431 -151 1438 -132 ct +1444 -112 1453 -95 1465 -81 ct 1477 -67 1491 -57 1508 -49 ct 1526 -41 1545 -37 1566 -37 ct +1581 -37 1595 -39 1607 -43 ct 1620 -47 1631 -53 1641 -60 ct 1651 -67 1660 -76 1668 -85 ct +1676 -95 1683 -106 1689 -118 ct 1732 -97 l 1725 -82 1716 -69 1706 -56 ct 1696 -44 1684 -33 1670 -24 ct +1656 -14 1640 -7 1623 -2 ct 1605 3 1586 6 1564 6 ct 1532 6 1505 1 1481 -9 ct 1458 -19 1438 -33 1422 -51 ct +1406 -69 1394 -90 1386 -115 ct 1379 -139 1375 -166 1375 -196 ct 1375 -226 1379 -253 1387 -278 ct +1396 -302 1408 -323 1424 -340 ct 1440 -358 1460 -371 1483 -380 ct 1507 -389 1533 -394 1564 -394 ct +1605 -394 1639 -386 1667 -370 ct 1695 -354 1715 -330 1728 -298 ct 1678 -281 l +1675 -290 1670 -299 1664 -308 ct 1657 -316 1649 -323 1640 -330 ct 1631 -336 1620 -341 1607 -345 ct +1595 -349 1580 -351 1564 -351 ct p ef +1805 0 m 1805 -389 l 1858 -389 l 1858 0 l 1805 0 l p ef +2259 -107 m 2259 -90 2256 -75 2250 -62 ct 2243 -48 2234 -36 2220 -26 ct 2207 -16 2191 -8 2170 -2 ct +2150 3 2127 6 2099 6 ct 2051 6 2013 -2 1986 -19 ct 1959 -36 1942 -61 1935 -93 ct +1986 -103 l 1988 -93 1992 -84 1997 -75 ct 2003 -67 2010 -60 2019 -54 ct 2028 -48 2039 -43 2053 -40 ct +2066 -37 2082 -35 2101 -35 ct 2117 -35 2131 -36 2144 -39 ct 2157 -42 2168 -46 2178 -51 ct +2187 -57 2194 -64 2199 -73 ct 2205 -81 2207 -92 2207 -104 ct 2207 -117 2204 -127 2199 -135 ct +2193 -143 2185 -149 2174 -155 ct 2164 -160 2151 -164 2137 -168 ct 2122 -171 2106 -175 2089 -179 ct +2078 -181 2067 -184 2056 -187 ct 2045 -190 2035 -193 2025 -197 ct 2015 -201 2005 -206 1996 -211 ct +1987 -216 1980 -223 1973 -230 ct 1967 -237 1962 -246 1958 -256 ct 1955 -266 1953 -277 1953 -290 ct +1953 -308 1957 -324 1964 -337 ct 1971 -350 1982 -361 1995 -370 ct 2008 -378 2024 -384 2042 -388 ct +2060 -392 2079 -394 2100 -394 ct 2124 -394 2145 -392 2162 -388 ct 2179 -385 2193 -379 2205 -371 ct +2217 -364 2226 -355 2233 -343 ct 2240 -332 2246 -319 2250 -305 ct 2198 -296 l +2196 -305 2192 -313 2187 -321 ct 2182 -328 2176 -334 2168 -339 ct 2160 -344 2151 -348 2139 -350 ct +2128 -353 2115 -354 2100 -354 ct 2082 -354 2066 -353 2054 -349 ct 2042 -346 2032 -342 2025 -336 ct +2017 -331 2012 -324 2009 -317 ct 2006 -309 2004 -301 2004 -293 ct 2004 -281 2007 -272 2013 -264 ct +2018 -257 2026 -251 2036 -246 ct 2046 -241 2058 -236 2071 -233 ct 2084 -230 2098 -227 2112 -223 ct +2124 -220 2136 -218 2148 -215 ct 2160 -212 2171 -209 2182 -205 ct 2193 -201 2203 -196 2212 -191 ct +2222 -185 2230 -179 2237 -171 ct 2244 -163 2249 -154 2253 -144 ct 2257 -133 2259 -121 2259 -107 ct +p ef +2338 0 m 2338 -389 l 2391 -389 l 2391 0 l 2338 0 l p ef +2855 -196 m 2855 -165 2850 -138 2842 -113 ct 2833 -88 2820 -67 2804 -49 ct +2787 -32 2767 -18 2743 -8 ct 2719 1 2692 6 2662 6 ct 2630 6 2602 1 2578 -9 ct 2554 -19 2534 -33 2518 -51 ct +2502 -69 2490 -90 2482 -115 ct 2474 -139 2470 -166 2470 -196 ct 2470 -226 2474 -253 2482 -278 ct +2491 -302 2503 -323 2520 -340 ct 2536 -358 2556 -371 2580 -380 ct 2604 -389 2631 -394 2662 -394 ct +2693 -394 2721 -389 2745 -380 ct 2769 -371 2789 -357 2805 -340 ct 2821 -323 2834 -302 2842 -277 ct +2850 -253 2855 -226 2855 -196 ct p +2801 -196 m 2801 -219 2798 -240 2792 -259 ct 2786 -279 2777 -295 2766 -308 ct +2754 -322 2740 -333 2722 -340 ct 2705 -347 2685 -351 2662 -351 ct 2639 -351 2619 -347 2602 -340 ct +2584 -333 2570 -322 2558 -308 ct 2546 -295 2538 -279 2532 -259 ct 2526 -240 2523 -219 2523 -196 ct +2523 -172 2526 -151 2532 -132 ct 2538 -112 2547 -95 2559 -81 ct 2570 -67 2585 -56 2602 -48 ct +2619 -41 2639 -37 2662 -37 ct 2686 -37 2707 -41 2725 -49 ct 2742 -57 2757 -68 2768 -82 ct +2779 -96 2787 -112 2793 -132 ct 2798 -151 2801 -173 2801 -196 ct p ef +3177 0 m 2969 -331 l 2970 -322 2970 -313 2971 -304 ct 2971 -297 2971 -289 2972 -280 ct +2972 -272 2972 -265 2972 -258 ct 2972 0 l 2925 0 l 2925 -389 l 2986 -389 l +3196 -55 l 3196 -64 3195 -73 3195 -82 ct 3194 -90 3194 -99 3194 -108 ct 3193 -117 3193 -126 3193 -134 ct +3193 -389 l 3240 -389 l 3240 0 l 3177 0 l p ef +3452 -349 m 3452 -339 3452 -330 3451 -322 ct 3450 -314 3449 -307 3447 -300 ct +3445 -293 3443 -287 3440 -280 ct 3437 -274 3434 -268 3430 -263 ct 3397 -263 l +3405 -274 3412 -287 3416 -299 ct 3421 -311 3423 -323 3423 -335 ct 3399 -335 l +3399 -389 l 3452 -389 l 3452 -349 l p +3361 -349 m 3361 -339 3361 -330 3360 -322 ct 3359 -314 3358 -307 3356 -300 ct +3354 -293 3352 -287 3349 -280 ct 3346 -274 3343 -268 3340 -263 ct 3306 -263 l +3314 -274 3320 -287 3325 -299 ct 3329 -311 3332 -323 3332 -335 ct 3307 -335 l +3307 -389 l 3361 -389 l 3361 -349 l p ef +pom +gs +19722 5768 m 17626 5768 l 17626 4498 l 21817 4498 l 21817 5768 l 19722 5768 l +eoclip newpath +17627 4498 m 21818 4498 l 21818 5768 l 17627 5768 l 17627 4498 l eoclip newpath +pum +17285 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17497 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17709 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17921 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18133 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18345 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18557 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18769 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18981 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19193 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19405 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19617 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19829 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20041 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20253 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20465 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20677 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20889 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21100 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21312 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21524 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21736 4603 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17497 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17709 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17921 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18133 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18345 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18557 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18769 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18981 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19193 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19405 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19617 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19829 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20041 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20253 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20465 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20677 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20889 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21100 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21312 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21524 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21736 4815 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17285 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17497 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17709 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17921 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18133 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18345 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18557 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18769 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18981 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19193 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19405 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19617 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19829 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20041 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20253 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20465 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20677 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20889 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21100 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21312 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21524 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21736 5027 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17497 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17709 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17921 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18133 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18345 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18557 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18769 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18981 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19193 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19405 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19617 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19829 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20041 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20253 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20465 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20677 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20889 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21100 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21312 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21524 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21736 5239 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17285 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17497 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17709 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17921 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18133 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18345 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18557 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18769 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18981 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19193 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19405 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19617 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19829 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20041 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20253 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20465 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20677 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20889 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21100 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21312 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21524 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21736 5451 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17497 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17709 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17921 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18133 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18345 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18557 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18769 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18981 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19193 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19405 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19617 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19829 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20041 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20253 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20465 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20677 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20889 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21100 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21312 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21524 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21736 5663 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17285 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17497 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17709 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17921 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18133 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18345 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18557 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18769 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18981 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19193 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19405 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19617 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19829 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20041 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20253 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20465 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20677 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20889 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21100 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21312 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21524 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21736 5875 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +gr +19722 5768 m 17626 5768 l 17626 4498 l 21817 4498 l 21817 5768 l 19722 5768 l +pc +pum +19077 5014 t +76 -150 m 76 -133 77 -117 79 -103 ct 82 -89 86 -76 92 -66 ct 98 -56 106 -47 115 -42 ct +125 -36 137 -33 151 -33 ct 169 -33 183 -38 195 -47 ct 207 -56 214 -71 217 -90 ct +267 -90 l 265 -78 262 -65 256 -54 ct 251 -42 243 -32 234 -23 ct 224 -14 213 -7 199 -2 ct +186 3 170 6 152 6 ct 129 6 109 2 93 -6 ct 76 -14 63 -25 53 -39 ct 43 -53 35 -69 31 -88 ct +26 -107 24 -127 24 -149 ct 24 -169 26 -187 29 -202 ct 32 -218 37 -231 43 -243 ct +49 -254 56 -264 64 -272 ct 72 -280 81 -286 90 -291 ct 100 -295 110 -299 120 -301 ct +131 -303 141 -304 152 -304 ct 168 -304 183 -302 196 -297 ct 209 -292 221 -286 230 -278 ct +240 -270 247 -261 253 -250 ct 259 -239 263 -227 265 -215 ct 215 -211 l 212 -227 205 -241 195 -250 ct +185 -260 170 -265 150 -265 ct 136 -265 124 -263 115 -258 ct 106 -253 98 -246 92 -237 ct +86 -227 82 -215 79 -201 ct 77 -187 76 -170 76 -150 ct p ef +322 0 m 322 -409 l 372 -409 l 372 0 l 322 0 l p ef +525 6 m 495 6 473 -2 458 -18 ct 442 -34 435 -56 435 -83 ct 435 -103 439 -119 446 -132 ct +454 -145 463 -154 475 -162 ct 487 -169 501 -174 516 -177 ct 532 -179 548 -181 564 -181 ct +630 -181 l 630 -197 l 630 -210 629 -220 627 -229 ct 624 -238 620 -245 615 -250 ct +609 -256 603 -260 595 -262 ct 587 -265 577 -266 567 -266 ct 557 -266 548 -265 541 -264 ct +533 -263 526 -260 521 -256 ct 515 -253 510 -248 507 -242 ct 503 -236 501 -228 500 -218 ct +448 -223 l 450 -235 454 -246 459 -256 ct 464 -265 471 -274 481 -281 ct 490 -288 502 -294 516 -298 ct +530 -302 548 -304 568 -304 ct 605 -304 633 -295 652 -278 ct 671 -261 681 -236 681 -203 ct +681 -74 l 681 -60 683 -49 686 -41 ct 690 -34 698 -30 708 -30 ct 711 -30 714 -30 717 -31 ct +719 -31 722 -31 725 -32 ct 725 -1 l 718 0 712 2 706 2 ct 700 3 693 3 686 3 ct +677 3 669 2 662 0 ct 656 -3 650 -7 646 -12 ct 642 -17 638 -23 636 -30 ct 634 -38 633 -47 632 -57 ct +630 -57 l 625 -47 619 -38 613 -31 ct 607 -23 599 -16 591 -11 ct 582 -6 573 -1 562 2 ct +551 5 539 6 525 6 ct p +536 -31 m 552 -31 566 -34 578 -40 ct 590 -46 599 -53 607 -62 ct 615 -71 621 -81 625 -91 ct +629 -102 630 -112 630 -122 ct 630 -146 l 576 -146 l 564 -146 553 -145 542 -144 ct +531 -142 521 -139 513 -134 ct 505 -130 498 -123 493 -115 ct 488 -107 486 -96 486 -82 ct +486 -66 490 -53 499 -45 ct 508 -36 520 -31 536 -31 ct p ef +986 -82 m 986 -68 983 -56 978 -45 ct 972 -34 964 -24 954 -17 ct 944 -10 931 -4 916 0 ct +901 4 884 6 865 6 ct 847 6 832 5 818 2 ct 804 -1 792 -5 782 -11 ct 771 -17 762 -24 755 -34 ct +748 -44 743 -56 740 -70 ct 783 -78 l 788 -62 796 -50 810 -43 ct 823 -36 841 -32 865 -32 ct +875 -32 885 -33 894 -34 ct 903 -35 911 -38 917 -42 ct 923 -45 928 -50 932 -56 ct +936 -62 937 -69 937 -78 ct 937 -87 935 -95 931 -100 ct 927 -106 921 -111 913 -115 ct +906 -119 897 -122 886 -125 ct 875 -128 864 -131 851 -134 ct 839 -137 827 -141 815 -145 ct +803 -149 793 -154 783 -160 ct 774 -166 766 -174 760 -184 ct 754 -193 752 -205 752 -219 ct +752 -246 761 -267 781 -281 ct 800 -295 828 -303 865 -303 ct 898 -303 924 -297 944 -285 ct +963 -274 975 -255 980 -229 ct 936 -224 l 934 -232 931 -238 927 -243 ct 922 -249 917 -253 911 -256 ct +904 -259 897 -262 890 -263 ct 882 -264 874 -265 865 -265 ct 843 -265 826 -262 816 -255 ct +805 -248 800 -238 800 -224 ct 800 -216 802 -209 806 -204 ct 810 -199 815 -194 822 -191 ct +829 -187 838 -184 848 -181 ct 858 -179 868 -176 880 -173 ct 888 -171 896 -169 905 -166 ct +913 -164 921 -161 929 -158 ct 937 -155 944 -151 951 -147 ct 958 -143 964 -137 969 -131 ct +974 -125 978 -118 981 -110 ct 984 -102 986 -93 986 -82 ct p ef +1270 -82 m 1270 -68 1267 -56 1262 -45 ct 1256 -34 1248 -24 1238 -17 ct 1228 -10 1215 -4 1200 0 ct +1185 4 1168 6 1149 6 ct 1131 6 1116 5 1102 2 ct 1088 -1 1076 -5 1066 -11 ct 1055 -17 1046 -24 1039 -34 ct +1032 -44 1027 -56 1024 -70 ct 1067 -78 l 1072 -62 1080 -50 1094 -43 ct 1107 -36 1125 -32 1149 -32 ct +1159 -32 1169 -33 1178 -34 ct 1187 -35 1195 -38 1201 -42 ct 1207 -45 1212 -50 1216 -56 ct +1220 -62 1221 -69 1221 -78 ct 1221 -87 1219 -95 1215 -100 ct 1211 -106 1205 -111 1197 -115 ct +1190 -119 1181 -122 1170 -125 ct 1159 -128 1148 -131 1135 -134 ct 1123 -137 1111 -141 1099 -145 ct +1087 -149 1077 -154 1067 -160 ct 1058 -166 1050 -174 1044 -184 ct 1038 -193 1036 -205 1036 -219 ct +1036 -246 1045 -267 1065 -281 ct 1084 -295 1112 -303 1149 -303 ct 1182 -303 1208 -297 1228 -285 ct +1247 -274 1259 -255 1264 -229 ct 1220 -224 l 1218 -232 1215 -238 1211 -243 ct +1206 -249 1201 -253 1195 -256 ct 1188 -259 1181 -262 1174 -263 ct 1166 -264 1158 -265 1149 -265 ct +1127 -265 1110 -262 1100 -255 ct 1089 -248 1084 -238 1084 -224 ct 1084 -216 1086 -209 1090 -204 ct +1094 -199 1099 -194 1106 -191 ct 1113 -187 1122 -184 1132 -181 ct 1142 -179 1152 -176 1164 -173 ct +1172 -171 1180 -169 1189 -166 ct 1197 -164 1205 -161 1213 -158 ct 1221 -155 1228 -151 1235 -147 ct +1242 -143 1248 -137 1253 -131 ct 1258 -125 1262 -118 1265 -110 ct 1268 -102 1270 -93 1270 -82 ct +p ef +pom +pum +18489 5641 t +112 -263 m 112 -303 l 112 -313 113 -322 113 -329 ct 114 -337 116 -345 117 -352 ct +119 -359 121 -365 124 -371 ct 127 -377 130 -383 134 -389 ct 167 -389 l 159 -377 153 -365 148 -353 ct +144 -341 141 -329 141 -317 ct 166 -317 l 166 -263 l 112 -263 l p +21 -263 m 21 -303 l 21 -313 21 -322 22 -329 ct 23 -337 24 -345 26 -352 ct +28 -359 30 -365 33 -371 ct 36 -377 39 -383 43 -389 ct 76 -389 l 68 -377 61 -365 57 -353 ct +52 -341 50 -329 50 -317 ct 74 -317 l 74 -263 l 21 -263 l p ef +pom +pum +18675 5641 t +350 -107 m 350 -90 347 -75 341 -62 ct 334 -48 325 -36 311 -26 ct 298 -16 282 -8 261 -2 ct +241 3 218 6 190 6 ct 142 6 104 -2 77 -19 ct 50 -36 33 -61 26 -93 ct 77 -103 l 79 -93 83 -84 88 -75 ct +94 -67 101 -60 110 -54 ct 119 -48 130 -43 144 -40 ct 157 -37 173 -35 192 -35 ct +208 -35 222 -36 235 -39 ct 248 -42 259 -46 269 -51 ct 278 -57 285 -64 290 -73 ct +296 -81 298 -92 298 -104 ct 298 -117 295 -127 290 -135 ct 284 -143 276 -149 265 -155 ct +255 -160 242 -164 228 -168 ct 213 -171 197 -175 180 -179 ct 169 -181 158 -184 147 -187 ct +136 -190 126 -193 116 -197 ct 106 -201 96 -206 87 -211 ct 78 -216 71 -223 64 -230 ct +58 -237 53 -246 49 -256 ct 46 -266 44 -277 44 -290 ct 44 -308 48 -324 55 -337 ct +62 -350 73 -361 86 -370 ct 99 -378 115 -384 133 -388 ct 151 -392 170 -394 191 -394 ct +215 -394 236 -392 253 -388 ct 270 -385 284 -379 296 -371 ct 308 -364 317 -355 324 -343 ct +331 -332 337 -319 341 -305 ct 289 -296 l 287 -305 283 -313 278 -321 ct 273 -328 267 -334 259 -339 ct +251 -344 242 -348 230 -350 ct 219 -353 206 -354 191 -354 ct 173 -354 157 -353 145 -349 ct +133 -346 123 -342 116 -336 ct 108 -331 103 -324 100 -317 ct 97 -309 95 -301 95 -293 ct +95 -281 98 -272 104 -264 ct 109 -257 117 -251 127 -246 ct 137 -241 149 -236 162 -233 ct +175 -230 189 -227 203 -223 ct 215 -220 227 -218 239 -215 ct 251 -212 262 -209 273 -205 ct +284 -201 294 -196 303 -191 ct 313 -185 321 -179 328 -171 ct 335 -163 340 -154 344 -144 ct +348 -133 350 -121 350 -107 ct p ef +pom +pum +19052 5641 t +-7 98 m -7 67 l 280 67 l 280 98 l -7 98 l p ef +pom +pum +19327 5641 t +218 -351 m 196 -351 177 -347 160 -340 ct 143 -333 128 -322 117 -308 ct 105 -295 97 -279 91 -259 ct +85 -240 82 -219 82 -196 ct 82 -172 85 -151 92 -132 ct 98 -112 107 -95 119 -81 ct +131 -67 145 -57 162 -49 ct 180 -41 199 -37 220 -37 ct 235 -37 249 -39 261 -43 ct +274 -47 285 -53 295 -60 ct 305 -67 314 -76 322 -85 ct 330 -95 337 -106 343 -118 ct +386 -97 l 379 -82 370 -69 360 -56 ct 350 -44 338 -33 324 -24 ct 310 -14 294 -7 277 -2 ct +259 3 240 6 218 6 ct 186 6 159 1 135 -9 ct 112 -19 92 -33 76 -51 ct 60 -69 48 -90 40 -115 ct +33 -139 29 -166 29 -196 ct 29 -226 33 -253 41 -278 ct 50 -302 62 -323 78 -340 ct +94 -358 114 -371 137 -380 ct 161 -389 187 -394 218 -394 ct 259 -394 293 -386 321 -370 ct +349 -354 369 -330 382 -298 ct 332 -281 l 329 -290 324 -299 318 -308 ct 311 -316 303 -323 294 -330 ct +285 -336 274 -341 261 -345 ct 249 -349 234 -351 218 -351 ct p ef +444 -362 m 444 -409 l 493 -409 l 493 -362 l 444 -362 l p +444 0 m 444 -298 l 493 -298 l 493 0 l 444 0 l p ef +572 0 m 572 -229 l 572 -235 572 -242 572 -248 ct 572 -255 572 -261 572 -267 ct +571 -273 571 -279 571 -284 ct 571 -289 571 -294 570 -298 ct 617 -298 l 617 -294 618 -289 618 -284 ct +618 -279 619 -273 619 -267 ct 619 -262 619 -256 619 -251 ct 619 -246 619 -241 619 -238 ct +621 -238 l 624 -249 628 -259 632 -267 ct 636 -276 640 -282 646 -288 ct 651 -293 657 -297 665 -300 ct +672 -303 681 -304 691 -304 ct 695 -304 699 -304 703 -303 ct 707 -302 709 -302 711 -301 ct +711 -256 l 708 -257 704 -257 700 -258 ct 695 -258 691 -258 685 -258 ct 674 -258 664 -256 656 -251 ct +648 -246 641 -238 636 -229 ct 631 -220 628 -209 625 -197 ct 623 -184 622 -170 622 -156 ct +622 0 l 572 0 l p ef +796 -150 m 796 -133 797 -117 799 -103 ct 802 -89 806 -76 812 -66 ct 818 -56 826 -47 835 -42 ct +845 -36 857 -33 871 -33 ct 889 -33 903 -38 915 -47 ct 927 -56 934 -71 937 -90 ct +987 -90 l 985 -78 982 -65 976 -54 ct 971 -42 963 -32 954 -23 ct 944 -14 933 -7 919 -2 ct +906 3 890 6 872 6 ct 849 6 829 2 813 -6 ct 796 -14 783 -25 773 -39 ct 763 -53 755 -69 751 -88 ct +746 -107 744 -127 744 -149 ct 744 -169 746 -187 749 -202 ct 752 -218 757 -231 763 -243 ct +769 -254 776 -264 784 -272 ct 792 -280 801 -286 810 -291 ct 820 -295 830 -299 840 -301 ct +851 -303 861 -304 872 -304 ct 888 -304 903 -302 916 -297 ct 929 -292 941 -286 950 -278 ct +960 -270 967 -261 973 -250 ct 979 -239 983 -227 985 -215 ct 935 -211 l 932 -227 925 -241 915 -250 ct +905 -260 890 -265 870 -265 ct 856 -265 844 -263 835 -258 ct 826 -253 818 -246 812 -237 ct +806 -227 802 -215 799 -201 ct 797 -187 796 -170 796 -150 ct p ef +1041 0 m 1041 -409 l 1091 -409 l 1091 0 l 1041 0 l p ef +1206 -138 m 1206 -122 1208 -108 1211 -95 ct 1214 -82 1219 -71 1226 -61 ct 1232 -52 1241 -44 1251 -39 ct +1262 -34 1274 -31 1289 -31 ct 1311 -31 1328 -36 1341 -44 ct 1354 -53 1363 -64 1367 -77 ct +1411 -65 l 1408 -56 1403 -48 1398 -40 ct 1392 -31 1384 -24 1375 -17 ct 1366 -10 1354 -5 1340 0 ct +1326 4 1309 6 1289 6 ct 1245 6 1212 -7 1189 -33 ct 1165 -60 1154 -99 1154 -151 ct +1154 -179 1157 -202 1164 -222 ct 1171 -241 1181 -257 1193 -269 ct 1205 -281 1219 -290 1235 -296 ct +1252 -301 1269 -304 1287 -304 ct 1312 -304 1333 -300 1350 -292 ct 1367 -283 1380 -272 1390 -258 ct +1401 -244 1408 -227 1412 -207 ct 1416 -188 1419 -167 1419 -145 ct 1419 -138 l +1206 -138 l p +1367 -176 m 1365 -208 1357 -231 1343 -245 ct 1330 -260 1311 -267 1286 -267 ct +1278 -267 1269 -266 1260 -263 ct 1251 -260 1243 -256 1235 -249 ct 1228 -242 1221 -233 1216 -221 ct +1210 -209 1207 -194 1207 -176 ct 1367 -176 l p ef +1611 -349 m 1611 -339 1611 -330 1610 -322 ct 1609 -314 1608 -307 1606 -300 ct +1604 -293 1602 -287 1599 -280 ct 1596 -274 1593 -268 1589 -263 ct 1556 -263 l +1564 -274 1571 -287 1575 -299 ct 1580 -311 1582 -323 1582 -335 ct 1558 -335 l +1558 -389 l 1611 -389 l 1611 -349 l p +1520 -349 m 1520 -339 1520 -330 1519 -322 ct 1518 -314 1517 -307 1515 -300 ct +1513 -293 1511 -287 1508 -280 ct 1505 -274 1502 -268 1499 -263 ct 1465 -263 l +1473 -274 1479 -287 1484 -299 ct 1488 -311 1491 -323 1491 -335 ct 1466 -335 l +1466 -389 l 1520 -389 l 1520 -349 l p ef +pom +1.000 1.000 1.000 c 8130 7170 m 7943 7170 7755 7358 7755 7546 ct 7755 8063 l +7755 8251 7943 8440 8130 8440 ct 11696 8440 l 11884 8440 12073 8251 12073 8063 ct +12073 7546 l 12073 7358 11884 7170 11696 7170 ct 8130 7170 l p +7755 7170 m 7755 7170 l p +12073 8440 m 12073 8440 l p ef +0.003 0.003 0.003 c 8130 7170 m 7942 7170 7754 7358 7754 7546 ct 7754 8063 l +7754 8251 7942 8439 8130 8439 ct 11696 8439 l 11884 8439 12073 8251 12073 8063 ct +12073 7546 l 12073 7358 11884 7170 11696 7170 ct 8130 7170 l pc +7754 7170 m 7754 7170 l pc +12073 8439 m 12073 8439 l pc +pum +8114 8011 t +274 0 m 213 0 165 -18 129 -54 ct 93 -90 75 -139 75 -200 ct 75 -261 93 -309 129 -345 ct +165 -381 213 -399 274 -399 ct 335 -399 383 -381 420 -345 ct 457 -309 475 -260 475 -200 ct +475 -139 457 -91 420 -54 ct 383 -18 335 0 274 0 ct p ef +pom +pum +8876 7976 t +41 0 m 41 -340 l 298 -340 l 298 -302 l 87 -302 l 87 -193 l 284 -193 l +284 -156 l 87 -156 l 87 -38 l 308 -38 l 308 0 l 41 0 l p ef +523 0 m 453 -107 l 382 0 l 336 0 l 428 -134 l 340 -261 l 388 -261 l +453 -160 l 518 -261 l 566 -261 l 478 -135 l 572 0 l 523 0 l p ef +639 -121 m 639 -107 640 -95 643 -83 ct 646 -72 650 -62 656 -54 ct 662 -45 669 -39 678 -34 ct +688 -30 699 -28 711 -28 ct 730 -28 745 -31 757 -39 ct 768 -46 776 -56 780 -68 ct +818 -57 l 815 -49 811 -42 806 -35 ct 801 -28 795 -21 787 -15 ct 778 -9 768 -4 756 -1 ct +744 3 729 5 711 5 ct 673 5 643 -7 623 -30 ct 603 -53 593 -87 593 -132 ct 593 -157 596 -177 602 -194 ct +608 -211 617 -225 627 -236 ct 638 -246 650 -254 664 -259 ct 679 -264 694 -266 710 -266 ct +732 -266 750 -262 765 -255 ct 779 -248 791 -238 800 -226 ct 809 -213 815 -199 819 -182 ct +823 -165 825 -147 825 -127 ct 825 -121 l 639 -121 l p +780 -154 m 778 -182 771 -202 759 -215 ct 747 -228 731 -234 709 -234 ct 702 -234 694 -233 686 -230 ct +678 -228 671 -224 664 -218 ct 657 -212 652 -204 647 -193 ct 642 -183 640 -170 639 -154 ct +780 -154 l p ef +913 -132 m 913 -117 914 -103 917 -90 ct 919 -78 922 -67 928 -58 ct 933 -49 940 -42 948 -37 ct +956 -32 967 -29 979 -29 ct 995 -29 1008 -33 1018 -41 ct 1028 -50 1035 -62 1037 -79 ct +1081 -79 l 1080 -68 1076 -58 1072 -47 ct 1067 -37 1060 -28 1052 -21 ct 1044 -13 1034 -7 1022 -2 ct +1010 3 996 5 980 5 ct 960 5 943 2 928 -5 ct 914 -12 902 -22 893 -34 ct 885 -46 878 -60 874 -77 ct +870 -94 868 -111 868 -131 ct 868 -148 869 -164 872 -177 ct 875 -191 879 -202 885 -213 ct +890 -223 896 -231 903 -238 ct 910 -245 918 -250 926 -254 ct 934 -258 943 -261 952 -263 ct +961 -265 971 -266 980 -266 ct 995 -266 1008 -264 1019 -260 ct 1030 -256 1040 -250 1049 -243 ct +1057 -236 1064 -228 1069 -219 ct 1074 -209 1077 -199 1080 -188 ct 1035 -185 l +1033 -199 1027 -211 1018 -219 ct 1009 -228 996 -232 979 -232 ct 966 -232 956 -230 948 -226 ct +939 -222 933 -216 928 -207 ct 922 -199 919 -188 917 -176 ct 914 -163 913 -149 913 -132 ct +p ef +1172 -261 m 1172 -95 l 1172 -83 1173 -72 1175 -64 ct 1176 -55 1179 -48 1184 -43 ct +1188 -38 1193 -34 1200 -32 ct 1207 -30 1215 -29 1226 -29 ct 1236 -29 1245 -30 1253 -34 ct +1262 -38 1269 -43 1275 -50 ct 1280 -57 1285 -65 1288 -75 ct 1291 -85 1293 -97 1293 -110 ct +1293 -261 l 1336 -261 l 1336 -56 l 1336 -50 1337 -44 1337 -38 ct 1337 -32 1337 -27 1337 -21 ct +1337 -16 1337 -11 1337 -7 ct 1338 -3 1338 -1 1338 0 ct 1297 0 l 1297 -1 1297 -3 1296 -6 ct +1296 -10 1296 -14 1296 -19 ct 1296 -23 1295 -28 1295 -33 ct 1295 -37 1295 -41 1295 -44 ct +1294 -44 l 1290 -37 1286 -30 1281 -24 ct 1276 -18 1270 -13 1263 -8 ct 1257 -4 1249 -1 1240 2 ct +1232 4 1222 5 1211 5 ct 1196 5 1184 3 1173 0 ct 1163 -4 1154 -9 1148 -17 ct 1141 -24 1136 -34 1133 -45 ct +1130 -57 1128 -71 1128 -87 ct 1128 -261 l 1172 -261 l p ef +1506 -2 m 1499 0 1492 1 1485 2 ct 1479 3 1471 4 1462 4 ct 1427 4 1410 -16 1410 -55 ct +1410 -229 l 1379 -229 l 1379 -261 l 1411 -261 l 1424 -320 l 1453 -320 l +1453 -261 l 1501 -261 l 1501 -229 l 1453 -229 l 1453 -65 l 1453 -52 1455 -43 1459 -38 ct +1463 -33 1470 -31 1481 -31 ct 1485 -31 1489 -31 1493 -31 ct 1497 -32 1501 -33 1506 -34 ct +1506 -2 l p ef +1544 -316 m 1544 -358 l 1587 -358 l 1587 -316 l 1544 -316 l p +1544 0 m 1544 -261 l 1587 -261 l 1587 0 l 1544 0 l p ef +1875 -131 m 1875 -85 1865 -51 1845 -29 ct 1825 -6 1796 5 1757 5 ct 1739 5 1723 2 1709 -3 ct +1694 -9 1682 -17 1672 -28 ct 1662 -40 1655 -54 1650 -71 ct 1644 -88 1642 -108 1642 -131 ct +1642 -221 1681 -266 1759 -266 ct 1779 -266 1796 -263 1811 -258 ct 1826 -252 1838 -243 1847 -232 ct +1857 -221 1864 -207 1868 -190 ct 1873 -173 1875 -153 1875 -131 ct p +1829 -131 m 1829 -151 1828 -168 1825 -181 ct 1822 -194 1817 -205 1811 -213 ct +1805 -221 1798 -226 1789 -229 ct 1780 -232 1770 -234 1759 -234 ct 1748 -234 1738 -232 1729 -229 ct +1721 -226 1713 -220 1707 -212 ct 1700 -204 1696 -193 1692 -180 ct 1689 -167 1687 -151 1687 -131 ct +1687 -110 1689 -94 1693 -80 ct 1696 -67 1701 -57 1707 -49 ct 1713 -41 1721 -35 1729 -32 ct +1738 -29 1747 -27 1757 -27 ct 1768 -27 1778 -29 1787 -32 ct 1796 -35 1804 -40 1810 -48 ct +1816 -56 1821 -67 1824 -80 ct 1828 -94 1829 -110 1829 -131 ct p ef +2096 0 m 2096 -166 l 2096 -178 2095 -189 2093 -197 ct 2091 -206 2088 -213 2084 -218 ct +2080 -223 2074 -227 2068 -229 ct 2061 -231 2052 -232 2042 -232 ct 2032 -232 2023 -231 2014 -227 ct +2006 -223 1999 -218 1993 -211 ct 1987 -205 1983 -196 1979 -186 ct 1976 -176 1975 -164 1975 -151 ct +1975 0 l 1931 0 l 1931 -205 l 1931 -211 1931 -217 1931 -223 ct 1931 -229 1931 -234 1931 -240 ct +1931 -245 1930 -250 1930 -254 ct 1930 -258 1930 -260 1930 -261 ct 1971 -261 l +1971 -260 1971 -258 1971 -255 ct 1971 -251 1972 -247 1972 -242 ct 1972 -238 1972 -233 1973 -228 ct +1973 -224 1973 -220 1973 -217 ct 1973 -217 l 1978 -224 1982 -231 1987 -237 ct +1992 -243 1998 -248 2005 -253 ct 2011 -257 2019 -260 2027 -263 ct 2036 -265 2046 -266 2057 -266 ct +2071 -266 2084 -264 2094 -261 ct 2105 -257 2113 -252 2120 -244 ct 2127 -237 2132 -227 2135 -216 ct +2138 -204 2140 -190 2140 -174 ct 2140 0 l 2096 0 l p ef +pom +gs +20217 8434 m 18121 8434 l 18121 7165 l 22312 7165 l 22312 8434 l 20217 8434 l +eoclip newpath +18122 7165 m 22313 7165 l 22313 8435 l 18122 8435 l 18122 7165 l eoclip newpath +pum +17780 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17992 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18204 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18416 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18628 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18840 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19052 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19264 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19476 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19688 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19900 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20112 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20324 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20536 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20748 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20960 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21172 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21384 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21595 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21807 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22019 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22231 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17992 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18204 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18416 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18628 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18840 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19052 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19264 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19476 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19688 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19900 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20112 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20324 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20536 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20748 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20960 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21172 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21384 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21595 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21807 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22019 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22231 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17780 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17992 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18204 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18416 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18628 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18840 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19052 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19264 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19476 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19688 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19900 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20112 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20324 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20536 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20748 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20960 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21172 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21384 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21595 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21807 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22019 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22231 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17992 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18204 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18416 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18628 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18840 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19052 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19264 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19476 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19688 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19900 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20112 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20324 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20536 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20748 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20960 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21172 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21384 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21595 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21807 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22019 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22231 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17780 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17992 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18204 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18416 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18628 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18840 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19052 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19264 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19476 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19688 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19900 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20112 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20324 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20536 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20748 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20960 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21172 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21384 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21595 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21807 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22019 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22231 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17992 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18204 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18416 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18628 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18840 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19052 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19264 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19476 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19688 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19900 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20112 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20324 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20536 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20748 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20960 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21172 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21384 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21595 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21807 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22019 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22231 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17780 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17992 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18204 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18416 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18628 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +18840 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19052 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19264 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19476 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19688 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +19900 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20112 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20324 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20536 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20748 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +20960 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21172 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21384 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21595 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +21807 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22019 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22231 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +gr +20217 8434 m 18121 8434 l 18121 7165 l 22312 7165 l 22312 8434 l 20217 8434 l +pc +pum +19200 7681 t +114 6 m 84 6 62 -2 47 -18 ct 31 -34 24 -56 24 -83 ct 24 -103 28 -119 35 -132 ct +43 -145 52 -154 64 -162 ct 76 -169 90 -174 105 -177 ct 121 -179 137 -181 153 -181 ct +219 -181 l 219 -197 l 219 -210 218 -220 216 -229 ct 213 -238 209 -245 204 -250 ct +198 -256 192 -260 184 -262 ct 176 -265 166 -266 156 -266 ct 146 -266 137 -265 130 -264 ct +122 -263 115 -260 110 -256 ct 104 -253 99 -248 96 -242 ct 92 -236 90 -228 89 -218 ct +37 -223 l 39 -235 43 -246 48 -256 ct 53 -265 60 -274 70 -281 ct 79 -288 91 -294 105 -298 ct +119 -302 137 -304 157 -304 ct 194 -304 222 -295 241 -278 ct 260 -261 270 -236 270 -203 ct +270 -74 l 270 -60 272 -49 275 -41 ct 279 -34 287 -30 297 -30 ct 300 -30 303 -30 306 -31 ct +308 -31 311 -31 314 -32 ct 314 -1 l 307 0 301 2 295 2 ct 289 3 282 3 275 3 ct +266 3 258 2 251 0 ct 245 -3 239 -7 235 -12 ct 231 -17 227 -23 225 -30 ct 223 -38 222 -47 221 -57 ct +219 -57 l 214 -47 208 -38 202 -31 ct 196 -23 188 -16 180 -11 ct 171 -6 162 -1 151 2 ct +140 5 128 6 114 6 ct p +125 -31 m 141 -31 155 -34 167 -40 ct 179 -46 188 -53 196 -62 ct 204 -71 210 -81 214 -91 ct +218 -102 219 -112 219 -122 ct 219 -146 l 165 -146 l 153 -146 142 -145 131 -144 ct +120 -142 110 -139 102 -134 ct 94 -130 87 -123 82 -115 ct 77 -107 75 -96 75 -82 ct +75 -66 79 -53 88 -45 ct 97 -36 109 -31 125 -31 ct p ef +466 -3 m 458 -1 450 1 443 2 ct 435 3 426 4 415 4 ct 376 4 356 -19 356 -64 ct 356 -263 l +322 -263 l 322 -299 l 358 -299 l 372 -366 l 406 -366 l 406 -299 l +461 -299 l 461 -263 l 406 -263 l 406 -74 l 406 -60 408 -50 413 -44 ct +417 -38 425 -35 437 -35 ct 442 -35 446 -36 451 -37 ct 455 -37 460 -38 466 -39 ct +466 -3 l p ef +623 -3 m 615 -1 607 1 600 2 ct 592 3 583 4 572 4 ct 533 4 513 -19 513 -64 ct 513 -263 l +479 -263 l 479 -299 l 515 -299 l 529 -366 l 563 -366 l 563 -299 l +618 -299 l 618 -263 l 563 -263 l 563 -74 l 563 -60 565 -50 570 -44 ct +574 -38 582 -35 594 -35 ct 599 -35 603 -36 608 -37 ct 612 -37 617 -38 623 -39 ct +623 -3 l p ef +666 0 m 666 -229 l 666 -235 666 -242 666 -248 ct 666 -255 666 -261 666 -267 ct +665 -273 665 -279 665 -284 ct 665 -289 665 -294 664 -298 ct 711 -298 l 711 -294 712 -289 712 -284 ct +712 -279 713 -273 713 -267 ct 713 -262 713 -256 713 -251 ct 713 -246 713 -241 713 -238 ct +715 -238 l 718 -249 722 -259 726 -267 ct 730 -276 734 -282 740 -288 ct 745 -293 751 -297 759 -300 ct +766 -303 775 -304 785 -304 ct 789 -304 793 -304 797 -303 ct 801 -302 803 -302 805 -301 ct +805 -256 l 802 -257 798 -257 794 -258 ct 789 -258 785 -258 779 -258 ct 768 -258 758 -256 750 -251 ct +742 -246 735 -238 730 -229 ct 725 -220 722 -209 719 -197 ct 717 -184 716 -170 716 -156 ct +716 0 l 666 0 l p ef +851 -362 m 851 -409 l 900 -409 l 900 -362 l 851 -362 l p +851 0 m 851 -298 l 900 -298 l 900 0 l 851 0 l p ef +1230 -150 m 1230 -46 1193 6 1120 6 ct 1098 6 1079 2 1064 -6 ct 1049 -14 1037 -28 1028 -46 ct +1027 -46 l 1027 -41 1027 -36 1027 -31 ct 1026 -26 1026 -21 1026 -17 ct 1026 -12 1025 -9 1025 -5 ct +1025 -2 1024 0 1024 0 ct 976 0 l 977 -1 977 -4 977 -8 ct 977 -12 977 -17 977 -22 ct +978 -28 978 -34 978 -40 ct 978 -47 978 -54 978 -61 ct 978 -409 l 1028 -409 l +1028 -292 l 1028 -287 1028 -281 1027 -276 ct 1027 -271 1027 -267 1027 -263 ct +1027 -258 1027 -254 1026 -250 ct 1028 -250 l 1037 -269 1049 -283 1064 -291 ct +1079 -299 1098 -303 1120 -303 ct 1158 -303 1186 -291 1203 -265 ct 1221 -240 1230 -202 1230 -150 ct +p +1178 -148 m 1178 -169 1177 -187 1174 -201 ct 1172 -216 1167 -228 1162 -238 ct +1156 -247 1149 -254 1140 -258 ct 1131 -263 1120 -265 1108 -265 ct 1095 -265 1083 -263 1073 -259 ct +1063 -254 1055 -248 1048 -238 ct 1041 -229 1036 -217 1033 -201 ct 1029 -186 1028 -167 1028 -145 ct +1028 -124 1029 -106 1033 -92 ct 1036 -77 1041 -65 1048 -56 ct 1055 -47 1063 -41 1073 -37 ct +1083 -33 1094 -31 1107 -31 ct 1119 -31 1130 -33 1139 -37 ct 1147 -41 1155 -48 1161 -57 ct +1166 -67 1171 -79 1174 -94 ct 1177 -109 1178 -127 1178 -148 ct p ef +1339 -298 m 1339 -109 l 1339 -94 1341 -82 1343 -72 ct 1345 -63 1348 -55 1353 -49 ct +1358 -43 1364 -39 1372 -36 ct 1380 -34 1389 -32 1401 -32 ct 1413 -32 1423 -34 1433 -39 ct +1442 -43 1450 -49 1457 -56 ct 1464 -64 1469 -74 1472 -85 ct 1476 -97 1478 -110 1478 -125 ct +1478 -298 l 1528 -298 l 1528 -63 l 1528 -57 1528 -50 1528 -44 ct 1528 -37 1528 -30 1528 -24 ct +1528 -18 1528 -12 1529 -8 ct 1529 -4 1529 -1 1529 0 ct 1482 0 l 1482 0 1482 -3 1482 -7 ct +1482 -11 1481 -16 1481 -21 ct 1481 -26 1481 -31 1480 -37 ct 1480 -42 1480 -47 1480 -51 ct +1479 -51 l 1475 -42 1469 -34 1464 -27 ct 1458 -20 1451 -14 1444 -9 ct 1436 -4 1428 -1 1418 2 ct +1408 5 1397 6 1384 6 ct 1368 6 1353 4 1341 0 ct 1329 -4 1320 -10 1312 -19 ct 1304 -27 1299 -38 1295 -51 ct +1291 -65 1290 -81 1290 -99 ct 1290 -298 l 1339 -298 l p ef +1719 -3 m 1711 -1 1703 1 1696 2 ct 1688 3 1679 4 1668 4 ct 1629 4 1609 -19 1609 -64 ct +1609 -263 l 1575 -263 l 1575 -299 l 1611 -299 l 1625 -366 l 1659 -366 l +1659 -299 l 1714 -299 l 1714 -263 l 1659 -263 l 1659 -74 l 1659 -60 1661 -50 1666 -44 ct +1670 -38 1678 -35 1690 -35 ct 1695 -35 1699 -36 1704 -37 ct 1708 -37 1713 -38 1719 -39 ct +1719 -3 l p ef +1799 -138 m 1799 -122 1801 -108 1804 -95 ct 1807 -82 1812 -71 1819 -61 ct 1825 -52 1834 -44 1844 -39 ct +1855 -34 1867 -31 1882 -31 ct 1904 -31 1921 -36 1934 -44 ct 1947 -53 1956 -64 1960 -77 ct +2004 -65 l 2001 -56 1996 -48 1991 -40 ct 1985 -31 1977 -24 1968 -17 ct 1959 -10 1947 -5 1933 0 ct +1919 4 1902 6 1882 6 ct 1838 6 1805 -7 1782 -33 ct 1758 -60 1747 -99 1747 -151 ct +1747 -179 1750 -202 1757 -222 ct 1764 -241 1774 -257 1786 -269 ct 1798 -281 1812 -290 1828 -296 ct +1845 -301 1862 -304 1880 -304 ct 1905 -304 1926 -300 1943 -292 ct 1960 -283 1973 -272 1983 -258 ct +1994 -244 2001 -227 2005 -207 ct 2009 -188 2012 -167 2012 -145 ct 2012 -138 l +1799 -138 l p +1960 -176 m 1958 -208 1950 -231 1936 -245 ct 1923 -260 1904 -267 1879 -267 ct +1871 -267 1862 -266 1853 -263 ct 1844 -260 1836 -256 1828 -249 ct 1821 -242 1814 -233 1809 -221 ct +1803 -209 1800 -194 1800 -176 ct 1960 -176 l p ef +pom +pum +18870 8308 t +112 -263 m 112 -303 l 112 -313 113 -322 113 -329 ct 114 -337 116 -345 117 -352 ct +119 -359 121 -365 124 -371 ct 127 -377 130 -383 134 -389 ct 167 -389 l 159 -377 153 -365 148 -353 ct +144 -341 141 -329 141 -317 ct 166 -317 l 166 -263 l 112 -263 l p +21 -263 m 21 -303 l 21 -313 21 -322 22 -329 ct 23 -337 24 -345 26 -352 ct +28 -359 30 -365 33 -371 ct 36 -377 39 -383 43 -389 ct 76 -389 l 68 -377 61 -365 57 -353 ct +52 -341 50 -329 50 -317 ct 74 -317 l 74 -263 l 21 -263 l p ef +pom +pum +19056 8308 t +212 0 m 212 -189 l 212 -204 211 -216 209 -226 ct 207 -235 204 -243 200 -249 ct +195 -255 190 -259 183 -262 ct 176 -264 167 -266 157 -266 ct 147 -266 137 -264 129 -259 ct +120 -255 113 -249 107 -242 ct 101 -234 96 -224 93 -213 ct 90 -201 88 -188 88 -173 ct +88 0 l 39 0 l 39 -235 l 39 -241 39 -248 39 -254 ct 39 -261 39 -268 39 -274 ct +38 -280 38 -286 38 -290 ct 38 -294 38 -297 37 -298 ct 84 -298 l 84 -298 85 -295 85 -291 ct +85 -287 85 -282 86 -277 ct 86 -272 86 -267 86 -261 ct 86 -256 86 -251 86 -247 ct +87 -247 l 92 -256 96 -264 102 -271 ct 107 -278 113 -284 120 -289 ct 127 -294 134 -297 143 -300 ct +152 -303 163 -304 174 -304 ct 197 -304 215 -300 228 -290 ct 241 -281 250 -267 255 -247 ct +256 -247 l 261 -256 265 -264 271 -271 ct 277 -278 283 -284 290 -289 ct 298 -294 306 -297 315 -300 ct +324 -303 335 -304 346 -304 ct 362 -304 374 -302 385 -298 ct 396 -294 405 -288 412 -279 ct +419 -271 424 -260 428 -246 ct 431 -233 433 -217 433 -199 ct 433 0 l 384 0 l +384 -189 l 384 -204 383 -216 381 -226 ct 379 -235 376 -243 372 -249 ct 367 -255 362 -259 355 -262 ct +348 -264 339 -266 329 -266 ct 319 -266 309 -264 301 -260 ct 292 -256 285 -250 279 -242 ct +273 -234 269 -225 265 -213 ct 262 -202 261 -188 261 -173 ct 261 0 l 212 0 l +p ef +465 112 m 465 76 l 794 76 l 794 112 l 465 112 l p ef +826 0 m 826 -229 l 826 -235 826 -242 826 -248 ct 826 -255 826 -261 826 -267 ct +825 -273 825 -279 825 -284 ct 825 -289 825 -294 824 -298 ct 871 -298 l 871 -294 872 -289 872 -284 ct +872 -279 873 -273 873 -267 ct 873 -262 873 -256 873 -251 ct 873 -246 873 -241 873 -238 ct +875 -238 l 878 -249 882 -259 886 -267 ct 890 -276 894 -282 900 -288 ct 905 -293 911 -297 919 -300 ct +926 -303 935 -304 945 -304 ct 949 -304 953 -304 957 -303 ct 961 -302 963 -302 965 -301 ct +965 -256 l 962 -257 958 -257 954 -258 ct 949 -258 945 -258 939 -258 ct 928 -258 918 -256 910 -251 ct +902 -246 895 -238 890 -229 ct 885 -220 882 -209 879 -197 ct 877 -184 876 -170 876 -156 ct +876 0 l 826 0 l p ef +1088 6 m 1058 6 1036 -2 1021 -18 ct 1005 -34 998 -56 998 -83 ct 998 -103 1002 -119 1009 -132 ct +1017 -145 1026 -154 1038 -162 ct 1050 -169 1064 -174 1079 -177 ct 1095 -179 1111 -181 1127 -181 ct +1193 -181 l 1193 -197 l 1193 -210 1192 -220 1190 -229 ct 1187 -238 1183 -245 1178 -250 ct +1172 -256 1166 -260 1158 -262 ct 1150 -265 1140 -266 1130 -266 ct 1120 -266 1111 -265 1104 -264 ct +1096 -263 1089 -260 1084 -256 ct 1078 -253 1073 -248 1070 -242 ct 1066 -236 1064 -228 1063 -218 ct +1011 -223 l 1013 -235 1017 -246 1022 -256 ct 1027 -265 1034 -274 1044 -281 ct +1053 -288 1065 -294 1079 -298 ct 1093 -302 1111 -304 1131 -304 ct 1168 -304 1196 -295 1215 -278 ct +1234 -261 1244 -236 1244 -203 ct 1244 -74 l 1244 -60 1246 -49 1249 -41 ct 1253 -34 1261 -30 1271 -30 ct +1274 -30 1277 -30 1280 -31 ct 1282 -31 1285 -31 1288 -32 ct 1288 -1 l 1281 0 1275 2 1269 2 ct +1263 3 1256 3 1249 3 ct 1240 3 1232 2 1225 0 ct 1219 -3 1213 -7 1209 -12 ct 1205 -17 1201 -23 1199 -30 ct +1197 -38 1196 -47 1195 -57 ct 1193 -57 l 1188 -47 1182 -38 1176 -31 ct 1170 -23 1162 -16 1154 -11 ct +1145 -6 1136 -1 1125 2 ct 1114 5 1102 6 1088 6 ct p +1099 -31 m 1115 -31 1129 -34 1141 -40 ct 1153 -46 1162 -53 1170 -62 ct 1178 -71 1184 -81 1188 -91 ct +1192 -102 1193 -112 1193 -122 ct 1193 -146 l 1139 -146 l 1127 -146 1116 -145 1105 -144 ct +1094 -142 1084 -139 1076 -134 ct 1068 -130 1061 -123 1056 -115 ct 1051 -107 1049 -96 1049 -82 ct +1049 -66 1053 -53 1062 -45 ct 1071 -36 1083 -31 1099 -31 ct p ef +1513 -48 m 1504 -28 1492 -15 1477 -6 ct 1461 2 1443 6 1420 6 ct 1383 6 1355 -7 1337 -32 ct +1320 -57 1311 -96 1311 -147 ct 1311 -252 1347 -304 1420 -304 ct 1443 -304 1462 -300 1477 -291 ct +1492 -283 1504 -270 1513 -252 ct 1514 -252 l 1514 -254 1514 -257 1514 -260 ct +1513 -264 1513 -269 1513 -273 ct 1513 -277 1513 -281 1513 -285 ct 1513 -289 1513 -292 1513 -293 ct +1513 -409 l 1563 -409 l 1563 -61 l 1563 -54 1563 -47 1563 -40 ct 1563 -34 1563 -28 1563 -22 ct +1563 -17 1564 -12 1564 -8 ct 1564 -4 1564 -1 1564 0 ct 1517 0 l 1517 -1 1516 -4 1516 -7 ct +1516 -11 1515 -15 1515 -19 ct 1515 -24 1515 -28 1514 -33 ct 1514 -38 1514 -43 1514 -48 ct +1513 -48 l p +1363 -149 m 1363 -129 1364 -111 1367 -96 ct 1369 -81 1373 -69 1379 -60 ct 1385 -50 1392 -43 1401 -39 ct +1410 -35 1420 -32 1433 -32 ct 1446 -32 1458 -34 1468 -39 ct 1478 -43 1486 -50 1493 -59 ct +1499 -69 1504 -81 1508 -96 ct 1511 -112 1513 -130 1513 -152 ct 1513 -174 1511 -191 1508 -206 ct +1504 -221 1499 -233 1492 -242 ct 1486 -251 1477 -257 1468 -261 ct 1458 -265 1446 -267 1434 -267 ct +1421 -267 1411 -265 1402 -261 ct 1393 -256 1386 -250 1380 -240 ct 1374 -231 1370 -219 1367 -204 ct +1364 -189 1363 -170 1363 -149 ct p ef +1638 -362 m 1638 -409 l 1687 -409 l 1687 -362 l 1638 -362 l p +1638 0 m 1638 -298 l 1687 -298 l 1687 0 l 1638 0 l p ef +1813 -298 m 1813 -109 l 1813 -94 1815 -82 1817 -72 ct 1819 -63 1822 -55 1827 -49 ct +1832 -43 1838 -39 1846 -36 ct 1854 -34 1863 -32 1875 -32 ct 1887 -32 1897 -34 1907 -39 ct +1916 -43 1924 -49 1931 -56 ct 1938 -64 1943 -74 1946 -85 ct 1950 -97 1952 -110 1952 -125 ct +1952 -298 l 2002 -298 l 2002 -63 l 2002 -57 2002 -50 2002 -44 ct 2002 -37 2002 -30 2002 -24 ct +2002 -18 2002 -12 2003 -8 ct 2003 -4 2003 -1 2003 0 ct 1956 0 l 1956 0 1956 -3 1956 -7 ct +1956 -11 1955 -16 1955 -21 ct 1955 -26 1955 -31 1954 -37 ct 1954 -42 1954 -47 1954 -51 ct +1953 -51 l 1949 -42 1943 -34 1938 -27 ct 1932 -20 1925 -14 1918 -9 ct 1910 -4 1902 -1 1892 2 ct +1882 5 1871 6 1858 6 ct 1842 6 1827 4 1815 0 ct 1803 -4 1794 -10 1786 -19 ct 1778 -27 1773 -38 1769 -51 ct +1765 -65 1764 -81 1764 -99 ct 1764 -298 l 1813 -298 l p ef +2302 -82 m 2302 -68 2299 -56 2294 -45 ct 2288 -34 2280 -24 2270 -17 ct 2260 -10 2247 -4 2232 0 ct +2217 4 2200 6 2181 6 ct 2163 6 2148 5 2134 2 ct 2120 -1 2108 -5 2098 -11 ct 2087 -17 2078 -24 2071 -34 ct +2064 -44 2059 -56 2056 -70 ct 2099 -78 l 2104 -62 2112 -50 2126 -43 ct 2139 -36 2157 -32 2181 -32 ct +2191 -32 2201 -33 2210 -34 ct 2219 -35 2227 -38 2233 -42 ct 2239 -45 2244 -50 2248 -56 ct +2252 -62 2253 -69 2253 -78 ct 2253 -87 2251 -95 2247 -100 ct 2243 -106 2237 -111 2229 -115 ct +2222 -119 2213 -122 2202 -125 ct 2191 -128 2180 -131 2167 -134 ct 2155 -137 2143 -141 2131 -145 ct +2119 -149 2109 -154 2099 -160 ct 2090 -166 2082 -174 2076 -184 ct 2070 -193 2068 -205 2068 -219 ct +2068 -246 2077 -267 2097 -281 ct 2116 -295 2144 -303 2181 -303 ct 2214 -303 2240 -297 2260 -285 ct +2279 -274 2291 -255 2296 -229 ct 2252 -224 l 2250 -232 2247 -238 2243 -243 ct +2238 -249 2233 -253 2227 -256 ct 2220 -259 2213 -262 2206 -263 ct 2198 -264 2190 -265 2181 -265 ct +2159 -265 2142 -262 2132 -255 ct 2121 -248 2116 -238 2116 -224 ct 2116 -216 2118 -209 2122 -204 ct +2126 -199 2131 -194 2138 -191 ct 2145 -187 2154 -184 2164 -181 ct 2174 -179 2184 -176 2196 -173 ct +2204 -171 2212 -169 2221 -166 ct 2229 -164 2237 -161 2245 -158 ct 2253 -155 2260 -151 2267 -147 ct +2274 -143 2280 -137 2285 -131 ct 2290 -125 2294 -118 2297 -110 ct 2300 -102 2302 -93 2302 -82 ct +p ef +2491 -349 m 2491 -339 2491 -330 2490 -322 ct 2489 -314 2488 -307 2486 -300 ct +2484 -293 2482 -287 2479 -280 ct 2476 -274 2473 -268 2469 -263 ct 2436 -263 l +2444 -274 2451 -287 2455 -299 ct 2460 -311 2462 -323 2462 -335 ct 2438 -335 l +2438 -389 l 2491 -389 l 2491 -349 l p +2400 -349 m 2400 -339 2400 -330 2399 -322 ct 2398 -314 2397 -307 2395 -300 ct +2393 -293 2391 -287 2388 -280 ct 2385 -274 2382 -268 2379 -263 ct 2345 -263 l +2353 -274 2359 -287 2364 -299 ct 2368 -311 2371 -323 2371 -335 ct 2346 -335 l +2346 -389 l 2400 -389 l 2400 -349 l p ef +pom +gs +25091 8440 m 22995 8440 l 22995 7171 l 27186 7171 l 27186 8440 l 25091 8440 l +eoclip newpath +22996 7171 m 27186 7171 l 27186 8441 l 22996 8441 l 22996 7171 l eoclip newpath +pum +22654 7276 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22866 7276 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23078 7276 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23290 7276 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23502 7276 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23714 7276 t +211 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23925 7276 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24137 7276 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24349 7276 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24561 7276 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24773 7276 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24985 7276 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25197 7276 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25409 7276 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25621 7276 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25833 7276 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26045 7276 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26257 7276 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26468 7276 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26680 7276 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26892 7276 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +27104 7276 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22866 7488 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23078 7488 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23290 7488 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23502 7488 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23714 7488 t +211 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23925 7488 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24137 7488 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24349 7488 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24561 7488 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24773 7488 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24985 7488 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25197 7488 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25409 7488 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25621 7488 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25833 7488 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26045 7488 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26257 7488 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26468 7488 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26680 7488 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26892 7488 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +27104 7488 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22654 7700 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22866 7700 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23078 7700 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23290 7700 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23502 7700 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23714 7700 t +211 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23925 7700 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24137 7700 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24349 7700 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24561 7700 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24773 7700 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24985 7700 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25197 7700 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25409 7700 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25621 7700 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25833 7700 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26045 7700 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26257 7700 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26468 7700 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26680 7700 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26892 7700 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +27104 7700 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22866 7912 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23078 7912 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23290 7912 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23502 7912 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23714 7912 t +211 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23925 7912 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24137 7912 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24349 7912 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24561 7912 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24773 7912 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24985 7912 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25197 7912 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25409 7912 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25621 7912 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25833 7912 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26045 7912 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26257 7912 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26468 7912 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26680 7912 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26892 7912 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +27104 7912 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22654 8124 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22866 8124 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23078 8124 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23290 8124 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23502 8124 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23714 8124 t +211 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23925 8124 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24137 8124 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24349 8124 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24561 8124 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24773 8124 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24985 8124 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25197 8124 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25409 8124 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25621 8124 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25833 8124 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26045 8124 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26257 8124 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26468 8124 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26680 8124 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26892 8124 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +27104 8124 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22866 8336 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23078 8336 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23290 8336 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23502 8336 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23714 8336 t +211 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23925 8336 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24137 8336 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24349 8336 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24561 8336 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24773 8336 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24985 8336 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25197 8336 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25409 8336 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25621 8336 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25833 8336 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26045 8336 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26257 8336 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26468 8336 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26680 8336 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26892 8336 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +27104 8336 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22654 8548 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +22866 8548 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23078 8548 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23290 8548 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23502 8548 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23714 8548 t +211 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +23925 8548 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24137 8548 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24349 8548 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24561 8548 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24773 8548 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +24985 8548 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25197 8548 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25409 8548 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25621 8548 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +25833 8548 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26045 8548 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26257 8548 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26468 8548 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26680 8548 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +26892 8548 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +27104 8548 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +gr +25091 8440 m 22995 8440 l 22995 7171 l 27186 7171 l 27186 8440 l 25091 8440 l +pc +pum +23839 7687 t +226 -48 m 217 -28 205 -15 190 -6 ct 174 2 156 6 133 6 ct 96 6 68 -7 50 -32 ct +33 -57 24 -96 24 -147 ct 24 -252 60 -304 133 -304 ct 156 -304 175 -300 190 -291 ct +205 -283 217 -270 226 -252 ct 227 -252 l 227 -254 227 -257 227 -260 ct 226 -264 226 -269 226 -273 ct +226 -277 226 -281 226 -285 ct 226 -289 226 -292 226 -293 ct 226 -409 l 276 -409 l +276 -61 l 276 -54 276 -47 276 -40 ct 276 -34 276 -28 276 -22 ct 276 -17 277 -12 277 -8 ct +277 -4 277 -1 277 0 ct 230 0 l 230 -1 229 -4 229 -7 ct 229 -11 228 -15 228 -19 ct +228 -24 228 -28 227 -33 ct 227 -38 227 -43 227 -48 ct 226 -48 l p +76 -149 m 76 -129 77 -111 80 -96 ct 82 -81 86 -69 92 -60 ct 98 -50 105 -43 114 -39 ct +123 -35 133 -32 146 -32 ct 159 -32 171 -34 181 -39 ct 191 -43 199 -50 206 -59 ct +212 -69 217 -81 221 -96 ct 224 -112 226 -130 226 -152 ct 226 -174 224 -191 221 -206 ct +217 -221 212 -233 205 -242 ct 199 -251 190 -257 181 -261 ct 171 -265 159 -267 147 -267 ct +134 -267 124 -265 115 -261 ct 106 -256 99 -250 93 -240 ct 87 -231 83 -219 80 -204 ct +77 -189 76 -170 76 -149 ct p ef +389 -138 m 389 -122 391 -108 394 -95 ct 397 -82 402 -71 409 -61 ct 415 -52 424 -44 434 -39 ct +445 -34 457 -31 472 -31 ct 494 -31 511 -36 524 -44 ct 537 -53 546 -64 550 -77 ct +594 -65 l 591 -56 586 -48 581 -40 ct 575 -31 567 -24 558 -17 ct 549 -10 537 -5 523 0 ct +509 4 492 6 472 6 ct 428 6 395 -7 372 -33 ct 348 -60 337 -99 337 -151 ct 337 -179 340 -202 347 -222 ct +354 -241 364 -257 376 -269 ct 388 -281 402 -290 418 -296 ct 435 -301 452 -304 470 -304 ct +495 -304 516 -300 533 -292 ct 550 -283 563 -272 573 -258 ct 584 -244 591 -227 595 -207 ct +599 -188 602 -167 602 -145 ct 602 -138 l 389 -138 l p +550 -176 m 548 -208 540 -231 526 -245 ct 513 -260 494 -267 469 -267 ct 461 -267 452 -266 443 -263 ct +434 -260 426 -256 418 -249 ct 411 -242 404 -233 399 -221 ct 393 -209 390 -194 390 -176 ct +550 -176 l p ef +889 -82 m 889 -68 886 -56 881 -45 ct 875 -34 867 -24 857 -17 ct 847 -10 834 -4 819 0 ct +804 4 787 6 768 6 ct 750 6 735 5 721 2 ct 707 -1 695 -5 685 -11 ct 674 -17 665 -24 658 -34 ct +651 -44 646 -56 643 -70 ct 686 -78 l 691 -62 699 -50 713 -43 ct 726 -36 744 -32 768 -32 ct +778 -32 788 -33 797 -34 ct 806 -35 814 -38 820 -42 ct 826 -45 831 -50 835 -56 ct +839 -62 840 -69 840 -78 ct 840 -87 838 -95 834 -100 ct 830 -106 824 -111 816 -115 ct +809 -119 800 -122 789 -125 ct 778 -128 767 -131 754 -134 ct 742 -137 730 -141 718 -145 ct +706 -149 696 -154 686 -160 ct 677 -166 669 -174 663 -184 ct 657 -193 655 -205 655 -219 ct +655 -246 664 -267 684 -281 ct 703 -295 731 -303 768 -303 ct 801 -303 827 -297 847 -285 ct +866 -274 878 -255 883 -229 ct 839 -224 l 837 -232 834 -238 830 -243 ct 825 -249 820 -253 814 -256 ct +807 -259 800 -262 793 -263 ct 785 -264 777 -265 768 -265 ct 746 -265 729 -262 719 -255 ct +708 -248 703 -238 703 -224 ct 703 -216 705 -209 709 -204 ct 713 -199 718 -194 725 -191 ct +732 -187 741 -184 751 -181 ct 761 -179 771 -176 783 -173 ct 791 -171 799 -169 808 -166 ct +816 -164 824 -161 832 -158 ct 840 -155 847 -151 854 -147 ct 861 -143 867 -137 872 -131 ct +877 -125 881 -118 884 -110 ct 887 -102 889 -93 889 -82 ct p ef +1063 -3 m 1055 -1 1047 1 1040 2 ct 1032 3 1023 4 1012 4 ct 973 4 953 -19 953 -64 ct +953 -263 l 919 -263 l 919 -299 l 955 -299 l 969 -366 l 1003 -366 l +1003 -299 l 1058 -299 l 1058 -263 l 1003 -263 l 1003 -74 l 1003 -60 1005 -50 1010 -44 ct +1014 -38 1022 -35 1034 -35 ct 1039 -35 1043 -36 1048 -37 ct 1052 -37 1057 -38 1063 -39 ct +1063 -3 l p ef +1106 0 m 1106 -229 l 1106 -235 1106 -242 1106 -248 ct 1106 -255 1106 -261 1106 -267 ct +1105 -273 1105 -279 1105 -284 ct 1105 -289 1105 -294 1104 -298 ct 1151 -298 l +1151 -294 1152 -289 1152 -284 ct 1152 -279 1153 -273 1153 -267 ct 1153 -262 1153 -256 1153 -251 ct +1153 -246 1153 -241 1153 -238 ct 1155 -238 l 1158 -249 1162 -259 1166 -267 ct +1170 -276 1174 -282 1180 -288 ct 1185 -293 1191 -297 1199 -300 ct 1206 -303 1215 -304 1225 -304 ct +1229 -304 1233 -304 1237 -303 ct 1241 -302 1243 -302 1245 -301 ct 1245 -256 l +1242 -257 1238 -257 1234 -258 ct 1229 -258 1225 -258 1219 -258 ct 1208 -258 1198 -256 1190 -251 ct +1182 -246 1175 -238 1170 -229 ct 1165 -220 1162 -209 1159 -197 ct 1157 -184 1156 -170 1156 -156 ct +1156 0 l 1106 0 l p ef +1339 -298 m 1339 -109 l 1339 -94 1341 -82 1343 -72 ct 1345 -63 1348 -55 1353 -49 ct +1358 -43 1364 -39 1372 -36 ct 1380 -34 1389 -32 1401 -32 ct 1413 -32 1423 -34 1433 -39 ct +1442 -43 1450 -49 1457 -56 ct 1464 -64 1469 -74 1472 -85 ct 1476 -97 1478 -110 1478 -125 ct +1478 -298 l 1528 -298 l 1528 -63 l 1528 -57 1528 -50 1528 -44 ct 1528 -37 1528 -30 1528 -24 ct +1528 -18 1528 -12 1529 -8 ct 1529 -4 1529 -1 1529 0 ct 1482 0 l 1482 0 1482 -3 1482 -7 ct +1482 -11 1481 -16 1481 -21 ct 1481 -26 1481 -31 1480 -37 ct 1480 -42 1480 -47 1480 -51 ct +1479 -51 l 1475 -42 1469 -34 1464 -27 ct 1458 -20 1451 -14 1444 -9 ct 1436 -4 1428 -1 1418 2 ct +1408 5 1397 6 1384 6 ct 1368 6 1353 4 1341 0 ct 1329 -4 1320 -10 1312 -19 ct 1304 -27 1299 -38 1295 -51 ct +1291 -65 1290 -81 1290 -99 ct 1290 -298 l 1339 -298 l p ef +1642 -150 m 1642 -133 1643 -117 1645 -103 ct 1648 -89 1652 -76 1658 -66 ct +1664 -56 1672 -47 1681 -42 ct 1691 -36 1703 -33 1717 -33 ct 1735 -33 1749 -38 1761 -47 ct +1773 -56 1780 -71 1783 -90 ct 1833 -90 l 1831 -78 1828 -65 1822 -54 ct 1817 -42 1809 -32 1800 -23 ct +1790 -14 1779 -7 1765 -2 ct 1752 3 1736 6 1718 6 ct 1695 6 1675 2 1659 -6 ct 1642 -14 1629 -25 1619 -39 ct +1609 -53 1601 -69 1597 -88 ct 1592 -107 1590 -127 1590 -149 ct 1590 -169 1592 -187 1595 -202 ct +1598 -218 1603 -231 1609 -243 ct 1615 -254 1622 -264 1630 -272 ct 1638 -280 1647 -286 1656 -291 ct +1666 -295 1676 -299 1686 -301 ct 1697 -303 1707 -304 1718 -304 ct 1734 -304 1749 -302 1762 -297 ct +1775 -292 1787 -286 1796 -278 ct 1806 -270 1813 -261 1819 -250 ct 1825 -239 1829 -227 1831 -215 ct +1781 -211 l 1778 -227 1771 -241 1761 -250 ct 1751 -260 1736 -265 1716 -265 ct +1702 -265 1690 -263 1681 -258 ct 1672 -253 1664 -246 1658 -237 ct 1652 -227 1648 -215 1645 -201 ct +1643 -187 1642 -170 1642 -150 ct p ef +2003 -3 m 1995 -1 1987 1 1980 2 ct 1972 3 1963 4 1952 4 ct 1913 4 1893 -19 1893 -64 ct +1893 -263 l 1859 -263 l 1859 -299 l 1895 -299 l 1909 -366 l 1943 -366 l +1943 -299 l 1998 -299 l 1998 -263 l 1943 -263 l 1943 -74 l 1943 -60 1945 -50 1950 -44 ct +1954 -38 1962 -35 1974 -35 ct 1979 -35 1983 -36 1988 -37 ct 1992 -37 1997 -38 2003 -39 ct +2003 -3 l p ef +2297 -149 m 2297 -97 2286 -58 2263 -32 ct 2240 -7 2206 6 2163 6 ct 2142 6 2123 3 2107 -3 ct +2091 -10 2077 -19 2066 -32 ct 2054 -45 2046 -61 2040 -81 ct 2034 -100 2031 -123 2031 -149 ct +2031 -252 2075 -304 2164 -304 ct 2187 -304 2207 -300 2224 -294 ct 2241 -288 2255 -278 2265 -265 ct +2276 -252 2284 -236 2289 -217 ct 2294 -197 2297 -175 2297 -149 ct p +2245 -149 m 2245 -172 2243 -191 2240 -207 ct 2236 -222 2231 -234 2224 -243 ct +2217 -252 2209 -258 2199 -262 ct 2189 -265 2178 -267 2165 -267 ct 2152 -267 2141 -265 2131 -261 ct +2121 -258 2112 -251 2105 -242 ct 2098 -233 2092 -221 2088 -206 ct 2085 -191 2083 -172 2083 -149 ct +2083 -126 2085 -107 2089 -92 ct 2093 -76 2098 -64 2105 -55 ct 2113 -46 2121 -40 2131 -36 ct +2140 -33 2151 -31 2162 -31 ct 2175 -31 2186 -32 2196 -36 ct 2207 -40 2215 -46 2223 -55 ct +2230 -64 2235 -76 2239 -91 ct 2243 -107 2245 -126 2245 -149 ct p ef +2359 0 m 2359 -229 l 2359 -235 2359 -242 2359 -248 ct 2359 -255 2359 -261 2359 -267 ct +2358 -273 2358 -279 2358 -284 ct 2358 -289 2358 -294 2357 -298 ct 2404 -298 l +2404 -294 2405 -289 2405 -284 ct 2405 -279 2406 -273 2406 -267 ct 2406 -262 2406 -256 2406 -251 ct +2406 -246 2406 -241 2406 -238 ct 2408 -238 l 2411 -249 2415 -259 2419 -267 ct +2423 -276 2427 -282 2433 -288 ct 2438 -293 2444 -297 2452 -300 ct 2459 -303 2468 -304 2478 -304 ct +2482 -304 2486 -304 2490 -303 ct 2494 -302 2496 -302 2498 -301 ct 2498 -256 l +2495 -257 2491 -257 2487 -258 ct 2482 -258 2478 -258 2472 -258 ct 2461 -258 2451 -256 2443 -251 ct +2435 -246 2428 -238 2423 -229 ct 2418 -220 2415 -209 2412 -197 ct 2410 -184 2409 -170 2409 -156 ct +2409 0 l 2359 0 l p ef +pom +pum +23674 8314 t +112 -263 m 112 -303 l 112 -313 113 -322 113 -329 ct 114 -337 116 -345 117 -352 ct +119 -359 121 -365 124 -371 ct 127 -377 130 -383 134 -389 ct 167 -389 l 159 -377 153 -365 148 -353 ct +144 -341 141 -329 141 -317 ct 166 -317 l 166 -263 l 112 -263 l p +21 -263 m 21 -303 l 21 -313 21 -322 22 -329 ct 23 -337 24 -345 26 -352 ct +28 -359 30 -365 33 -371 ct 36 -377 39 -383 43 -389 ct 76 -389 l 68 -377 61 -365 57 -353 ct +52 -341 50 -329 50 -317 ct 74 -317 l 74 -263 l 21 -263 l p ef +pom +pum +23859 8314 t +232 -153 m 220 -153 207 -155 193 -159 ct 180 -163 167 -168 153 -172 ct 130 -181 110 -185 94 -185 ct +87 -185 80 -184 74 -183 ct 68 -182 63 -180 57 -178 ct 52 -176 46 -174 41 -171 ct +36 -168 31 -164 25 -160 ct 25 -200 l 35 -207 45 -212 57 -217 ct 69 -221 83 -223 98 -223 ct +105 -223 112 -222 120 -221 ct 127 -220 134 -219 141 -217 ct 148 -215 155 -213 162 -210 ct +169 -208 176 -206 183 -203 ct 187 -202 191 -200 196 -199 ct 200 -198 205 -196 209 -195 ct +214 -194 219 -193 223 -192 ct 228 -191 233 -191 237 -191 ct 250 -191 261 -193 273 -198 ct +284 -202 294 -208 304 -216 ct 304 -175 l 298 -171 293 -167 287 -165 ct 282 -162 276 -160 271 -158 ct +265 -156 259 -155 253 -154 ct 247 -153 240 -153 232 -153 ct p ef +680 -107 m 680 -90 677 -75 671 -62 ct 664 -48 655 -36 641 -26 ct 628 -16 612 -8 591 -2 ct +571 3 548 6 520 6 ct 472 6 434 -2 407 -19 ct 380 -36 363 -61 356 -93 ct 407 -103 l +409 -93 413 -84 418 -75 ct 424 -67 431 -60 440 -54 ct 449 -48 460 -43 474 -40 ct +487 -37 503 -35 522 -35 ct 538 -35 552 -36 565 -39 ct 578 -42 589 -46 599 -51 ct +608 -57 615 -64 620 -73 ct 626 -81 628 -92 628 -104 ct 628 -117 625 -127 620 -135 ct +614 -143 606 -149 595 -155 ct 585 -160 572 -164 558 -168 ct 543 -171 527 -175 510 -179 ct +499 -181 488 -184 477 -187 ct 466 -190 456 -193 446 -197 ct 436 -201 426 -206 417 -211 ct +408 -216 401 -223 394 -230 ct 388 -237 383 -246 379 -256 ct 376 -266 374 -277 374 -290 ct +374 -308 378 -324 385 -337 ct 392 -350 403 -361 416 -370 ct 429 -378 445 -384 463 -388 ct +481 -392 500 -394 521 -394 ct 545 -394 566 -392 583 -388 ct 600 -385 614 -379 626 -371 ct +638 -364 647 -355 654 -343 ct 661 -332 667 -319 671 -305 ct 619 -296 l 617 -305 613 -313 608 -321 ct +603 -328 597 -334 589 -339 ct 581 -344 572 -348 560 -350 ct 549 -353 536 -354 521 -354 ct +503 -354 487 -353 475 -349 ct 463 -346 453 -342 446 -336 ct 438 -331 433 -324 430 -317 ct +427 -309 425 -301 425 -293 ct 425 -281 428 -272 434 -264 ct 439 -257 447 -251 457 -246 ct +467 -241 479 -236 492 -233 ct 505 -230 519 -227 533 -223 ct 545 -220 557 -218 569 -215 ct +581 -212 592 -209 603 -205 ct 614 -201 624 -196 633 -191 ct 643 -185 651 -179 658 -171 ct +665 -163 670 -154 674 -144 ct 678 -133 680 -121 680 -107 ct p ef +698 112 m 698 76 l 1027 76 l 1027 112 l 698 112 l p ef +1238 -351 m 1216 -351 1197 -347 1180 -340 ct 1163 -333 1148 -322 1137 -308 ct +1125 -295 1117 -279 1111 -259 ct 1105 -240 1102 -219 1102 -196 ct 1102 -172 1105 -151 1112 -132 ct +1118 -112 1127 -95 1139 -81 ct 1151 -67 1165 -57 1182 -49 ct 1200 -41 1219 -37 1240 -37 ct +1255 -37 1269 -39 1281 -43 ct 1294 -47 1305 -53 1315 -60 ct 1325 -67 1334 -76 1342 -85 ct +1350 -95 1357 -106 1363 -118 ct 1406 -97 l 1399 -82 1390 -69 1380 -56 ct 1370 -44 1358 -33 1344 -24 ct +1330 -14 1314 -7 1297 -2 ct 1279 3 1260 6 1238 6 ct 1206 6 1179 1 1155 -9 ct 1132 -19 1112 -33 1096 -51 ct +1080 -69 1068 -90 1060 -115 ct 1053 -139 1049 -166 1049 -196 ct 1049 -226 1053 -253 1061 -278 ct +1070 -302 1082 -323 1098 -340 ct 1114 -358 1134 -371 1157 -380 ct 1181 -389 1207 -394 1238 -394 ct +1279 -394 1313 -386 1341 -370 ct 1369 -354 1389 -330 1402 -298 ct 1352 -281 l +1349 -290 1344 -299 1338 -308 ct 1331 -316 1323 -323 1314 -330 ct 1305 -336 1294 -341 1281 -345 ct +1269 -349 1254 -351 1238 -351 ct p ef +1465 -362 m 1465 -409 l 1514 -409 l 1514 -362 l 1465 -362 l p +1465 0 m 1465 -298 l 1514 -298 l 1514 0 l 1465 0 l p ef +1593 0 m 1593 -229 l 1593 -235 1593 -242 1593 -248 ct 1593 -255 1593 -261 1593 -267 ct +1592 -273 1592 -279 1592 -284 ct 1592 -289 1592 -294 1591 -298 ct 1638 -298 l +1638 -294 1639 -289 1639 -284 ct 1639 -279 1640 -273 1640 -267 ct 1640 -262 1640 -256 1640 -251 ct +1640 -246 1640 -241 1640 -238 ct 1642 -238 l 1645 -249 1649 -259 1653 -267 ct +1657 -276 1661 -282 1667 -288 ct 1672 -293 1678 -297 1686 -300 ct 1693 -303 1702 -304 1712 -304 ct +1716 -304 1720 -304 1724 -303 ct 1728 -302 1730 -302 1732 -301 ct 1732 -256 l +1729 -257 1725 -257 1721 -258 ct 1716 -258 1712 -258 1706 -258 ct 1695 -258 1685 -256 1677 -251 ct +1669 -246 1662 -238 1657 -229 ct 1652 -220 1649 -209 1646 -197 ct 1644 -184 1643 -170 1643 -156 ct +1643 0 l 1593 0 l p ef +1816 -150 m 1816 -133 1817 -117 1819 -103 ct 1822 -89 1826 -76 1832 -66 ct +1838 -56 1846 -47 1855 -42 ct 1865 -36 1877 -33 1891 -33 ct 1909 -33 1923 -38 1935 -47 ct +1947 -56 1954 -71 1957 -90 ct 2007 -90 l 2005 -78 2002 -65 1996 -54 ct 1991 -42 1983 -32 1974 -23 ct +1964 -14 1953 -7 1939 -2 ct 1926 3 1910 6 1892 6 ct 1869 6 1849 2 1833 -6 ct 1816 -14 1803 -25 1793 -39 ct +1783 -53 1775 -69 1771 -88 ct 1766 -107 1764 -127 1764 -149 ct 1764 -169 1766 -187 1769 -202 ct +1772 -218 1777 -231 1783 -243 ct 1789 -254 1796 -264 1804 -272 ct 1812 -280 1821 -286 1830 -291 ct +1840 -295 1850 -299 1860 -301 ct 1871 -303 1881 -304 1892 -304 ct 1908 -304 1923 -302 1936 -297 ct +1949 -292 1961 -286 1970 -278 ct 1980 -270 1987 -261 1993 -250 ct 1999 -239 2003 -227 2005 -215 ct +1955 -211 l 1952 -227 1945 -241 1935 -250 ct 1925 -260 1910 -265 1890 -265 ct +1876 -265 1864 -263 1855 -258 ct 1846 -253 1838 -246 1832 -237 ct 1826 -227 1822 -215 1819 -201 ct +1817 -187 1816 -170 1816 -150 ct p ef +2062 0 m 2062 -409 l 2112 -409 l 2112 0 l 2062 0 l p ef +2227 -138 m 2227 -122 2229 -108 2232 -95 ct 2235 -82 2240 -71 2247 -61 ct 2253 -52 2262 -44 2272 -39 ct +2283 -34 2295 -31 2310 -31 ct 2332 -31 2349 -36 2362 -44 ct 2375 -53 2384 -64 2388 -77 ct +2432 -65 l 2429 -56 2424 -48 2419 -40 ct 2413 -31 2405 -24 2396 -17 ct 2387 -10 2375 -5 2361 0 ct +2347 4 2330 6 2310 6 ct 2266 6 2233 -7 2210 -33 ct 2186 -60 2175 -99 2175 -151 ct +2175 -179 2178 -202 2185 -222 ct 2192 -241 2202 -257 2214 -269 ct 2226 -281 2240 -290 2256 -296 ct +2273 -301 2290 -304 2308 -304 ct 2333 -304 2354 -300 2371 -292 ct 2388 -283 2401 -272 2411 -258 ct +2422 -244 2429 -227 2433 -207 ct 2437 -188 2440 -167 2440 -145 ct 2440 -138 l +2227 -138 l p +2388 -176 m 2386 -208 2378 -231 2364 -245 ct 2351 -260 2332 -267 2307 -267 ct +2299 -267 2290 -266 2281 -263 ct 2272 -260 2264 -256 2256 -249 ct 2249 -242 2242 -233 2237 -221 ct +2231 -209 2228 -194 2228 -176 ct 2388 -176 l p ef +2631 -349 m 2631 -339 2631 -330 2630 -322 ct 2629 -314 2628 -307 2626 -300 ct +2624 -293 2622 -287 2619 -280 ct 2616 -274 2613 -268 2609 -263 ct 2576 -263 l +2584 -274 2591 -287 2595 -299 ct 2600 -311 2602 -323 2602 -335 ct 2578 -335 l +2578 -389 l 2631 -389 l 2631 -349 l p +2540 -349 m 2540 -339 2540 -330 2539 -322 ct 2538 -314 2537 -307 2535 -300 ct +2533 -293 2531 -287 2528 -280 ct 2525 -274 2522 -268 2519 -263 ct 2485 -263 l +2493 -274 2499 -287 2504 -299 ct 2508 -311 2511 -323 2511 -335 ct 2486 -335 l +2486 -389 l 2540 -389 l 2540 -349 l p ef +pom +1.000 1.000 1.000 c 8130 9715 m 7943 9715 7755 9903 7755 10091 ct 7755 10608 l +7755 10796 7943 10985 8130 10985 ct 11696 10985 l 11884 10985 12073 10796 12073 10608 ct +12073 10091 l 12073 9903 11884 9715 11696 9715 ct 8130 9715 l p +7755 9715 m 7755 9715 l p +12073 10985 m 12073 10985 l p ef +0.003 0.003 0.003 c 8130 9714 m 7942 9714 7754 9902 7754 10090 ct 7754 10607 l +7754 10795 7942 10984 8130 10984 ct 11696 10984 l 11884 10984 12073 10795 12073 10607 ct +12073 10090 l 12073 9902 11884 9714 11696 9714 ct 8130 9714 l pc +7754 9714 m 7754 9714 l pc +12073 10984 m 12073 10984 l pc +pum +8114 10556 t +274 0 m 213 0 165 -18 129 -54 ct 93 -90 75 -139 75 -200 ct 75 -261 93 -309 129 -345 ct +165 -381 213 -399 274 -399 ct 335 -399 383 -381 420 -345 ct 457 -309 475 -260 475 -200 ct +475 -139 457 -91 420 -54 ct 383 -18 335 0 274 0 ct p ef +pom +pum +8876 10521 t +191 -307 m 172 -307 155 -304 140 -298 ct 125 -291 112 -282 102 -270 ct 92 -258 85 -244 80 -227 ct +74 -210 72 -192 72 -171 ct 72 -151 75 -132 80 -115 ct 86 -98 94 -84 104 -72 ct +114 -59 127 -50 142 -43 ct 157 -36 174 -33 193 -33 ct 206 -33 218 -35 229 -38 ct +240 -42 250 -46 258 -53 ct 267 -59 275 -66 282 -75 ct 289 -84 295 -93 300 -104 ct +338 -85 l 332 -72 324 -60 315 -49 ct 306 -38 296 -29 284 -21 ct 271 -13 258 -6 242 -2 ct +227 3 210 5 191 5 ct 163 5 139 1 119 -8 ct 98 -17 81 -29 67 -45 ct 53 -61 42 -79 35 -101 ct +29 -122 25 -146 25 -171 ct 25 -198 29 -222 36 -243 ct 43 -265 54 -283 68 -298 ct +82 -313 100 -325 120 -333 ct 141 -341 164 -345 191 -345 ct 227 -345 257 -338 281 -324 ct +306 -310 323 -289 335 -261 ct 291 -246 l 288 -254 284 -262 278 -269 ct 273 -277 266 -283 258 -289 ct +249 -294 240 -299 229 -302 ct 218 -306 205 -307 191 -307 ct p ef +460 5 m 434 5 414 -2 401 -16 ct 388 -30 381 -49 381 -73 ct 381 -90 384 -105 391 -116 ct +397 -127 406 -135 416 -142 ct 427 -148 439 -152 452 -155 ct 466 -157 480 -158 494 -158 ct +552 -158 l 552 -173 l 552 -184 551 -193 549 -201 ct 547 -208 543 -215 538 -219 ct +534 -224 528 -227 521 -230 ct 514 -232 506 -233 496 -233 ct 488 -233 480 -232 474 -231 ct +467 -230 461 -228 456 -225 ct 451 -221 447 -217 444 -212 ct 441 -206 439 -200 438 -191 ct +393 -195 l 394 -206 397 -215 402 -224 ct 406 -232 413 -240 421 -246 ct 429 -252 440 -257 452 -261 ct +464 -264 480 -266 497 -266 ct 530 -266 555 -258 571 -243 ct 588 -228 596 -207 596 -178 ct +596 -66 l 596 -53 598 -43 601 -37 ct 605 -30 611 -27 621 -27 ct 623 -27 625 -27 628 -27 ct +630 -28 632 -28 635 -28 ct 635 -2 l 629 0 624 1 618 1 ct 613 2 607 2 601 2 ct +593 2 586 1 580 -1 ct 574 -3 569 -6 566 -11 ct 562 -15 559 -21 557 -27 ct 555 -34 554 -41 554 -50 ct +552 -50 l 548 -41 542 -34 537 -27 ct 531 -20 525 -15 518 -10 ct 510 -5 502 -1 492 1 ct +483 4 472 5 460 5 ct p +470 -28 m 484 -28 496 -30 506 -35 ct 516 -40 525 -47 532 -54 ct 539 -62 544 -71 547 -80 ct +551 -89 552 -98 552 -107 ct 552 -128 l 505 -128 l 494 -128 484 -127 474 -126 ct +465 -125 456 -122 449 -118 ct 442 -114 436 -108 432 -101 ct 428 -94 426 -84 426 -72 ct +426 -58 429 -47 437 -39 ct 445 -31 456 -28 470 -28 ct p ef +668 0 m 668 -358 l 712 -358 l 712 0 l 668 0 l p ef +778 0 m 778 -358 l 822 -358 l 822 0 l 778 0 l p ef +pom +1.000 1.000 1.000 c 13572 10986 m 13383 10986 13195 11174 13195 11363 ct +13195 11879 l 13195 12068 13383 12257 13572 12257 ct 17136 12257 l 17325 12257 17514 12068 17514 11879 ct +17514 11363 l 17514 11174 17325 10986 17136 10986 ct 13572 10986 l p +13195 10986 m 13195 10986 l p +17514 12257 m 17514 12257 l p ef +0.003 0.003 0.003 c 13572 10985 m 13383 10985 13195 11173 13195 11362 ct 13195 11878 l +13195 12067 13383 12256 13572 12256 ct 17135 12256 l 17324 12256 17513 12067 17513 11878 ct +17513 11362 l 17513 11173 17324 10985 17135 10985 ct 13572 10985 l pc +13195 10985 m 13195 10985 l pc +17513 12256 m 17513 12256 l pc +pum +13555 11828 t +274 0 m 213 0 165 -18 129 -54 ct 93 -90 75 -139 75 -200 ct 75 -261 93 -309 129 -345 ct +165 -381 213 -399 274 -399 ct 335 -399 383 -381 420 -345 ct 457 -309 475 -260 475 -200 ct +475 -139 457 -91 420 -54 ct 383 -18 335 0 274 0 ct p ef +pom +pum +14317 11793 t +307 -94 m 307 -79 304 -66 299 -54 ct 293 -42 284 -32 273 -23 ct 261 -14 247 -7 229 -2 ct +211 3 191 5 166 5 ct 124 5 91 -2 68 -17 ct 44 -32 29 -53 22 -81 ct 67 -90 l 69 -81 73 -73 77 -66 ct +82 -59 88 -53 96 -48 ct 104 -42 114 -38 126 -35 ct 138 -32 152 -31 168 -31 ct 182 -31 194 -32 206 -34 ct +217 -37 227 -40 235 -45 ct 243 -50 250 -56 254 -64 ct 259 -72 261 -81 261 -91 ct +261 -102 259 -111 254 -118 ct 249 -125 241 -131 232 -135 ct 223 -140 212 -144 199 -147 ct +187 -150 173 -153 157 -157 ct 148 -159 138 -161 129 -164 ct 119 -166 110 -169 101 -173 ct +92 -176 84 -180 76 -185 ct 69 -189 62 -195 56 -202 ct 51 -208 46 -216 43 -224 ct +40 -233 38 -243 38 -254 ct 38 -270 42 -284 48 -295 ct 55 -307 64 -316 75 -324 ct +87 -331 101 -337 116 -340 ct 132 -343 149 -345 167 -345 ct 188 -345 206 -343 221 -340 ct +236 -337 249 -332 259 -325 ct 270 -319 278 -310 284 -301 ct 290 -291 295 -280 299 -267 ct +254 -259 l 251 -267 248 -274 244 -281 ct 239 -287 234 -293 227 -297 ct 220 -301 212 -305 202 -307 ct +192 -309 180 -310 167 -310 ct 151 -310 138 -309 127 -306 ct 117 -303 108 -299 101 -295 ct +95 -290 90 -284 87 -278 ct 85 -271 83 -264 83 -256 ct 83 -246 86 -238 91 -231 ct +96 -225 103 -219 111 -215 ct 120 -211 130 -207 142 -204 ct 153 -201 165 -198 178 -196 ct +188 -193 199 -191 209 -188 ct 220 -186 230 -183 239 -179 ct 249 -176 257 -172 266 -167 ct +274 -162 281 -157 287 -150 ct 293 -143 298 -135 302 -126 ct 305 -117 307 -106 307 -94 ct +p ef +397 -121 m 397 -107 398 -95 401 -83 ct 404 -72 408 -62 414 -54 ct 420 -45 427 -39 436 -34 ct +446 -30 457 -28 469 -28 ct 488 -28 503 -31 515 -39 ct 526 -46 534 -56 538 -68 ct +576 -57 l 573 -49 569 -42 564 -35 ct 559 -28 553 -21 545 -15 ct 536 -9 526 -4 514 -1 ct +502 3 487 5 469 5 ct 431 5 401 -7 381 -30 ct 361 -53 351 -87 351 -132 ct 351 -157 354 -177 360 -194 ct +366 -211 375 -225 385 -236 ct 396 -246 408 -254 422 -259 ct 437 -264 452 -266 468 -266 ct +490 -266 508 -262 523 -255 ct 537 -248 549 -238 558 -226 ct 567 -213 573 -199 577 -182 ct +581 -165 583 -147 583 -127 ct 583 -121 l 397 -121 l p +538 -154 m 536 -182 529 -202 517 -215 ct 505 -228 489 -234 467 -234 ct 460 -234 452 -233 444 -230 ct +436 -228 429 -224 422 -218 ct 415 -212 410 -204 405 -193 ct 400 -183 398 -170 397 -154 ct +538 -154 l p ef +739 -2 m 732 0 725 1 718 2 ct 712 3 704 4 695 4 ct 660 4 643 -16 643 -55 ct 643 -229 l +612 -229 l 612 -261 l 644 -261 l 657 -320 l 686 -320 l 686 -261 l +734 -261 l 734 -229 l 686 -229 l 686 -65 l 686 -52 688 -43 692 -38 ct +696 -33 703 -31 714 -31 ct 718 -31 722 -31 726 -31 ct 730 -32 734 -33 739 -34 ct +739 -2 l p ef +pom +1.000 1.000 1.000 c 13572 12256 m 13383 12256 13195 12444 13195 12632 ct +13195 13148 l 13195 13337 13383 13526 13572 13526 ct 17136 13526 l 17325 13526 17514 13337 17514 13148 ct +17514 12632 l 17514 12444 17325 12256 17136 12256 ct 13572 12256 l p +13195 12256 m 13195 12256 l p +17514 13526 m 17514 13526 l p ef +0.003 0.003 0.003 c 13572 12255 m 13383 12255 13195 12443 13195 12632 ct 13195 13148 l +13195 13337 13383 13526 13572 13526 ct 17135 13526 l 17324 13526 17513 13337 17513 13148 ct +17513 12632 l 17513 12443 17324 12255 17135 12255 ct 13572 12255 l pc +13195 12255 m 13195 12255 l pc +17513 13526 m 17513 13526 l pc +pum +13555 13097 t +274 0 m 213 0 165 -18 129 -54 ct 93 -90 75 -139 75 -200 ct 75 -261 93 -309 129 -345 ct +165 -381 213 -399 274 -399 ct 335 -399 383 -381 420 -345 ct 457 -309 475 -260 475 -200 ct +475 -139 457 -91 420 -54 ct 383 -18 335 0 274 0 ct p ef +pom +pum +14317 13062 t +303 -96 m 303 -79 300 -64 293 -52 ct 287 -40 277 -30 266 -22 ct 255 -14 241 -9 226 -5 ct +211 -2 195 0 179 0 ct 41 0 l 41 -340 l 164 -340 l 183 -340 200 -338 214 -335 ct +229 -332 242 -327 252 -321 ct 262 -314 270 -305 276 -295 ct 281 -285 284 -272 284 -258 ct +284 -248 282 -239 280 -231 ct 277 -223 273 -215 268 -208 ct 262 -201 255 -196 247 -191 ct +239 -186 230 -182 219 -180 ct 233 -178 245 -175 255 -170 ct 266 -166 275 -160 282 -152 ct +289 -145 294 -137 298 -127 ct 302 -118 303 -107 303 -96 ct p +237 -252 m 237 -270 231 -283 219 -291 ct 206 -299 188 -303 164 -303 ct 87 -303 l +87 -196 l 164 -196 l 178 -196 189 -197 198 -200 ct 208 -203 215 -206 221 -211 ct +227 -216 231 -222 234 -229 ct 236 -236 237 -244 237 -252 ct p +257 -100 m 257 -111 255 -120 251 -127 ct 247 -135 241 -141 234 -146 ct 227 -151 218 -154 207 -157 ct +197 -159 185 -160 172 -160 ct 87 -160 l 87 -37 l 176 -37 l 188 -37 199 -38 209 -40 ct +218 -42 227 -45 234 -50 ct 241 -55 247 -61 251 -69 ct 255 -77 257 -88 257 -100 ct +p ef +406 -261 m 406 -95 l 406 -83 407 -72 409 -64 ct 410 -55 413 -48 418 -43 ct +422 -38 427 -34 434 -32 ct 441 -30 449 -29 460 -29 ct 470 -29 479 -30 487 -34 ct +496 -38 503 -43 509 -50 ct 514 -57 519 -65 522 -75 ct 525 -85 527 -97 527 -110 ct +527 -261 l 570 -261 l 570 -56 l 570 -50 571 -44 571 -38 ct 571 -32 571 -27 571 -21 ct +571 -16 571 -11 571 -7 ct 572 -3 572 -1 572 0 ct 531 0 l 531 -1 531 -3 530 -6 ct +530 -10 530 -14 530 -19 ct 530 -23 529 -28 529 -33 ct 529 -37 529 -41 529 -44 ct +528 -44 l 524 -37 520 -30 515 -24 ct 510 -18 504 -13 497 -8 ct 491 -4 483 -1 474 2 ct +466 4 456 5 445 5 ct 430 5 418 3 407 0 ct 397 -4 388 -9 382 -17 ct 375 -24 370 -34 367 -45 ct +364 -57 362 -71 362 -87 ct 362 -261 l 406 -261 l p ef +638 -316 m 638 -358 l 681 -358 l 681 -316 l 638 -316 l p +638 0 m 638 -261 l 681 -261 l 681 0 l 638 0 l p ef +748 0 m 748 -358 l 792 -358 l 792 0 l 748 0 l p ef +960 -2 m 953 0 946 1 939 2 ct 933 3 925 4 916 4 ct 881 4 864 -16 864 -55 ct 864 -229 l +833 -229 l 833 -261 l 865 -261 l 878 -320 l 907 -320 l 907 -261 l +955 -261 l 955 -229 l 907 -229 l 907 -65 l 907 -52 909 -43 913 -38 ct +917 -33 924 -31 935 -31 ct 939 -31 943 -31 947 -31 ct 951 -32 955 -33 960 -34 ct +960 -2 l p ef +998 -316 m 998 -358 l 1041 -358 l 1041 -316 l 998 -316 l p +998 0 m 998 -261 l 1041 -261 l 1041 0 l 998 0 l p ef +1274 0 m 1274 -166 l 1274 -178 1273 -189 1271 -197 ct 1269 -206 1266 -213 1262 -218 ct +1258 -223 1252 -227 1246 -229 ct 1239 -231 1230 -232 1220 -232 ct 1210 -232 1201 -231 1192 -227 ct +1184 -223 1177 -218 1171 -211 ct 1165 -205 1161 -196 1157 -186 ct 1154 -176 1153 -164 1153 -151 ct +1153 0 l 1109 0 l 1109 -205 l 1109 -211 1109 -217 1109 -223 ct 1109 -229 1109 -234 1109 -240 ct +1109 -245 1108 -250 1108 -254 ct 1108 -258 1108 -260 1108 -261 ct 1149 -261 l +1149 -260 1149 -258 1149 -255 ct 1149 -251 1150 -247 1150 -242 ct 1150 -238 1150 -233 1151 -228 ct +1151 -224 1151 -220 1151 -217 ct 1151 -217 l 1156 -224 1160 -231 1165 -237 ct +1170 -243 1176 -248 1183 -253 ct 1189 -257 1197 -260 1205 -263 ct 1214 -265 1224 -266 1235 -266 ct +1249 -266 1262 -264 1272 -261 ct 1283 -257 1291 -252 1298 -244 ct 1305 -237 1310 -227 1313 -216 ct +1316 -204 1318 -190 1318 -174 ct 1318 0 l 1274 0 l p ef +pom +1.000 1.000 1.000 c 23374 9709 m 23185 9709 22997 9897 22997 10086 ct 22997 10602 l +22997 10791 23185 10980 23374 10980 ct 26937 10980 l 27126 10980 27315 10791 27315 10602 ct +27315 10086 l 27315 9897 27126 9709 26937 9709 ct 23374 9709 l p +22997 9709 m 22997 9709 l p +27315 10980 m 27315 10980 l p ef +0.003 0.003 0.003 c 23373 9708 m 23184 9708 22996 9896 22996 10085 ct 22996 10601 l +22996 10790 23184 10979 23373 10979 ct 26937 10979 l 27126 10979 27315 10790 27315 10601 ct +27315 10085 l 27315 9896 27126 9708 26937 9708 ct 23373 9708 l pc +22996 9708 m 22996 9708 l pc +27315 10979 m 27315 10979 l pc +pum +23357 10551 t +274 0 m 213 0 165 -18 129 -54 ct 93 -90 75 -139 75 -200 ct 75 -261 93 -309 129 -345 ct +165 -381 213 -399 274 -399 ct 335 -399 383 -381 420 -345 ct 457 -309 475 -260 475 -200 ct +475 -139 457 -91 420 -54 ct 383 -18 335 0 274 0 ct p ef +pom +pum +24118 10516 t +333 -173 m 333 -145 329 -120 320 -99 ct 312 -77 300 -59 285 -44 ct 271 -30 253 -19 233 -11 ct +213 -4 191 0 168 0 ct 41 0 l 41 -340 l 153 -340 l 179 -340 203 -337 225 -330 ct +248 -324 267 -314 282 -300 ct 298 -286 311 -269 320 -248 ct 329 -227 333 -202 333 -173 ct +p +287 -173 m 287 -197 284 -216 277 -233 ct 270 -249 261 -262 249 -273 ct 237 -283 223 -291 206 -296 ct +190 -301 172 -303 152 -303 ct 87 -303 l 87 -37 l 162 -37 l 180 -37 197 -40 212 -46 ct +227 -51 240 -60 251 -71 ct 262 -83 271 -97 277 -114 ct 284 -131 287 -151 287 -173 ct +p ef +427 -121 m 427 -107 428 -95 431 -83 ct 434 -72 438 -62 444 -54 ct 450 -45 457 -39 466 -34 ct +476 -30 487 -28 499 -28 ct 518 -28 533 -31 545 -39 ct 556 -46 564 -56 568 -68 ct +606 -57 l 603 -49 599 -42 594 -35 ct 589 -28 583 -21 575 -15 ct 566 -9 556 -4 544 -1 ct +532 3 517 5 499 5 ct 461 5 431 -7 411 -30 ct 391 -53 381 -87 381 -132 ct 381 -157 384 -177 390 -194 ct +396 -211 405 -225 415 -236 ct 426 -246 438 -254 452 -259 ct 467 -264 482 -266 498 -266 ct +520 -266 538 -262 553 -255 ct 567 -248 579 -238 588 -226 ct 597 -213 603 -199 607 -182 ct +611 -165 613 -147 613 -127 ct 613 -121 l 427 -121 l p +568 -154 m 566 -182 559 -202 547 -215 ct 535 -228 519 -234 497 -234 ct 490 -234 482 -233 474 -230 ct +466 -228 459 -224 452 -218 ct 445 -212 440 -204 435 -193 ct 430 -183 428 -170 427 -154 ct +568 -154 l p ef +864 -72 m 864 -60 862 -49 857 -39 ct 852 -30 845 -22 836 -15 ct 827 -9 816 -4 803 0 ct +790 3 775 5 758 5 ct 743 5 730 4 717 2 ct 705 -1 695 -5 685 -10 ct 676 -15 669 -22 662 -30 ct +656 -39 652 -49 649 -61 ct 687 -69 l 691 -55 698 -44 710 -38 ct 722 -31 738 -28 758 -28 ct +768 -28 776 -29 784 -30 ct 792 -31 798 -34 804 -37 ct 810 -40 814 -44 817 -49 ct +820 -54 822 -61 822 -69 ct 822 -76 820 -83 816 -88 ct 813 -93 808 -97 801 -101 ct +794 -104 786 -107 777 -110 ct 768 -112 757 -115 746 -118 ct 736 -121 725 -124 715 -127 ct +705 -130 695 -135 687 -140 ct 679 -146 672 -153 667 -161 ct 662 -169 659 -180 659 -192 ct +659 -216 668 -234 685 -246 ct 702 -259 726 -265 759 -265 ct 788 -265 810 -260 827 -250 ct +844 -240 855 -223 860 -201 ct 820 -196 l 819 -203 816 -209 813 -213 ct 809 -218 804 -222 799 -224 ct +793 -227 787 -229 780 -230 ct 773 -232 766 -232 759 -232 ct 739 -232 725 -229 715 -223 ct +706 -217 701 -208 701 -196 ct 701 -189 703 -183 707 -179 ct 710 -174 715 -170 721 -167 ct +727 -164 735 -161 743 -159 ct 752 -157 762 -154 772 -152 ct 779 -150 786 -148 793 -146 ct +800 -144 808 -142 814 -139 ct 821 -136 828 -133 834 -129 ct 840 -125 845 -120 849 -115 ct +854 -110 858 -104 860 -97 ct 863 -90 864 -81 864 -72 ct p ef +1019 -2 m 1012 0 1005 1 998 2 ct 992 3 984 4 975 4 ct 940 4 923 -16 923 -55 ct +923 -229 l 892 -229 l 892 -261 l 924 -261 l 937 -320 l 966 -320 l +966 -261 l 1014 -261 l 1014 -229 l 966 -229 l 966 -65 l 966 -52 968 -43 972 -38 ct +976 -33 983 -31 994 -31 ct 998 -31 1002 -31 1006 -31 ct 1010 -32 1014 -33 1019 -34 ct +1019 -2 l p ef +1058 0 m 1058 -200 l 1058 -206 1058 -211 1058 -217 ct 1058 -223 1058 -228 1058 -234 ct +1058 -239 1057 -244 1057 -249 ct 1057 -253 1057 -257 1057 -261 ct 1098 -261 l +1098 -257 1098 -253 1098 -249 ct 1099 -244 1099 -239 1099 -234 ct 1099 -229 1100 -224 1100 -220 ct +1100 -215 1100 -211 1100 -208 ct 1101 -208 l 1104 -218 1107 -226 1110 -234 ct +1114 -241 1118 -247 1123 -252 ct 1127 -257 1133 -260 1139 -263 ct 1146 -265 1154 -266 1163 -266 ct +1166 -266 1170 -266 1173 -265 ct 1176 -265 1179 -264 1180 -264 ct 1180 -224 l +1177 -225 1174 -225 1170 -226 ct 1166 -226 1162 -226 1157 -226 ct 1147 -226 1139 -224 1132 -219 ct +1125 -215 1119 -209 1115 -201 ct 1110 -193 1107 -183 1105 -172 ct 1103 -161 1102 -149 1102 -136 ct +1102 0 l 1058 0 l p ef +1266 -261 m 1266 -95 l 1266 -83 1267 -72 1269 -64 ct 1270 -55 1273 -48 1278 -43 ct +1282 -38 1287 -34 1294 -32 ct 1301 -30 1309 -29 1320 -29 ct 1330 -29 1339 -30 1347 -34 ct +1356 -38 1363 -43 1369 -50 ct 1374 -57 1379 -65 1382 -75 ct 1385 -85 1387 -97 1387 -110 ct +1387 -261 l 1430 -261 l 1430 -56 l 1430 -50 1431 -44 1431 -38 ct 1431 -32 1431 -27 1431 -21 ct +1431 -16 1431 -11 1431 -7 ct 1432 -3 1432 -1 1432 0 ct 1391 0 l 1391 -1 1391 -3 1390 -6 ct +1390 -10 1390 -14 1390 -19 ct 1390 -23 1389 -28 1389 -33 ct 1389 -37 1389 -41 1389 -44 ct +1388 -44 l 1384 -37 1380 -30 1375 -24 ct 1370 -18 1364 -13 1357 -8 ct 1351 -4 1343 -1 1334 2 ct +1326 4 1316 5 1305 5 ct 1290 5 1278 3 1267 0 ct 1257 -4 1248 -9 1242 -17 ct 1235 -24 1230 -34 1227 -45 ct +1224 -57 1222 -71 1222 -87 ct 1222 -261 l 1266 -261 l p ef +1531 -132 m 1531 -117 1532 -103 1535 -90 ct 1537 -78 1540 -67 1546 -58 ct 1551 -49 1558 -42 1566 -37 ct +1574 -32 1585 -29 1597 -29 ct 1613 -29 1626 -33 1636 -41 ct 1646 -50 1653 -62 1655 -79 ct +1699 -79 l 1698 -68 1694 -58 1690 -47 ct 1685 -37 1678 -28 1670 -21 ct 1662 -13 1652 -7 1640 -2 ct +1628 3 1614 5 1598 5 ct 1578 5 1561 2 1546 -5 ct 1532 -12 1520 -22 1511 -34 ct +1503 -46 1496 -60 1492 -77 ct 1488 -94 1486 -111 1486 -131 ct 1486 -148 1487 -164 1490 -177 ct +1493 -191 1497 -202 1503 -213 ct 1508 -223 1514 -231 1521 -238 ct 1528 -245 1536 -250 1544 -254 ct +1552 -258 1561 -261 1570 -263 ct 1579 -265 1589 -266 1598 -266 ct 1613 -266 1626 -264 1637 -260 ct +1648 -256 1658 -250 1667 -243 ct 1675 -236 1682 -228 1687 -219 ct 1692 -209 1695 -199 1698 -188 ct +1653 -185 l 1651 -199 1645 -211 1636 -219 ct 1627 -228 1614 -232 1597 -232 ct +1584 -232 1574 -230 1566 -226 ct 1557 -222 1551 -216 1546 -207 ct 1540 -199 1537 -188 1535 -176 ct +1532 -163 1531 -149 1531 -132 ct p ef +1849 -2 m 1842 0 1835 1 1828 2 ct 1822 3 1814 4 1805 4 ct 1770 4 1753 -16 1753 -55 ct +1753 -229 l 1722 -229 l 1722 -261 l 1754 -261 l 1767 -320 l 1796 -320 l +1796 -261 l 1844 -261 l 1844 -229 l 1796 -229 l 1796 -65 l 1796 -52 1798 -43 1802 -38 ct +1806 -33 1813 -31 1824 -31 ct 1828 -31 1832 -31 1836 -31 ct 1840 -32 1844 -33 1849 -34 ct +1849 -2 l p ef +1887 -316 m 1887 -358 l 1930 -358 l 1930 -316 l 1887 -316 l p +1887 0 m 1887 -261 l 1930 -261 l 1930 0 l 1887 0 l p ef +2218 -131 m 2218 -85 2208 -51 2188 -29 ct 2168 -6 2139 5 2100 5 ct 2082 5 2066 2 2052 -3 ct +2037 -9 2025 -17 2015 -28 ct 2005 -40 1998 -54 1993 -71 ct 1987 -88 1985 -108 1985 -131 ct +1985 -221 2024 -266 2102 -266 ct 2122 -266 2139 -263 2154 -258 ct 2169 -252 2181 -243 2190 -232 ct +2200 -221 2207 -207 2211 -190 ct 2216 -173 2218 -153 2218 -131 ct p +2172 -131 m 2172 -151 2171 -168 2168 -181 ct 2165 -194 2160 -205 2154 -213 ct +2148 -221 2141 -226 2132 -229 ct 2123 -232 2113 -234 2102 -234 ct 2091 -234 2081 -232 2072 -229 ct +2064 -226 2056 -220 2050 -212 ct 2043 -204 2039 -193 2035 -180 ct 2032 -167 2030 -151 2030 -131 ct +2030 -110 2032 -94 2036 -80 ct 2039 -67 2044 -57 2050 -49 ct 2056 -41 2064 -35 2072 -32 ct +2081 -29 2090 -27 2100 -27 ct 2111 -27 2121 -29 2130 -32 ct 2139 -35 2147 -40 2153 -48 ct +2159 -56 2164 -67 2167 -80 ct 2171 -94 2172 -110 2172 -131 ct p ef +2438 0 m 2438 -166 l 2438 -178 2437 -189 2435 -197 ct 2433 -206 2430 -213 2426 -218 ct +2422 -223 2416 -227 2410 -229 ct 2403 -231 2394 -232 2384 -232 ct 2374 -232 2365 -231 2356 -227 ct +2348 -223 2341 -218 2335 -211 ct 2329 -205 2325 -196 2321 -186 ct 2318 -176 2317 -164 2317 -151 ct +2317 0 l 2273 0 l 2273 -205 l 2273 -211 2273 -217 2273 -223 ct 2273 -229 2273 -234 2273 -240 ct +2273 -245 2272 -250 2272 -254 ct 2272 -258 2272 -260 2272 -261 ct 2313 -261 l +2313 -260 2313 -258 2313 -255 ct 2313 -251 2314 -247 2314 -242 ct 2314 -238 2314 -233 2315 -228 ct +2315 -224 2315 -220 2315 -217 ct 2315 -217 l 2320 -224 2324 -231 2329 -237 ct +2334 -243 2340 -248 2347 -253 ct 2353 -257 2361 -260 2369 -263 ct 2378 -265 2388 -266 2399 -266 ct +2413 -266 2426 -264 2436 -261 ct 2447 -257 2455 -252 2462 -244 ct 2469 -237 2474 -227 2477 -216 ct +2480 -204 2482 -190 2482 -174 ct 2482 0 l 2438 0 l p ef +pom +1.000 1.000 1.000 c 8131 8446 m 7943 8446 7755 8634 7755 8823 ct 7755 9339 l +7755 9528 7943 9717 8131 9717 ct 11695 9717 l 11884 9717 12073 9528 12073 9339 ct +12073 8823 l 12073 8634 11884 8446 11695 8446 ct 8131 8446 l p +7755 8446 m 7755 8446 l p +12073 9717 m 12073 9717 l p ef +0.003 0.003 0.003 c 8131 8445 m 7942 8445 7754 8633 7754 8822 ct 7754 9338 l +7754 9527 7942 9716 8131 9716 ct 11695 9716 l 11884 9716 12073 9527 12073 9338 ct +12073 8822 l 12073 8633 11884 8445 11695 8445 ct 8131 8445 l pc +7754 8445 m 7754 8445 l pc +12073 9716 m 12073 9716 l pc +pum +8114 9288 t +274 0 m 213 0 165 -18 129 -54 ct 93 -90 75 -139 75 -200 ct 75 -261 93 -309 129 -345 ct +165 -381 213 -399 274 -399 ct 335 -399 383 -381 420 -345 ct 457 -309 475 -260 475 -200 ct +475 -139 457 -91 420 -54 ct 383 -18 335 0 274 0 ct p ef +pom +pum +8876 9253 t +191 -307 m 172 -307 155 -304 140 -298 ct 125 -291 112 -282 102 -270 ct 92 -258 85 -244 80 -227 ct +74 -210 72 -192 72 -171 ct 72 -151 75 -132 80 -115 ct 86 -98 94 -84 104 -72 ct +114 -59 127 -50 142 -43 ct 157 -36 174 -33 193 -33 ct 206 -33 218 -35 229 -38 ct +240 -42 250 -46 258 -53 ct 267 -59 275 -66 282 -75 ct 289 -84 295 -93 300 -104 ct +338 -85 l 332 -72 324 -60 315 -49 ct 306 -38 296 -29 284 -21 ct 271 -13 258 -6 242 -2 ct +227 3 210 5 191 5 ct 163 5 139 1 119 -8 ct 98 -17 81 -29 67 -45 ct 53 -61 42 -79 35 -101 ct +29 -122 25 -146 25 -171 ct 25 -198 29 -222 36 -243 ct 43 -265 54 -283 68 -298 ct +82 -313 100 -325 120 -333 ct 141 -341 164 -345 191 -345 ct 227 -345 257 -338 281 -324 ct +306 -310 323 -289 335 -261 ct 291 -246 l 288 -254 284 -262 278 -269 ct 273 -277 266 -283 258 -289 ct +249 -294 240 -299 229 -302 ct 218 -306 205 -307 191 -307 ct p ef +460 5 m 434 5 414 -2 401 -16 ct 388 -30 381 -49 381 -73 ct 381 -90 384 -105 391 -116 ct +397 -127 406 -135 416 -142 ct 427 -148 439 -152 452 -155 ct 466 -157 480 -158 494 -158 ct +552 -158 l 552 -173 l 552 -184 551 -193 549 -201 ct 547 -208 543 -215 538 -219 ct +534 -224 528 -227 521 -230 ct 514 -232 506 -233 496 -233 ct 488 -233 480 -232 474 -231 ct +467 -230 461 -228 456 -225 ct 451 -221 447 -217 444 -212 ct 441 -206 439 -200 438 -191 ct +393 -195 l 394 -206 397 -215 402 -224 ct 406 -232 413 -240 421 -246 ct 429 -252 440 -257 452 -261 ct +464 -264 480 -266 497 -266 ct 530 -266 555 -258 571 -243 ct 588 -228 596 -207 596 -178 ct +596 -66 l 596 -53 598 -43 601 -37 ct 605 -30 611 -27 621 -27 ct 623 -27 625 -27 628 -27 ct +630 -28 632 -28 635 -28 ct 635 -2 l 629 0 624 1 618 1 ct 613 2 607 2 601 2 ct +593 2 586 1 580 -1 ct 574 -3 569 -6 566 -11 ct 562 -15 559 -21 557 -27 ct 555 -34 554 -41 554 -50 ct +552 -50 l 548 -41 542 -34 537 -27 ct 531 -20 525 -15 518 -10 ct 510 -5 502 -1 492 1 ct +483 4 472 5 460 5 ct p +470 -28 m 484 -28 496 -30 506 -35 ct 516 -40 525 -47 532 -54 ct 539 -62 544 -71 547 -80 ct +551 -89 552 -98 552 -107 ct 552 -128 l 505 -128 l 494 -128 484 -127 474 -126 ct +465 -125 456 -122 449 -118 ct 442 -114 436 -108 432 -101 ct 428 -94 426 -84 426 -72 ct +426 -58 429 -47 437 -39 ct 445 -31 456 -28 470 -28 ct p ef +668 0 m 668 -358 l 712 -358 l 712 0 l 668 0 l p ef +778 0 m 778 -358 l 822 -358 l 822 0 l 778 0 l p ef +pom +1.000 1.000 1.000 c 1462 5768 m 1273 5768 1085 5956 1085 6145 ct 1085 6661 l +1085 6850 1273 7039 1462 7039 ct 5026 7039 l 5215 7039 5404 6850 5404 6661 ct +5404 6145 l 5404 5956 5215 5768 5026 5768 ct 1462 5768 l p +1085 5768 m 1085 5768 l p +5404 7039 m 5404 7039 l p ef +0.003 0.003 0.003 c 1461 5768 m 1272 5768 1084 5956 1084 6145 ct 1084 6661 l +1084 6850 1272 7039 1461 7039 ct 5025 7039 l 5214 7039 5403 6850 5403 6661 ct +5403 6145 l 5403 5956 5214 5768 5025 5768 ct 1461 5768 l pc +1084 5768 m 1084 5768 l pc +5403 7039 m 5403 7039 l pc +pum +1445 6610 t +274 0 m 213 0 165 -18 129 -54 ct 93 -90 75 -139 75 -200 ct 75 -261 93 -309 129 -345 ct +165 -381 213 -399 274 -399 ct 335 -399 383 -381 420 -345 ct 457 -309 475 -260 475 -200 ct +475 -139 457 -91 420 -54 ct 383 -18 335 0 274 0 ct p ef +pom +pum +2207 6575 t +191 -307 m 172 -307 155 -304 140 -298 ct 125 -291 112 -282 102 -270 ct 92 -258 85 -244 80 -227 ct +74 -210 72 -192 72 -171 ct 72 -151 75 -132 80 -115 ct 86 -98 94 -84 104 -72 ct +114 -59 127 -50 142 -43 ct 157 -36 174 -33 193 -33 ct 206 -33 218 -35 229 -38 ct +240 -42 250 -46 258 -53 ct 267 -59 275 -66 282 -75 ct 289 -84 295 -93 300 -104 ct +338 -85 l 332 -72 324 -60 315 -49 ct 306 -38 296 -29 284 -21 ct 271 -13 258 -6 242 -2 ct +227 3 210 5 191 5 ct 163 5 139 1 119 -8 ct 98 -17 81 -29 67 -45 ct 53 -61 42 -79 35 -101 ct +29 -122 25 -146 25 -171 ct 25 -198 29 -222 36 -243 ct 43 -265 54 -283 68 -298 ct +82 -313 100 -325 120 -333 ct 141 -341 164 -345 191 -345 ct 227 -345 257 -338 281 -324 ct +306 -310 323 -289 335 -261 ct 291 -246 l 288 -254 284 -262 278 -269 ct 273 -277 266 -283 258 -289 ct +249 -294 240 -299 229 -302 ct 218 -306 205 -307 191 -307 ct p ef +460 5 m 434 5 414 -2 401 -16 ct 388 -30 381 -49 381 -73 ct 381 -90 384 -105 391 -116 ct +397 -127 406 -135 416 -142 ct 427 -148 439 -152 452 -155 ct 466 -157 480 -158 494 -158 ct +552 -158 l 552 -173 l 552 -184 551 -193 549 -201 ct 547 -208 543 -215 538 -219 ct +534 -224 528 -227 521 -230 ct 514 -232 506 -233 496 -233 ct 488 -233 480 -232 474 -231 ct +467 -230 461 -228 456 -225 ct 451 -221 447 -217 444 -212 ct 441 -206 439 -200 438 -191 ct +393 -195 l 394 -206 397 -215 402 -224 ct 406 -232 413 -240 421 -246 ct 429 -252 440 -257 452 -261 ct +464 -264 480 -266 497 -266 ct 530 -266 555 -258 571 -243 ct 588 -228 596 -207 596 -178 ct +596 -66 l 596 -53 598 -43 601 -37 ct 605 -30 611 -27 621 -27 ct 623 -27 625 -27 628 -27 ct +630 -28 632 -28 635 -28 ct 635 -2 l 629 0 624 1 618 1 ct 613 2 607 2 601 2 ct +593 2 586 1 580 -1 ct 574 -3 569 -6 566 -11 ct 562 -15 559 -21 557 -27 ct 555 -34 554 -41 554 -50 ct +552 -50 l 548 -41 542 -34 537 -27 ct 531 -20 525 -15 518 -10 ct 510 -5 502 -1 492 1 ct +483 4 472 5 460 5 ct p +470 -28 m 484 -28 496 -30 506 -35 ct 516 -40 525 -47 532 -54 ct 539 -62 544 -71 547 -80 ct +551 -89 552 -98 552 -107 ct 552 -128 l 505 -128 l 494 -128 484 -127 474 -126 ct +465 -125 456 -122 449 -118 ct 442 -114 436 -108 432 -101 ct 428 -94 426 -84 426 -72 ct +426 -58 429 -47 437 -39 ct 445 -31 456 -28 470 -28 ct p ef +668 0 m 668 -358 l 712 -358 l 712 0 l 668 0 l p ef +778 0 m 778 -358 l 822 -358 l 822 0 l 778 0 l p ef +pom +1.000 1.000 1.000 c 1462 4498 m 1273 4498 1085 4686 1085 4875 ct 1085 5391 l +1085 5580 1273 5769 1462 5769 ct 5026 5769 l 5215 5769 5404 5580 5404 5391 ct +5404 4875 l 5404 4686 5215 4498 5026 4498 ct 1462 4498 l p +1085 4498 m 1085 4498 l p +5404 5769 m 5404 5769 l p ef +0.003 0.003 0.003 c 1461 4498 m 1272 4498 1084 4686 1084 4875 ct 1084 5391 l +1084 5580 1272 5769 1461 5769 ct 5025 5769 l 5214 5769 5403 5580 5403 5391 ct +5403 4875 l 5403 4686 5214 4498 5025 4498 ct 1461 4498 l pc +1084 4498 m 1084 4498 l pc +5403 5769 m 5403 5769 l pc +pum +1445 5340 t +274 0 m 213 0 165 -18 129 -54 ct 93 -90 75 -139 75 -200 ct 75 -261 93 -309 129 -345 ct +165 -381 213 -399 274 -399 ct 335 -399 383 -381 420 -345 ct 457 -309 475 -260 475 -200 ct +475 -139 457 -91 420 -54 ct 383 -18 335 0 274 0 ct p ef +pom +pum +2207 5305 t +41 0 m 41 -340 l 298 -340 l 298 -302 l 87 -302 l 87 -193 l 284 -193 l +284 -156 l 87 -156 l 87 -38 l 308 -38 l 308 0 l 41 0 l p ef +523 0 m 453 -107 l 382 0 l 336 0 l 428 -134 l 340 -261 l 388 -261 l +453 -160 l 518 -261 l 566 -261 l 478 -135 l 572 0 l 523 0 l p ef +639 -121 m 639 -107 640 -95 643 -83 ct 646 -72 650 -62 656 -54 ct 662 -45 669 -39 678 -34 ct +688 -30 699 -28 711 -28 ct 730 -28 745 -31 757 -39 ct 768 -46 776 -56 780 -68 ct +818 -57 l 815 -49 811 -42 806 -35 ct 801 -28 795 -21 787 -15 ct 778 -9 768 -4 756 -1 ct +744 3 729 5 711 5 ct 673 5 643 -7 623 -30 ct 603 -53 593 -87 593 -132 ct 593 -157 596 -177 602 -194 ct +608 -211 617 -225 627 -236 ct 638 -246 650 -254 664 -259 ct 679 -264 694 -266 710 -266 ct +732 -266 750 -262 765 -255 ct 779 -248 791 -238 800 -226 ct 809 -213 815 -199 819 -182 ct +823 -165 825 -147 825 -127 ct 825 -121 l 639 -121 l p +780 -154 m 778 -182 771 -202 759 -215 ct 747 -228 731 -234 709 -234 ct 702 -234 694 -233 686 -230 ct +678 -228 671 -224 664 -218 ct 657 -212 652 -204 647 -193 ct 642 -183 640 -170 639 -154 ct +780 -154 l p ef +913 -132 m 913 -117 914 -103 917 -90 ct 919 -78 922 -67 928 -58 ct 933 -49 940 -42 948 -37 ct +956 -32 967 -29 979 -29 ct 995 -29 1008 -33 1018 -41 ct 1028 -50 1035 -62 1037 -79 ct +1081 -79 l 1080 -68 1076 -58 1072 -47 ct 1067 -37 1060 -28 1052 -21 ct 1044 -13 1034 -7 1022 -2 ct +1010 3 996 5 980 5 ct 960 5 943 2 928 -5 ct 914 -12 902 -22 893 -34 ct 885 -46 878 -60 874 -77 ct +870 -94 868 -111 868 -131 ct 868 -148 869 -164 872 -177 ct 875 -191 879 -202 885 -213 ct +890 -223 896 -231 903 -238 ct 910 -245 918 -250 926 -254 ct 934 -258 943 -261 952 -263 ct +961 -265 971 -266 980 -266 ct 995 -266 1008 -264 1019 -260 ct 1030 -256 1040 -250 1049 -243 ct +1057 -236 1064 -228 1069 -219 ct 1074 -209 1077 -199 1080 -188 ct 1035 -185 l +1033 -199 1027 -211 1018 -219 ct 1009 -228 996 -232 979 -232 ct 966 -232 956 -230 948 -226 ct +939 -222 933 -216 928 -207 ct 922 -199 919 -188 917 -176 ct 914 -163 913 -149 913 -132 ct +p ef +1172 -261 m 1172 -95 l 1172 -83 1173 -72 1175 -64 ct 1176 -55 1179 -48 1184 -43 ct +1188 -38 1193 -34 1200 -32 ct 1207 -30 1215 -29 1226 -29 ct 1236 -29 1245 -30 1253 -34 ct +1262 -38 1269 -43 1275 -50 ct 1280 -57 1285 -65 1288 -75 ct 1291 -85 1293 -97 1293 -110 ct +1293 -261 l 1336 -261 l 1336 -56 l 1336 -50 1337 -44 1337 -38 ct 1337 -32 1337 -27 1337 -21 ct +1337 -16 1337 -11 1337 -7 ct 1338 -3 1338 -1 1338 0 ct 1297 0 l 1297 -1 1297 -3 1296 -6 ct +1296 -10 1296 -14 1296 -19 ct 1296 -23 1295 -28 1295 -33 ct 1295 -37 1295 -41 1295 -44 ct +1294 -44 l 1290 -37 1286 -30 1281 -24 ct 1276 -18 1270 -13 1263 -8 ct 1257 -4 1249 -1 1240 2 ct +1232 4 1222 5 1211 5 ct 1196 5 1184 3 1173 0 ct 1163 -4 1154 -9 1148 -17 ct 1141 -24 1136 -34 1133 -45 ct +1130 -57 1128 -71 1128 -87 ct 1128 -261 l 1172 -261 l p ef +1506 -2 m 1499 0 1492 1 1485 2 ct 1479 3 1471 4 1462 4 ct 1427 4 1410 -16 1410 -55 ct +1410 -229 l 1379 -229 l 1379 -261 l 1411 -261 l 1424 -320 l 1453 -320 l +1453 -261 l 1501 -261 l 1501 -229 l 1453 -229 l 1453 -65 l 1453 -52 1455 -43 1459 -38 ct +1463 -33 1470 -31 1481 -31 ct 1485 -31 1489 -31 1493 -31 ct 1497 -32 1501 -33 1506 -34 ct +1506 -2 l p ef +1544 -316 m 1544 -358 l 1587 -358 l 1587 -316 l 1544 -316 l p +1544 0 m 1544 -261 l 1587 -261 l 1587 0 l 1544 0 l p ef +1875 -131 m 1875 -85 1865 -51 1845 -29 ct 1825 -6 1796 5 1757 5 ct 1739 5 1723 2 1709 -3 ct +1694 -9 1682 -17 1672 -28 ct 1662 -40 1655 -54 1650 -71 ct 1644 -88 1642 -108 1642 -131 ct +1642 -221 1681 -266 1759 -266 ct 1779 -266 1796 -263 1811 -258 ct 1826 -252 1838 -243 1847 -232 ct +1857 -221 1864 -207 1868 -190 ct 1873 -173 1875 -153 1875 -131 ct p +1829 -131 m 1829 -151 1828 -168 1825 -181 ct 1822 -194 1817 -205 1811 -213 ct +1805 -221 1798 -226 1789 -229 ct 1780 -232 1770 -234 1759 -234 ct 1748 -234 1738 -232 1729 -229 ct +1721 -226 1713 -220 1707 -212 ct 1700 -204 1696 -193 1692 -180 ct 1689 -167 1687 -151 1687 -131 ct +1687 -110 1689 -94 1693 -80 ct 1696 -67 1701 -57 1707 -49 ct 1713 -41 1721 -35 1729 -32 ct +1738 -29 1747 -27 1757 -27 ct 1768 -27 1778 -29 1787 -32 ct 1796 -35 1804 -40 1810 -48 ct +1816 -56 1821 -67 1824 -80 ct 1828 -94 1829 -110 1829 -131 ct p ef +2096 0 m 2096 -166 l 2096 -178 2095 -189 2093 -197 ct 2091 -206 2088 -213 2084 -218 ct +2080 -223 2074 -227 2068 -229 ct 2061 -231 2052 -232 2042 -232 ct 2032 -232 2023 -231 2014 -227 ct +2006 -223 1999 -218 1993 -211 ct 1987 -205 1983 -196 1979 -186 ct 1976 -176 1975 -164 1975 -151 ct +1975 0 l 1931 0 l 1931 -205 l 1931 -211 1931 -217 1931 -223 ct 1931 -229 1931 -234 1931 -240 ct +1931 -245 1930 -250 1930 -254 ct 1930 -258 1930 -260 1930 -261 ct 1971 -261 l +1971 -260 1971 -258 1971 -255 ct 1971 -251 1972 -247 1972 -242 ct 1972 -238 1972 -233 1973 -228 ct +1973 -224 1973 -220 1973 -217 ct 1973 -217 l 1978 -224 1982 -231 1987 -237 ct +1992 -243 1998 -248 2005 -253 ct 2011 -257 2019 -260 2027 -263 ct 2036 -265 2046 -266 2057 -266 ct +2071 -266 2084 -264 2094 -261 ct 2105 -257 2113 -252 2120 -244 ct 2127 -237 2132 -227 2135 -216 ct +2138 -204 2140 -190 2140 -174 ct 2140 0 l 2096 0 l p ef +pom +[ 152 152 ] 0 ld +3221 4498 m 3221 3101 l ps +gs +3256 3101 m 1160 3101 l 1160 1831 l 5351 1831 l 5351 3101 l 3256 3101 l +eoclip newpath +1161 1832 m 5352 1832 l 5352 3102 l 1161 3102 l 1161 1832 l eoclip newpath +pum +819 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1031 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1243 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1455 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1667 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1879 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2091 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2303 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2515 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2727 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2939 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3151 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3363 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3574 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3786 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3998 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +4210 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +4422 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +4634 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +4846 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +5058 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +5270 1937 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1031 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1243 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1455 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1667 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1879 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2091 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2303 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2515 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2727 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2939 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3151 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3363 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3574 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3786 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3998 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +4210 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +4422 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +4634 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +4846 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +5058 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +5270 2149 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +819 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1031 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1243 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1455 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1667 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1879 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2091 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2303 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2515 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2727 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2939 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3151 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3363 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3574 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3786 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3998 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +4210 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +4422 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +4634 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +4846 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +5058 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +5270 2361 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1031 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1243 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1455 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1667 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1879 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2091 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2303 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2515 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2727 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2939 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3151 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3363 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3574 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3786 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3998 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +4210 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +4422 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +4634 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +4846 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +5058 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +5270 2573 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +819 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1031 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1243 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1455 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1667 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1879 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2091 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2303 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2515 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2727 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2939 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3151 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3363 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3574 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3786 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3998 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +4210 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +4422 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +4634 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +4846 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +5058 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +5270 2785 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1031 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1243 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1455 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1667 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1879 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2091 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2303 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2515 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2727 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2939 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3151 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3363 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3574 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3786 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3998 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +4210 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +4422 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +4634 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +4846 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +5058 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +5270 2997 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +819 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1031 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1243 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1455 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1667 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +1879 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2091 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2303 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2515 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2727 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +2939 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3151 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3363 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3574 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3786 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +3998 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +4210 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +4422 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +4634 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +4846 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +5058 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +5270 3209 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +gr +[ ] 0 ld +3256 3101 m 1160 3101 l 1160 1831 l 5351 1831 l 5351 3101 l 3256 3101 l +pc +pum +2268 2348 t +99 -263 m 99 0 l 50 0 l 50 -263 l 8 -263 l 8 -299 l 50 -299 l 50 -333 l +50 -343 51 -353 53 -363 ct 55 -372 59 -380 64 -387 ct 69 -394 77 -399 86 -403 ct +96 -407 108 -409 123 -409 ct 128 -409 135 -409 141 -408 ct 147 -408 153 -407 158 -406 ct +158 -368 l 154 -368 151 -369 147 -369 ct 143 -370 139 -370 136 -370 ct 128 -370 122 -369 117 -367 ct +113 -365 109 -362 106 -358 ct 104 -355 102 -350 101 -345 ct 100 -339 99 -333 99 -326 ct +99 -299 l 158 -299 l 158 -263 l 99 -263 l p ef +243 -298 m 243 -109 l 243 -94 245 -82 247 -72 ct 249 -63 252 -55 257 -49 ct +262 -43 268 -39 276 -36 ct 284 -34 293 -32 305 -32 ct 317 -32 327 -34 337 -39 ct +346 -43 354 -49 361 -56 ct 368 -64 373 -74 376 -85 ct 380 -97 382 -110 382 -125 ct +382 -298 l 432 -298 l 432 -63 l 432 -57 432 -50 432 -44 ct 432 -37 432 -30 432 -24 ct +432 -18 432 -12 433 -8 ct 433 -4 433 -1 433 0 ct 386 0 l 386 0 386 -3 386 -7 ct +386 -11 385 -16 385 -21 ct 385 -26 385 -31 384 -37 ct 384 -42 384 -47 384 -51 ct +383 -51 l 379 -42 373 -34 368 -27 ct 362 -20 355 -14 348 -9 ct 340 -4 332 -1 322 2 ct +312 5 301 6 288 6 ct 272 6 257 4 245 0 ct 233 -4 224 -10 216 -19 ct 208 -27 203 -38 199 -51 ct +195 -65 194 -81 194 -99 ct 194 -298 l 243 -298 l p ef +697 0 m 697 -189 l 697 -204 696 -216 694 -226 ct 692 -235 688 -243 684 -249 ct +679 -255 673 -259 665 -262 ct 657 -264 647 -266 636 -266 ct 624 -266 613 -264 604 -259 ct +595 -255 586 -249 580 -242 ct 573 -234 568 -224 564 -213 ct 561 -201 559 -188 559 -173 ct +559 0 l 509 0 l 509 -235 l 509 -241 509 -248 509 -254 ct 509 -261 509 -268 509 -274 ct +508 -280 508 -286 508 -290 ct 508 -294 508 -297 507 -298 ct 554 -298 l 554 -298 555 -295 555 -291 ct +555 -287 555 -282 556 -277 ct 556 -272 556 -267 556 -261 ct 556 -256 556 -251 556 -247 ct +557 -247 l 562 -256 567 -264 573 -271 ct 579 -278 585 -284 593 -289 ct 600 -294 609 -297 619 -300 ct +628 -303 640 -304 653 -304 ct 669 -304 683 -302 695 -298 ct 707 -294 717 -288 725 -279 ct +732 -271 738 -260 742 -246 ct 745 -233 747 -217 747 -199 ct 747 0 l 697 0 l +p ef +859 -150 m 859 -133 860 -117 862 -103 ct 865 -89 869 -76 875 -66 ct 881 -56 889 -47 898 -42 ct +908 -36 920 -33 934 -33 ct 952 -33 966 -38 978 -47 ct 990 -56 997 -71 1000 -90 ct +1050 -90 l 1048 -78 1045 -65 1039 -54 ct 1034 -42 1026 -32 1017 -23 ct 1007 -14 996 -7 982 -2 ct +969 3 953 6 935 6 ct 912 6 892 2 876 -6 ct 859 -14 846 -25 836 -39 ct 826 -53 818 -69 814 -88 ct +809 -107 807 -127 807 -149 ct 807 -169 809 -187 812 -202 ct 815 -218 820 -231 826 -243 ct +832 -254 839 -264 847 -272 ct 855 -280 864 -286 873 -291 ct 883 -295 893 -299 903 -301 ct +914 -303 924 -304 935 -304 ct 951 -304 966 -302 979 -297 ct 992 -292 1004 -286 1013 -278 ct +1023 -270 1030 -261 1036 -250 ct 1042 -239 1046 -227 1048 -215 ct 998 -211 l +995 -227 988 -241 978 -250 ct 968 -260 953 -265 933 -265 ct 919 -265 907 -263 898 -258 ct +889 -253 881 -246 875 -237 ct 869 -227 865 -215 862 -201 ct 860 -187 859 -170 859 -150 ct +p ef +1220 -3 m 1212 -1 1204 1 1197 2 ct 1189 3 1180 4 1169 4 ct 1130 4 1110 -19 1110 -64 ct +1110 -263 l 1076 -263 l 1076 -299 l 1112 -299 l 1126 -366 l 1160 -366 l +1160 -299 l 1215 -299 l 1215 -263 l 1160 -263 l 1160 -74 l 1160 -60 1162 -50 1167 -44 ct +1171 -38 1179 -35 1191 -35 ct 1196 -35 1200 -36 1205 -37 ct 1209 -37 1214 -38 1220 -39 ct +1220 -3 l p ef +1261 -362 m 1261 -409 l 1310 -409 l 1310 -362 l 1261 -362 l p +1261 0 m 1261 -298 l 1310 -298 l 1310 0 l 1261 0 l p ef +1640 -149 m 1640 -97 1629 -58 1606 -32 ct 1583 -7 1549 6 1506 6 ct 1485 6 1466 3 1450 -3 ct +1434 -10 1420 -19 1409 -32 ct 1397 -45 1389 -61 1383 -81 ct 1377 -100 1374 -123 1374 -149 ct +1374 -252 1418 -304 1507 -304 ct 1530 -304 1550 -300 1567 -294 ct 1584 -288 1598 -278 1608 -265 ct +1619 -252 1627 -236 1632 -217 ct 1637 -197 1640 -175 1640 -149 ct p +1588 -149 m 1588 -172 1586 -191 1583 -207 ct 1579 -222 1574 -234 1567 -243 ct +1560 -252 1552 -258 1542 -262 ct 1532 -265 1521 -267 1508 -267 ct 1495 -267 1484 -265 1474 -261 ct +1464 -258 1455 -251 1448 -242 ct 1441 -233 1435 -221 1431 -206 ct 1428 -191 1426 -172 1426 -149 ct +1426 -126 1428 -107 1432 -92 ct 1436 -76 1441 -64 1448 -55 ct 1456 -46 1464 -40 1474 -36 ct +1483 -33 1494 -31 1505 -31 ct 1518 -31 1529 -32 1539 -36 ct 1550 -40 1558 -46 1566 -55 ct +1573 -64 1578 -76 1582 -91 ct 1586 -107 1588 -126 1588 -149 ct p ef +1891 0 m 1891 -189 l 1891 -204 1890 -216 1888 -226 ct 1886 -235 1882 -243 1878 -249 ct +1873 -255 1867 -259 1859 -262 ct 1851 -264 1841 -266 1830 -266 ct 1818 -266 1807 -264 1798 -259 ct +1789 -255 1780 -249 1774 -242 ct 1767 -234 1762 -224 1758 -213 ct 1755 -201 1753 -188 1753 -173 ct +1753 0 l 1703 0 l 1703 -235 l 1703 -241 1703 -248 1703 -254 ct 1703 -261 1703 -268 1703 -274 ct +1702 -280 1702 -286 1702 -290 ct 1702 -294 1702 -297 1701 -298 ct 1748 -298 l +1748 -298 1749 -295 1749 -291 ct 1749 -287 1749 -282 1750 -277 ct 1750 -272 1750 -267 1750 -261 ct +1750 -256 1750 -251 1750 -247 ct 1751 -247 l 1756 -256 1761 -264 1767 -271 ct +1773 -278 1779 -284 1787 -289 ct 1794 -294 1803 -297 1813 -300 ct 1822 -303 1834 -304 1847 -304 ct +1863 -304 1877 -302 1889 -298 ct 1901 -294 1911 -288 1919 -279 ct 1926 -271 1932 -260 1936 -246 ct +1939 -233 1941 -217 1941 -199 ct 1941 0 l 1891 0 l p ef +pom +pum +2457 2975 t +112 -263 m 112 -303 l 112 -313 113 -322 113 -329 ct 114 -337 116 -345 117 -352 ct +119 -359 121 -365 124 -371 ct 127 -377 130 -383 134 -389 ct 167 -389 l 159 -377 153 -365 148 -353 ct +144 -341 141 -329 141 -317 ct 166 -317 l 166 -263 l 112 -263 l p +21 -263 m 21 -303 l 21 -313 21 -322 22 -329 ct 23 -337 24 -345 26 -352 ct +28 -359 30 -365 33 -371 ct 36 -377 39 -383 43 -389 ct 76 -389 l 68 -377 61 -365 57 -353 ct +52 -341 50 -329 50 -317 ct 74 -317 l 74 -263 l 21 -263 l p ef +pom +pum +2643 2975 t +212 0 m 212 -189 l 212 -204 211 -216 209 -226 ct 207 -235 204 -243 200 -249 ct +195 -255 190 -259 183 -262 ct 176 -264 167 -266 157 -266 ct 147 -266 137 -264 129 -259 ct +120 -255 113 -249 107 -242 ct 101 -234 96 -224 93 -213 ct 90 -201 88 -188 88 -173 ct +88 0 l 39 0 l 39 -235 l 39 -241 39 -248 39 -254 ct 39 -261 39 -268 39 -274 ct +38 -280 38 -286 38 -290 ct 38 -294 38 -297 37 -298 ct 84 -298 l 84 -298 85 -295 85 -291 ct +85 -287 85 -282 86 -277 ct 86 -272 86 -267 86 -261 ct 86 -256 86 -251 86 -247 ct +87 -247 l 92 -256 96 -264 102 -271 ct 107 -278 113 -284 120 -289 ct 127 -294 134 -297 143 -300 ct +152 -303 163 -304 174 -304 ct 197 -304 215 -300 228 -290 ct 241 -281 250 -267 255 -247 ct +256 -247 l 261 -256 265 -264 271 -271 ct 277 -278 283 -284 290 -289 ct 298 -294 306 -297 315 -300 ct +324 -303 335 -304 346 -304 ct 362 -304 374 -302 385 -298 ct 396 -294 405 -288 412 -279 ct +419 -271 424 -260 428 -246 ct 431 -233 433 -217 433 -199 ct 433 0 l 384 0 l +384 -189 l 384 -204 383 -216 381 -226 ct 379 -235 376 -243 372 -249 ct 367 -255 362 -259 355 -262 ct +348 -264 339 -266 329 -266 ct 319 -266 309 -264 301 -260 ct 292 -256 285 -250 279 -242 ct +273 -234 269 -225 265 -213 ct 262 -202 261 -188 261 -173 ct 261 0 l 212 0 l +p ef +588 6 m 558 6 536 -2 521 -18 ct 505 -34 498 -56 498 -83 ct 498 -103 502 -119 509 -132 ct +517 -145 526 -154 538 -162 ct 550 -169 564 -174 579 -177 ct 595 -179 611 -181 627 -181 ct +693 -181 l 693 -197 l 693 -210 692 -220 690 -229 ct 687 -238 683 -245 678 -250 ct +672 -256 666 -260 658 -262 ct 650 -265 640 -266 630 -266 ct 620 -266 611 -265 604 -264 ct +596 -263 589 -260 584 -256 ct 578 -253 573 -248 570 -242 ct 566 -236 564 -228 563 -218 ct +511 -223 l 513 -235 517 -246 522 -256 ct 527 -265 534 -274 544 -281 ct 553 -288 565 -294 579 -298 ct +593 -302 611 -304 631 -304 ct 668 -304 696 -295 715 -278 ct 734 -261 744 -236 744 -203 ct +744 -74 l 744 -60 746 -49 749 -41 ct 753 -34 761 -30 771 -30 ct 774 -30 777 -30 780 -31 ct +782 -31 785 -31 788 -32 ct 788 -1 l 781 0 775 2 769 2 ct 763 3 756 3 749 3 ct +740 3 732 2 725 0 ct 719 -3 713 -7 709 -12 ct 705 -17 701 -23 699 -30 ct 697 -38 696 -47 695 -57 ct +693 -57 l 688 -47 682 -38 676 -31 ct 670 -23 662 -16 654 -11 ct 645 -6 636 -1 625 2 ct +614 5 602 6 588 6 ct p +599 -31 m 615 -31 629 -34 641 -40 ct 653 -46 662 -53 670 -62 ct 678 -71 684 -81 688 -91 ct +692 -102 693 -112 693 -122 ct 693 -146 l 639 -146 l 627 -146 616 -145 605 -144 ct +594 -142 584 -139 576 -134 ct 568 -130 561 -123 556 -115 ct 551 -107 549 -96 549 -82 ct +549 -66 553 -53 562 -45 ct 571 -36 583 -31 599 -31 ct p ef +825 -362 m 825 -409 l 874 -409 l 874 -362 l 825 -362 l p +825 0 m 825 -298 l 874 -298 l 874 0 l 825 0 l p ef +1141 0 m 1141 -189 l 1141 -204 1140 -216 1138 -226 ct 1136 -235 1132 -243 1128 -249 ct +1123 -255 1117 -259 1109 -262 ct 1101 -264 1091 -266 1080 -266 ct 1068 -266 1057 -264 1048 -259 ct +1039 -255 1030 -249 1024 -242 ct 1017 -234 1012 -224 1008 -213 ct 1005 -201 1003 -188 1003 -173 ct +1003 0 l 953 0 l 953 -235 l 953 -241 953 -248 953 -254 ct 953 -261 953 -268 953 -274 ct +952 -280 952 -286 952 -290 ct 952 -294 952 -297 951 -298 ct 998 -298 l 998 -298 999 -295 999 -291 ct +999 -287 999 -282 1000 -277 ct 1000 -272 1000 -267 1000 -261 ct 1000 -256 1000 -251 1000 -247 ct +1001 -247 l 1006 -256 1011 -264 1017 -271 ct 1023 -278 1029 -284 1037 -289 ct +1044 -294 1053 -297 1063 -300 ct 1072 -303 1084 -304 1097 -304 ct 1113 -304 1127 -302 1139 -298 ct +1151 -294 1161 -288 1169 -279 ct 1176 -271 1182 -260 1186 -246 ct 1189 -233 1191 -217 1191 -199 ct +1191 0 l 1141 0 l p ef +1395 -349 m 1395 -339 1395 -330 1394 -322 ct 1393 -314 1392 -307 1390 -300 ct +1388 -293 1386 -287 1383 -280 ct 1380 -274 1377 -268 1373 -263 ct 1340 -263 l +1348 -274 1355 -287 1359 -299 ct 1364 -311 1366 -323 1366 -335 ct 1342 -335 l +1342 -389 l 1395 -389 l 1395 -349 l p +1304 -349 m 1304 -339 1304 -330 1303 -322 ct 1302 -314 1301 -307 1299 -300 ct +1297 -293 1295 -287 1292 -280 ct 1289 -274 1286 -268 1283 -263 ct 1249 -263 l +1257 -274 1263 -287 1268 -299 ct 1272 -311 1275 -323 1275 -335 ct 1250 -335 l +1250 -389 l 1304 -389 l 1304 -349 l p ef +pom +[ 152 152 ] 0 ld +15351 9761 m 15351 8364 l ps +gs +15356 8434 m 13260 8434 l 13260 7165 l 17450 7165 l 17450 8434 l 15356 8434 l +eoclip newpath +13260 7165 m 17451 7165 l 17451 8435 l 13260 8435 l 13260 7165 l eoclip newpath +pum +12918 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13130 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13342 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13554 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13766 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13978 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14190 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14402 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14614 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14826 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15038 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15250 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15462 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15674 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15886 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16098 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16309 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16522 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16733 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16945 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17157 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17369 7270 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13130 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13342 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13554 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13766 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13978 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14190 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14402 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14614 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14826 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15038 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15250 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15462 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15674 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15886 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16098 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16309 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16522 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16733 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16945 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17157 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17369 7482 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +12918 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13130 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13342 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13554 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13766 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13978 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14190 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14402 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14614 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14826 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15038 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15250 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15462 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15674 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15886 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16098 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16309 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16522 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16733 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16945 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17157 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17369 7694 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13130 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13342 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13554 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13766 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13978 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14190 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14402 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14614 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14826 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15038 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15250 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15462 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15674 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15886 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16098 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16309 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16522 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16733 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16945 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17157 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17369 7906 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +12918 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13130 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13342 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13554 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13766 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13978 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14190 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14402 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14614 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14826 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15038 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15250 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15462 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15674 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15886 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16098 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16309 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16522 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16733 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16945 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17157 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17369 8118 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13130 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13342 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13554 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13766 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13978 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14190 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14402 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14614 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14826 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15038 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15250 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15462 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15674 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15886 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16098 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16309 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16522 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16733 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16945 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17157 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17369 8330 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +12918 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13130 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13342 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13554 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13766 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +13978 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14190 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14402 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14614 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +14826 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15038 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15250 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15462 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15674 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +15886 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16098 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16309 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16522 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16733 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +16945 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17157 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +pum +17369 8542 t +212 212 s +[/Indexed /DeviceRGB +1 +<000000 FFFFFF > +] setcolorspace +<< +/ImageType 1 +/Width 8 +/Height 8 +/BitsPerComponent 8 +/Decode[0 255] +/ImageMatrix[8 0 0 -8 0 8] +/DataSource currentfile +/ASCIIHexDecode filter +/LZWDecode filter +>> +image +800060503824160D07844261509808> +pom +gr +[ ] 0 ld +15356 8434 m 13260 8434 l 13260 7165 l 17450 7165 l 17450 8434 l 15356 8434 l +pc +pum +14367 7681 t +99 -263 m 99 0 l 50 0 l 50 -263 l 8 -263 l 8 -299 l 50 -299 l 50 -333 l +50 -343 51 -353 53 -363 ct 55 -372 59 -380 64 -387 ct 69 -394 77 -399 86 -403 ct +96 -407 108 -409 123 -409 ct 128 -409 135 -409 141 -408 ct 147 -408 153 -407 158 -406 ct +158 -368 l 154 -368 151 -369 147 -369 ct 143 -370 139 -370 136 -370 ct 128 -370 122 -369 117 -367 ct +113 -365 109 -362 106 -358 ct 104 -355 102 -350 101 -345 ct 100 -339 99 -333 99 -326 ct +99 -299 l 158 -299 l 158 -263 l 99 -263 l p ef +243 -298 m 243 -109 l 243 -94 245 -82 247 -72 ct 249 -63 252 -55 257 -49 ct +262 -43 268 -39 276 -36 ct 284 -34 293 -32 305 -32 ct 317 -32 327 -34 337 -39 ct +346 -43 354 -49 361 -56 ct 368 -64 373 -74 376 -85 ct 380 -97 382 -110 382 -125 ct +382 -298 l 432 -298 l 432 -63 l 432 -57 432 -50 432 -44 ct 432 -37 432 -30 432 -24 ct +432 -18 432 -12 433 -8 ct 433 -4 433 -1 433 0 ct 386 0 l 386 0 386 -3 386 -7 ct +386 -11 385 -16 385 -21 ct 385 -26 385 -31 384 -37 ct 384 -42 384 -47 384 -51 ct +383 -51 l 379 -42 373 -34 368 -27 ct 362 -20 355 -14 348 -9 ct 340 -4 332 -1 322 2 ct +312 5 301 6 288 6 ct 272 6 257 4 245 0 ct 233 -4 224 -10 216 -19 ct 208 -27 203 -38 199 -51 ct +195 -65 194 -81 194 -99 ct 194 -298 l 243 -298 l p ef +697 0 m 697 -189 l 697 -204 696 -216 694 -226 ct 692 -235 688 -243 684 -249 ct +679 -255 673 -259 665 -262 ct 657 -264 647 -266 636 -266 ct 624 -266 613 -264 604 -259 ct +595 -255 586 -249 580 -242 ct 573 -234 568 -224 564 -213 ct 561 -201 559 -188 559 -173 ct +559 0 l 509 0 l 509 -235 l 509 -241 509 -248 509 -254 ct 509 -261 509 -268 509 -274 ct +508 -280 508 -286 508 -290 ct 508 -294 508 -297 507 -298 ct 554 -298 l 554 -298 555 -295 555 -291 ct +555 -287 555 -282 556 -277 ct 556 -272 556 -267 556 -261 ct 556 -256 556 -251 556 -247 ct +557 -247 l 562 -256 567 -264 573 -271 ct 579 -278 585 -284 593 -289 ct 600 -294 609 -297 619 -300 ct +628 -303 640 -304 653 -304 ct 669 -304 683 -302 695 -298 ct 707 -294 717 -288 725 -279 ct +732 -271 738 -260 742 -246 ct 745 -233 747 -217 747 -199 ct 747 0 l 697 0 l +p ef +859 -150 m 859 -133 860 -117 862 -103 ct 865 -89 869 -76 875 -66 ct 881 -56 889 -47 898 -42 ct +908 -36 920 -33 934 -33 ct 952 -33 966 -38 978 -47 ct 990 -56 997 -71 1000 -90 ct +1050 -90 l 1048 -78 1045 -65 1039 -54 ct 1034 -42 1026 -32 1017 -23 ct 1007 -14 996 -7 982 -2 ct +969 3 953 6 935 6 ct 912 6 892 2 876 -6 ct 859 -14 846 -25 836 -39 ct 826 -53 818 -69 814 -88 ct +809 -107 807 -127 807 -149 ct 807 -169 809 -187 812 -202 ct 815 -218 820 -231 826 -243 ct +832 -254 839 -264 847 -272 ct 855 -280 864 -286 873 -291 ct 883 -295 893 -299 903 -301 ct +914 -303 924 -304 935 -304 ct 951 -304 966 -302 979 -297 ct 992 -292 1004 -286 1013 -278 ct +1023 -270 1030 -261 1036 -250 ct 1042 -239 1046 -227 1048 -215 ct 998 -211 l +995 -227 988 -241 978 -250 ct 968 -260 953 -265 933 -265 ct 919 -265 907 -263 898 -258 ct +889 -253 881 -246 875 -237 ct 869 -227 865 -215 862 -201 ct 860 -187 859 -170 859 -150 ct +p ef +1220 -3 m 1212 -1 1204 1 1197 2 ct 1189 3 1180 4 1169 4 ct 1130 4 1110 -19 1110 -64 ct +1110 -263 l 1076 -263 l 1076 -299 l 1112 -299 l 1126 -366 l 1160 -366 l +1160 -299 l 1215 -299 l 1215 -263 l 1160 -263 l 1160 -74 l 1160 -60 1162 -50 1167 -44 ct +1171 -38 1179 -35 1191 -35 ct 1196 -35 1200 -36 1205 -37 ct 1209 -37 1214 -38 1220 -39 ct +1220 -3 l p ef +1261 -362 m 1261 -409 l 1310 -409 l 1310 -362 l 1261 -362 l p +1261 0 m 1261 -298 l 1310 -298 l 1310 0 l 1261 0 l p ef +1640 -149 m 1640 -97 1629 -58 1606 -32 ct 1583 -7 1549 6 1506 6 ct 1485 6 1466 3 1450 -3 ct +1434 -10 1420 -19 1409 -32 ct 1397 -45 1389 -61 1383 -81 ct 1377 -100 1374 -123 1374 -149 ct +1374 -252 1418 -304 1507 -304 ct 1530 -304 1550 -300 1567 -294 ct 1584 -288 1598 -278 1608 -265 ct +1619 -252 1627 -236 1632 -217 ct 1637 -197 1640 -175 1640 -149 ct p +1588 -149 m 1588 -172 1586 -191 1583 -207 ct 1579 -222 1574 -234 1567 -243 ct +1560 -252 1552 -258 1542 -262 ct 1532 -265 1521 -267 1508 -267 ct 1495 -267 1484 -265 1474 -261 ct +1464 -258 1455 -251 1448 -242 ct 1441 -233 1435 -221 1431 -206 ct 1428 -191 1426 -172 1426 -149 ct +1426 -126 1428 -107 1432 -92 ct 1436 -76 1441 -64 1448 -55 ct 1456 -46 1464 -40 1474 -36 ct +1483 -33 1494 -31 1505 -31 ct 1518 -31 1529 -32 1539 -36 ct 1550 -40 1558 -46 1566 -55 ct +1573 -64 1578 -76 1582 -91 ct 1586 -107 1588 -126 1588 -149 ct p ef +1891 0 m 1891 -189 l 1891 -204 1890 -216 1888 -226 ct 1886 -235 1882 -243 1878 -249 ct +1873 -255 1867 -259 1859 -262 ct 1851 -264 1841 -266 1830 -266 ct 1818 -266 1807 -264 1798 -259 ct +1789 -255 1780 -249 1774 -242 ct 1767 -234 1762 -224 1758 -213 ct 1755 -201 1753 -188 1753 -173 ct +1753 0 l 1703 0 l 1703 -235 l 1703 -241 1703 -248 1703 -254 ct 1703 -261 1703 -268 1703 -274 ct +1702 -280 1702 -286 1702 -290 ct 1702 -294 1702 -297 1701 -298 ct 1748 -298 l +1748 -298 1749 -295 1749 -291 ct 1749 -287 1749 -282 1750 -277 ct 1750 -272 1750 -267 1750 -261 ct +1750 -256 1750 -251 1750 -247 ct 1751 -247 l 1756 -256 1761 -264 1767 -271 ct +1773 -278 1779 -284 1787 -289 ct 1794 -294 1803 -297 1813 -300 ct 1822 -303 1834 -304 1847 -304 ct +1863 -304 1877 -302 1889 -298 ct 1901 -294 1911 -288 1919 -279 ct 1926 -271 1932 -260 1936 -246 ct +1939 -233 1941 -217 1941 -199 ct 1941 0 l 1891 0 l p ef +pom +pum +14401 8308 t +112 -263 m 112 -303 l 112 -313 113 -322 113 -329 ct 114 -337 116 -345 117 -352 ct +119 -359 121 -365 124 -371 ct 127 -377 130 -383 134 -389 ct 167 -389 l 159 -377 153 -365 148 -353 ct +144 -341 141 -329 141 -317 ct 166 -317 l 166 -263 l 112 -263 l p +21 -263 m 21 -303 l 21 -313 21 -322 22 -329 ct 23 -337 24 -345 26 -352 ct +28 -359 30 -365 33 -371 ct 36 -377 39 -383 43 -389 ct 76 -389 l 68 -377 61 -365 57 -353 ct +52 -341 50 -329 50 -317 ct 74 -317 l 74 -263 l 21 -263 l p ef +pom +pum +14587 8308 t +39 0 m 39 -229 l 39 -235 39 -242 39 -248 ct 39 -255 39 -261 39 -267 ct 38 -273 38 -279 38 -284 ct +38 -289 38 -294 37 -298 ct 84 -298 l 84 -294 85 -289 85 -284 ct 85 -279 86 -273 86 -267 ct +86 -262 86 -256 86 -251 ct 86 -246 86 -241 86 -238 ct 88 -238 l 91 -249 95 -259 99 -267 ct +103 -276 107 -282 113 -288 ct 118 -293 124 -297 132 -300 ct 139 -303 148 -304 158 -304 ct +162 -304 166 -304 170 -303 ct 174 -302 176 -302 178 -301 ct 178 -256 l 175 -257 171 -257 167 -258 ct +162 -258 158 -258 152 -258 ct 141 -258 131 -256 123 -251 ct 115 -246 108 -238 103 -229 ct +98 -220 95 -209 92 -197 ct 90 -184 89 -170 89 -156 ct 89 0 l 39 0 l p ef +300 6 m 270 6 248 -2 233 -18 ct 217 -34 210 -56 210 -83 ct 210 -103 214 -119 221 -132 ct +229 -145 238 -154 250 -162 ct 262 -169 276 -174 291 -177 ct 307 -179 323 -181 339 -181 ct +405 -181 l 405 -197 l 405 -210 404 -220 402 -229 ct 399 -238 395 -245 390 -250 ct +384 -256 378 -260 370 -262 ct 362 -265 352 -266 342 -266 ct 332 -266 323 -265 316 -264 ct +308 -263 301 -260 296 -256 ct 290 -253 285 -248 282 -242 ct 278 -236 276 -228 275 -218 ct +223 -223 l 225 -235 229 -246 234 -256 ct 239 -265 246 -274 256 -281 ct 265 -288 277 -294 291 -298 ct +305 -302 323 -304 343 -304 ct 380 -304 408 -295 427 -278 ct 446 -261 456 -236 456 -203 ct +456 -74 l 456 -60 458 -49 461 -41 ct 465 -34 473 -30 483 -30 ct 486 -30 489 -30 492 -31 ct +494 -31 497 -31 500 -32 ct 500 -1 l 493 0 487 2 481 2 ct 475 3 468 3 461 3 ct +452 3 444 2 437 0 ct 431 -3 425 -7 421 -12 ct 417 -17 413 -23 411 -30 ct 409 -38 408 -47 407 -57 ct +405 -57 l 400 -47 394 -38 388 -31 ct 382 -23 374 -16 366 -11 ct 357 -6 348 -1 337 2 ct +326 5 314 6 300 6 ct p +311 -31 m 327 -31 341 -34 353 -40 ct 365 -46 374 -53 382 -62 ct 390 -71 396 -81 400 -91 ct +404 -102 405 -112 405 -122 ct 405 -146 l 351 -146 l 339 -146 328 -145 317 -144 ct +306 -142 296 -139 288 -134 ct 280 -130 273 -123 268 -115 ct 263 -107 261 -96 261 -82 ct +261 -66 265 -53 274 -45 ct 283 -36 295 -31 311 -31 ct p ef +726 -48 m 717 -28 705 -15 690 -6 ct 674 2 656 6 633 6 ct 596 6 568 -7 550 -32 ct +533 -57 524 -96 524 -147 ct 524 -252 560 -304 633 -304 ct 656 -304 675 -300 690 -291 ct +705 -283 717 -270 726 -252 ct 727 -252 l 727 -254 727 -257 727 -260 ct 726 -264 726 -269 726 -273 ct +726 -277 726 -281 726 -285 ct 726 -289 726 -292 726 -293 ct 726 -409 l 776 -409 l +776 -61 l 776 -54 776 -47 776 -40 ct 776 -34 776 -28 776 -22 ct 776 -17 777 -12 777 -8 ct +777 -4 777 -1 777 0 ct 730 0 l 730 -1 729 -4 729 -7 ct 729 -11 728 -15 728 -19 ct +728 -24 728 -28 727 -33 ct 727 -38 727 -43 727 -48 ct 726 -48 l p +576 -149 m 576 -129 577 -111 580 -96 ct 582 -81 586 -69 592 -60 ct 598 -50 605 -43 614 -39 ct +623 -35 633 -32 646 -32 ct 659 -32 671 -34 681 -39 ct 691 -43 699 -50 706 -59 ct +712 -69 717 -81 721 -96 ct 724 -112 726 -130 726 -152 ct 726 -174 724 -191 721 -206 ct +717 -221 712 -233 705 -242 ct 699 -251 690 -257 681 -261 ct 671 -265 659 -267 647 -267 ct +634 -267 624 -265 615 -261 ct 606 -256 599 -250 593 -240 ct 587 -231 583 -219 580 -204 ct +577 -189 576 -170 576 -149 ct p ef +851 -362 m 851 -409 l 900 -409 l 900 -362 l 851 -362 l p +851 0 m 851 -298 l 900 -298 l 900 0 l 851 0 l p ef +1026 -298 m 1026 -109 l 1026 -94 1028 -82 1030 -72 ct 1032 -63 1035 -55 1040 -49 ct +1045 -43 1051 -39 1059 -36 ct 1067 -34 1076 -32 1088 -32 ct 1100 -32 1110 -34 1120 -39 ct +1129 -43 1137 -49 1144 -56 ct 1151 -64 1156 -74 1159 -85 ct 1163 -97 1165 -110 1165 -125 ct +1165 -298 l 1215 -298 l 1215 -63 l 1215 -57 1215 -50 1215 -44 ct 1215 -37 1215 -30 1215 -24 ct +1215 -18 1215 -12 1216 -8 ct 1216 -4 1216 -1 1216 0 ct 1169 0 l 1169 0 1169 -3 1169 -7 ct +1169 -11 1168 -16 1168 -21 ct 1168 -26 1168 -31 1167 -37 ct 1167 -42 1167 -47 1167 -51 ct +1166 -51 l 1162 -42 1156 -34 1151 -27 ct 1145 -20 1138 -14 1131 -9 ct 1123 -4 1115 -1 1105 2 ct +1095 5 1084 6 1071 6 ct 1055 6 1040 4 1028 0 ct 1016 -4 1007 -10 999 -19 ct 991 -27 986 -38 982 -51 ct +978 -65 977 -81 977 -99 ct 977 -298 l 1026 -298 l p ef +1515 -82 m 1515 -68 1512 -56 1507 -45 ct 1501 -34 1493 -24 1483 -17 ct 1473 -10 1460 -4 1445 0 ct +1430 4 1413 6 1394 6 ct 1376 6 1361 5 1347 2 ct 1333 -1 1321 -5 1311 -11 ct 1300 -17 1291 -24 1284 -34 ct +1277 -44 1272 -56 1269 -70 ct 1312 -78 l 1317 -62 1325 -50 1339 -43 ct 1352 -36 1370 -32 1394 -32 ct +1404 -32 1414 -33 1423 -34 ct 1432 -35 1440 -38 1446 -42 ct 1452 -45 1457 -50 1461 -56 ct +1465 -62 1466 -69 1466 -78 ct 1466 -87 1464 -95 1460 -100 ct 1456 -106 1450 -111 1442 -115 ct +1435 -119 1426 -122 1415 -125 ct 1404 -128 1393 -131 1380 -134 ct 1368 -137 1356 -141 1344 -145 ct +1332 -149 1322 -154 1312 -160 ct 1303 -166 1295 -174 1289 -184 ct 1283 -193 1281 -205 1281 -219 ct +1281 -246 1290 -267 1310 -281 ct 1329 -295 1357 -303 1394 -303 ct 1427 -303 1453 -297 1473 -285 ct +1492 -274 1504 -255 1509 -229 ct 1465 -224 l 1463 -232 1460 -238 1456 -243 ct +1451 -249 1446 -253 1440 -256 ct 1433 -259 1426 -262 1419 -263 ct 1411 -264 1403 -265 1394 -265 ct +1372 -265 1355 -262 1345 -255 ct 1334 -248 1329 -238 1329 -224 ct 1329 -216 1331 -209 1335 -204 ct +1339 -199 1344 -194 1351 -191 ct 1358 -187 1367 -184 1377 -181 ct 1387 -179 1397 -176 1409 -173 ct +1417 -171 1425 -169 1434 -166 ct 1442 -164 1450 -161 1458 -158 ct 1466 -155 1473 -151 1480 -147 ct +1487 -143 1493 -137 1498 -131 ct 1503 -125 1507 -118 1510 -110 ct 1513 -102 1515 -93 1515 -82 ct +p ef +1704 -349 m 1704 -339 1704 -330 1703 -322 ct 1702 -314 1701 -307 1699 -300 ct +1697 -293 1695 -287 1692 -280 ct 1689 -274 1686 -268 1682 -263 ct 1649 -263 l +1657 -274 1664 -287 1668 -299 ct 1673 -311 1675 -323 1675 -335 ct 1651 -335 l +1651 -389 l 1704 -389 l 1704 -349 l p +1613 -349 m 1613 -339 1613 -330 1612 -322 ct 1611 -314 1610 -307 1608 -300 ct +1606 -293 1604 -287 1601 -280 ct 1598 -274 1595 -268 1592 -263 ct 1558 -263 l +1566 -274 1572 -287 1577 -299 ct 1581 -311 1584 -323 1584 -335 ct 1559 -335 l +1559 -389 l 1613 -389 l 1613 -349 l p ef +pom +1.000 1.000 1.000 c 13572 9705 m 13383 9705 13195 9893 13195 10082 ct 13195 10598 l +13195 10787 13383 10976 13572 10976 ct 17136 10976 l 17325 10976 17514 10787 17514 10598 ct +17514 10082 l 17514 9893 17325 9705 17136 9705 ct 13572 9705 l p +13195 9705 m 13195 9705 l p +17514 10976 m 17514 10976 l p ef +0.003 0.003 0.003 c 13572 9704 m 13383 9704 13195 9892 13195 10081 ct 13195 10597 l +13195 10786 13383 10975 13572 10975 ct 17135 10975 l 17324 10975 17513 10786 17513 10597 ct +17513 10081 l 17513 9892 17324 9704 17135 9704 ct 13572 9704 l pc +13195 9704 m 13195 9704 l pc +17513 10975 m 17513 10975 l pc +pum +13555 10547 t +274 0 m 213 0 165 -18 129 -54 ct 93 -90 75 -139 75 -200 ct 75 -261 93 -309 129 -345 ct +165 -381 213 -399 274 -399 ct 335 -399 383 -381 420 -345 ct 457 -309 475 -260 475 -200 ct +475 -139 457 -91 420 -54 ct 383 -18 335 0 274 0 ct p ef +pom +pum +14317 10512 t +41 0 m 41 -340 l 298 -340 l 298 -302 l 87 -302 l 87 -193 l 284 -193 l +284 -156 l 87 -156 l 87 -38 l 308 -38 l 308 0 l 41 0 l p ef +523 0 m 453 -107 l 382 0 l 336 0 l 428 -134 l 340 -261 l 388 -261 l +453 -160 l 518 -261 l 566 -261 l 478 -135 l 572 0 l 523 0 l p ef +639 -121 m 639 -107 640 -95 643 -83 ct 646 -72 650 -62 656 -54 ct 662 -45 669 -39 678 -34 ct +688 -30 699 -28 711 -28 ct 730 -28 745 -31 757 -39 ct 768 -46 776 -56 780 -68 ct +818 -57 l 815 -49 811 -42 806 -35 ct 801 -28 795 -21 787 -15 ct 778 -9 768 -4 756 -1 ct +744 3 729 5 711 5 ct 673 5 643 -7 623 -30 ct 603 -53 593 -87 593 -132 ct 593 -157 596 -177 602 -194 ct +608 -211 617 -225 627 -236 ct 638 -246 650 -254 664 -259 ct 679 -264 694 -266 710 -266 ct +732 -266 750 -262 765 -255 ct 779 -248 791 -238 800 -226 ct 809 -213 815 -199 819 -182 ct +823 -165 825 -147 825 -127 ct 825 -121 l 639 -121 l p +780 -154 m 778 -182 771 -202 759 -215 ct 747 -228 731 -234 709 -234 ct 702 -234 694 -233 686 -230 ct +678 -228 671 -224 664 -218 ct 657 -212 652 -204 647 -193 ct 642 -183 640 -170 639 -154 ct +780 -154 l p ef +913 -132 m 913 -117 914 -103 917 -90 ct 919 -78 922 -67 928 -58 ct 933 -49 940 -42 948 -37 ct +956 -32 967 -29 979 -29 ct 995 -29 1008 -33 1018 -41 ct 1028 -50 1035 -62 1037 -79 ct +1081 -79 l 1080 -68 1076 -58 1072 -47 ct 1067 -37 1060 -28 1052 -21 ct 1044 -13 1034 -7 1022 -2 ct +1010 3 996 5 980 5 ct 960 5 943 2 928 -5 ct 914 -12 902 -22 893 -34 ct 885 -46 878 -60 874 -77 ct +870 -94 868 -111 868 -131 ct 868 -148 869 -164 872 -177 ct 875 -191 879 -202 885 -213 ct +890 -223 896 -231 903 -238 ct 910 -245 918 -250 926 -254 ct 934 -258 943 -261 952 -263 ct +961 -265 971 -266 980 -266 ct 995 -266 1008 -264 1019 -260 ct 1030 -256 1040 -250 1049 -243 ct +1057 -236 1064 -228 1069 -219 ct 1074 -209 1077 -199 1080 -188 ct 1035 -185 l +1033 -199 1027 -211 1018 -219 ct 1009 -228 996 -232 979 -232 ct 966 -232 956 -230 948 -226 ct +939 -222 933 -216 928 -207 ct 922 -199 919 -188 917 -176 ct 914 -163 913 -149 913 -132 ct +p ef +1172 -261 m 1172 -95 l 1172 -83 1173 -72 1175 -64 ct 1176 -55 1179 -48 1184 -43 ct +1188 -38 1193 -34 1200 -32 ct 1207 -30 1215 -29 1226 -29 ct 1236 -29 1245 -30 1253 -34 ct +1262 -38 1269 -43 1275 -50 ct 1280 -57 1285 -65 1288 -75 ct 1291 -85 1293 -97 1293 -110 ct +1293 -261 l 1336 -261 l 1336 -56 l 1336 -50 1337 -44 1337 -38 ct 1337 -32 1337 -27 1337 -21 ct +1337 -16 1337 -11 1337 -7 ct 1338 -3 1338 -1 1338 0 ct 1297 0 l 1297 -1 1297 -3 1296 -6 ct +1296 -10 1296 -14 1296 -19 ct 1296 -23 1295 -28 1295 -33 ct 1295 -37 1295 -41 1295 -44 ct +1294 -44 l 1290 -37 1286 -30 1281 -24 ct 1276 -18 1270 -13 1263 -8 ct 1257 -4 1249 -1 1240 2 ct +1232 4 1222 5 1211 5 ct 1196 5 1184 3 1173 0 ct 1163 -4 1154 -9 1148 -17 ct 1141 -24 1136 -34 1133 -45 ct +1130 -57 1128 -71 1128 -87 ct 1128 -261 l 1172 -261 l p ef +1506 -2 m 1499 0 1492 1 1485 2 ct 1479 3 1471 4 1462 4 ct 1427 4 1410 -16 1410 -55 ct +1410 -229 l 1379 -229 l 1379 -261 l 1411 -261 l 1424 -320 l 1453 -320 l +1453 -261 l 1501 -261 l 1501 -229 l 1453 -229 l 1453 -65 l 1453 -52 1455 -43 1459 -38 ct +1463 -33 1470 -31 1481 -31 ct 1485 -31 1489 -31 1493 -31 ct 1497 -32 1501 -33 1506 -34 ct +1506 -2 l p ef +1544 -316 m 1544 -358 l 1587 -358 l 1587 -316 l 1544 -316 l p +1544 0 m 1544 -261 l 1587 -261 l 1587 0 l 1544 0 l p ef +1875 -131 m 1875 -85 1865 -51 1845 -29 ct 1825 -6 1796 5 1757 5 ct 1739 5 1723 2 1709 -3 ct +1694 -9 1682 -17 1672 -28 ct 1662 -40 1655 -54 1650 -71 ct 1644 -88 1642 -108 1642 -131 ct +1642 -221 1681 -266 1759 -266 ct 1779 -266 1796 -263 1811 -258 ct 1826 -252 1838 -243 1847 -232 ct +1857 -221 1864 -207 1868 -190 ct 1873 -173 1875 -153 1875 -131 ct p +1829 -131 m 1829 -151 1828 -168 1825 -181 ct 1822 -194 1817 -205 1811 -213 ct +1805 -221 1798 -226 1789 -229 ct 1780 -232 1770 -234 1759 -234 ct 1748 -234 1738 -232 1729 -229 ct +1721 -226 1713 -220 1707 -212 ct 1700 -204 1696 -193 1692 -180 ct 1689 -167 1687 -151 1687 -131 ct +1687 -110 1689 -94 1693 -80 ct 1696 -67 1701 -57 1707 -49 ct 1713 -41 1721 -35 1729 -32 ct +1738 -29 1747 -27 1757 -27 ct 1768 -27 1778 -29 1787 -32 ct 1796 -35 1804 -40 1810 -48 ct +1816 -56 1821 -67 1824 -80 ct 1828 -94 1829 -110 1829 -131 ct p ef +2096 0 m 2096 -166 l 2096 -178 2095 -189 2093 -197 ct 2091 -206 2088 -213 2084 -218 ct +2080 -223 2074 -227 2068 -229 ct 2061 -231 2052 -232 2042 -232 ct 2032 -232 2023 -231 2014 -227 ct +2006 -223 1999 -218 1993 -211 ct 1987 -205 1983 -196 1979 -186 ct 1976 -176 1975 -164 1975 -151 ct +1975 0 l 1931 0 l 1931 -205 l 1931 -211 1931 -217 1931 -223 ct 1931 -229 1931 -234 1931 -240 ct +1931 -245 1930 -250 1930 -254 ct 1930 -258 1930 -260 1930 -261 ct 1971 -261 l +1971 -260 1971 -258 1971 -255 ct 1971 -251 1972 -247 1972 -242 ct 1972 -238 1972 -233 1973 -228 ct +1973 -224 1973 -220 1973 -217 ct 1973 -217 l 1978 -224 1982 -231 1987 -237 ct +1992 -243 1998 -248 2005 -253 ct 2011 -257 2019 -260 2027 -263 ct 2036 -265 2046 -266 2057 -266 ct +2071 -266 2084 -264 2094 -261 ct 2105 -257 2113 -252 2120 -244 ct 2127 -237 2132 -227 2135 -216 ct +2138 -204 2140 -190 2140 -174 ct 2140 0 l 2096 0 l p ef +pom +0 16697 t +pom +count op_count sub {pop} repeat countdictstack dict_count sub {end} repeat b4_inc_state restore +%%PageTrailer +%%Trailer +%%EOF diff --git a/AspectC++/doc/images/JoinPointModelNew.odg b/AspectC++/doc/images/JoinPointModelNew.odg new file mode 100644 index 0000000..a890553 Binary files /dev/null and b/AspectC++/doc/images/JoinPointModelNew.odg differ diff --git a/AspectC++/doc/images/JoinPointModelNew.pdf b/AspectC++/doc/images/JoinPointModelNew.pdf new file mode 100644 index 0000000..46bf73f Binary files /dev/null and b/AspectC++/doc/images/JoinPointModelNew.pdf differ diff --git a/AspectC++/doc/images/ReadMe.txt b/AspectC++/doc/images/ReadMe.txt new file mode 100644 index 0000000..6a8d1b1 --- /dev/null +++ b/AspectC++/doc/images/ReadMe.txt @@ -0,0 +1,15 @@ +dot -> pdf: +""""""""""" + +1. dot -> eps +dot -Teps > + +2. eps -> pdf +epstopdf + +Example: +dot -Teps acmodel.dot > acmodel.eps +epstopdf acmodel.eps + +3. pdf rotation: +pdf90 acmodel.pdf diff --git a/AspectC++/doc/images/ac++logo.eps b/AspectC++/doc/images/ac++logo.eps new file mode 100644 index 0000000..4d1d883 --- /dev/null +++ b/AspectC++/doc/images/ac++logo.eps @@ -0,0 +1,3928 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Creator: Adobe Illustrator(TM) 7.0 +%%AI8_CreatorVersion: 8.0.1 +%%For: (Peter Schultz) (pete design) +%%Title: (ac++logo.eps) +%%CreationDate: (4/4/03) (12:32 PM) +%%BoundingBox: 208 393 396 495 +%%HiResBoundingBox: 208.9492 393.2559 395.7109 494.6265 +%%DocumentProcessColors: Magenta Yellow Black +%%DocumentSuppliedResources: procset Adobe_level2_AI5 1.2 0 +%%+ procset Adobe_ColorImage_AI6 1.1 0 +%%+ procset Adobe_Illustrator_AI5 1.3 0 +%%+ procset Adobe_cshow 2.0 8 +%AI5_FileFormat 3.0 +%AI3_ColorUsage: Color +%AI3_IncludePlacedImages +%AI7_ImageSettings: 1 +%%AI6_ColorSeparationSet: 1 1 (AI6 Default Color Separation Set) +%%+ Options: 1 16 0 1 0 1 1 1 0 1 1 1 1 8.504 0 0 0 0 0 0 0 0 -1 -1 +%%+ PPD: 1 21 0 0 60 45 2 2 1 0 0 1 0 0 0 0 0 0 0 0 0 0 () +%AI3_TemplateBox: 296.5 419.5 296.5 419.5 +%AI3_TileBox: 10 15 586 831 +%AI3_DocumentPreview: PC_ColorTIFF +%AI5_ArtSize: 592 840 +%AI5_RulerUnits: 1 +%AI5_ArtFlags: 1 0 0 1 0 0 1 0 0 +%AI5_TargetResolution: 800 +%AI5_NumLayers: 1 +%AI5_OpenToView: -263.5 849.5 1 1265 912 18 0 1 7 40 0 0 +%AI5_OpenViewLayers: 7 +%%PageOrigin:10 15 +%%AI3_PaperRect:-10 833 585 -9 +%%AI3_Margin:10 -14 -9 9 +%AI7_GridSettings: 28.3465 10 28.3465 10 1 0 1 0.749 0.498 1 0.8745 0.749 +%AI7_Thumbnail: 128 72 8 +%%BeginData: 9556 Hex Bytes +%0000330000660000990000CC0033000033330033660033990033CC0033FF +%0066000066330066660066990066CC0066FF009900009933009966009999 +%0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 +%00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 +%3333663333993333CC3333FF3366003366333366663366993366CC3366FF +%3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 +%33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 +%6600666600996600CC6600FF6633006633336633666633996633CC6633FF +%6666006666336666666666996666CC6666FF669900669933669966669999 +%6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 +%66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF +%9933009933339933669933999933CC9933FF996600996633996666996699 +%9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 +%99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF +%CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 +%CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 +%CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF +%CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC +%FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 +%FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 +%FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 +%000011111111220000002200000022222222440000004400000044444444 +%550000005500000055555555770000007700000077777777880000008800 +%000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB +%DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF +%00FF0000FFFFFF0000FF00FFFFFF00FFFFFF +%524C45FD22FFCA9ABC8D938D938D9393BCA1CBFD70FFCA9A938C9368938C +%9368938C9368938C93A1FD6CFFCABC8D938C938D938C938D938C938D938C +%938D938DC3FD69FFA1936893689368936893689368936893689368936893 +%6894A8FD6BFFCA9A938D938D938D938D938D938D938D938D938D93A1FD6D +%FFC38D9368938C9368938C9368938C9368938C93A1FD6EFF93938C938D93 +%8C938D938C938D938C938D93A1FD6EFF9393689368936893689368936893 +%68936893A1FD60FF9A9A939394C3CAFD06FFCA8D938D938D938D938D938D +%938D938D938D93CAFD5CFFCA9A68938C9368938C939AFD06FF9A68938C93 +%68938C9368938C9368938C93689AFD5CFFBC8D938C938D938C938D93A1FD +%05FFC4938C938D938C938D938C94949A93938D938CCAFD08FFA1C39BCAFD +%4EFFC3689368936893689368936893FD06FF689368936893689368939AFF +%FFCA689368938DFD08FF93689393FD4EFF93938D938D938D938D938D938D +%CAFD05FF9A8D938D938D938D938DC3FFFFCA938D938D93C4FD07FF8D938D +%BCFD4DFFCA9368938C9368938C9368938C939AFD05FF939368938C936893 +%8C939AFFFFCA68938C93689AFD07FF938C9393FD4DFFCA8D938C938D938C +%938D938C938D938C938D938C938D938C938D938C938DC3FFFFCA938C938D +%938CFD07FF8C938D9AFD4DFF9A9368936893689368936893689368936893 +%6893689368936893689368939AFFFFCA689368936893A1FD06FF93689393 +%FD4DFFBC8D938D938D938D938D938D938D938D938D938D938D938D938D93 +%8D938DC3FFFFCA938D938D938DC3FD06FF8D938D9AFD4DFF93938C936893 +%8C9368938C9368938C9368938C9368938C93A1CAA8CAA1CACAFFFFFFA8CA +%A1CAA8CA9A938C9368938C9368938C9368938C9368CAFD46FF9A8C938D93 +%8C938D938C938D938C938D938C938D938C938DFD10FFC38C938D938C938D +%938C938D938C938D93A8FD46FF9393689368936893689368936893689368 +%93689368936893FD10FFA193689368936893689368936893689368CAFD46 +%FF9A8D938D938D938D938D938D938D938D938D938D938D938DFD06CAFD04 +%FFFD06CAC38D938D938D938D938D938D938D938D93CAFD46FF939368938C +%9368938C9368938C9368938C9368938C9368938C9368938C939AFFFFCA68 +%938C9368938CFD06FF938C9393FD4DFFC38D938C938D938C938D938C938D +%938C938D938C938D938C938D938C938DC3FFFFCA938C938D938CBCFD06FF +%8C938D9AFD4DFF9A93689368936893689368936893689368936893689368 +%936893689368939AFFFFCA68936893689393FD06FF93689393FD4DFFCA8D +%938D938D938D938D938D938D9AFD05FFCA8D938D938D938D938DC3FFFFCA +%938D938D938DC3FD06FF8D938D9AFD4EFF938C9368938C9368938C936893 +%9AFD05FF9A938C9368938C9368939BFFFFCA8C9368938C93A1FD06FF9368 +%9393FD4EFF9A938D938C938D938C938D938CCAFD05FF9A8C938D938C938D +%938CC3FFFFA8938D938C938DFD07FF8D938CBCFD48FFC3FD05FFCA689368 +%936893689368936893A8FD05FF689368936893689368938D9A9393689368 +%93689AFD07FFC39AA1A1FD47FFBC8DC3FD05FFCA8D938D938D938D938D93 +%A1FD05FFC3938D938D938D938D938D938D938D938D938D93C3FD50FFA893 +%68938DFD06FFCA939368938C936894A8FD06FF948C9368938C9368938C93 +%68938C9368938C938DFD4FFFCA93938D938C9393FD07FFCACA9BC3CAFD08 +%FFC38C938D938C938D938C938D938C938D938C938DC3FD4DFFA89A689368 +%93689368939AFD12FFC36893689368936893689368936893689368936894 +%FD4DFFA1938D938D938D938D938D9393FD0FFFCABC8D938D938D938D938D +%938D938D938D938D938D93CAFD4CFFA19368938C9368938C9368938C9368 +%BDA8FD0AFFCA9A9368938C9368938C9368938C9368938C9368938C93A1FD +%4CFF9A938D938C938D938C938D938C938D938C93939A9BC3CACAA1C39A93 +%8C938D938C938D938C938D938C938D938C938D938C939AFD4CFFA1936893 +%689368936893689368936893689368936893689368936893689368936893 +%689368936893689368936893689368939AFD4CFFCA938D938D938D938D93 +%8D938D938D938D938D938D938D938D938D938D938D938D938D938D938D93 +%8D938D938D938D938D93A1FD4CFFCA938C9368938C9368938C9368938C93 +%68938C9368938C9368938C9368938C9368938C9368938C9368938C936893 +%8C936893A1FD4DFFC38C938D938C938D938C938D938C938D938C938D938C +%938D938C938D938C938D938C938D938C938D938C938D938C938DBDCAFD4E +%FF6893689368936893689368936893689368936893689368936893689368 +%93689368936893689368936893689368939AFD50FF9A938D938D938D938D +%938D938D938D938D938D938D938D938D938D938D938D938D938D938D938D +%938D938D938D93CAFD50FFCA938C9368938C9368938C9368938C9368938C +%9368938D9A9AC4A8CAA1CAA8A19A938C9368938C9368938C936894CAFD4B +%FFA8A8FD04FFCA8C938D938C938D938C938D938C938D938C938D9AA1FD0D +%FF9A938C938D938C938D9ACAFD4AFFA97D7D53FD04FF9493689368936893 +%6893689368936893689368C3FD10FFA893689368936893CAFD4BFF527D52 +%7DFD04FF938D938D938D938D938D938D938D938D938DCAFD12FFCA938D93 +%8D93C4FD4CFF7D527D7DFD04FF8C9368938C9368938C9368938C9368938C +%A1FD07FFCAA1C39BA1A1FD07FFA1938C9394FD07FFA8A87DA87DA8A8FD0D +%FF7EA87DA8A8FD0CFFA87DA87DA8A8FD0CFFA87DA87DA8A8FD09FF527D52 +%7DFD04FF938D938C938D938C938D938C938D938C93CAFD05FFCA948D938C +%938D938CC3FD06FF93938DFD07FF7D7D527D537D527D7DA8FD04FF7D7D53 +%7DA8A8537D527D537D7DFD09FFA87D527D537D527D7DA8FD08FFA87D537D +%527D537D52A8FD04FF537D527D537D527D537D5268936893689368936893 +%68936893689393FD05FFCA93689368936893689368C3FD05FFA1689AFD06 +%FF537D527D527D527D527D52A8FFFFFF7D527D527D527D527D527D527D52 +%A8FD06FF7D7D527D527D527D527D527DFD06FF7D7D527D527D527D527D52 +%7DA8FFA87D527D527D527D527D527D938D938D938D938D938D938D938D93 +%8DBCFD05FFC38D938D938D938D938D9393FD05FFCA93C3FD05FFFD047D52 +%A8A8A8537D7D7D52FFFFFFFD047D527D7DA8A8A87D7D527D7DFD05FFFD04 +%7D527DA8A8FD047D52A8FD04FFA87D52FD047DA87D7D527D7DA8FFFF7D7D +%527D7D7D527D7D7D5268938C9368938C9368938C9368938C939AFD05FF9A +%9368938C9368938C936893CAFD04FFCA68FD05FFA87D527D52A8FD04FF52 +%7D527DA8FFFF7D527D527D7DFD05FF527D527D7DFFFFFFA87D527D52A8FD +%04FF7E7D527D52FFFFFFA87D527D52A8FD04FF7D7D527D52FD05FF527D52 +%7DFD04FF938C938D938C938D938C938D938C938D938C938D938C938D938C +%938D938C938D938CCAFD05FF93FD06FF537D527DFD05FFA8527D53A8FFFF +%7D7D527D7DFD07FF537D527DFFFFFFA8537D52A8FD06FF7D7D537DA8FFFF +%A8527D53A8FD06FF7D7D527DA8FD04FF7D527D53FD04FF68936893689368 +%936893689368936893689368936893689368936893689368936893A1FD05 +%FF93FD05FFA87D527D52A8FD04FFA8A8A8FFA8FFFF7D527D52A8FD07FF7D +%527D52A8FFFF537D527DA8FD06FFA8527D52A8FFFF537D527DA8FD06FFA8 +%527D52A8FD04FF527D527DFD04FF938D938D938D938D938D938D938D938D +%938D938D938D938D938D938D9393BC949A94FD06FF9AFD06FF7D7D52FD04 +%7DA8FD08FF7D7D527DA8FD07FF7D7D527DA8FFFF7D7D7D52A87D7D7DA8FD +%067DA8FFFF7D527D7DFD10FF7D527D7DFD04FF8C9368938C9368938C9368 +%938C9368938C9368938C9393C3A1CACAFD0DFF9AFD06FFA8527D527D527D +%527D7DA8A8FD04FF7D527D52FD08FFA8527D52A8FFFF527D527D527D527D +%527D527D527D52A8FFFF527D527DFD10FF527D527DFD04FFBC8D938C938D +%938C938D938C938D938C938D938DC3CAFD12FFCAFD07FFA87D7D527D537D +%527D537DA8FFFFFF7D7D537DA8FD07FF7E7D537D7EFFA87D527D537D527D +%537D527D537D527DA8FFA87D537D7DFD10FF7D537D52FD04FF9B93689368 +%9368936893689368936893689393CAFD1EFFA87D527D527D527D527DA8FF +%FF7D527D52A8FD07FFA8527D52A8FFFF527D527D7DA87DA87DA87DA87DA8 +%7DFFFFFF527D527DFD10FF527D527DFD05FF8D938D938D938D938D938D93 +%8D938D9393FD23FFA8A8FD047D52A8FFFFFD047DA8FD07FFFD047DA8FFFF +%7D527D7DFD0EFF7D7D7D52FD09FFA8FFA8FD04FF7D7D7D52FD05FF9A8C93 +%68938C9368938C9368938C9393FD07FFA8C39A9A93938C936893A8FD0BFF +%A8A87DA8A8FD05FF7D7D527D7DFFFF7D527D52A8FD07FF7D527D52A8FFFF +%527D527DA8FD06FFA87D7D7DA8FFFF527D527DA8FD06FFA8527D52A8FD04 +%FF527D527DFD05FFA8938D938C938D938C938D938C938DCAFD06FF94938C +%938D938C938D938CCAFD0BFF7E537D52A8FD06FF527D537DFFFF7D7D527D +%7DFD07FF537D527DFFFFFFA8537D52A8FD06FF7D7D537DA8FFFFA8527D53 +%A8FD06FF7D7D527DA8FD04FF7D527D53FD06FF9393689368936893689368 +%93689AFD05FFCA689368936893689368936893A1FD0BFF7D7D527D53FD05 +%FF7D7D527D7DFFFF7D527D527D7DFD05FF527D527D7DFFFFFFA87D527D52 +%FD05FFA87D527D52FFFFFFA87D527D52FD05FFA87D527D52FD05FF527D52 +%7DFD07FF93938D938D938D938D938D93C4FD05FF94938D938D938D938D93 +%8D938DFD0DFF7D7D527D7DA8A8A87D7D527D7DA8FFFF7D7D52FD047DA8A8 +%A8537D7D7D53FD05FF7D7D527D7D7DA8A87D7D527D7DA8FD04FFFD047D52 +%A8A8A8FD047D52A8FD05FF7D527D7DA8A8A87DFFFFFFC48C9368938C9368 +%938C9368FD05FFCA9368938C9368938C9368938C93FD0DFFA8527D527D52 +%7D527D527D52A8FFFFFF7D527D527D527D527D527D527D52A8FD06FF7D7D +%527D527D527D527D527DFD06FF7D7D527D527D527D527D527DA8FD05FF7D +%7D527D527D527DFD04FFC38D938C938D938C938D93FD05FFCA8D938C938D +%938C938D938C9394FD0EFFA8537D527D537D527D53A8FD04FF7D7D537D7D +%7D537D527D537D7DFD09FF7D7D527D537D527D53A8FD08FF7D7D537D527D +%537D52A8FD08FF7D7D527D537D52FD05FF9A689368936893689368FD05FF +%A8936893689368936893689368C3FD10FFA8A87D7D7DA87DFD06FF7D527D +%52A8A8A87D7D7DA8A8FD0BFFA8A8FD057DFD0BFFA8A87D7D7DA8A8FD0BFF +%A8FD047DA8FD06FFBD8D938D938D938D93CAFD05FF93938D938D938D938D +%938D93CAFD1DFFFD047DA8FD43FFC368938C9368938CC3FD05FFC38C9368 +%938C9368938C939AFD1EFF7D527D52A8FD44FFCA93938D938C9394FD06FF +%C38D938C938D938C93A1FD1FFF7D7D527DA8FD46FFA19368936893A1FD07 +%FF9A9A939A94C3A8FD20FF7D527D52FD49FFCA9A938D93FD2EFF7D7D527D +%A8FD4BFFCA9BCAFD2EFFA8A8A8FDFCFFFD40FFFF +%%EndData +%%EndComments +%%BeginProlog +%%BeginResource: procset Adobe_level2_AI5 1.2 0 +%%Title: (Adobe Illustrator (R) Version 5.0 Level 2 Emulation) +%%Version: 1.2 0 +%%CreationDate: (04/10/93) () +%%Copyright: ((C) 1987-1996 Adobe Systems Incorporated All Rights Reserved) +userdict /Adobe_level2_AI5 26 dict dup begin + put + /packedarray where not + { + userdict begin + /packedarray + { + array astore readonly + } bind def + /setpacking /pop load def + /currentpacking false def + end + 0 + } if + pop + userdict /defaultpacking currentpacking put true setpacking + /initialize + { + Adobe_level2_AI5 begin + } bind def + /terminate + { + currentdict Adobe_level2_AI5 eq + { + end + } if + } bind def + mark + /setcustomcolor where not + { + /findcmykcustomcolor + { + (AI8_CMYK_CustomColor) + 6 packedarray + } bind def + /findrgbcustomcolor + { + (AI8_RGB_CustomColor) + 5 packedarray + } bind def + /setcustomcolor + { + exch + aload pop dup + (AI8_CMYK_CustomColor) eq + { + pop pop + 4 + { + 4 index mul + 4 1 roll + } repeat + 5 -1 roll pop + setcmykcolor + } + { + dup (AI8_RGB_CustomColor) eq + { + pop pop + 3 + { + 1 exch sub + 3 index mul + 1 exch sub + 3 1 roll + } repeat + 4 -1 roll pop + setrgbcolor + } + { + pop + 4 + { + 4 index mul 4 1 roll + } repeat + 5 -1 roll pop + setcmykcolor + } ifelse + } ifelse + } + def + } if + /setAIseparationgray + { + false setoverprint + 0 setgray + /setseparationgray where{ + pop setseparationgray + }{ + /setcolorspace where{ + pop + [/Separation (All) /DeviceCMYK {dup dup dup}] setcolorspace + 1 exch sub setcolor + }{ + setgray + }ifelse + }ifelse + } def + + /gt38? mark {version cvr cvx exec} stopped {cleartomark true} {38 gt exch pop} ifelse def + userdict /deviceDPI 72 0 matrix defaultmatrix dtransform dup mul exch dup mul add sqrt put + userdict /level2? + systemdict /languagelevel known dup + { + pop systemdict /languagelevel get 2 ge + } if + put +/level2ScreenFreq +{ + begin + 60 + HalftoneType 1 eq + { + pop Frequency + } if + HalftoneType 2 eq + { + pop GrayFrequency + } if + HalftoneType 5 eq + { + pop Default level2ScreenFreq + } if + end +} bind def +userdict /currentScreenFreq + level2? {currenthalftone level2ScreenFreq} {currentscreen pop pop} ifelse put +level2? not + { + /setcmykcolor where not + { + /setcmykcolor + { + exch .11 mul add exch .59 mul add exch .3 mul add + 1 exch sub setgray + } def + } if + /currentcmykcolor where not + { + /currentcmykcolor + { + 0 0 0 1 currentgray sub + } def + } if + /setoverprint where not + { + /setoverprint /pop load def + } if + /selectfont where not + { + /selectfont + { + exch findfont exch + dup type /arraytype eq + { + makefont + } + { + scalefont + } ifelse + setfont + } bind def + } if + /cshow where not + { + /cshow + { + [ + 0 0 5 -1 roll aload pop + ] cvx bind forall + } bind def + } if + } if + cleartomark + /anyColor? + { + add add add 0 ne + } bind def + /testColor + { + gsave + setcmykcolor currentcmykcolor + grestore + } bind def + /testCMYKColorThrough + { + testColor anyColor? + } bind def + userdict /composite? + 1 0 0 0 testCMYKColorThrough + 0 1 0 0 testCMYKColorThrough + 0 0 1 0 testCMYKColorThrough + 0 0 0 1 testCMYKColorThrough + and and and + put + composite? not + { + userdict begin + gsave + /cyan? 1 0 0 0 testCMYKColorThrough def + /magenta? 0 1 0 0 testCMYKColorThrough def + /yellow? 0 0 1 0 testCMYKColorThrough def + /black? 0 0 0 1 testCMYKColorThrough def + grestore + /isCMYKSep? cyan? magenta? yellow? black? or or or def + /customColor? isCMYKSep? not def + end + } if + end defaultpacking setpacking +%%EndResource +%%BeginProcSet: Adobe_ColorImage_AI6 1.2 0 +userdict /Adobe_ColorImage_AI6 known not +{ + userdict /Adobe_ColorImage_AI6 50 dict put +} if +userdict /Adobe_ColorImage_AI6 get begin +/initialize { + Adobe_ColorImage_AI6 begin + Adobe_ColorImage_AI6 { + dup type /arraytype eq { + dup xcheck { + bind + } if + } if + pop pop + } forall +} def +/terminate { end } def +currentdict /Adobe_ColorImage_AI6_Vars known not { + /Adobe_ColorImage_AI6_Vars 40 dict def +} if +Adobe_ColorImage_AI6_Vars begin + /plateindex -1 def + /_newproc null def + /_proc1 null def + /_proc2 null def + /channelcount 0 def + /sourcecount 0 def + /sourcearray 4 array def + /_ptispace null def + /_ptiname null def + /_pti0 0 def + /_pti1 0 def + /_ptiproc null def + /_ptiscale 0 def + /_pticomps 0 def + /_ptibuf 0 string def + /_gtigray 0 def + /_cticmyk null def + /_rtirgb null def + /XIEnable true def + /XIType 0 def + /XIEncoding 0 def + /XICompression 0 def + /XIChannelCount 0 def + /XIBitsPerPixel 0 def + /XIImageHeight 0 def + /XIImageWidth 0 def + /XIImageMatrix null def + /XIRowBytes 0 def + /XIFile null def + /XIBuffer1 null def + /XIBuffer2 null def + /XIDataProc null def + /XIVersion 6 def + /XIColorSpace /DeviceGray def + /XIColorValues 0 def +end +currentdict /_colorimage known not { + /colorimage where { + /colorimage get /_colorimage exch def + }{ + /_colorimage null def + } ifelse +} if +/_image systemdict /image get def +/_currenttransfer systemdict /currenttransfer get def +/FourEqual { + 4 index ne { + pop pop pop false + }{ + 4 index ne { + pop pop false + }{ + 4 index ne { + pop false + }{ + 4 index eq + } ifelse + } ifelse + } ifelse +} def +/TestPlateIndex { + Adobe_ColorImage_AI6_Vars begin + /plateindex -1 def + /setcmykcolor where { + pop + gsave + 1 0 0 0 setcmykcolor systemdict /currentgray get exec 1 exch sub + 0 1 0 0 setcmykcolor systemdict /currentgray get exec 1 exch sub + 0 0 1 0 setcmykcolor systemdict /currentgray get exec 1 exch sub + 0 0 0 1 setcmykcolor systemdict /currentgray get exec 1 exch sub + grestore + 1 0 0 0 FourEqual { + /plateindex 0 def + }{ + 0 1 0 0 FourEqual { + /plateindex 1 def + }{ + 0 0 1 0 FourEqual { + /plateindex 2 def + }{ + 0 0 0 1 FourEqual { + /plateindex 3 def + }{ + 0 0 0 0 FourEqual { + /plateindex 5 def + } if + } ifelse + } ifelse + } ifelse + } ifelse + pop pop pop pop + } if + plateindex + end +} def +/concatprocs { + /packedarray where { + pop dup type /packedarraytype eq 2 index type + /packedarraytype eq or + }{ + false + } ifelse + { + /_proc2 exch cvlit def + /_proc1 exch cvlit def + _proc1 aload pop + _proc2 aload pop + _proc1 length + _proc2 length add + packedarray cvx + }{ + /_proc2 exch cvlit def + /_proc1 exch cvlit def + /_newproc _proc1 length _proc2 length add array def + _newproc 0 _proc1 putinterval + _newproc _proc1 length _proc2 putinterval + _newproc cvx + } ifelse +} def +/clrspaceissepn { + type /arraytype eq +} def +/clrspacegetname { + dup clrspaceissepn {dup length 2 sub get}{pop ()} ifelse +} def +/clrspacegetalt { + aload pop pop pop colormake +} def +/clrspacegetcomps { + dup /DeviceGray eq { + pop 1 + }{ + dup /DeviceRGB eq { + pop 3 + }{ + /DeviceCMYK eq { + 4 + }{ + 1 + } ifelse + } ifelse + } ifelse +} def +/clrspacemarksplate { + dup /DeviceGray eq { + pop plateindex 3 eq + }{ + dup /DeviceRGB eq { + pop plateindex 5 ne + }{ + dup /DeviceCMYK eq { + pop plateindex 5 ne + }{ + /findcmykcustomcolor where { + pop + dup length 2 sub get + 0.1 0.1 0.1 0.1 5 -1 roll + findcmykcustomcolor 1 setcustomcolor + systemdict /currentgray get exec + 1 ne + }{ + pop plateindex 5 ne + } ifelse + } ifelse + } ifelse + } ifelse +} def +/colormake { + dup clrspacegetcomps + exch 1 index 2 add 1 roll + dup 1 eq {pop}{array astore} ifelse + exch +} def +/colorexpand { + dup clrspacegetname exch + dup clrspaceissepn { + clrspacegetalt + exch 4 1 roll + }{ + 1 3 1 roll + } ifelse +} def +/colortint { + dup /DeviceGray eq { + 3 1 roll 1 exch sub mul 1 exch sub exch + }{ + dup /DeviceRGB eq { + 3 1 roll {1 exch sub 1 index mul 1 exch sub exch} forall pop 3 array astore exch + }{ + dup /DeviceCMYK eq { + 3 1 roll {1 index mul exch} forall pop 4 array astore exch + }{ + 3 1 roll mul exch + } ifelse + } ifelse + } ifelse +} def +/colortocmyk { + dup /DeviceGray eq { + pop 1 exch sub 0 0 0 4 -1 roll 4 array astore + }{ + dup /DeviceRGB eq { + pop aload pop _rgbtocmyk 4 array astore + }{ + dup /DeviceCMYK eq { + pop + }{ + clrspacegetalt colortint colortocmyk + } ifelse + } ifelse + } ifelse +} def +/makeimagedict { + 7 dict begin + /ImageType 1 def + /Decode exch def + /DataSource exch def + /ImageMatrix exch def + /BitsPerComponent exch def + /Height exch def + /Width exch def + currentdict end +} def +/stringinvert { + 0 1 2 index length 1 sub { + dup 2 index exch get 255 exch sub 2 index 3 1 roll put + } for +} def +/stringknockout { + 0 1 2 index length 1 sub { + 255 2 index 3 1 roll put + } for +} def +/stringapply { + 0 1 4 index length 1 sub { + dup + 4 index exch get + 3 index 3 1 roll + 3 index exec + } for + pop exch pop +} def +/WalkRGBString { + 0 3 index + dup length 1 sub 0 3 3 -1 roll { + 3 getinterval {} forall + 5 index exec + 3 index + } for + + 5 {pop} repeat +} def +/WalkCMYKString +{ + 0 3 index + dup length 1 sub 0 4 3 -1 roll { + 4 getinterval {} forall + + 6 index exec + + 3 index + + } for + + 5 { pop } repeat + +} def +/StuffRGBIntoGrayString +{ + .11 mul exch + + .59 mul add exch + + .3 mul add + + cvi 3 copy put + + pop 1 add +} def +/StuffCMYKIntoGrayString +{ + exch .11 mul add + + exch .59 mul add + + exch .3 mul add + + dup 255 gt { pop 255 } if + + 255 exch sub cvi 3 copy put + + pop 1 add +} def +/RGBToGrayImageProc { + Adobe_ColorImage_AI6_Vars begin + sourcearray 0 get exec + dup length 3 idiv string + dup 3 1 roll + + /StuffRGBIntoGrayString load exch + WalkRGBString + end +} def +/CMYKToGrayImageProc { + Adobe_ColorImage_AI6_Vars begin + sourcearray 0 get exec + dup length 4 idiv string + dup 3 1 roll + + /StuffCMYKIntoGrayString load exch + WalkCMYKString + end +} def +/SeparateCMYKImageProc { + Adobe_ColorImage_AI6_Vars begin + sourcecount 0 ne { + sourcearray plateindex get exec + }{ + sourcearray 0 get exec + + dup length 4 idiv string + + 0 2 index + + plateindex 4 2 index length 1 sub { + get 255 exch sub + + 3 copy put pop 1 add + + 2 index + } for + pop pop exch pop + } ifelse + end +} def + +/ColorImageCompositeEmulator { + pop true eq { + Adobe_ColorImage_AI6_Vars /sourcecount get 5 add { pop } repeat + }{ + Adobe_ColorImage_AI6_Vars /channelcount get 1 ne { + Adobe_ColorImage_AI6_Vars begin + sourcearray 0 3 -1 roll put + + channelcount 3 eq {/RGBToGrayImageProc}{/CMYKToGrayImageProc} ifelse + load + end + } if + image + } ifelse +} def +/colorimage { + Adobe_ColorImage_AI6_Vars begin + /channelcount 1 index def + /sourcecount 2 index 1 eq { channelcount 1 sub } { 0 } ifelse def + 4 sourcecount add index + end + + dup 8 eq exch 1 eq or not { + /_colorimage load null ne { + _colorimage + }{ + Adobe_ColorImage_AI6_Vars /sourcecount get + 7 add { pop } repeat + } ifelse + }{ + dup 3 eq TestPlateIndex dup -1 eq exch 5 eq or or { + /_colorimage load null eq { + ColorImageCompositeEmulator + }{ + dup 1 eq { + pop pop image + }{ + Adobe_ColorImage_AI6_Vars /plateindex get 5 eq { + gsave + + 0 _currenttransfer exec + 1 _currenttransfer exec + eq + { 0 _currenttransfer exec 0.5 lt } + { 0 _currenttransfer exec 1 _currenttransfer exec gt } ifelse + + { { pop 0 } } { { pop 1 } } ifelse + systemdict /settransfer get exec + } if + + _colorimage + + Adobe_ColorImage_AI6_Vars /plateindex get 5 eq { + grestore + } if + } ifelse + } ifelse + }{ + dup 1 eq { + pop pop + image + }{ + pop pop + Adobe_ColorImage_AI6_Vars begin + sourcecount -1 0 { + exch sourcearray 3 1 roll put + } for + /SeparateCMYKImageProc load + end + systemdict /image get exec + } ifelse + } ifelse + } ifelse +} def +/proctintimage { + /_ptispace exch store /_ptiname exch store /_pti1 exch store /_pti0 exch store /_ptiproc exch store + /_pticomps _ptispace clrspacegetcomps store + /_ptiscale _pti1 _pti0 sub store + level2? { + _ptiname length 0 gt version cvr 2012 ge and { + [/Separation _ptiname _ptispace {_ptiproc}] setcolorspace + [_pti0 _pti1] makeimagedict _image + }{ + [/Indexed _ptispace 255 {255 div _ptiscale mul _pti0 add _ptiproc}] setcolorspace + [0 255] makeimagedict _image + } ifelse + }{ + _pticomps 1 eq { + { + dup + { + 255 div _ptiscale mul _pti0 add _ptiproc 255 mul cvi put + } stringapply + } concatprocs _image + }{ + { + dup length _pticomps mul dup _ptibuf length ne {/_ptibuf exch string store}{pop} ifelse + _ptibuf { + exch _pticomps mul exch 255 div _ptiscale mul _pti0 add _ptiproc + _pticomps 2 add -2 roll + _pticomps 1 sub -1 0 { + 1 index add 2 index exch + 5 -1 roll + 255 mul cvi put + } for + pop pop + } stringapply + } concatprocs false _pticomps + /_colorimage load null eq {7 {pop} repeat}{_colorimage} ifelse + } ifelse + } ifelse +} def +/graytintimage { + /_gtigray 5 -1 roll store + {1 _gtigray sub mul 1 exch sub} 4 1 roll + /DeviceGray proctintimage +} def +/cmyktintimage { + /_cticmyk 5 -1 roll store + {_cticmyk {1 index mul exch} forall pop} 4 1 roll + /DeviceCMYK proctintimage +} def +/rgbtintimage { + /_rtirgb 5 -1 roll store + {_rtirgb {1 exch sub 1 index mul 1 exch sub exch} forall pop} 4 1 roll + /DeviceRGB proctintimage +} def +/tintimage { + TestPlateIndex -1 eq { + colorexpand + 3 -1 roll 5 -1 roll {0}{0 exch} ifelse 4 2 roll + dup /DeviceGray eq { + pop graytintimage + }{ + dup /DeviceRGB eq { + pop rgbtintimage + }{ + pop cmyktintimage + } ifelse + } ifelse + }{ + dup clrspacemarksplate { + plateindex 5 lt { + colortocmyk plateindex get 1 exch sub + exch {1 0}{0 1} ifelse () graytintimage + }{ + pop exch {0}{0 exch} ifelse 0 3 1 roll () graytintimage + } ifelse + }{ + pop pop pop + {pop 1} 0 1 () /DeviceGray proctintimage + } ifelse + } ifelse +} def +/XINullImage { +} def +/XIImageMask { + XIImageWidth XIImageHeight false + [XIImageWidth 0 0 XIImageHeight neg 0 0] + /XIDataProc load + imagemask +} def +/XIImageTint { + 0 setgray + XIImageWidth XIImageHeight XIBitsPerPixel + [XIImageWidth 0 0 XIImageHeight neg 0 0] + /XIDataProc load + XIType 3 eq XIColorValues XIColorSpace tintimage +} def +/XIImage { + 0 setgray + XIImageWidth XIImageHeight XIBitsPerPixel + [XIImageWidth 0 0 XIImageHeight neg 0 0] + /XIDataProc load + XIChannelCount 1 eq {image}{false XIChannelCount colorimage} ifelse +} def +/XG { + pop pop +} def +/XF { + 13 {pop} repeat +} def +/Xh { + Adobe_ColorImage_AI6_Vars begin + gsave + /XIType exch def + /XIImageHeight exch def + /XIImageWidth exch def + /XIImageMatrix exch def + 0 0 moveto + XIImageMatrix concat + XIImageWidth XIImageHeight scale + + XIType 1 eq { + /_lp /null ddef + _fc + /_lp /imagemask ddef + } + if + /XIVersion 7 def + end +} def +/XH { + Adobe_ColorImage_AI6_Vars begin + /XIVersion 6 def + grestore + end +} def +/XIEnable { + Adobe_ColorImage_AI6_Vars /XIEnable 3 -1 roll put +} def +/XC { + Adobe_ColorImage_AI6_Vars begin + colormake + /XIColorSpace exch def + /XIColorValues exch def + end +} def +/XI +{ + Adobe_ColorImage_AI6_Vars begin + gsave + /XIType exch def + cvi dup + 256 idiv /XICompression exch store + 256 mod /XIEncoding exch store + pop pop + /XIChannelCount exch def + /XIBitsPerPixel exch def + /XIImageHeight exch def + /XIImageWidth exch def + pop pop pop pop + /XIImageMatrix exch def + XIBitsPerPixel 1 eq { + XIImageWidth 8 div ceiling cvi + }{ + XIImageWidth XIChannelCount mul + } ifelse + /XIRowBytes exch def + XIEncoding 0 ne XIVersion 6 le and { + currentfile 128 string readline pop pop + } if + XICompression 0 eq { + /XIBuffer1 XIRowBytes string def + XIEncoding 0 eq { + {currentfile XIBuffer1 readhexstring pop} + }{ + {currentfile XIBuffer1 readstring pop} + } ifelse + }{ + /XIBuffer1 256 string def + /XIBuffer2 XIRowBytes string def + {currentfile XIBuffer1 readline pop (%) anchorsearch {pop} if} + /ASCIIHexDecode filter /DCTDecode filter + /XIFile exch def + {XIFile XIBuffer2 readstring pop} + } ifelse + /XIDataProc exch def + + XIVersion 6 le { + 0 0 moveto + XIImageMatrix concat + XIImageWidth XIImageHeight scale + XIType 1 eq { + /_lp /null ddef + _fc + /_lp /imagemask ddef + } if + } if + XIEnable { + XIType 1 eq { + XIImageMask + }{ + XIType 2 eq XIType 3 eq or { + XIImageTint + }{ + XIImage + } ifelse + } ifelse + }{ + XINullImage + } ifelse + grestore + end +} def +end +%%EndProcSet +%%BeginResource: procset Adobe_Illustrator_AI5 1.2 0 +%%Title: (Adobe Illustrator (R) Version 7.0 Full Prolog) +%%Version: 1.2 0 +%%CreationDate: (3/7/1994) () +%%Copyright: ((C) 1987-1996 Adobe Systems Incorporated All Rights Reserved) +currentpacking true setpacking +userdict /Adobe_Illustrator_AI5_vars 107 dict dup begin +put +/_eo false def +/_lp /none def +/_pf +{ +} def +/_ps +{ +} def +/_psf +{ +} def +/_pss +{ +} def +/_pjsf +{ +} def +/_pjss +{ +} def +/_pola 0 def +/_doClip 0 def +/cf currentflat def +/_lineorientation 0 def +/_charorientation 0 def +/_yokoorientation 0 def +/_tm matrix def +/_renderStart +[ +/e0 /r0 /a0 /o0 /e1 /r1 /a1 /i0 +] def +/_renderEnd +[ +null null null null /i1 /i1 /i1 /i1 +] def +/_render -1 def +/_shift [0 0] def +/_ax 0 def +/_ay 0 def +/_cx 0 def +/_cy 0 def +/_leading +[ +0 0 +] def +/_ctm matrix def +/_mtx matrix def +/_sp 16#020 def +/_hyphen (-) def +/_fontSize 0 def +/_fontAscent 0 def +/_fontDescent 0 def +/_fontHeight 0 def +/_fontRotateAdjust 0 def +/Ss 256 string def +Ss 0 (fonts/) putinterval +/_cnt 0 def +/_scale [1 1] def +/_nativeEncoding 0 def +/_useNativeEncoding 0 def +/_tempEncode 0 def +/_pntr 0 def +/_tDict 2 dict def +/_hfname 100 string def +/_hffound false def +/Tx +{ +} def +/Tj +{ +} def +/CRender +{ +} def +/_AI3_savepage +{ +} def +/_gf null def +/_cf 4 array def +/_rgbf 3 array def +/_if null def +/_of false def +/_fc +{ +} def +/_gs null def +/_cs 4 array def +/_rgbs 3 array def +/_is null def +/_os false def +/_sc +{ +} def +/_pd 1 dict def +/_ed 15 dict def +/_pm matrix def +/_fm null def +/_fd null def +/_fdd null def +/_sm null def +/_sd null def +/_sdd null def +/_i null def +/_lobyte 0 def +/_hibyte 0 def +/_cproc null def +/_cscript 0 def +/_hvax 0 def +/_hvay 0 def +/_hvwb 0 def +/_hvcx 0 def +/_hvcy 0 def +/_bitfont null def +/_bitlobyte 0 def +/_bithibyte 0 def +/_bitkey null def +/_bitdata null def +/_bitindex 0 def +/discardSave null def +/buffer 256 string def +/beginString null def +/endString null def +/endStringLength null def +/layerCnt 1 def +/layerCount 1 def +/perCent (%) 0 get def +/perCentSeen? false def +/newBuff null def +/newBuffButFirst null def +/newBuffLast null def +/clipForward? false def +end +userdict /Adobe_Illustrator_AI5 known not { + userdict /Adobe_Illustrator_AI5 95 dict put +} if +userdict /Adobe_Illustrator_AI5 get begin +/initialize +{ + Adobe_Illustrator_AI5 dup begin + Adobe_Illustrator_AI5_vars begin + discardDict + { + bind pop pop + } forall + dup /nc get begin + { + dup xcheck 1 index type /operatortype ne and + { + bind + } if + pop pop + } forall + end + newpath +} def +/terminate +{ + end + end +} def +/_ +null def +/ddef +{ + Adobe_Illustrator_AI5_vars 3 1 roll put +} def +/xput +{ + dup load dup length exch maxlength eq + { + dup dup load dup + length 2 mul dict copy def + } if + load begin + def + end +} def +/npop +{ + { + pop + } repeat +} def +/hswj +{ + dup stringwidth 3 2 roll + { + _hvwb eq { exch _hvcx add exch _hvcy add } if + exch _hvax add exch _hvay add + } cforall +} def +/vswj +{ + 0 0 3 -1 roll + { + dup 255 le + _charorientation 1 eq + and + { + dup cstring stringwidth 5 2 roll + _hvwb eq { exch _hvcy sub exch _hvcx sub } if + exch _hvay sub exch _hvax sub + 4 -1 roll sub exch + 3 -1 roll sub exch + } + { + _hvwb eq { exch _hvcy sub exch _hvcx sub } if + exch _hvay sub exch _hvax sub + _fontHeight sub + } ifelse + } cforall +} def +/swj +{ + 6 1 roll + /_hvay exch ddef + /_hvax exch ddef + /_hvwb exch ddef + /_hvcy exch ddef + /_hvcx exch ddef + _lineorientation 0 eq { hswj } { vswj } ifelse +} def +/sw +{ + 0 0 0 6 3 roll swj +} def +/vjss +{ + 4 1 roll + { + dup cstring + dup length 1 eq + _charorientation 1 eq + and + { + -90 rotate + currentpoint + _fontRotateAdjust add + moveto + gsave + false charpath currentpoint + 5 index setmatrix stroke + grestore + _fontRotateAdjust sub + moveto + _sp eq + { + 5 index 5 index rmoveto + } if + 2 copy rmoveto + 90 rotate + } + { + currentpoint + _fontHeight sub + 5 index sub + 3 index _sp eq + { + 9 index sub + } if + + currentpoint + exch 4 index stringwidth pop 2 div sub + exch _fontAscent sub + moveto + + gsave + 2 index false charpath + 6 index setmatrix stroke + grestore + + moveto pop pop + } ifelse + } cforall + 6 npop +} def +/hjss +{ + 4 1 roll + { + dup cstring + gsave + false charpath currentpoint + 5 index setmatrix stroke + grestore + moveto + _sp eq + { + 5 index 5 index rmoveto + } if + 2 copy rmoveto + } cforall + 6 npop +} def +/jss +{ + _lineorientation 0 eq { hjss } { vjss } ifelse +} def +/ss +{ + 0 0 0 7 3 roll jss +} def +/vjsp +{ + 4 1 roll + { + dup cstring + dup length 1 eq + _charorientation 1 eq + and + { + -90 rotate + currentpoint + _fontRotateAdjust add + moveto + false charpath + currentpoint + _fontRotateAdjust sub + moveto + _sp eq + { + 5 index 5 index rmoveto + } if + 2 copy rmoveto + 90 rotate + } + { + currentpoint + _fontHeight sub + 5 index sub + 3 index _sp eq + { + 9 index sub + } if + + currentpoint + exch 4 index stringwidth pop 2 div sub + exch _fontAscent sub + moveto + + 2 index false charpath + + moveto pop pop + } ifelse + } cforall + 6 npop +} def +/hjsp +{ + 4 1 roll + { + dup cstring + false charpath + _sp eq + { + 5 index 5 index rmoveto + } if + 2 copy rmoveto + } cforall + 6 npop +} def +/jsp +{ + matrix currentmatrix + _lineorientation 0 eq {hjsp} {vjsp} ifelse +} def +/sp +{ + matrix currentmatrix + 0 0 0 7 3 roll + _lineorientation 0 eq {hjsp} {vjsp} ifelse +} def +/pl +{ + transform + 0.25 sub round 0.25 add exch + 0.25 sub round 0.25 add exch + itransform +} def +/setstrokeadjust where +{ + pop true setstrokeadjust + /c + { + curveto + } def + /C + /c load def + /v + { + currentpoint 6 2 roll curveto + } def + /V + /v load def + /y + { + 2 copy curveto + } def + /Y + /y load def + /l + { + lineto + } def + /L + /l load def + /m + { + moveto + } def +} +{ + /c + { + pl curveto + } def + /C + /c load def + /v + { + currentpoint 6 2 roll pl curveto + } def + /V + /v load def + /y + { + pl 2 copy curveto + } def + /Y + /y load def + /l + { + pl lineto + } def + /L + /l load def + /m + { + pl moveto + } def +} ifelse +/d +{ + setdash +} def +/cf +{ +} def +/i +{ + dup 0 eq + { + pop cf + } if + setflat +} def +/j +{ + setlinejoin +} def +/J +{ + setlinecap +} def +/M +{ + setmiterlimit +} def +/w +{ + setlinewidth +} def +/XR +{ + 0 ne + /_eo exch ddef +} def +/H +{ +} def +/h +{ + closepath +} def +/N +{ + _pola 0 eq + { + _doClip 1 eq + { + _eo {eoclip} {clip} ifelse /_doClip 0 ddef + } if + newpath + } + { + /CRender + { + N + } ddef + } ifelse +} def +/n +{ + N +} def +/F +{ + _pola 0 eq + { + _doClip 1 eq + { + gsave _pf grestore _eo {eoclip} {clip} ifelse newpath /_lp /none ddef _fc + /_doClip 0 ddef + } + { + _pf + } ifelse + } + { + /CRender + { + F + } ddef + } ifelse +} def +/f +{ + closepath + F +} def +/S +{ + _pola 0 eq + { + _doClip 1 eq + { + gsave _ps grestore _eo {eoclip} {clip} ifelse newpath /_lp /none ddef _sc + /_doClip 0 ddef + } + { + _ps + } ifelse + } + { + /CRender + { + S + } ddef + } ifelse +} def +/s +{ + closepath + S +} def +/B +{ + _pola 0 eq + { + _doClip 1 eq + gsave F grestore + { + gsave S grestore _eo {eoclip} {clip} ifelse newpath /_lp /none ddef _sc + /_doClip 0 ddef + } + { + S + } ifelse + } + { + /CRender + { + B + } ddef + } ifelse +} def +/b +{ + closepath + B +} def +/W +{ + /_doClip 1 ddef +} def +/* +{ + count 0 ne + { + dup type /stringtype eq + { + pop + } if + } if + newpath +} def +/u +{ +} def +/U +{ +} def +/q +{ + _pola 0 eq + { + gsave + } if +} def +/Q +{ + _pola 0 eq + { + grestore + } if +} def +/*u +{ + _pola 1 add /_pola exch ddef +} def +/*U +{ + _pola 1 sub /_pola exch ddef + _pola 0 eq + { + CRender + } if +} def +/D +{ + pop +} def +/*w +{ +} def +/*W +{ +} def +/` +{ + /_i save ddef + clipForward? + { + nulldevice + } if + 6 1 roll 4 npop + concat pop + userdict begin + /showpage + { + } def + 0 setgray + 0 setlinecap + 1 setlinewidth + 0 setlinejoin + 10 setmiterlimit + [] 0 setdash + /setstrokeadjust where {pop false setstrokeadjust} if + newpath + 0 setgray + false setoverprint +} def +/~ +{ + end + _i restore +} def +/O +{ + 0 ne + /_of exch ddef + /_lp /none ddef +} def +/R +{ + 0 ne + /_os exch ddef + /_lp /none ddef +} def +/g +{ + /_gf exch ddef + /_fc + { + _lp /fill ne + { + _of setoverprint + _gf setgray + /_lp /fill ddef + } if + } ddef + /_pf + { + _fc + _eo {eofill} {fill} ifelse + } ddef + /_psf + { + _fc + hvashow + } ddef + /_pjsf + { + _fc + hvawidthshow + } ddef + /_lp /none ddef +} def +/G +{ + /_gs exch ddef + /_sc + { + _lp /stroke ne + { + _os setoverprint + _gs setgray + /_lp /stroke ddef + } if + } ddef + /_ps + { + _sc + stroke + } ddef + /_pss + { + _sc + ss + } ddef + /_pjss + { + _sc + jss + } ddef + /_lp /none ddef +} def +/k +{ + _cf astore pop + /_fc + { + _lp /fill ne + { + _of setoverprint + _cf aload pop setcmykcolor + /_lp /fill ddef + } if + } ddef + /_pf + { + _fc + _eo {eofill} {fill} ifelse + } ddef + /_psf + { + _fc + hvashow + } ddef + /_pjsf + { + _fc + hvawidthshow + } ddef + /_lp /none ddef +} def +/K +{ + _cs astore pop + /_sc + { + _lp /stroke ne + { + _os setoverprint + _cs aload pop setcmykcolor + /_lp /stroke ddef + } if + } ddef + /_ps + { + _sc + stroke + } ddef + /_pss + { + _sc + ss + } ddef + /_pjss + { + _sc + jss + } ddef + /_lp /none ddef +} def +/Xa +{ + _rgbf astore pop + /_fc + { + _lp /fill ne + { + _of setoverprint + _rgbf aload pop setrgbcolor + /_lp /fill ddef + } if + } ddef + /_pf + { + _fc + _eo {eofill} {fill} ifelse + } ddef + /_psf + { + _fc + hvashow + } ddef + /_pjsf + { + _fc + hvawidthshow + } ddef + /_lp /none ddef +} def +/XA +{ + _rgbs astore pop + /_sc + { + _lp /stroke ne + { + _os setoverprint + _rgbs aload pop setrgbcolor + /_lp /stroke ddef + } if + } ddef + /_ps + { + _sc + stroke + } ddef + /_pss + { + _sc + ss + } ddef + /_pjss + { + _sc + jss + } ddef + /_lp /none ddef +} def +/_rgbtocmyk +{ +3 + { + 1 exch sub 3 1 roll + } repeat +3 copy 1 4 1 roll +3 + { + 3 index 2 copy gt + { + exch + } if + pop 4 1 roll + } repeat +pop pop pop +4 1 roll +3 + { + 3 index sub + 3 1 roll + } repeat +4 -1 roll +} def +/Xx +{ + exch + /_gf exch ddef + 0 eq + { + findcmykcustomcolor + } + { + /findrgbcustomcolor where not { + 4 1 roll _rgbtocmyk + 5 -1 roll + findcmykcustomcolor + } + { + pop + findrgbcustomcolor + } ifelse + } ifelse + /_if exch ddef + /_fc + { + _lp /fill ne + { + _of setoverprint + _if _gf 1 exch sub setcustomcolor + /_lp /fill ddef + } if + } ddef + /_pf + { + _fc + _eo {eofill} {fill} ifelse + } ddef + /_psf + { + _fc + hvashow + } ddef + /_pjsf + { + _fc + hvawidthshow + } ddef + /_lp /none ddef +} def +/XX +{ + exch + /_gs exch ddef + 0 eq + { + findcmykcustomcolor + } + { + /findrgbcustomcolor where not { + 4 1 roll _rgbtocmyk + 5 -1 roll + findcmykcustomcolor + } + { + pop + findrgbcustomcolor + } ifelse + } ifelse + /_is exch ddef + /_sc + { + _lp /stroke ne + { + _os setoverprint + _is _gs 1 exch sub setcustomcolor + /_lp /stroke ddef + } if + } ddef + /_ps + { + _sc + stroke + } ddef + /_pss + { + _sc + ss + } ddef + /_pjss + { + _sc + jss + } ddef + /_lp /none ddef +} def +/x +{ + /_gf exch ddef + findcmykcustomcolor + /_if exch ddef + /_fc + { + _lp /fill ne + { + _of setoverprint + _if _gf 1 exch sub setcustomcolor + /_lp /fill ddef + } if + } ddef + /_pf + { + _fc + _eo {eofill} {fill} ifelse + } ddef + /_psf + { + _fc + hvashow + } ddef + /_pjsf + { + _fc + hvawidthshow + } ddef + /_lp /none ddef +} def +/X +{ + /_gs exch ddef + findcmykcustomcolor + /_is exch ddef + /_sc + { + _lp /stroke ne + { + _os setoverprint + _is _gs 1 exch sub setcustomcolor + /_lp /stroke ddef + } if + } ddef + /_ps + { + _sc + stroke + } ddef + /_pss + { + _sc + ss + } ddef + /_pjss + { + _sc + jss + } ddef + /_lp /none ddef +} def +/A +{ + pop +} def +/annotatepage +{ +userdict /annotatepage 2 copy known {get exec} {pop pop} ifelse +} def +/XT { + pop pop +} def +/discard +{ + save /discardSave exch store + discardDict begin + /endString exch store + gt38? + { + 2 add + } if + load + stopped + pop + end + discardSave restore +} bind def +userdict /discardDict 7 dict dup begin +put +/pre38Initialize +{ + /endStringLength endString length store + /newBuff buffer 0 endStringLength getinterval store + /newBuffButFirst newBuff 1 endStringLength 1 sub getinterval store + /newBuffLast newBuff endStringLength 1 sub 1 getinterval store +} def +/shiftBuffer +{ + newBuff 0 newBuffButFirst putinterval + newBuffLast 0 + currentfile read not + { + stop + } if + put +} def +0 +{ + pre38Initialize + mark + currentfile newBuff readstring exch pop + { + { + newBuff endString eq + { + cleartomark stop + } if + shiftBuffer + } loop + } + { + stop + } ifelse +} def +1 +{ + pre38Initialize + /beginString exch store + mark + currentfile newBuff readstring exch pop + { + { + newBuff beginString eq + { + /layerCount dup load 1 add store + } + { + newBuff endString eq + { + /layerCount dup load 1 sub store + layerCount 0 eq + { + cleartomark stop + } if + } if + } ifelse + shiftBuffer + } loop + } if +} def +2 +{ + mark + { + currentfile buffer readline not + { + stop + } if + endString eq + { + cleartomark stop + } if + } loop +} def +3 +{ + /beginString exch store + /layerCnt 1 store + mark + { + currentfile buffer readline not + { + stop + } if + dup beginString eq + { + pop /layerCnt dup load 1 add store + } + { + endString eq + { + layerCnt 1 eq + { + cleartomark stop + } + { + /layerCnt dup load 1 sub store + } ifelse + } if + } ifelse + } loop +} def +end +userdict /clipRenderOff 15 dict dup begin +put +{ + /n /N /s /S /f /F /b /B +} +{ + { + _doClip 1 eq + { + /_doClip 0 ddef _eo {eoclip} {clip} ifelse + } if + newpath + } def +} forall +/Tr /pop load def +/Bb {} def +/BB /pop load def +/Bg {12 npop} def +/Bm {6 npop} def +/Bc /Bm load def +/Bh {4 npop} def +end +/Lb +{ + 4 npop + 6 1 roll + pop + 4 1 roll + pop pop pop + 0 eq + { + 0 eq + { + (%AI5_BeginLayer) 1 (%AI5_EndLayer--) discard + } + { + + /clipForward? true def + + /Tx /pop load def + /Tj /pop load def + + currentdict end clipRenderOff begin begin + } ifelse + } + { + 0 eq + { + save /discardSave exch store + } if + } ifelse +} bind def +/LB +{ + discardSave dup null ne + { + restore + } + { + pop + clipForward? + { + currentdict + end + end + begin + + /clipForward? false ddef + } if + } ifelse +} bind def +/Pb +{ + pop pop + 0 (%AI5_EndPalette) discard +} bind def +/Np +{ + 0 (%AI5_End_NonPrinting--) discard +} bind def +/Ln /pop load def +/Ap +/pop load def +/Ar +{ + 72 exch div + 0 dtransform dup mul exch dup mul add sqrt + dup 1 lt + { + pop 1 + } if + setflat +} def +/Mb +{ + q +} def +/Md +{ +} def +/MB +{ + Q +} def +/nc 4 dict def +nc begin +/setgray +{ + pop +} bind def +/setcmykcolor +{ + 4 npop +} bind def +/setrgbcolor +{ + 3 npop +} bind def +/setcustomcolor +{ + 2 npop +} bind def +currentdict readonly pop +end +end +setpacking +%%EndResource +%%BeginResource: procset Adobe_cshow 2.0 8 +%%Title: (Writing System Operators) +%%Version: 2.0 8 +%%CreationDate: (1/23/89) () +%%Copyright: ((C) 1992-1996 Adobe Systems Incorporated All Rights Reserved) +currentpacking true setpacking +userdict /Adobe_cshow 14 dict dup begin put +/initialize +{ + Adobe_cshow begin + Adobe_cshow + { + dup xcheck + { + bind + } if + pop pop + } forall + end + Adobe_cshow begin +} def +/terminate +{ +currentdict Adobe_cshow eq + { + end + } if +} def +/cforall +{ + /_lobyte 0 ddef + /_hibyte 0 ddef + /_cproc exch ddef + /_cscript currentfont /FontScript known { currentfont /FontScript get } { -1 } ifelse ddef + { + /_lobyte exch ddef + _hibyte 0 eq + _cscript 1 eq + _lobyte 129 ge _lobyte 159 le and + _lobyte 224 ge _lobyte 252 le and or and + _cscript 2 eq + _lobyte 161 ge _lobyte 254 le and and + _cscript 3 eq + _lobyte 161 ge _lobyte 254 le and and + _cscript 25 eq + _lobyte 161 ge _lobyte 254 le and and + _cscript -1 eq + or or or or and + { + /_hibyte _lobyte ddef + } + { + _hibyte 256 mul _lobyte add + _cproc + /_hibyte 0 ddef + } ifelse + } forall +} def +/cstring +{ + dup 256 lt + { + (s) dup 0 4 3 roll put + } + { + dup 256 idiv exch 256 mod + (hl) dup dup 0 6 5 roll put 1 4 3 roll put + } ifelse +} def +/clength +{ + 0 exch + { 256 lt { 1 } { 2 } ifelse add } cforall +} def +/hawidthshow +{ + { + dup cstring + show + _hvax _hvay rmoveto + _hvwb eq { _hvcx _hvcy rmoveto } if + } cforall +} def +/vawidthshow +{ + { + dup 255 le + _charorientation 1 eq + and + { + -90 rotate + 0 _fontRotateAdjust rmoveto + cstring + _hvcx _hvcy _hvwb _hvax _hvay 6 -1 roll awidthshow + 0 _fontRotateAdjust neg rmoveto + 90 rotate + } + { + currentpoint + _fontHeight sub + exch _hvay sub exch _hvax sub + 2 index _hvwb eq { exch _hvcy sub exch _hvcx sub } if + 3 2 roll + cstring + dup stringwidth pop 2 div neg _fontAscent neg rmoveto + show + moveto + } ifelse + } cforall +} def +/hvawidthshow +{ + 6 1 roll + /_hvay exch ddef + /_hvax exch ddef + /_hvwb exch ddef + /_hvcy exch ddef + /_hvcx exch ddef + _lineorientation 0 eq { hawidthshow } { vawidthshow } ifelse +} def +/hvwidthshow +{ + 0 0 3 -1 roll hvawidthshow +} def +/hvashow +{ + 0 0 0 6 -3 roll hvawidthshow +} def +/hvshow +{ + 0 0 0 0 0 6 -1 roll hvawidthshow +} def +currentdict readonly pop end +setpacking +%%EndResource +%%EndProlog +%%BeginSetup +userdict /_useSmoothShade false put +Adobe_level2_AI5 /initialize get exec +Adobe_cshow /initialize get exec +Adobe_ColorImage_AI6 /initialize get exec +Adobe_Illustrator_AI5 /initialize get exec +%AI5_Begin_NonPrinting +Np +%AI3_BeginPattern: (Bl\212tter) +(Bl\212tter) 0 0 64.0781 78.9336 [ +%AI3_Tile +(0 O 0 R 0.05 0.2 1 0 k + 0.05 0.2 1 0 K +) @ +( +%AI6_BeginPatternLayer +800 Ar +0 J 0 j 1 w 4 M []0 d +%AI3_Note: +0 D +0 XR +64.0781 78.9336 m +64.0781 0 L +0 0 L +0 78.9336 L +64.0781 78.9336 L +f +%AI6_EndPatternLayer +) & +(0 O 0 R 0.83 0 1 0 k + 0.83 0 1 0 K +) @ +( +%AI6_BeginPatternLayer +800 Ar +0 J 0 j 1 w 4 M []0 d +%AI3_Note: +1 D +0 XR +29.7578 0.9902 m +30.4346 1.1914 30.7246 1.3428 V +29.2559 4.0547 33.707 8.3359 34.627 9.0762 C +35.2275 8.8506 35.3477 6.3184 34.6699 4.9805 C +35.5137 5.1035 37.7031 3.7256 38.4609 2.4365 C +38.5254 3.125 40.0957 6.0664 40.9219 6.4434 C +40.002 6.8408 39.3359 8.3135 38.5742 9.7617 C +39.5957 9.9287 40.9961 9.0078 42.4668 8.1025 C +42.9814 8.9043 44.3555 9.875 45.6143 10.3916 C +44.5264 11.0781 44.0313 11.8203 43.5352 13.2793 C +42.4922 12.7139 40.3057 12.5645 39.7764 12.8516 C +40.291 13.9648 42.5371 14.5078 43.2676 14.4551 C +43.0137 15.3164 42.8652 17.4697 43.0391 20.0625 C +41.3789 18.7461 39.834 17.4297 38.1738 17.4883 C +38.4434 16.0664 37.8076 14.2607 37.4307 13.7676 C +36.8574 14.5117 36.4463 15.3389 36.8008 17.3164 C +35.3486 17.8008 34.1113 18.3467 32.7373 19.6045 C +32.7373 17.7734 32.166 16.5723 31.2969 15.2959 C +32.5576 14.8076 33.8301 13.6045 33.8252 12.5664 C +32.9775 12.7178 31.2852 13.4619 30.793 14.4551 C +30.0742 13.707 28.3906 12.3984 26.7871 12.3945 C +27.9746 11.5391 28.8945 10.5059 28.9893 8.5938 C +30.2422 9.5645 32.6953 10.1797 34.0752 9.582 C +29.2344 5.3457 29.7031 2.3125 29.7578 0.9902 C +f +13.8525 29.9844 m +13.3281 29.5127 13.1309 29.25 V +15.623 27.4326 13.3691 21.6074 12.8555 20.5439 C +12.2168 20.4883 10.8096 23.2285 10.8457 24.7266 C +9.7129 23.9707 8.0488 24.0918 6.4463 24.3779 C +7.0186 23.2891 6.6172 21.3447 5.8164 20.5439 C +6.8184 20.5801 8.1699 19.8652 9.4785 18.8838 C +8.6436 18.0645 6.8164 18.2246 4.9004 18.8838 C +4.9004 17.5107 4.0781 15.7734 3.2412 14.5918 C +4.5576 14.6484 5.7031 13.9629 6.5605 12.9316 C +7.2256 14.5 9.2598 15.6133 10.166 15.5645 C +10.1826 14.1992 8.6094 12.1094 7.5879 11.7109 C +8.1875 11.041 9.207 9.5107 10.166 7.0947 C +10.9648 9.0205 12.1348 10.2627 13.3672 11.1953 C +12.2256 12.7578 12.3994 13.6289 12.7988 15.1074 C +13.541 14.5664 14.5723 14.1338 14.7441 12.1309 C +16.4609 12.416 17.5957 12.3447 19.0938 11.4434 C +18.6387 13.1055 18.6348 14.707 18.9551 16.4063 C +17.1055 16.2666 15.5449 16.4795 14.5156 17.9688 C +15.3457 18.1953 17.6055 18.2549 18.4795 17.3223 C +18.8066 18.3047 19.7012 19.7109 21.1475 20.4043 C +19.707 20.6641 18.7227 21.7637 17.8135 23.4492 C +17.1006 22.0332 14.873 20.3691 13.3711 20.3145 C +15.373 24.3779 15.373 27.2959 13.8525 29.9844 C +f +41.2324 26.0742 m +41.5518 26.7021 41.7549 26.959 V +44.1523 25.0176 48.958 28.3262 49.8535 29.0957 C +49.7432 29.7266 47.6182 30.8643 45.9004 29.834 C +46.3408 31.123 45.4395 33.084 44.2402 34.126 C +45.9805 34.0254 48.126 35.3867 48.6484 36.1289 C +48.8701 35.1514 50.0527 33.8809 51.3379 32.8672 C +51.6895 33.8398 50.9941 35.958 50.0781 37.5605 C +51.3125 38.0605 52.4248 38.9912 52.8828 40.25 C +53.3398 38.9336 54.3428 38.2598 55.6875 37.5039 C +54.5273 36.0762 53.7471 33.9023 54.0273 33.0391 C +55.3496 33.374 56.9209 36.0918 57.0439 37.1816 C +57.9189 36.415 59.4727 35.7285 62.0537 35.4219 C +60.3535 34.3438 59.9902 32.3516 59.4063 30.9219 C +58.2588 31.3682 56.0898 31.4277 55.1152 30.8643 C +55.8281 30.2852 57.168 29.7344 59.1777 29.7207 C +59.1777 28.1758 59.6406 27.043 60.8945 25.8281 C +59.1719 25.8418 57.0723 25.3555 55.5762 24.9629 C +55.3281 26.292 54.4844 27.8887 53.3398 28.2891 C +53.334 27.4277 53.5996 25.1797 54.4844 24.5117 C +53.6201 23.9443 52.3672 22.5674 51.9102 20.8496 C +51.2881 22.1758 50.4268 23.4805 48.5645 23.9238 C +49.749 24.9766 50.584 26.9941 50.25 28.4609 C +45.1973 24.4785 42.5215 25.7773 41.2324 26.0742 C +f +27.7578 38.7324 m +28.4346 38.9316 28.7246 39.084 V +27.2559 41.7969 31.707 46.0776 32.627 46.8169 C +33.2275 46.5918 33.3477 44.0586 32.6699 42.7227 C +33.5137 42.8457 35.7031 41.4678 36.4609 40.1787 C +36.5254 40.8652 38.0957 43.8066 38.9219 44.1846 C +38.002 44.582 37.3359 46.0547 36.5742 47.5039 C +37.5957 47.6709 38.9961 46.7485 40.4668 45.8438 C +40.9814 46.6445 42.3555 47.6177 43.6143 48.1328 C +42.5264 48.8198 42.0313 49.5615 41.5352 51.0205 C +40.4922 50.4556 38.3057 50.3057 37.7764 50.5938 C +38.291 51.7056 40.5371 52.2485 41.2676 52.1958 C +41.0137 53.0576 40.8652 55.2109 41.0391 57.8037 C +39.3789 56.4878 37.834 55.1719 36.1738 55.2285 C +36.4434 53.8076 35.8076 52.002 35.4307 51.5088 C +34.8574 52.2529 34.4463 53.0796 34.8008 55.0576 C +33.3486 55.5425 32.1113 56.0879 30.7373 57.3467 C +30.7373 55.5146 30.166 54.314 29.2969 53.0366 C +30.5576 52.5488 31.8301 51.3467 31.8252 50.3076 C +30.9775 50.46 29.2852 51.2036 28.793 52.1958 C +28.0742 51.4497 26.3906 50.1396 24.7871 50.1357 C +25.9746 49.2817 26.8945 48.2466 26.9893 46.335 C +28.2422 47.3057 30.6953 47.9209 32.0752 47.3237 C +27.2344 43.0869 27.7031 40.0547 27.7578 38.7324 C +f +13.5195 70.3916 m +12.9941 69.9209 12.7988 69.6587 V +15.2891 67.8418 13.0352 62.0146 12.5225 60.9517 C +11.8828 60.8955 10.4766 63.6367 10.5117 65.1348 C +9.3809 64.3789 7.7148 64.4995 6.1133 64.7856 C +6.6855 63.6987 6.2842 61.7529 5.4834 60.9517 C +6.4854 60.9878 7.8359 60.2729 9.1455 59.2925 C +8.3105 58.4717 6.4834 58.6338 4.5674 59.2925 C +4.5674 57.9189 3.7461 56.1816 2.9082 54.9995 C +4.2246 55.0576 5.3691 54.3706 6.2275 53.3408 C +6.8926 54.9097 8.9258 56.0215 9.832 55.9727 C +9.8496 54.6079 8.2764 52.5176 7.2539 52.1187 C +7.8545 51.4497 8.873 49.9189 9.832 47.5039 C +10.6309 49.4297 11.8008 50.6719 13.0342 51.6045 C +11.8926 53.1655 12.0664 54.0366 12.4648 55.5146 C +13.209 54.9746 14.2393 54.5415 14.4102 52.5386 C +16.127 52.8247 17.2637 52.7529 18.7598 51.8525 C +18.3057 53.5137 18.3027 55.1147 18.623 56.8149 C +16.7725 56.6748 15.2129 56.8887 14.1826 58.377 C +15.0117 58.6035 17.2725 58.6626 18.1465 57.731 C +18.4736 58.7129 19.3691 60.1187 20.8145 60.8125 C +19.375 61.0728 18.3896 62.1719 17.4805 63.8579 C +16.7676 62.4429 14.541 60.7769 13.0371 60.7227 C +15.041 64.7856 15.041 67.7046 13.5195 70.3916 C +f +41.2324 64.4824 m +41.5518 65.1113 41.7549 65.3682 V +44.1523 63.4272 48.958 66.7354 49.8535 67.5034 C +49.7432 68.1362 47.6182 69.2725 45.9004 68.2422 C +46.3408 69.5313 45.4395 71.4922 44.2402 72.5342 C +45.9805 72.4341 48.126 73.7954 48.6484 74.5371 C +48.8701 73.5601 50.0527 72.29 51.3379 71.2754 C +51.6895 72.249 50.9941 74.3662 50.0781 75.9683 C +51.3125 76.4692 52.4248 77.3994 52.8828 78.6582 C +53.3398 77.3423 54.3428 76.667 55.6875 75.9111 C +54.5273 74.4844 53.7471 72.3101 54.0273 71.4473 C +55.3496 71.7822 56.9209 74.5 57.0439 75.5903 C +57.9189 74.8232 59.4727 74.1372 62.0537 73.8311 C +60.3535 72.7534 59.9902 70.7612 59.4063 69.3301 C +58.2588 69.7773 56.0898 69.8364 55.1152 69.2725 C +55.8281 68.6934 57.168 68.1431 59.1777 68.1284 C +59.1777 66.583 59.6406 65.4512 60.8945 64.2373 C +59.1719 64.249 57.0723 63.7632 55.5762 63.3721 C +55.3281 64.7002 54.4844 66.2974 53.3398 66.6973 C +53.334 65.8364 53.5996 63.5874 54.4844 62.9214 C +53.6201 62.353 52.3672 60.9751 51.9102 59.2583 C +51.2881 60.583 50.4268 61.8882 48.5645 62.333 C +49.749 63.3862 50.584 65.4033 50.25 66.8691 C +45.1973 62.8872 42.5215 64.1851 41.2324 64.4824 C +f +%AI6_EndPatternLayer +) & +] E +%AI3_EndPattern +%AI3_BeginPattern: (Konfetti) +(Konfetti) 4.85 3.617 76.85 75.617 [ +%AI3_Tile +(0 O 0 R 1 g + 1 G +) @ +( +%AI6_BeginPatternLayer +800 Ar +0 J 0 j 1 w 4 M []0 d +%AI3_Note: +0 D +0 XR +4.85 3.617 m +4.85 75.617 L +76.85 75.617 L +76.85 3.617 L +4.85 3.617 L +f +%AI6_EndPatternLayer +) & +(0 O 0 R 0 g + 0 G +) @ +( +%AI6_BeginPatternLayer +800 Ar +0 J 0 j 0.3 w 4 M []0 d +%AI3_Note: +0 D +0 XR +10.6 64.867 m +7.85 62.867 l +S +9.1 8.617 m +6.85 6.867 l +S +78.1 68.617 m +74.85 67.867 l +S +76.85 56.867 m +74.35 55.117 l +S +79.6 51.617 m +76.6 51.617 l +S +76.35 44.117 m +73.6 45.867 l +S +78.6 35.867 m +76.6 34.367 l +S +76.1 23.867 m +73.35 26.117 l +S +78.1 12.867 m +73.85 13.617 l +S +68.35 14.617 m +66.1 12.867 l +S +76.6 30.617 m +73.6 30.617 l +S +62.85 58.117 m +60.956 60.941 l +S +32.85 59.617 m +31.196 62.181 l +S +47.891 64.061 m +49.744 66.742 l +S +72.814 2.769 m +73.928 5.729 l +S +67.976 2.633 m +67.35 5.909 l +S +61.85 27.617 m +59.956 30.441 l +S +53.504 56.053 m +51.85 58.617 l +S +52.762 1.779 m +52.876 4.776 l +S +45.391 5.311 m +47.244 7.992 l +S +37.062 3.375 m +35.639 5.43 l +S +55.165 34.828 m +57.518 37.491 l +S +20.795 3.242 m +22.12 5.193 l +S +14.097 4.747 m +15.008 8.965 l +S +9.736 1.91 m +8.073 4.225 l +S +31.891 5.573 m +32.005 8.571 l +S +12.1 70.367 m +15.6 68.867 l +S +9.35 54.867 m +9.6 58.117 l +S +12.85 31.867 m +14.35 28.117 l +S +10.1 37.367 m +12.35 41.117 l +S +34.1 71.117 m +31.85 68.617 l +S +38.35 71.117 m +41.6 68.367 l +S +55.1 71.117 m +58.35 69.117 l +S +57.35 65.117 m +55.35 61.867 l +S +64.35 66.367 m +69.35 68.617 l +S +71.85 62.867 m +69.35 61.117 l +S +23.6 70.867 m +23.6 67.867 l +S +20.6 65.867 m +17.35 65.367 l +S +24.85 61.367 m +25.35 58.117 l +S +25.85 65.867 m +29.35 66.617 l +S +14.1 54.117 m +16.85 56.117 l +S +12.35 11.617 m +12.6 15.617 l +S +12.1 19.867 m +14.35 22.367 l +S +26.1 9.867 m +23.6 13.367 l +S +34.6 47.117 m +32.1 45.367 l +S +62.6 41.867 m +59.85 43.367 l +S +31.6 35.617 m +27.85 36.367 l +S +36.35 26.117 m +34.35 24.617 l +S +33.85 14.117 m +31.1 16.367 l +S +37.1 9.867 m +35.1 11.117 l +S +34.35 20.867 m +31.35 20.867 l +S +44.6 56.617 m +42.1 54.867 l +S +47.35 51.367 m +44.35 51.367 l +S +44.1 43.867 m +41.35 45.617 l +S +43.35 33.117 m +42.6 30.617 l +S +43.85 23.617 m +41.1 25.867 l +S +44.35 15.617 m +42.35 16.867 l +S +67.823 31.1 m +64.823 31.1 l +S +27.1 32.617 m +29.6 30.867 l +S +31.85 55.117 m +34.85 55.117 l +S +19.6 40.867 m +22.1 39.117 l +S +16.85 35.617 m +19.85 35.617 l +S +20.1 28.117 m +22.85 29.867 l +S +52.1 42.617 m +54.484 44.178 l +S +52.437 50.146 m +54.821 48.325 l +S +59.572 54.133 m +59.35 51.117 l +S +50.185 10.055 m +53.234 9.928 l +S +51.187 15.896 m +53.571 14.075 l +S +58.322 19.883 m +59.445 16.823 l +S +53.1 32.117 m +50.6 30.367 l +S +52.85 24.617 m +49.6 25.617 l +S +61.85 9.117 m +59.1 10.867 l +S +69.35 34.617 m +66.6 36.367 l +S +67.1 23.617 m +65.1 22.117 l +S +24.435 46.055 m +27.484 45.928 l +S +25.437 51.896 m +27.821 50.075 l +S +62.6 47.117 m +65.321 46.575 l +S +19.85 19.867 m +20.35 16.617 l +S +21.85 21.867 m +25.35 22.617 l +S +37.6 62.867 m +41.6 62.117 l +S +38.323 42.1 m +38.823 38.6 l +S +69.35 52.617 m +66.85 53.867 l +S +14.85 62.117 m +18.1 59.367 l +S +9.6 46.117 m +7.1 44.367 l +S +20.6 51.617 m +18.6 50.117 l +S +46.141 70.811 m +47.994 73.492 l +S +69.391 40.561 m +71.244 43.242 l +S +38.641 49.311 m +39.35 52.117 l +S +25.141 16.811 m +25.85 19.617 l +S +36.6 32.867 m +34.6 31.367 l +S +6.1 68.617 m +2.85 67.867 l +S +4.85 56.867 m +2.35 55.117 l +S +7.6 51.617 m +4.6 51.617 l +S +6.6 35.867 m +4.6 34.367 l +S +6.1 12.867 m +1.85 13.617 l +S +4.6 30.617 m +1.6 30.617 l +S +72.814 74.769 m +73.928 77.729 l +S +67.976 74.633 m +67.35 77.909 l +S +52.762 73.779 m +52.876 76.776 l +S +37.062 75.375 m +35.639 77.43 l +S +20.795 75.242 m +22.12 77.193 l +S +9.736 73.91 m +8.073 76.225 l +S +10.1 23.617 m +6.35 24.367 l +S +73.217 18.276 m +71.323 21.1 l +S +28.823 39.6 m +29.505 42.389 l +S +49.6 38.617 m +47.6 37.117 l +S +60.323 73.6 m +62.323 76.6 l +S +60.323 1.6 m +62.323 4.6 l +S +%AI6_EndPatternLayer +) & +] E +%AI3_EndPattern +%AI3_BeginPattern: (Streifen) +(Streifen) 8.45 4.6001 80.45 76.6001 [ +%AI3_Tile +(0 O 0 R 1 0.07 1 0 k + 1 0.07 1 0 K +) @ +( +%AI6_BeginPatternLayer +800 Ar +0 J 0 j 3.6 w 4 M []0 d +%AI3_Note: +0 D +0 XR +8.2 8.2 m +80.7 8.2 L +S +8.2 22.6001 m +80.7 22.6001 L +S +8.2 37.0002 m +80.7 37.0002 L +S +8.2 51.4 m +80.7 51.4 L +S +8.2 65.8001 m +80.7 65.8001 L +S +8.2 15.4 m +80.7 15.4 L +S +8.2 29.8001 m +80.7 29.8001 L +S +8.2 44.2 m +80.7 44.2 L +S +8.2 58.6001 m +80.7 58.6001 L +S +8.2 73.0002 m +80.7 73.0002 L +S +%AI6_EndPatternLayer +) & +] E +%AI3_EndPattern +%AI3_BeginPattern: (Ziegel) +(Ziegel) 0 0 72 72 [ +%AI3_Tile +(0 O 0 R 0.3 0.85 0.85 0 k + 0.3 0.85 0.85 0 K +) @ +( +%AI6_BeginPatternLayer +800 Ar +0 J 0 j 1 w 4 M []0 d +%AI3_Note: +0 D +0 XR +0 0 m +0 72 L +72 72 L +72 0 L +0 0 L +f +%AI6_EndPatternLayer +) & +(0 O 0 R 1 g + 1 G +) @ +( +%AI6_BeginPatternLayer +800 Ar +0 J 0 j 0.3 w 4 M []0 d +%AI3_Note: +0 D +0 XR +0 68.4097 m +72 68.4097 l +S +0 61.209 m +72 61.209 L +S +0 54.0088 m +72 54.0088 L +S +0 46.8076 m +72 46.8076 L +S +0 39.6084 m +72 39.6084 L +S +0 32.4072 m +72 32.4072 L +S +0 25.207 m +72 25.207 L +S +0 18.0059 m +72 18.0059 L +S +0 10.8057 m +72 10.8057 L +S +0 3.6064 m +72 3.6064 L +S +68.4102 68.4097 m +68.4102 61.2217 l +S +54.0098 68.4097 m +54.0098 61.2217 L +S +39.6094 68.4097 m +39.6094 61.2217 L +S +25.21 68.4097 m +25.21 61.2217 L +S +10.8105 68.4097 m +10.8105 61.2217 L +S +68.4102 53.9717 m +68.4102 46.7842 l +S +54.0098 53.9717 m +54.0098 46.7842 L +S +39.6094 53.9717 m +39.6094 46.7842 L +S +25.21 53.9717 m +25.21 46.7842 L +S +10.8105 53.9717 m +10.8105 46.7842 L +S +68.4102 39.5967 m +68.4102 32.4092 l +S +54.0098 39.5967 m +54.0098 32.4092 L +S +39.6094 39.5967 m +39.6094 32.4092 L +S +25.21 39.5967 m +25.21 32.4092 L +S +10.8105 39.5967 m +10.8105 32.4092 L +S +68.4102 25.2217 m +68.4102 18.0342 l +S +54.0098 25.2217 m +54.0098 18.0342 L +S +39.6094 25.2217 m +39.6094 18.0342 L +S +25.21 25.2217 m +25.21 18.0342 L +S +10.8105 25.2217 m +10.8105 18.0342 L +S +68.4102 10.7842 m +68.4102 3.5967 l +S +54.0098 10.7842 m +54.0098 3.5967 L +S +39.6094 10.7842 m +39.6094 3.5967 L +S +25.21 10.7842 m +25.21 3.5967 L +S +10.8105 10.7842 m +10.8105 3.5967 L +S +61.1973 3.5967 m +61.1973 0 L +S +46.7969 3.5967 m +46.7969 0 L +S +32.3965 3.5967 m +32.3965 0 L +S +17.9971 3.5967 m +17.9971 0 L +S +3.5967 3.5967 m +3.5967 0 l +S +61.1973 18.0342 m +61.1973 10.8467 L +S +46.7969 18.0342 m +46.7969 10.8467 L +S +32.3965 18.0342 m +32.3965 10.8467 L +S +17.9971 18.0342 m +17.9971 10.8467 L +S +3.5967 18.0342 m +3.5967 10.8467 l +S +61.1973 32.4092 m +61.1973 25.2217 L +S +46.7969 32.4092 m +46.7969 25.2217 L +S +17.9971 32.4092 m +17.9971 25.2217 L +S +3.5967 32.4092 m +3.5967 25.2217 l +S +61.1973 46.7842 m +61.1973 39.5967 L +S +46.7969 46.7842 m +46.7969 39.5967 L +S +32.3965 46.7842 m +32.3965 39.5967 L +S +17.9971 46.7842 m +17.9971 39.5967 L +S +3.5967 46.7842 m +3.5967 39.5967 l +S +61.1973 61.2217 m +61.1973 54.0347 L +S +46.7969 61.2217 m +46.7969 54.0347 L +S +32.3965 61.2217 m +32.3965 54.0347 L +S +17.9971 61.2217 m +17.9971 54.0347 L +S +3.5967 61.2217 m +3.5967 54.0347 l +S +61.1973 71.959 m +61.1973 68.4717 L +S +46.7969 71.959 m +46.7969 68.4717 L +S +32.3965 71.959 m +32.3965 68.4717 L +S +17.9971 71.959 m +17.9971 68.4717 L +S +3.5967 71.959 m +3.5967 68.4717 l +S +32.3965 32.4092 m +32.3965 25.2217 L +S +%AI6_EndPatternLayer +) & +] E +%AI3_EndPattern +%AI5_End_NonPrinting-- +%AI5_Begin_NonPrinting +Np +4 Bn +%AI5_BeginGradient: (Chrom) +(Chrom) 0 6 Bd +[ +0 +< +464646454545444444444343434342424241414141404040403F3F3F3E3E3E3E3D3D3D3C3C3C3C3B +3B3B3B3A3A3A39393939383838383737373636363635353535343434333333333232323131313130 +3030302F2F2F2E2E2E2E2D2D2D2D2C2C2C2B2B2B2B2A2A2A2A292929282828282727272626262625 +2525252424242323232322222222212121202020201F1F1F1F1E1E1E1D1D1D1D1C1C1C1B1B1B1B1A +1A1A1A1919191818181817171717161616151515151414141413131312121212111111101010100F +0F0F0F0E0E0E0D0D0D0D0C0C0C0C0B0B0B0A0A0A0A09090909080808070707070606060505050504 +04040403030302020202010101010000 +> +< +FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8 +D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0 +AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988 +87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160 +5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938 +37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110 +0F0E0D0C0B0A09080706050403020100 +> +< +1F1E1E1E1E1E1E1E1E1E1D1D1D1D1D1D1D1D1C1C1C1C1C1C1C1C1B1B1B1B1B1B1B1B1B1A1A1A1A1A +1A1A1A19191919191919191818181818181818181717171717171717161616161616161615151515 +15151515151414141414141414131313131313131312121212121212121211111111111111111010 +1010101010100F0F0F0F0F0F0F0F0F0E0E0E0E0E0E0E0E0D0D0D0D0D0D0D0D0C0C0C0C0C0C0C0C0C +0B0B0B0B0B0B0B0B0A0A0A0A0A0A0A0A090909090909090909080808080808080807070707070707 +07060606060606060606050505050505050504040404040404040303030303030303030202020202 +02020201010101010101010000000000 +> +1 %_Br +0 +0.275 +1 +< +6B6A696867666564636261605F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544 +434241403F3E3D3C3B3A393837363534333231302F2E2D2C2B2A292827262524232221201F +> +1 %_Br +0 +< +00000101010102020202030303040404040505050506060607070707080808090909090A0A0A0A0B +0B0B0C0C0C0C0D0D0D0D0E0E0E0F0F0F0F1010101011111112121212131313141414141515151516 +161617171717181818181919191A1A1A1A1B1B1B1C1C1C1C1D1D1D1D1E1E1E1F1F1F1F2020202021 +212122222222232323232424242525252526262626272727282828282929292A2A2A2A2B2B2B2B2C +2C2C2D2D2D2D2E2E2E2E2F2F2F303030303131313132323233333333343434353535353636363637 +373738383838393939393A3A3A3B3B3B3B3C3C3C3D3D3D3D3E3E3E3E3F3F3F404040404141414142 +42424343434344444444454545464646 +> +< +000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627 +28292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071727374757677 +78797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F +A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7 +C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF +F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF +> +< +00000101020203030304040505050606070708080809090A0A0B0B0B0C0C0D0D0D0E0E0F0F101010 +1111121212131314141515151616171718181819191A1A1A1B1B1C1C1D1D1D1E1E1F1F1F20202121 +222222232324242525252626272727282829292A2A2A2B2B2C2C2D2D2D2E2E2F2F2F303031313232 +32333334343435353636373737383839393A3A3A3B3B3C3C3C3D3D3E3E3F3F3F4040414142424243 +434444444545464647474748484949494A4A4B4B4C4C4C4D4D4E4E4F4F4F50505151515252535354 +54545555565657575758585959595A5A5B5B5C5C5C5D5D5E5E5E5F5F606061616162626363646464 +6565666666676768686969696A6A6B6B +> +1 %_Br +1 +0 %_Br +< +FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8 +D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0 +AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988 +87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160 +5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938 +37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110 +0F0E0D0C0B0A09080706050403020100 +> +< +4D4C4C4C4B4B4B4A4A4A4A4949494848484747474746464645454544444444434343424242414141 +414040403F3F3F3E3E3E3E3D3D3D3C3C3C3B3B3B3B3A3A3A39393938383838373737363636353535 +35343434333333323232323131313030302F2F2F2E2E2E2E2D2D2D2C2C2C2B2B2B2B2A2A2A292929 +282828282727272626262525252524242423232322222222212121202020201F1F1F1E1E1E1D1D1D +1D1C1C1C1B1B1B1A1A1A1A1919191818181717171616161615151514141413131313121212111111 +101010100F0F0F0E0E0E0D0D0D0D0C0C0C0B0B0B0A0A0A0A09090908080807070707060606050505 +04040404030303020202010101010000 +> +0 +0 +1 %_Br +[ +1 0 50 92 %_Bs +0 0.275 1 0.12 1 50 59 %_Bs +0 0.275 1 0.42 1 50 50 %_Bs +1 0 50 49 %_Bs +1 0 50 41 %_Bs +1 0.3 0 0 1 50 0 %_Bs +BD +%AI5_EndGradient +%AI5_BeginGradient: (Gelb, Orange-Radial) +(Gelb, Orange-Radial) 1 2 Bd +[ +0 +< +0001010203040506060708090A0B0C0C0D0E0F10111213131415161718191A1B1C1D1D1E1F202122 +232425262728292A2B2B2C2D2E2F303132333435363738393A3B3C3D3E3E3F404142434445464748 +494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F60606162636465666768696A6B6C6D6E6F +707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C +> +< +FFFFFFFFFEFEFEFEFEFEFEFDFDFDFDFDFDFCFCFCFCFCFCFBFBFBFBFBFBFAFAFAFAFAFAF9F9F9F9F9 +F9F8F8F8F8F8F8F7F7F7F7F7F7F6F6F6F6F6F6F5F5F5F5F5F5F4F4F4F4F4F3F3F3F3F3F3F2F2F2F2 +F2F2F1F1F1F1F1F0F0F0F0F0F0EFEFEFEFEFEFEEEEEEEEEEEDEDEDEDEDEDECECECECECEBEBEBEBEB +EBEAEAEAEAEAE9E9E9E9E9E9E8E8E8E8E8E8E7E7E7E7E7E6E6E6E6E6E6 +> +0 +1 %_Br +[ +0 0 1 0 1 52 19 %_Bs +0 0.55 0.9 0 1 50 100 %_Bs +BD +%AI5_EndGradient +%AI5_BeginGradient: (Regenbogen) +(Regenbogen) 0 6 Bd +[ +< +FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8 +D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0 +AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988 +87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160 +5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938 +37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110 +0F0E0D0C0B0A09080706050403020100 +> +1 +0 +0 +1 %_Br +1 +< +0708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E +2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F50515253545556 +5758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E +7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6 +A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCE +CFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6 +F7F8F9FAFBFCFDFEFF +> +0 +0 +1 %_Br +1 +< +00000000000000000000000000000000000001010101010101010101010101010101010101010101 +01010101010101010101010101010202020202020202020202020202020202020202020202020202 +02020202020202020202030303030303030303030303030303030303030303030303030303030303 +03030303030304040404040404040404040404040404040404040404040404040404040404040404 +04040505050505050505050505050505050505050505050505050505050505050505050505050606 +06060606060606060606060606060606060606060606060606060606060606060607070707070707 +07070707070707070707070707070707 +> +< +FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8 +D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0 +AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988 +87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160 +5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938 +37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110 +0F0E0D0C0B0A09080706050403020100 +> +0 +1 %_Br +< +000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627 +28292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071727374757677 +78797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F +A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7 +C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF +F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF +> +0 +1 +0 +1 %_Br +0 +< +FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8 +D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0 +AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988 +87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160 +5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938 +37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110 +0F0E0D0C0B0A09080706050403020100 +> +1 +0 +1 %_Br +[ +0 1 0 0 1 50 100 %_Bs +1 1 0 0 1 50 80 %_Bs +1 0.0279 0 0 1 50 60 %_Bs +1 0 1 0 1 50 40 %_Bs +0 0 1 0 1 50 20 %_Bs +0 1 1 0 1 50 0 %_Bs +BD +%AI5_EndGradient +%AI5_BeginGradient: (Schwarz, Wei\247) +(Schwarz, Wei\247) 0 2 Bd +[ +< +FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8 +D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0 +AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988 +87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160 +5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938 +37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110 +0F0E0D0C0B0A09080706050403020100 +> +0 %_Br +[ +0 0 50 100 %_Bs +1 0 50 0 %_Bs +BD +%AI5_EndGradient +%AI5_End_NonPrinting-- +%AI5_BeginPalette +0 0 Pb +1 1 1 1 k +([Passermarken]) Pc +0 0 0 1 k +([Passermarken]) Pc +0 0 0 0 k +(C=0 M=0 Y=0 K=0 Kopie) Pc +0 0 0 0.2 k +(0-0-0-20 Kopie) Pc +0 0 0 0.4 k +(0-0-0-40 Kopie) Pc +0 0 0 0.6 k +(0-0-0-60 Kopie) Pc +0 0 0 0.8 k +(0-0-0-80 Kopie) Pc +0 0 0 1 k +(C=0 M=0 Y=0 K=100 Kopie) Pc +0 0 1 0 k +(0-0-100-0 Kopie) Pc +0 0.2 1 0 k +(0-20-100-0 Kopie) Pc +0 0.4 1 0 k +(0-40-100-0 Kopie) Pc +0 0.6 1 0 k +(0-60-100-0 Kopie) Pc +0 0.8 1 0 k +(0-80-100-0 Kopie) Pc +0 1 1 0 k +(0-100-100-0 Kopie) Pc +0 1 1 0.2 k +(0-100-100-20 Kopie) Pc +0 1 1 0.4 k +(0-100-100-40 Kopie) Pc +0 1 1 0.6 k +(0-100-100-60 Kopie) Pc +0 1 1 0.8 k +(0-100-100-80 Kopie) Pc +0 0.5 0 0 k +(0-50-0-0 Kopie) Pc +0 1 0 0 k +(0-100-0-0 Kopie) Pc +0.2 1 0 0 k +(20-100-0-0 Kopie) Pc +0.4 1 0 0 k +(40-100-0-0 Kopie) Pc +0.6 1 0 0 k +(60-100-0-0 Kopie) Pc +0.8 1 0 0 k +(80-100-0-0 Kopie) Pc +1 1 0 0 k +(100-100-0-0 Kopie) Pc +1 0.8 0 0 k +(100-80-0-0 Kopie) Pc +1 0.6 0 0 k +(100-60-0-0 Kopie) Pc +1 0.4 0 0 k +(100-40-0-0 Kopie) Pc +1 0.2 0 0 k +(100-20-0-0 Kopie) Pc +1 0 0 0 k +(100-0-0-0 Kopie) Pc +1 0 1 0 k +(100-0-100-0 Kopie) Pc +1 0 0.8 0 k +(100-0-80-0 Kopie) Pc +1 0 0.6 0 k +(100-0-60-0 Kopie) Pc +1 0 0.4 0 k +(100-0-40-0 Kopie) Pc +1 0 0.2 0 k +(100-0-20-0 Kopie) Pc +Bb +2 (Schwarz, Wei\247) -4023.5 4739.5 0 0 1 0 0 1 0 0 Bg +0 BB +(Schwarz, Wei\247) Pc +Bb +2 (Chrom) -4023.5 4739.5 0 0 1 0 0 1 0 0 Bg +0 BB +(Chrom) Pc +Bb +2 (Regenbogen) -4023.5 4739.5 0 0 1 0 0 1 0 0 Bg +0 BB +(Regenbogen) Pc +Bb +0 0 0 0 Bh +2 (Gelb, Orange-Radial) -4023.5 4739.5 0 0 1 0 0 1 0 0 Bg +0 BB +(Gelb, Orange-Radial) Pc +(Ziegel) 0 0 1 1 0 0 0 0 0 [1 0 0 1 0 0] p +(Ziegel) Pc +(Konfetti) 0 0 1 1 0 0 0 0 0 [1 0 0 1 0 0] p +(Konfetti) Pc +(Bl\212tter) 0 0 1 1 0 0 0 0 0 [1 0 0 1 0 0] p +(Bl\212tter) Pc +(Streifen) 0 0 1 1 0 0 0 0 0 [1 0 0 1 0 0] p +(Streifen) Pc +PB +%AI5_EndPalette +%%EndSetup +%AI5_BeginLayer +1 1 1 1 0 0 0 79 128 255 Lb +(Ebene 1) Ln +0 A +u +u +0 O +0 1 1 0 k +800 Ar +0 J 0 j 1 w 4 M []0 d +%AI3_Note: +0 D +0 XR +257.6328 402.0234 m +258.3594 404.3613 258.7319 407.4629 258.7593 411.2148 C +258.0337 411.2148 254.2314 411.2148 Y +250.3223 411.1855 247.0942 410.7734 244.6396 409.9922 c +241.2041 408.873 239.5215 406.5918 239.4956 403.0254 c +239.5215 400.6309 240.3389 398.8906 241.9937 397.7051 c +243.6646 396.5078 245.6904 395.9141 248.0195 395.9395 c +250.4595 395.9395 252.4316 396.3984 253.9873 397.2949 c +254.1299 397.3809 254.2749 397.4609 254.416 397.5488 c +255.9351 398.5586 257.0068 400.0391 257.6328 402.0234 c +f +312.0674 469.5464 m +312.0674 470.9575 312.0674 479.1089 Y +311.2168 479.1089 L +306.8037 479.1089 L +306.8037 470.9575 306.8037 469.5464 V +305.3926 469.5464 297.2451 469.5464 Y +297.2451 469.4966 L +295.9775 477.1841 291.7412 484.3765 284.8545 489.1987 c +274.2344 496.6357 260.4712 496.2334 250.4307 489.2056 C +250.4653 489.2056 250.4976 489.2104 250.5327 489.2104 c +256.6919 489.1509 261.3081 487.4976 264.2534 484.2964 c +265.9233 482.4839 267.022 480.3208 267.5239 477.8433 C +268.1069 473.8608 L +259.2446 473.8608 L +259.1934 474.2271 L +258.4194 479.811 255.3755 482.5532 249.8882 482.6099 c +248.2383 482.6099 246.6787 482.3169 245.2505 481.7378 c +243.0776 480.8745 241.563 479.5356 240.6313 477.6792 c +240.5552 477.5229 240.4785 477.3677 240.4053 477.2104 c +240.2939 476.9507 240.189 476.686 240.0986 476.4077 c +239.1475 473.6616 238.665 470.687 238.665 467.5669 c +238.665 462.2417 239.2422 458.3423 240.3818 455.9751 c +242.1797 452.1812 245.2227 450.3774 249.6929 450.4604 c +254.7617 450.4604 257.7715 452.2378 258.8979 455.9077 c +259.229 456.8745 259.4966 458.1138 259.6934 459.5913 C +259.7422 459.9604 L +268.605 459.9604 L +268.5356 459.4751 L +268.0986 456.4194 267.6001 454.2485 267.0112 452.8374 c +266.1563 450.7788 264.7139 448.9937 262.7227 447.5298 c +259.3848 445.0952 255.0283 443.8608 249.7749 443.8608 c +243.0879 443.8608 237.9868 445.9468 234.6128 450.062 c +233.4941 451.438 232.5806 452.9995 231.8516 454.7212 C +230.0942 452.8315 228.1509 451.3892 226.3052 450.4321 C +225.6938 450.1606 225.0913 449.8687 224.4985 449.5552 c +220.5317 447.6011 217.0737 444.5269 214.2974 440.7144 c +214.1841 440.5601 214.064 440.4136 213.9536 440.2554 C +213.9458 440.2456 213.9399 440.2339 213.9321 440.2241 C +213.9292 440.2183 213.9233 440.2144 213.9204 440.2085 C +204.4146 426.6333 207.7134 407.9219 221.2886 398.416 c +225.3662 395.5605 229.9072 393.8691 234.5229 393.2559 C +234.3853 393.3887 234.2378 393.5117 234.1084 393.6523 C +233.0698 394.6602 232.2593 395.9043 231.7065 397.334 C +231.0005 398.9434 230.6436 400.6836 230.6436 402.4961 c +230.6436 402.5703 230.644 402.6426 230.645 402.7168 c +230.644 402.7949 230.6431 402.8711 230.6431 402.9492 c +230.6431 404.627 230.9551 406.2578 231.5723 407.8008 c +232.2188 409.416 233.229 410.918 234.5713 412.2598 c +236.1484 413.8672 237.8276 414.9941 239.5605 415.6113 c +243.29 416.9609 247.9546 417.6602 253.4258 417.6895 C +258.04 417.6895 258.77 417.6895 V +258.7661 421.6636 258.3462 424.2632 257.5205 425.4077 c +256.2358 427.1597 253.7344 428.062 250.0928 428.0903 c +247.543 428.062 245.561 427.6411 244.2021 426.8403 c +242.8926 426.0679 242.022 424.3804 241.6152 421.8237 C +241.5581 421.4653 L +232.7188 421.4653 L +232.7729 421.939 L +233.0933 424.7397 233.5122 426.6587 234.0527 427.8062 c +234.8862 429.5737 236.3135 431.0454 238.2954 432.1772 c +241.1714 433.8149 245.0889 434.6606 249.9438 434.6899 c +255.3135 434.6606 259.4399 433.73 262.2061 431.9263 c +265.5728 429.7671 267.3105 426.0327 267.3706 420.8198 C +267.3706 414.4531 L +267.9165 416.2637 268.2632 418.1074 268.3857 419.9644 c +268.7451 425.4331 272.2939 433.2417 280.3525 437.4097 C +284.9521 439.5591 289.0713 442.8999 292.1924 447.3589 C +292.2002 447.3687 292.2061 447.3794 292.2119 447.3901 C +292.2158 447.394 292.2217 447.3999 292.2236 447.4058 C +295.8262 452.5522 297.5859 458.4351 297.6465 464.2749 C +297.1631 464.2749 289.0625 464.2749 287.6523 464.2749 C +287.6523 462.8638 287.6523 454.7124 Y +282.3892 454.7124 L +282.3892 462.8638 282.3892 464.2749 V +280.9775 464.2749 272.8267 464.2749 Y +272.8267 469.5386 L +280.9775 469.5386 282.3892 469.5386 V +282.3892 470.9497 282.3892 479.1011 Y +286.8027 479.1011 L +287.6523 479.1011 L +287.6523 470.9497 287.6523 469.5386 V +289.0645 469.5386 297.2148 469.5386 Y +297.7207 466.8696 297.6514 464.2827 V +299.3047 464.2827 305.5811 464.2827 306.8037 464.2827 C +306.8037 462.8716 306.8037 454.7202 Y +312.0674 454.7202 L +312.0674 462.8716 312.0674 464.2827 V +313.4785 464.2827 321.6299 464.2827 Y +321.6299 469.5464 L +313.4785 469.5464 312.0674 469.5464 V +f +U +u +0 0 0 0.4 k +293.3037 416.209 m +293.3008 416.209 290.0479 417.2559 Y +287.5449 417.8848 285.6484 418.418 284.4058 418.8379 C +283.2568 419.2769 282.7344 419.9937 282.7764 421.0884 C +282.7349 422.0825 283.2275 422.8276 284.2822 423.4019 c +284.9775 423.7739 286.0098 423.979 287.3496 424.0112 c +289.9414 424.0112 291.2988 422.8706 291.4902 420.5269 C +291.5215 420.1362 L +296.9824 420.1362 L +296.9639 420.5796 L +296.8955 422.1616 296.6816 423.3032 296.3105 424.0698 c +295.835 425.0415 294.9922 425.9116 293.8047 426.6567 c +292.1748 427.6636 289.8936 428.1733 287.0225 428.1733 c +285.248 428.1733 283.5664 427.8667 282.0234 427.2622 c +280.666 426.729 279.5259 425.8618 278.6348 424.6851 c +277.7324 423.4937 277.2837 422.1235 277.3013 420.6118 c +277.3013 418.7266 277.8618 417.2012 278.9668 416.0781 c +279.7866 415.2031 281.2354 414.4824 283.3882 413.8848 C +283.3896 413.8848 288.042 412.6328 Y +288.0361 412.6348 290.5898 411.791 Y +291.623 411.3301 292.127 410.6035 292.1133 409.5723 c +292.0547 407.2324 290.3662 406.0781 286.9512 406.0488 c +283.9048 406.0332 282.3135 407.418 282.0879 410.2813 C +282.0571 410.6738 L +276.583 410.6738 L +276.6147 410.2188 L +276.8013 407.5391 277.5054 405.6074 278.7065 404.4766 c +280.4707 402.7266 283.3896 401.8535 287.375 401.8867 c +290.2676 401.8535 292.6016 402.4492 294.3008 403.6563 c +296.4824 405.2031 297.5898 407.3398 297.5898 410.0059 c +297.5371 412.9961 296.0957 415.0801 293.3037 416.209 C +f +*u +1 D +318.4785 427.3315 m +317.1396 427.8901 315.7246 428.1733 314.2715 428.1733 c +311.2705 428.1567 308.8516 427.187 307.0791 425.2915 C +307.0742 425.2866 306.9922 425.187 306.8838 425.0562 C +306.8838 425.9917 306.8838 427.4858 Y +301.5957 427.4858 L +301.5957 393.6367 L +306.8838 393.6367 L +306.8838 402.7813 306.8838 404.5488 V +308.6221 402.8047 310.9805 401.9023 313.9268 401.8867 c +315.4131 401.8867 316.8398 402.1641 318.168 402.7148 c +319.502 403.2676 320.6523 404.0645 321.5889 405.0879 c +323.7734 407.375 324.8838 410.7617 324.8838 415.1523 c +324.9004 419.5239 323.7813 422.9214 321.5586 425.2485 c +320.7197 426.1206 319.6836 426.8208 318.4785 427.3315 c +f +0 D +319.4092 415.2305 m +319.3926 410.5078 318.042 407.5742 315.3945 406.5078 C +314.6729 406.1855 313.8535 406.0332 312.9453 406.0488 c +310.1943 406.0488 308.4297 407.293 307.542 409.8535 c +307.0205 411.2344 306.7588 412.8281 306.7588 414.5977 c +306.7588 414.6504 306.7588 414.7031 306.7588 414.7559 c +306.7744 417.4473 307.2002 419.561 308.0254 421.0425 c +309.1758 423.0698 310.8604 424.0415 313.1758 424.0112 c +315.8447 424.0112 317.5938 422.7563 318.5293 420.1763 c +319.1289 418.6094 319.4238 416.9473 319.4092 415.2305 c +f +*U +*u +1 D +351.1064 417.8457 m +350.6318 424.6392 346.9629 428.0991 340.2012 428.1489 c +337.8291 428.1655 335.7432 427.6421 334.002 426.5933 c +331.9873 425.4077 330.5742 423.7935 329.8086 421.7993 c +328.9766 419.7026 328.5625 417.291 328.5801 414.6348 c +328.5459 410.8301 329.4922 407.7363 331.3926 405.4453 c +333.376 403.0508 336.3418 401.8457 340.209 401.8613 c +341.9434 401.8457 343.6162 402.1348 345.1748 402.7207 c +346.7607 403.3184 348.124 404.3535 349.2285 405.8008 c +349.9951 406.8125 350.5498 408.3789 350.9238 410.5898 C +351.0078 411.0859 L +345.5137 411.0859 L +345.459 410.7246 L +344.9873 407.5918 343.2588 406.0547 340.1768 406.0234 c +339.2813 406.0078 338.4395 406.1699 337.6719 406.5039 C +336.2715 407.0566 335.3164 408.1133 334.7363 409.7422 c +334.4219 410.6211 334.2139 412.0859 334.0947 413.9863 C +334.9756 413.9863 351.1895 413.9863 Y +351.1064 417.8457 L +f +0 D +345.6709 418.0859 m +344.8555 418.0859 335.0693 418.0859 334.1504 418.0859 C +334.2607 418.6328 334.4316 419.4741 334.4346 419.4907 C +335.1387 422.5005 337 423.9712 340.126 423.9868 c +342.0811 423.9712 343.5508 423.4067 344.4883 422.3081 c +345.166 421.52 345.5547 420.0845 345.6709 418.0859 C +f +*U +371.9424 411.1172 m +371.832 410.2832 371.6816 409.5859 371.4961 409.043 c +370.8779 407.0234 369.2148 406.0488 366.4082 406.0488 c +363.9287 406.002 362.2451 406.9961 361.2529 409.0879 c +360.6133 410.4141 360.2891 412.6094 360.2891 415.6172 c +360.2891 417.373 360.5625 419.0493 361.1006 420.5972 c +361.5566 421.9927 362.4873 422.9487 363.9482 423.5259 c +364.7471 423.8481 365.6182 424.0103 366.5391 424.0103 c +369.5781 423.979 371.2637 422.4634 371.6934 419.3774 C +371.7441 419.0112 L +377.2314 419.0112 L +376.8652 421.5024 L +376.5674 422.9663 375.9199 424.2358 374.9385 425.2983 c +373.21 427.1724 370.5107 428.1392 366.915 428.1733 c +362.9492 428.1567 359.8242 426.8628 357.6211 424.3276 c +355.7412 422.1646 354.7969 418.9199 354.8145 414.6855 c +354.8145 410.8613 355.7549 407.7695 357.6104 405.498 c +359.585 403.0996 362.5615 401.8867 366.458 401.8867 c +369.5137 401.8867 372.0508 402.6055 373.999 404.0254 c +375.1719 404.8867 376.0205 405.9375 376.5225 407.1484 c +376.8662 407.9707 377.1563 409.2324 377.4102 411 C +377.4795 411.4863 L +371.9922 411.4863 L +371.9424 411.1172 L +f +395.7109 423.3862 m +395.7109 427.4858 L +390.3838 427.4858 389.6484 427.4858 V +389.6484 428.2271 389.6484 434.0688 Y +389.0625 433.8296 L +384.3613 431.9087 L +384.3613 428.1851 384.3613 427.4858 V +383.6504 427.4858 379.4238 427.4858 Y +379.4238 423.3862 L +383.6504 423.3862 384.3613 423.3862 V +384.3613 422.5854 384.3613 409.4121 Y +384.3613 409.4082 384.3857 406.9102 Y +384.5801 403.5879 386.7363 401.9043 390.7949 401.8867 c +391.9551 401.8867 393.4844 402.0137 395.3428 402.2656 C +395.7109 402.3145 L +395.7109 406.5117 L +395.2061 406.416 L +393.9287 406.1719 392.8662 406.0488 392.0459 406.0488 c +390.1982 406.0059 389.9551 406.7871 389.875 407.0449 C +389.875 407.0547 389.7148 407.8086 389.7129 407.8145 C +389.7139 407.8145 389.7139 407.8164 389.7139 407.8203 c +389.7139 407.9199 389.6484 409.291 Y +389.6484 422.5845 389.6484 423.3862 V +390.3838 423.3862 395.7109 423.3862 Y +f +U +U +LB +%AI5_EndLayer-- +%%PageTrailer +gsave annotatepage grestore showpage +%%Trailer +Adobe_Illustrator_AI5 /terminate get exec +Adobe_ColorImage_AI6 /terminate get exec +Adobe_cshow /terminate get exec +Adobe_level2_AI5 /terminate get exec +%%EOF diff --git a/AspectC++/doc/images/ac++logo.pdf b/AspectC++/doc/images/ac++logo.pdf new file mode 100644 index 0000000..114600a Binary files /dev/null and b/AspectC++/doc/images/ac++logo.pdf differ diff --git a/AspectC++/doc/images/acmodel-rotated90.pdf b/AspectC++/doc/images/acmodel-rotated90.pdf new file mode 100644 index 0000000..ea31bfc Binary files /dev/null and b/AspectC++/doc/images/acmodel-rotated90.pdf differ diff --git a/AspectC++/doc/images/acmodel.dot b/AspectC++/doc/images/acmodel.dot new file mode 100644 index 0000000..3f2887f --- /dev/null +++ b/AspectC++/doc/images/acmodel.dot @@ -0,0 +1,121 @@ +digraph ACModel { + node [fontname = "Helvetica"]; + edge [fontname = "Helvetica"]; + File [shape=record label="{File|filename: string\nlen: int\ntime: int\n}"] + TUnit [shape=record label="{TUnit|}"] + File -> TUnit [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Header [shape=record label="{Header|}"] + File -> Header [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Header -> TUnit [label="in" headlabel="0..N"]; + Source [shape=record label="{Source|kind: SourceLocKind\nline: int\nlen: int\n}"] + Source -> File [label="file"]; + MemberIntro [shape=record label="{MemberIntro|}"] + MemberIntro -> Introduction [label="intro"]; + MemberIntro -> Name [label="members" headlabel="0..N"]; + BaseIntro [shape=record label="{BaseIntro|}"] + BaseIntro -> Introduction [label="intro"]; + BaseIntro -> Class [label="bases" headlabel="0..N"]; + ClassPlan [shape=record label="{ClassPlan|}"] + ClassPlan -> BaseIntro [label="base_intros" dir=back arrowtail="diamond" headlabel="0..N"]; + ClassPlan -> MemberIntro [label="member_intros" dir=back arrowtail="diamond" headlabel="0..N"]; + CodeAdvice [shape=record label="{CodeAdvice|conditional: bool\n}"] + CodeAdvice -> AdviceCode [label="advice"]; + CodePlan [shape=record label="{CodePlan|}"] + CodePlan -> CodeAdvice [label="before" dir=back arrowtail="diamond" headlabel="0..N"]; + CodePlan -> CodeAdvice [label="around" dir=back arrowtail="diamond" headlabel="0..1"]; + CodePlan -> CodeAdvice [label="after" dir=back arrowtail="diamond" headlabel="0..N"]; + CodePlan -> CodePlan [label="next_level" dir=back arrowtail="diamond" headlabel="0..1"]; + Any [shape=record label="{Any|jpid: int\n}"] + Any -> Source [label="source" dir=back arrowtail="diamond" headlabel="0..N"]; + Type [shape=record label="{Type|signature: string\n}"] + Any -> Type [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Arg [shape=record label="{Arg|type: string\nname: string\n}"] + Any -> Arg [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Name [shape=record label="{Name|name: string\nbuiltin: bool\n}"] + Any -> Name [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Name -> Any [label="children" dir=back arrowtail="diamond" headlabel="0..N"]; + Name -> TUnit [label="tunits" headlabel="0..N"]; + Namespace [shape=record label="{Namespace|}"] + Name -> Namespace [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Function [shape=record label="{Function|kind: FunctionType\nvariadic_args: bool\ncv_qualifiers: CVQualifiers\n}"] + Name -> Function [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Function -> Type [label="result_type" dir=back arrowtail="diamond" headlabel="0..1"]; + Function -> Type [label="arg_types" dir=back arrowtail="diamond" headlabel="0..N"]; + Function -> TUnit [label="static_in" headlabel="0..1"]; + Variable [shape=record label="{Variable|kind: VariableType\n}"] + Name -> Variable [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Variable -> Type [label="type" dir=back arrowtail="diamond"]; + Class [shape=record label="{Class|}"] + Name -> Class [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Class -> Class [label="bases" headlabel="0..N"]; + Class -> Class [label="derived" headlabel="0..N"]; + Class -> ClassPlan [label="plan" dir=back arrowtail="diamond" headlabel="0..1"]; + ClassSlice [shape=record label="{ClassSlice|is_struct: bool\n}"] + Name -> ClassSlice [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Code [shape=record label="{Code|}"] + Any -> Code [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Code -> CodePlan [label="plan" dir=back arrowtail="diamond" headlabel="0..1"]; + Access [shape=record label="{Access|lid: int\ntarget_object_lid: int\ncfg_block_lid: int\n}"] + Code -> Access [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Access -> Class [label="target_class" headlabel="0..1"]; + Get [shape=record label="{Get|}"] + Access -> Get [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Get -> Variable [label="variable" headlabel="0..1"]; + Set [shape=record label="{Set|}"] + Access -> Set [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Set -> Variable [label="variable" headlabel="0..1"]; + Call [shape=record label="{Call|default_args: int\n}"] + Access -> Call [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Call -> Function [label="target"]; + Call -> Type [label="variadic_arg_types" dir=back arrowtail="diamond" headlabel="0..N"]; + Call -> Access [label="implicit_access" dir=back arrowtail="diamond" headlabel="0..N"]; + Builtin [shape=record label="{Builtin|}"] + Access -> Builtin [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Builtin -> Function [label="target"]; + Builtin -> Access [label="implicit_access" dir=back arrowtail="diamond" headlabel="0..N"]; + Ref [shape=record label="{Ref|}"] + Access -> Ref [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Ref -> Variable [label="variable"]; + Ref -> Type [label="type" dir=back arrowtail="diamond"]; + GetRef [shape=record label="{GetRef|kind: VariableType\n}"] + Access -> GetRef [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + GetRef -> Type [label="type" dir=back arrowtail="diamond"]; + SetRef [shape=record label="{SetRef|kind: VariableType\n}"] + Access -> SetRef [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + SetRef -> Type [label="type" dir=back arrowtail="diamond"]; + CallRef [shape=record label="{CallRef|kind: VariableType\n}"] + Access -> CallRef [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + CallRef -> Type [label="type" dir=back arrowtail="diamond"]; + Execution [shape=record label="{Execution|}"] + Code -> Execution [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Construction [shape=record label="{Construction|}"] + Code -> Construction [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Destruction [shape=record label="{Destruction|}"] + Code -> Destruction [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Pointcut [shape=record label="{Pointcut|expr: string\nkind: PointcutType\n}"] + Name -> Pointcut [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Pointcut -> Arg [label="args" dir=back arrowtail="diamond" headlabel="0..N"]; + Advice [shape=record label="{Advice|lid: int\n}"] + Any -> Advice [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Advice -> Pointcut [label="pointcut" dir=back arrowtail="diamond"]; + AdviceCode [shape=record label="{AdviceCode|kind: AdviceCodeType\ncontext: AdviceCodeContext\n}"] + Advice -> AdviceCode [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Introduction [shape=record label="{Introduction|}"] + Advice -> Introduction [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Introduction -> ClassSlice [label="named_slice" headlabel="0..1"]; + Introduction -> ClassSlice [label="anon_slice" dir=back arrowtail="diamond" headlabel="0..1"]; + Order [shape=record label="{Order|}"] + Advice -> Order [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Order -> Pointcut [label="aspect_exprs" dir=back arrowtail="diamond" headlabel="0..N"]; + Aspect [shape=record label="{Aspect|}"] + Class -> Aspect [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Aspect -> Introduction [label="intros" dir=back arrowtail="diamond" headlabel="0..N"]; + Aspect -> AdviceCode [label="advices" dir=back arrowtail="diamond" headlabel="0..N"]; + Aspect -> Order [label="orders" dir=back arrowtail="diamond" headlabel="0..N"]; + Model [shape=record label="{Model|version: string\n}"] + Model -> File [label="files" dir=back arrowtail="diamond" headlabel="0..N"]; + Model -> Namespace [label="root" dir=back arrowtail="diamond"]; + { rank=same Name Code } + { rank=min Any } + +} diff --git a/AspectC++/doc/images/acmodel.eps b/AspectC++/doc/images/acmodel.eps new file mode 100644 index 0000000..0fbcfeb --- /dev/null +++ b/AspectC++/doc/images/acmodel.eps @@ -0,0 +1,2785 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Creator: graphviz version 2.26.3 (20100126.1600) +%%Title: ACModel +%%Pages: 1 +%%BoundingBox: 36 36 1861 1088 +%%EndComments +save +%%BeginProlog +/DotDict 200 dict def +DotDict begin + +/setupLatin1 { +mark +/EncodingVector 256 array def + EncodingVector 0 + +ISOLatin1Encoding 0 255 getinterval putinterval +EncodingVector 45 /hyphen put + +% Set up ISO Latin 1 character encoding +/starnetISO { + dup dup findfont dup length dict begin + { 1 index /FID ne { def }{ pop pop } ifelse + } forall + /Encoding EncodingVector def + currentdict end definefont +} def +/Times-Roman starnetISO def +/Times-Italic starnetISO def +/Times-Bold starnetISO def +/Times-BoldItalic starnetISO def +/Helvetica starnetISO def +/Helvetica-Oblique starnetISO def +/Helvetica-Bold starnetISO def +/Helvetica-BoldOblique starnetISO def +/Courier starnetISO def +/Courier-Oblique starnetISO def +/Courier-Bold starnetISO def +/Courier-BoldOblique starnetISO def +cleartomark +} bind def + +%%BeginResource: procset graphviz 0 0 +/coord-font-family /Times-Roman def +/default-font-family /Times-Roman def +/coordfont coord-font-family findfont 8 scalefont def + +/InvScaleFactor 1.0 def +/set_scale { + dup 1 exch div /InvScaleFactor exch def + scale +} bind def + +% styles +/solid { [] 0 setdash } bind def +/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def +/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def +/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def +/bold { 2 setlinewidth } bind def +/filled { } bind def +/unfilled { } bind def +/rounded { } bind def +/diagonals { } bind def + +% hooks for setting color +/nodecolor { sethsbcolor } bind def +/edgecolor { sethsbcolor } bind def +/graphcolor { sethsbcolor } bind def +/nopcolor {pop pop pop} bind def + +/beginpage { % i j npages + /npages exch def + /j exch def + /i exch def + /str 10 string def + npages 1 gt { + gsave + coordfont setfont + 0 0 moveto + (\() show i str cvs show (,) show j str cvs show (\)) show + grestore + } if +} bind def + +/set_font { + findfont exch + scalefont setfont +} def + +% draw text fitted to its expected width +/alignedtext { % width text + /text exch def + /width exch def + gsave + width 0 gt { + [] 0 setdash + text stringwidth pop width exch sub text length div 0 text ashow + } if + grestore +} def + +/boxprim { % xcorner ycorner xsize ysize + 4 2 roll + moveto + 2 copy + exch 0 rlineto + 0 exch rlineto + pop neg 0 rlineto + closepath +} bind def + +/ellipse_path { + /ry exch def + /rx exch def + /y exch def + /x exch def + matrix currentmatrix + newpath + x y translate + rx ry scale + 0 0 1 0 360 arc + setmatrix +} bind def + +/endpage { showpage } bind def +/showpage { } def + +/layercolorseq + [ % layer color sequence - darkest to lightest + [0 0 0] + [.2 .8 .8] + [.4 .8 .8] + [.6 .8 .8] + [.8 .8 .8] + ] +def + +/layerlen layercolorseq length def + +/setlayer {/maxlayer exch def /curlayer exch def + layercolorseq curlayer 1 sub layerlen mod get + aload pop sethsbcolor + /nodecolor {nopcolor} def + /edgecolor {nopcolor} def + /graphcolor {nopcolor} def +} bind def + +/onlayer { curlayer ne {invis} if } def + +/onlayers { + /myupper exch def + /mylower exch def + curlayer mylower lt + curlayer myupper gt + or + {invis} if +} def + +/curlayer 0 def + +%%EndResource +%%EndProlog +%%BeginSetup +14 default-font-family set_font +1 setmiterlimit +% /arrowlength 10 def +% /arrowwidth 5 def + +% make sure pdfmark is harmless for PS-interpreters other than Distiller +/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse +% make '<<' and '>>' safe on PS Level 1 devices +/languagelevel where {pop languagelevel}{1} ifelse +2 lt { + userdict (<<) cvn ([) cvn load put + userdict (>>) cvn ([) cvn load put +} if + +%%EndSetup +setupLatin1 +%%Page: 1 1 +%%PageBoundingBox: 36 36 1861 1088 +%%PageOrientation: Portrait +0 0 1 beginpage +gsave +36 36 1825 1052 boxprim clip newpath +1 1 set_scale 0 rotate 40 41 translate +% File +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 61.5 689 moveto +61.5 781 lineto +170.5 781 lineto +170.5 689 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +105 764.4 moveto 22 (File) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 61.5 754 moveto +170.5 754 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +69.5 737.4 moveto 93 (filename: string) alignedtext +0 0 0 nodecolor +14 /Helvetica set_font +96 718.4 moveto 40 (len: int) alignedtext +0 0 0 nodecolor +14 /Helvetica set_font +91.5 699.4 moveto 49 (time: int) alignedtext +grestore +% TUnit +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 118 270 moveto +118 324 lineto +172 324 lineto +172 270 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +128.5 307.4 moveto 33 (TUnit) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 118 297 moveto +172 297 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +143 280.4 moveto 4 ( ) alignedtext +grestore +% File->TUnit +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 115.73 673.8 moveto +115.9 626.77 116.98 560.21 121 502 curveto +125.42 438.01 135.39 363.28 140.99 324.11 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 110.48 673.95 moveto +115.7 688.96 lineto +120.98 673.97 lineto +closepath stroke +grestore +% Header +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 122.5 503 moveto +122.5 557 lineto +183.5 557 lineto +183.5 503 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +130.5 540.4 moveto 45 (Header) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 122.5 530 moveto +183.5 530 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +151 513.4 moveto 4 ( ) alignedtext +grestore +% File->Header +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 127 674.08 moveto +134.02 635.17 142.78 586.64 148.13 557 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 121.8 673.3 moveto +124.3 688.99 lineto +132.13 675.17 lineto +closepath stroke +grestore +% Header->TUnit +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 152.07 502.82 moveto +150.63 461.08 147.89 381.11 146.27 334.08 curveto +stroke +0 0 0 edgecolor +newpath 149.77 333.88 moveto +145.93 324.01 lineto +142.77 334.13 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 149.77 333.88 moveto +145.93 324.01 lineto +142.77 334.13 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +151 433.9 moveto 11 (in) alignedtext +0 0 0 edgecolor +14 /Helvetica set_font +137.96 329.82 moveto 25 (0..N) alignedtext +grestore +% Source +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 28 839 moveto +28 931 lineto +168 931 lineto +168 839 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +76.5 914.4 moveto 43 (Source) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 28 904 moveto +168 904 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +36 887.4 moveto 124 (kind: SourceLocKind) alignedtext +0 0 0 nodecolor +14 /Helvetica set_font +76.5 868.4 moveto 43 (line: int) alignedtext +0 0 0 nodecolor +14 /Helvetica set_font +78 849.4 moveto 40 (len: int) alignedtext +grestore +% Source->File +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 103.55 838.77 moveto +105.35 823.73 107.38 806.87 109.26 791.18 curveto +stroke +0 0 0 edgecolor +newpath 112.75 791.42 moveto +110.47 781.08 lineto +105.8 790.59 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 112.75 791.42 moveto +110.47 781.08 lineto +105.8 790.59 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +108 806.9 moveto 18 (file) alignedtext +grestore +% MemberIntro +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 733.5 270 moveto +733.5 324 lineto +828.5 324 lineto +828.5 270 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +741.5 307.4 moveto 79 (MemberIntro) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 733.5 297 moveto +828.5 297 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +779 280.4 moveto 4 ( ) alignedtext +grestore +% Introduction +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 638.5 140 moveto +638.5 194 lineto +725.5 194 lineto +725.5 140 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +646.5 177.4 moveto 71 (Introduction) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 638.5 167 moveto +725.5 167 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +680 150.4 moveto 4 ( ) alignedtext +grestore +% MemberIntro->Introduction +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 760.25 269.75 moveto +745.33 250.16 725.08 223.58 708.92 202.35 curveto +stroke +0 0 0 edgecolor +newpath 711.57 200.05 moveto +702.73 194.22 lineto +706 204.29 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 711.57 200.05 moveto +702.73 194.22 lineto +706 204.29 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +737 228.9 moveto 27 (intro) alignedtext +grestore +% Name +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 447 848.5 moveto +447 921.5 lineto +539 921.5 lineto +539 848.5 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +474.5 904.9 moveto 37 (Name) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 447 894.5 moveto +539 894.5 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +455 877.9 moveto 76 (name: string) alignedtext +0 0 0 nodecolor +14 /Helvetica set_font +458.5 858.9 moveto 69 (builtin: bool) alignedtext +grestore +% MemberIntro->Name +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 751.99 324.26 moveto +744.35 332.59 736.67 342.16 731 352 curveto +711.21 386.35 704 397.36 704 437 curveto +704 735 704 735 704 735 curveto +704 811.26 611.31 852.32 548.8 871.35 curveto +stroke +0 0 0 edgecolor +newpath 547.65 868.04 moveto +539.04 874.21 lineto +549.63 874.75 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 547.65 868.04 moveto +539.04 874.21 lineto +549.63 874.75 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +704 600.9 moveto 58 (members) alignedtext +0 0 0 edgecolor +14 /Helvetica set_font +534.05 864.5 moveto 25 (0..N) alignedtext +grestore +% ClassSlice +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 532 10 moveto +532 64 lineto +632 64 lineto +632 10 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +550 47.4 moveto 64 (ClassSlice) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 532 37 moveto +632 37 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +540 20.4 moveto 84 (is_struct: bool) alignedtext +grestore +% Introduction->ClassSlice +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 638.37 154.18 moveto +617.8 145.72 595.15 132.34 583 112 curveto +576.37 100.91 574.73 87.15 575.21 74.45 curveto +stroke +0 0 0 edgecolor +newpath 578.73 74.37 moveto +576.04 64.12 lineto +571.75 73.81 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 578.73 74.37 moveto +576.04 64.12 lineto +571.75 73.81 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +583 98.9 moveto 77 (named_slice) alignedtext +0 0 0 edgecolor +14 /Helvetica set_font +568.03 70.4 moveto 23 (0..1) alignedtext +grestore +% Introduction->ClassSlice +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 675.77 127.86 moveto +672.49 115.58 667.52 102.51 660 92 curveto +652.38 81.35 642.04 72.04 631.38 64.25 curveto +stroke +0 0 0 edgecolor +newpath 675.81 128.04 moveto +681.06 132.99 lineto +678.51 139.74 lineto +673.26 134.79 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 675.81 128.04 moveto +681.06 132.99 lineto +678.51 139.74 lineto +673.26 134.79 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +670 98.9 moveto 65 (anon_slice) alignedtext +0 0 0 edgecolor +14 /Helvetica set_font +629.67 63.19 moveto 23 (0..1) alignedtext +grestore +% Name->TUnit +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 446.9 862.27 moveto +428.38 851.43 407.93 837.07 393 820 curveto +388.57 814.93 217.5 451.28 162.11 333.42 curveto +stroke +0 0 0 edgecolor +newpath 165.14 331.64 moveto +157.72 324.08 lineto +158.81 334.62 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 165.14 331.64 moveto +157.72 324.08 lineto +158.81 334.62 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +301 600.9 moveto 33 (tunits) alignedtext +0 0 0 edgecolor +14 /Helvetica set_font +152.9 327.39 moveto 25 (0..N) alignedtext +grestore +% Class +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 791 577 moveto +791 631 lineto +845 631 lineto +845 577 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +801 614.4 moveto 34 (Class) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 791 604 moveto +845 604 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +816 587.4 moveto 4 ( ) alignedtext +grestore +% Name->Class +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 554.17 879.43 moveto +630.32 871.18 754.14 853.01 785 820 curveto +833.44 768.18 828.72 676.81 822.66 631.32 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 553.53 874.22 moveto +539.16 880.99 lineto +554.62 884.66 lineto +closepath stroke +grestore +% Any +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 400.5 989 moveto +400.5 1043 lineto +459.5 1043 lineto +459.5 989 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +418 1026.4 moveto 24 (Any) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 400.5 1016 moveto +459.5 1016 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +408.5 999.4 moveto 43 (jpid: int) alignedtext +grestore +% Name->Any +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 438.97 929.94 moveto +434.15 936.17 429.98 942.89 427 950 curveto +421.95 962.06 421.99 976.47 423.59 988.74 curveto +stroke +0 0 0 edgecolor +newpath 439.19 929.68 moveto +440.05 922.52 lineto +446.99 920.56 lineto +446.13 927.72 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 439.19 929.68 moveto +440.05 922.52 lineto +446.99 920.56 lineto +446.13 927.72 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +427 956.9 moveto 48 (children) alignedtext +0 0 0 edgecolor +14 /Helvetica set_font +405.86 977.12 moveto 25 (0..N) alignedtext +grestore +% Namespace +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 191.5 708 moveto +191.5 762 lineto +280.5 762 lineto +280.5 708 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +199.5 745.4 moveto 73 (Namespace) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 191.5 735 moveto +280.5 735 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +234 718.4 moveto 4 ( ) alignedtext +grestore +% Name->Namespace +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 432.67 866.17 moveto +401.4 855.06 363.31 839.38 332 820 curveto +305.88 803.83 280.02 780.4 261.74 762.22 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 431.06 871.17 moveto +446.95 871.09 lineto +434.49 861.24 lineto +closepath stroke +grestore +% Function +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 1015 391 moveto +1015 483 lineto +1191 483 lineto +1191 391 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +1077 466.4 moveto 52 (Function) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 1015 456 moveto +1191 456 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +1045.5 439.4 moveto 115 (kind: FunctionType) alignedtext +0 0 0 nodecolor +14 /Helvetica set_font +1046 420.4 moveto 114 (variadic_args: bool) alignedtext +0 0 0 nodecolor +14 /Helvetica set_font +1023 401.4 moveto 160 (cv_qualifiers: CVQualifiers) alignedtext +grestore +% Name->Function +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 554.26 880.14 moveto +618.99 873.23 722.86 857 805 820 curveto +906.63 774.22 937.47 757.92 1006 670 curveto +1050.31 613.15 1077.73 533.15 1091.67 483.23 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 553.48 874.94 moveto +539.08 881.67 lineto +554.53 885.39 lineto +closepath stroke +grestore +% Variable +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 1594 410 moveto +1594 464 lineto +1722 464 lineto +1722 410 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +1633 447.4 moveto 50 (Variable) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 1594 437 moveto +1722 437 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +1602 420.4 moveto 112 (kind: VariableType) alignedtext +grestore +% Name->Variable +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 554.38 881.61 moveto +751.97 870.26 1362.98 831.46 1436 782 curveto +1475.18 755.46 1447.87 716.02 1486 688 curveto +1520.98 662.3 1539.58 679.2 1582 670 curveto +1650.89 655.05 1683.53 679.09 1736 632 curveto +1779.92 592.58 1791.72 553.55 1763 502 curveto +1753.77 485.42 1738.37 472.54 1722.17 462.78 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 553.93 876.38 moveto +539.25 882.48 lineto +554.53 886.86 lineto +closepath stroke +grestore +% Name->ClassSlice +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 493 833.14 moveto +493 804.25 493 767.63 493 735 curveto +493 735 493 735 493 437 curveto +493 398.47 496.86 384.39 476 352 curveto +468.59 340.49 457.24 346.19 451 334 curveto +436.01 304.73 442.37 291.74 451 260 curveto +472.15 182.23 528.05 103.88 559.56 64 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 487.75 833.32 moveto +493 848.32 lineto +498.25 833.32 lineto +closepath stroke +grestore +% Pointcut +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 166 130.5 moveto +166 203.5 lineto +294 203.5 lineto +294 130.5 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +205.5 186.9 moveto 49 (Pointcut) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 166 176.5 moveto +294 176.5 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +196.5 159.9 moveto 67 (expr: string) alignedtext +0 0 0 nodecolor +14 /Helvetica set_font +174 140.9 moveto 112 (kind: PointcutType) alignedtext +grestore +% Name->Pointcut +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 481.88 833.47 moveto +448.64 679.75 351.69 234.25 342 222 curveto +329.7 206.45 311.89 194.99 294.07 186.69 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 476.78 834.7 moveto +485.08 848.25 lineto +487.04 832.48 lineto +closepath stroke +grestore +% BaseIntro +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 846 270 moveto +846 324 lineto +920 324 lineto +920 270 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +854 307.4 moveto 58 (BaseIntro) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 846 297 moveto +920 297 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +881 280.4 moveto 4 ( ) alignedtext +grestore +% BaseIntro->Introduction +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 850.5 269.96 moveto +846.04 266.51 841.46 263.11 837 260 curveto +803.97 236.97 765.1 213.65 734.55 196.13 curveto +stroke +0 0 0 edgecolor +newpath 736.18 193.03 moveto +725.76 191.12 lineto +732.71 199.11 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 736.18 193.03 moveto +725.76 191.12 lineto +732.71 199.11 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +808 228.9 moveto 27 (intro) alignedtext +grestore +% BaseIntro->Class +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 920.31 305.83 moveto +962.07 317.49 1020.83 340.3 996 372 curveto +975.39 398.31 948.64 368.57 923 390 curveto +860.27 442.45 887.12 486.2 848 558 curveto +846.21 561.29 844.26 564.66 842.24 568 curveto +stroke +0 0 0 edgecolor +newpath 839.13 566.37 moveto +836.81 576.7 lineto +845.07 570.07 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 839.13 566.37 moveto +836.81 576.7 lineto +845.07 570.07 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +923 433.9 moveto 37 (bases) alignedtext +0 0 0 edgecolor +14 /Helvetica set_font +825.52 563.68 moveto 25 (0..N) alignedtext +grestore +% Class->Class +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 845.24 609.24 moveto +855.02 609.36 863 607.61 863 604 curveto +863 601.8 860.04 600.29 855.51 599.47 curveto +stroke +0 0 0 edgecolor +newpath 855.46 595.96 moveto +845.24 598.76 lineto +854.97 602.95 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 855.46 595.96 moveto +845.24 598.76 lineto +854.97 602.95 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +863 600.9 moveto 37 (bases) alignedtext +0 0 0 edgecolor +14 /Helvetica set_font +842.08 592.07 moveto 25 (0..N) alignedtext +grestore +% Class->Class +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 845.06 620.4 moveto +870.18 627.65 900 622.18 900 604 curveto +900 588.16 877.37 581.97 854.93 585.43 curveto +stroke +0 0 0 edgecolor +newpath 854.07 582.03 moveto +845.06 587.6 lineto +855.58 588.87 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 854.07 582.03 moveto +845.06 587.6 lineto +855.58 588.87 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +900 600.9 moveto 45 (derived) alignedtext +0 0 0 edgecolor +14 /Helvetica set_font +840.5 578.42 moveto 25 (0..N) alignedtext +grestore +% ClassPlan +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 779.5 410 moveto +779.5 464 lineto +856.5 464 lineto +856.5 410 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +787.5 447.4 moveto 61 (ClassPlan) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 779.5 437 moveto +856.5 437 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +816 420.4 moveto 4 ( ) alignedtext +grestore +% Class->ClassPlan +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 818 564.73 moveto +818 533.8 818 491.48 818 464.19 curveto +stroke +0 0 0 edgecolor +newpath 818 564.8 moveto +822 570.8 lineto +818 576.8 lineto +814 570.8 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 818 564.8 moveto +822 570.8 lineto +818 576.8 lineto +814 570.8 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +818 526.9 moveto 26 (plan) alignedtext +0 0 0 edgecolor +14 /Helvetica set_font +810.73 470.15 moveto 23 (0..1) alignedtext +grestore +% Aspect +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 522 410 moveto +522 464 lineto +580 464 lineto +580 410 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +530 447.4 moveto 42 (Aspect) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 522 437 moveto +580 437 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +549 420.4 moveto 4 ( ) alignedtext +grestore +% Class->Aspect +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 777.22 582.03 moveto +773.43 579.99 769.64 577.96 766 576 curveto +689.61 535 662.46 537.19 594 484 curveto +586.66 478.3 579.51 471.28 573.21 464.42 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 775.05 586.82 moveto +790.75 589.31 lineto +780.03 577.58 lineto +closepath stroke +grestore +% ClassPlan->MemberIntro +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 769.09 408.52 moveto +756.64 398.66 744.86 386.41 738 372 curveto +730.26 355.74 739.22 338.24 750.93 324.24 curveto +stroke +0 0 0 edgecolor +newpath 769.47 408.8 moveto +776.67 409.13 lineto +779.14 415.91 lineto +771.93 415.57 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 769.47 408.8 moveto +776.67 409.13 lineto +779.14 415.91 lineto +771.93 415.57 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +738 358.9 moveto 92 (member_intros) alignedtext +0 0 0 edgecolor +14 /Helvetica set_font +736.1 330.87 moveto 25 (0..N) alignedtext +grestore +% ClassPlan->BaseIntro +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 832.78 398.6 moveto +838.72 383.87 845.85 367 853 352 curveto +857.4 342.77 862.61 332.9 867.45 324.11 curveto +stroke +0 0 0 edgecolor +newpath 832.73 398.72 moveto +834.23 405.78 lineto +828.3 409.88 lineto +826.8 402.82 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 832.73 398.72 moveto +834.23 405.78 lineto +828.3 409.88 lineto +826.8 402.82 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +853 358.9 moveto 70 (base_intros) alignedtext +0 0 0 edgecolor +14 /Helvetica set_font +854.3 330.99 moveto 25 (0..N) alignedtext +grestore +% CodeAdvice +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 545 577 moveto +545 631 lineto +659 631 lineto +659 577 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +565.5 614.4 moveto 73 (CodeAdvice) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 545 604 moveto +659 604 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +553 587.4 moveto 98 (conditional: bool) alignedtext +grestore +% AdviceCode +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 459.5 260.5 moveto +459.5 333.5 lineto +646.5 333.5 lineto +646.5 260.5 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +516.5 316.9 moveto 73 (AdviceCode) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 459.5 306.5 moveto +646.5 306.5 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +485 289.9 moveto 136 (kind: AdviceCodeType) alignedtext +0 0 0 nodecolor +14 /Helvetica set_font +467.5 270.9 moveto 171 (context: AdviceCodeContext) alignedtext +grestore +% CodeAdvice->AdviceCode +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 608.12 576.75 moveto +617.48 529.27 631.35 429.07 602 352 curveto +600.73 348.67 599.16 345.42 597.37 342.26 curveto +stroke +0 0 0 edgecolor +newpath 600.16 340.13 moveto +591.79 333.64 lineto +594.28 343.93 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 600.16 340.13 moveto +591.79 333.64 lineto +594.28 343.93 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +619 433.9 moveto 40 (advice) alignedtext +grestore +% CodePlan +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 521 708 moveto +521 762 lineto +597 762 lineto +597 708 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +529 745.4 moveto 60 (CodePlan) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 521 735 moveto +597 735 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +557 718.4 moveto 4 ( ) alignedtext +grestore +% CodePlan->CodeAdvice +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 533.47 696.89 moveto +526.63 681.78 523.08 664.58 531 650 curveto +534.93 642.77 540.54 636.51 546.9 631.13 curveto +stroke +0 0 0 edgecolor +newpath 533.69 697.29 moveto +540 700.78 lineto +539.21 707.95 lineto +532.9 704.46 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 533.69 697.29 moveto +540 700.78 lineto +539.21 707.95 lineto +532.9 704.46 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +531 656.9 moveto 39 (before) alignedtext +0 0 0 edgecolor +14 /Helvetica set_font +530.34 637.17 moveto 25 (0..N) alignedtext +grestore +% CodePlan->CodeAdvice +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 571.67 696.41 moveto +578.55 675.43 586.91 649.98 593.1 631.11 curveto +stroke +0 0 0 edgecolor +newpath 571.65 696.46 moveto +573.58 703.4 lineto +567.91 707.86 lineto +565.98 700.91 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 571.65 696.46 moveto +573.58 703.4 lineto +567.91 707.86 lineto +565.98 700.91 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +586 656.9 moveto 43 (around) alignedtext +0 0 0 edgecolor +14 /Helvetica set_font +582.79 637.94 moveto 23 (0..1) alignedtext +grestore +% CodePlan->CodeAdvice +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 606.78 703.7 moveto +617.37 694.24 627.16 682.89 633 670 curveto +638.79 657.2 633.74 643.09 626.15 631.21 curveto +stroke +0 0 0 edgecolor +newpath 606.59 703.86 moveto +604.53 710.76 lineto +597.36 711.51 lineto +599.42 704.6 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 606.59 703.86 moveto +604.53 710.76 lineto +597.36 711.51 lineto +599.42 704.6 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +635 656.9 moveto 28 (after) alignedtext +0 0 0 edgecolor +14 /Helvetica set_font +621.95 633.68 moveto 25 (0..N) alignedtext +grestore +% CodePlan->CodePlan +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 608.97 745.35 moveto +612.71 743.03 615 739.58 615 735 curveto +615 726.62 607.33 722.03 597.21 721.25 curveto +stroke +0 0 0 edgecolor +newpath 608.74 745.41 moveto +604.09 750.92 lineto +597.21 748.75 lineto +601.86 743.24 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 608.74 745.41 moveto +604.09 750.92 lineto +597.21 748.75 lineto +601.86 743.24 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +615 731.9 moveto 61 (next_level) alignedtext +0 0 0 edgecolor +14 /Helvetica set_font +595.21 715.01 moveto 23 (0..1) alignedtext +grestore +% Any->Source +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 388.36 1006.91 moveto +353.35 998.76 302.24 985.7 259 970 curveto +221.25 956.29 212.53 950.74 177 932 curveto +174.18 930.51 171.31 928.97 168.43 927.39 curveto +stroke +0 0 0 edgecolor +newpath 388.78 1007 moveto +395.53 1004.44 lineto +400.48 1009.68 lineto +393.74 1012.24 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 388.78 1007 moveto +395.53 1004.44 lineto +400.48 1009.68 lineto +393.74 1012.24 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +259 956.9 moveto 41 (source) alignedtext +0 0 0 edgecolor +14 /Helvetica set_font +165.91 924.93 moveto 25 (0..N) alignedtext +grestore +% Any->Name +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 469.99 983.17 moveto +473.43 979.03 476.54 974.62 479 970 curveto +486.81 955.35 490.48 937.43 492.13 921.82 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 466.17 979.56 moveto +459.62 994.04 lineto +473.77 986.8 lineto +closepath stroke +grestore +% Type +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 1320.5 270 moveto +1320.5 324 lineto +1433.5 324 lineto +1433.5 270 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +1361.5 307.4 moveto 31 (Type) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 1320.5 297 moveto +1433.5 297 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +1328.5 280.4 moveto 97 (signature: string) alignedtext +grestore +% Any->Type +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 474.93 1014.17 moveto +713.09 1004.16 1817 954.05 1817 885 curveto +1817 885 1817 885 1817 437 curveto +1817 357.44 1552.46 317.09 1433.62 302.97 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 474.38 1008.93 moveto +459.61 1014.8 lineto +474.82 1019.43 lineto +closepath stroke +grestore +% Arg +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 4 .5 moveto +4 73.5 lineto +96 73.5 lineto +96 .5 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +39 56.9 moveto 22 (Arg) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 4 46.5 moveto +96 46.5 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +16.5 29.9 moveto 67 (type: string) alignedtext +0 0 0 nodecolor +14 /Helvetica set_font +12 10.9 moveto 76 (name: string) alignedtext +grestore +% Any->Arg +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 385.2 1012.16 moveto +290.58 1003.22 74.5 978.19 19 932 curveto +1.68 917.59 0 907.53 0 885 curveto +0 885 0 885 0 167 curveto +0 133.87 14.32 98.97 27.63 73.68 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 384.93 1017.41 moveto +400.35 1013.55 lineto +385.89 1006.95 lineto +closepath stroke +grestore +% Code +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 1421 858 moveto +1421 912 lineto +1475 912 lineto +1475 858 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +1431.5 895.4 moveto 33 (Code) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 1421 885 moveto +1475 885 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +1446 868.4 moveto 4 ( ) alignedtext +grestore +% Any->Code +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 474.61 1010.26 moveto +649.02 987.82 1282.06 906.35 1420.94 888.48 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 473.85 1005.06 moveto +459.64 1012.19 lineto +475.19 1015.48 lineto +closepath stroke +grestore +% Advice +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 272.5 410 moveto +272.5 464 lineto +329.5 464 lineto +329.5 410 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +280.5 447.4 moveto 41 (Advice) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 272.5 437 moveto +329.5 437 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +283 420.4 moveto 36 (lid: int) alignedtext +grestore +% Any->Advice +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 404.22 975.96 moveto +380.94 937.6 347.98 877.24 332 820 curveto +295.86 690.53 297.41 527.59 299.7 464.08 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 399.8 978.81 moveto +412.15 988.81 lineto +408.74 973.29 lineto +closepath stroke +grestore +% Function->TUnit +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 1023.64 390.78 moveto +993.19 375.43 957.47 360.17 923 352 curveto +843.3 333.1 262.09 364.33 186 334 curveto +183.15 332.87 180.38 331.44 177.7 329.81 curveto +stroke +0 0 0 edgecolor +newpath 179.7 326.93 moveto +169.52 324.02 lineto +175.66 332.65 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 179.7 326.93 moveto +169.52 324.02 lineto +175.66 332.65 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +979 358.9 moveto 50 (static_in) alignedtext +0 0 0 edgecolor +14 /Helvetica set_font +167.86 322.7 moveto 23 (0..1) alignedtext +grestore +% Function->Type +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 1063.5 379.38 moveto +1061.26 369.62 1062.25 360.06 1069 352 curveto +1100.43 314.46 1240.29 302.52 1320.31 298.74 curveto +stroke +0 0 0 edgecolor +newpath 1063.54 379.5 moveto +1069.28 383.87 lineto +1067.46 390.85 lineto +1061.72 386.48 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 1063.54 379.5 moveto +1069.28 383.87 lineto +1067.46 390.85 lineto +1061.72 386.48 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +1069 358.9 moveto 67 (result_type) alignedtext +0 0 0 edgecolor +14 /Helvetica set_font +1299.99 300.35 moveto 23 (0..1) alignedtext +grestore +% Function->Type +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 1131.42 380.8 moveto +1139.1 369.95 1148.3 359.6 1159 352 curveto +1184.7 333.75 1264.73 316.63 1320.32 306.49 curveto +stroke +0 0 0 edgecolor +newpath 1131.4 380.83 moveto +1131.44 388.04 lineto +1124.8 390.85 lineto +1124.76 383.64 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 1131.4 380.83 moveto +1131.44 388.04 lineto +1124.8 390.85 lineto +1124.76 383.64 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +1159 358.9 moveto 60 (arg_types) alignedtext +0 0 0 edgecolor +14 /Helvetica set_font +1299.69 309.21 moveto 25 (0..N) alignedtext +grestore +% Variable->Type +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 1606.17 403.52 moveto +1579.49 386.97 1546.11 367.32 1515 352 curveto +1488.86 339.12 1458.91 326.89 1433.6 317.25 curveto +stroke +0 0 0 edgecolor +newpath 1606.24 403.56 moveto +1613.45 403.35 lineto +1616.42 409.92 lineto +1609.21 410.13 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 1606.24 403.56 moveto +1613.45 403.35 lineto +1616.42 409.92 lineto +1609.21 410.13 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +1551 358.9 moveto 26 (type) alignedtext +grestore +% Code->CodePlan +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 1409.03 878.42 moveto +1262.14 853.64 742.87 766.02 597.23 741.45 curveto +stroke +0 0 0 edgecolor +newpath 1409.08 878.43 moveto +1415.66 875.49 lineto +1420.91 880.43 lineto +1414.33 883.37 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 1409.08 878.43 moveto +1415.66 875.49 lineto +1420.91 880.43 lineto +1414.33 883.37 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +1056 806.9 moveto 26 (plan) alignedtext +0 0 0 edgecolor +14 /Helvetica set_font +595.37 735.69 moveto 23 (0..1) alignedtext +grestore +% Access +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 1290.5 689 moveto +1290.5 781 lineto +1427.5 781 lineto +1427.5 689 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +1337 764.4 moveto 44 (Access) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 1290.5 754 moveto +1427.5 754 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +1341 737.4 moveto 36 (lid: int) alignedtext +0 0 0 nodecolor +14 /Helvetica set_font +1298.5 718.4 moveto 121 (target_object_lid: int) alignedtext +0 0 0 nodecolor +14 /Helvetica set_font +1309 699.4 moveto 100 (cfg_block_lid: int) alignedtext +grestore +% Code->Access +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 1424.08 844.69 moveto +1412.45 825.09 1398.41 801.42 1386.35 781.1 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 1419.71 847.61 moveto +1431.88 857.84 lineto +1428.74 842.26 lineto +closepath stroke +grestore +% Execution +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 1597 708 moveto +1597 762 lineto +1673 762 lineto +1673 708 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +1605 745.4 moveto 60 (Execution) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 1597 735 moveto +1673 735 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +1633 718.4 moveto 4 ( ) alignedtext +grestore +% Code->Execution +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 1487.62 858.25 moveto +1516.34 838.3 1555.65 809.8 1588 782 curveto +1595.18 775.83 1602.58 768.79 1609.32 762.08 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 1484.61 853.95 moveto +1475.23 866.79 lineto +1490.57 862.6 lineto +closepath stroke +grestore +% Construction +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 1691 708 moveto +1691 762 lineto +1783 762 lineto +1783 708 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +1699 745.4 moveto 76 (Construction) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 1691 735 moveto +1783 735 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +1735 718.4 moveto 4 ( ) alignedtext +grestore +% Code->Construction +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 1489.7 870.87 moveto +1537.97 853.57 1618.92 821.63 1682 782 curveto +1691.15 776.25 1700.35 769.06 1708.55 762.05 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 1487.64 866.02 moveto +1475.24 875.96 lineto +1491.13 875.93 lineto +closepath stroke +grestore +% Destruction +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 1494.5 708 moveto +1494.5 762 lineto +1579.5 762 lineto +1579.5 708 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +1502.5 745.4 moveto 69 (Destruction) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 1494.5 735 moveto +1579.5 735 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +1535 718.4 moveto 4 ( ) alignedtext +grestore +% Code->Destruction +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 1471.78 844.92 moveto +1487.3 818.76 1507.15 785.31 1520.85 762.21 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 1467.26 842.26 moveto +1464.12 857.84 lineto +1476.29 847.61 lineto +closepath stroke +grestore +% Access->Class +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 1290.27 729.74 moveto +1209.32 722.21 1071.51 705.19 958 670 curveto +921.22 658.6 881.75 639.28 854.12 624.48 curveto +stroke +0 0 0 edgecolor +newpath 855.69 621.35 moveto +845.23 619.65 lineto +852.35 627.5 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 855.69 621.35 moveto +845.23 619.65 lineto +852.35 627.5 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +958 656.9 moveto 73 (target_class) alignedtext +0 0 0 edgecolor +14 /Helvetica set_font +843.71 617.16 moveto 23 (0..1) alignedtext +grestore +% Get +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 1569 577 moveto +1569 631 lineto +1623 631 lineto +1623 577 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +1584.5 614.4 moveto 23 (Get) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 1569 604 moveto +1623 604 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +1594 587.4 moveto 4 ( ) alignedtext +grestore +% Access->Get +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 1441.57 692.71 moveto +1445.41 691.07 1449.23 689.48 1453 688 curveto +1479.3 677.64 1488.96 683.11 1514 670 curveto +1533.91 659.57 1553.62 643.93 1568.72 630.49 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 1439.22 688.02 moveto +1427.67 698.93 lineto +1443.51 697.6 lineto +closepath stroke +grestore +% Set +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 1673 577 moveto +1673 631 lineto +1727 631 lineto +1727 577 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +1689.5 614.4 moveto 21 (Set) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 1673 604 moveto +1727 604 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +1698 587.4 moveto 4 ( ) alignedtext +grestore +% Access->Set +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 1441.54 692.25 moveto +1445.38 690.73 1449.21 689.31 1453 688 curveto +1491.16 674.86 1503.42 681.83 1542 670 curveto +1589.32 655.49 1641.92 631.93 1672.92 617.24 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 1439.45 687.43 moveto +1427.67 698.1 lineto +1443.53 697.11 lineto +closepath stroke +grestore +% Call +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 1089.5 577 moveto +1089.5 631 lineto +1202.5 631 lineto +1202.5 577 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +1134 614.4 moveto 24 (Call) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 1089.5 604 moveto +1202.5 604 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +1097.5 587.4 moveto 97 (default_args: int) alignedtext +grestore +% Access->Call +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 1277.1 693.88 moveto +1263.19 686.28 1249.03 678.16 1236 670 curveto +1217.11 658.17 1197.03 643.65 1180.64 631.25 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 1274.63 698.51 moveto +1290.32 700.98 lineto +1279.6 689.26 lineto +closepath stroke +grestore +% Builtin +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 1222 577 moveto +1222 631 lineto +1276 631 lineto +1276 577 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +1230.5 614.4 moveto 37 (Builtin) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 1222 604 moveto +1276 604 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +1247 587.4 moveto 4 ( ) alignedtext +grestore +% Access->Builtin +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 1353.89 673.95 moveto +1351.21 665.34 1347.4 657.04 1342 650 curveto +1325.77 628.85 1297.22 616.78 1276.03 610.36 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 1348.79 675.2 moveto +1357.38 688.57 lineto +1359 672.76 lineto +closepath stroke +grestore +% Ref +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 1409 577 moveto +1409 631 lineto +1463 631 lineto +1463 577 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +1425 614.4 moveto 22 (Ref) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 1409 604 moveto +1463 604 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +1434 587.4 moveto 4 ( ) alignedtext +grestore +% Access->Ref +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 1393.75 675.88 moveto +1402.94 660.24 1412.42 644.12 1420.06 631.11 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 1389.22 673.22 moveto +1386.15 688.81 lineto +1398.27 678.54 lineto +closepath stroke +grestore +% GetRef +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 914 503 moveto +914 557 lineto +1042 557 lineto +1042 503 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +956 540.4 moveto 44 (GetRef) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 914 530 moveto +1042 530 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +922 513.4 moveto 112 (kind: VariableType) alignedtext +grestore +% Access->GetRef +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 1275.18 726.59 moveto +1222.41 718.32 1154.6 702.02 1102 670 curveto +1054.85 641.3 1015.64 588.98 994.62 557.07 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 1274.73 731.83 moveto +1290.33 728.82 lineto +1276.25 721.45 lineto +closepath stroke +grestore +% SetRef +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 1278 503 moveto +1278 557 lineto +1406 557 lineto +1406 503 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +1321 540.4 moveto 42 (SetRef) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 1278 530 moveto +1406 530 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +1286 513.4 moveto 112 (kind: VariableType) alignedtext +grestore +% Access->SetRef +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 1359.97 673.75 moveto +1359.98 672.49 1359.99 671.24 1360 670 curveto +1360.07 661.11 1360.66 658.86 1360 650 curveto +1357.6 617.86 1351.64 581.27 1347.23 557.04 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 1354.72 673.78 moveto +1359.8 688.84 lineto +1365.22 673.9 lineto +closepath stroke +grestore +% CallRef +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 1436 503 moveto +1436 557 lineto +1564 557 lineto +1564 503 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +1477.5 540.4 moveto 45 (CallRef) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 1436 530 moveto +1564 530 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +1444 513.4 moveto 112 (kind: VariableType) alignedtext +grestore +% Access->CallRef +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 1433.27 678.52 moveto +1447.78 664.64 1461.67 648.86 1472 632 curveto +1486.1 608.98 1493.24 578.77 1496.77 557.21 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 1429.62 674.75 moveto +1422.11 688.76 lineto +1436.72 682.49 lineto +closepath stroke +grestore +% Get->Variable +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 1623.17 577.51 moveto +1628.09 571.51 1632.7 564.87 1636 558 curveto +1648.62 531.73 1654.04 499.07 1656.34 474.31 curveto +stroke +0 0 0 edgecolor +newpath 1659.84 474.47 moveto +1657.15 464.22 lineto +1652.86 473.91 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 1659.84 474.47 moveto +1657.15 464.22 lineto +1652.86 473.91 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +1652 526.9 moveto 48 (variable) alignedtext +0 0 0 edgecolor +14 /Helvetica set_font +1649.14 470.49 moveto 23 (0..1) alignedtext +grestore +% Set->Variable +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 1707.41 576.87 moveto +1711.84 555.89 1715.17 526.41 1707 502 curveto +1703.46 491.43 1697.46 481.21 1690.83 472.12 curveto +stroke +0 0 0 edgecolor +newpath 1693.53 469.87 moveto +1684.64 464.11 lineto +1687.99 474.16 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 1693.53 469.87 moveto +1684.64 464.11 lineto +1687.99 474.16 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +1711 526.9 moveto 48 (variable) alignedtext +0 0 0 edgecolor +14 /Helvetica set_font +1682.03 465.59 moveto 23 (0..1) alignedtext +grestore +% Call->Type +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 1168.12 565.88 moveto +1169.48 563.24 1170.79 560.59 1172 558 curveto +1186.92 526.16 1188.43 517.21 1200 484 curveto +1214.43 442.59 1203.19 424.7 1230 390 curveto +1253.36 359.77 1289.52 336.71 1320.14 321.11 curveto +stroke +0 0 0 edgecolor +newpath 1168.04 566.05 moveto +1168.73 573.23 lineto +1162.37 576.63 lineto +1161.68 569.45 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 1168.04 566.05 moveto +1168.73 573.23 lineto +1162.37 576.63 lineto +1161.68 569.45 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +1230 433.9 moveto 114 (variadic_arg_types) alignedtext +0 0 0 edgecolor +14 /Helvetica set_font +1301.58 325.97 moveto 25 (0..N) alignedtext +grestore +% Call->Function +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 1139 576.8 moveto +1133.16 554.14 1124.67 521.14 1117.39 492.89 curveto +stroke +0 0 0 edgecolor +newpath 1120.76 491.93 moveto +1114.88 483.12 lineto +1113.98 493.68 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 1120.76 491.93 moveto +1114.88 483.12 lineto +1113.98 493.68 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +1133 526.9 moveto 35 (target) alignedtext +grestore +% Call->Access +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 1110.9 641.51 moveto +1105.84 651.2 1104.31 661.33 1111 670 curveto +1132.82 698.28 1224.76 716.65 1290.32 726.42 curveto +stroke +0 0 0 edgecolor +newpath 1111.02 641.33 moveto +1110.93 634.12 lineto +1117.55 631.26 lineto +1117.64 638.47 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 1111.02 641.33 moveto +1110.93 634.12 lineto +1117.55 631.26 lineto +1117.64 638.47 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +1111 656.9 moveto 92 (implicit_access) alignedtext +0 0 0 edgecolor +14 /Helvetica set_font +1268.21 726.09 moveto 25 (0..N) alignedtext +grestore +% Builtin->Function +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 1230.24 576.61 moveto +1215.33 555.5 1193.48 525.95 1172 502 curveto +1168.59 498.19 1164.98 494.35 1161.29 490.54 curveto +stroke +0 0 0 edgecolor +newpath 1163.62 487.92 moveto +1154.1 483.27 lineto +1158.64 492.84 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 1163.62 487.92 moveto +1154.1 483.27 lineto +1158.64 492.84 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +1215 526.9 moveto 35 (target) alignedtext +grestore +% Builtin->Access +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 1240.18 643.52 moveto +1239.98 652.69 1241.42 662.08 1246 670 curveto +1256.09 687.44 1272.82 700.6 1290.35 710.37 curveto +stroke +0 0 0 edgecolor +newpath 1240.2 643.24 moveto +1236.78 636.9 lineto +1241.31 631.29 lineto +1244.74 637.64 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 1240.2 643.24 moveto +1236.78 636.9 lineto +1241.31 631.29 lineto +1244.74 637.64 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +1246 656.9 moveto 92 (implicit_access) alignedtext +0 0 0 edgecolor +14 /Helvetica set_font +1267.89 706.38 moveto 25 (0..N) alignedtext +grestore +% Ref->Type +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 1428.5 564.96 moveto +1416.36 501.79 1392.71 378.75 1382.22 324.18 curveto +stroke +0 0 0 edgecolor +newpath 1428.5 564.97 moveto +1433.56 570.11 lineto +1430.76 576.76 lineto +1425.7 571.62 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 1428.5 564.97 moveto +1433.56 570.11 lineto +1430.76 576.76 lineto +1425.7 571.62 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +1412 433.9 moveto 26 (type) alignedtext +grestore +% Ref->Variable +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 1463.14 601.25 moveto +1492.12 596.92 1537.56 585.87 1565 558 curveto +1583.44 539.27 1569.41 523.86 1584 502 curveto +1591.56 490.67 1601.59 480.09 1611.81 470.9 curveto +stroke +0 0 0 edgecolor +newpath 1614.35 473.33 moveto +1619.63 464.15 lineto +1609.77 468.04 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 1614.35 473.33 moveto +1619.63 464.15 lineto +1609.77 468.04 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +1584 526.9 moveto 48 (variable) alignedtext +grestore +% GetRef->Type +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 967.89 490.86 moveto +962.48 460.77 960.42 419.51 980 390 curveto +991 373.42 1003.12 380.74 1021 372 curveto +1037.79 363.79 1040.33 358.11 1058 352 curveto +1146.69 321.31 1255.42 307.25 1320.3 301.19 curveto +stroke +0 0 0 edgecolor +newpath 967.97 491.24 moveto +973.08 496.32 lineto +970.36 503 lineto +965.24 497.91 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 967.97 491.24 moveto +973.08 496.32 lineto +970.36 503 lineto +965.24 497.91 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +980 433.9 moveto 26 (type) alignedtext +grestore +% SetRef->Type +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 1347.87 490.92 moveto +1354.98 443.6 1366.77 365.12 1372.94 324.01 curveto +stroke +0 0 0 edgecolor +newpath 1347.87 490.95 moveto +1350.93 497.48 lineto +1346.08 502.82 lineto +1343.02 496.29 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 1347.87 490.95 moveto +1350.93 497.48 lineto +1346.08 502.82 lineto +1343.02 496.29 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +1362 433.9 moveto 26 (type) alignedtext +grestore +% CallRef->Type +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 1498.57 490.77 moveto +1495.26 451.76 1484.87 392.11 1453 352 curveto +1444.69 341.54 1433.91 332.14 1423.09 324.19 curveto +stroke +0 0 0 edgecolor +newpath 1498.58 490.93 moveto +1502.99 496.63 lineto +1499.43 502.9 lineto +1495.01 497.2 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 1498.58 490.93 moveto +1502.99 496.63 lineto +1499.43 502.9 lineto +1495.01 497.2 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +1497 433.9 moveto 26 (type) alignedtext +grestore +% Pointcut->Arg +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 169.36 123.2 moveto +145.48 105.96 118.5 86.47 96.24 70.39 curveto +stroke +0 0 0 edgecolor +newpath 169.65 123.42 moveto +176.86 123.69 lineto +179.38 130.44 lineto +172.17 130.17 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 169.65 123.42 moveto +176.86 123.69 lineto +179.38 130.44 lineto +172.17 130.17 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +150 98.9 moveto 27 (args) alignedtext +0 0 0 edgecolor +14 /Helvetica set_font +93.56 69.17 moveto 25 (0..N) alignedtext +grestore +% Advice->Introduction +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 326.23 397.18 moveto +353 357.71 398.62 297.81 451 260 curveto +509.36 217.87 589.52 191.2 638.44 177.7 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 321.82 394.33 moveto +317.89 409.73 lineto +330.57 400.14 lineto +closepath stroke +grestore +% Advice->AdviceCode +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 342.36 407.44 moveto +376.67 382.93 419.87 352.07 420 352 curveto +432.46 345.09 445.96 338.54 459.43 332.52 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 338.91 403.46 moveto +329.76 416.45 lineto +345.02 412 lineto +closepath stroke +grestore +% Advice->Pointcut +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 263.82 403.69 moveto +245.97 385.17 226.45 360.53 217 334 curveto +201.73 291.13 209.99 238.26 218.72 203.64 curveto +stroke +0 0 0 edgecolor +newpath 263.92 403.79 moveto +270.99 405.21 lineto +272.4 412.28 lineto +265.33 410.86 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 263.92 403.79 moveto +270.99 405.21 lineto +272.4 412.28 lineto +265.33 410.86 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +217 293.9 moveto 48 (pointcut) alignedtext +grestore +% Order +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 274 270 moveto +274 324 lineto +328 324 lineto +328 270 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +283 307.4 moveto 36 (Order) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 274 297 moveto +328 297 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +299 280.4 moveto 4 ( ) alignedtext +grestore +% Advice->Order +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 301 394.41 moveto +301 371.61 301 344.19 301 324.26 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 295.75 394.67 moveto +301 409.67 lineto +306.25 394.67 lineto +closepath stroke +grestore +% Order->Pointcut +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 272.13 259.76 moveto +268.16 253.96 264.32 247.92 261 242 curveto +254.26 229.95 248.13 216.14 243.14 203.67 curveto +stroke +0 0 0 edgecolor +newpath 272.36 260.09 moveto +279.1 262.67 lineto +279.32 269.87 lineto +272.58 267.3 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 272.36 260.09 moveto +279.1 262.67 lineto +279.32 269.87 lineto +272.58 267.3 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +261 228.9 moveto 81 (aspect_exprs) alignedtext +0 0 0 edgecolor +14 /Helvetica set_font +237.96 207.39 moveto 25 (0..N) alignedtext +grestore +% Aspect->Introduction +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 589.22 403.8 moveto +615.35 380.27 646.7 350.12 655 334 curveto +678.25 288.82 682.41 228.44 682.66 194.03 curveto +stroke +0 0 0 edgecolor +newpath 589.19 403.82 moveto +587.38 410.8 lineto +580.24 411.81 lineto +582.05 404.83 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 589.19 403.82 moveto +587.38 410.8 lineto +580.24 411.81 lineto +582.05 404.83 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +677 293.9 moveto 34 (intros) alignedtext +0 0 0 edgecolor +14 /Helvetica set_font +674.21 200.07 moveto 25 (0..N) alignedtext +grestore +% Aspect->AdviceCode +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 551.56 397.48 moveto +551.85 377.4 552.2 353.17 552.48 333.53 curveto +stroke +0 0 0 edgecolor +newpath 551.56 397.68 moveto +555.48 403.73 lineto +551.39 409.67 lineto +547.48 403.62 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 551.56 397.68 moveto +555.48 403.73 lineto +551.39 409.67 lineto +547.48 403.62 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +552 358.9 moveto 46 (advices) alignedtext +0 0 0 edgecolor +14 /Helvetica set_font +544.07 339.56 moveto 25 (0..N) alignedtext +grestore +% Aspect->Order +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 511.17 414.7 moveto +459.91 385.99 372.23 336.89 328.08 312.16 curveto +stroke +0 0 0 edgecolor +newpath 511.36 414.8 moveto +518.55 414.24 lineto +521.83 420.67 lineto +514.64 421.22 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 511.36 414.8 moveto +518.55 414.24 lineto +521.83 420.67 lineto +514.64 421.22 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +433 358.9 moveto 39 (orders) alignedtext +0 0 0 edgecolor +14 /Helvetica set_font +325.55 309.81 moveto 25 (0..N) alignedtext +grestore +% Model +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 185.5 858 moveto +185.5 912 lineto +286.5 912 lineto +286.5 858 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +217 895.4 moveto 38 (Model) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 185.5 885 moveto +286.5 885 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +193.5 868.4 moveto 85 (version: string) alignedtext +grestore +% Model->File +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 206.67 848.34 moveto +190.46 828.07 170.16 802.7 152.88 781.1 curveto +stroke +0 0 0 edgecolor +newpath 206.77 848.47 moveto +213.64 850.65 lineto +214.27 857.84 lineto +207.4 855.65 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 206.77 848.47 moveto +213.64 850.65 lineto +214.27 857.84 lineto +207.4 855.65 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +183 806.9 moveto 25 (files) alignedtext +0 0 0 edgecolor +14 /Helvetica set_font +149.34 782.44 moveto 25 (0..N) alignedtext +grestore +% Model->Namespace +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 236 845.63 moveto +236 819.37 236 785.52 236 762.21 curveto +stroke +0 0 0 edgecolor +newpath 236 845.84 moveto +240 851.84 lineto +236 857.84 lineto +232 851.84 lineto +closepath fill +1 setlinewidth +solid +0 0 0 edgecolor +newpath 236 845.84 moveto +240 851.84 lineto +236 857.84 lineto +232 851.84 lineto +closepath stroke +0 0 0 edgecolor +14 /Helvetica set_font +236 806.9 moveto 24 (root) alignedtext +grestore +endpage +showpage +grestore +%%PageTrailer +%%EndPage: 1 +%%Trailer +end +restore +%%EOF diff --git a/AspectC++/doc/images/acmodel.pdf b/AspectC++/doc/images/acmodel.pdf new file mode 100644 index 0000000..a18760f Binary files /dev/null and b/AspectC++/doc/images/acmodel.pdf differ diff --git a/AspectC++/doc/images/acmodel_inheri_only_less.dot b/AspectC++/doc/images/acmodel_inheri_only_less.dot new file mode 100644 index 0000000..b589fa2 --- /dev/null +++ b/AspectC++/doc/images/acmodel_inheri_only_less.dot @@ -0,0 +1,53 @@ +digraph ACModel { + node [fontname = "Helvetica"]; + edge [fontname = "Helvetica"]; + + + Any [shape=record label="{Any|jpid: int\n}"] + + + Name [shape=record label="{Name|name: string\nbuiltin: bool\n}"] + Any -> Name [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Namespace [shape=record label="{Namespace|}"] + Name -> Namespace [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Function [shape=record label="{Function|kind: FunctionType\nvariadic_args: bool\ncv_qualifiers: CVQualifiers\n}"] + Name -> Function [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Variable [shape=record label="{Variable|kind: VariableType\n}"] + Name -> Variable [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Class [shape=record label="{Class|}"] + Name -> Class [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + ClassSlice [shape=record label="{ClassSlice|is_struct: bool\n}"] + Name -> ClassSlice [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Code [shape=record label="{Code|}"] + Any -> Code [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Access [shape=record label="{Access|lid: int\ntarget_object_lid: int\ncfg_block_lid: int\n}"] + Code -> Access [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Get [shape=record label="{Get|}"] + Access -> Get [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Set [shape=record label="{Set|}"] + Access -> Set [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Call [shape=record label="{Call|default_args: int\n}"] + Access -> Call [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Builtin [shape=record label="{Builtin|}"] + Access -> Builtin [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Ref [shape=record label="{Ref|}"] + Access -> Ref [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + GetRef [shape=record label="{GetRef|kind: VariableType\n}"] + Access -> GetRef [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + SetRef [shape=record label="{SetRef|kind: VariableType\n}"] + Access -> SetRef [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + CallRef [shape=record label="{CallRef|kind: VariableType\n}"] + Access -> CallRef [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Execution [shape=record label="{Execution|}"] + Code -> Execution [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Construction [shape=record label="{Construction|}"] + Code -> Construction [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + Destruction [shape=record label="{Destruction|}"] + Code -> Destruction [dir=back arrowsize=1.5 arrowtail=empty weight=1.0]; + + + + { rank=same Name Code } + { rank=min Any } + +} diff --git a/AspectC++/doc/images/acmodel_inheri_only_less.eps b/AspectC++/doc/images/acmodel_inheri_only_less.eps new file mode 100644 index 0000000..5e2d5ea --- /dev/null +++ b/AspectC++/doc/images/acmodel_inheri_only_less.eps @@ -0,0 +1,921 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Creator: graphviz version 2.26.3 (20100126.1600) +%%Title: ACModel +%%Pages: 1 +%%BoundingBox: 36 36 1249 432 +%%EndComments +save +%%BeginProlog +/DotDict 200 dict def +DotDict begin + +/setupLatin1 { +mark +/EncodingVector 256 array def + EncodingVector 0 + +ISOLatin1Encoding 0 255 getinterval putinterval +EncodingVector 45 /hyphen put + +% Set up ISO Latin 1 character encoding +/starnetISO { + dup dup findfont dup length dict begin + { 1 index /FID ne { def }{ pop pop } ifelse + } forall + /Encoding EncodingVector def + currentdict end definefont +} def +/Times-Roman starnetISO def +/Times-Italic starnetISO def +/Times-Bold starnetISO def +/Times-BoldItalic starnetISO def +/Helvetica starnetISO def +/Helvetica-Oblique starnetISO def +/Helvetica-Bold starnetISO def +/Helvetica-BoldOblique starnetISO def +/Courier starnetISO def +/Courier-Oblique starnetISO def +/Courier-Bold starnetISO def +/Courier-BoldOblique starnetISO def +cleartomark +} bind def + +%%BeginResource: procset graphviz 0 0 +/coord-font-family /Times-Roman def +/default-font-family /Times-Roman def +/coordfont coord-font-family findfont 8 scalefont def + +/InvScaleFactor 1.0 def +/set_scale { + dup 1 exch div /InvScaleFactor exch def + scale +} bind def + +% styles +/solid { [] 0 setdash } bind def +/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def +/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def +/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def +/bold { 2 setlinewidth } bind def +/filled { } bind def +/unfilled { } bind def +/rounded { } bind def +/diagonals { } bind def + +% hooks for setting color +/nodecolor { sethsbcolor } bind def +/edgecolor { sethsbcolor } bind def +/graphcolor { sethsbcolor } bind def +/nopcolor {pop pop pop} bind def + +/beginpage { % i j npages + /npages exch def + /j exch def + /i exch def + /str 10 string def + npages 1 gt { + gsave + coordfont setfont + 0 0 moveto + (\() show i str cvs show (,) show j str cvs show (\)) show + grestore + } if +} bind def + +/set_font { + findfont exch + scalefont setfont +} def + +% draw text fitted to its expected width +/alignedtext { % width text + /text exch def + /width exch def + gsave + width 0 gt { + [] 0 setdash + text stringwidth pop width exch sub text length div 0 text ashow + } if + grestore +} def + +/boxprim { % xcorner ycorner xsize ysize + 4 2 roll + moveto + 2 copy + exch 0 rlineto + 0 exch rlineto + pop neg 0 rlineto + closepath +} bind def + +/ellipse_path { + /ry exch def + /rx exch def + /y exch def + /x exch def + matrix currentmatrix + newpath + x y translate + rx ry scale + 0 0 1 0 360 arc + setmatrix +} bind def + +/endpage { showpage } bind def +/showpage { } def + +/layercolorseq + [ % layer color sequence - darkest to lightest + [0 0 0] + [.2 .8 .8] + [.4 .8 .8] + [.6 .8 .8] + [.8 .8 .8] + ] +def + +/layerlen layercolorseq length def + +/setlayer {/maxlayer exch def /curlayer exch def + layercolorseq curlayer 1 sub layerlen mod get + aload pop sethsbcolor + /nodecolor {nopcolor} def + /edgecolor {nopcolor} def + /graphcolor {nopcolor} def +} bind def + +/onlayer { curlayer ne {invis} if } def + +/onlayers { + /myupper exch def + /mylower exch def + curlayer mylower lt + curlayer myupper gt + or + {invis} if +} def + +/curlayer 0 def + +%%EndResource +%%EndProlog +%%BeginSetup +14 default-font-family set_font +1 setmiterlimit +% /arrowlength 10 def +% /arrowwidth 5 def + +% make sure pdfmark is harmless for PS-interpreters other than Distiller +/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse +% make '<<' and '>>' safe on PS Level 1 devices +/languagelevel where {pop languagelevel}{1} ifelse +2 lt { + userdict (<<) cvn ([) cvn load put + userdict (>>) cvn ([) cvn load put +} if + +%%EndSetup +setupLatin1 +%%Page: 1 1 +%%PageBoundingBox: 36 36 1249 432 +%%PageOrientation: Portrait +0 0 1 beginpage +gsave +36 36 1213 396 boxprim clip newpath +1 1 set_scale 0 rotate 40 41 translate +% Any +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 620.5 333 moveto +620.5 387 lineto +679.5 387 lineto +679.5 333 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +638 370.4 moveto 24 (Any) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 620.5 360 moveto +679.5 360 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +628.5 343.4 moveto 43 (jpid: int) alignedtext +grestore +% Name +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 372 222.5 moveto +372 295.5 lineto +464 295.5 lineto +464 222.5 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +399.5 278.9 moveto 37 (Name) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 372 268.5 moveto +464 268.5 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +380 251.9 moveto 76 (name: string) alignedtext +0 0 0 nodecolor +14 /Helvetica set_font +383.5 232.9 moveto 69 (builtin: bool) alignedtext +grestore +% Any->Name +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 606.15 340.91 moveto +565.56 323.24 505.44 297.07 464.14 279.09 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 604.3 345.83 moveto +620.15 347 lineto +608.49 336.2 lineto +closepath stroke +grestore +% Code +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 801 232 moveto +801 286 lineto +855 286 lineto +855 232 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +811.5 269.4 moveto 33 (Code) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 801 259 moveto +855 259 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +826 242.4 moveto 4 ( ) alignedtext +grestore +% Any->Code +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 692.89 335.66 moveto +726.43 316.63 772.03 290.76 800.74 274.47 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 690.25 331.13 moveto +679.79 343.09 lineto +695.43 340.26 lineto +closepath stroke +grestore +% Namespace +gsave +1 setlinewidth +0 0 0 nodecolor +newpath -.5 112 moveto +-.5 166 lineto +88.5 166 lineto +88.5 112 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +7.5 149.4 moveto 73 (Namespace) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath -.5 139 moveto +88.5 139 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +42 122.4 moveto 4 ( ) alignedtext +grestore +% Name->Namespace +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 356.69 254.19 moveto +289.71 246.91 180.77 229.03 97 186 curveto +87.05 180.89 77.47 173.47 69.26 166.03 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 356.51 259.45 moveto +371.96 255.74 lineto +357.57 249 lineto +closepath stroke +grestore +% Function +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 106 93 moveto +106 185 lineto +282 185 lineto +282 93 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +168 168.4 moveto 52 (Function) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 106 158 moveto +282 158 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +136.5 141.4 moveto 115 (kind: FunctionType) alignedtext +0 0 0 nodecolor +14 /Helvetica set_font +137 122.4 moveto 114 (variadic_args: bool) alignedtext +0 0 0 nodecolor +14 /Helvetica set_font +114 103.4 moveto 160 (cv_qualifiers: CVQualifiers) alignedtext +grestore +% Name->Function +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 358.58 227.17 moveto +334.48 214.26 306.19 199.1 279.93 185.03 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 356.16 231.83 moveto +371.86 234.28 lineto +361.12 222.57 lineto +closepath stroke +grestore +% Variable +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 300 112 moveto +300 166 lineto +428 166 lineto +428 112 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +339 149.4 moveto 50 (Variable) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 300 139 moveto +428 139 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +308 122.4 moveto 112 (kind: VariableType) alignedtext +grestore +% Name->Variable +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 395.19 208.3 moveto +388.7 193.89 381.88 178.74 376.28 166.29 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 390.56 210.82 moveto +401.5 222.34 lineto +400.14 206.51 lineto +closepath stroke +grestore +% Class +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 446 112 moveto +446 166 lineto +500 166 lineto +500 112 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +456 149.4 moveto 34 (Class) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 446 139 moveto +500 139 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +471 122.4 moveto 4 ( ) alignedtext +grestore +% Name->Class +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 441.24 208.3 moveto +447.84 193.89 454.79 178.74 460.49 166.29 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 436.28 206.52 moveto +434.8 222.34 lineto +445.82 210.9 lineto +closepath stroke +grestore +% ClassSlice +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 518 112 moveto +518 166 lineto +618 166 lineto +618 112 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +536 149.4 moveto 64 (ClassSlice) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 518 139 moveto +618 139 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +526 122.4 moveto 84 (is_struct: bool) alignedtext +grestore +% Name->ClassSlice +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 475.78 212.78 moveto +495.41 197.07 516.71 180.03 533.89 166.29 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 472.25 208.87 moveto +463.82 222.34 lineto +478.81 217.07 lineto +closepath stroke +grestore +% Access +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 635.5 93 moveto +635.5 185 lineto +772.5 185 lineto +772.5 93 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +682 168.4 moveto 44 (Access) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 635.5 158 moveto +772.5 158 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +686 141.4 moveto 36 (lid: int) alignedtext +0 0 0 nodecolor +14 /Helvetica set_font +643.5 122.4 moveto 121 (target_object_lid: int) alignedtext +0 0 0 nodecolor +14 /Helvetica set_font +654 103.4 moveto 100 (cfg_block_lid: int) alignedtext +grestore +% Code->Access +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 789.75 221.98 moveto +777.7 210.33 764.25 197.31 751.64 185.1 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 786.36 226.01 moveto +800.79 232.67 lineto +793.66 218.46 lineto +closepath stroke +grestore +% Execution +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 790 112 moveto +790 166 lineto +866 166 lineto +866 112 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +798 149.4 moveto 60 (Execution) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 790 139 moveto +866 139 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +826 122.4 moveto 4 ( ) alignedtext +grestore +% Code->Execution +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 828 216.76 moveto +828 199.94 828 181.06 828 166.12 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 822.75 216.77 moveto +828 231.77 lineto +833.25 216.77 lineto +closepath stroke +grestore +% Construction +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 884 112 moveto +884 166 lineto +976 166 lineto +976 112 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +892 149.4 moveto 76 (Construction) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 884 139 moveto +976 139 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +928 122.4 moveto 4 ( ) alignedtext +grestore +% Code->Construction +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 861.07 220.1 moveto +876.05 202.47 893.4 182.06 906.95 166.12 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 856.86 216.94 moveto +851.15 231.77 lineto +864.86 223.74 lineto +closepath stroke +grestore +% Destruction +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 993.5 112 moveto +993.5 166 lineto +1078.5 166 lineto +1078.5 112 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +1001.5 149.4 moveto 69 (Destruction) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 993.5 139 moveto +1078.5 139 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +1034 122.4 moveto 4 ( ) alignedtext +grestore +% Code->Destruction +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 869.19 243.93 moveto +901.97 231 948.28 210.58 985 186 curveto +993.6 180.24 1002.18 173.05 1009.78 166.03 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 867.27 239.05 moveto +855.16 249.34 lineto +871.04 248.84 lineto +closepath stroke +grestore +% Get +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 367 1 moveto +367 55 lineto +421 55 lineto +421 1 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +382.5 38.4 moveto 23 (Get) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 367 28 moveto +421 28 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +392 11.4 moveto 4 ( ) alignedtext +grestore +% Access->Get +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 621.1 90.36 moveto +540.2 63.53 506.87 90.41 430 56 curveto +426.96 54.64 423.96 52.97 421.05 51.14 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 619.47 95.35 moveto +635.36 95.46 lineto +623.01 85.46 lineto +closepath stroke +grestore +% Set +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 439 1 moveto +439 55 lineto +493 55 lineto +493 1 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +455.5 38.4 moveto 21 (Set) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 439 28 moveto +493 28 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +464 11.4 moveto 4 ( ) alignedtext +grestore +% Access->Set +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 621.27 90.05 moveto +570.59 70.64 549.4 80.12 502 56 curveto +499.04 54.49 496.08 52.72 493.2 50.82 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 619.35 94.94 moveto +635.21 95.82 lineto +623.36 85.23 lineto +closepath stroke +grestore +% Call +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 510.5 1 moveto +510.5 55 lineto +623.5 55 lineto +623.5 1 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +555 38.4 moveto 24 (Call) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 510.5 28 moveto +623.5 28 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +518.5 11.4 moveto 97 (default_args: int) alignedtext +grestore +% Access->Call +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 635.08 83.16 moveto +623.01 73.38 610.96 63.62 600.43 55.09 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 632.13 87.53 moveto +647.09 92.89 lineto +638.74 79.37 lineto +closepath stroke +grestore +% Builtin +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 641 1 moveto +641 55 lineto +695 55 lineto +695 1 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +649.5 38.4 moveto 37 (Builtin) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 641 28 moveto +695 28 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +666 11.4 moveto 4 ( ) alignedtext +grestore +% Access->Builtin +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 684.4 78.58 moveto +681.74 70.36 679.12 62.29 676.79 55.09 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 679.42 80.24 moveto +689.05 92.89 lineto +689.41 77 lineto +closepath stroke +grestore +% Ref +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 713 1 moveto +713 55 lineto +767 55 lineto +767 1 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +729 38.4 moveto 22 (Ref) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 713 28 moveto +767 28 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +738 11.4 moveto 4 ( ) alignedtext +grestore +% Access->Ref +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 723.6 78.58 moveto +726.26 70.36 728.88 62.29 731.21 55.09 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 718.59 77 moveto +718.95 92.89 lineto +728.58 80.24 lineto +closepath stroke +grestore +% GetRef +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 785 1 moveto +785 55 lineto +913 55 lineto +913 1 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +827 38.4 moveto 44 (GetRef) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 785 28 moveto +913 28 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +793 11.4 moveto 112 (kind: VariableType) alignedtext +grestore +% Access->GetRef +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 776.15 83.77 moveto +789.19 73.79 802.24 63.8 813.62 55.09 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 772.95 79.6 moveto +764.23 92.89 lineto +779.34 87.94 lineto +closepath stroke +grestore +% SetRef +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 931 1 moveto +931 55 lineto +1059 55 lineto +1059 1 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +974 38.4 moveto 42 (SetRef) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 931 28 moveto +1059 28 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +939 11.4 moveto 112 (kind: VariableType) alignedtext +grestore +% Access->SetRef +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 786.73 90.02 moveto +843.67 67.99 864.82 74.2 922 56 curveto +924.85 55.09 927.74 54.14 930.66 53.15 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 784.66 85.2 moveto +772.74 95.71 lineto +788.61 94.93 lineto +closepath stroke +grestore +% CallRef +gsave +1 setlinewidth +0 0 0 nodecolor +newpath 1077 1 moveto +1077 55 lineto +1205 55 lineto +1205 1 lineto +closepath stroke +0 0 0 nodecolor +14 /Helvetica set_font +1118.5 38.4 moveto 45 (CallRef) alignedtext +1 setlinewidth +0 0 0 nodecolor +newpath 1077 28 moveto +1205 28 lineto +stroke +0 0 0 nodecolor +14 /Helvetica set_font +1085 11.4 moveto 112 (kind: VariableType) alignedtext +grestore +% Access->CallRef +gsave +1 setlinewidth +0 0 0 edgecolor +newpath 787.02 90.4 moveto +905.59 52.33 948.05 86.06 1068 56 curveto +1070.9 55.27 1073.83 54.47 1076.79 53.6 curveto +stroke +1 setlinewidth +solid +0 0 0 edgecolor +newpath 785.11 85.5 moveto +772.57 95.26 lineto +788.46 95.45 lineto +closepath stroke +grestore +endpage +showpage +grestore +%%PageTrailer +%%EndPage: 1 +%%Trailer +end +restore +%%EOF diff --git a/AspectC++/doc/images/acmodel_inheri_only_less.pdf b/AspectC++/doc/images/acmodel_inheri_only_less.pdf new file mode 100644 index 0000000..7481fa5 Binary files /dev/null and b/AspectC++/doc/images/acmodel_inheri_only_less.pdf differ diff --git a/AspectC++/doc/images/include_cycle.eps b/AspectC++/doc/images/include_cycle.eps new file mode 100644 index 0000000..e3e68ad --- /dev/null +++ b/AspectC++/doc/images/include_cycle.eps @@ -0,0 +1,4966 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 501 556 +%%Pages: 0 +%%Creator: Sun Microsystems, Inc. +%%Title: none +%%CreationDate: none +%%LanguageLevel: 2 +%%EndComments +%%BeginProlog +%%BeginResource: SDRes +/b4_inc_state save def +/dict_count countdictstack def +/op_count count 1 sub def +userdict begin +0 setgray 0 setlinecap 1 setlinewidth 0 setlinejoin 10 setmiterlimit[] 0 setdash newpath +/languagelevel where {pop languagelevel 1 ne {false setstrokeadjust false setoverprint} if} if +/bdef {bind def} bind def +/c {setrgbcolor} bdef +/l {neg lineto} bdef +/rl {neg rlineto} bdef +/lc {setlinecap} bdef +/lj {setlinejoin} bdef +/lw {setlinewidth} bdef +/ml {setmiterlimit} bdef +/ld {setdash} bdef +/m {neg moveto} bdef +/ct {6 2 roll neg 6 2 roll neg 6 2 roll neg curveto} bdef +/r {rotate} bdef +/t {neg translate} bdef +/s {scale} bdef +/sw {show} bdef +/gs {gsave} bdef +/gr {grestore} bdef +/f {findfont dup length dict begin +{1 index /FID ne {def} {pop pop} ifelse} forall /Encoding ISOLatin1Encoding def +currentdict end /NFont exch definefont pop /NFont findfont} bdef +/p {closepath} bdef +/sf {scalefont setfont} bdef +/ef {eofill}bdef +/pc {closepath stroke}bdef +/ps {stroke}bdef +/pum {matrix currentmatrix}bdef +/pom {setmatrix}bdef +/bs {/aString exch def /nXOfs exch def /nWidth exch def currentpoint nXOfs 0 rmoveto pum nWidth aString stringwidth pop div 1 scale aString show pom moveto} bdef +%%EndResource +%%EndProlog +%%BeginSetup +%%EndSetup +%%Page: 1 1 +%%BeginPageSetup +%%EndPageSetup +pum +0.02833 0.02834 s +0 -19616 t +/tm matrix currentmatrix def +tm setmatrix +-1810 -1222 t +1 1 s +0.503 0.503 0.503 c 5575 5508 m 2665 5508 l 2665 1356 l 8485 1356 l +8485 5508 l 5575 5508 l p ef +50 lw 1 lj 5575 5508 m 2665 5508 l 2665 1356 l 8485 1356 l 8485 5508 l +5575 5508 l pc +1.000 0.902 0.777 c 5475 5408 m 2565 5408 l 2565 1256 l 8385 1256 l +8385 5408 l 5475 5408 l p ef +0.003 0.003 0.003 c 5475 5408 m 2565 5408 l 2565 1256 l 8385 1256 l 8385 5408 l +5475 5408 l pc +gs +gs +pum +3054 1889 t +0.003 0.003 1.000 c 227 -4 m 202 2 177 5 152 5 ct 111 5 78 -5 55 -26 ct 32 -47 20 -75 20 -111 ct +20 -148 31 -177 54 -198 ct 76 -219 108 -229 148 -229 ct 178 -229 204 -226 227 -220 ct +227 -220 227 -220 227 -175 ct 202 -184 179 -188 156 -188 ct 134 -188 117 -182 105 -169 ct +92 -157 86 -140 86 -118 ct 86 -94 94 -74 109 -60 ct 124 -45 144 -38 169 -38 ct +188 -38 208 -42 227 -49 ct 227 -49 227 -49 227 -4 ct p ef +356 0 m 356 -285 l 274 -285 l 274 -326 l 417 -326 l 417 0 l 356 0 l +p ef +661 -24 m 654 -14 645 -7 635 -2 ct 625 3 614 5 601 5 ct 579 5 561 -2 547 -15 ct +533 -28 526 -45 526 -65 ct 526 -91 536 -111 555 -124 ct 575 -137 604 -143 643 -143 ct +643 -143 643 -143 667 -143 ct 667 -143 667 -143 667 -154 ct 667 -165 663 -174 655 -179 ct +647 -185 635 -188 619 -188 ct 597 -188 572 -182 545 -169 ct 545 -169 545 -169 545 -214 ct +573 -224 601 -229 630 -229 ct 662 -229 686 -223 702 -211 ct 712 -203 719 -194 723 -185 ct +726 -175 728 -160 728 -140 ct 728 -140 728 -140 728 -64 ct 728 -49 733 -41 742 -41 ct +744 -41 746 -41 749 -42 ct 749 -42 749 -42 749 -2 ct 737 3 725 5 715 5 ct 704 5 694 3 686 -2 ct +678 -7 672 -14 667 -24 ct 667 -24 667 -24 661 -24 ct p +667 -65 m 667 -65 667 -65 667 -102 ct 667 -102 667 -102 645 -102 ct 626 -102 611 -99 602 -94 ct +592 -88 587 -80 587 -69 ct 587 -61 590 -54 596 -49 ct 602 -44 609 -41 618 -41 ct +633 -41 650 -49 667 -65 ct p ef +795 -8 m 795 -8 795 -8 795 -54 ct 829 -42 857 -36 877 -36 ct 892 -36 903 -38 911 -42 ct +918 -46 922 -52 922 -60 ct 922 -64 920 -68 916 -72 ct 913 -75 907 -79 900 -82 ct +900 -82 900 -82 852 -101 ct 833 -109 819 -118 810 -127 ct 801 -137 796 -148 796 -161 ct +796 -182 806 -199 825 -211 ct 844 -223 871 -229 905 -229 ct 925 -229 948 -226 974 -221 ct +974 -221 974 -221 974 -174 ct 946 -183 922 -188 903 -188 ct 888 -188 878 -186 871 -183 ct +864 -180 860 -175 860 -169 ct 860 -165 863 -162 868 -158 ct 873 -154 880 -150 890 -146 ct +890 -146 890 -146 943 -124 ct 959 -118 971 -110 978 -100 ct 986 -91 990 -79 990 -66 ct +990 -45 981 -28 962 -15 ct 943 -2 919 5 889 5 ct 863 5 831 1 795 -8 ct p ef +1049 -8 m 1049 -8 1049 -8 1049 -54 ct 1083 -42 1111 -36 1131 -36 ct 1146 -36 1157 -38 1165 -42 ct +1172 -46 1176 -52 1176 -60 ct 1176 -64 1174 -68 1170 -72 ct 1167 -75 1161 -79 1154 -82 ct +1154 -82 1154 -82 1106 -101 ct 1087 -109 1073 -118 1064 -127 ct 1055 -137 1050 -148 1050 -161 ct +1050 -182 1060 -199 1079 -211 ct 1098 -223 1125 -229 1159 -229 ct 1179 -229 1202 -226 1228 -221 ct +1228 -221 1228 -221 1228 -174 ct 1200 -183 1176 -188 1157 -188 ct 1142 -188 1132 -186 1125 -183 ct +1118 -180 1114 -175 1114 -169 ct 1114 -165 1117 -162 1122 -158 ct 1127 -154 1134 -150 1144 -146 ct +1144 -146 1144 -146 1197 -124 ct 1213 -118 1225 -110 1232 -100 ct 1240 -91 1244 -79 1244 -66 ct +1244 -45 1235 -28 1216 -15 ct 1197 -2 1173 5 1143 5 ct 1117 5 1085 1 1049 -8 ct +p ef +pom +gr +gs +pum +4324 1889 t +361 0 m 361 -275 l 259 -275 l 259 -306 l 504 -306 l 504 -275 l 402 -275 l +402 0 l 361 0 l p ef +680 -26 m 656 -5 631 5 607 5 ct 586 5 569 -1 556 -13 ct 543 -24 536 -39 536 -57 ct +536 -81 546 -99 567 -114 ct 588 -128 615 -135 649 -135 ct 649 -135 649 -135 674 -135 ct +674 -135 674 -135 674 -154 ct 674 -169 670 -180 663 -187 ct 655 -194 644 -198 629 -198 ct +605 -198 580 -191 555 -177 ct 555 -177 555 -177 555 -213 ct 584 -224 611 -229 637 -229 ct +666 -229 686 -223 697 -212 ct 709 -201 715 -181 715 -153 ct 715 -153 715 -153 715 -59 ct +715 -45 716 -36 719 -31 ct 722 -26 728 -24 735 -24 ct 738 -24 742 -25 748 -26 ct +748 -26 748 -26 752 -2 ct 738 3 728 5 721 5 ct 711 5 702 2 696 -3 ct 689 -8 684 -16 680 -26 ct +p +674 -53 m 674 -53 674 -53 674 -110 ct 674 -110 674 -110 662 -110 ct 634 -110 613 -106 599 -99 ct +585 -91 578 -80 578 -64 ct 578 -52 581 -43 588 -37 ct 594 -31 604 -28 617 -28 ct +635 -28 654 -36 674 -53 ct p ef +826 0 m 826 0 826 0 826 -224 ct 826 -224 826 -224 867 -224 ct 867 -224 867 -224 865 -182 ct +865 -182 865 -182 867 -182 ct 877 -198 889 -209 903 -217 ct 917 -225 932 -229 950 -229 ct +962 -229 976 -227 991 -224 ct 991 -224 991 -224 991 -160 ct 991 -160 991 -160 960 -160 ct +960 -160 960 -160 960 -191 ct 954 -192 948 -193 943 -193 ct 929 -193 916 -189 904 -181 ct +891 -173 879 -161 867 -145 ct 867 -145 867 -145 867 0 ct 867 0 867 0 826 0 ct p ef +1059 75 m 1059 75 1059 75 1063 41 ct 1088 51 1111 56 1132 56 ct 1154 56 1170 51 1179 42 ct +1189 33 1195 17 1198 -6 ct 1198 -6 1198 -6 1202 -46 ct 1202 -46 1202 -46 1198 -46 ct +1190 -31 1179 -19 1167 -12 ct 1154 -4 1140 0 1124 0 ct 1099 0 1079 -10 1064 -29 ct +1049 -49 1041 -75 1041 -108 ct 1041 -144 1050 -173 1067 -195 ct 1085 -218 1107 -229 1135 -229 ct +1157 -229 1179 -219 1200 -198 ct 1200 -198 1200 -198 1203 -198 ct 1203 -198 1203 -198 1203 -224 ct +1203 -224 1203 -224 1239 -224 ct 1239 -224 1239 -224 1239 -45 ct 1239 -15 1237 6 1233 21 ct +1229 36 1222 49 1211 60 ct 1194 78 1168 87 1131 87 ct 1110 87 1086 83 1059 75 ct +p +1198 -80 m 1198 -80 1198 -80 1198 -167 ct 1180 -188 1160 -198 1141 -198 ct +1122 -198 1108 -191 1098 -176 ct 1089 -162 1084 -140 1084 -111 ct 1084 -86 1088 -67 1096 -55 ct +1105 -42 1117 -36 1134 -36 ct 1146 -36 1157 -40 1168 -47 ct 1179 -54 1189 -65 1198 -80 ct +p ef +1496 -9 m 1468 0 1442 5 1418 5 ct 1380 5 1351 -5 1330 -25 ct 1309 -45 1299 -73 1299 -110 ct +1299 -144 1309 -173 1329 -195 ct 1349 -218 1374 -229 1405 -229 ct 1436 -229 1458 -220 1473 -201 ct +1488 -182 1495 -153 1495 -114 ct 1495 -114 1495 -114 1495 -101 ct 1495 -101 1495 -101 1341 -101 ct +1342 -76 1350 -57 1364 -45 ct 1378 -32 1397 -26 1423 -26 ct 1446 -26 1470 -31 1496 -42 ct +1496 -42 1496 -42 1496 -9 ct p +1342 -132 m 1342 -132 1342 -132 1452 -132 ct 1452 -132 1452 -132 1452 -138 ct +1452 -158 1448 -173 1439 -183 ct 1430 -193 1418 -198 1401 -198 ct 1384 -198 1371 -192 1360 -181 ct +1350 -169 1344 -153 1342 -132 ct p ef +1752 0 m 1732 3 1712 5 1693 5 ct 1660 5 1637 -1 1625 -13 ct 1613 -25 1607 -47 1607 -80 ct +1607 -80 1607 -80 1607 -188 ct 1607 -188 1607 -188 1551 -188 ct 1551 -188 1551 -188 1551 -219 ct +1551 -219 1551 -219 1607 -219 ct 1607 -219 1607 -219 1607 -267 ct 1607 -267 1607 -267 1648 -267 ct +1648 -267 1648 -267 1648 -219 ct 1648 -219 1648 -219 1747 -219 ct 1747 -219 1747 -219 1747 -188 ct +1747 -188 1747 -188 1648 -188 ct 1648 -188 1648 -188 1648 -74 ct 1648 -61 1649 -53 1650 -48 ct +1652 -43 1655 -39 1661 -35 ct 1670 -29 1683 -26 1701 -26 ct 1718 -26 1735 -28 1752 -31 ct +1752 -31 1752 -31 1752 0 ct p ef +2244 -326 m 2244 -326 2244 -326 2244 -295 ct 2244 -295 2244 -295 2228 -295 ct +2207 -295 2193 -293 2185 -287 ct 2176 -282 2172 -274 2172 -261 ct 2172 -257 2173 -251 2174 -242 ct +2174 -242 2174 -242 2178 -214 ct 2179 -204 2180 -196 2180 -190 ct 2180 -175 2177 -163 2170 -153 ct +2163 -144 2153 -137 2139 -132 ct 2153 -128 2163 -121 2170 -111 ct 2177 -102 2180 -90 2180 -75 ct +2180 -68 2179 -61 2178 -51 ct 2178 -51 2178 -51 2174 -23 ct 2173 -14 2172 -8 2172 -4 ct +2172 9 2176 17 2185 22 ct 2193 27 2207 30 2228 30 ct 2228 30 2228 30 2244 30 ct +2244 30 2244 30 2244 61 ct 2244 61 2244 61 2221 61 ct 2192 61 2170 56 2156 46 ct +2141 36 2134 21 2134 2 ct 2134 -7 2135 -16 2137 -26 ct 2137 -26 2137 -26 2144 -63 ct +2145 -68 2145 -74 2145 -79 ct 2145 -92 2141 -101 2133 -108 ct 2126 -114 2114 -117 2099 -117 ct +2099 -117 2099 -117 2080 -117 ct 2080 -117 2080 -117 2080 -148 ct 2080 -148 2080 -148 2099 -148 ct +2114 -148 2126 -151 2133 -157 ct 2141 -164 2145 -173 2145 -186 ct 2145 -191 2145 -197 2144 -202 ct +2144 -202 2144 -202 2137 -239 ct 2135 -249 2134 -258 2134 -267 ct 2134 -286 2141 -301 2156 -311 ct +2170 -321 2192 -326 2221 -326 ct 2221 -326 2221 -326 2244 -326 ct p ef +pom +gr +gs +pum +3054 2380 t +0.003 0.003 1.000 c 24 82 m 24 82 24 82 24 -224 ct 24 -224 24 -224 85 -224 ct +85 -224 85 -224 83 -182 ct 83 -182 83 -182 85 -182 ct 95 -197 106 -209 117 -217 ct +129 -225 142 -229 156 -229 ct 182 -229 202 -219 218 -198 ct 233 -178 241 -151 241 -117 ct +241 -80 232 -50 215 -28 ct 198 -6 175 5 146 5 ct 134 5 122 3 112 -2 ct 102 -6 93 -13 85 -22 ct +85 -22 85 -22 83 -22 ct 83 -22 83 -22 85 0 ct 85 0 85 0 85 82 ct 85 82 85 82 24 82 ct +p +85 -64 m 92 -56 99 -50 106 -47 ct 113 -43 121 -41 130 -41 ct 145 -41 156 -47 164 -60 ct +171 -72 175 -91 175 -116 ct 175 -135 172 -149 165 -159 ct 158 -168 149 -173 135 -173 ct +127 -173 118 -170 109 -164 ct 101 -158 93 -149 85 -136 ct 85 -136 85 -136 85 -64 ct +p ef +480 -224 m 480 -224 480 -224 480 0 ct 480 0 480 0 419 0 ct 419 0 419 0 420 -22 ct +420 -22 420 -22 422 -43 ct 422 -43 422 -43 419 -43 ct 413 -27 404 -15 392 -7 ct +380 1 365 5 348 5 ct 326 5 309 -1 298 -14 ct 287 -27 281 -46 281 -71 ct 281 -71 281 -71 281 -224 ct +281 -224 281 -224 342 -224 ct 342 -224 342 -224 342 -85 ct 342 -73 344 -65 348 -59 ct +353 -54 359 -51 368 -51 ct 377 -51 386 -54 395 -59 ct 403 -65 411 -73 419 -85 ct +419 -85 419 -85 419 -224 ct 419 -224 419 -224 480 -224 ct p ef +533 0 m 533 0 533 0 533 -326 ct 533 -326 533 -326 594 -326 ct 594 -326 594 -326 594 -224 ct +594 -224 594 -224 592 -182 ct 592 -182 592 -182 594 -182 ct 604 -197 615 -209 626 -217 ct +638 -225 651 -229 665 -229 ct 691 -229 711 -219 727 -198 ct 742 -178 750 -151 750 -117 ct +750 -80 741 -50 724 -28 ct 707 -6 684 5 655 5 ct 643 5 631 3 621 -2 ct 611 -6 602 -13 594 -22 ct +594 -22 594 -22 592 -22 ct 592 -22 592 -22 584 0 ct 584 0 584 0 533 0 ct p +594 -64 m 601 -56 608 -50 615 -47 ct 622 -43 630 -41 639 -41 ct 654 -41 665 -47 673 -60 ct +680 -72 684 -91 684 -116 ct 684 -135 681 -149 674 -159 ct 667 -168 658 -173 644 -173 ct +636 -173 627 -170 618 -164 ct 610 -158 602 -149 594 -136 ct 594 -136 594 -136 594 -64 ct +p ef +864 0 m 864 -285 l 782 -285 l 782 -326 l 925 -326 l 925 0 l 864 0 l +p ef +1138 0 m 1138 -183 l 1056 -183 l 1056 -224 l 1199 -224 l 1199 0 l +1138 0 l p +1138 -265 m 1138 -326 l 1199 -326 l 1199 -265 l 1138 -265 l p ef +1497 -4 m 1472 2 1447 5 1422 5 ct 1381 5 1348 -5 1325 -26 ct 1302 -47 1290 -75 1290 -111 ct +1290 -148 1301 -177 1324 -198 ct 1346 -219 1378 -229 1418 -229 ct 1448 -229 1474 -226 1497 -220 ct +1497 -220 1497 -220 1497 -175 ct 1472 -184 1449 -188 1426 -188 ct 1404 -188 1387 -182 1375 -169 ct +1362 -157 1356 -140 1356 -118 ct 1356 -94 1364 -74 1379 -60 ct 1394 -45 1414 -38 1439 -38 ct +1458 -38 1478 -42 1497 -49 ct 1497 -49 1497 -49 1497 -4 ct p ef +pom +gr +gs +pum +4578 2380 t +97 -163 m 97 -224 l 158 -224 l 158 -163 l 97 -163 l p +97 0 m 97 -61 l 158 -61 l 158 0 l 97 0 l p ef +pom +gr +gs +pum +3054 2871 t +pom +gr +gs +pum +3562 2871 t +0.003 0.003 1.000 c 98 0 m 9 -224 l 75 -224 l 137 -67 l 198 -224 l 247 -224 l +159 0 l 98 0 l p ef +380 5 m 346 5 318 -6 297 -27 ct 276 -49 265 -77 265 -112 ct 265 -148 276 -176 297 -197 ct +318 -218 346 -229 382 -229 ct 417 -229 445 -218 466 -197 ct 487 -176 498 -148 498 -112 ct +498 -76 487 -48 466 -27 ct 445 -6 416 5 380 5 ct p +381 -36 m 398 -36 411 -42 419 -55 ct 428 -68 432 -87 432 -112 ct 432 -138 428 -156 419 -169 ct +411 -182 398 -188 382 -188 ct 365 -188 352 -182 344 -169 ct 335 -156 331 -137 331 -112 ct +331 -87 335 -68 343 -55 ct 352 -42 364 -36 381 -36 ct p ef +630 0 m 630 -183 l 548 -183 l 548 -224 l 691 -224 l 691 0 l 630 0 l +p +630 -265 m 630 -326 l 691 -326 l 691 -265 l 630 -265 l p ef +936 0 m 936 0 936 0 938 -42 ct 938 -42 938 -42 936 -42 ct 926 -27 915 -15 903 -7 ct +892 1 879 5 865 5 ct 839 5 819 -5 803 -26 ct 788 -46 780 -73 780 -107 ct 780 -144 789 -174 806 -196 ct +823 -218 846 -229 875 -229 ct 887 -229 898 -227 908 -222 ct 918 -218 927 -211 936 -203 ct +936 -203 936 -203 938 -203 ct 938 -203 938 -203 936 -224 ct 936 -224 936 -224 936 -326 ct +936 -326 936 -326 997 -326 ct 997 -326 997 -326 997 0 ct 997 0 997 0 936 0 ct p +936 -160 m 929 -168 922 -173 915 -177 ct 908 -181 900 -183 892 -183 ct 876 -183 865 -177 857 -164 ct +850 -152 846 -133 846 -108 ct 846 -89 849 -75 856 -65 ct 863 -56 873 -51 886 -51 ct +895 -51 903 -54 912 -60 ct 920 -66 928 -75 936 -88 ct 936 -88 936 -88 936 -160 ct +p ef +pom +gr +gs +pum +4578 2871 t +346 0 m 346 0 346 0 346 -188 ct 346 -188 346 -188 285 -188 ct 285 -188 285 -188 285 -219 ct +285 -219 285 -219 346 -219 ct 346 -219 346 -219 346 -243 ct 346 -274 353 -297 368 -310 ct +382 -324 406 -331 440 -331 ct 462 -331 482 -328 502 -322 ct 502 -322 502 -322 502 -289 ct +482 -296 462 -300 443 -300 ct 422 -300 408 -296 399 -288 ct 391 -280 387 -267 387 -247 ct +387 -247 387 -247 387 -219 ct 387 -219 387 -219 494 -219 ct 494 -219 494 -219 494 -188 ct +494 -188 494 -188 387 -188 ct 387 -188 387 -188 387 0 ct 387 0 387 0 346 0 ct p ef +732 61 m 687 56 651 36 622 -1 ct 593 -37 579 -81 579 -133 ct 579 -184 593 -228 622 -264 ct +651 -301 687 -321 732 -326 ct 732 -326 732 -326 732 -298 ct 696 -291 668 -273 649 -244 ct +630 -216 620 -178 620 -133 ct 620 -87 630 -49 649 -21 ct 668 8 696 26 732 33 ct +732 33 732 33 732 61 ct p ef +793 61 m 838 56 874 36 903 -1 ct 932 -37 946 -81 946 -133 ct 946 -184 932 -228 903 -264 ct +874 -301 838 -321 793 -326 ct 793 -326 793 -326 793 -298 ct 829 -291 857 -273 876 -244 ct +895 -216 905 -178 905 -133 ct 905 -87 895 -49 876 -21 ct 857 8 829 26 793 33 ct +793 33 793 33 793 61 ct p ef +1482 -326 m 1482 -326 1482 -326 1482 -295 ct 1482 -295 1482 -295 1466 -295 ct +1445 -295 1431 -293 1423 -287 ct 1414 -282 1410 -274 1410 -261 ct 1410 -257 1411 -251 1412 -242 ct +1412 -242 1412 -242 1416 -214 ct 1417 -204 1418 -196 1418 -190 ct 1418 -175 1415 -163 1408 -153 ct +1401 -144 1391 -137 1377 -132 ct 1391 -128 1401 -121 1408 -111 ct 1415 -102 1418 -90 1418 -75 ct +1418 -68 1417 -61 1416 -51 ct 1416 -51 1416 -51 1412 -23 ct 1411 -14 1410 -8 1410 -4 ct +1410 9 1414 17 1423 22 ct 1431 27 1445 30 1466 30 ct 1466 30 1466 30 1482 30 ct +1482 30 1482 30 1482 61 ct 1482 61 1482 61 1459 61 ct 1430 61 1408 56 1394 46 ct +1379 36 1372 21 1372 2 ct 1372 -7 1373 -16 1375 -26 ct 1375 -26 1375 -26 1382 -63 ct +1383 -68 1383 -74 1383 -79 ct 1383 -92 1379 -101 1371 -108 ct 1364 -114 1352 -117 1337 -117 ct +1337 -117 1337 -117 1318 -117 ct 1318 -117 1318 -117 1318 -148 ct 1318 -148 1318 -148 1337 -148 ct +1352 -148 1364 -151 1371 -157 ct 1379 -164 1383 -173 1383 -186 ct 1383 -191 1383 -197 1382 -202 ct +1382 -202 1382 -202 1375 -239 ct 1373 -249 1372 -258 1372 -267 ct 1372 -286 1379 -301 1394 -311 ct +1408 -321 1430 -326 1459 -326 ct 1459 -326 1459 -326 1482 -326 ct p ef +pom +gr +gs +pum +3054 3362 t +pom +gr +gs +pum +4070 3362 t +0.003 0.503 0.003 c 239 -326 m 65 61 l 15 61 l 189 -326 l 239 -326 l +p ef +493 -326 m 319 61 l 269 61 l 443 -326 l 493 -326 l p ef +936 0 m 936 0 936 0 938 -42 ct 938 -42 938 -42 936 -42 ct 926 -27 915 -15 903 -7 ct +892 1 879 5 865 5 ct 839 5 819 -5 803 -26 ct 788 -46 780 -73 780 -107 ct 780 -144 789 -174 806 -196 ct +823 -218 846 -229 875 -229 ct 887 -229 898 -227 908 -222 ct 918 -218 927 -211 936 -203 ct +936 -203 936 -203 938 -203 ct 938 -203 938 -203 936 -224 ct 936 -224 936 -224 936 -326 ct +936 -326 936 -326 997 -326 ct 997 -326 997 -326 997 0 ct 997 0 997 0 936 0 ct p +936 -160 m 929 -168 922 -173 915 -177 ct 908 -181 900 -183 892 -183 ct 876 -183 865 -177 857 -164 ct +850 -152 846 -133 846 -108 ct 846 -89 849 -75 856 -65 ct 863 -56 873 -51 886 -51 ct +895 -51 903 -54 912 -60 ct 920 -66 928 -75 936 -88 ct 936 -88 936 -88 936 -160 ct +p ef +1142 5 m 1108 5 1080 -6 1059 -27 ct 1038 -49 1027 -77 1027 -112 ct 1027 -148 1038 -176 1059 -197 ct +1080 -218 1108 -229 1144 -229 ct 1179 -229 1207 -218 1228 -197 ct 1249 -176 1260 -148 1260 -112 ct +1260 -76 1249 -48 1228 -27 ct 1207 -6 1178 5 1142 5 ct p +1143 -36 m 1160 -36 1173 -42 1181 -55 ct 1190 -68 1194 -87 1194 -112 ct 1194 -138 1190 -156 1181 -169 ct +1173 -182 1160 -188 1144 -188 ct 1127 -188 1114 -182 1106 -169 ct 1097 -156 1093 -137 1093 -112 ct +1093 -87 1097 -68 1105 -55 ct 1114 -42 1126 -36 1143 -36 ct p ef +1557 -8 m 1557 -8 1557 -8 1557 -54 ct 1591 -42 1619 -36 1639 -36 ct 1654 -36 1665 -38 1673 -42 ct +1680 -46 1684 -52 1684 -60 ct 1684 -64 1682 -68 1678 -72 ct 1675 -75 1669 -79 1662 -82 ct +1662 -82 1662 -82 1614 -101 ct 1595 -109 1581 -118 1572 -127 ct 1563 -137 1558 -148 1558 -161 ct +1558 -182 1568 -199 1587 -211 ct 1606 -223 1633 -229 1667 -229 ct 1687 -229 1710 -226 1736 -221 ct +1736 -221 1736 -221 1736 -174 ct 1708 -183 1684 -188 1665 -188 ct 1650 -188 1640 -186 1633 -183 ct +1626 -180 1622 -175 1622 -169 ct 1622 -165 1625 -162 1630 -158 ct 1635 -154 1642 -150 1652 -146 ct +1652 -146 1652 -146 1705 -124 ct 1721 -118 1733 -110 1740 -100 ct 1748 -91 1752 -79 1752 -66 ct +1752 -45 1743 -28 1724 -15 ct 1705 -2 1681 5 1651 5 ct 1625 5 1593 1 1557 -8 ct +p ef +1904 5 m 1870 5 1842 -6 1821 -27 ct 1800 -49 1789 -77 1789 -112 ct 1789 -148 1800 -176 1821 -197 ct +1842 -218 1870 -229 1906 -229 ct 1941 -229 1969 -218 1990 -197 ct 2011 -176 2022 -148 2022 -112 ct +2022 -76 2011 -48 1990 -27 ct 1969 -6 1940 5 1904 5 ct p +1905 -36 m 1922 -36 1935 -42 1943 -55 ct 1952 -68 1956 -87 1956 -112 ct 1956 -138 1952 -156 1943 -169 ct +1935 -182 1922 -188 1906 -188 ct 1889 -188 1876 -182 1868 -169 ct 1859 -156 1855 -137 1855 -112 ct +1855 -87 1859 -68 1867 -55 ct 1876 -42 1888 -36 1905 -36 ct p ef +2185 0 m 2185 0 2185 0 2134 0 ct 2134 0 2134 0 2134 -149 ct 2134 -157 2133 -163 2132 -167 ct +2130 -171 2128 -173 2125 -173 ct 2120 -173 2116 -171 2112 -166 ct 2108 -161 2105 -154 2101 -145 ct +2101 -145 2101 -145 2101 0 ct 2101 0 2101 0 2050 0 ct 2050 0 2050 0 2050 -224 ct +2050 -224 2050 -224 2101 -224 ct 2101 -224 2101 -224 2098 -181 ct 2098 -181 2098 -181 2101 -181 ct +2106 -197 2113 -209 2121 -217 ct 2129 -225 2138 -229 2148 -229 ct 2159 -229 2168 -225 2174 -217 ct +2180 -209 2184 -197 2185 -181 ct 2185 -181 2185 -181 2187 -181 ct 2192 -197 2198 -209 2205 -217 ct +2213 -225 2221 -229 2231 -229 ct 2245 -229 2255 -223 2261 -212 ct 2266 -200 2269 -179 2269 -150 ct +2269 -150 2269 -150 2269 0 ct 2269 0 2269 0 2218 0 ct 2218 0 2218 0 2218 -149 ct +2218 -157 2217 -163 2216 -167 ct 2214 -171 2212 -173 2209 -173 ct 2204 -173 2200 -171 2196 -166 ct +2193 -161 2189 -154 2185 -145 ct 2185 -145 2185 -145 2185 0 ct p ef +2522 -95 m 2522 -95 2522 -95 2370 -95 ct 2373 -77 2381 -63 2393 -54 ct 2405 -45 2421 -41 2442 -41 ct +2466 -41 2493 -46 2522 -56 ct 2522 -56 2522 -56 2522 -9 ct 2487 0 2456 5 2430 5 ct +2392 5 2361 -6 2338 -27 ct 2315 -48 2304 -76 2304 -111 ct 2304 -147 2315 -175 2336 -197 ct +2358 -218 2386 -229 2421 -229 ct 2453 -229 2477 -219 2495 -199 ct 2513 -180 2522 -152 2522 -118 ct +2522 -118 2522 -118 2522 -95 ct p +2369 -136 m 2369 -136 2369 -136 2463 -136 ct 2463 -153 2459 -166 2452 -175 ct +2444 -184 2433 -188 2418 -188 ct 2404 -188 2392 -184 2384 -175 ct 2376 -166 2371 -153 2369 -136 ct +p ef +2768 -6 m 2744 1 2722 5 2704 5 ct 2675 5 2654 -1 2640 -14 ct 2626 -26 2619 -45 2619 -70 ct +2619 -70 2619 -70 2619 -178 ct 2619 -178 2619 -178 2571 -178 ct 2571 -178 2571 -178 2571 -219 ct +2571 -219 2571 -219 2619 -219 ct 2619 -219 2619 -219 2619 -285 ct 2619 -285 2619 -285 2680 -285 ct +2680 -285 2680 -285 2680 -219 ct 2680 -219 2680 -219 2763 -219 ct 2763 -219 2763 -219 2763 -178 ct +2763 -178 2763 -178 2680 -178 ct 2680 -178 2680 -178 2680 -84 ct 2680 -68 2683 -57 2689 -51 ct +2695 -44 2705 -41 2719 -41 ct 2736 -41 2752 -44 2768 -51 ct 2768 -51 2768 -51 2768 -6 ct +p ef +2823 0 m 2823 0 2823 0 2823 -326 ct 2823 -326 2823 -326 2884 -326 ct 2884 -326 2884 -326 2884 -224 ct +2884 -224 2884 -224 2882 -181 ct 2882 -181 2882 -181 2884 -181 ct 2891 -197 2900 -209 2912 -217 ct +2924 -225 2938 -229 2956 -229 ct 2978 -229 2994 -223 3005 -210 ct 3016 -197 3022 -178 3022 -153 ct +3022 -153 3022 -153 3022 0 ct 3022 0 3022 0 2961 0 ct 2961 0 2961 0 2961 -139 ct +2961 -150 2959 -159 2955 -165 ct 2950 -170 2944 -173 2935 -173 ct 2926 -173 2917 -170 2908 -165 ct +2900 -159 2891 -151 2884 -139 ct 2884 -139 2884 -139 2884 0 ct 2884 0 2884 0 2823 0 ct +p ef +3170 0 m 3170 -183 l 3088 -183 l 3088 -224 l 3231 -224 l 3231 0 l +3170 0 l p +3170 -265 m 3170 -326 l 3231 -326 l 3231 -265 l 3170 -265 l p ef +3331 0 m 3331 0 3331 0 3331 -224 ct 3331 -224 3331 -224 3392 -224 ct 3392 -224 3392 -224 3391 -202 ct +3391 -202 3391 -202 3390 -181 ct 3390 -181 3390 -181 3392 -181 ct 3399 -197 3408 -209 3420 -217 ct +3432 -225 3446 -229 3464 -229 ct 3486 -229 3502 -223 3513 -210 ct 3524 -197 3530 -178 3530 -153 ct +3530 -153 3530 -153 3530 0 ct 3530 0 3530 0 3469 0 ct 3469 0 3469 0 3469 -139 ct +3469 -150 3467 -159 3463 -165 ct 3458 -170 3452 -173 3443 -173 ct 3434 -173 3425 -170 3416 -165 ct +3408 -159 3399 -151 3392 -139 ct 3392 -139 3392 -139 3392 0 ct 3392 0 3392 0 3331 0 ct +p ef +3596 69 m 3596 69 3596 69 3602 25 ct 3634 38 3660 44 3680 44 ct 3698 44 3711 39 3719 30 ct +3728 21 3732 7 3732 -11 ct 3732 -11 3732 -11 3733 -53 ct 3733 -53 3733 -53 3731 -53 ct +3723 -35 3713 -22 3702 -13 ct 3690 -4 3676 0 3660 0 ct 3634 0 3613 -10 3598 -31 ct +3582 -51 3574 -78 3574 -111 ct 3574 -147 3583 -175 3600 -197 ct 3618 -218 3641 -229 3670 -229 ct +3682 -229 3692 -227 3702 -223 ct 3712 -218 3721 -212 3730 -204 ct 3730 -204 3730 -204 3735 -204 ct +3735 -204 3735 -204 3740 -224 ct 3740 -224 3740 -224 3791 -224 ct 3791 -224 3791 -224 3791 -27 ct +3791 10 3782 38 3764 58 ct 3747 77 3721 87 3688 87 ct 3662 87 3631 81 3596 69 ct +p +3730 -95 m 3730 -95 3730 -95 3730 -163 ct 3722 -169 3714 -174 3706 -178 ct +3699 -181 3692 -183 3685 -183 ct 3670 -183 3659 -177 3651 -166 ct 3644 -155 3640 -138 3640 -116 ct +3640 -97 3643 -83 3650 -73 ct 3657 -64 3666 -59 3680 -59 ct 3689 -59 3698 -62 3707 -68 ct +3715 -74 3723 -83 3730 -95 ct p ef +pom +gr +gs +pum +3054 3853 t +pom +gr +gs +pum +3562 3853 t +43 -326 m 43 -326 43 -326 43 -295 ct 43 -295 43 -295 59 -295 ct 80 -295 94 -293 102 -287 ct +111 -282 115 -274 115 -261 ct 115 -257 114 -251 113 -242 ct 113 -242 113 -242 109 -214 ct +108 -204 107 -196 107 -190 ct 107 -175 110 -163 117 -153 ct 124 -144 134 -137 148 -132 ct +134 -128 124 -121 117 -111 ct 110 -102 107 -90 107 -75 ct 107 -68 108 -61 109 -51 ct +109 -51 109 -51 113 -23 ct 114 -14 115 -8 115 -4 ct 115 9 111 17 102 22 ct 94 27 80 30 59 30 ct +59 30 59 30 43 30 ct 43 30 43 30 43 61 ct 43 61 43 61 66 61 ct 95 61 117 56 131 46 ct +146 36 153 21 153 2 ct 153 -7 152 -16 150 -26 ct 150 -26 150 -26 143 -63 ct 142 -68 142 -74 142 -79 ct +142 -92 146 -101 154 -108 ct 161 -114 173 -117 188 -117 ct 188 -117 188 -117 207 -117 ct +207 -117 207 -117 207 -148 ct 207 -148 207 -148 188 -148 ct 173 -148 161 -151 154 -157 ct +146 -164 142 -173 142 -186 ct 142 -191 142 -197 143 -202 ct 143 -202 143 -202 150 -239 ct +152 -249 153 -258 153 -267 ct 153 -286 146 -301 131 -311 ct 117 -321 95 -326 66 -326 ct +66 -326 66 -326 43 -326 ct p ef +pom +gr +gs +pum +3054 4344 t +43 -326 m 43 -326 43 -326 43 -295 ct 43 -295 43 -295 59 -295 ct 80 -295 94 -293 102 -287 ct +111 -282 115 -274 115 -261 ct 115 -257 114 -251 113 -242 ct 113 -242 113 -242 109 -214 ct +108 -204 107 -196 107 -190 ct 107 -175 110 -163 117 -153 ct 124 -144 134 -137 148 -132 ct +134 -128 124 -121 117 -111 ct 110 -102 107 -90 107 -75 ct 107 -68 108 -61 109 -51 ct +109 -51 109 -51 113 -23 ct 114 -14 115 -8 115 -4 ct 115 9 111 17 102 22 ct 94 27 80 30 59 30 ct +59 30 59 30 43 30 ct 43 30 43 30 43 61 ct 43 61 43 61 66 61 ct 95 61 117 56 131 46 ct +146 36 153 21 153 2 ct 153 -7 152 -16 150 -26 ct 150 -26 150 -26 143 -63 ct 142 -68 142 -74 142 -79 ct +142 -92 146 -101 154 -108 ct 161 -114 173 -117 188 -117 ct 188 -117 188 -117 207 -117 ct +207 -117 207 -117 207 -148 ct 207 -148 207 -148 188 -148 ct 173 -148 161 -151 154 -157 ct +146 -164 142 -173 142 -186 ct 142 -191 142 -197 143 -202 ct 143 -202 143 -202 150 -239 ct +152 -249 153 -258 153 -267 ct 153 -286 146 -301 131 -311 ct 117 -321 95 -326 66 -326 ct +66 -326 66 -326 43 -326 ct p ef +351 66 m 351 66 351 66 351 46 ct 358 45 364 41 368 33 ct 373 25 375 14 376 0 ct +376 0 376 0 351 0 ct 351 0 351 0 351 -61 ct 351 -61 351 -61 412 -61 ct 412 -61 412 -61 412 -24 ct +412 5 407 27 397 42 ct 387 57 371 65 351 66 ct p +351 -163 m 351 -224 l 412 -224 l 412 -163 l 351 -163 l p ef +pom +gr +gs +pum +3054 5038 t +pom +gr +gr +0.503 0.503 0.503 c 4064 6180 m 3002 6180 l 3002 5505 l 5126 5505 l +5126 6180 l 4064 6180 l p ef +4064 6180 m 3002 6180 l 3002 5505 l 5126 5505 l 5126 6180 l 4064 6180 l +pc +0.753 0.753 0.753 c 3964 6080 m 2902 6080 l 2902 5405 l 5026 5405 l +5026 6080 l 3964 6080 l p ef +0.003 0.003 0.003 c 3964 6080 m 2902 6080 l 2902 5405 l 5026 5405 l 5026 6080 l +3964 6080 l pc +gs +gs +pum +3133 5893 t +1.000 1.000 1.000 c 248 -242 m 158 -242 l 158 0 l 99 0 l 99 -242 l +9 -242 l 9 -291 l 248 -291 l 248 -242 l p ef +472 0 m 472 0 472 0 413 0 ct 409 -9 407 -17 407 -25 ct 388 -5 365 5 338 5 ct 318 5 302 -1 291 -13 ct +280 -24 274 -40 274 -59 ct 274 -73 278 -85 285 -95 ct 293 -106 304 -114 319 -120 ct +334 -127 351 -131 372 -132 ct 372 -132 372 -132 407 -135 ct 407 -135 407 -135 407 -139 ct +407 -163 393 -175 366 -175 ct 358 -175 347 -173 333 -170 ct 319 -166 307 -162 297 -157 ct +297 -157 297 -157 283 -198 ct 296 -204 312 -210 329 -214 ct 347 -218 362 -220 376 -220 ct +405 -220 427 -213 442 -199 ct 457 -185 464 -165 464 -138 ct 464 -138 464 -138 464 -51 ct +464 -31 467 -14 472 0 ct p +407 -66 m 407 -66 407 -66 407 -101 ct 383 -99 368 -97 362 -96 ct 357 -95 351 -93 344 -89 ct +338 -86 334 -82 331 -77 ct 328 -72 326 -67 326 -61 ct 326 -54 328 -49 333 -45 ct +337 -40 343 -38 350 -38 ct 371 -38 390 -47 407 -66 ct p ef +662 -211 m 662 -211 662 -211 652 -159 ct 646 -163 640 -165 633 -165 ct 626 -165 619 -163 613 -158 ct +606 -153 599 -145 592 -134 ct 585 -123 582 -116 582 -114 ct 582 -114 582 -114 582 0 ct +582 0 582 0 525 0 ct 525 0 525 0 525 -215 ct 525 -215 525 -215 582 -215 ct 582 -215 582 -215 582 -172 ct +590 -190 598 -202 606 -209 ct 614 -216 624 -220 635 -220 ct 646 -220 655 -217 662 -211 ct +p ef +888 -9 m 888 23 878 47 858 64 ct 839 81 811 89 775 89 ct 743 89 713 81 687 65 ct +687 65 687 65 703 22 ct 727 35 750 42 774 42 ct 792 42 806 38 816 29 ct 826 21 831 8 831 -7 ct +831 -7 831 -7 831 -22 ct 814 -4 793 5 767 5 ct 741 5 719 -5 702 -25 ct 685 -45 676 -71 676 -105 ct +676 -141 685 -169 702 -189 ct 719 -210 742 -220 770 -220 ct 781 -220 793 -218 804 -213 ct +815 -209 824 -203 831 -195 ct 831 -195 831 -195 831 -219 ct 831 -219 831 -219 888 -219 ct +888 -219 888 -219 888 -9 ct p +831 -71 m 831 -71 831 -71 831 -146 ct 818 -163 802 -171 782 -171 ct 768 -171 757 -165 748 -154 ct +739 -142 735 -126 735 -106 ct 735 -87 739 -71 748 -60 ct 757 -50 768 -44 782 -44 ct +801 -44 817 -53 831 -71 ct p ef +1140 -20 m 1115 -3 1086 5 1054 5 ct 1018 5 989 -5 967 -26 ct 946 -46 935 -74 935 -108 ct +935 -142 945 -169 964 -189 ct 983 -210 1009 -220 1041 -220 ct 1070 -220 1094 -210 1112 -191 ct +1131 -171 1140 -144 1140 -109 ct 1140 -109 1140 -109 1140 -95 ct 1140 -95 1140 -95 994 -95 ct +996 -80 1003 -68 1014 -59 ct 1025 -49 1039 -44 1055 -44 ct 1080 -44 1105 -51 1130 -65 ct +1130 -65 1130 -65 1140 -20 ct p +1085 -133 m 1083 -147 1078 -158 1070 -167 ct 1062 -175 1053 -179 1041 -179 ct +1029 -179 1018 -175 1010 -167 ct 1001 -158 996 -147 994 -133 ct 994 -133 994 -133 1085 -133 ct +p ef +1301 -5 m 1289 2 1276 5 1262 5 ct 1239 5 1221 -1 1209 -13 ct 1197 -25 1191 -43 1191 -66 ct +1191 -66 1191 -66 1191 -171 ct 1191 -171 1191 -171 1161 -171 ct 1161 -171 1161 -171 1161 -215 ct +1161 -215 1161 -215 1191 -215 ct 1191 -215 1191 -215 1191 -282 ct 1191 -282 1191 -282 1248 -282 ct +1248 -282 1248 -282 1248 -215 ct 1248 -215 1248 -215 1290 -215 ct 1290 -215 1290 -215 1290 -171 ct +1290 -171 1290 -171 1248 -171 ct 1248 -171 1248 -171 1248 -75 ct 1248 -65 1250 -58 1254 -52 ct +1258 -47 1263 -44 1269 -44 ct 1277 -44 1284 -46 1292 -49 ct 1292 -49 1292 -49 1301 -5 ct +p ef +1353 -66 m 1363 -66 1372 -63 1379 -56 ct 1386 -49 1389 -41 1389 -31 ct 1389 -21 1386 -12 1379 -5 ct +1372 2 1363 5 1353 5 ct 1343 5 1335 2 1328 -5 ct 1321 -12 1318 -20 1318 -31 ct +1318 -41 1321 -49 1328 -56 ct 1335 -63 1343 -66 1353 -66 ct p ef +1643 0 m 1643 0 1643 0 1586 0 ct 1586 0 1586 0 1586 -125 ct 1586 -156 1575 -171 1553 -171 ct +1534 -171 1516 -160 1501 -139 ct 1501 -139 1501 -139 1501 0 ct 1501 0 1501 0 1444 0 ct +1444 0 1444 0 1444 -307 ct 1444 -307 1444 -307 1501 -307 ct 1501 -307 1501 -307 1501 -188 ct +1519 -209 1542 -220 1570 -220 ct 1592 -220 1610 -213 1623 -200 ct 1636 -187 1643 -168 1643 -144 ct +1643 -144 1643 -144 1643 0 ct p ef +pom +gr +gr +0.503 0.503 0.503 c 14611 9736 m 10090 9736 l 10090 1379 l 19133 1379 l +19133 9736 l 14611 9736 l p ef +14611 9736 m 10090 9736 l 10090 1379 l 19133 1379 l 19133 9736 l 14611 9736 l +pc +1.000 0.902 0.777 c 14511 9636 m 9990 9636 l 9990 1279 l 19033 1279 l +19033 9636 l 14511 9636 l p ef +0.003 0.003 0.003 c 14511 9636 m 9990 9636 l 9990 1279 l 19033 1279 l 19033 9636 l +14511 9636 l pc +gs +gs +pum +10197 1809 t +35 0 m 58 -93 l 11 -93 l 18 -124 l 66 -124 l 80 -184 l 33 -184 l +41 -215 l 88 -215 l 111 -306 l 142 -306 l 120 -215 l 168 -215 l 191 -306 l +222 -306 l 200 -215 l 246 -215 l 239 -184 l 192 -184 l 177 -124 l +224 -124 l 216 -93 l 169 -93 l 146 0 l 115 0 l 138 -93 l 89 -93 l +66 0 l 35 0 l p +97 -124 m 146 -124 l 160 -184 l 112 -184 l 97 -124 l p ef +371 0 m 371 -193 l 289 -193 l 289 -224 l 412 -224 l 412 0 l 371 0 l +p +366 -275 m 366 -326 l 417 -326 l 417 -275 l 366 -275 l p ef +545 0 m 545 0 545 0 545 -224 ct 545 -224 545 -224 586 -224 ct 586 -224 586 -224 584 -182 ct +584 -182 584 -182 586 -182 ct 596 -198 607 -209 620 -217 ct 632 -225 647 -229 663 -229 ct +684 -229 700 -223 711 -210 ct 722 -197 727 -178 727 -153 ct 727 -153 727 -153 727 0 ct +727 0 727 0 686 0 ct 686 0 686 0 686 -142 ct 686 -159 683 -172 678 -179 ct 672 -186 663 -190 650 -190 ct +640 -190 630 -186 619 -179 ct 608 -172 597 -161 586 -146 ct 586 -146 586 -146 586 0 ct +586 0 586 0 545 0 ct p ef +990 -7 m 966 1 942 5 918 5 ct 879 5 849 -5 828 -26 ct 807 -46 796 -75 796 -112 ct +796 -149 806 -177 827 -198 ct 848 -219 877 -229 914 -229 ct 938 -229 962 -225 986 -218 ct +986 -218 986 -218 986 -184 ct 959 -193 937 -198 918 -198 ct 894 -198 874 -190 860 -175 ct +846 -160 839 -139 839 -112 ct 839 -85 846 -64 861 -49 ct 876 -34 897 -26 923 -26 ct +943 -26 965 -31 990 -40 ct 990 -40 990 -40 990 -7 ct p ef +1138 0 m 1138 -295 l 1051 -295 l 1051 -326 l 1179 -326 l 1179 0 l +1138 0 l p ef +1488 -224 m 1488 -224 1488 -224 1488 0 ct 1488 0 1488 0 1447 0 ct 1447 0 1447 0 1449 -42 ct +1449 -42 1449 -42 1447 -42 ct 1438 -26 1426 -15 1414 -7 ct 1401 1 1386 5 1370 5 ct +1349 5 1333 -1 1322 -14 ct 1311 -27 1306 -46 1306 -71 ct 1306 -71 1306 -71 1306 -224 ct +1306 -224 1306 -224 1347 -224 ct 1347 -224 1347 -224 1347 -82 ct 1347 -65 1350 -52 1355 -45 ct +1361 -38 1370 -34 1383 -34 ct 1393 -34 1403 -38 1414 -45 ct 1425 -52 1436 -63 1447 -78 ct +1447 -78 1447 -78 1447 -224 ct 1447 -224 1447 -224 1488 -224 ct p ef +1706 0 m 1706 0 1706 0 1708 -42 ct 1708 -42 1708 -42 1706 -42 ct 1696 -26 1685 -15 1673 -7 ct +1660 1 1647 5 1632 5 ct 1607 5 1587 -5 1572 -24 ct 1557 -44 1550 -71 1550 -105 ct +1550 -142 1559 -172 1576 -195 ct 1594 -218 1616 -229 1644 -229 ct 1656 -229 1668 -226 1678 -221 ct +1688 -216 1698 -209 1706 -198 ct 1706 -198 1706 -198 1708 -198 ct 1708 -198 1708 -198 1706 -229 ct +1706 -229 1706 -229 1706 -326 ct 1706 -326 1706 -326 1747 -326 ct 1747 -326 1747 -326 1747 0 ct +1747 0 1747 0 1706 0 ct p +1706 -168 m 1696 -178 1687 -185 1678 -190 ct 1668 -195 1659 -198 1650 -198 ct +1632 -198 1618 -190 1608 -175 ct 1598 -159 1593 -137 1593 -109 ct 1593 -83 1597 -63 1605 -50 ct +1613 -38 1624 -31 1640 -31 ct 1652 -31 1663 -35 1674 -42 ct 1685 -49 1696 -59 1706 -73 ct +1706 -73 1706 -73 1706 -168 ct p ef +2004 -9 m 1976 0 1950 5 1926 5 ct 1888 5 1859 -5 1838 -25 ct 1817 -45 1807 -73 1807 -110 ct +1807 -144 1817 -173 1837 -195 ct 1857 -218 1882 -229 1913 -229 ct 1944 -229 1966 -220 1981 -201 ct +1996 -182 2003 -153 2003 -114 ct 2003 -114 2003 -114 2003 -101 ct 2003 -101 2003 -101 1849 -101 ct +1850 -76 1858 -57 1872 -45 ct 1886 -32 1905 -26 1931 -26 ct 1954 -26 1978 -31 2004 -42 ct +2004 -42 2004 -42 2004 -9 ct p +1850 -132 m 1850 -132 1850 -132 1960 -132 ct 1960 -132 1960 -132 1960 -138 ct +1960 -158 1956 -173 1947 -183 ct 1938 -193 1926 -198 1909 -198 ct 1892 -198 1879 -192 1868 -181 ct +1858 -169 1852 -153 1850 -132 ct p ef +2337 -214 m 2337 -214 2337 -214 2337 -260 ct 2337 -282 2341 -298 2350 -309 ct +2358 -320 2371 -326 2388 -326 ct 2388 -326 2388 -326 2388 -306 ct 2381 -306 2375 -303 2371 -298 ct +2368 -293 2366 -286 2366 -276 ct 2366 -276 2366 -276 2366 -265 ct 2366 -265 2366 -265 2388 -265 ct +2388 -265 2388 -265 2388 -214 ct 2388 -214 2388 -214 2337 -214 ct p +2439 -214 m 2439 -214 2439 -214 2439 -260 ct 2439 -282 2443 -298 2452 -309 ct +2460 -320 2473 -326 2490 -326 ct 2490 -326 2490 -326 2490 -306 ct 2483 -306 2477 -303 2473 -298 ct +2470 -293 2468 -286 2468 -276 ct 2468 -276 2468 -276 2468 -265 ct 2468 -265 2468 -265 2490 -265 ct +2490 -265 2490 -265 2490 -214 ct 2490 -214 2490 -214 2439 -214 ct p ef +2647 0 m 2647 -275 l 2545 -275 l 2545 -306 l 2790 -306 l 2790 -275 l +2688 -275 l 2688 0 l 2647 0 l p ef +2966 -26 m 2942 -5 2917 5 2893 5 ct 2872 5 2855 -1 2842 -13 ct 2829 -24 2822 -39 2822 -57 ct +2822 -81 2832 -99 2853 -114 ct 2874 -128 2901 -135 2935 -135 ct 2935 -135 2935 -135 2960 -135 ct +2960 -135 2960 -135 2960 -154 ct 2960 -169 2956 -180 2949 -187 ct 2941 -194 2930 -198 2915 -198 ct +2891 -198 2866 -191 2841 -177 ct 2841 -177 2841 -177 2841 -213 ct 2870 -224 2897 -229 2923 -229 ct +2952 -229 2972 -223 2983 -212 ct 2995 -201 3001 -181 3001 -153 ct 3001 -153 3001 -153 3001 -59 ct +3001 -45 3002 -36 3005 -31 ct 3008 -26 3014 -24 3021 -24 ct 3024 -24 3028 -25 3034 -26 ct +3034 -26 3034 -26 3038 -2 ct 3024 3 3014 5 3007 5 ct 2997 5 2988 2 2982 -3 ct 2975 -8 2970 -16 2966 -26 ct +p +2960 -53 m 2960 -53 2960 -53 2960 -110 ct 2960 -110 2960 -110 2948 -110 ct +2920 -110 2899 -106 2885 -99 ct 2871 -91 2864 -80 2864 -64 ct 2864 -52 2867 -43 2874 -37 ct +2880 -31 2890 -28 2903 -28 ct 2921 -28 2940 -36 2960 -53 ct p ef +3112 0 m 3112 0 3112 0 3112 -224 ct 3112 -224 3112 -224 3153 -224 ct 3153 -224 3153 -224 3151 -182 ct +3151 -182 3151 -182 3153 -182 ct 3163 -198 3175 -209 3189 -217 ct 3203 -225 3218 -229 3236 -229 ct +3248 -229 3262 -227 3277 -224 ct 3277 -224 3277 -224 3277 -160 ct 3277 -160 3277 -160 3246 -160 ct +3246 -160 3246 -160 3246 -191 ct 3240 -192 3234 -193 3229 -193 ct 3215 -193 3202 -189 3190 -181 ct +3177 -173 3165 -161 3153 -145 ct 3153 -145 3153 -145 3153 0 ct 3153 0 3153 0 3112 0 ct +p ef +3345 75 m 3345 75 3345 75 3349 41 ct 3374 51 3397 56 3418 56 ct 3440 56 3456 51 3465 42 ct +3475 33 3481 17 3484 -6 ct 3484 -6 3484 -6 3488 -46 ct 3488 -46 3488 -46 3484 -46 ct +3476 -31 3465 -19 3453 -12 ct 3440 -4 3426 0 3410 0 ct 3385 0 3365 -10 3350 -29 ct +3335 -49 3327 -75 3327 -108 ct 3327 -144 3336 -173 3353 -195 ct 3371 -218 3393 -229 3421 -229 ct +3443 -229 3465 -219 3486 -198 ct 3486 -198 3486 -198 3489 -198 ct 3489 -198 3489 -198 3489 -224 ct +3489 -224 3489 -224 3525 -224 ct 3525 -224 3525 -224 3525 -45 ct 3525 -15 3523 6 3519 21 ct +3515 36 3508 49 3497 60 ct 3480 78 3454 87 3417 87 ct 3396 87 3372 83 3345 75 ct +p +3484 -80 m 3484 -80 3484 -80 3484 -167 ct 3466 -188 3446 -198 3427 -198 ct +3408 -198 3394 -191 3384 -176 ct 3375 -162 3370 -140 3370 -111 ct 3370 -86 3374 -67 3382 -55 ct +3391 -42 3403 -36 3420 -36 ct 3432 -36 3443 -40 3454 -47 ct 3465 -54 3475 -65 3484 -80 ct +p ef +3782 -9 m 3754 0 3728 5 3704 5 ct 3666 5 3637 -5 3616 -25 ct 3595 -45 3585 -73 3585 -110 ct +3585 -144 3595 -173 3615 -195 ct 3635 -218 3660 -229 3691 -229 ct 3722 -229 3744 -220 3759 -201 ct +3774 -182 3781 -153 3781 -114 ct 3781 -114 3781 -114 3781 -101 ct 3781 -101 3781 -101 3627 -101 ct +3628 -76 3636 -57 3650 -45 ct 3664 -32 3683 -26 3709 -26 ct 3732 -26 3756 -31 3782 -42 ct +3782 -42 3782 -42 3782 -9 ct p +3628 -132 m 3628 -132 3628 -132 3738 -132 ct 3738 -132 3738 -132 3738 -138 ct +3738 -158 3734 -173 3725 -183 ct 3716 -193 3704 -198 3687 -198 ct 3670 -198 3657 -192 3646 -181 ct +3636 -169 3630 -153 3628 -132 ct p ef +4038 0 m 4018 3 3998 5 3979 5 ct 3946 5 3923 -1 3911 -13 ct 3899 -25 3893 -47 3893 -80 ct +3893 -80 3893 -80 3893 -188 ct 3893 -188 3893 -188 3837 -188 ct 3837 -188 3837 -188 3837 -219 ct +3837 -219 3837 -219 3893 -219 ct 3893 -219 3893 -219 3893 -267 ct 3893 -267 3893 -267 3934 -267 ct +3934 -267 3934 -267 3934 -219 ct 3934 -219 3934 -219 4033 -219 ct 4033 -219 4033 -219 4033 -188 ct +4033 -188 4033 -188 3934 -188 ct 3934 -188 3934 -188 3934 -74 ct 3934 -61 3935 -53 3936 -48 ct +3938 -43 3941 -39 3947 -35 ct 3956 -29 3969 -26 3987 -26 ct 4004 -26 4021 -28 4038 -31 ct +4038 -31 4038 -31 4038 0 ct p ef +4161 0 m 4161 -61 l 4222 -61 l 4222 0 l 4161 0 l p ef +4355 0 m 4355 0 4355 0 4355 -326 ct 4355 -326 4355 -326 4396 -326 ct 4396 -326 4396 -326 4396 -224 ct +4396 -224 4396 -224 4394 -182 ct 4394 -182 4394 -182 4396 -182 ct 4406 -198 4417 -209 4430 -217 ct +4442 -225 4457 -229 4473 -229 ct 4494 -229 4510 -223 4521 -210 ct 4532 -197 4537 -178 4537 -153 ct +4537 -153 4537 -153 4537 0 ct 4537 0 4537 0 4496 0 ct 4496 0 4496 0 4496 -142 ct +4496 -159 4493 -172 4488 -179 ct 4482 -186 4473 -190 4460 -190 ct 4450 -190 4440 -186 4429 -179 ct +4418 -172 4407 -161 4396 -146 ct 4396 -146 4396 -146 4396 0 ct 4396 0 4396 0 4355 0 ct +p ef +4623 -214 m 4623 -214 4623 -214 4623 -260 ct 4623 -282 4627 -298 4636 -309 ct +4644 -320 4657 -326 4674 -326 ct 4674 -326 4674 -326 4674 -306 ct 4667 -306 4661 -303 4657 -298 ct +4654 -293 4652 -286 4652 -276 ct 4652 -276 4652 -276 4652 -265 ct 4652 -265 4652 -265 4674 -265 ct +4674 -265 4674 -265 4674 -214 ct 4674 -214 4674 -214 4623 -214 ct p +4725 -214 m 4725 -214 4725 -214 4725 -260 ct 4725 -282 4729 -298 4738 -309 ct +4746 -320 4759 -326 4776 -326 ct 4776 -326 4776 -326 4776 -306 ct 4769 -306 4763 -303 4759 -298 ct +4756 -293 4754 -286 4754 -276 ct 4754 -276 4754 -276 4754 -265 ct 4754 -265 4754 -265 4776 -265 ct +4776 -265 4776 -265 4776 -214 ct 4776 -214 4776 -214 4725 -214 ct p ef +pom +gr +gs +pum +15277 1809 t +0.003 0.503 0.003 c 239 -326 m 65 61 l 15 61 l 189 -326 l 239 -326 l +p ef +493 -326 m 319 61 l 269 61 l 443 -326 l 493 -326 l p ef +847 0 m 847 0 847 0 847 -178 ct 847 -178 847 -178 804 -178 ct 804 -178 804 -178 804 -219 ct +804 -219 804 -219 847 -219 ct 847 -219 847 -219 847 -251 ct 847 -278 855 -298 870 -311 ct +885 -324 908 -331 939 -331 ct 965 -331 990 -328 1015 -322 ct 1015 -322 1015 -322 1015 -278 ct +989 -286 968 -290 952 -290 ct 936 -290 925 -287 918 -281 ct 911 -275 908 -265 908 -250 ct +908 -250 908 -250 908 -219 ct 908 -219 908 -219 995 -219 ct 995 -219 995 -219 995 -178 ct +995 -178 995 -178 908 -178 ct 908 -178 908 -178 908 0 ct 908 0 908 0 847 0 ct p ef +1142 5 m 1108 5 1080 -6 1059 -27 ct 1038 -49 1027 -77 1027 -112 ct 1027 -148 1038 -176 1059 -197 ct +1080 -218 1108 -229 1144 -229 ct 1179 -229 1207 -218 1228 -197 ct 1249 -176 1260 -148 1260 -112 ct +1260 -76 1249 -48 1228 -27 ct 1207 -6 1178 5 1142 5 ct p +1143 -36 m 1160 -36 1173 -42 1181 -55 ct 1190 -68 1194 -87 1194 -112 ct 1194 -138 1190 -156 1181 -169 ct +1173 -182 1160 -188 1144 -188 ct 1127 -188 1114 -182 1106 -169 ct 1097 -156 1093 -137 1093 -112 ct +1093 -87 1097 -68 1105 -55 ct 1114 -42 1126 -36 1143 -36 ct p ef +1316 0 m 1316 0 1316 0 1316 -224 ct 1316 -224 1316 -224 1377 -224 ct 1377 -224 1377 -224 1375 -181 ct +1375 -181 1375 -181 1377 -181 ct 1387 -197 1399 -209 1413 -217 ct 1426 -225 1442 -229 1460 -229 ct +1471 -229 1486 -227 1502 -224 ct 1502 -224 1502 -224 1502 -149 ct 1502 -149 1502 -149 1461 -149 ct +1461 -149 1461 -149 1461 -173 ct 1456 -174 1453 -174 1450 -174 ct 1435 -174 1422 -170 1409 -163 ct +1397 -156 1386 -145 1377 -130 ct 1377 -130 1377 -130 1377 0 ct 1377 0 1377 0 1316 0 ct +p ef +1880 0 m 1880 -285 l 1798 -285 l 1798 -326 l 1941 -326 l 1941 0 l +1880 0 l p ef +2185 -24 m 2178 -14 2169 -7 2159 -2 ct 2149 3 2138 5 2125 5 ct 2103 5 2085 -2 2071 -15 ct +2057 -28 2050 -45 2050 -65 ct 2050 -91 2060 -111 2079 -124 ct 2099 -137 2128 -143 2167 -143 ct +2167 -143 2167 -143 2191 -143 ct 2191 -143 2191 -143 2191 -154 ct 2191 -165 2187 -174 2179 -179 ct +2171 -185 2159 -188 2143 -188 ct 2121 -188 2096 -182 2069 -169 ct 2069 -169 2069 -169 2069 -214 ct +2097 -224 2125 -229 2154 -229 ct 2186 -229 2210 -223 2226 -211 ct 2236 -203 2243 -194 2247 -185 ct +2250 -175 2252 -160 2252 -140 ct 2252 -140 2252 -140 2252 -64 ct 2252 -49 2257 -41 2266 -41 ct +2268 -41 2270 -41 2273 -42 ct 2273 -42 2273 -42 2273 -2 ct 2261 3 2249 5 2239 5 ct +2228 5 2218 3 2210 -2 ct 2202 -7 2196 -14 2191 -24 ct 2191 -24 2191 -24 2185 -24 ct +p +2191 -65 m 2191 -65 2191 -65 2191 -102 ct 2191 -102 2191 -102 2169 -102 ct +2150 -102 2135 -99 2126 -94 ct 2116 -88 2111 -80 2111 -69 ct 2111 -61 2114 -54 2120 -49 ct +2126 -44 2133 -41 2142 -41 ct 2157 -41 2174 -49 2191 -65 ct p ef +2319 -8 m 2319 -8 2319 -8 2319 -54 ct 2353 -42 2381 -36 2401 -36 ct 2416 -36 2427 -38 2435 -42 ct +2442 -46 2446 -52 2446 -60 ct 2446 -64 2444 -68 2440 -72 ct 2437 -75 2431 -79 2424 -82 ct +2424 -82 2424 -82 2376 -101 ct 2357 -109 2343 -118 2334 -127 ct 2325 -137 2320 -148 2320 -161 ct +2320 -182 2330 -199 2349 -211 ct 2368 -223 2395 -229 2429 -229 ct 2449 -229 2472 -226 2498 -221 ct +2498 -221 2498 -221 2498 -174 ct 2470 -183 2446 -188 2427 -188 ct 2412 -188 2402 -186 2395 -183 ct +2388 -180 2384 -175 2384 -169 ct 2384 -165 2387 -162 2392 -158 ct 2397 -154 2404 -150 2414 -146 ct +2414 -146 2414 -146 2467 -124 ct 2483 -118 2495 -110 2502 -100 ct 2510 -91 2514 -79 2514 -66 ct +2514 -45 2505 -28 2486 -15 ct 2467 -2 2443 5 2413 5 ct 2387 5 2355 1 2319 -8 ct +p ef +2768 -6 m 2744 1 2722 5 2704 5 ct 2675 5 2654 -1 2640 -14 ct 2626 -26 2619 -45 2619 -70 ct +2619 -70 2619 -70 2619 -178 ct 2619 -178 2619 -178 2571 -178 ct 2571 -178 2571 -178 2571 -219 ct +2571 -219 2571 -219 2619 -219 ct 2619 -219 2619 -219 2619 -285 ct 2619 -285 2619 -285 2680 -285 ct +2680 -285 2680 -285 2680 -219 ct 2680 -219 2680 -219 2763 -219 ct 2763 -219 2763 -219 2763 -178 ct +2763 -178 2763 -178 2680 -178 ct 2680 -178 2680 -178 2680 -84 ct 2680 -68 2683 -57 2689 -51 ct +2695 -44 2705 -41 2719 -41 ct 2736 -41 2752 -44 2768 -51 ct 2768 -51 2768 -51 2768 -6 ct +p ef +2794 46 m 2794 0 l 3049 0 l 3049 46 l 2794 46 l p ef +pom +gr +gs +pum +10197 2300 t +35 0 m 58 -93 l 11 -93 l 18 -124 l 66 -124 l 80 -184 l 33 -184 l +41 -215 l 88 -215 l 111 -306 l 142 -306 l 120 -215 l 168 -215 l 191 -306 l +222 -306 l 200 -215 l 246 -215 l 239 -184 l 192 -184 l 177 -124 l +224 -124 l 216 -93 l 169 -93 l 146 0 l 115 0 l 138 -93 l 89 -93 l +66 0 l 35 0 l p +97 -124 m 146 -124 l 160 -184 l 112 -184 l 97 -124 l p ef +371 0 m 371 -193 l 289 -193 l 289 -224 l 412 -224 l 412 0 l 371 0 l +p +366 -275 m 366 -326 l 417 -326 l 417 -275 l 366 -275 l p ef +545 0 m 545 0 545 0 545 -224 ct 545 -224 545 -224 586 -224 ct 586 -224 586 -224 584 -182 ct +584 -182 584 -182 586 -182 ct 596 -198 607 -209 620 -217 ct 632 -225 647 -229 663 -229 ct +684 -229 700 -223 711 -210 ct 722 -197 727 -178 727 -153 ct 727 -153 727 -153 727 0 ct +727 0 727 0 686 0 ct 686 0 686 0 686 -142 ct 686 -159 683 -172 678 -179 ct 672 -186 663 -190 650 -190 ct +640 -190 630 -186 619 -179 ct 608 -172 597 -161 586 -146 ct 586 -146 586 -146 586 0 ct +586 0 586 0 545 0 ct p ef +990 -7 m 966 1 942 5 918 5 ct 879 5 849 -5 828 -26 ct 807 -46 796 -75 796 -112 ct +796 -149 806 -177 827 -198 ct 848 -219 877 -229 914 -229 ct 938 -229 962 -225 986 -218 ct +986 -218 986 -218 986 -184 ct 959 -193 937 -198 918 -198 ct 894 -198 874 -190 860 -175 ct +846 -160 839 -139 839 -112 ct 839 -85 846 -64 861 -49 ct 876 -34 897 -26 923 -26 ct +943 -26 965 -31 990 -40 ct 990 -40 990 -40 990 -7 ct p ef +1138 0 m 1138 -295 l 1051 -295 l 1051 -326 l 1179 -326 l 1179 0 l +1138 0 l p ef +1488 -224 m 1488 -224 1488 -224 1488 0 ct 1488 0 1488 0 1447 0 ct 1447 0 1447 0 1449 -42 ct +1449 -42 1449 -42 1447 -42 ct 1438 -26 1426 -15 1414 -7 ct 1401 1 1386 5 1370 5 ct +1349 5 1333 -1 1322 -14 ct 1311 -27 1306 -46 1306 -71 ct 1306 -71 1306 -71 1306 -224 ct +1306 -224 1306 -224 1347 -224 ct 1347 -224 1347 -224 1347 -82 ct 1347 -65 1350 -52 1355 -45 ct +1361 -38 1370 -34 1383 -34 ct 1393 -34 1403 -38 1414 -45 ct 1425 -52 1436 -63 1447 -78 ct +1447 -78 1447 -78 1447 -224 ct 1447 -224 1447 -224 1488 -224 ct p ef +1706 0 m 1706 0 1706 0 1708 -42 ct 1708 -42 1708 -42 1706 -42 ct 1696 -26 1685 -15 1673 -7 ct +1660 1 1647 5 1632 5 ct 1607 5 1587 -5 1572 -24 ct 1557 -44 1550 -71 1550 -105 ct +1550 -142 1559 -172 1576 -195 ct 1594 -218 1616 -229 1644 -229 ct 1656 -229 1668 -226 1678 -221 ct +1688 -216 1698 -209 1706 -198 ct 1706 -198 1706 -198 1708 -198 ct 1708 -198 1708 -198 1706 -229 ct +1706 -229 1706 -229 1706 -326 ct 1706 -326 1706 -326 1747 -326 ct 1747 -326 1747 -326 1747 0 ct +1747 0 1747 0 1706 0 ct p +1706 -168 m 1696 -178 1687 -185 1678 -190 ct 1668 -195 1659 -198 1650 -198 ct +1632 -198 1618 -190 1608 -175 ct 1598 -159 1593 -137 1593 -109 ct 1593 -83 1597 -63 1605 -50 ct +1613 -38 1624 -31 1640 -31 ct 1652 -31 1663 -35 1674 -42 ct 1685 -49 1696 -59 1706 -73 ct +1706 -73 1706 -73 1706 -168 ct p ef +2004 -9 m 1976 0 1950 5 1926 5 ct 1888 5 1859 -5 1838 -25 ct 1817 -45 1807 -73 1807 -110 ct +1807 -144 1817 -173 1837 -195 ct 1857 -218 1882 -229 1913 -229 ct 1944 -229 1966 -220 1981 -201 ct +1996 -182 2003 -153 2003 -114 ct 2003 -114 2003 -114 2003 -101 ct 2003 -101 2003 -101 1849 -101 ct +1850 -76 1858 -57 1872 -45 ct 1886 -32 1905 -26 1931 -26 ct 1954 -26 1978 -31 2004 -42 ct +2004 -42 2004 -42 2004 -9 ct p +1850 -132 m 1850 -132 1850 -132 1960 -132 ct 1960 -132 1960 -132 1960 -138 ct +1960 -158 1956 -173 1947 -183 ct 1938 -193 1926 -198 1909 -198 ct 1892 -198 1879 -192 1868 -181 ct +1858 -169 1852 -153 1850 -132 ct p ef +2523 0 m 2304 -110 l 2523 -219 l 2523 -185 l 2372 -110 l 2523 -34 l +2523 0 l p ef +2579 -9 m 2579 -9 2579 -9 2579 -45 ct 2610 -32 2637 -26 2660 -26 ct 2676 -26 2690 -29 2701 -36 ct +2712 -43 2717 -51 2717 -61 ct 2717 -74 2704 -84 2679 -93 ct 2679 -93 2679 -93 2636 -107 ct +2602 -118 2585 -138 2585 -165 ct 2585 -186 2593 -201 2608 -212 ct 2623 -223 2645 -229 2673 -229 ct +2694 -229 2718 -226 2746 -219 ct 2746 -219 2746 -219 2746 -186 ct 2719 -194 2695 -198 2673 -198 ct +2657 -198 2644 -196 2636 -191 ct 2628 -186 2624 -179 2624 -169 ct 2624 -158 2634 -149 2654 -142 ct +2654 -142 2654 -142 2706 -124 ct 2741 -111 2758 -91 2758 -64 ct 2758 -43 2749 -26 2732 -14 ct +2714 -1 2691 5 2661 5 ct 2636 5 2608 0 2579 -9 ct p ef +3022 0 m 3002 3 2982 5 2963 5 ct 2930 5 2907 -1 2895 -13 ct 2883 -25 2877 -47 2877 -80 ct +2877 -80 2877 -80 2877 -188 ct 2877 -188 2877 -188 2821 -188 ct 2821 -188 2821 -188 2821 -219 ct +2821 -219 2821 -219 2877 -219 ct 2877 -219 2877 -219 2877 -267 ct 2877 -267 2877 -267 2918 -267 ct +2918 -267 2918 -267 2918 -219 ct 2918 -219 2918 -219 3017 -219 ct 3017 -219 3017 -219 3017 -188 ct +3017 -188 3017 -188 2918 -188 ct 2918 -188 2918 -188 2918 -74 ct 2918 -61 2919 -53 2920 -48 ct +2922 -43 2925 -39 2931 -35 ct 2940 -29 2953 -26 2971 -26 ct 2988 -26 3005 -28 3022 -31 ct +3022 -31 3022 -31 3022 0 ct p ef +3230 0 m 3230 0 3230 0 3232 -42 ct 3232 -42 3232 -42 3230 -42 ct 3220 -26 3209 -15 3197 -7 ct +3184 1 3171 5 3156 5 ct 3131 5 3111 -5 3096 -24 ct 3081 -44 3074 -71 3074 -105 ct +3074 -142 3083 -172 3100 -195 ct 3118 -218 3140 -229 3168 -229 ct 3180 -229 3192 -226 3202 -221 ct +3212 -216 3222 -209 3230 -198 ct 3230 -198 3230 -198 3232 -198 ct 3232 -198 3232 -198 3230 -229 ct +3230 -229 3230 -229 3230 -326 ct 3230 -326 3230 -326 3271 -326 ct 3271 -326 3271 -326 3271 0 ct +3271 0 3271 0 3230 0 ct p +3230 -168 m 3220 -178 3211 -185 3202 -190 ct 3192 -195 3183 -198 3174 -198 ct +3156 -198 3142 -190 3132 -175 ct 3122 -159 3117 -137 3117 -109 ct 3117 -83 3121 -63 3129 -50 ct +3137 -38 3148 -31 3164 -31 ct 3176 -31 3187 -35 3198 -42 ct 3209 -49 3220 -59 3230 -73 ct +3230 -73 3230 -73 3230 -168 ct p ef +3419 0 m 3419 -193 l 3337 -193 l 3337 -224 l 3460 -224 l 3460 0 l +3419 0 l p +3414 -275 m 3414 -326 l 3465 -326 l 3465 -275 l 3414 -275 l p ef +3682 5 m 3650 5 3625 -6 3606 -27 ct 3587 -48 3578 -76 3578 -112 ct 3578 -148 3587 -177 3606 -198 ct +3625 -219 3651 -229 3684 -229 ct 3716 -229 3742 -219 3761 -198 ct 3780 -177 3789 -149 3789 -113 ct +3789 -76 3780 -47 3761 -26 ct 3742 -5 3716 5 3682 5 ct p +3683 -26 m 3704 -26 3720 -33 3730 -48 ct 3741 -62 3746 -84 3746 -113 ct 3746 -139 3740 -160 3729 -175 ct +3718 -190 3703 -198 3684 -198 ct 3664 -198 3649 -190 3638 -175 ct 3627 -160 3621 -139 3621 -112 ct +3621 -85 3626 -64 3637 -49 ct 3648 -34 3664 -26 3683 -26 ct p ef +3907 0 m 3907 -61 l 3968 -61 l 3968 0 l 3907 0 l p ef +4101 0 m 4101 0 4101 0 4101 -326 ct 4101 -326 4101 -326 4142 -326 ct 4142 -326 4142 -326 4142 -224 ct +4142 -224 4142 -224 4140 -182 ct 4140 -182 4140 -182 4142 -182 ct 4152 -198 4163 -209 4176 -217 ct +4188 -225 4203 -229 4219 -229 ct 4240 -229 4256 -223 4267 -210 ct 4278 -197 4283 -178 4283 -153 ct +4283 -153 4283 -153 4283 0 ct 4283 0 4283 0 4242 0 ct 4242 0 4242 0 4242 -142 ct +4242 -159 4239 -172 4234 -179 ct 4228 -186 4219 -190 4206 -190 ct 4196 -190 4186 -186 4175 -179 ct +4164 -172 4153 -161 4142 -146 ct 4142 -146 4142 -146 4142 0 ct 4142 0 4142 0 4101 0 ct +p ef +4336 0 m 4555 -110 l 4336 -219 l 4336 -185 l 4487 -110 l 4336 -34 l +4336 0 l p ef +pom +gr +gs +pum +15277 2300 t +0.003 0.503 0.003 c 239 -326 m 65 61 l 15 61 l 189 -326 l 239 -326 l +p ef +493 -326 m 319 61 l 269 61 l 443 -326 l 493 -326 l p ef +847 0 m 847 0 847 0 847 -178 ct 847 -178 847 -178 804 -178 ct 804 -178 804 -178 804 -219 ct +804 -219 804 -219 847 -219 ct 847 -219 847 -219 847 -251 ct 847 -278 855 -298 870 -311 ct +885 -324 908 -331 939 -331 ct 965 -331 990 -328 1015 -322 ct 1015 -322 1015 -322 1015 -278 ct +989 -286 968 -290 952 -290 ct 936 -290 925 -287 918 -281 ct 911 -275 908 -265 908 -250 ct +908 -250 908 -250 908 -219 ct 908 -219 908 -219 995 -219 ct 995 -219 995 -219 995 -178 ct +995 -178 995 -178 908 -178 ct 908 -178 908 -178 908 0 ct 908 0 908 0 847 0 ct p ef +1142 5 m 1108 5 1080 -6 1059 -27 ct 1038 -49 1027 -77 1027 -112 ct 1027 -148 1038 -176 1059 -197 ct +1080 -218 1108 -229 1144 -229 ct 1179 -229 1207 -218 1228 -197 ct 1249 -176 1260 -148 1260 -112 ct +1260 -76 1249 -48 1228 -27 ct 1207 -6 1178 5 1142 5 ct p +1143 -36 m 1160 -36 1173 -42 1181 -55 ct 1190 -68 1194 -87 1194 -112 ct 1194 -138 1190 -156 1181 -169 ct +1173 -182 1160 -188 1144 -188 ct 1127 -188 1114 -182 1106 -169 ct 1097 -156 1093 -137 1093 -112 ct +1093 -87 1097 -68 1105 -55 ct 1114 -42 1126 -36 1143 -36 ct p ef +1316 0 m 1316 0 1316 0 1316 -224 ct 1316 -224 1316 -224 1377 -224 ct 1377 -224 1377 -224 1375 -181 ct +1375 -181 1375 -181 1377 -181 ct 1387 -197 1399 -209 1413 -217 ct 1426 -225 1442 -229 1460 -229 ct +1471 -229 1486 -227 1502 -224 ct 1502 -224 1502 -224 1502 -149 ct 1502 -149 1502 -149 1461 -149 ct +1461 -149 1461 -149 1461 -173 ct 1456 -174 1453 -174 1450 -174 ct 1435 -174 1422 -170 1409 -163 ct +1397 -156 1386 -145 1377 -130 ct 1377 -130 1377 -130 1377 0 ct 1377 0 1377 0 1316 0 ct +p ef +1811 -8 m 1811 -8 1811 -8 1811 -54 ct 1845 -42 1873 -36 1893 -36 ct 1908 -36 1919 -38 1927 -42 ct +1934 -46 1938 -52 1938 -60 ct 1938 -64 1936 -68 1932 -72 ct 1929 -75 1923 -79 1916 -82 ct +1916 -82 1916 -82 1868 -101 ct 1849 -109 1835 -118 1826 -127 ct 1817 -137 1812 -148 1812 -161 ct +1812 -182 1822 -199 1841 -211 ct 1860 -223 1887 -229 1921 -229 ct 1941 -229 1964 -226 1990 -221 ct +1990 -221 1990 -221 1990 -174 ct 1962 -183 1938 -188 1919 -188 ct 1904 -188 1894 -186 1887 -183 ct +1880 -180 1876 -175 1876 -169 ct 1876 -165 1879 -162 1884 -158 ct 1889 -154 1896 -150 1906 -146 ct +1906 -146 1906 -146 1959 -124 ct 1975 -118 1987 -110 1994 -100 ct 2002 -91 2006 -79 2006 -66 ct +2006 -45 1997 -28 1978 -15 ct 1959 -2 1935 5 1905 5 ct 1879 5 1847 1 1811 -8 ct +p ef +2134 0 m 2134 -285 l 2052 -285 l 2052 -326 l 2195 -326 l 2195 0 l +2134 0 l p ef +2408 0 m 2408 -183 l 2326 -183 l 2326 -224 l 2469 -224 l 2469 0 l +2408 0 l p +2408 -265 m 2408 -326 l 2469 -326 l 2469 -265 l 2408 -265 l p ef +2767 -4 m 2742 2 2717 5 2692 5 ct 2651 5 2618 -5 2595 -26 ct 2572 -47 2560 -75 2560 -111 ct +2560 -148 2571 -177 2594 -198 ct 2616 -219 2648 -229 2688 -229 ct 2718 -229 2744 -226 2767 -220 ct +2767 -220 2767 -220 2767 -175 ct 2742 -184 2719 -188 2696 -188 ct 2674 -188 2657 -182 2645 -169 ct +2632 -157 2626 -140 2626 -118 ct 2626 -94 2634 -74 2649 -60 ct 2664 -45 2684 -38 2709 -38 ct +2728 -38 2748 -42 2767 -49 ct 2767 -49 2767 -49 2767 -4 ct p ef +3030 -95 m 3030 -95 3030 -95 2878 -95 ct 2881 -77 2889 -63 2901 -54 ct 2913 -45 2929 -41 2950 -41 ct +2974 -41 3001 -46 3030 -56 ct 3030 -56 3030 -56 3030 -9 ct 2995 0 2964 5 2938 5 ct +2900 5 2869 -6 2846 -27 ct 2823 -48 2812 -76 2812 -111 ct 2812 -147 2823 -175 2844 -197 ct +2866 -218 2894 -229 2929 -229 ct 2961 -229 2985 -219 3003 -199 ct 3021 -180 3030 -152 3030 -118 ct +3030 -118 3030 -118 3030 -95 ct p +2877 -136 m 2877 -136 2877 -136 2971 -136 ct 2971 -153 2967 -166 2960 -175 ct +2952 -184 2941 -188 2926 -188 ct 2912 -188 2900 -184 2892 -175 ct 2884 -166 2879 -153 2877 -136 ct +p ef +pom +gr +gs +pum +10197 3282 t +0.003 0.003 1.000 c 153 -24 m 146 -14 137 -7 127 -2 ct 117 3 106 5 93 5 ct 71 5 53 -2 39 -15 ct +25 -28 18 -45 18 -65 ct 18 -91 28 -111 47 -124 ct 67 -137 96 -143 135 -143 ct 135 -143 135 -143 159 -143 ct +159 -143 159 -143 159 -154 ct 159 -165 155 -174 147 -179 ct 139 -185 127 -188 111 -188 ct +89 -188 64 -182 37 -169 ct 37 -169 37 -169 37 -214 ct 65 -224 93 -229 122 -229 ct +154 -229 178 -223 194 -211 ct 204 -203 211 -194 215 -185 ct 218 -175 220 -160 220 -140 ct +220 -140 220 -140 220 -64 ct 220 -49 225 -41 234 -41 ct 236 -41 238 -41 241 -42 ct +241 -42 241 -42 241 -2 ct 229 3 217 5 207 5 ct 196 5 186 3 178 -2 ct 170 -7 164 -14 159 -24 ct +159 -24 159 -24 153 -24 ct p +159 -65 m 159 -65 159 -65 159 -102 ct 159 -102 159 -102 137 -102 ct 118 -102 103 -99 94 -94 ct +84 -88 79 -80 79 -69 ct 79 -61 82 -54 88 -49 ct 94 -44 101 -41 110 -41 ct 125 -41 142 -49 159 -65 ct +p ef +287 -8 m 287 -8 287 -8 287 -54 ct 321 -42 349 -36 369 -36 ct 384 -36 395 -38 403 -42 ct +410 -46 414 -52 414 -60 ct 414 -64 412 -68 408 -72 ct 405 -75 399 -79 392 -82 ct +392 -82 392 -82 344 -101 ct 325 -109 311 -118 302 -127 ct 293 -137 288 -148 288 -161 ct +288 -182 298 -199 317 -211 ct 336 -223 363 -229 397 -229 ct 417 -229 440 -226 466 -221 ct +466 -221 466 -221 466 -174 ct 438 -183 414 -188 395 -188 ct 380 -188 370 -186 363 -183 ct +356 -180 352 -175 352 -169 ct 352 -165 355 -162 360 -158 ct 365 -154 372 -150 382 -146 ct +382 -146 382 -146 435 -124 ct 451 -118 463 -110 470 -100 ct 478 -91 482 -79 482 -66 ct +482 -45 473 -28 454 -15 ct 435 -2 411 5 381 5 ct 355 5 323 1 287 -8 ct p ef +532 82 m 532 82 532 82 532 -224 ct 532 -224 532 -224 593 -224 ct 593 -224 593 -224 591 -182 ct +591 -182 591 -182 593 -182 ct 603 -197 614 -209 625 -217 ct 637 -225 650 -229 664 -229 ct +690 -229 710 -219 726 -198 ct 741 -178 749 -151 749 -117 ct 749 -80 740 -50 723 -28 ct +706 -6 683 5 654 5 ct 642 5 630 3 620 -2 ct 610 -6 601 -13 593 -22 ct 593 -22 593 -22 591 -22 ct +591 -22 591 -22 593 0 ct 593 0 593 0 593 82 ct 593 82 593 82 532 82 ct p +593 -64 m 600 -56 607 -50 614 -47 ct 621 -43 629 -41 638 -41 ct 653 -41 664 -47 672 -60 ct +679 -72 683 -91 683 -116 ct 683 -135 680 -149 673 -159 ct 666 -168 657 -173 643 -173 ct +635 -173 626 -170 617 -164 ct 609 -158 601 -149 593 -136 ct 593 -136 593 -136 593 -64 ct +p ef +998 -95 m 998 -95 998 -95 846 -95 ct 849 -77 857 -63 869 -54 ct 881 -45 897 -41 918 -41 ct +942 -41 969 -46 998 -56 ct 998 -56 998 -56 998 -9 ct 963 0 932 5 906 5 ct 868 5 837 -6 814 -27 ct +791 -48 780 -76 780 -111 ct 780 -147 791 -175 812 -197 ct 834 -218 862 -229 897 -229 ct +929 -229 953 -219 971 -199 ct 989 -180 998 -152 998 -118 ct 998 -118 998 -118 998 -95 ct +p +845 -136 m 845 -136 845 -136 939 -136 ct 939 -153 935 -166 928 -175 ct 920 -184 909 -188 894 -188 ct +880 -188 868 -184 860 -175 ct 852 -166 847 -153 845 -136 ct p ef +1243 -4 m 1218 2 1193 5 1168 5 ct 1127 5 1094 -5 1071 -26 ct 1048 -47 1036 -75 1036 -111 ct +1036 -148 1047 -177 1070 -198 ct 1092 -219 1124 -229 1164 -229 ct 1194 -229 1220 -226 1243 -220 ct +1243 -220 1243 -220 1243 -175 ct 1218 -184 1195 -188 1172 -188 ct 1150 -188 1133 -182 1121 -169 ct +1108 -157 1102 -140 1102 -118 ct 1102 -94 1110 -74 1125 -60 ct 1140 -45 1160 -38 1185 -38 ct +1204 -38 1224 -42 1243 -49 ct 1243 -49 1243 -49 1243 -4 ct p ef +1498 -6 m 1474 1 1452 5 1434 5 ct 1405 5 1384 -1 1370 -14 ct 1356 -26 1349 -45 1349 -70 ct +1349 -70 1349 -70 1349 -178 ct 1349 -178 1349 -178 1301 -178 ct 1301 -178 1301 -178 1301 -219 ct +1301 -219 1301 -219 1349 -219 ct 1349 -219 1349 -219 1349 -285 ct 1349 -285 1349 -285 1410 -285 ct +1410 -285 1410 -285 1410 -219 ct 1410 -219 1410 -219 1493 -219 ct 1493 -219 1493 -219 1493 -178 ct +1493 -178 1493 -178 1410 -178 ct 1410 -178 1410 -178 1410 -84 ct 1410 -68 1413 -57 1419 -51 ct +1425 -44 1435 -41 1449 -41 ct 1466 -41 1482 -44 1498 -51 ct 1498 -51 1498 -51 1498 -6 ct +p ef +pom +gr +gs +pum +11721 3282 t +301 0 m 301 0 301 0 301 -306 ct 301 -306 301 -306 387 -306 ct 425 -306 452 -300 468 -287 ct +485 -274 493 -253 493 -224 ct 493 -192 482 -167 461 -149 ct 439 -131 410 -122 372 -122 ct +372 -122 372 -122 342 -122 ct 342 -122 342 -122 342 0 ct 342 0 342 0 301 0 ct p +342 -153 m 342 -153 342 -153 367 -153 ct 395 -153 416 -159 429 -171 ct 443 -183 450 -200 450 -224 ct +450 -241 444 -254 433 -262 ct 422 -271 405 -275 383 -275 ct 383 -275 383 -275 342 -275 ct +342 -275 342 -275 342 -153 ct p ef +572 0 m 572 0 572 0 572 -224 ct 572 -224 572 -224 613 -224 ct 613 -224 613 -224 611 -182 ct +611 -182 611 -182 613 -182 ct 623 -198 635 -209 649 -217 ct 663 -225 678 -229 696 -229 ct +708 -229 722 -227 737 -224 ct 737 -224 737 -224 737 -160 ct 737 -160 737 -160 706 -160 ct +706 -160 706 -160 706 -191 ct 700 -192 694 -193 689 -193 ct 675 -193 662 -189 650 -181 ct +637 -173 625 -161 613 -145 ct 613 -145 613 -145 613 0 ct 613 0 613 0 572 0 ct p ef +888 5 m 856 5 831 -6 812 -27 ct 793 -48 784 -76 784 -112 ct 784 -148 793 -177 812 -198 ct +831 -219 857 -229 890 -229 ct 922 -229 948 -219 967 -198 ct 986 -177 995 -149 995 -113 ct +995 -76 986 -47 967 -26 ct 948 -5 922 5 888 5 ct p +889 -26 m 910 -26 926 -33 936 -48 ct 947 -62 952 -84 952 -113 ct 952 -139 946 -160 935 -175 ct +924 -190 909 -198 890 -198 ct 870 -198 855 -190 844 -175 ct 833 -160 827 -139 827 -112 ct +827 -85 832 -64 843 -49 ct 854 -34 870 -26 889 -26 ct p ef +1052 2 m 1052 2 1052 2 1052 -326 ct 1052 -326 1052 -326 1093 -326 ct 1093 -326 1093 -326 1093 -224 ct +1093 -224 1093 -224 1091 -182 ct 1091 -182 1091 -182 1093 -182 ct 1103 -198 1114 -209 1126 -217 ct +1138 -225 1152 -229 1166 -229 ct 1191 -229 1211 -219 1226 -200 ct 1241 -180 1248 -153 1248 -120 ct +1248 -82 1239 -52 1222 -29 ct 1205 -6 1182 5 1154 5 ct 1142 5 1131 2 1121 -3 ct +1111 -8 1101 -15 1093 -26 ct 1093 -26 1093 -26 1091 -26 ct 1091 -26 1091 -26 1083 2 ct +1083 2 1083 2 1052 2 ct p +1093 -56 m 1102 -46 1112 -39 1121 -34 ct 1130 -29 1139 -26 1149 -26 ct 1167 -26 1180 -34 1190 -49 ct +1200 -65 1205 -87 1205 -115 ct 1205 -141 1201 -160 1193 -173 ct 1185 -186 1174 -193 1158 -193 ct +1146 -193 1135 -189 1124 -182 ct 1113 -175 1103 -165 1093 -151 ct 1093 -151 1093 -151 1093 -56 ct +p ef +1392 0 m 1392 -295 l 1305 -295 l 1305 -326 l 1433 -326 l 1433 0 l +1392 0 l p ef +1750 -9 m 1722 0 1696 5 1672 5 ct 1634 5 1605 -5 1584 -25 ct 1563 -45 1553 -73 1553 -110 ct +1553 -144 1563 -173 1583 -195 ct 1603 -218 1628 -229 1659 -229 ct 1690 -229 1712 -220 1727 -201 ct +1742 -182 1749 -153 1749 -114 ct 1749 -114 1749 -114 1749 -101 ct 1749 -101 1749 -101 1595 -101 ct +1596 -76 1604 -57 1618 -45 ct 1632 -32 1651 -26 1677 -26 ct 1700 -26 1724 -31 1750 -42 ct +1750 -42 1750 -42 1750 -9 ct p +1596 -132 m 1596 -132 1596 -132 1706 -132 ct 1706 -132 1706 -132 1706 -138 ct +1706 -158 1702 -173 1693 -183 ct 1684 -193 1672 -198 1655 -198 ct 1638 -198 1625 -192 1614 -181 ct +1604 -169 1598 -153 1596 -132 ct p ef +1797 0 m 1797 0 1797 0 1797 -224 ct 1797 -224 1797 -224 1833 -224 ct 1833 -224 1833 -224 1830 -182 ct +1830 -182 1830 -182 1833 -182 ct 1841 -198 1850 -209 1859 -217 ct 1867 -225 1875 -229 1883 -229 ct +1894 -229 1902 -225 1909 -216 ct 1916 -208 1920 -196 1921 -182 ct 1921 -182 1921 -182 1924 -182 ct +1931 -198 1939 -209 1947 -217 ct 1956 -225 1965 -229 1975 -229 ct 1988 -229 1998 -224 2005 -213 ct +2012 -202 2015 -186 2015 -164 ct 2015 -164 2015 -164 2015 0 ct 2015 0 2015 0 1979 0 ct +1979 0 1979 0 1979 -162 ct 1979 -172 1978 -180 1976 -185 ct 1974 -190 1970 -193 1966 -193 ct +1960 -193 1953 -189 1946 -181 ct 1939 -173 1931 -160 1924 -144 ct 1924 -144 1924 -144 1924 0 ct +1924 0 1924 0 1888 0 ct 1888 0 1888 0 1888 -155 ct 1888 -167 1887 -177 1885 -183 ct +1882 -190 1879 -193 1875 -193 ct 1869 -193 1862 -188 1854 -179 ct 1846 -170 1839 -158 1833 -144 ct +1833 -144 1833 -144 1833 0 ct 1833 0 1833 0 1797 0 ct p ef +2498 -326 m 2498 -326 2498 -326 2498 -295 ct 2498 -295 2498 -295 2482 -295 ct +2461 -295 2447 -293 2439 -287 ct 2430 -282 2426 -274 2426 -261 ct 2426 -257 2427 -251 2428 -242 ct +2428 -242 2428 -242 2432 -214 ct 2433 -204 2434 -196 2434 -190 ct 2434 -175 2431 -163 2424 -153 ct +2417 -144 2407 -137 2393 -132 ct 2407 -128 2417 -121 2424 -111 ct 2431 -102 2434 -90 2434 -75 ct +2434 -68 2433 -61 2432 -51 ct 2432 -51 2432 -51 2428 -23 ct 2427 -14 2426 -8 2426 -4 ct +2426 9 2430 17 2439 22 ct 2447 27 2461 30 2482 30 ct 2482 30 2482 30 2498 30 ct +2498 30 2498 30 2498 61 ct 2498 61 2498 61 2475 61 ct 2446 61 2424 56 2410 46 ct +2395 36 2388 21 2388 2 ct 2388 -7 2389 -16 2391 -26 ct 2391 -26 2391 -26 2398 -63 ct +2399 -68 2399 -74 2399 -79 ct 2399 -92 2395 -101 2387 -108 ct 2380 -114 2368 -117 2353 -117 ct +2353 -117 2353 -117 2334 -117 ct 2334 -117 2334 -117 2334 -148 ct 2334 -148 2334 -148 2353 -148 ct +2368 -148 2380 -151 2387 -157 ct 2395 -164 2399 -173 2399 -186 ct 2399 -191 2399 -197 2398 -202 ct +2398 -202 2398 -202 2391 -239 ct 2389 -249 2388 -258 2388 -267 ct 2388 -286 2395 -301 2410 -311 ct +2424 -321 2446 -326 2475 -326 ct 2475 -326 2475 -326 2498 -326 ct p ef +pom +gr +gs +pum +10197 3773 t +pom +gr +gs +pum +10705 3773 t +107 0 m 107 -275 l 5 -275 l 5 -306 l 250 -306 l 250 -275 l 148 -275 l +148 0 l 107 0 l p ef +426 -26 m 402 -5 377 5 353 5 ct 332 5 315 -1 302 -13 ct 289 -24 282 -39 282 -57 ct +282 -81 292 -99 313 -114 ct 334 -128 361 -135 395 -135 ct 395 -135 395 -135 420 -135 ct +420 -135 420 -135 420 -154 ct 420 -169 416 -180 409 -187 ct 401 -194 390 -198 375 -198 ct +351 -198 326 -191 301 -177 ct 301 -177 301 -177 301 -213 ct 330 -224 357 -229 383 -229 ct +412 -229 432 -223 443 -212 ct 455 -201 461 -181 461 -153 ct 461 -153 461 -153 461 -59 ct +461 -45 462 -36 465 -31 ct 468 -26 474 -24 481 -24 ct 484 -24 488 -25 494 -26 ct +494 -26 494 -26 498 -2 ct 484 3 474 5 467 5 ct 457 5 448 2 442 -3 ct 435 -8 430 -16 426 -26 ct +p +420 -53 m 420 -53 420 -53 420 -110 ct 420 -110 420 -110 408 -110 ct 380 -110 359 -106 345 -99 ct +331 -91 324 -80 324 -64 ct 324 -52 327 -43 334 -37 ct 340 -31 350 -28 363 -28 ct +381 -28 400 -36 420 -53 ct p ef +572 0 m 572 0 572 0 572 -224 ct 572 -224 572 -224 613 -224 ct 613 -224 613 -224 611 -182 ct +611 -182 611 -182 613 -182 ct 623 -198 635 -209 649 -217 ct 663 -225 678 -229 696 -229 ct +708 -229 722 -227 737 -224 ct 737 -224 737 -224 737 -160 ct 737 -160 737 -160 706 -160 ct +706 -160 706 -160 706 -191 ct 700 -192 694 -193 689 -193 ct 675 -193 662 -189 650 -181 ct +637 -173 625 -161 613 -145 ct 613 -145 613 -145 613 0 ct 613 0 613 0 572 0 ct p ef +805 75 m 805 75 805 75 809 41 ct 834 51 857 56 878 56 ct 900 56 916 51 925 42 ct +935 33 941 17 944 -6 ct 944 -6 944 -6 948 -46 ct 948 -46 948 -46 944 -46 ct 936 -31 925 -19 913 -12 ct +900 -4 886 0 870 0 ct 845 0 825 -10 810 -29 ct 795 -49 787 -75 787 -108 ct 787 -144 796 -173 813 -195 ct +831 -218 853 -229 881 -229 ct 903 -229 925 -219 946 -198 ct 946 -198 946 -198 949 -198 ct +949 -198 949 -198 949 -224 ct 949 -224 949 -224 985 -224 ct 985 -224 985 -224 985 -45 ct +985 -15 983 6 979 21 ct 975 36 968 49 957 60 ct 940 78 914 87 877 87 ct 856 87 832 83 805 75 ct +p +944 -80 m 944 -80 944 -80 944 -167 ct 926 -188 906 -198 887 -198 ct 868 -198 854 -191 844 -176 ct +835 -162 830 -140 830 -111 ct 830 -86 834 -67 842 -55 ct 851 -42 863 -36 880 -36 ct +892 -36 903 -40 914 -47 ct 925 -54 935 -65 944 -80 ct p ef +1242 -9 m 1214 0 1188 5 1164 5 ct 1126 5 1097 -5 1076 -25 ct 1055 -45 1045 -73 1045 -110 ct +1045 -144 1055 -173 1075 -195 ct 1095 -218 1120 -229 1151 -229 ct 1182 -229 1204 -220 1219 -201 ct +1234 -182 1241 -153 1241 -114 ct 1241 -114 1241 -114 1241 -101 ct 1241 -101 1241 -101 1087 -101 ct +1088 -76 1096 -57 1110 -45 ct 1124 -32 1143 -26 1169 -26 ct 1192 -26 1216 -31 1242 -42 ct +1242 -42 1242 -42 1242 -9 ct p +1088 -132 m 1088 -132 1088 -132 1198 -132 ct 1198 -132 1198 -132 1198 -138 ct +1198 -158 1194 -173 1185 -183 ct 1176 -193 1164 -198 1147 -198 ct 1130 -198 1117 -192 1106 -181 ct +1096 -169 1090 -153 1088 -132 ct p ef +1498 0 m 1478 3 1458 5 1439 5 ct 1406 5 1383 -1 1371 -13 ct 1359 -25 1353 -47 1353 -80 ct +1353 -80 1353 -80 1353 -188 ct 1353 -188 1353 -188 1297 -188 ct 1297 -188 1297 -188 1297 -219 ct +1297 -219 1297 -219 1353 -219 ct 1353 -219 1353 -219 1353 -267 ct 1353 -267 1353 -267 1394 -267 ct +1394 -267 1394 -267 1394 -219 ct 1394 -219 1394 -219 1493 -219 ct 1493 -219 1493 -219 1493 -188 ct +1493 -188 1493 -188 1394 -188 ct 1394 -188 1394 -188 1394 -74 ct 1394 -61 1395 -53 1396 -48 ct +1398 -43 1401 -39 1407 -35 ct 1416 -29 1429 -26 1447 -26 ct 1464 -26 1481 -28 1498 -31 ct +1498 -31 1498 -31 1498 0 ct p ef +1923 -234 m 1923 -234 1923 -234 1986 -262 ct 1986 -262 1986 -262 1999 -223 ct +1999 -223 1999 -223 1931 -209 ct 1931 -209 1931 -209 1931 -212 ct 1931 -219 1928 -227 1923 -234 ct +p +1929 -203 m 1929 -203 1929 -203 1976 -152 ct 1976 -152 1976 -152 1943 -128 ct +1943 -128 1943 -128 1909 -188 ct 1917 -191 1924 -196 1929 -203 ct p +1902 -188 m 1902 -188 1902 -188 1868 -128 ct 1868 -128 1868 -128 1835 -152 ct +1835 -152 1835 -152 1882 -203 ct 1887 -196 1894 -191 1902 -188 ct p +1880 -209 m 1880 -209 1880 -209 1812 -223 ct 1812 -223 1812 -223 1825 -262 ct +1825 -262 1825 -262 1888 -233 ct 1883 -226 1880 -219 1880 -212 ct 1880 -212 1880 -212 1880 -209 ct +p +1893 -237 m 1893 -237 1893 -237 1885 -306 ct 1885 -306 1885 -306 1926 -306 ct +1926 -306 1926 -306 1918 -237 ct 1913 -239 1909 -240 1906 -240 ct 1902 -240 1898 -239 1893 -237 ct +p ef +2154 0 m 2154 -295 l 2067 -295 l 2067 -326 l 2195 -326 l 2195 0 l +2154 0 l p ef +2458 -26 m 2434 -5 2409 5 2385 5 ct 2364 5 2347 -1 2334 -13 ct 2321 -24 2314 -39 2314 -57 ct +2314 -81 2324 -99 2345 -114 ct 2366 -128 2393 -135 2427 -135 ct 2427 -135 2427 -135 2452 -135 ct +2452 -135 2452 -135 2452 -154 ct 2452 -169 2448 -180 2441 -187 ct 2433 -194 2422 -198 2407 -198 ct +2383 -198 2358 -191 2333 -177 ct 2333 -177 2333 -177 2333 -213 ct 2362 -224 2389 -229 2415 -229 ct +2444 -229 2464 -223 2475 -212 ct 2487 -201 2493 -181 2493 -153 ct 2493 -153 2493 -153 2493 -59 ct +2493 -45 2494 -36 2497 -31 ct 2500 -26 2506 -24 2513 -24 ct 2516 -24 2520 -25 2526 -26 ct +2526 -26 2526 -26 2530 -2 ct 2516 3 2506 5 2499 5 ct 2489 5 2480 2 2474 -3 ct 2467 -8 2462 -16 2458 -26 ct +p +2452 -53 m 2452 -53 2452 -53 2452 -110 ct 2452 -110 2452 -110 2440 -110 ct +2412 -110 2391 -106 2377 -99 ct 2363 -91 2356 -80 2356 -64 ct 2356 -52 2359 -43 2366 -37 ct +2372 -31 2382 -28 2395 -28 ct 2413 -28 2432 -36 2452 -53 ct p ef +2579 -9 m 2579 -9 2579 -9 2579 -45 ct 2610 -32 2637 -26 2660 -26 ct 2676 -26 2690 -29 2701 -36 ct +2712 -43 2717 -51 2717 -61 ct 2717 -74 2704 -84 2679 -93 ct 2679 -93 2679 -93 2636 -107 ct +2602 -118 2585 -138 2585 -165 ct 2585 -186 2593 -201 2608 -212 ct 2623 -223 2645 -229 2673 -229 ct +2694 -229 2718 -226 2746 -219 ct 2746 -219 2746 -219 2746 -186 ct 2719 -194 2695 -198 2673 -198 ct +2657 -198 2644 -196 2636 -191 ct 2628 -186 2624 -179 2624 -169 ct 2624 -158 2634 -149 2654 -142 ct +2654 -142 2654 -142 2706 -124 ct 2741 -111 2758 -91 2758 -64 ct 2758 -43 2749 -26 2732 -14 ct +2714 -1 2691 5 2661 5 ct 2636 5 2608 0 2579 -9 ct p ef +3022 0 m 3002 3 2982 5 2963 5 ct 2930 5 2907 -1 2895 -13 ct 2883 -25 2877 -47 2877 -80 ct +2877 -80 2877 -80 2877 -188 ct 2877 -188 2877 -188 2821 -188 ct 2821 -188 2821 -188 2821 -219 ct +2821 -219 2821 -219 2877 -219 ct 2877 -219 2877 -219 2877 -267 ct 2877 -267 2877 -267 2918 -267 ct +2918 -267 2918 -267 2918 -219 ct 2918 -219 2918 -219 3017 -219 ct 3017 -219 3017 -219 3017 -188 ct +3017 -188 3017 -188 2918 -188 ct 2918 -188 2918 -188 2918 -74 ct 2918 -61 2919 -53 2920 -48 ct +2922 -43 2925 -39 2931 -35 ct 2940 -29 2953 -26 2971 -26 ct 2988 -26 3005 -28 3022 -31 ct +3022 -31 3022 -31 3022 0 ct p ef +3048 31 m 3048 0 l 3303 0 l 3303 31 l 3048 31 l p ef +3399 66 m 3399 66 3399 66 3399 46 ct 3406 45 3412 41 3416 33 ct 3421 25 3423 14 3424 0 ct +3424 0 3424 0 3399 0 ct 3399 0 3399 0 3399 -61 ct 3399 -61 3399 -61 3460 -61 ct +3460 -61 3460 -61 3460 -24 ct 3460 5 3455 27 3445 42 ct 3435 57 3419 65 3399 66 ct +p +3399 -163 m 3399 -224 l 3460 -224 l 3460 -163 l 3399 -163 l p ef +pom +gr +gs +pum +10197 4264 t +pom +gr +gs +pum +10705 4264 t +0.003 0.003 1.000 c 153 -24 m 146 -14 137 -7 127 -2 ct 117 3 106 5 93 5 ct 71 5 53 -2 39 -15 ct +25 -28 18 -45 18 -65 ct 18 -91 28 -111 47 -124 ct 67 -137 96 -143 135 -143 ct 135 -143 135 -143 159 -143 ct +159 -143 159 -143 159 -154 ct 159 -165 155 -174 147 -179 ct 139 -185 127 -188 111 -188 ct +89 -188 64 -182 37 -169 ct 37 -169 37 -169 37 -214 ct 65 -224 93 -229 122 -229 ct +154 -229 178 -223 194 -211 ct 204 -203 211 -194 215 -185 ct 218 -175 220 -160 220 -140 ct +220 -140 220 -140 220 -64 ct 220 -49 225 -41 234 -41 ct 236 -41 238 -41 241 -42 ct +241 -42 241 -42 241 -2 ct 229 3 217 5 207 5 ct 196 5 186 3 178 -2 ct 170 -7 164 -14 159 -24 ct +159 -24 159 -24 153 -24 ct p +159 -65 m 159 -65 159 -65 159 -102 ct 159 -102 159 -102 137 -102 ct 118 -102 103 -99 94 -94 ct +84 -88 79 -80 79 -69 ct 79 -61 82 -54 88 -49 ct 94 -44 101 -41 110 -41 ct 125 -41 142 -49 159 -65 ct +p ef +428 0 m 428 0 428 0 430 -42 ct 430 -42 430 -42 428 -42 ct 418 -27 407 -15 395 -7 ct +384 1 371 5 357 5 ct 331 5 311 -5 295 -26 ct 280 -46 272 -73 272 -107 ct 272 -144 281 -174 298 -196 ct +315 -218 338 -229 367 -229 ct 379 -229 390 -227 400 -222 ct 410 -218 419 -211 428 -203 ct +428 -203 428 -203 430 -203 ct 430 -203 430 -203 428 -224 ct 428 -224 428 -224 428 -326 ct +428 -326 428 -326 489 -326 ct 489 -326 489 -326 489 0 ct 489 0 489 0 428 0 ct p +428 -160 m 421 -168 414 -173 407 -177 ct 400 -181 392 -183 384 -183 ct 368 -183 357 -177 349 -164 ct +342 -152 338 -133 338 -108 ct 338 -89 341 -75 348 -65 ct 355 -56 365 -51 378 -51 ct +387 -51 395 -54 404 -60 ct 412 -66 420 -75 428 -88 ct 428 -88 428 -88 428 -160 ct +p ef +606 0 m 517 -224 l 583 -224 l 645 -67 l 706 -224 l 755 -224 l 667 0 l +606 0 l p ef +884 0 m 884 -183 l 802 -183 l 802 -224 l 945 -224 l 945 0 l 884 0 l +p +884 -265 m 884 -326 l 945 -326 l 945 -265 l 884 -265 l p ef +1243 -4 m 1218 2 1193 5 1168 5 ct 1127 5 1094 -5 1071 -26 ct 1048 -47 1036 -75 1036 -111 ct +1036 -148 1047 -177 1070 -198 ct 1092 -219 1124 -229 1164 -229 ct 1194 -229 1220 -226 1243 -220 ct +1243 -220 1243 -220 1243 -175 ct 1218 -184 1195 -188 1172 -188 ct 1150 -188 1133 -182 1121 -169 ct +1108 -157 1102 -140 1102 -118 ct 1102 -94 1110 -74 1125 -60 ct 1140 -45 1160 -38 1185 -38 ct +1204 -38 1224 -42 1243 -49 ct 1243 -49 1243 -49 1243 -4 ct p ef +1506 -95 m 1506 -95 1506 -95 1354 -95 ct 1357 -77 1365 -63 1377 -54 ct 1389 -45 1405 -41 1426 -41 ct +1450 -41 1477 -46 1506 -56 ct 1506 -56 1506 -56 1506 -9 ct 1471 0 1440 5 1414 5 ct +1376 5 1345 -6 1322 -27 ct 1299 -48 1288 -76 1288 -111 ct 1288 -147 1299 -175 1320 -197 ct +1342 -218 1370 -229 1405 -229 ct 1437 -229 1461 -219 1479 -199 ct 1497 -180 1506 -152 1506 -118 ct +1506 -118 1506 -118 1506 -95 ct p +1353 -136 m 1353 -136 1353 -136 1447 -136 ct 1447 -153 1443 -166 1436 -175 ct +1428 -184 1417 -188 1402 -188 ct 1388 -188 1376 -184 1368 -175 ct 1360 -166 1355 -153 1353 -136 ct +p ef +pom +gr +gs +pum +12229 4264 t +305 -214 m 305 -214 305 -214 305 -260 ct 305 -282 309 -298 318 -309 ct 326 -320 339 -326 356 -326 ct +356 -326 356 -326 356 -306 ct 349 -306 343 -303 339 -298 ct 336 -293 334 -286 334 -276 ct +334 -276 334 -276 334 -265 ct 334 -265 334 -265 356 -265 ct 356 -265 356 -265 356 -214 ct +356 -214 356 -214 305 -214 ct p +407 -214 m 407 -214 407 -214 407 -260 ct 407 -282 411 -298 420 -309 ct 428 -320 441 -326 458 -326 ct +458 -326 458 -326 458 -306 ct 451 -306 445 -303 441 -298 ct 438 -293 436 -286 436 -276 ct +436 -276 436 -276 436 -265 ct 436 -265 436 -265 458 -265 ct 458 -265 458 -265 458 -214 ct +458 -214 458 -214 407 -214 ct p ef +615 0 m 615 -275 l 513 -275 l 513 -306 l 758 -306 l 758 -275 l 656 -275 l +656 0 l 615 0 l p ef +934 -26 m 910 -5 885 5 861 5 ct 840 5 823 -1 810 -13 ct 797 -24 790 -39 790 -57 ct +790 -81 800 -99 821 -114 ct 842 -128 869 -135 903 -135 ct 903 -135 903 -135 928 -135 ct +928 -135 928 -135 928 -154 ct 928 -169 924 -180 917 -187 ct 909 -194 898 -198 883 -198 ct +859 -198 834 -191 809 -177 ct 809 -177 809 -177 809 -213 ct 838 -224 865 -229 891 -229 ct +920 -229 940 -223 951 -212 ct 963 -201 969 -181 969 -153 ct 969 -153 969 -153 969 -59 ct +969 -45 970 -36 973 -31 ct 976 -26 982 -24 989 -24 ct 992 -24 996 -25 1002 -26 ct +1002 -26 1002 -26 1006 -2 ct 992 3 982 5 975 5 ct 965 5 956 2 950 -3 ct 943 -8 938 -16 934 -26 ct +p +928 -53 m 928 -53 928 -53 928 -110 ct 928 -110 928 -110 916 -110 ct 888 -110 867 -106 853 -99 ct +839 -91 832 -80 832 -64 ct 832 -52 835 -43 842 -37 ct 848 -31 858 -28 871 -28 ct +889 -28 908 -36 928 -53 ct p ef +1080 0 m 1080 0 1080 0 1080 -224 ct 1080 -224 1080 -224 1121 -224 ct 1121 -224 1121 -224 1119 -182 ct +1119 -182 1119 -182 1121 -182 ct 1131 -198 1143 -209 1157 -217 ct 1171 -225 1186 -229 1204 -229 ct +1216 -229 1230 -227 1245 -224 ct 1245 -224 1245 -224 1245 -160 ct 1245 -160 1245 -160 1214 -160 ct +1214 -160 1214 -160 1214 -191 ct 1208 -192 1202 -193 1197 -193 ct 1183 -193 1170 -189 1158 -181 ct +1145 -173 1133 -161 1121 -145 ct 1121 -145 1121 -145 1121 0 ct 1121 0 1121 0 1080 0 ct +p ef +1313 75 m 1313 75 1313 75 1317 41 ct 1342 51 1365 56 1386 56 ct 1408 56 1424 51 1433 42 ct +1443 33 1449 17 1452 -6 ct 1452 -6 1452 -6 1456 -46 ct 1456 -46 1456 -46 1452 -46 ct +1444 -31 1433 -19 1421 -12 ct 1408 -4 1394 0 1378 0 ct 1353 0 1333 -10 1318 -29 ct +1303 -49 1295 -75 1295 -108 ct 1295 -144 1304 -173 1321 -195 ct 1339 -218 1361 -229 1389 -229 ct +1411 -229 1433 -219 1454 -198 ct 1454 -198 1454 -198 1457 -198 ct 1457 -198 1457 -198 1457 -224 ct +1457 -224 1457 -224 1493 -224 ct 1493 -224 1493 -224 1493 -45 ct 1493 -15 1491 6 1487 21 ct +1483 36 1476 49 1465 60 ct 1448 78 1422 87 1385 87 ct 1364 87 1340 83 1313 75 ct +p +1452 -80 m 1452 -80 1452 -80 1452 -167 ct 1434 -188 1414 -198 1395 -198 ct +1376 -198 1362 -191 1352 -176 ct 1343 -162 1338 -140 1338 -111 ct 1338 -86 1342 -67 1350 -55 ct +1359 -42 1371 -36 1388 -36 ct 1400 -36 1411 -40 1422 -47 ct 1433 -54 1443 -65 1452 -80 ct +p ef +1750 -9 m 1722 0 1696 5 1672 5 ct 1634 5 1605 -5 1584 -25 ct 1563 -45 1553 -73 1553 -110 ct +1553 -144 1563 -173 1583 -195 ct 1603 -218 1628 -229 1659 -229 ct 1690 -229 1712 -220 1727 -201 ct +1742 -182 1749 -153 1749 -114 ct 1749 -114 1749 -114 1749 -101 ct 1749 -101 1749 -101 1595 -101 ct +1596 -76 1604 -57 1618 -45 ct 1632 -32 1651 -26 1677 -26 ct 1700 -26 1724 -31 1750 -42 ct +1750 -42 1750 -42 1750 -9 ct p +1596 -132 m 1596 -132 1596 -132 1706 -132 ct 1706 -132 1706 -132 1706 -138 ct +1706 -158 1702 -173 1693 -183 ct 1684 -193 1672 -198 1655 -198 ct 1638 -198 1625 -192 1614 -181 ct +1604 -169 1598 -153 1596 -132 ct p ef +2006 0 m 1986 3 1966 5 1947 5 ct 1914 5 1891 -1 1879 -13 ct 1867 -25 1861 -47 1861 -80 ct +1861 -80 1861 -80 1861 -188 ct 1861 -188 1861 -188 1805 -188 ct 1805 -188 1805 -188 1805 -219 ct +1805 -219 1805 -219 1861 -219 ct 1861 -219 1861 -219 1861 -267 ct 1861 -267 1861 -267 1902 -267 ct +1902 -267 1902 -267 1902 -219 ct 1902 -219 1902 -219 2001 -219 ct 2001 -219 2001 -219 2001 -188 ct +2001 -188 2001 -188 1902 -188 ct 1902 -188 1902 -188 1902 -74 ct 1902 -61 1903 -53 1904 -48 ct +1906 -43 1909 -39 1915 -35 ct 1924 -29 1937 -26 1955 -26 ct 1972 -26 1989 -28 2006 -31 ct +2006 -31 2006 -31 2006 0 ct p ef +2083 -214 m 2083 -214 2083 -214 2083 -260 ct 2083 -282 2087 -298 2096 -309 ct +2104 -320 2117 -326 2134 -326 ct 2134 -326 2134 -326 2134 -306 ct 2127 -306 2121 -303 2117 -298 ct +2114 -293 2112 -286 2112 -276 ct 2112 -276 2112 -276 2112 -265 ct 2112 -265 2112 -265 2134 -265 ct +2134 -265 2134 -265 2134 -214 ct 2134 -214 2134 -214 2083 -214 ct p +2185 -214 m 2185 -214 2185 -214 2185 -260 ct 2185 -282 2189 -298 2198 -309 ct +2206 -320 2219 -326 2236 -326 ct 2236 -326 2236 -326 2236 -306 ct 2229 -306 2223 -303 2219 -298 ct +2216 -293 2214 -286 2214 -276 ct 2214 -276 2214 -276 2214 -265 ct 2214 -265 2214 -265 2236 -265 ct +2236 -265 2236 -265 2236 -214 ct 2236 -214 2236 -214 2185 -214 ct p ef +2383 -163 m 2383 -224 l 2444 -224 l 2444 -163 l 2383 -163 l p +2383 0 m 2383 -61 l 2444 -61 l 2444 0 l 2383 0 l p ef +pom +gr +gs +pum +15023 4264 t +0.003 0.003 1.000 c 33 -8 m 33 -8 33 -8 33 -54 ct 67 -42 95 -36 115 -36 ct 130 -36 141 -38 149 -42 ct +156 -46 160 -52 160 -60 ct 160 -64 158 -68 154 -72 ct 151 -75 145 -79 138 -82 ct +138 -82 138 -82 90 -101 ct 71 -109 57 -118 48 -127 ct 39 -137 34 -148 34 -161 ct +34 -182 44 -199 63 -211 ct 82 -223 109 -229 143 -229 ct 163 -229 186 -226 212 -221 ct +212 -221 212 -221 212 -174 ct 184 -183 160 -188 141 -188 ct 126 -188 116 -186 109 -183 ct +102 -180 98 -175 98 -169 ct 98 -165 101 -162 106 -158 ct 111 -154 118 -150 128 -146 ct +128 -146 128 -146 181 -124 ct 197 -118 209 -110 216 -100 ct 224 -91 228 -79 228 -66 ct +228 -45 219 -28 200 -15 ct 181 -2 157 5 127 5 ct 101 5 69 1 33 -8 ct p ef +356 0 m 356 -285 l 274 -285 l 274 -326 l 417 -326 l 417 0 l 356 0 l +p ef +630 0 m 630 -183 l 548 -183 l 548 -224 l 691 -224 l 691 0 l 630 0 l +p +630 -265 m 630 -326 l 691 -326 l 691 -265 l 630 -265 l p ef +989 -4 m 964 2 939 5 914 5 ct 873 5 840 -5 817 -26 ct 794 -47 782 -75 782 -111 ct +782 -148 793 -177 816 -198 ct 838 -219 870 -229 910 -229 ct 940 -229 966 -226 989 -220 ct +989 -220 989 -220 989 -175 ct 964 -184 941 -188 918 -188 ct 896 -188 879 -182 867 -169 ct +854 -157 848 -140 848 -118 ct 848 -94 856 -74 871 -60 ct 886 -45 906 -38 931 -38 ct +950 -38 970 -42 989 -49 ct 989 -49 989 -49 989 -4 ct p ef +1252 -95 m 1252 -95 1252 -95 1100 -95 ct 1103 -77 1111 -63 1123 -54 ct 1135 -45 1151 -41 1172 -41 ct +1196 -41 1223 -46 1252 -56 ct 1252 -56 1252 -56 1252 -9 ct 1217 0 1186 5 1160 5 ct +1122 5 1091 -6 1068 -27 ct 1045 -48 1034 -76 1034 -111 ct 1034 -147 1045 -175 1066 -197 ct +1088 -218 1116 -229 1151 -229 ct 1183 -229 1207 -219 1225 -199 ct 1243 -180 1252 -152 1252 -118 ct +1252 -118 1252 -118 1252 -95 ct p +1099 -136 m 1099 -136 1099 -136 1193 -136 ct 1193 -153 1189 -166 1182 -175 ct +1174 -184 1163 -188 1148 -188 ct 1134 -188 1122 -184 1114 -175 ct 1106 -166 1101 -153 1099 -136 ct +p ef +1751 -4 m 1726 2 1701 5 1676 5 ct 1635 5 1602 -5 1579 -26 ct 1556 -47 1544 -75 1544 -111 ct +1544 -148 1555 -177 1578 -198 ct 1600 -219 1632 -229 1672 -229 ct 1702 -229 1728 -226 1751 -220 ct +1751 -220 1751 -220 1751 -175 ct 1726 -184 1703 -188 1680 -188 ct 1658 -188 1641 -182 1629 -169 ct +1616 -157 1610 -140 1610 -118 ct 1610 -94 1618 -74 1633 -60 ct 1648 -45 1668 -38 1693 -38 ct +1712 -38 1732 -42 1751 -49 ct 1751 -49 1751 -49 1751 -4 ct p ef +1880 0 m 1880 -285 l 1798 -285 l 1798 -326 l 1941 -326 l 1941 0 l +1880 0 l p ef +2185 -24 m 2178 -14 2169 -7 2159 -2 ct 2149 3 2138 5 2125 5 ct 2103 5 2085 -2 2071 -15 ct +2057 -28 2050 -45 2050 -65 ct 2050 -91 2060 -111 2079 -124 ct 2099 -137 2128 -143 2167 -143 ct +2167 -143 2167 -143 2191 -143 ct 2191 -143 2191 -143 2191 -154 ct 2191 -165 2187 -174 2179 -179 ct +2171 -185 2159 -188 2143 -188 ct 2121 -188 2096 -182 2069 -169 ct 2069 -169 2069 -169 2069 -214 ct +2097 -224 2125 -229 2154 -229 ct 2186 -229 2210 -223 2226 -211 ct 2236 -203 2243 -194 2247 -185 ct +2250 -175 2252 -160 2252 -140 ct 2252 -140 2252 -140 2252 -64 ct 2252 -49 2257 -41 2266 -41 ct +2268 -41 2270 -41 2273 -42 ct 2273 -42 2273 -42 2273 -2 ct 2261 3 2249 5 2239 5 ct +2228 5 2218 3 2210 -2 ct 2202 -7 2196 -14 2191 -24 ct 2191 -24 2191 -24 2185 -24 ct +p +2191 -65 m 2191 -65 2191 -65 2191 -102 ct 2191 -102 2191 -102 2169 -102 ct +2150 -102 2135 -99 2126 -94 ct 2116 -88 2111 -80 2111 -69 ct 2111 -61 2114 -54 2120 -49 ct +2126 -44 2133 -41 2142 -41 ct 2157 -41 2174 -49 2191 -65 ct p ef +2319 -8 m 2319 -8 2319 -8 2319 -54 ct 2353 -42 2381 -36 2401 -36 ct 2416 -36 2427 -38 2435 -42 ct +2442 -46 2446 -52 2446 -60 ct 2446 -64 2444 -68 2440 -72 ct 2437 -75 2431 -79 2424 -82 ct +2424 -82 2424 -82 2376 -101 ct 2357 -109 2343 -118 2334 -127 ct 2325 -137 2320 -148 2320 -161 ct +2320 -182 2330 -199 2349 -211 ct 2368 -223 2395 -229 2429 -229 ct 2449 -229 2472 -226 2498 -221 ct +2498 -221 2498 -221 2498 -174 ct 2470 -183 2446 -188 2427 -188 ct 2412 -188 2402 -186 2395 -183 ct +2388 -180 2384 -175 2384 -169 ct 2384 -165 2387 -162 2392 -158 ct 2397 -154 2404 -150 2414 -146 ct +2414 -146 2414 -146 2467 -124 ct 2483 -118 2495 -110 2502 -100 ct 2510 -91 2514 -79 2514 -66 ct +2514 -45 2505 -28 2486 -15 ct 2467 -2 2443 5 2413 5 ct 2387 5 2355 1 2319 -8 ct +p ef +2573 -8 m 2573 -8 2573 -8 2573 -54 ct 2607 -42 2635 -36 2655 -36 ct 2670 -36 2681 -38 2689 -42 ct +2696 -46 2700 -52 2700 -60 ct 2700 -64 2698 -68 2694 -72 ct 2691 -75 2685 -79 2678 -82 ct +2678 -82 2678 -82 2630 -101 ct 2611 -109 2597 -118 2588 -127 ct 2579 -137 2574 -148 2574 -161 ct +2574 -182 2584 -199 2603 -211 ct 2622 -223 2649 -229 2683 -229 ct 2703 -229 2726 -226 2752 -221 ct +2752 -221 2752 -221 2752 -174 ct 2724 -183 2700 -188 2681 -188 ct 2666 -188 2656 -186 2649 -183 ct +2642 -180 2638 -175 2638 -169 ct 2638 -165 2641 -162 2646 -158 ct 2651 -154 2658 -150 2668 -146 ct +2668 -146 2668 -146 2721 -124 ct 2737 -118 2749 -110 2756 -100 ct 2764 -91 2768 -79 2768 -66 ct +2768 -45 2759 -28 2740 -15 ct 2721 -2 2697 5 2667 5 ct 2641 5 2609 1 2573 -8 ct +p ef +pom +gr +gs +pum +17817 4264 t +466 -326 m 466 -326 466 -326 466 -295 ct 466 -295 466 -295 450 -295 ct 429 -295 415 -293 407 -287 ct +398 -282 394 -274 394 -261 ct 394 -257 395 -251 396 -242 ct 396 -242 396 -242 400 -214 ct +401 -204 402 -196 402 -190 ct 402 -175 399 -163 392 -153 ct 385 -144 375 -137 361 -132 ct +375 -128 385 -121 392 -111 ct 399 -102 402 -90 402 -75 ct 402 -68 401 -61 400 -51 ct +400 -51 400 -51 396 -23 ct 395 -14 394 -8 394 -4 ct 394 9 398 17 407 22 ct 415 27 429 30 450 30 ct +450 30 450 30 466 30 ct 466 30 466 30 466 61 ct 466 61 466 61 443 61 ct 414 61 392 56 378 46 ct +363 36 356 21 356 2 ct 356 -7 357 -16 359 -26 ct 359 -26 359 -26 366 -63 ct 367 -68 367 -74 367 -79 ct +367 -92 363 -101 355 -108 ct 348 -114 336 -117 321 -117 ct 321 -117 321 -117 302 -117 ct +302 -117 302 -117 302 -148 ct 302 -148 302 -148 321 -148 ct 336 -148 348 -151 355 -157 ct +363 -164 367 -173 367 -186 ct 367 -191 367 -197 366 -202 ct 366 -202 366 -202 359 -239 ct +357 -249 356 -258 356 -267 ct 356 -286 363 -301 378 -311 ct 392 -321 414 -326 443 -326 ct +443 -326 443 -326 466 -326 ct p ef +pom +gr +gs +pum +10197 4755 t +pom +gr +gs +pum +11213 4755 t +0.003 0.003 1.000 c 98 0 m 9 -224 l 75 -224 l 137 -67 l 198 -224 l 247 -224 l +159 0 l 98 0 l p ef +380 5 m 346 5 318 -6 297 -27 ct 276 -49 265 -77 265 -112 ct 265 -148 276 -176 297 -197 ct +318 -218 346 -229 382 -229 ct 417 -229 445 -218 466 -197 ct 487 -176 498 -148 498 -112 ct +498 -76 487 -48 466 -27 ct 445 -6 416 5 380 5 ct p +381 -36 m 398 -36 411 -42 419 -55 ct 428 -68 432 -87 432 -112 ct 432 -138 428 -156 419 -169 ct +411 -182 398 -188 382 -188 ct 365 -188 352 -182 344 -169 ct 335 -156 331 -137 331 -112 ct +331 -87 335 -68 343 -55 ct 352 -42 364 -36 381 -36 ct p ef +630 0 m 630 -183 l 548 -183 l 548 -224 l 691 -224 l 691 0 l 630 0 l +p +630 -265 m 630 -326 l 691 -326 l 691 -265 l 630 -265 l p ef +936 0 m 936 0 936 0 938 -42 ct 938 -42 938 -42 936 -42 ct 926 -27 915 -15 903 -7 ct +892 1 879 5 865 5 ct 839 5 819 -5 803 -26 ct 788 -46 780 -73 780 -107 ct 780 -144 789 -174 806 -196 ct +823 -218 846 -229 875 -229 ct 887 -229 898 -227 908 -222 ct 918 -218 927 -211 936 -203 ct +936 -203 936 -203 938 -203 ct 938 -203 938 -203 936 -224 ct 936 -224 936 -224 936 -326 ct +936 -326 936 -326 997 -326 ct 997 -326 997 -326 997 0 ct 997 0 997 0 936 0 ct p +936 -160 m 929 -168 922 -173 915 -177 ct 908 -181 900 -183 892 -183 ct 876 -183 865 -177 857 -164 ct +850 -152 846 -133 846 -108 ct 846 -89 849 -75 856 -65 ct 863 -56 873 -51 886 -51 ct +895 -51 903 -54 912 -60 ct 920 -66 928 -75 936 -88 ct 936 -88 936 -88 936 -160 ct +p ef +pom +gr +gs +pum +12229 4755 t +436 0 m 436 0 436 0 438 -42 ct 438 -42 438 -42 436 -42 ct 426 -26 415 -15 403 -7 ct +390 1 377 5 362 5 ct 337 5 317 -5 302 -24 ct 287 -44 280 -71 280 -105 ct 280 -142 289 -172 306 -195 ct +324 -218 346 -229 374 -229 ct 386 -229 398 -226 408 -221 ct 418 -216 428 -209 436 -198 ct +436 -198 436 -198 438 -198 ct 438 -198 438 -198 436 -229 ct 436 -229 436 -229 436 -326 ct +436 -326 436 -326 477 -326 ct 477 -326 477 -326 477 0 ct 477 0 477 0 436 0 ct p +436 -168 m 426 -178 417 -185 408 -190 ct 398 -195 389 -198 380 -198 ct 362 -198 348 -190 338 -175 ct +328 -159 323 -137 323 -109 ct 323 -83 327 -63 335 -50 ct 343 -38 354 -31 370 -31 ct +382 -31 393 -35 404 -42 ct 415 -49 426 -59 436 -73 ct 436 -73 436 -73 436 -168 ct +p ef +726 -224 m 726 -224 726 -224 726 0 ct 726 0 726 0 685 0 ct 685 0 685 0 687 -42 ct +687 -42 687 -42 685 -42 ct 676 -26 664 -15 652 -7 ct 639 1 624 5 608 5 ct 587 5 571 -1 560 -14 ct +549 -27 544 -46 544 -71 ct 544 -71 544 -71 544 -224 ct 544 -224 544 -224 585 -224 ct +585 -224 585 -224 585 -82 ct 585 -65 588 -52 593 -45 ct 599 -38 608 -34 621 -34 ct +631 -34 641 -38 652 -45 ct 663 -52 674 -63 685 -78 ct 685 -78 685 -78 685 -224 ct +685 -224 685 -224 726 -224 ct p ef +781 0 m 781 0 781 0 781 -224 ct 781 -224 781 -224 817 -224 ct 817 -224 817 -224 814 -182 ct +814 -182 814 -182 817 -182 ct 825 -198 834 -209 843 -217 ct 851 -225 859 -229 867 -229 ct +878 -229 886 -225 893 -216 ct 900 -208 904 -196 905 -182 ct 905 -182 905 -182 908 -182 ct +915 -198 923 -209 931 -217 ct 940 -225 949 -229 959 -229 ct 972 -229 982 -224 989 -213 ct +996 -202 999 -186 999 -164 ct 999 -164 999 -164 999 0 ct 999 0 999 0 963 0 ct 963 0 963 0 963 -162 ct +963 -172 962 -180 960 -185 ct 958 -190 954 -193 950 -193 ct 944 -193 937 -189 930 -181 ct +923 -173 915 -160 908 -144 ct 908 -144 908 -144 908 0 ct 908 0 908 0 872 0 ct 872 0 872 0 872 -155 ct +872 -167 871 -177 869 -183 ct 866 -190 863 -193 859 -193 ct 853 -193 846 -188 838 -179 ct +830 -170 823 -158 817 -144 ct 817 -144 817 -144 817 0 ct 817 0 817 0 781 0 ct p ef +1053 82 m 1053 82 1053 82 1053 -224 ct 1053 -224 1053 -224 1094 -224 ct 1094 -224 1094 -224 1092 -182 ct +1092 -182 1092 -182 1094 -182 ct 1104 -198 1115 -209 1127 -217 ct 1139 -225 1153 -229 1167 -229 ct +1192 -229 1212 -219 1227 -200 ct 1242 -180 1249 -153 1249 -120 ct 1249 -82 1240 -52 1223 -29 ct +1206 -6 1183 5 1155 5 ct 1143 5 1132 2 1122 -3 ct 1112 -8 1102 -15 1094 -26 ct +1094 -26 1094 -26 1092 -26 ct 1092 -26 1092 -26 1094 5 ct 1094 5 1094 5 1094 82 ct +1094 82 1094 82 1053 82 ct p +1094 -56 m 1103 -46 1113 -39 1122 -34 ct 1131 -29 1140 -26 1150 -26 ct 1168 -26 1181 -34 1191 -49 ct +1201 -65 1206 -87 1206 -115 ct 1206 -141 1202 -160 1194 -173 ct 1186 -186 1175 -193 1159 -193 ct +1148 -193 1136 -189 1125 -182 ct 1115 -175 1104 -165 1094 -151 ct 1094 -151 1094 -151 1094 -56 ct +p ef +1748 61 m 1703 56 1667 36 1638 -1 ct 1609 -37 1595 -81 1595 -133 ct 1595 -184 1609 -228 1638 -264 ct +1667 -301 1703 -321 1748 -326 ct 1748 -326 1748 -326 1748 -298 ct 1712 -291 1684 -273 1665 -244 ct +1646 -216 1636 -178 1636 -133 ct 1636 -87 1646 -49 1665 -21 ct 1684 8 1712 26 1748 33 ct +1748 33 1748 33 1748 61 ct p ef +1809 61 m 1854 56 1890 36 1919 -1 ct 1948 -37 1962 -81 1962 -133 ct 1962 -184 1948 -228 1919 -264 ct +1890 -301 1854 -321 1809 -326 ct 1809 -326 1809 -326 1809 -298 ct 1845 -291 1873 -273 1892 -244 ct +1911 -216 1921 -178 1921 -133 ct 1921 -87 1911 -49 1892 -21 ct 1873 8 1845 26 1809 33 ct +1809 33 1809 33 1809 61 ct p ef +2498 -326 m 2498 -326 2498 -326 2498 -295 ct 2498 -295 2498 -295 2482 -295 ct +2461 -295 2447 -293 2439 -287 ct 2430 -282 2426 -274 2426 -261 ct 2426 -257 2427 -251 2428 -242 ct +2428 -242 2428 -242 2432 -214 ct 2433 -204 2434 -196 2434 -190 ct 2434 -175 2431 -163 2424 -153 ct +2417 -144 2407 -137 2393 -132 ct 2407 -128 2417 -121 2424 -111 ct 2431 -102 2434 -90 2434 -75 ct +2434 -68 2433 -61 2432 -51 ct 2432 -51 2432 -51 2428 -23 ct 2427 -14 2426 -8 2426 -4 ct +2426 9 2430 17 2439 22 ct 2447 27 2461 30 2482 30 ct 2482 30 2482 30 2498 30 ct +2498 30 2498 30 2498 61 ct 2498 61 2498 61 2475 61 ct 2446 61 2424 56 2410 46 ct +2395 36 2388 21 2388 2 ct 2388 -7 2389 -16 2391 -26 ct 2391 -26 2391 -26 2398 -63 ct +2399 -68 2399 -74 2399 -79 ct 2399 -92 2395 -101 2387 -108 ct 2380 -114 2368 -117 2353 -117 ct +2353 -117 2353 -117 2334 -117 ct 2334 -117 2334 -117 2334 -148 ct 2334 -148 2334 -148 2353 -148 ct +2368 -148 2380 -151 2387 -157 ct 2395 -164 2399 -173 2399 -186 ct 2399 -191 2399 -197 2398 -202 ct +2398 -202 2398 -202 2391 -239 ct 2389 -249 2388 -258 2388 -267 ct 2388 -286 2395 -301 2410 -311 ct +2424 -321 2446 -326 2475 -326 ct 2475 -326 2475 -326 2498 -326 ct p ef +pom +gr +gs +pum +10197 5246 t +pom +gr +gs +pum +11721 5246 t +0.003 0.503 0.003 c 239 -326 m 65 61 l 15 61 l 189 -326 l 239 -326 l +p ef +493 -326 m 319 61 l 269 61 l 443 -326 l 493 -326 l p ef +786 82 m 786 82 786 82 786 -224 ct 786 -224 786 -224 847 -224 ct 847 -224 847 -224 845 -182 ct +845 -182 845 -182 847 -182 ct 857 -197 868 -209 879 -217 ct 891 -225 904 -229 918 -229 ct +944 -229 964 -219 980 -198 ct 995 -178 1003 -151 1003 -117 ct 1003 -80 994 -50 977 -28 ct +960 -6 937 5 908 5 ct 896 5 884 3 874 -2 ct 864 -6 855 -13 847 -22 ct 847 -22 847 -22 845 -22 ct +845 -22 845 -22 847 0 ct 847 0 847 0 847 82 ct 847 82 847 82 786 82 ct p +847 -64 m 854 -56 861 -50 868 -47 ct 875 -43 883 -41 892 -41 ct 907 -41 918 -47 926 -60 ct +933 -72 937 -91 937 -116 ct 937 -135 934 -149 927 -159 ct 920 -168 911 -173 897 -173 ct +889 -173 880 -170 871 -164 ct 863 -158 855 -149 847 -136 ct 847 -136 847 -136 847 -64 ct +p ef +1062 0 m 1062 0 1062 0 1062 -224 ct 1062 -224 1062 -224 1123 -224 ct 1123 -224 1123 -224 1121 -181 ct +1121 -181 1121 -181 1123 -181 ct 1133 -197 1145 -209 1159 -217 ct 1172 -225 1188 -229 1206 -229 ct +1217 -229 1232 -227 1248 -224 ct 1248 -224 1248 -224 1248 -149 ct 1248 -149 1248 -149 1207 -149 ct +1207 -149 1207 -149 1207 -173 ct 1202 -174 1199 -174 1196 -174 ct 1181 -174 1168 -170 1155 -163 ct +1143 -156 1132 -145 1123 -130 ct 1123 -130 1123 -130 1123 0 ct 1123 0 1123 0 1062 0 ct +p ef +1392 0 m 1392 -183 l 1310 -183 l 1310 -224 l 1453 -224 l 1453 0 l +1392 0 l p +1392 -265 m 1392 -326 l 1453 -326 l 1453 -265 l 1392 -265 l p ef +1553 0 m 1553 0 1553 0 1553 -224 ct 1553 -224 1553 -224 1614 -224 ct 1614 -224 1614 -224 1613 -202 ct +1613 -202 1613 -202 1612 -181 ct 1612 -181 1612 -181 1614 -181 ct 1621 -197 1630 -209 1642 -217 ct +1654 -225 1668 -229 1686 -229 ct 1708 -229 1724 -223 1735 -210 ct 1746 -197 1752 -178 1752 -153 ct +1752 -153 1752 -153 1752 0 ct 1752 0 1752 0 1691 0 ct 1691 0 1691 0 1691 -139 ct +1691 -150 1689 -159 1685 -165 ct 1680 -170 1674 -173 1665 -173 ct 1656 -173 1647 -170 1638 -165 ct +1630 -159 1621 -151 1614 -139 ct 1614 -139 1614 -139 1614 0 ct 1614 0 1614 0 1553 0 ct +p ef +2006 -6 m 1982 1 1960 5 1942 5 ct 1913 5 1892 -1 1878 -14 ct 1864 -26 1857 -45 1857 -70 ct +1857 -70 1857 -70 1857 -178 ct 1857 -178 1857 -178 1809 -178 ct 1809 -178 1809 -178 1809 -219 ct +1809 -219 1809 -219 1857 -219 ct 1857 -219 1857 -219 1857 -285 ct 1857 -285 1857 -285 1918 -285 ct +1918 -285 1918 -285 1918 -219 ct 1918 -219 1918 -219 2001 -219 ct 2001 -219 2001 -219 2001 -178 ct +2001 -178 2001 -178 1918 -178 ct 1918 -178 1918 -178 1918 -84 ct 1918 -68 1921 -57 1927 -51 ct +1933 -44 1943 -41 1957 -41 ct 1974 -41 1990 -44 2006 -51 ct 2006 -51 2006 -51 2006 -6 ct +p ef +2412 5 m 2378 5 2350 -6 2329 -27 ct 2308 -49 2297 -77 2297 -112 ct 2297 -148 2308 -176 2329 -197 ct +2350 -218 2378 -229 2414 -229 ct 2449 -229 2477 -218 2498 -197 ct 2519 -176 2530 -148 2530 -112 ct +2530 -76 2519 -48 2498 -27 ct 2477 -6 2448 5 2412 5 ct p +2413 -36 m 2430 -36 2443 -42 2451 -55 ct 2460 -68 2464 -87 2464 -112 ct 2464 -138 2460 -156 2451 -169 ct +2443 -182 2430 -188 2414 -188 ct 2397 -188 2384 -182 2376 -169 ct 2367 -156 2363 -137 2363 -112 ct +2363 -87 2367 -68 2375 -55 ct 2384 -42 2396 -36 2413 -36 ct p ef +2565 0 m 2565 0 2565 0 2565 -326 ct 2565 -326 2565 -326 2626 -326 ct 2626 -326 2626 -326 2626 -224 ct +2626 -224 2626 -224 2624 -182 ct 2624 -182 2624 -182 2626 -182 ct 2636 -197 2647 -209 2658 -217 ct +2670 -225 2683 -229 2697 -229 ct 2723 -229 2743 -219 2759 -198 ct 2774 -178 2782 -151 2782 -117 ct +2782 -80 2773 -50 2756 -28 ct 2739 -6 2716 5 2687 5 ct 2675 5 2663 3 2653 -2 ct +2643 -6 2634 -13 2626 -22 ct 2626 -22 2626 -22 2624 -22 ct 2624 -22 2624 -22 2616 0 ct +2616 0 2616 0 2565 0 ct p +2626 -64 m 2633 -56 2640 -50 2647 -47 ct 2654 -43 2662 -41 2671 -41 ct 2686 -41 2697 -47 2705 -60 ct +2712 -72 2716 -91 2716 -116 ct 2716 -135 2713 -149 2706 -159 ct 2699 -168 2690 -173 2676 -173 ct +2668 -173 2659 -170 2650 -164 ct 2642 -158 2634 -149 2626 -136 ct 2626 -136 2626 -136 2626 -64 ct +p ef +2819 78 m 2819 78 2819 78 2819 30 ct 2844 41 2866 46 2884 46 ct 2899 46 2909 42 2914 34 ct +2919 26 2921 11 2921 -13 ct 2921 -13 2921 -13 2921 -183 ct 2921 -183 2921 -183 2839 -183 ct +2839 -183 2839 -183 2839 -224 ct 2839 -224 2839 -224 2982 -224 ct 2982 -224 2982 -224 2982 -16 ct +2982 7 2980 24 2977 35 ct 2974 46 2968 56 2959 64 ct 2942 79 2919 87 2890 87 ct +2871 87 2847 84 2819 78 ct p +2921 -265 m 2921 -326 l 2982 -326 l 2982 -265 l 2921 -265 l p ef +3284 -95 m 3284 -95 3284 -95 3132 -95 ct 3135 -77 3143 -63 3155 -54 ct 3167 -45 3183 -41 3204 -41 ct +3228 -41 3255 -46 3284 -56 ct 3284 -56 3284 -56 3284 -9 ct 3249 0 3218 5 3192 5 ct +3154 5 3123 -6 3100 -27 ct 3077 -48 3066 -76 3066 -111 ct 3066 -147 3077 -175 3098 -197 ct +3120 -218 3148 -229 3183 -229 ct 3215 -229 3239 -219 3257 -199 ct 3275 -180 3284 -152 3284 -118 ct +3284 -118 3284 -118 3284 -95 ct p +3131 -136 m 3131 -136 3131 -136 3225 -136 ct 3225 -153 3221 -166 3214 -175 ct +3206 -184 3195 -188 3180 -188 ct 3166 -188 3154 -184 3146 -175 ct 3138 -166 3133 -153 3131 -136 ct +p ef +3529 -4 m 3504 2 3479 5 3454 5 ct 3413 5 3380 -5 3357 -26 ct 3334 -47 3322 -75 3322 -111 ct +3322 -148 3333 -177 3356 -198 ct 3378 -219 3410 -229 3450 -229 ct 3480 -229 3506 -226 3529 -220 ct +3529 -220 3529 -220 3529 -175 ct 3504 -184 3481 -188 3458 -188 ct 3436 -188 3419 -182 3407 -169 ct +3394 -157 3388 -140 3388 -118 ct 3388 -94 3396 -74 3411 -60 ct 3426 -45 3446 -38 3471 -38 ct +3490 -38 3510 -42 3529 -49 ct 3529 -49 3529 -49 3529 -4 ct p ef +3784 -6 m 3760 1 3738 5 3720 5 ct 3691 5 3670 -1 3656 -14 ct 3642 -26 3635 -45 3635 -70 ct +3635 -70 3635 -70 3635 -178 ct 3635 -178 3635 -178 3587 -178 ct 3587 -178 3587 -178 3587 -219 ct +3587 -219 3587 -219 3635 -219 ct 3635 -219 3635 -219 3635 -285 ct 3635 -285 3635 -285 3696 -285 ct +3696 -285 3696 -285 3696 -219 ct 3696 -219 3696 -219 3779 -219 ct 3779 -219 3779 -219 3779 -178 ct +3779 -178 3779 -178 3696 -178 ct 3696 -178 3696 -178 3696 -84 ct 3696 -68 3699 -57 3705 -51 ct +3711 -44 3721 -41 3735 -41 ct 3752 -41 3768 -44 3784 -51 ct 3784 -51 3784 -51 3784 -6 ct +p ef +3902 61 m 3902 61 3902 61 3902 33 ct 3911 32 3918 30 3923 26 ct 3928 22 3930 17 3930 10 ct +3930 10 3930 10 3930 0 ct 3930 0 3930 0 3902 0 ct 3902 0 3902 0 3902 -71 ct 3902 -71 3902 -71 3973 -71 ct +3973 -71 3973 -71 3973 -14 ct 3973 14 3968 33 3957 44 ct 3947 55 3928 61 3902 61 ct +p ef +4347 0 m 4347 0 4347 0 4347 -224 ct 4347 -224 4347 -224 4408 -224 ct 4408 -224 4408 -224 4407 -202 ct +4407 -202 4407 -202 4406 -181 ct 4406 -181 4406 -181 4408 -181 ct 4415 -197 4424 -209 4436 -217 ct +4448 -225 4462 -229 4480 -229 ct 4502 -229 4518 -223 4529 -210 ct 4540 -197 4546 -178 4546 -153 ct +4546 -153 4546 -153 4546 0 ct 4546 0 4546 0 4485 0 ct 4485 0 4485 0 4485 -139 ct +4485 -150 4483 -159 4479 -165 ct 4474 -170 4468 -173 4459 -173 ct 4450 -173 4441 -170 4432 -165 ct +4424 -159 4415 -151 4408 -139 ct 4408 -139 4408 -139 4408 0 ct 4408 0 4408 0 4347 0 ct +p ef +4808 -95 m 4808 -95 4808 -95 4656 -95 ct 4659 -77 4667 -63 4679 -54 ct 4691 -45 4707 -41 4728 -41 ct +4752 -41 4779 -46 4808 -56 ct 4808 -56 4808 -56 4808 -9 ct 4773 0 4742 5 4716 5 ct +4678 5 4647 -6 4624 -27 ct 4601 -48 4590 -76 4590 -111 ct 4590 -147 4601 -175 4622 -197 ct +4644 -218 4672 -229 4707 -229 ct 4739 -229 4763 -219 4781 -199 ct 4799 -180 4808 -152 4808 -118 ct +4808 -118 4808 -118 4808 -95 ct p +4655 -136 m 4655 -136 4655 -136 4749 -136 ct 4749 -153 4745 -166 4738 -175 ct +4730 -184 4719 -188 4704 -188 ct 4690 -188 4678 -184 4670 -175 ct 4662 -166 4657 -153 4655 -136 ct +p ef +5062 -95 m 5062 -95 5062 -95 4910 -95 ct 4913 -77 4921 -63 4933 -54 ct 4945 -45 4961 -41 4982 -41 ct +5006 -41 5033 -46 5062 -56 ct 5062 -56 5062 -56 5062 -9 ct 5027 0 4996 5 4970 5 ct +4932 5 4901 -6 4878 -27 ct 4855 -48 4844 -76 4844 -111 ct 4844 -147 4855 -175 4876 -197 ct +4898 -218 4926 -229 4961 -229 ct 4993 -229 5017 -219 5035 -199 ct 5053 -180 5062 -152 5062 -118 ct +5062 -118 5062 -118 5062 -95 ct p +4909 -136 m 4909 -136 4909 -136 5003 -136 ct 5003 -153 4999 -166 4992 -175 ct +4984 -184 4973 -188 4958 -188 ct 4944 -188 4932 -184 4924 -175 ct 4916 -166 4911 -153 4909 -136 ct +p ef +5254 0 m 5254 0 5254 0 5256 -42 ct 5256 -42 5256 -42 5254 -42 ct 5244 -27 5233 -15 5221 -7 ct +5210 1 5197 5 5183 5 ct 5157 5 5137 -5 5121 -26 ct 5106 -46 5098 -73 5098 -107 ct +5098 -144 5107 -174 5124 -196 ct 5141 -218 5164 -229 5193 -229 ct 5205 -229 5216 -227 5226 -222 ct +5236 -218 5245 -211 5254 -203 ct 5254 -203 5254 -203 5256 -203 ct 5256 -203 5256 -203 5254 -224 ct +5254 -224 5254 -224 5254 -326 ct 5254 -326 5254 -326 5315 -326 ct 5315 -326 5315 -326 5315 0 ct +5315 0 5315 0 5254 0 ct p +5254 -160 m 5247 -168 5240 -173 5233 -177 ct 5226 -181 5218 -183 5210 -183 ct +5194 -183 5183 -177 5175 -164 ct 5168 -152 5164 -133 5164 -108 ct 5164 -89 5167 -75 5174 -65 ct +5181 -56 5191 -51 5204 -51 ct 5213 -51 5221 -54 5230 -60 ct 5238 -66 5246 -75 5254 -88 ct +5254 -88 5254 -88 5254 -160 ct p ef +5367 -8 m 5367 -8 5367 -8 5367 -54 ct 5401 -42 5429 -36 5449 -36 ct 5464 -36 5475 -38 5483 -42 ct +5490 -46 5494 -52 5494 -60 ct 5494 -64 5492 -68 5488 -72 ct 5485 -75 5479 -79 5472 -82 ct +5472 -82 5472 -82 5424 -101 ct 5405 -109 5391 -118 5382 -127 ct 5373 -137 5368 -148 5368 -161 ct +5368 -182 5378 -199 5397 -211 ct 5416 -223 5443 -229 5477 -229 ct 5497 -229 5520 -226 5546 -221 ct +5546 -221 5546 -221 5546 -174 ct 5518 -183 5494 -188 5475 -188 ct 5460 -188 5450 -186 5443 -183 ct +5436 -180 5432 -175 5432 -169 ct 5432 -165 5435 -162 5440 -158 ct 5445 -154 5452 -150 5462 -146 ct +5462 -146 5462 -146 5515 -124 ct 5531 -118 5543 -110 5550 -100 ct 5558 -91 5562 -79 5562 -66 ct +5562 -45 5553 -28 5534 -15 ct 5515 -2 5491 5 5461 5 ct 5435 5 5403 1 5367 -8 ct +p ef +5875 -8 m 5875 -8 5875 -8 5875 -54 ct 5909 -42 5937 -36 5957 -36 ct 5972 -36 5983 -38 5991 -42 ct +5998 -46 6002 -52 6002 -60 ct 6002 -64 6000 -68 5996 -72 ct 5993 -75 5987 -79 5980 -82 ct +5980 -82 5980 -82 5932 -101 ct 5913 -109 5899 -118 5890 -127 ct 5881 -137 5876 -148 5876 -161 ct +5876 -182 5886 -199 5905 -211 ct 5924 -223 5951 -229 5985 -229 ct 6005 -229 6028 -226 6054 -221 ct +6054 -221 6054 -221 6054 -174 ct 6026 -183 6002 -188 5983 -188 ct 5968 -188 5958 -186 5951 -183 ct +5944 -180 5940 -175 5940 -169 ct 5940 -165 5943 -162 5948 -158 ct 5953 -154 5960 -150 5970 -146 ct +5970 -146 5970 -146 6023 -124 ct 6039 -118 6051 -110 6058 -100 ct 6066 -91 6070 -79 6070 -66 ct +6070 -45 6061 -28 6042 -15 ct 6023 -2 5999 5 5969 5 ct 5943 5 5911 1 5875 -8 ct +p ef +6324 -6 m 6300 1 6278 5 6260 5 ct 6231 5 6210 -1 6196 -14 ct 6182 -26 6175 -45 6175 -70 ct +6175 -70 6175 -70 6175 -178 ct 6175 -178 6175 -178 6127 -178 ct 6127 -178 6127 -178 6127 -219 ct +6127 -219 6127 -219 6175 -219 ct 6175 -219 6175 -219 6175 -285 ct 6175 -285 6175 -285 6236 -285 ct +6236 -285 6236 -285 6236 -219 ct 6236 -219 6236 -219 6319 -219 ct 6319 -219 6319 -219 6319 -178 ct +6319 -178 6319 -178 6236 -178 ct 6236 -178 6236 -178 6236 -84 ct 6236 -68 6239 -57 6245 -51 ct +6251 -44 6261 -41 6275 -41 ct 6292 -41 6308 -44 6324 -51 ct 6324 -51 6324 -51 6324 -6 ct +p ef +6524 0 m 6524 0 6524 0 6526 -42 ct 6526 -42 6526 -42 6524 -42 ct 6514 -27 6503 -15 6491 -7 ct +6480 1 6467 5 6453 5 ct 6427 5 6407 -5 6391 -26 ct 6376 -46 6368 -73 6368 -107 ct +6368 -144 6377 -174 6394 -196 ct 6411 -218 6434 -229 6463 -229 ct 6475 -229 6486 -227 6496 -222 ct +6506 -218 6515 -211 6524 -203 ct 6524 -203 6524 -203 6526 -203 ct 6526 -203 6526 -203 6524 -224 ct +6524 -224 6524 -224 6524 -326 ct 6524 -326 6524 -326 6585 -326 ct 6585 -326 6585 -326 6585 0 ct +6585 0 6585 0 6524 0 ct p +6524 -160 m 6517 -168 6510 -173 6503 -177 ct 6496 -181 6488 -183 6480 -183 ct +6464 -183 6453 -177 6445 -164 ct 6438 -152 6434 -133 6434 -108 ct 6434 -89 6437 -75 6444 -65 ct +6451 -56 6461 -51 6474 -51 ct 6483 -51 6491 -54 6500 -60 ct 6508 -66 6516 -75 6524 -88 ct +6524 -88 6524 -88 6524 -160 ct p ef +6726 0 m 6726 -183 l 6644 -183 l 6644 -224 l 6787 -224 l 6787 0 l +6726 0 l p +6726 -265 m 6726 -326 l 6787 -326 l 6787 -265 l 6726 -265 l p ef +6984 5 m 6950 5 6922 -6 6901 -27 ct 6880 -49 6869 -77 6869 -112 ct 6869 -148 6880 -176 6901 -197 ct +6922 -218 6950 -229 6986 -229 ct 7021 -229 7049 -218 7070 -197 ct 7091 -176 7102 -148 7102 -112 ct +7102 -76 7091 -48 7070 -27 ct 7049 -6 7020 5 6984 5 ct p +6985 -36 m 7002 -36 7015 -42 7023 -55 ct 7032 -68 7036 -87 7036 -112 ct 7036 -138 7032 -156 7023 -169 ct +7015 -182 7002 -188 6986 -188 ct 6969 -188 6956 -182 6948 -169 ct 6939 -156 6935 -137 6935 -112 ct +6935 -87 6939 -68 6947 -55 ct 6956 -42 6968 -36 6985 -36 ct p ef +pom +gr +gs +pum +10197 5737 t +pom +gr +gs +pum +11213 5737 t +43 -326 m 43 -326 43 -326 43 -295 ct 43 -295 43 -295 59 -295 ct 80 -295 94 -293 102 -287 ct +111 -282 115 -274 115 -261 ct 115 -257 114 -251 113 -242 ct 113 -242 113 -242 109 -214 ct +108 -204 107 -196 107 -190 ct 107 -175 110 -163 117 -153 ct 124 -144 134 -137 148 -132 ct +134 -128 124 -121 117 -111 ct 110 -102 107 -90 107 -75 ct 107 -68 108 -61 109 -51 ct +109 -51 109 -51 113 -23 ct 114 -14 115 -8 115 -4 ct 115 9 111 17 102 22 ct 94 27 80 30 59 30 ct +59 30 59 30 43 30 ct 43 30 43 30 43 61 ct 43 61 43 61 66 61 ct 95 61 117 56 131 46 ct +146 36 153 21 153 2 ct 153 -7 152 -16 150 -26 ct 150 -26 150 -26 143 -63 ct 142 -68 142 -74 142 -79 ct +142 -92 146 -101 154 -108 ct 161 -114 173 -117 188 -117 ct 188 -117 188 -117 207 -117 ct +207 -117 207 -117 207 -148 ct 207 -148 207 -148 188 -148 ct 173 -148 161 -151 154 -157 ct +146 -164 142 -173 142 -186 ct 142 -191 142 -197 143 -202 ct 143 -202 143 -202 150 -239 ct +152 -249 153 -258 153 -267 ct 153 -286 146 -301 131 -311 ct 117 -321 95 -326 66 -326 ct +66 -326 66 -326 43 -326 ct p ef +pom +gr +gs +pum +10197 6228 t +pom +gr +gs +pum +10705 6228 t +43 -326 m 43 -326 43 -326 43 -295 ct 43 -295 43 -295 59 -295 ct 80 -295 94 -293 102 -287 ct +111 -282 115 -274 115 -261 ct 115 -257 114 -251 113 -242 ct 113 -242 113 -242 109 -214 ct +108 -204 107 -196 107 -190 ct 107 -175 110 -163 117 -153 ct 124 -144 134 -137 148 -132 ct +134 -128 124 -121 117 -111 ct 110 -102 107 -90 107 -75 ct 107 -68 108 -61 109 -51 ct +109 -51 109 -51 113 -23 ct 114 -14 115 -8 115 -4 ct 115 9 111 17 102 22 ct 94 27 80 30 59 30 ct +59 30 59 30 43 30 ct 43 30 43 30 43 61 ct 43 61 43 61 66 61 ct 95 61 117 56 131 46 ct +146 36 153 21 153 2 ct 153 -7 152 -16 150 -26 ct 150 -26 150 -26 143 -63 ct 142 -68 142 -74 142 -79 ct +142 -92 146 -101 154 -108 ct 161 -114 173 -117 188 -117 ct 188 -117 188 -117 207 -117 ct +207 -117 207 -117 207 -148 ct 207 -148 207 -148 188 -148 ct 173 -148 161 -151 154 -157 ct +146 -164 142 -173 142 -186 ct 142 -191 142 -197 143 -202 ct 143 -202 143 -202 150 -239 ct +152 -249 153 -258 153 -267 ct 153 -286 146 -301 131 -311 ct 117 -321 95 -326 66 -326 ct +66 -326 66 -326 43 -326 ct p ef +351 66 m 351 66 351 66 351 46 ct 358 45 364 41 368 33 ct 373 25 375 14 376 0 ct +376 0 376 0 351 0 ct 351 0 351 0 351 -61 ct 351 -61 351 -61 412 -61 ct 412 -61 412 -61 412 -24 ct +412 5 407 27 397 42 ct 387 57 371 65 351 66 ct p +351 -163 m 351 -224 l 412 -224 l 412 -163 l 351 -163 l p ef +pom +gr +gs +pum +10197 6719 t +pom +gr +gs +pum +10705 6719 t +0.003 0.003 1.000 c 153 -24 m 146 -14 137 -7 127 -2 ct 117 3 106 5 93 5 ct 71 5 53 -2 39 -15 ct +25 -28 18 -45 18 -65 ct 18 -91 28 -111 47 -124 ct 67 -137 96 -143 135 -143 ct 135 -143 135 -143 159 -143 ct +159 -143 159 -143 159 -154 ct 159 -165 155 -174 147 -179 ct 139 -185 127 -188 111 -188 ct +89 -188 64 -182 37 -169 ct 37 -169 37 -169 37 -214 ct 65 -224 93 -229 122 -229 ct +154 -229 178 -223 194 -211 ct 204 -203 211 -194 215 -185 ct 218 -175 220 -160 220 -140 ct +220 -140 220 -140 220 -64 ct 220 -49 225 -41 234 -41 ct 236 -41 238 -41 241 -42 ct +241 -42 241 -42 241 -2 ct 229 3 217 5 207 5 ct 196 5 186 3 178 -2 ct 170 -7 164 -14 159 -24 ct +159 -24 159 -24 153 -24 ct p +159 -65 m 159 -65 159 -65 159 -102 ct 159 -102 159 -102 137 -102 ct 118 -102 103 -99 94 -94 ct +84 -88 79 -80 79 -69 ct 79 -61 82 -54 88 -49 ct 94 -44 101 -41 110 -41 ct 125 -41 142 -49 159 -65 ct +p ef +428 0 m 428 0 428 0 430 -42 ct 430 -42 430 -42 428 -42 ct 418 -27 407 -15 395 -7 ct +384 1 371 5 357 5 ct 331 5 311 -5 295 -26 ct 280 -46 272 -73 272 -107 ct 272 -144 281 -174 298 -196 ct +315 -218 338 -229 367 -229 ct 379 -229 390 -227 400 -222 ct 410 -218 419 -211 428 -203 ct +428 -203 428 -203 430 -203 ct 430 -203 430 -203 428 -224 ct 428 -224 428 -224 428 -326 ct +428 -326 428 -326 489 -326 ct 489 -326 489 -326 489 0 ct 489 0 489 0 428 0 ct p +428 -160 m 421 -168 414 -173 407 -177 ct 400 -181 392 -183 384 -183 ct 368 -183 357 -177 349 -164 ct +342 -152 338 -133 338 -108 ct 338 -89 341 -75 348 -65 ct 355 -56 365 -51 378 -51 ct +387 -51 395 -54 404 -60 ct 412 -66 420 -75 428 -88 ct 428 -88 428 -88 428 -160 ct +p ef +606 0 m 517 -224 l 583 -224 l 645 -67 l 706 -224 l 755 -224 l 667 0 l +606 0 l p ef +884 0 m 884 -183 l 802 -183 l 802 -224 l 945 -224 l 945 0 l 884 0 l +p +884 -265 m 884 -326 l 945 -326 l 945 -265 l 884 -265 l p ef +1243 -4 m 1218 2 1193 5 1168 5 ct 1127 5 1094 -5 1071 -26 ct 1048 -47 1036 -75 1036 -111 ct +1036 -148 1047 -177 1070 -198 ct 1092 -219 1124 -229 1164 -229 ct 1194 -229 1220 -226 1243 -220 ct +1243 -220 1243 -220 1243 -175 ct 1218 -184 1195 -188 1172 -188 ct 1150 -188 1133 -182 1121 -169 ct +1108 -157 1102 -140 1102 -118 ct 1102 -94 1110 -74 1125 -60 ct 1140 -45 1160 -38 1185 -38 ct +1204 -38 1224 -42 1243 -49 ct 1243 -49 1243 -49 1243 -4 ct p ef +1506 -95 m 1506 -95 1506 -95 1354 -95 ct 1357 -77 1365 -63 1377 -54 ct 1389 -45 1405 -41 1426 -41 ct +1450 -41 1477 -46 1506 -56 ct 1506 -56 1506 -56 1506 -9 ct 1471 0 1440 5 1414 5 ct +1376 5 1345 -6 1322 -27 ct 1299 -48 1288 -76 1288 -111 ct 1288 -147 1299 -175 1320 -197 ct +1342 -218 1370 -229 1405 -229 ct 1437 -229 1461 -219 1479 -199 ct 1497 -180 1506 -152 1506 -118 ct +1506 -118 1506 -118 1506 -95 ct p +1353 -136 m 1353 -136 1353 -136 1447 -136 ct 1447 -153 1443 -166 1436 -175 ct +1428 -184 1417 -188 1402 -188 ct 1388 -188 1376 -184 1368 -175 ct 1360 -166 1355 -153 1353 -136 ct +p ef +pom +gr +gs +pum +12229 6719 t +480 -9 m 452 0 426 5 402 5 ct 364 5 335 -5 314 -25 ct 293 -45 283 -73 283 -110 ct +283 -144 293 -173 313 -195 ct 333 -218 358 -229 389 -229 ct 420 -229 442 -220 457 -201 ct +472 -182 479 -153 479 -114 ct 479 -114 479 -114 479 -101 ct 479 -101 479 -101 325 -101 ct +326 -76 334 -57 348 -45 ct 362 -32 381 -26 407 -26 ct 430 -26 454 -31 480 -42 ct +480 -42 480 -42 480 -9 ct p +326 -132 m 326 -132 326 -132 436 -132 ct 436 -132 436 -132 436 -138 ct 436 -158 432 -173 423 -183 ct +414 -193 402 -198 385 -198 ct 368 -198 355 -192 344 -181 ct 334 -169 328 -153 326 -132 ct +p ef +527 0 m 611 -112 l 527 -224 l 578 -224 l 640 -141 l 696 -224 l 737 -224 l +660 -114 l 746 0 l 695 0 l 632 -84 l 568 0 l 527 0 l p ef +988 -9 m 960 0 934 5 910 5 ct 872 5 843 -5 822 -25 ct 801 -45 791 -73 791 -110 ct +791 -144 801 -173 821 -195 ct 841 -218 866 -229 897 -229 ct 928 -229 950 -220 965 -201 ct +980 -182 987 -153 987 -114 ct 987 -114 987 -114 987 -101 ct 987 -101 987 -101 833 -101 ct +834 -76 842 -57 856 -45 ct 870 -32 889 -26 915 -26 ct 938 -26 962 -31 988 -42 ct +988 -42 988 -42 988 -9 ct p +834 -132 m 834 -132 834 -132 944 -132 ct 944 -132 944 -132 944 -138 ct 944 -158 940 -173 931 -183 ct +922 -193 910 -198 893 -198 ct 876 -198 863 -192 852 -181 ct 842 -169 836 -153 834 -132 ct +p ef +1244 -7 m 1220 1 1196 5 1172 5 ct 1133 5 1103 -5 1082 -26 ct 1061 -46 1050 -75 1050 -112 ct +1050 -149 1060 -177 1081 -198 ct 1102 -219 1131 -229 1168 -229 ct 1192 -229 1216 -225 1240 -218 ct +1240 -218 1240 -218 1240 -184 ct 1213 -193 1191 -198 1172 -198 ct 1148 -198 1128 -190 1114 -175 ct +1100 -160 1093 -139 1093 -112 ct 1093 -85 1100 -64 1115 -49 ct 1130 -34 1151 -26 1177 -26 ct +1197 -26 1219 -31 1244 -40 ct 1244 -40 1244 -40 1244 -7 ct p ef +1488 -224 m 1488 -224 1488 -224 1488 0 ct 1488 0 1488 0 1447 0 ct 1447 0 1447 0 1449 -42 ct +1449 -42 1449 -42 1447 -42 ct 1438 -26 1426 -15 1414 -7 ct 1401 1 1386 5 1370 5 ct +1349 5 1333 -1 1322 -14 ct 1311 -27 1306 -46 1306 -71 ct 1306 -71 1306 -71 1306 -224 ct +1306 -224 1306 -224 1347 -224 ct 1347 -224 1347 -224 1347 -82 ct 1347 -65 1350 -52 1355 -45 ct +1361 -38 1370 -34 1383 -34 ct 1393 -34 1403 -38 1414 -45 ct 1425 -52 1436 -63 1447 -78 ct +1447 -78 1447 -78 1447 -224 ct 1447 -224 1447 -224 1488 -224 ct p ef +1752 0 m 1732 3 1712 5 1693 5 ct 1660 5 1637 -1 1625 -13 ct 1613 -25 1607 -47 1607 -80 ct +1607 -80 1607 -80 1607 -188 ct 1607 -188 1607 -188 1551 -188 ct 1551 -188 1551 -188 1551 -219 ct +1551 -219 1551 -219 1607 -219 ct 1607 -219 1607 -219 1607 -267 ct 1607 -267 1607 -267 1648 -267 ct +1648 -267 1648 -267 1648 -219 ct 1648 -219 1648 -219 1747 -219 ct 1747 -219 1747 -219 1747 -188 ct +1747 -188 1747 -188 1648 -188 ct 1648 -188 1648 -188 1648 -74 ct 1648 -61 1649 -53 1650 -48 ct +1652 -43 1655 -39 1661 -35 ct 1670 -29 1683 -26 1701 -26 ct 1718 -26 1735 -28 1752 -31 ct +1752 -31 1752 -31 1752 0 ct p ef +1895 0 m 1895 -193 l 1813 -193 l 1813 -224 l 1936 -224 l 1936 0 l +1895 0 l p +1890 -275 m 1890 -326 l 1941 -326 l 1941 -275 l 1890 -275 l p ef +2158 5 m 2126 5 2101 -6 2082 -27 ct 2063 -48 2054 -76 2054 -112 ct 2054 -148 2063 -177 2082 -198 ct +2101 -219 2127 -229 2160 -229 ct 2192 -229 2218 -219 2237 -198 ct 2256 -177 2265 -149 2265 -113 ct +2265 -76 2256 -47 2237 -26 ct 2218 -5 2192 5 2158 5 ct p +2159 -26 m 2180 -26 2196 -33 2206 -48 ct 2217 -62 2222 -84 2222 -113 ct 2222 -139 2216 -160 2205 -175 ct +2194 -190 2179 -198 2160 -198 ct 2140 -198 2125 -190 2114 -175 ct 2103 -160 2097 -139 2097 -112 ct +2097 -85 2102 -64 2113 -49 ct 2124 -34 2140 -26 2159 -26 ct p ef +2323 0 m 2323 0 2323 0 2323 -224 ct 2323 -224 2323 -224 2364 -224 ct 2364 -224 2364 -224 2362 -182 ct +2362 -182 2362 -182 2364 -182 ct 2374 -198 2385 -209 2398 -217 ct 2410 -225 2425 -229 2441 -229 ct +2462 -229 2478 -223 2489 -210 ct 2500 -197 2505 -178 2505 -153 ct 2505 -153 2505 -153 2505 0 ct +2505 0 2505 0 2464 0 ct 2464 0 2464 0 2464 -142 ct 2464 -159 2461 -172 2456 -179 ct +2450 -186 2441 -190 2428 -190 ct 2418 -190 2408 -186 2397 -179 ct 2386 -172 2375 -161 2364 -146 ct +2364 -146 2364 -146 2364 0 ct 2364 0 2364 0 2323 0 ct p ef +2764 61 m 2719 56 2683 36 2654 -1 ct 2625 -37 2611 -81 2611 -133 ct 2611 -184 2625 -228 2654 -264 ct +2683 -301 2719 -321 2764 -326 ct 2764 -326 2764 -326 2764 -298 ct 2728 -291 2700 -273 2681 -244 ct +2662 -216 2652 -178 2652 -133 ct 2652 -87 2662 -49 2681 -21 ct 2700 8 2728 26 2764 33 ct +2764 33 2764 33 2764 61 ct p ef +2845 -214 m 2845 -214 2845 -214 2845 -260 ct 2845 -282 2849 -298 2858 -309 ct +2866 -320 2879 -326 2896 -326 ct 2896 -326 2896 -326 2896 -306 ct 2889 -306 2883 -303 2879 -298 ct +2876 -293 2874 -286 2874 -276 ct 2874 -276 2874 -276 2874 -265 ct 2874 -265 2874 -265 2896 -265 ct +2896 -265 2896 -265 2896 -214 ct 2896 -214 2896 -214 2845 -214 ct p +2947 -214 m 2947 -214 2947 -214 2947 -260 ct 2947 -282 2951 -298 2960 -309 ct +2968 -320 2981 -326 2998 -326 ct 2998 -326 2998 -326 2998 -306 ct 2991 -306 2985 -303 2981 -298 ct +2978 -293 2976 -286 2976 -276 ct 2976 -276 2976 -276 2976 -265 ct 2976 -265 2976 -265 2998 -265 ct +2998 -265 2998 -265 2998 -214 ct 2998 -214 2998 -214 2947 -214 ct p ef +3155 0 m 3155 -275 l 3053 -275 l 3053 -306 l 3298 -306 l 3298 -275 l +3196 -275 l 3196 0 l 3155 0 l p ef +3474 -26 m 3450 -5 3425 5 3401 5 ct 3380 5 3363 -1 3350 -13 ct 3337 -24 3330 -39 3330 -57 ct +3330 -81 3340 -99 3361 -114 ct 3382 -128 3409 -135 3443 -135 ct 3443 -135 3443 -135 3468 -135 ct +3468 -135 3468 -135 3468 -154 ct 3468 -169 3464 -180 3457 -187 ct 3449 -194 3438 -198 3423 -198 ct +3399 -198 3374 -191 3349 -177 ct 3349 -177 3349 -177 3349 -213 ct 3378 -224 3405 -229 3431 -229 ct +3460 -229 3480 -223 3491 -212 ct 3503 -201 3509 -181 3509 -153 ct 3509 -153 3509 -153 3509 -59 ct +3509 -45 3510 -36 3513 -31 ct 3516 -26 3522 -24 3529 -24 ct 3532 -24 3536 -25 3542 -26 ct +3542 -26 3542 -26 3546 -2 ct 3532 3 3522 5 3515 5 ct 3505 5 3496 2 3490 -3 ct 3483 -8 3478 -16 3474 -26 ct +p +3468 -53 m 3468 -53 3468 -53 3468 -110 ct 3468 -110 3468 -110 3456 -110 ct +3428 -110 3407 -106 3393 -99 ct 3379 -91 3372 -80 3372 -64 ct 3372 -52 3375 -43 3382 -37 ct +3388 -31 3398 -28 3411 -28 ct 3429 -28 3448 -36 3468 -53 ct p ef +3620 0 m 3620 0 3620 0 3620 -224 ct 3620 -224 3620 -224 3661 -224 ct 3661 -224 3661 -224 3659 -182 ct +3659 -182 3659 -182 3661 -182 ct 3671 -198 3683 -209 3697 -217 ct 3711 -225 3726 -229 3744 -229 ct +3756 -229 3770 -227 3785 -224 ct 3785 -224 3785 -224 3785 -160 ct 3785 -160 3785 -160 3754 -160 ct +3754 -160 3754 -160 3754 -191 ct 3748 -192 3742 -193 3737 -193 ct 3723 -193 3710 -189 3698 -181 ct +3685 -173 3673 -161 3661 -145 ct 3661 -145 3661 -145 3661 0 ct 3661 0 3661 0 3620 0 ct +p ef +3853 75 m 3853 75 3853 75 3857 41 ct 3882 51 3905 56 3926 56 ct 3948 56 3964 51 3973 42 ct +3983 33 3989 17 3992 -6 ct 3992 -6 3992 -6 3996 -46 ct 3996 -46 3996 -46 3992 -46 ct +3984 -31 3973 -19 3961 -12 ct 3948 -4 3934 0 3918 0 ct 3893 0 3873 -10 3858 -29 ct +3843 -49 3835 -75 3835 -108 ct 3835 -144 3844 -173 3861 -195 ct 3879 -218 3901 -229 3929 -229 ct +3951 -229 3973 -219 3994 -198 ct 3994 -198 3994 -198 3997 -198 ct 3997 -198 3997 -198 3997 -224 ct +3997 -224 3997 -224 4033 -224 ct 4033 -224 4033 -224 4033 -45 ct 4033 -15 4031 6 4027 21 ct +4023 36 4016 49 4005 60 ct 3988 78 3962 87 3925 87 ct 3904 87 3880 83 3853 75 ct +p +3992 -80 m 3992 -80 3992 -80 3992 -167 ct 3974 -188 3954 -198 3935 -198 ct +3916 -198 3902 -191 3892 -176 ct 3883 -162 3878 -140 3878 -111 ct 3878 -86 3882 -67 3890 -55 ct +3899 -42 3911 -36 3928 -36 ct 3940 -36 3951 -40 3962 -47 ct 3973 -54 3983 -65 3992 -80 ct +p ef +4290 -9 m 4262 0 4236 5 4212 5 ct 4174 5 4145 -5 4124 -25 ct 4103 -45 4093 -73 4093 -110 ct +4093 -144 4103 -173 4123 -195 ct 4143 -218 4168 -229 4199 -229 ct 4230 -229 4252 -220 4267 -201 ct +4282 -182 4289 -153 4289 -114 ct 4289 -114 4289 -114 4289 -101 ct 4289 -101 4289 -101 4135 -101 ct +4136 -76 4144 -57 4158 -45 ct 4172 -32 4191 -26 4217 -26 ct 4240 -26 4264 -31 4290 -42 ct +4290 -42 4290 -42 4290 -9 ct p +4136 -132 m 4136 -132 4136 -132 4246 -132 ct 4246 -132 4246 -132 4246 -138 ct +4246 -158 4242 -173 4233 -183 ct 4224 -193 4212 -198 4195 -198 ct 4178 -198 4165 -192 4154 -181 ct +4144 -169 4138 -153 4136 -132 ct p ef +4546 0 m 4526 3 4506 5 4487 5 ct 4454 5 4431 -1 4419 -13 ct 4407 -25 4401 -47 4401 -80 ct +4401 -80 4401 -80 4401 -188 ct 4401 -188 4401 -188 4345 -188 ct 4345 -188 4345 -188 4345 -219 ct +4345 -219 4345 -219 4401 -219 ct 4401 -219 4401 -219 4401 -267 ct 4401 -267 4401 -267 4442 -267 ct +4442 -267 4442 -267 4442 -219 ct 4442 -219 4442 -219 4541 -219 ct 4541 -219 4541 -219 4541 -188 ct +4541 -188 4541 -188 4442 -188 ct 4442 -188 4442 -188 4442 -74 ct 4442 -61 4443 -53 4444 -48 ct +4446 -43 4449 -39 4455 -35 ct 4464 -29 4477 -26 4495 -26 ct 4512 -26 4529 -28 4546 -31 ct +4546 -31 4546 -31 4546 0 ct p ef +4623 -214 m 4623 -214 4623 -214 4623 -260 ct 4623 -282 4627 -298 4636 -309 ct +4644 -320 4657 -326 4674 -326 ct 4674 -326 4674 -326 4674 -306 ct 4667 -306 4661 -303 4657 -298 ct +4654 -293 4652 -286 4652 -276 ct 4652 -276 4652 -276 4652 -265 ct 4652 -265 4652 -265 4674 -265 ct +4674 -265 4674 -265 4674 -214 ct 4674 -214 4674 -214 4623 -214 ct p +4725 -214 m 4725 -214 4725 -214 4725 -260 ct 4725 -282 4729 -298 4738 -309 ct +4746 -320 4759 -326 4776 -326 ct 4776 -326 4776 -326 4776 -306 ct 4769 -306 4763 -303 4759 -298 ct +4756 -293 4754 -286 4754 -276 ct 4754 -276 4754 -276 4754 -265 ct 4754 -265 4754 -265 4776 -265 ct +4776 -265 4776 -265 4776 -214 ct 4776 -214 4776 -214 4725 -214 ct p ef +4857 61 m 4902 56 4938 36 4967 -1 ct 4996 -37 5010 -81 5010 -133 ct 5010 -184 4996 -228 4967 -264 ct +4938 -301 4902 -321 4857 -326 ct 4857 -326 4857 -326 4857 -298 ct 4893 -291 4921 -273 4940 -244 ct +4959 -216 4969 -178 4969 -133 ct 4969 -87 4959 -49 4940 -21 ct 4921 8 4893 26 4857 33 ct +4857 33 4857 33 4857 61 ct p ef +5431 -163 m 5431 -224 l 5492 -224 l 5492 -163 l 5431 -163 l p +5431 0 m 5431 -61 l 5492 -61 l 5492 0 l 5431 0 l p ef +pom +gr +gs +pum +10197 7210 t +pom +gr +gs +pum +11213 7210 t +0.003 0.003 1.000 c 153 -24 m 146 -14 137 -7 127 -2 ct 117 3 106 5 93 5 ct 71 5 53 -2 39 -15 ct +25 -28 18 -45 18 -65 ct 18 -91 28 -111 47 -124 ct 67 -137 96 -143 135 -143 ct 135 -143 135 -143 159 -143 ct +159 -143 159 -143 159 -154 ct 159 -165 155 -174 147 -179 ct 139 -185 127 -188 111 -188 ct +89 -188 64 -182 37 -169 ct 37 -169 37 -169 37 -214 ct 65 -224 93 -229 122 -229 ct +154 -229 178 -223 194 -211 ct 204 -203 211 -194 215 -185 ct 218 -175 220 -160 220 -140 ct +220 -140 220 -140 220 -64 ct 220 -49 225 -41 234 -41 ct 236 -41 238 -41 241 -42 ct +241 -42 241 -42 241 -2 ct 229 3 217 5 207 5 ct 196 5 186 3 178 -2 ct 170 -7 164 -14 159 -24 ct +159 -24 159 -24 153 -24 ct p +159 -65 m 159 -65 159 -65 159 -102 ct 159 -102 159 -102 137 -102 ct 118 -102 103 -99 94 -94 ct +84 -88 79 -80 79 -69 ct 79 -61 82 -54 88 -49 ct 94 -44 101 -41 110 -41 ct 125 -41 142 -49 159 -65 ct +p ef +339 0 m 339 0 339 0 339 -178 ct 339 -178 339 -178 296 -178 ct 296 -178 296 -178 296 -219 ct +296 -219 296 -219 339 -219 ct 339 -219 339 -219 339 -251 ct 339 -278 347 -298 362 -311 ct +377 -324 400 -331 431 -331 ct 457 -331 482 -328 507 -322 ct 507 -322 507 -322 507 -278 ct +481 -286 460 -290 444 -290 ct 428 -290 417 -287 410 -281 ct 403 -275 400 -265 400 -250 ct +400 -250 400 -250 400 -219 ct 400 -219 400 -219 487 -219 ct 487 -219 487 -219 487 -178 ct +487 -178 487 -178 400 -178 ct 400 -178 400 -178 400 0 ct 400 0 400 0 339 0 ct p ef +736 -6 m 712 1 690 5 672 5 ct 643 5 622 -1 608 -14 ct 594 -26 587 -45 587 -70 ct +587 -70 587 -70 587 -178 ct 587 -178 587 -178 539 -178 ct 539 -178 539 -178 539 -219 ct +539 -219 539 -219 587 -219 ct 587 -219 587 -219 587 -285 ct 587 -285 587 -285 648 -285 ct +648 -285 648 -285 648 -219 ct 648 -219 648 -219 731 -219 ct 731 -219 731 -219 731 -178 ct +731 -178 731 -178 648 -178 ct 648 -178 648 -178 648 -84 ct 648 -68 651 -57 657 -51 ct +663 -44 673 -41 687 -41 ct 704 -41 720 -44 736 -51 ct 736 -51 736 -51 736 -6 ct +p ef +998 -95 m 998 -95 998 -95 846 -95 ct 849 -77 857 -63 869 -54 ct 881 -45 897 -41 918 -41 ct +942 -41 969 -46 998 -56 ct 998 -56 998 -56 998 -9 ct 963 0 932 5 906 5 ct 868 5 837 -6 814 -27 ct +791 -48 780 -76 780 -111 ct 780 -147 791 -175 812 -197 ct 834 -218 862 -229 897 -229 ct +929 -229 953 -219 971 -199 ct 989 -180 998 -152 998 -118 ct 998 -118 998 -118 998 -95 ct +p +845 -136 m 845 -136 845 -136 939 -136 ct 939 -153 935 -166 928 -175 ct 920 -184 909 -188 894 -188 ct +880 -188 868 -184 860 -175 ct 852 -166 847 -153 845 -136 ct p ef +1062 0 m 1062 0 1062 0 1062 -224 ct 1062 -224 1062 -224 1123 -224 ct 1123 -224 1123 -224 1121 -181 ct +1121 -181 1121 -181 1123 -181 ct 1133 -197 1145 -209 1159 -217 ct 1172 -225 1188 -229 1206 -229 ct +1217 -229 1232 -227 1248 -224 ct 1248 -224 1248 -224 1248 -149 ct 1248 -149 1248 -149 1207 -149 ct +1207 -149 1207 -149 1207 -173 ct 1202 -174 1199 -174 1196 -174 ct 1181 -174 1168 -170 1155 -163 ct +1143 -156 1132 -145 1123 -130 ct 1123 -130 1123 -130 1123 0 ct 1123 0 1123 0 1062 0 ct +p ef +pom +gr +gs +pum +12483 7210 t +478 61 m 433 56 397 36 368 -1 ct 339 -37 325 -81 325 -133 ct 325 -184 339 -228 368 -264 ct +397 -301 433 -321 478 -326 ct 478 -326 478 -326 478 -298 ct 442 -291 414 -273 395 -244 ct +376 -216 366 -178 366 -133 ct 366 -87 376 -49 395 -21 ct 414 8 442 26 478 33 ct +478 33 478 33 478 61 ct p ef +539 61 m 584 56 620 36 649 -1 ct 678 -37 692 -81 692 -133 ct 692 -184 678 -228 649 -264 ct +620 -301 584 -321 539 -326 ct 539 -326 539 -326 539 -298 ct 575 -291 603 -273 622 -244 ct +641 -216 651 -178 651 -133 ct 651 -87 641 -49 622 -21 ct 603 8 575 26 539 33 ct +539 33 539 33 539 61 ct p ef +1228 -326 m 1228 -326 1228 -326 1228 -295 ct 1228 -295 1228 -295 1212 -295 ct +1191 -295 1177 -293 1169 -287 ct 1160 -282 1156 -274 1156 -261 ct 1156 -257 1157 -251 1158 -242 ct +1158 -242 1158 -242 1162 -214 ct 1163 -204 1164 -196 1164 -190 ct 1164 -175 1161 -163 1154 -153 ct +1147 -144 1137 -137 1123 -132 ct 1137 -128 1147 -121 1154 -111 ct 1161 -102 1164 -90 1164 -75 ct +1164 -68 1163 -61 1162 -51 ct 1162 -51 1162 -51 1158 -23 ct 1157 -14 1156 -8 1156 -4 ct +1156 9 1160 17 1169 22 ct 1177 27 1191 30 1212 30 ct 1212 30 1212 30 1228 30 ct +1228 30 1228 30 1228 61 ct 1228 61 1228 61 1205 61 ct 1176 61 1154 56 1140 46 ct +1125 36 1118 21 1118 2 ct 1118 -7 1119 -16 1121 -26 ct 1121 -26 1121 -26 1128 -63 ct +1129 -68 1129 -74 1129 -79 ct 1129 -92 1125 -101 1117 -108 ct 1110 -114 1098 -117 1083 -117 ct +1083 -117 1083 -117 1064 -117 ct 1064 -117 1064 -117 1064 -148 ct 1064 -148 1064 -148 1083 -148 ct +1098 -148 1110 -151 1117 -157 ct 1125 -164 1129 -173 1129 -186 ct 1129 -191 1129 -197 1128 -202 ct +1128 -202 1128 -202 1121 -239 ct 1119 -249 1118 -258 1118 -267 ct 1118 -286 1125 -301 1140 -311 ct +1154 -321 1176 -326 1205 -326 ct 1205 -326 1205 -326 1228 -326 ct p ef +pom +gr +gs +pum +10197 7701 t +pom +gr +gs +pum +11213 7701 t +122 0 m 122 -295 l 35 -295 l 35 -326 l 163 -326 l 163 0 l 122 0 l +p ef +426 -26 m 402 -5 377 5 353 5 ct 332 5 315 -1 302 -13 ct 289 -24 282 -39 282 -57 ct +282 -81 292 -99 313 -114 ct 334 -128 361 -135 395 -135 ct 395 -135 395 -135 420 -135 ct +420 -135 420 -135 420 -154 ct 420 -169 416 -180 409 -187 ct 401 -194 390 -198 375 -198 ct +351 -198 326 -191 301 -177 ct 301 -177 301 -177 301 -213 ct 330 -224 357 -229 383 -229 ct +412 -229 432 -223 443 -212 ct 455 -201 461 -181 461 -153 ct 461 -153 461 -153 461 -59 ct +461 -45 462 -36 465 -31 ct 468 -26 474 -24 481 -24 ct 484 -24 488 -25 494 -26 ct +494 -26 494 -26 498 -2 ct 484 3 474 5 467 5 ct 457 5 448 2 442 -3 ct 435 -8 430 -16 426 -26 ct +p +420 -53 m 420 -53 420 -53 420 -110 ct 420 -110 420 -110 408 -110 ct 380 -110 359 -106 345 -99 ct +331 -91 324 -80 324 -64 ct 324 -52 327 -43 334 -37 ct 340 -31 350 -28 363 -28 ct +381 -28 400 -36 420 -53 ct p ef +547 -9 m 547 -9 547 -9 547 -45 ct 578 -32 605 -26 628 -26 ct 644 -26 658 -29 669 -36 ct +680 -43 685 -51 685 -61 ct 685 -74 672 -84 647 -93 ct 647 -93 647 -93 604 -107 ct +570 -118 553 -138 553 -165 ct 553 -186 561 -201 576 -212 ct 591 -223 613 -229 641 -229 ct +662 -229 686 -226 714 -219 ct 714 -219 714 -219 714 -186 ct 687 -194 663 -198 641 -198 ct +625 -198 612 -196 604 -191 ct 596 -186 592 -179 592 -169 ct 592 -158 602 -149 622 -142 ct +622 -142 622 -142 674 -124 ct 709 -111 726 -91 726 -64 ct 726 -43 717 -26 700 -14 ct +682 -1 659 5 629 5 ct 604 5 576 0 547 -9 ct p ef +990 0 m 970 3 950 5 931 5 ct 898 5 875 -1 863 -13 ct 851 -25 845 -47 845 -80 ct +845 -80 845 -80 845 -188 ct 845 -188 845 -188 789 -188 ct 789 -188 789 -188 789 -219 ct +789 -219 789 -219 845 -219 ct 845 -219 845 -219 845 -267 ct 845 -267 845 -267 886 -267 ct +886 -267 886 -267 886 -219 ct 886 -219 886 -219 985 -219 ct 985 -219 985 -219 985 -188 ct +985 -188 985 -188 886 -188 ct 886 -188 886 -188 886 -74 ct 886 -61 887 -53 888 -48 ct +890 -43 893 -39 899 -35 ct 908 -29 921 -26 939 -26 ct 956 -26 973 -28 990 -31 ct +990 -31 990 -31 990 0 ct p ef +1016 31 m 1016 0 l 1271 0 l 1271 31 l 1016 31 l p ef +1542 -58 m 1542 -89 l 1761 -89 l 1761 -58 l 1542 -58 l p +1542 -130 m 1542 -161 l 1761 -161 l 1761 -130 l 1542 -130 l p ef +pom +gr +gs +pum +13245 7701 t +0.003 0.003 1.000 c 228 -6 m 204 1 182 5 164 5 ct 135 5 114 -1 100 -14 ct 86 -26 79 -45 79 -70 ct +79 -70 79 -70 79 -178 ct 79 -178 79 -178 31 -178 ct 31 -178 31 -178 31 -219 ct +31 -219 31 -219 79 -219 ct 79 -219 79 -219 79 -285 ct 79 -285 79 -285 140 -285 ct +140 -285 140 -285 140 -219 ct 140 -219 140 -219 223 -219 ct 223 -219 223 -219 223 -178 ct +223 -178 223 -178 140 -178 ct 140 -178 140 -178 140 -84 ct 140 -68 143 -57 149 -51 ct +155 -44 165 -41 179 -41 ct 196 -41 212 -44 228 -51 ct 228 -51 228 -51 228 -6 ct +p ef +279 78 m 279 78 279 78 279 30 ct 304 41 326 46 344 46 ct 359 46 369 42 374 34 ct +379 26 381 11 381 -13 ct 381 -13 381 -13 381 -183 ct 381 -183 381 -183 299 -183 ct +299 -183 299 -183 299 -224 ct 299 -224 299 -224 442 -224 ct 442 -224 442 -224 442 -16 ct +442 7 440 24 437 35 ct 434 46 428 56 419 64 ct 402 79 379 87 350 87 ct 331 87 307 84 279 78 ct +p +381 -265 m 381 -326 l 442 -326 l 442 -265 l 381 -265 l p ef +532 82 m 532 82 532 82 532 -224 ct 532 -224 532 -224 593 -224 ct 593 -224 593 -224 591 -182 ct +591 -182 591 -182 593 -182 ct 603 -197 614 -209 625 -217 ct 637 -225 650 -229 664 -229 ct +690 -229 710 -219 726 -198 ct 741 -178 749 -151 749 -117 ct 749 -80 740 -50 723 -28 ct +706 -6 683 5 654 5 ct 642 5 630 3 620 -2 ct 610 -6 601 -13 593 -22 ct 593 -22 593 -22 591 -22 ct +591 -22 591 -22 593 0 ct 593 0 593 0 593 82 ct 593 82 593 82 532 82 ct p +593 -64 m 600 -56 607 -50 614 -47 ct 621 -43 629 -41 638 -41 ct 653 -41 664 -47 672 -60 ct +679 -72 683 -91 683 -116 ct 683 -135 680 -149 673 -159 ct 666 -168 657 -173 643 -173 ct +635 -173 626 -170 617 -164 ct 609 -158 601 -149 593 -136 ct 593 -136 593 -136 593 -64 ct +p ef +pom +gr +gs +pum +14007 7701 t +43 -112 m 43 -143 l 211 -143 l 211 -112 l 43 -112 l p ef +272 0 m 491 -110 l 272 -219 l 272 -185 l 423 -110 l 272 -34 l 272 0 l +p ef +736 0 m 716 3 696 5 677 5 ct 644 5 621 -1 609 -13 ct 597 -25 591 -47 591 -80 ct +591 -80 591 -80 591 -188 ct 591 -188 591 -188 535 -188 ct 535 -188 535 -188 535 -219 ct +535 -219 535 -219 591 -219 ct 591 -219 591 -219 591 -267 ct 591 -267 591 -267 632 -267 ct +632 -267 632 -267 632 -219 ct 632 -219 632 -219 731 -219 ct 731 -219 731 -219 731 -188 ct +731 -188 731 -188 632 -188 ct 632 -188 632 -188 632 -74 ct 632 -61 633 -53 634 -48 ct +636 -43 639 -39 645 -35 ct 654 -29 667 -26 685 -26 ct 702 -26 719 -28 736 -31 ct +736 -31 736 -31 736 0 ct p ef +799 0 m 799 0 799 0 799 -326 ct 799 -326 799 -326 840 -326 ct 840 -326 840 -326 840 -224 ct +840 -224 840 -224 838 -182 ct 838 -182 838 -182 840 -182 ct 850 -198 861 -209 874 -217 ct +886 -225 901 -229 917 -229 ct 938 -229 954 -223 965 -210 ct 976 -197 981 -178 981 -153 ct +981 -153 981 -153 981 0 ct 981 0 981 0 940 0 ct 940 0 940 0 940 -142 ct 940 -159 937 -172 932 -179 ct +926 -186 917 -190 904 -190 ct 894 -190 884 -186 873 -179 ct 862 -172 851 -161 840 -146 ct +840 -146 840 -146 840 0 ct 840 0 840 0 799 0 ct p ef +1188 -26 m 1164 -5 1139 5 1115 5 ct 1094 5 1077 -1 1064 -13 ct 1051 -24 1044 -39 1044 -57 ct +1044 -81 1054 -99 1075 -114 ct 1096 -128 1123 -135 1157 -135 ct 1157 -135 1157 -135 1182 -135 ct +1182 -135 1182 -135 1182 -154 ct 1182 -169 1178 -180 1171 -187 ct 1163 -194 1152 -198 1137 -198 ct +1113 -198 1088 -191 1063 -177 ct 1063 -177 1063 -177 1063 -213 ct 1092 -224 1119 -229 1145 -229 ct +1174 -229 1194 -223 1205 -212 ct 1217 -201 1223 -181 1223 -153 ct 1223 -153 1223 -153 1223 -59 ct +1223 -45 1224 -36 1227 -31 ct 1230 -26 1236 -24 1243 -24 ct 1246 -24 1250 -25 1256 -26 ct +1256 -26 1256 -26 1260 -2 ct 1246 3 1236 5 1229 5 ct 1219 5 1210 2 1204 -3 ct 1197 -8 1192 -16 1188 -26 ct +p +1182 -53 m 1182 -53 1182 -53 1182 -110 ct 1182 -110 1182 -110 1170 -110 ct +1142 -110 1121 -106 1107 -99 ct 1093 -91 1086 -80 1086 -64 ct 1086 -52 1089 -43 1096 -37 ct +1102 -31 1112 -28 1125 -28 ct 1143 -28 1162 -36 1182 -53 ct p ef +1498 0 m 1478 3 1458 5 1439 5 ct 1406 5 1383 -1 1371 -13 ct 1359 -25 1353 -47 1353 -80 ct +1353 -80 1353 -80 1353 -188 ct 1353 -188 1353 -188 1297 -188 ct 1297 -188 1297 -188 1297 -219 ct +1297 -219 1297 -219 1353 -219 ct 1353 -219 1353 -219 1353 -267 ct 1353 -267 1353 -267 1394 -267 ct +1394 -267 1394 -267 1394 -219 ct 1394 -219 1394 -219 1493 -219 ct 1493 -219 1493 -219 1493 -188 ct +1493 -188 1493 -188 1394 -188 ct 1394 -188 1394 -188 1394 -74 ct 1394 -61 1395 -53 1396 -48 ct +1398 -43 1401 -39 1407 -35 ct 1416 -29 1429 -26 1447 -26 ct 1464 -26 1481 -28 1498 -31 ct +1498 -31 1498 -31 1498 0 ct p ef +1748 61 m 1703 56 1667 36 1638 -1 ct 1609 -37 1595 -81 1595 -133 ct 1595 -184 1609 -228 1638 -264 ct +1667 -301 1703 -321 1748 -326 ct 1748 -326 1748 -326 1748 -298 ct 1712 -291 1684 -273 1665 -244 ct +1646 -216 1636 -178 1636 -133 ct 1636 -87 1646 -49 1665 -21 ct 1684 8 1712 26 1748 33 ct +1748 33 1748 33 1748 61 ct p ef +1809 61 m 1854 56 1890 36 1919 -1 ct 1948 -37 1962 -81 1962 -133 ct 1962 -184 1948 -228 1919 -264 ct +1890 -301 1854 -321 1809 -326 ct 1809 -326 1809 -326 1809 -298 ct 1845 -291 1873 -273 1892 -244 ct +1911 -216 1921 -178 1921 -133 ct 1921 -87 1911 -49 1892 -21 ct 1873 8 1845 26 1809 33 ct +1809 33 1809 33 1809 61 ct p ef +2129 66 m 2129 66 2129 66 2129 46 ct 2136 45 2142 41 2146 33 ct 2151 25 2153 14 2154 0 ct +2154 0 2154 0 2129 0 ct 2129 0 2129 0 2129 -61 ct 2129 -61 2129 -61 2190 -61 ct +2190 -61 2190 -61 2190 -24 ct 2190 5 2185 27 2175 42 ct 2165 57 2149 65 2129 66 ct +p +2129 -163 m 2129 -224 l 2190 -224 l 2190 -163 l 2129 -163 l p ef +pom +gr +gs +pum +10197 8192 t +pom +gr +gs +pum +11213 8192 t +122 0 m 122 -295 l 35 -295 l 35 -326 l 163 -326 l 163 0 l 122 0 l +p ef +426 -26 m 402 -5 377 5 353 5 ct 332 5 315 -1 302 -13 ct 289 -24 282 -39 282 -57 ct +282 -81 292 -99 313 -114 ct 334 -128 361 -135 395 -135 ct 395 -135 395 -135 420 -135 ct +420 -135 420 -135 420 -154 ct 420 -169 416 -180 409 -187 ct 401 -194 390 -198 375 -198 ct +351 -198 326 -191 301 -177 ct 301 -177 301 -177 301 -213 ct 330 -224 357 -229 383 -229 ct +412 -229 432 -223 443 -212 ct 455 -201 461 -181 461 -153 ct 461 -153 461 -153 461 -59 ct +461 -45 462 -36 465 -31 ct 468 -26 474 -24 481 -24 ct 484 -24 488 -25 494 -26 ct +494 -26 494 -26 498 -2 ct 484 3 474 5 467 5 ct 457 5 448 2 442 -3 ct 435 -8 430 -16 426 -26 ct +p +420 -53 m 420 -53 420 -53 420 -110 ct 420 -110 420 -110 408 -110 ct 380 -110 359 -106 345 -99 ct +331 -91 324 -80 324 -64 ct 324 -52 327 -43 334 -37 ct 340 -31 350 -28 363 -28 ct +381 -28 400 -36 420 -53 ct p ef +547 -9 m 547 -9 547 -9 547 -45 ct 578 -32 605 -26 628 -26 ct 644 -26 658 -29 669 -36 ct +680 -43 685 -51 685 -61 ct 685 -74 672 -84 647 -93 ct 647 -93 647 -93 604 -107 ct +570 -118 553 -138 553 -165 ct 553 -186 561 -201 576 -212 ct 591 -223 613 -229 641 -229 ct +662 -229 686 -226 714 -219 ct 714 -219 714 -219 714 -186 ct 687 -194 663 -198 641 -198 ct +625 -198 612 -196 604 -191 ct 596 -186 592 -179 592 -169 ct 592 -158 602 -149 622 -142 ct +622 -142 622 -142 674 -124 ct 709 -111 726 -91 726 -64 ct 726 -43 717 -26 700 -14 ct +682 -1 659 5 629 5 ct 604 5 576 0 547 -9 ct p ef +990 0 m 970 3 950 5 931 5 ct 898 5 875 -1 863 -13 ct 851 -25 845 -47 845 -80 ct +845 -80 845 -80 845 -188 ct 845 -188 845 -188 789 -188 ct 789 -188 789 -188 789 -219 ct +789 -219 789 -219 845 -219 ct 845 -219 845 -219 845 -267 ct 845 -267 845 -267 886 -267 ct +886 -267 886 -267 886 -219 ct 886 -219 886 -219 985 -219 ct 985 -219 985 -219 985 -188 ct +985 -188 985 -188 886 -188 ct 886 -188 886 -188 886 -74 ct 886 -61 887 -53 888 -48 ct +890 -43 893 -39 899 -35 ct 908 -29 921 -26 939 -26 ct 956 -26 973 -28 990 -31 ct +990 -31 990 -31 990 0 ct p ef +1016 31 m 1016 0 l 1271 0 l 1271 31 l 1016 31 l p ef +1313 -112 m 1313 -143 l 1481 -143 l 1481 -112 l 1313 -112 l p ef +1542 0 m 1761 -110 l 1542 -219 l 1542 -185 l 1693 -110 l 1542 -34 l +1542 0 l p ef +1960 0 m 1960 0 1960 0 1962 -42 ct 1962 -42 1962 -42 1960 -42 ct 1950 -26 1939 -15 1927 -7 ct +1914 1 1901 5 1886 5 ct 1861 5 1841 -5 1826 -24 ct 1811 -44 1804 -71 1804 -105 ct +1804 -142 1813 -172 1830 -195 ct 1848 -218 1870 -229 1898 -229 ct 1910 -229 1922 -226 1932 -221 ct +1942 -216 1952 -209 1960 -198 ct 1960 -198 1960 -198 1962 -198 ct 1962 -198 1962 -198 1960 -229 ct +1960 -229 1960 -229 1960 -326 ct 1960 -326 1960 -326 2001 -326 ct 2001 -326 2001 -326 2001 0 ct +2001 0 2001 0 1960 0 ct p +1960 -168 m 1950 -178 1941 -185 1932 -190 ct 1922 -195 1913 -198 1904 -198 ct +1886 -198 1872 -190 1862 -175 ct 1852 -159 1847 -137 1847 -109 ct 1847 -83 1851 -63 1859 -50 ct +1867 -38 1878 -31 1894 -31 ct 1906 -31 1917 -35 1928 -42 ct 1939 -49 1950 -59 1960 -73 ct +1960 -73 1960 -73 1960 -168 ct p ef +2250 -224 m 2250 -224 2250 -224 2250 0 ct 2250 0 2250 0 2209 0 ct 2209 0 2209 0 2211 -42 ct +2211 -42 2211 -42 2209 -42 ct 2200 -26 2188 -15 2176 -7 ct 2163 1 2148 5 2132 5 ct +2111 5 2095 -1 2084 -14 ct 2073 -27 2068 -46 2068 -71 ct 2068 -71 2068 -71 2068 -224 ct +2068 -224 2068 -224 2109 -224 ct 2109 -224 2109 -224 2109 -82 ct 2109 -65 2112 -52 2117 -45 ct +2123 -38 2132 -34 2145 -34 ct 2155 -34 2165 -38 2176 -45 ct 2187 -52 2198 -63 2209 -78 ct +2209 -78 2209 -78 2209 -224 ct 2209 -224 2209 -224 2250 -224 ct p ef +2305 0 m 2305 0 2305 0 2305 -224 ct 2305 -224 2305 -224 2341 -224 ct 2341 -224 2341 -224 2338 -182 ct +2338 -182 2338 -182 2341 -182 ct 2349 -198 2358 -209 2367 -217 ct 2375 -225 2383 -229 2391 -229 ct +2402 -229 2410 -225 2417 -216 ct 2424 -208 2428 -196 2429 -182 ct 2429 -182 2429 -182 2432 -182 ct +2439 -198 2447 -209 2455 -217 ct 2464 -225 2473 -229 2483 -229 ct 2496 -229 2506 -224 2513 -213 ct +2520 -202 2523 -186 2523 -164 ct 2523 -164 2523 -164 2523 0 ct 2523 0 2523 0 2487 0 ct +2487 0 2487 0 2487 -162 ct 2487 -172 2486 -180 2484 -185 ct 2482 -190 2478 -193 2474 -193 ct +2468 -193 2461 -189 2454 -181 ct 2447 -173 2439 -160 2432 -144 ct 2432 -144 2432 -144 2432 0 ct +2432 0 2432 0 2396 0 ct 2396 0 2396 0 2396 -155 ct 2396 -167 2395 -177 2393 -183 ct +2390 -190 2387 -193 2383 -193 ct 2377 -193 2370 -188 2362 -179 ct 2354 -170 2347 -158 2341 -144 ct +2341 -144 2341 -144 2341 0 ct 2341 0 2341 0 2305 0 ct p ef +2577 82 m 2577 82 2577 82 2577 -224 ct 2577 -224 2577 -224 2618 -224 ct 2618 -224 2618 -224 2616 -182 ct +2616 -182 2616 -182 2618 -182 ct 2628 -198 2639 -209 2651 -217 ct 2663 -225 2677 -229 2691 -229 ct +2716 -229 2736 -219 2751 -200 ct 2766 -180 2773 -153 2773 -120 ct 2773 -82 2764 -52 2747 -29 ct +2730 -6 2707 5 2679 5 ct 2667 5 2656 2 2646 -3 ct 2636 -8 2626 -15 2618 -26 ct +2618 -26 2618 -26 2616 -26 ct 2616 -26 2616 -26 2618 5 ct 2618 5 2618 5 2618 82 ct +2618 82 2618 82 2577 82 ct p +2618 -56 m 2627 -46 2637 -39 2646 -34 ct 2655 -29 2664 -26 2674 -26 ct 2692 -26 2705 -34 2715 -49 ct +2725 -65 2730 -87 2730 -115 ct 2730 -141 2726 -160 2718 -173 ct 2710 -186 2699 -193 2683 -193 ct +2672 -193 2660 -189 2649 -182 ct 2639 -175 2628 -165 2618 -151 ct 2618 -151 2618 -151 2618 -56 ct +p ef +3018 61 m 2973 56 2937 36 2908 -1 ct 2879 -37 2865 -81 2865 -133 ct 2865 -184 2879 -228 2908 -264 ct +2937 -301 2973 -321 3018 -326 ct 3018 -326 3018 -326 3018 -298 ct 2982 -291 2954 -273 2935 -244 ct +2916 -216 2906 -178 2906 -133 ct 2906 -87 2916 -49 2935 -21 ct 2954 8 2982 26 3018 33 ct +3018 33 3018 33 3018 61 ct p ef +3079 61 m 3124 56 3160 36 3189 -1 ct 3218 -37 3232 -81 3232 -133 ct 3232 -184 3218 -228 3189 -264 ct +3160 -301 3124 -321 3079 -326 ct 3079 -326 3079 -326 3079 -298 ct 3115 -291 3143 -273 3162 -244 ct +3181 -216 3191 -178 3191 -133 ct 3191 -87 3181 -49 3162 -21 ct 3143 8 3115 26 3079 33 ct +3079 33 3079 33 3079 61 ct p ef +3399 66 m 3399 66 3399 66 3399 46 ct 3406 45 3412 41 3416 33 ct 3421 25 3423 14 3424 0 ct +3424 0 3424 0 3399 0 ct 3399 0 3399 0 3399 -61 ct 3399 -61 3399 -61 3460 -61 ct +3460 -61 3460 -61 3460 -24 ct 3460 5 3455 27 3445 42 ct 3435 57 3419 65 3399 66 ct +p +3399 -163 m 3399 -224 l 3460 -224 l 3460 -163 l 3399 -163 l p ef +pom +gr +gs +pum +10197 8683 t +pom +gr +gs +pum +10705 8683 t +43 -326 m 43 -326 43 -326 43 -295 ct 43 -295 43 -295 59 -295 ct 80 -295 94 -293 102 -287 ct +111 -282 115 -274 115 -261 ct 115 -257 114 -251 113 -242 ct 113 -242 113 -242 109 -214 ct +108 -204 107 -196 107 -190 ct 107 -175 110 -163 117 -153 ct 124 -144 134 -137 148 -132 ct +134 -128 124 -121 117 -111 ct 110 -102 107 -90 107 -75 ct 107 -68 108 -61 109 -51 ct +109 -51 109 -51 113 -23 ct 114 -14 115 -8 115 -4 ct 115 9 111 17 102 22 ct 94 27 80 30 59 30 ct +59 30 59 30 43 30 ct 43 30 43 30 43 61 ct 43 61 43 61 66 61 ct 95 61 117 56 131 46 ct +146 36 153 21 153 2 ct 153 -7 152 -16 150 -26 ct 150 -26 150 -26 143 -63 ct 142 -68 142 -74 142 -79 ct +142 -92 146 -101 154 -108 ct 161 -114 173 -117 188 -117 ct 188 -117 188 -117 207 -117 ct +207 -117 207 -117 207 -148 ct 207 -148 207 -148 188 -148 ct 173 -148 161 -151 154 -157 ct +146 -164 142 -173 142 -186 ct 142 -191 142 -197 143 -202 ct 143 -202 143 -202 150 -239 ct +152 -249 153 -258 153 -267 ct 153 -286 146 -301 131 -311 ct 117 -321 95 -326 66 -326 ct +66 -326 66 -326 43 -326 ct p ef +pom +gr +gs +pum +10197 9377 t +43 -326 m 43 -326 43 -326 43 -295 ct 43 -295 43 -295 59 -295 ct 80 -295 94 -293 102 -287 ct +111 -282 115 -274 115 -261 ct 115 -257 114 -251 113 -242 ct 113 -242 113 -242 109 -214 ct +108 -204 107 -196 107 -190 ct 107 -175 110 -163 117 -153 ct 124 -144 134 -137 148 -132 ct +134 -128 124 -121 117 -111 ct 110 -102 107 -90 107 -75 ct 107 -68 108 -61 109 -51 ct +109 -51 109 -51 113 -23 ct 114 -14 115 -8 115 -4 ct 115 9 111 17 102 22 ct 94 27 80 30 59 30 ct +59 30 59 30 43 30 ct 43 30 43 30 43 61 ct 43 61 43 61 66 61 ct 95 61 117 56 131 46 ct +146 36 153 21 153 2 ct 153 -7 152 -16 150 -26 ct 150 -26 150 -26 143 -63 ct 142 -68 142 -74 142 -79 ct +142 -92 146 -101 154 -108 ct 161 -114 173 -117 188 -117 ct 188 -117 188 -117 207 -117 ct +207 -117 207 -117 207 -148 ct 207 -148 207 -148 188 -148 ct 173 -148 161 -151 154 -157 ct +146 -164 142 -173 142 -186 ct 142 -191 142 -197 143 -202 ct 143 -202 143 -202 150 -239 ct +152 -249 153 -258 153 -267 ct 153 -286 146 -301 131 -311 ct 117 -321 95 -326 66 -326 ct +66 -326 66 -326 43 -326 ct p ef +351 66 m 351 66 351 66 351 46 ct 358 45 364 41 368 33 ct 373 25 375 14 376 0 ct +376 0 376 0 351 0 ct 351 0 351 0 351 -61 ct 351 -61 351 -61 412 -61 ct 412 -61 412 -61 412 -24 ct +412 5 407 27 397 42 ct 387 57 371 65 351 66 ct p +351 -163 m 351 -224 l 412 -224 l 412 -163 l 351 -163 l p ef +pom +gr +gs +pum +10705 9377 t +pom +gr +gr +0.503 0.503 0.503 c 11787 10423 m 10406 10423 l 10406 9748 l 13169 9748 l +13169 10423 l 11787 10423 l p ef +11787 10423 m 10406 10423 l 10406 9748 l 13169 9748 l 13169 10423 l +11787 10423 l pc +0.753 0.753 0.753 c 11687 10323 m 10306 10323 l 10306 9648 l 13069 9648 l +13069 10323 l 11687 10323 l p ef +0.003 0.003 0.003 c 11687 10323 m 10306 10323 l 10306 9648 l 13069 9648 l +13069 10323 l 11687 10323 l pc +gs +gs +pum +10541 10127 t +1.000 1.000 1.000 c 29 -291 m 29 -291 29 -291 154 -291 ct 189 -291 216 -283 235 -267 ct +254 -251 264 -229 264 -200 ct 264 -171 254 -148 235 -131 ct 215 -115 188 -107 153 -107 ct +153 -107 153 -107 88 -107 ct 88 -107 88 -107 88 0 ct 88 0 88 0 29 0 ct 29 0 29 0 29 -291 ct +p +88 -156 m 88 -156 88 -156 150 -156 ct 168 -156 181 -160 191 -168 ct 200 -176 205 -186 205 -200 ct +205 -212 200 -223 190 -230 ct 181 -238 167 -242 150 -242 ct 150 -242 150 -242 88 -242 ct +88 -242 88 -242 88 -156 ct p ef +451 -211 m 451 -211 451 -211 441 -159 ct 435 -163 429 -165 422 -165 ct 415 -165 408 -163 402 -158 ct +395 -153 388 -145 381 -134 ct 374 -123 371 -116 371 -114 ct 371 -114 371 -114 371 0 ct +371 0 371 0 314 0 ct 314 0 314 0 314 -215 ct 314 -215 314 -215 371 -215 ct 371 -215 371 -215 371 -172 ct +379 -190 387 -202 395 -209 ct 403 -216 413 -220 424 -220 ct 435 -220 444 -217 451 -211 ct +p ef +578 -220 m 612 -220 639 -210 660 -190 ct 681 -170 691 -143 691 -108 ct 691 -72 681 -45 660 -25 ct +639 -5 612 5 578 5 ct 544 5 517 -5 496 -25 ct 475 -45 465 -72 465 -108 ct 465 -143 475 -170 496 -190 ct +517 -210 544 -220 578 -220 ct p +578 -44 m 594 -44 607 -50 617 -61 ct 627 -73 632 -88 632 -108 ct 632 -127 627 -142 617 -154 ct +608 -165 594 -171 578 -171 ct 561 -171 547 -165 538 -154 ct 529 -143 524 -128 524 -108 ct +524 -88 529 -72 538 -61 ct 547 -50 561 -44 578 -44 ct p ef +794 -192 m 801 -201 810 -207 822 -212 ct 834 -217 846 -220 858 -220 ct 885 -220 906 -210 923 -190 ct +940 -171 949 -144 949 -112 ct 949 -76 940 -47 923 -26 ct 906 -5 885 5 858 5 ct +831 5 810 -4 794 -21 ct 794 -21 794 -21 794 0 ct 794 0 794 0 737 0 ct 737 0 737 0 737 -307 ct +737 -307 737 -307 794 -307 ct 794 -307 794 -307 794 -192 ct p +794 -69 m 807 -52 823 -44 843 -44 ct 857 -44 868 -50 877 -61 ct 886 -73 890 -89 890 -108 ct +890 -129 886 -144 877 -155 ct 868 -166 856 -171 843 -171 ct 824 -171 808 -162 794 -145 ct +794 -145 794 -145 794 -69 ct p ef +1052 0 m 995 0 l 995 -307 l 1052 -307 l 1052 0 l p ef +1305 -20 m 1280 -3 1251 5 1219 5 ct 1183 5 1154 -5 1132 -26 ct 1111 -46 1100 -74 1100 -108 ct +1100 -142 1110 -169 1129 -189 ct 1148 -210 1174 -220 1206 -220 ct 1235 -220 1259 -210 1277 -191 ct +1296 -171 1305 -144 1305 -109 ct 1305 -109 1305 -109 1305 -95 ct 1305 -95 1305 -95 1159 -95 ct +1161 -80 1168 -68 1179 -59 ct 1190 -49 1204 -44 1220 -44 ct 1245 -44 1270 -51 1295 -65 ct +1295 -65 1295 -65 1305 -20 ct p +1250 -133 m 1248 -147 1243 -158 1235 -167 ct 1227 -175 1218 -179 1206 -179 ct +1194 -179 1183 -175 1175 -167 ct 1166 -158 1161 -147 1159 -133 ct 1159 -133 1159 -133 1250 -133 ct +p ef +1668 0 m 1668 0 1668 0 1611 0 ct 1611 0 1611 0 1611 -125 ct 1611 -143 1609 -155 1604 -162 ct +1600 -168 1593 -171 1584 -171 ct 1569 -171 1554 -160 1538 -137 ct 1538 -137 1538 -137 1538 0 ct +1538 0 1538 0 1481 0 ct 1481 0 1481 0 1481 -125 ct 1481 -144 1479 -157 1474 -162 ct +1470 -168 1464 -171 1455 -171 ct 1440 -171 1424 -160 1408 -137 ct 1408 -137 1408 -137 1408 0 ct +1408 0 1408 0 1351 0 ct 1351 0 1351 0 1351 -215 ct 1351 -215 1351 -215 1408 -215 ct +1408 -215 1408 -215 1408 -182 ct 1425 -207 1446 -220 1473 -220 ct 1501 -220 1521 -207 1533 -182 ct +1551 -207 1574 -220 1603 -220 ct 1624 -220 1640 -214 1651 -201 ct 1662 -188 1668 -169 1668 -144 ct +1668 -144 1668 -144 1668 0 ct p ef +1756 -66 m 1766 -66 1775 -63 1782 -56 ct 1789 -49 1792 -41 1792 -31 ct 1792 -21 1789 -12 1782 -5 ct +1775 2 1766 5 1756 5 ct 1746 5 1738 2 1731 -5 ct 1724 -12 1721 -20 1721 -31 ct +1721 -41 1724 -49 1731 -56 ct 1738 -63 1746 -66 1756 -66 ct p ef +2030 0 m 2030 0 2030 0 1971 0 ct 1967 -9 1965 -17 1965 -25 ct 1946 -5 1923 5 1896 5 ct +1876 5 1860 -1 1849 -13 ct 1838 -24 1832 -40 1832 -59 ct 1832 -73 1836 -85 1843 -95 ct +1851 -106 1862 -114 1877 -120 ct 1892 -127 1909 -131 1930 -132 ct 1930 -132 1930 -132 1965 -135 ct +1965 -135 1965 -135 1965 -139 ct 1965 -163 1951 -175 1924 -175 ct 1916 -175 1905 -173 1891 -170 ct +1877 -166 1865 -162 1855 -157 ct 1855 -157 1855 -157 1841 -198 ct 1854 -204 1870 -210 1887 -214 ct +1905 -218 1920 -220 1934 -220 ct 1963 -220 1985 -213 2000 -199 ct 2015 -185 2022 -165 2022 -138 ct +2022 -138 2022 -138 2022 -51 ct 2022 -31 2025 -14 2030 0 ct p +1965 -66 m 1965 -66 1965 -66 1965 -101 ct 1941 -99 1926 -97 1920 -96 ct 1915 -95 1909 -93 1902 -89 ct +1896 -86 1892 -82 1889 -77 ct 1886 -72 1884 -67 1884 -61 ct 1884 -54 1886 -49 1891 -45 ct +1895 -40 1901 -38 1908 -38 ct 1929 -38 1948 -47 1965 -66 ct p ef +2282 0 m 2282 0 2282 0 2225 0 ct 2225 0 2225 0 2225 -125 ct 2225 -156 2214 -171 2192 -171 ct +2173 -171 2155 -160 2140 -139 ct 2140 -139 2140 -139 2140 0 ct 2140 0 2140 0 2083 0 ct +2083 0 2083 0 2083 -307 ct 2083 -307 2083 -307 2140 -307 ct 2140 -307 2140 -307 2140 -188 ct +2158 -209 2181 -220 2209 -220 ct 2231 -220 2249 -213 2262 -200 ct 2275 -187 2282 -168 2282 -144 ct +2282 -144 2282 -144 2282 0 ct p ef +pom +gr +gr +0.300 0.300 0.300 c 8573 1558 m 9729 1558 l 9729 1415 l 9936 1640 l +9729 1866 l 9729 1722 l 8573 1722 l 8573 1558 l p ef +gs +gs +pum +8769 1480 t +0.003 0.003 0.003 c 44 0 m 20 0 l 20 -143 l 44 -143 l 44 0 l p +32 -205 m 36 -205 40 -204 43 -201 ct 46 -198 47 -194 47 -190 ct 47 -186 46 -183 43 -180 ct +40 -177 36 -176 32 -176 ct 28 -176 25 -177 22 -180 ct 19 -183 18 -186 18 -190 ct +18 -194 19 -198 22 -201 ct 25 -204 28 -205 32 -205 ct p ef +202 0 m 202 0 202 0 178 0 ct 178 0 178 0 178 -91 ct 178 -102 175 -110 170 -116 ct +165 -122 157 -125 148 -125 ct 134 -125 120 -117 107 -101 ct 107 -101 107 -101 107 0 ct +107 0 107 0 83 0 ct 83 0 83 0 83 -143 ct 83 -143 83 -143 107 -143 ct 107 -143 107 -143 107 -122 ct +122 -138 138 -146 155 -146 ct 169 -146 181 -142 189 -133 ct 198 -125 202 -113 202 -97 ct +202 -97 202 -97 202 0 ct p ef +231 -72 m 231 -95 238 -113 251 -126 ct 265 -139 282 -146 302 -146 ct 319 -146 336 -141 351 -132 ct +351 -132 351 -132 344 -113 ct 331 -121 317 -125 303 -125 ct 289 -125 278 -120 269 -110 ct +260 -101 256 -88 256 -72 ct 256 -55 260 -42 269 -33 ct 278 -23 289 -18 303 -18 ct +316 -18 331 -23 346 -32 ct 346 -32 346 -32 353 -13 ct 337 -2 320 3 303 3 ct 281 3 264 -4 251 -18 ct +238 -31 231 -49 231 -72 ct p ef +408 0 m 384 0 l 384 -205 l 408 -205 l 408 0 l p ef +566 0 m 566 0 566 0 542 0 ct 542 0 542 0 542 -21 ct 527 -5 511 3 494 3 ct 480 3 468 -1 460 -10 ct +451 -18 447 -30 447 -46 ct 447 -46 447 -46 447 -143 ct 447 -143 447 -143 471 -143 ct +471 -143 471 -143 471 -52 ct 471 -42 474 -33 479 -27 ct 484 -21 492 -18 501 -18 ct +515 -18 529 -26 542 -42 ct 542 -42 542 -42 542 -143 ct 542 -143 542 -143 566 -143 ct +566 -143 566 -143 566 0 ct p ef +722 0 m 722 0 722 0 698 0 ct 698 0 698 0 698 -18 ct 688 -4 673 3 656 3 ct 637 3 622 -4 611 -18 ct +601 -32 595 -50 595 -74 ct 595 -96 601 -113 612 -126 ct 623 -139 637 -146 654 -146 ct +673 -146 688 -139 698 -125 ct 698 -125 698 -125 698 -205 ct 698 -205 698 -205 722 -205 ct +722 -205 722 -205 722 0 ct p +698 -42 m 698 -42 698 -42 698 -102 ct 695 -109 690 -114 683 -118 ct 676 -123 669 -125 661 -125 ct +648 -125 638 -120 631 -111 ct 624 -102 620 -89 620 -72 ct 620 -55 624 -42 631 -32 ct +638 -23 649 -18 661 -18 ct 667 -18 672 -19 677 -22 ct 683 -24 687 -28 692 -32 ct +696 -37 698 -40 698 -42 ct p ef +887 -15 m 867 -3 847 3 827 3 ct 803 3 785 -4 772 -17 ct 759 -30 752 -49 752 -72 ct +752 -94 758 -112 770 -126 ct 783 -139 799 -146 820 -146 ct 839 -146 854 -140 866 -127 ct +878 -114 884 -97 884 -75 ct 884 -75 884 -75 884 -69 ct 884 -69 884 -69 777 -69 ct +778 -52 782 -40 791 -31 ct 799 -22 811 -18 827 -18 ct 845 -18 862 -23 880 -34 ct +880 -34 880 -34 887 -15 ct p +859 -88 m 858 -99 854 -108 846 -115 ct 839 -122 830 -125 820 -125 ct 809 -125 800 -122 792 -115 ct +785 -109 780 -100 778 -88 ct 778 -88 778 -88 859 -88 ct p ef +pom +gr +gr +gs +gs +pum +2974 9847 t +0.003 0.003 0.003 c 237 -232 m 237 -232 237 -232 217 -199 ct 194 -214 169 -222 143 -222 ct +124 -222 108 -219 97 -213 ct 86 -206 80 -198 80 -188 ct 80 -182 83 -177 88 -172 ct +94 -167 108 -160 131 -152 ct 148 -146 163 -140 174 -135 ct 185 -129 194 -122 202 -112 ct +210 -102 214 -90 214 -75 ct 214 -50 204 -30 183 -16 ct 162 -1 135 6 101 6 ct 62 6 29 -3 1 -20 ct +1 -20 1 -20 21 -53 ct 46 -38 73 -30 101 -30 ct 121 -30 138 -34 152 -42 ct 165 -49 172 -59 172 -71 ct +172 -79 169 -86 162 -93 ct 155 -100 139 -108 112 -118 ct 80 -130 60 -141 51 -151 ct +42 -161 38 -172 38 -184 ct 38 -207 48 -224 67 -237 ct 87 -250 111 -257 141 -257 ct +177 -257 209 -249 237 -232 ct p ef +406 -257 m 438 -257 464 -248 482 -231 ct 501 -214 510 -190 510 -161 ct 510 -116 497 -78 470 -44 ct +444 -11 411 6 370 6 ct 338 6 312 -3 293 -21 ct 274 -38 265 -62 265 -91 ct 265 -136 278 -175 305 -208 ct +331 -241 365 -257 406 -257 ct p +370 -31 m 398 -31 420 -44 438 -71 ct 456 -98 465 -128 465 -160 ct 465 -178 460 -193 449 -204 ct +438 -215 424 -220 405 -220 ct 377 -220 354 -207 336 -182 ct 319 -157 310 -128 310 -94 ct +310 -76 315 -60 326 -49 ct 337 -37 351 -31 370 -31 ct p ef +792 -251 m 792 -251 792 -251 739 0 ct 739 0 739 0 696 0 ct 696 0 696 0 704 -39 ct +692 -26 678 -15 661 -7 ct 645 2 628 6 613 6 ct 591 6 574 0 562 -11 ct 551 -23 545 -39 545 -60 ct +545 -69 547 -85 552 -107 ct 552 -107 552 -107 583 -251 ct 583 -251 583 -251 626 -251 ct +626 -251 626 -251 595 -107 ct 593 -97 591 -88 589 -80 ct 588 -73 587 -67 587 -65 ct +587 -42 599 -31 623 -31 ct 635 -31 650 -35 667 -44 ct 684 -53 699 -65 713 -79 ct +713 -79 713 -79 749 -251 ct 749 -251 749 -251 792 -251 ct p ef +996 -246 m 996 -246 996 -246 977 -209 ct 970 -214 963 -216 957 -216 ct 953 -216 948 -215 943 -213 ct +938 -211 933 -208 928 -204 ct 923 -200 919 -196 914 -191 ct 910 -186 905 -181 901 -175 ct +897 -169 893 -164 889 -157 ct 883 -148 879 -140 878 -133 ct 878 -133 878 -133 850 0 ct +850 0 850 0 807 0 ct 807 0 807 0 860 -251 ct 860 -251 860 -251 901 -251 ct 901 -251 901 -251 889 -193 ct +903 -215 915 -232 928 -242 ct 940 -252 954 -257 968 -257 ct 980 -257 989 -253 996 -246 ct +p ef +1216 -233 m 1216 -233 1216 -233 1197 -200 ct 1176 -214 1154 -221 1129 -221 ct +1100 -221 1075 -209 1055 -185 ct 1035 -160 1025 -131 1025 -96 ct 1025 -75 1030 -58 1041 -47 ct +1052 -36 1068 -31 1087 -31 ct 1112 -31 1139 -39 1170 -56 ct 1170 -56 1170 -56 1175 -22 ct +1143 -3 1112 6 1081 6 ct 1050 6 1025 -3 1007 -20 ct 989 -38 980 -62 980 -93 ct +980 -139 995 -178 1024 -209 ct 1053 -241 1088 -257 1130 -257 ct 1145 -257 1161 -255 1177 -250 ct +1193 -246 1206 -240 1216 -233 ct p ef +1439 -22 m 1407 -3 1372 6 1336 6 ct 1303 6 1278 -3 1259 -20 ct 1240 -37 1230 -60 1230 -89 ct +1230 -134 1244 -173 1271 -207 ct 1298 -240 1332 -257 1373 -257 ct 1404 -257 1428 -249 1445 -233 ct +1462 -216 1470 -193 1470 -164 ct 1470 -156 1468 -142 1465 -122 ct 1465 -122 1465 -122 1278 -122 ct +1276 -114 1275 -104 1275 -92 ct 1275 -74 1280 -59 1291 -48 ct 1302 -37 1318 -31 1338 -31 ct +1366 -31 1398 -40 1433 -58 ct 1433 -58 1433 -58 1439 -22 ct p +1426 -155 m 1427 -159 1427 -161 1427 -163 ct 1427 -181 1422 -196 1412 -206 ct +1403 -217 1390 -222 1373 -222 ct 1334 -222 1305 -200 1288 -155 ct 1288 -155 1288 -155 1426 -155 ct +p ef +1881 -233 m 1881 -233 1881 -233 1862 -200 ct 1841 -214 1819 -221 1794 -221 ct +1765 -221 1740 -209 1720 -185 ct 1700 -160 1690 -131 1690 -96 ct 1690 -75 1695 -58 1706 -47 ct +1717 -36 1733 -31 1752 -31 ct 1777 -31 1804 -39 1835 -56 ct 1835 -56 1835 -56 1840 -22 ct +1808 -3 1777 6 1746 6 ct 1715 6 1690 -3 1672 -20 ct 1654 -38 1645 -62 1645 -93 ct +1645 -139 1660 -178 1689 -209 ct 1718 -241 1753 -257 1795 -257 ct 1810 -257 1826 -255 1842 -250 ct +1858 -246 1871 -240 1881 -233 ct p ef +2036 -257 m 2068 -257 2094 -248 2112 -231 ct 2131 -214 2140 -190 2140 -161 ct +2140 -116 2127 -78 2100 -44 ct 2074 -11 2041 6 2000 6 ct 1968 6 1942 -3 1923 -21 ct +1904 -38 1895 -62 1895 -91 ct 1895 -136 1908 -175 1935 -208 ct 1961 -241 1995 -257 2036 -257 ct +p +2000 -31 m 2028 -31 2050 -44 2068 -71 ct 2086 -98 2095 -128 2095 -160 ct 2095 -178 2090 -193 2079 -204 ct +2068 -215 2054 -220 2035 -220 ct 2007 -220 1984 -207 1966 -182 ct 1949 -157 1940 -128 1940 -94 ct +1940 -76 1945 -60 1956 -49 ct 1967 -37 1981 -31 2000 -31 ct p ef +2446 -359 m 2446 -359 2446 -359 2369 0 ct 2369 0 2369 0 2326 0 ct 2326 0 2326 0 2332 -28 ct +2312 -5 2287 6 2258 6 ct 2232 6 2210 -3 2194 -21 ct 2178 -39 2170 -63 2170 -93 ct +2170 -142 2183 -181 2210 -212 ct 2236 -242 2269 -257 2308 -257 ct 2335 -257 2357 -247 2374 -227 ct +2374 -227 2374 -227 2402 -359 ct 2402 -359 2402 -359 2446 -359 ct p +2365 -186 m 2350 -209 2331 -220 2308 -220 ct 2281 -220 2259 -208 2241 -184 ct +2224 -160 2215 -131 2215 -96 ct 2215 -76 2220 -61 2229 -49 ct 2239 -37 2252 -31 2269 -31 ct +2286 -31 2302 -37 2317 -49 ct 2332 -61 2340 -68 2341 -72 ct 2341 -72 2341 -72 2365 -186 ct +p ef +2654 -22 m 2622 -3 2587 6 2551 6 ct 2518 6 2493 -3 2474 -20 ct 2455 -37 2445 -60 2445 -89 ct +2445 -134 2459 -173 2486 -207 ct 2513 -240 2547 -257 2588 -257 ct 2619 -257 2643 -249 2660 -233 ct +2677 -216 2685 -193 2685 -164 ct 2685 -156 2683 -142 2680 -122 ct 2680 -122 2680 -122 2493 -122 ct +2491 -114 2490 -104 2490 -92 ct 2490 -74 2495 -59 2506 -48 ct 2517 -37 2533 -31 2553 -31 ct +2581 -31 2613 -40 2648 -58 ct 2648 -58 2648 -58 2654 -22 ct p +2641 -155 m 2642 -159 2642 -161 2642 -163 ct 2642 -181 2637 -196 2627 -206 ct +2618 -217 2605 -222 2588 -222 ct 2549 -222 2520 -200 2503 -155 ct 2503 -155 2503 -155 2641 -155 ct +p ef +pom +gr +gr +0 lw [ 508 508 508 508 ] 0 ld +0.003 0.003 0.003 c 2198 10743 m 19460 10743 l ps +2198 12343 m 19460 12343 l ps +1.000 0.003 0.003 c 9889 10903 m 9889 11895 l 9772 11895 l 10007 12226 l +10242 11895 l 10124 11895 l 10124 10903 l 9889 10903 l p ef +gs +gs +pum +10462 11593 t +0.003 0.003 0.003 c 350 -251 m 275 0 l 238 0 l 178 -202 l 116 0 l 79 0 l +6 -251 l 49 -251 l 100 -57 l 157 -251 l 198 -251 l 256 -57 l 307 -251 l +350 -251 l p ef +606 -24 m 570 -4 536 6 502 6 ct 461 6 429 -6 406 -29 ct 383 -53 371 -85 371 -126 ct +371 -165 382 -197 403 -221 ct 424 -245 453 -257 490 -257 ct 522 -257 549 -246 570 -224 ct +591 -201 601 -172 601 -134 ct 601 -134 601 -134 601 -123 ct 601 -123 601 -123 414 -123 ct +415 -93 423 -70 438 -55 ct 453 -39 474 -31 501 -31 ct 532 -31 563 -40 594 -58 ct +594 -58 594 -58 606 -24 ct p +558 -156 m 556 -176 548 -192 535 -204 ct 522 -216 507 -222 489 -222 ct 470 -222 454 -216 441 -205 ct +427 -193 419 -177 415 -156 ct 415 -156 415 -156 558 -156 ct p ef +879 0 m 879 0 879 0 834 0 ct 831 -4 829 -10 827 -17 ct 825 -24 824 -30 824 -35 ct +794 -8 761 6 726 6 ct 702 6 683 0 668 -12 ct 653 -25 646 -42 646 -64 ct 646 -81 650 -96 659 -108 ct +668 -120 681 -129 699 -136 ct 716 -142 739 -147 766 -148 ct 766 -148 766 -148 823 -152 ct +823 -152 823 -152 823 -160 ct 823 -183 818 -199 809 -208 ct 800 -217 783 -222 760 -222 ct +748 -222 734 -220 718 -215 ct 701 -210 687 -204 676 -198 ct 676 -198 676 -198 663 -230 ct +677 -238 693 -244 713 -249 ct 732 -254 750 -257 767 -257 ct 800 -257 825 -249 841 -234 ct +857 -219 865 -196 865 -165 ct 865 -165 865 -165 865 -60 ct 865 -34 870 -14 879 0 ct +p +823 -72 m 823 -72 823 -72 823 -119 ct 787 -117 764 -115 753 -114 ct 742 -113 731 -110 720 -107 ct +710 -103 702 -97 696 -91 ct 691 -84 688 -76 688 -65 ct 688 -55 692 -47 700 -41 ct +708 -34 719 -31 732 -31 ct 748 -31 765 -35 782 -42 ct 799 -50 813 -60 823 -72 ct +p ef +1146 -251 m 1046 0 l 1007 0 l 907 -251 l 950 -251 l 1027 -54 l 1103 -251 l +1146 -251 l p ef +1219 0 m 1177 0 l 1177 -251 l 1219 -251 l 1219 0 l p +1198 -359 m 1205 -359 1211 -356 1216 -351 ct 1221 -346 1224 -340 1224 -333 ct +1224 -326 1221 -320 1216 -315 ct 1211 -311 1205 -308 1198 -308 ct 1191 -308 1185 -311 1180 -315 ct +1176 -320 1173 -326 1173 -333 ct 1173 -340 1175 -347 1180 -352 ct 1185 -357 1191 -359 1198 -359 ct +p ef +1495 0 m 1495 0 1495 0 1453 0 ct 1453 0 1453 0 1453 -160 ct 1453 -179 1448 -194 1439 -204 ct +1429 -215 1417 -220 1400 -220 ct 1375 -220 1351 -206 1328 -179 ct 1328 -179 1328 -179 1328 0 ct +1328 0 1328 0 1286 0 ct 1286 0 1286 0 1286 -251 ct 1286 -251 1286 -251 1328 -251 ct +1328 -251 1328 -251 1328 -216 ct 1354 -243 1382 -257 1412 -257 ct 1437 -257 1458 -249 1473 -234 ct +1488 -219 1495 -198 1495 -171 ct 1495 -171 1495 -171 1495 0 ct p ef +1769 8 m 1769 39 1760 63 1741 79 ct 1722 96 1694 104 1659 104 ct 1623 104 1589 95 1556 76 ct +1556 76 1556 76 1568 42 ct 1600 59 1631 67 1660 67 ct 1681 67 1698 62 1709 51 ct +1721 41 1727 26 1727 7 ct 1727 7 1727 7 1727 -31 ct 1709 -6 1684 6 1654 6 ct 1621 6 1595 -6 1576 -30 ct +1557 -55 1548 -88 1548 -131 ct 1548 -168 1558 -199 1577 -222 ct 1597 -245 1621 -257 1651 -257 ct +1684 -257 1709 -245 1727 -220 ct 1727 -220 1727 -220 1727 -251 ct 1727 -251 1727 -251 1769 -251 ct +1769 -251 1769 -251 1769 8 ct p +1727 -73 m 1727 -73 1727 -73 1727 -180 ct 1721 -191 1713 -201 1701 -209 ct +1689 -216 1676 -220 1662 -220 ct 1639 -220 1622 -212 1609 -196 ct 1597 -179 1591 -156 1591 -127 ct +1591 -97 1597 -73 1610 -56 ct 1623 -39 1641 -31 1663 -31 ct 1672 -31 1681 -33 1691 -37 ct +1700 -42 1709 -48 1716 -56 ct 1723 -64 1727 -70 1727 -73 ct p ef +2092 69 m 2092 69 2092 69 2074 80 ct 2040 43 2016 8 2000 -26 ct 1985 -60 1977 -98 1977 -140 ct +1977 -181 1985 -219 2000 -253 ct 2016 -287 2040 -322 2074 -359 ct 2074 -359 2074 -359 2092 -348 ct +2068 -315 2050 -282 2039 -249 ct 2028 -216 2022 -180 2022 -140 ct 2022 -101 2028 -65 2039 -31 ct +2050 2 2068 35 2092 69 ct p ef +2360 0 m 2360 0 2360 0 2315 0 ct 2312 -4 2310 -10 2308 -17 ct 2306 -24 2305 -30 2305 -35 ct +2275 -8 2242 6 2207 6 ct 2183 6 2164 0 2149 -12 ct 2134 -25 2127 -42 2127 -64 ct +2127 -81 2131 -96 2140 -108 ct 2149 -120 2162 -129 2180 -136 ct 2197 -142 2220 -147 2247 -148 ct +2247 -148 2247 -148 2304 -152 ct 2304 -152 2304 -152 2304 -160 ct 2304 -183 2299 -199 2290 -208 ct +2281 -217 2264 -222 2241 -222 ct 2229 -222 2215 -220 2199 -215 ct 2182 -210 2168 -204 2157 -198 ct +2157 -198 2157 -198 2144 -230 ct 2158 -238 2174 -244 2194 -249 ct 2213 -254 2231 -257 2248 -257 ct +2281 -257 2306 -249 2322 -234 ct 2338 -219 2346 -196 2346 -165 ct 2346 -165 2346 -165 2346 -60 ct +2346 -34 2351 -14 2360 0 ct p +2304 -72 m 2304 -72 2304 -72 2304 -119 ct 2268 -117 2245 -115 2234 -114 ct +2223 -113 2212 -110 2201 -107 ct 2191 -103 2183 -97 2177 -91 ct 2172 -84 2169 -76 2169 -65 ct +2169 -55 2173 -47 2181 -41 ct 2189 -34 2200 -31 2213 -31 ct 2229 -31 2246 -35 2263 -42 ct +2280 -50 2294 -60 2304 -72 ct p ef +2403 -126 m 2403 -167 2415 -200 2439 -223 ct 2463 -246 2492 -257 2528 -257 ct +2557 -257 2586 -249 2613 -232 ct 2613 -232 2613 -232 2601 -199 ct 2577 -213 2553 -220 2528 -220 ct +2504 -220 2484 -211 2469 -194 ct 2454 -177 2446 -154 2446 -126 ct 2446 -97 2454 -74 2469 -57 ct +2485 -40 2505 -31 2528 -31 ct 2552 -31 2578 -39 2604 -56 ct 2604 -56 2604 -56 2617 -23 ct +2589 -4 2560 6 2528 6 ct 2491 6 2461 -6 2438 -30 ct 2415 -54 2403 -86 2403 -126 ct +p ef +2894 -145 m 2796 -145 l 2796 -47 l 2758 -47 l 2758 -145 l 2660 -145 l +2660 -183 l 2758 -183 l 2758 -281 l 2796 -281 l 2796 -183 l 2894 -183 l +2894 -145 l p ef +3182 -145 m 3084 -145 l 3084 -47 l 3046 -47 l 3046 -145 l 2948 -145 l +2948 -183 l 3046 -183 l 3046 -281 l 3084 -281 l 3084 -183 l 3182 -183 l +3182 -145 l p ef +3243 -359 m 3277 -322 3302 -287 3318 -253 ct 3333 -219 3341 -181 3341 -140 ct +3341 -98 3333 -60 3318 -26 ct 3302 8 3277 43 3243 80 ct 3243 80 3243 80 3225 69 ct +3249 36 3267 3 3279 -30 ct 3290 -63 3296 -100 3296 -140 ct 3296 -180 3290 -216 3279 -249 ct +3267 -282 3249 -315 3225 -348 ct 3225 -348 3225 -348 3243 -359 ct p ef +pom +gr +gr +0.503 0.503 0.503 c 14611 17623 m 10090 17623 l 10090 12802 l 19133 12802 l +19133 17623 l 14611 17623 l p ef +50 lw [ ] 0 ld +14611 17623 m 10090 17623 l 10090 12802 l 19133 12802 l 19133 17623 l +14611 17623 l pc +1.000 0.902 0.777 c 14511 17523 m 9990 17523 l 9990 12702 l 19033 12702 l +19033 17523 l 14511 17523 l p ef +0.003 0.003 0.003 c 14511 17523 m 9990 17523 l 9990 12702 l 19033 12702 l +19033 17523 l 14511 17523 l pc +gs +gs +pum +10197 13186 t +35 0 m 58 -93 l 11 -93 l 18 -124 l 66 -124 l 80 -184 l 33 -184 l +41 -215 l 88 -215 l 111 -306 l 142 -306 l 120 -215 l 168 -215 l 191 -306 l +222 -306 l 200 -215 l 246 -215 l 239 -184 l 192 -184 l 177 -124 l +224 -124 l 216 -93 l 169 -93 l 146 0 l 115 0 l 138 -93 l 89 -93 l +66 0 l 35 0 l p +97 -124 m 146 -124 l 160 -184 l 112 -184 l 97 -124 l p ef +371 0 m 371 -193 l 289 -193 l 289 -224 l 412 -224 l 412 0 l 371 0 l +p +366 -275 m 366 -326 l 417 -326 l 417 -275 l 366 -275 l p ef +545 0 m 545 0 545 0 545 -224 ct 545 -224 545 -224 586 -224 ct 586 -224 586 -224 584 -182 ct +584 -182 584 -182 586 -182 ct 596 -198 607 -209 620 -217 ct 632 -225 647 -229 663 -229 ct +684 -229 700 -223 711 -210 ct 722 -197 727 -178 727 -153 ct 727 -153 727 -153 727 0 ct +727 0 727 0 686 0 ct 686 0 686 0 686 -142 ct 686 -159 683 -172 678 -179 ct 672 -186 663 -190 650 -190 ct +640 -190 630 -186 619 -179 ct 608 -172 597 -161 586 -146 ct 586 -146 586 -146 586 0 ct +586 0 586 0 545 0 ct p ef +990 -7 m 966 1 942 5 918 5 ct 879 5 849 -5 828 -26 ct 807 -46 796 -75 796 -112 ct +796 -149 806 -177 827 -198 ct 848 -219 877 -229 914 -229 ct 938 -229 962 -225 986 -218 ct +986 -218 986 -218 986 -184 ct 959 -193 937 -198 918 -198 ct 894 -198 874 -190 860 -175 ct +846 -160 839 -139 839 -112 ct 839 -85 846 -64 861 -49 ct 876 -34 897 -26 923 -26 ct +943 -26 965 -31 990 -40 ct 990 -40 990 -40 990 -7 ct p ef +1138 0 m 1138 -295 l 1051 -295 l 1051 -326 l 1179 -326 l 1179 0 l +1138 0 l p ef +1488 -224 m 1488 -224 1488 -224 1488 0 ct 1488 0 1488 0 1447 0 ct 1447 0 1447 0 1449 -42 ct +1449 -42 1449 -42 1447 -42 ct 1438 -26 1426 -15 1414 -7 ct 1401 1 1386 5 1370 5 ct +1349 5 1333 -1 1322 -14 ct 1311 -27 1306 -46 1306 -71 ct 1306 -71 1306 -71 1306 -224 ct +1306 -224 1306 -224 1347 -224 ct 1347 -224 1347 -224 1347 -82 ct 1347 -65 1350 -52 1355 -45 ct +1361 -38 1370 -34 1383 -34 ct 1393 -34 1403 -38 1414 -45 ct 1425 -52 1436 -63 1447 -78 ct +1447 -78 1447 -78 1447 -224 ct 1447 -224 1447 -224 1488 -224 ct p ef +1706 0 m 1706 0 1706 0 1708 -42 ct 1708 -42 1708 -42 1706 -42 ct 1696 -26 1685 -15 1673 -7 ct +1660 1 1647 5 1632 5 ct 1607 5 1587 -5 1572 -24 ct 1557 -44 1550 -71 1550 -105 ct +1550 -142 1559 -172 1576 -195 ct 1594 -218 1616 -229 1644 -229 ct 1656 -229 1668 -226 1678 -221 ct +1688 -216 1698 -209 1706 -198 ct 1706 -198 1706 -198 1708 -198 ct 1708 -198 1708 -198 1706 -229 ct +1706 -229 1706 -229 1706 -326 ct 1706 -326 1706 -326 1747 -326 ct 1747 -326 1747 -326 1747 0 ct +1747 0 1747 0 1706 0 ct p +1706 -168 m 1696 -178 1687 -185 1678 -190 ct 1668 -195 1659 -198 1650 -198 ct +1632 -198 1618 -190 1608 -175 ct 1598 -159 1593 -137 1593 -109 ct 1593 -83 1597 -63 1605 -50 ct +1613 -38 1624 -31 1640 -31 ct 1652 -31 1663 -35 1674 -42 ct 1685 -49 1696 -59 1706 -73 ct +1706 -73 1706 -73 1706 -168 ct p ef +2004 -9 m 1976 0 1950 5 1926 5 ct 1888 5 1859 -5 1838 -25 ct 1817 -45 1807 -73 1807 -110 ct +1807 -144 1817 -173 1837 -195 ct 1857 -218 1882 -229 1913 -229 ct 1944 -229 1966 -220 1981 -201 ct +1996 -182 2003 -153 2003 -114 ct 2003 -114 2003 -114 2003 -101 ct 2003 -101 2003 -101 1849 -101 ct +1850 -76 1858 -57 1872 -45 ct 1886 -32 1905 -26 1931 -26 ct 1954 -26 1978 -31 2004 -42 ct +2004 -42 2004 -42 2004 -9 ct p +1850 -132 m 1850 -132 1850 -132 1960 -132 ct 1960 -132 1960 -132 1960 -138 ct +1960 -158 1956 -173 1947 -183 ct 1938 -193 1926 -198 1909 -198 ct 1892 -198 1879 -192 1868 -181 ct +1858 -169 1852 -153 1850 -132 ct p ef +2337 -214 m 2337 -214 2337 -214 2337 -260 ct 2337 -282 2341 -298 2350 -309 ct +2358 -320 2371 -326 2388 -326 ct 2388 -326 2388 -326 2388 -306 ct 2381 -306 2375 -303 2371 -298 ct +2368 -293 2366 -286 2366 -276 ct 2366 -276 2366 -276 2366 -265 ct 2366 -265 2366 -265 2388 -265 ct +2388 -265 2388 -265 2388 -214 ct 2388 -214 2388 -214 2337 -214 ct p +2439 -214 m 2439 -214 2439 -214 2439 -260 ct 2439 -282 2443 -298 2452 -309 ct +2460 -320 2473 -326 2490 -326 ct 2490 -326 2490 -326 2490 -306 ct 2483 -306 2477 -303 2473 -298 ct +2470 -293 2468 -286 2468 -276 ct 2468 -276 2468 -276 2468 -265 ct 2468 -265 2468 -265 2490 -265 ct +2490 -265 2490 -265 2490 -214 ct 2490 -214 2490 -214 2439 -214 ct p ef +2647 0 m 2647 -275 l 2545 -275 l 2545 -306 l 2790 -306 l 2790 -275 l +2688 -275 l 2688 0 l 2647 0 l p ef +2966 -26 m 2942 -5 2917 5 2893 5 ct 2872 5 2855 -1 2842 -13 ct 2829 -24 2822 -39 2822 -57 ct +2822 -81 2832 -99 2853 -114 ct 2874 -128 2901 -135 2935 -135 ct 2935 -135 2935 -135 2960 -135 ct +2960 -135 2960 -135 2960 -154 ct 2960 -169 2956 -180 2949 -187 ct 2941 -194 2930 -198 2915 -198 ct +2891 -198 2866 -191 2841 -177 ct 2841 -177 2841 -177 2841 -213 ct 2870 -224 2897 -229 2923 -229 ct +2952 -229 2972 -223 2983 -212 ct 2995 -201 3001 -181 3001 -153 ct 3001 -153 3001 -153 3001 -59 ct +3001 -45 3002 -36 3005 -31 ct 3008 -26 3014 -24 3021 -24 ct 3024 -24 3028 -25 3034 -26 ct +3034 -26 3034 -26 3038 -2 ct 3024 3 3014 5 3007 5 ct 2997 5 2988 2 2982 -3 ct 2975 -8 2970 -16 2966 -26 ct +p +2960 -53 m 2960 -53 2960 -53 2960 -110 ct 2960 -110 2960 -110 2948 -110 ct +2920 -110 2899 -106 2885 -99 ct 2871 -91 2864 -80 2864 -64 ct 2864 -52 2867 -43 2874 -37 ct +2880 -31 2890 -28 2903 -28 ct 2921 -28 2940 -36 2960 -53 ct p ef +3112 0 m 3112 0 3112 0 3112 -224 ct 3112 -224 3112 -224 3153 -224 ct 3153 -224 3153 -224 3151 -182 ct +3151 -182 3151 -182 3153 -182 ct 3163 -198 3175 -209 3189 -217 ct 3203 -225 3218 -229 3236 -229 ct +3248 -229 3262 -227 3277 -224 ct 3277 -224 3277 -224 3277 -160 ct 3277 -160 3277 -160 3246 -160 ct +3246 -160 3246 -160 3246 -191 ct 3240 -192 3234 -193 3229 -193 ct 3215 -193 3202 -189 3190 -181 ct +3177 -173 3165 -161 3153 -145 ct 3153 -145 3153 -145 3153 0 ct 3153 0 3153 0 3112 0 ct +p ef +3345 75 m 3345 75 3345 75 3349 41 ct 3374 51 3397 56 3418 56 ct 3440 56 3456 51 3465 42 ct +3475 33 3481 17 3484 -6 ct 3484 -6 3484 -6 3488 -46 ct 3488 -46 3488 -46 3484 -46 ct +3476 -31 3465 -19 3453 -12 ct 3440 -4 3426 0 3410 0 ct 3385 0 3365 -10 3350 -29 ct +3335 -49 3327 -75 3327 -108 ct 3327 -144 3336 -173 3353 -195 ct 3371 -218 3393 -229 3421 -229 ct +3443 -229 3465 -219 3486 -198 ct 3486 -198 3486 -198 3489 -198 ct 3489 -198 3489 -198 3489 -224 ct +3489 -224 3489 -224 3525 -224 ct 3525 -224 3525 -224 3525 -45 ct 3525 -15 3523 6 3519 21 ct +3515 36 3508 49 3497 60 ct 3480 78 3454 87 3417 87 ct 3396 87 3372 83 3345 75 ct +p +3484 -80 m 3484 -80 3484 -80 3484 -167 ct 3466 -188 3446 -198 3427 -198 ct +3408 -198 3394 -191 3384 -176 ct 3375 -162 3370 -140 3370 -111 ct 3370 -86 3374 -67 3382 -55 ct +3391 -42 3403 -36 3420 -36 ct 3432 -36 3443 -40 3454 -47 ct 3465 -54 3475 -65 3484 -80 ct +p ef +3782 -9 m 3754 0 3728 5 3704 5 ct 3666 5 3637 -5 3616 -25 ct 3595 -45 3585 -73 3585 -110 ct +3585 -144 3595 -173 3615 -195 ct 3635 -218 3660 -229 3691 -229 ct 3722 -229 3744 -220 3759 -201 ct +3774 -182 3781 -153 3781 -114 ct 3781 -114 3781 -114 3781 -101 ct 3781 -101 3781 -101 3627 -101 ct +3628 -76 3636 -57 3650 -45 ct 3664 -32 3683 -26 3709 -26 ct 3732 -26 3756 -31 3782 -42 ct +3782 -42 3782 -42 3782 -9 ct p +3628 -132 m 3628 -132 3628 -132 3738 -132 ct 3738 -132 3738 -132 3738 -138 ct +3738 -158 3734 -173 3725 -183 ct 3716 -193 3704 -198 3687 -198 ct 3670 -198 3657 -192 3646 -181 ct +3636 -169 3630 -153 3628 -132 ct p ef +4038 0 m 4018 3 3998 5 3979 5 ct 3946 5 3923 -1 3911 -13 ct 3899 -25 3893 -47 3893 -80 ct +3893 -80 3893 -80 3893 -188 ct 3893 -188 3893 -188 3837 -188 ct 3837 -188 3837 -188 3837 -219 ct +3837 -219 3837 -219 3893 -219 ct 3893 -219 3893 -219 3893 -267 ct 3893 -267 3893 -267 3934 -267 ct +3934 -267 3934 -267 3934 -219 ct 3934 -219 3934 -219 4033 -219 ct 4033 -219 4033 -219 4033 -188 ct +4033 -188 4033 -188 3934 -188 ct 3934 -188 3934 -188 3934 -74 ct 3934 -61 3935 -53 3936 -48 ct +3938 -43 3941 -39 3947 -35 ct 3956 -29 3969 -26 3987 -26 ct 4004 -26 4021 -28 4038 -31 ct +4038 -31 4038 -31 4038 0 ct p ef +4161 0 m 4161 -61 l 4222 -61 l 4222 0 l 4161 0 l p ef +4355 0 m 4355 0 4355 0 4355 -326 ct 4355 -326 4355 -326 4396 -326 ct 4396 -326 4396 -326 4396 -224 ct +4396 -224 4396 -224 4394 -182 ct 4394 -182 4394 -182 4396 -182 ct 4406 -198 4417 -209 4430 -217 ct +4442 -225 4457 -229 4473 -229 ct 4494 -229 4510 -223 4521 -210 ct 4532 -197 4537 -178 4537 -153 ct +4537 -153 4537 -153 4537 0 ct 4537 0 4537 0 4496 0 ct 4496 0 4496 0 4496 -142 ct +4496 -159 4493 -172 4488 -179 ct 4482 -186 4473 -190 4460 -190 ct 4450 -190 4440 -186 4429 -179 ct +4418 -172 4407 -161 4396 -146 ct 4396 -146 4396 -146 4396 0 ct 4396 0 4396 0 4355 0 ct +p ef +4623 -214 m 4623 -214 4623 -214 4623 -260 ct 4623 -282 4627 -298 4636 -309 ct +4644 -320 4657 -326 4674 -326 ct 4674 -326 4674 -326 4674 -306 ct 4667 -306 4661 -303 4657 -298 ct +4654 -293 4652 -286 4652 -276 ct 4652 -276 4652 -276 4652 -265 ct 4652 -265 4652 -265 4674 -265 ct +4674 -265 4674 -265 4674 -214 ct 4674 -214 4674 -214 4623 -214 ct p +4725 -214 m 4725 -214 4725 -214 4725 -260 ct 4725 -282 4729 -298 4738 -309 ct +4746 -320 4759 -326 4776 -326 ct 4776 -326 4776 -326 4776 -306 ct 4769 -306 4763 -303 4759 -298 ct +4756 -293 4754 -286 4754 -276 ct 4754 -276 4754 -276 4754 -265 ct 4754 -265 4754 -265 4776 -265 ct +4776 -265 4776 -265 4776 -214 ct 4776 -214 4776 -214 4725 -214 ct p ef +pom +gr +gs +pum +15277 13186 t +0.003 0.503 0.003 c 239 -326 m 65 61 l 15 61 l 189 -326 l 239 -326 l +p ef +493 -326 m 319 61 l 269 61 l 443 -326 l 493 -326 l p ef +847 0 m 847 0 847 0 847 -178 ct 847 -178 847 -178 804 -178 ct 804 -178 804 -178 804 -219 ct +804 -219 804 -219 847 -219 ct 847 -219 847 -219 847 -251 ct 847 -278 855 -298 870 -311 ct +885 -324 908 -331 939 -331 ct 965 -331 990 -328 1015 -322 ct 1015 -322 1015 -322 1015 -278 ct +989 -286 968 -290 952 -290 ct 936 -290 925 -287 918 -281 ct 911 -275 908 -265 908 -250 ct +908 -250 908 -250 908 -219 ct 908 -219 908 -219 995 -219 ct 995 -219 995 -219 995 -178 ct +995 -178 995 -178 908 -178 ct 908 -178 908 -178 908 0 ct 908 0 908 0 847 0 ct p ef +1142 5 m 1108 5 1080 -6 1059 -27 ct 1038 -49 1027 -77 1027 -112 ct 1027 -148 1038 -176 1059 -197 ct +1080 -218 1108 -229 1144 -229 ct 1179 -229 1207 -218 1228 -197 ct 1249 -176 1260 -148 1260 -112 ct +1260 -76 1249 -48 1228 -27 ct 1207 -6 1178 5 1142 5 ct p +1143 -36 m 1160 -36 1173 -42 1181 -55 ct 1190 -68 1194 -87 1194 -112 ct 1194 -138 1190 -156 1181 -169 ct +1173 -182 1160 -188 1144 -188 ct 1127 -188 1114 -182 1106 -169 ct 1097 -156 1093 -137 1093 -112 ct +1093 -87 1097 -68 1105 -55 ct 1114 -42 1126 -36 1143 -36 ct p ef +1316 0 m 1316 0 1316 0 1316 -224 ct 1316 -224 1316 -224 1377 -224 ct 1377 -224 1377 -224 1375 -181 ct +1375 -181 1375 -181 1377 -181 ct 1387 -197 1399 -209 1413 -217 ct 1426 -225 1442 -229 1460 -229 ct +1471 -229 1486 -227 1502 -224 ct 1502 -224 1502 -224 1502 -149 ct 1502 -149 1502 -149 1461 -149 ct +1461 -149 1461 -149 1461 -173 ct 1456 -174 1453 -174 1450 -174 ct 1435 -174 1422 -170 1409 -163 ct +1397 -156 1386 -145 1377 -130 ct 1377 -130 1377 -130 1377 0 ct 1377 0 1377 0 1316 0 ct +p ef +1880 0 m 1880 -285 l 1798 -285 l 1798 -326 l 1941 -326 l 1941 0 l +1880 0 l p ef +2185 -24 m 2178 -14 2169 -7 2159 -2 ct 2149 3 2138 5 2125 5 ct 2103 5 2085 -2 2071 -15 ct +2057 -28 2050 -45 2050 -65 ct 2050 -91 2060 -111 2079 -124 ct 2099 -137 2128 -143 2167 -143 ct +2167 -143 2167 -143 2191 -143 ct 2191 -143 2191 -143 2191 -154 ct 2191 -165 2187 -174 2179 -179 ct +2171 -185 2159 -188 2143 -188 ct 2121 -188 2096 -182 2069 -169 ct 2069 -169 2069 -169 2069 -214 ct +2097 -224 2125 -229 2154 -229 ct 2186 -229 2210 -223 2226 -211 ct 2236 -203 2243 -194 2247 -185 ct +2250 -175 2252 -160 2252 -140 ct 2252 -140 2252 -140 2252 -64 ct 2252 -49 2257 -41 2266 -41 ct +2268 -41 2270 -41 2273 -42 ct 2273 -42 2273 -42 2273 -2 ct 2261 3 2249 5 2239 5 ct +2228 5 2218 3 2210 -2 ct 2202 -7 2196 -14 2191 -24 ct 2191 -24 2191 -24 2185 -24 ct +p +2191 -65 m 2191 -65 2191 -65 2191 -102 ct 2191 -102 2191 -102 2169 -102 ct +2150 -102 2135 -99 2126 -94 ct 2116 -88 2111 -80 2111 -69 ct 2111 -61 2114 -54 2120 -49 ct +2126 -44 2133 -41 2142 -41 ct 2157 -41 2174 -49 2191 -65 ct p ef +2319 -8 m 2319 -8 2319 -8 2319 -54 ct 2353 -42 2381 -36 2401 -36 ct 2416 -36 2427 -38 2435 -42 ct +2442 -46 2446 -52 2446 -60 ct 2446 -64 2444 -68 2440 -72 ct 2437 -75 2431 -79 2424 -82 ct +2424 -82 2424 -82 2376 -101 ct 2357 -109 2343 -118 2334 -127 ct 2325 -137 2320 -148 2320 -161 ct +2320 -182 2330 -199 2349 -211 ct 2368 -223 2395 -229 2429 -229 ct 2449 -229 2472 -226 2498 -221 ct +2498 -221 2498 -221 2498 -174 ct 2470 -183 2446 -188 2427 -188 ct 2412 -188 2402 -186 2395 -183 ct +2388 -180 2384 -175 2384 -169 ct 2384 -165 2387 -162 2392 -158 ct 2397 -154 2404 -150 2414 -146 ct +2414 -146 2414 -146 2467 -124 ct 2483 -118 2495 -110 2502 -100 ct 2510 -91 2514 -79 2514 -66 ct +2514 -45 2505 -28 2486 -15 ct 2467 -2 2443 5 2413 5 ct 2387 5 2355 1 2319 -8 ct +p ef +2768 -6 m 2744 1 2722 5 2704 5 ct 2675 5 2654 -1 2640 -14 ct 2626 -26 2619 -45 2619 -70 ct +2619 -70 2619 -70 2619 -178 ct 2619 -178 2619 -178 2571 -178 ct 2571 -178 2571 -178 2571 -219 ct +2571 -219 2571 -219 2619 -219 ct 2619 -219 2619 -219 2619 -285 ct 2619 -285 2619 -285 2680 -285 ct +2680 -285 2680 -285 2680 -219 ct 2680 -219 2680 -219 2763 -219 ct 2763 -219 2763 -219 2763 -178 ct +2763 -178 2763 -178 2680 -178 ct 2680 -178 2680 -178 2680 -84 ct 2680 -68 2683 -57 2689 -51 ct +2695 -44 2705 -41 2719 -41 ct 2736 -41 2752 -44 2768 -51 ct 2768 -51 2768 -51 2768 -6 ct +p ef +2794 46 m 2794 0 l 3049 0 l 3049 46 l 2794 46 l p ef +pom +gr +gs +pum +10197 13677 t +35 0 m 58 -93 l 11 -93 l 18 -124 l 66 -124 l 80 -184 l 33 -184 l +41 -215 l 88 -215 l 111 -306 l 142 -306 l 120 -215 l 168 -215 l 191 -306 l +222 -306 l 200 -215 l 246 -215 l 239 -184 l 192 -184 l 177 -124 l +224 -124 l 216 -93 l 169 -93 l 146 0 l 115 0 l 138 -93 l 89 -93 l +66 0 l 35 0 l p +97 -124 m 146 -124 l 160 -184 l 112 -184 l 97 -124 l p ef +371 0 m 371 -193 l 289 -193 l 289 -224 l 412 -224 l 412 0 l 371 0 l +p +366 -275 m 366 -326 l 417 -326 l 417 -275 l 366 -275 l p ef +545 0 m 545 0 545 0 545 -224 ct 545 -224 545 -224 586 -224 ct 586 -224 586 -224 584 -182 ct +584 -182 584 -182 586 -182 ct 596 -198 607 -209 620 -217 ct 632 -225 647 -229 663 -229 ct +684 -229 700 -223 711 -210 ct 722 -197 727 -178 727 -153 ct 727 -153 727 -153 727 0 ct +727 0 727 0 686 0 ct 686 0 686 0 686 -142 ct 686 -159 683 -172 678 -179 ct 672 -186 663 -190 650 -190 ct +640 -190 630 -186 619 -179 ct 608 -172 597 -161 586 -146 ct 586 -146 586 -146 586 0 ct +586 0 586 0 545 0 ct p ef +990 -7 m 966 1 942 5 918 5 ct 879 5 849 -5 828 -26 ct 807 -46 796 -75 796 -112 ct +796 -149 806 -177 827 -198 ct 848 -219 877 -229 914 -229 ct 938 -229 962 -225 986 -218 ct +986 -218 986 -218 986 -184 ct 959 -193 937 -198 918 -198 ct 894 -198 874 -190 860 -175 ct +846 -160 839 -139 839 -112 ct 839 -85 846 -64 861 -49 ct 876 -34 897 -26 923 -26 ct +943 -26 965 -31 990 -40 ct 990 -40 990 -40 990 -7 ct p ef +1138 0 m 1138 -295 l 1051 -295 l 1051 -326 l 1179 -326 l 1179 0 l +1138 0 l p ef +1488 -224 m 1488 -224 1488 -224 1488 0 ct 1488 0 1488 0 1447 0 ct 1447 0 1447 0 1449 -42 ct +1449 -42 1449 -42 1447 -42 ct 1438 -26 1426 -15 1414 -7 ct 1401 1 1386 5 1370 5 ct +1349 5 1333 -1 1322 -14 ct 1311 -27 1306 -46 1306 -71 ct 1306 -71 1306 -71 1306 -224 ct +1306 -224 1306 -224 1347 -224 ct 1347 -224 1347 -224 1347 -82 ct 1347 -65 1350 -52 1355 -45 ct +1361 -38 1370 -34 1383 -34 ct 1393 -34 1403 -38 1414 -45 ct 1425 -52 1436 -63 1447 -78 ct +1447 -78 1447 -78 1447 -224 ct 1447 -224 1447 -224 1488 -224 ct p ef +1706 0 m 1706 0 1706 0 1708 -42 ct 1708 -42 1708 -42 1706 -42 ct 1696 -26 1685 -15 1673 -7 ct +1660 1 1647 5 1632 5 ct 1607 5 1587 -5 1572 -24 ct 1557 -44 1550 -71 1550 -105 ct +1550 -142 1559 -172 1576 -195 ct 1594 -218 1616 -229 1644 -229 ct 1656 -229 1668 -226 1678 -221 ct +1688 -216 1698 -209 1706 -198 ct 1706 -198 1706 -198 1708 -198 ct 1708 -198 1708 -198 1706 -229 ct +1706 -229 1706 -229 1706 -326 ct 1706 -326 1706 -326 1747 -326 ct 1747 -326 1747 -326 1747 0 ct +1747 0 1747 0 1706 0 ct p +1706 -168 m 1696 -178 1687 -185 1678 -190 ct 1668 -195 1659 -198 1650 -198 ct +1632 -198 1618 -190 1608 -175 ct 1598 -159 1593 -137 1593 -109 ct 1593 -83 1597 -63 1605 -50 ct +1613 -38 1624 -31 1640 -31 ct 1652 -31 1663 -35 1674 -42 ct 1685 -49 1696 -59 1706 -73 ct +1706 -73 1706 -73 1706 -168 ct p ef +2004 -9 m 1976 0 1950 5 1926 5 ct 1888 5 1859 -5 1838 -25 ct 1817 -45 1807 -73 1807 -110 ct +1807 -144 1817 -173 1837 -195 ct 1857 -218 1882 -229 1913 -229 ct 1944 -229 1966 -220 1981 -201 ct +1996 -182 2003 -153 2003 -114 ct 2003 -114 2003 -114 2003 -101 ct 2003 -101 2003 -101 1849 -101 ct +1850 -76 1858 -57 1872 -45 ct 1886 -32 1905 -26 1931 -26 ct 1954 -26 1978 -31 2004 -42 ct +2004 -42 2004 -42 2004 -9 ct p +1850 -132 m 1850 -132 1850 -132 1960 -132 ct 1960 -132 1960 -132 1960 -138 ct +1960 -158 1956 -173 1947 -183 ct 1938 -193 1926 -198 1909 -198 ct 1892 -198 1879 -192 1868 -181 ct +1858 -169 1852 -153 1850 -132 ct p ef +2523 0 m 2304 -110 l 2523 -219 l 2523 -185 l 2372 -110 l 2523 -34 l +2523 0 l p ef +2579 -9 m 2579 -9 2579 -9 2579 -45 ct 2610 -32 2637 -26 2660 -26 ct 2676 -26 2690 -29 2701 -36 ct +2712 -43 2717 -51 2717 -61 ct 2717 -74 2704 -84 2679 -93 ct 2679 -93 2679 -93 2636 -107 ct +2602 -118 2585 -138 2585 -165 ct 2585 -186 2593 -201 2608 -212 ct 2623 -223 2645 -229 2673 -229 ct +2694 -229 2718 -226 2746 -219 ct 2746 -219 2746 -219 2746 -186 ct 2719 -194 2695 -198 2673 -198 ct +2657 -198 2644 -196 2636 -191 ct 2628 -186 2624 -179 2624 -169 ct 2624 -158 2634 -149 2654 -142 ct +2654 -142 2654 -142 2706 -124 ct 2741 -111 2758 -91 2758 -64 ct 2758 -43 2749 -26 2732 -14 ct +2714 -1 2691 5 2661 5 ct 2636 5 2608 0 2579 -9 ct p ef +3022 0 m 3002 3 2982 5 2963 5 ct 2930 5 2907 -1 2895 -13 ct 2883 -25 2877 -47 2877 -80 ct +2877 -80 2877 -80 2877 -188 ct 2877 -188 2877 -188 2821 -188 ct 2821 -188 2821 -188 2821 -219 ct +2821 -219 2821 -219 2877 -219 ct 2877 -219 2877 -219 2877 -267 ct 2877 -267 2877 -267 2918 -267 ct +2918 -267 2918 -267 2918 -219 ct 2918 -219 2918 -219 3017 -219 ct 3017 -219 3017 -219 3017 -188 ct +3017 -188 3017 -188 2918 -188 ct 2918 -188 2918 -188 2918 -74 ct 2918 -61 2919 -53 2920 -48 ct +2922 -43 2925 -39 2931 -35 ct 2940 -29 2953 -26 2971 -26 ct 2988 -26 3005 -28 3022 -31 ct +3022 -31 3022 -31 3022 0 ct p ef +3230 0 m 3230 0 3230 0 3232 -42 ct 3232 -42 3232 -42 3230 -42 ct 3220 -26 3209 -15 3197 -7 ct +3184 1 3171 5 3156 5 ct 3131 5 3111 -5 3096 -24 ct 3081 -44 3074 -71 3074 -105 ct +3074 -142 3083 -172 3100 -195 ct 3118 -218 3140 -229 3168 -229 ct 3180 -229 3192 -226 3202 -221 ct +3212 -216 3222 -209 3230 -198 ct 3230 -198 3230 -198 3232 -198 ct 3232 -198 3232 -198 3230 -229 ct +3230 -229 3230 -229 3230 -326 ct 3230 -326 3230 -326 3271 -326 ct 3271 -326 3271 -326 3271 0 ct +3271 0 3271 0 3230 0 ct p +3230 -168 m 3220 -178 3211 -185 3202 -190 ct 3192 -195 3183 -198 3174 -198 ct +3156 -198 3142 -190 3132 -175 ct 3122 -159 3117 -137 3117 -109 ct 3117 -83 3121 -63 3129 -50 ct +3137 -38 3148 -31 3164 -31 ct 3176 -31 3187 -35 3198 -42 ct 3209 -49 3220 -59 3230 -73 ct +3230 -73 3230 -73 3230 -168 ct p ef +3419 0 m 3419 -193 l 3337 -193 l 3337 -224 l 3460 -224 l 3460 0 l +3419 0 l p +3414 -275 m 3414 -326 l 3465 -326 l 3465 -275 l 3414 -275 l p ef +3682 5 m 3650 5 3625 -6 3606 -27 ct 3587 -48 3578 -76 3578 -112 ct 3578 -148 3587 -177 3606 -198 ct +3625 -219 3651 -229 3684 -229 ct 3716 -229 3742 -219 3761 -198 ct 3780 -177 3789 -149 3789 -113 ct +3789 -76 3780 -47 3761 -26 ct 3742 -5 3716 5 3682 5 ct p +3683 -26 m 3704 -26 3720 -33 3730 -48 ct 3741 -62 3746 -84 3746 -113 ct 3746 -139 3740 -160 3729 -175 ct +3718 -190 3703 -198 3684 -198 ct 3664 -198 3649 -190 3638 -175 ct 3627 -160 3621 -139 3621 -112 ct +3621 -85 3626 -64 3637 -49 ct 3648 -34 3664 -26 3683 -26 ct p ef +3907 0 m 3907 -61 l 3968 -61 l 3968 0 l 3907 0 l p ef +4101 0 m 4101 0 4101 0 4101 -326 ct 4101 -326 4101 -326 4142 -326 ct 4142 -326 4142 -326 4142 -224 ct +4142 -224 4142 -224 4140 -182 ct 4140 -182 4140 -182 4142 -182 ct 4152 -198 4163 -209 4176 -217 ct +4188 -225 4203 -229 4219 -229 ct 4240 -229 4256 -223 4267 -210 ct 4278 -197 4283 -178 4283 -153 ct +4283 -153 4283 -153 4283 0 ct 4283 0 4283 0 4242 0 ct 4242 0 4242 0 4242 -142 ct +4242 -159 4239 -172 4234 -179 ct 4228 -186 4219 -190 4206 -190 ct 4196 -190 4186 -186 4175 -179 ct +4164 -172 4153 -161 4142 -146 ct 4142 -146 4142 -146 4142 0 ct 4142 0 4142 0 4101 0 ct +p ef +4336 0 m 4555 -110 l 4336 -219 l 4336 -185 l 4487 -110 l 4336 -34 l +4336 0 l p ef +pom +gr +gs +pum +15277 13677 t +0.003 0.503 0.003 c 239 -326 m 65 61 l 15 61 l 189 -326 l 239 -326 l +p ef +493 -326 m 319 61 l 269 61 l 443 -326 l 493 -326 l p ef +847 0 m 847 0 847 0 847 -178 ct 847 -178 847 -178 804 -178 ct 804 -178 804 -178 804 -219 ct +804 -219 804 -219 847 -219 ct 847 -219 847 -219 847 -251 ct 847 -278 855 -298 870 -311 ct +885 -324 908 -331 939 -331 ct 965 -331 990 -328 1015 -322 ct 1015 -322 1015 -322 1015 -278 ct +989 -286 968 -290 952 -290 ct 936 -290 925 -287 918 -281 ct 911 -275 908 -265 908 -250 ct +908 -250 908 -250 908 -219 ct 908 -219 908 -219 995 -219 ct 995 -219 995 -219 995 -178 ct +995 -178 995 -178 908 -178 ct 908 -178 908 -178 908 0 ct 908 0 908 0 847 0 ct p ef +1142 5 m 1108 5 1080 -6 1059 -27 ct 1038 -49 1027 -77 1027 -112 ct 1027 -148 1038 -176 1059 -197 ct +1080 -218 1108 -229 1144 -229 ct 1179 -229 1207 -218 1228 -197 ct 1249 -176 1260 -148 1260 -112 ct +1260 -76 1249 -48 1228 -27 ct 1207 -6 1178 5 1142 5 ct p +1143 -36 m 1160 -36 1173 -42 1181 -55 ct 1190 -68 1194 -87 1194 -112 ct 1194 -138 1190 -156 1181 -169 ct +1173 -182 1160 -188 1144 -188 ct 1127 -188 1114 -182 1106 -169 ct 1097 -156 1093 -137 1093 -112 ct +1093 -87 1097 -68 1105 -55 ct 1114 -42 1126 -36 1143 -36 ct p ef +1316 0 m 1316 0 1316 0 1316 -224 ct 1316 -224 1316 -224 1377 -224 ct 1377 -224 1377 -224 1375 -181 ct +1375 -181 1375 -181 1377 -181 ct 1387 -197 1399 -209 1413 -217 ct 1426 -225 1442 -229 1460 -229 ct +1471 -229 1486 -227 1502 -224 ct 1502 -224 1502 -224 1502 -149 ct 1502 -149 1502 -149 1461 -149 ct +1461 -149 1461 -149 1461 -173 ct 1456 -174 1453 -174 1450 -174 ct 1435 -174 1422 -170 1409 -163 ct +1397 -156 1386 -145 1377 -130 ct 1377 -130 1377 -130 1377 0 ct 1377 0 1377 0 1316 0 ct +p ef +1811 -8 m 1811 -8 1811 -8 1811 -54 ct 1845 -42 1873 -36 1893 -36 ct 1908 -36 1919 -38 1927 -42 ct +1934 -46 1938 -52 1938 -60 ct 1938 -64 1936 -68 1932 -72 ct 1929 -75 1923 -79 1916 -82 ct +1916 -82 1916 -82 1868 -101 ct 1849 -109 1835 -118 1826 -127 ct 1817 -137 1812 -148 1812 -161 ct +1812 -182 1822 -199 1841 -211 ct 1860 -223 1887 -229 1921 -229 ct 1941 -229 1964 -226 1990 -221 ct +1990 -221 1990 -221 1990 -174 ct 1962 -183 1938 -188 1919 -188 ct 1904 -188 1894 -186 1887 -183 ct +1880 -180 1876 -175 1876 -169 ct 1876 -165 1879 -162 1884 -158 ct 1889 -154 1896 -150 1906 -146 ct +1906 -146 1906 -146 1959 -124 ct 1975 -118 1987 -110 1994 -100 ct 2002 -91 2006 -79 2006 -66 ct +2006 -45 1997 -28 1978 -15 ct 1959 -2 1935 5 1905 5 ct 1879 5 1847 1 1811 -8 ct +p ef +2134 0 m 2134 -285 l 2052 -285 l 2052 -326 l 2195 -326 l 2195 0 l +2134 0 l p ef +2408 0 m 2408 -183 l 2326 -183 l 2326 -224 l 2469 -224 l 2469 0 l +2408 0 l p +2408 -265 m 2408 -326 l 2469 -326 l 2469 -265 l 2408 -265 l p ef +2767 -4 m 2742 2 2717 5 2692 5 ct 2651 5 2618 -5 2595 -26 ct 2572 -47 2560 -75 2560 -111 ct +2560 -148 2571 -177 2594 -198 ct 2616 -219 2648 -229 2688 -229 ct 2718 -229 2744 -226 2767 -220 ct +2767 -220 2767 -220 2767 -175 ct 2742 -184 2719 -188 2696 -188 ct 2674 -188 2657 -182 2645 -169 ct +2632 -157 2626 -140 2626 -118 ct 2626 -94 2634 -74 2649 -60 ct 2664 -45 2684 -38 2709 -38 ct +2728 -38 2748 -42 2767 -49 ct 2767 -49 2767 -49 2767 -4 ct p ef +3030 -95 m 3030 -95 3030 -95 2878 -95 ct 2881 -77 2889 -63 2901 -54 ct 2913 -45 2929 -41 2950 -41 ct +2974 -41 3001 -46 3030 -56 ct 3030 -56 3030 -56 3030 -9 ct 2995 0 2964 5 2938 5 ct +2900 5 2869 -6 2846 -27 ct 2823 -48 2812 -76 2812 -111 ct 2812 -147 2823 -175 2844 -197 ct +2866 -218 2894 -229 2929 -229 ct 2961 -229 2985 -219 3003 -199 ct 3021 -180 3030 -152 3030 -118 ct +3030 -118 3030 -118 3030 -95 ct p +2877 -136 m 2877 -136 2877 -136 2971 -136 ct 2971 -153 2967 -166 2960 -175 ct +2952 -184 2941 -188 2926 -188 ct 2912 -188 2900 -184 2892 -175 ct 2884 -166 2879 -153 2877 -136 ct +p ef +pom +gr +gs +pum +10197 14659 t +0.003 0.003 1.000 c 227 -4 m 202 2 177 5 152 5 ct 111 5 78 -5 55 -26 ct 32 -47 20 -75 20 -111 ct +20 -148 31 -177 54 -198 ct 76 -219 108 -229 148 -229 ct 178 -229 204 -226 227 -220 ct +227 -220 227 -220 227 -175 ct 202 -184 179 -188 156 -188 ct 134 -188 117 -182 105 -169 ct +92 -157 86 -140 86 -118 ct 86 -94 94 -74 109 -60 ct 124 -45 144 -38 169 -38 ct +188 -38 208 -42 227 -49 ct 227 -49 227 -49 227 -4 ct p ef +356 0 m 356 -285 l 274 -285 l 274 -326 l 417 -326 l 417 0 l 356 0 l +p ef +661 -24 m 654 -14 645 -7 635 -2 ct 625 3 614 5 601 5 ct 579 5 561 -2 547 -15 ct +533 -28 526 -45 526 -65 ct 526 -91 536 -111 555 -124 ct 575 -137 604 -143 643 -143 ct +643 -143 643 -143 667 -143 ct 667 -143 667 -143 667 -154 ct 667 -165 663 -174 655 -179 ct +647 -185 635 -188 619 -188 ct 597 -188 572 -182 545 -169 ct 545 -169 545 -169 545 -214 ct +573 -224 601 -229 630 -229 ct 662 -229 686 -223 702 -211 ct 712 -203 719 -194 723 -185 ct +726 -175 728 -160 728 -140 ct 728 -140 728 -140 728 -64 ct 728 -49 733 -41 742 -41 ct +744 -41 746 -41 749 -42 ct 749 -42 749 -42 749 -2 ct 737 3 725 5 715 5 ct 704 5 694 3 686 -2 ct +678 -7 672 -14 667 -24 ct 667 -24 667 -24 661 -24 ct p +667 -65 m 667 -65 667 -65 667 -102 ct 667 -102 667 -102 645 -102 ct 626 -102 611 -99 602 -94 ct +592 -88 587 -80 587 -69 ct 587 -61 590 -54 596 -49 ct 602 -44 609 -41 618 -41 ct +633 -41 650 -49 667 -65 ct p ef +795 -8 m 795 -8 795 -8 795 -54 ct 829 -42 857 -36 877 -36 ct 892 -36 903 -38 911 -42 ct +918 -46 922 -52 922 -60 ct 922 -64 920 -68 916 -72 ct 913 -75 907 -79 900 -82 ct +900 -82 900 -82 852 -101 ct 833 -109 819 -118 810 -127 ct 801 -137 796 -148 796 -161 ct +796 -182 806 -199 825 -211 ct 844 -223 871 -229 905 -229 ct 925 -229 948 -226 974 -221 ct +974 -221 974 -221 974 -174 ct 946 -183 922 -188 903 -188 ct 888 -188 878 -186 871 -183 ct +864 -180 860 -175 860 -169 ct 860 -165 863 -162 868 -158 ct 873 -154 880 -150 890 -146 ct +890 -146 890 -146 943 -124 ct 959 -118 971 -110 978 -100 ct 986 -91 990 -79 990 -66 ct +990 -45 981 -28 962 -15 ct 943 -2 919 5 889 5 ct 863 5 831 1 795 -8 ct p ef +1049 -8 m 1049 -8 1049 -8 1049 -54 ct 1083 -42 1111 -36 1131 -36 ct 1146 -36 1157 -38 1165 -42 ct +1172 -46 1176 -52 1176 -60 ct 1176 -64 1174 -68 1170 -72 ct 1167 -75 1161 -79 1154 -82 ct +1154 -82 1154 -82 1106 -101 ct 1087 -109 1073 -118 1064 -127 ct 1055 -137 1050 -148 1050 -161 ct +1050 -182 1060 -199 1079 -211 ct 1098 -223 1125 -229 1159 -229 ct 1179 -229 1202 -226 1228 -221 ct +1228 -221 1228 -221 1228 -174 ct 1200 -183 1176 -188 1157 -188 ct 1142 -188 1132 -186 1125 -183 ct +1118 -180 1114 -175 1114 -169 ct 1114 -165 1117 -162 1122 -158 ct 1127 -154 1134 -150 1144 -146 ct +1144 -146 1144 -146 1197 -124 ct 1213 -118 1225 -110 1232 -100 ct 1240 -91 1244 -79 1244 -66 ct +1244 -45 1235 -28 1216 -15 ct 1197 -2 1173 5 1143 5 ct 1117 5 1085 1 1049 -8 ct +p ef +pom +gr +gs +pum +11467 14659 t +301 0 m 301 0 301 0 301 -306 ct 301 -306 301 -306 387 -306 ct 425 -306 452 -300 468 -287 ct +485 -274 493 -253 493 -224 ct 493 -192 482 -167 461 -149 ct 439 -131 410 -122 372 -122 ct +372 -122 372 -122 342 -122 ct 342 -122 342 -122 342 0 ct 342 0 342 0 301 0 ct p +342 -153 m 342 -153 342 -153 367 -153 ct 395 -153 416 -159 429 -171 ct 443 -183 450 -200 450 -224 ct +450 -241 444 -254 433 -262 ct 422 -271 405 -275 383 -275 ct 383 -275 383 -275 342 -275 ct +342 -275 342 -275 342 -153 ct p ef +572 0 m 572 0 572 0 572 -224 ct 572 -224 572 -224 613 -224 ct 613 -224 613 -224 611 -182 ct +611 -182 611 -182 613 -182 ct 623 -198 635 -209 649 -217 ct 663 -225 678 -229 696 -229 ct +708 -229 722 -227 737 -224 ct 737 -224 737 -224 737 -160 ct 737 -160 737 -160 706 -160 ct +706 -160 706 -160 706 -191 ct 700 -192 694 -193 689 -193 ct 675 -193 662 -189 650 -181 ct +637 -173 625 -161 613 -145 ct 613 -145 613 -145 613 0 ct 613 0 613 0 572 0 ct p ef +888 5 m 856 5 831 -6 812 -27 ct 793 -48 784 -76 784 -112 ct 784 -148 793 -177 812 -198 ct +831 -219 857 -229 890 -229 ct 922 -229 948 -219 967 -198 ct 986 -177 995 -149 995 -113 ct +995 -76 986 -47 967 -26 ct 948 -5 922 5 888 5 ct p +889 -26 m 910 -26 926 -33 936 -48 ct 947 -62 952 -84 952 -113 ct 952 -139 946 -160 935 -175 ct +924 -190 909 -198 890 -198 ct 870 -198 855 -190 844 -175 ct 833 -160 827 -139 827 -112 ct +827 -85 832 -64 843 -49 ct 854 -34 870 -26 889 -26 ct p ef +1052 2 m 1052 2 1052 2 1052 -326 ct 1052 -326 1052 -326 1093 -326 ct 1093 -326 1093 -326 1093 -224 ct +1093 -224 1093 -224 1091 -182 ct 1091 -182 1091 -182 1093 -182 ct 1103 -198 1114 -209 1126 -217 ct +1138 -225 1152 -229 1166 -229 ct 1191 -229 1211 -219 1226 -200 ct 1241 -180 1248 -153 1248 -120 ct +1248 -82 1239 -52 1222 -29 ct 1205 -6 1182 5 1154 5 ct 1142 5 1131 2 1121 -3 ct +1111 -8 1101 -15 1093 -26 ct 1093 -26 1093 -26 1091 -26 ct 1091 -26 1091 -26 1083 2 ct +1083 2 1083 2 1052 2 ct p +1093 -56 m 1102 -46 1112 -39 1121 -34 ct 1130 -29 1139 -26 1149 -26 ct 1167 -26 1180 -34 1190 -49 ct +1200 -65 1205 -87 1205 -115 ct 1205 -141 1201 -160 1193 -173 ct 1185 -186 1174 -193 1158 -193 ct +1146 -193 1135 -189 1124 -182 ct 1113 -175 1103 -165 1093 -151 ct 1093 -151 1093 -151 1093 -56 ct +p ef +1392 0 m 1392 -295 l 1305 -295 l 1305 -326 l 1433 -326 l 1433 0 l +1392 0 l p ef +1750 -9 m 1722 0 1696 5 1672 5 ct 1634 5 1605 -5 1584 -25 ct 1563 -45 1553 -73 1553 -110 ct +1553 -144 1563 -173 1583 -195 ct 1603 -218 1628 -229 1659 -229 ct 1690 -229 1712 -220 1727 -201 ct +1742 -182 1749 -153 1749 -114 ct 1749 -114 1749 -114 1749 -101 ct 1749 -101 1749 -101 1595 -101 ct +1596 -76 1604 -57 1618 -45 ct 1632 -32 1651 -26 1677 -26 ct 1700 -26 1724 -31 1750 -42 ct +1750 -42 1750 -42 1750 -9 ct p +1596 -132 m 1596 -132 1596 -132 1706 -132 ct 1706 -132 1706 -132 1706 -138 ct +1706 -158 1702 -173 1693 -183 ct 1684 -193 1672 -198 1655 -198 ct 1638 -198 1625 -192 1614 -181 ct +1604 -169 1598 -153 1596 -132 ct p ef +1797 0 m 1797 0 1797 0 1797 -224 ct 1797 -224 1797 -224 1833 -224 ct 1833 -224 1833 -224 1830 -182 ct +1830 -182 1830 -182 1833 -182 ct 1841 -198 1850 -209 1859 -217 ct 1867 -225 1875 -229 1883 -229 ct +1894 -229 1902 -225 1909 -216 ct 1916 -208 1920 -196 1921 -182 ct 1921 -182 1921 -182 1924 -182 ct +1931 -198 1939 -209 1947 -217 ct 1956 -225 1965 -229 1975 -229 ct 1988 -229 1998 -224 2005 -213 ct +2012 -202 2015 -186 2015 -164 ct 2015 -164 2015 -164 2015 0 ct 2015 0 2015 0 1979 0 ct +1979 0 1979 0 1979 -162 ct 1979 -172 1978 -180 1976 -185 ct 1974 -190 1970 -193 1966 -193 ct +1960 -193 1953 -189 1946 -181 ct 1939 -173 1931 -160 1924 -144 ct 1924 -144 1924 -144 1924 0 ct +1924 0 1924 0 1888 0 ct 1888 0 1888 0 1888 -155 ct 1888 -167 1887 -177 1885 -183 ct +1882 -190 1879 -193 1875 -193 ct 1869 -193 1862 -188 1854 -179 ct 1846 -170 1839 -158 1833 -144 ct +1833 -144 1833 -144 1833 0 ct 1833 0 1833 0 1797 0 ct p ef +2498 -326 m 2498 -326 2498 -326 2498 -295 ct 2498 -295 2498 -295 2482 -295 ct +2461 -295 2447 -293 2439 -287 ct 2430 -282 2426 -274 2426 -261 ct 2426 -257 2427 -251 2428 -242 ct +2428 -242 2428 -242 2432 -214 ct 2433 -204 2434 -196 2434 -190 ct 2434 -175 2431 -163 2424 -153 ct +2417 -144 2407 -137 2393 -132 ct 2407 -128 2417 -121 2424 -111 ct 2431 -102 2434 -90 2434 -75 ct +2434 -68 2433 -61 2432 -51 ct 2432 -51 2432 -51 2428 -23 ct 2427 -14 2426 -8 2426 -4 ct +2426 9 2430 17 2439 22 ct 2447 27 2461 30 2482 30 ct 2482 30 2482 30 2498 30 ct +2498 30 2498 30 2498 61 ct 2498 61 2498 61 2475 61 ct 2446 61 2424 56 2410 46 ct +2395 36 2388 21 2388 2 ct 2388 -7 2389 -16 2391 -26 ct 2391 -26 2391 -26 2398 -63 ct +2399 -68 2399 -74 2399 -79 ct 2399 -92 2395 -101 2387 -108 ct 2380 -114 2368 -117 2353 -117 ct +2353 -117 2353 -117 2334 -117 ct 2334 -117 2334 -117 2334 -148 ct 2334 -148 2334 -148 2353 -148 ct +2368 -148 2380 -151 2387 -157 ct 2395 -164 2399 -173 2399 -186 ct 2399 -191 2399 -197 2398 -202 ct +2398 -202 2398 -202 2391 -239 ct 2389 -249 2388 -258 2388 -267 ct 2388 -286 2395 -301 2410 -311 ct +2424 -321 2446 -326 2475 -326 ct 2475 -326 2475 -326 2498 -326 ct p ef +pom +gr +gs +pum +10197 15150 t +pom +gr +gs +pum +10705 15150 t +107 0 m 107 -275 l 5 -275 l 5 -306 l 250 -306 l 250 -275 l 148 -275 l +148 0 l 107 0 l p ef +426 -26 m 402 -5 377 5 353 5 ct 332 5 315 -1 302 -13 ct 289 -24 282 -39 282 -57 ct +282 -81 292 -99 313 -114 ct 334 -128 361 -135 395 -135 ct 395 -135 395 -135 420 -135 ct +420 -135 420 -135 420 -154 ct 420 -169 416 -180 409 -187 ct 401 -194 390 -198 375 -198 ct +351 -198 326 -191 301 -177 ct 301 -177 301 -177 301 -213 ct 330 -224 357 -229 383 -229 ct +412 -229 432 -223 443 -212 ct 455 -201 461 -181 461 -153 ct 461 -153 461 -153 461 -59 ct +461 -45 462 -36 465 -31 ct 468 -26 474 -24 481 -24 ct 484 -24 488 -25 494 -26 ct +494 -26 494 -26 498 -2 ct 484 3 474 5 467 5 ct 457 5 448 2 442 -3 ct 435 -8 430 -16 426 -26 ct +p +420 -53 m 420 -53 420 -53 420 -110 ct 420 -110 420 -110 408 -110 ct 380 -110 359 -106 345 -99 ct +331 -91 324 -80 324 -64 ct 324 -52 327 -43 334 -37 ct 340 -31 350 -28 363 -28 ct +381 -28 400 -36 420 -53 ct p ef +572 0 m 572 0 572 0 572 -224 ct 572 -224 572 -224 613 -224 ct 613 -224 613 -224 611 -182 ct +611 -182 611 -182 613 -182 ct 623 -198 635 -209 649 -217 ct 663 -225 678 -229 696 -229 ct +708 -229 722 -227 737 -224 ct 737 -224 737 -224 737 -160 ct 737 -160 737 -160 706 -160 ct +706 -160 706 -160 706 -191 ct 700 -192 694 -193 689 -193 ct 675 -193 662 -189 650 -181 ct +637 -173 625 -161 613 -145 ct 613 -145 613 -145 613 0 ct 613 0 613 0 572 0 ct p ef +805 75 m 805 75 805 75 809 41 ct 834 51 857 56 878 56 ct 900 56 916 51 925 42 ct +935 33 941 17 944 -6 ct 944 -6 944 -6 948 -46 ct 948 -46 948 -46 944 -46 ct 936 -31 925 -19 913 -12 ct +900 -4 886 0 870 0 ct 845 0 825 -10 810 -29 ct 795 -49 787 -75 787 -108 ct 787 -144 796 -173 813 -195 ct +831 -218 853 -229 881 -229 ct 903 -229 925 -219 946 -198 ct 946 -198 946 -198 949 -198 ct +949 -198 949 -198 949 -224 ct 949 -224 949 -224 985 -224 ct 985 -224 985 -224 985 -45 ct +985 -15 983 6 979 21 ct 975 36 968 49 957 60 ct 940 78 914 87 877 87 ct 856 87 832 83 805 75 ct +p +944 -80 m 944 -80 944 -80 944 -167 ct 926 -188 906 -198 887 -198 ct 868 -198 854 -191 844 -176 ct +835 -162 830 -140 830 -111 ct 830 -86 834 -67 842 -55 ct 851 -42 863 -36 880 -36 ct +892 -36 903 -40 914 -47 ct 925 -54 935 -65 944 -80 ct p ef +1242 -9 m 1214 0 1188 5 1164 5 ct 1126 5 1097 -5 1076 -25 ct 1055 -45 1045 -73 1045 -110 ct +1045 -144 1055 -173 1075 -195 ct 1095 -218 1120 -229 1151 -229 ct 1182 -229 1204 -220 1219 -201 ct +1234 -182 1241 -153 1241 -114 ct 1241 -114 1241 -114 1241 -101 ct 1241 -101 1241 -101 1087 -101 ct +1088 -76 1096 -57 1110 -45 ct 1124 -32 1143 -26 1169 -26 ct 1192 -26 1216 -31 1242 -42 ct +1242 -42 1242 -42 1242 -9 ct p +1088 -132 m 1088 -132 1088 -132 1198 -132 ct 1198 -132 1198 -132 1198 -138 ct +1198 -158 1194 -173 1185 -183 ct 1176 -193 1164 -198 1147 -198 ct 1130 -198 1117 -192 1106 -181 ct +1096 -169 1090 -153 1088 -132 ct p ef +1498 0 m 1478 3 1458 5 1439 5 ct 1406 5 1383 -1 1371 -13 ct 1359 -25 1353 -47 1353 -80 ct +1353 -80 1353 -80 1353 -188 ct 1353 -188 1353 -188 1297 -188 ct 1297 -188 1297 -188 1297 -219 ct +1297 -219 1297 -219 1353 -219 ct 1353 -219 1353 -219 1353 -267 ct 1353 -267 1353 -267 1394 -267 ct +1394 -267 1394 -267 1394 -219 ct 1394 -219 1394 -219 1493 -219 ct 1493 -219 1493 -219 1493 -188 ct +1493 -188 1493 -188 1394 -188 ct 1394 -188 1394 -188 1394 -74 ct 1394 -61 1395 -53 1396 -48 ct +1398 -43 1401 -39 1407 -35 ct 1416 -29 1429 -26 1447 -26 ct 1464 -26 1481 -28 1498 -31 ct +1498 -31 1498 -31 1498 0 ct p ef +1923 -234 m 1923 -234 1923 -234 1986 -262 ct 1986 -262 1986 -262 1999 -223 ct +1999 -223 1999 -223 1931 -209 ct 1931 -209 1931 -209 1931 -212 ct 1931 -219 1928 -227 1923 -234 ct +p +1929 -203 m 1929 -203 1929 -203 1976 -152 ct 1976 -152 1976 -152 1943 -128 ct +1943 -128 1943 -128 1909 -188 ct 1917 -191 1924 -196 1929 -203 ct p +1902 -188 m 1902 -188 1902 -188 1868 -128 ct 1868 -128 1868 -128 1835 -152 ct +1835 -152 1835 -152 1882 -203 ct 1887 -196 1894 -191 1902 -188 ct p +1880 -209 m 1880 -209 1880 -209 1812 -223 ct 1812 -223 1812 -223 1825 -262 ct +1825 -262 1825 -262 1888 -233 ct 1883 -226 1880 -219 1880 -212 ct 1880 -212 1880 -212 1880 -209 ct +p +1893 -237 m 1893 -237 1893 -237 1885 -306 ct 1885 -306 1885 -306 1926 -306 ct +1926 -306 1926 -306 1918 -237 ct 1913 -239 1909 -240 1906 -240 ct 1902 -240 1898 -239 1893 -237 ct +p ef +2154 0 m 2154 -295 l 2067 -295 l 2067 -326 l 2195 -326 l 2195 0 l +2154 0 l p ef +2458 -26 m 2434 -5 2409 5 2385 5 ct 2364 5 2347 -1 2334 -13 ct 2321 -24 2314 -39 2314 -57 ct +2314 -81 2324 -99 2345 -114 ct 2366 -128 2393 -135 2427 -135 ct 2427 -135 2427 -135 2452 -135 ct +2452 -135 2452 -135 2452 -154 ct 2452 -169 2448 -180 2441 -187 ct 2433 -194 2422 -198 2407 -198 ct +2383 -198 2358 -191 2333 -177 ct 2333 -177 2333 -177 2333 -213 ct 2362 -224 2389 -229 2415 -229 ct +2444 -229 2464 -223 2475 -212 ct 2487 -201 2493 -181 2493 -153 ct 2493 -153 2493 -153 2493 -59 ct +2493 -45 2494 -36 2497 -31 ct 2500 -26 2506 -24 2513 -24 ct 2516 -24 2520 -25 2526 -26 ct +2526 -26 2526 -26 2530 -2 ct 2516 3 2506 5 2499 5 ct 2489 5 2480 2 2474 -3 ct 2467 -8 2462 -16 2458 -26 ct +p +2452 -53 m 2452 -53 2452 -53 2452 -110 ct 2452 -110 2452 -110 2440 -110 ct +2412 -110 2391 -106 2377 -99 ct 2363 -91 2356 -80 2356 -64 ct 2356 -52 2359 -43 2366 -37 ct +2372 -31 2382 -28 2395 -28 ct 2413 -28 2432 -36 2452 -53 ct p ef +2579 -9 m 2579 -9 2579 -9 2579 -45 ct 2610 -32 2637 -26 2660 -26 ct 2676 -26 2690 -29 2701 -36 ct +2712 -43 2717 -51 2717 -61 ct 2717 -74 2704 -84 2679 -93 ct 2679 -93 2679 -93 2636 -107 ct +2602 -118 2585 -138 2585 -165 ct 2585 -186 2593 -201 2608 -212 ct 2623 -223 2645 -229 2673 -229 ct +2694 -229 2718 -226 2746 -219 ct 2746 -219 2746 -219 2746 -186 ct 2719 -194 2695 -198 2673 -198 ct +2657 -198 2644 -196 2636 -191 ct 2628 -186 2624 -179 2624 -169 ct 2624 -158 2634 -149 2654 -142 ct +2654 -142 2654 -142 2706 -124 ct 2741 -111 2758 -91 2758 -64 ct 2758 -43 2749 -26 2732 -14 ct +2714 -1 2691 5 2661 5 ct 2636 5 2608 0 2579 -9 ct p ef +3022 0 m 3002 3 2982 5 2963 5 ct 2930 5 2907 -1 2895 -13 ct 2883 -25 2877 -47 2877 -80 ct +2877 -80 2877 -80 2877 -188 ct 2877 -188 2877 -188 2821 -188 ct 2821 -188 2821 -188 2821 -219 ct +2821 -219 2821 -219 2877 -219 ct 2877 -219 2877 -219 2877 -267 ct 2877 -267 2877 -267 2918 -267 ct +2918 -267 2918 -267 2918 -219 ct 2918 -219 2918 -219 3017 -219 ct 3017 -219 3017 -219 3017 -188 ct +3017 -188 3017 -188 2918 -188 ct 2918 -188 2918 -188 2918 -74 ct 2918 -61 2919 -53 2920 -48 ct +2922 -43 2925 -39 2931 -35 ct 2940 -29 2953 -26 2971 -26 ct 2988 -26 3005 -28 3022 -31 ct +3022 -31 3022 -31 3022 0 ct p ef +3048 31 m 3048 0 l 3303 0 l 3303 31 l 3048 31 l p ef +3399 66 m 3399 66 3399 66 3399 46 ct 3406 45 3412 41 3416 33 ct 3421 25 3423 14 3424 0 ct +3424 0 3424 0 3399 0 ct 3399 0 3399 0 3399 -61 ct 3399 -61 3399 -61 3460 -61 ct +3460 -61 3460 -61 3460 -24 ct 3460 5 3455 27 3445 42 ct 3435 57 3419 65 3399 66 ct +p +3399 -163 m 3399 -224 l 3460 -224 l 3460 -163 l 3399 -163 l p ef +pom +gr +gs +pum +10197 15641 t +pom +gr +gs +pum +10705 15641 t +0.003 0.003 1.000 c 98 0 m 9 -224 l 75 -224 l 137 -67 l 198 -224 l 247 -224 l +159 0 l 98 0 l p ef +380 5 m 346 5 318 -6 297 -27 ct 276 -49 265 -77 265 -112 ct 265 -148 276 -176 297 -197 ct +318 -218 346 -229 382 -229 ct 417 -229 445 -218 466 -197 ct 487 -176 498 -148 498 -112 ct +498 -76 487 -48 466 -27 ct 445 -6 416 5 380 5 ct p +381 -36 m 398 -36 411 -42 419 -55 ct 428 -68 432 -87 432 -112 ct 432 -138 428 -156 419 -169 ct +411 -182 398 -188 382 -188 ct 365 -188 352 -182 344 -169 ct 335 -156 331 -137 331 -112 ct +331 -87 335 -68 343 -55 ct 352 -42 364 -36 381 -36 ct p ef +630 0 m 630 -183 l 548 -183 l 548 -224 l 691 -224 l 691 0 l 630 0 l +p +630 -265 m 630 -326 l 691 -326 l 691 -265 l 630 -265 l p ef +936 0 m 936 0 936 0 938 -42 ct 938 -42 938 -42 936 -42 ct 926 -27 915 -15 903 -7 ct +892 1 879 5 865 5 ct 839 5 819 -5 803 -26 ct 788 -46 780 -73 780 -107 ct 780 -144 789 -174 806 -196 ct +823 -218 846 -229 875 -229 ct 887 -229 898 -227 908 -222 ct 918 -218 927 -211 936 -203 ct +936 -203 936 -203 938 -203 ct 938 -203 938 -203 936 -224 ct 936 -224 936 -224 936 -326 ct +936 -326 936 -326 997 -326 ct 997 -326 997 -326 997 0 ct 997 0 997 0 936 0 ct p +936 -160 m 929 -168 922 -173 915 -177 ct 908 -181 900 -183 892 -183 ct 876 -183 865 -177 857 -164 ct +850 -152 846 -133 846 -108 ct 846 -89 849 -75 856 -65 ct 863 -56 873 -51 886 -51 ct +895 -51 903 -54 912 -60 ct 920 -66 928 -75 936 -88 ct 936 -88 936 -88 936 -160 ct +p ef +pom +gr +gs +pum +11721 15641 t +pom +gr +gs +pum +11975 15641 t +228 0 m 208 3 188 5 169 5 ct 136 5 113 -1 101 -13 ct 89 -25 83 -47 83 -80 ct 83 -80 83 -80 83 -188 ct +83 -188 83 -188 27 -188 ct 27 -188 27 -188 27 -219 ct 27 -219 27 -219 83 -219 ct +83 -219 83 -219 83 -267 ct 83 -267 83 -267 124 -267 ct 124 -267 124 -267 124 -219 ct +124 -219 124 -219 223 -219 ct 223 -219 223 -219 223 -188 ct 223 -188 223 -188 124 -188 ct +124 -188 124 -188 124 -74 ct 124 -61 125 -53 126 -48 ct 128 -43 131 -39 137 -35 ct +146 -29 159 -26 177 -26 ct 194 -26 211 -28 228 -31 ct 228 -31 228 -31 228 0 ct +p ef +318 0 m 318 0 318 0 318 -224 ct 318 -224 318 -224 359 -224 ct 359 -224 359 -224 357 -182 ct +357 -182 357 -182 359 -182 ct 369 -198 381 -209 395 -217 ct 409 -225 424 -229 442 -229 ct +454 -229 468 -227 483 -224 ct 483 -224 483 -224 483 -160 ct 483 -160 483 -160 452 -160 ct +452 -160 452 -160 452 -191 ct 446 -192 440 -193 435 -193 ct 421 -193 408 -189 396 -181 ct +383 -173 371 -161 359 -145 ct 359 -145 359 -145 359 0 ct 359 0 359 0 318 0 ct p ef +680 -26 m 656 -5 631 5 607 5 ct 586 5 569 -1 556 -13 ct 543 -24 536 -39 536 -57 ct +536 -81 546 -99 567 -114 ct 588 -128 615 -135 649 -135 ct 649 -135 649 -135 674 -135 ct +674 -135 674 -135 674 -154 ct 674 -169 670 -180 663 -187 ct 655 -194 644 -198 629 -198 ct +605 -198 580 -191 555 -177 ct 555 -177 555 -177 555 -213 ct 584 -224 611 -229 637 -229 ct +666 -229 686 -223 697 -212 ct 709 -201 715 -181 715 -153 ct 715 -153 715 -153 715 -59 ct +715 -45 716 -36 719 -31 ct 722 -26 728 -24 735 -24 ct 738 -24 742 -25 748 -26 ct +748 -26 748 -26 752 -2 ct 738 3 728 5 721 5 ct 711 5 702 2 696 -3 ct 689 -8 684 -16 680 -26 ct +p +674 -53 m 674 -53 674 -53 674 -110 ct 674 -110 674 -110 662 -110 ct 634 -110 613 -106 599 -99 ct +585 -91 578 -80 578 -64 ct 578 -52 581 -43 588 -37 ct 594 -31 604 -28 617 -28 ct +635 -28 654 -36 674 -53 ct p ef +799 0 m 799 0 799 0 799 -224 ct 799 -224 799 -224 840 -224 ct 840 -224 840 -224 838 -182 ct +838 -182 838 -182 840 -182 ct 850 -198 861 -209 874 -217 ct 886 -225 901 -229 917 -229 ct +938 -229 954 -223 965 -210 ct 976 -197 981 -178 981 -153 ct 981 -153 981 -153 981 0 ct +981 0 981 0 940 0 ct 940 0 940 0 940 -142 ct 940 -159 937 -172 932 -179 ct 926 -186 917 -190 904 -190 ct +894 -190 884 -186 873 -179 ct 862 -172 851 -161 840 -146 ct 840 -146 840 -146 840 0 ct +840 0 840 0 799 0 ct p ef +1055 -9 m 1055 -9 1055 -9 1055 -45 ct 1086 -32 1113 -26 1136 -26 ct 1152 -26 1166 -29 1177 -36 ct +1188 -43 1193 -51 1193 -61 ct 1193 -74 1180 -84 1155 -93 ct 1155 -93 1155 -93 1112 -107 ct +1078 -118 1061 -138 1061 -165 ct 1061 -186 1069 -201 1084 -212 ct 1099 -223 1121 -229 1149 -229 ct +1170 -229 1194 -226 1222 -219 ct 1222 -219 1222 -219 1222 -186 ct 1195 -194 1171 -198 1149 -198 ct +1133 -198 1120 -196 1112 -191 ct 1104 -186 1100 -179 1100 -169 ct 1100 -158 1110 -149 1130 -142 ct +1130 -142 1130 -142 1182 -124 ct 1217 -111 1234 -91 1234 -64 ct 1234 -43 1225 -26 1208 -14 ct +1190 -1 1167 5 1137 5 ct 1112 5 1084 0 1055 -9 ct p ef +1362 0 m 1362 0 1362 0 1362 -188 ct 1362 -188 1362 -188 1301 -188 ct 1301 -188 1301 -188 1301 -219 ct +1301 -219 1301 -219 1362 -219 ct 1362 -219 1362 -219 1362 -243 ct 1362 -274 1369 -297 1384 -310 ct +1398 -324 1422 -331 1456 -331 ct 1478 -331 1498 -328 1518 -322 ct 1518 -322 1518 -322 1518 -289 ct +1498 -296 1478 -300 1459 -300 ct 1438 -300 1424 -296 1415 -288 ct 1407 -280 1403 -267 1403 -247 ct +1403 -247 1403 -247 1403 -219 ct 1403 -219 1403 -219 1510 -219 ct 1510 -219 1510 -219 1510 -188 ct +1510 -188 1510 -188 1403 -188 ct 1403 -188 1403 -188 1403 0 ct 1403 0 1403 0 1362 0 ct +p ef +1650 5 m 1618 5 1593 -6 1574 -27 ct 1555 -48 1546 -76 1546 -112 ct 1546 -148 1555 -177 1574 -198 ct +1593 -219 1619 -229 1652 -229 ct 1684 -229 1710 -219 1729 -198 ct 1748 -177 1757 -149 1757 -113 ct +1757 -76 1748 -47 1729 -26 ct 1710 -5 1684 5 1650 5 ct p +1651 -26 m 1672 -26 1688 -33 1698 -48 ct 1709 -62 1714 -84 1714 -113 ct 1714 -139 1708 -160 1697 -175 ct +1686 -190 1671 -198 1652 -198 ct 1632 -198 1617 -190 1606 -175 ct 1595 -160 1589 -139 1589 -112 ct +1589 -85 1594 -64 1605 -49 ct 1616 -34 1632 -26 1651 -26 ct p ef +1842 0 m 1842 0 1842 0 1842 -224 ct 1842 -224 1842 -224 1883 -224 ct 1883 -224 1883 -224 1881 -182 ct +1881 -182 1881 -182 1883 -182 ct 1893 -198 1905 -209 1919 -217 ct 1933 -225 1948 -229 1966 -229 ct +1978 -229 1992 -227 2007 -224 ct 2007 -224 2007 -224 2007 -160 ct 2007 -160 2007 -160 1976 -160 ct +1976 -160 1976 -160 1976 -191 ct 1970 -192 1964 -193 1959 -193 ct 1945 -193 1932 -189 1920 -181 ct +1907 -173 1895 -161 1883 -145 ct 1883 -145 1883 -145 1883 0 ct 1883 0 1883 0 1842 0 ct +p ef +2051 0 m 2051 0 2051 0 2051 -224 ct 2051 -224 2051 -224 2087 -224 ct 2087 -224 2087 -224 2084 -182 ct +2084 -182 2084 -182 2087 -182 ct 2095 -198 2104 -209 2113 -217 ct 2121 -225 2129 -229 2137 -229 ct +2148 -229 2156 -225 2163 -216 ct 2170 -208 2174 -196 2175 -182 ct 2175 -182 2175 -182 2178 -182 ct +2185 -198 2193 -209 2201 -217 ct 2210 -225 2219 -229 2229 -229 ct 2242 -229 2252 -224 2259 -213 ct +2266 -202 2269 -186 2269 -164 ct 2269 -164 2269 -164 2269 0 ct 2269 0 2269 0 2233 0 ct +2233 0 2233 0 2233 -162 ct 2233 -172 2232 -180 2230 -185 ct 2228 -190 2224 -193 2220 -193 ct +2214 -193 2207 -189 2200 -181 ct 2193 -173 2185 -160 2178 -144 ct 2178 -144 2178 -144 2178 0 ct +2178 0 2178 0 2142 0 ct 2142 0 2142 0 2142 -155 ct 2142 -167 2141 -177 2139 -183 ct +2136 -190 2133 -193 2129 -193 ct 2123 -193 2116 -188 2108 -179 ct 2100 -170 2093 -158 2087 -144 ct +2087 -144 2087 -144 2087 0 ct 2087 0 2087 0 2051 0 ct p ef +2512 -9 m 2484 0 2458 5 2434 5 ct 2396 5 2367 -5 2346 -25 ct 2325 -45 2315 -73 2315 -110 ct +2315 -144 2325 -173 2345 -195 ct 2365 -218 2390 -229 2421 -229 ct 2452 -229 2474 -220 2489 -201 ct +2504 -182 2511 -153 2511 -114 ct 2511 -114 2511 -114 2511 -101 ct 2511 -101 2511 -101 2357 -101 ct +2358 -76 2366 -57 2380 -45 ct 2394 -32 2413 -26 2439 -26 ct 2462 -26 2486 -31 2512 -42 ct +2512 -42 2512 -42 2512 -9 ct p +2358 -132 m 2358 -132 2358 -132 2468 -132 ct 2468 -132 2468 -132 2468 -138 ct +2468 -158 2464 -173 2455 -183 ct 2446 -193 2434 -198 2417 -198 ct 2400 -198 2387 -192 2376 -181 ct +2366 -169 2360 -153 2358 -132 ct p ef +2722 0 m 2722 0 2722 0 2724 -42 ct 2724 -42 2724 -42 2722 -42 ct 2712 -26 2701 -15 2689 -7 ct +2676 1 2663 5 2648 5 ct 2623 5 2603 -5 2588 -24 ct 2573 -44 2566 -71 2566 -105 ct +2566 -142 2575 -172 2592 -195 ct 2610 -218 2632 -229 2660 -229 ct 2672 -229 2684 -226 2694 -221 ct +2704 -216 2714 -209 2722 -198 ct 2722 -198 2722 -198 2724 -198 ct 2724 -198 2724 -198 2722 -229 ct +2722 -229 2722 -229 2722 -326 ct 2722 -326 2722 -326 2763 -326 ct 2763 -326 2763 -326 2763 0 ct +2763 0 2763 0 2722 0 ct p +2722 -168 m 2712 -178 2703 -185 2694 -190 ct 2684 -195 2675 -198 2666 -198 ct +2648 -198 2634 -190 2624 -175 ct 2614 -159 2609 -137 2609 -109 ct 2609 -83 2613 -63 2621 -50 ct +2629 -38 2640 -31 2656 -31 ct 2668 -31 2679 -35 2690 -42 ct 2701 -49 2712 -59 2722 -73 ct +2722 -73 2722 -73 2722 -168 ct p ef +3220 -26 m 3196 -5 3171 5 3147 5 ct 3126 5 3109 -1 3096 -13 ct 3083 -24 3076 -39 3076 -57 ct +3076 -81 3086 -99 3107 -114 ct 3128 -128 3155 -135 3189 -135 ct 3189 -135 3189 -135 3214 -135 ct +3214 -135 3214 -135 3214 -154 ct 3214 -169 3210 -180 3203 -187 ct 3195 -194 3184 -198 3169 -198 ct +3145 -198 3120 -191 3095 -177 ct 3095 -177 3095 -177 3095 -213 ct 3124 -224 3151 -229 3177 -229 ct +3206 -229 3226 -223 3237 -212 ct 3249 -201 3255 -181 3255 -153 ct 3255 -153 3255 -153 3255 -59 ct +3255 -45 3256 -36 3259 -31 ct 3262 -26 3268 -24 3275 -24 ct 3278 -24 3282 -25 3288 -26 ct +3288 -26 3288 -26 3292 -2 ct 3278 3 3268 5 3261 5 ct 3251 5 3242 2 3236 -3 ct 3229 -8 3224 -16 3220 -26 ct +p +3214 -53 m 3214 -53 3214 -53 3214 -110 ct 3214 -110 3214 -110 3202 -110 ct +3174 -110 3153 -106 3139 -99 ct 3125 -91 3118 -80 3118 -64 ct 3118 -52 3121 -43 3128 -37 ct +3134 -31 3144 -28 3157 -28 ct 3175 -28 3194 -36 3214 -53 ct p ef +3484 0 m 3484 0 3484 0 3486 -42 ct 3486 -42 3486 -42 3484 -42 ct 3474 -26 3463 -15 3451 -7 ct +3438 1 3425 5 3410 5 ct 3385 5 3365 -5 3350 -24 ct 3335 -44 3328 -71 3328 -105 ct +3328 -142 3337 -172 3354 -195 ct 3372 -218 3394 -229 3422 -229 ct 3434 -229 3446 -226 3456 -221 ct +3466 -216 3476 -209 3484 -198 ct 3484 -198 3484 -198 3486 -198 ct 3486 -198 3486 -198 3484 -229 ct +3484 -229 3484 -229 3484 -326 ct 3484 -326 3484 -326 3525 -326 ct 3525 -326 3525 -326 3525 0 ct +3525 0 3525 0 3484 0 ct p +3484 -168 m 3474 -178 3465 -185 3456 -190 ct 3446 -195 3437 -198 3428 -198 ct +3410 -198 3396 -190 3386 -175 ct 3376 -159 3371 -137 3371 -109 ct 3371 -83 3375 -63 3383 -50 ct +3391 -38 3402 -31 3418 -31 ct 3430 -31 3441 -35 3452 -42 ct 3463 -49 3474 -59 3484 -73 ct +3484 -73 3484 -73 3484 -168 ct p ef +3662 0 m 3570 -224 l 3612 -224 l 3686 -45 l 3762 -224 l 3798 -224 l +3703 0 l 3662 0 l p ef +3927 0 m 3927 -193 l 3845 -193 l 3845 -224 l 3968 -224 l 3968 0 l +3927 0 l p +3922 -275 m 3922 -326 l 3973 -326 l 3973 -275 l 3922 -275 l p ef +4292 -7 m 4268 1 4244 5 4220 5 ct 4181 5 4151 -5 4130 -26 ct 4109 -46 4098 -75 4098 -112 ct +4098 -149 4108 -177 4129 -198 ct 4150 -219 4179 -229 4216 -229 ct 4240 -229 4264 -225 4288 -218 ct +4288 -218 4288 -218 4288 -184 ct 4261 -193 4239 -198 4220 -198 ct 4196 -198 4176 -190 4162 -175 ct +4148 -160 4141 -139 4141 -112 ct 4141 -85 4148 -64 4163 -49 ct 4178 -34 4199 -26 4225 -26 ct +4245 -26 4267 -31 4292 -40 ct 4292 -40 4292 -40 4292 -7 ct p ef +4544 -9 m 4516 0 4490 5 4466 5 ct 4428 5 4399 -5 4378 -25 ct 4357 -45 4347 -73 4347 -110 ct +4347 -144 4357 -173 4377 -195 ct 4397 -218 4422 -229 4453 -229 ct 4484 -229 4506 -220 4521 -201 ct +4536 -182 4543 -153 4543 -114 ct 4543 -114 4543 -114 4543 -101 ct 4543 -101 4543 -101 4389 -101 ct +4390 -76 4398 -57 4412 -45 ct 4426 -32 4445 -26 4471 -26 ct 4494 -26 4518 -31 4544 -42 ct +4544 -42 4544 -42 4544 -9 ct p +4390 -132 m 4390 -132 4390 -132 4500 -132 ct 4500 -132 4500 -132 4500 -138 ct +4500 -158 4496 -173 4487 -183 ct 4478 -193 4466 -198 4449 -198 ct 4432 -198 4419 -192 4408 -181 ct +4398 -169 4392 -153 4390 -132 ct p ef +pom +gr +gs +pum +16547 15641 t +466 -326 m 466 -326 466 -326 466 -295 ct 466 -295 466 -295 450 -295 ct 429 -295 415 -293 407 -287 ct +398 -282 394 -274 394 -261 ct 394 -257 395 -251 396 -242 ct 396 -242 396 -242 400 -214 ct +401 -204 402 -196 402 -190 ct 402 -175 399 -163 392 -153 ct 385 -144 375 -137 361 -132 ct +375 -128 385 -121 392 -111 ct 399 -102 402 -90 402 -75 ct 402 -68 401 -61 400 -51 ct +400 -51 400 -51 396 -23 ct 395 -14 394 -8 394 -4 ct 394 9 398 17 407 22 ct 415 27 429 30 450 30 ct +450 30 450 30 466 30 ct 466 30 466 30 466 61 ct 466 61 466 61 443 61 ct 414 61 392 56 378 46 ct +363 36 356 21 356 2 ct 356 -7 357 -16 359 -26 ct 359 -26 359 -26 366 -63 ct 367 -68 367 -74 367 -79 ct +367 -92 363 -101 355 -108 ct 348 -114 336 -117 321 -117 ct 321 -117 321 -117 302 -117 ct +302 -117 302 -117 302 -148 ct 302 -148 302 -148 321 -148 ct 336 -148 348 -151 355 -157 ct +363 -164 367 -173 367 -186 ct 367 -191 367 -197 366 -202 ct 366 -202 366 -202 359 -239 ct +357 -249 356 -258 356 -267 ct 356 -286 363 -301 378 -311 ct 392 -321 414 -326 443 -326 ct +443 -326 443 -326 466 -326 ct p ef +pom +gr +gs +pum +10197 16132 t +pom +gr +gs +pum +11213 16132 t +0.003 0.503 0.003 c 239 -326 m 65 61 l 15 61 l 189 -326 l 239 -326 l +p ef +493 -326 m 319 61 l 269 61 l 443 -326 l 493 -326 l p ef +791 0 m 791 0 791 0 791 -224 ct 791 -224 791 -224 852 -224 ct 852 -224 852 -224 851 -202 ct +851 -202 851 -202 850 -181 ct 850 -181 850 -181 852 -181 ct 859 -197 868 -209 880 -217 ct +892 -225 906 -229 924 -229 ct 946 -229 962 -223 973 -210 ct 984 -197 990 -178 990 -153 ct +990 -153 990 -153 990 0 ct 990 0 990 0 929 0 ct 929 0 929 0 929 -139 ct 929 -150 927 -159 923 -165 ct +918 -170 912 -173 903 -173 ct 894 -173 885 -170 876 -165 ct 868 -159 859 -151 852 -139 ct +852 -139 852 -139 852 0 ct 852 0 852 0 791 0 ct p ef +1252 -95 m 1252 -95 1252 -95 1100 -95 ct 1103 -77 1111 -63 1123 -54 ct 1135 -45 1151 -41 1172 -41 ct +1196 -41 1223 -46 1252 -56 ct 1252 -56 1252 -56 1252 -9 ct 1217 0 1186 5 1160 5 ct +1122 5 1091 -6 1068 -27 ct 1045 -48 1034 -76 1034 -111 ct 1034 -147 1045 -175 1066 -197 ct +1088 -218 1116 -229 1151 -229 ct 1183 -229 1207 -219 1225 -199 ct 1243 -180 1252 -152 1252 -118 ct +1252 -118 1252 -118 1252 -95 ct p +1099 -136 m 1099 -136 1099 -136 1193 -136 ct 1193 -153 1189 -166 1182 -175 ct +1174 -184 1163 -188 1148 -188 ct 1134 -188 1122 -184 1114 -175 ct 1106 -166 1101 -153 1099 -136 ct +p ef +1506 -95 m 1506 -95 1506 -95 1354 -95 ct 1357 -77 1365 -63 1377 -54 ct 1389 -45 1405 -41 1426 -41 ct +1450 -41 1477 -46 1506 -56 ct 1506 -56 1506 -56 1506 -9 ct 1471 0 1440 5 1414 5 ct +1376 5 1345 -6 1322 -27 ct 1299 -48 1288 -76 1288 -111 ct 1288 -147 1299 -175 1320 -197 ct +1342 -218 1370 -229 1405 -229 ct 1437 -229 1461 -219 1479 -199 ct 1497 -180 1506 -152 1506 -118 ct +1506 -118 1506 -118 1506 -95 ct p +1353 -136 m 1353 -136 1353 -136 1447 -136 ct 1447 -153 1443 -166 1436 -175 ct +1428 -184 1417 -188 1402 -188 ct 1388 -188 1376 -184 1368 -175 ct 1360 -166 1355 -153 1353 -136 ct +p ef +1698 0 m 1698 0 1698 0 1700 -42 ct 1700 -42 1700 -42 1698 -42 ct 1688 -27 1677 -15 1665 -7 ct +1654 1 1641 5 1627 5 ct 1601 5 1581 -5 1565 -26 ct 1550 -46 1542 -73 1542 -107 ct +1542 -144 1551 -174 1568 -196 ct 1585 -218 1608 -229 1637 -229 ct 1649 -229 1660 -227 1670 -222 ct +1680 -218 1689 -211 1698 -203 ct 1698 -203 1698 -203 1700 -203 ct 1700 -203 1700 -203 1698 -224 ct +1698 -224 1698 -224 1698 -326 ct 1698 -326 1698 -326 1759 -326 ct 1759 -326 1759 -326 1759 0 ct +1759 0 1759 0 1698 0 ct p +1698 -160 m 1691 -168 1684 -173 1677 -177 ct 1670 -181 1662 -183 1654 -183 ct +1638 -183 1627 -177 1619 -164 ct 1612 -152 1608 -133 1608 -108 ct 1608 -89 1611 -75 1618 -65 ct +1625 -56 1635 -51 1648 -51 ct 1657 -51 1665 -54 1674 -60 ct 1682 -66 1690 -75 1698 -88 ct +1698 -88 1698 -88 1698 -160 ct p ef +1811 -8 m 1811 -8 1811 -8 1811 -54 ct 1845 -42 1873 -36 1893 -36 ct 1908 -36 1919 -38 1927 -42 ct +1934 -46 1938 -52 1938 -60 ct 1938 -64 1936 -68 1932 -72 ct 1929 -75 1923 -79 1916 -82 ct +1916 -82 1916 -82 1868 -101 ct 1849 -109 1835 -118 1826 -127 ct 1817 -137 1812 -148 1812 -161 ct +1812 -182 1822 -199 1841 -211 ct 1860 -223 1887 -229 1921 -229 ct 1941 -229 1964 -226 1990 -221 ct +1990 -221 1990 -221 1990 -174 ct 1962 -183 1938 -188 1919 -188 ct 1904 -188 1894 -186 1887 -183 ct +1880 -180 1876 -175 1876 -169 ct 1876 -165 1879 -162 1884 -158 ct 1889 -154 1896 -150 1906 -146 ct +1906 -146 1906 -146 1959 -124 ct 1975 -118 1987 -110 1994 -100 ct 2002 -91 2006 -79 2006 -66 ct +2006 -45 1997 -28 1978 -15 ct 1959 -2 1935 5 1905 5 ct 1879 5 1847 1 1811 -8 ct +p ef +2383 0 m 2383 -265 l 2291 -265 l 2291 -306 l 2536 -306 l 2536 -265 l +2444 -265 l 2444 0 l 2383 0 l p ef +2693 -24 m 2686 -14 2677 -7 2667 -2 ct 2657 3 2646 5 2633 5 ct 2611 5 2593 -2 2579 -15 ct +2565 -28 2558 -45 2558 -65 ct 2558 -91 2568 -111 2587 -124 ct 2607 -137 2636 -143 2675 -143 ct +2675 -143 2675 -143 2699 -143 ct 2699 -143 2699 -143 2699 -154 ct 2699 -165 2695 -174 2687 -179 ct +2679 -185 2667 -188 2651 -188 ct 2629 -188 2604 -182 2577 -169 ct 2577 -169 2577 -169 2577 -214 ct +2605 -224 2633 -229 2662 -229 ct 2694 -229 2718 -223 2734 -211 ct 2744 -203 2751 -194 2755 -185 ct +2758 -175 2760 -160 2760 -140 ct 2760 -140 2760 -140 2760 -64 ct 2760 -49 2765 -41 2774 -41 ct +2776 -41 2778 -41 2781 -42 ct 2781 -42 2781 -42 2781 -2 ct 2769 3 2757 5 2747 5 ct +2736 5 2726 3 2718 -2 ct 2710 -7 2704 -14 2699 -24 ct 2699 -24 2699 -24 2693 -24 ct +p +2699 -65 m 2699 -65 2699 -65 2699 -102 ct 2699 -102 2699 -102 2677 -102 ct +2658 -102 2643 -99 2634 -94 ct 2624 -88 2619 -80 2619 -69 ct 2619 -61 2622 -54 2628 -49 ct +2634 -44 2641 -41 2650 -41 ct 2665 -41 2682 -49 2699 -65 ct p ef +2840 0 m 2840 0 2840 0 2840 -224 ct 2840 -224 2840 -224 2901 -224 ct 2901 -224 2901 -224 2899 -181 ct +2899 -181 2899 -181 2901 -181 ct 2911 -197 2923 -209 2937 -217 ct 2950 -225 2966 -229 2984 -229 ct +2995 -229 3010 -227 3026 -224 ct 3026 -224 3026 -224 3026 -149 ct 3026 -149 3026 -149 2985 -149 ct +2985 -149 2985 -149 2985 -173 ct 2980 -174 2977 -174 2974 -174 ct 2959 -174 2946 -170 2933 -163 ct +2921 -156 2910 -145 2901 -130 ct 2901 -130 2901 -130 2901 0 ct 2901 0 2901 0 2840 0 ct +p ef +3088 69 m 3088 69 3088 69 3094 25 ct 3126 38 3152 44 3172 44 ct 3190 44 3203 39 3211 30 ct +3220 21 3224 7 3224 -11 ct 3224 -11 3224 -11 3225 -53 ct 3225 -53 3225 -53 3223 -53 ct +3215 -35 3205 -22 3194 -13 ct 3182 -4 3168 0 3152 0 ct 3126 0 3105 -10 3090 -31 ct +3074 -51 3066 -78 3066 -111 ct 3066 -147 3075 -175 3092 -197 ct 3110 -218 3133 -229 3162 -229 ct +3174 -229 3184 -227 3194 -223 ct 3204 -218 3213 -212 3222 -204 ct 3222 -204 3222 -204 3227 -204 ct +3227 -204 3227 -204 3232 -224 ct 3232 -224 3232 -224 3283 -224 ct 3283 -224 3283 -224 3283 -27 ct +3283 10 3274 38 3256 58 ct 3239 77 3213 87 3180 87 ct 3154 87 3123 81 3088 69 ct +p +3222 -95 m 3222 -95 3222 -95 3222 -163 ct 3214 -169 3206 -174 3198 -178 ct +3191 -181 3184 -183 3177 -183 ct 3162 -183 3151 -177 3143 -166 ct 3136 -155 3132 -138 3132 -116 ct +3132 -97 3135 -83 3142 -73 ct 3149 -64 3158 -59 3172 -59 ct 3181 -59 3190 -62 3199 -68 ct +3207 -74 3215 -83 3222 -95 ct p ef +3538 -95 m 3538 -95 3538 -95 3386 -95 ct 3389 -77 3397 -63 3409 -54 ct 3421 -45 3437 -41 3458 -41 ct +3482 -41 3509 -46 3538 -56 ct 3538 -56 3538 -56 3538 -9 ct 3503 0 3472 5 3446 5 ct +3408 5 3377 -6 3354 -27 ct 3331 -48 3320 -76 3320 -111 ct 3320 -147 3331 -175 3352 -197 ct +3374 -218 3402 -229 3437 -229 ct 3469 -229 3493 -219 3511 -199 ct 3529 -180 3538 -152 3538 -118 ct +3538 -118 3538 -118 3538 -95 ct p +3385 -136 m 3385 -136 3385 -136 3479 -136 ct 3479 -153 3475 -166 3468 -175 ct +3460 -184 3449 -188 3434 -188 ct 3420 -188 3408 -184 3400 -175 ct 3392 -166 3387 -153 3385 -136 ct +p ef +3784 -6 m 3760 1 3738 5 3720 5 ct 3691 5 3670 -1 3656 -14 ct 3642 -26 3635 -45 3635 -70 ct +3635 -70 3635 -70 3635 -178 ct 3635 -178 3635 -178 3587 -178 ct 3587 -178 3587 -178 3587 -219 ct +3587 -219 3587 -219 3635 -219 ct 3635 -219 3635 -219 3635 -285 ct 3635 -285 3635 -285 3696 -285 ct +3696 -285 3696 -285 3696 -219 ct 3696 -219 3696 -219 3779 -219 ct 3779 -219 3779 -219 3779 -178 ct +3779 -178 3779 -178 3696 -178 ct 3696 -178 3696 -178 3696 -84 ct 3696 -68 3699 -57 3705 -51 ct +3711 -44 3721 -41 3735 -41 ct 3752 -41 3768 -44 3784 -51 ct 3784 -51 3784 -51 3784 -6 ct +p ef +3902 61 m 3902 61 3902 61 3902 33 ct 3911 32 3918 30 3923 26 ct 3928 22 3930 17 3930 10 ct +3930 10 3930 10 3930 0 ct 3930 0 3930 0 3902 0 ct 3902 0 3902 0 3902 -71 ct 3902 -71 3902 -71 3973 -71 ct +3973 -71 3973 -71 3973 -14 ct 3973 14 3968 33 3957 44 ct 3947 55 3928 61 3902 61 ct +p ef +4546 -6 m 4522 1 4500 5 4482 5 ct 4453 5 4432 -1 4418 -14 ct 4404 -26 4397 -45 4397 -70 ct +4397 -70 4397 -70 4397 -178 ct 4397 -178 4397 -178 4349 -178 ct 4349 -178 4349 -178 4349 -219 ct +4349 -219 4349 -219 4397 -219 ct 4397 -219 4397 -219 4397 -285 ct 4397 -285 4397 -285 4458 -285 ct +4458 -285 4458 -285 4458 -219 ct 4458 -219 4458 -219 4541 -219 ct 4541 -219 4541 -219 4541 -178 ct +4541 -178 4541 -178 4458 -178 ct 4458 -178 4458 -178 4458 -84 ct 4458 -68 4461 -57 4467 -51 ct +4473 -44 4483 -41 4497 -41 ct 4514 -41 4530 -44 4546 -51 ct 4546 -51 4546 -51 4546 -6 ct +p ef +4601 0 m 4601 0 4601 0 4601 -326 ct 4601 -326 4601 -326 4662 -326 ct 4662 -326 4662 -326 4662 -224 ct +4662 -224 4662 -224 4660 -181 ct 4660 -181 4660 -181 4662 -181 ct 4669 -197 4678 -209 4690 -217 ct +4702 -225 4716 -229 4734 -229 ct 4756 -229 4772 -223 4783 -210 ct 4794 -197 4800 -178 4800 -153 ct +4800 -153 4800 -153 4800 0 ct 4800 0 4800 0 4739 0 ct 4739 0 4739 0 4739 -139 ct +4739 -150 4737 -159 4733 -165 ct 4728 -170 4722 -173 4713 -173 ct 4704 -173 4695 -170 4686 -165 ct +4678 -159 4669 -151 4662 -139 ct 4662 -139 4662 -139 4662 0 ct 4662 0 4662 0 4601 0 ct +p ef +5052 -224 m 5052 -224 5052 -224 5052 0 ct 5052 0 5052 0 4991 0 ct 4991 0 4991 0 4992 -22 ct +4992 -22 4992 -22 4994 -43 ct 4994 -43 4994 -43 4991 -43 ct 4985 -27 4976 -15 4964 -7 ct +4952 1 4937 5 4920 5 ct 4898 5 4881 -1 4870 -14 ct 4859 -27 4853 -46 4853 -71 ct +4853 -71 4853 -71 4853 -224 ct 4853 -224 4853 -224 4914 -224 ct 4914 -224 4914 -224 4914 -85 ct +4914 -73 4916 -65 4920 -59 ct 4925 -54 4931 -51 4940 -51 ct 4949 -51 4958 -54 4967 -59 ct +4975 -65 4983 -73 4991 -85 ct 4991 -85 4991 -85 4991 -224 ct 4991 -224 4991 -224 5052 -224 ct +p ef +5113 -8 m 5113 -8 5113 -8 5113 -54 ct 5147 -42 5175 -36 5195 -36 ct 5210 -36 5221 -38 5229 -42 ct +5236 -46 5240 -52 5240 -60 ct 5240 -64 5238 -68 5234 -72 ct 5231 -75 5225 -79 5218 -82 ct +5218 -82 5218 -82 5170 -101 ct 5151 -109 5137 -118 5128 -127 ct 5119 -137 5114 -148 5114 -161 ct +5114 -182 5124 -199 5143 -211 ct 5162 -223 5189 -229 5223 -229 ct 5243 -229 5266 -226 5292 -221 ct +5292 -221 5292 -221 5292 -174 ct 5264 -183 5240 -188 5221 -188 ct 5206 -188 5196 -186 5189 -183 ct +5182 -180 5178 -175 5178 -169 ct 5178 -165 5181 -162 5186 -158 ct 5191 -154 5198 -150 5208 -146 ct +5208 -146 5208 -146 5261 -124 ct 5277 -118 5289 -110 5296 -100 ct 5304 -91 5308 -79 5308 -66 ct +5308 -45 5299 -28 5280 -15 ct 5261 -2 5237 5 5207 5 ct 5181 5 5149 1 5113 -8 ct +p ef +5685 0 m 5685 -265 l 5593 -265 l 5593 -306 l 5838 -306 l 5838 -265 l +5746 -265 l 5746 0 l 5685 0 l p ef +5995 -24 m 5988 -14 5979 -7 5969 -2 ct 5959 3 5948 5 5935 5 ct 5913 5 5895 -2 5881 -15 ct +5867 -28 5860 -45 5860 -65 ct 5860 -91 5870 -111 5889 -124 ct 5909 -137 5938 -143 5977 -143 ct +5977 -143 5977 -143 6001 -143 ct 6001 -143 6001 -143 6001 -154 ct 6001 -165 5997 -174 5989 -179 ct +5981 -185 5969 -188 5953 -188 ct 5931 -188 5906 -182 5879 -169 ct 5879 -169 5879 -169 5879 -214 ct +5907 -224 5935 -229 5964 -229 ct 5996 -229 6020 -223 6036 -211 ct 6046 -203 6053 -194 6057 -185 ct +6060 -175 6062 -160 6062 -140 ct 6062 -140 6062 -140 6062 -64 ct 6062 -49 6067 -41 6076 -41 ct +6078 -41 6080 -41 6083 -42 ct 6083 -42 6083 -42 6083 -2 ct 6071 3 6059 5 6049 5 ct +6038 5 6028 3 6020 -2 ct 6012 -7 6006 -14 6001 -24 ct 6001 -24 6001 -24 5995 -24 ct +p +6001 -65 m 6001 -65 6001 -65 6001 -102 ct 6001 -102 6001 -102 5979 -102 ct +5960 -102 5945 -99 5936 -94 ct 5926 -88 5921 -80 5921 -69 ct 5921 -61 5924 -54 5930 -49 ct +5936 -44 5943 -41 5952 -41 ct 5967 -41 5984 -49 6001 -65 ct p ef +6142 0 m 6142 0 6142 0 6142 -224 ct 6142 -224 6142 -224 6203 -224 ct 6203 -224 6203 -224 6201 -181 ct +6201 -181 6201 -181 6203 -181 ct 6213 -197 6225 -209 6239 -217 ct 6252 -225 6268 -229 6286 -229 ct +6297 -229 6312 -227 6328 -224 ct 6328 -224 6328 -224 6328 -149 ct 6328 -149 6328 -149 6287 -149 ct +6287 -149 6287 -149 6287 -173 ct 6282 -174 6279 -174 6276 -174 ct 6261 -174 6248 -170 6235 -163 ct +6223 -156 6212 -145 6203 -130 ct 6203 -130 6203 -130 6203 0 ct 6203 0 6203 0 6142 0 ct +p ef +6390 69 m 6390 69 6390 69 6396 25 ct 6428 38 6454 44 6474 44 ct 6492 44 6505 39 6513 30 ct +6522 21 6526 7 6526 -11 ct 6526 -11 6526 -11 6527 -53 ct 6527 -53 6527 -53 6525 -53 ct +6517 -35 6507 -22 6496 -13 ct 6484 -4 6470 0 6454 0 ct 6428 0 6407 -10 6392 -31 ct +6376 -51 6368 -78 6368 -111 ct 6368 -147 6377 -175 6394 -197 ct 6412 -218 6435 -229 6464 -229 ct +6476 -229 6486 -227 6496 -223 ct 6506 -218 6515 -212 6524 -204 ct 6524 -204 6524 -204 6529 -204 ct +6529 -204 6529 -204 6534 -224 ct 6534 -224 6534 -224 6585 -224 ct 6585 -224 6585 -224 6585 -27 ct +6585 10 6576 38 6558 58 ct 6541 77 6515 87 6482 87 ct 6456 87 6425 81 6390 69 ct +p +6524 -95 m 6524 -95 6524 -95 6524 -163 ct 6516 -169 6508 -174 6500 -178 ct +6493 -181 6486 -183 6479 -183 ct 6464 -183 6453 -177 6445 -166 ct 6438 -155 6434 -138 6434 -116 ct +6434 -97 6437 -83 6444 -73 ct 6451 -64 6460 -59 6474 -59 ct 6483 -59 6492 -62 6501 -68 ct +6509 -74 6517 -83 6524 -95 ct p ef +6840 -95 m 6840 -95 6840 -95 6688 -95 ct 6691 -77 6699 -63 6711 -54 ct 6723 -45 6739 -41 6760 -41 ct +6784 -41 6811 -46 6840 -56 ct 6840 -56 6840 -56 6840 -9 ct 6805 0 6774 5 6748 5 ct +6710 5 6679 -6 6656 -27 ct 6633 -48 6622 -76 6622 -111 ct 6622 -147 6633 -175 6654 -197 ct +6676 -218 6704 -229 6739 -229 ct 6771 -229 6795 -219 6813 -199 ct 6831 -180 6840 -152 6840 -118 ct +6840 -118 6840 -118 6840 -95 ct p +6687 -136 m 6687 -136 6687 -136 6781 -136 ct 6781 -153 6777 -166 6770 -175 ct +6762 -184 6751 -188 6736 -188 ct 6722 -188 6710 -184 6702 -175 ct 6694 -166 6689 -153 6687 -136 ct +p ef +7086 -6 m 7062 1 7040 5 7022 5 ct 6993 5 6972 -1 6958 -14 ct 6944 -26 6937 -45 6937 -70 ct +6937 -70 6937 -70 6937 -178 ct 6937 -178 6937 -178 6889 -178 ct 6889 -178 6889 -178 6889 -219 ct +6889 -219 6889 -219 6937 -219 ct 6937 -219 6937 -219 6937 -285 ct 6937 -285 6937 -285 6998 -285 ct +6998 -285 6998 -285 6998 -219 ct 6998 -219 6998 -219 7081 -219 ct 7081 -219 7081 -219 7081 -178 ct +7081 -178 7081 -178 6998 -178 ct 6998 -178 6998 -178 6998 -84 ct 6998 -68 7001 -57 7007 -51 ct +7013 -44 7023 -41 7037 -41 ct 7054 -41 7070 -44 7086 -51 ct 7086 -51 7086 -51 7086 -6 ct +p ef +7204 0 m 7204 -71 l 7275 -71 l 7275 0 l 7204 0 l p ef +7395 0 m 7395 0 7395 0 7395 -326 ct 7395 -326 7395 -326 7456 -326 ct 7456 -326 7456 -326 7456 -224 ct +7456 -224 7456 -224 7454 -181 ct 7454 -181 7454 -181 7456 -181 ct 7463 -197 7472 -209 7484 -217 ct +7496 -225 7510 -229 7528 -229 ct 7550 -229 7566 -223 7577 -210 ct 7588 -197 7594 -178 7594 -153 ct +7594 -153 7594 -153 7594 0 ct 7594 0 7594 0 7533 0 ct 7533 0 7533 0 7533 -139 ct +7533 -150 7531 -159 7527 -165 ct 7522 -170 7516 -173 7507 -173 ct 7498 -173 7489 -170 7480 -165 ct +7472 -159 7463 -151 7456 -139 ct 7456 -139 7456 -139 7456 0 ct 7456 0 7456 0 7395 0 ct +p ef +pom +gr +gs +pum +10197 16623 t +pom +gr +gs +pum +10705 16623 t +43 -326 m 43 -326 43 -326 43 -295 ct 43 -295 43 -295 59 -295 ct 80 -295 94 -293 102 -287 ct +111 -282 115 -274 115 -261 ct 115 -257 114 -251 113 -242 ct 113 -242 113 -242 109 -214 ct +108 -204 107 -196 107 -190 ct 107 -175 110 -163 117 -153 ct 124 -144 134 -137 148 -132 ct +134 -128 124 -121 117 -111 ct 110 -102 107 -90 107 -75 ct 107 -68 108 -61 109 -51 ct +109 -51 109 -51 113 -23 ct 114 -14 115 -8 115 -4 ct 115 9 111 17 102 22 ct 94 27 80 30 59 30 ct +59 30 59 30 43 30 ct 43 30 43 30 43 61 ct 43 61 43 61 66 61 ct 95 61 117 56 131 46 ct +146 36 153 21 153 2 ct 153 -7 152 -16 150 -26 ct 150 -26 150 -26 143 -63 ct 142 -68 142 -74 142 -79 ct +142 -92 146 -101 154 -108 ct 161 -114 173 -117 188 -117 ct 188 -117 188 -117 207 -117 ct +207 -117 207 -117 207 -148 ct 207 -148 207 -148 188 -148 ct 173 -148 161 -151 154 -157 ct +146 -164 142 -173 142 -186 ct 142 -191 142 -197 143 -202 ct 143 -202 143 -202 150 -239 ct +152 -249 153 -258 153 -267 ct 153 -286 146 -301 131 -311 ct 117 -321 95 -326 66 -326 ct +66 -326 66 -326 43 -326 ct p ef +pom +gr +gs +pum +10197 17317 t +43 -326 m 43 -326 43 -326 43 -295 ct 43 -295 43 -295 59 -295 ct 80 -295 94 -293 102 -287 ct +111 -282 115 -274 115 -261 ct 115 -257 114 -251 113 -242 ct 113 -242 113 -242 109 -214 ct +108 -204 107 -196 107 -190 ct 107 -175 110 -163 117 -153 ct 124 -144 134 -137 148 -132 ct +134 -128 124 -121 117 -111 ct 110 -102 107 -90 107 -75 ct 107 -68 108 -61 109 -51 ct +109 -51 109 -51 113 -23 ct 114 -14 115 -8 115 -4 ct 115 9 111 17 102 22 ct 94 27 80 30 59 30 ct +59 30 59 30 43 30 ct 43 30 43 30 43 61 ct 43 61 43 61 66 61 ct 95 61 117 56 131 46 ct +146 36 153 21 153 2 ct 153 -7 152 -16 150 -26 ct 150 -26 150 -26 143 -63 ct 142 -68 142 -74 142 -79 ct +142 -92 146 -101 154 -108 ct 161 -114 173 -117 188 -117 ct 188 -117 188 -117 207 -117 ct +207 -117 207 -117 207 -148 ct 207 -148 207 -148 188 -148 ct 173 -148 161 -151 154 -157 ct +146 -164 142 -173 142 -186 ct 142 -191 142 -197 143 -202 ct 143 -202 143 -202 150 -239 ct +152 -249 153 -258 153 -267 ct 153 -286 146 -301 131 -311 ct 117 -321 95 -326 66 -326 ct +66 -326 66 -326 43 -326 ct p ef +351 66 m 351 66 351 66 351 46 ct 358 45 364 41 368 33 ct 373 25 375 14 376 0 ct +376 0 376 0 351 0 ct 351 0 351 0 351 -61 ct 351 -61 351 -61 412 -61 ct 412 -61 412 -61 412 -24 ct +412 5 407 27 397 42 ct 387 57 371 65 351 66 ct p +351 -163 m 351 -224 l 412 -224 l 412 -163 l 351 -163 l p ef +pom +gr +gs +pum +10705 17317 t +pom +gr +gr +0.503 0.503 0.503 c 11787 18310 m 10406 18310 l 10406 17635 l 13169 17635 l +13169 18310 l 11787 18310 l p ef +11787 18310 m 10406 18310 l 10406 17635 l 13169 17635 l 13169 18310 l +11787 18310 l pc +0.753 0.753 0.753 c 11687 18210 m 10306 18210 l 10306 17535 l 13069 17535 l +13069 18210 l 11687 18210 l p ef +0.003 0.003 0.003 c 11687 18210 m 10306 18210 l 10306 17535 l 13069 17535 l +13069 18210 l 11687 18210 l pc +gs +gs +pum +10541 18011 t +1.000 1.000 1.000 c 29 -291 m 29 -291 29 -291 154 -291 ct 189 -291 216 -283 235 -267 ct +254 -251 264 -229 264 -200 ct 264 -171 254 -148 235 -131 ct 215 -115 188 -107 153 -107 ct +153 -107 153 -107 88 -107 ct 88 -107 88 -107 88 0 ct 88 0 88 0 29 0 ct 29 0 29 0 29 -291 ct +p +88 -156 m 88 -156 88 -156 150 -156 ct 168 -156 181 -160 191 -168 ct 200 -176 205 -186 205 -200 ct +205 -212 200 -223 190 -230 ct 181 -238 167 -242 150 -242 ct 150 -242 150 -242 88 -242 ct +88 -242 88 -242 88 -156 ct p ef +451 -211 m 451 -211 451 -211 441 -159 ct 435 -163 429 -165 422 -165 ct 415 -165 408 -163 402 -158 ct +395 -153 388 -145 381 -134 ct 374 -123 371 -116 371 -114 ct 371 -114 371 -114 371 0 ct +371 0 371 0 314 0 ct 314 0 314 0 314 -215 ct 314 -215 314 -215 371 -215 ct 371 -215 371 -215 371 -172 ct +379 -190 387 -202 395 -209 ct 403 -216 413 -220 424 -220 ct 435 -220 444 -217 451 -211 ct +p ef +578 -220 m 612 -220 639 -210 660 -190 ct 681 -170 691 -143 691 -108 ct 691 -72 681 -45 660 -25 ct +639 -5 612 5 578 5 ct 544 5 517 -5 496 -25 ct 475 -45 465 -72 465 -108 ct 465 -143 475 -170 496 -190 ct +517 -210 544 -220 578 -220 ct p +578 -44 m 594 -44 607 -50 617 -61 ct 627 -73 632 -88 632 -108 ct 632 -127 627 -142 617 -154 ct +608 -165 594 -171 578 -171 ct 561 -171 547 -165 538 -154 ct 529 -143 524 -128 524 -108 ct +524 -88 529 -72 538 -61 ct 547 -50 561 -44 578 -44 ct p ef +794 -192 m 801 -201 810 -207 822 -212 ct 834 -217 846 -220 858 -220 ct 885 -220 906 -210 923 -190 ct +940 -171 949 -144 949 -112 ct 949 -76 940 -47 923 -26 ct 906 -5 885 5 858 5 ct +831 5 810 -4 794 -21 ct 794 -21 794 -21 794 0 ct 794 0 794 0 737 0 ct 737 0 737 0 737 -307 ct +737 -307 737 -307 794 -307 ct 794 -307 794 -307 794 -192 ct p +794 -69 m 807 -52 823 -44 843 -44 ct 857 -44 868 -50 877 -61 ct 886 -73 890 -89 890 -108 ct +890 -129 886 -144 877 -155 ct 868 -166 856 -171 843 -171 ct 824 -171 808 -162 794 -145 ct +794 -145 794 -145 794 -69 ct p ef +1052 0 m 995 0 l 995 -307 l 1052 -307 l 1052 0 l p ef +1305 -20 m 1280 -3 1251 5 1219 5 ct 1183 5 1154 -5 1132 -26 ct 1111 -46 1100 -74 1100 -108 ct +1100 -142 1110 -169 1129 -189 ct 1148 -210 1174 -220 1206 -220 ct 1235 -220 1259 -210 1277 -191 ct +1296 -171 1305 -144 1305 -109 ct 1305 -109 1305 -109 1305 -95 ct 1305 -95 1305 -95 1159 -95 ct +1161 -80 1168 -68 1179 -59 ct 1190 -49 1204 -44 1220 -44 ct 1245 -44 1270 -51 1295 -65 ct +1295 -65 1295 -65 1305 -20 ct p +1250 -133 m 1248 -147 1243 -158 1235 -167 ct 1227 -175 1218 -179 1206 -179 ct +1194 -179 1183 -175 1175 -167 ct 1166 -158 1161 -147 1159 -133 ct 1159 -133 1159 -133 1250 -133 ct +p ef +1668 0 m 1668 0 1668 0 1611 0 ct 1611 0 1611 0 1611 -125 ct 1611 -143 1609 -155 1604 -162 ct +1600 -168 1593 -171 1584 -171 ct 1569 -171 1554 -160 1538 -137 ct 1538 -137 1538 -137 1538 0 ct +1538 0 1538 0 1481 0 ct 1481 0 1481 0 1481 -125 ct 1481 -144 1479 -157 1474 -162 ct +1470 -168 1464 -171 1455 -171 ct 1440 -171 1424 -160 1408 -137 ct 1408 -137 1408 -137 1408 0 ct +1408 0 1408 0 1351 0 ct 1351 0 1351 0 1351 -215 ct 1351 -215 1351 -215 1408 -215 ct +1408 -215 1408 -215 1408 -182 ct 1425 -207 1446 -220 1473 -220 ct 1501 -220 1521 -207 1533 -182 ct +1551 -207 1574 -220 1603 -220 ct 1624 -220 1640 -214 1651 -201 ct 1662 -188 1668 -169 1668 -144 ct +1668 -144 1668 -144 1668 0 ct p ef +1756 -66 m 1766 -66 1775 -63 1782 -56 ct 1789 -49 1792 -41 1792 -31 ct 1792 -21 1789 -12 1782 -5 ct +1775 2 1766 5 1756 5 ct 1746 5 1738 2 1731 -5 ct 1724 -12 1721 -20 1721 -31 ct +1721 -41 1724 -49 1731 -56 ct 1738 -63 1746 -66 1756 -66 ct p ef +2030 0 m 2030 0 2030 0 1971 0 ct 1967 -9 1965 -17 1965 -25 ct 1946 -5 1923 5 1896 5 ct +1876 5 1860 -1 1849 -13 ct 1838 -24 1832 -40 1832 -59 ct 1832 -73 1836 -85 1843 -95 ct +1851 -106 1862 -114 1877 -120 ct 1892 -127 1909 -131 1930 -132 ct 1930 -132 1930 -132 1965 -135 ct +1965 -135 1965 -135 1965 -139 ct 1965 -163 1951 -175 1924 -175 ct 1916 -175 1905 -173 1891 -170 ct +1877 -166 1865 -162 1855 -157 ct 1855 -157 1855 -157 1841 -198 ct 1854 -204 1870 -210 1887 -214 ct +1905 -218 1920 -220 1934 -220 ct 1963 -220 1985 -213 2000 -199 ct 2015 -185 2022 -165 2022 -138 ct +2022 -138 2022 -138 2022 -51 ct 2022 -31 2025 -14 2030 0 ct p +1965 -66 m 1965 -66 1965 -66 1965 -101 ct 1941 -99 1926 -97 1920 -96 ct 1915 -95 1909 -93 1902 -89 ct +1896 -86 1892 -82 1889 -77 ct 1886 -72 1884 -67 1884 -61 ct 1884 -54 1886 -49 1891 -45 ct +1895 -40 1901 -38 1908 -38 ct 1929 -38 1948 -47 1965 -66 ct p ef +2282 0 m 2282 0 2282 0 2225 0 ct 2225 0 2225 0 2225 -125 ct 2225 -156 2214 -171 2192 -171 ct +2173 -171 2155 -160 2140 -139 ct 2140 -139 2140 -139 2140 0 ct 2140 0 2140 0 2083 0 ct +2083 0 2083 0 2083 -307 ct 2083 -307 2083 -307 2140 -307 ct 2140 -307 2140 -307 2140 -188 ct +2158 -209 2181 -220 2209 -220 ct 2231 -220 2249 -213 2262 -200 ct 2275 -187 2282 -168 2282 -144 ct +2282 -144 2282 -144 2282 0 ct p ef +pom +gr +gr +gs +gs +pum +2921 20562 t +376 -251 m 248 0 l 211 0 l 194 -202 l 89 0 l 54 0 l 32 -251 l 75 -251 l +85 -62 l 184 -251 l 225 -251 l 241 -62 l 333 -251 l 376 -251 l p ef +512 -257 m 544 -257 570 -248 588 -231 ct 607 -214 616 -190 616 -161 ct 616 -116 603 -78 576 -44 ct +550 -11 517 6 476 6 ct 444 6 418 -3 399 -21 ct 380 -38 371 -62 371 -91 ct 371 -136 384 -175 411 -208 ct +437 -241 471 -257 512 -257 ct p +476 -31 m 504 -31 526 -44 544 -71 ct 562 -98 571 -128 571 -160 ct 571 -178 566 -193 555 -204 ct +544 -215 530 -220 511 -220 ct 483 -220 460 -207 442 -182 ct 425 -157 416 -128 416 -94 ct +416 -76 421 -60 432 -49 ct 443 -37 457 -31 476 -31 ct p ef +897 -251 m 745 0 l 705 0 l 658 -251 l 701 -251 l 735 -52 l 851 -251 l +897 -251 l p ef +1105 -22 m 1073 -3 1038 6 1002 6 ct 969 6 944 -3 925 -20 ct 906 -37 896 -60 896 -89 ct +896 -134 910 -173 937 -207 ct 964 -240 998 -257 1039 -257 ct 1070 -257 1094 -249 1111 -233 ct +1128 -216 1136 -193 1136 -164 ct 1136 -156 1134 -142 1131 -122 ct 1131 -122 1131 -122 944 -122 ct +942 -114 941 -104 941 -92 ct 941 -74 946 -59 957 -48 ct 968 -37 984 -31 1004 -31 ct +1032 -31 1064 -40 1099 -58 ct 1099 -58 1099 -58 1105 -22 ct p +1092 -155 m 1093 -159 1093 -161 1093 -163 ct 1093 -181 1088 -196 1078 -206 ct +1069 -217 1056 -222 1039 -222 ct 1000 -222 971 -200 954 -155 ct 954 -155 954 -155 1092 -155 ct +p ef +1251 -212 m 1263 -226 1277 -236 1294 -245 ct 1310 -253 1326 -257 1343 -257 ct +1364 -257 1381 -251 1393 -240 ct 1404 -228 1410 -212 1410 -191 ct 1410 -181 1408 -166 1403 -143 ct +1403 -143 1403 -143 1372 0 ct 1372 0 1372 0 1329 0 ct 1329 0 1329 0 1360 -144 ct +1362 -154 1364 -163 1366 -171 ct 1367 -179 1368 -184 1368 -186 ct 1368 -209 1356 -220 1333 -220 ct +1320 -220 1305 -216 1288 -207 ct 1271 -198 1256 -186 1242 -172 ct 1242 -172 1242 -172 1206 0 ct +1206 0 1206 0 1163 0 ct 1163 0 1163 0 1216 -251 ct 1216 -251 1216 -251 1259 -251 ct +1259 -251 1259 -251 1251 -212 ct p ef +1822 -233 m 1822 -233 1822 -233 1803 -200 ct 1782 -214 1760 -221 1735 -221 ct +1706 -221 1681 -209 1661 -185 ct 1641 -160 1631 -131 1631 -96 ct 1631 -75 1636 -58 1647 -47 ct +1658 -36 1674 -31 1693 -31 ct 1718 -31 1745 -39 1776 -56 ct 1776 -56 1776 -56 1781 -22 ct +1749 -3 1718 6 1687 6 ct 1656 6 1631 -3 1613 -20 ct 1595 -38 1586 -62 1586 -93 ct +1586 -139 1601 -178 1630 -209 ct 1659 -241 1694 -257 1736 -257 ct 1751 -257 1767 -255 1783 -250 ct +1799 -246 1812 -240 1822 -233 ct p ef +1976 -257 m 2008 -257 2034 -248 2052 -231 ct 2071 -214 2080 -190 2080 -161 ct +2080 -116 2067 -78 2040 -44 ct 2014 -11 1981 6 1940 6 ct 1908 6 1882 -3 1863 -21 ct +1844 -38 1835 -62 1835 -91 ct 1835 -136 1848 -175 1875 -208 ct 1901 -241 1935 -257 1976 -257 ct +p +1940 -31 m 1968 -31 1990 -44 2008 -71 ct 2026 -98 2035 -128 2035 -160 ct 2035 -178 2030 -193 2019 -204 ct +2008 -215 1994 -220 1975 -220 ct 1947 -220 1924 -207 1906 -182 ct 1889 -157 1880 -128 1880 -94 ct +1880 -76 1885 -60 1896 -49 ct 1907 -37 1921 -31 1940 -31 ct p ef +2387 -359 m 2387 -359 2387 -359 2310 0 ct 2310 0 2310 0 2267 0 ct 2267 0 2267 0 2273 -28 ct +2253 -5 2228 6 2199 6 ct 2173 6 2151 -3 2135 -21 ct 2119 -39 2111 -63 2111 -93 ct +2111 -142 2124 -181 2151 -212 ct 2177 -242 2210 -257 2249 -257 ct 2276 -257 2298 -247 2315 -227 ct +2315 -227 2315 -227 2343 -359 ct 2343 -359 2343 -359 2387 -359 ct p +2306 -186 m 2291 -209 2272 -220 2249 -220 ct 2222 -220 2200 -208 2182 -184 ct +2165 -160 2156 -131 2156 -96 ct 2156 -76 2161 -61 2170 -49 ct 2180 -37 2193 -31 2210 -31 ct +2227 -31 2243 -37 2258 -49 ct 2273 -61 2281 -68 2282 -72 ct 2282 -72 2282 -72 2306 -186 ct +p ef +2595 -22 m 2563 -3 2528 6 2492 6 ct 2459 6 2434 -3 2415 -20 ct 2396 -37 2386 -60 2386 -89 ct +2386 -134 2400 -173 2427 -207 ct 2454 -240 2488 -257 2529 -257 ct 2560 -257 2584 -249 2601 -233 ct +2618 -216 2626 -193 2626 -164 ct 2626 -156 2624 -142 2621 -122 ct 2621 -122 2621 -122 2434 -122 ct +2432 -114 2431 -104 2431 -92 ct 2431 -74 2436 -59 2447 -48 ct 2458 -37 2474 -31 2494 -31 ct +2522 -31 2554 -40 2589 -58 ct 2589 -58 2589 -58 2595 -22 ct p +2582 -155 m 2583 -159 2583 -161 2583 -163 ct 2583 -181 2578 -196 2568 -206 ct +2559 -217 2546 -222 2529 -222 ct 2490 -222 2461 -200 2444 -155 ct 2444 -155 2444 -155 2582 -155 ct +p ef +pom +gr +gr +0.503 0.503 0.503 c 5210 19108 m 1935 19108 l 1935 12785 l 8485 12785 l +8485 19108 l 5210 19108 l p ef +5210 19108 m 1935 19108 l 1935 12785 l 8485 12785 l 8485 19108 l 5210 19108 l +pc +1.000 0.902 0.777 c 5110 19008 m 1835 19008 l 1835 12685 l 8385 12685 l +8385 19008 l 5110 19008 l p ef +0.003 0.003 0.003 c 5110 19008 m 1835 19008 l 1835 12685 l 8385 12685 l +8385 19008 l 5110 19008 l pc +gs +gs +pum +1942 13557 t +1.000 0.402 0.203 c 33 0 m 56 -89 l 15 -89 l 22 -125 l 65 -125 l 79 -181 l +33 -181 l 40 -217 l 88 -217 l 111 -306 l 147 -306 l 125 -217 l 161 -217 l +183 -306 l 220 -306 l 198 -217 l 239 -217 l 232 -181 l 189 -181 l +175 -125 l 221 -125 l 214 -89 l 165 -89 l 143 0 l 106 0 l 128 -89 l +92 -89 l 70 0 l 33 0 l p +101 -125 m 138 -125 l 152 -181 l 116 -181 l 101 -125 l p ef +376 0 m 376 -183 l 294 -183 l 294 -224 l 437 -224 l 437 0 l 376 0 l +p +376 -265 m 376 -326 l 437 -326 l 437 -265 l 376 -265 l p ef +537 0 m 537 0 537 0 537 -224 ct 537 -224 537 -224 598 -224 ct 598 -224 598 -224 597 -202 ct +597 -202 597 -202 596 -181 ct 596 -181 596 -181 598 -181 ct 605 -197 614 -209 626 -217 ct +638 -225 652 -229 670 -229 ct 692 -229 708 -223 719 -210 ct 730 -197 736 -178 736 -153 ct +736 -153 736 -153 736 0 ct 736 0 736 0 675 0 ct 675 0 675 0 675 -139 ct 675 -150 673 -159 669 -165 ct +664 -170 658 -173 649 -173 ct 640 -173 631 -170 622 -165 ct 614 -159 605 -151 598 -139 ct +598 -139 598 -139 598 0 ct 598 0 598 0 537 0 ct p ef +989 -4 m 964 2 939 5 914 5 ct 873 5 840 -5 817 -26 ct 794 -47 782 -75 782 -111 ct +782 -148 793 -177 816 -198 ct 838 -219 870 -229 910 -229 ct 940 -229 966 -226 989 -220 ct +989 -220 989 -220 989 -175 ct 964 -184 941 -188 918 -188 ct 896 -188 879 -182 867 -169 ct +854 -157 848 -140 848 -118 ct 848 -94 856 -74 871 -60 ct 886 -45 906 -38 931 -38 ct +950 -38 970 -42 989 -49 ct 989 -49 989 -49 989 -4 ct p ef +1118 0 m 1118 -285 l 1036 -285 l 1036 -326 l 1179 -326 l 1179 0 l +1118 0 l p ef +1496 -224 m 1496 -224 1496 -224 1496 0 ct 1496 0 1496 0 1435 0 ct 1435 0 1435 0 1436 -22 ct +1436 -22 1436 -22 1438 -43 ct 1438 -43 1438 -43 1435 -43 ct 1429 -27 1420 -15 1408 -7 ct +1396 1 1381 5 1364 5 ct 1342 5 1325 -1 1314 -14 ct 1303 -27 1297 -46 1297 -71 ct +1297 -71 1297 -71 1297 -224 ct 1297 -224 1297 -224 1358 -224 ct 1358 -224 1358 -224 1358 -85 ct +1358 -73 1360 -65 1364 -59 ct 1369 -54 1375 -51 1384 -51 ct 1393 -51 1402 -54 1411 -59 ct +1419 -65 1427 -73 1435 -85 ct 1435 -85 1435 -85 1435 -224 ct 1435 -224 1435 -224 1496 -224 ct +p ef +1698 0 m 1698 0 1698 0 1700 -42 ct 1700 -42 1700 -42 1698 -42 ct 1688 -27 1677 -15 1665 -7 ct +1654 1 1641 5 1627 5 ct 1601 5 1581 -5 1565 -26 ct 1550 -46 1542 -73 1542 -107 ct +1542 -144 1551 -174 1568 -196 ct 1585 -218 1608 -229 1637 -229 ct 1649 -229 1660 -227 1670 -222 ct +1680 -218 1689 -211 1698 -203 ct 1698 -203 1698 -203 1700 -203 ct 1700 -203 1700 -203 1698 -224 ct +1698 -224 1698 -224 1698 -326 ct 1698 -326 1698 -326 1759 -326 ct 1759 -326 1759 -326 1759 0 ct +1759 0 1759 0 1698 0 ct p +1698 -160 m 1691 -168 1684 -173 1677 -177 ct 1670 -181 1662 -183 1654 -183 ct +1638 -183 1627 -177 1619 -164 ct 1612 -152 1608 -133 1608 -108 ct 1608 -89 1611 -75 1618 -65 ct +1625 -56 1635 -51 1648 -51 ct 1657 -51 1665 -54 1674 -60 ct 1682 -66 1690 -75 1698 -88 ct +1698 -88 1698 -88 1698 -160 ct p ef +2014 -95 m 2014 -95 2014 -95 1862 -95 ct 1865 -77 1873 -63 1885 -54 ct 1897 -45 1913 -41 1934 -41 ct +1958 -41 1985 -46 2014 -56 ct 2014 -56 2014 -56 2014 -9 ct 1979 0 1948 5 1922 5 ct +1884 5 1853 -6 1830 -27 ct 1807 -48 1796 -76 1796 -111 ct 1796 -147 1807 -175 1828 -197 ct +1850 -218 1878 -229 1913 -229 ct 1945 -229 1969 -219 1987 -199 ct 2005 -180 2014 -152 2014 -118 ct +2014 -118 2014 -118 2014 -95 ct p +1861 -136 m 1861 -136 1861 -136 1955 -136 ct 1955 -153 1951 -166 1944 -175 ct +1936 -184 1925 -188 1910 -188 ct 1896 -188 1884 -184 1876 -175 ct 1868 -166 1863 -153 1861 -136 ct +p ef +2388 -326 m 2388 -326 2388 -326 2388 -301 ct 2378 -300 2371 -298 2368 -294 ct +2365 -290 2363 -283 2363 -272 ct 2363 -272 2363 -272 2363 -265 ct 2363 -265 2363 -265 2388 -265 ct +2388 -265 2388 -265 2388 -204 ct 2388 -204 2388 -204 2327 -204 ct 2327 -204 2327 -204 2327 -257 ct +2327 -283 2331 -300 2340 -310 ct 2348 -319 2365 -325 2388 -326 ct p +2500 -326 m 2500 -326 2500 -326 2500 -301 ct 2490 -300 2483 -298 2480 -294 ct +2477 -290 2475 -283 2475 -272 ct 2475 -272 2475 -272 2475 -265 ct 2475 -265 2475 -265 2500 -265 ct +2500 -265 2500 -265 2500 -204 ct 2500 -204 2500 -204 2439 -204 ct 2439 -204 2439 -204 2439 -257 ct +2439 -283 2443 -300 2452 -310 ct 2460 -319 2476 -325 2500 -326 ct p ef +2571 0 m 2571 0 2571 0 2571 -306 ct 2571 -306 2571 -306 2689 -306 ct 2721 -306 2744 -299 2760 -285 ct +2776 -271 2784 -251 2784 -223 ct 2784 -189 2773 -164 2752 -147 ct 2730 -130 2698 -121 2656 -121 ct +2656 -121 2656 -121 2632 -121 ct 2632 -121 2632 -121 2632 0 ct 2632 0 2632 0 2571 0 ct +p +2632 -162 m 2632 -162 2632 -162 2647 -162 ct 2671 -162 2688 -167 2700 -177 ct +2712 -187 2718 -203 2718 -223 ct 2718 -239 2714 -250 2705 -256 ct 2696 -262 2679 -265 2655 -265 ct +2655 -265 2655 -265 2632 -265 ct 2632 -265 2632 -265 2632 -162 ct p ef +2840 0 m 2840 0 2840 0 2840 -224 ct 2840 -224 2840 -224 2901 -224 ct 2901 -224 2901 -224 2899 -181 ct +2899 -181 2899 -181 2901 -181 ct 2911 -197 2923 -209 2937 -217 ct 2950 -225 2966 -229 2984 -229 ct +2995 -229 3010 -227 3026 -224 ct 3026 -224 3026 -224 3026 -149 ct 3026 -149 3026 -149 2985 -149 ct +2985 -149 2985 -149 2985 -173 ct 2980 -174 2977 -174 2974 -174 ct 2959 -174 2946 -170 2933 -163 ct +2921 -156 2910 -145 2901 -130 ct 2901 -130 2901 -130 2901 0 ct 2901 0 2901 0 2840 0 ct +p ef +3174 5 m 3140 5 3112 -6 3091 -27 ct 3070 -49 3059 -77 3059 -112 ct 3059 -148 3070 -176 3091 -197 ct +3112 -218 3140 -229 3176 -229 ct 3211 -229 3239 -218 3260 -197 ct 3281 -176 3292 -148 3292 -112 ct +3292 -76 3281 -48 3260 -27 ct 3239 -6 3210 5 3174 5 ct p +3175 -36 m 3192 -36 3205 -42 3213 -55 ct 3222 -68 3226 -87 3226 -112 ct 3226 -138 3222 -156 3213 -169 ct +3205 -182 3192 -188 3176 -188 ct 3159 -188 3146 -182 3138 -169 ct 3129 -156 3125 -137 3125 -112 ct +3125 -87 3129 -68 3137 -55 ct 3146 -42 3158 -36 3175 -36 ct p ef +3327 0 m 3327 0 3327 0 3327 -326 ct 3327 -326 3327 -326 3388 -326 ct 3388 -326 3388 -326 3388 -224 ct +3388 -224 3388 -224 3386 -182 ct 3386 -182 3386 -182 3388 -182 ct 3398 -197 3409 -209 3420 -217 ct +3432 -225 3445 -229 3459 -229 ct 3485 -229 3505 -219 3521 -198 ct 3536 -178 3544 -151 3544 -117 ct +3544 -80 3535 -50 3518 -28 ct 3501 -6 3478 5 3449 5 ct 3437 5 3425 3 3415 -2 ct +3405 -6 3396 -13 3388 -22 ct 3388 -22 3388 -22 3386 -22 ct 3386 -22 3386 -22 3378 0 ct +3378 0 3378 0 3327 0 ct p +3388 -64 m 3395 -56 3402 -50 3409 -47 ct 3416 -43 3424 -41 3433 -41 ct 3448 -41 3459 -47 3467 -60 ct +3474 -72 3478 -91 3478 -116 ct 3478 -135 3475 -149 3468 -159 ct 3461 -168 3452 -173 3438 -173 ct +3430 -173 3421 -170 3412 -164 ct 3404 -158 3396 -149 3388 -136 ct 3388 -136 3388 -136 3388 -64 ct +p ef +3658 0 m 3658 -285 l 3576 -285 l 3576 -326 l 3719 -326 l 3719 0 l +3658 0 l p ef +4046 -95 m 4046 -95 4046 -95 3894 -95 ct 3897 -77 3905 -63 3917 -54 ct 3929 -45 3945 -41 3966 -41 ct +3990 -41 4017 -46 4046 -56 ct 4046 -56 4046 -56 4046 -9 ct 4011 0 3980 5 3954 5 ct +3916 5 3885 -6 3862 -27 ct 3839 -48 3828 -76 3828 -111 ct 3828 -147 3839 -175 3860 -197 ct +3882 -218 3910 -229 3945 -229 ct 3977 -229 4001 -219 4019 -199 ct 4037 -180 4046 -152 4046 -118 ct +4046 -118 4046 -118 4046 -95 ct p +3893 -136 m 3893 -136 3893 -136 3987 -136 ct 3987 -153 3983 -166 3976 -175 ct +3968 -184 3957 -188 3942 -188 ct 3928 -188 3916 -184 3908 -175 ct 3900 -166 3895 -153 3893 -136 ct +p ef +4217 0 m 4217 0 4217 0 4166 0 ct 4166 0 4166 0 4166 -149 ct 4166 -157 4165 -163 4164 -167 ct +4162 -171 4160 -173 4157 -173 ct 4152 -173 4148 -171 4144 -166 ct 4140 -161 4137 -154 4133 -145 ct +4133 -145 4133 -145 4133 0 ct 4133 0 4133 0 4082 0 ct 4082 0 4082 0 4082 -224 ct +4082 -224 4082 -224 4133 -224 ct 4133 -224 4133 -224 4130 -181 ct 4130 -181 4130 -181 4133 -181 ct +4138 -197 4145 -209 4153 -217 ct 4161 -225 4170 -229 4180 -229 ct 4191 -229 4200 -225 4206 -217 ct +4212 -209 4216 -197 4217 -181 ct 4217 -181 4217 -181 4219 -181 ct 4224 -197 4230 -209 4237 -217 ct +4245 -225 4253 -229 4263 -229 ct 4277 -229 4287 -223 4293 -212 ct 4298 -200 4301 -179 4301 -150 ct +4301 -150 4301 -150 4301 0 ct 4301 0 4301 0 4250 0 ct 4250 0 4250 0 4250 -149 ct +4250 -157 4249 -163 4248 -167 ct 4246 -171 4244 -173 4241 -173 ct 4236 -173 4232 -171 4228 -166 ct +4225 -161 4221 -154 4217 -145 ct 4217 -145 4217 -145 4217 0 ct p ef +4410 0 m 4410 -71 l 4481 -71 l 4481 0 l 4410 0 l p ef +4725 -24 m 4718 -14 4709 -7 4699 -2 ct 4689 3 4678 5 4665 5 ct 4643 5 4625 -2 4611 -15 ct +4597 -28 4590 -45 4590 -65 ct 4590 -91 4600 -111 4619 -124 ct 4639 -137 4668 -143 4707 -143 ct +4707 -143 4707 -143 4731 -143 ct 4731 -143 4731 -143 4731 -154 ct 4731 -165 4727 -174 4719 -179 ct +4711 -185 4699 -188 4683 -188 ct 4661 -188 4636 -182 4609 -169 ct 4609 -169 4609 -169 4609 -214 ct +4637 -224 4665 -229 4694 -229 ct 4726 -229 4750 -223 4766 -211 ct 4776 -203 4783 -194 4787 -185 ct +4790 -175 4792 -160 4792 -140 ct 4792 -140 4792 -140 4792 -64 ct 4792 -49 4797 -41 4806 -41 ct +4808 -41 4810 -41 4813 -42 ct 4813 -42 4813 -42 4813 -2 ct 4801 3 4789 5 4779 5 ct +4768 5 4758 3 4750 -2 ct 4742 -7 4736 -14 4731 -24 ct 4731 -24 4731 -24 4725 -24 ct +p +4731 -65 m 4731 -65 4731 -65 4731 -102 ct 4731 -102 4731 -102 4709 -102 ct +4690 -102 4675 -99 4666 -94 ct 4656 -88 4651 -80 4651 -69 ct 4651 -61 4654 -54 4660 -49 ct +4666 -44 4673 -41 4682 -41 ct 4697 -41 4714 -49 4731 -65 ct p ef +4855 0 m 4855 0 4855 0 4855 -326 ct 4855 -326 4855 -326 4916 -326 ct 4916 -326 4916 -326 4916 -224 ct +4916 -224 4916 -224 4914 -181 ct 4914 -181 4914 -181 4916 -181 ct 4923 -197 4932 -209 4944 -217 ct +4956 -225 4970 -229 4988 -229 ct 5010 -229 5026 -223 5037 -210 ct 5048 -197 5054 -178 5054 -153 ct +5054 -153 5054 -153 5054 0 ct 5054 0 5054 0 4993 0 ct 4993 0 4993 0 4993 -139 ct +4993 -150 4991 -159 4987 -165 ct 4982 -170 4976 -173 4967 -173 ct 4958 -173 4949 -170 4940 -165 ct +4932 -159 4923 -151 4916 -139 ct 4916 -139 4916 -139 4916 0 ct 4916 0 4916 0 4855 0 ct +p ef +5182 -326 m 5182 -326 5182 -326 5182 -301 ct 5172 -300 5165 -298 5162 -294 ct +5159 -290 5157 -283 5157 -272 ct 5157 -272 5157 -272 5157 -265 ct 5157 -265 5157 -265 5182 -265 ct +5182 -265 5182 -265 5182 -204 ct 5182 -204 5182 -204 5121 -204 ct 5121 -204 5121 -204 5121 -257 ct +5121 -283 5125 -300 5134 -310 ct 5142 -319 5159 -325 5182 -326 ct p +5294 -326 m 5294 -326 5294 -326 5294 -301 ct 5284 -300 5277 -298 5274 -294 ct +5271 -290 5269 -283 5269 -272 ct 5269 -272 5269 -272 5269 -265 ct 5269 -265 5269 -265 5294 -265 ct +5294 -265 5294 -265 5294 -204 ct 5294 -204 5294 -204 5233 -204 ct 5233 -204 5233 -204 5233 -257 ct +5233 -283 5237 -300 5246 -310 ct 5254 -319 5270 -325 5294 -326 ct p ef +pom +gr +gs +pum +1942 14539 t +0.003 0.003 1.000 c 227 -4 m 202 2 177 5 152 5 ct 111 5 78 -5 55 -26 ct 32 -47 20 -75 20 -111 ct +20 -148 31 -177 54 -198 ct 76 -219 108 -229 148 -229 ct 178 -229 204 -226 227 -220 ct +227 -220 227 -220 227 -175 ct 202 -184 179 -188 156 -188 ct 134 -188 117 -182 105 -169 ct +92 -157 86 -140 86 -118 ct 86 -94 94 -74 109 -60 ct 124 -45 144 -38 169 -38 ct +188 -38 208 -42 227 -49 ct 227 -49 227 -49 227 -4 ct p ef +356 0 m 356 -285 l 274 -285 l 274 -326 l 417 -326 l 417 0 l 356 0 l +p ef +661 -24 m 654 -14 645 -7 635 -2 ct 625 3 614 5 601 5 ct 579 5 561 -2 547 -15 ct +533 -28 526 -45 526 -65 ct 526 -91 536 -111 555 -124 ct 575 -137 604 -143 643 -143 ct +643 -143 643 -143 667 -143 ct 667 -143 667 -143 667 -154 ct 667 -165 663 -174 655 -179 ct +647 -185 635 -188 619 -188 ct 597 -188 572 -182 545 -169 ct 545 -169 545 -169 545 -214 ct +573 -224 601 -229 630 -229 ct 662 -229 686 -223 702 -211 ct 712 -203 719 -194 723 -185 ct +726 -175 728 -160 728 -140 ct 728 -140 728 -140 728 -64 ct 728 -49 733 -41 742 -41 ct +744 -41 746 -41 749 -42 ct 749 -42 749 -42 749 -2 ct 737 3 725 5 715 5 ct 704 5 694 3 686 -2 ct +678 -7 672 -14 667 -24 ct 667 -24 667 -24 661 -24 ct p +667 -65 m 667 -65 667 -65 667 -102 ct 667 -102 667 -102 645 -102 ct 626 -102 611 -99 602 -94 ct +592 -88 587 -80 587 -69 ct 587 -61 590 -54 596 -49 ct 602 -44 609 -41 618 -41 ct +633 -41 650 -49 667 -65 ct p ef +795 -8 m 795 -8 795 -8 795 -54 ct 829 -42 857 -36 877 -36 ct 892 -36 903 -38 911 -42 ct +918 -46 922 -52 922 -60 ct 922 -64 920 -68 916 -72 ct 913 -75 907 -79 900 -82 ct +900 -82 900 -82 852 -101 ct 833 -109 819 -118 810 -127 ct 801 -137 796 -148 796 -161 ct +796 -182 806 -199 825 -211 ct 844 -223 871 -229 905 -229 ct 925 -229 948 -226 974 -221 ct +974 -221 974 -221 974 -174 ct 946 -183 922 -188 903 -188 ct 888 -188 878 -186 871 -183 ct +864 -180 860 -175 860 -169 ct 860 -165 863 -162 868 -158 ct 873 -154 880 -150 890 -146 ct +890 -146 890 -146 943 -124 ct 959 -118 971 -110 978 -100 ct 986 -91 990 -79 990 -66 ct +990 -45 981 -28 962 -15 ct 943 -2 919 5 889 5 ct 863 5 831 1 795 -8 ct p ef +1049 -8 m 1049 -8 1049 -8 1049 -54 ct 1083 -42 1111 -36 1131 -36 ct 1146 -36 1157 -38 1165 -42 ct +1172 -46 1176 -52 1176 -60 ct 1176 -64 1174 -68 1170 -72 ct 1167 -75 1161 -79 1154 -82 ct +1154 -82 1154 -82 1106 -101 ct 1087 -109 1073 -118 1064 -127 ct 1055 -137 1050 -148 1050 -161 ct +1050 -182 1060 -199 1079 -211 ct 1098 -223 1125 -229 1159 -229 ct 1179 -229 1202 -226 1228 -221 ct +1228 -221 1228 -221 1228 -174 ct 1200 -183 1176 -188 1157 -188 ct 1142 -188 1132 -186 1125 -183 ct +1118 -180 1114 -175 1114 -169 ct 1114 -165 1117 -162 1122 -158 ct 1127 -154 1134 -150 1144 -146 ct +1144 -146 1144 -146 1197 -124 ct 1213 -118 1225 -110 1232 -100 ct 1240 -91 1244 -79 1244 -66 ct +1244 -45 1235 -28 1216 -15 ct 1197 -2 1173 5 1143 5 ct 1117 5 1085 1 1049 -8 ct +p ef +pom +gr +gs +pum +3212 14539 t +361 0 m 361 -275 l 259 -275 l 259 -306 l 504 -306 l 504 -275 l 402 -275 l +402 0 l 361 0 l p ef +680 -26 m 656 -5 631 5 607 5 ct 586 5 569 -1 556 -13 ct 543 -24 536 -39 536 -57 ct +536 -81 546 -99 567 -114 ct 588 -128 615 -135 649 -135 ct 649 -135 649 -135 674 -135 ct +674 -135 674 -135 674 -154 ct 674 -169 670 -180 663 -187 ct 655 -194 644 -198 629 -198 ct +605 -198 580 -191 555 -177 ct 555 -177 555 -177 555 -213 ct 584 -224 611 -229 637 -229 ct +666 -229 686 -223 697 -212 ct 709 -201 715 -181 715 -153 ct 715 -153 715 -153 715 -59 ct +715 -45 716 -36 719 -31 ct 722 -26 728 -24 735 -24 ct 738 -24 742 -25 748 -26 ct +748 -26 748 -26 752 -2 ct 738 3 728 5 721 5 ct 711 5 702 2 696 -3 ct 689 -8 684 -16 680 -26 ct +p +674 -53 m 674 -53 674 -53 674 -110 ct 674 -110 674 -110 662 -110 ct 634 -110 613 -106 599 -99 ct +585 -91 578 -80 578 -64 ct 578 -52 581 -43 588 -37 ct 594 -31 604 -28 617 -28 ct +635 -28 654 -36 674 -53 ct p ef +826 0 m 826 0 826 0 826 -224 ct 826 -224 826 -224 867 -224 ct 867 -224 867 -224 865 -182 ct +865 -182 865 -182 867 -182 ct 877 -198 889 -209 903 -217 ct 917 -225 932 -229 950 -229 ct +962 -229 976 -227 991 -224 ct 991 -224 991 -224 991 -160 ct 991 -160 991 -160 960 -160 ct +960 -160 960 -160 960 -191 ct 954 -192 948 -193 943 -193 ct 929 -193 916 -189 904 -181 ct +891 -173 879 -161 867 -145 ct 867 -145 867 -145 867 0 ct 867 0 867 0 826 0 ct p ef +1059 75 m 1059 75 1059 75 1063 41 ct 1088 51 1111 56 1132 56 ct 1154 56 1170 51 1179 42 ct +1189 33 1195 17 1198 -6 ct 1198 -6 1198 -6 1202 -46 ct 1202 -46 1202 -46 1198 -46 ct +1190 -31 1179 -19 1167 -12 ct 1154 -4 1140 0 1124 0 ct 1099 0 1079 -10 1064 -29 ct +1049 -49 1041 -75 1041 -108 ct 1041 -144 1050 -173 1067 -195 ct 1085 -218 1107 -229 1135 -229 ct +1157 -229 1179 -219 1200 -198 ct 1200 -198 1200 -198 1203 -198 ct 1203 -198 1203 -198 1203 -224 ct +1203 -224 1203 -224 1239 -224 ct 1239 -224 1239 -224 1239 -45 ct 1239 -15 1237 6 1233 21 ct +1229 36 1222 49 1211 60 ct 1194 78 1168 87 1131 87 ct 1110 87 1086 83 1059 75 ct +p +1198 -80 m 1198 -80 1198 -80 1198 -167 ct 1180 -188 1160 -198 1141 -198 ct +1122 -198 1108 -191 1098 -176 ct 1089 -162 1084 -140 1084 -111 ct 1084 -86 1088 -67 1096 -55 ct +1105 -42 1117 -36 1134 -36 ct 1146 -36 1157 -40 1168 -47 ct 1179 -54 1189 -65 1198 -80 ct +p ef +1496 -9 m 1468 0 1442 5 1418 5 ct 1380 5 1351 -5 1330 -25 ct 1309 -45 1299 -73 1299 -110 ct +1299 -144 1309 -173 1329 -195 ct 1349 -218 1374 -229 1405 -229 ct 1436 -229 1458 -220 1473 -201 ct +1488 -182 1495 -153 1495 -114 ct 1495 -114 1495 -114 1495 -101 ct 1495 -101 1495 -101 1341 -101 ct +1342 -76 1350 -57 1364 -45 ct 1378 -32 1397 -26 1423 -26 ct 1446 -26 1470 -31 1496 -42 ct +1496 -42 1496 -42 1496 -9 ct p +1342 -132 m 1342 -132 1342 -132 1452 -132 ct 1452 -132 1452 -132 1452 -138 ct +1452 -158 1448 -173 1439 -183 ct 1430 -193 1418 -198 1401 -198 ct 1384 -198 1371 -192 1360 -181 ct +1350 -169 1344 -153 1342 -132 ct p ef +1752 0 m 1732 3 1712 5 1693 5 ct 1660 5 1637 -1 1625 -13 ct 1613 -25 1607 -47 1607 -80 ct +1607 -80 1607 -80 1607 -188 ct 1607 -188 1607 -188 1551 -188 ct 1551 -188 1551 -188 1551 -219 ct +1551 -219 1551 -219 1607 -219 ct 1607 -219 1607 -219 1607 -267 ct 1607 -267 1607 -267 1648 -267 ct +1648 -267 1648 -267 1648 -219 ct 1648 -219 1648 -219 1747 -219 ct 1747 -219 1747 -219 1747 -188 ct +1747 -188 1747 -188 1648 -188 ct 1648 -188 1648 -188 1648 -74 ct 1648 -61 1649 -53 1650 -48 ct +1652 -43 1655 -39 1661 -35 ct 1670 -29 1683 -26 1701 -26 ct 1718 -26 1735 -28 1752 -31 ct +1752 -31 1752 -31 1752 0 ct p ef +2244 -326 m 2244 -326 2244 -326 2244 -295 ct 2244 -295 2244 -295 2228 -295 ct +2207 -295 2193 -293 2185 -287 ct 2176 -282 2172 -274 2172 -261 ct 2172 -257 2173 -251 2174 -242 ct +2174 -242 2174 -242 2178 -214 ct 2179 -204 2180 -196 2180 -190 ct 2180 -175 2177 -163 2170 -153 ct +2163 -144 2153 -137 2139 -132 ct 2153 -128 2163 -121 2170 -111 ct 2177 -102 2180 -90 2180 -75 ct +2180 -68 2179 -61 2178 -51 ct 2178 -51 2178 -51 2174 -23 ct 2173 -14 2172 -8 2172 -4 ct +2172 9 2176 17 2185 22 ct 2193 27 2207 30 2228 30 ct 2228 30 2228 30 2244 30 ct +2244 30 2244 30 2244 61 ct 2244 61 2244 61 2221 61 ct 2192 61 2170 56 2156 46 ct +2141 36 2134 21 2134 2 ct 2134 -7 2135 -16 2137 -26 ct 2137 -26 2137 -26 2144 -63 ct +2145 -68 2145 -74 2145 -79 ct 2145 -92 2141 -101 2133 -108 ct 2126 -114 2114 -117 2099 -117 ct +2099 -117 2099 -117 2080 -117 ct 2080 -117 2080 -117 2080 -148 ct 2080 -148 2080 -148 2099 -148 ct +2114 -148 2126 -151 2133 -157 ct 2141 -164 2145 -173 2145 -186 ct 2145 -191 2145 -197 2144 -202 ct +2144 -202 2144 -202 2137 -239 ct 2135 -249 2134 -258 2134 -267 ct 2134 -286 2141 -301 2156 -311 ct +2170 -321 2192 -326 2221 -326 ct 2221 -326 2221 -326 2244 -326 ct p ef +pom +gr +gs +pum +1942 15030 t +pom +gr +gs +pum +2450 15030 t +0.003 0.003 1.000 c 98 0 m 9 -224 l 75 -224 l 137 -67 l 198 -224 l 247 -224 l +159 0 l 98 0 l p ef +380 5 m 346 5 318 -6 297 -27 ct 276 -49 265 -77 265 -112 ct 265 -148 276 -176 297 -197 ct +318 -218 346 -229 382 -229 ct 417 -229 445 -218 466 -197 ct 487 -176 498 -148 498 -112 ct +498 -76 487 -48 466 -27 ct 445 -6 416 5 380 5 ct p +381 -36 m 398 -36 411 -42 419 -55 ct 428 -68 432 -87 432 -112 ct 432 -138 428 -156 419 -169 ct +411 -182 398 -188 382 -188 ct 365 -188 352 -182 344 -169 ct 335 -156 331 -137 331 -112 ct +331 -87 335 -68 343 -55 ct 352 -42 364 -36 381 -36 ct p ef +630 0 m 630 -183 l 548 -183 l 548 -224 l 691 -224 l 691 0 l 630 0 l +p +630 -265 m 630 -326 l 691 -326 l 691 -265 l 630 -265 l p ef +936 0 m 936 0 936 0 938 -42 ct 938 -42 938 -42 936 -42 ct 926 -27 915 -15 903 -7 ct +892 1 879 5 865 5 ct 839 5 819 -5 803 -26 ct 788 -46 780 -73 780 -107 ct 780 -144 789 -174 806 -196 ct +823 -218 846 -229 875 -229 ct 887 -229 898 -227 908 -222 ct 918 -218 927 -211 936 -203 ct +936 -203 936 -203 938 -203 ct 938 -203 938 -203 936 -224 ct 936 -224 936 -224 936 -326 ct +936 -326 936 -326 997 -326 ct 997 -326 997 -326 997 0 ct 997 0 997 0 936 0 ct p +936 -160 m 929 -168 922 -173 915 -177 ct 908 -181 900 -183 892 -183 ct 876 -183 865 -177 857 -164 ct +850 -152 846 -133 846 -108 ct 846 -89 849 -75 856 -65 ct 863 -56 873 -51 886 -51 ct +895 -51 903 -54 912 -60 ct 920 -66 928 -75 936 -88 ct 936 -88 936 -88 936 -160 ct +p ef +pom +gr +gs +pum +3466 15030 t +pom +gr +gs +pum +3720 15030 t +228 0 m 208 3 188 5 169 5 ct 136 5 113 -1 101 -13 ct 89 -25 83 -47 83 -80 ct 83 -80 83 -80 83 -188 ct +83 -188 83 -188 27 -188 ct 27 -188 27 -188 27 -219 ct 27 -219 27 -219 83 -219 ct +83 -219 83 -219 83 -267 ct 83 -267 83 -267 124 -267 ct 124 -267 124 -267 124 -219 ct +124 -219 124 -219 223 -219 ct 223 -219 223 -219 223 -188 ct 223 -188 223 -188 124 -188 ct +124 -188 124 -188 124 -74 ct 124 -61 125 -53 126 -48 ct 128 -43 131 -39 137 -35 ct +146 -29 159 -26 177 -26 ct 194 -26 211 -28 228 -31 ct 228 -31 228 -31 228 0 ct +p ef +318 0 m 318 0 318 0 318 -224 ct 318 -224 318 -224 359 -224 ct 359 -224 359 -224 357 -182 ct +357 -182 357 -182 359 -182 ct 369 -198 381 -209 395 -217 ct 409 -225 424 -229 442 -229 ct +454 -229 468 -227 483 -224 ct 483 -224 483 -224 483 -160 ct 483 -160 483 -160 452 -160 ct +452 -160 452 -160 452 -191 ct 446 -192 440 -193 435 -193 ct 421 -193 408 -189 396 -181 ct +383 -173 371 -161 359 -145 ct 359 -145 359 -145 359 0 ct 359 0 359 0 318 0 ct p ef +680 -26 m 656 -5 631 5 607 5 ct 586 5 569 -1 556 -13 ct 543 -24 536 -39 536 -57 ct +536 -81 546 -99 567 -114 ct 588 -128 615 -135 649 -135 ct 649 -135 649 -135 674 -135 ct +674 -135 674 -135 674 -154 ct 674 -169 670 -180 663 -187 ct 655 -194 644 -198 629 -198 ct +605 -198 580 -191 555 -177 ct 555 -177 555 -177 555 -213 ct 584 -224 611 -229 637 -229 ct +666 -229 686 -223 697 -212 ct 709 -201 715 -181 715 -153 ct 715 -153 715 -153 715 -59 ct +715 -45 716 -36 719 -31 ct 722 -26 728 -24 735 -24 ct 738 -24 742 -25 748 -26 ct +748 -26 748 -26 752 -2 ct 738 3 728 5 721 5 ct 711 5 702 2 696 -3 ct 689 -8 684 -16 680 -26 ct +p +674 -53 m 674 -53 674 -53 674 -110 ct 674 -110 674 -110 662 -110 ct 634 -110 613 -106 599 -99 ct +585 -91 578 -80 578 -64 ct 578 -52 581 -43 588 -37 ct 594 -31 604 -28 617 -28 ct +635 -28 654 -36 674 -53 ct p ef +799 0 m 799 0 799 0 799 -224 ct 799 -224 799 -224 840 -224 ct 840 -224 840 -224 838 -182 ct +838 -182 838 -182 840 -182 ct 850 -198 861 -209 874 -217 ct 886 -225 901 -229 917 -229 ct +938 -229 954 -223 965 -210 ct 976 -197 981 -178 981 -153 ct 981 -153 981 -153 981 0 ct +981 0 981 0 940 0 ct 940 0 940 0 940 -142 ct 940 -159 937 -172 932 -179 ct 926 -186 917 -190 904 -190 ct +894 -190 884 -186 873 -179 ct 862 -172 851 -161 840 -146 ct 840 -146 840 -146 840 0 ct +840 0 840 0 799 0 ct p ef +1055 -9 m 1055 -9 1055 -9 1055 -45 ct 1086 -32 1113 -26 1136 -26 ct 1152 -26 1166 -29 1177 -36 ct +1188 -43 1193 -51 1193 -61 ct 1193 -74 1180 -84 1155 -93 ct 1155 -93 1155 -93 1112 -107 ct +1078 -118 1061 -138 1061 -165 ct 1061 -186 1069 -201 1084 -212 ct 1099 -223 1121 -229 1149 -229 ct +1170 -229 1194 -226 1222 -219 ct 1222 -219 1222 -219 1222 -186 ct 1195 -194 1171 -198 1149 -198 ct +1133 -198 1120 -196 1112 -191 ct 1104 -186 1100 -179 1100 -169 ct 1100 -158 1110 -149 1130 -142 ct +1130 -142 1130 -142 1182 -124 ct 1217 -111 1234 -91 1234 -64 ct 1234 -43 1225 -26 1208 -14 ct +1190 -1 1167 5 1137 5 ct 1112 5 1084 0 1055 -9 ct p ef +1362 0 m 1362 0 1362 0 1362 -188 ct 1362 -188 1362 -188 1301 -188 ct 1301 -188 1301 -188 1301 -219 ct +1301 -219 1301 -219 1362 -219 ct 1362 -219 1362 -219 1362 -243 ct 1362 -274 1369 -297 1384 -310 ct +1398 -324 1422 -331 1456 -331 ct 1478 -331 1498 -328 1518 -322 ct 1518 -322 1518 -322 1518 -289 ct +1498 -296 1478 -300 1459 -300 ct 1438 -300 1424 -296 1415 -288 ct 1407 -280 1403 -267 1403 -247 ct +1403 -247 1403 -247 1403 -219 ct 1403 -219 1403 -219 1510 -219 ct 1510 -219 1510 -219 1510 -188 ct +1510 -188 1510 -188 1403 -188 ct 1403 -188 1403 -188 1403 0 ct 1403 0 1403 0 1362 0 ct +p ef +1650 5 m 1618 5 1593 -6 1574 -27 ct 1555 -48 1546 -76 1546 -112 ct 1546 -148 1555 -177 1574 -198 ct +1593 -219 1619 -229 1652 -229 ct 1684 -229 1710 -219 1729 -198 ct 1748 -177 1757 -149 1757 -113 ct +1757 -76 1748 -47 1729 -26 ct 1710 -5 1684 5 1650 5 ct p +1651 -26 m 1672 -26 1688 -33 1698 -48 ct 1709 -62 1714 -84 1714 -113 ct 1714 -139 1708 -160 1697 -175 ct +1686 -190 1671 -198 1652 -198 ct 1632 -198 1617 -190 1606 -175 ct 1595 -160 1589 -139 1589 -112 ct +1589 -85 1594 -64 1605 -49 ct 1616 -34 1632 -26 1651 -26 ct p ef +1842 0 m 1842 0 1842 0 1842 -224 ct 1842 -224 1842 -224 1883 -224 ct 1883 -224 1883 -224 1881 -182 ct +1881 -182 1881 -182 1883 -182 ct 1893 -198 1905 -209 1919 -217 ct 1933 -225 1948 -229 1966 -229 ct +1978 -229 1992 -227 2007 -224 ct 2007 -224 2007 -224 2007 -160 ct 2007 -160 2007 -160 1976 -160 ct +1976 -160 1976 -160 1976 -191 ct 1970 -192 1964 -193 1959 -193 ct 1945 -193 1932 -189 1920 -181 ct +1907 -173 1895 -161 1883 -145 ct 1883 -145 1883 -145 1883 0 ct 1883 0 1883 0 1842 0 ct +p ef +2051 0 m 2051 0 2051 0 2051 -224 ct 2051 -224 2051 -224 2087 -224 ct 2087 -224 2087 -224 2084 -182 ct +2084 -182 2084 -182 2087 -182 ct 2095 -198 2104 -209 2113 -217 ct 2121 -225 2129 -229 2137 -229 ct +2148 -229 2156 -225 2163 -216 ct 2170 -208 2174 -196 2175 -182 ct 2175 -182 2175 -182 2178 -182 ct +2185 -198 2193 -209 2201 -217 ct 2210 -225 2219 -229 2229 -229 ct 2242 -229 2252 -224 2259 -213 ct +2266 -202 2269 -186 2269 -164 ct 2269 -164 2269 -164 2269 0 ct 2269 0 2269 0 2233 0 ct +2233 0 2233 0 2233 -162 ct 2233 -172 2232 -180 2230 -185 ct 2228 -190 2224 -193 2220 -193 ct +2214 -193 2207 -189 2200 -181 ct 2193 -173 2185 -160 2178 -144 ct 2178 -144 2178 -144 2178 0 ct +2178 0 2178 0 2142 0 ct 2142 0 2142 0 2142 -155 ct 2142 -167 2141 -177 2139 -183 ct +2136 -190 2133 -193 2129 -193 ct 2123 -193 2116 -188 2108 -179 ct 2100 -170 2093 -158 2087 -144 ct +2087 -144 2087 -144 2087 0 ct 2087 0 2087 0 2051 0 ct p ef +2512 -9 m 2484 0 2458 5 2434 5 ct 2396 5 2367 -5 2346 -25 ct 2325 -45 2315 -73 2315 -110 ct +2315 -144 2325 -173 2345 -195 ct 2365 -218 2390 -229 2421 -229 ct 2452 -229 2474 -220 2489 -201 ct +2504 -182 2511 -153 2511 -114 ct 2511 -114 2511 -114 2511 -101 ct 2511 -101 2511 -101 2357 -101 ct +2358 -76 2366 -57 2380 -45 ct 2394 -32 2413 -26 2439 -26 ct 2462 -26 2486 -31 2512 -42 ct +2512 -42 2512 -42 2512 -9 ct p +2358 -132 m 2358 -132 2358 -132 2468 -132 ct 2468 -132 2468 -132 2468 -138 ct +2468 -158 2464 -173 2455 -183 ct 2446 -193 2434 -198 2417 -198 ct 2400 -198 2387 -192 2376 -181 ct +2366 -169 2360 -153 2358 -132 ct p ef +2722 0 m 2722 0 2722 0 2724 -42 ct 2724 -42 2724 -42 2722 -42 ct 2712 -26 2701 -15 2689 -7 ct +2676 1 2663 5 2648 5 ct 2623 5 2603 -5 2588 -24 ct 2573 -44 2566 -71 2566 -105 ct +2566 -142 2575 -172 2592 -195 ct 2610 -218 2632 -229 2660 -229 ct 2672 -229 2684 -226 2694 -221 ct +2704 -216 2714 -209 2722 -198 ct 2722 -198 2722 -198 2724 -198 ct 2724 -198 2724 -198 2722 -229 ct +2722 -229 2722 -229 2722 -326 ct 2722 -326 2722 -326 2763 -326 ct 2763 -326 2763 -326 2763 0 ct +2763 0 2763 0 2722 0 ct p +2722 -168 m 2712 -178 2703 -185 2694 -190 ct 2684 -195 2675 -198 2666 -198 ct +2648 -198 2634 -190 2624 -175 ct 2614 -159 2609 -137 2609 -109 ct 2609 -83 2613 -63 2621 -50 ct +2629 -38 2640 -31 2656 -31 ct 2668 -31 2679 -35 2690 -42 ct 2701 -49 2712 -59 2722 -73 ct +2722 -73 2722 -73 2722 -168 ct p ef +3230 0 m 3230 0 3230 0 3232 -42 ct 3232 -42 3232 -42 3230 -42 ct 3220 -26 3209 -15 3197 -7 ct +3184 1 3171 5 3156 5 ct 3131 5 3111 -5 3096 -24 ct 3081 -44 3074 -71 3074 -105 ct +3074 -142 3083 -172 3100 -195 ct 3118 -218 3140 -229 3168 -229 ct 3180 -229 3192 -226 3202 -221 ct +3212 -216 3222 -209 3230 -198 ct 3230 -198 3230 -198 3232 -198 ct 3232 -198 3232 -198 3230 -229 ct +3230 -229 3230 -229 3230 -326 ct 3230 -326 3230 -326 3271 -326 ct 3271 -326 3271 -326 3271 0 ct +3271 0 3271 0 3230 0 ct p +3230 -168 m 3220 -178 3211 -185 3202 -190 ct 3192 -195 3183 -198 3174 -198 ct +3156 -198 3142 -190 3132 -175 ct 3122 -159 3117 -137 3117 -109 ct 3117 -83 3121 -63 3129 -50 ct +3137 -38 3148 -31 3164 -31 ct 3176 -31 3187 -35 3198 -42 ct 3209 -49 3220 -59 3230 -73 ct +3230 -73 3230 -73 3230 -168 ct p ef +3520 -224 m 3520 -224 3520 -224 3520 0 ct 3520 0 3520 0 3479 0 ct 3479 0 3479 0 3481 -42 ct +3481 -42 3481 -42 3479 -42 ct 3470 -26 3458 -15 3446 -7 ct 3433 1 3418 5 3402 5 ct +3381 5 3365 -1 3354 -14 ct 3343 -27 3338 -46 3338 -71 ct 3338 -71 3338 -71 3338 -224 ct +3338 -224 3338 -224 3379 -224 ct 3379 -224 3379 -224 3379 -82 ct 3379 -65 3382 -52 3387 -45 ct +3393 -38 3402 -34 3415 -34 ct 3425 -34 3435 -38 3446 -45 ct 3457 -52 3468 -63 3479 -78 ct +3479 -78 3479 -78 3479 -224 ct 3479 -224 3479 -224 3520 -224 ct p ef +3575 0 m 3575 0 3575 0 3575 -224 ct 3575 -224 3575 -224 3611 -224 ct 3611 -224 3611 -224 3608 -182 ct +3608 -182 3608 -182 3611 -182 ct 3619 -198 3628 -209 3637 -217 ct 3645 -225 3653 -229 3661 -229 ct +3672 -229 3680 -225 3687 -216 ct 3694 -208 3698 -196 3699 -182 ct 3699 -182 3699 -182 3702 -182 ct +3709 -198 3717 -209 3725 -217 ct 3734 -225 3743 -229 3753 -229 ct 3766 -229 3776 -224 3783 -213 ct +3790 -202 3793 -186 3793 -164 ct 3793 -164 3793 -164 3793 0 ct 3793 0 3793 0 3757 0 ct +3757 0 3757 0 3757 -162 ct 3757 -172 3756 -180 3754 -185 ct 3752 -190 3748 -193 3744 -193 ct +3738 -193 3731 -189 3724 -181 ct 3717 -173 3709 -160 3702 -144 ct 3702 -144 3702 -144 3702 0 ct +3702 0 3702 0 3666 0 ct 3666 0 3666 0 3666 -155 ct 3666 -167 3665 -177 3663 -183 ct +3660 -190 3657 -193 3653 -193 ct 3647 -193 3640 -188 3632 -179 ct 3624 -170 3617 -158 3611 -144 ct +3611 -144 3611 -144 3611 0 ct 3611 0 3611 0 3575 0 ct p ef +3847 82 m 3847 82 3847 82 3847 -224 ct 3847 -224 3847 -224 3888 -224 ct 3888 -224 3888 -224 3886 -182 ct +3886 -182 3886 -182 3888 -182 ct 3898 -198 3909 -209 3921 -217 ct 3933 -225 3947 -229 3961 -229 ct +3986 -229 4006 -219 4021 -200 ct 4036 -180 4043 -153 4043 -120 ct 4043 -82 4034 -52 4017 -29 ct +4000 -6 3977 5 3949 5 ct 3937 5 3926 2 3916 -3 ct 3906 -8 3896 -15 3888 -26 ct +3888 -26 3888 -26 3886 -26 ct 3886 -26 3886 -26 3888 5 ct 3888 5 3888 5 3888 82 ct +3888 82 3888 82 3847 82 ct p +3888 -56 m 3897 -46 3907 -39 3916 -34 ct 3925 -29 3934 -26 3944 -26 ct 3962 -26 3975 -34 3985 -49 ct +3995 -65 4000 -87 4000 -115 ct 4000 -141 3996 -160 3988 -173 ct 3980 -186 3969 -193 3953 -193 ct +3942 -193 3930 -189 3919 -182 ct 3909 -175 3898 -165 3888 -151 ct 3888 -151 3888 -151 3888 -56 ct +p ef +pom +gr +gs +pum +7784 15030 t +466 -326 m 466 -326 466 -326 466 -295 ct 466 -295 466 -295 450 -295 ct 429 -295 415 -293 407 -287 ct +398 -282 394 -274 394 -261 ct 394 -257 395 -251 396 -242 ct 396 -242 396 -242 400 -214 ct +401 -204 402 -196 402 -190 ct 402 -175 399 -163 392 -153 ct 385 -144 375 -137 361 -132 ct +375 -128 385 -121 392 -111 ct 399 -102 402 -90 402 -75 ct 402 -68 401 -61 400 -51 ct +400 -51 400 -51 396 -23 ct 395 -14 394 -8 394 -4 ct 394 9 398 17 407 22 ct 415 27 429 30 450 30 ct +450 30 450 30 466 30 ct 466 30 466 30 466 61 ct 466 61 466 61 443 61 ct 414 61 392 56 378 46 ct +363 36 356 21 356 2 ct 356 -7 357 -16 359 -26 ct 359 -26 359 -26 366 -63 ct 367 -68 367 -74 367 -79 ct +367 -92 363 -101 355 -108 ct 348 -114 336 -117 321 -117 ct 321 -117 321 -117 302 -117 ct +302 -117 302 -117 302 -148 ct 302 -148 302 -148 321 -148 ct 336 -148 348 -151 355 -157 ct +363 -164 367 -173 367 -186 ct 367 -191 367 -197 366 -202 ct 366 -202 366 -202 359 -239 ct +357 -249 356 -258 356 -267 ct 356 -286 363 -301 378 -311 ct 392 -321 414 -326 443 -326 ct +443 -326 443 -326 466 -326 ct p ef +pom +gr +gs +pum +1942 15521 t +pom +gr +gs +pum +2958 15521 t +0.003 0.503 0.003 c 239 -326 m 65 61 l 15 61 l 189 -326 l 239 -326 l +p ef +493 -326 m 319 61 l 269 61 l 443 -326 l 493 -326 l p ef +791 0 m 791 0 791 0 791 -224 ct 791 -224 791 -224 852 -224 ct 852 -224 852 -224 851 -202 ct +851 -202 851 -202 850 -181 ct 850 -181 850 -181 852 -181 ct 859 -197 868 -209 880 -217 ct +892 -225 906 -229 924 -229 ct 946 -229 962 -223 973 -210 ct 984 -197 990 -178 990 -153 ct +990 -153 990 -153 990 0 ct 990 0 990 0 929 0 ct 929 0 929 0 929 -139 ct 929 -150 927 -159 923 -165 ct +918 -170 912 -173 903 -173 ct 894 -173 885 -170 876 -165 ct 868 -159 859 -151 852 -139 ct +852 -139 852 -139 852 0 ct 852 0 852 0 791 0 ct p ef +1252 -95 m 1252 -95 1252 -95 1100 -95 ct 1103 -77 1111 -63 1123 -54 ct 1135 -45 1151 -41 1172 -41 ct +1196 -41 1223 -46 1252 -56 ct 1252 -56 1252 -56 1252 -9 ct 1217 0 1186 5 1160 5 ct +1122 5 1091 -6 1068 -27 ct 1045 -48 1034 -76 1034 -111 ct 1034 -147 1045 -175 1066 -197 ct +1088 -218 1116 -229 1151 -229 ct 1183 -229 1207 -219 1225 -199 ct 1243 -180 1252 -152 1252 -118 ct +1252 -118 1252 -118 1252 -95 ct p +1099 -136 m 1099 -136 1099 -136 1193 -136 ct 1193 -153 1189 -166 1182 -175 ct +1174 -184 1163 -188 1148 -188 ct 1134 -188 1122 -184 1114 -175 ct 1106 -166 1101 -153 1099 -136 ct +p ef +1506 -95 m 1506 -95 1506 -95 1354 -95 ct 1357 -77 1365 -63 1377 -54 ct 1389 -45 1405 -41 1426 -41 ct +1450 -41 1477 -46 1506 -56 ct 1506 -56 1506 -56 1506 -9 ct 1471 0 1440 5 1414 5 ct +1376 5 1345 -6 1322 -27 ct 1299 -48 1288 -76 1288 -111 ct 1288 -147 1299 -175 1320 -197 ct +1342 -218 1370 -229 1405 -229 ct 1437 -229 1461 -219 1479 -199 ct 1497 -180 1506 -152 1506 -118 ct +1506 -118 1506 -118 1506 -95 ct p +1353 -136 m 1353 -136 1353 -136 1447 -136 ct 1447 -153 1443 -166 1436 -175 ct +1428 -184 1417 -188 1402 -188 ct 1388 -188 1376 -184 1368 -175 ct 1360 -166 1355 -153 1353 -136 ct +p ef +1698 0 m 1698 0 1698 0 1700 -42 ct 1700 -42 1700 -42 1698 -42 ct 1688 -27 1677 -15 1665 -7 ct +1654 1 1641 5 1627 5 ct 1601 5 1581 -5 1565 -26 ct 1550 -46 1542 -73 1542 -107 ct +1542 -144 1551 -174 1568 -196 ct 1585 -218 1608 -229 1637 -229 ct 1649 -229 1660 -227 1670 -222 ct +1680 -218 1689 -211 1698 -203 ct 1698 -203 1698 -203 1700 -203 ct 1700 -203 1700 -203 1698 -224 ct +1698 -224 1698 -224 1698 -326 ct 1698 -326 1698 -326 1759 -326 ct 1759 -326 1759 -326 1759 0 ct +1759 0 1759 0 1698 0 ct p +1698 -160 m 1691 -168 1684 -173 1677 -177 ct 1670 -181 1662 -183 1654 -183 ct +1638 -183 1627 -177 1619 -164 ct 1612 -152 1608 -133 1608 -108 ct 1608 -89 1611 -75 1618 -65 ct +1625 -56 1635 -51 1648 -51 ct 1657 -51 1665 -54 1674 -60 ct 1682 -66 1690 -75 1698 -88 ct +1698 -88 1698 -88 1698 -160 ct p ef +1811 -8 m 1811 -8 1811 -8 1811 -54 ct 1845 -42 1873 -36 1893 -36 ct 1908 -36 1919 -38 1927 -42 ct +1934 -46 1938 -52 1938 -60 ct 1938 -64 1936 -68 1932 -72 ct 1929 -75 1923 -79 1916 -82 ct +1916 -82 1916 -82 1868 -101 ct 1849 -109 1835 -118 1826 -127 ct 1817 -137 1812 -148 1812 -161 ct +1812 -182 1822 -199 1841 -211 ct 1860 -223 1887 -229 1921 -229 ct 1941 -229 1964 -226 1990 -221 ct +1990 -221 1990 -221 1990 -174 ct 1962 -183 1938 -188 1919 -188 ct 1904 -188 1894 -186 1887 -183 ct +1880 -180 1876 -175 1876 -169 ct 1876 -165 1879 -162 1884 -158 ct 1889 -154 1896 -150 1906 -146 ct +1906 -146 1906 -146 1959 -124 ct 1975 -118 1987 -110 1994 -100 ct 2002 -91 2006 -79 2006 -66 ct +2006 -45 1997 -28 1978 -15 ct 1959 -2 1935 5 1905 5 ct 1879 5 1847 1 1811 -8 ct +p ef +2319 -8 m 2319 -8 2319 -8 2319 -54 ct 2353 -42 2381 -36 2401 -36 ct 2416 -36 2427 -38 2435 -42 ct +2442 -46 2446 -52 2446 -60 ct 2446 -64 2444 -68 2440 -72 ct 2437 -75 2431 -79 2424 -82 ct +2424 -82 2424 -82 2376 -101 ct 2357 -109 2343 -118 2334 -127 ct 2325 -137 2320 -148 2320 -161 ct +2320 -182 2330 -199 2349 -211 ct 2368 -223 2395 -229 2429 -229 ct 2449 -229 2472 -226 2498 -221 ct +2498 -221 2498 -221 2498 -174 ct 2470 -183 2446 -188 2427 -188 ct 2412 -188 2402 -186 2395 -183 ct +2388 -180 2384 -175 2384 -169 ct 2384 -165 2387 -162 2392 -158 ct 2397 -154 2404 -150 2414 -146 ct +2414 -146 2414 -146 2467 -124 ct 2483 -118 2495 -110 2502 -100 ct 2510 -91 2514 -79 2514 -66 ct +2514 -45 2505 -28 2486 -15 ct 2467 -2 2443 5 2413 5 ct 2387 5 2355 1 2319 -8 ct +p ef +2768 -6 m 2744 1 2722 5 2704 5 ct 2675 5 2654 -1 2640 -14 ct 2626 -26 2619 -45 2619 -70 ct +2619 -70 2619 -70 2619 -178 ct 2619 -178 2619 -178 2571 -178 ct 2571 -178 2571 -178 2571 -219 ct +2571 -219 2571 -219 2619 -219 ct 2619 -219 2619 -219 2619 -285 ct 2619 -285 2619 -285 2680 -285 ct +2680 -285 2680 -285 2680 -219 ct 2680 -219 2680 -219 2763 -219 ct 2763 -219 2763 -219 2763 -178 ct +2763 -178 2763 -178 2680 -178 ct 2680 -178 2680 -178 2680 -84 ct 2680 -68 2683 -57 2689 -51 ct +2695 -44 2705 -41 2719 -41 ct 2736 -41 2752 -44 2768 -51 ct 2768 -51 2768 -51 2768 -6 ct +p ef +2968 0 m 2968 0 2968 0 2970 -42 ct 2970 -42 2970 -42 2968 -42 ct 2958 -27 2947 -15 2935 -7 ct +2924 1 2911 5 2897 5 ct 2871 5 2851 -5 2835 -26 ct 2820 -46 2812 -73 2812 -107 ct +2812 -144 2821 -174 2838 -196 ct 2855 -218 2878 -229 2907 -229 ct 2919 -229 2930 -227 2940 -222 ct +2950 -218 2959 -211 2968 -203 ct 2968 -203 2968 -203 2970 -203 ct 2970 -203 2970 -203 2968 -224 ct +2968 -224 2968 -224 2968 -326 ct 2968 -326 2968 -326 3029 -326 ct 3029 -326 3029 -326 3029 0 ct +3029 0 3029 0 2968 0 ct p +2968 -160 m 2961 -168 2954 -173 2947 -177 ct 2940 -181 2932 -183 2924 -183 ct +2908 -183 2897 -177 2889 -164 ct 2882 -152 2878 -133 2878 -108 ct 2878 -89 2881 -75 2888 -65 ct +2895 -56 2905 -51 2918 -51 ct 2927 -51 2935 -54 2944 -60 ct 2952 -66 2960 -75 2968 -88 ct +2968 -88 2968 -88 2968 -160 ct p ef +3170 0 m 3170 -183 l 3088 -183 l 3088 -224 l 3231 -224 l 3231 0 l +3170 0 l p +3170 -265 m 3170 -326 l 3231 -326 l 3231 -265 l 3170 -265 l p ef +3428 5 m 3394 5 3366 -6 3345 -27 ct 3324 -49 3313 -77 3313 -112 ct 3313 -148 3324 -176 3345 -197 ct +3366 -218 3394 -229 3430 -229 ct 3465 -229 3493 -218 3514 -197 ct 3535 -176 3546 -148 3546 -112 ct +3546 -76 3535 -48 3514 -27 ct 3493 -6 3464 5 3428 5 ct p +3429 -36 m 3446 -36 3459 -42 3467 -55 ct 3476 -68 3480 -87 3480 -112 ct 3480 -138 3476 -156 3467 -169 ct +3459 -182 3446 -188 3430 -188 ct 3413 -188 3400 -182 3392 -169 ct 3383 -156 3379 -137 3379 -112 ct +3379 -87 3383 -68 3391 -55 ct 3400 -42 3412 -36 3429 -36 ct p ef +pom +gr +gs +pum +1942 16012 t +pom +gr +gs +pum +2450 16012 t +43 -326 m 43 -326 43 -326 43 -295 ct 43 -295 43 -295 59 -295 ct 80 -295 94 -293 102 -287 ct +111 -282 115 -274 115 -261 ct 115 -257 114 -251 113 -242 ct 113 -242 113 -242 109 -214 ct +108 -204 107 -196 107 -190 ct 107 -175 110 -163 117 -153 ct 124 -144 134 -137 148 -132 ct +134 -128 124 -121 117 -111 ct 110 -102 107 -90 107 -75 ct 107 -68 108 -61 109 -51 ct +109 -51 109 -51 113 -23 ct 114 -14 115 -8 115 -4 ct 115 9 111 17 102 22 ct 94 27 80 30 59 30 ct +59 30 59 30 43 30 ct 43 30 43 30 43 61 ct 43 61 43 61 66 61 ct 95 61 117 56 131 46 ct +146 36 153 21 153 2 ct 153 -7 152 -16 150 -26 ct 150 -26 150 -26 143 -63 ct 142 -68 142 -74 142 -79 ct +142 -92 146 -101 154 -108 ct 161 -114 173 -117 188 -117 ct 188 -117 188 -117 207 -117 ct +207 -117 207 -117 207 -148 ct 207 -148 207 -148 188 -148 ct 173 -148 161 -151 154 -157 ct +146 -164 142 -173 142 -186 ct 142 -191 142 -197 143 -202 ct 143 -202 143 -202 150 -239 ct +152 -249 153 -258 153 -267 ct 153 -286 146 -301 131 -311 ct 117 -321 95 -326 66 -326 ct +66 -326 66 -326 43 -326 ct p ef +pom +gr +gs +pum +1942 16503 t +0.003 0.003 1.000 c 24 82 m 24 82 24 82 24 -224 ct 24 -224 24 -224 85 -224 ct +85 -224 85 -224 83 -182 ct 83 -182 83 -182 85 -182 ct 95 -197 106 -209 117 -217 ct +129 -225 142 -229 156 -229 ct 182 -229 202 -219 218 -198 ct 233 -178 241 -151 241 -117 ct +241 -80 232 -50 215 -28 ct 198 -6 175 5 146 5 ct 134 5 122 3 112 -2 ct 102 -6 93 -13 85 -22 ct +85 -22 85 -22 83 -22 ct 83 -22 83 -22 85 0 ct 85 0 85 0 85 82 ct 85 82 85 82 24 82 ct +p +85 -64 m 92 -56 99 -50 106 -47 ct 113 -43 121 -41 130 -41 ct 145 -41 156 -47 164 -60 ct +171 -72 175 -91 175 -116 ct 175 -135 172 -149 165 -159 ct 158 -168 149 -173 135 -173 ct +127 -173 118 -170 109 -164 ct 101 -158 93 -149 85 -136 ct 85 -136 85 -136 85 -64 ct +p ef +480 -224 m 480 -224 480 -224 480 0 ct 480 0 480 0 419 0 ct 419 0 419 0 420 -22 ct +420 -22 420 -22 422 -43 ct 422 -43 422 -43 419 -43 ct 413 -27 404 -15 392 -7 ct +380 1 365 5 348 5 ct 326 5 309 -1 298 -14 ct 287 -27 281 -46 281 -71 ct 281 -71 281 -71 281 -224 ct +281 -224 281 -224 342 -224 ct 342 -224 342 -224 342 -85 ct 342 -73 344 -65 348 -59 ct +353 -54 359 -51 368 -51 ct 377 -51 386 -54 395 -59 ct 403 -65 411 -73 419 -85 ct +419 -85 419 -85 419 -224 ct 419 -224 419 -224 480 -224 ct p ef +533 0 m 533 0 533 0 533 -326 ct 533 -326 533 -326 594 -326 ct 594 -326 594 -326 594 -224 ct +594 -224 594 -224 592 -182 ct 592 -182 592 -182 594 -182 ct 604 -197 615 -209 626 -217 ct +638 -225 651 -229 665 -229 ct 691 -229 711 -219 727 -198 ct 742 -178 750 -151 750 -117 ct +750 -80 741 -50 724 -28 ct 707 -6 684 5 655 5 ct 643 5 631 3 621 -2 ct 611 -6 602 -13 594 -22 ct +594 -22 594 -22 592 -22 ct 592 -22 592 -22 584 0 ct 584 0 584 0 533 0 ct p +594 -64 m 601 -56 608 -50 615 -47 ct 622 -43 630 -41 639 -41 ct 654 -41 665 -47 673 -60 ct +680 -72 684 -91 684 -116 ct 684 -135 681 -149 674 -159 ct 667 -168 658 -173 644 -173 ct +636 -173 627 -170 618 -164 ct 610 -158 602 -149 594 -136 ct 594 -136 594 -136 594 -64 ct +p ef +864 0 m 864 -285 l 782 -285 l 782 -326 l 925 -326 l 925 0 l 864 0 l +p ef +1138 0 m 1138 -183 l 1056 -183 l 1056 -224 l 1199 -224 l 1199 0 l +1138 0 l p +1138 -265 m 1138 -326 l 1199 -326 l 1199 -265 l 1138 -265 l p ef +1497 -4 m 1472 2 1447 5 1422 5 ct 1381 5 1348 -5 1325 -26 ct 1302 -47 1290 -75 1290 -111 ct +1290 -148 1301 -177 1324 -198 ct 1346 -219 1378 -229 1418 -229 ct 1448 -229 1474 -226 1497 -220 ct +1497 -220 1497 -220 1497 -175 ct 1472 -184 1449 -188 1426 -188 ct 1404 -188 1387 -182 1375 -169 ct +1362 -157 1356 -140 1356 -118 ct 1356 -94 1364 -74 1379 -60 ct 1394 -45 1414 -38 1439 -38 ct +1458 -38 1478 -42 1497 -49 ct 1497 -49 1497 -49 1497 -4 ct p ef +pom +gr +gs +pum +3466 16503 t +97 -163 m 97 -224 l 158 -224 l 158 -163 l 97 -163 l p +97 0 m 97 -61 l 158 -61 l 158 0 l 97 0 l p ef +pom +gr +gs +pum +1942 16994 t +pom +gr +gs +pum +2450 16994 t +0.003 0.003 1.000 c 98 0 m 9 -224 l 75 -224 l 137 -67 l 198 -224 l 247 -224 l +159 0 l 98 0 l p ef +380 5 m 346 5 318 -6 297 -27 ct 276 -49 265 -77 265 -112 ct 265 -148 276 -176 297 -197 ct +318 -218 346 -229 382 -229 ct 417 -229 445 -218 466 -197 ct 487 -176 498 -148 498 -112 ct +498 -76 487 -48 466 -27 ct 445 -6 416 5 380 5 ct p +381 -36 m 398 -36 411 -42 419 -55 ct 428 -68 432 -87 432 -112 ct 432 -138 428 -156 419 -169 ct +411 -182 398 -188 382 -188 ct 365 -188 352 -182 344 -169 ct 335 -156 331 -137 331 -112 ct +331 -87 335 -68 343 -55 ct 352 -42 364 -36 381 -36 ct p ef +630 0 m 630 -183 l 548 -183 l 548 -224 l 691 -224 l 691 0 l 630 0 l +p +630 -265 m 630 -326 l 691 -326 l 691 -265 l 630 -265 l p ef +936 0 m 936 0 936 0 938 -42 ct 938 -42 938 -42 936 -42 ct 926 -27 915 -15 903 -7 ct +892 1 879 5 865 5 ct 839 5 819 -5 803 -26 ct 788 -46 780 -73 780 -107 ct 780 -144 789 -174 806 -196 ct +823 -218 846 -229 875 -229 ct 887 -229 898 -227 908 -222 ct 918 -218 927 -211 936 -203 ct +936 -203 936 -203 938 -203 ct 938 -203 938 -203 936 -224 ct 936 -224 936 -224 936 -326 ct +936 -326 936 -326 997 -326 ct 997 -326 997 -326 997 0 ct 997 0 997 0 936 0 ct p +936 -160 m 929 -168 922 -173 915 -177 ct 908 -181 900 -183 892 -183 ct 876 -183 865 -177 857 -164 ct +850 -152 846 -133 846 -108 ct 846 -89 849 -75 856 -65 ct 863 -56 873 -51 886 -51 ct +895 -51 903 -54 912 -60 ct 920 -66 928 -75 936 -88 ct 936 -88 936 -88 936 -160 ct +p ef +pom +gr +gs +pum +3466 16994 t +pom +gr +gs +pum +3720 16994 t +228 0 m 208 3 188 5 169 5 ct 136 5 113 -1 101 -13 ct 89 -25 83 -47 83 -80 ct 83 -80 83 -80 83 -188 ct +83 -188 83 -188 27 -188 ct 27 -188 27 -188 27 -219 ct 27 -219 27 -219 83 -219 ct +83 -219 83 -219 83 -267 ct 83 -267 83 -267 124 -267 ct 124 -267 124 -267 124 -219 ct +124 -219 124 -219 223 -219 ct 223 -219 223 -219 223 -188 ct 223 -188 223 -188 124 -188 ct +124 -188 124 -188 124 -74 ct 124 -61 125 -53 126 -48 ct 128 -43 131 -39 137 -35 ct +146 -29 159 -26 177 -26 ct 194 -26 211 -28 228 -31 ct 228 -31 228 -31 228 0 ct +p ef +318 0 m 318 0 318 0 318 -224 ct 318 -224 318 -224 359 -224 ct 359 -224 359 -224 357 -182 ct +357 -182 357 -182 359 -182 ct 369 -198 381 -209 395 -217 ct 409 -225 424 -229 442 -229 ct +454 -229 468 -227 483 -224 ct 483 -224 483 -224 483 -160 ct 483 -160 483 -160 452 -160 ct +452 -160 452 -160 452 -191 ct 446 -192 440 -193 435 -193 ct 421 -193 408 -189 396 -181 ct +383 -173 371 -161 359 -145 ct 359 -145 359 -145 359 0 ct 359 0 359 0 318 0 ct p ef +680 -26 m 656 -5 631 5 607 5 ct 586 5 569 -1 556 -13 ct 543 -24 536 -39 536 -57 ct +536 -81 546 -99 567 -114 ct 588 -128 615 -135 649 -135 ct 649 -135 649 -135 674 -135 ct +674 -135 674 -135 674 -154 ct 674 -169 670 -180 663 -187 ct 655 -194 644 -198 629 -198 ct +605 -198 580 -191 555 -177 ct 555 -177 555 -177 555 -213 ct 584 -224 611 -229 637 -229 ct +666 -229 686 -223 697 -212 ct 709 -201 715 -181 715 -153 ct 715 -153 715 -153 715 -59 ct +715 -45 716 -36 719 -31 ct 722 -26 728 -24 735 -24 ct 738 -24 742 -25 748 -26 ct +748 -26 748 -26 752 -2 ct 738 3 728 5 721 5 ct 711 5 702 2 696 -3 ct 689 -8 684 -16 680 -26 ct +p +674 -53 m 674 -53 674 -53 674 -110 ct 674 -110 674 -110 662 -110 ct 634 -110 613 -106 599 -99 ct +585 -91 578 -80 578 -64 ct 578 -52 581 -43 588 -37 ct 594 -31 604 -28 617 -28 ct +635 -28 654 -36 674 -53 ct p ef +799 0 m 799 0 799 0 799 -224 ct 799 -224 799 -224 840 -224 ct 840 -224 840 -224 838 -182 ct +838 -182 838 -182 840 -182 ct 850 -198 861 -209 874 -217 ct 886 -225 901 -229 917 -229 ct +938 -229 954 -223 965 -210 ct 976 -197 981 -178 981 -153 ct 981 -153 981 -153 981 0 ct +981 0 981 0 940 0 ct 940 0 940 0 940 -142 ct 940 -159 937 -172 932 -179 ct 926 -186 917 -190 904 -190 ct +894 -190 884 -186 873 -179 ct 862 -172 851 -161 840 -146 ct 840 -146 840 -146 840 0 ct +840 0 840 0 799 0 ct p ef +1055 -9 m 1055 -9 1055 -9 1055 -45 ct 1086 -32 1113 -26 1136 -26 ct 1152 -26 1166 -29 1177 -36 ct +1188 -43 1193 -51 1193 -61 ct 1193 -74 1180 -84 1155 -93 ct 1155 -93 1155 -93 1112 -107 ct +1078 -118 1061 -138 1061 -165 ct 1061 -186 1069 -201 1084 -212 ct 1099 -223 1121 -229 1149 -229 ct +1170 -229 1194 -226 1222 -219 ct 1222 -219 1222 -219 1222 -186 ct 1195 -194 1171 -198 1149 -198 ct +1133 -198 1120 -196 1112 -191 ct 1104 -186 1100 -179 1100 -169 ct 1100 -158 1110 -149 1130 -142 ct +1130 -142 1130 -142 1182 -124 ct 1217 -111 1234 -91 1234 -64 ct 1234 -43 1225 -26 1208 -14 ct +1190 -1 1167 5 1137 5 ct 1112 5 1084 0 1055 -9 ct p ef +1362 0 m 1362 0 1362 0 1362 -188 ct 1362 -188 1362 -188 1301 -188 ct 1301 -188 1301 -188 1301 -219 ct +1301 -219 1301 -219 1362 -219 ct 1362 -219 1362 -219 1362 -243 ct 1362 -274 1369 -297 1384 -310 ct +1398 -324 1422 -331 1456 -331 ct 1478 -331 1498 -328 1518 -322 ct 1518 -322 1518 -322 1518 -289 ct +1498 -296 1478 -300 1459 -300 ct 1438 -300 1424 -296 1415 -288 ct 1407 -280 1403 -267 1403 -247 ct +1403 -247 1403 -247 1403 -219 ct 1403 -219 1403 -219 1510 -219 ct 1510 -219 1510 -219 1510 -188 ct +1510 -188 1510 -188 1403 -188 ct 1403 -188 1403 -188 1403 0 ct 1403 0 1403 0 1362 0 ct +p ef +1650 5 m 1618 5 1593 -6 1574 -27 ct 1555 -48 1546 -76 1546 -112 ct 1546 -148 1555 -177 1574 -198 ct +1593 -219 1619 -229 1652 -229 ct 1684 -229 1710 -219 1729 -198 ct 1748 -177 1757 -149 1757 -113 ct +1757 -76 1748 -47 1729 -26 ct 1710 -5 1684 5 1650 5 ct p +1651 -26 m 1672 -26 1688 -33 1698 -48 ct 1709 -62 1714 -84 1714 -113 ct 1714 -139 1708 -160 1697 -175 ct +1686 -190 1671 -198 1652 -198 ct 1632 -198 1617 -190 1606 -175 ct 1595 -160 1589 -139 1589 -112 ct +1589 -85 1594 -64 1605 -49 ct 1616 -34 1632 -26 1651 -26 ct p ef +1842 0 m 1842 0 1842 0 1842 -224 ct 1842 -224 1842 -224 1883 -224 ct 1883 -224 1883 -224 1881 -182 ct +1881 -182 1881 -182 1883 -182 ct 1893 -198 1905 -209 1919 -217 ct 1933 -225 1948 -229 1966 -229 ct +1978 -229 1992 -227 2007 -224 ct 2007 -224 2007 -224 2007 -160 ct 2007 -160 2007 -160 1976 -160 ct +1976 -160 1976 -160 1976 -191 ct 1970 -192 1964 -193 1959 -193 ct 1945 -193 1932 -189 1920 -181 ct +1907 -173 1895 -161 1883 -145 ct 1883 -145 1883 -145 1883 0 ct 1883 0 1883 0 1842 0 ct +p ef +2051 0 m 2051 0 2051 0 2051 -224 ct 2051 -224 2051 -224 2087 -224 ct 2087 -224 2087 -224 2084 -182 ct +2084 -182 2084 -182 2087 -182 ct 2095 -198 2104 -209 2113 -217 ct 2121 -225 2129 -229 2137 -229 ct +2148 -229 2156 -225 2163 -216 ct 2170 -208 2174 -196 2175 -182 ct 2175 -182 2175 -182 2178 -182 ct +2185 -198 2193 -209 2201 -217 ct 2210 -225 2219 -229 2229 -229 ct 2242 -229 2252 -224 2259 -213 ct +2266 -202 2269 -186 2269 -164 ct 2269 -164 2269 -164 2269 0 ct 2269 0 2269 0 2233 0 ct +2233 0 2233 0 2233 -162 ct 2233 -172 2232 -180 2230 -185 ct 2228 -190 2224 -193 2220 -193 ct +2214 -193 2207 -189 2200 -181 ct 2193 -173 2185 -160 2178 -144 ct 2178 -144 2178 -144 2178 0 ct +2178 0 2178 0 2142 0 ct 2142 0 2142 0 2142 -155 ct 2142 -167 2141 -177 2139 -183 ct +2136 -190 2133 -193 2129 -193 ct 2123 -193 2116 -188 2108 -179 ct 2100 -170 2093 -158 2087 -144 ct +2087 -144 2087 -144 2087 0 ct 2087 0 2087 0 2051 0 ct p ef +2512 -9 m 2484 0 2458 5 2434 5 ct 2396 5 2367 -5 2346 -25 ct 2325 -45 2315 -73 2315 -110 ct +2315 -144 2325 -173 2345 -195 ct 2365 -218 2390 -229 2421 -229 ct 2452 -229 2474 -220 2489 -201 ct +2504 -182 2511 -153 2511 -114 ct 2511 -114 2511 -114 2511 -101 ct 2511 -101 2511 -101 2357 -101 ct +2358 -76 2366 -57 2380 -45 ct 2394 -32 2413 -26 2439 -26 ct 2462 -26 2486 -31 2512 -42 ct +2512 -42 2512 -42 2512 -9 ct p +2358 -132 m 2358 -132 2358 -132 2468 -132 ct 2468 -132 2468 -132 2468 -138 ct +2468 -158 2464 -173 2455 -183 ct 2446 -193 2434 -198 2417 -198 ct 2400 -198 2387 -192 2376 -181 ct +2366 -169 2360 -153 2358 -132 ct p ef +2722 0 m 2722 0 2722 0 2724 -42 ct 2724 -42 2724 -42 2722 -42 ct 2712 -26 2701 -15 2689 -7 ct +2676 1 2663 5 2648 5 ct 2623 5 2603 -5 2588 -24 ct 2573 -44 2566 -71 2566 -105 ct +2566 -142 2575 -172 2592 -195 ct 2610 -218 2632 -229 2660 -229 ct 2672 -229 2684 -226 2694 -221 ct +2704 -216 2714 -209 2722 -198 ct 2722 -198 2722 -198 2724 -198 ct 2724 -198 2724 -198 2722 -229 ct +2722 -229 2722 -229 2722 -326 ct 2722 -326 2722 -326 2763 -326 ct 2763 -326 2763 -326 2763 0 ct +2763 0 2763 0 2722 0 ct p +2722 -168 m 2712 -178 2703 -185 2694 -190 ct 2684 -195 2675 -198 2666 -198 ct +2648 -198 2634 -190 2624 -175 ct 2614 -159 2609 -137 2609 -109 ct 2609 -83 2613 -63 2621 -50 ct +2629 -38 2640 -31 2656 -31 ct 2668 -31 2679 -35 2690 -42 ct 2701 -49 2712 -59 2722 -73 ct +2722 -73 2722 -73 2722 -168 ct p ef +3140 0 m 3140 0 3140 0 3140 -188 ct 3140 -188 3140 -188 3079 -188 ct 3079 -188 3079 -188 3079 -219 ct +3079 -219 3079 -219 3140 -219 ct 3140 -219 3140 -219 3140 -243 ct 3140 -274 3147 -297 3162 -310 ct +3176 -324 3200 -331 3234 -331 ct 3256 -331 3276 -328 3296 -322 ct 3296 -322 3296 -322 3296 -289 ct +3276 -296 3256 -300 3237 -300 ct 3216 -300 3202 -296 3193 -288 ct 3185 -280 3181 -267 3181 -247 ct +3181 -247 3181 -247 3181 -219 ct 3181 -219 3181 -219 3288 -219 ct 3288 -219 3288 -219 3288 -188 ct +3288 -188 3288 -188 3181 -188 ct 3181 -188 3181 -188 3181 0 ct 3181 0 3181 0 3140 0 ct +p ef +pom +gr +gs +pum +7022 16994 t +466 -326 m 466 -326 466 -326 466 -295 ct 466 -295 466 -295 450 -295 ct 429 -295 415 -293 407 -287 ct +398 -282 394 -274 394 -261 ct 394 -257 395 -251 396 -242 ct 396 -242 396 -242 400 -214 ct +401 -204 402 -196 402 -190 ct 402 -175 399 -163 392 -153 ct 385 -144 375 -137 361 -132 ct +375 -128 385 -121 392 -111 ct 399 -102 402 -90 402 -75 ct 402 -68 401 -61 400 -51 ct +400 -51 400 -51 396 -23 ct 395 -14 394 -8 394 -4 ct 394 9 398 17 407 22 ct 415 27 429 30 450 30 ct +450 30 450 30 466 30 ct 466 30 466 30 466 61 ct 466 61 466 61 443 61 ct 414 61 392 56 378 46 ct +363 36 356 21 356 2 ct 356 -7 357 -16 359 -26 ct 359 -26 359 -26 366 -63 ct 367 -68 367 -74 367 -79 ct +367 -92 363 -101 355 -108 ct 348 -114 336 -117 321 -117 ct 321 -117 321 -117 302 -117 ct +302 -117 302 -117 302 -148 ct 302 -148 302 -148 321 -148 ct 336 -148 348 -151 355 -157 ct +363 -164 367 -173 367 -186 ct 367 -191 367 -197 366 -202 ct 366 -202 366 -202 359 -239 ct +357 -249 356 -258 356 -267 ct 356 -286 363 -301 378 -311 ct 392 -321 414 -326 443 -326 ct +443 -326 443 -326 466 -326 ct p ef +pom +gr +gs +pum +1942 17485 t +pom +gr +gs +pum +2958 17485 t +0.003 0.503 0.003 c 239 -326 m 65 61 l 15 61 l 189 -326 l 239 -326 l +p ef +493 -326 m 319 61 l 269 61 l 443 -326 l 493 -326 l p ef +936 0 m 936 0 936 0 938 -42 ct 938 -42 938 -42 936 -42 ct 926 -27 915 -15 903 -7 ct +892 1 879 5 865 5 ct 839 5 819 -5 803 -26 ct 788 -46 780 -73 780 -107 ct 780 -144 789 -174 806 -196 ct +823 -218 846 -229 875 -229 ct 887 -229 898 -227 908 -222 ct 918 -218 927 -211 936 -203 ct +936 -203 936 -203 938 -203 ct 938 -203 938 -203 936 -224 ct 936 -224 936 -224 936 -326 ct +936 -326 936 -326 997 -326 ct 997 -326 997 -326 997 0 ct 997 0 997 0 936 0 ct p +936 -160 m 929 -168 922 -173 915 -177 ct 908 -181 900 -183 892 -183 ct 876 -183 865 -177 857 -164 ct +850 -152 846 -133 846 -108 ct 846 -89 849 -75 856 -65 ct 863 -56 873 -51 886 -51 ct +895 -51 903 -54 912 -60 ct 920 -66 928 -75 936 -88 ct 936 -88 936 -88 936 -160 ct +p ef +1142 5 m 1108 5 1080 -6 1059 -27 ct 1038 -49 1027 -77 1027 -112 ct 1027 -148 1038 -176 1059 -197 ct +1080 -218 1108 -229 1144 -229 ct 1179 -229 1207 -218 1228 -197 ct 1249 -176 1260 -148 1260 -112 ct +1260 -76 1249 -48 1228 -27 ct 1207 -6 1178 5 1142 5 ct p +1143 -36 m 1160 -36 1173 -42 1181 -55 ct 1190 -68 1194 -87 1194 -112 ct 1194 -138 1190 -156 1181 -169 ct +1173 -182 1160 -188 1144 -188 ct 1127 -188 1114 -182 1106 -169 ct 1097 -156 1093 -137 1093 -112 ct +1093 -87 1097 -68 1105 -55 ct 1114 -42 1126 -36 1143 -36 ct p ef +1557 -8 m 1557 -8 1557 -8 1557 -54 ct 1591 -42 1619 -36 1639 -36 ct 1654 -36 1665 -38 1673 -42 ct +1680 -46 1684 -52 1684 -60 ct 1684 -64 1682 -68 1678 -72 ct 1675 -75 1669 -79 1662 -82 ct +1662 -82 1662 -82 1614 -101 ct 1595 -109 1581 -118 1572 -127 ct 1563 -137 1558 -148 1558 -161 ct +1558 -182 1568 -199 1587 -211 ct 1606 -223 1633 -229 1667 -229 ct 1687 -229 1710 -226 1736 -221 ct +1736 -221 1736 -221 1736 -174 ct 1708 -183 1684 -188 1665 -188 ct 1650 -188 1640 -186 1633 -183 ct +1626 -180 1622 -175 1622 -169 ct 1622 -165 1625 -162 1630 -158 ct 1635 -154 1642 -150 1652 -146 ct +1652 -146 1652 -146 1705 -124 ct 1721 -118 1733 -110 1740 -100 ct 1748 -91 1752 -79 1752 -66 ct +1752 -45 1743 -28 1724 -15 ct 1705 -2 1681 5 1651 5 ct 1625 5 1593 1 1557 -8 ct +p ef +1904 5 m 1870 5 1842 -6 1821 -27 ct 1800 -49 1789 -77 1789 -112 ct 1789 -148 1800 -176 1821 -197 ct +1842 -218 1870 -229 1906 -229 ct 1941 -229 1969 -218 1990 -197 ct 2011 -176 2022 -148 2022 -112 ct +2022 -76 2011 -48 1990 -27 ct 1969 -6 1940 5 1904 5 ct p +1905 -36 m 1922 -36 1935 -42 1943 -55 ct 1952 -68 1956 -87 1956 -112 ct 1956 -138 1952 -156 1943 -169 ct +1935 -182 1922 -188 1906 -188 ct 1889 -188 1876 -182 1868 -169 ct 1859 -156 1855 -137 1855 -112 ct +1855 -87 1859 -68 1867 -55 ct 1876 -42 1888 -36 1905 -36 ct p ef +2185 0 m 2185 0 2185 0 2134 0 ct 2134 0 2134 0 2134 -149 ct 2134 -157 2133 -163 2132 -167 ct +2130 -171 2128 -173 2125 -173 ct 2120 -173 2116 -171 2112 -166 ct 2108 -161 2105 -154 2101 -145 ct +2101 -145 2101 -145 2101 0 ct 2101 0 2101 0 2050 0 ct 2050 0 2050 0 2050 -224 ct +2050 -224 2050 -224 2101 -224 ct 2101 -224 2101 -224 2098 -181 ct 2098 -181 2098 -181 2101 -181 ct +2106 -197 2113 -209 2121 -217 ct 2129 -225 2138 -229 2148 -229 ct 2159 -229 2168 -225 2174 -217 ct +2180 -209 2184 -197 2185 -181 ct 2185 -181 2185 -181 2187 -181 ct 2192 -197 2198 -209 2205 -217 ct +2213 -225 2221 -229 2231 -229 ct 2245 -229 2255 -223 2261 -212 ct 2266 -200 2269 -179 2269 -150 ct +2269 -150 2269 -150 2269 0 ct 2269 0 2269 0 2218 0 ct 2218 0 2218 0 2218 -149 ct +2218 -157 2217 -163 2216 -167 ct 2214 -171 2212 -173 2209 -173 ct 2204 -173 2200 -171 2196 -166 ct +2193 -161 2189 -154 2185 -145 ct 2185 -145 2185 -145 2185 0 ct p ef +2522 -95 m 2522 -95 2522 -95 2370 -95 ct 2373 -77 2381 -63 2393 -54 ct 2405 -45 2421 -41 2442 -41 ct +2466 -41 2493 -46 2522 -56 ct 2522 -56 2522 -56 2522 -9 ct 2487 0 2456 5 2430 5 ct +2392 5 2361 -6 2338 -27 ct 2315 -48 2304 -76 2304 -111 ct 2304 -147 2315 -175 2336 -197 ct +2358 -218 2386 -229 2421 -229 ct 2453 -229 2477 -219 2495 -199 ct 2513 -180 2522 -152 2522 -118 ct +2522 -118 2522 -118 2522 -95 ct p +2369 -136 m 2369 -136 2369 -136 2463 -136 ct 2463 -153 2459 -166 2452 -175 ct +2444 -184 2433 -188 2418 -188 ct 2404 -188 2392 -184 2384 -175 ct 2376 -166 2371 -153 2369 -136 ct +p ef +2768 -6 m 2744 1 2722 5 2704 5 ct 2675 5 2654 -1 2640 -14 ct 2626 -26 2619 -45 2619 -70 ct +2619 -70 2619 -70 2619 -178 ct 2619 -178 2619 -178 2571 -178 ct 2571 -178 2571 -178 2571 -219 ct +2571 -219 2571 -219 2619 -219 ct 2619 -219 2619 -219 2619 -285 ct 2619 -285 2619 -285 2680 -285 ct +2680 -285 2680 -285 2680 -219 ct 2680 -219 2680 -219 2763 -219 ct 2763 -219 2763 -219 2763 -178 ct +2763 -178 2763 -178 2680 -178 ct 2680 -178 2680 -178 2680 -84 ct 2680 -68 2683 -57 2689 -51 ct +2695 -44 2705 -41 2719 -41 ct 2736 -41 2752 -44 2768 -51 ct 2768 -51 2768 -51 2768 -6 ct +p ef +2823 0 m 2823 0 2823 0 2823 -326 ct 2823 -326 2823 -326 2884 -326 ct 2884 -326 2884 -326 2884 -224 ct +2884 -224 2884 -224 2882 -181 ct 2882 -181 2882 -181 2884 -181 ct 2891 -197 2900 -209 2912 -217 ct +2924 -225 2938 -229 2956 -229 ct 2978 -229 2994 -223 3005 -210 ct 3016 -197 3022 -178 3022 -153 ct +3022 -153 3022 -153 3022 0 ct 3022 0 3022 0 2961 0 ct 2961 0 2961 0 2961 -139 ct +2961 -150 2959 -159 2955 -165 ct 2950 -170 2944 -173 2935 -173 ct 2926 -173 2917 -170 2908 -165 ct +2900 -159 2891 -151 2884 -139 ct 2884 -139 2884 -139 2884 0 ct 2884 0 2884 0 2823 0 ct +p ef +3170 0 m 3170 -183 l 3088 -183 l 3088 -224 l 3231 -224 l 3231 0 l +3170 0 l p +3170 -265 m 3170 -326 l 3231 -326 l 3231 -265 l 3170 -265 l p ef +3331 0 m 3331 0 3331 0 3331 -224 ct 3331 -224 3331 -224 3392 -224 ct 3392 -224 3392 -224 3391 -202 ct +3391 -202 3391 -202 3390 -181 ct 3390 -181 3390 -181 3392 -181 ct 3399 -197 3408 -209 3420 -217 ct +3432 -225 3446 -229 3464 -229 ct 3486 -229 3502 -223 3513 -210 ct 3524 -197 3530 -178 3530 -153 ct +3530 -153 3530 -153 3530 0 ct 3530 0 3530 0 3469 0 ct 3469 0 3469 0 3469 -139 ct +3469 -150 3467 -159 3463 -165 ct 3458 -170 3452 -173 3443 -173 ct 3434 -173 3425 -170 3416 -165 ct +3408 -159 3399 -151 3392 -139 ct 3392 -139 3392 -139 3392 0 ct 3392 0 3392 0 3331 0 ct +p ef +3596 69 m 3596 69 3596 69 3602 25 ct 3634 38 3660 44 3680 44 ct 3698 44 3711 39 3719 30 ct +3728 21 3732 7 3732 -11 ct 3732 -11 3732 -11 3733 -53 ct 3733 -53 3733 -53 3731 -53 ct +3723 -35 3713 -22 3702 -13 ct 3690 -4 3676 0 3660 0 ct 3634 0 3613 -10 3598 -31 ct +3582 -51 3574 -78 3574 -111 ct 3574 -147 3583 -175 3600 -197 ct 3618 -218 3641 -229 3670 -229 ct +3682 -229 3692 -227 3702 -223 ct 3712 -218 3721 -212 3730 -204 ct 3730 -204 3730 -204 3735 -204 ct +3735 -204 3735 -204 3740 -224 ct 3740 -224 3740 -224 3791 -224 ct 3791 -224 3791 -224 3791 -27 ct +3791 10 3782 38 3764 58 ct 3747 77 3721 87 3688 87 ct 3662 87 3631 81 3596 69 ct +p +3730 -95 m 3730 -95 3730 -95 3730 -163 ct 3722 -169 3714 -174 3706 -178 ct +3699 -181 3692 -183 3685 -183 ct 3670 -183 3659 -177 3651 -166 ct 3644 -155 3640 -138 3640 -116 ct +3640 -97 3643 -83 3650 -73 ct 3657 -64 3666 -59 3680 -59 ct 3689 -59 3698 -62 3707 -68 ct +3715 -74 3723 -83 3730 -95 ct p ef +pom +gr +gs +pum +1942 17976 t +pom +gr +gs +pum +2450 17976 t +43 -326 m 43 -326 43 -326 43 -295 ct 43 -295 43 -295 59 -295 ct 80 -295 94 -293 102 -287 ct +111 -282 115 -274 115 -261 ct 115 -257 114 -251 113 -242 ct 113 -242 113 -242 109 -214 ct +108 -204 107 -196 107 -190 ct 107 -175 110 -163 117 -153 ct 124 -144 134 -137 148 -132 ct +134 -128 124 -121 117 -111 ct 110 -102 107 -90 107 -75 ct 107 -68 108 -61 109 -51 ct +109 -51 109 -51 113 -23 ct 114 -14 115 -8 115 -4 ct 115 9 111 17 102 22 ct 94 27 80 30 59 30 ct +59 30 59 30 43 30 ct 43 30 43 30 43 61 ct 43 61 43 61 66 61 ct 95 61 117 56 131 46 ct +146 36 153 21 153 2 ct 153 -7 152 -16 150 -26 ct 150 -26 150 -26 143 -63 ct 142 -68 142 -74 142 -79 ct +142 -92 146 -101 154 -108 ct 161 -114 173 -117 188 -117 ct 188 -117 188 -117 207 -117 ct +207 -117 207 -117 207 -148 ct 207 -148 207 -148 188 -148 ct 173 -148 161 -151 154 -157 ct +146 -164 142 -173 142 -186 ct 142 -191 142 -197 143 -202 ct 143 -202 143 -202 150 -239 ct +152 -249 153 -258 153 -267 ct 153 -286 146 -301 131 -311 ct 117 -321 95 -326 66 -326 ct +66 -326 66 -326 43 -326 ct p ef +pom +gr +gs +pum +1942 18467 t +43 -326 m 43 -326 43 -326 43 -295 ct 43 -295 43 -295 59 -295 ct 80 -295 94 -293 102 -287 ct +111 -282 115 -274 115 -261 ct 115 -257 114 -251 113 -242 ct 113 -242 113 -242 109 -214 ct +108 -204 107 -196 107 -190 ct 107 -175 110 -163 117 -153 ct 124 -144 134 -137 148 -132 ct +134 -128 124 -121 117 -111 ct 110 -102 107 -90 107 -75 ct 107 -68 108 -61 109 -51 ct +109 -51 109 -51 113 -23 ct 114 -14 115 -8 115 -4 ct 115 9 111 17 102 22 ct 94 27 80 30 59 30 ct +59 30 59 30 43 30 ct 43 30 43 30 43 61 ct 43 61 43 61 66 61 ct 95 61 117 56 131 46 ct +146 36 153 21 153 2 ct 153 -7 152 -16 150 -26 ct 150 -26 150 -26 143 -63 ct 142 -68 142 -74 142 -79 ct +142 -92 146 -101 154 -108 ct 161 -114 173 -117 188 -117 ct 188 -117 188 -117 207 -117 ct +207 -117 207 -117 207 -148 ct 207 -148 207 -148 188 -148 ct 173 -148 161 -151 154 -157 ct +146 -164 142 -173 142 -186 ct 142 -191 142 -197 143 -202 ct 143 -202 143 -202 150 -239 ct +152 -249 153 -258 153 -267 ct 153 -286 146 -301 131 -311 ct 117 -321 95 -326 66 -326 ct +66 -326 66 -326 43 -326 ct p ef +351 66 m 351 66 351 66 351 46 ct 358 45 364 41 368 33 ct 373 25 375 14 376 0 ct +376 0 376 0 351 0 ct 351 0 351 0 351 -61 ct 351 -61 351 -61 412 -61 ct 412 -61 412 -61 412 -24 ct +412 5 407 27 397 42 ct 387 57 371 65 351 66 ct p +351 -163 m 351 -224 l 412 -224 l 412 -163 l 351 -163 l p ef +pom +gr +gr +0.503 0.503 0.503 c 4064 19780 m 3002 19780 l 3002 19105 l 5126 19105 l +5126 19780 l 4064 19780 l p ef +4064 19780 m 3002 19780 l 3002 19105 l 5126 19105 l 5126 19780 l 4064 19780 l +pc +0.753 0.753 0.753 c 3964 19680 m 2902 19680 l 2902 19005 l 5026 19005 l +5026 19680 l 3964 19680 l p ef +0.003 0.003 0.003 c 3964 19680 m 2902 19680 l 2902 19005 l 5026 19005 l +5026 19680 l 3964 19680 l pc +gs +gs +pum +3133 19493 t +1.000 1.000 1.000 c 248 -242 m 158 -242 l 158 0 l 99 0 l 99 -242 l +9 -242 l 9 -291 l 248 -291 l 248 -242 l p ef +472 0 m 472 0 472 0 413 0 ct 409 -9 407 -17 407 -25 ct 388 -5 365 5 338 5 ct 318 5 302 -1 291 -13 ct +280 -24 274 -40 274 -59 ct 274 -73 278 -85 285 -95 ct 293 -106 304 -114 319 -120 ct +334 -127 351 -131 372 -132 ct 372 -132 372 -132 407 -135 ct 407 -135 407 -135 407 -139 ct +407 -163 393 -175 366 -175 ct 358 -175 347 -173 333 -170 ct 319 -166 307 -162 297 -157 ct +297 -157 297 -157 283 -198 ct 296 -204 312 -210 329 -214 ct 347 -218 362 -220 376 -220 ct +405 -220 427 -213 442 -199 ct 457 -185 464 -165 464 -138 ct 464 -138 464 -138 464 -51 ct +464 -31 467 -14 472 0 ct p +407 -66 m 407 -66 407 -66 407 -101 ct 383 -99 368 -97 362 -96 ct 357 -95 351 -93 344 -89 ct +338 -86 334 -82 331 -77 ct 328 -72 326 -67 326 -61 ct 326 -54 328 -49 333 -45 ct +337 -40 343 -38 350 -38 ct 371 -38 390 -47 407 -66 ct p ef +662 -211 m 662 -211 662 -211 652 -159 ct 646 -163 640 -165 633 -165 ct 626 -165 619 -163 613 -158 ct +606 -153 599 -145 592 -134 ct 585 -123 582 -116 582 -114 ct 582 -114 582 -114 582 0 ct +582 0 582 0 525 0 ct 525 0 525 0 525 -215 ct 525 -215 525 -215 582 -215 ct 582 -215 582 -215 582 -172 ct +590 -190 598 -202 606 -209 ct 614 -216 624 -220 635 -220 ct 646 -220 655 -217 662 -211 ct +p ef +888 -9 m 888 23 878 47 858 64 ct 839 81 811 89 775 89 ct 743 89 713 81 687 65 ct +687 65 687 65 703 22 ct 727 35 750 42 774 42 ct 792 42 806 38 816 29 ct 826 21 831 8 831 -7 ct +831 -7 831 -7 831 -22 ct 814 -4 793 5 767 5 ct 741 5 719 -5 702 -25 ct 685 -45 676 -71 676 -105 ct +676 -141 685 -169 702 -189 ct 719 -210 742 -220 770 -220 ct 781 -220 793 -218 804 -213 ct +815 -209 824 -203 831 -195 ct 831 -195 831 -195 831 -219 ct 831 -219 831 -219 888 -219 ct +888 -219 888 -219 888 -9 ct p +831 -71 m 831 -71 831 -71 831 -146 ct 818 -163 802 -171 782 -171 ct 768 -171 757 -165 748 -154 ct +739 -142 735 -126 735 -106 ct 735 -87 739 -71 748 -60 ct 757 -50 768 -44 782 -44 ct +801 -44 817 -53 831 -71 ct p ef +1140 -20 m 1115 -3 1086 5 1054 5 ct 1018 5 989 -5 967 -26 ct 946 -46 935 -74 935 -108 ct +935 -142 945 -169 964 -189 ct 983 -210 1009 -220 1041 -220 ct 1070 -220 1094 -210 1112 -191 ct +1131 -171 1140 -144 1140 -109 ct 1140 -109 1140 -109 1140 -95 ct 1140 -95 1140 -95 994 -95 ct +996 -80 1003 -68 1014 -59 ct 1025 -49 1039 -44 1055 -44 ct 1080 -44 1105 -51 1130 -65 ct +1130 -65 1130 -65 1140 -20 ct p +1085 -133 m 1083 -147 1078 -158 1070 -167 ct 1062 -175 1053 -179 1041 -179 ct +1029 -179 1018 -175 1010 -167 ct 1001 -158 996 -147 994 -133 ct 994 -133 994 -133 1085 -133 ct +p ef +1301 -5 m 1289 2 1276 5 1262 5 ct 1239 5 1221 -1 1209 -13 ct 1197 -25 1191 -43 1191 -66 ct +1191 -66 1191 -66 1191 -171 ct 1191 -171 1191 -171 1161 -171 ct 1161 -171 1161 -171 1161 -215 ct +1161 -215 1161 -215 1191 -215 ct 1191 -215 1191 -215 1191 -282 ct 1191 -282 1191 -282 1248 -282 ct +1248 -282 1248 -282 1248 -215 ct 1248 -215 1248 -215 1290 -215 ct 1290 -215 1290 -215 1290 -171 ct +1290 -171 1290 -171 1248 -171 ct 1248 -171 1248 -171 1248 -75 ct 1248 -65 1250 -58 1254 -52 ct +1258 -47 1263 -44 1269 -44 ct 1277 -44 1284 -46 1292 -49 ct 1292 -49 1292 -49 1301 -5 ct +p ef +1353 -66 m 1363 -66 1372 -63 1379 -56 ct 1386 -49 1389 -41 1389 -31 ct 1389 -21 1386 -12 1379 -5 ct +1372 2 1363 5 1353 5 ct 1343 5 1335 2 1328 -5 ct 1321 -12 1318 -20 1318 -31 ct +1318 -41 1321 -49 1328 -56 ct 1335 -63 1343 -66 1353 -66 ct p ef +1643 0 m 1643 0 1643 0 1586 0 ct 1586 0 1586 0 1586 -125 ct 1586 -156 1575 -171 1553 -171 ct +1534 -171 1516 -160 1501 -139 ct 1501 -139 1501 -139 1501 0 ct 1501 0 1501 0 1444 0 ct +1444 0 1444 0 1444 -307 ct 1444 -307 1444 -307 1501 -307 ct 1501 -307 1501 -307 1501 -188 ct +1519 -209 1542 -220 1570 -220 ct 1592 -220 1610 -213 1623 -200 ct 1636 -187 1643 -168 1643 -144 ct +1643 -144 1643 -144 1643 0 ct p ef +pom +gr +gr +1.000 0.003 0.003 c 9154 14360 m 9408 15025 l 8959 15044 l 9154 14360 l +p ef +11494 19339 m 11267 19308 l 11274 19258 l 11280 19209 l 11508 19239 l +11501 19289 l 11494 19339 l p ef +11274 19258 m 11267 19308 l 11265 19307 l 11274 19258 l p ef +11265 19307 m 11057 19271 l 11066 19222 l 11074 19173 l 11282 19209 l +11274 19258 l 11265 19307 l p ef +11066 19222 m 11057 19271 l 11054 19271 l 11066 19222 l p ef +11054 19271 m 10955 19247 l 10967 19199 l 10978 19150 l 11077 19173 l +11066 19222 l 11054 19271 l p ef +10967 19199 m 10955 19247 l 10953 19246 l 10967 19199 l p ef +10953 19246 m 10855 19217 l 10870 19169 l 10884 19122 l 10981 19151 l +10967 19199 l 10953 19246 l p ef +10870 19169 m 10855 19217 l 10852 19216 l 10870 19169 l p ef +10852 19216 m 10756 19180 l 10773 19133 l 10791 19087 l 10887 19123 l +10870 19169 l 10852 19216 l p ef +10773 19133 m 10756 19180 l 10752 19179 l 10773 19133 l p ef +10752 19179 m 10656 19134 l 10677 19089 l 10698 19044 l 10794 19088 l +10773 19133 l 10752 19179 l p ef +10677 19089 m 10656 19134 l 10653 19133 l 10677 19089 l p ef +10653 19133 m 10555 19079 l 10579 19035 l 10603 18991 l 10701 19045 l +10677 19089 l 10653 19133 l p ef +10579 19035 m 10555 19079 l 10552 19077 l 10579 19035 l p ef +10552 19077 m 10452 19011 l 10479 18970 l 10506 18928 l 10606 18993 l +10579 19035 l 10552 19077 l p ef +10479 18970 m 10452 19011 l 10449 19010 l 10479 18970 l p ef +10449 19010 m 10345 18932 l 10375 18892 l 10406 18852 l 10509 18930 l +10479 18970 l 10449 19010 l p ef +10375 18892 m 10345 18932 l 10343 18930 l 10375 18892 l p ef +10343 18930 m 10235 18838 l 10268 18800 l 10300 18762 l 10408 18854 l +10375 18892 l 10343 18930 l p ef +10268 18800 m 10235 18838 l 10232 18835 l 10268 18800 l p ef +10232 18835 m 10000 18604 l 10035 18569 l 10070 18533 l 10303 18764 l +10268 18800 l 10232 18835 l p ef +10035 18569 m 10000 18604 l 9997 18601 l 10035 18569 l p ef +9997 18601 m 9735 18298 l 9773 18265 l 9811 18232 l 10073 18536 l +10035 18569 l 9997 18601 l p ef +9773 18265 m 9735 18298 l 9733 18295 l 9773 18265 l p ef +9733 18295 m 9632 18159 l 9673 18129 l 9713 18099 l 9813 18235 l 9773 18265 l +9733 18295 l p ef +9673 18129 m 9632 18159 l 9630 18155 l 9673 18129 l p ef +9630 18155 m 9543 18013 l 9586 17987 l 9628 17961 l 9715 18103 l 9673 18129 l +9630 18155 l p ef +9586 17987 m 9543 18013 l 9541 18010 l 9586 17987 l p ef +9541 18010 m 9467 17864 l 9511 17841 l 9556 17818 l 9630 17965 l 9586 17987 l +9541 18010 l p ef +9511 17841 m 9467 17864 l 9465 17861 l 9511 17841 l p ef +9465 17861 m 9403 17712 l 9449 17692 l 9495 17673 l 9557 17822 l 9511 17841 l +9465 17861 l p ef +9449 17692 m 9403 17712 l 9401 17709 l 9449 17692 l p ef +9401 17709 m 9349 17559 l 9397 17543 l 9444 17526 l 9496 17676 l 9449 17692 l +9401 17709 l p ef +9397 17543 m 9349 17559 l 9349 17556 l 9397 17543 l p ef +9349 17556 m 9306 17407 l 9354 17393 l 9402 17380 l 9445 17529 l 9397 17543 l +9349 17556 l p ef +9354 17393 m 9306 17407 l 9305 17404 l 9354 17393 l p ef +9305 17404 m 9245 17114 l 9294 17104 l 9343 17094 l 9403 17383 l 9354 17393 l +9305 17404 l p ef +9294 17104 m 9245 17114 l 9245 17110 l 9294 17104 l p ef +9245 17110 m 9211 16843 l 9261 16837 l 9310 16830 l 9344 17098 l 9294 17104 l +9245 17110 l p ef +9261 16837 m 9211 16843 l 9211 16840 l 9261 16837 l p ef +9211 16840 m 9196 16608 l 9246 16605 l 9295 16602 l 9310 16833 l 9261 16837 l +9211 16840 l p ef +9246 16605 m 9196 16608 l 9196 16606 l 9246 16605 l p ef +9196 16606 m 9189 16303 l 9239 16302 l 9289 16301 l 9296 16604 l 9246 16605 l +9196 16606 l p ef +9239 16302 m 9289 16300 l 9289 16301 l 9239 16302 l p ef +9189 16304 m 9128 14902 l 9178 14899 l 9228 14897 l 9289 16300 l 9239 16302 l +9189 16304 l p ef +gs +gs +pum +11811 19446 t +88 -465 m 101 -465 112 -460 122 -451 ct 132 -441 137 -429 137 -416 ct 137 -403 132 -392 122 -382 ct +113 -373 101 -368 88 -368 ct 74 -368 63 -373 53 -382 ct 44 -392 39 -403 39 -416 ct +39 -430 44 -441 53 -451 ct 63 -460 74 -465 88 -465 ct p +131 0 m 45 0 l 45 -323 l 131 -323 l 131 0 l p ef +523 0 m 523 0 523 0 437 0 ct 437 0 437 0 437 -189 ct 437 -235 421 -258 388 -258 ct +358 -258 332 -242 309 -211 ct 309 -211 309 -211 309 0 ct 309 0 309 0 223 0 ct 223 0 223 0 223 -323 ct +223 -323 223 -323 309 -323 ct 309 -323 309 -323 309 -283 ct 336 -315 371 -331 413 -331 ct +447 -331 473 -321 493 -301 ct 513 -281 523 -253 523 -217 ct 523 -217 523 -217 523 0 ct +p ef +899 -29 m 863 -4 821 8 773 8 ct 717 8 672 -7 640 -38 ct 607 -68 591 -110 591 -162 ct +591 -214 607 -255 640 -285 ct 672 -316 716 -331 771 -331 ct 815 -331 856 -321 895 -301 ct +895 -301 895 -301 879 -232 ct 843 -250 807 -259 772 -259 ct 747 -259 726 -251 708 -234 ct +689 -218 680 -194 680 -162 ct 680 -131 689 -107 708 -90 ct 726 -73 748 -65 773 -65 ct +812 -65 849 -76 884 -97 ct 884 -97 884 -97 899 -29 ct p ef +1050 0 m 964 0 l 964 -461 l 1050 -461 l 1050 0 l p ef +1439 0 m 1439 0 1439 0 1353 0 ct 1353 0 1353 0 1353 -40 ct 1326 -8 1292 8 1249 8 ct +1215 8 1189 -2 1169 -22 ct 1149 -42 1139 -70 1139 -106 ct 1139 -106 1139 -106 1139 -323 ct +1139 -323 1139 -323 1225 -323 ct 1225 -323 1225 -323 1225 -133 ct 1225 -88 1241 -65 1274 -65 ct +1304 -65 1330 -81 1353 -112 ct 1353 -112 1353 -112 1353 -323 ct 1353 -323 1353 -323 1439 -323 ct +1439 -323 1439 -323 1439 0 ct p ef +1830 0 m 1830 0 1830 0 1744 0 ct 1744 0 1744 0 1744 -31 ct 1718 -5 1686 8 1647 8 ct +1607 8 1574 -7 1549 -37 ct 1523 -66 1510 -106 1510 -155 ct 1510 -209 1523 -252 1549 -284 ct +1574 -315 1607 -331 1647 -331 ct 1688 -331 1720 -318 1744 -293 ct 1744 -293 1744 -293 1744 -461 ct +1744 -461 1744 -461 1830 -461 ct 1830 -461 1830 -461 1830 0 ct p +1744 -104 m 1744 -104 1744 -104 1744 -221 ct 1724 -246 1700 -258 1670 -258 ct +1649 -258 1632 -249 1619 -232 ct 1606 -214 1599 -190 1599 -160 ct 1599 -130 1606 -107 1619 -90 ct +1632 -73 1649 -65 1670 -65 ct 1698 -65 1723 -78 1744 -104 ct p ef +2207 -29 m 2170 -4 2127 8 2078 8 ct 2023 8 1980 -7 1947 -38 ct 1915 -69 1899 -111 1899 -162 ct +1899 -213 1913 -254 1942 -285 ct 1971 -316 2009 -331 2057 -331 ct 2101 -331 2137 -316 2164 -287 ct +2192 -257 2206 -216 2206 -163 ct 2206 -163 2206 -163 2206 -142 ct 2206 -142 2206 -142 1988 -142 ct +1991 -120 2001 -102 2018 -87 ct 2035 -72 2056 -65 2079 -65 ct 2117 -65 2154 -76 2192 -97 ct +2192 -97 2192 -97 2207 -29 ct p +2124 -200 m 2121 -221 2114 -238 2102 -251 ct 2091 -264 2076 -270 2059 -270 ct +2041 -270 2025 -264 2012 -251 ct 1999 -238 1992 -221 1989 -200 ct 1989 -200 1989 -200 2124 -200 ct +p ef +2737 -29 m 2701 -4 2659 8 2611 8 ct 2555 8 2510 -7 2478 -38 ct 2445 -68 2429 -110 2429 -162 ct +2429 -214 2445 -255 2478 -285 ct 2510 -316 2554 -331 2609 -331 ct 2653 -331 2694 -321 2733 -301 ct +2733 -301 2733 -301 2717 -232 ct 2681 -250 2645 -259 2610 -259 ct 2585 -259 2564 -251 2546 -234 ct +2527 -218 2518 -194 2518 -162 ct 2518 -131 2527 -107 2546 -90 ct 2564 -73 2586 -65 2611 -65 ct +2650 -65 2687 -76 2722 -97 ct 2722 -97 2722 -97 2737 -29 ct p ef +3107 -323 m 3107 -323 3107 -323 2980 6 ct 2964 47 2944 78 2919 100 ct 2895 121 2862 132 2820 132 ct +2799 132 2776 128 2753 121 ct 2753 121 2753 121 2768 52 ct 2785 57 2800 60 2812 60 ct +2831 60 2846 56 2857 47 ct 2869 39 2879 24 2887 2 ct 2887 2 2887 2 2762 -323 ct +2762 -323 2762 -323 2857 -323 ct 2857 -323 2857 -323 2934 -91 ct 2934 -91 2934 -91 3017 -323 ct +3017 -323 3017 -323 3107 -323 ct p ef +3435 -29 m 3399 -4 3357 8 3309 8 ct 3253 8 3208 -7 3176 -38 ct 3143 -68 3127 -110 3127 -162 ct +3127 -214 3143 -255 3176 -285 ct 3208 -316 3252 -331 3307 -331 ct 3351 -331 3392 -321 3431 -301 ct +3431 -301 3431 -301 3415 -232 ct 3379 -250 3343 -259 3308 -259 ct 3283 -259 3262 -251 3244 -234 ct +3225 -218 3216 -194 3216 -162 ct 3216 -131 3225 -107 3244 -90 ct 3262 -73 3284 -65 3309 -65 ct +3348 -65 3385 -76 3420 -97 ct 3420 -97 3420 -97 3435 -29 ct p ef +3585 0 m 3499 0 l 3499 -461 l 3585 -461 l 3585 0 l p ef +3964 -29 m 3927 -4 3884 8 3835 8 ct 3780 8 3737 -7 3704 -38 ct 3672 -69 3656 -111 3656 -162 ct +3656 -213 3670 -254 3699 -285 ct 3728 -316 3766 -331 3814 -331 ct 3858 -331 3894 -316 3921 -287 ct +3949 -257 3963 -216 3963 -163 ct 3963 -163 3963 -163 3963 -142 ct 3963 -142 3963 -142 3745 -142 ct +3748 -120 3758 -102 3775 -87 ct 3792 -72 3813 -65 3836 -65 ct 3874 -65 3911 -76 3949 -97 ct +3949 -97 3949 -97 3964 -29 ct p +3881 -200 m 3878 -221 3871 -238 3859 -251 ct 3848 -264 3833 -270 3816 -270 ct +3798 -270 3782 -264 3769 -251 ct 3756 -238 3749 -221 3746 -200 ct 3746 -200 3746 -200 3881 -200 ct +p ef +4136 -304 m 4114 -131 l 4064 -131 l 4041 -304 l 4041 -438 l 4136 -438 l +4136 -304 l p +4088 -98 m 4103 -98 4115 -93 4126 -83 ct 4136 -73 4141 -60 4141 -45 ct 4141 -30 4136 -17 4126 -7 ct +4115 3 4103 8 4088 8 ct 4073 8 4060 3 4050 -7 ct 4040 -17 4035 -30 4035 -45 ct +4035 -60 4040 -73 4050 -83 ct 4060 -93 4073 -98 4088 -98 ct p ef +pom +gr +gr +1.000 1.000 1.000 c 3668 10861 m 7276 10861 l 7276 12568 l 3668 12568 l +3668 10861 l p ef +1.000 0.402 0.203 c 3668 10861 m 7276 10861 l 7276 12568 l 3668 12568 l +3668 10861 l pc +1.000 1.000 1.000 c 2390 13016 m 2538 11900 l 2390 13016 l p ef +1.000 0.402 0.203 c 2390 13016 m 2538 11900 l ps +1.000 1.000 1.000 c 2538 11900 m 3419 11415 l 2538 11900 l p ef +1.000 0.402 0.203 c 2538 11900 m 3419 11415 l ps +gs +gs +pum +3953 11300 t +0.003 0.003 0.003 c 172 -7 m 172 17 165 35 150 48 ct 135 61 114 67 86 67 ct 62 67 40 61 20 49 ct +20 49 20 49 32 17 ct 50 27 68 32 86 32 ct 100 32 110 29 118 22 ct 125 16 129 7 129 -5 ct +129 -5 129 -5 129 -16 ct 116 -3 100 4 81 4 ct 61 4 44 -3 31 -18 ct 18 -33 12 -54 12 -79 ct +12 -106 19 -127 32 -143 ct 45 -158 62 -166 83 -166 ct 92 -166 100 -164 108 -161 ct +117 -157 124 -153 129 -147 ct 129 -147 129 -147 129 -165 ct 129 -165 129 -165 172 -165 ct +172 -165 172 -165 172 -7 ct p +129 -53 m 129 -53 129 -53 129 -110 ct 119 -123 107 -129 92 -129 ct 82 -129 74 -125 67 -116 ct +60 -107 57 -95 57 -80 ct 57 -65 60 -54 67 -45 ct 73 -37 82 -33 92 -33 ct 107 -33 119 -40 129 -53 ct +p ef +361 -15 m 342 -2 321 4 296 4 ct 269 4 247 -4 231 -19 ct 215 -35 207 -56 207 -81 ct +207 -107 214 -127 229 -143 ct 243 -158 262 -166 286 -166 ct 308 -166 326 -159 340 -144 ct +354 -129 361 -108 361 -82 ct 361 -82 361 -82 361 -71 ct 361 -71 361 -71 252 -71 ct +254 -60 259 -51 267 -44 ct 276 -37 286 -33 298 -33 ct 316 -33 335 -38 354 -49 ct +354 -49 354 -49 361 -15 ct p +320 -100 m 319 -111 315 -119 309 -126 ct 303 -132 296 -135 287 -135 ct 278 -135 270 -132 264 -126 ct +257 -119 253 -111 252 -100 ct 252 -100 252 -100 320 -100 ct p ef +545 0 m 545 0 545 0 502 0 ct 502 0 502 0 502 -95 ct 502 -118 494 -129 478 -129 ct +463 -129 450 -121 439 -105 ct 439 -105 439 -105 439 0 ct 439 0 439 0 396 0 ct 396 0 396 0 396 -162 ct +396 -162 396 -162 439 -162 ct 439 -162 439 -162 439 -142 ct 452 -158 470 -166 491 -166 ct +507 -166 520 -161 530 -151 ct 540 -141 545 -127 545 -109 ct 545 -109 545 -109 545 0 ct +p ef +733 -15 m 714 -2 693 4 668 4 ct 641 4 619 -4 603 -19 ct 587 -35 579 -56 579 -81 ct +579 -107 586 -127 601 -143 ct 615 -158 634 -166 658 -166 ct 680 -166 698 -159 712 -144 ct +726 -129 733 -108 733 -82 ct 733 -82 733 -82 733 -71 ct 733 -71 733 -71 624 -71 ct +626 -60 631 -51 639 -44 ct 648 -37 658 -33 670 -33 ct 688 -33 707 -38 726 -49 ct +726 -49 726 -49 733 -15 ct p +692 -100 m 691 -111 687 -119 681 -126 ct 675 -132 668 -135 659 -135 ct 650 -135 642 -132 636 -126 ct +629 -119 625 -111 624 -100 ct 624 -100 624 -100 692 -100 ct p ef +871 -159 m 871 -159 871 -159 864 -120 ct 859 -123 855 -125 850 -125 ct 844 -125 839 -123 834 -120 ct +829 -116 824 -110 819 -102 ct 814 -93 811 -88 811 -87 ct 811 -87 811 -87 811 0 ct +811 0 811 0 768 0 ct 768 0 768 0 768 -162 ct 768 -162 768 -162 811 -162 ct 811 -162 811 -162 811 -130 ct +817 -143 823 -153 829 -158 ct 835 -163 842 -166 851 -166 ct 859 -166 866 -164 871 -159 ct +p ef +1029 0 m 1029 0 1029 0 984 0 ct 981 -7 980 -13 980 -18 ct 966 -3 948 4 928 4 ct +913 4 901 0 893 -9 ct 884 -18 880 -29 880 -44 ct 880 -54 883 -64 888 -71 ct 894 -79 903 -85 914 -90 ct +925 -95 938 -98 954 -99 ct 954 -99 954 -99 980 -101 ct 980 -101 980 -101 980 -104 ct +980 -123 970 -132 950 -132 ct 943 -132 935 -131 925 -128 ct 915 -125 905 -122 898 -118 ct +898 -118 898 -118 887 -149 ct 897 -154 909 -158 922 -161 ct 935 -164 947 -166 957 -166 ct +979 -166 995 -161 1006 -150 ct 1017 -140 1023 -124 1023 -104 ct 1023 -104 1023 -104 1023 -39 ct +1023 -23 1025 -10 1029 0 ct p +980 -49 m 980 -49 980 -49 980 -75 ct 962 -73 951 -72 946 -71 ct 942 -70 938 -69 933 -66 ct +928 -64 925 -61 922 -57 ct 920 -54 919 -49 919 -45 ct 919 -40 921 -36 924 -33 ct +927 -30 932 -28 937 -28 ct 953 -28 967 -35 980 -49 ct p ef +1155 -3 m 1146 2 1136 4 1125 4 ct 1108 4 1095 -1 1086 -10 ct 1077 -19 1072 -32 1072 -50 ct +1072 -50 1072 -50 1072 -129 ct 1072 -129 1072 -129 1050 -129 ct 1050 -129 1050 -129 1050 -162 ct +1050 -162 1050 -162 1072 -162 ct 1072 -162 1072 -162 1072 -212 ct 1072 -212 1072 -212 1115 -212 ct +1115 -212 1115 -212 1115 -162 ct 1115 -162 1115 -162 1146 -162 ct 1146 -162 1146 -162 1146 -129 ct +1146 -129 1146 -129 1115 -129 ct 1115 -129 1115 -129 1115 -57 ct 1115 -49 1116 -43 1119 -39 ct +1122 -35 1126 -33 1131 -33 ct 1137 -33 1143 -34 1149 -36 ct 1149 -36 1149 -36 1155 -3 ct +p ef +1317 -15 m 1298 -2 1277 4 1252 4 ct 1225 4 1203 -4 1187 -19 ct 1171 -35 1163 -56 1163 -81 ct +1163 -107 1170 -127 1185 -143 ct 1199 -158 1218 -166 1242 -166 ct 1264 -166 1282 -159 1296 -144 ct +1310 -129 1317 -108 1317 -82 ct 1317 -82 1317 -82 1317 -71 ct 1317 -71 1317 -71 1208 -71 ct +1210 -60 1215 -51 1223 -44 ct 1232 -37 1242 -33 1254 -33 ct 1272 -33 1291 -38 1310 -49 ct +1310 -49 1310 -49 1317 -15 ct p +1276 -100 m 1275 -111 1271 -119 1265 -126 ct 1259 -132 1252 -135 1243 -135 ct +1234 -135 1226 -132 1220 -126 ct 1213 -119 1209 -111 1208 -100 ct 1208 -100 1208 -100 1276 -100 ct +p ef +1501 0 m 1501 0 1501 0 1458 0 ct 1458 0 1458 0 1458 -16 ct 1445 -3 1429 4 1410 4 ct +1390 4 1373 -3 1360 -18 ct 1347 -33 1341 -53 1341 -78 ct 1341 -105 1347 -127 1360 -142 ct +1373 -158 1390 -166 1410 -166 ct 1430 -166 1446 -160 1458 -147 ct 1458 -147 1458 -147 1458 -231 ct +1458 -231 1458 -231 1501 -231 ct 1501 -231 1501 -231 1501 0 ct p +1458 -53 m 1458 -53 1458 -53 1458 -111 ct 1448 -123 1436 -129 1421 -129 ct +1411 -129 1402 -125 1396 -116 ct 1389 -107 1386 -95 1386 -80 ct 1386 -65 1389 -54 1396 -45 ct +1402 -37 1411 -33 1421 -33 ct 1435 -33 1447 -40 1458 -53 ct p ef +1656 -233 m 1663 -233 1669 -231 1674 -226 ct 1679 -221 1681 -215 1681 -208 ct +1681 -202 1679 -196 1674 -191 ct 1669 -186 1663 -184 1656 -184 ct 1650 -184 1644 -186 1639 -191 ct +1634 -196 1632 -202 1632 -208 ct 1632 -215 1634 -221 1639 -226 ct 1644 -231 1650 -233 1656 -233 ct +p +1678 0 m 1635 0 l 1635 -162 l 1678 -162 l 1678 0 l p ef +1874 0 m 1874 0 1874 0 1831 0 ct 1831 0 1831 0 1831 -95 ct 1831 -118 1823 -129 1807 -129 ct +1792 -129 1779 -121 1768 -105 ct 1768 -105 1768 -105 1768 0 ct 1768 0 1768 0 1725 0 ct +1725 0 1725 0 1725 -162 ct 1725 -162 1725 -162 1768 -162 ct 1768 -162 1768 -162 1768 -142 ct +1781 -158 1799 -166 1820 -166 ct 1836 -166 1849 -161 1859 -151 ct 1869 -141 1874 -127 1874 -109 ct +1874 -109 1874 -109 1874 0 ct p ef +2064 -15 m 2046 -2 2025 4 2000 4 ct 1972 4 1950 -4 1934 -19 ct 1917 -34 1909 -55 1909 -81 ct +1909 -107 1917 -128 1934 -143 ct 1950 -158 1972 -166 2000 -166 ct 2022 -166 2042 -160 2062 -149 ct +2062 -149 2062 -149 2054 -115 ct 2036 -124 2018 -129 2000 -129 ct 1988 -129 1977 -125 1968 -117 ct +1959 -108 1954 -97 1954 -81 ct 1954 -66 1959 -54 1968 -45 ct 1977 -37 1988 -33 2000 -33 ct +2020 -33 2038 -38 2056 -49 ct 2056 -49 2056 -49 2064 -15 ct p ef +2139 0 m 2096 0 l 2096 -231 l 2139 -231 l 2139 0 l p ef +2334 0 m 2334 0 2334 0 2291 0 ct 2291 0 2291 0 2291 -20 ct 2278 -4 2261 4 2240 4 ct +2223 4 2210 -1 2200 -11 ct 2190 -21 2185 -35 2185 -53 ct 2185 -53 2185 -53 2185 -162 ct +2185 -162 2185 -162 2228 -162 ct 2228 -162 2228 -162 2228 -67 ct 2228 -44 2236 -33 2252 -33 ct +2267 -33 2280 -41 2291 -56 ct 2291 -56 2291 -56 2291 -162 ct 2291 -162 2291 -162 2334 -162 ct +2334 -162 2334 -162 2334 0 ct p ef +2530 0 m 2530 0 2530 0 2487 0 ct 2487 0 2487 0 2487 -16 ct 2474 -3 2458 4 2439 4 ct +2419 4 2402 -3 2389 -18 ct 2376 -33 2370 -53 2370 -78 ct 2370 -105 2376 -127 2389 -142 ct +2402 -158 2419 -166 2439 -166 ct 2459 -166 2475 -160 2487 -147 ct 2487 -147 2487 -147 2487 -231 ct +2487 -231 2487 -231 2530 -231 ct 2530 -231 2530 -231 2530 0 ct p +2487 -53 m 2487 -53 2487 -53 2487 -111 ct 2477 -123 2465 -129 2450 -129 ct +2440 -129 2431 -125 2425 -116 ct 2418 -107 2415 -95 2415 -80 ct 2415 -65 2418 -54 2425 -45 ct +2431 -37 2440 -33 2450 -33 ct 2464 -33 2476 -40 2487 -53 ct p ef +2719 -15 m 2700 -2 2679 4 2654 4 ct 2627 4 2605 -4 2589 -19 ct 2573 -35 2565 -56 2565 -81 ct +2565 -107 2572 -127 2587 -143 ct 2601 -158 2620 -166 2644 -166 ct 2666 -166 2684 -159 2698 -144 ct +2712 -129 2719 -108 2719 -82 ct 2719 -82 2719 -82 2719 -71 ct 2719 -71 2719 -71 2610 -71 ct +2612 -60 2617 -51 2625 -44 ct 2634 -37 2644 -33 2656 -33 ct 2674 -33 2693 -38 2712 -49 ct +2712 -49 2712 -49 2719 -15 ct p +2678 -100 m 2677 -111 2673 -119 2667 -126 ct 2661 -132 2654 -135 2645 -135 ct +2636 -135 2628 -132 2622 -126 ct 2615 -119 2611 -111 2610 -100 ct 2610 -100 2610 -100 2678 -100 ct +p ef +pom +gr +gs +pum +6684 11300 t +pom +gr +gs +pum +3953 11656 t +0.003 0.003 0.003 c 96 45 m 96 45 96 45 85 52 ct 63 28 47 5 37 -16 ct 27 -38 22 -63 22 -90 ct +22 -117 27 -141 37 -163 ct 47 -184 63 -207 85 -231 ct 85 -231 85 -231 96 -224 ct +80 -203 69 -182 61 -160 ct 54 -139 50 -115 50 -90 ct 50 -65 54 -41 61 -20 ct 68 2 80 23 96 45 ct +p ef +262 0 m 262 0 262 0 235 0 ct 235 0 235 0 235 -103 ct 235 -115 232 -125 226 -132 ct +220 -139 211 -142 201 -142 ct 185 -142 169 -133 154 -115 ct 154 -115 154 -115 154 0 ct +154 0 154 0 127 0 ct 127 0 127 0 127 -162 ct 127 -162 127 -162 154 -162 ct 154 -162 154 -162 154 -139 ct +171 -157 189 -166 208 -166 ct 225 -166 238 -161 248 -151 ct 257 -142 262 -128 262 -110 ct +262 -110 262 -110 262 0 ct p ef +448 -17 m 425 -3 403 4 381 4 ct 355 4 334 -4 319 -19 ct 304 -34 297 -55 297 -81 ct +297 -107 304 -127 318 -143 ct 331 -158 350 -166 373 -166 ct 394 -166 412 -159 425 -144 ct +438 -130 445 -111 445 -86 ct 445 -86 445 -86 445 -79 ct 445 -79 445 -79 325 -79 ct +326 -60 331 -45 341 -35 ct 350 -25 364 -20 381 -20 ct 401 -20 421 -26 441 -38 ct +441 -38 441 -38 448 -17 ct p +417 -100 m 416 -113 411 -123 403 -131 ct 394 -138 385 -142 373 -142 ct 361 -142 351 -138 342 -131 ct +334 -124 329 -113 326 -100 ct 326 -100 326 -100 417 -100 ct p ef +625 -17 m 602 -3 580 4 558 4 ct 532 4 511 -4 496 -19 ct 481 -34 474 -55 474 -81 ct +474 -107 481 -127 495 -143 ct 508 -158 527 -166 550 -166 ct 571 -166 589 -159 602 -144 ct +615 -130 622 -111 622 -86 ct 622 -86 622 -86 622 -79 ct 622 -79 622 -79 502 -79 ct +503 -60 508 -45 518 -35 ct 527 -25 541 -20 558 -20 ct 578 -20 598 -26 618 -38 ct +618 -38 618 -38 625 -17 ct p +594 -100 m 593 -113 588 -123 580 -131 ct 571 -138 562 -142 550 -142 ct 538 -142 528 -138 519 -131 ct +511 -124 506 -113 503 -100 ct 503 -100 503 -100 594 -100 ct p ef +794 0 m 794 0 794 0 767 0 ct 767 0 767 0 767 -20 ct 755 -4 740 4 720 4 ct 699 4 683 -4 670 -20 ct +658 -35 652 -57 652 -84 ct 652 -109 658 -128 671 -143 ct 683 -158 699 -166 718 -166 ct +740 -166 756 -158 767 -142 ct 767 -142 767 -142 767 -231 ct 767 -231 767 -231 794 -231 ct +794 -231 794 -231 794 0 ct p +767 -47 m 767 -47 767 -47 767 -116 ct 763 -123 758 -130 750 -135 ct 742 -140 734 -142 725 -142 ct +711 -142 700 -137 692 -126 ct 684 -116 680 -101 680 -82 ct 680 -62 684 -47 692 -36 ct +701 -25 712 -20 726 -20 ct 732 -20 738 -21 744 -24 ct 750 -27 755 -31 760 -36 ct +765 -41 767 -45 767 -47 ct p ef +981 -17 m 958 -3 936 4 914 4 ct 888 4 867 -4 852 -19 ct 837 -34 830 -55 830 -81 ct +830 -107 837 -127 851 -143 ct 864 -158 883 -166 906 -166 ct 927 -166 945 -159 958 -144 ct +971 -130 978 -111 978 -86 ct 978 -86 978 -86 978 -79 ct 978 -79 978 -79 858 -79 ct +859 -60 864 -45 874 -35 ct 883 -25 897 -20 914 -20 ct 934 -20 954 -26 974 -38 ct +974 -38 974 -38 981 -17 ct p +950 -100 m 949 -113 944 -123 936 -131 ct 927 -138 918 -142 906 -142 ct 894 -142 884 -138 875 -131 ct +867 -124 862 -113 859 -100 ct 859 -100 859 -100 950 -100 ct p ef +1150 0 m 1150 0 1150 0 1123 0 ct 1123 0 1123 0 1123 -20 ct 1111 -4 1096 4 1076 4 ct +1055 4 1039 -4 1026 -20 ct 1014 -35 1008 -57 1008 -84 ct 1008 -109 1014 -128 1027 -143 ct +1039 -158 1055 -166 1074 -166 ct 1096 -166 1112 -158 1123 -142 ct 1123 -142 1123 -142 1123 -231 ct +1123 -231 1123 -231 1150 -231 ct 1150 -231 1150 -231 1150 0 ct p +1123 -47 m 1123 -47 1123 -47 1123 -116 ct 1119 -123 1114 -130 1106 -135 ct +1098 -140 1090 -142 1081 -142 ct 1067 -142 1056 -137 1048 -126 ct 1040 -116 1036 -101 1036 -82 ct +1036 -62 1040 -47 1048 -36 ct 1057 -25 1068 -20 1082 -20 ct 1088 -20 1094 -21 1100 -24 ct +1106 -27 1111 -31 1116 -36 ct 1121 -41 1123 -45 1123 -47 ct p ef +1362 -226 m 1362 -226 1362 -226 1356 -205 ct 1347 -208 1340 -209 1334 -209 ct +1328 -209 1323 -207 1321 -201 ct 1318 -196 1317 -189 1317 -178 ct 1317 -178 1317 -178 1317 -162 ct +1317 -162 1317 -162 1353 -162 ct 1353 -162 1353 -162 1353 -140 ct 1353 -140 1353 -140 1317 -140 ct +1317 -140 1317 -140 1317 0 ct 1317 0 1317 0 1290 0 ct 1290 0 1290 0 1290 -140 ct +1290 -140 1290 -140 1263 -140 ct 1263 -140 1263 -140 1263 -162 ct 1263 -162 1263 -162 1290 -162 ct +1290 -162 1290 -162 1290 -182 ct 1290 -200 1294 -214 1301 -221 ct 1308 -229 1319 -233 1334 -233 ct +1342 -233 1352 -231 1362 -226 ct p ef +1439 -166 m 1462 -166 1480 -158 1494 -143 ct 1507 -127 1514 -107 1514 -81 ct +1514 -55 1507 -35 1494 -19 ct 1480 -4 1462 4 1439 4 ct 1415 4 1397 -4 1383 -19 ct +1370 -35 1363 -55 1363 -81 ct 1363 -107 1370 -127 1383 -143 ct 1397 -158 1415 -166 1439 -166 ct +p +1439 -20 m 1453 -20 1465 -26 1473 -38 ct 1482 -49 1486 -64 1486 -81 ct 1486 -99 1482 -114 1474 -125 ct +1465 -136 1454 -142 1439 -142 ct 1423 -142 1412 -136 1403 -125 ct 1395 -114 1391 -100 1391 -81 ct +1391 -64 1395 -49 1404 -38 ct 1412 -26 1424 -20 1439 -20 ct p ef +1637 -161 m 1637 -161 1637 -161 1630 -137 ct 1625 -140 1620 -141 1616 -141 ct +1610 -141 1605 -138 1599 -133 ct 1594 -127 1589 -119 1584 -109 ct 1579 -98 1576 -93 1576 -93 ct +1576 -93 1576 -93 1576 0 ct 1576 0 1576 0 1549 0 ct 1549 0 1549 0 1549 -162 ct +1549 -162 1549 -162 1574 -162 ct 1574 -162 1574 -162 1574 -125 ct 1582 -141 1589 -152 1595 -157 ct +1602 -163 1609 -166 1617 -166 ct 1625 -166 1632 -164 1637 -161 ct p ef +1811 -2 m 1801 2 1793 4 1787 4 ct 1773 4 1763 0 1757 -8 ct 1750 -16 1747 -28 1747 -45 ct +1747 -45 1747 -45 1747 -140 ct 1747 -140 1747 -140 1727 -140 ct 1727 -140 1727 -140 1727 -162 ct +1727 -162 1727 -162 1747 -162 ct 1747 -162 1747 -162 1747 -206 ct 1747 -206 1747 -206 1774 -206 ct +1774 -206 1774 -206 1774 -162 ct 1774 -162 1774 -162 1805 -162 ct 1805 -162 1805 -162 1805 -140 ct +1805 -140 1805 -140 1774 -140 ct 1774 -140 1774 -140 1774 -47 ct 1774 -29 1780 -20 1791 -20 ct +1795 -20 1801 -21 1807 -23 ct 1807 -23 1807 -23 1811 -2 ct p ef +1968 0 m 1968 0 1968 0 1941 0 ct 1941 0 1941 0 1941 -103 ct 1941 -115 1938 -125 1932 -132 ct +1926 -139 1917 -142 1907 -142 ct 1891 -142 1875 -133 1860 -115 ct 1860 -115 1860 -115 1860 0 ct +1860 0 1860 0 1833 0 ct 1833 0 1833 0 1833 -231 ct 1833 -231 1833 -231 1860 -231 ct +1860 -231 1860 -231 1860 -139 ct 1877 -157 1895 -166 1914 -166 ct 1931 -166 1944 -161 1954 -151 ct +1963 -142 1968 -128 1968 -110 ct 1968 -110 1968 -110 1968 0 ct p ef +2154 -17 m 2131 -3 2109 4 2087 4 ct 2061 4 2040 -4 2025 -19 ct 2010 -34 2003 -55 2003 -81 ct +2003 -107 2010 -127 2024 -143 ct 2037 -158 2056 -166 2079 -166 ct 2100 -166 2118 -159 2131 -144 ct +2144 -130 2151 -111 2151 -86 ct 2151 -86 2151 -86 2151 -79 ct 2151 -79 2151 -79 2031 -79 ct +2032 -60 2037 -45 2047 -35 ct 2056 -25 2070 -20 2087 -20 ct 2107 -20 2127 -26 2147 -38 ct +2147 -38 2147 -38 2154 -17 ct p +2123 -100 m 2122 -113 2117 -123 2109 -131 ct 2100 -138 2091 -142 2079 -142 ct +2067 -142 2057 -138 2048 -131 ct 2040 -124 2035 -113 2032 -100 ct 2032 -100 2032 -100 2123 -100 ct +p ef +2386 -127 m 2369 -137 2353 -142 2337 -142 ct 2325 -142 2316 -140 2309 -136 ct +2302 -133 2299 -128 2299 -121 ct 2299 -116 2301 -113 2306 -109 ct 2310 -106 2317 -103 2327 -101 ct +2327 -101 2327 -101 2348 -94 ct 2368 -88 2382 -81 2390 -74 ct 2397 -67 2401 -57 2401 -46 ct +2401 -30 2395 -18 2383 -9 ct 2372 0 2356 4 2336 4 ct 2312 4 2291 -2 2271 -14 ct +2271 -14 2271 -14 2280 -35 ct 2298 -25 2316 -20 2334 -20 ct 2361 -20 2374 -28 2374 -43 ct +2374 -49 2371 -54 2365 -58 ct 2360 -63 2348 -67 2329 -73 ct 2315 -77 2305 -81 2299 -83 ct +2294 -85 2289 -88 2285 -92 ct 2280 -95 2277 -99 2275 -104 ct 2273 -109 2272 -114 2272 -119 ct +2272 -133 2278 -145 2289 -153 ct 2300 -162 2316 -166 2337 -166 ct 2346 -166 2355 -164 2366 -161 ct +2376 -158 2386 -154 2394 -148 ct 2394 -148 2394 -148 2386 -127 ct p ef +2466 0 m 2439 0 l 2439 -231 l 2466 -231 l 2466 0 l p ef +2538 0 m 2511 0 l 2511 -162 l 2538 -162 l 2538 0 l p +2524 -231 m 2529 -231 2533 -229 2536 -226 ct 2539 -223 2541 -219 2541 -214 ct +2541 -210 2539 -206 2536 -203 ct 2533 -200 2529 -198 2524 -198 ct 2520 -198 2516 -200 2513 -203 ct +2510 -206 2508 -210 2508 -214 ct 2508 -219 2510 -223 2513 -226 ct 2516 -229 2520 -231 2524 -231 ct +p ef +2574 -81 m 2574 -108 2582 -129 2597 -144 ct 2612 -159 2631 -166 2654 -166 ct +2673 -166 2692 -160 2709 -149 ct 2709 -149 2709 -149 2701 -128 ct 2686 -137 2671 -142 2654 -142 ct +2639 -142 2627 -136 2617 -125 ct 2607 -114 2602 -100 2602 -81 ct 2602 -63 2607 -48 2617 -37 ct +2627 -26 2640 -20 2655 -20 ct 2670 -20 2687 -25 2704 -36 ct 2704 -36 2704 -36 2712 -15 ct +2694 -2 2675 4 2655 4 ct 2631 4 2611 -4 2596 -19 ct 2582 -35 2574 -56 2574 -81 ct +p ef +2886 -17 m 2863 -3 2841 4 2819 4 ct 2793 4 2772 -4 2757 -19 ct 2742 -34 2735 -55 2735 -81 ct +2735 -107 2742 -127 2756 -143 ct 2769 -158 2788 -166 2811 -166 ct 2832 -166 2850 -159 2863 -144 ct +2876 -130 2883 -111 2883 -86 ct 2883 -86 2883 -86 2883 -79 ct 2883 -79 2883 -79 2763 -79 ct +2764 -60 2769 -45 2779 -35 ct 2788 -25 2802 -20 2819 -20 ct 2839 -20 2859 -26 2879 -38 ct +2879 -38 2879 -38 2886 -17 ct p +2855 -100 m 2854 -113 2849 -123 2841 -131 ct 2832 -138 2823 -142 2811 -142 ct +2799 -142 2789 -138 2780 -131 ct 2772 -124 2767 -113 2764 -100 ct 2764 -100 2764 -100 2855 -100 ct +p ef +2944 4 m 2938 3 2934 1 2930 -3 ct 2927 -7 2925 -11 2925 -16 ct 2925 -21 2927 -26 2930 -30 ct +2934 -33 2938 -35 2943 -35 ct 2949 -35 2954 -33 2958 -28 ct 2962 -23 2964 -17 2964 -11 ct +2964 10 2953 26 2931 37 ct 2931 37 2931 37 2925 26 ct 2938 20 2944 12 2944 4 ct +p ef +pom +gr +gs +pum +3953 12012 t +0.003 0.003 0.003 c 226 -162 m 179 0 l 154 0 l 115 -130 l 76 0 l 51 0 l +4 -162 l 32 -162 l 65 -37 l 101 -162 l 127 -162 l 166 -37 l 198 -162 l +226 -162 l p ef +380 0 m 380 0 380 0 353 0 ct 353 0 353 0 353 -103 ct 353 -115 350 -125 344 -132 ct +338 -139 329 -142 319 -142 ct 303 -142 287 -133 272 -115 ct 272 -115 272 -115 272 0 ct +272 0 272 0 245 0 ct 245 0 245 0 245 -231 ct 245 -231 245 -231 272 -231 ct 272 -231 272 -231 272 -139 ct +289 -157 307 -166 326 -166 ct 343 -166 356 -161 366 -151 ct 375 -142 380 -128 380 -110 ct +380 -110 380 -110 380 0 ct p ef +451 0 m 424 0 l 424 -162 l 451 -162 l 451 0 l p +437 -231 m 442 -231 446 -229 449 -226 ct 452 -223 454 -219 454 -214 ct 454 -210 452 -206 449 -203 ct +446 -200 442 -198 437 -198 ct 433 -198 429 -200 426 -203 ct 423 -206 421 -210 421 -214 ct +421 -219 423 -223 426 -226 ct 429 -229 433 -231 437 -231 ct p ef +487 -81 m 487 -108 495 -129 510 -144 ct 525 -159 544 -166 567 -166 ct 586 -166 605 -160 622 -149 ct +622 -149 622 -149 614 -128 ct 599 -137 584 -142 567 -142 ct 552 -142 540 -136 530 -125 ct +520 -114 515 -100 515 -81 ct 515 -63 520 -48 530 -37 ct 540 -26 553 -20 568 -20 ct +583 -20 600 -25 617 -36 ct 617 -36 617 -36 625 -15 ct 607 -2 588 4 568 4 ct 544 4 524 -4 509 -19 ct +495 -35 487 -56 487 -81 ct p ef +791 0 m 791 0 791 0 764 0 ct 764 0 764 0 764 -103 ct 764 -115 761 -125 755 -132 ct +749 -139 740 -142 730 -142 ct 714 -142 698 -133 683 -115 ct 683 -115 683 -115 683 0 ct +683 0 683 0 656 0 ct 656 0 656 0 656 -231 ct 656 -231 656 -231 683 -231 ct 683 -231 683 -231 683 -139 ct +700 -157 718 -166 737 -166 ct 754 -166 767 -161 777 -151 ct 786 -142 791 -128 791 -110 ct +791 -110 791 -110 791 0 ct p ef +1057 0 m 1057 0 1057 0 1030 0 ct 1030 0 1030 0 1030 -20 ct 1018 -4 1003 4 983 4 ct +962 4 946 -4 933 -20 ct 921 -35 915 -57 915 -84 ct 915 -109 921 -128 934 -143 ct +946 -158 962 -166 981 -166 ct 1003 -166 1019 -158 1030 -142 ct 1030 -142 1030 -142 1030 -231 ct +1030 -231 1030 -231 1057 -231 ct 1057 -231 1057 -231 1057 0 ct p +1030 -47 m 1030 -47 1030 -47 1030 -116 ct 1026 -123 1021 -130 1013 -135 ct +1005 -140 997 -142 988 -142 ct 974 -142 963 -137 955 -126 ct 947 -116 943 -101 943 -82 ct +943 -62 947 -47 955 -36 ct 964 -25 975 -20 989 -20 ct 995 -20 1001 -21 1007 -24 ct +1013 -27 1018 -31 1023 -36 ct 1028 -41 1030 -45 1030 -47 ct p ef +1244 -17 m 1221 -3 1199 4 1177 4 ct 1151 4 1130 -4 1115 -19 ct 1100 -34 1093 -55 1093 -81 ct +1093 -107 1100 -127 1114 -143 ct 1127 -158 1146 -166 1169 -166 ct 1190 -166 1208 -159 1221 -144 ct +1234 -130 1241 -111 1241 -86 ct 1241 -86 1241 -86 1241 -79 ct 1241 -79 1241 -79 1121 -79 ct +1122 -60 1127 -45 1137 -35 ct 1146 -25 1160 -20 1177 -20 ct 1197 -20 1217 -26 1237 -38 ct +1237 -38 1237 -38 1244 -17 ct p +1213 -100 m 1212 -113 1207 -123 1199 -131 ct 1190 -138 1181 -142 1169 -142 ct +1157 -142 1147 -138 1138 -131 ct 1130 -124 1125 -113 1122 -100 ct 1122 -100 1122 -100 1213 -100 ct +p ef +1305 -142 m 1318 -158 1335 -166 1355 -166 ct 1374 -166 1389 -158 1402 -143 ct +1415 -128 1421 -109 1421 -84 ct 1421 -57 1415 -36 1402 -20 ct 1389 -4 1373 4 1354 4 ct +1334 4 1318 -4 1305 -19 ct 1305 -19 1305 -19 1305 63 ct 1305 63 1305 63 1278 63 ct +1278 63 1278 63 1278 -166 ct 1278 -166 1278 -166 1305 -166 ct 1305 -166 1305 -166 1305 -142 ct +p +1305 -116 m 1305 -116 1305 -116 1305 -47 ct 1309 -40 1315 -33 1323 -28 ct 1331 -23 1339 -20 1347 -20 ct +1362 -20 1373 -25 1381 -36 ct 1389 -47 1393 -62 1393 -82 ct 1393 -101 1389 -116 1381 -126 ct +1373 -137 1362 -142 1347 -142 ct 1340 -142 1333 -140 1325 -135 ct 1317 -130 1311 -124 1305 -116 ct +p ef +1599 -17 m 1576 -3 1554 4 1532 4 ct 1506 4 1485 -4 1470 -19 ct 1455 -34 1448 -55 1448 -81 ct +1448 -107 1455 -127 1469 -143 ct 1482 -158 1501 -166 1524 -166 ct 1545 -166 1563 -159 1576 -144 ct +1589 -130 1596 -111 1596 -86 ct 1596 -86 1596 -86 1596 -79 ct 1596 -79 1596 -79 1476 -79 ct +1477 -60 1482 -45 1492 -35 ct 1501 -25 1515 -20 1532 -20 ct 1552 -20 1572 -26 1592 -38 ct +1592 -38 1592 -38 1599 -17 ct p +1568 -100 m 1567 -113 1562 -123 1554 -131 ct 1545 -138 1536 -142 1524 -142 ct +1512 -142 1502 -138 1493 -131 ct 1485 -124 1480 -113 1477 -100 ct 1477 -100 1477 -100 1568 -100 ct +p ef +1769 0 m 1769 0 1769 0 1742 0 ct 1742 0 1742 0 1742 -103 ct 1742 -115 1739 -125 1733 -132 ct +1727 -139 1718 -142 1708 -142 ct 1692 -142 1676 -133 1661 -115 ct 1661 -115 1661 -115 1661 0 ct +1661 0 1661 0 1634 0 ct 1634 0 1634 0 1634 -162 ct 1634 -162 1634 -162 1661 -162 ct +1661 -162 1661 -162 1661 -139 ct 1678 -157 1696 -166 1715 -166 ct 1732 -166 1745 -161 1755 -151 ct +1764 -142 1769 -128 1769 -110 ct 1769 -110 1769 -110 1769 0 ct p ef +1946 0 m 1946 0 1946 0 1919 0 ct 1919 0 1919 0 1919 -20 ct 1907 -4 1892 4 1872 4 ct +1851 4 1835 -4 1822 -20 ct 1810 -35 1804 -57 1804 -84 ct 1804 -109 1810 -128 1823 -143 ct +1835 -158 1851 -166 1870 -166 ct 1892 -166 1908 -158 1919 -142 ct 1919 -142 1919 -142 1919 -231 ct +1919 -231 1919 -231 1946 -231 ct 1946 -231 1946 -231 1946 0 ct p +1919 -47 m 1919 -47 1919 -47 1919 -116 ct 1915 -123 1910 -130 1902 -135 ct +1894 -140 1886 -142 1877 -142 ct 1863 -142 1852 -137 1844 -126 ct 1836 -116 1832 -101 1832 -82 ct +1832 -62 1836 -47 1844 -36 ct 1853 -25 1864 -20 1878 -20 ct 1884 -20 1890 -21 1896 -24 ct +1902 -27 1907 -31 1912 -36 ct 1917 -41 1919 -45 1919 -47 ct p ef +2099 -127 m 2082 -137 2066 -142 2050 -142 ct 2038 -142 2029 -140 2022 -136 ct +2015 -133 2012 -128 2012 -121 ct 2012 -116 2014 -113 2019 -109 ct 2023 -106 2030 -103 2040 -101 ct +2040 -101 2040 -101 2061 -94 ct 2081 -88 2095 -81 2103 -74 ct 2110 -67 2114 -57 2114 -46 ct +2114 -30 2108 -18 2096 -9 ct 2085 0 2069 4 2049 4 ct 2025 4 2004 -2 1984 -14 ct +1984 -14 1984 -14 1993 -35 ct 2011 -25 2029 -20 2047 -20 ct 2074 -20 2087 -28 2087 -43 ct +2087 -49 2084 -54 2078 -58 ct 2073 -63 2061 -67 2042 -73 ct 2028 -77 2018 -81 2012 -83 ct +2007 -85 2002 -88 1998 -92 ct 1993 -95 1990 -99 1988 -104 ct 1986 -109 1985 -114 1985 -119 ct +1985 -133 1991 -145 2002 -153 ct 2013 -162 2029 -166 2050 -166 ct 2059 -166 2068 -164 2079 -161 ct +2089 -158 2099 -154 2107 -148 ct 2107 -148 2107 -148 2099 -127 ct p ef +2307 -166 m 2330 -166 2348 -158 2362 -143 ct 2375 -127 2382 -107 2382 -81 ct +2382 -55 2375 -35 2362 -19 ct 2348 -4 2330 4 2307 4 ct 2283 4 2265 -4 2251 -19 ct +2238 -35 2231 -55 2231 -81 ct 2231 -107 2238 -127 2251 -143 ct 2265 -158 2283 -166 2307 -166 ct +p +2307 -20 m 2321 -20 2333 -26 2341 -38 ct 2350 -49 2354 -64 2354 -81 ct 2354 -99 2350 -114 2342 -125 ct +2333 -136 2322 -142 2307 -142 ct 2291 -142 2280 -136 2271 -125 ct 2263 -114 2259 -100 2259 -81 ct +2259 -64 2263 -49 2272 -38 ct 2280 -26 2292 -20 2307 -20 ct p ef +2552 0 m 2552 0 2552 0 2525 0 ct 2525 0 2525 0 2525 -103 ct 2525 -115 2522 -125 2516 -132 ct +2510 -139 2501 -142 2491 -142 ct 2475 -142 2459 -133 2444 -115 ct 2444 -115 2444 -115 2444 0 ct +2444 0 2444 0 2417 0 ct 2417 0 2417 0 2417 -162 ct 2417 -162 2417 -162 2444 -162 ct +2444 -162 2444 -162 2444 -139 ct 2461 -157 2479 -166 2498 -166 ct 2515 -166 2528 -161 2538 -151 ct +2547 -142 2552 -128 2552 -110 ct 2552 -110 2552 -110 2552 0 ct p ef +pom +gr +gs +pum +3953 12368 t +0.003 0.003 0.003 c 130 -127 m 113 -137 97 -142 81 -142 ct 69 -142 60 -140 53 -136 ct +46 -133 43 -128 43 -121 ct 43 -116 45 -113 50 -109 ct 54 -106 61 -103 71 -101 ct +71 -101 71 -101 92 -94 ct 112 -88 126 -81 134 -74 ct 141 -67 145 -57 145 -46 ct +145 -30 139 -18 127 -9 ct 116 0 100 4 80 4 ct 56 4 35 -2 15 -14 ct 15 -14 15 -14 24 -35 ct +42 -25 60 -20 78 -20 ct 105 -20 118 -28 118 -43 ct 118 -49 115 -54 109 -58 ct 104 -63 92 -67 73 -73 ct +59 -77 49 -81 43 -83 ct 38 -85 33 -88 29 -92 ct 24 -95 21 -99 19 -104 ct 17 -109 16 -114 16 -119 ct +16 -133 22 -145 33 -153 ct 44 -162 60 -166 81 -166 ct 90 -166 99 -164 110 -161 ct +120 -158 130 -154 138 -148 ct 138 -148 138 -148 130 -127 ct p ef +249 -2 m 239 2 231 4 225 4 ct 211 4 201 0 195 -8 ct 188 -16 185 -28 185 -45 ct +185 -45 185 -45 185 -140 ct 185 -140 185 -140 165 -140 ct 165 -140 165 -140 165 -162 ct +165 -162 165 -162 185 -162 ct 185 -162 185 -162 185 -206 ct 185 -206 185 -206 212 -206 ct +212 -206 212 -206 212 -162 ct 212 -162 212 -162 243 -162 ct 243 -162 243 -162 243 -140 ct +243 -140 243 -140 212 -140 ct 212 -140 212 -140 212 -47 ct 212 -29 218 -20 229 -20 ct +233 -20 239 -21 245 -23 ct 245 -23 245 -23 249 -2 ct p ef +405 0 m 405 0 405 0 378 0 ct 378 0 378 0 378 -20 ct 366 -4 351 4 331 4 ct 310 4 294 -4 281 -20 ct +269 -35 263 -57 263 -84 ct 263 -109 269 -128 282 -143 ct 294 -158 310 -166 329 -166 ct +351 -166 367 -158 378 -142 ct 378 -142 378 -142 378 -231 ct 378 -231 378 -231 405 -231 ct +405 -231 405 -231 405 0 ct p +378 -47 m 378 -47 378 -47 378 -116 ct 374 -123 369 -130 361 -135 ct 353 -140 345 -142 336 -142 ct +322 -142 311 -137 303 -126 ct 295 -116 291 -101 291 -82 ct 291 -62 295 -47 303 -36 ct +312 -25 323 -20 337 -20 ct 343 -20 349 -21 355 -24 ct 361 -27 366 -31 371 -36 ct +376 -41 378 -45 378 -47 ct p ef +477 0 m 450 0 l 450 -162 l 477 -162 l 477 0 l p +463 -231 m 468 -231 472 -229 475 -226 ct 478 -223 480 -219 480 -214 ct 480 -210 478 -206 475 -203 ct +472 -200 468 -198 463 -198 ct 459 -198 455 -200 452 -203 ct 449 -206 447 -210 447 -214 ct +447 -219 449 -223 452 -226 ct 455 -229 459 -231 463 -231 ct p ef +589 -166 m 612 -166 630 -158 644 -143 ct 657 -127 664 -107 664 -81 ct 664 -55 657 -35 644 -19 ct +630 -4 612 4 589 4 ct 565 4 547 -4 533 -19 ct 520 -35 513 -55 513 -81 ct 513 -107 520 -127 533 -143 ct +547 -158 565 -166 589 -166 ct p +589 -20 m 603 -20 615 -26 623 -38 ct 632 -49 636 -64 636 -81 ct 636 -99 632 -114 624 -125 ct +615 -136 604 -142 589 -142 ct 573 -142 562 -136 553 -125 ct 545 -114 541 -100 541 -81 ct +541 -64 545 -49 554 -38 ct 562 -26 574 -20 589 -20 ct p ef +720 -35 m 726 -35 730 -33 734 -30 ct 737 -26 739 -22 739 -16 ct 739 -11 737 -7 734 -3 ct +730 0 726 2 720 2 ct 715 2 711 0 707 -3 ct 704 -7 702 -11 702 -16 ct 702 -22 704 -26 707 -30 ct +711 -33 715 -35 720 -35 ct p ef +922 0 m 922 0 922 0 895 0 ct 895 0 895 0 895 -103 ct 895 -115 892 -125 886 -132 ct +880 -139 871 -142 861 -142 ct 845 -142 829 -133 814 -115 ct 814 -115 814 -115 814 0 ct +814 0 814 0 787 0 ct 787 0 787 0 787 -231 ct 787 -231 787 -231 814 -231 ct 814 -231 814 -231 814 -139 ct +831 -157 849 -166 868 -166 ct 885 -166 898 -161 908 -151 ct 917 -142 922 -128 922 -110 ct +922 -110 922 -110 922 0 ct p ef +966 -231 m 988 -207 1004 -184 1014 -163 ct 1024 -141 1029 -117 1029 -90 ct +1029 -63 1024 -38 1014 -16 ct 1004 5 988 28 966 52 ct 966 52 966 52 955 45 ct 971 24 982 3 990 -19 ct +997 -40 1001 -64 1001 -90 ct 1001 -115 997 -139 990 -160 ct 982 -182 971 -203 955 -224 ct +955 -224 955 -224 966 -231 ct p ef +pom +gr +gr +0.300 0.300 0.300 c 9458 13212 m 9430 13207 l 9402 13203 l 9373 13199 l +9344 13197 l 9314 13194 l 9284 13193 l 9254 13192 l 9225 13192 l 9195 13193 l +9165 13194 l 9135 13196 l 9106 13198 l 9077 13201 l 9048 13205 l 9020 13210 l +8993 13215 l 8966 13221 l 8940 13227 l 8914 13234 l 8890 13241 l 8866 13249 l +8844 13258 l 8822 13267 l 8577 13159 l 8611 13145 l 8647 13131 l 8685 13119 l +8724 13107 l 8765 13096 l 8806 13086 l 8849 13077 l 8893 13068 l 8938 13061 l +8983 13055 l 9030 13050 l 9076 13046 l 9123 13043 l 9171 13041 l 9219 13040 l +9266 13040 l 9314 13042 l 9361 13044 l 9408 13047 l 9455 13052 l 9501 13057 l +9546 13064 l 9590 13071 l 9681 12978 l 9900 13210 l 9368 13305 l 9458 13212 l +p ef +9033 13557 m 9061 13562 l 9089 13566 l 9118 13570 l 9147 13572 l 9177 13575 l +9207 13576 l 9237 13577 l 9266 13577 l 9296 13576 l 9326 13575 l 9356 13573 l +9385 13571 l 9414 13568 l 9443 13564 l 9471 13559 l 9498 13554 l 9525 13548 l +9551 13542 l 9577 13535 l 9601 13528 l 9625 13520 l 9647 13511 l 9669 13502 l +9914 13610 l 9880 13624 l 9844 13638 l 9806 13650 l 9767 13662 l 9726 13673 l +9685 13683 l 9642 13692 l 9598 13701 l 9553 13708 l 9508 13714 l 9461 13719 l +9415 13723 l 9368 13726 l 9320 13728 l 9272 13729 l 9225 13729 l 9177 13727 l +9130 13725 l 9083 13722 l 9036 13717 l 8990 13712 l 8945 13705 l 8901 13698 l +8810 13791 l 8591 13559 l 9123 13464 l 9033 13557 l p ef +gs +gs +pum +8795 12884 t +0.003 0.003 0.003 c 44 0 m 20 0 l 20 -143 l 44 -143 l 44 0 l p +32 -205 m 36 -205 40 -204 43 -201 ct 46 -198 47 -194 47 -190 ct 47 -186 46 -183 43 -180 ct +40 -177 36 -176 32 -176 ct 28 -176 25 -177 22 -180 ct 19 -183 18 -186 18 -190 ct +18 -194 19 -198 22 -201 ct 25 -204 28 -205 32 -205 ct p ef +202 0 m 202 0 202 0 178 0 ct 178 0 178 0 178 -91 ct 178 -102 175 -110 170 -116 ct +165 -122 157 -125 148 -125 ct 134 -125 120 -117 107 -101 ct 107 -101 107 -101 107 0 ct +107 0 107 0 83 0 ct 83 0 83 0 83 -143 ct 83 -143 83 -143 107 -143 ct 107 -143 107 -143 107 -122 ct +122 -138 138 -146 155 -146 ct 169 -146 181 -142 189 -133 ct 198 -125 202 -113 202 -97 ct +202 -97 202 -97 202 0 ct p ef +231 -72 m 231 -95 238 -113 251 -126 ct 265 -139 282 -146 302 -146 ct 319 -146 336 -141 351 -132 ct +351 -132 351 -132 344 -113 ct 331 -121 317 -125 303 -125 ct 289 -125 278 -120 269 -110 ct +260 -101 256 -88 256 -72 ct 256 -55 260 -42 269 -33 ct 278 -23 289 -18 303 -18 ct +316 -18 331 -23 346 -32 ct 346 -32 346 -32 353 -13 ct 337 -2 320 3 303 3 ct 281 3 264 -4 251 -18 ct +238 -31 231 -49 231 -72 ct p ef +408 0 m 384 0 l 384 -205 l 408 -205 l 408 0 l p ef +566 0 m 566 0 566 0 542 0 ct 542 0 542 0 542 -21 ct 527 -5 511 3 494 3 ct 480 3 468 -1 460 -10 ct +451 -18 447 -30 447 -46 ct 447 -46 447 -46 447 -143 ct 447 -143 447 -143 471 -143 ct +471 -143 471 -143 471 -52 ct 471 -42 474 -33 479 -27 ct 484 -21 492 -18 501 -18 ct +515 -18 529 -26 542 -42 ct 542 -42 542 -42 542 -143 ct 542 -143 542 -143 566 -143 ct +566 -143 566 -143 566 0 ct p ef +722 0 m 722 0 722 0 698 0 ct 698 0 698 0 698 -18 ct 688 -4 673 3 656 3 ct 637 3 622 -4 611 -18 ct +601 -32 595 -50 595 -74 ct 595 -96 601 -113 612 -126 ct 623 -139 637 -146 654 -146 ct +673 -146 688 -139 698 -125 ct 698 -125 698 -125 698 -205 ct 698 -205 698 -205 722 -205 ct +722 -205 722 -205 722 0 ct p +698 -42 m 698 -42 698 -42 698 -102 ct 695 -109 690 -114 683 -118 ct 676 -123 669 -125 661 -125 ct +648 -125 638 -120 631 -111 ct 624 -102 620 -89 620 -72 ct 620 -55 624 -42 631 -32 ct +638 -23 649 -18 661 -18 ct 667 -18 672 -19 677 -22 ct 683 -24 687 -28 692 -32 ct +696 -37 698 -40 698 -42 ct p ef +887 -15 m 867 -3 847 3 827 3 ct 803 3 785 -4 772 -17 ct 759 -30 752 -49 752 -72 ct +752 -94 758 -112 770 -126 ct 783 -139 799 -146 820 -146 ct 839 -146 854 -140 866 -127 ct +878 -114 884 -97 884 -75 ct 884 -75 884 -75 884 -69 ct 884 -69 884 -69 777 -69 ct +778 -52 782 -40 791 -31 ct 799 -22 811 -18 827 -18 ct 845 -18 862 -23 880 -34 ct +880 -34 880 -34 887 -15 ct p +859 -88 m 858 -99 854 -108 846 -115 ct 839 -122 830 -125 820 -125 ct 809 -125 800 -122 792 -115 ct +785 -109 780 -100 778 -88 ct 778 -88 778 -88 859 -88 ct p ef +pom +gr +gr +tm setmatrix +0 0 t +1 1 s +0 19616 t +pom +count op_count sub {pop} repeat countdictstack dict_count sub {end} repeat b4_inc_state restore +%%PageTrailer +%%Trailer +%%EOF diff --git a/AspectC++/doc/images/include_cycle.odg b/AspectC++/doc/images/include_cycle.odg new file mode 100644 index 0000000..8a10304 Binary files /dev/null and b/AspectC++/doc/images/include_cycle.odg differ diff --git a/AspectC++/doc/images/no_include_cycle.eps b/AspectC++/doc/images/no_include_cycle.eps new file mode 100644 index 0000000..2674d8b --- /dev/null +++ b/AspectC++/doc/images/no_include_cycle.eps @@ -0,0 +1,5689 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 501 568 +%%Pages: 0 +%%Creator: Sun Microsystems, Inc. +%%Title: none +%%CreationDate: none +%%LanguageLevel: 2 +%%EndComments +%%BeginProlog +%%BeginResource: SDRes +/b4_inc_state save def +/dict_count countdictstack def +/op_count count 1 sub def +userdict begin +0 setgray 0 setlinecap 1 setlinewidth 0 setlinejoin 10 setmiterlimit[] 0 setdash newpath +/languagelevel where {pop languagelevel 1 ne {false setstrokeadjust false setoverprint} if} if +/bdef {bind def} bind def +/c {setrgbcolor} bdef +/l {neg lineto} bdef +/rl {neg rlineto} bdef +/lc {setlinecap} bdef +/lj {setlinejoin} bdef +/lw {setlinewidth} bdef +/ml {setmiterlimit} bdef +/ld {setdash} bdef +/m {neg moveto} bdef +/ct {6 2 roll neg 6 2 roll neg 6 2 roll neg curveto} bdef +/r {rotate} bdef +/t {neg translate} bdef +/s {scale} bdef +/sw {show} bdef +/gs {gsave} bdef +/gr {grestore} bdef +/f {findfont dup length dict begin +{1 index /FID ne {def} {pop pop} ifelse} forall /Encoding ISOLatin1Encoding def +currentdict end /NFont exch definefont pop /NFont findfont} bdef +/p {closepath} bdef +/sf {scalefont setfont} bdef +/ef {eofill}bdef +/pc {closepath stroke}bdef +/ps {stroke}bdef +/pum {matrix currentmatrix}bdef +/pom {setmatrix}bdef +/bs {/aString exch def /nXOfs exch def /nWidth exch def currentpoint nXOfs 0 rmoveto pum nWidth aString stringwidth pop div 1 scale aString show pom moveto} bdef +%%EndResource +%%EndProlog +%%BeginSetup +%%EndSetup +%%Page: 1 1 +%%BeginPageSetup +%%EndPageSetup +pum +0.02833 0.02836 s +0 -20028 t +/tm matrix currentmatrix def +tm setmatrix +-1810 -822 t +1 1 s +0.503 0.503 0.503 c 5575 8608 m 2665 8608 l 2665 5285 l 8485 5285 l +8485 8608 l 5575 8608 l p ef +50 lw 1 lj 5575 8608 m 2665 8608 l 2665 5285 l 8485 5285 l 8485 8608 l +5575 8608 l pc +1.000 0.902 0.777 c 5475 8508 m 2565 8508 l 2565 5185 l 8385 5185 l +8385 8508 l 5475 8508 l p ef +0.003 0.003 0.003 c 5475 8508 m 2565 8508 l 2565 5185 l 8385 5185 l 8385 8508 l +5475 8508 l pc +gs +gs +pum +3054 5643 t +0.003 0.003 1.000 c 227 -4 m 202 2 177 5 152 5 ct 111 5 78 -5 55 -26 ct 32 -47 20 -75 20 -111 ct +20 -148 31 -177 54 -198 ct 76 -219 108 -229 148 -229 ct 178 -229 204 -226 227 -220 ct +227 -220 227 -220 227 -175 ct 202 -184 179 -188 156 -188 ct 134 -188 117 -182 105 -169 ct +92 -157 86 -140 86 -118 ct 86 -94 94 -74 109 -60 ct 124 -45 144 -38 169 -38 ct +188 -38 208 -42 227 -49 ct 227 -49 227 -49 227 -4 ct p ef +356 0 m 356 -285 l 274 -285 l 274 -326 l 417 -326 l 417 0 l 356 0 l +p ef +661 -24 m 654 -14 645 -7 635 -2 ct 625 3 614 5 601 5 ct 579 5 561 -2 547 -15 ct +533 -28 526 -45 526 -65 ct 526 -91 536 -111 555 -124 ct 575 -137 604 -143 643 -143 ct +643 -143 643 -143 667 -143 ct 667 -143 667 -143 667 -154 ct 667 -165 663 -174 655 -179 ct +647 -185 635 -188 619 -188 ct 597 -188 572 -182 545 -169 ct 545 -169 545 -169 545 -214 ct +573 -224 601 -229 630 -229 ct 662 -229 686 -223 702 -211 ct 712 -203 719 -194 723 -185 ct +726 -175 728 -160 728 -140 ct 728 -140 728 -140 728 -64 ct 728 -49 733 -41 742 -41 ct +744 -41 746 -41 749 -42 ct 749 -42 749 -42 749 -2 ct 737 3 725 5 715 5 ct 704 5 694 3 686 -2 ct +678 -7 672 -14 667 -24 ct 667 -24 667 -24 661 -24 ct p +667 -65 m 667 -65 667 -65 667 -102 ct 667 -102 667 -102 645 -102 ct 626 -102 611 -99 602 -94 ct +592 -88 587 -80 587 -69 ct 587 -61 590 -54 596 -49 ct 602 -44 609 -41 618 -41 ct +633 -41 650 -49 667 -65 ct p ef +795 -8 m 795 -8 795 -8 795 -54 ct 829 -42 857 -36 877 -36 ct 892 -36 903 -38 911 -42 ct +918 -46 922 -52 922 -60 ct 922 -64 920 -68 916 -72 ct 913 -75 907 -79 900 -82 ct +900 -82 900 -82 852 -101 ct 833 -109 819 -118 810 -127 ct 801 -137 796 -148 796 -161 ct +796 -182 806 -199 825 -211 ct 844 -223 871 -229 905 -229 ct 925 -229 948 -226 974 -221 ct +974 -221 974 -221 974 -174 ct 946 -183 922 -188 903 -188 ct 888 -188 878 -186 871 -183 ct +864 -180 860 -175 860 -169 ct 860 -165 863 -162 868 -158 ct 873 -154 880 -150 890 -146 ct +890 -146 890 -146 943 -124 ct 959 -118 971 -110 978 -100 ct 986 -91 990 -79 990 -66 ct +990 -45 981 -28 962 -15 ct 943 -2 919 5 889 5 ct 863 5 831 1 795 -8 ct p ef +1049 -8 m 1049 -8 1049 -8 1049 -54 ct 1083 -42 1111 -36 1131 -36 ct 1146 -36 1157 -38 1165 -42 ct +1172 -46 1176 -52 1176 -60 ct 1176 -64 1174 -68 1170 -72 ct 1167 -75 1161 -79 1154 -82 ct +1154 -82 1154 -82 1106 -101 ct 1087 -109 1073 -118 1064 -127 ct 1055 -137 1050 -148 1050 -161 ct +1050 -182 1060 -199 1079 -211 ct 1098 -223 1125 -229 1159 -229 ct 1179 -229 1202 -226 1228 -221 ct +1228 -221 1228 -221 1228 -174 ct 1200 -183 1176 -188 1157 -188 ct 1142 -188 1132 -186 1125 -183 ct +1118 -180 1114 -175 1114 -169 ct 1114 -165 1117 -162 1122 -158 ct 1127 -154 1134 -150 1144 -146 ct +1144 -146 1144 -146 1197 -124 ct 1213 -118 1225 -110 1232 -100 ct 1240 -91 1244 -79 1244 -66 ct +1244 -45 1235 -28 1216 -15 ct 1197 -2 1173 5 1143 5 ct 1117 5 1085 1 1049 -8 ct +p ef +pom +gr +gs +pum +4324 5643 t +361 0 m 361 -275 l 259 -275 l 259 -306 l 504 -306 l 504 -275 l 402 -275 l +402 0 l 361 0 l p ef +680 -26 m 656 -5 631 5 607 5 ct 586 5 569 -1 556 -13 ct 543 -24 536 -39 536 -57 ct +536 -81 546 -99 567 -114 ct 588 -128 615 -135 649 -135 ct 649 -135 649 -135 674 -135 ct +674 -135 674 -135 674 -154 ct 674 -169 670 -180 663 -187 ct 655 -194 644 -198 629 -198 ct +605 -198 580 -191 555 -177 ct 555 -177 555 -177 555 -213 ct 584 -224 611 -229 637 -229 ct +666 -229 686 -223 697 -212 ct 709 -201 715 -181 715 -153 ct 715 -153 715 -153 715 -59 ct +715 -45 716 -36 719 -31 ct 722 -26 728 -24 735 -24 ct 738 -24 742 -25 748 -26 ct +748 -26 748 -26 752 -2 ct 738 3 728 5 721 5 ct 711 5 702 2 696 -3 ct 689 -8 684 -16 680 -26 ct +p +674 -53 m 674 -53 674 -53 674 -110 ct 674 -110 674 -110 662 -110 ct 634 -110 613 -106 599 -99 ct +585 -91 578 -80 578 -64 ct 578 -52 581 -43 588 -37 ct 594 -31 604 -28 617 -28 ct +635 -28 654 -36 674 -53 ct p ef +826 0 m 826 0 826 0 826 -224 ct 826 -224 826 -224 867 -224 ct 867 -224 867 -224 865 -182 ct +865 -182 865 -182 867 -182 ct 877 -198 889 -209 903 -217 ct 917 -225 932 -229 950 -229 ct +962 -229 976 -227 991 -224 ct 991 -224 991 -224 991 -160 ct 991 -160 991 -160 960 -160 ct +960 -160 960 -160 960 -191 ct 954 -192 948 -193 943 -193 ct 929 -193 916 -189 904 -181 ct +891 -173 879 -161 867 -145 ct 867 -145 867 -145 867 0 ct 867 0 867 0 826 0 ct p ef +1059 75 m 1059 75 1059 75 1063 41 ct 1088 51 1111 56 1132 56 ct 1154 56 1170 51 1179 42 ct +1189 33 1195 17 1198 -6 ct 1198 -6 1198 -6 1202 -46 ct 1202 -46 1202 -46 1198 -46 ct +1190 -31 1179 -19 1167 -12 ct 1154 -4 1140 0 1124 0 ct 1099 0 1079 -10 1064 -29 ct +1049 -49 1041 -75 1041 -108 ct 1041 -144 1050 -173 1067 -195 ct 1085 -218 1107 -229 1135 -229 ct +1157 -229 1179 -219 1200 -198 ct 1200 -198 1200 -198 1203 -198 ct 1203 -198 1203 -198 1203 -224 ct +1203 -224 1203 -224 1239 -224 ct 1239 -224 1239 -224 1239 -45 ct 1239 -15 1237 6 1233 21 ct +1229 36 1222 49 1211 60 ct 1194 78 1168 87 1131 87 ct 1110 87 1086 83 1059 75 ct +p +1198 -80 m 1198 -80 1198 -80 1198 -167 ct 1180 -188 1160 -198 1141 -198 ct +1122 -198 1108 -191 1098 -176 ct 1089 -162 1084 -140 1084 -111 ct 1084 -86 1088 -67 1096 -55 ct +1105 -42 1117 -36 1134 -36 ct 1146 -36 1157 -40 1168 -47 ct 1179 -54 1189 -65 1198 -80 ct +p ef +1496 -9 m 1468 0 1442 5 1418 5 ct 1380 5 1351 -5 1330 -25 ct 1309 -45 1299 -73 1299 -110 ct +1299 -144 1309 -173 1329 -195 ct 1349 -218 1374 -229 1405 -229 ct 1436 -229 1458 -220 1473 -201 ct +1488 -182 1495 -153 1495 -114 ct 1495 -114 1495 -114 1495 -101 ct 1495 -101 1495 -101 1341 -101 ct +1342 -76 1350 -57 1364 -45 ct 1378 -32 1397 -26 1423 -26 ct 1446 -26 1470 -31 1496 -42 ct +1496 -42 1496 -42 1496 -9 ct p +1342 -132 m 1342 -132 1342 -132 1452 -132 ct 1452 -132 1452 -132 1452 -138 ct +1452 -158 1448 -173 1439 -183 ct 1430 -193 1418 -198 1401 -198 ct 1384 -198 1371 -192 1360 -181 ct +1350 -169 1344 -153 1342 -132 ct p ef +1752 0 m 1732 3 1712 5 1693 5 ct 1660 5 1637 -1 1625 -13 ct 1613 -25 1607 -47 1607 -80 ct +1607 -80 1607 -80 1607 -188 ct 1607 -188 1607 -188 1551 -188 ct 1551 -188 1551 -188 1551 -219 ct +1551 -219 1551 -219 1607 -219 ct 1607 -219 1607 -219 1607 -267 ct 1607 -267 1607 -267 1648 -267 ct +1648 -267 1648 -267 1648 -219 ct 1648 -219 1648 -219 1747 -219 ct 1747 -219 1747 -219 1747 -188 ct +1747 -188 1747 -188 1648 -188 ct 1648 -188 1648 -188 1648 -74 ct 1648 -61 1649 -53 1650 -48 ct +1652 -43 1655 -39 1661 -35 ct 1670 -29 1683 -26 1701 -26 ct 1718 -26 1735 -28 1752 -31 ct +1752 -31 1752 -31 1752 0 ct p ef +2244 -326 m 2244 -326 2244 -326 2244 -295 ct 2244 -295 2244 -295 2228 -295 ct +2207 -295 2193 -293 2185 -287 ct 2176 -282 2172 -274 2172 -261 ct 2172 -257 2173 -251 2174 -242 ct +2174 -242 2174 -242 2178 -214 ct 2179 -204 2180 -196 2180 -190 ct 2180 -175 2177 -163 2170 -153 ct +2163 -144 2153 -137 2139 -132 ct 2153 -128 2163 -121 2170 -111 ct 2177 -102 2180 -90 2180 -75 ct +2180 -68 2179 -61 2178 -51 ct 2178 -51 2178 -51 2174 -23 ct 2173 -14 2172 -8 2172 -4 ct +2172 9 2176 17 2185 22 ct 2193 27 2207 30 2228 30 ct 2228 30 2228 30 2244 30 ct +2244 30 2244 30 2244 61 ct 2244 61 2244 61 2221 61 ct 2192 61 2170 56 2156 46 ct +2141 36 2134 21 2134 2 ct 2134 -7 2135 -16 2137 -26 ct 2137 -26 2137 -26 2144 -63 ct +2145 -68 2145 -74 2145 -79 ct 2145 -92 2141 -101 2133 -108 ct 2126 -114 2114 -117 2099 -117 ct +2099 -117 2099 -117 2080 -117 ct 2080 -117 2080 -117 2080 -148 ct 2080 -148 2080 -148 2099 -148 ct +2114 -148 2126 -151 2133 -157 ct 2141 -164 2145 -173 2145 -186 ct 2145 -191 2145 -197 2144 -202 ct +2144 -202 2144 -202 2137 -239 ct 2135 -249 2134 -258 2134 -267 ct 2134 -286 2141 -301 2156 -311 ct +2170 -321 2192 -326 2221 -326 ct 2221 -326 2221 -326 2244 -326 ct p ef +pom +gr +gs +pum +3054 6134 t +0.003 0.003 1.000 c 24 82 m 24 82 24 82 24 -224 ct 24 -224 24 -224 85 -224 ct +85 -224 85 -224 83 -182 ct 83 -182 83 -182 85 -182 ct 95 -197 106 -209 117 -217 ct +129 -225 142 -229 156 -229 ct 182 -229 202 -219 218 -198 ct 233 -178 241 -151 241 -117 ct +241 -80 232 -50 215 -28 ct 198 -6 175 5 146 5 ct 134 5 122 3 112 -2 ct 102 -6 93 -13 85 -22 ct +85 -22 85 -22 83 -22 ct 83 -22 83 -22 85 0 ct 85 0 85 0 85 82 ct 85 82 85 82 24 82 ct +p +85 -64 m 92 -56 99 -50 106 -47 ct 113 -43 121 -41 130 -41 ct 145 -41 156 -47 164 -60 ct +171 -72 175 -91 175 -116 ct 175 -135 172 -149 165 -159 ct 158 -168 149 -173 135 -173 ct +127 -173 118 -170 109 -164 ct 101 -158 93 -149 85 -136 ct 85 -136 85 -136 85 -64 ct +p ef +480 -224 m 480 -224 480 -224 480 0 ct 480 0 480 0 419 0 ct 419 0 419 0 420 -22 ct +420 -22 420 -22 422 -43 ct 422 -43 422 -43 419 -43 ct 413 -27 404 -15 392 -7 ct +380 1 365 5 348 5 ct 326 5 309 -1 298 -14 ct 287 -27 281 -46 281 -71 ct 281 -71 281 -71 281 -224 ct +281 -224 281 -224 342 -224 ct 342 -224 342 -224 342 -85 ct 342 -73 344 -65 348 -59 ct +353 -54 359 -51 368 -51 ct 377 -51 386 -54 395 -59 ct 403 -65 411 -73 419 -85 ct +419 -85 419 -85 419 -224 ct 419 -224 419 -224 480 -224 ct p ef +533 0 m 533 0 533 0 533 -326 ct 533 -326 533 -326 594 -326 ct 594 -326 594 -326 594 -224 ct +594 -224 594 -224 592 -182 ct 592 -182 592 -182 594 -182 ct 604 -197 615 -209 626 -217 ct +638 -225 651 -229 665 -229 ct 691 -229 711 -219 727 -198 ct 742 -178 750 -151 750 -117 ct +750 -80 741 -50 724 -28 ct 707 -6 684 5 655 5 ct 643 5 631 3 621 -2 ct 611 -6 602 -13 594 -22 ct +594 -22 594 -22 592 -22 ct 592 -22 592 -22 584 0 ct 584 0 584 0 533 0 ct p +594 -64 m 601 -56 608 -50 615 -47 ct 622 -43 630 -41 639 -41 ct 654 -41 665 -47 673 -60 ct +680 -72 684 -91 684 -116 ct 684 -135 681 -149 674 -159 ct 667 -168 658 -173 644 -173 ct +636 -173 627 -170 618 -164 ct 610 -158 602 -149 594 -136 ct 594 -136 594 -136 594 -64 ct +p ef +864 0 m 864 -285 l 782 -285 l 782 -326 l 925 -326 l 925 0 l 864 0 l +p ef +1138 0 m 1138 -183 l 1056 -183 l 1056 -224 l 1199 -224 l 1199 0 l +1138 0 l p +1138 -265 m 1138 -326 l 1199 -326 l 1199 -265 l 1138 -265 l p ef +1497 -4 m 1472 2 1447 5 1422 5 ct 1381 5 1348 -5 1325 -26 ct 1302 -47 1290 -75 1290 -111 ct +1290 -148 1301 -177 1324 -198 ct 1346 -219 1378 -229 1418 -229 ct 1448 -229 1474 -226 1497 -220 ct +1497 -220 1497 -220 1497 -175 ct 1472 -184 1449 -188 1426 -188 ct 1404 -188 1387 -182 1375 -169 ct +1362 -157 1356 -140 1356 -118 ct 1356 -94 1364 -74 1379 -60 ct 1394 -45 1414 -38 1439 -38 ct +1458 -38 1478 -42 1497 -49 ct 1497 -49 1497 -49 1497 -4 ct p ef +pom +gr +gs +pum +4578 6134 t +97 -163 m 97 -224 l 158 -224 l 158 -163 l 97 -163 l p +97 0 m 97 -61 l 158 -61 l 158 0 l 97 0 l p ef +pom +gr +gs +pum +3054 6625 t +pom +gr +gs +pum +3562 6625 t +0.003 0.003 1.000 c 98 0 m 9 -224 l 75 -224 l 137 -67 l 198 -224 l 247 -224 l +159 0 l 98 0 l p ef +380 5 m 346 5 318 -6 297 -27 ct 276 -49 265 -77 265 -112 ct 265 -148 276 -176 297 -197 ct +318 -218 346 -229 382 -229 ct 417 -229 445 -218 466 -197 ct 487 -176 498 -148 498 -112 ct +498 -76 487 -48 466 -27 ct 445 -6 416 5 380 5 ct p +381 -36 m 398 -36 411 -42 419 -55 ct 428 -68 432 -87 432 -112 ct 432 -138 428 -156 419 -169 ct +411 -182 398 -188 382 -188 ct 365 -188 352 -182 344 -169 ct 335 -156 331 -137 331 -112 ct +331 -87 335 -68 343 -55 ct 352 -42 364 -36 381 -36 ct p ef +630 0 m 630 -183 l 548 -183 l 548 -224 l 691 -224 l 691 0 l 630 0 l +p +630 -265 m 630 -326 l 691 -326 l 691 -265 l 630 -265 l p ef +936 0 m 936 0 936 0 938 -42 ct 938 -42 938 -42 936 -42 ct 926 -27 915 -15 903 -7 ct +892 1 879 5 865 5 ct 839 5 819 -5 803 -26 ct 788 -46 780 -73 780 -107 ct 780 -144 789 -174 806 -196 ct +823 -218 846 -229 875 -229 ct 887 -229 898 -227 908 -222 ct 918 -218 927 -211 936 -203 ct +936 -203 936 -203 938 -203 ct 938 -203 938 -203 936 -224 ct 936 -224 936 -224 936 -326 ct +936 -326 936 -326 997 -326 ct 997 -326 997 -326 997 0 ct 997 0 997 0 936 0 ct p +936 -160 m 929 -168 922 -173 915 -177 ct 908 -181 900 -183 892 -183 ct 876 -183 865 -177 857 -164 ct +850 -152 846 -133 846 -108 ct 846 -89 849 -75 856 -65 ct 863 -56 873 -51 886 -51 ct +895 -51 903 -54 912 -60 ct 920 -66 928 -75 936 -88 ct 936 -88 936 -88 936 -160 ct +p ef +pom +gr +gs +pum +4578 6625 t +346 0 m 346 0 346 0 346 -188 ct 346 -188 346 -188 285 -188 ct 285 -188 285 -188 285 -219 ct +285 -219 285 -219 346 -219 ct 346 -219 346 -219 346 -243 ct 346 -274 353 -297 368 -310 ct +382 -324 406 -331 440 -331 ct 462 -331 482 -328 502 -322 ct 502 -322 502 -322 502 -289 ct +482 -296 462 -300 443 -300 ct 422 -300 408 -296 399 -288 ct 391 -280 387 -267 387 -247 ct +387 -247 387 -247 387 -219 ct 387 -219 387 -219 494 -219 ct 494 -219 494 -219 494 -188 ct +494 -188 494 -188 387 -188 ct 387 -188 387 -188 387 0 ct 387 0 387 0 346 0 ct p ef +732 61 m 687 56 651 36 622 -1 ct 593 -37 579 -81 579 -133 ct 579 -184 593 -228 622 -264 ct +651 -301 687 -321 732 -326 ct 732 -326 732 -326 732 -298 ct 696 -291 668 -273 649 -244 ct +630 -216 620 -178 620 -133 ct 620 -87 630 -49 649 -21 ct 668 8 696 26 732 33 ct +732 33 732 33 732 61 ct p ef +793 61 m 838 56 874 36 903 -1 ct 932 -37 946 -81 946 -133 ct 946 -184 932 -228 903 -264 ct +874 -301 838 -321 793 -326 ct 793 -326 793 -326 793 -298 ct 829 -291 857 -273 876 -244 ct +895 -216 905 -178 905 -133 ct 905 -87 895 -49 876 -21 ct 857 8 829 26 793 33 ct +793 33 793 33 793 61 ct p ef +1482 -326 m 1482 -326 1482 -326 1482 -295 ct 1482 -295 1482 -295 1466 -295 ct +1445 -295 1431 -293 1423 -287 ct 1414 -282 1410 -274 1410 -261 ct 1410 -257 1411 -251 1412 -242 ct +1412 -242 1412 -242 1416 -214 ct 1417 -204 1418 -196 1418 -190 ct 1418 -175 1415 -163 1408 -153 ct +1401 -144 1391 -137 1377 -132 ct 1391 -128 1401 -121 1408 -111 ct 1415 -102 1418 -90 1418 -75 ct +1418 -68 1417 -61 1416 -51 ct 1416 -51 1416 -51 1412 -23 ct 1411 -14 1410 -8 1410 -4 ct +1410 9 1414 17 1423 22 ct 1431 27 1445 30 1466 30 ct 1466 30 1466 30 1482 30 ct +1482 30 1482 30 1482 61 ct 1482 61 1482 61 1459 61 ct 1430 61 1408 56 1394 46 ct +1379 36 1372 21 1372 2 ct 1372 -7 1373 -16 1375 -26 ct 1375 -26 1375 -26 1382 -63 ct +1383 -68 1383 -74 1383 -79 ct 1383 -92 1379 -101 1371 -108 ct 1364 -114 1352 -117 1337 -117 ct +1337 -117 1337 -117 1318 -117 ct 1318 -117 1318 -117 1318 -148 ct 1318 -148 1318 -148 1337 -148 ct +1352 -148 1364 -151 1371 -157 ct 1379 -164 1383 -173 1383 -186 ct 1383 -191 1383 -197 1382 -202 ct +1382 -202 1382 -202 1375 -239 ct 1373 -249 1372 -258 1372 -267 ct 1372 -286 1379 -301 1394 -311 ct +1408 -321 1430 -326 1459 -326 ct 1459 -326 1459 -326 1482 -326 ct p ef +pom +gr +gs +pum +3054 7116 t +pom +gr +gs +pum +4070 7116 t +0.003 0.503 0.003 c 239 -326 m 65 61 l 15 61 l 189 -326 l 239 -326 l +p ef +493 -326 m 319 61 l 269 61 l 443 -326 l 493 -326 l p ef +936 0 m 936 0 936 0 938 -42 ct 938 -42 938 -42 936 -42 ct 926 -27 915 -15 903 -7 ct +892 1 879 5 865 5 ct 839 5 819 -5 803 -26 ct 788 -46 780 -73 780 -107 ct 780 -144 789 -174 806 -196 ct +823 -218 846 -229 875 -229 ct 887 -229 898 -227 908 -222 ct 918 -218 927 -211 936 -203 ct +936 -203 936 -203 938 -203 ct 938 -203 938 -203 936 -224 ct 936 -224 936 -224 936 -326 ct +936 -326 936 -326 997 -326 ct 997 -326 997 -326 997 0 ct 997 0 997 0 936 0 ct p +936 -160 m 929 -168 922 -173 915 -177 ct 908 -181 900 -183 892 -183 ct 876 -183 865 -177 857 -164 ct +850 -152 846 -133 846 -108 ct 846 -89 849 -75 856 -65 ct 863 -56 873 -51 886 -51 ct +895 -51 903 -54 912 -60 ct 920 -66 928 -75 936 -88 ct 936 -88 936 -88 936 -160 ct +p ef +1142 5 m 1108 5 1080 -6 1059 -27 ct 1038 -49 1027 -77 1027 -112 ct 1027 -148 1038 -176 1059 -197 ct +1080 -218 1108 -229 1144 -229 ct 1179 -229 1207 -218 1228 -197 ct 1249 -176 1260 -148 1260 -112 ct +1260 -76 1249 -48 1228 -27 ct 1207 -6 1178 5 1142 5 ct p +1143 -36 m 1160 -36 1173 -42 1181 -55 ct 1190 -68 1194 -87 1194 -112 ct 1194 -138 1190 -156 1181 -169 ct +1173 -182 1160 -188 1144 -188 ct 1127 -188 1114 -182 1106 -169 ct 1097 -156 1093 -137 1093 -112 ct +1093 -87 1097 -68 1105 -55 ct 1114 -42 1126 -36 1143 -36 ct p ef +1557 -8 m 1557 -8 1557 -8 1557 -54 ct 1591 -42 1619 -36 1639 -36 ct 1654 -36 1665 -38 1673 -42 ct +1680 -46 1684 -52 1684 -60 ct 1684 -64 1682 -68 1678 -72 ct 1675 -75 1669 -79 1662 -82 ct +1662 -82 1662 -82 1614 -101 ct 1595 -109 1581 -118 1572 -127 ct 1563 -137 1558 -148 1558 -161 ct +1558 -182 1568 -199 1587 -211 ct 1606 -223 1633 -229 1667 -229 ct 1687 -229 1710 -226 1736 -221 ct +1736 -221 1736 -221 1736 -174 ct 1708 -183 1684 -188 1665 -188 ct 1650 -188 1640 -186 1633 -183 ct +1626 -180 1622 -175 1622 -169 ct 1622 -165 1625 -162 1630 -158 ct 1635 -154 1642 -150 1652 -146 ct +1652 -146 1652 -146 1705 -124 ct 1721 -118 1733 -110 1740 -100 ct 1748 -91 1752 -79 1752 -66 ct +1752 -45 1743 -28 1724 -15 ct 1705 -2 1681 5 1651 5 ct 1625 5 1593 1 1557 -8 ct +p ef +1904 5 m 1870 5 1842 -6 1821 -27 ct 1800 -49 1789 -77 1789 -112 ct 1789 -148 1800 -176 1821 -197 ct +1842 -218 1870 -229 1906 -229 ct 1941 -229 1969 -218 1990 -197 ct 2011 -176 2022 -148 2022 -112 ct +2022 -76 2011 -48 1990 -27 ct 1969 -6 1940 5 1904 5 ct p +1905 -36 m 1922 -36 1935 -42 1943 -55 ct 1952 -68 1956 -87 1956 -112 ct 1956 -138 1952 -156 1943 -169 ct +1935 -182 1922 -188 1906 -188 ct 1889 -188 1876 -182 1868 -169 ct 1859 -156 1855 -137 1855 -112 ct +1855 -87 1859 -68 1867 -55 ct 1876 -42 1888 -36 1905 -36 ct p ef +2185 0 m 2185 0 2185 0 2134 0 ct 2134 0 2134 0 2134 -149 ct 2134 -157 2133 -163 2132 -167 ct +2130 -171 2128 -173 2125 -173 ct 2120 -173 2116 -171 2112 -166 ct 2108 -161 2105 -154 2101 -145 ct +2101 -145 2101 -145 2101 0 ct 2101 0 2101 0 2050 0 ct 2050 0 2050 0 2050 -224 ct +2050 -224 2050 -224 2101 -224 ct 2101 -224 2101 -224 2098 -181 ct 2098 -181 2098 -181 2101 -181 ct +2106 -197 2113 -209 2121 -217 ct 2129 -225 2138 -229 2148 -229 ct 2159 -229 2168 -225 2174 -217 ct +2180 -209 2184 -197 2185 -181 ct 2185 -181 2185 -181 2187 -181 ct 2192 -197 2198 -209 2205 -217 ct +2213 -225 2221 -229 2231 -229 ct 2245 -229 2255 -223 2261 -212 ct 2266 -200 2269 -179 2269 -150 ct +2269 -150 2269 -150 2269 0 ct 2269 0 2269 0 2218 0 ct 2218 0 2218 0 2218 -149 ct +2218 -157 2217 -163 2216 -167 ct 2214 -171 2212 -173 2209 -173 ct 2204 -173 2200 -171 2196 -166 ct +2193 -161 2189 -154 2185 -145 ct 2185 -145 2185 -145 2185 0 ct p ef +2522 -95 m 2522 -95 2522 -95 2370 -95 ct 2373 -77 2381 -63 2393 -54 ct 2405 -45 2421 -41 2442 -41 ct +2466 -41 2493 -46 2522 -56 ct 2522 -56 2522 -56 2522 -9 ct 2487 0 2456 5 2430 5 ct +2392 5 2361 -6 2338 -27 ct 2315 -48 2304 -76 2304 -111 ct 2304 -147 2315 -175 2336 -197 ct +2358 -218 2386 -229 2421 -229 ct 2453 -229 2477 -219 2495 -199 ct 2513 -180 2522 -152 2522 -118 ct +2522 -118 2522 -118 2522 -95 ct p +2369 -136 m 2369 -136 2369 -136 2463 -136 ct 2463 -153 2459 -166 2452 -175 ct +2444 -184 2433 -188 2418 -188 ct 2404 -188 2392 -184 2384 -175 ct 2376 -166 2371 -153 2369 -136 ct +p ef +2768 -6 m 2744 1 2722 5 2704 5 ct 2675 5 2654 -1 2640 -14 ct 2626 -26 2619 -45 2619 -70 ct +2619 -70 2619 -70 2619 -178 ct 2619 -178 2619 -178 2571 -178 ct 2571 -178 2571 -178 2571 -219 ct +2571 -219 2571 -219 2619 -219 ct 2619 -219 2619 -219 2619 -285 ct 2619 -285 2619 -285 2680 -285 ct +2680 -285 2680 -285 2680 -219 ct 2680 -219 2680 -219 2763 -219 ct 2763 -219 2763 -219 2763 -178 ct +2763 -178 2763 -178 2680 -178 ct 2680 -178 2680 -178 2680 -84 ct 2680 -68 2683 -57 2689 -51 ct +2695 -44 2705 -41 2719 -41 ct 2736 -41 2752 -44 2768 -51 ct 2768 -51 2768 -51 2768 -6 ct +p ef +2823 0 m 2823 0 2823 0 2823 -326 ct 2823 -326 2823 -326 2884 -326 ct 2884 -326 2884 -326 2884 -224 ct +2884 -224 2884 -224 2882 -181 ct 2882 -181 2882 -181 2884 -181 ct 2891 -197 2900 -209 2912 -217 ct +2924 -225 2938 -229 2956 -229 ct 2978 -229 2994 -223 3005 -210 ct 3016 -197 3022 -178 3022 -153 ct +3022 -153 3022 -153 3022 0 ct 3022 0 3022 0 2961 0 ct 2961 0 2961 0 2961 -139 ct +2961 -150 2959 -159 2955 -165 ct 2950 -170 2944 -173 2935 -173 ct 2926 -173 2917 -170 2908 -165 ct +2900 -159 2891 -151 2884 -139 ct 2884 -139 2884 -139 2884 0 ct 2884 0 2884 0 2823 0 ct +p ef +3170 0 m 3170 -183 l 3088 -183 l 3088 -224 l 3231 -224 l 3231 0 l +3170 0 l p +3170 -265 m 3170 -326 l 3231 -326 l 3231 -265 l 3170 -265 l p ef +3331 0 m 3331 0 3331 0 3331 -224 ct 3331 -224 3331 -224 3392 -224 ct 3392 -224 3392 -224 3391 -202 ct +3391 -202 3391 -202 3390 -181 ct 3390 -181 3390 -181 3392 -181 ct 3399 -197 3408 -209 3420 -217 ct +3432 -225 3446 -229 3464 -229 ct 3486 -229 3502 -223 3513 -210 ct 3524 -197 3530 -178 3530 -153 ct +3530 -153 3530 -153 3530 0 ct 3530 0 3530 0 3469 0 ct 3469 0 3469 0 3469 -139 ct +3469 -150 3467 -159 3463 -165 ct 3458 -170 3452 -173 3443 -173 ct 3434 -173 3425 -170 3416 -165 ct +3408 -159 3399 -151 3392 -139 ct 3392 -139 3392 -139 3392 0 ct 3392 0 3392 0 3331 0 ct +p ef +3596 69 m 3596 69 3596 69 3602 25 ct 3634 38 3660 44 3680 44 ct 3698 44 3711 39 3719 30 ct +3728 21 3732 7 3732 -11 ct 3732 -11 3732 -11 3733 -53 ct 3733 -53 3733 -53 3731 -53 ct +3723 -35 3713 -22 3702 -13 ct 3690 -4 3676 0 3660 0 ct 3634 0 3613 -10 3598 -31 ct +3582 -51 3574 -78 3574 -111 ct 3574 -147 3583 -175 3600 -197 ct 3618 -218 3641 -229 3670 -229 ct +3682 -229 3692 -227 3702 -223 ct 3712 -218 3721 -212 3730 -204 ct 3730 -204 3730 -204 3735 -204 ct +3735 -204 3735 -204 3740 -224 ct 3740 -224 3740 -224 3791 -224 ct 3791 -224 3791 -224 3791 -27 ct +3791 10 3782 38 3764 58 ct 3747 77 3721 87 3688 87 ct 3662 87 3631 81 3596 69 ct +p +3730 -95 m 3730 -95 3730 -95 3730 -163 ct 3722 -169 3714 -174 3706 -178 ct +3699 -181 3692 -183 3685 -183 ct 3670 -183 3659 -177 3651 -166 ct 3644 -155 3640 -138 3640 -116 ct +3640 -97 3643 -83 3650 -73 ct 3657 -64 3666 -59 3680 -59 ct 3689 -59 3698 -62 3707 -68 ct +3715 -74 3723 -83 3730 -95 ct p ef +pom +gr +gs +pum +3054 7607 t +pom +gr +gs +pum +3562 7607 t +43 -326 m 43 -326 43 -326 43 -295 ct 43 -295 43 -295 59 -295 ct 80 -295 94 -293 102 -287 ct +111 -282 115 -274 115 -261 ct 115 -257 114 -251 113 -242 ct 113 -242 113 -242 109 -214 ct +108 -204 107 -196 107 -190 ct 107 -175 110 -163 117 -153 ct 124 -144 134 -137 148 -132 ct +134 -128 124 -121 117 -111 ct 110 -102 107 -90 107 -75 ct 107 -68 108 -61 109 -51 ct +109 -51 109 -51 113 -23 ct 114 -14 115 -8 115 -4 ct 115 9 111 17 102 22 ct 94 27 80 30 59 30 ct +59 30 59 30 43 30 ct 43 30 43 30 43 61 ct 43 61 43 61 66 61 ct 95 61 117 56 131 46 ct +146 36 153 21 153 2 ct 153 -7 152 -16 150 -26 ct 150 -26 150 -26 143 -63 ct 142 -68 142 -74 142 -79 ct +142 -92 146 -101 154 -108 ct 161 -114 173 -117 188 -117 ct 188 -117 188 -117 207 -117 ct +207 -117 207 -117 207 -148 ct 207 -148 207 -148 188 -148 ct 173 -148 161 -151 154 -157 ct +146 -164 142 -173 142 -186 ct 142 -191 142 -197 143 -202 ct 143 -202 143 -202 150 -239 ct +152 -249 153 -258 153 -267 ct 153 -286 146 -301 131 -311 ct 117 -321 95 -326 66 -326 ct +66 -326 66 -326 43 -326 ct p ef +pom +gr +gs +pum +3054 8301 t +43 -326 m 43 -326 43 -326 43 -295 ct 43 -295 43 -295 59 -295 ct 80 -295 94 -293 102 -287 ct +111 -282 115 -274 115 -261 ct 115 -257 114 -251 113 -242 ct 113 -242 113 -242 109 -214 ct +108 -204 107 -196 107 -190 ct 107 -175 110 -163 117 -153 ct 124 -144 134 -137 148 -132 ct +134 -128 124 -121 117 -111 ct 110 -102 107 -90 107 -75 ct 107 -68 108 -61 109 -51 ct +109 -51 109 -51 113 -23 ct 114 -14 115 -8 115 -4 ct 115 9 111 17 102 22 ct 94 27 80 30 59 30 ct +59 30 59 30 43 30 ct 43 30 43 30 43 61 ct 43 61 43 61 66 61 ct 95 61 117 56 131 46 ct +146 36 153 21 153 2 ct 153 -7 152 -16 150 -26 ct 150 -26 150 -26 143 -63 ct 142 -68 142 -74 142 -79 ct +142 -92 146 -101 154 -108 ct 161 -114 173 -117 188 -117 ct 188 -117 188 -117 207 -117 ct +207 -117 207 -117 207 -148 ct 207 -148 207 -148 188 -148 ct 173 -148 161 -151 154 -157 ct +146 -164 142 -173 142 -186 ct 142 -191 142 -197 143 -202 ct 143 -202 143 -202 150 -239 ct +152 -249 153 -258 153 -267 ct 153 -286 146 -301 131 -311 ct 117 -321 95 -326 66 -326 ct +66 -326 66 -326 43 -326 ct p ef +351 66 m 351 66 351 66 351 46 ct 358 45 364 41 368 33 ct 373 25 375 14 376 0 ct +376 0 376 0 351 0 ct 351 0 351 0 351 -61 ct 351 -61 351 -61 412 -61 ct 412 -61 412 -61 412 -24 ct +412 5 407 27 397 42 ct 387 57 371 65 351 66 ct p +351 -163 m 351 -224 l 412 -224 l 412 -163 l 351 -163 l p ef +pom +gr +gs +pum +3562 8301 t +pom +gr +gr +0.503 0.503 0.503 c 4064 9280 m 3002 9280 l 3002 8605 l 5126 8605 l +5126 9280 l 4064 9280 l p ef +4064 9280 m 3002 9280 l 3002 8605 l 5126 8605 l 5126 9280 l 4064 9280 l +pc +0.753 0.753 0.753 c 3964 9180 m 2902 9180 l 2902 8505 l 5026 8505 l +5026 9180 l 3964 9180 l p ef +0.003 0.003 0.003 c 3964 9180 m 2902 9180 l 2902 8505 l 5026 8505 l 5026 9180 l +3964 9180 l pc +gs +gs +pum +3133 8986 t +1.000 1.000 1.000 c 248 -242 m 158 -242 l 158 0 l 99 0 l 99 -242 l +9 -242 l 9 -291 l 248 -291 l 248 -242 l p ef +472 0 m 472 0 472 0 413 0 ct 409 -9 407 -17 407 -25 ct 388 -5 365 5 338 5 ct 318 5 302 -1 291 -13 ct +280 -24 274 -40 274 -59 ct 274 -73 278 -85 285 -95 ct 293 -106 304 -114 319 -120 ct +334 -127 351 -131 372 -132 ct 372 -132 372 -132 407 -135 ct 407 -135 407 -135 407 -139 ct +407 -163 393 -175 366 -175 ct 358 -175 347 -173 333 -170 ct 319 -166 307 -162 297 -157 ct +297 -157 297 -157 283 -198 ct 296 -204 312 -210 329 -214 ct 347 -218 362 -220 376 -220 ct +405 -220 427 -213 442 -199 ct 457 -185 464 -165 464 -138 ct 464 -138 464 -138 464 -51 ct +464 -31 467 -14 472 0 ct p +407 -66 m 407 -66 407 -66 407 -101 ct 383 -99 368 -97 362 -96 ct 357 -95 351 -93 344 -89 ct +338 -86 334 -82 331 -77 ct 328 -72 326 -67 326 -61 ct 326 -54 328 -49 333 -45 ct +337 -40 343 -38 350 -38 ct 371 -38 390 -47 407 -66 ct p ef +662 -211 m 662 -211 662 -211 652 -159 ct 646 -163 640 -165 633 -165 ct 626 -165 619 -163 613 -158 ct +606 -153 599 -145 592 -134 ct 585 -123 582 -116 582 -114 ct 582 -114 582 -114 582 0 ct +582 0 582 0 525 0 ct 525 0 525 0 525 -215 ct 525 -215 525 -215 582 -215 ct 582 -215 582 -215 582 -172 ct +590 -190 598 -202 606 -209 ct 614 -216 624 -220 635 -220 ct 646 -220 655 -217 662 -211 ct +p ef +888 -9 m 888 23 878 47 858 64 ct 839 81 811 89 775 89 ct 743 89 713 81 687 65 ct +687 65 687 65 703 22 ct 727 35 750 42 774 42 ct 792 42 806 38 816 29 ct 826 21 831 8 831 -7 ct +831 -7 831 -7 831 -22 ct 814 -4 793 5 767 5 ct 741 5 719 -5 702 -25 ct 685 -45 676 -71 676 -105 ct +676 -141 685 -169 702 -189 ct 719 -210 742 -220 770 -220 ct 781 -220 793 -218 804 -213 ct +815 -209 824 -203 831 -195 ct 831 -195 831 -195 831 -219 ct 831 -219 831 -219 888 -219 ct +888 -219 888 -219 888 -9 ct p +831 -71 m 831 -71 831 -71 831 -146 ct 818 -163 802 -171 782 -171 ct 768 -171 757 -165 748 -154 ct +739 -142 735 -126 735 -106 ct 735 -87 739 -71 748 -60 ct 757 -50 768 -44 782 -44 ct +801 -44 817 -53 831 -71 ct p ef +1140 -20 m 1115 -3 1086 5 1054 5 ct 1018 5 989 -5 967 -26 ct 946 -46 935 -74 935 -108 ct +935 -142 945 -169 964 -189 ct 983 -210 1009 -220 1041 -220 ct 1070 -220 1094 -210 1112 -191 ct +1131 -171 1140 -144 1140 -109 ct 1140 -109 1140 -109 1140 -95 ct 1140 -95 1140 -95 994 -95 ct +996 -80 1003 -68 1014 -59 ct 1025 -49 1039 -44 1055 -44 ct 1080 -44 1105 -51 1130 -65 ct +1130 -65 1130 -65 1140 -20 ct p +1085 -133 m 1083 -147 1078 -158 1070 -167 ct 1062 -175 1053 -179 1041 -179 ct +1029 -179 1018 -175 1010 -167 ct 1001 -158 996 -147 994 -133 ct 994 -133 994 -133 1085 -133 ct +p ef +1301 -5 m 1289 2 1276 5 1262 5 ct 1239 5 1221 -1 1209 -13 ct 1197 -25 1191 -43 1191 -66 ct +1191 -66 1191 -66 1191 -171 ct 1191 -171 1191 -171 1161 -171 ct 1161 -171 1161 -171 1161 -215 ct +1161 -215 1161 -215 1191 -215 ct 1191 -215 1191 -215 1191 -282 ct 1191 -282 1191 -282 1248 -282 ct +1248 -282 1248 -282 1248 -215 ct 1248 -215 1248 -215 1290 -215 ct 1290 -215 1290 -215 1290 -171 ct +1290 -171 1290 -171 1248 -171 ct 1248 -171 1248 -171 1248 -75 ct 1248 -65 1250 -58 1254 -52 ct +1258 -47 1263 -44 1269 -44 ct 1277 -44 1284 -46 1292 -49 ct 1292 -49 1292 -49 1301 -5 ct +p ef +1353 -66 m 1363 -66 1372 -63 1379 -56 ct 1386 -49 1389 -41 1389 -31 ct 1389 -21 1386 -12 1379 -5 ct +1372 2 1363 5 1353 5 ct 1343 5 1335 2 1328 -5 ct 1321 -12 1318 -20 1318 -31 ct +1318 -41 1321 -49 1328 -56 ct 1335 -63 1343 -66 1353 -66 ct p ef +1643 0 m 1643 0 1643 0 1586 0 ct 1586 0 1586 0 1586 -125 ct 1586 -156 1575 -171 1553 -171 ct +1534 -171 1516 -160 1501 -139 ct 1501 -139 1501 -139 1501 0 ct 1501 0 1501 0 1444 0 ct +1444 0 1444 0 1444 -307 ct 1444 -307 1444 -307 1501 -307 ct 1501 -307 1501 -307 1501 -188 ct +1519 -209 1542 -220 1570 -220 ct 1592 -220 1610 -213 1623 -200 ct 1636 -187 1643 -168 1643 -144 ct +1643 -144 1643 -144 1643 0 ct p ef +pom +gr +gr +0.503 0.503 0.503 c 14611 8636 m 10090 8636 l 10090 1060 l 19133 1060 l +19133 8636 l 14611 8636 l p ef +14611 8636 m 10090 8636 l 10090 1060 l 19133 1060 l 19133 8636 l 14611 8636 l +pc +1.000 0.902 0.777 c 14511 8536 m 9990 8536 l 9990 960 l 19033 960 l +19033 8536 l 14511 8536 l p ef +0.003 0.003 0.003 c 14511 8536 m 9990 8536 l 9990 960 l 19033 960 l 19033 8536 l +14511 8536 l pc +gs +gs +pum +10435 1594 t +35 0 m 58 -93 l 11 -93 l 18 -124 l 66 -124 l 80 -184 l 33 -184 l +41 -215 l 88 -215 l 111 -306 l 142 -306 l 120 -215 l 168 -215 l 191 -306 l +222 -306 l 200 -215 l 246 -215 l 239 -184 l 192 -184 l 177 -124 l +224 -124 l 216 -93 l 169 -93 l 146 0 l 115 0 l 138 -93 l 89 -93 l +66 0 l 35 0 l p +97 -124 m 146 -124 l 160 -184 l 112 -184 l 97 -124 l p ef +371 0 m 371 -193 l 289 -193 l 289 -224 l 412 -224 l 412 0 l 371 0 l +p +366 -275 m 366 -326 l 417 -326 l 417 -275 l 366 -275 l p ef +545 0 m 545 0 545 0 545 -224 ct 545 -224 545 -224 586 -224 ct 586 -224 586 -224 584 -182 ct +584 -182 584 -182 586 -182 ct 596 -198 607 -209 620 -217 ct 632 -225 647 -229 663 -229 ct +684 -229 700 -223 711 -210 ct 722 -197 727 -178 727 -153 ct 727 -153 727 -153 727 0 ct +727 0 727 0 686 0 ct 686 0 686 0 686 -142 ct 686 -159 683 -172 678 -179 ct 672 -186 663 -190 650 -190 ct +640 -190 630 -186 619 -179 ct 608 -172 597 -161 586 -146 ct 586 -146 586 -146 586 0 ct +586 0 586 0 545 0 ct p ef +990 -7 m 966 1 942 5 918 5 ct 879 5 849 -5 828 -26 ct 807 -46 796 -75 796 -112 ct +796 -149 806 -177 827 -198 ct 848 -219 877 -229 914 -229 ct 938 -229 962 -225 986 -218 ct +986 -218 986 -218 986 -184 ct 959 -193 937 -198 918 -198 ct 894 -198 874 -190 860 -175 ct +846 -160 839 -139 839 -112 ct 839 -85 846 -64 861 -49 ct 876 -34 897 -26 923 -26 ct +943 -26 965 -31 990 -40 ct 990 -40 990 -40 990 -7 ct p ef +1138 0 m 1138 -295 l 1051 -295 l 1051 -326 l 1179 -326 l 1179 0 l +1138 0 l p ef +1488 -224 m 1488 -224 1488 -224 1488 0 ct 1488 0 1488 0 1447 0 ct 1447 0 1447 0 1449 -42 ct +1449 -42 1449 -42 1447 -42 ct 1438 -26 1426 -15 1414 -7 ct 1401 1 1386 5 1370 5 ct +1349 5 1333 -1 1322 -14 ct 1311 -27 1306 -46 1306 -71 ct 1306 -71 1306 -71 1306 -224 ct +1306 -224 1306 -224 1347 -224 ct 1347 -224 1347 -224 1347 -82 ct 1347 -65 1350 -52 1355 -45 ct +1361 -38 1370 -34 1383 -34 ct 1393 -34 1403 -38 1414 -45 ct 1425 -52 1436 -63 1447 -78 ct +1447 -78 1447 -78 1447 -224 ct 1447 -224 1447 -224 1488 -224 ct p ef +1706 0 m 1706 0 1706 0 1708 -42 ct 1708 -42 1708 -42 1706 -42 ct 1696 -26 1685 -15 1673 -7 ct +1660 1 1647 5 1632 5 ct 1607 5 1587 -5 1572 -24 ct 1557 -44 1550 -71 1550 -105 ct +1550 -142 1559 -172 1576 -195 ct 1594 -218 1616 -229 1644 -229 ct 1656 -229 1668 -226 1678 -221 ct +1688 -216 1698 -209 1706 -198 ct 1706 -198 1706 -198 1708 -198 ct 1708 -198 1708 -198 1706 -229 ct +1706 -229 1706 -229 1706 -326 ct 1706 -326 1706 -326 1747 -326 ct 1747 -326 1747 -326 1747 0 ct +1747 0 1747 0 1706 0 ct p +1706 -168 m 1696 -178 1687 -185 1678 -190 ct 1668 -195 1659 -198 1650 -198 ct +1632 -198 1618 -190 1608 -175 ct 1598 -159 1593 -137 1593 -109 ct 1593 -83 1597 -63 1605 -50 ct +1613 -38 1624 -31 1640 -31 ct 1652 -31 1663 -35 1674 -42 ct 1685 -49 1696 -59 1706 -73 ct +1706 -73 1706 -73 1706 -168 ct p ef +2004 -9 m 1976 0 1950 5 1926 5 ct 1888 5 1859 -5 1838 -25 ct 1817 -45 1807 -73 1807 -110 ct +1807 -144 1817 -173 1837 -195 ct 1857 -218 1882 -229 1913 -229 ct 1944 -229 1966 -220 1981 -201 ct +1996 -182 2003 -153 2003 -114 ct 2003 -114 2003 -114 2003 -101 ct 2003 -101 2003 -101 1849 -101 ct +1850 -76 1858 -57 1872 -45 ct 1886 -32 1905 -26 1931 -26 ct 1954 -26 1978 -31 2004 -42 ct +2004 -42 2004 -42 2004 -9 ct p +1850 -132 m 1850 -132 1850 -132 1960 -132 ct 1960 -132 1960 -132 1960 -138 ct +1960 -158 1956 -173 1947 -183 ct 1938 -193 1926 -198 1909 -198 ct 1892 -198 1879 -192 1868 -181 ct +1858 -169 1852 -153 1850 -132 ct p ef +2337 -214 m 2337 -214 2337 -214 2337 -260 ct 2337 -282 2341 -298 2350 -309 ct +2358 -320 2371 -326 2388 -326 ct 2388 -326 2388 -326 2388 -306 ct 2381 -306 2375 -303 2371 -298 ct +2368 -293 2366 -286 2366 -276 ct 2366 -276 2366 -276 2366 -265 ct 2366 -265 2366 -265 2388 -265 ct +2388 -265 2388 -265 2388 -214 ct 2388 -214 2388 -214 2337 -214 ct p +2439 -214 m 2439 -214 2439 -214 2439 -260 ct 2439 -282 2443 -298 2452 -309 ct +2460 -320 2473 -326 2490 -326 ct 2490 -326 2490 -326 2490 -306 ct 2483 -306 2477 -303 2473 -298 ct +2470 -293 2468 -286 2468 -276 ct 2468 -276 2468 -276 2468 -265 ct 2468 -265 2468 -265 2490 -265 ct +2490 -265 2490 -265 2490 -214 ct 2490 -214 2490 -214 2439 -214 ct p ef +2567 0 m 2567 0 2567 0 2567 -306 ct 2567 -306 2567 -306 2647 -306 ct 2691 -306 2724 -294 2746 -269 ct +2768 -244 2779 -207 2779 -158 ct 2779 -105 2767 -66 2743 -39 ct 2719 -13 2684 0 2636 0 ct +2636 0 2636 0 2567 0 ct p +2608 -31 m 2608 -31 2608 -31 2628 -31 ct 2667 -31 2695 -41 2711 -60 ct 2728 -79 2736 -111 2736 -155 ct +2736 -204 2725 -238 2703 -257 ct 2689 -269 2664 -275 2627 -275 ct 2627 -275 2627 -275 2608 -275 ct +2608 -275 2608 -275 2608 -31 ct p ef +3012 -224 m 3012 -224 3012 -224 3012 0 ct 3012 0 3012 0 2971 0 ct 2971 0 2971 0 2973 -42 ct +2973 -42 2973 -42 2971 -42 ct 2962 -26 2950 -15 2938 -7 ct 2925 1 2910 5 2894 5 ct +2873 5 2857 -1 2846 -14 ct 2835 -27 2830 -46 2830 -71 ct 2830 -71 2830 -71 2830 -224 ct +2830 -224 2830 -224 2871 -224 ct 2871 -224 2871 -224 2871 -82 ct 2871 -65 2874 -52 2879 -45 ct +2885 -38 2894 -34 2907 -34 ct 2917 -34 2927 -38 2938 -45 ct 2949 -52 2960 -63 2971 -78 ct +2971 -78 2971 -78 2971 -224 ct 2971 -224 2971 -224 3012 -224 ct p ef +3067 0 m 3067 0 3067 0 3067 -224 ct 3067 -224 3067 -224 3103 -224 ct 3103 -224 3103 -224 3100 -182 ct +3100 -182 3100 -182 3103 -182 ct 3111 -198 3120 -209 3129 -217 ct 3137 -225 3145 -229 3153 -229 ct +3164 -229 3172 -225 3179 -216 ct 3186 -208 3190 -196 3191 -182 ct 3191 -182 3191 -182 3194 -182 ct +3201 -198 3209 -209 3217 -217 ct 3226 -225 3235 -229 3245 -229 ct 3258 -229 3268 -224 3275 -213 ct +3282 -202 3285 -186 3285 -164 ct 3285 -164 3285 -164 3285 0 ct 3285 0 3285 0 3249 0 ct +3249 0 3249 0 3249 -162 ct 3249 -172 3248 -180 3246 -185 ct 3244 -190 3240 -193 3236 -193 ct +3230 -193 3223 -189 3216 -181 ct 3209 -173 3201 -160 3194 -144 ct 3194 -144 3194 -144 3194 0 ct +3194 0 3194 0 3158 0 ct 3158 0 3158 0 3158 -155 ct 3158 -167 3157 -177 3155 -183 ct +3152 -190 3149 -193 3145 -193 ct 3139 -193 3132 -188 3124 -179 ct 3116 -170 3109 -158 3103 -144 ct +3103 -144 3103 -144 3103 0 ct 3103 0 3103 0 3067 0 ct p ef +3339 82 m 3339 82 3339 82 3339 -224 ct 3339 -224 3339 -224 3380 -224 ct 3380 -224 3380 -224 3378 -182 ct +3378 -182 3378 -182 3380 -182 ct 3390 -198 3401 -209 3413 -217 ct 3425 -225 3439 -229 3453 -229 ct +3478 -229 3498 -219 3513 -200 ct 3528 -180 3535 -153 3535 -120 ct 3535 -82 3526 -52 3509 -29 ct +3492 -6 3469 5 3441 5 ct 3429 5 3418 2 3408 -3 ct 3398 -8 3388 -15 3380 -26 ct +3380 -26 3380 -26 3378 -26 ct 3378 -26 3378 -26 3380 5 ct 3380 5 3380 5 3380 82 ct +3380 82 3380 82 3339 82 ct p +3380 -56 m 3389 -46 3399 -39 3408 -34 ct 3417 -29 3426 -26 3436 -26 ct 3454 -26 3467 -34 3477 -49 ct +3487 -65 3492 -87 3492 -115 ct 3492 -141 3488 -160 3480 -173 ct 3472 -186 3461 -193 3445 -193 ct +3434 -193 3422 -189 3411 -182 ct 3401 -175 3390 -165 3380 -151 ct 3380 -151 3380 -151 3380 -56 ct +p ef +3653 0 m 3653 -61 l 3714 -61 l 3714 0 l 3653 0 l p ef +3982 -26 m 3958 -5 3933 5 3909 5 ct 3888 5 3871 -1 3858 -13 ct 3845 -24 3838 -39 3838 -57 ct +3838 -81 3848 -99 3869 -114 ct 3890 -128 3917 -135 3951 -135 ct 3951 -135 3951 -135 3976 -135 ct +3976 -135 3976 -135 3976 -154 ct 3976 -169 3972 -180 3965 -187 ct 3957 -194 3946 -198 3931 -198 ct +3907 -198 3882 -191 3857 -177 ct 3857 -177 3857 -177 3857 -213 ct 3886 -224 3913 -229 3939 -229 ct +3968 -229 3988 -223 3999 -212 ct 4011 -201 4017 -181 4017 -153 ct 4017 -153 4017 -153 4017 -59 ct +4017 -45 4018 -36 4021 -31 ct 4024 -26 4030 -24 4037 -24 ct 4040 -24 4044 -25 4050 -26 ct +4050 -26 4050 -26 4054 -2 ct 4040 3 4030 5 4023 5 ct 4013 5 4004 2 3998 -3 ct 3991 -8 3986 -16 3982 -26 ct +p +3976 -53 m 3976 -53 3976 -53 3976 -110 ct 3976 -110 3976 -110 3964 -110 ct +3936 -110 3915 -106 3901 -99 ct 3887 -91 3880 -80 3880 -64 ct 3880 -52 3883 -43 3890 -37 ct +3896 -31 3906 -28 3919 -28 ct 3937 -28 3956 -36 3976 -53 ct p ef +4101 0 m 4101 0 4101 0 4101 -326 ct 4101 -326 4101 -326 4142 -326 ct 4142 -326 4142 -326 4142 -224 ct +4142 -224 4142 -224 4140 -182 ct 4140 -182 4140 -182 4142 -182 ct 4152 -198 4163 -209 4176 -217 ct +4188 -225 4203 -229 4219 -229 ct 4240 -229 4256 -223 4267 -210 ct 4278 -197 4283 -178 4283 -153 ct +4283 -153 4283 -153 4283 0 ct 4283 0 4283 0 4242 0 ct 4242 0 4242 0 4242 -142 ct +4242 -159 4239 -172 4234 -179 ct 4228 -186 4219 -190 4206 -190 ct 4196 -190 4186 -186 4175 -179 ct +4164 -172 4153 -161 4142 -146 ct 4142 -146 4142 -146 4142 0 ct 4142 0 4142 0 4101 0 ct +p ef +4369 -214 m 4369 -214 4369 -214 4369 -260 ct 4369 -282 4373 -298 4382 -309 ct +4390 -320 4403 -326 4420 -326 ct 4420 -326 4420 -326 4420 -306 ct 4413 -306 4407 -303 4403 -298 ct +4400 -293 4398 -286 4398 -276 ct 4398 -276 4398 -276 4398 -265 ct 4398 -265 4398 -265 4420 -265 ct +4420 -265 4420 -265 4420 -214 ct 4420 -214 4420 -214 4369 -214 ct p +4471 -214 m 4471 -214 4471 -214 4471 -260 ct 4471 -282 4475 -298 4484 -309 ct +4492 -320 4505 -326 4522 -326 ct 4522 -326 4522 -326 4522 -306 ct 4515 -306 4509 -303 4505 -298 ct +4502 -293 4500 -286 4500 -276 ct 4500 -276 4500 -276 4500 -265 ct 4500 -265 4500 -265 4522 -265 ct +4522 -265 4522 -265 4522 -214 ct 4522 -214 4522 -214 4471 -214 ct p ef +pom +gr +gs +pum +15515 1594 t +0.003 0.503 0.003 c 239 -326 m 65 61 l 15 61 l 189 -326 l 239 -326 l +p ef +493 -326 m 319 61 l 269 61 l 443 -326 l 493 -326 l p ef +990 -6 m 966 1 944 5 926 5 ct 897 5 876 -1 862 -14 ct 848 -26 841 -45 841 -70 ct +841 -70 841 -70 841 -178 ct 841 -178 841 -178 793 -178 ct 793 -178 793 -178 793 -219 ct +793 -219 793 -219 841 -219 ct 841 -219 841 -219 841 -285 ct 841 -285 841 -285 902 -285 ct +902 -285 902 -285 902 -219 ct 902 -219 902 -219 985 -219 ct 985 -219 985 -219 985 -178 ct +985 -178 985 -178 902 -178 ct 902 -178 902 -178 902 -84 ct 902 -68 905 -57 911 -51 ct +917 -44 927 -41 941 -41 ct 958 -41 974 -44 990 -51 ct 990 -51 990 -51 990 -6 ct +p ef +1045 0 m 1045 0 1045 0 1045 -326 ct 1045 -326 1045 -326 1106 -326 ct 1106 -326 1106 -326 1106 -224 ct +1106 -224 1106 -224 1104 -181 ct 1104 -181 1104 -181 1106 -181 ct 1113 -197 1122 -209 1134 -217 ct +1146 -225 1160 -229 1178 -229 ct 1200 -229 1216 -223 1227 -210 ct 1238 -197 1244 -178 1244 -153 ct +1244 -153 1244 -153 1244 0 ct 1244 0 1244 0 1183 0 ct 1183 0 1183 0 1183 -139 ct +1183 -150 1181 -159 1177 -165 ct 1172 -170 1166 -173 1157 -173 ct 1148 -173 1139 -170 1130 -165 ct +1122 -159 1113 -151 1106 -139 ct 1106 -139 1106 -139 1106 0 ct 1106 0 1106 0 1045 0 ct +p ef +1506 -95 m 1506 -95 1506 -95 1354 -95 ct 1357 -77 1365 -63 1377 -54 ct 1389 -45 1405 -41 1426 -41 ct +1450 -41 1477 -46 1506 -56 ct 1506 -56 1506 -56 1506 -9 ct 1471 0 1440 5 1414 5 ct +1376 5 1345 -6 1322 -27 ct 1299 -48 1288 -76 1288 -111 ct 1288 -147 1299 -175 1320 -197 ct +1342 -218 1370 -229 1405 -229 ct 1437 -229 1461 -219 1479 -199 ct 1497 -180 1506 -152 1506 -118 ct +1506 -118 1506 -118 1506 -95 ct p +1353 -136 m 1353 -136 1353 -136 1447 -136 ct 1447 -153 1443 -166 1436 -175 ct +1428 -184 1417 -188 1402 -188 ct 1388 -188 1376 -184 1368 -175 ct 1360 -166 1355 -153 1353 -136 ct +p ef +1811 -8 m 1811 -8 1811 -8 1811 -54 ct 1845 -42 1873 -36 1893 -36 ct 1908 -36 1919 -38 1927 -42 ct +1934 -46 1938 -52 1938 -60 ct 1938 -64 1936 -68 1932 -72 ct 1929 -75 1923 -79 1916 -82 ct +1916 -82 1916 -82 1868 -101 ct 1849 -109 1835 -118 1826 -127 ct 1817 -137 1812 -148 1812 -161 ct +1812 -182 1822 -199 1841 -211 ct 1860 -223 1887 -229 1921 -229 ct 1941 -229 1964 -226 1990 -221 ct +1990 -221 1990 -221 1990 -174 ct 1962 -183 1938 -188 1919 -188 ct 1904 -188 1894 -186 1887 -183 ct +1880 -180 1876 -175 1876 -169 ct 1876 -165 1879 -162 1884 -158 ct 1889 -154 1896 -150 1906 -146 ct +1906 -146 1906 -146 1959 -124 ct 1975 -118 1987 -110 1994 -100 ct 2002 -91 2006 -79 2006 -66 ct +2006 -45 1997 -28 1978 -15 ct 1959 -2 1935 5 1905 5 ct 1879 5 1847 1 1811 -8 ct +p ef +2134 0 m 2134 -285 l 2052 -285 l 2052 -326 l 2195 -326 l 2195 0 l +2134 0 l p ef +2408 0 m 2408 -183 l 2326 -183 l 2326 -224 l 2469 -224 l 2469 0 l +2408 0 l p +2408 -265 m 2408 -326 l 2469 -326 l 2469 -265 l 2408 -265 l p ef +2767 -4 m 2742 2 2717 5 2692 5 ct 2651 5 2618 -5 2595 -26 ct 2572 -47 2560 -75 2560 -111 ct +2560 -148 2571 -177 2594 -198 ct 2616 -219 2648 -229 2688 -229 ct 2718 -229 2744 -226 2767 -220 ct +2767 -220 2767 -220 2767 -175 ct 2742 -184 2719 -188 2696 -188 ct 2674 -188 2657 -182 2645 -169 ct +2632 -157 2626 -140 2626 -118 ct 2626 -94 2634 -74 2649 -60 ct 2664 -45 2684 -38 2709 -38 ct +2728 -38 2748 -42 2767 -49 ct 2767 -49 2767 -49 2767 -4 ct p ef +3030 -95 m 3030 -95 3030 -95 2878 -95 ct 2881 -77 2889 -63 2901 -54 ct 2913 -45 2929 -41 2950 -41 ct +2974 -41 3001 -46 3030 -56 ct 3030 -56 3030 -56 3030 -9 ct 2995 0 2964 5 2938 5 ct +2900 5 2869 -6 2846 -27 ct 2823 -48 2812 -76 2812 -111 ct 2812 -147 2823 -175 2844 -197 ct +2866 -218 2894 -229 2929 -229 ct 2961 -229 2985 -219 3003 -199 ct 3021 -180 3030 -152 3030 -118 ct +3030 -118 3030 -118 3030 -95 ct p +2877 -136 m 2877 -136 2877 -136 2971 -136 ct 2971 -153 2967 -166 2960 -175 ct +2952 -184 2941 -188 2926 -188 ct 2912 -188 2900 -184 2892 -175 ct 2884 -166 2879 -153 2877 -136 ct +p ef +pom +gr +gs +pum +10435 2085 t +35 0 m 58 -93 l 11 -93 l 18 -124 l 66 -124 l 80 -184 l 33 -184 l +41 -215 l 88 -215 l 111 -306 l 142 -306 l 120 -215 l 168 -215 l 191 -306 l +222 -306 l 200 -215 l 246 -215 l 239 -184 l 192 -184 l 177 -124 l +224 -124 l 216 -93 l 169 -93 l 146 0 l 115 0 l 138 -93 l 89 -93 l +66 0 l 35 0 l p +97 -124 m 146 -124 l 160 -184 l 112 -184 l 97 -124 l p ef +371 0 m 371 -193 l 289 -193 l 289 -224 l 412 -224 l 412 0 l 371 0 l +p +366 -275 m 366 -326 l 417 -326 l 417 -275 l 366 -275 l p ef +545 0 m 545 0 545 0 545 -224 ct 545 -224 545 -224 586 -224 ct 586 -224 586 -224 584 -182 ct +584 -182 584 -182 586 -182 ct 596 -198 607 -209 620 -217 ct 632 -225 647 -229 663 -229 ct +684 -229 700 -223 711 -210 ct 722 -197 727 -178 727 -153 ct 727 -153 727 -153 727 0 ct +727 0 727 0 686 0 ct 686 0 686 0 686 -142 ct 686 -159 683 -172 678 -179 ct 672 -186 663 -190 650 -190 ct +640 -190 630 -186 619 -179 ct 608 -172 597 -161 586 -146 ct 586 -146 586 -146 586 0 ct +586 0 586 0 545 0 ct p ef +990 -7 m 966 1 942 5 918 5 ct 879 5 849 -5 828 -26 ct 807 -46 796 -75 796 -112 ct +796 -149 806 -177 827 -198 ct 848 -219 877 -229 914 -229 ct 938 -229 962 -225 986 -218 ct +986 -218 986 -218 986 -184 ct 959 -193 937 -198 918 -198 ct 894 -198 874 -190 860 -175 ct +846 -160 839 -139 839 -112 ct 839 -85 846 -64 861 -49 ct 876 -34 897 -26 923 -26 ct +943 -26 965 -31 990 -40 ct 990 -40 990 -40 990 -7 ct p ef +1138 0 m 1138 -295 l 1051 -295 l 1051 -326 l 1179 -326 l 1179 0 l +1138 0 l p ef +1488 -224 m 1488 -224 1488 -224 1488 0 ct 1488 0 1488 0 1447 0 ct 1447 0 1447 0 1449 -42 ct +1449 -42 1449 -42 1447 -42 ct 1438 -26 1426 -15 1414 -7 ct 1401 1 1386 5 1370 5 ct +1349 5 1333 -1 1322 -14 ct 1311 -27 1306 -46 1306 -71 ct 1306 -71 1306 -71 1306 -224 ct +1306 -224 1306 -224 1347 -224 ct 1347 -224 1347 -224 1347 -82 ct 1347 -65 1350 -52 1355 -45 ct +1361 -38 1370 -34 1383 -34 ct 1393 -34 1403 -38 1414 -45 ct 1425 -52 1436 -63 1447 -78 ct +1447 -78 1447 -78 1447 -224 ct 1447 -224 1447 -224 1488 -224 ct p ef +1706 0 m 1706 0 1706 0 1708 -42 ct 1708 -42 1708 -42 1706 -42 ct 1696 -26 1685 -15 1673 -7 ct +1660 1 1647 5 1632 5 ct 1607 5 1587 -5 1572 -24 ct 1557 -44 1550 -71 1550 -105 ct +1550 -142 1559 -172 1576 -195 ct 1594 -218 1616 -229 1644 -229 ct 1656 -229 1668 -226 1678 -221 ct +1688 -216 1698 -209 1706 -198 ct 1706 -198 1706 -198 1708 -198 ct 1708 -198 1708 -198 1706 -229 ct +1706 -229 1706 -229 1706 -326 ct 1706 -326 1706 -326 1747 -326 ct 1747 -326 1747 -326 1747 0 ct +1747 0 1747 0 1706 0 ct p +1706 -168 m 1696 -178 1687 -185 1678 -190 ct 1668 -195 1659 -198 1650 -198 ct +1632 -198 1618 -190 1608 -175 ct 1598 -159 1593 -137 1593 -109 ct 1593 -83 1597 -63 1605 -50 ct +1613 -38 1624 -31 1640 -31 ct 1652 -31 1663 -35 1674 -42 ct 1685 -49 1696 -59 1706 -73 ct +1706 -73 1706 -73 1706 -168 ct p ef +2004 -9 m 1976 0 1950 5 1926 5 ct 1888 5 1859 -5 1838 -25 ct 1817 -45 1807 -73 1807 -110 ct +1807 -144 1817 -173 1837 -195 ct 1857 -218 1882 -229 1913 -229 ct 1944 -229 1966 -220 1981 -201 ct +1996 -182 2003 -153 2003 -114 ct 2003 -114 2003 -114 2003 -101 ct 2003 -101 2003 -101 1849 -101 ct +1850 -76 1858 -57 1872 -45 ct 1886 -32 1905 -26 1931 -26 ct 1954 -26 1978 -31 2004 -42 ct +2004 -42 2004 -42 2004 -9 ct p +1850 -132 m 1850 -132 1850 -132 1960 -132 ct 1960 -132 1960 -132 1960 -138 ct +1960 -158 1956 -173 1947 -183 ct 1938 -193 1926 -198 1909 -198 ct 1892 -198 1879 -192 1868 -181 ct +1858 -169 1852 -153 1850 -132 ct p ef +2337 -214 m 2337 -214 2337 -214 2337 -260 ct 2337 -282 2341 -298 2350 -309 ct +2358 -320 2371 -326 2388 -326 ct 2388 -326 2388 -326 2388 -306 ct 2381 -306 2375 -303 2371 -298 ct +2368 -293 2366 -286 2366 -276 ct 2366 -276 2366 -276 2366 -265 ct 2366 -265 2366 -265 2388 -265 ct +2388 -265 2388 -265 2388 -214 ct 2388 -214 2388 -214 2337 -214 ct p +2439 -214 m 2439 -214 2439 -214 2439 -260 ct 2439 -282 2443 -298 2452 -309 ct +2460 -320 2473 -326 2490 -326 ct 2490 -326 2490 -326 2490 -306 ct 2483 -306 2477 -303 2473 -298 ct +2470 -293 2468 -286 2468 -276 ct 2468 -276 2468 -276 2468 -265 ct 2468 -265 2468 -265 2490 -265 ct +2490 -265 2490 -265 2490 -214 ct 2490 -214 2490 -214 2439 -214 ct p ef +2647 0 m 2647 -275 l 2545 -275 l 2545 -306 l 2790 -306 l 2790 -275 l +2688 -275 l 2688 0 l 2647 0 l p ef +2966 -26 m 2942 -5 2917 5 2893 5 ct 2872 5 2855 -1 2842 -13 ct 2829 -24 2822 -39 2822 -57 ct +2822 -81 2832 -99 2853 -114 ct 2874 -128 2901 -135 2935 -135 ct 2935 -135 2935 -135 2960 -135 ct +2960 -135 2960 -135 2960 -154 ct 2960 -169 2956 -180 2949 -187 ct 2941 -194 2930 -198 2915 -198 ct +2891 -198 2866 -191 2841 -177 ct 2841 -177 2841 -177 2841 -213 ct 2870 -224 2897 -229 2923 -229 ct +2952 -229 2972 -223 2983 -212 ct 2995 -201 3001 -181 3001 -153 ct 3001 -153 3001 -153 3001 -59 ct +3001 -45 3002 -36 3005 -31 ct 3008 -26 3014 -24 3021 -24 ct 3024 -24 3028 -25 3034 -26 ct +3034 -26 3034 -26 3038 -2 ct 3024 3 3014 5 3007 5 ct 2997 5 2988 2 2982 -3 ct 2975 -8 2970 -16 2966 -26 ct +p +2960 -53 m 2960 -53 2960 -53 2960 -110 ct 2960 -110 2960 -110 2948 -110 ct +2920 -110 2899 -106 2885 -99 ct 2871 -91 2864 -80 2864 -64 ct 2864 -52 2867 -43 2874 -37 ct +2880 -31 2890 -28 2903 -28 ct 2921 -28 2940 -36 2960 -53 ct p ef +3112 0 m 3112 0 3112 0 3112 -224 ct 3112 -224 3112 -224 3153 -224 ct 3153 -224 3153 -224 3151 -182 ct +3151 -182 3151 -182 3153 -182 ct 3163 -198 3175 -209 3189 -217 ct 3203 -225 3218 -229 3236 -229 ct +3248 -229 3262 -227 3277 -224 ct 3277 -224 3277 -224 3277 -160 ct 3277 -160 3277 -160 3246 -160 ct +3246 -160 3246 -160 3246 -191 ct 3240 -192 3234 -193 3229 -193 ct 3215 -193 3202 -189 3190 -181 ct +3177 -173 3165 -161 3153 -145 ct 3153 -145 3153 -145 3153 0 ct 3153 0 3153 0 3112 0 ct +p ef +3345 75 m 3345 75 3345 75 3349 41 ct 3374 51 3397 56 3418 56 ct 3440 56 3456 51 3465 42 ct +3475 33 3481 17 3484 -6 ct 3484 -6 3484 -6 3488 -46 ct 3488 -46 3488 -46 3484 -46 ct +3476 -31 3465 -19 3453 -12 ct 3440 -4 3426 0 3410 0 ct 3385 0 3365 -10 3350 -29 ct +3335 -49 3327 -75 3327 -108 ct 3327 -144 3336 -173 3353 -195 ct 3371 -218 3393 -229 3421 -229 ct +3443 -229 3465 -219 3486 -198 ct 3486 -198 3486 -198 3489 -198 ct 3489 -198 3489 -198 3489 -224 ct +3489 -224 3489 -224 3525 -224 ct 3525 -224 3525 -224 3525 -45 ct 3525 -15 3523 6 3519 21 ct +3515 36 3508 49 3497 60 ct 3480 78 3454 87 3417 87 ct 3396 87 3372 83 3345 75 ct +p +3484 -80 m 3484 -80 3484 -80 3484 -167 ct 3466 -188 3446 -198 3427 -198 ct +3408 -198 3394 -191 3384 -176 ct 3375 -162 3370 -140 3370 -111 ct 3370 -86 3374 -67 3382 -55 ct +3391 -42 3403 -36 3420 -36 ct 3432 -36 3443 -40 3454 -47 ct 3465 -54 3475 -65 3484 -80 ct +p ef +3782 -9 m 3754 0 3728 5 3704 5 ct 3666 5 3637 -5 3616 -25 ct 3595 -45 3585 -73 3585 -110 ct +3585 -144 3595 -173 3615 -195 ct 3635 -218 3660 -229 3691 -229 ct 3722 -229 3744 -220 3759 -201 ct +3774 -182 3781 -153 3781 -114 ct 3781 -114 3781 -114 3781 -101 ct 3781 -101 3781 -101 3627 -101 ct +3628 -76 3636 -57 3650 -45 ct 3664 -32 3683 -26 3709 -26 ct 3732 -26 3756 -31 3782 -42 ct +3782 -42 3782 -42 3782 -9 ct p +3628 -132 m 3628 -132 3628 -132 3738 -132 ct 3738 -132 3738 -132 3738 -138 ct +3738 -158 3734 -173 3725 -183 ct 3716 -193 3704 -198 3687 -198 ct 3670 -198 3657 -192 3646 -181 ct +3636 -169 3630 -153 3628 -132 ct p ef +4038 0 m 4018 3 3998 5 3979 5 ct 3946 5 3923 -1 3911 -13 ct 3899 -25 3893 -47 3893 -80 ct +3893 -80 3893 -80 3893 -188 ct 3893 -188 3893 -188 3837 -188 ct 3837 -188 3837 -188 3837 -219 ct +3837 -219 3837 -219 3893 -219 ct 3893 -219 3893 -219 3893 -267 ct 3893 -267 3893 -267 3934 -267 ct +3934 -267 3934 -267 3934 -219 ct 3934 -219 3934 -219 4033 -219 ct 4033 -219 4033 -219 4033 -188 ct +4033 -188 4033 -188 3934 -188 ct 3934 -188 3934 -188 3934 -74 ct 3934 -61 3935 -53 3936 -48 ct +3938 -43 3941 -39 3947 -35 ct 3956 -29 3969 -26 3987 -26 ct 4004 -26 4021 -28 4038 -31 ct +4038 -31 4038 -31 4038 0 ct p ef +4161 0 m 4161 -61 l 4222 -61 l 4222 0 l 4161 0 l p ef +4355 0 m 4355 0 4355 0 4355 -326 ct 4355 -326 4355 -326 4396 -326 ct 4396 -326 4396 -326 4396 -224 ct +4396 -224 4396 -224 4394 -182 ct 4394 -182 4394 -182 4396 -182 ct 4406 -198 4417 -209 4430 -217 ct +4442 -225 4457 -229 4473 -229 ct 4494 -229 4510 -223 4521 -210 ct 4532 -197 4537 -178 4537 -153 ct +4537 -153 4537 -153 4537 0 ct 4537 0 4537 0 4496 0 ct 4496 0 4496 0 4496 -142 ct +4496 -159 4493 -172 4488 -179 ct 4482 -186 4473 -190 4460 -190 ct 4450 -190 4440 -186 4429 -179 ct +4418 -172 4407 -161 4396 -146 ct 4396 -146 4396 -146 4396 0 ct 4396 0 4396 0 4355 0 ct +p ef +4623 -214 m 4623 -214 4623 -214 4623 -260 ct 4623 -282 4627 -298 4636 -309 ct +4644 -320 4657 -326 4674 -326 ct 4674 -326 4674 -326 4674 -306 ct 4667 -306 4661 -303 4657 -298 ct +4654 -293 4652 -286 4652 -276 ct 4652 -276 4652 -276 4652 -265 ct 4652 -265 4652 -265 4674 -265 ct +4674 -265 4674 -265 4674 -214 ct 4674 -214 4674 -214 4623 -214 ct p +4725 -214 m 4725 -214 4725 -214 4725 -260 ct 4725 -282 4729 -298 4738 -309 ct +4746 -320 4759 -326 4776 -326 ct 4776 -326 4776 -326 4776 -306 ct 4769 -306 4763 -303 4759 -298 ct +4756 -293 4754 -286 4754 -276 ct 4754 -276 4754 -276 4754 -265 ct 4754 -265 4754 -265 4776 -265 ct +4776 -265 4776 -265 4776 -214 ct 4776 -214 4776 -214 4725 -214 ct p ef +pom +gr +gs +pum +15515 2085 t +0.003 0.503 0.003 c 239 -326 m 65 61 l 15 61 l 189 -326 l 239 -326 l +p ef +493 -326 m 319 61 l 269 61 l 443 -326 l 493 -326 l p ef +847 0 m 847 0 847 0 847 -178 ct 847 -178 847 -178 804 -178 ct 804 -178 804 -178 804 -219 ct +804 -219 804 -219 847 -219 ct 847 -219 847 -219 847 -251 ct 847 -278 855 -298 870 -311 ct +885 -324 908 -331 939 -331 ct 965 -331 990 -328 1015 -322 ct 1015 -322 1015 -322 1015 -278 ct +989 -286 968 -290 952 -290 ct 936 -290 925 -287 918 -281 ct 911 -275 908 -265 908 -250 ct +908 -250 908 -250 908 -219 ct 908 -219 908 -219 995 -219 ct 995 -219 995 -219 995 -178 ct +995 -178 995 -178 908 -178 ct 908 -178 908 -178 908 0 ct 908 0 908 0 847 0 ct p ef +1142 5 m 1108 5 1080 -6 1059 -27 ct 1038 -49 1027 -77 1027 -112 ct 1027 -148 1038 -176 1059 -197 ct +1080 -218 1108 -229 1144 -229 ct 1179 -229 1207 -218 1228 -197 ct 1249 -176 1260 -148 1260 -112 ct +1260 -76 1249 -48 1228 -27 ct 1207 -6 1178 5 1142 5 ct p +1143 -36 m 1160 -36 1173 -42 1181 -55 ct 1190 -68 1194 -87 1194 -112 ct 1194 -138 1190 -156 1181 -169 ct +1173 -182 1160 -188 1144 -188 ct 1127 -188 1114 -182 1106 -169 ct 1097 -156 1093 -137 1093 -112 ct +1093 -87 1097 -68 1105 -55 ct 1114 -42 1126 -36 1143 -36 ct p ef +1316 0 m 1316 0 1316 0 1316 -224 ct 1316 -224 1316 -224 1377 -224 ct 1377 -224 1377 -224 1375 -181 ct +1375 -181 1375 -181 1377 -181 ct 1387 -197 1399 -209 1413 -217 ct 1426 -225 1442 -229 1460 -229 ct +1471 -229 1486 -227 1502 -224 ct 1502 -224 1502 -224 1502 -149 ct 1502 -149 1502 -149 1461 -149 ct +1461 -149 1461 -149 1461 -173 ct 1456 -174 1453 -174 1450 -174 ct 1435 -174 1422 -170 1409 -163 ct +1397 -156 1386 -145 1377 -130 ct 1377 -130 1377 -130 1377 0 ct 1377 0 1377 0 1316 0 ct +p ef +1880 0 m 1880 -285 l 1798 -285 l 1798 -326 l 1941 -326 l 1941 0 l +1880 0 l p ef +2185 -24 m 2178 -14 2169 -7 2159 -2 ct 2149 3 2138 5 2125 5 ct 2103 5 2085 -2 2071 -15 ct +2057 -28 2050 -45 2050 -65 ct 2050 -91 2060 -111 2079 -124 ct 2099 -137 2128 -143 2167 -143 ct +2167 -143 2167 -143 2191 -143 ct 2191 -143 2191 -143 2191 -154 ct 2191 -165 2187 -174 2179 -179 ct +2171 -185 2159 -188 2143 -188 ct 2121 -188 2096 -182 2069 -169 ct 2069 -169 2069 -169 2069 -214 ct +2097 -224 2125 -229 2154 -229 ct 2186 -229 2210 -223 2226 -211 ct 2236 -203 2243 -194 2247 -185 ct +2250 -175 2252 -160 2252 -140 ct 2252 -140 2252 -140 2252 -64 ct 2252 -49 2257 -41 2266 -41 ct +2268 -41 2270 -41 2273 -42 ct 2273 -42 2273 -42 2273 -2 ct 2261 3 2249 5 2239 5 ct +2228 5 2218 3 2210 -2 ct 2202 -7 2196 -14 2191 -24 ct 2191 -24 2191 -24 2185 -24 ct +p +2191 -65 m 2191 -65 2191 -65 2191 -102 ct 2191 -102 2191 -102 2169 -102 ct +2150 -102 2135 -99 2126 -94 ct 2116 -88 2111 -80 2111 -69 ct 2111 -61 2114 -54 2120 -49 ct +2126 -44 2133 -41 2142 -41 ct 2157 -41 2174 -49 2191 -65 ct p ef +2319 -8 m 2319 -8 2319 -8 2319 -54 ct 2353 -42 2381 -36 2401 -36 ct 2416 -36 2427 -38 2435 -42 ct +2442 -46 2446 -52 2446 -60 ct 2446 -64 2444 -68 2440 -72 ct 2437 -75 2431 -79 2424 -82 ct +2424 -82 2424 -82 2376 -101 ct 2357 -109 2343 -118 2334 -127 ct 2325 -137 2320 -148 2320 -161 ct +2320 -182 2330 -199 2349 -211 ct 2368 -223 2395 -229 2429 -229 ct 2449 -229 2472 -226 2498 -221 ct +2498 -221 2498 -221 2498 -174 ct 2470 -183 2446 -188 2427 -188 ct 2412 -188 2402 -186 2395 -183 ct +2388 -180 2384 -175 2384 -169 ct 2384 -165 2387 -162 2392 -158 ct 2397 -154 2404 -150 2414 -146 ct +2414 -146 2414 -146 2467 -124 ct 2483 -118 2495 -110 2502 -100 ct 2510 -91 2514 -79 2514 -66 ct +2514 -45 2505 -28 2486 -15 ct 2467 -2 2443 5 2413 5 ct 2387 5 2355 1 2319 -8 ct +p ef +2768 -6 m 2744 1 2722 5 2704 5 ct 2675 5 2654 -1 2640 -14 ct 2626 -26 2619 -45 2619 -70 ct +2619 -70 2619 -70 2619 -178 ct 2619 -178 2619 -178 2571 -178 ct 2571 -178 2571 -178 2571 -219 ct +2571 -219 2571 -219 2619 -219 ct 2619 -219 2619 -219 2619 -285 ct 2619 -285 2619 -285 2680 -285 ct +2680 -285 2680 -285 2680 -219 ct 2680 -219 2680 -219 2763 -219 ct 2763 -219 2763 -219 2763 -178 ct +2763 -178 2763 -178 2680 -178 ct 2680 -178 2680 -178 2680 -84 ct 2680 -68 2683 -57 2689 -51 ct +2695 -44 2705 -41 2719 -41 ct 2736 -41 2752 -44 2768 -51 ct 2768 -51 2768 -51 2768 -6 ct +p ef +2794 46 m 2794 0 l 3049 0 l 3049 46 l 2794 46 l p ef +pom +gr +gs +pum +10435 3067 t +0.003 0.003 1.000 c 153 -24 m 146 -14 137 -7 127 -2 ct 117 3 106 5 93 5 ct 71 5 53 -2 39 -15 ct +25 -28 18 -45 18 -65 ct 18 -91 28 -111 47 -124 ct 67 -137 96 -143 135 -143 ct 135 -143 135 -143 159 -143 ct +159 -143 159 -143 159 -154 ct 159 -165 155 -174 147 -179 ct 139 -185 127 -188 111 -188 ct +89 -188 64 -182 37 -169 ct 37 -169 37 -169 37 -214 ct 65 -224 93 -229 122 -229 ct +154 -229 178 -223 194 -211 ct 204 -203 211 -194 215 -185 ct 218 -175 220 -160 220 -140 ct +220 -140 220 -140 220 -64 ct 220 -49 225 -41 234 -41 ct 236 -41 238 -41 241 -42 ct +241 -42 241 -42 241 -2 ct 229 3 217 5 207 5 ct 196 5 186 3 178 -2 ct 170 -7 164 -14 159 -24 ct +159 -24 159 -24 153 -24 ct p +159 -65 m 159 -65 159 -65 159 -102 ct 159 -102 159 -102 137 -102 ct 118 -102 103 -99 94 -94 ct +84 -88 79 -80 79 -69 ct 79 -61 82 -54 88 -49 ct 94 -44 101 -41 110 -41 ct 125 -41 142 -49 159 -65 ct +p ef +287 -8 m 287 -8 287 -8 287 -54 ct 321 -42 349 -36 369 -36 ct 384 -36 395 -38 403 -42 ct +410 -46 414 -52 414 -60 ct 414 -64 412 -68 408 -72 ct 405 -75 399 -79 392 -82 ct +392 -82 392 -82 344 -101 ct 325 -109 311 -118 302 -127 ct 293 -137 288 -148 288 -161 ct +288 -182 298 -199 317 -211 ct 336 -223 363 -229 397 -229 ct 417 -229 440 -226 466 -221 ct +466 -221 466 -221 466 -174 ct 438 -183 414 -188 395 -188 ct 380 -188 370 -186 363 -183 ct +356 -180 352 -175 352 -169 ct 352 -165 355 -162 360 -158 ct 365 -154 372 -150 382 -146 ct +382 -146 382 -146 435 -124 ct 451 -118 463 -110 470 -100 ct 478 -91 482 -79 482 -66 ct +482 -45 473 -28 454 -15 ct 435 -2 411 5 381 5 ct 355 5 323 1 287 -8 ct p ef +532 82 m 532 82 532 82 532 -224 ct 532 -224 532 -224 593 -224 ct 593 -224 593 -224 591 -182 ct +591 -182 591 -182 593 -182 ct 603 -197 614 -209 625 -217 ct 637 -225 650 -229 664 -229 ct +690 -229 710 -219 726 -198 ct 741 -178 749 -151 749 -117 ct 749 -80 740 -50 723 -28 ct +706 -6 683 5 654 5 ct 642 5 630 3 620 -2 ct 610 -6 601 -13 593 -22 ct 593 -22 593 -22 591 -22 ct +591 -22 591 -22 593 0 ct 593 0 593 0 593 82 ct 593 82 593 82 532 82 ct p +593 -64 m 600 -56 607 -50 614 -47 ct 621 -43 629 -41 638 -41 ct 653 -41 664 -47 672 -60 ct +679 -72 683 -91 683 -116 ct 683 -135 680 -149 673 -159 ct 666 -168 657 -173 643 -173 ct +635 -173 626 -170 617 -164 ct 609 -158 601 -149 593 -136 ct 593 -136 593 -136 593 -64 ct +p ef +998 -95 m 998 -95 998 -95 846 -95 ct 849 -77 857 -63 869 -54 ct 881 -45 897 -41 918 -41 ct +942 -41 969 -46 998 -56 ct 998 -56 998 -56 998 -9 ct 963 0 932 5 906 5 ct 868 5 837 -6 814 -27 ct +791 -48 780 -76 780 -111 ct 780 -147 791 -175 812 -197 ct 834 -218 862 -229 897 -229 ct +929 -229 953 -219 971 -199 ct 989 -180 998 -152 998 -118 ct 998 -118 998 -118 998 -95 ct +p +845 -136 m 845 -136 845 -136 939 -136 ct 939 -153 935 -166 928 -175 ct 920 -184 909 -188 894 -188 ct +880 -188 868 -184 860 -175 ct 852 -166 847 -153 845 -136 ct p ef +1243 -4 m 1218 2 1193 5 1168 5 ct 1127 5 1094 -5 1071 -26 ct 1048 -47 1036 -75 1036 -111 ct +1036 -148 1047 -177 1070 -198 ct 1092 -219 1124 -229 1164 -229 ct 1194 -229 1220 -226 1243 -220 ct +1243 -220 1243 -220 1243 -175 ct 1218 -184 1195 -188 1172 -188 ct 1150 -188 1133 -182 1121 -169 ct +1108 -157 1102 -140 1102 -118 ct 1102 -94 1110 -74 1125 -60 ct 1140 -45 1160 -38 1185 -38 ct +1204 -38 1224 -42 1243 -49 ct 1243 -49 1243 -49 1243 -4 ct p ef +1498 -6 m 1474 1 1452 5 1434 5 ct 1405 5 1384 -1 1370 -14 ct 1356 -26 1349 -45 1349 -70 ct +1349 -70 1349 -70 1349 -178 ct 1349 -178 1349 -178 1301 -178 ct 1301 -178 1301 -178 1301 -219 ct +1301 -219 1301 -219 1349 -219 ct 1349 -219 1349 -219 1349 -285 ct 1349 -285 1349 -285 1410 -285 ct +1410 -285 1410 -285 1410 -219 ct 1410 -219 1410 -219 1493 -219 ct 1493 -219 1493 -219 1493 -178 ct +1493 -178 1493 -178 1410 -178 ct 1410 -178 1410 -178 1410 -84 ct 1410 -68 1413 -57 1419 -51 ct +1425 -44 1435 -41 1449 -41 ct 1466 -41 1482 -44 1498 -51 ct 1498 -51 1498 -51 1498 -6 ct +p ef +pom +gr +gs +pum +11959 3067 t +301 0 m 301 0 301 0 301 -306 ct 301 -306 301 -306 387 -306 ct 425 -306 452 -300 468 -287 ct +485 -274 493 -253 493 -224 ct 493 -192 482 -167 461 -149 ct 439 -131 410 -122 372 -122 ct +372 -122 372 -122 342 -122 ct 342 -122 342 -122 342 0 ct 342 0 342 0 301 0 ct p +342 -153 m 342 -153 342 -153 367 -153 ct 395 -153 416 -159 429 -171 ct 443 -183 450 -200 450 -224 ct +450 -241 444 -254 433 -262 ct 422 -271 405 -275 383 -275 ct 383 -275 383 -275 342 -275 ct +342 -275 342 -275 342 -153 ct p ef +572 0 m 572 0 572 0 572 -224 ct 572 -224 572 -224 613 -224 ct 613 -224 613 -224 611 -182 ct +611 -182 611 -182 613 -182 ct 623 -198 635 -209 649 -217 ct 663 -225 678 -229 696 -229 ct +708 -229 722 -227 737 -224 ct 737 -224 737 -224 737 -160 ct 737 -160 737 -160 706 -160 ct +706 -160 706 -160 706 -191 ct 700 -192 694 -193 689 -193 ct 675 -193 662 -189 650 -181 ct +637 -173 625 -161 613 -145 ct 613 -145 613 -145 613 0 ct 613 0 613 0 572 0 ct p ef +888 5 m 856 5 831 -6 812 -27 ct 793 -48 784 -76 784 -112 ct 784 -148 793 -177 812 -198 ct +831 -219 857 -229 890 -229 ct 922 -229 948 -219 967 -198 ct 986 -177 995 -149 995 -113 ct +995 -76 986 -47 967 -26 ct 948 -5 922 5 888 5 ct p +889 -26 m 910 -26 926 -33 936 -48 ct 947 -62 952 -84 952 -113 ct 952 -139 946 -160 935 -175 ct +924 -190 909 -198 890 -198 ct 870 -198 855 -190 844 -175 ct 833 -160 827 -139 827 -112 ct +827 -85 832 -64 843 -49 ct 854 -34 870 -26 889 -26 ct p ef +1052 2 m 1052 2 1052 2 1052 -326 ct 1052 -326 1052 -326 1093 -326 ct 1093 -326 1093 -326 1093 -224 ct +1093 -224 1093 -224 1091 -182 ct 1091 -182 1091 -182 1093 -182 ct 1103 -198 1114 -209 1126 -217 ct +1138 -225 1152 -229 1166 -229 ct 1191 -229 1211 -219 1226 -200 ct 1241 -180 1248 -153 1248 -120 ct +1248 -82 1239 -52 1222 -29 ct 1205 -6 1182 5 1154 5 ct 1142 5 1131 2 1121 -3 ct +1111 -8 1101 -15 1093 -26 ct 1093 -26 1093 -26 1091 -26 ct 1091 -26 1091 -26 1083 2 ct +1083 2 1083 2 1052 2 ct p +1093 -56 m 1102 -46 1112 -39 1121 -34 ct 1130 -29 1139 -26 1149 -26 ct 1167 -26 1180 -34 1190 -49 ct +1200 -65 1205 -87 1205 -115 ct 1205 -141 1201 -160 1193 -173 ct 1185 -186 1174 -193 1158 -193 ct +1146 -193 1135 -189 1124 -182 ct 1113 -175 1103 -165 1093 -151 ct 1093 -151 1093 -151 1093 -56 ct +p ef +1392 0 m 1392 -295 l 1305 -295 l 1305 -326 l 1433 -326 l 1433 0 l +1392 0 l p ef +1750 -9 m 1722 0 1696 5 1672 5 ct 1634 5 1605 -5 1584 -25 ct 1563 -45 1553 -73 1553 -110 ct +1553 -144 1563 -173 1583 -195 ct 1603 -218 1628 -229 1659 -229 ct 1690 -229 1712 -220 1727 -201 ct +1742 -182 1749 -153 1749 -114 ct 1749 -114 1749 -114 1749 -101 ct 1749 -101 1749 -101 1595 -101 ct +1596 -76 1604 -57 1618 -45 ct 1632 -32 1651 -26 1677 -26 ct 1700 -26 1724 -31 1750 -42 ct +1750 -42 1750 -42 1750 -9 ct p +1596 -132 m 1596 -132 1596 -132 1706 -132 ct 1706 -132 1706 -132 1706 -138 ct +1706 -158 1702 -173 1693 -183 ct 1684 -193 1672 -198 1655 -198 ct 1638 -198 1625 -192 1614 -181 ct +1604 -169 1598 -153 1596 -132 ct p ef +1797 0 m 1797 0 1797 0 1797 -224 ct 1797 -224 1797 -224 1833 -224 ct 1833 -224 1833 -224 1830 -182 ct +1830 -182 1830 -182 1833 -182 ct 1841 -198 1850 -209 1859 -217 ct 1867 -225 1875 -229 1883 -229 ct +1894 -229 1902 -225 1909 -216 ct 1916 -208 1920 -196 1921 -182 ct 1921 -182 1921 -182 1924 -182 ct +1931 -198 1939 -209 1947 -217 ct 1956 -225 1965 -229 1975 -229 ct 1988 -229 1998 -224 2005 -213 ct +2012 -202 2015 -186 2015 -164 ct 2015 -164 2015 -164 2015 0 ct 2015 0 2015 0 1979 0 ct +1979 0 1979 0 1979 -162 ct 1979 -172 1978 -180 1976 -185 ct 1974 -190 1970 -193 1966 -193 ct +1960 -193 1953 -189 1946 -181 ct 1939 -173 1931 -160 1924 -144 ct 1924 -144 1924 -144 1924 0 ct +1924 0 1924 0 1888 0 ct 1888 0 1888 0 1888 -155 ct 1888 -167 1887 -177 1885 -183 ct +1882 -190 1879 -193 1875 -193 ct 1869 -193 1862 -188 1854 -179 ct 1846 -170 1839 -158 1833 -144 ct +1833 -144 1833 -144 1833 0 ct 1833 0 1833 0 1797 0 ct p ef +2498 -326 m 2498 -326 2498 -326 2498 -295 ct 2498 -295 2498 -295 2482 -295 ct +2461 -295 2447 -293 2439 -287 ct 2430 -282 2426 -274 2426 -261 ct 2426 -257 2427 -251 2428 -242 ct +2428 -242 2428 -242 2432 -214 ct 2433 -204 2434 -196 2434 -190 ct 2434 -175 2431 -163 2424 -153 ct +2417 -144 2407 -137 2393 -132 ct 2407 -128 2417 -121 2424 -111 ct 2431 -102 2434 -90 2434 -75 ct +2434 -68 2433 -61 2432 -51 ct 2432 -51 2432 -51 2428 -23 ct 2427 -14 2426 -8 2426 -4 ct +2426 9 2430 17 2439 22 ct 2447 27 2461 30 2482 30 ct 2482 30 2482 30 2498 30 ct +2498 30 2498 30 2498 61 ct 2498 61 2498 61 2475 61 ct 2446 61 2424 56 2410 46 ct +2395 36 2388 21 2388 2 ct 2388 -7 2389 -16 2391 -26 ct 2391 -26 2391 -26 2398 -63 ct +2399 -68 2399 -74 2399 -79 ct 2399 -92 2395 -101 2387 -108 ct 2380 -114 2368 -117 2353 -117 ct +2353 -117 2353 -117 2334 -117 ct 2334 -117 2334 -117 2334 -148 ct 2334 -148 2334 -148 2353 -148 ct +2368 -148 2380 -151 2387 -157 ct 2395 -164 2399 -173 2399 -186 ct 2399 -191 2399 -197 2398 -202 ct +2398 -202 2398 -202 2391 -239 ct 2389 -249 2388 -258 2388 -267 ct 2388 -286 2395 -301 2410 -311 ct +2424 -321 2446 -326 2475 -326 ct 2475 -326 2475 -326 2498 -326 ct p ef +pom +gr +gs +pum +10435 3558 t +pom +gr +gs +pum +10943 3558 t +107 0 m 107 -275 l 5 -275 l 5 -306 l 250 -306 l 250 -275 l 148 -275 l +148 0 l 107 0 l p ef +426 -26 m 402 -5 377 5 353 5 ct 332 5 315 -1 302 -13 ct 289 -24 282 -39 282 -57 ct +282 -81 292 -99 313 -114 ct 334 -128 361 -135 395 -135 ct 395 -135 395 -135 420 -135 ct +420 -135 420 -135 420 -154 ct 420 -169 416 -180 409 -187 ct 401 -194 390 -198 375 -198 ct +351 -198 326 -191 301 -177 ct 301 -177 301 -177 301 -213 ct 330 -224 357 -229 383 -229 ct +412 -229 432 -223 443 -212 ct 455 -201 461 -181 461 -153 ct 461 -153 461 -153 461 -59 ct +461 -45 462 -36 465 -31 ct 468 -26 474 -24 481 -24 ct 484 -24 488 -25 494 -26 ct +494 -26 494 -26 498 -2 ct 484 3 474 5 467 5 ct 457 5 448 2 442 -3 ct 435 -8 430 -16 426 -26 ct +p +420 -53 m 420 -53 420 -53 420 -110 ct 420 -110 420 -110 408 -110 ct 380 -110 359 -106 345 -99 ct +331 -91 324 -80 324 -64 ct 324 -52 327 -43 334 -37 ct 340 -31 350 -28 363 -28 ct +381 -28 400 -36 420 -53 ct p ef +572 0 m 572 0 572 0 572 -224 ct 572 -224 572 -224 613 -224 ct 613 -224 613 -224 611 -182 ct +611 -182 611 -182 613 -182 ct 623 -198 635 -209 649 -217 ct 663 -225 678 -229 696 -229 ct +708 -229 722 -227 737 -224 ct 737 -224 737 -224 737 -160 ct 737 -160 737 -160 706 -160 ct +706 -160 706 -160 706 -191 ct 700 -192 694 -193 689 -193 ct 675 -193 662 -189 650 -181 ct +637 -173 625 -161 613 -145 ct 613 -145 613 -145 613 0 ct 613 0 613 0 572 0 ct p ef +805 75 m 805 75 805 75 809 41 ct 834 51 857 56 878 56 ct 900 56 916 51 925 42 ct +935 33 941 17 944 -6 ct 944 -6 944 -6 948 -46 ct 948 -46 948 -46 944 -46 ct 936 -31 925 -19 913 -12 ct +900 -4 886 0 870 0 ct 845 0 825 -10 810 -29 ct 795 -49 787 -75 787 -108 ct 787 -144 796 -173 813 -195 ct +831 -218 853 -229 881 -229 ct 903 -229 925 -219 946 -198 ct 946 -198 946 -198 949 -198 ct +949 -198 949 -198 949 -224 ct 949 -224 949 -224 985 -224 ct 985 -224 985 -224 985 -45 ct +985 -15 983 6 979 21 ct 975 36 968 49 957 60 ct 940 78 914 87 877 87 ct 856 87 832 83 805 75 ct +p +944 -80 m 944 -80 944 -80 944 -167 ct 926 -188 906 -198 887 -198 ct 868 -198 854 -191 844 -176 ct +835 -162 830 -140 830 -111 ct 830 -86 834 -67 842 -55 ct 851 -42 863 -36 880 -36 ct +892 -36 903 -40 914 -47 ct 925 -54 935 -65 944 -80 ct p ef +1242 -9 m 1214 0 1188 5 1164 5 ct 1126 5 1097 -5 1076 -25 ct 1055 -45 1045 -73 1045 -110 ct +1045 -144 1055 -173 1075 -195 ct 1095 -218 1120 -229 1151 -229 ct 1182 -229 1204 -220 1219 -201 ct +1234 -182 1241 -153 1241 -114 ct 1241 -114 1241 -114 1241 -101 ct 1241 -101 1241 -101 1087 -101 ct +1088 -76 1096 -57 1110 -45 ct 1124 -32 1143 -26 1169 -26 ct 1192 -26 1216 -31 1242 -42 ct +1242 -42 1242 -42 1242 -9 ct p +1088 -132 m 1088 -132 1088 -132 1198 -132 ct 1198 -132 1198 -132 1198 -138 ct +1198 -158 1194 -173 1185 -183 ct 1176 -193 1164 -198 1147 -198 ct 1130 -198 1117 -192 1106 -181 ct +1096 -169 1090 -153 1088 -132 ct p ef +1498 0 m 1478 3 1458 5 1439 5 ct 1406 5 1383 -1 1371 -13 ct 1359 -25 1353 -47 1353 -80 ct +1353 -80 1353 -80 1353 -188 ct 1353 -188 1353 -188 1297 -188 ct 1297 -188 1297 -188 1297 -219 ct +1297 -219 1297 -219 1353 -219 ct 1353 -219 1353 -219 1353 -267 ct 1353 -267 1353 -267 1394 -267 ct +1394 -267 1394 -267 1394 -219 ct 1394 -219 1394 -219 1493 -219 ct 1493 -219 1493 -219 1493 -188 ct +1493 -188 1493 -188 1394 -188 ct 1394 -188 1394 -188 1394 -74 ct 1394 -61 1395 -53 1396 -48 ct +1398 -43 1401 -39 1407 -35 ct 1416 -29 1429 -26 1447 -26 ct 1464 -26 1481 -28 1498 -31 ct +1498 -31 1498 -31 1498 0 ct p ef +1923 -234 m 1923 -234 1923 -234 1986 -262 ct 1986 -262 1986 -262 1999 -223 ct +1999 -223 1999 -223 1931 -209 ct 1931 -209 1931 -209 1931 -212 ct 1931 -219 1928 -227 1923 -234 ct +p +1929 -203 m 1929 -203 1929 -203 1976 -152 ct 1976 -152 1976 -152 1943 -128 ct +1943 -128 1943 -128 1909 -188 ct 1917 -191 1924 -196 1929 -203 ct p +1902 -188 m 1902 -188 1902 -188 1868 -128 ct 1868 -128 1868 -128 1835 -152 ct +1835 -152 1835 -152 1882 -203 ct 1887 -196 1894 -191 1902 -188 ct p +1880 -209 m 1880 -209 1880 -209 1812 -223 ct 1812 -223 1812 -223 1825 -262 ct +1825 -262 1825 -262 1888 -233 ct 1883 -226 1880 -219 1880 -212 ct 1880 -212 1880 -212 1880 -209 ct +p +1893 -237 m 1893 -237 1893 -237 1885 -306 ct 1885 -306 1885 -306 1926 -306 ct +1926 -306 1926 -306 1918 -237 ct 1913 -239 1909 -240 1906 -240 ct 1902 -240 1898 -239 1893 -237 ct +p ef +2154 0 m 2154 -295 l 2067 -295 l 2067 -326 l 2195 -326 l 2195 0 l +2154 0 l p ef +2458 -26 m 2434 -5 2409 5 2385 5 ct 2364 5 2347 -1 2334 -13 ct 2321 -24 2314 -39 2314 -57 ct +2314 -81 2324 -99 2345 -114 ct 2366 -128 2393 -135 2427 -135 ct 2427 -135 2427 -135 2452 -135 ct +2452 -135 2452 -135 2452 -154 ct 2452 -169 2448 -180 2441 -187 ct 2433 -194 2422 -198 2407 -198 ct +2383 -198 2358 -191 2333 -177 ct 2333 -177 2333 -177 2333 -213 ct 2362 -224 2389 -229 2415 -229 ct +2444 -229 2464 -223 2475 -212 ct 2487 -201 2493 -181 2493 -153 ct 2493 -153 2493 -153 2493 -59 ct +2493 -45 2494 -36 2497 -31 ct 2500 -26 2506 -24 2513 -24 ct 2516 -24 2520 -25 2526 -26 ct +2526 -26 2526 -26 2530 -2 ct 2516 3 2506 5 2499 5 ct 2489 5 2480 2 2474 -3 ct 2467 -8 2462 -16 2458 -26 ct +p +2452 -53 m 2452 -53 2452 -53 2452 -110 ct 2452 -110 2452 -110 2440 -110 ct +2412 -110 2391 -106 2377 -99 ct 2363 -91 2356 -80 2356 -64 ct 2356 -52 2359 -43 2366 -37 ct +2372 -31 2382 -28 2395 -28 ct 2413 -28 2432 -36 2452 -53 ct p ef +2579 -9 m 2579 -9 2579 -9 2579 -45 ct 2610 -32 2637 -26 2660 -26 ct 2676 -26 2690 -29 2701 -36 ct +2712 -43 2717 -51 2717 -61 ct 2717 -74 2704 -84 2679 -93 ct 2679 -93 2679 -93 2636 -107 ct +2602 -118 2585 -138 2585 -165 ct 2585 -186 2593 -201 2608 -212 ct 2623 -223 2645 -229 2673 -229 ct +2694 -229 2718 -226 2746 -219 ct 2746 -219 2746 -219 2746 -186 ct 2719 -194 2695 -198 2673 -198 ct +2657 -198 2644 -196 2636 -191 ct 2628 -186 2624 -179 2624 -169 ct 2624 -158 2634 -149 2654 -142 ct +2654 -142 2654 -142 2706 -124 ct 2741 -111 2758 -91 2758 -64 ct 2758 -43 2749 -26 2732 -14 ct +2714 -1 2691 5 2661 5 ct 2636 5 2608 0 2579 -9 ct p ef +3022 0 m 3002 3 2982 5 2963 5 ct 2930 5 2907 -1 2895 -13 ct 2883 -25 2877 -47 2877 -80 ct +2877 -80 2877 -80 2877 -188 ct 2877 -188 2877 -188 2821 -188 ct 2821 -188 2821 -188 2821 -219 ct +2821 -219 2821 -219 2877 -219 ct 2877 -219 2877 -219 2877 -267 ct 2877 -267 2877 -267 2918 -267 ct +2918 -267 2918 -267 2918 -219 ct 2918 -219 2918 -219 3017 -219 ct 3017 -219 3017 -219 3017 -188 ct +3017 -188 3017 -188 2918 -188 ct 2918 -188 2918 -188 2918 -74 ct 2918 -61 2919 -53 2920 -48 ct +2922 -43 2925 -39 2931 -35 ct 2940 -29 2953 -26 2971 -26 ct 2988 -26 3005 -28 3022 -31 ct +3022 -31 3022 -31 3022 0 ct p ef +3048 31 m 3048 0 l 3303 0 l 3303 31 l 3048 31 l p ef +3399 66 m 3399 66 3399 66 3399 46 ct 3406 45 3412 41 3416 33 ct 3421 25 3423 14 3424 0 ct +3424 0 3424 0 3399 0 ct 3399 0 3399 0 3399 -61 ct 3399 -61 3399 -61 3460 -61 ct +3460 -61 3460 -61 3460 -24 ct 3460 5 3455 27 3445 42 ct 3435 57 3419 65 3399 66 ct +p +3399 -163 m 3399 -224 l 3460 -224 l 3460 -163 l 3399 -163 l p ef +pom +gr +gs +pum +10435 4049 t +pom +gr +gs +pum +10943 4049 t +0.003 0.503 0.003 c 239 -326 m 65 61 l 15 61 l 189 -326 l 239 -326 l +p ef +493 -326 m 319 61 l 269 61 l 443 -326 l 493 -326 l p ef +808 0 m 808 0 808 0 808 -224 ct 808 -224 808 -224 869 -224 ct 869 -224 869 -224 867 -181 ct +867 -181 867 -181 869 -181 ct 879 -197 891 -209 905 -217 ct 918 -225 934 -229 952 -229 ct +963 -229 978 -227 994 -224 ct 994 -224 994 -224 994 -149 ct 994 -149 994 -149 953 -149 ct +953 -149 953 -149 953 -173 ct 948 -174 945 -174 942 -174 ct 927 -174 914 -170 901 -163 ct +889 -156 878 -145 869 -130 ct 869 -130 869 -130 869 0 ct 869 0 869 0 808 0 ct p ef +1252 -95 m 1252 -95 1252 -95 1100 -95 ct 1103 -77 1111 -63 1123 -54 ct 1135 -45 1151 -41 1172 -41 ct +1196 -41 1223 -46 1252 -56 ct 1252 -56 1252 -56 1252 -9 ct 1217 0 1186 5 1160 5 ct +1122 5 1091 -6 1068 -27 ct 1045 -48 1034 -76 1034 -111 ct 1034 -147 1045 -175 1066 -197 ct +1088 -218 1116 -229 1151 -229 ct 1183 -229 1207 -219 1225 -199 ct 1243 -180 1252 -152 1252 -118 ct +1252 -118 1252 -118 1252 -95 ct p +1099 -136 m 1099 -136 1099 -136 1193 -136 ct 1193 -153 1189 -166 1182 -175 ct +1174 -184 1163 -188 1148 -188 ct 1134 -188 1122 -184 1114 -175 ct 1106 -166 1101 -153 1099 -136 ct +p ef +1355 0 m 1355 0 1355 0 1355 -178 ct 1355 -178 1355 -178 1312 -178 ct 1312 -178 1312 -178 1312 -219 ct +1312 -219 1312 -219 1355 -219 ct 1355 -219 1355 -219 1355 -251 ct 1355 -278 1363 -298 1378 -311 ct +1393 -324 1416 -331 1447 -331 ct 1473 -331 1498 -328 1523 -322 ct 1523 -322 1523 -322 1523 -278 ct +1497 -286 1476 -290 1460 -290 ct 1444 -290 1433 -287 1426 -281 ct 1419 -275 1416 -265 1416 -250 ct +1416 -250 1416 -250 1416 -219 ct 1416 -219 1416 -219 1503 -219 ct 1503 -219 1503 -219 1503 -178 ct +1503 -178 1503 -178 1416 -178 ct 1416 -178 1416 -178 1416 0 ct 1416 0 1416 0 1355 0 ct +p ef +1760 -95 m 1760 -95 1760 -95 1608 -95 ct 1611 -77 1619 -63 1631 -54 ct 1643 -45 1659 -41 1680 -41 ct +1704 -41 1731 -46 1760 -56 ct 1760 -56 1760 -56 1760 -9 ct 1725 0 1694 5 1668 5 ct +1630 5 1599 -6 1576 -27 ct 1553 -48 1542 -76 1542 -111 ct 1542 -147 1553 -175 1574 -197 ct +1596 -218 1624 -229 1659 -229 ct 1691 -229 1715 -219 1733 -199 ct 1751 -180 1760 -152 1760 -118 ct +1760 -118 1760 -118 1760 -95 ct p +1607 -136 m 1607 -136 1607 -136 1701 -136 ct 1701 -153 1697 -166 1690 -175 ct +1682 -184 1671 -188 1656 -188 ct 1642 -188 1630 -184 1622 -175 ct 1614 -166 1609 -153 1607 -136 ct +p ef +1824 0 m 1824 0 1824 0 1824 -224 ct 1824 -224 1824 -224 1885 -224 ct 1885 -224 1885 -224 1883 -181 ct +1883 -181 1883 -181 1885 -181 ct 1895 -197 1907 -209 1921 -217 ct 1934 -225 1950 -229 1968 -229 ct +1979 -229 1994 -227 2010 -224 ct 2010 -224 2010 -224 2010 -149 ct 2010 -149 2010 -149 1969 -149 ct +1969 -149 1969 -149 1969 -173 ct 1964 -174 1961 -174 1958 -174 ct 1943 -174 1930 -170 1917 -163 ct +1905 -156 1894 -145 1885 -130 ct 1885 -130 1885 -130 1885 0 ct 1885 0 1885 0 1824 0 ct +p ef +2514 -6 m 2490 1 2468 5 2450 5 ct 2421 5 2400 -1 2386 -14 ct 2372 -26 2365 -45 2365 -70 ct +2365 -70 2365 -70 2365 -178 ct 2365 -178 2365 -178 2317 -178 ct 2317 -178 2317 -178 2317 -219 ct +2317 -219 2317 -219 2365 -219 ct 2365 -219 2365 -219 2365 -285 ct 2365 -285 2365 -285 2426 -285 ct +2426 -285 2426 -285 2426 -219 ct 2426 -219 2426 -219 2509 -219 ct 2509 -219 2509 -219 2509 -178 ct +2509 -178 2509 -178 2426 -178 ct 2426 -178 2426 -178 2426 -84 ct 2426 -68 2429 -57 2435 -51 ct +2441 -44 2451 -41 2465 -41 ct 2482 -41 2498 -44 2514 -51 ct 2514 -51 2514 -51 2514 -6 ct +p ef +2666 5 m 2632 5 2604 -6 2583 -27 ct 2562 -49 2551 -77 2551 -112 ct 2551 -148 2562 -176 2583 -197 ct +2604 -218 2632 -229 2668 -229 ct 2703 -229 2731 -218 2752 -197 ct 2773 -176 2784 -148 2784 -112 ct +2784 -76 2773 -48 2752 -27 ct 2731 -6 2702 5 2666 5 ct p +2667 -36 m 2684 -36 2697 -42 2705 -55 ct 2714 -68 2718 -87 2718 -112 ct 2718 -138 2714 -156 2705 -169 ct +2697 -182 2684 -188 2668 -188 ct 2651 -188 2638 -182 2630 -169 ct 2621 -156 2617 -137 2617 -112 ct +2617 -87 2621 -68 2629 -55 ct 2638 -42 2650 -36 2667 -36 ct p ef +3081 -8 m 3081 -8 3081 -8 3081 -54 ct 3115 -42 3143 -36 3163 -36 ct 3178 -36 3189 -38 3197 -42 ct +3204 -46 3208 -52 3208 -60 ct 3208 -64 3206 -68 3202 -72 ct 3199 -75 3193 -79 3186 -82 ct +3186 -82 3186 -82 3138 -101 ct 3119 -109 3105 -118 3096 -127 ct 3087 -137 3082 -148 3082 -161 ct +3082 -182 3092 -199 3111 -211 ct 3130 -223 3157 -229 3191 -229 ct 3211 -229 3234 -226 3260 -221 ct +3260 -221 3260 -221 3260 -174 ct 3232 -183 3208 -188 3189 -188 ct 3174 -188 3164 -186 3157 -183 ct +3150 -180 3146 -175 3146 -169 ct 3146 -165 3149 -162 3154 -158 ct 3159 -154 3166 -150 3176 -146 ct +3176 -146 3176 -146 3229 -124 ct 3245 -118 3257 -110 3264 -100 ct 3272 -91 3276 -79 3276 -66 ct +3276 -45 3267 -28 3248 -15 ct 3229 -2 3205 5 3175 5 ct 3149 5 3117 1 3081 -8 ct +p ef +3404 0 m 3404 -285 l 3322 -285 l 3322 -326 l 3465 -326 l 3465 0 l +3404 0 l p ef +3678 0 m 3678 -183 l 3596 -183 l 3596 -224 l 3739 -224 l 3739 0 l +3678 0 l p +3678 -265 m 3678 -326 l 3739 -326 l 3739 -265 l 3678 -265 l p ef +4037 -4 m 4012 2 3987 5 3962 5 ct 3921 5 3888 -5 3865 -26 ct 3842 -47 3830 -75 3830 -111 ct +3830 -148 3841 -177 3864 -198 ct 3886 -219 3918 -229 3958 -229 ct 3988 -229 4014 -226 4037 -220 ct +4037 -220 4037 -220 4037 -175 ct 4012 -184 3989 -188 3966 -188 ct 3944 -188 3927 -182 3915 -169 ct +3902 -157 3896 -140 3896 -118 ct 3896 -94 3904 -74 3919 -60 ct 3934 -45 3954 -38 3979 -38 ct +3998 -38 4018 -42 4037 -49 ct 4037 -49 4037 -49 4037 -4 ct p ef +4300 -95 m 4300 -95 4300 -95 4148 -95 ct 4151 -77 4159 -63 4171 -54 ct 4183 -45 4199 -41 4220 -41 ct +4244 -41 4271 -46 4300 -56 ct 4300 -56 4300 -56 4300 -9 ct 4265 0 4234 5 4208 5 ct +4170 5 4139 -6 4116 -27 ct 4093 -48 4082 -76 4082 -111 ct 4082 -147 4093 -175 4114 -197 ct +4136 -218 4164 -229 4199 -229 ct 4231 -229 4255 -219 4273 -199 ct 4291 -180 4300 -152 4300 -118 ct +4300 -118 4300 -118 4300 -95 ct p +4147 -136 m 4147 -136 4147 -136 4241 -136 ct 4241 -153 4237 -166 4230 -175 ct +4222 -184 4211 -188 4196 -188 ct 4182 -188 4170 -184 4162 -175 ct 4154 -166 4149 -153 4147 -136 ct +p ef +4694 0 m 4694 -183 l 4612 -183 l 4612 -224 l 4755 -224 l 4755 0 l +4694 0 l p +4694 -265 m 4694 -326 l 4755 -326 l 4755 -265 l 4694 -265 l p ef +4855 0 m 4855 0 4855 0 4855 -224 ct 4855 -224 4855 -224 4916 -224 ct 4916 -224 4916 -224 4915 -202 ct +4915 -202 4915 -202 4914 -181 ct 4914 -181 4914 -181 4916 -181 ct 4923 -197 4932 -209 4944 -217 ct +4956 -225 4970 -229 4988 -229 ct 5010 -229 5026 -223 5037 -210 ct 5048 -197 5054 -178 5054 -153 ct +5054 -153 5054 -153 5054 0 ct 5054 0 5054 0 4993 0 ct 4993 0 4993 0 4993 -139 ct +4993 -150 4991 -159 4987 -165 ct 4982 -170 4976 -173 4967 -173 ct 4958 -173 4949 -170 4940 -165 ct +4932 -159 4923 -151 4916 -139 ct 4916 -139 4916 -139 4916 0 ct 4916 0 4916 0 4855 0 ct +p ef +5352 0 m 5352 0 5352 0 5352 -306 ct 5352 -306 5352 -306 5447 -306 ct 5490 -306 5522 -293 5545 -266 ct +5568 -240 5580 -202 5580 -153 ct 5580 -105 5568 -67 5545 -40 ct 5522 -13 5489 0 5447 0 ct +5447 0 5447 0 5352 0 ct p +5413 -41 m 5413 -41 5413 -41 5433 -41 ct 5462 -41 5483 -50 5495 -67 ct 5508 -84 5514 -114 5514 -154 ct +5514 -194 5508 -223 5495 -240 ct 5483 -257 5462 -265 5433 -265 ct 5433 -265 5433 -265 5413 -265 ct +5413 -265 5413 -265 5413 -41 ct p ef +5814 -224 m 5814 -224 5814 -224 5814 0 ct 5814 0 5814 0 5753 0 ct 5753 0 5753 0 5754 -22 ct +5754 -22 5754 -22 5756 -43 ct 5756 -43 5756 -43 5753 -43 ct 5747 -27 5738 -15 5726 -7 ct +5714 1 5699 5 5682 5 ct 5660 5 5643 -1 5632 -14 ct 5621 -27 5615 -46 5615 -71 ct +5615 -71 5615 -71 5615 -224 ct 5615 -224 5615 -224 5676 -224 ct 5676 -224 5676 -224 5676 -85 ct +5676 -73 5678 -65 5682 -59 ct 5687 -54 5693 -51 5702 -51 ct 5711 -51 5720 -54 5729 -59 ct +5737 -65 5745 -73 5753 -85 ct 5753 -85 5753 -85 5753 -224 ct 5753 -224 5753 -224 5814 -224 ct +p ef +5995 0 m 5995 0 5995 0 5944 0 ct 5944 0 5944 0 5944 -149 ct 5944 -157 5943 -163 5942 -167 ct +5940 -171 5938 -173 5935 -173 ct 5930 -173 5926 -171 5922 -166 ct 5918 -161 5915 -154 5911 -145 ct +5911 -145 5911 -145 5911 0 ct 5911 0 5911 0 5860 0 ct 5860 0 5860 0 5860 -224 ct +5860 -224 5860 -224 5911 -224 ct 5911 -224 5911 -224 5908 -181 ct 5908 -181 5908 -181 5911 -181 ct +5916 -197 5923 -209 5931 -217 ct 5939 -225 5948 -229 5958 -229 ct 5969 -229 5978 -225 5984 -217 ct +5990 -209 5994 -197 5995 -181 ct 5995 -181 5995 -181 5997 -181 ct 6002 -197 6008 -209 6015 -217 ct +6023 -225 6031 -229 6041 -229 ct 6055 -229 6065 -223 6071 -212 ct 6076 -200 6079 -179 6079 -150 ct +6079 -150 6079 -150 6079 0 ct 6079 0 6079 0 6028 0 ct 6028 0 6028 0 6028 -149 ct +6028 -157 6027 -163 6026 -167 ct 6024 -171 6022 -173 6019 -173 ct 6014 -173 6010 -171 6006 -166 ct +6003 -161 5999 -154 5995 -145 ct 5995 -145 5995 -145 5995 0 ct p ef +6120 82 m 6120 82 6120 82 6120 -224 ct 6120 -224 6120 -224 6181 -224 ct 6181 -224 6181 -224 6179 -182 ct +6179 -182 6179 -182 6181 -182 ct 6191 -197 6202 -209 6213 -217 ct 6225 -225 6238 -229 6252 -229 ct +6278 -229 6298 -219 6314 -198 ct 6329 -178 6337 -151 6337 -117 ct 6337 -80 6328 -50 6311 -28 ct +6294 -6 6271 5 6242 5 ct 6230 5 6218 3 6208 -2 ct 6198 -6 6189 -13 6181 -22 ct +6181 -22 6181 -22 6179 -22 ct 6179 -22 6179 -22 6181 0 ct 6181 0 6181 0 6181 82 ct +6181 82 6181 82 6120 82 ct p +6181 -64 m 6188 -56 6195 -50 6202 -47 ct 6209 -43 6217 -41 6226 -41 ct 6241 -41 6252 -47 6260 -60 ct +6267 -72 6271 -91 6271 -116 ct 6271 -135 6268 -149 6261 -159 ct 6254 -168 6245 -173 6231 -173 ct +6223 -173 6214 -170 6205 -164 ct 6197 -158 6189 -149 6181 -136 ct 6181 -136 6181 -136 6181 -64 ct +p ef +6442 0 m 6442 -71 l 6513 -71 l 6513 0 l 6442 0 l p ef +6757 -24 m 6750 -14 6741 -7 6731 -2 ct 6721 3 6710 5 6697 5 ct 6675 5 6657 -2 6643 -15 ct +6629 -28 6622 -45 6622 -65 ct 6622 -91 6632 -111 6651 -124 ct 6671 -137 6700 -143 6739 -143 ct +6739 -143 6739 -143 6763 -143 ct 6763 -143 6763 -143 6763 -154 ct 6763 -165 6759 -174 6751 -179 ct +6743 -185 6731 -188 6715 -188 ct 6693 -188 6668 -182 6641 -169 ct 6641 -169 6641 -169 6641 -214 ct +6669 -224 6697 -229 6726 -229 ct 6758 -229 6782 -223 6798 -211 ct 6808 -203 6815 -194 6819 -185 ct +6822 -175 6824 -160 6824 -140 ct 6824 -140 6824 -140 6824 -64 ct 6824 -49 6829 -41 6838 -41 ct +6840 -41 6842 -41 6845 -42 ct 6845 -42 6845 -42 6845 -2 ct 6833 3 6821 5 6811 5 ct +6800 5 6790 3 6782 -2 ct 6774 -7 6768 -14 6763 -24 ct 6763 -24 6763 -24 6757 -24 ct +p +6763 -65 m 6763 -65 6763 -65 6763 -102 ct 6763 -102 6763 -102 6741 -102 ct +6722 -102 6707 -99 6698 -94 ct 6688 -88 6683 -80 6683 -69 ct 6683 -61 6686 -54 6692 -49 ct +6698 -44 6705 -41 6714 -41 ct 6729 -41 6746 -49 6763 -65 ct p ef +6887 0 m 6887 0 6887 0 6887 -326 ct 6887 -326 6887 -326 6948 -326 ct 6948 -326 6948 -326 6948 -224 ct +6948 -224 6948 -224 6946 -181 ct 6946 -181 6946 -181 6948 -181 ct 6955 -197 6964 -209 6976 -217 ct +6988 -225 7002 -229 7020 -229 ct 7042 -229 7058 -223 7069 -210 ct 7080 -197 7086 -178 7086 -153 ct +7086 -153 7086 -153 7086 0 ct 7086 0 7086 0 7025 0 ct 7025 0 7025 0 7025 -139 ct +7025 -150 7023 -159 7019 -165 ct 7014 -170 7008 -173 6999 -173 ct 6990 -173 6981 -170 6972 -165 ct +6964 -159 6955 -151 6948 -139 ct 6948 -139 6948 -139 6948 0 ct 6948 0 6948 0 6887 0 ct +p ef +7204 0 m 7204 -71 l 7275 -71 l 7275 0 l 7204 0 l p +7204 -153 m 7204 -224 l 7275 -224 l 7275 -153 l 7204 -153 l p ef +pom +gr +gs +pum +10435 4540 t +pom +gr +gs +pum +10943 4540 t +0.003 0.003 1.000 c 153 -24 m 146 -14 137 -7 127 -2 ct 117 3 106 5 93 5 ct 71 5 53 -2 39 -15 ct +25 -28 18 -45 18 -65 ct 18 -91 28 -111 47 -124 ct 67 -137 96 -143 135 -143 ct 135 -143 135 -143 159 -143 ct +159 -143 159 -143 159 -154 ct 159 -165 155 -174 147 -179 ct 139 -185 127 -188 111 -188 ct +89 -188 64 -182 37 -169 ct 37 -169 37 -169 37 -214 ct 65 -224 93 -229 122 -229 ct +154 -229 178 -223 194 -211 ct 204 -203 211 -194 215 -185 ct 218 -175 220 -160 220 -140 ct +220 -140 220 -140 220 -64 ct 220 -49 225 -41 234 -41 ct 236 -41 238 -41 241 -42 ct +241 -42 241 -42 241 -2 ct 229 3 217 5 207 5 ct 196 5 186 3 178 -2 ct 170 -7 164 -14 159 -24 ct +159 -24 159 -24 153 -24 ct p +159 -65 m 159 -65 159 -65 159 -102 ct 159 -102 159 -102 137 -102 ct 118 -102 103 -99 94 -94 ct +84 -88 79 -80 79 -69 ct 79 -61 82 -54 88 -49 ct 94 -44 101 -41 110 -41 ct 125 -41 142 -49 159 -65 ct +p ef +428 0 m 428 0 428 0 430 -42 ct 430 -42 430 -42 428 -42 ct 418 -27 407 -15 395 -7 ct +384 1 371 5 357 5 ct 331 5 311 -5 295 -26 ct 280 -46 272 -73 272 -107 ct 272 -144 281 -174 298 -196 ct +315 -218 338 -229 367 -229 ct 379 -229 390 -227 400 -222 ct 410 -218 419 -211 428 -203 ct +428 -203 428 -203 430 -203 ct 430 -203 430 -203 428 -224 ct 428 -224 428 -224 428 -326 ct +428 -326 428 -326 489 -326 ct 489 -326 489 -326 489 0 ct 489 0 489 0 428 0 ct p +428 -160 m 421 -168 414 -173 407 -177 ct 400 -181 392 -183 384 -183 ct 368 -183 357 -177 349 -164 ct +342 -152 338 -133 338 -108 ct 338 -89 341 -75 348 -65 ct 355 -56 365 -51 378 -51 ct +387 -51 395 -54 404 -60 ct 412 -66 420 -75 428 -88 ct 428 -88 428 -88 428 -160 ct +p ef +606 0 m 517 -224 l 583 -224 l 645 -67 l 706 -224 l 755 -224 l 667 0 l +606 0 l p ef +884 0 m 884 -183 l 802 -183 l 802 -224 l 945 -224 l 945 0 l 884 0 l +p +884 -265 m 884 -326 l 945 -326 l 945 -265 l 884 -265 l p ef +1243 -4 m 1218 2 1193 5 1168 5 ct 1127 5 1094 -5 1071 -26 ct 1048 -47 1036 -75 1036 -111 ct +1036 -148 1047 -177 1070 -198 ct 1092 -219 1124 -229 1164 -229 ct 1194 -229 1220 -226 1243 -220 ct +1243 -220 1243 -220 1243 -175 ct 1218 -184 1195 -188 1172 -188 ct 1150 -188 1133 -182 1121 -169 ct +1108 -157 1102 -140 1102 -118 ct 1102 -94 1110 -74 1125 -60 ct 1140 -45 1160 -38 1185 -38 ct +1204 -38 1224 -42 1243 -49 ct 1243 -49 1243 -49 1243 -4 ct p ef +1506 -95 m 1506 -95 1506 -95 1354 -95 ct 1357 -77 1365 -63 1377 -54 ct 1389 -45 1405 -41 1426 -41 ct +1450 -41 1477 -46 1506 -56 ct 1506 -56 1506 -56 1506 -9 ct 1471 0 1440 5 1414 5 ct +1376 5 1345 -6 1322 -27 ct 1299 -48 1288 -76 1288 -111 ct 1288 -147 1299 -175 1320 -197 ct +1342 -218 1370 -229 1405 -229 ct 1437 -229 1461 -219 1479 -199 ct 1497 -180 1506 -152 1506 -118 ct +1506 -118 1506 -118 1506 -95 ct p +1353 -136 m 1353 -136 1353 -136 1447 -136 ct 1447 -153 1443 -166 1436 -175 ct +1428 -184 1417 -188 1402 -188 ct 1388 -188 1376 -184 1368 -175 ct 1360 -166 1355 -153 1353 -136 ct +p ef +pom +gr +gs +pum +12467 4540 t +305 -214 m 305 -214 305 -214 305 -260 ct 305 -282 309 -298 318 -309 ct 326 -320 339 -326 356 -326 ct +356 -326 356 -326 356 -306 ct 349 -306 343 -303 339 -298 ct 336 -293 334 -286 334 -276 ct +334 -276 334 -276 334 -265 ct 334 -265 334 -265 356 -265 ct 356 -265 356 -265 356 -214 ct +356 -214 356 -214 305 -214 ct p +407 -214 m 407 -214 407 -214 407 -260 ct 407 -282 411 -298 420 -309 ct 428 -320 441 -326 458 -326 ct +458 -326 458 -326 458 -306 ct 451 -306 445 -303 441 -298 ct 438 -293 436 -286 436 -276 ct +436 -276 436 -276 436 -265 ct 436 -265 436 -265 458 -265 ct 458 -265 458 -265 458 -214 ct +458 -214 458 -214 407 -214 ct p ef +615 0 m 615 -275 l 513 -275 l 513 -306 l 758 -306 l 758 -275 l 656 -275 l +656 0 l 615 0 l p ef +934 -26 m 910 -5 885 5 861 5 ct 840 5 823 -1 810 -13 ct 797 -24 790 -39 790 -57 ct +790 -81 800 -99 821 -114 ct 842 -128 869 -135 903 -135 ct 903 -135 903 -135 928 -135 ct +928 -135 928 -135 928 -154 ct 928 -169 924 -180 917 -187 ct 909 -194 898 -198 883 -198 ct +859 -198 834 -191 809 -177 ct 809 -177 809 -177 809 -213 ct 838 -224 865 -229 891 -229 ct +920 -229 940 -223 951 -212 ct 963 -201 969 -181 969 -153 ct 969 -153 969 -153 969 -59 ct +969 -45 970 -36 973 -31 ct 976 -26 982 -24 989 -24 ct 992 -24 996 -25 1002 -26 ct +1002 -26 1002 -26 1006 -2 ct 992 3 982 5 975 5 ct 965 5 956 2 950 -3 ct 943 -8 938 -16 934 -26 ct +p +928 -53 m 928 -53 928 -53 928 -110 ct 928 -110 928 -110 916 -110 ct 888 -110 867 -106 853 -99 ct +839 -91 832 -80 832 -64 ct 832 -52 835 -43 842 -37 ct 848 -31 858 -28 871 -28 ct +889 -28 908 -36 928 -53 ct p ef +1080 0 m 1080 0 1080 0 1080 -224 ct 1080 -224 1080 -224 1121 -224 ct 1121 -224 1121 -224 1119 -182 ct +1119 -182 1119 -182 1121 -182 ct 1131 -198 1143 -209 1157 -217 ct 1171 -225 1186 -229 1204 -229 ct +1216 -229 1230 -227 1245 -224 ct 1245 -224 1245 -224 1245 -160 ct 1245 -160 1245 -160 1214 -160 ct +1214 -160 1214 -160 1214 -191 ct 1208 -192 1202 -193 1197 -193 ct 1183 -193 1170 -189 1158 -181 ct +1145 -173 1133 -161 1121 -145 ct 1121 -145 1121 -145 1121 0 ct 1121 0 1121 0 1080 0 ct +p ef +1313 75 m 1313 75 1313 75 1317 41 ct 1342 51 1365 56 1386 56 ct 1408 56 1424 51 1433 42 ct +1443 33 1449 17 1452 -6 ct 1452 -6 1452 -6 1456 -46 ct 1456 -46 1456 -46 1452 -46 ct +1444 -31 1433 -19 1421 -12 ct 1408 -4 1394 0 1378 0 ct 1353 0 1333 -10 1318 -29 ct +1303 -49 1295 -75 1295 -108 ct 1295 -144 1304 -173 1321 -195 ct 1339 -218 1361 -229 1389 -229 ct +1411 -229 1433 -219 1454 -198 ct 1454 -198 1454 -198 1457 -198 ct 1457 -198 1457 -198 1457 -224 ct +1457 -224 1457 -224 1493 -224 ct 1493 -224 1493 -224 1493 -45 ct 1493 -15 1491 6 1487 21 ct +1483 36 1476 49 1465 60 ct 1448 78 1422 87 1385 87 ct 1364 87 1340 83 1313 75 ct +p +1452 -80 m 1452 -80 1452 -80 1452 -167 ct 1434 -188 1414 -198 1395 -198 ct +1376 -198 1362 -191 1352 -176 ct 1343 -162 1338 -140 1338 -111 ct 1338 -86 1342 -67 1350 -55 ct +1359 -42 1371 -36 1388 -36 ct 1400 -36 1411 -40 1422 -47 ct 1433 -54 1443 -65 1452 -80 ct +p ef +1750 -9 m 1722 0 1696 5 1672 5 ct 1634 5 1605 -5 1584 -25 ct 1563 -45 1553 -73 1553 -110 ct +1553 -144 1563 -173 1583 -195 ct 1603 -218 1628 -229 1659 -229 ct 1690 -229 1712 -220 1727 -201 ct +1742 -182 1749 -153 1749 -114 ct 1749 -114 1749 -114 1749 -101 ct 1749 -101 1749 -101 1595 -101 ct +1596 -76 1604 -57 1618 -45 ct 1632 -32 1651 -26 1677 -26 ct 1700 -26 1724 -31 1750 -42 ct +1750 -42 1750 -42 1750 -9 ct p +1596 -132 m 1596 -132 1596 -132 1706 -132 ct 1706 -132 1706 -132 1706 -138 ct +1706 -158 1702 -173 1693 -183 ct 1684 -193 1672 -198 1655 -198 ct 1638 -198 1625 -192 1614 -181 ct +1604 -169 1598 -153 1596 -132 ct p ef +2006 0 m 1986 3 1966 5 1947 5 ct 1914 5 1891 -1 1879 -13 ct 1867 -25 1861 -47 1861 -80 ct +1861 -80 1861 -80 1861 -188 ct 1861 -188 1861 -188 1805 -188 ct 1805 -188 1805 -188 1805 -219 ct +1805 -219 1805 -219 1861 -219 ct 1861 -219 1861 -219 1861 -267 ct 1861 -267 1861 -267 1902 -267 ct +1902 -267 1902 -267 1902 -219 ct 1902 -219 1902 -219 2001 -219 ct 2001 -219 2001 -219 2001 -188 ct +2001 -188 2001 -188 1902 -188 ct 1902 -188 1902 -188 1902 -74 ct 1902 -61 1903 -53 1904 -48 ct +1906 -43 1909 -39 1915 -35 ct 1924 -29 1937 -26 1955 -26 ct 1972 -26 1989 -28 2006 -31 ct +2006 -31 2006 -31 2006 0 ct p ef +2083 -214 m 2083 -214 2083 -214 2083 -260 ct 2083 -282 2087 -298 2096 -309 ct +2104 -320 2117 -326 2134 -326 ct 2134 -326 2134 -326 2134 -306 ct 2127 -306 2121 -303 2117 -298 ct +2114 -293 2112 -286 2112 -276 ct 2112 -276 2112 -276 2112 -265 ct 2112 -265 2112 -265 2134 -265 ct +2134 -265 2134 -265 2134 -214 ct 2134 -214 2134 -214 2083 -214 ct p +2185 -214 m 2185 -214 2185 -214 2185 -260 ct 2185 -282 2189 -298 2198 -309 ct +2206 -320 2219 -326 2236 -326 ct 2236 -326 2236 -326 2236 -306 ct 2229 -306 2223 -303 2219 -298 ct +2216 -293 2214 -286 2214 -276 ct 2214 -276 2214 -276 2214 -265 ct 2214 -265 2214 -265 2236 -265 ct +2236 -265 2236 -265 2236 -214 ct 2236 -214 2236 -214 2185 -214 ct p ef +2383 -163 m 2383 -224 l 2444 -224 l 2444 -163 l 2383 -163 l p +2383 0 m 2383 -61 l 2444 -61 l 2444 0 l 2383 0 l p ef +pom +gr +gs +pum +15261 4540 t +0.003 0.003 1.000 c 33 -8 m 33 -8 33 -8 33 -54 ct 67 -42 95 -36 115 -36 ct 130 -36 141 -38 149 -42 ct +156 -46 160 -52 160 -60 ct 160 -64 158 -68 154 -72 ct 151 -75 145 -79 138 -82 ct +138 -82 138 -82 90 -101 ct 71 -109 57 -118 48 -127 ct 39 -137 34 -148 34 -161 ct +34 -182 44 -199 63 -211 ct 82 -223 109 -229 143 -229 ct 163 -229 186 -226 212 -221 ct +212 -221 212 -221 212 -174 ct 184 -183 160 -188 141 -188 ct 126 -188 116 -186 109 -183 ct +102 -180 98 -175 98 -169 ct 98 -165 101 -162 106 -158 ct 111 -154 118 -150 128 -146 ct +128 -146 128 -146 181 -124 ct 197 -118 209 -110 216 -100 ct 224 -91 228 -79 228 -66 ct +228 -45 219 -28 200 -15 ct 181 -2 157 5 127 5 ct 101 5 69 1 33 -8 ct p ef +356 0 m 356 -285 l 274 -285 l 274 -326 l 417 -326 l 417 0 l 356 0 l +p ef +630 0 m 630 -183 l 548 -183 l 548 -224 l 691 -224 l 691 0 l 630 0 l +p +630 -265 m 630 -326 l 691 -326 l 691 -265 l 630 -265 l p ef +989 -4 m 964 2 939 5 914 5 ct 873 5 840 -5 817 -26 ct 794 -47 782 -75 782 -111 ct +782 -148 793 -177 816 -198 ct 838 -219 870 -229 910 -229 ct 940 -229 966 -226 989 -220 ct +989 -220 989 -220 989 -175 ct 964 -184 941 -188 918 -188 ct 896 -188 879 -182 867 -169 ct +854 -157 848 -140 848 -118 ct 848 -94 856 -74 871 -60 ct 886 -45 906 -38 931 -38 ct +950 -38 970 -42 989 -49 ct 989 -49 989 -49 989 -4 ct p ef +1252 -95 m 1252 -95 1252 -95 1100 -95 ct 1103 -77 1111 -63 1123 -54 ct 1135 -45 1151 -41 1172 -41 ct +1196 -41 1223 -46 1252 -56 ct 1252 -56 1252 -56 1252 -9 ct 1217 0 1186 5 1160 5 ct +1122 5 1091 -6 1068 -27 ct 1045 -48 1034 -76 1034 -111 ct 1034 -147 1045 -175 1066 -197 ct +1088 -218 1116 -229 1151 -229 ct 1183 -229 1207 -219 1225 -199 ct 1243 -180 1252 -152 1252 -118 ct +1252 -118 1252 -118 1252 -95 ct p +1099 -136 m 1099 -136 1099 -136 1193 -136 ct 1193 -153 1189 -166 1182 -175 ct +1174 -184 1163 -188 1148 -188 ct 1134 -188 1122 -184 1114 -175 ct 1106 -166 1101 -153 1099 -136 ct +p ef +pom +gr +gs +pum +16531 4540 t +281 0 m 281 0 281 0 281 -306 ct 281 -306 281 -306 361 -306 ct 405 -306 438 -294 460 -269 ct +482 -244 493 -207 493 -158 ct 493 -105 481 -66 457 -39 ct 433 -13 398 0 350 0 ct +350 0 350 0 281 0 ct p +322 -31 m 322 -31 322 -31 342 -31 ct 381 -31 409 -41 425 -60 ct 442 -79 450 -111 450 -155 ct +450 -204 439 -238 417 -257 ct 403 -269 378 -275 341 -275 ct 341 -275 341 -275 322 -275 ct +322 -275 322 -275 322 -31 ct p ef +726 -224 m 726 -224 726 -224 726 0 ct 726 0 726 0 685 0 ct 685 0 685 0 687 -42 ct +687 -42 687 -42 685 -42 ct 676 -26 664 -15 652 -7 ct 639 1 624 5 608 5 ct 587 5 571 -1 560 -14 ct +549 -27 544 -46 544 -71 ct 544 -71 544 -71 544 -224 ct 544 -224 544 -224 585 -224 ct +585 -224 585 -224 585 -82 ct 585 -65 588 -52 593 -45 ct 599 -38 608 -34 621 -34 ct +631 -34 641 -38 652 -45 ct 663 -52 674 -63 685 -78 ct 685 -78 685 -78 685 -224 ct +685 -224 685 -224 726 -224 ct p ef +781 0 m 781 0 781 0 781 -224 ct 781 -224 781 -224 817 -224 ct 817 -224 817 -224 814 -182 ct +814 -182 814 -182 817 -182 ct 825 -198 834 -209 843 -217 ct 851 -225 859 -229 867 -229 ct +878 -229 886 -225 893 -216 ct 900 -208 904 -196 905 -182 ct 905 -182 905 -182 908 -182 ct +915 -198 923 -209 931 -217 ct 940 -225 949 -229 959 -229 ct 972 -229 982 -224 989 -213 ct +996 -202 999 -186 999 -164 ct 999 -164 999 -164 999 0 ct 999 0 999 0 963 0 ct 963 0 963 0 963 -162 ct +963 -172 962 -180 960 -185 ct 958 -190 954 -193 950 -193 ct 944 -193 937 -189 930 -181 ct +923 -173 915 -160 908 -144 ct 908 -144 908 -144 908 0 ct 908 0 908 0 872 0 ct 872 0 872 0 872 -155 ct +872 -167 871 -177 869 -183 ct 866 -190 863 -193 859 -193 ct 853 -193 846 -188 838 -179 ct +830 -170 823 -158 817 -144 ct 817 -144 817 -144 817 0 ct 817 0 817 0 781 0 ct p ef +1053 82 m 1053 82 1053 82 1053 -224 ct 1053 -224 1053 -224 1094 -224 ct 1094 -224 1094 -224 1092 -182 ct +1092 -182 1092 -182 1094 -182 ct 1104 -198 1115 -209 1127 -217 ct 1139 -225 1153 -229 1167 -229 ct +1192 -229 1212 -219 1227 -200 ct 1242 -180 1249 -153 1249 -120 ct 1249 -82 1240 -52 1223 -29 ct +1206 -6 1183 5 1155 5 ct 1143 5 1132 2 1122 -3 ct 1112 -8 1102 -15 1094 -26 ct +1094 -26 1094 -26 1092 -26 ct 1092 -26 1092 -26 1094 5 ct 1094 5 1094 5 1094 82 ct +1094 82 1094 82 1053 82 ct p +1094 -56 m 1103 -46 1113 -39 1122 -34 ct 1131 -29 1140 -26 1150 -26 ct 1168 -26 1181 -34 1191 -49 ct +1201 -65 1206 -87 1206 -115 ct 1206 -141 1202 -160 1194 -173 ct 1186 -186 1175 -193 1159 -193 ct +1148 -193 1136 -189 1125 -182 ct 1115 -175 1104 -165 1094 -151 ct 1094 -151 1094 -151 1094 -56 ct +p ef +1367 66 m 1367 66 1367 66 1367 46 ct 1374 45 1380 41 1384 33 ct 1389 25 1391 14 1392 0 ct +1392 0 1392 0 1367 0 ct 1367 0 1367 0 1367 -61 ct 1367 -61 1367 -61 1428 -61 ct +1428 -61 1428 -61 1428 -24 ct 1428 5 1423 27 1413 42 ct 1403 57 1387 65 1367 66 ct +p +1367 -163 m 1367 -224 l 1428 -224 l 1428 -163 l 1367 -163 l p ef +pom +gr +gs +pum +10435 5031 t +pom +gr +gs +pum +10943 5031 t +0.003 0.503 0.003 c 239 -326 m 65 61 l 15 61 l 189 -326 l 239 -326 l +p ef +493 -326 m 319 61 l 269 61 l 443 -326 l 493 -326 l p ef +915 -24 m 908 -14 899 -7 889 -2 ct 879 3 868 5 855 5 ct 833 5 815 -2 801 -15 ct +787 -28 780 -45 780 -65 ct 780 -91 790 -111 809 -124 ct 829 -137 858 -143 897 -143 ct +897 -143 897 -143 921 -143 ct 921 -143 921 -143 921 -154 ct 921 -165 917 -174 909 -179 ct +901 -185 889 -188 873 -188 ct 851 -188 826 -182 799 -169 ct 799 -169 799 -169 799 -214 ct +827 -224 855 -229 884 -229 ct 916 -229 940 -223 956 -211 ct 966 -203 973 -194 977 -185 ct +980 -175 982 -160 982 -140 ct 982 -140 982 -140 982 -64 ct 982 -49 987 -41 996 -41 ct +998 -41 1000 -41 1003 -42 ct 1003 -42 1003 -42 1003 -2 ct 991 3 979 5 969 5 ct +958 5 948 3 940 -2 ct 932 -7 926 -14 921 -24 ct 921 -24 921 -24 915 -24 ct p +921 -65 m 921 -65 921 -65 921 -102 ct 921 -102 921 -102 899 -102 ct 880 -102 865 -99 856 -94 ct +846 -88 841 -80 841 -69 ct 841 -61 844 -54 850 -49 ct 856 -44 863 -41 872 -41 ct +887 -41 904 -49 921 -65 ct p ef +1190 0 m 1190 0 1190 0 1192 -42 ct 1192 -42 1192 -42 1190 -42 ct 1180 -27 1169 -15 1157 -7 ct +1146 1 1133 5 1119 5 ct 1093 5 1073 -5 1057 -26 ct 1042 -46 1034 -73 1034 -107 ct +1034 -144 1043 -174 1060 -196 ct 1077 -218 1100 -229 1129 -229 ct 1141 -229 1152 -227 1162 -222 ct +1172 -218 1181 -211 1190 -203 ct 1190 -203 1190 -203 1192 -203 ct 1192 -203 1192 -203 1190 -224 ct +1190 -224 1190 -224 1190 -326 ct 1190 -326 1190 -326 1251 -326 ct 1251 -326 1251 -326 1251 0 ct +1251 0 1251 0 1190 0 ct p +1190 -160 m 1183 -168 1176 -173 1169 -177 ct 1162 -181 1154 -183 1146 -183 ct +1130 -183 1119 -177 1111 -164 ct 1104 -152 1100 -133 1100 -108 ct 1100 -89 1103 -75 1110 -65 ct +1117 -56 1127 -51 1140 -51 ct 1149 -51 1157 -54 1166 -60 ct 1174 -66 1182 -75 1190 -88 ct +1190 -88 1190 -88 1190 -160 ct p ef +1368 0 m 1279 -224 l 1345 -224 l 1407 -67 l 1468 -224 l 1517 -224 l +1429 0 l 1368 0 l p ef +1646 0 m 1646 -183 l 1564 -183 l 1564 -224 l 1707 -224 l 1707 0 l +1646 0 l p +1646 -265 m 1646 -326 l 1707 -326 l 1707 -265 l 1646 -265 l p ef +2005 -4 m 1980 2 1955 5 1930 5 ct 1889 5 1856 -5 1833 -26 ct 1810 -47 1798 -75 1798 -111 ct +1798 -148 1809 -177 1832 -198 ct 1854 -219 1886 -229 1926 -229 ct 1956 -229 1982 -226 2005 -220 ct +2005 -220 2005 -220 2005 -175 ct 1980 -184 1957 -188 1934 -188 ct 1912 -188 1895 -182 1883 -169 ct +1870 -157 1864 -140 1864 -118 ct 1864 -94 1872 -74 1887 -60 ct 1902 -45 1922 -38 1947 -38 ct +1966 -38 1986 -42 2005 -49 ct 2005 -49 2005 -49 2005 -4 ct p ef +2268 -95 m 2268 -95 2268 -95 2116 -95 ct 2119 -77 2127 -63 2139 -54 ct 2151 -45 2167 -41 2188 -41 ct +2212 -41 2239 -46 2268 -56 ct 2268 -56 2268 -56 2268 -9 ct 2233 0 2202 5 2176 5 ct +2138 5 2107 -6 2084 -27 ct 2061 -48 2050 -76 2050 -111 ct 2050 -147 2061 -175 2082 -197 ct +2104 -218 2132 -229 2167 -229 ct 2199 -229 2223 -219 2241 -199 ct 2259 -180 2268 -152 2268 -118 ct +2268 -118 2268 -118 2268 -95 ct p +2115 -136 m 2115 -136 2115 -136 2209 -136 ct 2209 -153 2205 -166 2198 -175 ct +2190 -184 2179 -188 2164 -188 ct 2150 -188 2138 -184 2130 -175 ct 2122 -166 2117 -153 2115 -136 ct +p ef +2768 -6 m 2744 1 2722 5 2704 5 ct 2675 5 2654 -1 2640 -14 ct 2626 -26 2619 -45 2619 -70 ct +2619 -70 2619 -70 2619 -178 ct 2619 -178 2619 -178 2571 -178 ct 2571 -178 2571 -178 2571 -219 ct +2571 -219 2571 -219 2619 -219 ct 2619 -219 2619 -219 2619 -285 ct 2619 -285 2619 -285 2680 -285 ct +2680 -285 2680 -285 2680 -219 ct 2680 -219 2680 -219 2763 -219 ct 2763 -219 2763 -219 2763 -178 ct +2763 -178 2763 -178 2680 -178 ct 2680 -178 2680 -178 2680 -84 ct 2680 -68 2683 -57 2689 -51 ct +2695 -44 2705 -41 2719 -41 ct 2736 -41 2752 -44 2768 -51 ct 2768 -51 2768 -51 2768 -6 ct +p ef +2823 0 m 2823 0 2823 0 2823 -326 ct 2823 -326 2823 -326 2884 -326 ct 2884 -326 2884 -326 2884 -224 ct +2884 -224 2884 -224 2882 -181 ct 2882 -181 2882 -181 2884 -181 ct 2891 -197 2900 -209 2912 -217 ct +2924 -225 2938 -229 2956 -229 ct 2978 -229 2994 -223 3005 -210 ct 3016 -197 3022 -178 3022 -153 ct +3022 -153 3022 -153 3022 0 ct 3022 0 3022 0 2961 0 ct 2961 0 2961 0 2961 -139 ct +2961 -150 2959 -159 2955 -165 ct 2950 -170 2944 -173 2935 -173 ct 2926 -173 2917 -170 2908 -165 ct +2900 -159 2891 -151 2884 -139 ct 2884 -139 2884 -139 2884 0 ct 2884 0 2884 0 2823 0 ct +p ef +3201 -24 m 3194 -14 3185 -7 3175 -2 ct 3165 3 3154 5 3141 5 ct 3119 5 3101 -2 3087 -15 ct +3073 -28 3066 -45 3066 -65 ct 3066 -91 3076 -111 3095 -124 ct 3115 -137 3144 -143 3183 -143 ct +3183 -143 3183 -143 3207 -143 ct 3207 -143 3207 -143 3207 -154 ct 3207 -165 3203 -174 3195 -179 ct +3187 -185 3175 -188 3159 -188 ct 3137 -188 3112 -182 3085 -169 ct 3085 -169 3085 -169 3085 -214 ct +3113 -224 3141 -229 3170 -229 ct 3202 -229 3226 -223 3242 -211 ct 3252 -203 3259 -194 3263 -185 ct +3266 -175 3268 -160 3268 -140 ct 3268 -140 3268 -140 3268 -64 ct 3268 -49 3273 -41 3282 -41 ct +3284 -41 3286 -41 3289 -42 ct 3289 -42 3289 -42 3289 -2 ct 3277 3 3265 5 3255 5 ct +3244 5 3234 3 3226 -2 ct 3218 -7 3212 -14 3207 -24 ct 3207 -24 3207 -24 3201 -24 ct +p +3207 -65 m 3207 -65 3207 -65 3207 -102 ct 3207 -102 3207 -102 3185 -102 ct +3166 -102 3151 -99 3142 -94 ct 3132 -88 3127 -80 3127 -69 ct 3127 -61 3130 -54 3136 -49 ct +3142 -44 3149 -41 3158 -41 ct 3173 -41 3190 -49 3207 -65 ct p ef +3530 -6 m 3506 1 3484 5 3466 5 ct 3437 5 3416 -1 3402 -14 ct 3388 -26 3381 -45 3381 -70 ct +3381 -70 3381 -70 3381 -178 ct 3381 -178 3381 -178 3333 -178 ct 3333 -178 3333 -178 3333 -219 ct +3333 -219 3333 -219 3381 -219 ct 3381 -219 3381 -219 3381 -285 ct 3381 -285 3381 -285 3442 -285 ct +3442 -285 3442 -285 3442 -219 ct 3442 -219 3442 -219 3525 -219 ct 3525 -219 3525 -219 3525 -178 ct +3525 -178 3525 -178 3442 -178 ct 3442 -178 3442 -178 3442 -84 ct 3442 -68 3445 -57 3451 -51 ct +3457 -44 3467 -41 3481 -41 ct 3498 -41 3514 -44 3530 -51 ct 3530 -51 3530 -51 3530 -6 ct +p ef +3839 0 m 3839 0 3839 0 3839 -224 ct 3839 -224 3839 -224 3900 -224 ct 3900 -224 3900 -224 3899 -202 ct +3899 -202 3899 -202 3898 -181 ct 3898 -181 3898 -181 3900 -181 ct 3907 -197 3916 -209 3928 -217 ct +3940 -225 3954 -229 3972 -229 ct 3994 -229 4010 -223 4021 -210 ct 4032 -197 4038 -178 4038 -153 ct +4038 -153 4038 -153 4038 0 ct 4038 0 4038 0 3977 0 ct 3977 0 3977 0 3977 -139 ct +3977 -150 3975 -159 3971 -165 ct 3966 -170 3960 -173 3951 -173 ct 3942 -173 3933 -170 3924 -165 ct +3916 -159 3907 -151 3900 -139 ct 3900 -139 3900 -139 3900 0 ct 3900 0 3900 0 3839 0 ct +p ef +4300 -95 m 4300 -95 4300 -95 4148 -95 ct 4151 -77 4159 -63 4171 -54 ct 4183 -45 4199 -41 4220 -41 ct +4244 -41 4271 -46 4300 -56 ct 4300 -56 4300 -56 4300 -9 ct 4265 0 4234 5 4208 5 ct +4170 5 4139 -6 4116 -27 ct 4093 -48 4082 -76 4082 -111 ct 4082 -147 4093 -175 4114 -197 ct +4136 -218 4164 -229 4199 -229 ct 4231 -229 4255 -219 4273 -199 ct 4291 -180 4300 -152 4300 -118 ct +4300 -118 4300 -118 4300 -95 ct p +4147 -136 m 4147 -136 4147 -136 4241 -136 ct 4241 -153 4237 -166 4230 -175 ct +4222 -184 4211 -188 4196 -188 ct 4182 -188 4170 -184 4162 -175 ct 4154 -166 4149 -153 4147 -136 ct +p ef +4554 -95 m 4554 -95 4554 -95 4402 -95 ct 4405 -77 4413 -63 4425 -54 ct 4437 -45 4453 -41 4474 -41 ct +4498 -41 4525 -46 4554 -56 ct 4554 -56 4554 -56 4554 -9 ct 4519 0 4488 5 4462 5 ct +4424 5 4393 -6 4370 -27 ct 4347 -48 4336 -76 4336 -111 ct 4336 -147 4347 -175 4368 -197 ct +4390 -218 4418 -229 4453 -229 ct 4485 -229 4509 -219 4527 -199 ct 4545 -180 4554 -152 4554 -118 ct +4554 -118 4554 -118 4554 -95 ct p +4401 -136 m 4401 -136 4401 -136 4495 -136 ct 4495 -153 4491 -166 4484 -175 ct +4476 -184 4465 -188 4450 -188 ct 4436 -188 4424 -184 4416 -175 ct 4408 -166 4403 -153 4401 -136 ct +p ef +4746 0 m 4746 0 4746 0 4748 -42 ct 4748 -42 4748 -42 4746 -42 ct 4736 -27 4725 -15 4713 -7 ct +4702 1 4689 5 4675 5 ct 4649 5 4629 -5 4613 -26 ct 4598 -46 4590 -73 4590 -107 ct +4590 -144 4599 -174 4616 -196 ct 4633 -218 4656 -229 4685 -229 ct 4697 -229 4708 -227 4718 -222 ct +4728 -218 4737 -211 4746 -203 ct 4746 -203 4746 -203 4748 -203 ct 4748 -203 4748 -203 4746 -224 ct +4746 -224 4746 -224 4746 -326 ct 4746 -326 4746 -326 4807 -326 ct 4807 -326 4807 -326 4807 0 ct +4807 0 4807 0 4746 0 ct p +4746 -160 m 4739 -168 4732 -173 4725 -177 ct 4718 -181 4710 -183 4702 -183 ct +4686 -183 4675 -177 4667 -164 ct 4660 -152 4656 -133 4656 -108 ct 4656 -89 4659 -75 4666 -65 ct +4673 -56 4683 -51 4696 -51 ct 4705 -51 4713 -54 4722 -60 ct 4730 -66 4738 -75 4746 -88 ct +4746 -88 4746 -88 4746 -160 ct p ef +4859 -8 m 4859 -8 4859 -8 4859 -54 ct 4893 -42 4921 -36 4941 -36 ct 4956 -36 4967 -38 4975 -42 ct +4982 -46 4986 -52 4986 -60 ct 4986 -64 4984 -68 4980 -72 ct 4977 -75 4971 -79 4964 -82 ct +4964 -82 4964 -82 4916 -101 ct 4897 -109 4883 -118 4874 -127 ct 4865 -137 4860 -148 4860 -161 ct +4860 -182 4870 -199 4889 -211 ct 4908 -223 4935 -229 4969 -229 ct 4989 -229 5012 -226 5038 -221 ct +5038 -221 5038 -221 5038 -174 ct 5010 -183 4986 -188 4967 -188 ct 4952 -188 4942 -186 4935 -183 ct +4928 -180 4924 -175 4924 -169 ct 4924 -165 4927 -162 4932 -158 ct 4937 -154 4944 -150 4954 -146 ct +4954 -146 4954 -146 5007 -124 ct 5023 -118 5035 -110 5042 -100 ct 5050 -91 5054 -79 5054 -66 ct +5054 -45 5045 -28 5026 -15 ct 5007 -2 4983 5 4953 5 ct 4927 5 4895 1 4859 -8 ct +p ef +5431 0 m 5431 -265 l 5339 -265 l 5339 -306 l 5584 -306 l 5584 -265 l +5492 -265 l 5492 0 l 5431 0 l p ef +5741 -24 m 5734 -14 5725 -7 5715 -2 ct 5705 3 5694 5 5681 5 ct 5659 5 5641 -2 5627 -15 ct +5613 -28 5606 -45 5606 -65 ct 5606 -91 5616 -111 5635 -124 ct 5655 -137 5684 -143 5723 -143 ct +5723 -143 5723 -143 5747 -143 ct 5747 -143 5747 -143 5747 -154 ct 5747 -165 5743 -174 5735 -179 ct +5727 -185 5715 -188 5699 -188 ct 5677 -188 5652 -182 5625 -169 ct 5625 -169 5625 -169 5625 -214 ct +5653 -224 5681 -229 5710 -229 ct 5742 -229 5766 -223 5782 -211 ct 5792 -203 5799 -194 5803 -185 ct +5806 -175 5808 -160 5808 -140 ct 5808 -140 5808 -140 5808 -64 ct 5808 -49 5813 -41 5822 -41 ct +5824 -41 5826 -41 5829 -42 ct 5829 -42 5829 -42 5829 -2 ct 5817 3 5805 5 5795 5 ct +5784 5 5774 3 5766 -2 ct 5758 -7 5752 -14 5747 -24 ct 5747 -24 5747 -24 5741 -24 ct +p +5747 -65 m 5747 -65 5747 -65 5747 -102 ct 5747 -102 5747 -102 5725 -102 ct +5706 -102 5691 -99 5682 -94 ct 5672 -88 5667 -80 5667 -69 ct 5667 -61 5670 -54 5676 -49 ct +5682 -44 5689 -41 5698 -41 ct 5713 -41 5730 -49 5747 -65 ct p ef +5888 0 m 5888 0 5888 0 5888 -224 ct 5888 -224 5888 -224 5949 -224 ct 5949 -224 5949 -224 5947 -181 ct +5947 -181 5947 -181 5949 -181 ct 5959 -197 5971 -209 5985 -217 ct 5998 -225 6014 -229 6032 -229 ct +6043 -229 6058 -227 6074 -224 ct 6074 -224 6074 -224 6074 -149 ct 6074 -149 6074 -149 6033 -149 ct +6033 -149 6033 -149 6033 -173 ct 6028 -174 6025 -174 6022 -174 ct 6007 -174 5994 -170 5981 -163 ct +5969 -156 5958 -145 5949 -130 ct 5949 -130 5949 -130 5949 0 ct 5949 0 5949 0 5888 0 ct +p ef +6136 69 m 6136 69 6136 69 6142 25 ct 6174 38 6200 44 6220 44 ct 6238 44 6251 39 6259 30 ct +6268 21 6272 7 6272 -11 ct 6272 -11 6272 -11 6273 -53 ct 6273 -53 6273 -53 6271 -53 ct +6263 -35 6253 -22 6242 -13 ct 6230 -4 6216 0 6200 0 ct 6174 0 6153 -10 6138 -31 ct +6122 -51 6114 -78 6114 -111 ct 6114 -147 6123 -175 6140 -197 ct 6158 -218 6181 -229 6210 -229 ct +6222 -229 6232 -227 6242 -223 ct 6252 -218 6261 -212 6270 -204 ct 6270 -204 6270 -204 6275 -204 ct +6275 -204 6275 -204 6280 -224 ct 6280 -224 6280 -224 6331 -224 ct 6331 -224 6331 -224 6331 -27 ct +6331 10 6322 38 6304 58 ct 6287 77 6261 87 6228 87 ct 6202 87 6171 81 6136 69 ct +p +6270 -95 m 6270 -95 6270 -95 6270 -163 ct 6262 -169 6254 -174 6246 -178 ct +6239 -181 6232 -183 6225 -183 ct 6210 -183 6199 -177 6191 -166 ct 6184 -155 6180 -138 6180 -116 ct +6180 -97 6183 -83 6190 -73 ct 6197 -64 6206 -59 6220 -59 ct 6229 -59 6238 -62 6247 -68 ct +6255 -74 6263 -83 6270 -95 ct p ef +6586 -95 m 6586 -95 6586 -95 6434 -95 ct 6437 -77 6445 -63 6457 -54 ct 6469 -45 6485 -41 6506 -41 ct +6530 -41 6557 -46 6586 -56 ct 6586 -56 6586 -56 6586 -9 ct 6551 0 6520 5 6494 5 ct +6456 5 6425 -6 6402 -27 ct 6379 -48 6368 -76 6368 -111 ct 6368 -147 6379 -175 6400 -197 ct +6422 -218 6450 -229 6485 -229 ct 6517 -229 6541 -219 6559 -199 ct 6577 -180 6586 -152 6586 -118 ct +6586 -118 6586 -118 6586 -95 ct p +6433 -136 m 6433 -136 6433 -136 6527 -136 ct 6527 -153 6523 -166 6516 -175 ct +6508 -184 6497 -188 6482 -188 ct 6468 -188 6456 -184 6448 -175 ct 6440 -166 6435 -153 6433 -136 ct +p ef +6832 -6 m 6808 1 6786 5 6768 5 ct 6739 5 6718 -1 6704 -14 ct 6690 -26 6683 -45 6683 -70 ct +6683 -70 6683 -70 6683 -178 ct 6683 -178 6683 -178 6635 -178 ct 6635 -178 6635 -178 6635 -219 ct +6635 -219 6635 -219 6683 -219 ct 6683 -219 6683 -219 6683 -285 ct 6683 -285 6683 -285 6744 -285 ct +6744 -285 6744 -285 6744 -219 ct 6744 -219 6744 -219 6827 -219 ct 6827 -219 6827 -219 6827 -178 ct +6827 -178 6827 -178 6744 -178 ct 6744 -178 6744 -178 6744 -84 ct 6744 -68 6747 -57 6753 -51 ct +6759 -44 6769 -41 6783 -41 ct 6800 -41 6816 -44 6832 -51 ct 6832 -51 6832 -51 6832 -6 ct +p ef +6950 0 m 6950 -71 l 7021 -71 l 7021 0 l 6950 0 l p +6950 -153 m 6950 -224 l 7021 -224 l 7021 -153 l 6950 -153 l p ef +pom +gr +gs +pum +10435 5522 t +pom +gr +gs +pum +10943 5522 t +0.003 0.003 1.000 c 153 -24 m 146 -14 137 -7 127 -2 ct 117 3 106 5 93 5 ct 71 5 53 -2 39 -15 ct +25 -28 18 -45 18 -65 ct 18 -91 28 -111 47 -124 ct 67 -137 96 -143 135 -143 ct 135 -143 135 -143 159 -143 ct +159 -143 159 -143 159 -154 ct 159 -165 155 -174 147 -179 ct 139 -185 127 -188 111 -188 ct +89 -188 64 -182 37 -169 ct 37 -169 37 -169 37 -214 ct 65 -224 93 -229 122 -229 ct +154 -229 178 -223 194 -211 ct 204 -203 211 -194 215 -185 ct 218 -175 220 -160 220 -140 ct +220 -140 220 -140 220 -64 ct 220 -49 225 -41 234 -41 ct 236 -41 238 -41 241 -42 ct +241 -42 241 -42 241 -2 ct 229 3 217 5 207 5 ct 196 5 186 3 178 -2 ct 170 -7 164 -14 159 -24 ct +159 -24 159 -24 153 -24 ct p +159 -65 m 159 -65 159 -65 159 -102 ct 159 -102 159 -102 137 -102 ct 118 -102 103 -99 94 -94 ct +84 -88 79 -80 79 -69 ct 79 -61 82 -54 88 -49 ct 94 -44 101 -41 110 -41 ct 125 -41 142 -49 159 -65 ct +p ef +428 0 m 428 0 428 0 430 -42 ct 430 -42 430 -42 428 -42 ct 418 -27 407 -15 395 -7 ct +384 1 371 5 357 5 ct 331 5 311 -5 295 -26 ct 280 -46 272 -73 272 -107 ct 272 -144 281 -174 298 -196 ct +315 -218 338 -229 367 -229 ct 379 -229 390 -227 400 -222 ct 410 -218 419 -211 428 -203 ct +428 -203 428 -203 430 -203 ct 430 -203 430 -203 428 -224 ct 428 -224 428 -224 428 -326 ct +428 -326 428 -326 489 -326 ct 489 -326 489 -326 489 0 ct 489 0 489 0 428 0 ct p +428 -160 m 421 -168 414 -173 407 -177 ct 400 -181 392 -183 384 -183 ct 368 -183 357 -177 349 -164 ct +342 -152 338 -133 338 -108 ct 338 -89 341 -75 348 -65 ct 355 -56 365 -51 378 -51 ct +387 -51 395 -54 404 -60 ct 412 -66 420 -75 428 -88 ct 428 -88 428 -88 428 -160 ct +p ef +606 0 m 517 -224 l 583 -224 l 645 -67 l 706 -224 l 755 -224 l 667 0 l +606 0 l p ef +884 0 m 884 -183 l 802 -183 l 802 -224 l 945 -224 l 945 0 l 884 0 l +p +884 -265 m 884 -326 l 945 -326 l 945 -265 l 884 -265 l p ef +1243 -4 m 1218 2 1193 5 1168 5 ct 1127 5 1094 -5 1071 -26 ct 1048 -47 1036 -75 1036 -111 ct +1036 -148 1047 -177 1070 -198 ct 1092 -219 1124 -229 1164 -229 ct 1194 -229 1220 -226 1243 -220 ct +1243 -220 1243 -220 1243 -175 ct 1218 -184 1195 -188 1172 -188 ct 1150 -188 1133 -182 1121 -169 ct +1108 -157 1102 -140 1102 -118 ct 1102 -94 1110 -74 1125 -60 ct 1140 -45 1160 -38 1185 -38 ct +1204 -38 1224 -42 1243 -49 ct 1243 -49 1243 -49 1243 -4 ct p ef +1506 -95 m 1506 -95 1506 -95 1354 -95 ct 1357 -77 1365 -63 1377 -54 ct 1389 -45 1405 -41 1426 -41 ct +1450 -41 1477 -46 1506 -56 ct 1506 -56 1506 -56 1506 -9 ct 1471 0 1440 5 1414 5 ct +1376 5 1345 -6 1322 -27 ct 1299 -48 1288 -76 1288 -111 ct 1288 -147 1299 -175 1320 -197 ct +1342 -218 1370 -229 1405 -229 ct 1437 -229 1461 -219 1479 -199 ct 1497 -180 1506 -152 1506 -118 ct +1506 -118 1506 -118 1506 -95 ct p +1353 -136 m 1353 -136 1353 -136 1447 -136 ct 1447 -153 1443 -166 1436 -175 ct +1428 -184 1417 -188 1402 -188 ct 1388 -188 1376 -184 1368 -175 ct 1360 -166 1355 -153 1353 -136 ct +p ef +pom +gr +gs +pum +12467 5522 t +480 -9 m 452 0 426 5 402 5 ct 364 5 335 -5 314 -25 ct 293 -45 283 -73 283 -110 ct +283 -144 293 -173 313 -195 ct 333 -218 358 -229 389 -229 ct 420 -229 442 -220 457 -201 ct +472 -182 479 -153 479 -114 ct 479 -114 479 -114 479 -101 ct 479 -101 479 -101 325 -101 ct +326 -76 334 -57 348 -45 ct 362 -32 381 -26 407 -26 ct 430 -26 454 -31 480 -42 ct +480 -42 480 -42 480 -9 ct p +326 -132 m 326 -132 326 -132 436 -132 ct 436 -132 436 -132 436 -138 ct 436 -158 432 -173 423 -183 ct +414 -193 402 -198 385 -198 ct 368 -198 355 -192 344 -181 ct 334 -169 328 -153 326 -132 ct +p ef +527 0 m 611 -112 l 527 -224 l 578 -224 l 640 -141 l 696 -224 l 737 -224 l +660 -114 l 746 0 l 695 0 l 632 -84 l 568 0 l 527 0 l p ef +988 -9 m 960 0 934 5 910 5 ct 872 5 843 -5 822 -25 ct 801 -45 791 -73 791 -110 ct +791 -144 801 -173 821 -195 ct 841 -218 866 -229 897 -229 ct 928 -229 950 -220 965 -201 ct +980 -182 987 -153 987 -114 ct 987 -114 987 -114 987 -101 ct 987 -101 987 -101 833 -101 ct +834 -76 842 -57 856 -45 ct 870 -32 889 -26 915 -26 ct 938 -26 962 -31 988 -42 ct +988 -42 988 -42 988 -9 ct p +834 -132 m 834 -132 834 -132 944 -132 ct 944 -132 944 -132 944 -138 ct 944 -158 940 -173 931 -183 ct +922 -193 910 -198 893 -198 ct 876 -198 863 -192 852 -181 ct 842 -169 836 -153 834 -132 ct +p ef +1244 -7 m 1220 1 1196 5 1172 5 ct 1133 5 1103 -5 1082 -26 ct 1061 -46 1050 -75 1050 -112 ct +1050 -149 1060 -177 1081 -198 ct 1102 -219 1131 -229 1168 -229 ct 1192 -229 1216 -225 1240 -218 ct +1240 -218 1240 -218 1240 -184 ct 1213 -193 1191 -198 1172 -198 ct 1148 -198 1128 -190 1114 -175 ct +1100 -160 1093 -139 1093 -112 ct 1093 -85 1100 -64 1115 -49 ct 1130 -34 1151 -26 1177 -26 ct +1197 -26 1219 -31 1244 -40 ct 1244 -40 1244 -40 1244 -7 ct p ef +1488 -224 m 1488 -224 1488 -224 1488 0 ct 1488 0 1488 0 1447 0 ct 1447 0 1447 0 1449 -42 ct +1449 -42 1449 -42 1447 -42 ct 1438 -26 1426 -15 1414 -7 ct 1401 1 1386 5 1370 5 ct +1349 5 1333 -1 1322 -14 ct 1311 -27 1306 -46 1306 -71 ct 1306 -71 1306 -71 1306 -224 ct +1306 -224 1306 -224 1347 -224 ct 1347 -224 1347 -224 1347 -82 ct 1347 -65 1350 -52 1355 -45 ct +1361 -38 1370 -34 1383 -34 ct 1393 -34 1403 -38 1414 -45 ct 1425 -52 1436 -63 1447 -78 ct +1447 -78 1447 -78 1447 -224 ct 1447 -224 1447 -224 1488 -224 ct p ef +1752 0 m 1732 3 1712 5 1693 5 ct 1660 5 1637 -1 1625 -13 ct 1613 -25 1607 -47 1607 -80 ct +1607 -80 1607 -80 1607 -188 ct 1607 -188 1607 -188 1551 -188 ct 1551 -188 1551 -188 1551 -219 ct +1551 -219 1551 -219 1607 -219 ct 1607 -219 1607 -219 1607 -267 ct 1607 -267 1607 -267 1648 -267 ct +1648 -267 1648 -267 1648 -219 ct 1648 -219 1648 -219 1747 -219 ct 1747 -219 1747 -219 1747 -188 ct +1747 -188 1747 -188 1648 -188 ct 1648 -188 1648 -188 1648 -74 ct 1648 -61 1649 -53 1650 -48 ct +1652 -43 1655 -39 1661 -35 ct 1670 -29 1683 -26 1701 -26 ct 1718 -26 1735 -28 1752 -31 ct +1752 -31 1752 -31 1752 0 ct p ef +1895 0 m 1895 -193 l 1813 -193 l 1813 -224 l 1936 -224 l 1936 0 l +1895 0 l p +1890 -275 m 1890 -326 l 1941 -326 l 1941 -275 l 1890 -275 l p ef +2158 5 m 2126 5 2101 -6 2082 -27 ct 2063 -48 2054 -76 2054 -112 ct 2054 -148 2063 -177 2082 -198 ct +2101 -219 2127 -229 2160 -229 ct 2192 -229 2218 -219 2237 -198 ct 2256 -177 2265 -149 2265 -113 ct +2265 -76 2256 -47 2237 -26 ct 2218 -5 2192 5 2158 5 ct p +2159 -26 m 2180 -26 2196 -33 2206 -48 ct 2217 -62 2222 -84 2222 -113 ct 2222 -139 2216 -160 2205 -175 ct +2194 -190 2179 -198 2160 -198 ct 2140 -198 2125 -190 2114 -175 ct 2103 -160 2097 -139 2097 -112 ct +2097 -85 2102 -64 2113 -49 ct 2124 -34 2140 -26 2159 -26 ct p ef +2323 0 m 2323 0 2323 0 2323 -224 ct 2323 -224 2323 -224 2364 -224 ct 2364 -224 2364 -224 2362 -182 ct +2362 -182 2362 -182 2364 -182 ct 2374 -198 2385 -209 2398 -217 ct 2410 -225 2425 -229 2441 -229 ct +2462 -229 2478 -223 2489 -210 ct 2500 -197 2505 -178 2505 -153 ct 2505 -153 2505 -153 2505 0 ct +2505 0 2505 0 2464 0 ct 2464 0 2464 0 2464 -142 ct 2464 -159 2461 -172 2456 -179 ct +2450 -186 2441 -190 2428 -190 ct 2418 -190 2408 -186 2397 -179 ct 2386 -172 2375 -161 2364 -146 ct +2364 -146 2364 -146 2364 0 ct 2364 0 2364 0 2323 0 ct p ef +2764 61 m 2719 56 2683 36 2654 -1 ct 2625 -37 2611 -81 2611 -133 ct 2611 -184 2625 -228 2654 -264 ct +2683 -301 2719 -321 2764 -326 ct 2764 -326 2764 -326 2764 -298 ct 2728 -291 2700 -273 2681 -244 ct +2662 -216 2652 -178 2652 -133 ct 2652 -87 2662 -49 2681 -21 ct 2700 8 2728 26 2764 33 ct +2764 33 2764 33 2764 61 ct p ef +2845 -214 m 2845 -214 2845 -214 2845 -260 ct 2845 -282 2849 -298 2858 -309 ct +2866 -320 2879 -326 2896 -326 ct 2896 -326 2896 -326 2896 -306 ct 2889 -306 2883 -303 2879 -298 ct +2876 -293 2874 -286 2874 -276 ct 2874 -276 2874 -276 2874 -265 ct 2874 -265 2874 -265 2896 -265 ct +2896 -265 2896 -265 2896 -214 ct 2896 -214 2896 -214 2845 -214 ct p +2947 -214 m 2947 -214 2947 -214 2947 -260 ct 2947 -282 2951 -298 2960 -309 ct +2968 -320 2981 -326 2998 -326 ct 2998 -326 2998 -326 2998 -306 ct 2991 -306 2985 -303 2981 -298 ct +2978 -293 2976 -286 2976 -276 ct 2976 -276 2976 -276 2976 -265 ct 2976 -265 2976 -265 2998 -265 ct +2998 -265 2998 -265 2998 -214 ct 2998 -214 2998 -214 2947 -214 ct p ef +3155 0 m 3155 -275 l 3053 -275 l 3053 -306 l 3298 -306 l 3298 -275 l +3196 -275 l 3196 0 l 3155 0 l p ef +3474 -26 m 3450 -5 3425 5 3401 5 ct 3380 5 3363 -1 3350 -13 ct 3337 -24 3330 -39 3330 -57 ct +3330 -81 3340 -99 3361 -114 ct 3382 -128 3409 -135 3443 -135 ct 3443 -135 3443 -135 3468 -135 ct +3468 -135 3468 -135 3468 -154 ct 3468 -169 3464 -180 3457 -187 ct 3449 -194 3438 -198 3423 -198 ct +3399 -198 3374 -191 3349 -177 ct 3349 -177 3349 -177 3349 -213 ct 3378 -224 3405 -229 3431 -229 ct +3460 -229 3480 -223 3491 -212 ct 3503 -201 3509 -181 3509 -153 ct 3509 -153 3509 -153 3509 -59 ct +3509 -45 3510 -36 3513 -31 ct 3516 -26 3522 -24 3529 -24 ct 3532 -24 3536 -25 3542 -26 ct +3542 -26 3542 -26 3546 -2 ct 3532 3 3522 5 3515 5 ct 3505 5 3496 2 3490 -3 ct 3483 -8 3478 -16 3474 -26 ct +p +3468 -53 m 3468 -53 3468 -53 3468 -110 ct 3468 -110 3468 -110 3456 -110 ct +3428 -110 3407 -106 3393 -99 ct 3379 -91 3372 -80 3372 -64 ct 3372 -52 3375 -43 3382 -37 ct +3388 -31 3398 -28 3411 -28 ct 3429 -28 3448 -36 3468 -53 ct p ef +3620 0 m 3620 0 3620 0 3620 -224 ct 3620 -224 3620 -224 3661 -224 ct 3661 -224 3661 -224 3659 -182 ct +3659 -182 3659 -182 3661 -182 ct 3671 -198 3683 -209 3697 -217 ct 3711 -225 3726 -229 3744 -229 ct +3756 -229 3770 -227 3785 -224 ct 3785 -224 3785 -224 3785 -160 ct 3785 -160 3785 -160 3754 -160 ct +3754 -160 3754 -160 3754 -191 ct 3748 -192 3742 -193 3737 -193 ct 3723 -193 3710 -189 3698 -181 ct +3685 -173 3673 -161 3661 -145 ct 3661 -145 3661 -145 3661 0 ct 3661 0 3661 0 3620 0 ct +p ef +3853 75 m 3853 75 3853 75 3857 41 ct 3882 51 3905 56 3926 56 ct 3948 56 3964 51 3973 42 ct +3983 33 3989 17 3992 -6 ct 3992 -6 3992 -6 3996 -46 ct 3996 -46 3996 -46 3992 -46 ct +3984 -31 3973 -19 3961 -12 ct 3948 -4 3934 0 3918 0 ct 3893 0 3873 -10 3858 -29 ct +3843 -49 3835 -75 3835 -108 ct 3835 -144 3844 -173 3861 -195 ct 3879 -218 3901 -229 3929 -229 ct +3951 -229 3973 -219 3994 -198 ct 3994 -198 3994 -198 3997 -198 ct 3997 -198 3997 -198 3997 -224 ct +3997 -224 3997 -224 4033 -224 ct 4033 -224 4033 -224 4033 -45 ct 4033 -15 4031 6 4027 21 ct +4023 36 4016 49 4005 60 ct 3988 78 3962 87 3925 87 ct 3904 87 3880 83 3853 75 ct +p +3992 -80 m 3992 -80 3992 -80 3992 -167 ct 3974 -188 3954 -198 3935 -198 ct +3916 -198 3902 -191 3892 -176 ct 3883 -162 3878 -140 3878 -111 ct 3878 -86 3882 -67 3890 -55 ct +3899 -42 3911 -36 3928 -36 ct 3940 -36 3951 -40 3962 -47 ct 3973 -54 3983 -65 3992 -80 ct +p ef +4290 -9 m 4262 0 4236 5 4212 5 ct 4174 5 4145 -5 4124 -25 ct 4103 -45 4093 -73 4093 -110 ct +4093 -144 4103 -173 4123 -195 ct 4143 -218 4168 -229 4199 -229 ct 4230 -229 4252 -220 4267 -201 ct +4282 -182 4289 -153 4289 -114 ct 4289 -114 4289 -114 4289 -101 ct 4289 -101 4289 -101 4135 -101 ct +4136 -76 4144 -57 4158 -45 ct 4172 -32 4191 -26 4217 -26 ct 4240 -26 4264 -31 4290 -42 ct +4290 -42 4290 -42 4290 -9 ct p +4136 -132 m 4136 -132 4136 -132 4246 -132 ct 4246 -132 4246 -132 4246 -138 ct +4246 -158 4242 -173 4233 -183 ct 4224 -193 4212 -198 4195 -198 ct 4178 -198 4165 -192 4154 -181 ct +4144 -169 4138 -153 4136 -132 ct p ef +4546 0 m 4526 3 4506 5 4487 5 ct 4454 5 4431 -1 4419 -13 ct 4407 -25 4401 -47 4401 -80 ct +4401 -80 4401 -80 4401 -188 ct 4401 -188 4401 -188 4345 -188 ct 4345 -188 4345 -188 4345 -219 ct +4345 -219 4345 -219 4401 -219 ct 4401 -219 4401 -219 4401 -267 ct 4401 -267 4401 -267 4442 -267 ct +4442 -267 4442 -267 4442 -219 ct 4442 -219 4442 -219 4541 -219 ct 4541 -219 4541 -219 4541 -188 ct +4541 -188 4541 -188 4442 -188 ct 4442 -188 4442 -188 4442 -74 ct 4442 -61 4443 -53 4444 -48 ct +4446 -43 4449 -39 4455 -35 ct 4464 -29 4477 -26 4495 -26 ct 4512 -26 4529 -28 4546 -31 ct +4546 -31 4546 -31 4546 0 ct p ef +4623 -214 m 4623 -214 4623 -214 4623 -260 ct 4623 -282 4627 -298 4636 -309 ct +4644 -320 4657 -326 4674 -326 ct 4674 -326 4674 -326 4674 -306 ct 4667 -306 4661 -303 4657 -298 ct +4654 -293 4652 -286 4652 -276 ct 4652 -276 4652 -276 4652 -265 ct 4652 -265 4652 -265 4674 -265 ct +4674 -265 4674 -265 4674 -214 ct 4674 -214 4674 -214 4623 -214 ct p +4725 -214 m 4725 -214 4725 -214 4725 -260 ct 4725 -282 4729 -298 4738 -309 ct +4746 -320 4759 -326 4776 -326 ct 4776 -326 4776 -326 4776 -306 ct 4769 -306 4763 -303 4759 -298 ct +4756 -293 4754 -286 4754 -276 ct 4754 -276 4754 -276 4754 -265 ct 4754 -265 4754 -265 4776 -265 ct +4776 -265 4776 -265 4776 -214 ct 4776 -214 4776 -214 4725 -214 ct p ef +4857 61 m 4902 56 4938 36 4967 -1 ct 4996 -37 5010 -81 5010 -133 ct 5010 -184 4996 -228 4967 -264 ct +4938 -301 4902 -321 4857 -326 ct 4857 -326 4857 -326 4857 -298 ct 4893 -291 4921 -273 4940 -244 ct +4959 -216 4969 -178 4969 -133 ct 4969 -87 4959 -49 4940 -21 ct 4921 8 4893 26 4857 33 ct +4857 33 4857 33 4857 61 ct p ef +5431 -163 m 5431 -224 l 5492 -224 l 5492 -163 l 5431 -163 l p +5431 0 m 5431 -61 l 5492 -61 l 5492 0 l 5431 0 l p ef +pom +gr +gs +pum +10435 6013 t +pom +gr +gs +pum +11451 6013 t +0.003 0.003 1.000 c 153 -24 m 146 -14 137 -7 127 -2 ct 117 3 106 5 93 5 ct 71 5 53 -2 39 -15 ct +25 -28 18 -45 18 -65 ct 18 -91 28 -111 47 -124 ct 67 -137 96 -143 135 -143 ct 135 -143 135 -143 159 -143 ct +159 -143 159 -143 159 -154 ct 159 -165 155 -174 147 -179 ct 139 -185 127 -188 111 -188 ct +89 -188 64 -182 37 -169 ct 37 -169 37 -169 37 -214 ct 65 -224 93 -229 122 -229 ct +154 -229 178 -223 194 -211 ct 204 -203 211 -194 215 -185 ct 218 -175 220 -160 220 -140 ct +220 -140 220 -140 220 -64 ct 220 -49 225 -41 234 -41 ct 236 -41 238 -41 241 -42 ct +241 -42 241 -42 241 -2 ct 229 3 217 5 207 5 ct 196 5 186 3 178 -2 ct 170 -7 164 -14 159 -24 ct +159 -24 159 -24 153 -24 ct p +159 -65 m 159 -65 159 -65 159 -102 ct 159 -102 159 -102 137 -102 ct 118 -102 103 -99 94 -94 ct +84 -88 79 -80 79 -69 ct 79 -61 82 -54 88 -49 ct 94 -44 101 -41 110 -41 ct 125 -41 142 -49 159 -65 ct +p ef +339 0 m 339 0 339 0 339 -178 ct 339 -178 339 -178 296 -178 ct 296 -178 296 -178 296 -219 ct +296 -219 296 -219 339 -219 ct 339 -219 339 -219 339 -251 ct 339 -278 347 -298 362 -311 ct +377 -324 400 -331 431 -331 ct 457 -331 482 -328 507 -322 ct 507 -322 507 -322 507 -278 ct +481 -286 460 -290 444 -290 ct 428 -290 417 -287 410 -281 ct 403 -275 400 -265 400 -250 ct +400 -250 400 -250 400 -219 ct 400 -219 400 -219 487 -219 ct 487 -219 487 -219 487 -178 ct +487 -178 487 -178 400 -178 ct 400 -178 400 -178 400 0 ct 400 0 400 0 339 0 ct p ef +736 -6 m 712 1 690 5 672 5 ct 643 5 622 -1 608 -14 ct 594 -26 587 -45 587 -70 ct +587 -70 587 -70 587 -178 ct 587 -178 587 -178 539 -178 ct 539 -178 539 -178 539 -219 ct +539 -219 539 -219 587 -219 ct 587 -219 587 -219 587 -285 ct 587 -285 587 -285 648 -285 ct +648 -285 648 -285 648 -219 ct 648 -219 648 -219 731 -219 ct 731 -219 731 -219 731 -178 ct +731 -178 731 -178 648 -178 ct 648 -178 648 -178 648 -84 ct 648 -68 651 -57 657 -51 ct +663 -44 673 -41 687 -41 ct 704 -41 720 -44 736 -51 ct 736 -51 736 -51 736 -6 ct +p ef +998 -95 m 998 -95 998 -95 846 -95 ct 849 -77 857 -63 869 -54 ct 881 -45 897 -41 918 -41 ct +942 -41 969 -46 998 -56 ct 998 -56 998 -56 998 -9 ct 963 0 932 5 906 5 ct 868 5 837 -6 814 -27 ct +791 -48 780 -76 780 -111 ct 780 -147 791 -175 812 -197 ct 834 -218 862 -229 897 -229 ct +929 -229 953 -219 971 -199 ct 989 -180 998 -152 998 -118 ct 998 -118 998 -118 998 -95 ct +p +845 -136 m 845 -136 845 -136 939 -136 ct 939 -153 935 -166 928 -175 ct 920 -184 909 -188 894 -188 ct +880 -188 868 -184 860 -175 ct 852 -166 847 -153 845 -136 ct p ef +1062 0 m 1062 0 1062 0 1062 -224 ct 1062 -224 1062 -224 1123 -224 ct 1123 -224 1123 -224 1121 -181 ct +1121 -181 1121 -181 1123 -181 ct 1133 -197 1145 -209 1159 -217 ct 1172 -225 1188 -229 1206 -229 ct +1217 -229 1232 -227 1248 -224 ct 1248 -224 1248 -224 1248 -149 ct 1248 -149 1248 -149 1207 -149 ct +1207 -149 1207 -149 1207 -173 ct 1202 -174 1199 -174 1196 -174 ct 1181 -174 1168 -170 1155 -163 ct +1143 -156 1132 -145 1123 -130 ct 1123 -130 1123 -130 1123 0 ct 1123 0 1123 0 1062 0 ct +p ef +pom +gr +gs +pum +12721 6013 t +478 61 m 433 56 397 36 368 -1 ct 339 -37 325 -81 325 -133 ct 325 -184 339 -228 368 -264 ct +397 -301 433 -321 478 -326 ct 478 -326 478 -326 478 -298 ct 442 -291 414 -273 395 -244 ct +376 -216 366 -178 366 -133 ct 366 -87 376 -49 395 -21 ct 414 8 442 26 478 33 ct +478 33 478 33 478 61 ct p ef +539 61 m 584 56 620 36 649 -1 ct 678 -37 692 -81 692 -133 ct 692 -184 678 -228 649 -264 ct +620 -301 584 -321 539 -326 ct 539 -326 539 -326 539 -298 ct 575 -291 603 -273 622 -244 ct +641 -216 651 -178 651 -133 ct 651 -87 641 -49 622 -21 ct 603 8 575 26 539 33 ct +539 33 539 33 539 61 ct p ef +1228 -326 m 1228 -326 1228 -326 1228 -295 ct 1228 -295 1228 -295 1212 -295 ct +1191 -295 1177 -293 1169 -287 ct 1160 -282 1156 -274 1156 -261 ct 1156 -257 1157 -251 1158 -242 ct +1158 -242 1158 -242 1162 -214 ct 1163 -204 1164 -196 1164 -190 ct 1164 -175 1161 -163 1154 -153 ct +1147 -144 1137 -137 1123 -132 ct 1137 -128 1147 -121 1154 -111 ct 1161 -102 1164 -90 1164 -75 ct +1164 -68 1163 -61 1162 -51 ct 1162 -51 1162 -51 1158 -23 ct 1157 -14 1156 -8 1156 -4 ct +1156 9 1160 17 1169 22 ct 1177 27 1191 30 1212 30 ct 1212 30 1212 30 1228 30 ct +1228 30 1228 30 1228 61 ct 1228 61 1228 61 1205 61 ct 1176 61 1154 56 1140 46 ct +1125 36 1118 21 1118 2 ct 1118 -7 1119 -16 1121 -26 ct 1121 -26 1121 -26 1128 -63 ct +1129 -68 1129 -74 1129 -79 ct 1129 -92 1125 -101 1117 -108 ct 1110 -114 1098 -117 1083 -117 ct +1083 -117 1083 -117 1064 -117 ct 1064 -117 1064 -117 1064 -148 ct 1064 -148 1064 -148 1083 -148 ct +1098 -148 1110 -151 1117 -157 ct 1125 -164 1129 -173 1129 -186 ct 1129 -191 1129 -197 1128 -202 ct +1128 -202 1128 -202 1121 -239 ct 1119 -249 1118 -258 1118 -267 ct 1118 -286 1125 -301 1140 -311 ct +1154 -321 1176 -326 1205 -326 ct 1205 -326 1205 -326 1228 -326 ct p ef +pom +gr +gs +pum +10435 6504 t +pom +gr +gs +pum +11451 6504 t +122 0 m 122 -295 l 35 -295 l 35 -326 l 163 -326 l 163 0 l 122 0 l +p ef +426 -26 m 402 -5 377 5 353 5 ct 332 5 315 -1 302 -13 ct 289 -24 282 -39 282 -57 ct +282 -81 292 -99 313 -114 ct 334 -128 361 -135 395 -135 ct 395 -135 395 -135 420 -135 ct +420 -135 420 -135 420 -154 ct 420 -169 416 -180 409 -187 ct 401 -194 390 -198 375 -198 ct +351 -198 326 -191 301 -177 ct 301 -177 301 -177 301 -213 ct 330 -224 357 -229 383 -229 ct +412 -229 432 -223 443 -212 ct 455 -201 461 -181 461 -153 ct 461 -153 461 -153 461 -59 ct +461 -45 462 -36 465 -31 ct 468 -26 474 -24 481 -24 ct 484 -24 488 -25 494 -26 ct +494 -26 494 -26 498 -2 ct 484 3 474 5 467 5 ct 457 5 448 2 442 -3 ct 435 -8 430 -16 426 -26 ct +p +420 -53 m 420 -53 420 -53 420 -110 ct 420 -110 420 -110 408 -110 ct 380 -110 359 -106 345 -99 ct +331 -91 324 -80 324 -64 ct 324 -52 327 -43 334 -37 ct 340 -31 350 -28 363 -28 ct +381 -28 400 -36 420 -53 ct p ef +547 -9 m 547 -9 547 -9 547 -45 ct 578 -32 605 -26 628 -26 ct 644 -26 658 -29 669 -36 ct +680 -43 685 -51 685 -61 ct 685 -74 672 -84 647 -93 ct 647 -93 647 -93 604 -107 ct +570 -118 553 -138 553 -165 ct 553 -186 561 -201 576 -212 ct 591 -223 613 -229 641 -229 ct +662 -229 686 -226 714 -219 ct 714 -219 714 -219 714 -186 ct 687 -194 663 -198 641 -198 ct +625 -198 612 -196 604 -191 ct 596 -186 592 -179 592 -169 ct 592 -158 602 -149 622 -142 ct +622 -142 622 -142 674 -124 ct 709 -111 726 -91 726 -64 ct 726 -43 717 -26 700 -14 ct +682 -1 659 5 629 5 ct 604 5 576 0 547 -9 ct p ef +990 0 m 970 3 950 5 931 5 ct 898 5 875 -1 863 -13 ct 851 -25 845 -47 845 -80 ct +845 -80 845 -80 845 -188 ct 845 -188 845 -188 789 -188 ct 789 -188 789 -188 789 -219 ct +789 -219 789 -219 845 -219 ct 845 -219 845 -219 845 -267 ct 845 -267 845 -267 886 -267 ct +886 -267 886 -267 886 -219 ct 886 -219 886 -219 985 -219 ct 985 -219 985 -219 985 -188 ct +985 -188 985 -188 886 -188 ct 886 -188 886 -188 886 -74 ct 886 -61 887 -53 888 -48 ct +890 -43 893 -39 899 -35 ct 908 -29 921 -26 939 -26 ct 956 -26 973 -28 990 -31 ct +990 -31 990 -31 990 0 ct p ef +1016 31 m 1016 0 l 1271 0 l 1271 31 l 1016 31 l p ef +1542 -58 m 1542 -89 l 1761 -89 l 1761 -58 l 1542 -58 l p +1542 -130 m 1542 -161 l 1761 -161 l 1761 -130 l 1542 -130 l p ef +pom +gr +gs +pum +13483 6504 t +0.003 0.003 1.000 c 228 -6 m 204 1 182 5 164 5 ct 135 5 114 -1 100 -14 ct 86 -26 79 -45 79 -70 ct +79 -70 79 -70 79 -178 ct 79 -178 79 -178 31 -178 ct 31 -178 31 -178 31 -219 ct +31 -219 31 -219 79 -219 ct 79 -219 79 -219 79 -285 ct 79 -285 79 -285 140 -285 ct +140 -285 140 -285 140 -219 ct 140 -219 140 -219 223 -219 ct 223 -219 223 -219 223 -178 ct +223 -178 223 -178 140 -178 ct 140 -178 140 -178 140 -84 ct 140 -68 143 -57 149 -51 ct +155 -44 165 -41 179 -41 ct 196 -41 212 -44 228 -51 ct 228 -51 228 -51 228 -6 ct +p ef +279 78 m 279 78 279 78 279 30 ct 304 41 326 46 344 46 ct 359 46 369 42 374 34 ct +379 26 381 11 381 -13 ct 381 -13 381 -13 381 -183 ct 381 -183 381 -183 299 -183 ct +299 -183 299 -183 299 -224 ct 299 -224 299 -224 442 -224 ct 442 -224 442 -224 442 -16 ct +442 7 440 24 437 35 ct 434 46 428 56 419 64 ct 402 79 379 87 350 87 ct 331 87 307 84 279 78 ct +p +381 -265 m 381 -326 l 442 -326 l 442 -265 l 381 -265 l p ef +532 82 m 532 82 532 82 532 -224 ct 532 -224 532 -224 593 -224 ct 593 -224 593 -224 591 -182 ct +591 -182 591 -182 593 -182 ct 603 -197 614 -209 625 -217 ct 637 -225 650 -229 664 -229 ct +690 -229 710 -219 726 -198 ct 741 -178 749 -151 749 -117 ct 749 -80 740 -50 723 -28 ct +706 -6 683 5 654 5 ct 642 5 630 3 620 -2 ct 610 -6 601 -13 593 -22 ct 593 -22 593 -22 591 -22 ct +591 -22 591 -22 593 0 ct 593 0 593 0 593 82 ct 593 82 593 82 532 82 ct p +593 -64 m 600 -56 607 -50 614 -47 ct 621 -43 629 -41 638 -41 ct 653 -41 664 -47 672 -60 ct +679 -72 683 -91 683 -116 ct 683 -135 680 -149 673 -159 ct 666 -168 657 -173 643 -173 ct +635 -173 626 -170 617 -164 ct 609 -158 601 -149 593 -136 ct 593 -136 593 -136 593 -64 ct +p ef +pom +gr +gs +pum +14245 6504 t +43 -112 m 43 -143 l 211 -143 l 211 -112 l 43 -112 l p ef +272 0 m 491 -110 l 272 -219 l 272 -185 l 423 -110 l 272 -34 l 272 0 l +p ef +736 0 m 716 3 696 5 677 5 ct 644 5 621 -1 609 -13 ct 597 -25 591 -47 591 -80 ct +591 -80 591 -80 591 -188 ct 591 -188 591 -188 535 -188 ct 535 -188 535 -188 535 -219 ct +535 -219 535 -219 591 -219 ct 591 -219 591 -219 591 -267 ct 591 -267 591 -267 632 -267 ct +632 -267 632 -267 632 -219 ct 632 -219 632 -219 731 -219 ct 731 -219 731 -219 731 -188 ct +731 -188 731 -188 632 -188 ct 632 -188 632 -188 632 -74 ct 632 -61 633 -53 634 -48 ct +636 -43 639 -39 645 -35 ct 654 -29 667 -26 685 -26 ct 702 -26 719 -28 736 -31 ct +736 -31 736 -31 736 0 ct p ef +799 0 m 799 0 799 0 799 -326 ct 799 -326 799 -326 840 -326 ct 840 -326 840 -326 840 -224 ct +840 -224 840 -224 838 -182 ct 838 -182 838 -182 840 -182 ct 850 -198 861 -209 874 -217 ct +886 -225 901 -229 917 -229 ct 938 -229 954 -223 965 -210 ct 976 -197 981 -178 981 -153 ct +981 -153 981 -153 981 0 ct 981 0 981 0 940 0 ct 940 0 940 0 940 -142 ct 940 -159 937 -172 932 -179 ct +926 -186 917 -190 904 -190 ct 894 -190 884 -186 873 -179 ct 862 -172 851 -161 840 -146 ct +840 -146 840 -146 840 0 ct 840 0 840 0 799 0 ct p ef +1188 -26 m 1164 -5 1139 5 1115 5 ct 1094 5 1077 -1 1064 -13 ct 1051 -24 1044 -39 1044 -57 ct +1044 -81 1054 -99 1075 -114 ct 1096 -128 1123 -135 1157 -135 ct 1157 -135 1157 -135 1182 -135 ct +1182 -135 1182 -135 1182 -154 ct 1182 -169 1178 -180 1171 -187 ct 1163 -194 1152 -198 1137 -198 ct +1113 -198 1088 -191 1063 -177 ct 1063 -177 1063 -177 1063 -213 ct 1092 -224 1119 -229 1145 -229 ct +1174 -229 1194 -223 1205 -212 ct 1217 -201 1223 -181 1223 -153 ct 1223 -153 1223 -153 1223 -59 ct +1223 -45 1224 -36 1227 -31 ct 1230 -26 1236 -24 1243 -24 ct 1246 -24 1250 -25 1256 -26 ct +1256 -26 1256 -26 1260 -2 ct 1246 3 1236 5 1229 5 ct 1219 5 1210 2 1204 -3 ct 1197 -8 1192 -16 1188 -26 ct +p +1182 -53 m 1182 -53 1182 -53 1182 -110 ct 1182 -110 1182 -110 1170 -110 ct +1142 -110 1121 -106 1107 -99 ct 1093 -91 1086 -80 1086 -64 ct 1086 -52 1089 -43 1096 -37 ct +1102 -31 1112 -28 1125 -28 ct 1143 -28 1162 -36 1182 -53 ct p ef +1498 0 m 1478 3 1458 5 1439 5 ct 1406 5 1383 -1 1371 -13 ct 1359 -25 1353 -47 1353 -80 ct +1353 -80 1353 -80 1353 -188 ct 1353 -188 1353 -188 1297 -188 ct 1297 -188 1297 -188 1297 -219 ct +1297 -219 1297 -219 1353 -219 ct 1353 -219 1353 -219 1353 -267 ct 1353 -267 1353 -267 1394 -267 ct +1394 -267 1394 -267 1394 -219 ct 1394 -219 1394 -219 1493 -219 ct 1493 -219 1493 -219 1493 -188 ct +1493 -188 1493 -188 1394 -188 ct 1394 -188 1394 -188 1394 -74 ct 1394 -61 1395 -53 1396 -48 ct +1398 -43 1401 -39 1407 -35 ct 1416 -29 1429 -26 1447 -26 ct 1464 -26 1481 -28 1498 -31 ct +1498 -31 1498 -31 1498 0 ct p ef +1748 61 m 1703 56 1667 36 1638 -1 ct 1609 -37 1595 -81 1595 -133 ct 1595 -184 1609 -228 1638 -264 ct +1667 -301 1703 -321 1748 -326 ct 1748 -326 1748 -326 1748 -298 ct 1712 -291 1684 -273 1665 -244 ct +1646 -216 1636 -178 1636 -133 ct 1636 -87 1646 -49 1665 -21 ct 1684 8 1712 26 1748 33 ct +1748 33 1748 33 1748 61 ct p ef +1809 61 m 1854 56 1890 36 1919 -1 ct 1948 -37 1962 -81 1962 -133 ct 1962 -184 1948 -228 1919 -264 ct +1890 -301 1854 -321 1809 -326 ct 1809 -326 1809 -326 1809 -298 ct 1845 -291 1873 -273 1892 -244 ct +1911 -216 1921 -178 1921 -133 ct 1921 -87 1911 -49 1892 -21 ct 1873 8 1845 26 1809 33 ct +1809 33 1809 33 1809 61 ct p ef +2129 66 m 2129 66 2129 66 2129 46 ct 2136 45 2142 41 2146 33 ct 2151 25 2153 14 2154 0 ct +2154 0 2154 0 2129 0 ct 2129 0 2129 0 2129 -61 ct 2129 -61 2129 -61 2190 -61 ct +2190 -61 2190 -61 2190 -24 ct 2190 5 2185 27 2175 42 ct 2165 57 2149 65 2129 66 ct +p +2129 -163 m 2129 -224 l 2190 -224 l 2190 -163 l 2129 -163 l p ef +pom +gr +gs +pum +10435 6995 t +pom +gr +gs +pum +11451 6995 t +122 0 m 122 -295 l 35 -295 l 35 -326 l 163 -326 l 163 0 l 122 0 l +p ef +426 -26 m 402 -5 377 5 353 5 ct 332 5 315 -1 302 -13 ct 289 -24 282 -39 282 -57 ct +282 -81 292 -99 313 -114 ct 334 -128 361 -135 395 -135 ct 395 -135 395 -135 420 -135 ct +420 -135 420 -135 420 -154 ct 420 -169 416 -180 409 -187 ct 401 -194 390 -198 375 -198 ct +351 -198 326 -191 301 -177 ct 301 -177 301 -177 301 -213 ct 330 -224 357 -229 383 -229 ct +412 -229 432 -223 443 -212 ct 455 -201 461 -181 461 -153 ct 461 -153 461 -153 461 -59 ct +461 -45 462 -36 465 -31 ct 468 -26 474 -24 481 -24 ct 484 -24 488 -25 494 -26 ct +494 -26 494 -26 498 -2 ct 484 3 474 5 467 5 ct 457 5 448 2 442 -3 ct 435 -8 430 -16 426 -26 ct +p +420 -53 m 420 -53 420 -53 420 -110 ct 420 -110 420 -110 408 -110 ct 380 -110 359 -106 345 -99 ct +331 -91 324 -80 324 -64 ct 324 -52 327 -43 334 -37 ct 340 -31 350 -28 363 -28 ct +381 -28 400 -36 420 -53 ct p ef +547 -9 m 547 -9 547 -9 547 -45 ct 578 -32 605 -26 628 -26 ct 644 -26 658 -29 669 -36 ct +680 -43 685 -51 685 -61 ct 685 -74 672 -84 647 -93 ct 647 -93 647 -93 604 -107 ct +570 -118 553 -138 553 -165 ct 553 -186 561 -201 576 -212 ct 591 -223 613 -229 641 -229 ct +662 -229 686 -226 714 -219 ct 714 -219 714 -219 714 -186 ct 687 -194 663 -198 641 -198 ct +625 -198 612 -196 604 -191 ct 596 -186 592 -179 592 -169 ct 592 -158 602 -149 622 -142 ct +622 -142 622 -142 674 -124 ct 709 -111 726 -91 726 -64 ct 726 -43 717 -26 700 -14 ct +682 -1 659 5 629 5 ct 604 5 576 0 547 -9 ct p ef +990 0 m 970 3 950 5 931 5 ct 898 5 875 -1 863 -13 ct 851 -25 845 -47 845 -80 ct +845 -80 845 -80 845 -188 ct 845 -188 845 -188 789 -188 ct 789 -188 789 -188 789 -219 ct +789 -219 789 -219 845 -219 ct 845 -219 845 -219 845 -267 ct 845 -267 845 -267 886 -267 ct +886 -267 886 -267 886 -219 ct 886 -219 886 -219 985 -219 ct 985 -219 985 -219 985 -188 ct +985 -188 985 -188 886 -188 ct 886 -188 886 -188 886 -74 ct 886 -61 887 -53 888 -48 ct +890 -43 893 -39 899 -35 ct 908 -29 921 -26 939 -26 ct 956 -26 973 -28 990 -31 ct +990 -31 990 -31 990 0 ct p ef +1016 31 m 1016 0 l 1271 0 l 1271 31 l 1016 31 l p ef +1313 -112 m 1313 -143 l 1481 -143 l 1481 -112 l 1313 -112 l p ef +1542 0 m 1761 -110 l 1542 -219 l 1542 -185 l 1693 -110 l 1542 -34 l +1542 0 l p ef +1960 0 m 1960 0 1960 0 1962 -42 ct 1962 -42 1962 -42 1960 -42 ct 1950 -26 1939 -15 1927 -7 ct +1914 1 1901 5 1886 5 ct 1861 5 1841 -5 1826 -24 ct 1811 -44 1804 -71 1804 -105 ct +1804 -142 1813 -172 1830 -195 ct 1848 -218 1870 -229 1898 -229 ct 1910 -229 1922 -226 1932 -221 ct +1942 -216 1952 -209 1960 -198 ct 1960 -198 1960 -198 1962 -198 ct 1962 -198 1962 -198 1960 -229 ct +1960 -229 1960 -229 1960 -326 ct 1960 -326 1960 -326 2001 -326 ct 2001 -326 2001 -326 2001 0 ct +2001 0 2001 0 1960 0 ct p +1960 -168 m 1950 -178 1941 -185 1932 -190 ct 1922 -195 1913 -198 1904 -198 ct +1886 -198 1872 -190 1862 -175 ct 1852 -159 1847 -137 1847 -109 ct 1847 -83 1851 -63 1859 -50 ct +1867 -38 1878 -31 1894 -31 ct 1906 -31 1917 -35 1928 -42 ct 1939 -49 1950 -59 1960 -73 ct +1960 -73 1960 -73 1960 -168 ct p ef +2250 -224 m 2250 -224 2250 -224 2250 0 ct 2250 0 2250 0 2209 0 ct 2209 0 2209 0 2211 -42 ct +2211 -42 2211 -42 2209 -42 ct 2200 -26 2188 -15 2176 -7 ct 2163 1 2148 5 2132 5 ct +2111 5 2095 -1 2084 -14 ct 2073 -27 2068 -46 2068 -71 ct 2068 -71 2068 -71 2068 -224 ct +2068 -224 2068 -224 2109 -224 ct 2109 -224 2109 -224 2109 -82 ct 2109 -65 2112 -52 2117 -45 ct +2123 -38 2132 -34 2145 -34 ct 2155 -34 2165 -38 2176 -45 ct 2187 -52 2198 -63 2209 -78 ct +2209 -78 2209 -78 2209 -224 ct 2209 -224 2209 -224 2250 -224 ct p ef +2305 0 m 2305 0 2305 0 2305 -224 ct 2305 -224 2305 -224 2341 -224 ct 2341 -224 2341 -224 2338 -182 ct +2338 -182 2338 -182 2341 -182 ct 2349 -198 2358 -209 2367 -217 ct 2375 -225 2383 -229 2391 -229 ct +2402 -229 2410 -225 2417 -216 ct 2424 -208 2428 -196 2429 -182 ct 2429 -182 2429 -182 2432 -182 ct +2439 -198 2447 -209 2455 -217 ct 2464 -225 2473 -229 2483 -229 ct 2496 -229 2506 -224 2513 -213 ct +2520 -202 2523 -186 2523 -164 ct 2523 -164 2523 -164 2523 0 ct 2523 0 2523 0 2487 0 ct +2487 0 2487 0 2487 -162 ct 2487 -172 2486 -180 2484 -185 ct 2482 -190 2478 -193 2474 -193 ct +2468 -193 2461 -189 2454 -181 ct 2447 -173 2439 -160 2432 -144 ct 2432 -144 2432 -144 2432 0 ct +2432 0 2432 0 2396 0 ct 2396 0 2396 0 2396 -155 ct 2396 -167 2395 -177 2393 -183 ct +2390 -190 2387 -193 2383 -193 ct 2377 -193 2370 -188 2362 -179 ct 2354 -170 2347 -158 2341 -144 ct +2341 -144 2341 -144 2341 0 ct 2341 0 2341 0 2305 0 ct p ef +2577 82 m 2577 82 2577 82 2577 -224 ct 2577 -224 2577 -224 2618 -224 ct 2618 -224 2618 -224 2616 -182 ct +2616 -182 2616 -182 2618 -182 ct 2628 -198 2639 -209 2651 -217 ct 2663 -225 2677 -229 2691 -229 ct +2716 -229 2736 -219 2751 -200 ct 2766 -180 2773 -153 2773 -120 ct 2773 -82 2764 -52 2747 -29 ct +2730 -6 2707 5 2679 5 ct 2667 5 2656 2 2646 -3 ct 2636 -8 2626 -15 2618 -26 ct +2618 -26 2618 -26 2616 -26 ct 2616 -26 2616 -26 2618 5 ct 2618 5 2618 5 2618 82 ct +2618 82 2618 82 2577 82 ct p +2618 -56 m 2627 -46 2637 -39 2646 -34 ct 2655 -29 2664 -26 2674 -26 ct 2692 -26 2705 -34 2715 -49 ct +2725 -65 2730 -87 2730 -115 ct 2730 -141 2726 -160 2718 -173 ct 2710 -186 2699 -193 2683 -193 ct +2672 -193 2660 -189 2649 -182 ct 2639 -175 2628 -165 2618 -151 ct 2618 -151 2618 -151 2618 -56 ct +p ef +3018 61 m 2973 56 2937 36 2908 -1 ct 2879 -37 2865 -81 2865 -133 ct 2865 -184 2879 -228 2908 -264 ct +2937 -301 2973 -321 3018 -326 ct 3018 -326 3018 -326 3018 -298 ct 2982 -291 2954 -273 2935 -244 ct +2916 -216 2906 -178 2906 -133 ct 2906 -87 2916 -49 2935 -21 ct 2954 8 2982 26 3018 33 ct +3018 33 3018 33 3018 61 ct p ef +3079 61 m 3124 56 3160 36 3189 -1 ct 3218 -37 3232 -81 3232 -133 ct 3232 -184 3218 -228 3189 -264 ct +3160 -301 3124 -321 3079 -326 ct 3079 -326 3079 -326 3079 -298 ct 3115 -291 3143 -273 3162 -244 ct +3181 -216 3191 -178 3191 -133 ct 3191 -87 3181 -49 3162 -21 ct 3143 8 3115 26 3079 33 ct +3079 33 3079 33 3079 61 ct p ef +3399 66 m 3399 66 3399 66 3399 46 ct 3406 45 3412 41 3416 33 ct 3421 25 3423 14 3424 0 ct +3424 0 3424 0 3399 0 ct 3399 0 3399 0 3399 -61 ct 3399 -61 3399 -61 3460 -61 ct +3460 -61 3460 -61 3460 -24 ct 3460 5 3455 27 3445 42 ct 3435 57 3419 65 3399 66 ct +p +3399 -163 m 3399 -224 l 3460 -224 l 3460 -163 l 3399 -163 l p ef +pom +gr +gs +pum +10435 7486 t +pom +gr +gs +pum +10943 7486 t +43 -326 m 43 -326 43 -326 43 -295 ct 43 -295 43 -295 59 -295 ct 80 -295 94 -293 102 -287 ct +111 -282 115 -274 115 -261 ct 115 -257 114 -251 113 -242 ct 113 -242 113 -242 109 -214 ct +108 -204 107 -196 107 -190 ct 107 -175 110 -163 117 -153 ct 124 -144 134 -137 148 -132 ct +134 -128 124 -121 117 -111 ct 110 -102 107 -90 107 -75 ct 107 -68 108 -61 109 -51 ct +109 -51 109 -51 113 -23 ct 114 -14 115 -8 115 -4 ct 115 9 111 17 102 22 ct 94 27 80 30 59 30 ct +59 30 59 30 43 30 ct 43 30 43 30 43 61 ct 43 61 43 61 66 61 ct 95 61 117 56 131 46 ct +146 36 153 21 153 2 ct 153 -7 152 -16 150 -26 ct 150 -26 150 -26 143 -63 ct 142 -68 142 -74 142 -79 ct +142 -92 146 -101 154 -108 ct 161 -114 173 -117 188 -117 ct 188 -117 188 -117 207 -117 ct +207 -117 207 -117 207 -148 ct 207 -148 207 -148 188 -148 ct 173 -148 161 -151 154 -157 ct +146 -164 142 -173 142 -186 ct 142 -191 142 -197 143 -202 ct 143 -202 143 -202 150 -239 ct +152 -249 153 -258 153 -267 ct 153 -286 146 -301 131 -311 ct 117 -321 95 -326 66 -326 ct +66 -326 66 -326 43 -326 ct p ef +pom +gr +gs +pum +10435 8180 t +43 -326 m 43 -326 43 -326 43 -295 ct 43 -295 43 -295 59 -295 ct 80 -295 94 -293 102 -287 ct +111 -282 115 -274 115 -261 ct 115 -257 114 -251 113 -242 ct 113 -242 113 -242 109 -214 ct +108 -204 107 -196 107 -190 ct 107 -175 110 -163 117 -153 ct 124 -144 134 -137 148 -132 ct +134 -128 124 -121 117 -111 ct 110 -102 107 -90 107 -75 ct 107 -68 108 -61 109 -51 ct +109 -51 109 -51 113 -23 ct 114 -14 115 -8 115 -4 ct 115 9 111 17 102 22 ct 94 27 80 30 59 30 ct +59 30 59 30 43 30 ct 43 30 43 30 43 61 ct 43 61 43 61 66 61 ct 95 61 117 56 131 46 ct +146 36 153 21 153 2 ct 153 -7 152 -16 150 -26 ct 150 -26 150 -26 143 -63 ct 142 -68 142 -74 142 -79 ct +142 -92 146 -101 154 -108 ct 161 -114 173 -117 188 -117 ct 188 -117 188 -117 207 -117 ct +207 -117 207 -117 207 -148 ct 207 -148 207 -148 188 -148 ct 173 -148 161 -151 154 -157 ct +146 -164 142 -173 142 -186 ct 142 -191 142 -197 143 -202 ct 143 -202 143 -202 150 -239 ct +152 -249 153 -258 153 -267 ct 153 -286 146 -301 131 -311 ct 117 -321 95 -326 66 -326 ct +66 -326 66 -326 43 -326 ct p ef +351 66 m 351 66 351 66 351 46 ct 358 45 364 41 368 33 ct 373 25 375 14 376 0 ct +376 0 376 0 351 0 ct 351 0 351 0 351 -61 ct 351 -61 351 -61 412 -61 ct 412 -61 412 -61 412 -24 ct +412 5 407 27 397 42 ct 387 57 371 65 351 66 ct p +351 -163 m 351 -224 l 412 -224 l 412 -163 l 351 -163 l p ef +pom +gr +gs +pum +10943 8180 t +pom +gr +gr +0.503 0.503 0.503 c 11787 9323 m 10406 9323 l 10406 8648 l 13169 8648 l +13169 9323 l 11787 9323 l p ef +11787 9323 m 10406 9323 l 10406 8648 l 13169 8648 l 13169 9323 l 11787 9323 l +pc +0.753 0.753 0.753 c 11687 9223 m 10306 9223 l 10306 8548 l 13069 8548 l +13069 9223 l 11687 9223 l p ef +0.003 0.003 0.003 c 11687 9223 m 10306 9223 l 10306 8548 l 13069 8548 l +13069 9223 l 11687 9223 l pc +gs +gs +pum +10541 9039 t +1.000 1.000 1.000 c 29 -291 m 29 -291 29 -291 154 -291 ct 189 -291 216 -283 235 -267 ct +254 -251 264 -229 264 -200 ct 264 -171 254 -148 235 -131 ct 215 -115 188 -107 153 -107 ct +153 -107 153 -107 88 -107 ct 88 -107 88 -107 88 0 ct 88 0 88 0 29 0 ct 29 0 29 0 29 -291 ct +p +88 -156 m 88 -156 88 -156 150 -156 ct 168 -156 181 -160 191 -168 ct 200 -176 205 -186 205 -200 ct +205 -212 200 -223 190 -230 ct 181 -238 167 -242 150 -242 ct 150 -242 150 -242 88 -242 ct +88 -242 88 -242 88 -156 ct p ef +451 -211 m 451 -211 451 -211 441 -159 ct 435 -163 429 -165 422 -165 ct 415 -165 408 -163 402 -158 ct +395 -153 388 -145 381 -134 ct 374 -123 371 -116 371 -114 ct 371 -114 371 -114 371 0 ct +371 0 371 0 314 0 ct 314 0 314 0 314 -215 ct 314 -215 314 -215 371 -215 ct 371 -215 371 -215 371 -172 ct +379 -190 387 -202 395 -209 ct 403 -216 413 -220 424 -220 ct 435 -220 444 -217 451 -211 ct +p ef +578 -220 m 612 -220 639 -210 660 -190 ct 681 -170 691 -143 691 -108 ct 691 -72 681 -45 660 -25 ct +639 -5 612 5 578 5 ct 544 5 517 -5 496 -25 ct 475 -45 465 -72 465 -108 ct 465 -143 475 -170 496 -190 ct +517 -210 544 -220 578 -220 ct p +578 -44 m 594 -44 607 -50 617 -61 ct 627 -73 632 -88 632 -108 ct 632 -127 627 -142 617 -154 ct +608 -165 594 -171 578 -171 ct 561 -171 547 -165 538 -154 ct 529 -143 524 -128 524 -108 ct +524 -88 529 -72 538 -61 ct 547 -50 561 -44 578 -44 ct p ef +794 -192 m 801 -201 810 -207 822 -212 ct 834 -217 846 -220 858 -220 ct 885 -220 906 -210 923 -190 ct +940 -171 949 -144 949 -112 ct 949 -76 940 -47 923 -26 ct 906 -5 885 5 858 5 ct +831 5 810 -4 794 -21 ct 794 -21 794 -21 794 0 ct 794 0 794 0 737 0 ct 737 0 737 0 737 -307 ct +737 -307 737 -307 794 -307 ct 794 -307 794 -307 794 -192 ct p +794 -69 m 807 -52 823 -44 843 -44 ct 857 -44 868 -50 877 -61 ct 886 -73 890 -89 890 -108 ct +890 -129 886 -144 877 -155 ct 868 -166 856 -171 843 -171 ct 824 -171 808 -162 794 -145 ct +794 -145 794 -145 794 -69 ct p ef +1052 0 m 995 0 l 995 -307 l 1052 -307 l 1052 0 l p ef +1305 -20 m 1280 -3 1251 5 1219 5 ct 1183 5 1154 -5 1132 -26 ct 1111 -46 1100 -74 1100 -108 ct +1100 -142 1110 -169 1129 -189 ct 1148 -210 1174 -220 1206 -220 ct 1235 -220 1259 -210 1277 -191 ct +1296 -171 1305 -144 1305 -109 ct 1305 -109 1305 -109 1305 -95 ct 1305 -95 1305 -95 1159 -95 ct +1161 -80 1168 -68 1179 -59 ct 1190 -49 1204 -44 1220 -44 ct 1245 -44 1270 -51 1295 -65 ct +1295 -65 1295 -65 1305 -20 ct p +1250 -133 m 1248 -147 1243 -158 1235 -167 ct 1227 -175 1218 -179 1206 -179 ct +1194 -179 1183 -175 1175 -167 ct 1166 -158 1161 -147 1159 -133 ct 1159 -133 1159 -133 1250 -133 ct +p ef +1668 0 m 1668 0 1668 0 1611 0 ct 1611 0 1611 0 1611 -125 ct 1611 -143 1609 -155 1604 -162 ct +1600 -168 1593 -171 1584 -171 ct 1569 -171 1554 -160 1538 -137 ct 1538 -137 1538 -137 1538 0 ct +1538 0 1538 0 1481 0 ct 1481 0 1481 0 1481 -125 ct 1481 -144 1479 -157 1474 -162 ct +1470 -168 1464 -171 1455 -171 ct 1440 -171 1424 -160 1408 -137 ct 1408 -137 1408 -137 1408 0 ct +1408 0 1408 0 1351 0 ct 1351 0 1351 0 1351 -215 ct 1351 -215 1351 -215 1408 -215 ct +1408 -215 1408 -215 1408 -182 ct 1425 -207 1446 -220 1473 -220 ct 1501 -220 1521 -207 1533 -182 ct +1551 -207 1574 -220 1603 -220 ct 1624 -220 1640 -214 1651 -201 ct 1662 -188 1668 -169 1668 -144 ct +1668 -144 1668 -144 1668 0 ct p ef +1756 -66 m 1766 -66 1775 -63 1782 -56 ct 1789 -49 1792 -41 1792 -31 ct 1792 -21 1789 -12 1782 -5 ct +1775 2 1766 5 1756 5 ct 1746 5 1738 2 1731 -5 ct 1724 -12 1721 -20 1721 -31 ct +1721 -41 1724 -49 1731 -56 ct 1738 -63 1746 -66 1756 -66 ct p ef +2030 0 m 2030 0 2030 0 1971 0 ct 1967 -9 1965 -17 1965 -25 ct 1946 -5 1923 5 1896 5 ct +1876 5 1860 -1 1849 -13 ct 1838 -24 1832 -40 1832 -59 ct 1832 -73 1836 -85 1843 -95 ct +1851 -106 1862 -114 1877 -120 ct 1892 -127 1909 -131 1930 -132 ct 1930 -132 1930 -132 1965 -135 ct +1965 -135 1965 -135 1965 -139 ct 1965 -163 1951 -175 1924 -175 ct 1916 -175 1905 -173 1891 -170 ct +1877 -166 1865 -162 1855 -157 ct 1855 -157 1855 -157 1841 -198 ct 1854 -204 1870 -210 1887 -214 ct +1905 -218 1920 -220 1934 -220 ct 1963 -220 1985 -213 2000 -199 ct 2015 -185 2022 -165 2022 -138 ct +2022 -138 2022 -138 2022 -51 ct 2022 -31 2025 -14 2030 0 ct p +1965 -66 m 1965 -66 1965 -66 1965 -101 ct 1941 -99 1926 -97 1920 -96 ct 1915 -95 1909 -93 1902 -89 ct +1896 -86 1892 -82 1889 -77 ct 1886 -72 1884 -67 1884 -61 ct 1884 -54 1886 -49 1891 -45 ct +1895 -40 1901 -38 1908 -38 ct 1929 -38 1948 -47 1965 -66 ct p ef +2282 0 m 2282 0 2282 0 2225 0 ct 2225 0 2225 0 2225 -125 ct 2225 -156 2214 -171 2192 -171 ct +2173 -171 2155 -160 2140 -139 ct 2140 -139 2140 -139 2140 0 ct 2140 0 2140 0 2083 0 ct +2083 0 2083 0 2083 -307 ct 2083 -307 2083 -307 2140 -307 ct 2140 -307 2140 -307 2140 -188 ct +2158 -209 2181 -220 2209 -220 ct 2231 -220 2249 -213 2262 -200 ct 2275 -187 2282 -168 2282 -144 ct +2282 -144 2282 -144 2282 0 ct p ef +pom +gr +gr +0.300 0.300 0.300 c 8573 1158 m 9729 1158 l 9729 1015 l 9936 1240 l +9729 1466 l 9729 1322 l 8573 1322 l 8573 1158 l p ef +gs +gs +pum +8769 1080 t +0.003 0.003 0.003 c 44 0 m 20 0 l 20 -143 l 44 -143 l 44 0 l p +32 -205 m 36 -205 40 -204 43 -201 ct 46 -198 47 -194 47 -190 ct 47 -186 46 -183 43 -180 ct +40 -177 36 -176 32 -176 ct 28 -176 25 -177 22 -180 ct 19 -183 18 -186 18 -190 ct +18 -194 19 -198 22 -201 ct 25 -204 28 -205 32 -205 ct p ef +202 0 m 202 0 202 0 178 0 ct 178 0 178 0 178 -91 ct 178 -102 175 -110 170 -116 ct +165 -122 157 -125 148 -125 ct 134 -125 120 -117 107 -101 ct 107 -101 107 -101 107 0 ct +107 0 107 0 83 0 ct 83 0 83 0 83 -143 ct 83 -143 83 -143 107 -143 ct 107 -143 107 -143 107 -122 ct +122 -138 138 -146 155 -146 ct 169 -146 181 -142 189 -133 ct 198 -125 202 -113 202 -97 ct +202 -97 202 -97 202 0 ct p ef +231 -72 m 231 -95 238 -113 251 -126 ct 265 -139 282 -146 302 -146 ct 319 -146 336 -141 351 -132 ct +351 -132 351 -132 344 -113 ct 331 -121 317 -125 303 -125 ct 289 -125 278 -120 269 -110 ct +260 -101 256 -88 256 -72 ct 256 -55 260 -42 269 -33 ct 278 -23 289 -18 303 -18 ct +316 -18 331 -23 346 -32 ct 346 -32 346 -32 353 -13 ct 337 -2 320 3 303 3 ct 281 3 264 -4 251 -18 ct +238 -31 231 -49 231 -72 ct p ef +408 0 m 384 0 l 384 -205 l 408 -205 l 408 0 l p ef +566 0 m 566 0 566 0 542 0 ct 542 0 542 0 542 -21 ct 527 -5 511 3 494 3 ct 480 3 468 -1 460 -10 ct +451 -18 447 -30 447 -46 ct 447 -46 447 -46 447 -143 ct 447 -143 447 -143 471 -143 ct +471 -143 471 -143 471 -52 ct 471 -42 474 -33 479 -27 ct 484 -21 492 -18 501 -18 ct +515 -18 529 -26 542 -42 ct 542 -42 542 -42 542 -143 ct 542 -143 542 -143 566 -143 ct +566 -143 566 -143 566 0 ct p ef +722 0 m 722 0 722 0 698 0 ct 698 0 698 0 698 -18 ct 688 -4 673 3 656 3 ct 637 3 622 -4 611 -18 ct +601 -32 595 -50 595 -74 ct 595 -96 601 -113 612 -126 ct 623 -139 637 -146 654 -146 ct +673 -146 688 -139 698 -125 ct 698 -125 698 -125 698 -205 ct 698 -205 698 -205 722 -205 ct +722 -205 722 -205 722 0 ct p +698 -42 m 698 -42 698 -42 698 -102 ct 695 -109 690 -114 683 -118 ct 676 -123 669 -125 661 -125 ct +648 -125 638 -120 631 -111 ct 624 -102 620 -89 620 -72 ct 620 -55 624 -42 631 -32 ct +638 -23 649 -18 661 -18 ct 667 -18 672 -19 677 -22 ct 683 -24 687 -28 692 -32 ct +696 -37 698 -40 698 -42 ct p ef +887 -15 m 867 -3 847 3 827 3 ct 803 3 785 -4 772 -17 ct 759 -30 752 -49 752 -72 ct +752 -94 758 -112 770 -126 ct 783 -139 799 -146 820 -146 ct 839 -146 854 -140 866 -127 ct +878 -114 884 -97 884 -75 ct 884 -75 884 -75 884 -69 ct 884 -69 884 -69 777 -69 ct +778 -52 782 -40 791 -31 ct 799 -22 811 -18 827 -18 ct 845 -18 862 -23 880 -34 ct +880 -34 880 -34 887 -15 ct p +859 -88 m 858 -99 854 -108 846 -115 ct 839 -122 830 -125 820 -125 ct 809 -125 800 -122 792 -115 ct +785 -109 780 -100 778 -88 ct 778 -88 778 -88 859 -88 ct p ef +pom +gr +gr +gs +gs +pum +2974 10055 t +0.003 0.003 0.003 c 237 -232 m 237 -232 237 -232 217 -199 ct 194 -214 169 -222 143 -222 ct +124 -222 108 -219 97 -213 ct 86 -206 80 -198 80 -188 ct 80 -182 83 -177 88 -172 ct +94 -167 108 -160 131 -152 ct 148 -146 163 -140 174 -135 ct 185 -129 194 -122 202 -112 ct +210 -102 214 -90 214 -75 ct 214 -50 204 -30 183 -16 ct 162 -1 135 6 101 6 ct 62 6 29 -3 1 -20 ct +1 -20 1 -20 21 -53 ct 46 -38 73 -30 101 -30 ct 121 -30 138 -34 152 -42 ct 165 -49 172 -59 172 -71 ct +172 -79 169 -86 162 -93 ct 155 -100 139 -108 112 -118 ct 80 -130 60 -141 51 -151 ct +42 -161 38 -172 38 -184 ct 38 -207 48 -224 67 -237 ct 87 -250 111 -257 141 -257 ct +177 -257 209 -249 237 -232 ct p ef +406 -257 m 438 -257 464 -248 482 -231 ct 501 -214 510 -190 510 -161 ct 510 -116 497 -78 470 -44 ct +444 -11 411 6 370 6 ct 338 6 312 -3 293 -21 ct 274 -38 265 -62 265 -91 ct 265 -136 278 -175 305 -208 ct +331 -241 365 -257 406 -257 ct p +370 -31 m 398 -31 420 -44 438 -71 ct 456 -98 465 -128 465 -160 ct 465 -178 460 -193 449 -204 ct +438 -215 424 -220 405 -220 ct 377 -220 354 -207 336 -182 ct 319 -157 310 -128 310 -94 ct +310 -76 315 -60 326 -49 ct 337 -37 351 -31 370 -31 ct p ef +792 -251 m 792 -251 792 -251 739 0 ct 739 0 739 0 696 0 ct 696 0 696 0 704 -39 ct +692 -26 678 -15 661 -7 ct 645 2 628 6 613 6 ct 591 6 574 0 562 -11 ct 551 -23 545 -39 545 -60 ct +545 -69 547 -85 552 -107 ct 552 -107 552 -107 583 -251 ct 583 -251 583 -251 626 -251 ct +626 -251 626 -251 595 -107 ct 593 -97 591 -88 589 -80 ct 588 -73 587 -67 587 -65 ct +587 -42 599 -31 623 -31 ct 635 -31 650 -35 667 -44 ct 684 -53 699 -65 713 -79 ct +713 -79 713 -79 749 -251 ct 749 -251 749 -251 792 -251 ct p ef +996 -246 m 996 -246 996 -246 977 -209 ct 970 -214 963 -216 957 -216 ct 953 -216 948 -215 943 -213 ct +938 -211 933 -208 928 -204 ct 923 -200 919 -196 914 -191 ct 910 -186 905 -181 901 -175 ct +897 -169 893 -164 889 -157 ct 883 -148 879 -140 878 -133 ct 878 -133 878 -133 850 0 ct +850 0 850 0 807 0 ct 807 0 807 0 860 -251 ct 860 -251 860 -251 901 -251 ct 901 -251 901 -251 889 -193 ct +903 -215 915 -232 928 -242 ct 940 -252 954 -257 968 -257 ct 980 -257 989 -253 996 -246 ct +p ef +1216 -233 m 1216 -233 1216 -233 1197 -200 ct 1176 -214 1154 -221 1129 -221 ct +1100 -221 1075 -209 1055 -185 ct 1035 -160 1025 -131 1025 -96 ct 1025 -75 1030 -58 1041 -47 ct +1052 -36 1068 -31 1087 -31 ct 1112 -31 1139 -39 1170 -56 ct 1170 -56 1170 -56 1175 -22 ct +1143 -3 1112 6 1081 6 ct 1050 6 1025 -3 1007 -20 ct 989 -38 980 -62 980 -93 ct +980 -139 995 -178 1024 -209 ct 1053 -241 1088 -257 1130 -257 ct 1145 -257 1161 -255 1177 -250 ct +1193 -246 1206 -240 1216 -233 ct p ef +1439 -22 m 1407 -3 1372 6 1336 6 ct 1303 6 1278 -3 1259 -20 ct 1240 -37 1230 -60 1230 -89 ct +1230 -134 1244 -173 1271 -207 ct 1298 -240 1332 -257 1373 -257 ct 1404 -257 1428 -249 1445 -233 ct +1462 -216 1470 -193 1470 -164 ct 1470 -156 1468 -142 1465 -122 ct 1465 -122 1465 -122 1278 -122 ct +1276 -114 1275 -104 1275 -92 ct 1275 -74 1280 -59 1291 -48 ct 1302 -37 1318 -31 1338 -31 ct +1366 -31 1398 -40 1433 -58 ct 1433 -58 1433 -58 1439 -22 ct p +1426 -155 m 1427 -159 1427 -161 1427 -163 ct 1427 -181 1422 -196 1412 -206 ct +1403 -217 1390 -222 1373 -222 ct 1334 -222 1305 -200 1288 -155 ct 1288 -155 1288 -155 1426 -155 ct +p ef +1881 -233 m 1881 -233 1881 -233 1862 -200 ct 1841 -214 1819 -221 1794 -221 ct +1765 -221 1740 -209 1720 -185 ct 1700 -160 1690 -131 1690 -96 ct 1690 -75 1695 -58 1706 -47 ct +1717 -36 1733 -31 1752 -31 ct 1777 -31 1804 -39 1835 -56 ct 1835 -56 1835 -56 1840 -22 ct +1808 -3 1777 6 1746 6 ct 1715 6 1690 -3 1672 -20 ct 1654 -38 1645 -62 1645 -93 ct +1645 -139 1660 -178 1689 -209 ct 1718 -241 1753 -257 1795 -257 ct 1810 -257 1826 -255 1842 -250 ct +1858 -246 1871 -240 1881 -233 ct p ef +2036 -257 m 2068 -257 2094 -248 2112 -231 ct 2131 -214 2140 -190 2140 -161 ct +2140 -116 2127 -78 2100 -44 ct 2074 -11 2041 6 2000 6 ct 1968 6 1942 -3 1923 -21 ct +1904 -38 1895 -62 1895 -91 ct 1895 -136 1908 -175 1935 -208 ct 1961 -241 1995 -257 2036 -257 ct +p +2000 -31 m 2028 -31 2050 -44 2068 -71 ct 2086 -98 2095 -128 2095 -160 ct 2095 -178 2090 -193 2079 -204 ct +2068 -215 2054 -220 2035 -220 ct 2007 -220 1984 -207 1966 -182 ct 1949 -157 1940 -128 1940 -94 ct +1940 -76 1945 -60 1956 -49 ct 1967 -37 1981 -31 2000 -31 ct p ef +2446 -359 m 2446 -359 2446 -359 2369 0 ct 2369 0 2369 0 2326 0 ct 2326 0 2326 0 2332 -28 ct +2312 -5 2287 6 2258 6 ct 2232 6 2210 -3 2194 -21 ct 2178 -39 2170 -63 2170 -93 ct +2170 -142 2183 -181 2210 -212 ct 2236 -242 2269 -257 2308 -257 ct 2335 -257 2357 -247 2374 -227 ct +2374 -227 2374 -227 2402 -359 ct 2402 -359 2402 -359 2446 -359 ct p +2365 -186 m 2350 -209 2331 -220 2308 -220 ct 2281 -220 2259 -208 2241 -184 ct +2224 -160 2215 -131 2215 -96 ct 2215 -76 2220 -61 2229 -49 ct 2239 -37 2252 -31 2269 -31 ct +2286 -31 2302 -37 2317 -49 ct 2332 -61 2340 -68 2341 -72 ct 2341 -72 2341 -72 2365 -186 ct +p ef +2654 -22 m 2622 -3 2587 6 2551 6 ct 2518 6 2493 -3 2474 -20 ct 2455 -37 2445 -60 2445 -89 ct +2445 -134 2459 -173 2486 -207 ct 2513 -240 2547 -257 2588 -257 ct 2619 -257 2643 -249 2660 -233 ct +2677 -216 2685 -193 2685 -164 ct 2685 -156 2683 -142 2680 -122 ct 2680 -122 2680 -122 2493 -122 ct +2491 -114 2490 -104 2490 -92 ct 2490 -74 2495 -59 2506 -48 ct 2517 -37 2533 -31 2553 -31 ct +2581 -31 2613 -40 2648 -58 ct 2648 -58 2648 -58 2654 -22 ct p +2641 -155 m 2642 -159 2642 -161 2642 -163 ct 2642 -181 2637 -196 2627 -206 ct +2618 -217 2605 -222 2588 -222 ct 2549 -222 2520 -200 2503 -155 ct 2503 -155 2503 -155 2641 -155 ct +p ef +pom +gr +gr +0 lw [ 508 508 508 508 ] 0 ld +0.003 0.003 0.003 c 2198 10743 m 19460 10743 l ps +2198 12343 m 19460 12343 l ps +1.000 0.003 0.003 c 9889 10903 m 9889 11895 l 9772 11895 l 10007 12226 l +10242 11895 l 10124 11895 l 10124 10903 l 9889 10903 l p ef +gs +gs +pum +10462 11590 t +0.003 0.003 0.003 c 350 -251 m 275 0 l 238 0 l 178 -202 l 116 0 l 79 0 l +6 -251 l 49 -251 l 100 -57 l 157 -251 l 198 -251 l 256 -57 l 307 -251 l +350 -251 l p ef +606 -24 m 570 -4 536 6 502 6 ct 461 6 429 -6 406 -29 ct 383 -53 371 -85 371 -126 ct +371 -165 382 -197 403 -221 ct 424 -245 453 -257 490 -257 ct 522 -257 549 -246 570 -224 ct +591 -201 601 -172 601 -134 ct 601 -134 601 -134 601 -123 ct 601 -123 601 -123 414 -123 ct +415 -93 423 -70 438 -55 ct 453 -39 474 -31 501 -31 ct 532 -31 563 -40 594 -58 ct +594 -58 594 -58 606 -24 ct p +558 -156 m 556 -176 548 -192 535 -204 ct 522 -216 507 -222 489 -222 ct 470 -222 454 -216 441 -205 ct +427 -193 419 -177 415 -156 ct 415 -156 415 -156 558 -156 ct p ef +879 0 m 879 0 879 0 834 0 ct 831 -4 829 -10 827 -17 ct 825 -24 824 -30 824 -35 ct +794 -8 761 6 726 6 ct 702 6 683 0 668 -12 ct 653 -25 646 -42 646 -64 ct 646 -81 650 -96 659 -108 ct +668 -120 681 -129 699 -136 ct 716 -142 739 -147 766 -148 ct 766 -148 766 -148 823 -152 ct +823 -152 823 -152 823 -160 ct 823 -183 818 -199 809 -208 ct 800 -217 783 -222 760 -222 ct +748 -222 734 -220 718 -215 ct 701 -210 687 -204 676 -198 ct 676 -198 676 -198 663 -230 ct +677 -238 693 -244 713 -249 ct 732 -254 750 -257 767 -257 ct 800 -257 825 -249 841 -234 ct +857 -219 865 -196 865 -165 ct 865 -165 865 -165 865 -60 ct 865 -34 870 -14 879 0 ct +p +823 -72 m 823 -72 823 -72 823 -119 ct 787 -117 764 -115 753 -114 ct 742 -113 731 -110 720 -107 ct +710 -103 702 -97 696 -91 ct 691 -84 688 -76 688 -65 ct 688 -55 692 -47 700 -41 ct +708 -34 719 -31 732 -31 ct 748 -31 765 -35 782 -42 ct 799 -50 813 -60 823 -72 ct +p ef +1146 -251 m 1046 0 l 1007 0 l 907 -251 l 950 -251 l 1027 -54 l 1103 -251 l +1146 -251 l p ef +1219 0 m 1177 0 l 1177 -251 l 1219 -251 l 1219 0 l p +1198 -359 m 1205 -359 1211 -356 1216 -351 ct 1221 -346 1224 -340 1224 -333 ct +1224 -326 1221 -320 1216 -315 ct 1211 -311 1205 -308 1198 -308 ct 1191 -308 1185 -311 1180 -315 ct +1176 -320 1173 -326 1173 -333 ct 1173 -340 1175 -347 1180 -352 ct 1185 -357 1191 -359 1198 -359 ct +p ef +1495 0 m 1495 0 1495 0 1453 0 ct 1453 0 1453 0 1453 -160 ct 1453 -179 1448 -194 1439 -204 ct +1429 -215 1417 -220 1400 -220 ct 1375 -220 1351 -206 1328 -179 ct 1328 -179 1328 -179 1328 0 ct +1328 0 1328 0 1286 0 ct 1286 0 1286 0 1286 -251 ct 1286 -251 1286 -251 1328 -251 ct +1328 -251 1328 -251 1328 -216 ct 1354 -243 1382 -257 1412 -257 ct 1437 -257 1458 -249 1473 -234 ct +1488 -219 1495 -198 1495 -171 ct 1495 -171 1495 -171 1495 0 ct p ef +1769 8 m 1769 39 1760 63 1741 79 ct 1722 96 1694 104 1659 104 ct 1623 104 1589 95 1556 76 ct +1556 76 1556 76 1568 42 ct 1600 59 1631 67 1660 67 ct 1681 67 1698 62 1709 51 ct +1721 41 1727 26 1727 7 ct 1727 7 1727 7 1727 -31 ct 1709 -6 1684 6 1654 6 ct 1621 6 1595 -6 1576 -30 ct +1557 -55 1548 -88 1548 -131 ct 1548 -168 1558 -199 1577 -222 ct 1597 -245 1621 -257 1651 -257 ct +1684 -257 1709 -245 1727 -220 ct 1727 -220 1727 -220 1727 -251 ct 1727 -251 1727 -251 1769 -251 ct +1769 -251 1769 -251 1769 8 ct p +1727 -73 m 1727 -73 1727 -73 1727 -180 ct 1721 -191 1713 -201 1701 -209 ct +1689 -216 1676 -220 1662 -220 ct 1639 -220 1622 -212 1609 -196 ct 1597 -179 1591 -156 1591 -127 ct +1591 -97 1597 -73 1610 -56 ct 1623 -39 1641 -31 1663 -31 ct 1672 -31 1681 -33 1691 -37 ct +1700 -42 1709 -48 1716 -56 ct 1723 -64 1727 -70 1727 -73 ct p ef +2092 69 m 2092 69 2092 69 2074 80 ct 2040 43 2016 8 2000 -26 ct 1985 -60 1977 -98 1977 -140 ct +1977 -181 1985 -219 2000 -253 ct 2016 -287 2040 -322 2074 -359 ct 2074 -359 2074 -359 2092 -348 ct +2068 -315 2050 -282 2039 -249 ct 2028 -216 2022 -180 2022 -140 ct 2022 -101 2028 -65 2039 -31 ct +2050 2 2068 35 2092 69 ct p ef +2360 0 m 2360 0 2360 0 2315 0 ct 2312 -4 2310 -10 2308 -17 ct 2306 -24 2305 -30 2305 -35 ct +2275 -8 2242 6 2207 6 ct 2183 6 2164 0 2149 -12 ct 2134 -25 2127 -42 2127 -64 ct +2127 -81 2131 -96 2140 -108 ct 2149 -120 2162 -129 2180 -136 ct 2197 -142 2220 -147 2247 -148 ct +2247 -148 2247 -148 2304 -152 ct 2304 -152 2304 -152 2304 -160 ct 2304 -183 2299 -199 2290 -208 ct +2281 -217 2264 -222 2241 -222 ct 2229 -222 2215 -220 2199 -215 ct 2182 -210 2168 -204 2157 -198 ct +2157 -198 2157 -198 2144 -230 ct 2158 -238 2174 -244 2194 -249 ct 2213 -254 2231 -257 2248 -257 ct +2281 -257 2306 -249 2322 -234 ct 2338 -219 2346 -196 2346 -165 ct 2346 -165 2346 -165 2346 -60 ct +2346 -34 2351 -14 2360 0 ct p +2304 -72 m 2304 -72 2304 -72 2304 -119 ct 2268 -117 2245 -115 2234 -114 ct +2223 -113 2212 -110 2201 -107 ct 2191 -103 2183 -97 2177 -91 ct 2172 -84 2169 -76 2169 -65 ct +2169 -55 2173 -47 2181 -41 ct 2189 -34 2200 -31 2213 -31 ct 2229 -31 2246 -35 2263 -42 ct +2280 -50 2294 -60 2304 -72 ct p ef +2403 -126 m 2403 -167 2415 -200 2439 -223 ct 2463 -246 2492 -257 2528 -257 ct +2557 -257 2586 -249 2613 -232 ct 2613 -232 2613 -232 2601 -199 ct 2577 -213 2553 -220 2528 -220 ct +2504 -220 2484 -211 2469 -194 ct 2454 -177 2446 -154 2446 -126 ct 2446 -97 2454 -74 2469 -57 ct +2485 -40 2505 -31 2528 -31 ct 2552 -31 2578 -39 2604 -56 ct 2604 -56 2604 -56 2617 -23 ct +2589 -4 2560 6 2528 6 ct 2491 6 2461 -6 2438 -30 ct 2415 -54 2403 -86 2403 -126 ct +p ef +2894 -145 m 2796 -145 l 2796 -47 l 2758 -47 l 2758 -145 l 2660 -145 l +2660 -183 l 2758 -183 l 2758 -281 l 2796 -281 l 2796 -183 l 2894 -183 l +2894 -145 l p ef +3182 -145 m 3084 -145 l 3084 -47 l 3046 -47 l 3046 -145 l 2948 -145 l +2948 -183 l 3046 -183 l 3046 -281 l 3084 -281 l 3084 -183 l 3182 -183 l +3182 -145 l p ef +3243 -359 m 3277 -322 3302 -287 3318 -253 ct 3333 -219 3341 -181 3341 -140 ct +3341 -98 3333 -60 3318 -26 ct 3302 8 3277 43 3243 80 ct 3243 80 3243 80 3225 69 ct +3249 36 3267 3 3279 -30 ct 3290 -63 3296 -100 3296 -140 ct 3296 -180 3290 -216 3279 -249 ct +3267 -282 3249 -315 3225 -348 ct 3225 -348 3225 -348 3243 -359 ct p ef +pom +gr +gr +0.503 0.503 0.503 c 14611 19223 m 10090 19223 l 10090 14993 l 19133 14993 l +19133 19223 l 14611 19223 l p ef +50 lw [ ] 0 ld +14611 19223 m 10090 19223 l 10090 14993 l 19133 14993 l 19133 19223 l +14611 19223 l pc +1.000 0.902 0.777 c 14511 19123 m 9990 19123 l 9990 14893 l 19033 14893 l +19033 19123 l 14511 19123 l p ef +0.003 0.003 0.003 c 14511 19123 m 9990 19123 l 9990 14893 l 19033 14893 l +19033 19123 l 14511 19123 l pc +gs +gs +pum +10197 15326 t +35 0 m 58 -93 l 11 -93 l 18 -124 l 66 -124 l 80 -184 l 33 -184 l +41 -215 l 88 -215 l 111 -306 l 142 -306 l 120 -215 l 168 -215 l 191 -306 l +222 -306 l 200 -215 l 246 -215 l 239 -184 l 192 -184 l 177 -124 l +224 -124 l 216 -93 l 169 -93 l 146 0 l 115 0 l 138 -93 l 89 -93 l +66 0 l 35 0 l p +97 -124 m 146 -124 l 160 -184 l 112 -184 l 97 -124 l p ef +371 0 m 371 -193 l 289 -193 l 289 -224 l 412 -224 l 412 0 l 371 0 l +p +366 -275 m 366 -326 l 417 -326 l 417 -275 l 366 -275 l p ef +545 0 m 545 0 545 0 545 -224 ct 545 -224 545 -224 586 -224 ct 586 -224 586 -224 584 -182 ct +584 -182 584 -182 586 -182 ct 596 -198 607 -209 620 -217 ct 632 -225 647 -229 663 -229 ct +684 -229 700 -223 711 -210 ct 722 -197 727 -178 727 -153 ct 727 -153 727 -153 727 0 ct +727 0 727 0 686 0 ct 686 0 686 0 686 -142 ct 686 -159 683 -172 678 -179 ct 672 -186 663 -190 650 -190 ct +640 -190 630 -186 619 -179 ct 608 -172 597 -161 586 -146 ct 586 -146 586 -146 586 0 ct +586 0 586 0 545 0 ct p ef +990 -7 m 966 1 942 5 918 5 ct 879 5 849 -5 828 -26 ct 807 -46 796 -75 796 -112 ct +796 -149 806 -177 827 -198 ct 848 -219 877 -229 914 -229 ct 938 -229 962 -225 986 -218 ct +986 -218 986 -218 986 -184 ct 959 -193 937 -198 918 -198 ct 894 -198 874 -190 860 -175 ct +846 -160 839 -139 839 -112 ct 839 -85 846 -64 861 -49 ct 876 -34 897 -26 923 -26 ct +943 -26 965 -31 990 -40 ct 990 -40 990 -40 990 -7 ct p ef +1138 0 m 1138 -295 l 1051 -295 l 1051 -326 l 1179 -326 l 1179 0 l +1138 0 l p ef +1488 -224 m 1488 -224 1488 -224 1488 0 ct 1488 0 1488 0 1447 0 ct 1447 0 1447 0 1449 -42 ct +1449 -42 1449 -42 1447 -42 ct 1438 -26 1426 -15 1414 -7 ct 1401 1 1386 5 1370 5 ct +1349 5 1333 -1 1322 -14 ct 1311 -27 1306 -46 1306 -71 ct 1306 -71 1306 -71 1306 -224 ct +1306 -224 1306 -224 1347 -224 ct 1347 -224 1347 -224 1347 -82 ct 1347 -65 1350 -52 1355 -45 ct +1361 -38 1370 -34 1383 -34 ct 1393 -34 1403 -38 1414 -45 ct 1425 -52 1436 -63 1447 -78 ct +1447 -78 1447 -78 1447 -224 ct 1447 -224 1447 -224 1488 -224 ct p ef +1706 0 m 1706 0 1706 0 1708 -42 ct 1708 -42 1708 -42 1706 -42 ct 1696 -26 1685 -15 1673 -7 ct +1660 1 1647 5 1632 5 ct 1607 5 1587 -5 1572 -24 ct 1557 -44 1550 -71 1550 -105 ct +1550 -142 1559 -172 1576 -195 ct 1594 -218 1616 -229 1644 -229 ct 1656 -229 1668 -226 1678 -221 ct +1688 -216 1698 -209 1706 -198 ct 1706 -198 1706 -198 1708 -198 ct 1708 -198 1708 -198 1706 -229 ct +1706 -229 1706 -229 1706 -326 ct 1706 -326 1706 -326 1747 -326 ct 1747 -326 1747 -326 1747 0 ct +1747 0 1747 0 1706 0 ct p +1706 -168 m 1696 -178 1687 -185 1678 -190 ct 1668 -195 1659 -198 1650 -198 ct +1632 -198 1618 -190 1608 -175 ct 1598 -159 1593 -137 1593 -109 ct 1593 -83 1597 -63 1605 -50 ct +1613 -38 1624 -31 1640 -31 ct 1652 -31 1663 -35 1674 -42 ct 1685 -49 1696 -59 1706 -73 ct +1706 -73 1706 -73 1706 -168 ct p ef +2004 -9 m 1976 0 1950 5 1926 5 ct 1888 5 1859 -5 1838 -25 ct 1817 -45 1807 -73 1807 -110 ct +1807 -144 1817 -173 1837 -195 ct 1857 -218 1882 -229 1913 -229 ct 1944 -229 1966 -220 1981 -201 ct +1996 -182 2003 -153 2003 -114 ct 2003 -114 2003 -114 2003 -101 ct 2003 -101 2003 -101 1849 -101 ct +1850 -76 1858 -57 1872 -45 ct 1886 -32 1905 -26 1931 -26 ct 1954 -26 1978 -31 2004 -42 ct +2004 -42 2004 -42 2004 -9 ct p +1850 -132 m 1850 -132 1850 -132 1960 -132 ct 1960 -132 1960 -132 1960 -138 ct +1960 -158 1956 -173 1947 -183 ct 1938 -193 1926 -198 1909 -198 ct 1892 -198 1879 -192 1868 -181 ct +1858 -169 1852 -153 1850 -132 ct p ef +2337 -214 m 2337 -214 2337 -214 2337 -260 ct 2337 -282 2341 -298 2350 -309 ct +2358 -320 2371 -326 2388 -326 ct 2388 -326 2388 -326 2388 -306 ct 2381 -306 2375 -303 2371 -298 ct +2368 -293 2366 -286 2366 -276 ct 2366 -276 2366 -276 2366 -265 ct 2366 -265 2366 -265 2388 -265 ct +2388 -265 2388 -265 2388 -214 ct 2388 -214 2388 -214 2337 -214 ct p +2439 -214 m 2439 -214 2439 -214 2439 -260 ct 2439 -282 2443 -298 2452 -309 ct +2460 -320 2473 -326 2490 -326 ct 2490 -326 2490 -326 2490 -306 ct 2483 -306 2477 -303 2473 -298 ct +2470 -293 2468 -286 2468 -276 ct 2468 -276 2468 -276 2468 -265 ct 2468 -265 2468 -265 2490 -265 ct +2490 -265 2490 -265 2490 -214 ct 2490 -214 2490 -214 2439 -214 ct p ef +2647 0 m 2647 -275 l 2545 -275 l 2545 -306 l 2790 -306 l 2790 -275 l +2688 -275 l 2688 0 l 2647 0 l p ef +2966 -26 m 2942 -5 2917 5 2893 5 ct 2872 5 2855 -1 2842 -13 ct 2829 -24 2822 -39 2822 -57 ct +2822 -81 2832 -99 2853 -114 ct 2874 -128 2901 -135 2935 -135 ct 2935 -135 2935 -135 2960 -135 ct +2960 -135 2960 -135 2960 -154 ct 2960 -169 2956 -180 2949 -187 ct 2941 -194 2930 -198 2915 -198 ct +2891 -198 2866 -191 2841 -177 ct 2841 -177 2841 -177 2841 -213 ct 2870 -224 2897 -229 2923 -229 ct +2952 -229 2972 -223 2983 -212 ct 2995 -201 3001 -181 3001 -153 ct 3001 -153 3001 -153 3001 -59 ct +3001 -45 3002 -36 3005 -31 ct 3008 -26 3014 -24 3021 -24 ct 3024 -24 3028 -25 3034 -26 ct +3034 -26 3034 -26 3038 -2 ct 3024 3 3014 5 3007 5 ct 2997 5 2988 2 2982 -3 ct 2975 -8 2970 -16 2966 -26 ct +p +2960 -53 m 2960 -53 2960 -53 2960 -110 ct 2960 -110 2960 -110 2948 -110 ct +2920 -110 2899 -106 2885 -99 ct 2871 -91 2864 -80 2864 -64 ct 2864 -52 2867 -43 2874 -37 ct +2880 -31 2890 -28 2903 -28 ct 2921 -28 2940 -36 2960 -53 ct p ef +3112 0 m 3112 0 3112 0 3112 -224 ct 3112 -224 3112 -224 3153 -224 ct 3153 -224 3153 -224 3151 -182 ct +3151 -182 3151 -182 3153 -182 ct 3163 -198 3175 -209 3189 -217 ct 3203 -225 3218 -229 3236 -229 ct +3248 -229 3262 -227 3277 -224 ct 3277 -224 3277 -224 3277 -160 ct 3277 -160 3277 -160 3246 -160 ct +3246 -160 3246 -160 3246 -191 ct 3240 -192 3234 -193 3229 -193 ct 3215 -193 3202 -189 3190 -181 ct +3177 -173 3165 -161 3153 -145 ct 3153 -145 3153 -145 3153 0 ct 3153 0 3153 0 3112 0 ct +p ef +3345 75 m 3345 75 3345 75 3349 41 ct 3374 51 3397 56 3418 56 ct 3440 56 3456 51 3465 42 ct +3475 33 3481 17 3484 -6 ct 3484 -6 3484 -6 3488 -46 ct 3488 -46 3488 -46 3484 -46 ct +3476 -31 3465 -19 3453 -12 ct 3440 -4 3426 0 3410 0 ct 3385 0 3365 -10 3350 -29 ct +3335 -49 3327 -75 3327 -108 ct 3327 -144 3336 -173 3353 -195 ct 3371 -218 3393 -229 3421 -229 ct +3443 -229 3465 -219 3486 -198 ct 3486 -198 3486 -198 3489 -198 ct 3489 -198 3489 -198 3489 -224 ct +3489 -224 3489 -224 3525 -224 ct 3525 -224 3525 -224 3525 -45 ct 3525 -15 3523 6 3519 21 ct +3515 36 3508 49 3497 60 ct 3480 78 3454 87 3417 87 ct 3396 87 3372 83 3345 75 ct +p +3484 -80 m 3484 -80 3484 -80 3484 -167 ct 3466 -188 3446 -198 3427 -198 ct +3408 -198 3394 -191 3384 -176 ct 3375 -162 3370 -140 3370 -111 ct 3370 -86 3374 -67 3382 -55 ct +3391 -42 3403 -36 3420 -36 ct 3432 -36 3443 -40 3454 -47 ct 3465 -54 3475 -65 3484 -80 ct +p ef +3782 -9 m 3754 0 3728 5 3704 5 ct 3666 5 3637 -5 3616 -25 ct 3595 -45 3585 -73 3585 -110 ct +3585 -144 3595 -173 3615 -195 ct 3635 -218 3660 -229 3691 -229 ct 3722 -229 3744 -220 3759 -201 ct +3774 -182 3781 -153 3781 -114 ct 3781 -114 3781 -114 3781 -101 ct 3781 -101 3781 -101 3627 -101 ct +3628 -76 3636 -57 3650 -45 ct 3664 -32 3683 -26 3709 -26 ct 3732 -26 3756 -31 3782 -42 ct +3782 -42 3782 -42 3782 -9 ct p +3628 -132 m 3628 -132 3628 -132 3738 -132 ct 3738 -132 3738 -132 3738 -138 ct +3738 -158 3734 -173 3725 -183 ct 3716 -193 3704 -198 3687 -198 ct 3670 -198 3657 -192 3646 -181 ct +3636 -169 3630 -153 3628 -132 ct p ef +4038 0 m 4018 3 3998 5 3979 5 ct 3946 5 3923 -1 3911 -13 ct 3899 -25 3893 -47 3893 -80 ct +3893 -80 3893 -80 3893 -188 ct 3893 -188 3893 -188 3837 -188 ct 3837 -188 3837 -188 3837 -219 ct +3837 -219 3837 -219 3893 -219 ct 3893 -219 3893 -219 3893 -267 ct 3893 -267 3893 -267 3934 -267 ct +3934 -267 3934 -267 3934 -219 ct 3934 -219 3934 -219 4033 -219 ct 4033 -219 4033 -219 4033 -188 ct +4033 -188 4033 -188 3934 -188 ct 3934 -188 3934 -188 3934 -74 ct 3934 -61 3935 -53 3936 -48 ct +3938 -43 3941 -39 3947 -35 ct 3956 -29 3969 -26 3987 -26 ct 4004 -26 4021 -28 4038 -31 ct +4038 -31 4038 -31 4038 0 ct p ef +4161 0 m 4161 -61 l 4222 -61 l 4222 0 l 4161 0 l p ef +4355 0 m 4355 0 4355 0 4355 -326 ct 4355 -326 4355 -326 4396 -326 ct 4396 -326 4396 -326 4396 -224 ct +4396 -224 4396 -224 4394 -182 ct 4394 -182 4394 -182 4396 -182 ct 4406 -198 4417 -209 4430 -217 ct +4442 -225 4457 -229 4473 -229 ct 4494 -229 4510 -223 4521 -210 ct 4532 -197 4537 -178 4537 -153 ct +4537 -153 4537 -153 4537 0 ct 4537 0 4537 0 4496 0 ct 4496 0 4496 0 4496 -142 ct +4496 -159 4493 -172 4488 -179 ct 4482 -186 4473 -190 4460 -190 ct 4450 -190 4440 -186 4429 -179 ct +4418 -172 4407 -161 4396 -146 ct 4396 -146 4396 -146 4396 0 ct 4396 0 4396 0 4355 0 ct +p ef +4623 -214 m 4623 -214 4623 -214 4623 -260 ct 4623 -282 4627 -298 4636 -309 ct +4644 -320 4657 -326 4674 -326 ct 4674 -326 4674 -326 4674 -306 ct 4667 -306 4661 -303 4657 -298 ct +4654 -293 4652 -286 4652 -276 ct 4652 -276 4652 -276 4652 -265 ct 4652 -265 4652 -265 4674 -265 ct +4674 -265 4674 -265 4674 -214 ct 4674 -214 4674 -214 4623 -214 ct p +4725 -214 m 4725 -214 4725 -214 4725 -260 ct 4725 -282 4729 -298 4738 -309 ct +4746 -320 4759 -326 4776 -326 ct 4776 -326 4776 -326 4776 -306 ct 4769 -306 4763 -303 4759 -298 ct +4756 -293 4754 -286 4754 -276 ct 4754 -276 4754 -276 4754 -265 ct 4754 -265 4754 -265 4776 -265 ct +4776 -265 4776 -265 4776 -214 ct 4776 -214 4776 -214 4725 -214 ct p ef +pom +gr +gs +pum +15277 15326 t +0.003 0.503 0.003 c 239 -326 m 65 61 l 15 61 l 189 -326 l 239 -326 l +p ef +493 -326 m 319 61 l 269 61 l 443 -326 l 493 -326 l p ef +847 0 m 847 0 847 0 847 -178 ct 847 -178 847 -178 804 -178 ct 804 -178 804 -178 804 -219 ct +804 -219 804 -219 847 -219 ct 847 -219 847 -219 847 -251 ct 847 -278 855 -298 870 -311 ct +885 -324 908 -331 939 -331 ct 965 -331 990 -328 1015 -322 ct 1015 -322 1015 -322 1015 -278 ct +989 -286 968 -290 952 -290 ct 936 -290 925 -287 918 -281 ct 911 -275 908 -265 908 -250 ct +908 -250 908 -250 908 -219 ct 908 -219 908 -219 995 -219 ct 995 -219 995 -219 995 -178 ct +995 -178 995 -178 908 -178 ct 908 -178 908 -178 908 0 ct 908 0 908 0 847 0 ct p ef +1142 5 m 1108 5 1080 -6 1059 -27 ct 1038 -49 1027 -77 1027 -112 ct 1027 -148 1038 -176 1059 -197 ct +1080 -218 1108 -229 1144 -229 ct 1179 -229 1207 -218 1228 -197 ct 1249 -176 1260 -148 1260 -112 ct +1260 -76 1249 -48 1228 -27 ct 1207 -6 1178 5 1142 5 ct p +1143 -36 m 1160 -36 1173 -42 1181 -55 ct 1190 -68 1194 -87 1194 -112 ct 1194 -138 1190 -156 1181 -169 ct +1173 -182 1160 -188 1144 -188 ct 1127 -188 1114 -182 1106 -169 ct 1097 -156 1093 -137 1093 -112 ct +1093 -87 1097 -68 1105 -55 ct 1114 -42 1126 -36 1143 -36 ct p ef +1316 0 m 1316 0 1316 0 1316 -224 ct 1316 -224 1316 -224 1377 -224 ct 1377 -224 1377 -224 1375 -181 ct +1375 -181 1375 -181 1377 -181 ct 1387 -197 1399 -209 1413 -217 ct 1426 -225 1442 -229 1460 -229 ct +1471 -229 1486 -227 1502 -224 ct 1502 -224 1502 -224 1502 -149 ct 1502 -149 1502 -149 1461 -149 ct +1461 -149 1461 -149 1461 -173 ct 1456 -174 1453 -174 1450 -174 ct 1435 -174 1422 -170 1409 -163 ct +1397 -156 1386 -145 1377 -130 ct 1377 -130 1377 -130 1377 0 ct 1377 0 1377 0 1316 0 ct +p ef +1880 0 m 1880 -285 l 1798 -285 l 1798 -326 l 1941 -326 l 1941 0 l +1880 0 l p ef +2185 -24 m 2178 -14 2169 -7 2159 -2 ct 2149 3 2138 5 2125 5 ct 2103 5 2085 -2 2071 -15 ct +2057 -28 2050 -45 2050 -65 ct 2050 -91 2060 -111 2079 -124 ct 2099 -137 2128 -143 2167 -143 ct +2167 -143 2167 -143 2191 -143 ct 2191 -143 2191 -143 2191 -154 ct 2191 -165 2187 -174 2179 -179 ct +2171 -185 2159 -188 2143 -188 ct 2121 -188 2096 -182 2069 -169 ct 2069 -169 2069 -169 2069 -214 ct +2097 -224 2125 -229 2154 -229 ct 2186 -229 2210 -223 2226 -211 ct 2236 -203 2243 -194 2247 -185 ct +2250 -175 2252 -160 2252 -140 ct 2252 -140 2252 -140 2252 -64 ct 2252 -49 2257 -41 2266 -41 ct +2268 -41 2270 -41 2273 -42 ct 2273 -42 2273 -42 2273 -2 ct 2261 3 2249 5 2239 5 ct +2228 5 2218 3 2210 -2 ct 2202 -7 2196 -14 2191 -24 ct 2191 -24 2191 -24 2185 -24 ct +p +2191 -65 m 2191 -65 2191 -65 2191 -102 ct 2191 -102 2191 -102 2169 -102 ct +2150 -102 2135 -99 2126 -94 ct 2116 -88 2111 -80 2111 -69 ct 2111 -61 2114 -54 2120 -49 ct +2126 -44 2133 -41 2142 -41 ct 2157 -41 2174 -49 2191 -65 ct p ef +2319 -8 m 2319 -8 2319 -8 2319 -54 ct 2353 -42 2381 -36 2401 -36 ct 2416 -36 2427 -38 2435 -42 ct +2442 -46 2446 -52 2446 -60 ct 2446 -64 2444 -68 2440 -72 ct 2437 -75 2431 -79 2424 -82 ct +2424 -82 2424 -82 2376 -101 ct 2357 -109 2343 -118 2334 -127 ct 2325 -137 2320 -148 2320 -161 ct +2320 -182 2330 -199 2349 -211 ct 2368 -223 2395 -229 2429 -229 ct 2449 -229 2472 -226 2498 -221 ct +2498 -221 2498 -221 2498 -174 ct 2470 -183 2446 -188 2427 -188 ct 2412 -188 2402 -186 2395 -183 ct +2388 -180 2384 -175 2384 -169 ct 2384 -165 2387 -162 2392 -158 ct 2397 -154 2404 -150 2414 -146 ct +2414 -146 2414 -146 2467 -124 ct 2483 -118 2495 -110 2502 -100 ct 2510 -91 2514 -79 2514 -66 ct +2514 -45 2505 -28 2486 -15 ct 2467 -2 2443 5 2413 5 ct 2387 5 2355 1 2319 -8 ct +p ef +2768 -6 m 2744 1 2722 5 2704 5 ct 2675 5 2654 -1 2640 -14 ct 2626 -26 2619 -45 2619 -70 ct +2619 -70 2619 -70 2619 -178 ct 2619 -178 2619 -178 2571 -178 ct 2571 -178 2571 -178 2571 -219 ct +2571 -219 2571 -219 2619 -219 ct 2619 -219 2619 -219 2619 -285 ct 2619 -285 2619 -285 2680 -285 ct +2680 -285 2680 -285 2680 -219 ct 2680 -219 2680 -219 2763 -219 ct 2763 -219 2763 -219 2763 -178 ct +2763 -178 2763 -178 2680 -178 ct 2680 -178 2680 -178 2680 -84 ct 2680 -68 2683 -57 2689 -51 ct +2695 -44 2705 -41 2719 -41 ct 2736 -41 2752 -44 2768 -51 ct 2768 -51 2768 -51 2768 -6 ct +p ef +2794 46 m 2794 0 l 3049 0 l 3049 46 l 2794 46 l p ef +pom +gr +gs +pum +10197 16308 t +0.003 0.003 1.000 c 227 -4 m 202 2 177 5 152 5 ct 111 5 78 -5 55 -26 ct 32 -47 20 -75 20 -111 ct +20 -148 31 -177 54 -198 ct 76 -219 108 -229 148 -229 ct 178 -229 204 -226 227 -220 ct +227 -220 227 -220 227 -175 ct 202 -184 179 -188 156 -188 ct 134 -188 117 -182 105 -169 ct +92 -157 86 -140 86 -118 ct 86 -94 94 -74 109 -60 ct 124 -45 144 -38 169 -38 ct +188 -38 208 -42 227 -49 ct 227 -49 227 -49 227 -4 ct p ef +356 0 m 356 -285 l 274 -285 l 274 -326 l 417 -326 l 417 0 l 356 0 l +p ef +661 -24 m 654 -14 645 -7 635 -2 ct 625 3 614 5 601 5 ct 579 5 561 -2 547 -15 ct +533 -28 526 -45 526 -65 ct 526 -91 536 -111 555 -124 ct 575 -137 604 -143 643 -143 ct +643 -143 643 -143 667 -143 ct 667 -143 667 -143 667 -154 ct 667 -165 663 -174 655 -179 ct +647 -185 635 -188 619 -188 ct 597 -188 572 -182 545 -169 ct 545 -169 545 -169 545 -214 ct +573 -224 601 -229 630 -229 ct 662 -229 686 -223 702 -211 ct 712 -203 719 -194 723 -185 ct +726 -175 728 -160 728 -140 ct 728 -140 728 -140 728 -64 ct 728 -49 733 -41 742 -41 ct +744 -41 746 -41 749 -42 ct 749 -42 749 -42 749 -2 ct 737 3 725 5 715 5 ct 704 5 694 3 686 -2 ct +678 -7 672 -14 667 -24 ct 667 -24 667 -24 661 -24 ct p +667 -65 m 667 -65 667 -65 667 -102 ct 667 -102 667 -102 645 -102 ct 626 -102 611 -99 602 -94 ct +592 -88 587 -80 587 -69 ct 587 -61 590 -54 596 -49 ct 602 -44 609 -41 618 -41 ct +633 -41 650 -49 667 -65 ct p ef +795 -8 m 795 -8 795 -8 795 -54 ct 829 -42 857 -36 877 -36 ct 892 -36 903 -38 911 -42 ct +918 -46 922 -52 922 -60 ct 922 -64 920 -68 916 -72 ct 913 -75 907 -79 900 -82 ct +900 -82 900 -82 852 -101 ct 833 -109 819 -118 810 -127 ct 801 -137 796 -148 796 -161 ct +796 -182 806 -199 825 -211 ct 844 -223 871 -229 905 -229 ct 925 -229 948 -226 974 -221 ct +974 -221 974 -221 974 -174 ct 946 -183 922 -188 903 -188 ct 888 -188 878 -186 871 -183 ct +864 -180 860 -175 860 -169 ct 860 -165 863 -162 868 -158 ct 873 -154 880 -150 890 -146 ct +890 -146 890 -146 943 -124 ct 959 -118 971 -110 978 -100 ct 986 -91 990 -79 990 -66 ct +990 -45 981 -28 962 -15 ct 943 -2 919 5 889 5 ct 863 5 831 1 795 -8 ct p ef +1049 -8 m 1049 -8 1049 -8 1049 -54 ct 1083 -42 1111 -36 1131 -36 ct 1146 -36 1157 -38 1165 -42 ct +1172 -46 1176 -52 1176 -60 ct 1176 -64 1174 -68 1170 -72 ct 1167 -75 1161 -79 1154 -82 ct +1154 -82 1154 -82 1106 -101 ct 1087 -109 1073 -118 1064 -127 ct 1055 -137 1050 -148 1050 -161 ct +1050 -182 1060 -199 1079 -211 ct 1098 -223 1125 -229 1159 -229 ct 1179 -229 1202 -226 1228 -221 ct +1228 -221 1228 -221 1228 -174 ct 1200 -183 1176 -188 1157 -188 ct 1142 -188 1132 -186 1125 -183 ct +1118 -180 1114 -175 1114 -169 ct 1114 -165 1117 -162 1122 -158 ct 1127 -154 1134 -150 1144 -146 ct +1144 -146 1144 -146 1197 -124 ct 1213 -118 1225 -110 1232 -100 ct 1240 -91 1244 -79 1244 -66 ct +1244 -45 1235 -28 1216 -15 ct 1197 -2 1173 5 1143 5 ct 1117 5 1085 1 1049 -8 ct +p ef +pom +gr +gs +pum +11467 16308 t +301 0 m 301 0 301 0 301 -306 ct 301 -306 301 -306 387 -306 ct 425 -306 452 -300 468 -287 ct +485 -274 493 -253 493 -224 ct 493 -192 482 -167 461 -149 ct 439 -131 410 -122 372 -122 ct +372 -122 372 -122 342 -122 ct 342 -122 342 -122 342 0 ct 342 0 342 0 301 0 ct p +342 -153 m 342 -153 342 -153 367 -153 ct 395 -153 416 -159 429 -171 ct 443 -183 450 -200 450 -224 ct +450 -241 444 -254 433 -262 ct 422 -271 405 -275 383 -275 ct 383 -275 383 -275 342 -275 ct +342 -275 342 -275 342 -153 ct p ef +572 0 m 572 0 572 0 572 -224 ct 572 -224 572 -224 613 -224 ct 613 -224 613 -224 611 -182 ct +611 -182 611 -182 613 -182 ct 623 -198 635 -209 649 -217 ct 663 -225 678 -229 696 -229 ct +708 -229 722 -227 737 -224 ct 737 -224 737 -224 737 -160 ct 737 -160 737 -160 706 -160 ct +706 -160 706 -160 706 -191 ct 700 -192 694 -193 689 -193 ct 675 -193 662 -189 650 -181 ct +637 -173 625 -161 613 -145 ct 613 -145 613 -145 613 0 ct 613 0 613 0 572 0 ct p ef +888 5 m 856 5 831 -6 812 -27 ct 793 -48 784 -76 784 -112 ct 784 -148 793 -177 812 -198 ct +831 -219 857 -229 890 -229 ct 922 -229 948 -219 967 -198 ct 986 -177 995 -149 995 -113 ct +995 -76 986 -47 967 -26 ct 948 -5 922 5 888 5 ct p +889 -26 m 910 -26 926 -33 936 -48 ct 947 -62 952 -84 952 -113 ct 952 -139 946 -160 935 -175 ct +924 -190 909 -198 890 -198 ct 870 -198 855 -190 844 -175 ct 833 -160 827 -139 827 -112 ct +827 -85 832 -64 843 -49 ct 854 -34 870 -26 889 -26 ct p ef +1052 2 m 1052 2 1052 2 1052 -326 ct 1052 -326 1052 -326 1093 -326 ct 1093 -326 1093 -326 1093 -224 ct +1093 -224 1093 -224 1091 -182 ct 1091 -182 1091 -182 1093 -182 ct 1103 -198 1114 -209 1126 -217 ct +1138 -225 1152 -229 1166 -229 ct 1191 -229 1211 -219 1226 -200 ct 1241 -180 1248 -153 1248 -120 ct +1248 -82 1239 -52 1222 -29 ct 1205 -6 1182 5 1154 5 ct 1142 5 1131 2 1121 -3 ct +1111 -8 1101 -15 1093 -26 ct 1093 -26 1093 -26 1091 -26 ct 1091 -26 1091 -26 1083 2 ct +1083 2 1083 2 1052 2 ct p +1093 -56 m 1102 -46 1112 -39 1121 -34 ct 1130 -29 1139 -26 1149 -26 ct 1167 -26 1180 -34 1190 -49 ct +1200 -65 1205 -87 1205 -115 ct 1205 -141 1201 -160 1193 -173 ct 1185 -186 1174 -193 1158 -193 ct +1146 -193 1135 -189 1124 -182 ct 1113 -175 1103 -165 1093 -151 ct 1093 -151 1093 -151 1093 -56 ct +p ef +1392 0 m 1392 -295 l 1305 -295 l 1305 -326 l 1433 -326 l 1433 0 l +1392 0 l p ef +1750 -9 m 1722 0 1696 5 1672 5 ct 1634 5 1605 -5 1584 -25 ct 1563 -45 1553 -73 1553 -110 ct +1553 -144 1563 -173 1583 -195 ct 1603 -218 1628 -229 1659 -229 ct 1690 -229 1712 -220 1727 -201 ct +1742 -182 1749 -153 1749 -114 ct 1749 -114 1749 -114 1749 -101 ct 1749 -101 1749 -101 1595 -101 ct +1596 -76 1604 -57 1618 -45 ct 1632 -32 1651 -26 1677 -26 ct 1700 -26 1724 -31 1750 -42 ct +1750 -42 1750 -42 1750 -9 ct p +1596 -132 m 1596 -132 1596 -132 1706 -132 ct 1706 -132 1706 -132 1706 -138 ct +1706 -158 1702 -173 1693 -183 ct 1684 -193 1672 -198 1655 -198 ct 1638 -198 1625 -192 1614 -181 ct +1604 -169 1598 -153 1596 -132 ct p ef +1797 0 m 1797 0 1797 0 1797 -224 ct 1797 -224 1797 -224 1833 -224 ct 1833 -224 1833 -224 1830 -182 ct +1830 -182 1830 -182 1833 -182 ct 1841 -198 1850 -209 1859 -217 ct 1867 -225 1875 -229 1883 -229 ct +1894 -229 1902 -225 1909 -216 ct 1916 -208 1920 -196 1921 -182 ct 1921 -182 1921 -182 1924 -182 ct +1931 -198 1939 -209 1947 -217 ct 1956 -225 1965 -229 1975 -229 ct 1988 -229 1998 -224 2005 -213 ct +2012 -202 2015 -186 2015 -164 ct 2015 -164 2015 -164 2015 0 ct 2015 0 2015 0 1979 0 ct +1979 0 1979 0 1979 -162 ct 1979 -172 1978 -180 1976 -185 ct 1974 -190 1970 -193 1966 -193 ct +1960 -193 1953 -189 1946 -181 ct 1939 -173 1931 -160 1924 -144 ct 1924 -144 1924 -144 1924 0 ct +1924 0 1924 0 1888 0 ct 1888 0 1888 0 1888 -155 ct 1888 -167 1887 -177 1885 -183 ct +1882 -190 1879 -193 1875 -193 ct 1869 -193 1862 -188 1854 -179 ct 1846 -170 1839 -158 1833 -144 ct +1833 -144 1833 -144 1833 0 ct 1833 0 1833 0 1797 0 ct p ef +2498 -326 m 2498 -326 2498 -326 2498 -295 ct 2498 -295 2498 -295 2482 -295 ct +2461 -295 2447 -293 2439 -287 ct 2430 -282 2426 -274 2426 -261 ct 2426 -257 2427 -251 2428 -242 ct +2428 -242 2428 -242 2432 -214 ct 2433 -204 2434 -196 2434 -190 ct 2434 -175 2431 -163 2424 -153 ct +2417 -144 2407 -137 2393 -132 ct 2407 -128 2417 -121 2424 -111 ct 2431 -102 2434 -90 2434 -75 ct +2434 -68 2433 -61 2432 -51 ct 2432 -51 2432 -51 2428 -23 ct 2427 -14 2426 -8 2426 -4 ct +2426 9 2430 17 2439 22 ct 2447 27 2461 30 2482 30 ct 2482 30 2482 30 2498 30 ct +2498 30 2498 30 2498 61 ct 2498 61 2498 61 2475 61 ct 2446 61 2424 56 2410 46 ct +2395 36 2388 21 2388 2 ct 2388 -7 2389 -16 2391 -26 ct 2391 -26 2391 -26 2398 -63 ct +2399 -68 2399 -74 2399 -79 ct 2399 -92 2395 -101 2387 -108 ct 2380 -114 2368 -117 2353 -117 ct +2353 -117 2353 -117 2334 -117 ct 2334 -117 2334 -117 2334 -148 ct 2334 -148 2334 -148 2353 -148 ct +2368 -148 2380 -151 2387 -157 ct 2395 -164 2399 -173 2399 -186 ct 2399 -191 2399 -197 2398 -202 ct +2398 -202 2398 -202 2391 -239 ct 2389 -249 2388 -258 2388 -267 ct 2388 -286 2395 -301 2410 -311 ct +2424 -321 2446 -326 2475 -326 ct 2475 -326 2475 -326 2498 -326 ct p ef +pom +gr +gs +pum +10197 16799 t +pom +gr +gs +pum +10705 16799 t +107 0 m 107 -275 l 5 -275 l 5 -306 l 250 -306 l 250 -275 l 148 -275 l +148 0 l 107 0 l p ef +426 -26 m 402 -5 377 5 353 5 ct 332 5 315 -1 302 -13 ct 289 -24 282 -39 282 -57 ct +282 -81 292 -99 313 -114 ct 334 -128 361 -135 395 -135 ct 395 -135 395 -135 420 -135 ct +420 -135 420 -135 420 -154 ct 420 -169 416 -180 409 -187 ct 401 -194 390 -198 375 -198 ct +351 -198 326 -191 301 -177 ct 301 -177 301 -177 301 -213 ct 330 -224 357 -229 383 -229 ct +412 -229 432 -223 443 -212 ct 455 -201 461 -181 461 -153 ct 461 -153 461 -153 461 -59 ct +461 -45 462 -36 465 -31 ct 468 -26 474 -24 481 -24 ct 484 -24 488 -25 494 -26 ct +494 -26 494 -26 498 -2 ct 484 3 474 5 467 5 ct 457 5 448 2 442 -3 ct 435 -8 430 -16 426 -26 ct +p +420 -53 m 420 -53 420 -53 420 -110 ct 420 -110 420 -110 408 -110 ct 380 -110 359 -106 345 -99 ct +331 -91 324 -80 324 -64 ct 324 -52 327 -43 334 -37 ct 340 -31 350 -28 363 -28 ct +381 -28 400 -36 420 -53 ct p ef +572 0 m 572 0 572 0 572 -224 ct 572 -224 572 -224 613 -224 ct 613 -224 613 -224 611 -182 ct +611 -182 611 -182 613 -182 ct 623 -198 635 -209 649 -217 ct 663 -225 678 -229 696 -229 ct +708 -229 722 -227 737 -224 ct 737 -224 737 -224 737 -160 ct 737 -160 737 -160 706 -160 ct +706 -160 706 -160 706 -191 ct 700 -192 694 -193 689 -193 ct 675 -193 662 -189 650 -181 ct +637 -173 625 -161 613 -145 ct 613 -145 613 -145 613 0 ct 613 0 613 0 572 0 ct p ef +805 75 m 805 75 805 75 809 41 ct 834 51 857 56 878 56 ct 900 56 916 51 925 42 ct +935 33 941 17 944 -6 ct 944 -6 944 -6 948 -46 ct 948 -46 948 -46 944 -46 ct 936 -31 925 -19 913 -12 ct +900 -4 886 0 870 0 ct 845 0 825 -10 810 -29 ct 795 -49 787 -75 787 -108 ct 787 -144 796 -173 813 -195 ct +831 -218 853 -229 881 -229 ct 903 -229 925 -219 946 -198 ct 946 -198 946 -198 949 -198 ct +949 -198 949 -198 949 -224 ct 949 -224 949 -224 985 -224 ct 985 -224 985 -224 985 -45 ct +985 -15 983 6 979 21 ct 975 36 968 49 957 60 ct 940 78 914 87 877 87 ct 856 87 832 83 805 75 ct +p +944 -80 m 944 -80 944 -80 944 -167 ct 926 -188 906 -198 887 -198 ct 868 -198 854 -191 844 -176 ct +835 -162 830 -140 830 -111 ct 830 -86 834 -67 842 -55 ct 851 -42 863 -36 880 -36 ct +892 -36 903 -40 914 -47 ct 925 -54 935 -65 944 -80 ct p ef +1242 -9 m 1214 0 1188 5 1164 5 ct 1126 5 1097 -5 1076 -25 ct 1055 -45 1045 -73 1045 -110 ct +1045 -144 1055 -173 1075 -195 ct 1095 -218 1120 -229 1151 -229 ct 1182 -229 1204 -220 1219 -201 ct +1234 -182 1241 -153 1241 -114 ct 1241 -114 1241 -114 1241 -101 ct 1241 -101 1241 -101 1087 -101 ct +1088 -76 1096 -57 1110 -45 ct 1124 -32 1143 -26 1169 -26 ct 1192 -26 1216 -31 1242 -42 ct +1242 -42 1242 -42 1242 -9 ct p +1088 -132 m 1088 -132 1088 -132 1198 -132 ct 1198 -132 1198 -132 1198 -138 ct +1198 -158 1194 -173 1185 -183 ct 1176 -193 1164 -198 1147 -198 ct 1130 -198 1117 -192 1106 -181 ct +1096 -169 1090 -153 1088 -132 ct p ef +1498 0 m 1478 3 1458 5 1439 5 ct 1406 5 1383 -1 1371 -13 ct 1359 -25 1353 -47 1353 -80 ct +1353 -80 1353 -80 1353 -188 ct 1353 -188 1353 -188 1297 -188 ct 1297 -188 1297 -188 1297 -219 ct +1297 -219 1297 -219 1353 -219 ct 1353 -219 1353 -219 1353 -267 ct 1353 -267 1353 -267 1394 -267 ct +1394 -267 1394 -267 1394 -219 ct 1394 -219 1394 -219 1493 -219 ct 1493 -219 1493 -219 1493 -188 ct +1493 -188 1493 -188 1394 -188 ct 1394 -188 1394 -188 1394 -74 ct 1394 -61 1395 -53 1396 -48 ct +1398 -43 1401 -39 1407 -35 ct 1416 -29 1429 -26 1447 -26 ct 1464 -26 1481 -28 1498 -31 ct +1498 -31 1498 -31 1498 0 ct p ef +1923 -234 m 1923 -234 1923 -234 1986 -262 ct 1986 -262 1986 -262 1999 -223 ct +1999 -223 1999 -223 1931 -209 ct 1931 -209 1931 -209 1931 -212 ct 1931 -219 1928 -227 1923 -234 ct +p +1929 -203 m 1929 -203 1929 -203 1976 -152 ct 1976 -152 1976 -152 1943 -128 ct +1943 -128 1943 -128 1909 -188 ct 1917 -191 1924 -196 1929 -203 ct p +1902 -188 m 1902 -188 1902 -188 1868 -128 ct 1868 -128 1868 -128 1835 -152 ct +1835 -152 1835 -152 1882 -203 ct 1887 -196 1894 -191 1902 -188 ct p +1880 -209 m 1880 -209 1880 -209 1812 -223 ct 1812 -223 1812 -223 1825 -262 ct +1825 -262 1825 -262 1888 -233 ct 1883 -226 1880 -219 1880 -212 ct 1880 -212 1880 -212 1880 -209 ct +p +1893 -237 m 1893 -237 1893 -237 1885 -306 ct 1885 -306 1885 -306 1926 -306 ct +1926 -306 1926 -306 1918 -237 ct 1913 -239 1909 -240 1906 -240 ct 1902 -240 1898 -239 1893 -237 ct +p ef +2154 0 m 2154 -295 l 2067 -295 l 2067 -326 l 2195 -326 l 2195 0 l +2154 0 l p ef +2458 -26 m 2434 -5 2409 5 2385 5 ct 2364 5 2347 -1 2334 -13 ct 2321 -24 2314 -39 2314 -57 ct +2314 -81 2324 -99 2345 -114 ct 2366 -128 2393 -135 2427 -135 ct 2427 -135 2427 -135 2452 -135 ct +2452 -135 2452 -135 2452 -154 ct 2452 -169 2448 -180 2441 -187 ct 2433 -194 2422 -198 2407 -198 ct +2383 -198 2358 -191 2333 -177 ct 2333 -177 2333 -177 2333 -213 ct 2362 -224 2389 -229 2415 -229 ct +2444 -229 2464 -223 2475 -212 ct 2487 -201 2493 -181 2493 -153 ct 2493 -153 2493 -153 2493 -59 ct +2493 -45 2494 -36 2497 -31 ct 2500 -26 2506 -24 2513 -24 ct 2516 -24 2520 -25 2526 -26 ct +2526 -26 2526 -26 2530 -2 ct 2516 3 2506 5 2499 5 ct 2489 5 2480 2 2474 -3 ct 2467 -8 2462 -16 2458 -26 ct +p +2452 -53 m 2452 -53 2452 -53 2452 -110 ct 2452 -110 2452 -110 2440 -110 ct +2412 -110 2391 -106 2377 -99 ct 2363 -91 2356 -80 2356 -64 ct 2356 -52 2359 -43 2366 -37 ct +2372 -31 2382 -28 2395 -28 ct 2413 -28 2432 -36 2452 -53 ct p ef +2579 -9 m 2579 -9 2579 -9 2579 -45 ct 2610 -32 2637 -26 2660 -26 ct 2676 -26 2690 -29 2701 -36 ct +2712 -43 2717 -51 2717 -61 ct 2717 -74 2704 -84 2679 -93 ct 2679 -93 2679 -93 2636 -107 ct +2602 -118 2585 -138 2585 -165 ct 2585 -186 2593 -201 2608 -212 ct 2623 -223 2645 -229 2673 -229 ct +2694 -229 2718 -226 2746 -219 ct 2746 -219 2746 -219 2746 -186 ct 2719 -194 2695 -198 2673 -198 ct +2657 -198 2644 -196 2636 -191 ct 2628 -186 2624 -179 2624 -169 ct 2624 -158 2634 -149 2654 -142 ct +2654 -142 2654 -142 2706 -124 ct 2741 -111 2758 -91 2758 -64 ct 2758 -43 2749 -26 2732 -14 ct +2714 -1 2691 5 2661 5 ct 2636 5 2608 0 2579 -9 ct p ef +3022 0 m 3002 3 2982 5 2963 5 ct 2930 5 2907 -1 2895 -13 ct 2883 -25 2877 -47 2877 -80 ct +2877 -80 2877 -80 2877 -188 ct 2877 -188 2877 -188 2821 -188 ct 2821 -188 2821 -188 2821 -219 ct +2821 -219 2821 -219 2877 -219 ct 2877 -219 2877 -219 2877 -267 ct 2877 -267 2877 -267 2918 -267 ct +2918 -267 2918 -267 2918 -219 ct 2918 -219 2918 -219 3017 -219 ct 3017 -219 3017 -219 3017 -188 ct +3017 -188 3017 -188 2918 -188 ct 2918 -188 2918 -188 2918 -74 ct 2918 -61 2919 -53 2920 -48 ct +2922 -43 2925 -39 2931 -35 ct 2940 -29 2953 -26 2971 -26 ct 2988 -26 3005 -28 3022 -31 ct +3022 -31 3022 -31 3022 0 ct p ef +3048 31 m 3048 0 l 3303 0 l 3303 31 l 3048 31 l p ef +3399 66 m 3399 66 3399 66 3399 46 ct 3406 45 3412 41 3416 33 ct 3421 25 3423 14 3424 0 ct +3424 0 3424 0 3399 0 ct 3399 0 3399 0 3399 -61 ct 3399 -61 3399 -61 3460 -61 ct +3460 -61 3460 -61 3460 -24 ct 3460 5 3455 27 3445 42 ct 3435 57 3419 65 3399 66 ct +p +3399 -163 m 3399 -224 l 3460 -224 l 3460 -163 l 3399 -163 l p ef +pom +gr +gs +pum +10197 17290 t +pom +gr +gs +pum +10705 17290 t +0.003 0.003 1.000 c 98 0 m 9 -224 l 75 -224 l 137 -67 l 198 -224 l 247 -224 l +159 0 l 98 0 l p ef +380 5 m 346 5 318 -6 297 -27 ct 276 -49 265 -77 265 -112 ct 265 -148 276 -176 297 -197 ct +318 -218 346 -229 382 -229 ct 417 -229 445 -218 466 -197 ct 487 -176 498 -148 498 -112 ct +498 -76 487 -48 466 -27 ct 445 -6 416 5 380 5 ct p +381 -36 m 398 -36 411 -42 419 -55 ct 428 -68 432 -87 432 -112 ct 432 -138 428 -156 419 -169 ct +411 -182 398 -188 382 -188 ct 365 -188 352 -182 344 -169 ct 335 -156 331 -137 331 -112 ct +331 -87 335 -68 343 -55 ct 352 -42 364 -36 381 -36 ct p ef +630 0 m 630 -183 l 548 -183 l 548 -224 l 691 -224 l 691 0 l 630 0 l +p +630 -265 m 630 -326 l 691 -326 l 691 -265 l 630 -265 l p ef +936 0 m 936 0 936 0 938 -42 ct 938 -42 938 -42 936 -42 ct 926 -27 915 -15 903 -7 ct +892 1 879 5 865 5 ct 839 5 819 -5 803 -26 ct 788 -46 780 -73 780 -107 ct 780 -144 789 -174 806 -196 ct +823 -218 846 -229 875 -229 ct 887 -229 898 -227 908 -222 ct 918 -218 927 -211 936 -203 ct +936 -203 936 -203 938 -203 ct 938 -203 938 -203 936 -224 ct 936 -224 936 -224 936 -326 ct +936 -326 936 -326 997 -326 ct 997 -326 997 -326 997 0 ct 997 0 997 0 936 0 ct p +936 -160 m 929 -168 922 -173 915 -177 ct 908 -181 900 -183 892 -183 ct 876 -183 865 -177 857 -164 ct +850 -152 846 -133 846 -108 ct 846 -89 849 -75 856 -65 ct 863 -56 873 -51 886 -51 ct +895 -51 903 -54 912 -60 ct 920 -66 928 -75 936 -88 ct 936 -88 936 -88 936 -160 ct +p ef +pom +gr +gs +pum +11721 17290 t +pom +gr +gs +pum +11975 17290 t +228 0 m 208 3 188 5 169 5 ct 136 5 113 -1 101 -13 ct 89 -25 83 -47 83 -80 ct 83 -80 83 -80 83 -188 ct +83 -188 83 -188 27 -188 ct 27 -188 27 -188 27 -219 ct 27 -219 27 -219 83 -219 ct +83 -219 83 -219 83 -267 ct 83 -267 83 -267 124 -267 ct 124 -267 124 -267 124 -219 ct +124 -219 124 -219 223 -219 ct 223 -219 223 -219 223 -188 ct 223 -188 223 -188 124 -188 ct +124 -188 124 -188 124 -74 ct 124 -61 125 -53 126 -48 ct 128 -43 131 -39 137 -35 ct +146 -29 159 -26 177 -26 ct 194 -26 211 -28 228 -31 ct 228 -31 228 -31 228 0 ct +p ef +318 0 m 318 0 318 0 318 -224 ct 318 -224 318 -224 359 -224 ct 359 -224 359 -224 357 -182 ct +357 -182 357 -182 359 -182 ct 369 -198 381 -209 395 -217 ct 409 -225 424 -229 442 -229 ct +454 -229 468 -227 483 -224 ct 483 -224 483 -224 483 -160 ct 483 -160 483 -160 452 -160 ct +452 -160 452 -160 452 -191 ct 446 -192 440 -193 435 -193 ct 421 -193 408 -189 396 -181 ct +383 -173 371 -161 359 -145 ct 359 -145 359 -145 359 0 ct 359 0 359 0 318 0 ct p ef +680 -26 m 656 -5 631 5 607 5 ct 586 5 569 -1 556 -13 ct 543 -24 536 -39 536 -57 ct +536 -81 546 -99 567 -114 ct 588 -128 615 -135 649 -135 ct 649 -135 649 -135 674 -135 ct +674 -135 674 -135 674 -154 ct 674 -169 670 -180 663 -187 ct 655 -194 644 -198 629 -198 ct +605 -198 580 -191 555 -177 ct 555 -177 555 -177 555 -213 ct 584 -224 611 -229 637 -229 ct +666 -229 686 -223 697 -212 ct 709 -201 715 -181 715 -153 ct 715 -153 715 -153 715 -59 ct +715 -45 716 -36 719 -31 ct 722 -26 728 -24 735 -24 ct 738 -24 742 -25 748 -26 ct +748 -26 748 -26 752 -2 ct 738 3 728 5 721 5 ct 711 5 702 2 696 -3 ct 689 -8 684 -16 680 -26 ct +p +674 -53 m 674 -53 674 -53 674 -110 ct 674 -110 674 -110 662 -110 ct 634 -110 613 -106 599 -99 ct +585 -91 578 -80 578 -64 ct 578 -52 581 -43 588 -37 ct 594 -31 604 -28 617 -28 ct +635 -28 654 -36 674 -53 ct p ef +799 0 m 799 0 799 0 799 -224 ct 799 -224 799 -224 840 -224 ct 840 -224 840 -224 838 -182 ct +838 -182 838 -182 840 -182 ct 850 -198 861 -209 874 -217 ct 886 -225 901 -229 917 -229 ct +938 -229 954 -223 965 -210 ct 976 -197 981 -178 981 -153 ct 981 -153 981 -153 981 0 ct +981 0 981 0 940 0 ct 940 0 940 0 940 -142 ct 940 -159 937 -172 932 -179 ct 926 -186 917 -190 904 -190 ct +894 -190 884 -186 873 -179 ct 862 -172 851 -161 840 -146 ct 840 -146 840 -146 840 0 ct +840 0 840 0 799 0 ct p ef +1055 -9 m 1055 -9 1055 -9 1055 -45 ct 1086 -32 1113 -26 1136 -26 ct 1152 -26 1166 -29 1177 -36 ct +1188 -43 1193 -51 1193 -61 ct 1193 -74 1180 -84 1155 -93 ct 1155 -93 1155 -93 1112 -107 ct +1078 -118 1061 -138 1061 -165 ct 1061 -186 1069 -201 1084 -212 ct 1099 -223 1121 -229 1149 -229 ct +1170 -229 1194 -226 1222 -219 ct 1222 -219 1222 -219 1222 -186 ct 1195 -194 1171 -198 1149 -198 ct +1133 -198 1120 -196 1112 -191 ct 1104 -186 1100 -179 1100 -169 ct 1100 -158 1110 -149 1130 -142 ct +1130 -142 1130 -142 1182 -124 ct 1217 -111 1234 -91 1234 -64 ct 1234 -43 1225 -26 1208 -14 ct +1190 -1 1167 5 1137 5 ct 1112 5 1084 0 1055 -9 ct p ef +1362 0 m 1362 0 1362 0 1362 -188 ct 1362 -188 1362 -188 1301 -188 ct 1301 -188 1301 -188 1301 -219 ct +1301 -219 1301 -219 1362 -219 ct 1362 -219 1362 -219 1362 -243 ct 1362 -274 1369 -297 1384 -310 ct +1398 -324 1422 -331 1456 -331 ct 1478 -331 1498 -328 1518 -322 ct 1518 -322 1518 -322 1518 -289 ct +1498 -296 1478 -300 1459 -300 ct 1438 -300 1424 -296 1415 -288 ct 1407 -280 1403 -267 1403 -247 ct +1403 -247 1403 -247 1403 -219 ct 1403 -219 1403 -219 1510 -219 ct 1510 -219 1510 -219 1510 -188 ct +1510 -188 1510 -188 1403 -188 ct 1403 -188 1403 -188 1403 0 ct 1403 0 1403 0 1362 0 ct +p ef +1650 5 m 1618 5 1593 -6 1574 -27 ct 1555 -48 1546 -76 1546 -112 ct 1546 -148 1555 -177 1574 -198 ct +1593 -219 1619 -229 1652 -229 ct 1684 -229 1710 -219 1729 -198 ct 1748 -177 1757 -149 1757 -113 ct +1757 -76 1748 -47 1729 -26 ct 1710 -5 1684 5 1650 5 ct p +1651 -26 m 1672 -26 1688 -33 1698 -48 ct 1709 -62 1714 -84 1714 -113 ct 1714 -139 1708 -160 1697 -175 ct +1686 -190 1671 -198 1652 -198 ct 1632 -198 1617 -190 1606 -175 ct 1595 -160 1589 -139 1589 -112 ct +1589 -85 1594 -64 1605 -49 ct 1616 -34 1632 -26 1651 -26 ct p ef +1842 0 m 1842 0 1842 0 1842 -224 ct 1842 -224 1842 -224 1883 -224 ct 1883 -224 1883 -224 1881 -182 ct +1881 -182 1881 -182 1883 -182 ct 1893 -198 1905 -209 1919 -217 ct 1933 -225 1948 -229 1966 -229 ct +1978 -229 1992 -227 2007 -224 ct 2007 -224 2007 -224 2007 -160 ct 2007 -160 2007 -160 1976 -160 ct +1976 -160 1976 -160 1976 -191 ct 1970 -192 1964 -193 1959 -193 ct 1945 -193 1932 -189 1920 -181 ct +1907 -173 1895 -161 1883 -145 ct 1883 -145 1883 -145 1883 0 ct 1883 0 1883 0 1842 0 ct +p ef +2051 0 m 2051 0 2051 0 2051 -224 ct 2051 -224 2051 -224 2087 -224 ct 2087 -224 2087 -224 2084 -182 ct +2084 -182 2084 -182 2087 -182 ct 2095 -198 2104 -209 2113 -217 ct 2121 -225 2129 -229 2137 -229 ct +2148 -229 2156 -225 2163 -216 ct 2170 -208 2174 -196 2175 -182 ct 2175 -182 2175 -182 2178 -182 ct +2185 -198 2193 -209 2201 -217 ct 2210 -225 2219 -229 2229 -229 ct 2242 -229 2252 -224 2259 -213 ct +2266 -202 2269 -186 2269 -164 ct 2269 -164 2269 -164 2269 0 ct 2269 0 2269 0 2233 0 ct +2233 0 2233 0 2233 -162 ct 2233 -172 2232 -180 2230 -185 ct 2228 -190 2224 -193 2220 -193 ct +2214 -193 2207 -189 2200 -181 ct 2193 -173 2185 -160 2178 -144 ct 2178 -144 2178 -144 2178 0 ct +2178 0 2178 0 2142 0 ct 2142 0 2142 0 2142 -155 ct 2142 -167 2141 -177 2139 -183 ct +2136 -190 2133 -193 2129 -193 ct 2123 -193 2116 -188 2108 -179 ct 2100 -170 2093 -158 2087 -144 ct +2087 -144 2087 -144 2087 0 ct 2087 0 2087 0 2051 0 ct p ef +2512 -9 m 2484 0 2458 5 2434 5 ct 2396 5 2367 -5 2346 -25 ct 2325 -45 2315 -73 2315 -110 ct +2315 -144 2325 -173 2345 -195 ct 2365 -218 2390 -229 2421 -229 ct 2452 -229 2474 -220 2489 -201 ct +2504 -182 2511 -153 2511 -114 ct 2511 -114 2511 -114 2511 -101 ct 2511 -101 2511 -101 2357 -101 ct +2358 -76 2366 -57 2380 -45 ct 2394 -32 2413 -26 2439 -26 ct 2462 -26 2486 -31 2512 -42 ct +2512 -42 2512 -42 2512 -9 ct p +2358 -132 m 2358 -132 2358 -132 2468 -132 ct 2468 -132 2468 -132 2468 -138 ct +2468 -158 2464 -173 2455 -183 ct 2446 -193 2434 -198 2417 -198 ct 2400 -198 2387 -192 2376 -181 ct +2366 -169 2360 -153 2358 -132 ct p ef +2722 0 m 2722 0 2722 0 2724 -42 ct 2724 -42 2724 -42 2722 -42 ct 2712 -26 2701 -15 2689 -7 ct +2676 1 2663 5 2648 5 ct 2623 5 2603 -5 2588 -24 ct 2573 -44 2566 -71 2566 -105 ct +2566 -142 2575 -172 2592 -195 ct 2610 -218 2632 -229 2660 -229 ct 2672 -229 2684 -226 2694 -221 ct +2704 -216 2714 -209 2722 -198 ct 2722 -198 2722 -198 2724 -198 ct 2724 -198 2724 -198 2722 -229 ct +2722 -229 2722 -229 2722 -326 ct 2722 -326 2722 -326 2763 -326 ct 2763 -326 2763 -326 2763 0 ct +2763 0 2763 0 2722 0 ct p +2722 -168 m 2712 -178 2703 -185 2694 -190 ct 2684 -195 2675 -198 2666 -198 ct +2648 -198 2634 -190 2624 -175 ct 2614 -159 2609 -137 2609 -109 ct 2609 -83 2613 -63 2621 -50 ct +2629 -38 2640 -31 2656 -31 ct 2668 -31 2679 -35 2690 -42 ct 2701 -49 2712 -59 2722 -73 ct +2722 -73 2722 -73 2722 -168 ct p ef +3220 -26 m 3196 -5 3171 5 3147 5 ct 3126 5 3109 -1 3096 -13 ct 3083 -24 3076 -39 3076 -57 ct +3076 -81 3086 -99 3107 -114 ct 3128 -128 3155 -135 3189 -135 ct 3189 -135 3189 -135 3214 -135 ct +3214 -135 3214 -135 3214 -154 ct 3214 -169 3210 -180 3203 -187 ct 3195 -194 3184 -198 3169 -198 ct +3145 -198 3120 -191 3095 -177 ct 3095 -177 3095 -177 3095 -213 ct 3124 -224 3151 -229 3177 -229 ct +3206 -229 3226 -223 3237 -212 ct 3249 -201 3255 -181 3255 -153 ct 3255 -153 3255 -153 3255 -59 ct +3255 -45 3256 -36 3259 -31 ct 3262 -26 3268 -24 3275 -24 ct 3278 -24 3282 -25 3288 -26 ct +3288 -26 3288 -26 3292 -2 ct 3278 3 3268 5 3261 5 ct 3251 5 3242 2 3236 -3 ct 3229 -8 3224 -16 3220 -26 ct +p +3214 -53 m 3214 -53 3214 -53 3214 -110 ct 3214 -110 3214 -110 3202 -110 ct +3174 -110 3153 -106 3139 -99 ct 3125 -91 3118 -80 3118 -64 ct 3118 -52 3121 -43 3128 -37 ct +3134 -31 3144 -28 3157 -28 ct 3175 -28 3194 -36 3214 -53 ct p ef +3484 0 m 3484 0 3484 0 3486 -42 ct 3486 -42 3486 -42 3484 -42 ct 3474 -26 3463 -15 3451 -7 ct +3438 1 3425 5 3410 5 ct 3385 5 3365 -5 3350 -24 ct 3335 -44 3328 -71 3328 -105 ct +3328 -142 3337 -172 3354 -195 ct 3372 -218 3394 -229 3422 -229 ct 3434 -229 3446 -226 3456 -221 ct +3466 -216 3476 -209 3484 -198 ct 3484 -198 3484 -198 3486 -198 ct 3486 -198 3486 -198 3484 -229 ct +3484 -229 3484 -229 3484 -326 ct 3484 -326 3484 -326 3525 -326 ct 3525 -326 3525 -326 3525 0 ct +3525 0 3525 0 3484 0 ct p +3484 -168 m 3474 -178 3465 -185 3456 -190 ct 3446 -195 3437 -198 3428 -198 ct +3410 -198 3396 -190 3386 -175 ct 3376 -159 3371 -137 3371 -109 ct 3371 -83 3375 -63 3383 -50 ct +3391 -38 3402 -31 3418 -31 ct 3430 -31 3441 -35 3452 -42 ct 3463 -49 3474 -59 3484 -73 ct +3484 -73 3484 -73 3484 -168 ct p ef +3662 0 m 3570 -224 l 3612 -224 l 3686 -45 l 3762 -224 l 3798 -224 l +3703 0 l 3662 0 l p ef +3927 0 m 3927 -193 l 3845 -193 l 3845 -224 l 3968 -224 l 3968 0 l +3927 0 l p +3922 -275 m 3922 -326 l 3973 -326 l 3973 -275 l 3922 -275 l p ef +4292 -7 m 4268 1 4244 5 4220 5 ct 4181 5 4151 -5 4130 -26 ct 4109 -46 4098 -75 4098 -112 ct +4098 -149 4108 -177 4129 -198 ct 4150 -219 4179 -229 4216 -229 ct 4240 -229 4264 -225 4288 -218 ct +4288 -218 4288 -218 4288 -184 ct 4261 -193 4239 -198 4220 -198 ct 4196 -198 4176 -190 4162 -175 ct +4148 -160 4141 -139 4141 -112 ct 4141 -85 4148 -64 4163 -49 ct 4178 -34 4199 -26 4225 -26 ct +4245 -26 4267 -31 4292 -40 ct 4292 -40 4292 -40 4292 -7 ct p ef +4544 -9 m 4516 0 4490 5 4466 5 ct 4428 5 4399 -5 4378 -25 ct 4357 -45 4347 -73 4347 -110 ct +4347 -144 4357 -173 4377 -195 ct 4397 -218 4422 -229 4453 -229 ct 4484 -229 4506 -220 4521 -201 ct +4536 -182 4543 -153 4543 -114 ct 4543 -114 4543 -114 4543 -101 ct 4543 -101 4543 -101 4389 -101 ct +4390 -76 4398 -57 4412 -45 ct 4426 -32 4445 -26 4471 -26 ct 4494 -26 4518 -31 4544 -42 ct +4544 -42 4544 -42 4544 -9 ct p +4390 -132 m 4390 -132 4390 -132 4500 -132 ct 4500 -132 4500 -132 4500 -138 ct +4500 -158 4496 -173 4487 -183 ct 4478 -193 4466 -198 4449 -198 ct 4432 -198 4419 -192 4408 -181 ct +4398 -169 4392 -153 4390 -132 ct p ef +pom +gr +gs +pum +16547 17290 t +466 -326 m 466 -326 466 -326 466 -295 ct 466 -295 466 -295 450 -295 ct 429 -295 415 -293 407 -287 ct +398 -282 394 -274 394 -261 ct 394 -257 395 -251 396 -242 ct 396 -242 396 -242 400 -214 ct +401 -204 402 -196 402 -190 ct 402 -175 399 -163 392 -153 ct 385 -144 375 -137 361 -132 ct +375 -128 385 -121 392 -111 ct 399 -102 402 -90 402 -75 ct 402 -68 401 -61 400 -51 ct +400 -51 400 -51 396 -23 ct 395 -14 394 -8 394 -4 ct 394 9 398 17 407 22 ct 415 27 429 30 450 30 ct +450 30 450 30 466 30 ct 466 30 466 30 466 61 ct 466 61 466 61 443 61 ct 414 61 392 56 378 46 ct +363 36 356 21 356 2 ct 356 -7 357 -16 359 -26 ct 359 -26 359 -26 366 -63 ct 367 -68 367 -74 367 -79 ct +367 -92 363 -101 355 -108 ct 348 -114 336 -117 321 -117 ct 321 -117 321 -117 302 -117 ct +302 -117 302 -117 302 -148 ct 302 -148 302 -148 321 -148 ct 336 -148 348 -151 355 -157 ct +363 -164 367 -173 367 -186 ct 367 -191 367 -197 366 -202 ct 366 -202 366 -202 359 -239 ct +357 -249 356 -258 356 -267 ct 356 -286 363 -301 378 -311 ct 392 -321 414 -326 443 -326 ct +443 -326 443 -326 466 -326 ct p ef +pom +gr +gs +pum +10197 17781 t +pom +gr +gs +pum +11213 17781 t +0.003 0.503 0.003 c 239 -326 m 65 61 l 15 61 l 189 -326 l 239 -326 l +p ef +493 -326 m 319 61 l 269 61 l 443 -326 l 493 -326 l p ef +791 0 m 791 0 791 0 791 -224 ct 791 -224 791 -224 852 -224 ct 852 -224 852 -224 851 -202 ct +851 -202 851 -202 850 -181 ct 850 -181 850 -181 852 -181 ct 859 -197 868 -209 880 -217 ct +892 -225 906 -229 924 -229 ct 946 -229 962 -223 973 -210 ct 984 -197 990 -178 990 -153 ct +990 -153 990 -153 990 0 ct 990 0 990 0 929 0 ct 929 0 929 0 929 -139 ct 929 -150 927 -159 923 -165 ct +918 -170 912 -173 903 -173 ct 894 -173 885 -170 876 -165 ct 868 -159 859 -151 852 -139 ct +852 -139 852 -139 852 0 ct 852 0 852 0 791 0 ct p ef +1252 -95 m 1252 -95 1252 -95 1100 -95 ct 1103 -77 1111 -63 1123 -54 ct 1135 -45 1151 -41 1172 -41 ct +1196 -41 1223 -46 1252 -56 ct 1252 -56 1252 -56 1252 -9 ct 1217 0 1186 5 1160 5 ct +1122 5 1091 -6 1068 -27 ct 1045 -48 1034 -76 1034 -111 ct 1034 -147 1045 -175 1066 -197 ct +1088 -218 1116 -229 1151 -229 ct 1183 -229 1207 -219 1225 -199 ct 1243 -180 1252 -152 1252 -118 ct +1252 -118 1252 -118 1252 -95 ct p +1099 -136 m 1099 -136 1099 -136 1193 -136 ct 1193 -153 1189 -166 1182 -175 ct +1174 -184 1163 -188 1148 -188 ct 1134 -188 1122 -184 1114 -175 ct 1106 -166 1101 -153 1099 -136 ct +p ef +1506 -95 m 1506 -95 1506 -95 1354 -95 ct 1357 -77 1365 -63 1377 -54 ct 1389 -45 1405 -41 1426 -41 ct +1450 -41 1477 -46 1506 -56 ct 1506 -56 1506 -56 1506 -9 ct 1471 0 1440 5 1414 5 ct +1376 5 1345 -6 1322 -27 ct 1299 -48 1288 -76 1288 -111 ct 1288 -147 1299 -175 1320 -197 ct +1342 -218 1370 -229 1405 -229 ct 1437 -229 1461 -219 1479 -199 ct 1497 -180 1506 -152 1506 -118 ct +1506 -118 1506 -118 1506 -95 ct p +1353 -136 m 1353 -136 1353 -136 1447 -136 ct 1447 -153 1443 -166 1436 -175 ct +1428 -184 1417 -188 1402 -188 ct 1388 -188 1376 -184 1368 -175 ct 1360 -166 1355 -153 1353 -136 ct +p ef +1698 0 m 1698 0 1698 0 1700 -42 ct 1700 -42 1700 -42 1698 -42 ct 1688 -27 1677 -15 1665 -7 ct +1654 1 1641 5 1627 5 ct 1601 5 1581 -5 1565 -26 ct 1550 -46 1542 -73 1542 -107 ct +1542 -144 1551 -174 1568 -196 ct 1585 -218 1608 -229 1637 -229 ct 1649 -229 1660 -227 1670 -222 ct +1680 -218 1689 -211 1698 -203 ct 1698 -203 1698 -203 1700 -203 ct 1700 -203 1700 -203 1698 -224 ct +1698 -224 1698 -224 1698 -326 ct 1698 -326 1698 -326 1759 -326 ct 1759 -326 1759 -326 1759 0 ct +1759 0 1759 0 1698 0 ct p +1698 -160 m 1691 -168 1684 -173 1677 -177 ct 1670 -181 1662 -183 1654 -183 ct +1638 -183 1627 -177 1619 -164 ct 1612 -152 1608 -133 1608 -108 ct 1608 -89 1611 -75 1618 -65 ct +1625 -56 1635 -51 1648 -51 ct 1657 -51 1665 -54 1674 -60 ct 1682 -66 1690 -75 1698 -88 ct +1698 -88 1698 -88 1698 -160 ct p ef +1811 -8 m 1811 -8 1811 -8 1811 -54 ct 1845 -42 1873 -36 1893 -36 ct 1908 -36 1919 -38 1927 -42 ct +1934 -46 1938 -52 1938 -60 ct 1938 -64 1936 -68 1932 -72 ct 1929 -75 1923 -79 1916 -82 ct +1916 -82 1916 -82 1868 -101 ct 1849 -109 1835 -118 1826 -127 ct 1817 -137 1812 -148 1812 -161 ct +1812 -182 1822 -199 1841 -211 ct 1860 -223 1887 -229 1921 -229 ct 1941 -229 1964 -226 1990 -221 ct +1990 -221 1990 -221 1990 -174 ct 1962 -183 1938 -188 1919 -188 ct 1904 -188 1894 -186 1887 -183 ct +1880 -180 1876 -175 1876 -169 ct 1876 -165 1879 -162 1884 -158 ct 1889 -154 1896 -150 1906 -146 ct +1906 -146 1906 -146 1959 -124 ct 1975 -118 1987 -110 1994 -100 ct 2002 -91 2006 -79 2006 -66 ct +2006 -45 1997 -28 1978 -15 ct 1959 -2 1935 5 1905 5 ct 1879 5 1847 1 1811 -8 ct +p ef +2383 0 m 2383 -265 l 2291 -265 l 2291 -306 l 2536 -306 l 2536 -265 l +2444 -265 l 2444 0 l 2383 0 l p ef +2693 -24 m 2686 -14 2677 -7 2667 -2 ct 2657 3 2646 5 2633 5 ct 2611 5 2593 -2 2579 -15 ct +2565 -28 2558 -45 2558 -65 ct 2558 -91 2568 -111 2587 -124 ct 2607 -137 2636 -143 2675 -143 ct +2675 -143 2675 -143 2699 -143 ct 2699 -143 2699 -143 2699 -154 ct 2699 -165 2695 -174 2687 -179 ct +2679 -185 2667 -188 2651 -188 ct 2629 -188 2604 -182 2577 -169 ct 2577 -169 2577 -169 2577 -214 ct +2605 -224 2633 -229 2662 -229 ct 2694 -229 2718 -223 2734 -211 ct 2744 -203 2751 -194 2755 -185 ct +2758 -175 2760 -160 2760 -140 ct 2760 -140 2760 -140 2760 -64 ct 2760 -49 2765 -41 2774 -41 ct +2776 -41 2778 -41 2781 -42 ct 2781 -42 2781 -42 2781 -2 ct 2769 3 2757 5 2747 5 ct +2736 5 2726 3 2718 -2 ct 2710 -7 2704 -14 2699 -24 ct 2699 -24 2699 -24 2693 -24 ct +p +2699 -65 m 2699 -65 2699 -65 2699 -102 ct 2699 -102 2699 -102 2677 -102 ct +2658 -102 2643 -99 2634 -94 ct 2624 -88 2619 -80 2619 -69 ct 2619 -61 2622 -54 2628 -49 ct +2634 -44 2641 -41 2650 -41 ct 2665 -41 2682 -49 2699 -65 ct p ef +2840 0 m 2840 0 2840 0 2840 -224 ct 2840 -224 2840 -224 2901 -224 ct 2901 -224 2901 -224 2899 -181 ct +2899 -181 2899 -181 2901 -181 ct 2911 -197 2923 -209 2937 -217 ct 2950 -225 2966 -229 2984 -229 ct +2995 -229 3010 -227 3026 -224 ct 3026 -224 3026 -224 3026 -149 ct 3026 -149 3026 -149 2985 -149 ct +2985 -149 2985 -149 2985 -173 ct 2980 -174 2977 -174 2974 -174 ct 2959 -174 2946 -170 2933 -163 ct +2921 -156 2910 -145 2901 -130 ct 2901 -130 2901 -130 2901 0 ct 2901 0 2901 0 2840 0 ct +p ef +3088 69 m 3088 69 3088 69 3094 25 ct 3126 38 3152 44 3172 44 ct 3190 44 3203 39 3211 30 ct +3220 21 3224 7 3224 -11 ct 3224 -11 3224 -11 3225 -53 ct 3225 -53 3225 -53 3223 -53 ct +3215 -35 3205 -22 3194 -13 ct 3182 -4 3168 0 3152 0 ct 3126 0 3105 -10 3090 -31 ct +3074 -51 3066 -78 3066 -111 ct 3066 -147 3075 -175 3092 -197 ct 3110 -218 3133 -229 3162 -229 ct +3174 -229 3184 -227 3194 -223 ct 3204 -218 3213 -212 3222 -204 ct 3222 -204 3222 -204 3227 -204 ct +3227 -204 3227 -204 3232 -224 ct 3232 -224 3232 -224 3283 -224 ct 3283 -224 3283 -224 3283 -27 ct +3283 10 3274 38 3256 58 ct 3239 77 3213 87 3180 87 ct 3154 87 3123 81 3088 69 ct +p +3222 -95 m 3222 -95 3222 -95 3222 -163 ct 3214 -169 3206 -174 3198 -178 ct +3191 -181 3184 -183 3177 -183 ct 3162 -183 3151 -177 3143 -166 ct 3136 -155 3132 -138 3132 -116 ct +3132 -97 3135 -83 3142 -73 ct 3149 -64 3158 -59 3172 -59 ct 3181 -59 3190 -62 3199 -68 ct +3207 -74 3215 -83 3222 -95 ct p ef +3538 -95 m 3538 -95 3538 -95 3386 -95 ct 3389 -77 3397 -63 3409 -54 ct 3421 -45 3437 -41 3458 -41 ct +3482 -41 3509 -46 3538 -56 ct 3538 -56 3538 -56 3538 -9 ct 3503 0 3472 5 3446 5 ct +3408 5 3377 -6 3354 -27 ct 3331 -48 3320 -76 3320 -111 ct 3320 -147 3331 -175 3352 -197 ct +3374 -218 3402 -229 3437 -229 ct 3469 -229 3493 -219 3511 -199 ct 3529 -180 3538 -152 3538 -118 ct +3538 -118 3538 -118 3538 -95 ct p +3385 -136 m 3385 -136 3385 -136 3479 -136 ct 3479 -153 3475 -166 3468 -175 ct +3460 -184 3449 -188 3434 -188 ct 3420 -188 3408 -184 3400 -175 ct 3392 -166 3387 -153 3385 -136 ct +p ef +3784 -6 m 3760 1 3738 5 3720 5 ct 3691 5 3670 -1 3656 -14 ct 3642 -26 3635 -45 3635 -70 ct +3635 -70 3635 -70 3635 -178 ct 3635 -178 3635 -178 3587 -178 ct 3587 -178 3587 -178 3587 -219 ct +3587 -219 3587 -219 3635 -219 ct 3635 -219 3635 -219 3635 -285 ct 3635 -285 3635 -285 3696 -285 ct +3696 -285 3696 -285 3696 -219 ct 3696 -219 3696 -219 3779 -219 ct 3779 -219 3779 -219 3779 -178 ct +3779 -178 3779 -178 3696 -178 ct 3696 -178 3696 -178 3696 -84 ct 3696 -68 3699 -57 3705 -51 ct +3711 -44 3721 -41 3735 -41 ct 3752 -41 3768 -44 3784 -51 ct 3784 -51 3784 -51 3784 -6 ct +p ef +3902 61 m 3902 61 3902 61 3902 33 ct 3911 32 3918 30 3923 26 ct 3928 22 3930 17 3930 10 ct +3930 10 3930 10 3930 0 ct 3930 0 3930 0 3902 0 ct 3902 0 3902 0 3902 -71 ct 3902 -71 3902 -71 3973 -71 ct +3973 -71 3973 -71 3973 -14 ct 3973 14 3968 33 3957 44 ct 3947 55 3928 61 3902 61 ct +p ef +4546 -6 m 4522 1 4500 5 4482 5 ct 4453 5 4432 -1 4418 -14 ct 4404 -26 4397 -45 4397 -70 ct +4397 -70 4397 -70 4397 -178 ct 4397 -178 4397 -178 4349 -178 ct 4349 -178 4349 -178 4349 -219 ct +4349 -219 4349 -219 4397 -219 ct 4397 -219 4397 -219 4397 -285 ct 4397 -285 4397 -285 4458 -285 ct +4458 -285 4458 -285 4458 -219 ct 4458 -219 4458 -219 4541 -219 ct 4541 -219 4541 -219 4541 -178 ct +4541 -178 4541 -178 4458 -178 ct 4458 -178 4458 -178 4458 -84 ct 4458 -68 4461 -57 4467 -51 ct +4473 -44 4483 -41 4497 -41 ct 4514 -41 4530 -44 4546 -51 ct 4546 -51 4546 -51 4546 -6 ct +p ef +4601 0 m 4601 0 4601 0 4601 -326 ct 4601 -326 4601 -326 4662 -326 ct 4662 -326 4662 -326 4662 -224 ct +4662 -224 4662 -224 4660 -181 ct 4660 -181 4660 -181 4662 -181 ct 4669 -197 4678 -209 4690 -217 ct +4702 -225 4716 -229 4734 -229 ct 4756 -229 4772 -223 4783 -210 ct 4794 -197 4800 -178 4800 -153 ct +4800 -153 4800 -153 4800 0 ct 4800 0 4800 0 4739 0 ct 4739 0 4739 0 4739 -139 ct +4739 -150 4737 -159 4733 -165 ct 4728 -170 4722 -173 4713 -173 ct 4704 -173 4695 -170 4686 -165 ct +4678 -159 4669 -151 4662 -139 ct 4662 -139 4662 -139 4662 0 ct 4662 0 4662 0 4601 0 ct +p ef +5052 -224 m 5052 -224 5052 -224 5052 0 ct 5052 0 5052 0 4991 0 ct 4991 0 4991 0 4992 -22 ct +4992 -22 4992 -22 4994 -43 ct 4994 -43 4994 -43 4991 -43 ct 4985 -27 4976 -15 4964 -7 ct +4952 1 4937 5 4920 5 ct 4898 5 4881 -1 4870 -14 ct 4859 -27 4853 -46 4853 -71 ct +4853 -71 4853 -71 4853 -224 ct 4853 -224 4853 -224 4914 -224 ct 4914 -224 4914 -224 4914 -85 ct +4914 -73 4916 -65 4920 -59 ct 4925 -54 4931 -51 4940 -51 ct 4949 -51 4958 -54 4967 -59 ct +4975 -65 4983 -73 4991 -85 ct 4991 -85 4991 -85 4991 -224 ct 4991 -224 4991 -224 5052 -224 ct +p ef +5113 -8 m 5113 -8 5113 -8 5113 -54 ct 5147 -42 5175 -36 5195 -36 ct 5210 -36 5221 -38 5229 -42 ct +5236 -46 5240 -52 5240 -60 ct 5240 -64 5238 -68 5234 -72 ct 5231 -75 5225 -79 5218 -82 ct +5218 -82 5218 -82 5170 -101 ct 5151 -109 5137 -118 5128 -127 ct 5119 -137 5114 -148 5114 -161 ct +5114 -182 5124 -199 5143 -211 ct 5162 -223 5189 -229 5223 -229 ct 5243 -229 5266 -226 5292 -221 ct +5292 -221 5292 -221 5292 -174 ct 5264 -183 5240 -188 5221 -188 ct 5206 -188 5196 -186 5189 -183 ct +5182 -180 5178 -175 5178 -169 ct 5178 -165 5181 -162 5186 -158 ct 5191 -154 5198 -150 5208 -146 ct +5208 -146 5208 -146 5261 -124 ct 5277 -118 5289 -110 5296 -100 ct 5304 -91 5308 -79 5308 -66 ct +5308 -45 5299 -28 5280 -15 ct 5261 -2 5237 5 5207 5 ct 5181 5 5149 1 5113 -8 ct +p ef +5685 0 m 5685 -265 l 5593 -265 l 5593 -306 l 5838 -306 l 5838 -265 l +5746 -265 l 5746 0 l 5685 0 l p ef +5995 -24 m 5988 -14 5979 -7 5969 -2 ct 5959 3 5948 5 5935 5 ct 5913 5 5895 -2 5881 -15 ct +5867 -28 5860 -45 5860 -65 ct 5860 -91 5870 -111 5889 -124 ct 5909 -137 5938 -143 5977 -143 ct +5977 -143 5977 -143 6001 -143 ct 6001 -143 6001 -143 6001 -154 ct 6001 -165 5997 -174 5989 -179 ct +5981 -185 5969 -188 5953 -188 ct 5931 -188 5906 -182 5879 -169 ct 5879 -169 5879 -169 5879 -214 ct +5907 -224 5935 -229 5964 -229 ct 5996 -229 6020 -223 6036 -211 ct 6046 -203 6053 -194 6057 -185 ct +6060 -175 6062 -160 6062 -140 ct 6062 -140 6062 -140 6062 -64 ct 6062 -49 6067 -41 6076 -41 ct +6078 -41 6080 -41 6083 -42 ct 6083 -42 6083 -42 6083 -2 ct 6071 3 6059 5 6049 5 ct +6038 5 6028 3 6020 -2 ct 6012 -7 6006 -14 6001 -24 ct 6001 -24 6001 -24 5995 -24 ct +p +6001 -65 m 6001 -65 6001 -65 6001 -102 ct 6001 -102 6001 -102 5979 -102 ct +5960 -102 5945 -99 5936 -94 ct 5926 -88 5921 -80 5921 -69 ct 5921 -61 5924 -54 5930 -49 ct +5936 -44 5943 -41 5952 -41 ct 5967 -41 5984 -49 6001 -65 ct p ef +6142 0 m 6142 0 6142 0 6142 -224 ct 6142 -224 6142 -224 6203 -224 ct 6203 -224 6203 -224 6201 -181 ct +6201 -181 6201 -181 6203 -181 ct 6213 -197 6225 -209 6239 -217 ct 6252 -225 6268 -229 6286 -229 ct +6297 -229 6312 -227 6328 -224 ct 6328 -224 6328 -224 6328 -149 ct 6328 -149 6328 -149 6287 -149 ct +6287 -149 6287 -149 6287 -173 ct 6282 -174 6279 -174 6276 -174 ct 6261 -174 6248 -170 6235 -163 ct +6223 -156 6212 -145 6203 -130 ct 6203 -130 6203 -130 6203 0 ct 6203 0 6203 0 6142 0 ct +p ef +6390 69 m 6390 69 6390 69 6396 25 ct 6428 38 6454 44 6474 44 ct 6492 44 6505 39 6513 30 ct +6522 21 6526 7 6526 -11 ct 6526 -11 6526 -11 6527 -53 ct 6527 -53 6527 -53 6525 -53 ct +6517 -35 6507 -22 6496 -13 ct 6484 -4 6470 0 6454 0 ct 6428 0 6407 -10 6392 -31 ct +6376 -51 6368 -78 6368 -111 ct 6368 -147 6377 -175 6394 -197 ct 6412 -218 6435 -229 6464 -229 ct +6476 -229 6486 -227 6496 -223 ct 6506 -218 6515 -212 6524 -204 ct 6524 -204 6524 -204 6529 -204 ct +6529 -204 6529 -204 6534 -224 ct 6534 -224 6534 -224 6585 -224 ct 6585 -224 6585 -224 6585 -27 ct +6585 10 6576 38 6558 58 ct 6541 77 6515 87 6482 87 ct 6456 87 6425 81 6390 69 ct +p +6524 -95 m 6524 -95 6524 -95 6524 -163 ct 6516 -169 6508 -174 6500 -178 ct +6493 -181 6486 -183 6479 -183 ct 6464 -183 6453 -177 6445 -166 ct 6438 -155 6434 -138 6434 -116 ct +6434 -97 6437 -83 6444 -73 ct 6451 -64 6460 -59 6474 -59 ct 6483 -59 6492 -62 6501 -68 ct +6509 -74 6517 -83 6524 -95 ct p ef +6840 -95 m 6840 -95 6840 -95 6688 -95 ct 6691 -77 6699 -63 6711 -54 ct 6723 -45 6739 -41 6760 -41 ct +6784 -41 6811 -46 6840 -56 ct 6840 -56 6840 -56 6840 -9 ct 6805 0 6774 5 6748 5 ct +6710 5 6679 -6 6656 -27 ct 6633 -48 6622 -76 6622 -111 ct 6622 -147 6633 -175 6654 -197 ct +6676 -218 6704 -229 6739 -229 ct 6771 -229 6795 -219 6813 -199 ct 6831 -180 6840 -152 6840 -118 ct +6840 -118 6840 -118 6840 -95 ct p +6687 -136 m 6687 -136 6687 -136 6781 -136 ct 6781 -153 6777 -166 6770 -175 ct +6762 -184 6751 -188 6736 -188 ct 6722 -188 6710 -184 6702 -175 ct 6694 -166 6689 -153 6687 -136 ct +p ef +7086 -6 m 7062 1 7040 5 7022 5 ct 6993 5 6972 -1 6958 -14 ct 6944 -26 6937 -45 6937 -70 ct +6937 -70 6937 -70 6937 -178 ct 6937 -178 6937 -178 6889 -178 ct 6889 -178 6889 -178 6889 -219 ct +6889 -219 6889 -219 6937 -219 ct 6937 -219 6937 -219 6937 -285 ct 6937 -285 6937 -285 6998 -285 ct +6998 -285 6998 -285 6998 -219 ct 6998 -219 6998 -219 7081 -219 ct 7081 -219 7081 -219 7081 -178 ct +7081 -178 7081 -178 6998 -178 ct 6998 -178 6998 -178 6998 -84 ct 6998 -68 7001 -57 7007 -51 ct +7013 -44 7023 -41 7037 -41 ct 7054 -41 7070 -44 7086 -51 ct 7086 -51 7086 -51 7086 -6 ct +p ef +7204 0 m 7204 -71 l 7275 -71 l 7275 0 l 7204 0 l p ef +7395 0 m 7395 0 7395 0 7395 -326 ct 7395 -326 7395 -326 7456 -326 ct 7456 -326 7456 -326 7456 -224 ct +7456 -224 7456 -224 7454 -181 ct 7454 -181 7454 -181 7456 -181 ct 7463 -197 7472 -209 7484 -217 ct +7496 -225 7510 -229 7528 -229 ct 7550 -229 7566 -223 7577 -210 ct 7588 -197 7594 -178 7594 -153 ct +7594 -153 7594 -153 7594 0 ct 7594 0 7594 0 7533 0 ct 7533 0 7533 0 7533 -139 ct +7533 -150 7531 -159 7527 -165 ct 7522 -170 7516 -173 7507 -173 ct 7498 -173 7489 -170 7480 -165 ct +7472 -159 7463 -151 7456 -139 ct 7456 -139 7456 -139 7456 0 ct 7456 0 7456 0 7395 0 ct +p ef +pom +gr +gs +pum +10197 18272 t +pom +gr +gs +pum +10705 18272 t +43 -326 m 43 -326 43 -326 43 -295 ct 43 -295 43 -295 59 -295 ct 80 -295 94 -293 102 -287 ct +111 -282 115 -274 115 -261 ct 115 -257 114 -251 113 -242 ct 113 -242 113 -242 109 -214 ct +108 -204 107 -196 107 -190 ct 107 -175 110 -163 117 -153 ct 124 -144 134 -137 148 -132 ct +134 -128 124 -121 117 -111 ct 110 -102 107 -90 107 -75 ct 107 -68 108 -61 109 -51 ct +109 -51 109 -51 113 -23 ct 114 -14 115 -8 115 -4 ct 115 9 111 17 102 22 ct 94 27 80 30 59 30 ct +59 30 59 30 43 30 ct 43 30 43 30 43 61 ct 43 61 43 61 66 61 ct 95 61 117 56 131 46 ct +146 36 153 21 153 2 ct 153 -7 152 -16 150 -26 ct 150 -26 150 -26 143 -63 ct 142 -68 142 -74 142 -79 ct +142 -92 146 -101 154 -108 ct 161 -114 173 -117 188 -117 ct 188 -117 188 -117 207 -117 ct +207 -117 207 -117 207 -148 ct 207 -148 207 -148 188 -148 ct 173 -148 161 -151 154 -157 ct +146 -164 142 -173 142 -186 ct 142 -191 142 -197 143 -202 ct 143 -202 143 -202 150 -239 ct +152 -249 153 -258 153 -267 ct 153 -286 146 -301 131 -311 ct 117 -321 95 -326 66 -326 ct +66 -326 66 -326 43 -326 ct p ef +pom +gr +gs +pum +10197 18966 t +43 -326 m 43 -326 43 -326 43 -295 ct 43 -295 43 -295 59 -295 ct 80 -295 94 -293 102 -287 ct +111 -282 115 -274 115 -261 ct 115 -257 114 -251 113 -242 ct 113 -242 113 -242 109 -214 ct +108 -204 107 -196 107 -190 ct 107 -175 110 -163 117 -153 ct 124 -144 134 -137 148 -132 ct +134 -128 124 -121 117 -111 ct 110 -102 107 -90 107 -75 ct 107 -68 108 -61 109 -51 ct +109 -51 109 -51 113 -23 ct 114 -14 115 -8 115 -4 ct 115 9 111 17 102 22 ct 94 27 80 30 59 30 ct +59 30 59 30 43 30 ct 43 30 43 30 43 61 ct 43 61 43 61 66 61 ct 95 61 117 56 131 46 ct +146 36 153 21 153 2 ct 153 -7 152 -16 150 -26 ct 150 -26 150 -26 143 -63 ct 142 -68 142 -74 142 -79 ct +142 -92 146 -101 154 -108 ct 161 -114 173 -117 188 -117 ct 188 -117 188 -117 207 -117 ct +207 -117 207 -117 207 -148 ct 207 -148 207 -148 188 -148 ct 173 -148 161 -151 154 -157 ct +146 -164 142 -173 142 -186 ct 142 -191 142 -197 143 -202 ct 143 -202 143 -202 150 -239 ct +152 -249 153 -258 153 -267 ct 153 -286 146 -301 131 -311 ct 117 -321 95 -326 66 -326 ct +66 -326 66 -326 43 -326 ct p ef +351 66 m 351 66 351 66 351 46 ct 358 45 364 41 368 33 ct 373 25 375 14 376 0 ct +376 0 376 0 351 0 ct 351 0 351 0 351 -61 ct 351 -61 351 -61 412 -61 ct 412 -61 412 -61 412 -24 ct +412 5 407 27 397 42 ct 387 57 371 65 351 66 ct p +351 -163 m 351 -224 l 412 -224 l 412 -163 l 351 -163 l p ef +pom +gr +gs +pum +10705 18966 t +pom +gr +gr +0.503 0.503 0.503 c 11787 19910 m 10406 19910 l 10406 19235 l 13169 19235 l +13169 19910 l 11787 19910 l p ef +11787 19910 m 10406 19910 l 10406 19235 l 13169 19235 l 13169 19910 l +11787 19910 l pc +0.753 0.753 0.753 c 11687 19810 m 10306 19810 l 10306 19135 l 13069 19135 l +13069 19810 l 11687 19810 l p ef +0.003 0.003 0.003 c 11687 19810 m 10306 19810 l 10306 19135 l 13069 19135 l +13069 19810 l 11687 19810 l pc +gs +gs +pum +10541 19622 t +1.000 1.000 1.000 c 29 -291 m 29 -291 29 -291 154 -291 ct 189 -291 216 -283 235 -267 ct +254 -251 264 -229 264 -200 ct 264 -171 254 -148 235 -131 ct 215 -115 188 -107 153 -107 ct +153 -107 153 -107 88 -107 ct 88 -107 88 -107 88 0 ct 88 0 88 0 29 0 ct 29 0 29 0 29 -291 ct +p +88 -156 m 88 -156 88 -156 150 -156 ct 168 -156 181 -160 191 -168 ct 200 -176 205 -186 205 -200 ct +205 -212 200 -223 190 -230 ct 181 -238 167 -242 150 -242 ct 150 -242 150 -242 88 -242 ct +88 -242 88 -242 88 -156 ct p ef +451 -211 m 451 -211 451 -211 441 -159 ct 435 -163 429 -165 422 -165 ct 415 -165 408 -163 402 -158 ct +395 -153 388 -145 381 -134 ct 374 -123 371 -116 371 -114 ct 371 -114 371 -114 371 0 ct +371 0 371 0 314 0 ct 314 0 314 0 314 -215 ct 314 -215 314 -215 371 -215 ct 371 -215 371 -215 371 -172 ct +379 -190 387 -202 395 -209 ct 403 -216 413 -220 424 -220 ct 435 -220 444 -217 451 -211 ct +p ef +578 -220 m 612 -220 639 -210 660 -190 ct 681 -170 691 -143 691 -108 ct 691 -72 681 -45 660 -25 ct +639 -5 612 5 578 5 ct 544 5 517 -5 496 -25 ct 475 -45 465 -72 465 -108 ct 465 -143 475 -170 496 -190 ct +517 -210 544 -220 578 -220 ct p +578 -44 m 594 -44 607 -50 617 -61 ct 627 -73 632 -88 632 -108 ct 632 -127 627 -142 617 -154 ct +608 -165 594 -171 578 -171 ct 561 -171 547 -165 538 -154 ct 529 -143 524 -128 524 -108 ct +524 -88 529 -72 538 -61 ct 547 -50 561 -44 578 -44 ct p ef +794 -192 m 801 -201 810 -207 822 -212 ct 834 -217 846 -220 858 -220 ct 885 -220 906 -210 923 -190 ct +940 -171 949 -144 949 -112 ct 949 -76 940 -47 923 -26 ct 906 -5 885 5 858 5 ct +831 5 810 -4 794 -21 ct 794 -21 794 -21 794 0 ct 794 0 794 0 737 0 ct 737 0 737 0 737 -307 ct +737 -307 737 -307 794 -307 ct 794 -307 794 -307 794 -192 ct p +794 -69 m 807 -52 823 -44 843 -44 ct 857 -44 868 -50 877 -61 ct 886 -73 890 -89 890 -108 ct +890 -129 886 -144 877 -155 ct 868 -166 856 -171 843 -171 ct 824 -171 808 -162 794 -145 ct +794 -145 794 -145 794 -69 ct p ef +1052 0 m 995 0 l 995 -307 l 1052 -307 l 1052 0 l p ef +1305 -20 m 1280 -3 1251 5 1219 5 ct 1183 5 1154 -5 1132 -26 ct 1111 -46 1100 -74 1100 -108 ct +1100 -142 1110 -169 1129 -189 ct 1148 -210 1174 -220 1206 -220 ct 1235 -220 1259 -210 1277 -191 ct +1296 -171 1305 -144 1305 -109 ct 1305 -109 1305 -109 1305 -95 ct 1305 -95 1305 -95 1159 -95 ct +1161 -80 1168 -68 1179 -59 ct 1190 -49 1204 -44 1220 -44 ct 1245 -44 1270 -51 1295 -65 ct +1295 -65 1295 -65 1305 -20 ct p +1250 -133 m 1248 -147 1243 -158 1235 -167 ct 1227 -175 1218 -179 1206 -179 ct +1194 -179 1183 -175 1175 -167 ct 1166 -158 1161 -147 1159 -133 ct 1159 -133 1159 -133 1250 -133 ct +p ef +1668 0 m 1668 0 1668 0 1611 0 ct 1611 0 1611 0 1611 -125 ct 1611 -143 1609 -155 1604 -162 ct +1600 -168 1593 -171 1584 -171 ct 1569 -171 1554 -160 1538 -137 ct 1538 -137 1538 -137 1538 0 ct +1538 0 1538 0 1481 0 ct 1481 0 1481 0 1481 -125 ct 1481 -144 1479 -157 1474 -162 ct +1470 -168 1464 -171 1455 -171 ct 1440 -171 1424 -160 1408 -137 ct 1408 -137 1408 -137 1408 0 ct +1408 0 1408 0 1351 0 ct 1351 0 1351 0 1351 -215 ct 1351 -215 1351 -215 1408 -215 ct +1408 -215 1408 -215 1408 -182 ct 1425 -207 1446 -220 1473 -220 ct 1501 -220 1521 -207 1533 -182 ct +1551 -207 1574 -220 1603 -220 ct 1624 -220 1640 -214 1651 -201 ct 1662 -188 1668 -169 1668 -144 ct +1668 -144 1668 -144 1668 0 ct p ef +1756 -66 m 1766 -66 1775 -63 1782 -56 ct 1789 -49 1792 -41 1792 -31 ct 1792 -21 1789 -12 1782 -5 ct +1775 2 1766 5 1756 5 ct 1746 5 1738 2 1731 -5 ct 1724 -12 1721 -20 1721 -31 ct +1721 -41 1724 -49 1731 -56 ct 1738 -63 1746 -66 1756 -66 ct p ef +2030 0 m 2030 0 2030 0 1971 0 ct 1967 -9 1965 -17 1965 -25 ct 1946 -5 1923 5 1896 5 ct +1876 5 1860 -1 1849 -13 ct 1838 -24 1832 -40 1832 -59 ct 1832 -73 1836 -85 1843 -95 ct +1851 -106 1862 -114 1877 -120 ct 1892 -127 1909 -131 1930 -132 ct 1930 -132 1930 -132 1965 -135 ct +1965 -135 1965 -135 1965 -139 ct 1965 -163 1951 -175 1924 -175 ct 1916 -175 1905 -173 1891 -170 ct +1877 -166 1865 -162 1855 -157 ct 1855 -157 1855 -157 1841 -198 ct 1854 -204 1870 -210 1887 -214 ct +1905 -218 1920 -220 1934 -220 ct 1963 -220 1985 -213 2000 -199 ct 2015 -185 2022 -165 2022 -138 ct +2022 -138 2022 -138 2022 -51 ct 2022 -31 2025 -14 2030 0 ct p +1965 -66 m 1965 -66 1965 -66 1965 -101 ct 1941 -99 1926 -97 1920 -96 ct 1915 -95 1909 -93 1902 -89 ct +1896 -86 1892 -82 1889 -77 ct 1886 -72 1884 -67 1884 -61 ct 1884 -54 1886 -49 1891 -45 ct +1895 -40 1901 -38 1908 -38 ct 1929 -38 1948 -47 1965 -66 ct p ef +2282 0 m 2282 0 2282 0 2225 0 ct 2225 0 2225 0 2225 -125 ct 2225 -156 2214 -171 2192 -171 ct +2173 -171 2155 -160 2140 -139 ct 2140 -139 2140 -139 2140 0 ct 2140 0 2140 0 2083 0 ct +2083 0 2083 0 2083 -307 ct 2083 -307 2083 -307 2140 -307 ct 2140 -307 2140 -307 2140 -188 ct +2158 -209 2181 -220 2209 -220 ct 2231 -220 2249 -213 2262 -200 ct 2275 -187 2282 -168 2282 -144 ct +2282 -144 2282 -144 2282 0 ct p ef +pom +gr +gr +gs +gs +pum +2921 20586 t +376 -251 m 248 0 l 211 0 l 194 -202 l 89 0 l 54 0 l 32 -251 l 75 -251 l +85 -62 l 184 -251 l 225 -251 l 241 -62 l 333 -251 l 376 -251 l p ef +512 -257 m 544 -257 570 -248 588 -231 ct 607 -214 616 -190 616 -161 ct 616 -116 603 -78 576 -44 ct +550 -11 517 6 476 6 ct 444 6 418 -3 399 -21 ct 380 -38 371 -62 371 -91 ct 371 -136 384 -175 411 -208 ct +437 -241 471 -257 512 -257 ct p +476 -31 m 504 -31 526 -44 544 -71 ct 562 -98 571 -128 571 -160 ct 571 -178 566 -193 555 -204 ct +544 -215 530 -220 511 -220 ct 483 -220 460 -207 442 -182 ct 425 -157 416 -128 416 -94 ct +416 -76 421 -60 432 -49 ct 443 -37 457 -31 476 -31 ct p ef +897 -251 m 745 0 l 705 0 l 658 -251 l 701 -251 l 735 -52 l 851 -251 l +897 -251 l p ef +1105 -22 m 1073 -3 1038 6 1002 6 ct 969 6 944 -3 925 -20 ct 906 -37 896 -60 896 -89 ct +896 -134 910 -173 937 -207 ct 964 -240 998 -257 1039 -257 ct 1070 -257 1094 -249 1111 -233 ct +1128 -216 1136 -193 1136 -164 ct 1136 -156 1134 -142 1131 -122 ct 1131 -122 1131 -122 944 -122 ct +942 -114 941 -104 941 -92 ct 941 -74 946 -59 957 -48 ct 968 -37 984 -31 1004 -31 ct +1032 -31 1064 -40 1099 -58 ct 1099 -58 1099 -58 1105 -22 ct p +1092 -155 m 1093 -159 1093 -161 1093 -163 ct 1093 -181 1088 -196 1078 -206 ct +1069 -217 1056 -222 1039 -222 ct 1000 -222 971 -200 954 -155 ct 954 -155 954 -155 1092 -155 ct +p ef +1251 -212 m 1263 -226 1277 -236 1294 -245 ct 1310 -253 1326 -257 1343 -257 ct +1364 -257 1381 -251 1393 -240 ct 1404 -228 1410 -212 1410 -191 ct 1410 -181 1408 -166 1403 -143 ct +1403 -143 1403 -143 1372 0 ct 1372 0 1372 0 1329 0 ct 1329 0 1329 0 1360 -144 ct +1362 -154 1364 -163 1366 -171 ct 1367 -179 1368 -184 1368 -186 ct 1368 -209 1356 -220 1333 -220 ct +1320 -220 1305 -216 1288 -207 ct 1271 -198 1256 -186 1242 -172 ct 1242 -172 1242 -172 1206 0 ct +1206 0 1206 0 1163 0 ct 1163 0 1163 0 1216 -251 ct 1216 -251 1216 -251 1259 -251 ct +1259 -251 1259 -251 1251 -212 ct p ef +1822 -233 m 1822 -233 1822 -233 1803 -200 ct 1782 -214 1760 -221 1735 -221 ct +1706 -221 1681 -209 1661 -185 ct 1641 -160 1631 -131 1631 -96 ct 1631 -75 1636 -58 1647 -47 ct +1658 -36 1674 -31 1693 -31 ct 1718 -31 1745 -39 1776 -56 ct 1776 -56 1776 -56 1781 -22 ct +1749 -3 1718 6 1687 6 ct 1656 6 1631 -3 1613 -20 ct 1595 -38 1586 -62 1586 -93 ct +1586 -139 1601 -178 1630 -209 ct 1659 -241 1694 -257 1736 -257 ct 1751 -257 1767 -255 1783 -250 ct +1799 -246 1812 -240 1822 -233 ct p ef +1976 -257 m 2008 -257 2034 -248 2052 -231 ct 2071 -214 2080 -190 2080 -161 ct +2080 -116 2067 -78 2040 -44 ct 2014 -11 1981 6 1940 6 ct 1908 6 1882 -3 1863 -21 ct +1844 -38 1835 -62 1835 -91 ct 1835 -136 1848 -175 1875 -208 ct 1901 -241 1935 -257 1976 -257 ct +p +1940 -31 m 1968 -31 1990 -44 2008 -71 ct 2026 -98 2035 -128 2035 -160 ct 2035 -178 2030 -193 2019 -204 ct +2008 -215 1994 -220 1975 -220 ct 1947 -220 1924 -207 1906 -182 ct 1889 -157 1880 -128 1880 -94 ct +1880 -76 1885 -60 1896 -49 ct 1907 -37 1921 -31 1940 -31 ct p ef +2387 -359 m 2387 -359 2387 -359 2310 0 ct 2310 0 2310 0 2267 0 ct 2267 0 2267 0 2273 -28 ct +2253 -5 2228 6 2199 6 ct 2173 6 2151 -3 2135 -21 ct 2119 -39 2111 -63 2111 -93 ct +2111 -142 2124 -181 2151 -212 ct 2177 -242 2210 -257 2249 -257 ct 2276 -257 2298 -247 2315 -227 ct +2315 -227 2315 -227 2343 -359 ct 2343 -359 2343 -359 2387 -359 ct p +2306 -186 m 2291 -209 2272 -220 2249 -220 ct 2222 -220 2200 -208 2182 -184 ct +2165 -160 2156 -131 2156 -96 ct 2156 -76 2161 -61 2170 -49 ct 2180 -37 2193 -31 2210 -31 ct +2227 -31 2243 -37 2258 -49 ct 2273 -61 2281 -68 2282 -72 ct 2282 -72 2282 -72 2306 -186 ct +p ef +2595 -22 m 2563 -3 2528 6 2492 6 ct 2459 6 2434 -3 2415 -20 ct 2396 -37 2386 -60 2386 -89 ct +2386 -134 2400 -173 2427 -207 ct 2454 -240 2488 -257 2529 -257 ct 2560 -257 2584 -249 2601 -233 ct +2618 -216 2626 -193 2626 -164 ct 2626 -156 2624 -142 2621 -122 ct 2621 -122 2621 -122 2434 -122 ct +2432 -114 2431 -104 2431 -92 ct 2431 -74 2436 -59 2447 -48 ct 2458 -37 2474 -31 2494 -31 ct +2522 -31 2554 -40 2589 -58 ct 2589 -58 2589 -58 2595 -22 ct p +2582 -155 m 2583 -159 2583 -161 2583 -163 ct 2583 -181 2578 -196 2568 -206 ct +2559 -217 2546 -222 2529 -222 ct 2490 -222 2461 -200 2444 -155 ct 2444 -155 2444 -155 2582 -155 ct +p ef +pom +gr +gr +0.503 0.503 0.503 c 5210 19108 m 1935 19108 l 1935 13649 l 8485 13649 l +8485 19108 l 5210 19108 l p ef +5210 19108 m 1935 19108 l 1935 13649 l 8485 13649 l 8485 19108 l 5210 19108 l +pc +1.000 0.902 0.777 c 5110 19008 m 1835 19008 l 1835 13549 l 8385 13549 l +8385 19008 l 5110 19008 l p ef +0.003 0.003 0.003 c 5110 19008 m 1835 19008 l 1835 13549 l 8385 13549 l +8385 19008 l 5110 19008 l pc +gs +gs +pum +1942 13977 t +1.000 0.402 0.203 c 33 0 m 56 -89 l 15 -89 l 22 -125 l 65 -125 l 79 -181 l +33 -181 l 40 -217 l 88 -217 l 111 -306 l 147 -306 l 125 -217 l 161 -217 l +183 -306 l 220 -306 l 198 -217 l 239 -217 l 232 -181 l 189 -181 l +175 -125 l 221 -125 l 214 -89 l 165 -89 l 143 0 l 106 0 l 128 -89 l +92 -89 l 70 0 l 33 0 l p +101 -125 m 138 -125 l 152 -181 l 116 -181 l 101 -125 l p ef +376 0 m 376 -183 l 294 -183 l 294 -224 l 437 -224 l 437 0 l 376 0 l +p +376 -265 m 376 -326 l 437 -326 l 437 -265 l 376 -265 l p ef +537 0 m 537 0 537 0 537 -224 ct 537 -224 537 -224 598 -224 ct 598 -224 598 -224 597 -202 ct +597 -202 597 -202 596 -181 ct 596 -181 596 -181 598 -181 ct 605 -197 614 -209 626 -217 ct +638 -225 652 -229 670 -229 ct 692 -229 708 -223 719 -210 ct 730 -197 736 -178 736 -153 ct +736 -153 736 -153 736 0 ct 736 0 736 0 675 0 ct 675 0 675 0 675 -139 ct 675 -150 673 -159 669 -165 ct +664 -170 658 -173 649 -173 ct 640 -173 631 -170 622 -165 ct 614 -159 605 -151 598 -139 ct +598 -139 598 -139 598 0 ct 598 0 598 0 537 0 ct p ef +989 -4 m 964 2 939 5 914 5 ct 873 5 840 -5 817 -26 ct 794 -47 782 -75 782 -111 ct +782 -148 793 -177 816 -198 ct 838 -219 870 -229 910 -229 ct 940 -229 966 -226 989 -220 ct +989 -220 989 -220 989 -175 ct 964 -184 941 -188 918 -188 ct 896 -188 879 -182 867 -169 ct +854 -157 848 -140 848 -118 ct 848 -94 856 -74 871 -60 ct 886 -45 906 -38 931 -38 ct +950 -38 970 -42 989 -49 ct 989 -49 989 -49 989 -4 ct p ef +1118 0 m 1118 -285 l 1036 -285 l 1036 -326 l 1179 -326 l 1179 0 l +1118 0 l p ef +1496 -224 m 1496 -224 1496 -224 1496 0 ct 1496 0 1496 0 1435 0 ct 1435 0 1435 0 1436 -22 ct +1436 -22 1436 -22 1438 -43 ct 1438 -43 1438 -43 1435 -43 ct 1429 -27 1420 -15 1408 -7 ct +1396 1 1381 5 1364 5 ct 1342 5 1325 -1 1314 -14 ct 1303 -27 1297 -46 1297 -71 ct +1297 -71 1297 -71 1297 -224 ct 1297 -224 1297 -224 1358 -224 ct 1358 -224 1358 -224 1358 -85 ct +1358 -73 1360 -65 1364 -59 ct 1369 -54 1375 -51 1384 -51 ct 1393 -51 1402 -54 1411 -59 ct +1419 -65 1427 -73 1435 -85 ct 1435 -85 1435 -85 1435 -224 ct 1435 -224 1435 -224 1496 -224 ct +p ef +1698 0 m 1698 0 1698 0 1700 -42 ct 1700 -42 1700 -42 1698 -42 ct 1688 -27 1677 -15 1665 -7 ct +1654 1 1641 5 1627 5 ct 1601 5 1581 -5 1565 -26 ct 1550 -46 1542 -73 1542 -107 ct +1542 -144 1551 -174 1568 -196 ct 1585 -218 1608 -229 1637 -229 ct 1649 -229 1660 -227 1670 -222 ct +1680 -218 1689 -211 1698 -203 ct 1698 -203 1698 -203 1700 -203 ct 1700 -203 1700 -203 1698 -224 ct +1698 -224 1698 -224 1698 -326 ct 1698 -326 1698 -326 1759 -326 ct 1759 -326 1759 -326 1759 0 ct +1759 0 1759 0 1698 0 ct p +1698 -160 m 1691 -168 1684 -173 1677 -177 ct 1670 -181 1662 -183 1654 -183 ct +1638 -183 1627 -177 1619 -164 ct 1612 -152 1608 -133 1608 -108 ct 1608 -89 1611 -75 1618 -65 ct +1625 -56 1635 -51 1648 -51 ct 1657 -51 1665 -54 1674 -60 ct 1682 -66 1690 -75 1698 -88 ct +1698 -88 1698 -88 1698 -160 ct p ef +2014 -95 m 2014 -95 2014 -95 1862 -95 ct 1865 -77 1873 -63 1885 -54 ct 1897 -45 1913 -41 1934 -41 ct +1958 -41 1985 -46 2014 -56 ct 2014 -56 2014 -56 2014 -9 ct 1979 0 1948 5 1922 5 ct +1884 5 1853 -6 1830 -27 ct 1807 -48 1796 -76 1796 -111 ct 1796 -147 1807 -175 1828 -197 ct +1850 -218 1878 -229 1913 -229 ct 1945 -229 1969 -219 1987 -199 ct 2005 -180 2014 -152 2014 -118 ct +2014 -118 2014 -118 2014 -95 ct p +1861 -136 m 1861 -136 1861 -136 1955 -136 ct 1955 -153 1951 -166 1944 -175 ct +1936 -184 1925 -188 1910 -188 ct 1896 -188 1884 -184 1876 -175 ct 1868 -166 1863 -153 1861 -136 ct +p ef +2388 -326 m 2388 -326 2388 -326 2388 -301 ct 2378 -300 2371 -298 2368 -294 ct +2365 -290 2363 -283 2363 -272 ct 2363 -272 2363 -272 2363 -265 ct 2363 -265 2363 -265 2388 -265 ct +2388 -265 2388 -265 2388 -204 ct 2388 -204 2388 -204 2327 -204 ct 2327 -204 2327 -204 2327 -257 ct +2327 -283 2331 -300 2340 -310 ct 2348 -319 2365 -325 2388 -326 ct p +2500 -326 m 2500 -326 2500 -326 2500 -301 ct 2490 -300 2483 -298 2480 -294 ct +2477 -290 2475 -283 2475 -272 ct 2475 -272 2475 -272 2475 -265 ct 2475 -265 2475 -265 2500 -265 ct +2500 -265 2500 -265 2500 -204 ct 2500 -204 2500 -204 2439 -204 ct 2439 -204 2439 -204 2439 -257 ct +2439 -283 2443 -300 2452 -310 ct 2460 -319 2476 -325 2500 -326 ct p ef +2558 0 m 2558 0 2558 0 2558 -306 ct 2558 -306 2558 -306 2653 -306 ct 2696 -306 2728 -293 2751 -266 ct +2774 -240 2786 -202 2786 -153 ct 2786 -105 2774 -67 2751 -40 ct 2728 -13 2695 0 2653 0 ct +2653 0 2653 0 2558 0 ct p +2619 -41 m 2619 -41 2619 -41 2639 -41 ct 2668 -41 2689 -50 2701 -67 ct 2714 -84 2720 -114 2720 -154 ct +2720 -194 2714 -223 2701 -240 ct 2689 -257 2668 -265 2639 -265 ct 2639 -265 2639 -265 2619 -265 ct +2619 -265 2619 -265 2619 -41 ct p ef +3020 -224 m 3020 -224 3020 -224 3020 0 ct 3020 0 3020 0 2959 0 ct 2959 0 2959 0 2960 -22 ct +2960 -22 2960 -22 2962 -43 ct 2962 -43 2962 -43 2959 -43 ct 2953 -27 2944 -15 2932 -7 ct +2920 1 2905 5 2888 5 ct 2866 5 2849 -1 2838 -14 ct 2827 -27 2821 -46 2821 -71 ct +2821 -71 2821 -71 2821 -224 ct 2821 -224 2821 -224 2882 -224 ct 2882 -224 2882 -224 2882 -85 ct +2882 -73 2884 -65 2888 -59 ct 2893 -54 2899 -51 2908 -51 ct 2917 -51 2926 -54 2935 -59 ct +2943 -65 2951 -73 2959 -85 ct 2959 -85 2959 -85 2959 -224 ct 2959 -224 2959 -224 3020 -224 ct +p ef +3201 0 m 3201 0 3201 0 3150 0 ct 3150 0 3150 0 3150 -149 ct 3150 -157 3149 -163 3148 -167 ct +3146 -171 3144 -173 3141 -173 ct 3136 -173 3132 -171 3128 -166 ct 3124 -161 3121 -154 3117 -145 ct +3117 -145 3117 -145 3117 0 ct 3117 0 3117 0 3066 0 ct 3066 0 3066 0 3066 -224 ct +3066 -224 3066 -224 3117 -224 ct 3117 -224 3117 -224 3114 -181 ct 3114 -181 3114 -181 3117 -181 ct +3122 -197 3129 -209 3137 -217 ct 3145 -225 3154 -229 3164 -229 ct 3175 -229 3184 -225 3190 -217 ct +3196 -209 3200 -197 3201 -181 ct 3201 -181 3201 -181 3203 -181 ct 3208 -197 3214 -209 3221 -217 ct +3229 -225 3237 -229 3247 -229 ct 3261 -229 3271 -223 3277 -212 ct 3282 -200 3285 -179 3285 -150 ct +3285 -150 3285 -150 3285 0 ct 3285 0 3285 0 3234 0 ct 3234 0 3234 0 3234 -149 ct +3234 -157 3233 -163 3232 -167 ct 3230 -171 3228 -173 3225 -173 ct 3220 -173 3216 -171 3212 -166 ct +3209 -161 3205 -154 3201 -145 ct 3201 -145 3201 -145 3201 0 ct p ef +3326 82 m 3326 82 3326 82 3326 -224 ct 3326 -224 3326 -224 3387 -224 ct 3387 -224 3387 -224 3385 -182 ct +3385 -182 3385 -182 3387 -182 ct 3397 -197 3408 -209 3419 -217 ct 3431 -225 3444 -229 3458 -229 ct +3484 -229 3504 -219 3520 -198 ct 3535 -178 3543 -151 3543 -117 ct 3543 -80 3534 -50 3517 -28 ct +3500 -6 3477 5 3448 5 ct 3436 5 3424 3 3414 -2 ct 3404 -6 3395 -13 3387 -22 ct +3387 -22 3387 -22 3385 -22 ct 3385 -22 3385 -22 3387 0 ct 3387 0 3387 0 3387 82 ct +3387 82 3387 82 3326 82 ct p +3387 -64 m 3394 -56 3401 -50 3408 -47 ct 3415 -43 3423 -41 3432 -41 ct 3447 -41 3458 -47 3466 -60 ct +3473 -72 3477 -91 3477 -116 ct 3477 -135 3474 -149 3467 -159 ct 3460 -168 3451 -173 3437 -173 ct +3429 -173 3420 -170 3411 -164 ct 3403 -158 3395 -149 3387 -136 ct 3387 -136 3387 -136 3387 -64 ct +p ef +3648 0 m 3648 -71 l 3719 -71 l 3719 0 l 3648 0 l p ef +3963 -24 m 3956 -14 3947 -7 3937 -2 ct 3927 3 3916 5 3903 5 ct 3881 5 3863 -2 3849 -15 ct +3835 -28 3828 -45 3828 -65 ct 3828 -91 3838 -111 3857 -124 ct 3877 -137 3906 -143 3945 -143 ct +3945 -143 3945 -143 3969 -143 ct 3969 -143 3969 -143 3969 -154 ct 3969 -165 3965 -174 3957 -179 ct +3949 -185 3937 -188 3921 -188 ct 3899 -188 3874 -182 3847 -169 ct 3847 -169 3847 -169 3847 -214 ct +3875 -224 3903 -229 3932 -229 ct 3964 -229 3988 -223 4004 -211 ct 4014 -203 4021 -194 4025 -185 ct +4028 -175 4030 -160 4030 -140 ct 4030 -140 4030 -140 4030 -64 ct 4030 -49 4035 -41 4044 -41 ct +4046 -41 4048 -41 4051 -42 ct 4051 -42 4051 -42 4051 -2 ct 4039 3 4027 5 4017 5 ct +4006 5 3996 3 3988 -2 ct 3980 -7 3974 -14 3969 -24 ct 3969 -24 3969 -24 3963 -24 ct +p +3969 -65 m 3969 -65 3969 -65 3969 -102 ct 3969 -102 3969 -102 3947 -102 ct +3928 -102 3913 -99 3904 -94 ct 3894 -88 3889 -80 3889 -69 ct 3889 -61 3892 -54 3898 -49 ct +3904 -44 3911 -41 3920 -41 ct 3935 -41 3952 -49 3969 -65 ct p ef +4093 0 m 4093 0 4093 0 4093 -326 ct 4093 -326 4093 -326 4154 -326 ct 4154 -326 4154 -326 4154 -224 ct +4154 -224 4154 -224 4152 -181 ct 4152 -181 4152 -181 4154 -181 ct 4161 -197 4170 -209 4182 -217 ct +4194 -225 4208 -229 4226 -229 ct 4248 -229 4264 -223 4275 -210 ct 4286 -197 4292 -178 4292 -153 ct +4292 -153 4292 -153 4292 0 ct 4292 0 4292 0 4231 0 ct 4231 0 4231 0 4231 -139 ct +4231 -150 4229 -159 4225 -165 ct 4220 -170 4214 -173 4205 -173 ct 4196 -173 4187 -170 4178 -165 ct +4170 -159 4161 -151 4154 -139 ct 4154 -139 4154 -139 4154 0 ct 4154 0 4154 0 4093 0 ct +p ef +4420 -326 m 4420 -326 4420 -326 4420 -301 ct 4410 -300 4403 -298 4400 -294 ct +4397 -290 4395 -283 4395 -272 ct 4395 -272 4395 -272 4395 -265 ct 4395 -265 4395 -265 4420 -265 ct +4420 -265 4420 -265 4420 -204 ct 4420 -204 4420 -204 4359 -204 ct 4359 -204 4359 -204 4359 -257 ct +4359 -283 4363 -300 4372 -310 ct 4380 -319 4397 -325 4420 -326 ct p +4532 -326 m 4532 -326 4532 -326 4532 -301 ct 4522 -300 4515 -298 4512 -294 ct +4509 -290 4507 -283 4507 -272 ct 4507 -272 4507 -272 4507 -265 ct 4507 -265 4507 -265 4532 -265 ct +4532 -265 4532 -265 4532 -204 ct 4532 -204 4532 -204 4471 -204 ct 4471 -204 4471 -204 4471 -257 ct +4471 -283 4475 -300 4484 -310 ct 4492 -319 4508 -325 4532 -326 ct p ef +pom +gr +gs +pum +1942 14959 t +0.003 0.003 1.000 c 227 -4 m 202 2 177 5 152 5 ct 111 5 78 -5 55 -26 ct 32 -47 20 -75 20 -111 ct +20 -148 31 -177 54 -198 ct 76 -219 108 -229 148 -229 ct 178 -229 204 -226 227 -220 ct +227 -220 227 -220 227 -175 ct 202 -184 179 -188 156 -188 ct 134 -188 117 -182 105 -169 ct +92 -157 86 -140 86 -118 ct 86 -94 94 -74 109 -60 ct 124 -45 144 -38 169 -38 ct +188 -38 208 -42 227 -49 ct 227 -49 227 -49 227 -4 ct p ef +356 0 m 356 -285 l 274 -285 l 274 -326 l 417 -326 l 417 0 l 356 0 l +p ef +661 -24 m 654 -14 645 -7 635 -2 ct 625 3 614 5 601 5 ct 579 5 561 -2 547 -15 ct +533 -28 526 -45 526 -65 ct 526 -91 536 -111 555 -124 ct 575 -137 604 -143 643 -143 ct +643 -143 643 -143 667 -143 ct 667 -143 667 -143 667 -154 ct 667 -165 663 -174 655 -179 ct +647 -185 635 -188 619 -188 ct 597 -188 572 -182 545 -169 ct 545 -169 545 -169 545 -214 ct +573 -224 601 -229 630 -229 ct 662 -229 686 -223 702 -211 ct 712 -203 719 -194 723 -185 ct +726 -175 728 -160 728 -140 ct 728 -140 728 -140 728 -64 ct 728 -49 733 -41 742 -41 ct +744 -41 746 -41 749 -42 ct 749 -42 749 -42 749 -2 ct 737 3 725 5 715 5 ct 704 5 694 3 686 -2 ct +678 -7 672 -14 667 -24 ct 667 -24 667 -24 661 -24 ct p +667 -65 m 667 -65 667 -65 667 -102 ct 667 -102 667 -102 645 -102 ct 626 -102 611 -99 602 -94 ct +592 -88 587 -80 587 -69 ct 587 -61 590 -54 596 -49 ct 602 -44 609 -41 618 -41 ct +633 -41 650 -49 667 -65 ct p ef +795 -8 m 795 -8 795 -8 795 -54 ct 829 -42 857 -36 877 -36 ct 892 -36 903 -38 911 -42 ct +918 -46 922 -52 922 -60 ct 922 -64 920 -68 916 -72 ct 913 -75 907 -79 900 -82 ct +900 -82 900 -82 852 -101 ct 833 -109 819 -118 810 -127 ct 801 -137 796 -148 796 -161 ct +796 -182 806 -199 825 -211 ct 844 -223 871 -229 905 -229 ct 925 -229 948 -226 974 -221 ct +974 -221 974 -221 974 -174 ct 946 -183 922 -188 903 -188 ct 888 -188 878 -186 871 -183 ct +864 -180 860 -175 860 -169 ct 860 -165 863 -162 868 -158 ct 873 -154 880 -150 890 -146 ct +890 -146 890 -146 943 -124 ct 959 -118 971 -110 978 -100 ct 986 -91 990 -79 990 -66 ct +990 -45 981 -28 962 -15 ct 943 -2 919 5 889 5 ct 863 5 831 1 795 -8 ct p ef +1049 -8 m 1049 -8 1049 -8 1049 -54 ct 1083 -42 1111 -36 1131 -36 ct 1146 -36 1157 -38 1165 -42 ct +1172 -46 1176 -52 1176 -60 ct 1176 -64 1174 -68 1170 -72 ct 1167 -75 1161 -79 1154 -82 ct +1154 -82 1154 -82 1106 -101 ct 1087 -109 1073 -118 1064 -127 ct 1055 -137 1050 -148 1050 -161 ct +1050 -182 1060 -199 1079 -211 ct 1098 -223 1125 -229 1159 -229 ct 1179 -229 1202 -226 1228 -221 ct +1228 -221 1228 -221 1228 -174 ct 1200 -183 1176 -188 1157 -188 ct 1142 -188 1132 -186 1125 -183 ct +1118 -180 1114 -175 1114 -169 ct 1114 -165 1117 -162 1122 -158 ct 1127 -154 1134 -150 1144 -146 ct +1144 -146 1144 -146 1197 -124 ct 1213 -118 1225 -110 1232 -100 ct 1240 -91 1244 -79 1244 -66 ct +1244 -45 1235 -28 1216 -15 ct 1197 -2 1173 5 1143 5 ct 1117 5 1085 1 1049 -8 ct +p ef +pom +gr +gs +pum +3212 14959 t +361 0 m 361 -275 l 259 -275 l 259 -306 l 504 -306 l 504 -275 l 402 -275 l +402 0 l 361 0 l p ef +680 -26 m 656 -5 631 5 607 5 ct 586 5 569 -1 556 -13 ct 543 -24 536 -39 536 -57 ct +536 -81 546 -99 567 -114 ct 588 -128 615 -135 649 -135 ct 649 -135 649 -135 674 -135 ct +674 -135 674 -135 674 -154 ct 674 -169 670 -180 663 -187 ct 655 -194 644 -198 629 -198 ct +605 -198 580 -191 555 -177 ct 555 -177 555 -177 555 -213 ct 584 -224 611 -229 637 -229 ct +666 -229 686 -223 697 -212 ct 709 -201 715 -181 715 -153 ct 715 -153 715 -153 715 -59 ct +715 -45 716 -36 719 -31 ct 722 -26 728 -24 735 -24 ct 738 -24 742 -25 748 -26 ct +748 -26 748 -26 752 -2 ct 738 3 728 5 721 5 ct 711 5 702 2 696 -3 ct 689 -8 684 -16 680 -26 ct +p +674 -53 m 674 -53 674 -53 674 -110 ct 674 -110 674 -110 662 -110 ct 634 -110 613 -106 599 -99 ct +585 -91 578 -80 578 -64 ct 578 -52 581 -43 588 -37 ct 594 -31 604 -28 617 -28 ct +635 -28 654 -36 674 -53 ct p ef +826 0 m 826 0 826 0 826 -224 ct 826 -224 826 -224 867 -224 ct 867 -224 867 -224 865 -182 ct +865 -182 865 -182 867 -182 ct 877 -198 889 -209 903 -217 ct 917 -225 932 -229 950 -229 ct +962 -229 976 -227 991 -224 ct 991 -224 991 -224 991 -160 ct 991 -160 991 -160 960 -160 ct +960 -160 960 -160 960 -191 ct 954 -192 948 -193 943 -193 ct 929 -193 916 -189 904 -181 ct +891 -173 879 -161 867 -145 ct 867 -145 867 -145 867 0 ct 867 0 867 0 826 0 ct p ef +1059 75 m 1059 75 1059 75 1063 41 ct 1088 51 1111 56 1132 56 ct 1154 56 1170 51 1179 42 ct +1189 33 1195 17 1198 -6 ct 1198 -6 1198 -6 1202 -46 ct 1202 -46 1202 -46 1198 -46 ct +1190 -31 1179 -19 1167 -12 ct 1154 -4 1140 0 1124 0 ct 1099 0 1079 -10 1064 -29 ct +1049 -49 1041 -75 1041 -108 ct 1041 -144 1050 -173 1067 -195 ct 1085 -218 1107 -229 1135 -229 ct +1157 -229 1179 -219 1200 -198 ct 1200 -198 1200 -198 1203 -198 ct 1203 -198 1203 -198 1203 -224 ct +1203 -224 1203 -224 1239 -224 ct 1239 -224 1239 -224 1239 -45 ct 1239 -15 1237 6 1233 21 ct +1229 36 1222 49 1211 60 ct 1194 78 1168 87 1131 87 ct 1110 87 1086 83 1059 75 ct +p +1198 -80 m 1198 -80 1198 -80 1198 -167 ct 1180 -188 1160 -198 1141 -198 ct +1122 -198 1108 -191 1098 -176 ct 1089 -162 1084 -140 1084 -111 ct 1084 -86 1088 -67 1096 -55 ct +1105 -42 1117 -36 1134 -36 ct 1146 -36 1157 -40 1168 -47 ct 1179 -54 1189 -65 1198 -80 ct +p ef +1496 -9 m 1468 0 1442 5 1418 5 ct 1380 5 1351 -5 1330 -25 ct 1309 -45 1299 -73 1299 -110 ct +1299 -144 1309 -173 1329 -195 ct 1349 -218 1374 -229 1405 -229 ct 1436 -229 1458 -220 1473 -201 ct +1488 -182 1495 -153 1495 -114 ct 1495 -114 1495 -114 1495 -101 ct 1495 -101 1495 -101 1341 -101 ct +1342 -76 1350 -57 1364 -45 ct 1378 -32 1397 -26 1423 -26 ct 1446 -26 1470 -31 1496 -42 ct +1496 -42 1496 -42 1496 -9 ct p +1342 -132 m 1342 -132 1342 -132 1452 -132 ct 1452 -132 1452 -132 1452 -138 ct +1452 -158 1448 -173 1439 -183 ct 1430 -193 1418 -198 1401 -198 ct 1384 -198 1371 -192 1360 -181 ct +1350 -169 1344 -153 1342 -132 ct p ef +1752 0 m 1732 3 1712 5 1693 5 ct 1660 5 1637 -1 1625 -13 ct 1613 -25 1607 -47 1607 -80 ct +1607 -80 1607 -80 1607 -188 ct 1607 -188 1607 -188 1551 -188 ct 1551 -188 1551 -188 1551 -219 ct +1551 -219 1551 -219 1607 -219 ct 1607 -219 1607 -219 1607 -267 ct 1607 -267 1607 -267 1648 -267 ct +1648 -267 1648 -267 1648 -219 ct 1648 -219 1648 -219 1747 -219 ct 1747 -219 1747 -219 1747 -188 ct +1747 -188 1747 -188 1648 -188 ct 1648 -188 1648 -188 1648 -74 ct 1648 -61 1649 -53 1650 -48 ct +1652 -43 1655 -39 1661 -35 ct 1670 -29 1683 -26 1701 -26 ct 1718 -26 1735 -28 1752 -31 ct +1752 -31 1752 -31 1752 0 ct p ef +2244 -326 m 2244 -326 2244 -326 2244 -295 ct 2244 -295 2244 -295 2228 -295 ct +2207 -295 2193 -293 2185 -287 ct 2176 -282 2172 -274 2172 -261 ct 2172 -257 2173 -251 2174 -242 ct +2174 -242 2174 -242 2178 -214 ct 2179 -204 2180 -196 2180 -190 ct 2180 -175 2177 -163 2170 -153 ct +2163 -144 2153 -137 2139 -132 ct 2153 -128 2163 -121 2170 -111 ct 2177 -102 2180 -90 2180 -75 ct +2180 -68 2179 -61 2178 -51 ct 2178 -51 2178 -51 2174 -23 ct 2173 -14 2172 -8 2172 -4 ct +2172 9 2176 17 2185 22 ct 2193 27 2207 30 2228 30 ct 2228 30 2228 30 2244 30 ct +2244 30 2244 30 2244 61 ct 2244 61 2244 61 2221 61 ct 2192 61 2170 56 2156 46 ct +2141 36 2134 21 2134 2 ct 2134 -7 2135 -16 2137 -26 ct 2137 -26 2137 -26 2144 -63 ct +2145 -68 2145 -74 2145 -79 ct 2145 -92 2141 -101 2133 -108 ct 2126 -114 2114 -117 2099 -117 ct +2099 -117 2099 -117 2080 -117 ct 2080 -117 2080 -117 2080 -148 ct 2080 -148 2080 -148 2099 -148 ct +2114 -148 2126 -151 2133 -157 ct 2141 -164 2145 -173 2145 -186 ct 2145 -191 2145 -197 2144 -202 ct +2144 -202 2144 -202 2137 -239 ct 2135 -249 2134 -258 2134 -267 ct 2134 -286 2141 -301 2156 -311 ct +2170 -321 2192 -326 2221 -326 ct 2221 -326 2221 -326 2244 -326 ct p ef +pom +gr +gs +pum +1942 15450 t +pom +gr +gs +pum +2450 15450 t +0.003 0.003 1.000 c 98 0 m 9 -224 l 75 -224 l 137 -67 l 198 -224 l 247 -224 l +159 0 l 98 0 l p ef +380 5 m 346 5 318 -6 297 -27 ct 276 -49 265 -77 265 -112 ct 265 -148 276 -176 297 -197 ct +318 -218 346 -229 382 -229 ct 417 -229 445 -218 466 -197 ct 487 -176 498 -148 498 -112 ct +498 -76 487 -48 466 -27 ct 445 -6 416 5 380 5 ct p +381 -36 m 398 -36 411 -42 419 -55 ct 428 -68 432 -87 432 -112 ct 432 -138 428 -156 419 -169 ct +411 -182 398 -188 382 -188 ct 365 -188 352 -182 344 -169 ct 335 -156 331 -137 331 -112 ct +331 -87 335 -68 343 -55 ct 352 -42 364 -36 381 -36 ct p ef +630 0 m 630 -183 l 548 -183 l 548 -224 l 691 -224 l 691 0 l 630 0 l +p +630 -265 m 630 -326 l 691 -326 l 691 -265 l 630 -265 l p ef +936 0 m 936 0 936 0 938 -42 ct 938 -42 938 -42 936 -42 ct 926 -27 915 -15 903 -7 ct +892 1 879 5 865 5 ct 839 5 819 -5 803 -26 ct 788 -46 780 -73 780 -107 ct 780 -144 789 -174 806 -196 ct +823 -218 846 -229 875 -229 ct 887 -229 898 -227 908 -222 ct 918 -218 927 -211 936 -203 ct +936 -203 936 -203 938 -203 ct 938 -203 938 -203 936 -224 ct 936 -224 936 -224 936 -326 ct +936 -326 936 -326 997 -326 ct 997 -326 997 -326 997 0 ct 997 0 997 0 936 0 ct p +936 -160 m 929 -168 922 -173 915 -177 ct 908 -181 900 -183 892 -183 ct 876 -183 865 -177 857 -164 ct +850 -152 846 -133 846 -108 ct 846 -89 849 -75 856 -65 ct 863 -56 873 -51 886 -51 ct +895 -51 903 -54 912 -60 ct 920 -66 928 -75 936 -88 ct 936 -88 936 -88 936 -160 ct +p ef +pom +gr +gs +pum +3466 15450 t +pom +gr +gs +pum +3720 15450 t +228 0 m 208 3 188 5 169 5 ct 136 5 113 -1 101 -13 ct 89 -25 83 -47 83 -80 ct 83 -80 83 -80 83 -188 ct +83 -188 83 -188 27 -188 ct 27 -188 27 -188 27 -219 ct 27 -219 27 -219 83 -219 ct +83 -219 83 -219 83 -267 ct 83 -267 83 -267 124 -267 ct 124 -267 124 -267 124 -219 ct +124 -219 124 -219 223 -219 ct 223 -219 223 -219 223 -188 ct 223 -188 223 -188 124 -188 ct +124 -188 124 -188 124 -74 ct 124 -61 125 -53 126 -48 ct 128 -43 131 -39 137 -35 ct +146 -29 159 -26 177 -26 ct 194 -26 211 -28 228 -31 ct 228 -31 228 -31 228 0 ct +p ef +318 0 m 318 0 318 0 318 -224 ct 318 -224 318 -224 359 -224 ct 359 -224 359 -224 357 -182 ct +357 -182 357 -182 359 -182 ct 369 -198 381 -209 395 -217 ct 409 -225 424 -229 442 -229 ct +454 -229 468 -227 483 -224 ct 483 -224 483 -224 483 -160 ct 483 -160 483 -160 452 -160 ct +452 -160 452 -160 452 -191 ct 446 -192 440 -193 435 -193 ct 421 -193 408 -189 396 -181 ct +383 -173 371 -161 359 -145 ct 359 -145 359 -145 359 0 ct 359 0 359 0 318 0 ct p ef +680 -26 m 656 -5 631 5 607 5 ct 586 5 569 -1 556 -13 ct 543 -24 536 -39 536 -57 ct +536 -81 546 -99 567 -114 ct 588 -128 615 -135 649 -135 ct 649 -135 649 -135 674 -135 ct +674 -135 674 -135 674 -154 ct 674 -169 670 -180 663 -187 ct 655 -194 644 -198 629 -198 ct +605 -198 580 -191 555 -177 ct 555 -177 555 -177 555 -213 ct 584 -224 611 -229 637 -229 ct +666 -229 686 -223 697 -212 ct 709 -201 715 -181 715 -153 ct 715 -153 715 -153 715 -59 ct +715 -45 716 -36 719 -31 ct 722 -26 728 -24 735 -24 ct 738 -24 742 -25 748 -26 ct +748 -26 748 -26 752 -2 ct 738 3 728 5 721 5 ct 711 5 702 2 696 -3 ct 689 -8 684 -16 680 -26 ct +p +674 -53 m 674 -53 674 -53 674 -110 ct 674 -110 674 -110 662 -110 ct 634 -110 613 -106 599 -99 ct +585 -91 578 -80 578 -64 ct 578 -52 581 -43 588 -37 ct 594 -31 604 -28 617 -28 ct +635 -28 654 -36 674 -53 ct p ef +799 0 m 799 0 799 0 799 -224 ct 799 -224 799 -224 840 -224 ct 840 -224 840 -224 838 -182 ct +838 -182 838 -182 840 -182 ct 850 -198 861 -209 874 -217 ct 886 -225 901 -229 917 -229 ct +938 -229 954 -223 965 -210 ct 976 -197 981 -178 981 -153 ct 981 -153 981 -153 981 0 ct +981 0 981 0 940 0 ct 940 0 940 0 940 -142 ct 940 -159 937 -172 932 -179 ct 926 -186 917 -190 904 -190 ct +894 -190 884 -186 873 -179 ct 862 -172 851 -161 840 -146 ct 840 -146 840 -146 840 0 ct +840 0 840 0 799 0 ct p ef +1055 -9 m 1055 -9 1055 -9 1055 -45 ct 1086 -32 1113 -26 1136 -26 ct 1152 -26 1166 -29 1177 -36 ct +1188 -43 1193 -51 1193 -61 ct 1193 -74 1180 -84 1155 -93 ct 1155 -93 1155 -93 1112 -107 ct +1078 -118 1061 -138 1061 -165 ct 1061 -186 1069 -201 1084 -212 ct 1099 -223 1121 -229 1149 -229 ct +1170 -229 1194 -226 1222 -219 ct 1222 -219 1222 -219 1222 -186 ct 1195 -194 1171 -198 1149 -198 ct +1133 -198 1120 -196 1112 -191 ct 1104 -186 1100 -179 1100 -169 ct 1100 -158 1110 -149 1130 -142 ct +1130 -142 1130 -142 1182 -124 ct 1217 -111 1234 -91 1234 -64 ct 1234 -43 1225 -26 1208 -14 ct +1190 -1 1167 5 1137 5 ct 1112 5 1084 0 1055 -9 ct p ef +1362 0 m 1362 0 1362 0 1362 -188 ct 1362 -188 1362 -188 1301 -188 ct 1301 -188 1301 -188 1301 -219 ct +1301 -219 1301 -219 1362 -219 ct 1362 -219 1362 -219 1362 -243 ct 1362 -274 1369 -297 1384 -310 ct +1398 -324 1422 -331 1456 -331 ct 1478 -331 1498 -328 1518 -322 ct 1518 -322 1518 -322 1518 -289 ct +1498 -296 1478 -300 1459 -300 ct 1438 -300 1424 -296 1415 -288 ct 1407 -280 1403 -267 1403 -247 ct +1403 -247 1403 -247 1403 -219 ct 1403 -219 1403 -219 1510 -219 ct 1510 -219 1510 -219 1510 -188 ct +1510 -188 1510 -188 1403 -188 ct 1403 -188 1403 -188 1403 0 ct 1403 0 1403 0 1362 0 ct +p ef +1650 5 m 1618 5 1593 -6 1574 -27 ct 1555 -48 1546 -76 1546 -112 ct 1546 -148 1555 -177 1574 -198 ct +1593 -219 1619 -229 1652 -229 ct 1684 -229 1710 -219 1729 -198 ct 1748 -177 1757 -149 1757 -113 ct +1757 -76 1748 -47 1729 -26 ct 1710 -5 1684 5 1650 5 ct p +1651 -26 m 1672 -26 1688 -33 1698 -48 ct 1709 -62 1714 -84 1714 -113 ct 1714 -139 1708 -160 1697 -175 ct +1686 -190 1671 -198 1652 -198 ct 1632 -198 1617 -190 1606 -175 ct 1595 -160 1589 -139 1589 -112 ct +1589 -85 1594 -64 1605 -49 ct 1616 -34 1632 -26 1651 -26 ct p ef +1842 0 m 1842 0 1842 0 1842 -224 ct 1842 -224 1842 -224 1883 -224 ct 1883 -224 1883 -224 1881 -182 ct +1881 -182 1881 -182 1883 -182 ct 1893 -198 1905 -209 1919 -217 ct 1933 -225 1948 -229 1966 -229 ct +1978 -229 1992 -227 2007 -224 ct 2007 -224 2007 -224 2007 -160 ct 2007 -160 2007 -160 1976 -160 ct +1976 -160 1976 -160 1976 -191 ct 1970 -192 1964 -193 1959 -193 ct 1945 -193 1932 -189 1920 -181 ct +1907 -173 1895 -161 1883 -145 ct 1883 -145 1883 -145 1883 0 ct 1883 0 1883 0 1842 0 ct +p ef +2051 0 m 2051 0 2051 0 2051 -224 ct 2051 -224 2051 -224 2087 -224 ct 2087 -224 2087 -224 2084 -182 ct +2084 -182 2084 -182 2087 -182 ct 2095 -198 2104 -209 2113 -217 ct 2121 -225 2129 -229 2137 -229 ct +2148 -229 2156 -225 2163 -216 ct 2170 -208 2174 -196 2175 -182 ct 2175 -182 2175 -182 2178 -182 ct +2185 -198 2193 -209 2201 -217 ct 2210 -225 2219 -229 2229 -229 ct 2242 -229 2252 -224 2259 -213 ct +2266 -202 2269 -186 2269 -164 ct 2269 -164 2269 -164 2269 0 ct 2269 0 2269 0 2233 0 ct +2233 0 2233 0 2233 -162 ct 2233 -172 2232 -180 2230 -185 ct 2228 -190 2224 -193 2220 -193 ct +2214 -193 2207 -189 2200 -181 ct 2193 -173 2185 -160 2178 -144 ct 2178 -144 2178 -144 2178 0 ct +2178 0 2178 0 2142 0 ct 2142 0 2142 0 2142 -155 ct 2142 -167 2141 -177 2139 -183 ct +2136 -190 2133 -193 2129 -193 ct 2123 -193 2116 -188 2108 -179 ct 2100 -170 2093 -158 2087 -144 ct +2087 -144 2087 -144 2087 0 ct 2087 0 2087 0 2051 0 ct p ef +2512 -9 m 2484 0 2458 5 2434 5 ct 2396 5 2367 -5 2346 -25 ct 2325 -45 2315 -73 2315 -110 ct +2315 -144 2325 -173 2345 -195 ct 2365 -218 2390 -229 2421 -229 ct 2452 -229 2474 -220 2489 -201 ct +2504 -182 2511 -153 2511 -114 ct 2511 -114 2511 -114 2511 -101 ct 2511 -101 2511 -101 2357 -101 ct +2358 -76 2366 -57 2380 -45 ct 2394 -32 2413 -26 2439 -26 ct 2462 -26 2486 -31 2512 -42 ct +2512 -42 2512 -42 2512 -9 ct p +2358 -132 m 2358 -132 2358 -132 2468 -132 ct 2468 -132 2468 -132 2468 -138 ct +2468 -158 2464 -173 2455 -183 ct 2446 -193 2434 -198 2417 -198 ct 2400 -198 2387 -192 2376 -181 ct +2366 -169 2360 -153 2358 -132 ct p ef +2722 0 m 2722 0 2722 0 2724 -42 ct 2724 -42 2724 -42 2722 -42 ct 2712 -26 2701 -15 2689 -7 ct +2676 1 2663 5 2648 5 ct 2623 5 2603 -5 2588 -24 ct 2573 -44 2566 -71 2566 -105 ct +2566 -142 2575 -172 2592 -195 ct 2610 -218 2632 -229 2660 -229 ct 2672 -229 2684 -226 2694 -221 ct +2704 -216 2714 -209 2722 -198 ct 2722 -198 2722 -198 2724 -198 ct 2724 -198 2724 -198 2722 -229 ct +2722 -229 2722 -229 2722 -326 ct 2722 -326 2722 -326 2763 -326 ct 2763 -326 2763 -326 2763 0 ct +2763 0 2763 0 2722 0 ct p +2722 -168 m 2712 -178 2703 -185 2694 -190 ct 2684 -195 2675 -198 2666 -198 ct +2648 -198 2634 -190 2624 -175 ct 2614 -159 2609 -137 2609 -109 ct 2609 -83 2613 -63 2621 -50 ct +2629 -38 2640 -31 2656 -31 ct 2668 -31 2679 -35 2690 -42 ct 2701 -49 2712 -59 2722 -73 ct +2722 -73 2722 -73 2722 -168 ct p ef +3230 0 m 3230 0 3230 0 3232 -42 ct 3232 -42 3232 -42 3230 -42 ct 3220 -26 3209 -15 3197 -7 ct +3184 1 3171 5 3156 5 ct 3131 5 3111 -5 3096 -24 ct 3081 -44 3074 -71 3074 -105 ct +3074 -142 3083 -172 3100 -195 ct 3118 -218 3140 -229 3168 -229 ct 3180 -229 3192 -226 3202 -221 ct +3212 -216 3222 -209 3230 -198 ct 3230 -198 3230 -198 3232 -198 ct 3232 -198 3232 -198 3230 -229 ct +3230 -229 3230 -229 3230 -326 ct 3230 -326 3230 -326 3271 -326 ct 3271 -326 3271 -326 3271 0 ct +3271 0 3271 0 3230 0 ct p +3230 -168 m 3220 -178 3211 -185 3202 -190 ct 3192 -195 3183 -198 3174 -198 ct +3156 -198 3142 -190 3132 -175 ct 3122 -159 3117 -137 3117 -109 ct 3117 -83 3121 -63 3129 -50 ct +3137 -38 3148 -31 3164 -31 ct 3176 -31 3187 -35 3198 -42 ct 3209 -49 3220 -59 3230 -73 ct +3230 -73 3230 -73 3230 -168 ct p ef +3520 -224 m 3520 -224 3520 -224 3520 0 ct 3520 0 3520 0 3479 0 ct 3479 0 3479 0 3481 -42 ct +3481 -42 3481 -42 3479 -42 ct 3470 -26 3458 -15 3446 -7 ct 3433 1 3418 5 3402 5 ct +3381 5 3365 -1 3354 -14 ct 3343 -27 3338 -46 3338 -71 ct 3338 -71 3338 -71 3338 -224 ct +3338 -224 3338 -224 3379 -224 ct 3379 -224 3379 -224 3379 -82 ct 3379 -65 3382 -52 3387 -45 ct +3393 -38 3402 -34 3415 -34 ct 3425 -34 3435 -38 3446 -45 ct 3457 -52 3468 -63 3479 -78 ct +3479 -78 3479 -78 3479 -224 ct 3479 -224 3479 -224 3520 -224 ct p ef +3575 0 m 3575 0 3575 0 3575 -224 ct 3575 -224 3575 -224 3611 -224 ct 3611 -224 3611 -224 3608 -182 ct +3608 -182 3608 -182 3611 -182 ct 3619 -198 3628 -209 3637 -217 ct 3645 -225 3653 -229 3661 -229 ct +3672 -229 3680 -225 3687 -216 ct 3694 -208 3698 -196 3699 -182 ct 3699 -182 3699 -182 3702 -182 ct +3709 -198 3717 -209 3725 -217 ct 3734 -225 3743 -229 3753 -229 ct 3766 -229 3776 -224 3783 -213 ct +3790 -202 3793 -186 3793 -164 ct 3793 -164 3793 -164 3793 0 ct 3793 0 3793 0 3757 0 ct +3757 0 3757 0 3757 -162 ct 3757 -172 3756 -180 3754 -185 ct 3752 -190 3748 -193 3744 -193 ct +3738 -193 3731 -189 3724 -181 ct 3717 -173 3709 -160 3702 -144 ct 3702 -144 3702 -144 3702 0 ct +3702 0 3702 0 3666 0 ct 3666 0 3666 0 3666 -155 ct 3666 -167 3665 -177 3663 -183 ct +3660 -190 3657 -193 3653 -193 ct 3647 -193 3640 -188 3632 -179 ct 3624 -170 3617 -158 3611 -144 ct +3611 -144 3611 -144 3611 0 ct 3611 0 3611 0 3575 0 ct p ef +3847 82 m 3847 82 3847 82 3847 -224 ct 3847 -224 3847 -224 3888 -224 ct 3888 -224 3888 -224 3886 -182 ct +3886 -182 3886 -182 3888 -182 ct 3898 -198 3909 -209 3921 -217 ct 3933 -225 3947 -229 3961 -229 ct +3986 -229 4006 -219 4021 -200 ct 4036 -180 4043 -153 4043 -120 ct 4043 -82 4034 -52 4017 -29 ct +4000 -6 3977 5 3949 5 ct 3937 5 3926 2 3916 -3 ct 3906 -8 3896 -15 3888 -26 ct +3888 -26 3888 -26 3886 -26 ct 3886 -26 3886 -26 3888 5 ct 3888 5 3888 5 3888 82 ct +3888 82 3888 82 3847 82 ct p +3888 -56 m 3897 -46 3907 -39 3916 -34 ct 3925 -29 3934 -26 3944 -26 ct 3962 -26 3975 -34 3985 -49 ct +3995 -65 4000 -87 4000 -115 ct 4000 -141 3996 -160 3988 -173 ct 3980 -186 3969 -193 3953 -193 ct +3942 -193 3930 -189 3919 -182 ct 3909 -175 3898 -165 3888 -151 ct 3888 -151 3888 -151 3888 -56 ct +p ef +pom +gr +gs +pum +7784 15450 t +466 -326 m 466 -326 466 -326 466 -295 ct 466 -295 466 -295 450 -295 ct 429 -295 415 -293 407 -287 ct +398 -282 394 -274 394 -261 ct 394 -257 395 -251 396 -242 ct 396 -242 396 -242 400 -214 ct +401 -204 402 -196 402 -190 ct 402 -175 399 -163 392 -153 ct 385 -144 375 -137 361 -132 ct +375 -128 385 -121 392 -111 ct 399 -102 402 -90 402 -75 ct 402 -68 401 -61 400 -51 ct +400 -51 400 -51 396 -23 ct 395 -14 394 -8 394 -4 ct 394 9 398 17 407 22 ct 415 27 429 30 450 30 ct +450 30 450 30 466 30 ct 466 30 466 30 466 61 ct 466 61 466 61 443 61 ct 414 61 392 56 378 46 ct +363 36 356 21 356 2 ct 356 -7 357 -16 359 -26 ct 359 -26 359 -26 366 -63 ct 367 -68 367 -74 367 -79 ct +367 -92 363 -101 355 -108 ct 348 -114 336 -117 321 -117 ct 321 -117 321 -117 302 -117 ct +302 -117 302 -117 302 -148 ct 302 -148 302 -148 321 -148 ct 336 -148 348 -151 355 -157 ct +363 -164 367 -173 367 -186 ct 367 -191 367 -197 366 -202 ct 366 -202 366 -202 359 -239 ct +357 -249 356 -258 356 -267 ct 356 -286 363 -301 378 -311 ct 392 -321 414 -326 443 -326 ct +443 -326 443 -326 466 -326 ct p ef +pom +gr +gs +pum +1942 15941 t +pom +gr +gs +pum +2958 15941 t +0.003 0.503 0.003 c 239 -326 m 65 61 l 15 61 l 189 -326 l 239 -326 l +p ef +493 -326 m 319 61 l 269 61 l 443 -326 l 493 -326 l p ef +791 0 m 791 0 791 0 791 -224 ct 791 -224 791 -224 852 -224 ct 852 -224 852 -224 851 -202 ct +851 -202 851 -202 850 -181 ct 850 -181 850 -181 852 -181 ct 859 -197 868 -209 880 -217 ct +892 -225 906 -229 924 -229 ct 946 -229 962 -223 973 -210 ct 984 -197 990 -178 990 -153 ct +990 -153 990 -153 990 0 ct 990 0 990 0 929 0 ct 929 0 929 0 929 -139 ct 929 -150 927 -159 923 -165 ct +918 -170 912 -173 903 -173 ct 894 -173 885 -170 876 -165 ct 868 -159 859 -151 852 -139 ct +852 -139 852 -139 852 0 ct 852 0 852 0 791 0 ct p ef +1252 -95 m 1252 -95 1252 -95 1100 -95 ct 1103 -77 1111 -63 1123 -54 ct 1135 -45 1151 -41 1172 -41 ct +1196 -41 1223 -46 1252 -56 ct 1252 -56 1252 -56 1252 -9 ct 1217 0 1186 5 1160 5 ct +1122 5 1091 -6 1068 -27 ct 1045 -48 1034 -76 1034 -111 ct 1034 -147 1045 -175 1066 -197 ct +1088 -218 1116 -229 1151 -229 ct 1183 -229 1207 -219 1225 -199 ct 1243 -180 1252 -152 1252 -118 ct +1252 -118 1252 -118 1252 -95 ct p +1099 -136 m 1099 -136 1099 -136 1193 -136 ct 1193 -153 1189 -166 1182 -175 ct +1174 -184 1163 -188 1148 -188 ct 1134 -188 1122 -184 1114 -175 ct 1106 -166 1101 -153 1099 -136 ct +p ef +1506 -95 m 1506 -95 1506 -95 1354 -95 ct 1357 -77 1365 -63 1377 -54 ct 1389 -45 1405 -41 1426 -41 ct +1450 -41 1477 -46 1506 -56 ct 1506 -56 1506 -56 1506 -9 ct 1471 0 1440 5 1414 5 ct +1376 5 1345 -6 1322 -27 ct 1299 -48 1288 -76 1288 -111 ct 1288 -147 1299 -175 1320 -197 ct +1342 -218 1370 -229 1405 -229 ct 1437 -229 1461 -219 1479 -199 ct 1497 -180 1506 -152 1506 -118 ct +1506 -118 1506 -118 1506 -95 ct p +1353 -136 m 1353 -136 1353 -136 1447 -136 ct 1447 -153 1443 -166 1436 -175 ct +1428 -184 1417 -188 1402 -188 ct 1388 -188 1376 -184 1368 -175 ct 1360 -166 1355 -153 1353 -136 ct +p ef +1698 0 m 1698 0 1698 0 1700 -42 ct 1700 -42 1700 -42 1698 -42 ct 1688 -27 1677 -15 1665 -7 ct +1654 1 1641 5 1627 5 ct 1601 5 1581 -5 1565 -26 ct 1550 -46 1542 -73 1542 -107 ct +1542 -144 1551 -174 1568 -196 ct 1585 -218 1608 -229 1637 -229 ct 1649 -229 1660 -227 1670 -222 ct +1680 -218 1689 -211 1698 -203 ct 1698 -203 1698 -203 1700 -203 ct 1700 -203 1700 -203 1698 -224 ct +1698 -224 1698 -224 1698 -326 ct 1698 -326 1698 -326 1759 -326 ct 1759 -326 1759 -326 1759 0 ct +1759 0 1759 0 1698 0 ct p +1698 -160 m 1691 -168 1684 -173 1677 -177 ct 1670 -181 1662 -183 1654 -183 ct +1638 -183 1627 -177 1619 -164 ct 1612 -152 1608 -133 1608 -108 ct 1608 -89 1611 -75 1618 -65 ct +1625 -56 1635 -51 1648 -51 ct 1657 -51 1665 -54 1674 -60 ct 1682 -66 1690 -75 1698 -88 ct +1698 -88 1698 -88 1698 -160 ct p ef +1811 -8 m 1811 -8 1811 -8 1811 -54 ct 1845 -42 1873 -36 1893 -36 ct 1908 -36 1919 -38 1927 -42 ct +1934 -46 1938 -52 1938 -60 ct 1938 -64 1936 -68 1932 -72 ct 1929 -75 1923 -79 1916 -82 ct +1916 -82 1916 -82 1868 -101 ct 1849 -109 1835 -118 1826 -127 ct 1817 -137 1812 -148 1812 -161 ct +1812 -182 1822 -199 1841 -211 ct 1860 -223 1887 -229 1921 -229 ct 1941 -229 1964 -226 1990 -221 ct +1990 -221 1990 -221 1990 -174 ct 1962 -183 1938 -188 1919 -188 ct 1904 -188 1894 -186 1887 -183 ct +1880 -180 1876 -175 1876 -169 ct 1876 -165 1879 -162 1884 -158 ct 1889 -154 1896 -150 1906 -146 ct +1906 -146 1906 -146 1959 -124 ct 1975 -118 1987 -110 1994 -100 ct 2002 -91 2006 -79 2006 -66 ct +2006 -45 1997 -28 1978 -15 ct 1959 -2 1935 5 1905 5 ct 1879 5 1847 1 1811 -8 ct +p ef +2319 -8 m 2319 -8 2319 -8 2319 -54 ct 2353 -42 2381 -36 2401 -36 ct 2416 -36 2427 -38 2435 -42 ct +2442 -46 2446 -52 2446 -60 ct 2446 -64 2444 -68 2440 -72 ct 2437 -75 2431 -79 2424 -82 ct +2424 -82 2424 -82 2376 -101 ct 2357 -109 2343 -118 2334 -127 ct 2325 -137 2320 -148 2320 -161 ct +2320 -182 2330 -199 2349 -211 ct 2368 -223 2395 -229 2429 -229 ct 2449 -229 2472 -226 2498 -221 ct +2498 -221 2498 -221 2498 -174 ct 2470 -183 2446 -188 2427 -188 ct 2412 -188 2402 -186 2395 -183 ct +2388 -180 2384 -175 2384 -169 ct 2384 -165 2387 -162 2392 -158 ct 2397 -154 2404 -150 2414 -146 ct +2414 -146 2414 -146 2467 -124 ct 2483 -118 2495 -110 2502 -100 ct 2510 -91 2514 -79 2514 -66 ct +2514 -45 2505 -28 2486 -15 ct 2467 -2 2443 5 2413 5 ct 2387 5 2355 1 2319 -8 ct +p ef +2768 -6 m 2744 1 2722 5 2704 5 ct 2675 5 2654 -1 2640 -14 ct 2626 -26 2619 -45 2619 -70 ct +2619 -70 2619 -70 2619 -178 ct 2619 -178 2619 -178 2571 -178 ct 2571 -178 2571 -178 2571 -219 ct +2571 -219 2571 -219 2619 -219 ct 2619 -219 2619 -219 2619 -285 ct 2619 -285 2619 -285 2680 -285 ct +2680 -285 2680 -285 2680 -219 ct 2680 -219 2680 -219 2763 -219 ct 2763 -219 2763 -219 2763 -178 ct +2763 -178 2763 -178 2680 -178 ct 2680 -178 2680 -178 2680 -84 ct 2680 -68 2683 -57 2689 -51 ct +2695 -44 2705 -41 2719 -41 ct 2736 -41 2752 -44 2768 -51 ct 2768 -51 2768 -51 2768 -6 ct +p ef +2968 0 m 2968 0 2968 0 2970 -42 ct 2970 -42 2970 -42 2968 -42 ct 2958 -27 2947 -15 2935 -7 ct +2924 1 2911 5 2897 5 ct 2871 5 2851 -5 2835 -26 ct 2820 -46 2812 -73 2812 -107 ct +2812 -144 2821 -174 2838 -196 ct 2855 -218 2878 -229 2907 -229 ct 2919 -229 2930 -227 2940 -222 ct +2950 -218 2959 -211 2968 -203 ct 2968 -203 2968 -203 2970 -203 ct 2970 -203 2970 -203 2968 -224 ct +2968 -224 2968 -224 2968 -326 ct 2968 -326 2968 -326 3029 -326 ct 3029 -326 3029 -326 3029 0 ct +3029 0 3029 0 2968 0 ct p +2968 -160 m 2961 -168 2954 -173 2947 -177 ct 2940 -181 2932 -183 2924 -183 ct +2908 -183 2897 -177 2889 -164 ct 2882 -152 2878 -133 2878 -108 ct 2878 -89 2881 -75 2888 -65 ct +2895 -56 2905 -51 2918 -51 ct 2927 -51 2935 -54 2944 -60 ct 2952 -66 2960 -75 2968 -88 ct +2968 -88 2968 -88 2968 -160 ct p ef +3170 0 m 3170 -183 l 3088 -183 l 3088 -224 l 3231 -224 l 3231 0 l +3170 0 l p +3170 -265 m 3170 -326 l 3231 -326 l 3231 -265 l 3170 -265 l p ef +3428 5 m 3394 5 3366 -6 3345 -27 ct 3324 -49 3313 -77 3313 -112 ct 3313 -148 3324 -176 3345 -197 ct +3366 -218 3394 -229 3430 -229 ct 3465 -229 3493 -218 3514 -197 ct 3535 -176 3546 -148 3546 -112 ct +3546 -76 3535 -48 3514 -27 ct 3493 -6 3464 5 3428 5 ct p +3429 -36 m 3446 -36 3459 -42 3467 -55 ct 3476 -68 3480 -87 3480 -112 ct 3480 -138 3476 -156 3467 -169 ct +3459 -182 3446 -188 3430 -188 ct 3413 -188 3400 -182 3392 -169 ct 3383 -156 3379 -137 3379 -112 ct +3379 -87 3383 -68 3391 -55 ct 3400 -42 3412 -36 3429 -36 ct p ef +pom +gr +gs +pum +1942 16432 t +pom +gr +gs +pum +2450 16432 t +43 -326 m 43 -326 43 -326 43 -295 ct 43 -295 43 -295 59 -295 ct 80 -295 94 -293 102 -287 ct +111 -282 115 -274 115 -261 ct 115 -257 114 -251 113 -242 ct 113 -242 113 -242 109 -214 ct +108 -204 107 -196 107 -190 ct 107 -175 110 -163 117 -153 ct 124 -144 134 -137 148 -132 ct +134 -128 124 -121 117 -111 ct 110 -102 107 -90 107 -75 ct 107 -68 108 -61 109 -51 ct +109 -51 109 -51 113 -23 ct 114 -14 115 -8 115 -4 ct 115 9 111 17 102 22 ct 94 27 80 30 59 30 ct +59 30 59 30 43 30 ct 43 30 43 30 43 61 ct 43 61 43 61 66 61 ct 95 61 117 56 131 46 ct +146 36 153 21 153 2 ct 153 -7 152 -16 150 -26 ct 150 -26 150 -26 143 -63 ct 142 -68 142 -74 142 -79 ct +142 -92 146 -101 154 -108 ct 161 -114 173 -117 188 -117 ct 188 -117 188 -117 207 -117 ct +207 -117 207 -117 207 -148 ct 207 -148 207 -148 188 -148 ct 173 -148 161 -151 154 -157 ct +146 -164 142 -173 142 -186 ct 142 -191 142 -197 143 -202 ct 143 -202 143 -202 150 -239 ct +152 -249 153 -258 153 -267 ct 153 -286 146 -301 131 -311 ct 117 -321 95 -326 66 -326 ct +66 -326 66 -326 43 -326 ct p ef +pom +gr +gs +pum +1942 16923 t +0.003 0.003 1.000 c 24 82 m 24 82 24 82 24 -224 ct 24 -224 24 -224 85 -224 ct +85 -224 85 -224 83 -182 ct 83 -182 83 -182 85 -182 ct 95 -197 106 -209 117 -217 ct +129 -225 142 -229 156 -229 ct 182 -229 202 -219 218 -198 ct 233 -178 241 -151 241 -117 ct +241 -80 232 -50 215 -28 ct 198 -6 175 5 146 5 ct 134 5 122 3 112 -2 ct 102 -6 93 -13 85 -22 ct +85 -22 85 -22 83 -22 ct 83 -22 83 -22 85 0 ct 85 0 85 0 85 82 ct 85 82 85 82 24 82 ct +p +85 -64 m 92 -56 99 -50 106 -47 ct 113 -43 121 -41 130 -41 ct 145 -41 156 -47 164 -60 ct +171 -72 175 -91 175 -116 ct 175 -135 172 -149 165 -159 ct 158 -168 149 -173 135 -173 ct +127 -173 118 -170 109 -164 ct 101 -158 93 -149 85 -136 ct 85 -136 85 -136 85 -64 ct +p ef +480 -224 m 480 -224 480 -224 480 0 ct 480 0 480 0 419 0 ct 419 0 419 0 420 -22 ct +420 -22 420 -22 422 -43 ct 422 -43 422 -43 419 -43 ct 413 -27 404 -15 392 -7 ct +380 1 365 5 348 5 ct 326 5 309 -1 298 -14 ct 287 -27 281 -46 281 -71 ct 281 -71 281 -71 281 -224 ct +281 -224 281 -224 342 -224 ct 342 -224 342 -224 342 -85 ct 342 -73 344 -65 348 -59 ct +353 -54 359 -51 368 -51 ct 377 -51 386 -54 395 -59 ct 403 -65 411 -73 419 -85 ct +419 -85 419 -85 419 -224 ct 419 -224 419 -224 480 -224 ct p ef +533 0 m 533 0 533 0 533 -326 ct 533 -326 533 -326 594 -326 ct 594 -326 594 -326 594 -224 ct +594 -224 594 -224 592 -182 ct 592 -182 592 -182 594 -182 ct 604 -197 615 -209 626 -217 ct +638 -225 651 -229 665 -229 ct 691 -229 711 -219 727 -198 ct 742 -178 750 -151 750 -117 ct +750 -80 741 -50 724 -28 ct 707 -6 684 5 655 5 ct 643 5 631 3 621 -2 ct 611 -6 602 -13 594 -22 ct +594 -22 594 -22 592 -22 ct 592 -22 592 -22 584 0 ct 584 0 584 0 533 0 ct p +594 -64 m 601 -56 608 -50 615 -47 ct 622 -43 630 -41 639 -41 ct 654 -41 665 -47 673 -60 ct +680 -72 684 -91 684 -116 ct 684 -135 681 -149 674 -159 ct 667 -168 658 -173 644 -173 ct +636 -173 627 -170 618 -164 ct 610 -158 602 -149 594 -136 ct 594 -136 594 -136 594 -64 ct +p ef +864 0 m 864 -285 l 782 -285 l 782 -326 l 925 -326 l 925 0 l 864 0 l +p ef +1138 0 m 1138 -183 l 1056 -183 l 1056 -224 l 1199 -224 l 1199 0 l +1138 0 l p +1138 -265 m 1138 -326 l 1199 -326 l 1199 -265 l 1138 -265 l p ef +1497 -4 m 1472 2 1447 5 1422 5 ct 1381 5 1348 -5 1325 -26 ct 1302 -47 1290 -75 1290 -111 ct +1290 -148 1301 -177 1324 -198 ct 1346 -219 1378 -229 1418 -229 ct 1448 -229 1474 -226 1497 -220 ct +1497 -220 1497 -220 1497 -175 ct 1472 -184 1449 -188 1426 -188 ct 1404 -188 1387 -182 1375 -169 ct +1362 -157 1356 -140 1356 -118 ct 1356 -94 1364 -74 1379 -60 ct 1394 -45 1414 -38 1439 -38 ct +1458 -38 1478 -42 1497 -49 ct 1497 -49 1497 -49 1497 -4 ct p ef +pom +gr +gs +pum +3466 16923 t +97 -163 m 97 -224 l 158 -224 l 158 -163 l 97 -163 l p +97 0 m 97 -61 l 158 -61 l 158 0 l 97 0 l p ef +pom +gr +gs +pum +1942 17414 t +pom +gr +gs +pum +2450 17414 t +0.003 0.003 1.000 c 98 0 m 9 -224 l 75 -224 l 137 -67 l 198 -224 l 247 -224 l +159 0 l 98 0 l p ef +380 5 m 346 5 318 -6 297 -27 ct 276 -49 265 -77 265 -112 ct 265 -148 276 -176 297 -197 ct +318 -218 346 -229 382 -229 ct 417 -229 445 -218 466 -197 ct 487 -176 498 -148 498 -112 ct +498 -76 487 -48 466 -27 ct 445 -6 416 5 380 5 ct p +381 -36 m 398 -36 411 -42 419 -55 ct 428 -68 432 -87 432 -112 ct 432 -138 428 -156 419 -169 ct +411 -182 398 -188 382 -188 ct 365 -188 352 -182 344 -169 ct 335 -156 331 -137 331 -112 ct +331 -87 335 -68 343 -55 ct 352 -42 364 -36 381 -36 ct p ef +630 0 m 630 -183 l 548 -183 l 548 -224 l 691 -224 l 691 0 l 630 0 l +p +630 -265 m 630 -326 l 691 -326 l 691 -265 l 630 -265 l p ef +936 0 m 936 0 936 0 938 -42 ct 938 -42 938 -42 936 -42 ct 926 -27 915 -15 903 -7 ct +892 1 879 5 865 5 ct 839 5 819 -5 803 -26 ct 788 -46 780 -73 780 -107 ct 780 -144 789 -174 806 -196 ct +823 -218 846 -229 875 -229 ct 887 -229 898 -227 908 -222 ct 918 -218 927 -211 936 -203 ct +936 -203 936 -203 938 -203 ct 938 -203 938 -203 936 -224 ct 936 -224 936 -224 936 -326 ct +936 -326 936 -326 997 -326 ct 997 -326 997 -326 997 0 ct 997 0 997 0 936 0 ct p +936 -160 m 929 -168 922 -173 915 -177 ct 908 -181 900 -183 892 -183 ct 876 -183 865 -177 857 -164 ct +850 -152 846 -133 846 -108 ct 846 -89 849 -75 856 -65 ct 863 -56 873 -51 886 -51 ct +895 -51 903 -54 912 -60 ct 920 -66 928 -75 936 -88 ct 936 -88 936 -88 936 -160 ct +p ef +pom +gr +gs +pum +3466 17414 t +pom +gr +gs +pum +3720 17414 t +228 0 m 208 3 188 5 169 5 ct 136 5 113 -1 101 -13 ct 89 -25 83 -47 83 -80 ct 83 -80 83 -80 83 -188 ct +83 -188 83 -188 27 -188 ct 27 -188 27 -188 27 -219 ct 27 -219 27 -219 83 -219 ct +83 -219 83 -219 83 -267 ct 83 -267 83 -267 124 -267 ct 124 -267 124 -267 124 -219 ct +124 -219 124 -219 223 -219 ct 223 -219 223 -219 223 -188 ct 223 -188 223 -188 124 -188 ct +124 -188 124 -188 124 -74 ct 124 -61 125 -53 126 -48 ct 128 -43 131 -39 137 -35 ct +146 -29 159 -26 177 -26 ct 194 -26 211 -28 228 -31 ct 228 -31 228 -31 228 0 ct +p ef +318 0 m 318 0 318 0 318 -224 ct 318 -224 318 -224 359 -224 ct 359 -224 359 -224 357 -182 ct +357 -182 357 -182 359 -182 ct 369 -198 381 -209 395 -217 ct 409 -225 424 -229 442 -229 ct +454 -229 468 -227 483 -224 ct 483 -224 483 -224 483 -160 ct 483 -160 483 -160 452 -160 ct +452 -160 452 -160 452 -191 ct 446 -192 440 -193 435 -193 ct 421 -193 408 -189 396 -181 ct +383 -173 371 -161 359 -145 ct 359 -145 359 -145 359 0 ct 359 0 359 0 318 0 ct p ef +680 -26 m 656 -5 631 5 607 5 ct 586 5 569 -1 556 -13 ct 543 -24 536 -39 536 -57 ct +536 -81 546 -99 567 -114 ct 588 -128 615 -135 649 -135 ct 649 -135 649 -135 674 -135 ct +674 -135 674 -135 674 -154 ct 674 -169 670 -180 663 -187 ct 655 -194 644 -198 629 -198 ct +605 -198 580 -191 555 -177 ct 555 -177 555 -177 555 -213 ct 584 -224 611 -229 637 -229 ct +666 -229 686 -223 697 -212 ct 709 -201 715 -181 715 -153 ct 715 -153 715 -153 715 -59 ct +715 -45 716 -36 719 -31 ct 722 -26 728 -24 735 -24 ct 738 -24 742 -25 748 -26 ct +748 -26 748 -26 752 -2 ct 738 3 728 5 721 5 ct 711 5 702 2 696 -3 ct 689 -8 684 -16 680 -26 ct +p +674 -53 m 674 -53 674 -53 674 -110 ct 674 -110 674 -110 662 -110 ct 634 -110 613 -106 599 -99 ct +585 -91 578 -80 578 -64 ct 578 -52 581 -43 588 -37 ct 594 -31 604 -28 617 -28 ct +635 -28 654 -36 674 -53 ct p ef +799 0 m 799 0 799 0 799 -224 ct 799 -224 799 -224 840 -224 ct 840 -224 840 -224 838 -182 ct +838 -182 838 -182 840 -182 ct 850 -198 861 -209 874 -217 ct 886 -225 901 -229 917 -229 ct +938 -229 954 -223 965 -210 ct 976 -197 981 -178 981 -153 ct 981 -153 981 -153 981 0 ct +981 0 981 0 940 0 ct 940 0 940 0 940 -142 ct 940 -159 937 -172 932 -179 ct 926 -186 917 -190 904 -190 ct +894 -190 884 -186 873 -179 ct 862 -172 851 -161 840 -146 ct 840 -146 840 -146 840 0 ct +840 0 840 0 799 0 ct p ef +1055 -9 m 1055 -9 1055 -9 1055 -45 ct 1086 -32 1113 -26 1136 -26 ct 1152 -26 1166 -29 1177 -36 ct +1188 -43 1193 -51 1193 -61 ct 1193 -74 1180 -84 1155 -93 ct 1155 -93 1155 -93 1112 -107 ct +1078 -118 1061 -138 1061 -165 ct 1061 -186 1069 -201 1084 -212 ct 1099 -223 1121 -229 1149 -229 ct +1170 -229 1194 -226 1222 -219 ct 1222 -219 1222 -219 1222 -186 ct 1195 -194 1171 -198 1149 -198 ct +1133 -198 1120 -196 1112 -191 ct 1104 -186 1100 -179 1100 -169 ct 1100 -158 1110 -149 1130 -142 ct +1130 -142 1130 -142 1182 -124 ct 1217 -111 1234 -91 1234 -64 ct 1234 -43 1225 -26 1208 -14 ct +1190 -1 1167 5 1137 5 ct 1112 5 1084 0 1055 -9 ct p ef +1362 0 m 1362 0 1362 0 1362 -188 ct 1362 -188 1362 -188 1301 -188 ct 1301 -188 1301 -188 1301 -219 ct +1301 -219 1301 -219 1362 -219 ct 1362 -219 1362 -219 1362 -243 ct 1362 -274 1369 -297 1384 -310 ct +1398 -324 1422 -331 1456 -331 ct 1478 -331 1498 -328 1518 -322 ct 1518 -322 1518 -322 1518 -289 ct +1498 -296 1478 -300 1459 -300 ct 1438 -300 1424 -296 1415 -288 ct 1407 -280 1403 -267 1403 -247 ct +1403 -247 1403 -247 1403 -219 ct 1403 -219 1403 -219 1510 -219 ct 1510 -219 1510 -219 1510 -188 ct +1510 -188 1510 -188 1403 -188 ct 1403 -188 1403 -188 1403 0 ct 1403 0 1403 0 1362 0 ct +p ef +1650 5 m 1618 5 1593 -6 1574 -27 ct 1555 -48 1546 -76 1546 -112 ct 1546 -148 1555 -177 1574 -198 ct +1593 -219 1619 -229 1652 -229 ct 1684 -229 1710 -219 1729 -198 ct 1748 -177 1757 -149 1757 -113 ct +1757 -76 1748 -47 1729 -26 ct 1710 -5 1684 5 1650 5 ct p +1651 -26 m 1672 -26 1688 -33 1698 -48 ct 1709 -62 1714 -84 1714 -113 ct 1714 -139 1708 -160 1697 -175 ct +1686 -190 1671 -198 1652 -198 ct 1632 -198 1617 -190 1606 -175 ct 1595 -160 1589 -139 1589 -112 ct +1589 -85 1594 -64 1605 -49 ct 1616 -34 1632 -26 1651 -26 ct p ef +1842 0 m 1842 0 1842 0 1842 -224 ct 1842 -224 1842 -224 1883 -224 ct 1883 -224 1883 -224 1881 -182 ct +1881 -182 1881 -182 1883 -182 ct 1893 -198 1905 -209 1919 -217 ct 1933 -225 1948 -229 1966 -229 ct +1978 -229 1992 -227 2007 -224 ct 2007 -224 2007 -224 2007 -160 ct 2007 -160 2007 -160 1976 -160 ct +1976 -160 1976 -160 1976 -191 ct 1970 -192 1964 -193 1959 -193 ct 1945 -193 1932 -189 1920 -181 ct +1907 -173 1895 -161 1883 -145 ct 1883 -145 1883 -145 1883 0 ct 1883 0 1883 0 1842 0 ct +p ef +2051 0 m 2051 0 2051 0 2051 -224 ct 2051 -224 2051 -224 2087 -224 ct 2087 -224 2087 -224 2084 -182 ct +2084 -182 2084 -182 2087 -182 ct 2095 -198 2104 -209 2113 -217 ct 2121 -225 2129 -229 2137 -229 ct +2148 -229 2156 -225 2163 -216 ct 2170 -208 2174 -196 2175 -182 ct 2175 -182 2175 -182 2178 -182 ct +2185 -198 2193 -209 2201 -217 ct 2210 -225 2219 -229 2229 -229 ct 2242 -229 2252 -224 2259 -213 ct +2266 -202 2269 -186 2269 -164 ct 2269 -164 2269 -164 2269 0 ct 2269 0 2269 0 2233 0 ct +2233 0 2233 0 2233 -162 ct 2233 -172 2232 -180 2230 -185 ct 2228 -190 2224 -193 2220 -193 ct +2214 -193 2207 -189 2200 -181 ct 2193 -173 2185 -160 2178 -144 ct 2178 -144 2178 -144 2178 0 ct +2178 0 2178 0 2142 0 ct 2142 0 2142 0 2142 -155 ct 2142 -167 2141 -177 2139 -183 ct +2136 -190 2133 -193 2129 -193 ct 2123 -193 2116 -188 2108 -179 ct 2100 -170 2093 -158 2087 -144 ct +2087 -144 2087 -144 2087 0 ct 2087 0 2087 0 2051 0 ct p ef +2512 -9 m 2484 0 2458 5 2434 5 ct 2396 5 2367 -5 2346 -25 ct 2325 -45 2315 -73 2315 -110 ct +2315 -144 2325 -173 2345 -195 ct 2365 -218 2390 -229 2421 -229 ct 2452 -229 2474 -220 2489 -201 ct +2504 -182 2511 -153 2511 -114 ct 2511 -114 2511 -114 2511 -101 ct 2511 -101 2511 -101 2357 -101 ct +2358 -76 2366 -57 2380 -45 ct 2394 -32 2413 -26 2439 -26 ct 2462 -26 2486 -31 2512 -42 ct +2512 -42 2512 -42 2512 -9 ct p +2358 -132 m 2358 -132 2358 -132 2468 -132 ct 2468 -132 2468 -132 2468 -138 ct +2468 -158 2464 -173 2455 -183 ct 2446 -193 2434 -198 2417 -198 ct 2400 -198 2387 -192 2376 -181 ct +2366 -169 2360 -153 2358 -132 ct p ef +2722 0 m 2722 0 2722 0 2724 -42 ct 2724 -42 2724 -42 2722 -42 ct 2712 -26 2701 -15 2689 -7 ct +2676 1 2663 5 2648 5 ct 2623 5 2603 -5 2588 -24 ct 2573 -44 2566 -71 2566 -105 ct +2566 -142 2575 -172 2592 -195 ct 2610 -218 2632 -229 2660 -229 ct 2672 -229 2684 -226 2694 -221 ct +2704 -216 2714 -209 2722 -198 ct 2722 -198 2722 -198 2724 -198 ct 2724 -198 2724 -198 2722 -229 ct +2722 -229 2722 -229 2722 -326 ct 2722 -326 2722 -326 2763 -326 ct 2763 -326 2763 -326 2763 0 ct +2763 0 2763 0 2722 0 ct p +2722 -168 m 2712 -178 2703 -185 2694 -190 ct 2684 -195 2675 -198 2666 -198 ct +2648 -198 2634 -190 2624 -175 ct 2614 -159 2609 -137 2609 -109 ct 2609 -83 2613 -63 2621 -50 ct +2629 -38 2640 -31 2656 -31 ct 2668 -31 2679 -35 2690 -42 ct 2701 -49 2712 -59 2722 -73 ct +2722 -73 2722 -73 2722 -168 ct p ef +3140 0 m 3140 0 3140 0 3140 -188 ct 3140 -188 3140 -188 3079 -188 ct 3079 -188 3079 -188 3079 -219 ct +3079 -219 3079 -219 3140 -219 ct 3140 -219 3140 -219 3140 -243 ct 3140 -274 3147 -297 3162 -310 ct +3176 -324 3200 -331 3234 -331 ct 3256 -331 3276 -328 3296 -322 ct 3296 -322 3296 -322 3296 -289 ct +3276 -296 3256 -300 3237 -300 ct 3216 -300 3202 -296 3193 -288 ct 3185 -280 3181 -267 3181 -247 ct +3181 -247 3181 -247 3181 -219 ct 3181 -219 3181 -219 3288 -219 ct 3288 -219 3288 -219 3288 -188 ct +3288 -188 3288 -188 3181 -188 ct 3181 -188 3181 -188 3181 0 ct 3181 0 3181 0 3140 0 ct +p ef +pom +gr +gs +pum +7022 17414 t +466 -326 m 466 -326 466 -326 466 -295 ct 466 -295 466 -295 450 -295 ct 429 -295 415 -293 407 -287 ct +398 -282 394 -274 394 -261 ct 394 -257 395 -251 396 -242 ct 396 -242 396 -242 400 -214 ct +401 -204 402 -196 402 -190 ct 402 -175 399 -163 392 -153 ct 385 -144 375 -137 361 -132 ct +375 -128 385 -121 392 -111 ct 399 -102 402 -90 402 -75 ct 402 -68 401 -61 400 -51 ct +400 -51 400 -51 396 -23 ct 395 -14 394 -8 394 -4 ct 394 9 398 17 407 22 ct 415 27 429 30 450 30 ct +450 30 450 30 466 30 ct 466 30 466 30 466 61 ct 466 61 466 61 443 61 ct 414 61 392 56 378 46 ct +363 36 356 21 356 2 ct 356 -7 357 -16 359 -26 ct 359 -26 359 -26 366 -63 ct 367 -68 367 -74 367 -79 ct +367 -92 363 -101 355 -108 ct 348 -114 336 -117 321 -117 ct 321 -117 321 -117 302 -117 ct +302 -117 302 -117 302 -148 ct 302 -148 302 -148 321 -148 ct 336 -148 348 -151 355 -157 ct +363 -164 367 -173 367 -186 ct 367 -191 367 -197 366 -202 ct 366 -202 366 -202 359 -239 ct +357 -249 356 -258 356 -267 ct 356 -286 363 -301 378 -311 ct 392 -321 414 -326 443 -326 ct +443 -326 443 -326 466 -326 ct p ef +pom +gr +gs +pum +1942 17905 t +pom +gr +gs +pum +2958 17905 t +0.003 0.503 0.003 c 239 -326 m 65 61 l 15 61 l 189 -326 l 239 -326 l +p ef +493 -326 m 319 61 l 269 61 l 443 -326 l 493 -326 l p ef +936 0 m 936 0 936 0 938 -42 ct 938 -42 938 -42 936 -42 ct 926 -27 915 -15 903 -7 ct +892 1 879 5 865 5 ct 839 5 819 -5 803 -26 ct 788 -46 780 -73 780 -107 ct 780 -144 789 -174 806 -196 ct +823 -218 846 -229 875 -229 ct 887 -229 898 -227 908 -222 ct 918 -218 927 -211 936 -203 ct +936 -203 936 -203 938 -203 ct 938 -203 938 -203 936 -224 ct 936 -224 936 -224 936 -326 ct +936 -326 936 -326 997 -326 ct 997 -326 997 -326 997 0 ct 997 0 997 0 936 0 ct p +936 -160 m 929 -168 922 -173 915 -177 ct 908 -181 900 -183 892 -183 ct 876 -183 865 -177 857 -164 ct +850 -152 846 -133 846 -108 ct 846 -89 849 -75 856 -65 ct 863 -56 873 -51 886 -51 ct +895 -51 903 -54 912 -60 ct 920 -66 928 -75 936 -88 ct 936 -88 936 -88 936 -160 ct +p ef +1142 5 m 1108 5 1080 -6 1059 -27 ct 1038 -49 1027 -77 1027 -112 ct 1027 -148 1038 -176 1059 -197 ct +1080 -218 1108 -229 1144 -229 ct 1179 -229 1207 -218 1228 -197 ct 1249 -176 1260 -148 1260 -112 ct +1260 -76 1249 -48 1228 -27 ct 1207 -6 1178 5 1142 5 ct p +1143 -36 m 1160 -36 1173 -42 1181 -55 ct 1190 -68 1194 -87 1194 -112 ct 1194 -138 1190 -156 1181 -169 ct +1173 -182 1160 -188 1144 -188 ct 1127 -188 1114 -182 1106 -169 ct 1097 -156 1093 -137 1093 -112 ct +1093 -87 1097 -68 1105 -55 ct 1114 -42 1126 -36 1143 -36 ct p ef +1557 -8 m 1557 -8 1557 -8 1557 -54 ct 1591 -42 1619 -36 1639 -36 ct 1654 -36 1665 -38 1673 -42 ct +1680 -46 1684 -52 1684 -60 ct 1684 -64 1682 -68 1678 -72 ct 1675 -75 1669 -79 1662 -82 ct +1662 -82 1662 -82 1614 -101 ct 1595 -109 1581 -118 1572 -127 ct 1563 -137 1558 -148 1558 -161 ct +1558 -182 1568 -199 1587 -211 ct 1606 -223 1633 -229 1667 -229 ct 1687 -229 1710 -226 1736 -221 ct +1736 -221 1736 -221 1736 -174 ct 1708 -183 1684 -188 1665 -188 ct 1650 -188 1640 -186 1633 -183 ct +1626 -180 1622 -175 1622 -169 ct 1622 -165 1625 -162 1630 -158 ct 1635 -154 1642 -150 1652 -146 ct +1652 -146 1652 -146 1705 -124 ct 1721 -118 1733 -110 1740 -100 ct 1748 -91 1752 -79 1752 -66 ct +1752 -45 1743 -28 1724 -15 ct 1705 -2 1681 5 1651 5 ct 1625 5 1593 1 1557 -8 ct +p ef +1904 5 m 1870 5 1842 -6 1821 -27 ct 1800 -49 1789 -77 1789 -112 ct 1789 -148 1800 -176 1821 -197 ct +1842 -218 1870 -229 1906 -229 ct 1941 -229 1969 -218 1990 -197 ct 2011 -176 2022 -148 2022 -112 ct +2022 -76 2011 -48 1990 -27 ct 1969 -6 1940 5 1904 5 ct p +1905 -36 m 1922 -36 1935 -42 1943 -55 ct 1952 -68 1956 -87 1956 -112 ct 1956 -138 1952 -156 1943 -169 ct +1935 -182 1922 -188 1906 -188 ct 1889 -188 1876 -182 1868 -169 ct 1859 -156 1855 -137 1855 -112 ct +1855 -87 1859 -68 1867 -55 ct 1876 -42 1888 -36 1905 -36 ct p ef +2185 0 m 2185 0 2185 0 2134 0 ct 2134 0 2134 0 2134 -149 ct 2134 -157 2133 -163 2132 -167 ct +2130 -171 2128 -173 2125 -173 ct 2120 -173 2116 -171 2112 -166 ct 2108 -161 2105 -154 2101 -145 ct +2101 -145 2101 -145 2101 0 ct 2101 0 2101 0 2050 0 ct 2050 0 2050 0 2050 -224 ct +2050 -224 2050 -224 2101 -224 ct 2101 -224 2101 -224 2098 -181 ct 2098 -181 2098 -181 2101 -181 ct +2106 -197 2113 -209 2121 -217 ct 2129 -225 2138 -229 2148 -229 ct 2159 -229 2168 -225 2174 -217 ct +2180 -209 2184 -197 2185 -181 ct 2185 -181 2185 -181 2187 -181 ct 2192 -197 2198 -209 2205 -217 ct +2213 -225 2221 -229 2231 -229 ct 2245 -229 2255 -223 2261 -212 ct 2266 -200 2269 -179 2269 -150 ct +2269 -150 2269 -150 2269 0 ct 2269 0 2269 0 2218 0 ct 2218 0 2218 0 2218 -149 ct +2218 -157 2217 -163 2216 -167 ct 2214 -171 2212 -173 2209 -173 ct 2204 -173 2200 -171 2196 -166 ct +2193 -161 2189 -154 2185 -145 ct 2185 -145 2185 -145 2185 0 ct p ef +2522 -95 m 2522 -95 2522 -95 2370 -95 ct 2373 -77 2381 -63 2393 -54 ct 2405 -45 2421 -41 2442 -41 ct +2466 -41 2493 -46 2522 -56 ct 2522 -56 2522 -56 2522 -9 ct 2487 0 2456 5 2430 5 ct +2392 5 2361 -6 2338 -27 ct 2315 -48 2304 -76 2304 -111 ct 2304 -147 2315 -175 2336 -197 ct +2358 -218 2386 -229 2421 -229 ct 2453 -229 2477 -219 2495 -199 ct 2513 -180 2522 -152 2522 -118 ct +2522 -118 2522 -118 2522 -95 ct p +2369 -136 m 2369 -136 2369 -136 2463 -136 ct 2463 -153 2459 -166 2452 -175 ct +2444 -184 2433 -188 2418 -188 ct 2404 -188 2392 -184 2384 -175 ct 2376 -166 2371 -153 2369 -136 ct +p ef +2768 -6 m 2744 1 2722 5 2704 5 ct 2675 5 2654 -1 2640 -14 ct 2626 -26 2619 -45 2619 -70 ct +2619 -70 2619 -70 2619 -178 ct 2619 -178 2619 -178 2571 -178 ct 2571 -178 2571 -178 2571 -219 ct +2571 -219 2571 -219 2619 -219 ct 2619 -219 2619 -219 2619 -285 ct 2619 -285 2619 -285 2680 -285 ct +2680 -285 2680 -285 2680 -219 ct 2680 -219 2680 -219 2763 -219 ct 2763 -219 2763 -219 2763 -178 ct +2763 -178 2763 -178 2680 -178 ct 2680 -178 2680 -178 2680 -84 ct 2680 -68 2683 -57 2689 -51 ct +2695 -44 2705 -41 2719 -41 ct 2736 -41 2752 -44 2768 -51 ct 2768 -51 2768 -51 2768 -6 ct +p ef +2823 0 m 2823 0 2823 0 2823 -326 ct 2823 -326 2823 -326 2884 -326 ct 2884 -326 2884 -326 2884 -224 ct +2884 -224 2884 -224 2882 -181 ct 2882 -181 2882 -181 2884 -181 ct 2891 -197 2900 -209 2912 -217 ct +2924 -225 2938 -229 2956 -229 ct 2978 -229 2994 -223 3005 -210 ct 3016 -197 3022 -178 3022 -153 ct +3022 -153 3022 -153 3022 0 ct 3022 0 3022 0 2961 0 ct 2961 0 2961 0 2961 -139 ct +2961 -150 2959 -159 2955 -165 ct 2950 -170 2944 -173 2935 -173 ct 2926 -173 2917 -170 2908 -165 ct +2900 -159 2891 -151 2884 -139 ct 2884 -139 2884 -139 2884 0 ct 2884 0 2884 0 2823 0 ct +p ef +3170 0 m 3170 -183 l 3088 -183 l 3088 -224 l 3231 -224 l 3231 0 l +3170 0 l p +3170 -265 m 3170 -326 l 3231 -326 l 3231 -265 l 3170 -265 l p ef +3331 0 m 3331 0 3331 0 3331 -224 ct 3331 -224 3331 -224 3392 -224 ct 3392 -224 3392 -224 3391 -202 ct +3391 -202 3391 -202 3390 -181 ct 3390 -181 3390 -181 3392 -181 ct 3399 -197 3408 -209 3420 -217 ct +3432 -225 3446 -229 3464 -229 ct 3486 -229 3502 -223 3513 -210 ct 3524 -197 3530 -178 3530 -153 ct +3530 -153 3530 -153 3530 0 ct 3530 0 3530 0 3469 0 ct 3469 0 3469 0 3469 -139 ct +3469 -150 3467 -159 3463 -165 ct 3458 -170 3452 -173 3443 -173 ct 3434 -173 3425 -170 3416 -165 ct +3408 -159 3399 -151 3392 -139 ct 3392 -139 3392 -139 3392 0 ct 3392 0 3392 0 3331 0 ct +p ef +3596 69 m 3596 69 3596 69 3602 25 ct 3634 38 3660 44 3680 44 ct 3698 44 3711 39 3719 30 ct +3728 21 3732 7 3732 -11 ct 3732 -11 3732 -11 3733 -53 ct 3733 -53 3733 -53 3731 -53 ct +3723 -35 3713 -22 3702 -13 ct 3690 -4 3676 0 3660 0 ct 3634 0 3613 -10 3598 -31 ct +3582 -51 3574 -78 3574 -111 ct 3574 -147 3583 -175 3600 -197 ct 3618 -218 3641 -229 3670 -229 ct +3682 -229 3692 -227 3702 -223 ct 3712 -218 3721 -212 3730 -204 ct 3730 -204 3730 -204 3735 -204 ct +3735 -204 3735 -204 3740 -224 ct 3740 -224 3740 -224 3791 -224 ct 3791 -224 3791 -224 3791 -27 ct +3791 10 3782 38 3764 58 ct 3747 77 3721 87 3688 87 ct 3662 87 3631 81 3596 69 ct +p +3730 -95 m 3730 -95 3730 -95 3730 -163 ct 3722 -169 3714 -174 3706 -178 ct +3699 -181 3692 -183 3685 -183 ct 3670 -183 3659 -177 3651 -166 ct 3644 -155 3640 -138 3640 -116 ct +3640 -97 3643 -83 3650 -73 ct 3657 -64 3666 -59 3680 -59 ct 3689 -59 3698 -62 3707 -68 ct +3715 -74 3723 -83 3730 -95 ct p ef +pom +gr +gs +pum +1942 18396 t +pom +gr +gs +pum +2450 18396 t +43 -326 m 43 -326 43 -326 43 -295 ct 43 -295 43 -295 59 -295 ct 80 -295 94 -293 102 -287 ct +111 -282 115 -274 115 -261 ct 115 -257 114 -251 113 -242 ct 113 -242 113 -242 109 -214 ct +108 -204 107 -196 107 -190 ct 107 -175 110 -163 117 -153 ct 124 -144 134 -137 148 -132 ct +134 -128 124 -121 117 -111 ct 110 -102 107 -90 107 -75 ct 107 -68 108 -61 109 -51 ct +109 -51 109 -51 113 -23 ct 114 -14 115 -8 115 -4 ct 115 9 111 17 102 22 ct 94 27 80 30 59 30 ct +59 30 59 30 43 30 ct 43 30 43 30 43 61 ct 43 61 43 61 66 61 ct 95 61 117 56 131 46 ct +146 36 153 21 153 2 ct 153 -7 152 -16 150 -26 ct 150 -26 150 -26 143 -63 ct 142 -68 142 -74 142 -79 ct +142 -92 146 -101 154 -108 ct 161 -114 173 -117 188 -117 ct 188 -117 188 -117 207 -117 ct +207 -117 207 -117 207 -148 ct 207 -148 207 -148 188 -148 ct 173 -148 161 -151 154 -157 ct +146 -164 142 -173 142 -186 ct 142 -191 142 -197 143 -202 ct 143 -202 143 -202 150 -239 ct +152 -249 153 -258 153 -267 ct 153 -286 146 -301 131 -311 ct 117 -321 95 -326 66 -326 ct +66 -326 66 -326 43 -326 ct p ef +pom +gr +gs +pum +1942 18887 t +43 -326 m 43 -326 43 -326 43 -295 ct 43 -295 43 -295 59 -295 ct 80 -295 94 -293 102 -287 ct +111 -282 115 -274 115 -261 ct 115 -257 114 -251 113 -242 ct 113 -242 113 -242 109 -214 ct +108 -204 107 -196 107 -190 ct 107 -175 110 -163 117 -153 ct 124 -144 134 -137 148 -132 ct +134 -128 124 -121 117 -111 ct 110 -102 107 -90 107 -75 ct 107 -68 108 -61 109 -51 ct +109 -51 109 -51 113 -23 ct 114 -14 115 -8 115 -4 ct 115 9 111 17 102 22 ct 94 27 80 30 59 30 ct +59 30 59 30 43 30 ct 43 30 43 30 43 61 ct 43 61 43 61 66 61 ct 95 61 117 56 131 46 ct +146 36 153 21 153 2 ct 153 -7 152 -16 150 -26 ct 150 -26 150 -26 143 -63 ct 142 -68 142 -74 142 -79 ct +142 -92 146 -101 154 -108 ct 161 -114 173 -117 188 -117 ct 188 -117 188 -117 207 -117 ct +207 -117 207 -117 207 -148 ct 207 -148 207 -148 188 -148 ct 173 -148 161 -151 154 -157 ct +146 -164 142 -173 142 -186 ct 142 -191 142 -197 143 -202 ct 143 -202 143 -202 150 -239 ct +152 -249 153 -258 153 -267 ct 153 -286 146 -301 131 -311 ct 117 -321 95 -326 66 -326 ct +66 -326 66 -326 43 -326 ct p ef +351 66 m 351 66 351 66 351 46 ct 358 45 364 41 368 33 ct 373 25 375 14 376 0 ct +376 0 376 0 351 0 ct 351 0 351 0 351 -61 ct 351 -61 351 -61 412 -61 ct 412 -61 412 -61 412 -24 ct +412 5 407 27 397 42 ct 387 57 371 65 351 66 ct p +351 -163 m 351 -224 l 412 -224 l 412 -163 l 351 -163 l p ef +pom +gr +gr +0.503 0.503 0.503 c 4064 19780 m 3002 19780 l 3002 19105 l 5126 19105 l +5126 19780 l 4064 19780 l p ef +4064 19780 m 3002 19780 l 3002 19105 l 5126 19105 l 5126 19780 l 4064 19780 l +pc +0.753 0.753 0.753 c 3964 19680 m 2902 19680 l 2902 19005 l 5026 19005 l +5026 19680 l 3964 19680 l p ef +0.003 0.003 0.003 c 3964 19680 m 2902 19680 l 2902 19005 l 5026 19005 l +5026 19680 l 3964 19680 l pc +gs +gs +pum +3133 19490 t +1.000 1.000 1.000 c 248 -242 m 158 -242 l 158 0 l 99 0 l 99 -242 l +9 -242 l 9 -291 l 248 -291 l 248 -242 l p ef +472 0 m 472 0 472 0 413 0 ct 409 -9 407 -17 407 -25 ct 388 -5 365 5 338 5 ct 318 5 302 -1 291 -13 ct +280 -24 274 -40 274 -59 ct 274 -73 278 -85 285 -95 ct 293 -106 304 -114 319 -120 ct +334 -127 351 -131 372 -132 ct 372 -132 372 -132 407 -135 ct 407 -135 407 -135 407 -139 ct +407 -163 393 -175 366 -175 ct 358 -175 347 -173 333 -170 ct 319 -166 307 -162 297 -157 ct +297 -157 297 -157 283 -198 ct 296 -204 312 -210 329 -214 ct 347 -218 362 -220 376 -220 ct +405 -220 427 -213 442 -199 ct 457 -185 464 -165 464 -138 ct 464 -138 464 -138 464 -51 ct +464 -31 467 -14 472 0 ct p +407 -66 m 407 -66 407 -66 407 -101 ct 383 -99 368 -97 362 -96 ct 357 -95 351 -93 344 -89 ct +338 -86 334 -82 331 -77 ct 328 -72 326 -67 326 -61 ct 326 -54 328 -49 333 -45 ct +337 -40 343 -38 350 -38 ct 371 -38 390 -47 407 -66 ct p ef +662 -211 m 662 -211 662 -211 652 -159 ct 646 -163 640 -165 633 -165 ct 626 -165 619 -163 613 -158 ct +606 -153 599 -145 592 -134 ct 585 -123 582 -116 582 -114 ct 582 -114 582 -114 582 0 ct +582 0 582 0 525 0 ct 525 0 525 0 525 -215 ct 525 -215 525 -215 582 -215 ct 582 -215 582 -215 582 -172 ct +590 -190 598 -202 606 -209 ct 614 -216 624 -220 635 -220 ct 646 -220 655 -217 662 -211 ct +p ef +888 -9 m 888 23 878 47 858 64 ct 839 81 811 89 775 89 ct 743 89 713 81 687 65 ct +687 65 687 65 703 22 ct 727 35 750 42 774 42 ct 792 42 806 38 816 29 ct 826 21 831 8 831 -7 ct +831 -7 831 -7 831 -22 ct 814 -4 793 5 767 5 ct 741 5 719 -5 702 -25 ct 685 -45 676 -71 676 -105 ct +676 -141 685 -169 702 -189 ct 719 -210 742 -220 770 -220 ct 781 -220 793 -218 804 -213 ct +815 -209 824 -203 831 -195 ct 831 -195 831 -195 831 -219 ct 831 -219 831 -219 888 -219 ct +888 -219 888 -219 888 -9 ct p +831 -71 m 831 -71 831 -71 831 -146 ct 818 -163 802 -171 782 -171 ct 768 -171 757 -165 748 -154 ct +739 -142 735 -126 735 -106 ct 735 -87 739 -71 748 -60 ct 757 -50 768 -44 782 -44 ct +801 -44 817 -53 831 -71 ct p ef +1140 -20 m 1115 -3 1086 5 1054 5 ct 1018 5 989 -5 967 -26 ct 946 -46 935 -74 935 -108 ct +935 -142 945 -169 964 -189 ct 983 -210 1009 -220 1041 -220 ct 1070 -220 1094 -210 1112 -191 ct +1131 -171 1140 -144 1140 -109 ct 1140 -109 1140 -109 1140 -95 ct 1140 -95 1140 -95 994 -95 ct +996 -80 1003 -68 1014 -59 ct 1025 -49 1039 -44 1055 -44 ct 1080 -44 1105 -51 1130 -65 ct +1130 -65 1130 -65 1140 -20 ct p +1085 -133 m 1083 -147 1078 -158 1070 -167 ct 1062 -175 1053 -179 1041 -179 ct +1029 -179 1018 -175 1010 -167 ct 1001 -158 996 -147 994 -133 ct 994 -133 994 -133 1085 -133 ct +p ef +1301 -5 m 1289 2 1276 5 1262 5 ct 1239 5 1221 -1 1209 -13 ct 1197 -25 1191 -43 1191 -66 ct +1191 -66 1191 -66 1191 -171 ct 1191 -171 1191 -171 1161 -171 ct 1161 -171 1161 -171 1161 -215 ct +1161 -215 1161 -215 1191 -215 ct 1191 -215 1191 -215 1191 -282 ct 1191 -282 1191 -282 1248 -282 ct +1248 -282 1248 -282 1248 -215 ct 1248 -215 1248 -215 1290 -215 ct 1290 -215 1290 -215 1290 -171 ct +1290 -171 1290 -171 1248 -171 ct 1248 -171 1248 -171 1248 -75 ct 1248 -65 1250 -58 1254 -52 ct +1258 -47 1263 -44 1269 -44 ct 1277 -44 1284 -46 1292 -49 ct 1292 -49 1292 -49 1301 -5 ct +p ef +1353 -66 m 1363 -66 1372 -63 1379 -56 ct 1386 -49 1389 -41 1389 -31 ct 1389 -21 1386 -12 1379 -5 ct +1372 2 1363 5 1353 5 ct 1343 5 1335 2 1328 -5 ct 1321 -12 1318 -20 1318 -31 ct +1318 -41 1321 -49 1328 -56 ct 1335 -63 1343 -66 1353 -66 ct p ef +1643 0 m 1643 0 1643 0 1586 0 ct 1586 0 1586 0 1586 -125 ct 1586 -156 1575 -171 1553 -171 ct +1534 -171 1516 -160 1501 -139 ct 1501 -139 1501 -139 1501 0 ct 1501 0 1501 0 1444 0 ct +1444 0 1444 0 1444 -307 ct 1444 -307 1444 -307 1501 -307 ct 1501 -307 1501 -307 1501 -188 ct +1519 -209 1542 -220 1570 -220 ct 1592 -220 1610 -213 1623 -200 ct 1636 -187 1643 -168 1643 -144 ct +1643 -144 1643 -144 1643 0 ct p ef +pom +gr +gr +gs +gs +pum +7022 20554 t +0.003 0.683 0.003 c 345 0 m 345 0 345 0 259 0 ct 259 0 259 0 259 -189 ct 259 -235 243 -258 210 -258 ct +180 -258 154 -242 131 -211 ct 131 -211 131 -211 131 0 ct 131 0 131 0 45 0 ct 45 0 45 0 45 -323 ct +45 -323 45 -323 131 -323 ct 131 -323 131 -323 131 -283 ct 158 -315 193 -331 235 -331 ct +269 -331 295 -321 315 -301 ct 335 -281 345 -253 345 -217 ct 345 -217 345 -217 345 0 ct +p ef +583 -331 m 634 -331 675 -316 706 -286 ct 737 -256 753 -215 753 -162 ct 753 -108 737 -67 706 -37 ct +675 -7 634 8 583 8 ct 532 8 491 -7 460 -37 ct 429 -67 413 -108 413 -162 ct 413 -215 429 -256 460 -286 ct +491 -316 532 -331 583 -331 ct p +583 -65 m 607 -65 627 -74 642 -91 ct 657 -109 664 -132 664 -162 ct 664 -191 657 -215 642 -232 ct +628 -249 608 -258 583 -258 ct 557 -258 537 -250 523 -233 ct 509 -216 502 -192 502 -162 ct +502 -132 509 -108 523 -91 ct 537 -74 557 -65 583 -65 ct p ef +1045 -465 m 1058 -465 1069 -460 1079 -451 ct 1089 -441 1094 -429 1094 -416 ct +1094 -403 1089 -392 1079 -382 ct 1070 -373 1058 -368 1045 -368 ct 1031 -368 1020 -373 1010 -382 ct +1001 -392 996 -403 996 -416 ct 996 -430 1001 -441 1010 -451 ct 1020 -460 1031 -465 1045 -465 ct +p +1088 0 m 1002 0 l 1002 -323 l 1088 -323 l 1088 0 l p ef +1480 0 m 1480 0 1480 0 1394 0 ct 1394 0 1394 0 1394 -189 ct 1394 -235 1378 -258 1345 -258 ct +1315 -258 1289 -242 1266 -211 ct 1266 -211 1266 -211 1266 0 ct 1266 0 1266 0 1180 0 ct +1180 0 1180 0 1180 -323 ct 1180 -323 1180 -323 1266 -323 ct 1266 -323 1266 -323 1266 -283 ct +1293 -315 1328 -331 1370 -331 ct 1404 -331 1430 -321 1450 -301 ct 1470 -281 1480 -253 1480 -217 ct +1480 -217 1480 -217 1480 0 ct p ef +1856 -29 m 1820 -4 1778 8 1730 8 ct 1674 8 1629 -7 1597 -38 ct 1564 -68 1548 -110 1548 -162 ct +1548 -214 1564 -255 1597 -285 ct 1629 -316 1673 -331 1728 -331 ct 1772 -331 1813 -321 1852 -301 ct +1852 -301 1852 -301 1836 -232 ct 1800 -250 1764 -259 1729 -259 ct 1704 -259 1683 -251 1665 -234 ct +1646 -218 1637 -194 1637 -162 ct 1637 -131 1646 -107 1665 -90 ct 1683 -73 1705 -65 1730 -65 ct +1769 -65 1806 -76 1841 -97 ct 1841 -97 1841 -97 1856 -29 ct p ef +2006 0 m 1920 0 l 1920 -461 l 2006 -461 l 2006 0 l p ef +2396 0 m 2396 0 2396 0 2310 0 ct 2310 0 2310 0 2310 -40 ct 2283 -8 2249 8 2206 8 ct +2172 8 2146 -2 2126 -22 ct 2106 -42 2096 -70 2096 -106 ct 2096 -106 2096 -106 2096 -323 ct +2096 -323 2096 -323 2182 -323 ct 2182 -323 2182 -323 2182 -133 ct 2182 -88 2198 -65 2231 -65 ct +2261 -65 2287 -81 2310 -112 ct 2310 -112 2310 -112 2310 -323 ct 2310 -323 2310 -323 2396 -323 ct +2396 -323 2396 -323 2396 0 ct p ef +2787 0 m 2787 0 2787 0 2701 0 ct 2701 0 2701 0 2701 -31 ct 2675 -5 2643 8 2604 8 ct +2564 8 2531 -7 2506 -37 ct 2480 -66 2467 -106 2467 -155 ct 2467 -209 2480 -252 2506 -284 ct +2531 -315 2564 -331 2604 -331 ct 2645 -331 2677 -318 2701 -293 ct 2701 -293 2701 -293 2701 -461 ct +2701 -461 2701 -461 2787 -461 ct 2787 -461 2787 -461 2787 0 ct p +2701 -104 m 2701 -104 2701 -104 2701 -221 ct 2681 -246 2657 -258 2627 -258 ct +2606 -258 2589 -249 2576 -232 ct 2563 -214 2556 -190 2556 -160 ct 2556 -130 2563 -107 2576 -90 ct +2589 -73 2606 -65 2627 -65 ct 2655 -65 2680 -78 2701 -104 ct p ef +3164 -29 m 3127 -4 3084 8 3035 8 ct 2980 8 2937 -7 2904 -38 ct 2872 -69 2856 -111 2856 -162 ct +2856 -213 2870 -254 2899 -285 ct 2928 -316 2966 -331 3014 -331 ct 3058 -331 3094 -316 3121 -287 ct +3149 -257 3163 -216 3163 -163 ct 3163 -163 3163 -163 3163 -142 ct 3163 -142 3163 -142 2945 -142 ct +2948 -120 2958 -102 2975 -87 ct 2992 -72 3013 -65 3036 -65 ct 3074 -65 3111 -76 3149 -97 ct +3149 -97 3149 -97 3164 -29 ct p +3081 -200 m 3078 -221 3071 -238 3059 -251 ct 3048 -264 3033 -270 3016 -270 ct +2998 -270 2982 -264 2969 -251 ct 2956 -238 2949 -221 2946 -200 ct 2946 -200 2946 -200 3081 -200 ct +p ef +3693 -29 m 3657 -4 3615 8 3567 8 ct 3511 8 3466 -7 3434 -38 ct 3401 -68 3385 -110 3385 -162 ct +3385 -214 3401 -255 3434 -285 ct 3466 -316 3510 -331 3565 -331 ct 3609 -331 3650 -321 3689 -301 ct +3689 -301 3689 -301 3673 -232 ct 3637 -250 3601 -259 3566 -259 ct 3541 -259 3520 -251 3502 -234 ct +3483 -218 3474 -194 3474 -162 ct 3474 -131 3483 -107 3502 -90 ct 3520 -73 3542 -65 3567 -65 ct +3606 -65 3643 -76 3678 -97 ct 3678 -97 3678 -97 3693 -29 ct p ef +4064 -323 m 4064 -323 4064 -323 3937 6 ct 3921 47 3901 78 3876 100 ct 3852 121 3819 132 3777 132 ct +3756 132 3733 128 3710 121 ct 3710 121 3710 121 3725 52 ct 3742 57 3757 60 3769 60 ct +3788 60 3803 56 3814 47 ct 3826 39 3836 24 3844 2 ct 3844 2 3844 2 3719 -323 ct +3719 -323 3719 -323 3814 -323 ct 3814 -323 3814 -323 3891 -91 ct 3891 -91 3891 -91 3974 -323 ct +3974 -323 3974 -323 4064 -323 ct p ef +4392 -29 m 4356 -4 4314 8 4266 8 ct 4210 8 4165 -7 4133 -38 ct 4100 -68 4084 -110 4084 -162 ct +4084 -214 4100 -255 4133 -285 ct 4165 -316 4209 -331 4264 -331 ct 4308 -331 4349 -321 4388 -301 ct +4388 -301 4388 -301 4372 -232 ct 4336 -250 4300 -259 4265 -259 ct 4240 -259 4219 -251 4201 -234 ct +4182 -218 4173 -194 4173 -162 ct 4173 -131 4182 -107 4201 -90 ct 4219 -73 4241 -65 4266 -65 ct +4305 -65 4342 -76 4377 -97 ct 4377 -97 4377 -97 4392 -29 ct p ef +4542 0 m 4456 0 l 4456 -461 l 4542 -461 l 4542 0 l p ef +4921 -29 m 4884 -4 4841 8 4792 8 ct 4737 8 4694 -7 4661 -38 ct 4629 -69 4613 -111 4613 -162 ct +4613 -213 4627 -254 4656 -285 ct 4685 -316 4723 -331 4771 -331 ct 4815 -331 4851 -316 4878 -287 ct +4906 -257 4920 -216 4920 -163 ct 4920 -163 4920 -163 4920 -142 ct 4920 -142 4920 -142 4702 -142 ct +4705 -120 4715 -102 4732 -87 ct 4749 -72 4770 -65 4793 -65 ct 4831 -65 4868 -76 4906 -97 ct +4906 -97 4906 -97 4921 -29 ct p +4838 -200 m 4835 -221 4828 -238 4816 -251 ct 4805 -264 4790 -270 4773 -270 ct +4755 -270 4739 -264 4726 -251 ct 4713 -238 4706 -221 4703 -200 ct 4703 -200 4703 -200 4838 -200 ct +p ef +5092 -304 m 5070 -131 l 5020 -131 l 4997 -304 l 4997 -438 l 5092 -438 l +5092 -304 l p +5044 -98 m 5059 -98 5071 -93 5082 -83 ct 5092 -73 5097 -60 5097 -45 ct 5097 -30 5092 -17 5082 -7 ct +5071 3 5059 8 5044 8 ct 5029 8 5016 3 5006 -7 ct 4996 -17 4991 -30 4991 -45 ct +4991 -60 4996 -73 5006 -83 ct 5016 -93 5029 -98 5044 -98 ct p ef +pom +gr +gr +1.000 1.000 1.000 c 4168 11261 m 7776 11261 l 7776 12968 l 4168 12968 l +4168 11261 l p ef +1.000 0.402 0.203 c 4168 11261 m 7776 11261 l 7776 12968 l 4168 12968 l +4168 11261 l pc +1.000 1.000 1.000 c 2890 13416 m 3038 12300 l 2890 13416 l p ef +1.000 0.402 0.203 c 2890 13416 m 3038 12300 l ps +1.000 1.000 1.000 c 3038 12300 m 3919 11814 l 3038 12300 l p ef +1.000 0.402 0.203 c 3038 12300 m 3919 11814 l ps +gs +gs +pum +4456 11693 t +0.003 0.003 0.003 c 172 -7 m 172 17 165 35 150 48 ct 135 61 114 67 86 67 ct 62 67 40 61 20 49 ct +20 49 20 49 32 17 ct 50 27 68 32 86 32 ct 100 32 110 29 118 22 ct 125 16 129 7 129 -5 ct +129 -5 129 -5 129 -16 ct 116 -3 100 4 81 4 ct 61 4 44 -3 31 -18 ct 18 -33 12 -54 12 -79 ct +12 -106 19 -127 32 -143 ct 45 -158 62 -166 83 -166 ct 92 -166 100 -164 108 -161 ct +117 -157 124 -153 129 -147 ct 129 -147 129 -147 129 -165 ct 129 -165 129 -165 172 -165 ct +172 -165 172 -165 172 -7 ct p +129 -53 m 129 -53 129 -53 129 -110 ct 119 -123 107 -129 92 -129 ct 82 -129 74 -125 67 -116 ct +60 -107 57 -95 57 -80 ct 57 -65 60 -54 67 -45 ct 73 -37 82 -33 92 -33 ct 107 -33 119 -40 129 -53 ct +p ef +361 -15 m 342 -2 321 4 296 4 ct 269 4 247 -4 231 -19 ct 215 -35 207 -56 207 -81 ct +207 -107 214 -127 229 -143 ct 243 -158 262 -166 286 -166 ct 308 -166 326 -159 340 -144 ct +354 -129 361 -108 361 -82 ct 361 -82 361 -82 361 -71 ct 361 -71 361 -71 252 -71 ct +254 -60 259 -51 267 -44 ct 276 -37 286 -33 298 -33 ct 316 -33 335 -38 354 -49 ct +354 -49 354 -49 361 -15 ct p +320 -100 m 319 -111 315 -119 309 -126 ct 303 -132 296 -135 287 -135 ct 278 -135 270 -132 264 -126 ct +257 -119 253 -111 252 -100 ct 252 -100 252 -100 320 -100 ct p ef +545 0 m 545 0 545 0 502 0 ct 502 0 502 0 502 -95 ct 502 -118 494 -129 478 -129 ct +463 -129 450 -121 439 -105 ct 439 -105 439 -105 439 0 ct 439 0 439 0 396 0 ct 396 0 396 0 396 -162 ct +396 -162 396 -162 439 -162 ct 439 -162 439 -162 439 -142 ct 452 -158 470 -166 491 -166 ct +507 -166 520 -161 530 -151 ct 540 -141 545 -127 545 -109 ct 545 -109 545 -109 545 0 ct +p ef +733 -15 m 714 -2 693 4 668 4 ct 641 4 619 -4 603 -19 ct 587 -35 579 -56 579 -81 ct +579 -107 586 -127 601 -143 ct 615 -158 634 -166 658 -166 ct 680 -166 698 -159 712 -144 ct +726 -129 733 -108 733 -82 ct 733 -82 733 -82 733 -71 ct 733 -71 733 -71 624 -71 ct +626 -60 631 -51 639 -44 ct 648 -37 658 -33 670 -33 ct 688 -33 707 -38 726 -49 ct +726 -49 726 -49 733 -15 ct p +692 -100 m 691 -111 687 -119 681 -126 ct 675 -132 668 -135 659 -135 ct 650 -135 642 -132 636 -126 ct +629 -119 625 -111 624 -100 ct 624 -100 624 -100 692 -100 ct p ef +871 -159 m 871 -159 871 -159 864 -120 ct 859 -123 855 -125 850 -125 ct 844 -125 839 -123 834 -120 ct +829 -116 824 -110 819 -102 ct 814 -93 811 -88 811 -87 ct 811 -87 811 -87 811 0 ct +811 0 811 0 768 0 ct 768 0 768 0 768 -162 ct 768 -162 768 -162 811 -162 ct 811 -162 811 -162 811 -130 ct +817 -143 823 -153 829 -158 ct 835 -163 842 -166 851 -166 ct 859 -166 866 -164 871 -159 ct +p ef +1029 0 m 1029 0 1029 0 984 0 ct 981 -7 980 -13 980 -18 ct 966 -3 948 4 928 4 ct +913 4 901 0 893 -9 ct 884 -18 880 -29 880 -44 ct 880 -54 883 -64 888 -71 ct 894 -79 903 -85 914 -90 ct +925 -95 938 -98 954 -99 ct 954 -99 954 -99 980 -101 ct 980 -101 980 -101 980 -104 ct +980 -123 970 -132 950 -132 ct 943 -132 935 -131 925 -128 ct 915 -125 905 -122 898 -118 ct +898 -118 898 -118 887 -149 ct 897 -154 909 -158 922 -161 ct 935 -164 947 -166 957 -166 ct +979 -166 995 -161 1006 -150 ct 1017 -140 1023 -124 1023 -104 ct 1023 -104 1023 -104 1023 -39 ct +1023 -23 1025 -10 1029 0 ct p +980 -49 m 980 -49 980 -49 980 -75 ct 962 -73 951 -72 946 -71 ct 942 -70 938 -69 933 -66 ct +928 -64 925 -61 922 -57 ct 920 -54 919 -49 919 -45 ct 919 -40 921 -36 924 -33 ct +927 -30 932 -28 937 -28 ct 953 -28 967 -35 980 -49 ct p ef +1155 -3 m 1146 2 1136 4 1125 4 ct 1108 4 1095 -1 1086 -10 ct 1077 -19 1072 -32 1072 -50 ct +1072 -50 1072 -50 1072 -129 ct 1072 -129 1072 -129 1050 -129 ct 1050 -129 1050 -129 1050 -162 ct +1050 -162 1050 -162 1072 -162 ct 1072 -162 1072 -162 1072 -212 ct 1072 -212 1072 -212 1115 -212 ct +1115 -212 1115 -212 1115 -162 ct 1115 -162 1115 -162 1146 -162 ct 1146 -162 1146 -162 1146 -129 ct +1146 -129 1146 -129 1115 -129 ct 1115 -129 1115 -129 1115 -57 ct 1115 -49 1116 -43 1119 -39 ct +1122 -35 1126 -33 1131 -33 ct 1137 -33 1143 -34 1149 -36 ct 1149 -36 1149 -36 1155 -3 ct +p ef +1317 -15 m 1298 -2 1277 4 1252 4 ct 1225 4 1203 -4 1187 -19 ct 1171 -35 1163 -56 1163 -81 ct +1163 -107 1170 -127 1185 -143 ct 1199 -158 1218 -166 1242 -166 ct 1264 -166 1282 -159 1296 -144 ct +1310 -129 1317 -108 1317 -82 ct 1317 -82 1317 -82 1317 -71 ct 1317 -71 1317 -71 1208 -71 ct +1210 -60 1215 -51 1223 -44 ct 1232 -37 1242 -33 1254 -33 ct 1272 -33 1291 -38 1310 -49 ct +1310 -49 1310 -49 1317 -15 ct p +1276 -100 m 1275 -111 1271 -119 1265 -126 ct 1259 -132 1252 -135 1243 -135 ct +1234 -135 1226 -132 1220 -126 ct 1213 -119 1209 -111 1208 -100 ct 1208 -100 1208 -100 1276 -100 ct +p ef +1501 0 m 1501 0 1501 0 1458 0 ct 1458 0 1458 0 1458 -16 ct 1445 -3 1429 4 1410 4 ct +1390 4 1373 -3 1360 -18 ct 1347 -33 1341 -53 1341 -78 ct 1341 -105 1347 -127 1360 -142 ct +1373 -158 1390 -166 1410 -166 ct 1430 -166 1446 -160 1458 -147 ct 1458 -147 1458 -147 1458 -231 ct +1458 -231 1458 -231 1501 -231 ct 1501 -231 1501 -231 1501 0 ct p +1458 -53 m 1458 -53 1458 -53 1458 -111 ct 1448 -123 1436 -129 1421 -129 ct +1411 -129 1402 -125 1396 -116 ct 1389 -107 1386 -95 1386 -80 ct 1386 -65 1389 -54 1396 -45 ct +1402 -37 1411 -33 1421 -33 ct 1435 -33 1447 -40 1458 -53 ct p ef +1656 -233 m 1663 -233 1669 -231 1674 -226 ct 1679 -221 1681 -215 1681 -208 ct +1681 -202 1679 -196 1674 -191 ct 1669 -186 1663 -184 1656 -184 ct 1650 -184 1644 -186 1639 -191 ct +1634 -196 1632 -202 1632 -208 ct 1632 -215 1634 -221 1639 -226 ct 1644 -231 1650 -233 1656 -233 ct +p +1678 0 m 1635 0 l 1635 -162 l 1678 -162 l 1678 0 l p ef +1874 0 m 1874 0 1874 0 1831 0 ct 1831 0 1831 0 1831 -95 ct 1831 -118 1823 -129 1807 -129 ct +1792 -129 1779 -121 1768 -105 ct 1768 -105 1768 -105 1768 0 ct 1768 0 1768 0 1725 0 ct +1725 0 1725 0 1725 -162 ct 1725 -162 1725 -162 1768 -162 ct 1768 -162 1768 -162 1768 -142 ct +1781 -158 1799 -166 1820 -166 ct 1836 -166 1849 -161 1859 -151 ct 1869 -141 1874 -127 1874 -109 ct +1874 -109 1874 -109 1874 0 ct p ef +2064 -15 m 2046 -2 2025 4 2000 4 ct 1972 4 1950 -4 1934 -19 ct 1917 -34 1909 -55 1909 -81 ct +1909 -107 1917 -128 1934 -143 ct 1950 -158 1972 -166 2000 -166 ct 2022 -166 2042 -160 2062 -149 ct +2062 -149 2062 -149 2054 -115 ct 2036 -124 2018 -129 2000 -129 ct 1988 -129 1977 -125 1968 -117 ct +1959 -108 1954 -97 1954 -81 ct 1954 -66 1959 -54 1968 -45 ct 1977 -37 1988 -33 2000 -33 ct +2020 -33 2038 -38 2056 -49 ct 2056 -49 2056 -49 2064 -15 ct p ef +2139 0 m 2096 0 l 2096 -231 l 2139 -231 l 2139 0 l p ef +2334 0 m 2334 0 2334 0 2291 0 ct 2291 0 2291 0 2291 -20 ct 2278 -4 2261 4 2240 4 ct +2223 4 2210 -1 2200 -11 ct 2190 -21 2185 -35 2185 -53 ct 2185 -53 2185 -53 2185 -162 ct +2185 -162 2185 -162 2228 -162 ct 2228 -162 2228 -162 2228 -67 ct 2228 -44 2236 -33 2252 -33 ct +2267 -33 2280 -41 2291 -56 ct 2291 -56 2291 -56 2291 -162 ct 2291 -162 2291 -162 2334 -162 ct +2334 -162 2334 -162 2334 0 ct p ef +2530 0 m 2530 0 2530 0 2487 0 ct 2487 0 2487 0 2487 -16 ct 2474 -3 2458 4 2439 4 ct +2419 4 2402 -3 2389 -18 ct 2376 -33 2370 -53 2370 -78 ct 2370 -105 2376 -127 2389 -142 ct +2402 -158 2419 -166 2439 -166 ct 2459 -166 2475 -160 2487 -147 ct 2487 -147 2487 -147 2487 -231 ct +2487 -231 2487 -231 2530 -231 ct 2530 -231 2530 -231 2530 0 ct p +2487 -53 m 2487 -53 2487 -53 2487 -111 ct 2477 -123 2465 -129 2450 -129 ct +2440 -129 2431 -125 2425 -116 ct 2418 -107 2415 -95 2415 -80 ct 2415 -65 2418 -54 2425 -45 ct +2431 -37 2440 -33 2450 -33 ct 2464 -33 2476 -40 2487 -53 ct p ef +2719 -15 m 2700 -2 2679 4 2654 4 ct 2627 4 2605 -4 2589 -19 ct 2573 -35 2565 -56 2565 -81 ct +2565 -107 2572 -127 2587 -143 ct 2601 -158 2620 -166 2644 -166 ct 2666 -166 2684 -159 2698 -144 ct +2712 -129 2719 -108 2719 -82 ct 2719 -82 2719 -82 2719 -71 ct 2719 -71 2719 -71 2610 -71 ct +2612 -60 2617 -51 2625 -44 ct 2634 -37 2644 -33 2656 -33 ct 2674 -33 2693 -38 2712 -49 ct +2712 -49 2712 -49 2719 -15 ct p +2678 -100 m 2677 -111 2673 -119 2667 -126 ct 2661 -132 2654 -135 2645 -135 ct +2636 -135 2628 -132 2622 -126 ct 2615 -119 2611 -111 2610 -100 ct 2610 -100 2610 -100 2678 -100 ct +p ef +pom +gr +gs +pum +7187 11693 t +pom +gr +gs +pum +4456 12049 t +0.003 0.003 0.003 c 96 45 m 96 45 96 45 85 52 ct 63 28 47 5 37 -16 ct 27 -38 22 -63 22 -90 ct +22 -117 27 -141 37 -163 ct 47 -184 63 -207 85 -231 ct 85 -231 85 -231 96 -224 ct +80 -203 69 -182 61 -160 ct 54 -139 50 -115 50 -90 ct 50 -65 54 -41 61 -20 ct 68 2 80 23 96 45 ct +p ef +262 0 m 262 0 262 0 235 0 ct 235 0 235 0 235 -103 ct 235 -115 232 -125 226 -132 ct +220 -139 211 -142 201 -142 ct 185 -142 169 -133 154 -115 ct 154 -115 154 -115 154 0 ct +154 0 154 0 127 0 ct 127 0 127 0 127 -162 ct 127 -162 127 -162 154 -162 ct 154 -162 154 -162 154 -139 ct +171 -157 189 -166 208 -166 ct 225 -166 238 -161 248 -151 ct 257 -142 262 -128 262 -110 ct +262 -110 262 -110 262 0 ct p ef +448 -17 m 425 -3 403 4 381 4 ct 355 4 334 -4 319 -19 ct 304 -34 297 -55 297 -81 ct +297 -107 304 -127 318 -143 ct 331 -158 350 -166 373 -166 ct 394 -166 412 -159 425 -144 ct +438 -130 445 -111 445 -86 ct 445 -86 445 -86 445 -79 ct 445 -79 445 -79 325 -79 ct +326 -60 331 -45 341 -35 ct 350 -25 364 -20 381 -20 ct 401 -20 421 -26 441 -38 ct +441 -38 441 -38 448 -17 ct p +417 -100 m 416 -113 411 -123 403 -131 ct 394 -138 385 -142 373 -142 ct 361 -142 351 -138 342 -131 ct +334 -124 329 -113 326 -100 ct 326 -100 326 -100 417 -100 ct p ef +625 -17 m 602 -3 580 4 558 4 ct 532 4 511 -4 496 -19 ct 481 -34 474 -55 474 -81 ct +474 -107 481 -127 495 -143 ct 508 -158 527 -166 550 -166 ct 571 -166 589 -159 602 -144 ct +615 -130 622 -111 622 -86 ct 622 -86 622 -86 622 -79 ct 622 -79 622 -79 502 -79 ct +503 -60 508 -45 518 -35 ct 527 -25 541 -20 558 -20 ct 578 -20 598 -26 618 -38 ct +618 -38 618 -38 625 -17 ct p +594 -100 m 593 -113 588 -123 580 -131 ct 571 -138 562 -142 550 -142 ct 538 -142 528 -138 519 -131 ct +511 -124 506 -113 503 -100 ct 503 -100 503 -100 594 -100 ct p ef +794 0 m 794 0 794 0 767 0 ct 767 0 767 0 767 -20 ct 755 -4 740 4 720 4 ct 699 4 683 -4 670 -20 ct +658 -35 652 -57 652 -84 ct 652 -109 658 -128 671 -143 ct 683 -158 699 -166 718 -166 ct +740 -166 756 -158 767 -142 ct 767 -142 767 -142 767 -231 ct 767 -231 767 -231 794 -231 ct +794 -231 794 -231 794 0 ct p +767 -47 m 767 -47 767 -47 767 -116 ct 763 -123 758 -130 750 -135 ct 742 -140 734 -142 725 -142 ct +711 -142 700 -137 692 -126 ct 684 -116 680 -101 680 -82 ct 680 -62 684 -47 692 -36 ct +701 -25 712 -20 726 -20 ct 732 -20 738 -21 744 -24 ct 750 -27 755 -31 760 -36 ct +765 -41 767 -45 767 -47 ct p ef +981 -17 m 958 -3 936 4 914 4 ct 888 4 867 -4 852 -19 ct 837 -34 830 -55 830 -81 ct +830 -107 837 -127 851 -143 ct 864 -158 883 -166 906 -166 ct 927 -166 945 -159 958 -144 ct +971 -130 978 -111 978 -86 ct 978 -86 978 -86 978 -79 ct 978 -79 978 -79 858 -79 ct +859 -60 864 -45 874 -35 ct 883 -25 897 -20 914 -20 ct 934 -20 954 -26 974 -38 ct +974 -38 974 -38 981 -17 ct p +950 -100 m 949 -113 944 -123 936 -131 ct 927 -138 918 -142 906 -142 ct 894 -142 884 -138 875 -131 ct +867 -124 862 -113 859 -100 ct 859 -100 859 -100 950 -100 ct p ef +1150 0 m 1150 0 1150 0 1123 0 ct 1123 0 1123 0 1123 -20 ct 1111 -4 1096 4 1076 4 ct +1055 4 1039 -4 1026 -20 ct 1014 -35 1008 -57 1008 -84 ct 1008 -109 1014 -128 1027 -143 ct +1039 -158 1055 -166 1074 -166 ct 1096 -166 1112 -158 1123 -142 ct 1123 -142 1123 -142 1123 -231 ct +1123 -231 1123 -231 1150 -231 ct 1150 -231 1150 -231 1150 0 ct p +1123 -47 m 1123 -47 1123 -47 1123 -116 ct 1119 -123 1114 -130 1106 -135 ct +1098 -140 1090 -142 1081 -142 ct 1067 -142 1056 -137 1048 -126 ct 1040 -116 1036 -101 1036 -82 ct +1036 -62 1040 -47 1048 -36 ct 1057 -25 1068 -20 1082 -20 ct 1088 -20 1094 -21 1100 -24 ct +1106 -27 1111 -31 1116 -36 ct 1121 -41 1123 -45 1123 -47 ct p ef +1362 -226 m 1362 -226 1362 -226 1356 -205 ct 1347 -208 1340 -209 1334 -209 ct +1328 -209 1323 -207 1321 -201 ct 1318 -196 1317 -189 1317 -178 ct 1317 -178 1317 -178 1317 -162 ct +1317 -162 1317 -162 1353 -162 ct 1353 -162 1353 -162 1353 -140 ct 1353 -140 1353 -140 1317 -140 ct +1317 -140 1317 -140 1317 0 ct 1317 0 1317 0 1290 0 ct 1290 0 1290 0 1290 -140 ct +1290 -140 1290 -140 1263 -140 ct 1263 -140 1263 -140 1263 -162 ct 1263 -162 1263 -162 1290 -162 ct +1290 -162 1290 -162 1290 -182 ct 1290 -200 1294 -214 1301 -221 ct 1308 -229 1319 -233 1334 -233 ct +1342 -233 1352 -231 1362 -226 ct p ef +1439 -166 m 1462 -166 1480 -158 1494 -143 ct 1507 -127 1514 -107 1514 -81 ct +1514 -55 1507 -35 1494 -19 ct 1480 -4 1462 4 1439 4 ct 1415 4 1397 -4 1383 -19 ct +1370 -35 1363 -55 1363 -81 ct 1363 -107 1370 -127 1383 -143 ct 1397 -158 1415 -166 1439 -166 ct +p +1439 -20 m 1453 -20 1465 -26 1473 -38 ct 1482 -49 1486 -64 1486 -81 ct 1486 -99 1482 -114 1474 -125 ct +1465 -136 1454 -142 1439 -142 ct 1423 -142 1412 -136 1403 -125 ct 1395 -114 1391 -100 1391 -81 ct +1391 -64 1395 -49 1404 -38 ct 1412 -26 1424 -20 1439 -20 ct p ef +1637 -161 m 1637 -161 1637 -161 1630 -137 ct 1625 -140 1620 -141 1616 -141 ct +1610 -141 1605 -138 1599 -133 ct 1594 -127 1589 -119 1584 -109 ct 1579 -98 1576 -93 1576 -93 ct +1576 -93 1576 -93 1576 0 ct 1576 0 1576 0 1549 0 ct 1549 0 1549 0 1549 -162 ct +1549 -162 1549 -162 1574 -162 ct 1574 -162 1574 -162 1574 -125 ct 1582 -141 1589 -152 1595 -157 ct +1602 -163 1609 -166 1617 -166 ct 1625 -166 1632 -164 1637 -161 ct p ef +1811 -2 m 1801 2 1793 4 1787 4 ct 1773 4 1763 0 1757 -8 ct 1750 -16 1747 -28 1747 -45 ct +1747 -45 1747 -45 1747 -140 ct 1747 -140 1747 -140 1727 -140 ct 1727 -140 1727 -140 1727 -162 ct +1727 -162 1727 -162 1747 -162 ct 1747 -162 1747 -162 1747 -206 ct 1747 -206 1747 -206 1774 -206 ct +1774 -206 1774 -206 1774 -162 ct 1774 -162 1774 -162 1805 -162 ct 1805 -162 1805 -162 1805 -140 ct +1805 -140 1805 -140 1774 -140 ct 1774 -140 1774 -140 1774 -47 ct 1774 -29 1780 -20 1791 -20 ct +1795 -20 1801 -21 1807 -23 ct 1807 -23 1807 -23 1811 -2 ct p ef +1968 0 m 1968 0 1968 0 1941 0 ct 1941 0 1941 0 1941 -103 ct 1941 -115 1938 -125 1932 -132 ct +1926 -139 1917 -142 1907 -142 ct 1891 -142 1875 -133 1860 -115 ct 1860 -115 1860 -115 1860 0 ct +1860 0 1860 0 1833 0 ct 1833 0 1833 0 1833 -231 ct 1833 -231 1833 -231 1860 -231 ct +1860 -231 1860 -231 1860 -139 ct 1877 -157 1895 -166 1914 -166 ct 1931 -166 1944 -161 1954 -151 ct +1963 -142 1968 -128 1968 -110 ct 1968 -110 1968 -110 1968 0 ct p ef +2154 -17 m 2131 -3 2109 4 2087 4 ct 2061 4 2040 -4 2025 -19 ct 2010 -34 2003 -55 2003 -81 ct +2003 -107 2010 -127 2024 -143 ct 2037 -158 2056 -166 2079 -166 ct 2100 -166 2118 -159 2131 -144 ct +2144 -130 2151 -111 2151 -86 ct 2151 -86 2151 -86 2151 -79 ct 2151 -79 2151 -79 2031 -79 ct +2032 -60 2037 -45 2047 -35 ct 2056 -25 2070 -20 2087 -20 ct 2107 -20 2127 -26 2147 -38 ct +2147 -38 2147 -38 2154 -17 ct p +2123 -100 m 2122 -113 2117 -123 2109 -131 ct 2100 -138 2091 -142 2079 -142 ct +2067 -142 2057 -138 2048 -131 ct 2040 -124 2035 -113 2032 -100 ct 2032 -100 2032 -100 2123 -100 ct +p ef +2386 -127 m 2369 -137 2353 -142 2337 -142 ct 2325 -142 2316 -140 2309 -136 ct +2302 -133 2299 -128 2299 -121 ct 2299 -116 2301 -113 2306 -109 ct 2310 -106 2317 -103 2327 -101 ct +2327 -101 2327 -101 2348 -94 ct 2368 -88 2382 -81 2390 -74 ct 2397 -67 2401 -57 2401 -46 ct +2401 -30 2395 -18 2383 -9 ct 2372 0 2356 4 2336 4 ct 2312 4 2291 -2 2271 -14 ct +2271 -14 2271 -14 2280 -35 ct 2298 -25 2316 -20 2334 -20 ct 2361 -20 2374 -28 2374 -43 ct +2374 -49 2371 -54 2365 -58 ct 2360 -63 2348 -67 2329 -73 ct 2315 -77 2305 -81 2299 -83 ct +2294 -85 2289 -88 2285 -92 ct 2280 -95 2277 -99 2275 -104 ct 2273 -109 2272 -114 2272 -119 ct +2272 -133 2278 -145 2289 -153 ct 2300 -162 2316 -166 2337 -166 ct 2346 -166 2355 -164 2366 -161 ct +2376 -158 2386 -154 2394 -148 ct 2394 -148 2394 -148 2386 -127 ct p ef +2466 0 m 2439 0 l 2439 -231 l 2466 -231 l 2466 0 l p ef +2538 0 m 2511 0 l 2511 -162 l 2538 -162 l 2538 0 l p +2524 -231 m 2529 -231 2533 -229 2536 -226 ct 2539 -223 2541 -219 2541 -214 ct +2541 -210 2539 -206 2536 -203 ct 2533 -200 2529 -198 2524 -198 ct 2520 -198 2516 -200 2513 -203 ct +2510 -206 2508 -210 2508 -214 ct 2508 -219 2510 -223 2513 -226 ct 2516 -229 2520 -231 2524 -231 ct +p ef +2574 -81 m 2574 -108 2582 -129 2597 -144 ct 2612 -159 2631 -166 2654 -166 ct +2673 -166 2692 -160 2709 -149 ct 2709 -149 2709 -149 2701 -128 ct 2686 -137 2671 -142 2654 -142 ct +2639 -142 2627 -136 2617 -125 ct 2607 -114 2602 -100 2602 -81 ct 2602 -63 2607 -48 2617 -37 ct +2627 -26 2640 -20 2655 -20 ct 2670 -20 2687 -25 2704 -36 ct 2704 -36 2704 -36 2712 -15 ct +2694 -2 2675 4 2655 4 ct 2631 4 2611 -4 2596 -19 ct 2582 -35 2574 -56 2574 -81 ct +p ef +2886 -17 m 2863 -3 2841 4 2819 4 ct 2793 4 2772 -4 2757 -19 ct 2742 -34 2735 -55 2735 -81 ct +2735 -107 2742 -127 2756 -143 ct 2769 -158 2788 -166 2811 -166 ct 2832 -166 2850 -159 2863 -144 ct +2876 -130 2883 -111 2883 -86 ct 2883 -86 2883 -86 2883 -79 ct 2883 -79 2883 -79 2763 -79 ct +2764 -60 2769 -45 2779 -35 ct 2788 -25 2802 -20 2819 -20 ct 2839 -20 2859 -26 2879 -38 ct +2879 -38 2879 -38 2886 -17 ct p +2855 -100 m 2854 -113 2849 -123 2841 -131 ct 2832 -138 2823 -142 2811 -142 ct +2799 -142 2789 -138 2780 -131 ct 2772 -124 2767 -113 2764 -100 ct 2764 -100 2764 -100 2855 -100 ct +p ef +2944 4 m 2938 3 2934 1 2930 -3 ct 2927 -7 2925 -11 2925 -16 ct 2925 -21 2927 -26 2930 -30 ct +2934 -33 2938 -35 2943 -35 ct 2949 -35 2954 -33 2958 -28 ct 2962 -23 2964 -17 2964 -11 ct +2964 10 2953 26 2931 37 ct 2931 37 2931 37 2925 26 ct 2938 20 2944 12 2944 4 ct +p ef +pom +gr +gs +pum +4456 12405 t +0.003 0.003 0.003 c 226 -162 m 179 0 l 154 0 l 115 -130 l 76 0 l 51 0 l +4 -162 l 32 -162 l 65 -37 l 101 -162 l 127 -162 l 166 -37 l 198 -162 l +226 -162 l p ef +380 0 m 380 0 380 0 353 0 ct 353 0 353 0 353 -103 ct 353 -115 350 -125 344 -132 ct +338 -139 329 -142 319 -142 ct 303 -142 287 -133 272 -115 ct 272 -115 272 -115 272 0 ct +272 0 272 0 245 0 ct 245 0 245 0 245 -231 ct 245 -231 245 -231 272 -231 ct 272 -231 272 -231 272 -139 ct +289 -157 307 -166 326 -166 ct 343 -166 356 -161 366 -151 ct 375 -142 380 -128 380 -110 ct +380 -110 380 -110 380 0 ct p ef +451 0 m 424 0 l 424 -162 l 451 -162 l 451 0 l p +437 -231 m 442 -231 446 -229 449 -226 ct 452 -223 454 -219 454 -214 ct 454 -210 452 -206 449 -203 ct +446 -200 442 -198 437 -198 ct 433 -198 429 -200 426 -203 ct 423 -206 421 -210 421 -214 ct +421 -219 423 -223 426 -226 ct 429 -229 433 -231 437 -231 ct p ef +487 -81 m 487 -108 495 -129 510 -144 ct 525 -159 544 -166 567 -166 ct 586 -166 605 -160 622 -149 ct +622 -149 622 -149 614 -128 ct 599 -137 584 -142 567 -142 ct 552 -142 540 -136 530 -125 ct +520 -114 515 -100 515 -81 ct 515 -63 520 -48 530 -37 ct 540 -26 553 -20 568 -20 ct +583 -20 600 -25 617 -36 ct 617 -36 617 -36 625 -15 ct 607 -2 588 4 568 4 ct 544 4 524 -4 509 -19 ct +495 -35 487 -56 487 -81 ct p ef +791 0 m 791 0 791 0 764 0 ct 764 0 764 0 764 -103 ct 764 -115 761 -125 755 -132 ct +749 -139 740 -142 730 -142 ct 714 -142 698 -133 683 -115 ct 683 -115 683 -115 683 0 ct +683 0 683 0 656 0 ct 656 0 656 0 656 -231 ct 656 -231 656 -231 683 -231 ct 683 -231 683 -231 683 -139 ct +700 -157 718 -166 737 -166 ct 754 -166 767 -161 777 -151 ct 786 -142 791 -128 791 -110 ct +791 -110 791 -110 791 0 ct p ef +1057 0 m 1057 0 1057 0 1030 0 ct 1030 0 1030 0 1030 -20 ct 1018 -4 1003 4 983 4 ct +962 4 946 -4 933 -20 ct 921 -35 915 -57 915 -84 ct 915 -109 921 -128 934 -143 ct +946 -158 962 -166 981 -166 ct 1003 -166 1019 -158 1030 -142 ct 1030 -142 1030 -142 1030 -231 ct +1030 -231 1030 -231 1057 -231 ct 1057 -231 1057 -231 1057 0 ct p +1030 -47 m 1030 -47 1030 -47 1030 -116 ct 1026 -123 1021 -130 1013 -135 ct +1005 -140 997 -142 988 -142 ct 974 -142 963 -137 955 -126 ct 947 -116 943 -101 943 -82 ct +943 -62 947 -47 955 -36 ct 964 -25 975 -20 989 -20 ct 995 -20 1001 -21 1007 -24 ct +1013 -27 1018 -31 1023 -36 ct 1028 -41 1030 -45 1030 -47 ct p ef +1244 -17 m 1221 -3 1199 4 1177 4 ct 1151 4 1130 -4 1115 -19 ct 1100 -34 1093 -55 1093 -81 ct +1093 -107 1100 -127 1114 -143 ct 1127 -158 1146 -166 1169 -166 ct 1190 -166 1208 -159 1221 -144 ct +1234 -130 1241 -111 1241 -86 ct 1241 -86 1241 -86 1241 -79 ct 1241 -79 1241 -79 1121 -79 ct +1122 -60 1127 -45 1137 -35 ct 1146 -25 1160 -20 1177 -20 ct 1197 -20 1217 -26 1237 -38 ct +1237 -38 1237 -38 1244 -17 ct p +1213 -100 m 1212 -113 1207 -123 1199 -131 ct 1190 -138 1181 -142 1169 -142 ct +1157 -142 1147 -138 1138 -131 ct 1130 -124 1125 -113 1122 -100 ct 1122 -100 1122 -100 1213 -100 ct +p ef +1305 -142 m 1318 -158 1335 -166 1355 -166 ct 1374 -166 1389 -158 1402 -143 ct +1415 -128 1421 -109 1421 -84 ct 1421 -57 1415 -36 1402 -20 ct 1389 -4 1373 4 1354 4 ct +1334 4 1318 -4 1305 -19 ct 1305 -19 1305 -19 1305 63 ct 1305 63 1305 63 1278 63 ct +1278 63 1278 63 1278 -166 ct 1278 -166 1278 -166 1305 -166 ct 1305 -166 1305 -166 1305 -142 ct +p +1305 -116 m 1305 -116 1305 -116 1305 -47 ct 1309 -40 1315 -33 1323 -28 ct 1331 -23 1339 -20 1347 -20 ct +1362 -20 1373 -25 1381 -36 ct 1389 -47 1393 -62 1393 -82 ct 1393 -101 1389 -116 1381 -126 ct +1373 -137 1362 -142 1347 -142 ct 1340 -142 1333 -140 1325 -135 ct 1317 -130 1311 -124 1305 -116 ct +p ef +1599 -17 m 1576 -3 1554 4 1532 4 ct 1506 4 1485 -4 1470 -19 ct 1455 -34 1448 -55 1448 -81 ct +1448 -107 1455 -127 1469 -143 ct 1482 -158 1501 -166 1524 -166 ct 1545 -166 1563 -159 1576 -144 ct +1589 -130 1596 -111 1596 -86 ct 1596 -86 1596 -86 1596 -79 ct 1596 -79 1596 -79 1476 -79 ct +1477 -60 1482 -45 1492 -35 ct 1501 -25 1515 -20 1532 -20 ct 1552 -20 1572 -26 1592 -38 ct +1592 -38 1592 -38 1599 -17 ct p +1568 -100 m 1567 -113 1562 -123 1554 -131 ct 1545 -138 1536 -142 1524 -142 ct +1512 -142 1502 -138 1493 -131 ct 1485 -124 1480 -113 1477 -100 ct 1477 -100 1477 -100 1568 -100 ct +p ef +1769 0 m 1769 0 1769 0 1742 0 ct 1742 0 1742 0 1742 -103 ct 1742 -115 1739 -125 1733 -132 ct +1727 -139 1718 -142 1708 -142 ct 1692 -142 1676 -133 1661 -115 ct 1661 -115 1661 -115 1661 0 ct +1661 0 1661 0 1634 0 ct 1634 0 1634 0 1634 -162 ct 1634 -162 1634 -162 1661 -162 ct +1661 -162 1661 -162 1661 -139 ct 1678 -157 1696 -166 1715 -166 ct 1732 -166 1745 -161 1755 -151 ct +1764 -142 1769 -128 1769 -110 ct 1769 -110 1769 -110 1769 0 ct p ef +1946 0 m 1946 0 1946 0 1919 0 ct 1919 0 1919 0 1919 -20 ct 1907 -4 1892 4 1872 4 ct +1851 4 1835 -4 1822 -20 ct 1810 -35 1804 -57 1804 -84 ct 1804 -109 1810 -128 1823 -143 ct +1835 -158 1851 -166 1870 -166 ct 1892 -166 1908 -158 1919 -142 ct 1919 -142 1919 -142 1919 -231 ct +1919 -231 1919 -231 1946 -231 ct 1946 -231 1946 -231 1946 0 ct p +1919 -47 m 1919 -47 1919 -47 1919 -116 ct 1915 -123 1910 -130 1902 -135 ct +1894 -140 1886 -142 1877 -142 ct 1863 -142 1852 -137 1844 -126 ct 1836 -116 1832 -101 1832 -82 ct +1832 -62 1836 -47 1844 -36 ct 1853 -25 1864 -20 1878 -20 ct 1884 -20 1890 -21 1896 -24 ct +1902 -27 1907 -31 1912 -36 ct 1917 -41 1919 -45 1919 -47 ct p ef +2099 -127 m 2082 -137 2066 -142 2050 -142 ct 2038 -142 2029 -140 2022 -136 ct +2015 -133 2012 -128 2012 -121 ct 2012 -116 2014 -113 2019 -109 ct 2023 -106 2030 -103 2040 -101 ct +2040 -101 2040 -101 2061 -94 ct 2081 -88 2095 -81 2103 -74 ct 2110 -67 2114 -57 2114 -46 ct +2114 -30 2108 -18 2096 -9 ct 2085 0 2069 4 2049 4 ct 2025 4 2004 -2 1984 -14 ct +1984 -14 1984 -14 1993 -35 ct 2011 -25 2029 -20 2047 -20 ct 2074 -20 2087 -28 2087 -43 ct +2087 -49 2084 -54 2078 -58 ct 2073 -63 2061 -67 2042 -73 ct 2028 -77 2018 -81 2012 -83 ct +2007 -85 2002 -88 1998 -92 ct 1993 -95 1990 -99 1988 -104 ct 1986 -109 1985 -114 1985 -119 ct +1985 -133 1991 -145 2002 -153 ct 2013 -162 2029 -166 2050 -166 ct 2059 -166 2068 -164 2079 -161 ct +2089 -158 2099 -154 2107 -148 ct 2107 -148 2107 -148 2099 -127 ct p ef +2307 -166 m 2330 -166 2348 -158 2362 -143 ct 2375 -127 2382 -107 2382 -81 ct +2382 -55 2375 -35 2362 -19 ct 2348 -4 2330 4 2307 4 ct 2283 4 2265 -4 2251 -19 ct +2238 -35 2231 -55 2231 -81 ct 2231 -107 2238 -127 2251 -143 ct 2265 -158 2283 -166 2307 -166 ct +p +2307 -20 m 2321 -20 2333 -26 2341 -38 ct 2350 -49 2354 -64 2354 -81 ct 2354 -99 2350 -114 2342 -125 ct +2333 -136 2322 -142 2307 -142 ct 2291 -142 2280 -136 2271 -125 ct 2263 -114 2259 -100 2259 -81 ct +2259 -64 2263 -49 2272 -38 ct 2280 -26 2292 -20 2307 -20 ct p ef +2552 0 m 2552 0 2552 0 2525 0 ct 2525 0 2525 0 2525 -103 ct 2525 -115 2522 -125 2516 -132 ct +2510 -139 2501 -142 2491 -142 ct 2475 -142 2459 -133 2444 -115 ct 2444 -115 2444 -115 2444 0 ct +2444 0 2444 0 2417 0 ct 2417 0 2417 0 2417 -162 ct 2417 -162 2417 -162 2444 -162 ct +2444 -162 2444 -162 2444 -139 ct 2461 -157 2479 -166 2498 -166 ct 2515 -166 2528 -161 2538 -151 ct +2547 -142 2552 -128 2552 -110 ct 2552 -110 2552 -110 2552 0 ct p ef +pom +gr +gs +pum +4456 12761 t +0.003 0.003 0.003 c 130 -127 m 113 -137 97 -142 81 -142 ct 69 -142 60 -140 53 -136 ct +46 -133 43 -128 43 -121 ct 43 -116 45 -113 50 -109 ct 54 -106 61 -103 71 -101 ct +71 -101 71 -101 92 -94 ct 112 -88 126 -81 134 -74 ct 141 -67 145 -57 145 -46 ct +145 -30 139 -18 127 -9 ct 116 0 100 4 80 4 ct 56 4 35 -2 15 -14 ct 15 -14 15 -14 24 -35 ct +42 -25 60 -20 78 -20 ct 105 -20 118 -28 118 -43 ct 118 -49 115 -54 109 -58 ct 104 -63 92 -67 73 -73 ct +59 -77 49 -81 43 -83 ct 38 -85 33 -88 29 -92 ct 24 -95 21 -99 19 -104 ct 17 -109 16 -114 16 -119 ct +16 -133 22 -145 33 -153 ct 44 -162 60 -166 81 -166 ct 90 -166 99 -164 110 -161 ct +120 -158 130 -154 138 -148 ct 138 -148 138 -148 130 -127 ct p ef +249 -2 m 239 2 231 4 225 4 ct 211 4 201 0 195 -8 ct 188 -16 185 -28 185 -45 ct +185 -45 185 -45 185 -140 ct 185 -140 185 -140 165 -140 ct 165 -140 165 -140 165 -162 ct +165 -162 165 -162 185 -162 ct 185 -162 185 -162 185 -206 ct 185 -206 185 -206 212 -206 ct +212 -206 212 -206 212 -162 ct 212 -162 212 -162 243 -162 ct 243 -162 243 -162 243 -140 ct +243 -140 243 -140 212 -140 ct 212 -140 212 -140 212 -47 ct 212 -29 218 -20 229 -20 ct +233 -20 239 -21 245 -23 ct 245 -23 245 -23 249 -2 ct p ef +405 0 m 405 0 405 0 378 0 ct 378 0 378 0 378 -20 ct 366 -4 351 4 331 4 ct 310 4 294 -4 281 -20 ct +269 -35 263 -57 263 -84 ct 263 -109 269 -128 282 -143 ct 294 -158 310 -166 329 -166 ct +351 -166 367 -158 378 -142 ct 378 -142 378 -142 378 -231 ct 378 -231 378 -231 405 -231 ct +405 -231 405 -231 405 0 ct p +378 -47 m 378 -47 378 -47 378 -116 ct 374 -123 369 -130 361 -135 ct 353 -140 345 -142 336 -142 ct +322 -142 311 -137 303 -126 ct 295 -116 291 -101 291 -82 ct 291 -62 295 -47 303 -36 ct +312 -25 323 -20 337 -20 ct 343 -20 349 -21 355 -24 ct 361 -27 366 -31 371 -36 ct +376 -41 378 -45 378 -47 ct p ef +477 0 m 450 0 l 450 -162 l 477 -162 l 477 0 l p +463 -231 m 468 -231 472 -229 475 -226 ct 478 -223 480 -219 480 -214 ct 480 -210 478 -206 475 -203 ct +472 -200 468 -198 463 -198 ct 459 -198 455 -200 452 -203 ct 449 -206 447 -210 447 -214 ct +447 -219 449 -223 452 -226 ct 455 -229 459 -231 463 -231 ct p ef +589 -166 m 612 -166 630 -158 644 -143 ct 657 -127 664 -107 664 -81 ct 664 -55 657 -35 644 -19 ct +630 -4 612 4 589 4 ct 565 4 547 -4 533 -19 ct 520 -35 513 -55 513 -81 ct 513 -107 520 -127 533 -143 ct +547 -158 565 -166 589 -166 ct p +589 -20 m 603 -20 615 -26 623 -38 ct 632 -49 636 -64 636 -81 ct 636 -99 632 -114 624 -125 ct +615 -136 604 -142 589 -142 ct 573 -142 562 -136 553 -125 ct 545 -114 541 -100 541 -81 ct +541 -64 545 -49 554 -38 ct 562 -26 574 -20 589 -20 ct p ef +720 -35 m 726 -35 730 -33 734 -30 ct 737 -26 739 -22 739 -16 ct 739 -11 737 -7 734 -3 ct +730 0 726 2 720 2 ct 715 2 711 0 707 -3 ct 704 -7 702 -11 702 -16 ct 702 -22 704 -26 707 -30 ct +711 -33 715 -35 720 -35 ct p ef +922 0 m 922 0 922 0 895 0 ct 895 0 895 0 895 -103 ct 895 -115 892 -125 886 -132 ct +880 -139 871 -142 861 -142 ct 845 -142 829 -133 814 -115 ct 814 -115 814 -115 814 0 ct +814 0 814 0 787 0 ct 787 0 787 0 787 -231 ct 787 -231 787 -231 814 -231 ct 814 -231 814 -231 814 -139 ct +831 -157 849 -166 868 -166 ct 885 -166 898 -161 908 -151 ct 917 -142 922 -128 922 -110 ct +922 -110 922 -110 922 0 ct p ef +966 -231 m 988 -207 1004 -184 1014 -163 ct 1024 -141 1029 -117 1029 -90 ct +1029 -63 1024 -38 1014 -16 ct 1004 5 988 28 966 52 ct 966 52 966 52 955 45 ct 971 24 982 3 990 -19 ct +997 -40 1001 -64 1001 -90 ct 1001 -115 997 -139 990 -160 ct 982 -182 971 -203 955 -224 ct +955 -224 955 -224 966 -231 ct p ef +pom +gr +gr +0.503 0.503 0.503 c 5575 4309 m 2665 4309 l 2665 986 l 8485 986 l 8485 4309 l +5575 4309 l p ef +5575 4309 m 2665 4309 l 2665 986 l 8485 986 l 8485 4309 l 5575 4309 l +pc +1.000 0.902 0.777 c 5475 4209 m 2565 4209 l 2565 886 l 8385 886 l 8385 4209 l +5475 4209 l p ef +0.003 0.003 0.003 c 5475 4209 m 2565 4209 l 2565 886 l 8385 886 l 8385 4209 l +5475 4209 l pc +gs +gs +pum +3054 1356 t +35 0 m 58 -93 l 11 -93 l 18 -124 l 66 -124 l 80 -184 l 33 -184 l +41 -215 l 88 -215 l 111 -306 l 142 -306 l 120 -215 l 168 -215 l 191 -306 l +222 -306 l 200 -215 l 246 -215 l 239 -184 l 192 -184 l 177 -124 l +224 -124 l 216 -93 l 169 -93 l 146 0 l 115 0 l 138 -93 l 89 -93 l +66 0 l 35 0 l p +97 -124 m 146 -124 l 160 -184 l 112 -184 l 97 -124 l p ef +371 0 m 371 -193 l 289 -193 l 289 -224 l 412 -224 l 412 0 l 371 0 l +p +366 -275 m 366 -326 l 417 -326 l 417 -275 l 366 -275 l p ef +545 0 m 545 0 545 0 545 -224 ct 545 -224 545 -224 586 -224 ct 586 -224 586 -224 584 -182 ct +584 -182 584 -182 586 -182 ct 596 -198 607 -209 620 -217 ct 632 -225 647 -229 663 -229 ct +684 -229 700 -223 711 -210 ct 722 -197 727 -178 727 -153 ct 727 -153 727 -153 727 0 ct +727 0 727 0 686 0 ct 686 0 686 0 686 -142 ct 686 -159 683 -172 678 -179 ct 672 -186 663 -190 650 -190 ct +640 -190 630 -186 619 -179 ct 608 -172 597 -161 586 -146 ct 586 -146 586 -146 586 0 ct +586 0 586 0 545 0 ct p ef +990 -7 m 966 1 942 5 918 5 ct 879 5 849 -5 828 -26 ct 807 -46 796 -75 796 -112 ct +796 -149 806 -177 827 -198 ct 848 -219 877 -229 914 -229 ct 938 -229 962 -225 986 -218 ct +986 -218 986 -218 986 -184 ct 959 -193 937 -198 918 -198 ct 894 -198 874 -190 860 -175 ct +846 -160 839 -139 839 -112 ct 839 -85 846 -64 861 -49 ct 876 -34 897 -26 923 -26 ct +943 -26 965 -31 990 -40 ct 990 -40 990 -40 990 -7 ct p ef +1138 0 m 1138 -295 l 1051 -295 l 1051 -326 l 1179 -326 l 1179 0 l +1138 0 l p ef +1488 -224 m 1488 -224 1488 -224 1488 0 ct 1488 0 1488 0 1447 0 ct 1447 0 1447 0 1449 -42 ct +1449 -42 1449 -42 1447 -42 ct 1438 -26 1426 -15 1414 -7 ct 1401 1 1386 5 1370 5 ct +1349 5 1333 -1 1322 -14 ct 1311 -27 1306 -46 1306 -71 ct 1306 -71 1306 -71 1306 -224 ct +1306 -224 1306 -224 1347 -224 ct 1347 -224 1347 -224 1347 -82 ct 1347 -65 1350 -52 1355 -45 ct +1361 -38 1370 -34 1383 -34 ct 1393 -34 1403 -38 1414 -45 ct 1425 -52 1436 -63 1447 -78 ct +1447 -78 1447 -78 1447 -224 ct 1447 -224 1447 -224 1488 -224 ct p ef +1706 0 m 1706 0 1706 0 1708 -42 ct 1708 -42 1708 -42 1706 -42 ct 1696 -26 1685 -15 1673 -7 ct +1660 1 1647 5 1632 5 ct 1607 5 1587 -5 1572 -24 ct 1557 -44 1550 -71 1550 -105 ct +1550 -142 1559 -172 1576 -195 ct 1594 -218 1616 -229 1644 -229 ct 1656 -229 1668 -226 1678 -221 ct +1688 -216 1698 -209 1706 -198 ct 1706 -198 1706 -198 1708 -198 ct 1708 -198 1708 -198 1706 -229 ct +1706 -229 1706 -229 1706 -326 ct 1706 -326 1706 -326 1747 -326 ct 1747 -326 1747 -326 1747 0 ct +1747 0 1747 0 1706 0 ct p +1706 -168 m 1696 -178 1687 -185 1678 -190 ct 1668 -195 1659 -198 1650 -198 ct +1632 -198 1618 -190 1608 -175 ct 1598 -159 1593 -137 1593 -109 ct 1593 -83 1597 -63 1605 -50 ct +1613 -38 1624 -31 1640 -31 ct 1652 -31 1663 -35 1674 -42 ct 1685 -49 1696 -59 1706 -73 ct +1706 -73 1706 -73 1706 -168 ct p ef +2004 -9 m 1976 0 1950 5 1926 5 ct 1888 5 1859 -5 1838 -25 ct 1817 -45 1807 -73 1807 -110 ct +1807 -144 1817 -173 1837 -195 ct 1857 -218 1882 -229 1913 -229 ct 1944 -229 1966 -220 1981 -201 ct +1996 -182 2003 -153 2003 -114 ct 2003 -114 2003 -114 2003 -101 ct 2003 -101 2003 -101 1849 -101 ct +1850 -76 1858 -57 1872 -45 ct 1886 -32 1905 -26 1931 -26 ct 1954 -26 1978 -31 2004 -42 ct +2004 -42 2004 -42 2004 -9 ct p +1850 -132 m 1850 -132 1850 -132 1960 -132 ct 1960 -132 1960 -132 1960 -138 ct +1960 -158 1956 -173 1947 -183 ct 1938 -193 1926 -198 1909 -198 ct 1892 -198 1879 -192 1868 -181 ct +1858 -169 1852 -153 1850 -132 ct p ef +2523 0 m 2304 -110 l 2523 -219 l 2523 -185 l 2372 -110 l 2523 -34 l +2523 0 l p ef +2579 -9 m 2579 -9 2579 -9 2579 -45 ct 2610 -32 2637 -26 2660 -26 ct 2676 -26 2690 -29 2701 -36 ct +2712 -43 2717 -51 2717 -61 ct 2717 -74 2704 -84 2679 -93 ct 2679 -93 2679 -93 2636 -107 ct +2602 -118 2585 -138 2585 -165 ct 2585 -186 2593 -201 2608 -212 ct 2623 -223 2645 -229 2673 -229 ct +2694 -229 2718 -226 2746 -219 ct 2746 -219 2746 -219 2746 -186 ct 2719 -194 2695 -198 2673 -198 ct +2657 -198 2644 -196 2636 -191 ct 2628 -186 2624 -179 2624 -169 ct 2624 -158 2634 -149 2654 -142 ct +2654 -142 2654 -142 2706 -124 ct 2741 -111 2758 -91 2758 -64 ct 2758 -43 2749 -26 2732 -14 ct +2714 -1 2691 5 2661 5 ct 2636 5 2608 0 2579 -9 ct p ef +3022 0 m 3002 3 2982 5 2963 5 ct 2930 5 2907 -1 2895 -13 ct 2883 -25 2877 -47 2877 -80 ct +2877 -80 2877 -80 2877 -188 ct 2877 -188 2877 -188 2821 -188 ct 2821 -188 2821 -188 2821 -219 ct +2821 -219 2821 -219 2877 -219 ct 2877 -219 2877 -219 2877 -267 ct 2877 -267 2877 -267 2918 -267 ct +2918 -267 2918 -267 2918 -219 ct 2918 -219 2918 -219 3017 -219 ct 3017 -219 3017 -219 3017 -188 ct +3017 -188 3017 -188 2918 -188 ct 2918 -188 2918 -188 2918 -74 ct 2918 -61 2919 -53 2920 -48 ct +2922 -43 2925 -39 2931 -35 ct 2940 -29 2953 -26 2971 -26 ct 2988 -26 3005 -28 3022 -31 ct +3022 -31 3022 -31 3022 0 ct p ef +3230 0 m 3230 0 3230 0 3232 -42 ct 3232 -42 3232 -42 3230 -42 ct 3220 -26 3209 -15 3197 -7 ct +3184 1 3171 5 3156 5 ct 3131 5 3111 -5 3096 -24 ct 3081 -44 3074 -71 3074 -105 ct +3074 -142 3083 -172 3100 -195 ct 3118 -218 3140 -229 3168 -229 ct 3180 -229 3192 -226 3202 -221 ct +3212 -216 3222 -209 3230 -198 ct 3230 -198 3230 -198 3232 -198 ct 3232 -198 3232 -198 3230 -229 ct +3230 -229 3230 -229 3230 -326 ct 3230 -326 3230 -326 3271 -326 ct 3271 -326 3271 -326 3271 0 ct +3271 0 3271 0 3230 0 ct p +3230 -168 m 3220 -178 3211 -185 3202 -190 ct 3192 -195 3183 -198 3174 -198 ct +3156 -198 3142 -190 3132 -175 ct 3122 -159 3117 -137 3117 -109 ct 3117 -83 3121 -63 3129 -50 ct +3137 -38 3148 -31 3164 -31 ct 3176 -31 3187 -35 3198 -42 ct 3209 -49 3220 -59 3230 -73 ct +3230 -73 3230 -73 3230 -168 ct p ef +3419 0 m 3419 -193 l 3337 -193 l 3337 -224 l 3460 -224 l 3460 0 l +3419 0 l p +3414 -275 m 3414 -326 l 3465 -326 l 3465 -275 l 3414 -275 l p ef +3682 5 m 3650 5 3625 -6 3606 -27 ct 3587 -48 3578 -76 3578 -112 ct 3578 -148 3587 -177 3606 -198 ct +3625 -219 3651 -229 3684 -229 ct 3716 -229 3742 -219 3761 -198 ct 3780 -177 3789 -149 3789 -113 ct +3789 -76 3780 -47 3761 -26 ct 3742 -5 3716 5 3682 5 ct p +3683 -26 m 3704 -26 3720 -33 3730 -48 ct 3741 -62 3746 -84 3746 -113 ct 3746 -139 3740 -160 3729 -175 ct +3718 -190 3703 -198 3684 -198 ct 3664 -198 3649 -190 3638 -175 ct 3627 -160 3621 -139 3621 -112 ct +3621 -85 3626 -64 3637 -49 ct 3648 -34 3664 -26 3683 -26 ct p ef +3907 0 m 3907 -61 l 3968 -61 l 3968 0 l 3907 0 l p ef +4101 0 m 4101 0 4101 0 4101 -326 ct 4101 -326 4101 -326 4142 -326 ct 4142 -326 4142 -326 4142 -224 ct +4142 -224 4142 -224 4140 -182 ct 4140 -182 4140 -182 4142 -182 ct 4152 -198 4163 -209 4176 -217 ct +4188 -225 4203 -229 4219 -229 ct 4240 -229 4256 -223 4267 -210 ct 4278 -197 4283 -178 4283 -153 ct +4283 -153 4283 -153 4283 0 ct 4283 0 4283 0 4242 0 ct 4242 0 4242 0 4242 -142 ct +4242 -159 4239 -172 4234 -179 ct 4228 -186 4219 -190 4206 -190 ct 4196 -190 4186 -186 4175 -179 ct +4164 -172 4153 -161 4142 -146 ct 4142 -146 4142 -146 4142 0 ct 4142 0 4142 0 4101 0 ct +p ef +4336 0 m 4555 -110 l 4336 -219 l 4336 -185 l 4487 -110 l 4336 -34 l +4336 0 l p ef +pom +gr +gs +pum +3054 1847 t +0.003 0.003 1.000 c 33 -8 m 33 -8 33 -8 33 -54 ct 67 -42 95 -36 115 -36 ct 130 -36 141 -38 149 -42 ct +156 -46 160 -52 160 -60 ct 160 -64 158 -68 154 -72 ct 151 -75 145 -79 138 -82 ct +138 -82 138 -82 90 -101 ct 71 -109 57 -118 48 -127 ct 39 -137 34 -148 34 -161 ct +34 -182 44 -199 63 -211 ct 82 -223 109 -229 143 -229 ct 163 -229 186 -226 212 -221 ct +212 -221 212 -221 212 -174 ct 184 -183 160 -188 141 -188 ct 126 -188 116 -186 109 -183 ct +102 -180 98 -175 98 -169 ct 98 -165 101 -162 106 -158 ct 111 -154 118 -150 128 -146 ct +128 -146 128 -146 181 -124 ct 197 -118 209 -110 216 -100 ct 224 -91 228 -79 228 -66 ct +228 -45 219 -28 200 -15 ct 181 -2 157 5 127 5 ct 101 5 69 1 33 -8 ct p ef +356 0 m 356 -285 l 274 -285 l 274 -326 l 417 -326 l 417 0 l 356 0 l +p ef +630 0 m 630 -183 l 548 -183 l 548 -224 l 691 -224 l 691 0 l 630 0 l +p +630 -265 m 630 -326 l 691 -326 l 691 -265 l 630 -265 l p ef +989 -4 m 964 2 939 5 914 5 ct 873 5 840 -5 817 -26 ct 794 -47 782 -75 782 -111 ct +782 -148 793 -177 816 -198 ct 838 -219 870 -229 910 -229 ct 940 -229 966 -226 989 -220 ct +989 -220 989 -220 989 -175 ct 964 -184 941 -188 918 -188 ct 896 -188 879 -182 867 -169 ct +854 -157 848 -140 848 -118 ct 848 -94 856 -74 871 -60 ct 886 -45 906 -38 931 -38 ct +950 -38 970 -42 989 -49 ct 989 -49 989 -49 989 -4 ct p ef +1252 -95 m 1252 -95 1252 -95 1100 -95 ct 1103 -77 1111 -63 1123 -54 ct 1135 -45 1151 -41 1172 -41 ct +1196 -41 1223 -46 1252 -56 ct 1252 -56 1252 -56 1252 -9 ct 1217 0 1186 5 1160 5 ct +1122 5 1091 -6 1068 -27 ct 1045 -48 1034 -76 1034 -111 ct 1034 -147 1045 -175 1066 -197 ct +1088 -218 1116 -229 1151 -229 ct 1183 -229 1207 -219 1225 -199 ct 1243 -180 1252 -152 1252 -118 ct +1252 -118 1252 -118 1252 -95 ct p +1099 -136 m 1099 -136 1099 -136 1193 -136 ct 1193 -153 1189 -166 1182 -175 ct +1174 -184 1163 -188 1148 -188 ct 1134 -188 1122 -184 1114 -175 ct 1106 -166 1101 -153 1099 -136 ct +p ef +1751 -4 m 1726 2 1701 5 1676 5 ct 1635 5 1602 -5 1579 -26 ct 1556 -47 1544 -75 1544 -111 ct +1544 -148 1555 -177 1578 -198 ct 1600 -219 1632 -229 1672 -229 ct 1702 -229 1728 -226 1751 -220 ct +1751 -220 1751 -220 1751 -175 ct 1726 -184 1703 -188 1680 -188 ct 1658 -188 1641 -182 1629 -169 ct +1616 -157 1610 -140 1610 -118 ct 1610 -94 1618 -74 1633 -60 ct 1648 -45 1668 -38 1693 -38 ct +1712 -38 1732 -42 1751 -49 ct 1751 -49 1751 -49 1751 -4 ct p ef +1880 0 m 1880 -285 l 1798 -285 l 1798 -326 l 1941 -326 l 1941 0 l +1880 0 l p ef +2185 -24 m 2178 -14 2169 -7 2159 -2 ct 2149 3 2138 5 2125 5 ct 2103 5 2085 -2 2071 -15 ct +2057 -28 2050 -45 2050 -65 ct 2050 -91 2060 -111 2079 -124 ct 2099 -137 2128 -143 2167 -143 ct +2167 -143 2167 -143 2191 -143 ct 2191 -143 2191 -143 2191 -154 ct 2191 -165 2187 -174 2179 -179 ct +2171 -185 2159 -188 2143 -188 ct 2121 -188 2096 -182 2069 -169 ct 2069 -169 2069 -169 2069 -214 ct +2097 -224 2125 -229 2154 -229 ct 2186 -229 2210 -223 2226 -211 ct 2236 -203 2243 -194 2247 -185 ct +2250 -175 2252 -160 2252 -140 ct 2252 -140 2252 -140 2252 -64 ct 2252 -49 2257 -41 2266 -41 ct +2268 -41 2270 -41 2273 -42 ct 2273 -42 2273 -42 2273 -2 ct 2261 3 2249 5 2239 5 ct +2228 5 2218 3 2210 -2 ct 2202 -7 2196 -14 2191 -24 ct 2191 -24 2191 -24 2185 -24 ct +p +2191 -65 m 2191 -65 2191 -65 2191 -102 ct 2191 -102 2191 -102 2169 -102 ct +2150 -102 2135 -99 2126 -94 ct 2116 -88 2111 -80 2111 -69 ct 2111 -61 2114 -54 2120 -49 ct +2126 -44 2133 -41 2142 -41 ct 2157 -41 2174 -49 2191 -65 ct p ef +2319 -8 m 2319 -8 2319 -8 2319 -54 ct 2353 -42 2381 -36 2401 -36 ct 2416 -36 2427 -38 2435 -42 ct +2442 -46 2446 -52 2446 -60 ct 2446 -64 2444 -68 2440 -72 ct 2437 -75 2431 -79 2424 -82 ct +2424 -82 2424 -82 2376 -101 ct 2357 -109 2343 -118 2334 -127 ct 2325 -137 2320 -148 2320 -161 ct +2320 -182 2330 -199 2349 -211 ct 2368 -223 2395 -229 2429 -229 ct 2449 -229 2472 -226 2498 -221 ct +2498 -221 2498 -221 2498 -174 ct 2470 -183 2446 -188 2427 -188 ct 2412 -188 2402 -186 2395 -183 ct +2388 -180 2384 -175 2384 -169 ct 2384 -165 2387 -162 2392 -158 ct 2397 -154 2404 -150 2414 -146 ct +2414 -146 2414 -146 2467 -124 ct 2483 -118 2495 -110 2502 -100 ct 2510 -91 2514 -79 2514 -66 ct +2514 -45 2505 -28 2486 -15 ct 2467 -2 2443 5 2413 5 ct 2387 5 2355 1 2319 -8 ct +p ef +2573 -8 m 2573 -8 2573 -8 2573 -54 ct 2607 -42 2635 -36 2655 -36 ct 2670 -36 2681 -38 2689 -42 ct +2696 -46 2700 -52 2700 -60 ct 2700 -64 2698 -68 2694 -72 ct 2691 -75 2685 -79 2678 -82 ct +2678 -82 2678 -82 2630 -101 ct 2611 -109 2597 -118 2588 -127 ct 2579 -137 2574 -148 2574 -161 ct +2574 -182 2584 -199 2603 -211 ct 2622 -223 2649 -229 2683 -229 ct 2703 -229 2726 -226 2752 -221 ct +2752 -221 2752 -221 2752 -174 ct 2724 -183 2700 -188 2681 -188 ct 2666 -188 2656 -186 2649 -183 ct +2642 -180 2638 -175 2638 -169 ct 2638 -165 2641 -162 2646 -158 ct 2651 -154 2658 -150 2668 -146 ct +2668 -146 2668 -146 2721 -124 ct 2737 -118 2749 -110 2756 -100 ct 2764 -91 2768 -79 2768 -66 ct +2768 -45 2759 -28 2740 -15 ct 2721 -2 2697 5 2667 5 ct 2641 5 2609 1 2573 -8 ct +p ef +pom +gr +gs +pum +5848 1847 t +281 0 m 281 0 281 0 281 -306 ct 281 -306 281 -306 361 -306 ct 405 -306 438 -294 460 -269 ct +482 -244 493 -207 493 -158 ct 493 -105 481 -66 457 -39 ct 433 -13 398 0 350 0 ct +350 0 350 0 281 0 ct p +322 -31 m 322 -31 322 -31 342 -31 ct 381 -31 409 -41 425 -60 ct 442 -79 450 -111 450 -155 ct +450 -204 439 -238 417 -257 ct 403 -269 378 -275 341 -275 ct 341 -275 341 -275 322 -275 ct +322 -275 322 -275 322 -31 ct p ef +726 -224 m 726 -224 726 -224 726 0 ct 726 0 726 0 685 0 ct 685 0 685 0 687 -42 ct +687 -42 687 -42 685 -42 ct 676 -26 664 -15 652 -7 ct 639 1 624 5 608 5 ct 587 5 571 -1 560 -14 ct +549 -27 544 -46 544 -71 ct 544 -71 544 -71 544 -224 ct 544 -224 544 -224 585 -224 ct +585 -224 585 -224 585 -82 ct 585 -65 588 -52 593 -45 ct 599 -38 608 -34 621 -34 ct +631 -34 641 -38 652 -45 ct 663 -52 674 -63 685 -78 ct 685 -78 685 -78 685 -224 ct +685 -224 685 -224 726 -224 ct p ef +781 0 m 781 0 781 0 781 -224 ct 781 -224 781 -224 817 -224 ct 817 -224 817 -224 814 -182 ct +814 -182 814 -182 817 -182 ct 825 -198 834 -209 843 -217 ct 851 -225 859 -229 867 -229 ct +878 -229 886 -225 893 -216 ct 900 -208 904 -196 905 -182 ct 905 -182 905 -182 908 -182 ct +915 -198 923 -209 931 -217 ct 940 -225 949 -229 959 -229 ct 972 -229 982 -224 989 -213 ct +996 -202 999 -186 999 -164 ct 999 -164 999 -164 999 0 ct 999 0 999 0 963 0 ct 963 0 963 0 963 -162 ct +963 -172 962 -180 960 -185 ct 958 -190 954 -193 950 -193 ct 944 -193 937 -189 930 -181 ct +923 -173 915 -160 908 -144 ct 908 -144 908 -144 908 0 ct 908 0 908 0 872 0 ct 872 0 872 0 872 -155 ct +872 -167 871 -177 869 -183 ct 866 -190 863 -193 859 -193 ct 853 -193 846 -188 838 -179 ct +830 -170 823 -158 817 -144 ct 817 -144 817 -144 817 0 ct 817 0 817 0 781 0 ct p ef +1053 82 m 1053 82 1053 82 1053 -224 ct 1053 -224 1053 -224 1094 -224 ct 1094 -224 1094 -224 1092 -182 ct +1092 -182 1092 -182 1094 -182 ct 1104 -198 1115 -209 1127 -217 ct 1139 -225 1153 -229 1167 -229 ct +1192 -229 1212 -219 1227 -200 ct 1242 -180 1249 -153 1249 -120 ct 1249 -82 1240 -52 1223 -29 ct +1206 -6 1183 5 1155 5 ct 1143 5 1132 2 1122 -3 ct 1112 -8 1102 -15 1094 -26 ct +1094 -26 1094 -26 1092 -26 ct 1092 -26 1092 -26 1094 5 ct 1094 5 1094 5 1094 82 ct +1094 82 1094 82 1053 82 ct p +1094 -56 m 1103 -46 1113 -39 1122 -34 ct 1131 -29 1140 -26 1150 -26 ct 1168 -26 1181 -34 1191 -49 ct +1201 -65 1206 -87 1206 -115 ct 1206 -141 1202 -160 1194 -173 ct 1186 -186 1175 -193 1159 -193 ct +1148 -193 1136 -189 1125 -182 ct 1115 -175 1104 -165 1094 -151 ct 1094 -151 1094 -151 1094 -56 ct +p ef +1736 -326 m 1736 -326 1736 -326 1736 -295 ct 1736 -295 1736 -295 1720 -295 ct +1699 -295 1685 -293 1677 -287 ct 1668 -282 1664 -274 1664 -261 ct 1664 -257 1665 -251 1666 -242 ct +1666 -242 1666 -242 1670 -214 ct 1671 -204 1672 -196 1672 -190 ct 1672 -175 1669 -163 1662 -153 ct +1655 -144 1645 -137 1631 -132 ct 1645 -128 1655 -121 1662 -111 ct 1669 -102 1672 -90 1672 -75 ct +1672 -68 1671 -61 1670 -51 ct 1670 -51 1670 -51 1666 -23 ct 1665 -14 1664 -8 1664 -4 ct +1664 9 1668 17 1677 22 ct 1685 27 1699 30 1720 30 ct 1720 30 1720 30 1736 30 ct +1736 30 1736 30 1736 61 ct 1736 61 1736 61 1713 61 ct 1684 61 1662 56 1648 46 ct +1633 36 1626 21 1626 2 ct 1626 -7 1627 -16 1629 -26 ct 1629 -26 1629 -26 1636 -63 ct +1637 -68 1637 -74 1637 -79 ct 1637 -92 1633 -101 1625 -108 ct 1618 -114 1606 -117 1591 -117 ct +1591 -117 1591 -117 1572 -117 ct 1572 -117 1572 -117 1572 -148 ct 1572 -148 1572 -148 1591 -148 ct +1606 -148 1618 -151 1625 -157 ct 1633 -164 1637 -173 1637 -186 ct 1637 -191 1637 -197 1636 -202 ct +1636 -202 1636 -202 1629 -239 ct 1627 -249 1626 -258 1626 -267 ct 1626 -286 1633 -301 1648 -311 ct +1662 -321 1684 -326 1713 -326 ct 1713 -326 1713 -326 1736 -326 ct p ef +pom +gr +gs +pum +3054 2338 t +pom +gr +gs +pum +3562 2338 t +0.003 0.003 1.000 c 98 0 m 9 -224 l 75 -224 l 137 -67 l 198 -224 l 247 -224 l +159 0 l 98 0 l p ef +380 5 m 346 5 318 -6 297 -27 ct 276 -49 265 -77 265 -112 ct 265 -148 276 -176 297 -197 ct +318 -218 346 -229 382 -229 ct 417 -229 445 -218 466 -197 ct 487 -176 498 -148 498 -112 ct +498 -76 487 -48 466 -27 ct 445 -6 416 5 380 5 ct p +381 -36 m 398 -36 411 -42 419 -55 ct 428 -68 432 -87 432 -112 ct 432 -138 428 -156 419 -169 ct +411 -182 398 -188 382 -188 ct 365 -188 352 -182 344 -169 ct 335 -156 331 -137 331 -112 ct +331 -87 335 -68 343 -55 ct 352 -42 364 -36 381 -36 ct p ef +630 0 m 630 -183 l 548 -183 l 548 -224 l 691 -224 l 691 0 l 630 0 l +p +630 -265 m 630 -326 l 691 -326 l 691 -265 l 630 -265 l p ef +936 0 m 936 0 936 0 938 -42 ct 938 -42 938 -42 936 -42 ct 926 -27 915 -15 903 -7 ct +892 1 879 5 865 5 ct 839 5 819 -5 803 -26 ct 788 -46 780 -73 780 -107 ct 780 -144 789 -174 806 -196 ct +823 -218 846 -229 875 -229 ct 887 -229 898 -227 908 -222 ct 918 -218 927 -211 936 -203 ct +936 -203 936 -203 938 -203 ct 938 -203 938 -203 936 -224 ct 936 -224 936 -224 936 -326 ct +936 -326 936 -326 997 -326 ct 997 -326 997 -326 997 0 ct 997 0 997 0 936 0 ct p +936 -160 m 929 -168 922 -173 915 -177 ct 908 -181 900 -183 892 -183 ct 876 -183 865 -177 857 -164 ct +850 -152 846 -133 846 -108 ct 846 -89 849 -75 856 -65 ct 863 -56 873 -51 886 -51 ct +895 -51 903 -54 912 -60 ct 920 -66 928 -75 936 -88 ct 936 -88 936 -88 936 -160 ct +p ef +pom +gr +gs +pum +4578 2338 t +436 0 m 436 0 436 0 438 -42 ct 438 -42 438 -42 436 -42 ct 426 -26 415 -15 403 -7 ct +390 1 377 5 362 5 ct 337 5 317 -5 302 -24 ct 287 -44 280 -71 280 -105 ct 280 -142 289 -172 306 -195 ct +324 -218 346 -229 374 -229 ct 386 -229 398 -226 408 -221 ct 418 -216 428 -209 436 -198 ct +436 -198 436 -198 438 -198 ct 438 -198 438 -198 436 -229 ct 436 -229 436 -229 436 -326 ct +436 -326 436 -326 477 -326 ct 477 -326 477 -326 477 0 ct 477 0 477 0 436 0 ct p +436 -168 m 426 -178 417 -185 408 -190 ct 398 -195 389 -198 380 -198 ct 362 -198 348 -190 338 -175 ct +328 -159 323 -137 323 -109 ct 323 -83 327 -63 335 -50 ct 343 -38 354 -31 370 -31 ct +382 -31 393 -35 404 -42 ct 415 -49 426 -59 436 -73 ct 436 -73 436 -73 436 -168 ct +p ef +726 -224 m 726 -224 726 -224 726 0 ct 726 0 726 0 685 0 ct 685 0 685 0 687 -42 ct +687 -42 687 -42 685 -42 ct 676 -26 664 -15 652 -7 ct 639 1 624 5 608 5 ct 587 5 571 -1 560 -14 ct +549 -27 544 -46 544 -71 ct 544 -71 544 -71 544 -224 ct 544 -224 544 -224 585 -224 ct +585 -224 585 -224 585 -82 ct 585 -65 588 -52 593 -45 ct 599 -38 608 -34 621 -34 ct +631 -34 641 -38 652 -45 ct 663 -52 674 -63 685 -78 ct 685 -78 685 -78 685 -224 ct +685 -224 685 -224 726 -224 ct p ef +781 0 m 781 0 781 0 781 -224 ct 781 -224 781 -224 817 -224 ct 817 -224 817 -224 814 -182 ct +814 -182 814 -182 817 -182 ct 825 -198 834 -209 843 -217 ct 851 -225 859 -229 867 -229 ct +878 -229 886 -225 893 -216 ct 900 -208 904 -196 905 -182 ct 905 -182 905 -182 908 -182 ct +915 -198 923 -209 931 -217 ct 940 -225 949 -229 959 -229 ct 972 -229 982 -224 989 -213 ct +996 -202 999 -186 999 -164 ct 999 -164 999 -164 999 0 ct 999 0 999 0 963 0 ct 963 0 963 0 963 -162 ct +963 -172 962 -180 960 -185 ct 958 -190 954 -193 950 -193 ct 944 -193 937 -189 930 -181 ct +923 -173 915 -160 908 -144 ct 908 -144 908 -144 908 0 ct 908 0 908 0 872 0 ct 872 0 872 0 872 -155 ct +872 -167 871 -177 869 -183 ct 866 -190 863 -193 859 -193 ct 853 -193 846 -188 838 -179 ct +830 -170 823 -158 817 -144 ct 817 -144 817 -144 817 0 ct 817 0 817 0 781 0 ct p ef +1053 82 m 1053 82 1053 82 1053 -224 ct 1053 -224 1053 -224 1094 -224 ct 1094 -224 1094 -224 1092 -182 ct +1092 -182 1092 -182 1094 -182 ct 1104 -198 1115 -209 1127 -217 ct 1139 -225 1153 -229 1167 -229 ct +1192 -229 1212 -219 1227 -200 ct 1242 -180 1249 -153 1249 -120 ct 1249 -82 1240 -52 1223 -29 ct +1206 -6 1183 5 1155 5 ct 1143 5 1132 2 1122 -3 ct 1112 -8 1102 -15 1094 -26 ct +1094 -26 1094 -26 1092 -26 ct 1092 -26 1092 -26 1094 5 ct 1094 5 1094 5 1094 82 ct +1094 82 1094 82 1053 82 ct p +1094 -56 m 1103 -46 1113 -39 1122 -34 ct 1131 -29 1140 -26 1150 -26 ct 1168 -26 1181 -34 1191 -49 ct +1201 -65 1206 -87 1206 -115 ct 1206 -141 1202 -160 1194 -173 ct 1186 -186 1175 -193 1159 -193 ct +1148 -193 1136 -189 1125 -182 ct 1115 -175 1104 -165 1094 -151 ct 1094 -151 1094 -151 1094 -56 ct +p ef +1494 61 m 1449 56 1413 36 1384 -1 ct 1355 -37 1341 -81 1341 -133 ct 1341 -184 1355 -228 1384 -264 ct +1413 -301 1449 -321 1494 -326 ct 1494 -326 1494 -326 1494 -298 ct 1458 -291 1430 -273 1411 -244 ct +1392 -216 1382 -178 1382 -133 ct 1382 -87 1392 -49 1411 -21 ct 1430 8 1458 26 1494 33 ct +1494 33 1494 33 1494 61 ct p ef +1555 61 m 1600 56 1636 36 1665 -1 ct 1694 -37 1708 -81 1708 -133 ct 1708 -184 1694 -228 1665 -264 ct +1636 -301 1600 -321 1555 -326 ct 1555 -326 1555 -326 1555 -298 ct 1591 -291 1619 -273 1638 -244 ct +1657 -216 1667 -178 1667 -133 ct 1667 -87 1657 -49 1638 -21 ct 1619 8 1591 26 1555 33 ct +1555 33 1555 33 1555 61 ct p ef +2244 -326 m 2244 -326 2244 -326 2244 -295 ct 2244 -295 2244 -295 2228 -295 ct +2207 -295 2193 -293 2185 -287 ct 2176 -282 2172 -274 2172 -261 ct 2172 -257 2173 -251 2174 -242 ct +2174 -242 2174 -242 2178 -214 ct 2179 -204 2180 -196 2180 -190 ct 2180 -175 2177 -163 2170 -153 ct +2163 -144 2153 -137 2139 -132 ct 2153 -128 2163 -121 2170 -111 ct 2177 -102 2180 -90 2180 -75 ct +2180 -68 2179 -61 2178 -51 ct 2178 -51 2178 -51 2174 -23 ct 2173 -14 2172 -8 2172 -4 ct +2172 9 2176 17 2185 22 ct 2193 27 2207 30 2228 30 ct 2228 30 2228 30 2244 30 ct +2244 30 2244 30 2244 61 ct 2244 61 2244 61 2221 61 ct 2192 61 2170 56 2156 46 ct +2141 36 2134 21 2134 2 ct 2134 -7 2135 -16 2137 -26 ct 2137 -26 2137 -26 2144 -63 ct +2145 -68 2145 -74 2145 -79 ct 2145 -92 2141 -101 2133 -108 ct 2126 -114 2114 -117 2099 -117 ct +2099 -117 2099 -117 2080 -117 ct 2080 -117 2080 -117 2080 -148 ct 2080 -148 2080 -148 2099 -148 ct +2114 -148 2126 -151 2133 -157 ct 2141 -164 2145 -173 2145 -186 ct 2145 -191 2145 -197 2144 -202 ct +2144 -202 2144 -202 2137 -239 ct 2135 -249 2134 -258 2134 -267 ct 2134 -286 2141 -301 2156 -311 ct +2170 -321 2192 -326 2221 -326 ct 2221 -326 2221 -326 2244 -326 ct p ef +pom +gr +gs +pum +3054 2829 t +pom +gr +gs +pum +4070 2829 t +0.003 0.503 0.003 c 239 -326 m 65 61 l 15 61 l 189 -326 l 239 -326 l +p ef +493 -326 m 319 61 l 269 61 l 443 -326 l 493 -326 l p ef +786 82 m 786 82 786 82 786 -224 ct 786 -224 786 -224 847 -224 ct 847 -224 847 -224 845 -182 ct +845 -182 845 -182 847 -182 ct 857 -197 868 -209 879 -217 ct 891 -225 904 -229 918 -229 ct +944 -229 964 -219 980 -198 ct 995 -178 1003 -151 1003 -117 ct 1003 -80 994 -50 977 -28 ct +960 -6 937 5 908 5 ct 896 5 884 3 874 -2 ct 864 -6 855 -13 847 -22 ct 847 -22 847 -22 845 -22 ct +845 -22 845 -22 847 0 ct 847 0 847 0 847 82 ct 847 82 847 82 786 82 ct p +847 -64 m 854 -56 861 -50 868 -47 ct 875 -43 883 -41 892 -41 ct 907 -41 918 -47 926 -60 ct +933 -72 937 -91 937 -116 ct 937 -135 934 -149 927 -159 ct 920 -168 911 -173 897 -173 ct +889 -173 880 -170 871 -164 ct 863 -158 855 -149 847 -136 ct 847 -136 847 -136 847 -64 ct +p ef +1062 0 m 1062 0 1062 0 1062 -224 ct 1062 -224 1062 -224 1123 -224 ct 1123 -224 1123 -224 1121 -181 ct +1121 -181 1121 -181 1123 -181 ct 1133 -197 1145 -209 1159 -217 ct 1172 -225 1188 -229 1206 -229 ct +1217 -229 1232 -227 1248 -224 ct 1248 -224 1248 -224 1248 -149 ct 1248 -149 1248 -149 1207 -149 ct +1207 -149 1207 -149 1207 -173 ct 1202 -174 1199 -174 1196 -174 ct 1181 -174 1168 -170 1155 -163 ct +1143 -156 1132 -145 1123 -130 ct 1123 -130 1123 -130 1123 0 ct 1123 0 1123 0 1062 0 ct +p ef +1392 0 m 1392 -183 l 1310 -183 l 1310 -224 l 1453 -224 l 1453 0 l +1392 0 l p +1392 -265 m 1392 -326 l 1453 -326 l 1453 -265 l 1392 -265 l p ef +1553 0 m 1553 0 1553 0 1553 -224 ct 1553 -224 1553 -224 1614 -224 ct 1614 -224 1614 -224 1613 -202 ct +1613 -202 1613 -202 1612 -181 ct 1612 -181 1612 -181 1614 -181 ct 1621 -197 1630 -209 1642 -217 ct +1654 -225 1668 -229 1686 -229 ct 1708 -229 1724 -223 1735 -210 ct 1746 -197 1752 -178 1752 -153 ct +1752 -153 1752 -153 1752 0 ct 1752 0 1752 0 1691 0 ct 1691 0 1691 0 1691 -139 ct +1691 -150 1689 -159 1685 -165 ct 1680 -170 1674 -173 1665 -173 ct 1656 -173 1647 -170 1638 -165 ct +1630 -159 1621 -151 1614 -139 ct 1614 -139 1614 -139 1614 0 ct 1614 0 1614 0 1553 0 ct +p ef +2006 -6 m 1982 1 1960 5 1942 5 ct 1913 5 1892 -1 1878 -14 ct 1864 -26 1857 -45 1857 -70 ct +1857 -70 1857 -70 1857 -178 ct 1857 -178 1857 -178 1809 -178 ct 1809 -178 1809 -178 1809 -219 ct +1809 -219 1809 -219 1857 -219 ct 1857 -219 1857 -219 1857 -285 ct 1857 -285 1857 -285 1918 -285 ct +1918 -285 1918 -285 1918 -219 ct 1918 -219 1918 -219 2001 -219 ct 2001 -219 2001 -219 2001 -178 ct +2001 -178 2001 -178 1918 -178 ct 1918 -178 1918 -178 1918 -84 ct 1918 -68 1921 -57 1927 -51 ct +1933 -44 1943 -41 1957 -41 ct 1974 -41 1990 -44 2006 -51 ct 2006 -51 2006 -51 2006 -6 ct +p ef +2412 5 m 2378 5 2350 -6 2329 -27 ct 2308 -49 2297 -77 2297 -112 ct 2297 -148 2308 -176 2329 -197 ct +2350 -218 2378 -229 2414 -229 ct 2449 -229 2477 -218 2498 -197 ct 2519 -176 2530 -148 2530 -112 ct +2530 -76 2519 -48 2498 -27 ct 2477 -6 2448 5 2412 5 ct p +2413 -36 m 2430 -36 2443 -42 2451 -55 ct 2460 -68 2464 -87 2464 -112 ct 2464 -138 2460 -156 2451 -169 ct +2443 -182 2430 -188 2414 -188 ct 2397 -188 2384 -182 2376 -169 ct 2367 -156 2363 -137 2363 -112 ct +2363 -87 2367 -68 2375 -55 ct 2384 -42 2396 -36 2413 -36 ct p ef +2565 0 m 2565 0 2565 0 2565 -326 ct 2565 -326 2565 -326 2626 -326 ct 2626 -326 2626 -326 2626 -224 ct +2626 -224 2626 -224 2624 -182 ct 2624 -182 2624 -182 2626 -182 ct 2636 -197 2647 -209 2658 -217 ct +2670 -225 2683 -229 2697 -229 ct 2723 -229 2743 -219 2759 -198 ct 2774 -178 2782 -151 2782 -117 ct +2782 -80 2773 -50 2756 -28 ct 2739 -6 2716 5 2687 5 ct 2675 5 2663 3 2653 -2 ct +2643 -6 2634 -13 2626 -22 ct 2626 -22 2626 -22 2624 -22 ct 2624 -22 2624 -22 2616 0 ct +2616 0 2616 0 2565 0 ct p +2626 -64 m 2633 -56 2640 -50 2647 -47 ct 2654 -43 2662 -41 2671 -41 ct 2686 -41 2697 -47 2705 -60 ct +2712 -72 2716 -91 2716 -116 ct 2716 -135 2713 -149 2706 -159 ct 2699 -168 2690 -173 2676 -173 ct +2668 -173 2659 -170 2650 -164 ct 2642 -158 2634 -149 2626 -136 ct 2626 -136 2626 -136 2626 -64 ct +p ef +2819 78 m 2819 78 2819 78 2819 30 ct 2844 41 2866 46 2884 46 ct 2899 46 2909 42 2914 34 ct +2919 26 2921 11 2921 -13 ct 2921 -13 2921 -13 2921 -183 ct 2921 -183 2921 -183 2839 -183 ct +2839 -183 2839 -183 2839 -224 ct 2839 -224 2839 -224 2982 -224 ct 2982 -224 2982 -224 2982 -16 ct +2982 7 2980 24 2977 35 ct 2974 46 2968 56 2959 64 ct 2942 79 2919 87 2890 87 ct +2871 87 2847 84 2819 78 ct p +2921 -265 m 2921 -326 l 2982 -326 l 2982 -265 l 2921 -265 l p ef +3284 -95 m 3284 -95 3284 -95 3132 -95 ct 3135 -77 3143 -63 3155 -54 ct 3167 -45 3183 -41 3204 -41 ct +3228 -41 3255 -46 3284 -56 ct 3284 -56 3284 -56 3284 -9 ct 3249 0 3218 5 3192 5 ct +3154 5 3123 -6 3100 -27 ct 3077 -48 3066 -76 3066 -111 ct 3066 -147 3077 -175 3098 -197 ct +3120 -218 3148 -229 3183 -229 ct 3215 -229 3239 -219 3257 -199 ct 3275 -180 3284 -152 3284 -118 ct +3284 -118 3284 -118 3284 -95 ct p +3131 -136 m 3131 -136 3131 -136 3225 -136 ct 3225 -153 3221 -166 3214 -175 ct +3206 -184 3195 -188 3180 -188 ct 3166 -188 3154 -184 3146 -175 ct 3138 -166 3133 -153 3131 -136 ct +p ef +3529 -4 m 3504 2 3479 5 3454 5 ct 3413 5 3380 -5 3357 -26 ct 3334 -47 3322 -75 3322 -111 ct +3322 -148 3333 -177 3356 -198 ct 3378 -219 3410 -229 3450 -229 ct 3480 -229 3506 -226 3529 -220 ct +3529 -220 3529 -220 3529 -175 ct 3504 -184 3481 -188 3458 -188 ct 3436 -188 3419 -182 3407 -169 ct +3394 -157 3388 -140 3388 -118 ct 3388 -94 3396 -74 3411 -60 ct 3426 -45 3446 -38 3471 -38 ct +3490 -38 3510 -42 3529 -49 ct 3529 -49 3529 -49 3529 -4 ct p ef +3784 -6 m 3760 1 3738 5 3720 5 ct 3691 5 3670 -1 3656 -14 ct 3642 -26 3635 -45 3635 -70 ct +3635 -70 3635 -70 3635 -178 ct 3635 -178 3635 -178 3587 -178 ct 3587 -178 3587 -178 3587 -219 ct +3587 -219 3587 -219 3635 -219 ct 3635 -219 3635 -219 3635 -285 ct 3635 -285 3635 -285 3696 -285 ct +3696 -285 3696 -285 3696 -219 ct 3696 -219 3696 -219 3779 -219 ct 3779 -219 3779 -219 3779 -178 ct +3779 -178 3779 -178 3696 -178 ct 3696 -178 3696 -178 3696 -84 ct 3696 -68 3699 -57 3705 -51 ct +3711 -44 3721 -41 3735 -41 ct 3752 -41 3768 -44 3784 -51 ct 3784 -51 3784 -51 3784 -6 ct +p ef +pom +gr +gs +pum +3054 3320 t +pom +gr +gs +pum +3562 3320 t +43 -326 m 43 -326 43 -326 43 -295 ct 43 -295 43 -295 59 -295 ct 80 -295 94 -293 102 -287 ct +111 -282 115 -274 115 -261 ct 115 -257 114 -251 113 -242 ct 113 -242 113 -242 109 -214 ct +108 -204 107 -196 107 -190 ct 107 -175 110 -163 117 -153 ct 124 -144 134 -137 148 -132 ct +134 -128 124 -121 117 -111 ct 110 -102 107 -90 107 -75 ct 107 -68 108 -61 109 -51 ct +109 -51 109 -51 113 -23 ct 114 -14 115 -8 115 -4 ct 115 9 111 17 102 22 ct 94 27 80 30 59 30 ct +59 30 59 30 43 30 ct 43 30 43 30 43 61 ct 43 61 43 61 66 61 ct 95 61 117 56 131 46 ct +146 36 153 21 153 2 ct 153 -7 152 -16 150 -26 ct 150 -26 150 -26 143 -63 ct 142 -68 142 -74 142 -79 ct +142 -92 146 -101 154 -108 ct 161 -114 173 -117 188 -117 ct 188 -117 188 -117 207 -117 ct +207 -117 207 -117 207 -148 ct 207 -148 207 -148 188 -148 ct 173 -148 161 -151 154 -157 ct +146 -164 142 -173 142 -186 ct 142 -191 142 -197 143 -202 ct 143 -202 143 -202 150 -239 ct +152 -249 153 -258 153 -267 ct 153 -286 146 -301 131 -311 ct 117 -321 95 -326 66 -326 ct +66 -326 66 -326 43 -326 ct p ef +pom +gr +gs +pum +3054 4014 t +43 -326 m 43 -326 43 -326 43 -295 ct 43 -295 43 -295 59 -295 ct 80 -295 94 -293 102 -287 ct +111 -282 115 -274 115 -261 ct 115 -257 114 -251 113 -242 ct 113 -242 113 -242 109 -214 ct +108 -204 107 -196 107 -190 ct 107 -175 110 -163 117 -153 ct 124 -144 134 -137 148 -132 ct +134 -128 124 -121 117 -111 ct 110 -102 107 -90 107 -75 ct 107 -68 108 -61 109 -51 ct +109 -51 109 -51 113 -23 ct 114 -14 115 -8 115 -4 ct 115 9 111 17 102 22 ct 94 27 80 30 59 30 ct +59 30 59 30 43 30 ct 43 30 43 30 43 61 ct 43 61 43 61 66 61 ct 95 61 117 56 131 46 ct +146 36 153 21 153 2 ct 153 -7 152 -16 150 -26 ct 150 -26 150 -26 143 -63 ct 142 -68 142 -74 142 -79 ct +142 -92 146 -101 154 -108 ct 161 -114 173 -117 188 -117 ct 188 -117 188 -117 207 -117 ct +207 -117 207 -117 207 -148 ct 207 -148 207 -148 188 -148 ct 173 -148 161 -151 154 -157 ct +146 -164 142 -173 142 -186 ct 142 -191 142 -197 143 -202 ct 143 -202 143 -202 150 -239 ct +152 -249 153 -258 153 -267 ct 153 -286 146 -301 131 -311 ct 117 -321 95 -326 66 -326 ct +66 -326 66 -326 43 -326 ct p ef +351 66 m 351 66 351 66 351 46 ct 358 45 364 41 368 33 ct 373 25 375 14 376 0 ct +376 0 376 0 351 0 ct 351 0 351 0 351 -61 ct 351 -61 351 -61 412 -61 ct 412 -61 412 -61 412 -24 ct +412 5 407 27 397 42 ct 387 57 371 65 351 66 ct p +351 -163 m 351 -224 l 412 -224 l 412 -163 l 351 -163 l p ef +pom +gr +gs +pum +3562 4014 t +pom +gr +gr +0.503 0.503 0.503 c 4134 4981 m 3002 4981 l 3002 4306 l 5266 4306 l +5266 4981 l 4134 4981 l p ef +4134 4981 m 3002 4981 l 3002 4306 l 5266 4306 l 5266 4981 l 4134 4981 l +pc +0.753 0.753 0.753 c 4034 4881 m 2902 4881 l 2902 4206 l 5166 4206 l +5166 4881 l 4034 4881 l p ef +0.003 0.003 0.003 c 4034 4881 m 2902 4881 l 2902 4206 l 5166 4206 l 5166 4881 l +4034 4881 l pc +gs +gs +pum +3133 4700 t +1.000 1.000 1.000 c 29 -291 m 29 -291 29 -291 144 -291 ct 186 -291 220 -277 246 -250 ct +272 -223 285 -189 285 -146 ct 285 -105 272 -70 245 -42 ct 219 -14 185 0 144 0 ct +144 0 144 0 29 0 ct 29 0 29 0 29 -291 ct p +88 -49 m 88 -49 88 -49 138 -49 ct 159 -49 179 -58 197 -75 ct 215 -93 224 -116 224 -145 ct +224 -176 216 -200 199 -217 ct 182 -234 161 -242 138 -242 ct 138 -242 138 -242 88 -242 ct +88 -242 88 -242 88 -49 ct p ef +533 0 m 533 0 533 0 476 0 ct 476 0 476 0 476 -27 ct 458 -6 435 5 407 5 ct 385 5 367 -2 354 -15 ct +341 -28 334 -47 334 -71 ct 334 -71 334 -71 334 -215 ct 334 -215 334 -215 391 -215 ct +391 -215 391 -215 391 -89 ct 391 -59 402 -44 424 -44 ct 443 -44 461 -54 476 -75 ct +476 -75 476 -75 476 -215 ct 476 -215 476 -215 533 -215 ct 533 -215 533 -215 533 0 ct +p ef +910 0 m 910 0 910 0 853 0 ct 853 0 853 0 853 -125 ct 853 -143 851 -155 846 -162 ct +842 -168 835 -171 826 -171 ct 811 -171 796 -160 780 -137 ct 780 -137 780 -137 780 0 ct +780 0 780 0 723 0 ct 723 0 723 0 723 -125 ct 723 -144 721 -157 716 -162 ct 712 -168 706 -171 697 -171 ct +682 -171 666 -160 650 -137 ct 650 -137 650 -137 650 0 ct 650 0 650 0 593 0 ct 593 0 593 0 593 -215 ct +593 -215 593 -215 650 -215 ct 650 -215 650 -215 650 -182 ct 667 -207 688 -220 715 -220 ct +743 -220 763 -207 775 -182 ct 793 -207 816 -220 845 -220 ct 866 -220 882 -214 893 -201 ct +904 -188 910 -169 910 -144 ct 910 -144 910 -144 910 0 ct p ef +1027 -192 m 1034 -201 1043 -207 1055 -212 ct 1067 -217 1079 -220 1091 -220 ct +1118 -220 1139 -210 1156 -190 ct 1173 -171 1182 -144 1182 -112 ct 1182 -76 1173 -47 1156 -26 ct +1139 -5 1118 5 1091 5 ct 1064 5 1043 -4 1027 -21 ct 1027 -21 1027 -21 1027 84 ct +1027 84 1027 84 970 84 ct 970 84 970 84 970 -215 ct 970 -215 970 -215 1027 -215 ct +1027 -215 1027 -215 1027 -192 ct p +1027 -69 m 1040 -52 1056 -44 1076 -44 ct 1090 -44 1101 -50 1110 -61 ct 1119 -73 1123 -89 1123 -108 ct +1123 -129 1119 -144 1110 -155 ct 1101 -166 1089 -171 1076 -171 ct 1057 -171 1041 -162 1027 -145 ct +1027 -145 1027 -145 1027 -69 ct p ef +1256 -66 m 1266 -66 1275 -63 1282 -56 ct 1289 -49 1292 -41 1292 -31 ct 1292 -21 1289 -12 1282 -5 ct +1275 2 1266 5 1256 5 ct 1246 5 1238 2 1231 -5 ct 1224 -12 1221 -20 1221 -31 ct +1221 -41 1224 -49 1231 -56 ct 1238 -63 1246 -66 1256 -66 ct p ef +1531 0 m 1531 0 1531 0 1472 0 ct 1468 -9 1466 -17 1466 -25 ct 1447 -5 1424 5 1397 5 ct +1377 5 1361 -1 1350 -13 ct 1339 -24 1333 -40 1333 -59 ct 1333 -73 1337 -85 1344 -95 ct +1352 -106 1363 -114 1378 -120 ct 1393 -127 1410 -131 1431 -132 ct 1431 -132 1431 -132 1466 -135 ct +1466 -135 1466 -135 1466 -139 ct 1466 -163 1452 -175 1425 -175 ct 1417 -175 1406 -173 1392 -170 ct +1378 -166 1366 -162 1356 -157 ct 1356 -157 1356 -157 1342 -198 ct 1355 -204 1371 -210 1388 -214 ct +1406 -218 1421 -220 1435 -220 ct 1464 -220 1486 -213 1501 -199 ct 1516 -185 1523 -165 1523 -138 ct +1523 -138 1523 -138 1523 -51 ct 1523 -31 1526 -14 1531 0 ct p +1466 -66 m 1466 -66 1466 -66 1466 -101 ct 1442 -99 1427 -97 1421 -96 ct 1416 -95 1410 -93 1403 -89 ct +1397 -86 1393 -82 1390 -77 ct 1387 -72 1385 -67 1385 -61 ct 1385 -54 1387 -49 1392 -45 ct +1396 -40 1402 -38 1409 -38 ct 1430 -38 1449 -47 1466 -66 ct p ef +1783 0 m 1783 0 1783 0 1726 0 ct 1726 0 1726 0 1726 -125 ct 1726 -156 1715 -171 1693 -171 ct +1674 -171 1656 -160 1641 -139 ct 1641 -139 1641 -139 1641 0 ct 1641 0 1641 0 1584 0 ct +1584 0 1584 0 1584 -307 ct 1584 -307 1584 -307 1641 -307 ct 1641 -307 1641 -307 1641 -188 ct +1659 -209 1682 -220 1710 -220 ct 1732 -220 1750 -213 1763 -200 ct 1776 -187 1783 -168 1783 -144 ct +1783 -144 1783 -144 1783 0 ct p ef +pom +gr +gr +0.300 0.300 0.300 c 8430 5104 m 9601 1962 l 9473 1914 l 9769 1765 l +9896 2072 l 9768 2024 l 8597 5166 l 8430 5104 l p ef +gs +gs +pum +8825 3864 t +69.5 r 0.003 0.003 0.003 c 44 0 m 20 0 l 20 -143 l 44 -143 l 44 0 l p +32 -205 m 36 -205 40 -204 43 -201 ct 46 -198 47 -194 47 -190 ct 47 -186 46 -183 43 -180 ct +40 -177 36 -176 32 -176 ct 28 -176 25 -177 22 -180 ct 19 -183 18 -186 18 -190 ct +18 -194 19 -198 22 -201 ct 25 -204 28 -205 32 -205 ct p ef +202 0 m 202 0 202 0 178 0 ct 178 0 178 0 178 -91 ct 178 -102 175 -110 170 -116 ct +165 -122 157 -125 148 -125 ct 134 -125 120 -117 107 -101 ct 107 -101 107 -101 107 0 ct +107 0 107 0 83 0 ct 83 0 83 0 83 -143 ct 83 -143 83 -143 107 -143 ct 107 -143 107 -143 107 -122 ct +122 -138 138 -146 155 -146 ct 169 -146 181 -142 189 -133 ct 198 -125 202 -113 202 -97 ct +202 -97 202 -97 202 0 ct p ef +231 -72 m 231 -95 238 -113 251 -126 ct 265 -139 282 -146 302 -146 ct 319 -146 336 -141 351 -132 ct +351 -132 351 -132 344 -113 ct 331 -121 317 -125 303 -125 ct 289 -125 278 -120 269 -110 ct +260 -101 256 -88 256 -72 ct 256 -55 260 -42 269 -33 ct 278 -23 289 -18 303 -18 ct +316 -18 331 -23 346 -32 ct 346 -32 346 -32 353 -13 ct 337 -2 320 3 303 3 ct 281 3 264 -4 251 -18 ct +238 -31 231 -49 231 -72 ct p ef +408 0 m 384 0 l 384 -205 l 408 -205 l 408 0 l p ef +566 0 m 566 0 566 0 542 0 ct 542 0 542 0 542 -21 ct 527 -5 511 3 494 3 ct 480 3 468 -1 460 -10 ct +451 -18 447 -30 447 -46 ct 447 -46 447 -46 447 -143 ct 447 -143 447 -143 471 -143 ct +471 -143 471 -143 471 -52 ct 471 -42 474 -33 479 -27 ct 484 -21 492 -18 501 -18 ct +515 -18 529 -26 542 -42 ct 542 -42 542 -42 542 -143 ct 542 -143 542 -143 566 -143 ct +566 -143 566 -143 566 0 ct p ef +722 0 m 722 0 722 0 698 0 ct 698 0 698 0 698 -18 ct 688 -4 673 3 656 3 ct 637 3 622 -4 611 -18 ct +601 -32 595 -50 595 -74 ct 595 -96 601 -113 612 -126 ct 623 -139 637 -146 654 -146 ct +673 -146 688 -139 698 -125 ct 698 -125 698 -125 698 -205 ct 698 -205 698 -205 722 -205 ct +722 -205 722 -205 722 0 ct p +698 -42 m 698 -42 698 -42 698 -102 ct 695 -109 690 -114 683 -118 ct 676 -123 669 -125 661 -125 ct +648 -125 638 -120 631 -111 ct 624 -102 620 -89 620 -72 ct 620 -55 624 -42 631 -32 ct +638 -23 649 -18 661 -18 ct 667 -18 672 -19 677 -22 ct 683 -24 687 -28 692 -32 ct +696 -37 698 -40 698 -42 ct p ef +887 -15 m 867 -3 847 3 827 3 ct 803 3 785 -4 772 -17 ct 759 -30 752 -49 752 -72 ct +752 -94 758 -112 770 -126 ct 783 -139 799 -146 820 -146 ct 839 -146 854 -140 866 -127 ct +878 -114 884 -97 884 -75 ct 884 -75 884 -75 884 -69 ct 884 -69 884 -69 777 -69 ct +778 -52 782 -40 791 -31 ct 799 -22 811 -18 827 -18 ct 845 -18 862 -23 880 -34 ct +880 -34 880 -34 887 -15 ct p +859 -88 m 858 -99 854 -108 846 -115 ct 839 -122 830 -125 820 -125 ct 809 -125 800 -122 792 -115 ct +785 -109 780 -100 778 -88 ct 778 -88 778 -88 859 -88 ct p ef +pom +gr +gr +0.503 0.503 0.503 c 14637 14109 m 10100 14109 l 10100 12822 l 19175 12822 l +19175 14109 l 14637 14109 l p ef +14637 14109 m 10100 14109 l 10100 12822 l 19175 12822 l 19175 14109 l +14637 14109 l pc +1.000 0.902 0.777 c 14537 14009 m 10000 14009 l 10000 12722 l 19075 12722 l +19075 14009 l 14537 14009 l p ef +0.003 0.003 0.003 c 14537 14009 m 10000 14009 l 10000 12722 l 19075 12722 l +19075 14009 l 14537 14009 l pc +gs +gs +pum +10594 13289 t +35 0 m 58 -93 l 11 -93 l 18 -124 l 66 -124 l 80 -184 l 33 -184 l +41 -215 l 88 -215 l 111 -306 l 142 -306 l 120 -215 l 168 -215 l 191 -306 l +222 -306 l 200 -215 l 246 -215 l 239 -184 l 192 -184 l 177 -124 l +224 -124 l 216 -93 l 169 -93 l 146 0 l 115 0 l 138 -93 l 89 -93 l +66 0 l 35 0 l p +97 -124 m 146 -124 l 160 -184 l 112 -184 l 97 -124 l p ef +371 0 m 371 -193 l 289 -193 l 289 -224 l 412 -224 l 412 0 l 371 0 l +p +366 -275 m 366 -326 l 417 -326 l 417 -275 l 366 -275 l p ef +545 0 m 545 0 545 0 545 -224 ct 545 -224 545 -224 586 -224 ct 586 -224 586 -224 584 -182 ct +584 -182 584 -182 586 -182 ct 596 -198 607 -209 620 -217 ct 632 -225 647 -229 663 -229 ct +684 -229 700 -223 711 -210 ct 722 -197 727 -178 727 -153 ct 727 -153 727 -153 727 0 ct +727 0 727 0 686 0 ct 686 0 686 0 686 -142 ct 686 -159 683 -172 678 -179 ct 672 -186 663 -190 650 -190 ct +640 -190 630 -186 619 -179 ct 608 -172 597 -161 586 -146 ct 586 -146 586 -146 586 0 ct +586 0 586 0 545 0 ct p ef +990 -7 m 966 1 942 5 918 5 ct 879 5 849 -5 828 -26 ct 807 -46 796 -75 796 -112 ct +796 -149 806 -177 827 -198 ct 848 -219 877 -229 914 -229 ct 938 -229 962 -225 986 -218 ct +986 -218 986 -218 986 -184 ct 959 -193 937 -198 918 -198 ct 894 -198 874 -190 860 -175 ct +846 -160 839 -139 839 -112 ct 839 -85 846 -64 861 -49 ct 876 -34 897 -26 923 -26 ct +943 -26 965 -31 990 -40 ct 990 -40 990 -40 990 -7 ct p ef +1138 0 m 1138 -295 l 1051 -295 l 1051 -326 l 1179 -326 l 1179 0 l +1138 0 l p ef +1488 -224 m 1488 -224 1488 -224 1488 0 ct 1488 0 1488 0 1447 0 ct 1447 0 1447 0 1449 -42 ct +1449 -42 1449 -42 1447 -42 ct 1438 -26 1426 -15 1414 -7 ct 1401 1 1386 5 1370 5 ct +1349 5 1333 -1 1322 -14 ct 1311 -27 1306 -46 1306 -71 ct 1306 -71 1306 -71 1306 -224 ct +1306 -224 1306 -224 1347 -224 ct 1347 -224 1347 -224 1347 -82 ct 1347 -65 1350 -52 1355 -45 ct +1361 -38 1370 -34 1383 -34 ct 1393 -34 1403 -38 1414 -45 ct 1425 -52 1436 -63 1447 -78 ct +1447 -78 1447 -78 1447 -224 ct 1447 -224 1447 -224 1488 -224 ct p ef +1706 0 m 1706 0 1706 0 1708 -42 ct 1708 -42 1708 -42 1706 -42 ct 1696 -26 1685 -15 1673 -7 ct +1660 1 1647 5 1632 5 ct 1607 5 1587 -5 1572 -24 ct 1557 -44 1550 -71 1550 -105 ct +1550 -142 1559 -172 1576 -195 ct 1594 -218 1616 -229 1644 -229 ct 1656 -229 1668 -226 1678 -221 ct +1688 -216 1698 -209 1706 -198 ct 1706 -198 1706 -198 1708 -198 ct 1708 -198 1708 -198 1706 -229 ct +1706 -229 1706 -229 1706 -326 ct 1706 -326 1706 -326 1747 -326 ct 1747 -326 1747 -326 1747 0 ct +1747 0 1747 0 1706 0 ct p +1706 -168 m 1696 -178 1687 -185 1678 -190 ct 1668 -195 1659 -198 1650 -198 ct +1632 -198 1618 -190 1608 -175 ct 1598 -159 1593 -137 1593 -109 ct 1593 -83 1597 -63 1605 -50 ct +1613 -38 1624 -31 1640 -31 ct 1652 -31 1663 -35 1674 -42 ct 1685 -49 1696 -59 1706 -73 ct +1706 -73 1706 -73 1706 -168 ct p ef +2004 -9 m 1976 0 1950 5 1926 5 ct 1888 5 1859 -5 1838 -25 ct 1817 -45 1807 -73 1807 -110 ct +1807 -144 1817 -173 1837 -195 ct 1857 -218 1882 -229 1913 -229 ct 1944 -229 1966 -220 1981 -201 ct +1996 -182 2003 -153 2003 -114 ct 2003 -114 2003 -114 2003 -101 ct 2003 -101 2003 -101 1849 -101 ct +1850 -76 1858 -57 1872 -45 ct 1886 -32 1905 -26 1931 -26 ct 1954 -26 1978 -31 2004 -42 ct +2004 -42 2004 -42 2004 -9 ct p +1850 -132 m 1850 -132 1850 -132 1960 -132 ct 1960 -132 1960 -132 1960 -138 ct +1960 -158 1956 -173 1947 -183 ct 1938 -193 1926 -198 1909 -198 ct 1892 -198 1879 -192 1868 -181 ct +1858 -169 1852 -153 1850 -132 ct p ef +2523 0 m 2304 -110 l 2523 -219 l 2523 -185 l 2372 -110 l 2523 -34 l +2523 0 l p ef +2579 -9 m 2579 -9 2579 -9 2579 -45 ct 2610 -32 2637 -26 2660 -26 ct 2676 -26 2690 -29 2701 -36 ct +2712 -43 2717 -51 2717 -61 ct 2717 -74 2704 -84 2679 -93 ct 2679 -93 2679 -93 2636 -107 ct +2602 -118 2585 -138 2585 -165 ct 2585 -186 2593 -201 2608 -212 ct 2623 -223 2645 -229 2673 -229 ct +2694 -229 2718 -226 2746 -219 ct 2746 -219 2746 -219 2746 -186 ct 2719 -194 2695 -198 2673 -198 ct +2657 -198 2644 -196 2636 -191 ct 2628 -186 2624 -179 2624 -169 ct 2624 -158 2634 -149 2654 -142 ct +2654 -142 2654 -142 2706 -124 ct 2741 -111 2758 -91 2758 -64 ct 2758 -43 2749 -26 2732 -14 ct +2714 -1 2691 5 2661 5 ct 2636 5 2608 0 2579 -9 ct p ef +3022 0 m 3002 3 2982 5 2963 5 ct 2930 5 2907 -1 2895 -13 ct 2883 -25 2877 -47 2877 -80 ct +2877 -80 2877 -80 2877 -188 ct 2877 -188 2877 -188 2821 -188 ct 2821 -188 2821 -188 2821 -219 ct +2821 -219 2821 -219 2877 -219 ct 2877 -219 2877 -219 2877 -267 ct 2877 -267 2877 -267 2918 -267 ct +2918 -267 2918 -267 2918 -219 ct 2918 -219 2918 -219 3017 -219 ct 3017 -219 3017 -219 3017 -188 ct +3017 -188 3017 -188 2918 -188 ct 2918 -188 2918 -188 2918 -74 ct 2918 -61 2919 -53 2920 -48 ct +2922 -43 2925 -39 2931 -35 ct 2940 -29 2953 -26 2971 -26 ct 2988 -26 3005 -28 3022 -31 ct +3022 -31 3022 -31 3022 0 ct p ef +3230 0 m 3230 0 3230 0 3232 -42 ct 3232 -42 3232 -42 3230 -42 ct 3220 -26 3209 -15 3197 -7 ct +3184 1 3171 5 3156 5 ct 3131 5 3111 -5 3096 -24 ct 3081 -44 3074 -71 3074 -105 ct +3074 -142 3083 -172 3100 -195 ct 3118 -218 3140 -229 3168 -229 ct 3180 -229 3192 -226 3202 -221 ct +3212 -216 3222 -209 3230 -198 ct 3230 -198 3230 -198 3232 -198 ct 3232 -198 3232 -198 3230 -229 ct +3230 -229 3230 -229 3230 -326 ct 3230 -326 3230 -326 3271 -326 ct 3271 -326 3271 -326 3271 0 ct +3271 0 3271 0 3230 0 ct p +3230 -168 m 3220 -178 3211 -185 3202 -190 ct 3192 -195 3183 -198 3174 -198 ct +3156 -198 3142 -190 3132 -175 ct 3122 -159 3117 -137 3117 -109 ct 3117 -83 3121 -63 3129 -50 ct +3137 -38 3148 -31 3164 -31 ct 3176 -31 3187 -35 3198 -42 ct 3209 -49 3220 -59 3230 -73 ct +3230 -73 3230 -73 3230 -168 ct p ef +3419 0 m 3419 -193 l 3337 -193 l 3337 -224 l 3460 -224 l 3460 0 l +3419 0 l p +3414 -275 m 3414 -326 l 3465 -326 l 3465 -275 l 3414 -275 l p ef +3682 5 m 3650 5 3625 -6 3606 -27 ct 3587 -48 3578 -76 3578 -112 ct 3578 -148 3587 -177 3606 -198 ct +3625 -219 3651 -229 3684 -229 ct 3716 -229 3742 -219 3761 -198 ct 3780 -177 3789 -149 3789 -113 ct +3789 -76 3780 -47 3761 -26 ct 3742 -5 3716 5 3682 5 ct p +3683 -26 m 3704 -26 3720 -33 3730 -48 ct 3741 -62 3746 -84 3746 -113 ct 3746 -139 3740 -160 3729 -175 ct +3718 -190 3703 -198 3684 -198 ct 3664 -198 3649 -190 3638 -175 ct 3627 -160 3621 -139 3621 -112 ct +3621 -85 3626 -64 3637 -49 ct 3648 -34 3664 -26 3683 -26 ct p ef +3907 0 m 3907 -61 l 3968 -61 l 3968 0 l 3907 0 l p ef +4101 0 m 4101 0 4101 0 4101 -326 ct 4101 -326 4101 -326 4142 -326 ct 4142 -326 4142 -326 4142 -224 ct +4142 -224 4142 -224 4140 -182 ct 4140 -182 4140 -182 4142 -182 ct 4152 -198 4163 -209 4176 -217 ct +4188 -225 4203 -229 4219 -229 ct 4240 -229 4256 -223 4267 -210 ct 4278 -197 4283 -178 4283 -153 ct +4283 -153 4283 -153 4283 0 ct 4283 0 4283 0 4242 0 ct 4242 0 4242 0 4242 -142 ct +4242 -159 4239 -172 4234 -179 ct 4228 -186 4219 -190 4206 -190 ct 4196 -190 4186 -186 4175 -179 ct +4164 -172 4153 -161 4142 -146 ct 4142 -146 4142 -146 4142 0 ct 4142 0 4142 0 4101 0 ct +p ef +4336 0 m 4555 -110 l 4336 -219 l 4336 -185 l 4487 -110 l 4336 -34 l +4336 0 l p ef +pom +gr +gs +pum +10594 13780 t +0.003 0.503 0.003 c 239 -326 m 65 61 l 15 61 l 189 -326 l 239 -326 l +p ef +493 -326 m 319 61 l 269 61 l 443 -326 l 493 -326 l p ef +795 -8 m 795 -8 795 -8 795 -54 ct 829 -42 857 -36 877 -36 ct 892 -36 903 -38 911 -42 ct +918 -46 922 -52 922 -60 ct 922 -64 920 -68 916 -72 ct 913 -75 907 -79 900 -82 ct +900 -82 900 -82 852 -101 ct 833 -109 819 -118 810 -127 ct 801 -137 796 -148 796 -161 ct +796 -182 806 -199 825 -211 ct 844 -223 871 -229 905 -229 ct 925 -229 948 -226 974 -221 ct +974 -221 974 -221 974 -174 ct 946 -183 922 -188 903 -188 ct 888 -188 878 -186 871 -183 ct +864 -180 860 -175 860 -169 ct 860 -165 863 -162 868 -158 ct 873 -154 880 -150 890 -146 ct +890 -146 890 -146 943 -124 ct 959 -118 971 -110 978 -100 ct 986 -91 990 -79 990 -66 ct +990 -45 981 -28 962 -15 ct 943 -2 919 5 889 5 ct 863 5 831 1 795 -8 ct p ef +1118 0 m 1118 -285 l 1036 -285 l 1036 -326 l 1179 -326 l 1179 0 l +1118 0 l p ef +1392 0 m 1392 -183 l 1310 -183 l 1310 -224 l 1453 -224 l 1453 0 l +1392 0 l p +1392 -265 m 1392 -326 l 1453 -326 l 1453 -265 l 1392 -265 l p ef +1751 -4 m 1726 2 1701 5 1676 5 ct 1635 5 1602 -5 1579 -26 ct 1556 -47 1544 -75 1544 -111 ct +1544 -148 1555 -177 1578 -198 ct 1600 -219 1632 -229 1672 -229 ct 1702 -229 1728 -226 1751 -220 ct +1751 -220 1751 -220 1751 -175 ct 1726 -184 1703 -188 1680 -188 ct 1658 -188 1641 -182 1629 -169 ct +1616 -157 1610 -140 1610 -118 ct 1610 -94 1618 -74 1633 -60 ct 1648 -45 1668 -38 1693 -38 ct +1712 -38 1732 -42 1751 -49 ct 1751 -49 1751 -49 1751 -4 ct p ef +2014 -95 m 2014 -95 2014 -95 1862 -95 ct 1865 -77 1873 -63 1885 -54 ct 1897 -45 1913 -41 1934 -41 ct +1958 -41 1985 -46 2014 -56 ct 2014 -56 2014 -56 2014 -9 ct 1979 0 1948 5 1922 5 ct +1884 5 1853 -6 1830 -27 ct 1807 -48 1796 -76 1796 -111 ct 1796 -147 1807 -175 1828 -197 ct +1850 -218 1878 -229 1913 -229 ct 1945 -229 1969 -219 1987 -199 ct 2005 -180 2014 -152 2014 -118 ct +2014 -118 2014 -118 2014 -95 ct p +1861 -136 m 1861 -136 1861 -136 1955 -136 ct 1955 -153 1951 -166 1944 -175 ct +1936 -184 1925 -188 1910 -188 ct 1896 -188 1884 -184 1876 -175 ct 1868 -166 1863 -153 1861 -136 ct +p ef +2513 -4 m 2488 2 2463 5 2438 5 ct 2397 5 2364 -5 2341 -26 ct 2318 -47 2306 -75 2306 -111 ct +2306 -148 2317 -177 2340 -198 ct 2362 -219 2394 -229 2434 -229 ct 2464 -229 2490 -226 2513 -220 ct +2513 -220 2513 -220 2513 -175 ct 2488 -184 2465 -188 2442 -188 ct 2420 -188 2403 -182 2391 -169 ct +2378 -157 2372 -140 2372 -118 ct 2372 -94 2380 -74 2395 -60 ct 2410 -45 2430 -38 2455 -38 ct +2474 -38 2494 -42 2513 -49 ct 2513 -49 2513 -49 2513 -4 ct p ef +2666 5 m 2632 5 2604 -6 2583 -27 ct 2562 -49 2551 -77 2551 -112 ct 2551 -148 2562 -176 2583 -197 ct +2604 -218 2632 -229 2668 -229 ct 2703 -229 2731 -218 2752 -197 ct 2773 -176 2784 -148 2784 -112 ct +2784 -76 2773 -48 2752 -27 ct 2731 -6 2702 5 2666 5 ct p +2667 -36 m 2684 -36 2697 -42 2705 -55 ct 2714 -68 2718 -87 2718 -112 ct 2718 -138 2714 -156 2705 -169 ct +2697 -182 2684 -188 2668 -188 ct 2651 -188 2638 -182 2630 -169 ct 2621 -156 2617 -137 2617 -112 ct +2617 -87 2621 -68 2629 -55 ct 2638 -42 2650 -36 2667 -36 ct p ef +2968 0 m 2968 0 2968 0 2970 -42 ct 2970 -42 2970 -42 2968 -42 ct 2958 -27 2947 -15 2935 -7 ct +2924 1 2911 5 2897 5 ct 2871 5 2851 -5 2835 -26 ct 2820 -46 2812 -73 2812 -107 ct +2812 -144 2821 -174 2838 -196 ct 2855 -218 2878 -229 2907 -229 ct 2919 -229 2930 -227 2940 -222 ct +2950 -218 2959 -211 2968 -203 ct 2968 -203 2968 -203 2970 -203 ct 2970 -203 2970 -203 2968 -224 ct +2968 -224 2968 -224 2968 -326 ct 2968 -326 2968 -326 3029 -326 ct 3029 -326 3029 -326 3029 0 ct +3029 0 3029 0 2968 0 ct p +2968 -160 m 2961 -168 2954 -173 2947 -177 ct 2940 -181 2932 -183 2924 -183 ct +2908 -183 2897 -177 2889 -164 ct 2882 -152 2878 -133 2878 -108 ct 2878 -89 2881 -75 2888 -65 ct +2895 -56 2905 -51 2918 -51 ct 2927 -51 2935 -54 2944 -60 ct 2952 -66 2960 -75 2968 -88 ct +2968 -88 2968 -88 2968 -160 ct p ef +3284 -95 m 3284 -95 3284 -95 3132 -95 ct 3135 -77 3143 -63 3155 -54 ct 3167 -45 3183 -41 3204 -41 ct +3228 -41 3255 -46 3284 -56 ct 3284 -56 3284 -56 3284 -9 ct 3249 0 3218 5 3192 5 ct +3154 5 3123 -6 3100 -27 ct 3077 -48 3066 -76 3066 -111 ct 3066 -147 3077 -175 3098 -197 ct +3120 -218 3148 -229 3183 -229 ct 3215 -229 3239 -219 3257 -199 ct 3275 -180 3284 -152 3284 -118 ct +3284 -118 3284 -118 3284 -95 ct p +3131 -136 m 3131 -136 3131 -136 3225 -136 ct 3225 -153 3221 -166 3214 -175 ct +3206 -184 3195 -188 3180 -188 ct 3166 -188 3154 -184 3146 -175 ct 3138 -166 3133 -153 3131 -136 ct +p ef +3602 0 m 3602 0 3602 0 3602 -224 ct 3602 -224 3602 -224 3663 -224 ct 3663 -224 3663 -224 3661 -181 ct +3661 -181 3661 -181 3663 -181 ct 3673 -197 3685 -209 3699 -217 ct 3712 -225 3728 -229 3746 -229 ct +3757 -229 3772 -227 3788 -224 ct 3788 -224 3788 -224 3788 -149 ct 3788 -149 3788 -149 3747 -149 ct +3747 -149 3747 -149 3747 -173 ct 3742 -174 3739 -174 3736 -174 ct 3721 -174 3708 -170 3695 -163 ct +3683 -156 3672 -145 3663 -130 ct 3663 -130 3663 -130 3663 0 ct 3663 0 3663 0 3602 0 ct +p ef +4046 -95 m 4046 -95 4046 -95 3894 -95 ct 3897 -77 3905 -63 3917 -54 ct 3929 -45 3945 -41 3966 -41 ct +3990 -41 4017 -46 4046 -56 ct 4046 -56 4046 -56 4046 -9 ct 4011 0 3980 5 3954 5 ct +3916 5 3885 -6 3862 -27 ct 3839 -48 3828 -76 3828 -111 ct 3828 -147 3839 -175 3860 -197 ct +3882 -218 3910 -229 3945 -229 ct 3977 -229 4001 -219 4019 -199 ct 4037 -180 4046 -152 4046 -118 ct +4046 -118 4046 -118 4046 -95 ct p +3893 -136 m 3893 -136 3893 -136 3987 -136 ct 3987 -153 3983 -166 3976 -175 ct +3968 -184 3957 -188 3942 -188 ct 3928 -188 3916 -184 3908 -175 ct 3900 -166 3895 -153 3893 -136 ct +p ef +4217 0 m 4217 0 4217 0 4166 0 ct 4166 0 4166 0 4166 -149 ct 4166 -157 4165 -163 4164 -167 ct +4162 -171 4160 -173 4157 -173 ct 4152 -173 4148 -171 4144 -166 ct 4140 -161 4137 -154 4133 -145 ct +4133 -145 4133 -145 4133 0 ct 4133 0 4133 0 4082 0 ct 4082 0 4082 0 4082 -224 ct +4082 -224 4082 -224 4133 -224 ct 4133 -224 4133 -224 4130 -181 ct 4130 -181 4130 -181 4133 -181 ct +4138 -197 4145 -209 4153 -217 ct 4161 -225 4170 -229 4180 -229 ct 4191 -229 4200 -225 4206 -217 ct +4212 -209 4216 -197 4217 -181 ct 4217 -181 4217 -181 4219 -181 ct 4224 -197 4230 -209 4237 -217 ct +4245 -225 4253 -229 4263 -229 ct 4277 -229 4287 -223 4293 -212 ct 4298 -200 4301 -179 4301 -150 ct +4301 -150 4301 -150 4301 0 ct 4301 0 4301 0 4250 0 ct 4250 0 4250 0 4250 -149 ct +4250 -157 4249 -163 4248 -167 ct 4246 -171 4244 -173 4241 -173 ct 4236 -173 4232 -171 4228 -166 ct +4225 -161 4221 -154 4217 -145 ct 4217 -145 4217 -145 4217 0 ct p ef +4444 5 m 4410 5 4382 -6 4361 -27 ct 4340 -49 4329 -77 4329 -112 ct 4329 -148 4340 -176 4361 -197 ct +4382 -218 4410 -229 4446 -229 ct 4481 -229 4509 -218 4530 -197 ct 4551 -176 4562 -148 4562 -112 ct +4562 -76 4551 -48 4530 -27 ct 4509 -6 4480 5 4444 5 ct p +4445 -36 m 4462 -36 4475 -42 4483 -55 ct 4492 -68 4496 -87 4496 -112 ct 4496 -138 4492 -156 4483 -169 ct +4475 -182 4462 -188 4446 -188 ct 4429 -188 4416 -182 4408 -169 ct 4399 -156 4395 -137 4395 -112 ct +4395 -87 4399 -68 4407 -55 ct 4416 -42 4428 -36 4445 -36 ct p ef +4670 0 m 4581 -224 l 4647 -224 l 4709 -67 l 4770 -224 l 4819 -224 l +4731 0 l 4670 0 l p ef +5062 -95 m 5062 -95 5062 -95 4910 -95 ct 4913 -77 4921 -63 4933 -54 ct 4945 -45 4961 -41 4982 -41 ct +5006 -41 5033 -46 5062 -56 ct 5062 -56 5062 -56 5062 -9 ct 5027 0 4996 5 4970 5 ct +4932 5 4901 -6 4878 -27 ct 4855 -48 4844 -76 4844 -111 ct 4844 -147 4855 -175 4876 -197 ct +4898 -218 4926 -229 4961 -229 ct 4993 -229 5017 -219 5035 -199 ct 5053 -180 5062 -152 5062 -118 ct +5062 -118 5062 -118 5062 -95 ct p +4909 -136 m 4909 -136 4909 -136 5003 -136 ct 5003 -153 4999 -166 4992 -175 ct +4984 -184 4973 -188 4958 -188 ct 4944 -188 4932 -184 4924 -175 ct 4916 -166 4911 -153 4909 -136 ct +p ef +5254 0 m 5254 0 5254 0 5256 -42 ct 5256 -42 5256 -42 5254 -42 ct 5244 -27 5233 -15 5221 -7 ct +5210 1 5197 5 5183 5 ct 5157 5 5137 -5 5121 -26 ct 5106 -46 5098 -73 5098 -107 ct +5098 -144 5107 -174 5124 -196 ct 5141 -218 5164 -229 5193 -229 ct 5205 -229 5216 -227 5226 -222 ct +5236 -218 5245 -211 5254 -203 ct 5254 -203 5254 -203 5256 -203 ct 5256 -203 5256 -203 5254 -224 ct +5254 -224 5254 -224 5254 -326 ct 5254 -326 5254 -326 5315 -326 ct 5315 -326 5315 -326 5315 0 ct +5315 0 5315 0 5254 0 ct p +5254 -160 m 5247 -168 5240 -173 5233 -177 ct 5226 -181 5218 -183 5210 -183 ct +5194 -183 5183 -177 5175 -164 ct 5168 -152 5164 -133 5164 -108 ct 5164 -89 5167 -75 5174 -65 ct +5181 -56 5191 -51 5204 -51 ct 5213 -51 5221 -54 5230 -60 ct 5238 -66 5246 -75 5254 -88 ct +5254 -88 5254 -88 5254 -160 ct p ef +5613 0 m 5613 0 5613 0 5613 -326 ct 5613 -326 5613 -326 5674 -326 ct 5674 -326 5674 -326 5674 -224 ct +5674 -224 5674 -224 5672 -182 ct 5672 -182 5672 -182 5674 -182 ct 5684 -197 5695 -209 5706 -217 ct +5718 -225 5731 -229 5745 -229 ct 5771 -229 5791 -219 5807 -198 ct 5822 -178 5830 -151 5830 -117 ct +5830 -80 5821 -50 5804 -28 ct 5787 -6 5764 5 5735 5 ct 5723 5 5711 3 5701 -2 ct +5691 -6 5682 -13 5674 -22 ct 5674 -22 5674 -22 5672 -22 ct 5672 -22 5672 -22 5664 0 ct +5664 0 5664 0 5613 0 ct p +5674 -64 m 5681 -56 5688 -50 5695 -47 ct 5702 -43 5710 -41 5719 -41 ct 5734 -41 5745 -47 5753 -60 ct +5760 -72 5764 -91 5764 -116 ct 5764 -135 5761 -149 5754 -159 ct 5747 -168 5738 -173 5724 -173 ct +5716 -173 5707 -170 5698 -164 ct 5690 -158 5682 -149 5674 -136 ct 5674 -136 5674 -136 5674 -64 ct +p ef +5863 82 m 5863 82 5863 82 5863 41 ct 5863 41 5863 41 5885 41 ct 5900 41 5910 39 5916 35 ct +5922 31 5928 21 5936 6 ct 5936 6 5936 6 5948 -17 ct 5948 -17 5948 -17 5850 -224 ct +5850 -224 5850 -224 5918 -224 ct 5918 -224 5918 -224 5981 -91 ct 5981 -91 5981 -91 5981 -92 ct +5981 -92 5981 -92 6042 -224 ct 6042 -224 6042 -224 6093 -224 ct 6093 -224 6093 -224 5980 21 ct +5970 44 5958 60 5945 69 ct 5932 77 5915 82 5893 82 ct 5893 82 5893 82 5863 82 ct +p ef +6388 0 m 6352 -224 l 6406 -224 l 6428 -85 l 6462 -204 l 6505 -204 l +6540 -84 l 6563 -224 l 6603 -224 l 6565 0 l 6517 0 l 6478 -137 l +6438 0 l 6388 0 l p ef +6840 -95 m 6840 -95 6840 -95 6688 -95 ct 6691 -77 6699 -63 6711 -54 ct 6723 -45 6739 -41 6760 -41 ct +6784 -41 6811 -46 6840 -56 ct 6840 -56 6840 -56 6840 -9 ct 6805 0 6774 5 6748 5 ct +6710 5 6679 -6 6656 -27 ct 6633 -48 6622 -76 6622 -111 ct 6622 -147 6633 -175 6654 -197 ct +6676 -218 6704 -229 6739 -229 ct 6771 -229 6795 -219 6813 -199 ct 6831 -180 6840 -152 6840 -118 ct +6840 -118 6840 -118 6840 -95 ct p +6687 -136 m 6687 -136 6687 -136 6781 -136 ct 6781 -153 6777 -166 6770 -175 ct +6762 -184 6751 -188 6736 -188 ct 6722 -188 6710 -184 6702 -175 ct 6694 -166 6689 -153 6687 -136 ct +p ef +7011 -24 m 7004 -14 6995 -7 6985 -2 ct 6975 3 6964 5 6951 5 ct 6929 5 6911 -2 6897 -15 ct +6883 -28 6876 -45 6876 -65 ct 6876 -91 6886 -111 6905 -124 ct 6925 -137 6954 -143 6993 -143 ct +6993 -143 6993 -143 7017 -143 ct 7017 -143 7017 -143 7017 -154 ct 7017 -165 7013 -174 7005 -179 ct +6997 -185 6985 -188 6969 -188 ct 6947 -188 6922 -182 6895 -169 ct 6895 -169 6895 -169 6895 -214 ct +6923 -224 6951 -229 6980 -229 ct 7012 -229 7036 -223 7052 -211 ct 7062 -203 7069 -194 7073 -185 ct +7076 -175 7078 -160 7078 -140 ct 7078 -140 7078 -140 7078 -64 ct 7078 -49 7083 -41 7092 -41 ct +7094 -41 7096 -41 7099 -42 ct 7099 -42 7099 -42 7099 -2 ct 7087 3 7075 5 7065 5 ct +7054 5 7044 3 7036 -2 ct 7028 -7 7022 -14 7017 -24 ct 7017 -24 7017 -24 7011 -24 ct +p +7017 -65 m 7017 -65 7017 -65 7017 -102 ct 7017 -102 7017 -102 6995 -102 ct +6976 -102 6961 -99 6952 -94 ct 6942 -88 6937 -80 6937 -69 ct 6937 -61 6940 -54 6946 -49 ct +6952 -44 6959 -41 6968 -41 ct 6983 -41 7000 -49 7017 -65 ct p ef +7210 0 m 7121 -224 l 7187 -224 l 7249 -67 l 7310 -224 l 7359 -224 l +7271 0 l 7210 0 l p ef +7602 -95 m 7602 -95 7602 -95 7450 -95 ct 7453 -77 7461 -63 7473 -54 ct 7485 -45 7501 -41 7522 -41 ct +7546 -41 7573 -46 7602 -56 ct 7602 -56 7602 -56 7602 -9 ct 7567 0 7536 5 7510 5 ct +7472 5 7441 -6 7418 -27 ct 7395 -48 7384 -76 7384 -111 ct 7384 -147 7395 -175 7416 -197 ct +7438 -218 7466 -229 7501 -229 ct 7533 -229 7557 -219 7575 -199 ct 7593 -180 7602 -152 7602 -118 ct +7602 -118 7602 -118 7602 -95 ct p +7449 -136 m 7449 -136 7449 -136 7543 -136 ct 7543 -153 7539 -166 7532 -175 ct +7524 -184 7513 -188 7498 -188 ct 7484 -188 7472 -184 7464 -175 ct 7456 -166 7451 -153 7449 -136 ct +p ef +7666 0 m 7666 0 7666 0 7666 -224 ct 7666 -224 7666 -224 7727 -224 ct 7727 -224 7727 -224 7725 -181 ct +7725 -181 7725 -181 7727 -181 ct 7737 -197 7749 -209 7763 -217 ct 7776 -225 7792 -229 7810 -229 ct +7821 -229 7836 -227 7852 -224 ct 7852 -224 7852 -224 7852 -149 ct 7852 -149 7852 -149 7811 -149 ct +7811 -149 7811 -149 7811 -173 ct 7806 -174 7803 -174 7800 -174 ct 7785 -174 7772 -170 7759 -163 ct +7747 -156 7736 -145 7727 -130 ct 7727 -130 7727 -130 7727 0 ct 7727 0 7727 0 7666 0 ct +p ef +pom +gr +gr +0.503 0.503 0.503 c 11590 14802 m 10458 14802 l 10458 14127 l 12722 14127 l +12722 14802 l 11590 14802 l p ef +11590 14802 m 10458 14802 l 10458 14127 l 12722 14127 l 12722 14802 l +11590 14802 l pc +0.753 0.753 0.753 c 11490 14702 m 10358 14702 l 10358 14027 l 12622 14027 l +12622 14702 l 11490 14702 l p ef +0.003 0.003 0.003 c 11490 14702 m 10358 14702 l 10358 14027 l 12622 14027 l +12622 14702 l 11490 14702 l pc +gs +gs +pum +10594 14516 t +1.000 1.000 1.000 c 29 -291 m 29 -291 29 -291 144 -291 ct 186 -291 220 -277 246 -250 ct +272 -223 285 -189 285 -146 ct 285 -105 272 -70 245 -42 ct 219 -14 185 0 144 0 ct +144 0 144 0 29 0 ct 29 0 29 0 29 -291 ct p +88 -49 m 88 -49 88 -49 138 -49 ct 159 -49 179 -58 197 -75 ct 215 -93 224 -116 224 -145 ct +224 -176 216 -200 199 -217 ct 182 -234 161 -242 138 -242 ct 138 -242 138 -242 88 -242 ct +88 -242 88 -242 88 -49 ct p ef +533 0 m 533 0 533 0 476 0 ct 476 0 476 0 476 -27 ct 458 -6 435 5 407 5 ct 385 5 367 -2 354 -15 ct +341 -28 334 -47 334 -71 ct 334 -71 334 -71 334 -215 ct 334 -215 334 -215 391 -215 ct +391 -215 391 -215 391 -89 ct 391 -59 402 -44 424 -44 ct 443 -44 461 -54 476 -75 ct +476 -75 476 -75 476 -215 ct 476 -215 476 -215 533 -215 ct 533 -215 533 -215 533 0 ct +p ef +910 0 m 910 0 910 0 853 0 ct 853 0 853 0 853 -125 ct 853 -143 851 -155 846 -162 ct +842 -168 835 -171 826 -171 ct 811 -171 796 -160 780 -137 ct 780 -137 780 -137 780 0 ct +780 0 780 0 723 0 ct 723 0 723 0 723 -125 ct 723 -144 721 -157 716 -162 ct 712 -168 706 -171 697 -171 ct +682 -171 666 -160 650 -137 ct 650 -137 650 -137 650 0 ct 650 0 650 0 593 0 ct 593 0 593 0 593 -215 ct +593 -215 593 -215 650 -215 ct 650 -215 650 -215 650 -182 ct 667 -207 688 -220 715 -220 ct +743 -220 763 -207 775 -182 ct 793 -207 816 -220 845 -220 ct 866 -220 882 -214 893 -201 ct +904 -188 910 -169 910 -144 ct 910 -144 910 -144 910 0 ct p ef +1027 -192 m 1034 -201 1043 -207 1055 -212 ct 1067 -217 1079 -220 1091 -220 ct +1118 -220 1139 -210 1156 -190 ct 1173 -171 1182 -144 1182 -112 ct 1182 -76 1173 -47 1156 -26 ct +1139 -5 1118 5 1091 5 ct 1064 5 1043 -4 1027 -21 ct 1027 -21 1027 -21 1027 84 ct +1027 84 1027 84 970 84 ct 970 84 970 84 970 -215 ct 970 -215 970 -215 1027 -215 ct +1027 -215 1027 -215 1027 -192 ct p +1027 -69 m 1040 -52 1056 -44 1076 -44 ct 1090 -44 1101 -50 1110 -61 ct 1119 -73 1123 -89 1123 -108 ct +1123 -129 1119 -144 1110 -155 ct 1101 -166 1089 -171 1076 -171 ct 1057 -171 1041 -162 1027 -145 ct +1027 -145 1027 -145 1027 -69 ct p ef +1256 -66 m 1266 -66 1275 -63 1282 -56 ct 1289 -49 1292 -41 1292 -31 ct 1292 -21 1289 -12 1282 -5 ct +1275 2 1266 5 1256 5 ct 1246 5 1238 2 1231 -5 ct 1224 -12 1221 -20 1221 -31 ct +1221 -41 1224 -49 1231 -56 ct 1238 -63 1246 -66 1256 -66 ct p ef +1531 0 m 1531 0 1531 0 1472 0 ct 1468 -9 1466 -17 1466 -25 ct 1447 -5 1424 5 1397 5 ct +1377 5 1361 -1 1350 -13 ct 1339 -24 1333 -40 1333 -59 ct 1333 -73 1337 -85 1344 -95 ct +1352 -106 1363 -114 1378 -120 ct 1393 -127 1410 -131 1431 -132 ct 1431 -132 1431 -132 1466 -135 ct +1466 -135 1466 -135 1466 -139 ct 1466 -163 1452 -175 1425 -175 ct 1417 -175 1406 -173 1392 -170 ct +1378 -166 1366 -162 1356 -157 ct 1356 -157 1356 -157 1342 -198 ct 1355 -204 1371 -210 1388 -214 ct +1406 -218 1421 -220 1435 -220 ct 1464 -220 1486 -213 1501 -199 ct 1516 -185 1523 -165 1523 -138 ct +1523 -138 1523 -138 1523 -51 ct 1523 -31 1526 -14 1531 0 ct p +1466 -66 m 1466 -66 1466 -66 1466 -101 ct 1442 -99 1427 -97 1421 -96 ct 1416 -95 1410 -93 1403 -89 ct +1397 -86 1393 -82 1390 -77 ct 1387 -72 1385 -67 1385 -61 ct 1385 -54 1387 -49 1392 -45 ct +1396 -40 1402 -38 1409 -38 ct 1430 -38 1449 -47 1466 -66 ct p ef +1783 0 m 1783 0 1783 0 1726 0 ct 1726 0 1726 0 1726 -125 ct 1726 -156 1715 -171 1693 -171 ct +1674 -171 1656 -160 1641 -139 ct 1641 -139 1641 -139 1641 0 ct 1641 0 1641 0 1584 0 ct +1584 0 1584 0 1584 -307 ct 1584 -307 1584 -307 1641 -307 ct 1641 -307 1641 -307 1641 -188 ct +1659 -209 1682 -220 1710 -220 ct 1732 -220 1750 -213 1763 -200 ct 1776 -187 1783 -168 1783 -144 ct +1783 -144 1783 -144 1783 0 ct p ef +pom +gr +gr +0.300 0.300 0.300 c 8672 14197 m 9709 14947 l 9793 14831 l 9847 15147 l +9529 15196 l 9613 15080 l 8576 14330 l 8672 14197 l p ef +gs +gs +pum +8932 14288 t +324.1 r 0.003 0.003 0.003 c 44 0 m 20 0 l 20 -143 l 44 -143 l 44 0 l p +32 -205 m 36 -205 40 -204 43 -201 ct 46 -198 47 -194 47 -190 ct 47 -186 46 -183 43 -180 ct +40 -177 36 -176 32 -176 ct 28 -176 25 -177 22 -180 ct 19 -183 18 -186 18 -190 ct +18 -194 19 -198 22 -201 ct 25 -204 28 -205 32 -205 ct p ef +202 0 m 202 0 202 0 178 0 ct 178 0 178 0 178 -91 ct 178 -102 175 -110 170 -116 ct +165 -122 157 -125 148 -125 ct 134 -125 120 -117 107 -101 ct 107 -101 107 -101 107 0 ct +107 0 107 0 83 0 ct 83 0 83 0 83 -143 ct 83 -143 83 -143 107 -143 ct 107 -143 107 -143 107 -122 ct +122 -138 138 -146 155 -146 ct 169 -146 181 -142 189 -133 ct 198 -125 202 -113 202 -97 ct +202 -97 202 -97 202 0 ct p ef +231 -72 m 231 -95 238 -113 251 -126 ct 265 -139 282 -146 302 -146 ct 319 -146 336 -141 351 -132 ct +351 -132 351 -132 344 -113 ct 331 -121 317 -125 303 -125 ct 289 -125 278 -120 269 -110 ct +260 -101 256 -88 256 -72 ct 256 -55 260 -42 269 -33 ct 278 -23 289 -18 303 -18 ct +316 -18 331 -23 346 -32 ct 346 -32 346 -32 353 -13 ct 337 -2 320 3 303 3 ct 281 3 264 -4 251 -18 ct +238 -31 231 -49 231 -72 ct p ef +408 0 m 384 0 l 384 -205 l 408 -205 l 408 0 l p ef +566 0 m 566 0 566 0 542 0 ct 542 0 542 0 542 -21 ct 527 -5 511 3 494 3 ct 480 3 468 -1 460 -10 ct +451 -18 447 -30 447 -46 ct 447 -46 447 -46 447 -143 ct 447 -143 447 -143 471 -143 ct +471 -143 471 -143 471 -52 ct 471 -42 474 -33 479 -27 ct 484 -21 492 -18 501 -18 ct +515 -18 529 -26 542 -42 ct 542 -42 542 -42 542 -143 ct 542 -143 542 -143 566 -143 ct +566 -143 566 -143 566 0 ct p ef +722 0 m 722 0 722 0 698 0 ct 698 0 698 0 698 -18 ct 688 -4 673 3 656 3 ct 637 3 622 -4 611 -18 ct +601 -32 595 -50 595 -74 ct 595 -96 601 -113 612 -126 ct 623 -139 637 -146 654 -146 ct +673 -146 688 -139 698 -125 ct 698 -125 698 -125 698 -205 ct 698 -205 698 -205 722 -205 ct +722 -205 722 -205 722 0 ct p +698 -42 m 698 -42 698 -42 698 -102 ct 695 -109 690 -114 683 -118 ct 676 -123 669 -125 661 -125 ct +648 -125 638 -120 631 -111 ct 624 -102 620 -89 620 -72 ct 620 -55 624 -42 631 -32 ct +638 -23 649 -18 661 -18 ct 667 -18 672 -19 677 -22 ct 683 -24 687 -28 692 -32 ct +696 -37 698 -40 698 -42 ct p ef +887 -15 m 867 -3 847 3 827 3 ct 803 3 785 -4 772 -17 ct 759 -30 752 -49 752 -72 ct +752 -94 758 -112 770 -126 ct 783 -139 799 -146 820 -146 ct 839 -146 854 -140 866 -127 ct +878 -114 884 -97 884 -75 ct 884 -75 884 -75 884 -69 ct 884 -69 884 -69 777 -69 ct +778 -52 782 -40 791 -31 ct 799 -22 811 -18 827 -18 ct 845 -18 862 -23 880 -34 ct +880 -34 880 -34 887 -15 ct p +859 -88 m 858 -99 854 -108 846 -115 ct 839 -122 830 -125 820 -125 ct 809 -125 800 -122 792 -115 ct +785 -109 780 -100 778 -88 ct 778 -88 778 -88 859 -88 ct p ef +pom +gr +gr +9932 12877 m 8681 13424 l 8647 13346 l 8515 13579 l 8776 13640 l 8742 13563 l +9992 13015 l 9932 12877 l p ef +gs +gs +pum +8806 13270 t +23.6 r 0.003 0.003 0.003 c 44 0 m 20 0 l 20 -143 l 44 -143 l 44 0 l p +32 -205 m 36 -205 40 -204 43 -201 ct 46 -198 47 -194 47 -190 ct 47 -186 46 -183 43 -180 ct +40 -177 36 -176 32 -176 ct 28 -176 25 -177 22 -180 ct 19 -183 18 -186 18 -190 ct +18 -194 19 -198 22 -201 ct 25 -204 28 -205 32 -205 ct p ef +202 0 m 202 0 202 0 178 0 ct 178 0 178 0 178 -91 ct 178 -102 175 -110 170 -116 ct +165 -122 157 -125 148 -125 ct 134 -125 120 -117 107 -101 ct 107 -101 107 -101 107 0 ct +107 0 107 0 83 0 ct 83 0 83 0 83 -143 ct 83 -143 83 -143 107 -143 ct 107 -143 107 -143 107 -122 ct +122 -138 138 -146 155 -146 ct 169 -146 181 -142 189 -133 ct 198 -125 202 -113 202 -97 ct +202 -97 202 -97 202 0 ct p ef +231 -72 m 231 -95 238 -113 251 -126 ct 265 -139 282 -146 302 -146 ct 319 -146 336 -141 351 -132 ct +351 -132 351 -132 344 -113 ct 331 -121 317 -125 303 -125 ct 289 -125 278 -120 269 -110 ct +260 -101 256 -88 256 -72 ct 256 -55 260 -42 269 -33 ct 278 -23 289 -18 303 -18 ct +316 -18 331 -23 346 -32 ct 346 -32 346 -32 353 -13 ct 337 -2 320 3 303 3 ct 281 3 264 -4 251 -18 ct +238 -31 231 -49 231 -72 ct p ef +408 0 m 384 0 l 384 -205 l 408 -205 l 408 0 l p ef +566 0 m 566 0 566 0 542 0 ct 542 0 542 0 542 -21 ct 527 -5 511 3 494 3 ct 480 3 468 -1 460 -10 ct +451 -18 447 -30 447 -46 ct 447 -46 447 -46 447 -143 ct 447 -143 447 -143 471 -143 ct +471 -143 471 -143 471 -52 ct 471 -42 474 -33 479 -27 ct 484 -21 492 -18 501 -18 ct +515 -18 529 -26 542 -42 ct 542 -42 542 -42 542 -143 ct 542 -143 542 -143 566 -143 ct +566 -143 566 -143 566 0 ct p ef +722 0 m 722 0 722 0 698 0 ct 698 0 698 0 698 -18 ct 688 -4 673 3 656 3 ct 637 3 622 -4 611 -18 ct +601 -32 595 -50 595 -74 ct 595 -96 601 -113 612 -126 ct 623 -139 637 -146 654 -146 ct +673 -146 688 -139 698 -125 ct 698 -125 698 -125 698 -205 ct 698 -205 698 -205 722 -205 ct +722 -205 722 -205 722 0 ct p +698 -42 m 698 -42 698 -42 698 -102 ct 695 -109 690 -114 683 -118 ct 676 -123 669 -125 661 -125 ct +648 -125 638 -120 631 -111 ct 624 -102 620 -89 620 -72 ct 620 -55 624 -42 631 -32 ct +638 -23 649 -18 661 -18 ct 667 -18 672 -19 677 -22 ct 683 -24 687 -28 692 -32 ct +696 -37 698 -40 698 -42 ct p ef +887 -15 m 867 -3 847 3 827 3 ct 803 3 785 -4 772 -17 ct 759 -30 752 -49 752 -72 ct +752 -94 758 -112 770 -126 ct 783 -139 799 -146 820 -146 ct 839 -146 854 -140 866 -127 ct +878 -114 884 -97 884 -75 ct 884 -75 884 -75 884 -69 ct 884 -69 884 -69 777 -69 ct +778 -52 782 -40 791 -31 ct 799 -22 811 -18 827 -18 ct 845 -18 862 -23 880 -34 ct +880 -34 880 -34 887 -15 ct p +859 -88 m 858 -99 854 -108 846 -115 ct 839 -122 830 -125 820 -125 ct 809 -125 800 -122 792 -115 ct +785 -109 780 -100 778 -88 ct 778 -88 778 -88 859 -88 ct p ef +pom +gr +gr +tm setmatrix +0 0 t +1 1 s +0 20028 t +pom +count op_count sub {pop} repeat countdictstack dict_count sub {end} repeat b4_inc_state restore +%%PageTrailer +%%Trailer +%%EOF diff --git a/AspectC++/doc/images/no_include_cycle.odg b/AspectC++/doc/images/no_include_cycle.odg new file mode 100644 index 0000000..850c729 Binary files /dev/null and b/AspectC++/doc/images/no_include_cycle.odg differ diff --git a/AspectC++/doc/images/peanut.png b/AspectC++/doc/images/peanut.png new file mode 100644 index 0000000..3d335b9 Binary files /dev/null and b/AspectC++/doc/images/peanut.png differ diff --git a/AspectC++/doc/images/peanut.xcf b/AspectC++/doc/images/peanut.xcf new file mode 100644 index 0000000..ae25ebf Binary files /dev/null and b/AspectC++/doc/images/peanut.xcf differ diff --git a/AspectC++/doc/images/ps-logo.eps b/AspectC++/doc/images/ps-logo.eps new file mode 100644 index 0000000..bcd7294 --- /dev/null +++ b/AspectC++/doc/images/ps-logo.eps @@ -0,0 +1,1524 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Creator: GIMP PostScript file plugin V 1.12 by Peter Kirchgessner +%%Title: /home/papajews/pure-systems/FastBoot/Studie/images/ps-logo.eps +%%CreationDate: Sat Jul 20 14:19:35 2002 +%%DocumentData: Clean7Bit +%%LanguageLevel: 2 +%%Pages: 1 +%%BoundingBox: 14 14 643 141 +%%EndComments +%%BeginProlog +% Use own dictionary to avoid conflicts +10 dict begin +%%EndProlog +%%Page: 1 1 +% Translate for offset +14.173228 14.173228 translate +% Translate to begin of first scanline +0.000000 126.000000 translate +628.000000 -126.000000 scale +% Image geometry +628 126 8 +% Transformation matrix +[ 628 0 0 126 0 0 ] +% Strings to hold RGB-samples per scanline +/rstr 628 string def +/gstr 628 string def +/bstr 628 string def +{currentfile /ASCII85Decode filter /RunLengthDecode filter rstr readstring pop} +{currentfile /ASCII85Decode filter /RunLengthDecode filter gstr readstring pop} +{currentfile /ASCII85Decode filter /RunLengthDecode filter bstr readstring pop} +true 3 +%%BeginData: 100554 ASCII Bytes +colorimage +"T735h;.JT!o2o9rVllsaSuJBi8*8GhVI\Xs4m\DJcC<$JcC?%J,~> +"T735h;.JT!o2o9rVllsaSuJBi8*8GhVI\Xs4m\DJcC<$JcC?%J,~> +"T7-1gY;,N!nuc7rVllsaSuJBi8*2ChVI\Vs4[PBJcC<$JcC?%J,~> +#krpqH$Xa]H?o%,!d0k._uBr4Is6-`G^8h*"*o33\q0m4s+13%s*t~> +#PWgpH$Xa]HLQ1]FdN'Errr"DGBeFYms+t\E4UW#JcC<$K)^?~> +#PWalGBe=UGjonYF-Z^Arrr"BF`r"QmrnhXDRb8tJcC<$K)^?~> +#PWjpH$aj`Hgl=aFI<"+rl+m=o7(uOH3AS?Ek21#s+13$s+C?%~> +#PWgnG^=X\HLQ1_FI<"+rl+m=o7(uOGm&G +#PWajG'J4TGjon[EgHY'rl+m=o6kcKG6E/6Dn#^ss+13$s+C?%~> +!r%@nl[&\UQi4i%!qLkel[&_S])Vb\s+13$s+LE&~> +!r%=llZrVTQi4i%!qLkdlZrYQ])Vb\s+13$s+LE&~> +!r%7hlZ`JPQ2SW#"7Ub_G3jGUDn,iHJcC<$JcCE'J,~> +!r%@np3Qder-JZrH[C'cG*i0FrrhnDH$al:HiA?kHN8HkHO"qFH$XgaEk6i%JcC<$K)^?~> +!r%=lp3H^cr-ATpH?sj_FdN'ErrVbAGl;pgHi/0iHi/3iHN8?jH3&#rJcC<$JcC?%J,~> +"8@@iG5$4]H2MmlH$FRXG]T/K_uBf/IWk[7!."Ke!."Kes*4TgrceH^[t4R1s+13%s*t~> +!r%@npNlmfrd+uuI!^3fH@1'_Qi4i%"S.+hH[>R9!.=Wi#C:`DH@(!Z\q0m4s+13%s*t~> +!r%=lpNcgdrd"osH[:!bH$aj[Qi4i%!qLkdq0E$fqK`3gH@,X;!HGZ$s+13$s+:9$~> +"8@@iG5-:^H2`$qGBnFXH$=OYF-Z^ArrVb?G56@_H2;aeGBeE4GQD`lJcC<$JcC?%J,~> +!r%@nqKi3ird+Wmr-JEkrd+`pG*i0FrrhnDH$al:HN8HiHN8HmHNnkDH@(!Z\q0m4s+13%s*t~> +!r%=lqK`-grd"Qkr-A?ird"ZnFdN'ErrVbAGl2jfHhr$gHiA +"8@@iG5HLaH2`$gH2MmeH2`$jH#o8L_uBf/IWkX6!."Ec!."Qg!I8ngGQD`lJcC<$JcC?%J,~> +!r%@nq0N*hr-JcsI!^3fI!^3`Qi4i%)Y/H)H[:$cI!U-eH[C$cH[:$bH[C-dH[BeEJcC<$JcC?% +J,~> +!r%=lq0E$fr-A]qH[:!bH[:!\Qi4i%!qLkdrH]-(H$Xg`H?ad_H$Xa^H@'p`H?$KHs+13$s+:9$~> +"8@@iG5?F`H2MmoGBnFXH$OXZF-Z^ArrVb?G5ZY!H$=LYG^+CWG^"CVG^+LXG^+/9JcC<$JcC?% +J,~> +!r%@nqg/`tI!KgXF`_qXH@($erd+]iQi4i%"S.+hH[>R9#Bk04F*)_SI/A6kEk6i%JcC<$K)^?~> +!r%=lqg&ZrH['UTFE;_TH$Xgard"WgQi4i%!qLkdq0E9gEd)SGH$Oc6H3&#rJcC<$JcC?%J,~> +"8@@iG5QRnFa8.MFE2AFH?XUZH2`$iF-Z^ArrVb?G56@fF)Z8AEHcVPqfi-[[t4R1s+13%s*t~> +!r%@nqg/ZrFbR!C_khj,I!Yd="F>EU:#Bc0;bep6*GlE$iI/\HnEk6i%JcC<$ +K)^?~> +!r%=lqK`HjKs&\ +"8@@iG5HLjF+^R;_4uF#H$B74"F#*3Q2SW#!qLe`qKN6cO0m'GU3h%^GQ<$gGQD`lJcC<$JcC?% +J,~> +!r%@nqg/`pMWt0?s8U_uH$amcrd+]iQi4i%$hAjoH[:$cI!Tq-p\k*pe:2ajHMr0kEk6i%JcC<$ +K)^?~> +!r%=lqg&ZoMWt0?s8U_tG^=[_rd"WgQi4i%!qLkdrH\TnH$#\QrVm#MIX$0arH\Ka\Ujd3s+13% +s*t~> +"8@@iG5QRnFGT2]rr<#NG]n=VH2`$iF-Z^ArrVb?G5ZXgH$=;"p\k*pe9lFaGPuaeDmt;tJcC<$ +K)^?~> +!r%@nqg/?hhZ!NYrr<#/FF="5!d9q/_uC)7JU)TgH[C'bKCAg>"TJH$_0,X%!HPc&s+13$s+:9$~> +!r%=lqg&9ghZ!NYrr<#.F*mh2!d0k._uBf/J9_$=s*4Wtn,E=irr<#7FSg@bEOgZ#JcC<$K)^?~> +"8@@iG5QRcGM`5s!k*)or-/9aQ2SW#!qLe`rHS?d!J0Y;rrrE%s1`Str-/6\[t4R1s+13%s*t~> +%JPR%I!^6fH[(;>s8W)trsS.AH@(!bH[Bq&rVl*^!<1dR"S.+hH[>[ +%JPO#H[:$bH?Y,C2oja;?#rH\Ka\Ujd3 +s+13%s*t~> +%JPHtH$FUZG]ec8s8W)trsS+?GBe@VG^+:prVlfr!<)?c!<1dR!qLe`r-/6^U\aumja),rrHJ?] +[t4R1s+13%s*t~> +!r%@nr-JHdU&G!(rr<#lJp;ZiH[L0`Qi-m_q8U8=_?@cm_nFn*rrW#9_!]&B_nj1(hZ!NXnpu(5 +HN&6pFN+7Zrr2os!r@h"r-JHb\q0m4s+13%s*t~> +!r%=lr-ABbU&G!(rr<#jJTlHeH@'s\Qi-m_q8U5;_?7Wl^"r\f!r9jOm_T+E_83nCrr3&jJ9_!< +"`qZ^s8N#srrW%TGPlafEOgZ#JcC<$K)^?~> +!r%7hr-/6^U&G!(rr<#kIs$$]G^4OTQ2L[]q8U/;^]hTj^VRV>rr3,s`kK7*n\>=F_nWt"hZ!NV +npYc[GQi*)rr;usrr3&rM08`@!H5Gus+13$s+:9$~> +!r%@nr-JKgPPtCY&,(R#H@(!dHZkbSrVuM9EU\#ZFE2GEF(hlZrr2P8E,p!hF8p:\Erg!]rr3,l +JU)Tgrd,#p\,ZI-s8N&uo7VAdHNA/uJcC<$JcC?%J,~> +!r%=lr-AEePPtCY&+kBtH$Xd`H?GSQrVuM9E:@lVF)c5AEbMcYrr2P8E:%ZJF)l!$rr3&jJ9_!< +$ZifWrr<#ts8V\CGPlafEOgZ#JcC<$K)^?~> +!r%7hr-/9aOo>1W&+tBqGBe@XG]T/KrVuM9DX_TREGof9E+Z?Srr2P6DXDBFEH#Qqrr3&jIWkX6 +$ZWTSrr<#ts8VV?Fo6IbDmt;tJcC<$K)^?~> +!r%@nrHeWoH@>2Xrt!M%H@1'cH[Bq&rVulhJU-d4!do?Brd+Ze[f6:.oRM5UHOY:JH@'\Brr<#h +JU)Tgrd+fmOT#4Zrr2ouds1b:!HPc&s+13$s+:9$~> +!r%=lrH\QmH%#)Wrt!J#H$aj_H?s_#rVulhJU$^2!df6?rd"Tc[f6:.oRM2RH3nkCEOc#Js71\b +r-ANiO8]+Yrr2ouds(\8!HGZ$s+13$s+:9$~> +!r%7hrHJEiGC/ZQrt!CtGBnFWG^+:prVulhIs1@,!dT$9rceH_[/U(,oR:uNGR8S=DmoZFs71V^ +r-/BeNW&nWrr2oud<5>2!H5Gus+13$s+:9$~> +!r%@nqg/BfVXscd&F,*rH[C'dH@'h%rVuojJU-[1"F>HAEjkuI!q_"gl[&YP\c2U3npu(5HMr0l +FgqAKrsItRGC"U_H@(!Z\q0m4s+13%s*t~> +!r%=lqg&EjkuI!q_"flZrSN\,QC/npku^H3/2t +rr)j!k`U+7r-AB`\Ujd3s+13%s*t~> +!r%7hqfi0aV"+E`&F,!lG^+FXGBe1orVuojIs17)"F#-8E4#WE!q^qblZ`GJ\GlL0npYcZGQMon +rr)j!k`Bn1r-/6\[t4R1s+13%s*t~> +!r%@nqKj!!NmdOb`IrD]H[L0eI!Tt&rVuojJU-R.!HGRIrrVhDH0]eXF1;/K"S.+hH[>X;&UJYq +h"0dKK6;QhH@'sbHZH]Ks+13$s+:9$~> +!r%=lqK`otNmdOb`IrA[H@'saH[0b#rVuojJU$O-!depqrr3&lJU$L,!HP[KrrVbAGl)dpH$5q; +oBF2GFF/@[rH\Ka\Ujd3s+13%s*t~> +!r%7hqKNcpN6q1^_h)rSG^4OYH$==prVuojIs11'!dS^krr3&lIs1.&!H>OIrrVb?G5HLlGBBM5 +oBF,CEd;qSrHJ?][t4R1s+13%s*t~> +!r%@nrd,!"H[L0eGBe[eGBj+6%!m;IH[L"'r;ZchJU-d4#CLlFI!^3Z\,QC/oRV;UHN\_CHZQ[q +rt4gQH$ajaH[:$dHZa[cIWg!arHeZnH[BeEJcC<$JcC?%J,~> +!r%=lrd"ouH@'saG'JRdG'Eq3%!d2FH@'e$r;ZchJU$^2#CCcCH[:!W\,QC/oRM2SH3AS@H?-Lo +rrVbAGl)dmH[9d[J:;WcHhr$hEOgZ#JcC<$K)^?~> +!r%7hrcecqG^4OYFEW.\FERS-%!Qu@G^4@qr;ZchIs1@,#C1Q=H$FRO[Jp1-oR:uOGQ`;:G]:(i +rrVb?G5HLiH$F@SIXH3[H2;adDmt;tJcC<$K)^?~> +!r%Cord+Wmr-JKkH$TC9!.+Wk$@I2IG*i1-s7Lqgl[&qX[K$:+omqF9I.;O`I/\HnEOYrI%e>0r +H[:$cH@(!dH[:!`r-JWqH[:$cEk6i%JcC<$K)^?~> +!r%@mrd"Qkr-AEiG^046!."Qi$@@)FFdN(,s7LqflZrkW[K$:+omh=6HguC^HiA +!r%:irceEgr-/9eG' +!r%@nl[&kZQN$paon%JeHO5(GH@($bH[C-frHeZpH[Bb@rr3&lJ9^g8s*4Tjpj3$^\,QC/npu)P +HNA/uJcC<$U]1Mss8N&urr2otrdk+7s*t~> +!r%=llZreYQN$paomqAcH2rrr3&lJ9^g7s*=?b!HGUJrrVbAGjBYV +EOp`$JcDMF"oeQ$s8W)trrE%Ls6BW7~> +!r%7hlZ`YUPlC^_om_/_GQ;seGQiA9G^+LZrHJHjG^+/6rr3&lIWkI1s*+3^!H5CFrr_h@FE["q +!H5K!s+13FrrrE%rr<#trr2utJcG$8J,~> +!r%@nl['FjQi-m`omqC7I!^0eH[C'_FaA=SH$ar9HNA,prr3&lJ9_'?%=EMMH[BmZH[0^XH[C/< +HNA/rrr3&jJp?U.!ckpPJcC<$TDo/qs8N&urr;tKs6]i:~> +!r%=llZs@iQi-m`omh:4H[9saH@'s]FF&4RG^=`6H3&#orr3&lJ9_'>%= +!r%7hlZa4eQ2L[^omV(.H$FOYG^4OUEd2eJG'J<0GQD`irr3&lIWk^8%=*2DG^+7NH$=:OG^+N3 +GQD`jrr3&jIs((%!cPUJJcC<$TDo/qs8N&urr;tKs6]i:~> +!r%@nl['IkQi@$boRhC9H@($dH[0ds`9#ghJp;Tfr-JHa[f6:1oRM15H[Pd=$@&/hkM+,!HPc&s+13GrsJc*s8N&tm(1: +!r%=llZsCjQi@$boR_:6H$Xg`H?j[r`9#ghJp2Kcr-AB`[f6:1oRM14H@,U:$?r&dkM +!r%7hlZa7fQ2^g`oRM(0GBeCXG^"7j`9#gfJ9?'[r-/6\[/U(/oR:t.G^974$?_iakM<[uFEi"T +rHJ?][Jp10o6kh-H$A\$!H5Gus+13GrsJc*s8N&tm't.:rIP"6s*t~> +!r%@nl['1cQi6sap47O:I!^0eH?6:drVlr]Jp@0>!HGRIrrVhCGl;skI!]t=rr30$s5elWI/JgPprVm#YZ[unnJcFs6J,~> +!r%=llZs+bQi6sap4.F7H[9saH#p1crVlr]Jp@0=!HGRIrrVhCGl;pjH[9b:rr30$s5eiUHi/0j +EOYrI"S.(fH[5%*!deptJcC<$V>gPprVm#YZ[unnJcFs6J,~> +!r%7hlZ`t^Q2Ua_p3q41H$FOYGB'b]rVlr[J9Lg7!H5@ErrVhAG5ZXfH$F>2rr30$s5ecQH2Mmf +DmfTE"S."bH$A\$!dS^nJcC<$V>gPprVm#YZ%-JfJcFs6J,~> +!r%=lrd"Qkms54\Qi-m`on%JeHNJGLp\XssaE2fVH?spbEOPlH$hSsoH[C-eH[(MFrquct`cZS) +HNA/rrr3/mJU)QfHgl=aH[0YCrdk*#s.oZ"rnO;rFEhf1JcFs6J,~> +!r%:jrcnKims,.[Qi-m`omqAcH3/;Jp\XssaE2cTH$O^^EOPlH$hSsoH?spaH?Y>Drquct`cQJ' +H3&#prr3/kJ9Z?bHLQ1_H?aG?rdk*#s.oZ"rnO;rFEhf1JcFs6J,~> +!r%4frc\?emro"WQ2L[^om_/_GQN#Dp&"aq`c??LGB\:VDm]ND$hSmkG^+LYG]eo>rquct`,^&! +GQD`jrr3/lIWfpZGjon[G]n#7rdk*#s.oZ"r7[ljEcuB)JcFs6J,~> +!r.7grHJ1YPl:X^on%JeHNA2lrr2utrr3&mKR*KB!HGRIrrVhCGl2mhEj5E?!qV%ir-JHb +\,QC/o6kfLGQi;9DR]ZFJcC<$W;d8)psY[VFEr4[E3T=ms69Q6~> +!r.4erHA6bn95+XPl:X^omqAcH3&&jrr2utrr3&mKR!E@!HGRIrrVhCGl2jgEj5E?!qV%hr-AB` +\,QC/o6b]IG6E/-\,ZGYs+13KrsSi$e!bN'G^=[TYl94Rl2Q8~> +!r..arH/*^n9"tTP5YF\om_/_GQDcdrr2utrr3&kJp.':!H5@ErrVhAG5QRcE3B';!qUtdr-/6\ +[Jp1-o6PKEFTcl'[K$5Ws+13KrsSi"d?o)tG'J7LY5X"Pl2Q8~> +!rUQold,m_g]%3Pon%JeHOP#7s8W)us8N&uPBV?OHNA,prr3&lJ9_!=!cuB\rVm$"s8A+)r-JHb +\,QC/r6j$mciDJ^ciq_Xrr<#tJcC<$WrEG'R<3OqI=$?gE3Fimkl6/~> +!rUQold,m_g]%3PomqAcH44l5s8W)us8N&uPBM6MH3&#orr3&lJ9_! +!rUQold,m]g]%3Pom_)]GRST/s8W)us8N&uPB;$IGQD`irr3&lIWkX6!cc0XrVm$"s8A%$r-/6\ +[Jp1-r6WdhciDJ^ciqYVrr<#tJcC<$WrEG'QZ@+iH?a^[DQSKikl6/~> +k5PVas8VbDH2N!iFK,9>!<2ut!pY8\r-JHa[f6:.oRM2aHNA2fqu6ful@4)*rHeQc\,QC-rosFc +rr<#trdk*#s/H#+q1a'=I!U0dHZ-.fJcG!7J,~> +k5PVas8VbCGl2jgF/f0=!<2ut!pY8[r-AB`[f6:.oRM2aH3&)equ6ful@4&(rH\Ka\,QC-rosFc +rr<#trdk*#s/H#+q1a'=H[0s`H>g%eJcG!7J,~> +kl1nds8N&uo7(l[GQDf`rr2utrr3&bIs1a7!H5@ErrVhAG5QRcEN8p9"TI\7G'En0!H5CFrrE&_ +rri?$s8N"Ks+13LrsSXUFEi(TH$=LMYl94Rl2Q8~> +j8T2RJU.6A"FPQAK(Ss?!QoQ^HNA,prr3&lJ9_!=!dK=gr;Qp!aE;fVrHeQc\$>r5rltHFrr<#t +p&>$kqYpQpr;Qlus8W)hrrE&prrW3"rp]pfrql]qrl4s?rr<#te,KFId/O:GMKX>nI/\HpENoKB +r;Qits8MWi!<2Ng!ri6!li-taqYpQpq#:?n^&NT~> +j8T2RJU%0?"FGH>Jb/d=!QoQ^H3&#orr3&lJ9_!r5rltHFrr<#t +p&>$kqYpQpr;Qlus8W)hrrE&prrW3"rp]pfrql]qrl4s?rr<#te,KFId/O:GMKX;lHiA +j8T2RIs1g9"F568J+$kqYpQpr;Qlus8W)hrrE&prrW3"rp]pfrql]qrl4s?rr<#te,KFId/O:GLidldH2`$jDQa$= +r;Qits8MWi!<2Ng!ri6!li-taqYpQpq#:?n^&NT~> +j8TbbJU)WhH[C-dFgLiBrr;u_Lj&ZB!HGRIrrVhCGl)ghFLD,Hrr_PBGC9=8!HPZWrr`9#s8LXM +!<2ut"TJH#s8MHd!<2fo!<2ip!<2lqs8M?a!<2or!<2Ed!<1pV!<1sW!<2rs!<2Kf"9/?"rql]q +rr2otrqQKnrql^!rr;uts8Mcm!<2fo!<2lq"8RgtI/\I"I!]n;s8W)us8N#rrrE&jrr`9#s8Mrr +!<29`!ri6!rr2utqYpQpr;Qcrqu6Zqp\t6mrr2utg]%9Qo`'F~> +j8TbbJTuNeH?sp`FL(Z@rr;u_Lj&ZA!HGRIrrVhCGl)dgFLD,Hrr_PBG'j.5!HGTVrr`9#s8LXM +!<2ut"TJH#s8MHd!<2fo!<2ip!<2lqs8M?a!<2or!<2Ed!<1pV!<1sW!<2rs!<2Kf"9/?"rql]q +rr2otrqQKnrql^!rr;uts8Mcm!<2fo!<2lq"8RgtHiA +j8TbbIs-*]G^+LXEj5< +j8T_aJU)QhH[L-fH?YLtg=jN!G5?OdEOPlH!q_"fr-SHi#^<#pf\=;rG'a%4!HPZXrrE&UrrE&R +rr`9#s8M0\!<2ip!<2ut"oeQ%rr;uprrE&rrrW3"rqucrrr)isrmUlIrql]qrp]pfrquctrr;uj +rrE&srrE&drrE&prr`9#s8MEc!<2rs!r7^rqg/BaYl=M!!<2ut!<1XN!<2fo!<2ut"TJH#s8Mio +"9/?#rq??orr<#tqu6cts8W)]rrW3"rr2otrql]qrr)kI~> +j8T_aJTuHeH@'pbH$5=rg=jN!G5?LcEOPlH!q_"fr-A]qH?Z+8f\=;rFa +j8T_aIs-$]G^4LZGBAnjg=jMtFS^4_Dm]ND!q^qbr-/QmG]f\0f%IljF*IM+!H5BSrrE&UrrE&R +rr`9#s8M0\!<2ip!<2ut"oeQ%rr;uprrE&rrrW3"rqucrrr)isrmUlIrql]qrp]pfrquctrr;uj +rrE&srrE&drrE&prr`9#s8MEc!<2rs!r7Xnqfi0[Yl=M!!<2ut!<1XN!<2fo!<2ut"TJH#s8Mio +"9/?#rq??orr<#tqu6cts8W)]rrW3"rr2otrql]qrr)kI~> +j8T\`JU)TgI!U0fH[Bs^H?sd[q0N-^[f6:.oRM2cHN8HmHO+n>G^=UZGC4i9HNA/r[/U7-s8W)M +rrE&`rrrE%rr<#tp\t?ps8W)nrrE&srrE&rrrE&lrrE&rrrE&srr`9#s8Mfn!<1jT!<2Wjs8MEc +s8E'!rpTjerql]qrr2otrq-3lrr;ugrrE&irri?$q20@nHN\_8Z2ah$rs&K&s8N&urqHEmrqZQo +rp9XbrqHF!rr<#ts8W)us8Mrr!<2Qh"9/?#rnRMRrq$/?~> +j8T\`JTuKdH[0sbH?saZH$ORWq0E'][f6:.oRM2cH2r +j8TbbIs-'\H$=OZG^+=RGB\.OG]rt/!H5@ErrVhAG5c^dH2`$oGB7qPG'.nPHM_pfDmctP"9/?# +rn%/Mrp'Lerr;uts8Mcm"9/?#rqQKnrr)isrqucrrq??lrqucrrr)j!rr<#tq#:?nhZ!TTo`+sj +mJm4c!WW/frrE&qrrE&trrE&jrrW3"rpp'hrq$-mrr;eMFSp@dH#9hdrqud#rr<#ts8W)mrrE&o +rrE&brrE&mrsA])s8N&urr<#tr;Qcro)Agks8W)RrrE&is*t~> +j8T2RJU.0?$@7)HI!L'bI!U-eqg/?`[f6:.oRM2bHO+qFH$jsbH@'r:I/A6kEjrIV"oeQ%rr;ug +s8W)nrrE&trrE#`rrE&krs&K&rr;utrqQKnrr2p!rr;uorrE&trr`9#s8Moq#6+Z&rr<#trVlls +rr<#trr3*"s8W)rrrE&PrrE&trrE&rrrE&trrE&trrE&irrE&srrE&trrE&hrrW3"roa:`rr<#t +mf*:dr;QioM0AcC!HPCCrrE&prrE&]rri?$s8N#krrE&rrrE&qs8W)lrrE&trrE&prrE&lrrE&b +rrE&ps8W)prrE&trrE&rs*t~> +j8T2RJU%*=$@-uEH['j^H[0paqg&9_[f6:.oRM2bH3eeCG^Fa^H$X`7Hi&*iEOW@U"oeQ%rr;ug +s8W)nrrE&trrE#`rrE&krs&K&rr;utrqQKnrr2p!rr;uorrE&trr`9#s8Moq#6+Z&rr<#trVlls +rr<#trr3*"s8W)rrrE&PrrE&trrE&rrrE&trrE&trrE&irrE&srrE&trrE&hrrW3"roa:`rr<#t +mf*:dr;QioM0AcB!HG=BrrE&prrE&]rri?$s8N#krrE&rrrE&qs8W)lrrE&trrE&prrE&lrrE&b +rrE&ps8W)prrE&trrE&rs*t~> +j8T2RIs1a7$?pc?H$4FVH$=LWqfi-[[/U(,oR:u^GR/M=G'S=VGBe<1H2DgeDmd"Q"oeQ%rr;ug +s8W)nrrE&trrE#`rrE&krs&K&rr;utrqQKnrr2p!rr;uorrE&trr`9#s8Moq#6+Z&rr<#trVlls +rr<#trr3*"s8W)rrrE&PrrE&trrE&rrrE&trrE&trrE&irrE&srrE&trrE&hrrW3"roa:`rr<#t +mf*:dr;QioLNNErrE&prrE&]rri?$s8N#krrE&rrrE&qs8W)lrrE&trrE&prrE&lrrE&b +rrE&ps8W)prrE&trrE&rs*t~> +j8T8TJU)Tipj3-kH@1'cqg/?`[f6:.oRM2aHO>(HH[C-dH[L0eI/A6kEjrOX!<2ut!<2]l!<2]l +!<2ut!<2He#lal's8N&ts8N#t!<2Wj!ri6!rr30$s8W)urql^*rr<#ts8W)us8N&ts8W)qrrE&q +rr`9#s8MKe!<1[O"oeQ%rr;urrrE&trrE&srrW3"rpKddrpp'hrquctrr;ujrrE&srrE&nrr`9# +s8MQg%fZM.rq_LqH@1'dI!]k;q#:?no`"pjq#:Hqs8W)errW3"rn.5Qrr<#tjo>A[p&>$kqYu'~> +j8T8TJTuKfpj*'iH$aj_qg&9_[f6:.oRM2aH4"qEH?sp`H@'saHi&*iEOWFW!<2ut!<2]l!<2]l +!<2ut!<2He#lal's8N&ts8N#t!<2Wj!ri6!rr30$s8W)urql^*rr<#ts8W)us8N&ts8W)qrrE&q +rr`9#s8MKe!<1[O"oeQ%rr;urrrE&trrE&srrW3"rpKddrpp'hrquctrr;ujrrE&srrE&nrr`9# +s8MQg%fZM.rq_LqH$aj`H[9Y8q#:?no`"pjq#:Hqs8W)errW3"rn.5Qrr<#tjo>A[p&>$kqYu'~> +j8T8TIs-'^pilpeGBnFWqfi-[[/U(,oR:u]GRAY?G^+LXG^4OYH2DgeDmd(S!<2ut!<2]l!<2]l +!<2ut!<2He#lal's8N&ts8N#t!<2Wj!ri6!rr30$s8W)urql^*rr<#ts8W)us8N&ts8W)qrrE&q +rr`9#s8MKe!<1[O"oeQ%rr;urrrE&trrE&srrW3"rpKddrpp'hrquctrr;ujrrE&srrE&nrr`9# +s8MQg%fZM.rq_FmGBnFXH$F50q#:?no`"pjq#:Hqs8W)errW3"rn.5Qrr<#tjo>A[p&>$kqYu'~> +j8T2RJU.*=#(1cFH[C-dq0N-^[f6:.oRM2]HO+qEH[:'cI!^8>HNA/r[/U.*nc'.!s8ViTdCd$" +^=)6Err;uhrrE&trrE&trrE&trrE&krrE&lrri?$rr;uirrE&srrrDjgW.Y>q#:?nrVmH%imYfT +\@T2cd,"*ms8Mio!ri6!pAY3ns8MEc')qq1 +s7b[*a1&Uh\&6YQnbrLeoD\gir;QkWGC"Z8HNA,nr;Qlus8W)trrE&jrsSJXd)*<'\@BH)iV!0L +!<2Qh!<2or!<2ip$2!&q\[f2cdcUE%rrE&srsShsg;^\5][,R3s8M<`%0#bNcb$]t\[]r9mJ?h^ +!<2lqJ,~> +j8T2RJU%$;#((ZCH?sp`q0E'][f6:.oRM2]H3eeBH?jj_H[:&;H3&#p[/U.*nc'.!s8ViTdCd$" +^=)6Err;uhrrE&trrE&trrE&trrE&krrE&lrri?$rr;uirrE&srrrDjgW.Y>q#:?nrVlumimYgE +\-]UZd,"*ms8Mio!ri6!pAY3ns8MEc')qq1 +s7b[*a1&Uh\&6YQnbrLeoD\gir;QkWGBnQ6H3%ulr;Qlus8W)trrE&jrsSJXd)*<'\@BH)iV!0L +!<2Qh!<2or!<2ip$2!&q\[f2cdcUE%rrE&srsShsg;^\5][,R3s8M<`%0#bNcb$]t\[]r9mJ?h^ +!<2lqJ,~> +j8T2RIs1[5#'kH=G^+LXq02pY[/U(,oR:uYGR/McFUHo[CFH-jnA`Rp&>*ms8Mio!ri6!pAY3ns8MEc')qq1 +s7bU&`O31`[DC5In,<:coD\gir;QkUFa&-0GQD]fr;Qlus8W)trrE&jrsSJXcG6lt[^O$!ht-gH +!<2Qh!<2or!<2ors8<8pgW-e4[D1)LqYC-krr)j)rpnd_\[];sht[6NlMh:lnCc's[^W`SbgbtT +rr2utqu;0~> +j8T5SJU)S;HNneCH[:'cHM`$iEOPlH!q_"frHeQkI/A6oI!^3dH[>X;!HPZUrr`9#ou-aFs2#E3 +s8W)ujfjPfH#n"GF*W.tbPh&4"SK^O_o2Mk!Q!skrt"J4_Sa:0_o'@5r;Zcqs8Mus!TUum_Z@R# +r;QutbaX'*Dk-M#'(Wr7L3n2gEH6&>F*Dn^QFZ)UfDcHF]9e"mG]IkEEcQAJI#4lOp\4[hrQ2qU +_["&s_nY",s8MZj$NA\n_ns=._o'7Cp&>Wud&2_IH$+.IEH6/GH[qNtkOecUhn[,._Z[c.GC+Z7 +HO4k``59F0_SX:eo)BEk]:FV$GB7bDEcH8JHA.g%kl1V]pAYKs`koX2_Sj@0^Z#1l"od)GLO+.C +EWpQ1HBGr1q#:m#e"_SAF`DAAGC#(Dh>dKBrt4D*Q@O1(F)l8?Ed)eYNN(A%qYu'~> +j8T5SJTuJ9H3AM>H?jl5H3&#orr3&lJ9_$=!I9%hH3AS@H[:&:H3&#pZi:.,s7O>-_uIRdkPtS] +s5gJ@H?aIME,p2MPfs$srri#5`5BOl_Z@U:o`#Hg_8=+-`5BL0ao)2G^4t2^?GRrrq?@!qo6Lj_ns@0_nY10rrrDPT8%W6rc&*_ +G^>Ldn+cnnq9l!iG][nCEd)hcW87LQmf*m]]9[tkG]IeCE,g&GIZ:>Tq>1,A~> +j8T5SIs-&3GQ`58G^"H/GQD`irr3&lIWk[7!I&hdGQ`;:H$FW4GQD`jZi:.,s7O>-_>h:`kPtS] +s5gJ@G]n%EDK'cEPfs$srri#5`5BOl_Z@U:o`#Hg_8=+-`5BL0ao)2TnR`7Ec,f5DfBfBJX!Y)rn%/^k.?t0G'._BD/X?7FaAhAdeEM9!r^6XrkeuX +`5B@Fs8W)jrsJbX^r+%,_Sa:+g@bIXpX#alH$=:IDJjB4Fa/A%]BAhd!oLf1rkelSJou<^rHJWi +Qc-bY_ns:0q""G!mCSp@G]e"DDJsE6G'AP,^?GRrrq?@!qo6Lj_ns@0_nY10rrrDNSV23.rbhs[ +G'K(^n+cnnq9YdcG&hJ;E-6D[VVV:Omf*m]]9IbeG&VA;DJsW?I#Y,Rq>1,A~> +j8T2RJU$L-!HGUJrrVhCH1$"^I!U-\\?Z&KkB1feFE;PGF)Anrs7`dGEd2nWI!bj="F5*0R-=2B +!pFiKr,`!]CrZ,I"OM./FE@G'!cW\bq#:B.C\r2TDNk)!rs-u7FEMkTF//R2$3'tr[tSgCGBnN5 +HO5(GH?jaXF*se@rr2uthZ!lJX*\o1H$XdarHefrH[0mXG)aN?q>Us(Q>C\cF`_bID3t8%s8M]k +!rS*tr,`!\DTD_U!<2uts8E6&cAcsgG^B:7$$prFH$OORIAuE-rrE&rrs-#JFEDSGFF*n4%"*DK +I<]jTF`__FGjbS2!<2cn#4A[GEHHJPrHes#H[:!`G]e(VWoa9[rVlrus8N#t!qq(_qfE0Y\c;Zj +RW`asH$]F9"akW?EJ)L3rrp`/G&qnSrHnQj"F,!4V +j8T2RJU-R-!H>LHrrVhCGj]k\H[0pX\$>rIkB(]bF)l>CEbr_ps7`dGEHc\SHi/0lF`Nl5o`#!V +G&dG$!ci+so`#!>E,kes!cNVaq#:B.CAW&RDNk)!rs-u7F*)YPEhiI1$3'tr[tSjDGBnK4H3nqE +H?jaXEdOS=rr2uthZ!lJX*\l/G^4R]rH\`pH?a[TFcFE>q>Us(Q>CYaFE;PECmY/$s8M]k!rS*s +r,VpZDTD_U!<2uts8E6&cAcpeGBs+4$$giCG^+=NI&Z<,rrE&rrs-#IF)uACF*[_1%"!;HI!9XP +FE;MBGjbS2!<2cn#4A[GEH?AMrH\Hjrd"iqG][tSWoa9[rVlrus8N#t!qq%]qf<*X\c;ZjRW`as +H$T@7"abN +j8T2PIrt"$!H,:DrrVhAG4'SXH$+:L[B]`GkAkK\EH#o;E,*Als7`^CDf^,IH2VsjF`;;ck4JZT +k]CbAEUs(P\P/UEcH&;C6e_ss8M]k +!rS$or,DdVCrcMS!<2uts8E6&b_pL]Fa*b.$$UW=G'7nFHDfm&rrE&rrs-#GDf9N5EHhA+%!d)B +H?F4FE,T`6G3o5.!<2cn#4AUCDfKrErHJCc&?^_Fa*e/s*"TgE-A#Cq#:?nqYq;oW-E<'Fa81UGBeCXGBe:R +EH@)XrVZ\G~> +kPkbcs8W)kJ9LI.!.+Wi"*f*1[f6:/oRD(0mlHZi:*kH[5R:#^guAaT(IiEI%M0s*P0# +I!U0dH?+f(s8Mcm!pP)Xr-JKkF3+"R"Oq^CI!Yd=!dKFprr2utr;Qf5ErLCmH@($^RK!6_[<6Ti +HNA5aqu7*(s8Uc0E-H\VH[L0frd,'"I!U*cI9HOkLMH[L0eI!^3dI!U!W +TD&*\!l/o(r-JQkK_>BEp\tKts8VG5H$ar +kPkbcs8W)kJ9LI-!."Qg"*]!.[Jp1.oRD%.maT(IiEHqG.s*G*! +H[0sbH?+f(s8Mcm!pP&Vr-AEiF3+"R"4VR@Hi86lGD5klrrE&rrrKoTrd"osH@'e&rr;i&F`dS. +!HY(6rs\o,s4N9KGC+X^H[:&rd"WjII@(6"9/?#rr)j'd"?=^H?jj`H?oF7!I9%kH38G7 +IDu*`!<2rs!r.@kqg&Qg]Dpf?F*W(WHiA +kPkbcs8W)kIWY+'!-eEc"*Jd(Zi9t,oR1h(m +jSo>]on.SXI/eTqF1;/K"S@=mI!tL3"FY`IFh+p[!<2ut!pG#Wqg/Tkcglm4H[:$dq0N9kH[U!p +p%JCel$RgSHNA60p&>-ne9QBk3rHeWoH@(&=HNSYBI!Yd=$%.)DF1VDNs8W)trri?$pOmhjHOY@LEl7!j +G'eO^I!g9grHf'$H[C-dEOu2Mo:BrJI!^8=HO>(GH[L0eH?FVarql]qrr2p%rr9WPGC+Z4HNJSA +I/SBrI!^3cE1Zt+s*t~> +jSo>]on.SXI/eTqF1;/K!q_+kmX,.aI=-+H[Jp7+rr3&`H[,F6#^"D`LiRifH@,C4"+50Kp%JCe +l$I^QH3&-/p&>3pe9H7bHiAGl2jgFJAd7!<2rs!n_sDrH\Wo +H$aj`HiA=!H[:!`H[:'bENfB@i;X#5I!'a^H@,R9!I9%iH3SYAH?jJ#qYL3ni-BVGHN/6mh#IER +p\tBqs35_4r-AlqQN$m`s8N&ts8MMGEI)p.H3AS@H@'r5H3/87ec,UKrr)j']5`.CH$Xg`H@,F5 +"aPE?H%#,UrrrE%c?OJYrd"ZnH$Xi:H38M?H[5U:s*FupF1VDNs8W)trri?$pOd_hH3S_BEPpmi +FoH^eHNAG>rH]!"H?sp`EOu2Mo:BrIH[:&:H4"qDH@'sbH?FVarql]qrr2p%rr9WPGC+W3H3/G> +Hi86pH[:!`E1Zt+s*t~> +jSo>]on.MVHN/"]"+,?9\[DG;rr2p!k]q@KGR/?9nqM+/GBeE-GQW83MY6]C +!pOuSrHJEfG]LmurrrDOG'A1VrceKfK_Y?B%`*+/G^"FXH#o>Ps/Bp[r-/6_T`4rkrr)iuepMN: +GQiA:H$FRZrcefrG^+FXG^=RPXoA=Xrs%#"F*MtTH2MmfGBs+2#'Y?;GA`uJqYpWTGB`t0s*"S! +s8W)mrri?$bB.t+GRnhZrr2rtrr;utrpYhaG^'(1"F56:H$B(/!d&V7rr<#trVm29Dg6MNG^4OY +H2)UfGBe@VHg^\/"oePIG&qs.GQW58G^9:5"*o-:GQ)jeGmAJ3\GcF,s8N#t"TJGqJTh!:#'kH3 +_rZDircnHg!I/ngGRo"CG^4LO])Vg%S8WUsG^943$?p`>H$FUZF*c=7qu6Zqrr33%s132mH$B+0 +!dT$9rHJNlG^+FMSGW +j8T2ZmHa0+"7,=>o`"jkr9`k;s6B^PoX4`!rr[R9!.=cm!d0:hrVllsrr3>; +F*`4\I!U-dI!kg<#CLlGI!^-fmf*4frr;urrrUSlGPujlI!U0eH@#:3"aYE7_#OE4rrrE%s7_1l +r-JQoGG'n<[]I/\KmHiSKiHO"qFH[:!\JFNRHNeeDH[L0fr-JKkEPDGPJ,~> +j8T2ZmHa0+"7,=>o`"jkr9`k;s6B^PoX4`!rr +H[:!bH?6k$rq-3kZ#T\f"+,%!rr)j#rr<#qS9+US#((WAH@'s`qg&HnH?sp\L[tED!<2ut!kWJu +rd+cnH?spbqg&KoH@(!bG^f)[rrW3"rr)iudFo?XdGm/P@H[0s_r-JBf"PrsEE-qS1s*F`kqg&6hrH\NfJFNRHiA +j8T2ZmHa0+"7,=>o`"jkr9`k;s6B^PoX4`!rrfF%/>O" +GBnFXH$F>Bs8MZj!O$G>GQW50])M[."oeQ%qjMO&GQrG;G^+LYGPcUhH$FRZF+s2`rrE&trrTfO +GQ)jjGBe@XH2DgkH$FU[G]nK&rr3'!s8Mus!mu.5rHJKkGBnFWGP-1`G&b7rrr)j#rr<#mJTgs9 +"F5*[M0&W?s*"WlG^4LYG5QUbFp-RqR;R +j8T,Ymf*:dqu6Zqr;QcrRf#(1^Ps8N&trVmGMEdN.ZH[C-dI=$0ZEH?8Jrd,$#H[C-dI<)Ojs8W)srsZM[ +H[C'dH[C-eI!^8 +j8T,Ymf*:dqu6Zqr;QcrRf@F*;hTH2`-iHNSP>EObcC +*qtY;H?jg_H$aj`G][tGEcu_TH?sp`H?sj^Id-n4J,~> +j8T,Ymf*:dqu6Zqr;QcrRfE-6@%GQrA:G'85srr2p%rr<"pEHud-GQN/0 +V"=ThrK;5HH2`$mH$8$Drr;urrt*7jG^+FWG^4LZG][nBE,p.$GRJeAG^4LZDls$=s8Mus%(U;$ +G^"FXG^4OZG^912"aP<:G'r]TrrE&trtFaMF*MkQH$=LXGBe7MDK'Q +kPkP]l2Lb_rVllsrVllsmf*@fs8N#t!<0;(!p=rVqg0-,H$am\Fd02F]sBEc?3hs8W)qrrKQKq0W-c&s93,];ga3G^OjbI!U0eHZt59rr2ut +rr3&oKR*KB!.=cm%X`GHR'aNbrd,*#H[L-dFFKsq]s*TCGl)gkI!KhFs8IN~> +kPkP]l2Lb_rVllsrVllsmf*@fs8N#t!<0;(!p=oTqg''*G^=[YFd02F]snfrrKrVrd"isH?jglIX$-bqg&9bUAb)orr9lUrd#'$H?jg` +G]o(L]Y(A*GB`n0"+,-PqW%SYc#S&UH2`*tH$XU]U:IqAP';+srd"`pH?jgW\GQ:0rlK8.H[5U: +!dBS!o`#WmIX$0bH[:$_LA(ZHs8W)us87q#rd"uuH?sp_F-!Q=]:jh!rH\ZpH?sp_K(Js@"TJH$ +[qP_[!ciR5qg&ZtGB.\DEH,o?mJm4cqu6]*EVXq\FqTq;]Xt2#Fa&1YH@'paH?sahoD\airr2p! +pOd_gH2rG'eL]r-AKhMYdAPqYpT? +F8gIpH$Xg_H?=V1]"P>0GB`q1"abK8])Vb[~> +kPkP]l2Lb_rVllsrVllsmf*@fs8N#t!<0;(!p=iPqfip&G'J7QF-]bbs)\m9W4KOOEG^CGQiA9EOu2LJ,~> +jSo;\s8MKe!ri6!i;WfVZ2XmhI!PL6%sH[>["+59WjSf)fr6g:BH[C-eH[L3`RJm$_"6Y/[HN&6n +H$Xo)p&>Bue96.aI!U-eFJAd7s8N#t!o8*HrHnQl"*o70q#::&rpQS'I!^3fH[C'bGLZKh#h>iS +Xfeb,JU76@"+5 +jSo;\s8MKe!ri6!i;WfVZ2XmhH[,=3%s3fYqZ$Qprqt&mG'eO]HiAG^945"abQ?GAa&Prs8W(qiQ&JH$al:HN\JJd/*b@rr`)B +LiiWB#'bKAH?aYjjo5Pas.aX^H@,X;"+,0UjSf)fr6g:BH?spaH@(!\RJm$_$Klk`H$Xd`H$Of' +p&>Bue96.`H[0paF.rU5s8N#t!o8*GrHeKj"*f1/q#::&rpQS'H[:!bH?sj^G1?Bg#h>iSXfeb, +J9h'="+,6RY5YR'X9,Qurr)j$rr<#lLj+.AH38;PfDPUI"norhFa8?5H3AM?H?@C0rs&K&s7_.j +HiA]CYt##Q2r*FaA=ZHiA +jSo;\s8MKe!ri6!i;WfVZ2XmhH$8t-%s!TSqZ$QprqsuiFEr+UH2`$iFc-%jrsJ"9G^4OXG]n:O +aS#Q8rmZ+8r-/9cK_Y?B!Pi[PGQW58G'Ek/"aP?9F_mWJrs8W(qi>iDGBnH4Gm&2DcMIP>rr`)@ +L3!9<#'P9;G]n5bjo5Pas.OFXG^9:5"*nsQjSf)fr6g4>G^+LYG^4RTQi6g]$KZYZGBe@XGB\B! +p&>Bue9#qZH$=LYEM*71s8N#t!o8$CrHS?f"*St)q#::&rpQM#H$FRZG^+FVFOL$c#h>cOXfeb* +IWt^7$[HlTXK/J*WiE/orr)j$rr<#jL37_;GQW#JfDPUI"n]`bF*Dp/GQ`59G]Lt*rs&K&s7_(f +H2`$gH2VsiEgP\]rVm&oaG+YYH2;dcGlr58\b#b!#Q2r*F*MnRH2`$iGBr6FrrrE%T5f.!rceiq +H#o;2s8W)ur6Th6rHJNjG^4=ts8RT~> +j8T2W^:NjH#J.OX]=PS]gA_*SqS0VQn%/_8]=YN,\,QI-r;Qi^I!P[;!.=cm"a,jqs8W)trri?$ +hLBkNHNeeDH['krq#:E[I!Y^;!d\q/o`#'EH$Xg`rd+]kLA:QD'u=sMnG3(cmYl;eHN\YAHZQRTrrVnKGPujkI!^*nn,<7krr<#bL3@rjrHeTk +K_50A$N635I!^3dH[9k[o`"s#E;k1_HNA6.q>UN1Ed[b2!HbmLrr`8sRlHNnkEH[(8; +s*t~> +j8T2W^:NjH#J.OX]=PS]gA_*SqS0VQn%/_8]=YN,\,QI-r;Qi^H[,L8!.4]k"a#dps8W)trri?$ +hLBhMH3JYAH?abqq#:E[H[5O8!dSk.o`#!CG^945!dBCoq#:B2Er:4nH$Xa^H@'saH#n(YL5s(I +rrh/%H$Oc8H3/2KnG3(cmYl8aH3&&mjSo;TL3NTB"FGH=L@>*@#QFc'm"T\1H2W$jG_G_drr`4` +G'j47"+,<9c1M#=[W$P +rrE&trrUPiH2MsjHZYYJr;R'%s8V26G^Fa`rH\NdUAk&i!r%=lq0EKmReQj^rr;utrr;2CGPQOe +H['haq#:`bJTuKfH$ag`H?@1&rrVkHGPlakHZt87s8W)srrLVnrH\ZpH?sdhp&BO~> +j8T2W^:NjH#J.OX]=PS]gA_*TqS0VO\a[36]Xteagpd:`rquctk]q@MGQ<$gGQi,Hnc/Xgrr3-# +s5&0JrceTlG^+CVi;!UN/E-_>*!HP[Hrr`8qQZDqI!H>^JrrE&qrrIsuqfi-\ +Z2=P$rVZZqrr2p!c?"4-GQW53QM(1U#lal&j+;H"G^974!can4qu6`lJTgj6% +j8T2PH#W(i!GA_;rrqt=DfTl>q/QLUF80bVBsY)E!pG#WqKi9iF3s[]!NU8;HNA?9rr2utr;Qi_ +I!Y^;!d\t0o`#'DH$Xg`rd+]jLA:QD!PidOHiA"qu7)4F*r:\H@(!aJ+EX=r;Qf#FT$OhI!]qArq??p +rge+XHN&6mH@+`Prt#,/s8N&(EI<(ZI!U-cHg:G,!Rl2jHN8BkHNA2ro`#!gMK\lD!HG@6rrfiQ +H[L5?HNJM:0npOmhjHNe_BH[0qsp\tZPGC"U`H@1'cH[Bh3pAY<. +F*i:^HN&6lEk2/K!<2ut$LN4dH[:$cH@'\8q#:A[G5HUgH%5JdJ,~> +j8T2PH#N"g!GA_;rrqt=DfKc;q/HFSEqjVTBX=uD!pFuUq0E'_d.dP@X)e&_!Hu`errE&rrrVG3 +H2MsiH$%."rrU\pH2MsiGD>nfrrKoUpj2pb#BbWkc04s$rqucu`,g9NrH\TlFO1!dqu6cts3#K] +H38M?Fdr=/!<29`"7U_`Hi/0mEif<@rql^(ZZ:Db/:H@'p`H$eiPrrLSjrd"Qird"Tb[e0S$q20@mH3%uhnc&a$EdE(Z +rH\KhhYI0Rrr9]RqK`3eMY[/L!r%=lqKi0d!93bQ#1[pCH@'sbrH\KcVtU,n]5r:FHi86kEk2/K +!<2ut!ptA[rH\QkH?-1`rrJC-qg&?hIJ!Pi~> +j8T2PGAZYa!G/M7rrqt;D/X?3q/6:OE;4>PB!JW@!pFoQq02p[d.dP@X)Ro[!HcNarrE&rrrVG1 +GPl[eGB1dsrrU\nGPl[eFbKPbrrKoSpim-gGB\+YTZu]qrVl`p"2]&'GPuahGB2%0rql]trr:/] +r-/UKEErL:`GQ)gfEjkW?!r7Xoqfi-ZY4;Mp[;^A9 +H2VsgG2E&p"9/>7EVan]FboehrrVqGG5?FbG'W*Ars%"rGBeCXH2VsgEM`C/"M8YuH$T@5!H>OH +rrE&trrVS6G5ZXfGBe).q#:A[F8L1aG(0)`J,~> +j8T2SJ9gm9!.+Wk!.=Zj!dnsrrr3)nJ9ZJ.HNA,qZ2XmhI!PR8!d0k.p\tBTH?sparHeQd\bQ1+ +l$RgTHNJM8aRoK8e9Q@eHN&6mGD>nfrrp2ZH[L0fqg/EiHarS>rrW(dG5HUfFdN+&rr`8uP'6_L +!dTIkkl1ebs8Uo$r-J]qI!*X4rr<#trVm#YH[1!crd"WnIcpY/s8E&?Fo6RhH?GbXrqHEpon@X: +rd+isGDuCus8Mrr+J +j8T2SJ9^g7!."Qi!.4Th!demqrr3)nJ9ZG-H3%uoZ2XmhH[,C5!d0k.p\tBTH?jg^rH\Kb\G6(* +l$I^RH3/A6aRoK6e9H9:H3/;Fq"Xjm^iFaJH@,O8"*]($nFuqaqjDU(H3/2SrqQKqrqqq%qg&;L(H$a\Ws8N&urr)j!i-T]qrd"ZlH[Y)Ts8W'!`cV-)"F5*Zs8Mcm"8.@mH2`*o +HZk>Ds8W)rrudtVH$Xd^H[0dsqu?]qs8N&ts8%e#H$Xa^H[9_9rr;ulrrW"RG5HRdE3Ss6s8E%f +FSpFdHZPtYrrE&trsSLTFaJF\H$O^\I-CJ-!r%=lr-AHjHZYnRrrW(^G5cdfH2`*kH$\HCrrhP6 +GC+]9H3/A5V>gJprr)itgj/aB#Be5is8N&urr2p*_K1$NH?jg`H%5)YJ,~> +j8T2SIWkI1!-eEe!."Hd!dS[krr3)nIWg#'GQD]iZ2XmhH$9%/!csY*p\tBTG^"CVrHJ?^[eTk( +l$7LNGQN)0aRoK6e96'6GQN#@q"Xjm^i4ODG^912"*JjsnFuqaqj2C$GQMoMrqQKqrqqk!qfi0c +Jb81+"9/?#h>;F&GBn8Os8N&urr)j!i-BKkrceNhH$e`Ps8W'!a)_*&"F"mTs8Mcm"8.:iGQ)gk +GBA]#BS#es8N&urr2p*_JsgHG^"CXGCA`UJ,~> +j8T2RJU.$;!.=Th"akZDHuZRnrrr%FG^Fdbq0N*hrHeNlr-JHb\$>r7k^7[QHNe_;bPqP@rr2ut +rVm6'OEZ"tH[:'eF/Sg5!pP)Yr-JKkFNF+S"Oq^CH[>[UHo +rr3&fIX:s>"akZ>b5_J;rri?$s1rd+cqH[9tprr2utr;R-!Km7rj +I!U-cH.`&p"TJGaIX:p="*oRkrqHF$gN\$lI!U-dFK,<>rqud)rg@tXH?spbHuu1arqZQs]lSRI +I/\HnFe87*!r7^sqg/?`Yk%etpPF-AH[Pg>!d*#mr;Qcrr;Qf"FT$OhH@'s^e,0.HpOmhhHNSS; +ec,:B$Ft5(I!L*dH@'h$p&>L"P'D;"H@1'eEhi[7rr2p%rr:JmH@'u;HNSS>iVriV#6+Z&rr:`! +qg8?h!SRL'~> +j8T2RJU$s9!.4Nf"abQAHZ?Imrrr%FG^=[_q0E$frH\Hjr-AB`\$>r7k^.ROH3JS9bPqP@rr2ut +rVm6'OEPnqH?jjaEi/X3!pP&Wr-AEiFNF+S!n;I?r-AEgLA:QD!PiaSH3\_AH[:!]K\Q>&!<2ut +!q(J^rH\WoH?@=0rqcWtrr<#1F8C1eFO0sdrr;u`rr`8NG^9:7"FGH?H/JW$!<2or$M]="H?jj` +H?jbfr;Qp!s6"fUr-AHiK_,3;rs[Y,H$am`H?sY3s8N#qrs\mpG'eO\H?spZV#UGirrfuTH[0u; +H3&,Zo`#!gMK\lC!H>:6rrr.QGC"R^rd"Wff)GUI!<2or!N^AAH3JYAH?j\_qu6`lK6[9>"*o%> +rq??q\T2tBH$fO:!Hj_$rsepiGBnL\H[:$ZU]:Anrr3-#s3c+:r-JBg!TF%Wrs&K&s8N&QH2Dpf +GlcUuJ,~> +j8T2RIs1U3!."Bb"aP?;H#L%grrr%DG'J7Wq02mbrHJ>rr2ut +rVm6'Nc]JiG^"FYE2<:/!pOuSr-/9eEldnQ!n;C;r-/9cK_Y?B!Pi[QGR&G;H$FRUK%]u"!<2ut +!q(DZrHJKkG]Ln*rqcWtrr<#/EVanaEmOabrr;u`rr`8NG'Eq1"F569GMW8u!<2or$M]6sG^"FX +G^">`r;Qp!s6"`Qr-/ +j8T2RJpI0=!.=`l!.=Zj"+#<6[f6:.oRM2YHN\_CH[L5>HNA/rZ2XmhI!PU9!d]IhqYpQprVlo& +FT$OhI!Tt.rqZQql$RgTHNJM8aRoK8e9Q@eHN&6mGD>nfrrKoVqKiUg$RWWt'H[C'bFJJa5!<2ut$,CS-I!^3fHZYkWrrE&prrW"R +G5HUeENo$6"71M`HMr0lH%>8Ws8W)ursI"oH[C'bH[C'`e,0.HpOmhhHNJJEoC`+cb]S8Yrd+`n +HZQOdrsSh!FaJI]H@1'aNVWPQ%K?D-e9H=eH?spbH@"KHs8W'$s8Lf"HMi-iH3)^uJ,~> +j8T2RJp@*;!.4Zj!.4Th"*o34[f6:.oRM2YH3AS@H@(#;H3&#pZ2XmhH[,F6!dTCgqYpQprVlo& +F8^CfH[0b*rqZQql$I^RH3/A6aRoK6e9H9:H3/;Fq"Xji^iK9t"+,<:eboFIrqucurr:f"qg&:6rr_V:H$T@7!dK7^q>^Kos8N5HFaA@Zrd"WkGLQHh!r%=lqg& +rrW1mFT-RiH$aj^NVWPQ"TJH$dWb\:"aPE?H$\BGs8W'$s8Lf!H2N!gGlcUtJ,~> +j8T2RJ9La5!."Nf!."Hd"*]!.[/U(,oR:uUGQ`;:G^4T5GQD`jZ2XmhH$9(0!dB1cqYpQprVlo$ +EW(+bH$=>"rqZQql$7LNGQN)0aRoK6e96'6GQN#@q"Xji^i9-p"*o*4e,94Grqucurr:euqfi0d +HJnPt"TJGTH$B74#'kH*mSoXgT"a>6:G)Q1prri?$s3l,iGQi;9G^"Dir;Zfr"TSJVGB`t0s*"LqrdX~> +j8T2RJU-R.!HGRIrrVhCGl2mgI/SBlI/\HmHMVshEjr=R!pG#Wqg/KiQi6sarV6Bn]Q3ps"FYKO +q>U6j!pP)Yr-JKkFNF+S"Oq^CH[>[I-LY1!<2rs$iQK:H[:!bH[L!sqtg=#rr9ZNH?jgaH?s\'rVllsq>UNlMK\lD!HG@7 +rrUl!HN&6qI!^*nqZ$Qmrs8W(s8N&YH[:) +j8T2RJU$L,!HGRIrrVhCGl2jfHi86jHiAU6j!pP&Wr-AEiFNF+S!n;I?r-AEgLA:QD!PiaSH2rarqHEr +n:,\.H@,X;!HYpQrrE&drsA])rr<#KG^4U^rH\Kca8#Z9pkO$Z#P&9H@'p`G)H.rs8N#t$i\OuH$Xd`H?jjZaS>cCgNRmgH$FU[GB_^>J,~> +j8T2RIs1.&!H5@ErrVhAG5QRbH2VsfH2`$gGPZObDmckM!pFoQqfi9cQi6sarV6Bn\o7Lk"F>0F +q>U6j!pOuSr-/9eEldnQ!n;C;r-/9cK_Y?B!Pi[QGQ<$gGQMlcrq-4!a`DZOG^+LXG(/u]rqHEr +mX98&G^9:5!HGdOrrE&drsA])rr<#KG'A1VrHJ?_`VBH7pk*YcG62r1ebT4GX`4/^!cl*Up\t8d +E;Xq^G'`EPrrE&srsSdlF*MqRG^+LTN;NJO$i^1;D0L/IH$=IPRf36drqZQqq1s.iGQD]bo)AdE +G'Eq1#'kH9L%t]Ir;R'%s8W)uiHTQlrHJBhEl@qV"TJGqJTh!:s*4ZdQMpLV$K-/QG^"CXH$FDN +p&>O$YA\W1G^4LXFGTens8N#t$i\RtGBe@XG^"FRaS>cCgN@[aGBS1SF`l:8J,~> +j8T2RJU.$;"FPNBI!YU8!HGRIrrVhCGkHCcI!^3fqg/?a\$>r9k^7]'I/SBnEif9;rrE&srr`88 +F+!q5"+#0Hq"apkl$RgTHNJM8aRoK8e9Q@eHN&6mGD>nfrrg,YH[C/>HNSY?K(&U:!<2ut"oeQ% +rkELPHN\_CG_c"lrrE#nrrW([GPujjI!]n0rVllsn,ECerVlrZH@#R;#(1cEFIrO3qYq$"LO+>r +I!pBhH.W&qrqud&cus\]I!^3fF/AX2"87FnHMr0oG*Dk(s8Moq"/L'eHMi*jGhi2r"TJH$_/oU( +$%./LGG+s8rr;unrrW"RG5HUeENo$6"3u.:I/SBoG*Dh&r;Qcrr;QimKmEQB"*1mNrr)iupOmhi +HNJM9T_/6lj*Q*"H$amaH?n$>p&>/uEdN+Yrd+`kMu*GOrseu-id5uuH?sscHZYq[q>UQOI=-G@ +IK+Zqg&?L~> +j8T2RJU$s9"FGE?H[5F5!HGRIrrVhCGkH@bH[:!bqg&9_\$>r9k^.T$Hi86lENK0:rrE&srr`88 +EdRb2"*o'Eq"apkl$I^RH3/A6aRoK6e9H9:H3/;Fq"Xjl^iFaIHiAPPkI\rql]sUi^t\H3&9Gqu6fus8TlTrd5$! +I!g+1rr;utrqZQqq20@mH3%uho)Ag;GBeK5H38;Rqu6Nn!<2or!r%Cnqg&?a\,ZI+rrVqIGl2jh +H$#_OrrhA.H$ai9H38G;eGf.@"0Z]jH2W$kGDl=srVm?+s583KH?sj`H?s\+rqZQrgO+?prI"Wl +!SRI&~> +j8T2RIs1U3"F539H$B(/!H5@ErrVhAG4g(^H$FRZqfi-[[B]`7k]qAsH2VshDlis8rrE&srr`86 +E-_D,"*\j?q"apkl$7LNGQN)0aRoK6e96'6GQN#@q"Xjl^i4OCH2`$jH$+W*qu6Zqrr30$s8W)5 +DuFn`H$FIepAY'lrV?Hpq2TRqGQW59Dl!@3!<2He!<2rs!onNLrceWmG^+8!s8Mlp%JYX$H$Xa^ +H$OVcrr;uqrs@%oG'J:WG^4;(p\t?hK6;D;GQrG8Oo57Zrql]sU2kPVGQE!Cqu6fus8TfPrd"lr +H?s\)rr;utrqZQqq1s.iGQD]bo)Ag;F`r'/GQW#Lqu6Nn!<2or!r%=jqfi3][K$7)rrVqGG5QRd +GB0;Irrh;*GBnE3GQW/5df/q>"0HKdGPuagFc#torVm?+s5A3HG^+FXG^+8#rqZQrgNn-jrHeKh +!S@=$~> +j8T2RJU.$;$$prEH[L0dH[L5?HNA,prr3&lJ9^p;$@I/HH$XdaI!U-erHeQc\$>r7k^7[QHNnN! +s8N&urr2otrr)j(d +j8T2RJU$s9$$giBH@'s`H@(#r7k^.ROH3SAt +s8N&urr2otrr)j(dqhrrVG3H2MsiH$%."rrU\pH2MsiGD>nfrrKoUqg&skkXHDqYu'~> +j8T2RIs1U3$$UWskkaNFkPG4/~> +j8T2RJU.'<#'b9>I!'a_qKi6_[f6:.oRM2aHO5"GHZsX^I!'[]rHeZpH[BeBZ2XmhI!PX:"+544 +rql]qrr2p"rr:Jnqg/BhL\U]F!pP)Yr-JKkFNF+S"Oq^CH[>[H3/;@h"C[Krr;uprrE&s +rrW1hFSpIeH$niNrrKiTr-JKkGhN&q!<2or"4_XAHN&6tH@1$[X8`+us8Mfn!<2ip!<2fo!r7^s +qg/?`Yk%es[W6_@I/\HnFee^2#6+Z&pkX;"*o*@hY7$Mrql]rrr7K~> +j8T2RJU%!:#'Y0;HZXO[qK`0^[f6:.oRM2aH3nkDH?OFZHZXIYrH\TnH?sS?Z2XmhH[,I7"+,+2 +rql]qrr2p"rr:Jmqg&-kP'2-MH38G>Ei/"!s8ECpFF&:[H?jd^GC\KArrW3"rql]qrr)iu +rgS$-H3/A>kkP/Y]lO!r!I3;rrrE&rrrU_pGl;ppH$ajYX8`+us8Mfn!ri6!r;Qcrq>UNlMK\lC +!H>:6rrfcMH?jl:H3&,_p\tHss8VkJGC0=8"+,?6\GQ:-pOd_fH3/*#rq69nj*GutrH\WlIII48 +rqHEpY]+o6rd"ZlGDl=orrW.eFS^:bGC\QErrE&rs8W&us*t~> +j8T2RIs1X4#'Fs5H#e+SqKN$Z[/U(,oR:u]GR8S>G]\"RH#e%QrHJHjG^+/7Z2XmhH$9+1"*nn. +rql]qrr2p"rr:Diqfi0bK_YBC!pOuSr-/9eEldnQ!n;C;r-/9cK_Y?B!Pi[OGQN/1`;KW:rr;ur +rseu-rhja[H$=LXH#o8Lp&>-iOE>^GGQW/8E2Mdts8ECnEd2kSG^"@VFb&9?rrW3"rql]qrr)iu +rg@g)GQN)8k4nrY]5W"G]B_^rr<#tq#:?nqYpQpq>UNlLiiN= +!H,(2rrfcKG^"H4GQDiYp\t^%s8VkHFa&"RG^4OP[ep(+pORMbGQMfrrq69niHTQlrHJKhHgh"6 +rqHEpY&8K.rceNhFc#tkrrW.cEr:.bG'.qVh"UgKrql]rrr7K~> +kl1Y^rVlrmJpI9@$%.&@Mn/-4Y^^lpHNSS@EOPlH!q_"fqg/ZrG*L/:iidiUH[PanfrsHP_H[L0d +I!^0chX^[IVK;``"akZDG*W%!rrW+\GPc^fEi/X3#5nN#rr<#trr33%s8W)us8N#t%)?n1I!^3d +H$Xd[K%Tes!<2Ti!k*,qr-JHfbPM8=rW8a8I/SBnG_>\ars&JrKm7rkI/JUN0EdI_3#'tWCI!:4qrr2utr;Qits8MoqJ,~> +kl1Y^rVlrmJU%*=$%$u?Mn/-4Y^^ioH38G=EOPlH!q_"fqK`HkPfiCQYCC_AHi/0jEOYlG"9/?# +rjr+2k^.ROH3&-/o`#!AGBs+4!dBCoq>UN\H[5O8!dSn/o`#!BG^945!dBCoq#:]:EdE(YH@'s` +HJ\5m!N'o:H3JYAH?GMOp&>*kO`pVJ!HG"/rrE&prrE&trrE&trr^&WH@,X;"aPE?Fb/3=rrE&i +rrTWLH2MshFj'X]s8E(lFF3t4!dB:iq#:Qtp4RX9H@,R9!ck:5jSo;WMK\lC!H>:6rrKQJqg&9b +U\+Qipk($l]lJDtH3SY@ +H@'gef`(mNrquctrr;ups*t~> +kl1Y^rVlrmIs1a7$$gc9Mn/-4Y^LWkGQW/7Dm]ND!q^qbqKNUN\H$B12!dA\+o`#!BG'Ek/!d01kq#:]:E-QYQG^4OX +Gi&#k!Mj]6GQiA;G]T/Kp&>*iO*(8D!H4e1rrE#rrr`6"s8D`m!<2ut"2Jr#H2`$lGBe@PJ(F>n +!<2Ti!k*&jr-/6`bPM8=rW8X2H2VshFb05\rs&JrJou6]H2MmgE2WT@!o\BJr-/9dHgLD)!Np>;GQN#Ep\Fgt]5Vt; +G^+FWG^4C]f)G[Lrquctrr;ups*t~> +j8T2QJpI[U:!dT4^o`"rrEVk(aG`2Cn +rseIKG^=^`I!U0eHZsbMrr2utrr2utrr2utr;V9~> +j8T2QJU%->$[[2BV"F]ds8Ul*GPc[eEOPlH$hSsoH?sp`H@'b1qu-Nsfn"Eor-AB`\,H=.rr;uc +rrE&BrrVD2Gl)dfFNF+S!n2@=r-AEgLA:TE!pP&Wr-AEiFNF+S!n;I?r-AEgLA:QD"Mf&(H@,X; +!dT=go)A`fEr1.dFdE"*s8Mfn!rS4)qg&9_VYU5orr;utrVlfr%K?D-rr;uts8N&eJp2S>me$M[Y]0Jc!dBRu +q>UonJTlBcH@'paH?sa[^]+65rr2otrr2otrqueH~> +j8T2QIs1d8$[Hu)qu-Nsf7/!gr-/6\[Jg+,rr;uc +rrE&BrrVD0G5HLbEldnQ!n2:9r-/9cK_YBC!pOuSr-/9eEldnQ!n;C;r-/9cK_Y?B"Meu$G^9:5 +!dB+co)A`dE;Ok`F-ce(s8Mfn!rS.%qfi-[V"jrmqu6Wqr;Q^,rVQWpqu?]qs8W)umt,\-qKN-b +G.[bQli.%cg33F>"*o*1Y5A5%rr;YDFo6IbE1lq)%fWkRG^4LYG^4OXG]/l/rVllslMgq]LiiN= +!H,(2rrKKFqfi-]U%J?lpk*^7G^+LYG]1%frrVqGG5HLbDn>T@!o\BJr-/9dHgLD)!Np>;GQN#E +p\Fgun:,S'G^+LXH$FRUGJ4"U!<2ut!<2ut!<2orJ,~> +!WW/trrE&errE&srrVkEH2W'mH?b/8rqucta)lY*HNA,prr3&lJ9_!=!dBFlqu6`nfrsHP_H[L-cH[C$lp@A4aVK;W]!d9k-rr2utrVm*$s8N&rOa$\L!HP(2rs/Q'r;Q]qrr2os +!<2lq"9-,YHN&9kHN&6qH$#eOs8W)crri"KG^Fi;HNJDUrVHNoh#;X"HNSYAG0U$d!ri6!qu7/s +M0F8nH[C'cI!^0[K$aMs#6+Z&rr<#tnG`RcMK\lD!HG@7rrKQKqg/?bU\+QnpkF$>I!^0dHZHXn +rrVqJH2DphEkM&E!onWRr-JKjII?b-!O-S@HNJGMq>1+'rr9`SH[L0eH?spcH[0\.oD\@]J,~> +!WW/trrE&errE&srrVkDGl;pkH$=u6rqucta)lV)H3&#orr3&lJ9_!>me$M[Y]0Jc!dBRuqYq0,s1`T#H[:!`H$Xg`H#oeQrq$/?~> +!WW/trrE&errE&srrVkBG5ZXgGBJQ0rquct`H$2#GQD`irr3&lIWkX6!d'.gqu6`9Ed@S-!H5CE +s8W)trrE&frr`9#s8LCF!pFoQqfi-^aRoK6drfm4GQN#@q"apkl$7LNGQN)0aRoK6e96'6GQN#@ +q"Xjl^i4ODGQ)ggG(]MZrrJp7qfi0`Q2U^^!<2rs#6+Z%s87q"qfi-[V"FZhqu?]pp&>-n_/X\u +GlN!eGQr>2T^r-_rpB^gon.C3H2`$iFHZV!rrCjRGQ2miH$=>Srr3'!s8Moq%e>BsGBnFXGBeCX +G]82Yrr33%s8W)us8MNf!r7Xoqfi-ZY4DSnZu>hd!H=b)rsJOSFa&+UGBe@N[ep(+pORMbGQD`o +o`#!OG^'(1!d8qWo`"rpDYnY[Fc#khrt581]l84AG^+FVG^4OXEME((oDa=~> +!ri6!k5Pb]JpD]iI!U0]Z2O\+rr<#jKR!EA!HGRIrsA=JG^FdbH[Bh>qYpWfKR*KB!HP[4rrW3" +rm(NFk^7[QHNA91o`#!AG^B:7!dKLqq>UN\I!Y^;!d\t0o`#'DH$Xg`rd+]jLA:QD$G^_0H[L0f +HZkeUo)A`fF8L:dG*`1-qu6Zqr;Qe\Gl)ggEi/X3!;lWm"TJH$rVcQl!r]QLpj3*hF,JZLrr`9# +s8MTh!Mac9HN\YAG_5Mbrri?$s1WRPHNJGOq=jmnrr<#OG^"K1HN\_?G-L];rrE&errW"RG5HUe +ENo$6!Od%GHNJ8arq69mqh07oHN\_CHZHXnrrVqJH2DphEkM&E!onWRr-JKjII?b-!O-S@HNJGM +q=sspr1A"VI!^3fr-JNeMq\1,rrE&rs*t~> +!ri6!k5Pb]JTuKeH[0sYZ2O\+rr<#jKQm??!HGRIrsA=JG^=[_H?sV;qYpWdK6[UN\H[5O8!dSn/o`#!BG^945!dBCoq#:H3EdE'2HNSS: +R/Z[V!N'o7H38;Us8Moq!<2or!Kq[(H3&#_j8T2Z[<)4k#((ZBH#eeqrVm!!s8W)hrrJm9rd"]m +H?Xu3rVm$"s8TfRr-AEgN;<5J"oeQ%fm%`:H3AS +!ri6!k5Pb]Is-']H$=IOYPnJ)rr<#jJp%!9!H5@ErsA=HG'J7WG^+23qYpWeJTgs9!H5CBrrE#d +rrW3"rm(NFk]q@KGQDj+o`#!AFa*b.!d01kq>UN\H$B12!dA\+o`#!BG'Ek/!d01kq#:H3E-QX, +Glr;4QN$IT!Mj]3GQW#Qs8Moq!<2or!K_I$GQD`Yq>UKorr)lsrVccrrqZQqrNgM@GQrG-fF#Q1-2G^4OYH2MmhE/E6HqYpQpr;V9~> +#l:KlTqS-QTV1hK#G&=%s8VeDH2`-nH@'bQrr)j"rr;q\Gl2mhEOPlH!q_"frHeTlG/X7W!re@+ +r-JHb\,QC1p8+CUT^JKVTUX7+rmC`Ik^7[QHNA91o`#!AG^B:7!dKLqq>UN\I!Y^;!d\t0o`#'D +H$Xg`rd+]jLA:QD!PidUHiJBoHZkhVo)A`fF8L:dGEV=]q!J:Pmd-!Zqg/?bVYU6#rr)clrVZZm +qu-Hkrr2otrql^,rigHjH[L0eH@($dI!9eDp&+girpp'q`-$EQI!^3dG1HKi!res:rd+fpHZZ7e +rr2otrr2otrqud$bBnDZH[:'erd4Zk!cjC_qYpQpnc&[dMK\lD!HG@7rrKQKr-JWoFJ%sgmd9f; +"R(MaH[>X;!HP^IrrVqJH2DphEkM&E!onWRr-JKjII?b-!O-S@HNJGMq>L=!rr<#ts8VYUEW(4a +I/SBpI!0bFqtg +#l:KlTqS-QTV1hK#G&=%s8VeCGlE!lH$XPNrr)j"rr;q\GPlafEOPlH!q_"frH\NjFi=.V!rS1' +r-AB`\,QC1p8+@ST^JKVTUX7+rmC`Ik^.ROH3&-/o`#!AGBs+4!dBCoq>UN\H[5O8!dSn/o`#!B +G^945!dBCoq#:B1ErC:eH$XV$rpp'iVK2Q["*Tjon+c;RmI'>%GPc[eEi/[4&H2G!p\FUXq"ORX +rVulrs8Moq"ob`HH?sr:H3S_BHZjVBp&+girpp'q`,p:6rrKQJr-AQmFJ%sgmd9f;"R(M` +H?oI8!HGXHrrVqIGl)dfEP1rD!onTPr-AEhII?b-!O-P?H3/;Kq>L=!rr<#ts8VYUE;b(_Hi86n +HZaSDqtg +#l:EhT:_^ISt>JE#G&=%s8VeAG5c^hGBRuDrr)j"rr;qZFo6IbDm]ND!q^qbrHJBfF2IeR!r\1$ +r-/6\[Jp1/p7n.MT'i3RSsdh%rmC`Ik]q@KGQDj+o`#!AFa*b.!d01kq>UN\H$B12!dA\+o`#!B +G'Ek/!d01kq#:B1E;b"aGBe1qrpp'iUi?3U"a#jkn*]W?lic_BlA]r`GQDcZq>Uj"nF>l7n+6#9 +o^VVQrrE&qrrrD)E-QVQrHJNlG^4CR\+T\!!<2Qh$,U_-GBnFXGBD=2rrW1nEW11dGBe,)s8N#t +!<2ut!<2or#KqC7G^+FXH2`'gG62`Dj8/cUrpg!iq1s.iGQD]bo)A`tDu=haGB08?m-a37licI& +G'J60GQD`kqu6`lJTgp8!H5RArrV/(GPl[eG'iTJrrK9?qfi0bM>-uK#lal(rr<#fP]$GE!."Nf +"F5'3\bl7'!<2rsJ,~> +!r%.arcJ3amr\kPPPtO]oRhGgHNSYBF/]';"oeQ%msfZ]HNA,prr3&lJ9_'?#(1`=X8i5!rr3*" +msfW\HNA/rrr3&jHZSOr!d&4dci4(1I!PU9!HlKUrrUYoHMi*kG_c(irrVG4HMi*kH?@7#rrghs +H@'u;HNJDGq"Xjr^iOjKI!L*dG+&@#rrK!!.Ooq#_%/LIXQZpI!Y[:!HP(5rseVD +cH=ARcHFJYali^'r;Qcrrr<#t"Kl]iH@5X;$%.&GF,\iQrr;ufrrV8.HMr0lHucgqrs\a^GC"U_ +H@0k]s8W)prs8T's8N&uhLfnGHO,"GHZXeXs8W)crrW"RG5HUeENo$6!Od%EHiAHnIe\?jHNnkD +H[:$Z\GQ:-pOmhhHNA0"o`#!QH[>U:!dT4^o`"rrEVk(aG`2CmrsA])o;-JQI!g9grd,$#H[0\' +mJm4cs8W)rs*t~> +!r%+_rcA-_mrSeOPPtO]oR_>eH38M?EiAs:"oeQ%msfW\H3&#orr3&lJ9_'>#((W:X8i5!rr3*" +m='UiYP*D2s +PE_>sPDmT^rr)isrr2rtrWKBCH$Oc7H3nqDH?5&!s8N&tnc&[OH?oI8!depuqu7*$MfsAlH?jjZ +cN!qDqYpj"s8W)us5&BLqK`EoH?s[``rH):6rrKQJqK`-grd=cqpO*?pH?sp` +H?jgV\GQ:-pOd_fH3&#uo`#!QH?oF7!dK.]o`"rrE;Oq_GDl:lrsA])o;-JQH[C'crd"s!H?aM% +mJm4cs8W)rs*t~> +!r%%[rc/![mrAYKOo>=[oRM,aGQW59E2NU6"oeQ%msTEXGQD`irr3&lIWk^8#'kE4WW3"trr3*" +mX03UGQD`jrr3&jG];th!GSperrVD0G5HLbEldnQ!n2:9r-/9cK_YBC!pOuSr-/9eEldnQ!n;C; +r-/9cK_Y?B$G^V*GBnCXG]T5No)A`dE;Xq^H$=Q5HN8HmHO,"FH[L0fI!Kr5GQD`Yq>UZ2&J#?^ +'G(0T!=st^rrE&ts8W'$XDW6+H2MmnH$=LQN8"=2s8MQg!p"TMrHJBhDn,]E%/>[$GBe@VH#h./ +s8Mlp#lXf'rr<#RJT:O2#^LZ>Edkt,s8MEc!r7Xoqfi-ZY4DSnZu>ec!."Qj!.=Nf$$gc?H$=LW +G]1%frrVqGG5HLbDn>T@!o\BJr-/9dHgLD)!Np>;GQN#Ep\=aprr;SbE-HSQG^9:5$[Hu?ELlLs +s8N&urqueH~> +"8@InI-c1rG*`.-s7LtiH[L0fH?k24s8N&urr9QOqg/?`[f6:.oRM2bHN\_@KCJmUN\I!Y^;!d\t0o`#'DH$Xg`rd+]j +LA:QD!PidUHNe_BH?bhVo)A`fF8L:pI!^-aH?a^]H$=OZG^4OYq0N-_VYU6%n'&kqb/q`JaiD?[ +s8W)trrE&qrri>6G'J?4HOP4IH[L-dFaLe"s8W)hrsAO]G^FaaH[9e0rVm9)s5J?NI!^0dG_,;] +rrW3"rqHErj,nA/H[Pd=#(1cFH$5M5rr3'!s8MTh!r7^sqg/?`Yk%ep[W;7l#(1`CG^=U\pj)jc +#'tZDI!]nDqu6`lKR*HA!HPjFrrV5-HMi*kH%#,QrrK?Dqg/BhMu!2K!<2rs"hSu'H@1&8HO4hM +_Z'T8rr<#trr7K~> +"8@FlHgH%pG*`.-s7LqgH@'sbH$G#2s8N&urr9QOqg&9_[f6:.oRM2bH3AS=KCJmUN\H[5O8!dSn/o`#!BG^945!dBCo +q#:B1Er:4cH$>YTo)A`fEr1.nH[9p]H$=LYG^"FXGBe=Uq0E']VYU6$gkprHLl.+HMM[#*s8Mus +!<2lq"TH&WGBs16%!d/FH[0pZHFs.Us8MTh$2TU)H[:$bH#oe[rsSi+id,lsH?jg\JF*77!ri6! +p\tEWO`>\nHi86pH[:$`FdD%drrW3"rpp'jq20@mH3%uho)Aa!EVk%dH[0p^H$=Q0GRA_CH?sj` +H@'sX\GQ:-pOd_fH3&#uo`#!QH?oF7!dK.]o`"rrE;Oq_GDl:mrrE&srrp#YG^4X]qK`HiL;Nri +s8N&urr2qJ~> +"8@@hH0fblFHle)s7LkaG^4OZGBST*s8N&urr9KKqfi-[[/U(,oR:u^GQ`;7JaWO8rrKWMqfi-[ +[Jp1/npbh,G3sMTDn"'m!pFoQqfi-^aRoK6drfm4GQN#@q"apkl$7LNGQN)0aRoK6e96'6GQN#@ +q"Xji^i93r"*\mRrpp'iUi?3U&:&MDG'A(PGBS+QG'.tNFa!V+!H4e0rrKJ.qu?^!rW!"Ls8Dor +!<2lq"TH&UFa*h0%!Qr@H$=LRGe*_Os8MTh$2TO%H$FUZGB'AUrsSi+i-9HkG^"CTIdR+6!ri6! +p\tEWO)K8fH2VsrH$FUXF-PV]s8W)urpp'jq1s.iGQD]bo)A`tDu4b`H$=LVGBJ-*Fp`G=G^+FX +G^4OP[ep(+pORMbGQD`oo`#!OG^'(1!d8qWo`"rpDYnY[Fc#kgrrE&srrp#WG'A4UqKN +!qq:ml['FjR/R'bon%L9H[L0fHZYY6s8W)uc$Xd7HNSS@EOPlH!q_"fr-JNnFdqjurrUDkH2Dph +Eju&J!qUqel[&YQ]$LBXk^7[QHNA91o`#!AG^B:7!dKLqq>UN\I!Y^;!d\t0o`#'DH$Xg`rd+]j +LA:QD!PidUHNe_BHZkhVo)AcgF+!n4!.=`l!.=`l"aYNCH[C)7HNA/aqYpd!m` +!qq7klZs@iR/R'bomqC6H@'sbH?>P5s8W)uc$Xd7H38G=EOPlH!q_"fr-AHlFdqjurrUDjGl)df +EOYrI!qUqdlZrSO]$LBXk^.ROH3&-/o`#!AGBs+4!dBCoq>UN\H[5O8!dSn/o`#!BG^945!dBCo +q#:B1Er1.aFd`7"rrT'>H3/;EpAP"&rk``&H@(!aFdrC1rr;utrqucrrql^"ntgGR +H[C&7H385;aStW-!r7^sqg&9^Yk%ep[W2.i"+,??Hh;UaHi/0jEOboG!r%=lqg&9_]_)4*j*H"K +H3/>>me$M[Y]0Jc!dBRuoD\m>JTq*>$@-rDH[0saG&a)Aq>Ys~> +!qq1glZa4eQMpj`om_+.G^4OZG]K,/s8W)uc$FR3GQW/7Dm]ND!q^qbr-/-WA!mc@:rcecoG^+LXH$F@JS+$1QJ,~> +!r%@npNlpgHM;akFdN(,s7Lthqg/TpFb%K]e[KaHqKi6_[f6:.oRM5bHO>.IF-+i!e@0UGI/A6k +Eju&J$M&anH[:$cH@'saqg/BjI!bj=s*Fce]$LBXk^7[QHNA91o`#!AG^B:7!dKLqq>UN\I!Y^; +!d\t0o`#'DH$Xg`rd+]jLA:QD!PidRHNJAYrpp'iVK;``!.+Wk!IB+lHN/r;Qcrq>^Ko!rp;`r-JQmF3FU_rr38) +F*r=^H[9\>nG`Lfrr3&$Ed7S1"+5HCI/\HoGBM!prrW"RG5HUeENo$6!Od%FHiA +!r%=lpNcjeH1uUiFdN(,s7Lqfqg&NnFFV9Ye@'ODqK`0^[f6:.oRM2aH4#"FEf\Vre$aCCHi&*i +EOYrI!qLkdr-A?iq0E'eHi&*iEOjEq!pFuUqg&9baRoK6ds$*8H3/;Fq"apkl$I^RH3/A6aRoK6 +e9H9:H3/;Fq"Xji^iK^Ko!rp;_qg&?cbQ%S@rs5ZGH[:$bH?$@^rrE&t +rrT9AGQ)mjH[:$crd"WhFNEnM!r7^sqg&9^Yk%ep[W2%f!.4-[!HGXHrrVqIGl)dfEP1rD!onTP +r-AEhII?b-!O-P?H3/;Kq==OjiIGupH[:$aqg&BbPk+kRr;V9~> +"8@@iG5-:_H$B"-#BQ1/s8VbAG5HLiGB/,LdF,CDFS^4_Dm]ND!q^qbr-/WqG]8Ygd*]4AFa8.R +rHJ?][Jp1-npYc[GQ<$bGQE#6qfi-[\'P'Uk]q@KGQDj+o`#!AFa*b.!d01kq>UN\H$B12!dA\+ +o`#!BG'Ek/!d01kq#:B1E;Ok]F-lmsrrJp7rceEerceEerceEenot:_G^+,'q>UN*!W`-#"pG)/ +JH#TIp\tp+s8V&/EHl_RG^+LYG^4OXDisMdrrE&os8W'$s2T/)G5ZXfEQeC]rr38'E-Z\RG^+/5 +nG`Lfrr3&$Dfu&("*o-:H2`$iFE5ChrrW"PFSg:`DQ`R1!OQe>GQ<$XGQN&,[ep(+pORMbGQD`o +o`#!OG^'(1!d8qWo`"rpDYnY[Fc#k`rs.M6EHc\QH$B.1"E0Ios8MrrJ,~> +!r%@npj3'iH@5^=!.=`l$$puAQi6saon%JdHNSYBH$9.2q0N-^[f6:.oRM5cHNSYBH[Pd:"a>9? +H[C/=HNA/rrr3,lJU)TgqKi6hI/SBtH@1'dH@(!Z]$LBXk^7[QHNA91o`#!AG^B:7!dKLqq>UN\ +I!Y^;!d\t0o`#'DH$Xg`rd+]jLA:QD!PidRHNJAYrpp'lVK7*2I/Jrr2Wk!WM$VHN&:(HZH@js8N&qOEPtu +H@'p[df/Y6#6)ViG'nX_rd+iqH[C'bFgq;K!<2Zk!r7^sqg/?`Yk%ep[W;1js*F]l!.+-]!HYaI +rrVqJH2DphEkM&E!onWRr-JKjII?b-!O-S@HNJGMq=4Ifl'c^>HMMmiI!(D1qu;0~> +!r%=lpj*!gH$fO:!.4Zj$$gl?Qi6saomqAbH38M?G]it/q0E'][f6:.oRM2bH38M?H@,U7"a50< +H?sr:H3&#prr3&jJ9^j8!I9%jH38G>H@,X;!HGZrrrVD2Gl)dfFNF+S!n2@=r-AEgLA:TE!pP&W +r-AEiFNF+S!n;I?r-AEgLA:QD!PiaQH3/5Wrpp'lVK.!/Hi/0iHiAUHOrJLl> +N/`aTKuW`a#6+Z&lBu[;rH\m!H?spaHZP/-s8W)tpAY0mi;S$$HP(REYlFb&s8.n#H@'p`H$.R7 +mJdCi`Hu`SH?oL9#'kN@H$OPAr;Qcrp&>*hMK\lC!H>:6rrKQJq0N'ds*=Zjn9P+U\,61,pOd_f +H3&#uo`#!QH?oF7!dK.]o`"rrE;Oq_GDl:errhSSF*N!+H38M9N9:$;J,~> +"8@@iG56@aH$=Q5GQ<$fGR8S>F-Z_(s7Lkbqfi3gG]n0,Fnp7_Dm]ND!q^qbrHJEiG^+N4FTll2 +H$FRZrHJ?][Jp1-npYcWGQE#6rHJEgH$FW6GQD`lci4(1H$9(0!HQ9RrrUYlGPl[eFbKPcrrVG1 +GPl[eGB1dsrrU\nGPl[eFbKPbrrKoSqfi0`Qi?RU"Jg!]G^943!."Qg!I8n[GQN/0VY^<$rO;q0 +!WiQ0!s/K(JFidFrr<#^QZ.-HGRSkBG^4OZEJilXs8N#krrN,Wrce?e&U89!s8W)uqi5`BH$=LW +F3spRrs&J?H#n7UGQ)gkGBe@VGB:1irrE&krrW"PFSg:`DQ`R1!OQe@GlN!fGQ;sXGQN&-[JTt* +pORMbGQD`oo`#!OG^'(1!d8qWo`"rpDYnY[Fc#k_rrhSQEHZR%GQW53MWXg9J,~> +!r%@npj30lH[L0eHMi*rI!^"&rVuojJpI?B!.=]krd"WmI!YX9!HGRIrrVhCH2`-jI/J?jHMr0k +I!Yag@krrVqJH2DphEkM&E!onWRr-JKjII?b-!O-S@HNJGMq=+CjqQtEiH[C'd +H[Pg>"+> +!r%=lpj**jH@'saH2MspH[9h$rVuojJU%0?!.4WircnQkH[5I6!HGRIrrVhCGlE!hHi/3hH2W$i +H[5R9!HGUJrrVbAGl)dqH[:!bH?spaH@(!bHiA:6rrKQJqg&6h +rcnNhGOThYH#C1irrVqIGl)dfEP1rD!onTPr-AEhII?b-!O-P?H3/;Kq=+CjqQtEhH?sj`H@,X; +"+56@eboGt~> +"8@@iG56@dH$FUZG^'(1$$gc:Q2Ua_om_/aGQ<$eGlDmgG^4N0GQD`irr3&lIWk^8!."KercegK- +rr;uts1&76#Qk/0"p4i*JcG]Brs8W(s8N&qZZU?fGQ<$fGQ`>5IFJ2orrE&nrri.VF*Mp.GQMrK +r;Q^&l?mf#GBnFVJFDt,!<2ut"TI;EM<4.rr<#tpAY3iLiiN=!H,(2rrKKF +qfi*drc\BdFmsPUGAObcrrVqGG5HLbDn>T@!o\BJr-/9dHgLD)!Np>;GQN#Ep[J1hqQt?dG^+FX +G^9:5"+#$:eboGt~> +!r%@npj3*gH?sunfrrKoVqg/BfRJudW!N'r8HO+qEH?jg`H[:#2HiAU:!dT4^o`"rrEVk(aG`2ChrrE&trri>LKQDP9 +HNJD=f)>W!~> +!r%=lpj*$eH$Oc9H3/G=HiA!IK+jH38M? +H$fO:!I9%jH3&#prr3&jJ9^m9$%.#CH?jjaH?sr:H3&#rci4(1H[,F6!HcETrrUYnH2MsiGD>ng +rrVG3H2MsiH$%."rrU\pH2MsiGD>nfrrKoUqg&s8Mio"oeQ$s/^;>H3\\FnG`Ifc#s#3 +"*o36T'u[Zrql]uo;?\SHi&-hHNe\8U&"`frr2utq#:EkMK\lC!H>:6rrKQJqg&6hrd"WkH?o"+ +!cbdMr;QimK6[9>!HGdErrV5,H2MsiG^]#PrrK?Cqg& +"8@@iG5QRhG'J7TGB\?3GQN/7H2`$nF-Z_(s7Lkbr-/UWts8N%uEVt%d +G(/r[s8U8`rceNhG]B8BrrE&qrrhqiEcl[)GlN$mGAs2Ms8N#t!<2cn!r7Xoqfi-ZY4DSnZu>hd +!."Qg!dAm5nTG"ZDn#`DrrVqGG5HLbDn>T@!o\BJr-/9dHgLD)!Np>;GQN#Ep[eCbrr2p#rmHC< +H2)UcFaDR9s*t~> +!r%@nq0N9jGCFs_GlE'iHjY4HHZb\Rs8VbDH2N!lI!^3dI._geEOPlH#kWXmH[L0dH[P[:"+>NC +I/JX;&U\nJH%(*_H$XgbH$k!dHZH^DrrVD3H2DphFia4T!n2C?r-JKiL\U]F +!pP)Yr-JKkFNF+S"Oq^CH[>[HNSJPhV\=h!8mA(#N+># +s8W)urr2p#n]K"rao0?cbK&]Ds8M]k!<2or"RMRtH$oO:"akZEGCABGrrE&qrtbUXFa8=[H[C'_ +e,KCHY&eu:I!^3[]^5Y4rr;uts8KrbFaSL_H[C'cI!U-[W;cesrq??nq20@mHNA,jo)Aa!Er:7g +H?G\6hVR)Wh>uI"qu6`lKR*HA!HPjFrrV5-HMi*kH%#,QrrK?Dqg/BhMturD!<2rs$1""#H$aja +H[:)=HNJD>i;Wb,~> +!r%=lq0E3hG("a[GQ)pgHO>(EH?GSQs8VbCGl2jjH[:!`HhD[cEOPlH#kWXlH@'s`H@,L7"+5E@ +Hi/0jEOYrI!qLkdqg&j$H$+@\HZXLXH@'m`H[:!X\^19Wk^.ROH3&-/o`#!AGBs+4!dBCoq>UN\ +H[5O8!dSn/o`#!BG^945!dBCoq#:B1Er1.aFd`7"rrf3>H?sr;H38>NhV\=h!8mA(#N+>#s8W)u +rr2p-h27,KNf8pVN/NA/s8W)krrE&rrrh\WEd2s/H3JYAHZjeoqu6Zqqu7H2b]S/VH$Xd^GLQQk +riU9gH$aj`EP1Z<'`S.3s8W):I<9g]H[:!`H@'paEiB!;!<2]l!r7^sqg&9^Yk%ep[W24k#'k?[ +hqm5Gn(n*$mJHnbpOd_fH3&#uo`#!QH?oF7!dK.]o`"rrE;Oq_GDl:frrE&srsA"ZEd2nUH?sj` +rd"WiIGk,)J,~> +"8@@iG5QRiG'J1PH[9^TrcnHg$@$c>F-Z_(s7Lkbr-/?iG^+FXolpLU[/U(2oR:t.H$FOXH2;af +H?a[[r-/6\[Jp1-npYcZGS,4FF*;qVEcuYOH$4IYG^+/9ci4(1H$9(0!HQ9RrrUYlGPl[eFbKPc +rrVG1GPl[eGB1dsrrU\nGPl[eFbKPbrrKoSqfi0`Qi?RU"Jg!]G^9:5"*BLWhu;I5hqn1eqq`4J +h!"e +!r%@nqg/ZrFHOl8jMcjtI$%.&AQi6saon%JbHNAM?om6^Z[f6:7oRM46H[:'eH@($crHeQk +I/80jEju&J"S.+hH[>[<%=EGFUt4qo_1[#\H@'u;HNA/uci4(1I!PU9!HlKUrrUYoHMi*kG_c(i +rrVG4HMi*kH?@7#rrghsH@'u;HNJDGq"Xji^iTC"!d:"2o)A`fF8L:cG*`-lrtPJ4s8N&urpe+R +b/h`Ka32]Ijo58NrrW3"rr2p"r3prpr-JEird+]iMsp<quH@1$aiU6^G +rqZR!hN2`)H@(!drd+`pH$$gmrrW"RG5HUeENo$6!Od%HHNSS8V>fl^!ri6!rVm$"s7_1lqg/?a +]_)4*j*Q+MHNJJ@me$M[Y]9Pe!dKY!nc'*us8W)ur3^cnI=$ +!r%=lqK`HiOj<=S`J/P`H2`*rH[0b#rVuojJU%!:!IK+bH3&#orr3AuJ9ZBdH$am`H@'r9H3&;< +qK`0^\,QC/npku_H4>4GG,3^VjM?IlI!L$`rd"Tb\^19Wk^.ROH3&-/o`#!AGBs+4!dBCoq>UN\ +H[5O8!dSn/o`#!BG^945!dBCoq#:B1Er1.aFd`7"rrK!;qg& +"8@@iG5HLjEf\N4jMQXmH?]@5$$g`9Q2Ua_om_/\GQE)6olpLU[/U(5oR:t.G^"FYGBeCWrHJ?e +H2;adDmfTE!qLe`r-/ZrG''J.lf>g3FF&.UGQ)gfDn"'m!pFoQqfi-^aRoK6drfm4GQN#@q"apk +l$7LNGQN)0aRoK6e96'6GQN#@q"Xji^i90q!cs_-o)A`dE;Ok]F-cgirr`9#s8N#t%^lB=!sJc/ +"pG&.J,fNHo`#!ls8N#t"T5ZOFF!h0!-eEe!cs1do`#!\Ihd!cb"7mJd7es8Mus"TJGqJTgp8!H5RA +rrV/(GPl[eG'iTJrrK9?qfi0bM>-Q?%fZM.rr;o(G'&%TG^4LYrceQeM"(HEJ,~> +!r%@nqg/EfT_SNcrrq_DG^Ojcrd+onQi6saon%I:q0N6lH[C-dq0N-^[f6:1oRD.5H[PU8s*Olp +I!Y^;!HP[KrrhnDH$al9HO4f&s8N&ts65Sfrd+cqH[BeEci4(1I!PU9!HlKUrrUYoHMi*kG_c(i +rrVG4HMi*kH?@7#rrghsH@'u;HNJDGq"Xji^iTC"!d:"2o)A`fF8L:gG*W(+s8W)arrE&srs\;9 +aN;KC`lZ?C_W(RgrrE&trrE&qrri>LKlh\@I/J +!<2lq"7rF5H2N!pI!U0aHfk;,rqHEoq20@mHNA,jo)Aa!Er:7cHuc"JrrE&prrVqJH2DphEkM&E +!onWRr-JKjII?b-!O-S@HNJGMq=O[err)isrr)iud"HN +!r%=lqg&?eT_SNcrrq_CGC+X_rd"imQi6saomq@7q0E0jH?sp`q0E'][f6:1oRD+3H@,F5s*Ffn +H[5O8!HGUJrrVbAGl)dnF12,Js8N&_Nck>I"FGH@EOjEq!pFuUqg&9baRoK6ds$*8H3/;Fq"apk +l$I^RH3/A6aRoK6e9H9:H3/;Fq"Xji^iK +M#N/2J]%K\rrE&trrE&qrri>LKlhY?Hi/0jEN&O0"T=U/H$fO:#'?O!<2lq +"7rF5H2MsoH[0s]Hfk;,rqHEoq20@mH3%uho)Aa!EVt+aHZGnIrrE&prrVqIGl)dfEP1rD!onTP +r-AEhII?b-!O-P?H3/;Kq=O[err)isrr)iud"HN +"8@@iG5QReF.W1+rr3/fKQVQbH2`$oF-Z_(s7LkbH22[fH$FRZGPQIaDm]ND"n[4dG^+N/GlN$j +G^4N2GQD`jrr3&jIWkU5$$!?Prr;utl&9]_GQ`;:G]1(;rrVD0G5HLbEldnQ!n2:9r-/9cK_YBC +!pOuSr-/9eEldnQ!n;C;r-/9cK_Y?B!Pi[OGQMrQrpp'iUi?3U#'6(/rr<#tli-tarVm#-"TSQ* +qu?g"JGfB?rrE&trrE&qrri>LK5u59H2MmfDlE=."T=O+GBs14#'-C:s6"ZOrHJBcM>HQT@!o\BJ +r-/9dHgLD)!Np>;GQN#Ep[nIcrr)isrr)iud"6<8GQrG +!r%@nqg/?klhg\mc?FV_H@1'dFdN(,s7LthoQgRcH?oC6!H>IGrrVhBGklXcHi86jHhhsoEOPlG +s71_dH[>[nfrrKoVqg/BfRJudW!N'r;HNeeDHZk\QrVllsmf*:dqu6`hg=Q8U#1qGYn,NFe +q>UHorr3'!s8Mus$NC))l&9Y0H[:'crd+]lI-(5)!<2or!OHhEHNe\Jp]&EYr-JHdWTX9_rr;us +rr]lTH$oR;#(1cFEiT0=pAY3iMK\lD!HG@7rrKQKqg/?cUZqdYrquctpOmhhHNA0"o`#!QH[>U: +!dT4^o`"rrEVk(aG`2C^rrVDBFS^=eI!L,&s*t~> +!r%=lqg&9jlhg\mc$"D[H$aj`FdN(,s7LqfoQ^LaH$K43!H>IGrrVhBGPQLaHMr*hHMMgkE45cF +s71\br-AEfNr&YQ!RGocH3&#rci4(1H[,F6!HcETrrUYnH2MsiGD>ngrrVG3H2MsiH$%."rrU\p +H2MsiGD>nfrrKoUqg&:6rrKQJqg&9aUZqdYrquctpOd_fH3&#uo`#!QH?oF7!dK.] +o`"rrE;Oq_GDl:]rrVDBF8C1cH['r$s*t~> +"8@@iG5QRcHKk>,&'K'>H$=OYG]T/Ks8VbAG4]t[G^"?.G6)Tfrr3&lIqu6]AF8L1_Dn"'m!pFoQqfi-^aRoK6drfm4GQN#@q"apkl$7LNGQN)0aRoK6 +e96'6GQN#@q"Xji^i90q!cs_-o)A`dE;k(cH$FRTQ2U[]!<2Ed!<2lq%F%:28kDEE84Q9BV>pGb +rrW3"rr)j(rr;u\MJ[T_GBnE3GQN&9jneuWrqucsZZ,he"a5Rns2f +"8@IoI/SBnGEMe%s8W'#s7Cedrd+s!HZkbTs8V_BG3aDSE45cG!q_%fmHN\SKq#C?jrrVG4HMi*kH?@4, +rrE&nrrghsH@'u;HNJDGq"Xji^iTC"!d:"2oD\plVK7._HOY.brVulsrr;utrr<#thZ!TTqYpQp +pAYEts8VDPG'eO_r-JHb^%D=5f62IfH[L0dHfP..ErLCfI!^"Yir98_s1 +"8@FmHi86lG*2\$s8W'#s7Cedrd"ltH?GSRs8V_BG3aARDmfTE!q_"dmnmrql]sl$I^RH3/A6a8Z)= +rqQKpe9H9:H3/;Fq"Xji^iK"_rVulsrr;utrr<#thZ!TTmf*Rls8VDP +FaA=[r-AB`]_)44f62FdH@'s`HK5%-ErL@eH[9eVir98_s1T@%+fTFH$FUZGBi0JX)S&_"*o-3aQ!4)rr9TOG'J7UrHJEeK(Ap7rrW"PFSg:` +DQ`R1!OctEGQDfXo`+sjo)AdcJTgp8!H5RArrV/(GPl[eG'iTJrrK9?qfi0bM>-K=!<2lq"mUtd +G^4T5GQW,.]DmB~> +"8@IoI/\HoH?>q]rrE&trr_qGG^B=8#'Q@3s8W)Nn(.Qlrmq5(eEQu4"T7!*f\,fH"k_M[g!o($jrr)isrr2otrqZQrk'hQ&rd+frH[Bk-s*t~> +"8@FmHiAZeE[&5 +!qLkdr-ABcaSPongrrVG3H2MsjH$%1- +pAY6oeTcB;H3/;Fq"Xji^iK0os8Sp9qg&U^!s8VkYF*`-0H3&/\o`#TrK6DQeH$ajW_uGgAH?sp`H%,,OrrE&nrrW3"rqcWqY&F/_!dT%G +p&>*hMK\lC!H>:6rsZ>UH[:!bH?sY-s8W)krrE&trrE&srrW3"rr2p!pOd_fH3&#uo`#!QH?oF7 +!dK.]o`"rrE;Oq_GDl:mrrE&srrE&trrE&orr_D4GC0=8"abQAF.iP`~> +"8@@iH2`$iGB'DWrrE&trr_qEG'En0#BQ71s8W)NfC7;jf)F2$f$`a\rri8Re^`7?eHFIRg!oUN\H$B12"*\e+ +rq??ormc19r-/9cK_Y?B!Pi[OGQMrQrq69orr<"nE;Ok]F-HRurrE&irr`9#s8MEc!<2ip"9/?# +rqZR!rr<#lP&Y_jr-/6`Sb2pqo7;".G^"FXDo)I6FEi%UGB\H$oD\giq#:Eps8Mlp!N^/7GQN)4 +g@bIIq1s.iGQD]bo)B-,Dg?SPH$FRRU&Y/lp&>$krr2utrVlrus8N#t!r%7hqfi-[](H"(iHTSE +GQN&8m.C;YY&=,]!d0@oq>UHorVllsrr2utq>UQXI!'`6GQiA;G]B>TJ,~> +!r%@nr-JNjMu!AMrsJ%=GC4daI!^%'rT4%Zrquctrr;ucrrE&rrsA7IH$ajaH[Kq8rr2utrr3,a +IO%0$:nhVd;Ki8ESPjSeiQ +!m>h7rHeZpH[(GDJ,~> +!r%=lr-AHhMu!AMrsJ%=GC+[^H[9h$rT4%Zrquctrr;ucrrE&rrrVbAGl;piHZQ4drrE&trrhM4 +H$Xc8H3&#rci4(1H[,F6"`qBWrr;urrsA])s8N&?FF/=Zrd"ZjM"puGrrVG3H2MsiH$%1#rrUbr +Gl2jhGD>nfrrKoUqg&)?p&>*mS94aVs*4`fX6tF^rd"ZnFd;ptrrMrSrnme6 +rnmh7o)&Ferr2p#q4MqXH2MsjF2\+Xp\t:6rs?/SH@'saH$aS-rr2utp](9g!r)Ka +rqHipqu?Wps8N&mK6[9>!HGdErrV5,H2MsiG^]#PrrK?Cqg&O#6+YhhVd;Krnmk8jSeiQ +!m>e5rH\TnH?Y8BJ,~> +!r%7hr-/@/KrsJ%;Fa87VH$FCqrT4%Zrquctrr;ucrrE&rrrVb?G5ZXeH#]e^rrE&trrhG0 +GBe?2GQD`lci4(1H$9(0"`_6Urr;urrsA])s8N&?Ed;nRrceNfLA:cErrVG1GPl[eGB1arrrUbp +G5QRdFbKPbrrKoSqfi0`Qi?RU!Msf6GQW/2PPkCZ"9/?#rqucsq=jg^!r;Qdr;Qcrn,Ejrs8VH@ +hVI&Fi8*5Mrr)isrqud(kC.PuGBeCXGBJZ9p&>*mRWACPs*"TbWU,"VrceNjF-HRprrMrSrn[Y2 +rn[\3o)&Ferr2p#q4;_RGPl[fEPhbTp\t-uK%0$:nhVd5GhVd8HjSeiQ +!m>_1rHJHjG]ei +"8@IoI/JnfrrKoVqg/BfRJumZ"TJH$VKD`_"+#-VrVlg!rr<#tr;QirRXk9g!I_*IrrE&grrE&trsc/N +H@'sbH$adoqZ$Tpr;R!#s8K?HH@5[3pl[*i&HiA +"8@FmHi/0lGL6BhrVlu!FaA?3H3/5UrTX=^roO1[rW3&ur;QihJ9_!<"*o=TrVZZtZu^M>rH\Ka +\^19Wk^.RQH3\eCE3B3?s8Mrr#lal(rjd&qH@5^UN\H[5L7!HcETrrgMfH[9u:H3/;F +q"Xji^iK0os8Ss;r-AHjFd;q)rr`9#s8Mrr!rSL;qh+uuXo&+urpg!grr2p,YAec5 +H$X^]GDl=ts8Mrr#6+Z%ZZCD=rH\NiId?Y+$GLS-H@'sbG*U*lr-AEb[Jok!"odh7GC"T7Gli;6 +aSPo:rr2p-msfP.H?jj`H?-=js8W)orrW"RG5HRdE3Sp5%(C8(H$ag`H?5k]s8Mcm!r.h.qh,*" +^An64rr3&oK6[9>!HGdErrV5,H2MsiG^]#PrrK?Cqg& +"8@@iH2MmhFjC$drVlttF*Mp-GQMrOrTX=^roO1[rW3&ur;QihIWkX6"*]+PrVZZtZ>k)6rHJ?] +\'P'Uk]q@MGR&M=DQa!=s8Mrr#lal(rjQikG^B@6!csn2q>UN\H$B.1!HQ3PrrgGbH$FQ4GQN#@ +q"Xji^i90q!cs_-p&>0os8Sm7r-/-oI%'4>kGBe=VGBAf?s8Mfn!Mjf6 +GQN);m!o~> +!r%@nqg0'&J(FZ!s89fYH[U6fI!U-_Qi@!arpTjorr;utrr;uss8W)]rrE&trrhnDH$al:HP1^K +OR)rGs8'NUH$ajbH@(!Z]$LBXk^7[QHN\Aks8W)trrE&qrrK`PrHeWmHZc(XrrVG4HM`$kFNXU^ +pAY9-EdE(Yrd+]jLA:QD!PidRHNJAYrqHHmrWN9#s1<@LHNJDXrV-[*hMK\lD!HG@7rs?klH[L-eH@'b/ +rVllsq>UiuK6DKbG'S=WDRf]Frri?$pOmhhHNA0"o`#!QH[>U:!dT4^o`"rrEVk(aG`2Cqrs\n. +E-ckVH?jj\Nqr\Ns8W'+s4DRBH[C-eH[9u!J,~> +!r%=lqg'!%J(FZ!s89fYH@1$bH[0p[Qi@!arpTjorr;utrr;uss8W)]rrE&trrVbAGl2jsHZYA8 +s8N&p^it$LH$fO:!HGZrrrVD2Gl)diENT9@rr2otrql]r]5ddq"*o37U%nWhl$I^QH3893rr2Wk +!kWGtr-AEgLA:QD!PiaQH3/5WrqHHmrWN9#s1<=KH3/8UrV-*hMK\lC!H>:6rs?kkH@'sbH$XP,rVlls +q>UiuK6DH`Fa/+SDRf]Frri?$pOd_fH3&#uo`#!QH?oF7!dK.]o`"rrE;Oq_GDl:prs\n.E-ZbS +H$FXXNVWSMs8W'+s4;I?H?spaH?jetJ,~> +!r%7hqfij!IFS;rs89fWG^=UZH$=LSQ2^d_rpTjorr;utrr;uss8W)]rrE&trrVb?G5ZXqG'S+g +li6taqS%)qG^"H4GQD`lci4(1H$9(0"E1@@s8N#t!<2lq!P*.IGQW/7EhE.,!pOuSqfi3`aSu24 +rrT`LGPl[eFbKPbrrKoSqfi0`Qi?aZs8E0$rr9NJqfi0aPl:@V"TJH"O)b&>#Ag49rr;utrpTjj +rr<#!E-D5)$[?l;M>I5Ns8W)urr)itflm@>"aP?F*MtTH$=LQU&Fuk +rqZR%q13X1G&qhLF_nSerr3-#s7_(fqfi-[](H"(iHTSEGQN&8m.C;YY&=,]!d0@or;R3)XDW6, +G'A+SF,TknqZ$Tp$ieb"GBe@XG^+FVja[~> +!r%@nqKiQoH(D@MQ$.D#H@5[<"a672s8W)`rrE&trri?$s8N#drrE&orrhnDH$al8HOtCOWOK*m +GBnO_H[C'cHZH^DrrVD3H2DpiG*r:.rrE&prrW2"FT-UiI!^3^V>1&ll$RgUHNe_CEjbrHpAYJu +FF/C]H[L0aLA:QD!PidRHNJAYrq69orr<#6F8L:hG_Yqls8N&tqYpWiLj8iE"akBfs8W)_rsGlI +I!^6fH@'joq"F^hm=HNSAgs8Mcm!r7^sqg/?`Yk%esd!'h`HN&6mGED^prtF^JG^=aaH@(!Z\,ZL- +rr<#mKR*HA!HPjFrrV5-HMi*kH%#,QrrK?Dqg/BhMu!8M$EJ/mH@1$dHZtJFrVm!!s8W&srrVJ7 +H2N$hH3!&W~> +!r%=lqK`KmH(D@MQ$.A!H$fL9"a-11s8W)`rrE&trri?$s8N#drrE&orrVbAGku^mG(?R$Y`F!Q +H@,R9!HGZrrrVD2Gl)dgFdW1-rrE&prrW2"F8gIgH[:!ZV"jrkl$I^SH3JS@EjbrHpAYJuF*`1Z +H@'s^LA:QD!PiaQH3/5Wrq69orr<#6Er1.fGD5bjs8N&tqYpWiLj/cC"ab9ds8W)_rsGlHH[:$b +H$XXlq"F^hmrd"ouH?jg`H[:!`M"gTB"TJGaH?fF8$[I)FFN=C\rr;ut +rr)iuri^;]kIs?6cH?jg_EOYuJrr2rtpOd_f +H3&#uo`#!QH?oF7!dK.]o`"rrE;Oq_GDl:orsGfHH$Oa^H[9joq>L +!r%7hqKN?iGFPqEPB:qnGBs.3"`ot-s8W)`rrE&trri?$s8N#drrE&orrVb?G5?FiFFL-qY)RRI +G^943!H5HnrrVD0G5HLcF-cb'rrE&prrW1uEW11cH$FRRUA4`il$7LOGQi;:E3oTDpAYJsEHlbR +G^4OVK_Y?B!Pi[OGQMrQrq69orr<#4E;OkbFbBDfs8N&tqYpWgL3]kIL +!r%@oqg/ZrI!TsUEd)hWH[Pa<#'Q@3s8N&tbl7\BrVmK#JU)TgH[C'cH[U0]EH6>NIK"QsI!U-d +Ek9Ts!pG#Wqg/BiL\CZG!<2or$N?<5H[:'cH[KhDrr<#trVlr`I!Ya<"FPN9Yl=@r$i>s.I!U*c +H@'jjq"Xji^iTC"!d:"2oD\mkdU*f"Q"HNI!Ya< +!Hc*RrrVqJH2DphEkM&E!onWRr-JKjII?b-!O-S@HNJGMq>:1!\T<+EH@(!dH%GG^rt,20s8N&u +m!O)*H[L0eH%>42~> +!r%=mqg&TpH[0dSEcu_TH@,R9#'H:2s8N&tbl7\BrVlriJ9^p:#CLc;EH6;LI/\ElHiAs-H[0p`H$X[h +q"Xji^iKD5!dK4arr2utrr36&s8N&umHkK6V`hH@'p`EjG`E +rr2utqu6c#EdE*2H3&&krr2utq>UNlMK\lC!H>:7rr`8YH?oI8"FGU*f"Q"ELH[5R9!HZ$Q +rrVqIGl)dfEP1rD!onTPr-AEhII?b-!O-P?H3/;Kq>:1!\T<(CH$Xd`G_#8\rt,20s8N&ul?dc% +H@'saG_#+1~> +!r%7iqfiHlH$=@KE--;LG^943#'6(.s8N&tbl7\BrVlriIWkR4#C:Q5DfBlDHN&-hH2`$hDn"'m +!pFoQqfi0cL%Pm)H$=LXGBe7` +q"Xji^i90q!cs_-oD\mkcZK&/!d9"]rr2utrr36&s8N&ulZm^RGQ`;:G]9nPrrrE%s8KNJr-/Nk +FFb.G^+LXG]9tg +rr2otrql]tX`/N1rHJ?^YQ"P%rqZQqq1s.iGQD]boD\pli-9JEGQ`;6L&(`Arrh2&GBnE3GQN&. +^&.g2pORMbGQD`oo`#!OG^'(1!d8qWo`"rpDYnY[Fc#kirsH5TG^+FWG^4I]n,31srr<#ts8VD1 +G'8+UG^+C\l[S~> +!r%@nq0N6lH@($eqKi?mHZthTm/I(bi;WfVqu7&pJU)TgH[C'dH[:);HN8BjHN\V@HZH^DrrqV6 +H$apbrd+]mGME,s!<2ip!ptD]qg/?c^\Ig1l$RgTHNJS:U%SEhg3%diH[>[gJo"9/?#rr2p"rg\+Yr-JHc_Y*p1q20@mHNA,j +o)Aj]J9cNgrd+]mHfk#$"N5G0H@5[<"F/Aps8N#t!r%@nqg/?a]_)4*j*Q+MHNJJ@me$M[Y]9Pe +!dKY!qu7#EFEr4ZH[:!`HK+i%!<2rs$J0NLH[L0fH[1DBJ,~> +!r%=lq0E0jH$XgaqK`9kH?PYRm/I(bi;WfVqu6`gJ9_!<"+,?>Hi/0iH2W$lH$XdV\^19Zk^.Q# +H[5U:!dT"Err2utqYpWaInfrrKoUqg&'@GPZUdF3WkI$HI:8H[:$bH?jeorVllsqu6]KGlE!mH$Xd]LACNB#6+YC +FF&7[pj)s__=IU6qi#`FH@'sbH?,k]rr3*"s8W)trr`7jFF3q3!HQ'MrrW"RG5HRdE3Sp5"7L_a +Hi86lH$e]Hrrg2\H?jl9H3AH?s8W)trrVqIGl)dfEP1rD!onTPr-AEhII?b-!O-P?H3/;Kq>:1! +aE2]RH@'s`G^ABHrrE&srsI;#H?spaH[9plq1&~> +!r%7hq03$fGBeCYrceEdrceQkG]]5Lm/I(bi;WfVqu6`gIWkX6"*o-6GPl[cGPuahGBe@N\'P'X +k]q>rH$B74!dAe?rr2utqYpWaHZ].0!HGdIrrVG1GPl[eH#fPMrrUnqH2DgfFbKPbrrKoSqfi0` +Qi?RU!T/2%GQE#5rc\@rp&>'>Fo$=`ER!YG$HI44H$FUZG'/#erVllsqu6]IG5c^iGBe@UK_P0> +#6+YAEd2hSpilg[^[hC4q20<>G^4OZG]9MYrr3*"s8W)trr`7jEd@S-!H>jIrrW"PFSg:`DQ`R1 +"7LY]H2VshGBr?Drrg5[G^"H4GQi85d/X.Frr3&oJTgp8!H5RArrV/(GPl[eG'iTJrrK9?qfi0b +M>-oI$H@+1G^+LYGBS5jqu6ZqrVm5UFa/(TG^4OWL&$6~> +"o![rH[L/-HN\JYrVul9rrM_BrHdmY"EM-Ss8LIH!pG#WqKi6_\+fn(rl0*XHNJJ:dJ3_Cl$RgS +HNJANqu-Nprqud!rgn7ZI/JnfrrKoVqg/BfRJugX"9.qEH2W'lI!TnQqYpQprVm#-EI)tZ +rHeZhc2[hCl2Le4GPZXeFi3qQ!PEIOHiJHpG*DjtrrrE%s5J9Kpj.E +Mu!DPs8W)urr2p#on.L9I/SBnG0p6^rrVtQGPldkHuu7cs8Mrr$i^2*s8N&uqMf`HI/\HoH?R[3 +rs&K&rr<"pFT$OjI!^0`df9=FrrVqJH2DphEkM&E!onWRr-JKjII?b-!O-S@HNJGMq>:0ndWTs9 +HO,"GHZ[:,s8W)srrrE%s0Qlqr-JKgPl-%~> +"o!XpH@'r*H3A>WrVul9rr_kCH$en("ED$Qs8LIH!pFuUqK`0^\+fn(rl0'WH3/A9dJ3_Cl$RdR +H3/5Lqu-Nprqud!rge.WHi/0kGD>nfrrKoUqg&:0ndWTp8 +H3ekDHZ[:,s8W)srrrE%s0Hcnr-AEePl-%~> +"o!RlG^4N$GQ`&QrVul9rr_kAFa!+r"E1gMs8LIH!pFoQqKN$Z[J0\&rl0!UGQN)3chRMAl$@LL +GQMrFqu6TrrVl`p"TFg0G^9:5"Eo$4K_Y?B!Pi[OGQMrQrq$-lrq(\`rHJEiG]CRrrrE&srrfWG +G'J<2GQ`$2s8W)_rrLPiqKN$]_=mm0\o@Um"F#-4Oo4qQ"oeQ%i-'>>GlDmhirB&Xp&>*jQ#lkJ +$@-`Mq>^Hos8N&trr3,mJTc9`rHJBbd/Nb=!r.Ror-/BjEMWX7rqud(rr;utrr<#pMKO/hrceKg +F3sd`#6+Z%s8Sg5rHJNlG^"8Xs8Mus!r%7hqfi-[](H"(iHTSEGQN&8m.C;YY&=,]!d0@oqu6`G +FEd_/#^LZ?El@tWs8Mus"oeQ%Z#P'eGQMrLr."~> +!r%@nl[&\VQi4i%"nI1hH?su.HN\YAEk;7srrVD3H2;jhG_knfs8W'$s8MeUG5HUfG^8nfrrKoVqg/BfRJudW%/cuEH[C-dH[0h"qu6Hl%K?CqLNe&l +H@1'dG_5>FrsS1CH@'scH[C-`Q2CIY#6+Z&qMf]Fr-JKdZi9Xt"TJGsMg+oB!dT[rnc&WoEr:7e +H@'k`rqQL#_01-PH[C'dH@YJ`rrE&prt#,)Mg'MqH?spbG_u7qs8Mrrs8N#ts8EG#FF8F^I!^6` +T)\iirr2utrr3E+k(%](H[L0dH[:)%qu6`lKR*HA!HPjFrrV5-HMi*kH%#,QrrK?Dqg/BhMu!8M +"6t;\I/J +!r%=llZrVTQi4i%"nI.fH$Xi,H3AM>EOl(qrrVD2Gku^fGDPees8W'$s8MeTFo-IdG^8nfrrKoUqg&!HGdErrV5,H2MsiG^]#PrrK?Cqg& +!r%7hlZ`JPQ2SW#"nI(bGBeE&GQ`58Dn#_mrrVD0G5?FbFb]A_s8W'$s8MeRF8L1`G'Dm>rrVqJ +FSg:aGBMC/rs$8XG^+FXGQ)ggFbKPbrrKoSqfi0`Qi?RU%/cl?G^+LXG^"7lqu6Hl%K?CqKlqWc +GBnFXFarf@rsS1@GBe=WG^+LTPPP+U#6+Z&qMTK?r-/9^Z2XFr"TJGsM08Q;!d9@lnc&WlDu=h_ +GBe8VrqQL#^N=[FG^+FXGCArZrrE&prt#,)M04&gGB\:VFb]_ks8Mrrs8N#ts8EG!EHueRH$FUT +SH&Wgrr2utrr3E+k'_AtG^4OXG^"Gqqu6`lJTgp8!H5RArrV/(GPl[eG'iTJrrK9?qfi0bM>-oI +"6t5WH2MmiF-QV&rr2otrr2p!j*PtHGQMfgrdX~> +!r%@nl[&\UR/Or&"S74jI!Y7."+5H9]$LBXk^7[PHNSS9T_eTd"oeQ%Z#kBmHNe_BHZt2;q#:Kp +Oa)2"r-JWkMsCUTh +RrWk%rd+`nHuteidHNeeDHZt5/q>UN?G'a+6#(1cAQN$p`pAYJnEdE([H[:$cFhmhQ!ri6!rVmeU +FaJI_H[C-eFg_8Ks8W)us8N&dO`l(uI!Yd=!dTXuqu6`lKR*HA!HPjFrrV5-HMi*kH%#,QrrK?D +qg/BhMu!8M%/c63H@(!dH@1'][f61(%K?$dFa\U`H@'scFOU8?~> +!r%=llZrVSR/Or&"S71hH[5(+"+,?6\^19Wk^.RNH38G6T_eTd"oeQ%Y]G0jH3JS?H?Y):q#:Kp +O`u(tr-AQjMsCUNqs8Mus)THlF +H@'saH[9hBs8N&urr<#ts6c"lH?sp`rd"WjM#$rJ!r%=lqg&9_]_)4*j*H"KH3/>>me$M[Y]0Jc +!dBRuqu7*&O`l"rH@'paH??Upqu7-)op0]IH?sj_H$aY^s*t~> +!r%7hlZ`JOQMn`$"S7+dH$A_%"*o-0\'P'Uk]q@JGQW/0T)/Bb"oeQ%Y&SadGQi;9G]eZ2q#:Kp +O*,Ylr-/EfMUQg +R;dHMGQW/8EgPnf+oIIBH$OUXH$=OSZiC()s8W)us8K3AH$OXZH$FRSdf9=@rrE&trrK';pNQ^X +W;cesrUg*jb]T@!o\BJr-/9dHgLD)!Np>; +GQN#Ep\Xt!r/YrDG^+LXH$FA:rql^)rq2RtH?a[YG^"FRdJn^~> +"o!^qI!^8/HNJDWrPSX;npu(4m!AbR]$LBXk^7[PHPV!UFct5Ks8N#qh4f(=I!L'cI!U-[W:p5o +YB5,s8MH-OE>erH@1'cI!]nOrr2utm/I7gs8N&6F8gM,I=$6iLNn,lH[Pg>(3>AVp\t3mqVnT'H$ajbI!U-dF3=O^p&>&g +FT-UnI!^6gG^QRMq#(-k"9/?"rr)iumXBK[HOY@KFJ@F]rr<#slbe[(rd+lrI!^6gEjG]ArrVqJ +H2DphEkM&E!onWRr-JKjII?b-!O-S@HNJGMq>L +"o![oH[:&,H3/8UrPSX;npkt1m!8\P\^19Wk^.RNH5:jRFHY,Js8N#qh4\t:H[0p`H[0pXW:p5o +YB,#9Hi/0lEf/HCrr3,sh4f%9rd"Qir-AEgLA:QD!PiaQH3/5Wrq??lrr)j#p4IR8H$fO:(3t"j +eFW\>s8MH-OE>eqH@'s`H[9_Mrr2utm/I7gs8N&6ErLA*I!U*cH$61Jr;Zfro$!MEH[9s`H[:$^ +NVNMQs8M]k!QT9UH3&0/rVllsp&>6iLNn)jH@,X;(3>AVp\t3mqVnT&G^=X^H[0p`Em"F]p&>&g +FT-RmH[:$cGC-CKq#(-k"9/?"rr)iumX9BYH4>4HFJ@F]rr<#slb\R%rd"fpH[:$cEO,T@rrVqI +Gl)dfEP1rD!onTPr-AEhII?b-!O-P?H3/;Kq>L +"o!UkH$FW&GQMuOrPSX;npYb+m!&PL\'P'Uk]q@JGSYRLEfe]Ds8N#ogRiP2H$=LXH$=LPVY:#m +X`8T1H2MmhE/<$=rr3,sh4Sh3rceEer-/9cK_Y?B!Pi[OGQMrQrq??lrr)j#p47@2GBs14(3aed +de!J6iKm%ZbG^9:5(3,/Pp\t3mqVnN"G'J4VH$=LVE6/(Yp&>&e +ErL:pH$FU[Fa:%Gq#(0js8N&trr)iumX'0UGR\qBEhM"Wrr<#slbJ?trceZlH$FU[Dm96T@!o\BJr-/9dHgLD)!Np>;GQN#Ep\k*qrr<#3DgD;+(jU@LFf=I$s8Mueabt4bG^4OY +GB\%dqYl!~> +"o!XmH$O`(Gli&QrP\^@rpkP_H$FUZn9G([EOa?p!pG#WqKj!*H@'g[MkQo@NdGnpH[:$cH@($e +FOg*b!S;GkHP(XPI!g*[NM<2AMgKPmH[:$bqg/BgLA:QD!PidRHNJAYrq??lrqud!ZZ1;>HMi*r +Fa&M-US=0,G'2Mrri>0EdW33HPLjTGB\h:U7mKnFF&:\I!^0eH?G;Drr2utp\t>lEdN33HO>.HFF8h0 +U8@G\rqcX.V/q!2H[C-eH[KpZKp\X1Q[a+$qKi1+.m"BV1I!g9eI!^3^I[-\'R"9F)H[C-dI/\HpFij[`J,~> +"o!UkG^+N%GQMoOrP\^"YE4F6o!pFuUqK`p(H$XUXMkQo@Nd>emH?jj`H$Xga +FOg*b!S;GkH4bLMH[BpYNM<2AMgBGjH?jg^qg&0EdN*1H51^QG'8Y8U7mKmF*W(XH[9saH$#,Brr2utp\t>lEdE*1H4#"EF*iY. +U8@G\rqcX.V/gm/H?spaH@'aXKp\X1Q[X"!qK`6jG^JZNrrVqIGl)dfEP1rD!onTPr-AEhII?b- +!O-P?H3/;Kq>1+.m"9M.H[C'aH[:!ZI?gS&R"0=&H?sp`HiA +"o!OgG'8)tFolWIrP\^o`!tP#4$k`H$OU[rce`nEI!bATpC4MErL:`H2VsgEQ.GI!onWO +qKN*fGC/`Hrri>.E-Z[+GSPFKFEE50TV%'eEHcSNH$FOYGB/]jE-Q[,GRJ\?GB%n] +Q(XoCs8Mlp';KMkH$FRZG^+LSFb?'TTp:"FFS^4aH$4JsqYpWkJTgp8!H5RArrV/(GPl[eG'iTJ +rrK9?qfi0bM>-lH+7+Q$G^4RZGBnFXEI3tETpC.KFEi%UGBnFXG&YS's*t~> +!r.S$l[T.dS,NBerl4sAoS%aDJ:I'=s*k&o][-TZk^7[QHNnkAH@'saH2_jbGP?FcFdE"#rs8W$ +PB;.uH@'u;HOY@KGB7kJH$XgbI!U'crHeZpHZt5>q#:B1F8L:cG+&@!ruLQ^G^=abH?spbI=$6^ +F*)SNH@1'cH[C-dI!TkRq>UHomJdIks1`Q"H@(!drHf6)G'%hLH$XgbH@(!bI!g"&qZ$Tpp\tKt +s8W)rOa)9MHNJAWr:0e$rr;SFG'n[aH[:$eH[9mWFEMeRI/SC#I!U-bG1-Eis8N&urqZQs\oW1F +HMr0tH$jsbG^"+Nmf3:_rrV>2GlE$jH@5^=#'tQ:F)uMLq0N +!r.P"l[K(bS,NBerl4s@oS%^CJF.geGJ)9%!pFuUqg&HnG'SCZH$K=0!-\*_!d'b,p\t?pqic+" +H2r6iH4>4HG&qbIG^4U^H[0j_rH\TnH?Y,=q#:B1Er1.aFd`6urs%qGGBnO^H2`+'I!U$[F)uJK +H$aj_H?sp`H[0\Pq>UHomJd:fs1`RPH2rUT/F*W+XrH\fq +H[9s]G&VZns8Mlp!p4oUrd"TjHiA +!r.Isl[8q^S,NBerl4s@oRhL=IdMOaFh5p!!pFoQqfiAG'A1VH$=FWrHJHjG]e]7q#:B1E;Ok]F-lmqrs%qEFa&+VGQ)h#H?aUSEH-&C +GBnFWG^+LXH$=8Jq>UHomJd:fs1N@LGQ<$fGSG@CEH-&CGBeCWG^+FXH#T)Gs8W)mrs/Q's8MqW +FaUT-EHc\PrcnHd +$$gc>F`_MDmf3:_rrV>0G5c^eGBs14#'Y62EH-&Bq03*hGB1Fts8Mrr!r%7hqfi-[](H"(iHTSE +GQN&8m.C;YY&=,]!d0@orVllsrr3)6DKpI'GR/J6EcH/DGBeE3GQrA +"TS,ao(25="nqurrr;u=ncJ@Vrm:ZHk^7[THO"kDI!_!%H$oL9"aYNAI!^8>HNJHI +rq69reoZ1_H@(!dqKiNrH@1*eG)!DRHMi*kGD>nfrrKoVqg/BfRJus\!<2lq&cU+!H$ajbH@(!b +H[L0dH[:):HNe_CHZ5YVrVuosli.7is8VtcE-ZhWo6U^iH[:'dF,KAQrrT($m +qjhbRrHeTnH[Pg>"akZDH@1& +"TS,ao(28>#4V?ds8N&ta8Z;@oCDGCmIC>Kq#8Y?!pFuUrd"fpH@'t#H?af6H3JS?H$ajarH\Nh +h#@!H"4hR?H2`*iHhr$pH[0sbH?FnJI!HGdErrV5,H2MsiG^]#PrrK?Cqg& +"TS,ao(28>#4_Ees8N&ta8Z;@naQ)?mIC>Kq#8Y?!pFoQrceZlG^4OpG]nB0GQi;9GBnFYrHJBd +h#@!H"4hL8GQ)geH2;alH$=OZG]SSEH[#C4!d01kq#:B1E;Ok]F-ln#rrE&qrs&JIF*;ePH2`$i +GBeE4GQE#6qfi9gH$F4urVccrrp0Rirr<#qRr3FqGOp%aH$FOYG]8K)mf*?hE-M2(#^:9rs8W)u +s8MZj"ocqlFa/31GRJ_@H$FRXH$=OYG^9:5$$L4#s8N&ts8W)nrt4=9G^"CWH$FOYG^+FXG^"Q% +rVllrrVm-%^i+FAG^=T&GQN)+Wr)f"rr<#mJTgp8!H5RArrV/(GPl[eG'iTJrrK9?qfi0bM>-iG +!rJF)r-/9gG^9:5"aP?;GBnE3GQ`;:E/Eu]s*t~> +W;cqus8KJ,!pG#WrHecsHZmWNFEr9-HNeeDHZHduoD\p.FE`'1HNAM?qKiHpH?Fhoh0F>EHNJDG +q"Xji^iTC"!d:"2mf*I,Fa&1ZHMr0kH@5I6"FYQ;T(Cq@#laLrFEi.ZI!YO6$%.)IH[Bdli;`fH +rr`9#c?B#1!I*#`rrE&rrrUAiFoH^fI/80iHMi*nI!^*][f-.(!<2rs!<2lq!N:#9HNSS>H[Pg> +!dT7_qu6Zqrr33%[<-Y?H@5F5!.=`l"FPH9WVZDi!r%@nqg/?a]_)4*j*Q+MHNJJ@me$M[Y]9Pe +!dKY!rVm0&s8N&uoU0`Erd+0_s*=ljNT1!;s8RT~> +kl1Y^_Z']:s8KJ,!pFuUrH\]qH?IHLF*N'.H2r +W;cqus8KJ,!pFoQrHJQmG]V*FEHZX(GQ<$gGQiA;G]1.loD\m+E-;,(!I8ncGR&M9ELcRXrs8VsWH*-+G^4N-GR8Y?H$FRPM;J:3 +nc&^js3,Q[GQDp8o)A^hrVluua`he)GQ<$cGQ;scGQiA;F`b"fr;QcrrVllsr;QisVJc9U!dAm7 +rceKfI-gb1!<2ut#6(rKFa/+Up36R_rHJHjF`F;Qq#:EiJTgp8!H5RArrV/(GPl[eG'iTJrrK9? +qfi0bM>-uK#lal's8VVTE-D5*!-\!Zs*"ZdMW+U7s8RT~> +!WW/_rrW3"rke[8rj_t0k^7[QHNeQ7rk*Gtqg/[YsIrTa\HMr0n +I!^0dI/\HqH?XJ)mdL/Zrr;ugJ9h$="a>Ulrr;ufrs/Q's4`TVFaF%6!d]3@rd+osH[C'dG]\P] +mf*IXM/digI/SBrH@1$dH%,2[rrE&rrs\o,_0pBMH[:'eH@(&66 +U%&![J,~> +!WW/_rrW3"rke[8rj_t0k^.ROH3JE5rk*Gsqg&6fr-AHfG.%8EI,%kh>[YsIrT^ZH2W$l +H[9s`HiAUlrr;ufrs/Q's4`TVFa^KorVm3's8VepH?4=XH2`0iHN/?jH3AM9FJ84% +s*t~> +!WW/_rrW3"rke[8rj_t0k]q@KGR/?4rjm5mG^+E2GQ;scGQW#/Zi'@n"2fD'G5-:gH$4=KMW=`d +Fa!\,!d0.jq#:]8Dfp;KF`hnKQ2^7P%0$:LIrKRUGBe=WH$B74!-eEe#'Y<8Dg8Veh>[\tI;a:R +GBWt1%!d)AG^4IWG^"7MTBu%H"oeQ$npYcZGQi5@p&>!jnc''ts8Ui5EcZGLG]n4SH2`$oGBe@T +H$++Wb3o95m>5b*G^974#'Y?:H$4T'rVllsr;R3)s1s,&G'J4VGBJ(SrHS?f#'bEEHZVOH$4B1GlN'f +GQ`53EhW"#s*t~> +"TJH#s8VEa_>id!!<(4C!pG#Wqg/TkaT):jO*#Jgrd"iqH[9sZFc4WGn,E[NSpYR&H$Xg_rd"fl +Edb1_rr:LIGQrJ@H$X[hq#(-lrr2p(_/XaHH[0p`FIVb!!<2ut%-jsGF`_hSH$Xj`H@,X;"a>$1 +JuIT+rrE&TrtFV$Irf[UH?jj`H@1$bH$4:TONZng!LS'-HNJ8[rr)isrq-3jrr)j&qTkCLF*2_S +H2MsmH$47MJun;*rs/PjU3(I%H?oI8"FGE;GjY/'#3;Y2F*2\Prd"QkrH\ZnGB7q^Y3#?V"8@In +HiA9mH[0VCo`#$QH?a`6H3/A@me$M[YB'Mc!d9Itp\tR!s5gM9F)uMNH2MsoH['[RHBQMPrqueH~> +"TJH#s8VEa_>id!!<(4C!pFuUqg&NiaT):jO)oAdrcncoH?jaVFc4WGn,E[NSpPI#G^4U[rcn`j +Edb1_rr:LIGlN'mG^4Idq#(-lrr2p)_/XaGH?a^\F.*!rrrE&trs\1pJ95jUH?a^^G^4W7Gm/A3 +FFpIKrr2uthZ"8QZ%$e7GBnFZH$Oa^H$FIQG`^,5rrJL0qg& +"TJH#s8VEa_>id!!<(4C!pFoQqfiBeaT):jNH&r\rc\WkG^"=NF,A3AnG`gnh4/b/FEVkQG5c[j +Ec?B.o)A[=rc\BE!<2ut$GgY)GBe:TGB')NnG`Lfrr3DjX+#)/FEhtQH$4CVrc\Nf +E,pK+h>[ESrndYgkc]DRE-6AJG^"@WGB\4OEH[Aal2LdMF8L1`ELd%,rrE&jrrE&srs8DEP&tY` +Fa/*-G6W53E,^<,lg=]Wrp?A!E-?GKrHABhG&qoqo`#-VUO7$$FE[Y-!-nHd#'P*-F+^RUp&>Bn +Jou<]GB\:TDS,Q@!oeHJr-&3cHg^P+!O$J>G62lBqY1!qrr;#^IW9@LGl)[jG]e%FGE9oHrqueH~> +!r8OXl^J'FZ2O\%rl>$Drq2qQS"#q:n!a?BbKp1ik^7[QHNA91rr3H)cD$&?GBS1RI#"?=p@/(g +rr<#ts6$kSIsM$:'7#+o]'KCqs8V`Ih;6rChVR&GrqcWsrr;HAr8%D.!9EDE"n0U/N.$$NFpE59 +H\%?XbOGN2!<1gS'`S.4m)Gr`I=-3^GBS7YKpf=)r;Q'_"TJH#\T@Xp"EMBZs8MTh!<2ip&cC7i +RY6$5G'A+PH[q +!r8OXl^J'FZ2O\%rl>$Drq2qQS"#q:n!a?BbKp1ik^.ROH3&-/rr3H)cD$&?GBS1RI#"?=p@/(g +rr<#ts6$kSIsM$:'7#+o]'KCqs8V`Ih;6rChV?oErqcWsrr;HAr8%D.!9EDE"n0U/N.$$NFpE59 +H\%?XbOGN2!<1gS'`S.4m)Gr`I=-3^GBS7YKUB.'r;Q'_"TJH#\T7Rn"EMBZs8MTh!<2ip&cC7i +RY6$5G'A+PH[q +!r8ITqjHuD"dZFlrr;uh;$rfqYp`us6n^sh>Z.1g>(cRrrql4To+2A +rH&9eG'SS!V9/6+rrE&SrtPJ4s6Rb'N-fkmF`heMH%M?fhYdB>rri?$rjQkDGQ`!$s8W)hrrE&p +rt51\[?uPkGB@tLF*W4sVT\K.li.Lps3[ZsH?OCOF`_hTM4XG?rrW3"rr2otrqud1m)5KPH$=CQ +F*2SKH%D0\ch.8;rq??nr8?<.gB??fh:qAirrVuOgA]k+h#uU2s8W)mrrDEbg]-"-h#cBjrq$.$ +lc#]ZH['[SFEMeRL7>[/r;$AC~> +!r%1dqf_LP"`T\)s8W)=rs/PoHZXFTG'LYs~> +!r%.blZEAMPQ(U^rl>$DrpkDWF`qnNnT=qWF_eJ4rrVD2Gl)dfFNF@Z#P@93cHal%p$;VXrr2p) +rr)6>cHsnonG`FbrrE&rrrE&srrE&rrr`9#s8N#t"TJH$rr2 +!r%(^lZ35IOoGC\rl>$Drpk>SF*)JFnT+eSF(r&.rrVD0G5HLbEle.X#k[<0bfnGroDS%U!<2ut +$NC"kgs49mh!Y1@r;Qcrr;QcrrVllsr;Qlus8W)trri?$s8N#brrE&prr`)`j3[bN#1r,-r;Zfr +fDbjMrr3?%m,cU>d*C>/o)8Oe!<2He!<2rs!P!1JGQW/8j8SWL#QFc&s8N&urr)j"rr;ZUf`',$ +cJn9gs8W)urpKddrr2p*rr;WSda-:dcf"9frVlrus8N#t!ri6!qYprulf$17cHXSckO/6;rrE&r +rr`9#s8MQg!<2or!ri6!rVllsn,ECerr2utrVm*$s8N&ts8Drs%JoGQcHa\Yf')c)rr;uns*t~> +"8IOoI-c1_FdN%+rl+m>npu+7m!AnV\c2X/rmUlKk^7[QHNA91r;Qlus8W)lrrE&lrrE&srrE&s +rrE&irrE&orri?$rVulqrrE&XrrE&jrrE&ErrE&srrW3"rqucrrr)isrp0RbR!/FT"+5 +"8ILmHgH%]FdN%+rl+m>npl"4m!8hT\c2X/rmUlKk^.ROH3&-/r;Qlus8W)lrrE&lrrE&srrE&s +rrE&irrE&orri?$rVulqrrE&XrrE&jrrE&ErrE&srrW3"rqucrrr)isrp0RbR!&@R"+,3QqtpBn +rpp'hrr)iurr;ulrrE&_rrE&trrE&qrs/Q'rr<#ts8N#t"TJH#s8M3]!<2]l!ri6!lMh%es8N&u +rpp'krr<#trVllsrr3'!s8MNf!<2rs!<2lq!<2orJ,~> +"8IFiH0fbYF-Z\'rl+m>npYe,m!&\P\,QF-rmUlKk]q@KGQDj+r;Qlus8W)lrrE&lrrE&srrE&s +rrE&irrE&orri?$rVulqrrE&XrrE&jrrE&ErrE&srrW3"rqucrrr)isrp0RbQ?3"L"*o!KqtpBn +rpp'hrr)iurr;ulrrE&_rrE&trrE&qrs/Q'rr<#ts8N#t"TJH#s8M3]!<2]l!ri6!lMh%es8N&u +rpp'krr<#trVllsrr3'!s8MNf!<2rs!<2lq!<2orJ,~> +!r%@ml[&_VQN$m_rrE&>rrqtEG^FgamX#%U])VcWrrVD3H2DpjFiaU^rVllsr;Qcrqu6`ss8M<` +"9/?#rr)isrr)iurr;unrrE&qrrE&qrrE&arrW3"rqcZprr)j!rr<#teGfOJq#:?nqYpQpmJd=g +s6>#Yr-JQeWrN+uo)Ajls8W)trr2utq#:?nrr3*"s8W)VrrE&rrrE&trrE&trrE&hrrE&brrrE% +s8N&trr2uto)A^hr;Zfr!WW/urrE&hrrE&rrrW3"rr2otrpg!grqHHmrr2qJ~> +!r%=klZrYUQN$m_rrE&>rrqtDGC"U]mWntS\c;ZVrrVD2Gl)dhFNFL]rVllsr;Qcrqu6`ss8M<` +"9/?#rr)isrr)iurr;unrrE&qrrE&qrrE&arrW3"rqcZprr)j!rr<#teGfOJq#:?nqYpQpmJd=g +s6>#Xr-AKcWrN+uo)Ajls8W)trr2utq#:?nrr3*"s8W)VrrE&rrrE&trrE&trrE&hrrE&brrrE% +s8N&trr2uto)A^hr;Zfr!WW/urrE&hrrE&rrrW3"rr2otrpg!grqHHmrr2qJ~> +!r%7glZ`MQPlC[]rrE&>rrqtBF*;hQmW\hO\,ZHTrrVD0G5HLdEle:[rVllsr;Qcrqu6`ss8M<` +"9/?#rr)isrr)iurr;unrrE&qrrE&qrrE&arrW3"rqcZprr)j!rr<#teGfOJq#:?nqYpQpmJd=g +s6=rTr-/?_WrN+uo)Ajls8W)trr2utq#:?nrr3*"s8W)VrrE&rrrE&trrE&trrE&hrrE&brrrE% +s8N&trr2uto)A^hr;Zfr!WW/urrE&hrrE&rrrW3"rr2otrpg!grqHHmrr2qJ~> +!qq=nrd+Wmms>+YR/Fl%"nR:jI!U20HN\_BEkD=trrVD3H2DpiFiaRVrrE&trrW3"rpKddrr2ot +rr)iurr;ukrrE&qs8W)trrE&krrE&drrE&qrrE&trs/Q'rr<#ts8Moq!<1@F!<2ut"9/?#rpB^h +rr<#t`cM$(!dDuirVllspAY3ns8Mrr!<2or"9/?#rr2otrqucrro3q]rr<#ts8N#t!<2Zk!<2rs +!<2rs!<2cn!<2]l"9/?#rr2p"rr;usn,ECeq>UHoo)A^hq#:Hqs8W)qrsJc*s8N&urr<#trq-5@~> +!qq:lrd"Qkms5%XR/Fl%"nR7hH[0u-H3AS?EOu.rrrVD2Gl)dgFNFIUrrE&trrW3"rpKddrr2ot +rr)iurr;ukrrE&qs8W)trrE&krrE&drrE&qrrE&trs/Q'rr<#ts8Moq!<1@F!<2ut"9/?#rpB^h +rr<#t`cM$'!d;ohrVllspAY3ns8Mrr!<2or"9/?#rr2otrqucrro3q]rr<#ts8N#t!<2Zk!<2rs +!<2rs!<2cn!<2]l"9/?#rr2p"rr;usn,ECeq>UHoo)A^hq#:Hqs8W)qrsJc*s8N&urr<#trq-5@~> +!qq4hrceEgms"nTQMeZ#"nR1dH$=Q'GQ`;9Dn,enrrVD0G5HLcEle7SrrE&trrW3"rpKddrr2ot +rr)iurr;ukrrE&qs8W)trrE&krrE&drrE&qrrE&trs/Q'rr<#ts8Moq!<1@F!<2ut"9/?#rpB^h +rr<#t`c:m#!d)cfrVllspAY3ns8Mrr!<2or"9/?#rr2otrqucrro3q]rr<#ts8N#t!<2Zk!<2rs +!<2rs!<2cn!<2]l"9/?#rr2p"rr;usn,ECeq>UHoo)A^hq#:Hqs8W)qrsJc*s8N&urr<#trq-5@~> +"o![qH[C),HN\JXrVul9rs&(GH?ssbI.2IaHuZaDrrVD3H2DphFiaFZ!<2rs!<2ip!<26_"TJH# +s8Mfn!ri6!rVm!!s8W)jrrE&arrE&qrrE&frrW3"rmUlIrr)isroj@`rh4E3HiJBmJFE"-s8N&u +!<2fo!<2or!<1dR"9/?#rql]qrqZQqrr;uprrE&srrE&lrrE&err`9#s8MZj!ri6!rVlrus8MNf +!<2or!<2lq!<2ut!<2cn!<2HeJ,~> +"o!XoH?sl)H3AAWrVul9rs&(FH$Oa^Hgl=_HZ6OArrVD2Gl)dfFNF=Y!<2rs!<2ip!<26_"TJH# +s8Mfn!ri6!rVm!!s8W)jrrE&arrE&qrrE&frrW3"rmUlIrr)isroj@`rh4E3HN/6kJ+)n,s8N&u +!<2fo!<2or!<1dR"9/?#rql]qrqZQqrr;uprrE&srrE&lrrE&nrrE#nrr`9#s8MZj!ri6!rVlru +s8MNf!<2or!<2lq!<2ut!<2cn!<2HeJ,~> +"o!RkG^+H#GQ`)SrVul9rs&"BGB\=VH16%[H#C+;rrVD0G5HLbEle+W!<2rs!<2ip!<26_"TJH# +s8Mfn!ri6!rVm!!s8W)jrrE&arrE&qrrE&frrW3"rmUlIrr)isroj@`rh4?1GlMsgIIH\*s8N&u +!<2fo!<2or!<1dR"9/?#rql]qrqZQqrr;uprrE&srrE&lrrE&nrrE&orr`9#s8MZj!ri6!rVlru +s8MNf!<2or!<2lq!<2ut!<2cn!<2HeJ,~> +$ho="H[C-eH[L0eI/\HmHN&6mI!^2=HNJ>WrVlisrpTjgrr;rXrrE&qrs81HH$ajaH[:#.HNA/u +ci4(1I!PU9!HlJ7s/uA/q29KEH[L0eFdW,Ys.01?~> +$ho9uH?spaH@'saHiAMPJcD;@J,~> +$ho3qG^+LYG^4OYH2`$gGQ)ggGBe?2GQMrRqs47arVlcnjSo5Zqu6`gIWk%%!H5HnrrVD0G5HLb +El`h3Y5\k)LimreH$FRSQ2Q:6Sc=3~> +!r%@nqKiEpH@'s`H[Pd=#(1`DHZk_RlMgk`rr2utrr2utkl1Y^rVm#kJU)TgrHeftH$aj_H$ama +qKi6`]$LBXk^7[QHNA91JcE%U#QFc'rn_pIHMr0kF0^AsSH"*~> +!r%=lqK`?nH$Xa\H@,U:"abN@H?>JOrrE&fs8N!!s8N#rrrE&^rrE&srrVbAGl)dmH['j^G^+O\ +H2;gfEOjEq!pFuUqg&9baFXAsrs/Q's8Ll"H?oI8!HPJss.'+>~> +!r%7hqKN3jGBe=TG^974#'kE;G]f>MrVllrlMgtbs8W)^rrE&srrVb?G5HLiH$4FVG'8+TGPZOb +Dn"'m!pFoQqfi-^aFXAsrs/Q's8LesG^'+2!H>8os.'+>~> +!r%@nqg0'*HZs^bIs$!_H[L0eI!g9aQi@!arpKdirr;uss8M$X#QFc'npu(5HMr0uH@'d\Jphcc +I!^3frHeQc]$LBXk^7[QHNA91JcDnQ$+b/(I!^3fH?dqjs.'+>~> +!r%=lqg&m%H?OL^IWTd[H@'saH[C'_RJc4Is8M'Y"oeQ%npku^H4,"EFF&OeFEW"WH@,U:!HGZr +rrVD2Gl)dfFNB%5Y5\g>EI)tXH@'p]e:IXis*t~> +!r%7hqficuG'%kTHua@SG^4OYH$OXTPlLd_rTsRar;ciVrrrE%s71V^qfiKmG]J%ZHZF4RG^+N4 +GQD`lci4(1H$9(0!HQ84s/uA.\8QV;G^+LXFjbj@SH"*~> +!r%@nqg/`tFHtAIlH4p+I!U-erd+]kQi?=N"9/?#rVHNorosF_rr2p1npu(5H@(!bH[9q7g[jXL +LNIq@HNA/uci4(1I!PU9!HlJ7s0)G(rK_[+HiJBmK_'cpSH"*~> +!r%=lqg&ZtFHtAIlH4p+H[0pard"cjQN$m`s8MHd"9/?#rql]qrosF_rr2p!npku`H4,"EH$?1@ +oB=5MFF3n2!HGZrrrVD2Gl)dfFNB%5YQ"t.Q?IS$H?sj^KCaZoSH"*~> +!r%7hqfiNmEg+rCkfAL#H$=LYrceTfPlC^_rU0[irVuios8DoprrE&_rrE&trrVb?G5ZXnGBe=S +V;(V*`J&>Xqfi-[\'P'Uk]q@KGQDj+JcDqR$N632G^4OYGB\W0JcD8?J,~> +!r%@nr-K9.G,"j4s8N&dM0=5mH@1*eFdW.-rr2rsli."aro!eZnpu(5HMr0kFL_8K!pl(nrd+co +H[BeEci4(1I!PU9!HlJ7s0DY6rr<#`I +!r%=lr-B0+G,"j4s8N&dM0=2kH$amaFdE"(s8W)frrE&srrE&TrrVbAGl)dfF1D/J!pl(nrd"]m +H?sSAci4(1H[,F6!HcD6s0DY.rr<#`I +!r%7hr-/s%FJ/L0s8N&dLNIccGBnIYF-le(rTsOarVlfsr87MUnpYcZGQDfmr;Qi`OECJH"F#*8 +Dn"'m!pFoQqfi-^aFXAsrrrE%s6=rTrceQkG]9;SJcD8?J,~> +!r%@nr-SHi!9a=\"TJGGGBj(5#CLZ\rVlisrpKgdrX8c*rr<#ts8W)us8MQgs8N&u!<2rs"S.+h +H[>[ +!r%=lr-AEiHKY8,"TJGGGBj(4"+,0WrVZ]crr2otrVlg&rr;uts8N&urpg$grr;uurr)iunpku_ +H3/;Hp&"aqc?=M[H$aj`EOjEq!pFuUqg&9baFXArrsSi+a)lWSH@'saEk[,)S,\!~> +!r%7hr-/9eGj#&*"TJGGFa!_.#^LKXqu-Qns8DEd%K6>,rVuirrr<#ts8W)gs8W)urrE&srrVb? +G5QRdFb]Sdrs?nkG^+FXG^+/9ci4(1H$9(0!HQ84s0;S3rr9rXG^4OZG^+2?JcD5>J,~> +!r%@nr-JlsPPkI\rr<#tnUPn3I/\HtGaJC.s8N&tnc&jns8N&trr;uss6BRbr;ZcprsA7IH$aja +H[0\@qu7$&n:Yt4H[:$cEk9Ts!pG#Wqg/?daFXAqrsJauFaJF\H[C$`iIV#us*t~> +!r%=lr-AfqPPkI\rr<#tnUPn2HiAJ,~> +!r%7hr-/ZmPPkI\rr<#tnU>\,H2`$iEL6\(s8W&fs8W$#rr)fqrVcc]rW<#trr)iunpYc\GQN)/ +[ep(3rpGA[H$FOXG]1(;rrVD0G5HLbEl`h3Yl=e(SoXaRs*"J%JcD5>J,~> +!r%@nr-JHdUAb)qrr<#lJU%*>#BlF3rr;oNeaV0"f%8U*g=GQhs8MbcR[`f:s-j+\R[)"orsA7I +H$ajaH[9bSqYpWqO*CMK!HPctrrVD3H2DphFi].6Yl>.(KR%ojH@(!_NVibTJcD;@J,~> +!r%=lr-ABbUAb)qrr<#lJU%*=#BcF4rr;erW:?qfWXPi+WMIrAs8MbcR[]i9Rff1LQ-'%*!qLkd +r-ABbaSPo +!r%7hr-/6^UAb)qrr<#lJTgs9#BQ7/r;Z7^61I8P6U+"(6:*u-s8W)mTUM@?nX9EH".YgFao;;A +npYc[GQDg*qYpWoNHP/D!H5HnrrVD0G5HLbEl`h3Yl=dsJp.':"EfY"s8ITLSc=3~> +$MT7"H[C-eH?b>BrVmK/s6G)ZH[C'cHZk_Rs8W#?`qd[d`lH0Aa2c9AaN)?Ba2l0Urr35qHusOS +G'8*.FoZaaFoZ[aGQ)adCpa3A"S.+hH[>[<"E^XCs8Mus!p=oVr-JHb]$UHZroncSqg&9baSu2> +rdk*XrsSi+eTc@eH?spcF0:)oRf@m~> +$MT3uH?spaH$>/@rVmK/s6=uWH?sj_H?GPPs8VbRL\QZ8LPUbALPU_ALPL\BLk*2rdk*V +rr^eqG^KF9!desjJcD2=J,~> +$MT-qG^+LYGBJ`8rVmH.s6+cQG^+FWG]T,Js8VBpo)Jakp](;:rr3&lH?&n)!-J0\!-J-[!-8'\ +rc8*SZMsk*npYc[GQ`#`s8W)srrVA/GPl[dDn"*n"9.J/G5HLbEle7[!<.QL[/U6WF`r'0GQN/0 +XF^D?s*t~> +!r%@nr-JKkGM)op&cVh1[rm%EH@1'dGF/:.s8C7!HPctrrVD2H2DpnFiaU_rr<#tJcE4Z +"obcJH[C/>HNSK9s8ITLSH"*~> +!r%=lr-AEiGM)op')qq2[WHhAH$aj`G*i1-s7VY7q2>N9Nf/jVNJmdps,-us8W(Ls0r"3 +ripKiH@,X;"*Vogrdk*>s*t~> +!r%7hr-/9eFk6Ql')qq2ZuUD9GBnFXFHuh)s6L +!r%@nqg/ZoM:hk-s8U2gH$oU<$%.)DQi6saqT[.Wap,u1bf\&NaSX*\a5[*u"S@4iH[>[<#CLlE +H[L0eI/A6nI!^3\\,QC1npu(5HN&6nH?P\>rr30$a*i5[I/SBmEk9Ts!pFuVqg/HgaT);>JcE.X +"TJ=[GC9C:"+5?Dm=G;+s*t~> +!r%=lqg&TnM:hk-s8U2fG^KF9$%$uAQi6sap6(=/Muefor/:W8qhtQ/_#F?8oRM2aH3\eCH$Xg` +H@,O8"FGH@EOYrI!qLkdr-AHjFdVClrrrDBI +!r%7hqfiHjLXuM)s8U,bG'X(3$$gc;Q2Ua_lOX'l!sSf0#6k81!Vum!!I4VD!q^qbr-/HlG^"CX +G^+N2GQ`;:G]1"hrrVb?G5QReGB9)4rr30$`HufRH2VsgDn"'m!p4cOqfi6aaT);>JcE.X"TJ=X +FF!k1"*o'=m=G;+s*t~> +!r%@nqKiNlH_mpLT6>L.HN&6tH@0n&rVuoobfKS%#0>!2aNDZKqoSr[iVriYoRM5aHNSSAH[>[< +s*OioI/J[<$[d;DL9.P]S90"&I/Js*t~> +!r%=lqK`HjHDI^HSoo:*H2`*rH$a\#rVuokPDf3p#*"P"NJraQqhtQ/_>aH;oRM14Hi86mH$aj_ +rd+Tk!IB+jH3&#prr3&jJ9_!<$[[2AL9.P]S90"%Hi/0jEOjEq!pFlOqf`-^a8c-is0M_6i-'9f +G^"@TEKpG%rdk*>s*t~> +!r%7hqKN +!r%@nqg0-,H[9aRF*2eUH[L0dI!^3`Qi6s`qT[+WaoT].rl>,^bPK?^a5[*u#5!FkH[:$doQpRc +rd+]oF1;/K$hAjoH[:$cI!^6fGQ)R^Fng:aEk9a"#6+Z%s6>GqqhG3)c2IYBrdk*Xrs?JkLkpeA +LPLGorr2utJcD;@J,~> +!r%=lqg''*H?jONEccSQH@'s`H[:!\Qi6sap6:I1Mu\e7NW4n:NVeY8KY[Te!q_"frd"QkoQgLa +rd"WmEju&J!qLkdrH\TnH@'s]rc%p[pj)s\\^UQ_rr;utlA:8mLB3%PrVllsJcE1Y$,D(ILk^_@ +LOm/ +!r%7hqfip&G^"+FE,p/IG^4OXH$FRTQ2Ua_lOa0n!s\u1!sJc."TeK&!Goqh5'%c2IYBrdk*Xrs?JiL5(A9 +KnY#irr2utJcD;@J,~> +!r%@nqg/npu(5H@(!dH[:$cI!^3fH@5^="akWCHZH^IrrE&rs82Tsq"a[_rr<#t +JcE1Y$3'erq"a^[q=s]8s-Wh:~> +!r%=lqg&6frH\Hjrd#'$H?sp`H?s_#rVuokPD]-orJL`7N/dao!fM`Irr3&lJ9_'>$[[2HH?spa +H?jjaH2;gfEOYrI!qLkdrH\ftH?jg_H[:!bH$fO:"abN@H?$LFrrE&rs82Tsq"a[_rr<#tJcE1Y +$3'erq"a^[q=s]8s-Wh:~> +!r%7hqfi*brHJ +!r%@npj3*jH[:)=HiJKnHO5(HG*i1-s8(!]q8rr`bK7fIbK.m(aoTQBrr3,nIsHBer-JTpH?sd[ +H2`0jI/\HoHuc^qrrhnDH$al:HiJI"H@1'dI!^3dI!kj=!HPd%rrW3"rqHEmrqcWprdk*QrrE&s +rrE%Ls.'+>~> +!r%=lpj*$hH?jl:HN/?lH3nqEFdN(,s7V\7q2>Q~> +!r%7hpilmdG^"H4GlN'hGR8Y?F-Z_(s6C6tq#gWt"Tn`)"p5,-!s&FIrr3&lI~> +!r%@npj3!eq0N*frd+lnQi6saqT[.Xap,r1f[@mbbPK?^a5d1!!q_"gqg/QqH$4n3P'_BJHNA/r +rr3,lJU)TgqKi^"H[L3fH[:'dH[:$cEk9d#!<2?b!<.QL[f6@,JcCo5J,~> +!r%=lpj)pcq0E$drd"flQi6sap6(:.N!>*$V5''-Nr"\8KYdZf"S@4hH@,U:#CC] +!r%7hpild_q02m`rceZhQ2Ua_lOX*m!sSf33\^a +!qq7lrd"WkH@#+.#BlI3s8Vr>aSs +!qq7lrd"Qims5dmQi-m`p61DoN/W[SN/NLjkl1M9Q\^RsMueUKrr3&lJ9_'>$[[2GH$-.Yrqk?% +G5?LcEOYrI"7q%fH0fhXEOgZ#JcC<$K)^?~> +!qq1hrceEems#+ZQ2L[^lOX$sr +"8@IoI-c1rG*i1-s8(!\bK.oMaNDNarr<#trqOa[qoSr[iVriaoRM15H[L0eHuljrrrVVDG5HUe +Eju&J!qCedl[&bT\c;^/JcC<$JcCH(J,~> +"8@FmHgH%iFdN(,s7V\7NK&mUNK&\.rr)iun!T(1MueUJrr3>tJ9ZBdH[:!bF1M5K!q(heqg&9_ +\,QC/nUPlMH3A5us8W(Ls+13$s+UK'~> +"8@@iH0fbfF-Z_(s6C6s"pG27"T\ULrr)ir!oP.#qZ?j"GlI^MoR:t.G^4OYH#^=krrVP@FSg:` +DmfTE!qC__lZ`PN\,ZL-JcC<$JcCH(J,~> +!r%@mrH\Hhn9P[hQMpj`q96t'ai_iJ`mO\_rr2p)rp.\Jb0%iKb/WE>rrVhCGl2miGE;XurrL;e +qg/?a\,QC1o7)"3H1#t[H#U9Es+13$s+:9$~> +!r%=krHSBfn9H*tQMpj`ook8jNf8pVMk0_Es8N&urmcmaN/W[RN.\tGrrVhCGl2jhG)uOtrrL;e +qg&9_\,QC1o7(t1GjTbWE4CK!JcC<$K)^?~> +!r%7grHA6bn95FaPl:X^l4 +#l''uH@'sbH@#+.%X"-:s8Vo>aihiIc-=AjrVm'#s8VuAaSa0]`o@!t!q_"frd+`nHZQUkrr_tK +G^TI:!HP[Krs&(FG^4X^HLZ=cH?jMAs8ITLJcC<$K`?Q~> +#l'$sH$Xa^H$Sq+%X"-:s8VbVMMmFPMMm/$rr33%s8DukR#:g#!JA8grrVhCGlE!kH$XM=qYpZk +Km.nBH3&#prr32oJ9Z?cH$Sn*"F5!us8ITLJcC<$K`?Q~> +#l&soGBe=VGB`S%(j2,Bs8V?r!!NH)"TnjIrVccrrVlif*!,s>!<@EErrVhAG5c^gGBe)5qYpZi +K6;J +!r_*5leN3/jo,5ZqTI%)aiMQGaQEO&rr;rr!Rf'eaoTNArr3&lJ9_$>!d\t-qYpWoNd(DJ!HP[K +rrN&TrS7J1nD+0$g[B^nJcC<$K)^?~> +!r_*5leN--jo,5Zp6(;kMiE^TL!K\srVluur1AlEMueRJrr3&lJ9_$=!dSk+qYpWoNct>H!HGUJ +rrN&TrS7J1nD+0$g[B^nJcC<$K)^?~> +!r_*5leMm&j8K#XlOO%!!r`9&!0I*X"8i$J!W3$#!."SD!q^qbrHJBfEPqYQ!r7dsr-/6\[Jp1, +r87J/!8d5$!o2JtJcC<$JcC?%J,~> +r;Zfrm/I4fs8($_rQ52^b1Zdo!<2ut$2)E^b0%iKb/WE>rrVhCGl2mjFeSj6r;QcYqKiEe\,ZL- +s8MBb!<.QLJcC<$JcGcMJ,~> +r;Zfrm/I4fs7VY5rJVDJL9:LTs8W)us6G]'N/W[RN.\tGrrVhCGl2jiFJ8a5r;QfZHi&*nEOYuJ +rr;uarrE%Ls+13$s+14Ms*t~> +r;Zfrm/IIms6C6t!s8]/"p%EqrsS`(cisOR!s/Q,!-nMC!q^qbr-/ +r;Qcrm/I:hs8Vo?aiaV+"N\d-nG`Fes8E&Oans3]a5R$t'(g^!H[C-dH[:"ps8N&ts8Sg8qg/?a +\,?7-rr;ucrrE%Ls+13$s+11Ms*t~> +r;Qcrm/Ih"s8VbUM2R:NN/`dTir8uXrVuo&LAQo1KYdZf'(g^!H?sp`H?jhns8N&ts8Sg8qg&9_ +\,?7-rr;ucrrE%Ls+13$s+11Ms*t~> +r;Qcrm/I=is8V?r!<<6#!=9%Frr<#ts8Q%!qZ?j"GlI^UoR:t.G^4LXGBhpCrr;utrLe3.GQD`j +r;Qits8MHd!<.QLJcC<$Jc>`MJ,~> +s8N)ukl2=qs8($_b/_]Hb0.uTkPYA[q;99iaoTQBrr3&lJ9_'?%"*DKG)"KFs8VSjFa +s8N)ukl2@rs7VY5N/WdVMN!CWc2%A=n[XI6qhtQ/_Z'Q:oRM2cH45.HH?P%lrr<#fX`\pdH3&#p +q>UHoli-taJcC<$JcCE'J,~> +s8N)ukl2@rs6C6t"U"l/"9AKCP48MOjCeMnqZ?j"H2dgFoR:u_GRSkBG]\Vdrr<#fX)iL^GQD`j +q>UHoli-taJcC<$JcCE'J,~> +j8T2Wc,ok*s2bMedb`d)b07s(aoTK?rr3&lJ9^s<$@R,FR]rcJFF&:[r-JHb[t4R1s+13$s5a31~> +j8T2SP)9'ps,., +j8T2H&-;Y1rW36VARQkb!;Zcu!I4VD!q^qbqfiHoFEj.SVM9)7G^'(1!H5Ass+13$s+142s*t~> +j8T2WbfTb)s2bMhaiDEBb0.p(aoTQArr3&lJ9_'?!.+Wk#^goAF*)\SI!Y[:!HPZ#s+13$s+142 +s*t~> +j8T2SPDT0qregu +j8T2H&-;Y1rrN0&r;Zm$#Qjl*! +j8T2WbfT\'#KY'2aih`IbPTE_a5R$t!q^teqKiKoI!^3dI!^3fqg/?a[t4R1s+13$s5a31~> +j8T2SPDT*os,I&:"-/>!NVeY8KYdZf!q^teqK`EmH[:!`H[:!bqg&9_[t4R1s+13$s5a31~> +j8T2H&-;S/!X/T,rW3*("T&9%!I4VD!q^naqKN9iH$FRXH$FRZqfi-[[=S@/s+13$s5a31~> +j8T2WbfTY&"3J^.bP93\a5R$t#5!FjI!g9gom6afH[Pg>!HPZ#s+13$s+142s*t~> +j8T2SPDT*o"c\G!N/NShMueUJrr32pJ9ZEfH@,=2!df6?rd"Tb[t4R1s+13$s5a31~> +j8T2H&-;S/! +j8T2Wc,oh)"O"s1bKKY&!QX0urrhtEG^Fi4HNe_BI!U-crHeQc[t4R1s+13$s5a31~> +j8T2SP)9$os,@2@Mi3ORNV\S7KYdZf"S@4hH@,C4"aPE@H$Xc7H3&#pJcC<$JcC<$jSs`~> +j8T2H&-;V0#6Y&0"U+u/!W)s#"T`lIrrhtCG'J<,GQi;9H$=LWrHJ?][=S@/s+13$s5a31~> +j8T/Xc1oEdbK@oIb0.uRr5o)aa5R$t#kWXlH[C'dI!Ya<"+#?AHMMmgEjpW"JcC<$JcFg2J,~> +j8T2RP)B'o#)eG"NJrdRqhtT7KYdZf#kWXlH?sj`H[5R9"*o6>H22aeEOUN!JcC<$JcFg2J,~> +j8T2H&-DY0#6b21! +j8T2Yc,oe)s2kMgbf\#Lb5KKcb0.icrr3&lJ9_!=$[d;II!^3dH[L0eI/J +j8T2RP)9!ms,7#;N/[aqrepf8!fM`Jrr3&lJ9_!<$[[2FH[:!`H@'saHi/0jEO^T"JcC<$JcFg2 +J,~> +j8T2H&-;S/#6b23"9S`,!WE0(! +j8T2Yc-,q*!mAa/rQ>2`qoJlXiVri[o7(q.GOB\WH#U3Cs+13$s+142s*t~> +j8T2RP)9!m!f;hnrJ:T6MM_=i!f;NDrr3,mIs-$ZmWS_WDmk5sJcC<$JcFg2J,~> +j8T2H&-;D'rrN-"!!3'!!W`:Drr3,mI<9URmWASSD7"loJcC<$JcFg2J,~> +jSo>]qpE[Xc3DV +k5PVas8Mb^P4=h:PlHpKP`3W]rr_qOJV!6@"G;;Q]`*K^JcC<$JcFj3J,~> +jSo>[lld#3'F,Bf().Jt%tOZZ"8.J"J*qgiJUi*[rdk*#s+13$s5j92~> +jo5J_s8Dlmn,*@crVZNjqu6TurV6-]q!n+Yp]L6bp\TOAJcC<$JcFg2J,~> +k5PVas8W&nq!n.bqYC!`qYL$crr3-"q"OOXnb<(Y"8;Naqgncus+13$s5a31~> +kl1nds8W&tqsa.Gn-ACNmdTZ6nFlk]"TA,gp%IqMrq6Egp\TOAJcC<$JcFg2J,~> +%%EndData +showpage +%%Trailer +end +%%EOF diff --git a/AspectC++/doc/images/ps-logo.pdf b/AspectC++/doc/images/ps-logo.pdf new file mode 100644 index 0000000..9a97b79 Binary files /dev/null and b/AspectC++/doc/images/ps-logo.pdf differ diff --git a/AspectC++/doc/images/ps-logo.png b/AspectC++/doc/images/ps-logo.png new file mode 100644 index 0000000..4a83434 Binary files /dev/null and b/AspectC++/doc/images/ps-logo.png differ diff --git a/AspectC++/doc/styles/pure-systems.sty b/AspectC++/doc/styles/pure-systems.sty new file mode 100644 index 0000000..e0e3bca --- /dev/null +++ b/AspectC++/doc/styles/pure-systems.sty @@ -0,0 +1,129 @@ +\NeedsTeXFormat{LaTeX2e}[1994/06/01] +\ProvidesPackage{pure-systems}[2002/12/18 v0.2 Standard LaTeX package] +\RequirePackage{ifthen} +\RequirePackage{graphics} + +% +% set font to helvetica +% +\RequirePackage{helvet} +\renewcommand{\familydefault}{phv} + +% +% setup page geometry +% the geometry package works better with pdflatex +% +\RequirePackage{geometry} +\geometry{a4paper,dvips,pdftex,textwidth=15cm,textheight=23cm} +%\geometry{a4paper,dvips,pdftex,textwidth=15cm,textheight=23cm,twosideshift=0pt} + +% +% setup fancyhdr +% +\RequirePackage{fancyhdr} +\fancypagestyle{plain}{% + % + % two side book class setup + % odd page - left head: chapter - left foot: page number + % even page - right head: section - right foot: page number + % no head on plain pages + % + \fancyhf{}% + \fancyhead[LE,RO]{\slshape \rightmark} + \fancyhead[LO,RE]{\slshape \leftmark} + \fancyfoot[LE,RO]{\bfseries \thepage} + % + % rules for head and foot + % also on plain pages + % + \renewcommand{\headrulewidth}{.4pt} + \renewcommand{\footrulewidth}{.4pt} + \renewcommand{\plainfootrulewidth}{.4pt} +} +\pagestyle{plain} + +% +% Variables to change some details +% +% version number for this document +% +\newcommand{\@version}{1} +\newcommand{\version}[1]{ \renewcommand{\@version}{#1} } +% +% +\newcommand\pslogo[1]{\gdef\@pslogo{#1}} +\pslogo{} +% +\newcommand\otherlogo[1]{\gdef\@otherlogo{#1}} +\otherlogo{} +% +\newcommand\remark[1]{\gdef\@remark{#1}} +\remark{} +% +\newcommand{\doctype}[1]{\gdef\@doctype{#1}} +\doctype{Studie:} +% +\newcommand\credit[1]{\gdef\@credit{#1}} +\credit{Diese Studie wurde durch die\par +\vskip .3cm +pure-systems GmbH\par +Agnetenstr. 14\par +39106 Magdeburg\par +http://www.pure-systems.com\par +\vskip .3cm +erstellt.} + +% +% +% +\newcommand\layoutlogos{ + + \newlength{\@pslogowidth} + \newlength{\@otherlogowidth} + \settowidth{\@otherlogowidth}{\@otherlogo} + \settowidth{\@pslogowidth}{\@pslogo} + + \noindent + \begin{minipage}{\@otherlogowidth} + {\@otherlogo} + \end{minipage} + \hspace*{\fill} + \begin{minipage}{\@pslogowidth} + {\@pslogo} + \end{minipage} +} + +% +% redefine \maketitle macro +% +\renewcommand{\maketitle}{ + \null + \thispagestyle{empty} + + {\layoutlogos} + + \vskip 3cm + \begin{center}\leavevmode + {\Huge\raggedright {\@doctype}\\ {\@title}\par} + \rule{\textwidth}{1mm} + \vskip 3mm + {\LARGE\raggedleft pure-systems GmbH\par} + \vskip 3mm + {\Large\raggedleft {\@author}\par} + \vskip 15mm + {\Large\raggedleft Version {\@version}\par} + \end{center} + \vfill + {\large\raggedleft {\@remark}\par} + \vskip 1cm + \null +% + \newpage +% + \null + \thispagestyle{empty} + \vfill + {\@credit} + \null + \cleardoublepage +} diff --git a/AspectC++/examples/Makefile.generic b/AspectC++/examples/Makefile.generic new file mode 100644 index 0000000..2e02c80 --- /dev/null +++ b/AspectC++/examples/Makefile.generic @@ -0,0 +1,44 @@ +CXX ?= g++ +ACXX ?= ag++ + +PROG:=$(shell basename $$PWD) + +SOURCES := $(wildcard *.cc) + +JUNK := Junk +OBJECTS := $(addprefix $(JUNK)/,$(patsubst %.cc,%.o,$(SOURCES))) +DEPS := $(addprefix $(JUNK)/,$(patsubst %.cc,%.d,$(SOURCES))) +HEADERS := $(wildcard *.h) +ASPECTS := $(wildcard *.ah) +INCLUDE_LIST := $(patsubst %.ah,-include %.ah,$(ASPECTS)) + +all: $(PROG) + +run: all + ./$(PROG) + +$(PROG): $(OBJECTS) + @echo Linking $@ + @$(CXX) $(CXXFLAGS) -o $@ $(OBJECTS) $(LDFLAGS) + +clean: + @rm -rf *.o $(JUNK) $(PROG) + +$(JUNK)/%.o : %.cc + @echo Compiling $< + @$(ACXX) $(CXXFLAGS) -x c++ -c $< -o $@ + +$(JUNK)/%.d : %.cc + @mkdir -p $(JUNK) + @$(CXX) $(CXXFLAGS) -x c++ -MM $(INCLUDE_LIST) $< | \ + sed -e "s/$*\.o/$(JUNK)\/& $(JUNK)\/$*.d/g" > $@ + + +ifneq ($(MAKECMDGOALS),clean) +-include $(DEPS) +endif + +.PHONY: clean all + +# don't remove any intermediate files +.SECONDARY: diff --git a/AspectC++/examples/coverage/Makefile b/AspectC++/examples/coverage/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/examples/coverage/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/examples/coverage/coverage.ah b/AspectC++/examples/coverage/coverage.ah new file mode 100644 index 0000000..848bbc4 --- /dev/null +++ b/AspectC++/examples/coverage/coverage.ah @@ -0,0 +1,80 @@ +#ifndef __coverage_ah__ +#define __coverage_ah__ + +#include +using namespace std; + +// Implementation of a generic coveragemonitor that does not only +// count how often a function is executed, but also which functions +// are not executed. + + +namespace coveragemonitor { + // data structure used to gather information about a joinpoint + struct Data { + unsigned _calls; + const char *(*_sig)(); + }; + + // data structure used to link the joinpoint data elements + struct Chain { + static Chain *&first () { static Chain *chain = 0; return chain; } + Data *_data; + Chain *_next; + Chain (Data *data) : _data (data) { + Chain *head = first (); + first () = this; + _next = head; + } + }; + + // data structure used to combine data and chain elements + template + struct Collector { + static Data _data; + static Chain _chain; + }; + + template Data Collector::_data = { 0, SIG }; + template Chain Collector::_chain (&_data); + +} + + +aspect GenericCoverageAspect { + // Do not measure the coverage aspect's own methods + pointcut dontMeasure () = "% coveragemonitor::...::%(...)"; + + // Specify this joinpoint to define the functions you are + // interested in. + pointcut virtual coverage() = 0; + + // Whenever one of the functions you are interested in is + // executed, save its name and count the number of invocations. + advice execution (coverage() && !dontMeasure()) : before() { + using namespace coveragemonitor; + typedef Collector<&JoinPoint::signature> Collector; + + // As the compiler recognizes the access to the elements of + // Collector it will create a template instance + // for all joinpoints - even for those that will never be + // visited. + // It is necessary to explicitly mention the _chain element + // here otherwise the compiler will not instantiate + // any Chain elements. + Collector::_chain._data->_calls++; + } + + // Print the resulting information. + advice execution ("% main(...)") : after () { + std::cout << "*** Result of coverage monitoring ***" << std::endl; + for (coveragemonitor::Chain *curr = coveragemonitor::Chain::first(); + curr; curr = curr->_next) { + std::cout << curr->_data->_sig() << " was executed " + << curr->_data->_calls << " times." << std::endl; + } + } +}; + + +#endif diff --git a/AspectC++/examples/coverage/main.cc b/AspectC++/examples/coverage/main.cc new file mode 100644 index 0000000..ab3c97f --- /dev/null +++ b/AspectC++/examples/coverage/main.cc @@ -0,0 +1,24 @@ +class MyClass { +private: + void privateWork() {} +public: + MyClass() {} + void work() { for (int i=0; i<2; i++) privateWork(); } + void work (int x) { for (int i=0; i + +void hello(){ + std::cout << "Hello" << std::endl; +} + +#endif diff --git a/AspectC++/examples/helloworld/main.cc b/AspectC++/examples/helloworld/main.cc new file mode 100644 index 0000000..bde3877 --- /dev/null +++ b/AspectC++/examples/helloworld/main.cc @@ -0,0 +1,6 @@ +#include "hello.h" + +int main(){ + hello(); //print "Hello" + return 0; +} diff --git a/AspectC++/examples/helloworld/world.ah b/AspectC++/examples/helloworld/world.ah new file mode 100644 index 0000000..d8ccd6d --- /dev/null +++ b/AspectC++/examples/helloworld/world.ah @@ -0,0 +1,15 @@ +#ifndef __WORLD_AH__ +#define __WORLD_AH__ + +#include + +aspect World { + + advice execution("void hello()") : after() { + //print "World" after execution of the 'hello()' function + std::cout << "World" << std::endl; + } + +}; + +#endif diff --git a/AspectC++/examples/modules/Makefile b/AspectC++/examples/modules/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/examples/modules/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/examples/modules/Module0.ah b/AspectC++/examples/modules/Module0.ah new file mode 100644 index 0000000..2f99a77 --- /dev/null +++ b/AspectC++/examples/modules/Module0.ah @@ -0,0 +1,15 @@ +#ifndef __MODULE_0_AH__ +#define __MODULE_0_AH__ + +#include "Module0.h" + +aspect Module0Initializer { + + //bind to init function and initialize Module0 + advice execution("void Modules::init()") : after() { + Modules::Module0::init(); + } + +}; + +#endif diff --git a/AspectC++/examples/modules/Module0.h b/AspectC++/examples/modules/Module0.h new file mode 100644 index 0000000..9428d23 --- /dev/null +++ b/AspectC++/examples/modules/Module0.h @@ -0,0 +1,18 @@ +#ifndef __MODULE_0_H__ +#define __MODULE_0_H__ + +#include + +namespace Modules { + +class Module0 { +private: + static void init() { + std::cout << "Module 0 initialized" << std::endl; + } + +}; + +} //namespace Modules + +#endif diff --git a/AspectC++/examples/modules/Module1.ah b/AspectC++/examples/modules/Module1.ah new file mode 100644 index 0000000..d5e21d5 --- /dev/null +++ b/AspectC++/examples/modules/Module1.ah @@ -0,0 +1,15 @@ +#ifndef __MODULE_1_AH__ +#define __MODULE_1_AH__ + +#include "Module1.h" + +aspect Module1Initializer { + + //bind to init function and initialize Module1 + advice execution("void Modules::init()") : after() { + Modules::Module1::init(); + } + +}; + +#endif diff --git a/AspectC++/examples/modules/Module1.h b/AspectC++/examples/modules/Module1.h new file mode 100644 index 0000000..143c114 --- /dev/null +++ b/AspectC++/examples/modules/Module1.h @@ -0,0 +1,18 @@ +#ifndef __MODULE_1_H__ +#define __MODULE_1_H__ + +#include + +namespace Modules { + +class Module1 { +private: + static void init() { + std::cout << "Module 1 initialized" << std::endl; + } + +}; + +} //namespace Modules + +#endif diff --git a/AspectC++/examples/modules/Modules.h b/AspectC++/examples/modules/Modules.h new file mode 100644 index 0000000..503c988 --- /dev/null +++ b/AspectC++/examples/modules/Modules.h @@ -0,0 +1,18 @@ +#ifndef __MODULES_H__ +#define __MODULES_H__ + +namespace Modules { + +void init() { + /* + This function is empty and serves as an explicit joinpoint. + Aspects that belong to modules can bind to this function + in order to get initialized. + This way, modules can be omitted without changing or modifying + other parts of the system. The modules are loosely coupled. + */ +} + +} //namespace Modules + +#endif diff --git a/AspectC++/examples/modules/main.cc b/AspectC++/examples/modules/main.cc new file mode 100644 index 0000000..eb86f5a --- /dev/null +++ b/AspectC++/examples/modules/main.cc @@ -0,0 +1,9 @@ +#include "Modules.h" + +int main(){ + + //initialize all modules + Modules::init(); + + return 0; +} diff --git a/AspectC++/examples/profiling/Makefile b/AspectC++/examples/profiling/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/examples/profiling/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/examples/profiling/genericprofiler.ah b/AspectC++/examples/profiling/genericprofiler.ah new file mode 100644 index 0000000..f9fdcfa --- /dev/null +++ b/AspectC++/examples/profiling/genericprofiler.ah @@ -0,0 +1,124 @@ +#ifndef __genericprofiler_ah__ +#define __genericprofiler_ah__ + +#include +#include +using namespace std; + + +// GenericProfiler - generic aspect to gather profiling information +// (Name and signature of each executed function, how often the function +// was executed and how many clock cycles were spent executing it.) +// +// The following definitions need to be specialized: +// +// pointcut virtual measureFct () = ... ; +// Define a match expression for the functions to be profiled +// +// virtual void (*summary())() { ... } +// This function should return a pointer to a static function that +// will be called when exiting the program. +// If this function is not defined in a derived aspect, a simple +// textual summary will be printed. +// Refer to the function simple_stat() to learn how to access the +// profiling data. +// +// This aspect uses the time stamp counter of the x86 processors +// to measure the execution time in clock cycles. +// When the profiling aspect should be used on other architectures +// the rdtsc() function and possibly the definition of the typedef +// ClockTicks and the function duration() must be replaced accordingly. + + + +namespace Profiler { + + typedef unsigned long long int ClockTicks; + + // rdtsc() - read the time stamp counter of x86 processors + extern inline ClockTicks rdtsc() { + unsigned long long int x; + __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x)); + return x; + } + + // duration() - calculate time spent between start and stop + extern inline ClockTicks duration(ClockTicks start, ClockTicks end) { + if (end > start) { + return (end - start); + } else { // counter overflow + return (ClockTicks)(-1LL) - end + start; + } + } + + // Data structure used to gather the profiling information + // New Data objects link themselves to existing ones at creation + // time. + struct Data { + static Data *&first () { static Data *data = 0; return data; } + struct Data *_next; + unsigned _calls; + ClockTicks _time; + const char *_name; + Data (const char* n) : _calls(0), _time(0L), _name (n) { + Data *head = first (); + first () = this; + _next = head; + } + }; + +} + + +aspect GenericProfiler { + + // Do not measure the Profiler's own methods + pointcut dontMeasure () = "% Profiler::...::%(...)" || + "% GenericProfiler::...::%(...)"; + + // Pure virtual pointcut: to be specified in a derived aspect + pointcut virtual measureFct () = 0; + + // Execution advice for the functions that are to be measured. + // For each JoinPoint the advice code will be transformed into + // a new template function instantiation. Therefore a new Data object + // will be created whenever a function is executed the first time. + // Further executions of the same function will reuse this object, + // enabling it to count the number of invocations and the overall + // time consumed. + advice execution(measureFct() && !dontMeasure()) : around() { + static Profiler::Data data (JoinPoint::signature ()); + Profiler::ClockTicks start = Profiler::rdtsc(); + tjp->proceed(); + Profiler::ClockTicks end = Profiler::rdtsc(); + data._calls++; + data._time += Profiler::duration (start, end); + }; + + // Print a simple summary + static void simple_stat () { + cout << "Statistics:" << endl; + for (Profiler::Data *curr = Profiler::Data::first (); + curr; curr = curr->_next) { + cout << "---" << endl; + cout << "function: " << curr->_name << endl; + cout << "no of execs: " << curr->_calls << endl; + cout << "total time: " << curr->_time << endl; + } + } + + // Return the function that should be used to print the profiling summary + // Specialize this function if you prefer a different kind of output. + virtual void (*summary())() { + return &simple_stat; + } + + // This advice is used to register the function that prints the summary + // to be executed when the program exits. + advice execution ("% main(...)") : after () { + atexit (summary()); + } +}; + + +#endif diff --git a/AspectC++/examples/profiling/main.cc b/AspectC++/examples/profiling/main.cc new file mode 100644 index 0000000..ab3c97f --- /dev/null +++ b/AspectC++/examples/profiling/main.cc @@ -0,0 +1,24 @@ +class MyClass { +private: + void privateWork() {} +public: + MyClass() {} + void work() { for (int i=0; i<2; i++) privateWork(); } + void work (int x) { for (int i=0; i +using namespace std; + + +//------------------------------------------------------------ +// Specialized profiling aspect +// +// Here the specialization is used to add all functions +// to the profiling and to replace the default summary by a summary +// that uses the csv format + +aspect CSVProfiler : public GenericProfiler { + + // Gather profiling information for all functions + pointcut virtual measureFct () = "% ...::% (...)" && + !"% CSVProfiler::%(...)"; + + + // Print summary using the csv format + static void csv_stat () { + cout << "function ; number of executions ; total time (clock cycles)" + << endl; + for (Profiler::Data *curr = Profiler::Data::first (); + curr; curr = curr->_next) { + cout << curr->_name << " ; " + << curr->_calls << " ; " + << curr->_time << endl; + } + } + + // Register the specialized function that prints the summary + virtual void (*summary())() { + return &csv_stat; + } + +}; + +#endif diff --git a/AspectC++/examples/singleton/Makefile b/AspectC++/examples/singleton/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/examples/singleton/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/examples/singleton/falsefriend.h b/AspectC++/examples/singleton/falsefriend.h new file mode 100644 index 0000000..5968638 --- /dev/null +++ b/AspectC++/examples/singleton/falsefriend.h @@ -0,0 +1,19 @@ +#ifndef __falsefriend_h__ +#define __falsefriend_h__ + +#include "singleton.h" + +// Example implementation of a "false friend". +// Being a friend of Singleton, FalseFriend has got access to the +// private methods of that class. +// Although objects of class Singleton should only be created +// by calling Singleton::getInstance(), FalseFriend misuses its +// privileges and directly calls the constructor, thus creating +// additional Singleton objects. + +class FalseFriend { + public: + FalseFriend() { Singleton s1; Singleton s2(s1); } +}; + +#endif diff --git a/AspectC++/examples/singleton/main.cc b/AspectC++/examples/singleton/main.cc new file mode 100644 index 0000000..b8e0a6d --- /dev/null +++ b/AspectC++/examples/singleton/main.cc @@ -0,0 +1,11 @@ +#include "singleton.h" +#include "falsefriend.h" + +int main () { + + Singleton& s1 = Singleton::getInstance(); + + FalseFriend f; + + return 0; +} diff --git a/AspectC++/examples/singleton/mysingletonmonitor.ah b/AspectC++/examples/singleton/mysingletonmonitor.ah new file mode 100644 index 0000000..1c39ce3 --- /dev/null +++ b/AspectC++/examples/singleton/mysingletonmonitor.ah @@ -0,0 +1,14 @@ +#ifndef __mysingletonmonitor_ah__ +#define __mysingletonmonitor_ah__ + +#include "singletonmonitor.ah" + +// Example for a specialization of the GenericSingletonMonitor +// Use the pointcut singleton() to specify which classes should +// obey the singleton pattern. + +aspect MySingletonMonitor : public GenericSingletonMonitor { + pointcut virtual singleton() = "Singleton"; +}; + +#endif diff --git a/AspectC++/examples/singleton/singleton.h b/AspectC++/examples/singleton/singleton.h new file mode 100644 index 0000000..71daa8e --- /dev/null +++ b/AspectC++/examples/singleton/singleton.h @@ -0,0 +1,34 @@ +#ifndef __singleton_h__ +#define __singleton_h__ + +// Example implementation of the singleton pattern: +// Constructor and copy constructor are private to prevent +// the uncontrolled creation of Singleton instances. +// The creation of the only allowed instance is accomplished +// using the public getInstance() method, which always returns +// the same object. + +// While the implementation looks straightforward, the +// declaration of a friend class is a security hole. +// Thus the SingletonMonitor aspect can be used to look +// for violations of the singleton pattern. + +class FalseFriend; + +class Singleton +{ + private: + Singleton() {} + Singleton(const Singleton&) {} + ~Singleton() {} + public: + static Singleton& getInstance() { + static Singleton instance; + return instance; + } + + friend class FalseFriend; +}; + + +#endif diff --git a/AspectC++/examples/singleton/singletonmonitor.ah b/AspectC++/examples/singleton/singletonmonitor.ah new file mode 100644 index 0000000..5e48207 --- /dev/null +++ b/AspectC++/examples/singleton/singletonmonitor.ah @@ -0,0 +1,47 @@ +#ifndef __singletonmonitor_ah__ +#define __singletonmonitor_ah__ + +#include + +// Generic singleton monitor aspect +// +// A class obeying the singleton pattern should guarantee that +// no more than a single object of this class will be ever created. +// This generic aspect checks the behavior: it counts the instances +// and emits an error message if more than one instance is created. + +// singletonmonitor::Counter is a helper class used to count the number +// of objects created. +// The usage of a template class and its intantiation with JoinPoint::That +// ensures, that a new counter will be used for each singleton class, +// while constructor and copy-constructor of the same class will use +// the same counter. + + +namespace singletonmonitor { + template struct Counter { + static int _val; + }; + template int Counter::_val = 0; +} + + +aspect GenericSingletonMonitor { + pointcut virtual singleton() = 0; + + advice construction (singleton()) : before() { + using namespace singletonmonitor; + typedef Counter InstanceCounter; + + InstanceCounter::_val++; + if (InstanceCounter::_val > 1) { + std::cerr << "Error: " + << "created instance number "<< InstanceCounter::_val + << " of singleton class by calling the constructor " + << JoinPoint::signature() + << std::endl; + } + }; +}; + +#endif diff --git a/AspectC++/examples/threads/Log.h b/AspectC++/examples/threads/Log.h new file mode 100644 index 0000000..73624ec --- /dev/null +++ b/AspectC++/examples/threads/Log.h @@ -0,0 +1,20 @@ +#ifndef __Log_h__ +#define __Log_h__ + +#include + +class Log { +public: + void print (int indent, bool enter, const char *text) { + for (int i = 0; i < indent; i++) printf (" "); + if (enter) printf ("> "); else printf ("< "); + printf ("%s\n", text); + } + + static Log &instance () { + static Log log; + return log; + } +}; + +#endif // __Log_h__ diff --git a/AspectC++/examples/threads/Makefile b/AspectC++/examples/threads/Makefile new file mode 100644 index 0000000..6884118 --- /dev/null +++ b/AspectC++/examples/threads/Makefile @@ -0,0 +1,2 @@ +LDFLAGS=-lpthread +include ../Makefile.generic diff --git a/AspectC++/examples/threads/SynchronizedLog.ah b/AspectC++/examples/threads/SynchronizedLog.ah new file mode 100644 index 0000000..67bcec5 --- /dev/null +++ b/AspectC++/examples/threads/SynchronizedLog.ah @@ -0,0 +1,27 @@ +#ifndef __SynchronizedLog_ah__ +#define __SynchronizedLog_ah__ + +#include + +aspect SynchronizedLog { + // introduce a mutex into the Log class + // -> there is one mutex instance per log object + advice "Log": slice struct { + pthread_mutex_t _mutex; + }; + + // initialize the mutex upon Log construction + advice construction("Log") : before () { + pthread_mutex_t helper = PTHREAD_MUTEX_INITIALIZER; + tjp->that ()->_mutex = helper; + } + + // protect the critical section + advice execution("% Log::print(...)") : around () { + pthread_mutex_lock(&tjp->that ()->_mutex); + tjp->proceed (); + pthread_mutex_unlock(&tjp->that ()->_mutex); + } +}; + +#endif // __SynchronizedLog_ah__ diff --git a/AspectC++/examples/threads/ThreadSafeLogging.ah b/AspectC++/examples/threads/ThreadSafeLogging.ah new file mode 100644 index 0000000..eca04f9 --- /dev/null +++ b/AspectC++/examples/threads/ThreadSafeLogging.ah @@ -0,0 +1,74 @@ +#ifndef __ThreadSafeLogging_ah__ +#define __ThreadSafeLogging_ah__ + +#include +#include + +#include "Log.h" + +// This example illustrates how to use the aspectof() function +// to implement thread-local aspects with the pthread library +// or others that support thread-local storage in a similiar way. + +// The beginning looks quite normal ... +aspect ThreadSafeLogging { + + int _execs; // thread local function execution counter + int _indent; // per thread indentation of the log + + advice execution ("% TestClass::%(...)") : before () { + _execs++; + Log::instance ().print (_indent, true, JoinPoint::signature ()); + _indent++; + } + + advice execution ("% TestClass::%(...)") : after () { + _indent--; + Log::instance ().print (_indent, false, JoinPoint::signature ()); + } + +public: + + ThreadSafeLogging () : _execs (0), _indent (0) {} + + ~ThreadSafeLogging () { + printf ("aspect %p counted %d\n", this, _execs); + } + + // Here comes the magic: aspectof() is called at each joinpoint in + // order to determine the aspect instrance to be used for the + // advice invocation. + // The following definition retrieves a thread-local aspect instance + // pointer. If it is still NULL, an aspect object is created and assigned. + + static ThreadSafeLogging *aspectof() { + extern pthread_key_t tls_aspects_key; + + ThreadSafeLogging *me = + (ThreadSafeLogging*)pthread_getspecific (tls_aspects_key); + if (!me) { + me = new ThreadSafeLogging; + pthread_setspecific (tls_aspects_key, me); + printf ("created aspect instance %p\n", me); + } + return me; + } + + static void init () { + extern pthread_key_t tls_aspects_key; + + // create a key for thread-local storage + pthread_key_create(&tls_aspects_key, &ThreadSafeLogging::destructor); + } + + // We passed this function to pthread_key_create as a destructor function. + // It is called by the pthread library when the thread terminates. + + static void destructor (void *me) { + delete (ThreadSafeLogging*)me; + printf ("destroyed aspect instance %p\n", me); + } + +}; + +#endif // __ThreadSafeLogging_ah__ diff --git a/AspectC++/examples/threads/main.cc b/AspectC++/examples/threads/main.cc new file mode 100644 index 0000000..ffbdd8e --- /dev/null +++ b/AspectC++/examples/threads/main.cc @@ -0,0 +1,51 @@ +#include +#include +#include + +#define NUMTHREADS 3 + +pthread_key_t tls_aspects_key; + +class Thread { +public: + virtual void run () = 0; +}; + +class TestClass : public Thread { + void f1 () { f2 (); } + void f2 () { } +public: + virtual void run () { f1(); } +}; + +void *thread_start(void*) { + TestClass thread_object; + thread_object.run (); +} + +#include "ThreadSafeLogging.ah" + +int main () { + pthread_t thread[NUMTHREADS]; + + // initialize the thread-safe logging aspect *before* forking threads + ThreadSafeLogging::init (); + + printf("Create/start threads\n"); + for (int i = 0; i < NUMTHREADS; i++) { + if (pthread_create(&thread[i], NULL, thread_start, NULL)) { + perror("thread_create failed"); + exit(1); + } + } + + for (int i = 0; i < NUMTHREADS; i++) { + if (pthread_join(thread[i], NULL)) { + perror("thread_join failed"); + exit(1); + } + } + + printf("done\n"); + return 0; +} diff --git a/AspectC++/infos.h b/AspectC++/infos.h new file mode 100644 index 0000000..44c4bd8 --- /dev/null +++ b/AspectC++/infos.h @@ -0,0 +1,8 @@ +#ifndef __ac_infos_h__ +#define __ac_infos_h__ + +#define AC_VERSION "2.2" +#define COMPANY_NAME "www.aspectc.org" +#define COPYRIGHT "Gnu Public License (GPL)" + +#endif diff --git a/AspectC++/tests/AbstractDerivedAspect/Makefile b/AspectC++/tests/AbstractDerivedAspect/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/AbstractDerivedAspect/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/AbstractDerivedAspect/feature.ref b/AspectC++/tests/AbstractDerivedAspect/feature.ref new file mode 100644 index 0000000..6e6ddb7 --- /dev/null +++ b/AspectC++/tests/AbstractDerivedAspect/feature.ref @@ -0,0 +1,4 @@ +AbstractDerivedAspect: check whether an aspect is abtract +... fine if this is underlined twice! +===================================== +===================================== diff --git a/AspectC++/tests/AbstractDerivedAspect/main.cc b/AspectC++/tests/AbstractDerivedAspect/main.cc new file mode 100644 index 0000000..8a3033e --- /dev/null +++ b/AspectC++/tests/AbstractDerivedAspect/main.cc @@ -0,0 +1,48 @@ +#include +using std::printf; + +aspect AbstractBase { + pointcut virtual fn () = 0; + advice execution (fn ()) : after () { + printf ("=====================================\n"); + } + virtual void dummy () = 0; +}; + +// this one is also abstract and is therefore allowed to be a base class +aspect Mediator : public AbstractBase { + pointcut fn () = "% main(...)"; +}; + +// this aspect should not be considered by Final although it defines fn +aspect Monster { + pointcut fn () = "% bar(...)"; + virtual void dummyMonster () = 0; +}; + +aspect Final : public Monster, public Mediator { + void dummy () {} + void dummyMonster () {} +}; + +aspect AbstractDestructorBase { +public: + // pure virtual destructor! + virtual ~AbstractDestructorBase() = 0; + advice execution ("% main(...)") : after () { + printf ("=====================================\n"); + } +}; + +// oh what a hell: here is the definition of the pure virtual destructor +AbstractDestructorBase::~AbstractDestructorBase () {} + + +aspect WithImplicitDestructor : public AbstractDestructorBase { +}; + +int main () { + printf ("AbstractDerivedAspect: check whether an aspect is abtract\n"); + printf ("... fine if this is underlined twice!\n"); + return 0; +} diff --git a/AspectC++/tests/AccessControl/Makefile b/AspectC++/tests/AccessControl/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/AccessControl/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/AccessControl/feature.ref b/AspectC++/tests/AccessControl/feature.ref new file mode 100644 index 0000000..8badf62 --- /dev/null +++ b/AspectC++/tests/AccessControl/feature.ref @@ -0,0 +1,49 @@ +AccessControl: advice for calls with special privileges +======================================================= +call to int Derived::val() +around1: call to int Derived::val() +around2: call to int Derived::val() + --> call to private member from constructor init list +call to void Derived::g1() +around1: call to void Derived::g1() +around2: call to void Derived::g1() + --> public +call to void Derived::p() +around1: call to void Derived::p() +around2: call to void Derived::p() + --> private in same class +call to void Base::f() +around1: call to void Base::f() +around2: call to void Base::f() + --> protected in base +call to void Base::x() +around1: call to void Base::x() +around2: call to void Base::x() +call to void HasFriend::h() +around1: call to void HasFriend::h() +around2: call to void HasFriend::h() +Calls2: call to void HasFriend::h() +Calls3: call to void HasFriend::h() + --> access for friend Base::x() only +call to void Derived::g2() +around1: call to void Derived::g2() +around2: call to void Derived::g2() + --> public +call to void Derived::p() +around1: call to void Derived::p() +around2: call to void Derived::p() + --> private in same class +call to void Base::f() +around1: call to void Base::f() +around2: call to void Base::f() + --> protected in base +call to void Base::x() +around1: call to void Base::x() +around2: call to void Base::x() +call to void HasFriend::h() +around1: call to void HasFriend::h() +around2: call to void HasFriend::h() +Calls2: call to void HasFriend::h() +Calls3: call to void HasFriend::h() + --> access for friend Base::x() only +======================================================= diff --git a/AspectC++/tests/AccessControl/main.cc b/AspectC++/tests/AccessControl/main.cc new file mode 100644 index 0000000..854ecea --- /dev/null +++ b/AspectC++/tests/AccessControl/main.cc @@ -0,0 +1,90 @@ +#include + +aspect Calls { + advice call ("% %::%(...)") : before () { + printf ("call to %s\n", tjp->signature ()); + } + advice call ("% %::%(...)") : around () { + printf ("around1: call to %s\n", tjp->signature ()); + tjp->proceed (); + } + advice call ("% %::%(...)") : around () { + printf ("around2: call to %s\n", tjp->signature ()); + tjp->proceed (); + } +}; + +aspect Calls2 { + advice call ("% HasFriend::h(...)") : around () { + printf ("Calls2: call to %s\n", tjp->signature ()); + tjp->proceed (); + } +}; + +aspect Calls3 { + advice call ("% HasFriend::h(...)") : around () { + printf ("Calls3: call to %s\n", tjp->signature ()); + tjp->proceed (); + } +}; + +class Base { +protected: + Base () {} + void f (); +public: + void x (); +}; + +class HasFriend { + friend void Base::x (); + static void h () { + printf (" --> access for friend Base::x() only\n"); + } +}; + +void Base::f () { + printf (" --> protected in base\n"); + x (); +} + +// need because starting with g++ 3.4.1 a friend has to be accessible +void Base::x () { + HasFriend::h (); +} + +class Derived : private Base { + int _attr; + void p () { + printf (" --> private in same class\n"); + } + int val () { return 4711; } +public: + Derived (); + void g1 () { + printf (" --> public\n"); + p (); + f (); + } + void g2 (); +}; + +Derived::Derived () : _attr (val ()) { + printf (" --> call to private member from constructor init list\n"); +} + +void Derived::g2 () { + printf (" --> public\n"); + p (); + f (); +} + +int main () { + printf ("AccessControl: advice for calls with special privileges\n"); + printf ("=======================================================\n"); + + Derived d; + d.g1 (); + d.g2 (); + printf ("=======================================================\n"); +} diff --git a/AspectC++/tests/Advice/Aspect.ah b/AspectC++/tests/Advice/Aspect.ah new file mode 100644 index 0000000..14d7a81 --- /dev/null +++ b/AspectC++/tests/Advice/Aspect.ah @@ -0,0 +1,19 @@ +#ifndef __Aspect_ah__ +#define __Aspect_ah__ + +#include + +aspect Action { + advice execution("% A::%(...)"||"% b(...)"||"% d(...)"||"% e(...)"||"% f(...)") : around() { + printf("A: before(exec) %s\n", JoinPoint::signature()); + tjp->proceed(); + printf("A: after(exec) %s\n", JoinPoint::signature()); + } + advice call("% A::%(...)"||"% b(...)"||"% d(...)"||"% e(...)"||"% f(...)") : around() { + printf("A: before(call) %s\n", JoinPoint::signature()); + tjp->proceed(); + printf("A: after(call) %s\n", JoinPoint::signature()); + } +}; + +#endif // __Aspect_ah__ diff --git a/AspectC++/tests/Advice/Makefile b/AspectC++/tests/Advice/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Advice/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Advice/feature.ref b/AspectC++/tests/Advice/feature.ref new file mode 100644 index 0000000..cbd61a7 --- /dev/null +++ b/AspectC++/tests/Advice/feature.ref @@ -0,0 +1,38 @@ +Advice: each function must be wrapped by call and exec advice +============================================================= +A: before(call) int A::a(int,float) +A: before(exec) int A::a(int,float) +inside A::a(4711, 3.140000) +A: after(exec) int A::a(int,float) +A: after(call) int A::a(int,float) +------------------------------------------------------------- +A: before(call) void b(char,const char *) +A: before(exec) void b(char,const char *) +b(H, ello World) +A: after(exec) void b(char,const char *) +A: after(call) void b(char,const char *) +------------------------------------------------------------- +A: before(call) int A::c(int,int) +A: before(exec) int A::c(int,int) +A::c(4, 5) +A: after(exec) int A::c(int,int) +A: after(call) int A::c(int,int) +------------------------------------------------------------- +A: before(call) void d(char,const char *) +A: before(exec) void d(char,const char *) +d(H, ello World) +A: after(exec) void d(char,const char *) +A: after(call) void d(char,const char *) +------------------------------------------------------------- +A: before(call) void e() +A: before(exec) void e() +e(void) +A: after(exec) void e() +A: after(call) void e() +------------------------------------------------------------- +A: before(call) void f(int,int) +A: before(exec) void f(int,int) +f(1, anon int) +A: after(exec) void f(int,int) +A: after(call) void f(int,int) +============================================================= diff --git a/AspectC++/tests/Advice/main.cc b/AspectC++/tests/Advice/main.cc new file mode 100644 index 0000000..fb419c6 --- /dev/null +++ b/AspectC++/tests/Advice/main.cc @@ -0,0 +1,53 @@ +#include + +class A { +public: + int a(int i, float b) { + printf("inside A::a(%d, %f)\n", i, b); + return i; + } + int c(int p, int q); + friend void b(char c, char *str); +}; + +int A::c(int p, int q){ + printf("A::c(%d, %d)\n",p,q); + return p; +} + +void b(char c, const char *str); + +void b(char c, const char *str) { + printf("b(%c, %s)\n", c, str); +} + +void d(char c, const char *str) { + printf("d(%c, %s)\n", c, str); +} + +void e(void) { + printf ("e(void)\n"); +} + +void f(int i, int j); +void f(int i, int) { + printf ("f(%d, anon int)\n", i); +} + +int main() { + A a; + printf ("Advice: each function must be wrapped by call and exec advice\n"); + printf ("=============================================================\n"); + a.a(4711, 3.14f); + printf ("-------------------------------------------------------------\n"); + b('H', "ello World"); + printf ("-------------------------------------------------------------\n"); + a.c(4,5); + printf ("-------------------------------------------------------------\n"); + d('H', "ello World"); + printf ("-------------------------------------------------------------\n"); + e(); + printf ("-------------------------------------------------------------\n"); + f(1,0); + printf ("=============================================================\n"); +} diff --git a/AspectC++/tests/AdviceVirtualFct/Aspect.ah b/AspectC++/tests/AdviceVirtualFct/Aspect.ah new file mode 100644 index 0000000..0aa0e93 --- /dev/null +++ b/AspectC++/tests/AdviceVirtualFct/Aspect.ah @@ -0,0 +1,23 @@ +#ifndef __Aspect_ah__ +#define __Aspect_ah__ + +#include + +aspect Action { + advice execution("% Base::%(...)") : around() { + printf("A: before(exec) %s\n", JoinPoint::signature()); + tjp->proceed(); + printf("A: after(exec) %s\n", JoinPoint::signature()); + } + advice call("% Base::%(...)") : around() { + printf("A: before(call) %s\n", JoinPoint::signature()); + tjp->proceed(); + printf("A: after(call) %s\n", JoinPoint::signature()); + } +}; + +#endif // __Aspect_ah__ + + + + diff --git a/AspectC++/tests/AdviceVirtualFct/Makefile b/AspectC++/tests/AdviceVirtualFct/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/AdviceVirtualFct/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/AdviceVirtualFct/feature.ref b/AspectC++/tests/AdviceVirtualFct/feature.ref new file mode 100644 index 0000000..2688d7d --- /dev/null +++ b/AspectC++/tests/AdviceVirtualFct/feature.ref @@ -0,0 +1,22 @@ +AdviceVirtualFct +============================================================= +first we cast 'obj' to 'Derived': here should be *no* advice +inside Derived::a(1, 2.000000) +------------------------------------------------------------- +now we call 'b()' on 'obj': *only call* advice should be run +A: before(call) int Base::b(int,int) +inside Derived::b(3, 4) +A: after(call) int Base::b(int,int) +------------------------------------------------------------- +a call 'Base::b()' fully qualified: *both* call and exec +A: before(call) int Base::b(int,int) +A: before(exec) int Base::b(int,int) +inside Base::b(5, 6) +A: after(exec) int Base::b(int,int) +A: after(call) int Base::b(int,int) +------------------------------------------------------------- +a call to a pure virtual function: *only call* advice +A: before(call) void Base::c() +inside Derived::c() +A: after(call) void Base::c() +============================================================= diff --git a/AspectC++/tests/AdviceVirtualFct/main.cc b/AspectC++/tests/AdviceVirtualFct/main.cc new file mode 100644 index 0000000..59e1f52 --- /dev/null +++ b/AspectC++/tests/AdviceVirtualFct/main.cc @@ -0,0 +1,53 @@ +#include + +class Base { +public: + virtual int a(int i, float b) { + printf("inside Base::a(%d, %f)\n", i, b); + return i; + } + virtual int b(int p, int q); + virtual void c () = 0; +}; + +int Base::b (int p, int q) { + printf("inside Base::b(%d, %d)\n", p, q); + return p + q; +} + +class Derived : public Base { +public: + virtual int a(int i, float b) { + printf("inside Derived::a(%d, %f)\n", i, b); + return i; + } + virtual int b(int p, int q); + void c () { + printf("inside Derived::c()\n"); + } +}; + +int Derived::b (int p, int q) { + printf("inside Derived::b(%d, %d)\n", p, q); + return p + q; +} + + +int main() { + Base *obj = new Derived (); + printf ("AdviceVirtualFct\n"); + printf ("=============================================================\n"); + printf ("first we cast 'obj' to 'Derived': here should be *no* advice\n"); + ((Derived*)obj)->a (1, 2); + printf ("-------------------------------------------------------------\n"); + printf ("now we call 'b()' on 'obj': *only call* advice should be run\n"); + obj->b (3, 4); + printf ("-------------------------------------------------------------\n"); + printf ("a call 'Base::b()' fully qualified: *both* call and exec\n"); + ((Derived*)obj)->Base::b (5, 6); + printf ("-------------------------------------------------------------\n"); + printf ("a call to a pure virtual function: *only call* advice\n"); + obj->c (); + printf ("=============================================================\n"); + delete obj; +} diff --git a/AspectC++/tests/AnonymousStuff/Makefile b/AspectC++/tests/AnonymousStuff/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/AnonymousStuff/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/AnonymousStuff/feature.ref b/AspectC++/tests/AnonymousStuff/feature.ref new file mode 100644 index 0000000..53ce315 --- /dev/null +++ b/AspectC++/tests/AnonymousStuff/feature.ref @@ -0,0 +1,35 @@ + execution ("int main()") +AnonymousStuff: tests if ac++ can deal with anonymous classes, + namespace, etc. +============================================================= + call ("void ::g1()") + execution ("void ::g1()") + in unnamed namespace + call ("void f()") + execution ("void f()") + call ("void ::C::cfunc()") + execution ("void ::C::cfunc()") + in unnamed namespace + call ("void ::::g2()") + execution ("void ::::g2()") + in unnamed namespace + call ("void f()") + call within g2() to ("void f()") + execution ("void f()") + call ("void ::g1()") + call within g2() to ("void ::g1()") + execution ("void ::g1()") + in unnamed namespace + call ("void f()") + execution ("void f()") + call ("void ::C::cfunc()") + execution ("void ::C::cfunc()") + in unnamed namespace + execution ("const ::C &::C::staticcfunc(::C &)") + in unnamed namespace + call ("void ::C::cfunc()") + execution ("void ::C::cfunc()") + in unnamed namespace + execution ("FooBar::MyEnum ::A::B::f(FooBar::FooBar2::C &)") + in unnamed namespace +============================================================= diff --git a/AspectC++/tests/AnonymousStuff/main.cc b/AspectC++/tests/AnonymousStuff/main.cc new file mode 100644 index 0000000..67b1424 --- /dev/null +++ b/AspectC++/tests/AnonymousStuff/main.cc @@ -0,0 +1,83 @@ +#include + +// See Bug770 for more anonymous related tests (especially anonymous unions) + +void f () {} + +namespace { +} + +namespace { + class C { + public: + void cfunc() { intro++; } + static const C &staticcfunc (C &obj) { obj.cfunc(); return obj; } + } cobj; + void g1 () { f (); cobj.cfunc(); } + namespace { + void g2 () { f (); g1 (); } + namespace { + void g3() {} + } + } +}; + +namespace { +} + +namespace FooBar { + enum MyEnum {}; + + namespace FooBar2 { + class C {}; + } +} + +namespace { + +class A +{ +public: + class B + { + public: + FooBar::MyEnum f(FooBar::FooBar2::C&) + { + return FooBar::MyEnum (); + } + }; + +}; // class + +} // local namespace + +aspect Test { + advice call("% ...::%()") : before () { + printf (" call (\"%s\")\n", JoinPoint::signature ()); + } + advice call("% ...::%(...)") && within("% ...::g2(...)") : before () { + printf (" call within g2() to (\"%s\")\n", JoinPoint::signature ()); + } + advice execution ("% ...::%(...)") : before () { + printf (" execution (\"%s\")\n", JoinPoint::signature ()); + } + advice execution ("% ...::::...::%(...)") : before () { + printf (" in unnamed namespace\n"); + } + advice "::C" : slice struct { int intro; }; +}; + +int main() { + printf ("AnonymousStuff: tests if ac++ can deal with anonymous classes,\n"); + printf (" namespace, etc.\n"); + printf ("=============================================================\n"); + g1 (); + g2 (); + C c; + C::staticcfunc(c); + FooBar::FooBar2::C x; + A::B ab; + ab.f (x); + printf ("=============================================================\n"); + return 0; // TODO: it should also work without this return statement +} diff --git a/AspectC++/tests/ArrayAccessAdvice/Makefile b/AspectC++/tests/ArrayAccessAdvice/Makefile new file mode 100644 index 0000000..04f3f8b --- /dev/null +++ b/AspectC++/tests/ArrayAccessAdvice/Makefile @@ -0,0 +1,3 @@ +ACFLAGS += --builtin_operators --data_joinpoints +CXXFLAGS += -std=gnu++11 +include ../Makefile.generic diff --git a/AspectC++/tests/ArrayAccessAdvice/around.ah b/AspectC++/tests/ArrayAccessAdvice/around.ah new file mode 100644 index 0000000..254c45f --- /dev/null +++ b/AspectC++/tests/ArrayAccessAdvice/around.ah @@ -0,0 +1,22 @@ +#ifndef __AROUNDCHECK_AH__ +#define __AROUNDCHECK_AH__ + +#include + +using namespace std; + +aspect AroundCheck { + advice builtin( "% operator =(...)" || "% operator +=(...)" ) && within( "void check_tunnel()" ) : around() { + cout << " ## operator" << endl; + tjp->proceed(); + } + advice ( get( "% ...::%" ) || set( "% ...::%" ) ) && within( "void check_proceed()" ) : around() { + cout << " ## proceed()" << endl; + tjp->proceed(); + } + advice ( get( "% ...::%" ) || set( "% ...::%" ) ) && within( "void check_action()" ) : around() { + cout << " ## action()" << endl; + tjp->action().trigger(); + } +}; +#endif diff --git a/AspectC++/tests/ArrayAccessAdvice/feature.ref b/AspectC++/tests/ArrayAccessAdvice/feature.ref new file mode 100644 index 0000000..deb707d --- /dev/null +++ b/AspectC++/tests/ArrayAccessAdvice/feature.ref @@ -0,0 +1,119 @@ +~~~ Construct: CTest::CTest() +Basic Checks: + +array 1-Dim: +~~~ Get: int a[5] @ a+2 < 5 > | a[2|5] +~~~ Set: int a[5] @ a+0 < 1 > | a[0|5] := 11 +~~~ Ref: int a[5] @ a+1 < 3 > | a[1|5] +~~~ Ref: int a[5] @ a+0 < 11 > | a[0|5] +~~~ Ref: int a[5] @ a+2 < 5 > | a[2|5] + +array 2-Dim: +~~~ Get: int b[2][3] @ b+3 < 1 > | b[1|2][0|3] +~~~ Set: int b[2][3] @ b+2 < 6 > | b[0|2][2|3] := 12 +~~~ Ref: int b[2][3] @ b+5 < 5 > | b[1|2][2|3] +~~~ Ref: int b[2][3] @ b+1 < b+3[3] > | b[1|2] +~~~ Ref: int b[2][3] @ b+0 < b+0[3] > | b[0|2] +~~~ Ref: int b[2][3] @ b+0 < 2 > | b[0|2][0|3] +~~~ Ref: int b[2][3] @ b+1 < 4 > | b[0|2][1|3] +~~~ Ref: int b[2][3] @ b+1 < b+3[3] > | b[1|2] + +array 3-Dim Member: +~~~ Get: int T::m[2][3][2] @ t.m+3 < 0 > -> t ? true | 1 | t.m[0|2][1|3][1|2] +~~~ Set: int T::m[2][3][2] @ t.m+4 < 20 > -> t ? true | 1 | t.m[0|2][2|3][0|2] := 42 + +array 3-Dim Member (internal): +~~~ Get: int T::m[2][3][2] @ t.m+0 < 3 > -> t ? true | 1 | t.m[0|2][0|3][0|2] +~~~ Set: int T::m[2][3][2] @ t.m+1 < 4 > -> t ? true | 1 | t.m[0|2][0|3][1|2] := 13 + +array 1-Dim Private (internal): +~~~ Get: int T::p[3] @ t.p+0 < 22 > -> t ? true | 1 | t.p[0|3] +~~~ Set: int T::p[3] @ t.p+2 < 44 > -> t ? true | 1 | t.p[2|3] := 99 + +array 1-Dim Static: +~~~ Get: int T::s[2] @ T::s+0 < 60 > | T::s[0|2] +~~~ Set: int T::s[2] @ T::s+1 < 90 > | T::s[1|2] := 23 +~~~ Get: int T::s[2] @ T::s+1 < 23 > | T::s[1|2] +~~~ Set: int T::s[2] @ T::s+0 < 60 > | T::s[0|2] := 17 + + +Checking dual Weaving: + +array 1-Dim: + ~~ Idx: a+0 [ 4 ] +~~~ Get: int a[5] @ a+4 < 9 > | a[4|5] + ~~ Idx: a+0 [ 1 ] +~~~ Set: int a[5] @ a+1 < 3 > | a[1|5] := 99 + +array 3-Dim Member: + ~~ Idx: t.m+0 [ 1 ] + ~~ Idx: t.m+3 [ 2 ] + ~~ Idx: t.m+10 [ 0 ] +~~~ Get: int T::m[2][3][2] @ t.m+10 < 2000 > -> t ? true | 1 | t.m[1|2][2|3][0|2] + ~~ Idx: t.m+0 [ 1 ] + ~~ Idx: t.m+3 [ 0 ] + ~~ Idx: t.m+6 [ 1 ] +~~~ Set: int T::m[2][3][2] @ t.m+7 < 400 > -> t ? true | 1 | t.m[1|2][0|3][1|2] := 21 + + +Checking partial dual Weaving: + +partial one: + ~~ Idx: t.m+0 [ 1 ] +~~~ Get: int T::m[2][3][2] @ t.m+10 < 2000 > -> t ? true | 1 | t.m[1|2][2|3][0|2] + ~~ Idx: t.m+0 [ 1 ] +~~~ Set: int T::m[2][3][2] @ t.m+7 < 21 > -> t ? true | 1 | t.m[1|2][0|3][1|2] := 21 + +partial two: + ~~ Idx: t.m+3 [ 2 ] +~~~ Get: int T::m[2][3][2] @ t.m+10 < 2000 > -> t ? true | 1 | t.m[1|2][2|3][0|2] + ~~ Idx: t.m+3 [ 0 ] +~~~ Set: int T::m[2][3][2] @ t.m+7 < 21 > -> t ? true | 1 | t.m[1|2][0|3][1|2] := 21 + +partial three: + ~~ Idx: t.m+10 [ 0 ] +~~~ Get: int T::m[2][3][2] @ t.m+10 < 2000 > -> t ? true | 1 | t.m[1|2][2|3][0|2] + ~~ Idx: t.m+6 [ 1 ] +~~~ Set: int T::m[2][3][2] @ t.m+7 < 21 > -> t ? true | 1 | t.m[1|2][0|3][1|2] := 21 + + +Checking proceed: + ## proceed() +~~~ Get: int b[2][3] @ b+1 < 4 > | b[0|2][1|3] + ## proceed() +~~~ Set: int b[2][3] @ b+3 < 1 > | b[1|2][0|3] := 32 + + +Checking action: + ## action() +~~~ Get: int b[2][3] @ b+4 < 3 > | b[1|2][1|3] + ## action() +~~~ Set: int b[2][3] @ b+5 < 5 > | b[1|2][2|3] := 48 + + +Checking tunneling: + ## operator +~~~ Set: int T::s[2] @ T::s+1 < 23 > | T::s[1|2] := 666 + ## operator +~~~ Get: int T::s[2] @ T::s+0 < 17 > | T::s[0|2] +~~~ Set: int T::s[2] @ T::s+0 < 17 > | T::s[0|2] := 239 + + +Checking qualified accesses: +~~~ Get: int T::m[2][3][2] @ t.m+11 < 2500 > -> t ? true | 1 | t.m[1|2][2|3][1|2] +~~~ Set: int T::m[2][3][2] @ t.m+11 < 2500 > -> t ? true | 1 | t.m[1|2][2|3][1|2] := 7500 +~~~ Ref: int T::m[2][3][2] @ t.m+7 < 21 > -> t ? true | 1 | t.m[1|2][0|3][1|2] + + +Checking interaction with other types: +~~~ Ref: std::map,std::allocator > > TestMap @ < ~~OBJ~~ > +~~~ Set (alias): char @ < 3 > := a +~~~ Get: int *TestPointer @ < ~~ADDR~~ > +~~~ Get: int *TestPointer @ < ~~ADDR~~ > + + +Checking interaction with construction advice: +~~~ Get: int CTest::m[12] @ cTest.m+6 < 0 > -> cTest ? true | 1 | cTest.m[6|12] + + +Checking incomplete array type: diff --git a/AspectC++/tests/ArrayAccessAdvice/idx.ah b/AspectC++/tests/ArrayAccessAdvice/idx.ah new file mode 100644 index 0000000..b8f189f --- /dev/null +++ b/AspectC++/tests/ArrayAccessAdvice/idx.ah @@ -0,0 +1,19 @@ +#ifndef __IDXMARKER_AH__ +#define __IDXMARKER_AH__ + +#include +#include "namemap.h" + +using namespace std; + +aspect IdxMarker { + pointcut weave() = + builtin( "% operator [](...)" ) && within( "void check_dual()" ) + || builtin( "% operator []( int (*)[3][2], ...)" ) && within( "void check_dual_partial1()" ) + || builtin( "% operator []( int (*)[2], ...)" ) && within( "void check_dual_partial2()" ) + || builtin( "% operator []( int *, ...)" ) && within( "void check_dual_partial3()" ); + advice weave() : before() { + cout << " ~~ Idx: "; NameMap::mangle_arraypart( *( tjp->template arg<0>() ) ); cout << " [ " << *( tjp->template arg<1>() ) << " ]" << endl; + } +}; +#endif diff --git a/AspectC++/tests/ArrayAccessAdvice/main.cc b/AspectC++/tests/ArrayAccessAdvice/main.cc new file mode 100644 index 0000000..9a0ea4d --- /dev/null +++ b/AspectC++/tests/ArrayAccessAdvice/main.cc @@ -0,0 +1,232 @@ +#include +#include "namemap.h" + +using namespace std; + +// forward decl for friend +namespace NameMap { void register_vars(); } + +class T { + double fill; + friend void NameMap::register_vars(); +private: + int p[3] = { 22, 33, 44 }; +public: + int m[2][3][2] = { { { 3, 4 }, { 1, 0 }, { 20, 25 } }, { { 300, 400 }, { 100, -1 }, { 2000, 2500 } } }; + static int s[2]; + + void test() { + cout << endl; + cout << "array 3-Dim Member (internal):" << endl; + int x = m[0][0][0]; + m[0][0][1] = 13; + + cout << endl; + cout << "array 1-Dim Private (internal):" << endl; + int y = p[0]; + p[2] = 99; + } +} t; +int T::s[2] = { 60, 90 }; + +int a[5] = { 1, 3, 5, 7, 9 }; +int b[2][3] = { 2, 4, 6, 1, 3, 5 }; + +// --- Helper code +namespace NameMap { + void register_vars() { + objs[ &t ] = Info( "t", sizeof( t ) ); + arrays[ &T::s ] = Info( "T::s", sizeof( T::s ) ); + arrays[ &t.m ] = Info( "t.m", sizeof( t.m ) ); + arrays[ &t.p ] = Info( "t.p", sizeof( t.p ) ); + + arrays[ &a ] = Info( "a", sizeof( a ) ); + arrays[ &b ] = Info( "b", sizeof( b ) ); + } +} +// --- end Helpers + +void check_basic() { + cout << endl; + cout << "array 1-Dim:" << endl; { + int x = a[2]; + a[0] = 11; + int *p1 = &a[1]; + int *p2 = a; + int &r = a[2]; + } + + cout << endl; + cout << "array 2-Dim:" << endl; { + int x = b[1][0]; + b[0][2] = 12; + int *p1 = &b[1][2]; + int (*p1a)[3] = &b[1]; + int (*p2)[3] = b; + int *p2a = b[0]; + int &r = b[0][1]; + int (&ra)[3] = b[1]; + } + + cout << endl; + cout << "array 3-Dim Member:" << endl; { + int x = t.m[0][1][1]; + t.m[0][2][0] = 42; + } + + t.test(); + + cout << endl; + cout << "array 1-Dim Static:" << endl; { + int x = t.s[0]; + t.s[1] = 23; + + int y = T::s[1]; + T::s[0] = 17; + } +} + +void check_dual() { + cout << endl; + cout << "array 1-Dim:" << endl; { + int x = a[4]; + a[1] = 99; + } + + cout << endl; + cout << "array 3-Dim Member:" << endl; { + int x = t.m[1][2][0]; + t.m[1][0][1] = 21; + } +} + +void check_dual_partial1() { + cout << endl; + cout << "partial one:" << endl; { + int x = t.m[1][2][0]; + t.m[1][0][1] = 21; + } +} + +void check_dual_partial2() { + cout << endl; + cout << "partial two:" << endl; { + int x = t.m[1][2][0]; + t.m[1][0][1] = 21; + } +} + +void check_dual_partial3() { + cout << endl; + cout << "partial three:" << endl; { + int x = t.m[1][2][0]; + t.m[1][0][1] = 21; + } +} + +void check_proceed() { + int x = b[0][1]; + b[1][0] = 32; +} + +void check_action() { + int x = b[1][1]; + b[1][2] = 48; +} + +void check_tunnel() { + T::s[1] = 666; + t.s[0] += 222; +} + +void check_qualified() { + t.T::m[1][2][1] *= 3; + + unsigned int i = 5; // dummy non const expr + i /= 3; + int *p = 0; + p = &t.T::m[i][i-1][i]; +} + +#include +map TestMap; +int *TestPointer = new int[3]; + +namespace NameMap { + char DUMMY = TestMap[3] = '3'; // preinit TestMap element for output + char *DUMMYPOINTER = &DUMMY; // needed to enable alias matching +} + +void check_interaction() { + TestMap[3] = 'a'; + + int x = TestPointer[2]; + TestPointer[0] = 5; + + a[3]; +} + +struct CTest { + int m[12]; +} cTest; + +namespace NameMap { + void register_vars2() { + objs[ &cTest ] = Info( "cTest", sizeof( cTest ) ); + arrays[ &cTest.m ] = Info( "cTest.m", sizeof( cTest.m ) ); + } +} + +void check_constr() { + int x = cTest.m[6]; +} + +struct Incomplete { + static const int incomp[]; + static int check_incomp() { + return incomp[0] + incomp[1]; + } +}; + +const int Incomplete::incomp[2] = { 1, 2 }; + + +int main() { + NameMap::register_vars(); + + cout << "Basic Checks:" << endl; + check_basic(); + + cout << endl << endl << "Checking dual Weaving:" << endl; + check_dual(); + + cout << endl << endl << "Checking partial dual Weaving:" << endl; + check_dual_partial1(); + check_dual_partial2(); + check_dual_partial3(); + + cout << endl << endl << "Checking proceed:" << endl; + check_proceed(); + + cout << endl << endl << "Checking action:" << endl; + check_action(); + + cout << endl << endl << "Checking tunneling:" << endl; + check_tunnel(); + + cout << endl << endl << "Checking qualified accesses:" << endl; + check_qualified(); + + cout << endl << endl << "Checking interaction with other types:" << endl; + check_interaction(); + + NameMap::register_vars2(); + + cout << endl << endl << "Checking interaction with construction advice:" << endl; + check_constr(); + + cout << endl << endl << "Checking incomplete array type:" << endl; + Incomplete::check_incomp(); + + return 0; +} diff --git a/AspectC++/tests/ArrayAccessAdvice/namemap.cc b/AspectC++/tests/ArrayAccessAdvice/namemap.cc new file mode 100644 index 0000000..6adc9df --- /dev/null +++ b/AspectC++/tests/ArrayAccessAdvice/namemap.cc @@ -0,0 +1,35 @@ +#include +#include + +using namespace std; + +namespace NameMap { + typedef std::pair Info; + typedef map Map; + Map objs; + Map arrays; + + void mangle_arraypart( void *addr, size_t s ) { + void *base = 0; + const char * name = 0; + size_t diff = 0; + Map::iterator it = arrays.upper_bound( addr ); + if( it != arrays.begin() ) { + --it; + base = it->first; + name = it->second.first; + diff = ( reinterpret_cast( addr ) - reinterpret_cast( base ) ); + + if( diff >= it->second.second ) + name = 0; + + diff /= s; + } + + if( name ) { + cout << name << "+" << diff; + } + else + cout << ""; + } +} diff --git a/AspectC++/tests/ArrayAccessAdvice/namemap.h b/AspectC++/tests/ArrayAccessAdvice/namemap.h new file mode 100644 index 0000000..9678fee --- /dev/null +++ b/AspectC++/tests/ArrayAccessAdvice/namemap.h @@ -0,0 +1,18 @@ +#ifndef __NAMEMAP_H__ +#define __NAMEMAP_H__ + +#include + +namespace NameMap { + typedef std::pair Info; + typedef std::map Map; + extern Map objs; + extern Map arrays; + + extern void mangle_arraypart( void *addr, size_t s ); + template inline void mangle_arraypart( T* addr ) { + mangle_arraypart( addr, sizeof( *addr ) ); + } +} + +#endif diff --git a/AspectC++/tests/ArrayAccessAdvice/trace.ah b/AspectC++/tests/ArrayAccessAdvice/trace.ah new file mode 100644 index 0000000..5571d07 --- /dev/null +++ b/AspectC++/tests/ArrayAccessAdvice/trace.ah @@ -0,0 +1,105 @@ +#ifndef __TRACE_AH__ +#define __TRACE_AH__ + +#include +#include "namemap.h" + +using namespace std; + +template struct IdxPrinter { + inline static void print( TJP *tjp ) { + IdxPrinter::print( tjp ); + cout << "[" << tjp->template idx() << "|" << TJP::template Dim::Size << "]"; + } +}; +template struct IdxPrinter { + inline static void print( TJP *tjp ) {} +}; +template struct ValPrinter { + inline static void print( T e ) { cout << " < " << e << " >"; } +}; +template struct ValPrinter { + inline static void print( T a[D] ) { cout << " < "; NameMap::mangle_arraypart( a ); cout << "[" << D << "] >"; } +}; +template struct ValPrinter { + inline static void print( T* p ) { cout << " < ~~ADDR~~ >"; } +}; +template<> struct ValPrinter< map > { + inline static void print( map &m ) { cout << " < ~~OBJ~~ >"; } +}; + +aspect Tracer { + template struct is_arraymember { + static const bool result = false; + }; + template struct is_arraymember { + static const bool result = true; + }; + template inline void print_indices( TJP *tjp ) { + IdxPrinter::print( tjp ); + } + template inline void print_entity( TJP *tjp ) { + cout << tjp->signature() << " @ "; NameMap::mangle_arraypart( tjp->entity() ); + ValPrinter::print( *tjp->entity() ); + if( tjp->target() ) { + const char * name = NameMap::objs[ tjp->target() ].first; + cout << " -> " << ( name ? name : "" ); + cout << " ? " << ( is_arraymember::result ? "true" : "false" ) << " | " << tjp->memberptr(); + } + if( tjp->array() ) { + const char * name = NameMap::arrays[ tjp->array() ].first; + cout << " | " << ( name ? name : "" ); + print_indices( tjp ); + } + } +#define INCTJP tjp->entity(); tjp->signature(); tjp->target(); tjp->memberptr(); tjp->array(); tjp->idx<0>(); + + pointcut ignore() = within( "NameMap" ); + + advice get( "% ...::%" ) && ! ignore() : before() { + INCTJP + + cout << "~~~ Get: "; + print_entity( tjp ); + cout << endl; + } + + advice set( "% ...::%" ) && ! ignore() : before() { + INCTJP + + cout << "~~~ Set: "; + print_entity( tjp ); + cout << " := " << *( tjp->template arg<0>() ); + cout << endl; + } + + advice ref( "% ...::%" ) && ! ignore() : before() { + INCTJP + + cout << "~~~ Ref: "; + print_entity( tjp ); + cout << endl; + } + + advice get( alias( "% ...::%" ) ) && ! ignore() : before() { + INCTJP + + cout << "~~~ Get (alias): "; + print_entity( tjp ); + cout << endl; + } + + advice set( alias( "% ...::%" ) ) && ! ignore() : before() { + INCTJP + + cout << "~~~ Set (alias): "; + print_entity( tjp ); + cout << " := " << *( tjp->template arg<0>() ); + cout << endl; + } + + advice construction( "CTest" ) : before() { + cout << "~~~ Construct: " << tjp->signature() << endl; + } +}; +#endif diff --git a/AspectC++/tests/ArrayMangling/Makefile b/AspectC++/tests/ArrayMangling/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/ArrayMangling/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/ArrayMangling/feature.ref b/AspectC++/tests/ArrayMangling/feature.ref new file mode 100644 index 0000000..7ee1c6f --- /dev/null +++ b/AspectC++/tests/ArrayMangling/feature.ref @@ -0,0 +1,5 @@ +ArrayMangling +============================================================= +this is a quite complicated signature with array types +void f(int *,int *,int **,int (*)[4],int (*)[10],int (*(*)())[3],int (**)[14],double (C::*)(long int *(*)[64])) +============================================================= diff --git a/AspectC++/tests/ArrayMangling/main.cc b/AspectC++/tests/ArrayMangling/main.cc new file mode 100644 index 0000000..7652d19 --- /dev/null +++ b/AspectC++/tests/ArrayMangling/main.cc @@ -0,0 +1,35 @@ +#include + +class C {}; + +void f (int a1[], + int a2[2], + int *a3[3], + int (*a4)[4], + int a5[5][10], + int (*(*a6)())[3], + int (*a7[7])[14], + double (C::*a8)(long *(a[32])[64]) = 0) { +} + +aspect Nonsense { + advice execution ("% f(...)") : before () { + printf ("%s\n", tjp->signature ()); + } +}; + +int main () { + int a1[] = { 1, 2 }; + int a2[2] = { 3, 4 }; + int *a3[3]; + int (*a4)[4] = 0; + int a5[5][10]; + int (*(*a6)())[3] = 0; + int (*a7[7])[14]; + printf ("ArrayMangling\n"); + printf ("=============================================================\n"); + printf ("this is a quite complicated signature with array types\n"); + f (a1, a2, a3, a4, a5, a6, a7); + printf ("=============================================================\n"); + return 0; +} diff --git a/AspectC++/tests/ArrayWrapper/Makefile b/AspectC++/tests/ArrayWrapper/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/ArrayWrapper/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/ArrayWrapper/feature.ref b/AspectC++/tests/ArrayWrapper/feature.ref new file mode 100644 index 0000000..b200958 --- /dev/null +++ b/AspectC++/tests/ArrayWrapper/feature.ref @@ -0,0 +1,7 @@ +ArrayWrapper: tests if wrapped arrays behave like arrays +======================================================== +before C::C() +after C::C() +before C::C(const C &) +after C::C(const C &) +======================================================== diff --git a/AspectC++/tests/ArrayWrapper/main.cc b/AspectC++/tests/ArrayWrapper/main.cc new file mode 100644 index 0000000..c588f24 --- /dev/null +++ b/AspectC++/tests/ArrayWrapper/main.cc @@ -0,0 +1,66 @@ +#include +#include + +struct S { + int i; + int j; + S () {} + void g () const {} +}; + +void f1 (S a[1]) {} +void f2 (S *a) {} +void f3 (S (&a)[2]) {} + +class C { +public: + C () {} + S a[2]; + char b[10]; + union { + short shortVal; + int intVal; + char* stringVal; + }; + union { + int blibs; + double blubs; + }; + char *str () const { return (char*)b; } +}; + +aspect TestCopyConstructorGeneration { + advice construction ("C") : around () { + printf ("before %s\n", JoinPoint::signature ()); + tjp->proceed (); + printf ("after %s\n", JoinPoint::signature ()); + } +}; + +int main () { + printf ("ArrayWrapper: tests if wrapped arrays behave like arrays\n"); + printf ("========================================================\n"); + const C cc; + C c (cc); + cc.a[0]; + &cc.a[0]; + c.a[0]; + &c.a[0]; + const S *p = 0; + p = &c.a[1l]; + c.a[1] = c.a[0]; + c.a[0] = cc.a[0]; + c.a[0].g (); + // error ... + // cc.a[0] = c.a[0]; + memcpy (c.a, cc.a, sizeof (c.a)); + f1 (c.a); + f2 (c.a); + // another error + // f3 (cc.a); + f3 (c.a); + &c.a; + printf ("========================================================\n"); + return 0; +} + diff --git a/AspectC++/tests/AspectOf/Makefile b/AspectC++/tests/AspectOf/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/AspectOf/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/AspectOf/feature.ref b/AspectC++/tests/AspectOf/feature.ref new file mode 100644 index 0000000..9668dce --- /dev/null +++ b/AspectC++/tests/AspectOf/feature.ref @@ -0,0 +1,8 @@ +AspectOf: non-default aspect instantiation test +=============================================== +ID 1: inside A::a(4711, 3.140000) +----------------------------------------------- +ID 2: inside C::c(4, 5) +----------------------------------------------- +ID 1: inside A::a(4712, 2.710000) +=============================================== diff --git a/AspectC++/tests/AspectOf/main.cc b/AspectC++/tests/AspectOf/main.cc new file mode 100644 index 0000000..afb3087 --- /dev/null +++ b/AspectC++/tests/AspectOf/main.cc @@ -0,0 +1,46 @@ +#include + +aspect A { + int _obj_id; + static int _obj_count; + advice "C": slice struct { A _aspect_instance; }; + static A *aspectof () { + JoinPoint::That *that = tjp->that (); + return &that->_aspect_instance; + } + advice construction ("C"): before () { + _obj_id = ++_obj_count; + } + advice execution("C") : before () { + printf ("ID %d: ", _obj_id); + } +}; + +class C { +public: + int a(int i, float b) { + printf("inside A::a(%d, %f)\n", i, b); + return i; + } + int c(int p, int q); +}; + +int C::c(int p, int q){ + printf("inside C::c(%d, %d)\n",p,q); + return p; +} + +int main() { + C c1; + C c2; + printf ("AspectOf: non-default aspect instantiation test\n"); + printf ("===============================================\n"); + c1.a(4711, 3.14f); + printf ("-----------------------------------------------\n"); + c2.c(4,5); + printf ("-----------------------------------------------\n"); + c1.a(4712, 2.71f); + printf ("===============================================\n"); +} + +int A::_obj_count = 0; diff --git a/AspectC++/tests/AspectPrivileges/Makefile b/AspectC++/tests/AspectPrivileges/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/AspectPrivileges/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/AspectPrivileges/feature.ref b/AspectC++/tests/AspectPrivileges/feature.ref new file mode 100644 index 0000000..db4970e --- /dev/null +++ b/AspectC++/tests/AspectPrivileges/feature.ref @@ -0,0 +1,13 @@ +AspectPrivileges: Check whether aspects are friends of all classes +================================================================== +printing private attribute + private attribute: 0 +increasing private attribute by calling private member function + in private function +printing private attribute again + private attribute: 1 +writing into private attribute of introduced class +writing into private attribute of a union +calling private member function of template + in private T::f() +================================================================== diff --git a/AspectC++/tests/AspectPrivileges/main.cc b/AspectC++/tests/AspectPrivileges/main.cc new file mode 100644 index 0000000..e2c2b6d --- /dev/null +++ b/AspectC++/tests/AspectPrivileges/main.cc @@ -0,0 +1,58 @@ +#include + +class C { + int _priv_attr; + void priv_fct () { printf (" in private function\n"); _priv_attr++; } +public: + C() : _priv_attr (0) {} + void pub_fct () {} +}; + +union U { + int u1; + char u2; +}; + +slice class Slice { + int _priv_slice_attr; + class Inner { + int _priv_inner_attr; + public: + Inner () : _priv_inner_attr (0) {} + } _inner; + union InnerUnion { + int i; + long j; + } _inner_union; +}; + +template class T { static void f() { printf (" in private T::f()\n"); } }; + +int main() { + C c; + printf ("AspectPrivileges: Check whether aspects are friends of all classes\n"); + printf ("==================================================================\n"); + c.pub_fct (); + printf ("==================================================================\n"); +} + +aspect A { + U _u; + + advice "C" : slice Slice; + + advice execution("void C::pub_fct()") : before () { + printf ("printing private attribute\n"); + printf (" private attribute: %d\n", tjp->that ()->_priv_attr); + printf ("increasing private attribute by calling private member function\n"); + tjp->that ()->priv_fct (); + printf ("printing private attribute again\n"); + printf (" private attribute: %d\n", tjp->that ()->_priv_attr); + printf ("writing into private attribute of introduced class\n"); + tjp->that ()->_inner._priv_inner_attr++; + printf ("writing into private attribute of a union\n"); + _u.u1 = 42; + printf ("calling private member function of template\n"); + T::f(); + } +}; diff --git a/AspectC++/tests/AttribAligned/Makefile b/AspectC++/tests/AttribAligned/Makefile new file mode 100644 index 0000000..f485359 --- /dev/null +++ b/AspectC++/tests/AttribAligned/Makefile @@ -0,0 +1,2 @@ +ACFLAGS ?= --introspection +include ../Makefile.generic diff --git a/AspectC++/tests/AttribAligned/feature.ref b/AspectC++/tests/AttribAligned/feature.ref new file mode 100644 index 0000000..5f4f374 --- /dev/null +++ b/AspectC++/tests/AttribAligned/feature.ref @@ -0,0 +1 @@ +sizeof T1(16), T2(2), T3(16) diff --git a/AspectC++/tests/AttribAligned/main.cc b/AspectC++/tests/AttribAligned/main.cc new file mode 100644 index 0000000..5df6b24 --- /dev/null +++ b/AspectC++/tests/AttribAligned/main.cc @@ -0,0 +1,36 @@ +#include + +#ifdef __GNUC__ +typedef char more_aligned_char __attribute__ ((aligned (8))); +#else +typedef struct X { char x[8]; X(){} X(int){} } more_aligned_char; +#endif + +void foo(more_aligned_char x) {} + +int main() { + foo(0); + return 0; +} + +class T1 { more_aligned_char t1, t2; }; // for reference + +class T3 { more_aligned_char t1; }; + +aspect AlignAspect { + advice "T3" : slice class { JoinPoint::Member<0>::Type t2; }; // test Introspection + + advice execution("void foo(%)") : before() { + *tjp->arg<0>(); // needed somehow ... + +#ifdef __GNUC__ + class T2 { JoinPoint::template Arg<0>::Type t1, t2; }; // test JoinPoint API + // ... ignoring attributes on template argument ... +#else + class T2 { char t1, t2 }; +#endif + + printf("sizeof T1(%u), T2(%u), T3(%u)\n", sizeof(T1), sizeof(T2), sizeof(T3)); + } +}; + diff --git a/AspectC++/tests/Attribute_basic/Makefile b/AspectC++/tests/Attribute_basic/Makefile new file mode 100644 index 0000000..5691029 --- /dev/null +++ b/AspectC++/tests/Attribute_basic/Makefile @@ -0,0 +1,3 @@ +ACFLAGS ?= --data_joinpoints --builtin_operators -D "__cplusplus=201103L" +CXXFLAGS ?= -std=c++11 +include ../Makefile.generic diff --git a/AspectC++/tests/Attribute_basic/feature.ref b/AspectC++/tests/Attribute_basic/feature.ref new file mode 100644 index 0000000..2780aba --- /dev/null +++ b/AspectC++/tests/Attribute_basic/feature.ref @@ -0,0 +1,10 @@ +Execution or Construction +var set! +var set - other Attr! +Execution of namespaceAttr +Execution or Construction +Execution of funny member +Execution of namespaceAttr +Execution or Construction +Execution of other Attr +This function will not return!! diff --git a/AspectC++/tests/Attribute_basic/main.cc b/AspectC++/tests/Attribute_basic/main.cc new file mode 100644 index 0000000..7cebff3 --- /dev/null +++ b/AspectC++/tests/Attribute_basic/main.cc @@ -0,0 +1,86 @@ +#include +#include + +using namespace std; + +attribute noreturn(); + +namespace [[ out::namespaceAttr ]] N { +} + +struct [[out::classAttr()]] myClass; + +struct myClass { + [[noreturn]][[out::funcAttr]] void func [[out::otherAttr]] () {exit(0);} + + [[out::varAttr]] int var [[out::otherAttr]]; +}; + +namespace N { + namespace [[out::innerNsAttr]] N2 { + void func() { } + struct [[out::classAttr]] C { + static void func() {} + }; + } +} + +int main() +{ + myClass obj; + obj.var = 0; + N::N2::func(); + N::N2::C::func(); + obj.func(); + + return 0; +} + + +aspect out { + attribute classAttr(); + attribute funcAttr(); + attribute varAttr(); + attribute namespaceAttr(); + attribute innerNsAttr(); + + attribute otherAttr(); + + pointcut all() = classAttr() || funcAttr(); + + advice execution(all()) || construction(all()) : before() { + cout << "Execution or Construction" << endl; + } + + advice construction(otherAttr()) : before() { + cout << "Failed: This attribute should have no affect!" << endl; + } + + advice execution(otherAttr()) : before() { + cout << "Execution of other Attr" << endl; + } + + advice execution(member(classAttr() && member(namespaceAttr()))) : before() { + cout << "Execution of funny member" << endl; + } + + advice execution(namespaceAttr()) : before() { + cout << "Execution of namespaceAttr" << endl; + } + + advice execution(namespaceAttr() && !innerNsAttr()) : before() { + cout << "Failed: This execution should be filtered!" << endl; + } + + advice set(varAttr()) : before() { + cout << "var set!" << endl; + } + + advice set(otherAttr()) : before() { + cout << "var set - other Attr!" << endl; + } + + advice execution(noreturn()) : before() { + cout << "This function will not return!!" << endl; + } +}; diff --git a/AspectC++/tests/Attribute_inMacro/Makefile b/AspectC++/tests/Attribute_inMacro/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Attribute_inMacro/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Attribute_inMacro/feature.ref b/AspectC++/tests/Attribute_inMacro/feature.ref new file mode 100644 index 0000000..9d83483 --- /dev/null +++ b/AspectC++/tests/Attribute_inMacro/feature.ref @@ -0,0 +1,4 @@ +Test successfull - first advice! +Test successfull - second advice! +Test successfull - first advice! +Test successfull - second advice! diff --git a/AspectC++/tests/Attribute_inMacro/main.cc b/AspectC++/tests/Attribute_inMacro/main.cc new file mode 100644 index 0000000..080335d --- /dev/null +++ b/AspectC++/tests/Attribute_inMacro/main.cc @@ -0,0 +1,37 @@ +#include + +#define attrDef attribute test() +#define attrName1 [[myAttr::test]] +#define attrName2 myAttr::test + +#define className MyClass + + +namespace myAttr { +attrDef; +} + +struct className { + attrName1 int myFunc() {return 0;} + [[ attrName2 ]] int mySecondFunc() {return 0;} +}; + +int main() +{ + MyClass a; + a.myFunc(); + a.mySecondFunc(); + return 0; +} + +aspect output { + advice execution( attrName2() ) : before() { + using namespace std; + cout << "Test successfull - first advice!" << endl; + } + + advice execution( myAttr::test() ) : before() { + using namespace std; + cout << "Test successfull - second advice!" << endl; + } +}; diff --git a/AspectC++/tests/Attribute_pointcuts/Makefile b/AspectC++/tests/Attribute_pointcuts/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Attribute_pointcuts/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Attribute_pointcuts/Test.ah b/AspectC++/tests/Attribute_pointcuts/Test.ah new file mode 100644 index 0000000..f0ac488 --- /dev/null +++ b/AspectC++/tests/Attribute_pointcuts/Test.ah @@ -0,0 +1,34 @@ +#include + +namespace acc { + attribute myNoreturn(); + attribute aha(typename X, template class A); + attribute myAttr(int i, void (*param)(int)); + attribute myNNAttr(typename X, X& b); + attribute wholeFunc(int a); + attribute hi(int a, const char* B); +} + +aspect funcModifierClass { + advice construction ("[[acc::aha(int, List)]]") : before() { + std::cout << "ClassAttributed" << std::endl; + } +}; + +aspect funcModifierClassFail { + advice construction ("[[acc::aha(char, List)]]") : before() { + std::cout << "ClassAttributed failed" << std::endl; + } +}; + +aspect funcModifierFail { + advice execution (/*"% %(...)"*/"[[acc::myNNAttr(Core, co2)]]" && "[[acc::hi( 3, \"al\" \"oa\" )]]" && "[[acc::aha(char, List)]]") && within("[[acc::aha(int, List)]]") : before() { + std::cout << "FunctionAttributed faied" << std::endl; + } +}; + +aspect funcModifier { + advice execution (/*"% %(...)"*/"[[acc::myNNAttr(Core, co)]]" && "[[acc::hi( 3, \"al\" \"oa\" )]]" && "[[acc::aha(char, List)]]") && within("[[acc::aha(int, List)]]") : before() { + std::cout << "FunctionAttributed" << std::endl; + } +}; diff --git a/AspectC++/tests/Attribute_pointcuts/feature.ref b/AspectC++/tests/Attribute_pointcuts/feature.ref new file mode 100644 index 0000000..e8bd7c0 --- /dev/null +++ b/AspectC++/tests/Attribute_pointcuts/feature.ref @@ -0,0 +1,3 @@ +ClassAttributed +FunctionAttributed +ClassAttributed diff --git a/AspectC++/tests/Attribute_pointcuts/main.cc b/AspectC++/tests/Attribute_pointcuts/main.cc new file mode 100644 index 0000000..eb5f551 --- /dev/null +++ b/AspectC++/tests/Attribute_pointcuts/main.cc @@ -0,0 +1,34 @@ +//#include +#include +#include + +#define ATTR [[ac::typeDefAttr]] +#define TESTNN [[Test]] + +template struct List : std::vector { }; + +void func(int ab) { + +} + +int attrParam; + +class Core2 {}; + +class Core {}; + +Core co; + +class [[acc::aha(int, List)]] myClass { +public: +[[acc::myNNAttr(Core, co), acc::wholeFunc(4)]] int hi [[acc::myNoreturn, acc::aha(char, List), acc::hi(3, "alo" "a"), acc::myAttr(8, func)]] [[acc::myAttr(4, func)]] (const int a, const char b[], int c) { + return c; +} +}; + +int main() { + myClass mC; + mC.hi(5, "as", 0); + myClass mC2; + return 0; +} diff --git a/AspectC++/tests/Attribute_removeAttrs/Makefile b/AspectC++/tests/Attribute_removeAttrs/Makefile new file mode 100644 index 0000000..17f8501 --- /dev/null +++ b/AspectC++/tests/Attribute_removeAttrs/Makefile @@ -0,0 +1,3 @@ +ACFLAGS ?= --data_joinpoints --builtin_operators -D "__cplusplus=201103L" +CXXFLAGS ?= -std=c++11 -Werror +include ../Makefile.generic diff --git a/AspectC++/tests/Attribute_removeAttrs/feature.ref b/AspectC++/tests/Attribute_removeAttrs/feature.ref new file mode 100644 index 0000000..f599e28 --- /dev/null +++ b/AspectC++/tests/Attribute_removeAttrs/feature.ref @@ -0,0 +1 @@ +10 diff --git a/AspectC++/tests/Attribute_removeAttrs/main.cc b/AspectC++/tests/Attribute_removeAttrs/main.cc new file mode 100644 index 0000000..5253987 --- /dev/null +++ b/AspectC++/tests/Attribute_removeAttrs/main.cc @@ -0,0 +1,30 @@ +#include + +using namespace std; + +namespace myAttr { + attribute attr(); +} + +//test if Attributes are removed +//this would cause a warning if it is not removed +class [[myAttr::attr]] myClass {}; + + +int a = 0; + +//if attribute is found by following compiler +//this function is called before entering +//main()-function. +void constructA [[gnu::constructor]] () { + a = 10; +} + +int main() { + //if attribute not found: 0 + //if attribute found: 10 + cout << a << endl; + + return 0; +} + diff --git a/AspectC++/tests/Base/Makefile b/AspectC++/tests/Base/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Base/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Base/feature.ref b/AspectC++/tests/Base/feature.ref new file mode 100644 index 0000000..0702418 --- /dev/null +++ b/AspectC++/tests/Base/feature.ref @@ -0,0 +1,22 @@ +Base: test the 'base' pointcut function: +======================================== + before base("C3") + before base("% C3::f(double)") + void C1::f(double) +---------------------------------------- + before base("C3") + void C1::f() +---------------------------------------- + before base("C3") + before base("% C3::f(double)") + void C2::f(double) +---------------------------------------- + before base("C3") + before base("% C3::f(X&)") + void C2::f(X&) +---------------------------------------- + before base("C3") + void C2::x() +---------------------------------------- + void C3::f() +======================================== diff --git a/AspectC++/tests/Base/main.cc b/AspectC++/tests/Base/main.cc new file mode 100644 index 0000000..58a5031 --- /dev/null +++ b/AspectC++/tests/Base/main.cc @@ -0,0 +1,80 @@ +#include + +struct X { + X () {} +}; + +struct C1 { + void x () { + printf (" void C1::x()\n"); + } + void f () { + printf (" void C1::f()\n"); + } + void f (double) { + printf (" void C1::f(double)\n"); + } + void f (const X&) { + printf (" void C1::f(X&)\n"); + } +}; + +struct C2 : C1 { + void x () { + printf (" void C2::x()\n"); + } + void f () { + printf (" void C2::f()\n"); + } + void f (double) { + printf (" void C2::f(double)\n"); + } + void f (const X&) { + printf (" void C2::f(X&)\n"); + } +}; + +struct C3 : C2 { + void x () { + printf (" void C3::x()\n"); + } + void f () { + printf (" void C3::f()\n"); + } + void f (double) { + printf (" void C3::f(double)\n"); + } + void f (const X&) { + printf (" void C3::f(X&)\n"); + } +}; + +aspect Tracer { + advice execution (base ("C3")) : before () { + printf (" before base(\"C3\")\n"); + } + advice execution (base ("% C3::f(double)")) : before () { + printf (" before base(\"%% C3::f(double)\")\n"); + } + advice execution (base ("% C3::f(X&)")) : before () { + printf (" before base(\"%% C3::f(X&)\")\n"); + } +}; + +int main() { + C3 c; + printf ("Base: test the 'base' pointcut function:\n"); + printf ("========================================\n"); + c.C1::f (3.0); + printf ("----------------------------------------\n"); + c.C1::f (); + printf ("----------------------------------------\n"); + c.C2::f (3.0); + printf ("----------------------------------------\n"); + c.C2::f (X ()); + printf ("----------------------------------------\n"); + c.C2::x (); + printf ("----------------------------------------\n"); + c.C3::f (); + printf ("========================================\n"); +} diff --git a/AspectC++/tests/Bug-Typenames/Makefile b/AspectC++/tests/Bug-Typenames/Makefile new file mode 100644 index 0000000..daa5e9e --- /dev/null +++ b/AspectC++/tests/Bug-Typenames/Makefile @@ -0,0 +1,2 @@ +ACFLAGS ?= --builtin_operators --data_joinpoints +include ../Makefile.generic diff --git a/AspectC++/tests/Bug-Typenames/feature.ref b/AspectC++/tests/Bug-Typenames/feature.ref new file mode 100644 index 0000000..a2ec58b --- /dev/null +++ b/AspectC++/tests/Bug-Typenames/feature.ref @@ -0,0 +1,3 @@ +Cyg_Mqueue::qentry *Cyg_Mqueue::q +double (*test2())(int) +HH \ No newline at end of file diff --git a/AspectC++/tests/Bug-Typenames/main.cc b/AspectC++/tests/Bug-Typenames/main.cc new file mode 100644 index 0000000..1189b05 --- /dev/null +++ b/AspectC++/tests/Bug-Typenames/main.cc @@ -0,0 +1,47 @@ +#include +using namespace std; + +class Cyg_Mqueue { +public: + struct qentry { + struct qentry *next; + }; + + struct qentry *q; +}; + +typedef double (*fnt)( int ); + +double test( int a ) { + return a / 2.0; +} + +fnt test2() { + std::cout << "H"; + return &test; +} + +int main() { + Cyg_Mqueue mq; + mq.q = 0; + + test2(); + return 0; +} + +aspect Setter { + advice set("% Cyg_Mqueue::%") : before() { + cout << tjp->signature() << endl; + } +}; + +aspect Caller { + advice call("% Cyg_Mqueue::%(...)") : before() { + cout << tjp->signature() << endl; + } +}; + +aspect GenericCaller { + advice call("% %(...)"): before() { std::cout << tjp->signature() << std::endl; (*tjp->entity())(); } +}; + diff --git a/AspectC++/tests/Bug179/Makefile b/AspectC++/tests/Bug179/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug179/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug179/feature.ref b/AspectC++/tests/Bug179/feature.ref new file mode 100644 index 0000000..996a497 --- /dev/null +++ b/AspectC++/tests/Bug179/feature.ref @@ -0,0 +1,4 @@ +Bug179: advice for main without return statement +================================================ +in main +================================================ diff --git a/AspectC++/tests/Bug179/main.cc b/AspectC++/tests/Bug179/main.cc new file mode 100644 index 0000000..da42745 --- /dev/null +++ b/AspectC++/tests/Bug179/main.cc @@ -0,0 +1,15 @@ +#include + +aspect AroundMain { + advice execution ("% main(...)") : around () { + printf ("Bug179: advice for main without return statement\n"); + printf ("================================================\n"); + tjp->proceed (); + printf ("================================================\n"); + } +}; + +int main() { + printf ("in main\n"); + // note: here is no return, which is perfectly valid C/C++. +} diff --git a/AspectC++/tests/Bug190/Makefile b/AspectC++/tests/Bug190/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug190/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug190/feature.ref b/AspectC++/tests/Bug190/feature.ref new file mode 100644 index 0000000..3fdff44 --- /dev/null +++ b/AspectC++/tests/Bug190/feature.ref @@ -0,0 +1,2 @@ +before function "void f(int)" +before function "void f(float)" diff --git a/AspectC++/tests/Bug190/main.cc b/AspectC++/tests/Bug190/main.cc new file mode 100644 index 0000000..283ed9c --- /dev/null +++ b/AspectC++/tests/Bug190/main.cc @@ -0,0 +1,16 @@ +#include + +aspect Bug190 { + advice execution ("% f(...)") : before () { + printf ("before function \"%s\"\n", JoinPoint::signature ()); + } +}; + +void f (int) {} +void f (float) {} + +int main () { + f (2); + f (3.14f); + return 0; +} diff --git a/AspectC++/tests/Bug191/Makefile b/AspectC++/tests/Bug191/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug191/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug191/feature.ref b/AspectC++/tests/Bug191/feature.ref new file mode 100644 index 0000000..fa789d0 --- /dev/null +++ b/AspectC++/tests/Bug191/feature.ref @@ -0,0 +1 @@ +before function "void *volatile f(void *)" diff --git a/AspectC++/tests/Bug191/main.cc b/AspectC++/tests/Bug191/main.cc new file mode 100644 index 0000000..07d1f43 --- /dev/null +++ b/AspectC++/tests/Bug191/main.cc @@ -0,0 +1,18 @@ +#include + +aspect Bug191 { + advice execution ("% * volatile ...::%(...)") : around () { + printf ("before function \"%s\"\n", JoinPoint::signature ()); + tjp->proceed (); + } +}; + +typedef void * volatile VPTR; + +VPTR f (VPTR a) { VPTR p = 0; return p; } + +int main () { + VPTR a = 0; + VPTR p = f (a); + return 0; +} diff --git a/AspectC++/tests/Bug192/Makefile b/AspectC++/tests/Bug192/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug192/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug192/feature.ref b/AspectC++/tests/Bug192/feature.ref new file mode 100644 index 0000000..ba1d4f1 --- /dev/null +++ b/AspectC++/tests/Bug192/feature.ref @@ -0,0 +1 @@ +before JP 'void f(Foo &,ABC,Named)' diff --git a/AspectC++/tests/Bug192/main.cc b/AspectC++/tests/Bug192/main.cc new file mode 100644 index 0000000..2fdb6e2 --- /dev/null +++ b/AspectC++/tests/Bug192/main.cc @@ -0,0 +1,19 @@ +#include + +aspect Bug192 { + advice execution ("void f(...)") : before () { + printf ("before JP '%s'\n", JoinPoint::signature ()); + } +}; + +typedef struct { int _i; } Foo; +typedef enum { A, B, C } ABC; +enum Named { D, E }; +typedef Named DE; +void f (Foo &arg, ABC abc, DE de) {} + +int main () { + Foo foo; + f (foo, A, D); + return 0; +} diff --git a/AspectC++/tests/Bug207/Makefile b/AspectC++/tests/Bug207/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug207/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug207/feature.ref b/AspectC++/tests/Bug207/feature.ref new file mode 100644 index 0000000..3010ea6 --- /dev/null +++ b/AspectC++/tests/Bug207/feature.ref @@ -0,0 +1,4 @@ +Bug207: ac++ mixes up private and public +============================================================== +Check if methodA and B are still private after weaving +============================================================== diff --git a/AspectC++/tests/Bug207/main.cc b/AspectC++/tests/Bug207/main.cc new file mode 100644 index 0000000..63f318e --- /dev/null +++ b/AspectC++/tests/Bug207/main.cc @@ -0,0 +1,32 @@ +#include + +aspect anotherBaseAspect { + pointcut methods() = execution("% anotherClass::%(...)"); + + advice methods() : before() { + printf("ENTRY: %s\n",JoinPoint::signature()); + } + advice methods() : around() { + printf("ENTRY: %s\n",JoinPoint::signature()); + tjp->proceed (); + } +}; + +class anotherClass { +public: + anotherClass(); + +private: + void methodA(); + void methodB(); +}; + +void anotherClass::methodB () {} + +int main () { + printf ("Bug207: ac++ mixes up private and public\n"); + printf ("==============================================================\n"); + printf ("Check if methodA and B are still private after weaving\n"); + printf ("==============================================================\n"); + return 0; +} diff --git a/AspectC++/tests/Bug209/AbstractTrace.ah b/AspectC++/tests/Bug209/AbstractTrace.ah new file mode 100644 index 0000000..924019f --- /dev/null +++ b/AspectC++/tests/Bug209/AbstractTrace.ah @@ -0,0 +1,22 @@ +#ifndef __Abstract_Trace_ah__ +#define __Abstract_Trace_ah__ + +#include + +using namespace std; + +aspect AbstractTrace { +public: + pointcut pc1() = call("% ...::B::%(...)"); + pointcut pc2() = execution("% ...::B::%(...)"); + + advice pc1() : after () { + cout << "after call " << JoinPoint::signature () << "\n"; + } + + advice pc2() : after () { + cout << "after execution " << JoinPoint::signature () << "\n"; + } +}; + +#endif // __Abstract_Trace_ah__ diff --git a/AspectC++/tests/Bug209/Makefile b/AspectC++/tests/Bug209/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug209/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug209/feature.ref b/AspectC++/tests/Bug209/feature.ref new file mode 100644 index 0000000..1991270 --- /dev/null +++ b/AspectC++/tests/Bug209/feature.ref @@ -0,0 +1,3 @@ +m( 5 ) +after execution void B::m(A) +after call void B::m(A) diff --git a/AspectC++/tests/Bug209/main.cc b/AspectC++/tests/Bug209/main.cc new file mode 100644 index 0000000..11ead00 --- /dev/null +++ b/AspectC++/tests/Bug209/main.cc @@ -0,0 +1,23 @@ +#include +using namespace std; + +template +class A { +public: + T s; +}; + +typedef A myA; + +class B { +public: + void m(myA a){ cout << "m( " << a.s << " )\n"; } +}; + +int main() { + myA a; + a.s = 5; + B b; + b.m(a); + return 0; +} diff --git a/AspectC++/tests/Bug216/Makefile b/AspectC++/tests/Bug216/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug216/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug216/feature.ref b/AspectC++/tests/Bug216/feature.ref new file mode 100644 index 0000000..daaba9f --- /dev/null +++ b/AspectC++/tests/Bug216/feature.ref @@ -0,0 +1,4 @@ +Bug 216: copy constructor generation +==================================== +in IntroductionTarget::IntroductionTarget() +==================================== diff --git a/AspectC++/tests/Bug216/main.cc b/AspectC++/tests/Bug216/main.cc new file mode 100644 index 0000000..df963f3 --- /dev/null +++ b/AspectC++/tests/Bug216/main.cc @@ -0,0 +1,43 @@ +#include + +aspect introductions { + pointcut pTarget() = "IntroductionTarget"; + + public: + + advice pTarget() : slice struct { + struct myStruct { + int member1; + long member2; + float member3; + }; + }; + + advice pTarget() : slice struct { int myArray1[10]; }; + advice pTarget() : slice struct { myStruct myArray2[10]; }; + +}; + +class IntroductionTarget { +}; + +aspect abstract_trace_construction { + pointcut virtual pClasses() = 0; + + private: + advice construction(pClasses()) : before () { + printf("in %s\n",JoinPoint::signature()); + } +}; + +aspect trace : public abstract_trace_construction { + pointcut pClasses() = "IntroductionTarget"; +}; + +int main () { + printf ("Bug 216: copy constructor generation\n"); + printf ("====================================\n"); + IntroductionTarget it; + printf ("====================================\n"); + return 0; +} diff --git a/AspectC++/tests/Bug228/Makefile b/AspectC++/tests/Bug228/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug228/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug228/feature.ref b/AspectC++/tests/Bug228/feature.ref new file mode 100644 index 0000000..64793c1 --- /dev/null +++ b/AspectC++/tests/Bug228/feature.ref @@ -0,0 +1 @@ +my_trace_call CALLING: int mySimpleTemplateClass<10>::getArraySize() diff --git a/AspectC++/tests/Bug228/main.cc b/AspectC++/tests/Bug228/main.cc new file mode 100644 index 0000000..a4546de --- /dev/null +++ b/AspectC++/tests/Bug228/main.cc @@ -0,0 +1,19 @@ +#include + +template < int I > class mySimpleTemplateClass { + private: + int myArray[I]; + public: + int getArraySize() { return I; } +}; + +aspect my_trace_call { + advice call("mySimpleTemplateClass<...>") : before () { + printf("my_trace_call CALLING: %s\n",JoinPoint::signature()); + } +}; + +int main () { + mySimpleTemplateClass<10> t; + t.getArraySize (); +} diff --git a/AspectC++/tests/Bug234-2/Makefile b/AspectC++/tests/Bug234-2/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug234-2/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug234-2/feature.ref b/AspectC++/tests/Bug234-2/feature.ref new file mode 100644 index 0000000..d71d9f7 --- /dev/null +++ b/AspectC++/tests/Bug234-2/feature.ref @@ -0,0 +1,5 @@ +Bug234-2: another test for Bug234 +================================= +introTargetMethod(a): a = 5! +int this_func(5) +================================= diff --git a/AspectC++/tests/Bug234-2/introTarget.cc b/AspectC++/tests/Bug234-2/introTarget.cc new file mode 100644 index 0000000..b907d65 --- /dev/null +++ b/AspectC++/tests/Bug234-2/introTarget.cc @@ -0,0 +1,7 @@ +#include "introTarget.hxx" +#include "stdio.h" + +int introTarget::introTargetMethod(int i) { + printf("introTargetMethod(a): a = %d!\n",i); + return 0; +} diff --git a/AspectC++/tests/Bug234-2/introTarget.hxx b/AspectC++/tests/Bug234-2/introTarget.hxx new file mode 100644 index 0000000..ef01cff --- /dev/null +++ b/AspectC++/tests/Bug234-2/introTarget.hxx @@ -0,0 +1,9 @@ +#ifndef __introTarget_hxx__ +#define __introTarget_hxx__ + +class introTarget { +public: + int introTargetMethod(int i); +}; + +#endif /* __introTarget_hxx__ */ diff --git a/AspectC++/tests/Bug234-2/main.cc b/AspectC++/tests/Bug234-2/main.cc new file mode 100644 index 0000000..35ef228 --- /dev/null +++ b/AspectC++/tests/Bug234-2/main.cc @@ -0,0 +1,17 @@ +#include "stdio.h" +#include "introTarget.hxx" + +int this_func(int i) { + printf("int this_func(%d)\n", i); + return i + 3; +} + +int main() { + printf ("Bug234-2: another test for Bug234\n"); + printf ("=================================\n"); + introTarget bumsbla; + + bumsbla.set_a_func(this_func); + bumsbla.introTargetMethod(5); + printf ("=================================\n"); +} diff --git a/AspectC++/tests/Bug234-2/myAspect.ah b/AspectC++/tests/Bug234-2/myAspect.ah new file mode 100644 index 0000000..25cd9e7 --- /dev/null +++ b/AspectC++/tests/Bug234-2/myAspect.ah @@ -0,0 +1,34 @@ +/* -*- c++ -*- */ +#ifndef __myAspect_ah__ +#define __myAspect_ah__ + +typedef int (*my_func)(int); + +aspect myAspect { + advice "introTarget" : slice struct { my_func a_func; }; + + public: + advice "introTarget" : slice struct { + void set_a_func(my_func b_func) { + a_func = b_func; + } + }; + + advice "introTarget" : slice struct { + my_func get_a_func() { + return a_func; + } + }; + + advice construction("introTarget") : after() { + tjp->that()->a_func = 0; + } + + advice execution("introTarget") && args(i) : after(int i) { + if(tjp->that()->a_func != 0) { + *tjp->result() = tjp->that()->a_func(i); + } + } +}; + +#endif /* __myAspect_ah__ */ diff --git a/AspectC++/tests/Bug234/Makefile b/AspectC++/tests/Bug234/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug234/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug234/anotherAspect.ah b/AspectC++/tests/Bug234/anotherAspect.ah new file mode 100644 index 0000000..0a269ca --- /dev/null +++ b/AspectC++/tests/Bug234/anotherAspect.ah @@ -0,0 +1,9 @@ +#ifndef __anotherAspect_ah__ +#define __anotherAspect_ah__ + +#include "introTarget.h" + +aspect anotherAspect { +}; + +#endif /* __anotherAspect_ah__ */ diff --git a/AspectC++/tests/Bug234/feature.ref b/AspectC++/tests/Bug234/feature.ref new file mode 100644 index 0000000..a14ce62 --- /dev/null +++ b/AspectC++/tests/Bug234/feature.ref @@ -0,0 +1,5 @@ +Bug 234: Types from the aspect-header in introductions +====================================================== +introTargetMethod(a): a = 5! +Hallo +====================================================== diff --git a/AspectC++/tests/Bug234/introTarget.cc b/AspectC++/tests/Bug234/introTarget.cc new file mode 100644 index 0000000..a92be2c --- /dev/null +++ b/AspectC++/tests/Bug234/introTarget.cc @@ -0,0 +1,7 @@ +#include "introTarget.h" +#include + +int introTarget::introTargetMethod(int i) { + printf("introTargetMethod(a): a = %d!\n",i); + return 0; +} diff --git a/AspectC++/tests/Bug234/introTarget.h b/AspectC++/tests/Bug234/introTarget.h new file mode 100644 index 0000000..1e6d4e6 --- /dev/null +++ b/AspectC++/tests/Bug234/introTarget.h @@ -0,0 +1,10 @@ +#ifndef __introTarget_hxx__ +#define __introTarget_hxx__ + +class introTarget { +public: + int introTargetMethod(int i); +}; + +#endif /* __introTarget_hxx__ */ + diff --git a/AspectC++/tests/Bug234/main.cc b/AspectC++/tests/Bug234/main.cc new file mode 100644 index 0000000..d2b04c3 --- /dev/null +++ b/AspectC++/tests/Bug234/main.cc @@ -0,0 +1,17 @@ +#include +#include "introTarget.h" + +int meine_funktion(int i) { + printf("Hallo\n"); + return i + 3; +} + +int main() { + printf ("Bug 234: Types from the aspect-header in introductions\n"); + printf ("======================================================\n"); + introTarget bumsbla; + + bumsbla.set_a_func(meine_funktion); + bumsbla.introTargetMethod(5); + printf ("======================================================\n"); +} diff --git a/AspectC++/tests/Bug234/myAspect.ah b/AspectC++/tests/Bug234/myAspect.ah new file mode 100644 index 0000000..19e7e04 --- /dev/null +++ b/AspectC++/tests/Bug234/myAspect.ah @@ -0,0 +1,21 @@ +#ifndef __myAspect_ah__ +#define __myAspect_ah__ + +#include "anotherAspect.ah" +#include "mySlice.ah" + +aspect myAspect { + advice "introTarget" : slice mySlice; + + advice construction("introTarget") : after() { + tjp->that()->a_func = 0; + } + + advice execution("introTarget") && args(i) : after(int i) { + if(tjp->that()->a_func != 0) { + *tjp->result() = tjp->that()->a_func(i); + } + } +}; + +#endif /* __myAspect_ah__ */ diff --git a/AspectC++/tests/Bug234/mySlice.ah b/AspectC++/tests/Bug234/mySlice.ah new file mode 100644 index 0000000..8d74df2 --- /dev/null +++ b/AspectC++/tests/Bug234/mySlice.ah @@ -0,0 +1,13 @@ +#ifndef __mySlice_ah__ +#define __mySlice_ah__ + +typedef int (*my_func)(int); + +slice class mySlice { + my_func a_func; +public: + void set_a_func(my_func b_func) { a_func = b_func; } + my_func get_a_func() { return a_func; } +}; + +#endif /* __mySlice_ah__ */ diff --git a/AspectC++/tests/Bug235/Makefile b/AspectC++/tests/Bug235/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug235/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug235/abstractTrace.ah b/AspectC++/tests/Bug235/abstractTrace.ah new file mode 100644 index 0000000..0d5c055 --- /dev/null +++ b/AspectC++/tests/Bug235/abstractTrace.ah @@ -0,0 +1,18 @@ +#ifndef __abstractTrace_ah__ +#define __abstractTrace_ah__ + +#include + +aspect abstractTrace { + pointcut virtual methods() = 0; + + advice execution(methods()) : before() { + printf("ENTRY: %s\n",tjp->signature()); + } + + advice execution(methods()) : after() { + printf("EXIT: %s\n",tjp->signature()); + } +}; + +#endif /* __abstractTrace_ah__ */ diff --git a/AspectC++/tests/Bug235/classA.h b/AspectC++/tests/Bug235/classA.h new file mode 100644 index 0000000..7a03687 --- /dev/null +++ b/AspectC++/tests/Bug235/classA.h @@ -0,0 +1,13 @@ +#ifndef __classA_hxx__ +#define __classA_hxx__ + +#include "stdio.h" + +class classA { +public: + void methodA() { + printf("void classA::methodA()\n"); + } +}; + +#endif /* __classA_hxx__ */ diff --git a/AspectC++/tests/Bug235/classB.h b/AspectC++/tests/Bug235/classB.h new file mode 100644 index 0000000..363a99f --- /dev/null +++ b/AspectC++/tests/Bug235/classB.h @@ -0,0 +1,13 @@ +#ifndef __classB_hxx__ +#define __classB_hxx__ + +#include "stdio.h" + +class classB { +public: + void methodB() { + printf("void classB::methodB()\n"); + } +}; + +#endif /* __classB_hxx__ */ diff --git a/AspectC++/tests/Bug235/concreteTraceA.ah b/AspectC++/tests/Bug235/concreteTraceA.ah new file mode 100644 index 0000000..6e5673c --- /dev/null +++ b/AspectC++/tests/Bug235/concreteTraceA.ah @@ -0,0 +1,10 @@ +#ifndef __concreteTraceA_ah__ +#define __concreteTraceA_ah__ + +#include "abstractTrace.ah" + +aspect concreteTraceA : public abstractTrace { + pointcut methods() = "classA"; +}; + +#endif /* __concreteTraceA_ah__ */ diff --git a/AspectC++/tests/Bug235/concreteTraceB.ah b/AspectC++/tests/Bug235/concreteTraceB.ah new file mode 100644 index 0000000..425104f --- /dev/null +++ b/AspectC++/tests/Bug235/concreteTraceB.ah @@ -0,0 +1,10 @@ +#ifndef __concreteTraceB_ah__ +#define __concreteTraceB_ah__ + +#include "abstractTrace.ah" + +aspect concreteTraceB : public abstractTrace { + pointcut methods() = "classB"; +}; + +#endif /* __concreteTraceB_ah__ */ diff --git a/AspectC++/tests/Bug235/feature.ref b/AspectC++/tests/Bug235/feature.ref new file mode 100644 index 0000000..60af913 --- /dev/null +++ b/AspectC++/tests/Bug235/feature.ref @@ -0,0 +1,9 @@ +Bug235: buggy project repository with abstract aspects +====================================================== +ENTRY: void classA::methodA() +void classA::methodA() +EXIT: void classA::methodA() +ENTRY: void classB::methodB() +void classB::methodB() +EXIT: void classB::methodB() +====================================================== diff --git a/AspectC++/tests/Bug235/main.cc b/AspectC++/tests/Bug235/main.cc new file mode 100644 index 0000000..1c2853d --- /dev/null +++ b/AspectC++/tests/Bug235/main.cc @@ -0,0 +1,16 @@ +#include "classA.h" +#include "classB.h" + +int main() { + classA classAObject; + classB classBObject; + + printf ("Bug235: buggy project repository with abstract aspects\n"); + printf ("======================================================\n"); + + classAObject.methodA(); + classBObject.methodB(); + + printf ("======================================================\n"); + return 0; +} diff --git a/AspectC++/tests/Bug239/Makefile b/AspectC++/tests/Bug239/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug239/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug239/feature.ref b/AspectC++/tests/Bug239/feature.ref new file mode 100644 index 0000000..a363b9a --- /dev/null +++ b/AspectC++/tests/Bug239/feature.ref @@ -0,0 +1,7 @@ +Bug239: distinguish call advice for operator ++ +=============================================== +before A A::operator ++(int) +inside A A::operator ++(int) +before A A::operator ++() +inside A A::operator ++() +=============================================== diff --git a/AspectC++/tests/Bug239/main.cc b/AspectC++/tests/Bug239/main.cc new file mode 100644 index 0000000..72a7fc3 --- /dev/null +++ b/AspectC++/tests/Bug239/main.cc @@ -0,0 +1,31 @@ +#include + +class A { +public: + A operator++ () { + printf("inside A A::operator ++()\n"); + return *this; + } + A operator++ (int) { + printf("inside A A::operator ++(int)\n"); + return *this; + } +}; + +aspect PlusPlus { + advice call ("% A::operator ++()") : before () { + printf ("before %s\n", JoinPoint::signature ()); + } + advice call ("% A::operator ++(int)") : before () { + printf ("before %s\n", JoinPoint::signature ()); + } +}; + +int main() { + printf ("Bug239: distinguish call advice for operator ++\n"); + printf ("===============================================\n"); + A a; + a++; + ++a; + printf ("===============================================\n"); +} diff --git a/AspectC++/tests/Bug242/Makefile b/AspectC++/tests/Bug242/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug242/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug242/OutputStream.h b/AspectC++/tests/Bug242/OutputStream.h new file mode 100644 index 0000000..26bbf5e --- /dev/null +++ b/AspectC++/tests/Bug242/OutputStream.h @@ -0,0 +1,12 @@ +#ifndef __OUTPUTSTREAM_H +#define __OUTPUTSTREAM_H + +#include + +class OutputStream { +public: + // uses the introduced attribute _fill + void print_fill () { printf ("%c", _fill); } +}; + +#endif diff --git a/AspectC++/tests/Bug242/Padding.ah b/AspectC++/tests/Bug242/Padding.ah new file mode 100644 index 0000000..cd2e578 --- /dev/null +++ b/AspectC++/tests/Bug242/Padding.ah @@ -0,0 +1,19 @@ +#ifndef __PADDING_AH__ +#define __PADDING_AH__ + +#include "OutputStream.h" + +aspect Padding { + + // this introduction leads to an 'include "Padding.ah"' in OutputStream.h in + // the first phase + advice "OutputStream" : char _fill; + + // here the type OutputStream is used + advice construction("OutputStream") && that(os) : + before(OutputStream& os) { + os._fill = '_'; + } +}; + +#endif // __PADDING_AH__ diff --git a/AspectC++/tests/Bug242/feature.ref b/AspectC++/tests/Bug242/feature.ref new file mode 100644 index 0000000..6fbcb93 --- /dev/null +++ b/AspectC++/tests/Bug242/feature.ref @@ -0,0 +1,4 @@ +Bug242: wrong include guard generation +====================================== +The introduced fill char is '_' +====================================== diff --git a/AspectC++/tests/Bug242/main.cc b/AspectC++/tests/Bug242/main.cc new file mode 100644 index 0000000..2ae0909 --- /dev/null +++ b/AspectC++/tests/Bug242/main.cc @@ -0,0 +1,12 @@ +#include "OutputStream.h" + +OutputStream out; + +int main () { + printf ("Bug242: wrong include guard generation\n"); + printf ("======================================\n"); + printf ("The introduced fill char is '"); + out.print_fill (); + printf ("'\n"); + printf ("======================================\n"); +} diff --git a/AspectC++/tests/Bug267/Makefile b/AspectC++/tests/Bug267/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug267/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug267/feature.ref b/AspectC++/tests/Bug267/feature.ref new file mode 100644 index 0000000..2b7c715 --- /dev/null +++ b/AspectC++/tests/Bug267/feature.ref @@ -0,0 +1,6 @@ +Bug267: around advice without proceed +===================================== +replaced void C::f() by advice! +replaced int C::g(int) by advice! +replaced void C::h() by advice! +===================================== diff --git a/AspectC++/tests/Bug267/main.cc b/AspectC++/tests/Bug267/main.cc new file mode 100644 index 0000000..861edfc --- /dev/null +++ b/AspectC++/tests/Bug267/main.cc @@ -0,0 +1,33 @@ +#include + +class C { +public: + void f () {} + int g (int) { return 0; } + void h () {} +}; + +aspect A { + advice execution ("void C::f()") : around () { + printf ("replaced %s by advice!\n", JoinPoint::signature ()); + } + advice execution ("% C::g(...)") && + cflow(execution("% main(...)")): around () { + printf ("replaced %s by advice!\n", JoinPoint::signature ()); + } + advice execution ("void C::h()") : around () { + printf ("replaced %s by advice!\n", JoinPoint::signature ()); + tjp->action ().trigger (); + } +}; + +int main () { + printf ("Bug267: around advice without proceed\n"); + printf ("=====================================\n"); + C c; + c.f (); + c.g (42); + c.h (); + printf ("=====================================\n"); + return 0; +} diff --git a/AspectC++/tests/Bug268/Makefile b/AspectC++/tests/Bug268/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug268/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug268/feature.ref b/AspectC++/tests/Bug268/feature.ref new file mode 100644 index 0000000..06d3725 --- /dev/null +++ b/AspectC++/tests/Bug268/feature.ref @@ -0,0 +1,24 @@ +Bug268: this pointer used in advice for static member functions +=============================================================== +called void C::f1(Vector &) + that: NULL + target: NULL +called void C::f2(Vector &) + that: NULL + target: not NULL +called void C::f3() + that: NULL + target: NULL +called void C::f1(Vector &) + that: NULL + target: NULL +called void C::f2(Vector &) + that: NULL + target: not NULL +called void C::f3() + that: NULL + target: NULL +called void C::f2(Vector &) + that: NULL + target: not NULL +=============================================================== diff --git a/AspectC++/tests/Bug268/main.cc b/AspectC++/tests/Bug268/main.cc new file mode 100644 index 0000000..6035060 --- /dev/null +++ b/AspectC++/tests/Bug268/main.cc @@ -0,0 +1,41 @@ +#include + +template class Vector { +}; + +class B { + void f1 () {} +}; + +class C : public B { +public: + void static f1 (Vector &); + + void f2 (Vector &) {} + static void f3 () {} +}; + +typedef C X; +void X::f1 (Vector &) { Vector v; C c; c.f2 (v); f3 (); } + +aspect A { + advice call ("void ...::f%(...)") : around () { + printf ("called %s\n", JoinPoint::signature ()); + printf (" that: %s\n", (tjp->that () ? "not NULL" : "NULL")); + printf (" target: %s\n", (tjp->target () ? "not NULL" : "NULL")); + tjp->proceed (); + } +}; + +int main () { + printf ("Bug268: this pointer used in advice for static member functions\n"); + printf ("===============================================================\n"); + C c; + Vector d; + C::f1 (d); + c.f1 (d); + Vector v; + c.f2 (v); + printf ("===============================================================\n"); + return 0; +} diff --git a/AspectC++/tests/Bug271/Makefile b/AspectC++/tests/Bug271/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug271/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug271/feature.ref b/AspectC++/tests/Bug271/feature.ref new file mode 100644 index 0000000..cf46985 --- /dev/null +++ b/AspectC++/tests/Bug271/feature.ref @@ -0,0 +1,7 @@ +Bug271: access control problem with privately inherited func +============================================================ +before void BAR::barMethod() +before void FOOBAR::fooBarMethod() +before int MyNS::FOO1::d() +before int MyNS::FOO2::d() +============================================================ diff --git a/AspectC++/tests/Bug271/main.cc b/AspectC++/tests/Bug271/main.cc new file mode 100644 index 0000000..31a0572 --- /dev/null +++ b/AspectC++/tests/Bug271/main.cc @@ -0,0 +1,65 @@ +#include + +class MyNS { +public: + class FOO1 { + public: + int d(); + }; + + class FOO2 { + public: + int d(); + }; +}; + +int MyNS::FOO1::d() { return 1; } +int MyNS::FOO2::d() { return 2; } + +class FOOBAR { +protected: + void fooBarMethod(); +}; + +class FOO : protected FOOBAR{ +private: + int disc; + MyNS::FOO1 *obj1; + MyNS::FOO2 *obj2; +public: + FOO () {} + FOO(MyNS::FOO1 *obj); + FOO(MyNS::FOO2 *obj); + int d(); +}; + +FOO::FOO(MyNS::FOO1* obj) : obj1(obj), obj2(0), disc(obj->d()) {} +FOO::FOO(MyNS::FOO2* obj) : obj1(0), obj2(obj), disc(obj->d()) {} + +class BAR : FOO { +public: + void barMethod(); +}; + +void FOOBAR::fooBarMethod() {} + +void BAR::barMethod() { fooBarMethod(); } + +aspect Trace { + advice target("%") : before () { + printf ("before %s\n", JoinPoint::signature ()); + } +}; + +int main () { + printf ("Bug271: access control problem with privately inherited func\n"); + printf ("============================================================\n"); + BAR bar; + bar.barMethod(); + MyNS::FOO1 foo1; + FOO foo_a (&foo1); + MyNS::FOO2 foo2; + FOO foo_b (&foo2); + printf ("============================================================\n"); + return 0; +} diff --git a/AspectC++/tests/Bug293/ArgumentSizeCalculator.h b/AspectC++/tests/Bug293/ArgumentSizeCalculator.h new file mode 100644 index 0000000..b0991da --- /dev/null +++ b/AspectC++/tests/Bug293/ArgumentSizeCalculator.h @@ -0,0 +1,41 @@ +#ifndef ARGUMENTSIZECALCULATOR_H +#define ARGUMENTSIZECALCULATOR_H + +/* + * Template Metaprogram to calculate the size of the arguments + * of a given JoinPoint on the stack + * + * uses the JoinPoint API + */ + +template +struct TypedSizeCalculator { + enum { RESULT = sizeof(T) }; +}; + +template +struct TypedSizeCalculator { + enum { RESULT = sizeof(T*) }; +}; + +template +class ArgumentSizeCalculator { + // Workaround for http://aspectc.org/bugzilla/show_bug.cgi?id=236 +#ifndef __puma + private: + template struct Sum_N { + enum { RESULT = TypedSizeCalculator::Type>::RESULT + Sum_N::RESULT }; + }; + + template struct Sum_N { + enum { RESULT = 0}; + }; + + public: + enum { RES = Sum_N::RESULT }; +#else + enum { RES = 42 }; +#endif +}; + +#endif diff --git a/AspectC++/tests/Bug293/Callee.h b/AspectC++/tests/Bug293/Callee.h new file mode 100644 index 0000000..0f043c8 --- /dev/null +++ b/AspectC++/tests/Bug293/Callee.h @@ -0,0 +1,12 @@ +#ifndef __callee_h__ +#define __callee_h__ + +class CalleeBase { +public: + virtual void callee() {} +}; + +class Callee : public CalleeBase { +}; + +#endif // __callee_h__ diff --git a/AspectC++/tests/Bug293/Derived.cc b/AspectC++/tests/Bug293/Derived.cc new file mode 100644 index 0000000..7be0a45 --- /dev/null +++ b/AspectC++/tests/Bug293/Derived.cc @@ -0,0 +1,8 @@ +#include "Derived.h" +#include "Callee.h" + +extern CalleeBase *callee_ptr; + +void Base::f () { + callee_ptr->callee(); +} diff --git a/AspectC++/tests/Bug293/Derived.h b/AspectC++/tests/Bug293/Derived.h new file mode 100644 index 0000000..1ac3323 --- /dev/null +++ b/AspectC++/tests/Bug293/Derived.h @@ -0,0 +1,12 @@ +#ifndef __derived_h__ +#define __derived_h__ + +class Base { +public: + void f (); +}; + +class Derived : public Base { +}; + +#endif // __derived_h__ diff --git a/AspectC++/tests/Bug293/Makefile b/AspectC++/tests/Bug293/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug293/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug293/SaveStack.h b/AspectC++/tests/Bug293/SaveStack.h new file mode 100644 index 0000000..dfcbee2 --- /dev/null +++ b/AspectC++/tests/Bug293/SaveStack.h @@ -0,0 +1,269 @@ +#ifndef SAVESTACK_H +#define SAVESTACK_H + +/* + * SaveStack.h + * + * Helper Templates to "simulate" call to function matched by pointcut + * saveStack template is overloaded with up to ten parameters. + * + * TODO: find a way to do this more generic. Perhaps with gcc macro functions? + * + */ + + +#define SAVESTACK(var) __asm__ volatile ( "mov %%esp, %0" : "=m" (var) : : "memory" ) +#define SAVEFRAME(var) var = __builtin_frame_address(0) +#define SAVESP SAVESTACK(frameAddress) + +// 64bit architectures use 128bit rdtsc register. +// we just take the lower ones from rax and forget about rdx, +// because we don't expect longer functions to measure ;) +#ifdef __x86_64__ +#define RDTSC(var) __asm__ volatile ("rdtsc" : "=a" (var) : : "memory" ) +#else +#define RDTSC(var) __asm__ volatile ("rdtsc" : "=A" (var) : : "memory" ) +#endif + + extern void *frameAddress; + + //void saveStack() { SAVESP; } + + template + void saveStack(P1 a1) { SAVESP; } + + template + void saveStack(P1 a1, P2 a2) { SAVESP; } + + template + void saveStack(P1 a1, P2 a2, P3 a3) { SAVESP; } + + template + void saveStack(P1 a1, P2 a2, P3 a3, P4 a4) { SAVESP; } + + template + void saveStack(P1 a1, P2 a2, P3 a3, P4 a4, P5 a5) { SAVESP; } + + template + void saveStack(P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6) { SAVESP; } + + template + void saveStack(P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6, P7 a7) { SAVESP; } + + template + void saveStack(P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6, P7 a7, P8 a8) { SAVESP; } + + template + void saveStack(P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6, P7 a7, P8 a8, P9 a9) { SAVESP; } + + template + void saveStack(P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6, P7 a7, P8 a8, P9 a9, P10 a10) { SAVESP; } + + + template + struct dispatch { + static void doit(AC::Action &action) { + UNSUPPORTED_NUMBER_OF_ARGUMENTS_EXPAND_MEASURE_ASPECT_AH; + } + }; + + template + struct dispatch { + static void doit(AC::Action &action) { + SAVESP; + } + }; + + template + struct dispatch { + static void doit(AC::Action &action) { + saveStack< + typename JoinPoint::template Arg<0>::Type + > ( + *(typename JoinPoint::template Arg<0>::ReferredType*)action._args[0] + ); + } + }; + + template + struct dispatch { + static void doit(AC::Action &action) { + saveStack< + typename JoinPoint::template Arg<0>::Type, + typename JoinPoint::template Arg<1>::Type + > ( + *(typename JoinPoint::template Arg<0>::ReferredType*)action._args[0], + *(typename JoinPoint::template Arg<1>::ReferredType*)action._args[1]); + } + }; + + template + struct dispatch { + static void doit(AC::Action &action) { + saveStack< + typename JoinPoint::template Arg<0>::Type, + typename JoinPoint::template Arg<1>::Type, + typename JoinPoint::template Arg<2>::Type + >( + *(typename JoinPoint::template Arg<0>::ReferredType*)action._args[0], + *(typename JoinPoint::template Arg<1>::ReferredType*)action._args[1], + *(typename JoinPoint::template Arg<2>::ReferredType*)action._args[2]); + } + }; + + template + struct dispatch { + static void doit(AC::Action &action) { + saveStack< + typename JoinPoint::template Arg<0>::Type, + typename JoinPoint::template Arg<1>::Type, + typename JoinPoint::template Arg<2>::Type, + typename JoinPoint::template Arg<3>::Type + >( + *(typename JoinPoint::template Arg<0>::ReferredType*)action._args[0], + *(typename JoinPoint::template Arg<1>::ReferredType*)action._args[1], + *(typename JoinPoint::template Arg<2>::ReferredType*)action._args[2], + *(typename JoinPoint::template Arg<3>::ReferredType*)action._args[3]); + } + }; + + template + struct dispatch { + static void doit(AC::Action &action) { + saveStack< + typename JoinPoint::template Arg<0>::Type, + typename JoinPoint::template Arg<1>::Type, + typename JoinPoint::template Arg<2>::Type, + typename JoinPoint::template Arg<3>::Type, + typename JoinPoint::template Arg<4>::Type + >( + *(typename JoinPoint::template Arg<0>::ReferredType*)action._args[0], + *(typename JoinPoint::template Arg<1>::ReferredType*)action._args[1], + *(typename JoinPoint::template Arg<2>::ReferredType*)action._args[2], + *(typename JoinPoint::template Arg<3>::ReferredType*)action._args[3], + *(typename JoinPoint::template Arg<4>::ReferredType*)action._args[4]); + } + }; + + template + struct dispatch { + static void doit(AC::Action &action) { + saveStack< + typename JoinPoint::template Arg<0>::Type, + typename JoinPoint::template Arg<1>::Type, + typename JoinPoint::template Arg<2>::Type, + typename JoinPoint::template Arg<3>::Type, + typename JoinPoint::template Arg<4>::Type, + typename JoinPoint::template Arg<5>::Type + >( + *(typename JoinPoint::template Arg<0>::ReferredType*)action._args[0], + *(typename JoinPoint::template Arg<1>::ReferredType*)action._args[1], + *(typename JoinPoint::template Arg<2>::ReferredType*)action._args[2], + *(typename JoinPoint::template Arg<3>::ReferredType*)action._args[3], + *(typename JoinPoint::template Arg<4>::ReferredType*)action._args[4], + *(typename JoinPoint::template Arg<5>::ReferredType*)action._args[5]); + } + }; + + template + struct dispatch { + static void doit(AC::Action &action) { + saveStack< + typename JoinPoint::template Arg<0>::Type, + typename JoinPoint::template Arg<1>::Type, + typename JoinPoint::template Arg<2>::Type, + typename JoinPoint::template Arg<3>::Type, + typename JoinPoint::template Arg<4>::Type, + typename JoinPoint::template Arg<5>::Type, + typename JoinPoint::template Arg<6>::Type + >( + *(typename JoinPoint::template Arg<0>::ReferredType*)action._args[0], + *(typename JoinPoint::template Arg<1>::ReferredType*)action._args[1], + *(typename JoinPoint::template Arg<2>::ReferredType*)action._args[2], + *(typename JoinPoint::template Arg<3>::ReferredType*)action._args[3], + *(typename JoinPoint::template Arg<4>::ReferredType*)action._args[4], + *(typename JoinPoint::template Arg<5>::ReferredType*)action._args[5], + *(typename JoinPoint::template Arg<6>::ReferredType*)action._args[6]); + } + }; + + template + struct dispatch { + static void doit(AC::Action &action) { + saveStack< + typename JoinPoint::template Arg<0>::Type, + typename JoinPoint::template Arg<1>::Type, + typename JoinPoint::template Arg<2>::Type, + typename JoinPoint::template Arg<3>::Type, + typename JoinPoint::template Arg<4>::Type, + typename JoinPoint::template Arg<5>::Type, + typename JoinPoint::template Arg<6>::Type, + typename JoinPoint::template Arg<7>::Type + >( + *(typename JoinPoint::template Arg<0>::ReferredType*)action._args[0], + *(typename JoinPoint::template Arg<1>::ReferredType*)action._args[1], + *(typename JoinPoint::template Arg<2>::ReferredType*)action._args[2], + *(typename JoinPoint::template Arg<3>::ReferredType*)action._args[3], + *(typename JoinPoint::template Arg<4>::ReferredType*)action._args[4], + *(typename JoinPoint::template Arg<5>::ReferredType*)action._args[5], + *(typename JoinPoint::template Arg<6>::ReferredType*)action._args[6], + *(typename JoinPoint::template Arg<7>::ReferredType*)action._args[7]); + } + }; + + template + struct dispatch { + static void doit(AC::Action &action) { + saveStack< + typename JoinPoint::template Arg<0>::Type, + typename JoinPoint::template Arg<1>::Type, + typename JoinPoint::template Arg<2>::Type, + typename JoinPoint::template Arg<3>::Type, + typename JoinPoint::template Arg<4>::Type, + typename JoinPoint::template Arg<5>::Type, + typename JoinPoint::template Arg<6>::Type, + typename JoinPoint::template Arg<7>::Type, + typename JoinPoint::template Arg<8>::Type + >( + *(typename JoinPoint::template Arg<0>::ReferredType*)action._args[0], + *(typename JoinPoint::template Arg<1>::ReferredType*)action._args[1], + *(typename JoinPoint::template Arg<2>::ReferredType*)action._args[2], + *(typename JoinPoint::template Arg<3>::ReferredType*)action._args[3], + *(typename JoinPoint::template Arg<4>::ReferredType*)action._args[4], + *(typename JoinPoint::template Arg<5>::ReferredType*)action._args[5], + *(typename JoinPoint::template Arg<6>::ReferredType*)action._args[6], + *(typename JoinPoint::template Arg<7>::ReferredType*)action._args[7], + *(typename JoinPoint::template Arg<8>::ReferredType*)action._args[8]); + } + }; + + template + struct dispatch { + static void doit(AC::Action &action) { + saveStack< + typename JoinPoint::template Arg<0>::Type, + typename JoinPoint::template Arg<1>::Type, + typename JoinPoint::template Arg<2>::Type, + typename JoinPoint::template Arg<3>::Type, + typename JoinPoint::template Arg<4>::Type, + typename JoinPoint::template Arg<5>::Type, + typename JoinPoint::template Arg<6>::Type, + typename JoinPoint::template Arg<7>::Type, + typename JoinPoint::template Arg<8>::Type, + typename JoinPoint::template Arg<9>::Type + >( + *(typename JoinPoint::template Arg<0>::ReferredType*)action._args[0], + *(typename JoinPoint::template Arg<1>::ReferredType*)action._args[1], + *(typename JoinPoint::template Arg<2>::ReferredType*)action._args[2], + *(typename JoinPoint::template Arg<3>::ReferredType*)action._args[3], + *(typename JoinPoint::template Arg<4>::ReferredType*)action._args[4], + *(typename JoinPoint::template Arg<5>::ReferredType*)action._args[5], + *(typename JoinPoint::template Arg<6>::ReferredType*)action._args[6], + *(typename JoinPoint::template Arg<7>::ReferredType*)action._args[7], + *(typename JoinPoint::template Arg<8>::ReferredType*)action._args[8], + *(typename JoinPoint::template Arg<9>::ReferredType*)action._args[9]); + } + }; + + +#endif diff --git a/AspectC++/tests/Bug293/doMeasurement.h b/AspectC++/tests/Bug293/doMeasurement.h new file mode 100644 index 0000000..d7a4e7c --- /dev/null +++ b/AspectC++/tests/Bug293/doMeasurement.h @@ -0,0 +1,44 @@ +#ifndef DOMEASUREMENT_H +#define DOMEASUREMENT_H + + + +typedef unsigned long long int cycle_t; +extern void *frameAddress; +extern void *stackBeforeAction; + + cycle_t doMeasurement(AC::Action &action) { + /* pseudocode: + cycle_t start, current; + RDTSC(start); + SAVESTACK(stackBeforeAction); + action.trigger(); + RDTSC(current); + return current - start; + */ + + cycle_t result; + AC::Action *a = &action; + + __asm__ volatile ( + "mov %2, %%ecx\n" // push argument (action == this) on the stack + "push %%ecx\n" + "movl %%esp, %0 \n" + "cpuid \n" + "rdtsc \n" + "mov %%eax, %%esi\n" + "cpuid \n" + "call *%%edi \n" + "cpuid \n" + "rdtsc \n" + "sub %%esi,%%eax\n" // current - start + "xorl %%edx, %%edx\n" + "pop %%ecx\n" + + : "=m" (stackBeforeAction), "=A"(result) + : "m" ( a ), "D" (a->_wrapper) + : "%ebx", "%ecx", "%esi" // add "%ecx" in case of problems + ); + return result; + } +#endif diff --git a/AspectC++/tests/Bug293/dynamic.cc b/AspectC++/tests/Bug293/dynamic.cc new file mode 100644 index 0000000..ed062a2 --- /dev/null +++ b/AspectC++/tests/Bug293/dynamic.cc @@ -0,0 +1,17 @@ +#include "Derived.h" +#include "Callee.h" + +Base *base_ptr; +CalleeBase *callee_ptr; + +void measurePoint() { + base_ptr->f (); +} + +int main () { + Derived d; + base_ptr = &d; + Callee c; + callee_ptr = &c; + measurePoint (); +} diff --git a/AspectC++/tests/Bug293/measure.ah b/AspectC++/tests/Bug293/measure.ah new file mode 100644 index 0000000..3cdccd1 --- /dev/null +++ b/AspectC++/tests/Bug293/measure.ah @@ -0,0 +1,12 @@ +#ifndef MEASURE_AH +#define MEASURE_AH + +#include "measureAspect.ah" + +aspect measureThat : public measure { + pointcut measureTarget() = "void ...::measurePoint()"; +}; + + +#endif + diff --git a/AspectC++/tests/Bug293/measureAspect.ah b/AspectC++/tests/Bug293/measureAspect.ah new file mode 100644 index 0000000..912c2ad --- /dev/null +++ b/AspectC++/tests/Bug293/measureAspect.ah @@ -0,0 +1,127 @@ +/* + * measureAspect.ah + * + * measure the runtime of target + */ +#ifndef __MEASURE_ASPECT +#define __MEASURE_ASPECT + +#include // for std::sort +#include +#include +#include + +#include "doMeasurement.h" +#include "ArgumentSizeCalculator.h" +#include "SaveStack.h" + +#define RUNS 20 +#define SUMS 500 +#define COUNTSKIP 5 + +void *frameAddress; +void *stackBeforeAction; + +static int weirdCount; +static double average; +static cycle_t calibration; +static AC::Action nullAction; + +aspect measure { + // returns average, stores summed up results to buf of length len + void __attribute__ ((noinline)) runTests(AC::Action &action, cycle_t *buf, unsigned len, cycle_t calibration = 0) { + register unsigned i,j; + double avg = 0; + weirdCount = 0; + average = 0; + for(i = 0; i < len; i++) { + buf[i] = 0; + + // Accumulate RUNS runs, and calcualate mean + j = RUNS; + while(j--) { + cycle_t result = doMeasurement(action); + buf[i] += result; + } + buf[i] /= RUNS; + + if (calibration > buf[i]) { // something weird happened + buf[i] = 0; + weirdCount++; + } else { + buf[i] -= calibration; + } + + avg += buf[i]; + } + + average = avg / (double)len; + } + + pointcut virtual measureTarget () = 0; + advice call(measureTarget()) : order("measure", !"measure"); + advice call(measureTarget()) : around() { + cycle_t runtimes[SUMS]; + register unsigned i = COUNTSKIP; + ptrdiff_t overhead; + std::ofstream out("out.txt", std::ios_base::app); + + if(sched_yield()) + perror("doMeasurement"); + + while(i--) + doMeasurement(tjp->action()); // warm up caches + + size_t param_size = ArgumentSizeCalculator::RES; + nullAction._wrapper = dispatch::doit; + + // do calibration + runTests(nullAction, runtimes, SUMS); + std::sort(runtimes, runtimes + SUMS); + calibration = runtimes[SUMS/2]; + +#ifdef DEBUG + out << "\n results of calibration runs:\n"; + for (i = 0; i < SUMS; i++) + out << runtimes[i] << ", "; +#endif + + // Expected overhead of measureAspect: + // Action Object, Arguments, Stackalignment + overhead = (ptrdiff_t)stackBeforeAction - (ptrdiff_t)frameAddress; + +// calibration = 0; // disable calibration + frameAddress = 0; // reset frameAddress + runTests(tjp->action(), runtimes, SUMS, calibration); + + + // sort the array for median processing + std::sort(runtimes, runtimes + SUMS); + + out << "\nMeasure times of target: " << tjp->signature() << "\n"; + out << "\n Calibration took (in cycles): " << calibration; + out << "\n Average runtime: " << average; + out << "\n Median is " << runtimes[SUMS/2]; + out << "\n esp overhead is " << overhead; + out << "\n Number of arguments is: " << JoinPoint::ARGS; + out << "\n Total Size of arguments: " << param_size; + out << "\n Number of runs with calibration bigger than run: " << weirdCount; + out << "\n Total runs of target: " << SUMS; + + if (frameAddress) { + ptrdiff_t stackUsed = + (ptrdiff_t)stackBeforeAction - (ptrdiff_t)frameAddress - overhead; + out << "\n Stack used: " << stackUsed << std::endl; + } else { + out << "\n Callee did not set used stack" << std::endl; + } +#ifdef DEBUG + out << "\n runtimes are: "; + for (i = 0; i < SUMS; i++) + out << runtimes[i] << ", "; +#endif + out.close(); + } +}; + +#endif diff --git a/AspectC++/tests/Bug293/target.ah b/AspectC++/tests/Bug293/target.ah new file mode 100644 index 0000000..5bc2d13 --- /dev/null +++ b/AspectC++/tests/Bug293/target.ah @@ -0,0 +1,14 @@ +#ifndef __target_ah__ +#define __target_ah__ + +#include +#include "SaveStack.h" + +aspect _Target { + advice that("Callee") && call("void CalleeBase::callee()") : around () { + SAVESP; + tjp->proceed (); + } +}; + +#endif // __target_ah__ diff --git a/AspectC++/tests/Bug316/Makefile b/AspectC++/tests/Bug316/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug316/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug316/feature.ref b/AspectC++/tests/Bug316/feature.ref new file mode 100644 index 0000000..9e09f5d --- /dev/null +++ b/AspectC++/tests/Bug316/feature.ref @@ -0,0 +1,8 @@ +e1: before void X::fx() +e2: before void X::fx() +e1: before void X::Y::fy(X::Y *) +e2: before void X::Y::fy(X::Y *) +e2: after void X::Y::fy(X::Y *) +e1: after void X::Y::fy(X::Y *) +e2: after void X::fx() +e1: after void X::fx() diff --git a/AspectC++/tests/Bug316/main.cc b/AspectC++/tests/Bug316/main.cc new file mode 100644 index 0000000..41ed7d5 --- /dev/null +++ b/AspectC++/tests/Bug316/main.cc @@ -0,0 +1,106 @@ +#include + +class X { + struct Y; // this one is private! +public: + static void fx(); +}; + +struct X::Y { + void fy(Y *arg); +}; + +// this is a member of a private class, thus Y cannot be used in TJP so far +void X::Y::fy(Y *arg) { +} + +// this function may call fy +void X::fx () { + Y y; + y.fy (&y); +} + +aspect Bug316 { + advice execution ("% ...::f%(...)") : around () { + printf ("e1: before %s\n",JoinPoint::signature ()); + tjp->proceed (); + printf ("e1: after %s\n",JoinPoint::signature ()); + } + advice execution ("% ...::f%(...)") : around () { + printf ("e2: before %s\n",JoinPoint::signature ()); + tjp->proceed (); + printf ("e2: after %s\n",JoinPoint::signature ()); + } + // this call advice still does not work! +// advice call ("% ...::f%(...)") : around () { +// printf ("c1: before %s\n",JoinPoint::signature ()); +// tjp->proceed (); +// printf ("c1: after %s\n",JoinPoint::signature ()); +// } +// advice call ("% ...::f%(...)") : around () { +// printf ("c2: before %s\n",JoinPoint::signature ()); +// tjp->action ().trigger (); +// printf ("c2: after %s\n",JoinPoint::signature ()); +// } +}; + +int main () { + X::fx (); + return 0; +} + +// moegliche Loesung ... + +// #include + +// template +// struct TJP {}; + + +// class X { +// template friend struct TJP; +// struct Y; // this one is private! +// public: +// static void fx(); +// }; + +// struct X::Y { +// void old_fy(); +// void fy(); +// }; + +// template <> struct TJP<1> { +// typedef X::Y That; +// typedef X::Y Target; +// X::Y *_that; +// X::Y *that () { return _that; } +// X::Y *target () { return 0; } +// static const char *signature () { return "X::Y::fy"; } +// void proceed () { _that->old_fy (); } +// }; + +// template void adv (JP *tjp) { +// printf ("before %s\n", JP::signature ()); +// tjp->proceed (); +// } + +// // this is a member of a private class, thus Y cannot be used in TJP so far +// void X::Y::fy() { +// TJP<1> tjp = { this }; +// adv< TJP<1> >(&tjp); +// } +// // this is a member of a private class, thus Y cannot be used in TJP so far +// void X::Y::old_fy() { +// printf ("X::Y::old_fy\n"); +// } + +// // this function may call fy +// void X::fx () { +// Y y; +// y.fy (); +// } + +// int main () { +// X::fx (); +// return 0; +// } diff --git a/AspectC++/tests/Bug321/Makefile b/AspectC++/tests/Bug321/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug321/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug321/feature.ref b/AspectC++/tests/Bug321/feature.ref new file mode 100644 index 0000000..fd961a5 --- /dev/null +++ b/AspectC++/tests/Bug321/feature.ref @@ -0,0 +1,11 @@ +execution: int main() +Bug484: va_list improperly weaved +================================= +call: int add(int,...) +36 +call: int add(int,...) +231 +call: int add(int,...) +call: int add(int,...) +62 +================================= diff --git a/AspectC++/tests/Bug321/main.cc b/AspectC++/tests/Bug321/main.cc new file mode 100644 index 0000000..597d1be --- /dev/null +++ b/AspectC++/tests/Bug321/main.cc @@ -0,0 +1,49 @@ +#include +using namespace std; + +#include +#include + + +int add(int zahlen, ...); + +int add(int zahlen, ...) +{ + va_list zeiger; + int zahl; + + va_start(zeiger,zahlen); + + do{ + zahl = va_arg(zeiger,int); + zahlen += zahl; + }while(zahl != 0); + + va_end(zeiger); + return zahlen; +} + +int main(){ + cout << "Bug484: va_list improperly weaved\n"; + cout << "=================================\n"; + int erg; + printf("%d\n",add(11,12,13,0)); + printf("%d\n",add(99,66,33,22,11,0)); + erg = add(10, 13, 11, 0) + add(9, 8, 11, 0); + printf("%d\n",erg); + cout << "=================================\n"; + return 0; +} + +aspect Logger { + advice execution("% ...::%(...)" && !"% Logger::%(...)") : around() { + cout << "execution: " << tjp->signature() << endl; + tjp->proceed(); + } + + advice call("% add(...)" && !"% Logger::%(...)") : around() { + cout << "call: " << tjp->signature() << endl; + tjp->proceed(); + } +}; + diff --git a/AspectC++/tests/Bug323/A0.ah b/AspectC++/tests/Bug323/A0.ah new file mode 100644 index 0000000..917c81a --- /dev/null +++ b/AspectC++/tests/Bug323/A0.ah @@ -0,0 +1,12 @@ +#ifndef __A0_ah__ +#define __A0_ah__ + +#include + +aspect A0 { + advice execution ("% in_header(...)") : before () { + printf ("A0\n"); + } +}; + +#endif diff --git a/AspectC++/tests/Bug323/A1.ah b/AspectC++/tests/Bug323/A1.ah new file mode 100644 index 0000000..bfddb5d --- /dev/null +++ b/AspectC++/tests/Bug323/A1.ah @@ -0,0 +1,15 @@ +#ifndef __A1_ah__ +#define __A1_ah__ + +#include + +#include "header.h" + +aspect A1 { + advice execution ("% main(...)") : before () { + printf ("A1\n"); + in_header (); + } +}; + +#endif diff --git a/AspectC++/tests/Bug323/A2.ah b/AspectC++/tests/Bug323/A2.ah new file mode 100644 index 0000000..fb7a5e2 --- /dev/null +++ b/AspectC++/tests/Bug323/A2.ah @@ -0,0 +1,12 @@ +#ifndef __A2_ah__ +#define __A2_ah__ + +#include + +aspect A2 { + advice execution ("% in_header(...)") : before () { + printf ("A2\n"); + } +}; + +#endif diff --git a/AspectC++/tests/Bug323/Makefile b/AspectC++/tests/Bug323/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug323/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug323/feature.ref b/AspectC++/tests/Bug323/feature.ref new file mode 100644 index 0000000..6139751 --- /dev/null +++ b/AspectC++/tests/Bug323/feature.ref @@ -0,0 +1,6 @@ +Bug323: undefined advice definitions +==================================== +A1 +A0 +A2 +==================================== diff --git a/AspectC++/tests/Bug323/header.h b/AspectC++/tests/Bug323/header.h new file mode 100644 index 0000000..c047007 --- /dev/null +++ b/AspectC++/tests/Bug323/header.h @@ -0,0 +1,6 @@ +#ifndef __header_h__ +#define __header_h__ + +inline void in_header () {} + +#endif // __header_h__ diff --git a/AspectC++/tests/Bug323/main.cc b/AspectC++/tests/Bug323/main.cc new file mode 100644 index 0000000..0f46478 --- /dev/null +++ b/AspectC++/tests/Bug323/main.cc @@ -0,0 +1,15 @@ +#include + +struct Global { + Global () { + printf ("Bug323: undefined advice definitions\n"); + printf ("====================================\n"); + } + ~Global () { + printf ("====================================\n"); + } +} global; + +int main () { + return 0; +} diff --git a/AspectC++/tests/Bug336/Makefile b/AspectC++/tests/Bug336/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug336/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug336/feature.ref b/AspectC++/tests/Bug336/feature.ref new file mode 100644 index 0000000..977a1a6 --- /dev/null +++ b/AspectC++/tests/Bug336/feature.ref @@ -0,0 +1,5 @@ +Bug 336: wrong ordering if order advice has no match: +===================================================== +the result should be 031 ... +031 +===================================================== diff --git a/AspectC++/tests/Bug336/main.cc b/AspectC++/tests/Bug336/main.cc new file mode 100644 index 0000000..b3ea252 --- /dev/null +++ b/AspectC++/tests/Bug336/main.cc @@ -0,0 +1,57 @@ +#include + +#define FAILING + +struct test { + int field0; +}; + +#ifndef FAILING + test teststruct = {0, 1, 2, 3}; +#else + test teststruct = {0, 1, 3}; +#endif + +int main () { + + std::cout << "Bug 336: wrong ordering if order advice has no match:" << std::endl; + std::cout << "=====================================================" << std::endl; + std::cout << "the result should be 031 ..." << std::endl; +#ifndef FAILING + std::cout << teststruct.field0 << teststruct.field1 << teststruct.field2 << +teststruct.field3 << std::endl; + // returns 0321 +#else + std::cout << teststruct.field0 << teststruct.field1 << teststruct.field3 << +std::endl; + // should return 031, + // but returns 013 (as if order advice was not given) +#endif + std::cout << "=====================================================" << std::endl; + + return 0; +} + +aspect orderaspect { + advice "test" : order ("slice3", "slice2", "slice1"); +}; + +aspect slice1 { + advice "test" : slice struct { + int field1; + }; +}; + +#ifndef FAILING +aspect slice2 { + advice "test" : slice struct { + int field2; + }; +}; +#endif + +aspect slice3 { + advice "test" : slice struct { + int field3; + }; +}; diff --git a/AspectC++/tests/Bug353/Makefile b/AspectC++/tests/Bug353/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug353/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug353/feature.ref b/AspectC++/tests/Bug353/feature.ref new file mode 100644 index 0000000..71de053 --- /dev/null +++ b/AspectC++/tests/Bug353/feature.ref @@ -0,0 +1,4 @@ +Bug 353: first token shouldn't be join-point +===================================================== +should compile without error ... +===================================================== diff --git a/AspectC++/tests/Bug353/main.cc b/AspectC++/tests/Bug353/main.cc new file mode 100644 index 0000000..358b394 --- /dev/null +++ b/AspectC++/tests/Bug353/main.cc @@ -0,0 +1,15 @@ +void t(){} + +#include + +int main () { + std::cout << "Bug 353: first token shouldn't be join-point" << std::endl; + std::cout << "=====================================================" << std::endl; + std::cout << "should compile without error ..." << std::endl; + std::cout << "=====================================================" << std::endl; + return 0; +} +aspect Oops { + advice execution("void t()") : around() { tjp->proceed(); } + advice execution("void t()") : around() { tjp->proceed(); } +}; diff --git a/AspectC++/tests/Bug368/Makefile b/AspectC++/tests/Bug368/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug368/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug368/feature.ref b/AspectC++/tests/Bug368/feature.ref new file mode 100644 index 0000000..bbb88b8 --- /dev/null +++ b/AspectC++/tests/Bug368/feature.ref @@ -0,0 +1,9 @@ +Bug368: access control problem with private class +================================================= +before call to void C::foo() +before call to void C::foo() +before call to void C::foo(C::D *) +before call to void C::foo(C::D *) +before call to C::E C::returner() +before call to C::E C::returner() +================================================= diff --git a/AspectC++/tests/Bug368/main.cc b/AspectC++/tests/Bug368/main.cc new file mode 100644 index 0000000..7b0680b --- /dev/null +++ b/AspectC++/tests/Bug368/main.cc @@ -0,0 +1,40 @@ +#include +using std::printf; + +class C { +public: + C() { foo(); } +private: + class D { }; + enum E { E1 }; + + E returner () { return E1; } + void foo (); + void foo (D *pD); +}; + +void C::foo () { + D d; + foo (&d); + returner (); +} + +void C::foo (D *pD) { } + +aspect AspC { + public: + pointcut methods () = call ("% C::%(...)") || execution ("% C::%(...)"); + + advice methods () : before () { + printf ("before call to %s\n", JoinPoint::signature()); + } +}; + + +int main () { + printf ("Bug368: access control problem with private class\n"); + printf ("=================================================\n"); + C c; + printf ("=================================================\n"); + return 0; +} diff --git a/AspectC++/tests/Bug418/Makefile b/AspectC++/tests/Bug418/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug418/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug418/falsefriend.h b/AspectC++/tests/Bug418/falsefriend.h new file mode 100644 index 0000000..5968638 --- /dev/null +++ b/AspectC++/tests/Bug418/falsefriend.h @@ -0,0 +1,19 @@ +#ifndef __falsefriend_h__ +#define __falsefriend_h__ + +#include "singleton.h" + +// Example implementation of a "false friend". +// Being a friend of Singleton, FalseFriend has got access to the +// private methods of that class. +// Although objects of class Singleton should only be created +// by calling Singleton::getInstance(), FalseFriend misuses its +// privileges and directly calls the constructor, thus creating +// additional Singleton objects. + +class FalseFriend { + public: + FalseFriend() { Singleton s1; Singleton s2(s1); } +}; + +#endif diff --git a/AspectC++/tests/Bug418/feature.ref b/AspectC++/tests/Bug418/feature.ref new file mode 100644 index 0000000..e69de29 diff --git a/AspectC++/tests/Bug418/main.cc b/AspectC++/tests/Bug418/main.cc new file mode 100644 index 0000000..b8e0a6d --- /dev/null +++ b/AspectC++/tests/Bug418/main.cc @@ -0,0 +1,11 @@ +#include "singleton.h" +#include "falsefriend.h" + +int main () { + + Singleton& s1 = Singleton::getInstance(); + + FalseFriend f; + + return 0; +} diff --git a/AspectC++/tests/Bug418/mysingletonmonitor.ah b/AspectC++/tests/Bug418/mysingletonmonitor.ah new file mode 100644 index 0000000..1c39ce3 --- /dev/null +++ b/AspectC++/tests/Bug418/mysingletonmonitor.ah @@ -0,0 +1,14 @@ +#ifndef __mysingletonmonitor_ah__ +#define __mysingletonmonitor_ah__ + +#include "singletonmonitor.ah" + +// Example for a specialization of the GenericSingletonMonitor +// Use the pointcut singleton() to specify which classes should +// obey the singleton pattern. + +aspect MySingletonMonitor : public GenericSingletonMonitor { + pointcut virtual singleton() = "Singleton"; +}; + +#endif diff --git a/AspectC++/tests/Bug418/singleton.h b/AspectC++/tests/Bug418/singleton.h new file mode 100644 index 0000000..71daa8e --- /dev/null +++ b/AspectC++/tests/Bug418/singleton.h @@ -0,0 +1,34 @@ +#ifndef __singleton_h__ +#define __singleton_h__ + +// Example implementation of the singleton pattern: +// Constructor and copy constructor are private to prevent +// the uncontrolled creation of Singleton instances. +// The creation of the only allowed instance is accomplished +// using the public getInstance() method, which always returns +// the same object. + +// While the implementation looks straightforward, the +// declaration of a friend class is a security hole. +// Thus the SingletonMonitor aspect can be used to look +// for violations of the singleton pattern. + +class FalseFriend; + +class Singleton +{ + private: + Singleton() {} + Singleton(const Singleton&) {} + ~Singleton() {} + public: + static Singleton& getInstance() { + static Singleton instance; + return instance; + } + + friend class FalseFriend; +}; + + +#endif diff --git a/AspectC++/tests/Bug418/singletonmonitor.ah b/AspectC++/tests/Bug418/singletonmonitor.ah new file mode 100644 index 0000000..d056715 --- /dev/null +++ b/AspectC++/tests/Bug418/singletonmonitor.ah @@ -0,0 +1,46 @@ +#ifndef __singletonmonitor_ah__ +#define __singletonmonitor_ah__ + +#include + +// Generic singleton monitor aspect +// +// A class obeying the singleton pattern should guarantee that +// no more than a single object of this class will be ever created. +// This generic aspect checks the behavior: it counts the instances +// and emits an error message if more than one instance is created. + +// singletonmonitor::Counter is a helper class used to count the number +// of objects created. +// The usage of a template class and its intantiation with JoinPoint::That +// ensures, that a new counter will be used for each singleton class, +// while constructor and copy-constructor of the same class will use +// the same counter. + + +namespace singletonmonitor { + template struct Counter { + static int _val; + }; + template int Counter::_val = 0; +} + + +aspect GenericSingletonMonitor { + pointcut virtual singleton() = 0; + + advice construction (singleton()) : before() { + typedef singletonmonitor::Counter InstanceCounter; + + InstanceCounter::_val++; + if (InstanceCounter::_val > 1) { + std::cerr << "Error: " + << "created "<< InstanceCounter::_val << " instances of " + << "singleton class by calling the constructor " + << JoinPoint::signature() + << std::endl; + } + }; +}; + +#endif diff --git a/AspectC++/tests/Bug427/Makefile b/AspectC++/tests/Bug427/Makefile new file mode 100644 index 0000000..f485359 --- /dev/null +++ b/AspectC++/tests/Bug427/Makefile @@ -0,0 +1,2 @@ +ACFLAGS ?= --introspection +include ../Makefile.generic diff --git a/AspectC++/tests/Bug427/feature.ref b/AspectC++/tests/Bug427/feature.ref new file mode 100644 index 0000000..1c3ef69 --- /dev/null +++ b/AspectC++/tests/Bug427/feature.ref @@ -0,0 +1,9 @@ +Bug427: args() keyword ignores __attribute__ on types +==================================================================== +sizeof arg<0>: 1 +sizeof ARG<0>: 1 +sizeof a: 1 +sizeof b: 2 +sizeof c: 4 +sizeof d: 8 +==================================================================== diff --git a/AspectC++/tests/Bug427/main.cc b/AspectC++/tests/Bug427/main.cc new file mode 100644 index 0000000..78c9fd1 --- /dev/null +++ b/AspectC++/tests/Bug427/main.cc @@ -0,0 +1,59 @@ +#include + +#ifndef __GNUC__ +#include +#endif + +namespace Bug427 { + +#ifdef __GNUC__ +// typedefs from avr's +typedef unsigned int uint8_t __attribute__((__mode__(__QI__))); +typedef unsigned int uint16_t __attribute__ ((__mode__ (__HI__))); +typedef unsigned int uint32_t __attribute__ ((__mode__ (__SI__))); +typedef unsigned int uint64_t __attribute__((__mode__(__DI__))); +#endif + +typedef uint64_t UInt64; + +// one argument with 8 bits +void foo(uint8_t x) { /* do something */ } + +class A { + uint8_t a; + uint16_t b; + uint32_t c; + uint64_t d; +}; + +} // namespace Bug427 + +int main(){ + printf("Bug427: args() keyword ignores __attribute__ on types\n"); + printf("====================================================================\n"); + Bug427::foo(42); + printf("sizeof a: %u\n", sizeof(AC::TypeInfo::Member<0>::Type)); + printf("sizeof b: %u\n", sizeof(AC::TypeInfo::Member<1>::Type)); + printf("sizeof c: %u\n", sizeof(AC::TypeInfo::Member<2>::Type)); + printf("sizeof d: %u\n", sizeof(AC::TypeInfo::Member<3>::Type)); + printf("====================================================================\n"); + + return 0; +} + +aspect ShadowAspect { + advice execution("% ...::%(...)" && !"% main(...)") : around() { + tjp->proceed(); + //printf("%s\n", tjp->signature()); // may be not portable + printf("sizeof arg<0>: %u\n", sizeof(*tjp->arg<0>()) ); + typedef JoinPoint::template Arg<0>::Type ARG0; + printf("sizeof ARG<0>: %u\n", sizeof( ARG0 )); + } +}; + +// aspect that must not match +aspect BuggyAspect { + advice execution("void Bug427::foo(%)") && args(x) : before(Bug427::UInt64 x) { + printf("must not match: %s\n", tjp->signature()); + } +}; diff --git a/AspectC++/tests/Bug477/Makefile b/AspectC++/tests/Bug477/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug477/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug477/feature.ref b/AspectC++/tests/Bug477/feature.ref new file mode 100644 index 0000000..9a8919a --- /dev/null +++ b/AspectC++/tests/Bug477/feature.ref @@ -0,0 +1,12 @@ +Bug477: Templates muddle base() and derived() pointcut functions +================================================================ +derived("A"): void C::foo() +base("E"): void C::foo() +derived("A"): void C::bar() +base("E"): void C::bar() +derived("A"): void A::foo() +base("E"): void A::foo() +derived("A"): void D::moo() +base("E"): void D::moo() +derived("A"): void E::bla() +================================================================ diff --git a/AspectC++/tests/Bug477/main.cc b/AspectC++/tests/Bug477/main.cc new file mode 100644 index 0000000..c652ea5 --- /dev/null +++ b/AspectC++/tests/Bug477/main.cc @@ -0,0 +1,61 @@ +#include + +class A { + int a; +public: + virtual void foo() {}; +}; + +class A0 : public A {}; + +template +class B : private A { + struct Inner {}; +}; + +B bbb; // create two instances of B! + +template +class C : private B { +public: + void foo() {} + void bar() {} +}; + +class D : public C { +public: + void moo() {} +}; + +class E : public D { +public: + void bla() {} +}; + + +int main(){ + E e; + printf ("Bug477: Templates muddle base() and derived() pointcut functions\n"); + printf ("================================================================\n"); + e.foo(); // not matched by derived(A) + e.bar(); // not matched by derived(A) + + ((A*)&e)->foo(); // not matched by base(E) + + e.moo(); // not matched by derived(A) + e.bla(); // not matched by derived(A) + printf ("================================================================\n"); + + return 0; +} + +aspect DerivedTest { + + advice call(derived("A")) : before() { + printf ("derived(\"A\"): %s\n", JoinPoint::signature()); + } + + advice call(base("E")) : before() { + printf ("base(\"E\"): %s\n", JoinPoint::signature()); + } +}; diff --git a/AspectC++/tests/Bug484/Makefile b/AspectC++/tests/Bug484/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug484/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug484/feature.ref b/AspectC++/tests/Bug484/feature.ref new file mode 100644 index 0000000..16c0ddf --- /dev/null +++ b/AspectC++/tests/Bug484/feature.ref @@ -0,0 +1,5 @@ +Bug484: Execution advice for function with parameter 'result' broken +==================================================================== +int func(int) -> 42 +int func2(int) -> 4711 +==================================================================== diff --git a/AspectC++/tests/Bug484/main.cc b/AspectC++/tests/Bug484/main.cc new file mode 100644 index 0000000..4bfbe9a --- /dev/null +++ b/AspectC++/tests/Bug484/main.cc @@ -0,0 +1,23 @@ +#include +using namespace std; + +int func(int result) { return result; } +int func2(int __result) { return __result; } + + +int main(){ + cout << "Bug484: Execution advice for function with parameter 'result' broken\n"; + cout << "====================================================================\n"; + func(42); + func2(4711); + cout << "====================================================================\n"; + + return 0; +} + +aspect ShadowAspect { + advice execution("% ...::%(...)" && !"% main(...)") : around() { + tjp->proceed(); + cout << tjp->signature() << " -> " << *tjp->result() << endl; + } +}; diff --git a/AspectC++/tests/Bug512/Makefile b/AspectC++/tests/Bug512/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug512/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug512/feature.ref b/AspectC++/tests/Bug512/feature.ref new file mode 100644 index 0000000..cc85f32 --- /dev/null +++ b/AspectC++/tests/Bug512/feature.ref @@ -0,0 +1,7 @@ +Bug512: advice for macro-generated call not woven +================================================= +BEFORE: void hal_thread_switch_context() +BEFORE: void hal_thread_switch_context() +BEFORE: C a() +BEFORE: void C::b() +================================================= diff --git a/AspectC++/tests/Bug512/main.cc b/AspectC++/tests/Bug512/main.cc new file mode 100644 index 0000000..d710b68 --- /dev/null +++ b/AspectC++/tests/Bug512/main.cc @@ -0,0 +1,26 @@ +#include + +#define __B__ b +struct C { void b() {} }; +C a() { return C (); } +#define CALL a().__B__() + +void hal_thread_switch_context() {} + +#define HAL_THREAD_SWITCH_CONTEXT() \ + hal_thread_switch_context(); + +int main() { + printf ("Bug512: advice for macro-generated call not woven\n"); + printf ("=================================================\n"); + HAL_THREAD_SWITCH_CONTEXT(); // no call advice with Bug 512 :( + hal_thread_switch_context(); // call advice is ordinarily woven + CALL; + printf ("=================================================\n"); +} + +aspect CallAdvisor { + advice call("% ...::%(...)" && !"% printf(...)") : before() { + printf ("BEFORE: %s\n", JoinPoint::signature()); + } +}; diff --git a/AspectC++/tests/Bug524/Makefile b/AspectC++/tests/Bug524/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug524/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug524/feature.ref b/AspectC++/tests/Bug524/feature.ref new file mode 100644 index 0000000..e69de29 diff --git a/AspectC++/tests/Bug524/main.cc b/AspectC++/tests/Bug524/main.cc new file mode 100644 index 0000000..f41da1f --- /dev/null +++ b/AspectC++/tests/Bug524/main.cc @@ -0,0 +1,13 @@ +pointcut asEnableAllInterrupts () = "% AS::EnableAllInterrupts (...)"; +pointcut asInterruptServices () = asEnableAllInterrupts (); + +aspect os_dep_KernelStructsSupport { + advice call (asInterruptServices ()) : order ( + "os_krn_EnterLeave_Weaving_Static", + "os_dep_KernelStructsSupport", + ! "os_dep_KernelStructsSupport"&& +!"os_krn_EnterLeave_Weaving_Static" + ); +}; + +int main() {} diff --git a/AspectC++/tests/Bug548/Makefile b/AspectC++/tests/Bug548/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug548/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug548/feature.ref b/AspectC++/tests/Bug548/feature.ref new file mode 100644 index 0000000..0e71639 --- /dev/null +++ b/AspectC++/tests/Bug548/feature.ref @@ -0,0 +1,5 @@ +Bug548: operator->() chains not resolved properly +================================================= +In Foo's bar. +That's it! +================================================= diff --git a/AspectC++/tests/Bug548/main.cc b/AspectC++/tests/Bug548/main.cc new file mode 100644 index 0000000..7edcddb --- /dev/null +++ b/AspectC++/tests/Bug548/main.cc @@ -0,0 +1,64 @@ +#include + +// This code is from bug report 548 -- it showed up in Fiaco + +class Foo { +public: + int bar() { printf ("In Foo's bar.\n"); return 42; } +}; + +template +class Iterator { + typedef T *Value_type; + Value_type _c; + +public: + Iterator() { _c = new Foo(); } + + Value_type operator * () { return static_cast(_c); } + Value_type operator -> () { return static_cast(_c); } + + void bar() {}; +}; + +// These classes are needed to create an even longer operator-> chain + +struct C4 { + int thats_it() const { printf("That's it!\n"); return 42; } +} c4; + +struct C3 { + C4 *operator -> () const { return &c4; } +} c3; + +struct C2 { + C3 operator -> () const { return c3; } +} c2; + +struct C1 { + C2 operator -> () const { return c2; } +} c1; + +// Call both chains +int main() { + printf ("Bug548: operator->() chains not resolved properly\n"); + printf ("=================================================\n"); + + Iterator i; + int x = i->bar(); + + c1->thats_it(); + + printf ("=================================================\n"); +} + +// Weave call advice for it +aspect MyAspect { + //advice call("% ...::%(...)") : around() { // works, though + advice call("% Foo::%(...)") : around() { + tjp->target()->bar(); + } + advice call("% C2::%(...)"||"% C4::%(...)") : around() { + tjp->proceed(); + } +}; diff --git a/AspectC++/tests/Bug549/Makefile b/AspectC++/tests/Bug549/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug549/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug549/feature.ref b/AspectC++/tests/Bug549/feature.ref new file mode 100644 index 0000000..f684a65 --- /dev/null +++ b/AspectC++/tests/Bug549/feature.ref @@ -0,0 +1,5 @@ +Bug549: exec joinpoint with function-reference-return-type +========================================================== +executing void (&get_func_ref())(int) +executing void (*get_func_pointer())(int) +executing int (&get_array_ref())[10] diff --git a/AspectC++/tests/Bug549/main.cc b/AspectC++/tests/Bug549/main.cc new file mode 100644 index 0000000..94a8045 --- /dev/null +++ b/AspectC++/tests/Bug549/main.cc @@ -0,0 +1,30 @@ +#include + +void void_int_func(int arg) {} + +void (&get_func_ref())(int) { + return void_int_func; +} + +void (*get_func_pointer())(int) { + return &void_int_func; +} + +int (&get_array_ref())[10] { + static int an_array[10]; + return an_array; +} + +int main() { + printf ("Bug549: exec joinpoint with function-reference-return-type\n"); + printf ("==========================================================\n"); + get_func_ref(); + get_func_pointer(); + get_array_ref(); +} + +aspect TestAspect { + advice execution("% get_%()") : before() { + printf ("executing %s\n", JoinPoint::signature ()); + } +}; diff --git a/AspectC++/tests/Bug552/Makefile b/AspectC++/tests/Bug552/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug552/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug552/Mem.h b/AspectC++/tests/Bug552/Mem.h new file mode 100644 index 0000000..52d9ade --- /dev/null +++ b/AspectC++/tests/Bug552/Mem.h @@ -0,0 +1,21 @@ +#pragma once + +class Mem +{ +public: + static void memset_mwords(void *dst, const unsigned long val, unsigned long nr_of_mwords); //FIXME: const triggers crash + +}; + +inline void +Mem::memset_mwords(void *dst, unsigned long value, unsigned long n) +{ + unsigned dummy1, dummy2; +#if 0 + asm volatile ("cld \n\t" + "repz stosl \n\t" + : "=c"(dummy1), "=D"(dummy2) + : "a"(value), "c"(n), "D"(dst) + : "memory"); +#endif +} diff --git a/AspectC++/tests/Bug552/feature.ref b/AspectC++/tests/Bug552/feature.ref new file mode 100644 index 0000000..386bb95 --- /dev/null +++ b/AspectC++/tests/Bug552/feature.ref @@ -0,0 +1,3 @@ +Bug552: repository-merge crashes ... +==================================== +no output, fine if it compiles without crashing diff --git a/AspectC++/tests/Bug552/file1.cc b/AspectC++/tests/Bug552/file1.cc new file mode 100644 index 0000000..8069d24 --- /dev/null +++ b/AspectC++/tests/Bug552/file1.cc @@ -0,0 +1,11 @@ +#include + +#include "Mem.h" + +int main() { + printf ("Bug552: repository-merge crashes ...\n"); + printf ("====================================\n"); + printf ("no output, fine if it compiles without crashing\n"); + Mem::memset_mwords(0, 42, 4711); + return 0; +} diff --git a/AspectC++/tests/Bug552/file2.cc b/AspectC++/tests/Bug552/file2.cc new file mode 100644 index 0000000..33f838c --- /dev/null +++ b/AspectC++/tests/Bug552/file2.cc @@ -0,0 +1,5 @@ +#include "Mem.h" + +void foo() { + Mem::memset_mwords(0, 42, 4711); +} diff --git a/AspectC++/tests/Bug552/file3.cc b/AspectC++/tests/Bug552/file3.cc new file mode 100644 index 0000000..6d6a000 --- /dev/null +++ b/AspectC++/tests/Bug552/file3.cc @@ -0,0 +1,5 @@ +#include "Mem.h" + +void bar() { + Mem::memset_mwords(0, 42, 4711); +} diff --git a/AspectC++/tests/Bug554/Makefile b/AspectC++/tests/Bug554/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug554/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug554/feature.ref b/AspectC++/tests/Bug554/feature.ref new file mode 100644 index 0000000..e26dd29 --- /dev/null +++ b/AspectC++/tests/Bug554/feature.ref @@ -0,0 +1,16 @@ +========== const call ========= +call: void A::__leave() const + JoinPoint::That is const: 0 + JoinPoint::Target is const: 1 +exec: void A::__leave() const + JoinPoint::That is const: 1 + JoinPoint::Target is const: 1 +const leave +======== non-const call ======= +call: void A::__leave() + JoinPoint::That is const: 0 + JoinPoint::Target is const: 0 +exec: void A::__leave() + JoinPoint::That is const: 0 + JoinPoint::Target is const: 0 +non-const leave diff --git a/AspectC++/tests/Bug554/main.cc b/AspectC++/tests/Bug554/main.cc new file mode 100644 index 0000000..d9d73c5 --- /dev/null +++ b/AspectC++/tests/Bug554/main.cc @@ -0,0 +1,62 @@ +#include +using namespace std; + +// --- test for constness --- +template +struct is_constant { + enum { IS_CONSTANT = 0 }; +}; +template +struct is_constant { + enum { IS_CONSTANT = 1 }; +}; + + +class A { + int foo(); +public: + A() {} +}; + +int A::foo() { __leave(); return 0; } + +int main() { + const A a; + cout << "========== const call =========" << endl; + a.__leave(); // const call + + A a1; + cout << "======== non-const call =======" << endl; + a1.__leave(); // non-const call + return 0; +} + + +slice class MySlice { +public: + __attribute__((always_inline)) inline void __leave() const { + cout << "const leave" << endl; + } + void __leave(); +}; + +slice void MySlice::__leave() { cout << "non-const leave" << endl; } + +aspect Aspect1 { + advice execution("% ...::__leave()") : around() { + cout << "exec: " << tjp->signature() << endl; + cout << " JoinPoint::That is const: " << is_constant::IS_CONSTANT << endl; // 1 (this is correct) + cout << " JoinPoint::Target is const: " << is_constant::IS_CONSTANT << endl; // puma: 0 (does this make sense?) + tjp->proceed(); + } + + advice call("% ...::__leave()") : around() { + cout << "call: " << tjp->signature() << endl; + cout << " JoinPoint::That is const: " << is_constant::IS_CONSTANT << endl; // 1 (this is correct) + cout << " JoinPoint::Target is const: " << is_constant::IS_CONSTANT << endl; // puma: 0 (does this make sense?) + tjp->proceed(); + } + + advice "A" : slice MySlice; +}; + diff --git a/AspectC++/tests/Bug561/Makefile b/AspectC++/tests/Bug561/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug561/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug561/feature.ref b/AspectC++/tests/Bug561/feature.ref new file mode 100644 index 0000000..68a584e --- /dev/null +++ b/AspectC++/tests/Bug561/feature.ref @@ -0,0 +1,12 @@ +Bug561: intro into macro-generated class +======================================== +called void Class_C::intro() const +called void Class_C::stuff() const +called void Class_C::intro() const +called void A_Foo::doStuff() +called void A_Foo::print() const +i is 5 +called int A_Bar::doStuff(int,int,int) +called void A_Bar::print() const +i is 6 +======================================== diff --git a/AspectC++/tests/Bug561/main.cc b/AspectC++/tests/Bug561/main.cc new file mode 100644 index 0000000..3cc6a47 --- /dev/null +++ b/AspectC++/tests/Bug561/main.cc @@ -0,0 +1,70 @@ +//#include + +#define GEN_CLASS(name) class Class_ ## name { \ +public: \ + inline void stuff () const; \ + }; \ + inline void Class_ ## name :: stuff () const { intro (); } + + +GEN_CLASS(C); + +#define FOO_GEN(func_name) \ +class func_name ## _Foo { \ +public: \ + static void doStuff(); \ +}; \ +inline void func_name ## _Foo::doStuff() + +FOO_GEN(A) { + A_Foo instance(5); + instance.print(); +} + +// .. and now more complicated: + +#define BAR_GEN(func_name, ret_type, ...) \ +class func_name ## _Bar { \ +public: \ + static ret_type doStuff(__VA_ARGS__); \ +}; \ +inline ret_type func_name ## _Bar::doStuff(__VA_ARGS__) + +#define IFACE(GEN, ...) \ + GEN(__VA_ARGS__) + +#define SIGNATURE A, int, int a1, int a2, int a3 + +IFACE(BAR_GEN, SIGNATURE) { + int sum = a1 + a2 + a3; + A_Bar instance(sum); + instance.print(); + return sum; +} + +int main () { + Class_C c; + printf ("Bug561: intro into macro-generated class\n"); + printf ("========================================\n"); + c.intro (); + c.stuff (); + A_Foo::doStuff (); + A_Bar::doStuff(1,2,3); + printf ("========================================\n"); +} + +aspect A { + advice "Class_C" : slice class { + public : + void intro ( ) const { } + }; + advice call("% Class_C::%(...)" || "% A_Foo::%(...)" || "% A_Bar::%(...)") : before () { + printf ("called %s\n", JoinPoint::signature ()); + } +}; + +#include "slice.ah" + +aspect Test_Aspect { + advice "%_Foo" || "%_Bar" : slice Test_Slice; +}; diff --git a/AspectC++/tests/Bug561/slice.ah b/AspectC++/tests/Bug561/slice.ah new file mode 100644 index 0000000..34301df --- /dev/null +++ b/AspectC++/tests/Bug561/slice.ah @@ -0,0 +1,15 @@ +#ifndef SLICE_AH__ +#define SLICE_AH__ + +#include + +slice class Test_Slice { + int i; +public: + Test_Slice(int i) : i(i) { } + void print() const { + printf("i is %d\n", i); + } +}; + +#endif // SLICE_AH__ diff --git a/AspectC++/tests/Bug564/Makefile b/AspectC++/tests/Bug564/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug564/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug564/feature.ref b/AspectC++/tests/Bug564/feature.ref new file mode 100644 index 0000000..e69de29 diff --git a/AspectC++/tests/Bug564/main.cc b/AspectC++/tests/Bug564/main.cc new file mode 100644 index 0000000..5c06b8b --- /dev/null +++ b/AspectC++/tests/Bug564/main.cc @@ -0,0 +1,7 @@ +#include "random_header.h" /* A + B */ + +int main() { + // If this compiles, then everything is fine. + return 0; +} diff --git a/AspectC++/tests/Bug564/random_header.h b/AspectC++/tests/Bug564/random_header.h new file mode 100644 index 0000000..8d1c8b6 --- /dev/null +++ b/AspectC++/tests/Bug564/random_header.h @@ -0,0 +1 @@ + diff --git a/AspectC++/tests/Bug566/Makefile b/AspectC++/tests/Bug566/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug566/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug566/feature.ref b/AspectC++/tests/Bug566/feature.ref new file mode 100644 index 0000000..c8cefc3 --- /dev/null +++ b/AspectC++/tests/Bug566/feature.ref @@ -0,0 +1,10 @@ +A::A(const char *,unsigned int) +0x1234, 4 +A::A(const char *,unsigned int,bool) +0x1234, 4 +void A::matchFunc1(const char *,unsigned int) +void A::matchFunc1(const char *,unsigned int) +0x1234, 4 +void A::matchFunc2(const char *,unsigned int) +void A::matchFunc2(const char *,unsigned int) +0x1234, 4 diff --git a/AspectC++/tests/Bug566/main.cc b/AspectC++/tests/Bug566/main.cc new file mode 100644 index 0000000..1ace344 --- /dev/null +++ b/AspectC++/tests/Bug566/main.cc @@ -0,0 +1,34 @@ +#include +using namespace std; +aspect TestAround { + pointcut matchFunc() = "% A::matchFunc%(...)"; + advice call(matchFunc()) || execution(matchFunc()) || construction("A") : around() { + cout << tjp->signature() << endl; + tjp->proceed(); + } +}; + +#include +class A { +public: + A(const char p1[], unsigned int p2) { + printf("0x%x, %u\n", *(int*)(&p1), p2); + } + A(const char* p1, unsigned int p2, bool b) { + printf("0x%x, %u\n", *(int*)(&p1), p2); + } + void matchFunc1(const char p1[], unsigned int p2) { + printf("0x%x, %u\n", *(int*)(&p1), p2); + } + void matchFunc2(const char* p1, unsigned int p2) { + printf("0x%x, %u\n", *(int*)(&p1), p2); + } +}; + +int main() { + A a = A((char*) 0x1234, 4); + a = A((char*) 0x1234, 4, true); + a.matchFunc1((char*) 0x1234, 4); + a.matchFunc2((char*) 0x1234, 4); + return 0; +} diff --git a/AspectC++/tests/Bug567/Makefile b/AspectC++/tests/Bug567/Makefile new file mode 100644 index 0000000..daa5e9e --- /dev/null +++ b/AspectC++/tests/Bug567/Makefile @@ -0,0 +1,2 @@ +ACFLAGS ?= --builtin_operators --data_joinpoints +include ../Makefile.generic diff --git a/AspectC++/tests/Bug567/feature.ref b/AspectC++/tests/Bug567/feature.ref new file mode 100644 index 0000000..80e450d --- /dev/null +++ b/AspectC++/tests/Bug567/feature.ref @@ -0,0 +1,15 @@ +Bug567: target() pointcut function defect for get/set advice +============================================================ +set/args int FooBar::z 3 +call/target void FooBar::f() +set/that int FooBar::y +set/args int FooBar::y 6 +get/that int FooBar::y +get/result int FooBar::y 6 +set/that int FooBar::z +set/args int FooBar::z 6 +set/args int FooBar::y 4 +set/args int FooBar::y 5 +set/target int FooBar::z +set/args int FooBar::z 7 +============================================================ diff --git a/AspectC++/tests/Bug567/main.cc b/AspectC++/tests/Bug567/main.cc new file mode 100644 index 0000000..e1dc9cf --- /dev/null +++ b/AspectC++/tests/Bug567/main.cc @@ -0,0 +1,53 @@ +#include + +struct FooBar { + int z; + static int y; + void f() { y = 6; z = y; } + static void g() { y = 5; } +}; + +int FooBar::y; + +struct BarFoos : public FooBar {}; + +int main() { + printf ("Bug567: target() pointcut function defect for get/set advice\n"); + printf ("============================================================\n"); + FooBar b; + b.z = 3; + b.f(); + + FooBar::y = 4; + FooBar::g(); + + BarFoos f; + f.z = 7; + printf ("============================================================\n"); +} + +aspect MemberTrace { + advice call("% %::...::%(...)") && target(!"void") : before() { + printf ("call/target %s\n", JoinPoint::signature()); + } + + advice set("% %::...::%") && target(bf) : before(BarFoos* bf) { + printf ("set/target %s\n", JoinPoint::signature()); + } + + advice set("% %::...::%") && that("%") : before() { + printf ("set/that %s\n", JoinPoint::signature()); + } + + advice get("% %::...::%") && that("%") : before() { + printf ("get/that %s\n", JoinPoint::signature()); + } + + advice set("% %::...::%") && args(i) : before(int i) { + printf ("set/args %s %d\n", JoinPoint::signature(), i); + } + + advice get("% %::...::%") && result(i) : after(int i) { + printf ("get/result %s %d\n", JoinPoint::signature(), i); + } +}; diff --git a/AspectC++/tests/Bug568/Makefile b/AspectC++/tests/Bug568/Makefile new file mode 100644 index 0000000..01d074c --- /dev/null +++ b/AspectC++/tests/Bug568/Makefile @@ -0,0 +1,2 @@ +ACFLAGS += --builtin_operators --data_joinpoints +include ../Makefile.generic diff --git a/AspectC++/tests/Bug568/feature.ref b/AspectC++/tests/Bug568/feature.ref new file mode 100644 index 0000000..16ecd32 --- /dev/null +++ b/AspectC++/tests/Bug568/feature.ref @@ -0,0 +1,15 @@ +Should select 1: 1 +Should select 1: 1 +Should select 1: 1 +Should select 1: 1 +Should select 3: 3 +Should select 2: 2 +Should select 2: 2 +Should select 3: 3 +Should select 1: 1 +Should be 4711: 4711 +Should be 4711: 4711 +Should be 4711: 4711 +Should be 11: 11 +Should be 32: 32 +Should be 48: 48 diff --git a/AspectC++/tests/Bug568/main.cc b/AspectC++/tests/Bug568/main.cc new file mode 100644 index 0000000..2dc588d --- /dev/null +++ b/AspectC++/tests/Bug568/main.cc @@ -0,0 +1,147 @@ +#include +using namespace std; + +namespace A { + namespace A { + namespace B { + class C { + public: + static C* m; + static int n; + void func(int) { + cout << "1" << endl; + } + }; + } + namespace A { + namespace B { + class C { + public: + static ::A::A::B::C* m; + static int n; + void func(int) { + cout << "2" << endl; + } + }; + } + } + } + namespace B { + class C { + public: + static A::A::B::C* m; + static int n; + void func(int) { + cout << "3" << endl; + } + }; + } + void caller2(A::B::C c) { + c.func(1); + } + void caller3(A::B::C& c) { + c.func(1); + } + void caller4(A::B::C* c) { + c->func(1); + } + void caller5(void (A::B::C::* c)(int)) { + A::B::C obj; + (obj.*c)(1); + obj.n = obj.n + 1; + } + void caller6(void (::A::B::C::* c)(int)) { + ::A::B::C obj; + (obj.*c)(1); + obj.n = obj.n + 2; + } + void caller7(void (A::A::B::C::* c)(int)) { + A::A::B::C obj; + (obj.*c)(1); + obj.n = obj.n + 4; + } + void caller8(void (::A::A::A::B::C::* c)(int)) { + ::A::A::A::B::C obj; + (obj.*c)(1); + obj.n = obj.n + 8; + } + void caller9(void (B::C::* c)(int)) { + B::C obj; + (obj.*c)(1); + obj.n = obj.n + 16; + } + + template + void TemplTester (T2*& t2) { + T t = T2(); + t.func(42); + } + + void caller(int) { + + + A::A::B::C c5; + ::A::B::C::m = &c5; + ::A::A::B::C::m = A::A::B::C::m = B::C::m->m = reinterpret_cast(4711); + + + cout << "Should select 1: "; + caller2(A::B::C()); + A::B::C c; + cout << "Should select 1: "; + caller3(c); + cout << "Should select 1: "; + caller4(&c); + cout << "Should select 1: "; + caller5(&A::B::C::func); + cout << "Should select 3: "; + caller6(&::A::B::C::func); + cout << "Should select 2: "; + caller7(&A::A::B::C::func); + cout << "Should select 2: "; + caller8(&::A::A::A::B::C::func); + cout << "Should select 3: "; + caller9(&B::C::func); + + ::A::A::B::C c2; + c2 = A::B::C(); + A::B::C* c3; + c3 = &c2; + ::A::A::B::C*& c4 = c3; + cout << "Should select 1: "; + TemplTester(c4); + + } +} + +A::A::B::C* A::A::B::C::m = 0; +::A::A::B::C* A::A::A::B::C::m = 0; +A::A::A::B::C* ::A::B::C::m = 0; + +int A::A::B::C::n = 10; +int A::A::A::B::C::n = 20; +int ::A::B::C::n = 30; + +int main() { + + A::caller(0); + + cout << "Should be 4711: " << reinterpret_cast(A::A::B::C::m) << endl; + cout << "Should be 4711: " << reinterpret_cast(A::A::A::B::C::m) << endl; + cout << "Should be 4711: " << reinterpret_cast(A::B::C::m->m) << endl; + + cout << "Should be 11: " << A::A::B::C::n << endl; + cout << "Should be 32: " << A::A::A::B::C::n << endl; + cout << "Should be 48: " << A::B::C::n << endl; + return 0; +} + +aspect Asp { + advice call("% ...::%(...)") || builtin("% ...::%(...)") || set("% ...::%") : before() { + tjp->arg<0>(); // All matchable functions have exactly one argument. + } + + advice get("% ...::%") : around() { + tjp->proceed(); + } +}; diff --git a/AspectC++/tests/Bug570/Makefile b/AspectC++/tests/Bug570/Makefile new file mode 100644 index 0000000..71aca95 --- /dev/null +++ b/AspectC++/tests/Bug570/Makefile @@ -0,0 +1,4 @@ +WEAVE_ERROR := 1 +# make sure the error message, which depends on the frontend, is hidden as well as the column +AC_PATTERN_REPLACEMENTS := | grep "error: " | sed -e 's/cc:\([0-9][0-9]*\):[0-9][0-9]*:/cc:\1:/' | sed -e "s/error: .*/error: <<>>/" +include ../Makefile.generic diff --git a/AspectC++/tests/Bug570/feature.ref b/AspectC++/tests/Bug570/feature.ref new file mode 100644 index 0000000..a6f34fd --- /dev/null +++ b/AspectC++/tests/Bug570/feature.ref @@ -0,0 +1 @@ +main.cc:5: error: <<>> diff --git a/AspectC++/tests/Bug570/main.cc b/AspectC++/tests/Bug570/main.cc new file mode 100644 index 0000000..ca3f0bc --- /dev/null +++ b/AspectC++/tests/Bug570/main.cc @@ -0,0 +1,7 @@ +// This test shows whether error messages by the internal parser refer +// to the correct line + +int main() { + bla; // this is line 5 of main.cc! + return 0; +} diff --git a/AspectC++/tests/Bug571-1/Makefile b/AspectC++/tests/Bug571-1/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug571-1/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug571-1/feature.ref b/AspectC++/tests/Bug571-1/feature.ref new file mode 100644 index 0000000..afef7c1 --- /dev/null +++ b/AspectC++/tests/Bug571-1/feature.ref @@ -0,0 +1,6 @@ +before execution of "memberfunc" in B +before call of "func" in B +in B +after call of "func" in B +after execution of "memberfunc" in B +in C diff --git a/AspectC++/tests/Bug571-1/main.cc b/AspectC++/tests/Bug571-1/main.cc new file mode 100644 index 0000000..315bb99 --- /dev/null +++ b/AspectC++/tests/Bug571-1/main.cc @@ -0,0 +1,61 @@ +// Testing passing of "this" as argument of the call-wrapper if +// "that" pointcut functions with runtime checks are used. +// In this test a TJP-Struct should not be inserted. + +#include +using namespace std; + +void func(const char* c) { + cout << c << endl; +} +class A{ + public: + virtual void memberfunc() { + func("in A"); + } +}; +class B : public A{ + public: + virtual void memberfunc() { + func("in B"); + } +}; +class C : public A{ + public: + virtual void memberfunc() { + func("in C"); + } +}; + +int main() { + B b; + A& a = b; + a.memberfunc(); + C c; + A& a2 = c; + a2.memberfunc(); + return 0; +} + +const char* call_text = " call of \"func\" in B"; +const char* execution_text = " execution of \"memberfunc\" in B"; +aspect Asp { + pointcut call_func_that_B() = call("void func(...)") && that("B"); + pointcut execution_memberfunc_that_B() = execution("void ...::memberfunc(...)") && that("B"); + + advice call_func_that_B() : before() { + cout << "before" << call_text << endl; + } + + advice call_func_that_B() : after() { + cout << "after" << call_text << endl; + } + + advice execution_memberfunc_that_B() : before() { + cout << "before" << execution_text << endl; + } + + advice execution_memberfunc_that_B() : after() { + cout << "after" << execution_text << endl; + } +}; diff --git a/AspectC++/tests/Bug571-2/Makefile b/AspectC++/tests/Bug571-2/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug571-2/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug571-2/feature.ref b/AspectC++/tests/Bug571-2/feature.ref new file mode 100644 index 0000000..1655833 --- /dev/null +++ b/AspectC++/tests/Bug571-2/feature.ref @@ -0,0 +1,10 @@ +before execution of "memberfunc" in B +around 1 execution of "memberfunc" in B +around 2 execution of "memberfunc" in B +before call of "func" in B +around 1 call of "func" in B +around 2 call of "func" in B +in B +after call of "func" in B +after execution of "memberfunc" in B +in C diff --git a/AspectC++/tests/Bug571-2/main.cc b/AspectC++/tests/Bug571-2/main.cc new file mode 100644 index 0000000..46e20f5 --- /dev/null +++ b/AspectC++/tests/Bug571-2/main.cc @@ -0,0 +1,84 @@ +// Testing passing of "this" as argument of the call-wrapper if +// "that" pointcut functions with runtime checks are used. +// Additionally, this test checks if the runtime condition code +// accesses "this"/"that" via the TJP-Struct in case of multiple +// around advice." +#include +using namespace std; + +void func(const char* c) { + cout << c << endl; +} +class A{ + public: + virtual void memberfunc() { + func("in A"); + } +}; +class B : public A{ + public: + virtual void memberfunc() { + func("in B"); + } +}; +class C : public A{ + public: + virtual void memberfunc() { + func("in C"); + } +}; + +int main() { + B b; + A& a = b; + a.memberfunc(); + C c; + A& a2 = c; + a2.memberfunc(); + return 0; +} + +const char* call_text = " call of \"func\" in B"; +const char* execution_text = " execution of \"memberfunc\" in B"; +aspect Asp { + pointcut call_func_that_B() = call("void func(...)") && that("B"); + pointcut execution_memberfunc_that_B() = execution("void ...::memberfunc(...)") && that("B"); + + advice call_func_that_B() : before() { + cout << "before" << call_text << endl; + } + + advice call_func_that_B() : after() { + cout << "after" << call_text << endl; + } + + advice call_func_that_B() : around() { + cout << "around 1" << call_text << endl; + tjp->proceed(); + } + + advice call_func_that_B() : around() { + cout << "around 2" << call_text << endl; + tjp->proceed(); + } + + + advice execution_memberfunc_that_B() : before() { + cout << "before" << execution_text << endl; + } + + advice execution_memberfunc_that_B() : after() { + cout << "after" << execution_text << endl; + } + + advice execution_memberfunc_that_B() : around() { + cout << "around 1" << execution_text << endl; + tjp->proceed(); + } + + advice execution_memberfunc_that_B() : around() { + cout << "around 2" << execution_text << endl; + tjp->proceed(); + } +}; + diff --git a/AspectC++/tests/Bug571-3/Makefile b/AspectC++/tests/Bug571-3/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug571-3/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug571-3/feature.ref b/AspectC++/tests/Bug571-3/feature.ref new file mode 100644 index 0000000..07fb29e --- /dev/null +++ b/AspectC++/tests/Bug571-3/feature.ref @@ -0,0 +1,4 @@ +before execution of "memberfunc" in B +around 1 execution of "memberfunc" in B +after execution of "memberfunc" in B +in C diff --git a/AspectC++/tests/Bug571-3/main.cc b/AspectC++/tests/Bug571-3/main.cc new file mode 100644 index 0000000..91bee08 --- /dev/null +++ b/AspectC++/tests/Bug571-3/main.cc @@ -0,0 +1,81 @@ +// Testing passing of "this" as argument of the call-wrapper if +// "that" pointcut functions with runtime checks are used. +// Additionally, this test checks if the TJP-Struct incl. proceed +// function is correctly inserted even if it is only used by the condition +// check code. + +#include +using namespace std; + +void func(const char* c) { + cout << c << endl; +} +class A{ + public: + virtual void memberfunc() { + func("in A"); + } +}; +class B : public A{ + public: + virtual void memberfunc() { + func("in B"); + } +}; +class C : public A{ + public: + virtual void memberfunc() { + func("in C"); + } +}; + +int main() { + B b; + A& a = b; + a.memberfunc(); + C c; + A& a2 = c; + a2.memberfunc(); + return 0; +} + +const char* call_text = " call of \"func\" in B"; +const char* execution_text = " execution of \"memberfunc\" in B"; +aspect Asp { + pointcut call_func_that_B() = call("void func(...)") && that("B"); + pointcut execution_memberfunc_that_B() = execution("void ...::memberfunc(...)") && that("B"); + + advice call_func_that_B() : before() { + cout << "before" << call_text << endl; + } + + advice call_func_that_B() : after() { + cout << "after" << call_text << endl; + } + + advice call_func_that_B() : around() { + cout << "around 1" << call_text << endl; + } + + advice call_func_that_B() : around() { + cout << "around 2" << call_text << endl; + } + + + advice execution_memberfunc_that_B() : before() { + cout << "before" << execution_text << endl; + } + + advice execution_memberfunc_that_B() : after() { + cout << "after" << execution_text << endl; + } + + advice execution_memberfunc_that_B() : around() { + cout << "around 1" << execution_text << endl; + } + + advice execution_memberfunc_that_B() : around() { + cout << "around 2" << execution_text << endl; + } +}; + diff --git a/AspectC++/tests/Bug574/Makefile b/AspectC++/tests/Bug574/Makefile new file mode 100644 index 0000000..daa5e9e --- /dev/null +++ b/AspectC++/tests/Bug574/Makefile @@ -0,0 +1,2 @@ +ACFLAGS ?= --builtin_operators --data_joinpoints +include ../Makefile.generic diff --git a/AspectC++/tests/Bug574/feature.ref b/AspectC++/tests/Bug574/feature.ref new file mode 100644 index 0000000..35f7aea --- /dev/null +++ b/AspectC++/tests/Bug574/feature.ref @@ -0,0 +1,2 @@ +bool Cyg_SchedThread::priority_inherited +int Cyg_SchedThread::original_priority diff --git a/AspectC++/tests/Bug574/main.cc b/AspectC++/tests/Bug574/main.cc new file mode 100644 index 0000000..4983142 --- /dev/null +++ b/AspectC++/tests/Bug574/main.cc @@ -0,0 +1,53 @@ +typedef int cyg_priority; +typedef bool cyg_bool; + +class Cyg_SchedThread + //: public Cyg_SchedThread_Implementation +{ + + +protected: + cyg_priority original_priority; // our original priority + + cyg_bool priority_inherited; // have we inherited? + +}; + +class Cyg_HardwareThread {}; + +class Cyg_Thread + : public Cyg_HardwareThread, // provides hardware abstractions + public Cyg_SchedThread // provides scheduling abstractions +{ + +public: + cyg_priority get_priority(); + +}; + +inline cyg_priority Cyg_Thread::get_priority() +{ + if( priority_inherited ) return original_priority; + else return 0; +} + + + +int main() { + Cyg_Thread t; + t.get_priority(); + return 0; +} + +#include +using namespace std; + +aspect GetterSetter { + pointcut all_variables() = "% ...::%"; + + advice get(all_variables()) || set(all_variables()) : before() { + cout << tjp->signature() << endl; + } + +}; + diff --git a/AspectC++/tests/Bug575/Makefile b/AspectC++/tests/Bug575/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug575/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug575/feature.ref b/AspectC++/tests/Bug575/feature.ref new file mode 100644 index 0000000..cc30bcf --- /dev/null +++ b/AspectC++/tests/Bug575/feature.ref @@ -0,0 +1,4 @@ +Bug575: Inject bypass class vs. macros +====================================== +... fine if it compiles +====================================== diff --git a/AspectC++/tests/Bug575/main.cc b/AspectC++/tests/Bug575/main.cc new file mode 100644 index 0000000..d8a841d --- /dev/null +++ b/AspectC++/tests/Bug575/main.cc @@ -0,0 +1,32 @@ +#include + +#define TRAP_CTOR_SCOPE public + +class TrapListener { + TRAP_CTOR_SCOPE: +public: + TrapListener() {} +}; + +#define CLASS_START class C2 { + +CLASS_START +public: + int i; +}; + +struct A { typedef struct {} B; struct X{} x; }; + +int main () { + printf ("Bug575: Inject bypass class vs. macros\n"); + printf ("======================================\n"); + TrapListener tl; + C2 c2; + c2.i = 42; + printf ("... fine if it compiles\n"); + printf ("======================================\n"); +} + +aspect X { + advice "A" : slice struct : public TrapListener; +}; diff --git a/AspectC++/tests/Bug576/Makefile b/AspectC++/tests/Bug576/Makefile new file mode 100644 index 0000000..daa5e9e --- /dev/null +++ b/AspectC++/tests/Bug576/Makefile @@ -0,0 +1,2 @@ +ACFLAGS ?= --builtin_operators --data_joinpoints +include ../Makefile.generic diff --git a/AspectC++/tests/Bug576/feature.ref b/AspectC++/tests/Bug576/feature.ref new file mode 100644 index 0000000..84b8ede --- /dev/null +++ b/AspectC++/tests/Bug576/feature.ref @@ -0,0 +1,4 @@ +int Cyg_Interrupt::vector +unsigned int *volatile hal_interrupt_handlers[224] +int Cyg_Interrupt::vector +unsigned int *volatile hal_interrupt_handlers[224] diff --git a/AspectC++/tests/Bug576/main.cc b/AspectC++/tests/Bug576/main.cc new file mode 100644 index 0000000..898f643 --- /dev/null +++ b/AspectC++/tests/Bug576/main.cc @@ -0,0 +1,110 @@ +#include + +#define CYG_MACRO_START do { +#define CYG_MACRO_END } while (0) + +#define CYGNUM_HAL_ISR_MIN 32 +#define CYGNUM_HAL_ISR_MAX 255 +#define CYGNUM_HAL_ISR_COUNT (CYGNUM_HAL_ISR_MAX - CYGNUM_HAL_ISR_MIN + 1) + +typedef int cyg_uint32; +typedef cyg_uint32 cyg_vector_t; +typedef cyg_vector_t cyg_vector; +typedef unsigned int* CYG_ADDRESS; +typedef unsigned int CYG_ADDRWORD; + +//-------------------------------------------------------------------------- +// Static data used by HAL + +// ISR tables +volatile CYG_ADDRESS hal_interrupt_handlers[CYGNUM_HAL_ISR_COUNT]; +volatile CYG_ADDRWORD hal_interrupt_data[CYGNUM_HAL_ISR_COUNT]; +volatile CYG_ADDRESS hal_interrupt_objects[CYGNUM_HAL_ISR_COUNT]; + +// VSR table +//volatile CYG_ADDRESS hal_vsr_table[CYGNUM_HAL_VSR_COUNT]; + +//-------------------------------------------------------------------------- +// Interrupt state storage + +typedef cyg_uint32 CYG_INTERRUPT_STATE; + + +//--------------------------------------------------------------------------- +// Default ISR + +cyg_uint32 hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data); +cyg_uint32 hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data) { return 42; } + +typedef cyg_uint32 cyg_ISR(cyg_vector vector, CYG_ADDRWORD data); + + +#define HAL_DEFAULT_ISR hal_default_isr + + +#define HAL_TRANSLATE_VECTOR(_vector_,_index_) \ + ((_index_) = ((_vector_)-CYGNUM_HAL_ISR_MIN)) + +#define HAL_INTERRUPT_IN_USE( _vector_, _state_) \ + CYG_MACRO_START \ + cyg_uint32 _index_; \ + HAL_TRANSLATE_VECTOR ((_vector_), _index_); \ + \ + if (hal_interrupt_handlers[_index_] \ + ==(CYG_ADDRESS)HAL_DEFAULT_ISR) \ + (_state_) = 0; \ + else \ + (_state_) = 1; \ + CYG_MACRO_END + +#define HAL_INTERRUPT_ATTACH( _vector_, _isr_, _data_, _object_ ) \ + CYG_MACRO_START \ + cyg_uint32 _index_; \ + HAL_TRANSLATE_VECTOR((_vector_), _index_); \ + \ + if( hal_interrupt_handlers[_index_] == (CYG_ADDRESS)HAL_DEFAULT_ISR ) \ + { \ + hal_interrupt_handlers[_index_] = (CYG_ADDRESS)(_isr_); \ + hal_interrupt_data[_index_] = (CYG_ADDRWORD)(_data_); \ + hal_interrupt_objects[_index_] = (CYG_ADDRESS)(_object_); \ + } \ + CYG_MACRO_END + +class Cyg_Interrupt +{ + cyg_vector vector; // Interrupt vector + + cyg_ISR *isr; // Pointer to ISR + + CYG_ADDRWORD data; // Data pointer + +public: + void attach(void); + Cyg_Interrupt() : vector(CYGNUM_HAL_ISR_MIN + 1), isr(0), data(0) {} +}; + + +void +Cyg_Interrupt::attach(void) +{ + int in_use; + + + HAL_INTERRUPT_IN_USE( vector, in_use ); + //CYG_ASSERT( 0 == in_use, "Interrupt vector not free."); + + HAL_INTERRUPT_ATTACH( vector, isr, data, this ); +} + +int main() { + Cyg_Interrupt i; + i.attach(); + return 0; +} + +aspect Tracer { + advice get("% ...::%") || set("% ...::%") : before() { + printf("%s\n", JoinPoint::signature()); + } +}; + diff --git a/AspectC++/tests/Bug577/Makefile b/AspectC++/tests/Bug577/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug577/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug577/alex.ah b/AspectC++/tests/Bug577/alex.ah new file mode 100644 index 0000000..157050c --- /dev/null +++ b/AspectC++/tests/Bug577/alex.ah @@ -0,0 +1,8 @@ +#ifndef __alex_ah__ +#define __alex_ah__ + +#include "alex.h" + +M + +#endif diff --git a/AspectC++/tests/Bug577/alex.h b/AspectC++/tests/Bug577/alex.h new file mode 100644 index 0000000..cdb4824 --- /dev/null +++ b/AspectC++/tests/Bug577/alex.h @@ -0,0 +1,8 @@ +#ifndef __alex_h__ +#define __alex_h__ + +#include + +#include "macro.ah" + +#endif diff --git a/AspectC++/tests/Bug577/feature.ref b/AspectC++/tests/Bug577/feature.ref new file mode 100644 index 0000000..70ff2ca --- /dev/null +++ b/AspectC++/tests/Bug577/feature.ref @@ -0,0 +1,4 @@ +Bug577: Aspect generated by macro +================================= +... seems to work! +================================= diff --git a/AspectC++/tests/Bug577/macro.ah b/AspectC++/tests/Bug577/macro.ah new file mode 100644 index 0000000..e2a3c2e --- /dev/null +++ b/AspectC++/tests/Bug577/macro.ah @@ -0,0 +1,9 @@ +#ifndef __macro_ah__ +#define __macro_ah__ + +#define M aspect A { advice execution("% main(...)") : after () { \ + printf ("... seems to work!\n"); \ + printf ("=================================\n"); \ +} }; + +#endif // __macro_ah__ diff --git a/AspectC++/tests/Bug577/main.cc b/AspectC++/tests/Bug577/main.cc new file mode 100644 index 0000000..f45115d --- /dev/null +++ b/AspectC++/tests/Bug577/main.cc @@ -0,0 +1,7 @@ +#include + +int main() { + printf ("Bug577: Aspect generated by macro\n"); + printf ("=================================\n"); + return 0; +} diff --git a/AspectC++/tests/Bug580/Makefile b/AspectC++/tests/Bug580/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug580/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug580/feature.ref b/AspectC++/tests/Bug580/feature.ref new file mode 100644 index 0000000..5daf978 --- /dev/null +++ b/AspectC++/tests/Bug580/feature.ref @@ -0,0 +1 @@ +enter: true diff --git a/AspectC++/tests/Bug580/main.cc b/AspectC++/tests/Bug580/main.cc new file mode 100644 index 0000000..1e19a04 --- /dev/null +++ b/AspectC++/tests/Bug580/main.cc @@ -0,0 +1,31 @@ +#include +//Extracted from memcached: +//------------------------ + +#define bool bool +#define true true + +class C { + void f(); +}; +void C::f() {} + + +slice class Foo { +public: + bool enter(); +}; +slice bool Foo::enter() { return true; } + + +aspect Bar { + advice "C" : slice Foo; + advice execution("% C::%(...)") : before() {} +}; + + +int main() { + C c; + printf ("enter: %s\n", c.enter() ? "true":"false"); + return 0; +} diff --git a/AspectC++/tests/Bug589/Makefile b/AspectC++/tests/Bug589/Makefile new file mode 100644 index 0000000..dd5d808 --- /dev/null +++ b/AspectC++/tests/Bug589/Makefile @@ -0,0 +1,2 @@ +ACFLAGS ?= --data_joinpoints +include ../Makefile.generic diff --git a/AspectC++/tests/Bug589/feature.ref b/AspectC++/tests/Bug589/feature.ref new file mode 100644 index 0000000..f1549c7 --- /dev/null +++ b/AspectC++/tests/Bug589/feature.ref @@ -0,0 +1,4 @@ +Bug589: Entity type uses private types instead of deduced types +=============================================================== +Fine if it compiles without errors +=============================================================== diff --git a/AspectC++/tests/Bug589/main.cc b/AspectC++/tests/Bug589/main.cc new file mode 100644 index 0000000..6a830c3 --- /dev/null +++ b/AspectC++/tests/Bug589/main.cc @@ -0,0 +1,64 @@ +#include + +struct Basic_list_policy_Timeout +{ + typedef Basic_list_policy_Timeout **Type; +}; + +class Basic_list_Timeout +{ + +public: + class Iterator + { + private: + typedef Basic_list_policy_Timeout::Type Internal_type; + + public: + + + Internal_type get_c_const() const { return _c; } + + //template + //Internal_type ttest(T o) const { return _c; } + + //Internal_type arg_test(Internal_type o) const { return _c; } + + private: + + Internal_type _c; + + public: + + Internal_type _internal; + + }; + +public: + static Basic_list_policy_Timeout::Type __get_internal(Iterator const &i) { return i.get_c_const(); } + + //static Basic_list_policy_Timeout::Type __get_ttest(Iterator const &i) { return i.ttest(i.get_c_const()); } + + //static Basic_list_policy_Timeout::Type __get_arg_test(Iterator const &i) { return i.arg_test(i.get_c_const()); } +}; + +int main() { + printf ("Bug589: Entity type uses private types instead of deduced types\n"); + printf ("===============================================================\n"); + Basic_list_Timeout::Iterator i; + Basic_list_policy_Timeout::Type v1 = Basic_list_Timeout::__get_internal(i); + Basic_list_policy_Timeout::Type v2 = i._internal; + printf ("Fine if it compiles without errors\n"); + printf ("===============================================================\n"); +} + +aspect Buggy { + // This advice doesn't work yet + // advice get("% ...::%") : before() { + // tjp->entity(); + // } + advice call("% ...::%(...)") : before() { + tjp->target(); + } +}; + diff --git a/AspectC++/tests/Bug594/Makefile b/AspectC++/tests/Bug594/Makefile new file mode 100644 index 0000000..8abc008 --- /dev/null +++ b/AspectC++/tests/Bug594/Makefile @@ -0,0 +1,2 @@ +ACFLAGS ?= --builtin_operators +include ../Makefile.generic diff --git a/AspectC++/tests/Bug594/feature.ref b/AspectC++/tests/Bug594/feature.ref new file mode 100644 index 0000000..2edb1c8 --- /dev/null +++ b/AspectC++/tests/Bug594/feature.ref @@ -0,0 +1,4 @@ +int *operator &(int &) at line 8 +int operator +(int) at line 9 +int operator +(int,int) at line 10 +int &operator ++(int &) at line 11 diff --git a/AspectC++/tests/Bug594/main.cc b/AspectC++/tests/Bug594/main.cc new file mode 100644 index 0000000..24aa87f --- /dev/null +++ b/AspectC++/tests/Bug594/main.cc @@ -0,0 +1,20 @@ +#include +using namespace std; + +int main() { + // If clang 3.7.1 is used, the register builtin operator member function + // is called two times for the same operator inside an array init expr. + int i = 0; + int* a[] = { &i }; + int a2[] = { +i }; + int a3[] = { i + i }; + int a4[] = { ++i }; + // ... + return 0; +} + +aspect TestExecution { + advice builtin("% ...::%(...)") : before () { + cout << tjp->signature() << " at line " << tjp->line() << endl; + } +}; diff --git a/AspectC++/tests/Bug598/Makefile b/AspectC++/tests/Bug598/Makefile new file mode 100644 index 0000000..daa5e9e --- /dev/null +++ b/AspectC++/tests/Bug598/Makefile @@ -0,0 +1,2 @@ +ACFLAGS ?= --builtin_operators --data_joinpoints +include ../Makefile.generic diff --git a/AspectC++/tests/Bug598/feature.ref b/AspectC++/tests/Bug598/feature.ref new file mode 100644 index 0000000..e339d9f --- /dev/null +++ b/AspectC++/tests/Bug598/feature.ref @@ -0,0 +1,5 @@ +Get: char const arr[2] +Entity type: char type +Result type: char type +Res::Type: char type +Res::ReferredType: char type diff --git a/AspectC++/tests/Bug598/main.cc b/AspectC++/tests/Bug598/main.cc new file mode 100644 index 0000000..cb80815 --- /dev/null +++ b/AspectC++/tests/Bug598/main.cc @@ -0,0 +1,32 @@ +#include +using namespace std; + +template +struct is_char { + static void print() { cout << "wrong type" << endl; } +}; +template<> +struct is_char { + static void print() { cout << "char type" << endl; } +}; + +const char arr[2] = {'A', 'B'}; + +int main() { + char x = arr[1]; + return 0; +} + +aspect Bar { + advice get("% ...::%") : before() { + cout << "Get: " << JoinPoint::signature() << endl; + cout << "Entity type: "; + is_char::print(); // should be: char type + cout << "Result type: "; + is_char::print(); // should be: char type + cout << "Res::Type: "; + is_char::print(); + cout << "Res::ReferredType: "; + is_char::print(); + } +}; diff --git a/AspectC++/tests/Bug768/Makefile b/AspectC++/tests/Bug768/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug768/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug768/feature.ref b/AspectC++/tests/Bug768/feature.ref new file mode 100644 index 0000000..e69de29 diff --git a/AspectC++/tests/Bug768/main.cc b/AspectC++/tests/Bug768/main.cc new file mode 100644 index 0000000..1bc0316 --- /dev/null +++ b/AspectC++/tests/Bug768/main.cc @@ -0,0 +1,7 @@ +static union { + int i; +}; +// If it compiles it is fine. +int main () { + +} diff --git a/AspectC++/tests/Bug769/Makefile b/AspectC++/tests/Bug769/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug769/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug769/feature.ref b/AspectC++/tests/Bug769/feature.ref new file mode 100644 index 0000000..e69de29 diff --git a/AspectC++/tests/Bug769/main.cc b/AspectC++/tests/Bug769/main.cc new file mode 100644 index 0000000..7c1c7d2 --- /dev/null +++ b/AspectC++/tests/Bug769/main.cc @@ -0,0 +1,8 @@ +namespace { + union { + int i; + } u; +} +// If it compiles it is fine. +int main() { +} diff --git a/AspectC++/tests/Bug770/Makefile b/AspectC++/tests/Bug770/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Bug770/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Bug770/feature.ref b/AspectC++/tests/Bug770/feature.ref new file mode 100644 index 0000000..e69de29 diff --git a/AspectC++/tests/Bug770/main.cc b/AspectC++/tests/Bug770/main.cc new file mode 100644 index 0000000..8cdfcf4 --- /dev/null +++ b/AspectC++/tests/Bug770/main.cc @@ -0,0 +1,81 @@ +// This test tests the phase 1 de-anonymization of unions. +// If it compiles it is fine. + +static union { + int i; +}; + +union { + int i_b; +} name1; + + +namespace { + static union { + int i2; + }; +} + +namespace { + union { + int i2_b; + } name2; +} + +namespace { + static union { + int i2_c; + } name2_c; +} + + +namespace N { + static union { + int i3; + }; +} + +namespace N { + union { + int i3_b; + } name3; +} + +namespace N { + static union { + int i3_c; + } name3_c; +} + +class { + union { + int i4; + }; +} c; + +class C { + union { + int i4; + }; +}; + +class C_b { + static union { + int i4; + } name4; +}; + +class C_c { + union { + int i4; + } name4; +}; + + +void f() { + static union { + int i4; + }; +} + +int main() { } diff --git a/AspectC++/tests/CFlowCycle/A.h b/AspectC++/tests/CFlowCycle/A.h new file mode 100644 index 0000000..151babd --- /dev/null +++ b/AspectC++/tests/CFlowCycle/A.h @@ -0,0 +1,12 @@ +#ifndef __A_h__ +#define __A_h__ + +#include "C.h" + +class A { +public: + static void f() { C::f(); } +}; + + +#endif // __A_h__ diff --git a/AspectC++/tests/CFlowCycle/B.h b/AspectC++/tests/CFlowCycle/B.h new file mode 100644 index 0000000..7bc974a --- /dev/null +++ b/AspectC++/tests/CFlowCycle/B.h @@ -0,0 +1,10 @@ +#ifndef __B_h__ +#define __B_h__ + +class B { +public: + static void f() {} +}; + + +#endif // __B_h__ diff --git a/AspectC++/tests/CFlowCycle/C.h b/AspectC++/tests/CFlowCycle/C.h new file mode 100644 index 0000000..3ebf1f7 --- /dev/null +++ b/AspectC++/tests/CFlowCycle/C.h @@ -0,0 +1,10 @@ +#ifndef __C_h__ +#define __C_h__ + +class C { +public: + static void f() {} +}; + + +#endif // __C_h__ diff --git a/AspectC++/tests/CFlowCycle/CFlow.ah b/AspectC++/tests/CFlowCycle/CFlow.ah new file mode 100644 index 0000000..174605b --- /dev/null +++ b/AspectC++/tests/CFlowCycle/CFlow.ah @@ -0,0 +1,19 @@ +#ifndef __CFlow_ah__ +#define __CFlow_ah__ + +#include + +#include "D.h" + +aspect CFlow { + + advice execution ("C") && cflow (execution ("A"||"B")) : around () { + printf ("executing %s\n", JoinPoint::signature ()); + D::f (); + printf ("... and D::f()\n"); + tjp->proceed (); + } + +}; + +#endif // __CFlow_ah__ diff --git a/AspectC++/tests/CFlowCycle/D.h b/AspectC++/tests/CFlowCycle/D.h new file mode 100644 index 0000000..44a2bdd --- /dev/null +++ b/AspectC++/tests/CFlowCycle/D.h @@ -0,0 +1,12 @@ +#ifndef __D_h__ +#define __D_h__ + +#include "B.h" + +class D { +public: + static void f() { B::f (); } +}; + + +#endif // __D_h__ diff --git a/AspectC++/tests/CFlowCycle/Makefile b/AspectC++/tests/CFlowCycle/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/CFlowCycle/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/CFlowCycle/feature.ref b/AspectC++/tests/CFlowCycle/feature.ref new file mode 100644 index 0000000..522d126 --- /dev/null +++ b/AspectC++/tests/CFlowCycle/feature.ref @@ -0,0 +1,7 @@ +CFlowCycle: cflow generation and cycle problem check +==================================================== +executing void C::f() +... and D::f() +now calling C::f() directly from main(): +the execution advice shall print nothing above this line +==================================================== diff --git a/AspectC++/tests/CFlowCycle/main.cc b/AspectC++/tests/CFlowCycle/main.cc new file mode 100644 index 0000000..3282a11 --- /dev/null +++ b/AspectC++/tests/CFlowCycle/main.cc @@ -0,0 +1,14 @@ +#include + +#include "D.h" +#include "A.h" + +int main() { + printf ("CFlowCycle: cflow generation and cycle problem check\n"); + printf ("====================================================\n"); + A::f (); + printf ("now calling C::f() directly from main():\n"); + C::f (); + printf ("the execution advice shall print nothing above this line\n"); + printf ("====================================================\n"); +} diff --git a/AspectC++/tests/CallAccess/Makefile b/AspectC++/tests/CallAccess/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/CallAccess/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/CallAccess/feature.ref b/AspectC++/tests/CallAccess/feature.ref new file mode 100644 index 0000000..e6038f2 --- /dev/null +++ b/AspectC++/tests/CallAccess/feature.ref @@ -0,0 +1,18 @@ +CallAccess: call advice for private or protected member fcts +============================================================ +--- f --- + External::prot() + Internal::priv() +--- g --- + External::vprot() + Internal::vprot() + Internal::priv() +--- x --- +--- friends --- + External::prot() + Internal::priv() +--- problem with static private functions (bug 485) + Internal::static_priv() + Internal::static_priv() + Internal::static_pub() +============================================================ diff --git a/AspectC++/tests/CallAccess/main.cc b/AspectC++/tests/CallAccess/main.cc new file mode 100644 index 0000000..0c63603 --- /dev/null +++ b/AspectC++/tests/CallAccess/main.cc @@ -0,0 +1,89 @@ +#include + +class External { +protected: + void prot () { printf (" External::prot()\n"); } + virtual void vprot () { printf (" External::vprot()\n");} +}; + +extern "C" { + struct DontInsertBypassTemplate {}; +} + +// --------------------------------- + +class InternalPrivateBase { +public: + void x() { printf ("--- x ---\n"); } +}; + +class Internal : private External, private InternalPrivateBase { + friend void friend_priv (Internal *obj); + friend void friend_prot (Internal *a); + friend void friend_static_stuff (); + void priv () { printf (" Internal::priv()\n");} + static void static_priv () { printf (" Internal::static_priv()\n");} + void vprot () { printf (" Internal::vprot()\n");} +public: + static void static_pub () { printf (" Internal::static_pub()\n");} + void f (); +private: + void g () { + printf ("--- g ---\n"); + External::vprot (); vprot (); priv (); + } +}; + +void Internal::f () { + printf ("--- f ---\n"); + External::prot (); priv (); g(); x(); +} + +void friend_prot (Internal *obj) { obj->prot (); } +void friend_priv (Internal *obj) { obj->priv (); } +void friend_static_stuff () { Internal::static_priv (); Internal i; i.static_priv (); i.static_pub (); } + +class Internal2 : public Internal { +protected: + virtual void vprot () {} +}; + +int main () { + printf ("CallAccess: call advice for private or protected member fcts\n"); + printf ("============================================================\n"); + Internal i; + i.f (); + printf ("--- friends ---\n"); + friend_prot (&i); + friend_priv (&i); + printf ("--- problem with static private functions (bug 485)\n"); + friend_static_stuff (); + printf ("============================================================\n"); +} + +aspect X { + advice call("% External::prot()") : around () { tjp->proceed (); } + advice call("% External::vprot()") : around () { tjp->proceed (); } + advice call("% Internal::priv()") : around () { tjp->proceed (); } + advice call("% Internal::static_p%()") : before () { } + advice call("% InternalPrivateBase::x()") : around () { tjp->proceed (); } +}; + +/* + +Possible cases: + +1. A member function calls a PROTECTED member function of a base class + => put friend declaration into the calling (derived) class +2. A friend class or function of a class A calls a PROTECTED base class + function of A + => put friend declaration in A +3. Within a class A a private member is called + => put friend declaration into A +4. A function or class is a friend and calls a PRIVATE member of class A + => put friend declaration into target class A + +The cases 3. and 4. will not be supported for external target classes +=> error message! + +*/ diff --git a/AspectC++/tests/CallAdvice/Makefile b/AspectC++/tests/CallAdvice/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/CallAdvice/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/CallAdvice/feature.ref b/AspectC++/tests/CallAdvice/feature.ref new file mode 100644 index 0000000..269f6cf --- /dev/null +++ b/AspectC++/tests/CallAdvice/feature.ref @@ -0,0 +1,134 @@ +CallAdvice: code generation for all kinds of functions +============================================================= +global initialization: +before int global() +in a global function +before int global() +in a global function +before int global() +in a global function +------------------------------------------------------------- +call to global function from local class => shall not match: +in a global function +------------------------------------------------------------- +various kinds of functions: +before C C::dup() +before C &C::operator =(const C &) +before int f2(int,int) +before int f1(int) +before C C::dup() +before C &C::operator =(const C &) +before C C::dup() +before C &C::operator =(const C &) +before int C::val() const +result is 4717 +before int f2(int,int) +before int f1(int) +before int f2(int,int) +before int f1(int) +before int f3(int,int,int) +before C C::operator !() +before C C::operator !() +before C C::operator !() +before C C::operator !() +before int C::operator +(int) +before int f1(int) +before int C::operator +(int) +before bool operator +(C,C) +before int operator ~(C) +before void C::cnst() +the non-const version +before int C::stuff(C *) +before int C::stuff(C *) +in function with class-ptr arg +before void C::cnst() const +the const function +before void testfoo::ldebug(const char *,const char *) +in ldebug +------------------------------------------------------------- +static member called: +before void C::stat(int) +in a static member +------------------------------------------------------------- +call in default arg: +before void G::f(int) +before int global() +in a global function +------------------------------------------------------------- +static member called with object: +before void C::stat(int) +in a static member +------------------------------------------------------------- +function with variable argument list: +before void var_arg_fct(const char *,...) +before void var_arg_fct(const char *,...) +------------------------------------------------------------- +calls with fully qualified name: +before void B2::f() +before void B1::f(int) +before void B1::g() +in the base function - OK +------------------------------------------------------------- +calls in const member function: +before void A::f() const +before void C::cnst() const +the const function +before void C::cnst() +the non-const version +before void A::g() +before void C::cnst() +the non-const version +before void C::cnst() +the non-const version +------------------------------------------------------------- +operator calls from within non-static methods: +before void OpTester::run() +before bool operator +(C,C) +before int operator ~(C) +before int C::operator *() +before modulo operator C operator %(const C &,const C &) +before C operator %(const C &,const C &) +before modulo operator C &C::operator %=(int) +before C &C::operator %=(int) +------------------------------------------------------------- +calls to conversion functions: +before C::operator int() +------------------------------------------------------------- +calls to operator(): +before void CallOp::operator ()() +before void CallOp::operator ()(int) +------------------------------------------------------------- +chained calls to operator->(): +before DataProxy &C::operator ->() +before Data *DataProxy::operator ->() +other chained call (bug 513): +before Cyg_Thread *Cyg_Thread::self() +before void Cyg_Thread::set_timer() +before Cyg_Thread *Cyg_Thread::self() +before void Foo::bar() +------------------------------------------------------------- +implicit conversion: +before QStream &QStream::operator <<(const QString &) + *hello* +before QStream &QStream::operator <<(const QString &) + *world* +------------------------------------------------------------- +prefix and postfix operators: +before C &C::operator ++(int) +before C &C::operator ++(int) +before C &C::operator ++() +------------------------------------------------------------- +checking index operator []: +before int C::operator [](int) const + The answer is 42! +------------------------------------------------------------- +calls with macros expansions as argument: +before bool C::operator !=(int) + operator != +before int C::operator +(int) + operator + +before int f1(int) + ordinary function +before void assert_fct() + call in macro +============================================================= diff --git a/AspectC++/tests/CallAdvice/main.cc b/AspectC++/tests/CallAdvice/main.cc new file mode 100644 index 0000000..932839d --- /dev/null +++ b/AspectC++/tests/CallAdvice/main.cc @@ -0,0 +1,291 @@ +#include + +int f1 (int a) { return a + 1; } +int f2 (int a, int) { return a + 2; } +int f3 (int a, int, int) { return a + 2; } +void var_arg_fct (const char *fmt, ...) { } + +class Foo { +public: + void bar() {} +}; + +class Cyg_Thread { + Foo foo; +public: + static Cyg_Thread *self() { return 0; } + void set_timer() { + self()->foo.bar(); // THIS FAILS with Bug 513 + } + +}; + +struct Data { + int i; +}; + +struct DataProxy { + Data d; + Data *operator ->() { return &d; } +}; + +struct QString { + const char *_s; + QString (const char*s) : _s(s) {} +}; + +struct QStream { + QStream &operator << (const QString &qs) { + static QStream stream; + printf ("%s", qs._s); + return stream; + } +}; + +class C { + int _val; + DataProxy _dp; +public: + C () : _val (4711) {} + operator int () { return _val; } + int val () const { return _val; } + C &operator = (const C &obj) { + return *this; + } + C dup () { + C duplicate; + duplicate = *this; + return duplicate; + } + C operator ! () { return *this; } + int operator + (int) { return 0; } + DataProxy &operator -> () { return _dp; } + void cnst () const { printf ("the const function\n"); } + void cnst () { printf ("the non-const version\n"); }; + static void stat (int = 0) { printf ("in a static member\n"); } + int stuff (C *pClass) { printf ("in function with class-ptr arg\n"); return 0; } + bool operator != (int) { return true; } + int operator * () { return 0; } + C& operator ++ (int) { return *this; } + C& operator ++ () { return *this; } + int operator [] (int) const { return 42; } + C& operator %= (int i) { return *this; } +}; + +C operator % (const C& c1, const C& c2) { return C(); } +bool operator + (C, C) { return false; } +int operator ~ (C) { return 0; } + +class B1 { +public: + void f (int) {} + virtual void g () { printf ("in the base function - OK\n"); } +}; + +class B2 : public B1 { +public: + void f () { B1::f (0); } + void g () { printf ("in the derived function - ERROR\n"); } +}; + +struct ABase { + C c1; + mutable C c2; +}; + +class A : public ABase { +public: + void f () const { c1.cnst (); c2.cnst (); } + void g () { c1.cnst (); c2.cnst (); } +}; + +class OpTester { +public: + void run () { + C c1, c2; + c1 + c2; + ~c1; + *c1; + c1 % c2; + c1 %= 99; + } +}; + +struct GlobalPrinter { + GlobalPrinter () { + printf ("CallAdvice: code generation for all kinds of functions\n"); + printf ("=============================================================\n"); + printf ("global initialization:\n"); + } + ~GlobalPrinter () { + printf ("=============================================================\n"); + } +} gp; + +int global () { printf ("in a global function\n"); return 42; } + +int g = global (); +namespace XX {} +namespace XX { int g = global (); } +class G { + static int g2; +public: + static void f (int i = global ()) {} +}; + +int G::g2 = global (); + +#define SOME_MACRO(x) x + +void assert_fct() {} +#define MY_ASSERT(x) assert_fct() + +class testfoo { +public: + void ldebug(const char *, const char *) { printf ("in ldebug\n"); } +}; + +// --- bug 557: +class ABC { + typedef struct { + int a; + } newtype; + +public: + int b; + +}; +// --- end bug 557 + +// --- bug 588 +class CallOp { +public: + void operator() () {} + void operator() (int) {} +} call_op; +// -- end bug 588 + +int main () { + struct Local { + static void f () { global (); } // call in local class => shall not match! + }; + printf ("-------------------------------------------------------------\n"); + printf ("call to global function from local class => shall not match:\n"); + Local::f (); + printf ("-------------------------------------------------------------\n"); + printf ("various kinds of functions:\n"); + C inst; + C inst2 (inst.dup ()); + printf ("result is %d\n", f1 (f2 (3, 4)) + inst.dup ().dup ().val ()); + f3 (f1 (f2 (5, 6)), f1 (f2 (7, 8)), 1); + !!!!inst; + inst + 0; + inst + f1 (2); + inst + inst; + ~inst; + inst.cnst (); + inst.stuff (&inst); + const C cc; + cc.cnst (); + testfoo *foo = new testfoo; + const char *s = "Hi"; + ((foo-> ldebug))("something '%s'", s); + delete foo; + printf ("-------------------------------------------------------------\n"); + printf ("static member called:\n"); + C::stat (); + printf ("-------------------------------------------------------------\n"); + printf ("call in default arg:\n"); + G::f (); + printf ("-------------------------------------------------------------\n"); + printf ("static member called with object:\n"); + inst.stat (3); + printf ("-------------------------------------------------------------\n"); + printf ("function with variable argument list:\n"); + var_arg_fct ("bla %s %d %d", "a string", 4711, true); + var_arg_fct ("bla %f", 3.14); + printf ("-------------------------------------------------------------\n"); + printf ("calls with fully qualified name:\n"); + B2 b2; + b2.f (); + b2.B1::g (); + printf ("-------------------------------------------------------------\n"); + printf ("calls in const member function:\n"); + A a; + a.f (); + a.g (); + printf ("-------------------------------------------------------------\n"); + printf ("operator calls from within non-static methods:\n"); + OpTester ot; + ot.run (); + printf ("-------------------------------------------------------------\n"); + printf ("calls to conversion functions:\n"); + C c; + int i; + i = c; + // i = (int)c; <-- this should also be affected by advice + printf ("-------------------------------------------------------------\n"); + printf ("calls to operator():\n"); + call_op(); + call_op(42); + printf ("-------------------------------------------------------------\n"); + printf ("chained calls to operator->():\n"); + C c2; + i = c2->i; + printf ("other chained call (bug 513):\n"); + Cyg_Thread::self()->set_timer(); + printf ("-------------------------------------------------------------\n"); + printf ("implicit conversion:\n"); + QStream qs; + qs << " *hello*\n" << " *world*\n"; + printf ("-------------------------------------------------------------\n"); + printf ("prefix and postfix operators:\n"); + ++c++++; + printf ("-------------------------------------------------------------\n"); + printf ("checking index operator []:\n"); + printf (" The answer is %d!\n", c[99]); + printf ("-------------------------------------------------------------\n"); + printf ("calls with macros expansions as argument:\n"); + bool b = (c != SOME_MACRO(42)); + printf (" operator !=\n"); + c + SOME_MACRO(42); + printf (" operator +\n"); + f1(SOME_MACRO(0)); + printf (" ordinary function\n"); + MY_ASSERT(b==true); + printf (" call in macro\n"); + + return 0; +} + +aspect CallTracer { + pointcut builtin_ops() = call("C &operator*(C *)") || call("int operator+(int,int)") + || call("int &operator =(int &,int)") || call("C *operator &(C &)") || call("Data *operator &(Data &)"); + advice call ("% ...::%(...)") && !call ("% printf(...)") && ! builtin_ops() : around () { + printf ("before %s", tjp->signature ()); + tjp->proceed (); + } +}; + +aspect CallTracer2 { + pointcut builtin_ops() = call("C &operator*(C *)") || call("int operator+(int,int)") + || call("int &operator =(int &,int)") || call("C *operator &(C &)") || call("Data *operator &(Data &)"); + advice call ("% ...::%(...)") && !call ("% printf(...)") && ! builtin_ops() : before () { + printf ("\n"); + } +}; + +aspect CallWithClassPtrTest { + advice call ("% %::%(C *)") : before () { + printf ("before %s\n", JoinPoint::signature ()); + } +}; + +// special treatment of operator % and operator %=: +// in a match expression we use %% and %%=, because % is our wildcard +aspect CallModuloTest { + advice call ("% ...::operator %%(...)" || + "% ...::operator %%=(...)") : before () { + printf ("before modulo operator %s\n", JoinPoint::signature ()); + } +}; diff --git a/AspectC++/tests/CallBuiltinOperator/Makefile b/AspectC++/tests/CallBuiltinOperator/Makefile new file mode 100644 index 0000000..8abc008 --- /dev/null +++ b/AspectC++/tests/CallBuiltinOperator/Makefile @@ -0,0 +1,2 @@ +ACFLAGS ?= --builtin_operators +include ../Makefile.generic diff --git a/AspectC++/tests/CallBuiltinOperator/feature.ref b/AspectC++/tests/CallBuiltinOperator/feature.ref new file mode 100644 index 0000000..0f27d3f --- /dev/null +++ b/AspectC++/tests/CallBuiltinOperator/feature.ref @@ -0,0 +1,1591 @@ + +int operator +(int,int) (Line: 186) + int Arg1 = 0 + int Arg2 = 5 + int Result = 5 + void That = nullptr + void Target = nullptr +>>>> + + + ~~~ Simple checks ~~~ + +a = 8 +b = 23 +m = 0 +n = 1 +x = 1 + +int operator +(int) (Line: 21) + int Arg1 = 8 + int Result = 8 + void That = nullptr + void Target = nullptr +>>>> 8 + +int operator -(int) (Line: 22) + int Arg1 = 8 + int Result = -8 + void That = nullptr + void Target = nullptr +>>>> -8 + +int operator +(int,int) (Line: 23) + int Arg1 = 8 + int Arg2 = 23 + int Result = 31 + void That = nullptr + void Target = nullptr +>>>> 31 + +int operator -(int,int) (Line: 24) + int Arg1 = 8 + int Arg2 = 23 + int Result = -15 + void That = nullptr + void Target = nullptr +>>>> -15 + +int operator *(int,int) (Line: 25) + int Arg1 = 8 + int Arg2 = 23 + int Result = 184 + void That = nullptr + void Target = nullptr +>>>> 184 + +int operator /(int,int) (Line: 26) + int Arg1 = 8 + int Arg2 = 23 + int Result = 0 + void That = nullptr + void Target = nullptr +>>>> 0 + +int operator %(int,int) (Line: 27) + int Arg1 = 8 + int Arg2 = 23 + int Result = 8 + void That = nullptr + void Target = nullptr +>>>> 8 + +int operator ~(int) (Line: 29) + int Arg1 = 8 + int Result = -9 + void That = nullptr + void Target = nullptr +>>>> -9 + +int operator &(int,int) (Line: 30) + int Arg1 = 8 + int Arg2 = 23 + int Result = 0 + void That = nullptr + void Target = nullptr +>>>> 0 + +int operator |(int,int) (Line: 31) + int Arg1 = 8 + int Arg2 = 23 + int Result = 31 + void That = nullptr + void Target = nullptr +>>>> 31 + +int operator ^(int,int) (Line: 32) + int Arg1 = 8 + int Arg2 = 23 + int Result = 31 + void That = nullptr + void Target = nullptr +>>>> 31 + +int operator <<(int,int) (Line: 33) + int Arg1 = 8 + int Arg2 = 23 + int Result = 67108864 + void That = nullptr + void Target = nullptr +>>>> 67108864 + +int operator >>(int,int) (Line: 34) + int Arg1 = 8 + int Arg2 = 23 + int Result = 0 + void That = nullptr + void Target = nullptr +>>>> 0 + +bool operator ==(int,int) (Line: 36) + int Arg1 = 8 + int Arg2 = 23 + bool Result = false + void That = nullptr + void Target = nullptr +>>>> 0 + +bool operator !=(int,int) (Line: 37) + int Arg1 = 8 + int Arg2 = 23 + bool Result = true + void That = nullptr + void Target = nullptr +>>>> 1 + +bool operator >=(int,int) (Line: 38) + int Arg1 = 8 + int Arg2 = 23 + bool Result = false + void That = nullptr + void Target = nullptr +>>>> 0 + +bool operator <=(int,int) (Line: 39) + int Arg1 = 8 + int Arg2 = 23 + bool Result = true + void That = nullptr + void Target = nullptr +>>>> 1 + +bool operator <(int,int) (Line: 40) + int Arg1 = 8 + int Arg2 = 23 + bool Result = true + void That = nullptr + void Target = nullptr +>>>> 1 + +bool operator >(int,int) (Line: 41) + int Arg1 = 8 + int Arg2 = 23 + bool Result = false + void That = nullptr + void Target = nullptr +>>>> 0 + +bool operator !(bool) (Line: 43) + bool Arg1 = false + bool Result = true + void That = nullptr + void Target = nullptr +>>>> 1 + +> +bool operator &&(bool,bool) (Line: 44) + const bool Arg1 = false + bool Arg2 = + bool Result = false + void That = nullptr + void Target = nullptr +>>>> 0 + + +bool operator ||(bool,bool) (Line: 45) + const bool Arg1 = false + bool Arg2 = true + bool Result = true + void That = nullptr + void Target = nullptr +>>>> 1 + +int &operator =(int &,int) (Line: 47) + int & Arg1 = 1 + int Arg2 = 8 + int * const Result = ptr<8> + void That = nullptr + void Target = nullptr +>>>> 8 +Var: 8 + +int &operator +=(int &,int) (Line: 50) + int & Arg1 = 8 + int Arg2 = 23 + int * const Result = ptr<31> + void That = nullptr + void Target = nullptr +>>>> 31 +Var: 31 + +int &operator -=(int &,int) (Line: 52) + int & Arg1 = 31 + int Arg2 = 8 + int * const Result = ptr<23> + void That = nullptr + void Target = nullptr +>>>> 23 +Var: 23 + +int &operator *=(int &,int) (Line: 54) + int & Arg1 = 23 + int Arg2 = 23 + int * const Result = ptr<529> + void That = nullptr + void Target = nullptr +>>>> 529 +Var: 529 + +int &operator /=(int &,int) (Line: 56) + int & Arg1 = 529 + int Arg2 = 8 + int * const Result = ptr<66> + void That = nullptr + void Target = nullptr +>>>> 66 +Var: 66 + +int &operator %=(int &,int) (Line: 58) + int & Arg1 = 66 + int Arg2 = 23 + int * const Result = ptr<20> + void That = nullptr + void Target = nullptr +>>>> 20 +Var: 20 + +int &operator &=(int &,int) (Line: 60) + int & Arg1 = 20 + int Arg2 = 23 + int * const Result = ptr<20> + void That = nullptr + void Target = nullptr +>>>> 20 +Var: 20 + +int &operator |=(int &,int) (Line: 62) + int & Arg1 = 20 + int Arg2 = 8 + int * const Result = ptr<28> + void That = nullptr + void Target = nullptr +>>>> 28 +Var: 28 + +int &operator ^=(int &,int) (Line: 64) + int & Arg1 = 28 + int Arg2 = 23 + int * const Result = ptr<11> + void That = nullptr + void Target = nullptr +>>>> 11 +Var: 11 + +int &operator <<=(int &,int) (Line: 66) + int & Arg1 = 11 + int Arg2 = 8 + int * const Result = ptr<2816> + void That = nullptr + void Target = nullptr +>>>> 2816 +Var: 2816 + +int &operator >>=(int &,int) (Line: 68) + int & Arg1 = 2816 + int Arg2 = 23 + int * const Result = ptr<0> + void That = nullptr + void Target = nullptr +>>>> 0 +Var: 0 + +int operator ++(int &,int) (Line: 71) + int & Arg1 = 0 + int Arg2 = 0 + int Result = 0 + void That = nullptr + void Target = nullptr +>>>> 0 +Var: 1 + +int operator --(int &,int) (Line: 73) + int & Arg1 = 1 + int Arg2 = 0 + int Result = 1 + void That = nullptr + void Target = nullptr +>>>> 1 +Var: 0 + +int &operator --(int &) (Line: 75) + int & Arg1 = 0 + int * const Result = ptr<-1> + void That = nullptr + void Target = nullptr +>>>> -1 +Var: -1 + +int &operator ++(int &) (Line: 77) + int & Arg1 = -1 + int * const Result = ptr<0> + void That = nullptr + void Target = nullptr +>>>> 0 +Var: 0 + +int &operator *(int *) (Line: 81) + int * Arg1 = ptr<13> + int * Result = ptr<13> + void That = nullptr + void Target = nullptr +>>>> 13 + +int &operator [](int *,int) (Line: 82) + int * const Arg1 = ptr<13> + int Arg2 = 3 + int * const Result = ptr<43> + void That = nullptr + void Target = nullptr +>>>> 43 + +int &operator [](int *,unsigned int) (Line: 83) + int * const Arg1 = ptr<13> + unsigned int Arg2 = 1 + int * const Result = ptr<23> + void That = nullptr + void Target = nullptr +>>>> 23 +8 + + +int &operator ?:(bool,int &,int &) (Line: 86) + const bool Arg1 = false + int & Arg2 = + int & Arg3 = 23 + int * Result = ptr<23> + void That = nullptr + void Target = nullptr +>>>> 23 + + +int &operator ?:(bool,int &,int &) (Line: 87) + const bool Arg1 = true + int & Arg2 = 8 + int & Arg3 = + int * Result = ptr<8> + void That = nullptr + void Target = nullptr +>>>> 8 + + + + ~~~ Complex checks ~~~ + + +int operator +(int,int) (Line: 199) + int Arg1 = 1 + int Arg2 = 4 + int Result = 5 + void That = nullptr + void Target = nullptr +>>>> +int &operator =(int &,int) (Line: 199) + int & Arg1 = 32767 + int Arg2 = 5 + int * const Result = ptr<5> + void That = nullptr + void Target = nullptr +>>>> +void (**operator &(void (*&)()))() (Line: 210) + void (*&)() Arg1 = fptr + void (**)() Result = ptr> + void That = nullptr + void Target = nullptr +>>>> +void (*&operator [](void (**)(),int))() (Line: 211) + void (** const)() Arg1 = ptr> + int Arg2 = 0 + void (** const)() Result = ptr> + void That = nullptr + void Target = nullptr +>>>> +void (&operator *(void (*)(int)))(int) (Line: 214) + void (*)(int) Arg1 = fptr + void (*)(int) Result = fptr + void That = nullptr + void Target = nullptr +>>>> +bool operator !=(int,int) (Line: 96) + int Arg1 = 1 + int Arg2 = 0 + bool Result = true + void That = nullptr + void Target = nullptr +>>>> + +int operator ?:(bool,int,int) (Line: 96) + const bool Arg1 = true + int Arg2 = 3 + int Arg3 = + int Result = 3 + void That = nullptr + void Target = nullptr +>>>> +int &operator =(int &,int) (Line: 96) + int & Arg1 = 0 + int Arg2 = 3 + int * const Result = ptr<3> + void That = nullptr + void Target = nullptr +>>>> +~~~TestClass init >>> +int &operator =(int &,int) (Line: 113) + int & Arg1 = 424242 + int Arg2 = 3 + int * const Result = ptr<3> + TestClass That = + void Target = nullptr +>>>> + +bool operator &&(bool,bool) (Line: 115) + const bool Arg1 = true + bool Arg2 = false + bool Result = false + TestClass That = + void Target = nullptr +>>>> + +int operator ?:(bool,int,int) (Line: 115) + const bool Arg1 = false + int Arg2 = + int Arg3 = 5 + int Result = 5 + TestClass That = + void Target = nullptr +>>>> +int &operator =(int &,int) (Line: 115) + int & Arg1 = 422142 + int Arg2 = 5 + int * const Result = ptr<5> + TestClass That = + void Target = nullptr +>>>> +const int *operator &(const int &) (Line: 118) + const int & Arg1 = 3 + const int * Result = ptr<3> + TestClass That = + void Target = nullptr +>>>> +int &operator =(int &,int) (Line: 119) + int & Arg1 = 212121 + int Arg2 = 1 + int * const Result = ptr<1> + TestClass That = + void Target = nullptr +>>>> +int &operator =(int &,int) (Line: 124) + int & Arg1 = 214221 + int Arg2 = 4 + int * const Result = ptr<4> + TestClass That = + void Target = nullptr +>>>> +int operator +(int,int) (Line: 125) + int Arg1 = 4 + int Arg2 = 21 + int Result = 25 + TestClass That = + void Target = nullptr +>>>> +int &operator =(int &,int) (Line: 125) + int & Arg1 = 4 + int Arg2 = 25 + int * const Result = ptr<25> + TestClass That = + void Target = nullptr +>>>> +int operator ++(int &,int) (Line: 126) + int & Arg1 = 0 + int Arg2 = 0 + int Result = 0 + TestClass That = + void Target = nullptr +>>>> +bool operator <(int,int) (Line: 126) + int Arg1 = 0 + int Arg2 = 10 + bool Result = true + TestClass That = + void Target = nullptr +>>>> +int &operator --(int &) (Line: 127) + int & Arg1 = 1 + int * const Result = ptr<0> + TestClass That = + void Target = nullptr +>>>> +int operator ++(int &,int) (Line: 129) + int & Arg1 = 0 + int Arg2 = 0 + int Result = 0 + TestClass That = + void Target = nullptr +>>>> +bool operator >(int,int) (Line: 129) + int Arg1 = 10 + int Arg2 = 0 + bool Result = true + TestClass That = + void Target = nullptr +>>>> +int operator --(int &,int) (Line: 130) + int & Arg1 = 1 + int Arg2 = 0 + int Result = 1 + TestClass That = + void Target = nullptr +>>>> +TestClass *&operator =(TestClass *&,TestClass *) (Line: 132) + TestClass *& Arg1 = nullptr + TestClass * Arg2 = nullptr + TestClass ** const Result = ptr + TestClass That = + void Target = nullptr +>>>> +void (*&operator =(void (*&)(int),void (*)(int)))(int) (Line: 133) + void (*&)(int) Arg1 = nullfptr + void (*)(int) Arg2 = fptr + void (** const)(int) Result = ptr> + TestClass That = + void Target = nullptr +>>>> +~~~TestClass init <<< +TestClass *TestClass::*&operator =(TestClass *TestClass::*&,TestClass *TestClass::*) (Line: 217) + TestClass * TestClass::*& Arg1 = memptr + TestClass * TestClass::* Arg2 = memptr + TestClass * TestClass::** const Result = ptr> + void That = nullptr + void Target = nullptr +>>>> +TestClass *&operator .*(TestClass &,TestClass *TestClass::*) (Line: 218) + TestClass & Arg1 = + TestClass * TestClass::* Arg2 = memptr + TestClass ** Result = ptr + void That = nullptr + void Target = nullptr +>>>> +TestClass *operator &(TestClass &) (Line: 219) + TestClass & Arg1 = + TestClass * Result = objptr<{TestClass}> + void That = nullptr + void Target = nullptr +>>>> +TestClass *&operator ->*(TestClass *,TestClass *TestClass::*) (Line: 219) + TestClass * Arg1 = objptr<{TestClass}> + TestClass * TestClass::* Arg2 = memptr + TestClass ** Result = ptr + void That = nullptr + void Target = nullptr +>>>> +TestClass *&operator =(TestClass *&,TestClass *) (Line: 219) + TestClass *& Arg1 = nullptr + TestClass * Arg2 = nullptr + TestClass ** const Result = ptr + void That = nullptr + void Target = nullptr +>>>> +~~~TestClass init >>> +int &operator =(int &,int) (Line: 113) + int & Arg1 = 424242 + int Arg2 = 3 + int * const Result = ptr<3> + TestClass That = + void Target = nullptr +>>>> + +bool operator &&(bool,bool) (Line: 115) + const bool Arg1 = true + bool Arg2 = false + bool Result = false + TestClass That = + void Target = nullptr +>>>> + +int operator ?:(bool,int,int) (Line: 115) + const bool Arg1 = false + int Arg2 = + int Arg3 = 5 + int Result = 5 + TestClass That = + void Target = nullptr +>>>> +int &operator =(int &,int) (Line: 115) + int & Arg1 = 422142 + int Arg2 = 5 + int * const Result = ptr<5> + TestClass That = + void Target = nullptr +>>>> +const int *operator &(const int &) (Line: 118) + const int & Arg1 = 3 + const int * Result = ptr<3> + TestClass That = + void Target = nullptr +>>>> +int &operator =(int &,int) (Line: 119) + int & Arg1 = 212121 + int Arg2 = 1 + int * const Result = ptr<1> + TestClass That = + void Target = nullptr +>>>> +int &operator =(int &,int) (Line: 124) + int & Arg1 = 214221 + int Arg2 = 4 + int * const Result = ptr<4> + TestClass That = + void Target = nullptr +>>>> +int operator +(int,int) (Line: 125) + int Arg1 = 4 + int Arg2 = 21 + int Result = 25 + TestClass That = + void Target = nullptr +>>>> +int &operator =(int &,int) (Line: 125) + int & Arg1 = 4 + int Arg2 = 25 + int * const Result = ptr<25> + TestClass That = + void Target = nullptr +>>>> +int operator ++(int &,int) (Line: 126) + int & Arg1 = 0 + int Arg2 = 0 + int Result = 0 + TestClass That = + void Target = nullptr +>>>> +bool operator <(int,int) (Line: 126) + int Arg1 = 0 + int Arg2 = 10 + bool Result = true + TestClass That = + void Target = nullptr +>>>> +int &operator --(int &) (Line: 127) + int & Arg1 = 1 + int * const Result = ptr<0> + TestClass That = + void Target = nullptr +>>>> +int operator ++(int &,int) (Line: 129) + int & Arg1 = 0 + int Arg2 = 0 + int Result = 0 + TestClass That = + void Target = nullptr +>>>> +bool operator >(int,int) (Line: 129) + int Arg1 = 10 + int Arg2 = 0 + bool Result = true + TestClass That = + void Target = nullptr +>>>> +int operator --(int &,int) (Line: 130) + int & Arg1 = 1 + int Arg2 = 0 + int Result = 1 + TestClass That = + void Target = nullptr +>>>> +TestClass *&operator =(TestClass *&,TestClass *) (Line: 132) + TestClass *& Arg1 = nullptr + TestClass * Arg2 = nullptr + TestClass ** const Result = ptr + TestClass That = + void Target = nullptr +>>>> +void (*&operator =(void (*&)(int),void (*)(int)))(int) (Line: 133) + void (*&)(int) Arg1 = nullfptr + void (*)(int) Arg2 = fptr + void (** const)(int) Result = ptr> + TestClass That = + void Target = nullptr +>>>> +~~~TestClass init <<< +int TestClass::*&operator =(int TestClass::*&,int TestClass::*) (Line: 223) + int TestClass::*& Arg1 = memptr + int TestClass::* Arg2 = memptr + int TestClass::** const Result = ptr> + void That = nullptr + void Target = nullptr +>>>> +int &operator .*(TestClass &,int TestClass::*) (Line: 224) + TestClass & Arg1 = + int TestClass::* Arg2 = memptr + int * Result = ptr<3> + void That = nullptr + void Target = nullptr +>>>> +TestClass *operator &(TestClass &) (Line: 225) + TestClass & Arg1 = + TestClass * Result = objptr<{TestClass}> + void That = nullptr + void Target = nullptr +>>>> +int &operator ->*(TestClass *,int TestClass::*) (Line: 225) + TestClass * Arg1 = objptr<{TestClass}> + int TestClass::* Arg2 = memptr + int * Result = ptr<3> + void That = nullptr + void Target = nullptr +>>>> +int &operator =(int &,int) (Line: 225) + int & Arg1 = 3 + int Arg2 = 3 + int * const Result = ptr<3> + void That = nullptr + void Target = nullptr +>>>> +Begin: Obj-Copy-Test +~~~TestClass init >>> +int &operator =(int &,int) (Line: 113) + int & Arg1 = 424242 + int Arg2 = 3 + int * const Result = ptr<3> + TestClass That = + void Target = nullptr +>>>> + +bool operator &&(bool,bool) (Line: 115) + const bool Arg1 = true + bool Arg2 = false + bool Result = false + TestClass That = + void Target = nullptr +>>>> + +int operator ?:(bool,int,int) (Line: 115) + const bool Arg1 = false + int Arg2 = + int Arg3 = 5 + int Result = 5 + TestClass That = + void Target = nullptr +>>>> +int &operator =(int &,int) (Line: 115) + int & Arg1 = 422142 + int Arg2 = 5 + int * const Result = ptr<5> + TestClass That = + void Target = nullptr +>>>> +const int *operator &(const int &) (Line: 118) + const int & Arg1 = 3 + const int * Result = ptr<3> + TestClass That = + void Target = nullptr +>>>> +int &operator =(int &,int) (Line: 119) + int & Arg1 = 212121 + int Arg2 = 1 + int * const Result = ptr<1> + TestClass That = + void Target = nullptr +>>>> +int &operator =(int &,int) (Line: 124) + int & Arg1 = 214221 + int Arg2 = 4 + int * const Result = ptr<4> + TestClass That = + void Target = nullptr +>>>> +int operator +(int,int) (Line: 125) + int Arg1 = 4 + int Arg2 = 21 + int Result = 25 + TestClass That = + void Target = nullptr +>>>> +int &operator =(int &,int) (Line: 125) + int & Arg1 = 4 + int Arg2 = 25 + int * const Result = ptr<25> + TestClass That = + void Target = nullptr +>>>> +int operator ++(int &,int) (Line: 126) + int & Arg1 = 0 + int Arg2 = 0 + int Result = 0 + TestClass That = + void Target = nullptr +>>>> +bool operator <(int,int) (Line: 126) + int Arg1 = 0 + int Arg2 = 10 + bool Result = true + TestClass That = + void Target = nullptr +>>>> +int &operator --(int &) (Line: 127) + int & Arg1 = 1 + int * const Result = ptr<0> + TestClass That = + void Target = nullptr +>>>> +int operator ++(int &,int) (Line: 129) + int & Arg1 = 0 + int Arg2 = 0 + int Result = 0 + TestClass That = + void Target = nullptr +>>>> +bool operator >(int,int) (Line: 129) + int Arg1 = 10 + int Arg2 = 0 + bool Result = true + TestClass That = + void Target = nullptr +>>>> +int operator --(int &,int) (Line: 130) + int & Arg1 = 1 + int Arg2 = 0 + int Result = 1 + TestClass That = + void Target = nullptr +>>>> +TestClass *&operator =(TestClass *&,TestClass *) (Line: 132) + TestClass *& Arg1 = nullptr + TestClass * Arg2 = nullptr + TestClass ** const Result = ptr + TestClass That = + void Target = nullptr +>>>> +void (*&operator =(void (*&)(int),void (*)(int)))(int) (Line: 133) + void (*&)(int) Arg1 = nullfptr + void (*)(int) Arg2 = fptr + void (** const)(int) Result = ptr> + TestClass That = + void Target = nullptr +>>>> +~~~TestClass init <<< +TestClass &operator *(TestClass *) (Line: 167) + TestClass * Arg1 = objptr<{TestClass}> + TestClass * Result = objptr<{TestClass}> + void That = nullptr + void Target = nullptr +>>>> +~~~TestClass init >>> +~~~TestClass init <<< +TestClass *&operator =(TestClass *&,TestClass *) (Line: 167) + TestClass *& Arg1 = nullptr + TestClass * Arg2 = objptr<{TestClass}> + TestClass ** const Result = ptr> + void That = nullptr + void Target = nullptr +>>>> +~~~TestClass init >>> +int &operator =(int &,int) (Line: 113) + int & Arg1 = 424242 + int Arg2 = 3 + int * const Result = ptr<3> + TestClass That = + void Target = nullptr +>>>> + +bool operator &&(bool,bool) (Line: 115) + const bool Arg1 = true + bool Arg2 = false + bool Result = false + TestClass That = + void Target = nullptr +>>>> + +int operator ?:(bool,int,int) (Line: 115) + const bool Arg1 = false + int Arg2 = + int Arg3 = 5 + int Result = 5 + TestClass That = + void Target = nullptr +>>>> +int &operator =(int &,int) (Line: 115) + int & Arg1 = 422142 + int Arg2 = 5 + int * const Result = ptr<5> + TestClass That = + void Target = nullptr +>>>> +const int *operator &(const int &) (Line: 118) + const int & Arg1 = 3 + const int * Result = ptr<3> + TestClass That = + void Target = nullptr +>>>> +int &operator =(int &,int) (Line: 119) + int & Arg1 = 212121 + int Arg2 = 1 + int * const Result = ptr<1> + TestClass That = + void Target = nullptr +>>>> +int &operator =(int &,int) (Line: 124) + int & Arg1 = 214221 + int Arg2 = 4 + int * const Result = ptr<4> + TestClass That = + void Target = nullptr +>>>> +int operator +(int,int) (Line: 125) + int Arg1 = 4 + int Arg2 = 21 + int Result = 25 + TestClass That = + void Target = nullptr +>>>> +int &operator =(int &,int) (Line: 125) + int & Arg1 = 4 + int Arg2 = 25 + int * const Result = ptr<25> + TestClass That = + void Target = nullptr +>>>> +int operator ++(int &,int) (Line: 126) + int & Arg1 = 0 + int Arg2 = 0 + int Result = 0 + TestClass That = + void Target = nullptr +>>>> +bool operator <(int,int) (Line: 126) + int Arg1 = 0 + int Arg2 = 10 + bool Result = true + TestClass That = + void Target = nullptr +>>>> +int &operator --(int &) (Line: 127) + int & Arg1 = 1 + int * const Result = ptr<0> + TestClass That = + void Target = nullptr +>>>> +int operator ++(int &,int) (Line: 129) + int & Arg1 = 0 + int Arg2 = 0 + int Result = 0 + TestClass That = + void Target = nullptr +>>>> +bool operator >(int,int) (Line: 129) + int Arg1 = 10 + int Arg2 = 0 + bool Result = true + TestClass That = + void Target = nullptr +>>>> +int operator --(int &,int) (Line: 130) + int & Arg1 = 1 + int Arg2 = 0 + int Result = 1 + TestClass That = + void Target = nullptr +>>>> +TestClass *&operator =(TestClass *&,TestClass *) (Line: 132) + TestClass *& Arg1 = nullptr + TestClass * Arg2 = nullptr + TestClass ** const Result = ptr + TestClass That = + void Target = nullptr +>>>> +void (*&operator =(void (*&)(int),void (*)(int)))(int) (Line: 133) + void (*&)(int) Arg1 = nullfptr + void (*)(int) Arg2 = fptr + void (** const)(int) Result = ptr> + TestClass That = + void Target = nullptr +>>>> +~~~TestClass init <<< +~~~TestClass init >>> +int &operator =(int &,int) (Line: 113) + int & Arg1 = 424242 + int Arg2 = 3 + int * const Result = ptr<3> + TestClass That = + void Target = nullptr +>>>> + +bool operator &&(bool,bool) (Line: 115) + const bool Arg1 = true + bool Arg2 = false + bool Result = false + TestClass That = + void Target = nullptr +>>>> + +int operator ?:(bool,int,int) (Line: 115) + const bool Arg1 = false + int Arg2 = + int Arg3 = 5 + int Result = 5 + TestClass That = + void Target = nullptr +>>>> +int &operator =(int &,int) (Line: 115) + int & Arg1 = 422142 + int Arg2 = 5 + int * const Result = ptr<5> + TestClass That = + void Target = nullptr +>>>> +const int *operator &(const int &) (Line: 118) + const int & Arg1 = 3 + const int * Result = ptr<3> + TestClass That = + void Target = nullptr +>>>> +int &operator =(int &,int) (Line: 119) + int & Arg1 = 212121 + int Arg2 = 1 + int * const Result = ptr<1> + TestClass That = + void Target = nullptr +>>>> +int &operator =(int &,int) (Line: 124) + int & Arg1 = 214221 + int Arg2 = 4 + int * const Result = ptr<4> + TestClass That = + void Target = nullptr +>>>> +int operator +(int,int) (Line: 125) + int Arg1 = 4 + int Arg2 = 21 + int Result = 25 + TestClass That = + void Target = nullptr +>>>> +int &operator =(int &,int) (Line: 125) + int & Arg1 = 4 + int Arg2 = 25 + int * const Result = ptr<25> + TestClass That = + void Target = nullptr +>>>> +int operator ++(int &,int) (Line: 126) + int & Arg1 = 0 + int Arg2 = 0 + int Result = 0 + TestClass That = + void Target = nullptr +>>>> +bool operator <(int,int) (Line: 126) + int Arg1 = 0 + int Arg2 = 10 + bool Result = true + TestClass That = + void Target = nullptr +>>>> +int &operator --(int &) (Line: 127) + int & Arg1 = 1 + int * const Result = ptr<0> + TestClass That = + void Target = nullptr +>>>> +int operator ++(int &,int) (Line: 129) + int & Arg1 = 0 + int Arg2 = 0 + int Result = 0 + TestClass That = + void Target = nullptr +>>>> +bool operator >(int,int) (Line: 129) + int Arg1 = 10 + int Arg2 = 0 + bool Result = true + TestClass That = + void Target = nullptr +>>>> +int operator --(int &,int) (Line: 130) + int & Arg1 = 1 + int Arg2 = 0 + int Result = 1 + TestClass That = + void Target = nullptr +>>>> +TestClass *&operator =(TestClass *&,TestClass *) (Line: 132) + TestClass *& Arg1 = nullptr + TestClass * Arg2 = nullptr + TestClass ** const Result = ptr + TestClass That = + void Target = nullptr +>>>> +void (*&operator =(void (*&)(int),void (*)(int)))(int) (Line: 133) + void (*&)(int) Arg1 = nullfptr + void (*)(int) Arg2 = fptr + void (** const)(int) Result = ptr> + TestClass That = + void Target = nullptr +>>>> +~~~TestClass init <<< +~~~TestClass init >>> +~~~TestClass init <<< +~~~TestClass init >>> +~~~TestClass init <<< +~~~TestClass init >>> +int &operator =(int &,int) (Line: 113) + int & Arg1 = 424242 + int Arg2 = 3 + int * const Result = ptr<3> + TestClass That = + void Target = nullptr +>>>> + +bool operator &&(bool,bool) (Line: 115) + const bool Arg1 = true + bool Arg2 = false + bool Result = false + TestClass That = + void Target = nullptr +>>>> + +int operator ?:(bool,int,int) (Line: 115) + const bool Arg1 = false + int Arg2 = + int Arg3 = 5 + int Result = 5 + TestClass That = + void Target = nullptr +>>>> +int &operator =(int &,int) (Line: 115) + int & Arg1 = 422142 + int Arg2 = 5 + int * const Result = ptr<5> + TestClass That = + void Target = nullptr +>>>> +const int *operator &(const int &) (Line: 118) + const int & Arg1 = 3 + const int * Result = ptr<3> + TestClass That = + void Target = nullptr +>>>> +int &operator =(int &,int) (Line: 119) + int & Arg1 = 212121 + int Arg2 = 1 + int * const Result = ptr<1> + TestClass That = + void Target = nullptr +>>>> +int &operator =(int &,int) (Line: 124) + int & Arg1 = 214221 + int Arg2 = 4 + int * const Result = ptr<4> + TestClass That = + void Target = nullptr +>>>> +int operator +(int,int) (Line: 125) + int Arg1 = 4 + int Arg2 = 21 + int Result = 25 + TestClass That = + void Target = nullptr +>>>> +int &operator =(int &,int) (Line: 125) + int & Arg1 = 4 + int Arg2 = 25 + int * const Result = ptr<25> + TestClass That = + void Target = nullptr +>>>> +int operator ++(int &,int) (Line: 126) + int & Arg1 = 0 + int Arg2 = 0 + int Result = 0 + TestClass That = + void Target = nullptr +>>>> +bool operator <(int,int) (Line: 126) + int Arg1 = 0 + int Arg2 = 10 + bool Result = true + TestClass That = + void Target = nullptr +>>>> +int &operator --(int &) (Line: 127) + int & Arg1 = 1 + int * const Result = ptr<0> + TestClass That = + void Target = nullptr +>>>> +int operator ++(int &,int) (Line: 129) + int & Arg1 = 0 + int Arg2 = 0 + int Result = 0 + TestClass That = + void Target = nullptr +>>>> +bool operator >(int,int) (Line: 129) + int Arg1 = 10 + int Arg2 = 0 + bool Result = true + TestClass That = + void Target = nullptr +>>>> +int operator --(int &,int) (Line: 130) + int & Arg1 = 1 + int Arg2 = 0 + int Result = 1 + TestClass That = + void Target = nullptr +>>>> +TestClass *&operator =(TestClass *&,TestClass *) (Line: 132) + TestClass *& Arg1 = nullptr + TestClass * Arg2 = nullptr + TestClass ** const Result = ptr + TestClass That = + void Target = nullptr +>>>> +void (*&operator =(void (*&)(int),void (*)(int)))(int) (Line: 133) + void (*&)(int) Arg1 = nullfptr + void (*)(int) Arg2 = fptr + void (** const)(int) Result = ptr> + TestClass That = + void Target = nullptr +>>>> +~~~TestClass init <<< +End: Obj-Copy-Test +void (&operator *(void (*)(int)))(int) (Line: 139) + void (*)(int) Arg1 = fptr + void (*)(int) Result = fptr + TestClass That = + void Target = nullptr +>>>> +bool operator !=(int,int) (Line: 96) + int Arg1 = 1 + int Arg2 = 0 + bool Result = true + void That = nullptr + void Target = nullptr +>>>> + +int operator ?:(bool,int,int) (Line: 96) + const bool Arg1 = true + int Arg2 = 3 + int Arg3 = + int Result = 3 + void That = nullptr + void Target = nullptr +>>>> +int &operator =(int &,int) (Line: 96) + int & Arg1 = 0 + int Arg2 = 3 + int * const Result = ptr<3> + void That = nullptr + void Target = nullptr +>>>> +void (&operator *(void (*)(int)))(int) (Line: 140) + void (*)(int) Arg1 = fptr + void (*)(int) Result = fptr + TestClass That = + void Target = nullptr +>>>> +bool operator !=(int,int) (Line: 96) + int Arg1 = 1 + int Arg2 = 0 + bool Result = true + void That = nullptr + void Target = nullptr +>>>> + +int operator ?:(bool,int,int) (Line: 96) + const bool Arg1 = true + int Arg2 = 3 + int Arg3 = + int Result = 3 + void That = nullptr + void Target = nullptr +>>>> +int &operator =(int &,int) (Line: 96) + int & Arg1 = 0 + int Arg2 = 3 + int * const Result = ptr<3> + void That = nullptr + void Target = nullptr +>>>> +int &operator [](int *,int) (Line: 142) + int * const Arg1 = ptr<0> + int Arg2 = 5 + int * const Result = ptr<0> + TestClass That = + void Target = nullptr +>>>> + +bool operator &&(bool,bool) (Line: 146) + const bool Arg1 = true + bool Arg2 = false + bool Result = false + TestClass That = + void Target = nullptr +>>>> +> +bool operator &&(bool,bool) (Line: 147) + const bool Arg1 = false + bool Arg2 = + bool Result = false + TestClass That = + void Target = nullptr +>>>> +bool &operator =(bool &,bool) (Line: 147) + bool & Arg1 = false + bool Arg2 = false + bool * const Result = ptr + TestClass That = + void Target = nullptr +>>>> +> +bool operator ||(bool,bool) (Line: 148) + const bool Arg1 = true + bool Arg2 = + bool Result = true + TestClass That = + void Target = nullptr +>>>> +bool &operator =(bool &,bool) (Line: 148) + bool & Arg1 = false + bool Arg2 = true + bool * const Result = ptr + TestClass That = + void Target = nullptr +>>>> + +bool operator ||(bool,bool) (Line: 149) + const bool Arg1 = false + bool Arg2 = true + bool Result = true + TestClass That = + void Target = nullptr +>>>> +bool &operator =(bool &,bool) (Line: 149) + bool & Arg1 = true + bool Arg2 = true + bool * const Result = ptr + TestClass That = + void Target = nullptr +>>>> + +int &operator ?:(bool,int &,int &) (Line: 151) + const bool Arg1 = true + int & Arg2 = -1 + int & Arg3 = + int * Result = ptr<-1> + TestClass That = + void Target = nullptr +>>>> +bool operator !(bool) (Line: 152) + bool Arg1 = true + bool Result = false + TestClass That = + void Target = nullptr +>>>> + +int &operator ?:(bool,int &,int &) (Line: 152) + const bool Arg1 = false + int & Arg2 = + int & Arg3 = 3 + int * Result = ptr<3> + TestClass That = + void Target = nullptr +>>>> +int &operator =(int &,int) (Line: 152) + int & Arg1 = -1 + int Arg2 = 3 + int * const Result = ptr<3> + TestClass That = + void Target = nullptr +>>>> +~~~TestClass init >>> +~~~TestClass init <<< +>> +~~~TestClass init << +TestClass operator ?:(bool,TestClass,TestClass) (Line: 153) + const bool Arg1 = true + TestClass Arg2 = + TestClass Arg3 = + +~~~TestClass init >>> +~~~TestClass init <<< TestClass Result = + TestClass That = + void Target = nullptr +>>>> +~~~TestClass init >>> +~~~TestClass init <<< +~~~TestClass init >>> +~~~TestClass init <<< +~~~TestClass init >>> +~~~TestClass init <<< + +TestClass &operator ?:(bool,TestClass &,TestClass &) (Line: 155) + const bool Arg1 = true + TestClass & Arg2 = + TestClass & Arg3 = + TestClass * Result = objptr<{TestClass}> + TestClass That = + void Target = nullptr +>>>> +~~~TestClass init >>> +~~~TestClass init <<< + +TestClass *operator ?:(bool,TestClass *,TestClass *) (Line: 156) + const bool Arg1 = true + TestClass * Arg2 = objptr<{TestClass}> + TestClass * Arg3 = + TestClass * Result = objptr<{TestClass}> + TestClass That = + void Target = nullptr +>>>> +TestClass *operator &(TestClass &) (Line: 232) + TestClass & Arg1 = + TestClass * Result = objptr<{TestClass}> + void That = nullptr + void Target = nullptr +>>>> + +void *operator ?:(bool,void *,void *) (Line: 232) + const bool Arg1 = false + void * Arg2 = + void * Arg3 = ptr + void * Result = ptr + void That = nullptr + void Target = nullptr +>>>> +int *operator &(int &) (Line: 232) + int & Arg1 = 3 + int * Result = ptr<3> + void That = nullptr + void Target = nullptr +>>>> +bool operator !=(void *,void *) (Line: 232) + void * Arg1 = ptr + void * Arg2 = ptr + bool Result = true + void That = nullptr + void Target = nullptr +>>>> + +bool operator &&(bool,bool) (Line: 234) + const bool Arg1 = true + bool Arg2 = true + bool Result = true + void That = nullptr + void Target = nullptr +>>>> +TestClass *operator &(TestClass &) (Line: 234) + TestClass & Arg1 = + TestClass * Result = objptr<{TestClass}> + void That = nullptr + void Target = nullptr +>>>> + +bool operator &&(bool,bool) (Line: 234) + const bool Arg1 = true + bool Arg2 = true + bool Result = true + void That = nullptr + void Target = nullptr +>>>> hello + + +int operator ?:(bool,int,int) (Line: 235) + const bool Arg1 = true + int Arg2 = 4 + int Arg3 = + int Result = 4 + void That = nullptr + void Target = nullptr +>>>> +int *operator &(int &) (Line: 237) + int & Arg1 = 4 + int * Result = ptr<4> + void That = nullptr + void Target = nullptr +>>>> +int *&operator =(int *&,int *) (Line: 237) + int *& Arg1 = nullptr + int * Arg2 = ptr<4> + int ** const Result = ptr> + void That = nullptr + void Target = nullptr +>>>> +int &operator *(int *) (Line: 237) + int * Arg1 = ptr<4> + int * Result = ptr<4> + void That = nullptr + void Target = nullptr +>>>> +int *operator &(int &) (Line: 240) + int & Arg1 = 1 + int * Result = ptr<1> + void That = nullptr + void Target = nullptr +>>>> +int *&operator =(int *&,int *) (Line: 240) + int *& Arg1 = nullptr + int * Arg2 = ptr<1> + int ** const Result = ptr> + void That = nullptr + void Target = nullptr +>>>> +int &operator *(int *) (Line: 240) + int * Arg1 = ptr<1> + int * Result = ptr<1> + void That = nullptr + void Target = nullptr +>>>> +int *operator &(int &) (Line: 246) + int & Arg1 = 3 + int * Result = ptr<3> + void That = nullptr + void Target = nullptr +>>>> +int &operator *(int *) (Line: 246) + int * Arg1 = ptr<3> + int * Result = ptr<3> + void That = nullptr + void Target = nullptr +>>>> +int &operator *(int *) (Line: 246) + int * Arg1 = ptr<7> + int * Result = ptr<7> + void That = nullptr + void Target = nullptr +>>>> +int operator +(int,int) (Line: 246) + int Arg1 = 7 + int Arg2 = 3 + int Result = 10 + void That = nullptr + void Target = nullptr +>>>> +int &operator =(int &,int) (Line: 246) + int & Arg1 = 3 + int Arg2 = 10 + int * const Result = ptr<10> + void That = nullptr + void Target = nullptr +>>>> +int &operator *(int *) (Line: 247) + int * Arg1 = ptr<9> + int * Result = ptr<9> + void That = nullptr + void Target = nullptr +>>>> +int operator +(int,int) (Line: 247) + int Arg1 = 9 + int Arg2 = 5 + int Result = 14 + void That = nullptr + void Target = nullptr +>>>> +int &operator =(int &,int) (Line: 247) + int & Arg1 = 5 + int Arg2 = 14 + int * const Result = ptr<14> + void That = nullptr + void Target = nullptr +>>>> 10, 14 diff --git a/AspectC++/tests/CallBuiltinOperator/main.cc b/AspectC++/tests/CallBuiltinOperator/main.cc new file mode 100644 index 0000000..75a39f3 --- /dev/null +++ b/AspectC++/tests/CallBuiltinOperator/main.cc @@ -0,0 +1,563 @@ +#include + +using namespace std; + +int global; + +void basicTests() { + int a = 8, b = 23; + bool n = true, m = false; + int x = 1; + int q[] = { 13, 23, 33, 43, 53 }; + const unsigned int i = 1; + int *p = q; + + cout << "a = " << a << endl; + cout << "b = " << b << endl; + cout << "m = " << m << endl; + cout << "n = " << n << endl; + cout << "x = " << x << endl; + + cout << ( +a ) << endl; + cout << ( -a ) << endl; + cout << ( a + b ) << endl; + cout << ( a - b ) << endl; + cout << ( a * b ) << endl; + cout << ( a / b ) << endl; + cout << ( a % b ) << endl; + + cout << ( ~a ) << endl; + cout << ( a & b ) << endl; + cout << ( a | b ) << endl; + cout << ( a ^ b ) << endl; + cout << ( a << b ) << endl; + cout << ( a >> b ) << endl; + + cout << ( a == b ) << endl; + cout << ( a != b ) << endl; + cout << ( a >= b ) << endl; + cout << ( a <= b ) << endl; + cout << ( a < b ) << endl; + cout << ( a > b ) << endl; + + cout << ( !m ) << endl; + cout << ( m && n ) << endl; + cout << ( m || n ) << endl; + + cout << ( x = a ) << endl; + cout << "Var: " << x << endl; + + cout << ( x += b ) << endl; + cout << "Var: " << x << endl; + cout << ( x -= a ) << endl; + cout << "Var: " << x << endl; + cout << ( x *= b ) << endl; + cout << "Var: " << x << endl; + cout << ( x /= a ) << endl; + cout << "Var: " << x << endl; + cout << ( x %= b ) << endl; + cout << "Var: " << x << endl; + cout << ( x &= b ) << endl; + cout << "Var: " << x << endl; + cout << ( x |= a ) << endl; + cout << "Var: " << x << endl; + cout << ( x ^= b ) << endl; + cout << "Var: " << x << endl; + cout << ( x <<= a ) << endl; + cout << "Var: " << x << endl; + cout << ( x >>= b ) << endl; + cout << "Var: " << x << endl; + + cout << ( x++ ) << endl; + cout << "Var: " << x << endl; + cout << ( x-- ) << endl; + cout << "Var: " << x << endl; + cout << ( --x ) << endl; + cout << "Var: " << x << endl; + cout << ( ++x ) << endl; + cout << "Var: " << x << endl; + +// cout << ( &global ) << endl; + cout << ( *p ) << endl; + cout << ( q[3] ) << endl; + cout << ( q[i] ) << endl; + + cout << ( "dummy", a ) << endl; + cout << ( m ? a : b ) << endl; + cout << ( n ? a : b ) << endl; +}; + +void nothing_to_do() { + +} + +void func(int arg) { + int h = 0; + h = arg != 0 ? (nothing_to_do(), 3) : 2; +} + +class TestClass { + // Members: + int privatemember; + static const int constmember = 5 * 2; + public: + unsigned int bitfield1 : 4; + unsigned int bitfield2 : constmember - 5; + static int depth; + int intmember; + TestClass* member; + void (*mfunc)(int); + + // Constructor: + TestClass(void (*pfunc)(int)) : intmember(424242), privatemember(212121), bitfield2(0x15), member(0), mfunc(0) { + intmember = 3; + int bla = 422142; + bla = (intmember && depth) ? 4 : 5; + const int drei = 3; + const int& dreir = drei; + const int* dreip = &dreir; + privatemember = 1; + bitfield1 = 2; + ++bitfield1; + bitfield1++; + int k = 214221; + k = bitfield1; + k = bitfield1 + bitfield2; + if(depth++ < 10) { + --depth; + } + if(10 > depth++) { + depth--; + } + member = 0; + mfunc = pfunc; + } + TestClass() {} + + // Member-functions: + void callmemfuncpointer() { + mfunc(1); + (*mfunc)(1); + int* arr = new int[10]; + int k = arr[5]; + + // Short-circuit-evaluation: + bool b1 = true, b2 = false; + bool shortcut = b1 && b2; + shortcut = b2 && b1; + shortcut = b1 || b2; + shortcut = b2 || b1; + int i1 = -1, i2 = 3; + int shortcut_int = shortcut ? i1 : i2; + shortcut_int = !shortcut ? i1 : i2; + TestClass shortcut_tc = shortcut ? TestClass() : TestClass(); + TestClass tc1, tc2; + shortcut_tc = shortcut ? tc1 : tc2; + TestClass* shortcut_tcp = shortcut ? new TestClass() : new TestClass(); + delete shortcut_tcp; + delete[] arr; + } +}; +int TestClass::depth = 0; + +void caller(void (*fnc)(int)) { + cout << endl << "Begin: Obj-Copy-Test"; + // Copy-assignment und copy-constructor: + TestClass* tcp2 = new TestClass(fnc); + tcp2->member = new TestClass(*tcp2); + TestClass tc = TestClass(fnc); + TestClass* tcp = new TestClass(fnc); + TestClass tc2 = tc; + TestClass tc3 = TestClass(tc); + tc = TestClass(fnc); + tc = tc2; + cout << endl << "End: Obj-Copy-Test"; + + tc.callmemfuncpointer(); + delete tcp; + delete tcp2->member; + delete tcp2; +} + +// Constant, static, global: +const int const_two = 3 - 1; +static char char_array[const_two + 5]; +int g1 = 0; +int g2 = g1 + 5; +enum ExampleEnum { + ENUM_VALUE = const_two + 1 +}; + +// Extern C: +extern "C" +{ + extern "C" + { + extern "C" void extern_c_func(int arg) + { + int e = 32767, e2 = 1; + e = e2 + 4; + } + extern "C" int i; + } +} + +void complexTests() { + extern_c_func(0); + void* voidp = 0; + const int const_22 = 3 - 1; + void (*sfp)() = ¬hing_to_do; + void (**dfp)() = &sfp; + dfp[0]; + + //Member-pointer: + ((1 == 2 ? (*dfp, &func) : &func))(1); + TestClass tc = TestClass(&func); + TestClass* (TestClass::*member_pointer) = 0; + member_pointer = &TestClass::member; + TestClass* value = tc.*member_pointer; + value = (&tc)->*member_pointer; + + TestClass tc2 = TestClass(&func); + int (TestClass::*int_member_pointer) = 0; + int_member_pointer = &TestClass::intmember; + int int_value = tc2.*int_member_pointer; + int_value = (&tc2)->*int_member_pointer; + + caller( &func ); + + // Miscellaneous: + + // ?: required to break the const_expr + if( static_cast( &int_value ) != ( voidp ? static_cast( &tc2 ) : static_cast( &tc ) ) ) {} + + bool bool_value = true && int_value && &tc; + int lala = dfp ? cout<< "hello" << endl, 4 : 5; + int* lalap = 0; + int la = (lalap = &lala, *lalap); + int i = 1; + int* ip = 0; + int i2 = (ip = &i, *ip); + + int m1 = 3, m2 = 5; + + int* int_pointer1 = new int(7); + int* int_pointer2 = new int(9); + m1 = *int_pointer1 + *(&(((m1)))); + m2 = *int_pointer2 + m2; + + // FIXME: Due to pointers and result-type not reliable: + // std::ptrdiff_t d = int_pointer2 - int_pointer1; + + cout << m1 << ", " << m2 << endl; + delete int_pointer1; + delete int_pointer2; +} + +int main () { + cout << endl << endl << endl; + cout << " ~~~ Simple checks ~~~" << endl << endl; + basicTests(); + + cout << endl << endl << endl; + cout << " ~~~ Complex checks ~~~" << endl << endl; + complexTests(); +} + +template inline void print_type() { cout << ""; } +template <> inline void print_type() { cout << "int"; }; +template <> inline void print_type() { cout << "int *"; }; +template <> inline void print_type() { cout << "int * const"; }; +template <> inline void print_type() { cout << "int &"; }; +template <> inline void print_type() { cout << "int *&"; }; +template <> inline void print_type() { cout << "int **"; }; +template <> inline void print_type() { cout << "int ** const"; }; +template <> inline void print_type() { cout << "const int"; }; +template <> inline void print_type() { cout << "const int *"; }; +template <> inline void print_type() { cout << "const int &"; }; +template <> inline void print_type() { cout << "unsigned int"; }; +template <> inline void print_type() { cout << "unsigned long int"; }; +template <> inline void print_type() { cout << "long int"; }; +template <> inline void print_type() { cout << "bool"; }; +template <> inline void print_type() { cout << "bool *"; }; +template <> inline void print_type() { cout << "bool &"; }; +template <> inline void print_type() { cout << "const bool"; }; +template <> inline void print_type() { cout << "bool * const"; }; +template <> inline void print_type() { cout << "void"; }; +template <> inline void print_type() { cout << "void *"; }; + +template <> inline void print_type() { cout << "TestClass"; }; +template <> inline void print_type() { cout << "TestClass *"; }; +template <> inline void print_type() { cout << "TestClass &"; }; +template <> inline void print_type() { cout << "TestClass *&"; }; +template <> inline void print_type() { cout << "TestClass **"; }; +template <> inline void print_type() { cout << "TestClass ** const"; }; +template <> inline void print_type() { cout << "TestClass * TestClass::*"; }; +template <> inline void print_type() { cout << "TestClass * TestClass::*&"; }; +template <> inline void print_type() { cout << "TestClass * TestClass::**"; }; +template <> inline void print_type() { cout << "TestClass * TestClass::** const"; }; +template <> inline void print_type() { cout << "int TestClass::*"; }; +template <> inline void print_type() { cout << "int TestClass::*&"; }; +template <> inline void print_type() { cout << "int TestClass::**"; }; +template <> inline void print_type() { cout << "int TestClass::** const"; }; + +template <> inline void print_type() { cout << "void (*)(int)"; }; +template <> inline void print_type() { cout << "void (*&)(int)"; }; +template <> inline void print_type() { cout << "void (**)(int)"; }; +template <> inline void print_type() { cout << "void (** const)(int)"; }; +template <> inline void print_type() { cout << "void (*)()"; }; +template <> inline void print_type() { cout << "void (*&)()"; }; +template <> inline void print_type() { cout << "void (**)()"; }; +template <> inline void print_type() { cout << "void (** const)()"; }; + +template inline void print_value( T v ) { cout << v; } +template inline void print_value( T *p ) { + if( p ) { + cout << "ptr<"; + print_value( *p ); + cout << ">"; + } + else + cout << "nullptr"; +} +template <> inline void print_value( bool b ) { cout << ( b ? "true" : "false" ); } +template <> inline void print_value( void *p ) { + if( p ) + cout << "ptr"; + else + cout << "nullptr"; +} +template <> inline void print_value( void (* p)(int) ) { + if( p == &func ) + cout << "fptr"; + else if( p == 0 ) + cout << "nullfptr"; + else + cout << "fptr"; +} +template <> inline void print_value( void (* p)() ) { + if( p == ¬hing_to_do ) + cout << "fptr"; + else if( p == 0 ) + cout << "nullfptr"; + else + cout << "fptr"; +} +inline void print_value( TestClass & ) { cout << ""; } +template <> inline void print_value( TestClass *p ) { + if( p ) + cout << "objptr<{TestClass}>"; + else + cout << "nullptr"; +} +template <> inline void print_value( TestClass * TestClass::*p ) { + if( p == &TestClass::member ) + cout << "memptr"; + else if( p ) + cout << "memptr"; + else + cout << "memptr"; +} +template <> inline void print_value( int TestClass::*p ) { + if( p == &TestClass::intmember ) + cout << "memptr"; + else if( p ) + cout << "memptr"; + else + cout << "memptr"; +} + +template struct ARGPrinter { + template static inline void print( JoinPoint &tjp ) { + ARGPrinter::print( tjp ); + cout << " "; + print_type< typename JoinPoint::template Arg::Type >(); + cout << " Arg" << I << " = "; + if(tjp.template arg() > 0) { + print_value( *tjp.template arg() ); + } + else { + cout << ""; + } + cout << endl; + } +}; +template <> struct ARGPrinter<0> { + template static inline void print( JoinPoint &tjp ) {} +}; + +template inline void print_args( JoinPoint &tjp ) { + ARGPrinter::print( tjp ); +} + +template inline void print_objptr( T *p ) { + if( p ) + cout << ""; + else + cout << "nullptr"; +} + +aspect CallTracer { + pointcut builtin_ops() = builtin("% operator %(...)"); + + advice builtin_ops() : before() { + cout << endl << tjp->signature() << " (Line: " << tjp->line() << ")" << endl; + } + + advice builtin_ops() : after() { + cout << " "; + print_type< JoinPoint::That >(); + cout << " That = "; + print_objptr( tjp->that() ); + cout << endl; + + cout << " "; + print_type< JoinPoint::Target >(); + cout << " Target = "; + print_objptr( tjp->target() ); + cout << endl; + + cout << ">>>> "; + } + + advice builtin_ops() : around() { + print_args<>( *tjp ); + + tjp->proceed(); + } + + advice builtin_ops() : around() { + tjp->proceed(); + cout << " "; + print_type< JoinPoint::Result >(); + cout << " Result = "; + print_value( *tjp->result() ); + cout << endl; + } + + // advice to structure the output + advice construction( "TestClass" ) : before() { + cout << endl << "~~~TestClass init >>>"; + } + advice construction( "TestClass" ) : after() { + cout << endl << "~~~TestClass init <<<"; + } +}; + +// Test whether advice with args-pointcut-function will be handled +// correctly on join-points with short-circuit-evaluation: +aspect ShortCircuitArgsPointcutFunctionTester { + pointcut shortcircuiting_ops() = builtin("% operator &&(...)" || "% operator ||(...)" || "% operator ?:(...)"); + + advice shortcircuiting_ops() : order("ShortCircuitArgsPointcutFunctionTester", "CallTracer"); + + advice shortcircuiting_ops() : before() { + cout << endl << "proceed(); + } + + advice shortcircuiting_ops() && args("%", b2) : around(bool b2) { + cout << "co"; + tjp->proceed(); + } + + advice shortcircuiting_ops() && args("%", "%") : around() { + if(tjp->arg<1>() > 0) { + cout << "nd" << " (" << (*(tjp->arg<1>()) ? "true" : "false") << ")"; + } + else { + cout << ""; + } + tjp->proceed(); + } + + advice shortcircuiting_ops() && args(b1, i1, i2) : around(bool b1, int i1, int i2) { + cout << "!!! This should never be displayed !!!" << endl; + tjp->proceed(); + } + + advice shortcircuiting_ops() && args("%", i1, i2) : around(int i1, int i2) { + cout << "!!! This should never be displayed !!!" << endl; + tjp->proceed(); + } + + advice shortcircuiting_ops() && args("%", "%", "%") : before() { + cout << " arg: "; + } + + advice shortcircuiting_ops() && args("%", "%", i2) : around(int i2) { + cout << "third (" << i2 << ")"; + tjp->proceed(); + } + + advice shortcircuiting_ops() && args("%", i1, "%") : around(int i1) { + cout << "second (" << i1 << ")"; + tjp->proceed(); + } + + advice shortcircuiting_ops() && args("%", "%", ir2) : around(int& ir2) { + cout << "third (" << ir2 << ")"; + tjp->proceed(); + } + + advice shortcircuiting_ops() && args("%", ir1, "%") : around(int& ir1) { + cout << "second (" << ir1 << ")"; + tjp->proceed(); + } + + advice shortcircuiting_ops() && args("%", "%", t2) : around(TestClass t2) { + cout << "third ([TestClass])"; + tjp->proceed(); + } + + advice shortcircuiting_ops() && args("%", t1, "%") : around(TestClass t1) { + cout << "second ([TestClass])"; + tjp->proceed(); + } + + advice shortcircuiting_ops() && args("%", "%", tr2) : around(TestClass& tr2) { + cout << "third ([TestClass-reference])"; + tjp->proceed(); + } + + advice shortcircuiting_ops() && args("%", tr1, "%") : around(TestClass& tr1) { + cout << "second ([TestClass-reference])"; + tjp->proceed(); + } + + advice shortcircuiting_ops() && args("%", "%", tp2) : around(TestClass* tp2) { + cout << "third ([TestClass-pointer])"; + tjp->proceed(); + } + + advice shortcircuiting_ops() && args("%", tp1, "%") : around(TestClass* tp1) { + cout << "second ([TestClass-pointer])"; + tjp->proceed(); + } + + advice shortcircuiting_ops() && args("%", "%", vp2) : around(void* vp2) { + cout << "third ([void-pointer])"; + tjp->proceed(); + } + + advice shortcircuiting_ops() && args("%", vp1, "%") : around(void* vp1) { + cout << "second ([void pointer])"; + tjp->proceed(); + } + + advice shortcircuiting_ops() : before() { + cout << ">"; + } +}; diff --git a/AspectC++/tests/CallOnRef/Makefile b/AspectC++/tests/CallOnRef/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/CallOnRef/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/CallOnRef/feature.ref b/AspectC++/tests/CallOnRef/feature.ref new file mode 100644 index 0000000..c93db60 --- /dev/null +++ b/AspectC++/tests/CallOnRef/feature.ref @@ -0,0 +1,5 @@ +CallOnRef: +============================================================= +before call to void f(C &) +before call to void C::func() +============================================================= diff --git a/AspectC++/tests/CallOnRef/main.cc b/AspectC++/tests/CallOnRef/main.cc new file mode 100644 index 0000000..44afadb --- /dev/null +++ b/AspectC++/tests/CallOnRef/main.cc @@ -0,0 +1,27 @@ +#include + +aspect CallTracer { + advice call ("% ...::%(...)") && !call ("% printf(...)") : around () { + printf ("before call to %s\n", tjp->signature ()); + tjp->proceed (); + } +}; + +class C { +public: + void func () {} +}; + +void f (C& obj) { + obj.func (); +} + +int main () { + printf ("CallOnRef:\n"); + printf ("=============================================================\n"); + C c; + f (c); + printf ("=============================================================\n"); + return 0; +} + diff --git a/AspectC++/tests/CallPostfixOp/Makefile b/AspectC++/tests/CallPostfixOp/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/CallPostfixOp/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/CallPostfixOp/feature.ref b/AspectC++/tests/CallPostfixOp/feature.ref new file mode 100644 index 0000000..36329b7 --- /dev/null +++ b/AspectC++/tests/CallPostfixOp/feature.ref @@ -0,0 +1,19 @@ +CallPostfixOp: advice for calls to postfix operators +==================================================== +before A A::operator ++(int) +inside A A::operator ++(int) +before A A::operator ++() +inside A A::operator ++() +before A A::operator --(int) +inside A A::operator --(int) +before A A::operator --() +inside A A::operator --() +before int A::operator [](int) +inside A A::operator [](int) +before void A::operator ()(int,bool) +inside A A::operator ()(int,bool=false) +before void A::operator ()(int,bool) +inside A A::operator ()(int,bool=false) +before void A::operator ()(int,bool) +inside A A::operator ()(int,bool=false) +==================================================== diff --git a/AspectC++/tests/CallPostfixOp/main.cc b/AspectC++/tests/CallPostfixOp/main.cc new file mode 100644 index 0000000..0a406f4 --- /dev/null +++ b/AspectC++/tests/CallPostfixOp/main.cc @@ -0,0 +1,64 @@ +#include + +class A { +public: + A operator++ () { + printf("inside A A::operator ++()\n"); + return *this; + } + A operator++ (int) { + printf("inside A A::operator ++(int)\n"); + return *this; + } + A operator-- () { + printf("inside A A::operator --()\n"); + return *this; + } + A operator-- (int) { + printf("inside A A::operator --(int)\n"); + return *this; + } + int operator [] (int) { + printf("inside A A::operator [](int)\n"); + return 0; + } + void operator () (int, bool = false) { + printf("inside A A::operator ()(int,bool=false)\n"); + } +}; + +aspect Postfix { + advice call ("% A::operator ++()") : before () { + printf ("before %s\n", JoinPoint::signature ()); + } + advice call ("% A::operator ++(int)") : before () { + printf ("before %s\n", JoinPoint::signature ()); + } + advice call ("% A::operator --()") : before () { + printf ("before %s\n", JoinPoint::signature ()); + } + advice call ("% A::operator --(int)") : before () { + printf ("before %s\n", JoinPoint::signature ()); + } + advice call ("% A::operator [](...)") : before () { + printf ("before %s\n", JoinPoint::signature ()); + } + advice call ("% A::operator ()(...)") : before () { + printf ("before %s\n", JoinPoint::signature ()); + } +}; + +int main() { + printf ("CallPostfixOp: advice for calls to postfix operators\n"); + printf ("====================================================\n"); + A a; + a++; + ++a; + a--; + --a; + a[4711]; + a (1); + a (2, true); + a.operator()(3); + printf ("====================================================\n"); +} diff --git a/AspectC++/tests/CallRef/Makefile b/AspectC++/tests/CallRef/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/CallRef/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/CallRef/feature.ref b/AspectC++/tests/CallRef/feature.ref new file mode 100644 index 0000000..e69de29 diff --git a/AspectC++/tests/CallRef/main.cc b/AspectC++/tests/CallRef/main.cc new file mode 100644 index 0000000..719743f --- /dev/null +++ b/AspectC++/tests/CallRef/main.cc @@ -0,0 +1,27 @@ +class A { + public: void bar(int x) {} +}; + +// the function itself +int foo(int f) { return f; } + +int main() { + // function pointer + int (*foo2)(int) = &foo; + foo2 = &foo; + foo2 = foo; + + // function reference + int(& func)(int) = foo; + func(5); + + // function-pointer call + foo2(42); + (*foo2)(4711); + + // member-function pointer: + A a; + void (A::*fptr) (int) = &A::bar; + (a.*fptr)(3); +} + diff --git a/AspectC++/tests/CallViaADN/Makefile b/AspectC++/tests/CallViaADN/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/CallViaADN/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/CallViaADN/classes.h b/AspectC++/tests/CallViaADN/classes.h new file mode 100644 index 0000000..5c49825 --- /dev/null +++ b/AspectC++/tests/CallViaADN/classes.h @@ -0,0 +1,49 @@ +#ifndef __classes_h__ +#define __classes_h__ + +class A { +public: + friend void declared_friend_1(const A&); + friend void declared_friend_2(const A&); + friend inline void defined_friend_1(const A&) {} + friend void defined_friend_2(const A&); +}; + +void declared_friend_1(const A&); +inline void defined_friend_2(const A&) {} + +namespace N { + class B { + public: + friend void declared_friend(const B&); + friend inline void defined_friend_1(const B&) {} + friend void defined_friend_2(const B&); + }; + + inline void defined_friend_2(const B&) {} +} + +namespace QT { + class QString { + friend bool operator==(const QString&, const QString&); + }; +} + +namespace Peer { + class TorrentPeer { + public: + QT::QString id; + + inline bool operator==(const TorrentPeer &other) { + return id == other.id; + } + inline bool foo(); + }; + + + bool TorrentPeer::foo () { + return id == id; + } +} + +#endif // __classes_h__ diff --git a/AspectC++/tests/CallViaADN/feature.ref b/AspectC++/tests/CallViaADN/feature.ref new file mode 100644 index 0000000..716f153 --- /dev/null +++ b/AspectC++/tests/CallViaADN/feature.ref @@ -0,0 +1,15 @@ +CallViaADN: Calls that require argument-dependent name lookup +============================================================= +calling void declared_friend_1(const A &) +calling void declared_friend_2(const A &) +calling void defined_friend_1(const A &) +calling void defined_friend_2(const A &) +------------------------------------------------------------- +calling void N::declared_friend(const N::B &) +calling void N::defined_friend_1(const N::B &) +calling void N::defined_friend_2(const N::B &) +------------------------------------------------------------- +calling bool QT::operator ==(const QT::QString &,const QT::QString &) +calling bool Peer::TorrentPeer::operator ==(const Peer::TorrentPeer &) +calling bool QT::operator ==(const QT::QString &,const QT::QString &) +============================================================= diff --git a/AspectC++/tests/CallViaADN/functions.cc b/AspectC++/tests/CallViaADN/functions.cc new file mode 100644 index 0000000..367e4f0 --- /dev/null +++ b/AspectC++/tests/CallViaADN/functions.cc @@ -0,0 +1,12 @@ +#include "classes.h" + +void declared_friend_1(const A&) {} +void declared_friend_2(const A&) {} + +namespace N { + void declared_friend(const N::B&) {} +} + +namespace QT { + bool operator==(const QString&, const QString&) { return true; } +} diff --git a/AspectC++/tests/CallViaADN/main.cc b/AspectC++/tests/CallViaADN/main.cc new file mode 100644 index 0000000..987ca31 --- /dev/null +++ b/AspectC++/tests/CallViaADN/main.cc @@ -0,0 +1,24 @@ +#include + +#include "classes.h" + +int main() { + A a; + N::B b; + printf ("CallViaADN: Calls that require argument-dependent name lookup\n"); + printf ("=============================================================\n"); + ::declared_friend_1(a); + declared_friend_2(a); + defined_friend_1(a); + ::defined_friend_2(a); + printf ("-------------------------------------------------------------\n"); + declared_friend(b); + defined_friend_1(b); + N::defined_friend_2(b); + printf ("-------------------------------------------------------------\n"); + QT::QString s1, s2; + operator ==(s1, s2); + Peer::TorrentPeer p1,p2; + bool c = (p1==p2); + printf ("=============================================================\n"); +} diff --git a/AspectC++/tests/CallViaADN/trace.ah b/AspectC++/tests/CallViaADN/trace.ah new file mode 100644 index 0000000..3953816 --- /dev/null +++ b/AspectC++/tests/CallViaADN/trace.ah @@ -0,0 +1,12 @@ +#ifndef __trace_ah__ +#define __trace_ah__ + +#include + +aspect TraceCall { + advice call("% ...::%(...)" && !"% printf(...)") : before () { + printf ("calling %s\n", JoinPoint::signature()); + } +}; + +#endif diff --git a/AspectC++/tests/CompoundGetSetAdvice/Makefile b/AspectC++/tests/CompoundGetSetAdvice/Makefile new file mode 100644 index 0000000..daa5e9e --- /dev/null +++ b/AspectC++/tests/CompoundGetSetAdvice/Makefile @@ -0,0 +1,2 @@ +ACFLAGS ?= --builtin_operators --data_joinpoints +include ../Makefile.generic diff --git a/AspectC++/tests/CompoundGetSetAdvice/feature.ref b/AspectC++/tests/CompoundGetSetAdvice/feature.ref new file mode 100644 index 0000000..92575f7 --- /dev/null +++ b/AspectC++/tests/CompoundGetSetAdvice/feature.ref @@ -0,0 +1,347 @@ +COMPOUND: + + += : +Get: int a = 42 +Before: int a +ent: 42 +new: 45 +Around: int a +ent: 42 +new: 45 +ent (inner): 42 +new (inner): 90 +set (inner): 90 +set: 90 +After: int a +set: 122 +Get: int a = 122 +122 + + += : +Get: int b = 3 +Get: int a = 122 +Before: int a +ent: 122 +new: 125 +Around: int a +ent: 122 +new: 125 +ent (inner): 122 +new (inner): 250 +set (inner): 250 +set: 250 +After: int a +set: 282 +Get: int a = 282 +282 + +++: +Get: int a = 282 +Before: int a +ent: 282 +new: 283 +Around: int a +ent: 282 +new: 283 +ent (inner): 282 +new (inner): 566 +set (inner): 566 +set: 566 +After: int a +set: 598 +282 + +++: +Hello Operator: int &operator ++(int &) +Get: int a = 598 +Before: int a +ent: 598 +new: 599 +Around: int a +ent: 598 +new: 599 +ent (inner): 598 +new (inner): 1198 +set (inner): 1198 +set: 1198 +After: int a +set: 1230 +Bye. +Get: int a = 1230 +1230 + +--: +Get: int a = 1230 +Before: int a +ent: 1230 +new: 1229 +Around: int a +ent: 1230 +new: 1229 +ent (inner): 1230 +new (inner): 2458 +set (inner): 2458 +set: 2458 +After: int a +set: 2490 +1230 + +--: +Get: int a = 2490 +Before: int a +ent: 2490 +new: 2489 +Around: int a +ent: 2490 +new: 2489 +ent (inner): 2490 +new (inner): 4978 +set (inner): 4978 +set: 4978 +After: int a +set: 5010 +Get: int a = 5010 +5010 + + -= : +Get: int b = 3 +Get: int a = 5010 +Before: int a +ent: 5010 +new: 5007 +Around: int a +ent: 5010 +new: 5007 +ent (inner): 5010 +new (inner): 10014 +set (inner): 10014 +set: 10014 +After: int a +set: 10046 +Get: int a = 10046 +10046 + + *= : +Get: int b = 3 +Get: int a = 10046 +Before: int a +ent: 10046 +new: 30138 +Around: int a +ent: 10046 +new: 30138 +ent (inner): 10046 +new (inner): 60276 +set (inner): 60276 +set: 60276 +After: int a +set: 60308 +Get: int a = 60308 +60308 + + /= : +Get: int b = 3 +Get: int a = 60308 +Before: int a +ent: 60308 +new: 20102 +Around: int a +ent: 60308 +new: 20102 +ent (inner): 60308 +new (inner): 40204 +set (inner): 40204 +set: 40204 +After: int a +set: 40236 +Get: int a = 40236 +40236 + + %= : +Get: int b = 3 +Get: int a = 40236 +Before: int a +ent: 40236 +new: 0 +Around: int a +ent: 40236 +new: 0 +ent (inner): 40236 +new (inner): 0 +set (inner): 0 +set: 0 +After: int a +set: 32 +Get: int a = 32 +32 + + |= : +Get: int b = 3 +Get: int a = 32 +Before: int a +ent: 32 +new: 35 +Around: int a +ent: 32 +new: 35 +ent (inner): 32 +new (inner): 70 +set (inner): 70 +set: 70 +After: int a +set: 102 +Get: int a = 102 +102 + + ^= : +Get: int b = 3 +Get: int a = 102 +Before: int a +ent: 102 +new: 101 +Around: int a +ent: 102 +new: 101 +ent (inner): 102 +new (inner): 202 +set (inner): 202 +set: 202 +After: int a +set: 234 +Get: int a = 234 +234 + + &= : +Get: int b = 3 +Get: int a = 234 +Before: int a +ent: 234 +new: 2 +Around: int a +ent: 234 +new: 2 +ent (inner): 234 +new (inner): 4 +set (inner): 4 +set: 4 +After: int a +set: 36 +Get: int a = 36 +36 + + <<= : +Get: int b = 3 +Get: int a = 36 +Before: int a +ent: 36 +new: 288 +Around: int a +ent: 36 +new: 288 +ent (inner): 36 +new (inner): 576 +set (inner): 576 +set: 576 +After: int a +set: 608 +Get: int a = 608 +608 + + >>= : +Get: int b = 3 +Get: int a = 608 +Before: int a +ent: 608 +new: 76 +Around: int a +ent: 608 +new: 76 +ent (inner): 608 +new (inner): 152 +set (inner): 152 +set: 152 +After: int a +set: 184 +Get: int a = 184 +184 + + +FORWARD: + + = : +Ref: short int s _. PASSED +5 +Ref: short int S::s .. PASSED +16 + + += : +Ref: short int s _. PASSED +7 +Ref: short int S::s .. PASSED +18 + + -= : +Ref: short int s _. PASSED +3 +Ref: short int S::s .. PASSED +14 + + *= : +Ref: short int s _. PASSED +15 +Ref: short int S::s .. PASSED +70 + + /= : +Ref: short int s _. PASSED +5 +Ref: short int S::s .. PASSED +23 + + %= : +Ref: short int s _. PASSED +5 +Ref: short int S::s .. PASSED +2 + + ^= : +Ref: short int s _. PASSED +6 +Ref: short int S::s .. PASSED +1 + + |= : +Ref: short int s _. PASSED +7 +Ref: short int S::s .. PASSED +5 + + &= : +Ref: short int s _. PASSED +3 +Ref: short int S::s .. PASSED +1 + + <<= : +Ref: short int s _. PASSED +24 +Ref: short int S::s .. PASSED +8 + + >>= : +Ref: short int s _. PASSED +6 +Ref: short int S::s .. PASSED +2 + +++: +Ref: short int s _. PASSED +7 +Ref: short int S::s .. PASSED +3 + +--: +Ref: short int s _. PASSED +6 +Ref: short int S::s .. PASSED +2 diff --git a/AspectC++/tests/CompoundGetSetAdvice/main.cc b/AspectC++/tests/CompoundGetSetAdvice/main.cc new file mode 100644 index 0000000..0b50a5b --- /dev/null +++ b/AspectC++/tests/CompoundGetSetAdvice/main.cc @@ -0,0 +1,194 @@ +#include + +using namespace std; + +int a = 42; +int b = 3; + +short s; + +struct S { + short s; +} o; + +int main() { + cout << "COMPOUND:" << endl; + + cout << endl << " += :" << endl; + cout << ( a += 3 ) << endl; + + cout << endl << " += :" << endl; + cout << ( a += b ) << endl; + + cout << endl << "++:" << endl; + cout << ( a++ ) << endl; + + cout << endl << "++:" << endl; + cout << ( ++a ) << endl; + + cout << endl << "--:" << endl; + cout << ( a-- ) << endl; + + cout << endl << "--:" << endl; + cout << ( --a ) << endl; + + cout << endl << " -= :" << endl; + cout << ( a -= b ) << endl; + + cout << endl << " *= :" << endl; + cout << ( a *= b ) << endl; + + cout << endl << " /= :" << endl; + cout << ( a /= b ) << endl; + + cout << endl << " %= :" << endl; + cout << ( a %= b ) << endl; + + cout << endl << " |= :" << endl; + cout << ( a |= b ) << endl; + + cout << endl << " ^= :" << endl; + cout << ( a ^= b ) << endl; + + cout << endl << " &= :" << endl; + cout << ( a &= b ) << endl; + + cout << endl << " <<= :" << endl; + cout << ( a <<= b ) << endl; + + cout << endl << " >>= :" << endl; + cout << ( a >>= b ) << endl; + + // checking forwarding without advice on op + cout << endl << endl << "FORWARD:" << endl; + + cout << endl << " = :" << endl; + { short& r = ( s = 5 ); cout << r << endl; } + { short& r = ( o.s = 16 ); cout << r << endl; } + + cout << endl << " += :" << endl; + { short& r = ( s += 2 ); cout << r << endl; } + { short& r = ( o.s += 2 ); cout << r << endl; } + + cout << endl << " -= :" << endl; + { short& r = ( s -= 4 ); cout << r << endl; } + { short& r = ( o.s -= 4 ); cout << r << endl; } + + cout << endl << " *= :" << endl; + { short& r = ( s *= 5 ); cout << r << endl; } + { short& r = ( o.s *= 5 ); cout << r << endl; } + + cout << endl << " /= :" << endl; + { short& r = ( s /= 3 ); cout << r << endl; } + { short& r = ( o.s /= 3 ); cout << r << endl; } + + cout << endl << " %= :" << endl; + { short& r = ( s %= 7 ); cout << r << endl; } + { short& r = ( o.s %= 7 ); cout << r << endl; } + + cout << endl << " ^= :" << endl; + { short& r = ( s ^= 3 ); cout << r << endl; } + { short& r = ( o.s ^= 3 ); cout << r << endl; } + + cout << endl << " |= :" << endl; + { short& r = ( s |= 5 ); cout << r << endl; } + { short& r = ( o.s |= 5 ); cout << r << endl; } + + cout << endl << " &= :" << endl; + { short& r = ( s &= 3 ); cout << r << endl; } + { short& r = ( o.s &= 3 ); cout << r << endl; } + + cout << endl << " <<= :" << endl; + { short& r = ( s <<= 3 ); cout << r << endl; } + { short& r = ( o.s <<= 3 ); cout << r << endl; } + + cout << endl << " >>= :" << endl; + { short& r = ( s >>= 2 ); cout << r << endl; } + { short& r = ( o.s >>= 2 ); cout << r << endl; } + + cout << endl << "++:" << endl; + { short& r = ( ++s ); cout << r << endl; } + { short& r = ( ++o.s ); cout << r << endl; } + + cout << endl << "--:" << endl; + { short& r = ( --s ); cout << r << endl; } + { short& r = ( --o.s ); cout << r << endl; } + + return 0; +} + +aspect SetTest1 { + advice set("int ...::%") : before() { + cout << "Before: " << tjp->signature() << endl; + cout << "ent: " << *tjp->entity() << endl; + cout << "new: " << *tjp->arg<0>() << endl; + } + + advice set("int ...::%") : after() { + cout << "After: " << tjp->signature() << endl; + cout << "set: " << *tjp->entity() << endl; + } +}; + +aspect SetTest2 { + advice set("int ...::%") : around() { + cout << "Around: " << tjp->signature() << endl; + cout << "ent: " << *tjp->entity() << endl; + cout << "new: " << *tjp->arg<0>() << endl; + *tjp->arg<0>() *= 2; + + tjp->proceed(); + + JoinPoint::Entity &tmp = *tjp->entity(); + cout << "set: " << tmp << endl; + tmp += 32; + } +}; + +aspect SetTest3 { + advice set("int ...::%") : around() { + cout << "ent (inner): " << *tjp->entity() << endl; + cout << "new (inner): " << *tjp->arg<0>() << endl; + + tjp->proceed(); + + cout << "set (inner): " << *tjp->entity() << endl; + } +}; + +aspect GetTest { + advice get("int ...::%") : after() { + cout << "Get: " << tjp->signature() << " = " << *tjp->entity() << endl; + } +}; + +aspect Call { + advice builtin("int &operator ++(int &)") : around() { + cout << "Hello Operator: " << tjp->signature() << endl; + tjp->proceed(); + cout << "Bye." << endl; + } +}; + +aspect RefTest { + advice ref("short ...::%") : after() { + cout << "Ref: " << tjp->signature() << " "; + bool pass = true; + if( tjp->target() ) { + pass = pass && ( tjp->target() == &o ); + cout << ( tjp->target() == &o ? "." : "F" ); + pass = pass && ( tjp->entity() == &o.s ); + cout << ( tjp->entity() == &o.s ? "." : "F" ); + } + else { + cout << "_"; + pass = pass && ( tjp->entity() == &s ); + cout << ( tjp->entity() == &s ? "." : "F" ); + } + if( pass ) + cout << " PASSED"; + else + cout << " FAILED !!!"; + cout << endl; + } +}; diff --git a/AspectC++/tests/ConsDesAdvice/ConsDesTracker.ah b/AspectC++/tests/ConsDesAdvice/ConsDesTracker.ah new file mode 100644 index 0000000..c9e447f --- /dev/null +++ b/AspectC++/tests/ConsDesAdvice/ConsDesTracker.ah @@ -0,0 +1,57 @@ +#ifndef __ConsDesTracker_ah__ +#define __ConsDesTracker_ah__ + +#include +#include "c1.h" + +aspect ConsDesTracker { + advice construction ("C4") : around () { + printf (" instead of %s\n", tjp->signature ()); + tjp->proceed (); + } + advice destruction ("C4") : after () { + printf (" after %s\n", tjp->signature ()); + } + advice (destruction ("%") || construction("%")) && within("C4"): after () { + printf (" after cons/dest within %s\n", tjp->signature ()); + } + advice args() && (construction ("C%" && !"ConsDesTracker") || + destruction ("C1"||"C2")) : before () { + printf (" before %s\n", tjp->signature ()); + } + advice construction ("%") && that (obj) : before (C1 *obj) { + printf (" before %s, that C1 %d\n", JoinPoint::signature (), obj->id ()); + } + advice construction ("%") && that (obj) : after (Unique *obj) { + printf (" after %s, that Unique %d\n", + JoinPoint::signature (), obj->id ()); + } + advice construction ("C2") : around () { + printf (" instead of %s\n", tjp->signature ()); + } + advice within ("C1") && call("% ...::dump(...)") : around () { + printf (" dump: "); + tjp->proceed (); + } + advice construction ("C1") : before () { + printf (" before %s\n", tjp->signature ()); + } + advice construction ("%") && args(i) : after (int i) { + printf (" after integer constructor %d\n", i); + } + advice construction ("Unconstructable") : before () {} + + advice construction("Bug530") : before() { + printf (" before %s\n", JoinPoint::signature()); + } + + advice construction("Bug530") : after() { + printf (" after %s\n", JoinPoint::signature()); + } + + advice construction("TXXX<...>") : before() { + printf (" before %s\n", JoinPoint::signature()); + } +}; + +#endif // __ConsDesTracker_ah__ diff --git a/AspectC++/tests/ConsDesAdvice/Makefile b/AspectC++/tests/ConsDesAdvice/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/ConsDesAdvice/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/ConsDesAdvice/c1.h b/AspectC++/tests/ConsDesAdvice/c1.h new file mode 100644 index 0000000..bccb0c0 --- /dev/null +++ b/AspectC++/tests/ConsDesAdvice/c1.h @@ -0,0 +1,80 @@ +#ifndef __C1_h__ +#define __C1_h__ + +#include + +class M { + int i; +public: + M() { i = 815; }; + M(const M&c) { i = c.i; } + int val () const { return i; } +}; + +template class TemplateBase { +}; + +class Unique { + int _id; + void gen () { + static int curr = 0; + _id = curr++; + } + public: + Unique () { gen (); } + Unique (const Unique &obj) { gen (); } + int id () const { return _id; } +}; + +// the TemplateBase is only handled correct with --real-instances +class C1 : TemplateBase, Unique { + // these elements should not be copied! + friend class M; + enum E { E1 = 10, E2 }; + static const int c = 13; + // -- + M m; + M ma[3]; + const int &r; + const int val; + double array[2]; + unsigned scalar; + static char *static_ptr; + int a1[3], s1; + int s2, a2[6]; + typedef int INT[10]; + int s3, a3[4][6], s4; + INT a4; + union { int u1; float u2; }; + union { int u3; float u4; INT u5; }; +public: + C1 (int v) : val (v), r(val) { + array[0] = 3.14; array[1] = 2.71; + scalar = 4711; + dump (); + } + inline C1 (double); + ~C1 () {} + void dump () const { + printf ("C1 obj %d (%d, [%d, %d, %d], %d, %d, %d, [%1.2lf, %1.2lf] %d)\n", + id (), + m.val (), + ma[0].val (), ma[1].val (), ma[2].val (), + r, + val, + c, + array[0], array[1], + scalar); + } +}; + +char *C1::static_ptr = (char*)0; // this cast creates an anonymous attribute! + +inline C1::C1 (double d) : val (-1), r (val) { + array[0] = d + 1.0; + array[1] = d + 2.0; + scalar = 4712; + dump (); +} + +#endif // __C1_h__ diff --git a/AspectC++/tests/ConsDesAdvice/feature.ref b/AspectC++/tests/ConsDesAdvice/feature.ref new file mode 100644 index 0000000..e3fc88d --- /dev/null +++ b/AspectC++/tests/ConsDesAdvice/feature.ref @@ -0,0 +1,53 @@ +ConsDesAdvice: advice for object construction & destruction +=========================================================== +--C2: + after Unique::Unique(), that Unique 0 + before C1::C1(int), that C1 0 + before C1::C1(int) + dump: C1 obj 0 (815, [815, 815, 815], 4711, 4711, 13, [3.14, 2.71] 4711) + after integer constructor 4711 + after C1::C1(int), that Unique 0 + before C2::C2() + before C2::C2(), that C1 0 + instead of C2::C2() + after C2::C2(), that Unique 0 +--C2-copy: + after Unique::Unique(const Unique &), that Unique 1 + before C1::C1(const C1 &), that C1 1 + before C1::C1(const C1 &) + after C1::C1(const C1 &), that Unique 1 + before C2::C2(const C2 &), that C1 1 + instead of C2::C2(const C2 &) + after C2::C2(const C2 &), that Unique 1 +--C3: + after Unique::Unique(), that Unique 2 + before C1::C1(int), that C1 2 + before C1::C1(int) + dump: C1 obj 2 (815, [815, 815, 815], 50, 50, 13, [3.14, 2.71] 4711) + after integer constructor 50 + after C1::C1(int), that Unique 2 + before C3::C3(int), that C1 2 + after integer constructor 10 + after C3::C3(int), that Unique 2 +--C4: + instead of C4::C4() + before C4::C4() + after cons/dest within C4::C4() +--correctly copied? + C1 obj 0 (815, [815, 815, 815], 4711, 4711, 13, [3.14, 2.71] 4711) + C1 obj 1 (815, [815, 815, 815], 4711, 4711, 13, [3.14, 2.71] 4711) +--Bug530: is that object constructed here? + before Bug530::Bug530() + after Bug530::Bug530() + before Bug530::Bug530(const Bug530 &) + after Bug530::Bug530(const Bug530 &) +--Instantiating template TXXX: no advice should match here +----------------------end-of-main-------------------------- + after cons/dest within C4::~C4() + after C4::~C4() + before C1::~C1() + before C2::~C2() + before C1::~C1() + before C2::~C2() + before C1::~C1() +=========================================================== diff --git a/AspectC++/tests/ConsDesAdvice/main.cc b/AspectC++/tests/ConsDesAdvice/main.cc new file mode 100644 index 0000000..13e87cb --- /dev/null +++ b/AspectC++/tests/ConsDesAdvice/main.cc @@ -0,0 +1,63 @@ +#include + +#include "c1.h" + +class UCBase { UCBase (); }; +class Unconstructable : public UCBase { +}; + +class C2 : public C1 { +public: + C2 () : C1 (4711) {} + ~C2 (); + void f () {} +}; + +C2::~C2 () { +} + +class C3 : public C1 { +public: + C3 (int i) : C1 ((2 * i) + 3 * i) {} +}; + +class C4 {}; + +class Bug530 { + Bug530 xxx() { Bug530 a; return a; } // this is NO ctor +}; + +template +class TXXX { +public: + TXXX() {} +}; + +int main () { + printf ("ConsDesAdvice: advice for object construction & destruction\n"); + printf ("===========================================================\n"); + printf ("--C2:\n"); + C2 c2; + printf ("--C2-copy:\n"); + C2 copy (c2); + printf ("--C3:\n"); + C3 c3 (10); + printf ("--C4:\n"); + C4 c4; + printf ("--correctly copied?\n"); + printf (" "); c2.dump (); + printf (" "); copy.dump (); + printf ("--Bug530: is that object constructed here?\n"); + Bug530 b1; + Bug530 b2 = Bug530(b1); + printf ("--Instantiating template TXXX: no advice should match here\n"); + TXXX ti; + printf ("----------------------end-of-main--------------------------\n"); + return 0; +} + +aspect AfterMainActions { + advice execution ("% main (...)") : after () { + printf ("===========================================================\n"); + } +}; diff --git a/AspectC++/tests/Context/Makefile b/AspectC++/tests/Context/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Context/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Context/feature.ref b/AspectC++/tests/Context/feature.ref new file mode 100644 index 0000000..215b774 --- /dev/null +++ b/AspectC++/tests/Context/feature.ref @@ -0,0 +1,7 @@ +Context information is requested by advice in arbitrary order: +============================================================== +that: main()::t, int 10, Complex(2.000000,0.500000) +that: main()::t, int 10, Complex(2.000000,0.500000) +that: main()::t, int 10, Complex(2.000000,0.500000) +that: main()::t, int 10, Complex(2.000000,0.500000) +============================================================== diff --git a/AspectC++/tests/Context/main.cc b/AspectC++/tests/Context/main.cc new file mode 100644 index 0000000..730fb86 --- /dev/null +++ b/AspectC++/tests/Context/main.cc @@ -0,0 +1,37 @@ +#include + +struct Complex { + double r; + double i; +}; + +class Test { + const char *_name; +public: + Test (const char *n) : _name (n) {} + const char *name () const { return _name; } + void f (int i, Complex c) {} + void run () { + Complex c = { 2.0, .5 }; + f (10, c); + } +}; + +aspect ContextTest { + pointcut _args(Complex _c, int _i) = args (_i, _c); + advice _args (c, i) && that (obj) : before (int i, Test *obj, Complex c) { + printf ("that: %s, int %d, Complex(%lf,%lf)\n", obj->name (), i, c.r, c.i); + } + advice args (i, c) && that (obj) : before (Test *obj, Complex c, int i) { + printf ("that: %s, int %d, Complex(%lf,%lf)\n", obj->name (), i, c.r, c.i); + } +}; + + +int main () { + Test t ("main()::t"); + printf ("Context information is requested by advice in arbitrary order:\n"); + printf ("==============================================================\n"); + t.run (); + printf ("==============================================================\n"); +} diff --git a/AspectC++/tests/DataFlowAnalysis/Makefile b/AspectC++/tests/DataFlowAnalysis/Makefile new file mode 100644 index 0000000..d54147b --- /dev/null +++ b/AspectC++/tests/DataFlowAnalysis/Makefile @@ -0,0 +1,2 @@ +ACFLAGS ?= --flow_analysis +include ../Makefile.generic diff --git a/AspectC++/tests/DataFlowAnalysis/feature.ref b/AspectC++/tests/DataFlowAnalysis/feature.ref new file mode 100644 index 0000000..ffa212b --- /dev/null +++ b/AspectC++/tests/DataFlowAnalysis/feature.ref @@ -0,0 +1,133 @@ +Function name="~Foo" +Function name="Foo" +Function name="Foo" +Function name="f" +Function name="g" +Function name="~RefToPtr" +Function name="RefToPtr" +Function name="RefToPtr" +Function name="f" +Function name="g" +Function name="~MyStaticContainer" +Function name="MyStaticContainer" +Function name="MyStaticContainer" +Function name="member_expressions" + target_object_lid="2" + target_object_lid="2" + target_object_lid="3" + target_object_lid="3" + target_object_lid="0" + target_object_lid="0" + target_object_lid="4" + target_object_lid="4" + target_object_lid="5" + target_object_lid="5" + target_object_lid="0" + target_object_lid="0" + target_object_lid="6" + target_object_lid="6" + target_object_lid="7" + target_object_lid="7" + target_object_lid="0" + target_object_lid="0" + target_object_lid="7" + target_object_lid="7" + target_object_lid="8" + target_object_lid="8" + target_object_lid="0" + target_object_lid="0" + target_object_lid="9" + target_object_lid="9" + target_object_lid="7" + target_object_lid="7" + target_object_lid="10" + target_object_lid="10" + target_object_lid="0" + target_object_lid="0" + target_object_lid="11" + target_object_lid="11" +Function name="for_loop_test" + target_object_lid="2" + target_object_lid="2" + target_object_lid="5" + target_object_lid="5" + target_object_lid="2" + target_object_lid="4" +Function name="do_while_loop_test" + target_object_lid="2" + target_object_lid="2" + target_object_lid="4" + target_object_lid="4" + target_object_lid="2" + target_object_lid="3" +Function name="while_loop_test" + target_object_lid="2" + target_object_lid="2" + target_object_lid="2" +Function name="addr_op_test" + target_object_lid="2" + target_object_lid="2" + target_object_lid="0" + target_object_lid="0" + target_object_lid="2" + target_object_lid="2" + target_object_lid="0" + target_object_lid="2" + target_object_lid="0" + target_object_lid="0" + target_object_lid="2" + target_object_lid="0" + target_object_lid="2" +Function name="ref_to_ptr_test" + target_object_lid="2" + target_object_lid="2" + target_object_lid="2" + target_object_lid="0" + target_object_lid="2" + target_object_lid="2" + target_object_lid="0" + target_object_lid="0" +Function name="nested_call_order" + target_object_lid="0" + target_object_lid="0" + target_object_lid="0" + target_object_lid="0" +Function name="conditional_operator" + target_object_lid="2" + target_object_lid="2" + target_object_lid="0" + target_object_lid="4" +Function name="compound_test" + target_object_lid="2" + target_object_lid="3" + target_object_lid="4" + target_object_lid="4" + target_object_lid="4" + target_object_lid="3" + target_object_lid="3" + target_object_lid="3" +Function name="increment_decrement_op" + target_object_lid="2" + target_object_lid="0" + target_object_lid="3" + target_object_lid="4" + target_object_lid="0" + target_object_lid="5" + target_object_lid="0" +Function name="global_pointer" + target_object_lid="2" + target_object_lid="3" + target_object_lid="0" + target_object_lid="4" + target_object_lid="0" + target_object_lid="5" + target_object_lid="6" +Function name="if_then_else_test" + target_object_lid="2" + target_object_lid="3" + target_object_lid="5" + target_object_lid="2" + target_object_lid="3" + target_object_lid="7" + target_object_lid="8" + target_object_lid="10" diff --git a/AspectC++/tests/DataFlowAnalysis/main.cc b/AspectC++/tests/DataFlowAnalysis/main.cc new file mode 100644 index 0000000..f3a9136 --- /dev/null +++ b/AspectC++/tests/DataFlowAnalysis/main.cc @@ -0,0 +1,387 @@ +namespace DataFlowAnalysis { + +//----------------------- Member Expression Test ------------------------------ + +class Foo { +public: + Foo& ref; + Foo* ptr; + Foo* const const_ptr; + Foo() : ref(*this), ptr(this), const_ptr(this) {} + + void f() {} + void g(Foo *ptr) {} +} foo; + +void member_expressions() { + foo.f(); // ID: 2 + foo.f(); // ID: 2 + + foo.ref.f(); // ID: 3 + foo.ref.f(); // ID: 3 + + foo.ptr->f(); // ID: 0 + foo.ptr->f(); // ID: 0 + + foo.const_ptr->f(); // ID: 4 + foo.const_ptr->f(); // ID: 4 + + foo.ref.ref.f(); // ID: 5 + foo.ref.ref.f(); // ID: 5 + + foo.ref.ptr->f(); // ID: 0 + foo.ref.ptr->f(); // ID: 0 + + foo.ref.const_ptr->f(); // ID: 6 + foo.ref.const_ptr->f(); // ID: 6 + + Foo* foo_ptr = new Foo(); + foo_ptr->f(); // ID: 7 + foo_ptr->f(); // ID: 7 + + foo_ptr->ref.f(); // ID: 0 + foo_ptr->ref.f(); // ID: 0 + + Foo* const foo_const_ptr = foo_ptr; + foo_const_ptr->f(); // ID: 7 + foo_const_ptr->f(); // ID: 7 + + foo_const_ptr->ref.f(); // ID: 8 + foo_const_ptr->ref.f(); // ID: 8 + + foo_const_ptr->ptr->f(); // ID: 0 + foo_const_ptr->ptr->f(); // ID: 0 + + foo_const_ptr->const_ptr->f(); // ID: 9 + foo_const_ptr->const_ptr->f(); // ID: 9 + + Foo& foo_ref = *foo_const_ptr; + foo_ref.f(); // ID: 7 + foo_ref.f(); // ID: 7 + + foo_ref.ref.f(); // ID: 10 + foo_ref.ref.f(); // ID: 10 + + foo_ref.ptr->f(); // ID: 0 + foo_ref.ptr->f(); // ID: 0 + + foo_ref.const_ptr->f(); // ID: 11 + foo_ref.const_ptr->f(); // ID: 11 +} + +//--------------------------- For-Loop Test ----------------------------------- + +void for_loop_test(int _a, char** _b) { + Foo b; + Foo* ptr = &b; + + b.f(); // ID: 2 + ptr->f(); // ID: 2 + + for(int i=0; i<10; i++) { + ptr->f(); // ID: 5 + ptr->f(); // ID: 5 + ptr++; + } + + b.f(); // ID: 2 + ptr->f(); // ID: 4 +} + +//------------------------- Do-While-Loop Test -------------------------------- + +void do_while_loop_test() { + Foo b; + Foo* ptr = &b; + + b.f(); // ID: 2 + ptr->f(); // ID: 2 + int i = 0; + + do { + i++; + ptr->f(); // ID: 4 + ptr->f(); // ID: 4 + ptr++; + } while (i<10); + + b.f(); // ID: 2 + ptr->f(); // ID: 3 +} + +//--------------------------- While-Loop Test --------------------------------- + +void while_loop_test(void* __ch_data, const char* __buf, int __len) +{ + Foo b; + b.f(); // ID: 2 + + while(__len-- > 0) + b.f(); // ID: 2 + + b.f(); // ID: 2 +} + +//-------------------------- Address-Operator-Test ---------------------------- + +void addr_op_test() { + Foo b; + Foo* ptr = &b; + + b.f(); // ID: 2 + ptr->f(); // ID: 2 + Foo *const * double_ptr = &ptr; // kills the pointer + + ptr->f(); // ID: 0 + (**double_ptr).f(); // ID: 0 + + Foo* ptr2 = &b; + ptr2->f(); // ID: 2 + ptr2->g( *(&ptr2) ); // ID: 2 + ptr2->f(); // ID: 0 + + Foo* ptr3 = &b; + (*(&ptr3))->f(); // ID: 2 + ptr3->f(); // ID: 0 + + Foo *ptr_a, *ptr_b; + ptr_a = &b; + ptr_b = *(&ptr_a); // kill the pointer and transfer its id + ptr_a->f(); // ID: 0 + ptr_b->f(); // ID: 2 + + Foo* ptr_c = *(&ptr_b); // kill the pointer and transfer its id + ptr_b->f(); // ID: 0 + ptr_c->f(); // ID: 2 +} + + +//---------------------- Reference-to-Pointer Test ---------------------------- + +class RefToPtr { +public: + int f(RefToPtr*& _ff) { return 0; } + void g() {}; +}; + +void ref_to_ptr_test() { + RefToPtr foo; + RefToPtr* ptr = &foo; + + foo.g(); // ID: 2 + ptr->g(); // ID: 2 + + ptr->f(ptr); // ID: 2 + ptr->g(); // ID: 0 + + RefToPtr* ptr2 = &foo; + ptr2->g(); // ID: 2 + + RefToPtr& ref = *ptr2; + ref.g(); // ID: 2 + + RefToPtr*& ref_to_ptr = ptr2; // kills the pointer + ptr2->g(); // ID: 0 + ref_to_ptr->g(); // ID: 0 +} + +//----------------------- Nested-Call-Order Test ------------------------------ + +void nested_call_order() { + Foo foo; + Foo* ptr = &foo; + + ptr->g( // ID: 0 + ( ptr->f(), // ID: 0 (or 2) + ptr->g(*(&ptr)), // ID: 0 (or 2) + ptr->f(), &foo) ); // ID: 0 +} + +//----------------------- Conditional-Operator Test --------------------------- + +void conditional_operator() { + Foo foo, foo2; + Foo* ptr = &foo; + Foo* ptr2 = &foo2; + (1 ? ptr : ptr2)->f(); // ID: 2 + Foo* ptr3 = (2 ? ptr : ptr2); + ptr3->f(); // ID: 2 + ( (&conditional_operator > &nested_call_order) ? ptr : ptr2)->f(); // ID: 0 + ptr3 = ( (&conditional_operator > &nested_call_order) ? ptr : ptr2); + ptr3->f(); // ID: 4 +} + +//--------------------------- Compound Test ----------------------------------- + +void compound_test(Foo* param) { + param->f(); // ID: 2 + + Foo foo, foo2; + (foo.f(), // ID: 3 + foo2).f(); // ID: 4 + + Foo* ptr = &foo; + (ptr = &foo2)->f(); // ID: 4 + ptr->f(); // ID: 4 + + Foo *ptr2, *ptr3; + ptr = ptr2 = ptr3 = &foo; + ptr->f(); // ID: 3 + ptr2->f(); // ID: 3 + ptr3->f(); // ID: 3 +} + +//--------------------------- Increment/Decrement Test ------------------------ + +void increment_decrement_op() { + Foo array[2]; + Foo* ptr_1 = &array[0]; + ptr_1->f(); // ID: 2 + (ptr_1++)->f(); // ID: 0 + ptr_1->f(); // ID: 3 + + Foo* ptr_2 = &array[1]; + ptr_2->f(); // ID: 4 + (--ptr_2)->f(); // ID: 0 + ptr_2->f(); // ID: 5 + + (ptr_2+1)->f(); // ID: 0 +} + +//-------------------------------- Global-Pointer Test ------------------------ + +Foo glob; +Foo& glob_ref = glob; +Foo* glob_ptr = &glob; +Foo* const glob_const_ptr = &glob; + +class MyStaticContainer { +public: + static Foo* ptr; + static Foo* const const_ptr; + static Foo& ref; +}; + +Foo* MyStaticContainer::ptr = &glob; +Foo* const MyStaticContainer::const_ptr = &glob; +Foo& MyStaticContainer::ref = glob; + +void global_pointer() { + glob.f(); // ID: 2 + glob_ref.f(); // ID: 3 + glob_ptr->f(); // ID: 0 + glob_const_ptr->f(); // ID: 4 + + MyStaticContainer::ptr->f(); // ID: 0 + MyStaticContainer::const_ptr->f(); // ID: 5 + MyStaticContainer::ref.f(); // ID: 6 +} + +//----------------------------- If-Then-Else Test ----------------------------- + +void if_then_else_test() { + Foo foo1; + Foo foo2; + Foo* ptr = 0; + if (&increment_decrement_op > &global_pointer) { + ptr = &foo1; + ptr->f(); // ID: 2 + } + else { + ptr = &foo2; + ptr->f(); // ID: 3 + } + ptr->f(); // ID: 5 + + for(int i=0; i<10; ++i) { + ptr = 0; + if (&increment_decrement_op < &global_pointer) { + ptr = &foo1; + ptr->f(); // ID: 2 + } + else { + ptr = &foo2; + ptr->f(); // ID: 3 + } + ptr->f(); // ID: 7 + } + ptr->f(); // ID: 8 + + ptr = &foo1; + if (&increment_decrement_op > &global_pointer) { + goto set; + } + else { + goto exec; + } +set: + ptr = &foo2; +exec: + ptr->f(); // ID: 10 +} + +} // namespace DataFlowAnalysis + + +//-------------------------- Print project model ------------------------------ + +#include +#include +#include +#include + +int main() { + std::ifstream input("repo.acp"); + std::string line; + + bool namespace_dflow = false; + + while ( std::getline( input, line ) ) { + + if ( (line.find("Namespace") != std::string::npos) && + (line.find("name=") != std::string::npos) ) { + if ( line.find("\"DataFlowAnalysis\"") != std::string::npos ) + namespace_dflow = true; + else + namespace_dflow = false; + } + + if (namespace_dflow) { + // print function name + if (line.find(" + +using namespace std; + +static const int MaxBufferSize = 1024000; + +const int getMBS() { return MaxBufferSize; } + +class Connection +{ +public: + int readDataIntoBuffer(int maxSize = getMBS() ); +}; + +int Connection::readDataIntoBuffer(int maxSize) +{ + if (maxSize > MaxBufferSize) + return 0; + + return 10; +} + +int main() { + int x = 42; + Connection con; + + x = con.readDataIntoBuffer(); + cout << x << endl; + + x = con.readDataIntoBuffer( 2048000 ); + cout << x << endl; + + return 0; +} + +aspect TestExecution { + advice call("const int getMBS()") : before() { + cout << " call " << JoinPoint::signature() << endl; + } +}; diff --git a/AspectC++/tests/DefaultArgs2/Makefile b/AspectC++/tests/DefaultArgs2/Makefile new file mode 100644 index 0000000..daa5e9e --- /dev/null +++ b/AspectC++/tests/DefaultArgs2/Makefile @@ -0,0 +1,2 @@ +ACFLAGS ?= --builtin_operators --data_joinpoints +include ../Makefile.generic diff --git a/AspectC++/tests/DefaultArgs2/feature.ref b/AspectC++/tests/DefaultArgs2/feature.ref new file mode 100644 index 0000000..34362a9 --- /dev/null +++ b/AspectC++/tests/DefaultArgs2/feature.ref @@ -0,0 +1,8 @@ + call const int getMBS() + get const int MaxBufferSize + get const int MaxBufferSize + builtin int operator +(int,int) + get const int MaxBufferSize +0 + get const int MaxBufferSize +10 diff --git a/AspectC++/tests/DefaultArgs2/main.cc b/AspectC++/tests/DefaultArgs2/main.cc new file mode 100644 index 0000000..52c0cc8 --- /dev/null +++ b/AspectC++/tests/DefaultArgs2/main.cc @@ -0,0 +1,48 @@ +#include + +using namespace std; + +static const int MaxBufferSize = 1024000; + +const int getMBS() { return MaxBufferSize; } + +class Connection +{ +public: + int readDataIntoBuffer(int maxSize = MaxBufferSize + getMBS() ); +}; + +int Connection::readDataIntoBuffer(int maxSize) +{ + if (maxSize > MaxBufferSize) + return 0; + + return 10; +} + +int main() { + int x = 42; + Connection con; + + x = con.readDataIntoBuffer(); + cout << x << endl; + + x = con.readDataIntoBuffer( 1024 ); + cout << x << endl; + + return 0; +} + +aspect TestExecution { + advice call("const int getMBS()") : before() { + cout << " call " << JoinPoint::signature() << endl; + } + + advice builtin("int operator +(int,int)") : before() { + cout << " builtin " << JoinPoint::signature() << endl; + } + + advice get("const int MaxBufferSize") : before () { + cout << " get " << JoinPoint::signature() << endl; + } +}; diff --git a/AspectC++/tests/Derived/Makefile b/AspectC++/tests/Derived/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Derived/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Derived/feature.ref b/AspectC++/tests/Derived/feature.ref new file mode 100644 index 0000000..d7c9af9 --- /dev/null +++ b/AspectC++/tests/Derived/feature.ref @@ -0,0 +1,20 @@ +Derived: test the 'derived' pointcut function: +============================================== + void C1::f(double) +---------------------------------------------- + void C1::f() +---------------------------------------------- + before derived("C2") + before derived("% C2::f(double)") + void C2::f(double) +---------------------------------------------- + before derived("C2") + void C3::f() +---------------------------------------------- + before derived("C2") + before derived("% C2::f(X&)") + void C3::f(X&) +---------------------------------------------- + before derived("C2") + void C3::x() +============================================== diff --git a/AspectC++/tests/Derived/main.cc b/AspectC++/tests/Derived/main.cc new file mode 100644 index 0000000..240a29c --- /dev/null +++ b/AspectC++/tests/Derived/main.cc @@ -0,0 +1,80 @@ +#include + +struct X { + X () {} +}; + +struct C1 { + void x () { + printf (" void C1::x()\n"); + } + void f () { + printf (" void C1::f()\n"); + } + void f (double) { + printf (" void C1::f(double)\n"); + } + void f (const X&) { + printf (" void C1::f(X&)\n"); + } +}; + +struct C2 : C1 { + void x () { + printf (" void C2::x()\n"); + } + void f () { + printf (" void C2::f()\n"); + } + void f (double) { + printf (" void C2::f(double)\n"); + } + void f (const X&) { + printf (" void C2::f(X&)\n"); + } +}; + +struct C3 : C2 { + void x () { + printf (" void C3::x()\n"); + } + void f () { + printf (" void C3::f()\n"); + } + void f (double) { + printf (" void C3::f(double)\n"); + } + void f (const X&) { + printf (" void C3::f(X&)\n"); + } +}; + +aspect Tracer { + advice execution (derived ("C2")) : before () { + printf (" before derived(\"C2\")\n"); + } + advice execution (derived ("% C2::f(double)")) : before () { + printf (" before derived(\"%% C2::f(double)\")\n"); + } + advice execution (derived ("% C2::f(X&)")) : before () { + printf (" before derived(\"%% C2::f(X&)\")\n"); + } +}; + +int main() { + C3 c; + printf ("Derived: test the 'derived' pointcut function:\n"); + printf ("==============================================\n"); + c.C1::f (3.0); + printf ("----------------------------------------------\n"); + c.C1::f (); + printf ("----------------------------------------------\n"); + c.C2::f (3.0); + printf ("----------------------------------------------\n"); + c.C3::f (); + printf ("----------------------------------------------\n"); + c.C3::f (X ()); + printf ("----------------------------------------------\n"); + c.C3::x (); + printf ("==============================================\n"); +} diff --git a/AspectC++/tests/DisjointIds/Makefile b/AspectC++/tests/DisjointIds/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/DisjointIds/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/DisjointIds/a.ah b/AspectC++/tests/DisjointIds/a.ah new file mode 100644 index 0000000..9321994 --- /dev/null +++ b/AspectC++/tests/DisjointIds/a.ah @@ -0,0 +1,72 @@ +#ifndef __a_ah__ +#define __a_ah__ + +#include + +namespace coveragemonitor { + // data structure used to gather information about a joinpoint + struct Data { + unsigned _id; + }; + + // data structure used to link the joinpoint data elements + struct Chain { + static Chain *&_first () { static Chain *chain = 0; return chain; } + Data *_data; + Chain *_next; + Chain (Data *data) : _data (data) { + Chain *head = _first (); + _first () = this; + _next = head; + } + }; + + // data structure used to combine data and chain elements + template + struct Collector { + static Data _data; + static Chain _chain; + }; + + template Data Collector::_data = { ID }; + template Chain Collector::_chain (&_data); + +} // coveragemonitor + + + +aspect IdChecker { + advice execution ("% ...::%(...)" && !("% IdChecker::%(...)" || "% coveragemonitor::...::%(...)") ) : after () { + using namespace coveragemonitor; + typedef Collector Collector; + + // As the compiler recognizes the access to the elements of + // Collector it will create a template instance + // for all joinpoints - even for those that will never be + // visited. + // It is necessary to explicitly mention the _chain element + // here otherwise the compiler will not instantiate + // any Chain elements. + Collector::_chain._data->_id = JoinPoint::JPID; + } + + advice execution ("% main(...)") : after() { + coveragemonitor::Chain *first = coveragemonitor::Chain::_first(); // remember starting point + unsigned count = 0; + + for (coveragemonitor::Chain *i = first; i; i = i->_next) { + count++; + for (coveragemonitor::Chain *j = first; j; j = j->_next) { + if( (i != j) && (i->_data->_id == j->_data->_id) ) { + printf("Error: duplicate JPID found: %u\n", j->_data->_id); + } + } + } + if(count < 4) { + printf("Error: only %u disjoint JPID(s) found (min 4 required)\n", count); + } + } + +}; + +#endif // __a_ah__ diff --git a/AspectC++/tests/DisjointIds/feature.ref b/AspectC++/tests/DisjointIds/feature.ref new file mode 100644 index 0000000..35a37ba --- /dev/null +++ b/AspectC++/tests/DisjointIds/feature.ref @@ -0,0 +1,3 @@ +DisjointIds: checks whether JPID are disjoint +============================================= +============================================= diff --git a/AspectC++/tests/DisjointIds/main.cc b/AspectC++/tests/DisjointIds/main.cc new file mode 100644 index 0000000..98ca645 --- /dev/null +++ b/AspectC++/tests/DisjointIds/main.cc @@ -0,0 +1,14 @@ +#include + +void f1() {} +void f2(); +void f3() {} + +int main () { + printf ("DisjointIds: checks whether JPID are disjoint\n"); + printf ("=============================================\n"); + f1 (); + f2 (); + f3 (); + printf ("=============================================\n"); +} diff --git a/AspectC++/tests/DisjointIds/other.cc b/AspectC++/tests/DisjointIds/other.cc new file mode 100644 index 0000000..8ccc02b --- /dev/null +++ b/AspectC++/tests/DisjointIds/other.cc @@ -0,0 +1 @@ +void f2() {} diff --git a/AspectC++/tests/Empty/Makefile b/AspectC++/tests/Empty/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Empty/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Empty/empty.cc b/AspectC++/tests/Empty/empty.cc new file mode 100644 index 0000000..e69de29 diff --git a/AspectC++/tests/Empty/feature.ref b/AspectC++/tests/Empty/feature.ref new file mode 100644 index 0000000..e69de29 diff --git a/AspectC++/tests/Empty/main.cc b/AspectC++/tests/Empty/main.cc new file mode 100644 index 0000000..ca2ac4a --- /dev/null +++ b/AspectC++/tests/Empty/main.cc @@ -0,0 +1 @@ +int main () {} diff --git a/AspectC++/tests/ExecAdviceFriend/Makefile b/AspectC++/tests/ExecAdviceFriend/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/ExecAdviceFriend/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/ExecAdviceFriend/feature.ref b/AspectC++/tests/ExecAdviceFriend/feature.ref new file mode 100644 index 0000000..505e08b --- /dev/null +++ b/AspectC++/tests/ExecAdviceFriend/feature.ref @@ -0,0 +1,6 @@ +before exec int main() +ExecAdviceFriend: advice for func declared as a friend only +=========================================================== +before exec int myfunc(void *,int) +myfunc() running +=========================================================== diff --git a/AspectC++/tests/ExecAdviceFriend/main.cc b/AspectC++/tests/ExecAdviceFriend/main.cc new file mode 100644 index 0000000..beaf4b0 --- /dev/null +++ b/AspectC++/tests/ExecAdviceFriend/main.cc @@ -0,0 +1,27 @@ +#include + +class something { +public: + friend int myfunc(void *, int); +}; + +int myfunc(void *, int) { + printf("myfunc() running\n"); + return 0; +} + +aspect Trace { +public: + advice execution("% ...::%(...)") : before() { + printf ("before exec %s\n", JoinPoint::signature()); + } +}; + +int main() { + printf ("ExecAdviceFriend: advice for func declared as a friend only\n"); + printf ("===========================================================\n"); + myfunc (0, 0); + printf ("===========================================================\n"); + // problem: advice for main does not auto-generate return 0! + return 0; +} diff --git a/AspectC++/tests/ExecAdviceNewDelete/Makefile b/AspectC++/tests/ExecAdviceNewDelete/Makefile new file mode 100644 index 0000000..da73ec2 --- /dev/null +++ b/AspectC++/tests/ExecAdviceNewDelete/Makefile @@ -0,0 +1,2 @@ +AC_PATTERN_REPLACEMENTS := | sed -e "s/new(.*)/new(<<>>)/" | sed -e "s/new\[\](.*)/new[](<<>>)/" +include ../Makefile.generic diff --git a/AspectC++/tests/ExecAdviceNewDelete/feature.ref b/AspectC++/tests/ExecAdviceNewDelete/feature.ref new file mode 100644 index 0000000..a8d0c4a --- /dev/null +++ b/AspectC++/tests/ExecAdviceNewDelete/feature.ref @@ -0,0 +1,19 @@ +ExecAdviceNewDelete: execution advice for heap operations +========================================================= +executing heap operation "void *C::operator new(<<>>)" + tjp->that() is 0 (should be 0) +executing heap operation "void C::operator delete(void *)" + tjp->that() is 0 (should be 0) +executing heap operation "void *operator new(<<>>)" + tjp->that() is 0 (should be 0) +executing heap operation "void operator delete(void *)" + tjp->that() is 0 (should be 0) +executing heap operation "void *operator new[](<<>>)" + tjp->that() is 0 (should be 0) +executing heap operation "void operator delete[](void *)" + tjp->that() is 0 (should be 0) +executing heap operation "void *operator new(<<>>)" + tjp->that() is 0 (should be 0) +executing heap operation "void A::operator delete(void *)" + tjp->that() is 0 (should be 0) +========================================================= diff --git a/AspectC++/tests/ExecAdviceNewDelete/main.cc b/AspectC++/tests/ExecAdviceNewDelete/main.cc new file mode 100644 index 0000000..99ef92b --- /dev/null +++ b/AspectC++/tests/ExecAdviceNewDelete/main.cc @@ -0,0 +1,66 @@ +#include +#include +#include + +void *operator new (size_t ) throw(std::bad_alloc); + +void *operator new (size_t s) throw(std::bad_alloc) { + return malloc (s); +} + +void *operator new[] (size_t s) throw(std::bad_alloc) { + return malloc (s); +} + +void operator delete (void *obj) throw() { + free (obj); +} + +void operator delete[] (void *obj) throw() { + free (obj); +} + +struct A { // bug 517 + /*static*/ void operator delete(void* ptr) throw (); // bug 517 was: fails without 'static' +}; + +void A::operator delete (void* ptr) throw() {} + + +class C { +public: + void f () {} + + // we always use the same C instance + void *operator new (size_t) { + static C c; + return &c; + } + void operator delete (void *) { + } + +}; + +#define STRING(x) #x + +aspect HeapSurveillance { + advice execution ("% ...::operator new(...)" || + "% ...::operator delete(...)" || + "% ...::operator new[](...)" || + "% ...::operator delete[](...)") : before () { + printf ("executing heap operation \"%s\"\n", JoinPoint::signature ()); + printf (" tjp->that() is %s (should be 0)\n", (tjp->that () ? "not 0" : "0")); + } +}; + +int main () { + printf ("ExecAdviceNewDelete: execution advice for heap operations\n"); + printf ("=========================================================\n"); + C *c = new C; + c->f (); + delete c; + delete new int; + delete[] new double[20]; + delete new A; + printf ("=========================================================\n"); +} diff --git a/AspectC++/tests/ExecAdviceRecursive/Makefile b/AspectC++/tests/ExecAdviceRecursive/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/ExecAdviceRecursive/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/ExecAdviceRecursive/feature.ref b/AspectC++/tests/ExecAdviceRecursive/feature.ref new file mode 100644 index 0000000..1e2b082 --- /dev/null +++ b/AspectC++/tests/ExecAdviceRecursive/feature.ref @@ -0,0 +1,15 @@ +ExecAdviceRecursive: checks exec advice for recursive fcts +========================================================== +before int fak1(int) +before int fak1(int) +around-before int fak2(int) +around-before int fak2(int) +around-before int fak2(int) +around-after int fak2(int) +around-after int fak2(int) +around-after int fak2(int) +after int N::fak3(int) +after int N::fak3(int) +after int N::fak3(int) +after int N::fak3(int) +========================================================== diff --git a/AspectC++/tests/ExecAdviceRecursive/main.cc b/AspectC++/tests/ExecAdviceRecursive/main.cc new file mode 100644 index 0000000..46179f9 --- /dev/null +++ b/AspectC++/tests/ExecAdviceRecursive/main.cc @@ -0,0 +1,47 @@ +#include + +int fak2 (int n); + +namespace N { + int fak3 (int n); +} + +#ifdef XXXXXXXXXXXX +XYZ +#else +int fak1 (int n) +#endif +{ + return (n <= 1) ? 1 : n * fak1 (n - 1); +} + +int fak2 (int n) { + return (n <= 1) ? 1 : n * fak2 (n - 1); +} + +int N::fak3 (int n) { + return (n <= 1) ? 1 : n * fak3 (n - 1); +} + +aspect Tracer { + advice execution ("% ...::fak1(...)") : before () { + printf ("before %s\n", JoinPoint::signature ()); + } + advice execution ("% ...::fak2(...)") : around () { + printf ("around-before %s\n", JoinPoint::signature ()); + tjp->proceed (); + printf ("around-after %s\n", JoinPoint::signature ()); + } + advice execution ("% ...::fak3(...)") : after () { + printf ("after %s\n", JoinPoint::signature ()); + } +}; + +int main() { + printf ("ExecAdviceRecursive: checks exec advice for recursive fcts\n"); + printf ("==========================================================\n"); + fak1 (2); + fak2 (3); + N::fak3 (4); + printf ("==========================================================\n"); +} diff --git a/AspectC++/tests/ExternC/Makefile b/AspectC++/tests/ExternC/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/ExternC/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/ExternC/feature.ref b/AspectC++/tests/ExternC/feature.ref new file mode 100644 index 0000000..93acfa0 --- /dev/null +++ b/AspectC++/tests/ExternC/feature.ref @@ -0,0 +1,35 @@ +ExternC: advice for call/exec of extern "C" functions +======================================================= +call "void b(char,const char *)" +exec "void b(char,const char *)" +b(H, ello World) +------------------------------------------------------- +call "void d(char,const char *)" +exec "void d(char,const char *)" +d(H, ello World) +call "void b(char,const char *)" +exec "void b(char,const char *)" +b(H, ello World) +------------------------------------------------------- +call "void b2(char,const char *)" +exec "void b2(char,const char *)" +b2(H, ello World) +------------------------------------------------------- +call "void d2(char,const char *)" +exec "void d2(char,const char *)" +d2(H, ello World) +call "void b2(char,const char *)" +exec "void b2(char,const char *)" +b2(H, ello World) +------------------------------------------------------- +call "void b3(char,const char *)" +exec "void b3(char,const char *)" +b3(H, ello World) +------------------------------------------------------- +call "void d3(char,const char *)" +exec "void d3(char,const char *)" +d3(H, ello World) +call "void b3(char,const char *)" +exec "void b3(char,const char *)" +b3(H, ello World) +======================================================= diff --git a/AspectC++/tests/ExternC/main.cc b/AspectC++/tests/ExternC/main.cc new file mode 100644 index 0000000..e139e48 --- /dev/null +++ b/AspectC++/tests/ExternC/main.cc @@ -0,0 +1,67 @@ +#include + +extern "C" void b(char c, const char *str); + +void b(char c, const char *str) { + printf("b(%c, %s)\n", c, str); +} + +extern "C" void d(char c, const char *str) { + printf("d(%c, %s)\n", c, str); + b (c, str); +} + +extern "C" { + void b2(char c, const char *str); + + void b2(char c, const char *str) { + printf("b2(%c, %s)\n", c, str); + } + + void d2(char c, const char *str) { + printf("d2(%c, %s)\n", c, str); + b2 (c, str); + } +} + +extern "C" { + extern "C" { + extern "C" void b3(char c, const char *str); + + extern "C" void b3(char c, const char *str) { + printf("b3(%c, %s)\n", c, str); + } + + extern "C" void d3(char c, const char *str) { + printf("d3(%c, %s)\n", c, str); + b3 (c, str); + } + } +} + +aspect Trace { + pointcut fcts() = "% b(...)" || "% d(...)" || "% b2(...)" || "% d2(...)" || "% b3(...)" || "% d3(...)"; + advice execution (fcts ()) : before () { + printf ("exec \"%s\"\n", JoinPoint::signature ()); + } + advice call (fcts ()) : before () { + printf ("call \"%s\"\n", JoinPoint::signature ()); + } +}; + +int main() { + printf ("ExternC: advice for call/exec of extern \"C\" functions\n"); + printf ("=======================================================\n"); + b('H', "ello World"); + printf ("-------------------------------------------------------\n"); + d('H', "ello World"); + printf ("-------------------------------------------------------\n"); + b2('H', "ello World"); + printf ("-------------------------------------------------------\n"); + d2('H', "ello World"); + printf ("-------------------------------------------------------\n"); + b3('H', "ello World"); + printf ("-------------------------------------------------------\n"); + d3('H', "ello World"); + printf ("=======================================================\n"); +} diff --git a/AspectC++/tests/Float128Basic/Makefile b/AspectC++/tests/Float128Basic/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Float128Basic/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Float128Basic/feature.ref b/AspectC++/tests/Float128Basic/feature.ref new file mode 100644 index 0000000..df3b21f --- /dev/null +++ b/AspectC++/tests/Float128Basic/feature.ref @@ -0,0 +1,4 @@ +call +16 +16 +16 diff --git a/AspectC++/tests/Float128Basic/main.cc b/AspectC++/tests/Float128Basic/main.cc new file mode 100644 index 0000000..bcf52dc --- /dev/null +++ b/AspectC++/tests/Float128Basic/main.cc @@ -0,0 +1,58 @@ +// Basic __float128 test. Types/Signatures differ between clang >= 3.9.1 +// and clang < 3.9.1 due to imitated __float128 type. + +#include +using namespace std; + +class Test { + public: + __float128 member; + + __float128* mf(__float128& p) { + return &p; + } + + Test(__float128 p) : member(p) { + + } +}; + +template +class TestTemplate { + public: + T template_member; +}; + +__float128 global_float = 242424.2424; + +int main() { + Test t(213.4124); + t.member = 2323.42452; + __float128* fp = t.mf(t.member); + + TestTemplate<__float128> tt; + tt.template_member = 242424.2424; + + cout << sizeof(__float128) << endl; + cout << sizeof(tt.template_member) << endl; + cout << sizeof(*fp) << endl; + + __float128 result = tt.template_member + *fp; + result = result - *fp; + result = result * tt.template_member; + result = result / *fp; + result += *fp; + result -= *fp; + result *= *fp; + result /= *fp; +} + + +aspect A { + // TODO: Weaving does not work if " || builtin("% ...::%(...)")" is added + advice (call("% ...::%(...)") && !call("% std::...::%(...)")) : before() { + // TODO: Signature is not consistent over clang versions + cout << "call" << endl; + } +}; + diff --git a/AspectC++/tests/ForcedInclude/Makefile b/AspectC++/tests/ForcedInclude/Makefile new file mode 100644 index 0000000..f952cdd --- /dev/null +++ b/AspectC++/tests/ForcedInclude/Makefile @@ -0,0 +1,2 @@ +ACFLAGS ?= --include config.h +include ../Makefile.generic diff --git a/AspectC++/tests/ForcedInclude/config.h b/AspectC++/tests/ForcedInclude/config.h new file mode 100644 index 0000000..e5ac875 --- /dev/null +++ b/AspectC++/tests/ForcedInclude/config.h @@ -0,0 +1,6 @@ +#ifndef __CONFIG_H__ +#define __CONFIG_H__ + +typedef int INT; + +#endif // __CONFIG_H__ diff --git a/AspectC++/tests/ForcedInclude/feature.ref b/AspectC++/tests/ForcedInclude/feature.ref new file mode 100644 index 0000000..4737b9d --- /dev/null +++ b/AspectC++/tests/ForcedInclude/feature.ref @@ -0,0 +1,4 @@ +ForcedInclude: check if --include works +============================================================= +fine if it compiles +============================================================= diff --git a/AspectC++/tests/ForcedInclude/main.cc b/AspectC++/tests/ForcedInclude/main.cc new file mode 100644 index 0000000..43ef23e --- /dev/null +++ b/AspectC++/tests/ForcedInclude/main.cc @@ -0,0 +1,9 @@ +#include + +// INT is defined in config.h which is included by the forced include +INT main () { + printf ("ForcedInclude: check if --include works\n"); + printf ("=============================================================\n"); + printf ("fine if it compiles\n"); + printf ("=============================================================\n"); +} diff --git a/AspectC++/tests/Forward/Aspect.ah b/AspectC++/tests/Forward/Aspect.ah new file mode 100644 index 0000000..ffafaa3 --- /dev/null +++ b/AspectC++/tests/Forward/Aspect.ah @@ -0,0 +1,23 @@ +#ifndef __Aspect_ah__ +#define __Aspect_ah__ + +#include +#include "Forward.h" + +aspect Aspect { + pointcut both () = "Forward"||"Backward"; + advice both () : slice class { + int _val; + public: + void introduced () { + _val = 0; + } + }; + advice within (both ()) && execution ("% %::introduced()") && + that (fwd) : before (Forward *fwd) { + printf ("before %s\n", JoinPoint::signature ()); + fwd->needed_by_aspect (); + } +}; + +#endif // __Aspect_ah__ diff --git a/AspectC++/tests/Forward/Forward.h b/AspectC++/tests/Forward/Forward.h new file mode 100644 index 0000000..d8673bf --- /dev/null +++ b/AspectC++/tests/Forward/Forward.h @@ -0,0 +1,8 @@ +#ifndef __Forward_h__ +#define __Forward_h__ + +class Forward { + void needed_by_aspect () {} +}; + +#endif // __Forward_h__ diff --git a/AspectC++/tests/Forward/Makefile b/AspectC++/tests/Forward/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Forward/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Forward/feature.ref b/AspectC++/tests/Forward/feature.ref new file mode 100644 index 0000000..a652525 --- /dev/null +++ b/AspectC++/tests/Forward/feature.ref @@ -0,0 +1,2 @@ +before void Forward::introduced() +before void Backward::introduced() diff --git a/AspectC++/tests/Forward/main.cc b/AspectC++/tests/Forward/main.cc new file mode 100644 index 0000000..2418761 --- /dev/null +++ b/AspectC++/tests/Forward/main.cc @@ -0,0 +1,15 @@ +#include "Forward.h" + +class Backward : public Forward { +public: + void run () { + Forward::introduced (); + introduced (); + } +}; + +int main () { + Backward b; + b.run (); + return 0; +} diff --git a/AspectC++/tests/FunctionEntity/Makefile b/AspectC++/tests/FunctionEntity/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/FunctionEntity/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/FunctionEntity/feature.ref b/AspectC++/tests/FunctionEntity/feature.ref new file mode 100644 index 0000000..37c4cbf --- /dev/null +++ b/AspectC++/tests/FunctionEntity/feature.ref @@ -0,0 +1,53 @@ +Construction of T1::T1() + memberptr: 0 + entity: 0 + +FUNC-ENTITY: + +FUNC_NM: +self: FUNC_NM +After execution: int FUNC_NM(int,int) +self: FUNC_NM +After call: int FUNC_NM(int,int) +self: FUNC_NM +After execution: int FUNC_NM(int,int) +self: FUNC_NM + +FUNC_SM (1): +self: FUNC_SM +After execution: int T1::FUNC_SM(int,int) +self: FUNC_SM +After call: int T1::FUNC_SM(int,int) +self: FUNC_SM +After execution: int T1::FUNC_SM(int,int) +self: FUNC_SM + +FUNC_SM (2): +self: FUNC_SM +After execution: int T1::FUNC_SM(int,int) +self: FUNC_SM +After call: int T1::FUNC_SM(int,int) +self: FUNC_SM +After execution: int T1::FUNC_SM(int,int) +self: FUNC_SM + +FUNC_OM: +self: FUNC_OM +After execution: int T1::FUNC_OM(int,int) +self: FUNC_OM +After call: int T1::FUNC_OM(int,int) +self: FUNC_OM +After execution: int T1::FUNC_OM(int,int) +self: FUNC_OM + +FUNC_VM: +self: FUNC_VM +After execution: int T1::FUNC_VM(int,int) +self: FUNC_VM +After call: int T1::FUNC_VM(int,int) +self: FUNC_VM +After execution: int T1::FUNC_VM(int,int) +self: FUNC_VM +Destruction of T1::~T1() + memberptr: 0 + entity: 0 diff --git a/AspectC++/tests/FunctionEntity/main.cc b/AspectC++/tests/FunctionEntity/main.cc new file mode 100644 index 0000000..babb4f4 --- /dev/null +++ b/AspectC++/tests/FunctionEntity/main.cc @@ -0,0 +1,91 @@ +#include + +using namespace std; + +int FUNC_NM( int a, int b ) { + cout << "self: FUNC_NM" << endl; + return a * 4 + b; +} + +class T1 { +public: + static int FUNC_SM( int a, int b ) { + cout << "self: FUNC_SM" << endl; + return a * 7 - b; + } + + int FUNC_OM( int a, int b ) { + cout << "self: FUNC_OM" << endl; + return a * -1 + 10 * b; + } + + virtual int FUNC_VM( int a, int b ) { + cout << "self: FUNC_VM" << endl; + return a * -5 + 12 * b; + } +}; + +int main() { + int b; + T1 o; + + cout << endl << "FUNC-ENTITY:" << endl; + + cout << endl << "FUNC_NM:" << endl; + b = FUNC_NM( 1, 2 ); + + cout << endl << "FUNC_SM (1):" << endl; + b = T1::FUNC_SM( 1, 2 ); + + cout << endl << "FUNC_SM (2):" << endl; + b = o.FUNC_SM( 1, 2 ); + + cout << endl << "FUNC_OM:" << endl; + b = o.FUNC_OM( 1, 2 ); + + cout << endl << "FUNC_VM:" << endl; + b = o.FUNC_VM( 1, 2 ); + + return 0; +} + +template int call_member( TARGET *t, MEMBER m ) { + return (t->*m)( 1, 2 ); +} + +template int call_member( TARGET *t, void * ) { return 0; } + +aspect FuncTest { + advice call("int ...::FUNC%( int, int )") : after() { + cout << "After call: " << tjp->signature() << endl; + if( tjp->entity() ) + int r = tjp->entity()( 1, 2 ); + if( tjp->memberptr() ) + int r = call_member( tjp->target(), tjp->memberptr() ); + } + + advice execution("int ...::FUNC%( int, int )") : after() { + static bool recursion = false; + if (!recursion) { + cout << "After execution: " << tjp->signature() << endl; + recursion = true; + if( tjp->entity() ) + int r = tjp->entity()( 1, 2 ); + if( tjp->memberptr() ) + int r = call_member( tjp->target(), tjp->memberptr() ); + recursion = false; + } + } + + advice construction("T%") : before() { + cout << "Construction of " << tjp->signature() << endl; + cout << " memberptr: " << (void*)tjp->memberptr() << endl; + cout << " entity: " << (void*)tjp->entity() << endl; + } + + advice destruction("T%") : before() { + cout << "Destruction of " << tjp->signature() << endl; + cout << " memberptr: " << (void*)tjp->memberptr() << endl; + cout << " entity: " << (void*)tjp->entity() << endl; + } +}; diff --git a/AspectC++/tests/GetBaseDerived/Makefile b/AspectC++/tests/GetBaseDerived/Makefile new file mode 100644 index 0000000..daa5e9e --- /dev/null +++ b/AspectC++/tests/GetBaseDerived/Makefile @@ -0,0 +1,2 @@ +ACFLAGS ?= --builtin_operators --data_joinpoints +include ../Makefile.generic diff --git a/AspectC++/tests/GetBaseDerived/feature.ref b/AspectC++/tests/GetBaseDerived/feature.ref new file mode 100644 index 0000000..bd0eeb8 --- /dev/null +++ b/AspectC++/tests/GetBaseDerived/feature.ref @@ -0,0 +1,11 @@ +get: int A::a = 1 +get: int B::b = 2 +derived from "B": int B::b = 2 +derived from "B::b": int B::b = 2 +get: int C::c = 3 +derived from "B": int C::c = 3 +get: int D::d = 4 +derived from "B": int D::d = 4 +get: int D::b = 5 +derived from "B": int D::b = 5 +derived from "B::b": int D::b = 5 diff --git a/AspectC++/tests/GetBaseDerived/main.cc b/AspectC++/tests/GetBaseDerived/main.cc new file mode 100644 index 0000000..338b8df --- /dev/null +++ b/AspectC++/tests/GetBaseDerived/main.cc @@ -0,0 +1,44 @@ +#include + +struct A { + int a; + A() { a = 1; } +}; + +struct B : public A { + int b; + B() { b = 2; } +}; + +struct C : public B { + int c; + C() { c = 3; } +}; + +struct D : public C { + int d; + int b; + D() { d = 4; b = 5; } +}; + +int main () { + D obj; + int v; + v = obj.a; + v = obj.B::b; + v = obj.c; + v = obj.d; + v = obj.b; +} + +aspect Test { + advice get("%") : before () { + printf ("get: %s = %i\n", JoinPoint::signature (), *tjp->entity()); + } + advice get(derived("B")) : before () { + printf ("derived from \"B\": %s = %i\n", JoinPoint::signature (), *tjp->entity()); + } + advice get(derived("% B::b")) : before () { + printf ("derived from \"B::b\": %s = %i\n", JoinPoint::signature (), *tjp->entity()); + } +}; diff --git a/AspectC++/tests/GetConditional/Makefile b/AspectC++/tests/GetConditional/Makefile new file mode 100644 index 0000000..daa5e9e --- /dev/null +++ b/AspectC++/tests/GetConditional/Makefile @@ -0,0 +1,2 @@ +ACFLAGS ?= --builtin_operators --data_joinpoints +include ../Makefile.generic diff --git a/AspectC++/tests/GetConditional/feature.ref b/AspectC++/tests/GetConditional/feature.ref new file mode 100644 index 0000000..0238f97 --- /dev/null +++ b/AspectC++/tests/GetConditional/feature.ref @@ -0,0 +1,3 @@ +GET: Container *Container::thread_list +GET: Container *Container::thread_list +GET: Container *Container::thread_list diff --git a/AspectC++/tests/GetConditional/main.cc b/AspectC++/tests/GetConditional/main.cc new file mode 100644 index 0000000..a37814a --- /dev/null +++ b/AspectC++/tests/GetConditional/main.cc @@ -0,0 +1,26 @@ +#include + +class Container { + Container* thread_list; + +public: + Container() : thread_list(this) {} + + Container* get_list_head() { + return thread_list?thread_list->thread_list:0; + } +}; + +int main() { + Container c; + c.get_list_head(); + return 0; +} + + +aspect ConditionalGet { + advice get("% ...::%") : before() { + printf("GET: %s\n", JoinPoint::signature()); + } +}; + diff --git a/AspectC++/tests/GlobalIds/Makefile b/AspectC++/tests/GlobalIds/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/GlobalIds/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/GlobalIds/a.ah b/AspectC++/tests/GlobalIds/a.ah new file mode 100644 index 0000000..6dc42ee --- /dev/null +++ b/AspectC++/tests/GlobalIds/a.ah @@ -0,0 +1,33 @@ +#ifndef __a_ah__ +#define __a_ah__ + +#include + +struct GlobalMsg { + bool instantiate; + GlobalMsg (int id) { + static int last_id = -1; + if (last_id == -1) { + printf ("GlobalIds: checks whether a JPID is globally unique\n"); + printf ("===================================================\n"); + printf ("IDs are fine if no other message follows.\n", id); + } + else if (last_id != id) + printf ("IDs of two translation units differ!\n", id); + last_id = id; + } +}; + +template struct Tester { + static GlobalMsg msg; +}; + +template GlobalMsg Tester::msg (ID); + +aspect IdChecker { + advice execution ("void f()") : after () { + Tester::msg.instantiate = true; + } +}; + +#endif // __a_ah__ diff --git a/AspectC++/tests/GlobalIds/another_module.cc b/AspectC++/tests/GlobalIds/another_module.cc new file mode 100644 index 0000000..19b3dd6 --- /dev/null +++ b/AspectC++/tests/GlobalIds/another_module.cc @@ -0,0 +1,14 @@ +// used to generate some exec join-point ids +void f1() {} +void f2() {} +void f3() {} +void f4() {} + +#include "h1.h" + +void f5() {} +void f6() {} + +void another_function () { + f (); +} diff --git a/AspectC++/tests/GlobalIds/feature.ref b/AspectC++/tests/GlobalIds/feature.ref new file mode 100644 index 0000000..e332e17 --- /dev/null +++ b/AspectC++/tests/GlobalIds/feature.ref @@ -0,0 +1,4 @@ +GlobalIds: checks whether a JPID is globally unique +=================================================== +IDs are fine if no other message follows. +=================================================== diff --git a/AspectC++/tests/GlobalIds/h1.h b/AspectC++/tests/GlobalIds/h1.h new file mode 100644 index 0000000..e665b82 --- /dev/null +++ b/AspectC++/tests/GlobalIds/h1.h @@ -0,0 +1,6 @@ +#ifndef __h1_h__ +#define __h1_h__ + +inline void f () {} + +#endif // __h1_h__ diff --git a/AspectC++/tests/GlobalIds/main.cc b/AspectC++/tests/GlobalIds/main.cc new file mode 100644 index 0000000..837e1d7 --- /dev/null +++ b/AspectC++/tests/GlobalIds/main.cc @@ -0,0 +1,10 @@ +#include +#include "h1.h" + +extern void another_function (); + +int main () { + f (); + another_function (); + printf ("===================================================\n"); +} diff --git a/AspectC++/tests/Instantiation/Makefile b/AspectC++/tests/Instantiation/Makefile new file mode 100644 index 0000000..1cb4e22 --- /dev/null +++ b/AspectC++/tests/Instantiation/Makefile @@ -0,0 +1,2 @@ +ACFLAGS ?= -v9 +include ../Makefile.generic diff --git a/AspectC++/tests/Instantiation/feature.ref b/AspectC++/tests/Instantiation/feature.ref new file mode 100644 index 0000000..16af905 --- /dev/null +++ b/AspectC++/tests/Instantiation/feature.ref @@ -0,0 +1,4 @@ +Instantiation: advice for template instances +============================================================= +... not yet implement +============================================================= diff --git a/AspectC++/tests/Instantiation/main.cc b/AspectC++/tests/Instantiation/main.cc new file mode 100644 index 0000000..7c504f3 --- /dev/null +++ b/AspectC++/tests/Instantiation/main.cc @@ -0,0 +1,32 @@ +#include +using std::printf; + +void resolved_func () {}; + +template class Array { + T _data[I]; +public: + T get (int i) const { resolved_func (); return _data[i]; } + void set (int i, const T &d) { _data[i] = d; } +}; + +aspect Bla { + advice execution ("% ...::set(...)") : before () { + } +}; + +namespace bla { +Array darray; +} + +int main () { + printf ("Instantiation: advice for template instances\n"); + printf ("=============================================================\n"); + printf ("... not yet implement\n"); + Array iarray; + iarray.set (0, 0); + Array darray_second_inst; + darray_second_inst.set (0, 3.14); + printf ("=============================================================\n"); + return 0; +} diff --git a/AspectC++/tests/IntroInAll/Makefile b/AspectC++/tests/IntroInAll/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/IntroInAll/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/IntroInAll/feature.ref b/AspectC++/tests/IntroInAll/feature.ref new file mode 100644 index 0000000..a337343 --- /dev/null +++ b/AspectC++/tests/IntroInAll/feature.ref @@ -0,0 +1,4 @@ +IntroInAll: tests intros into "%" +============================================================= +it is OK if it compiles! +============================================================= diff --git a/AspectC++/tests/IntroInAll/main.cc b/AspectC++/tests/IntroInAll/main.cc new file mode 100644 index 0000000..7157263 --- /dev/null +++ b/AspectC++/tests/IntroInAll/main.cc @@ -0,0 +1,114 @@ +// foo.h +#include +#include + +#define std_default_vector std::vector + +template +class FOO +{ +public: + typedef std_default_vector vector; + class MyVec; + class BlaBla {}; +}; + +template +class std_vector : public FOO::vector { }; + +template +class MyStdVector : public std_default_vector +{ +}; + +template +class FOO::MyVec : public std::vector +{ +}; + +#define std_vector MyStdVector + +class GOO; + +typedef std_vector GooList; + +class GOO { +public: + GOO(void) {}; + GOO(const GOO &, int = 0) {}; + virtual void m(void); + static void m(GooList& glist); + virtual int m2(void); +}; + +// foo.cpp + +int main(int argc, char **argv) +{ + printf ("IntroInAll: tests intros into \"%%\"\n"); + printf ("=============================================================\n"); + printf ("it is OK if it compiles!\n"); +GooList glist; +GOO::m(glist); + printf ("=============================================================\n"); +} + +void GOO::m(GooList &glist) +{ +GooList::const_iterator idx = glist.begin(); +for (; idx != glist.end(); idx++) + (*idx)->m(); + +int sorted = 1; +for (; sorted < (int)glist.size(); sorted++) +{ + GOO* tmp = glist[sorted]; + int index = sorted - 1; + while (index >= 0) + { + GOO* current = glist[index]; + if (tmp->m2() > current->m2()) + break; + + glist[index+1] = glist[index]; + index--; + } + glist[index+1] = tmp; +} +} + +void GOO::m(void) +{ +} + +int GOO::m2(void) +{ +return 1; +} + +// foo.ah +aspect Trace { + pointcut all() = "%"; + + advice all() : slice struct { void *fAttr; }; + advice all() : slice struct { + void *getAttr(void) { + return fAttr; + } + }; + advice all() : slice struct { void setAttr(void* attr) { + fAttr = attr; + } + }; + advice construction (all ()) : after () { + void *attr = 0; +// compute attr + tjp->target()->setAttr(attr); + } + advice call ("virtual % ...::%(...)") : before () { + void *selfAttr = tjp->target()->getAttr(); + void *myAttr = (void *)1; + // compare selfAttr & myAttr + } +}; + diff --git a/AspectC++/tests/IntroInBase/Base.ah b/AspectC++/tests/IntroInBase/Base.ah new file mode 100644 index 0000000..4f38014 --- /dev/null +++ b/AspectC++/tests/IntroInBase/Base.ah @@ -0,0 +1,11 @@ +#ifndef __Base_ah__ +#define __Base_ah__ + +typedef int SomeType; + +aspect Base { + pointcut virtual target_class () = 0; + advice target_class() : slice struct { SomeType _something; }; +}; + +#endif // __Base_ah__ diff --git a/AspectC++/tests/IntroInBase/C.h b/AspectC++/tests/IntroInBase/C.h new file mode 100644 index 0000000..a5f0c84 --- /dev/null +++ b/AspectC++/tests/IntroInBase/C.h @@ -0,0 +1,10 @@ +#ifndef __C_h__ +#define __C_h__ + +class C { + void g () {} +public: + void f () { g (); } +}; + +#endif // __C_h__ diff --git a/AspectC++/tests/IntroInBase/Derived.ah b/AspectC++/tests/IntroInBase/Derived.ah new file mode 100644 index 0000000..04d5048 --- /dev/null +++ b/AspectC++/tests/IntroInBase/Derived.ah @@ -0,0 +1,34 @@ +#ifndef __Derived_ah__ +#define __Derived_ah__ + +#include + +#include "Base.ah" +#include "C.h" + +aspect Derived : public Base { + // make the base aspect introduce something into "C" + pointcut target_class () = "C"; + pointcut virtual late_target_class_copy () = 0; + + advice execution (target_class ()) : before () { + printf ("before %s\n", JoinPoint::signature ()); + } + // advice execution (late_target_class_copy ()) : after () { + // printf ("after %s\n", JoinPoint::signature ()); + // } +}; + +struct Confusion { + pointcut target_class() = "DoesNotExists"; +}; + +aspect Derived2 : public Confusion, public Derived { + // make the base aspect introduce something into "C" + pointcut late_target_class_copy () = "C"; + // advice late_target_class_copy() : slice struct { + // void func() { _something = 42; } + // }; +}; + +#endif // __Derived_ah__ diff --git a/AspectC++/tests/IntroInBase/Makefile b/AspectC++/tests/IntroInBase/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/IntroInBase/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/IntroInBase/feature.ref b/AspectC++/tests/IntroInBase/feature.ref new file mode 100644 index 0000000..ae016b6 --- /dev/null +++ b/AspectC++/tests/IntroInBase/feature.ref @@ -0,0 +1,5 @@ +IntroInBase: checks if the right #include is generated +====================================================== +before void C::f() +before void C::g() +====================================================== diff --git a/AspectC++/tests/IntroInBase/main.cc b/AspectC++/tests/IntroInBase/main.cc new file mode 100644 index 0000000..01f9d1b --- /dev/null +++ b/AspectC++/tests/IntroInBase/main.cc @@ -0,0 +1,11 @@ +#include + +#include "C.h" + +int main() { + C c; + printf ("IntroInBase: checks if the right #include is generated\n"); + printf ("======================================================\n"); + c.f (); + printf ("======================================================\n"); +} diff --git a/AspectC++/tests/IntroIncludes/A1.ah b/AspectC++/tests/IntroIncludes/A1.ah new file mode 100644 index 0000000..dd66384 --- /dev/null +++ b/AspectC++/tests/IntroIncludes/A1.ah @@ -0,0 +1,6 @@ +#ifndef __A1_ah__ +#define __A1_ah__ + +#include "C.h" + +#endif // __A1_ah__ diff --git a/AspectC++/tests/IntroIncludes/A2.ah b/AspectC++/tests/IntroIncludes/A2.ah new file mode 100644 index 0000000..6a22b35 --- /dev/null +++ b/AspectC++/tests/IntroIncludes/A2.ah @@ -0,0 +1,11 @@ +#ifndef __A2_ah__ +#define __A2_ah__ + +typedef int T; + +aspect A2 { +public: + advice "C" : slice struct { T _var; }; +}; + +#endif // __A2_ah__ diff --git a/AspectC++/tests/IntroIncludes/A3.ah b/AspectC++/tests/IntroIncludes/A3.ah new file mode 100644 index 0000000..c6a3417 --- /dev/null +++ b/AspectC++/tests/IntroIncludes/A3.ah @@ -0,0 +1,6 @@ +#ifndef __A3_ah__ +#define __A3_ah__ + +#include "C.h" + +#endif // __A3_ah__ diff --git a/AspectC++/tests/IntroIncludes/C.h b/AspectC++/tests/IntroIncludes/C.h new file mode 100644 index 0000000..01fcee6 --- /dev/null +++ b/AspectC++/tests/IntroIncludes/C.h @@ -0,0 +1,6 @@ +#ifndef __C_h__ +#define __C_h__ + +class C {}; + +#endif // __C_h__ diff --git a/AspectC++/tests/IntroIncludes/Makefile b/AspectC++/tests/IntroIncludes/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/IntroIncludes/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/IntroIncludes/feature.ref b/AspectC++/tests/IntroIncludes/feature.ref new file mode 100644 index 0000000..79869dd --- /dev/null +++ b/AspectC++/tests/IntroIncludes/feature.ref @@ -0,0 +1,4 @@ +IntroIncludes: check for problems with intros +============================================= +just fine if it compiles +============================================= diff --git a/AspectC++/tests/IntroIncludes/main.cc b/AspectC++/tests/IntroIncludes/main.cc new file mode 100644 index 0000000..1b873ba --- /dev/null +++ b/AspectC++/tests/IntroIncludes/main.cc @@ -0,0 +1,12 @@ +#include + +#include "C.h" + +int main () { + C c; + c._var = 42; + printf ("IntroIncludes: check for problems with intros\n"); + printf ("=============================================\n"); + printf ("just fine if it compiles\n"); + printf ("=============================================\n"); +} diff --git a/AspectC++/tests/Introspection/Makefile b/AspectC++/tests/Introspection/Makefile new file mode 100644 index 0000000..f485359 --- /dev/null +++ b/AspectC++/tests/Introspection/Makefile @@ -0,0 +1,2 @@ +ACFLAGS ?= --introspection +include ../Makefile.generic diff --git a/AspectC++/tests/Introspection/feature.ref b/AspectC++/tests/Introspection/feature.ref new file mode 100644 index 0000000..5424410 --- /dev/null +++ b/AspectC++/tests/Introspection/feature.ref @@ -0,0 +1,18 @@ +Introspection: Test AC::TypeInfo +================================================== +{ public i=42 public j=3.14 public k="Hallo" } +-> { public mutable foo=true public id=42 public size=1.8 public name="Olaf" public c=-> -> { public i=43 public j=2.1 public k= } public i={ public inner=42 } public array={ [0]=1 [1]=2 [2]=3 [3]=0 [4]=0 } public static dd=3.14 public b=false public same_as_member_0=false } +-> { no type info } +{ no type info } +42 +{ public _pad={ [0]=0 [1]=0 } } +-------------------------------------------------- +{{ baseclass public: public i=31}{ baseclass public virtual: public j=2.71} public k="Christoph" public c2=-889275714 } +-Bug-469------------------------------------------ +{ public a=123 } +-Bug-525------------------------------------------ +#members of Bug525_1: 2 +#members of Bug525_2: 0 +Bug524: must be 1: 1 +Bug524: must be 4: 4 +================================================== diff --git a/AspectC++/tests/Introspection/main.cc b/AspectC++/tests/Introspection/main.cc new file mode 100644 index 0000000..fcfd4f3 --- /dev/null +++ b/AspectC++/tests/Introspection/main.cc @@ -0,0 +1,397 @@ +#include +#include +using namespace std; + +// ===================================================================== +// some preliminary functions for generic printing ... to be extended +template ::AVAILABLE> +struct PrinterSelector; +template ::BASECLASSES> +struct PrintBaseClasses; + +void print (bool c) { cout << (c ? "true" : "false"); } +void print (unsigned char c) { cout << (int)c; } +void print (int c) { cout << c; } +void print (float f) { cout << f; } +void print (const char *c) { if (c) cout << "\"" << c << "\""; else cout << ""; } +template void print (T &c) { + cout << "{"; + PrinterSelector::print (c); + cout << " }"; +} +template void print (T *c) { + cout << "-> "; + print (*c); +} + +void print (AC::Protection prot) { + switch (prot) { + case AC::PROT_PRIVATE: cout << " private"; return; + case AC::PROT_PROTECTED: cout << " protected"; return; + case AC::PROT_PUBLIC: cout << " public"; return; + default: break; + } +} + +void print (AC::Specifiers spec) { + if (spec & AC::SPEC_STATIC) cout << " static"; + if (spec & AC::SPEC_MUTABLE) cout << " mutable"; + if (spec & AC::SPEC_VIRTUAL) cout << " virtual"; +} + + +template +struct AP { + static void print (T c) { ::print (c); } +}; +template struct AP { + template + static void print (T2 *c) { + cout << "{ "; + for (unsigned int i = 0; i < N; ++i) { + cout << "[" << i << "]="; + ::print (c[i]); + cout << " "; + } + cout << "}"; + } +}; + +template::MEMBERS> struct _Printer { + static void print (T &c) { + _Printer::print (c); + typedef typename AC::TypeInfo::template Member Member; + ::print (Member::prot); + ::print (Member::spec); + cout << " " << Member::name () << "="; + AP::print(*Member::pointer(&c)); + } +}; +template struct _Printer { + static void print (T &c) {} +}; + +template +struct PrinterSelector { + static void print (T &obj) { + PrintBaseClasses::print (obj); + _Printer::print (obj); + } +}; +template struct PrinterSelector { + static void print (T &) { + cout << " no type info"; + } +}; + +template +struct PrintBaseClasses { + static void print (T &obj) { + PrintBaseClasses::print (obj); + cout << "{ baseclass"; + typedef typename AC::TypeInfo::template BaseClass Base; + ::print (Base::prot); + ::print (Base::spec); + cout << ":"; + _Printer< typename Base::Type >::print (obj); + cout << "}"; + } +}; + +template +struct PrintBaseClasses { + static void print (T &obj) {} +}; + + +// ===================================================================== + +// The test code itself ... +// Led.h +typedef unsigned char uint8_t; + +class LED0 { +public: + volatile uint8_t _pad[0x2]; + + // PINA + volatile uint8_t + LEDPIN : 1, + : 7; + + // DDRA + volatile uint8_t + LEDDDR : 1, + : 7; + + // PORTA + volatile uint8_t + LEDPORT : 1, + : 7; +}; + +aspect Led { + pointcut ledfunc() = "LED%"; + + advice ledfunc() : slice class S { + public: + S() { + LEDPORT = 0; + LEDDDR = 1; + } + + void on() { + LEDPORT = 1; + } + + void off() { + LEDPORT = 0; + } + }; +}; + +struct C { + int i; + float j; + const char *k; +}; + +C inner_c = { 43, 2.1, 0 }; +C *cptr = &inner_c; + +// inheritance ... +struct Base1 { + int i; +}; + +struct Base2 { + float j; +}; + +struct Derived : public Base1, public virtual Base2 { + const char *k; // non-const + //int* const c; // const + const int c2; // const + void cee() const {} // const + const int zee() { return 0; } // non-const + Derived() : /*c((int*)this),*/ c2(0xCAFEBABE) {} +}; + +// arbitrary members ... +struct D { + mutable bool foo; + int id; + float size; + const char *name; + C **c; + struct Inner { + int inner; + } i; + int array[5]; + static float dd; + void f() {} +} d = {true, 42, 1.8, "Olaf", &cptr, { 42 }, { 1,2,3 }}; + +float D::dd = 3.14; + +struct F; // an incomplete type +LED0 l0; // constructed type with bit field and pad bytes + +aspect TypeExtensions { + advice "D": slice struct SL1 { + bool b; + JoinPoint::Member<0>::ReferredType same_as_member_0; + }; + advice execution("% D::f()") : before () { + // typename JoinPoint::That::Inner ii; + JoinPoint::That *ptr; + } +}; + +// template members as introduction +namespace Test { +template +class A {}; +}; + +class B {}; + +aspect Introducer { + advice "B" : slice class { Test::A a; }; +}; + +// ------- +// Bug 469: enums are counted for MEMBERS, but not treated in the list itself + +struct Bug469 { + enum { VAL = 1 }; + int a; +} bug469 = { 123 }; + +// ------- +// Bug 474: segfault; fine if it compiles + +// template +// class Per_cpu {}; + +// class Jdb +// { +// typedef enum +// { +// SS_NONE=0, SS_BRANCH, SS_RETURN +// } Step_state; + +// static Per_cpu ss_state; +// }; + +// ------- +// Bug 475: introspection code in extern "C" structs +// -> fine if it compiles + +extern "C" { + struct A { + int a; + }; +} + +// ------- +// Bug 525: introspection code for members that are instances of anonymous types +// -> fine if it compiles + +class Bug525_1 { + struct + { + bool hit : 1; + unsigned res : 6; + } _flags; + typedef struct { int i; } IStruct; + IStruct _is; +}; + +class Bug525_2 { +union + { + struct + { + unsigned long _space:32; + unsigned long address:20; + } __attribute__((packed)) data; + int *_submap; + } __attribute__((packed)); +}; + +// don't de-anonymize typedef'd classes +class Bug525_3 { +public: + Bug525_3 () {} +}; + +typedef class { Bug525_3 _attr; } Bug525_4; +Bug525_4 global_obj; + +struct { + Bug525_4 _obj; + int _bla; +} typedef Bug525_5; + +void f(const Bug525_5 &p) {} +aspect Bug525_Check { + advice execution("void f(const %&)") : before () {} +}; + +// +// Bug reported on problems compiling Gem5 +// +// De-Anonymize class with a base class +// Fine if it compiles +struct YYY {}; + +class BitfieldUnderlyingClassesExtMachInst { + union { + class : public YYY { + } puswl; + }; +}; + +// ------- +// Bug 546: Type hiding by a non-type declaration +// -> requires elaborated type specifier +struct settings { + int hashpower_init; +}; + +class Memcached { + static struct settings settings; + const volatile struct settings hmpf; + void (Memcached::*wr)(char const *, int, unsigned & ); +}; + +settings Memcached::settings; + +// ------- +// Bug 524: handle ambiguous type names +// + +// case 1 +namespace Addr { + +template< int SHIFT > +struct Addr {}; + +} // namespace Addr + +class Virt_addr +: public Addr::Addr<42> {}; + +// case 2 +class Page +{ + typedef int Type; + Type t; +}; + +// case 3 (sanity check) +namespace Inner { + struct T { uint32_t a; }; +} + +class C2 { + public: + class Inner { + public: struct T { uint8_t a; }; + }; + Inner::T my_t; + ::Inner::T my_t2; +}; + +// ====== + +int main () { + C c; + c.i = 42; + c.j = 3.14; + c.k = "Hallo"; + cout << "Introspection: Test AC::TypeInfo" << endl; + cout << "==================================================" << endl; + print (c); cout << endl; + print (&d); cout << endl; + print ((F*)0); cout << endl; + print (cout); cout << endl; + print (42); cout << endl; + print (l0); cout << endl; + cout << "--------------------------------------------------" << endl; + Derived d; + d.i = 31; + d.j = 2.71; + d.k = "Christoph"; + print (d); cout << endl; + cout << "-Bug-469------------------------------------------" << endl; + print (bug469); cout << endl; + cout << "-Bug-525------------------------------------------" << endl; + cout << "#members of Bug525_1: " << AC::TypeInfo::MEMBERS << endl; + cout << "#members of Bug525_2: " << AC::TypeInfo::MEMBERS << endl; + f (Bug525_5 ()); + cout << "Bug524: must be 1: " << sizeof(AC::TypeInfo::Member<0>::Type) << endl; + cout << "Bug524: must be 4: " << sizeof(AC::TypeInfo::Member<1>::Type) << endl; + cout << "==================================================" << endl; +} diff --git a/AspectC++/tests/JPTL/JPTL.h b/AspectC++/tests/JPTL/JPTL.h new file mode 100644 index 0000000..c7eba70 --- /dev/null +++ b/AspectC++/tests/JPTL/JPTL.h @@ -0,0 +1,893 @@ +// This file is part of the JoinPoint Template Library (JPTL) +// +// JPTL 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 3 of the License, or +// (at your option) any later version. +// +// JPTL 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 JPTL. If not, see . +// +// Copyright (C) 2012-2014 Christoph Borchert + +#ifndef __JPTL_H__ +#define __JPTL_H__ + +namespace JPTL { + + +namespace SFINAE_CHECK { + +namespace EXEC { +// static check, whether has an attribute 'EXEC' +template long ttest(...); // overload resolution matches always +template char ttest(typename T::EXEC const volatile *); // preferred by overload resolution + +template(0))==sizeof(char))?1:0) > +struct GET { + typedef typename T::EXEC Type; +}; +template +struct GET { + typedef void Type; +}; +} // namespace EXEC + +// For looking up EXEC, use this dummy ones if the real one has no members/functions +// FIXME: this needs maintenance if future ac++ versions change this structures +template struct DummyMember { typedef char Type; typedef AC::Referred::type ReferredType; static const AC::Protection prot = AC::PROT_PRIVATE; static const AC::Specifiers spec = AC::SPEC_NONE; static ReferredType *pointer (const void* const obj = 0) { return 0; } static const char *name () { return "null"; } }; +template struct DummyFunction { static const AC::Protection prot = AC::PROT_PRIVATE; static const AC::Specifiers spec = AC::SPEC_NONE; }; +template struct DummyConstructor { static const AC::Protection prot = AC::PROT_PRIVATE; static const AC::Specifiers spec = AC::SPEC_NONE; }; +template struct DummyDestructor { static const AC::Protection prot = AC::PROT_PRIVATE; static const AC::Specifiers spec = AC::SPEC_NONE; }; + +template +struct GetFirstMember { + typedef typename TypeInfo::template Member<0> MemberInfo; +}; +template +struct GetFirstMember { + typedef DummyMember<> MemberInfo; +}; + +template +struct GetFirstFunction { + typedef typename TypeInfo::template Function<0> FunctionInfo; +}; +template +struct GetFirstFunction { + typedef DummyFunction<> FunctionInfo; +}; + +template +struct GetFirstConstructor { + typedef typename TypeInfo::template Constructor<0> ConstructorInfo; +}; +template +struct GetFirstConstructor { + typedef DummyConstructor<> ConstructorInfo; +}; + +template +struct GetFirstDestructor { + typedef typename TypeInfo::template Destructor<0> DestructorInfo; +}; +template +struct GetFirstDestructor { + typedef DummyDestructor<> DestructorInfo; +}; + +} // namespace SFINAE_CHECK + +//------------------------------------------------------------------------------------------------------------------------------- + +#ifndef __acweaving + +template class Action, + typename LAST_EXEC=typename SFINAE_CHECK::EXEC::GET< Action >::Type, // look for EXEC in Action<...> //TODO: improve readability of this particular feature + unsigned I=TypeInfo::BASECLASSES> +struct BaseIterator { + + //base type information + typedef typename TypeInfo::template BaseClass::Type BASE_TYPE; + typedef AC::TypeInfo BASE_TYPE_INFO; + + // try to cast (a pointer) from TypeInfo::That* to BASE_TYPE* + // if that fails, return the original value + template + __attribute__((always_inline)) inline static T base_cast(T arg) { return arg; } + __attribute__((always_inline)) inline static BASE_TYPE* base_cast(typename TypeInfo::That* arg) { + return (BASE_TYPE*)arg; + } + __attribute__((always_inline)) inline static const BASE_TYPE* base_cast(const typename TypeInfo::That* arg) { + return (const BASE_TYPE*)arg; + } + __attribute__((always_inline)) inline static volatile BASE_TYPE* base_cast(volatile typename TypeInfo::That* arg) { + return (volatile BASE_TYPE*)arg; + } + __attribute__((always_inline)) inline static const volatile BASE_TYPE* base_cast(const volatile typename TypeInfo::That* arg) { + return (const volatile BASE_TYPE*)arg; + } + + // calculation of the context type + typedef typename BaseIterator::EXEC PREV_EXEC; // recursion to the current base class + typedef typename BaseIterator::EXEC EXEC; // process next base class + + // the exec(...) function + __attribute__((always_inline)) inline static void exec() { // rule: I > 0 + BaseIterator::exec(); // recursion to the current base class + BaseIterator::exec(); // process next base class + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0) { // rule: I > 0 + BaseIterator::exec( base_cast(arg0) ); // recursion to the current base class + BaseIterator::exec(arg0); // process next base class + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1) { // rule: I > 0 + BaseIterator::exec( base_cast(arg0) , base_cast(arg1) ); // recursion to the current base class + BaseIterator::exec(arg0, arg1); // process next base class + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1, ARG_2 arg2) { // rule: I > 0 + BaseIterator::exec( base_cast(arg0) , base_cast(arg1) , base_cast(arg2) ); // recursion to the current base class + BaseIterator::exec(arg0, arg1, arg2); // process next base class + } +}; + +// Specialization for I=0 +template class Action, + typename LAST_EXEC> +struct BaseIterator { + + // calculation of the context type + typedef typename SFINAE_CHECK::EXEC::GET< Action >::Type EXEC; + + // the exec(...) function + __attribute__((always_inline)) inline static void exec() { + Action::exec(); + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0) { + Action::exec(arg0); + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1) { + Action::exec(arg0, arg1); + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1, ARG_2 arg2) { + Action::exec(arg0, arg1, arg2); + } +}; + +//------------------------------------------------------------------------------------------------------------------------------- + + +template class Action, + typename LAST_EXEC=typename SFINAE_CHECK::EXEC::GET< Action::MemberInfo, void> >::Type, // look for EXEC in Action<...> //TODO: improve readability of this particular feature + unsigned I=TypeInfo::MEMBERS> +struct MemberIterator { + + //member type info + typedef typename TypeInfo::template Member MEMBER_TYPE_INFO; + + // calculation of the context type + typedef typename MemberIterator::EXEC PREV_EXEC; + typedef typename SFINAE_CHECK::EXEC::GET< Action >::Type EXEC; + + // the exec(...) function + __attribute__((always_inline)) inline static void exec() { + MemberIterator::exec(); + Action::exec(); + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0) { + MemberIterator::exec(arg0); + Action::exec(arg0); + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1) { + MemberIterator::exec(arg0, arg1); + Action::exec(arg0, arg1); + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1, ARG_2 arg2) { + MemberIterator::exec(arg0, arg1, arg2); + Action::exec(arg0, arg1, arg2); + } +}; + +// Specialization for I=0 (end of recursion) +template class Action, + typename LAST_EXEC> +struct MemberIterator { + + // calculation of the context type + typedef LAST_EXEC EXEC; + + // the exec(...) function + __attribute__((always_inline)) inline static void exec() {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0) {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1) {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1, ARG_2 arg2) {} +}; + +//------------------------------------------------------------------------------------------------------------------------------- + + +template class Action, + typename LAST_EXEC=typename SFINAE_CHECK::EXEC::GET< Action::FunctionInfo, void> >::Type, // look for EXEC in Action<...> //TODO: improve readability of this particular feature + unsigned I=TypeInfo::FUNCTIONS> +struct FunctionIterator { + + //member type info + typedef typename TypeInfo::template Function FUNCTION_INFO; + + // calculation of the context type + typedef typename FunctionIterator::EXEC PREV_EXEC; + typedef typename SFINAE_CHECK::EXEC::GET< Action >::Type EXEC; + + // the exec(...) function + __attribute__((always_inline)) inline static void exec() { + FunctionIterator::exec(); + Action::exec(); + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0) { + FunctionIterator::exec(arg0); + Action::exec(arg0); + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1) { + FunctionIterator::exec(arg0, arg1); + Action::exec(arg0, arg1); + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1, ARG_2 arg2) { + FunctionIterator::exec(arg0, arg1, arg2); + Action::exec(arg0, arg1, arg2); + } +}; + +// Specialization for I=0 (end of recursion) +template class Action, + typename LAST_EXEC> +struct FunctionIterator { + + // calculation of the context type + typedef LAST_EXEC EXEC; + + // the exec(...) function + __attribute__((always_inline)) inline static void exec() {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0) {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1) {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1, ARG_2 arg2) {} +}; + +//------------------------------------------------------------------------------------------------------------------------------- + +template class Action, + typename LAST_EXEC=typename SFINAE_CHECK::EXEC::GET< Action::ConstructorInfo, void> >::Type, // look for EXEC in Action<...> //TODO: improve readability of this particular feature + unsigned I=TypeInfo::CONSTRUCTORS> +struct ConstructorIterator { + + //member type info + typedef typename TypeInfo::template Constructor CONSTRUCTOR_INFO; + + // calculation of the context type + typedef typename ConstructorIterator::EXEC PREV_EXEC; + typedef typename SFINAE_CHECK::EXEC::GET< Action >::Type EXEC; + + // the exec(...) function + __attribute__((always_inline)) inline static void exec() { + ConstructorIterator::exec(); + Action::exec(); + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0) { + ConstructorIterator::exec(arg0); + Action::exec(arg0); + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1) { + ConstructorIterator::exec(arg0, arg1); + Action::exec(arg0, arg1); + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1, ARG_2 arg2) { + ConstructorIterator::exec(arg0, arg1, arg2); + Action::exec(arg0, arg1, arg2); + } +}; + +// Specialization for I=0 (end of recursion) +template class Action, + typename LAST_EXEC> +struct ConstructorIterator { + + // calculation of the context type + typedef LAST_EXEC EXEC; + + // the exec(...) function + __attribute__((always_inline)) inline static void exec() {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0) {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1) {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1, ARG_2 arg2) {} +}; + +//------------------------------------------------------------------------------------------------------------------------------- + +template class Action, + typename LAST_EXEC=typename SFINAE_CHECK::EXEC::GET< Action::DestructorInfo, void> >::Type, // look for EXEC in Action<...> //TODO: improve readability of this particular feature + unsigned I=TypeInfo::DESTRUCTORS> +struct DestructorIterator { + + //member type info + typedef typename TypeInfo::template Destructor DESTRUCTOR_INFO; + + // calculation of the context type + typedef typename DestructorIterator::EXEC PREV_EXEC; + typedef typename SFINAE_CHECK::EXEC::GET< Action >::Type EXEC; + + // the exec(...) function + __attribute__((always_inline)) inline static void exec() { + DestructorIterator::exec(); + Action::exec(); + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0) { + DestructorIterator::exec(arg0); + Action::exec(arg0); + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1) { + DestructorIterator::exec(arg0, arg1); + Action::exec(arg0, arg1); + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1, ARG_2 arg2) { + DestructorIterator::exec(arg0, arg1, arg2); + Action::exec(arg0, arg1, arg2); + } +}; + +// Specialization for I=0 (end of recursion) +template class Action, + typename LAST_EXEC> +struct DestructorIterator { + + // calculation of the context type + typedef LAST_EXEC EXEC; + + // the exec(...) function + __attribute__((always_inline)) inline static void exec() {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0) {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1) {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1, ARG_2 arg2) {} +}; + +//------------------------------------------------------------------------------------------------------------------------------- + + +template class Action, + typename LAST_EXEC=typename SFINAE_CHECK::EXEC::GET< Action::MemberInfo, void> >::Type, // look for EXEC in Action<...> //TODO: improve readability of this particular feature + unsigned I=TypeInfo::BASECLASSES> +struct BaseMemberIterator { + + //base type information + typedef typename TypeInfo::template BaseClass::Type BASE_TYPE; + typedef AC::TypeInfo BASE_TYPE_INFO; + + // try to cast (a pointer) from TypeInfo::That* to BASE_TYPE* + // if that fails, return the original value + template + __attribute__((always_inline)) inline static T base_cast(T arg) { return arg; } + __attribute__((always_inline)) inline static BASE_TYPE* base_cast(typename TypeInfo::That* arg) { + return (BASE_TYPE*)arg; + } + __attribute__((always_inline)) inline static const BASE_TYPE* base_cast(const typename TypeInfo::That* arg) { + return (const BASE_TYPE*)arg; + } + __attribute__((always_inline)) inline static volatile BASE_TYPE* base_cast(volatile typename TypeInfo::That* arg) { + return (volatile BASE_TYPE*)arg; + } + __attribute__((always_inline)) inline static const volatile BASE_TYPE* base_cast(const volatile typename TypeInfo::That* arg) { + return (const volatile BASE_TYPE*)arg; + } + + // calculation of the context type + typedef typename BaseMemberIterator::EXEC PREV_EXEC; // recursion to the current base class + typedef typename BaseMemberIterator::EXEC EXEC; // process next base class + + // the exec(...) function + __attribute__((always_inline)) inline static void exec() { // rule: I > 0 + BaseMemberIterator::exec(); // recursion to the current base class + BaseMemberIterator::exec(); // process next base class + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0) { // rule: I > 0 + BaseMemberIterator::exec( base_cast(arg0) ); // recursion to the current base class + BaseMemberIterator::exec(arg0); // process next base class + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1) { // rule: I > 0 + BaseMemberIterator::exec( base_cast(arg0) , base_cast(arg1) ); // recursion to the current base class + BaseMemberIterator::exec(arg0, arg1); // process next base class + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1, ARG_2 arg2) { // rule: I > 0 + BaseMemberIterator::exec( base_cast(arg0) , base_cast(arg1) , base_cast(arg2) ); // recursion to the current base class + BaseMemberIterator::exec(arg0, arg1, arg2); // process next base class + } +}; + +// Specialization for I=0 +template class Action, + typename LAST_EXEC> +struct BaseMemberIterator { + + // use the MemberIterator for now, as we reached a child node + typedef MemberIterator MIT; + + // calculation of the context type + typedef typename MIT::EXEC EXEC; + + // the exec(...) function + __attribute__((always_inline)) inline static void exec() { + MIT::exec(); + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0) { + MIT::exec(arg0); + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1) { + MIT::exec(arg0, arg1); + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1, ARG_2 arg2) { + MIT::exec(arg0, arg1, arg2); + } +}; + +//------------------------------------------------------------------------------------------------------------------------------- + + +template class Action, + typename LAST_EXEC=typename SFINAE_CHECK::EXEC::GET< Action::FunctionInfo, void> >::Type, // look for EXEC in Action<...> //TODO: improve readability of this particular feature + unsigned I=TypeInfo::BASECLASSES> +struct BaseFunctionIterator { + + //base type information + typedef typename TypeInfo::template BaseClass::Type BASE_TYPE; + typedef AC::TypeInfo BASE_TYPE_INFO; + + // try to cast (a pointer) from TypeInfo::That* to BASE_TYPE* + // if that fails, return the original value + template + __attribute__((always_inline)) inline static T base_cast(T arg) { return arg; } + __attribute__((always_inline)) inline static BASE_TYPE* base_cast(typename TypeInfo::That* arg) { + return (BASE_TYPE*)arg; + } + __attribute__((always_inline)) inline static const BASE_TYPE* base_cast(const typename TypeInfo::That* arg) { + return (const BASE_TYPE*)arg; + } + __attribute__((always_inline)) inline static volatile BASE_TYPE* base_cast(volatile typename TypeInfo::That* arg) { + return (volatile BASE_TYPE*)arg; + } + __attribute__((always_inline)) inline static const volatile BASE_TYPE* base_cast(const volatile typename TypeInfo::That* arg) { + return (const volatile BASE_TYPE*)arg; + } + + // calculation of the context type + typedef typename BaseFunctionIterator::EXEC PREV_EXEC; // recursion to the current base class + typedef typename BaseFunctionIterator::EXEC EXEC; // process next base class + + // the exec(...) function + __attribute__((always_inline)) inline static void exec() { // rule: I > 0 + BaseFunctionIterator::exec(); // recursion to the current base class + BaseFunctionIterator::exec(); // process next base class + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0) { // rule: I > 0 + BaseFunctionIterator::exec( base_cast(arg0) ); // recursion to the current base class + BaseFunctionIterator::exec(arg0); // process next base class + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1) { // rule: I > 0 + BaseFunctionIterator::exec( base_cast(arg0) , base_cast(arg1) ); // recursion to the current base class + BaseFunctionIterator::exec(arg0, arg1); // process next base class + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1, ARG_2 arg2) { // rule: I > 0 + BaseFunctionIterator::exec( base_cast(arg0) , base_cast(arg1) , base_cast(arg2) ); // recursion to the current base class + BaseFunctionIterator::exec(arg0, arg1, arg2); // process next base class + } +}; + +// Specialization for I=0 +template class Action, + typename LAST_EXEC> +struct BaseFunctionIterator { + + // use the FunctionIterator for now, as we reached a child node + typedef FunctionIterator FIT; + + // calculation of the context type + typedef typename FIT::EXEC EXEC; + + // the exec(...) function + __attribute__((always_inline)) inline static void exec() { + FIT::exec(); + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0) { + FIT::exec(arg0); + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1) { + FIT::exec(arg0, arg1); + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1, ARG_2 arg2) { + FIT::exec(arg0, arg1, arg2); + } +}; + +//------------------------------------------------------------------------------------------------------------------------------- + + +template class Action, + typename LAST_EXEC=typename SFINAE_CHECK::EXEC::GET< Action::ConstructorInfo, void> >::Type, // look for EXEC in Action<...> //TODO: improve readability of this particular feature + unsigned I=TypeInfo::BASECLASSES> +struct BaseConstructorIterator { + + //base type information + typedef typename TypeInfo::template BaseClass::Type BASE_TYPE; + typedef AC::TypeInfo BASE_TYPE_INFO; + + // try to cast (a pointer) from TypeInfo::That* to BASE_TYPE* + // if that fails, return the original value + template + __attribute__((always_inline)) inline static T base_cast(T arg) { return arg; } + __attribute__((always_inline)) inline static BASE_TYPE* base_cast(typename TypeInfo::That* arg) { + return (BASE_TYPE*)arg; + } + __attribute__((always_inline)) inline static const BASE_TYPE* base_cast(const typename TypeInfo::That* arg) { + return (const BASE_TYPE*)arg; + } + __attribute__((always_inline)) inline static volatile BASE_TYPE* base_cast(volatile typename TypeInfo::That* arg) { + return (volatile BASE_TYPE*)arg; + } + __attribute__((always_inline)) inline static const volatile BASE_TYPE* base_cast(const volatile typename TypeInfo::That* arg) { + return (const volatile BASE_TYPE*)arg; + } + + // calculation of the context type + typedef typename BaseConstructorIterator::EXEC PREV_EXEC; // recursion to the current base class + typedef typename BaseConstructorIterator::EXEC EXEC; // process next base class + + // the exec(...) function + __attribute__((always_inline)) inline static void exec() { // rule: I > 0 + BaseConstructorIterator::exec(); // recursion to the current base class + BaseConstructorIterator::exec(); // process next base class + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0) { // rule: I > 0 + BaseConstructorIterator::exec( base_cast(arg0) ); // recursion to the current base class + BaseConstructorIterator::exec(arg0); // process next base class + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1) { // rule: I > 0 + BaseConstructorIterator::exec( base_cast(arg0) , base_cast(arg1) ); // recursion to the current base class + BaseConstructorIterator::exec(arg0, arg1); // process next base class + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1, ARG_2 arg2) { // rule: I > 0 + BaseConstructorIterator::exec( base_cast(arg0) , base_cast(arg1) , base_cast(arg2) ); // recursion to the current base class + BaseConstructorIterator::exec(arg0, arg1, arg2); // process next base class + } +}; + +// Specialization for I=0 +template class Action, + typename LAST_EXEC> +struct BaseConstructorIterator { + + // use the FunctionIterator for now, as we reached a child node + typedef ConstructorIterator CIT; + + // calculation of the context type + typedef typename CIT::EXEC EXEC; + + // the exec(...) function + __attribute__((always_inline)) inline static void exec() { + CIT::exec(); + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0) { + CIT::exec(arg0); + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1) { + CIT::exec(arg0, arg1); + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1, ARG_2 arg2) { + CIT::exec(arg0, arg1, arg2); + } +}; + +//------------------------------------------------------------------------------------------------------------------------------- + + +template class Action, + typename LAST_EXEC=typename SFINAE_CHECK::EXEC::GET< Action::DestructorInfo, void> >::Type, // look for EXEC in Action<...> //TODO: improve readability of this particular feature + unsigned I=TypeInfo::BASECLASSES> +struct BaseDestructorIterator { + + //base type information + typedef typename TypeInfo::template BaseClass::Type BASE_TYPE; + typedef AC::TypeInfo BASE_TYPE_INFO; + + // try to cast (a pointer) from TypeInfo::That* to BASE_TYPE* + // if that fails, return the original value + template + __attribute__((always_inline)) inline static T base_cast(T arg) { return arg; } + __attribute__((always_inline)) inline static BASE_TYPE* base_cast(typename TypeInfo::That* arg) { + return (BASE_TYPE*)arg; + } + __attribute__((always_inline)) inline static const BASE_TYPE* base_cast(const typename TypeInfo::That* arg) { + return (const BASE_TYPE*)arg; + } + __attribute__((always_inline)) inline static volatile BASE_TYPE* base_cast(volatile typename TypeInfo::That* arg) { + return (volatile BASE_TYPE*)arg; + } + __attribute__((always_inline)) inline static const volatile BASE_TYPE* base_cast(const volatile typename TypeInfo::That* arg) { + return (const volatile BASE_TYPE*)arg; + } + + // calculation of the context type + typedef typename BaseDestructorIterator::EXEC PREV_EXEC; // recursion to the current base class + typedef typename BaseDestructorIterator::EXEC EXEC; // process next base class + + // the exec(...) function + __attribute__((always_inline)) inline static void exec() { // rule: I > 0 + BaseDestructorIterator::exec(); // recursion to the current base class + BaseDestructorIterator::exec(); // process next base class + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0) { // rule: I > 0 + BaseDestructorIterator::exec( base_cast(arg0) ); // recursion to the current base class + BaseDestructorIterator::exec(arg0); // process next base class + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1) { // rule: I > 0 + BaseDestructorIterator::exec( base_cast(arg0) , base_cast(arg1) ); // recursion to the current base class + BaseDestructorIterator::exec(arg0, arg1); // process next base class + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1, ARG_2 arg2) { // rule: I > 0 + BaseDestructorIterator::exec( base_cast(arg0) , base_cast(arg1) , base_cast(arg2) ); // recursion to the current base class + BaseDestructorIterator::exec(arg0, arg1, arg2); // process next base class + } +}; + +// Specialization for I=0 +template class Action, + typename LAST_EXEC> +struct BaseDestructorIterator { + + // use the FunctionIterator for now, as we reached a child node + typedef DestructorIterator DIT; + + // calculation of the context type + typedef typename DIT::EXEC EXEC; + + // the exec(...) function + __attribute__((always_inline)) inline static void exec() { + DIT::exec(); + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0) { + DIT::exec(arg0); + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1) { + DIT::exec(arg0, arg1); + } + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1, ARG_2 arg2) { + DIT::exec(arg0, arg1, arg2); + } +}; + +#else // __acweaving + +// These are dummy iterators to speed up the weaving phase (no recursion). +// Thus, the real iterators get only instantiated once during the final compilation. + +template class Action, + typename LAST_EXEC=void, + unsigned I=0> +struct BaseIterator { + typedef typename SFINAE_CHECK::EXEC::GET< Action >::Type EXEC; + // the exec(...) function + __attribute__((always_inline)) inline static void exec() {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0) {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1) {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1, ARG_2 arg2) {} +}; + +template class Action, + typename LAST_EXEC=void, + unsigned I=0> +struct MemberIterator { + typedef typename SFINAE_CHECK::EXEC::GET< Action, LAST_EXEC> >::Type EXEC; + // the exec(...) function + __attribute__((always_inline)) inline static void exec() {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0) {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1) {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1, ARG_2 arg2) {} +}; + +template class Action, + typename LAST_EXEC=void, + unsigned I=0> +struct FunctionIterator { + typedef typename SFINAE_CHECK::EXEC::GET< Action, LAST_EXEC> >::Type EXEC; + // the exec(...) function + __attribute__((always_inline)) inline static void exec() {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0) {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1) {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1, ARG_2 arg2) {} +}; + +template class Action, + typename LAST_EXEC=void, + unsigned I=0> +struct ConstructorIterator { + typedef typename SFINAE_CHECK::EXEC::GET< Action, LAST_EXEC> >::Type EXEC; + // the exec(...) function + __attribute__((always_inline)) inline static void exec() {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0) {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1) {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1, ARG_2 arg2) {} +}; + +template class Action, + typename LAST_EXEC=void, + unsigned I=0> +struct DestructorIterator { + typedef typename SFINAE_CHECK::EXEC::GET< Action, LAST_EXEC> >::Type EXEC; + // the exec(...) function + __attribute__((always_inline)) inline static void exec() {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0) {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1) {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1, ARG_2 arg2) {} +}; + +template class Action, + typename LAST_EXEC=void, + unsigned I=0> +struct BaseMemberIterator { + typedef typename MemberIterator::EXEC EXEC; + // the exec(...) function + __attribute__((always_inline)) inline static void exec() {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0) {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1) {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1, ARG_2 arg2) {} +}; + +template class Action, + typename LAST_EXEC=void, + unsigned I=0> +struct BaseFunctionIterator { + typedef typename FunctionIterator::EXEC EXEC; + // the exec(...) function + __attribute__((always_inline)) inline static void exec() {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0) {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1) {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1, ARG_2 arg2) {} +}; + +template class Action, + typename LAST_EXEC=void, + unsigned I=0> +struct BaseConstructorIterator { + typedef typename ConstructorIterator::EXEC EXEC; + // the exec(...) function + __attribute__((always_inline)) inline static void exec() {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0) {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1) {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1, ARG_2 arg2) {} +}; + +template class Action, + typename LAST_EXEC=void, + unsigned I=0> +struct BaseDestructorIterator { + typedef typename DestructorIterator::EXEC EXEC; + // the exec(...) function + __attribute__((always_inline)) inline static void exec() {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0) {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1) {} + template + __attribute__((always_inline)) inline static void exec(ARG_0 arg0, ARG_1 arg1, ARG_2 arg2) {} +}; +#endif // __acweaving + +} // namespace JPTL + +#endif // __JPTL_H__ + diff --git a/AspectC++/tests/JPTL/Makefile b/AspectC++/tests/JPTL/Makefile new file mode 100644 index 0000000..f485359 --- /dev/null +++ b/AspectC++/tests/JPTL/Makefile @@ -0,0 +1,2 @@ +ACFLAGS ?= --introspection +include ../Makefile.generic diff --git a/AspectC++/tests/JPTL/TestAspect.ah b/AspectC++/tests/JPTL/TestAspect.ah new file mode 100644 index 0000000..3bcf897 --- /dev/null +++ b/AspectC++/tests/JPTL/TestAspect.ah @@ -0,0 +1,88 @@ +#pragma once + +#include "JPTL.h" + +#include +using namespace std; + + + +template +struct Printer { + template + static void exec(T obj, bool* proceed) { if(*proceed) { cout << TypeInfo::signature() << endl; } *proceed = true; } + + // EXEC is optional, and so is the specialization for void (initial EXEC) + struct EXEC { + enum { BASES = CONTEXT::BASES + TypeInfo::BASECLASSES }; + }; +}; +template +struct Printer { + // initial EXEC + struct EXEC { + enum { BASES = 0 }; + }; +}; + + +template +struct MemberView { + struct EXEC { + enum { SIZE = CONTEXT::SIZE + sizeof(typename MemberInfo::ReferredType) }; + }; + + template + static void exec(T obj) { cout << "+ " << sizeof(*MemberInfo::pointer(obj)) << " = " << EXEC::SIZE << endl; } +}; +template +struct MemberView { + // initial EXEC + struct EXEC { + enum { SIZE = 0 }; + }; +}; + + +template +struct FunctionCount { + struct EXEC { + enum { COUNT = CONTEXT::COUNT + 1 }; + }; +}; +template +struct FunctionCount { + struct EXEC { + enum { COUNT = 0 }; + }; +}; + + + +aspect TestAspect { + + advice "%" && !"TestAspect" : slice class { + public: + //int should_not_work[AC::TypeInfo::MEMBERS]; //THIS yields the TypeInfo of the BASE CLASS :-( : FIXME! + + typedef JPTL::BaseIterator bit; + typedef JPTL::MemberIterator mit; + typedef JPTL::FunctionIterator fit; + }; + + advice execution("%" && !"TestAspect") : after() { + cout << "*** BaseIterator ***" << endl; + bool result = true; + JoinPoint::That::bit::exec(tjp->that(), &result); + + cout << "BASES: " << JoinPoint::That::bit::EXEC::BASES << endl; + + cout << "*** MemberIterator ***" << endl; + JoinPoint::That::mit::exec(tjp->that()); + cout << "SIZE: " << JoinPoint::That::mit::EXEC::SIZE << endl; + + cout << "*** FunctionIterator ***" << endl; + cout << "COUNT: " << JoinPoint::That::fit::EXEC::COUNT << endl; + } + +}; diff --git a/AspectC++/tests/JPTL/feature.ref b/AspectC++/tests/JPTL/feature.ref new file mode 100644 index 0000000..56cfdfe --- /dev/null +++ b/AspectC++/tests/JPTL/feature.ref @@ -0,0 +1,13 @@ +*** BaseIterator *** +Base1 +Base2 +Base3 +Derived +BASES: 3 +*** MemberIterator *** ++ 8 = 8 ++ 1 = 9 ++ 8 = 17 +SIZE: 17 +*** FunctionIterator *** +COUNT: 2 diff --git a/AspectC++/tests/JPTL/main.cc b/AspectC++/tests/JPTL/main.cc new file mode 100644 index 0000000..f6417d6 --- /dev/null +++ b/AspectC++/tests/JPTL/main.cc @@ -0,0 +1,27 @@ +#include + +class Base1 {}; + +class Base2 {}; + +class Base3 : private Base2 { + int32_t a; + int64_t a2; +}; + +class Derived : public Base3, public Base1 { + int32_t b[2]; + int8_t c; + int64_t d; + + public: + void bar() {}; + void foo(); +}; + +int main() { + Derived b; + b.bar(); + + return 0; +} diff --git a/AspectC++/tests/JPType/Makefile b/AspectC++/tests/JPType/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/JPType/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/JPType/feature.ref b/AspectC++/tests/JPType/feature.ref new file mode 100644 index 0000000..83eb415 --- /dev/null +++ b/AspectC++/tests/JPType/feature.ref @@ -0,0 +1,11 @@ +execution join point int main() +call join point int printf(const char *,...) +JPType: checks the JPType number generation +call join point int printf(const char *,...) +=========================================== +construction join point C::C() +call join point void C::f() +execution join point void C::f() +call join point int printf(const char *,...) +=========================================== +destruction join point C::~C() diff --git a/AspectC++/tests/JPType/main.cc b/AspectC++/tests/JPType/main.cc new file mode 100644 index 0000000..2ae61cf --- /dev/null +++ b/AspectC++/tests/JPType/main.cc @@ -0,0 +1,36 @@ +#include + +aspect JPTypePrinter { + + void print_jp_type (AC::JPType jptype) { + switch (jptype) { + case AC::EXECUTION: printf ("execution"); break; + case AC::CALL: printf ("call"); break; + case AC::CONSTRUCTION: printf ("construction"); break; + case AC::DESTRUCTION: printf ("destruction"); break; + default: printf ("unknown"); + } + } + + advice (execution ("% ...::%(...)") || call ("% ...::%(...)") || + construction ("C") || destruction ("C")) && + !within ("JPTypePrinter") : before () { + print_jp_type (JoinPoint::JPTYPE); + printf (" join point %s\n", JoinPoint::signature ()); + } + +}; + +class C { +public: + void f () {} +}; + +int main () { + printf ("JPType: checks the JPType number generation\n"); + printf ("===========================================\n"); + C c; + c.f (); + printf ("===========================================\n"); + return 0; +} diff --git a/AspectC++/tests/MacroCall/Makefile b/AspectC++/tests/MacroCall/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/MacroCall/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/MacroCall/external.cc b/AspectC++/tests/MacroCall/external.cc new file mode 100644 index 0000000..1c55f18 --- /dev/null +++ b/AspectC++/tests/MacroCall/external.cc @@ -0,0 +1,7 @@ +#include +using std::printf; + +int qInitResources_foo () { + printf ("in qInitResources_foo\n"); + return 0; +} diff --git a/AspectC++/tests/MacroCall/feature.ref b/AspectC++/tests/MacroCall/feature.ref new file mode 100644 index 0000000..622ccfa --- /dev/null +++ b/AspectC++/tests/MacroCall/feature.ref @@ -0,0 +1,9 @@ +MacroCall: +============================================================= +call to foo() -> before foo() call -> in foo() +call to bar() -> before bar() execution -> in bar() +============================================================= +call to qInitResources_foo() -> in qInitResources_foo +============================================================= +call to qInitResources_bar() -> before qInitResources_% call -> in qInitResources_bar +============================================================= diff --git a/AspectC++/tests/MacroCall/main.cc b/AspectC++/tests/MacroCall/main.cc new file mode 100644 index 0000000..2b1a80e --- /dev/null +++ b/AspectC++/tests/MacroCall/main.cc @@ -0,0 +1,82 @@ +#include +using std::printf; + +#define XSTR(s) STR(s) +#define STR(s) #s +#define ARGDECL int i +#define BAR bar +#define INT int + +aspect Calls { + advice call ("% _foo(...)") : before () { + printf ("before foo() call -> "); + } + advice execution ("% " XSTR(BAR) "(...)") : before () { + printf ("before bar() execution -> "); + } + advice call ("% qInitResources_%(...)") : before () { + printf ("before qInitResources_%% call -> "); + } +}; + +#define VOID void + +#define FOODEF \ +VOID _foo (int, float) { \ + printf ("in foo()\n"); \ +} + +FOODEF + +VOID BAR (INT i) { + printf ("in bar()\n"); \ +} + +#define ARG 3+3 + +#define foo _foo + +#define QT_MANGLE_NAMESPACE(name) name + +#define Q_INIT_RESOURCE(name) \ + do { extern int QT_MANGLE_NAMESPACE(qInitResources_ ## name) (); \ + QT_MANGLE_NAMESPACE(qInitResources_ ## name) (); } while (0) + +int qInitResources_bar () { + printf ("in qInitResources_bar\n"); + return 0; +} + +#define EXPECT_FALSE(exp) __builtin_expect((exp),false) + +class A { +public: + int test() { return 0; } + static A* getInstance() { static A inst; return &inst; } +}; + +int test() { + if (EXPECT_FALSE(A::getInstance()->test())) { return 1; } + return 0; +} + +aspect A_call { + advice call("% A::%(...)") : before() {} +}; + +int main () { + printf ("MacroCall:\n"); + printf ("=============================================================\n"); + printf ("call to foo() -> "); + foo (ARG,ARG); + printf ("call to bar() -> "); + bar (ARG); + printf ("=============================================================\n"); + printf ("call to qInitResources_foo() -> "); + Q_INIT_RESOURCE(foo); // should not match. + printf ("=============================================================\n"); + printf ("call to qInitResources_bar() -> "); + Q_INIT_RESOURCE(bar); // should match. + printf ("=============================================================\n"); + return 0; +} diff --git a/AspectC++/tests/MacroExpansion/Makefile b/AspectC++/tests/MacroExpansion/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/MacroExpansion/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/MacroExpansion/feature.ref b/AspectC++/tests/MacroExpansion/feature.ref new file mode 100644 index 0000000..c4f673e --- /dev/null +++ b/AspectC++/tests/MacroExpansion/feature.ref @@ -0,0 +1,4 @@ +MacroExpansion: test automatic macro expansion +============================================== +fine if it compiles +============================================== diff --git a/AspectC++/tests/MacroExpansion/main.cc b/AspectC++/tests/MacroExpansion/main.cc new file mode 100644 index 0000000..4192574 --- /dev/null +++ b/AspectC++/tests/MacroExpansion/main.cc @@ -0,0 +1,34 @@ +// code reproduces the problem that caused bug 764, which was related +// to boost's BOOST_SCOPE_EXIT macros. + +#include +// #include + +#define PP_CAT(a,b) a ## b + +#define AUX(id) \ + PP_CAT(boost_se_guard_, id) + +# define CLASS_END(id) \ + } AUX(id)(0); + +int main() { + printf ("MacroExpansion: test automatic macro expansion\n"); + printf ("==============================================\n"); + + // int a = 0; + // BOOST_SCOPE_EXIT(&a) + // { + // a = 42; + // hello(); + // } + // BOOST_SCOPE_EXIT_END + struct A { A(int) { int rumpf; } float t; CLASS_END(42) + + printf ("fine if it compiles\n"); + printf ("==============================================\n"); + return 0; +} + +aspect NeededToTriggerTransformation {}; + diff --git a/AspectC++/tests/Makefile b/AspectC++/tests/Makefile new file mode 100644 index 0000000..5cc3d15 --- /dev/null +++ b/AspectC++/tests/Makefile @@ -0,0 +1,266 @@ +ifeq ($(REGRESSIONTEST),1) +MAKELEVEL := 1 +endif + +ifeq ($(MAKELEVEL),0) +$(error Sorry, this makefile is not intended to be \ +used directly. Please use the makefile in the toplevel \ +directory of the AspectC++ source tree instead) +endif + +SHELL=/bin/bash +DIFF=diff --strip-trailing-cr + +ACTESTS = Advice AdviceVirtualFct That StaticTrace Context NameMangling \ + Forward StandAloneCalls UnknownTypeCheck AccessControl Result \ + ArrayMangling MatchExpr ConsDesAdvice NestedClassFuncAdvice \ + MacroCall CallAdvice CallOnRef TemplateExtCall Bug190 Bug191 Bug192 \ + Order NonInlineIntros JPType PragmaOnce Bug207 \ + AbstractDerivedAspect PragmaOnceObserver ThatConst PrivateResult \ + VoidArg ArrayWrapper Bug216 Bug228 ExecAdviceRecursive ExternC \ + ThatContext IntroIncludes Bug234 Bug234-2 Bug235 Bug239 \ + ExecAdviceNewDelete ExecAdviceFriend CallPostfixOp STLString \ + CFlowCycle Bug368 Bug179 RightlessCalls Bug477 \ + IntroInBase Bug267 Bug268 Bug271 MatchVirtual \ + PctInClass IntroInAll Instantiation Slice NonInlineSliceInclude \ + Empty Bug316 Derived Base Bug323 GlobalIds AnonymousStuff \ + ForcedInclude Bug336 Bug353 Introspection CallAccess Bug418 Bug209 \ + MatchStatic Bug512 SliceJPAPI JPTL NamedPointcuts AspectPrivileges \ + RepoInvalid RepoVersion Bug321 Bug484 Bug524 DisjointIds AspectOf \ + MemberPointCut MatchScopeWithin \ + Bug549 Bug552 Bug554 DefaultArgs Bug561 Bug564 Bug566 Bug570 \ + Bug571-1 Bug571-2 Bug571-3 Bug575 Bug577 Bug427 AttribAligned \ + VirtualPointcuts Bug580 MacroExpansion Bug768 Bug769 Bug770 + +ifeq ($(FRONTEND),Clang) +ACTESTS += DataFlowAnalysis +ACTESTS += CallBuiltinOperator MemberPointCut2 +ACTESTS += SimpleGetAdvice SimpleSetAdvice CompoundGetSetAdvice FunctionEntity \ + SimpleRefAdvice SimpleAliasAccessMember SimpleGetSetFuncPtr \ + ArrayAccessAdvice MatchScope GetBaseDerived \ + Bug-Typenames DefaultArgs2 CallViaADN Bug574 GetConditional Bug576 \ + Bug567 Bug568 Bug548 Bug589 Bug594 Bug598 CallRef Float128Basic +ACTESTS += Attribute_basic Attribute_inMacro Attribute_removeAttrs + #Attribute_pointcuts Attribute_params Attribute_paramEvaluation \ + #Attribute_paramsIntrospection Attribute_stringParam +endif + +# disabled: UnsizedArray +# to be removed: NonInlineIntroInclude +# (uses deprecated introduction syntax massively) + +ACMSGTESTS := RepoInvalid RepoVersion Bug570 + +ACNORUN := $(filter $(ACMSGTESTS), $(ACTESTS)) + +ACRUN := $(filter-out $(ACNORUN), $(ACTESTS)) + +STDOUT_FILE := stdout.txt +STDERR_FILE := stderr.txt +ERROR_FILE := error.txt + +# ***** The following is only used for the Akut testsystem (REGRESSIONTEST == 1) ***** +# ==================================================================================== +ifeq ($(REGRESSIONTEST),1) + +define do_test_start + @COUNT=0;PASS=0;FAIL=0; +endef + +define do_test_weave + COUNT=$$(($$COUNT+1)); \ + echo ---START TEST $$COUNT: $1: is expected to PASS; \ + unset LANG; \ + exec 6>&1; \ + exec 7>&2; \ + exec > $(1)/feature.out; \ + exec 2> $(1)/feature.err; \ + $(MAKE) -s EXT="$(EXT)" -C $(1) ; \ + exec 1>&6 6>&-; \ + exec 2>&7 7>&-; \ + cp $(1)/feature.err $(1)/feature.out; \ + rm $(1)/feature.err; \ + exec 6>&1; \ + exec 7>&2; \ + exec > $(STDOUT_FILE); \ + exec 2> $(STDERR_FILE); \ + $(MAKE) -s EXT="$(EXT)" -C $(1) diff-only; \ + RET=$$?; \ + exec 1>&6 6>&-; \ + exec 2>&7 7>&-; \ + if [ $$RET == 0 ];then \ + echo ---END TEST $$COUNT: $1: PASS \(was expected to pass and did pass\); \ + PASS=$$(($$PASS+1)); \ + else \ + cat $(STDOUT_FILE) ;\ + cat $(STDERR_FILE) ;\ + FAIL=$$(($$FAIL+1)); \ + echo ---END TEST $$COUNT: $1: FAIL \(was expected to pass, but failed\); \ + fi; +endef + +define do_test_run + COUNT=$$(($$COUNT+1)); \ + echo ---START TEST $$COUNT: $1: is expected to PASS; \ + exec 6>&1; \ + exec 7>&2; \ + exec > $(STDOUT_FILE); \ + exec 2> $(STDERR_FILE); \ + $(MAKE) -s EXT="$(EXT)" -C $(1) ; \ + RET=$$?; \ + ERR_FLAG=C; \ + if [ $$RET == 0 ];then \ + $(MAKE) -s EXT="$(EXT)" -C $(1) diff; \ + RET=$$?; \ + ERR_FLAG=D; \ + fi; \ + exec 1>&6 6>&-; \ + exec 2>&7 7>&-; \ + if [ $$RET == 0 ];then \ + echo ---END TEST $$COUNT: $1: PASS \(was expected to pass and did pass\); \ + PASS=$$(($$PASS+1)); \ + else \ + cat $(STDOUT_FILE) ;\ + cat $(STDERR_FILE) ;\ + FAIL=$$(($$FAIL+1)); \ + echo ---END TEST $$COUNT: $1: FAIL \(was expected to pass, but failed\); \ + fi; +endef + +define do_test_end + echo -n "---EXECUTIVE SUMMARY: " ;\ + if [ $$FAIL -eq $$COUNT ]; then\ + echo FAIL \(all tests failed\) ;\ + elif [ $$FAIL -gt 0 ]; then \ + echo PARTLY \($$(( $$PASS * 100 / $$COUNT ))% tests passed as expected\); \ + else \ + echo PASS \(all tests passed\) ;\ + fi ;\ + echo ---START SUMMARY; \ + echo $$COUNT tests in this testcase; \ + echo $$PASS tests passed as expected; \ + echo $$FAIL tests did not pass as expected; \ + echo $$FAIL expected to pass but failed; \ + echo 0 expected to fail but passed; \ + echo ---END SUMMARY +endef + +regression_test: + $(call do_test_start) \ + $(foreach T, $(ACRUN), $(call do_test_run, $(T))) \ + $(foreach T, $(ACNORUN), $(call do_test_weave, $(T))) \ + $(call do_test_end) + +endif + +# ================================================================================ +# ***** The above is only used for the Akut testsystem (REGRESSIONTEST == 1) ***** + + +all: $(addsuffix .make, $(ACRUN)) $(addsuffix .weave, $(ACNORUN)) + @if [ -f $(ERROR_FILE) ];then \ + echo -e "\n\n"; \ + echo "+---------+"; \ + echo "|ERRORS: |"; \ + echo "+---------+"; \ + cat $(ERROR_FILE); \ + rm -f $(STDOUT_FILE) $(STDERR_FILE) $(ERROR_FILE); \ + exit 1; \ + else \ + echo -e "\n\n"; \ + echo "All tests OK"; \ + rm -f $(STDOUT_FILE) $(STDERR_FILE); \ + fi;\ + +ref: $(addsuffix .ref, $(ACTESTS)) + +refclean: + rm */feature.ref + +run: $(addsuffix .run, $(ACRUN)) + +clean: $(addsuffix .clean, $(ACTESTS)) + + +%.weave: % + @unset LANG; \ + exec 6>&1; \ + exec 7>&2; \ + exec > $ $&6 6>&-; \ + exec 2>&7 7>&-; \ + cp $&1; \ + exec 7>&2; \ + exec > $(STDOUT_FILE); \ + exec 2> $(STDERR_FILE); \ + $(MAKE) -s EXT="$(EXT)" -C $< diff-only; \ + RET=$$?; \ + exec 1>&6 6>&-; \ + exec 2>&7 7>&-; \ + if [ $$RET == 0 ];then \ + echo -n "."; \ + else \ + ERR_FLAG=D; \ + echo -n "[$$ERR_FLAG:$<]"; \ + echo -ne "\n-----------------------------------------------------------------------------\n" >> $(ERROR_FILE); \ + echo -n "TEST: $<" >> $(ERROR_FILE); \ + echo -ne "\n-----------------------------------------------------------------------------\n" >> $(ERROR_FILE); \ + echo -e "STDOUT:\n--------" >> $(ERROR_FILE); \ + cat $(STDOUT_FILE) >> $(ERROR_FILE); \ + echo >> $(ERROR_FILE); \ + echo -e "STDERR:\n--------" >> $(ERROR_FILE); \ + cat $(STDERR_FILE) >> $(ERROR_FILE); \ + echo >> $(ERROR_FILE); \ + fi; + + +%.make: % + @exec 6>&1; \ + exec 7>&2; \ + exec > $(STDOUT_FILE); \ + exec 2> $(STDERR_FILE); \ + $(MAKE) -s EXT="$(EXT)" -C $< ; \ + RET=$$?; \ + ERR_FLAG=C; \ + if [ $$RET == 0 ];then \ + $(MAKE) -s EXT="$(EXT)" -C $< diff; \ + RET=$$?; \ + ERR_FLAG=D; \ + fi; \ + exec 1>&6 6>&-; \ + exec 2>&7 7>&-; \ + if [ $$RET == 0 ];then \ + echo -n "."; \ + else \ + echo -n "[$$ERR_FLAG:$<]"; \ + echo -ne "\n-----------------------------------------------------------------------------\n" >> $(ERROR_FILE); \ + echo -n "TEST: $<" >> $(ERROR_FILE); \ + echo -ne "\n-----------------------------------------------------------------------------\n" >> $(ERROR_FILE); \ + echo -e "STDOUT:\n--------" >> $(ERROR_FILE); \ + cat $(STDOUT_FILE) >> $(ERROR_FILE); \ + echo >> $(ERROR_FILE); \ + echo -e "STDERR:\n--------" >> $(ERROR_FILE); \ + cat $(STDERR_FILE) >> $(ERROR_FILE); \ + echo >> $(ERROR_FILE); \ + fi; + + + + +%.ref: % + $(MAKE) -s EXT="$(EXT)" -C $< ref; + +%.run: % + @echo Making and running test '$<' + cd $< && $(MAKE) run + +%.clean: % + cd $< && $(MAKE) clean + +.PHONY: all clean run ref + + diff --git a/AspectC++/tests/Makefile.generic b/AspectC++/tests/Makefile.generic new file mode 100644 index 0000000..0ca3743 --- /dev/null +++ b/AspectC++/tests/Makefile.generic @@ -0,0 +1,97 @@ +ifeq ($(MAKELEVEL),0) +$(error Sorry, this makefile is not intended to be \ +used directly. Please use the makefile in the toplevel \ +directory of the ApectC++ source tree instead) +endif + +CXX ?= g++ -O6 +DIFF=diff --strip-trailing-cr +ACFLAGS += $(ACOPTFLAGS) -k + +ifeq ($(filter -r, $(ACFLAGS)),) + ACFLAGS += -r repo.acp +endif + +ifneq ($(MAKECMDGOALS),run) + ACFLAGS += -v9 +endif + +PROG:=feature$(EXT) + +SOURCES := $(wildcard *.cc) + +ACTEST :=$(shell pwd|sed -e s+/.*/++) + +JUNK := Junk +OBJECTS := $(addprefix $(JUNK)/,$(patsubst %.cc,%.o,$(SOURCES))) +DEPS := $(addprefix $(JUNK)/,$(patsubst %.cc,%.d,$(SOURCES))) +ACC := $(patsubst %.cc,%.acc,$(SOURCES)) +HEADERS := $(wildcard *.h) +ASPECTS := $(wildcard *.ah) +INCLUDE_LIST := $(patsubst %.ah,-include %.ah,$(ASPECTS)) + +ifeq ($(WEAVE_ERROR),) +all: $(PROG) +else +all: $(ACC) +endif + +run: all + ./$(PROG) + +check: all + + +SED := $(foreach pat, $(AC_PATTERN_REPLACEMENTS), | sed -e "$(pat)") + +diff: $(PROG) + ./$(PROG) $(AC_PATTERN_REPLACEMENTS) > $(basename $(PROG)).out + @$(DIFF) $(basename $(PROG)).out $(basename $(PROG)).ref + @rm $(basename $(PROG)).out + + +diff-only: + @cat $(basename $(PROG)).out $(AC_PATTERN_REPLACEMENTS) > $(basename $(PROG)).fil + @$(DIFF) $(basename $(PROG)).fil $(basename $(PROG)).ref + @rm $(basename $(PROG)).out $(basename $(PROG)).fil + + +ref: $(PROG) + @./$(PROG) > $(basename $(PROG)).ref + + +feature$(EXT): $(OBJECTS) + @echo Linking + @$(CXX) $(CXXFLAGS) -o $@ $(OBJECTS) + + +clean: + @rm -rf *.o $(JUNK) *.acc feature$(EXT) *~ *.acp + +%.acc : %.cc + @echo Weaving $< +ifeq ($(WEAVE_ERROR),) + $(AC) $(ACFLAGS) -p . -c $< -o $@ +else + -$(AC) $(ACFLAGS) -p . -c $< -o $@ +endif + +$(JUNK)/%.o : %.acc + @echo Compiling $< + @$(CXX) $(CXXFLAGS) -x c++ -c $< -o $@ + +$(JUNK)/%.d : %.cc + @mkdir -p $(JUNK) + @$(CXX) $(CXXFLAGS) -x c++ -MM $(INCLUDE_LIST) $< | \ + sed -e "s/$*\.o/$(JUNK)\/& $(JUNK)\/$*.d $*.acc/g" > $@ + + +ifneq ($(MAKECMDGOALS),clean) +-include $(DEPS) +endif + +.PHONY: clean all run diff diff-only ref + +# don't remove any intermediate files +.SECONDARY: + diff --git a/AspectC++/tests/MatchExpr/Makefile b/AspectC++/tests/MatchExpr/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/MatchExpr/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/MatchExpr/feature.ref b/AspectC++/tests/MatchExpr/feature.ref new file mode 100644 index 0000000..dc19357 --- /dev/null +++ b/AspectC++/tests/MatchExpr/feature.ref @@ -0,0 +1,168 @@ +MatchExpr: match expression semantics implemented correctly? +============================================================== +CONS C(int) is matched by ... +CONS C(int) is matched by ... +CONS C(int) is matched by ... +CONS C(int) is matched by ... +const/volatile function qualifiers: +----------------------------------- +FUNC void C::f () is matched by ... +'% C::f()' +'% ...::%(...)' +FUNC void C::f() const is matched by ... +'% C::f() const' +'% C::f()' +'% ...::%(...)' +FUNC void C::f() volatile is matched by +'% C::f() volatile' +'% C::f()' +'% ...::%(...)' +FUNC void C::f() const volatile is matched by +'% C::f() const volatile' +'% C::f() volatile' +'% C::f() const' +'% C::f()' +'% ...::%(...)' +============================================================== +qualified names with '...' +-------------------------- +FUNC void N1::N2::Inside::o () is matched by ... +'void N1::...::Inside::...::o ()' +'void ...::N2::...::% ()' +'void ...::N1::...::o ()' +'void N1::...::o ()' +'void N1::N2::Inside::o ()' +'% ...::%(...)' +FUNC void N1::N2::Inside::p () is matched by ... +'void ...::N2::...::% ()' +'% ...::%(...)' +FUNC void N3::o () is matched by ... +'% ...::%(...)' +FUNC void N3::p () is matched by ... +'% ...::%(...)' +FUNC void o () is matched by ... +'% ...::%(...)' +'% %(...)' +FUNC void p () is matched by ... +'void p ()' +'% ...::%(...)' +'% %(...)' +============================================================== +const / non-const function results +---------------------------------- +FUNC const char r1 () is matched by ... +'const % %()' +'% ...::%(...)' +'% %(...)' +FUNC const float r2 () is matched by ... +'const float %()' +'float %()' +'const % %()' +'% ...::%(...)' +'% %(...)' +FUNC char r3 () is matched by ... +'% ...::%(...)' +'% %(...)' +FUNC float r4 () is matched by ... +'float %()' +'% ...::%(...)' +'% %(...)' +============================================================== +const / volatile pointers +------------------------- +FUNC char * p1 () is matched by ... +'% * %()' +'% ...::%(...)' +'% %(...)' +FUNC char * const p2 () is matched by ... +'char * const %()' +'% * %()' +'const % %()' +'% ...::%(...)' +'% %(...)' +FUNC char * volatile p3 () is matched by ... +'% * volatile %()' +'% * %()' +'% ...::%(...)' +'% %(...)' +FUNC char * const volatile p4 () is matched by ... +'% * volatile const %()' +'% * volatile %()' +'char * const %()' +'% * %()' +'const % %()' +'% ...::%(...)' +'% %(...)' +============================================================== +check parameter type adjustments +-------------------------------- +FUNC void conv1 () is matched by ... +'void conv%(void)' +'% ...::%(...)' +'% %(...)' +FUNC void conv1 (float) is matched by ... +void conv%(const float)'' +'% ...::%(...)' +'% %(...)' +FUNC void conv1 (float *) is matched by ... +'void conv%(float[32])' +'% ...::%(...)' +'% %(...)' +FUNC void conv2 (const float) is matched by ... +void conv%(const float)'' +'% ...::%(...)' +'% %(...)' +FUNC void conv2 (float [32]) is matched by ... +'void conv%(float[32])' +'% ...::%(...)' +'% %(...)' +============================================================== +fancy operators +--------------- +FUNC Op::operator double* () is matched by ... +'% %::operator %(...)' +'% ...::%(...)' +FUNC Op &operator + (Op&, const Op&) is matched by ... +'Op& operator +(Op&,Op&)' +'% operator %(...)' +'% ...::%(...)' +'% %(...)' +FUNC Op &Op::operator =(const Op &) is matched by ... +'% %::operator %(...)' +'% ...::%(...)' +FUNC void Op::operator <<(int) is matched by ... +'% %::operator <<(...)' +'% %::operator %(...)' +'% ...::%(...)' +============================================================== +check for enumerations in match expressions +------------------------------------------- +FUNC void fe1 (Enum1) is matched by ... +'void fe% (Enum%)' +'void fe1 (Enum1)' +'% ...::%(...)' +'% %(...)' +FUNC static void EC::fe2 (EC::Enum2) is matched by ... +'void EC::fe2 (EC::Enum2)' +'% ...::%(...)' +============================================================== +check for addresses in template argument lists in match exprs +------------------------------------------------------------- +FUNC void void x1(T<&S::s>) is matched by ... +void x%(T<&%::%>) +void x%(T<&...::%>) +void x%(T<%>) +void x%(%) +'% ...::%(...)' +'% %(...)' +FUNC void void x2(T<&ss>) is matched by ... +void x%(T<&...::%>) +void x%(T<&%>) +void x%(T<%>) +void x%(%) +'% ...::%(...)' +'% %(...)' +============================================================== +FUNC main () is matched by ... +'% ...::%(...)' +'% %(...)' diff --git a/AspectC++/tests/MatchExpr/main.cc b/AspectC++/tests/MatchExpr/main.cc new file mode 100644 index 0000000..1e1bc84 --- /dev/null +++ b/AspectC++/tests/MatchExpr/main.cc @@ -0,0 +1,375 @@ +#include + +// this was only used for checking the match expression parser +// aspect MatchExprTest { +// // declaration specifier sequences +// advice call ("% foo(...)") : before () {} +// advice call ("const % foo(...)") : before () {} +// advice call ("int foo(...)") : before () {} +// advice call ("unsigned int foo(...)") : before () {} +// advice call ("const char *foo(...)") : before () {} +// advice call ("const char*foo(...)") : before () {} +// advice call ("Bar::% foo(...)") : before () {} +// advice call ("...::% foo(...)") : before () {} +// advice call ("...:: X% ::% foo(...)") : before () {} +// advice call ("const ... :: Bar &foo(...)") : before () {} +// // pointer operators +// advice call ("int *& foo ()") : before () {} +// advice call ("int Bar::* & foo ()") : before () {} +// advice call ("int * const volatile foo ()") : before () {} +// advice call ("bool ... :: * foo ()") : before () {} +// // nested declarators +// advice call ("const char *(*foo)(...)") : before () {} +// advice call ("const char *( * foo )(...)") : before () {} +// // qualified names +// advice call ("const char unsigned *(*Bar::foo)(...)") : before () {} +// advice call ("const char *( * ... :: Foo :: foo )(...)") : before () {} +// // argument lists +// advice call ("% foo()") : before () {} +// advice call ("% foo(int)") : before () {} +// advice call ("% foo(%,int,...)") : before () {} +// advice call ("% foo(int, double (*)())") : before () {} +// advice call ("% %::foo(double (*)() const) const volatile") : before () {} +// // array stuff +// advice call ("% a[10]") : before () {} +// advice call ("% a[10][ 15 ]") : before () {} +// advice call ("% a[%][%]") : before () {} +// // classes +// advice call ("%") : before () {} +// advice call ("A%") : before () {} +// advice call ("%B") : before () {} +// advice call ("A%B") : before () {} +// advice call ("A%B%C%") : before () {} +// // various types +// advice call ("bool") : before () {} +// advice call ("char") : before () {} +// advice call ("signed char") : before () {} +// advice call ("char unsigned") : before () {} +// advice call ("short") : before () {} +// advice call ("signed short") : before () {} +// advice call ("unsigned short") : before () {} +// advice call ("int") : before () {} +// advice call ("signed int") : before () {} +// advice call ("unsigned int") : before () {} +// advice call ("signed") : before () {} +// advice call ("unsigned") : before () {} +// advice call ("wchar_t") : before () {} +// advice call ("long") : before () {} +// advice call ("signed long") : before () {} +// advice call ("unsigned long") : before () {} +// advice call ("long long") : before () {} +// advice call ("long signed long") : before () {} +// advice call ("unsigned long long") : before () {} +// advice call ("float") : before () {} +// advice call ("double") : before () {} +// advice call ("long double") : before () {} +// advice call ("void") : before () {} +// // types with declarator +// advice call ("void *") : before () {} +// advice call ("void (*)(...)") : before () {} +// // invalid advice call ("void (...) const") : before () {} +// }; + +class C { + int _i; +public: + C (int i) : _i (i) { printf ("CONS C(int) is matched by ...\n"); } + void f () { printf ("FUNC void C::f () is matched by ...\n"); } + void f () const { printf ("FUNC void C::f() const is matched by ...\n"); } + void f () volatile { printf ("FUNC void C::f() volatile is matched by\n"); } + void f () const volatile { printf ("FUNC void C::f() const volatile is matched by\n"); } +}; + +const char r1 () { printf ("FUNC const char r1 () is matched by ...\n"); return 0; } +const float r2 () { printf ("FUNC const float r2 () is matched by ...\n"); return 0; } +char r3 () { printf ("FUNC char r3 () is matched by ...\n"); return 0; } +float r4 () { printf ("FUNC float r4 () is matched by ...\n"); return 0; } + +char * p1 () { printf ("FUNC char * p1 () is matched by ...\n"); return 0; } +char * const p2 () { printf ("FUNC char * const p2 () is matched by ...\n"); return 0; } +char * volatile p3 () { printf ("FUNC char * volatile p3 () is matched by ...\n"); return 0; } +char * const volatile p4 () { printf ("FUNC char * const volatile p4 () is matched by ...\n"); return 0; } + +aspect QualCheck { + advice execution ("% C::f()") : after () { + printf ("'%% C::f()'\n"); + } + advice execution ("% C::f() const") : after () { + printf ("'%% C::f() const'\n"); + } + advice execution ("% C::f() volatile") : after () { + printf ("'%% C::f() volatile'\n"); + } + advice execution ("% C::f() const volatile") : after () { + printf ("'%% C::f() const volatile'\n"); + } + advice execution ("const % %()") : after () { + printf ("'const %% %%()'\n"); + } + advice execution ("float %()") : after () { + printf ("'float %%()'\n"); + } + advice execution ("const float %()") : after () { + printf ("'const float %%()'\n"); + } + advice execution ("% * %()") : after () { + printf ("'%% * %%()'\n"); + } + advice execution ("char * const %()") : after () { + printf ("'char * const %%()'\n"); + } + advice execution ("% * volatile %()") : after () { + printf ("'%% * volatile %%()'\n"); + } + advice execution ("% * volatile const %()") : after () { + printf ("'%% * volatile const %%()'\n"); + } +}; + +namespace N1 { + namespace N2 { + class Inside { + public: + void o() { printf ("FUNC void N1::N2::Inside::o () is matched by ...\n"); } + void p() { printf ("FUNC void N1::N2::Inside::p () is matched by ...\n");} + }; + } +} + +namespace N3 { + void o() { printf ("FUNC void N3::o () is matched by ...\n"); } + void p() { printf ("FUNC void N3::p () is matched by ...\n"); } +} + +void o() { printf ("FUNC void o () is matched by ...\n"); } +void p() { printf ("FUNC void p () is matched by ...\n"); } + +aspect DotCheck { + advice execution ("void N1::N2::Inside::o ()") : after () { + printf ("'void N1::N2::Inside::o ()'\n"); + } + advice execution ("void N1::...::o ()") : after () { + printf ("'void N1::...::o ()'\n"); + } + advice execution ("void ...::N1::...::o ()") : after () { + printf ("'void ...::N1::...::o ()'\n"); + } + advice execution ("void ...::N2::...::% ()") : after () { + printf ("'void ...::N2::...::%% ()'\n"); + } + advice execution ("void N1::...::Inside::...::o ()") : after () { + printf ("'void N1::...::Inside::...::o ()'\n"); + } + advice execution ("void p ()") : after () { + printf ("'void p ()'\n"); + } +}; + +aspect AnyCheck { + advice execution ("% %(...)") : after () { + printf ("'%% %%(...)'\n"); + } + advice execution ("% ...::%(...)") : after () { + printf ("'%% ...::%%(...)'\n"); + } +}; + +void conv1 () { printf ("FUNC void conv1 () is matched by ...\n"); } +void conv1 (float) { printf ("FUNC void conv1 (float) is matched by ...\n"); } +void conv1 (void (*)(int)) { printf ("FUNC void conv1 (void (*)(int)) is matched by ...\n"); } +void conv1 (float *) { printf ("FUNC void conv1 (float *) is matched by ...\n"); } +// code generation problem here: void conv2 (void) { printf ("FUNC void conv2 (void) is matched by ...\n"); } +void conv2 (const float) { printf ("FUNC void conv2 (const float) is matched by ...\n"); } +void conv2 (void (int)) { printf ("FUNC void conv2 (void (int)) is matched by ...\n"); } +void conv2 (float [32]) { printf ("FUNC void conv2 (float [32]) is matched by ...\n"); } +aspect ConvWarningCheck { + // => argument list '(void)' converted to '()' + advice execution ("void conv%(void)") : after () { + printf ("'void conv%%(void)'\n"); + } + // => qualifier removed from argument + advice execution ("void conv%(const float)") : after () { + printf ("void conv%%(const float)''\n"); + } + // => function argument adjusted to pointer to function + // parser syntax: advice execution ("void conv%(void (int))") : after () { + // printf ("'void conv%%(void (int))'\n"); + // } + // => array argument adjusted to pointer + advice execution ("void conv%(float[32])") : after () { + printf ("'void conv%%(float[32])'\n"); + } +}; + +class Op { +public: + operator double* () { + printf ("FUNC Op::operator double* () is matched by ...\n"); + return 0; + } + Op &operator = (const Op &op) { + printf ("FUNC Op &Op::operator =(const Op &) is matched by ...\n"); + return *this; + } + void operator << (int) { + printf ("FUNC void Op::operator <<(int) is matched by ...\n"); + } +}; + +Op& operator + (Op& o1, const Op& o2) { + printf ("FUNC Op &operator + (Op&, const Op&) is matched by ...\n"); + return o1; +} + +aspect OperatorCheck { + advice execution ("% operator %(...)") : after () { + printf ("'%% operator %%(...)'\n"); + } + advice execution ("operator %(...)") : after () { + printf ("'operator %%(...)'\n"); + } + advice execution ("% operator double*()") : after () { + printf ("'operator double*()'\n"); + } + advice execution ("Op& operator +(Op&,Op&)") : after () { + printf ("'Op& operator +(Op&,Op&)'\n"); + } + advice execution ("% %::operator %(...)") : after () { + printf ("'%% %%::operator %%(...)'\n"); + } + advice execution ("% %::operator <<(...)") : after () { + printf ("'%% %%::operator <<(...)'\n"); + } +}; + +enum Enum1 { E1, E2, E3 }; +void fe1 (Enum1 enum1) { + printf ("FUNC void fe1 (Enum1) is matched by ...\n"); +} +class EC { +public: + enum Enum2 { E4 = E3 + 1, E5 }; + static void fe2 (Enum2 enum1) { + printf ("FUNC static void EC::fe2 (EC::Enum2) is matched by ...\n"); +} +}; + +aspect EnumCheck { + advice execution ("void fe1 (Enum1)") : after () { + printf ("'void fe1 (Enum1)'\n"); + } + advice execution ("void EC::fe2 (EC::Enum2)") : after () { + printf ("'void EC::fe2 (EC::Enum2)'\n"); + } + advice execution ("void fe2 (Enum2)") : after () { + printf ("'void fe2 (Enum2)'\n"); + } + advice execution ("void fe% (Enum%)") : after () { + printf ("'void fe%% (Enum%%)'\n"); + } +}; + +struct S { static void s() {} }; +void ss() {} + +template struct T {}; + +T<&S::s> t1; +T<&ss> t2; + +void x1(T<&S::s>) { + printf ("FUNC void void x1(T<&S::s>) is matched by ...\n"); +} +void x2(T<&ss>) { + printf ("FUNC void void x2(T<&ss>) is matched by ...\n"); +} + +aspect TemplAddrCheck { + advice execution("void x%(%)") : after () { + printf ("void x%%(%%)\n"); + } + advice execution("void x%(T<%>)") : after () { + printf ("void x%%(T<%%>)\n"); + } + advice execution("void x%(T<&%>)") : after () { + printf ("void x%%(T<&%%>)\n"); + } + advice execution("void x%(T<&...::%>)") : after () { + printf ("void x%%(T<&...::%%>)\n"); + } + advice execution("void x%(T<&%::%>)") : after () { + printf ("void x%%(T<&%%::%%>)\n"); + } +}; + +int main () { + printf ("MatchExpr: match expression semantics implemented correctly?\n"); + printf ("==============================================================\n"); + C c (1); + const C cc (2); + volatile C cv (3); + const volatile C ccv (4); + printf ("const/volatile function qualifiers:\n"); + printf ("-----------------------------------\n"); + c.f (); + cc.f (); + cv.f (); + ccv.f (); + printf ("==============================================================\n"); + printf ("qualified names with '...'\n"); + printf ("--------------------------\n"); + + N1::N2::Inside i; + i.o (); + i.p (); + N3::o (); + N3::p (); + o (); + p (); + + printf ("==============================================================\n"); + printf ("const / non-const function results\n"); + printf ("----------------------------------\n"); + r1 (); + r2 (); + r3 (); + r4 (); + printf ("==============================================================\n"); + printf ("const / volatile pointers\n"); + printf ("-------------------------\n"); + p1 (); + p2 (); + p3 (); + p4 (); + printf ("==============================================================\n"); + printf ("check parameter type adjustments\n"); + printf ("--------------------------------\n"); + conv1 (); + conv1 (3.14f); + // NYI: conv1 ((void (*)(int))0); + conv1 ((float*)0); + // code generation problem with advice for conv2 (); + conv2 (3.14f); + // NYI: conv2 ((void (*)(int))0); + conv2 ((float*)0); + printf ("==============================================================\n"); + printf ("fancy operators\n"); + printf ("---------------\n"); + Op op1, op2, op3; + double *ptr = (double*)op2; + op3 = op1 + op2; + op3 << 2; + printf ("==============================================================\n"); + printf ("check for enumerations in match expressions\n"); + printf ("-------------------------------------------\n"); + fe1 (E2); + EC::fe2 (EC::E4); + printf ("==============================================================\n"); + printf ("check for addresses in template argument lists in match exprs\n"); + printf ("-------------------------------------------------------------\n"); + x1 (t1); + x2 (t2); + printf ("==============================================================\n"); + printf ("FUNC main () is matched by ...\n"); + return 0; +} diff --git a/AspectC++/tests/MatchScope/Makefile b/AspectC++/tests/MatchScope/Makefile new file mode 100644 index 0000000..b75c633 --- /dev/null +++ b/AspectC++/tests/MatchScope/Makefile @@ -0,0 +1,2 @@ +ACFLAGS ?= --builtin_operators --data_joinpoints --introspection +include ../Makefile.generic diff --git a/AspectC++/tests/MatchScope/feature.ref b/AspectC++/tests/MatchScope/feature.ref new file mode 100644 index 0000000..c47309b --- /dev/null +++ b/AspectC++/tests/MatchScope/feature.ref @@ -0,0 +1,120 @@ + +Creating instance of the class type: A::InA +=========================================================================== +constr("A"): A::InA::InA() +call ("A"): void A::InA::foo() +exec ("A"): void A::InA::foo() +get ("A"): int A::InA::x +set ("A"): int A::InA::x +ref ("A"): int A::InA::x +destr ("A"): A::InA::~InA() + +Creating instance of the class type: A::B::InB +=========================================================================== +constr("A"): A::B::InB::InB() +constr("A::B"): A::B::InB::InB() +call ("A"): void A::B::InB::foo() +call ("A::B"): void A::B::InB::foo() +exec ("A"): void A::B::InB::foo() +exec ("A::B"): void A::B::InB::foo() +get ("A"): int A::B::InB::x +get ("A::B"): int A::B::InB::x +set ("A"): int A::B::InB::x +set ("A::B"): int A::B::InB::x +ref ("A"): int A::B::InB::x +ref ("A::B"): int A::B::InB::x +destr ("A"): A::B::InB::~InB() +destr ("A::B"): A::B::InB::~InB() + +Creating instance of the class type: A::B::C::InC +=========================================================================== +constr("A"): A::B::C::InC::InC() +constr("A::B"): A::B::C::InC::InC() +constr("A::B::C"): A::B::C::InC::InC() +constr("A::B::C::InC"): A::B::C::InC::InC() +call ("A"): void A::B::C::InC::foo() +call ("A::B"): void A::B::C::InC::foo() +call ("A::B::C"): void A::B::C::InC::foo() +call ("A::B::C::InC"): void A::B::C::InC::foo() +exec ("A"): void A::B::C::InC::foo() +exec ("A::B"): void A::B::C::InC::foo() +exec ("A::B::C"): void A::B::C::InC::foo() +exec ("A::B::C::InC"): void A::B::C::InC::foo() +get ("A"): int A::B::C::InC::x +get ("A::B"): int A::B::C::InC::x +get ("A::B::C"): int A::B::C::InC::x +get ("A::B::C::InC"): int A::B::C::InC::x +set ("A"): int A::B::C::InC::x +set ("A::B"): int A::B::C::InC::x +set ("A::B::C"): int A::B::C::InC::x +set ("A::B::C::InC"): int A::B::C::InC::x +ref ("A"): int A::B::C::InC::x +ref ("A::B"): int A::B::C::InC::x +ref ("A::B::C"): int A::B::C::InC::x +ref ("A::B::C::InC"): int A::B::C::InC::x +destr ("A"): A::B::C::InC::~InC() +destr ("A::B"): A::B::C::InC::~InC() +destr ("A::B::C"): A::B::C::InC::~InC() +destr ("A::B::C::InC"): A::B::C::InC::~InC() + +Creating instance of the class type: A::B::C::InC::Inner +=========================================================================== +constr("A"): A::B::C::InC::Inner::Inner() +constr("A::B"): A::B::C::InC::Inner::Inner() +constr("A::B::C"): A::B::C::InC::Inner::Inner() +constr("A::B::C::InC::Inner"): A::B::C::InC::Inner::Inner() +call ("A"): void A::B::C::InC::Inner::foo() +call ("A::B"): void A::B::C::InC::Inner::foo() +call ("A::B::C"): void A::B::C::InC::Inner::foo() +call ("A::B::C::InC::Inner"): void A::B::C::InC::Inner::foo() +exec ("A"): void A::B::C::InC::Inner::foo() +exec ("A::B"): void A::B::C::InC::Inner::foo() +exec ("A::B::C"): void A::B::C::InC::Inner::foo() +exec ("A::B::C::InC::Inner"): void A::B::C::InC::Inner::foo() +get ("A"): int A::B::C::InC::Inner::x +get ("A::B"): int A::B::C::InC::Inner::x +get ("A::B::C"): int A::B::C::InC::Inner::x +get ("A::B::C::InC::Inner"): int A::B::C::InC::Inner::x +set ("A"): int A::B::C::InC::Inner::x +set ("A::B"): int A::B::C::InC::Inner::x +set ("A::B::C"): int A::B::C::InC::Inner::x +set ("A::B::C::InC::Inner"): int A::B::C::InC::Inner::x +ref ("A"): int A::B::C::InC::Inner::x +ref ("A::B"): int A::B::C::InC::Inner::x +ref ("A::B::C"): int A::B::C::InC::Inner::x +ref ("A::B::C::InC::Inner"): int A::B::C::InC::Inner::x +destr ("A"): A::B::C::InC::Inner::~Inner() +destr ("A::B"): A::B::C::InC::Inner::~Inner() +destr ("A::B::C"): A::B::C::InC::Inner::~Inner() +destr ("A::B::C::InC::Inner"): A::B::C::InC::Inner::~Inner() + +Creating instance of the class type: A::B::C::InC::Inner::InnerInner +=========================================================================== +constr("A"): A::B::C::InC::Inner::InnerInner::InnerInner() +constr("A::B"): A::B::C::InC::Inner::InnerInner::InnerInner() +constr("A::B::C"): A::B::C::InC::Inner::InnerInner::InnerInner() +call ("A"): void A::B::C::InC::Inner::InnerInner::foo() +call ("A::B"): void A::B::C::InC::Inner::InnerInner::foo() +call ("A::B::C"): void A::B::C::InC::Inner::InnerInner::foo() +exec ("A"): void A::B::C::InC::Inner::InnerInner::foo() +exec ("A::B"): void A::B::C::InC::Inner::InnerInner::foo() +exec ("A::B::C"): void A::B::C::InC::Inner::InnerInner::foo() +get ("A"): int A::B::C::InC::Inner::InnerInner::x +get ("A::B"): int A::B::C::InC::Inner::InnerInner::x +get ("A::B::C"): int A::B::C::InC::Inner::InnerInner::x +set ("A"): int A::B::C::InC::Inner::InnerInner::x +set ("A::B"): int A::B::C::InC::Inner::InnerInner::x +set ("A::B::C"): int A::B::C::InC::Inner::InnerInner::x +ref ("A"): int A::B::C::InC::Inner::InnerInner::x +ref ("A::B"): int A::B::C::InC::Inner::InnerInner::x +ref ("A::B::C"): int A::B::C::InC::Inner::InnerInner::x +destr ("A"): A::B::C::InC::Inner::InnerInner::~InnerInner() +destr ("A::B"): A::B::C::InC::Inner::InnerInner::~InnerInner() +destr ("A::B::C"): A::B::C::InC::Inner::InnerInner::~InnerInner() + +Slice test: +# members of A::InA: 2 (should be 2) +# members of A::B::InB: 2 (should be 2) +# members of A::B::C::InC: 3 (should be 3) +# members of A::B::C::InC::Inner: 5 (should be 5) +# members of A::B::C::InC::Inner::InnerInner: 2 (should be 2) diff --git a/AspectC++/tests/MatchScope/main.cc b/AspectC++/tests/MatchScope/main.cc new file mode 100644 index 0000000..e49f942 --- /dev/null +++ b/AspectC++/tests/MatchScope/main.cc @@ -0,0 +1,161 @@ +#include +using namespace std; + +const char* JPType(int num) { + switch (num) { + case AC::GET: + return "get "; break; + case AC::SET: + return "set "; break; + case AC::REF: + return "ref "; break; + case AC::CALL: + return "call "; break; + case AC::EXECUTION: + return "exec "; break; + case AC::CONSTRUCTION: + return "constr"; break; + case AC::DESTRUCTION: + return "destr "; break; + default: + return "error "; + } +} + +namespace A { + +class InA { +public: + void foo() {} + int x; +}; + +namespace B { + +class InB { +public: + void foo() {} + int x; +}; + +namespace C { + +class InC { +public: + void foo() {} + int x; + + class Inner { + public: + void foo() {} + int x; + + class InnerInner { + public: + void foo() {} + int x; + }; + }; +}; + +} // C + +} // B + +} // A + + +int main() { + { + A::InA a; + a.foo(); + a.x++; + int *x = &a.x; + } + + { + A::B::InB b; + b.foo(); + b.x++; + int *x = &b.x; + } + + { + A::B::C::InC c; + c.foo(); + c.x++; + int *x = &c.x; + } + + { + A::B::C::InC::Inner in; + in.foo(); + in.x++; + int *x = &in.x; + } + + { + A::B::C::InC::Inner::InnerInner inin; + inin.foo(); + inin.x++; + int *x = &inin.x; + } + + cout << endl << "Slice test:" << endl; + cout << "# members of A::InA: " << AC::TypeInfo::MEMBERS << " (should be 2)" << endl; + cout << "# members of A::B::InB: " << AC::TypeInfo::MEMBERS << " (should be 2)" << endl; + cout << "# members of A::B::C::InC: " << AC::TypeInfo::MEMBERS << " (should be 3)" << endl; + cout << "# members of A::B::C::InC::Inner: " << AC::TypeInfo::MEMBERS << " (should be 5)" << endl; + cout << "# members of A::B::C::InC::Inner::InnerInner: " << AC::TypeInfo::MEMBERS << " (should be 2)" << endl; +} + +aspect MatchingTest { + + // information for the human reader + advice construction(!"MatchingTest") : before() { + cout << endl << "Creating instance of the class type: " << AC::TypeInfo::signature() << endl; + cout << "===========================================================================" << endl; + } + + // the actual pointcuts to be checked + pointcut a() = "A"; + pointcut b() = "A::B"; + pointcut c() = "A::B::C"; + pointcut in_c() = "A::B::C::InC"; // only a class + pointcut inner() = "A::B::C::InC::Inner"; // only a nested class + + // namespace matching + advice call(a()) || execution(a()) || construction(a()) || destruction(a()) || get(a()) || set(a()) || ref(a()) : before() { + cout << JPType(JoinPoint::JPTYPE) << "(\"A\"): " << JoinPoint::signature() << endl; + } + advice call(b()) || execution(b()) || construction(b()) || destruction(b()) || get(b()) || set(b()) || ref(b()) : before() { + cout << JPType(JoinPoint::JPTYPE) << "(\"A::B\"): " << JoinPoint::signature() << endl; + } + advice call(c()) || execution(c()) || construction(c()) || destruction(c()) || get(c()) || set(c()) || ref(c()) : before() { + cout << JPType(JoinPoint::JPTYPE) << "(\"A::B::C\"): " << JoinPoint::signature() << endl; + } + + // class matching + advice call(in_c()) || execution(in_c()) || construction(in_c()) || destruction(in_c()) || get(in_c()) || set(in_c()) || ref(in_c()) : before() { + cout << JPType(JoinPoint::JPTYPE) << "(\"A::B::C::InC\"): " << JoinPoint::signature() << endl; + } + advice call(inner()) || execution(inner()) || construction(inner()) || destruction(inner()) || get(inner()) || set(inner()) || ref(inner()) : before() { + cout << JPType(JoinPoint::JPTYPE) << "(\"A::B::C::InC::Inner\"): " << JoinPoint::signature() << endl; + } + + // slice matching + advice a() : slice class { + static const int y = JoinPoint::MEMBERS; + }; + + advice in_c() : slice class { + static const int z = JoinPoint::MEMBERS; + }; + + advice inner() : slice class { + static const int a1 = JoinPoint::MEMBERS; + static const int a2 = JoinPoint::MEMBERS; + static const int a3 = JoinPoint::MEMBERS; + }; + +}; diff --git a/AspectC++/tests/MatchScopeWithin/Makefile b/AspectC++/tests/MatchScopeWithin/Makefile new file mode 100644 index 0000000..f485359 --- /dev/null +++ b/AspectC++/tests/MatchScopeWithin/Makefile @@ -0,0 +1,2 @@ +ACFLAGS ?= --introspection +include ../Makefile.generic diff --git a/AspectC++/tests/MatchScopeWithin/feature.ref b/AspectC++/tests/MatchScopeWithin/feature.ref new file mode 100644 index 0000000..d36c221 --- /dev/null +++ b/AspectC++/tests/MatchScopeWithin/feature.ref @@ -0,0 +1,6 @@ +within("A"): void foo() at line 14 +within("A::B"): void foo() at line 14 +within("A::B::C::InC"): void foo() at line 14 +within("A"): void foo() at line 18 +within("A::B"): void foo() at line 18 +within("A::B::C::InC::Inner"): void foo() at line 18 diff --git a/AspectC++/tests/MatchScopeWithin/main.cc b/AspectC++/tests/MatchScopeWithin/main.cc new file mode 100644 index 0000000..fb7c199 --- /dev/null +++ b/AspectC++/tests/MatchScopeWithin/main.cc @@ -0,0 +1,62 @@ +#include +using namespace std; + +void foo() {} + +namespace A { + +namespace B { + +namespace C { + +class InC { + public: + void bar() { foo(); in.bar1(); } + + class Inner { + public: + void bar1() { foo(); } // within("A::B::C::InC") should not match + } in; +}; + +} // C + +} // B + +} // A + +static const int expected_matches = 6; +int matches = 0; + +int main() { + A::B::C::InC c; + c.bar(); + + if(matches != expected_matches){ + cout << "ERROR: there should have been " << expected_matches << " matches instead of " << matches << endl; + } +}; + +aspect MatchScopeWithin { + + advice call("void foo()") && within("A") : before() { // 2 matches + cout << "within(\"A\"): " << JoinPoint::signature() << " at line " << tjp->line() << endl; + ++matches; + } + + advice call("void foo()") && within("A::B") : before() { // 2 matches + cout << "within(\"A::B\"): " << JoinPoint::signature() << " at line " << tjp->line() << endl; + ++matches; + } + + advice call("void foo()") && within("A::B::C::InC") : before() { // should only match at line 14 (not 18) -> 1 match + cout << "within(\"A::B::C::InC\"): " << JoinPoint::signature() << " at line " << tjp->line() << endl; + ++matches; + } + + advice call("void foo()") && within("A::B::C::InC::Inner") : before() { // 1 match + cout << "within(\"A::B::C::InC::Inner\"): " << JoinPoint::signature() << " at line " << tjp->line() << endl; + ++matches; + } + +}; diff --git a/AspectC++/tests/MatchStatic/Makefile b/AspectC++/tests/MatchStatic/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/MatchStatic/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/MatchStatic/feature.ref b/AspectC++/tests/MatchStatic/feature.ref new file mode 100644 index 0000000..98df428 --- /dev/null +++ b/AspectC++/tests/MatchStatic/feature.ref @@ -0,0 +1,16 @@ +Check the match mechanism for 'static' in match expressions +============================================================ +call to void Test::static_func() + STATIC function +call to void Test::static_func() + STATIC function +call to void Test::non_static_func() + NON-STATIC function +call to void Test::virtual_func() + NON-STATIC function +------------------------------------------------------------ +call to void static_func() + STATIC function +call to void non_static_func() + NON-STATIC function +============================================================ diff --git a/AspectC++/tests/MatchStatic/main.cc b/AspectC++/tests/MatchStatic/main.cc new file mode 100644 index 0000000..91c1857 --- /dev/null +++ b/AspectC++/tests/MatchStatic/main.cc @@ -0,0 +1,38 @@ +#include + +struct Test { + static void static_func() {} + void non_static_func () {} + virtual void virtual_func () {} +}; + +static void static_func() {} +void non_static_func() {} + +aspect Trace { + pointcut excl() = call ("% printf(...)"); + advice !excl() && call("% ...::%(...)") : before () { + printf ("call to %s\n", JoinPoint::signature ()); + } + advice !excl() && call("static % ...::%(...)") : before () { + printf (" STATIC function\n"); + } + advice !excl() && call("% ...::%(...)") && !call ("static % ...::%(...)"): before () { + printf (" NON-STATIC function\n"); + } +}; + +int main () { + printf ("Check the match mechanism for 'static' in match expressions\n"); + printf ("============================================================\n"); + Test test; + test.static_func (); + Test::static_func (); + test.non_static_func (); + test.virtual_func (); + printf ("------------------------------------------------------------\n"); + static_func (); + non_static_func (); + printf ("============================================================\n"); + return 0; +} diff --git a/AspectC++/tests/MatchVirtual/Makefile b/AspectC++/tests/MatchVirtual/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/MatchVirtual/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/MatchVirtual/feature.ref b/AspectC++/tests/MatchVirtual/feature.ref new file mode 100644 index 0000000..fbcef40 --- /dev/null +++ b/AspectC++/tests/MatchVirtual/feature.ref @@ -0,0 +1,13 @@ +Check the match mechanism for 'virtual' in match expressions +============================================================ +call to void BAR::barMethod() + NON-VIRTUAL method +call to void BAR::fooBarMethod() + VIRTUAL method +call to void BAR::fooBarMethod(int) + NON-VIRTUAL method +call to void FOO::fooBarMethod() + VIRTUAL method +call to void FOOBAR::other() + NON-VIRTUAL method +============================================================ diff --git a/AspectC++/tests/MatchVirtual/main.cc b/AspectC++/tests/MatchVirtual/main.cc new file mode 100644 index 0000000..5202d94 --- /dev/null +++ b/AspectC++/tests/MatchVirtual/main.cc @@ -0,0 +1,52 @@ +#include + +class FOOBAR { +protected: + virtual void fooBarMethod(); + void other () {} +}; + +class FOO : protected FOOBAR{ +public: + friend int main (); + void fooBarMethod () { other(); } // virtual function, too +}; + +class BAR : FOO { +public: + void barMethod(); + void fooBarMethod(); // virtual, but not declared as virtual + void fooBarMethod(int); // same name, but not virtual +}; + +void FOOBAR::fooBarMethod() {} + +void BAR::fooBarMethod() {} +void BAR::fooBarMethod(int) {} + +void BAR::barMethod() { fooBarMethod(); fooBarMethod (42); } + +aspect Trace { + pointcut excl() = call ("% printf(...)"); + advice !excl() && call("% ...::%(...)") : before () { + printf ("call to %s\n", JoinPoint::signature ()); + } + advice !excl() && call("virtual % ...::%(...)") : before () { + printf (" VIRTUAL method\n"); + } + advice !excl() && target("%") && !call ("virtual % ...::%(...)"): before () { + printf (" NON-VIRTUAL method\n"); + } +}; + +int main () { + printf ("Check the match mechanism for 'virtual' in match expressions\n"); + printf ("============================================================\n"); + BAR bar; + bar.barMethod(); + FOO *fooptr = new FOO; + fooptr->fooBarMethod (); + delete fooptr; + printf ("============================================================\n"); + return 0; +} diff --git a/AspectC++/tests/MemberPointCut/Makefile b/AspectC++/tests/MemberPointCut/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/MemberPointCut/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/MemberPointCut/feature.ref b/AspectC++/tests/MemberPointCut/feature.ref new file mode 100644 index 0000000..1928e84 --- /dev/null +++ b/AspectC++/tests/MemberPointCut/feature.ref @@ -0,0 +1,52 @@ + +All: void test() +Root (long): void test() +Root (rec,new): void test() +Root (norec,new): void test() + +All: void T::test() +Root (rec,new): void T::test() +WCard (rec,new): void T::test() +WCard (norec,new): void T::test() +T (long): void T::test() +T (new): void T::test() + +All: void T::testS() +Root (rec,new): void T::testS() +WCard (rec,new): void T::testS() +WCard (norec,new): void T::testS() +T (long): void T::testS() +T (new): void T::testS() + +All: void Q::R::test() +Root (rec,new): void Q::R::test() +WCard (rec,new): void Q::R::test() +Q (rec,long): void Q::R::test() +Q (rec,new): void Q::R::test() +Q::R (long): void Q::R::test() +Q::R (new): void Q::R::test() + +All: void Q::R::test() +Root (rec,new): void Q::R::test() +WCard (rec,new): void Q::R::test() +Q (rec,long): void Q::R::test() +Q (rec,new): void Q::R::test() +Q::R (long): void Q::R::test() +Q::R (new): void Q::R::test() + +All: void Q::R::testS() +Root (rec,new): void Q::R::testS() +WCard (rec,new): void Q::R::testS() +Q (rec,long): void Q::R::testS() +Q (rec,new): void Q::R::testS() +Q::R (long): void Q::R::testS() +Q::R (new): void Q::R::testS() + +All: void Q::test() +Root (rec,new): void Q::test() +WCard (rec,new): void Q::test() +WCard (norec,new): void Q::test() +Q (long): void Q::test() +Q (norec,new): void Q::test() +Q (rec,long): void Q::test() +Q (rec,new): void Q::test() diff --git a/AspectC++/tests/MemberPointCut/main.cc b/AspectC++/tests/MemberPointCut/main.cc new file mode 100644 index 0000000..521f88c --- /dev/null +++ b/AspectC++/tests/MemberPointCut/main.cc @@ -0,0 +1,33 @@ +#include + +using namespace std; + +void test() {}; + +class T { +public: + void test() {}; + static void testS() {}; +} t; + +namespace Q { + class R { + public: + void test() {}; + static void testS() {}; + } r; + void test() {}; +} +Q::R r; + +int main() { + test(); + t.test(); + T::testS(); + Q::r.test(); + r.test(); + Q::R::testS(); + Q::test(); + + return 0; +} diff --git a/AspectC++/tests/MemberPointCut/marker.ah b/AspectC++/tests/MemberPointCut/marker.ah new file mode 100644 index 0000000..1dbe127 --- /dev/null +++ b/AspectC++/tests/MemberPointCut/marker.ah @@ -0,0 +1,52 @@ +#ifndef __MARKER_AH__ +#define __MARKER_AH__ + +#include + +using namespace std; + +aspect Marker { + advice call( "% ...::%(...)" ) : before() { + cout << endl << "All: " << tjp->signature() << endl; + } + advice call( "% %(...)" ) : before() { + cout << "Root (long): " << tjp->signature() << endl; + } + advice call( member( "::" ) ) : before() { + cout << "Root (rec,new): " << tjp->signature() << endl; + } + advice call( member( "::" ) && ! member( member( "::" ) ) ) : before() { + cout << "Root (norec,new): " << tjp->signature() << endl; + } + advice call( member( "%" ) ) : before() { + cout << "WCard (rec,new): " << tjp->signature() << endl; + } + advice call( member( "%" ) && ! member( member( "%" ) ) ) : before() { + cout << "WCard (norec,new): " << tjp->signature() << endl; + } + advice call( "% T::%(...)" ) : before() { + cout << "T (long): " << tjp->signature() << endl; + } + advice call( member( "T" ) ) : before() { + cout << "T (new): " << tjp->signature() << endl; + } + advice call( "% Q::%(...)" ) : before() { + cout << "Q (long): " << tjp->signature() << endl; + } + advice call( member( "Q" ) && ! member( member( "Q" ) ) ) : before() { + cout << "Q (norec,new): " << tjp->signature() << endl; + } + advice call( "% Q::...::%(...)" ) : before() { + cout << "Q (rec,long): " << tjp->signature() << endl; + } + advice call( member( "Q" ) ) : before() { + cout << "Q (rec,new): " << tjp->signature() << endl; + } + advice call( "% Q::R::%(...)" ) : before() { + cout << "Q::R (long): " << tjp->signature() << endl; + } + advice call( member( "Q::R" ) ) : before() { + cout << "Q::R (new): " << tjp->signature() << endl; + } +}; +#endif diff --git a/AspectC++/tests/MemberPointCut2/Makefile b/AspectC++/tests/MemberPointCut2/Makefile new file mode 100644 index 0000000..daa5e9e --- /dev/null +++ b/AspectC++/tests/MemberPointCut2/Makefile @@ -0,0 +1,2 @@ +ACFLAGS ?= --builtin_operators --data_joinpoints +include ../Makefile.generic diff --git a/AspectC++/tests/MemberPointCut2/feature.ref b/AspectC++/tests/MemberPointCut2/feature.ref new file mode 100644 index 0000000..402e56b --- /dev/null +++ b/AspectC++/tests/MemberPointCut2/feature.ref @@ -0,0 +1,57 @@ + +All: int a +Root (long): int a +Root (rec,new): int a +Root (norec,new): int a + +All: int b +Root (long): int b +Root (rec,new): int b +Root (norec,new): int b + +All: int T::a +Root (rec,new): int T::a +WCard (rec,new): int T::a +WCard (norec,new): int T::a +T (long): int T::a +T (new): int T::a + +All: int T::b +Root (rec,new): int T::b +WCard (rec,new): int T::b +WCard (norec,new): int T::b +T (long): int T::b +T (new): int T::b + +All: int Q::R::a +Root (rec,new): int Q::R::a +WCard (rec,new): int Q::R::a +Q (rec,long): int Q::R::a +Q (rec,new): int Q::R::a +Q::R (long): int Q::R::a +Q::R (new): int Q::R::a + +All: int Q::R::a +Root (rec,new): int Q::R::a +WCard (rec,new): int Q::R::a +Q (rec,long): int Q::R::a +Q (rec,new): int Q::R::a +Q::R (long): int Q::R::a +Q::R (new): int Q::R::a + +All: int Q::R::b +Root (rec,new): int Q::R::b +WCard (rec,new): int Q::R::b +Q (rec,long): int Q::R::b +Q (rec,new): int Q::R::b +Q::R (long): int Q::R::b +Q::R (new): int Q::R::b + +All: int Q::a +Root (rec,new): int Q::a +WCard (rec,new): int Q::a +WCard (norec,new): int Q::a +Q (long): int Q::a +Q (norec,new): int Q::a +Q (rec,long): int Q::a +Q (rec,new): int Q::a diff --git a/AspectC++/tests/MemberPointCut2/main.cc b/AspectC++/tests/MemberPointCut2/main.cc new file mode 100644 index 0000000..4ad8575 --- /dev/null +++ b/AspectC++/tests/MemberPointCut2/main.cc @@ -0,0 +1,37 @@ +#include + +using namespace std; + +int a = 42; +int b = 3; + +class T { +public: + int a; + static int b; +} t; +int T::b; + +namespace Q { + class R { + public: + int a; + static int b; + } r; + int a; +} +int Q::R::b; +Q::R r; + +int main() { + {int x = a;} + {int x = b;} + {int x = t.a;} + {int x = T::b;} + {int x = Q::r.a;} + {int x = r.a;} + {int x = Q::R::b;} + {int x = Q::a;} + + return 0; +} diff --git a/AspectC++/tests/MemberPointCut2/marker.ah b/AspectC++/tests/MemberPointCut2/marker.ah new file mode 100644 index 0000000..d96a289 --- /dev/null +++ b/AspectC++/tests/MemberPointCut2/marker.ah @@ -0,0 +1,52 @@ +#ifndef __MARKER_AH__ +#define __MARKER_AH__ + +#include + +using namespace std; + +aspect Marker { + advice get( "% ...::%" ) : before() { + cout << endl << "All: " << tjp->signature() << endl; + } + advice get( "% %" ) : before() { + cout << "Root (long): " << tjp->signature() << endl; + } + advice get( member( "::" ) ) : before() { + cout << "Root (rec,new): " << tjp->signature() << endl; + } + advice get( member( "::" ) && ! member( member( "::" ) ) ) : before() { + cout << "Root (norec,new): " << tjp->signature() << endl; + } + advice get( member( "%" ) ) : before() { + cout << "WCard (rec,new): " << tjp->signature() << endl; + } + advice get( member( "%" ) && ! member( member( "%" ) ) ) : before() { + cout << "WCard (norec,new): " << tjp->signature() << endl; + } + advice get( "% T::%" ) : before() { + cout << "T (long): " << tjp->signature() << endl; + } + advice get( member( "T" ) ) : before() { + cout << "T (new): " << tjp->signature() << endl; + } + advice get( "% Q::%" ) : before() { + cout << "Q (long): " << tjp->signature() << endl; + } + advice get( member( "Q" ) && ! member( member( "Q" ) ) ) : before() { + cout << "Q (norec,new): " << tjp->signature() << endl; + } + advice get( "% Q::...::%" ) : before() { + cout << "Q (rec,long): " << tjp->signature() << endl; + } + advice get( member( "Q" ) ) : before() { + cout << "Q (rec,new): " << tjp->signature() << endl; + } + advice get( "% Q::R::%" ) : before() { + cout << "Q::R (long): " << tjp->signature() << endl; + } + advice get( member( "Q::R" ) ) : before() { + cout << "Q::R (new): " << tjp->signature() << endl; + } +}; +#endif diff --git a/AspectC++/tests/NameMangling/Makefile b/AspectC++/tests/NameMangling/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/NameMangling/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/NameMangling/NeedsMangling.ah b/AspectC++/tests/NameMangling/NeedsMangling.ah new file mode 100644 index 0000000..7efd488 --- /dev/null +++ b/AspectC++/tests/NameMangling/NeedsMangling.ah @@ -0,0 +1,12 @@ +#ifndef __NeedsMangling__ +#define __NeedsMangling__ + +#include + +aspect NeedsMangling { + advice call("% func()") : before () { + printf ("%s\n", JoinPoint::signature ()); + } +}; + +#endif // __NeedsMangling__ diff --git a/AspectC++/tests/NameMangling/feature.ref b/AspectC++/tests/NameMangling/feature.ref new file mode 100644 index 0000000..ab631d9 --- /dev/null +++ b/AspectC++/tests/NameMangling/feature.ref @@ -0,0 +1,7 @@ +Name Mangling: func() should be invoked several times: +====================================================== +void func() +void func() +void func() +void func() +void func() diff --git a/AspectC++/tests/NameMangling/main.cc b/AspectC++/tests/NameMangling/main.cc new file mode 100644 index 0000000..d5fc6b7 --- /dev/null +++ b/AspectC++/tests/NameMangling/main.cc @@ -0,0 +1,41 @@ +#include + +void func () { +} + +class Test { +public: + Test () { + func (); + } + ~Test () { + func (); + } + void *operator -> () { + func (); + return 0; + } + void foo (int) const /* volatile */ { + func (); + } + void foo (int) { + func (); + } +}; + +namespace Name { + void space () { + func (); + } +} + +int main () { + printf ("Name Mangling: func() should be invoked several times:\n"); + printf ("======================================================\n"); + Test obj; + obj.operator -> (); + obj.foo (4711); + Name::space (); + return 0; +} + diff --git a/AspectC++/tests/NamedPointcuts/Makefile b/AspectC++/tests/NamedPointcuts/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/NamedPointcuts/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/NamedPointcuts/feature.ref b/AspectC++/tests/NamedPointcuts/feature.ref new file mode 100644 index 0000000..bd6efa3 --- /dev/null +++ b/AspectC++/tests/NamedPointcuts/feature.ref @@ -0,0 +1,14 @@ +NamePointcuts: test use of named pointcuts in different scopes +============================================================== +advice on pGlobal +advice on pGlobal2 +advice on A::pA +advice on B::pA +advice on C::pA +advice on N1::pN1 +advice on N1::N2::pN2 +advice on N3::pN1 +advice on pTestParam in advice +advice on pTestParam in aspect +advice on pGlobalParam +============================================================= diff --git a/AspectC++/tests/NamedPointcuts/main.cc b/AspectC++/tests/NamedPointcuts/main.cc new file mode 100644 index 0000000..85f18bb --- /dev/null +++ b/AspectC++/tests/NamedPointcuts/main.cc @@ -0,0 +1,94 @@ +#include + +void func() {} +void func(int) {} + +pointcut pGlobalParam(int i) = execution("void func(...)") && args(i); + +pointcut pGlobal() = execution("void func()"); +pointcut pGlobal2() = pGlobal(); + +struct A { + pointcut pA() = ::pGlobal(); +}; + +struct B : public A {}; + +typedef B C; + +template struct T { + // forbidden: named pointcuts may not be defined in templates (new phase 1 parser!) + // pointcut pT() = pGlobal (); +}; + +namespace N1 { + + pointcut pN1() = pGlobal2(); + + namespace N2 { + pointcut pN2() = pGlobal(); + } + +} + +// Does not work! For some unknown reason a using declaration does not work +// for named pointcuts: +// using N1::pN1; + +namespace N3 { + + using namespace N1; + +} + +int main() { + A a; + printf ("NamePointcuts: test use of named pointcuts in different scopes\n"); + printf ("==============================================================\n"); + func(); + func(42); + printf ("=============================================================\n"); +} + +aspect Test { + pointcut pTestParam(int i) = execution("void func(...)") && args(i); + + advice execution("void func(...)") && args(i) : before (int i) { + printf ("advice on pTestParam in advice\n"); + } + advice pTestParam(j) : before (int j) { + printf ("advice on pTestParam in aspect\n"); + } + advice ::pGlobalParam(k) : before (int k) { + printf ("advice on pGlobalParam\n"); + } + + advice pGlobal() : before () { + printf ("advice on pGlobal\n"); + } + advice pGlobal2() : before () { + printf ("advice on pGlobal2\n"); + } + advice A::pA() : before () { + printf ("advice on A::pA\n"); + } + advice B::pA() : before () { + printf ("advice on B::pA\n"); + } + advice C::pA() : before () { + printf ("advice on C::pA\n"); + } + // forbidden: named pointcuts may not be defined in templates (new phase 1 parser!) + // advice T<1>::pT() : before () { + // printf ("advice on T<1>::pT\n"); + // } + advice N1::pN1() : before () { + printf ("advice on N1::pN1\n"); + } + advice N1::N2::pN2() : before () { + printf ("advice on N1::N2::pN2\n"); + } + advice N3::pN1() : before () { + printf ("advice on N3::pN1\n"); + } +}; diff --git a/AspectC++/tests/Namespaces/Makefile b/AspectC++/tests/Namespaces/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Namespaces/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Namespaces/main.cc b/AspectC++/tests/Namespaces/main.cc new file mode 100644 index 0000000..7077b7b --- /dev/null +++ b/AspectC++/tests/Namespaces/main.cc @@ -0,0 +1,54 @@ +#include + +namespace n1 { + namespace n2 { +// class C1; + class C2 { + enum { VAL = 2 }; + public: + void f () {} + }; + template class C3 { + enum { VAL = 3 }; + public: + void f () {} + }; + } +} + +namespace n3 { +template class C4; +} + +template class n3::C4 { + enum { VAL = 4 }; +public: + void f () {} +}; + +// class n1::n2::C1 { enum { VAL = 3 }; void f () {} }; + +aspect BigBrother { + advice execution ("%") : before () { + printf ("%s: %d\n", tjp->signature (), tjp->that ()->VAL); + } + advice that ("n1::n2::C2") && execution ("%") : before () { + printf ("that C2: %s\n", tjp->signature ()); + } +}; + +int main() { + using namespace n1::n2; +// C1 c1; + C2 c2; + C3 c3; + n3::C4 c4; + printf ("Namespace:\n"); + printf ("===============================================================\n"); +// c1.f (); + c2.f (); + c3.f (); + c4.f (); + printf ("---------------------------------------------------------------\n"); + return 0; +} diff --git a/AspectC++/tests/NestedClassFuncAdvice/Aspect.ah b/AspectC++/tests/NestedClassFuncAdvice/Aspect.ah new file mode 100644 index 0000000..82478f8 --- /dev/null +++ b/AspectC++/tests/NestedClassFuncAdvice/Aspect.ah @@ -0,0 +1,17 @@ +#ifndef __Aspect_ah__ +#define __Aspect_ah__ + +#include + +aspect Aspect { + + // pointcut methods() = execution("% ...::func1(...)"); + pointcut methods() = execution("% ...::%func%(...)"); + + advice methods() : before() + { + printf("before %s\n", thisJoinPoint->signature()); + } + +}; +#endif // __Aspect_ah__ diff --git a/AspectC++/tests/NestedClassFuncAdvice/Makefile b/AspectC++/tests/NestedClassFuncAdvice/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/NestedClassFuncAdvice/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/NestedClassFuncAdvice/feature.ref b/AspectC++/tests/NestedClassFuncAdvice/feature.ref new file mode 100644 index 0000000..c57b37c --- /dev/null +++ b/AspectC++/tests/NestedClassFuncAdvice/feature.ref @@ -0,0 +1,7 @@ +NestedClassFuncAdvice +============================================================= +before void func() +in func() +before void Class1::Class2::func1() +in Class1::Class2::func1() +============================================================= diff --git a/AspectC++/tests/NestedClassFuncAdvice/main.cc b/AspectC++/tests/NestedClassFuncAdvice/main.cc new file mode 100644 index 0000000..b62e2c9 --- /dev/null +++ b/AspectC++/tests/NestedClassFuncAdvice/main.cc @@ -0,0 +1,32 @@ +#include + + +void func () { + + printf ("in func()\n"); +} + + +class Class1 +{ +public: + class Class2 + { + public: + void func1() + { + printf("in Class1::Class2::func1()\n"); + } + } class2Instance; +}; + + +int main (int argc, char * argv[]) { + printf ("NestedClassFuncAdvice\n"); + printf ("=============================================================\n"); + func (); + Class1 class1; + class1.class2Instance.func1(); + printf ("=============================================================\n"); + return 0; +} diff --git a/AspectC++/tests/NonInlineIntroInclude/A.cc b/AspectC++/tests/NonInlineIntroInclude/A.cc new file mode 100644 index 0000000..93d9705 --- /dev/null +++ b/AspectC++/tests/NonInlineIntroInclude/A.cc @@ -0,0 +1,3 @@ +#include "A.h" + +int A::I_am_the_link_once_object = 0; diff --git a/AspectC++/tests/NonInlineIntroInclude/A.h b/AspectC++/tests/NonInlineIntroInclude/A.h new file mode 100644 index 0000000..5cd83e1 --- /dev/null +++ b/AspectC++/tests/NonInlineIntroInclude/A.h @@ -0,0 +1,8 @@ +#ifndef __A_h__ +#define __A_h__ + +class A { + static int I_am_the_link_once_object; +}; + +#endif // __A_h__ diff --git a/AspectC++/tests/NonInlineIntroInclude/ABDecl.ah b/AspectC++/tests/NonInlineIntroInclude/ABDecl.ah new file mode 100644 index 0000000..f76d288 --- /dev/null +++ b/AspectC++/tests/NonInlineIntroInclude/ABDecl.ah @@ -0,0 +1,19 @@ +#ifndef __ABDecl_ah__ +#define __ABDecl_ah__ + +// Forward declarations +class A; +class B; + +aspect ABDecl { +public: + // introduce references into A and B (crossed) + advice "A" : B *_bref; + advice "B" : A *_aref; + + // introduce the function declarations + advice "A"||"B" : void f1 (); + advice "A"||"B" : void f2 (); +}; + +#endif // __ABDecl_ah__ diff --git a/AspectC++/tests/NonInlineIntroInclude/ABDef.ah b/AspectC++/tests/NonInlineIntroInclude/ABDef.ah new file mode 100644 index 0000000..42a9054 --- /dev/null +++ b/AspectC++/tests/NonInlineIntroInclude/ABDef.ah @@ -0,0 +1,29 @@ +#ifndef __ABDef_ah__ +#define __ABDef_ah__ + +#include +#include "A.h" +#include "B.h" + +aspect ABDef { +}; + +advice "A" : void ABDef::f1 () { + printf (" function A::f1()\n"); +} + +advice "A" : void ABDef::f2 () { + printf (" function A::f2 calls B::f1\n"); + _bref->f1 (); +} + +advice "B" : void ABDef::f1 () { + printf (" function B::f1()\n"); +} + +advice "B" : void ABDef::f2 () { + printf (" function B::f2 calls A::f1\n"); + _aref->f1 (); +} + +#endif // __ABDef_ah__ diff --git a/AspectC++/tests/NonInlineIntroInclude/B.cc b/AspectC++/tests/NonInlineIntroInclude/B.cc new file mode 100644 index 0000000..cba1b64 --- /dev/null +++ b/AspectC++/tests/NonInlineIntroInclude/B.cc @@ -0,0 +1,3 @@ +#include "B.h" + +int B::I_am_the_link_once_object = 0; diff --git a/AspectC++/tests/NonInlineIntroInclude/B.h b/AspectC++/tests/NonInlineIntroInclude/B.h new file mode 100644 index 0000000..df6ba75 --- /dev/null +++ b/AspectC++/tests/NonInlineIntroInclude/B.h @@ -0,0 +1,8 @@ +#ifndef __B_h__ +#define __B_h__ + +class B { + static int I_am_the_link_once_object; +}; + +#endif // __B_h__ diff --git a/AspectC++/tests/NonInlineIntroInclude/C.cc b/AspectC++/tests/NonInlineIntroInclude/C.cc new file mode 100644 index 0000000..283514e --- /dev/null +++ b/AspectC++/tests/NonInlineIntroInclude/C.cc @@ -0,0 +1,3 @@ +#include "C.h" + +int C::I_am_the_link_once_object = 0; diff --git a/AspectC++/tests/NonInlineIntroInclude/C.h b/AspectC++/tests/NonInlineIntroInclude/C.h new file mode 100644 index 0000000..cfec84d --- /dev/null +++ b/AspectC++/tests/NonInlineIntroInclude/C.h @@ -0,0 +1,11 @@ +#ifndef __C_h__ +#define __C_h__ + +class C { + static int I_am_the_link_once_object; + +public: + enum T { V1, V2 }; +}; + +#endif // __C_h__ diff --git a/AspectC++/tests/NonInlineIntroInclude/CDecl.ah b/AspectC++/tests/NonInlineIntroInclude/CDecl.ah new file mode 100644 index 0000000..5ea27dd --- /dev/null +++ b/AspectC++/tests/NonInlineIntroInclude/CDecl.ah @@ -0,0 +1,9 @@ +#ifndef __CDdecl_ah__ +#define __CDdecl_ah__ + +aspect CDecl { +public: + advice "C" : void f (); +}; + +#endif // __CDdecl_ah__ diff --git a/AspectC++/tests/NonInlineIntroInclude/CDef.ah b/AspectC++/tests/NonInlineIntroInclude/CDef.ah new file mode 100644 index 0000000..20831db --- /dev/null +++ b/AspectC++/tests/NonInlineIntroInclude/CDef.ah @@ -0,0 +1,13 @@ +#ifndef __Aspect_ah__ +#define __Aspect_ah__ + +#include +#include "C.h" +#include "CDecl.ah" + +advice "C" : void CDecl::f () { + C::T _a_type_from_C_used_for_me; + printf (" function f () introducd by an aspect\n"); +} + +#endif // __Aspect_ah__ diff --git a/AspectC++/tests/NonInlineIntroInclude/Makefile b/AspectC++/tests/NonInlineIntroInclude/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/NonInlineIntroInclude/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/NonInlineIntroInclude/feature.ref b/AspectC++/tests/NonInlineIntroInclude/feature.ref new file mode 100644 index 0000000..c164b92 --- /dev/null +++ b/AspectC++/tests/NonInlineIntroInclude/feature.ref @@ -0,0 +1,7 @@ +NonInlineIntroIncludes: check for include generation in .cc +=========================================================== + function f () introducd by an aspect + function A::f1() + function A::f2 calls B::f1 + function B::f1() +=========================================================== diff --git a/AspectC++/tests/NonInlineIntroInclude/main.cc b/AspectC++/tests/NonInlineIntroInclude/main.cc new file mode 100644 index 0000000..b0fd2c8 --- /dev/null +++ b/AspectC++/tests/NonInlineIntroInclude/main.cc @@ -0,0 +1,15 @@ +#include + +#include "C.h" +#include "A.h" + +int main () { + C c; + A a; + printf ("NonInlineIntroIncludes: check for include generation in .cc\n"); + printf ("===========================================================\n"); + c.f (); + a.f1 (); + a.f2 (); + printf ("===========================================================\n"); +} diff --git a/AspectC++/tests/NonInlineIntros/C.cc b/AspectC++/tests/NonInlineIntros/C.cc new file mode 100644 index 0000000..bcb7817 --- /dev/null +++ b/AspectC++/tests/NonInlineIntros/C.cc @@ -0,0 +1,35 @@ +#include + +#include "C.h" +#include "D.h" +#include "E.h" +#include "F.h" + +void C::f () { printf ("void C::f()\n"); } + +void D::f () { printf ("void D::f()\n"); } + +int main () { + C c; + D d; + E e; + printf ("NonInlineIntros: Checks location of non-inline introductions\n"); + printf ("============================================================\n"); + printf ("calling normal functions:\n"); + c.f (); + d.f (); + e.f (); + F::f (); + printf ("calling introduced functions:\n"); + c.g (); + d.g (); + F f; + f.g (); + printf ("accessing introduced static members:\n"); + printf ("C::pi is %f\n", C::pi); + printf ("D::pi is %f\n", D::pi); + printf ("F::pi is %f\n", F::pi); + printf ("============================================================\n"); +} + +// here the non-inline intros for C and D should be added ... diff --git a/AspectC++/tests/NonInlineIntros/C.h b/AspectC++/tests/NonInlineIntros/C.h new file mode 100644 index 0000000..0637eb5 --- /dev/null +++ b/AspectC++/tests/NonInlineIntros/C.h @@ -0,0 +1,15 @@ +#ifndef __C_h__ +#define __C_h__ + +class C { +public: + template void a_template_function (); + + void f (); // link-once code element +}; + +// this should no be considered as the link-once code element +template +void C::a_template_function () {} + +#endif // __C_h__ diff --git a/AspectC++/tests/NonInlineIntros/D.cc b/AspectC++/tests/NonInlineIntros/D.cc new file mode 100644 index 0000000..a6d3c03 --- /dev/null +++ b/AspectC++/tests/NonInlineIntros/D.cc @@ -0,0 +1,5 @@ +#include "D.h" + +int D::k = 4711; + +// here nothing should be added diff --git a/AspectC++/tests/NonInlineIntros/D.h b/AspectC++/tests/NonInlineIntros/D.h new file mode 100644 index 0000000..2ec7141 --- /dev/null +++ b/AspectC++/tests/NonInlineIntros/D.h @@ -0,0 +1,12 @@ +#ifndef __D_h__ +#define __D_h__ + +class D { + int i; + static const int j = 3; + static int k; +public: + void f (); // link-once code element (functions first) +}; + +#endif // __D_h__ diff --git a/AspectC++/tests/NonInlineIntros/E.h b/AspectC++/tests/NonInlineIntros/E.h new file mode 100644 index 0000000..eca3b2f --- /dev/null +++ b/AspectC++/tests/NonInlineIntros/E.h @@ -0,0 +1,19 @@ +#ifndef __E_h__ +#define __E_h__ + +#include + +class E { + int a; + int b; +public: + template void a_template_function (); + + void f () { printf ("void E::f()\n"); } +}; + +// this should no be considered as the link-once code element +template +void E::a_template_function () {} + +#endif // __E_h__ diff --git a/AspectC++/tests/NonInlineIntros/F.cc b/AspectC++/tests/NonInlineIntros/F.cc new file mode 100644 index 0000000..75afece --- /dev/null +++ b/AspectC++/tests/NonInlineIntros/F.cc @@ -0,0 +1,3 @@ +#include "F.h" + +int F::nci = 4711; diff --git a/AspectC++/tests/NonInlineIntros/F.h b/AspectC++/tests/NonInlineIntros/F.h new file mode 100644 index 0000000..e27c7d1 --- /dev/null +++ b/AspectC++/tests/NonInlineIntros/F.h @@ -0,0 +1,22 @@ +#ifndef __F_h__ +#define __F_h__ + +#include + +class F { + int a; + int b; +public: + template void a_template_function (); + + static void f () { printf ("static void F::f()\n"); } + + static const int ci = 12; + static int nci; +}; + +// this should no be considered as the link-once code element +template +void F::a_template_function () {} + +#endif // __F_h__ diff --git a/AspectC++/tests/NonInlineIntros/Intro.ah b/AspectC++/tests/NonInlineIntros/Intro.ah new file mode 100644 index 0000000..215e368 --- /dev/null +++ b/AspectC++/tests/NonInlineIntros/Intro.ah @@ -0,0 +1,60 @@ +#ifndef __Intro_ah__ +#define __Intro_ah__ + +#include + +class Foo; + +aspect Intro { + pointcut dest () = "C"||"D"||"E"||"F"; +public: + static const int val = 2; + advice dest () : slice struct { unsigned long int I1; }; + advice dest () : slice struct { signed short (I2); }; + advice dest () : slice struct { int Foo::*(*I3); }; + advice dest () : slice struct { double Foo::*(* const (*I4(int,long))[47 + 11]); }; + advice dest () : slice struct { void I5(Intro::Int*),(*I6); }; + advice dest () : slice struct SL0 { static float pi; }; + advice dest () && !"E": slice struct SL05 { struct S1 { + S1 (); + ~S1 (); + void f (); + } IS1; }; + // advice dest () : struct { struct Y {}; } IS2, *IS3; <== invalid C++ code! + advice dest () : slice struct { struct Z { struct Y {}; } IS2, *IS3; }; + typedef int Int; + advice dest () : slice struct SL1 { + SL1 () {} + SL1 (Intro::Int); + }; + advice dest () && !"E" : slice struct SL2 { ~SL2 (); }; + advice dest () : slice struct SL3 { const Intro::Int square (Intro::Int); }; + advice dest () : slice struct { void *operator new (size_t), *pp; }; + advice dest () : slice struct SL4 { void g(); }; + advice dest () : slice struct { static const int v = (8 + 15 ) * sizeof(int) / Intro::val; }; +}; + +slice void Intro::SL4::g() { printf ("introduced ...::g()\n"); } +slice float Intro::SL0::pi = 3.14f; +slice Intro::SL1::SL1 (Intro::Int) : I3 (0) { + printf ("introduced constructor\n"); +} +slice Intro::SL2::~SL2 () { + square (Intro::val); + printf ("introduced destructor\n"); +} +slice const Intro::Int Intro::SL3::square (Intro::Int arg) { + printf ("introduced ...::square(Intro::Int)\n"); + return arg * arg; +} + +slice void Intro::SL05::S1::f () { +} + +slice Intro::SL05::S1::S1 () { +} + +slice Intro::SL05::S1::~S1 () { +} + +#endif // __Intro_ah__ diff --git a/AspectC++/tests/NonInlineIntros/Makefile b/AspectC++/tests/NonInlineIntros/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/NonInlineIntros/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/NonInlineIntros/feature.ref b/AspectC++/tests/NonInlineIntros/feature.ref new file mode 100644 index 0000000..db7b2fd --- /dev/null +++ b/AspectC++/tests/NonInlineIntros/feature.ref @@ -0,0 +1,22 @@ +NonInlineIntros: Checks location of non-inline introductions +============================================================ +calling normal functions: +void C::f() +void D::f() +void E::f() +static void F::f() +calling introduced functions: +introduced ...::g() +introduced ...::g() +introduced ...::g() +accessing introduced static members: +C::pi is 3.140000 +D::pi is 3.140000 +F::pi is 3.140000 +============================================================ +introduced ...::square(Intro::Int) +introduced destructor +introduced ...::square(Intro::Int) +introduced destructor +introduced ...::square(Intro::Int) +introduced destructor diff --git a/AspectC++/tests/NonInlineSliceInclude/A.cc b/AspectC++/tests/NonInlineSliceInclude/A.cc new file mode 100644 index 0000000..93d9705 --- /dev/null +++ b/AspectC++/tests/NonInlineSliceInclude/A.cc @@ -0,0 +1,3 @@ +#include "A.h" + +int A::I_am_the_link_once_object = 0; diff --git a/AspectC++/tests/NonInlineSliceInclude/A.h b/AspectC++/tests/NonInlineSliceInclude/A.h new file mode 100644 index 0000000..5cd83e1 --- /dev/null +++ b/AspectC++/tests/NonInlineSliceInclude/A.h @@ -0,0 +1,8 @@ +#ifndef __A_h__ +#define __A_h__ + +class A { + static int I_am_the_link_once_object; +}; + +#endif // __A_h__ diff --git a/AspectC++/tests/NonInlineSliceInclude/ABDecl.ah b/AspectC++/tests/NonInlineSliceInclude/ABDecl.ah new file mode 100644 index 0000000..fa98ceb --- /dev/null +++ b/AspectC++/tests/NonInlineSliceInclude/ABDecl.ah @@ -0,0 +1,27 @@ +#ifndef __ABDecl_ah__ +#define __ABDecl_ah__ + +#include + +// Forward declarations +class A; +class B; + +aspect ABCrossed { + + // introduce references into A and B (crossed) + advice "A" : slice class ASlice { + B *_bref; + public: + void f1 () { printf (" function ASlice::f1()\n"); } + void f2 (); + }; + advice "B" : slice class BSlice { + A *_aref; + public: + void f1 () { printf (" function BSlice::f1()\n"); } + void f2 (); + }; +}; + +#endif // __ABDecl_ah__ diff --git a/AspectC++/tests/NonInlineSliceInclude/ABDef.ah b/AspectC++/tests/NonInlineSliceInclude/ABDef.ah new file mode 100644 index 0000000..1766891 --- /dev/null +++ b/AspectC++/tests/NonInlineSliceInclude/ABDef.ah @@ -0,0 +1,19 @@ +#ifndef __ABDef_ah__ +#define __ABDef_ah__ + +#include +#include "A.h" +#include "B.h" +#include "ABDecl.ah" + +slice void ABCrossed::ASlice::f2 () { + printf (" function ABCrossed::ASlice::f2 calls B::f1\n"); + _bref->f1 (); +} + +slice void ABCrossed::BSlice::f2 () { + printf (" function ABCrossed::BSlice::f2 calls A::f1\n"); + _aref->f1 (); +} + +#endif // __ABDef_ah__ diff --git a/AspectC++/tests/NonInlineSliceInclude/B.cc b/AspectC++/tests/NonInlineSliceInclude/B.cc new file mode 100644 index 0000000..cba1b64 --- /dev/null +++ b/AspectC++/tests/NonInlineSliceInclude/B.cc @@ -0,0 +1,3 @@ +#include "B.h" + +int B::I_am_the_link_once_object = 0; diff --git a/AspectC++/tests/NonInlineSliceInclude/B.h b/AspectC++/tests/NonInlineSliceInclude/B.h new file mode 100644 index 0000000..df6ba75 --- /dev/null +++ b/AspectC++/tests/NonInlineSliceInclude/B.h @@ -0,0 +1,8 @@ +#ifndef __B_h__ +#define __B_h__ + +class B { + static int I_am_the_link_once_object; +}; + +#endif // __B_h__ diff --git a/AspectC++/tests/NonInlineSliceInclude/C.cc b/AspectC++/tests/NonInlineSliceInclude/C.cc new file mode 100644 index 0000000..283514e --- /dev/null +++ b/AspectC++/tests/NonInlineSliceInclude/C.cc @@ -0,0 +1,3 @@ +#include "C.h" + +int C::I_am_the_link_once_object = 0; diff --git a/AspectC++/tests/NonInlineSliceInclude/C.h b/AspectC++/tests/NonInlineSliceInclude/C.h new file mode 100644 index 0000000..cfec84d --- /dev/null +++ b/AspectC++/tests/NonInlineSliceInclude/C.h @@ -0,0 +1,11 @@ +#ifndef __C_h__ +#define __C_h__ + +class C { + static int I_am_the_link_once_object; + +public: + enum T { V1, V2 }; +}; + +#endif // __C_h__ diff --git a/AspectC++/tests/NonInlineSliceInclude/CDecl.ah b/AspectC++/tests/NonInlineSliceInclude/CDecl.ah new file mode 100644 index 0000000..ada1121 --- /dev/null +++ b/AspectC++/tests/NonInlineSliceInclude/CDecl.ah @@ -0,0 +1,8 @@ +#ifndef __CDecl_ah__ +#define __CDecl_ah__ + +aspect CDecl { + advice "C" : slice class CSlice { public: CSlice *f (); }; +}; + +#endif // __CDecl_ah__ diff --git a/AspectC++/tests/NonInlineSliceInclude/CDef.ah b/AspectC++/tests/NonInlineSliceInclude/CDef.ah new file mode 100644 index 0000000..e46d47d --- /dev/null +++ b/AspectC++/tests/NonInlineSliceInclude/CDef.ah @@ -0,0 +1,15 @@ +#ifndef __CDef_ah__ +#define __CDef_ah__ + +#include +#include "C.h" +#include "CDecl.ah" + +slice +CDecl::CSlice *CDecl::CSlice::f () { + C::T _a_type_from_C_used_for_me; + printf (" function f () introducd by an aspect\n"); + return this; +} + +#endif // __CDef_ah__ diff --git a/AspectC++/tests/NonInlineSliceInclude/Makefile b/AspectC++/tests/NonInlineSliceInclude/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/NonInlineSliceInclude/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/NonInlineSliceInclude/feature.ref b/AspectC++/tests/NonInlineSliceInclude/feature.ref new file mode 100644 index 0000000..9aebe7c --- /dev/null +++ b/AspectC++/tests/NonInlineSliceInclude/feature.ref @@ -0,0 +1,7 @@ +NonInlineSliceInclude: check for include generation in .cc +========================================================== + function f () introducd by an aspect + function ASlice::f1() + function ABCrossed::ASlice::f2 calls B::f1 + function BSlice::f1() +========================================================== diff --git a/AspectC++/tests/NonInlineSliceInclude/main.cc b/AspectC++/tests/NonInlineSliceInclude/main.cc new file mode 100644 index 0000000..535bec5 --- /dev/null +++ b/AspectC++/tests/NonInlineSliceInclude/main.cc @@ -0,0 +1,15 @@ +#include + +#include "C.h" +#include "A.h" + +int main () { + C c; + A a; + printf ("NonInlineSliceInclude: check for include generation in .cc\n"); + printf ("==========================================================\n"); + c.f (); + a.f1 (); + a.f2 (); + printf ("==========================================================\n"); +} diff --git a/AspectC++/tests/Order/Makefile b/AspectC++/tests/Order/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Order/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Order/feature.ref b/AspectC++/tests/Order/feature.ref new file mode 100644 index 0000000..a413c4e --- /dev/null +++ b/AspectC++/tests/Order/feature.ref @@ -0,0 +1,34 @@ +A1::before +A2::before +A3Base::around 1 +A3Base::around 2 +run +A3Base::after +A3::after first +A3::after last +A2::after +A1::after + + +A3Base::around 1 +A3Base::around 2 +A1::before +A2::before +run2 +A2::after +A1::after +A3Base::after +A3::after first +A3::after last + + +A2::before +A3Base::around 1 +A3Base::around 2 +A1::before +run3 +A1::after +A3Base::after +A3::after first +A3::after last +A2::after diff --git a/AspectC++/tests/Order/main.cc b/AspectC++/tests/Order/main.cc new file mode 100644 index 0000000..1e5ef3b --- /dev/null +++ b/AspectC++/tests/Order/main.cc @@ -0,0 +1,82 @@ +#include + +// --------------------------- Ordering code --------------------------- + +aspect Order_A1_A2_and_A3 { + advice execution("% C1::run2(...)") : order(base ("A3")||"A3","A1"||"A2"); +}; + +aspect Order_A1_and_A3 { + advice execution("% C1::run2(...)") : order("A3", "A1"); + advice "C1" : order("A3", "A1"); // order for intros into "C1" +}; + +aspect Order_A2_first { + advice execution("% C1::run3(...)") : order("A2", !"A2"); +}; + +// --------------------------- Aspect code ----------------------------- + +aspect A1 { + advice execution("void %::run%()") : after() { + printf("A1::after\n"); + } + advice execution("void %::run%()") : before() { + printf("A1::before\n"); + } + // type INT comes from A3 -> A3 needs higher precedence + advice "C1" : slice struct { INT i; }; +}; + +aspect A2 { + advice execution("void %::run%()") : before() { + printf("A2::before\n"); + } + advice execution("void %::run%()") : after() { + printf("A2::after\n"); + } +}; + +aspect A3Base { + pointcut virtual jps () = 0; + advice execution("void %::run%()") : after() { + printf("A3Base::after\n"); + } + advice execution("void %::run%()") : around() { + printf("A3Base::around 1\n"); + tjp->action ().trigger (); + } + advice execution("void %::run%()") : around() { + printf("A3Base::around 2\n"); + tjp->proceed (); + } +}; + +aspect A3 : public A3Base { + pointcut jps () = execution("void %::run%()"); + advice jps (): after() { + printf("A3::after last\n"); + } + advice jps () : after() { + printf("A3::after first\n"); + } + advice "C1" : slice struct { typedef int INT; }; +}; + +// ------------------------------- normal C++ ---------------------------- +class C1 { +public: + void run() { printf("run\n"); } + void run2() { printf("run2\n"); } + void run3() { printf("run3\n"); } +}; + +int main () { + C1 c1; + + c1.run(); + printf ("\n\n"); + c1.run2(); + printf ("\n\n"); + c1.run3(); +} diff --git a/AspectC++/tests/PctInClass/Makefile b/AspectC++/tests/PctInClass/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/PctInClass/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/PctInClass/feature.ref b/AspectC++/tests/PctInClass/feature.ref new file mode 100644 index 0000000..30bb3ee --- /dev/null +++ b/AspectC++/tests/PctInClass/feature.ref @@ -0,0 +1,5 @@ +PctInClass: tests pointcut lookup +================================= +before void N1::C::f() +after void N1::C::f() +================================= diff --git a/AspectC++/tests/PctInClass/main.cc b/AspectC++/tests/PctInClass/main.cc new file mode 100644 index 0000000..0dd3eaf --- /dev/null +++ b/AspectC++/tests/PctInClass/main.cc @@ -0,0 +1,26 @@ +#include + +namespace N1 { + class C { + public: + pointcut me() = "N1::C"; + void f () {} + }; +} + +aspect A { + advice execution ("% ...::%(...)") && within(N1::C::me()) : around () { + printf ("before %s\n", JoinPoint::signature ()); + tjp->proceed (); + printf ("after %s\n", JoinPoint::signature ()); + } +}; + +int main () { + N1::C c; + printf ("PctInClass: tests pointcut lookup\n"); + printf ("=================================\n"); + c.f (); + printf ("=================================\n"); +} + diff --git a/AspectC++/tests/PragmaOnce/Makefile b/AspectC++/tests/PragmaOnce/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/PragmaOnce/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/PragmaOnce/a.h b/AspectC++/tests/PragmaOnce/a.h new file mode 100644 index 0000000..062df26 --- /dev/null +++ b/AspectC++/tests/PragmaOnce/a.h @@ -0,0 +1,5 @@ +#pragma once +class C { +public: + int _var; +}; diff --git a/AspectC++/tests/PragmaOnce/b.h b/AspectC++/tests/PragmaOnce/b.h new file mode 100644 index 0000000..e91a09a --- /dev/null +++ b/AspectC++/tests/PragmaOnce/b.h @@ -0,0 +1,4 @@ +#pragma once + +#include "a.h" + diff --git a/AspectC++/tests/PragmaOnce/feature.ref b/AspectC++/tests/PragmaOnce/feature.ref new file mode 100644 index 0000000..796da0a --- /dev/null +++ b/AspectC++/tests/PragmaOnce/feature.ref @@ -0,0 +1,4 @@ +PragmaOnce: check how the include expander handles pragma once +============================================================== +Everything is fine if it compiles without warnings or errors +============================================================== diff --git a/AspectC++/tests/PragmaOnce/main.cc b/AspectC++/tests/PragmaOnce/main.cc new file mode 100644 index 0000000..5ef5ce1 --- /dev/null +++ b/AspectC++/tests/PragmaOnce/main.cc @@ -0,0 +1,15 @@ +#include + +// this should not result in an error +#include "a.h" +#include "b.h" + +int main () { + C c; + c._var = 0; // to avoid warnings + printf ("PragmaOnce: check how the include expander handles pragma once\n"); + printf ("==============================================================\n"); + printf ("Everything is fine if it compiles without warnings or errors\n"); + printf ("==============================================================\n"); + return 0; +} diff --git a/AspectC++/tests/PragmaOnceObserver/AnalogClock.cc b/AspectC++/tests/PragmaOnceObserver/AnalogClock.cc new file mode 100644 index 0000000..e7382b8 --- /dev/null +++ b/AspectC++/tests/PragmaOnceObserver/AnalogClock.cc @@ -0,0 +1,20 @@ +//========================================================= +// AnalogClock.cpp +// +// Implement member functions in AnalogClock class which +// is in file AnalogClock.h +//========================================================= +#include "AnalogClock.h" +#include "ClockTimer.h" +#include + +void AnalogClock::Draw (const ClockTimer &clock) +{ + int hour = clock.GetHour(); + int minute = clock.GetMinute(); + int second = clock.GetSecond(); + + std::cout << "Analog Clock time is " << hour << ":" + << minute << ":" + << second << std::endl; +} diff --git a/AspectC++/tests/PragmaOnceObserver/AnalogClock.h b/AspectC++/tests/PragmaOnceObserver/AnalogClock.h new file mode 100644 index 0000000..a0e5730 --- /dev/null +++ b/AspectC++/tests/PragmaOnceObserver/AnalogClock.h @@ -0,0 +1,29 @@ +#ifndef ANALOGCLOCK_H +#define ANALOGCLOCK_H + +//========================================================= +// ConcreteObserver class +// +// AnalogClock +// +// It is a ConcreteObserver class and is a child class of +// the Observer class. +// +// It is a analog clock observer. It attaches to a timer +// object of the type Subject at run time. The timer +// object calls AnalogClock member function Update() +// whenever there is a AnalogClock update required. +// AnalogClock obtain current time from the timer object +// by timer object's member functions GetHour(), +// GetMinutes, and GetSecond(). AnalogClock prints out +// the updated time. +// +//========================================================= +class ClockTimer; + +class AnalogClock { +public: + void Draw(const ClockTimer &); // print updated time +}; + +#endif diff --git a/AspectC++/tests/PragmaOnceObserver/ClockObserver.ah b/AspectC++/tests/PragmaOnceObserver/ClockObserver.ah new file mode 100644 index 0000000..f877066 --- /dev/null +++ b/AspectC++/tests/PragmaOnceObserver/ClockObserver.ah @@ -0,0 +1,37 @@ +#ifndef CLOCKOBSERVER_AH +#define CLOCKOBSERVER_AH + +#include "ObserverPattern.ah" + +slice struct Test { + void dummy1(); + void dummy2(); +}; + +slice void Test::dummy1() {} + + +slice void Test::dummy2() {} +aspect ClockObserver : public ObserverPattern { + pointcut subjectChange (Subject &subject) = + execution ("void ClockTimer::Tick()") && that (subject); + pointcut observers() = "DigitalClock"||"AnalogClock"; + +public: + + advice "ClockTimer" : slice struct : public ObserverPattern::Subject; + advice observers () : slice struct : public ObserverPattern::Observer; + advice observers () : slice struct { + void update (ObserverPattern::Subject *subject) { + Draw ((const ClockTimer &)*subject); + } + }; + advice observers () : slice Test; + + virtual void updateObserver(Subject *subject, Observer *observer) { + observer->update (subject); + } +}; + +#endif // CLOCKOBSERVER_AH + diff --git a/AspectC++/tests/PragmaOnceObserver/ClockTimer.cc b/AspectC++/tests/PragmaOnceObserver/ClockTimer.cc new file mode 100644 index 0000000..e431f92 --- /dev/null +++ b/AspectC++/tests/PragmaOnceObserver/ClockTimer.cc @@ -0,0 +1,18 @@ +//========================================================= +// ClockTimer.cpp +// +// Implement member functions in ClockTimer class which +// is in file ClockTimer.h +//========================================================= +#include "ClockTimer.h" + +void ClockTimer::Tick() { + // Obtain operating system-style time. (not portable, therefore faked) + _sec = (_sec + 1) % 60; + if (_sec == 0) { + _min = (_min + 1) % 60; + if (_min == 0) { + _hour = (_hour + 1) % 24; + } + } +} diff --git a/AspectC++/tests/PragmaOnceObserver/ClockTimer.h b/AspectC++/tests/PragmaOnceObserver/ClockTimer.h new file mode 100644 index 0000000..2c0cd9b --- /dev/null +++ b/AspectC++/tests/PragmaOnceObserver/ClockTimer.h @@ -0,0 +1,41 @@ +#pragma once + +// include files used to obtain the current system time +#include + +//========================================================= +// ConcreteSubject class +// +// ClockTimer +// +// It is a ConcreteSubject class and is a child class of +// the Subject class. +// +// It is a time observer. Whenever member function Tick() +// is called. It obtains the current system +// time and store it as a character string. It called +// the update function for all of its observer objects. +// +//========================================================= + +class ClockTimer { + // store system time + int _hour; + int _min; + int _sec; +public: + ClockTimer() { + // normally we would get the real local system time here + _hour = 12; + _min = 58; + _sec = 48; + }; + // get hour (used by observer) + int GetHour() const { return _hour; } + // get minute (used by observer) + int GetMinute() const { return _min; } + // get second (used by observer) + int GetSecond() const { return _sec; } + + void Tick(); // obtian system time (change state) +}; diff --git a/AspectC++/tests/PragmaOnceObserver/DigitalClock.cc b/AspectC++/tests/PragmaOnceObserver/DigitalClock.cc new file mode 100644 index 0000000..eee0143 --- /dev/null +++ b/AspectC++/tests/PragmaOnceObserver/DigitalClock.cc @@ -0,0 +1,20 @@ +//========================================================= +// DigitalClock.cpp +// +// Implement member functions in DigitalClock class which +// is in file DigitalClock.h +//========================================================= +#include "DigitalClock.h" +#include "ClockTimer.h" +#include + +void DigitalClock::Draw (const ClockTimer &clock) +{ + int hour = clock.GetHour(); + int minute = clock.GetMinute(); + int second = clock.GetSecond(); + + std::cout << "Digital Clock time is " << hour << ":" + << minute << ":" + << second << std::endl; +} diff --git a/AspectC++/tests/PragmaOnceObserver/DigitalClock.h b/AspectC++/tests/PragmaOnceObserver/DigitalClock.h new file mode 100644 index 0000000..0df1b0b --- /dev/null +++ b/AspectC++/tests/PragmaOnceObserver/DigitalClock.h @@ -0,0 +1,29 @@ +#ifndef DIGITALCLOCK_H +#define DIGITALCLOCK_H + +//========================================================= +// ConcreteObserver class +// +// DigitalClock +// +// It is a ConcreteObserver class and is a child class of +// the Observer class. +// +// It is a digital clock observer. It attaches to a timer +// object of the type Subject at run time. The timer +// object calls DigitalClock member function Update() +// whenever there is a DigitalClock update required. +// DigitalClock obtain current time from the timer object +// by timer object's member functions GetHour(), +// GetMinutes, and GetSecond(). DigitalClock prints out +// the updated time. +// +//========================================================= +class ClockTimer; + +class DigitalClock { +public: + void Draw(const ClockTimer &); // print updated time +}; + +#endif diff --git a/AspectC++/tests/PragmaOnceObserver/Makefile b/AspectC++/tests/PragmaOnceObserver/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/PragmaOnceObserver/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/PragmaOnceObserver/ObserverPattern.ah b/AspectC++/tests/PragmaOnceObserver/ObserverPattern.ah new file mode 100644 index 0000000..0995b5d --- /dev/null +++ b/AspectC++/tests/PragmaOnceObserver/ObserverPattern.ah @@ -0,0 +1,59 @@ +#ifndef __ObserverPattern_ah__ +#define __ObserverPattern_ah__ + +#include +#include +using namespace std; + +aspect ObserverPattern { + +public: + // interfaces for each role + class Subject {}; + class Observer { + public: + virtual void update (Subject *) = 0; + }; + +private: + + // data structures to manage subjects and observers + typedef set ObserverSet; + typedef map SubjectMap; + typedef SubjectMap::value_type SubjectMapPair; + + SubjectMap _perSubjectObservers; + + // to be defined by the concrete derived aspect + pointcut virtual subjectChange (Subject &subject) = 0; + virtual void updateObserver (Subject *subject, Observer *observer) = 0; + + public: + + void addObserver (Subject *subject, Observer *observer) { + SubjectMap::iterator subject_pos = _perSubjectObservers.find (subject); + if (subject_pos != _perSubjectObservers.end ()) { + ObserverSet &oset = (*subject_pos).second; + oset.insert (observer); + } + else { + ObserverSet oset; + oset.insert (observer); + _perSubjectObservers.insert (SubjectMapPair (subject, oset)); + } + } + + // here all registered observers are informed about a subject change + advice subjectChange (subject) : after (Subject &subject) { + SubjectMap::iterator subject_pos = _perSubjectObservers.find (&subject); + if (subject_pos != _perSubjectObservers.end ()) { + ObserverSet &oset = (*subject_pos).second; + for (ObserverSet::iterator iter = oset.begin (); iter != oset.end (); + ++iter) + updateObserver (&subject, *iter); + } + } + +}; + +#endif // __ObserverPattern_ah__ diff --git a/AspectC++/tests/PragmaOnceObserver/feature.ref b/AspectC++/tests/PragmaOnceObserver/feature.ref new file mode 100644 index 0000000..7279b99 --- /dev/null +++ b/AspectC++/tests/PragmaOnceObserver/feature.ref @@ -0,0 +1,4 @@ +Analog Clock time is 12:58:49 +Digital Clock time is 12:58:49 +Analog Clock time is 12:58:50 +Digital Clock time is 12:58:50 diff --git a/AspectC++/tests/PragmaOnceObserver/main.cc b/AspectC++/tests/PragmaOnceObserver/main.cc new file mode 100644 index 0000000..c93eed0 --- /dev/null +++ b/AspectC++/tests/PragmaOnceObserver/main.cc @@ -0,0 +1,40 @@ +//========================================================= +// main.cpp +// +// Program main function that demonstrates the Observer +// Design pattern. +// +// In this program: +// +// ConcreteSubject class: ClockTimer +// ConcreteObserver class: DigitalClock +// AnalogClock +// +// The ClockTimer object changes state by memeber function +// Tick(). This will trigger Update() function for both +// ConcreteObserver DigitalClock and AnalogClock. For demo, +// purpose, the observer objects will print out the current +// time in respond. +// +//========================================================= +#include "ClockTimer.h" +#include "DigitalClock.h" +#include "AnalogClock.h" + +int main(void) +{ + ClockTimer timer; + + DigitalClock digitalClock; + ClockObserver::aspectof ()->addObserver (&timer, &digitalClock); + + AnalogClock analogClock; + ClockObserver::aspectof ()->addObserver (&timer, &analogClock); + + timer.Tick(); // subject state change and update all it's + // observers which are digitalClock and + // analogClock in this program + timer.Tick(); // and again + + return 0; +} diff --git a/AspectC++/tests/PrivateResult/Aspect.ah b/AspectC++/tests/PrivateResult/Aspect.ah new file mode 100644 index 0000000..0c6d49a --- /dev/null +++ b/AspectC++/tests/PrivateResult/Aspect.ah @@ -0,0 +1,45 @@ +#ifndef __Aspect_h__ +#define __Aspect_h__ + +#include +using namespace std; + +#include "Safe.h" + +aspect Test { +public: + advice call ("Safe f(...)") : around () { + tjp->proceed (); + cout << "call result 1: " << *tjp->result () << endl; + } + advice call ("Safe f(...)") : around () { + tjp->proceed (); + cout << "* incrementing result id" << endl; + (*tjp->result ())._id++; + cout << "call result 2: " << *tjp->result () << endl; + } + advice call ("Safe f(...)") && result (safe) : after (Safe safe) { + cout << "call result 3: " << safe << endl; + } + advice execution ("Safe g(...)") : around () { + tjp->proceed (); + cout << "execution result 1: " << *tjp->result () << endl; + } + advice execution ("Safe g(...)") : around () { + tjp->proceed (); + cout << "* incrementing result id" << endl; + (*tjp->result ())._id++; + cout << "execution result 2: " << *tjp->result () << endl; + } + advice execution ("Safe g(...)") && result (safe) : after (Safe safe) { + cout << "execution result 3: " << safe << endl; + } + advice execution ("% Safe::uses_private_inner%(...)") : before () { + cout << "execution (\"" << JoinPoint::signature () << "\")" << endl; + } + advice execution ("AUnion h()") : after () { + cout << "execution (\"" << JoinPoint::signature () << "\")" << endl; + } +}; + +#endif // __Aspect_h__ diff --git a/AspectC++/tests/PrivateResult/Makefile b/AspectC++/tests/PrivateResult/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/PrivateResult/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/PrivateResult/Safe.h b/AspectC++/tests/PrivateResult/Safe.h new file mode 100644 index 0000000..e4507b6 --- /dev/null +++ b/AspectC++/tests/PrivateResult/Safe.h @@ -0,0 +1,46 @@ +#ifndef __Safe_h__ +#define __Safe_h__ + +#include + +class SafeBase {}; + +class Safe : public SafeBase { + friend Safe f (); + int _id; + Safe (int id) : _id (id) {} + Safe &operator = (const Safe &obj) { _id = obj._id; return *this; } + class Inner {}; // a private inner type! +public: + Safe (const Safe &obj) { *this = obj; } + Safe (const SafeBase &obj) { _id = -1; } // for confusion! + ~Safe () {} + // the following function is needed to make the overload resolution more + // complicated + void *operator new (size_t s) { return malloc (s); } + void print (ostream &os) const { os << _id; } + // the following code is needed to check how wrapper code can access private + // inner types + friend int main(); + inline Inner uses_private_inner1 (); + inline const Inner &uses_private_inner2 (); +}; + +inline Safe::Inner Safe::uses_private_inner1 () { return Inner (); } + +inline const Safe::Inner &Safe::uses_private_inner2 () { + static Inner i; + return i; +} + +ostream &operator << (ostream &os, const Safe& safe) { + safe.print (os); + return os; +} + +union AUnion { + int i; + int j; +}; + +#endif // __Safe_h__ diff --git a/AspectC++/tests/PrivateResult/feature.ref b/AspectC++/tests/PrivateResult/feature.ref new file mode 100644 index 0000000..97ef60f --- /dev/null +++ b/AspectC++/tests/PrivateResult/feature.ref @@ -0,0 +1,23 @@ +PrivateResult: advice for functions returning object with + non-public default constructor/assignment op. +============================================================ +call result 3: 4711 +* incrementing result id +call result 2: 4712 +call result 1: 4712 +call result 3: 4711 +* incrementing result id +call result 2: 4712 +call result 1: 4712 +execution result 3: 4712 +* incrementing result id +execution result 2: 4713 +execution result 1: 4713 +------------------------------------------------------------ +problem with private inner types: +execution ("Safe::Inner Safe::uses_private_inner1()") +execution ("const Safe::Inner &Safe::uses_private_inner2()") +------------------------------------------------------------ +return a union: +execution ("AUnion h()") +============================================================ diff --git a/AspectC++/tests/PrivateResult/main.cc b/AspectC++/tests/PrivateResult/main.cc new file mode 100644 index 0000000..79ebf4c --- /dev/null +++ b/AspectC++/tests/PrivateResult/main.cc @@ -0,0 +1,36 @@ +#include +#include +using namespace std; + +#include "Safe.h" + +Safe f () { + Safe safe (4711); + return safe; +}; + +Safe g () { + return f (); +} + +AUnion h () { + AUnion u; + return u; +} + +int main () { + printf ("PrivateResult: advice for functions returning object with\n"); + printf (" non-public default constructor/assignment op.\n"); + printf ("============================================================\n"); + Safe s(f ()); + g (); + Safe s2 (1); + printf ("------------------------------------------------------------\n"); + printf ("problem with private inner types:\n"); + Safe::Inner i = s2.uses_private_inner1 (); + const Safe::Inner &r = s2.uses_private_inner2 (); + printf ("------------------------------------------------------------\n"); + printf ("return a union:\n"); + AUnion u = h (); + printf ("============================================================\n"); +} diff --git a/AspectC++/tests/RepoInvalid/Makefile b/AspectC++/tests/RepoInvalid/Makefile new file mode 100644 index 0000000..b27152c --- /dev/null +++ b/AspectC++/tests/RepoInvalid/Makefile @@ -0,0 +1,3 @@ +ACFLAGS := -r repo.inv +WEAVE_ERROR := 1 +include ../Makefile.generic diff --git a/AspectC++/tests/RepoInvalid/feature.ref b/AspectC++/tests/RepoInvalid/feature.ref new file mode 100644 index 0000000..f9bca11 --- /dev/null +++ b/AspectC++/tests/RepoInvalid/feature.ref @@ -0,0 +1 @@ +error: project repository 'repo.inv' cannot be opened or is invalid diff --git a/AspectC++/tests/RepoInvalid/main.cc b/AspectC++/tests/RepoInvalid/main.cc new file mode 100644 index 0000000..9325380 --- /dev/null +++ b/AspectC++/tests/RepoInvalid/main.cc @@ -0,0 +1,3 @@ +// this code should not be compiled, because the project repository is invalid + +int main () {} diff --git a/AspectC++/tests/RepoInvalid/repo.inv b/AspectC++/tests/RepoInvalid/repo.inv new file mode 100644 index 0000000..d35e62f --- /dev/null +++ b/AspectC++/tests/RepoInvalid/repo.inv @@ -0,0 +1 @@ +blabla diff --git a/AspectC++/tests/RepoVersion/Makefile b/AspectC++/tests/RepoVersion/Makefile new file mode 100644 index 0000000..5f4484c --- /dev/null +++ b/AspectC++/tests/RepoVersion/Makefile @@ -0,0 +1,4 @@ +$(shell cp repo.inv repo.use) + +ACFLAGS := -r repo.use +include ../Makefile.generic diff --git a/AspectC++/tests/RepoVersion/feature.ref b/AspectC++/tests/RepoVersion/feature.ref new file mode 100644 index 0000000..dc22ea2 --- /dev/null +++ b/AspectC++/tests/RepoVersion/feature.ref @@ -0,0 +1 @@ +warning: project file version '0.0.1' differs from ac++ version diff --git a/AspectC++/tests/RepoVersion/main.cc b/AspectC++/tests/RepoVersion/main.cc new file mode 100644 index 0000000..9325380 --- /dev/null +++ b/AspectC++/tests/RepoVersion/main.cc @@ -0,0 +1,3 @@ +// this code should not be compiled, because the project repository is invalid + +int main () {} diff --git a/AspectC++/tests/RepoVersion/repo.inv b/AspectC++/tests/RepoVersion/repo.inv new file mode 100644 index 0000000..bba13c1 --- /dev/null +++ b/AspectC++/tests/RepoVersion/repo.inv @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AspectC++/tests/Result/Makefile b/AspectC++/tests/Result/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Result/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Result/PointerTracker.ah b/AspectC++/tests/Result/PointerTracker.ah new file mode 100644 index 0000000..1a6db54 --- /dev/null +++ b/AspectC++/tests/Result/PointerTracker.ah @@ -0,0 +1,30 @@ +#ifndef __PointerTracker_ah__ +#define __PointerTracker_ah__ + +#include + +aspect PointerTracker { + advice call ("% ...::%(...)") && result("% *") : before () { + printf (" call to '%s'\n", tjp->signature ()); + } + + advice execution ("% ...::%(...)") && result("% *") : after () { + printf (" executed '%s' -> 0x%lu\n", tjp->signature (), + (unsigned long)(size_t)*(void**)tjp->result ()); + } + + advice call ("% %(...)") && result(res) : after (long **res) { + printf (" result after call: 0x%lu\n", (unsigned long)(size_t)res); + } +}; + +aspect ResultManipulator { + advice call ("% select_v()") && result ("int &") : after () { + static int new_result = 815; + JoinPoint::Result * result = tjp->result (); + printf (" changing result! now: %d\n", **result); + *result = &new_result; + } +}; + +#endif // __PointerTracker_ah__ diff --git a/AspectC++/tests/Result/feature.ref b/AspectC++/tests/Result/feature.ref new file mode 100644 index 0000000..576c789 --- /dev/null +++ b/AspectC++/tests/Result/feature.ref @@ -0,0 +1,14 @@ +Result: checks if the result pointcut function works +==================================================== + call to 'void *h()' + executed 'void *h()' -> 0x1 + call to 'int *i()' + executed 'int *i()' -> 0x2 + call to 'long int **j()' + executed 'long int **j()' -> 0x3 + result after call: 0x3 + call to 'C::operator int *() const' + executed 'C::operator int *() const' -> 0x4 + changing result! now: 4711 + changed result reference refers to: 815 +==================================================== diff --git a/AspectC++/tests/Result/main.cc b/AspectC++/tests/Result/main.cc new file mode 100644 index 0000000..f477aef --- /dev/null +++ b/AspectC++/tests/Result/main.cc @@ -0,0 +1,32 @@ +#include + +void f () {} +int g () { return 0; } +void *h () { return (void*)1; } +int *i () { return (int*)2; } +long **j () { return (long**)3; } +class C { +public: + operator int * () const { return (int*)4; } +}; + +int v1 = 4711; + +// this is changed by advice to return something else instead of v1! +const int & select_v () { return v1; } + +int main () { + printf ("Result: checks if the result pointcut function works\n"); + printf ("====================================================\n"); + f (); + g (); + h (); + i (); + j (); + C c; + int *i; + i = c; // TODO: call to operator int* + printf (" changed result reference refers to: %d\n", select_v ()); + printf ("====================================================\n"); + return 0; +} diff --git a/AspectC++/tests/RightlessCalls/Makefile b/AspectC++/tests/RightlessCalls/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/RightlessCalls/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/RightlessCalls/feature.ref b/AspectC++/tests/RightlessCalls/feature.ref new file mode 100644 index 0000000..258ce21 --- /dev/null +++ b/AspectC++/tests/RightlessCalls/feature.ref @@ -0,0 +1,6 @@ +RightlessCalls: Calls using inaccesible types +============================================================= +calling Map::Iter MapIter::prev(): inaccessible result type +calling int Map::Iter::value(): inaccessible target object type +calling Map::Iter friendFunc(): inaccessible result, no object type +============================================================= diff --git a/AspectC++/tests/RightlessCalls/main.cc b/AspectC++/tests/RightlessCalls/main.cc new file mode 100644 index 0000000..57d04f1 --- /dev/null +++ b/AspectC++/tests/RightlessCalls/main.cc @@ -0,0 +1,55 @@ +#include + +class Map { + class Iter { + public: + int value () { // object type inaccessible for main() + printf ("inaccessible target object type\n"); + } + }; + friend class MapIter; +}; + +class MapIter { + typedef Map::Iter Item; + friend Item friendFunc(); +public: + Item prev () { // result type inaccessible for main() + printf ("inaccessible result type\n"); + return Item (); + } + static void check (const Map::Iter &) {} +}; + +MapIter::Item friendFunc () { + printf ("inaccessible result, no object type\n"); +} + +class Outer { + class C {}; + class D : public C {}; + friend int main(); + friend C& func(C); +}; + +Outer::C& func(Outer::C) {} +void func(int) {} + +int main() { + printf ("RightlessCalls: Calls using inaccesible types\n"); + printf ("=============================================================\n"); + MapIter i; + i.prev ().value (); + // MapIter::check (i.prev ()); + friendFunc (); + // TODO: inaccesible argument types are not supported yet! + // printf ("-------------------------------------------------------------\n"); + // func (Outer::D()); // here type deduction is tricky + printf ("=============================================================\n"); +} + +aspect Trace { + advice call("% Map%::...::%(...)" || "% friendFunc()") : before () { + printf ("calling %s: ", JoinPoint::signature ()); + } +}; diff --git a/AspectC++/tests/STLSet/Makefile b/AspectC++/tests/STLSet/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/STLSet/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/STLSet/main.cc b/AspectC++/tests/STLSet/main.cc new file mode 100644 index 0000000..9f9d7ec --- /dev/null +++ b/AspectC++/tests/STLSet/main.cc @@ -0,0 +1,19 @@ +#include +using std::printf; +#include +using std::set; + +aspect SetTracer { + advice call ("% ...::%(...)" && !"% printf(...)") : before () { + printf ("calling %s\n", JoinPoint::signature ()); + } +}; + +set sint; + +int main () { + printf ("STLSet: checks advice weaving for the STL set template\n"); + printf ("======================================================\n"); + sint.insert (4711); + printf ("======================================================\n"); +}; diff --git a/AspectC++/tests/STLString/Makefile b/AspectC++/tests/STLString/Makefile new file mode 100644 index 0000000..791d96c --- /dev/null +++ b/AspectC++/tests/STLString/Makefile @@ -0,0 +1,3 @@ +#AC_PATTERN_REPLACEMENTS := | sed -e "s/std::.*basic_string/<<>>/" | sed -e "s/void /VOID /" +AC_PATTERN_REPLACEMENTS := | sed -e "s/std::.*basic_string/<<>>/" +include ../Makefile.generic diff --git a/AspectC++/tests/STLString/feature.ref b/AspectC++/tests/STLString/feature.ref new file mode 100644 index 0000000..488d314 --- /dev/null +++ b/AspectC++/tests/STLString/feature.ref @@ -0,0 +1,5 @@ +StdString: checks advice weaving for the STL string class +========================================================= +calling void foo(<<>>) +in foo(this is a string) +========================================================= diff --git a/AspectC++/tests/STLString/main.cc b/AspectC++/tests/STLString/main.cc new file mode 100644 index 0000000..b991617 --- /dev/null +++ b/AspectC++/tests/STLString/main.cc @@ -0,0 +1,22 @@ +#include +using std::printf; +#include + +aspect StringTracer { + public: + advice call ("% foo(... :: basic_string)" && !"% printf(...)") : before () { + printf ("calling %s\n", JoinPoint::signature ()); + } +}; + +//void foo(std::string s) { +void foo(std::basic_string s) { + printf("in foo(%s)\n", s.c_str ()); +} + +int main () { + printf ("StdString: checks advice weaving for the STL string class\n"); + printf ("=========================================================\n"); + foo ("this is a string"); + printf ("=========================================================\n"); +} diff --git a/AspectC++/tests/SimpleAliasAccessMember/Makefile b/AspectC++/tests/SimpleAliasAccessMember/Makefile new file mode 100644 index 0000000..daa5e9e --- /dev/null +++ b/AspectC++/tests/SimpleAliasAccessMember/Makefile @@ -0,0 +1,2 @@ +ACFLAGS ?= --builtin_operators --data_joinpoints +include ../Makefile.generic diff --git a/AspectC++/tests/SimpleAliasAccessMember/feature.ref b/AspectC++/tests/SimpleAliasAccessMember/feature.ref new file mode 100644 index 0000000..43f907e --- /dev/null +++ b/AspectC++/tests/SimpleAliasAccessMember/feature.ref @@ -0,0 +1,28 @@ +Taking reference of a member + REF "int MyTest::x" : + +Accessing member of MyTest + GET via ALIAS "int " : 3 + +Accessing member of MyTest + GET via ALIAS "int " : 3 + +Accessing member of MyTest + SET via ALIAS "int " : 3 -> 6 + +Taking reference of a member + REF "int MyTest::x" : + +Accessing member of MyTest + GET via ALIAS "int " : 6 + +Accessing member of MyTest + SET via ALIAS "int " : 6 -> 5 + +Taking reference of a member + REF "unsigned long int MyAnother::z" : + +Accessing member of MyAnother + SET via ALIAS "unsigned long int " : 42 -> 4711 + +UNKNOWN SET diff --git a/AspectC++/tests/SimpleAliasAccessMember/main.cc b/AspectC++/tests/SimpleAliasAccessMember/main.cc new file mode 100644 index 0000000..6539b6e --- /dev/null +++ b/AspectC++/tests/SimpleAliasAccessMember/main.cc @@ -0,0 +1,91 @@ +#include +#include +using namespace std; + +class TestInterface { +public: + virtual void print() = 0; +}; + +class MyTest : public TestInterface { +public: + int x; + + MyTest() : x(0) {} + + virtual void print() { + cout << "Accessing member of MyTest" << endl; + } +}; + +class MyAnother : public TestInterface { +public: + unsigned long int z; + + MyAnother() : z(0) {} + + virtual void print() { + cout << "Accessing member of MyAnother" << endl; + } +}; + +int main() { + // MyTest + MyTest obj; + obj.x = 3; + int* ptr = &obj.x; + int y; + y = *ptr; // get #1 + *ptr += 3; // get #2 and set #1 + + int& myref = obj.x; + myref = myref - 1; + + // MyAnother + MyAnother other; + other.z = 42; + unsigned long int* oth_ptr = &other.z; + *oth_ptr = 4711; + + // unkown: + ptr = &y; + *ptr = 0; +} + + +aspect DynGetSet { + pointcut observe() = "% My%::%"; + + map var_table; + + advice ref(observe()) : before() { + cout << "Taking reference of a member" << endl; + cout << " REF \"" << JoinPoint::signature() << "\" : " << /*tjp->entity()*/ "" << endl << endl; + if (tjp->target() != 0) { + var_table[tjp->entity()] = tjp->target(); + } + } + + advice get(alias(observe())) : before() { + TestInterface* target = var_table[tjp->entity()]; + if (target != 0) { + target->print(); + cout << " GET via ALIAS \"" << JoinPoint::signature() << "\" : " << *tjp->entity() << endl << endl; + } + else { + cout << "UNKNOWN GET" << endl; + } + } + + advice set(alias(observe())) : before() { + TestInterface* target = var_table[tjp->entity()]; + if (target != 0) { + target->print(); + cout << " SET via ALIAS \"" << JoinPoint::signature() << "\" : " << *tjp->entity() << " -> " << *tjp->arg<0>() << endl << endl; + } + else { + cout << "UNKNOWN SET" << endl; + } + } +}; + diff --git a/AspectC++/tests/SimpleGetAdvice/Makefile b/AspectC++/tests/SimpleGetAdvice/Makefile new file mode 100644 index 0000000..daa5e9e --- /dev/null +++ b/AspectC++/tests/SimpleGetAdvice/Makefile @@ -0,0 +1,2 @@ +ACFLAGS ?= --builtin_operators --data_joinpoints +include ../Makefile.generic diff --git a/AspectC++/tests/SimpleGetAdvice/feature.ref b/AspectC++/tests/SimpleGetAdvice/feature.ref new file mode 100644 index 0000000..0918422 --- /dev/null +++ b/AspectC++/tests/SimpleGetAdvice/feature.ref @@ -0,0 +1,99 @@ +Before: int a +ent: 42 +Around: int a +ent: 42 +Around (inner): int a +ent (inner): 64 +res (inner): 64 +tmp: 64 +After: int a +res: 96 + +GET: + +A: +Before: int a +ent: 64 +Around: int a +ent: 64 +Around (inner): int a +ent (inner): 64 +res (inner): 64 +tmp: 64 +After: int a +res: 96 + +X1: +Before: int T1::x +ent: 23 +Around: int T1::x +ent: 23 +Around (inner): int T1::x +ent (inner): 64 +res (inner): 64 +tmp: 64 +After: int T1::x +res: 96 + +X2: +Before: int T1::x +ent: 64 +Around: int T1::x +ent: 64 +Around (inner): int T1::x +ent (inner): 64 +res (inner): 64 +tmp: 64 +After: int T1::x +res: 96 + +X3: +Before: int T1::x +ent: 64 +Around: int T1::x +ent: 64 +Around (inner): int T1::x +ent (inner): 64 +res (inner): 64 +tmp: 64 +After: int T1::x +res: 96 + +M1: +Before: int T1::m +ent: 5 +Around: int T1::m +ent: 5 +Around (inner): int T1::m +ent (inner): 64 +ent ( via memberptr() ): 64 +res (inner): 64 +tmp: 64 +After: int T1::m +res: 96 + +M2: +Before: int T1::m +ent: 64 +Around: int T1::m +ent: 64 +Around (inner): int T1::m +ent (inner): 64 +ent ( via memberptr() ): 64 +res (inner): 64 +tmp: 64 +After: int T1::m +res: 96 + +P1: +Before: int T1::p +ent: 13 +Around: int T1::p +ent: 13 +Around (inner): int T1::p +ent (inner): 64 +ent ( via memberptr() ): 64 +res (inner): 64 +tmp: 64 +After: int T1::p +res: 96 diff --git a/AspectC++/tests/SimpleGetAdvice/main.cc b/AspectC++/tests/SimpleGetAdvice/main.cc new file mode 100644 index 0000000..246332e --- /dev/null +++ b/AspectC++/tests/SimpleGetAdvice/main.cc @@ -0,0 +1,106 @@ +#include + +using namespace std; + +class T1 { +private: + int p; +public: + int m; + static int x; + + T1() : m( 5 ), p( 13 ) {} + + static void testgetS() { + int r = x; + } + + void testgetM() { + int r = m; + } + + void testgetP(); +}; + +int T1::x = 23; + +void T1::testgetP() { + int r = p; +}; + +int a = 42; + +int i = a; + +int main() { + int b; + T1 o; + + cout << endl << "GET:" << endl; + + cout << endl << "A:" << endl; + b = a; + + cout << endl << "X1:" << endl; + b = T1::x; + + cout << endl << "X2:" << endl; + T1::testgetS(); + + cout << endl << "X3:" << endl; + b = o.x; + + cout << endl << "M1:" << endl; + b = o.m; + + cout << endl << "M2:" << endl; + o.testgetM(); + + cout << endl << "P1:" << endl; + o.testgetP(); + + return 0; +} + +aspect GetTest1 { + advice get("int ...::%") : before() { + cout << "Before: " << tjp->signature() << endl; + cout << "ent: " << *tjp->entity() << endl; + } + + advice get("int ...::%") : after() { + cout << "After: " << tjp->signature() << endl; + cout << "res: " << *tjp->result() << endl; + } +}; + +aspect GetTest2 { + advice get("int ...::%") : around() { + cout << "Around: " << tjp->signature() << endl; + cout << "ent: " << *tjp->entity() << endl; + *tjp->entity() = 64; + + tjp->proceed(); + + JoinPoint::Result &tmp = *tjp->result(); + cout << "tmp: " << tmp << endl; + tmp += 32; + } +}; + +aspect GetTest3 { + advice get("int ...::%") : around() { + cout << "Around (inner): " << tjp->signature() << endl; + cout << "ent (inner): " << *tjp->entity() << endl; + + tjp->proceed(); + + cout << "res (inner): " << *tjp->result() << endl; + } +}; + +aspect MemberTest { + advice get("int T1::%" && ! "static % T1::%") : before() { + cout << "ent ( via memberptr() ): " << tjp->target()->*(tjp->memberptr()) << endl; + } +}; diff --git a/AspectC++/tests/SimpleGetSetFuncPtr/Makefile b/AspectC++/tests/SimpleGetSetFuncPtr/Makefile new file mode 100644 index 0000000..daa5e9e --- /dev/null +++ b/AspectC++/tests/SimpleGetSetFuncPtr/Makefile @@ -0,0 +1,2 @@ +ACFLAGS ?= --builtin_operators --data_joinpoints +include ../Makefile.generic diff --git a/AspectC++/tests/SimpleGetSetFuncPtr/feature.ref b/AspectC++/tests/SimpleGetSetFuncPtr/feature.ref new file mode 100644 index 0000000..1d3072b --- /dev/null +++ b/AspectC++/tests/SimpleGetSetFuncPtr/feature.ref @@ -0,0 +1,7 @@ +SET: void (*Container::foo)(int) at line 13 +SET of foo at line 13 +SET of any function pointer: void (*Container::foo)(int) at line 13 +GET: void (*Container::foo)(int) at line 17 +GET of foo at line 17 +GET of any function pointer: void (*Container::foo)(int) at line 17 +called with x=42 diff --git a/AspectC++/tests/SimpleGetSetFuncPtr/main.cc b/AspectC++/tests/SimpleGetSetFuncPtr/main.cc new file mode 100644 index 0000000..ac938a0 --- /dev/null +++ b/AspectC++/tests/SimpleGetSetFuncPtr/main.cc @@ -0,0 +1,54 @@ +#include +using namespace std; + +void my_int_func(int x) { + cout << "called with x=" << x << endl; +} + +class Container { + void (*foo)(int); + +public: + Container() { + foo = &my_int_func; + } + + void bar(int x) { + foo(x); + } +}; + +int main() { + Container c; + c.bar(42); +} + +aspect GetSetFuncPtr { + // matching any member access + advice get("% Container::%") : before() { + cout << "GET: " << JoinPoint::signature() << " at line " << tjp->line() << endl; + } + + advice set("% Container::%") : before() { + cout << "SET: " << JoinPoint::signature() << " at line " << tjp->line() << endl; + } + + // matching only the function pointer 'foo' + advice get("void (*Container::foo)(int)") : before() { + cout << "GET of foo at line " << tjp->line() << endl; + } + + advice set("void (*Container::foo)(int)") : before() { + cout << "SET of foo at line " << tjp->line() << endl; + } + + // matching any function pointer + advice get("% (*...::%)(...)") : before() { + cout << "GET of any function pointer: " << JoinPoint::signature() << " at line " << tjp->line() << endl; + } + + advice set("% (*...::%)(...)") : before() { + cout << "SET of any function pointer: " << JoinPoint::signature() << " at line " << tjp->line() << endl; + } +}; + diff --git a/AspectC++/tests/SimpleRefAdvice/Makefile b/AspectC++/tests/SimpleRefAdvice/Makefile new file mode 100644 index 0000000..daa5e9e --- /dev/null +++ b/AspectC++/tests/SimpleRefAdvice/Makefile @@ -0,0 +1,2 @@ +ACFLAGS ?= --builtin_operators --data_joinpoints +include ../Makefile.generic diff --git a/AspectC++/tests/SimpleRefAdvice/feature.ref b/AspectC++/tests/SimpleRefAdvice/feature.ref new file mode 100644 index 0000000..85e272e --- /dev/null +++ b/AspectC++/tests/SimpleRefAdvice/feature.ref @@ -0,0 +1,175 @@ +Before: int a +ent: 42 +Around: int a +ent: 42 +Around (inner): int a +ent (inner): 42 +res (inner): 42 +tmp: 42 +After: int a +res: 42 +Before: int T1::x +ent: 23 +Around: int T1::x +ent: 23 +Around (inner): int T1::x +ent (inner): 23 +res (inner): 23 +tmp: 23 +After: int T1::x +res: 23 + +REF (explitcit): + +A: +Before: int a +ent: 42 +Around: int a +ent: 42 +Around (inner): int a +ent (inner): 42 +res (inner): 42 +tmp: 42 +After: int a +res: 42 + +X1: +Before: int T1::x +ent: 23 +Around: int T1::x +ent: 23 +Around (inner): int T1::x +ent (inner): 23 +res (inner): 23 +tmp: 23 +After: int T1::x +res: 23 + +X2: +Before: int T1::x +ent: 23 +Around: int T1::x +ent: 23 +Around (inner): int T1::x +ent (inner): 23 +res (inner): 23 +tmp: 23 +After: int T1::x +res: 23 + +X3: +Before: int T1::x +ent: 23 +Around: int T1::x +ent: 23 +Around (inner): int T1::x +ent (inner): 23 +res (inner): 23 +tmp: 23 +After: int T1::x +res: 23 + +M1: +ent ( via memberptr() ): 5 +Before: int T1::m +ent: 5 +Around: int T1::m +ent: 5 +Around (inner): int T1::m +ent (inner): 5 +res (inner): 5 +tmp: 5 +After: int T1::m +res: 5 + +M2: +ent ( via memberptr() ): 5 +Before: int T1::m +ent: 5 +Around: int T1::m +ent: 5 +Around (inner): int T1::m +ent (inner): 5 +res (inner): 5 +tmp: 5 +After: int T1::m +res: 5 + +P1: +ent ( via memberptr() ): 13 +Before: int T1::p +ent: 13 +Around: int T1::p +ent: 13 +Around (inner): int T1::p +ent (inner): 13 +res (inner): 13 +tmp: 13 +After: int T1::p +res: 13 + +REF (implicit): + +local ref: +Before: int a +ent: 42 +Around: int a +ent: 42 +Around (inner): int a +ent (inner): 42 +res (inner): 42 +tmp: 42 +After: int a +res: 42 + +param ref: +Before: int a +ent: 42 +Around: int a +ent: 42 +Around (inner): int a +ent (inner): 42 +res (inner): 42 +tmp: 42 +After: int a +res: 42 +1: 42 + +default param ref (no default): +Before: int a +ent: 42 +Around: int a +ent: 42 +Around (inner): int a +ent (inner): 42 +res (inner): 42 +tmp: 42 +After: int a +res: 42 +2: 42 + +default param ref (default): +Before: int T1::x +ent: 23 +Around: int T1::x +ent: 23 +Around (inner): int T1::x +ent (inner): 23 +res (inner): 23 +tmp: 23 +After: int T1::x +res: 23 +2: 23 + +return ref: +Before: int T1::x +ent: 23 +Around: int T1::x +ent: 23 +Around (inner): int T1::x +ent (inner): 23 +res (inner): 23 +tmp: 23 +After: int T1::x +res: 23 +23 diff --git a/AspectC++/tests/SimpleRefAdvice/main.cc b/AspectC++/tests/SimpleRefAdvice/main.cc new file mode 100644 index 0000000..55b451f --- /dev/null +++ b/AspectC++/tests/SimpleRefAdvice/main.cc @@ -0,0 +1,134 @@ +#include + +using namespace std; + +class T1 { +private: + int p; +public: + int m; + static int x; + + T1() : m( 5 ), p( 13 ) {} + + static void testrefS() { + int *r = &x; + } + + void testrefM() { + int *r = &m; + } + + void testrefP(); +}; + +void paramtest1( int &r ) { + cout << "1: " << r << endl; +} + +void paramtest2( int &r = T1::x ) { + cout << "2: " << r << endl; +} + +int &returntest() { + return T1::x; +} + +int T1::x = 23; + +void T1::testrefP() { + int *r = &p; +}; + +int a = 42; + +int *i = &a; +int &j = T1::x; + +int main() { + int *b; + T1 o; + + cout << endl << "REF (explitcit):" << endl; + + cout << endl << "A:" << endl; + b = &a; + + cout << endl << "X1:" << endl; + b = &T1::x; + + cout << endl << "X2:" << endl; + T1::testrefS(); + + cout << endl << "X3:" << endl; + b = &o.x; + + cout << endl << "M1:" << endl; + b = &o.m; + + cout << endl << "M2:" << endl; + o.testrefM(); + + cout << endl << "P1:" << endl; + o.testrefP(); + + cout << endl << "REF (implicit):" << endl; + + cout << endl << "local ref:" << endl; + int &c = a; + + cout << endl << "param ref:" << endl; + paramtest1( a ); + + cout << endl << "default param ref (no default):" << endl; + paramtest2( a ); + + cout << endl << "default param ref (default):" << endl; + paramtest2(); + + cout << endl << "return ref:" << endl; + cout << returntest() << endl; + + return 0; +} + +aspect RefTest1 { + advice ref("int ...::%") : before() { + cout << "Before: " << tjp->signature() << endl; + cout << "ent: " << *tjp->entity() << endl; + } + + advice ref("int ...::%") : after() { + cout << "After: " << tjp->signature() << endl; + cout << "res: " << **tjp->result() << endl; + } +}; + +aspect RefTest2 { + advice ref("int ...::%") : around() { + cout << "Around: " << tjp->signature() << endl; + cout << "ent: " << *tjp->entity() << endl; + + tjp->proceed(); + + int &tmp = **tjp->result(); + cout << "tmp: " << tmp << endl; + } +}; + +aspect RefTest3 { + advice ref("int ...::%") : around() { + cout << "Around (inner): " << tjp->signature() << endl; + cout << "ent (inner): " << *tjp->entity() << endl; + + tjp->proceed(); + + cout << "res (inner): " << **tjp->result() << endl; + } +}; + +aspect MemberTest { + advice ref("int T1::%" && ! "static % T1::%") : before() { + cout << "ent ( via memberptr() ): " << tjp->target()->*(tjp->memberptr()) << endl; + } +}; diff --git a/AspectC++/tests/SimpleSetAdvice/Makefile b/AspectC++/tests/SimpleSetAdvice/Makefile new file mode 100644 index 0000000..daa5e9e --- /dev/null +++ b/AspectC++/tests/SimpleSetAdvice/Makefile @@ -0,0 +1,2 @@ +ACFLAGS ?= --builtin_operators --data_joinpoints +include ../Makefile.generic diff --git a/AspectC++/tests/SimpleSetAdvice/feature.ref b/AspectC++/tests/SimpleSetAdvice/feature.ref new file mode 100644 index 0000000..45936fd --- /dev/null +++ b/AspectC++/tests/SimpleSetAdvice/feature.ref @@ -0,0 +1,129 @@ +SET: + +A: +Before: int a +ent: 42 +new: 5 +obj: +src: +Around: int a +ent: 42 +new: 5 +ent (inner): 42 +new (inner): 10 +set (inner): 10 +set: 10 +After: int a +set: 42 + +X1: +Before: int T1::x +ent: 23 +new: 7 +obj: +src: +Around: int T1::x +ent: 23 +new: 7 +ent (inner): 23 +new (inner): 14 +set (inner): 14 +set: 14 +After: int T1::x +set: 46 + +X2: +Before: int T1::x +ent: 46 +new: 99 +obj: +src: +Around: int T1::x +ent: 46 +new: 99 +ent (inner): 46 +new (inner): 198 +set (inner): 198 +set: 198 +After: int T1::x +set: 230 + +X3: +Before: int T1::x +ent: 230 +new: 21 +obj: +src: +Around: int T1::x +ent: 230 +new: 21 +ent (inner): 230 +new (inner): 42 +set (inner): 42 +set: 42 +After: int T1::x +set: 74 + +M1: +Before: int T1::m +ent: 5 +new: -3 +obj: +src: +Around: int T1::m +ent: 5 +new: -3 +ent (inner): 5 +new (inner): -6 +set (inner): -6 +set: -6 +After: int T1::m +set: 26 + +M2: +Before: int T1::m +ent: 26 +new: 49 +obj: +src: +Around: int T1::m +ent: 26 +new: 49 +ent (inner): 26 +new (inner): 98 +set (inner): 98 +set: 98 +After: int T1::m +set: 130 + +M3: +Before: int T1::m +ent: 130 +new: 33 +obj: +src: +Around: int T1::m +ent: 130 +new: 33 +ent (inner): 130 +new (inner): 66 +set (inner): 66 +set: 66 +After: int T1::m +set: 98 + +P1: +Before: int T1::p +ent: 13 +new: 15 +obj: +src: +Around: int T1::p +ent: 13 +new: 15 +ent (inner): 13 +new (inner): 30 +set (inner): 30 +set: 30 +After: int T1::p +set: 62 diff --git a/AspectC++/tests/SimpleSetAdvice/main.cc b/AspectC++/tests/SimpleSetAdvice/main.cc new file mode 100644 index 0000000..2dea52c --- /dev/null +++ b/AspectC++/tests/SimpleSetAdvice/main.cc @@ -0,0 +1,125 @@ +#include + +using namespace std; + +class T1 { +private: + int p; +public: + int m; + static int x; + + T1() : m( 5 ), p( 13 ) {} + + static void testsetS() { + x = 99; + } + + void testsetM() { + m = 49; + } + + void testsetP(); + + void set_via_this(int m) { + this->m = m; + } + + int b:4; + void set_bitfield() { + b = 0; + } +}; + +void T1::testsetP() { + p = 15; +}; + +int T1::x = 23; + +int a = 42; + +T1 *o_ref; // for comparing in advice + +int main() { + T1 o; + o_ref = &o; // init for comparison + + cout << "SET:" << endl; + + cout << endl << "A:" << endl; + a = 5; + + cout << endl << "X1:" << endl; + T1::x = 7; + + cout << endl << "X2:" << endl; + T1::testsetS(); + + cout << endl << "X3:" << endl; + o.x = 21; + + cout << endl << "M1:" << endl; + o.m = -3; + + cout << endl << "M2:" << endl; + o.testsetM(); + + cout << endl << "M3:" << endl; + o.set_via_this(33); + + cout << endl << "P1:" << endl; + o.testsetP(); + + return 0; +} + +void print_obj( void *ptr ) { + if( ptr == 0 ) + cout << ""; + else if( ptr == o_ref ) + cout << ""; + else + cout << ""; +} + +aspect SetTest1 { + advice set("int ...::%") : before() { + cout << "Before: " << tjp->signature() << endl; + cout << "ent: " << *tjp->entity() << endl; + cout << "new: " << *tjp->arg<0>() << endl; + cout << "obj: "; print_obj( tjp->target() ); cout << endl; + cout << "src: "; print_obj( tjp->that() ); cout << endl; + } + + advice set("int ...::%") : after() { + cout << "After: " << tjp->signature() << endl; + cout << "set: " << *tjp->entity() << endl; + } +}; + +aspect SetTest2 { + advice set("int ...::%") : around() { + cout << "Around: " << tjp->signature() << endl; + cout << "ent: " << *tjp->entity() << endl; + cout << "new: " << *tjp->arg<0>() << endl; + *tjp->arg<0>() *= 2; + + tjp->proceed(); + + JoinPoint::Entity &tmp = *tjp->entity(); + cout << "set: " << tmp << endl; + tmp += 32; + } +}; + +aspect SetTest3 { + advice set("int ...::%") : around() { + cout << "ent (inner): " << *tjp->entity() << endl; + cout << "new (inner): " << *tjp->arg<0>() << endl; + + tjp->proceed(); + + cout << "set (inner): " << *tjp->entity() << endl; + } +}; diff --git a/AspectC++/tests/Slice/Makefile b/AspectC++/tests/Slice/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/Slice/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/Slice/feature.ref b/AspectC++/tests/Slice/feature.ref new file mode 100644 index 0000000..3b44495 --- /dev/null +++ b/AspectC++/tests/Slice/feature.ref @@ -0,0 +1,17 @@ +Slice: of few simple slice implementations +========================================== +before Puma::XXX::XXX(bool) +before bool Puma::XXX::in_advice() const +in: 1 +before void Puma::XXX::enter_advice() +before void Puma::XXX::Nested3::nf() +call advice for introduced code works. +before void Puma::XXX::Nested3::here_I_am() +before bool Puma::XXX::in_advice() const +in: 1 +before void Puma::XXX::leave_advice() +before bool Puma::XXX::in_advice() const +in: 0 +before void Puma::XXX::g() +========================================== +before Puma::XXX::~XXX() diff --git a/AspectC++/tests/Slice/main.cc b/AspectC++/tests/Slice/main.cc new file mode 100644 index 0000000..61a1912 --- /dev/null +++ b/AspectC++/tests/Slice/main.cc @@ -0,0 +1,156 @@ +#include + +class SomeBase1 {}; +class SomeBase2 {}; +class SomeBase3 {}; + +namespace Puma { + + class XXX { + }; + + slice class ACSemanticForC : public SomeBase2 { + bool _in_advice; + class Nested; + struct Nested3 { + static void nf() {} + }; +public: + static int anon; + ACSemanticForC () : _in_advice (false) {} + explicit ACSemanticForC (bool a); + virtual ~ACSemanticForC (); + void enter_advice () { + _in_advice = true; + Nested3::nf (); + Nested3::here_I_am(); + } + void enter_advice2 () { + _in_advice = true; + } + bool in_advice () const { return _in_advice; } + void leave_advice (); +}; + + slice class ACBuilder; +} + +slice class IntoNested3 { + struct Nested4 {}; +public: + static void here_I_am() {} +}; + +slice class IntoNested4 { + struct Nested3 {}; + static void here_I_am() {} +}; + +slice class Puma::ACBuilder; +slice class Puma::ACBuilder {}; + +slice struct InGlobal { + int _in_global; + void global (); +}; + +class WithBase : public SomeBase1 {}; + +namespace Puma { + slice class Bla; +} + +int main () { + printf ("Slice: of few simple slice implementations\n"); + printf ("==========================================\n"); + Puma::XXX x(true); + printf ("in: %d\n", x.in_advice ()); + x.enter_advice (); + printf ("in: %d\n", x.in_advice ()); + x.leave_advice (); + printf ("in: %d\n", x.in_advice ()); + x.g (); // from DefinedLater + printf ("==========================================\n"); +}; + +slice class DefinedLater; + +aspect Foo { + // advice "Puma::XXX" : baseclass (SomeBase1); + advice "Puma::XXX" : slice class U : public SomeBase3; + advice "WithBase" : slice struct : SomeBase2; + + advice "Puma::XXX" : slice Puma::Bla; + advice "...::Nested3" : slice IntoNested3; + // advice "...::Nested4" : slice IntoNested4; // doesn't work! Infinite intro recursion. + + slice class Local { + typedef Local THIS; + }; +/* advice "XXX" : slice class Bla; // wrong */ +/* advice "XXX" : slice struct ::Foo; // wrong */ + advice "Puma::XXX" : slice Puma::ACSemanticForC; + advice "Puma::XXX" : slice InGlobal; + +/* advice "XXX" : { */ +/* void *blob; */ +/* }; */ + advice "Puma::XXX" : slice DefinedLater; + slice struct Later2; + advice "Puma::XXX" : slice Later2; + advice "Puma::XXX" : slice class {}; // useless :-) + advice "Puma::XXX" : slice class S { + double murks; + long long murks2; + public: +// S () {} + explicit S(int) {} + explicit S(double i) : murks(i) {} + S(unsigned long long ll) : murks2(ll) {} + int bar2; + class Nested2; + }; +}; + +slice class Puma::Bla { + void func (); +}; + +slice void Puma::Bla::func () { +} + +slice struct Foo::Later2 { int _later2; }; + +slice class DefinedLater { int _def_later; public: void g (); }; + +slice void DefinedLater::g () {} + +aspect Trace { + advice execution (member ("Puma::XXX")) || + construction ("Puma::XXX") || destruction ("Puma::XXX") : before () { + printf ("before %s\n", JoinPoint::signature ()); + } + advice call ("% ...::here_I_am()") : before () { + printf ("call advice for introduced code works.\n"); + } +}; + +slice class Puma::ACSemanticForC::Nested { + int i; +}; + +slice +void Puma::ACSemanticForC::leave_advice () { _in_advice = false; } + + +slice +int Puma::ACSemanticForC::anon = 0; + +slice +class ::Foo::S::Nested2 {}; + +slice Puma::ACSemanticForC::~ACSemanticForC () {} + +slice Puma::ACSemanticForC::ACSemanticForC (bool a) : _in_advice (a) {} + +slice void InGlobal::global () {} diff --git a/AspectC++/tests/SliceJPAPI/Makefile b/AspectC++/tests/SliceJPAPI/Makefile new file mode 100644 index 0000000..f485359 --- /dev/null +++ b/AspectC++/tests/SliceJPAPI/Makefile @@ -0,0 +1,2 @@ +ACFLAGS ?= --introspection +include ../Makefile.generic diff --git a/AspectC++/tests/SliceJPAPI/feature.ref b/AspectC++/tests/SliceJPAPI/feature.ref new file mode 100644 index 0000000..7e1d204 --- /dev/null +++ b/AspectC++/tests/SliceJPAPI/feature.ref @@ -0,0 +1,19 @@ +SliceJPAPI: The static joinpoint API +==================================== +Introspecting class/struct 'Target' +------------------------------------ +MEMBERS 1: 1 +------------------------------------ +BASECLASSES 2: 0 +MEMBERS 2: 3 +member 1: i +member 2: j +member 3: MEMBERS1 +------------------------------------ +increased no of members by 2 +member 1: i +member 2: j +member 3: MEMBERS1 +member 4: MEMBERS2 +member 5: BASECLASSES +==================================== diff --git a/AspectC++/tests/SliceJPAPI/main.cc b/AspectC++/tests/SliceJPAPI/main.cc new file mode 100644 index 0000000..f9f8de9 --- /dev/null +++ b/AspectC++/tests/SliceJPAPI/main.cc @@ -0,0 +1,61 @@ +#include + +template +struct Introspector { + static void print_names() { + Introspector::print_names(); + printf ("member %d: %s\n", N, JP::template Member::name()); + } +}; + +template +struct Introspector { + static void print_names() {} +}; + +struct Target { + int i; +}; + +slice class Slice1 { + int j; +public: + static const int MEMBERS1 = JoinPoint::MEMBERS; + static int get_elements(); +}; + +slice int Slice1::get_elements() { return JoinPoint::MEMBERS; } + +slice class Slice2 { +public: + static const int MEMBERS2 = JoinPoint::MEMBERS; + static const int BASECLASSES = JoinPoint::BASECLASSES; + static void print_names (); + static int get_delta() { + return AC::TypeInfo::MEMBERS -JoinPoint::MEMBERS; + } +}; + +slice void Slice2::print_names() { Introspector::print_names (); } + +int main () { + printf ("SliceJPAPI: The static joinpoint API\n"); + printf ("====================================\n"); + printf ("Introspecting class/struct '%s'\n", + AC::TypeInfo::signature ()); + printf ("------------------------------------\n"); + printf ("MEMBERS 1: %d\n", Target::MEMBERS1); + printf ("------------------------------------\n"); + printf ("BASECLASSES 2: %d\n", Target::BASECLASSES); + printf ("MEMBERS 2: %d\n", Target::MEMBERS2); + Target::print_names (); + printf ("------------------------------------\n"); + printf ("increased no of members by %d\n", Target::get_delta ()); + Introspector >::print_names (); + printf ("====================================\n"); +}; + +aspect Foo { + advice "Target" : slice Slice1; + advice "Target" : slice Slice2; +}; diff --git a/AspectC++/tests/StandAloneCalls/Aspect.ah b/AspectC++/tests/StandAloneCalls/Aspect.ah new file mode 100644 index 0000000..f228b9a --- /dev/null +++ b/AspectC++/tests/StandAloneCalls/Aspect.ah @@ -0,0 +1,13 @@ +#ifndef __Aspect__ +#define __Aspect__ + +#include + + +aspect Aspect { + advice call("% %::foo()"||"% bar()") : before() { + printf("%s\n", JoinPoint::signature()); + } +}; + +#endif /* __Aspect__ */ diff --git a/AspectC++/tests/StandAloneCalls/Makefile b/AspectC++/tests/StandAloneCalls/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/StandAloneCalls/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/StandAloneCalls/feature.ref b/AspectC++/tests/StandAloneCalls/feature.ref new file mode 100644 index 0000000..cb366b9 --- /dev/null +++ b/AspectC++/tests/StandAloneCalls/feature.ref @@ -0,0 +1,18 @@ +int N1::foo() +int N2::foo() +int N2::foo() +int bar() +int bar() +int bar() +int bar() +StandAloneCalls: +=============================================================== +here starts main, but we should have seen our advice already +global var 1 = 1 +global var 2-1 = 1, 2-2 = 1 +global var 3 = 42 +--------------------------------------------------------------- +Now the advice for calls in constructor init lists is checked +int bar() +int bar() +--------------------------------------------------------------- diff --git a/AspectC++/tests/StandAloneCalls/main.cc b/AspectC++/tests/StandAloneCalls/main.cc new file mode 100644 index 0000000..db63548 --- /dev/null +++ b/AspectC++/tests/StandAloneCalls/main.cc @@ -0,0 +1,81 @@ +#include + +// case 1: call and function in the same namespace +namespace N1 { + + int foo() { + return 1; + } + + const int var = foo(); +} + +// case 2: call outside the namespace, function inside +namespace N2 { + + int foo() { + return 1; + } +} + +int var2_1 = N2::foo(), var2_2 = N2::foo (); + +// case 3: call inside the namespace, function outside +int bar() { return 42; } + +namespace N3 { + int var = ::bar(); +} + +// case 4: static attribute initialization +class Test { +public: + static int var; +}; + +int Test::var = bar (); + +// case 5: static attribute initialization in a namespace +namespace N3 { + class Test { + public: + static int var; + }; + + int Test::var = bar (); +} + +// case 6: static attribute initialization of class in namespace +namespace N4 { + class Test { + public: + static int var; + }; +} + +int N4::Test::var = bar (); + +// case 7: a call in an initializer list +class WithInitializer { + int attr; +public: + WithInitializer () : attr (bar ()) {} + WithInitializer (int); +}; + +WithInitializer::WithInitializer (int v) : attr (v + bar ()) {} + +int main() { + printf ("StandAloneCalls:\n"); + printf ("===============================================================\n"); + printf ("here starts main, but we should have seen our advice already\n"); + printf ("global var 1 = %d\n", N1::var); + printf ("global var 2-1 = %d, 2-2 = %d\n", var2_1, var2_2); + printf ("global var 3 = %d\n", N3::var); + printf ("---------------------------------------------------------------\n"); + printf ("Now the advice for calls in constructor init lists is checked\n"); + WithInitializer wi1; + WithInitializer wi2 (3); + printf ("---------------------------------------------------------------\n"); + return 0; +} diff --git a/AspectC++/tests/StaticTrace/Makefile b/AspectC++/tests/StaticTrace/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/StaticTrace/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/StaticTrace/Trace.ah b/AspectC++/tests/StaticTrace/Trace.ah new file mode 100644 index 0000000..1e343d8 --- /dev/null +++ b/AspectC++/tests/StaticTrace/Trace.ah @@ -0,0 +1,34 @@ +#ifndef __Trace_ah__ +#define __Trace_ah__ + +#include +using namespace std; + +template struct ArgPrinter { + template static inline void work (JP &tjp) { + ArgPrinter::work (tjp); + cout << "Arg " << I << ": " << *tjp.template arg () << endl; + } +}; + +template <> struct ArgPrinter<0> { + template static inline void work (JP &tjp) {} +}; + +aspect Trace { + template void print_args (JP &tjp) { + ArgPrinter::work (tjp); + } + advice call("% A::%(...)" || "% no_args()") : before() { + tjp->arg(0); // TODO: a workaround, because on demand code generation + // does not check the instantiated template + cout << JoinPoint::filename () << ":" << JoinPoint::line () << endl; + print_args (*tjp); + } +}; + +#endif // __Trace_ah__ + + + + diff --git a/AspectC++/tests/StaticTrace/feature.ref b/AspectC++/tests/StaticTrace/feature.ref new file mode 100644 index 0000000..c5a32ff --- /dev/null +++ b/AspectC++/tests/StaticTrace/feature.ref @@ -0,0 +1,15 @@ +Static Trace: arguments for each call +============================================================= +main.cc:16 +Arg 1: 4711 +Arg 2: 3.14 +Arg 3: 42 +------------------------------------------------------------- +main.cc:18 +Arg 1: 4712 +Arg 2: 3.15 +Arg 3: 42 +Arg 4: 0x12345678 +------------------------------------------------------------- +main.cc:20 +============================================================= diff --git a/AspectC++/tests/StaticTrace/main.cc b/AspectC++/tests/StaticTrace/main.cc new file mode 100644 index 0000000..a646761 --- /dev/null +++ b/AspectC++/tests/StaticTrace/main.cc @@ -0,0 +1,22 @@ +#include + +class A { +public: + void a(int i, float b, const int &a, void *p = (void*)0x4711) { + } +}; + +void no_args() {} + +int main() { + int val = 42; + A a; + printf ("Static Trace: arguments for each call\n"); + printf ("=============================================================\n"); + a.a(4711, 3.14f, val); + printf ("-------------------------------------------------------------\n"); + a.a(4712, 3.15f, val, (void*)0x12345678); + printf ("-------------------------------------------------------------\n"); + no_args (); + printf ("=============================================================\n"); +} diff --git a/AspectC++/tests/TemplateExtCall/Makefile b/AspectC++/tests/TemplateExtCall/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/TemplateExtCall/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/TemplateExtCall/feature.ref b/AspectC++/tests/TemplateExtCall/feature.ref new file mode 100644 index 0000000..7a84649 --- /dev/null +++ b/AspectC++/tests/TemplateExtCall/feature.ref @@ -0,0 +1,57 @@ +TemplateExtCall: tracing template arg dependant calls +===================================================== +methods of class template instances + +--- "void Array::set(int,const int &)" --- +ArrayTracer for any Array: "void Array::set(int,const int &)" +ArrayTracer for : "void Array::set(int,const int &)" + +--- "void Array::set(int,const int &)" --- +ArrayTracer for any Array: "void Array::set(int,const int &)" +ArrayTracer for : "void Array::set(int,const int &)" + +--- "void Array::set(int,const int &)" --- +ArrayTracer for any Array: "void Array::set(int,const int &)" +ArrayTracer for : "void Array::set(int,const int &)" + +--- "void Array::set(int,const int &)" --- +ArrayTracer for any Array: "void Array::set(int,const int &)" +ArrayTracer for : "void Array::set(int,const int &)" + +--- "int Array::get(int) const" --- +ArrayTracer for any Array: "int Array::get(int) const" +ArrayTracer for : "int Array::get(int) const" + +--- "void Array::set(int,const long int &)" --- +ArrayTracer for any Array: "void Array::set(int,const long int &)" +ArrayTracer for : "void Array::set(int,const long int &)" + +--- "void Array::set(int,const float &)" --- +ArrayTracer for any Array: "void Array::set(int,const float &)" +ArrayTracer for <%,3>: "void Array::set(int,const float &)" + +--- "float Array::get(int) const" --- +ArrayTracer for any Array: "float Array::get(int) const" +ArrayTracer for <%,3>: "float Array::get(int) const" + +--- "int Max(const int &,const int &)" --- +MaxTracer for any Max(...): "int Max(const int &,const int &)" +MaxTracer for Max(...): "int Max(const int &,const int &)" + +--- "double HardMatch::Max(const double &,const double &)" --- +MaxTracer for any Max(...): "double HardMatch::Max(const double &,const double &)" +----------------------------------------------------- +static template functions/member functions + +--- "C *alloc()" --- +C constructor + +--- "void dealloc(C *)" --- +C destructor + +--- "C *Sys<42>::Mem::alloc()" --- +C constructor + +--- "void Sys<42>::Mem::dealloc(C *)" --- +C destructor +===================================================== diff --git a/AspectC++/tests/TemplateExtCall/main.cc b/AspectC++/tests/TemplateExtCall/main.cc new file mode 100644 index 0000000..093b29f --- /dev/null +++ b/AspectC++/tests/TemplateExtCall/main.cc @@ -0,0 +1,116 @@ +#include +#include + +aspect AllTracer { + pointcut builtin_ops() = call("bool operator <(int,int)") || call("int operator -(int,int)") || call("int operator ++(int &,int)"); + pointcut the_calls () = call ("% ...::%(...)") && !call("% printf(...)") && ! builtin_ops(); + advice the_calls () : before () { + printf ("\n--- \"%s\" ---\n", JoinPoint::signature ()); + } +}; + +aspect ArrayTracer { + advice call ("% Array::%(...)") : before () { + printf ("ArrayTracer for any Array: \"%s\"\n", JoinPoint::signature ()); + } + advice call ("% Array::%(...)") : before () { + printf ("ArrayTracer for : \"%s\"\n", JoinPoint::signature ()); + } + advice call ("% Array<%,3>::%(...)") : before () { + printf ("ArrayTracer for <%%,3>: \"%s\"\n", JoinPoint::signature ()); + } + advice call ("% Array::%(...)") : before () { + printf ("ArrayTracer for : \"%s\"\n", JoinPoint::signature ()); + } +}; + +aspect MaxTracer { + advice call ("% ...::Max(...)") : before () { + printf ("MaxTracer for any Max(...): \"%s\"\n", + JoinPoint::signature ()); + } + advice call ("% Max(...)") : before () { + printf ("MaxTracer for Max(...): \"%s\"\n", + JoinPoint::signature ()); + } +}; + +template class Array { + T _data[I]; +public: + T get (int i) const { return _data[i]; } + void set (int i, const T &d) { _data[i] = d; } +}; + +template T Max(const T& v1, const T& v2) { + return v1 > v2 ? v1 : v2; +} + +namespace HardMatch { + template T Max(const T& v1, const T& v2) { + return v1 > v2 ? v1 : v2; + } +} + +template T* alloc () { return new T; } +template void dealloc (T *obj) { delete obj; } + +template struct Sys { + template struct Mem { + static T *alloc () { return new T; } + static void dealloc (T* obj) { delete obj; } + }; +}; + +template class HeapInt {}; + +template class BestFit : public HeapInt { +public: + void* Alloc(int s) { return malloc (s); } + void Dealloc(void *p) { free (p); } +}; + +template class P, int BS = 0> class Heap : public P +{ + typedef P Policy; +public: + void* Alloc(int s) { return Policy::Alloc(s); } + void Dealloc(void *p) { Policy::Dealloc(p); } +}; + + +struct C { + C () { printf ("C constructor\n"); } + ~C () { printf ("C destructor\n"); } +}; + +int main () { + Array data; + Array data_long; + Array data_3; + + printf ("TemplateExtCall: tracing template arg dependant calls\n"); + printf ("=====================================================\n"); + printf ("methods of class template instances\n"); + for (int i = 0; i < 4; i++) + data.set (i, 4 - i); + data.get (3); + data_long.set (2, 2L); + data_3.set (0, 3.14f); + data_3.get (0); + int max = Max (1, 2); + double harder_max = HardMatch::Max (2.3, 4.5); + printf ("-----------------------------------------------------\n"); + printf ("static template functions/member functions\n"); + C *ptr1 = alloc (); + dealloc (ptr1); + C *ptr2 = Sys<42>::Mem::alloc (); + Sys<42>::Mem::dealloc (ptr2); +// does not work yet!!! +// printf ("-----------------------------------------------------\n"); +// printf ("allocation with help of template template parameter\n"); +// Heap<10, BestFit> a; +// void *mem = a.Alloc(10); +// a.Dealloc (mem); + printf ("=====================================================\n"); +} diff --git a/AspectC++/tests/That/Makefile b/AspectC++/tests/That/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/That/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/That/feature.ref b/AspectC++/tests/That/feature.ref new file mode 100644 index 0000000..f9f974e --- /dev/null +++ b/AspectC++/tests/That/feature.ref @@ -0,0 +1,67 @@ +ordinary functions (there should be no advice) +on A: +A::A() +void A::f() +void A::f() +void A::g() +void A::g() +void A::h() +on B: +A::A() +B::B() +B::B() +void B::f() +void B::f() +void B::f() +void B::g() +void B::g() +void B::g() +void B::h() +on C: +A::A() +B::B() +B::B() +C::C() +C::C() +C::C() +void C::f() +void C::f() +void C::f() +void C::f() +void C::g() +void C::g() +void C::g() +void C::g() +void C::h() +on D: +A::A() +B::B() +B::B() +D::D() +D::D() +D::D() +void D::f() +void D::f() +void D::f() +void D::f() +void D::g() +void D::g() +void D::g() +void D::g() +void D::h() +D::~D() +D::~D() +D::~D() +B::~B() +B::~B() +A::~A() +C::~C() +C::~C() +C::~C() +B::~B() +B::~B() +A::~A() +B::~B() +B::~B() +A::~A() +A::~A() diff --git a/AspectC++/tests/That/main.cc b/AspectC++/tests/That/main.cc new file mode 100644 index 0000000..3d470ef --- /dev/null +++ b/AspectC++/tests/That/main.cc @@ -0,0 +1,96 @@ +#include "stdio.h" + +// aspects; that() used for each kind of object + +aspect On { + pointcut virtual kind() = 0; + advice kind () && !within("On") : after () { + printf ("%s\n", JoinPoint::signature ()); + } +}; + +aspect OnA : public On { pointcut kind () = that("A"); }; +aspect OnB : public On { pointcut kind () = that("B"); }; +aspect OnC : public On { pointcut kind () = that("C"); }; +aspect OnD : public On { pointcut kind () = that("D"); }; +aspect OnTargetCorD : public On { + pointcut kind () = target("C") || target("D"); +// pointcut kind () = that(derived("C%") && !base("A"||"B")) || target("D"); +}; +aspect OnThatnotCandnotD : public On { + pointcut kind () = !that("C") && !that("D") && execution("% %::%(...)"); +}; + +// class hierarchy; each class has an inline, static and non-inline function +// +// A (root) +// | +// B +// / \ +// C D (leafs) + +class A { +public: + void f () {} + void g (); + static void h () {} +}; +void A::g () {} + +class B : public A { +public: + void f () {} + void g (); + static void h () {} +}; +void B::g () {} + +class C : public B { +public: + void f () {} + void g (); + static void h () {} +}; +void C::g () {} + +class D : public B { +public: + void f () {} + void g (); + static void h () {} +}; +void D::g () {} + +// ordinary functions +void a () {} + +void b (); +void b () {} + +// testcode +int main () { + printf ("ordinary functions (there should be no advice)\n"); + a (); + b (); + printf ("on A:\n"); + A a; + a.f (); + a.g (); + a.h (); + printf ("on B:\n"); + B b; + b.f (); + b.g (); + b.h (); + printf ("on C:\n"); + C c; + c.f (); + c.g (); + c.h (); + printf ("on D:\n"); + D d; + d.f (); + d.g (); + d.h (); + return 0; +} diff --git a/AspectC++/tests/ThatConst/Makefile b/AspectC++/tests/ThatConst/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/ThatConst/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/ThatConst/feature.ref b/AspectC++/tests/ThatConst/feature.ref new file mode 100644 index 0000000..a4a52ba --- /dev/null +++ b/AspectC++/tests/ThatConst/feature.ref @@ -0,0 +1,15 @@ +construction 1 +construction 2 +ThatConst: checks access to const objects with 'that' +===================================================== +c1 (non-const object): +execution 1 +call 1 +execution 1 +c2 (const object): +execution 2 +call 2 +execution 2 +===================================================== +destruction 2 +destruction 1 diff --git a/AspectC++/tests/ThatConst/main.cc b/AspectC++/tests/ThatConst/main.cc new file mode 100644 index 0000000..2f0769b --- /dev/null +++ b/AspectC++/tests/ThatConst/main.cc @@ -0,0 +1,43 @@ +#include + +// in this class 'this' is constant in all functions! +class C { + int _id; + void g () const {} +public: + C (int id) : _id (id) {} + void f () const { g (); } +}; + +aspect ObjTracker { + + void print_jp_type (AC::JPType jptype) { + switch (jptype) { + case AC::EXECUTION: printf ("execution"); break; + case AC::CALL: printf ("call"); break; + case AC::CONSTRUCTION: printf ("construction"); break; + case AC::DESTRUCTION: printf ("destruction"); break; + default: printf ("unknown"); + } + } + + advice within ("C") && that (c) : around (C &c) { + print_jp_type (JoinPoint::JPTYPE); + printf (" %d\n", c._id); + tjp->proceed (); + } +}; + +int main () { + C c1(1); + const C c2 (2); + + printf ("ThatConst: checks access to const objects with 'that'\n"); + printf ("=====================================================\n"); + printf ("c1 (non-const object):\n"); + c1.f (); + printf ("c2 (const object):\n"); + c2.f (); + printf ("=====================================================\n"); + return 0; +} diff --git a/AspectC++/tests/ThatContext/Makefile b/AspectC++/tests/ThatContext/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/ThatContext/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/ThatContext/feature.ref b/AspectC++/tests/ThatContext/feature.ref new file mode 100644 index 0000000..54f283a --- /dev/null +++ b/AspectC++/tests/ThatContext/feature.ref @@ -0,0 +1,10 @@ +ThatContext: checks 'that' with context variables +================================================= +a.call() should yield nothing: +------------------------------------------------- +c.call() should yield two invocations of foo() within serve(): +before serve() +in Client_B::foo() +in Client_B::foo() +after serve() +================================================= diff --git a/AspectC++/tests/ThatContext/main.cc b/AspectC++/tests/ThatContext/main.cc new file mode 100644 index 0000000..61de775 --- /dev/null +++ b/AspectC++/tests/ThatContext/main.cc @@ -0,0 +1,57 @@ +#include + +class Server +{ +public: + void serve() {} +}; + +class Client_A +{ +public: + void call() + { + Server s; + s.serve(); + } +}; + +class Client_B : public Client_A { +public: + void foo() { + printf ("in Client_B::foo()\n"); + } +}; + +aspect Log { + pointcut log(Client_B &c) = call("% Server::serve(...)") && that(c); + + advice log(c) : after(Client_B &c) { + c.foo(); + } + + advice call("% Server::serve(...)") && that("Client_B") : after() { + Client_B &c = *(Client_B*)tjp->that (); + c.foo(); + } + + advice execution("% Client_A::call(...)") && that("Client_B") : around() { + printf ("before serve()\n"); + tjp->proceed (); + printf ("after serve()\n"); + } + +}; + +int main() { + printf ("ThatContext: checks 'that' with context variables\n"); + printf ("=================================================\n"); + printf ("a.call() should yield nothing:\n"); + Client_A a; + a.call(); + printf ("-------------------------------------------------\n"); + printf ("c.call() should yield two invocations of foo() within serve():\n"); + Client_B c; + c.call(); + printf ("=================================================\n"); +} diff --git a/AspectC++/tests/UnknownTypeCheck/Makefile b/AspectC++/tests/UnknownTypeCheck/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/UnknownTypeCheck/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/UnknownTypeCheck/a.cc b/AspectC++/tests/UnknownTypeCheck/a.cc new file mode 100644 index 0000000..d99f0a4 --- /dev/null +++ b/AspectC++/tests/UnknownTypeCheck/a.cc @@ -0,0 +1,10 @@ +#include +#include "a.h" + +void A::f () { + printf ("A::f() running\n"); +} + +void A::g () { + f (); +} diff --git a/AspectC++/tests/UnknownTypeCheck/a.h b/AspectC++/tests/UnknownTypeCheck/a.h new file mode 100644 index 0000000..5ce46b9 --- /dev/null +++ b/AspectC++/tests/UnknownTypeCheck/a.h @@ -0,0 +1,10 @@ +#ifndef __A_h__ +#define __A_h__ + +class A { +public: + void f (); + void g (); +}; + +#endif // __A_h__ diff --git a/AspectC++/tests/UnknownTypeCheck/b.h b/AspectC++/tests/UnknownTypeCheck/b.h new file mode 100644 index 0000000..3672a92 --- /dev/null +++ b/AspectC++/tests/UnknownTypeCheck/b.h @@ -0,0 +1,10 @@ +#ifndef __B_h__ +#define __B_h__ + +#include "a.h" + +class B : public A { +public: +}; + +#endif // __B_h__ diff --git a/AspectC++/tests/UnknownTypeCheck/check.ah b/AspectC++/tests/UnknownTypeCheck/check.ah new file mode 100644 index 0000000..fd2de50 --- /dev/null +++ b/AspectC++/tests/UnknownTypeCheck/check.ah @@ -0,0 +1,14 @@ +#ifndef __Check_ah__ +#define __Check_ah__ + +#include + +aspect Check { + advice target ("B") && call ("% %::f(...)") : around () { + printf ("--> %s\n", tjp->signature ()); + tjp->proceed (); + printf ("<--\n"); + } +}; + +#endif // __Check_ah__ diff --git a/AspectC++/tests/UnknownTypeCheck/feature.ref b/AspectC++/tests/UnknownTypeCheck/feature.ref new file mode 100644 index 0000000..669dfc8 --- /dev/null +++ b/AspectC++/tests/UnknownTypeCheck/feature.ref @@ -0,0 +1,13 @@ +UnknownTypeCheck: dynamic check for an unknown type +=============================================================== +with advice (invocation on B object): +--> void A::f() +A::f() running +<-- +--------------------------------------------------------------- +without advice (invocation on A object): +A::f() running +--------------------------------------------------------------- +without advice (invocation on Unrelated object): +void Unrelated::f() +=============================================================== diff --git a/AspectC++/tests/UnknownTypeCheck/main.cc b/AspectC++/tests/UnknownTypeCheck/main.cc new file mode 100644 index 0000000..ada09d7 --- /dev/null +++ b/AspectC++/tests/UnknownTypeCheck/main.cc @@ -0,0 +1,28 @@ +#include + +#include "b.h" + +class Unrelated { +public: + void f () { + printf ("void Unrelated::f()\n"); + } +}; + +int main () { + B b; + A a; + Unrelated u; + printf ("UnknownTypeCheck: dynamic check for an unknown type\n"); + printf ("===============================================================\n"); + printf ("with advice (invocation on B object):\n"); + b.g (); + printf ("---------------------------------------------------------------\n"); + printf ("without advice (invocation on A object):\n"); + a.g (); + printf ("---------------------------------------------------------------\n"); + printf ("without advice (invocation on Unrelated object):\n"); + u.f (); + printf ("===============================================================\n"); + return 0; +} diff --git a/AspectC++/tests/UnsizedArray/Makefile b/AspectC++/tests/UnsizedArray/Makefile new file mode 100644 index 0000000..f485359 --- /dev/null +++ b/AspectC++/tests/UnsizedArray/Makefile @@ -0,0 +1,2 @@ +ACFLAGS ?= --introspection +include ../Makefile.generic diff --git a/AspectC++/tests/UnsizedArray/feature.ref b/AspectC++/tests/UnsizedArray/feature.ref new file mode 100644 index 0000000..56cecfa --- /dev/null +++ b/AspectC++/tests/UnsizedArray/feature.ref @@ -0,0 +1,22 @@ +member offsets (should be distinct): +==================================== +i: 0 +letter: 1 +data: 2 + +member values: +============== +i: 0 +letter: 56 +data: + +write to m->data[] and use copy ctor (m2's data should be zeros): +================================================================= +m->data[]: 49494949494949494949 +m2->data[]: 0000000000 + +member values (m2's letter should be 56): +========================================= +i: 0 +letter: 56 +data: diff --git a/AspectC++/tests/UnsizedArray/main.cc b/AspectC++/tests/UnsizedArray/main.cc new file mode 100644 index 0000000..1df6db6 --- /dev/null +++ b/AspectC++/tests/UnsizedArray/main.cc @@ -0,0 +1,92 @@ +#include +using namespace std; + +class MyClass { +public: + int i; + // non-static introductions should be inserted before the unsized array + char data[]; + static int fourtytwo; +}; + +int MyClass::fourtytwo = 42; + + +aspect IntroAspect { + advice "MyClass" : slice class { public: int letter; }; + + advice construction("MyClass") : before() { tjp->that()->letter = 56; } +}; + + +unsigned char mempool[100]; + +int main() { + MyClass *m = (MyClass *)&mempool[0]; + new(&mempool[0]) MyClass; // placement new + + cout << "member offsets (should be distinct):" << endl + << "====================================" << endl; + if((AC::TypeInfo::Member<0>::spec & AC::SPEC_STATIC) == 0) + cout << AC::TypeInfo::Member<0>::name() << ": " << ((int*)AC::TypeInfo::Member<0>::pointer(m) - (int*)m) << endl; + if((AC::TypeInfo::Member<1>::spec & AC::SPEC_STATIC) == 0) + cout << AC::TypeInfo::Member<1>::name() << ": " << ((int*)AC::TypeInfo::Member<1>::pointer(m) - (int*)m) << endl; + if((AC::TypeInfo::Member<2>::spec & AC::SPEC_STATIC) == 0) + cout << AC::TypeInfo::Member<2>::name() << ": " << ((int*)AC::TypeInfo::Member<2>::pointer(m) - (int*)m) << endl; + if((AC::TypeInfo::Member<3>::spec & AC::SPEC_STATIC) == 0) + cout << AC::TypeInfo::Member<3>::name() << ": " << ((int*)AC::TypeInfo::Member<3>::pointer(m) - (int*)m) << endl; + + cout << endl + << "member values:" << endl + << "==============" << endl; + + if((AC::TypeInfo::Member<0>::spec & AC::SPEC_STATIC) == 0) + cout << AC::TypeInfo::Member<0>::name() << ": " << *AC::TypeInfo::Member<0>::pointer(m) << endl; + if((AC::TypeInfo::Member<1>::spec & AC::SPEC_STATIC) == 0) + cout << AC::TypeInfo::Member<1>::name() << ": " << *AC::TypeInfo::Member<1>::pointer(m) << endl; + if((AC::TypeInfo::Member<2>::spec & AC::SPEC_STATIC) == 0) + cout << AC::TypeInfo::Member<2>::name() << ": " << *AC::TypeInfo::Member<2>::pointer(m) << endl; + if((AC::TypeInfo::Member<3>::spec & AC::SPEC_STATIC) == 0) + cout << AC::TypeInfo::Member<3>::name() << ": " << *AC::TypeInfo::Member<3>::pointer(m) << endl; + + cout << endl; + + cout << "write to m->data[] and use copy ctor (m2's data should be zeros):" << endl + << "=================================================================" << endl; + for(int i=0; i<10; i++) { + m->data[i] = '1'; + } + m->data[10] = '\0'; + + // test (default) copy ctor + MyClass *m2 = (MyClass *)&mempool[50]; + *m2 = *m; + + // show that default copy ctor doesn't copy unsized arrays + cout << "m->data[]: "; + for(int i=0; i<10; i++) { + cout << (short)m->data[i]; + } + cout << endl; + cout << "m2->data[]: "; + for(int i=0; i<10; i++) { + cout << (short)m2->data[i]; + } + cout << endl; + + + cout << endl + << "member values (m2's letter should be 56):" << endl + << "=========================================" << endl; + + if((AC::TypeInfo::Member<0>::spec & AC::SPEC_STATIC) == 0) + cout << AC::TypeInfo::Member<0>::name() << ": " << *AC::TypeInfo::Member<0>::pointer(m2) << endl; + if((AC::TypeInfo::Member<1>::spec & AC::SPEC_STATIC) == 0) + cout << AC::TypeInfo::Member<1>::name() << ": " << *AC::TypeInfo::Member<1>::pointer(m2) << endl; + if((AC::TypeInfo::Member<2>::spec & AC::SPEC_STATIC) == 0) + cout << AC::TypeInfo::Member<2>::name() << ": " << *AC::TypeInfo::Member<2>::pointer(m2) << endl; + if((AC::TypeInfo::Member<3>::spec & AC::SPEC_STATIC) == 0) + cout << AC::TypeInfo::Member<3>::name() << ": " << *AC::TypeInfo::Member<3>::pointer(m2) << endl; + + return 0; +} diff --git a/AspectC++/tests/VirtualPointcuts/Makefile b/AspectC++/tests/VirtualPointcuts/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/VirtualPointcuts/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/VirtualPointcuts/feature.ref b/AspectC++/tests/VirtualPointcuts/feature.ref new file mode 100644 index 0000000..4a0d13b --- /dev/null +++ b/AspectC++/tests/VirtualPointcuts/feature.ref @@ -0,0 +1,5 @@ +VirtualPointcuts: checks virtual pointcut lookup +================================================ +Advice on virtual pct 'f()': void b() +Advice on pure virtual pct 'g()': void b() +================================================ diff --git a/AspectC++/tests/VirtualPointcuts/main.cc b/AspectC++/tests/VirtualPointcuts/main.cc new file mode 100644 index 0000000..c1722d6 --- /dev/null +++ b/AspectC++/tests/VirtualPointcuts/main.cc @@ -0,0 +1,32 @@ +#include + +void a() {} +void b() {} + +int main() { + printf ("VirtualPointcuts: checks virtual pointcut lookup\n"); + printf ("================================================\n"); + a(); + b(); + printf ("================================================\n"); +} + +aspect Base { + pointcut virtual f() = "void a()"; + pointcut virtual g() = 0; + + advice execution(f()) : before() { + printf ("Advice on virtual pct 'f()': %s\n", JoinPoint::signature()); + } + advice execution(g()) : before() { + printf ("Advice on pure virtual pct 'g()': %s\n", JoinPoint::signature()); + } +}; + +aspect Derived : public Base { + // should override, but doesn't: + pointcut virtual f() = "void b()"; + + // works + pointcut virtual g() = "void b()"; +}; diff --git a/AspectC++/tests/VoidArg/Makefile b/AspectC++/tests/VoidArg/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/AspectC++/tests/VoidArg/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/AspectC++/tests/VoidArg/feature.ref b/AspectC++/tests/VoidArg/feature.ref new file mode 100644 index 0000000..b6dd5c0 --- /dev/null +++ b/AspectC++/tests/VoidArg/feature.ref @@ -0,0 +1,45 @@ +VoidArg: checks advice for functions with void argument (#206) +============================================================== + -> before advice 1 for joinpoint "void myClass::inlineMethod()" + -> around advice 1 for joinpoint "void myClass::inlineMethod()" + >>> + -> before advice 2 for joinpoint "void myClass::inlineMethod()" + -> around advice 2 for joinpoint "void myClass::inlineMethod()" + >>> + -> before advice 1 for joinpoint "void myClass::inlineMethod()" + -> around advice 1 for joinpoint "void myClass::inlineMethod()" + >>> + -> before advice 2 for joinpoint "void myClass::inlineMethod()" + -> around advice 2 for joinpoint "void myClass::inlineMethod()" + >>> + in myClass::inlineMethod() + -> after advice 2 for joinpoint "void myClass::inlineMethod()" + <<< + -> after advice 1 for joinpoint "void myClass::inlineMethod()" + <<< + -> after advice 2 for joinpoint "void myClass::inlineMethod()" + <<< + -> after advice 1 for joinpoint "void myClass::inlineMethod()" + <<< + -> before advice 1 for joinpoint "void myClass::method()" + -> around advice 1 for joinpoint "void myClass::method()" + >>> + -> before advice 2 for joinpoint "void myClass::method()" + -> around advice 2 for joinpoint "void myClass::method()" + >>> + -> before advice 1 for joinpoint "void myClass::method()" + -> around advice 1 for joinpoint "void myClass::method()" + >>> + -> before advice 2 for joinpoint "void myClass::method()" + -> around advice 2 for joinpoint "void myClass::method()" + >>> + in myClass::method() + -> after advice 2 for joinpoint "void myClass::method()" + <<< + -> after advice 1 for joinpoint "void myClass::method()" + <<< + -> after advice 2 for joinpoint "void myClass::method()" + <<< + -> after advice 1 for joinpoint "void myClass::method()" + <<< +============================================================== diff --git a/AspectC++/tests/VoidArg/main.cc b/AspectC++/tests/VoidArg/main.cc new file mode 100644 index 0000000..9e1ff3a --- /dev/null +++ b/AspectC++/tests/VoidArg/main.cc @@ -0,0 +1,68 @@ +#include + +class myClass { +public: + void method(void); + + void inlineMethod(void) { + printf(" in myClass::inlineMethod()\n"); + } +}; + + +void myClass::method(void) { + printf(" in myClass::method()\n"); +} + +aspect myClassTracer { + + pointcut jps () = + call ("% myClass::%(...)") || execution ("% myClass::%(...)"); + + advice jps () : before () { + printf (" -> before advice 1 for joinpoint \"%s\"\n", + JoinPoint::signature ()); + } + + advice jps () : around () { + printf (" -> around advice 1 for joinpoint \"%s\"\n", + JoinPoint::signature ()); + printf (" >>>\n"); + tjp->proceed (); + printf (" <<<\n"); + } + + advice jps () : after () { + printf (" -> after advice 1 for joinpoint \"%s\"\n", + JoinPoint::signature ()); + } + + advice jps () : before () { + printf (" -> before advice 2 for joinpoint \"%s\"\n", + JoinPoint::signature ()); + } + + advice jps () : around () { + printf (" -> around advice 2 for joinpoint \"%s\"\n", + JoinPoint::signature ()); + printf (" >>>\n"); + tjp->proceed (); + printf (" <<<\n"); + } + + advice jps () : after () { + printf (" -> after advice 2 for joinpoint \"%s\"\n", + JoinPoint::signature ()); + } +}; + +int main () { + myClass mc; + + printf ("VoidArg: checks advice for functions with void argument (#206)\n"); + printf ("==============================================================\n"); + mc.inlineMethod (); + mc.method (); + printf ("==============================================================\n"); + return 0; +} diff --git a/AspectC++/tests/conv_junit.py b/AspectC++/tests/conv_junit.py new file mode 100755 index 0000000..3471bd4 --- /dev/null +++ b/AspectC++/tests/conv_junit.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# This script is reads "test-result.txt" and creates "test-result.xml". +# The latter provides the test results in JUnit format, so that it can +# be visualized by Jenkins. + +import re +import xml.dom.minidom +import sys + +# simply hard coded filename ... +input_file = "test-result.txt" +output_file = "test-result.xml" + +re_test_start = re.compile('^\-\-\-START TEST (?P[0-9]+): (?P\S*):.*') +re_test_end = re.compile('^\-\-\-END TEST (?P[0-9]+): (?P\S*): (?P\w+).*') + +test_results = [] +test_number = None +test_name = None +test_result = None +test_output = "" +test_summary = None + +file = open(input_file, 'r') + +for line in file: + match_line_start = re.match(re_test_start, line) + match_line_end = re.match(re_test_end, line) + if match_line_start: + test_number = match_line_start.group('no') + test_name = match_line_start.group('name') + elif match_line_end: + test_result = match_line_end.group('result') + test_results.append((test_number, test_name, test_result, test_output)) + test_number = None + test_output = "" + elif line[:-1] == "---START SUMMARY": + test_number = None + test_summary = "" +# print "Start Summary" + elif line[:-1] == "---END SUMMARY": +# print 'End Summary:', test_summary + test_summary = None + else: + if test_number: + test_output += line + elif test_summary != None: +# print "Summary Line", line + test_summary += line +# else: +# print "strange line" + +file.close() + +doc = xml.dom.minidom.Document() + +suites = doc.createElement("testsuites") +doc.appendChild(suites) +suite = doc.createElement("testsuite") +suite.setAttribute("name", "AspectC++ regression tests") +suite.setAttribute("tests", str(len(test_results))) +suites.appendChild(suite) + +for test in test_results: + (number, name, result, output) = test + elem = doc.createElement("testcase") + elem.setAttribute("name", name) + if result=="FAIL": + elem_err = doc.createElement("error") + elem.appendChild(elem_err) + if output != "": + elem_out = doc.createElement("system-out") + elem_out_txt = doc.createTextNode(output) + elem_out.appendChild(elem_out_txt) + elem.appendChild(elem_out) + suite.appendChild (elem) + +try: + file_object = open("test-result.xml", "w") +# file_object.write(doc.toprettyxml(encoding="utf-8")) + file_object.write(doc.toxml()) + file_object.close() +except: + print "Unexpected error:", sys.exc_info()[0] diff --git a/AspectC++/tests/genvcprojs.sh b/AspectC++/tests/genvcprojs.sh new file mode 100755 index 0000000..6f765e4 --- /dev/null +++ b/AspectC++/tests/genvcprojs.sh @@ -0,0 +1,230 @@ +#!/bin/sh + +# to be executed in the AspectC++/tests directory + +find . -maxdepth 2 -mindepth 2 -type f -name "Makefile" | +while read testmakefile; do + testdir=`dirname "$testmakefile"` + testname=`basename "$testdir"` + + echo "Generating project file $testdir/$testname.vcproj" + cd "$testdir" + rm -f "$testname.vcproj" + + REALINST=`grep -q "real-instances" Makefile && echo ";AC_OPTIONS="--real-instances""` + + cat >> "$testname.vcproj" << EOF + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +EOF + + find . -maxdepth 1 -type f -regex "\./.*\.\(c\|cc\|cxx\|cpp\)" -printf "%f\n" | + while read transunit; do + cat >> "$testname.vcproj" << EOF + +EOF + done + + cat >> "$testname.vcproj" << EOF + + +EOF + + find . -maxdepth 1 -type f -regex "\./.*\.\(h\|hxx\|hpp\)" -printf "%f\n" | + while read include; do + cat >> "$testname.vcproj" << EOF + +EOF + done + + cat >> "$testname.vcproj" << EOF + + + + + +EOF + + rm -f "${testname}_DummyAspect.ah" + + find . -maxdepth 1 -type f -regex "\./.*\.\(ah\|acc\)" -printf "%f\n" | + while read aspect; do + cat >> "$testname.vcproj" << EOF + +EOF + done + + if [ -z "`find . -maxdepth 1 -type f -regex "\./.*\.\(ah\|acc\)" -printf "%f\n"`" ]; then + echo " add dummy aspect" + cat >> "$testname.vcproj" << EOF + +EOF + echo " " > "${testname}_DummyAspect.ah" + fi + + cat >> "$testname.vcproj" << EOF + + + + + + + + +EOF + +# recode lat1..ibmpc -q "$testname.vcproj" + cd .. +done + +echo "Generating solution file WeaverTests.sln" +rm -f "WeaverTests.sln" + +cat >> "WeaverTests.sln" << EOF +Microsoft Visual Studio Solution File, Format Version 7.00 +EOF + +find . -maxdepth 2 -mindepth 2 -type f -name "Makefile" | +while read testmakefile; do + testdir=`dirname "$testmakefile"` + testname=`basename "$testdir"` + cat >> "WeaverTests.sln" << EOF +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "$testname", "$testname\\$testname.vcproj", "{37F3A735-0447-48C0-8FC5-832F01725A47}" +EndProject +EOF +done + +cat >> "WeaverTests.sln" << EOF +Global + GlobalSection(SolutionConfiguration) = preSolution + ConfigName.0 = Debug + ConfigName.1 = Release + EndGlobalSection + GlobalSection(ProjectDependencies) = postSolution + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {37F3A735-0447-48C0-8FC5-832F01725A47}.Debug.ActiveCfg = Debug|Win32 + {37F3A735-0447-48C0-8FC5-832F01725A47}.Debug.Build.0 = Debug|Win32 + {37F3A735-0447-48C0-8FC5-832F01725A47}.Release.ActiveCfg = Release|Win32 + {37F3A735-0447-48C0-8FC5-832F01725A47}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal +EOF + +#recode lat1..ibmpc -q "WeaverTests.sln" diff --git a/AspectC++/tests/rmvcprojs.sh b/AspectC++/tests/rmvcprojs.sh new file mode 100755 index 0000000..230fab5 --- /dev/null +++ b/AspectC++/tests/rmvcprojs.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +# to be executed in the AspectC++/tests directory + +rm -f */*.vcproj* */*DummyAspect.ah +rm -f WeaverTests.* +rm -rf */Debug */Release + diff --git a/AspectC++/tools/cvs2cl b/AspectC++/tools/cvs2cl new file mode 100755 index 0000000..cc76507 --- /dev/null +++ b/AspectC++/tools/cvs2cl @@ -0,0 +1,2404 @@ +#!/bin/sh +exec perl -w -x $0 ${1+"$@"} # -*- mode: perl; perl-indent-level: 2; -*- +#!perl -w + + +############################################################## +### ### +### cvs2cl.pl: produce ChangeLog(s) from `cvs log` output. ### +### ### +############################################################## + +## $Revision: 1.1 $ +## $Date: 2004/01/28 10:45:56 $ +## $Author: matthias.urban $ +## +## (C) 2001,2002,2003 Martyn J. Pearce , under the GNU GPL. +## (C) 1999 Karl Fogel , under the GNU GPL. +## +## (Extensively hacked on by Melissa O'Neill .) +## (Gecos hacking by Robin Johnson .) +## +## cvs2cl.pl 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, or (at your option) +## any later version. +## +## cvs2cl.pl 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 may have received a copy of the GNU General Public License +## along with cvs2cl.pl; see the file COPYING. If not, write to the +## Free Software Foundation, Inc., 59 Temple Place - Suite 330, +## Boston, MA 02111-1307, USA. + + +use strict; +use Text::Wrap qw( ); +use Time::Local; +use File::Basename qw( fileparse ); +use User::pwent; + + +# The Plan: +# +# Read in the logs for multiple files, spit out a nice ChangeLog that +# mirrors the information entered during `cvs commit'. +# +# The problem presents some challenges. In an ideal world, we could +# detect files with the same author, log message, and checkin time -- +# each would be a changelog entry. +# We'd sort them; and spit them out. Unfortunately, CVS is *not atomic* +# so checkins can span a range of times. Also, the directory structure +# could be hierarchical. +# +# Another question is whether we really want to have the ChangeLog +# exactly reflect commits. An author could issue two related commits, +# with different log entries, reflecting a single logical change to the +# source. GNU style ChangeLogs group these under a single author/date. +# We try to do the same. +# +# So, we parse the output of `cvs log', storing log messages in a +# multilevel hash that stores the mapping: +# directory => author => time => message => filelist +# As we go, we notice "nearby" commit times and store them together +# (i.e., under the same timestamp), so they appear in the same log +# entry. +# +# When we've read all the logs, we twist this mapping into +# a time => author => message => filelist mapping for each directory. +# +# If we're not using the `--distributed' flag, the directory is always +# considered to be `./', even as descend into subdirectories. + + +############### Globals ################ + +use constant MAILNAME => "/etc/mailname"; + +# What we run to generate it: +my $Log_Source_Command = "cvs log"; + +# In case we have to print it out: +my $VERSION = '$Revision: 1.1 $'; +$VERSION =~ s/\S+\s+(\S+)\s+\S+/$1/; + +## Vars set by options: + +# Print debugging messages? +my $Debug = 0; + +# Just show version and exit? +my $Print_Version = 0; + +# Just print usage message and exit? +my $Print_Usage = 0; + +# Single top-level ChangeLog, or one per subdirectory? +my $Distributed = 0; + +# What file should we generate (defaults to "ChangeLog")? +my $Log_File_Name = "ChangeLog"; + +# Grab most recent entry date from existing ChangeLog file, just add +# to that ChangeLog. +my $Cumulative = 0; + +# `cvs log -d`, this will repeat the last entry in the old log. This is OK, +# as it guarantees at least one entry in the update changelog, which means +# that there will always be a date to extract for the next update. The repeat +# entry can be removed in postprocessing, if necessary. +my $Update = 0; + +# Expand usernames to email addresses based on a map file? +my $User_Map_File = ""; +my $User_Passwd_File; +my $Mail_Domain; + +# Output log in chronological order? [default is reverse chronological order] +my $Chronological_Order = 0; + +# Grab user details via gecos +my $Gecos = 0; + +# User domain for gecos email addresses +my $Domain; + +# Output to a file or to stdout? +my $Output_To_Stdout = 0; + +# Eliminate empty log messages? +my $Prune_Empty_Msgs = 0; + +# Tags of which not to output +my %ignore_tags; + +# Show only revisions with Tags +my %show_tags; + +# Don't call Text::Wrap on the body of the message +my $No_Wrap = 0; + +# Don't do any pretty print processing +my $Summary = 0; + +# Separates header from log message. Code assumes it is either " " or +# "\n\n", so if there's ever an option to set it to something else, +# make sure to go through all conditionals that use this var. +my $After_Header = " "; + +# XML Encoding +my $XML_Encoding = ''; + +# Format more for programs than for humans. +my $XML_Output = 0; + +# Do some special tweaks for log data that was written in FSF +# ChangeLog style. +my $FSF_Style = 0; + +# Show times in UTC instead of local time +my $UTC_Times = 0; + +# Show times in output? +my $Show_Times = 1; + +# Show day of week in output? +my $Show_Day_Of_Week = 0; + +# Show revision numbers in output? +my $Show_Revisions = 0; + +# Show dead files in output? +my $Show_Dead = 0; + +# Hide dead trunk files which were created as a result of additions on a +# branch? +my $Hide_Branch_Additions = 1; + +# Show tags (symbolic names) in output? +my $Show_Tags = 0; + +# Show tags separately in output? +my $Show_Tag_Dates = 0; + +# Show branches by symbolic name in output? +my $Show_Branches = 0; + +# Show only revisions on these branches or their ancestors. +my @Follow_Branches; + +# Don't bother with files matching this regexp. +my @Ignore_Files; + +# How exactly we match entries. We definitely want "o", +# and user might add "i" by using --case-insensitive option. +my $Case_Insensitive = 0; + +# Maybe only show log messages matching a certain regular expression. +my $Regexp_Gate = ""; + +# Pass this global option string along to cvs, to the left of `log': +my $Global_Opts = ""; + +# Pass this option string along to the cvs log subcommand: +my $Command_Opts = ""; + +# Read log output from stdin instead of invoking cvs log? +my $Input_From_Stdin = 0; + +# Don't show filenames in output. +my $Hide_Filenames = 0; + +# Don't shorten directory names from filenames. +my $Common_Dir = 1; + +# Max checkin duration. CVS checkin is not atomic, so we may have checkin +# times that span a range of time. We assume that checkins will last no +# longer than $Max_Checkin_Duration seconds, and that similarly, no +# checkins will happen from the same users with the same message less +# than $Max_Checkin_Duration seconds apart. +my $Max_Checkin_Duration = 180; + +# What to put at the front of [each] ChangeLog. +my $ChangeLog_Header = ""; + +# Whether to enable 'delta' mode, and for what start/end tags. +my $Delta_Mode = 0; +my $Delta_From = ""; +my $Delta_To = ""; + +my $TestCode; + +# Whether to parse filenames from the RCS filename, and if so what +# prefix to strip. +my $RCS_Mode = 0; +my $RCS_Root = ""; + +## end vars set by options. + +# latest observed times for the start/end tags in delta mode +my $Delta_StartTime = 0; +my $Delta_EndTime = 0; + +# In 'cvs log' output, one long unbroken line of equal signs separates +# files: +my $file_separator = "=======================================" + . "======================================"; + +# In 'cvs log' output, a shorter line of dashes separates log messages +# within a file: +my $logmsg_separator = "----------------------------"; + +my $No_Ancestors = 0; + +############### End globals ############ + + + +&parse_options (); +if ( defined $TestCode ) { + eval $TestCode; + die "Eval failed: '$@'\n" + if $@; +} else { + &derive_change_log (); +} + + +### Everything below is subroutine definitions. ### + +sub run_ext { + my ($cmd) = @_; + $cmd = [$cmd] + unless ref $cmd; + local $" = ' '; + my $out = qx"@$cmd 2>&1"; + my $rv = $?; + my ($sig, $core, $exit) = ($? & 127, $? & 128, $? >> 8); + return $out, $exit, $sig, $core; +} + +# If accumulating, grab the boundary date from pre-existing ChangeLog. +sub maybe_grab_accumulation_date () +{ + if (! $Cumulative || $Update) { + return ""; + } + + # else + + open (LOG, "$Log_File_Name") + or die ("trouble opening $Log_File_Name for reading ($!)"); + + my $boundary_date; + while () + { + if (/^(\d\d\d\d-\d\d-\d\d\s+\d\d:\d\d)/) + { + $boundary_date = "$1"; + last; + } + } + + close (LOG); + + # convert time from utc to local timezone if the ChangeLog has + # dates/times in utc + if ($UTC_Times && $boundary_date) + { + # convert the utc time to a time value + my ($year,$mon,$mday,$hour,$min) = $boundary_date =~ + m#(\d+)-(\d+)-(\d+)\s+(\d+):(\d+)#; + my $time = timegm(0,$min,$hour,$mday,$mon-1,$year-1900); + # print the timevalue in the local timezone + my ($ignore,$wday); + ($ignore,$min,$hour,$mday,$mon,$year,$wday) = localtime($time); + $boundary_date=sprintf ("%4u-%02u-%02u %02u:%02u", + $year+1900,$mon+1,$mday,$hour,$min); + } + + return $boundary_date; +} + +sub wrap { + my ($indent1, $indent2, @text) = @_; + my $text = Text::Wrap::wrap($indent1, $indent2, @text); + # If incoming text looks preformatted, don't get clever + if ( grep /^\s+/m, @text ) { + return $text; + } + my @lines = split /\n/, $text; + $indent2 =~ s!^((?: {8})+)!"\t" x (length($1)/8)!e; + $lines[0] =~ s/^$indent1\s+/$indent1/; + s/^$indent2\s+/$indent2/ + for @lines[1..$#lines]; + my $newtext = join "\n", @lines; + $newtext .= "\n" + if substr($text, -1) eq "\n"; + return $newtext; +} + +# Fills up a ChangeLog structure in the current directory. +sub derive_change_log () +{ + # See "The Plan" above for a full explanation. + + my %grand_poobah; + + my $file_full_path; + my $time; + my $revision; + my $author; + my $state; + my $lines; + my $cvsstate; + my $msg_txt; + my $detected_file_separator; + + my %tag_date_printed; + + # Might be adding to an existing ChangeLog + my $accumulation_date = &maybe_grab_accumulation_date (); + if ($accumulation_date) { + # Insert -d immediately after 'cvs log' + my $Log_Date_Command = "-d\'>${accumulation_date}\'"; + $Log_Source_Command =~ s/(^.*log\S*)/$1 $Log_Date_Command/; + &debug ("(adding log msg starting from $accumulation_date)\n"); + } + + # We might be expanding usernames + my %usermap; + + # In general, it's probably not very maintainable to use state + # variables like this to tell the loop what it's doing at any given + # moment, but this is only the first one, and if we never have more + # than a few of these, it's okay. + my $collecting_symbolic_names = 0; + my %symbolic_names; # Where tag names get stored. + my %branch_names; # We'll grab branch names while we're at it. + my %branch_numbers; # Save some revisions for @Follow_Branches + my @branch_roots; # For showing which files are branch ancestors. + + # Bleargh. Compensate for a deficiency of custom wrapping. + if (($After_Header ne " ") and $FSF_Style) + { + $After_Header .= "\t"; + } + + if (! $Input_From_Stdin) { + &debug ("(run \"${Log_Source_Command}\")\n"); + open (LOG_SOURCE, "$Log_Source_Command |") + or die "unable to run \"${Log_Source_Command}\""; + } + else { + open (LOG_SOURCE, "-") or die "unable to open stdin for reading"; + } + + binmode LOG_SOURCE; + + %usermap = &maybe_read_user_map_file (); + + while () + { + # Canonicalize line endings + s/\r$//; + my $new_full_path; + + # If on a new file and don't see filename, skip until we find it, and + # when we find it, grab it. + if (! (defined $file_full_path)) + { + if (/^Working file: (.*)/) { + $new_full_path = $1; + } elsif ($RCS_Mode && m|^RCS file: $RCS_Root[/\\](.*),v$|) { + $new_full_path = $1; + } + } + + if (defined $new_full_path) + { + $file_full_path = $new_full_path; + if (@Ignore_Files) + { + my $base; + ($base, undef, undef) = fileparse ($file_full_path); + # Ouch, I wish trailing operators in regexps could be + # evaluated on the fly! + if ($Case_Insensitive) { + if (grep ($file_full_path =~ m|$_|i, @Ignore_Files)) { + undef $file_full_path; + } + } + elsif (grep ($file_full_path =~ m|$_|, @Ignore_Files)) { + undef $file_full_path; + } + } + next; + } + + # Just spin wheels if no file defined yet. + next if (! $file_full_path); + + # Collect tag names in case we're asked to print them in the output. + if (/^symbolic names:$/) { + $collecting_symbolic_names = 1; + next; # There's no more info on this line, so skip to next + } + if ($collecting_symbolic_names) + { + # All tag names are listed with whitespace in front in cvs log + # output; so if see non-whitespace, then we're done collecting. + if (/^\S/) { + $collecting_symbolic_names = 0; + } + else # we're looking at a tag name, so parse & store it + { + # According to the Cederqvist manual, in node "Tags", tag + # names must start with an uppercase or lowercase letter and + # can contain uppercase and lowercase letters, digits, `-', + # and `_'. However, it's not our place to enforce that, so + # we'll allow anything CVS hands us to be a tag: + /^\s+([^:]+): ([\d.]+)$/; + my $tag_name = $1; + my $tag_rev = $2; + + # A branch number either has an odd number of digit sections + # (and hence an even number of dots), or has ".0." as the + # second-to-last digit section. Test for these conditions. + my $real_branch_rev = ""; + if (($tag_rev =~ /^(\d+\.\d+\.)+\d+$/) # Even number of dots... + and (! ($tag_rev =~ /^(1\.)+1$/))) # ...but not "1.[1.]1" + { + $real_branch_rev = $tag_rev; + } + elsif ($tag_rev =~ /(\d+\.(\d+\.)+)0.(\d+)/) # Has ".0." + { + $real_branch_rev = $1 . $3; + } + # If we got a branch, record its number. + if ($real_branch_rev) + { + $branch_names{$real_branch_rev} = $tag_name; + if (@Follow_Branches) { + if (grep ($_ eq $tag_name, @Follow_Branches)) { + $branch_numbers{$tag_name} = $real_branch_rev; + } + } + } + else { + # Else it's just a regular (non-branch) tag. + push (@{$symbolic_names{$tag_rev}}, $tag_name); + } + } + } + # End of code for collecting tag names. + + # If have file name, but not revision, and see revision, then grab + # it. (We collect unconditionally, even though we may or may not + # ever use it.) + if ((! (defined $revision)) and (/^revision (\d+\.[\d.]+)/)) + { + $revision = $1; + + if (@Follow_Branches) + { + foreach my $branch (@Follow_Branches) + { + # Special case for following trunk revisions + if (($branch =~ /^trunk$/i) and ($revision =~ /^[0-9]+\.[0-9]+$/)) + { + goto dengo; + } + + my $branch_number = $branch_numbers{$branch}; + if ($branch_number) + { + # Are we on one of the follow branches or an ancestor of + # same? + # + # If this revision is a prefix of the branch number, or + # possibly is less in the minormost number, OR if this + # branch number is a prefix of the revision, then yes. + # Otherwise, no. + # + # So below, we determine if any of those conditions are + # met. + + # Trivial case: is this revision on the branch? + # (Compare this way to avoid regexps that screw up Emacs + # indentation, argh.) + if ((substr ($revision, 0, ((length ($branch_number)) + 1))) + eq ($branch_number . ".")) + { + goto dengo; + } + # Non-trivial case: check if rev is ancestral to branch + elsif ((length ($branch_number)) > (length ($revision)) + and + $No_Ancestors) + { + $revision =~ /^((?:\d+\.)+)(\d+)$/; + my $r_left = $1; # still has the trailing "." + my $r_end = $2; + + $branch_number =~ /^((?:\d+\.)+)(\d+)\.\d+$/; + my $b_left = $1; # still has trailing "." + my $b_mid = $2; # has no trailing "." + + if (($r_left eq $b_left) + && ($r_end <= $b_mid)) + { + goto dengo; + } + } + } + } + } + else # (! @Follow_Branches) + { + next; + } + + # Else we are following branches, but this revision isn't on the + # path. So skip it. + undef $revision; + dengo: + next; + } + + # If we don't have a revision right now, we couldn't possibly + # be looking at anything useful. + if (! (defined ($revision))) { + $detected_file_separator = /^$file_separator$/o; + if ($detected_file_separator) { + # No revisions for this file; can happen, e.g. "cvs log -d DATE" + goto CLEAR; + } + else { + next; + } + } + + # If have file name but not date and author, and see date or + # author, then grab them: + unless (defined $time) + { + if (/^date: .*/) + { + ($time, $author, $state, $lines) = + &parse_date_author_and_state ($_); + if (defined ($usermap{$author}) and $usermap{$author}) { + $author = $usermap{$author}; + } elsif(defined $Domain or $Gecos == 1) { + my $email = $author; + if(defined $Domain && $Domain ne '') { + $email = $author."@".$Domain; + } + my $pw = getpwnam($author); + my $fullname; + my $office; + my $workphone; + my $homephone; + for (($fullname, $office, $workphone, $homephone) = split /\s*,\s*/, $pw->gecos) { + s/&/ucfirst(lc($pw->name))/ge; + } + if($fullname ne "") { + $author = $fullname . " <" . $email . ">"; + } + } + } + else { + $detected_file_separator = /^$file_separator$/o; + if ($detected_file_separator) { + # No revisions for this file; can happen, e.g. "cvs log -d DATE" + goto CLEAR; + } + } + # If the date/time/author hasn't been found yet, we couldn't + # possibly care about anything we see. So skip: + next; + } + + # A "branches: ..." line here indicates that one or more branches + # are rooted at this revision. If we're showing branches, then we + # want to show that fact as well, so we collect all the branches + # that this is the latest ancestor of and store them in + # @branch_roots. Just for reference, the format of the line we're + # seeing at this point is: + # + # branches: 1.5.2; 1.5.4; ...; + # + # Okay, here goes: + + if (/^branches:\s+(.*);$/) + { + if ($Show_Branches) + { + my $lst = $1; + $lst =~ s/(1\.)+1;|(1\.)+1$//; # ignore the trivial branch 1.1.1 + if ($lst) { + @branch_roots = split (/;\s+/, $lst); + } + else { + undef @branch_roots; + } + next; + } + else + { + # Ugh. This really bothers me. Suppose we see a log entry + # like this: + # + # ---------------------------- + # revision 1.1 + # date: 1999/10/17 03:07:38; author: jrandom; state: Exp; + # branches: 1.1.2; + # Intended first line of log message begins here. + # ---------------------------- + # + # The question is, how we can tell the difference between that + # log message and a *two*-line log message whose first line is + # + # "branches: 1.1.2;" + # + # See the problem? The output of "cvs log" is inherently + # ambiguous. + # + # For now, we punt: we liberally assume that people don't + # write log messages like that, and just toss a "branches:" + # line if we see it but are not showing branches. I hope no + # one ever loses real log data because of this. + next; + } + } + + # If have file name, time, and author, then we're just grabbing + # log message texts: + $detected_file_separator = /^$file_separator$/o; + if ($detected_file_separator && ! (defined $revision)) { + # No revisions for this file; can happen, e.g. "cvs log -d DATE" + goto CLEAR; + } + unless ($detected_file_separator || /^$logmsg_separator$/o) + { + $msg_txt .= $_; # Normally, just accumulate the message... + next; + } + # ... until a msg separator is encountered: + # Ensure the message contains something: + if ((! $msg_txt) + || ($msg_txt =~ /^\s*\.\s*$|^\s*$/) + || ($msg_txt =~ /\*\*\* empty log message \*\*\*/)) + { + if ($Prune_Empty_Msgs) { + goto CLEAR; + } + # else + $msg_txt = "[no log message]\n"; + } + + ### Store it all in the Grand Poobah: + { + my $dir_key; # key into %grand_poobah + my %qunk; # complicated little jobbie, see below + + # Each revision of a file has a little data structure (a `qunk') + # associated with it. That data structure holds not only the + # file's name, but any additional information about the file + # that might be needed in the output, such as the revision + # number, tags, branches, etc. The reason to have these things + # arranged in a data structure, instead of just appending them + # textually to the file's name, is that we may want to do a + # little rearranging later as we write the output. For example, + # all the files on a given tag/branch will go together, followed + # by the tag in parentheses (so trunk or otherwise non-tagged + # files would go at the end of the file list for a given log + # message). This rearrangement is a lot easier to do if we + # don't have to reparse the text. + # + # A qunk looks like this: + # + # { + # filename => "hello.c", + # revision => "1.4.3.2", + # time => a timegm() return value (moment of commit) + # tags => [ "tag1", "tag2", ... ], + # branch => "branchname" # There should be only one, right? + # branchroots => [ "branchtag1", "branchtag2", ... ] + # } + + if ($Distributed) { + # Just the basename, don't include the path. + ($qunk{'filename'}, $dir_key, undef) = fileparse ($file_full_path); + } + else { + $dir_key = "./"; + $qunk{'filename'} = $file_full_path; + } + + # This may someday be used in a more sophisticated calculation + # of what other files are involved in this commit. For now, we + # don't use it much except for delta mode, because the + # common-commit-detection algorithm is hypothesized to be + # "good enough" as it stands. + $qunk{'time'} = $time; + + # We might be including revision numbers and/or tags and/or + # branch names in the output. Most of the code from here to + # loop-end deals with organizing these in qunk. + + $qunk{'revision'} = $revision; + $qunk{'state'} = $state; + if ( defined( $lines )) { + $qunk{'lines'} = $lines; + } + + # Grab the branch, even though we may or may not need it: + $qunk{'revision'} =~ /((?:\d+\.)+)\d+/; + my $branch_prefix = $1; + $branch_prefix =~ s/\.$//; # strip off final dot + if ($branch_names{$branch_prefix}) { + $qunk{'branch'} = $branch_names{$branch_prefix}; + } + + # Keep a record of the file's cvs state. + $qunk{'cvsstate'} = $state; + + # If there's anything in the @branch_roots array, then this + # revision is the root of at least one branch. We'll display + # them as branch names instead of revision numbers, the + # substitution for which is done directly in the array: + if (@branch_roots) { + my @roots = map { $branch_names{$_} } @branch_roots; + $qunk{'branchroots'} = \@roots; + } + + # Save tags too. + if (defined ($symbolic_names{$revision})) { + $qunk{'tags'} = $symbolic_names{$revision}; + delete $symbolic_names{$revision}; + + # If we're in 'delta' mode, update the latest observed + # times for the beginning and ending tags, and + # when we get around to printing output, we will simply restrict + # ourselves to that timeframe... + + if ($Delta_Mode) { + if (($time > $Delta_StartTime) && + (grep { $_ eq $Delta_From } @{$qunk{'tags'}})) + { + $Delta_StartTime = $time; + } + + if (($time > $Delta_EndTime) && + (grep { $_ eq $Delta_To } @{$qunk{'tags'}})) + { + $Delta_EndTime = $time; + } + } + } + + unless ($Hide_Branch_Additions and $msg_txt =~ /file \S+ was initially added on branch \S+./) { + # Add this file to the list + # (We use many spoonfuls of autovivication magic. Hashes and arrays + # will spring into existence if they aren't there already.) + + &debug ("(pushing log msg for ${dir_key}$qunk{'filename'})\n"); + + # Store with the files in this commit. Later we'll loop through + # again, making sure that revisions with the same log message + # and nearby commit times are grouped together as one commit. + push (@{$grand_poobah{$dir_key}{$author}{$time}{$msg_txt}}, \%qunk); + } + } + + CLEAR: + # Make way for the next message + undef $msg_txt; + undef $time; + undef $revision; + undef $author; + undef @branch_roots; + + # Maybe even make way for the next file: + if ($detected_file_separator) { + undef $file_full_path; + undef %branch_names; + undef %branch_numbers; + undef %symbolic_names; + } + } + + close (LOG_SOURCE); + + ### Process each ChangeLog + + while (my ($dir,$authorhash) = each %grand_poobah) + { + &debug ("DOING DIR: $dir\n"); + + # Here we twist our hash around, from being + # author => time => message => filelist + # in %$authorhash to + # time => author => message => filelist + # in %changelog. + # + # This is also where we merge entries. The algorithm proceeds + # through the timeline of the changelog with a sliding window of + # $Max_Checkin_Duration seconds; within that window, entries that + # have the same log message are merged. + # + # (To save space, we zap %$authorhash after we've copied + # everything out of it.) + + my %changelog; + while (my ($author,$timehash) = each %$authorhash) + { + my $lasttime; + my %stamptime; + foreach my $time (sort {$main::a <=> $main::b} (keys %$timehash)) + { + my $msghash = $timehash->{$time}; + while (my ($msg,$qunklist) = each %$msghash) + { + my $stamptime = $stamptime{$msg}; + if ((defined $stamptime) + and (($time - $stamptime) < $Max_Checkin_Duration) + and (defined $changelog{$stamptime}{$author}{$msg})) + { + push(@{$changelog{$stamptime}{$author}{$msg}}, @$qunklist); + } + else { + $changelog{$time}{$author}{$msg} = $qunklist; + $stamptime{$msg} = $time; + } + } + } + } + undef (%$authorhash); + + ### Now we can write out the ChangeLog! + + my ($logfile_here, $logfile_bak, $tmpfile); + + if (! $Output_To_Stdout) { + $logfile_here = $dir . $Log_File_Name; + $logfile_here =~ s/^\.\/\//\//; # fix any leading ".//" problem + $tmpfile = "${logfile_here}.cvs2cl$$.tmp"; + $logfile_bak = "${logfile_here}.bak"; + + open (LOG_OUT, ">$tmpfile") or die "Unable to open \"$tmpfile\""; + } + else { + open (LOG_OUT, ">-") or die "Unable to open stdout for writing"; + } + + print LOG_OUT $ChangeLog_Header; + + if ($XML_Output) { + my $encoding = + length $XML_Encoding ? qq'encoding="$XML_Encoding"' : ''; + my $version = 'version="1.0"'; + my $declaration = + sprintf '', join ' ', grep length, $version, $encoding; + my $root = + ''; + print LOG_OUT "$declaration\n\n$root\n\n"; + } + + my @key_list = (); + if($Chronological_Order) { + @key_list = sort {$main::a <=> $main::b} (keys %changelog); + } else { + @key_list = sort {$main::b <=> $main::a} (keys %changelog); + } + foreach my $time (@key_list) + { + next if ($Delta_Mode && + (($time <= $Delta_StartTime) || + ($time > $Delta_EndTime && $Delta_EndTime))); + + # Set up the date/author line. + # kff todo: do some more XML munging here, on the header + # part of the entry: + my ($ignore,$min,$hour,$mday,$mon,$year,$wday) + = $UTC_Times ? gmtime($time) : localtime($time); + + # XML output includes everything else, we might as well make + # it always include Day Of Week too, for consistency. + if ($Show_Day_Of_Week or $XML_Output) { + $wday = ("Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday")[$wday]; + $wday = ($XML_Output) ? "${wday}\n" : " $wday"; + } + else { + $wday = ""; + } + + my $authorhash = $changelog{$time}; + if ($Show_Tag_Dates) { + my %tags; + while (my ($author,$mesghash) = each %$authorhash) { + while (my ($msg,$qunk) = each %$mesghash) { + foreach my $qunkref2 (@$qunk) { + if (defined ($$qunkref2{'tags'})) { + foreach my $tag (@{$$qunkref2{'tags'}}) { + $tags{$tag} = 1; + } + } + } + } + } + foreach my $tag (keys %tags) { + if (!defined $tag_date_printed{$tag}) { + $tag_date_printed{$tag} = $time; + if ($XML_Output) { + # NOT YET DONE + } + else { + if ($Show_Times) { + printf LOG_OUT ("%4u-%02u-%02u${wday} %02u:%02u tag %s\n\n", + $year+1900, $mon+1, $mday, $hour, $min, $tag); + } else { + printf LOG_OUT ("%4u-%02u-%02u${wday} tag %s\n\n", + $year+1900, $mon+1, $mday, $tag); + } + } + } + } + } + while (my ($author,$mesghash) = each %$authorhash) + { + # If XML, escape in outer loop to avoid compound quoting: + if ($XML_Output) { + $author = &xml_escape ($author); + } + + FOOBIE: + # We sort here to enable predictable ordering for the testing porpoises + for my $msg (sort keys %$mesghash) + { + my $qunklist = $mesghash->{$msg}; + + ## MJP: 19.xii.01 : Exclude @ignore_tags + for my $ignore_tag (keys %ignore_tags) { + next FOOBIE + if grep($_ eq $ignore_tag, map(@{$_->{tags}}, + grep(defined $_->{tags}, + @$qunklist))); + } + ## MJP: 19.xii.01 : End exclude @ignore_tags + + # show only files with tag --show-tag $show_tag + if ( keys %show_tags ) { + next FOOBIE + if !grep(exists $show_tags{$_}, map(@{$_->{tags}}, + grep(defined $_->{tags}, + @$qunklist))); + } + + my $files = &pretty_file_list ($qunklist); + my $header_line; # date and author + my $body; # see below + my $wholething; # $header_line + $body + + if ($XML_Output) { + $header_line = + sprintf ("%4u-%02u-%02u\n" + . "${wday}" + . "\n" + . "%s\n", + $year+1900, $mon+1, $mday, $hour, $min, $author); + } + else { + if ($Show_Times) { + $header_line = + sprintf ("%4u-%02u-%02u${wday} %02u:%02u %s\n\n", + $year+1900, $mon+1, $mday, $hour, $min, $author); + } else { + $header_line = + sprintf ("%4u-%02u-%02u${wday} %s\n\n", + $year+1900, $mon+1, $mday, $author); + } + } + + $Text::Wrap::huge = 'overflow' + if $Text::Wrap::VERSION >= 2001.0130; + # Reshape the body according to user preferences. + if ($XML_Output) + { + $msg = &preprocess_msg_text ($msg); + $body = $files . $msg; + } + elsif ($No_Wrap && !$Summary) + { + $msg = &preprocess_msg_text ($msg); + $files = wrap ("\t", "\t", "* $files"); + $msg =~ s/\n(.+)/\n\t$1/g; + unless ($After_Header eq " ") { + $msg =~ s/^(.+)/\t$1/g; + } + $body = $files . $After_Header . $msg; + } + elsif ($Summary) + { + my( $filelist, $qunk ); + my( @DeletedQunks, @AddedQunks, @ChangedQunks ); + + $msg = &preprocess_msg_text ($msg); + # + # Sort the files (qunks) according to the operation that was + # performed. Files which were added have no line change + # indicator, whereas deleted files have state dead. + # + foreach $qunk ( @$qunklist ) + { + if ( "dead" eq $qunk->{'state'}) + { + push( @DeletedQunks, $qunk ); + } + elsif ( !exists( $qunk->{'lines'})) + { + push( @AddedQunks, $qunk ); + } + else + { + push( @ChangedQunks, $qunk ); + } + } + # + # The qunks list was originally in tree search order. Let's + # get that back. The lists, if they exist, will be reversed upon + # processing. + # + + # + # Now write the three sections onto $filelist + # + if ( @DeletedQunks ) + { + $filelist .= "\tDeleted:\n"; + foreach $qunk ( @DeletedQunks ) + { + $filelist .= "\t\t" . $qunk->{'filename'}; + $filelist .= " (" . $qunk->{'revision'} . ")"; + $filelist .= "\n"; + } + undef( @DeletedQunks ); + } + if ( @AddedQunks ) + { + $filelist .= "\tAdded:\n"; + foreach $qunk ( @AddedQunks ) + { + $filelist .= "\t\t" . $qunk->{'filename'}; + $filelist .= " (" . $qunk->{'revision'} . ")"; + $filelist .= "\n"; + } + undef( @AddedQunks ); + } + if ( @ChangedQunks ) + { + $filelist .= "\tChanged:\n"; + foreach $qunk ( @ChangedQunks ) + { + $filelist .= "\t\t" . $qunk->{'filename'}; + $filelist .= " (" . $qunk->{'revision'} . ")"; + $filelist .= ", \"" . $qunk->{'state'} . "\""; + $filelist .= ", lines: " . $qunk->{'lines'}; + $filelist .= "\n"; + } + undef( @ChangedQunks ); + } + chomp( $filelist ); + $msg =~ s/\n(.*)/\n\t$1/g; + unless ($After_Header eq " ") { + $msg =~ s/^(.*)/\t$1/g; + } + $body = $filelist . $After_Header . $msg; + } + else # do wrapping, either FSF-style or regular + { + if ($FSF_Style) + { + $files = wrap ("\t", "\t", "* $files"); + + my $files_last_line_len = 0; + if ($After_Header eq " ") + { + $files_last_line_len = &last_line_len ($files); + $files_last_line_len += 1; # for $After_Header + } + + $msg = &wrap_log_entry + ($msg, "\t", 69 - $files_last_line_len, 69); + $body = $files . $After_Header . $msg; + } + else # not FSF-style + { + $msg = &preprocess_msg_text ($msg); + $body = $files . $After_Header . $msg; + $body = wrap ("\t", "\t ", "* $body"); + $body =~ s/[ \t]+\n/\n/g; + } + } + + $body =~ s/[ \t]+\n/\n/g; + $wholething = $header_line . $body; + + if ($XML_Output) { + $wholething = "\n${wholething}\n"; + } + + # One last check: make sure it passes the regexp test, if the + # user asked for that. We have to do it here, so that the + # test can match against information in the header as well + # as in the text of the log message. + + # How annoying to duplicate so much code just because I + # can't figure out a way to evaluate scalars on the trailing + # operator portion of a regular expression. Grrr. + if ($Case_Insensitive) { + unless ($Regexp_Gate && ($wholething !~ /$Regexp_Gate/oi)) { + print LOG_OUT "${wholething}\n"; + } + } + else { + unless ($Regexp_Gate && ($wholething !~ /$Regexp_Gate/o)) { + print LOG_OUT "${wholething}\n"; + } + } + } + } + } + + if ($XML_Output) { + print LOG_OUT "\n"; + } + + close (LOG_OUT); + + if (! $Output_To_Stdout) + { + # If accumulating, append old data to new before renaming. But + # don't append the most recent entry, since it's already in the + # new log due to CVS's idiosyncratic interpretation of "log -d". + if ($Cumulative && -f $logfile_here) + { + open (NEW_LOG, ">>$tmpfile") + or die "trouble appending to $tmpfile ($!)"; + + open (OLD_LOG, "<$logfile_here") + or die "trouble reading from $logfile_here ($!)"; + + my $started_first_entry = 0; + my $passed_first_entry = 0; + while () + { + if (! $passed_first_entry) + { + if ((! $started_first_entry) + && /^(\d\d\d\d-\d\d-\d\d\s+\d\d:\d\d)/) { + $started_first_entry = 1; + } + elsif (/^(\d\d\d\d-\d\d-\d\d\s+\d\d:\d\d)/) { + $passed_first_entry = 1; + print NEW_LOG $_; + } + } + else { + print NEW_LOG $_; + } + } + + close (NEW_LOG); + close (OLD_LOG); + } + + if (-f $logfile_here) { + rename ($logfile_here, $logfile_bak); + } + rename ($tmpfile, $logfile_here); + } + } +} + +sub parse_date_author_and_state () +{ + # Parses the date/time and author out of a line like: + # + # date: 1999/02/19 23:29:05; author: apharris; state: Exp; + + my $line = shift; + + my ($year, $mon, $mday, $hours, $min, $secs, $author, $state, $rest) = + $line =~ + m#(\d+)/(\d+)/(\d+)\s+(\d+):(\d+):(\d+);\s+author:\s+([^;]+);\s+state:\s+([^;]+);(.*)# + or die "Couldn't parse date ``$line''"; + die "Bad date or Y2K issues" unless ($year > 1969 and $year < 2258); + # Kinda arbitrary, but useful as a sanity check + my $time = timegm($secs,$min,$hours,$mday,$mon-1,$year-1900); + my $lines; + if ( $rest =~ m#\s+lines:\s+(.*)# ) + { + $lines =$1; + } + return ($time, $author, $state, $lines); +} + +# Here we take a bunch of qunks and convert them into printed +# summary that will include all the information the user asked for. +sub pretty_file_list () +{ + if ($Hide_Filenames and (! $XML_Output)) { + return ""; + } + + my $qunksref = shift; + + my @qunkrefs = + grep +((! exists $_->{'tags'} or + ! grep exists $ignore_tags{$_}, @{$_->{'tags'}}) and + (! keys %show_tags or + (exists $_->{'tags'} and + grep exists $show_tags{$_}, @{$_->{'tags'}})) + ), + @$qunksref; + my @filenames; + my $beauty = ""; # The accumulating header string for this entry. + my %non_unanimous_tags; # Tags found in a proper subset of qunks + my %unanimous_tags; # Tags found in all qunks + my %all_branches; # Branches found in any qunk + my $common_dir = undef; # Dir prefix common to all files ("" if none) + my $fbegun = 0; # Did we begin printing filenames yet? + + # First, loop over the qunks gathering all the tag/branch names. + # We'll put them all in non_unanimous_tags, and take out the + # unanimous ones later. + QUNKREF: + foreach my $qunkref (@qunkrefs) + { + # Keep track of whether all the files in this commit were in the + # same directory, and memorize it if so. We can make the output a + # little more compact by mentioning the directory only once. + if ($Common_Dir && (scalar (@qunkrefs)) > 1) + { + if (! (defined ($common_dir))) + { + my ($base, $dir); + ($base, $dir, undef) = fileparse ($$qunkref{'filename'}); + + if ((! (defined ($dir))) # this first case is sheer paranoia + or ($dir eq "") + or ($dir eq "./") + or ($dir eq ".\\")) + { + $common_dir = ""; + } + else + { + $common_dir = $dir; + } + } + elsif ($common_dir ne "") + { + # Already have a common dir prefix, so how much of it can we preserve? + $common_dir = &common_path_prefix ($$qunkref{'filename'}, $common_dir); + } + } + else # only one file in this entry anyway, so common dir not an issue + { + $common_dir = ""; + } + + if (defined ($$qunkref{'branch'})) { + $all_branches{$$qunkref{'branch'}} = 1; + } + if (defined ($$qunkref{'tags'})) { + foreach my $tag (@{$$qunkref{'tags'}}) { + $non_unanimous_tags{$tag} = 1; + } + } + } + + # Any tag held by all qunks will be printed specially... but only if + # there are multiple qunks in the first place! + if ((scalar (@qunkrefs)) > 1) { + foreach my $tag (keys (%non_unanimous_tags)) { + my $everyone_has_this_tag = 1; + foreach my $qunkref (@qunkrefs) { + if ((! (defined ($$qunkref{'tags'}))) + or (! (grep ($_ eq $tag, @{$$qunkref{'tags'}})))) { + $everyone_has_this_tag = 0; + } + } + if ($everyone_has_this_tag) { + $unanimous_tags{$tag} = 1; + delete $non_unanimous_tags{$tag}; + } + } + } + + if ($XML_Output) + { + # If outputting XML, then our task is pretty simple, because we + # don't have to detect common dir, common tags, branch prefixing, + # etc. We just output exactly what we have, and don't worry about + # redundancy or readability. + + foreach my $qunkref (@qunkrefs) + { + my $filename = $$qunkref{'filename'}; + my $cvsstate = $$qunkref{'cvsstate'}; + my $revision = $$qunkref{'revision'}; + my $tags = $$qunkref{'tags'}; + my $branch = $$qunkref{'branch'}; + my $branchroots = $$qunkref{'branchroots'}; + + $filename = &xml_escape ($filename); # probably paranoia + $revision = &xml_escape ($revision); # definitely paranoia + + $beauty .= "\n"; + $beauty .= "${filename}\n"; + $beauty .= "${cvsstate}\n"; + $beauty .= "${revision}\n"; + if ($branch) { + $branch = &xml_escape ($branch); # more paranoia + $beauty .= "${branch}\n"; + } + foreach my $tag (@$tags) { + $tag = &xml_escape ($tag); # by now you're used to the paranoia + $beauty .= "${tag}\n"; + } + foreach my $root (@$branchroots) { + $root = &xml_escape ($root); # which is good, because it will continue + $beauty .= "${root}\n"; + } + $beauty .= "\n"; + } + + # Theoretically, we could go home now. But as long as we're here, + # let's print out the common_dir and utags, as a convenience to + # the receiver (after all, earlier code calculated that stuff + # anyway, so we might as well take advantage of it). + + if ((scalar (keys (%unanimous_tags))) > 1) { + foreach my $utag ((keys (%unanimous_tags))) { + $utag = &xml_escape ($utag); # the usual paranoia + $beauty .= "${utag}\n"; + } + } + if ($common_dir) { + $common_dir = &xml_escape ($common_dir); + $beauty .= "${common_dir}\n"; + } + + # That's enough for XML, time to go home: + return $beauty; + } + + # Else not XML output, so complexly compactify for chordate + # consumption. At this point we have enough global information + # about all the qunks to organize them non-redundantly for output. + + if ($common_dir) { + # Note that $common_dir still has its trailing slash + $beauty .= "$common_dir: "; + } + + if ($Show_Branches) + { + # For trailing revision numbers. + my @brevisions; + + foreach my $branch (keys (%all_branches)) + { + foreach my $qunkref (@qunkrefs) + { + if ((defined ($$qunkref{'branch'})) + and ($$qunkref{'branch'} eq $branch)) + { + if ($fbegun) { + # kff todo: comma-delimited in XML too? Sure. + $beauty .= ", "; + } + else { + $fbegun = 1; + } + my $fname = substr ($$qunkref{'filename'}, length ($common_dir)); + $beauty .= $fname; + $$qunkref{'printed'} = 1; # Just setting a mark bit, basically + + if ($Show_Tags && (defined @{$$qunkref{'tags'}})) { + my @tags = grep ($non_unanimous_tags{$_}, @{$$qunkref{'tags'}}); + + if (@tags) { + $beauty .= " (tags: "; + $beauty .= join (', ', @tags); + $beauty .= ")"; + } + } + + if ($Show_Revisions) { + # Collect the revision numbers' last components, but don't + # print them -- they'll get printed with the branch name + # later. + $$qunkref{'revision'} =~ /.+\.([\d]+)$/; + push (@brevisions, $1); + + # todo: we're still collecting branch roots, but we're not + # showing them anywhere. If we do show them, it would be + # nifty to just call them revision "0" on a the branch. + # Yeah, that's the ticket. + } + } + } + $beauty .= " ($branch"; + if (@brevisions) { + if ((scalar (@brevisions)) > 1) { + $beauty .= ".["; + $beauty .= (join (',', @brevisions)); + $beauty .= "]"; + } + else { + # Square brackets are spurious here, since there's no range to + # encapsulate + $beauty .= ".$brevisions[0]"; + } + } + $beauty .= ")"; + } + } + + # Okay; any qunks that were done according to branch are taken care + # of, and marked as printed. Now print everyone else. + + my %fileinfo_printed; + foreach my $qunkref (@qunkrefs) + { + next if (defined ($$qunkref{'printed'})); # skip if already printed + + my $b = substr ($$qunkref{'filename'}, length ($common_dir)); + # todo: Shlomo's change was this: + # $beauty .= substr ($$qunkref{'filename'}, + # (($common_dir eq "./") ? "" : length ($common_dir))); + $$qunkref{'printed'} = 1; # Set a mark bit. + + if ($Show_Revisions || $Show_Tags || $Show_Dead) + { + my $started_addendum = 0; + + if ($Show_Revisions) { + $started_addendum = 1; + $b .= " ("; + $b .= "$$qunkref{'revision'}"; + } + if ($Show_Dead && $$qunkref{'cvsstate'} =~ /dead/) + { + # Deliberately not using $started_addendum. Keeping it simple. + $b .= "[DEAD]"; + } + if ($Show_Tags && (defined $$qunkref{'tags'})) { + my @tags = grep ($non_unanimous_tags{$_}, @{$$qunkref{'tags'}}); + if ((scalar (@tags)) > 0) { + if ($started_addendum) { + $b .= ", "; + } + else { + $b .= " (tags: "; + } + $b .= join (', ', @tags); + $started_addendum = 1; + } + } + if ($started_addendum) { + $b .= ")"; + } + } + + unless ( exists $fileinfo_printed{$b} ) { + if ($fbegun) { + $beauty .= ", "; + } else { + $fbegun = 1; + } + $beauty .= $b, $fileinfo_printed{$b} = 1; + } + } + + # Unanimous tags always come last. + if ($Show_Tags && %unanimous_tags) + { + $beauty .= " (utags: "; + $beauty .= join (', ', sort keys (%unanimous_tags)); + $beauty .= ")"; + } + + # todo: still have to take care of branch_roots? + + $beauty = "$beauty:"; + + return $beauty; +} + +sub min ($$) { $_[0] < $_[1] ? $_[0] : $_[1] } + +sub common_path_prefix ($$) +{ + my ($path1, $path2) = @_; + + # For compatibility (with older versions of cvs2cl.pl), we think in UN*X + # terms, and mould windoze filenames to match. Is this really appropriate? + # If a file is checked in under UN*X, and cvs log run on windoze, which way + # do the path separators slope? Can we use fileparse as per the local + # conventions? If so, we should probably have a user option to specify an + # OS to emulate to handle stdin-fed logs. If we did this, we could avoid + # the nasty \-/ transmogrification below. + + my ($dir1, $dir2) = map +(fileparse($_))[1], $path1, $path2; + + # Transmogrify Windows filenames to look like Unix. + # (It is far more likely that someone is running cvs2cl.pl under + # Windows than that they would genuinely have backslashes in their + # filenames.) + tr!\\!/! + for $dir1, $dir2; + + my ($accum1, $accum2, $last_common_prefix) = ('') x 3; + + my @path1 = grep length($_), split qr!/!, $dir1; + my @path2 = grep length($_), split qr!/!, $dir2; + + my @common_path; + for (0..min($#path1,$#path2)) { + if ( $path1[$_] eq $path2[$_]) { + push @common_path, $path1[$_]; + } else { + last; + } + } + + return join '', map "$_/", @common_path; +} + +sub preprocess_msg_text () +{ + my $text = shift; + + # Strip out carriage returns (as they probably result from DOSsy editors). + $text =~ s/\r\n/\n/g; + + # If it *looks* like two newlines, make it *be* two newlines: + $text =~ s/\n\s*\n/\n\n/g; + + if ($XML_Output) + { + $text = &xml_escape ($text); + $text = "${text}\n"; + } + elsif (! $No_Wrap) + { + # Strip off lone newlines, but only for lines that don't begin with + # whitespace or a mail-quoting character, since we want to preserve + # that kind of formatting. Also don't strip newlines that follow a + # period; we handle those specially next. And don't strip + # newlines that precede an open paren. + 1 while ($text =~ s/(^|\n)([^>\s].*[^.\n])\n([^>\n])/$1$2 $3/g); + + # If a newline follows a period, make sure that when we bring up the + # bottom sentence, it begins with two spaces. + 1 while ($text =~ s/(^|\n)([^>\s].*)\n([^>\n])/$1$2 $3/g); + } + + return $text; +} + +sub last_line_len () +{ + my $files_list = shift; + my @lines = split (/\n/, $files_list); + my $last_line = pop (@lines); + return length ($last_line); +} + +# A custom wrap function, sensitive to some common constructs used in +# log entries. +sub wrap_log_entry () +{ + my $text = shift; # The text to wrap. + my $left_pad_str = shift; # String to pad with on the left. + + # These do NOT take left_pad_str into account: + my $length_remaining = shift; # Amount left on current line. + my $max_line_length = shift; # Amount left for a blank line. + + my $wrapped_text = ""; # The accumulating wrapped entry. + my $user_indent = ""; # Inherited user_indent from prev line. + + my $first_time = 1; # First iteration of the loop? + my $suppress_line_start_match = 0; # Set to disable line start checks. + + my @lines = split (/\n/, $text); + while (@lines) # Don't use `foreach' here, it won't work. + { + my $this_line = shift (@lines); + chomp $this_line; + + if ($this_line =~ /^(\s+)/) { + $user_indent = $1; + } + else { + $user_indent = ""; + } + + # If it matches any of the line-start regexps, print a newline now... + if ($suppress_line_start_match) + { + $suppress_line_start_match = 0; + } + elsif (($this_line =~ /^(\s*)\*\s+[a-zA-Z0-9]/) + || ($this_line =~ /^(\s*)\* [a-zA-Z0-9_\.\/\+-]+/) + || ($this_line =~ /^(\s*)\([a-zA-Z0-9_\.\/\+-]+(\)|,\s*)/) + || ($this_line =~ /^(\s+)(\S+)/) + || ($this_line =~ /^(\s*)- +/) + || ($this_line =~ /^()\s*$/) + || ($this_line =~ /^(\s*)\*\) +/) + || ($this_line =~ /^(\s*)[a-zA-Z0-9](\)|\.|\:) +/)) + { + # Make a line break immediately, unless header separator is set + # and this line is the first line in the entry, in which case + # we're getting the blank line for free already and shouldn't + # add an extra one. + unless (($After_Header ne " ") and ($first_time)) + { + if ($this_line =~ /^()\s*$/) { + $suppress_line_start_match = 1; + $wrapped_text .= "\n${left_pad_str}"; + } + + $wrapped_text .= "\n${left_pad_str}"; + } + + $length_remaining = $max_line_length - (length ($user_indent)); + } + + # Now that any user_indent has been preserved, strip off leading + # whitespace, so up-folding has no ugly side-effects. + $this_line =~ s/^\s*//; + + # Accumulate the line, and adjust parameters for next line. + my $this_len = length ($this_line); + if ($this_len == 0) + { + # Blank lines should cancel any user_indent level. + $user_indent = ""; + $length_remaining = $max_line_length; + } + elsif ($this_len >= $length_remaining) # Line too long, try breaking it. + { + # Walk backwards from the end. At first acceptable spot, break + # a new line. + my $idx = $length_remaining - 1; + if ($idx < 0) { $idx = 0 }; + while ($idx > 0) + { + if (substr ($this_line, $idx, 1) =~ /\s/) + { + my $line_now = substr ($this_line, 0, $idx); + my $next_line = substr ($this_line, $idx); + $this_line = $line_now; + + # Clean whitespace off the end. + chomp $this_line; + + # The current line is ready to be printed. + $this_line .= "\n${left_pad_str}"; + + # Make sure the next line is allowed full room. + $length_remaining = $max_line_length - (length ($user_indent)); + + # Strip next_line, but then preserve any user_indent. + $next_line =~ s/^\s*//; + + # Sneak a peek at the user_indent of the upcoming line, so + # $next_line (which will now precede it) can inherit that + # indent level. Otherwise, use whatever user_indent level + # we currently have, which might be none. + my $next_next_line = shift (@lines); + if ((defined ($next_next_line)) && ($next_next_line =~ /^(\s+)/)) { + $next_line = $1 . $next_line if (defined ($1)); + # $length_remaining = $max_line_length - (length ($1)); + $next_next_line =~ s/^\s*//; + } + else { + $next_line = $user_indent . $next_line; + } + if (defined ($next_next_line)) { + unshift (@lines, $next_next_line); + } + unshift (@lines, $next_line); + + # Our new next line might, coincidentally, begin with one of + # the line-start regexps, so we temporarily turn off + # sensitivity to that until we're past the line. + $suppress_line_start_match = 1; + + last; + } + else + { + $idx--; + } + } + + if ($idx == 0) + { + # We bottomed out because the line is longer than the + # available space. But that could be because the space is + # small, or because the line is longer than even the maximum + # possible space. Handle both cases below. + + if ($length_remaining == ($max_line_length - (length ($user_indent)))) + { + # The line is simply too long -- there is no hope of ever + # breaking it nicely, so just insert it verbatim, with + # appropriate padding. + $this_line = "\n${left_pad_str}${this_line}"; + } + else + { + # Can't break it here, but may be able to on the next round... + unshift (@lines, $this_line); + $length_remaining = $max_line_length - (length ($user_indent)); + $this_line = "\n${left_pad_str}"; + } + } + } + else # $this_len < $length_remaining, so tack on what we can. + { + # Leave a note for the next iteration. + $length_remaining = $length_remaining - $this_len; + + if ($this_line =~ /\.$/) + { + $this_line .= " "; + $length_remaining -= 2; + } + else # not a sentence end + { + $this_line .= " "; + $length_remaining -= 1; + } + } + + # Unconditionally indicate that loop has run at least once. + $first_time = 0; + + $wrapped_text .= "${user_indent}${this_line}"; + } + + # One last bit of padding. + $wrapped_text .= "\n"; + + return $wrapped_text; +} + +sub xml_escape () +{ + my $txt = shift; + $txt =~ s/&/&/g; + $txt =~ s//>/g; + return $txt; +} + +sub maybe_read_user_map_file () +{ + my %expansions; + + if ($User_Map_File) + { + open (MAPFILE, "<$User_Map_File") + or die ("Unable to open $User_Map_File ($!)"); + + while () + { + next if /^\s*#/; # Skip comment lines. + next if not /:/; # Skip lines without colons. + + # It is now safe to split on ':'. + my ($username, $expansion) = split ':'; + chomp $expansion; + $expansion =~ s/^'(.*)'$/$1/; + $expansion =~ s/^"(.*)"$/$1/; + + # If it looks like the expansion has a real name already, then + # we toss the username we got from CVS log. Otherwise, keep + # it to use in combination with the email address. + + if ($expansion =~ /^\s*<{0,1}\S+@.*/) { + # Also, add angle brackets if none present + if (! ($expansion =~ /<\S+@\S+>/)) { + $expansions{$username} = "$username <$expansion>"; + } + else { + $expansions{$username} = "$username $expansion"; + } + } + else { + $expansions{$username} = $expansion; + } + } # fi ($User_Map_File) + + close (MAPFILE); + } + + if (defined $User_Passwd_File) + { + if ( ! defined $Domain ) { + if ( -e MAILNAME ) { + chomp($Domain = slurp_file(MAILNAME)); + } else { + MAILDOMAIN_CMD: + for ([qw(hostname -d)], 'dnsdomainname', 'domainname') { + my ($text, $exit, $sig, $core) = run_ext($_); + if ( $exit == 0 && $sig == 0 && $core == 0 ) { + chomp $text; + if ( length $text ) { + $Domain = $text; + last MAILDOMAIN_CMD; + } + } + } + } + } + + die "No mail domain found\n" + unless defined $Domain; + + open (MAPFILE, "<$User_Passwd_File") + or die ("Unable to open $User_Passwd_File ($!)"); + while () + { + # all lines are valid + my ($username, $pw, $uid, $gid, $gecos, $homedir, $shell) = split ':'; + my $expansion = ''; + ($expansion) = split (',', $gecos) + if defined $gecos && length $gecos; + + my $mailname = $Domain eq '' ? $username : "$username\@$Domain"; + $expansions{$username} = "$expansion <$mailname>"; + } + close (MAPFILE); + } + + return %expansions; +} + +sub parse_options () +{ + # Check this internally before setting the global variable. + my $output_file; + + # If this gets set, we encountered unknown options and will exit at + # the end of this subroutine. + my $exit_with_admonishment = 0; + + my (@Global_Opts, @Local_Opts); + + while (my $arg = shift (@ARGV)) + { + if ($arg =~ /^-h$|^-help$|^--help$|^--usage$|^-?$/) { + $Print_Usage = 1; + } + elsif ($arg =~ /^--delta$/) { + my $narg = shift(@ARGV) || die "$arg needs argument.\n"; + if ($narg =~ /^([A-Za-z][A-Za-z0-9_\-]*):([A-Za-z][A-Za-z0-9_\-]*)$/) { + $Delta_From = $1; + $Delta_To = $2; + $Delta_Mode = 1; + } else { + die "--delta FROM_TAG:TO_TAG is what you meant to say.\n"; + } + } + elsif ($arg =~ /^--debug$/) { # unadvertised option, heh + $Debug = 1; + } + elsif ($arg =~ /^--version$/) { + $Print_Version = 1; + } + elsif ($arg =~ /^-g$|^--global-opts$/) { + my $narg = shift (@ARGV) || die "$arg needs argument.\n"; + # Don't assume CVS is called "cvs" on the user's system: + push @Global_Opts, $narg; + $Log_Source_Command =~ s/(^\S*)/$1 $narg/; + } + elsif ($arg =~ /^-l$|^--log-opts$/) { + my $narg = shift (@ARGV) || die "$arg needs argument.\n"; + push @Local_Opts, $narg; + $Log_Source_Command .= " $narg"; + } + elsif ($arg =~ /^-f$|^--file$/) { + my $narg = shift (@ARGV) || die "$arg needs argument.\n"; + $output_file = $narg; + } + elsif ($arg =~ /^--accum$/) { + $Cumulative = 1; + } + elsif ($arg =~ /^--update$/) { + $Update = 1; + } + elsif ($arg =~ /^--fsf$/) { + $FSF_Style = 1; + } + elsif ($arg =~ /^--FSF$/) { + $Show_Times = 0; + $Common_Dir = 0; + } + elsif ($arg =~ /^--rcs/) { + my $narg = shift (@ARGV) || die "$arg needs argument.\n"; + $RCS_Root = $narg; + $RCS_Mode = 1; + } + elsif ($arg =~ /^-U$|^--usermap$/) { + my $narg = shift (@ARGV) || die "$arg needs argument.\n"; + $User_Map_File = $narg; + } + elsif ($arg =~ /^--gecos$/) { + $Gecos = 1; + } + elsif ($arg =~ /^--domain$/) { + my $narg = shift (@ARGV) || die "$arg needs argument.\n"; + $Domain = $narg; + } + elsif ($arg =~ /^--passwd$/) { + my $narg = shift (@ARGV) || die "$arg needs argument.\n"; + $User_Passwd_File = $narg; + } + elsif ($arg =~ /^--mailname$/) { + my $narg = shift (@ARGV) || die "$arg needs argument.\n"; + warn "--mailname is deprecated; please use --domain instead\n"; + $Domain = $narg; + } + elsif ($arg =~ /^-W$|^--window$/) { + defined(my $narg = shift (@ARGV)) || die "$arg needs argument.\n"; + $Max_Checkin_Duration = $narg; + } + elsif ($arg =~ /^--chrono$/) { + $Chronological_Order = 1; + } + elsif ($arg =~ /^-I$|^--ignore$/) { + my $narg = shift (@ARGV) || die "$arg needs argument.\n"; + push (@Ignore_Files, $narg); + } + elsif ($arg =~ /^-C$|^--case-insensitive$/) { + $Case_Insensitive = 1; + } + elsif ($arg =~ /^-R$|^--regexp$/) { + my $narg = shift (@ARGV) || die "$arg needs argument.\n"; + $Regexp_Gate = $narg; + } + elsif ($arg =~ /^--stdout$/) { + $Output_To_Stdout = 1; + } + elsif ($arg =~ /^--version$/) { + $Print_Version = 1; + } + elsif ($arg =~ /^-d$|^--distributed$/) { + $Distributed = 1; + } + elsif ($arg =~ /^-P$|^--prune$/) { + $Prune_Empty_Msgs = 1; + } + elsif ($arg =~ /^-S$|^--separate-header$/) { + $After_Header = "\n\n"; + } + elsif ($arg =~ /^--no-wrap$/) { + $No_Wrap = 1; + } + elsif ($arg =~ /^--summary$/) { + $Summary = 1; + $After_Header = "\n\n"; # Summary implies --separate-header + } + elsif ($arg =~ /^--gmt$|^--utc$/) { + $UTC_Times = 1; + } + elsif ($arg =~ /^-w$|^--day-of-week$/) { + $Show_Day_Of_Week = 1; + } + elsif ($arg =~ /^--no-times$/) { + $Show_Times = 0; + } + elsif ($arg =~ /^-r$|^--revisions$/) { + $Show_Revisions = 1; + } + elsif ($arg =~ /^--show-dead$/) { + $Show_Dead = 1; + } + elsif ($arg =~ /^--no-hide-branch-additions$/) { + $Hide_Branch_Additions = 0; + } + elsif ($arg =~ /^-t$|^--tags$/) { + $Show_Tags = 1; + } + elsif ($arg =~ /^-T$|^--tagdates$/) { + $Show_Tag_Dates = 1; + } + elsif ($arg =~ /^-b$|^--branches$/) { + $Show_Branches = 1; + } + elsif ($arg =~ /^-F$|^--follow$/) { + my $narg = shift (@ARGV) || die "$arg needs argument.\n"; + push (@Follow_Branches, $narg); + } + elsif ($arg =~ /^--stdin$/) { + $Input_From_Stdin = 1; + } + elsif ($arg =~ /^--header$/) { + my $narg = shift (@ARGV) || die "$arg needs argument.\n"; + $ChangeLog_Header = &slurp_file ($narg); + if (! defined ($ChangeLog_Header)) { + $ChangeLog_Header = ""; + } + } + elsif ($arg =~ /^--xml-encoding$/) { + my $narg = shift (@ARGV) || die "$arg needs argument.\n"; + $XML_Encoding = $narg ; + } + elsif ($arg =~ /^--xml$/) { + $XML_Output = 1; + } + elsif ($arg =~ /^--hide-filenames$/) { + $Hide_Filenames = 1; + $After_Header = ""; + } + elsif ($arg =~ /^--no-common-dir$/) { + $Common_Dir = 0; + } + elsif ($arg =~ /^--ignore-tag$/ ) { + die "$arg needs argument.\n" + unless @ARGV; + $ignore_tags{shift @ARGV} = 1; + } + elsif ($arg =~ /^--show-tag$/ ) { + die "$arg needs argument.\n" + unless @ARGV; + $show_tags{shift @ARGV} = 1; + } + elsif ( lc ($arg) eq '--test-code' ) { + # Deliberately undocumented. This is not a public interface, + # and may change/disappear at any time. + die "$arg needs argument.\n" + unless @ARGV; + $TestCode = shift @ARGV; + } + elsif ($arg =~ /^--no-ancestors$/) { + $No_Ancestors = 1; + } + else { + # Just add a filename as argument to the log command + $Log_Source_Command .= " '$arg'"; + } + } + + ## Check for contradictions... + + if ($Output_To_Stdout && $Distributed) { + print STDERR "cannot pass both --stdout and --distributed\n"; + $exit_with_admonishment = 1; + } + + if ($Output_To_Stdout && $output_file) { + print STDERR "cannot pass both --stdout and --file\n"; + $exit_with_admonishment = 1; + } + + if ($Input_From_Stdin && @Global_Opts) { + print STDERR "cannot pass both --stdin and -g\n"; + $exit_with_admonishment = 1; + } + + if ($Input_From_Stdin && @Local_Opts) { + print STDERR "cannot pass both --stdin and -l\n"; + $exit_with_admonishment = 1; + } + + if ($XML_Output && $Cumulative) { + print STDERR "cannot pass both --xml and --accum\n"; + $exit_with_admonishment = 1; + } + + # Or if any other error message has already been printed out, we + # just leave now: + if ($exit_with_admonishment) { + &usage (); + exit (1); + } + elsif ($Print_Usage) { + &usage (); + exit (0); + } + elsif ($Print_Version) { + &version (); + exit (0); + } + + ## Else no problems, so proceed. + + if ($output_file) { + $Log_File_Name = $output_file; + } +} + +sub slurp_file () +{ + my $filename = shift || die ("no filename passed to slurp_file()"); + my $retstr; + + open (SLURPEE, "<${filename}") or die ("unable to open $filename ($!)"); + my $saved_sep = $/; + undef $/; + $retstr = ; + $/ = $saved_sep; + close (SLURPEE); + return $retstr; +} + +sub debug () +{ + if ($Debug) { + my $msg = shift; + print STDERR $msg; + } +} + +sub version () +{ + print "cvs2cl.pl version ${VERSION}; distributed under the GNU GPL.\n"; +} + +sub usage () +{ + &version (); + print <<'END_OF_INFO'; +Generate GNU-style ChangeLogs in CVS working copies. + +Notes about the output format(s): + + The default output of cvs2cl.pl is designed to be compact, formally + unambiguous, but still easy for humans to read. It is largely + self-explanatory, I hope; the one abbreviation that might not be + obvious is "utags". That stands for "universal tags" -- a + universal tag is one held by all the files in a given change entry. + + If you need output that's easy for a program to parse, use the + --xml option. Note that with XML output, just about all available + information is included with each change entry, whether you asked + for it or not, on the theory that your parser can ignore anything + it's not looking for. + +Notes about the options and arguments (the actual options are listed +last in this usage message): + + * The -I and -F options may appear multiple times. + + * To follow trunk revisions, use "-F trunk" ("-F TRUNK" also works). + This is okay because no would ever, ever be crazy enough to name a + branch "trunk", right? Right. + + * For the -U option, the UFILE should be formatted like + CVSROOT/users. That is, each line of UFILE looks like this + jrandom:jrandom@red-bean.com + or maybe even like this + jrandom:'Jesse Q. Random ' + Don't forget to quote the portion after the colon if necessary. + + * Many people want to filter by date. To do so, invoke cvs2cl.pl + like this: + cvs2cl.pl -l "-d'DATESPEC'" + where DATESPEC is any date specification valid for "cvs log -d". + (Note that CVS 1.10.7 and below requires there be no space between + -d and its argument). + +Options/Arguments: + + -h, -help, --help, or -? Show this usage and exit + --version Show version and exit + -r, --revisions Show revision numbers in output + -b, --branches Show branch names in revisions when possible + -t, --tags Show tags (symbolic names) in output + -T, --tagdates Show tags in output on their first occurance + --show-dead Show dead files + --stdin Read from stdin, don't run cvs log + --stdout Output to stdout not to ChangeLog + -d, --distributed Put ChangeLogs in subdirs + -f FILE, --file FILE Write to FILE instead of "ChangeLog" + --fsf Use this if log data is in FSF ChangeLog style + --FSF Attempt strict FSF-standard compatible output + -W SECS, --window SECS Window of time within which log entries unify + -U UFILE, --usermap UFILE Expand usernames to email addresses from UFILE + --passwd PASSWORDFILE Use system passwd file for user name expansion. + If no mail domain is provided (via --domain), + it tries to read one from /etc/mailname else + output of + hostname -d / dnsdomainname / domainname. Dies + if none successful. Use a domain of '' to + prevent the addition of a mail domain. + --domain DOMAIN Domain to build email addresses from + --gecos Get user information from GECOS data + -R REGEXP, --regexp REGEXP Include only entries that match REGEXP + -I REGEXP, --ignore REGEXP Ignore files whose names match REGEXP + -C, --case-insensitive Any regexp matching is done case-insensitively + -F BRANCH, --follow BRANCH Show only revisions on or ancestral to BRANCH + --no-ancestors When using -F, only track changes since the + BRANCH started + --no-hide-branch-additions By default, entries generated by cvs for a file + added on a branch (a dead 1.1 entry) are not + shown. This flag reverses that action. + -S, --separate-header Blank line between each header and log message + --summary Add CVS change summary information + --no-wrap Don't auto-wrap log message (recommend -S also) + --gmt, --utc Show times in GMT/UTC instead of local time + --accum Add to an existing ChangeLog (incompat w/ --xml) + --update As --accum, but lists only files changed since + last run + -w, --day-of-week Show day of week + --no-times Don't show times in output + --chrono Output log in chronological order + (default is reverse chronological order) + --header FILE Get ChangeLog header from FILE ("-" means stdin) + --xml Output XML instead of ChangeLog format + --xml-encoding ENCODING Insert encoding clause in XML header + --hide-filenames Don't show filenames (ignored for XML output) + --no-common-dir Don't shorten directory names from filenames. + --rcs CVSROOT Handle filenames from raw RCS, for instance + those produced by "cvs rlog" output, stripping + the prefix CVSROOT. + -P, --prune Don't show empty log messages + --ignore-tag TAG Ignore individual changes that are associated + with a given tag. May be repeated, if so, + changes that are associated with any of the + given tags are ignored. + --show-tag TAG Log only individual changes that are associated + with a given tag. May be repeated, if so, + changes that are associated with any of the + given tags are logged. + --delta FROM_TAG:TO_TAG Attempt a delta between two tags (since FROM_TAG + up to & including TO_TAG). The algorithm is a + simple date-based one (this is a *hard* problem) + so results are imperfect + -g OPTS, --global-opts OPTS Invoke like this "cvs OPTS log ..." + -l OPTS, --log-opts OPTS Invoke like this "cvs ... log OPTS" + FILE1 [FILE2 ...] Show only log information for the named FILE(s) + +See http://www.red-bean.com/cvs2cl for maintenance and bug info. +END_OF_INFO +} + +__END__ + +=head1 NAME + +cvs2cl.pl - produces GNU-style ChangeLogs in CVS working copies, by + running "cvs log" and parsing the output. Shared log entries are + unified in an intuitive way. + +=head1 DESCRIPTION + +This script generates GNU-style ChangeLog files from CVS log +information. Basic usage: just run it inside a working copy and a +ChangeLog will appear. It requires repository access (i.e., 'cvs log' +must work). Run "cvs2cl.pl --help" to see more advanced options. + +See http://www.red-bean.com/cvs2cl for updates, and for instructions +on getting anonymous CVS access to this script. + +Maintainer: Karl Fogel +Please report bugs to . + +=head1 README + +This script generates GNU-style ChangeLog files from CVS log +information. Basic usage: just run it inside a working copy and a +ChangeLog will appear. It requires repository access (i.e., 'cvs log' +must work). Run "cvs2cl.pl --help" to see more advanced options. + +See http://www.red-bean.com/cvs2cl for updates, and for instructions +on getting anonymous CVS access to this script. + +Maintainer: Karl Fogel +Please report bugs to . + +=head1 PREREQUISITES + +This script requires C, C, and +C. +It also seems to require C or higher. + +=pod OSNAMES + +any + +=pod SCRIPT CATEGORIES + +Version_Control/CVS + +=cut + +-*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- + +Note about a bug-slash-opportunity: +----------------------------------- + +There's a bug in Text::Wrap, which affects cvs2cl. This script +reveals it: + + #!/usr/bin/perl -w + + use Text::Wrap; + + my $test_text = + "This script demonstrates a bug in Text::Wrap. The very long line + following this paragraph will be relocated relative to the surrounding + text: + + ==================================================================== + + See? When the bug happens, we'll get the line of equal signs below + this paragraph, even though it should be above."; + + # Print out the test text with no wrapping: + print "$test_text"; + print "\n"; + print "\n"; + + # Now print it out wrapped, and see the bug: + print wrap ("\t", " ", "$test_text"); + print "\n"; + print "\n"; + +If the line of equal signs were one shorter, then the bug doesn't +happen. Interesting. + +Anyway, rather than fix this in Text::Wrap, we might as well write a +new wrap() which has the following much-needed features: + +* initial indentation, like current Text::Wrap() +* subsequent line indentation, like current Text::Wrap() +* user chooses among: force-break long words, leave them alone, or die()? +* preserve existing indentation: chopped chunks from an indented line + are indented by same (like this line, not counting the asterisk!) +* optional list of things to preserve on line starts, default ">" + +Note that the last two are essentially the same concept, so unify in +implementation and give a good interface to controlling them. + +And how about: + +Optionally, when encounter a line pre-indented by same as previous +line, then strip the newline and refill, but indent by the same. +Yeah... + diff --git a/AspectC++/tools/gpl b/AspectC++/tools/gpl new file mode 100755 index 0000000..40d83a8 --- /dev/null +++ b/AspectC++/tools/gpl @@ -0,0 +1,45 @@ +#!/bin/sh + +[ "$#" != "1" ] && \ +echo -e "Add/remove GPL header.\nusage: gpl (add|remove)" && \ +exit 1 + +if [ "$1" = "add" ]; then + echo "Adding GPL header to AspectC++ source files." + + FILES=`find . -maxdepth 1 \( -name "*.cc" -or -name "*.*h" \)` + + for file in $FILES; do + cat <> $file.t +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 + +EOF + cat $file >> $file.t + mv $file.t $file + done +else + echo "Removing GPL header from AspectC++ source files." + + FILES=`find . -maxdepth 1 \( -name "*.cc" -or -name "*.*h" \) \ + -exec grep -l "// This file is part of the AspectC++" \{} \;` + + for file in $FILES; do + ex -s "+d18" "+:x" $file + done +fi diff --git a/AspectC++/version.h b/AspectC++/version.h new file mode 100644 index 0000000..4fa6d3a --- /dev/null +++ b/AspectC++/version.h @@ -0,0 +1,51 @@ +// This file is part of the AspectC++ compiler 'ac++'. +// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org) +// +// 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 __version_h__ +#define __version_h__ + +#include "infos.h" + +static inline const char *ac_version() {return AC_VERSION;} +static inline const char *ac_program() {return "ac++";} + +// Version management helpers: +// Returns a version number that can be compared by using >, >=, ==, ... +#define GET_VERSION_NUMBER(MAJOR, MINOR, PATCHLEVEL) \ + MAJOR * 10000 \ + + MINOR * 100 \ + + PATCHLEVEL + +#ifdef FRONTEND_CLANG +// Clang version: +#include "clang/Basic/Version.h" +#define CLANG_VERSION_NUMBER GET_VERSION_NUMBER(CLANG_VERSION_MAJOR, \ + CLANG_VERSION_MINOR, \ + CLANG_VERSION_PATCHLEVEL) + +// Some version numbers: +#define VERSION_NUMBER_3_5_2 GET_VERSION_NUMBER(3, 5, 2) +#define VERSION_NUMBER_3_6_2 GET_VERSION_NUMBER(3, 6, 2) +#define VERSION_NUMBER_3_7_1 GET_VERSION_NUMBER(3, 7, 1) +#define VERSION_NUMBER_3_8_0 GET_VERSION_NUMBER(3, 8, 0) +#define VERSION_NUMBER_3_9_1 GET_VERSION_NUMBER(3, 9, 1) +#define VERSION_NUMBER_4_0_0 GET_VERSION_NUMBER(4, 0, 0) +#define VERSION_NUMBER_5_0_0 GET_VERSION_NUMBER(5, 0, 0) +#endif // FRONTEND_CLANG + +#endif // __version_h__ diff --git a/AspectC++/win-ac++.ico b/AspectC++/win-ac++.ico new file mode 100755 index 0000000..80b7e32 Binary files /dev/null and b/AspectC++/win-ac++.ico differ diff --git a/AspectC++/win-ac++.rc b/AspectC++/win-ac++.rc new file mode 100644 index 0000000..3e9fc5b --- /dev/null +++ b/AspectC++/win-ac++.rc @@ -0,0 +1,41 @@ +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +#include "infos.h" + +1 ICON DISCARDABLE "win-ac++.ico" + +1 VERSIONINFO + FILEVERSION 1,0,0,4 + PRODUCTVERSION 1,0,0,4 + FILEFLAGSMASK 0x3fL + FILEFLAGS 0x0L + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040704b0" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", COMPANY_NAME + VALUE "FileDescription", "The AspectC++ Compiler\0" + VALUE "FileVersion", AC_VERSION + VALUE "InternalName", "ac++\0" + VALUE "LegalCopyright", COPYRIGHT + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "win-ac++.rc\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "ac++\0" + VALUE "ProductVersion", AC_VERSION + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x407, 1200 + END +END diff --git a/Puma/.cproject b/Puma/.cproject new file mode 100644 index 0000000..d493979 --- /dev/null +++ b/Puma/.cproject @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Puma/.project b/Puma/.project new file mode 100644 index 0000000..6ae2213 --- /dev/null +++ b/Puma/.project @@ -0,0 +1,27 @@ + + + Puma + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/Puma/COPYING b/Puma/COPYING new file mode 100644 index 0000000..3512f1c --- /dev/null +++ b/Puma/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/Puma/INSTALL b/Puma/INSTALL new file mode 100644 index 0000000..dbd649b --- /dev/null +++ b/Puma/INSTALL @@ -0,0 +1,87 @@ +Prerequisites +============= + +To be able to compile the PUMA library ensure that a suitable version +of the program `ac++' is installed and the environment variable AC is +set to the program location. You can download the newest version at +www.aspectc.org. + + +Basic Installation +================== + +The simplest way to build and install the PUMA library is to follow +these steps: + + 1. `cd' to the directory containing PUMA's source code. + + 2. Type `make' to compile the PUMA library. If `make' succeeds you + can find the library in the `lib' sub-directory and PUMA's headers + in the `include' sub-directory. + + If you want to compile PUMA for a non-default target platform, use: + 'make TARGET=' or 'make TARGET=-release' for a + "release build" (no debugging & optimization), e.g. + 'make TARGET=win32-release'. + + If you want to enable/disable parser extensions, use: + 'make EXTENSIONS=""'. The available extensions + are listed in extensions.mk. + + On multi-processor machines parallel weaving and compilation + will probably pay off. In order to run multiple build processes + in parallel add -j to the make command line. + + 3. Optionally, type `make examples' to compile any examples that + come along with PUMA. + + 4. Type `make install' to install the library and headers to + `/usr/local'. You may change the target directory by typing + `make install PREFIX=...'. + + 5. By typing `make clean' you can remove all the files created during + the make process except the files in the `lib', `include', and + `examples' sub-directories. To also remove these files, type + `make distclean'. + + +Generating the Visual C++ Project +================================= + +To compile the PUMA library on Win32 using Visual Studio 7.0 or higher +follow these steps: + + 1. `cd' to the directory containing PUMA's source code and type + `make cleanall'. + + 2. Type `export AC_OPTFLAGS="--no_line --problem_force_inline + --problem_local_class --no_problem_spec_scope"'. + + 3. Type `make weave EXTENSIONS="winext"' to generate the woven PUMA + source files for a Release build. + + Or type `make weave EXTENSIONS="winext tracing" TARGET=linux' to + generate the woven PUMA source files for a Debug build. + + The extensions are optional and can be omitted. + + 4. Type `bash ./tools/gen_vcpp_proj.sh release pack' to generate the + project file Puma.vcproj and the source package PumaVCProj.zip for + a Release build. + + Or type `bash ./tools/gen_vcpp_proj.sh debug pack' to generate the + project file Puma_d.vcproj and the source package PumaVCProj_d.zip + for a Debug build. + + +Compilers and Options +===================== + +The following special build targets are supported: + + * `weave' only builds the tools and applies the aspects coming along + with PUMA to the sources + + * `compile' only compiles the previously transformed sources + + * `libclean' only removes the object files and libraries diff --git a/Puma/Makefile b/Puma/Makefile new file mode 100644 index 0000000..d282673 --- /dev/null +++ b/Puma/Makefile @@ -0,0 +1,128 @@ +#------------------------------------------------- +# variables +#------------------------------------------------- + +ROOT ?= $(shell pwd) +TARGET ?= linux-release +AC ?= ac++ +PREFIX ?= /usr/local + +include vars.mk +include files.mk + +ifneq ($(MINI),) +LIBNAME := libMiniPuma +else +LIBNAME := libPuma +endif + +LIBDIR := $(ROOT)/lib/$(TARGET) +GENDIR := $(ROOT)/gen-$(RELEASE) + +INCDIR := $(ROOT)/include +EXTDIR := $(ROOT)/extern +OBJDIR := $(GENDIR)/obj-$(_TARGET) +STEP1 := $(GENDIR)/step1 +STEP2 := $(GENDIR)/step2 + +CONFIG := $(GENDIR)/puma.cfg +ACNEWREPO ?= $(GENDIR)/acpp.repo + +# exported variables +export GENDIR INCDIR EXTDIR LIBNAME LIBDIR OBJDIR STEP1 STEP2 +export ROOT TARGET AC DONTWEAVE CONFIG ACNEWREPO +export LEMSOURCES SOURCES CSOURCES ASPECTS + +# suppress reporting directory changes +MAKE := $(MAKE) --no-print-directory + +#------------------------------------------------- +# rules +#------------------------------------------------- + +all: showinfo src + +generate: showinfo src + +weave: showinfo src + +compile_after_weave: showinfo src + +compile: showinfo src + +dry: showinfo + @cd $(ROOT)/src && $(MAKE) $(MAKECMDGOALS) + +showinfo: + @echo + @echo "---" + @echo "Making PUMA for TARGET=$(TARGET)" + @echo " Extensions = $(EXTENSIONS)" + @echo "---" + @echo + +tools: + @cd $(ROOT)/tools && $(MAKE) + +src: tools + @cd $(ROOT)/src && $(MAKE) $(MAKECMDGOALS) + +examples: tools + @$(MAKE) -C $(ROOT)/src + @cd $(ROOT)/examples && $(MAKE) + +doc: + @echo "Generating Puma reference manual..." + @doxygen doc/RefMan/doxygen.conf && echo "=> see doc/RefMan/html/index.html" + +install: src + @echo "Installing library and headers..." + @mkdir -p $(PREFIX)/lib + @cp -pv $(LIBDIR)/$(LIBNAME).* $(PREFIX)/lib + @mkdir -p $(PREFIX)/include/Puma + @cp -pv $(INCDIR)/Puma/*.*h $(PREFIX)/include/Puma + +uninstall: + @echo "Uninstalling library and headers..." + @rm -fv $(PREFIX)/lib/$(LIBNAME).* + @rm -rfv $(PREFIX)/include/Puma + +clean: tools-clean + @cd $(ROOT)/src && $(MAKE) clean + +tools-clean: + @cd $(ROOT)/tools && $(MAKE) -s clean + +examples-clean: + @cd $(ROOT)/examples && $(MAKE) -s clean + +docs-clean: + @echo "Making docs clean..." + @rm -rf $(ROOT)/doc/RefMan/html + +cleanall: test-clean examples-clean tools-clean docs-clean + @echo "Making completely clean..." + @rm -rf $(ROOT)/lib + @rm -rf $(ROOT)/gen-* + +distclean: clean examples-clean docs-clean + @cd $(ROOT)/src && $(MAKE) distclean + +libclean: + @echo "Removing library and object files..." + @rm -f $(LIBDIR)/$(LIBNAME).* + @rm -rf $(OBJDIR) + @rm -rf $(STEP2)/dep + +test: test-all + +test-%: + @echo "Making tests $*..." + @$(MAKE) -C tests -s $* + +#------------------------------------------------- +# targets +#------------------------------------------------- + +.PHONY: all tools src install examples distclean cleanall \ +clean tools-clean examples-clean libclean weave compile uninstall doc diff --git a/Puma/README b/Puma/README new file mode 100644 index 0000000..f322e48 --- /dev/null +++ b/Puma/README @@ -0,0 +1,78 @@ +PUMA 1.0 - a library for parsing and manipulating C/C++ source code +Copyright (C) 1999-2008 The PUMA developer team. + +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. + + +Roadmap +======= + + * The COPYING file contains a copy of the GPL described above. + + * See INSTALL for installation details. + + * ChangeLog describes the changes between the versions of the PUMA + library. + + * Some documentation is located in the `doc' directory. + + * Examples of how to use PUMA can be found in the `examples' + directory. + + * `src' and `tools' contain all the stuff to build the library. + + * In the `lib' directory you will find the PUMA library after + building it. The corresponding header files will be placed in + the `include' directory. + + +Description +=========== + +PUMA is a library of C++ classes for parsing and manipulating C/C++ +source code. It provides different levels of analyzing source code, +i.e. lexical, syntactical, and semantical analyses. Additionally, +PUMA contains its own C preprocessor following the macro language +understood by the GNU C preprocessor (cpp). + The parsers for C and C++ are based on an extensible recursive +descent parser architecture that can be easily adapted for your own +needs by inheriting from one of the parsers. They are oriented on +the ISO/IEC standards defined in ISO/IEC 9899:1999(E) and ISO/IEC +14882:1998(E) but also supporting a list of extensions to the C and +C++ languages. The information about the source code being analyzed +is organized in an attributed syntax tree referring to a separate +structure of semantic information. + For the purpose of manipulating source code PUMA provides a syntax +based mechanism for searching code structures. Manipulations on the +source code can be collected and validated before executing them in a +single transaction. + + +Limitations +=========== + +This version of PUMA is distributed under the terms of the GPL. + +There is also a commercial edition of the PUMA library available, which +may be used to develop commercial/proprietary software. For pricing and +availability of the commercial edition, please contact pure-systems GmbH +at contact@pure-systems.com. + + +Contact +======= + +If you want any information about the AspectC++ project or have any +comments, feel free to contact the development team via info@aspectc.org. diff --git a/Puma/TODO b/Puma/TODO new file mode 100644 index 0000000..c2f2a6a --- /dev/null +++ b/Puma/TODO @@ -0,0 +1,144 @@ +TODO +==== + +General +------- + +* documentation +* parse way optimization +* implement member access control +* improve expression evaluation +* improve template support +* RTTI support +* better management of different targets for size and alignment of types +* shared type objects => faster type comparison, less memory consumption... +* GNU C/C++ extensions: + - generalized lvalues => less restrictive isLvalue() + - introduce variable name after initializer instead of before + + +Preprocessor +------------ +- change macro expansion scheme to fit the standard, e.g. + --- + #define hash_hash # ## # + #define mkstr(a) # a + #define in_between(a) mkstr(a) + #define join(c, d) in_between(c hash_hash d) + join(x, y); + --- + should result in `"x ## y"' not in `" xy "' +- GNU extensions, e.g. + --- + #define FILE(x) + #include FILE(bar.h) + --- + results in `#include ' but GNU's cpp produces + `#include ' + + +GNU Parser Extensions +--------------------- + +1. Thread-Local Storage +storage-class __thread + +2. more built-in functions for C/C++ + +3. C/C++ offsetof +Calculation of real offset is not yet implemented. +Currently always returns 0. + +4. __alignof__, with same syntax as for sizeof +Calculation of real alignment is not yet implemented. +Currently always returns 1. + +5. Getting the Return or Frame Address of a Function +void * __builtin_return_address (unsigned int level); +void * __builtin_frame_address (unsigned int level); + +6. Function Names as Strings +static const char __func__[] = "function-name"; +__FUNCTION__ = __func__ +__PRETTY_FUNCTION__ = void a::sub(int) + +7. Case Ranges +switch (1) { + case 1 ... 9: break; +} + +8. Cast to a Union Type +union foo { int i; double d; }; +int x; +double y; +union foo u; +u = (union foo) x; +u = (union foo) y; + +9. Designated Initializers +int whitespace[256] + = { [' '] = 1, ['\t'] = 1, ['\h'] = 1, + ['\f'] = 1, ['\n'] = 1, ['\r'] = 1 }; +struct point ptarray[10] = { [2].y = yv2, [2].x = xv2, [0].x = xv0 }; + +10. Compound Literals +structure = ((struct foo) {x + y, 'a', 0}); + +11. C: Non-Constant Initializers +void foo (float f, float g) { + float beat_freqs[2] = { f-g, f+g }; +} + +12. Arithmetic on void- and Function-Pointers +In GNU C, addition and subtraction operations are supported on pointers to void and on +pointers to functions. This is done by treating the size of a void or of a function as 1. +A consequence of this is that sizeof is also allowed on void and on function types, and +returns 1. + +13. Non-Lvalue Arrays May Have Subscripts +struct foo {int a[4];}; +struct foo f(); +bar (int index){ + return f().a[index]; +} + +14. Slightly Looser Rules for Escaped Newlines +Recently, the preprocessor has relaxed its treatment of escaped newlines. Previously, +the newline had to immediately follow a backslash. The current implementation allows +whitespace in the form of spaces, horizontal and vertical tabs, and form feeds between +the backslash and the subsequent newline. + +15. Arrays of Variable Length, or Zero, in C/C++ + +16. Complex Numbers + +17. Conditionals with Omitted Operands +x ? : y + +18. Referring to a Type with typeof + +19. Constructing Function Calls (done) +void * __builtin_apply_args () +void * __builtin_apply (void (*function)(), void *arguments, size_t size) +void __builtin_return (void *result) + +20. Nested Functions +foo (double a, double b) { + double square (double z) { return z * z; } + return square (a) + square (b); +} + +21. Labels as Values +void *ptr; +ptr = &&foo; +goto *ptr; + +22. C: Statements and Declarations in Expressions +({ int y = foo (); int z; + if (y > 0) z = y; + else z = - y; + z; }) + +23. Locally Declared Labels +__label__ label; +__label__ label1, label2, /* ... */; diff --git a/Puma/doc/MindMaps/Puma-Parser.mm b/Puma/doc/MindMaps/Puma-Parser.mm new file mode 100644 index 0000000..d32d2e5 --- /dev/null +++ b/Puma/doc/MindMaps/Puma-Parser.mm @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Puma/doc/MindMaps/TemplatesParsen.mm b/Puma/doc/MindMaps/TemplatesParsen.mm new file mode 100644 index 0000000..2478b23 --- /dev/null +++ b/Puma/doc/MindMaps/TemplatesParsen.mm @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/Puma/doc/RefMan/doxygen.conf b/Puma/doc/RefMan/doxygen.conf new file mode 100644 index 0000000..79ffd60 --- /dev/null +++ b/Puma/doc/RefMan/doxygen.conf @@ -0,0 +1,2362 @@ +# Doxyfile 1.8.9.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all text +# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv +# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv +# for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = "PUMA Library Reference Manual" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. + +PROJECT_LOGO = doc/RefMan/logo.png + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = doc/RefMan + +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = NO + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding "class=itcl::class" +# will allow you to use the command class in the itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, Javascript, +# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: +# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: +# Fortran. In the later case the parser tries to guess whether the code is fixed +# or free formatted code, this is the default for Fortran type files), VHDL. For +# instance to make doxygen treat .inc files as Fortran files (default is PHP), +# and .f files as C (default is Fortran), use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. + +EXTENSION_MAPPING = h=C++ inc=C++ + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = YES + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = NO + +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# (class|struct|union) declarations. If set to NO, these declarations will be +# included in the documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES, upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. +# The default value is: system dependent. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = YES + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. + +GENERATE_TESTLIST = NO + +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = NO + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= NO + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = doc/RefMan/layout.xml + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong or incomplete +# parameter documentation, but not about the absence of documentation. +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. +# Note: If this tag is empty the current directory is searched. + +INPUT = src + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: http://www.gnu.org/software/libiconv) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank the +# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii, +# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, +# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, +# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, +# *.qsf, *.as and *.js. + +FILE_PATTERNS = *.h *.inc + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = src/win32 + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# function all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see http://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the config file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# http://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to NO can help when comparing the output of multiple runs. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = NO + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = YES + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: http://developer.apple.com/tools/xcode/), introduced with +# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the master .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = YES + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- +# folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = YES + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 1 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# http://www.mathjax.org) which uses client side Javascript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from http://www.mathjax.org before deployment. +# The default value is: http://cdn.mathjax.org/mathjax/latest. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = http://www.mathjax.org/mathjax + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /> +>> endobj +1442 0 obj << +/D [1440 0 R /XYZ 123.806 735.519 null] +>> endobj +14 0 obj << +/D [1440 0 R /XYZ 123.806 710.612 null] +>> endobj +18 0 obj << +/D [1440 0 R /XYZ 123.806 685.811 null] +>> endobj +1443 0 obj << +/D [1440 0 R /XYZ 123.806 584.459 null] +>> endobj +1444 0 obj << +/D [1440 0 R /XYZ 123.806 584.578 null] +>> endobj +22 0 obj << +/D [1440 0 R /XYZ 123.806 539.04 null] +>> endobj +1446 0 obj << +/D [1440 0 R /XYZ 123.806 454.184 null] +>> endobj +1448 0 obj << +/D [1440 0 R /XYZ 123.806 427.532 null] +>> endobj +1449 0 obj << +/D [1440 0 R /XYZ 123.806 400.992 null] +>> endobj +1439 0 obj << +/Font << /F45 1109 0 R /F43 1107 0 R /F44 1108 0 R /F82 1445 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1452 0 obj << +/Length 1418 +/Filter /FlateDecode +>> +stream +xڭXn8}WaPE}H$l łDXYr%i~ɒ#'r(R䐜shf+< x x"GJy+C]^g'qRΩ7_yc%,EB,/> B1>̃ޝ~Cm"Ca_o2)ZUV|}FdGb= {KX{aR=˵*1xν4AF^ + +f=;Ō8B<ؗU@;(כ,W}Řɻڞ8t"tG$F1qiQիgp0BF#\y^Yqg߀`4R3YP{e\1I Dhb/y>X8ߨvCns +(I,_o4mg~1՛R֨(IvsnN2І]RzbiY\?ݩ,kU4b:P?b.U*h朇VioXuV U310s!tP\4=e KSAeǏ̊cir,mx:sPФ;y%eHw^Cwވo1?q{ɶNr!G}HJimYߥ ]HcDH2Ĺ0B88oŝe'k4&+ڴQe:mTdOW @"_1 +ݍXKy{.d:'fo???T'J1$e7q0,S˶.<}Gt]v"me*ܛo+ÓʣY= !SeVA>)s7\gZ4C)ޔ%*^KMk\MN x+G$7#mY:P~Z;G^A\B|>( +endstream +endobj +1451 0 obj << +/Type /Page +/Contents 1452 0 R +/Resources 1450 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1438 0 R +>> endobj +1453 0 obj << +/D [1451 0 R /XYZ 81.963 735.519 null] +>> endobj +1454 0 obj << +/D [1451 0 R /XYZ 81.963 623.854 null] +>> endobj +1450 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F82 1445 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1457 0 obj << +/Length 774 +/Filter /FlateDecode +>> +stream +xڭU]O0}ϯxY"Tؓ0PAC2Mb߈pEUJTTdӫٗW`SBǗr>6eʴ^ IpnTƙjld,9 j c*dpŜ +Jk%:Ja:d{D㉆*v[_{骪:sEvdp; +r!$]ϙ#zIR[X1 K? +endstream +endobj +1456 0 obj << +/Type /Page +/Contents 1457 0 R +/Resources 1455 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1438 0 R +>> endobj +1458 0 obj << +/D [1456 0 R /XYZ 123.806 735.519 null] +>> endobj +26 0 obj << +/D [1456 0 R /XYZ 123.806 710.612 null] +>> endobj +1459 0 obj << +/D [1456 0 R /XYZ 123.806 485.625 null] +>> endobj +1460 0 obj << +/D [1456 0 R /XYZ 123.806 488.213 null] +>> endobj +1455 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1463 0 obj << +/Length 1204 +/Filter /FlateDecode +>> +stream +xڵVmo6_& C"EeIvM ES#H:_X`-"GQψG;C"'1$1$2BBsF Jqys$A ,Rkfc~@ !BNoc+|:?^{ᇈJCm椫2~7~9j"-i59Зx8f4ArpwO l,ٹD 9G^1)vĂ{I֋|U.CV a A8#w +T/ӥWi + ºO͍ n^b1X"pؾOW7LYOV )򕛛o"O1g[ ݀jgR~uzӧSUJe1[ ͦ,-ye0 c\.5kzpPEػ] M[ +3ro'>ZƽݹZT]UףE F -͎ǣrZ˴ͦ!dh.FAD\[U64c]`|qa M ϓ ^For^ݝ~ݾOy$P.<GFV$3Gt|qb2ZG!kc9x 9ޜ#zy=&L3]t+mlыG~hxw30Z/w6  +! +endstream +endobj +1462 0 obj << +/Type /Page +/Contents 1463 0 R +/Resources 1461 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1438 0 R +>> endobj +1464 0 obj << +/D [1462 0 R /XYZ 81.963 735.519 null] +>> endobj +30 0 obj << +/D [1462 0 R /XYZ 81.963 710.612 null] +>> endobj +34 0 obj << +/D [1462 0 R /XYZ 81.963 682.789 null] +>> endobj +1465 0 obj << +/D [1462 0 R /XYZ 81.963 600.856 null] +>> endobj +1466 0 obj << +/D [1462 0 R /XYZ 81.963 603.444 null] +>> endobj +1467 0 obj << +/D [1462 0 R /XYZ 81.963 531.128 null] +>> endobj +1468 0 obj << +/D [1462 0 R /XYZ 81.963 533.716 null] +>> endobj +38 0 obj << +/D [1462 0 R /XYZ 81.963 489.998 null] +>> endobj +1469 0 obj << +/D [1462 0 R /XYZ 81.963 409.245 null] +>> endobj +1470 0 obj << +/D [1462 0 R /XYZ 81.963 411.833 null] +>> endobj +42 0 obj << +/D [1462 0 R /XYZ 81.963 368.115 null] +>> endobj +1471 0 obj << +/D [1462 0 R /XYZ 81.963 231.733 null] +>> endobj +1472 0 obj << +/D [1462 0 R /XYZ 81.963 219.778 null] +>> endobj +1461 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1475 0 obj << +/Length 1078 +/Filter /FlateDecode +>> +stream +x͗mo6W؇IȐaeNb<)PtŠHNTQ"JM A`=wGO[!b8B a?| 9؀?X/bzqrĀ3 1 v(.$cam2Qy)\1Q5}~~r:/Zh%F{16W'Eb\/-H0DI  29]Tb>\/&^FA޸0>j70^͍x 1sSI^2u]f&pvI*\HqpEF)QNы! P@yyz2 :&& \巹#ZIz̹w sPL[?uNY-Ŷc.b\ &XxiW?2Q;.C.bqP%A8p r~AMRhf9|]Ia,@~*d"œE,80!":rS\XPGIO^2y  <.ƒJm 7{~(FlI~,,ܘ_w!tQVE'՘)J}vT`UׯV[}ͭE[&ť%L[/t+("oe+^!?$VJff?$_<)t]U"R^r)r4q7TޗKTzJʙ!o*Vo~O-P\ԟNN_1쯂j?9FΞ#Bٳ'[u授ߓ~`򴄧?\$Эd/̗. mj#fmîPP78;wus ̪$!UT.Yt&}Zl{kD\Owg4}rAKUf: B7v< mWEq+ǕЦsjs0T@5Z-&xx7z85nwY:-`^yh=8FKv0ipVWl5|&N:aD4ne@w< uRd?BH4Z\/'P +endstream +endobj +1474 0 obj << +/Type /Page +/Contents 1475 0 R +/Resources 1473 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1438 0 R +>> endobj +1476 0 obj << +/D [1474 0 R /XYZ 123.806 735.519 null] +>> endobj +1477 0 obj << +/D [1474 0 R /XYZ 123.806 551.382 null] +>> endobj +1478 0 obj << +/D [1474 0 R /XYZ 123.806 539.427 null] +>> endobj +1479 0 obj << +/D [1474 0 R /XYZ 123.806 314.073 null] +>> endobj +1480 0 obj << +/D [1474 0 R /XYZ 123.806 230.683 null] +>> endobj +1481 0 obj << +/D [1474 0 R /XYZ 123.806 218.727 null] +>> endobj +1473 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F82 1445 0 R /F43 1107 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1484 0 obj << +/Length 1194 +/Filter /FlateDecode +>> +stream +xڵ[o8+D386WZ6̶jv(80MmB*2MDUC;w41+#50\SߠQ(15`xWO BPຖ1mvh}'6I0Ç/W#rpr}!7F;gcy|]qح򽇒#0¤1 ~HY&`#>5͓sÆ\džub^)I5%}8P乾$3YZyXsiC< V" &<Vi$xʫF4=L |"]M*fXCZ#BjRQ juAR4fqJbҊ/;c˼8,/YhW+sܥJZ0 (c%RCO,=PL)i}/El> XH;VƷYr1#>׮blͪ"\M}'j?J8xR&ۀF<)NVH勬*_b^Hd:n5f8*jO;v݇w. +.!PAp9mEOMW (Z%V&BѶ=½c*3iy%^e[V)_>YP˰m؞)[hԷX̒x-@-gffϬ6WE'>{t{k)1dPs]2\2e5/vB5$T+}*ӲztݭF OU$c>ަd<";z&ǑQG}"^S&׏ٝEsFO]um,>EOa# ,ZۺFB% z#.r,PO!ov0(LS`qz{(BvYrXj!ۡǠ%0zcKI;b(&Z9/䨔0*L6iփ׭Tmyb5X{] 3Y$Y복!H'''07*q i)H/iJ.TMw@5 +endstream +endobj +1483 0 obj << +/Type /Page +/Contents 1484 0 R +/Resources 1482 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1496 0 R +>> endobj +1485 0 obj << +/D [1483 0 R /XYZ 81.963 735.519 null] +>> endobj +1486 0 obj << +/D [1483 0 R /XYZ 81.963 518.157 null] +>> endobj +1487 0 obj << +/D [1483 0 R /XYZ 81.963 506.202 null] +>> endobj +46 0 obj << +/D [1483 0 R /XYZ 81.963 312.936 null] +>> endobj +1488 0 obj << +/D [1483 0 R /XYZ 81.963 231.179 null] +>> endobj +1489 0 obj << +/D [1483 0 R /XYZ 81.963 233.767 null] +>> endobj +1490 0 obj << +/D [1483 0 R /XYZ 81.963 218.186 null] +>> endobj +1491 0 obj << +/D [1483 0 R /XYZ 81.963 202.604 null] +>> endobj +1492 0 obj << +/D [1483 0 R /XYZ 81.963 149.399 null] +>> endobj +1493 0 obj << +/D [1483 0 R /XYZ 81.963 151.987 null] +>> endobj +1495 0 obj << +/D [1483 0 R /XYZ 81.963 136.405 null] +>> endobj +1482 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F82 1445 0 R /F43 1107 0 R /F86 1494 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1499 0 obj << +/Length 1021 +/Filter /FlateDecode +>> +stream +xڵWmo6_!$&wQ]^k+5ش#@V=Tm ԑ:>w`~"MJ\*T: 0Lxpz!Ӏ +A< !e)kBXqKin1Vyi +^-m>ߜ^p*Zy3׺!"iº@6HL>`oX۩g/`%^.&SREbvsLI6`l&V +I|gQ,!EnvordPr/^N{||fZ43]YR\Aex}iSWy(S@BvRl)A[3(>/3tӶAڗx))udJfUDThY4-*Mn^fS𯈈P[ WӮ]Ǧ\bqarcH$ sVi&,gy2XڕfK7 ޒ^6Pŷ5c2ߜ /.&?'sK;g_ Uld2yށoL/u:: .I?G1%;? A$#`'a;zUS4,ӦqSv?yz=}G`M̍sΉFk)(^*#6Ui▸17$^]@Tj%π50337Ve>aWb/+7ͥ)W>Yc>wlwe?>љi Ԋp)zm29Ӷk)#ͫeW@إDn}Vp\bW\rm;yz;|}6y>#Ny?y +d- Wh|jde; x d$/^j \xћQzl_b 0V$A);5z^W|yIO0ȺL/ӗ(CwlP=8ԥx)3$I +endstream +endobj +1498 0 obj << +/Type /Page +/Contents 1499 0 R +/Resources 1497 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1496 0 R +>> endobj +1500 0 obj << +/D [1498 0 R /XYZ 123.806 735.519 null] +>> endobj +1501 0 obj << +/D [1498 0 R /XYZ 123.806 714.238 null] +>> endobj +1502 0 obj << +/D [1498 0 R /XYZ 123.806 698.657 null] +>> endobj +1503 0 obj << +/D [1498 0 R /XYZ 123.806 683.075 null] +>> endobj +1504 0 obj << +/D [1498 0 R /XYZ 123.806 667.494 null] +>> endobj +1505 0 obj << +/D [1498 0 R /XYZ 123.806 595.177 null] +>> endobj +1506 0 obj << +/D [1498 0 R /XYZ 123.806 597.766 null] +>> endobj +1507 0 obj << +/D [1498 0 R /XYZ 123.806 582.184 null] +>> endobj +1508 0 obj << +/D [1498 0 R /XYZ 123.806 566.603 null] +>> endobj +1509 0 obj << +/D [1498 0 R /XYZ 123.806 477.674 null] +>> endobj +1510 0 obj << +/D [1498 0 R /XYZ 123.806 480.262 null] +>> endobj +1511 0 obj << +/D [1498 0 R /XYZ 123.806 464.68 null] +>> endobj +1512 0 obj << +/D [1498 0 R /XYZ 123.806 449.099 null] +>> endobj +1513 0 obj << +/D [1498 0 R /XYZ 123.806 433.517 null] +>> endobj +1514 0 obj << +/D [1498 0 R /XYZ 123.806 417.936 null] +>> endobj +1497 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F82 1445 0 R /F86 1494 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1517 0 obj << +/Length 252 +/Filter /FlateDecode +>> +stream +x]Oo0 =4I?Mu'ġZ Bj+BKMc(8~wCppyްDcs{x*,d`VPjp:H?tj&&|bL^ϫźHwruPKeM\0߮]5>.!eN.U;Xy)N:x';qW쓓pewulcC dt&3ED;XX +endstream +endobj +1516 0 obj << +/Type /Page +/Contents 1517 0 R +/Resources 1515 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1496 0 R +>> endobj +1518 0 obj << +/D [1516 0 R /XYZ 81.963 735.519 null] +>> endobj +50 0 obj << +/D [1516 0 R /XYZ 81.963 710.612 null] +>> endobj +1515 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1521 0 obj << +/Length 229 +/Filter /FlateDecode +>> +stream +x]OMo0 WC=;:iCBDwB*(PB+  4R1 z%u:e8 ֘j(:{lյo*c78ןm4. :\g%' l}.Rb$.Gͳ6 dEM۝Nj 8-+ab5w +]7av'|Ta<+3KZK +endstream +endobj +1520 0 obj << +/Type /Page +/Contents 1521 0 R +/Resources 1519 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1496 0 R +>> endobj +1522 0 obj << +/D [1520 0 R /XYZ 123.806 735.519 null] +>> endobj +54 0 obj << +/D [1520 0 R /XYZ 123.806 710.612 null] +>> endobj +1519 0 obj << +/Font << /F45 1109 0 R /F43 1107 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1525 0 obj << +/Length 261 +/Filter /FlateDecode +>> +stream +x]j@)EŖ"^EHwL(aY?w%% +"Do 6K3z|L&ӧP|b5[U!H,녞/M9lv.%J!,KY_%Ĭ'zgQvl[J| >Ep\C.F\W^jE cuܱ-~nj-dZ z[bL\[ +endstream +endobj +1524 0 obj << +/Type /Page +/Contents 1525 0 R +/Resources 1523 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1496 0 R +>> endobj +1526 0 obj << +/D [1524 0 R /XYZ 81.963 735.519 null] +>> endobj +58 0 obj << +/D [1524 0 R /XYZ 81.963 710.612 null] +>> endobj +1523 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1529 0 obj << +/Length 234 +/Filter /FlateDecode +>> +stream +x]Mk@+[әݝV +-'4JwMPgdgH9ĀW_ cn^k"T-X[eUyrfa{z*Ua?u0o9/ :\e%' mgVk&7`r)wb$.,#vWRJʙ0s=ۉoa?lwg%߶cVq`eRR~MI +endstream +endobj +1528 0 obj << +/Type /Page +/Contents 1529 0 R +/Resources 1527 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1496 0 R +>> endobj +1530 0 obj << +/D [1528 0 R /XYZ 123.806 735.519 null] +>> endobj +62 0 obj << +/D [1528 0 R /XYZ 123.806 710.612 null] +>> endobj +1527 0 obj << +/Font << /F45 1109 0 R /F43 1107 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1533 0 obj << +/Length 264 +/Filter /FlateDecode +>> +stream +x]Kk@)!cqLR%顈I@S)Ėj@G9(8AoH2sXR"| }eT""ϧl],Tlhs{=_ɶXNfnBY J/nu!!5_{ 6-؉ɁACBm[ +<| xq 9AƺtBI276xaɍ l?_ȶc7<8=d0Zt)yTt~]% +endstream +endobj +1532 0 obj << +/Type /Page +/Contents 1533 0 R +/Resources 1531 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1535 0 R +>> endobj +1534 0 obj << +/D [1532 0 R /XYZ 81.963 735.519 null] +>> endobj +66 0 obj << +/D [1532 0 R /XYZ 81.963 710.612 null] +>> endobj +1531 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1538 0 obj << +/Length 239 +/Filter /FlateDecode +>> +stream +x]Mk0 >Dl׍Pl,;’AdenC+BWU|#P1b < lC3f u-R2s~= XΈe_̾ުZ_.3u(A>B^Fp)xW[6Ѳ3U5A +MD[jq=C=ȫ\ lP-6[*HO +endstream +endobj +1537 0 obj << +/Type /Page +/Contents 1538 0 R +/Resources 1536 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1535 0 R +>> endobj +1539 0 obj << +/D [1537 0 R /XYZ 123.806 735.519 null] +>> endobj +70 0 obj << +/D [1537 0 R /XYZ 123.806 710.612 null] +>> endobj +1536 0 obj << +/Font << /F45 1109 0 R /F43 1107 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1542 0 obj << +/Length 800 +/Filter /FlateDecode +>> +stream +xڭVO0~_aiKډ84it-6^nLIslMSj>=P|x`N 8&, +7#AgQSC4_#8BIb-+tS(!ĿΦ/ip3?? a 2U 8,˭57{KWs- #Tߝg"9;MpH9;'NyrZ:WRٜ ]N \m1s+[h aT2eӨfg У3=*dfKml߶fMA2v$g"<~E)e]cye47Epv*MRӠjckq`lke=jgj(ࡼ5*&Jndko1-,8VR+\9hcjKܖ0[O‰vS^`K[+h@ͰγV2o g1̸H:)'QUPa)f%W7jK--cFZMs<`QRuK몰D!&nڦ}Op.IGp=}万ܿ^K~G,1a'4>ͤv0躺#\vIhTC~vêvںC]s8Jà:`LY_P.]qq1q(@sҴ>d+i# Rn;;CaVBCg +QCBc? ~Ԏ& +endstream +endobj +1541 0 obj << +/Type /Page +/Contents 1542 0 R +/Resources 1540 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1535 0 R +>> endobj +1543 0 obj << +/D [1541 0 R /XYZ 81.963 735.519 null] +>> endobj +74 0 obj << +/D [1541 0 R /XYZ 81.963 710.612 null] +>> endobj +78 0 obj << +/D [1541 0 R /XYZ 81.963 685.437 null] +>> endobj +82 0 obj << +/D [1541 0 R /XYZ 81.963 646.237 null] +>> endobj +86 0 obj << +/D [1541 0 R /XYZ 81.963 616.522 null] +>> endobj +90 0 obj << +/D [1541 0 R /XYZ 81.963 480.793 null] +>> endobj +94 0 obj << +/D [1541 0 R /XYZ 81.963 364.121 null] +>> endobj +98 0 obj << +/D [1541 0 R /XYZ 81.963 230.837 null] +>> endobj +1540 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1546 0 obj << +/Length 688 +/Filter /FlateDecode +>> +stream +xڭMo0 +K=(O RCIZ99nl_]mi*43_c `msH%X&$\ ㄃V`;2) BP\BJp $KQB#Fc IQIː *yu쌋]}$n+֙_SPykY$ep(@ k +;x0bi5`v/+ʶ#eib!˶K_z7'5A(y7Ϋma[$n?h7@o1`WM[gl47Un͡n lqn +ա02ljٹ!&MHδt].- c\;(0aNT.qjs_n42]x#oMdFJ[?fs#,x"i/Qp^rz)MӖzmCX Nvc۞\MUt~*ot;*3XavѾ0O<Iӿjhm|X"uO7ϐgw>I "#^1AkgGxBl=k< BlOhl[#TGEӣ&#)hOIchB'L9Odk +endstream +endobj +1545 0 obj << +/Type /Page +/Contents 1546 0 R +/Resources 1544 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1535 0 R +>> endobj +1547 0 obj << +/D [1545 0 R /XYZ 123.806 735.519 null] +>> endobj +102 0 obj << +/D [1545 0 R /XYZ 123.806 710.612 null] +>> endobj +106 0 obj << +/D [1545 0 R /XYZ 123.806 596.866 null] +>> endobj +110 0 obj << +/D [1545 0 R /XYZ 123.806 475.217 null] +>> endobj +1544 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1550 0 obj << +/Length 1853 +/Filter /FlateDecode +>> +stream +xڍXmo6_!d&3CRDk6Hh5Y KL͖\$%WɆ u<;;';}LXǞaC6ޭ F>yusrv%,QJz7exq0 X +ιכgWZ3 ۦT1 ߥenPɷaՊ"aYhrnT0ƻ>9?%E*aIӫ)22f~7(iLe a‰Fzή[rBp'$秢6] +#6_əHhZV5-ytv-}٦if|4Y*&tD:np4;ԢgKlگMmZ"VGVFb𑞖f"[ u;XuuYRH-;+Q~bLhM[wYՆ^,|8Vtͮ59v+GI[e6t+!Va L( +!Fp[\eN.cDM],BqՖg$i?E-6iK]V ؀j +DVmwU W 8yW]Z72@ .C0KT_x҆ʑr+ Ht[cw5"y_fb(f1nӖiCChDÀL:-@p|X { ع_V8EU3^$/[ӮnCѮM_^WUK/]T1"uBw + -$}-r(z_-.EUp϶#G0̡h89KF[ꄉ(B[1e,W_dGL縮Iy:HRB "lG vSr( 9P+í@!=YCS\K$v%\+W+phˌ q,ckOJk$g$,4Ou :)`XL a,.jlӒL3bm/ +Yi( r˚j"3ap8w]Ӷ!|6fK +iI +NM xW0䎽nX?(let 'yDPt`mB{xPٙ..$%)$ø"z x`i+G(rp.-ޱBoK{YF۪'tVV0 +`gD7tf=}aϟ󋛿^eZ/s<&1&Scٲ ь Iw>mzDdXMn_0o4܆oQʝܙ .Oخ )A00+eθ{t;LTa_YEy,d=E+7d{bDoZj6v A+0ɸ9xx@/5F֬"J_>#B',_=t$/4T(Jƨ #uSߚa)qF/Lf]26-9 Dt# FQ)GθI%\:e} Od]<<`_փfzr)h?~^HO"d F\=qVtu"|vtm"7A +rcߋ^bZ6քYA>ǹW]q4?15spAޥe)!n. ɸ_)PCVd´v(. tu +endstream +endobj +1549 0 obj << +/Type /Page +/Contents 1550 0 R +/Resources 1548 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1535 0 R +>> endobj +1551 0 obj << +/D [1549 0 R /XYZ 81.963 735.519 null] +>> endobj +114 0 obj << +/D [1549 0 R /XYZ 81.963 710.612 null] +>> endobj +118 0 obj << +/D [1549 0 R /XYZ 81.963 689.042 null] +>> endobj +1552 0 obj << +/D [1549 0 R /XYZ 81.963 275.824 null] +>> endobj +1553 0 obj << +/D [1549 0 R /XYZ 81.963 278.412 null] +>> endobj +1548 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1556 0 obj << +/Length 675 +/Filter /FlateDecode +>> +stream +xU]k0}a6Ŋ-C(tT5sVr:8dl+b{ѽzD{jDi%ItЧ#Ai.T(ũ e+Dǚ(δD7!%F1%$$n_8 1l^fW !֘)o73m$eǼUgc@Iѽ%4E:%h W`jsFøB mI[+icِz5R6#JBSoc0gs=ԛ.QK{6π0|gΔY58Se}[< wjwo~589[FL?"*CWY{}~\0 P γNR$h=c2& $q(·ҵiҺsigw\C8K ?“N$f2 b$ڈ2˲rW`~T~ô=`f?0bzQ⊶,z{ԮuM$l*\7SKV͟:|ҔX@{Ң1I*-G{l~ ?7M{񚕿k ]Hϫ'N~fjh-q*w9G X ^Q$Բ(T@By9]-> +endstream +endobj +1555 0 obj << +/Type /Page +/Contents 1556 0 R +/Resources 1554 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1535 0 R +>> endobj +1557 0 obj << +/D [1555 0 R /XYZ 123.806 735.519 null] +>> endobj +122 0 obj << +/D [1555 0 R /XYZ 123.806 710.612 null] +>> endobj +126 0 obj << +/D [1555 0 R /XYZ 123.806 613.479 null] +>> endobj +130 0 obj << +/D [1555 0 R /XYZ 123.806 508.298 null] +>> endobj +134 0 obj << +/D [1555 0 R /XYZ 123.806 386.505 null] +>> endobj +1554 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1560 0 obj << +/Length 816 +/Filter /FlateDecode +>> +stream +xVn@}W*o~)*T$Nd;;qTTZ*f39̱E9C "'ƒh@ifS@ AgS)(VJ2Tinwʡ(!Ĺ{GB6d`$.nc80}JdA> endobj +1561 0 obj << +/D [1559 0 R /XYZ 81.963 735.519 null] +>> endobj +138 0 obj << +/D [1559 0 R /XYZ 81.963 710.612 null] +>> endobj +142 0 obj << +/D [1559 0 R /XYZ 81.963 690.444 null] +>> endobj +146 0 obj << +/D [1559 0 R /XYZ 81.963 588.168 null] +>> endobj +150 0 obj << +/D [1559 0 R /XYZ 81.963 471.867 null] +>> endobj +1562 0 obj << +/D [1559 0 R /XYZ 81.963 350.794 null] +>> endobj +1563 0 obj << +/D [1559 0 R /XYZ 81.963 353.382 null] +>> endobj +154 0 obj << +/D [1559 0 R /XYZ 81.963 310.528 null] +>> endobj +1564 0 obj << +/D [1559 0 R /XYZ 81.963 175.071 null] +>> endobj +1565 0 obj << +/D [1559 0 R /XYZ 81.963 177.66 null] +>> endobj +1566 0 obj << +/D [1559 0 R /XYZ 81.963 162.078 null] +>> endobj +1567 0 obj << +/D [1559 0 R /XYZ 81.963 146.497 null] +>> endobj +1558 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1571 0 obj << +/Length 889 +/Filter /FlateDecode +>> +stream +xŖ]o6+I6ؽA֘v({(QhP; [uxt>^>G=}Y8}u9+lq2zb:_k-tPHp0+=05goib|qvfBdoͿ4i*u)bWUQ羚WJw @E=~Λ5ob4:yytquR PDfw+Az>צk&]ZId6m.mԧ\UdցWNtqI|Olu7rKy|1j_Ϯ +URQUQnY^6"+(bMfeYB'RZ^f[z-H#ږQ&[]k!± XOf7Ő[m@˚L"K]blqwnPXpШƒVDA;wPGJCoh=v奍t uh z0Ҵ59]#2S +fWpޒo&ggϏSxOf[*B7a~JB3%)1=Y'hؓs~DO1 Qz8#:=_#܈6;NO>/?0s:ͥÍ QAXs$-KbtWjzb?o'O p">^B%&6OBp _Dٓi!9}\,&xl^ YCˋM.)L<]>]1Kf E;JJ0=:I` VuI{7; +:J(C[Ux>CEMqK#X)z>([ +endstream +endobj +1570 0 obj << +/Type /Page +/Contents 1571 0 R +/Resources 1569 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1568 0 R +>> endobj +1572 0 obj << +/D [1570 0 R /XYZ 123.806 735.519 null] +>> endobj +158 0 obj << +/D [1570 0 R /XYZ 123.806 710.612 null] +>> endobj +1573 0 obj << +/D [1570 0 R /XYZ 123.806 578.181 null] +>> endobj +1574 0 obj << +/D [1570 0 R /XYZ 123.806 580.77 null] +>> endobj +1575 0 obj << +/D [1570 0 R /XYZ 123.806 565.188 null] +>> endobj +1576 0 obj << +/D [1570 0 R /XYZ 123.806 549.607 null] +>> endobj +1577 0 obj << +/D [1570 0 R /XYZ 123.806 534.025 null] +>> endobj +1578 0 obj << +/D [1570 0 R /XYZ 123.806 518.444 null] +>> endobj +162 0 obj << +/D [1570 0 R /XYZ 123.806 475.284 null] +>> endobj +1579 0 obj << +/D [1570 0 R /XYZ 123.806 337.256 null] +>> endobj +1580 0 obj << +/D [1570 0 R /XYZ 123.806 339.844 null] +>> endobj +1581 0 obj << +/D [1570 0 R /XYZ 123.806 324.263 null] +>> endobj +1582 0 obj << +/D [1570 0 R /XYZ 123.806 308.681 null] +>> endobj +166 0 obj << +/D [1570 0 R /XYZ 123.806 265.522 null] +>> endobj +1583 0 obj << +/D [1570 0 R /XYZ 123.806 144.106 null] +>> endobj +1584 0 obj << +/D [1570 0 R /XYZ 123.806 146.695 null] +>> endobj +1569 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1587 0 obj << +/Length 769 +/Filter /FlateDecode +>> +stream +xVj@}W,E락oSZإi(j$'Kvd {GDVThPΜsfuM\dG9C3+eR[IL'##'ۉ7iGSɔXjApcp4<~8wTZʵ妏7i\1*_J(Eo8=( VT#wvHkYr[zDࣔ8RL*:|-:]j FC1 +(/f&NPc7EI$gP8@(Uq=˓el=.+KUclQVhMP|p(|r拴NO$F:,ȸ ׇ6HxS҈ HrXjmxyNJ'iȠ UJ:{@IGFsТҎѫ$ +C ""}͓$eIäb-nӆmpCukM(񎲸/&8>8IÚeJS,[8eߑ06ĸx.MEMT)%`Uv͍hRPq)A +u +e)@( ?0Iɩj=Ey/EI<~PSս^ƘZrGn]nQOMk$ 4 +P߁F^D +Sn[B3m9_`.5S x +endstream +endobj +1586 0 obj << +/Type /Page +/Contents 1587 0 R +/Resources 1585 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1568 0 R +>> endobj +1588 0 obj << +/D [1586 0 R /XYZ 81.963 735.519 null] +>> endobj +170 0 obj << +/D [1586 0 R /XYZ 81.963 710.612 null] +>> endobj +1589 0 obj << +/D [1586 0 R /XYZ 81.963 582.394 null] +>> endobj +1590 0 obj << +/D [1586 0 R /XYZ 81.963 584.982 null] +>> endobj +174 0 obj << +/D [1586 0 R /XYZ 81.963 538.287 null] +>> endobj +1591 0 obj << +/D [1586 0 R /XYZ 81.963 386.69 null] +>> endobj +1592 0 obj << +/D [1586 0 R /XYZ 81.963 389.279 null] +>> endobj +1593 0 obj << +/D [1586 0 R /XYZ 81.963 373.697 null] +>> endobj +1594 0 obj << +/D [1586 0 R /XYZ 81.963 358.116 null] +>> endobj +178 0 obj << +/D [1586 0 R /XYZ 81.963 311.42 null] +>> endobj +1595 0 obj << +/D [1586 0 R /XYZ 81.963 176.437 null] +>> endobj +1596 0 obj << +/D [1586 0 R /XYZ 81.963 179.025 null] +>> endobj +1597 0 obj << +/D [1586 0 R /XYZ 81.963 163.443 null] +>> endobj +1598 0 obj << +/D [1586 0 R /XYZ 81.963 147.862 null] +>> endobj +1585 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1601 0 obj << +/Length 767 +/Filter /FlateDecode +>> +stream +xVn@}W*OvnZx JR!+qKiά/I(]3g!)-hneNi8Ŋ]=N^{"Z 6d($8n18o9`!<GGa$4F?Ur[ǡA`,2J @E/߯z2-Z]nzX&;jI;lJ7;t͘wi%i?g^dH۴AnrBbVeh d.g VHfd=pN|ptli\bZtY~UKrQrҌ H TtZ;j(|S3au"hNi'&G54 "k&[MTA +6FBooz(ɦljn{!~֩78(6onRŲvՅ_jboO@}Dn5ZҍӬΟf/q% nGG.~@U;V( v *5ihy BǍF 1M;/:_KP:n"Eu00zO[H";șN"c U2V;~< +endstream +endobj +1600 0 obj << +/Type /Page +/Contents 1601 0 R +/Resources 1599 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1568 0 R +>> endobj +1602 0 obj << +/D [1600 0 R /XYZ 123.806 735.519 null] +>> endobj +182 0 obj << +/D [1600 0 R /XYZ 123.806 710.612 null] +>> endobj +1603 0 obj << +/D [1600 0 R /XYZ 123.806 558.067 null] +>> endobj +1604 0 obj << +/D [1600 0 R /XYZ 123.806 560.656 null] +>> endobj +1605 0 obj << +/D [1600 0 R /XYZ 123.806 545.074 null] +>> endobj +1606 0 obj << +/D [1600 0 R /XYZ 123.806 529.493 null] +>> endobj +186 0 obj << +/D [1600 0 R /XYZ 123.806 479.943 null] +>> endobj +1607 0 obj << +/D [1600 0 R /XYZ 123.806 336.475 null] +>> endobj +1608 0 obj << +/D [1600 0 R /XYZ 123.806 339.063 null] +>> endobj +190 0 obj << +/D [1600 0 R /XYZ 123.806 289.514 null] +>> endobj +1609 0 obj << +/D [1600 0 R /XYZ 123.806 146.045 null] +>> endobj +1610 0 obj << +/D [1600 0 R /XYZ 123.806 148.633 null] +>> endobj +1599 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1613 0 obj << +/Length 738 +/Filter /FlateDecode +>> +stream +xՖKo0 v}"e[wX(akSQ^hwmىأ)"H S$%;#$ ?&T$HEFܑ)0tddZ8O$ҒXc,< gAt9> jGrc(WAis/k +COe`0 ۥ`d\\2)aTXC*srՃ_P +TPuYhU΋EQIH*i^͖}Xce8w޼˳۩tq;wGUŗMڶ. +\—FdPTmIݵ@%F-В_YN[_ϗZʻÓT7Jt%]Ԗ72llu?ag5iiI ăN`NJIA 9)A!ou\'oz[?]7{߀9ÿ3({`Ҹe qLۺo7ɏ8)7MO@R'@WΥ~"s)+jzaVLnM" xT7hA> endobj +1614 0 obj << +/D [1612 0 R /XYZ 81.963 735.519 null] +>> endobj +194 0 obj << +/D [1612 0 R /XYZ 81.963 710.612 null] +>> endobj +1615 0 obj << +/D [1612 0 R /XYZ 81.963 605.791 null] +>> endobj +1616 0 obj << +/D [1612 0 R /XYZ 81.963 608.379 null] +>> endobj +198 0 obj << +/D [1612 0 R /XYZ 81.963 566.631 null] +>> endobj +1617 0 obj << +/D [1612 0 R /XYZ 81.963 457.128 null] +>> endobj +1618 0 obj << +/D [1612 0 R /XYZ 81.963 459.716 null] +>> endobj +202 0 obj << +/D [1612 0 R /XYZ 81.963 417.968 null] +>> endobj +1619 0 obj << +/D [1612 0 R /XYZ 81.963 308.465 null] +>> endobj +1620 0 obj << +/D [1612 0 R /XYZ 81.963 311.053 null] +>> endobj +206 0 obj << +/D [1612 0 R /XYZ 81.963 269.305 null] +>> endobj +1621 0 obj << +/D [1612 0 R /XYZ 81.963 143.19 null] +>> endobj +1622 0 obj << +/D [1612 0 R /XYZ 81.963 145.778 null] +>> endobj +1611 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1625 0 obj << +/Length 615 +/Filter /FlateDecode +>> +stream +xڵUj@+DռmnlZP-'II$M(^i$G6^-B<;G- Rr5+P$uN6K@1E! v1pJqn,ZQ`Q(,]\D1W4\>Wmi$TX͊i&ITS|n-p-qM^ +U 4x XOMT #2dWpCK"p/% h Yʼ̎iddX?/۲S!S镠`p&uommS-9DaMۯ:=1X$%xR  +endstream +endobj +1624 0 obj << +/Type /Page +/Contents 1625 0 R +/Resources 1623 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1568 0 R +>> endobj +1626 0 obj << +/D [1624 0 R /XYZ 123.806 735.519 null] +>> endobj +210 0 obj << +/D [1624 0 R /XYZ 123.806 710.612 null] +>> endobj +1627 0 obj << +/D [1624 0 R /XYZ 123.806 590.44 null] +>> endobj +1628 0 obj << +/D [1624 0 R /XYZ 123.806 593.028 null] +>> endobj +1629 0 obj << +/D [1624 0 R /XYZ 123.806 577.447 null] +>> endobj +1630 0 obj << +/D [1624 0 R /XYZ 123.806 561.865 null] +>> endobj +1631 0 obj << +/D [1624 0 R /XYZ 123.806 546.284 null] +>> endobj +1632 0 obj << +/D [1624 0 R /XYZ 123.806 530.702 null] +>> endobj +1623 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R /F86 1494 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1635 0 obj << +/Length 852 +/Filter /FlateDecode +>> +stream +xVo6~_A`X {(ڭmEtBHJ(V-4yxw Ԅ៲*frCr(:qdC^2r=\.%*rCrjA43k:fK^-Ӌ+;yS%M/"͸bk~LJyQC p:ZQoYS¨9;Xn8,9PiI!O\ۖn!V&OОBc|7B})CYڥF}.9/g0a.d5qPTUTvn=GnZfXkʔ`vL(#'IIzB17/$(G=sUJz{ڙnj*Q7Tl>+q +\ GBpڄB+v89ԫ} 06.Dx)jPVl#$~1dࣻWk1^{ Ԇ6ʳvźݹ_z@ +@ɡBt6ٗRTo(=9^O凣3צ{,NRQ]SoЗ<7Y4_$Pfy J䂚Ƶŧ{21'T> endobj +1636 0 obj << +/D [1634 0 R /XYZ 81.963 735.519 null] +>> endobj +214 0 obj << +/D [1634 0 R /XYZ 81.963 710.612 null] +>> endobj +218 0 obj << +/D [1634 0 R /XYZ 81.963 687.513 null] +>> endobj +222 0 obj << +/D [1634 0 R /XYZ 81.963 570.539 null] +>> endobj +226 0 obj << +/D [1634 0 R /XYZ 81.963 437.258 null] +>> endobj +230 0 obj << +/D [1634 0 R /XYZ 81.963 287.221 null] +>> endobj +1637 0 obj << +/D [1634 0 R /XYZ 81.963 145.668 null] +>> endobj +1638 0 obj << +/D [1634 0 R /XYZ 81.963 148.256 null] +>> endobj +1633 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1642 0 obj << +/Length 1104 +/Filter /FlateDecode +>> +stream +xWmo6_A`w0``n+Ef6JrQUf!pD=wω#9DOKi!1J [tXH`| ) 8DiD`:QBH4ONN#&Ityd!Qnm,\ȶ5fJ$ xIPBhi\yi?~h*G+a`h͓2˻~P)~T/K3W_߆ Anv5m]u'M^A + #R>!p +I:l[*mǏ y˓!s֓z|L&&M}2(L,G# q6QΨ9>#m.jyU7oJC4_K'fO{5:͇TGِhs]$WKRHRB3/7zk x8Ib +KZjKWוue\^ (EMHNQNO6+EIՌ՞x_Ⱦ`# l%vEEE0ƱO.:c}riG5g|-|}7|u~P, ? ~m|fS1}SN0!svj(|P*z +endstream +endobj +1641 0 obj << +/Type /Page +/Contents 1642 0 R +/Resources 1640 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1639 0 R +>> endobj +1643 0 obj << +/D [1641 0 R /XYZ 123.806 735.519 null] +>> endobj +234 0 obj << +/D [1641 0 R /XYZ 123.806 710.612 null] +>> endobj +1644 0 obj << +/D [1641 0 R /XYZ 123.806 591.512 null] +>> endobj +1645 0 obj << +/D [1641 0 R /XYZ 123.806 594.1 null] +>> endobj +1646 0 obj << +/D [1641 0 R /XYZ 123.806 578.518 null] +>> endobj +1647 0 obj << +/D [1641 0 R /XYZ 123.806 562.937 null] +>> endobj +1648 0 obj << +/D [1641 0 R /XYZ 123.806 547.355 null] +>> endobj +1649 0 obj << +/D [1641 0 R /XYZ 123.806 531.774 null] +>> endobj +1650 0 obj << +/D [1641 0 R /XYZ 123.806 516.192 null] +>> endobj +1651 0 obj << +/D [1641 0 R /XYZ 123.806 500.611 null] +>> endobj +1652 0 obj << +/D [1641 0 R /XYZ 123.806 485.029 null] +>> endobj +1653 0 obj << +/D [1641 0 R /XYZ 123.806 469.448 null] +>> endobj +1654 0 obj << +/D [1641 0 R /XYZ 123.806 453.866 null] +>> endobj +238 0 obj << +/D [1641 0 R /XYZ 123.806 412.418 null] +>> endobj +1655 0 obj << +/D [1641 0 R /XYZ 123.806 305.443 null] +>> endobj +1656 0 obj << +/D [1641 0 R /XYZ 123.806 308.031 null] +>> endobj +242 0 obj << +/D [1641 0 R /XYZ 123.806 266.583 null] +>> endobj +1657 0 obj << +/D [1641 0 R /XYZ 123.806 142.995 null] +>> endobj +1658 0 obj << +/D [1641 0 R /XYZ 123.806 145.584 null] +>> endobj +1640 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R /F86 1494 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1661 0 obj << +/Length 798 +/Filter /FlateDecode +>> +stream +xŖIO@#z>x2oAU '* *18-?o@A(J<~85~IF~3T1c RQ&$|14dqiGSԂ 9 0Ƣte0/F'#V=kKoy'\RѢftB}tъ +pd<_02A aT8Ks"QJ +\Yoo֣Z +TR[W5:3_]^Yk,˻i6-'>N4y*FZv83-NQv;Wg4$iuVkbz81E>\EO*˫v^Na;FU1m Z4.i6 +GTCݵEW`y +L Ija2jfl4ccWe])B@,@Qe)+du=͢9XML*zXe'kܖiBfIHN-ЃlQqbŎLsmjê4:0&vka<ָřkMa-v$e/ּk xE1982.EY} +]|[j ]Yubɐp)(aN"p [y[Ъ-[PVv|lr5Fz܊Irޤy:.ڹ%J@6?f^Vb*> endobj +1662 0 obj << +/D [1660 0 R /XYZ 81.963 735.519 null] +>> endobj +246 0 obj << +/D [1660 0 R /XYZ 81.963 710.612 null] +>> endobj +1663 0 obj << +/D [1660 0 R /XYZ 81.963 592.699 null] +>> endobj +1664 0 obj << +/D [1660 0 R /XYZ 81.963 595.287 null] +>> endobj +250 0 obj << +/D [1660 0 R /XYZ 81.963 553.991 null] +>> endobj +1665 0 obj << +/D [1660 0 R /XYZ 81.963 431.69 null] +>> endobj +1666 0 obj << +/D [1660 0 R /XYZ 81.963 434.278 null] +>> endobj +254 0 obj << +/D [1660 0 R /XYZ 81.963 392.982 null] +>> endobj +1667 0 obj << +/D [1660 0 R /XYZ 81.963 287.293 null] +>> endobj +1668 0 obj << +/D [1660 0 R /XYZ 81.963 289.881 null] +>> endobj +258 0 obj << +/D [1660 0 R /XYZ 81.963 248.585 null] +>> endobj +1669 0 obj << +/D [1660 0 R /XYZ 81.963 142.897 null] +>> endobj +1670 0 obj << +/D [1660 0 R /XYZ 81.963 145.485 null] +>> endobj +1659 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1673 0 obj << +/Length 743 +/Filter /FlateDecode +>> +stream +xՖ]o0VwQPb{vTeҦdEWM,q[$BR kwIkN""cs0rI şF#PI2G'@Jμw? -a RL L5#>$qE񯴈$ϜI..'Tm}n P+叫yT8PQR;xbft]\R2Ç焂UCD໔NK;Pm &3~%8JrZR ӣGhwy`got"T[j5x`r\$| ٺ-Pdp{*F({'&Cւ~B.E|pf*8P1Ebf_u"z\EQ:aIw40ߋ +endstream +endobj +1672 0 obj << +/Type /Page +/Contents 1673 0 R +/Resources 1671 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1639 0 R +>> endobj +1674 0 obj << +/D [1672 0 R /XYZ 123.806 735.519 null] +>> endobj +262 0 obj << +/D [1672 0 R /XYZ 123.806 710.612 null] +>> endobj +1675 0 obj << +/D [1672 0 R /XYZ 123.806 602.27 null] +>> endobj +1676 0 obj << +/D [1672 0 R /XYZ 123.806 604.858 null] +>> endobj +266 0 obj << +/D [1672 0 R /XYZ 123.806 562.658 null] +>> endobj +1677 0 obj << +/D [1672 0 R /XYZ 123.806 449.341 null] +>> endobj +1678 0 obj << +/D [1672 0 R /XYZ 123.806 451.929 null] +>> endobj +270 0 obj << +/D [1672 0 R /XYZ 123.806 409.729 null] +>> endobj +1679 0 obj << +/D [1672 0 R /XYZ 123.806 296.412 null] +>> endobj +1680 0 obj << +/D [1672 0 R /XYZ 123.806 299 null] +>> endobj +274 0 obj << +/D [1672 0 R /XYZ 123.806 256.8 null] +>> endobj +1681 0 obj << +/D [1672 0 R /XYZ 123.806 143.483 null] +>> endobj +1682 0 obj << +/D [1672 0 R /XYZ 123.806 146.072 null] +>> endobj +1671 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1685 0 obj << +/Length 750 +/Filter /FlateDecode +>> +stream +xŖKo@|zþUC(D6M)*KJebH~_!Q!;;3f}Mŏr5+P$'sGq!%Gq?Ҏ0N)NsbԂ33r0FR Gó0GRwrkkM7iF\oCu|g7qR ǽ+eG+̑iڻd +Y\G))Nyo'7,he|eQ?퇒kBU.,ir3a"`{?vlW+?PUɖ*kmU5Ss8qa$ >|r + +Z2ϗiRK 0hja <&bu)lp{'0KH$DXgxįߗ@X.. +C*((řeYqKJ,c-87?DbU_"DKA1[9߂؁Kr`TnsnZJ_v/e o{1U\>y˼ªRW3y)0@$6UoTl E^hae^ N.$.LYV%XH9z +CNN7M56DL\ )^-٦y(:*V>DQ*j6ELf'u"K.s~Mch-vR33˸.K0˸[?}V:5l n_Z +endstream +endobj +1684 0 obj << +/Type /Page +/Contents 1685 0 R +/Resources 1683 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1639 0 R +>> endobj +1686 0 obj << +/D [1684 0 R /XYZ 81.963 735.519 null] +>> endobj +278 0 obj << +/D [1684 0 R /XYZ 81.963 710.612 null] +>> endobj +1687 0 obj << +/D [1684 0 R /XYZ 81.963 609.093 null] +>> endobj +1688 0 obj << +/D [1684 0 R /XYZ 81.963 611.681 null] +>> endobj +1689 0 obj << +/D [1684 0 R /XYZ 81.963 596.1 null] +>> endobj +282 0 obj << +/D [1684 0 R /XYZ 81.963 554.775 null] +>> endobj +1690 0 obj << +/D [1684 0 R /XYZ 81.963 448.85 null] +>> endobj +1691 0 obj << +/D [1684 0 R /XYZ 81.963 451.438 null] +>> endobj +286 0 obj << +/D [1684 0 R /XYZ 81.963 410.114 null] +>> endobj +1692 0 obj << +/D [1684 0 R /XYZ 81.963 304.189 null] +>> endobj +1693 0 obj << +/D [1684 0 R /XYZ 81.963 306.777 null] +>> endobj +290 0 obj << +/D [1684 0 R /XYZ 81.963 265.453 null] +>> endobj +1694 0 obj << +/D [1684 0 R /XYZ 81.963 142.915 null] +>> endobj +1695 0 obj << +/D [1684 0 R /XYZ 81.963 145.503 null] +>> endobj +1683 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1698 0 obj << +/Length 741 +/Filter /FlateDecode +>> +stream +xŖmk0Sh 6N4`BЭ髮 7Q@dv~'?4Ia]ӍX -}OX8}M@$( \Fܱ pIp8 DZe`l8a($DZ0k̮BQ9?88zB>[=s窻,- +WDm}a X<,\6:,4Kg^"8?,Ma+@ -̓k4x8HkدrIZK+I:u +o79Z/2FlD[ %^OnLىI7 )]CGf;[ &hy-u+w.[M۪'.s +ͤ]6qp+ (Htj$_RvpRXr(R9_Mvn>?z1EjhΗ3L=O'jCErP6XV(!E`6$XI\V [R*I1mpeôݪ9YUc=s6ttx<j5Hg]\)I+i|vq\)Ir|A6JJl:+bx5\?>NRV_)Vi{rH()ր7H(4_$CgٶuV- 0G +endstream +endobj +1697 0 obj << +/Type /Page +/Contents 1698 0 R +/Resources 1696 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1639 0 R +>> endobj +1699 0 obj << +/D [1697 0 R /XYZ 123.806 735.519 null] +>> endobj +294 0 obj << +/D [1697 0 R /XYZ 123.806 710.612 null] +>> endobj +1700 0 obj << +/D [1697 0 R /XYZ 123.806 602.27 null] +>> endobj +1701 0 obj << +/D [1697 0 R /XYZ 123.806 604.858 null] +>> endobj +298 0 obj << +/D [1697 0 R /XYZ 123.806 562.658 null] +>> endobj +1702 0 obj << +/D [1697 0 R /XYZ 123.806 449.341 null] +>> endobj +1703 0 obj << +/D [1697 0 R /XYZ 123.806 451.929 null] +>> endobj +302 0 obj << +/D [1697 0 R /XYZ 123.806 409.729 null] +>> endobj +1704 0 obj << +/D [1697 0 R /XYZ 123.806 296.412 null] +>> endobj +1705 0 obj << +/D [1697 0 R /XYZ 123.806 299 null] +>> endobj +306 0 obj << +/D [1697 0 R /XYZ 123.806 256.8 null] +>> endobj +1706 0 obj << +/D [1697 0 R /XYZ 123.806 143.483 null] +>> endobj +1707 0 obj << +/D [1697 0 R /XYZ 123.806 146.072 null] +>> endobj +1696 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1710 0 obj << +/Length 944 +/Filter /FlateDecode +>> +stream +xŗmo6WpJCD]d@='XҠP,QaˮlwDr4 Ct<_Es*DOKi!1J T[T#FceHЬ@$G%qB !ѻd^dZcn-8aD6~Kmˬe gb4h.j95hû`n4h.|ޏxXɴS,0!_l1\׍kf]%LaΥ]nD?\ɬ_駫Ye%CjYm׵j[V$zUV[ymm T+5S]śrUaH=!2f2^kj6Tt=䀍TP҇*m3P*0ײN%lX)&mΦrM~`=d?UW64L:DŁ6wbhiN BqizqKD0L']ةNc*cf}$X7 t2ydL+@֤9HL=Ҹ"IS=6GMS85!SGYvxժ.u^w<{ne] lW~PY5ͬ{ q)VS;{3\m2mcC"~*?`|uO~Y*U{aHNCCYN +65 +NaUı9`8),S {|}ηCj{GC ?Fc`ϠJͽ${% +WӳWU:=[?zݭ3W݃vX_yswp}bNLbQǥIcX2$$r`2{RvJim` \ +޳ +endstream +endobj +1709 0 obj << +/Type /Page +/Contents 1710 0 R +/Resources 1708 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1721 0 R +>> endobj +1711 0 obj << +/D [1709 0 R /XYZ 81.963 735.519 null] +>> endobj +310 0 obj << +/D [1709 0 R /XYZ 81.963 710.612 null] +>> endobj +1712 0 obj << +/D [1709 0 R /XYZ 81.963 609.093 null] +>> endobj +1713 0 obj << +/D [1709 0 R /XYZ 81.963 611.681 null] +>> endobj +314 0 obj << +/D [1709 0 R /XYZ 81.963 570.357 null] +>> endobj +1714 0 obj << +/D [1709 0 R /XYZ 81.963 464.432 null] +>> endobj +1715 0 obj << +/D [1709 0 R /XYZ 81.963 467.02 null] +>> endobj +1716 0 obj << +/D [1709 0 R /XYZ 81.963 451.438 null] +>> endobj +318 0 obj << +/D [1709 0 R /XYZ 81.963 410.114 null] +>> endobj +1717 0 obj << +/D [1709 0 R /XYZ 81.963 287.576 null] +>> endobj +1718 0 obj << +/D [1709 0 R /XYZ 81.963 290.164 null] +>> endobj +322 0 obj << +/D [1709 0 R /XYZ 81.963 248.84 null] +>> endobj +1719 0 obj << +/D [1709 0 R /XYZ 81.963 142.915 null] +>> endobj +1720 0 obj << +/D [1709 0 R /XYZ 81.963 145.503 null] +>> endobj +1708 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F86 1494 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1724 0 obj << +/Length 756 +/Filter /FlateDecode +>> +stream +xՖj@ DzOrQ7  +m^![I HN}gu%צqYkGi=g$' ? f!VeJ[Eܐ/@F΂I08ՎpN BR41Q/eQcp0|.wH:$EӴ,2J +Z*+[o#Jt%$xU$TrGF1nFW:#%q=%Fx}KY˦ +֞\rq+Z]1Fb2Vy3GӇ1ZQW<&q!ӷa[ͪ$40zE¥+'F,H@of:Ϛ^4 ҄V֭n>R1j82Mx?VtmB9im9P¾m'TL62]&:*S΀Z xNEtTKO{t@ M9JJ)[yHG]$,hKI~K%Qb)a6z~<#zv*?GqX]zK\<̟:_}u?ÛkG nUbWK  ++M*w*_^ݽmKk}*5+p kCNǰd3P0%(똹d5¾.ɻC%_*)zhx +endstream +endobj +1723 0 obj << +/Type /Page +/Contents 1724 0 R +/Resources 1722 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1721 0 R +>> endobj +1725 0 obj << +/D [1723 0 R /XYZ 123.806 735.519 null] +>> endobj +326 0 obj << +/D [1723 0 R /XYZ 123.806 710.612 null] +>> endobj +1726 0 obj << +/D [1723 0 R /XYZ 123.806 602.27 null] +>> endobj +1727 0 obj << +/D [1723 0 R /XYZ 123.806 604.858 null] +>> endobj +330 0 obj << +/D [1723 0 R /XYZ 123.806 562.658 null] +>> endobj +1728 0 obj << +/D [1723 0 R /XYZ 123.806 449.341 null] +>> endobj +1729 0 obj << +/D [1723 0 R /XYZ 123.806 451.929 null] +>> endobj +334 0 obj << +/D [1723 0 R /XYZ 123.806 409.729 null] +>> endobj +1730 0 obj << +/D [1723 0 R /XYZ 123.806 296.412 null] +>> endobj +1731 0 obj << +/D [1723 0 R /XYZ 123.806 299 null] +>> endobj +338 0 obj << +/D [1723 0 R /XYZ 123.806 256.8 null] +>> endobj +1732 0 obj << +/D [1723 0 R /XYZ 123.806 143.483 null] +>> endobj +1733 0 obj << +/D [1723 0 R /XYZ 123.806 146.072 null] +>> endobj +1722 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1736 0 obj << +/Length 768 +/Filter /FlateDecode +>> +stream +xՖ]k0+=fE4J/&¾Z])&V:CN;$Rm!-<EK%QZ!-$&"Uї@ A4 (FJ1ppڭ2$)!$< 烏AtBnf21KIY3I¯ [ CVe' 6utĜ4W ̍F)Ⱅ'"'1'R`i^<ٴŲ.U 5۔#(fDЫMr {8ޒzu҈Ҽ?,o*;–ˢ+/ߌhŜVEd32>ff`30Rp̖kN V`a]98~(#}6Oʏ͵] H-@9z;o*Դxc6IАA!n L%Ѫe7ur&mGMHG6ESs߉$|#tFVLXpKwkHan|p?u:d]࢘Oά5ϵ\^sӊc6Ӓaʓ3-8)L `ޒјCmoS${MBmg}ly..j @Q @߇_@9fc^>D[oj|+k? ܟo.75rCf> endobj +1737 0 obj << +/D [1735 0 R /XYZ 81.963 735.519 null] +>> endobj +342 0 obj << +/D [1735 0 R /XYZ 81.963 710.612 null] +>> endobj +1738 0 obj << +/D [1735 0 R /XYZ 81.963 602.27 null] +>> endobj +1739 0 obj << +/D [1735 0 R /XYZ 81.963 604.858 null] +>> endobj +346 0 obj << +/D [1735 0 R /XYZ 81.963 562.658 null] +>> endobj +1740 0 obj << +/D [1735 0 R /XYZ 81.963 449.341 null] +>> endobj +1741 0 obj << +/D [1735 0 R /XYZ 81.963 451.929 null] +>> endobj +350 0 obj << +/D [1735 0 R /XYZ 81.963 409.729 null] +>> endobj +1742 0 obj << +/D [1735 0 R /XYZ 81.963 296.412 null] +>> endobj +1743 0 obj << +/D [1735 0 R /XYZ 81.963 299 null] +>> endobj +354 0 obj << +/D [1735 0 R /XYZ 81.963 256.8 null] +>> endobj +1744 0 obj << +/D [1735 0 R /XYZ 81.963 143.483 null] +>> endobj +1745 0 obj << +/D [1735 0 R /XYZ 81.963 146.072 null] +>> endobj +1734 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1748 0 obj << +/Length 798 +/Filter /FlateDecode +>> +stream +xՖn@+q-͞.H(Bn-bokNp%Eٙw()KFFHL2]# :'"J5cCbStPiQBH0O= #&I0㭷g!A᜿,tex9;ُόL X~~OC)ߟ&^T!FdzjDh/A9h.. J"[C3a-)8 4 5XIݕ檭}mvHz:6İ~@"ʇz&QeUx2 _^ݯ8/*mJ{_&c7qqJ#W!א%uĎlbmx+\Y|Hj13wJj8( UQgt띀ݮ}4H슆A2mD}X0OSke~/՟#Mesc?ӫV˸qͤ|M;G: ]uˮ\zYK)I:4?(!,CigC !0)"%0P7m IWlFX2TɟbXƊYRwYn!`[e4mk+TJ>FtJ`̽@Y*]Z0w/8OC8-v.Z^.SH)ظ3R7y`b)6{b)>B{(:Z(5SMBĀ~ +endstream +endobj +1747 0 obj << +/Type /Page +/Contents 1748 0 R +/Resources 1746 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1721 0 R +>> endobj +1749 0 obj << +/D [1747 0 R /XYZ 123.806 735.519 null] +>> endobj +358 0 obj << +/D [1747 0 R /XYZ 123.806 710.612 null] +>> endobj +1750 0 obj << +/D [1747 0 R /XYZ 123.806 605.791 null] +>> endobj +1751 0 obj << +/D [1747 0 R /XYZ 123.806 608.379 null] +>> endobj +362 0 obj << +/D [1747 0 R /XYZ 123.806 566.631 null] +>> endobj +1752 0 obj << +/D [1747 0 R /XYZ 123.806 457.128 null] +>> endobj +1753 0 obj << +/D [1747 0 R /XYZ 123.806 459.716 null] +>> endobj +366 0 obj << +/D [1747 0 R /XYZ 123.806 417.968 null] +>> endobj +1754 0 obj << +/D [1747 0 R /XYZ 123.806 308.465 null] +>> endobj +1755 0 obj << +/D [1747 0 R /XYZ 123.806 311.053 null] +>> endobj +370 0 obj << +/D [1747 0 R /XYZ 123.806 269.305 null] +>> endobj +1756 0 obj << +/D [1747 0 R /XYZ 123.806 143.19 null] +>> endobj +1757 0 obj << +/D [1747 0 R /XYZ 123.806 145.778 null] +>> endobj +1746 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R /F86 1494 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1760 0 obj << +/Length 889 +/Filter /FlateDecode +>> +stream +xVnF}W,Ї4(W64i3OIa!Q2)wKYD sf0rפ"3XJm%=Y?''Rr=yM.#SlA, F8!R QJY6{zq%U%]b)W4yT?˫] )&lr7a-\vZ`Wo))SBA8Kig8^Q=?G; Z}=@u5˼η床n6~^ 1;0W_fB-i>RPVTc_[Y=(ϐ}͓h04b]X\3wպM ~SW۲OFjV)Wɇq^Gh:Y:&AӆpGO DHB=HeB3?-eZ/rU{A} 'H´#@$q76K ~l̈F{e +JmڱugB]~YԥaP1` +:&2?Jf Q`}=ArW5meqt<|,52w|mg/a4 _D%U@#[Č!z$CR>p׺4t +endstream +endobj +1759 0 obj << +/Type /Page +/Contents 1760 0 R +/Resources 1758 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1721 0 R +>> endobj +1761 0 obj << +/D [1759 0 R /XYZ 81.963 735.519 null] +>> endobj +374 0 obj << +/D [1759 0 R /XYZ 81.963 710.612 null] +>> endobj +378 0 obj << +/D [1759 0 R /XYZ 81.963 688.16 null] +>> endobj +382 0 obj << +/D [1759 0 R /XYZ 81.963 577.121 null] +>> endobj +386 0 obj << +/D [1759 0 R /XYZ 81.963 477.967 null] +>> endobj +1762 0 obj << +/D [1759 0 R /XYZ 81.963 361.291 null] +>> endobj +1763 0 obj << +/D [1759 0 R /XYZ 81.963 363.879 null] +>> endobj +1764 0 obj << +/D [1759 0 R /XYZ 81.963 348.297 null] +>> endobj +1765 0 obj << +/D [1759 0 R /XYZ 81.963 332.716 null] +>> endobj +1766 0 obj << +/D [1759 0 R /XYZ 81.963 317.134 null] +>> endobj +390 0 obj << +/D [1759 0 R /XYZ 81.963 274.784 null] +>> endobj +1767 0 obj << +/D [1759 0 R /XYZ 81.963 143.581 null] +>> endobj +1768 0 obj << +/D [1759 0 R /XYZ 81.963 146.169 null] +>> endobj +1758 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1771 0 obj << +/Length 771 +/Filter /FlateDecode +>> +stream +xՖmk0SbŊ؋Pۈ /QیidNةnD9Kt(C^j,6!1;tL$! Eb+%CcCbMtQi?h8c&I4-Ӈ0N\Fsp+HȦf fJϫy֜.ۗ2*iJgE0hm(1罳 &̭A9Ⱇ34m 5XIIK,ԓ2ѭqG53W͛i6&/|ʃab[~Zmh̥Ť6w˖:X5цa1O a.c>я>Wb^UN*9ֆו5xVZ[ONIK\'+(-a( ++oxٵ :0TGvKa9?h:B:oj`ֵAhYbi=FHC\=[p,u_[48jWb`'ނ[m>ͦۏp{K/V>0| 71~prIJܭAK86\9jBsJ Y僢9a0[_rhuy%yp,7yAkv1-ʎ1m~aC^NL-xaQx._Gë8a?p;K.;A1>IۆP*,!CH,[K@H9pa&_s"Iﻺ`h>EҡGJ)aZ>@_ +endstream +endobj +1770 0 obj << +/Type /Page +/Contents 1771 0 R +/Resources 1769 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1721 0 R +>> endobj +1772 0 obj << +/D [1770 0 R /XYZ 123.806 735.519 null] +>> endobj +394 0 obj << +/D [1770 0 R /XYZ 123.806 710.612 null] +>> endobj +1773 0 obj << +/D [1770 0 R /XYZ 123.806 589.178 null] +>> endobj +1774 0 obj << +/D [1770 0 R /XYZ 123.806 591.766 null] +>> endobj +398 0 obj << +/D [1770 0 R /XYZ 123.806 550.018 null] +>> endobj +1775 0 obj << +/D [1770 0 R /XYZ 123.806 440.515 null] +>> endobj +1776 0 obj << +/D [1770 0 R /XYZ 123.806 443.103 null] +>> endobj +402 0 obj << +/D [1770 0 R /XYZ 123.806 401.355 null] +>> endobj +1777 0 obj << +/D [1770 0 R /XYZ 123.806 291.853 null] +>> endobj +1778 0 obj << +/D [1770 0 R /XYZ 123.806 294.441 null] +>> endobj +406 0 obj << +/D [1770 0 R /XYZ 123.806 252.693 null] +>> endobj +1779 0 obj << +/D [1770 0 R /XYZ 123.806 143.19 null] +>> endobj +1780 0 obj << +/D [1770 0 R /XYZ 123.806 145.778 null] +>> endobj +1769 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1783 0 obj << +/Length 679 +/Filter /FlateDecode +>> +stream +xՖmo0SXD~ !N$`LSzRuI ||.OmR`l {9}zKŗF#PIrG[#%Ga썦%U\Fha99 BF)O&xǣTݝDjӛr\Q]ǁR~Q~56&w*\;Z`$K윒9>;&5k$RR:%^>h1n +l88t*Vm45+EI(8(%jG,I7s<-9lO_=8muqy*w֋캶4`UΊFD)wyYjB勀+KU~l( 6pBy 61;.{!mhm\ +nǺG +umCH(Ak^"Q3ʰ +CT`AR:`(A2]$uew8Ams}o=fS(#YێTbإ2mxmٻhhGO3K/t|:YRqA[N&\;rdPB$V+Yd HZOj>LJ v?OWw=kxQ7fx@s..߸g`9t F3ir)4֐'ix> +endstream +endobj +1782 0 obj << +/Type /Page +/Contents 1783 0 R +/Resources 1781 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1791 0 R +>> endobj +1784 0 obj << +/D [1782 0 R /XYZ 81.963 735.519 null] +>> endobj +410 0 obj << +/D [1782 0 R /XYZ 81.963 710.612 null] +>> endobj +1785 0 obj << +/D [1782 0 R /XYZ 81.963 590.44 null] +>> endobj +1786 0 obj << +/D [1782 0 R /XYZ 81.963 593.028 null] +>> endobj +414 0 obj << +/D [1782 0 R /XYZ 81.963 549.31 null] +>> endobj +1787 0 obj << +/D [1782 0 R /XYZ 81.963 423.178 null] +>> endobj +1788 0 obj << +/D [1782 0 R /XYZ 81.963 425.766 null] +>> endobj +418 0 obj << +/D [1782 0 R /XYZ 81.963 382.048 null] +>> endobj +1789 0 obj << +/D [1782 0 R /XYZ 81.963 255.915 null] +>> endobj +1790 0 obj << +/D [1782 0 R /XYZ 81.963 258.504 null] +>> endobj +1781 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1794 0 obj << +/Length 794 +/Filter /FlateDecode +>> +stream +xV]O0}ϯ5CG;z4iȞBI!SXRۯu$&T5qks=/9~HA(~d@RѾ'eJVC1g7rAHPJNa\Q"mrȐ/"s +5'EFM84!§-(&id&AjV yjڭ5ZwkA%h5+RX3Ul@3+wF ܨ8(405!2^#ṍ>؂m{]Hأ@ $It*$BO%T6/BeW!!BmjA%¦erp`hI9n +endstream +endobj +1793 0 obj << +/Type /Page +/Contents 1794 0 R +/Resources 1792 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1791 0 R +>> endobj +1795 0 obj << +/D [1793 0 R /XYZ 123.806 735.519 null] +>> endobj +422 0 obj << +/D [1793 0 R /XYZ 123.806 710.612 null] +>> endobj +426 0 obj << +/D [1793 0 R /XYZ 123.806 690.2 null] +>> endobj +430 0 obj << +/D [1793 0 R /XYZ 123.806 578.191 null] +>> endobj +434 0 obj << +/D [1793 0 R /XYZ 123.806 468.628 null] +>> endobj +1796 0 obj << +/D [1793 0 R /XYZ 123.806 318.826 null] +>> endobj +1797 0 obj << +/D [1793 0 R /XYZ 123.806 321.414 null] +>> endobj +438 0 obj << +/D [1793 0 R /XYZ 123.806 276.024 null] +>> endobj +1798 0 obj << +/D [1793 0 R /XYZ 123.806 144.921 null] +>> endobj +1799 0 obj << +/D [1793 0 R /XYZ 123.806 147.509 null] +>> endobj +1792 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1802 0 obj << +/Length 820 +/Filter /FlateDecode +>> +stream +x͖kk0W=1[ +W.8wK.4#$Q >%aR6&&F*ʤ6LɗÍ>{Z8O$oIe,1G0GRP% +>oIqł+ + +VII^7n{P [+*ɢwyHع o\Zn<U\Cj<{&$O˼ Wd$Z#Jl2ߤ.4ja9]K8*ca$eZrwֳ[xd;].ӝgFX峐W*piyx/UdzXC]=INI;>dip$b<$M5T.[A2߸.q%T~ *cāP\I7sH6tmm]S ༽ UCvF-BL%{hcnUW}l1[gշt_5qk]V.~㽴"S yKCu&a&nqơnM$q~1.ĩm5Ŷ4=ITJ8\R]9Yg-#53?="߳I]&gpdl]ꇷ.(VQJD\BJ7ߙbeX཭EUl]mja=-jA62[2&_(n<<M]{:1l,kAA'~dGy( 22(ظj  +endstream +endobj +1801 0 obj << +/Type /Page +/Contents 1802 0 R +/Resources 1800 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1791 0 R +>> endobj +1803 0 obj << +/D [1801 0 R /XYZ 81.963 735.519 null] +>> endobj +442 0 obj << +/D [1801 0 R /XYZ 81.963 710.612 null] +>> endobj +1804 0 obj << +/D [1801 0 R /XYZ 81.963 590.537 null] +>> endobj +1805 0 obj << +/D [1801 0 R /XYZ 81.963 593.125 null] +>> endobj +446 0 obj << +/D [1801 0 R /XYZ 81.963 551.551 null] +>> endobj +1806 0 obj << +/D [1801 0 R /XYZ 81.963 452.691 null] +>> endobj +1807 0 obj << +/D [1801 0 R /XYZ 81.963 455.279 null] +>> endobj +1808 0 obj << +/D [1801 0 R /XYZ 81.963 439.697 null] +>> endobj +450 0 obj << +/D [1801 0 R /XYZ 81.963 398.124 null] +>> endobj +1809 0 obj << +/D [1801 0 R /XYZ 81.963 290.093 null] +>> endobj +1810 0 obj << +/D [1801 0 R /XYZ 81.963 292.681 null] +>> endobj +454 0 obj << +/D [1801 0 R /XYZ 81.963 251.108 null] +>> endobj +1811 0 obj << +/D [1801 0 R /XYZ 81.963 143.077 null] +>> endobj +1812 0 obj << +/D [1801 0 R /XYZ 81.963 145.665 null] +>> endobj +1800 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1815 0 obj << +/Length 707 +/Filter /FlateDecode +>> +stream +x͖]o0v1XlhEӦҤjʤI]5vL@ZBC4Tզ(}_|p( + bH`8BAG`"AG~͖R#JQqL$R\؆2tSiRB- 6ƍE٘Mp-#1gqm56~o8nJxw6):ؠj*s2u~SK^"/Щ7I;Җ:RmXbݧ|=i*:mu^sP3,wRjUf6"w_:zTM^]Hg:SA;S:T&s3/uٕ/OiL|`î=8TAKI JJ2htxׅrݛ3B(b +{ +,b?`Z4l% D!B +VߴYHPTTNGt[օd(vlʋ8{lo )aז7ۿPGFዧJg/"}"d|-~yM#ؔ?Uǟ5y~!]wpH<|G)x|~IZeC(f1 +Ēv-NMY5tJ ]yqf ExfLû?3[Da;~ j&tڷ9E1~D" +endstream +endobj +1814 0 obj << +/Type /Page +/Contents 1815 0 R +/Resources 1813 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1791 0 R +>> endobj +1816 0 obj << +/D [1814 0 R /XYZ 123.806 735.519 null] +>> endobj +458 0 obj << +/D [1814 0 R /XYZ 123.806 710.612 null] +>> endobj +1817 0 obj << +/D [1814 0 R /XYZ 123.806 590.44 null] +>> endobj +1818 0 obj << +/D [1814 0 R /XYZ 123.806 593.028 null] +>> endobj +462 0 obj << +/D [1814 0 R /XYZ 123.806 549.31 null] +>> endobj +1819 0 obj << +/D [1814 0 R /XYZ 123.806 423.178 null] +>> endobj +1820 0 obj << +/D [1814 0 R /XYZ 123.806 425.766 null] +>> endobj +466 0 obj << +/D [1814 0 R /XYZ 123.806 382.048 null] +>> endobj +1821 0 obj << +/D [1814 0 R /XYZ 123.806 239.303 null] +>> endobj +1822 0 obj << +/D [1814 0 R /XYZ 123.806 241.891 null] +>> endobj +1813 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1825 0 obj << +/Length 813 +/Filter /FlateDecode +>> +stream +xUmO0_aiLﱧi`-4'Ph](jRH˶sФ&$TQ<0r ?&hbb*tdN~ (Rr0K1JqΉAQ  kfth3Jx<폣h"U&7踺.Ϣ+:vH}wһUmhY2g !+˜ @yIN;a=*iI鳛.2,V焎bAR6sʾ ;ގ+M͢.f.5:spqOOd/[AxZȖZؠZ*V3JwS+6ZuC (W_SC7 UO3\F"bߋIX(d yh;._kFl#>JZ_ynȟ7`.g朁1s"`.^rL֕FxFw-C䶅{wki,^J)p'.?nzߑ Ӕ&^FѣgO2B~DEx;ny~h\˳jAZdҽ0눂>ǣy\$@q=f1ʰjk\_jARZK].XW=[S&f^S[՘BU/:4*R.ROe]>mcbXU8j^}g?b=AmpjVMENVTV>{կoXHtwsJ4 4&D/kz +endstream +endobj +1824 0 obj << +/Type /Page +/Contents 1825 0 R +/Resources 1823 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1791 0 R +>> endobj +1826 0 obj << +/D [1824 0 R /XYZ 81.963 735.519 null] +>> endobj +470 0 obj << +/D [1824 0 R /XYZ 81.963 710.612 null] +>> endobj +474 0 obj << +/D [1824 0 R /XYZ 81.963 690.444 null] +>> endobj +478 0 obj << +/D [1824 0 R /XYZ 81.963 589.03 null] +>> endobj +482 0 obj << +/D [1824 0 R /XYZ 81.963 490.061 null] +>> endobj +486 0 obj << +/D [1824 0 R /XYZ 81.963 374.623 null] +>> endobj +1827 0 obj << +/D [1824 0 R /XYZ 81.963 254.725 null] +>> endobj +1828 0 obj << +/D [1824 0 R /XYZ 81.963 257.313 null] +>> endobj +490 0 obj << +/D [1824 0 R /XYZ 81.963 214.598 null] +>> endobj +1823 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1831 0 obj << +/Length 849 +/Filter /FlateDecode +>> +stream +xVmo0_a ^ng $(loZ>iZoTj-iys 4\|sWsPSE5JTj+I8ыhr3dJq2?# T#2޵$_FcF)M+~GcSʹf4]uxzr(U[ \K|a[;kW=JJf./ڇF,$Ţ *,#b嘒%N&Df @{Mf?,heK}~JM_ބuQ'!)sd@&؃UXoXO}!ۋ!mtR^,[r)K.+Wr*g<ζb(e^۸UD #XKWRo)S[/cEђ) P~"Z[ˡcapK C6ť +4]#w,)=bsܲzr1ޓ77?55~1ᠱZ97a[VxF a?7J F +\t5vPv3wuϪS"gD`Ə#;N.1#tjj@>- V1o(9 2ɀAյ=:yke+NL6 7VUd/0Lcj lS{#/. # 7xrXpe +efC_ǮBF3d |. t{LJ+\#{MemTćt_d78ߦﶢ^%* ^x[m /εXx6̀r0dva%{1__ +endstream +endobj +1830 0 obj << +/Type /Page +/Contents 1831 0 R +/Resources 1829 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1791 0 R +>> endobj +1832 0 obj << +/D [1830 0 R /XYZ 123.806 735.519 null] +>> endobj +494 0 obj << +/D [1830 0 R /XYZ 123.806 710.612 null] +>> endobj +498 0 obj << +/D [1830 0 R /XYZ 123.806 607.663 null] +>> endobj +502 0 obj << +/D [1830 0 R /XYZ 123.806 514.24 null] +>> endobj +506 0 obj << +/D [1830 0 R /XYZ 123.806 404.491 null] +>> endobj +1833 0 obj << +/D [1830 0 R /XYZ 123.806 292.346 null] +>> endobj +1834 0 obj << +/D [1830 0 R /XYZ 123.806 294.934 null] +>> endobj +510 0 obj << +/D [1830 0 R /XYZ 123.806 253.137 null] +>> endobj +1835 0 obj << +/D [1830 0 R /XYZ 123.806 143.222 null] +>> endobj +1836 0 obj << +/D [1830 0 R /XYZ 123.806 145.81 null] +>> endobj +1829 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1839 0 obj << +/Length 899 +/Filter /FlateDecode +>> +stream +x͖o0_aDGo4 $ Bb"hjXH^ )(k72BG]JB~U^l +ɴL 0\mz((ftgv0;/rD?whu\|Ĝ4,:G`"V+ URp蠳_GLj0 4||6+v:SmlkW%b 拑b&8wz隝Uj;D\vaצBojϦvfyVmVYV->~ <89%;"&_"*v׍"P4ƙVG]v0o &:V'{_YnWv߻9ֆ4+8&S ^PAaڀBit$qQ_.+jO?I/;{=+o0BeƂa"*le\u..:07? SMdgl;M 6 '73TaEC,#Az`ן>Ͱ48Q||Mx׷+Ne=O}o7?Xn/PyUvER?1t#kUXhsre,Qq*֗0n,?˞8TlEC 7OJUTG&|mXeyQzu}+ Y9o3Q}Yk.+q(ȭjԚ9b9%gwcG5O/4.L5RYT=Q j䈸[ e3fq hTk^%FXgb $+z5rH +endstream +endobj +1838 0 obj << +/Type /Page +/Contents 1839 0 R +/Resources 1837 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1849 0 R +>> endobj +1840 0 obj << +/D [1838 0 R /XYZ 81.963 735.519 null] +>> endobj +514 0 obj << +/D [1838 0 R /XYZ 81.963 710.612 null] +>> endobj +1841 0 obj << +/D [1838 0 R /XYZ 81.963 609.311 null] +>> endobj +1842 0 obj << +/D [1838 0 R /XYZ 81.963 611.9 null] +>> endobj +518 0 obj << +/D [1838 0 R /XYZ 81.963 570.603 null] +>> endobj +1843 0 obj << +/D [1838 0 R /XYZ 81.963 448.302 null] +>> endobj +1844 0 obj << +/D [1838 0 R /XYZ 81.963 450.89 null] +>> endobj +522 0 obj << +/D [1838 0 R /XYZ 81.963 409.594 null] +>> endobj +1845 0 obj << +/D [1838 0 R /XYZ 81.963 287.293 null] +>> endobj +1846 0 obj << +/D [1838 0 R /XYZ 81.963 289.881 null] +>> endobj +526 0 obj << +/D [1838 0 R /XYZ 81.963 248.585 null] +>> endobj +1847 0 obj << +/D [1838 0 R /XYZ 81.963 142.897 null] +>> endobj +1848 0 obj << +/D [1838 0 R /XYZ 81.963 145.485 null] +>> endobj +1837 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1852 0 obj << +/Length 768 +/Filter /FlateDecode +>> +stream +xŖKo0 vŠ,KCa❺bةݿjiˊ LR4Or(!$T!R$*@E !`HЙ!r&R#Jh(XBEstRSB;L< dyhבDž[X>MSSi 30e4o-zBedk.ȹuh +P`N5AsP#V1]"uf m-Rqs~d-LMdɩby8zdqCu$yW'=FP.|~gZ?[UfA*li*ɮ[i%v'y*<++UrmxLwE0ہq&26NǀTc|RB|*:?ٸs,4%dT]rERVxB~GV %mV`e|.~i#5}5gJ@ >  >F 6mϯP}0<TlF ̵Uj*gÐ3CΠ3n[=Xw Fæ50QeWfַ-c~k +endstream +endobj +1851 0 obj << +/Type /Page +/Contents 1852 0 R +/Resources 1850 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1849 0 R +>> endobj +1853 0 obj << +/D [1851 0 R /XYZ 123.806 735.519 null] +>> endobj +530 0 obj << +/D [1851 0 R /XYZ 123.806 710.612 null] +>> endobj +534 0 obj << +/D [1851 0 R /XYZ 123.806 592.047 null] +>> endobj +538 0 obj << +/D [1851 0 R /XYZ 123.806 481.19 null] +>> endobj +542 0 obj << +/D [1851 0 R /XYZ 123.806 354.897 null] +>> endobj +546 0 obj << +/D [1851 0 R /XYZ 123.806 226.681 null] +>> endobj +1850 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1856 0 obj << +/Length 765 +/Filter /FlateDecode +>> +stream +x͖_o00x_li&ZTUK,}14@i;M:E|wwp(O +KBZHLD* ZOCNě-Qc)JHqxլеOIRB9_/&9-dZc pl d+S+w!-̺wh92oZ"l,sQRp3txXH.L¬ 81M\i'f-4;'( j[, '1ۑaF~ +|p,*'w,sB TV*;4)mi-E+q Ԧu0ASowBiĄ\4\6`P雕c.wy[ $8tahg)o`R~7zʡxg[AMTXa*h*_"ڳ%~[!sIݥeޚHz({V3#cam⬣CƱRp3ZId|W=5o@)Rcٵ- Eٵ^!6>ECl~[/1{Dm `mp#eo3v!La!Eovx0C9L>3CF(f*t;K;(Qa!L&RL}WZgk__mO4Iд_/)iZz؁O!9,qxysp-Д` |i팤Xgoz] +endstream +endobj +1855 0 obj << +/Type /Page +/Contents 1856 0 R +/Resources 1854 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1849 0 R +>> endobj +1857 0 obj << +/D [1855 0 R /XYZ 81.963 735.519 null] +>> endobj +550 0 obj << +/D [1855 0 R /XYZ 81.963 710.612 null] +>> endobj +554 0 obj << +/D [1855 0 R /XYZ 81.963 592.047 null] +>> endobj +558 0 obj << +/D [1855 0 R /XYZ 81.963 464.72 null] +>> endobj +562 0 obj << +/D [1855 0 R /XYZ 81.963 337.394 null] +>> endobj +566 0 obj << +/D [1855 0 R /XYZ 81.963 210.068 null] +>> endobj +1854 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1860 0 obj << +/Length 870 +/Filter /FlateDecode +>> +stream +x͖Yk@)PG/h +󔆢XTŖIAwH+ْMH1oGDeGZ%F##$&BrЇCF񾲈Rldhz(4TC :(4(!$';;a$ deݷ!AMqQ"< όL ؾj5GR￉x^MG#ZE;Sf A LFskзt8%6†񁰕5XIkdxኋxvY}x߰C +Ll~> +=O bO_ ? eҴrwee1i컉H2]f8ӐkHeow/MD/}M(fD Qa%JBp.H.a( ++Pxw[?;i#D3Nj{RkA`wl;*&ZƨuHڡ +-K43QיZ}+u=V?P c=jG b}/i\<p n ]Z&.{/ mI?<=^?*4 @4‚ɇaC>6J=4O.н*VI0؇dg"j9zQ Z5PFGlmԬRz#@+D_ɖ =YC:YfI]bLr$~b|92.  A6 JlUYı\ Y؟4!LSR0U_2u$Q0qx֍>| +endstream +endobj +1859 0 obj << +/Type /Page +/Contents 1860 0 R +/Resources 1858 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1849 0 R +>> endobj +1861 0 obj << +/D [1859 0 R /XYZ 123.806 735.519 null] +>> endobj +570 0 obj << +/D [1859 0 R /XYZ 123.806 710.612 null] +>> endobj +1862 0 obj << +/D [1859 0 R /XYZ 123.806 596.22 null] +>> endobj +1863 0 obj << +/D [1859 0 R /XYZ 123.806 598.808 null] +>> endobj +574 0 obj << +/D [1859 0 R /XYZ 123.806 557.964 null] +>> endobj +1864 0 obj << +/D [1859 0 R /XYZ 123.806 439.477 null] +>> endobj +1865 0 obj << +/D [1859 0 R /XYZ 123.806 442.065 null] +>> endobj +578 0 obj << +/D [1859 0 R /XYZ 123.806 401.22 null] +>> endobj +1866 0 obj << +/D [1859 0 R /XYZ 123.806 299.346 null] +>> endobj +1867 0 obj << +/D [1859 0 R /XYZ 123.806 301.934 null] +>> endobj +582 0 obj << +/D [1859 0 R /XYZ 123.806 261.09 null] +>> endobj +1868 0 obj << +/D [1859 0 R /XYZ 123.806 142.603 null] +>> endobj +1869 0 obj << +/D [1859 0 R /XYZ 123.806 145.191 null] +>> endobj +1858 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1872 0 obj << +/Length 846 +/Filter /FlateDecode +>> +stream +xV[o0}ﯰ Z=o'#!7w21SMϗEFLUmۡA$2`8I-1[&p̍Fqx9:zXɸScfڲFN:fLEa)'i0R@qߕ8vx3 `[qr6iWlmEV;D1]"jb!ra:8U2| oVؚQ M ZqdӼo"Ƃ.0)'tKWl6rQP"ggm}{Pkx۴CXܤT*6wʢKM󲡯>Fsvlj9\<Ӊjဴu 7^5XqKD )uh&PK̺TŲ*(U)I(P \ß~L`c?I4(|ݲ ;#my!'k/|bG(zt(5G$IzQ-Ŭ$>GPsGbܑ莜ipG]SÆccYlm\8MgIߵASH9(]yRyhg+7h5&Jnh$NW%ΗL-Sr]{Ԍ?!jZoU2hXsL"*8I|i@k[w( +endstream +endobj +1871 0 obj << +/Type /Page +/Contents 1872 0 R +/Resources 1870 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1849 0 R +>> endobj +1873 0 obj << +/D [1871 0 R /XYZ 81.963 735.519 null] +>> endobj +586 0 obj << +/D [1871 0 R /XYZ 81.963 710.612 null] +>> endobj +1874 0 obj << +/D [1871 0 R /XYZ 81.963 573.827 null] +>> endobj +1875 0 obj << +/D [1871 0 R /XYZ 81.963 576.416 null] +>> endobj +1876 0 obj << +/D [1871 0 R /XYZ 81.963 560.834 null] +>> endobj +1877 0 obj << +/D [1871 0 R /XYZ 81.963 545.253 null] +>> endobj +590 0 obj << +/D [1871 0 R /XYZ 81.963 501.535 null] +>> endobj +1878 0 obj << +/D [1871 0 R /XYZ 81.963 358.79 null] +>> endobj +1879 0 obj << +/D [1871 0 R /XYZ 81.963 361.378 null] +>> endobj +594 0 obj << +/D [1871 0 R /XYZ 81.963 317.66 null] +>> endobj +1870 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1882 0 obj << +/Length 1068 +/Filter /FlateDecode +>> +stream +xWnF}W,ЇM;mӇiRXKkieH3{Dt p99wk*D3,I3D(-Pc Hz:W9R2!8DX-zPiluId$TueXJӶM߮_΅gZcl#ݛomNLpTt!׋w ꋢ%4G["{a/)8%\LʆU٩lcῘ}B,:CS^Ci >~չf=]|UTv -Tיzo~~fZ7-C0wu S´nnƶ:G(KAYm.2qb4mERXPvXrВ…R +Y*,OYn&q6{u̦.s yj;vf,?)BWl@ZTCTq 2h{8}1oJ/õY*IqƄ{ӆJ,51 P$CBI='}fςbIb~0&XY`EZX=WЄKJ/@A>J&ewJI#Atα:r^r G݄H6XFNpI sGA]wtK trc djr ?w|/H$ZK俴|I8VZN n<74qV=k0Les4 nknZ|V*Ӛ?VV1 Q"*X8Ph'򳐟2d;vqa~:=}: · ApdEEF!+Hn +endstream +endobj +1881 0 obj << +/Type /Page +/Contents 1882 0 R +/Resources 1880 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1849 0 R +>> endobj +1883 0 obj << +/D [1881 0 R /XYZ 123.806 735.519 null] +>> endobj +598 0 obj << +/D [1881 0 R /XYZ 123.806 710.612 null] +>> endobj +602 0 obj << +/D [1881 0 R /XYZ 123.806 690.444 null] +>> endobj +1884 0 obj << +/D [1881 0 R /XYZ 123.806 566.392 null] +>> endobj +1885 0 obj << +/D [1881 0 R /XYZ 123.806 568.98 null] +>> endobj +606 0 obj << +/D [1881 0 R /XYZ 123.806 528.013 null] +>> endobj +610 0 obj << +/D [1881 0 R /XYZ 123.806 425.493 null] +>> endobj +1886 0 obj << +/D [1881 0 R /XYZ 123.806 299.551 null] +>> endobj +1887 0 obj << +/D [1881 0 R /XYZ 123.806 302.139 null] +>> endobj +1888 0 obj << +/D [1881 0 R /XYZ 123.806 286.558 null] +>> endobj +614 0 obj << +/D [1881 0 R /XYZ 123.806 245.591 null] +>> endobj +1889 0 obj << +/D [1881 0 R /XYZ 123.806 142.683 null] +>> endobj +1890 0 obj << +/D [1881 0 R /XYZ 123.806 145.271 null] +>> endobj +1880 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R /F86 1494 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1893 0 obj << +/Length 746 +/Filter /FlateDecode +>> +stream +xŖn@+v%/3rQ*5jWJFKb lbL۫>{g}L/ٙ?#n}2D%‚(.5GEStHЩ>z#ix4,%Ce}JBhx1< CoŶg5$ӧ< Ho!ec cޣUts4{7MD03vgKo?GPm=bT5eYe^%s[t0X&ƳHG .w;ajSlj&|p;fUEa6+춶4M3n\ oi G@o'ixG5Ekՠ ;NYۈ5Rv?v[PȄ*P %.7};mǁEgo5 M+w@E`C ݢAh#%D_ud; C< 8q]'-iwiYr.KR޵\*פE>]erك\LKr<1{Y8sCc{Lb/lT?^uu]Z;\:KI46Ɓ| JJTT<e>sM= :8S@BFt_aEPWGOo8:_mFsToD-!x(@F$/| ~(#_{ zL< <'åMvb@ID +endstream +endobj +1892 0 obj << +/Type /Page +/Contents 1893 0 R +/Resources 1891 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1903 0 R +>> endobj +1894 0 obj << +/D [1892 0 R /XYZ 81.963 735.519 null] +>> endobj +618 0 obj << +/D [1892 0 R /XYZ 81.963 710.612 null] +>> endobj +1895 0 obj << +/D [1892 0 R /XYZ 81.963 602.27 null] +>> endobj +1896 0 obj << +/D [1892 0 R /XYZ 81.963 604.858 null] +>> endobj +622 0 obj << +/D [1892 0 R /XYZ 81.963 562.658 null] +>> endobj +1897 0 obj << +/D [1892 0 R /XYZ 81.963 449.341 null] +>> endobj +1898 0 obj << +/D [1892 0 R /XYZ 81.963 451.929 null] +>> endobj +626 0 obj << +/D [1892 0 R /XYZ 81.963 409.729 null] +>> endobj +1899 0 obj << +/D [1892 0 R /XYZ 81.963 296.412 null] +>> endobj +1900 0 obj << +/D [1892 0 R /XYZ 81.963 299 null] +>> endobj +630 0 obj << +/D [1892 0 R /XYZ 81.963 256.8 null] +>> endobj +1901 0 obj << +/D [1892 0 R /XYZ 81.963 143.483 null] +>> endobj +1902 0 obj << +/D [1892 0 R /XYZ 81.963 146.072 null] +>> endobj +1891 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1906 0 obj << +/Length 518 +/Filter /FlateDecode +>> +stream +xmSao0ίU\lcMTiRi[WM(8-RH!i p>=?#.IE(> ic*dM= )Yz_RoP0FJN5a<M#ڥrr3 +,ԟA%oU]:iIv7Y6xHf !\kJ=} 5wm>R0Ul y'F J!һ$+B!2KK^RDoȭ73ѠdN4#M]w}kGB1%aAh@PT>Gy}rgS&8#):?D6UWT.laJ5>z)!*W]Sա~۬ɺq3j")VY7uy081QӱS17@KC6L]fvc^J,F1w&8wMR*`ʙaf(zTt$NgJ'>Oe`ABV{,O@ΰ +endstream +endobj +1905 0 obj << +/Type /Page +/Contents 1906 0 R +/Resources 1904 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1903 0 R +>> endobj +1907 0 obj << +/D [1905 0 R /XYZ 123.806 735.519 null] +>> endobj +634 0 obj << +/D [1905 0 R /XYZ 123.806 710.612 null] +>> endobj +1908 0 obj << +/D [1905 0 R /XYZ 123.806 573.827 null] +>> endobj +1909 0 obj << +/D [1905 0 R /XYZ 123.806 576.416 null] +>> endobj +1904 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1912 0 obj << +/Length 587 +/Filter /FlateDecode +>> +stream +xՕQo0),@g[BHI 6fH ߭\"U^oMYp\-L%EpqIN gr\B%"A?~m 0o{@eUXELL}g{}|V?:d/<*Y)r$Y~zg OF%>X/~ԸO[z]W~wh$/\SRg +7E/)_b&Y_CebcwֻFHqc5+Fx_j }ب{-vX?`O([w)㈲QN]*PQ۹wFr̅۰27)_C7w8, { +a^m&muGc=AOMSLuQ?;:~jvWs9c/^HI3rd> +endstream +endobj +1911 0 obj << +/Type /Page +/Contents 1912 0 R +/Resources 1910 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1903 0 R +>> endobj +1913 0 obj << +/D [1911 0 R /XYZ 81.963 735.519 null] +>> endobj +638 0 obj << +/D [1911 0 R /XYZ 81.963 710.612 null] +>> endobj +642 0 obj << +/D [1911 0 R /XYZ 81.963 690.444 null] +>> endobj +646 0 obj << +/D [1911 0 R /XYZ 81.963 582.819 null] +>> endobj +650 0 obj << +/D [1911 0 R /XYZ 81.963 477.638 null] +>> endobj +654 0 obj << +/D [1911 0 R /XYZ 81.963 372.458 null] +>> endobj +1910 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1916 0 obj << +/Length 750 +/Filter /FlateDecode +>> +stream +xVmk0_!:Fm(:r :}b3$Nj;mɲ'dc)H>ɧG$' ?*b2jI +Cp##޻? c@c8 pA5 I$b)%>0 +Ac? z\1G^%n> c`)YD5ki\b7P/$_$;z7IA'@Ed4.Iq0*bMS",%'[KcMC-Ӧ˹U6{ RK_ld%?w:'[G!*Y>,R2D7->߮9ZEuDZ|6 SkgIfvNf9 zd,ʿ @&ulTYWY0VhqXZ + +Q*#MzX(j9Oٯ1{G׶1k* -;@QF#NychbF C4@ +t4/L1J)nfƳel?(ph"toUDEWcngծqK8.?Kru$ VΗ +Xx.p7gXѢrO3N0ǩQ&TG-롋"^9Ar[2~l0A"DjihEv^Yx#ZO`Xl yn/[ncYv7<yKғ@#ހoj] +endstream +endobj +1915 0 obj << +/Type /Page +/Contents 1916 0 R +/Resources 1914 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1903 0 R +>> endobj +1917 0 obj << +/D [1915 0 R /XYZ 123.806 735.519 null] +>> endobj +658 0 obj << +/D [1915 0 R /XYZ 123.806 710.612 null] +>> endobj +662 0 obj << +/D [1915 0 R /XYZ 123.806 687.521 null] +>> endobj +1918 0 obj << +/D [1915 0 R /XYZ 123.806 546.126 null] +>> endobj +1919 0 obj << +/D [1915 0 R /XYZ 123.806 548.714 null] +>> endobj +1920 0 obj << +/D [1915 0 R /XYZ 123.806 533.133 null] +>> endobj +1921 0 obj << +/D [1915 0 R /XYZ 123.806 517.551 null] +>> endobj +666 0 obj << +/D [1915 0 R /XYZ 123.806 469.455 null] +>> endobj +1922 0 obj << +/D [1915 0 R /XYZ 123.806 330.308 null] +>> endobj +1923 0 obj << +/D [1915 0 R /XYZ 123.806 332.896 null] +>> endobj +670 0 obj << +/D [1915 0 R /XYZ 123.806 284.8 null] +>> endobj +1924 0 obj << +/D [1915 0 R /XYZ 123.806 145.652 null] +>> endobj +1925 0 obj << +/D [1915 0 R /XYZ 123.806 148.241 null] +>> endobj +1914 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1928 0 obj << +/Length 822 +/Filter /FlateDecode +>> +stream +xŖ[k0+{`EK;[] :2<[2u0wd9:0l9ѹ|:5cT ?i5De*O-^ZힲRldh0D>G[l|O#JBn{}vO͙̔դI'L̕c)Y.-ثhu̥%Ԣl: (D0$'RRp~k돲+`%j:ooySM+=6pAϳQZ^xۯ:9厢X(\F0LJE4JwU+2EhG`4_dѴIc7lq©\9nb*#a9rIM)OXBVF%-&u`Xm&lztJ +"%PaP fm:*0"ǫo5q&a%[M* uDȿI[Tlw + 5q:ǐ#30\`gNˠϼ.Մ}rk|})c#8eY8b6qwH;(ם2 3#e{J )ch0L\RWbg| &嗅S +\`6&T*qCngQ mU0#.FU:u'?:$wΪ &0\ ]U'$i:!`n?fmWf9zYBjе> endobj +1929 0 obj << +/D [1927 0 R /XYZ 81.963 735.519 null] +>> endobj +674 0 obj << +/D [1927 0 R /XYZ 81.963 710.612 null] +>> endobj +1930 0 obj << +/D [1927 0 R /XYZ 81.963 573.827 null] +>> endobj +1931 0 obj << +/D [1927 0 R /XYZ 81.963 576.416 null] +>> endobj +678 0 obj << +/D [1927 0 R /XYZ 81.963 532.698 null] +>> endobj +1932 0 obj << +/D [1927 0 R /XYZ 81.963 389.953 null] +>> endobj +1933 0 obj << +/D [1927 0 R /XYZ 81.963 392.541 null] +>> endobj +1934 0 obj << +/D [1927 0 R /XYZ 81.963 376.959 null] +>> endobj +1935 0 obj << +/D [1927 0 R /XYZ 81.963 361.378 null] +>> endobj +682 0 obj << +/D [1927 0 R /XYZ 81.963 317.66 null] +>> endobj +1936 0 obj << +/D [1927 0 R /XYZ 81.963 191.527 null] +>> endobj +1937 0 obj << +/D [1927 0 R /XYZ 81.963 194.115 null] +>> endobj +1926 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1940 0 obj << +/Length 533 +/Filter /FlateDecode +>> +stream +xmSmk0_!؇_1k +xۇR(vҵ,qB0Os>(՗fg>9NP$ *lnEJjy(iN¯'P@7٬l-{)/l(z;X ~mI "]u'G7TYl))I^X +,.[WEPw t$q8c DR FWe432sdgb> endobj +1941 0 obj << +/D [1939 0 R /XYZ 123.806 735.519 null] +>> endobj +686 0 obj << +/D [1939 0 R /XYZ 123.806 710.612 null] +>> endobj +690 0 obj << +/D [1939 0 R /XYZ 123.806 690.444 null] +>> endobj +1942 0 obj << +/D [1939 0 R /XYZ 123.806 559.78 null] +>> endobj +1943 0 obj << +/D [1939 0 R /XYZ 123.806 562.368 null] +>> endobj +1938 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1946 0 obj << +/Length 772 +/Filter /FlateDecode +>> +stream +xŖYo@+WQA)=a7=ֱ-Ej&)")w#۩%Qeaafv[D c!?C,IBDJܠ P$h|(ЈRd( ˀk$A.%O !p4<et ٶdJap\}]bgg_{REu9VԺps2\ZbN59%p̵BJⰕStl|p &L1euR*Ao_>Рim1c1;]2&HQWiv=]%pΖQn aU+^<.]04qyRrMaeT8ƣҽ[,1I%IivqQꪀ Bm0&O=&ݟSdg5/!V,lpDQЅw-:.s +3 n bjj9+זL3!Ri!k3ki 34ĩ@.ebJ5x$zA$g~mKYVC($L P +jW]@%NP+i5*1,] ަ=D'K-Zj]ĤB 2k᳂ɩ3À>Ifw {U{?V.K;Jm8bOoea8K;T̷22ʬ5yg(3w^Vck > endobj +1947 0 obj << +/D [1945 0 R /XYZ 81.963 735.519 null] +>> endobj +694 0 obj << +/D [1945 0 R /XYZ 81.963 710.612 null] +>> endobj +698 0 obj << +/D [1945 0 R /XYZ 81.963 689.618 null] +>> endobj +1948 0 obj << +/D [1945 0 R /XYZ 81.963 542.122 null] +>> endobj +1949 0 obj << +/D [1945 0 R /XYZ 81.963 544.711 null] +>> endobj +702 0 obj << +/D [1945 0 R /XYZ 81.963 495.331 null] +>> endobj +1950 0 obj << +/D [1945 0 R /XYZ 81.963 335.755 null] +>> endobj +1951 0 obj << +/D [1945 0 R /XYZ 81.963 338.343 null] +>> endobj +706 0 obj << +/D [1945 0 R /XYZ 81.963 288.963 null] +>> endobj +1952 0 obj << +/D [1945 0 R /XYZ 81.963 145.999 null] +>> endobj +1953 0 obj << +/D [1945 0 R /XYZ 81.963 148.587 null] +>> endobj +1944 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1957 0 obj << +/Length 913 +/Filter /FlateDecode +>> +stream +xՖmo6SًJL$[lnX - +Ŧ3Jv`wQlIUk#w-IA8E&"F*ʤ6l\O~YMW:&4VՖ0M"S\*F!c,Xi8y{ +"KVՋT]}n ZkߏyPIqL2'1\MMN +:TT@LF680*bCCs"]J +3 FH:6T6Neuq2)6u']IF0LžKuv`4JbU4m )A4VilqH[A:xk Aw[l{"KFȭ^~7ϴB@Ù`&xn4*xTZm˛Ƀ錰! !9F\˻$gi]4|_ +ң"ŷ"=n%Ume 5CnY ]sԯų텷^3p-6Cdt"K!lw nlЫW!8,EjScq{ 0֘K+M+9`? +k*[Ϧ8l!<$#wR,Z`\eU;i*B܀CAcIENQ5p2j6Es PGMjxt>[DS-tmZ4;/dz 3߰|N'32`E*dpx} +aHY}'q~#9NS,R:[zaF ?}+7ȘLD@y7uSxdG;&dw&iy4QpDLZ_ӛ}p汬/-5k>? +endstream +endobj +1956 0 obj << +/Type /Page +/Contents 1957 0 R +/Resources 1955 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1954 0 R +>> endobj +1958 0 obj << +/D [1956 0 R /XYZ 123.806 735.519 null] +>> endobj +710 0 obj << +/D [1956 0 R /XYZ 123.806 710.612 null] +>> endobj +1959 0 obj << +/D [1956 0 R /XYZ 123.806 596.22 null] +>> endobj +1960 0 obj << +/D [1956 0 R /XYZ 123.806 598.808 null] +>> endobj +714 0 obj << +/D [1956 0 R /XYZ 123.806 557.964 null] +>> endobj +1961 0 obj << +/D [1956 0 R /XYZ 123.806 439.477 null] +>> endobj +1962 0 obj << +/D [1956 0 R /XYZ 123.806 442.065 null] +>> endobj +718 0 obj << +/D [1956 0 R /XYZ 123.806 401.22 null] +>> endobj +1963 0 obj << +/D [1956 0 R /XYZ 123.806 299.346 null] +>> endobj +1964 0 obj << +/D [1956 0 R /XYZ 123.806 301.934 null] +>> endobj +722 0 obj << +/D [1956 0 R /XYZ 123.806 261.09 null] +>> endobj +1965 0 obj << +/D [1956 0 R /XYZ 123.806 142.603 null] +>> endobj +1966 0 obj << +/D [1956 0 R /XYZ 123.806 145.191 null] +>> endobj +1955 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1969 0 obj << +/Length 1517 +/Filter /FlateDecode +>> +stream +xڵWmo6_!`&5C^u@E +,ZS[L7Ze)v#ԋX pD?|(<%Yd 4N8hU~[PH狧:H.DlÄ́)If$mr(͋u,+,#QbA.WB(+bqY`\6l-gyPo`c/Jx_Ca+shWʼn? g1q2'3C"kuuWhfadYJ.*_>+ 0^tyU]e$<[gѩ))aCYq.$'sg|mz^[ڞluʢCR;h + +6=~eUaCO.a GK&(M,?;VmJD +ww~G?Xf6Q]@ O+@f*v7 Hpd{ftnx3#aE,!fQVypOesQ!2hw" N`lӒP͹'ӌ1IY#:Cސ|bs\"b',ObWx0ٓC4Xy6\):&@L]1HVIwFSDd&Q&, 4gG >)a:(nT @ 5~e?2=mq *H +oD!n[֘:d9IxFCh ڙ!:1~M^=?%n+7&<߈%4&wW(uOCDO8Ir>0LC[>@<8k>2 ף)<"2!7]gcE_+\GfG 9Vah +;|ozUֲӥR4ۦ +H!9u$2Bq.1Z")EZEXݫoe\Fw$*2 p_$IijB%MȶJq'4sJ1(rd H ܙ0 y:dʌu^c-zMfM*ZU[] rzGn좔L8rrȥQN]I>7?0ެ" +endstream +endobj +1968 0 obj << +/Type /Page +/Contents 1969 0 R +/Resources 1967 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1954 0 R +>> endobj +1970 0 obj << +/D [1968 0 R /XYZ 81.963 735.519 null] +>> endobj +726 0 obj << +/D [1968 0 R /XYZ 81.963 710.612 null] +>> endobj +730 0 obj << +/D [1968 0 R /XYZ 81.963 689.593 null] +>> endobj +734 0 obj << +/D [1968 0 R /XYZ 81.963 656.618 null] +>> endobj +1971 0 obj << +/D [1968 0 R /XYZ 81.963 439.012 null] +>> endobj +1972 0 obj << +/D [1968 0 R /XYZ 81.963 441.6 null] +>> endobj +1973 0 obj << +/D [1968 0 R /XYZ 81.963 426.019 null] +>> endobj +1974 0 obj << +/D [1968 0 R /XYZ 81.963 410.437 null] +>> endobj +1975 0 obj << +/D [1968 0 R /XYZ 81.963 394.856 null] +>> endobj +1976 0 obj << +/D [1968 0 R /XYZ 81.963 379.274 null] +>> endobj +1977 0 obj << +/D [1968 0 R /XYZ 81.963 363.693 null] +>> endobj +1978 0 obj << +/D [1968 0 R /XYZ 81.963 348.111 null] +>> endobj +1979 0 obj << +/D [1968 0 R /XYZ 81.963 332.53 null] +>> endobj +1967 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F86 1494 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1983 0 obj << +/Length 1220 +/Filter /FlateDecode +>> +stream +xڵWko6_!t"͇(Q0 qԅeS k@eG,~"%Kx͆ Dǹ7_ blH ?Ǟ pW8Fkظ],zK7A>X B5<#!VG`D-`y "ZZ6\XYay[oR!u`-@ /=RBvqĈo,/1__˭[w<Ƽw-wx;xHp$} K*M$l،"Ι)J~qoBauUw21)ezKjslIFLW{)\}^ѳ"VYr䯇ֆLr ԢZ3T6icBviV+uJ(&"Ѯ-,1*ŦI^6[nq`I99W?QmɄp`09^sa"G^On*0^nn,v4lpJ0dDK4}Ĵx:ztjݗj2*]U"\|h&(血S !I e(($?>O>Q4E T-"S}B'hʎuV +J+L}_4M,?PZ5kjUծ[@jZgCgrY y h] ee8]CiR-Cvfh*gi s7PeSuTAXgmn rY頋V| zYeȁ/1v"D(?" + vi_ _='VCi |םRFF.+xn n[0~j#H _!þj*>6W2D-M ˕ujNЇ,bΕ +|]LW ðPJ|a`ga֞$h öc]fa9xR MC + ¨A@O擮A +C.8x^]MxfyOt[qyI_tz?f{v|f[s1@ )<gͦ'f o }|spb +Dyf/ d</Nj_62(`r(`@)i> endobj +1980 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [122.809 436.363 234.921 448.905] +/Subtype/Link/A<> +>> endobj +1984 0 obj << +/D [1982 0 R /XYZ 123.806 735.519 null] +>> endobj +738 0 obj << +/D [1982 0 R /XYZ 123.806 710.612 null] +>> endobj +1985 0 obj << +/D [1982 0 R /XYZ 123.806 573.827 null] +>> endobj +1986 0 obj << +/D [1982 0 R /XYZ 123.806 396.693 null] +>> endobj +1987 0 obj << +/D [1982 0 R /XYZ 123.806 399.281 null] +>> endobj +1988 0 obj << +/D [1982 0 R /XYZ 123.806 383.699 null] +>> endobj +742 0 obj << +/D [1982 0 R /XYZ 123.806 339.981 null] +>> endobj +1989 0 obj << +/D [1982 0 R /XYZ 123.806 225.804 null] +>> endobj +1981 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R /F86 1494 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1992 0 obj << +/Length 1233 +/Filter /FlateDecode +>> +stream +xڭVmo6_A`&3WÀSt%6- +EfbJrEҶ\e["Qt oP8ĒQ"!1A$P }@@7׳I#Jq,%C0(1d{CJ."щ;Yan7M72IZU?RzKMd62tgZbNc?4`G\!0^y^Q@cA8 o˵0Uգ4:^|yx{tӔ}Q:= NN' L2/ ǍMԐBIiaeZM^FPX`kw,J9h(!u S,,Kgy9m=^Iry-7s@Y/P(8(kg=Syc=*y0"]YDo5?ͦt`T56"s6[g[:zESZϤwP]Hǘkym$wy_/!\nwA>3?r.//UҝƧĒr `Px࢙ˢnҢ?z?!!Db~" =0Jp=f ]FAϒϥw|gah^NX6;yy<V3>oz;l1k[IKOg l妩4 bRuq6?{&6Ztxd.ͺ ꥵ%}D%aw-;=[2Wc>nMu]y7J["J +57V8:+ȴOZtȳŁmeO_)uxp`d0o +}S̹tJ+.0꒬-l݆0G.ӳ3vŰKE] 2|у I(;-O7álT6wV_6,SNy-S A>~ vFz+ׂߴi̅Z2Rct.4a_HT)i~΋y滓>4;6vrf Y-NPxaSi=- ܟ=>ĥ;H_`@@"3aɎBs34z}v:A :&[2Pdoy#M,զ]Sd}J)aNl:6k&hH vT]z. +endstream +endobj +1991 0 obj << +/Type /Page +/Contents 1992 0 R +/Resources 1990 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 1954 0 R +>> endobj +1993 0 obj << +/D [1991 0 R /XYZ 81.963 735.519 null] +>> endobj +746 0 obj << +/D [1991 0 R /XYZ 81.963 642.963 null] +>> endobj +1994 0 obj << +/D [1991 0 R /XYZ 81.963 504.11 null] +>> endobj +750 0 obj << +/D [1991 0 R /XYZ 81.963 310.81 null] +>> endobj +1995 0 obj << +/D [1991 0 R /XYZ 81.963 171.957 null] +>> endobj +1990 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F44 1108 0 R /F43 1107 0 R /F82 1445 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +1998 0 obj << +/Length 718 +/Filter /FlateDecode +>> +stream +xڭT[k0~a6,.,1 +Katexrj;t;4I2ґ}|(2O$RR$*DFs#p3s Oe(ű %sDNJH+k̂%S]ɳ` ˴u&Pl20!W"uok]kf.-wxmc[~ i»%h`+^-.rX/ۋv׭U +K9%WUK:orvߙA3z֙2F/ +ͽ[,u+#=KʝkJg%U;v@p?$Ds0ŲKxڔUz[y{YAp(&[g 6s/>Aʻճle9wt_ ;`;Nm)b,źpd J=[sv-zX4)`٬#h QCI.fY>4TAGMQ +cݔ:'yvBC!A4i>~}\ n E#6'b`z"1ny( %7_@50O +cC%\Mӟ$? +(~e *  f-{{duP_N(V;*˱e~ahb> endobj +1999 0 obj << +/D [1997 0 R /XYZ 123.806 735.519 null] +>> endobj +754 0 obj << +/D [1997 0 R /XYZ 123.806 661.972 null] +>> endobj +2000 0 obj << +/D [1997 0 R /XYZ 123.806 523.118 null] +>> endobj +1996 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2003 0 obj << +/Length 1021 +/Filter /FlateDecode +>> +stream +xڵmo6W؇DU"a9A "30$w|"+Ny-DGx=<2=G"#u%ITX t~P$|f<5k)\#bQ5Vg>)YD2X/N׋3!3R It1I[|riK kbgԹKSr#A[{ZOND\$Oeǃf!WqI0¼Lk|LVuv˫m"̏v_4[L.'M9hʴwW Ɍ$,IפU[謁!O4aAluS!b(hS}Oߥi#Q?4@ufn$(V71ULh>F+ߦ BmTiY}g~rwkz[Qvj.$IXp8`jW&gx8qzXZ :Y]RJbu% 8r euM~`_gzb'&-Tc&y Ec;h|+-:paE}W7 !p!p!pB6oL֍ pzV)9'LJp0$zc;L=,ӿi}ʋa'1[|!o"4*V5f:!(W7Jb5F?]aN\"!|H{>$uwdD`$X*nmyhwBh5tt2 }K,pW׿-\'_5& " Lj4d'+Ҷ=<#~x>>cE;%(,Jxq-01]CwL~H6<.VR> endobj +2004 0 obj << +/D [2002 0 R /XYZ 81.963 735.519 null] +>> endobj +758 0 obj << +/D [2002 0 R /XYZ 81.963 710.612 null] +>> endobj +762 0 obj << +/D [2002 0 R /XYZ 81.963 690.298 null] +>> endobj +766 0 obj << +/D [2002 0 R /XYZ 81.963 540.581 null] +>> endobj +770 0 obj << +/D [2002 0 R /XYZ 81.963 395.777 null] +>> endobj +2005 0 obj << +/D [2002 0 R /XYZ 81.963 222.647 null] +>> endobj +2006 0 obj << +/D [2002 0 R /XYZ 81.963 225.235 null] +>> endobj +2007 0 obj << +/D [2002 0 R /XYZ 81.963 209.653 null] +>> endobj +2008 0 obj << +/D [2002 0 R /XYZ 81.963 194.072 null] +>> endobj +2009 0 obj << +/D [2002 0 R /XYZ 81.963 178.49 null] +>> endobj +2010 0 obj << +/D [2002 0 R /XYZ 81.963 162.909 null] +>> endobj +2011 0 obj << +/D [2002 0 R /XYZ 81.963 147.327 null] +>> endobj +2001 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R /F86 1494 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2015 0 obj << +/Length 731 +/Filter /FlateDecode +>> +stream +xڵV]o0}WX6iekJ&}iQV4YՏU˱9 .>B5"p4$2A Lx,9 +@ AGǥ7;SD)Nrhİ$1JXU3!% UeuWA /&|iY۪68_؆Qa{_eV鷁~k_yxt̅nK`FSW9A #Y*Z!s }Nп'88]pq.K +"7PFpV-xR$+ES?J2q?4) ?TPYݟ V!2f5q]>f mi[]s5ꩆ@ 3ANZQ Jt e2`*=~W ȁn:Ӱwt,A ațkunzvH8f I4@=~41 __Ag +endstream +endobj +2014 0 obj << +/Type /Page +/Contents 2015 0 R +/Resources 2013 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 2012 0 R +>> endobj +2016 0 obj << +/D [2014 0 R /XYZ 123.806 735.519 null] +>> endobj +774 0 obj << +/D [2014 0 R /XYZ 123.806 710.612 null] +>> endobj +778 0 obj << +/D [2014 0 R /XYZ 123.806 607.219 null] +>> endobj +782 0 obj << +/D [2014 0 R /XYZ 123.806 466.297 null] +>> endobj +786 0 obj << +/D [2014 0 R /XYZ 123.806 327.821 null] +>> endobj +790 0 obj << +/D [2014 0 R /XYZ 123.806 215.38 null] +>> endobj +2013 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2019 0 obj << +/Length 1420 +/Filter /FlateDecode +>> +stream +xX[o6~ڃ͐Uk҇eqۺ:t}e1 K.튡}7ERqb A+#ϕS@ex$R@10el?&qrjrQ@86P044BJS6)O\,/\v~1zud2T +YdzE*-8Vqę\&&l%Q'?`sh/sP؊3 +,x;H!9W(,˼z*ω@?CFn!v4uJ,I3l|jG[)J33lBzpX1^`4T..&ᖧBc#eGv{G0?Fڠ*LKƺ(; ~9\9핮d+hyd#…%Y&#wuh[^ٺ*?+rݏ3S(T:&P /F"͎\R#jSPP *z+y_=H=F #(=L}W K#tX;g@͋I@_n:MrݽQ3轩x魨$Ӣt&P}>a ]o]I:08oxdg:VUl~հPn *z+yL'kuc ;vT~ǎ*;vz.=O7`3k?&OnV{B1%-wO?ug!_#:t|)EᑼqR +endstream +endobj +2018 0 obj << +/Type /Page +/Contents 2019 0 R +/Resources 2017 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 2012 0 R +>> endobj +2020 0 obj << +/D [2018 0 R /XYZ 81.963 735.519 null] +>> endobj +794 0 obj << +/D [2018 0 R /XYZ 81.963 710.612 null] +>> endobj +2021 0 obj << +/D [2018 0 R /XYZ 81.963 573.931 null] +>> endobj +2022 0 obj << +/D [2018 0 R /XYZ 81.963 576.519 null] +>> endobj +2023 0 obj << +/D [2018 0 R /XYZ 81.963 524.993 null] +>> endobj +2024 0 obj << +/D [2018 0 R /XYZ 81.963 527.581 null] +>> endobj +2025 0 obj << +/D [2018 0 R /XYZ 81.963 443.861 null] +>> endobj +2026 0 obj << +/D [2018 0 R /XYZ 81.963 446.45 null] +>> endobj +2027 0 obj << +/D [2018 0 R /XYZ 81.963 430.868 null] +>> endobj +2028 0 obj << +/D [2018 0 R /XYZ 81.963 415.287 null] +>> endobj +2029 0 obj << +/D [2018 0 R /XYZ 81.963 399.705 null] +>> endobj +2030 0 obj << +/D [2018 0 R /XYZ 81.963 384.124 null] +>> endobj +2031 0 obj << +/D [2018 0 R /XYZ 81.963 368.542 null] +>> endobj +2032 0 obj << +/D [2018 0 R /XYZ 81.963 352.961 null] +>> endobj +2033 0 obj << +/D [2018 0 R /XYZ 81.963 337.379 null] +>> endobj +2034 0 obj << +/D [2018 0 R /XYZ 81.963 321.798 null] +>> endobj +2035 0 obj << +/D [2018 0 R /XYZ 81.963 306.216 null] +>> endobj +798 0 obj << +/D [2018 0 R /XYZ 81.963 211.801 null] +>> endobj +2017 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F83 1447 0 R /F86 1494 0 R /F44 1108 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2038 0 obj << +/Length 940 +/Filter /FlateDecode +>> +stream +xڭVK6WPs%(z hѴ랒V*^JJߡHy-Ai'0ly|3'D#|_aAwC[i_ȌM79$h {襁"ԏK@?-[]ğӨ(,RfCQ)TDݏQ.3椭ꍍM֣/Tv,w4X:ot[NI􋶕 +5MM2K8|C6Y׈&&LN8̒eV$Yd}"0q?Œ>MU '䲬\@N}rF'8qBL'6tz*oMX}mPUo uO !\*@yr~?F8W= + '\S(ͪ~Bw<wK783/s:3@gM#kyu*<#a  xI5 0YhR͐8z +I~Y7v.> endobj +2039 0 obj << +/D [2037 0 R /XYZ 123.806 735.519 null] +>> endobj +802 0 obj << +/D [2037 0 R /XYZ 123.806 710.612 null] +>> endobj +806 0 obj << +/D [2037 0 R /XYZ 123.806 602.791 null] +>> endobj +810 0 obj << +/D [2037 0 R /XYZ 123.806 482.44 null] +>> endobj +814 0 obj << +/D [2037 0 R /XYZ 123.806 342.352 null] +>> endobj +818 0 obj << +/D [2037 0 R /XYZ 123.806 224.59 null] +>> endobj +2036 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2042 0 obj << +/Length 854 +/Filter /FlateDecode +>> +stream +xڵVێ6}WC%*@Q uAhwOAhި(.-_ߑH@0Lg.g4'D#"&N$Cgc)5n0lWO+:KO%T^}HPg\+Y#మj?' +2 8vc&froƽUxߕ.I +h?߬Giwܽg6}8/0fNIm1b*#[x}ԁ4qAXft&m}7{gH35=aTx}7**;/4ϙz/D땍xKx҇xL'hgvԹCF!4) ~a(L%i ls]o\n.^\OzD47'1ө.\QoCe^yUO3X{HB1g%7JR,(%WIйʘ{m޾Z+:NıcAsvӛU;v<\_Q^ζcIKr#9$_2ߍW5}D vyQW ^5\*8nFNCU(4כ'o?V-+,/S'vykDH SI*.&q ^e.5f$;@$mo5'Qwyi,5lLa NCDC-uTfم| m +endstream +endobj +2041 0 obj << +/Type /Page +/Contents 2042 0 R +/Resources 2040 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 2012 0 R +>> endobj +2043 0 obj << +/D [2041 0 R /XYZ 81.963 735.519 null] +>> endobj +822 0 obj << +/D [2041 0 R /XYZ 81.963 710.612 null] +>> endobj +826 0 obj << +/D [2041 0 R /XYZ 81.963 578.163 null] +>> endobj +830 0 obj << +/D [2041 0 R /XYZ 81.963 460.401 null] +>> endobj +834 0 obj << +/D [2041 0 R /XYZ 81.963 342.496 null] +>> endobj +838 0 obj << +/D [2041 0 R /XYZ 81.963 241.203 null] +>> endobj +2040 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2046 0 obj << +/Length 1327 +/Filter /FlateDecode +>> +stream +xڵXmo6_A`&Q" @-E + ,3VIv$]0(RR'ZR'<:Q F"'Ted(0 #ZkیB^^%EX Pr(X\aiDKޣ3?Ji0A«OE4?&o؅eRbpjnSv66ia f$l;z ̩BY9{%|Jq8KY k#%q$⭵:rE6յτSC^ef N>\ᛳ=ȱzHn!Q.6_UV.VMPv99Y׹1Ovu*]qU*[vv*qy,A1^Ƭi+iSY֝'ӈ﹑8"|WmMScܣ]*m 2Eڌfyq`ت Ymf{nuZٕ٪ja hH#Q,^szpxc Ei+qJKݬ @MIbi{e%hǁ#b% x #ÞLBsz|La42ɭ a-DOݒfj~'@f&9B{"q&) A]طZX':`XI86G<9;2Y(a{1i0(##H1`CUGh]jzR{lnQ/FN}b1.¾3uy>YxD 8--][a0Ӯrk7ؖ79P9G!#{C  :S1^4wcYfNCfjVٱ}"oZ;뼷=dև)UnӮXtuyM3m%p:-vٵC5ղS 0./yݺW)r?׏|e, + o= +6]>vn;EFO[ +endstream +endobj +2045 0 obj << +/Type /Page +/Contents 2046 0 R +/Resources 2044 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 2012 0 R +>> endobj +2047 0 obj << +/D [2045 0 R /XYZ 123.806 735.519 null] +>> endobj +842 0 obj << +/D [2045 0 R /XYZ 123.806 710.612 null] +>> endobj +846 0 obj << +/D [2045 0 R /XYZ 123.806 606.201 null] +>> endobj +850 0 obj << +/D [2045 0 R /XYZ 123.806 483.252 null] +>> endobj +2048 0 obj << +/D [2045 0 R /XYZ 123.806 359.144 null] +>> endobj +2049 0 obj << +/D [2045 0 R /XYZ 123.806 361.732 null] +>> endobj +2050 0 obj << +/D [2045 0 R /XYZ 123.806 346.15 null] +>> endobj +2051 0 obj << +/D [2045 0 R /XYZ 123.806 330.569 null] +>> endobj +2052 0 obj << +/D [2045 0 R /XYZ 123.806 314.987 null] +>> endobj +2053 0 obj << +/D [2045 0 R /XYZ 123.806 299.406 null] +>> endobj +2054 0 obj << +/D [2045 0 R /XYZ 123.806 283.824 null] +>> endobj +2055 0 obj << +/D [2045 0 R /XYZ 123.806 268.243 null] +>> endobj +854 0 obj << +/D [2045 0 R /XYZ 123.806 226.997 null] +>> endobj +2044 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F86 1494 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2058 0 obj << +/Length 917 +/Filter /FlateDecode +>> +stream +xڵVY6~ ЇJ@%Cd[䡮wѠ SYc:6:5ٖѐf(wA~BgXLeHq Π=uE AwW7R#J"E{@ eLce5;.$N(!$n7oכ[..L©^e8I~Mu,D7y3故XmWWԹKϦfT^{O^#VٝS3+GjȦxpj"^WyTDslBU%A K#}U6E5LH|sBk;!X ^~I*q[iKQ@ApI$AUzɥ26@7džC;~8 yUWѫ<]x˺b +ي9Fͦq zg}h&pC:+t3iضǥQ1?K cVgݜP;dJ8$vS;Bv^>Cfbl?[]g'EE55>wsܶc,9SIˌ}e 8ɜ_g%y֯\'nEja3T+* 慐+:otw'b.uK Ow X@FY2n[Jk-44S>C!׭\O/ j`5Y=Pƒɉ߉ cXJc_=0 CYX#(gcO O\B Y Z` +endstream +endobj +2057 0 obj << +/Type /Page +/Contents 2058 0 R +/Resources 2056 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 2064 0 R +>> endobj +2059 0 obj << +/D [2057 0 R /XYZ 81.963 735.519 null] +>> endobj +858 0 obj << +/D [2057 0 R /XYZ 81.963 710.612 null] +>> endobj +862 0 obj << +/D [2057 0 R /XYZ 81.963 557.663 null] +>> endobj +2060 0 obj << +/D [2057 0 R /XYZ 81.963 412.832 null] +>> endobj +2061 0 obj << +/D [2057 0 R /XYZ 81.963 415.42 null] +>> endobj +2062 0 obj << +/D [2057 0 R /XYZ 81.963 399.838 null] +>> endobj +2063 0 obj << +/D [2057 0 R /XYZ 81.963 384.257 null] +>> endobj +2056 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2067 0 obj << +/Length 931 +/Filter /FlateDecode +>> +stream +xW[o6~ J(L.xR >2 %GlV LK(zwB~ɰ$ΐ@C;ۂ"A?o[eHf(X2n-PYmyd$ˤq.nJ۶M?m>n21S޺M*e:C,~,4BG~I̩A~A[xFq%sт|&Ze4V2;Gy=yֻ0Kf0QzYo.rڥL&ud`uؼSj~(\8(f y~86> endobj +2068 0 obj << +/D [2066 0 R /XYZ 123.806 735.519 null] +>> endobj +866 0 obj << +/D [2066 0 R /XYZ 123.806 710.612 null] +>> endobj +870 0 obj << +/D [2066 0 R /XYZ 123.806 688.16 null] +>> endobj +874 0 obj << +/D [2066 0 R /XYZ 123.806 577.007 null] +>> endobj +878 0 obj << +/D [2066 0 R /XYZ 123.806 449.402 null] +>> endobj +882 0 obj << +/D [2066 0 R /XYZ 123.806 321.797 null] +>> endobj +886 0 obj << +/D [2066 0 R /XYZ 123.806 231.804 null] +>> endobj +2065 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2071 0 obj << +/Length 1022 +/Filter /FlateDecode +>> +stream +xڵWێ6}WCyMtk/6Hi<IPh%-o,AP;)[v]4W0lp<(רB>j,6!1)2"Hd4+(VJ2Uinq(ǔggW}b2?`jJ1$zSc)ڏJmt&FdaD[w~i9([޾'(^ 5cBC~r*0+x0%ѧ{vS-b&f6«eZEB s%{Whpdnر% We-9wn/'W7:<%ý$6db ƒAPTM|wDmPV? @bqlH'/6wt4Se^gmnS[8ݟ^oY>8CE8#qKpISS +&;%#W}c 1UXQ[> 1.'/lSNfS,`ݱvGVWm( +C;BX{]@F[#~wNQ]NњJ, m/O-(̳bJL<"{r[s+}۷aj9ᗆOl-<ղפ+:d9F`M>g|twLof^%7?:;šK H /H( + +$ SPLœ,һ2{pԩlAϾr/\s:PGCYM +瑸 +7zL7@v^~ŏwyobjbO]UV@~  s> +endstream +endobj +2070 0 obj << +/Type /Page +/Contents 2071 0 R +/Resources 2069 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 2064 0 R +>> endobj +2072 0 obj << +/D [2070 0 R /XYZ 81.963 735.519 null] +>> endobj +890 0 obj << +/D [2070 0 R /XYZ 81.963 710.612 null] +>> endobj +894 0 obj << +/D [2070 0 R /XYZ 81.963 687.021 null] +>> endobj +2073 0 obj << +/D [2070 0 R /XYZ 81.963 505.553 null] +>> endobj +2074 0 obj << +/D [2070 0 R /XYZ 81.963 508.141 null] +>> endobj +2075 0 obj << +/D [2070 0 R /XYZ 81.963 492.559 null] +>> endobj +2076 0 obj << +/D [2070 0 R /XYZ 81.963 476.978 null] +>> endobj +2077 0 obj << +/D [2070 0 R /XYZ 81.963 461.396 null] +>> endobj +2078 0 obj << +/D [2070 0 R /XYZ 81.963 445.815 null] +>> endobj +2079 0 obj << +/D [2070 0 R /XYZ 81.963 430.233 null] +>> endobj +2080 0 obj << +/D [2070 0 R /XYZ 81.963 414.652 null] +>> endobj +2081 0 obj << +/D [2070 0 R /XYZ 81.963 399.07 null] +>> endobj +2082 0 obj << +/D [2070 0 R /XYZ 81.963 383.489 null] +>> endobj +2083 0 obj << +/D [2070 0 R /XYZ 81.963 367.907 null] +>> endobj +2084 0 obj << +/D [2070 0 R /XYZ 81.963 352.326 null] +>> endobj +2085 0 obj << +/D [2070 0 R /XYZ 81.963 336.744 null] +>> endobj +898 0 obj << +/D [2070 0 R /XYZ 81.963 288.548 null] +>> endobj +902 0 obj << +/D [2070 0 R /XYZ 81.963 173.867 null] +>> endobj +2069 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F86 1494 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2088 0 obj << +/Length 955 +/Filter /FlateDecode +>> +stream +xڽX[O0}ﯰ4i4u}&1hH@+!kSԦhgiT%dB%n|9>9> >(CXm42Bb"(Ott$y((VJcDdž(Ɲ.%G=J"CwIctdY>,+OMHbp?r233%bII-_lO\sӡ݀&1 FpBk/u8Id1 +jt1_}W#]- 2bI0IUq+Wlq_ZV,C6Údz"IXDVu| ;@B5ZNʾ Bdno*=^ @NwEX#r|RkM4Lh㥟m*vR^j,iv۶]8duS2eJTIa>>CCkQ;QNbI;K֛Tuڀ{ૠj5_Y@ +endstream +endobj +2087 0 obj << +/Type /Page +/Contents 2088 0 R +/Resources 2086 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 2064 0 R +>> endobj +2089 0 obj << +/D [2087 0 R /XYZ 123.806 735.519 null] +>> endobj +2090 0 obj << +/D [2087 0 R /XYZ 123.806 663.437 null] +>> endobj +2091 0 obj << +/D [2087 0 R /XYZ 123.806 666.025 null] +>> endobj +2092 0 obj << +/D [2087 0 R /XYZ 123.806 650.444 null] +>> endobj +2093 0 obj << +/D [2087 0 R /XYZ 123.806 634.862 null] +>> endobj +2094 0 obj << +/D [2087 0 R /XYZ 123.806 619.281 null] +>> endobj +2095 0 obj << +/D [2087 0 R /XYZ 123.806 603.699 null] +>> endobj +2096 0 obj << +/D [2087 0 R /XYZ 123.806 588.118 null] +>> endobj +2097 0 obj << +/D [2087 0 R /XYZ 123.806 572.536 null] +>> endobj +2098 0 obj << +/D [2087 0 R /XYZ 123.806 556.955 null] +>> endobj +2099 0 obj << +/D [2087 0 R /XYZ 123.806 541.373 null] +>> endobj +2100 0 obj << +/D [2087 0 R /XYZ 123.806 525.792 null] +>> endobj +2101 0 obj << +/D [2087 0 R /XYZ 123.806 510.21 null] +>> endobj +2102 0 obj << +/D [2087 0 R /XYZ 123.806 494.629 null] +>> endobj +906 0 obj << +/D [2087 0 R /XYZ 123.806 453.949 null] +>> endobj +2103 0 obj << +/D [2087 0 R /XYZ 123.806 348.431 null] +>> endobj +2104 0 obj << +/D [2087 0 R /XYZ 123.806 351.02 null] +>> endobj +2105 0 obj << +/D [2087 0 R /XYZ 123.806 335.438 null] +>> endobj +2106 0 obj << +/D [2087 0 R /XYZ 123.806 319.857 null] +>> endobj +2107 0 obj << +/D [2087 0 R /XYZ 123.806 304.275 null] +>> endobj +910 0 obj << +/D [2087 0 R /XYZ 123.806 263.595 null] +>> endobj +2108 0 obj << +/D [2087 0 R /XYZ 123.806 158.078 null] +>> endobj +2109 0 obj << +/D [2087 0 R /XYZ 123.806 160.666 null] +>> endobj +2110 0 obj << +/D [2087 0 R /XYZ 123.806 145.085 null] +>> endobj +2086 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F83 1447 0 R /F82 1445 0 R /F86 1494 0 R /F43 1107 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2113 0 obj << +/Length 910 +/Filter /FlateDecode +>> +stream +xW[O0~ﯰZ_! !mIYHm +I&N^8}||E{D#ƒh@iE` AGAWQ @SqŦ6%.%ς~p|8 :^_̔n|vL,J:R3>Lp +usjp: h#59EC{>@C<`UpѢ}{|ꂪ-",{/d8NWop%_,9fAǐ"06Ȣ4Y .)3~v#^Ml- k}u9ZcUzPG$w70`K,]J<8 hTgv13oy6G(<|^7a{Eke5xJʍ l$O   f d/Lft6V4eI[Kj q40kw qɰt> endobj +2114 0 obj << +/D [2112 0 R /XYZ 81.963 735.519 null] +>> endobj +914 0 obj << +/D [2112 0 R /XYZ 81.963 710.612 null] +>> endobj +2115 0 obj << +/D [2112 0 R /XYZ 81.963 594.727 null] +>> endobj +2116 0 obj << +/D [2112 0 R /XYZ 81.963 597.315 null] +>> endobj +2117 0 obj << +/D [2112 0 R /XYZ 81.963 581.734 null] +>> endobj +2118 0 obj << +/D [2112 0 R /XYZ 81.963 566.153 null] +>> endobj +2119 0 obj << +/D [2112 0 R /XYZ 81.963 550.571 null] +>> endobj +2120 0 obj << +/D [2112 0 R /XYZ 81.963 534.99 null] +>> endobj +918 0 obj << +/D [2112 0 R /XYZ 81.963 491.983 null] +>> endobj +2121 0 obj << +/D [2112 0 R /XYZ 81.963 370.599 null] +>> endobj +2122 0 obj << +/D [2112 0 R /XYZ 81.963 373.187 null] +>> endobj +2123 0 obj << +/D [2112 0 R /XYZ 81.963 357.606 null] +>> endobj +2124 0 obj << +/D [2112 0 R /XYZ 81.963 342.024 null] +>> endobj +2125 0 obj << +/D [2112 0 R /XYZ 81.963 326.443 null] +>> endobj +2126 0 obj << +/D [2112 0 R /XYZ 81.963 310.861 null] +>> endobj +2127 0 obj << +/D [2112 0 R /XYZ 81.963 295.28 null] +>> endobj +2128 0 obj << +/D [2112 0 R /XYZ 81.963 279.698 null] +>> endobj +922 0 obj << +/D [2112 0 R /XYZ 81.963 236.692 null] +>> endobj +2111 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F83 1447 0 R /F86 1494 0 R /F44 1108 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2131 0 obj << +/Length 1141 +/Filter /FlateDecode +>> +stream +xڽYnF}W,P +hKFb4@UiX XCJI -ҺasZΙ93(+T!?j,6!1T@Ft5e>VQ Ddž(M-1%O2O OLUW٦\Wa>k|+y]eߛH9nYѫz8ĜZX h _A5_B6e`^LYan3E+J, xocol]+k:cde };)ʰex=6X::pL *f_xeMl?E +@)Mp4VA@4zlƌ4KJ_AwweQ0| {4œjZu*7姼LgBʻ Bx!Se"e! kє􇸮/"Fe'by\ͳ14{r +ƂՏ1.u &0>ʂçA&D3)9" K t&i0VL͘w$z3HS d(}BȻU"ASH}ژ]m=/-\6_FD: EeT'Wμʮw??/b, ׯExƺv n'(_>oP4*Ńp0Դ<,H\`fjmU%La +3N6 Qqj&D.'zRA$9IP)̪ ȪPL@"Vp+|'pj6

> endobj +2132 0 obj << +/D [2130 0 R /XYZ 123.806 735.519 null] +>> endobj +2133 0 obj << +/D [2130 0 R /XYZ 123.806 710.612 null] +>> endobj +2134 0 obj << +/D [2130 0 R /XYZ 123.806 714.238 null] +>> endobj +2135 0 obj << +/D [2130 0 R /XYZ 123.806 698.657 null] +>> endobj +2136 0 obj << +/D [2130 0 R /XYZ 123.806 683.075 null] +>> endobj +2137 0 obj << +/D [2130 0 R /XYZ 123.806 667.494 null] +>> endobj +2138 0 obj << +/D [2130 0 R /XYZ 123.806 651.912 null] +>> endobj +2139 0 obj << +/D [2130 0 R /XYZ 123.806 636.331 null] +>> endobj +2140 0 obj << +/D [2130 0 R /XYZ 123.806 620.749 null] +>> endobj +2141 0 obj << +/D [2130 0 R /XYZ 123.806 605.168 null] +>> endobj +2142 0 obj << +/D [2130 0 R /XYZ 123.806 589.586 null] +>> endobj +2143 0 obj << +/D [2130 0 R /XYZ 123.806 574.005 null] +>> endobj +2144 0 obj << +/D [2130 0 R /XYZ 123.806 558.423 null] +>> endobj +2145 0 obj << +/D [2130 0 R /XYZ 123.806 542.842 null] +>> endobj +926 0 obj << +/D [2130 0 R /XYZ 123.806 497.757 null] +>> endobj +2146 0 obj << +/D [2130 0 R /XYZ 123.806 367.539 null] +>> endobj +2147 0 obj << +/D [2130 0 R /XYZ 123.806 370.128 null] +>> endobj +2148 0 obj << +/D [2130 0 R /XYZ 123.806 354.546 null] +>> endobj +2149 0 obj << +/D [2130 0 R /XYZ 123.806 338.965 null] +>> endobj +2150 0 obj << +/D [2130 0 R /XYZ 123.806 323.383 null] +>> endobj +2151 0 obj << +/D [2130 0 R /XYZ 123.806 307.802 null] +>> endobj +2152 0 obj << +/D [2130 0 R /XYZ 123.806 292.22 null] +>> endobj +2153 0 obj << +/D [2130 0 R /XYZ 123.806 276.639 null] +>> endobj +2154 0 obj << +/D [2130 0 R /XYZ 123.806 261.057 null] +>> endobj +2155 0 obj << +/D [2130 0 R /XYZ 123.806 245.476 null] +>> endobj +2156 0 obj << +/D [2130 0 R /XYZ 123.806 229.894 null] +>> endobj +2157 0 obj << +/D [2130 0 R /XYZ 123.806 214.313 null] +>> endobj +2158 0 obj << +/D [2130 0 R /XYZ 123.806 198.731 null] +>> endobj +2159 0 obj << +/D [2130 0 R /XYZ 123.806 183.15 null] +>> endobj +2160 0 obj << +/D [2130 0 R /XYZ 123.806 167.568 null] +>> endobj +2161 0 obj << +/D [2130 0 R /XYZ 123.806 151.987 null] +>> endobj +2162 0 obj << +/D [2130 0 R /XYZ 123.806 136.405 null] +>> endobj +2129 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F83 1447 0 R /F82 1445 0 R /F86 1494 0 R /F43 1107 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2165 0 obj << +/Length 934 +/Filter /FlateDecode +>> +stream +xڽXMoFW,ЃI5dZ8zJr$& )%pIZ-rv7C}an}2饽ͭ) \X {?ⴐѯx^khh$҃fdJ9FpaLʤh=./r[/# qk =[F?s1;-1I[i%iexUgx މjjG:Ð;4ށѶlFt?![> endobj +2166 0 obj << +/D [2164 0 R /XYZ 81.963 735.519 null] +>> endobj +2167 0 obj << +/D [2164 0 R /XYZ 81.963 714.238 null] +>> endobj +2168 0 obj << +/D [2164 0 R /XYZ 81.963 698.657 null] +>> endobj +930 0 obj << +/D [2164 0 R /XYZ 81.963 656.93 null] +>> endobj +2169 0 obj << +/D [2164 0 R /XYZ 81.963 544.274 null] +>> endobj +2170 0 obj << +/D [2164 0 R /XYZ 81.963 546.863 null] +>> endobj +2171 0 obj << +/D [2164 0 R /XYZ 81.963 531.281 null] +>> endobj +2172 0 obj << +/D [2164 0 R /XYZ 81.963 515.7 null] +>> endobj +2173 0 obj << +/D [2164 0 R /XYZ 81.963 500.118 null] +>> endobj +2174 0 obj << +/D [2164 0 R /XYZ 81.963 484.537 null] +>> endobj +2175 0 obj << +/D [2164 0 R /XYZ 81.963 468.955 null] +>> endobj +934 0 obj << +/D [2164 0 R /XYZ 81.963 427.228 null] +>> endobj +2176 0 obj << +/D [2164 0 R /XYZ 81.963 314.573 null] +>> endobj +2177 0 obj << +/D [2164 0 R /XYZ 81.963 317.161 null] +>> endobj +2178 0 obj << +/D [2164 0 R /XYZ 81.963 301.579 null] +>> endobj +2179 0 obj << +/D [2164 0 R /XYZ 81.963 285.998 null] +>> endobj +2180 0 obj << +/D [2164 0 R /XYZ 81.963 270.416 null] +>> endobj +2181 0 obj << +/D [2164 0 R /XYZ 81.963 254.835 null] +>> endobj +2182 0 obj << +/D [2164 0 R /XYZ 81.963 239.253 null] +>> endobj +2183 0 obj << +/D [2164 0 R /XYZ 81.963 223.672 null] +>> endobj +2184 0 obj << +/D [2164 0 R /XYZ 81.963 208.09 null] +>> endobj +2185 0 obj << +/D [2164 0 R /XYZ 81.963 192.509 null] +>> endobj +2186 0 obj << +/D [2164 0 R /XYZ 81.963 176.927 null] +>> endobj +2187 0 obj << +/D [2164 0 R /XYZ 81.963 161.346 null] +>> endobj +2188 0 obj << +/D [2164 0 R /XYZ 81.963 145.764 null] +>> endobj +2163 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F86 1494 0 R /F43 1107 0 R /F82 1445 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2192 0 obj << +/Length 909 +/Filter /FlateDecode +>> +stream +xWYH~ϯhqX F$$v>΃;ĒvT8!,ډBQ|TWWWu3QXm42Bb"9#HjRQ 62 QHse&Bܐ]>_0Ii/:.˴n~zrl0.o/R&]xֻt&foV3QhsjѺ;Zx +q%} ƔE̗_i3`qyeA fГ^ ҥszyS.sxa@[o6v#mjX-h1Wm~F>4%aꛯiuW8z{,;I14;N4NyD30`K,MhD+>,K^)LAJqC3H Q'H @˰Em.<~!EX9kŒOM88Ķn10ӄϠNBj~zAlXf@-/ +=7(,W.5̚p ƴ Y[o_ +̂:IP}K)ة]z#ϩ>\!!\1l>xs{66vFQyNYh,*q1v9|uUg}O{34GE)2q3+j |irb:Ԍ6Ra2>%`*h}NIr.R@t!$mmvuVy9 ҶUk.PGf)#RVHiYYpz,|3* 8BwIrJMY6nƗ CeY!3|D +taԁ;I +endstream +endobj +2191 0 obj << +/Type /Page +/Contents 2192 0 R +/Resources 2190 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 2189 0 R +>> endobj +2193 0 obj << +/D [2191 0 R /XYZ 123.806 735.519 null] +>> endobj +938 0 obj << +/D [2191 0 R /XYZ 123.806 710.612 null] +>> endobj +942 0 obj << +/D [2191 0 R /XYZ 123.806 613.379 null] +>> endobj +2194 0 obj << +/D [2191 0 R /XYZ 123.806 485.061 null] +>> endobj +2195 0 obj << +/D [2191 0 R /XYZ 123.806 487.649 null] +>> endobj +2196 0 obj << +/D [2191 0 R /XYZ 123.806 472.067 null] +>> endobj +2197 0 obj << +/D [2191 0 R /XYZ 123.806 456.486 null] +>> endobj +2198 0 obj << +/D [2191 0 R /XYZ 123.806 440.904 null] +>> endobj +2199 0 obj << +/D [2191 0 R /XYZ 123.806 425.323 null] +>> endobj +2200 0 obj << +/D [2191 0 R /XYZ 123.806 409.741 null] +>> endobj +2201 0 obj << +/D [2191 0 R /XYZ 123.806 394.16 null] +>> endobj +2202 0 obj << +/D [2191 0 R /XYZ 123.806 378.578 null] +>> endobj +2203 0 obj << +/D [2191 0 R /XYZ 123.806 362.997 null] +>> endobj +2204 0 obj << +/D [2191 0 R /XYZ 123.806 347.415 null] +>> endobj +2205 0 obj << +/D [2191 0 R /XYZ 123.806 331.834 null] +>> endobj +2206 0 obj << +/D [2191 0 R /XYZ 123.806 316.252 null] +>> endobj +946 0 obj << +/D [2191 0 R /XYZ 123.806 272.534 null] +>> endobj +2190 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F83 1447 0 R /F86 1494 0 R /F44 1108 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2209 0 obj << +/Length 860 +/Filter /FlateDecode +>> +stream +xڭ]S@; ,Mvm3,j: BTژ(U}OiY<=gC}D»"D%q-0iInЗ +5*~Zw+!oÑə4(1-J1^zg^'պ-֯dRb8t~?0-&q6 &{4ya +Mӥ+*4\^4N\IμGP0QίeE9Jb%"I(eyk/As#LKEn]2 ٛoPs\r,*3rU@UPU{kSse +SĢq5ZγjayAW040 { 5mH5߾.-ۑQIv5OKPVNf5(]nz(~`zi9YfpLkfϴ\ J/^,H2d.V.*昊g-mZ-L:\ !Gp>;@I՚M>nʗ9Je|So^ flQ0yp| +~LS3_g0Bt;f EM +8"Uf5]M}sr]d|~_^`w鮂"A6Y"p7fYdiN{BmU^P~ߒ3"Z nnBJ%` +endstream +endobj +2208 0 obj << +/Type /Page +/Contents 2209 0 R +/Resources 2207 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 2189 0 R +>> endobj +2210 0 obj << +/D [2208 0 R /XYZ 81.963 735.519 null] +>> endobj +2211 0 obj << +/D [2208 0 R /XYZ 81.963 710.612 null] +>> endobj +950 0 obj << +/D [2208 0 R /XYZ 81.963 292.018 null] +>> endobj +2212 0 obj << +/D [2208 0 R /XYZ 81.963 164.98 null] +>> endobj +2213 0 obj << +/D [2208 0 R /XYZ 81.963 167.568 null] +>> endobj +2214 0 obj << +/D [2208 0 R /XYZ 81.963 151.987 null] +>> endobj +2215 0 obj << +/D [2208 0 R /XYZ 81.963 136.405 null] +>> endobj +2207 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F44 1108 0 R /F82 1445 0 R /F83 1447 0 R /F86 1494 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2218 0 obj << +/Length 468 +/Filter /FlateDecode +>> +stream +xڥSM0W yd}xDK Ѕ–eكIdm#ˡvC1͛- 9@Ԗ4t[>QzcH)1r=<J"!_OU _ñk؆M]}'mz9#\xļ;7e󣯺UbL܇e{.k}.H5#tkG=/3t2Zq\OL#^uJ8|1pFo@ɹ֑&zCw A87K#Isx}? +VCW9 {W{"%07kNdT!Fh jlR2Gkmν))\{9P%+~y9a +]}O> endobj +2219 0 obj << +/D [2217 0 R /XYZ 123.806 735.519 null] +>> endobj +2220 0 obj << +/D [2217 0 R /XYZ 123.806 714.238 null] +>> endobj +2221 0 obj << +/D [2217 0 R /XYZ 123.806 698.657 null] +>> endobj +954 0 obj << +/D [2217 0 R /XYZ 123.806 654.939 null] +>> endobj +2216 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F83 1447 0 R /F82 1445 0 R /F86 1494 0 R /F43 1107 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2224 0 obj << +/Length 758 +/Filter /FlateDecode +>> +stream +xŖo0+,aiCӤRU]=U}@"H!~Iݦ(sxD{ +De9%$I*VG`"AτDby+)ĉDw>%Blz3LxaPD8r]WM|5CPu]Vv?]lyGIֵAP¢zMYc16!+~ {쳖x|]y~rO"8eЙXsK +SwU*ET5>! +T!]QӢLͶ{{L+d +oWF)m4Rv4JiUJ] nC* B?jʍ5:/XP_ZJcMR vFncC;2b+,wbVrLzd´ $qFpq9T:vqI jDJ/, ,=Iժe2YejX2;+zDU}H/$cPMĔrvObH>WrereڗZgMݮڳ8$h(@;ChnԓQ$ᔍIdo#{ +endstream +endobj +2223 0 obj << +/Type /Page +/Contents 2224 0 R +/Resources 2222 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 2189 0 R +>> endobj +2225 0 obj << +/D [2223 0 R /XYZ 81.963 735.519 null] +>> endobj +958 0 obj << +/D [2223 0 R /XYZ 81.963 710.612 null] +>> endobj +962 0 obj << +/D [2223 0 R /XYZ 81.963 687.675 null] +>> endobj +966 0 obj << +/D [2223 0 R /XYZ 81.963 587.602 null] +>> endobj +970 0 obj << +/D [2223 0 R /XYZ 81.963 473.038 null] +>> endobj +974 0 obj << +/D [2223 0 R /XYZ 81.963 370.197 null] +>> endobj +978 0 obj << +/D [2223 0 R /XYZ 81.963 253.331 null] +>> endobj +2222 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2228 0 obj << +/Length 865 +/Filter /FlateDecode +>> +stream +xVMoFW,CɃQ$9vMʡ0r M@"RJ]m" 7o0r R? (j!V*R[IO EGJ.&&'#Sْ0.RMp`iA3FASF).ioۺɧ\j[ܥ,*kOOm}}8y/6ZZbqݺHk>5W*kǢbr>|x6'ן)YBA8Kk"p/%WjpzLGz1j{va0f +eG-ckgA+\#($X% +F,,5 +XjK:Mi {4!{q`h<9 +5Ф(xNMiۣY-:rK;*WLJԩI}/9?\fEL b -jSW6<{u~BW-ܾ{n(NR#Eml {V lɷږM妩wd(?ߖ9W]DײvA;p@^} +" uf^c-e]+ hv曽=m뮣A(ohM.Lg?כ-~"Ìj\rvNy`\t> endobj +2229 0 obj << +/D [2227 0 R /XYZ 123.806 735.519 null] +>> endobj +2230 0 obj << +/D [2227 0 R /XYZ 123.806 710.612 null] +>> endobj +2231 0 obj << +/D [2227 0 R /XYZ 123.806 714.238 null] +>> endobj +2232 0 obj << +/D [2227 0 R /XYZ 123.806 698.657 null] +>> endobj +2233 0 obj << +/D [2227 0 R /XYZ 123.806 683.075 null] +>> endobj +2234 0 obj << +/D [2227 0 R /XYZ 123.806 667.494 null] +>> endobj +2235 0 obj << +/D [2227 0 R /XYZ 123.806 651.912 null] +>> endobj +2236 0 obj << +/D [2227 0 R /XYZ 123.806 636.331 null] +>> endobj +2237 0 obj << +/D [2227 0 R /XYZ 123.806 620.749 null] +>> endobj +982 0 obj << +/D [2227 0 R /XYZ 123.806 572.101 null] +>> endobj +986 0 obj << +/D [2227 0 R /XYZ 123.806 439.792 null] +>> endobj +990 0 obj << +/D [2227 0 R /XYZ 123.806 305.254 null] +>> endobj +2238 0 obj << +/D [2227 0 R /XYZ 123.806 145.802 null] +>> endobj +2239 0 obj << +/D [2227 0 R /XYZ 123.806 148.39 null] +>> endobj +2226 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F83 1447 0 R /F82 1445 0 R /F43 1107 0 R /F44 1108 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2242 0 obj << +/Length 691 +/Filter /FlateDecode +>> +stream +x͕o0+,a`O֒je-{>Dh!MJtڴTrw}G UGK)!11h : >hhD)R2ϑ3(+)uHISBHx$nXa&S +D@.i^NI~kM&2li.l ˃vۥKK̩Fep}CP#VWD@W~D+ȴ }O&*4煙f*#JŸtW'( ]売-օJ&c.´'5r(aczfڶn`+䬪.eLkUY:ϴrףvl}`8 f,\𼩗piL:ӜfZ]\lLP/]ݖ+,0v%/fSY˻y =H:K +We%*T{@@ZLA! %(twZf!JQշ[P B9!˛ts_4C30j`dgpf3| 9f9w,>ᬆ8mEyࣙaZ0[^ 4('Q/OfK}&3r`PcBt xg);rdNj~ *( t{Mc +endstream +endobj +2241 0 obj << +/Type /Page +/Contents 2242 0 R +/Resources 2240 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 2250 0 R +>> endobj +2243 0 obj << +/D [2241 0 R /XYZ 81.963 735.519 null] +>> endobj +994 0 obj << +/D [2241 0 R /XYZ 81.963 710.612 null] +>> endobj +2244 0 obj << +/D [2241 0 R /XYZ 81.963 558.636 null] +>> endobj +2245 0 obj << +/D [2241 0 R /XYZ 81.963 561.224 null] +>> endobj +998 0 obj << +/D [2241 0 R /XYZ 81.963 511.802 null] +>> endobj +2246 0 obj << +/D [2241 0 R /XYZ 81.963 352.323 null] +>> endobj +2247 0 obj << +/D [2241 0 R /XYZ 81.963 354.911 null] +>> endobj +1002 0 obj << +/D [2241 0 R /XYZ 81.963 305.489 null] +>> endobj +2248 0 obj << +/D [2241 0 R /XYZ 81.963 146.011 null] +>> endobj +2249 0 obj << +/D [2241 0 R /XYZ 81.963 148.599 null] +>> endobj +2240 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2253 0 obj << +/Length 731 +/Filter /FlateDecode +>> +stream +xݖ]o0z10SKSUUM(8R-Э;NJ8$w ~HE~TP-e2֒4@F΂Y^ue,n/muXby8?# 4ὯehW K48C?ՅiwtS1d$.Nj) ;W UuGviMՕՍo+?0(ʇE8Y\YY*4ˁǦ5~𺩷}x{+ +P&Ih2[]z3і~bCmݖUOXD|{1o8m׳GCm{RR]Xlǀ(44j +23MY +cȔLLt~\QŬ +D#:ŌΪ(Vsbg?)^ XBjt ק zDmln;i1~i1,c {e88>T\?.2$ ^n|A +˼^,qZv튲7U<^xUӘ}rb\L jvY蛟 h> endobj +2254 0 obj << +/D [2252 0 R /XYZ 123.806 735.519 null] +>> endobj +1006 0 obj << +/D [2252 0 R /XYZ 123.806 710.612 null] +>> endobj +2255 0 obj << +/D [2252 0 R /XYZ 123.806 562.471 null] +>> endobj +2256 0 obj << +/D [2252 0 R /XYZ 123.806 565.059 null] +>> endobj +1010 0 obj << +/D [2252 0 R /XYZ 123.806 517.087 null] +>> endobj +2257 0 obj << +/D [2252 0 R /XYZ 123.806 361.836 null] +>> endobj +2258 0 obj << +/D [2252 0 R /XYZ 123.806 364.424 null] +>> endobj +1014 0 obj << +/D [2252 0 R /XYZ 123.806 316.452 null] +>> endobj +2259 0 obj << +/D [2252 0 R /XYZ 123.806 161.2 null] +>> endobj +2260 0 obj << +/D [2252 0 R /XYZ 123.806 163.789 null] +>> endobj +2261 0 obj << +/D [2252 0 R /XYZ 123.806 148.207 null] +>> endobj +2251 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2264 0 obj << +/Length 819 +/Filter /FlateDecode +>> +stream +x͖o0WX)"?c!$IeжqGDlI 9ΚCUm.w;;XaIVH @A3GI`ňRKd4GX[MJ!%|xv8LNFBg218'Wd2Iʔ/R{?MU2.zIGswuCP +c'`k\ KIAF<ߎ'5jSm.26]fJo[m8i^3,wY>R3#f`\IiY +yᮛEp'(VD,,` L;Ir'uX%:0&m`20 +#S3—Y79NJ23u9, !pD}*[a5st!q1Y:02ir"L +Om &*ԴS908j -/k֒MMu,+/&C'_IYzvxiq1︀=v +endstream +endobj +2263 0 obj << +/Type /Page +/Contents 2264 0 R +/Resources 2262 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 2250 0 R +>> endobj +2265 0 obj << +/D [2263 0 R /XYZ 81.963 735.519 null] +>> endobj +1018 0 obj << +/D [2263 0 R /XYZ 81.963 710.612 null] +>> endobj +2266 0 obj << +/D [2263 0 R /XYZ 81.963 558.636 null] +>> endobj +2267 0 obj << +/D [2263 0 R /XYZ 81.963 561.224 null] +>> endobj +1022 0 obj << +/D [2263 0 R /XYZ 81.963 511.802 null] +>> endobj +2268 0 obj << +/D [2263 0 R /XYZ 81.963 352.323 null] +>> endobj +2269 0 obj << +/D [2263 0 R /XYZ 81.963 354.911 null] +>> endobj +1026 0 obj << +/D [2263 0 R /XYZ 81.963 305.489 null] +>> endobj +2270 0 obj << +/D [2263 0 R /XYZ 81.963 146.011 null] +>> endobj +2271 0 obj << +/D [2263 0 R /XYZ 81.963 148.599 null] +>> endobj +2262 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2274 0 obj << +/Length 823 +/Filter /FlateDecode +>> +stream +x͕O0WXÒ>řI/ iFQB6 ;%) js9|wso +0,&%F*ʤ6TLɷCCF_@gfJqO pA $5N5!0*cieoXt\^cZ;/e~4:Cx&ݢ{k[}j(s1hr9bpq"31](`#{o^gj>fO /WEڛyx5E܏m݆ލH"8\(Y9Mt|rasrbkzy]NM I8\Nlmլ=D4v2̸r(qBM$٪c%9sXIs'9wO(G97inWASa^8`~0B#`zm{cxw![h<_-\#Eu4fӡ>?br--x4ϵ,p>Ϊ {@QmpOv­SJ؀9,Wܩ o7=iއl|YiEԋ8a ޛ1z|2;ϑ`%̄gJ~ +endstream +endobj +2273 0 obj << +/Type /Page +/Contents 2274 0 R +/Resources 2272 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 2250 0 R +>> endobj +2275 0 obj << +/D [2273 0 R /XYZ 123.806 735.519 null] +>> endobj +1030 0 obj << +/D [2273 0 R /XYZ 123.806 710.612 null] +>> endobj +2276 0 obj << +/D [2273 0 R /XYZ 123.806 558.636 null] +>> endobj +2277 0 obj << +/D [2273 0 R /XYZ 123.806 561.224 null] +>> endobj +1034 0 obj << +/D [2273 0 R /XYZ 123.806 511.802 null] +>> endobj +2278 0 obj << +/D [2273 0 R /XYZ 123.806 352.323 null] +>> endobj +2279 0 obj << +/D [2273 0 R /XYZ 123.806 354.911 null] +>> endobj +1038 0 obj << +/D [2273 0 R /XYZ 123.806 305.489 null] +>> endobj +2280 0 obj << +/D [2273 0 R /XYZ 123.806 146.011 null] +>> endobj +2281 0 obj << +/D [2273 0 R /XYZ 123.806 148.599 null] +>> endobj +2272 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2284 0 obj << +/Length 870 +/Filter /FlateDecode +>> +stream +xUKo@W[}x_qҊ +R©p0Z$vNy{fn6"z@Qڝ\ GQZ!] +LJK,Zw3^,f{ J +iJ7X{IN3JBd~rZbɴL88_n`dzBd}h,%f4%ur3;waܫ& +&$lxp޾f;*Q.ח B;puᦅp\b떶;6$Bk:mm/QRq}d<ƅYbh_Y7xMjs9~TUyfsمoڗݦF-r(y7[AX!0!` +ffڜPDp2߃e&D%ha^> +,4 ajg<6΄0TG̵5RS=8kaEaBugpk&uzsT(TX=& +uqfݛ'F&j]MΒe%*[|[ŵtmnƁějT@Ffm}ض>2Nw»XF)0G߳n&7DBD20XW.\c>> endobj +2285 0 obj << +/D [2283 0 R /XYZ 81.963 735.519 null] +>> endobj +1042 0 obj << +/D [2283 0 R /XYZ 81.963 710.612 null] +>> endobj +2286 0 obj << +/D [2283 0 R /XYZ 81.963 572.362 null] +>> endobj +2287 0 obj << +/D [2283 0 R /XYZ 81.963 574.95 null] +>> endobj +1046 0 obj << +/D [2283 0 R /XYZ 81.963 530.716 null] +>> endobj +2288 0 obj << +/D [2283 0 R /XYZ 81.963 386.367 null] +>> endobj +2289 0 obj << +/D [2283 0 R /XYZ 81.963 388.955 null] +>> endobj +1050 0 obj << +/D [2283 0 R /XYZ 81.963 344.721 null] +>> endobj +1054 0 obj << +/D [2283 0 R /XYZ 81.963 223.734 null] +>> endobj +2282 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R /F83 1447 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2292 0 obj << +/Length 574 +/Filter /FlateDecode +>> +stream +x͔=o0w +* I(:4hd$:`I )$Ѯܡax>ψ^ J+K͑hn#]EhQʷf k"b!U̓Bg\WZ; {ߦ8ObWxo}r_\̏ɴƙx;)=u!b?? e=GtFg} +̨AeT׈`f4:6Y3whpX +=q ձjcO]eZaO*A{#afǏo_-r`Xp orZGm%Xk=NRFI޺:D%"U(w]AH%L6M=ŝ),8l¡d ePjRN0QbA.!|awCUQP?=6xkHTe?2mj}QuP6Ē`֔L>53k%V* Zt/~z"-<##Ȅp>X@wF$6q}!1p(ɿe +endstream +endobj +2291 0 obj << +/Type /Page +/Contents 2292 0 R +/Resources 2290 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 2250 0 R +>> endobj +2293 0 obj << +/D [2291 0 R /XYZ 123.806 735.519 null] +>> endobj +1058 0 obj << +/D [2291 0 R /XYZ 123.806 710.612 null] +>> endobj +1062 0 obj << +/D [2291 0 R /XYZ 123.806 613.379 null] +>> endobj +1066 0 obj << +/D [2291 0 R /XYZ 123.806 493.931 null] +>> endobj +2290 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R /F44 1108 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2296 0 obj << +/Length 811 +/Filter /FlateDecode +>> +stream +xڭko0+,Mju;cZzPi( BK.&}^?qs_$s8d eQ[P0TIدԚ0cP?m8qȯY!5wzg֤lu%lO]OY2zi1 I!*_yvRA +wt%(QcЭlBBUf|ٌ7=2IgXd *AжK!-vkAgŦjMam (YUwm5=0F1pCJgZ|k?d1rGII,|X2I&+0Gb`#qkHڑ:0NSwxH틠nbi]"ö]Obژlh4FCaoOC.aRdܞoWeA$K\5tPv+QޭB#8:%] wo8|ޅH_ ŽO:,]24$@O%AykzQV{vr!sTZ!/zHgzvntNh%[fuD-ah~6cY8Wx zWrg{%EaXԗQ\'W| +m9wt,{ǻH, URf*^er\ѢhGorl9k?ڪPx+jŜKT[XY0ۂ"&:avz봔_juJ*>!7ۛuY꒪Bfݒז7%bX +endstream +endobj +2295 0 obj << +/Type /Page +/Contents 2296 0 R +/Resources 2294 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 2299 0 R +>> endobj +2297 0 obj << +/D [2295 0 R /XYZ 81.963 735.519 null] +>> endobj +1070 0 obj << +/D [2295 0 R /XYZ 81.963 710.612 null] +>> endobj +1074 0 obj << +/D [2295 0 R /XYZ 81.963 690.415 null] +>> endobj +2298 0 obj << +/D [2295 0 R /XYZ 81.963 602.52 null] +>> endobj +2294 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2302 0 obj << +/Length 819 +/Filter /FlateDecode +>> +stream +xڥmo0S`0JJGCSU!8U4mBmnvr!0>s[} +Q e/0飕Bst!AN:_A?8l(X<ܚk,\B̕ĩ8Z7A-0)1 | ؾ{Yq&k +YQmҘYCnW.i A3)"G>D\uƝ?oE8đ>o܈iwT;պ)F3Rw+JGUըڈzhWD?!{6bg9<̌kKq/L<&O(nS,Sc"sovM!8yiC cuO3`j櫽 + Pjr~z]xiWp`͢( ǽyZ㾩]S')rԼؔ$bT600‘uRHjk=DfVeӐ#a=qL&_l7Kfз! bB Neq ǃ1$ +1$z\[x89 ZE Yۿ:O$\Li:OGn[V{UY<0ZU=h $K\/iQ^B{#BoT˺"v+/]j Col.۶1ӗȌE-S]9{2]^Nۚqp)ze Cf>}|7'O{@uLxbOq7t I +endstream +endobj +2301 0 obj << +/Type /Page +/Contents 2302 0 R +/Resources 2300 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 2299 0 R +>> endobj +2303 0 obj << +/D [2301 0 R /XYZ 123.806 735.519 null] +>> endobj +2300 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2306 0 obj << +/Length 847 +/Filter /FlateDecode +>> +stream +xڭWko0ί>LKV#NM40!졶X jsHh +Ř!9}=^S7A +xcClnn2L`8 1f(kX: M:=}pa!n ]ɻVg!Lax1v ֝'7:cڼxo(7Qqʴ'h)vոr~@_|;R1TGS_cCáiY;D1Ғp)mS{I$g4 `L\KI% a$6Ұ +66y䰷<[C>7hF9S ݚ rjs +˘~Xwc9ZֱnpjPh8 AdVd?zYLtRvTma.oNf}{%\,Z@Չ:(q<p͕l~" wbCge@|W&Zh&> endobj +2307 0 obj << +/D [2305 0 R /XYZ 81.963 735.519 null] +>> endobj +2304 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2310 0 obj << +/Length 789 +/Filter /FlateDecode +>> +stream +xڥS0WIba/Btam?~"m$y' ԷrD |9.&T +tND=HP;^(ŁZ_"j٘v٢i Jk6)!&#FݤyeC}lb [wٴ\b +Q1]רQ>M&!o4Q\lgMcD0s5ulu>EI/aF^pq3j^qw_3Q_\MϢԈŬ4)3D%r)&o(#V> 5jTo=._hJ0nT [z|1a~|(G(7MManfB wfiS 9Lʝe&;]%~!0fE\jK&]c5C~G1yxBR!Eץ2b=mQi!Rv& fLfchf^*v!󣒓h:Ot?6]5 +j +endstream +endobj +2309 0 obj << +/Type /Page +/Contents 2310 0 R +/Resources 2308 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 2299 0 R +>> endobj +2311 0 obj << +/D [2309 0 R /XYZ 123.806 735.519 null] +>> endobj +2308 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2314 0 obj << +/Length 816 +/Filter /FlateDecode +>> +stream +xڭ]S0o.@Bg-mJ26*c + e;N =9Oޓ@pþ}ckX 5ݴ R +3Ct@m[Ps06@p {\PWT5ȖDrr:s**+zCm K򠯰?bRXkVC˴8@Mp Š.Nܖ恰{J0DmE5]NXQ Pa(k{}$U4rÀ v'8ŁC-.Vt*!.x8YQo9N +Qkc+PUg#kxLS^7\p >.ڈ˵k7[Nn)ײ3>qV˗/-{W ZؠyJҐ>*˅kV7]M0ch&nȴ +endstream +endobj +2313 0 obj << +/Type /Page +/Contents 2314 0 R +/Resources 2312 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 2299 0 R +>> endobj +2315 0 obj << +/D [2313 0 R /XYZ 81.963 735.519 null] +>> endobj +2312 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2318 0 obj << +/Length 855 +/Filter /FlateDecode +>> +stream +xڭVn@}WZ6{aoUU)uH6!MJUQ{ZqXiNHieY,r̙=#~%GQZ! L|}Zt>l$!H(FDǚHi:`zD&֥ıI~>bi`p] \f6} +dyy }æ[!̩AE7GD07=..sXѸ$1!1i4BmìJmT;n}YNl-25iҚmq,afdZדpaJDPoh[|ΖweqsFU6In[_yЊ`ds33>܋?:F;CSHR "Zp\Nħv]w즩/z,9zp[1)Lm,'ak kj*,G2Zqj%Vm J:Wh<F,ƽQAwُoflvyܪL6ow&)VGkؼ}[xXdtTN?7QR<?lʛm}Bb кu?kTz=/jRy7S_ID ڲh3E/Ne^7Im=*/yFbw6y6o +ybL=l)hߛU +endstream +endobj +2317 0 obj << +/Type /Page +/Contents 2318 0 R +/Resources 2316 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 2299 0 R +>> endobj +2319 0 obj << +/D [2317 0 R /XYZ 123.806 735.519 null] +>> endobj +1078 0 obj << +/D [2317 0 R /XYZ 123.806 710.612 null] +>> endobj +2320 0 obj << +/D [2317 0 R /XYZ 123.806 645.135 null] +>> endobj +1082 0 obj << +/D [2317 0 R /XYZ 123.806 343.518 null] +>> endobj +2321 0 obj << +/D [2317 0 R /XYZ 123.806 267.405 null] +>> endobj +2316 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F82 1445 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2337 0 obj << +/Length 841 +/Filter /FlateDecode +>> +stream +xWn@}W[޽>%д)RidYI-aBӋMLVB{v̙;D |h|$@IG!ACĵ J!iT` ЬCIG !3p&ΨtwG!wW21S.cct.a+eg]/Er\΢9\ZbN 슠Csя2FBIz}*0j7e4VUQ4L8xL 14DPgٚIt˵w:BlxwJ_Œ /uxmccܞZg$b2Q.ȯp6 4eٟ3P|ښZAx-8 Z712P;JL3^%NkaFa[3"1 ,&`D4ldHM '9'kG9XJDAL0KFܢ δu ea!'ZeUXRӊ mjdzkVv-0y&IR´̶LM ,ju5V7?i=懽K?wɦnmPys)8}Kz(FթE;WNktER=P M{B/ȋ3hDp,L[՞ѰiZӖ&ҼaNJp/%v\ lvSŒ*χʓ{ P_8#o2Q᫻ÂNnQ-1-[4 2rzPDDeY[h8o(bIp3 +endstream +endobj +2336 0 obj << +/Type /Page +/Contents 2337 0 R +/Resources 2335 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 2339 0 R +/Annots [ 2322 0 R 2323 0 R 2324 0 R 2325 0 R 2326 0 R 2327 0 R 2328 0 R 2329 0 R 2330 0 R 2331 0 R 2332 0 R 2333 0 R ] +>> endobj +2322 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [423.243 646.858 466.855 658.478] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.2.5) >> +>> endobj +2323 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [409.073 584.358 466.855 594.008] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.8.1) >> +>> endobj +2324 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [409.073 532.806 466.855 542.008] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.8.1) >> +>> endobj +2325 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [409.073 486.415 466.855 496.066] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.8.1) >> +>> endobj +2326 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [428.24 423.409 466.855 433.059] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.10) >> +>> endobj +2327 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [428.24 406.796 466.855 418.62] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.10) >> +>> endobj +2328 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [354.031 390.599 401.174 402.007] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.11) >> +>> endobj +2329 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [402.768 390.599 466.855 402.007] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.12) >> +>> endobj +2330 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [434.306 373.986 466.855 385.394] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.15) >> +>> endobj +2331 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [377.017 230.946 412.667 240.597] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.13) >> +>> endobj +2332 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [414.261 230.946 466.855 240.597] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.14) >> +>> endobj +2333 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [412.627 134.209 466.855 146.538] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.17) >> +>> endobj +2338 0 obj << +/D [2336 0 R /XYZ 81.963 735.519 null] +>> endobj +1086 0 obj << +/D [2336 0 R /XYZ 81.963 710.612 null] +>> endobj +2335 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R /F44 1108 0 R /F82 1445 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2354 0 obj << +/Length 1146 +/Filter /FlateDecode +>> +stream +xXn"G}+-@e!r0 C1Miv]="Ee0]{݊i5De#4G+$ۨrq,[)e_3t[ZBZIR4ݍ>]\ L p?ٙ6IYf;t4G¦9sjr{G >֠o+^/Ѱ|@.fHi s̥G!wqqm*G+P*(zOZW[MR,*LAg÷ጆ82y1GdXmQw6%·wyVc$6;r&.kTV3ъΤĊ0œVRNqwϖZ=ob=OJ6ڽa08f )EGX/vvw$g8T*^;' UnÒ ,0[4\RdɎl/E%R&)+"ċIM>E!UCHY;B$y+Zƅf'΢>Kty0i[l(=Rչt> /=D}8%:>e󙯰0M)v^kAӛ + KǴCI'd!,JR,+3#DA\=$a\5oԶP'nutNF +(bwE7`=b"`D| `ӆ؉V y9^4 wq蠮)}'6xo 6n+S ΍^s5~ٚ@sJTIh~>lqXagz\O%0/QLdaOe4ڇy|oȃ|_ nw'uf r66_-Cw4,(.{M5/?Z?kMŰ~[!,s+ @Y*Gni*Lwee4Fڤ(I-'--~{<|b;S 15jc{X])xu1ű +]~ZkUt8S?n+{ )TJ1fŮp4GB) +endstream +endobj +2353 0 obj << +/Type /Page +/Contents 2354 0 R +/Resources 2352 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 2339 0 R +/Annots [ 2334 0 R 2340 0 R 2341 0 R 2342 0 R 2343 0 R 2344 0 R 2345 0 R 2346 0 R 2347 0 R 2348 0 R 2349 0 R 2350 0 R 2351 0 R ] +>> endobj +2334 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [450.916 679.323 508.698 688.973] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.8.1) >> +>> endobj +2340 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [451.8 603.626 508.698 615.45] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.26) >> +>> endobj +2341 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [463.755 494.199 508.698 506.528] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.4) >> +>> endobj +2342 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [459.013 477.587 508.698 489.916] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.27) >> +>> endobj +2343 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [454.893 460.974 508.698 473.303] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.22) >> +>> endobj +2344 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [444.723 444.361 508.698 456.69] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.20) >> +>> endobj +2345 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [446.931 427.749 508.698 440.078] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.19) >> +>> endobj +2346 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [464.64 335.44 508.698 347.769] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.2) >> +>> endobj +2347 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [460.663 243.131 508.698 255.46] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.23) >> +>> endobj +2348 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [458.901 226.518 508.698 238.847] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.24) >> +>> endobj +2349 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [456.678 209.906 508.698 222.234] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.34) >> +>> endobj +2350 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [457.124 193.293 508.698 205.622] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.21) >> +>> endobj +2351 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [457.124 176.68 508.698 189.009] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.21) >> +>> endobj +2355 0 obj << +/D [2353 0 R /XYZ 123.806 735.519 null] +>> endobj +2352 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F44 1108 0 R /F82 1445 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2367 0 obj << +/Length 977 +/Filter /FlateDecode +>> +stream +x͘Yo@)X۽M = N% E +$6R?|s#M +!ٝog!»KZ%F##$&B17,[)&Hs]4(eEKLf fJdl7$2^Z,. f\^"&F6$b&k?Dp3MC>"ҕH/jh &!!,fc<3!,^"f 6V^j?+ +W~]?78#/S+Vj'cE*L)H͔rUXBSCC g"c?ZUn(2`WL)VJL }b q ā16'z%`LhQ200O)E7^kvJ h"Mw[Cӈt# w̟KiikC>=nx:6n*ͫ+f +,; )X|T Hɦn4]\KkGzd@ {wv;k*0 erɡx-M'%MC0U!XCmFU$d)d$QNԲCk2gRqRjK4U9aVE]*2Ԛe'la ^GAeLE-;ǧ m&5|#INȠ\ 󯶄QQ g{lHoAAODX +endstream +endobj +2366 0 obj << +/Type /Page +/Contents 2367 0 R +/Resources 2365 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 2339 0 R +/Annots [ 2356 0 R 2357 0 R 2358 0 R 2359 0 R 2360 0 R 2361 0 R 2362 0 R 2363 0 R ] +>> endobj +2356 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [408.841 634.241 466.855 645.861] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.35) >> +>> endobj +2357 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [403.764 573.053 466.855 584.672] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.39) >> +>> endobj +2358 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [403.764 556.44 466.855 568.06] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.39) >> +>> endobj +2359 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [421.028 478.639 466.855 490.968] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.28) >> +>> endobj +2360 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [413.504 400.838 466.855 413.167] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.18) >> +>> endobj +2361 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [413.504 323.037 466.855 335.366] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.18) >> +>> endobj +2362 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [413.504 245.236 466.855 257.564] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.18) >> +>> endobj +2363 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [413.504 134.209 466.855 146.538] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.18) >> +>> endobj +2368 0 obj << +/D [2366 0 R /XYZ 81.963 735.519 null] +>> endobj +2365 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F44 1108 0 R /F82 1445 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2378 0 obj << +/Length 798 +/Filter /FlateDecode +>> +stream +xWMO@W!n{*4DPJ0EbJNlxM젶";yoƻwk؜!}:˜Ҁ8Ų bY/M},b\HphK6lqpDl;Bcgq>OwF΁0}?>ƅ${ֺu_0?I7M$b ϑ]C crV4yJ,HP)F xh%Luy. G֖5n\K揥M +(j1|j,`fa$;IGQ4'1 +m;TiۥY2‚SE\RJaO!l^B|薑~Ȇ(c;I܅, 4] )]͜q:󖇘D~NBUi{.3O p'^>Emڂ Y8Zl04kqW=f_/[]lvo 5TVהZ Yi؆ږ8pb{R?v^;!ɴͲ*\mQ]Q3h!2-ilM-,As2׍j*YG!F.B?T4muV 5sٮikC;,&o;_ `S :_jmiuOӃq,U`E8£Q;a'^';_9L4WOfՐ5򦲡aVi1NGw(&0Ox +endstream +endobj +2377 0 obj << +/Type /Page +/Contents 2378 0 R +/Resources 2376 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 2339 0 R +/Annots [ 2364 0 R 2369 0 R 2370 0 R 2371 0 R 2372 0 R 2373 0 R 2374 0 R ] +>> endobj +2364 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [455.347 662.205 508.698 674.533] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.18) >> +>> endobj +2369 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [455.347 584.403 508.698 596.732] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.18) >> +>> endobj +2370 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [455.347 506.602 508.698 518.931] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.18) >> +>> endobj +2371 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [455.347 428.801 508.698 441.13] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.18) >> +>> endobj +2372 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [455.347 351 508.698 363.329] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.18) >> +>> endobj +2373 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [455.347 273.199 508.698 285.528] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.18) >> +>> endobj +2374 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [455.355 195.398 508.698 207.727] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.25) >> +>> endobj +2379 0 obj << +/D [2377 0 R /XYZ 123.806 735.519 null] +>> endobj +2376 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F44 1108 0 R /F82 1445 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2388 0 obj << +/Length 949 +/Filter /FlateDecode +>> +stream +xXnF}W[%}Bh׉..AT.\H-Jh3$S Ha9s93'~Ȓ0QPŌ5JEVUD!#W(xuN)NFGm͌Ԁ pZavեTOrk)Ӈmz+VꧺRxwwL DRw!;ZQ-[Ffx aT8KI-DQJ +axIIQRiO:gWy z?#G}6>b;kG;YNWK(}i99uT=꿝4^.>a,;LXX?5@hE蓩Cm]uRB* ;N9Idv5dld FPť l9xnh99>h\ Z-TJ?\x5\<$ +eܤ 0.=PU,l)%pT8d\QVeZnYƹO>Y&йIJC2>^/ֹyMP-xi]O"t> P"6yS{xUiͣ|XGfxWy'xWxE'x++ %FFdf9=qLQ0ZOwPՖT9^6ǝQ=Qrb^@,r6ק;/XZaE!8lB$|x+5SP~+erWLGKmmל8> endobj +2375 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [413.504 579.141 466.855 591.47] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.18) >> +>> endobj +2380 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [413.504 500.123 466.855 512.451] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.18) >> +>> endobj +2381 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [417.481 292.247 466.855 303.867] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.3.3) >> +>> endobj +2382 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [411.806 276.555 466.855 287.963] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.3.17) >> +>> endobj +2383 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [420.135 259.022 466.855 271.351] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.3.16) >> +>> endobj +2384 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [420.135 196.616 466.855 208.944] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.3.8) >> +>> endobj +2385 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [416.142 134.209 466.855 146.538] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.3.2) >> +>> endobj +2389 0 obj << +/D [2387 0 R /XYZ 81.963 735.519 null] +>> endobj +2386 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F44 1108 0 R /F82 1445 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2402 0 obj << +/Length 942 +/Filter /FlateDecode +>> +stream +xڽWMs9+t[-db<88I )X]>WrȏOπa4qT\.c[~HdN~)gbbLj+I{p!#~N)Nib6ԁQhcj4bd4m-U>r-1Ale'4/׿͟F4D-kE82?/Y-[:#s))j¼$XcjgVf ra)Xx.M9>iZ@&hA2 vq4iYR(vpHFCeam6GuF^itMPV?Un6c$"D*gm9qi~ðwޗ95;ΰl+y }IAkwPookoi mYMaو蕝0-.5E,ڹ߳L0T +w%^SDk5a5qˆM@G :B Tc/)^w\1juNjd5YKT(*. 29U* +\Ueǂ.0Y@9@>|q5r lss51B5ԋ8!x8:=߂as smK&̙^:ΩdJm^3lu/We'cS&bQP:e{=p2lnbWfWىJ<f B!]~ Aی"ZU_$q9Zvk<g+ur;YJyLOGBGF4rz8OqAf:MZ)OD.$ ^ cy[o>v +endstream +endobj +2401 0 obj << +/Type /Page +/Contents 2402 0 R +/Resources 2400 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 2339 0 R +/Annots [ 2390 0 R 2391 0 R 2392 0 R 2393 0 R 2394 0 R 2395 0 R 2396 0 R ] +>> endobj +2390 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [455.331 620.815 508.698 631.622] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.3.6) >> +>> endobj +2391 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [472.164 604.202 508.698 615.718] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.3.4) >> +>> endobj +2392 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [458.439 587.589 508.698 599.106] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.3.5) >> +>> endobj +2393 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [457.993 335.716 508.698 346.523] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.3.9) >> +>> endobj +2394 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [467.732 301.678 508.698 311.834] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.3.10) >> +>> endobj +2395 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [466.521 251.84 508.698 264.169] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.3.11) >> +>> endobj +2396 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [458.439 118.518 508.698 127.753] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.3.7) >> +>> endobj +2403 0 obj << +/D [2401 0 R /XYZ 123.806 735.519 null] +>> endobj +2400 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F44 1108 0 R /F82 1445 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2410 0 obj << +/Length 825 +/Filter /FlateDecode +>> +stream +xڭWn@}W[A_ڇJM J@ +CFrmVw֎iL 4Be={fٳcQZ i5DeC4E=uwVQ Sd`8bf&AIE !~om!d`gQ$i$a)e#_Ax~=z4+M-1Av֠YqH% ->(3HYym CR2!EA .7~ŁW0jB 6SݶA`x\by m&]-f9TUXQ~[bZ"6l2S{_bB# u8N.N(>Ŏ zUbI -IajذzjtX-6~, γtk1*_2 dza>V%ptA~lCYAW`ơ'.擯Ap\`1Jg˱;I߇JWn-X ]h1)Jj72YxP_M %}r(r^0ea +ǻNQ:nrEfՎ&Q(IT`n޻v$j +͟3>o%3ᛔ4O8H)|k0A@V-p%c_гp.{XwJ,5-||vMRxZL~GsSuZٹ3Ѽ*){2IY8ȩUҽGQ* 1xٱ xEi +endstream +endobj +2409 0 obj << +/Type /Page +/Contents 2410 0 R +/Resources 2408 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 2412 0 R +/Annots [ 2397 0 R 2398 0 R 2399 0 R 2404 0 R 2405 0 R 2406 0 R ] +>> endobj +2397 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [406.403 696.351 466.855 707.759] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.3.12) >> +>> endobj +2398 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [413.934 678.817 466.855 691.146] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.3.13) >> +>> endobj +2399 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [419.689 662.205 466.855 674.533] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.3.14) >> +>> endobj +2404 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [423.69 374.732 466.855 387.061] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.7.4) >> +>> endobj +2405 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [404.649 198.276 466.855 207.927] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.5.3) >> +>> endobj +2406 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [408.196 134.209 466.855 145.829] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.5.2) >> +>> endobj +2411 0 obj << +/D [2409 0 R /XYZ 81.963 735.519 null] +>> endobj +2408 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F82 1445 0 R /F44 1108 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2421 0 obj << +/Length 910 +/Filter /FlateDecode +>> +stream +xW[oX~8o Y) +-!*w|!MV0xwfQF^j,6!1D}t4pBYD)R2"86D!-6_ tݡnB:nI$aI&xwr!>33%`l퇇8L7QGW&}U +ḁsmĜZ4p"[e1ⰗWh<+K,'JKҥv)|N?|n6]4bi &c0dUL=)1 Š|E࿟N +[&%HO`8 qX6`4)Mܿ+KcI1tgz/@8fe|W"Fיn|1K3oJYڀ5 ]})%m +@Zf*PXRCo4܊B_6FcBE]Sm*܄9,kpq2v!nȚ} +U4ɛVpCh`hf0"ODEʄ=AOJtDz@=J RU Gb9xy䐿vl(MS^YR]GJĹ?=ǙWf5)Z'?;q׉{ϿȖ[ ~oBֵ)kL[ .ۦ}FVb|0'~>͎]N:ߡokY.v%UjnQ'N/**\k]719N8fBfm +D{<0Ne9O22] +uU[!--tM0))OA̰ +endstream +endobj +2420 0 obj << +/Type /Page +/Contents 2421 0 R +/Resources 2419 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 2412 0 R +/Annots [ 2407 0 R 2413 0 R 2414 0 R 2415 0 R 2416 0 R 2417 0 R ] +>> endobj +2407 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [446.492 679.323 508.698 691.146] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.5.3) >> +>> endobj +2413 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [446.492 616.242 508.698 625.893] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.5.3) >> +>> endobj +2414 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [446.492 323.541 508.698 335.779] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.5.3) >> +>> endobj +2415 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [406.594 197.29 455.522 208.909] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.5.5) >> +>> endobj +2416 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [457.116 197.29 508.698 208.909] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.5.6) >> +>> endobj +2417 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [458.001 180.677 508.698 193.006] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.5.7) >> +>> endobj +2422 0 obj << +/D [2420 0 R /XYZ 123.806 735.519 null] +>> endobj +2419 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F44 1108 0 R /F82 1445 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2437 0 obj << +/Length 973 +/Filter /FlateDecode +>> +stream +xXn"G}@"zCc^B`Dڏߚn=Deyl:TiȂ0RPŌ5JEV4!S\E dH,>jApff c^|y||p)In-Zb|lqw$TcY-^F,D/taG 0*%PJ +|~Tr0)@[Zڠ{ww?ֹH: ڨM*eMP)ΦUqȃ23M{  1@*}^icл0F +cM>/CH`Zb 0/r-P@? VӎIgfK2*T>3BY((@^ݻYԸDH~ qN _CI1YKS?5gp'TT'- 5W&Y} i[r5L5~0;TVUJ*)c(zckk*ʁ.|VIXM?3Ɠ4Pu"B >UTGhv3cs^sYYg,Wٮ^5f9 +iޏ׸nXHaΖ'::x. +FJj])E5o2pz~f(y°&tG{ 9\ +˺J]Օ ʼqD G'JŜZw)_I> endobj +2418 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [419.704 696.242 466.855 707.049] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.7.12) >> +>> endobj +2423 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [400.664 634.918 466.855 647.247] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.7.16) >> +>> endobj +2424 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [413.065 574.406 466.855 586.735] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.7.15) >> +>> endobj +2425 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [413.065 513.894 466.855 525.513] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.7.15) >> +>> endobj +2426 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [423.69 437.69 466.855 446.925] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.7.11) >> +>> endobj +2427 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [404.657 376.348 466.855 388.586] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.6.2) >> +>> endobj +2428 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [405.988 272.659 466.855 284.175] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.6.3) >> +>> endobj +2429 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [407.758 194.721 466.855 207.05] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.6.9) >> +>> endobj +2430 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [336.896 118.102 405.279 129.926] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.6.5) >> +>> endobj +2431 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [406.873 118.102 466.855 129.926] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.6.7) >> +>> endobj +2438 0 obj << +/D [2436 0 R /XYZ 81.963 735.519 null] +>> endobj +2435 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F82 1445 0 R /F44 1108 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2449 0 obj << +/Length 1111 +/Filter /FlateDecode +>> +stream +xXnF}W[̾FRr$/AZFi ]ι? G>Xm42Bb"(O) p]9WQ E_eWctۢM !Nf.d:M.\m ̔is3O_B)[ϗc2)L(xh6 +AbN-M;Ǐ`n <:E|I ܰh5XI yab*S>Ws~@%Jo Be+Y|=ƅŔm^uKդ4On.ܖh- odߗ1o A%w>PCm +Pi[(!7pMA"k7YrJGH}CFa#,ϓ?4p>Z>&0Ds +YYhR _48+\^%:mgl=k/y&W +kiw"G^A(|7|&>E$/|v\gQTo08<,1j+`@AS]NYJ;MR6F`H4Ka847ϡD9s@_^yX[ >a+~z0k%N׫dV /V`X'o 2UF<}+/mlՁCmA^|F5d>Ӑֿ3~_[AEF{ 0i#YZIb:CLJbPAh0'ffQ J| PEEYT ӘJ^܉m b밑c3M`[Crb#zUh, FųGx<#3{ў-,߃^yX#ƴa4ЉoM¶S:ϦkpGtKy+ k'بj-4OtO<{iyJ^([Q6e6˳"AzݗSlbп(45)];mZpmY2P7 +*rH +endstream +endobj +2448 0 obj << +/Type /Page +/Contents 2449 0 R +/Resources 2447 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 2412 0 R +/Annots [ 2432 0 R 2433 0 R 2434 0 R 2439 0 R 2440 0 R 2441 0 R 2442 0 R 2443 0 R 2444 0 R 2445 0 R ] +>> endobj +2432 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [436.33 696.351 508.698 707.759] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.6.4) >> +>> endobj +2433 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [378.739 662.71 447.122 673.824] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.6.5) >> +>> endobj +2434 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [448.716 662.71 508.698 673.824] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.6.7) >> +>> endobj +2439 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [448.851 526.053 508.698 538.381] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.7.7) >> +>> endobj +2440 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [443.4 466.283 508.698 478.612] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.6.6) >> +>> endobj +2441 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [443.4 449.67 508.698 461.999] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.6.6) >> +>> endobj +2442 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [443.4 433.058 508.698 445.387] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.6.6) >> +>> endobj +2443 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [450.039 313.518 508.698 325.138] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.5.2) >> +>> endobj +2444 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [446.492 254.254 508.698 266.078] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.5.3) >> +>> endobj +2445 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [453.777 134.209 508.698 146.538] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.5.4) >> +>> endobj +2450 0 obj << +/D [2448 0 R /XYZ 123.806 735.519 null] +>> endobj +2447 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F82 1445 0 R /F44 1108 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2463 0 obj << +/Length 1081 +/Filter /FlateDecode +>> +stream +xڵXNH}W&JO/f6& O,<'.|ĸ=m$"]uԩj?#{KFFHL2 3eJx <*4d%%tY8 /Oˇ3!;1)MW/ctI[WrE?d&p<4K\K̩EypsK~֠s(xljKD R\^C\.hH&2y8&tE~saw*(8?%[MrL2̬.JLg~:GaFP +&'l&6,ddo-WiNzJtZhɧ X +hu'.5+@-*IQ?eα r];l6L#8(0NW4wuVMs*v +_,S| r込7X%8M׆ dUǘ &vîaULm*lcWe4\_Ra.rQ+,ǃfX|qT@.mh&SO^Ǔ"̫C{0ěr*\~H,mR=pmz^d2 N.wiW1XN{Za@UR y./ć@|vѝ-OCuY0;ZbqvM$52Jt[xO3A!EMxqݯ3$x QIalg.c1a A|*0aU+U"*+_=N W#P-4/8w;0X(ն3ueͥv 3spo;.I FYUY]֔+w(@. ,u=ږs2f+3@%Xbknݐuw +) .U=so hSBI\kzI5?d9|p +-VDpbj"a.LC8ݺaո${e;84}ޯ5̴Kl>)vɩ. y. p&rgQ8~LK +endstream +endobj +2462 0 obj << +/Type /Page +/Contents 2463 0 R +/Resources 2461 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 2412 0 R +/Annots [ 2446 0 R 2451 0 R 2452 0 R 2453 0 R 2454 0 R 2455 0 R 2456 0 R 2457 0 R 2458 0 R 2459 0 R ] +>> endobj +2446 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [408.196 678.817 466.855 689.102] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.5.2) >> +>> endobj +2451 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [407.758 601.016 466.855 613.345] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.6.9) >> +>> endobj +2452 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [341.619 523.72 410.002 535.544] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.6.5) >> +>> endobj +2453 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [411.519 523.72 471.502 535.544] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.6.7) >> +>> endobj +2454 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [394.487 490.802 466.855 502.319] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.6.4) >> +>> endobj +2455 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [336.896 457.27 405.279 468.384] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.6.5) >> +>> endobj +2456 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [406.873 457.27 466.855 468.384] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.6.7) >> +>> endobj +2457 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [410.993 317.775 466.855 330.104] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.7.6) >> +>> endobj +2458 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [423.395 195.398 466.855 207.727] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.7.5) >> +>> endobj +2459 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [428.559 134.209 466.855 146.538] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.7.29) >> +>> endobj +2464 0 obj << +/D [2462 0 R /XYZ 81.963 735.519 null] +>> endobj +2461 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F44 1108 0 R /F82 1445 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2476 0 obj << +/Length 982 +/Filter /FlateDecode +>> +stream +xWMoI++:]ݻ!1rޑ= lzm1۸.h\V_P rTzZԨ\OP4 D֙LYT.E(6Iޒi02Hj=r\*0>]t2_hN,!DyP&A +4]q )<5taC2J:cNX[ ZХ>QFi4_1W BlG/` +.~ E7%jQ- Ir?1B4 ,$ PQ=:;; vXA[P~mNey8٩;M/K[CDm?%ezNj6ȧ:Smë4UjT`XB2vMeΥ6aqqvFp8j6 Q.!5mXu,֛rtN!T +$di)Β|~b'EQ\q,>Rj9e\>89*uYclޏº֋]V6M>K:_G?9U8wtM':?I< 8JZ+)BWgs I$cr|ds5"OC~;X;"4>+/XIw8Ho>; +endstream +endobj +2475 0 obj << +/Type /Page +/Contents 2476 0 R +/Resources 2474 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 2412 0 R +/Annots [ 2460 0 R 2465 0 R 2466 0 R 2467 0 R 2468 0 R 2469 0 R 2470 0 R 2471 0 R 2472 0 R 2473 0 R ] +>> endobj +2460 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [453.283 678.817 508.698 690.437] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.7.8) >> +>> endobj +2465 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [464.64 559.783 508.698 570.897] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.2) >> +>> endobj +2466 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [464.64 483.401 508.698 495.224] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.2) >> +>> endobj +2467 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [464.64 423.217 508.698 435.455] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.2) >> +>> endobj +2468 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [455.347 346.744 508.698 359.072] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.18) >> +>> endobj +2469 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [445.608 286.974 508.698 298.594] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.39) >> +>> endobj +2470 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [436.753 227.204 508.698 238.824] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.37) >> +>> endobj +2471 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [439.534 210.592 508.698 222.92] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.4.38) >> +>> endobj +2472 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [413.688 135.13 461.723 144.365] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.7.14) >> +>> endobj +2473 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [463.317 135.13 508.698 144.365] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.7.13) >> +>> endobj +2477 0 obj << +/D [2475 0 R /XYZ 123.806 735.519 null] +>> endobj +2474 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F44 1108 0 R /F82 1445 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2486 0 obj << +/Length 812 +/Filter /FlateDecode +>> +stream +xڭV]SP}ϯoMa"8"-'t2bK mw&hBnΞ={vs #{BƄG9k +ViBn7FJN;hjG'-ԂIg41Ji4y\Rm>ɭ%g}}A+_Β@)nxBxлXFC+̑^S{ , oO!/) cyigA+S ,|cVf|k̡4F$,"A(rE]* p-7 x>'RHZ2> endobj +2478 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [431.046 619.938 466.855 631.346] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.2.2) >> +>> endobj +2479 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [417.481 560.029 466.855 570.836] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.7.3) >> +>> endobj +2480 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [423.69 499.416 466.855 511.035] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.7.4) >> +>> endobj +2481 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [404.657 439.706 466.855 451.944] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.6.2) >> +>> endobj +2482 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [405.988 380.766 466.855 391.434] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.6.3) >> +>> endobj +2483 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [390.925 363.202 466.855 375.531] +/Subtype /Link +/A << /S /GoTo /D (paragraph.10.1.6.11) >> +>> endobj +2487 0 obj << +/D [2485 0 R /XYZ 81.963 735.519 null] +>> endobj +2484 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F44 1108 0 R /F82 1445 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2491 0 obj << +/Length 239 +/Filter /FlateDecode +>> +stream +xڍOk1]q&ϵ.nOaڋ+"k)ꩄ@f2 *\H1E$>$a- AFc[3 ʪb%.S:XV0s4S\5CPlæD6bT8nZ:^nvg ܚ1\Prٛ励. 0=pezW;;O·BgTb8R&FU~5/X +endstream +endobj +2490 0 obj << +/Type /Page +/Contents 2491 0 R +/Resources 2489 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 2488 0 R +>> endobj +2492 0 obj << +/D [2490 0 R /XYZ 123.806 735.519 null] +>> endobj +1090 0 obj << +/D [2490 0 R /XYZ 123.806 710.612 null] +>> endobj +2489 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2495 0 obj << +/Length 259 +/Filter /FlateDecode +>> +stream +x]n0 y +&NR ic qBaB{CQ۱ҭax -+Lznd\BI3Mrl`!bբz{U3L-O"t6 CSEɘ}]|ʙᒿS;KQGE][Pu+Mj~LZ֤x'jc= +<$Y=>u7 xqYǶ8ڼ?"$P8ڗt'o*A[ +endstream +endobj +2494 0 obj << +/Type /Page +/Contents 2495 0 R +/Resources 2493 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 2488 0 R +>> endobj +2496 0 obj << +/D [2494 0 R /XYZ 81.963 735.519 null] +>> endobj +1094 0 obj << +/D [2494 0 R /XYZ 81.963 710.612 null] +>> endobj +2493 0 obj << +/Font << /F69 1138 0 R /F45 1109 0 R /F43 1107 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2511 0 obj << +/Length 366 +/Filter /FlateDecode +>> +stream +xڭMk@9*i6;~ B%A&XZM ? ƤEvg}go@X_z _AP.=Xw5{." p\Q Rgc{3|ͬ _f(L'mmUx;Ln,lF9,LPy`$feKML&yV %l+#C3΢cmܿ+ҥé=sJ]y*6hWݦ1߇L{. d?4Aa:LNښS睵ݑN]^5liGpэИ5௲m+rh^mw/r&Y +endstream +endobj +2510 0 obj << +/Type /Page +/Contents 2511 0 R +/Resources 2509 0 R +/MediaBox [0 0 595.276 841.89] +/Parent 2488 0 R +/Annots [ 2497 0 R 2498 0 R 2499 0 R 2500 0 R 2501 0 R 2502 0 R 2503 0 R 2504 0 R 2505 0 R 2506 0 R 2507 0 R 2508 0 R ] +>> endobj +2497 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [183.445 651.802 197.393 664.488] +/Subtype /Link +/A << /S /GoTo /D (page.14) >> +>> endobj +2498 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [235.055 625.226 249.003 637.913] +/Subtype /Link +/A << /S /GoTo /D (page.17) >> +>> endobj +2499 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [183.92 592.001 197.868 604.687] +/Subtype /Link +/A << /S /GoTo /D (page.17) >> +>> endobj +2500 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [177.44 575.389 191.388 588.075] +/Subtype /Link +/A << /S /GoTo /D (page.18) >> +>> endobj +2501 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [209.313 558.776 223.26 571.462] +/Subtype /Link +/A << /S /GoTo /D (page.17) >> +>> endobj +2502 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [181.911 542.163 195.859 554.85] +/Subtype /Link +/A << /S /GoTo /D (page.19) >> +>> endobj +2503 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [210.811 525.551 224.758 538.237] +/Subtype /Link +/A << /S /GoTo /D (page.19) >> +>> endobj +2504 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [210.352 483.224 224.3 495.049] +/Subtype /Link +/A << /S /GoTo /D (page.18) >> +>> endobj +2505 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [200.669 466.611 214.616 478.436] +/Subtype /Link +/A << /S /GoTo /D (page.18) >> +>> endobj +2506 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [161.986 440.036 175.934 451.861] +/Subtype /Link +/A << /S /GoTo /D (page.13) >> +>> endobj +2507 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [212.469 395.987 226.416 408.673] +/Subtype /Link +/A << /S /GoTo /D (page.18) >> +>> endobj +2508 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [212.469 362.762 226.416 375.448] +/Subtype /Link +/A << /S /GoTo /D (page.17) >> +>> endobj +2512 0 obj << +/D [2510 0 R /XYZ 123.806 735.519 null] +>> endobj +1098 0 obj << +/D [2510 0 R /XYZ 123.806 667.341 null] +>> endobj +2509 0 obj << +/Font << /F43 1107 0 R /F45 1109 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2514 0 obj +[600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600] +endobj +2515 0 obj +[600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600] +endobj +2516 0 obj +[600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600] +endobj +2518 0 obj +[500] +endobj +2519 0 obj +[556 556 167 333 611 278 333 333 0 333 564 0 611 444 333 278 0 0 0 0 0 0 0 0 0 0 0 0 333 180 250 333 408 500 500 833 778 333 333 333 500 564 250 333 250 278 500 500 500 500 500 500 500 500 500 500 278 278 564 564 564 444 921 722 667 667 722 611 556 722 722 333 389 722 611 889 722 722 556 722 667 556 611 722 722 944 722 722 611 333 278 333 469 500 333 444 500 444 500 444 333 500 500 278 278 500 278 778 500 500 500 500 333 389 278 500 500 722 500 500] +endobj +2520 0 obj +[556 556 167 333 611 278 333 333 0 333 564 0 611 444 333 278 0 0 0 0 0 0 0 0 0 0 0 0 333 180 250 333 408 500 500 833 778 333 333 333 500 564 250 333 250 278 500 500 500 500 500 500 500 500 500 500 278 278 564 564 564 444 921 722 667 667 722 611 556 722 722 333 389 722 611 889 722 722 556 722 667 556 611 722 722 944 722 722 611 333 278 333 469 500 333 444 500 444 500 444 333 500 500 278 278 500 278 778 500 500 500 500 333 389 278 500 500 722 500 500 444 480 200] +endobj +2521 0 obj +[500 500 167 333 556 278 333 333 0 333 675 0 556 389 333 278 0 0 0 0 0 0 0 0 0 0 0 0 333 214 250 333 420 500 500 833 778 333 333 333 500 675 250 333 250 278 500 500 500 500 500 500 500 500 500 500 333 333 675 675 675 500 920 611 611 667 722 611 611 722 722 333 444 667 556 833 667 722 611 722 611 500 556 722 611 833 611 556 556 389 278 389 422 500 333 500 500 444 500 444 278 500 500 278 278 444 278 722 500 500 500 500 389 389 278 500 444 667 444 444 389 400 275] +endobj +2522 0 obj +[556 556 167 333 667 278 333 333 0 333 570 0 667 444 333 278 0 0 0 0 0 0 0 0 0 0 0 0 333 278 250 333 555 500 500 1000 833 333 333 333 500 570 250 333 250 278 500 500 500 500 500 500 500 500 500 500 333 333 570 570 570 500 930 722 667 722 722 667 611 778 778 389 500 778 667 944 722 778 611 778 722 556 667 722 722 1000 722 722 667 333 278 333 581 500 333 500 556 444 556 444 333 500 556 278 333 556 278 833 556 500 556 556 444 389 333 556 500 722 500 500 444] +endobj +2523 0 obj << +/Length1 750 +/Length2 576 +/Length3 0 +/Length 1089 +/Filter /FlateDecode +>> +stream +xSU uLOJu+53Rp 44P03RUu.JM,sI,IR04Tp,MW04U002225RUp/,L(Qp)2WpM-LNSM,HZRQZZTeh\ǥrg^Z9D8&UZT tБ +@'T*qJB7ܭ4'/1d<80s3s**s JKR|SRЕB盚Y.Y옗khg`l +,vˬHM ,IPHK)N楠;|`軻9kC,WRY`P "P*ʬP6300*B+2׼̼t#S3ĢJ.` +L 2RR+R+./jQMBZ~(ZI? % q.L89WTY*Z 644S077EQ\ZTWN+2AZuZ~uKmm+\_XŪڗ7D쨛Rl:/P1dɫϾ(l=Uhd_OܗEkv-X1tލ`i_y. 1dz:un~Q?3/S}] +$e~s]F1ʻ/Q?m򻳷|<ċݺ/q'}I+6EgxT.GgtvՏGU|~]Rޅ_k9:{pG d}dN<6-uBoH=cMvHzqaRK~,K̞}˛myo~v +_s>.#ҭߦ{/əkܗ\m|rXϾadj|ǝR/, +endstream +endobj +2524 0 obj << +/Type /FontDescriptor +/FontName /GFAWRG+CMSY10 +/Flags 4 +/FontBBox [-29 -960 1116 775] +/Ascent 750 +/CapHeight 683 +/Descent -194 +/ItalicAngle -14 +/StemV 85 +/XHeight 431 +/CharSet (/bullet) +/FontFile 2523 0 R +>> endobj +2525 0 obj << +/Length1 1606 +/Length2 9325 +/Length3 0 +/Length 10152 +/Filter /FlateDecode +>> +stream +xڭteT[5qkt# ,h ]ޙygo~ͼ?SUg׮uRUUble*yPii%fP,i +tI ϏJ 8z:m-uFffY=rd н!@0}Q@m+= ',`Q@g3{=]+3)ͅK`pqZ^=,\,GrX;/=B /v+_!//0U dU' ' XDZB,\ 5]PO.s ho W_ X@k3gK{ NېbCzi}m 9?}n@gf_HYBK*2S'AyoSҮf/l@gf {!:O rP6_`ry-UAP Kk- 0E˿`Odat]@?ov)e-q)5nӿT_Tjz:: u!.xrqx9?Y Wd)ϔh@/_?n Wg=z/=s `h5QV߰Aw''|_cQf~%/9l*SԾ<@'=}QjƮ\%V^@v"(Iw[kjƅHd?[Qri1}-jc ڰapvv"vm0gƾtCw$*gN'|a'wAn!3Lpٮ +Z?DW`WXVtg2 Ǯ&ػɄV}rn]ѰPԞhբW?>rô+?'j9j1+Gdel o\ Tr?P?Ch,ۨC#2_&*fxsxWJ4}~LHI*V?"$ Dy"+f`Mē'BKpxIzu^=>Q QL k ϓUJFW=E`:jDBT|4n5No\!j;X*ѽ>j%ΠOybv?|889?=׫(\uahKv6|%}xQ484{{`>/ؖ~~uY:ib+@|2ps޴7Ew #R3Lү0QhM ?7}]!f߷tҐnl'" IkJ#i؃wX[R%蓠Q!z?@Yf@Ȱ.lnSVj:&4QM+}dBp86m1m)U~fB^|+(To!fMdɢ~tWar.h(~IƤm=i |\q+L2f0Y!X 8qvB8=[:׮pPw6"{ec0ĸ_/ז-p~gMQ&_cՇ%ŧߑk#Dp.Gղb&6t4 ?^#cd5eԬzQdGCUAcm 6<ԝW-ay=d*/9٢gAkv!0]7BX\쬱WWqR`2O$"Y;Tct>>R^7o$nk{$Зzrh3{(!݉'Ti\mOȏ6K4ULp!lĬ42b81}k*1ޏANdHb 'VRFf(dA!y{{A|'JSBjF^M2zK$ӮG :+}p I풑LA8E\R),6|kx(USa[=BmD@a -a1G~gUXI|JB:^ⲨҲu ^9q[Ʋ[i3Sv̉HBjT_MrW˺pk']ښ("FM> N0a t.!&i$#z!B!.:T'U^O+C,>sheӟ)Z)2 ^m; ivizجDžuqL> ##gT2g4[癫,"nԼP-thOZFeVnػ#I!sS~ ntRH@KˇvZ[Cb=ܦQz +n ^ Oԉ|伧z%QC(INijf4!X GU#p1~3 ,MTr"ozu+ɀB_^[z^+ \EAbM͠gP͓'xllXbW+ғzgm$˂rI axul3,<8wOPY۷1~Q7O +0vնJ\ԇWH/eChEI=^G`nu;ٿ3eJXS=Rk^b$`W6c0<5.pƿ>ôk}Ou㧬4* =꾏vg-CADZ.ke>.dnE/px&im)^NaPێF26ݕ mV,i5xͷ8/d7Z4!)|ֽE0b6oD0~s!璷gYV8Rbn7w8Mfۼ|And(IYŜSt"tC)1x1 !CD=S~ۅO4Ulj7L6v RZ +(d  ;'yiOIKcShJ&YѰY,iQNö60 +*6θ+-'&T_+C(ҳ-ѷcYƏp5K-M k`200+C8 2<6J?Re,(l? x4yWC1bR2D{KMKɻ>wE/}V?6!FOCDՎCDhz4Lhda'=btx403%{ER"HL܇l94gœfMg u氅yreX']S* audmjsͳˬ@td"QWHGJtBm͖8Q,,8`GmĒ{*GG]QE6/lNF; E߽>n`baw٭ĥ,z2?q xzcx~;2Um7GIC BQq&uN\d!d *_TrMH}?N0OIPӦo3`nD7aWw؞L%07ԋ+lϟ ?2;Mͷ.aA P_$4XeXI؞32s۰5Htz +8bgڢ%{0n7TTqB?dpx"CNwM|!r!UEpUn߉6loZ~ݚuIJ=K6.H~{&ELGvרn~K;qLigfoFT% غepup˝M jwV{oκclZRڼk0wܝiboLF3`^#l$g ] wtZfEXn\ (u:^]~o:HL6bc{eIZ{uB2+ww@wU1ѝ0L*#1 +154-i{]Ko gQ; a!d⁒L7n'5BYN}wCNںCniY,7|q2=SA|j+8PA6[(J걬Vi8Ӿ*9챤:N2 C|4D=7ݏ9W>_{anQ歹} :*J2?YNeƌ/Q)|uF U6b]zY:T"yRҊ>u) +mYA֥t{} ҶǸlG Uv+u!/0F⦶|-.]qp,"63‰췫9(\c?=Lw +[R"=| )Xm9 +'F-$TOs_'Et]b#_YkvHfMBn%̈s/sK,ptC֦\s愵#7e"ObcHrD{&co$蝵6P->#_Y{FG` ?Gw۩%WcQF{tz&ASF(BD-ĕfO|_7ح͠~l*`qiNg Nc];9vU&/ kaCm?LmgxhH'.nqI_LK՚Rs9p̫VdY1Tu;hNzKY\#]I!Z)ߨG-'e$oW=kcSV*%;;&i\bmޥN=yXUL(喭0]\3 wTm馮EeJ;#s G*˔Ee5/ o+{yP 3PEɻt𐉙mS?p` ]bxQ*I3Ȳ2}j[smr2 (cQk+{N/-qwv6Vz{S Bj}H`'uJ*rL/5 ^ 3P0(H5$ttrsyyYo1n2&~o\Lʌΰ8 dn3h)NQʐo HlϼEͦM=+dE1=_P5U+lQ:z*X{t-*A;H.D<,=HFթJFd'.HwN8sM~vPD.ES  $ oQ+LTI"i)ZӨvWz23ͭZ3\?VgceE edZ>wB#N?$B +B4&Thi["S >Jd?Ŭ yth)D][syK9լn|6,LZ[P2ྒྷ"*_ +f +ٟS_̭w9XB~&"_vƻ-z"kL;#&ȷt*%58noˆ7]xՄxE-~dMj/ar*8p1#0oE| `4 vd8YZ)쥹ߺ^ `/fVD7VAo|S|7kpyP?:׵OMCAlu;~Ub9@iC1R7S+b-;~:Awi`ږ +F;tE_o|/q9*'=m^(پ=M҅y9Ytf~>kMc%q =ƓqygQ\neYټRgRpk7[>wmC:5eگw?tc$>_qþ&4ˮЮ2 #ZwTssf) !<^1ªU[31ɩ\:z=r!KW˩}NtGXG#]%f +5I/ĂESaZYؖ5淠4F(iB8Oj?!b9ީպ(n hl`U]H.}"&4`PLuơI?O擊q b>JH\ z=xF0<TٽZg^l_>XS 穓5, +(4aW\{]\ѧg[㼥.Y\BImRVc[Գy~z1$2J3Б_8`d^R}@c Gzf2`7?Xlk+z$Spw⛑^=8[5In'HMo^=2 kDH ;7iehЍ=J1Z;K;.DaKD uw(Ȝ-)$o>g L\?mo:vŌ/*zr]|졊,;li* {yUq9=zށFMJ{LfMxT%f\Ѱ 'OlsEw[1< {eST!)zIz6Od8U8VӁVq/7P؆g"M*wp> R6Ь6 Oɱ,\,`uR3q,juۂ86h]Up!*]v²Job.ջ#d[=6#8zBSY2diP՝-2\ڧE,;,SN yciG_ȋܺz0NWE:E!+G.=M.3<ߑNK8e<{;NH0_8Q53)v,KfPC:o;&Y%(dP8Wd6DpԁܰKri}z),hCn\wˮ\Py˂fTH +\G=OdkAM4A&Yir)F+ËŽڸLMmEɭj^[UxlUoGNOΈZbԘIƺ*3n|dUqb/>R?κAD(7̩Qs15&[Zr8/-3KLSY,z. EP3vjc4@蚂=Dн0VXMc7_'{w\1f6c.}u:mwAԘ8KOS'Lяyme3'ۗϰT,yוu˄^)#z X􆫣N +fDtoOֽ1ʢ]inv^eEG+efL\OX#Aqb_ 7lXxYזI:H-'3tJoz(ˎг_Y+\dt'%]7L6 Y[WK6. x7jD=}ՈzA\lgfNK +r[_]!4=)^=g[!X2 +endstream +endobj +2526 0 obj << +/Type /FontDescriptor +/FontName /ENUBEQ+NimbusMonL-Bold +/Flags 4 +/FontBBox [-43 -278 681 871] +/Ascent 623 +/CapHeight 552 +/Descent -126 +/ItalicAngle 0 +/StemV 101 +/XHeight 439 +/CharSet (/a/b/c/d/e/f/g/h/i/k/l/m/n/numbersign/o/p/r/s/t/u/underscore/v/w/x/y/z) +/FontFile 2525 0 R +>> endobj +2527 0 obj << +/Length1 1612 +/Length2 19313 +/Length3 0 +/Length 20152 +/Filter /FlateDecode +>> +stream +xڬctf&۶m۶ߏ5ƺ'ky +=PY KlfJWCF&dfbe5r1&03%53!df&d!#wtt!TS֠/?&ƞS@H Q̌Ҍ֌PDAQKJ^RB^P `ddKjlkeB(kebp6"4w"`jOi Ly9%t0srvNhLhdp{B+? +!'vu]M\FUw.F.v&7kijoOIu18y،o`NVJ +`_:Y9ښ9;OwNz#[y`lfkN7VE +`nOoԹ9A $Lf0 .CR߱LG-B/¿ƞPck27?8ٿr1 !_B-r03Ur1$47۩fNVtLS2z_: +Y)Eob9{uCXރЛ cf d_0Lu3rq [2#ӿ +F `boϬL6qurn߂_nfafbobR;2%3:PڨZTPcUiYJ4|Hxݖ7&חi8A>R#vIvLQxJIYo *ĭ $!Gr]%y p=xMN4{ӕLw:xaΆ4x6r9»ή!wqtV∌n4ҵ +AKwUX,;keIØoަR4Wϩ.S%Ш^tpZv$N[~RRɳ&m4)ZS:퉡TUvQ5yg9$[ԏ+ .4x1k"\b4cVyu:N 3Xhp@QOj+dY4I^R<(:LVo _z~X"n#h"mi΄L,oW֣Dl##RT(Bq?I\7 +(iHe)~zR_盢d߯8ܵOIU#6/HpT^BwFbB4,(QQ +)H Xgk.d7z~tuA$8!"6쀰\ vmTj#cijI10T05?`({vKn虅ic&@9[ ϿW_d~~b'L!t7{;z;v~iv wG*|81J4B׿Ab<#C4~ b,`L!be땎|G@H[w\~LG?aZ4jQ>%ЇצeJf,s= + }9ȡn1QXyQ2ig㗋 k-.cpi&j0!#T7ү=Oicqpj4[-i5VT¨آ#_?y)yAt52pTpZRB6_J|:@/oӴ*iQ1Dj9EwNڌ/YٙgnFUK@R!Mb-r<,Z]"w#LdY*oGрQjxcKiU}ɷ^l’,d*孅͎ ] 6X8|#JKP-r^g4]wpOJi0.vcb 3C'S&> 4y#OsOu$ J6VA=(5^R ȉ,!hB+E!o D#׭]dq]!MϫVMFn=W7m>?8+YALGɶ` +ǛEb'dvLDagcb%,n$T%7?>_RA\,w]S2D5wo@ PMXT{m,Y>dpda} J]ec.%æ9ZJa3l/oP^Lq-Ss3őN{,>Od2lҳ| zTa;eQXj1p;DjÎۚK9gy%zL"#<~|U` [f|ɠ@M5Njф#o9ɟOw樟*i X -)xhSv"hofǁ̓ 2I) +Tܗy׌=:͔r^"T2W8a~%;*::n &&~tH6hfґ]__$-ԆE[Ԙpxegn`nIfM>A>YoΝ}>o.DzdDC,@@wwAoQ{i:+Kĩ>A&I~a(Uu L:*EDdT2o7d,Fb|Lqyc7z:XyW`s9)WI8CBͩ JߍӬ 83A- +`jީLAV ]ʙ3mJn6-|PyeM, AZLd63YK1o+|8ۥ֫((CkM&Zиqm@R  |dԌL! XƘ,:TK=y`Tn:pP{`KKq3S,gx5\>ua1O/W b=$A7z,h&^1T_h&,GoLF>^>D 3"r€ozHxPw4h5 +ma?<0h3=|'mL6| .4s7P2O 8,ZˢY8l De\{P&~,?I4PxmA I&Nʧ巡aՈ8Dt:)xl)zfmX3m#Wl҄c~+S9!P#*y?:B6eᑮ Tu qs@{bN#لR2] +d{ Ĉ ,U `jmUoǡl2su;`,:DVBdDZ= csfI7) 7$M86S7[g=| ] Ubz5^z&إx\P&QAAJSǧ6\9IoX'E0>W| ۤ ~*;6C1JnݤDc$ P[ץJc.}3 ڷLwN4: +:?\O E@ twJ`+y\i^G}>lzVeE`AX{tPLX.bي̅,<!9 +aTS A 09vaKDך{mu`t+nY@¾MEfœFFKSE^pAq6[L=[ ^sn%:w D<2ő͘׶qFH^)'sr~9Kف.>5OYf\#hRHbw!+UVs#ɹF% JT6C/?- FEqptB_&)<#S{[ujSCUߟ/(`Z 9!@u~P=lyQہ2G+Ss)Βoݰ#Xvu7B.e9rJ{a?TA wN4[jt؁~> }JF>hucf\ӋXGJArJbvz!kQ aoFoJrc[vu1)ȣ9T= ȹ9[FPdGcV[Y)A2T72V#a|2U:`}t=kd]fg C'%U}Eѷ}| +v <*Z/̶nׇ{;IiyꚑٿxK-8yr&%bƠH8{}?dߖX5].V9 t?HvT UNU9YB;}^RNݰ-"-H'2"c@n?R;`wJāՊRqFrsF_ʼ.!?DE)v}H9ó7:6HT02SdsdhVg0-moonÚOPȢrU2 4Atѽh`o$w ߺ2R=1ZOnd(%üZGU=Y%xF#sR0R|YeƋ=)ع-po_J|aS>JRV"~vY%[ K&OH|ht2f>o*Qo_5Gqo!+Ɖoe<.X|]?bjFg2C]\<&{-W $WfH!Vf]A%qxK`̈́[NJ!$紷6eZ5Lw+C>ޣZ{jUzܽP*7+ tT'e/y : MrwTEM ^zG|"y'5Q=#vx&jW&]*Y _/n6^CGBJ_AL!!r[^6ŕhW}p^NzjM>A٩a?֌ͻs_[ELw?EWM[`T~=s#?GuM:螄0[ [AxU(\$ 82{37"pHPRqТ9F*="yua冐VvZ2‘|I+gϺCflrA\NyD$q5eM(+N_cyk2%MDY"ɸ>e +1ߢ]#'#r6A*2N-DXz*z -̯'0aAįU"Gf۔*sYbJk^-:qXx4z]o̝ ?P;6 3F0s9⾉/(39qߠ8`bԶPyz *vծ\fRY&S-#vTTj\%%p侞%OvudV,e!:&_xr;L:SS^lӚ9oLhA#\|v ݩ%^Zg>'YS?^3TO џw܃a&pٻŎFZ>GUxs=κ6U=ncu7QW1g d*grUJY3s%:!_Jrt +x4SGֺ6E9@:~ok]thEZˍ14pFV'/&s-6ֆLiFKnCʋRIPr؜rw-ЃC0([_TCd`JmMgԛ5sDAN6C2;;Hy 4E[8,fέdrOn$yIofb*IuΝݴIf~ge^a 98 +H2LtX9dx^gIU tXkqcqWB*2XGKα3lj3_Nhh- /UuWc'k8tIh,%XSdkKႅ[GE7'zMȊ |U&e4bH_p"-M5SbzA{i24Ԋ*C ۺ3DNɨ%h>";ǞZ$4G o O¶ʀu6쑪[w|w(~*6iu&t ;HbGm^l]pE]r My + ۦvAa)ג+^n6RU6cXM]DLa({%B/Ab5ʯD?m v@_m g4x;_VlDGБ2AJ;~G3zg)0{tv2DK$ lTCjq2C*σ}`8,Vo t|A+Mm7BsVH\.Dy$7S^&yߡC6Udp բcMEBlM}EzNN( յ`*8;6DNf)#nECG=!q}G}dNn߇+d$~E?OoYuUqn S (c{dž V24뼡UidO + {!OryBA6.?tZe1;-y[|MљHzTcWKb;9D<7e]Kڶ{<8JK]'LBcou#xsd턻 +*:W&S6BkׯӲ3&t$iz +lPB +ִ0%(LPQޖ}=riVU2rYV\cM?N{24xiE0:1erU%8WEG:bO(uӴlb-*N[D̰%2݃KMLBgS0, +L/^\#]6#.-Ţhfd'2VVх؝d8|?,"5%~2@5"8er}C4ZtKd#JO]OTKIAIz_3N^a&︦=^0)fD?[G&Bs\Zbऋ/,THqEXW&BY/GI`ui?yfBMHLўH3A3X\97Gц_/nr_<邚e,8I^&;ƱjCShVs$(g2g7_9Z \q,?ؗ[{$G;d}m+T).ey˿ ٽL4e[zcݪw@W`,ya<~lQ{j2~^k]-1 DO@8mň^:qUv!jzFCŽHSGͼ] .Uny :*154w}i׽ܗ=қC!B: +U-o Ezn>ȍg@iJAD";"v003 ʕc4 e&U0-COIq\7xuCG.Ǵ A?˙vM>17=o"qAeW2X+(od]y!gp Ab*̏i/ Te 6V>6Ȼ}2MTl)jq8S"knR[AQӣʗ?k<{SSn\෍q)n^$?e cy)r O^(i\ҟ` laLp+Hdss65AbݲWFb݉9â! ت܅ x3>`l.$tUxemȃp/7n;#,C &҆^71 :"mx|=&X̐5_o2mێsLBΡƗ:N ح\A7V,M N;Ac@`︔/=3'O4Q)QpGJt%_Rltl85oà&'/b |{v?&<- A6Aj'Jo8g,p;-l)m:%+d'__MT?$H*6i\8ц LfSϱؘןy|Sتuď#>1 +71Z5N_#]av`%T{:7Eob9H(n/$WXՌ1?8Š`ZB)$]N!q" CkcbZPۣ '1M? < %3QPL1U U?Bh#Ķ̳N+$s/~_~䏃V, w?F((_rGk|#7ìcK)ûP~R13~زP).l*+sOݭ.б;g m?ZZ45 V$)yP7jؓ[k%d/˙xP|ee e6洍@MJ 䁷|3 5nB[? +zA/=YP [ulDhPfPOo7.nncTQ%PRCuBPL_'*Z&@`^#ia@:933 @tD}fuMC7Zv1QһuY?Ӄ ?]P>īG}b3W69 y&P eDMnxCM1/USoџ9D} %?ن5rA_HP S90DiԽ~"w!}k#Hw$Ø*~qh >^7{3z0˥bOE,~$!&6fjKIm^e_L ǾC`ېzl>k0 `awGB9&@| B哢d"&_PY_4r{y^{ +2k572eyMʂY1-1<=c,I\./sɍ~u4J +HP`_ c +WFݾmOԇ& `;!O eݷRA73vgCQ~0jDaĴ8{Ǐj]4KSCLdˑӝŗONȜO:k +iO.@̠'ziGj2D)ypbBkT;N2JQ4kyUWCImXz EtoL#Z+]kp`o=\5 oYZֲocnY3flcmb9P+ԃşvMzC`N2ϴzHı(}h:ISPs*(.f$G|T&8r-~ɐP%@$FS֏ڲ.#@w3M}G:xgҴP9V2H!~SuNf'; +jdx[k 6!H&:|?sxj }Uvx$EiLGGoN`^+y[ebV0ey3)[>IcK5#CoȠ:@cgL ǃ}s;YAAo晦 Je#ԌQrCP4NM0^F""(.h1-~94+Nif#kj#kq G:} ^oTD8^j|v8EU}UI3^8ɼDKuIcOҹl#m!#c .e^Gj;n_2vp6e|='!'5hZ=?({z1j."G9JR5 !(]ơqOvuf6}}(YOlO: S+i곖z5&>PR⻱V\ہ*|os/In4OǽXhȭa& fidZI v AASq!j`Tjexմ~I-"!߿G āA/xf\ͫ*Ō8h3Chƌ1qiAyPw NV00̧.i|vr$=hd>ib*'F.uйY385ot;*ooA0D KnZ`lUqKt :梕6ߑy8NLA#;`3I+Nv4&l_ST +̈́(ѿw.d^̇BtKpΔR9 BWۆVs%Q87'o ,p}\#%_N b dl&طծ>aqP7NlbhN~F.A莕4p:#/,nWrd-##pQZ gC*2އ;G4˨Kު N`U(VbdNmGD5_~[E7IP݆MNد# ZzӡZESo#!EȭBb耇6Z9]@ݛ">@nChT2=tcy@r`= Zg:ڇGy$&&ؽ4ufiT[kHs󈘲UZbXvpb[sH@sU&8?xMѐ9@}P3pA.X +LU~O*k2,nԐfzc]kjȥ4#{(T=opb, +HqU +UJ1h٬ Nr0N YQ)*OOll"{/q&=_/#గYE/1֨q=pZ沱듧}A{M01%r*scL"ȒUܜſȟJ2EPK_%Y _)%WWAQ t&2 4uo*x"sٰ\FP}-7_B%4ױQ J״)_61agm?Fw?QL:#fUDŚ3Q1e +aQ({$!yK" ^jSX[Ytd3Vb5З%TV|c .v0:IH"G[W`:#,n 5 jmDG߅W!'w [E0+Z9]S.BCZcQr$g؝ٹ@?:3= A#XtL2ඦg(l +]g +AHe+34{$AL0nP3G7d EviFO ܛKjBW~T߻" TwiUp6c=R^}F<2c@(=)vRn~ *OjDx- +I6?.fv{J.IH#X} &A7`Bin?Fv~Hdrˇ>NeS hBYF)gqTz<3;/QFV/ܶ41P< f@ 3* (.jʠ)AF֯qirYsX;7hcSpSsQvąK,%?_P4`5Ε7_0&Wzh4駎[9CAPX*w|]t YS5ջrM\j,=G6tu +Q򡄑*/VMaz TUoJu^`BDRzEզ,K_~O"kzqi=Kdo߉UD.Q܁w\^\&&)bX9k*͖[?c=PGʎwrszv]5HUYw}lUVX@`_saĩ3CLdDU$~TpU U<6ՀYO~>e@JA<3:\b'nq%J{ f`4.2f&ID"M}02 MEVǴGvx/>v_C PОkȆrDg0|1G/7A@)ijp8qϳe"`@fV]PS_h^#ck(h̀Յ 5$!<~&l(m)6qI}UM"ꑦωZ $9rVN9bA Tc |xxqЌ bY_2%ڶj{:7ZXJWva.uh5D xk9voCz ;=n ~t)6&! oEhVW8o@% + +.!?i![UUDgD&:Vyjt! b d1;FtOjoOF>vNևl 3|Zd9[O0g*lfkvDGWމQy00 +O\$"DWI +iyYn (,/+f0oĭSDSOھƬpOw +i(cF1TL_C%_ nΘS]4ǭXyhjK UG|[66&+FIY"g4{^m,F,gA3[%ƩdSVoY]T0}q\''j%~l"Ӟ_-cfZbLs +RTy*znaҶMJq7Xx,J ^ \^iw6VLXxq5u", +endstream +endobj +2528 0 obj << +/Type /FontDescriptor +/FontName /WPLVDS+NimbusMonL-Regu +/Flags 4 +/FontBBox [-12 -237 650 811] +/Ascent 625 +/CapHeight 557 +/Descent -147 +/ItalicAngle 0 +/StemV 41 +/XHeight 426 +/CharSet (/A/B/C/D/E/F/G/H/I/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/a/ampersand/asciicircum/asciitilde/asterisk/at/b/backslash/bar/braceleft/braceright/bracketleft/bracketright/c/colon/comma/d/dollar/e/eight/equal/exclam/f/five/four/g/greater/h/hyphen/i/j/k/l/less/m/n/nine/numbersign/o/one/p/parenleft/parenright/percent/period/plus/q/question/quotedbl/quoteright/r/s/semicolon/six/slash/t/three/two/u/underscore/v/w/x/y/z/zero) +/FontFile 2527 0 R +>> endobj +2529 0 obj << +/Length1 1630 +/Length2 14608 +/Length3 0 +/Length 15462 +/Filter /FlateDecode +>> +stream +xڭcx]-vcc6:bWl;c۶mc;={s:g5ǜcb{UQ~QVc17J932-m]@ +v@s%cK_R hlio'n hM@ fdin Pբg/?.c@F,T\6@;ׁj@ 0Ĕud4R) ;l}ۙZ/`9M,M@ %` ;9=U_ۿ_2e{37t0r'7/ 7ijoOKE,@g?SK,U *`8͍Lm _Lo98x+_^Y3hcƄ7v,=vS\N?;C#S{;) YoJLs"H?"ow}Ԓ.66Fߗ -cs9k]0#[KCwagC3+ #+˿͖ IKweװ3:Xj bao?"pڙe%O7hߨu2}79q%YF2u-i곅Jg ʱF݂svܰS!FV20v> Shdd#ೄPj [[bq?#d.Gu 4ܰО~xa=Q=[Zb4ٗXLZwhBաe0@$6GyT_:|2f}Ih ٪3~IWEGGx|T8ɚ AiDa!noA1_[+PͿlՆJDpվO׉#,mvnx Flr> c8!vcqrMd5]#1*Ģڜ#qn% [dpgȓd}üjlmwG 'wԆE/qEљ|yN[\@ok@K_p 2`5#$M&j}Kf@Oظ8syw@{Y0 j23rOf8* +ef#p4=9 :,Dn yNWMeҐ0P>%6#͗mƵĄDIYB^OiOy^Cvuu<읲֖Ȅ^Vѧ裖{ǣBӊn;>qg,1nNwâdߏ"4މ' eh_/? ]K&U#o<tAteEwJo7Ϗ0͸!QbI1L:{n^k`}Q~ 6ZqJ^Hn3s71v^j6ѽn_|NX 2=^Fq[m \$H|*:Vt2H=Pۍ$~^CB_bt)6|"%_̲xݪU21Skc".@-6, xLc6R}A4`;y5 +Ӯ|U+ +:EĄxRb8&n\f1 ]Uq .Ctw|).bvRh 1|sqσ[7rd}4*&(1wАvu<9{[t%$hF.+PB:iO˦4e>,1Q}`u&YM!V1!cǻٙ,{FuD  PbzE]m@좎bpwdҏֱ{"*덒+) J82ޜǨKLrF!M*}Tŗ6gi^;V+.`6OgթlCf#h G9=9H?UA:LwGa '-v?pA޲[_ưLtCkI*cZhQp20dws08C)ҫe1_tƝyCHRfWkPĺT]|$LK?u[%Yu'X^v⒞]YS#AtR|є^8ڀtpet9Lo)1lL,j,I5.lžo` (ebh$' R>w,,6 հq ~OD5&q`[/dJ8C;j= u1IxʩR8HfKLiDB{V!07s^Db6l>(_[f&+fW|'0$遂KCp*ր?PCΩhREM&Wf*en)8X:>}fKYƾVs;Gsw豳Vxf$Q~Աf@ܲX& *̦\r E㦌?p5KXE4>9w#{Z@GutЈ_O2;lIVb5vPfx!)ޯ|ꇾÆC^h\A{ĂԾN[/DӁMԕ]%ňfYq6R59 )' REǝycwVH5;<ݰBv:_VZZ?IgQ9bϛDa3kF% b~\!$=F_}s+il?vԣ ,šÉ*ȀHJuD99D܂pkhi+!Hз3Sdii]a8ҪBVdk +C+Rt^F.rZdb/d/^ڪVpQ;={~xc [1\1yԘ g +<AYnǙXo Y&oi-gS7ȳ<[HnLi|k5w,5 O#y:Fօzo,uHϿ#ڍJ 9K̮:>fR]Wk۱L~ +gkG_U/9fϋyG "9B1Gxq(e@zͥ\DP>#?"--jqC܄(cJraGSQB#(0 A)5" KMEe1"9US/#:!nrպ^;+ōImI|?K]هKq˛^ԽQ 2x +dTS"Ѹf6h8(`Izs?l)rJ`Wsay9e<((@'ATc*z&B7O5y{[a$!NznE +Ge?./TyRD(fmJSBe3oz'prܫK#j8pkٳؿM4}gZwIkX3>aX|n9#O<vd8  +SY}ВsiR#(䞘)Hq5#\XR|`tPk{=A,鵘O܁oR$YwMe8 \9v 3dYSk[).4nBp#FS2i fmeKiX g-o\,A^ +oRTmJ=8 `qmk{LJaݠ}0|HOD (kWqobovZL0s%z^SٕO#l. +A%O]ǹ)ZouqYM_>67=o*㭠wFbb5QpK4"} @jѨO|:RTAoV%iԽ.[*B }=ȧ{wP蒮I%np wcSCyYЧPL/O@ h +^ +"9ixsR0\EL~%r&=jG_V*5H};'Pҡ4=,j++ !vQOtM[(,T4h[[3ң MS^Y30&ڼmgKx䟄,UXi8gS\FF, L'.44E󯀊ul"+1}׎gN4"RL4.MyqCsjI,ffBX +6[1H1Zh=0 mWHxO:cP" +ѧj=(VQo=JpRavsԪߐ Vؒxb/]#XJM'Jőtsr|=-+) f+$$Zf_:f[})[ =4ql@@#ihc=KJݡg']PD^×l:9'֫mx#-b۔oA4lRYc +zb=er<536]ifAs,!mLЬ/!WrG[ƚgICm{j_`%6lXhJ"<Jtļ©d? ɽk?.<'rwgZJ=W,!LNde.dJm AדwgKY6 uU@MD[)D_W3O6ߑ> t zU0= ;A~ %%okXfI;[KP$c@Dmaӛ}GDp`4pz +_ =@>,J>1[q/}ceL,Uƾ|۞>r9r%\V|&QOK0q@qr7♛05IK=ڑ{uY3&_5mjtV*?J%P[,3b{*L$z0S#trX[R7;8.`yK%B7J*Bz)}PUW](]uԒ"'xpsT7,4U5Zmo m>n&vL +?=8 +[7ЧP]gPRr%{%UYB낚;t^uXܜy5j@% Uy8xю6+ ([3ͪcX ˍnfUPğhXk]JJcVpM:X@3B0)<ň%_M =k%MS]|өIɊgϣкYbnapSF[5vV;)x I&GK}FC_${Fo@@c[]rd%4yͯxyW'JUنu'<_O$k+dp}2>b91%kS;js߇F;%}%+Ӌ<5gPMbl,U\N;FfzA4ȎV +>:Q·edYI|G _Je.ۈ742-ؾ1TyDg;H"y?nRH{dE?#wG3y>KL`Iu (L3P܄x*ƤM>gmp+w.f!pq|Tl!V;m4k(*(M4:^oTdWBjUrlI߅5QiYy@3EO"ӽkGkN“r>T}d1ɭ F!tYr puDR:Co.1$$߃7JeV9q>X/r Ro_V c')U'˯9y58\ +B%?7ob{ӆB͆G[4ڭSE"m~UuA"7z"`/w{7UG\clW+˪u2w= ,c ׁG:"P\pUh^1EȬV7 6/OѡO u^b\2#sm=FLj^T$4L?ĦLuyqSV@Qk97t1OK, ܺWg;aNrλ" Ruc荐JDFD;yUwZERͫ;FYjZ@뒘w l^Yd`ټdY` yn =wVGY*Q6BKM^n>i qNˊLr؁ŗP+'.wm16N3$#lŇ΅xn%ޅPSGM\'rGAkL`gdmڇaZ""#<}o`8)lwg5΀b[J7Da 2ϨJoHv$ʿ/B5\7!A>5bp/Z%iL`9HMP6xef CEebp +\eĵT}Z6sZ}aI= K(WDR%+a7bi0<$+VZ7t+YhjPC?\;\ZdUfաH(vo!=7l& ;Jo& z`mKd2&ۓ5c.j"/%Cx3]^]Dj{r(XK؏]Rt++ңi;h%eÈ(cz4Br]꘩c"1Z|CӹLXD$OyC< +mnV> ^#Q&Q_ԥYOy5<;8+(%qa_^6+AYRlMΡ% hEuR7~Nrlůo!#(m5-x_8#^ ^C,Q|.&}7G'\h{/ +¢:\8A0MЍ=d-]Di&TxCI Vz~|(p3~DŽ1W LE/;O0|/$a 71Yw[7L[l~.n@Z"lI[+tC*Ng;H۶9@ޡ/-6|g7VqOp G ˍy?pO/姵3D$Ri[ReyP7ۓ_Vs7Z0 lFC>mȄLqlM& ke q8buL6T0ojtm}v9 ieKՂ;tŭ q\?doO8J=VZTq?‡>*4tۆTjp,Q!L1ɡ_F]&`07+ȁx,!a$ :]pp5cP CK;JM&C@]p=%lSZ8'W)VzgC1+M2 lߙv[." 4Ҥ+}d=!E*9Q˺Ws}g]jGࣧն͔M* @X=~]0G9zG,t gG +:u.&V7j8e "WJ./0$l嘊5.z-_KL9Ȼh,tyM:@PT20((: +KŞV'bOA[©-~2;S-ۚm}_ +ɷ6='?ZXw-Olٚ d +E?'`3_ O3hO:L܈Ƣ7G#έu' .rr=W:K-ţaQr={tԈZCOل9܀SHۖe;lhA?U2A aS.05}Y\ E9)z~|I"</^#f]<(s@YS@ 82aI:>/_F=s_~r$H 8Hyɱ2JRW ,cX:\*WaDʓCCDK66j,H|qw I2U+#O{U/QGp5(nV)z6YP?􈬂wsmlق"W$&^a#E{n~BH2uEٯZGjC4KL2]4W@؏g H:zדu6 `1ՇM7M1kMs)CD/f\;"?:d>I\wF$i\va]6BO񂒙FpK)7 769f\-IȂk>3C<׭ }[Rq&(Nn5xD5G:[DgJO ʀVv0ɪ-V?}9u9A~_US@+|;/:+ D)4^O6B¥uC7BISG)`9޴MEcrDž'BʝRm,{dFh۸C|ۊ鞢fŦV8W],?w%$]C<^nXz%Ji@/OZYۂ=ps/gM'c>c^F%RE=6HOVt >aY/K䌏ASmq_;6`hʤSU:ۙ c=5iVM\К -Ylo&;c[z=}QJsڈ*hǘ?AQhm^a> .tR:U{ +˲xDS?1Q p*L#H +丐랪Hl҄U0+){ׅv`g@‘Nʊ<)-j'0(,CCTiN`g ao{҃0McH<]?F+F9EКoo1d:)jxLj5/OAA373ɩ@őAdLFKLpfFcaZ<XQ481|xU@ +lFa 7 >;;s͙ :3:+yآΖE 2u' +$ lQxʅ6Ci!%{ߙO1c_y4(_^6jw|8PGg8C.!*A +!j|ӧɞ-k?D<;Fi%~RQt E_;U(I"A8!ޤ3UpqsֻXpE +q.?|i?n'q{dh=Sne h\ H?5boLv&)EK~ċTE*4Gn]v˛(Y#$YF _ Bi +ՌOg I3G2GӐ9S+ I5 27( r;@skd*/ǐMs?_|l`lu;`-~~LWɮ$¦ /lpb*#(OEv?pAԝqP9]P{"N&A'#l_fͤovxɓMabdf} .T*Jo_s>yWC jM`;._ raE1 +?>Y 3Q:"fδg~-Jy"AG[GO ?\|~/vkeu9@> 6ܺceϸ<7j7~Xeآfу6ȅUpBǩ,ҿ&#]wkY$@"T" ׿z;{ c_Z& n;Y3TpYRv4ezrjq\$5_sJHU>V?BW:nJL4ҍh 5XQ{{,-*ɒYMe)!h,@DQ1*xXqM03QJk릊+L_qj|?X]e;jXcGIyb|n+(r7\iB"z3tn MܯbaUYP<ԋdЦ4}_ +20>hA+: += wL +.mqsNESxQĝĹlQ trib\ũ˔+ qAo00s.#$Įeeކ^xjs_3f^红sX$ j_ 3HA%&czya[ҥLq0RݾY)Ct/_R_dKl}"ydpy_ocb)XE5L!2[YbČp~<!~o6üA7F5:G-;f:6b7J~s}$MwG*eM$«qEci팟ZN;B,@z>TvGjL\b;.YTJo&.C#Ee:d}?Os k^(3[OZԁA{RF+}JUϺ'@=| ‘c?cPXEXb^ m Zhi6Im^tA >ᤫ| j`Kn,$o[ +endstream +endobj +2530 0 obj << +/Type /FontDescriptor +/FontName /IHXFNW+NimbusMonL-ReguObli +/Flags 4 +/FontBBox [-61 -237 774 811] +/Ascent 625 +/CapHeight 557 +/Descent -147 +/ItalicAngle -12 +/StemV 43 +/XHeight 426 +/CharSet (/A/B/C/E/F/I/M/O/P/Q/R/S/T/V/X/Y/Z/a/b/braceleft/braceright/c/colon/comma/d/dollar/e/equal/exclam/f/five/four/g/greater/h/hyphen/i/j/k/l/less/m/n/numbersign/o/one/p/parenleft/parenright/period/plus/question/quotedbl/quoteright/r/s/slash/t/three/two/u/underscore/v/w/x/y/z/zero) +/FontFile 2529 0 R +>> endobj +2531 0 obj << +/Length1 1626 +/Length2 14852 +/Length3 0 +/Length 15703 +/Filter /FlateDecode +>> +stream +xڭeP%S;Ҹ6;4.C Ms=gfsg\+(*2U &1K's;3+?@`ħȤڹ$\f 'GI3w ?@h Zl|||T 'gW;VK],}o@htt m+= ',QfUs{@dtt\>,-AK `psZ-@Wo `jwN?ڭEo__0U'7w7 W;oUUIt1sd7㟖 nrteXܜ| + 71`\-nnab3uollE/ w73ߚk[X9G+' t׀h$,}@+e'%w*3 -?5.fo #c<43WFV?}rfG"hWVfAn o*`efw^k9Z]Ak&6Viڀ,.+տȳIH*K(0]wMG+JN7%(/ :+feW_'rpgm4-n2pu+.߮_;z-W,mrqNK AF8Wh;eE՘n`n|q$O<>cOӟ)" +,Fߦa8e1@ξԉ]R܅f>ޟVS7. C< +wBLYEhٜ݃ +XrqIzL3216z J +:.إPD_/7ċ"Slb;̣ + 3A>2rLZx A<د6Y>d CP)a.E65D# +ւNFsBcS<=%^y-!-[T!l ]3lgZp )]rXX +C{R@t·\6\XsbRF|t;n, OH -WХC*Ho +SlKM ?%Ã+o#9kj=!*l1/RFuE/Jk}*GxD`3պ)x+c3ƕU|iKx| FdqM_ ޷_X3F6j˚R/5Ɓ1 BQFQ]>:rgrWy䗀yb TTeƫ1ZE G4 )z5qiP"( {?ׁŘ35ߩSgETԕ's >3G&ùm  bǢ=y(2y][7]bع)-⮩*T]}^8cɧUlz(oW@Ct?L~Y(ӈ}\"Ur+ X{6 5 +] H!˙rV+C{H /يY^:M4'R7ßP318(|8-qrj y;+X'SC,kvhXw›P1ṆqfGQb7x}mv&u G+BlR7acN6mɋ-fqIx߿s`3] N٪W|*5.32|GeKѠFjR$ Ž4ʗ5sHd ?yQ^N^cB\hv7t+ro=( KhJ6g0nQ@PC96u7~ޒߌ/|+2uqsg0۾b` !,UORV=8WYyhzlJ4#p=,1:R0q1o_T縊SudqS岚${[v6!GgXYHHn[ZY U{\@XKH`{Vt[ +5p<p[@g(f}^'J7*-K"m!nkn̹Jn47qo[Xv ΂W{ܛ=Գ$Ic!N`3 +1Fx9EI#``VI 5,&bVKC ^/ \4ðz}Y`<*p3㋇p=;_1EYCiE%=`,!ZvlǨ$3y9y)ܷO$}̷A9Xa(ϹEϽ3QDS{Z&,Z{ZȌ+ ڴFZٵţg-.%=z +yP])w4J tCEx( 0P0_%vI&R1HX jȓ +w!?s=ttx={ŤjW6$ٳs3-RN#RyH] ZB| MloR;[Q\J-__';s۬)&kj"WP^0pOؙ[ˑed/{ / :G]vKM5h.xpXfŖ[ Pfʟp)zs\M:Ζ:'vB˥jD xZn30|3 Πk DZM5fIF 5ƪT@⇒Awt6]`>hҎe\%UP~5+Ripm s ؅%jlY8 +P[왰KrS0Szūٽ@L_)ڪNΤs`&s;pO cwG?<_{ͮ~蠕)cma|jnfSZη)rx0vyޯh>hJV+٘;HédS@I.hNQOWXr( + +lv +t" ?ǘBk,NƇy;LMIj̚ā>ëre9d-(-׸*2ݨG" C#PAuFޑ`6*BmzM] GKy/{+`Z Pȕ~5[VN`{xJbk_ȄEr +O{GM`Mɲskh:mJLBoÜ:(pO ֭ddDEan/E |y0+Z -H&bF~^f~5'0#5 A8& /AD`0eT`T-(9ʥ|#EVl]-'Cm&:Mo.u5:K+c_!I߽Z64;?|_5TyA RRPGWTl_|3,qV||MVsZ`˅I>|*p0z.^|=BXŀω\~R.}Kmċ*'j1 o@ D,$WLjʱKlH{ +i!6ϋC +^] UooagEܸ`Nk1:%'<y--_?j%nKmy͙x [~̗] ă0!\^3 +l#HwSvjQ3-2 "FGJCSl]x([ +pE)NuM};#I^Q/}T%Ry^!Ƌ^ӺuwypCտMQ!m^n?x{Sm.1M8G^:܋W/Gn*tE6rA/Wz^E8Wp lso_&O.@@yO-B ZnҲ-l Đ;ײ3hrZTai)Dȩ99.8%-ȃ"}>k " .yҢZHvLq?Yg@X&Oc^wtlEp iL|~ !O bmv`%]UtFxr 9\VM2Ł]EOM\򂘰g#¡kH()$Gvk9U){4p]6~Eïh~Rq<7:F{aI2qi% F4^&7/LDQr8O\Z!^bP1V2 +h}CKbIMdQh4 ^zoߐnie +FfO>'__v=IMp#4>nvrѳ##4pY;Ec D<2SD|H0K<lGm:0kjKcd]Mך= V+KKÖjC\UmZ rooם1E{I9efЯʿ +LR$iE3|IU?/z8.q6f5(ha4 +9|MVJz_Mk/5! xQ n'І2lk{ Z4w +~8PɭOG|ظm| _>w7 mꓛYj6WFYNmGJK\aۀu vթI{ߗ鿿^Aф*Zc;܆M o03G…a\pCH.Q}A6+K/Z~˒KH o m32o͢WAKRfUF{Sc٦AREIHeiI]~漄ʺw_@q~XT)MB_?3 JK5B<5zXşҕ=E14]%KYuN '%Np71ќgȂ1-βr9.Jx|/,߅ 3NɈ䮋[<ypKFQҸt{XwւL#3N:%WPO {VG"d$75t.gGEqJ֐~ccEi= BJ2]զszf& P-됍Ji;{xP*bʈtd)@?9oF'|&Szs:Hƽ_ bFӿ2|GXBVxfl@>n}ӯK9Ic?eg7nOH"?ܐu +o9~RxZP%8+%3{גXD .6-&FW?ǎ#4*ul \zC}C TZ &fF\u#=çubWu"goy@'Uo"}ֽX`;xyn<[H\C޾ U`Ѯ+!?-ɔKn4Mk:94FF;5^Ex3𝤈'+6OK8_1(!]#M4,M6d81̙:_ A}@iE7)S:&Vڍx<߿)<; pƌ3{ +x0hu +M WZj$YRJ2xrjra,r~.4kGؔJWwQ櫋8+ >9Fݡ~D;ʶd_9ϕs: |BeJ,GULԧHr ]E`݉*G^//59$T "Ү ժ, 6CAvF +neSҶW&5PJSjB24v)M]Uˆyqb%unNMtq G4Jy~1IVz z+q`,n(8ߏP˟odPUI!|lBT+ 6Lig{-q,LE#"Qׅ%PΝMK'FtgX1z$N˓UYϝhF˛ ,t +U'8o$N18 a`sӂ#'5O[c\ Q +vBD(|xUjvEЎْM"Wa-Y0 T^䌯◿Ez//. s ]:.J}uN>Ӓ;y=OG3?7cCt58~: sumAD=9 ^o `# + +I^U)"G @UE+6iD%^D&WiѺ^sopZo -Llu|P:PS0Ij䔧Q 0&j M8JO;r.2J 7?%u\+kC~Aiœvr/&]NOKkCa62~nYSxI/w\j8@,n-W$ m5Kf"9G ;ҊTK> FM.2Pd r5j:g-폎BQv5uF`f +"uK'y*C,sMD[u+W_PpM{%]bK@/g2WMȟ#Or"CXzhW>ۖb;ycl hb%{H[E}|[1]S5*I.NXx?j>MIb$#mȘ(ڭD ꇯ/Y@pM`WܚvMAlÔvb/Z/!:/]{Yɫ h w' G0$ph'.;ũwr 9j,`SMelH:o0е&mn_1TӅMLNLÐ1|칄(t}/%ms>pkN;NBs]ʹYEac~u6b Sa9s6uo.}$SnB&^Jëi0 {w^RYj +lnvzv[_zjg@om#xLoet{ 0+ +Xh:h/q[ذ$lU{ +Qâ-Pxg>_j9E-c_"t[Nu~4FV~MQ?ZxD8v++9zZ2e:0oR+o7XnÈ<#GpQ/v[zzo%,[!f"0^ܯͫY`!]|RY!ۿRև~ҿ@+-'b}?B7Ukr \g3^P+勠|I?@nHⅴdqb,=Q+嫚{ 5Ze({T^;F=NK\ȇ*,er\(Q׾7nq-v@V.{.Ե +)i]辌9ֲNF=ƃ?ߖ4.v'!n),[>f]zU[")^;T'kIl*̗489.3G9n϶=W |ꩬɘ.iD %gCm3!_ESL7;m5'mQBU^ڷJD?GLmK,WVuZؖs8UnI߯udzfE!7Nd~E.OaA? +7x,6KD ?.ʦ40 +?)^AJwy[FNÉzVi%>/%b-rc K|~8Q8fɻк~6~ ҿ΅Qh[`wX,g` $kXLw.ew_+W -2KÏąPk#}z[" ;t# {84pg|B݅m?v?(w[ToTYRxjbr( 2ݯ\_UX/sxO&afY./7OV4oBt ]{QSF]N0R2#9kMnUH"j}12F-/b}]#rTa{@m?Rt)\j0煪}k̢Nw2Udv!#^pqJvcV9?!]p]ybn88/#]ퟸ9%+.X[wLQߨL+Ǝ&y}hJVqnu+kk+-x\0 H|jJTKh6ɱL:0Yz lXr@V= +'= +$;!?~#hs1A%wXǢU⤒5y '$3q2PEmyE1l9heGt-i;w6m_-+(Z/`,0i+4?d.MU12"/wj_ڼqp仗[%-,J +L7$HCy2B)δc1l261ik+1hv,ަЗ? Z3 +~L6e[|4C"b4ړ͵Œp f62Ԙx\ñp,:*')#a +px1hǎ:cہCvy@xҔkpI7t3jky"A(ve(D|Ū{5ע,Gff t[`:(X ~HSpDaxKR`,["g{ 9` +=J݅83 C}EX؂' d4]YJR\ZdZIGC>('ZԚ@E4Ƞ(,$_='p(wU&&>Cˇ$L3S*|*W3~7T+ I37d&?Fw +F]Drpm? fʰ:jp4EeT6XŎ*[7RP̡ur-ڊ8DJA>X.Oq4\<2Q3n|YJw}m昺ƨT_ȊDo2c] J'x[1$ \z'{_I&tC(|7d5(;SxpKP)u%OxhVX+c" m$CO!Wٮo#V\V'¥/DmqTB!gp"nj&L0i~+0Y9WBۭu";X0;S +uZ tZiA 7pP^w5:!t mEPb➖|cCW,mZӸA) 0H3~c%L%hT',/’:pK?2RҴZ*zވ+X;F80JB2ذ5%:'ݑi樰5TZ}7_Z?H ,.vP +EWZB3/6#*@qyO^$jrHʵav4k 42ƥv@ܠ}Wqtr<;`yT\i"z61OCņ=$mD+ZY,=& +WJҫr;Lkx&ƄĔy6ٹ*G@pww!_Ņ$Pvt` }Mt̶umi y2<@57ۆ[ܲ/ur@=y%\3ۇiK|gmE>jL>YDn*D!"$c-Rj)'5藠bowS!HbiljT8ݨאaB^Z!8~*/%wBO7%-Q1"?_R.2ěw<!/>MIu ݷ!R3KfLo%h"bx5NEk޳ Z(xy {|ROڈ]6sMLhGZA, u >Arl3%Gw݇$,ݿEY:Fvٖ\[ ɴ[e}U\/e@yJQ8ͻQKDoh4{;'CK%[Y D֟9YSZn) =XmZGט{C:`m$!>Oܨ$XLM )Ԃi.(Dggu(V@H+Fs)鶴7|7F;W\tegZYp0yjJLrHS +""?6n 8dGҝK(d:N*YMhe~SG̘vxԕ|uVDܨrpSqu鉷z5*-W(gLj %jt>D4[(4/3)-Of%̜65.z mae7'wj"KM_ %#\S:[&m ۃ8isQ],w7.Pom^TP?|YyΗcԝG*QӛA$A)qr^=ɴ맡l.gVqo4HAz{) N{$"}H%+޾pK3+4vrnIh! A"Ը8Wt!86LvǬ=dS-Ҥuhm±V^H0}`UU86«cB kP3TN0zTTm7frb r=/LUԅy+fA +Ny?r("<V ѪZ}5C2X6S {aFrĝyFfa0'Aa-x i?~eItHsD(b;aEqçCxiBN|7Э_I%%}x?)̡G @_Bnŀ~z=OڈM KP[*f; ຝizUFur^7DKїwUYdF.bn9GQWc_QФ&$. t.NyOG&FGCuJm;ƣPoWцH^hBphI3TX?Dwt4EQY" +vay01tsvM#;^4#>Y 3Y] 󍣹F )գ/j`#+2,sw+GR"儋a0|JW5j)N34Z= %MpT|Uq@oA 8 'Xr/=-(!رCw.oJv4c?OJSXCA׈F-=9yTW؞!Y03&t02KE Q$/[UMlk-Tü'2.Oy`Q"*^@|/tC&z-XVSsnƼ l‚}p.N*_|\CUpN@ˆ8Dl1px~Y $  p5hNJpnBܳ: v~u+`HRۓ +#-U/_ /=&n]ZUvcfhbDf2?p|!6BYҕcU_"F߇ _mz钡#f ~|ڹ'v%]"I$˙gNZŶwmPQ{Pt+bRF @ѳ +gi1{9̏`gQO L}Yk`qY88+ +V8r3Qmȣ^hKv[!cx$ FPvsǟ7]я׶8G!4Ejf<\vwrdC*h~y~Sx8Z~&۠.Sw8UD\$Դ\DJo+a|ŗ?/ۻ'>HLQ*cDVFC"ĜX5W;.d--h7J]=5;p`xoN{ӵ",`kHy*BR*BR?Ql{8'7]ݯZZ +}q{e-{Qzȵx +?g\m GA8^Y 3V&n$}_{γCƁ7ʭɀ_tW\[|IVsP~{ EL-uJ8|qL*^*RlJNUzf~JNhG:iAWM !*OyRn_8صQ.H/*SyY"<`ͿvcG:xsX!tG=fmk@d+e'r/0y$J , +endstream +endobj +2532 0 obj << +/Type /FontDescriptor +/FontName /QCDNCK+NimbusRomNo9L-Medi +/Flags 4 +/FontBBox [-168 -341 1000 960] +/Ascent 690 +/CapHeight 690 +/Descent -209 +/ItalicAngle 0 +/StemV 140 +/XHeight 461 +/CharSet (/A/B/C/D/E/F/G/H/I/L/M/N/O/P/Q/R/S/T/U/V/W/a/b/c/colon/d/e/eight/f/fi/five/four/g/h/i/j/k/l/m/n/nine/o/one/p/period/plus/q/r/s/seven/six/slash/t/three/two/u/underscore/v/w/x/y/z/zero) +/FontFile 2531 0 R +>> endobj +2533 0 obj << +/Length1 1630 +/Length2 18781 +/Length3 0 +/Length 19628 +/Filter /FlateDecode +>> +stream +xڬctfm&۪8OlOl;6+mFŶʩzOckޓXQ^(ngL1rqR㖥WEv@: +4"vf*UeujZZ0H' 3[W /u +p6L-EM)y *@h t4(Y[d-N@j#֜b 9 N@ca@wc?&:=? `hhwv [ck +7WAv=l)99;;Z;fUwvkؙ43v:Z:2L, = fh2\,l:#/?>K hm7fp슔z5 vo&v)ߔ;Hoz/=WhqkkyC {d m @ϡ6tXX{: E/5L LVZ8[M-g/ @_l?-l!&/]QAHR^Es`wxt#gg?`^\z.oA,l>bOYo&u?t ?lhkw_uvtí-Ye;~e/iQ_m]aQ8c@p˚'xCJݗII{W~u( v;WE0sLOAdkZىV[pvNxD98629,X!jaZmm+=OJ!Ә ԣj9擎'$S% ԓzUAVMA]vNhp3$`|7q.4MWHAl G߆MJfU~3<:&ъ7h8ۋoi^P^ˡZYX:s&VSi=;bS圕rz&kxtf v" C";hҾ? ~bW7d,n0K\Kqwl6KaCQk8Oj!Xԏ+k2pAy[֛K"i,7|ľQfPˑ29G%Ve. 2yf*N &90ų xKŞDZ2iR1R|"~`VlwIFІzz0Mb.]{̼ K rqX~<^В' +@b{8YF1|ѻtt +K;F_eK*7PC׌1SQX?ފƯSx'.5=Os3Y>H+1Ϛ?RfFz<*AXՃD/>;l|@L k#yHRTcmMjvJ`8c J]쏈+qb_ |*xTؔ' +01+왌 9RÀfvXݠ'ZBv=څakaV)76Me_&`v=ͤGz#Y6:ac$-/,l!3U +|Ѣ]DTq&M4p9oQqդARikr+/lԄ[j$CЫ(Z3,+<{yznh Nq^wBDG]O^/TeWA6'U!6*}(%w{^pq<_QJ@-0јW +Erum5 XЁ;=U5ㅏ(*́ iL9QGOJ x M]_d;ouW@5x[ojS h#ֲ[PڊU~bd $喈Ři`Y-BtLr~U盌]Ez %/>1h~3<}1{1<$ECs>sցeyW6m=fK_)k{d]=#y x.NDPz CU$t@f"oA@jzjMɑzQ=(%5{H8dUn,1yč SXw7J$Z3_)fBp7'#hJMxCAU >6!d{>^vMɍ<TQW%n98|.so֡\hlOMA}%:5p8^ m4ASiLMIdX-yd*]D}ܐ5} /3hضP7`e(Iu;~vSw<<68|x7N2<2MS5%Ϸ>?:VO| @s]&q,vpD*"gY eyu#>!ϒB([AĒ`?]hAFZY x%ѸUXN7O{9{ <"[DȞ"?BZ9@`]|7t2 {S¡ +r\MKa$L' J)&B!_qn_xf zoe<< qMN8k{mAWY244"BtRzCuw_{NAWɋ\Ӷ5Hk;EdЃHrI޼i8+iDƜT%yը(CG=H@[s+V:i +)HӡW$ΰ+qhk`f~pY^텃$f+suR.Yeb/myԴ7dSfy +&_pDp"\@`Rż(Yh^F!zUFc1&;U4dZNhwr|liۤV=P aɾ,[^l{7g/k.^L&HNe;TSOʶ +l y)Q 7cCẵ?%'q +inAY$R`5W-VrXJdcsuX-0\?ަWg2*R[mQQkPې.]B/ 9hTCO <&|) gA`Ȑ'?`{uS~v?[e]hvȚ-ElJ9biY0b7j nI/do+4`,{ 3$f]{Yϭa^=܈ /i!គ w5!VFg?)B]gP^- ,_VS=S_ׂTel!*AYNbUj|$DBwfFv9AK:Dl1MDcFK h&g58k D]=`)Nx\)ޱ#e`8c?RMݰkXwJSEBli E!KNLx7ëBq]sIKl:#^!:G7~(gT >34T +i "ch_JUCE'tqax>)95ױg0TPOʃåt1T:GQ**#>OݡYA VS +j8'"?ӎC7ʧ"zU{cfaY!X筵>ng}n*i5wY]G~=3D*EiwC3 0 +p/2 +07&YRY{{I *A !W 5]n:5R8/l5$İm۲yGL|;\MX;)?j46~%^[ qm0ryP֑sX N:F}~IE)E.jU|Y"-On?:AJp?zi$_勣&C\MTơBDA0gx i\8"n5-/Xs d5n($*tDdod3B^OߚkWE[YÆL%r^KU+oSEAx @]֕[ #; ka +Q4'ڠ<%.$fz|`nxۓ!1Eʔ]I+l7 QǘarY[o + ? QX)cbP  n܉KhX/-t*ꢁ=Ϙ5Ai(/ ;BG+Jh8S:JᛝVo$9P1W +zOwH^,g_ #-`s MYkKZLR0k\&jj=9lR)pkMQ +쒉"MeL~ ,*h@r}D.qv1T3þT{nIOTqj;i%` s/[uR uE<_IlP/3dC}N.VOJGłU]d`^>*ݨ\Nr-TĽJ)e>pݭvt85]ڽ{CN.S5Ԁ ,I' J 3 QpO*..X.$f+bCr"mrϝǟd.*733/6R"_ P WcOUk߫ )fw* d'c;gWmT=uڽ+kNT%{E3_FgJ[\7.)Q^3bY}\tv˾C,?eVv϶z'O2UW٩Reׅ< +^x!_K2VX~Z{Ip `eq1iβӅ`i T}?[#!'P5i4/Yȫ =J#|?=)K^T6 5E/yh yˠF("s~܇⬔-@"]}oe,ud0c:v,E# 'U }hοF~%Z_)r`p}jb.zWT#F"e*"Fl{"JUܴH#8"߄@1/7ZC;G|ٹ9f.NיﺻMˤƨbEӄD3gnrGqs͓{]+-I+jH$խ ǯ?>=|$O )N%>@d-PQjQWc8.gh &F9@K2g vHmp | xM"15 +c"@*XyFKWG ?m,/X-"3YFY̆?GiP:L3'@uN;?l.c{q^6rjVaSIqLa=(cERo} Éf艡27+&POk,L$t@o4hD%"[0܃-F33gНdbدJQ//0Xc2lX`GpM%2ovچO8 94\n>Ը=ڐM BrftF2\@ᷗB&׵ЌX zO'fٵ|kyӛjPweXk3pd|c[B?mxSvπ6E7v G*uNiM F mHn_)¥ C@Д:^O*;˳[\*3>e*#gqkqz]G ^"Mx2Y:ToJ7th;)aJK^nb 'OY}LfˊKڃkRd@0HZB[{6NZ)֞,V$&Gv]|$R;G;EbO[sDZMe ;28r7Lu0#vB3k.2s_.)mWF-dqYw Wc !jn~|kAOK_[rեl%en>A(3H?3Y]9q5'TGeg-y%i%i@UP>zXdrpUg?2]ËN\huYJY!=U5ʁU5+9I9mZd)_(K*DN +Iuʶs?ڌBgnQ[t9nwa#j"qNaXHN ӏ?.F؎ @H[\Ɵv@Vc~/g~ +4 7,-ON2Fx^#Sy&9X WL.qF`b, `=Y0$r?F1\UUB,T~q@Mi!uS_^߿c`:ތ݂ӔɭgD%蹴Kꁃ5K *Q&C +Ih/ߘdZ^E5Ơ]L#ƍ[sg)lέt͉8V酡x2?ɷ^GTaT)U:qH&IJe+ܳduRˣyEq3L3Ό3> [eMLRJnDxSQ +@Z +Ff(Qw<l5Y>?PےxnڂQ4k-W@l,uW4>̶΍p N~GHơh$y4Ql,#،Q؄@ZX+Ξ_Ch3g<ɽ<)C y? mӠ4+p\2_X,f#ůy.V~W˹!{Z1ctSnL1ڥU+;a M~nFScGR+ V's!]yOs-4桄J{j#Eg'I)Rg{Ff}XvQVv>ˢd*H$695"-5['pa @xj-{7t9/B'ތ_xvgONJ/`dh@@Sqƿ5Z% }P-YRy9 ɺg7Dnڱ Ѓ'O74e ȳ?pő_a7w,>E'nE0x& %v-Xa"-l󉨼Qa5t yq?`De%"X\-QZ4cІ%ͥыz/um)x\ +[yb +ׇTG,9(}АUFQ Lx풫3`a{vW4M@c('Hm;۱O3 imw?^3ϷQUw&(XX;"=Bq%Sㄵ IH]w &HuJdNN*&뭂a* Mlh'jDx 7ö RXp?ybJOݤ`!wkSAm(NSԄlOj#=&{}ԩwVMN5Ke౭V/"%:{e~ +uE!weƢ򾏾W' u.O%c)Jj,gS86q6AV{ū틽QZuW4 +kIk*ٶq8$nmRA.ܨ>t;~ќF+˜5]̣i(fV[`N_15hGE _ +Z0/!fyTV9/yjdA0(}W[!d_19ByQf-gUZ[| hLz{(0 2af7[XbD,LzR|y*KTZ)%^\!4p/ ~^ҶBy e 6ɺxZLj$dnЉ8Bu7,7Fs]2m3:A5fYU"}B T@yIYe8FJ0΢DZ>pq糂lNáh(#yqjhS@YJZ_ (b:b7Y$&{D7 kbNGyHQѩ0MswCdzSA({ebU9H5|'=xIM^-}~t*д>%THl4w!A +ilQ 7]S1SrX2l:CDn=@d0҂\:v|tHkq0s%yo~`nj1| G@@.u܁}!h>3KXC`YCoA TfgR#k~IDOCijsE"a*+:3 DӓsWyp7k>8ˡ?=H?ThL 3.ZIt M+ɳ`i#\i%u[Wʚ3Ax&+FJ#jS lhnI,-滵4Xy[_tB:d2e٢z Ԩ?xqqkL[w~ìZH~ry6Tۼ#Hk}@΍OCؚqů'=5b=!zcMǡv !#Pk{YЄ_|B0ӷxirr j EAe5 m{spF\,HitFFHytj ;$sbQ}.ɊC +^l;mkNz8~ڔBFX; R3ޮ|=yd0CAmv TK[gXV(*!> &ɪyg +foPj+!2-MT<%†cUiG/L+!5_迳okkQ KGG}ZuF6_Gs7`urC͊q[ka|!B}qfbF+TEN + +6N~J.uTF?8ɫjFWTlq t(Ĥhg4Q|`3&/=]nMbbVN>(&g(; }%+^ynW.m֌P`B~zLAحRp 9ops6|hHt_$j1YjX@ޡ OGR6oPܷ5MSz/rI (1UIF% MfybD ^VQ͇VoIʡpyU܁<>qś+(rr?ؒ68۵?YӚAjvϳ\B.6Vv*G+Q iڼ1[3UE/ it:iFH."w0d2;eG>ןVhXGW]-Py;OKiRv a_.:VKC{<-^~p8'j~^k{!꽐$-ԢT)\ P^7g#e11 +zU;KgX{ uA׶VU+Bcg9^m޶nJWN}jR +-S܇;M+~>|YG;%oޗGQ8&1md4h=EqmY; V7E>am1k VH*_Ӵ*Pv}|L19iEJCS8IYXduYQuoZ]DdNq"{3TC9عbڳG|A ?2R7<ˈܓ ?/ĺcq[C=jwbmV6^D]<[N6p݌6v\u#9E|#ѧ#m 񦒀7/r?e)-4wr|ο$t՞%)%#~F0Y^Mҭ˽*ɄVzh#Za悂$<"B'[ eE 6T:2HN{BD~>"AktÑEoꠐsjM%b s}~;-2$854JRZe5DΌjZOm(o{K_a_?HRN=mD}d([QCo ; +K\\ o^>`3Lu]LT-[Oi&v8zC}o`q<>Huj?LV#LԮ:=8ίI%*gFV03!&})q<3u"èBJ58cS-@^%"3aAdA$;BPGM*8%t;Vƿ'IYTM|"x6Xm/C~'&VQz` 5ֿk/,qf7&Fڼhh2SRқV[E]-avU`yxxL@|Yy @IZ!//+Tg2ʌ겯'Ւ훙̹GۙBuٕ +woZQy`VR$u.怛_RSp ;=.3J03HRJ5!pq 6%kf6*@zkl2cH·xyJE>(\2N|ǵa;Uu#:K7Cn1U;(6fZpU jIWƪyJպBowJ5+2~7)WpqSJ8pn3 ]xZPQ!wX҈^sv\1q֛Q _{關Po?>S㤱r蚝M,|Ms5o[EgIɛUw_.[U1ǔ4DVE!a]SW >/xZFއ 6򚐡:5ؑɹPcdf+g|CNGM=eBN f*lr |X lv;dVD%(DbZ1[Z V$%=ZKMݟ}eikd }8 <q6)J\iPw 7YT^Ò<"E:Έp|+7J& LFB)|^V_)4a i i%oz.4%д)齡35T^;(N@WEukڴTQ^,@6_z L[\p&.VuTVpzcmcn)bQOVj vf"=5Rdj>Y4Ll}! zU;yI/˭ŧ(8)r !|se߭$/ATBʹ9s"EЮRml5~ +\02D߯dLL2{O3EoHLC*_ϩy' )'*#Rf.8^UA4]*ѳl 8fnu3ɔfFU i14Wybd~@(3"[uFK+$3WU}UmP A4t7 +.uv4<SUɾro#nqN]4dEe0-z amc4Z<oZh9I/-e@%ɼ'b[B;gw0졫rOHEi"_SLuI(a\X(bԐYkoYpӟoDM%Gƹ3WSb2t.yn(Lwa_BSȯlLPdb,w|f?"^6|((&F;]wO2CvPEQBW8,^]š1EʰZAtyJqj%0_t_J_%&O3# +֒h%Lty +$DΣOJ3J(/s+wJ|ZU fMR|I4vaMs:;ONKd17p]yd\8w>Y/SE#o8 p~ PD [^0k7a|qD5Xn)U~l1r2gBXoi*e(y@#E,3lA)pfsN}yquZr0qn5RDg#7ZM@fX8e6{MI&Ԏ^(h\hJ|AAܟPƁ 2M1JU7e + +n>U#>(T2_tp1(h4*+z'dV)ۚ}o浱l5n=xlye~\ u0ommy'O ;!ZFzJ;4kw9 ;(++ U}'[tR AR̳~cv%b4%-v[pNP꛴2Di#ԙPw*ق"d, L6q"/e[uݔuDwZI m,Ø  +NR(L7Pk׬y҃.q> k$gkx7ْtdĻB{*">QW#S!iN9( -s{BмfOCp _\X CY0l@%4]H6"$=K[ \ {$y7睖EHvN-,(b9=٬T+phAy5ݼ?;.VcA\d|¤!CwТ01]O߃[JD, +I.}PulO|ՎҧR3K@);R@Z33.ArP@n(kl9x *pYfK@tø_~۞EYr^G(=̳&Bo_o;A88pTX${k6i&~!B+DF[Ӈ4`6M%ÅlУ>aRkB…w};%7R~t_xHeEPyDL|yJZ|K_)0iP -,4B:Qu|0=^Qf#ai)R9Z)KIj+3?`׻ g֎G"9H!$b[ +{oY@|z1kPݩpQ:Xw|!-1|`L츤u'r CR 1Âɐm~mDL n0 'sX3^a ?g( 0v[4-(BD*:*/v;xڹ$9WQr)QyYՑ[ lS!t8`K%,& zSX\4H,sְ@O'ie켙K &_!d + :Fob %^i6o|G(ь:潣CU}_VA0/!SՃYSwXQIFuT[7"`oc)~깶FbGnfrA͈!, +`NID$<;n A⋉O̻W~{.쒽Epx`+hj9#r s>FY0csʖN$+Jasq4^ggG<;&uƝ#)6q >дamhE |88jLxϨKOlt烈}q9rŲa,l[/l !Z &0'w}cMzBU]۰ [TLLCPT{!: \딦&}l_U<Q7K]1 2?XD"-ӵ +endstream +endobj +2534 0 obj << +/Type /FontDescriptor +/FontName /OAHNSG+NimbusRomNo9L-Regu +/Flags 4 +/FontBBox [-168 -281 1000 924] +/Ascent 678 +/CapHeight 651 +/Descent -216 +/ItalicAngle 0 +/StemV 85 +/XHeight 450 +/CharSet (/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/a/ampersand/asterisk/b/bar/bracketleft/bracketright/c/colon/comma/d/e/eight/f/fi/five/fl/four/g/h/hyphen/i/j/k/l/m/n/nine/numbersign/o/one/p/parenleft/parenright/period/plus/q/question/quotedbl/quoteright/r/s/semicolon/seven/six/slash/t/three/two/u/underscore/v/w/x/y/z/zero) +/FontFile 2533 0 R +>> endobj +2535 0 obj << +/Length1 1644 +/Length2 14439 +/Length3 0 +/Length 15304 +/Filter /FlateDecode +>> +stream +xڭUX]]&pwY8,%;ww';$@h?w?Ot9GըQsL*2u&Qs)P +P7usQ+ԀnO93 a +h@3;; + rrrji100-SttP@@OkCu jXX*JZi%M4lbPq36(X\t 3 \?D]&G tvq|X,M\?k +X;ٹA;?u`* W3gkGWW jeoO5ddOJ}|j]M\@O|.v&^?FpZ8]\>a> _7qt5_#kW3O3Oߖ,􊬃oԹU z3shrt c[or_rS2l1q|Acg٘[ynm?ɺ|E&>fN^V+]=*֮fV ϺK`tv~XYN":,>)W,*Z eRl6#6n|#V@11'y?Ccq/ \+:[{YYY>Ay?#`2]M?{?ܜ?)8u +@O2L [vk=n>60&ހo;|oua;GphzӁWD~tE]< ,șڱ>׋ +PzܬZjeo0]ptEXO(f h`g)'O4c#C y TP1Nyz>"ɲw&/Vp)OwC)  |5V'R8fR )Wd 6ۇ(CI]-`\oVq+{X~SQA-?1s9 ]]ЬqVN; TcDKRuЉ8MK!+%O1RI֤'y_# l.$DE:hB" xռs[g- 4݇mXz x-C2P3*ܷ>MZ; fھ08x߭* OJ]A ockբTOLlYk'_][j_mkhvY<У(wd/b1*5z%(i%gj3)ae#9Afp{GU&GŬ;Y}u>gM{JttuppԢAyMl%C/GWE׍Wqn:`sM+`]To58{" dT8x S$ Oh.mBN +X\ w +GGSN8⑱s*9hRZsu׋{TVvYJi#YCQ5P38jyqõ#7pxo吚#(_ .(V%BI&~X9DrX3!y7ш +QVƗd}Wh=z"J9Y`8ysa" k 6 Ī]ZOP@!?z0ϖI6Or r4;l^<)| IQjK*9B^і롓6i[!;" )]=  ^jbBKwy.Y"Fu~?D_WLֻܶC-u6;'fOtSF)5#ZWha,/C _@nOf:[l\OH"zd`R>SZU- | M[ԄrW 2r9<@"S۴:'ߟ G\-IL]&p3f~35Ou''l{ujK9TnJEafGHx4AZkK;a#@j˿5(>Zs]+L}Uə+p»7#|sݙJ>gm a{txȃeِd:'EpS$|; y}^ƚrvGCsФͿ}X@>f[`R!&r0$"Qf_V(O^B+B+XhMx8XO!cGŲ?IDLoʰ T@tOk\w2c)#zTbI2DV+<(!_/#˩G՗n*iLtqɇjFL t9cSOl[6~F~ȋazQj:Wʐg W;[١$=M7;k嗅1c *YM'lO>K jD2y쐢PvŦg(Dtny^*$& B`}ԁJps1p\υ?"KEQ~Rڊ`OQxPqn_3ria9%b + e +7jۋǦh/h2bCSbmhfQK.5%\0Z! iÿrHXbj-c>ƻisI)bĻb~/:_Rzawݶ7ݽË +N^P3ǰ}':7,5J٫v*yF #G[A,]O8)2(^\9,Q Kwbe@]<}7^rtKD/g蕉a GpQE;ƔkGHiqdjp "gT)oH:("KmM<GM7) +el 0;(U +Z+ `m/4bG lڀ%<_w۫ݜl9af? OBeL +.@#qDKϪΧr< 9E֥;N&T(ĤX2K]-! ~XŘRDL6+}#`AB9jVCyE􂯢>I>^VJN2ksi]M@$Vϭ 2Y` +2&ޕ=}sѮ?py8Ċ>hN_BOϲ(`L-z@n^l( d4~z@{fI mYTTi;$a*=l# "#YޢpC!ٞ2h#ݙ~8qsW2^ƏoPa*CWQkM@%#W/kXgұ8YpD؈:FxV,s`qӤJjLL*5 bq 7gw'v&G-*e:yHS߼wEڌXM~||ʾzl)0 eL!b3U70$/G7f"Uɾ?o iqo]@:PnuiA>)s[RqBpxrNz+i>.ʎbIJE3OӶwcX@QN#8v|ooc~IjzpxMk&Dұ.8Huv5B1؎XIp\KFCؤRSʥ_+J.u%- -0\tJLlwCğsa`B}_/5nC4jaeաpj^$E +L&QKȭ+6Iozx!Zr?-$6gOŠ8C-nqx(?j+MH;Qӊψ14z4ZoUZ~3ҋxVMCht5S3 +"ُ;H<.[m|$)dO=;|b9hgp $H!<<@[h3M\XE"I^AT5T״v\F +M;OS=?Vns91`GLG Ϯrg=eYQ471eyyS2 +MHQ('G=}e^m9L-`Tȉ}zʂնIw;ɳэI&*>qYQ6dy^1.| E<1qV< K +$ :sh?S|<)|n.Hr ukjUCpxK@rwɬZH{ +s(;èM(C#Y't@Y±>iոÝ3R2_6҃,he[KA$JW7 +hc ާccT-{~G֚_~|AY7wC'3-.L6;Tzo9Zїt `"0`*Ơz"!iVc[Mߊ̑MAۀWwޡZpX8DFh4q|>~C-q>ԃP U.aMmqj_:٧vUV&<^ >#Lc%F9f ċ=?`~vF_c^Rx| f0maYRWsBb`q%vSY#tA/%}Wx $|P H=T~#d#%8:t_J-\i%6 5=Bk|o1o~Cc0hx,<6ě[ 9<{̈xy#bw\7v;m<%vk`Sعd'p?Ulg8>OF<Օ] -B[VAr"4[B՝VIp +<%"vj }Fr] f[@{ `^w1[G-Į_A`f9Yd:dԱ?0W j'ePiz+TWԤ/ˊB4"n@W/ BvФ a_p\Pk.6eSn< +GaSz\5P@M_ZX5k&l/n DlQc +$C|ƺ2a'.^yg#c陸X͑W0أi!ts"IL 8;KЗyy1')`uHc)ϺdÕ7\™ + X"Sٶszi9}IjiWw G$+oIüjz6|ls ADtaca`ckew/%$~5J?UxͯwHlniGbKt8 Fgi*[/ᚸWvuutj| XM:ߑTejZm83`&i WhM +6 UBTFCqQ2eYZ˘J岉4 rܗWd=YYN:;Ft&Xa%y%ѭ֌_m"""n YW떭S{31^" +|tkyё.s5GbSz^\;K\ww׬ZoUT镞]4jՇ֦Ov *f,E )}5PW-V- A5~ F E9-˞kSlSvPʭl%)e;y^`EqzSkHBEZDdqcR{G}o}qR^BfՍ :)u)*M)|M ?ࡵ}oB\?,Xt ^B/v8jfF¤HZqeUs.2f#G[em'm0X~5Ev[ֱ s6GR~t|*4Se?\ba௢Vx)PB4@˅nPđIC%Jx}ncI+:i)%+$VbrR?p^-G.'>ʣ$A~pW(#kS+TU_֠ q "Eu&x}ygCH+.[;C*L;4uہPcLאfHEbN{KA<>7Wy$_xwJ/&P_]q~EŇg(;{%:HL|F׷斄 <l:խb)#n5S+A=+7Pb T.Xv˜>#\$=#9bei`޺f턒fC|>X?8BK4g>abj č +3_Z=Aaɼ'+n"bm5 ~6c[^`5‡ES?̤LZҍ|U@_gIKj䩯O`o۶s#%^X+ESn1Mq5iT "ВTAf";tFAlԘp^2"dh/|]4-wY&mm0,j' +򱒟w^Ij6R'^aK}Ldp *_YAQF~Gk-E- R0ryxuԡ3c5 ɸU _DΧ'&'4j&cu^hB^wd& +5_x!R'ϪKR38N2?.Wɻ ;>Ϣ4i5z"D>x0r$^-o7=B?Jv-@dOf9uzspNjn >y'Oe +d*HnSAf;ߠH6 L@팞ג!TlkD@@z)n< +TD>ld,n߻߲&F!RڶLQliVYǹXeuM70%dHE7v +y;x oz7upўvWߠue㾅y08ݲ#юt\A4jeM#t&yM>JJGMݯӷb63ȁ2xrCDїJ|] tQZiqN*֒JI +˄/&F^'um{LZ^t9:2Y\ÅE/P̰ܨ^m7; +u`U*47O' L4d$!SI'/NKpL7N:֞ufL;B9ҪQśm";+} +?_Y%lQ:XAj,łx[Dq_8E`!!rc7pVKi%e 9ryr A@T vA0p*CECj<8$h7f9M(Coph_0$^r@,[p '3g41i}ݨ#qZIdSM6@ۗUp:TPD&'ۨÌ0Cv-e>>:иH "@)% bҠ&#.q +;W/ (PQ%ߜMN`-GloOOF=EOOËG1Ŝ(Ɂ'ͫӆ#^Kɗ,QelTGj]uu.ޣ,+kwkؠ6F8S  4.0Q1Kw~v>%VqߊMđkK @)q6V"lvIb7"`r1E&%" $g(#o]^{k9}Fiˎ>j^lUS&^"(tՆsNI6sĝq҇ND0 %`P1ւ`v'6U.ޑAc +iDѠ4eGc}P~px9лs ~q`~>Luѧ~z(L.,a>X{?픂5vʿѸNmmgT~hWugy%+V{yv0^訜E.bP}%4q5/M2Sgy2a2^Y֛"Z: L$'_0Roh<1w4/:xPQl@Urs`SWT|6N?*N0U7} Nr7_sd]ɟp4w,´{*¼ ^To?ro|eb!jD 'j$NyZς +: }W5>͂3eܦ׈.3+݉"/̪7n^XLo\~/6a㸦'F +w]CZ_}}Qq8u''g4_JYN/O +s\ݿ e^d$>ӷ贳LgK6#%c!&4,*gODy[P=Χ.Fu+!hڹPNjAX|\f|+;<4ֶ$受<۪gfԣViFj8ϲ^QuSR[ws2S.M$hkhxHMSIDbOyʹ4{ NT}{^jpb:•j;X\\vyhl\I=4X{׃1O<;=e[t`v$$X9P^Fnl1-g~{;7 nA*Y4؆3Rm_K9c$TK/g}5#c?"^,PuQNj/~#XivFRu(?4ih3ku*Q9aqKAzX2>`oz9Wݱ@LH9xRYMM1 TB4A0@0K|$ kybǦ^ Pi/jKNȼUfno^jEŷG0ΤzY;YxƢr&1Ӽ2(n[oPbCY 9|V͇ n%4-aJm*/O薭Id_r^rGOTV:t/Mvf@C^=z^D(;X:T=ߎX_*ZUG9kzy".n}xpn T1֭@̓rMc5wwbvw`GʹI#wG0ervsbRZ9օds+hrPsjX$-m{D;y);]b` iBaUͮ@T- +z0a +*3|5c(B6ٞo#}SȹUvh+B}=Em||VYL-ws(r?"Sw^Lh_M#/4yY͋ɒw7N3q@=c/&ԵqԕCuMw(ÙUp9?&PB jPl2xW+h5=1fGk3̋a?]Y[CBld W/xұuJ6crtBcXjtzr1޼v7Kw(MO9xtO I ӝB-x3#S=xMIˣ:YZ\C90:LH]4͌ dDl9VUu]܁bXX?QKsrfq7@JmǙl{kЍ}2[1 7D?PM\(3:! qbɡ,ech)c8\Mbs_ {Zތ~Sg'$QAbz^F2ky˘eS٪4czUh8jBCT&Zd&JR).%SsV;5OI?¥lADt`2Vp4|wR7u;#P5_܃2$o/Nǖ[Ew >2{SG" ayCx4Yq4PN4f, )46q#xRosLl=轡zh,D卌Qll&jet^%vNWKĥt} ^0~ ~Ln$:ۄ0{< jJ(vJ@Q2Sp٤HN&{.',AXCCW2`Q73||8Hd-o4Qo#o<^d^Wē{e3A>i{V\lqs4]z9ue,ltv2hav7 +!I\~GL}wlxRRw}씓掦4z_lR)+ 1]vKI\[A1AM`';ҐӰ*a\G<~mҜTTR2LM|)Yʁ7!i^R>$˛,﹁gM÷ٚ %(O>NX4,c3]1Sr +x/ɌC7{xӋQWrC7$]ӣ3)[NM]IMI]!݁Fr*T,TM wLi W@SHRG)Oudh$H,1;"˓,36B"y[^Uf^~9?7j +MN.v˦BԈɜv.bÈMjofBRxM;g<ކx⨴.l)R'Nr0JK|]s6DQǽMV1e!dX21Y +endstream +endobj +2536 0 obj << +/Type /FontDescriptor +/FontName /OPVUMD+NimbusRomNo9L-Regu-Slant_167 +/Flags 4 +/FontBBox [-168 -281 1000 924] +/Ascent 678 +/CapHeight 651 +/Descent -216 +/ItalicAngle -9 +/StemV 85 +/XHeight 450 +/CharSet (/A/B/C/D/E/F/G/H/I/L/M/N/O/P/R/S/T/U/X/Y/a/b/c/d/e/eight/f/fi/five/four/g/h/i/k/l/m/n/o/one/p/period/plus/r/s/seven/six/slash/t/three/two/u/x/y/zero) +/FontFile 2535 0 R +>> endobj +2537 0 obj << +/Length1 1647 +/Length2 14611 +/Length3 0 +/Length 15466 +/Filter /FlateDecode +>> +stream +xڭeT\m&L7Nw ܃3<;gά}g^ꪪdMNB/ljg 9330-m]le镁.RF6O\hli3r41  Gp4pP)kP N +r6T@  %%/WHA@$]m,M&@`f`b2'5'O.a'hbit7쁎NNK' + {GO OLUQLq:[9ؙ}jڙҿOOp;0t1Ifh0\,Ahnhjtrv3Oǿbtvژ11|4qmn c_@fvfM]s:남 L@6SK]PFw7l1>w @ϲ1rp,M?F6'wv! 2=3;ŖN@SEKg K2:XE~11LO5 A5Ϻ+FQeY aIögW8zӓ:C%"bgгp2}8r匜-:L LL̀I|ؙG*F _`Gϊk|f 4dgl#ù;whBLb(ľQƮ/=|6{۾4H ew*"uoE'A ~)bƩF6΄~+4T#_jodH&i q(? +ON)>P v_C}%uDwVEmb_#`M/}j;*܆$Z9)$A|Z.+-~{BKݍZ svaۧ7V U-)S3ύ'C$&HR`pS[_S䛾Ѭ{yn3HR$"j" A{_qjn UB\1"f\ה^? k+THǦ~p̎=9z k:AT> \3za !/ّ_*j}' rCÐ4`ەW}\s +lgLgCe|Qs2ُmxRz@IW 1ꇑFF}K@z#+4jjRb9{U&:swӋT̓Ԁu|ϲX6Zc\~7$z;@A䪺˞!~d\9K?e`&djX} eErc|!;},HdHD6q !eʼ:4bՌָ*9;QUwo~D5dk.&e kf:HqSuF:ѧ$g˅kMhҟǷTJa3W>RtTd˔F,#-IB; eWEascͶV^jXJW? +<8,${_į AOPd7`r/'*bE,.GxQSZ*X*_CeI |r-Ӭvnm@C~=/j20:iY/d|Mg-% &ۚ\& Ed]}/Bɺ^L+_ݮ0z`k ++Rv "0>n%fPzG grBz¥rʍ]p(x$2>>9tQ +v&u1NBtO/FyJ)#]-CoBw큤̨T|ArC xZ$xɸӐ\ۙ/F{FpPcFcLEF+u>z)_9 Gsh-D 4ȉ %O+Wɧٖ50YF3DN?r5?Ä/A>)*N#ًK3ۿtb'9 + 6&:̽0B5k"QL*WC,*h ơtґcO +5`Fݔ0Kvե^|ۭ.&|89 +{`+v;ƙᙫ+es[NhVP^{;4%l^u'l\4[\!rj}.RQTLCYwT\k92լRֱ=<_Pn:iZCbDVG\G^3VG>w9>ӹ1:،(F!nV/qo7;+R[axCq8xoͷpGF4gtѭv񤞡=ۗm4?}ǎJRѣ܇Ӯׄh|"lնW@T=.hڦ(:3Mi_xZSz/C9C J8KZ#4/]4īW~b|TlNy a^k 4㍜᤻e`V[alXiƖ,>zXF5(/y8Ak6e9AU'Q=E2upAUihY$o>^!=$ [`X"- +*0 +tda "_2K^g8sub̶g?R!3`('fX4L[l_38k܆Ny;ːz LIq/gm*Wm@片Pf)8Z]?z).ٶT OiXc@Y_\~wi ^koaCE{:~58t28}=h"cwtwBõ" bAz'TZ7`"teu_\$N'gpnOZ1oŪd~Bunt3H{mZ37wIxC+#6waJ*oHLuM襳/&=E}1eg X30Qܞ ;^Ӻc;Spv~lT}2F7|#8HwNI-%ٚS Q9jMʍc03>B%](GWt~AhI-_ҫu3x#`_Qq7uKW#l̳jn6@WΪ heʈV+̒/U2 +BY6g2jv_dglq 0Q%RAS=f#$nEykMAauhAۡ>%ؒR_d3G4_'Oij5 +-BdėuB:0EZ[>$꠮9*kn/2|s3.^N;#-3#đFgaa"bRhN}+v/ &cttZOm(DCG_e ohמ;`5vFx k(yF'DAVܷ5ש`vC+Ӫ\rB҄^Y^Z6ES@i6pzba3F?Mp< A/3mZ@Lɔ5++,;{lkk +^xy0}<հ7wTHT:ϔ׿^]::0GR%7wШ_7fZhW,3x3vkdܖɴԭQW< $MWHi{nTLFE wn*ImWPf3֘Qz,:j 7)ޭ<2ӽv͒ɉK*Ή{I]T! & }1ͅ)'Djy*0EL?|Kv&fj'BFMmebܷ-nj7)e9'E97<*MQ侈N=#Q {)8/N>i@[R^QF|!*I+Ci0A/sj^d>E$qv~vt?7ДI\ه|JxK%~I>$\vpߥ,MuwwRWZUex 39Oo5:T#Ҩ +_).-f6)OךU)pՈġNjrHĚ^77JerG"&s4g/WGT Wh"WU? /=.2O1 ;ILRǕ*D[AEܣ_{ Y4D +I`7?{g#]G] --,b`^mZj|rO3ÕML1:́„k2(Z.hYN`5_4Dõ32aۼKR>)q@yr +_ݱY\8ܓ:o#ox\=vNpx.u|WɥQ̑R9nU=W ?PReqa([]KvQ&u7e Z's^C\7 l"k}4 g?nc*]n bem:Ι:]7 ~2CDc1!0YP#shqwiAopX37NkCڐ#fnCbp>OǰSk\%GiFP>#P2prȌ+<[j$i00r͡1MLܻI}9#)<Z_ljmBB96g`PL-?KڵzȥĞ't|ugk[J3CayC:٤gS:t}wɓ-$#lQ'HiLy]#.gŬ}Z$!2js3=xO<1̝oq#Bḳ'☮g 3̦hw',Ttkg3]OYŝ{߅"56Ϡ{7æ01[qKWAΏh.HgNHS`2$X \kWwQX2^sqѭh r(8.J8b7@9|ʼ*aYkLÄ%żm).lV$*Vc2Io$-mA +^淸 @tnG@:7u +u,5Ь&7,B(%~(&r>,/kМ xcE2O)Y!31p7`Dl!IAV#}_ni gŖ7sJ* 1St̎#]#p9*Ry2NAʼ£4IH*ZlXHYrؕ,8q+???|7&Q,:O+d)}3UCj\N2!cnj@V/dq] }Zp%e<2Rrpz{"hY,U>Pw pPߪW[3.iͰ$>bx IrWٮBK {S%{}*Y +>Qգ. +>gJڻGK8 +F)r>S77U*BJ drO֨t,E:Zʃ`C썻TJTT n7ވQp?`}~ +^oxhP?j|itLϛ3 ~Wt6yj=;6_c1)dTlZCsR~;uZmP.dGU0?NA8>h,'9Tp|EJL&$Av\)ߊΙqP۠ZjA6`{|Ah\5!I)gq Yꋬm]OvO8hNB#AlwHPXfjJG'}[2޶*#Pzr =mGJEh[Z|2(\U#H:eߌJYE9&lmxZ/\L2)ɬ(+I:)p/#C(16oEFd\3Ϥ^)~.2[{~.~$n1G7Zܔ!/B5A O +:$_[H~q T@֪FùQv3`S='%}e|MibXt ~#ѥ)<-wB NXQ*HdMS\F||(SEW?/)8P !3)y%(00 {P3^; QeޅḠ 󌶌E 8.WDpUn9D /Z\ba+0][EkсL<墫b|onސsܯ +]sJ̵a1Cee0F'n{F㨄]ie(kFc<;~K) Qѷ))LQƣoC.uxfnnic{nrbYb1mP6U 1RXaʞp`1KNCGS{󅇝p|ey㗗zy,ji}$6O'\TڰM󱹃ÔHDmiA8!p4g f. PXi: \h⁻ @:pUm%pr'7K~K?/0IҚ5aUQg^łb U2;́j($:tM~v3ړ3wO0~!ߖ,w)Щws/ ßRNSϻ9j;i뭉joݬy$~*ax8Bu2^ +_nU.1κ㈂QWesl `݋LK!E07 +V EA%܂[~<2x* kAT + mm%G +ǥ_$Yp z4Y4y@7TnF.(IClqvO*W_H'ϋWuCr sǻ=L#vR>t$±H vّ];#YPY".;䬄"J.?_ A_m׻R;*Obf|wrvev^\4m ٙ- 8s@T#AfMأM5YU@xZի]'1~D~XCÙ 5M*GrWb[:#s3(2Nt {ggqm.~w&` ah-ioapWosJ, C8EuˇYH'֒q8E;M 盌*YR@vW{bЫ-= o-f`"UH˵ep ;^dK"٠[] /i\xi }_HUgQM2M_&["x_Vf4|,\`GTL;PE[(|NȮ'Io[;dT%t3!E75k +?$}]CUfhߣTF"1c-òdl |[8ԬQw?5Rk\˭3a 1+2P*ӽF4s'㶠fi94<+?`sq"֙&!{]4Ԇx@3W|ϕ~5gQZP$%; %&-2Fnv 呮Di8ĮK),&Y4m9/$G1BfK+24N,mt{aHJd*%{/u%19|@tɺ2PֹO_բoAK;o_Eo-ZʭsЬ~w 8)Z/oNڛaq JT%Kgg29#[᳒4}ڗa2]z#xl,y ?Zs҇Mb_?-t|O HrIP& #^\T;Vac]i6ڿ&"?˕`b@:!\YİhmF`H`V/yuM |RuWIWڱ0ޘcr8XZ 1Mwp^WzW~TlfU.vt"ǹMC hU4{S 7hч|qЖE \Ixq $a~'-dr=A!P*ˠN{.3Fzn1)D U뮪za.崔u4x5M^Msc 4]}m OeΞ?Vco`uc. +< wø]Maxʿz;J9Qf]͆G~ sSy| 4Otq~a-[ψc9z"ݮ'dnc0hyru鎓+RC&fhK5UG wf"Q0V=c^t{T']Q. +yS::)-}iSRGg>Y3 sIYk?@k9^ YRJv³wW6m\P:1B~yO 0KA^B-(\L+uE6lҵlޅZϧp(S:nP-ω|\(%]~b65Q-0 _8F@p Ay MB`^oa_\jzeb~ÃmSq ?s:&O ^۲_G7TK=XwvάW C?4/}?Y|0A Q3vȈ޹| +FߗӏEV&+ӽIs{$:qq uLZ`>*ėqӌHT*{X`=Iİj +7Hq_j?9Ol]Mڍv o+S6͖Undf?CwAC7d(^gMnJĐSz!k`V*yT[kwU¹zEGlUo*tegr?QW- Vn%{mʊhfuO zP~~;3G5bכuGQ e? 蛞J'IlË֮j+7OEƴNRx00+j2X>f^_+u&L)ɯEr@]xAo/ct(-$%Ӻ֤&zKXi@]Z4A/uK##a_u-"0]Yhmhm־ ~(i}дT%uΟ EҪr Yr ƿzb e\8TV/*@M]1UߞZ>qlhuqlތ(4A}z3lJuU+ +[桎{_$\|ݟ\28` ].yBh#e~BYMH0DSmE^l/(DYpz[5=(G*rM 0]õ< ͘!Rx(pBF'Rզ_VSU??$8o XY]h$ .둰**t%0E2C3CCMt)x? n +OloԶQ4TQE۾~%LNTHfTP.=U<\þܣ6v1E`mkW;xhyNя_; QD2F`Q++xYJb?Czq[{%紎+_L2;u *x{{ܒ}h5">O&}ݘ$O+@| h Yv)εu|YD11yH4MTyh2pNW4s`1H9rGe?J2Q$zZ;NGٸo^W3/37 p0t}ߡeb}',>ʊgCd93:",4ͨlFXZIy2^\pu`vѤ=gFrpSb4S# (S Q|n#7]2$\ĚF" ܱ.LWZ  +ݣ͵ QAKyvQ\e?N)7 lpm]Cd5֭ii]}N)#q ^Qsk濖[Mr׬/NZD[$J ƤRJf4'L(]hDlZLԓAY*~O7F 6v ILwf7_M~ٯ[99B ć0'݀(-fb!{,05xr<8saR^8ɪ8Mqxjh֨q] tdlQԊ0T:oV`.{tf +x;({ۺf b~m +Ӫc6Im ,Y"xߒN/k +endstream +endobj +2538 0 obj << +/Type /FontDescriptor +/FontName /CRLWAH+NimbusRomNo9L-ReguItal +/Flags 4 +/FontBBox [-169 -270 1010 924] +/Ascent 668 +/CapHeight 668 +/Descent -193 +/ItalicAngle -15 +/StemV 78 +/XHeight 441 +/CharSet (/A/B/C/D/E/F/H/I/L/M/N/O/P/Q/R/S/T/U/V/a/asterisk/b/bar/c/colon/d/e/f/fi/fl/g/h/hyphen/i/j/k/l/m/n/o/one/p/parenleft/parenright/plus/q/quoteright/r/s/t/three/u/underscore/v/w/x/y) +/FontFile 2537 0 R +>> endobj +2513 0 obj << +/Type /Encoding +/Differences [2/fi/fl 33/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright/asciicircum/underscore 97/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/asciitilde] +>> endobj +2517 0 obj << +/Type /Encoding +/Differences [178/bullet] +>> endobj +1437 0 obj << +/Type /Font +/Subtype /Type1 +/BaseFont /GFAWRG+CMSY10 +/FontDescriptor 2524 0 R +/FirstChar 178 +/LastChar 178 +/Widths 2518 0 R +/Encoding 2517 0 R +>> endobj +1447 0 obj << +/Type /Font +/Subtype /Type1 +/BaseFont /ENUBEQ+NimbusMonL-Bold +/FontDescriptor 2526 0 R +/FirstChar 35 +/LastChar 122 +/Widths 2515 0 R +/Encoding 2513 0 R +>> endobj +1445 0 obj << +/Type /Font +/Subtype /Type1 +/BaseFont /WPLVDS+NimbusMonL-Regu +/FontDescriptor 2528 0 R +/FirstChar 33 +/LastChar 126 +/Widths 2516 0 R +/Encoding 2513 0 R +>> endobj +1494 0 obj << +/Type /Font +/Subtype /Type1 +/BaseFont /IHXFNW+NimbusMonL-ReguObli +/FontDescriptor 2530 0 R +/FirstChar 33 +/LastChar 125 +/Widths 2514 0 R +/Encoding 2513 0 R +>> endobj +1107 0 obj << +/Type /Font +/Subtype /Type1 +/BaseFont /QCDNCK+NimbusRomNo9L-Medi +/FontDescriptor 2532 0 R +/FirstChar 2 +/LastChar 122 +/Widths 2522 0 R +/Encoding 2513 0 R +>> endobj +1109 0 obj << +/Type /Font +/Subtype /Type1 +/BaseFont /OAHNSG+NimbusRomNo9L-Regu +/FontDescriptor 2534 0 R +/FirstChar 2 +/LastChar 124 +/Widths 2520 0 R +/Encoding 2513 0 R +>> endobj +1108 0 obj << +/Type /Font +/Subtype /Type1 +/BaseFont /CRLWAH+NimbusRomNo9L-ReguItal +/FontDescriptor 2538 0 R +/FirstChar 2 +/LastChar 124 +/Widths 2521 0 R +/Encoding 2513 0 R +>> endobj +1138 0 obj << +/Type /Font +/Subtype /Type1 +/BaseFont /OPVUMD+NimbusRomNo9L-Regu-Slant_167 +/FontDescriptor 2536 0 R +/FirstChar 2 +/LastChar 121 +/Widths 2519 0 R +/Encoding 2513 0 R +>> endobj +1110 0 obj << +/Type /Pages +/Count 6 +/Parent 2539 0 R +/Kids [1102 0 R 1135 0 R 1168 0 R 1199 0 R 1230 0 R 1261 0 R] +>> endobj +1295 0 obj << +/Type /Pages +/Count 6 +/Parent 2539 0 R +/Kids [1292 0 R 1324 0 R 1355 0 R 1386 0 R 1417 0 R 1429 0 R] +>> endobj +1438 0 obj << +/Type /Pages +/Count 6 +/Parent 2539 0 R +/Kids [1434 0 R 1440 0 R 1451 0 R 1456 0 R 1462 0 R 1474 0 R] +>> endobj +1496 0 obj << +/Type /Pages +/Count 6 +/Parent 2539 0 R +/Kids [1483 0 R 1498 0 R 1516 0 R 1520 0 R 1524 0 R 1528 0 R] +>> endobj +1535 0 obj << +/Type /Pages +/Count 6 +/Parent 2539 0 R +/Kids [1532 0 R 1537 0 R 1541 0 R 1545 0 R 1549 0 R 1555 0 R] +>> endobj +1568 0 obj << +/Type /Pages +/Count 6 +/Parent 2539 0 R +/Kids [1559 0 R 1570 0 R 1586 0 R 1600 0 R 1612 0 R 1624 0 R] +>> endobj +1639 0 obj << +/Type /Pages +/Count 6 +/Parent 2540 0 R +/Kids [1634 0 R 1641 0 R 1660 0 R 1672 0 R 1684 0 R 1697 0 R] +>> endobj +1721 0 obj << +/Type /Pages +/Count 6 +/Parent 2540 0 R +/Kids [1709 0 R 1723 0 R 1735 0 R 1747 0 R 1759 0 R 1770 0 R] +>> endobj +1791 0 obj << +/Type /Pages +/Count 6 +/Parent 2540 0 R +/Kids [1782 0 R 1793 0 R 1801 0 R 1814 0 R 1824 0 R 1830 0 R] +>> endobj +1849 0 obj << +/Type /Pages +/Count 6 +/Parent 2540 0 R +/Kids [1838 0 R 1851 0 R 1855 0 R 1859 0 R 1871 0 R 1881 0 R] +>> endobj +1903 0 obj << +/Type /Pages +/Count 6 +/Parent 2540 0 R +/Kids [1892 0 R 1905 0 R 1911 0 R 1915 0 R 1927 0 R 1939 0 R] +>> endobj +1954 0 obj << +/Type /Pages +/Count 6 +/Parent 2540 0 R +/Kids [1945 0 R 1956 0 R 1968 0 R 1982 0 R 1991 0 R 1997 0 R] +>> endobj +2012 0 obj << +/Type /Pages +/Count 6 +/Parent 2541 0 R +/Kids [2002 0 R 2014 0 R 2018 0 R 2037 0 R 2041 0 R 2045 0 R] +>> endobj +2064 0 obj << +/Type /Pages +/Count 6 +/Parent 2541 0 R +/Kids [2057 0 R 2066 0 R 2070 0 R 2087 0 R 2112 0 R 2130 0 R] +>> endobj +2189 0 obj << +/Type /Pages +/Count 6 +/Parent 2541 0 R +/Kids [2164 0 R 2191 0 R 2208 0 R 2217 0 R 2223 0 R 2227 0 R] +>> endobj +2250 0 obj << +/Type /Pages +/Count 6 +/Parent 2541 0 R +/Kids [2241 0 R 2252 0 R 2263 0 R 2273 0 R 2283 0 R 2291 0 R] +>> endobj +2299 0 obj << +/Type /Pages +/Count 6 +/Parent 2541 0 R +/Kids [2295 0 R 2301 0 R 2305 0 R 2309 0 R 2313 0 R 2317 0 R] +>> endobj +2339 0 obj << +/Type /Pages +/Count 6 +/Parent 2541 0 R +/Kids [2336 0 R 2353 0 R 2366 0 R 2377 0 R 2387 0 R 2401 0 R] +>> endobj +2412 0 obj << +/Type /Pages +/Count 6 +/Parent 2542 0 R +/Kids [2409 0 R 2420 0 R 2436 0 R 2448 0 R 2462 0 R 2475 0 R] +>> endobj +2488 0 obj << +/Type /Pages +/Count 4 +/Parent 2542 0 R +/Kids [2485 0 R 2490 0 R 2494 0 R 2510 0 R] +>> endobj +2539 0 obj << +/Type /Pages +/Count 36 +/Parent 2543 0 R +/Kids [1110 0 R 1295 0 R 1438 0 R 1496 0 R 1535 0 R 1568 0 R] +>> endobj +2540 0 obj << +/Type /Pages +/Count 36 +/Parent 2543 0 R +/Kids [1639 0 R 1721 0 R 1791 0 R 1849 0 R 1903 0 R 1954 0 R] +>> endobj +2541 0 obj << +/Type /Pages +/Count 36 +/Parent 2543 0 R +/Kids [2012 0 R 2064 0 R 2189 0 R 2250 0 R 2299 0 R 2339 0 R] +>> endobj +2542 0 obj << +/Type /Pages +/Count 10 +/Parent 2543 0 R +/Kids [2412 0 R 2488 0 R] +>> endobj +2543 0 obj << +/Type /Pages +/Count 118 +/Kids [2539 0 R 2540 0 R 2541 0 R 2542 0 R] +>> endobj +2544 0 obj << +/Type /Outlines +/First 7 0 R +/Last 1099 0 R +/Count 11 +>> endobj +1099 0 obj << +/Title 1100 0 R +/A 1097 0 R +/Parent 2544 0 R +/Prev 75 0 R +>> endobj +1095 0 obj << +/Title 1096 0 R +/A 1093 0 R +/Parent 75 0 R +/Prev 1091 0 R +>> endobj +1091 0 obj << +/Title 1092 0 R +/A 1089 0 R +/Parent 75 0 R +/Prev 1087 0 R +/Next 1095 0 R +>> endobj +1087 0 obj << +/Title 1088 0 R +/A 1085 0 R +/Parent 75 0 R +/Prev 1071 0 R +/Next 1091 0 R +>> endobj +1083 0 obj << +/Title 1084 0 R +/A 1081 0 R +/Parent 1071 0 R +/Prev 1079 0 R +>> endobj +1079 0 obj << +/Title 1080 0 R +/A 1077 0 R +/Parent 1071 0 R +/Prev 1075 0 R +/Next 1083 0 R +>> endobj +1075 0 obj << +/Title 1076 0 R +/A 1073 0 R +/Parent 1071 0 R +/Next 1079 0 R +>> endobj +1071 0 obj << +/Title 1072 0 R +/A 1069 0 R +/Parent 75 0 R +/Prev 959 0 R +/Next 1087 0 R +/First 1075 0 R +/Last 1083 0 R +/Count -3 +>> endobj +1067 0 obj << +/Title 1068 0 R +/A 1065 0 R +/Parent 959 0 R +/Prev 1063 0 R +>> endobj +1063 0 obj << +/Title 1064 0 R +/A 1061 0 R +/Parent 959 0 R +/Prev 1059 0 R +/Next 1067 0 R +>> endobj +1059 0 obj << +/Title 1060 0 R +/A 1057 0 R +/Parent 959 0 R +/Prev 1055 0 R +/Next 1063 0 R +>> endobj +1055 0 obj << +/Title 1056 0 R +/A 1053 0 R +/Parent 959 0 R +/Prev 1051 0 R +/Next 1059 0 R +>> endobj +1051 0 obj << +/Title 1052 0 R +/A 1049 0 R +/Parent 959 0 R +/Prev 1047 0 R +/Next 1055 0 R +>> endobj +1047 0 obj << +/Title 1048 0 R +/A 1045 0 R +/Parent 959 0 R +/Prev 1043 0 R +/Next 1051 0 R +>> endobj +1043 0 obj << +/Title 1044 0 R +/A 1041 0 R +/Parent 959 0 R +/Prev 1039 0 R +/Next 1047 0 R +>> endobj +1039 0 obj << +/Title 1040 0 R +/A 1037 0 R +/Parent 959 0 R +/Prev 1035 0 R +/Next 1043 0 R +>> endobj +1035 0 obj << +/Title 1036 0 R +/A 1033 0 R +/Parent 959 0 R +/Prev 1031 0 R +/Next 1039 0 R +>> endobj +1031 0 obj << +/Title 1032 0 R +/A 1029 0 R +/Parent 959 0 R +/Prev 1027 0 R +/Next 1035 0 R +>> endobj +1027 0 obj << +/Title 1028 0 R +/A 1025 0 R +/Parent 959 0 R +/Prev 1023 0 R +/Next 1031 0 R +>> endobj +1023 0 obj << +/Title 1024 0 R +/A 1021 0 R +/Parent 959 0 R +/Prev 1019 0 R +/Next 1027 0 R +>> endobj +1019 0 obj << +/Title 1020 0 R +/A 1017 0 R +/Parent 959 0 R +/Prev 1015 0 R +/Next 1023 0 R +>> endobj +1015 0 obj << +/Title 1016 0 R +/A 1013 0 R +/Parent 959 0 R +/Prev 1011 0 R +/Next 1019 0 R +>> endobj +1011 0 obj << +/Title 1012 0 R +/A 1009 0 R +/Parent 959 0 R +/Prev 1007 0 R +/Next 1015 0 R +>> endobj +1007 0 obj << +/Title 1008 0 R +/A 1005 0 R +/Parent 959 0 R +/Prev 1003 0 R +/Next 1011 0 R +>> endobj +1003 0 obj << +/Title 1004 0 R +/A 1001 0 R +/Parent 959 0 R +/Prev 999 0 R +/Next 1007 0 R +>> endobj +999 0 obj << +/Title 1000 0 R +/A 997 0 R +/Parent 959 0 R +/Prev 995 0 R +/Next 1003 0 R +>> endobj +995 0 obj << +/Title 996 0 R +/A 993 0 R +/Parent 959 0 R +/Prev 991 0 R +/Next 999 0 R +>> endobj +991 0 obj << +/Title 992 0 R +/A 989 0 R +/Parent 959 0 R +/Prev 987 0 R +/Next 995 0 R +>> endobj +987 0 obj << +/Title 988 0 R +/A 985 0 R +/Parent 959 0 R +/Prev 983 0 R +/Next 991 0 R +>> endobj +983 0 obj << +/Title 984 0 R +/A 981 0 R +/Parent 959 0 R +/Prev 979 0 R +/Next 987 0 R +>> endobj +979 0 obj << +/Title 980 0 R +/A 977 0 R +/Parent 959 0 R +/Prev 975 0 R +/Next 983 0 R +>> endobj +975 0 obj << +/Title 976 0 R +/A 973 0 R +/Parent 959 0 R +/Prev 971 0 R +/Next 979 0 R +>> endobj +971 0 obj << +/Title 972 0 R +/A 969 0 R +/Parent 959 0 R +/Prev 967 0 R +/Next 975 0 R +>> endobj +967 0 obj << +/Title 968 0 R +/A 965 0 R +/Parent 959 0 R +/Prev 963 0 R +/Next 971 0 R +>> endobj +963 0 obj << +/Title 964 0 R +/A 961 0 R +/Parent 959 0 R +/Next 967 0 R +>> endobj +959 0 obj << +/Title 960 0 R +/A 957 0 R +/Parent 75 0 R +/Prev 891 0 R +/Next 1071 0 R +/First 963 0 R +/Last 1067 0 R +/Count -27 +>> endobj +955 0 obj << +/Title 956 0 R +/A 953 0 R +/Parent 891 0 R +/Prev 951 0 R +>> endobj +951 0 obj << +/Title 952 0 R +/A 949 0 R +/Parent 891 0 R +/Prev 947 0 R +/Next 955 0 R +>> endobj +947 0 obj << +/Title 948 0 R +/A 945 0 R +/Parent 891 0 R +/Prev 943 0 R +/Next 951 0 R +>> endobj +943 0 obj << +/Title 944 0 R +/A 941 0 R +/Parent 891 0 R +/Prev 939 0 R +/Next 947 0 R +>> endobj +939 0 obj << +/Title 940 0 R +/A 937 0 R +/Parent 891 0 R +/Prev 935 0 R +/Next 943 0 R +>> endobj +935 0 obj << +/Title 936 0 R +/A 933 0 R +/Parent 891 0 R +/Prev 931 0 R +/Next 939 0 R +>> endobj +931 0 obj << +/Title 932 0 R +/A 929 0 R +/Parent 891 0 R +/Prev 927 0 R +/Next 935 0 R +>> endobj +927 0 obj << +/Title 928 0 R +/A 925 0 R +/Parent 891 0 R +/Prev 923 0 R +/Next 931 0 R +>> endobj +923 0 obj << +/Title 924 0 R +/A 921 0 R +/Parent 891 0 R +/Prev 919 0 R +/Next 927 0 R +>> endobj +919 0 obj << +/Title 920 0 R +/A 917 0 R +/Parent 891 0 R +/Prev 915 0 R +/Next 923 0 R +>> endobj +915 0 obj << +/Title 916 0 R +/A 913 0 R +/Parent 891 0 R +/Prev 911 0 R +/Next 919 0 R +>> endobj +911 0 obj << +/Title 912 0 R +/A 909 0 R +/Parent 891 0 R +/Prev 907 0 R +/Next 915 0 R +>> endobj +907 0 obj << +/Title 908 0 R +/A 905 0 R +/Parent 891 0 R +/Prev 903 0 R +/Next 911 0 R +>> endobj +903 0 obj << +/Title 904 0 R +/A 901 0 R +/Parent 891 0 R +/Prev 899 0 R +/Next 907 0 R +>> endobj +899 0 obj << +/Title 900 0 R +/A 897 0 R +/Parent 891 0 R +/Prev 895 0 R +/Next 903 0 R +>> endobj +895 0 obj << +/Title 896 0 R +/A 893 0 R +/Parent 891 0 R +/Next 899 0 R +>> endobj +891 0 obj << +/Title 892 0 R +/A 889 0 R +/Parent 75 0 R +/Prev 727 0 R +/Next 959 0 R +/First 895 0 R +/Last 955 0 R +/Count -16 +>> endobj +887 0 obj << +/Title 888 0 R +/A 885 0 R +/Parent 867 0 R +/Prev 883 0 R +>> endobj +883 0 obj << +/Title 884 0 R +/A 881 0 R +/Parent 867 0 R +/Prev 879 0 R +/Next 887 0 R +>> endobj +879 0 obj << +/Title 880 0 R +/A 877 0 R +/Parent 867 0 R +/Prev 875 0 R +/Next 883 0 R +>> endobj +875 0 obj << +/Title 876 0 R +/A 873 0 R +/Parent 867 0 R +/Prev 871 0 R +/Next 879 0 R +>> endobj +871 0 obj << +/Title 872 0 R +/A 869 0 R +/Parent 867 0 R +/Next 875 0 R +>> endobj +867 0 obj << +/Title 868 0 R +/A 865 0 R +/Parent 727 0 R +/Prev 759 0 R +/First 871 0 R +/Last 887 0 R +/Count -5 +>> endobj +863 0 obj << +/Title 864 0 R +/A 861 0 R +/Parent 759 0 R +/Prev 859 0 R +>> endobj +859 0 obj << +/Title 860 0 R +/A 857 0 R +/Parent 759 0 R +/Prev 855 0 R +/Next 863 0 R +>> endobj +855 0 obj << +/Title 856 0 R +/A 853 0 R +/Parent 759 0 R +/Prev 851 0 R +/Next 859 0 R +>> endobj +851 0 obj << +/Title 852 0 R +/A 849 0 R +/Parent 759 0 R +/Prev 847 0 R +/Next 855 0 R +>> endobj +847 0 obj << +/Title 848 0 R +/A 845 0 R +/Parent 759 0 R +/Prev 843 0 R +/Next 851 0 R +>> endobj +843 0 obj << +/Title 844 0 R +/A 841 0 R +/Parent 759 0 R +/Prev 839 0 R +/Next 847 0 R +>> endobj +839 0 obj << +/Title 840 0 R +/A 837 0 R +/Parent 759 0 R +/Prev 835 0 R +/Next 843 0 R +>> endobj +835 0 obj << +/Title 836 0 R +/A 833 0 R +/Parent 759 0 R +/Prev 831 0 R +/Next 839 0 R +>> endobj +831 0 obj << +/Title 832 0 R +/A 829 0 R +/Parent 759 0 R +/Prev 827 0 R +/Next 835 0 R +>> endobj +827 0 obj << +/Title 828 0 R +/A 825 0 R +/Parent 759 0 R +/Prev 823 0 R +/Next 831 0 R +>> endobj +823 0 obj << +/Title 824 0 R +/A 821 0 R +/Parent 759 0 R +/Prev 819 0 R +/Next 827 0 R +>> endobj +819 0 obj << +/Title 820 0 R +/A 817 0 R +/Parent 759 0 R +/Prev 815 0 R +/Next 823 0 R +>> endobj +815 0 obj << +/Title 816 0 R +/A 813 0 R +/Parent 759 0 R +/Prev 811 0 R +/Next 819 0 R +>> endobj +811 0 obj << +/Title 812 0 R +/A 809 0 R +/Parent 759 0 R +/Prev 807 0 R +/Next 815 0 R +>> endobj +807 0 obj << +/Title 808 0 R +/A 805 0 R +/Parent 759 0 R +/Prev 803 0 R +/Next 811 0 R +>> endobj +803 0 obj << +/Title 804 0 R +/A 801 0 R +/Parent 759 0 R +/Prev 799 0 R +/Next 807 0 R +>> endobj +799 0 obj << +/Title 800 0 R +/A 797 0 R +/Parent 759 0 R +/Prev 795 0 R +/Next 803 0 R +>> endobj +795 0 obj << +/Title 796 0 R +/A 793 0 R +/Parent 759 0 R +/Prev 791 0 R +/Next 799 0 R +>> endobj +791 0 obj << +/Title 792 0 R +/A 789 0 R +/Parent 759 0 R +/Prev 787 0 R +/Next 795 0 R +>> endobj +787 0 obj << +/Title 788 0 R +/A 785 0 R +/Parent 759 0 R +/Prev 783 0 R +/Next 791 0 R +>> endobj +783 0 obj << +/Title 784 0 R +/A 781 0 R +/Parent 759 0 R +/Prev 779 0 R +/Next 787 0 R +>> endobj +779 0 obj << +/Title 780 0 R +/A 777 0 R +/Parent 759 0 R +/Prev 775 0 R +/Next 783 0 R +>> endobj +775 0 obj << +/Title 776 0 R +/A 773 0 R +/Parent 759 0 R +/Prev 771 0 R +/Next 779 0 R +>> endobj +771 0 obj << +/Title 772 0 R +/A 769 0 R +/Parent 759 0 R +/Prev 767 0 R +/Next 775 0 R +>> endobj +767 0 obj << +/Title 768 0 R +/A 765 0 R +/Parent 759 0 R +/Prev 763 0 R +/Next 771 0 R +>> endobj +763 0 obj << +/Title 764 0 R +/A 761 0 R +/Parent 759 0 R +/Next 767 0 R +>> endobj +759 0 obj << +/Title 760 0 R +/A 757 0 R +/Parent 727 0 R +/Prev 731 0 R +/Next 867 0 R +/First 763 0 R +/Last 863 0 R +/Count -26 +>> endobj +755 0 obj << +/Title 756 0 R +/A 753 0 R +/Parent 731 0 R +/Prev 751 0 R +>> endobj +751 0 obj << +/Title 752 0 R +/A 749 0 R +/Parent 731 0 R +/Prev 747 0 R +/Next 755 0 R +>> endobj +747 0 obj << +/Title 748 0 R +/A 745 0 R +/Parent 731 0 R +/Prev 743 0 R +/Next 751 0 R +>> endobj +743 0 obj << +/Title 744 0 R +/A 741 0 R +/Parent 731 0 R +/Prev 739 0 R +/Next 747 0 R +>> endobj +739 0 obj << +/Title 740 0 R +/A 737 0 R +/Parent 731 0 R +/Prev 735 0 R +/Next 743 0 R +>> endobj +735 0 obj << +/Title 736 0 R +/A 733 0 R +/Parent 731 0 R +/Next 739 0 R +>> endobj +731 0 obj << +/Title 732 0 R +/A 729 0 R +/Parent 727 0 R +/Next 759 0 R +/First 735 0 R +/Last 755 0 R +/Count -6 +>> endobj +727 0 obj << +/Title 728 0 R +/A 725 0 R +/Parent 75 0 R +/Prev 79 0 R +/Next 891 0 R +/First 731 0 R +/Last 867 0 R +/Count -3 +>> endobj +723 0 obj << +/Title 724 0 R +/A 721 0 R +/Parent 695 0 R +/Prev 719 0 R +>> endobj +719 0 obj << +/Title 720 0 R +/A 717 0 R +/Parent 695 0 R +/Prev 715 0 R +/Next 723 0 R +>> endobj +715 0 obj << +/Title 716 0 R +/A 713 0 R +/Parent 695 0 R +/Prev 711 0 R +/Next 719 0 R +>> endobj +711 0 obj << +/Title 712 0 R +/A 709 0 R +/Parent 695 0 R +/Prev 707 0 R +/Next 715 0 R +>> endobj +707 0 obj << +/Title 708 0 R +/A 705 0 R +/Parent 695 0 R +/Prev 703 0 R +/Next 711 0 R +>> endobj +703 0 obj << +/Title 704 0 R +/A 701 0 R +/Parent 695 0 R +/Prev 699 0 R +/Next 707 0 R +>> endobj +699 0 obj << +/Title 700 0 R +/A 697 0 R +/Parent 695 0 R +/Next 703 0 R +>> endobj +695 0 obj << +/Title 696 0 R +/A 693 0 R +/Parent 79 0 R +/Prev 687 0 R +/First 699 0 R +/Last 723 0 R +/Count -7 +>> endobj +691 0 obj << +/Title 692 0 R +/A 689 0 R +/Parent 687 0 R +>> endobj +687 0 obj << +/Title 688 0 R +/A 685 0 R +/Parent 79 0 R +/Prev 659 0 R +/Next 695 0 R +/First 691 0 R +/Last 691 0 R +/Count -1 +>> endobj +683 0 obj << +/Title 684 0 R +/A 681 0 R +/Parent 659 0 R +/Prev 679 0 R +>> endobj +679 0 obj << +/Title 680 0 R +/A 677 0 R +/Parent 659 0 R +/Prev 675 0 R +/Next 683 0 R +>> endobj +675 0 obj << +/Title 676 0 R +/A 673 0 R +/Parent 659 0 R +/Prev 671 0 R +/Next 679 0 R +>> endobj +671 0 obj << +/Title 672 0 R +/A 669 0 R +/Parent 659 0 R +/Prev 667 0 R +/Next 675 0 R +>> endobj +667 0 obj << +/Title 668 0 R +/A 665 0 R +/Parent 659 0 R +/Prev 663 0 R +/Next 671 0 R +>> endobj +663 0 obj << +/Title 664 0 R +/A 661 0 R +/Parent 659 0 R +/Next 667 0 R +>> endobj +659 0 obj << +/Title 660 0 R +/A 657 0 R +/Parent 79 0 R +/Prev 639 0 R +/Next 687 0 R +/First 663 0 R +/Last 683 0 R +/Count -6 +>> endobj +655 0 obj << +/Title 656 0 R +/A 653 0 R +/Parent 639 0 R +/Prev 651 0 R +>> endobj +651 0 obj << +/Title 652 0 R +/A 649 0 R +/Parent 639 0 R +/Prev 647 0 R +/Next 655 0 R +>> endobj +647 0 obj << +/Title 648 0 R +/A 645 0 R +/Parent 639 0 R +/Prev 643 0 R +/Next 651 0 R +>> endobj +643 0 obj << +/Title 644 0 R +/A 641 0 R +/Parent 639 0 R +/Next 647 0 R +>> endobj +639 0 obj << +/Title 640 0 R +/A 637 0 R +/Parent 79 0 R +/Prev 599 0 R +/Next 659 0 R +/First 643 0 R +/Last 655 0 R +/Count -4 +>> endobj +635 0 obj << +/Title 636 0 R +/A 633 0 R +/Parent 599 0 R +/Prev 631 0 R +>> endobj +631 0 obj << +/Title 632 0 R +/A 629 0 R +/Parent 599 0 R +/Prev 627 0 R +/Next 635 0 R +>> endobj +627 0 obj << +/Title 628 0 R +/A 625 0 R +/Parent 599 0 R +/Prev 623 0 R +/Next 631 0 R +>> endobj +623 0 obj << +/Title 624 0 R +/A 621 0 R +/Parent 599 0 R +/Prev 619 0 R +/Next 627 0 R +>> endobj +619 0 obj << +/Title 620 0 R +/A 617 0 R +/Parent 599 0 R +/Prev 615 0 R +/Next 623 0 R +>> endobj +615 0 obj << +/Title 616 0 R +/A 613 0 R +/Parent 599 0 R +/Prev 611 0 R +/Next 619 0 R +>> endobj +611 0 obj << +/Title 612 0 R +/A 609 0 R +/Parent 599 0 R +/Prev 607 0 R +/Next 615 0 R +>> endobj +607 0 obj << +/Title 608 0 R +/A 605 0 R +/Parent 599 0 R +/Prev 603 0 R +/Next 611 0 R +>> endobj +603 0 obj << +/Title 604 0 R +/A 601 0 R +/Parent 599 0 R +/Next 607 0 R +>> endobj +599 0 obj << +/Title 600 0 R +/A 597 0 R +/Parent 79 0 R +/Prev 471 0 R +/Next 639 0 R +/First 603 0 R +/Last 635 0 R +/Count -9 +>> endobj +595 0 obj << +/Title 596 0 R +/A 593 0 R +/Parent 471 0 R +/Prev 591 0 R +>> endobj +591 0 obj << +/Title 592 0 R +/A 589 0 R +/Parent 471 0 R +/Prev 587 0 R +/Next 595 0 R +>> endobj +587 0 obj << +/Title 588 0 R +/A 585 0 R +/Parent 471 0 R +/Prev 583 0 R +/Next 591 0 R +>> endobj +583 0 obj << +/Title 584 0 R +/A 581 0 R +/Parent 471 0 R +/Prev 579 0 R +/Next 587 0 R +>> endobj +579 0 obj << +/Title 580 0 R +/A 577 0 R +/Parent 471 0 R +/Prev 575 0 R +/Next 583 0 R +>> endobj +575 0 obj << +/Title 576 0 R +/A 573 0 R +/Parent 471 0 R +/Prev 571 0 R +/Next 579 0 R +>> endobj +571 0 obj << +/Title 572 0 R +/A 569 0 R +/Parent 471 0 R +/Prev 567 0 R +/Next 575 0 R +>> endobj +567 0 obj << +/Title 568 0 R +/A 565 0 R +/Parent 471 0 R +/Prev 563 0 R +/Next 571 0 R +>> endobj +563 0 obj << +/Title 564 0 R +/A 561 0 R +/Parent 471 0 R +/Prev 559 0 R +/Next 567 0 R +>> endobj +559 0 obj << +/Title 560 0 R +/A 557 0 R +/Parent 471 0 R +/Prev 555 0 R +/Next 563 0 R +>> endobj +555 0 obj << +/Title 556 0 R +/A 553 0 R +/Parent 471 0 R +/Prev 551 0 R +/Next 559 0 R +>> endobj +551 0 obj << +/Title 552 0 R +/A 549 0 R +/Parent 471 0 R +/Prev 547 0 R +/Next 555 0 R +>> endobj +547 0 obj << +/Title 548 0 R +/A 545 0 R +/Parent 471 0 R +/Prev 543 0 R +/Next 551 0 R +>> endobj +543 0 obj << +/Title 544 0 R +/A 541 0 R +/Parent 471 0 R +/Prev 539 0 R +/Next 547 0 R +>> endobj +539 0 obj << +/Title 540 0 R +/A 537 0 R +/Parent 471 0 R +/Prev 535 0 R +/Next 543 0 R +>> endobj +535 0 obj << +/Title 536 0 R +/A 533 0 R +/Parent 471 0 R +/Prev 531 0 R +/Next 539 0 R +>> endobj +531 0 obj << +/Title 532 0 R +/A 529 0 R +/Parent 471 0 R +/Prev 527 0 R +/Next 535 0 R +>> endobj +527 0 obj << +/Title 528 0 R +/A 525 0 R +/Parent 471 0 R +/Prev 523 0 R +/Next 531 0 R +>> endobj +523 0 obj << +/Title 524 0 R +/A 521 0 R +/Parent 471 0 R +/Prev 519 0 R +/Next 527 0 R +>> endobj +519 0 obj << +/Title 520 0 R +/A 517 0 R +/Parent 471 0 R +/Prev 515 0 R +/Next 523 0 R +>> endobj +515 0 obj << +/Title 516 0 R +/A 513 0 R +/Parent 471 0 R +/Prev 511 0 R +/Next 519 0 R +>> endobj +511 0 obj << +/Title 512 0 R +/A 509 0 R +/Parent 471 0 R +/Prev 507 0 R +/Next 515 0 R +>> endobj +507 0 obj << +/Title 508 0 R +/A 505 0 R +/Parent 471 0 R +/Prev 503 0 R +/Next 511 0 R +>> endobj +503 0 obj << +/Title 504 0 R +/A 501 0 R +/Parent 471 0 R +/Prev 499 0 R +/Next 507 0 R +>> endobj +499 0 obj << +/Title 500 0 R +/A 497 0 R +/Parent 471 0 R +/Prev 495 0 R +/Next 503 0 R +>> endobj +495 0 obj << +/Title 496 0 R +/A 493 0 R +/Parent 471 0 R +/Prev 491 0 R +/Next 499 0 R +>> endobj +491 0 obj << +/Title 492 0 R +/A 489 0 R +/Parent 471 0 R +/Prev 487 0 R +/Next 495 0 R +>> endobj +487 0 obj << +/Title 488 0 R +/A 485 0 R +/Parent 471 0 R +/Prev 483 0 R +/Next 491 0 R +>> endobj +483 0 obj << +/Title 484 0 R +/A 481 0 R +/Parent 471 0 R +/Prev 479 0 R +/Next 487 0 R +>> endobj +479 0 obj << +/Title 480 0 R +/A 477 0 R +/Parent 471 0 R +/Prev 475 0 R +/Next 483 0 R +>> endobj +475 0 obj << +/Title 476 0 R +/A 473 0 R +/Parent 471 0 R +/Next 479 0 R +>> endobj +471 0 obj << +/Title 472 0 R +/A 469 0 R +/Parent 79 0 R +/Prev 423 0 R +/Next 599 0 R +/First 475 0 R +/Last 595 0 R +/Count -31 +>> endobj +467 0 obj << +/Title 468 0 R +/A 465 0 R +/Parent 423 0 R +/Prev 463 0 R +>> endobj +463 0 obj << +/Title 464 0 R +/A 461 0 R +/Parent 423 0 R +/Prev 459 0 R +/Next 467 0 R +>> endobj +459 0 obj << +/Title 460 0 R +/A 457 0 R +/Parent 423 0 R +/Prev 455 0 R +/Next 463 0 R +>> endobj +455 0 obj << +/Title 456 0 R +/A 453 0 R +/Parent 423 0 R +/Prev 451 0 R +/Next 459 0 R +>> endobj +451 0 obj << +/Title 452 0 R +/A 449 0 R +/Parent 423 0 R +/Prev 447 0 R +/Next 455 0 R +>> endobj +447 0 obj << +/Title 448 0 R +/A 445 0 R +/Parent 423 0 R +/Prev 443 0 R +/Next 451 0 R +>> endobj +443 0 obj << +/Title 444 0 R +/A 441 0 R +/Parent 423 0 R +/Prev 439 0 R +/Next 447 0 R +>> endobj +439 0 obj << +/Title 440 0 R +/A 437 0 R +/Parent 423 0 R +/Prev 435 0 R +/Next 443 0 R +>> endobj +435 0 obj << +/Title 436 0 R +/A 433 0 R +/Parent 423 0 R +/Prev 431 0 R +/Next 439 0 R +>> endobj +431 0 obj << +/Title 432 0 R +/A 429 0 R +/Parent 423 0 R +/Prev 427 0 R +/Next 435 0 R +>> endobj +427 0 obj << +/Title 428 0 R +/A 425 0 R +/Parent 423 0 R +/Next 431 0 R +>> endobj +423 0 obj << +/Title 424 0 R +/A 421 0 R +/Parent 79 0 R +/Prev 375 0 R +/Next 471 0 R +/First 427 0 R +/Last 467 0 R +/Count -11 +>> endobj +419 0 obj << +/Title 420 0 R +/A 417 0 R +/Parent 375 0 R +/Prev 415 0 R +>> endobj +415 0 obj << +/Title 416 0 R +/A 413 0 R +/Parent 375 0 R +/Prev 411 0 R +/Next 419 0 R +>> endobj +411 0 obj << +/Title 412 0 R +/A 409 0 R +/Parent 375 0 R +/Prev 407 0 R +/Next 415 0 R +>> endobj +407 0 obj << +/Title 408 0 R +/A 405 0 R +/Parent 375 0 R +/Prev 403 0 R +/Next 411 0 R +>> endobj +403 0 obj << +/Title 404 0 R +/A 401 0 R +/Parent 375 0 R +/Prev 399 0 R +/Next 407 0 R +>> endobj +399 0 obj << +/Title 400 0 R +/A 397 0 R +/Parent 375 0 R +/Prev 395 0 R +/Next 403 0 R +>> endobj +395 0 obj << +/Title 396 0 R +/A 393 0 R +/Parent 375 0 R +/Prev 391 0 R +/Next 399 0 R +>> endobj +391 0 obj << +/Title 392 0 R +/A 389 0 R +/Parent 375 0 R +/Prev 387 0 R +/Next 395 0 R +>> endobj +387 0 obj << +/Title 388 0 R +/A 385 0 R +/Parent 375 0 R +/Prev 383 0 R +/Next 391 0 R +>> endobj +383 0 obj << +/Title 384 0 R +/A 381 0 R +/Parent 375 0 R +/Prev 379 0 R +/Next 387 0 R +>> endobj +379 0 obj << +/Title 380 0 R +/A 377 0 R +/Parent 375 0 R +/Next 383 0 R +>> endobj +375 0 obj << +/Title 376 0 R +/A 373 0 R +/Parent 79 0 R +/Prev 215 0 R +/Next 423 0 R +/First 379 0 R +/Last 419 0 R +/Count -11 +>> endobj +371 0 obj << +/Title 372 0 R +/A 369 0 R +/Parent 215 0 R +/Prev 367 0 R +>> endobj +367 0 obj << +/Title 368 0 R +/A 365 0 R +/Parent 215 0 R +/Prev 363 0 R +/Next 371 0 R +>> endobj +363 0 obj << +/Title 364 0 R +/A 361 0 R +/Parent 215 0 R +/Prev 359 0 R +/Next 367 0 R +>> endobj +359 0 obj << +/Title 360 0 R +/A 357 0 R +/Parent 215 0 R +/Prev 355 0 R +/Next 363 0 R +>> endobj +355 0 obj << +/Title 356 0 R +/A 353 0 R +/Parent 215 0 R +/Prev 351 0 R +/Next 359 0 R +>> endobj +351 0 obj << +/Title 352 0 R +/A 349 0 R +/Parent 215 0 R +/Prev 347 0 R +/Next 355 0 R +>> endobj +347 0 obj << +/Title 348 0 R +/A 345 0 R +/Parent 215 0 R +/Prev 343 0 R +/Next 351 0 R +>> endobj +343 0 obj << +/Title 344 0 R +/A 341 0 R +/Parent 215 0 R +/Prev 339 0 R +/Next 347 0 R +>> endobj +339 0 obj << +/Title 340 0 R +/A 337 0 R +/Parent 215 0 R +/Prev 335 0 R +/Next 343 0 R +>> endobj +335 0 obj << +/Title 336 0 R +/A 333 0 R +/Parent 215 0 R +/Prev 331 0 R +/Next 339 0 R +>> endobj +331 0 obj << +/Title 332 0 R +/A 329 0 R +/Parent 215 0 R +/Prev 327 0 R +/Next 335 0 R +>> endobj +327 0 obj << +/Title 328 0 R +/A 325 0 R +/Parent 215 0 R +/Prev 323 0 R +/Next 331 0 R +>> endobj +323 0 obj << +/Title 324 0 R +/A 321 0 R +/Parent 215 0 R +/Prev 319 0 R +/Next 327 0 R +>> endobj +319 0 obj << +/Title 320 0 R +/A 317 0 R +/Parent 215 0 R +/Prev 315 0 R +/Next 323 0 R +>> endobj +315 0 obj << +/Title 316 0 R +/A 313 0 R +/Parent 215 0 R +/Prev 311 0 R +/Next 319 0 R +>> endobj +311 0 obj << +/Title 312 0 R +/A 309 0 R +/Parent 215 0 R +/Prev 307 0 R +/Next 315 0 R +>> endobj +307 0 obj << +/Title 308 0 R +/A 305 0 R +/Parent 215 0 R +/Prev 303 0 R +/Next 311 0 R +>> endobj +303 0 obj << +/Title 304 0 R +/A 301 0 R +/Parent 215 0 R +/Prev 299 0 R +/Next 307 0 R +>> endobj +299 0 obj << +/Title 300 0 R +/A 297 0 R +/Parent 215 0 R +/Prev 295 0 R +/Next 303 0 R +>> endobj +295 0 obj << +/Title 296 0 R +/A 293 0 R +/Parent 215 0 R +/Prev 291 0 R +/Next 299 0 R +>> endobj +291 0 obj << +/Title 292 0 R +/A 289 0 R +/Parent 215 0 R +/Prev 287 0 R +/Next 295 0 R +>> endobj +287 0 obj << +/Title 288 0 R +/A 285 0 R +/Parent 215 0 R +/Prev 283 0 R +/Next 291 0 R +>> endobj +283 0 obj << +/Title 284 0 R +/A 281 0 R +/Parent 215 0 R +/Prev 279 0 R +/Next 287 0 R +>> endobj +279 0 obj << +/Title 280 0 R +/A 277 0 R +/Parent 215 0 R +/Prev 275 0 R +/Next 283 0 R +>> endobj +275 0 obj << +/Title 276 0 R +/A 273 0 R +/Parent 215 0 R +/Prev 271 0 R +/Next 279 0 R +>> endobj +271 0 obj << +/Title 272 0 R +/A 269 0 R +/Parent 215 0 R +/Prev 267 0 R +/Next 275 0 R +>> endobj +267 0 obj << +/Title 268 0 R +/A 265 0 R +/Parent 215 0 R +/Prev 263 0 R +/Next 271 0 R +>> endobj +263 0 obj << +/Title 264 0 R +/A 261 0 R +/Parent 215 0 R +/Prev 259 0 R +/Next 267 0 R +>> endobj +259 0 obj << +/Title 260 0 R +/A 257 0 R +/Parent 215 0 R +/Prev 255 0 R +/Next 263 0 R +>> endobj +255 0 obj << +/Title 256 0 R +/A 253 0 R +/Parent 215 0 R +/Prev 251 0 R +/Next 259 0 R +>> endobj +251 0 obj << +/Title 252 0 R +/A 249 0 R +/Parent 215 0 R +/Prev 247 0 R +/Next 255 0 R +>> endobj +247 0 obj << +/Title 248 0 R +/A 245 0 R +/Parent 215 0 R +/Prev 243 0 R +/Next 251 0 R +>> endobj +243 0 obj << +/Title 244 0 R +/A 241 0 R +/Parent 215 0 R +/Prev 239 0 R +/Next 247 0 R +>> endobj +239 0 obj << +/Title 240 0 R +/A 237 0 R +/Parent 215 0 R +/Prev 235 0 R +/Next 243 0 R +>> endobj +235 0 obj << +/Title 236 0 R +/A 233 0 R +/Parent 215 0 R +/Prev 231 0 R +/Next 239 0 R +>> endobj +231 0 obj << +/Title 232 0 R +/A 229 0 R +/Parent 215 0 R +/Prev 227 0 R +/Next 235 0 R +>> endobj +227 0 obj << +/Title 228 0 R +/A 225 0 R +/Parent 215 0 R +/Prev 223 0 R +/Next 231 0 R +>> endobj +223 0 obj << +/Title 224 0 R +/A 221 0 R +/Parent 215 0 R +/Prev 219 0 R +/Next 227 0 R +>> endobj +219 0 obj << +/Title 220 0 R +/A 217 0 R +/Parent 215 0 R +/Next 223 0 R +>> endobj +215 0 obj << +/Title 216 0 R +/A 213 0 R +/Parent 79 0 R +/Prev 139 0 R +/Next 375 0 R +/First 219 0 R +/Last 371 0 R +/Count -39 +>> endobj +211 0 obj << +/Title 212 0 R +/A 209 0 R +/Parent 139 0 R +/Prev 207 0 R +>> endobj +207 0 obj << +/Title 208 0 R +/A 205 0 R +/Parent 139 0 R +/Prev 203 0 R +/Next 211 0 R +>> endobj +203 0 obj << +/Title 204 0 R +/A 201 0 R +/Parent 139 0 R +/Prev 199 0 R +/Next 207 0 R +>> endobj +199 0 obj << +/Title 200 0 R +/A 197 0 R +/Parent 139 0 R +/Prev 195 0 R +/Next 203 0 R +>> endobj +195 0 obj << +/Title 196 0 R +/A 193 0 R +/Parent 139 0 R +/Prev 191 0 R +/Next 199 0 R +>> endobj +191 0 obj << +/Title 192 0 R +/A 189 0 R +/Parent 139 0 R +/Prev 187 0 R +/Next 195 0 R +>> endobj +187 0 obj << +/Title 188 0 R +/A 185 0 R +/Parent 139 0 R +/Prev 183 0 R +/Next 191 0 R +>> endobj +183 0 obj << +/Title 184 0 R +/A 181 0 R +/Parent 139 0 R +/Prev 179 0 R +/Next 187 0 R +>> endobj +179 0 obj << +/Title 180 0 R +/A 177 0 R +/Parent 139 0 R +/Prev 175 0 R +/Next 183 0 R +>> endobj +175 0 obj << +/Title 176 0 R +/A 173 0 R +/Parent 139 0 R +/Prev 171 0 R +/Next 179 0 R +>> endobj +171 0 obj << +/Title 172 0 R +/A 169 0 R +/Parent 139 0 R +/Prev 167 0 R +/Next 175 0 R +>> endobj +167 0 obj << +/Title 168 0 R +/A 165 0 R +/Parent 139 0 R +/Prev 163 0 R +/Next 171 0 R +>> endobj +163 0 obj << +/Title 164 0 R +/A 161 0 R +/Parent 139 0 R +/Prev 159 0 R +/Next 167 0 R +>> endobj +159 0 obj << +/Title 160 0 R +/A 157 0 R +/Parent 139 0 R +/Prev 155 0 R +/Next 163 0 R +>> endobj +155 0 obj << +/Title 156 0 R +/A 153 0 R +/Parent 139 0 R +/Prev 151 0 R +/Next 159 0 R +>> endobj +151 0 obj << +/Title 152 0 R +/A 149 0 R +/Parent 139 0 R +/Prev 147 0 R +/Next 155 0 R +>> endobj +147 0 obj << +/Title 148 0 R +/A 145 0 R +/Parent 139 0 R +/Prev 143 0 R +/Next 151 0 R +>> endobj +143 0 obj << +/Title 144 0 R +/A 141 0 R +/Parent 139 0 R +/Next 147 0 R +>> endobj +139 0 obj << +/Title 140 0 R +/A 137 0 R +/Parent 79 0 R +/Prev 115 0 R +/Next 215 0 R +/First 143 0 R +/Last 211 0 R +/Count -18 +>> endobj +135 0 obj << +/Title 136 0 R +/A 133 0 R +/Parent 115 0 R +/Prev 131 0 R +>> endobj +131 0 obj << +/Title 132 0 R +/A 129 0 R +/Parent 115 0 R +/Prev 127 0 R +/Next 135 0 R +>> endobj +127 0 obj << +/Title 128 0 R +/A 125 0 R +/Parent 115 0 R +/Prev 123 0 R +/Next 131 0 R +>> endobj +123 0 obj << +/Title 124 0 R +/A 121 0 R +/Parent 115 0 R +/Prev 119 0 R +/Next 127 0 R +>> endobj +119 0 obj << +/Title 120 0 R +/A 117 0 R +/Parent 115 0 R +/Next 123 0 R +>> endobj +115 0 obj << +/Title 116 0 R +/A 113 0 R +/Parent 79 0 R +/Prev 83 0 R +/Next 139 0 R +/First 119 0 R +/Last 135 0 R +/Count -5 +>> endobj +111 0 obj << +/Title 112 0 R +/A 109 0 R +/Parent 83 0 R +/Prev 107 0 R +>> endobj +107 0 obj << +/Title 108 0 R +/A 105 0 R +/Parent 83 0 R +/Prev 103 0 R +/Next 111 0 R +>> endobj +103 0 obj << +/Title 104 0 R +/A 101 0 R +/Parent 83 0 R +/Prev 99 0 R +/Next 107 0 R +>> endobj +99 0 obj << +/Title 100 0 R +/A 97 0 R +/Parent 83 0 R +/Prev 95 0 R +/Next 103 0 R +>> endobj +95 0 obj << +/Title 96 0 R +/A 93 0 R +/Parent 83 0 R +/Prev 91 0 R +/Next 99 0 R +>> endobj +91 0 obj << +/Title 92 0 R +/A 89 0 R +/Parent 83 0 R +/Prev 87 0 R +/Next 95 0 R +>> endobj +87 0 obj << +/Title 88 0 R +/A 85 0 R +/Parent 83 0 R +/Next 91 0 R +>> endobj +83 0 obj << +/Title 84 0 R +/A 81 0 R +/Parent 79 0 R +/Next 115 0 R +/First 87 0 R +/Last 111 0 R +/Count -7 +>> endobj +79 0 obj << +/Title 80 0 R +/A 77 0 R +/Parent 75 0 R +/Next 727 0 R +/First 83 0 R +/Last 695 0 R +/Count -12 +>> endobj +75 0 obj << +/Title 76 0 R +/A 73 0 R +/Parent 2544 0 R +/Prev 71 0 R +/Next 1099 0 R +/First 79 0 R +/Last 1095 0 R +/Count -8 +>> endobj +71 0 obj << +/Title 72 0 R +/A 69 0 R +/Parent 2544 0 R +/Prev 67 0 R +/Next 75 0 R +>> endobj +67 0 obj << +/Title 68 0 R +/A 65 0 R +/Parent 2544 0 R +/Prev 63 0 R +/Next 71 0 R +>> endobj +63 0 obj << +/Title 64 0 R +/A 61 0 R +/Parent 2544 0 R +/Prev 59 0 R +/Next 67 0 R +>> endobj +59 0 obj << +/Title 60 0 R +/A 57 0 R +/Parent 2544 0 R +/Prev 55 0 R +/Next 63 0 R +>> endobj +55 0 obj << +/Title 56 0 R +/A 53 0 R +/Parent 2544 0 R +/Prev 51 0 R +/Next 59 0 R +>> endobj +51 0 obj << +/Title 52 0 R +/A 49 0 R +/Parent 2544 0 R +/Prev 31 0 R +/Next 55 0 R +>> endobj +47 0 obj << +/Title 48 0 R +/A 45 0 R +/Parent 43 0 R +>> endobj +43 0 obj << +/Title 44 0 R +/A 41 0 R +/Parent 31 0 R +/Prev 39 0 R +/First 47 0 R +/Last 47 0 R +/Count -1 +>> endobj +39 0 obj << +/Title 40 0 R +/A 37 0 R +/Parent 31 0 R +/Prev 35 0 R +/Next 43 0 R +>> endobj +35 0 obj << +/Title 36 0 R +/A 33 0 R +/Parent 31 0 R +/Next 39 0 R +>> endobj +31 0 obj << +/Title 32 0 R +/A 29 0 R +/Parent 2544 0 R +/Prev 15 0 R +/Next 51 0 R +/First 35 0 R +/Last 43 0 R +/Count -3 +>> endobj +27 0 obj << +/Title 28 0 R +/A 25 0 R +/Parent 23 0 R +>> endobj +23 0 obj << +/Title 24 0 R +/A 21 0 R +/Parent 15 0 R +/Prev 19 0 R +/First 27 0 R +/Last 27 0 R +/Count -1 +>> endobj +19 0 obj << +/Title 20 0 R +/A 17 0 R +/Parent 15 0 R +/Next 23 0 R +>> endobj +15 0 obj << +/Title 16 0 R +/A 13 0 R +/Parent 2544 0 R +/Prev 7 0 R +/Next 31 0 R +/First 19 0 R +/Last 23 0 R +/Count -2 +>> endobj +11 0 obj << +/Title 12 0 R +/A 9 0 R +/Parent 7 0 R +>> endobj +7 0 obj << +/Title 8 0 R +/A 5 0 R +/Parent 2544 0 R +/Next 15 0 R +/First 11 0 R +/Last 11 0 R +/Count -1 +>> endobj +2545 0 obj << +/Names [(Doc-Start) 1106 0 R (Item.1) 1446 0 R (Item.2) 1448 0 R (Item.3) 1449 0 R (lstlisting.-1) 1443 0 R (lstlisting.-10) 1552 0 R] +/Limits [(Doc-Start) (lstlisting.-10)] +>> endobj +2546 0 obj << +/Names [(lstlisting.-100) 1901 0 R (lstlisting.-101) 1908 0 R (lstlisting.-102) 1918 0 R (lstlisting.-103) 1922 0 R (lstlisting.-104) 1924 0 R (lstlisting.-105) 1930 0 R] +/Limits [(lstlisting.-100) (lstlisting.-105)] +>> endobj +2547 0 obj << +/Names [(lstlisting.-106) 1932 0 R (lstlisting.-107) 1936 0 R (lstlisting.-108) 1942 0 R (lstlisting.-109) 1948 0 R (lstlisting.-11) 1562 0 R (lstlisting.-110) 1950 0 R] +/Limits [(lstlisting.-106) (lstlisting.-110)] +>> endobj +2548 0 obj << +/Names [(lstlisting.-111) 1952 0 R (lstlisting.-112) 1959 0 R (lstlisting.-113) 1961 0 R (lstlisting.-114) 1963 0 R (lstlisting.-115) 1965 0 R (lstlisting.-116) 1971 0 R] +/Limits [(lstlisting.-111) (lstlisting.-116)] +>> endobj +2549 0 obj << +/Names [(lstlisting.-117) 1986 0 R (lstlisting.-118) 2005 0 R (lstlisting.-119) 2021 0 R (lstlisting.-12) 1564 0 R (lstlisting.-120) 2023 0 R (lstlisting.-121) 2025 0 R] +/Limits [(lstlisting.-117) (lstlisting.-121)] +>> endobj +2550 0 obj << +/Names [(lstlisting.-122) 2048 0 R (lstlisting.-123) 2060 0 R (lstlisting.-124) 2073 0 R (lstlisting.-125) 2090 0 R (lstlisting.-126) 2103 0 R (lstlisting.-127) 2108 0 R] +/Limits [(lstlisting.-122) (lstlisting.-127)] +>> endobj +2551 0 obj << +/Names [(lstlisting.-128) 2115 0 R (lstlisting.-129) 2121 0 R (lstlisting.-13) 1573 0 R (lstlisting.-130) 2133 0 R (lstlisting.-131) 2146 0 R (lstlisting.-132) 2169 0 R] +/Limits [(lstlisting.-128) (lstlisting.-132)] +>> endobj +2552 0 obj << +/Names [(lstlisting.-133) 2176 0 R (lstlisting.-134) 2194 0 R (lstlisting.-135) 2212 0 R (lstlisting.-136) 2230 0 R (lstlisting.-137) 2238 0 R (lstlisting.-138) 2244 0 R] +/Limits [(lstlisting.-133) (lstlisting.-138)] +>> endobj +2553 0 obj << +/Names [(lstlisting.-139) 2246 0 R (lstlisting.-14) 1579 0 R (lstlisting.-140) 2248 0 R (lstlisting.-141) 2255 0 R (lstlisting.-142) 2257 0 R (lstlisting.-143) 2259 0 R] +/Limits [(lstlisting.-139) (lstlisting.-143)] +>> endobj +2554 0 obj << +/Names [(lstlisting.-144) 2266 0 R (lstlisting.-145) 2268 0 R (lstlisting.-146) 2270 0 R (lstlisting.-147) 2276 0 R (lstlisting.-148) 2278 0 R (lstlisting.-149) 2280 0 R] +/Limits [(lstlisting.-144) (lstlisting.-149)] +>> endobj +2555 0 obj << +/Names [(lstlisting.-15) 1583 0 R (lstlisting.-150) 2286 0 R (lstlisting.-151) 2288 0 R (lstlisting.-16) 1589 0 R (lstlisting.-17) 1591 0 R (lstlisting.-18) 1595 0 R] +/Limits [(lstlisting.-15) (lstlisting.-18)] +>> endobj +2556 0 obj << +/Names [(lstlisting.-19) 1603 0 R (lstlisting.-2) 1459 0 R (lstlisting.-20) 1607 0 R (lstlisting.-21) 1609 0 R (lstlisting.-22) 1615 0 R (lstlisting.-23) 1617 0 R] +/Limits [(lstlisting.-19) (lstlisting.-23)] +>> endobj +2557 0 obj << +/Names [(lstlisting.-24) 1619 0 R (lstlisting.-25) 1621 0 R (lstlisting.-26) 1627 0 R (lstlisting.-27) 1637 0 R (lstlisting.-28) 1644 0 R (lstlisting.-29) 1655 0 R] +/Limits [(lstlisting.-24) (lstlisting.-29)] +>> endobj +2558 0 obj << +/Names [(lstlisting.-3) 1465 0 R (lstlisting.-30) 1657 0 R (lstlisting.-31) 1663 0 R (lstlisting.-32) 1665 0 R (lstlisting.-33) 1667 0 R (lstlisting.-34) 1669 0 R] +/Limits [(lstlisting.-3) (lstlisting.-34)] +>> endobj +2559 0 obj << +/Names [(lstlisting.-35) 1675 0 R (lstlisting.-36) 1677 0 R (lstlisting.-37) 1679 0 R (lstlisting.-38) 1681 0 R (lstlisting.-39) 1687 0 R (lstlisting.-4) 1467 0 R] +/Limits [(lstlisting.-35) (lstlisting.-4)] +>> endobj +2560 0 obj << +/Names [(lstlisting.-40) 1690 0 R (lstlisting.-41) 1692 0 R (lstlisting.-42) 1694 0 R (lstlisting.-43) 1700 0 R (lstlisting.-44) 1702 0 R (lstlisting.-45) 1704 0 R] +/Limits [(lstlisting.-40) (lstlisting.-45)] +>> endobj +2561 0 obj << +/Names [(lstlisting.-46) 1706 0 R (lstlisting.-47) 1712 0 R (lstlisting.-48) 1714 0 R (lstlisting.-49) 1717 0 R (lstlisting.-5) 1469 0 R (lstlisting.-50) 1719 0 R] +/Limits [(lstlisting.-46) (lstlisting.-50)] +>> endobj +2562 0 obj << +/Names [(lstlisting.-51) 1726 0 R (lstlisting.-52) 1728 0 R (lstlisting.-53) 1730 0 R (lstlisting.-54) 1732 0 R (lstlisting.-55) 1738 0 R (lstlisting.-56) 1740 0 R] +/Limits [(lstlisting.-51) (lstlisting.-56)] +>> endobj +2563 0 obj << +/Names [(lstlisting.-57) 1742 0 R (lstlisting.-58) 1744 0 R (lstlisting.-59) 1750 0 R (lstlisting.-6) 1488 0 R (lstlisting.-60) 1752 0 R (lstlisting.-61) 1754 0 R] +/Limits [(lstlisting.-57) (lstlisting.-61)] +>> endobj +2564 0 obj << +/Names [(lstlisting.-62) 1756 0 R (lstlisting.-63) 1762 0 R (lstlisting.-64) 1767 0 R (lstlisting.-65) 1773 0 R (lstlisting.-66) 1775 0 R (lstlisting.-67) 1777 0 R] +/Limits [(lstlisting.-62) (lstlisting.-67)] +>> endobj +2565 0 obj << +/Names [(lstlisting.-68) 1779 0 R (lstlisting.-69) 1785 0 R (lstlisting.-7) 1492 0 R (lstlisting.-70) 1787 0 R (lstlisting.-71) 1789 0 R (lstlisting.-72) 1796 0 R] +/Limits [(lstlisting.-68) (lstlisting.-72)] +>> endobj +2566 0 obj << +/Names [(lstlisting.-73) 1798 0 R (lstlisting.-74) 1804 0 R (lstlisting.-75) 1806 0 R (lstlisting.-76) 1809 0 R (lstlisting.-77) 1811 0 R (lstlisting.-78) 1817 0 R] +/Limits [(lstlisting.-73) (lstlisting.-78)] +>> endobj +2567 0 obj << +/Names [(lstlisting.-79) 1819 0 R (lstlisting.-8) 1505 0 R (lstlisting.-80) 1821 0 R (lstlisting.-81) 1827 0 R (lstlisting.-82) 1833 0 R (lstlisting.-83) 1835 0 R] +/Limits [(lstlisting.-79) (lstlisting.-83)] +>> endobj +2568 0 obj << +/Names [(lstlisting.-84) 1841 0 R (lstlisting.-85) 1843 0 R (lstlisting.-86) 1845 0 R (lstlisting.-87) 1847 0 R (lstlisting.-88) 1862 0 R (lstlisting.-89) 1864 0 R] +/Limits [(lstlisting.-84) (lstlisting.-89)] +>> endobj +2569 0 obj << +/Names [(lstlisting.-9) 1509 0 R (lstlisting.-90) 1866 0 R (lstlisting.-91) 1868 0 R (lstlisting.-92) 1874 0 R (lstlisting.-93) 1878 0 R (lstlisting.-94) 1884 0 R] +/Limits [(lstlisting.-9) (lstlisting.-94)] +>> endobj +2570 0 obj << +/Names [(lstlisting.-95) 1886 0 R (lstlisting.-96) 1889 0 R (lstlisting.-97) 1895 0 R (lstlisting.-98) 1897 0 R (lstlisting.-99) 1899 0 R (lstnumber.-1.1) 1444 0 R] +/Limits [(lstlisting.-95) (lstnumber.-1.1)] +>> endobj +2571 0 obj << +/Names [(lstnumber.-10.1) 1553 0 R (lstnumber.-100.1) 1902 0 R (lstnumber.-101.1) 1909 0 R (lstnumber.-102.1) 1919 0 R (lstnumber.-102.2) 1920 0 R (lstnumber.-102.3) 1921 0 R] +/Limits [(lstnumber.-10.1) (lstnumber.-102.3)] +>> endobj +2572 0 obj << +/Names [(lstnumber.-103.1) 1923 0 R (lstnumber.-104.1) 1925 0 R (lstnumber.-105.1) 1931 0 R (lstnumber.-106.1) 1933 0 R (lstnumber.-106.2) 1934 0 R (lstnumber.-106.3) 1935 0 R] +/Limits [(lstnumber.-103.1) (lstnumber.-106.3)] +>> endobj +2573 0 obj << +/Names [(lstnumber.-107.1) 1937 0 R (lstnumber.-108.1) 1943 0 R (lstnumber.-109.1) 1949 0 R (lstnumber.-11.1) 1563 0 R (lstnumber.-110.1) 1951 0 R (lstnumber.-111.1) 1953 0 R] +/Limits [(lstnumber.-107.1) (lstnumber.-111.1)] +>> endobj +2574 0 obj << +/Names [(lstnumber.-112.1) 1960 0 R (lstnumber.-113.1) 1962 0 R (lstnumber.-114.1) 1964 0 R (lstnumber.-115.1) 1966 0 R (lstnumber.-116.1) 1972 0 R (lstnumber.-116.2) 1973 0 R] +/Limits [(lstnumber.-112.1) (lstnumber.-116.2)] +>> endobj +2575 0 obj << +/Names [(lstnumber.-116.3) 1974 0 R (lstnumber.-116.4) 1975 0 R (lstnumber.-116.5) 1976 0 R (lstnumber.-116.6) 1977 0 R (lstnumber.-116.7) 1978 0 R (lstnumber.-116.8) 1979 0 R] +/Limits [(lstnumber.-116.3) (lstnumber.-116.8)] +>> endobj +2576 0 obj << +/Names [(lstnumber.-117.1) 1987 0 R (lstnumber.-117.2) 1988 0 R (lstnumber.-118.1) 2006 0 R (lstnumber.-118.2) 2007 0 R (lstnumber.-118.3) 2008 0 R (lstnumber.-118.4) 2009 0 R] +/Limits [(lstnumber.-117.1) (lstnumber.-118.4)] +>> endobj +2577 0 obj << +/Names [(lstnumber.-118.5) 2010 0 R (lstnumber.-118.6) 2011 0 R (lstnumber.-119.1) 2022 0 R (lstnumber.-12.1) 1565 0 R (lstnumber.-12.2) 1566 0 R (lstnumber.-12.3) 1567 0 R] +/Limits [(lstnumber.-118.5) (lstnumber.-12.3)] +>> endobj +2578 0 obj << +/Names [(lstnumber.-120.1) 2024 0 R (lstnumber.-121.1) 2026 0 R (lstnumber.-121.10) 2035 0 R (lstnumber.-121.2) 2027 0 R (lstnumber.-121.3) 2028 0 R (lstnumber.-121.4) 2029 0 R] +/Limits [(lstnumber.-120.1) (lstnumber.-121.4)] +>> endobj +2579 0 obj << +/Names [(lstnumber.-121.5) 2030 0 R (lstnumber.-121.6) 2031 0 R (lstnumber.-121.7) 2032 0 R (lstnumber.-121.8) 2033 0 R (lstnumber.-121.9) 2034 0 R (lstnumber.-122.1) 2049 0 R] +/Limits [(lstnumber.-121.5) (lstnumber.-122.1)] +>> endobj +2580 0 obj << +/Names [(lstnumber.-122.2) 2050 0 R (lstnumber.-122.3) 2051 0 R (lstnumber.-122.4) 2052 0 R (lstnumber.-122.5) 2053 0 R (lstnumber.-122.6) 2054 0 R (lstnumber.-122.7) 2055 0 R] +/Limits [(lstnumber.-122.2) (lstnumber.-122.7)] +>> endobj +2581 0 obj << +/Names [(lstnumber.-123.1) 2061 0 R (lstnumber.-123.2) 2062 0 R (lstnumber.-123.3) 2063 0 R (lstnumber.-124.1) 2074 0 R (lstnumber.-124.10) 2083 0 R (lstnumber.-124.11) 2084 0 R] +/Limits [(lstnumber.-123.1) (lstnumber.-124.11)] +>> endobj +2582 0 obj << +/Names [(lstnumber.-124.12) 2085 0 R (lstnumber.-124.2) 2075 0 R (lstnumber.-124.3) 2076 0 R (lstnumber.-124.4) 2077 0 R (lstnumber.-124.5) 2078 0 R (lstnumber.-124.6) 2079 0 R] +/Limits [(lstnumber.-124.12) (lstnumber.-124.6)] +>> endobj +2583 0 obj << +/Names [(lstnumber.-124.7) 2080 0 R (lstnumber.-124.8) 2081 0 R (lstnumber.-124.9) 2082 0 R (lstnumber.-125.1) 2091 0 R (lstnumber.-125.10) 2100 0 R (lstnumber.-125.11) 2101 0 R] +/Limits [(lstnumber.-124.7) (lstnumber.-125.11)] +>> endobj +2584 0 obj << +/Names [(lstnumber.-125.12) 2102 0 R (lstnumber.-125.2) 2092 0 R (lstnumber.-125.3) 2093 0 R (lstnumber.-125.4) 2094 0 R (lstnumber.-125.5) 2095 0 R (lstnumber.-125.6) 2096 0 R] +/Limits [(lstnumber.-125.12) (lstnumber.-125.6)] +>> endobj +2585 0 obj << +/Names [(lstnumber.-125.7) 2097 0 R (lstnumber.-125.8) 2098 0 R (lstnumber.-125.9) 2099 0 R (lstnumber.-126.1) 2104 0 R (lstnumber.-126.2) 2105 0 R (lstnumber.-126.3) 2106 0 R] +/Limits [(lstnumber.-125.7) (lstnumber.-126.3)] +>> endobj +2586 0 obj << +/Names [(lstnumber.-126.4) 2107 0 R (lstnumber.-127.1) 2109 0 R (lstnumber.-127.2) 2110 0 R (lstnumber.-128.1) 2116 0 R (lstnumber.-128.2) 2117 0 R (lstnumber.-128.3) 2118 0 R] +/Limits [(lstnumber.-126.4) (lstnumber.-128.3)] +>> endobj +2587 0 obj << +/Names [(lstnumber.-128.4) 2119 0 R (lstnumber.-128.5) 2120 0 R (lstnumber.-129.1) 2122 0 R (lstnumber.-129.2) 2123 0 R (lstnumber.-129.3) 2124 0 R (lstnumber.-129.4) 2125 0 R] +/Limits [(lstnumber.-128.4) (lstnumber.-129.4)] +>> endobj +2588 0 obj << +/Names [(lstnumber.-129.5) 2126 0 R (lstnumber.-129.6) 2127 0 R (lstnumber.-129.7) 2128 0 R (lstnumber.-13.1) 1574 0 R (lstnumber.-13.2) 1575 0 R (lstnumber.-13.3) 1576 0 R] +/Limits [(lstnumber.-129.5) (lstnumber.-13.3)] +>> endobj +2589 0 obj << +/Names [(lstnumber.-13.4) 1577 0 R (lstnumber.-13.5) 1578 0 R (lstnumber.-130.1) 2134 0 R (lstnumber.-130.10) 2143 0 R (lstnumber.-130.11) 2144 0 R (lstnumber.-130.12) 2145 0 R] +/Limits [(lstnumber.-13.4) (lstnumber.-130.12)] +>> endobj +2590 0 obj << +/Names [(lstnumber.-130.2) 2135 0 R (lstnumber.-130.3) 2136 0 R (lstnumber.-130.4) 2137 0 R (lstnumber.-130.5) 2138 0 R (lstnumber.-130.6) 2139 0 R (lstnumber.-130.7) 2140 0 R] +/Limits [(lstnumber.-130.2) (lstnumber.-130.7)] +>> endobj +2591 0 obj << +/Names [(lstnumber.-130.8) 2141 0 R (lstnumber.-130.9) 2142 0 R (lstnumber.-131.1) 2147 0 R (lstnumber.-131.10) 2156 0 R (lstnumber.-131.11) 2157 0 R (lstnumber.-131.12) 2158 0 R] +/Limits [(lstnumber.-130.8) (lstnumber.-131.12)] +>> endobj +2592 0 obj << +/Names [(lstnumber.-131.13) 2159 0 R (lstnumber.-131.14) 2160 0 R (lstnumber.-131.15) 2161 0 R (lstnumber.-131.16) 2162 0 R (lstnumber.-131.17) 2167 0 R (lstnumber.-131.18) 2168 0 R] +/Limits [(lstnumber.-131.13) (lstnumber.-131.18)] +>> endobj +2593 0 obj << +/Names [(lstnumber.-131.2) 2148 0 R (lstnumber.-131.3) 2149 0 R (lstnumber.-131.4) 2150 0 R (lstnumber.-131.5) 2151 0 R (lstnumber.-131.6) 2152 0 R (lstnumber.-131.7) 2153 0 R] +/Limits [(lstnumber.-131.2) (lstnumber.-131.7)] +>> endobj +2594 0 obj << +/Names [(lstnumber.-131.8) 2154 0 R (lstnumber.-131.9) 2155 0 R (lstnumber.-132.1) 2170 0 R (lstnumber.-132.2) 2171 0 R (lstnumber.-132.3) 2172 0 R (lstnumber.-132.4) 2173 0 R] +/Limits [(lstnumber.-131.8) (lstnumber.-132.4)] +>> endobj +2595 0 obj << +/Names [(lstnumber.-132.5) 2174 0 R (lstnumber.-132.6) 2175 0 R (lstnumber.-133.1) 2177 0 R (lstnumber.-133.10) 2186 0 R (lstnumber.-133.11) 2187 0 R (lstnumber.-133.12) 2188 0 R] +/Limits [(lstnumber.-132.5) (lstnumber.-133.12)] +>> endobj +2596 0 obj << +/Names [(lstnumber.-133.2) 2178 0 R (lstnumber.-133.3) 2179 0 R (lstnumber.-133.4) 2180 0 R (lstnumber.-133.5) 2181 0 R (lstnumber.-133.6) 2182 0 R (lstnumber.-133.7) 2183 0 R] +/Limits [(lstnumber.-133.2) (lstnumber.-133.7)] +>> endobj +2597 0 obj << +/Names [(lstnumber.-133.8) 2184 0 R (lstnumber.-133.9) 2185 0 R (lstnumber.-134.1) 2195 0 R (lstnumber.-134.10) 2204 0 R (lstnumber.-134.11) 2205 0 R (lstnumber.-134.12) 2206 0 R] +/Limits [(lstnumber.-133.8) (lstnumber.-134.12)] +>> endobj +2598 0 obj << +/Names [(lstnumber.-134.2) 2196 0 R (lstnumber.-134.3) 2197 0 R (lstnumber.-134.4) 2198 0 R (lstnumber.-134.5) 2199 0 R (lstnumber.-134.6) 2200 0 R (lstnumber.-134.7) 2201 0 R] +/Limits [(lstnumber.-134.2) (lstnumber.-134.7)] +>> endobj +2599 0 obj << +/Names [(lstnumber.-134.8) 2202 0 R (lstnumber.-134.9) 2203 0 R (lstnumber.-135.1) 2213 0 R (lstnumber.-135.2) 2214 0 R (lstnumber.-135.3) 2215 0 R (lstnumber.-135.4) 2220 0 R] +/Limits [(lstnumber.-134.8) (lstnumber.-135.4)] +>> endobj +2600 0 obj << +/Names [(lstnumber.-135.5) 2221 0 R (lstnumber.-136.1) 2231 0 R (lstnumber.-136.2) 2232 0 R (lstnumber.-136.3) 2233 0 R (lstnumber.-136.4) 2234 0 R (lstnumber.-136.5) 2235 0 R] +/Limits [(lstnumber.-135.5) (lstnumber.-136.5)] +>> endobj +2601 0 obj << +/Names [(lstnumber.-136.6) 2236 0 R (lstnumber.-136.7) 2237 0 R (lstnumber.-137.1) 2239 0 R (lstnumber.-138.1) 2245 0 R (lstnumber.-139.1) 2247 0 R (lstnumber.-14.1) 1580 0 R] +/Limits [(lstnumber.-136.6) (lstnumber.-14.1)] +>> endobj +2602 0 obj << +/Names [(lstnumber.-14.2) 1581 0 R (lstnumber.-14.3) 1582 0 R (lstnumber.-140.1) 2249 0 R (lstnumber.-141.1) 2256 0 R (lstnumber.-142.1) 2258 0 R (lstnumber.-143.1) 2260 0 R] +/Limits [(lstnumber.-14.2) (lstnumber.-143.1)] +>> endobj +2603 0 obj << +/Names [(lstnumber.-143.2) 2261 0 R (lstnumber.-144.1) 2267 0 R (lstnumber.-145.1) 2269 0 R (lstnumber.-146.1) 2271 0 R (lstnumber.-147.1) 2277 0 R (lstnumber.-148.1) 2279 0 R] +/Limits [(lstnumber.-143.2) (lstnumber.-148.1)] +>> endobj +2604 0 obj << +/Names [(lstnumber.-149.1) 2281 0 R (lstnumber.-15.1) 1584 0 R (lstnumber.-150.1) 2287 0 R (lstnumber.-151.1) 2289 0 R (lstnumber.-16.1) 1590 0 R (lstnumber.-17.1) 1592 0 R] +/Limits [(lstnumber.-149.1) (lstnumber.-17.1)] +>> endobj +2605 0 obj << +/Names [(lstnumber.-17.2) 1593 0 R (lstnumber.-17.3) 1594 0 R (lstnumber.-18.1) 1596 0 R (lstnumber.-18.2) 1597 0 R (lstnumber.-18.3) 1598 0 R (lstnumber.-19.1) 1604 0 R] +/Limits [(lstnumber.-17.2) (lstnumber.-19.1)] +>> endobj +2606 0 obj << +/Names [(lstnumber.-19.2) 1605 0 R (lstnumber.-19.3) 1606 0 R (lstnumber.-2.1) 1460 0 R (lstnumber.-20.1) 1608 0 R (lstnumber.-21.1) 1610 0 R (lstnumber.-22.1) 1616 0 R] +/Limits [(lstnumber.-19.2) (lstnumber.-22.1)] +>> endobj +2607 0 obj << +/Names [(lstnumber.-23.1) 1618 0 R (lstnumber.-24.1) 1620 0 R (lstnumber.-25.1) 1622 0 R (lstnumber.-26.1) 1628 0 R (lstnumber.-26.2) 1629 0 R (lstnumber.-26.3) 1630 0 R] +/Limits [(lstnumber.-23.1) (lstnumber.-26.3)] +>> endobj +2608 0 obj << +/Names [(lstnumber.-26.4) 1631 0 R (lstnumber.-26.5) 1632 0 R (lstnumber.-27.1) 1638 0 R (lstnumber.-28.1) 1645 0 R (lstnumber.-28.10) 1654 0 R (lstnumber.-28.2) 1646 0 R] +/Limits [(lstnumber.-26.4) (lstnumber.-28.2)] +>> endobj +2609 0 obj << +/Names [(lstnumber.-28.3) 1647 0 R (lstnumber.-28.4) 1648 0 R (lstnumber.-28.5) 1649 0 R (lstnumber.-28.6) 1650 0 R (lstnumber.-28.7) 1651 0 R (lstnumber.-28.8) 1652 0 R] +/Limits [(lstnumber.-28.3) (lstnumber.-28.8)] +>> endobj +2610 0 obj << +/Names [(lstnumber.-28.9) 1653 0 R (lstnumber.-29.1) 1656 0 R (lstnumber.-3.1) 1466 0 R (lstnumber.-30.1) 1658 0 R (lstnumber.-31.1) 1664 0 R (lstnumber.-32.1) 1666 0 R] +/Limits [(lstnumber.-28.9) (lstnumber.-32.1)] +>> endobj +2611 0 obj << +/Names [(lstnumber.-33.1) 1668 0 R (lstnumber.-34.1) 1670 0 R (lstnumber.-35.1) 1676 0 R (lstnumber.-36.1) 1678 0 R (lstnumber.-37.1) 1680 0 R (lstnumber.-38.1) 1682 0 R] +/Limits [(lstnumber.-33.1) (lstnumber.-38.1)] +>> endobj +2612 0 obj << +/Names [(lstnumber.-39.1) 1688 0 R (lstnumber.-39.2) 1689 0 R (lstnumber.-4.1) 1468 0 R (lstnumber.-40.1) 1691 0 R (lstnumber.-41.1) 1693 0 R (lstnumber.-42.1) 1695 0 R] +/Limits [(lstnumber.-39.1) (lstnumber.-42.1)] +>> endobj +2613 0 obj << +/Names [(lstnumber.-43.1) 1701 0 R (lstnumber.-44.1) 1703 0 R (lstnumber.-45.1) 1705 0 R (lstnumber.-46.1) 1707 0 R (lstnumber.-47.1) 1713 0 R (lstnumber.-48.1) 1715 0 R] +/Limits [(lstnumber.-43.1) (lstnumber.-48.1)] +>> endobj +2614 0 obj << +/Names [(lstnumber.-48.2) 1716 0 R (lstnumber.-49.1) 1718 0 R (lstnumber.-5.1) 1470 0 R (lstnumber.-50.1) 1720 0 R (lstnumber.-51.1) 1727 0 R (lstnumber.-52.1) 1729 0 R] +/Limits [(lstnumber.-48.2) (lstnumber.-52.1)] +>> endobj +2615 0 obj << +/Names [(lstnumber.-53.1) 1731 0 R (lstnumber.-54.1) 1733 0 R (lstnumber.-55.1) 1739 0 R (lstnumber.-56.1) 1741 0 R (lstnumber.-57.1) 1743 0 R (lstnumber.-58.1) 1745 0 R] +/Limits [(lstnumber.-53.1) (lstnumber.-58.1)] +>> endobj +2616 0 obj << +/Names [(lstnumber.-59.1) 1751 0 R (lstnumber.-6.1) 1489 0 R (lstnumber.-6.2) 1490 0 R (lstnumber.-6.3) 1491 0 R (lstnumber.-60.1) 1753 0 R (lstnumber.-61.1) 1755 0 R] +/Limits [(lstnumber.-59.1) (lstnumber.-61.1)] +>> endobj +2617 0 obj << +/Names [(lstnumber.-62.1) 1757 0 R (lstnumber.-63.1) 1763 0 R (lstnumber.-63.2) 1764 0 R (lstnumber.-63.3) 1765 0 R (lstnumber.-63.4) 1766 0 R (lstnumber.-64.1) 1768 0 R] +/Limits [(lstnumber.-62.1) (lstnumber.-64.1)] +>> endobj +2618 0 obj << +/Names [(lstnumber.-65.1) 1774 0 R (lstnumber.-66.1) 1776 0 R (lstnumber.-67.1) 1778 0 R (lstnumber.-68.1) 1780 0 R (lstnumber.-69.1) 1786 0 R (lstnumber.-7.1) 1493 0 R] +/Limits [(lstnumber.-65.1) (lstnumber.-7.1)] +>> endobj +2619 0 obj << +/Names [(lstnumber.-7.2) 1495 0 R (lstnumber.-7.3) 1501 0 R (lstnumber.-7.4) 1502 0 R (lstnumber.-7.5) 1503 0 R (lstnumber.-7.6) 1504 0 R (lstnumber.-70.1) 1788 0 R] +/Limits [(lstnumber.-7.2) (lstnumber.-70.1)] +>> endobj +2620 0 obj << +/Names [(lstnumber.-71.1) 1790 0 R (lstnumber.-72.1) 1797 0 R (lstnumber.-73.1) 1799 0 R (lstnumber.-74.1) 1805 0 R (lstnumber.-75.1) 1807 0 R (lstnumber.-75.2) 1808 0 R] +/Limits [(lstnumber.-71.1) (lstnumber.-75.2)] +>> endobj +2621 0 obj << +/Names [(lstnumber.-76.1) 1810 0 R (lstnumber.-77.1) 1812 0 R (lstnumber.-78.1) 1818 0 R (lstnumber.-79.1) 1820 0 R (lstnumber.-8.1) 1506 0 R (lstnumber.-8.2) 1507 0 R] +/Limits [(lstnumber.-76.1) (lstnumber.-8.2)] +>> endobj +2622 0 obj << +/Names [(lstnumber.-8.3) 1508 0 R (lstnumber.-80.1) 1822 0 R (lstnumber.-81.1) 1828 0 R (lstnumber.-82.1) 1834 0 R (lstnumber.-83.1) 1836 0 R (lstnumber.-84.1) 1842 0 R] +/Limits [(lstnumber.-8.3) (lstnumber.-84.1)] +>> endobj +2623 0 obj << +/Names [(lstnumber.-85.1) 1844 0 R (lstnumber.-86.1) 1846 0 R (lstnumber.-87.1) 1848 0 R (lstnumber.-88.1) 1863 0 R (lstnumber.-89.1) 1865 0 R (lstnumber.-9.1) 1510 0 R] +/Limits [(lstnumber.-85.1) (lstnumber.-9.1)] +>> endobj +2624 0 obj << +/Names [(lstnumber.-9.2) 1511 0 R (lstnumber.-9.3) 1512 0 R (lstnumber.-9.4) 1513 0 R (lstnumber.-9.5) 1514 0 R (lstnumber.-90.1) 1867 0 R (lstnumber.-91.1) 1869 0 R] +/Limits [(lstnumber.-9.2) (lstnumber.-91.1)] +>> endobj +2625 0 obj << +/Names [(lstnumber.-92.1) 1875 0 R (lstnumber.-92.2) 1876 0 R (lstnumber.-92.3) 1877 0 R (lstnumber.-93.1) 1879 0 R (lstnumber.-94.1) 1885 0 R (lstnumber.-95.1) 1887 0 R] +/Limits [(lstnumber.-92.1) (lstnumber.-95.1)] +>> endobj +2626 0 obj << +/Names [(lstnumber.-95.2) 1888 0 R (lstnumber.-96.1) 1890 0 R (lstnumber.-97.1) 1896 0 R (lstnumber.-98.1) 1898 0 R (lstnumber.-99.1) 1900 0 R (page.1) 1105 0 R] +/Limits [(lstnumber.-95.2) (page.1)] +>> endobj +2627 0 obj << +/Names [(page.10) 1388 0 R (page.100) 2311 0 R (page.101) 2315 0 R (page.102) 2319 0 R (page.103) 2338 0 R (page.104) 2355 0 R] +/Limits [(page.10) (page.104)] +>> endobj +2628 0 obj << +/Names [(page.105) 2368 0 R (page.106) 2379 0 R (page.107) 2389 0 R (page.108) 2403 0 R (page.109) 2411 0 R (page.11) 1419 0 R] +/Limits [(page.105) (page.11)] +>> endobj +2629 0 obj << +/Names [(page.110) 2422 0 R (page.111) 2438 0 R (page.112) 2450 0 R (page.113) 2464 0 R (page.114) 2477 0 R (page.115) 2487 0 R] +/Limits [(page.110) (page.115)] +>> endobj +2630 0 obj << +/Names [(page.116) 2492 0 R (page.117) 2496 0 R (page.118) 2512 0 R (page.12) 1431 0 R (page.13) 1436 0 R (page.14) 1442 0 R] +/Limits [(page.116) (page.14)] +>> endobj +2631 0 obj << +/Names [(page.15) 1453 0 R (page.16) 1458 0 R (page.17) 1464 0 R (page.18) 1476 0 R (page.19) 1485 0 R (page.2) 1137 0 R] +/Limits [(page.15) (page.2)] +>> endobj +2632 0 obj << +/Names [(page.20) 1500 0 R (page.21) 1518 0 R (page.22) 1522 0 R (page.23) 1526 0 R (page.24) 1530 0 R (page.25) 1534 0 R] +/Limits [(page.20) (page.25)] +>> endobj +2633 0 obj << +/Names [(page.26) 1539 0 R (page.27) 1543 0 R (page.28) 1547 0 R (page.29) 1551 0 R (page.3) 1170 0 R (page.30) 1557 0 R] +/Limits [(page.26) (page.30)] +>> endobj +2634 0 obj << +/Names [(page.31) 1561 0 R (page.32) 1572 0 R (page.33) 1588 0 R (page.34) 1602 0 R (page.35) 1614 0 R (page.36) 1626 0 R] +/Limits [(page.31) (page.36)] +>> endobj +2635 0 obj << +/Names [(page.37) 1636 0 R (page.38) 1643 0 R (page.39) 1662 0 R (page.4) 1201 0 R (page.40) 1674 0 R (page.41) 1686 0 R] +/Limits [(page.37) (page.41)] +>> endobj +2636 0 obj << +/Names [(page.42) 1699 0 R (page.43) 1711 0 R (page.44) 1725 0 R (page.45) 1737 0 R (page.46) 1749 0 R (page.47) 1761 0 R] +/Limits [(page.42) (page.47)] +>> endobj +2637 0 obj << +/Names [(page.48) 1772 0 R (page.49) 1784 0 R (page.5) 1232 0 R (page.50) 1795 0 R (page.51) 1803 0 R (page.52) 1816 0 R] +/Limits [(page.48) (page.52)] +>> endobj +2638 0 obj << +/Names [(page.53) 1826 0 R (page.54) 1832 0 R (page.55) 1840 0 R (page.56) 1853 0 R (page.57) 1857 0 R (page.58) 1861 0 R] +/Limits [(page.53) (page.58)] +>> endobj +2639 0 obj << +/Names [(page.59) 1873 0 R (page.6) 1263 0 R (page.60) 1883 0 R (page.61) 1894 0 R (page.62) 1907 0 R (page.63) 1913 0 R] +/Limits [(page.59) (page.63)] +>> endobj +2640 0 obj << +/Names [(page.64) 1917 0 R (page.65) 1929 0 R (page.66) 1941 0 R (page.67) 1947 0 R (page.68) 1958 0 R (page.69) 1970 0 R] +/Limits [(page.64) (page.69)] +>> endobj +2641 0 obj << +/Names [(page.7) 1294 0 R (page.70) 1984 0 R (page.71) 1993 0 R (page.72) 1999 0 R (page.73) 2004 0 R (page.74) 2016 0 R] +/Limits [(page.7) (page.74)] +>> endobj +2642 0 obj << +/Names [(page.75) 2020 0 R (page.76) 2039 0 R (page.77) 2043 0 R (page.78) 2047 0 R (page.79) 2059 0 R (page.8) 1326 0 R] +/Limits [(page.75) (page.8)] +>> endobj +2643 0 obj << +/Names [(page.80) 2068 0 R (page.81) 2072 0 R (page.82) 2089 0 R (page.83) 2114 0 R (page.84) 2132 0 R (page.85) 2166 0 R] +/Limits [(page.80) (page.85)] +>> endobj +2644 0 obj << +/Names [(page.86) 2193 0 R (page.87) 2210 0 R (page.88) 2219 0 R (page.89) 2225 0 R (page.9) 1357 0 R (page.90) 2229 0 R] +/Limits [(page.86) (page.90)] +>> endobj +2645 0 obj << +/Names [(page.91) 2243 0 R (page.92) 2254 0 R (page.93) 2265 0 R (page.94) 2275 0 R (page.95) 2285 0 R (page.96) 2293 0 R] +/Limits [(page.91) (page.96)] +>> endobj +2646 0 obj << +/Names [(page.97) 2297 0 R (page.98) 2303 0 R (page.99) 2307 0 R (paragraph.10.1.1.1) 86 0 R (paragraph.10.1.1.2) 90 0 R (paragraph.10.1.1.3) 94 0 R] +/Limits [(page.97) (paragraph.10.1.1.3)] +>> endobj +2647 0 obj << +/Names [(paragraph.10.1.1.4) 98 0 R (paragraph.10.1.1.5) 102 0 R (paragraph.10.1.1.6) 106 0 R (paragraph.10.1.1.7) 110 0 R (paragraph.10.1.10.1) 662 0 R (paragraph.10.1.10.2) 666 0 R] +/Limits [(paragraph.10.1.1.4) (paragraph.10.1.10.2)] +>> endobj +2648 0 obj << +/Names [(paragraph.10.1.10.3) 670 0 R (paragraph.10.1.10.4) 674 0 R (paragraph.10.1.10.5) 678 0 R (paragraph.10.1.10.6) 682 0 R (paragraph.10.1.11.1) 690 0 R (paragraph.10.1.12.1) 698 0 R] +/Limits [(paragraph.10.1.10.3) (paragraph.10.1.12.1)] +>> endobj +2649 0 obj << +/Names [(paragraph.10.1.12.2) 702 0 R (paragraph.10.1.12.3) 706 0 R (paragraph.10.1.12.4) 710 0 R (paragraph.10.1.12.5) 714 0 R (paragraph.10.1.12.6) 718 0 R (paragraph.10.1.12.7) 722 0 R] +/Limits [(paragraph.10.1.12.2) (paragraph.10.1.12.7)] +>> endobj +2650 0 obj << +/Names [(paragraph.10.1.2.1) 118 0 R (paragraph.10.1.2.2) 122 0 R (paragraph.10.1.2.3) 126 0 R (paragraph.10.1.2.4) 130 0 R (paragraph.10.1.2.5) 134 0 R (paragraph.10.1.3.1) 142 0 R] +/Limits [(paragraph.10.1.2.1) (paragraph.10.1.3.1)] +>> endobj +2651 0 obj << +/Names [(paragraph.10.1.3.10) 178 0 R (paragraph.10.1.3.11) 182 0 R (paragraph.10.1.3.12) 186 0 R (paragraph.10.1.3.13) 190 0 R (paragraph.10.1.3.14) 194 0 R (paragraph.10.1.3.15) 198 0 R] +/Limits [(paragraph.10.1.3.10) (paragraph.10.1.3.15)] +>> endobj +2652 0 obj << +/Names [(paragraph.10.1.3.16) 202 0 R (paragraph.10.1.3.17) 206 0 R (paragraph.10.1.3.18) 210 0 R (paragraph.10.1.3.2) 146 0 R (paragraph.10.1.3.3) 150 0 R (paragraph.10.1.3.4) 154 0 R] +/Limits [(paragraph.10.1.3.16) (paragraph.10.1.3.4)] +>> endobj +2653 0 obj << +/Names [(paragraph.10.1.3.5) 158 0 R (paragraph.10.1.3.6) 162 0 R (paragraph.10.1.3.7) 166 0 R (paragraph.10.1.3.8) 170 0 R (paragraph.10.1.3.9) 174 0 R (paragraph.10.1.4.1) 218 0 R] +/Limits [(paragraph.10.1.3.5) (paragraph.10.1.4.1)] +>> endobj +2654 0 obj << +/Names [(paragraph.10.1.4.10) 254 0 R (paragraph.10.1.4.11) 258 0 R (paragraph.10.1.4.12) 262 0 R (paragraph.10.1.4.13) 266 0 R (paragraph.10.1.4.14) 270 0 R (paragraph.10.1.4.15) 274 0 R] +/Limits [(paragraph.10.1.4.10) (paragraph.10.1.4.15)] +>> endobj +2655 0 obj << +/Names [(paragraph.10.1.4.16) 278 0 R (paragraph.10.1.4.17) 282 0 R (paragraph.10.1.4.18) 286 0 R (paragraph.10.1.4.19) 290 0 R (paragraph.10.1.4.2) 222 0 R (paragraph.10.1.4.20) 294 0 R] +/Limits [(paragraph.10.1.4.16) (paragraph.10.1.4.20)] +>> endobj +2656 0 obj << +/Names [(paragraph.10.1.4.21) 298 0 R (paragraph.10.1.4.22) 302 0 R (paragraph.10.1.4.23) 306 0 R (paragraph.10.1.4.24) 310 0 R (paragraph.10.1.4.25) 314 0 R (paragraph.10.1.4.26) 318 0 R] +/Limits [(paragraph.10.1.4.21) (paragraph.10.1.4.26)] +>> endobj +2657 0 obj << +/Names [(paragraph.10.1.4.27) 322 0 R (paragraph.10.1.4.28) 326 0 R (paragraph.10.1.4.29) 330 0 R (paragraph.10.1.4.3) 226 0 R (paragraph.10.1.4.30) 334 0 R (paragraph.10.1.4.31) 338 0 R] +/Limits [(paragraph.10.1.4.27) (paragraph.10.1.4.31)] +>> endobj +2658 0 obj << +/Names [(paragraph.10.1.4.32) 342 0 R (paragraph.10.1.4.33) 346 0 R (paragraph.10.1.4.34) 350 0 R (paragraph.10.1.4.35) 354 0 R (paragraph.10.1.4.36) 358 0 R (paragraph.10.1.4.37) 362 0 R] +/Limits [(paragraph.10.1.4.32) (paragraph.10.1.4.37)] +>> endobj +2659 0 obj << +/Names [(paragraph.10.1.4.38) 366 0 R (paragraph.10.1.4.39) 370 0 R (paragraph.10.1.4.4) 230 0 R (paragraph.10.1.4.5) 234 0 R (paragraph.10.1.4.6) 238 0 R (paragraph.10.1.4.7) 242 0 R] +/Limits [(paragraph.10.1.4.38) (paragraph.10.1.4.7)] +>> endobj +2660 0 obj << +/Names [(paragraph.10.1.4.8) 246 0 R (paragraph.10.1.4.9) 250 0 R (paragraph.10.1.5.1) 378 0 R (paragraph.10.1.5.10) 414 0 R (paragraph.10.1.5.11) 418 0 R (paragraph.10.1.5.2) 382 0 R] +/Limits [(paragraph.10.1.4.8) (paragraph.10.1.5.2)] +>> endobj +2661 0 obj << +/Names [(paragraph.10.1.5.3) 386 0 R (paragraph.10.1.5.4) 390 0 R (paragraph.10.1.5.5) 394 0 R (paragraph.10.1.5.6) 398 0 R (paragraph.10.1.5.7) 402 0 R (paragraph.10.1.5.8) 406 0 R] +/Limits [(paragraph.10.1.5.3) (paragraph.10.1.5.8)] +>> endobj +2662 0 obj << +/Names [(paragraph.10.1.5.9) 410 0 R (paragraph.10.1.6.1) 426 0 R (paragraph.10.1.6.10) 462 0 R (paragraph.10.1.6.11) 466 0 R (paragraph.10.1.6.2) 430 0 R (paragraph.10.1.6.3) 434 0 R] +/Limits [(paragraph.10.1.5.9) (paragraph.10.1.6.3)] +>> endobj +2663 0 obj << +/Names [(paragraph.10.1.6.4) 438 0 R (paragraph.10.1.6.5) 442 0 R (paragraph.10.1.6.6) 446 0 R (paragraph.10.1.6.7) 450 0 R (paragraph.10.1.6.8) 454 0 R (paragraph.10.1.6.9) 458 0 R] +/Limits [(paragraph.10.1.6.4) (paragraph.10.1.6.9)] +>> endobj +2664 0 obj << +/Names [(paragraph.10.1.7.1) 474 0 R (paragraph.10.1.7.10) 510 0 R (paragraph.10.1.7.11) 514 0 R (paragraph.10.1.7.12) 518 0 R (paragraph.10.1.7.13) 522 0 R (paragraph.10.1.7.14) 526 0 R] +/Limits [(paragraph.10.1.7.1) (paragraph.10.1.7.14)] +>> endobj +2665 0 obj << +/Names [(paragraph.10.1.7.15) 530 0 R (paragraph.10.1.7.16) 534 0 R (paragraph.10.1.7.17) 538 0 R (paragraph.10.1.7.18) 542 0 R (paragraph.10.1.7.19) 546 0 R (paragraph.10.1.7.2) 478 0 R] +/Limits [(paragraph.10.1.7.15) (paragraph.10.1.7.2)] +>> endobj +2666 0 obj << +/Names [(paragraph.10.1.7.20) 550 0 R (paragraph.10.1.7.21) 554 0 R (paragraph.10.1.7.22) 558 0 R (paragraph.10.1.7.23) 562 0 R (paragraph.10.1.7.24) 566 0 R (paragraph.10.1.7.25) 570 0 R] +/Limits [(paragraph.10.1.7.20) (paragraph.10.1.7.25)] +>> endobj +2667 0 obj << +/Names [(paragraph.10.1.7.26) 574 0 R (paragraph.10.1.7.27) 578 0 R (paragraph.10.1.7.28) 582 0 R (paragraph.10.1.7.29) 586 0 R (paragraph.10.1.7.3) 482 0 R (paragraph.10.1.7.30) 590 0 R] +/Limits [(paragraph.10.1.7.26) (paragraph.10.1.7.30)] +>> endobj +2668 0 obj << +/Names [(paragraph.10.1.7.31) 594 0 R (paragraph.10.1.7.4) 486 0 R (paragraph.10.1.7.5) 490 0 R (paragraph.10.1.7.6) 494 0 R (paragraph.10.1.7.7) 498 0 R (paragraph.10.1.7.8) 502 0 R] +/Limits [(paragraph.10.1.7.31) (paragraph.10.1.7.8)] +>> endobj +2669 0 obj << +/Names [(paragraph.10.1.7.9) 506 0 R (paragraph.10.1.8.1) 602 0 R (paragraph.10.1.8.2) 606 0 R (paragraph.10.1.8.3) 610 0 R (paragraph.10.1.8.4) 614 0 R (paragraph.10.1.8.5) 618 0 R] +/Limits [(paragraph.10.1.7.9) (paragraph.10.1.8.5)] +>> endobj +2670 0 obj << +/Names [(paragraph.10.1.8.6) 622 0 R (paragraph.10.1.8.7) 626 0 R (paragraph.10.1.8.8) 630 0 R (paragraph.10.1.8.9) 634 0 R (paragraph.10.1.9.1) 642 0 R (paragraph.10.1.9.2) 646 0 R] +/Limits [(paragraph.10.1.8.6) (paragraph.10.1.9.2)] +>> endobj +2671 0 obj << +/Names [(paragraph.10.1.9.3) 650 0 R (paragraph.10.1.9.4) 654 0 R (paragraph.10.2.1.1) 734 0 R (paragraph.10.2.1.2) 738 0 R (paragraph.10.2.1.3) 742 0 R (paragraph.10.2.1.4) 746 0 R] +/Limits [(paragraph.10.1.9.3) (paragraph.10.2.1.4)] +>> endobj +2672 0 obj << +/Names [(paragraph.10.2.1.5) 750 0 R (paragraph.10.2.1.6) 754 0 R (paragraph.10.2.2.1) 762 0 R (paragraph.10.2.2.10) 798 0 R (paragraph.10.2.2.11) 802 0 R (paragraph.10.2.2.12) 806 0 R] +/Limits [(paragraph.10.2.1.5) (paragraph.10.2.2.12)] +>> endobj +2673 0 obj << +/Names [(paragraph.10.2.2.13) 810 0 R (paragraph.10.2.2.14) 814 0 R (paragraph.10.2.2.15) 818 0 R (paragraph.10.2.2.16) 822 0 R (paragraph.10.2.2.17) 826 0 R (paragraph.10.2.2.18) 830 0 R] +/Limits [(paragraph.10.2.2.13) (paragraph.10.2.2.18)] +>> endobj +2674 0 obj << +/Names [(paragraph.10.2.2.19) 834 0 R (paragraph.10.2.2.2) 766 0 R (paragraph.10.2.2.20) 838 0 R (paragraph.10.2.2.21) 842 0 R (paragraph.10.2.2.22) 846 0 R (paragraph.10.2.2.23) 850 0 R] +/Limits [(paragraph.10.2.2.19) (paragraph.10.2.2.23)] +>> endobj +2675 0 obj << +/Names [(paragraph.10.2.2.24) 854 0 R (paragraph.10.2.2.25) 858 0 R (paragraph.10.2.2.26) 862 0 R (paragraph.10.2.2.3) 770 0 R (paragraph.10.2.2.4) 774 0 R (paragraph.10.2.2.5) 778 0 R] +/Limits [(paragraph.10.2.2.24) (paragraph.10.2.2.5)] +>> endobj +2676 0 obj << +/Names [(paragraph.10.2.2.6) 782 0 R (paragraph.10.2.2.7) 786 0 R (paragraph.10.2.2.8) 790 0 R (paragraph.10.2.2.9) 794 0 R (paragraph.10.2.3.1) 870 0 R (paragraph.10.2.3.2) 874 0 R] +/Limits [(paragraph.10.2.2.6) (paragraph.10.2.3.2)] +>> endobj +2677 0 obj << +/Names [(paragraph.10.2.3.3) 878 0 R (paragraph.10.2.3.4) 882 0 R (paragraph.10.2.3.5) 886 0 R (section*.1) 1139 0 R (section*.2) 1471 0 R (section*.3) 1477 0 R] +/Limits [(paragraph.10.2.3.3) (section*.3)] +>> endobj +2678 0 obj << +/Names [(section*.4) 1479 0 R (section*.5) 1480 0 R (section*.6) 1486 0 R (section*.7) 1098 0 R (section.1) 6 0 R (section.10) 74 0 R] +/Limits [(section*.4) (section.10)] +>> endobj +2679 0 obj << +/Names [(section.2) 14 0 R (section.3) 30 0 R (section.4) 50 0 R (section.5) 54 0 R (section.6) 58 0 R (section.7) 62 0 R] +/Limits [(section.2) (section.7)] +>> endobj +2680 0 obj << +/Names [(section.8) 66 0 R (section.9) 70 0 R (subsection.1.1) 10 0 R (subsection.10.1) 78 0 R (subsection.10.2) 726 0 R (subsection.10.3) 890 0 R] +/Limits [(section.8) (subsection.10.3)] +>> endobj +2681 0 obj << +/Names [(subsection.10.4) 958 0 R (subsection.10.5) 1070 0 R (subsection.10.6) 1086 0 R (subsection.10.7) 1090 0 R (subsection.10.8) 1094 0 R (subsection.2.1) 18 0 R] +/Limits [(subsection.10.4) (subsection.2.1)] +>> endobj +2682 0 obj << +/Names [(subsection.2.2) 22 0 R (subsection.3.1) 34 0 R (subsection.3.2) 38 0 R (subsection.3.3) 42 0 R (subsubsection.10.1.1) 82 0 R (subsubsection.10.1.10) 658 0 R] +/Limits [(subsection.2.2) (subsubsection.10.1.10)] +>> endobj +2683 0 obj << +/Names [(subsubsection.10.1.11) 686 0 R (subsubsection.10.1.12) 694 0 R (subsubsection.10.1.2) 114 0 R (subsubsection.10.1.3) 138 0 R (subsubsection.10.1.4) 214 0 R (subsubsection.10.1.5) 374 0 R] +/Limits [(subsubsection.10.1.11) (subsubsection.10.1.5)] +>> endobj +2684 0 obj << +/Names [(subsubsection.10.1.6) 422 0 R (subsubsection.10.1.7) 470 0 R (subsubsection.10.1.8) 598 0 R (subsubsection.10.1.9) 638 0 R (subsubsection.10.2.1) 730 0 R (subsubsection.10.2.2) 758 0 R] +/Limits [(subsubsection.10.1.6) (subsubsection.10.2.2)] +>> endobj +2685 0 obj << +/Names [(subsubsection.10.2.3) 866 0 R (subsubsection.10.3.1) 894 0 R (subsubsection.10.3.10) 930 0 R (subsubsection.10.3.11) 934 0 R (subsubsection.10.3.12) 938 0 R (subsubsection.10.3.13) 942 0 R] +/Limits [(subsubsection.10.2.3) (subsubsection.10.3.13)] +>> endobj +2686 0 obj << +/Names [(subsubsection.10.3.14) 946 0 R (subsubsection.10.3.15) 950 0 R (subsubsection.10.3.16) 954 0 R (subsubsection.10.3.2) 898 0 R (subsubsection.10.3.3) 902 0 R (subsubsection.10.3.4) 906 0 R] +/Limits [(subsubsection.10.3.14) (subsubsection.10.3.4)] +>> endobj +2687 0 obj << +/Names [(subsubsection.10.3.5) 910 0 R (subsubsection.10.3.6) 914 0 R (subsubsection.10.3.7) 918 0 R (subsubsection.10.3.8) 922 0 R (subsubsection.10.3.9) 926 0 R (subsubsection.10.4.1) 962 0 R] +/Limits [(subsubsection.10.3.5) (subsubsection.10.4.1)] +>> endobj +2688 0 obj << +/Names [(subsubsection.10.4.10) 998 0 R (subsubsection.10.4.11) 1002 0 R (subsubsection.10.4.12) 1006 0 R (subsubsection.10.4.13) 1010 0 R (subsubsection.10.4.14) 1014 0 R (subsubsection.10.4.15) 1018 0 R] +/Limits [(subsubsection.10.4.10) (subsubsection.10.4.15)] +>> endobj +2689 0 obj << +/Names [(subsubsection.10.4.16) 1022 0 R (subsubsection.10.4.17) 1026 0 R (subsubsection.10.4.18) 1030 0 R (subsubsection.10.4.19) 1034 0 R (subsubsection.10.4.2) 966 0 R (subsubsection.10.4.20) 1038 0 R] +/Limits [(subsubsection.10.4.16) (subsubsection.10.4.20)] +>> endobj +2690 0 obj << +/Names [(subsubsection.10.4.21) 1042 0 R (subsubsection.10.4.22) 1046 0 R (subsubsection.10.4.23) 1050 0 R (subsubsection.10.4.24) 1054 0 R (subsubsection.10.4.25) 1058 0 R (subsubsection.10.4.26) 1062 0 R] +/Limits [(subsubsection.10.4.21) (subsubsection.10.4.26)] +>> endobj +2691 0 obj << +/Names [(subsubsection.10.4.27) 1066 0 R (subsubsection.10.4.3) 970 0 R (subsubsection.10.4.4) 974 0 R (subsubsection.10.4.5) 978 0 R (subsubsection.10.4.6) 982 0 R (subsubsection.10.4.7) 986 0 R] +/Limits [(subsubsection.10.4.27) (subsubsection.10.4.7)] +>> endobj +2692 0 obj << +/Names [(subsubsection.10.4.8) 990 0 R (subsubsection.10.4.9) 994 0 R (subsubsection.10.5.1) 1074 0 R (subsubsection.10.5.2) 1078 0 R (subsubsection.10.5.3) 1082 0 R (subsubsection.2.2.1) 26 0 R] +/Limits [(subsubsection.10.4.8) (subsubsection.2.2.1)] +>> endobj +2693 0 obj << +/Names [(subsubsection.3.3.1) 46 0 R (table.1) 1454 0 R (table.10) 2000 0 R (table.11) 2211 0 R (table.12) 2298 0 R (table.13) 2320 0 R] +/Limits [(subsubsection.3.3.1) (table.13)] +>> endobj +2694 0 obj << +/Names [(table.14) 2321 0 R (table.2) 1472 0 R (table.3) 1478 0 R (table.4) 1481 0 R (table.5) 1487 0 R (table.6) 1985 0 R] +/Limits [(table.14) (table.6)] +>> endobj +2695 0 obj << +/Names [(table.7) 1989 0 R (table.8) 1994 0 R (table.9) 1995 0 R] +/Limits [(table.7) (table.9)] +>> endobj +2696 0 obj << +/Kids [2545 0 R 2546 0 R 2547 0 R 2548 0 R 2549 0 R 2550 0 R] +/Limits [(Doc-Start) (lstlisting.-127)] +>> endobj +2697 0 obj << +/Kids [2551 0 R 2552 0 R 2553 0 R 2554 0 R 2555 0 R 2556 0 R] +/Limits [(lstlisting.-128) (lstlisting.-23)] +>> endobj +2698 0 obj << +/Kids [2557 0 R 2558 0 R 2559 0 R 2560 0 R 2561 0 R 2562 0 R] +/Limits [(lstlisting.-24) (lstlisting.-56)] +>> endobj +2699 0 obj << +/Kids [2563 0 R 2564 0 R 2565 0 R 2566 0 R 2567 0 R 2568 0 R] +/Limits [(lstlisting.-57) (lstlisting.-89)] +>> endobj +2700 0 obj << +/Kids [2569 0 R 2570 0 R 2571 0 R 2572 0 R 2573 0 R 2574 0 R] +/Limits [(lstlisting.-9) (lstnumber.-116.2)] +>> endobj +2701 0 obj << +/Kids [2575 0 R 2576 0 R 2577 0 R 2578 0 R 2579 0 R 2580 0 R] +/Limits [(lstnumber.-116.3) (lstnumber.-122.7)] +>> endobj +2702 0 obj << +/Kids [2581 0 R 2582 0 R 2583 0 R 2584 0 R 2585 0 R 2586 0 R] +/Limits [(lstnumber.-123.1) (lstnumber.-128.3)] +>> endobj +2703 0 obj << +/Kids [2587 0 R 2588 0 R 2589 0 R 2590 0 R 2591 0 R 2592 0 R] +/Limits [(lstnumber.-128.4) (lstnumber.-131.18)] +>> endobj +2704 0 obj << +/Kids [2593 0 R 2594 0 R 2595 0 R 2596 0 R 2597 0 R 2598 0 R] +/Limits [(lstnumber.-131.2) (lstnumber.-134.7)] +>> endobj +2705 0 obj << +/Kids [2599 0 R 2600 0 R 2601 0 R 2602 0 R 2603 0 R 2604 0 R] +/Limits [(lstnumber.-134.8) (lstnumber.-17.1)] +>> endobj +2706 0 obj << +/Kids [2605 0 R 2606 0 R 2607 0 R 2608 0 R 2609 0 R 2610 0 R] +/Limits [(lstnumber.-17.2) (lstnumber.-32.1)] +>> endobj +2707 0 obj << +/Kids [2611 0 R 2612 0 R 2613 0 R 2614 0 R 2615 0 R 2616 0 R] +/Limits [(lstnumber.-33.1) (lstnumber.-61.1)] +>> endobj +2708 0 obj << +/Kids [2617 0 R 2618 0 R 2619 0 R 2620 0 R 2621 0 R 2622 0 R] +/Limits [(lstnumber.-62.1) (lstnumber.-84.1)] +>> endobj +2709 0 obj << +/Kids [2623 0 R 2624 0 R 2625 0 R 2626 0 R 2627 0 R 2628 0 R] +/Limits [(lstnumber.-85.1) (page.11)] +>> endobj +2710 0 obj << +/Kids [2629 0 R 2630 0 R 2631 0 R 2632 0 R 2633 0 R 2634 0 R] +/Limits [(page.110) (page.36)] +>> endobj +2711 0 obj << +/Kids [2635 0 R 2636 0 R 2637 0 R 2638 0 R 2639 0 R 2640 0 R] +/Limits [(page.37) (page.69)] +>> endobj +2712 0 obj << +/Kids [2641 0 R 2642 0 R 2643 0 R 2644 0 R 2645 0 R 2646 0 R] +/Limits [(page.7) (paragraph.10.1.1.3)] +>> endobj +2713 0 obj << +/Kids [2647 0 R 2648 0 R 2649 0 R 2650 0 R 2651 0 R 2652 0 R] +/Limits [(paragraph.10.1.1.4) (paragraph.10.1.3.4)] +>> endobj +2714 0 obj << +/Kids [2653 0 R 2654 0 R 2655 0 R 2656 0 R 2657 0 R 2658 0 R] +/Limits [(paragraph.10.1.3.5) (paragraph.10.1.4.37)] +>> endobj +2715 0 obj << +/Kids [2659 0 R 2660 0 R 2661 0 R 2662 0 R 2663 0 R 2664 0 R] +/Limits [(paragraph.10.1.4.38) (paragraph.10.1.7.14)] +>> endobj +2716 0 obj << +/Kids [2665 0 R 2666 0 R 2667 0 R 2668 0 R 2669 0 R 2670 0 R] +/Limits [(paragraph.10.1.7.15) (paragraph.10.1.9.2)] +>> endobj +2717 0 obj << +/Kids [2671 0 R 2672 0 R 2673 0 R 2674 0 R 2675 0 R 2676 0 R] +/Limits [(paragraph.10.1.9.3) (paragraph.10.2.3.2)] +>> endobj +2718 0 obj << +/Kids [2677 0 R 2678 0 R 2679 0 R 2680 0 R 2681 0 R 2682 0 R] +/Limits [(paragraph.10.2.3.3) (subsubsection.10.1.10)] +>> endobj +2719 0 obj << +/Kids [2683 0 R 2684 0 R 2685 0 R 2686 0 R 2687 0 R 2688 0 R] +/Limits [(subsubsection.10.1.11) (subsubsection.10.4.15)] +>> endobj +2720 0 obj << +/Kids [2689 0 R 2690 0 R 2691 0 R 2692 0 R 2693 0 R 2694 0 R] +/Limits [(subsubsection.10.4.16) (table.6)] +>> endobj +2721 0 obj << +/Kids [2695 0 R] +/Limits [(table.7) (table.9)] +>> endobj +2722 0 obj << +/Kids [2696 0 R 2697 0 R 2698 0 R 2699 0 R 2700 0 R 2701 0 R] +/Limits [(Doc-Start) (lstnumber.-122.7)] +>> endobj +2723 0 obj << +/Kids [2702 0 R 2703 0 R 2704 0 R 2705 0 R 2706 0 R 2707 0 R] +/Limits [(lstnumber.-123.1) (lstnumber.-61.1)] +>> endobj +2724 0 obj << +/Kids [2708 0 R 2709 0 R 2710 0 R 2711 0 R 2712 0 R 2713 0 R] +/Limits [(lstnumber.-62.1) (paragraph.10.1.3.4)] +>> endobj +2725 0 obj << +/Kids [2714 0 R 2715 0 R 2716 0 R 2717 0 R 2718 0 R 2719 0 R] +/Limits [(paragraph.10.1.3.5) (subsubsection.10.4.15)] +>> endobj +2726 0 obj << +/Kids [2720 0 R 2721 0 R] +/Limits [(subsubsection.10.4.16) (table.9)] +>> endobj +2727 0 obj << +/Kids [2722 0 R 2723 0 R 2724 0 R 2725 0 R 2726 0 R] +/Limits [(Doc-Start) (table.9)] +>> endobj +2728 0 obj << +/Dests 2727 0 R +>> endobj +2729 0 obj << +/Type /Catalog +/Pages 2543 0 R +/Outlines 2544 0 R +/Names 2728 0 R +/PageMode/None +/OpenAction 1101 0 R +>> endobj +2730 0 obj << +/Author(\251 2006-2008 Matthias Urban)/Title(Puma User's Manual)/Subject(Dokumentation)/Creator(LaTeX with package \253hyperref\273)/Producer(pdfTeX-0.1403)/Keywords(C, C++, Parser, Scanner, Lexer, Semantic, Syntax) +/CreationDate (D:20090311162923+01'00') +/ModDate (D:20090311162923+01'00') +/Trapped /False +/PTEX.Fullbanner (This is pdfTeX using libpoppler, Version 3.141592-1.40.3-2.2 (Web2C 7.5.6) kpathsea version 3.5.6) +>> endobj +xref +0 2731 +0000000001 65535 f +0000000002 00000 f +0000000003 00000 f +0000000004 00000 f +0000000000 00000 f +0000000015 00000 n +0000089240 00000 n +0000441476 00000 n +0000000060 00000 n +0000000085 00000 n +0000089300 00000 n +0000441417 00000 n +0000000135 00000 n +0000000165 00000 n +0000091240 00000 n +0000441292 00000 n +0000000211 00000 n +0000000244 00000 n +0000091302 00000 n +0000441218 00000 n +0000000295 00000 n +0000000330 00000 n +0000091492 00000 n +0000441107 00000 n +0000000381 00000 n +0000000424 00000 n +0000094769 00000 n +0000441046 00000 n +0000000480 00000 n +0000000524 00000 n +0000096547 00000 n +0000440920 00000 n +0000000570 00000 n +0000000608 00000 n +0000096608 00000 n +0000440846 00000 n +0000000659 00000 n +0000000696 00000 n +0000096921 00000 n +0000440759 00000 n +0000000747 00000 n +0000000791 00000 n +0000097108 00000 n +0000440648 00000 n +0000000842 00000 n +0000000886 00000 n +0000100796 00000 n +0000440587 00000 n +0000000942 00000 n +0000000985 00000 n +0000104263 00000 n +0000440498 00000 n +0000001031 00000 n +0000001065 00000 n +0000104924 00000 n +0000440409 00000 n +0000001111 00000 n +0000001144 00000 n +0000105603 00000 n +0000440320 00000 n +0000001190 00000 n +0000001227 00000 n +0000106269 00000 n +0000440231 00000 n +0000001273 00000 n +0000001312 00000 n +0000106951 00000 n +0000440142 00000 n +0000001358 00000 n +0000001396 00000 n +0000107622 00000 n +0000440053 00000 n +0000001442 00000 n +0000001482 00000 n +0000108840 00000 n +0000439923 00000 n +0000001529 00000 n +0000001560 00000 n +0000108901 00000 n +0000439809 00000 n +0000001612 00000 n +0000001661 00000 n +0000108962 00000 n +0000439696 00000 n +0000001718 00000 n +0000001763 00000 n +0000109023 00000 n +0000439622 00000 n +0000001818 00000 n +0000001856 00000 n +0000109084 00000 n +0000439535 00000 n +0000001911 00000 n +0000001948 00000 n +0000109145 00000 n +0000439448 00000 n +0000002003 00000 n +0000002041 00000 n +0000109206 00000 n +0000439359 00000 n +0000002096 00000 n +0000002134 00000 n +0000110354 00000 n +0000439268 00000 n +0000002190 00000 n +0000002228 00000 n +0000110417 00000 n +0000439176 00000 n +0000002284 00000 n +0000002324 00000 n +0000110480 00000 n +0000439098 00000 n +0000002380 00000 n +0000002421 00000 n +0000112794 00000 n +0000438968 00000 n +0000002479 00000 n +0000002524 00000 n +0000112856 00000 n +0000438889 00000 n +0000002580 00000 n +0000002614 00000 n +0000114132 00000 n +0000438796 00000 n +0000002670 00000 n +0000002710 00000 n +0000114195 00000 n +0000438703 00000 n +0000002766 00000 n +0000002805 00000 n +0000114258 00000 n +0000438610 00000 n +0000002861 00000 n +0000002901 00000 n +0000114321 00000 n +0000438531 00000 n +0000002957 00000 n +0000002999 00000 n +0000115598 00000 n +0000438399 00000 n +0000003057 00000 n +0000003094 00000 n +0000115660 00000 n +0000438320 00000 n +0000003150 00000 n +0000003194 00000 n +0000115722 00000 n +0000438227 00000 n +0000003250 00000 n +0000003293 00000 n +0000115784 00000 n +0000438134 00000 n +0000003349 00000 n +0000003393 00000 n +0000115972 00000 n +0000438041 00000 n +0000003449 00000 n +0000003490 00000 n +0000117587 00000 n +0000437948 00000 n +0000003546 00000 n +0000003591 00000 n +0000118033 00000 n +0000437855 00000 n +0000003647 00000 n +0000003692 00000 n +0000118352 00000 n +0000437762 00000 n +0000003748 00000 n +0000003792 00000 n +0000119724 00000 n +0000437669 00000 n +0000003848 00000 n +0000003891 00000 n +0000119912 00000 n +0000437576 00000 n +0000003947 00000 n +0000003991 00000 n +0000120225 00000 n +0000437483 00000 n +0000004048 00000 n +0000004090 00000 n +0000121718 00000 n +0000437390 00000 n +0000004147 00000 n +0000004190 00000 n +0000122037 00000 n +0000437297 00000 n +0000004247 00000 n +0000004295 00000 n +0000122228 00000 n +0000437204 00000 n +0000004352 00000 n +0000004398 00000 n +0000123569 00000 n +0000437111 00000 n +0000004455 00000 n +0000004499 00000 n +0000123757 00000 n +0000437018 00000 n +0000004556 00000 n +0000004600 00000 n +0000123945 00000 n +0000436925 00000 n +0000004657 00000 n +0000004701 00000 n +0000124133 00000 n +0000436832 00000 n +0000004758 00000 n +0000004805 00000 n +0000125348 00000 n +0000436753 00000 n +0000004862 00000 n +0000004905 00000 n +0000127072 00000 n +0000436621 00000 n +0000004963 00000 n +0000005001 00000 n +0000127134 00000 n +0000436542 00000 n +0000005057 00000 n +0000005102 00000 n +0000127196 00000 n +0000436449 00000 n +0000005158 00000 n +0000005201 00000 n +0000127258 00000 n +0000436356 00000 n +0000005257 00000 n +0000005296 00000 n +0000127320 00000 n +0000436263 00000 n +0000005352 00000 n +0000005395 00000 n +0000129011 00000 n +0000436170 00000 n +0000005451 00000 n +0000005498 00000 n +0000129776 00000 n +0000436077 00000 n +0000005554 00000 n +0000005598 00000 n +0000129967 00000 n +0000435984 00000 n +0000005654 00000 n +0000005696 00000 n +0000131382 00000 n +0000435891 00000 n +0000005752 00000 n +0000005797 00000 n +0000131570 00000 n +0000435798 00000 n +0000005853 00000 n +0000005901 00000 n +0000131757 00000 n +0000435705 00000 n +0000005958 00000 n +0000006001 00000 n +0000131945 00000 n +0000435612 00000 n +0000006058 00000 n +0000006103 00000 n +0000133289 00000 n +0000435519 00000 n +0000006160 00000 n +0000006209 00000 n +0000133479 00000 n +0000435426 00000 n +0000006266 00000 n +0000006308 00000 n +0000133670 00000 n +0000435333 00000 n +0000006365 00000 n +0000006411 00000 n +0000133857 00000 n +0000435240 00000 n +0000006468 00000 n +0000006509 00000 n +0000135194 00000 n +0000435147 00000 n +0000006566 00000 n +0000006606 00000 n +0000135443 00000 n +0000435054 00000 n +0000006663 00000 n +0000006709 00000 n +0000135630 00000 n +0000434961 00000 n +0000006766 00000 n +0000006812 00000 n +0000135818 00000 n +0000434868 00000 n +0000006869 00000 n +0000006916 00000 n +0000137160 00000 n +0000434775 00000 n +0000006973 00000 n +0000007020 00000 n +0000137350 00000 n +0000434682 00000 n +0000007077 00000 n +0000007122 00000 n +0000137541 00000 n +0000434589 00000 n +0000007179 00000 n +0000007226 00000 n +0000137728 00000 n +0000434496 00000 n +0000007283 00000 n +0000007327 00000 n +0000139259 00000 n +0000434403 00000 n +0000007384 00000 n +0000007429 00000 n +0000139447 00000 n +0000434310 00000 n +0000007486 00000 n +0000007532 00000 n +0000139697 00000 n +0000434217 00000 n +0000007589 00000 n +0000007636 00000 n +0000139885 00000 n +0000434124 00000 n +0000007693 00000 n +0000007738 00000 n +0000141255 00000 n +0000434031 00000 n +0000007795 00000 n +0000007839 00000 n +0000141445 00000 n +0000433938 00000 n +0000007896 00000 n +0000007942 00000 n +0000141636 00000 n +0000433845 00000 n +0000007999 00000 n +0000008044 00000 n +0000141823 00000 n +0000433752 00000 n +0000008101 00000 n +0000008146 00000 n +0000143192 00000 n +0000433659 00000 n +0000008203 00000 n +0000008250 00000 n +0000143379 00000 n +0000433566 00000 n +0000008307 00000 n +0000008353 00000 n +0000143567 00000 n +0000433473 00000 n +0000008410 00000 n +0000008456 00000 n +0000143751 00000 n +0000433380 00000 n +0000008513 00000 n +0000008561 00000 n +0000145148 00000 n +0000433287 00000 n +0000008618 00000 n +0000008666 00000 n +0000145339 00000 n +0000433194 00000 n +0000008723 00000 n +0000008773 00000 n +0000145530 00000 n +0000433101 00000 n +0000008830 00000 n +0000008881 00000 n +0000145721 00000 n +0000433022 00000 n +0000008938 00000 n +0000008987 00000 n +0000147226 00000 n +0000432890 00000 n +0000009045 00000 n +0000009094 00000 n +0000147288 00000 n +0000432811 00000 n +0000009150 00000 n +0000009193 00000 n +0000147349 00000 n +0000432718 00000 n +0000009249 00000 n +0000009295 00000 n +0000147411 00000 n +0000432625 00000 n +0000009351 00000 n +0000009398 00000 n +0000147788 00000 n +0000432532 00000 n +0000009454 00000 n +0000009498 00000 n +0000149160 00000 n +0000432439 00000 n +0000009554 00000 n +0000009598 00000 n +0000149351 00000 n +0000432346 00000 n +0000009654 00000 n +0000009698 00000 n +0000149542 00000 n +0000432253 00000 n +0000009754 00000 n +0000009797 00000 n +0000149733 00000 n +0000432160 00000 n +0000009853 00000 n +0000009901 00000 n +0000151014 00000 n +0000432067 00000 n +0000009957 00000 n +0000010000 00000 n +0000151201 00000 n +0000431974 00000 n +0000010057 00000 n +0000010105 00000 n +0000151388 00000 n +0000431895 00000 n +0000010162 00000 n +0000010208 00000 n +0000152783 00000 n +0000431763 00000 n +0000010266 00000 n +0000010304 00000 n +0000152846 00000 n +0000431684 00000 n +0000010360 00000 n +0000010405 00000 n +0000152907 00000 n +0000431591 00000 n +0000010461 00000 n +0000010510 00000 n +0000152970 00000 n +0000431498 00000 n +0000010566 00000 n +0000010615 00000 n +0000153161 00000 n +0000431405 00000 n +0000010671 00000 n +0000010722 00000 n +0000154584 00000 n +0000431312 00000 n +0000010778 00000 n +0000010828 00000 n +0000154772 00000 n +0000431219 00000 n +0000010884 00000 n +0000010933 00000 n +0000155023 00000 n +0000431126 00000 n +0000010989 00000 n +0000011037 00000 n +0000155211 00000 n +0000431033 00000 n +0000011093 00000 n +0000011141 00000 n +0000156519 00000 n +0000430940 00000 n +0000011197 00000 n +0000011245 00000 n +0000156709 00000 n +0000430847 00000 n +0000011302 00000 n +0000011355 00000 n +0000156899 00000 n +0000430768 00000 n +0000011412 00000 n +0000011466 00000 n +0000158301 00000 n +0000430636 00000 n +0000011524 00000 n +0000011563 00000 n +0000158363 00000 n +0000430557 00000 n +0000011619 00000 n +0000011658 00000 n +0000158425 00000 n +0000430464 00000 n +0000011714 00000 n +0000011757 00000 n +0000158486 00000 n +0000430371 00000 n +0000011813 00000 n +0000011856 00000 n +0000158548 00000 n +0000430278 00000 n +0000011912 00000 n +0000011954 00000 n +0000158736 00000 n +0000430185 00000 n +0000012010 00000 n +0000012052 00000 n +0000160060 00000 n +0000430092 00000 n +0000012108 00000 n +0000012154 00000 n +0000160123 00000 n +0000429999 00000 n +0000012210 00000 n +0000012256 00000 n +0000160186 00000 n +0000429906 00000 n +0000012312 00000 n +0000012357 00000 n +0000160248 00000 n +0000429813 00000 n +0000012413 00000 n +0000012458 00000 n +0000160439 00000 n +0000429720 00000 n +0000012515 00000 n +0000012560 00000 n +0000161940 00000 n +0000429627 00000 n +0000012617 00000 n +0000012659 00000 n +0000162126 00000 n +0000429534 00000 n +0000012716 00000 n +0000012759 00000 n +0000162313 00000 n +0000429441 00000 n +0000012816 00000 n +0000012860 00000 n +0000162501 00000 n +0000429348 00000 n +0000012917 00000 n +0000012961 00000 n +0000163870 00000 n +0000429255 00000 n +0000013018 00000 n +0000013064 00000 n +0000163933 00000 n +0000429162 00000 n +0000013121 00000 n +0000013171 00000 n +0000163996 00000 n +0000429069 00000 n +0000013228 00000 n +0000013275 00000 n +0000164058 00000 n +0000428976 00000 n +0000013332 00000 n +0000013375 00000 n +0000164121 00000 n +0000428883 00000 n +0000013432 00000 n +0000013480 00000 n +0000165347 00000 n +0000428790 00000 n +0000013537 00000 n +0000013590 00000 n +0000165409 00000 n +0000428697 00000 n +0000013647 00000 n +0000013696 00000 n +0000165471 00000 n +0000428604 00000 n +0000013753 00000 n +0000013805 00000 n +0000165532 00000 n +0000428511 00000 n +0000013862 00000 n +0000013915 00000 n +0000165594 00000 n +0000428418 00000 n +0000013972 00000 n +0000014023 00000 n +0000166925 00000 n +0000428325 00000 n +0000014080 00000 n +0000014128 00000 n +0000167115 00000 n +0000428232 00000 n +0000014185 00000 n +0000014238 00000 n +0000167306 00000 n +0000428139 00000 n +0000014295 00000 n +0000014345 00000 n +0000167496 00000 n +0000428046 00000 n +0000014402 00000 n +0000014447 00000 n +0000168944 00000 n +0000427953 00000 n +0000014504 00000 n +0000014546 00000 n +0000169258 00000 n +0000427860 00000 n +0000014603 00000 n +0000014651 00000 n +0000169445 00000 n +0000427781 00000 n +0000014708 00000 n +0000014754 00000 n +0000170987 00000 n +0000427650 00000 n +0000014812 00000 n +0000014844 00000 n +0000171050 00000 n +0000427571 00000 n +0000014900 00000 n +0000014945 00000 n +0000171240 00000 n +0000427478 00000 n +0000015001 00000 n +0000015047 00000 n +0000171303 00000 n +0000427385 00000 n +0000015103 00000 n +0000015149 00000 n +0000171558 00000 n +0000427292 00000 n +0000015205 00000 n +0000015252 00000 n +0000172921 00000 n +0000427199 00000 n +0000015308 00000 n +0000015357 00000 n +0000173108 00000 n +0000427106 00000 n +0000015413 00000 n +0000015462 00000 n +0000173296 00000 n +0000427013 00000 n +0000015518 00000 n +0000015565 00000 n +0000173480 00000 n +0000426920 00000 n +0000015621 00000 n +0000015664 00000 n +0000174597 00000 n +0000426841 00000 n +0000015720 00000 n +0000015767 00000 n +0000175773 00000 n +0000426710 00000 n +0000015825 00000 n +0000015861 00000 n +0000175835 00000 n +0000426631 00000 n +0000015917 00000 n +0000015955 00000 n +0000175897 00000 n +0000426538 00000 n +0000016011 00000 n +0000016053 00000 n +0000175959 00000 n +0000426445 00000 n +0000016109 00000 n +0000016156 00000 n +0000176021 00000 n +0000426366 00000 n +0000016212 00000 n +0000016259 00000 n +0000177232 00000 n +0000426235 00000 n +0000016318 00000 n +0000016355 00000 n +0000177295 00000 n +0000426156 00000 n +0000016412 00000 n +0000016458 00000 n +0000177614 00000 n +0000426063 00000 n +0000016515 00000 n +0000016560 00000 n +0000177805 00000 n +0000425970 00000 n +0000016617 00000 n +0000016665 00000 n +0000179214 00000 n +0000425877 00000 n +0000016722 00000 n +0000016763 00000 n +0000179402 00000 n +0000425784 00000 n +0000016820 00000 n +0000016870 00000 n +0000179716 00000 n +0000425705 00000 n +0000016927 00000 n +0000016971 00000 n +0000180849 00000 n +0000425574 00000 n +0000017030 00000 n +0000017067 00000 n +0000180912 00000 n +0000425509 00000 n +0000017124 00000 n +0000017168 00000 n +0000182286 00000 n +0000425392 00000 n +0000017227 00000 n +0000017264 00000 n +0000182348 00000 n +0000425313 00000 n +0000017321 00000 n +0000017367 00000 n +0000182536 00000 n +0000425220 00000 n +0000017424 00000 n +0000017469 00000 n +0000182724 00000 n +0000425127 00000 n +0000017526 00000 n +0000017575 00000 n +0000184238 00000 n +0000425034 00000 n +0000017632 00000 n +0000017682 00000 n +0000184428 00000 n +0000424941 00000 n +0000017739 00000 n +0000017789 00000 n +0000184619 00000 n +0000424848 00000 n +0000017846 00000 n +0000017898 00000 n +0000184809 00000 n +0000424769 00000 n +0000017955 00000 n +0000018000 00000 n +0000186928 00000 n +0000424639 00000 n +0000018053 00000 n +0000018099 00000 n +0000186990 00000 n +0000424521 00000 n +0000018157 00000 n +0000018206 00000 n +0000187052 00000 n +0000424442 00000 n +0000018262 00000 n +0000018302 00000 n +0000189548 00000 n +0000424349 00000 n +0000018358 00000 n +0000018396 00000 n +0000189867 00000 n +0000424256 00000 n +0000018452 00000 n +0000018492 00000 n +0000191653 00000 n +0000424163 00000 n +0000018548 00000 n +0000018585 00000 n +0000191777 00000 n +0000424070 00000 n +0000018641 00000 n +0000018681 00000 n +0000193018 00000 n +0000423991 00000 n +0000018737 00000 n +0000018774 00000 n +0000194550 00000 n +0000423858 00000 n +0000018832 00000 n +0000018864 00000 n +0000194612 00000 n +0000423779 00000 n +0000018920 00000 n +0000018958 00000 n +0000194674 00000 n +0000423686 00000 n +0000019014 00000 n +0000019058 00000 n +0000194736 00000 n +0000423593 00000 n +0000019114 00000 n +0000019153 00000 n +0000196396 00000 n +0000423500 00000 n +0000019209 00000 n +0000019248 00000 n +0000196459 00000 n +0000423407 00000 n +0000019304 00000 n +0000019347 00000 n +0000196522 00000 n +0000423314 00000 n +0000019403 00000 n +0000019443 00000 n +0000196585 00000 n +0000423221 00000 n +0000019499 00000 n +0000019535 00000 n +0000196648 00000 n +0000423128 00000 n +0000019591 00000 n +0000019633 00000 n +0000198528 00000 n +0000423035 00000 n +0000019689 00000 n +0000019735 00000 n +0000199534 00000 n +0000422942 00000 n +0000019792 00000 n +0000019834 00000 n +0000200963 00000 n +0000422849 00000 n +0000019891 00000 n +0000019934 00000 n +0000201026 00000 n +0000422756 00000 n +0000019991 00000 n +0000020034 00000 n +0000201089 00000 n +0000422663 00000 n +0000020091 00000 n +0000020131 00000 n +0000201151 00000 n +0000422570 00000 n +0000020188 00000 n +0000020232 00000 n +0000201214 00000 n +0000422477 00000 n +0000020289 00000 n +0000020329 00000 n +0000202528 00000 n +0000422384 00000 n +0000020386 00000 n +0000020428 00000 n +0000202590 00000 n +0000422291 00000 n +0000020485 00000 n +0000020529 00000 n +0000202652 00000 n +0000422198 00000 n +0000020586 00000 n +0000020630 00000 n +0000202714 00000 n +0000422105 00000 n +0000020687 00000 n +0000020726 00000 n +0000202776 00000 n +0000422012 00000 n +0000020783 00000 n +0000020826 00000 n +0000204564 00000 n +0000421919 00000 n +0000020883 00000 n +0000020929 00000 n +0000204627 00000 n +0000421826 00000 n +0000020986 00000 n +0000021026 00000 n +0000204690 00000 n +0000421733 00000 n +0000021083 00000 n +0000021131 00000 n +0000205264 00000 n +0000421640 00000 n +0000021188 00000 n +0000021232 00000 n +0000206670 00000 n +0000421547 00000 n +0000021289 00000 n +0000021329 00000 n +0000206732 00000 n +0000421468 00000 n +0000021386 00000 n +0000021427 00000 n +0000208389 00000 n +0000421350 00000 n +0000021485 00000 n +0000021521 00000 n +0000208452 00000 n +0000421271 00000 n +0000021577 00000 n +0000021618 00000 n +0000208514 00000 n +0000421178 00000 n +0000021674 00000 n +0000021715 00000 n +0000208577 00000 n +0000421085 00000 n +0000021771 00000 n +0000021811 00000 n +0000208640 00000 n +0000420992 00000 n +0000021867 00000 n +0000021914 00000 n +0000208703 00000 n +0000420913 00000 n +0000021970 00000 n +0000022013 00000 n +0000210186 00000 n +0000420781 00000 n +0000022066 00000 n +0000022115 00000 n +0000210248 00000 n +0000420702 00000 n +0000022173 00000 n +0000022209 00000 n +0000211128 00000 n +0000420609 00000 n +0000022267 00000 n +0000022303 00000 n +0000211190 00000 n +0000420516 00000 n +0000022361 00000 n +0000022400 00000 n +0000213465 00000 n +0000420423 00000 n +0000022458 00000 n +0000022498 00000 n +0000213847 00000 n +0000420330 00000 n +0000022556 00000 n +0000022593 00000 n +0000215424 00000 n +0000420237 00000 n +0000022651 00000 n +0000022687 00000 n +0000215863 00000 n +0000420144 00000 n +0000022745 00000 n +0000022785 00000 n +0000216428 00000 n +0000420051 00000 n +0000022843 00000 n +0000022884 00000 n +0000218890 00000 n +0000419958 00000 n +0000022942 00000 n +0000022987 00000 n +0000221511 00000 n +0000419865 00000 n +0000023046 00000 n +0000023087 00000 n +0000222011 00000 n +0000419772 00000 n +0000023146 00000 n +0000023186 00000 n +0000224213 00000 n +0000419679 00000 n +0000023245 00000 n +0000023284 00000 n +0000224276 00000 n +0000419586 00000 n +0000023343 00000 n +0000023381 00000 n +0000225170 00000 n +0000419493 00000 n +0000023440 00000 n +0000023482 00000 n +0000226582 00000 n +0000419400 00000 n +0000023541 00000 n +0000023579 00000 n +0000227918 00000 n +0000419321 00000 n +0000023638 00000 n +0000023684 00000 n +0000229151 00000 n +0000419187 00000 n +0000023737 00000 n +0000023794 00000 n +0000229213 00000 n +0000419108 00000 n +0000023852 00000 n +0000023886 00000 n +0000229275 00000 n +0000419015 00000 n +0000023944 00000 n +0000023987 00000 n +0000229337 00000 n +0000418922 00000 n +0000024045 00000 n +0000024082 00000 n +0000229399 00000 n +0000418829 00000 n +0000024140 00000 n +0000024185 00000 n +0000229461 00000 n +0000418736 00000 n +0000024243 00000 n +0000024289 00000 n +0000231299 00000 n +0000418643 00000 n +0000024347 00000 n +0000024385 00000 n +0000231362 00000 n +0000418550 00000 n +0000024443 00000 n +0000024481 00000 n +0000231425 00000 n +0000418457 00000 n +0000024539 00000 n +0000024580 00000 n +0000232718 00000 n +0000418364 00000 n +0000024638 00000 n +0000024682 00000 n +0000232906 00000 n +0000418269 00000 n +0000024741 00000 n +0000024788 00000 n +0000233094 00000 n +0000418172 00000 n +0000024848 00000 n +0000024893 00000 n +0000234427 00000 n +0000418074 00000 n +0000024953 00000 n +0000024998 00000 n +0000234619 00000 n +0000417976 00000 n +0000025058 00000 n +0000025104 00000 n +0000234811 00000 n +0000417878 00000 n +0000025164 00000 n +0000025212 00000 n +0000236296 00000 n +0000417780 00000 n +0000025272 00000 n +0000025319 00000 n +0000236485 00000 n +0000417682 00000 n +0000025379 00000 n +0000025428 00000 n +0000236674 00000 n +0000417584 00000 n +0000025488 00000 n +0000025543 00000 n +0000238099 00000 n +0000417486 00000 n +0000025603 00000 n +0000025658 00000 n +0000238291 00000 n +0000417388 00000 n +0000025718 00000 n +0000025764 00000 n +0000238483 00000 n +0000417290 00000 n +0000025824 00000 n +0000025872 00000 n +0000239957 00000 n +0000417192 00000 n +0000025932 00000 n +0000025978 00000 n +0000240145 00000 n +0000417094 00000 n +0000026038 00000 n +0000026084 00000 n +0000240334 00000 n +0000416996 00000 n +0000026144 00000 n +0000026185 00000 n +0000240397 00000 n +0000416898 00000 n +0000026245 00000 n +0000026290 00000 n +0000241447 00000 n +0000416800 00000 n +0000026350 00000 n +0000026393 00000 n +0000241511 00000 n +0000416702 00000 n +0000026453 00000 n +0000026496 00000 n +0000241575 00000 n +0000416619 00000 n +0000026556 00000 n +0000026593 00000 n +0000242848 00000 n +0000416482 00000 n +0000026647 00000 n +0000026679 00000 n +0000242911 00000 n +0000416398 00000 n +0000026738 00000 n +0000026778 00000 n +0000249085 00000 n +0000416299 00000 n +0000026837 00000 n +0000026884 00000 n +0000249213 00000 n +0000416215 00000 n +0000026943 00000 n +0000027001 00000 n +0000252635 00000 n +0000416118 00000 n +0000027055 00000 n +0000027090 00000 n +0000286702 00000 n +0000416021 00000 n +0000027144 00000 n +0000027181 00000 n +0000287395 00000 n +0000415939 00000 n +0000027235 00000 n +0000027281 00000 n +0000290121 00000 n +0000415857 00000 n +0000027330 00000 n +0000027356 00000 n +0000027712 00000 n +0000027961 00000 n +0000027410 00000 n +0000027835 00000 n +0000027898 00000 n +0000412015 00000 n +0000412369 00000 n +0000412192 00000 n +0000412737 00000 n +0000029248 00000 n +0000029401 00000 n +0000029559 00000 n +0000029712 00000 n +0000029869 00000 n +0000030027 00000 n +0000030190 00000 n +0000030343 00000 n +0000030501 00000 n +0000030658 00000 n +0000030816 00000 n +0000030979 00000 n +0000031131 00000 n +0000031283 00000 n +0000031436 00000 n +0000031589 00000 n +0000031742 00000 n +0000031895 00000 n +0000032048 00000 n +0000032207 00000 n +0000033814 00000 n +0000033976 00000 n +0000034138 00000 n +0000032499 00000 n +0000028933 00000 n +0000028063 00000 n +0000032371 00000 n +0000412550 00000 n +0000032435 00000 n +0000034299 00000 n +0000034461 00000 n +0000034622 00000 n +0000034784 00000 n +0000034946 00000 n +0000035110 00000 n +0000035272 00000 n +0000035433 00000 n +0000035591 00000 n +0000035753 00000 n +0000035914 00000 n +0000036078 00000 n +0000036240 00000 n +0000036402 00000 n +0000036564 00000 n +0000036725 00000 n +0000036886 00000 n +0000037048 00000 n +0000037210 00000 n +0000037372 00000 n +0000037533 00000 n +0000037696 00000 n +0000037858 00000 n +0000038020 00000 n +0000039539 00000 n +0000039702 00000 n +0000039864 00000 n +0000038246 00000 n +0000033436 00000 n +0000032601 00000 n +0000038183 00000 n +0000040026 00000 n +0000040189 00000 n +0000040350 00000 n +0000040514 00000 n +0000040676 00000 n +0000040838 00000 n +0000041000 00000 n +0000041160 00000 n +0000041322 00000 n +0000041484 00000 n +0000041645 00000 n +0000041807 00000 n +0000041969 00000 n +0000042132 00000 n +0000042294 00000 n +0000042456 00000 n +0000042618 00000 n +0000042780 00000 n +0000042942 00000 n +0000043105 00000 n +0000043268 00000 n +0000043431 00000 n +0000043594 00000 n +0000043756 00000 n +0000045289 00000 n +0000045452 00000 n +0000045615 00000 n +0000043983 00000 n +0000039161 00000 n +0000038334 00000 n +0000043919 00000 n +0000045777 00000 n +0000045940 00000 n +0000046102 00000 n +0000046265 00000 n +0000046428 00000 n +0000046591 00000 n +0000046754 00000 n +0000046915 00000 n +0000047078 00000 n +0000047241 00000 n +0000047403 00000 n +0000047566 00000 n +0000047729 00000 n +0000047892 00000 n +0000048055 00000 n +0000048218 00000 n +0000048381 00000 n +0000048542 00000 n +0000048704 00000 n +0000048866 00000 n +0000049028 00000 n +0000049190 00000 n +0000049352 00000 n +0000049513 00000 n +0000050984 00000 n +0000051146 00000 n +0000051309 00000 n +0000049738 00000 n +0000044911 00000 n +0000044071 00000 n +0000049675 00000 n +0000051471 00000 n +0000051635 00000 n +0000051797 00000 n +0000051959 00000 n +0000052121 00000 n +0000052283 00000 n +0000052444 00000 n +0000052605 00000 n +0000052763 00000 n +0000052925 00000 n +0000053087 00000 n +0000053250 00000 n +0000053413 00000 n +0000053577 00000 n +0000053739 00000 n +0000053900 00000 n +0000054061 00000 n +0000054222 00000 n +0000054384 00000 n +0000054546 00000 n +0000054708 00000 n +0000054870 00000 n +0000055031 00000 n +0000055193 00000 n +0000056726 00000 n +0000056889 00000 n +0000057051 00000 n +0000055420 00000 n +0000050606 00000 n +0000049826 00000 n +0000055356 00000 n +0000057213 00000 n +0000057376 00000 n +0000057539 00000 n +0000057702 00000 n +0000057865 00000 n +0000058028 00000 n +0000058191 00000 n +0000058353 00000 n +0000058516 00000 n +0000058679 00000 n +0000058841 00000 n +0000059004 00000 n +0000059167 00000 n +0000059330 00000 n +0000059492 00000 n +0000059654 00000 n +0000059816 00000 n +0000059978 00000 n +0000060142 00000 n +0000060304 00000 n +0000060466 00000 n +0000060628 00000 n +0000060790 00000 n +0000060951 00000 n +0000062559 00000 n +0000062721 00000 n +0000062882 00000 n +0000061176 00000 n +0000056348 00000 n +0000055508 00000 n +0000061113 00000 n +0000412862 00000 n +0000063043 00000 n +0000063207 00000 n +0000063369 00000 n +0000063530 00000 n +0000063692 00000 n +0000063850 00000 n +0000064015 00000 n +0000064177 00000 n +0000064336 00000 n +0000064498 00000 n +0000064661 00000 n +0000064824 00000 n +0000064987 00000 n +0000065152 00000 n +0000065315 00000 n +0000065480 00000 n +0000065642 00000 n +0000065805 00000 n +0000065968 00000 n +0000066131 00000 n +0000066292 00000 n +0000066455 00000 n +0000066618 00000 n +0000066776 00000 n +0000068320 00000 n +0000068482 00000 n +0000068644 00000 n +0000067004 00000 n +0000062181 00000 n +0000061264 00000 n +0000066940 00000 n +0000068805 00000 n +0000068967 00000 n +0000069129 00000 n +0000069291 00000 n +0000069455 00000 n +0000069617 00000 n +0000069779 00000 n +0000069940 00000 n +0000070101 00000 n +0000070263 00000 n +0000070425 00000 n +0000070587 00000 n +0000070749 00000 n +0000070911 00000 n +0000071074 00000 n +0000071237 00000 n +0000071399 00000 n +0000071561 00000 n +0000071724 00000 n +0000071886 00000 n +0000072049 00000 n +0000072212 00000 n +0000072375 00000 n +0000072537 00000 n +0000074135 00000 n +0000074298 00000 n +0000074461 00000 n +0000072762 00000 n +0000067942 00000 n +0000067092 00000 n +0000072699 00000 n +0000074623 00000 n +0000074786 00000 n +0000074947 00000 n +0000075110 00000 n +0000075274 00000 n +0000075436 00000 n +0000075598 00000 n +0000075759 00000 n +0000075921 00000 n +0000076083 00000 n +0000076241 00000 n +0000076405 00000 n +0000076569 00000 n +0000076732 00000 n +0000076896 00000 n +0000077060 00000 n +0000077223 00000 n +0000077386 00000 n +0000077549 00000 n +0000077713 00000 n +0000077878 00000 n +0000078043 00000 n +0000078206 00000 n +0000078370 00000 n +0000079946 00000 n +0000080111 00000 n +0000080276 00000 n +0000078599 00000 n +0000073757 00000 n +0000072850 00000 n +0000078535 00000 n +0000080433 00000 n +0000080597 00000 n +0000080761 00000 n +0000080925 00000 n +0000081089 00000 n +0000081252 00000 n +0000081416 00000 n +0000081579 00000 n +0000081742 00000 n +0000081905 00000 n +0000082070 00000 n +0000082234 00000 n +0000082399 00000 n +0000082564 00000 n +0000082729 00000 n +0000082894 00000 n +0000083058 00000 n +0000083223 00000 n +0000083388 00000 n +0000083553 00000 n +0000083718 00000 n +0000083883 00000 n +0000084047 00000 n +0000084211 00000 n +0000085389 00000 n +0000085554 00000 n +0000085719 00000 n +0000084439 00000 n +0000079568 00000 n +0000078687 00000 n +0000084376 00000 n +0000085884 00000 n +0000086043 00000 n +0000086207 00000 n +0000086371 00000 n +0000086535 00000 n +0000086693 00000 n +0000086851 00000 n +0000087009 00000 n +0000087226 00000 n +0000085155 00000 n +0000084527 00000 n +0000087162 00000 n +0000091004 00000 n +0000089361 00000 n +0000089054 00000 n +0000087328 00000 n +0000089177 00000 n +0000411319 00000 n +0000412987 00000 n +0000091745 00000 n +0000090860 00000 n +0000089477 00000 n +0000091176 00000 n +0000091364 00000 n +0000091428 00000 n +0000411661 00000 n +0000091553 00000 n +0000411486 00000 n +0000091617 00000 n +0000091681 00000 n +0000093624 00000 n +0000093375 00000 n +0000091875 00000 n +0000093498 00000 n +0000093561 00000 n +0000094959 00000 n +0000094582 00000 n +0000093726 00000 n +0000094705 00000 n +0000094831 00000 n +0000094895 00000 n +0000097295 00000 n +0000096361 00000 n +0000095075 00000 n +0000096484 00000 n +0000096669 00000 n +0000096732 00000 n +0000096795 00000 n +0000096858 00000 n +0000096982 00000 n +0000097045 00000 n +0000097169 00000 n +0000097232 00000 n +0000099092 00000 n +0000098585 00000 n +0000097425 00000 n +0000098708 00000 n +0000098772 00000 n +0000098836 00000 n +0000098900 00000 n +0000098964 00000 n +0000099028 00000 n +0000101298 00000 n +0000100484 00000 n +0000099208 00000 n +0000100607 00000 n +0000100670 00000 n +0000100733 00000 n +0000100857 00000 n +0000100920 00000 n +0000100983 00000 n +0000101046 00000 n +0000101109 00000 n +0000101172 00000 n +0000411836 00000 n +0000101235 00000 n +0000413112 00000 n +0000103613 00000 n +0000102531 00000 n +0000101428 00000 n +0000102654 00000 n +0000102718 00000 n +0000102782 00000 n +0000102846 00000 n +0000102910 00000 n +0000102974 00000 n +0000103038 00000 n +0000103102 00000 n +0000103166 00000 n +0000103230 00000 n +0000103294 00000 n +0000103358 00000 n +0000103421 00000 n +0000103485 00000 n +0000103549 00000 n +0000104324 00000 n +0000104077 00000 n +0000103743 00000 n +0000104200 00000 n +0000104986 00000 n +0000104737 00000 n +0000104426 00000 n +0000104860 00000 n +0000105664 00000 n +0000105417 00000 n +0000105074 00000 n +0000105540 00000 n +0000106331 00000 n +0000106082 00000 n +0000105766 00000 n +0000106205 00000 n +0000107012 00000 n +0000106765 00000 n +0000106419 00000 n +0000106888 00000 n +0000413237 00000 n +0000107684 00000 n +0000107435 00000 n +0000107114 00000 n +0000107558 00000 n +0000109267 00000 n +0000108654 00000 n +0000107772 00000 n +0000108777 00000 n +0000110543 00000 n +0000110167 00000 n +0000109397 00000 n +0000110290 00000 n +0000113044 00000 n +0000112608 00000 n +0000110673 00000 n +0000112731 00000 n +0000112918 00000 n +0000112981 00000 n +0000114384 00000 n +0000113945 00000 n +0000113188 00000 n +0000114068 00000 n +0000116285 00000 n +0000115412 00000 n +0000114514 00000 n +0000115535 00000 n +0000115846 00000 n +0000115909 00000 n +0000116034 00000 n +0000116097 00000 n +0000116159 00000 n +0000116222 00000 n +0000413362 00000 n +0000118543 00000 n +0000117400 00000 n +0000116429 00000 n +0000117523 00000 n +0000117650 00000 n +0000117714 00000 n +0000117777 00000 n +0000117841 00000 n +0000117905 00000 n +0000117969 00000 n +0000118096 00000 n +0000118160 00000 n +0000118224 00000 n +0000118288 00000 n +0000118415 00000 n +0000118479 00000 n +0000120538 00000 n +0000119538 00000 n +0000118687 00000 n +0000119661 00000 n +0000119786 00000 n +0000119849 00000 n +0000119974 00000 n +0000120036 00000 n +0000120099 00000 n +0000120162 00000 n +0000120286 00000 n +0000120349 00000 n +0000120412 00000 n +0000120475 00000 n +0000122419 00000 n +0000121531 00000 n +0000120682 00000 n +0000121654 00000 n +0000121781 00000 n +0000121845 00000 n +0000121909 00000 n +0000121973 00000 n +0000122100 00000 n +0000122164 00000 n +0000122291 00000 n +0000122355 00000 n +0000124320 00000 n +0000123383 00000 n +0000122563 00000 n +0000123506 00000 n +0000123631 00000 n +0000123694 00000 n +0000123819 00000 n +0000123882 00000 n +0000124007 00000 n +0000124070 00000 n +0000124195 00000 n +0000124257 00000 n +0000125794 00000 n +0000125161 00000 n +0000124464 00000 n +0000125284 00000 n +0000125411 00000 n +0000125474 00000 n +0000125538 00000 n +0000125602 00000 n +0000125666 00000 n +0000125730 00000 n +0000127508 00000 n +0000126886 00000 n +0000125952 00000 n +0000127009 00000 n +0000127382 00000 n +0000127445 00000 n +0000413487 00000 n +0000130158 00000 n +0000128824 00000 n +0000127638 00000 n +0000128947 00000 n +0000129074 00000 n +0000129138 00000 n +0000129200 00000 n +0000129264 00000 n +0000129328 00000 n +0000129392 00000 n +0000129456 00000 n +0000129520 00000 n +0000129584 00000 n +0000129648 00000 n +0000129712 00000 n +0000129839 00000 n +0000129903 00000 n +0000130030 00000 n +0000130094 00000 n +0000132133 00000 n +0000131196 00000 n +0000130316 00000 n +0000131319 00000 n +0000131444 00000 n +0000131507 00000 n +0000131632 00000 n +0000131694 00000 n +0000131819 00000 n +0000131882 00000 n +0000132007 00000 n +0000132070 00000 n +0000134046 00000 n +0000133102 00000 n +0000132277 00000 n +0000133225 00000 n +0000133352 00000 n +0000133415 00000 n +0000133542 00000 n +0000133606 00000 n +0000133733 00000 n +0000133797 00000 n +0000133918 00000 n +0000133982 00000 n +0000136006 00000 n +0000135008 00000 n +0000134176 00000 n +0000135131 00000 n +0000135256 00000 n +0000135319 00000 n +0000135382 00000 n +0000135505 00000 n +0000135567 00000 n +0000135692 00000 n +0000135755 00000 n +0000135880 00000 n +0000135943 00000 n +0000137917 00000 n +0000136973 00000 n +0000136150 00000 n +0000137096 00000 n +0000137223 00000 n +0000137286 00000 n +0000137413 00000 n +0000137477 00000 n +0000137604 00000 n +0000137668 00000 n +0000137789 00000 n +0000137853 00000 n +0000140072 00000 n +0000139073 00000 n +0000138047 00000 n +0000139196 00000 n +0000139321 00000 n +0000139384 00000 n +0000139509 00000 n +0000139572 00000 n +0000139634 00000 n +0000139759 00000 n +0000139822 00000 n +0000139946 00000 n +0000140009 00000 n +0000413612 00000 n +0000142012 00000 n +0000141068 00000 n +0000140230 00000 n +0000141191 00000 n +0000141318 00000 n +0000141381 00000 n +0000141508 00000 n +0000141572 00000 n +0000141699 00000 n +0000141763 00000 n +0000141884 00000 n +0000141948 00000 n +0000143937 00000 n +0000143006 00000 n +0000142156 00000 n +0000143129 00000 n +0000143254 00000 n +0000143316 00000 n +0000143441 00000 n +0000143504 00000 n +0000143629 00000 n +0000143692 00000 n +0000143811 00000 n +0000143874 00000 n +0000145911 00000 n +0000144961 00000 n +0000144081 00000 n +0000145084 00000 n +0000145211 00000 n +0000145275 00000 n +0000145402 00000 n +0000145466 00000 n +0000145593 00000 n +0000145657 00000 n +0000145784 00000 n +0000145847 00000 n +0000147976 00000 n +0000147040 00000 n +0000146069 00000 n +0000147163 00000 n +0000147473 00000 n +0000147536 00000 n +0000147599 00000 n +0000147662 00000 n +0000147725 00000 n +0000147850 00000 n +0000147913 00000 n +0000149923 00000 n +0000148973 00000 n +0000148120 00000 n +0000149096 00000 n +0000149223 00000 n +0000149287 00000 n +0000149414 00000 n +0000149478 00000 n +0000149605 00000 n +0000149669 00000 n +0000149796 00000 n +0000149859 00000 n +0000151576 00000 n +0000150828 00000 n +0000150067 00000 n +0000150951 00000 n +0000151076 00000 n +0000151138 00000 n +0000151262 00000 n +0000151325 00000 n +0000151450 00000 n +0000151513 00000 n +0000413737 00000 n +0000153352 00000 n +0000152596 00000 n +0000151720 00000 n +0000152719 00000 n +0000153033 00000 n +0000153097 00000 n +0000153224 00000 n +0000153288 00000 n +0000155399 00000 n +0000154398 00000 n +0000153496 00000 n +0000154521 00000 n +0000154646 00000 n +0000154709 00000 n +0000154834 00000 n +0000154897 00000 n +0000154960 00000 n +0000155085 00000 n +0000155148 00000 n +0000155273 00000 n +0000155336 00000 n +0000157090 00000 n +0000156332 00000 n +0000155543 00000 n +0000156455 00000 n +0000156582 00000 n +0000156645 00000 n +0000156771 00000 n +0000156835 00000 n +0000156962 00000 n +0000157026 00000 n +0000158798 00000 n +0000158115 00000 n +0000157220 00000 n +0000158238 00000 n +0000158610 00000 n +0000158673 00000 n +0000160629 00000 n +0000159873 00000 n +0000158942 00000 n +0000159996 00000 n +0000160311 00000 n +0000160375 00000 n +0000160502 00000 n +0000160566 00000 n +0000162689 00000 n +0000161754 00000 n +0000160773 00000 n +0000161877 00000 n +0000162002 00000 n +0000162065 00000 n +0000162188 00000 n +0000162251 00000 n +0000162375 00000 n +0000162438 00000 n +0000162563 00000 n +0000162626 00000 n +0000413862 00000 n +0000164184 00000 n +0000163683 00000 n +0000162833 00000 n +0000163806 00000 n +0000165656 00000 n +0000165161 00000 n +0000164314 00000 n +0000165284 00000 n +0000167686 00000 n +0000166738 00000 n +0000165786 00000 n +0000166861 00000 n +0000166988 00000 n +0000167051 00000 n +0000167178 00000 n +0000167242 00000 n +0000167368 00000 n +0000167432 00000 n +0000167558 00000 n +0000167622 00000 n +0000169506 00000 n +0000168758 00000 n +0000167830 00000 n +0000168881 00000 n +0000169006 00000 n +0000169069 00000 n +0000169132 00000 n +0000169195 00000 n +0000169320 00000 n +0000169382 00000 n +0000171749 00000 n +0000170800 00000 n +0000169650 00000 n +0000170923 00000 n +0000171113 00000 n +0000171177 00000 n +0000171366 00000 n +0000171430 00000 n +0000171494 00000 n +0000171621 00000 n +0000171685 00000 n +0000173666 00000 n +0000172735 00000 n +0000171907 00000 n +0000172858 00000 n +0000172983 00000 n +0000173045 00000 n +0000173170 00000 n +0000173233 00000 n +0000173358 00000 n +0000173421 00000 n +0000173540 00000 n +0000173603 00000 n +0000413987 00000 n +0000174788 00000 n +0000174410 00000 n +0000173810 00000 n +0000174533 00000 n +0000174660 00000 n +0000174724 00000 n +0000176083 00000 n +0000175587 00000 n +0000174918 00000 n +0000175710 00000 n +0000177994 00000 n +0000177045 00000 n +0000176213 00000 n +0000177168 00000 n +0000177358 00000 n +0000177422 00000 n +0000177486 00000 n +0000177550 00000 n +0000177677 00000 n +0000177741 00000 n +0000177866 00000 n +0000177930 00000 n +0000179903 00000 n +0000179028 00000 n +0000178124 00000 n +0000179151 00000 n +0000179276 00000 n +0000179339 00000 n +0000179464 00000 n +0000179527 00000 n +0000179590 00000 n +0000179653 00000 n +0000179777 00000 n +0000179840 00000 n +0000181102 00000 n +0000180662 00000 n +0000180047 00000 n +0000180785 00000 n +0000180975 00000 n +0000181038 00000 n +0000182912 00000 n +0000182100 00000 n +0000181246 00000 n +0000182223 00000 n +0000182410 00000 n +0000182473 00000 n +0000182598 00000 n +0000182661 00000 n +0000182786 00000 n +0000182849 00000 n +0000414112 00000 n +0000184999 00000 n +0000184051 00000 n +0000183056 00000 n +0000184174 00000 n +0000184301 00000 n +0000184364 00000 n +0000184491 00000 n +0000184555 00000 n +0000184681 00000 n +0000184745 00000 n +0000184871 00000 n +0000184935 00000 n +0000187678 00000 n +0000186742 00000 n +0000185143 00000 n +0000186865 00000 n +0000187114 00000 n +0000187177 00000 n +0000187238 00000 n +0000187301 00000 n +0000187364 00000 n +0000187427 00000 n +0000187490 00000 n +0000187553 00000 n +0000187616 00000 n +0000189282 00000 n +0000189994 00000 n +0000189138 00000 n +0000187836 00000 n +0000189484 00000 n +0000189611 00000 n +0000189675 00000 n +0000189739 00000 n +0000189803 00000 n +0000189930 00000 n +0000191901 00000 n +0000191467 00000 n +0000190152 00000 n +0000191590 00000 n +0000191715 00000 n +0000191838 00000 n +0000193145 00000 n +0000192831 00000 n +0000192031 00000 n +0000192954 00000 n +0000193081 00000 n +0000195238 00000 n +0000194364 00000 n +0000193261 00000 n +0000194487 00000 n +0000194798 00000 n +0000194861 00000 n +0000194924 00000 n +0000194987 00000 n +0000195050 00000 n +0000195112 00000 n +0000195175 00000 n +0000414237 00000 n +0000196710 00000 n +0000196209 00000 n +0000195396 00000 n +0000196332 00000 n +0000199596 00000 n +0000198342 00000 n +0000196840 00000 n +0000198465 00000 n +0000198590 00000 n +0000198653 00000 n +0000198716 00000 n +0000198779 00000 n +0000198842 00000 n +0000198905 00000 n +0000198967 00000 n +0000199030 00000 n +0000199093 00000 n +0000199156 00000 n +0000199219 00000 n +0000199282 00000 n +0000199345 00000 n +0000199408 00000 n +0000199471 00000 n +0000201276 00000 n +0000200776 00000 n +0000199754 00000 n +0000200899 00000 n +0000202838 00000 n +0000202342 00000 n +0000201406 00000 n +0000202465 00000 n +0000205327 00000 n +0000204377 00000 n +0000202968 00000 n +0000204500 00000 n +0000204753 00000 n +0000204817 00000 n +0000204881 00000 n +0000204944 00000 n +0000205008 00000 n +0000205072 00000 n +0000205136 00000 n +0000205200 00000 n +0000207045 00000 n +0000206484 00000 n +0000205485 00000 n +0000206607 00000 n +0000206794 00000 n +0000206857 00000 n +0000206919 00000 n +0000206982 00000 n +0000414362 00000 n +0000208766 00000 n +0000208202 00000 n +0000207189 00000 n +0000208325 00000 n +0000211252 00000 n +0000210000 00000 n +0000208896 00000 n +0000210123 00000 n +0000210310 00000 n +0000210373 00000 n +0000210436 00000 n +0000210499 00000 n +0000210562 00000 n +0000210625 00000 n +0000210688 00000 n +0000210751 00000 n +0000210814 00000 n +0000210876 00000 n +0000210939 00000 n +0000211002 00000 n +0000211065 00000 n +0000214102 00000 n +0000212447 00000 n +0000211410 00000 n +0000212570 00000 n +0000212634 00000 n +0000212698 00000 n +0000212762 00000 n +0000212826 00000 n +0000212890 00000 n +0000212954 00000 n +0000213018 00000 n +0000213082 00000 n +0000213146 00000 n +0000213210 00000 n +0000213274 00000 n +0000213338 00000 n +0000213401 00000 n +0000213528 00000 n +0000213592 00000 n +0000213655 00000 n +0000213719 00000 n +0000213783 00000 n +0000213910 00000 n +0000213974 00000 n +0000214038 00000 n +0000216490 00000 n +0000215238 00000 n +0000214246 00000 n +0000215361 00000 n +0000215486 00000 n +0000215549 00000 n +0000215612 00000 n +0000215675 00000 n +0000215738 00000 n +0000215801 00000 n +0000215925 00000 n +0000215988 00000 n +0000216051 00000 n +0000216114 00000 n +0000216177 00000 n +0000216240 00000 n +0000216303 00000 n +0000216365 00000 n +0000220039 00000 n +0000217871 00000 n +0000216648 00000 n +0000217994 00000 n +0000218058 00000 n +0000218122 00000 n +0000218186 00000 n +0000218250 00000 n +0000218314 00000 n +0000218378 00000 n +0000218442 00000 n +0000218506 00000 n +0000218570 00000 n +0000218634 00000 n +0000218698 00000 n +0000218762 00000 n +0000218826 00000 n +0000218953 00000 n +0000219017 00000 n +0000219081 00000 n +0000219145 00000 n +0000219209 00000 n +0000219273 00000 n +0000219337 00000 n +0000219400 00000 n +0000219464 00000 n +0000219528 00000 n +0000219592 00000 n +0000219656 00000 n +0000219720 00000 n +0000219784 00000 n +0000219847 00000 n +0000219911 00000 n +0000219975 00000 n +0000222891 00000 n +0000221199 00000 n +0000220183 00000 n +0000221322 00000 n +0000221385 00000 n +0000221448 00000 n +0000221572 00000 n +0000221635 00000 n +0000221698 00000 n +0000221761 00000 n +0000221822 00000 n +0000221885 00000 n +0000221948 00000 n +0000222073 00000 n +0000222136 00000 n +0000222199 00000 n +0000222262 00000 n +0000222325 00000 n +0000222388 00000 n +0000222451 00000 n +0000222514 00000 n +0000222577 00000 n +0000222639 00000 n +0000222702 00000 n +0000222765 00000 n +0000222828 00000 n +0000414487 00000 n +0000225233 00000 n +0000224026 00000 n +0000223035 00000 n +0000224149 00000 n +0000224339 00000 n +0000224403 00000 n +0000224467 00000 n +0000224531 00000 n +0000224595 00000 n +0000224659 00000 n +0000224723 00000 n +0000224787 00000 n +0000224850 00000 n +0000224914 00000 n +0000224978 00000 n +0000225042 00000 n +0000225106 00000 n +0000226895 00000 n +0000226333 00000 n +0000225391 00000 n +0000226456 00000 n +0000226519 00000 n +0000226644 00000 n +0000226706 00000 n +0000226769 00000 n +0000226832 00000 n +0000227981 00000 n +0000227603 00000 n +0000227053 00000 n +0000227726 00000 n +0000227790 00000 n +0000227854 00000 n +0000229523 00000 n +0000228965 00000 n +0000228125 00000 n +0000229088 00000 n +0000231615 00000 n +0000230600 00000 n +0000229653 00000 n +0000230723 00000 n +0000230787 00000 n +0000230851 00000 n +0000230915 00000 n +0000230979 00000 n +0000231043 00000 n +0000231107 00000 n +0000231171 00000 n +0000231235 00000 n +0000231488 00000 n +0000231552 00000 n +0000233283 00000 n +0000232532 00000 n +0000231759 00000 n +0000232655 00000 n +0000232780 00000 n +0000232843 00000 n +0000232968 00000 n +0000233031 00000 n +0000233157 00000 n +0000233220 00000 n +0000414612 00000 n +0000235065 00000 n +0000234240 00000 n +0000233427 00000 n +0000234363 00000 n +0000234491 00000 n +0000234555 00000 n +0000234683 00000 n +0000234747 00000 n +0000234875 00000 n +0000234937 00000 n +0000235001 00000 n +0000236863 00000 n +0000236110 00000 n +0000235209 00000 n +0000236233 00000 n +0000236359 00000 n +0000236422 00000 n +0000236548 00000 n +0000236611 00000 n +0000236737 00000 n +0000236800 00000 n +0000238675 00000 n +0000237912 00000 n +0000237007 00000 n +0000238035 00000 n +0000238163 00000 n +0000238227 00000 n +0000238355 00000 n +0000238419 00000 n +0000238547 00000 n +0000238611 00000 n +0000240460 00000 n +0000239771 00000 n +0000238819 00000 n +0000239894 00000 n +0000240020 00000 n +0000240083 00000 n +0000240208 00000 n +0000240271 00000 n +0000241639 00000 n +0000241260 00000 n +0000240604 00000 n +0000241383 00000 n +0000243036 00000 n +0000242662 00000 n +0000241769 00000 n +0000242785 00000 n +0000242974 00000 n +0000414737 00000 n +0000244240 00000 n +0000244053 00000 n +0000243152 00000 n +0000244176 00000 n +0000245471 00000 n +0000245285 00000 n +0000244356 00000 n +0000245408 00000 n +0000246645 00000 n +0000246458 00000 n +0000245587 00000 n +0000246581 00000 n +0000247845 00000 n +0000247659 00000 n +0000246761 00000 n +0000247782 00000 n +0000249341 00000 n +0000248898 00000 n +0000247961 00000 n +0000249021 00000 n +0000249149 00000 n +0000249277 00000 n +0000250623 00000 n +0000250785 00000 n +0000250947 00000 n +0000251109 00000 n +0000251271 00000 n +0000251433 00000 n +0000251594 00000 n +0000251757 00000 n +0000251920 00000 n +0000252083 00000 n +0000252246 00000 n +0000252409 00000 n +0000254308 00000 n +0000252698 00000 n +0000250380 00000 n +0000249457 00000 n +0000252572 00000 n +0000414862 00000 n +0000254470 00000 n +0000254630 00000 n +0000254792 00000 n +0000254955 00000 n +0000255118 00000 n +0000255280 00000 n +0000255443 00000 n +0000255603 00000 n +0000255765 00000 n +0000255928 00000 n +0000256091 00000 n +0000256254 00000 n +0000256480 00000 n +0000254056 00000 n +0000252828 00000 n +0000256416 00000 n +0000257862 00000 n +0000258025 00000 n +0000258188 00000 n +0000258349 00000 n +0000258512 00000 n +0000258675 00000 n +0000258838 00000 n +0000259001 00000 n +0000260421 00000 n +0000259227 00000 n +0000257655 00000 n +0000256596 00000 n +0000259164 00000 n +0000260584 00000 n +0000260747 00000 n +0000260910 00000 n +0000261072 00000 n +0000261231 00000 n +0000261394 00000 n +0000262966 00000 n +0000261621 00000 n +0000260223 00000 n +0000259343 00000 n +0000261557 00000 n +0000263128 00000 n +0000263291 00000 n +0000263453 00000 n +0000263616 00000 n +0000263779 00000 n +0000263941 00000 n +0000264166 00000 n +0000262768 00000 n +0000261737 00000 n +0000264103 00000 n +0000265504 00000 n +0000265666 00000 n +0000265828 00000 n +0000265990 00000 n +0000266152 00000 n +0000266315 00000 n +0000266477 00000 n +0000267915 00000 n +0000268078 00000 n +0000268241 00000 n +0000266703 00000 n +0000265306 00000 n +0000264282 00000 n +0000266639 00000 n +0000268404 00000 n +0000268565 00000 n +0000268727 00000 n +0000270249 00000 n +0000268952 00000 n +0000267726 00000 n +0000266819 00000 n +0000268889 00000 n +0000414987 00000 n +0000270411 00000 n +0000270573 00000 n +0000270735 00000 n +0000270896 00000 n +0000271057 00000 n +0000272679 00000 n +0000271283 00000 n +0000270060 00000 n +0000269068 00000 n +0000271219 00000 n +0000272842 00000 n +0000273005 00000 n +0000273168 00000 n +0000273331 00000 n +0000273492 00000 n +0000273654 00000 n +0000273816 00000 n +0000273977 00000 n +0000274139 00000 n +0000275898 00000 n +0000276059 00000 n +0000276220 00000 n +0000274364 00000 n +0000272454 00000 n +0000271399 00000 n +0000274301 00000 n +0000276381 00000 n +0000276543 00000 n +0000276703 00000 n +0000276862 00000 n +0000277022 00000 n +0000277184 00000 n +0000277346 00000 n +0000279075 00000 n +0000277572 00000 n +0000275673 00000 n +0000274480 00000 n +0000277508 00000 n +0000279237 00000 n +0000279399 00000 n +0000279560 00000 n +0000279721 00000 n +0000279883 00000 n +0000280044 00000 n +0000280205 00000 n +0000280367 00000 n +0000280529 00000 n +0000282160 00000 n +0000280755 00000 n +0000278850 00000 n +0000277688 00000 n +0000280692 00000 n +0000282322 00000 n +0000282483 00000 n +0000282644 00000 n +0000282805 00000 n +0000282968 00000 n +0000283131 00000 n +0000283294 00000 n +0000283456 00000 n +0000283618 00000 n +0000283844 00000 n +0000281935 00000 n +0000280871 00000 n +0000283780 00000 n +0000285043 00000 n +0000285205 00000 n +0000285367 00000 n +0000285528 00000 n +0000285690 00000 n +0000285852 00000 n +0000286078 00000 n +0000284854 00000 n +0000283960 00000 n +0000286015 00000 n +0000415112 00000 n +0000286766 00000 n +0000286515 00000 n +0000286194 00000 n +0000286638 00000 n +0000287458 00000 n +0000287209 00000 n +0000286868 00000 n +0000287332 00000 n +0000288251 00000 n +0000288402 00000 n +0000288553 00000 n +0000288703 00000 n +0000288853 00000 n +0000289003 00000 n +0000289153 00000 n +0000289304 00000 n +0000289453 00000 n +0000289604 00000 n +0000289755 00000 n +0000289906 00000 n +0000290185 00000 n +0000288008 00000 n +0000287560 00000 n +0000290057 00000 n +0000410765 00000 n +0000290273 00000 n +0000290665 00000 n +0000291037 00000 n +0000411253 00000 n +0000291433 00000 n +0000291457 00000 n +0000291929 00000 n +0000292413 00000 n +0000292897 00000 n +0000293375 00000 n +0000294583 00000 n +0000294812 00000 n +0000305085 00000 n +0000305384 00000 n +0000325658 00000 n +0000326297 00000 n +0000341881 00000 n +0000342391 00000 n +0000358216 00000 n +0000358632 00000 n +0000378382 00000 n +0000378942 00000 n +0000394368 00000 n +0000394760 00000 n +0000410348 00000 n +0000415219 00000 n +0000415345 00000 n +0000415471 00000 n +0000415597 00000 n +0000415687 00000 n +0000415779 00000 n +0000441586 00000 n +0000441784 00000 n +0000442025 00000 n +0000442265 00000 n +0000442506 00000 n +0000442746 00000 n +0000442987 00000 n +0000443227 00000 n +0000443468 00000 n +0000443708 00000 n +0000443949 00000 n +0000444184 00000 n +0000444416 00000 n +0000444649 00000 n +0000444880 00000 n +0000445111 00000 n +0000445344 00000 n +0000445576 00000 n +0000445809 00000 n +0000446041 00000 n +0000446274 00000 n +0000446506 00000 n +0000446739 00000 n +0000446971 00000 n +0000447204 00000 n +0000447435 00000 n +0000447668 00000 n +0000447915 00000 n +0000448164 00000 n +0000448412 00000 n +0000448661 00000 n +0000448910 00000 n +0000449159 00000 n +0000449404 00000 n +0000449654 00000 n +0000449903 00000 n +0000450152 00000 n +0000450404 00000 n +0000450655 00000 n +0000450907 00000 n +0000451158 00000 n +0000451407 00000 n +0000451656 00000 n +0000451905 00000 n +0000452150 00000 n +0000452400 00000 n +0000452649 00000 n +0000452902 00000 n +0000453159 00000 n +0000453408 00000 n +0000453657 00000 n +0000453910 00000 n +0000454159 00000 n +0000454412 00000 n +0000454661 00000 n +0000454910 00000 n +0000455159 00000 n +0000455406 00000 n +0000455652 00000 n +0000455901 00000 n +0000456146 00000 n +0000456387 00000 n +0000456627 00000 n +0000456868 00000 n +0000457110 00000 n +0000457351 00000 n +0000457591 00000 n +0000457832 00000 n +0000458072 00000 n +0000458313 00000 n +0000458553 00000 n +0000458794 00000 n +0000459032 00000 n +0000459273 00000 n +0000459512 00000 n +0000459747 00000 n +0000459988 00000 n +0000460226 00000 n +0000460465 00000 n +0000460704 00000 n +0000460940 00000 n +0000461181 00000 n +0000461404 00000 n +0000461587 00000 n +0000461770 00000 n +0000461955 00000 n +0000462136 00000 n +0000462311 00000 n +0000462488 00000 n +0000462664 00000 n +0000462841 00000 n +0000463017 00000 n +0000463194 00000 n +0000463370 00000 n +0000463547 00000 n +0000463723 00000 n +0000463900 00000 n +0000464075 00000 n +0000464250 00000 n +0000464427 00000 n +0000464603 00000 n +0000464780 00000 n +0000464995 00000 n +0000465256 00000 n +0000465523 00000 n +0000465790 00000 n +0000466049 00000 n +0000466316 00000 n +0000466579 00000 n +0000466838 00000 n +0000467105 00000 n +0000467371 00000 n +0000467638 00000 n +0000467904 00000 n +0000468171 00000 n +0000468433 00000 n +0000468694 00000 n +0000468953 00000 n +0000469214 00000 n +0000469473 00000 n +0000469738 00000 n +0000470003 00000 n +0000470270 00000 n +0000470536 00000 n +0000470797 00000 n +0000471056 00000 n +0000471315 00000 n +0000471574 00000 n +0000471837 00000 n +0000472104 00000 n +0000472370 00000 n +0000472633 00000 n +0000472892 00000 n +0000473122 00000 n +0000473317 00000 n +0000473498 00000 n +0000473710 00000 n +0000473946 00000 n +0000474188 00000 n +0000474466 00000 n +0000474741 00000 n +0000475021 00000 n +0000475300 00000 n +0000475575 00000 n +0000475863 00000 n +0000476150 00000 n +0000476439 00000 n +0000476717 00000 n +0000476992 00000 n +0000477196 00000 n +0000477375 00000 n +0000477495 00000 n +0000477621 00000 n +0000477752 00000 n +0000477882 00000 n +0000478012 00000 n +0000478143 00000 n +0000478277 00000 n +0000478411 00000 n +0000478546 00000 n +0000478680 00000 n +0000478813 00000 n +0000478945 00000 n +0000479077 00000 n +0000479209 00000 n +0000479333 00000 n +0000479450 00000 n +0000479566 00000 n +0000479692 00000 n +0000479830 00000 n +0000479969 00000 n +0000480109 00000 n +0000480248 00000 n +0000480386 00000 n +0000480527 00000 n +0000480671 00000 n +0000480801 00000 n +0000480872 00000 n +0000480999 00000 n +0000481132 00000 n +0000481267 00000 n +0000481408 00000 n +0000481502 00000 n +0000481611 00000 n +0000481651 00000 n +0000481777 00000 n +trailer +<< /Size 2731 +/Root 2729 0 R +/Info 2730 0 R +/ID [<5BA9E235E9B0123FC19746A4A8C71377> <5BA9E235E9B0123FC19746A4A8C71377>] >> +startxref +482225 +%%EOF diff --git a/Puma/doc/lemon/lemon.html b/Puma/doc/lemon/lemon.html new file mode 100644 index 0000000..9b4648f --- /dev/null +++ b/Puma/doc/lemon/lemon.html @@ -0,0 +1,861 @@ + + +The Lemon Parser Generator + + +

The Lemon Parser Generator

+ +

Lemon is an LALR(1) parser generator for C or C++. +It does the same job as ``bison'' and ``yacc''. +But lemon is not another bison or yacc clone. It +uses a different grammar syntax which is designed to +reduce the number of coding errors. Lemon also uses a more +sophisticated parsing engine that is faster than yacc and +bison and which is both reentrant and thread-safe. +Furthermore, Lemon implements features that can be used +to eliminate resource leaks, making is suitable for use +in long-running programs such as graphical user interfaces +or embedded controllers.

+ +

This document is an introduction to the Lemon +parser generator.

+ +

Theory of Operation

+ +

The main goal of Lemon is to translate a context free grammar (CFG) +for a particular language into C code that implements a parser for +that language. +The program has two inputs: +

    +
  • The grammar specification. +
  • A parser template file. +
+Typically, only the grammar specification is supplied by the programmer. +Lemon comes with a default parser template which works fine for most +applications. But the user is free to substitute a different parser +template if desired.

+ +

Depending on command-line options, Lemon will generate between +one and three files of outputs. +

    +
  • C code to implement the parser. +
  • A header file defining an integer ID for each terminal symbol. +
  • An information file that describes the states of the generated parser + automaton. +
+By default, all three of these output files are generated. +The header file is suppressed if the ``-m'' command-line option is +used and the report file is omitted when ``-q'' is selected.

+ +

The grammar specification file uses a ``.y'' suffix, by convention. +In the examples used in this document, we'll assume the name of the +grammar file is ``gram.y''. A typical use of Lemon would be the +following command: +

+   lemon gram.y
+
+This command will generate three output files named ``gram.c'', +``gram.h'' and ``gram.out''. +The first is C code to implement the parser. The second +is the header file that defines numerical values for all +terminal symbols, and the last is the report that explains +the states used by the parser automaton.

+ +

Command Line Options

+ +

The behavior of Lemon can be modified using command-line options. +You can obtain a list of the available command-line options together +with a brief explanation of what each does by typing +

+   lemon -?
+
+As of this writing, the following command-line options are supported: +
    +
  • -b +
  • -c +
  • -g +
  • -m +
  • -q +
  • -s +
  • -x +
+The ``-b'' option reduces the amount of text in the report file by +printing only the basis of each parser state, rather than the full +configuration. +The ``-c'' option suppresses action table compression. Using -c +will make the parser a little larger and slower but it will detect +syntax errors sooner. +The ``-g'' option causes no output files to be generated at all. +Instead, the input grammar file is printed on standard output but +with all comments, actions and other extraneous text deleted. This +is a useful way to get a quick summary of a grammar. +The ``-m'' option causes the output C source file to be compatible +with the ``makeheaders'' program. +Makeheaders is a program that automatically generates header files +from C source code. When the ``-m'' option is used, the header +file is not output since the makeheaders program will take care +of generated all header files automatically. +The ``-q'' option suppresses the report file. +Using ``-s'' causes a brief summary of parser statistics to be +printed. Like this: +
+   Parser statistics: 74 terminals, 70 nonterminals, 179 rules
+                      340 states, 2026 parser table entries, 0 conflicts
+
+Finally, the ``-x'' option causes Lemon to print its version number +and copyright information +and then stop without attempting to read the grammar or generate a parser.

+ +

The Parser Interface

+ +

Lemon doesn't generate a complete, working program. It only generates +a few subroutines that implement a parser. This section describes +the interface to those subroutines. It is up to the programmer to +call these subroutines in an appropriate way in order to produce a +complete system.

+ +

Before a program begins using a Lemon-generated parser, the program +must first create the parser. +A new parser is created as follows: +

+   void *pParser = ParseAlloc( malloc );
+
+The ParseAlloc() routine allocates and initializes a new parser and +returns a pointer to it. +The actual data structure used to represent a parser is opaque -- +its internal structure is not visible or usable by the calling routine. +For this reason, the ParseAlloc() routine returns a pointer to void +rather than a pointer to some particular structure. +The sole argument to the ParseAlloc() routine is a pointer to the +subroutine used to allocate memory. Typically this means ``malloc()''.

+ +

After a program is finished using a parser, it can reclaim all +memory allocated by that parser by calling +

+   ParseFree(pParser, free);
+
+The first argument is the same pointer returned by ParseAlloc(). The +second argument is a pointer to the function used to release bulk +memory back to the system.

+ +

After a parser has been allocated using ParseAlloc(), the programmer +must supply the parser with a sequence of tokens (terminal symbols) to +be parsed. This is accomplished by calling the following function +once for each token: +

+   Parse(pParser, hTokenID, sTokenData, pArg);
+
+The first argument to the Parse() routine is the pointer returned by +ParseAlloc(). +The second argument is a small positive integer that tells the parse the +type of the next token in the data stream. +There is one token type for each terminal symbol in the grammar. +The gram.h file generated by Lemon contains #define statements that +map symbolic terminal symbol names into appropriate integer values. +(A value of 0 for the second argument is a special flag to the +parser to indicate that the end of input has been reached.) +The third argument is the value of the given token. By default, +the type of the third argument is integer, but the grammar will +usually redefine this type to be some kind of structure. +Typically the second argument will be a broad category of tokens +such as ``identifier'' or ``number'' and the third argument will +be the name of the identifier or the value of the number.

+ +

The Parse() function may have either three or four arguments, +depending on the grammar. If the grammar specification file request +it, the Parse() function will have a fourth parameter that can be +of any type chosen by the programmer. The parser doesn't do anything +with this argument except to pass it through to action routines. +This is a convenient mechanism for passing state information down +to the action routines without having to use global variables.

+ +

A typical use of a Lemon parser might look something like the +following: +

+   01 ParseTree *ParseFile(const char *zFilename){
+   02    Tokenizer *pTokenizer;
+   03    void *pParser;
+   04    Token sToken;
+   05    int hTokenId;
+   06    ParserState sState;
+   07
+   08    pTokenizer = TokenizerCreate(zFilename);
+   09    pParser = ParseAlloc( malloc );
+   10    InitParserState(&sState);
+   11    while( GetNextToken(pTokenizer, &hTokenId, &sToken) ){
+   12       Parse(pParser, hTokenId, sToken, &sState);
+   13    }
+   14    Parse(pParser, 0, sToken, &sState);
+   15    ParseFree(pParser, free );
+   16    TokenizerFree(pTokenizer);
+   17    return sState.treeRoot;
+   18 }
+
+This example shows a user-written routine that parses a file of +text and returns a pointer to the parse tree. +(We've omitted all error-handling from this example to keep it +simple.) +We assume the existence of some kind of tokenizer which is created +using TokenizerCreate() on line 8 and deleted by TokenizerFree() +on line 16. The GetNextToken() function on line 11 retrieves the +next token from the input file and puts its type in the +integer variable hTokenId. The sToken variable is assumed to be +some kind of structure that contains details about each token, +such as its complete text, what line it occurs on, etc.

+ +

This example also assumes the existence of structure of type +ParserState that holds state information about a particular parse. +An instance of such a structure is created on line 6 and initialized +on line 10. A pointer to this structure is passed into the Parse() +routine as the optional 4th argument. +The action routine specified by the grammar for the parser can use +the ParserState structure to hold whatever information is useful and +appropriate. In the example, we note that the treeRoot field of +the ParserState structure is left pointing to the root of the parse +tree.

+ +

The core of this example as it relates to Lemon is as follows: +

+   ParseFile(){
+      pParser = ParseAlloc( malloc );
+      while( GetNextToken(pTokenizer,&hTokenId, &sToken) ){
+         Parse(pParser, hTokenId, sToken);
+      }
+      Parse(pParser, 0, sToken);
+      ParseFree(pParser, free );
+   }
+
+Basically, what a program has to do to use a Lemon-generated parser +is first create the parser, then send it lots of tokens obtained by +tokenizing an input source. When the end of input is reached, the +Parse() routine should be called one last time with a token type +of 0. This step is necessary to inform the parser that the end of +input has been reached. Finally, we reclaim memory used by the +parser by calling ParseFree().

+ +

There is one other interface routine that should be mentioned +before we move on. +The ParseTrace() function can be used to generate debugging output +from the parser. A prototype for this routine is as follows: +

+   ParseTrace(FILE *stream, char *zPrefix);
+
+After this routine is called, a short (one-line) message is written +to the designated output stream every time the parser changes states +or calls an action routine. Each such message is prefaced using +the text given by zPrefix. This debugging output can be turned off +by calling ParseTrace() again with a first argument of NULL (0).

+ +

Differences With YACC and BISON

+ +

Programmers who have previously used the yacc or bison parser +generator will notice several important differences between yacc and/or +bison and Lemon. +

    +
  • In yacc and bison, the parser calls the tokenizer. In Lemon, + the tokenizer calls the parser. +
  • Lemon uses no global variables. Yacc and bison use global variables + to pass information between the tokenizer and parser. +
  • Lemon allows multiple parsers to be running simultaneously. Yacc + and bison do not. +
+These differences may cause some initial confusion for programmers +with prior yacc and bison experience. +But after years of experience using Lemon, I firmly +believe that the Lemon way of doing things is better.

+ +

Input File Syntax

+ +

The main purpose of the grammar specification file for Lemon is +to define the grammar for the parser. But the input file also +specifies additional information Lemon requires to do its job. +Most of the work in using Lemon is in writing an appropriate +grammar file.

+ +

The grammar file for lemon is, for the most part, free format. +It does not have sections or divisions like yacc or bison. Any +declaration can occur at any point in the file. +Lemon ignores whitespace (except where it is needed to separate +tokens) and it honors the same commenting conventions as C and C++.

+ +

Terminals and Nonterminals

+ +

A terminal symbol (token) is any string of alphanumeric +and underscore characters +that begins with an upper case letter. +A terminal can contain lower class letters after the first character, +but the usual convention is to make terminals all upper case. +A nonterminal, on the other hand, is any string of alphanumeric +and underscore characters than begins with a lower case letter. +Again, the usual convention is to make nonterminals use all lower +case letters.

+ +

In Lemon, terminal and nonterminal symbols do not need to +be declared or identified in a separate section of the grammar file. +Lemon is able to generate a list of all terminals and nonterminals +by examining the grammar rules, and it can always distinguish a +terminal from a nonterminal by checking the case of the first +character of the name.

+ +

Yacc and bison allow terminal symbols to have either alphanumeric +names or to be individual characters included in single quotes, like +this: ')' or '$'. Lemon does not allow this alternative form for +terminal symbols. With Lemon, all symbols, terminals and nonterminals, +must have alphanumeric names.

+ +

Grammar Rules

+ +

The main component of a Lemon grammar file is a sequence of grammar +rules. +Each grammar rule consists of a nonterminal symbol followed by +the special symbol ``::='' and then a list of terminals and/or nonterminals. +The rule is terminated by a period. +The list of terminals and nonterminals on the right-hand side of the +rule can be empty. +Rules can occur in any order, except that the left-hand side of the +first rule is assumed to be the start symbol for the grammar (unless +specified otherwise using the %start directive described below.) +A typical sequence of grammar rules might look something like this: +

+  expr ::= expr PLUS expr.
+  expr ::= expr TIMES expr.
+  expr ::= LPAREN expr RPAREN.
+  expr ::= VALUE.
+
+

+ +

There is one non-terminal in this example, ``expr'', and five +terminal symbols or tokens: ``PLUS'', ``TIMES'', ``LPAREN'', +``RPAREN'' and ``VALUE''.

+ +

Like yacc and bison, Lemon allows the grammar to specify a block +of C code that will be executed whenever a grammar rule is reduced +by the parser. +In Lemon, this action is specified by putting the C code (contained +within curly braces {...}) immediately after the +period that closes the rule. +For example: +

+  expr ::= expr PLUS expr.   { printf("Doing an addition...\n"); }
+
+

+ +

In order to be useful, grammar actions must normally be linked to +their associated grammar rules. +In yacc and bison, this is accomplished by embedding a ``$$'' in the +action to stand for the value of the left-hand side of the rule and +symbols ``$1'', ``$2'', and so forth to stand for the value of +the terminal or nonterminal at position 1, 2 and so forth on the +right-hand side of the rule. +This idea is very powerful, but it is also very error-prone. The +single most common source of errors in a yacc or bison grammar is +to miscount the number of symbols on the right-hand side of a grammar +rule and say ``$7'' when you really mean ``$8''.

+ +

Lemon avoids the need to count grammar symbols by assigning symbolic +names to each symbol in a grammar rule and then using those symbolic +names in the action. +In yacc or bison, one would write this: +

+  expr -> expr PLUS expr  { $$ = $1 + $3; };
+
+But in Lemon, the same rule becomes the following: +
+  expr(A) ::= expr(B) PLUS expr(C).  { A = B+C; }
+
+In the Lemon rule, any symbol in parentheses after a grammar rule +symbol becomes a place holder for that symbol in the grammar rule. +This place holder can then be used in the associated C action to +stand for the value of that symbol.

+ +

The Lemon notation for linking a grammar rule with its reduce +action is superior to yacc/bison on several counts. +First, as mentioned above, the Lemon method avoids the need to +count grammar symbols. +Secondly, if a terminal or nonterminal in a Lemon grammar rule +includes a linking symbol in parentheses but that linking symbol +is not actually used in the reduce action, then an error message +is generated. +For example, the rule +

+  expr(A) ::= expr(B) PLUS expr(C).  { A = B; }
+
+will generate an error because the linking symbol ``C'' is used +in the grammar rule but not in the reduce action.

+ +

The Lemon notation for linking grammar rules to reduce actions +also facilitates the use of destructors for reclaiming memory +allocated by the values of terminals and nonterminals on the +right-hand side of a rule.

+ +

Precedence Rules

+ +

Lemon resolves parsing ambiguities in exactly the same way as +yacc and bison. A shift-reduce conflict is resolved in favor +of the shift, and a reduce-reduce conflict is resolved by reducing +whichever rule comes first in the grammar file.

+ +

Just like in +yacc and bison, Lemon allows a measure of control +over the resolution of paring conflicts using precedence rules. +A precedence value can be assigned to any terminal symbol +using the %left, %right or %nonassoc directives. Terminal symbols +mentioned in earlier directives have a lower precedence that +terminal symbols mentioned in later directives. For example:

+ +

+   %left AND.
+   %left OR.
+   %nonassoc EQ NE GT GE LT LE.
+   %left PLUS MINUS.
+   %left TIMES DIVIDE MOD.
+   %right EXP NOT.
+

+ +

In the preceding sequence of directives, the AND operator is +defined to have the lowest precedence. The OR operator is one +precedence level higher. And so forth. Hence, the grammar would +attempt to group the ambiguous expression +

+     a AND b OR c
+
+like this +
+     a AND (b OR c).
+
+The associativity (left, right or nonassoc) is used to determine +the grouping when the precedence is the same. AND is left-associative +in our example, so +
+     a AND b AND c
+
+is parsed like this +
+     (a AND b) AND c.
+
+The EXP operator is right-associative, though, so +
+     a EXP b EXP c
+
+is parsed like this +
+     a EXP (b EXP c).
+
+The nonassoc precedence is used for non-associative operators. +So +
+     a EQ b EQ c
+
+is an error.

+ +

The precedence of non-terminals is transferred to rules as follows: +The precedence of a grammar rule is equal to the precedence of the +left-most terminal symbol in the rule for which a precedence is +defined. This is normally what you want, but in those cases where +you want to precedence of a grammar rule to be something different, +you can specify an alternative precedence symbol by putting the +symbol in square braces after the period at the end of the rule and +before any C-code. For example:

+ +

+   expr = MINUS expr.  [NOT]
+

+ +

This rule has a precedence equal to that of the NOT symbol, not the +MINUS symbol as would have been the case by default.

+ +

With the knowledge of how precedence is assigned to terminal +symbols and individual +grammar rules, we can now explain precisely how parsing conflicts +are resolved in Lemon. Shift-reduce conflicts are resolved +as follows: +

    +
  • If either the token to be shifted or the rule to be reduced + lacks precedence information, then resolve in favor of the + shift, but report a parsing conflict. +
  • If the precedence of the token to be shifted is greater than + the precedence of the rule to reduce, then resolve in favor + of the shift. No parsing conflict is reported. +
  • If the precedence of the token it be shifted is less than the + precedence of the rule to reduce, then resolve in favor of the + reduce action. No parsing conflict is reported. +
  • If the precedences are the same and the shift token is + right-associative, then resolve in favor of the shift. + No parsing conflict is reported. +
  • If the precedences are the same the the shift token is + left-associative, then resolve in favor of the reduce. + No parsing conflict is reported. +
  • Otherwise, resolve the conflict by doing the shift and + report the parsing conflict. +
+Reduce-reduce conflicts are resolved this way: +
    +
  • If either reduce rule + lacks precedence information, then resolve in favor of the + rule that appears first in the grammar and report a parsing + conflict. +
  • If both rules have precedence and the precedence is different + then resolve the dispute in favor of the rule with the highest + precedence and do not report a conflict. +
  • Otherwise, resolve the conflict by reducing by the rule that + appears first in the grammar and report a parsing conflict. +
+ +

Special Directives

+ +

The input grammar to Lemon consists of grammar rules and special +directives. We've described all the grammar rules, so now we'll +talk about the special directives.

+ +

Directives in lemon can occur in any order. You can put them before +the grammar rules, or after the grammar rules, or in the mist of the +grammar rules. It doesn't matter. The relative order of +directives used to assign precedence to terminals is important, but +other than that, the order of directives in Lemon is arbitrary.

+ +

Lemon supports the following special directives: +

    +
  • %destructor +
  • %extra_argument +
  • %include +
  • %left +
  • %name +
  • %nonassoc +
  • %parse_accept +
  • %parse_failure +
  • %right +
  • %stack_overflow +
  • %stack_size +
  • %start_symbol +
  • %syntax_error +
  • %token_destructor +
  • %token_prefix +
  • %token_type +
  • %type +
+Each of these directives will be described separately in the +following sections:

+ +

The %destructor directive

+ +

The %destructor directive is used to specify a destructor for +a non-terminal symbol. +(See also the %token_destructor directive which is used to +specify a destructor for terminal symbols.)

+ +

A non-terminal's destructor is called to dispose of the +non-terminal's value whenever the non-terminal is popped from +the stack. This includes all of the following circumstances: +

    +
  • When a rule reduces and the value of a non-terminal on + the right-hand side is not linked to C code. +
  • When the stack is popped during error processing. +
  • When the ParseFree() function runs. +
+The destructor can do whatever it wants with the value of +the non-terminal, but its design is to deallocate memory +or other resources held by that non-terminal.

+ +

Consider an example: +

+   %type nt {void*}
+   %destructor nt { free($$); }
+   nt(A) ::= ID NUM.   { A = malloc( 100 ); }
+
+This example is a bit contrived but it serves to illustrate how +destructors work. The example shows a non-terminal named +``nt'' that holds values of type ``void*''. When the rule for +an ``nt'' reduces, it sets the value of the non-terminal to +space obtained from malloc(). Later, when the nt non-terminal +is popped from the stack, the destructor will fire and call +free() on this malloced space, thus avoiding a memory leak. +(Note that the symbol ``$$'' in the destructor code is replaced +by the value of the non-terminal.)

+ +

It is important to note that the value of a non-terminal is passed +to the destructor whenever the non-terminal is removed from the +stack, unless the non-terminal is used in a C-code action. If +the non-terminal is used by C-code, then it is assumed that the +C-code will take care of destroying it if it should really +be destroyed. More commonly, the value is used to build some +larger structure and we don't want to destroy it, which is why +the destructor is not called in this circumstance.

+ +

By appropriate use of destructors, it is possible to +build a parser using Lemon that can be used within a long-running +program, such as a GUI, that will not leak memory or other resources. +To do the same using yacc or bison is much more difficult.

+ +

The %extra_argument directive

+ +The %extra_argument directive instructs Lemon to add a 4th parameter +to the parameter list of the Parse() function it generates. Lemon +doesn't do anything itself with this extra argument, but it does +make the argument available to C-code action routines, destructors, +and so forth. For example, if the grammar file contains:

+ +

+    %extra_argument { MyStruct *pAbc }
+

+ +

Then the Parse() function generated will have an 4th parameter +of type ``MyStruct*'' and all action routines will have access to +a variable named ``pAbc'' that is the value of the 4th parameter +in the most recent call to Parse().

+ +

The %include directive

+ +

The %include directive specifies C code that is included at the +top of the generated parser. You can include any text you want -- +the Lemon parser generator copies to blindly. If you have multiple +%include directives in your grammar file, their values are concatenated +before being put at the beginning of the generated parser.

+ +

The %include directive is very handy for getting some extra #include +preprocessor statements at the beginning of the generated parser. +For example:

+ +

+   %include {#include <unistd.h>}
+

+ +

This might be needed, for example, if some of the C actions in the +grammar call functions that are prototyed in unistd.h.

+ +

The %left directive

+ +The %left directive is used (along with the %right and +%nonassoc directives) to declare precedences of terminal +symbols. Every terminal symbol whose name appears after +a %left directive but before the next period (``.'') is +given the same left-associative precedence value. Subsequent +%left directives have higher precedence. For example:

+ +

+   %left AND.
+   %left OR.
+   %nonassoc EQ NE GT GE LT LE.
+   %left PLUS MINUS.
+   %left TIMES DIVIDE MOD.
+   %right EXP NOT.
+

+ +

Note the period that terminates each %left, %right or %nonassoc +directive.

+ +

LALR(1) grammars can get into a situation where they require +a large amount of stack space if you make heavy use or right-associative +operators. For this reason, it is recommended that you use %left +rather than %right whenever possible.

+ +

The %name directive

+ +

By default, the functions generated by Lemon all begin with the +five-character string ``Parse''. You can change this string to something +different using the %name directive. For instance:

+ +

+   %name Abcde
+

+ +

Putting this directive in the grammar file will cause Lemon to generate +functions named +

    +
  • AbcdeAlloc(), +
  • AbcdeFree(), +
  • AbcdeTrace(), and +
  • Abcde(). +
+The %name directive allows you to generator two or more different +parsers and link them all into the same executable. +

+ +

The %nonassoc directive

+ +

This directive is used to assign non-associative precedence to +one or more terminal symbols. See the section on precedence rules +or on the %left directive for additional information.

+ +

The %parse_accept directive

+ +

The %parse_accept directive specifies a block of C code that is +executed whenever the parser accepts its input string. To ``accept'' +an input string means that the parser was able to process all tokens +without error.

+ +

For example:

+ +

+   %parse_accept {
+      printf("parsing complete!\n");
+   }
+

+ + +

The %parse_failure directive

+ +

The %parse_failure directive specifies a block of C code that +is executed whenever the parser fails complete. This code is not +executed until the parser has tried and failed to resolve an input +error using is usual error recovery strategy. The routine is +only invoked when parsing is unable to continue.

+ +

+   %parse_failure {
+     fprintf(stderr,"Giving up.  Parser is hopelessly lost...\n");
+   }
+

+ +

The %right directive

+ +

This directive is used to assign right-associative precedence to +one or more terminal symbols. See the section on precedence rules +or on the %left directive for additional information.

+ +

The %stack_overflow directive

+ +

The %stack_overflow directive specifies a block of C code that +is executed if the parser's internal stack ever overflows. Typically +this just prints an error message. After a stack overflow, the parser +will be unable to continue and must be reset.

+ +

+   %stack_overflow {
+     fprintf(stderr,"Giving up.  Parser stack overflow\n");
+   }
+

+ +

You can help prevent parser stack overflows by avoiding the use +of right recursion and right-precedence operators in your grammar. +Use left recursion and and left-precedence operators instead, to +encourage rules to reduce sooner and keep the stack size down. +For example, do rules like this: +

+   list ::= list element.      // left-recursion.  Good!
+   list ::= .
+
+Not like this: +
+   list ::= element list.      // right-recursion.  Bad!
+   list ::= .
+
+ +

The %stack_size directive

+ +

If stack overflow is a problem and you can't resolve the trouble +by using left-recursion, then you might want to increase the size +of the parser's stack using this directive. Put an positive integer +after the %stack_size directive and Lemon will generate a parse +with a stack of the requested size. The default value is 100.

+ +

+   %stack_size 2000
+

+ +

The %start_symbol directive

+ +

By default, the start-symbol for the grammar that Lemon generates +is the first non-terminal that appears in the grammar file. But you +can choose a different start-symbol using the %start_symbol directive.

+ +

+   %start_symbol  prog
+

+ +

The %token_destructor directive

+ +

The %destructor directive assigns a destructor to a non-terminal +symbol. (See the description of the %destructor directive above.) +This directive does the same thing for all terminal symbols.

+ +

Unlike non-terminal symbols which may each have a different data type +for their values, terminals all use the same data type (defined by +the %token_type directive) and so they use a common destructor. Other +than that, the token destructor works just like the non-terminal +destructors.

+ +

The %token_prefix directive

+ +

Lemon generates #defines that assign small integer constants +to each terminal symbol in the grammar. If desired, Lemon will +add a prefix specified by this directive +to each of the #defines it generates. +So if the default output of Lemon looked like this: +

+    #define AND              1
+    #define MINUS            2
+    #define OR               3
+    #define PLUS             4
+
+You can insert a statement into the grammar like this: +
+    %token_prefix    TOKEN_
+
+to cause Lemon to produce these symbols instead: +
+    #define TOKEN_AND        1
+    #define TOKEN_MINUS      2
+    #define TOKEN_OR         3
+    #define TOKEN_PLUS       4
+
+ +

The %token_type and %type directives

+ +

These directives are used to specify the data types for values +on the parser's stack associated with terminal and non-terminal +symbols. The values of all terminal symbols must be of the same +type. This turns out to be the same data type as the 3rd parameter +to the Parse() function generated by Lemon. Typically, you will +make the value of a terminal symbol by a pointer to some kind of +token structure. Like this:

+ +

+   %token_type    {Token*}
+

+ +

If the data type of terminals is not specified, the default value +is ``int''.

+ +

Non-terminal symbols can each have their own data types. Typically +the data type of a non-terminal is a pointer to the root of a parse-tree +structure that contains all information about that non-terminal. +For example:

+ +

+   %type   expr  {Expr*}
+

+ +

Each entry on the parser's stack is actually a union containing +instances of all data types for every non-terminal and terminal symbol. +Lemon will automatically use the correct element of this union depending +on what the corresponding non-terminal or terminal symbol is. But +the grammar designer should keep in mind that the size of the union +will be the size of its largest element. So if you have a single +non-terminal whose data type requires 1K of storage, then your 100 +entry parser stack will require 100K of heap space. If you are willing +and able to pay that price, fine. You just need to know.

+ +

Error Processing

+ +

After extensive experimentation over several years, it has been +discovered that the error recovery strategy used by yacc is about +as good as it gets. And so that is what Lemon uses.

+ +

When a Lemon-generated parser encounters a syntax error, it +first invokes the code specified by the %syntax_error directive, if +any. It then enters its error recovery strategy. The error recovery +strategy is to begin popping the parsers stack until it enters a +state where it is permitted to shift a special non-terminal symbol +named ``error''. It then shifts this non-terminal and continues +parsing. But the %syntax_error routine will not be called again +until at least three new tokens have been successfully shifted.

+ +

If the parser pops its stack until the stack is empty, and it still +is unable to shift the error symbol, then the %parse_failed routine +is invoked and the parser resets itself to its start state, ready +to begin parsing a new file. This is what will happen at the very +first syntax error, of course, if there are no instances of the +``error'' non-terminal in your grammar.

+ + + diff --git a/Puma/examples/Makefile b/Puma/examples/Makefile new file mode 100644 index 0000000..32f087a --- /dev/null +++ b/Puma/examples/Makefile @@ -0,0 +1,19 @@ +#------------------------------------------------- +# variables +#------------------------------------------------- + +SUBDIRS := $(shell find $(shell pwd) -maxdepth 1 -mindepth 1 -type d) +SUBDIRS := $(filter-out %/.svn %/CVS, $(SUBDIRS)) +SUBDIRS := $(SUBDIRS) + +#------------------------------------------------- +# rules +#------------------------------------------------- + +all: $(SUBDIRS) +clean: $(SUBDIRS) + +$(SUBDIRS): + @$(MAKE) -C $@ $(MAKECMDGOALS) + +.PHONY: all clean $(SUBDIRS) diff --git a/Puma/examples/annotator/Makefile b/Puma/examples/annotator/Makefile new file mode 100644 index 0000000..9529711 --- /dev/null +++ b/Puma/examples/annotator/Makefile @@ -0,0 +1,103 @@ +#------------------------------------------------- +# variables +#------------------------------------------------- + +PROG := annotator +ROOT := $(shell pwd)/../.. +TARGET ?= linux-release + +OBJDIR := obj +DEPDIR := dep +GENDIR := gen +INCDIR := $(ROOT)/include $(ROOT)/extern $(GENDIR) +LIBDIR := $(ROOT)/lib/$(TARGET) + +ifeq ($(MAKELEVEL),0) + +SOURCES := $(wildcard *.ora) +OBJECTS := $(addprefix $(GENDIR)/,$(SOURCES:.ora=.ot)) + +else + +SOURCES := $(wildcard *.cc) +OBJECTS := $(addprefix $(OBJDIR)/,$(SOURCES:.cc=.o)) +DEPS := $(addprefix $(DEPDIR)/,$(SOURCES:.cc=.d)) + +include $(ROOT)/vars.mk + +CPPFLAGS += $(CXXFLAGS) $(addprefix -I,$(INCDIR)) + +endif + +#------------------------------------------------- +# rules +#------------------------------------------------- + +ifeq ($(MAKELEVEL),0) + +all: $(OBJECTS) + @$(MAKE) + +else + +all: showinfo $(PROG) + +showinfo: + @echo + @echo "---" + @echo "Compiling $(PROG) for TARGET=$(TARGET)" + @echo " Compiler = $(CXX) $(CPPFLAGS) $(CXXFLAGS)" + @echo " Linker = $(CXX) $(CXXFLAGS) $(LDFLAGS)" + @echo "---" + @echo + +$(PROG): $(OBJECTS) + @echo "Linking $@..." + export LD_LIBRARY_PATH=$(LIBDIR); \ + $(CXX) -o $@ $^ -L$(LIBDIR) $(CXXFLAGS) -Wl,-Bstatic -lPuma -Wl,-Bdynamic $(CPPFLAGS) +# $(CXX) -o $@ $^ -L$(LIBDIR) $(CXXFLAGS) -Wl,-Bdynamic -lPuma -Wl,-Bdynamic $(CPPFLAGS) + +endif + +clean: + @echo "Making $(PROG) clean..." + @rm -f $(PROG) + @rm -rf $(DEPDIR) $(OBJDIR) $(GENDIR) + +#------------------------------------------------- +# targets +#------------------------------------------------- + +ifeq ($(MAKELEVEL),0) + +$(GENDIR)/%.ot : %.ora + @echo "Generating $@..." + @mkdir -p $(GENDIR) + @$(ROOT)/tools/orange/orange $< >> $@ + +else + +$(OBJDIR)/%.o : %.cc + @echo "Compiling $(filter %.cc,$^)..." + @mkdir -p $(OBJDIR) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -g -o $@ $(filter %.cc,$^) + +$(DEPDIR)/%.d : %.cc + @echo "Generating dependencies for $(filter %.cc,$^)..." + @mkdir -p $(DEPDIR) + @$(CXX) $(CPPFLAGS) $(CXXFLAGS) -MM $(filter %.cc,$^) | \ + sed -e "s/$*\.o/$(OBJDIR)\/& $(DEPDIR)\/$*.d/g" > $@ + +endif + +.PHONY: clean + +#------------------------------------------------- +# includes +#------------------------------------------------- + +ifneq ($(MAKELEVEL),0) +ifneq ($(MAKECMDGOALS),clean) +-include $(DEPS) +endif +endif diff --git a/Puma/examples/annotator/Transformer.cc b/Puma/examples/annotator/Transformer.cc new file mode 100644 index 0000000..c7ccbe4 --- /dev/null +++ b/Puma/examples/annotator/Transformer.cc @@ -0,0 +1,62 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 +#include +#include +#include "Transformer.h" + + +Transformer::Transformer(Puma::ErrorStream& err) : m_Err(err) { +} + + +void Transformer::transform(Puma::CTree* node) { + // Visit the syntax tree top-down. + visit(node); +} + + +// Overwrite pre_visit(...) from Puma::CVisitor +// that is called before a subtree is visited. +void Transformer::pre_visit(Puma::CTree* node) { + // Match if and if-else statements. + if (node->NodeName() == Puma::CT_IfStmt::NodeId() || + node->NodeName() == Puma::CT_IfElseStmt::NodeId()) { + // Insert the command before the statement. + insertComment(node); + } +} + + +// Overwrite pre_visit(...) from Puma::CVisitor +// that is called before a subtree is visited. +void Transformer::insertComment(Puma::CTree* node) { + // Get the first token of the statement, i.e. the 'if'. + Puma::Token* token_if = node->token(); + + // Scan the commant tokens. + Puma::CUnit comment(m_Err); + comment.name(token_if->location().filename().name()); + comment << "/* " << token_if->location() << " */ " << Puma::endu; + + // Insert the comment tokens before the 'if' token. + Puma::ManipCommander mc; + mc.paste_before(token_if, &comment); + mc.commit(); +} diff --git a/Puma/examples/annotator/Transformer.h b/Puma/examples/annotator/Transformer.h new file mode 100644 index 0000000..c3980ab --- /dev/null +++ b/Puma/examples/annotator/Transformer.h @@ -0,0 +1,47 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __Transformer_h__ +#define __Transformer_h__ + +#include +#include +#include + + +// Transform the source code on syntax tree level. +class Transformer : private Puma::CVisitor { + Puma::ErrorStream& m_Err; + +private: + // Insert the comment before the first token of + // the matched syntax tree node. + void insertComment(Puma::CTree *node); + +protected: + // Overwrite pre_visit(...) from Puma::CVisitor + // that is called before a subtree is visited. + void pre_visit(Puma::CTree* node); + +public: + Transformer(Puma::ErrorStream& err); + void transform(Puma::CTree* node); +}; + + +#endif /* __Transformer_h__ */ diff --git a/Puma/examples/annotator/annotator.cc b/Puma/examples/annotator/annotator.cc new file mode 100644 index 0000000..c0a66e8 --- /dev/null +++ b/Puma/examples/annotator/annotator.cc @@ -0,0 +1,105 @@ +#include "Transformer.h" +#include +#include +#include +//#include +//#include +//#include +//#include +#include + + +int main(int argc, char** argv) { + // This is the error stream object used throughout + // the whole system, it supports several error + // severities and auto-formatted error location + // output. + Puma::ErrorStream err; + + // The project handles all file related task like + // finding, opening, writing, and closing files. + // The special CProject additionally is able to + // scan files and strings, i.e. it provides an easy + // to use interface to the lexical analyzer (scanner). + Puma::CProject project(err, argc, argv); + // Set the initial source/destination path pair. If + // a file shall be written using the project it is + // first checked if this file is located in one of + // source paths known to the project. If not, the file + // is not written. This mechanism is necessary to + // avoid system headers to be overwritten (except for + // the case that the corresponding system include + // path is added as a source path). + project.addPath(".", "."); + + // Check the arguments, need an input file. + if (argc != 2) { + std::cout << "Usage: " << argv[0] << " FILE" << std::endl; + return 1; + } + + // Scan the input file. The result is a token list + // representation of the input file. + Puma::Unit* unit = project.scanFile(argv[1]); + if (! unit) { + std::cerr << "Aborted: Unable to scan input file" << std::endl; + return 1; + } + + // After the input file was successfully scanned, it is + // now tried to parse it. The result is the so-called + // translation unit encapsulating the preprocessor, + // syntax, and semantic trees. + Puma::CCParser parser; + Puma::CTranslationUnit* tu = parser.parse(*unit, project); + + if (tu->tree()) { + // During the parsing of the input file only those + // semantic analyses are performed that are necessary + // to build the correct syntax tree and to recognize + // the correct types. Expression evaluation and so on + // is performed in an additional sematic analysis. It + // is optional and not needed for this application. + //Puma::CCSemVisitor semantics(err); + //semantics.run(tu->tree()); + + // The generated syntax tree is an attributed syntax + // tree referring to both tokens and semantic information. + // It can be traversed using a corresponding tree visitor. + // Formatted printing of the tree is performed by the + // CPrintVisitor tree visitor. + //CPrintVisitor cprinter; + //cprinter.print(tu->tree(), std::cout); + + // The collected semantic information also is organized + // as a tree reflecting the scope structure of the parsed + // code. The interface to the semantic tree is the class + // CSemDatabase. It can also be used to print this tree. + //tu->db().Dump(std::cout, 10); + + // Now transform the "if" statements so that a comment + // exists before every "if" statement. + Transformer transformer(err); + transformer.transform(tu->tree()); + + // At last the transformed unit has to be saved as file + // again. This is also realized using the project class. + // The original file shall be renamed to filename.bak + // before the transformed version of this file is written. + project.saveMode(Puma::SaveMode::RENAME_OLD, ".bak"); + project.save(unit); + } + if (tu->cpp_tree()) { + // Beside the syntax and semantic trees there is also + // a separate tree for the preprocessor directives. + // This tree can be printed using the PrePrintVisitor. + //Puma::PrePrintVisitor preprinter; + //tu->cpp_tree()->accept(preprinter); + } + + // Clean up. + delete tu; + + // Return 1 if errors or fatal errors occurred. + return err.severity() > Puma::sev_warning ? 1 : 0; +} diff --git a/Puma/examples/annotator/example.cpp b/Puma/examples/annotator/example.cpp new file mode 100644 index 0000000..4d447e7 --- /dev/null +++ b/Puma/examples/annotator/example.cpp @@ -0,0 +1,58 @@ +#include + +int prod(int m, int n) { + if (m > n) + return -1; + int prod = m; + do { + m++; + prod *= m; + } while (m < n); + return prod; +} + +int prod_r(int m, int n) { + if (m > n) + return -1; + if (m == n-1) + return m * n; + else + return m * prod_r(++m, n); +} + +int fac(int n) { + int fac = n; + while (n > 1) { + n--; + fac *= n; + } + return fac; +} + +int fac_r(int n) { + if (n == 0) + return 1; + return n * fac_r(--n); +} + +int binom1(int m, int n) { + if (m < n) + return 0; + return fac(m) / (fac(n) * fac(m-n)); +} + +int binom2(int m, int n) { + return prod(n, m) * (m-n + 1) / fac(n); +} + + +int main() { + int x = 2, y = 4; + std::cout << "Product: " << prod(x,y) << std::endl; + std::cout << "Product: " << prod_r(x,y) << std::endl; + std::cout << "Faculty: " << fac(x) << std::endl; + std::cout << "Faculty: " << fac_r(x) << std::endl; + std::cout << "Binom 1: " << binom1(y,x) << std::endl; + std::cout << "Binom 2: " << binom2(y,x) << std::endl; + return 0; +} diff --git a/Puma/examples/ccparser/IncludeVisitor.cc b/Puma/examples/ccparser/IncludeVisitor.cc new file mode 100644 index 0000000..e8aaed8 --- /dev/null +++ b/Puma/examples/ccparser/IncludeVisitor.cc @@ -0,0 +1,34 @@ +#include "IncludeVisitor.h" +#include "Puma/PreTreeToken.h" +#include "Puma/PreSonIterator.h" +#include + +using namespace Puma; + + +IncludeVisitor::~IncludeVisitor () { + for (int i = 0; i < _struct.length (); i++) + _struct[i] = (const char*)0; +} + +void IncludeVisitor::iterateNodes (PreTree *node) { + PreSonIterator i (node); + for (i.first (); ! i.isDone (); i.next ()) + i.currentItem ()->accept (*this); +} + +void IncludeVisitor::visitPreIncludeDirective_Pre (PreIncludeDirective *node) { + + // if there is no semantic node this include directive was never + // executed (maybe a FALSE conditional branch) + if (! node->daughters () || ! ((PreInclSemNode*)(node->daughter (0)))->unit ()) + return; + + // print "depth" spaces + for (int i = 0; i < node->depth (); i++) + *_os << " "; + + // print the name of the file included (to find in the semantic node) + *_os << ((PreInclSemNode*)(node->daughter (0)))->unit ()->name () + << endl; +} diff --git a/Puma/examples/ccparser/IncludeVisitor.h b/Puma/examples/ccparser/IncludeVisitor.h new file mode 100644 index 0000000..333c83e --- /dev/null +++ b/Puma/examples/ccparser/IncludeVisitor.h @@ -0,0 +1,33 @@ +#ifndef __INCLUDE_VISITOR__ +#define __INCLUDE_VISITOR__ + +// Visitor to print the name of each file included. + +#include "Puma/PreVisitor.h" +#include "Puma/PreTreeNodes.h" +#include "Puma/Array.h" +#include +using namespace std; + +using namespace Puma; + + +class IncludeVisitor : public PreVisitor { + ostream *_os; + long _length; + + // array of include file names to get the inclusion depth + Array _struct; + +public: + IncludeVisitor (ostream &os = cout) : _os (&os), _length (0) {} + virtual ~IncludeVisitor (); + + void iterateNodes (PreTree *); + +public: + // called on visit of the include directive node + void visitPreIncludeDirective_Pre (PreIncludeDirective *); +}; + +#endif /* __INCLUDE_VISITOR__ */ diff --git a/Puma/examples/ccparser/Makefile b/Puma/examples/ccparser/Makefile new file mode 100644 index 0000000..8522644 --- /dev/null +++ b/Puma/examples/ccparser/Makefile @@ -0,0 +1,74 @@ +#------------------------------------------------- +# variables +#------------------------------------------------- + +PROG := ccparser + +ROOT ?= $(shell pwd)/../.. +TARGET ?= linux-release + +INCDIR := $(ROOT)/include +LIBDIR := $(ROOT)/lib/$(TARGET) +EXTDIR := $(ROOT)/extern +OBJDIR := obj +DEPDIR := dep + +SOURCES := $(wildcard *.cc) +OBJECTS := $(addprefix $(OBJDIR)/,$(SOURCES:.cc=.o)) +DEPS := $(addprefix $(DEPDIR)/,$(SOURCES:.cc=.d)) + +include $(ROOT)/vars.mk + +CPPFLAGS := $(CPPFLAGS) -I$(INCDIR) -I$(EXTDIR) +#-L$(LIBDIR) + +#------------------------------------------------- +# rules +#------------------------------------------------- + +all: showinfo $(PROG) + +showinfo: + @echo + @echo "---" + @echo "Compiling $(PROG) for TARGET=$(TARGET)" + @echo " Compiler = $(CXX) $(CPPFLAGS) $(CXXFLAGS)" + @echo " Linker = $(CXX) $(CXXFLAGS) $(LDFLAGS)" + @echo "---" + @echo + +$(PROG): $(OBJECTS) + @echo "Linking $@..." + @export LD_LIBRARY_PATH=$(LIBDIR); \ + $(CXX) -o $@ $^ $(CXXFLAGS) -L$(LIBDIR) -Wl,-Bstatic -lPuma -Wl,-Bdynamic $(CPPFLAGS) +# $(CXX) -o $@ $^ $(CXXFLAGS) -L$(LIBDIR) -Wl,-Bdynamic -lPuma -Wl,-Bdynamic $(CPPFLAGS) + +clean: + @echo "Making $(PROG) clean..." + @rm -f $(PROG) + @rm -rf $(DEPDIR) $(OBJDIR) + +#------------------------------------------------- +# targets +#------------------------------------------------- + +$(OBJDIR)/%.o : %.cc + @echo "Compiling $(filter %.cc,$^)..." + @mkdir -p $(OBJDIR) + @$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -g -o $@ $(filter %.cc,$^) + +$(DEPDIR)/%.d : %.cc + @echo "Generating dependencies for $(filter %.cc,$^)..." + @mkdir -p $(DEPDIR) + @$(CXX) $(CPPFLAGS) $(CXXFLAGS) -MM $(filter %.cc,$^) | \ + sed -e "s/$*\.o/$(OBJDIR)\/& $(DEPDIR)\/$*.d/g" > $@ + +.PHONY: clean + +#------------------------------------------------- +# includes +#------------------------------------------------- + +ifneq ($(MAKECMDGOALS),clean) +-include $(DEPS) +endif diff --git a/Puma/examples/ccparser/ccparser.cc b/Puma/examples/ccparser/ccparser.cc new file mode 100644 index 0000000..5a48099 --- /dev/null +++ b/Puma/examples/ccparser/ccparser.cc @@ -0,0 +1,159 @@ +#include "IncludeVisitor.h" +#include "Puma/version.h" +#include "Puma/CCParser.h" +#include "Puma/ErrorStream.h" +#include "Puma/CCSemVisitor.h" +#include "Puma/CPrintVisitor.h" +#include "Puma/PrePrintVisitor.h" +#include "Puma/CTranslationUnit.h" +#include +using namespace std; + +/*DEBUG*/#include + +using namespace Puma; + + +namespace Puma { +/*DEBUG*/extern int TRACE_TYPE; // created types +/*DEBUG*/extern int TRACE_UNDO; // deleted syntax trees +/*DEBUG*/extern int TRACE_OBJS; // inserted/deleted sem objects +/*DEBUG*/extern int TRACE_FCT; // current function +/*DEBUG*/extern int TRACE_SCOPES; // entered/leaved scopes +/*DEBUG*/extern int TRACE_INSTANCE_CODE; // instance code +/*DEBUG*/extern int SEM_DECL_SPECS; // created - deleted CSemDeclSpecs +} + +static bool TRACE_STDOUT = false; +static bool TRACE_FILE = false; +static bool TRACE_TOKENS = false; +static bool DO_SEMANTICS = true; +static bool PRINT_TREE = true; +static bool PRINT_DB = true; +static bool PRINT_DEP = false; +static int ONLY_PRE = 0; + +void evalOptions (int argc, char **argv) { + if (argc < 2) { + cout << "PUMA C++ parser, library version " << PUMA_VERSION << endl; + cout << "usage: ccparser [options] " << endl; + cout << "options:" << endl; + cout << " -tr|--trace trace parse process, write to stdout" << endl; + cout << " -tf|--trace-file trace parse process, write to debug/trace.file" << endl; + cout << " -tt|--trace-tokens trace parsing tokens too" << endl; + cout << " -ts|--trace-scopes trace entered/leaved scopes" << endl; + cout << " -to|--trace-objs trace inserted/destroyed semantic objects" << endl; + cout << " -tu|--trace-undo trace deleted syntax tree nodes" << endl; + cout << " -tc|--trace-types trace created types" << endl; + cout << " -ti|--trace-instances trace code of created instances" << endl; + cout << " -nd|--no-print-db do not print the class database" << endl; + cout << " -nt|--no-print-tree do not print the syntax tree" << endl; + cout << " -ns|--no-semantics do not start the semantic process" << endl; + cout << " -E write preprocessor output to stdout" << endl; + cout << " -M print dependencies" << endl; + cout << " -Q preprocess without output" << endl; + exit (1); + } + for (int i = 1; i < argc-1; i++) { + const char *arg = argv[i]; + if (! strcmp (arg, "-tr") || ! strcmp (arg, "--trace")) + TRACE_STDOUT = (TRACE_FILE = false, true); + else if (! strcmp (arg, "-tf") || ! strcmp (arg, "--trace-file")) + TRACE_FILE = (TRACE_STDOUT = false, true); + else if (! strcmp (arg, "-tt") || ! strcmp (arg, "--trace-tokens")) + TRACE_TOKENS = ((! TRACE_FILE && (TRACE_STDOUT = true)), true); + else if (! strcmp (arg, "-ts") || ! strcmp (arg, "--trace-scopes")) + TRACE_SCOPES = 1; + else if (! strcmp (arg, "-to") || ! strcmp (arg, "--trace-objs")) + TRACE_OBJS = 1; + else if (! strcmp (arg, "-tu") || ! strcmp (arg, "--trace-undo")) + TRACE_UNDO = 1; + else if (! strcmp (arg, "-tc") || ! strcmp (arg, "--trace-types")) + TRACE_TYPE = 1; + else if (! strcmp (arg, "-ti") || ! strcmp (arg, "--trace-instances")) + TRACE_INSTANCE_CODE = 1; + else if (! strcmp (arg, "-nd") || ! strcmp (arg, "--no-print-db")) + PRINT_DB = false; + else if (! strcmp (arg, "-nt") || ! strcmp (arg, "--no-print-tree")) + PRINT_TREE = false; + else if (! strcmp (arg, "-ns") || ! strcmp (arg, "--no-semantics")) + DO_SEMANTICS = false; + else if (! strcmp (arg, "-E")) + ONLY_PRE = 1; + else if (! strcmp (arg, "-M")) { + ONLY_PRE = 2; // no preprocessor output + PRINT_DEP = true; + } + else if (! strcmp (arg, "-Q")) + ONLY_PRE = 2; // no preprocessor output + } +} + +int run (int argc, char **argv) { + ErrorStream err; + CProject project (err, argc, argv); + evalOptions (argc, argv); + + Unit *unit = project.scanFile (argv[argc-1]); + if (! unit) { + cout << "Aborted: Unable to scan input file" << endl; + return 1; + } + + CCParser parser; + ofstream *fout = 0; +#ifdef __PUMA_TRACING__ + if (TRACE_STDOUT) + parser.trace (cout, TRACE_TOKENS); // trace the parse process + else if (TRACE_FILE) { + fout = new ofstream ("debug/trace.file"); + parser.trace (*fout, TRACE_TOKENS); // trace the parse process + } +#endif + + cout << "Starting parse process..." << endl; + CTranslationUnit *tu = parser.parse (*unit, project, ONLY_PRE); + + if (tu->tree ()) { + if (DO_SEMANTICS) { + CCSemVisitor semantics (err); + cout << "Starting semantic analysis..." << endl; + semantics.run (tu->tree ()); + } + if (PRINT_TREE) { + CPrintVisitor printer; + cout << "Printing syntax tree..." << endl; + printer.print (tu->tree (), cout); + } + if (PRINT_DB) { + cout << "Printing semantic database..." << endl; + tu->db ().Dump (cout, 10); + } + // print dependency information + } else if (PRINT_DEP && tu->cpp_tree ()) { + IncludeVisitor visitor; + tu->cpp_tree ()->accept (visitor); + } else + cout << "Note: Empty program" << endl; + + if (err.severity () > sev_warning) + cout << "Errors!" << endl; + else if (err.severity () > sev_none) + cout << "Warnings!" << endl; + else + cout << "No errors" << endl; + + delete tu; + if (fout) delete fout; + + return err.severity () > sev_warning; +} + +int main (int argc, char **argv) { + int ret = run (argc, argv); +#ifndef NDEBUG + /*DEBUG*/cout << "Statistics: +" << CTree::alloc << " -" << CTree::release << endl; + /*DEBUG*/if (SEM_DECL_SPECS) cerr<<"WARNING: "< $(LDFLAGS)" + @echo "---" + @echo + +$(PROG): $(OBJECTS) + @echo "Linking $@..." + @export LD_LIBRARY_PATH=$(LIBDIR); \ + $(CXX) -o $@ $^ -L$(LIBDIR) $(CXXFLAGS) -Wl,-Bstatic -lPuma -Wl,-Bdynamic $(CPPFLAGS) +# $(CXX) -o $@ $^ -L$(LIBDIR) $(CXXFLAGS) -Wl,-Bdynamic -lPuma -Wl,-Bdynamic $(CPPFLAGS) + +clean: + @echo "Making $(PROG) clean..." + @rm -f $(PROG) + @rm -rf $(DEPDIR) $(OBJDIR) + +#------------------------------------------------- +# targets +#------------------------------------------------- + +$(OBJDIR)/%.o : %.cc + @echo "Compiling $(filter %.cc,$^)..." + @mkdir -p $(OBJDIR) + @$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -g -o $@ $(filter %.cc,$^) + +$(DEPDIR)/%.d : %.cc + @echo "Generating dependencies for $(filter %.cc,$^)..." + @mkdir -p $(DEPDIR) + @$(CXX) $(CPPFLAGS) $(CXXFLAGS) -MM $(filter %.cc,$^) | \ + sed -e "s/$*\.o/$(OBJDIR)\/& $(DEPDIR)\/$*.d/g" > $@ + +.PHONY: clean + +#------------------------------------------------- +# includes +#------------------------------------------------- + +ifneq ($(MAKECMDGOALS),clean) +-include $(DEPS) +endif diff --git a/Puma/examples/cparser/cparser.cc b/Puma/examples/cparser/cparser.cc new file mode 100644 index 0000000..d28633b --- /dev/null +++ b/Puma/examples/cparser/cparser.cc @@ -0,0 +1,133 @@ +#include "Puma/CParser.h" +#include "Puma/ErrorStream.h" +#include "Puma/CSemVisitor.h" +#include "Puma/CPrintVisitor.h" +#include "Puma/CTranslationUnit.h" +#include +using namespace std; + +/*DEBUG*/#include + +using namespace Puma; + +namespace Puma { +/*DEBUG*/extern int TRACE_TYPE; // created types +/*DEBUG*/extern int TRACE_UNDO; // deleted syntax trees +/*DEBUG*/extern int TRACE_OBJS; // inserted/deleted sem objects +/*DEBUG*/extern int TRACE_FCT; // current function +/*DEBUG*/extern int TRACE_SCOPES; // entered/leaved scopes +/*DEBUG*/extern int SEM_DECL_SPECS; // created - deleted CSemDeclSpecs +} + +static bool TRACE_STDOUT = false; +static bool TRACE_FILE = false; +static bool TRACE_TOKENS = false; +static bool DO_SEMANTICS = true; +static bool PRINT_TREE = true; +static bool PRINT_DB = true; +static int ONLY_PRE = 0; + +void evalOptions (int argc, char **argv) { + if (argc < 2) { + cout << "usage: cparser [options] " << endl; + cout << "options:" << endl; + cout << " -tr|--trace trace parse process, write to stdout" << endl; + cout << " -tf|--trace-file trace parse process, write to debug/trace.file" << endl; + cout << " -tt|--trace-tokens trace parsing tokens too" << endl; + cout << " -ts|--trace-scopes trace entered/leaved scopes" << endl; + cout << " -to|--trace-objs trace inserted/destroyed semantic objects" << endl; + cout << " -tu|--trace-undo trace deleted syntax tree nodes" << endl; + cout << " -tc|--trace-types trace created types" << endl; + cout << " -nd|--no-print-db do not print the class database" << endl; + cout << " -nt|--no-print-tree do not print the syntax tree" << endl; + cout << " -ns|--no-semantics do not start the semantic process" << endl; + cout << " -E write preprocessor output to stdout" << endl; + exit (1); + } + for (int i = 1; i < argc-1; i++) { + const char *arg = argv[i]; + if (! strcmp (arg, "-tr") || ! strcmp (arg, "--trace")) + TRACE_STDOUT = (TRACE_FILE = false, true); + else if (! strcmp (arg, "-tf") || ! strcmp (arg, "--trace-file")) + TRACE_FILE = (TRACE_STDOUT = false, true); + else if (! strcmp (arg, "-tt") || ! strcmp (arg, "--trace-tokens")) + TRACE_TOKENS = ((! TRACE_FILE && (TRACE_STDOUT = true)), true); + else if (! strcmp (arg, "-ts") || ! strcmp (arg, "--trace-scopes")) + TRACE_SCOPES = 1; + else if (! strcmp (arg, "-to") || ! strcmp (arg, "--trace-objs")) + TRACE_OBJS = 1; + else if (! strcmp (arg, "-tu") || ! strcmp (arg, "--trace-undo")) + TRACE_UNDO = 1; + else if (! strcmp (arg, "-tc") || ! strcmp (arg, "--trace-types")) + TRACE_TYPE = 1; + else if (! strcmp (arg, "-nd") || ! strcmp (arg, "--no-print-db")) + PRINT_DB = false; + else if (! strcmp (arg, "-nt") || ! strcmp (arg, "--no-print-tree")) + PRINT_TREE = false; + else if (! strcmp (arg, "-ns") || ! strcmp (arg, "--no-semantics")) + DO_SEMANTICS = false; + else if (! strcmp (arg, "-E")) + ONLY_PRE = 1; + } +} + +int main (int argc, char **argv) { + ErrorStream err; + CProject project (err, argc, argv); + evalOptions (argc, argv); + + // language C mode + project.config ().Add ("--lang-c"); + project.configure (project.config ()); + + Unit *unit = project.scanFile (argv[argc-1]); + if (! unit) { + cout << "Aborted: Unable to scan input file" << endl; + exit (1); + } + + CParser parser; + ofstream *fout = 0; +#ifdef __PUMA_TRACING__ + if (TRACE_STDOUT) + parser.trace (cout, TRACE_TOKENS); // trace the parse process + else if (TRACE_FILE) { + fout = new ofstream ("debug/trace.file"); + parser.trace (*fout, TRACE_TOKENS); // trace the parse process + } +#endif + + cout << "Starting parse process..." << endl; + CTranslationUnit *tu = parser.parse (*unit, project, ONLY_PRE); + + if (tu->tree ()) { + if (DO_SEMANTICS) { + CSemVisitor semantics (err); + cout << "Starting semantic analysis..." << endl; + semantics.run (tu->tree ()); + } + if (PRINT_TREE) { + CPrintVisitor printer; + cout << "Printing syntax tree..." << endl; + printer.print (tu->tree (), cout); + } + if (PRINT_DB) { + cout << "Printing semantic database..." << endl; + tu->db ().Dump (cout, 2); + } + } else + cout << "Note: Empty program" << endl; + + if (err.severity () > sev_warning) + cout << "Errors!" << endl; + else if (err.severity () > sev_none) + cout << "Warnings!" << endl; + else + cout << "No errors" << endl; + + delete tu; + if (fout) delete fout; + /*DEBUG*/cout << "Statistics: +" << CTree::alloc << " -" << CTree::release << endl; + /*DEBUG*/if (SEM_DECL_SPECS) cerr<<"WARNING: "< sev_warning; +} diff --git a/Puma/examples/macronames/Makefile b/Puma/examples/macronames/Makefile new file mode 100644 index 0000000..0714c11 --- /dev/null +++ b/Puma/examples/macronames/Makefile @@ -0,0 +1,74 @@ +#------------------------------------------------- +# variables +#------------------------------------------------- + +PROG := macronames + +ROOT ?= $(shell pwd)/../.. +TARGET ?= linux-release + +INCDIR := $(ROOT)/include +EXTDIR := $(ROOT)/extern +LIBDIR := $(ROOT)/lib/$(TARGET) +OBJDIR := obj +DEPDIR := dep + +SOURCES := $(wildcard *.cc) +OBJECTS := $(addprefix $(OBJDIR)/,$(SOURCES:.cc=.o)) +DEPS := $(addprefix $(DEPDIR)/,$(SOURCES:.cc=.d)) + +include $(ROOT)/vars.mk + +CPPFLAGS := $(CPPFLAGS) -I$(INCDIR) -I$(EXTDIR) +#-L$(LIBDIR) + +#------------------------------------------------- +# rules +#------------------------------------------------- + +all: showinfo $(PROG) + +showinfo: + @echo + @echo "---" + @echo "Compiling $(PROG) for TARGET=$(TARGET)" + @echo " Compiler = $(CXX) $(CPPFLAGS) $(CXXFLAGS)" + @echo " Linker = $(CXX) $(CXXFLAGS) $(LDFLAGS)" + @echo "---" + @echo + +$(PROG): $(OBJECTS) + @echo "Linking $@..." + @export LD_LIBRARY_PATH=$(LIBDIR); \ + $(CXX) -o $@ $^ $(CXXFLAGS) -L$(LIBDIR) -Wl,-Bstatic -lPuma -Wl,-Bdynamic $(CPPFLAGS) +# $(CXX) -o $@ $^ $(CXXFLAGS) -L$(LIBDIR) -Wl,-Bdynamic -lPuma -Wl,-Bdynamic $(CPPFLAGS) + +clean: + @echo "Making $(PROG) clean..." + @rm -f $(PROG) + @rm -rf $(DEPDIR) $(OBJDIR) + +#------------------------------------------------- +# targets +#------------------------------------------------- + +$(OBJDIR)/%.o : %.cc + @echo "Compiling $(filter %.cc,$^)..." + @mkdir -p $(OBJDIR) + @$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -g -o $@ $(filter %.cc,$^) + +$(DEPDIR)/%.d : %.cc + @echo "Generating dependencies for $(filter %.cc,$^)..." + @mkdir -p $(DEPDIR) + @$(CXX) $(CPPFLAGS) $(CXXFLAGS) -MM $(filter %.cc,$^) | \ + sed -e "s/$*\.o/$(OBJDIR)\/& $(DEPDIR)\/$*.d/g" > $@ + +.PHONY: clean + +#------------------------------------------------- +# includes +#------------------------------------------------- + +ifneq ($(MAKECMDGOALS),clean) +-include $(DEPS) +endif diff --git a/Puma/examples/macronames/macronames.cc b/Puma/examples/macronames/macronames.cc new file mode 100644 index 0000000..76d152f --- /dev/null +++ b/Puma/examples/macronames/macronames.cc @@ -0,0 +1,78 @@ +#include "Puma/CCParser.h" +#include "Puma/ErrorStream.h" +#include "Puma/UnitIterator.h" +#include "Puma/CTokens.h" +#include "Puma/PreParser.h" +#include +#include +#include + +typedef std::set LineNumbers; +typedef std::map Macros; + + +int main (int argc, char **argv) { + if (argc < 2) { + std::cout << "Extract C preprocessor macro names from a file" << std::endl; + std::cout << "usage: macronames " << std::endl; + return 1; + } + + // scan input file + Puma::ErrorStream err; + Puma::CProject project(err, argc, argv); + Puma::Unit *file = project.scanFile(argv[argc-1]); + if (! file) { + std::cerr << argv[argc-1] << ": unable to scan input file" << std::endl; + return 1; + } + + // find macro names in the token lists of #if, #elseif, + // #ifdef, and #ifndef directives + Macros macros; + Puma::UnitIterator token(*file); + for (; *token; ++token) { + if (token->is_preprocessor()) { + int type = token->type(); + if (type == TOK_PRE_IF || type == TOK_PRE_ELIF) { + // search for identifiers, ignore special identifier "defined" + for (++token; *token; ++token) { + if (token->is_whitespace()) { + // white space, let's see if it is the end of the directive + const char *c = token->text(); + for (; *c && *c != '\n'; c++); + if (*c == '\n') { + // end of directive, stop searching for macro names + break; + } + } else if (token->is_identifier() && strcmp(token->text(), "defined") != 0) { + // macro name found + macros[token->text()].insert(token->location().line()); + } + } + } else if (type == TOK_PRE_IFDEF || type == TOK_PRE_IFNDEF) { + // skip comments and white spaces + for (++token; *token && (token->is_comment() || token->is_whitespace()); ++token); + if (*token && token->is_identifier()) { + // macro name found + macros[token->text()].insert(token->location().line()); + } + } + } + } + + // print the macro names and the line numbers where they are called (XML) + std::cout << "\n" << std::endl; + Macros::const_iterator macro = macros.begin(); + for (; macro != macros.end(); ++macro) { + std::cout << " first << "\">" << std::endl; + LineNumbers::const_iterator number = macro->second.begin(); + for (; number != macro->second.end(); ++number) { + std::cout << " " << *number << "" << std::endl; + } + std::cout << " " << std::endl; + } + std::cout << "" << std::endl; + + return 0; +} diff --git a/Puma/examples/parser/Makefile b/Puma/examples/parser/Makefile new file mode 100644 index 0000000..6c0f887 --- /dev/null +++ b/Puma/examples/parser/Makefile @@ -0,0 +1,73 @@ +#------------------------------------------------- +# variables +#------------------------------------------------- + +PROG := parser + +ROOT ?= $(shell pwd)/../.. +TARGET ?= linux-release + +INCDIR := $(ROOT)/include +LIBDIR := $(ROOT)/lib/$(TARGET) +OBJDIR := obj +DEPDIR := dep + +SOURCES := $(wildcard *.cc) +OBJECTS := $(addprefix $(OBJDIR)/,$(SOURCES:.cc=.o)) +DEPS := $(addprefix $(DEPDIR)/,$(SOURCES:.cc=.d)) + +include $(ROOT)/vars.mk + +CPPFLAGS := $(CPPFLAGS) -I$(ROOT)/extern -I$(INCDIR) -fno-stack-limit +#-L$(LIBDIR) + +#------------------------------------------------- +# rules +#------------------------------------------------- + +all: showinfo $(PROG) + +showinfo: + @echo + @echo "---" + @echo "Compiling $(PROG) for TARGET=$(TARGET)" + @echo " Compiler = $(CXX) $(CPPFLAGS) $(CXXFLAGS)" + @echo " Linker = $(CXX) $(CXXFLAGS) $(LDFLAGS)" + @echo "---" + @echo + +$(PROG): $(OBJECTS) + @echo "Linking $@..." + @export LD_LIBRARY_PATH=$(LIBDIR); \ + $(CXX) -o $@ $^ $(CXXFLAGS) -fno-stack-limit -L$(LIBDIR) -Wl,-Bstatic -lPuma -Wl,-Bdynamic $(CPPFLAGS) +# $(CXX) -o $@ $^ $(CXXFLAGS) -L$(LIBDIR) -Wl,-Bdynamic -lPuma -Wl,-Bdynamic $(CPPFLAGS) + +clean: + @echo "Making $(PROG) clean..." + @rm -f $(PROG) + @rm -rf $(DEPDIR) $(OBJDIR) + +#------------------------------------------------- +# targets +#------------------------------------------------- + +$(OBJDIR)/%.o : %.cc + @echo "Compiling $(filter %.cc,$^)..." + @mkdir -p $(OBJDIR) + @$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -g -o $@ $(filter %.cc,$^) + +$(DEPDIR)/%.d : %.cc + @echo "Generating dependencies for $(filter %.cc,$^)..." + @mkdir -p $(DEPDIR) + @$(CXX) $(CPPFLAGS) $(CXXFLAGS) -MM $(filter %.cc,$^) | \ + sed -e "s/$*\.o/$(OBJDIR)\/& $(DEPDIR)\/$*.d/g" > $@ + +.PHONY: clean + +#------------------------------------------------- +# includes +#------------------------------------------------- + +ifneq ($(MAKECMDGOALS),clean) +-include $(DEPS) +endif diff --git a/Puma/examples/parser/parser.cc b/Puma/examples/parser/parser.cc new file mode 100644 index 0000000..deea971 --- /dev/null +++ b/Puma/examples/parser/parser.cc @@ -0,0 +1,606 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef WIN32 +#include +#else +#include +#endif + + +namespace Puma { + extern int TRACE_TYPE; // trace created types + extern int TRACE_UNDO; // trace discarded subtrees + extern int TRACE_OBJS; // trace created and discarded semantic objects + extern int TRACE_SCOPES; // trace entered/leaved scopes + extern int TRACE_INSTANCE_CODE; // trace instance units + extern int TRACE_PARSE_INSTANCE; // trace parse instance units + extern int TRACE_CPP; // trace preprocessor +} + + +static bool verify_tree = false; +static bool lang_c = false; +static bool lang_cc = false; +static std::string input_file = ""; +static bool verbose = false; +static bool dump_cpp = false; +static std::string dump_cpp_file; +static int dump_db = 0; +static std::string dump_db_file; +static bool dump_unit = false; +static std::string dump_unit_file; +static bool dump_tree = false; +static std::string dump_tree_file; +static bool dump_cpp_tree = false; +static std::string dump_cpp_tree_file; +static bool trace_parse = false; +static std::string trace_parse_file; + + +void log(const std::string& message) { + if (verbose) { + time_t ltime; + time(<ime); + struct tm *today = localtime(<ime); + char buffer[128]; + strftime(buffer,127,"%b %d %H:%M:%S",today); + std::cout << "-- " << buffer << "."; +#ifdef WIN32 + timeb btime; + ftime(&btime); + std::cout << btime.millitm; +#else + struct timeval tv; + gettimeofday(&tv,0); + std::cout << tv.tv_usec/1000; +#endif + std::cout << ": " << message << std::endl; + } +} + + +void printError(Puma::ErrorStream& err, Puma::CTree* node, const std::string& message) { + if (node) { + Puma::Token* t = node->token(); + if (t) { + err << t->location(); + } + } + err << Puma::sev_error << message.c_str() << Puma::endMessage; +} + + +void printError(Puma::ErrorStream& err, const std::string& message) { + printError(err, 0, message); +} + + +std::ostream* openStream(const std::string& file) { + return file.empty() ? &std::cout : new std::ofstream(file.c_str()); +} + + +void closeStream(const std::string& file, std::ostream* os) { + if (! file.empty()) { + delete os; + } +} + + +void addCompilerConfig(Puma::ErrorStream& err, Puma::Config& config) { + // always set when Puma parses something, can be used + // to hide code from Puma's view + config.Add("-D", "__puma", true); + // signal that Puma prefers standard C code + config.Add("-D", "__STDC__", true); + + // command to get the configuration options from the compiler + std::string cmd; + if (lang_c) { + cmd = "gcc -E -dM -v -x c /dev/null 2>&1"; + } + else { + cmd = "g++ -E -dM -v -x c++ /dev/null 2>&1"; + } + // execute command to get the compiler config + Puma::PipedCmd pipedcmd; + pipedcmd.exec(cmd.c_str()); + + // parse the compiler config + std::istringstream in(pipedcmd.getOutput()); + if (! in) { + printError(err, "unable to read compiler configuration"); + printError(err, "command '"+cmd+"' failed"); + return; + } + + // regular expressions for matching includes and macros + Puma::RegComp regincl("#include [<\"].*:.*"); + Puma::RegComp reginlist("^ .*"); + Puma::RegComp regdef("#define .*"); + + // GNU compiler version + std::string gnu_major_version, gnu_minor_version, gnu_patchlevel; + + // read file line by line + bool in_include_list = false; + std::string line; + while (std::getline(in, line)) { + // start of list of include paths + if (regincl.match(line.c_str())) { + in_include_list = true; + // within a list of include paths + } else if (in_include_list && reginlist.match(line.c_str())) { + // strip leading white space + unsigned int pos = line.find_first_not_of(" "); + line = line.substr(pos); + + // convert '//*' to '/' + char lastchar = '0'; + for (std::string::iterator c = line.begin(); c != line.end(); ++c) { + if (lastchar == *c && *c == '/') { + c = line.erase(c); + --c; + } + lastchar = *c; + } + + // add the include path + config.Add("--isystem", line.c_str(), true); + // end of list of include paths + } else if (in_include_list) { + in_include_list = false; + // match a '#define ...' + } else if (regdef.match(line.c_str())) { + // remove '#define ' (8 characters) + line = line.substr(8); + + // split name and argument of macro + + // find name, split at first whitespace + std::string::size_type pos = line.find(" "); + std::string name = line.substr(0, pos); + + // set '1' as default argument if no argument is defined + std::string value = "1"; + + // find value, i.e. the string behind the macro name + if ((pos != std::string::npos) && (line.find_first_not_of(" ", pos) != std::string::npos)) { + value = line.substr(pos+1); + } + + // add the macro definition to the configuration + config.Add("-D", name.c_str(), value.c_str(), true); + + // GNU compiler major version + if (name == "__GNUC__") { + gnu_major_version = value; + // GNU compiler minor version + } else if (name == "__GNUC_MINOR__") { + gnu_minor_version = value; + // GNU compiler patchlevel + } else if (name == "__GNUC_PATCHLEVEL__") { + gnu_patchlevel = value; + // check for the size_t + } else if (name == "__SIZE_TYPE__") { + config.Add("--size-type", value.c_str(), true); + // check for the ptrdiff_t + } else if (name == "__PTRDIFF_TYPE__") { + config.Add("--ptrdiff-type", value.c_str(), true); + } + } + } + + // enable correct gcc support + if (! gnu_major_version.empty()) { + std::string version = gnu_major_version + "." + gnu_minor_version + "." + gnu_patchlevel; + config.Add("--gnu", version.c_str(), true); + } +} + + +void readOptionArg(int argc, char** argv, int& i, std::string& file) { + if (argc > (i+2) && argv[i+1][0] != '-') { + file = argv[++i]; + } +} + + +void printUsage(Puma::CProject& project) { + std::cout << "PUMA C/C++ Parser, v" << Puma::puma_version() << std::endl; + std::cout << "usage: parser [options] " << std::endl; + std::cout << "options:" << std::endl; + project.config().PrintOptions(std::cout); + std::cout << " --dump-db [FILE] Dump the semantic database to file or stdout" << std::endl; + std::cout << " --dump-db-all [FILE] Dump the semantic database incl. builtins to file or stdout" << std::endl; + std::cout << " --dump-tree [FILE] Dump the syntax tree to file or stdout" << std::endl; + std::cout << " --dump-unit [FILE] Dump the primary token unit to file or stdout" << std::endl; + std::cout << " --dump-cpp [FILE] Dump the C preprocessor output to file or stdout" << std::endl; + std::cout << " --dump-cpp-tree [FILE] Dump the C preprocessor syntax tree to file or stdout" << std::endl; + std::cout << " --dump-instances Dump the created template instances to stdout [debug]" << std::endl; + std::cout << " --trace-parse [FILE] Trace the parse process and write it to file or stdout [debug]" << std::endl; + std::cout << " --trace-cpp Trace the preprocessor and write it to stdout [debug]" << std::endl; + std::cout << " --trace-instances Trace parsing template instances and write it to stdout [debug]" << std::endl; + std::cout << " --trace-types Trace the created types and write it to stdout [debug]" << std::endl; + std::cout << " --trace-scopes Trace the entered scopes and write it to stdout [debug]" << std::endl; + std::cout << " --trace-objects Trace the created semantic opjects and write it to stdout [debug]" << std::endl; + std::cout << " --trace-undo-tree Trace the backtracking and write it to stdout [debug]" << std::endl; + std::cout << " --verify-tree Verify the syntax tree" << std::endl; + std::cout << " --default-path Add the path to the input file as source path" << std::endl; + std::cout << " --no-default-config Don't add the default configuration of the target compiler" << std::endl; + std::cout << " --help Show the usage information and exit" << std::endl; + std::cout << " -v Enable verbose logging" << std::endl; + exit(1); +} + + +void evalOptions(Puma::CProject& project, int argc, char **argv) { + // need usage information? + if (argc < 2) { + printUsage(project); + } + + // read additional command line options + bool default_path = false; + bool default_config = true; + for (int i = 1; i < argc; i++) { + std::string o = argv[i]; + if (o == "--help") { + printUsage(project); + } else if (o == "-v") { + verbose = true; + } else if (o == "--verify-tree") { + verify_tree = true; + } else if (o == "--default-path") { + default_path = true; + } else if (o == "--no-default-config") { + default_config = false; + } else if (o == "--dump-db") { + dump_db = 1; + readOptionArg(argc, argv, i, dump_db_file); + } else if (o == "--dump-db-all") { + dump_db = 2; + readOptionArg(argc, argv, i, dump_db_file); + } else if (o == "--dump-tree") { + dump_tree = true; + readOptionArg(argc, argv, i, dump_tree_file); + } else if (o == "--dump-unit") { + dump_unit = true; + readOptionArg(argc, argv, i, dump_unit_file); + } else if (o == "--dump-cpp") { + dump_cpp = true; + readOptionArg(argc, argv, i, dump_cpp_file); + } else if (o == "--dump-cpp-tree") { + dump_cpp_tree = true; + readOptionArg(argc, argv, i, dump_cpp_tree_file); + } else if (o == "--trace-parse") { + trace_parse = true; + readOptionArg(argc, argv, i, trace_parse_file); + } else if (o == "--trace-cpp") { + Puma::TRACE_CPP = 1; + } else if (o == "--trace-types") { + Puma::TRACE_TYPE = 1; + } else if (o == "--trace-scopes") { + Puma::TRACE_SCOPES = 1; + } else if (o == "--dump-instances") { + Puma::TRACE_INSTANCE_CODE = 1; + } else if (o == "--trace-instances") { + Puma::TRACE_PARSE_INSTANCE = 1; + } else if (o == "--trace-objects") { + Puma::TRACE_OBJS = 1; + } else if (o == "--trace-undo-tree") { + Puma::TRACE_UNDO = 1; + } + } + + // add compiler configuration + if (default_config) { + addCompilerConfig(project.err(),project.config()); + } + + // add command line options + project.config().Read(argc,argv); + + // evaluate options + lang_c = project.config().Option("--lang-c"); + lang_cc = project.config().Option("--lang-c++") || + project.config().Option("--lang-ac++"); + input_file = argc > 1 ? argv[argc-1] : ""; + + // get input language + if (! lang_c && ! lang_cc) { + std::string::size_type pos = input_file.rfind('.'); + if (pos != input_file.npos) { + std::string suffix = input_file.substr(pos+1); + if (suffix == "cc" || suffix == "cpp") { + lang_cc = true; + } + else if (suffix == "c") { + lang_c = true; + } + } + + // set input language + if (lang_c) { + project.config().Add("--lang-c", true); + } + else { + lang_cc = true; + project.config().Add("--lang-c++", true); + } + } + + if (default_path) { + // add the directory containing the current input file + // as source directory + std::string path = "."; + std::string::size_type pos = input_file.rfind("/"); + if (pos != std::string::npos) { + path = "/"; + if (pos != 0) { + path = input_file.substr(0, pos); + } + } + project.config().Add("-p", path.c_str(), true); + } + + // propagate the configuration + project.configure(project.config()); +} + + +Puma::CTranslationUnit* parseCFile(Puma::ErrorStream& err, Puma::CProject& project) { + // lexical analysis + log("lexical analysis"); + Puma::Unit *unit = project.scanFile(input_file.c_str()); + if (! unit) { + printError(err, "lexical analysis of input file failed"); + return 0; + } + + // dump unit + if (dump_unit) { + std::ostream* unit_os = openStream(dump_unit_file); + unit->print(*unit_os); + closeStream(dump_unit_file, unit_os); + } + + // syntactic analysis + log("syntactic analysis"); + Puma::CParser parser; + std::ostream* trace_os = openStream(trace_parse_file); + std::ostream* cpp_os = openStream(dump_cpp_file); + if (trace_parse) { +#ifdef __PUMA_TRACING__ + parser.trace(*trace_os, verbose); +#endif + } + Puma::CTranslationUnit* file = parser.parse(*unit, project, dump_cpp, *cpp_os); + closeStream(dump_cpp_file, cpp_os); + closeStream(trace_parse_file, trace_os); + + // semantic analysis + if (file && file->tree()) { + log("semantic analysis"); + Puma::CSemVisitor semantics(err); + semantics.run(file->tree()); + } + + return file; +} + + +Puma::CTranslationUnit* parseCCFile(Puma::ErrorStream& err, Puma::CProject& project) { + // lexical analysis + log("lexical analysis"); + Puma::Unit *unit = project.scanFile(input_file.c_str()); + if (! unit) { + return 0; + } + + // dump unit + if (dump_unit) { + std::ostream* unit_os = openStream(dump_unit_file); + unit->print(*unit_os); + closeStream(dump_unit_file, unit_os); + } + + // syntactic analysis + log("syntactic analysis"); + Puma::CCParser parser; + std::ostream* trace_os = openStream(trace_parse_file); + std::ostream* cpp_os = openStream(dump_cpp_file); + if (trace_parse) { +#ifdef __PUMA_TRACING__ + parser.trace(*trace_os, verbose); +#endif + } + Puma::CTranslationUnit* file = parser.parse(*unit, project, dump_cpp, *cpp_os); + closeStream(dump_cpp_file, cpp_os); + closeStream(trace_parse_file, trace_os); + + // semantic analysis + if (file && file->tree()) { + log("semantic analysis"); + Puma::CCSemVisitor semantics(err); + semantics.run(file->tree()); + } + + return file; +} + + +bool isDependent(Puma::CTree* node) { + // check if any sub expression of a given expression + // depends on a template parameter + if (node->Type() && node->Type()->isDependent()) { + return true; + } + // check the child nodes + unsigned sons = node->Sons(); + for (unsigned i = 0; i < sons; ++i) { + if (isDependent(node->Son(i))) { + return true; + } + } + return false; +} + + +std::string printTree(Puma::CTree* node) { + // print the tokens of a sub-tree + std::ostringstream s; + Puma::Token* token = node->token(); + Puma::Token* end = node->end_token(); + if (token && end) { + Puma::Unit* file = token->unit(); + while (token) { + s << token->text(); + if (token == end) { + break; + } + token = file->next(token); + } + } + return s.str(); +} + + +void walk(Puma::ErrorStream& err, Puma::CTree* node, Puma::CTree* parent = 0) { + if (! node) { + return; + } + // every node has to have a parent except the top level node + if (! node->Parent() && node->NodeName() != Puma::CT_Program::NodeId()) { + printError(err, node, node->NodeName()+std::string(" node has no parent")); + } + // parent - child relations must be correct + if (node->Parent() && node->Parent() != parent) { + printError(err, node, node->NodeName()+std::string(" node has wrong parent ")+node->Parent()->NodeName()); + } + // node indicating an error in the input file + if (node->NodeName() == Puma::CT_Error::NodeId()) { + printError(err, node, "error node found in tree"); + } + // all expressions shall have a type + else if (node->IsExpression() && ! node->Type()) { + if (! isDependent(node)) { + printError(err, node, "expression without type"); + } + } + // all expressions shall have a defined type + else if (node->IsExpression() && node->Type()->is_undefined()) { + if (! isDependent(node)) { + printError(err, node, "expression with undefined type"); + } + } + // all symbols shall be resolved + else if (node->IsSimpleName() && node->SemObject() && ! node->SemObject()->Object()) { + if (! isDependent(node)) { + printError(err, node, std::string("unresolved symbol "+printTree(node))); + } + } + // walk over the child nodes + else { + unsigned int sons = node->Sons(); + for (unsigned i = 0; i < sons; ++i) { + walk(err, node->Son(i), node); + } + } +} + + +int main(int argc, char **argv) { + Puma::ErrorStream err; + Puma::CProject project(err); + + evalOptions(project,argc,argv); + + // parse input file + Puma::CTranslationUnit* file = 0; + if (lang_c) { + file = parseCFile(err,project); + } + else if (lang_cc) { + file = parseCCFile(err,project); + } + + // dump the syntax tree + if (dump_tree && file && file->tree()) { + log("dump syntax tree"); + std::ostream* tree_os = openStream(dump_tree_file); + Puma::CPrintVisitor printer; + printer.configure(project.config()); + printer.print(file->tree(), *tree_os); + closeStream(dump_tree_file, tree_os); + } + + // dump the preprocessor syntax tree + if (dump_cpp_tree && file && file->cpp_tree()) { + log("dump preprocessor syntax tree"); + std::ostream* tree_os = openStream(dump_cpp_tree_file); + Puma::PrePrintVisitor printer(*tree_os); + file->cpp_tree()->accept(printer); + closeStream(dump_cpp_tree_file, tree_os); + } + + // dump the semantic database + if (dump_db && file) { + log("dump semantic information database"); + std::ostream* db_os = openStream(dump_db_file); + file->db().Dump(*db_os, 10, dump_db == 2); + closeStream(dump_db_file, db_os); + } + + // walk over the tree + if (verify_tree && file && file->tree()) { + log("verify syntax tree"); + walk(err, file->tree()); + } + + log("cleanup"); + if (file) { + delete file; + } + bool haveError = err.severity() > Puma::sev_warning; + Puma::DString::clearDict(); + + return haveError; +} diff --git a/Puma/examples/sync/Makefile b/Puma/examples/sync/Makefile new file mode 100644 index 0000000..177fd30 --- /dev/null +++ b/Puma/examples/sync/Makefile @@ -0,0 +1,72 @@ +#------------------------------------------------- +# variables +#------------------------------------------------- + +PROG := sync +ROOT := $(shell pwd)/../.. +TARGET ?= linux-release + +OBJDIR := obj +DEPDIR := dep +GENDIR := gen +INCDIR := $(ROOT)/include $(ROOT)/extern $(GENDIR) +LIBDIR := $(ROOT)/lib/$(TARGET) + +SOURCES := $(wildcard *.cc) +OBJECTS := $(addprefix $(OBJDIR)/,$(SOURCES:.cc=.o)) +DEPS := $(addprefix $(DEPDIR)/,$(SOURCES:.cc=.d)) + +include $(ROOT)/vars.mk + +CPPFLAGS += $(CXXFLAGS) $(addprefix -I,$(INCDIR)) + +#------------------------------------------------- +# rules +#------------------------------------------------- + +all: showinfo $(PROG) + +showinfo: + @echo + @echo "---" + @echo "Compiling $(PROG) for TARGET=$(TARGET)" + @echo " Compiler = $(CXX) $(CPPFLAGS) $(CXXFLAGS)" + @echo " Linker = $(CXX) $(CXXFLAGS) $(LDFLAGS)" + @echo "---" + @echo + +$(PROG): $(OBJECTS) + @echo "Linking $@..." + export LD_LIBRARY_PATH=$(LIBDIR); \ + $(CXX) -o $@ $^ -L$(LIBDIR) $(CXXFLAGS) -Wl,-Bstatic -lPuma -Wl,-Bdynamic $(CPPFLAGS) +# $(CXX) -o $@ $^ -L$(LIBDIR) $(CXXFLAGS) -Wl,-Bdynamic -lPuma -Wl,-Bdynamic $(CPPFLAGS) + +clean: + @echo "Making $(PROG) clean..." + @rm -f $(PROG) + @rm -rf $(DEPDIR) $(OBJDIR) $(GENDIR) + +#------------------------------------------------- +# targets +#------------------------------------------------- + +$(OBJDIR)/%.o : %.cc + @echo "Compiling $(filter %.cc,$^)..." + @mkdir -p $(OBJDIR) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -g -o $@ $(filter %.cc,$^) + +$(DEPDIR)/%.d : %.cc + @echo "Generating dependencies for $(filter %.cc,$^)..." + @mkdir -p $(DEPDIR) + @$(CXX) $(CPPFLAGS) $(CXXFLAGS) -MM $(filter %.cc,$^) | \ + sed -e "s/$*\.o/$(OBJDIR)\/& $(DEPDIR)\/$*.d/g" > $@ + +.PHONY: clean + +#------------------------------------------------- +# includes +#------------------------------------------------- + +ifneq ($(MAKECMDGOALS),clean) +-include $(DEPS) +endif diff --git a/Puma/examples/sync/README.txt b/Puma/examples/sync/README.txt new file mode 100644 index 0000000..de190f5 --- /dev/null +++ b/Puma/examples/sync/README.txt @@ -0,0 +1,134 @@ + + + Example + + "synchronized" + statement extension + + + + +INTRODUCTION +------------ + +The intention of this example is to demonstrate how to extend +the C++ parser. Thus it will be mainly shown how to extend the +lexical, syntactical, and semantical analysis. Additionally +two ways of manipulating parsed source code will be presented. + + +THE EXTENSION +------------- + +The extension to the C++ parser to realize is a new statement +protecting the enclosed sub-statements from being modified by +more than one thread. The syntax of the new statement looks as +follows: + + sync_stmt -> 'synchronized' '{' sub-statements '}' + | 'synchronized' '{' '}' + +It may be used for instance like this: + + void Log::write(const std::string &message) { + std::string entry = getCurrentTime(); + entry += ": "+getUserName(); + entry += ": "+message; + + synchronized { + std::ofstream logfile(m_File, std::ios::app); + logfile << entry << std::endl; + logfile.close(); + } + } + +The "synchronized" statement shall not open a new local scope, +i.e. the object "logfile" is to be introduced into the same scope +as the object "entry". Furthermore "synchronized" statements shall +not be nested. Otherwise an error message shall be generated. For +instance the following code: + + synchronized { + ... + synchronized { + ... + } + } + +shall cause the parser to show a message like this: + + file:3: error: synchronized statements cannot be nested + + +REALIZATION +----------- + +The protection of the enclosed statements shall be realized using +a pthread's mutex implementation. More precisely, the statement's +head shall be replaced by: + + pthread_mutex_t __mutex_n; + pthread_mutex_init(&__mutex_n, 0); + pthread_mutex_lock(&__mutex_n); + +and its tail by: + + pthread_mutex_unlock(&__mutex_n); + pthread_mutex_destroy(&__mutex_n); + +For instance the above code shall be transformed into: + + void Log::write(const std::string &message) { + std::string entry = getCurrentTime(); + entry += ": "+getUserName(); + entry += ": "+message; + + pthread_mutex_t __mutex_1; + pthread_mutex_init(&__mutex_1, 0); + pthread_mutex_lock(&__mutex_1); + + std::ofstream logfile(m_File, std::ios::app); + logfile << entry << std::endl; + logfile.close(); + + pthread_mutex_unlock(&__mutex_1); + pthread_mutex_destroy(&__mutex_1); + } + +Additionally an include directive for the system header pthread.h +has to be added to the input file. + + +IMPLEMENTATION +-------------- + +The following steps has to be performed to realize this extension: + +1. Implement a scanner extension for the "synchronized" keyword. + For this purpose a lexer class has to be written. The lexer + has to be set as lexer to use in the C++ scanner. + +2. Implement a grammar extension for the "synchronized" statement. + For this purpose a new syntactical analysis class has to be + derived from the C++ syntax class. A new syntactical rule has + to be implemented for the "synchronized" statement. Additionally + a new syntax tree node for the "synchronized" statement is needed + as well as a new syntax tree builder class supporting the new + syntax tree node. + +3. Implement a semantic analysis extension that is able to decide + whether a "synchronized" statement is nested. For this purpose + a new semantical analysis class has to be derived from the C++ + semantics class. A new semantic state has to be introduced used + to decide whether a "synchronized" statement is nested or not. + +4. Implement a transformer that replaces the "synchronized" statement + with the pthread function calls. For this purpose a syntax tree + visitor has to be derived to find all "synchronized" statements + in the syntax tree. Each "synchronized" statement has to be + transformed as described above using special code manipulation + classes. + +5. Implement the main application putting all the components together. + This includes opening the input file, performing scanning, parsing, + and transforming in the correct order, and saving the result. diff --git a/Puma/examples/sync/SyncBuilder.cc b/Puma/examples/sync/SyncBuilder.cc new file mode 100644 index 0000000..d73553f --- /dev/null +++ b/Puma/examples/sync/SyncBuilder.cc @@ -0,0 +1,74 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "SyncBuilder.h" +#include "SyncSyntax.h" +#include "SyncTokens.h" +#include "SyncTree.h" + + +/*****************************************************************************/ +/* */ +/* A . 5 S t a t e m e n t s */ +/* */ +/*****************************************************************************/ + + +Puma::CTree *SyncBuilder::sync_stmt() { + // This method creates a new syntax tree node resp. + // sub-tree for the parsed "synchronized" statement + // from the nodes and tokens laying on the builder + // stack. + // + // 3: SYNCHRONIZED { } => token token token + // 4: SYNCHRONIZED { stmt_seq } => token token container token + + // Create a new "synchronized" statement node. + SyncStmt *result = new SyncStmt; + + // Add the keyword "synchronized" to the node. + // get_node() returns the given node from the + // builder stack. + result->AddSon(get_node(0)); + // Add the opening curly bracket. + result->AddSon(get_node(1)); + + // Distinguish between the two variations. + // nodes() returns the number of nodes + // laying on the builder stack. + if (nodes() == 4) { + // The statements of the parsed statement sequence are + // collected in a generic container object, and have to + // be added to the new node one by one. + Container *container = (Container*)get_node(2); + for (int i = 0; i < container->Sons(); i++) { + result->AddSon(container->Son(i)); + } + // The container is not needed anymore, so delete it. + delete container; + + // Add the closing curly bracket. + result->AddSon (get_node (3)); + // An empty statement sequence. + } else { + // Add the closing curly bracket. + result->AddSon (get_node (2)); + } + + return result; +} diff --git a/Puma/examples/sync/SyncBuilder.h b/Puma/examples/sync/SyncBuilder.h new file mode 100644 index 0000000..647b909 --- /dev/null +++ b/Puma/examples/sync/SyncBuilder.h @@ -0,0 +1,33 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __SyncBuilder_h__ +#define __SyncBuilder_h__ + +#include + + +// The syntax tree builder for the "synchronize" extension. +class SyncBuilder : public Puma::CCBuilder { +public: + // A.5 Statements. + virtual Puma::CTree *sync_stmt(); +}; + + +#endif /* __SyncBuilder_h__ */ diff --git a/Puma/examples/sync/SyncLexer.cc b/Puma/examples/sync/SyncLexer.cc new file mode 100644 index 0000000..3e2ed6c --- /dev/null +++ b/Puma/examples/sync/SyncLexer.cc @@ -0,0 +1,33 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "SyncLexer.h" + + +SyncLexer& SyncLexer::instance(unsigned int id) { + return Puma::Lexer::instance(id); +} + + +void SyncLexer::add_keywords(lexertl::rules &rules) { + // add C++ keywords first + Puma::CCLexer::add_keywords(rules); + + // add 'synchronized' keyword + rules.add("synchronized", TOK_SYNC, LID(Puma::Token::keyword_id)); +} diff --git a/Puma/examples/sync/SyncLexer.h b/Puma/examples/sync/SyncLexer.h new file mode 100644 index 0000000..283c920 --- /dev/null +++ b/Puma/examples/sync/SyncLexer.h @@ -0,0 +1,36 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __SyncLexer_h__ +#define __SyncLexer_h__ + +#include +#include "SyncTokens.h" + + +class SyncLexer : public Puma::CCLexer { +public: + // get instance of the lexer + static SyncLexer& instance(unsigned int id); + + // add the keywords + void add_keywords(lexertl::rules &rules); +}; + + +#endif /* __SyncLexer_h__ */ diff --git a/Puma/examples/sync/SyncParser.h b/Puma/examples/sync/SyncParser.h new file mode 100644 index 0000000..924aecc --- /dev/null +++ b/Puma/examples/sync/SyncParser.h @@ -0,0 +1,50 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __SyncParser_h__ +#define __SyncParser_h__ + +#include +#include "SyncSyntax.h" +#include "SyncBuilder.h" +#include "SyncSemantic.h" + + +// Parser of the "synchronized" extension. +class SyncParser : public Puma::Parser { + // The "synchronized" extension grammar. + SyncSyntax m_Syntax; + // The "synchronized" extension syntax tree builder. + SyncBuilder m_Builder; + // The "synchronized" extension semantic analyzer. + SyncSemantic m_Semantic; + +public: + // Constructor, initialize the members and base class. + SyncParser() : Puma::Parser(m_Syntax, m_Builder, m_Semantic), + m_Syntax(m_Builder, m_Semantic), + m_Semantic(m_Syntax, m_Builder) {} + + // Member access methods. + SyncSyntax &syntax() const { return (SyncSyntax&)m_Syntax; } + SyncBuilder &builder() const { return (SyncBuilder&)m_Builder; } + SyncSemantic &semantic() const { return (SyncSemantic&)m_Semantic; } +}; + + +#endif /* __SyncParser_h__ */ diff --git a/Puma/examples/sync/SyncSemantic.cc b/Puma/examples/sync/SyncSemantic.cc new file mode 100644 index 0000000..1be94d9 --- /dev/null +++ b/Puma/examples/sync/SyncSemantic.cc @@ -0,0 +1,87 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "SyncSemantic.h" + + +SyncSemantic::SyncSemantic(SyncSyntax &syntax, SyncBuilder &builder) : + Puma::CCSemantic(syntax, builder), m_InSyncStmt(0) { +} + + +SyncBuilder &SyncSemantic::builder() const { + return (SyncBuilder&)Puma::CCSemantic::builder(); +} + + +SyncSyntax &SyncSemantic::syntax() const { + return (SyncSyntax&)Puma::CCSemantic::syntax(); +} + + +void SyncSemantic::enter_sync_stmt() { + // "synchronized" statements shall not be nested. + // This is checked by using this state variable. + // A value greater than 0 means that currently + // a "synchronized" statement is parsed. + m_InSyncStmt++; +} + + +void SyncSemantic::leave_sync_stmt() { + // Reset the state variable when parsing the + // "synchronized" statement is finished. + m_InSyncStmt--; +} + + +Puma::CTree *SyncSemantic::sync_stmt() { + // Build the syntax tree node for the + // "synchronized" statement. + SyncStmt *stmt = (SyncStmt*)builder().sync_stmt(); + + // "synchronized" statements shall not be nested. + // Generate an error message in case of such a + // nested statement. + if (m_InSyncStmt > 1) { + // For the error reporting a special error stream + // is used supporting several error severities and + // auto-formatted error location output. Available + // error severities are sev_none, sev_message, + // sev_warning, sev_error, and sev_fatal. + *_err << Puma::sev_error; + // For the location of the error the current position + // in the input file can be used. To get this position + // the location information object of the first token + // of the "synchronized" statement, i.e. the keyword + // "synchronized", is used. + *_err << stmt->token()->location(); + *_err << "synchronized statements cannot be nested"; + // The error message is finished using endMessage. + *_err << Puma::endMessage; + + // Delete the newly create syntax tree node and + // set it to 0 to indicate an error. + delete stmt; + stmt = 0; + } + + // Return the syntax tree node for the + // "synchronized" statement. + return stmt; +} diff --git a/Puma/examples/sync/SyncSemantic.h b/Puma/examples/sync/SyncSemantic.h new file mode 100644 index 0000000..d338a98 --- /dev/null +++ b/Puma/examples/sync/SyncSemantic.h @@ -0,0 +1,57 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __SyncSemantic_h__ +#define __SyncSemantic_h__ + +#include +#include "SyncSyntax.h" +#include "SyncBuilder.h" +#include "SyncTree.h" + + +// Semantic analyzer of the "synchronized" extension. +class SyncSemantic : public Puma::CCSemantic { + // State variable, is greater than 0 while parsing the + // statement sequence of a "synchronized" statement. + int m_InSyncStmt; + +public: + // Constructor. + SyncSemantic(SyncSyntax &syntax, SyncBuilder &builder); + +protected: + // Return the concrete builder and syntax objects. + virtual SyncBuilder &builder() const; + virtual SyncSyntax &syntax() const; + +public: + // Set the "parsing a synchronized statement" state. + void enter_sync_stmt(); + // Reset the "parsing a synchronized statement" state. + void leave_sync_stmt(); + + // Check the "parsing a synchronized statement" state. + // If not parsing a "synchronized" statement, build the + // corresponding syntax tree node. Otherwise generate an + // error message and return 0. + Puma::CTree *sync_stmt(); +}; + + +#endif /* __SyncSemantic_h__ */ diff --git a/Puma/examples/sync/SyncSyntax.cc b/Puma/examples/sync/SyncSyntax.cc new file mode 100644 index 0000000..f4cb3b4 --- /dev/null +++ b/Puma/examples/sync/SyncSyntax.cc @@ -0,0 +1,102 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "SyncSyntax.h" +#include "SyncSemantic.h" +#include "SyncBuilder.h" +#include "SyncTokens.h" +#include "SyncTree.h" + + +SyncSyntax::SyncSyntax(SyncBuilder &b, SyncSemantic &s) : + CCSyntax(b, s) { +} + + +SyncBuilder &SyncSyntax::builder() const { + return (SyncBuilder&)Puma::Syntax::builder(); +} + + +SyncSemantic &SyncSyntax::semantic () const { + return (SyncSemantic&)Puma::Syntax::semantic(); +} + + +/*****************************************************************************/ +/* */ +/* A . 5 S t a t e m e n t s */ +/* */ +/*****************************************************************************/ + + +bool SyncSyntax::stmt() { + // This method overloads the C++ statement parse method + // first trying to parse a "synchronized" statement. + + // Try to parse a "synchronized" statement. If that fails, + // parse a normal C++ statement instead. + return parse(&SyncSyntax::rule_sync_stmt) || Puma::CCSyntax::stmt(); +} + + +Puma::CTree *SyncSyntax::rule_sync_stmt() { + // This is the new grammar rule for the "synchronized" + // statement, i.e. the keyword "synchronized" followed + // by an optional statement sequence enclosed by curly + // brackets. + // + // 3: SYNCHRONIZED { } + // 4: SYNCHRONIZED { stmt_seq } + + // A result of 0 always means that the rule is failed. + Puma::CTree *result = 0; + + // Try to parse the "synchronized" keyword followed + // by the opening curly bracket. + if (parse(TOK_SYNC) && parse(Puma::TOK_OPEN_CURLY)) { + // If the names declared in a "synchronized" block shall + // be local to that block, a local scope has to be entered + // by calling the semantic object method enter_local_scope(). + // This scope is left automatically when this rule is left. + //semantic().enter_local_scope(); + + // "synchronized" statements shall not be nested. This + // is checked by the semantic analysis using a simple + // state variable set by enter_sync_stmt() and reset + // by leave_sync_stmt(). + semantic().enter_sync_stmt(); + + // Try to parse every statement (if any) up to the next + // closing curly bracket on the same nesting level. + if (stmt_seq(), parse(Puma::TOK_CLOSE_CURLY)) { + // Check if the "synchronized" statement is nested. + // Build the corresponding syntax tree if it is not + // nested, otherwise generate an error message and + // return 0. + result = semantic().sync_stmt(); + } + + // Reset the "nested" state after parsing the statement + // sequence is finished. + semantic().leave_sync_stmt(); + } + + // Return the result. + return result; +} diff --git a/Puma/examples/sync/SyncSyntax.h b/Puma/examples/sync/SyncSyntax.h new file mode 100644 index 0000000..90578d5 --- /dev/null +++ b/Puma/examples/sync/SyncSyntax.h @@ -0,0 +1,51 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __SyncSyntax_h__ +#define __SyncSyntax_h__ + +#include + + +// Cannot include the header of SyncSemantic because +// SyncSemantic need to include this header. +class SyncBuilder; +class SyncSemantic; + + +// Grammar for the "synchronized" extension. +class SyncSyntax : public Puma::CCSyntax { +public: + // Constructor. + SyncSyntax(SyncBuilder &, SyncSemantic &); + +protected: + // Return the concrete builder and semantic object. + SyncBuilder &builder() const; + SyncSemantic &semantic() const; + +protected: + // Overwrite statement parse method to first try + // to parse a synchronized statement. + virtual bool stmt(); + // Add syntax rule for synchronized statements. + Puma::CTree *rule_sync_stmt(); +}; + + +#endif /* __SyncSyntax_h__ */ diff --git a/Puma/examples/sync/SyncTokens.h b/Puma/examples/sync/SyncTokens.h new file mode 100644 index 0000000..a92d09f --- /dev/null +++ b/Puma/examples/sync/SyncTokens.h @@ -0,0 +1,30 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __SyncTokens_h__ +#define __SyncTokens_h__ + + +enum SyncTokens { + // The token numbers used for own tokens should + // be greater than 1000. + TOK_SYNC = 1000 +}; + + +#endif /* __SyncTokens_h__ */ diff --git a/Puma/examples/sync/SyncTransformer.cc b/Puma/examples/sync/SyncTransformer.cc new file mode 100644 index 0000000..ddb6cf0 --- /dev/null +++ b/Puma/examples/sync/SyncTransformer.cc @@ -0,0 +1,146 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "SyncTransformer.h" +#include +#include + + +// Counter for generating variable names. +unsigned SyncTransformer::m_Counter = 0; + + +// Constructor. +SyncTransformer::SyncTransformer(Puma::ErrorStream &err) : m_Err(err) { +} + + +void SyncTransformer::transform(Puma::CTree *node) { + // Start the transformation of the "synchronized" + // statements. visit() starts traversing the tree + // beginning at the given node. + visit(node); +} + + +void SyncTransformer::pre_visit(Puma::CTree *node) { + // This method is called for every node before the + // sub-nodes of the node are visited. It is part + // of the visitor mechanism. + + // Better to check it. + if (! node) { + return; + } + + // Check if this is a "synchronized" statement by + // comparing the unique identifier returned by + // calling NodeName() on the node with the unqiue + // identifier of a "synchronized" statement node. + if (node->NodeName() == SyncStmt::NodeId()) { + // This is a "synchronized" statement node, so + // transform it. + pre_action((SyncStmt*)node); + } +} + + +void SyncTransformer::pre_action(SyncStmt *node) { + // This method performs the transformation of a + // "synchronized" statement. The name "pre_action" + // was chosen because this action is performed + // before the sub-nodes of the "synchronized" + // statement node are visited. Accordingly a + // transformation performed after visiting the + // sub-nodes would be called "post_action". Since + // this transformation is so simple, an extra + // "post_action" is not necessary. + + // The performed transformation is the following: + // * Replace the "synchronized" keyword and the + // opening bracket with: + // + // pthread_mutex_t mutex; + // pthread_mutex_init(&mutex, 0); + // pthread_mutex_lock(&mutex); + // + // * Replace the closing bracket with: + // + // pthread_mutex_unlock(&mutex); + // pthread_mutex_destroy(&mutex); + + // First the tokens of the code to replace with are needed. + // These tokens can be easily generated from a string using + // the class CUnit, derived from std::ostringstream. The + // collected string is scanned after delivering the stream + // manipulator Puma::endu. + // TODO: Implement a better creation of the variable name + // checking if it already exists in the current scope. + Puma::CUnit lock(m_Err); + lock.name(node->Son(0)->token()->location().filename().name()); + lock << "\npthread_mutex_t __mutex_" << ++m_Counter << ";" << std::endl; + lock << "pthread_mutex_init(&__mutex_" << m_Counter << ", 0);" << std::endl; + lock << "pthread_mutex_lock(&__mutex_" << m_Counter << ");" << std::endl; + lock << Puma::endu; + + Puma::CUnit unlock(m_Err); + unlock.name(node->end_token()->location().filename().name()); + unlock << "\npthread_mutex_unlock(&__mutex_" << m_Counter << ");" << std::endl; + unlock << "pthread_mutex_destroy(&__mutex_" << m_Counter << ");" << std::endl; + unlock << Puma::endu; + + // For this kind of code manipulation the class ManipCommander + // provides a set of manipulation operations. The manipulations + // performed by this class are based on transactions, i.e. + // single manipulations are collected and then executed all + // at once after calling commit(). + Puma::ManipCommander mc; + + // Replace the "synchronized" keyword and the opening bracket. + // For this manipulation the "replace" operation can be used + // expecting the first and last tokens of the code to replace + // and of the replacement code as arguments. This means here + // to replace the first two tokens of the of the statement + // with the whole replacement token list. token() returns + // the first token referred in a sub-tree. + mc.replace(node->Son(0)->token(), node->Son(1)->token(), + (Puma::Token*)lock.first(), (Puma::Token*)lock.last()); + // Replace the closing bracket. The closing bracket is the + // last token of the statement. end_token() returns the last + // token referred in a sub-tree. + mc.replace(node->end_token(), node->end_token(), + (Puma::Token*)unlock.first(), (Puma::Token*)unlock.last()); + + // Execute the two manipulations now, together. It is also + // possible first to check if the manipulations are valid + // by calling valid() on the ManipCommander object. The + // transaction is valid if the following conditions are + // true: + // 1. The start-token is not NULL. + // 2. The start-token and end-token belong to the same + // unit and are not the result of a macro expansion + // 3. There are only balanced preprocessor directives + // within the manipulation range. + // Because this manipulation is so simple, it is not + // necessary to check its validity. + //Puma::ManipError error = mc.valid(); + //if (error) + // std::cerr << "ERROR: " << error << std::endl; + //else + mc.commit(); +} diff --git a/Puma/examples/sync/SyncTransformer.h b/Puma/examples/sync/SyncTransformer.h new file mode 100644 index 0000000..8c18a4d --- /dev/null +++ b/Puma/examples/sync/SyncTransformer.h @@ -0,0 +1,56 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __SyncTransformer_h__ +#define __SyncTransformer_h__ + +#include "Puma/CVisitor.h" +#include "Puma/ErrorStream.h" +#include "SyncTree.h" + + +// Transformer for the "synchronized" extension. +class SyncTransformer : private Puma::CVisitor { + // This counter is later used for generating + // variable names. + static unsigned m_Counter; + // A reference to the global error stream. + Puma::ErrorStream &m_Err; + +public: + // Constructor. + SyncTransformer(Puma::ErrorStream &err); + + // Start the transformation of the + // "synchronized" statements. + void transform(Puma::CTree *node); + +protected: + // Called for every node before the sub-nodes of + // this node are visited. This is part of the + // visitor mechanism. + void pre_visit(Puma::CTree *node); + + // The transformation action to be performed before + // the sub-nodes of the "synchronized" statement node + // are visited. + void pre_action(SyncStmt *node); +}; + + +#endif /* __SyncTransformer_h__ */ diff --git a/Puma/examples/sync/SyncTree.cc b/Puma/examples/sync/SyncTree.cc new file mode 100644 index 0000000..7d7ab88 --- /dev/null +++ b/Puma/examples/sync/SyncTree.cc @@ -0,0 +1,42 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "SyncTree.h" + + +SyncStmt::SyncStmt() { + // The "synchronized" statement is simply a statement + // list introduced by the keyword "synchronized" and + // enclosed by an opening and closing curly bracket. + AddProperties(INTRO | OPEN_CLOSE); +} + + +const char *SyncStmt::NodeId() { + // Every kind of syntax tree node has a unique identifier. + return "SyncStmt"; +} + + +const char *SyncStmt::NodeName() const { + // This method returns the unique identifier of + // this kind of syntax tree node. It is mostly used + // in conjunction with NodeId() to identify a node, + // e.g. if (node->NodeName() == SyncStmt::NodeId()) + return NodeId(); +} diff --git a/Puma/examples/sync/SyncTree.h b/Puma/examples/sync/SyncTree.h new file mode 100644 index 0000000..15189f9 --- /dev/null +++ b/Puma/examples/sync/SyncTree.h @@ -0,0 +1,38 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __SyncTree_h__ +#define __SyncTree_h__ + +#include + + +// Syntax tree node for the "synchronized" statement. +class SyncStmt : public Puma::CT_List { +public: + // Constructor. + SyncStmt(); + + // Returns the unique identifier of this kind of node. + static const char *NodeId(); + // Returns the unique identifier of this kind of node. + const char *NodeName() const; +}; + + +#endif /* __SyncTree_h__ */ diff --git a/Puma/examples/sync/sync.cc b/Puma/examples/sync/sync.cc new file mode 100644 index 0000000..423b404 --- /dev/null +++ b/Puma/examples/sync/sync.cc @@ -0,0 +1,129 @@ +#include +#include +#include +#include +#include +#include +#include "SyncLexer.h" +#include "SyncParser.h" +#include "SyncTransformer.h" +#include + + +int main(int argc, char **argv) { + // This is the error stream object used throughout + // the whole system, it supports several error + // severities and auto-formatted error location + // output. + Puma::ErrorStream err; + + // The project handles all file related task like + // finding, opening, writing, and closing files. + // The special CProject additionally is able to + // scan files and strings, i.e. it provides an easy + // to use interface to the lexical analyzer (scanner). + Puma::CProject project(err, argc, argv); + // Set the initial source/destination path pair. If + // a file shall be written using the project it is + // first checked if this file is located in one of + // source paths known to the project. If not, the file + // is not written. This mechanism is necessary to + // avoid system headers to be overwritten (except for + // the case that the corresponding system include + // path is added as a source path). + project.addPath(".", "."); + + // Check the arguments, need an input file. + if (argc != 2) { + std::cout << "Usage: " << argv[0] << " " << std::endl; + return 1; + } + + // Add the lexer for the keyword "synchronized" + // to the project to be able to scan it. + project.scanner().lexer(SyncLexer::instance(0)); + + // Scan the input file. The result is a token list + // representation of the input file. + Puma::Unit *unit = project.scanFile(argv[1]); + if (! unit) { + std::cerr << "Aborted: Unable to scan input file" << std::endl; + return 1; + } + + // After the input file was successfully scanned, it is + // now tried to parse it. The result is the so-called + // translation unit encapsulating the preprocessor, + // syntax, and semantic trees. + SyncParser parser; + Puma::CTranslationUnit *tu = parser.parse(*unit, project); + + // Parsing succeeded. + if (tu->tree()) { + // During the parsing of the input file only those + // semantic analyses are performed that are necessary + // to build the correct syntax tree and to recognize + // the correct types. Expression evaluation and so on + // is performed in an additional sematic analysis. It + // is optional and not needed for this application. + //Puma::CCSemVisitor semantics(err); + //semantics.run(tu->tree()); + + // The generated syntax tree is an attributed syntax + // tree referring to both tokens and semantic information. + // It can be traversed using a corresponding tree visitor. + // Formatted printing of the tree is performed by the + // CPrintVisitor tree visitor. + //CPrintVisitor cprinter; + //cprinter.print(tu->tree(), std::cout); + + // The collected semantic information also is organized + // as a tree reflecting the scope structure of the parsed + // code. The interface to the semantic tree is the class + // CSemDatabase. It can also be used to print this tree. + //tu->db().Dump(std::cout, 10); + + // Now transform the "synchronized" statements so that the + // enclosed statements are protected from concurrent + // modifications. + SyncTransformer transformer(err); + transformer.transform(tu->tree()); + + // The "synchronized" statement is replaced by calls to + // pthread functions. Thus pthread.h has to be included. + // This is one of the simplest source code manipulations + // and is entirely realized on token level using the token + // list of the input file. First the corresponding include + // directive has to be scanned. + Puma::Unit *pthread_inc = project.scanString("#include \n"); + // The resulting token list can now simply be prepended to + // the input file's token list. Token lists are organized + // as double-linked lists. Prepending something means to + // insert something before the first element of the list. + unit->paste_before((Puma::Token*)unit->first(), *pthread_inc); + // The scanned tokens should be deleted if they are not + // more needed. This is safe to do because paste_before() + // copies the tokens before they are prepended. + delete pthread_inc; + + // At last the transformed unit has to be saved as file + // again. This is also realized using the project class. + // The original file shall be renamed to filename.bak + // before the transformed version of this file is written. + project.saveMode(Puma::SaveMode::RENAME_OLD, ".bak"); + project.save(unit); + } + if (tu->cpp_tree()) { + // Beside the syntax and semantic trees there is also + // a separate tree for the preprocessor directives. + // This tree can be printed using the PrePrintVisitor. + //Puma::PrePrintVisitor preprinter; + //tu->cpp_tree()->accept(preprinter); + } + + // Clean up. + delete tu; + + // Return 1 if errors or fatal errors occurred. + return err.severity() > Puma::sev_warning ? 1 : 0; +} diff --git a/Puma/extensions.mk b/Puma/extensions.mk new file mode 100644 index 0000000..ac9d583 --- /dev/null +++ b/Puma/extensions.mk @@ -0,0 +1,166 @@ +#------------------------------------------------- +# extensions +#------------------------------------------------- + + +EXTENSIONS ?= gnuext winext acppext cc1xext +#EXTENSIONS ?= gnuext winext acppext cc1xext tracing matchexpr profiling + + +# No extensions +ifeq ($(EXTENSIONS),) +DONTWEAVE += \ + cpp/PreFileIncluder.cc \ + cpp/PreprocessorParser.cc \ + common/UnitManager.cc \ + scanner/CScanner.cc \ + parser/ccparser/CCBuilder.cc \ + parser/ccparser/CCNameLookup.cc \ + parser/ccparser/CCSemExpr.cc \ + parser/ccparser/CCSemantic.cc \ + parser/ccparser/CCSyntax.cc \ + parser/cparser/CBuilder.cc \ + parser/cparser/CSemExpr.cc \ + parser/cparser/CSyntax.cc \ + parser/cparser/CSemantic.cc \ + parser/cparser/CSemDeclSpecs.cc \ + parser/cparser/CProject.cc \ + parser/Syntax.cc \ + parser/Parser.cc \ + infos/CSemDatabase.cc +endif + + +# Win32/VisualC++ extensions +ifneq ($(findstring winext,$(EXTENSIONS)),) +ASPECTS += \ + aspects/WinIfExists.ah \ + aspects/WinImportHandler.ah \ + aspects/WinMacros.ah \ + aspects/WinAsm.ah \ + aspects/WinDeclSpecs.ah \ + aspects/WinMemberExplSpec.ah \ + aspects/WinTypeKeywords.ah \ + aspects/WinFriend.ah \ + aspects/WinKeywords.ah +endif + + +# AspectC++ extensions +ifneq ($(findstring acppext,$(EXTENSIONS)),) +ASPECTS += \ + aspects/ExtAC.ah \ + aspects/ExtACTree.ah + +SOURCES += \ + aspects/ExtACTree.cc \ + parser/acparser/ACIntroducer_dummy.cc + +DONTWEAVE += \ + aspects/ExtACTree.cc \ + parser/acparser/ACIntroducer_dummy.cc +endif + + +# GNU C/C++ extensions +ifneq ($(findstring gnuext,$(EXTENSIONS)),) +ASPECTS += \ + aspects/ExtGnu.ah \ + aspects/ExtGnuCTree.ah \ + aspects/ExtGnuCInfos.ah \ + aspects/ExtGnuCSemantic.ah \ + aspects/ExtGnuCSemExpr.ah \ + aspects/ExtGnuCSemDeclSpecs.ah \ + aspects/ExtGnuKeywords.ah +endif + + +# C++1X extensions +ifneq ($(findstring cc1xext,$(EXTENSIONS)),) +ASPECTS += \ + aspects/ExtCC1X.ah \ + aspects/ExtCC1XBuilderH.ah \ + aspects/ExtCC1XBuilderCC.ah \ + aspects/ExtCC1XSyntaxH.ah \ + aspects/ExtCC1XSyntaxCC.ah \ + aspects/ExtCC1XSemanticH.ah \ + aspects/ExtCC1XSemanticCC.ah + +SOURCES += \ + aspects/CC1XTree.cc + +DONTWEAVE += \ + aspects/CC1XTree.cc +endif + + +# #pragma once extension (if gnuext or winext is enabled) +ifneq ($(findstring gnuext,$(EXTENSIONS)),) +ASPECTS += \ + aspects/PragmaOnceUnitState.ah \ + aspects/PragmaOnce.ah +else +ifneq ($(findstring winext,$(EXTENSIONS)),) +ASPECTS += \ + aspects/PragmaOnceUnitState.ah \ + aspects/PragmaOnce.ah +endif +endif + + +# Grammar rule tracing +ifneq ($(findstring tracing,$(EXTENSIONS)),) +ASPECTS += \ + aspects/TraceSyntax.ah + +SOURCES += \ + parser/Tracing.cc + +DONTWEAVE += \ + parser/Tracing.cc +endif + + +# AST match expressions +ifneq ($(findstring matchexpr,$(EXTENSIONS)),) +ASPECTS += \ + aspects/CMatchSyntax.ah + +SOURCES += \ + manip/CMatch.cc \ + manip/CMatchChecker.cc \ + manip/CSubMatch.cc \ + manip/CTreeMatcher.cc \ + manip/MatchCollector.cc + +DONTWEAVE += \ + manip/CMatch.cc \ + manip/CMatchChecker.cc \ + manip/CSubMatch.cc \ + manip/CTreeMatcher.cc \ + manip/MatchCollector.cc + +LEMSOURCES += \ + manip/CMatchParser.lem +endif + + +# Profiling +ifneq ($(findstring profiling,$(EXTENSIONS)),) +ASPECTS += \ + aspects/GenericProfiler.ah \ + aspects/Profiler.ah + +FORCEWEAVE := \ + parser/ccparser/CCSemantic.cc \ + parser/ccparser/CCInstantiation.cc \ + parser/ccparser/CCNameLookup.cc \ + basics/SysCall.cc \ + scanner/CRecognizer.cc \ + scanner/CScanner.cc \ + cpp/PreprocessorParser.cc \ + parser/Parser.cc \ + manip/ManipCommander.cc + +DONTWEAVE := $(filter-out $(FORCEWEAVE), $(DONTWEAVE)) +endif diff --git a/Puma/extern/README b/Puma/extern/README new file mode 100644 index 0000000..2815686 --- /dev/null +++ b/Puma/extern/README @@ -0,0 +1,10 @@ +This file documents external code that has been imported into PUMA: + +lexertl +======= + + * is an open source lexical analyzer generator + * has been downloaded from http://www.benhanson.net/lexertl/download.html + on 27/8/2015 and imported into PUMA + +Read the license in the lexertl directory! diff --git a/Puma/extern/lexertl/bool.hpp b/Puma/extern/lexertl/bool.hpp new file mode 100644 index 0000000..02c871a --- /dev/null +++ b/Puma/extern/lexertl/bool.hpp @@ -0,0 +1,22 @@ +// bool.hpp +// Copyright (c) 2010-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef LEXERTL_BOOL_H +#define LEXERTL_BOOL_H + +namespace lexertl +{ +// Named template param for compiler compatibility +template +struct bool_ +{ +}; + +typedef bool_ true_; +typedef bool_ false_; +} + +#endif diff --git a/Puma/extern/lexertl/char_traits.hpp b/Puma/extern/lexertl/char_traits.hpp new file mode 100644 index 0000000..d1444b8 --- /dev/null +++ b/Puma/extern/lexertl/char_traits.hpp @@ -0,0 +1,43 @@ +// char_traits.hpp +// Copyright (c) 2005-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef LEXERTL_CHAR_TRAITS_H +#define LEXERTL_CHAR_TRAITS_H + +#include + +namespace lexertl +{ +template +struct basic_char_traits +{ + typedef ch_type char_type; + typedef ch_type index_type; + + static index_type max_val() + { + return sizeof(char_type) > 2 ? 0x10ffff : + ~static_cast(0); + } +}; + +template<> +struct basic_char_traits +{ + typedef char char_type; + typedef unsigned char index_type; + + static index_type max_val() + { + // Prevent annoying warning (VC++) + index_type zero_ = 0; + + return ~zero_; + } +}; +} + +#endif diff --git a/Puma/extern/lexertl/compile_assert.hpp b/Puma/extern/lexertl/compile_assert.hpp new file mode 100644 index 0000000..b097c3e --- /dev/null +++ b/Puma/extern/lexertl/compile_assert.hpp @@ -0,0 +1,24 @@ +// compile_assert.hpp +// Copyright (c) 2010-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef LEXERTL_COMPILE_ASSERT_H +#define LEXERTL_COMPILE_ASSERT_H + +namespace lexertl +{ +// Named template param for compiler compatibility +template +struct compile_assert; + +// enum for compiler compatibility +template<> +struct compile_assert +{ + enum {value = 1}; +}; +} + +#endif diff --git a/Puma/extern/lexertl/containers/bitvector.hpp b/Puma/extern/lexertl/containers/bitvector.hpp new file mode 100644 index 0000000..2c1755c --- /dev/null +++ b/Puma/extern/lexertl/containers/bitvector.hpp @@ -0,0 +1,228 @@ +// bitvector.hpp +// Copyright (c) 2013-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef LEXERTL_BITVECTOR_HPP +#define LEXERTL_BITVECTOR_HPP + +#include + +namespace lexertl +{ +template +class basic_bitvector +{ +public: + template + class reference + { + public: + reference(Ty &block_, const std::size_t mask_) : + _block(block_), + _mask(mask_) + { + } + + operator bool() const + { + return (_block & _mask) != 0; + } + + reference &operator =(const bool bit_) + { + if (bit_) + { + _block |= _mask; + } + else + { + _block &= ~_mask; + } + + return *this; + } + + reference &operator =(reference &rhs_) + { + if (rhs_) + { + _block |= _mask; + } + else + { + _block &= ~_mask; + } + } + + private: + Ty &_block; + const std::size_t _mask; + }; + + basic_bitvector(const std::size_t size_) : + _vec(block(size_) + (bit(size_) ? 1 : 0), 0) + { + } + + basic_bitvector(const basic_bitvector &rhs_) : + _vec(rhs_._vec) + { + } + + basic_bitvector &operator =(const basic_bitvector &rhs_) + { + if (&rhs_ != this) + { + _vec = rhs_._vec; + } + + return *this; + } + + bool operator [](const std::size_t index_) const + { + return (_vec[block(index_)] & (1 << bit(index_))) != 0; + } + + reference operator [](const std::size_t index_) + { + return reference(_vec[block(index_)], (1 << bit(index_))); + } + + basic_bitvector &operator |=(const basic_bitvector &rhs_) + { + typename t_vector::iterator lhs_iter_ = _vec.begin(); + typename t_vector::iterator lhs_end_ = _vec.end(); + typename t_vector::const_iterator rhs_iter_ = rhs_._vec.begin(); + typename t_vector::const_iterator rhs_end_ = rhs_._vec.end(); + + for (; lhs_iter_ != lhs_end_ && rhs_iter_ != rhs_end_; + ++lhs_iter_, ++rhs_iter_) + { + *lhs_iter_ |= *rhs_iter_; + } + + return *this; + } + + basic_bitvector &operator &=(const basic_bitvector &rhs_) + { + typename t_vector::iterator lhs_iter_ = _vec.begin(); + typename t_vector::iterator lhs_end_ = _vec.end(); + typename t_vector::const_iterator rhs_iter_ = rhs_._vec.begin(); + typename t_vector::const_iterator rhs_end_ = rhs_._vec.end(); + + for (; lhs_iter_ != lhs_end_ && rhs_iter_ != rhs_end_; + ++lhs_iter_, ++rhs_iter_) + { + *lhs_iter_ &= *rhs_iter_; + } + + return *this; + } + + void clear() + { + typename t_vector::iterator iter_ = _vec.begin(); + typename t_vector::iterator end_ = _vec.end(); + + for (; iter_ != end_; ++iter_) + { + *iter_ = 0; + } + } + + bool any() const + { + typename t_vector::const_iterator iter_ = _vec.begin(); + typename t_vector::const_iterator end_ = _vec.end(); + + for (; iter_ != end_; ++iter_) + { + if (*iter_) break; + } + + return iter_ != end_; + } + + void negate() + { + typename t_vector::iterator iter_ = _vec.begin(); + typename t_vector::iterator end_ = _vec.end(); + + for (; iter_ != end_; ++iter_) + { + *iter_ = ~*iter_; + } + } + + std::size_t find_first() const + { + return find_next(npos()); + } + + std::size_t find_next(const std::size_t index_) const + { + std::size_t ret_ = npos(); + const std::size_t block_ = index_ == npos() ? 0 : block(index_ + 1); + std::size_t bit_ = index_ == npos() ? 0 : bit(index_ + 1); + typename t_vector::const_iterator iter_ = _vec.begin() + block_; + typename t_vector::const_iterator end_ = _vec.end(); + + for (std::size_t i_ = block_; iter_ != end_; ++iter_, ++i_) + { + const bool bits_ = (*iter_ & (~static_cast(0) << bit_)) != 0; + + if (bits_) + { + std::size_t j_ = bit_; + std::size_t b_ = 1 << bit_; + bool found_ = false; + + for (; j_ < sizeof(T) * 8; ++j_, b_ <<= 1) + { + if (*iter_ & b_) + { + found_ = true; + break; + } + } + + if (found_) + { + ret_ = i_ * sizeof(T) * 8 + j_; + break; + } + } + + bit_ = 0; + } + + return ret_; + } + + std::size_t npos() const + { + return ~static_cast(0); + } + +private: + typedef std::vector t_vector; + + t_vector _vec; + + std::size_t block(const std::size_t index_) const + { + return index_ / (sizeof(T) * 8); + } + + std::size_t bit(const std::size_t index_) const + { + return index_ % (sizeof(T) * 8); + } +}; +} + +#endif diff --git a/Puma/extern/lexertl/containers/ptr_list.hpp b/Puma/extern/lexertl/containers/ptr_list.hpp new file mode 100644 index 0000000..8120aa4 --- /dev/null +++ b/Puma/extern/lexertl/containers/ptr_list.hpp @@ -0,0 +1,69 @@ +// ptr_list.hpp +// Copyright (c) 2005-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_PTR_LIST_HPP +#define LEXERTL_PTR_LIST_HPP + +#include + +namespace lexertl +{ +namespace detail +{ +template +class ptr_list +{ +public: + typedef std::list list; + + ptr_list() : + _list() + { + } + + ~ptr_list() + { + clear(); + } + + list *operator ->() + { + return &_list; + } + + const list *operator ->() const + { + return &_list; + } + + list &operator *() + { + return _list; + } + + const list &operator *() const + { + return _list; + } + + void clear() + { + while (!_list.empty()) + { + delete _list.front(); + _list.pop_front(); + } + } + +private: + list _list; + + ptr_list(const ptr_list &); // No copy construction. + ptr_list &operator =(const ptr_list &); // No assignment. +}; +} +} + +#endif diff --git a/Puma/extern/lexertl/containers/ptr_map.hpp b/Puma/extern/lexertl/containers/ptr_map.hpp new file mode 100644 index 0000000..9b67026 --- /dev/null +++ b/Puma/extern/lexertl/containers/ptr_map.hpp @@ -0,0 +1,72 @@ +// ptr_map.hpp +// Copyright (c) 2005-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_PTR_MAP_HPP +#define LEXERTL_PTR_MAP_HPP + +#include + +namespace lexertl +{ +namespace detail +{ +template +class ptr_map +{ +public: + typedef std::map map; + typedef std::pair pair; + typedef std::pair iter_pair; + + ptr_map() + { + } + + ~ptr_map() + { + clear(); + } + + map *operator ->() + { + return &_map; + } + + const map *operator ->() const + { + return &_map; + } + + map &operator *() + { + return _map; + } + + const map &operator *() const + { + return _map; + } + + void clear() + { + for (typename map::iterator iter_ = _map.begin(), end_ = _map.end(); + iter_ != end_; ++iter_) + { + delete iter_->second; + } + + _map.clear(); + } + +private: + map _map; + + ptr_map(const ptr_map &); // No copy construction. + ptr_map &operator =(const ptr_map &); // No assignment. +}; +} +} + +#endif diff --git a/Puma/extern/lexertl/containers/ptr_stack.hpp b/Puma/extern/lexertl/containers/ptr_stack.hpp new file mode 100644 index 0000000..23e9e9a --- /dev/null +++ b/Puma/extern/lexertl/containers/ptr_stack.hpp @@ -0,0 +1,69 @@ +// ptr_stack.hpp +// Copyright (c) 2005-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_PTR_STACK_HPP +#define LEXERTL_PTR_STACK_HPP + +#include + +namespace lexertl +{ +namespace detail +{ +template +class ptr_stack +{ +public: + typedef std::stack stack; + + ptr_stack() : + _stack() + { + } + + ~ptr_stack() + { + clear(); + } + + stack *operator ->() + { + return &_stack; + } + + const stack *operator ->() const + { + return &_stack; + } + + stack &operator *() + { + return _stack; + } + + const stack &operator *() const + { + return _stack; + } + + void clear() + { + while (!_stack.empty()) + { + delete _stack.top(); + _stack.pop(); + } + } + +private: + stack _stack; + + ptr_stack(const ptr_stack &); // No copy construction. + ptr_stack &operator =(const ptr_stack &); // No assignment. +}; +} +} + +#endif diff --git a/Puma/extern/lexertl/containers/ptr_vector.hpp b/Puma/extern/lexertl/containers/ptr_vector.hpp new file mode 100644 index 0000000..4b431fd --- /dev/null +++ b/Puma/extern/lexertl/containers/ptr_vector.hpp @@ -0,0 +1,106 @@ +// ptr_vector.hpp +// Copyright (c) 2005-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_PTR_VECTOR_HPP +#define LEXERTL_PTR_VECTOR_HPP + +#include "../size_t.hpp" +#include + +namespace lexertl +{ +namespace detail +{ +template +class ptr_vector +{ +public: + typedef std::vector vector; + + ptr_vector() : + _vector() + { + } + + ~ptr_vector() + { + clear(); + } + + vector *operator ->() + { + return &_vector; + } + + const vector *operator ->() const + { + return &_vector; + } + + vector &operator *() + { + return _vector; + } + + const vector &operator *() const + { + return _vector; + } + + ptr_type * &operator [](const std::size_t index_) + { + return _vector[index_]; + } + + ptr_type * const &operator [](const std::size_t index_) const + { + return _vector[index_]; + } + + bool operator ==(const ptr_vector &rhs_) const + { + bool equal_ = _vector.size() == rhs_._vector.size(); + + if (equal_) + { + typename vector::const_iterator lhs_iter_ = _vector.begin(); + typename vector::const_iterator end_ = _vector.end(); + typename vector::const_iterator rhs_iter_ = rhs_._vector.begin(); + + for (; equal_ && lhs_iter_ != end_; ++lhs_iter_, ++rhs_iter_) + { + equal_ = **lhs_iter_ == **rhs_iter_; + } + } + + return equal_; + } + + void clear() + { + if (!_vector.empty()) + { + ptr_type **iter_ = &_vector.front(); + ptr_type **end_ = iter_ + _vector.size(); + + for (; iter_ != end_; ++iter_) + { + delete *iter_; + } + } + + _vector.clear(); + } + +private: + vector _vector; + + ptr_vector(const ptr_vector &); // No copy construction. + ptr_vector &operator =(const ptr_vector &); // No assignment. +}; +} +} + +#endif diff --git a/Puma/extern/lexertl/debug.hpp b/Puma/extern/lexertl/debug.hpp new file mode 100644 index 0000000..81d8007 --- /dev/null +++ b/Puma/extern/lexertl/debug.hpp @@ -0,0 +1,324 @@ +// debug.hpp +// Copyright (c) 2005-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_DEBUG_HPP +#define LEXERTL_DEBUG_HPP + +#include +#include +#include "rules.hpp" +#include "size_t.hpp" +#include "sm_to_csm.hpp" +#include "state_machine.hpp" +#include "string_token.hpp" +#include + +namespace lexertl +{ +template +class basic_debug +{ +public: + typedef lexertl::basic_char_state_machine + char_state_machine; + typedef std::basic_ostream ostream; + typedef lexertl::basic_rules rules; + typedef std::basic_string string; + + static void dump(const sm &sm_, rules &rules_, ostream &stream_) + { + char_state_machine csm_; + + sm_to_csm(sm_, csm_); + dump(csm_, rules_, stream_); + } + + static void dump(const sm &sm_, ostream &stream_) + { + char_state_machine csm_; + + sm_to_csm(sm_, csm_); + dump(csm_, stream_); + } + + static void dump(const char_state_machine &csm_, rules &rules_, + ostream &stream_) + { + for (std::size_t dfa_ = 0, dfas_ = csm_.size(); dfa_ < dfas_; ++dfa_) + { + lexer_state(stream_); + stream_ << rules_.state(dfa_) << std::endl << std::endl; + + dump_ex(csm_._sm_deque[dfa_], stream_); + } + } + + static void dump(const char_state_machine &csm_, ostream &stream_) + { + for (std::size_t dfa_ = 0, dfas_ = csm_.size(); dfa_ < dfas_; ++dfa_) + { + lexer_state(stream_); + stream_ << dfa_ << std::endl << std::endl; + + dump_ex(csm_._sm_deque[dfa_], stream_); + } + } + +protected: + typedef typename char_state_machine::state dfa_state; + typedef typename dfa_state::string_token string_token; + typedef std::basic_stringstream stringstream; + + static void dump_ex(const typename char_state_machine::dfa &dfa_, + ostream &stream_) + { + const std::size_t states_ = dfa_._states.size(); + const id_type bol_index_ = dfa_._bol_index; + typename dfa_state::id_type_string_token_map::const_iterator iter_; + typename dfa_state::id_type_string_token_map::const_iterator end_; + + for (std::size_t i_ = 0; i_ < states_; ++i_) + { + const dfa_state &state_ = dfa_._states[i_]; + + state(stream_); + stream_ << i_ << std::endl; + + if (state_._end_state) + { + end_state(stream_); + + if (state_._push_pop_dfa == dfa_state::push_dfa) + { + push(stream_); + stream_ << state_._push_dfa; + } + else if (state_._push_pop_dfa == dfa_state::pop_dfa) + { + pop(stream_); + } + + id(stream_); + stream_ << static_cast(state_._id); + user_id(stream_); + stream_ << static_cast(state_._user_id); + dfa(stream_); + stream_ << static_cast(state_._next_dfa); + stream_ << std::endl; + } + + if (i_ == 0 && bol_index_ != char_state_machine::npos()) + { + bol(stream_); + stream_ << static_cast(bol_index_) << std::endl; + } + + if (state_._eol_index != char_state_machine::npos()) + { + eol(stream_); + stream_ << static_cast(state_._eol_index) << + std::endl; + } + + iter_ = state_._transitions.begin(); + end_ = state_._transitions.end(); + + for (; iter_ != end_; ++iter_) + { + string_token token_ = iter_->second; + + open_bracket(stream_); + + if (!iter_->second.any() && iter_->second.negatable()) + { + token_.negate(); + negated(stream_); + } + + string chars_; + typename string_token::range_vector::const_iterator + ranges_iter_ = token_._ranges.begin(); + typename string_token::range_vector::const_iterator + ranges_end_ = token_._ranges.end(); + + for (; ranges_iter_ != ranges_end_; ++ranges_iter_) + { + if (ranges_iter_->first == '-' || + ranges_iter_->first == '^' || + ranges_iter_->first == ']') + { + stream_ << '\\'; + } + + chars_ = string_token::escape_char + (ranges_iter_->first); + + if (ranges_iter_->first != ranges_iter_->second) + { + if (ranges_iter_->first + 1 < ranges_iter_->second) + { + chars_ += '-'; + } + + if (ranges_iter_->second == '-' || + ranges_iter_->second == '^' || + ranges_iter_->second == ']') + { + stream_ << '\\'; + } + + chars_ += string_token::escape_char + (ranges_iter_->second); + } + + stream_ << chars_; + } + + close_bracket(stream_); + stream_ << static_cast(iter_->first) << + std::endl; + } + + stream_ << std::endl; + } + } + + static void lexer_state(std::ostream &stream_) + { + stream_ << "Lexer state: "; + } + + static void lexer_state(std::wostream &stream_) + { + stream_ << L"Lexer state: "; + } + + static void state(std::ostream &stream_) + { + stream_ << "State: "; + } + + static void state(std::wostream &stream_) + { + stream_ << L"State: "; + } + + static void bol(std::ostream &stream_) + { + stream_ << " BOL -> "; + } + + static void bol(std::wostream &stream_) + { + stream_ << L" BOL -> "; + } + + static void eol(std::ostream &stream_) + { + stream_ << " EOL -> "; + } + + static void eol(std::wostream &stream_) + { + stream_ << L" EOL -> "; + } + + static void end_state(std::ostream &stream_) + { + stream_ << " END STATE"; + } + + static void end_state(std::wostream &stream_) + { + stream_ << L" END STATE"; + } + + static void id(std::ostream &stream_) + { + stream_ << ", Id = "; + } + + static void id(std::wostream &stream_) + { + stream_ << L", Id = "; + } + + static void push(std::ostream &stream_) + { + stream_ << ", PUSH "; + } + + static void push(std::wostream &stream_) + { + stream_ << L", PUSH "; + } + + static void pop(std::ostream &stream_) + { + stream_ << ", POP"; + } + + static void pop(std::wostream &stream_) + { + stream_ << L", POP"; + } + + static void user_id(std::ostream &stream_) + { + stream_ << ", User Id = "; + } + + static void user_id(std::wostream &stream_) + { + stream_ << L", User Id = "; + } + + static void open_bracket(std::ostream &stream_) + { + stream_ << " ["; + } + + static void open_bracket(std::wostream &stream_) + { + stream_ << L" ["; + } + + static void negated(std::ostream &stream_) + { + stream_ << "^"; + } + + static void negated(std::wostream &stream_) + { + stream_ << L"^"; + } + + static void close_bracket(std::ostream &stream_) + { + stream_ << "] -> "; + } + + static void close_bracket(std::wostream &stream_) + { + stream_ << L"] -> "; + } + + static void dfa(std::ostream &stream_) + { + stream_ << ", dfa = "; + } + + static void dfa(std::wostream &stream_) + { + stream_ << L", dfa = "; + } +}; + +typedef basic_debug, char> debug; +typedef basic_debug, wchar_t> wdebug; +} + +#endif diff --git a/Puma/extern/lexertl/dot.hpp b/Puma/extern/lexertl/dot.hpp new file mode 100644 index 0000000..42d61fd --- /dev/null +++ b/Puma/extern/lexertl/dot.hpp @@ -0,0 +1,295 @@ +// dot.hpp +// Copyright (c) 2005-2015 Ben Hanson (http://www.benhanson.net/) +// Copyright (c) 2013 Autodesk, Inc. All rights reserved. +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_DOT_HPP +#define LEXERTL_DOT_HPP + +#include +#include "rules.hpp" +#include "state_machine.hpp" +#include "sm_to_csm.hpp" + +namespace lexertl +{ +//! The class template basic_dot contains utility functions used to +//! dump a description of a finite state machine formatted in the +//! DOT language (http://www.graphviz.org/doc/info/lang.html). The +//! resulting directed graph can previewed by opening the ".dot" file +//! into the GraphViz application (http://www.graphviz.org). +template +class basic_dot +{ +public: + typedef lexertl::basic_char_state_machine + char_state_machine; + typedef lexertl::basic_rules rules; + typedef std::basic_ostream ostream; + typedef std::basic_string string; + + //! Dumps a description of the finite state machine expressed in + //! the DOT language to the given output stream. + static void dump(const sm &sm_, rules &rules_, ostream &stream_) + { + char_state_machine csm_; + + sm_to_csm(sm_, csm_); + dump(csm_, rules_, stream_); + } + + //! Dumps a description of the finite state machine expressed in + //! the DOT language to the given output stream. + static void dump(const char_state_machine &csm_, rules &rules_, + ostream &stream_) + { + header(stream_); + for (std::size_t dfa_ = 0, dfas_ = csm_.size(); dfa_ < dfas_; ++dfa_) + { + dump_ex(dfa_, csm_._sm_deque[dfa_], rules_, stream_); + } + trailer(stream_); + } + +protected: + typedef typename char_state_machine::state dfa_state; + typedef typename dfa_state::string_token string_token; + typedef std::basic_stringstream stringstream; + + // Naming of nodes used in the DOT diagram. The naming is of the + // form: L_S. + static string node_name(id_type dfa_id_, id_type state_id_) + { + stringstream namestream_; + namestream_ << "L" << dfa_id_ << "_S" << state_id_; + return namestream_.str(); + } + + // Escape control characters twice. This is necessary when + // expressing character sets attached as to DOT nodes as + // labels. + static string double_escape_char(const id_type ch_) + { + stringstream out_; + + switch (ch_) + { + case '\0': + out_ << '\\'; + out_ << '\\'; + out_ << '0'; + break; + case '\a': + out_ << '\\'; + out_ << '\\'; + out_ << 'a'; + break; + case '\b': + out_ << '\\'; + out_ << '\\'; + out_ << 'b'; + break; + case '\f': + out_ << '\\'; + out_ << '\\'; + out_ << 'f'; + break; + case '\n': + out_ << '\\'; + out_ << '\\'; + out_ << 'n'; + break; + case '\r': + out_ << '\\'; + out_ << '\\'; + out_ << 'r'; + break; + case '\t': + out_ << '\\'; + out_ << '\\'; + out_ << 't'; + break; + case '\v': + out_ << '\\'; + out_ << '\\'; + out_ << 'v'; + break; + case '\\': + out_ << '\\'; + out_ << '\\'; + break; + case '"': + out_ << '\\'; + out_ << '\\'; + out_ << '"'; + break; + case '\'': + out_ << '\\'; + out_ << '\\'; + out_ << '\''; + break; + default: + { + if (ch_ < 32 || ch_ > 126) + { + out_ << '\\'; + out_ << 'x'; + out_ << std::hex << + static_cast(ch_); + } + else + { + out_ << char_type(ch_); + } + + break; + } + } + + return out_.str(); + } + + // Internal function actually performing the work of dumping the + // state machine in DOT. + static void dump_ex(id_type dfa_id_, + const typename char_state_machine::dfa &dfa_, + rules &rules_, + ostream &stream_) + { + const std::size_t states_ = dfa_._states.size(); + typename dfa_state::id_type_string_token_map::const_iterator iter_; + typename dfa_state::id_type_string_token_map::const_iterator end_; + + stream_ << std::endl; + + for (std::size_t i_ = 0; i_ < states_; ++i_) + { + const dfa_state &state_ = dfa_._states[i_]; + + const string name = node_name(dfa_id_, i_); + if (i_ == 0) + { + stream_ << " " << name << " [shape = doublecircle, xlabel=\"" + << rules_.state(dfa_id_) << "\"];" << std::endl; + } + else if (state_._end_state) + { + stream_ << " " << name << + " [shape = doublecircle, xlabel=\"id =" << + static_cast(state_._id) << "\"];" << + std::endl; + } + else { + stream_ << " " << name << " [shape = circle];" << std::endl; + } + } + + stream_ << std::endl; + + for (std::size_t i_ = 0; i_ < states_; ++i_) + { + const dfa_state &state_ = dfa_._states[i_]; + + iter_ = state_._transitions.begin(); + end_ = state_._transitions.end(); + + const string src_name = node_name(dfa_id_, i_); + + for (; iter_ != end_; ++iter_) + { + const string dst_name = node_name(dfa_id_, iter_->first); + stream_ << " " << src_name << " -> " << dst_name << + " [label = \""; + + string_token token_ = iter_->second; + + open_bracket(stream_); + + if (!iter_->second.any() && iter_->second.negatable()) + { + token_.negate(); + negated(stream_); + } + + string chars_; + typename string_token::range_vector::const_iterator + ranges_iter_ = token_._ranges.begin(); + typename string_token::range_vector::const_iterator + ranges_end_ = token_._ranges.end(); + + for (; ranges_iter_ != ranges_end_; ++ranges_iter_) + { + if (ranges_iter_->first == '^' || + ranges_iter_->first == ']') + { + stream_ << "\\\\"; + } + + chars_ = double_escape_char(ranges_iter_->first); + + if (ranges_iter_->first != ranges_iter_->second) + { + if (ranges_iter_->first + 1 < ranges_iter_->second) + { + chars_ += '-'; + } + + if (ranges_iter_->second == '^' || + ranges_iter_->second == ']') + { + stream_ << "\\\\"; + } + + chars_ += double_escape_char(ranges_iter_->second); + } + + stream_ << chars_; + } + + close_bracket(stream_); + stream_ << "\"];" << std::endl; + } + + if (state_._end_state) { + const string dst_name = node_name(state_._next_dfa, 0); + stream_ << " " << src_name << " -> " << dst_name + << " [style = \"dashed\"];" << std::endl; + } + } + } + + static void header(ostream &stream_) + { + stream_ << "digraph DFAs {" << std::endl; + stream_ << " rankdir = LR;" << std::endl; + } + + static void trailer(ostream &stream_) + { + stream_ << "}" << std::endl; + } + + static void open_bracket(ostream &stream_) + { + stream_ << "["; + } + + static void negated(ostream &stream_) + { + stream_ << "^"; + } + + static void close_bracket(ostream &stream_) + { + stream_ << "]"; + } + +}; + +typedef basic_dot, char> dot; +typedef basic_dot, wchar_t> wdot; +} + +#endif diff --git a/Puma/extern/lexertl/enums.hpp b/Puma/extern/lexertl/enums.hpp new file mode 100644 index 0000000..17dfb64 --- /dev/null +++ b/Puma/extern/lexertl/enums.hpp @@ -0,0 +1,25 @@ +// enums.hpp +// Copyright (c) 2005-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef LEXERTL_ENUMS_H +#define LEXERTL_ENUMS_H + +namespace lexertl +{ + enum regex_flags {icase = 1, dot_not_newline = 2, skip_ws = 4, + match_zero_len = 8}; + // 0 = end state, 1 = id, 2 = user id, 3 = push_dfa_index + // 4 = next dfa, 5 = dead state, 6 = dfa_start + enum {end_state_index, id_index, user_id_index, push_dfa_index, + next_dfa_index, eol_index, dead_state_index, transitions_index}; + // Rule flags: + enum feature_flags {bol_bit = 1, eol_bit = 2, skip_bit = 4, again_bit = 8, + multi_state_bit = 16, recursive_bit = 32, advance_bit = 64}; + // End state flags: + enum {end_state_bit = 1, pop_dfa_bit = 2}; +} + +#endif diff --git a/Puma/extern/lexertl/generate_cpp.hpp b/Puma/extern/lexertl/generate_cpp.hpp new file mode 100644 index 0000000..b079a38 --- /dev/null +++ b/Puma/extern/lexertl/generate_cpp.hpp @@ -0,0 +1,1122 @@ +// generate_cpp.hpp +// Copyright (c) 2005-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_GENERATE_CPP_HPP +#define LEXERTL_GENERATE_CPP_HPP + +#include "bool.hpp" +#include "enums.hpp" +#include +#include "state_machine.hpp" + +namespace lexertl +{ +class table_based_cpp +{ +public: + template + static void generate_cpp + (const std::string &name_, + const basic_state_machine &sm_, + const bool pointers_, std::ostream &os_) + { + typedef basic_state_machine sm; + typedef typename sm::internals internals; + const internals &internals_ = sm_.data(); + std::size_t additional_tabs_ = 0; + + os_ << "template\n"; + os_ << "void " << name_ << " (lexertl::"; + + if (internals_._features & recursive_bit) + { + os_ << "recursive_match_results"; + } + else + { + os_ << "match_results"; + } + + os_ << " &results_)\n"; + os_ << "{\n"; + os_ << " typedef lexertl::"; + + if (internals_._features & recursive_bit) + { + os_ << "recursive_match_results"; + } + else + { + os_ << "match_results"; + } + + os_ << " results;\n"; + os_ << " typedef typename results::char_type char_type;\n"; + os_ << " typename results::iter_type end_token_ = results_.end;\n"; + + if (internals_._features & skip_bit) + { + os_ << "skip:\n"; + } + + os_ << " typename results::iter_type curr_ = results_.end;\n\n"; + os_ << " results_.start = curr_;\n\n"; + + if (internals_._features & again_bit) + { + os_ << "again:\n"; + } + + os_ << " if (curr_ == results_.eoi)\n"; + os_ << " {\n"; + // We want a number regardless of id_type. + os_ << " results_.id = " << static_cast + (internals_._eoi) << ";\n"; + os_ << " results_.user_id = results::npos();\n"; + os_ << " return;\n"; + os_ << " }\n\n"; + + if (internals_._features & bol_bit) + { + os_ << " bool bol_ = results_.bol;\n"; + } + + dump_tables(sm_, 1, pointers_, os_); + + if (internals_._dfa->size() > 1) + { + os_ << " const id_type *lookup_ = lookups_[results_.state];\n"; + os_ << " const id_type dfa_alphabet_ = dfa_alphabets_" + "[results_.state];\n"; + os_ << " const "; + + if (pointers_) + { + os_ << "void * const"; + } + else + { + os_ << "id_type"; + } + + os_ << " *dfa_ = dfas_[results_.state];\n"; + } + + os_ << " const "; + + if (pointers_) + { + os_ << "void * const"; + } + else + { + os_ << "id_type"; + } + + os_ << " *ptr_ = dfa_ + dfa_alphabet_;\n"; + os_ << " bool end_state_ = *ptr_ != 0;\n"; + + if (internals_._features & recursive_bit) + { + os_ << " bool pop_ = ("; + + if (pointers_) + { + // Done this way for GCC: + os_ << "static_cast(reinterpret_cast("; + } + + os_ << "*ptr_"; + + if (pointers_) + { + os_ << ')'; + } + + os_ <<" & " << pop_dfa_bit; + + if (pointers_) + { + os_ << ')'; + } + + os_ << ") != 0;\n"; + } + + os_ << " id_type id_ = "; + + if (pointers_) + { + // Done this way for GCC: + os_ << "static_cast(reinterpret_cast("; + } + + os_ << "*(ptr_ + " << id_index << ")"; + + if (pointers_) + { + os_ << "))"; + } + + os_ << ";\n"; + os_ << " id_type uid_ = "; + + if (pointers_) + { + // Done this way for GCC: + os_ << "static_cast(reinterpret_cast("; + } + + os_ << "*(ptr_ + " << user_id_index << ")"; + + if (pointers_) + { + os_ << "))"; + } + + os_ << ";\n"; + + if (internals_._features & recursive_bit) + { + os_ << " id_type push_dfa_ = "; + + if (pointers_) + { + // Done this way for GCC: + os_ << "static_cast(reinterpret_cast("; + } + + os_ << "*(ptr_ + " << push_dfa_index << ")"; + + if (pointers_) + { + os_ << "))"; + } + + os_ << ";\n"; + } + + if (internals_._dfa->size() > 1) + { + os_ << " id_type start_state_ = results_.state;\n"; + } + + if (internals_._features & bol_bit) + { + os_ << " bool end_bol_ = bol_;\n"; + } + + if (internals_._features & eol_bit) + { + os_ << " "; + + if (pointers_) + { + os_ << "const void * const *"; + } + else + { + os_ << "id_type "; + } + + os_ << "EOL_state_ = 0;\n"; + } + + os_ << '\n'; + + if (internals_._features & bol_bit) + { + os_ << " if (bol_)\n"; + os_ << " {\n"; + os_ << " const "; + + if (pointers_) + { + os_ << "void *"; + } + else + { + os_ << "id_type "; + } + + os_ << "state_ = *dfa_;\n\n"; + os_ << " if (state_)\n"; + os_ << " {\n"; + os_ << " ptr_ = "; + + if (pointers_) + { + os_ << "reinterpret_cast(state_);\n"; + } + else + { + os_ << "&dfa_[state_ * dfa_alphabet_];\n"; + } + + os_ << " }\n"; + os_ << " }\n\n"; + } + + os_ << " while (curr_ != results_.eoi)\n"; + os_ << " {\n"; + + if (internals_._features & eol_bit) + { + os_ << " EOL_state_ = "; + + if (pointers_) + { + os_ << "reinterpret_cast("; + } + + os_ << "ptr_[" << eol_index << ']'; + + if (pointers_) + { + os_ << ')'; + } + + os_ << ";\n\n"; + os_ << " if (EOL_state_ && *curr_ == '\\n')\n"; + os_ << " {\n"; + os_ << " ptr_ = "; + + if (pointers_) + { + os_ << "EOL_state_"; + } + else + { + os_ << "&dfa_[EOL_state_ * dfa_alphabet_]"; + } + + os_ << ";\n"; + os_ << " }\n"; + os_ << " else\n"; + os_ << " {\n"; + ++additional_tabs_; + } + + output_char_loop(internals_._features, additional_tabs_, pointers_, + os_, bool_<(sizeof(typename sm::traits::input_char_type) > 1)>()); + + if (internals_._features & eol_bit) + { + output_tabs(additional_tabs_, os_); + os_ << " }\n"; + --additional_tabs_; + } + + os_ << '\n'; + os_ << " if (*ptr_)\n"; + os_ << " {\n"; + os_ << " end_state_ = true;\n"; + + + if (internals_._features & recursive_bit) + { + os_ << " pop_ = ("; + + if (pointers_) + { + // Done this way for GCC: + os_ << "static_cast(reinterpret_cast("; + } + + os_ << "*ptr_"; + + if (pointers_) + { + os_ << ')'; + } + + os_ <<" & " << pop_dfa_bit; + + if (pointers_) + { + os_ << ')'; + } + + os_ << ") != 0;\n"; + } + + os_ << " id_ = "; + + if (pointers_) + { + // Done this way for GCC: + os_ << "static_cast(reinterpret_cast("; + } + + os_ << "*(ptr_ + " << id_index << ")"; + + if (pointers_) + { + os_ << "))"; + } + + os_ << ";\n"; + os_ << " uid_ = "; + + if (pointers_) + { + // Done this way for GCC: + os_ << "static_cast(reinterpret_cast("; + } + + os_ << "*(ptr_ + " << user_id_index << ")"; + + if (pointers_) + { + os_ << "))"; + } + + os_ << ";\n"; + + if (internals_._features & recursive_bit) + { + os_ << " push_dfa_ = "; + + if (pointers_) + { + // Done this way for GCC: + os_ << "static_cast(reinterpret_cast("; + } + + os_ << "*(ptr_ + " << push_dfa_index << ')'; + + if (pointers_) + { + os_ << "))"; + } + + os_ << ";\n"; + } + + if (internals_._dfa->size() > 1) + { + os_ << " start_state_ = "; + + if (pointers_) + { + // Done this way for GCC: + os_ << "static_cast(reinterpret_cast("; + } + + os_ << "*(ptr_ + " << next_dfa_index << ')'; + + if (pointers_) + { + os_ << "))"; + } + + os_ << ";\n"; + } + + if (internals_._features & bol_bit) + { + os_ << " end_bol_ = bol_;\n"; + } + + os_ << " end_token_ = curr_;\n"; + os_ << " }\n"; + os_ << " }\n\n"; + output_quit(os_, + bool_<(sizeof(typename sm::traits::input_char_type) > 1)>()); + + if (internals_._features & eol_bit) + { + os_ << " if (curr_ == results_.eoi)\n"; + os_ << " {\n"; + os_ << " EOL_state_ = "; + + if (pointers_) + { + os_ << "reinterpret_cast("; + } + + os_ << "ptr_[" << eol_index << ']'; + + if (pointers_) + { + os_ << ')'; + } + + os_ << ";\n"; + os_ << "\n"; + os_ << " if (EOL_state_)\n"; + os_ << " {\n"; + os_ << " ptr_ = "; + + if (pointers_) + { + os_ << "EOL_state_"; + } + else + { + os_ << "&dfa_[EOL_state_ * dfa_alphabet_]"; + } + + os_ << ";\n\n"; + os_ << " if (*ptr_)\n"; + os_ << " {\n"; + os_ << " end_state_ = true;\n"; + + + if (internals_._features & recursive_bit) + { + os_ << " pop_ = ("; + + if (pointers_) + { + // Done this way for GCC: + os_ << "static_cast(reinterpret_cast("; + } + + os_ << "*ptr_"; + + if (pointers_) + { + os_ << ')'; + } + + os_ <<" & " << pop_dfa_bit; + + if (pointers_) + { + os_ << ')'; + } + + os_ << ") != 0;\n"; + } + + os_ << " id_ = "; + + if (pointers_) + { + // Done this way for GCC: + os_ << "static_cast(reinterpret_cast("; + } + + os_ << "*(ptr_ + " << id_index << ")"; + + if (pointers_) + { + os_ << "))"; + } + + os_ << ";\n"; + os_ << " uid_ = "; + + if (pointers_) + { + // Done this way for GCC: + os_ << "static_cast(reinterpret_cast("; + } + + os_ << "*(ptr_ + " << user_id_index << ")"; + + if (pointers_) + { + os_ << "))"; + } + + os_ <<";\n"; + + if (internals_._features & recursive_bit) + { + os_ << " push_dfa_ = "; + + if (pointers_) + { + // Done this way for GCC: + os_ << "static_cast(reinterpret_cast("; + } + + os_ << "*(ptr_ + " << push_dfa_index << ')'; + + if (pointers_) + { + os_ << "))"; + } + + os_ << ";\n"; + } + + if (internals_._dfa->size() > 1) + { + os_ << " start_state_ = "; + + if (pointers_) + { + // Done this way for GCC: + os_ << "static_cast(reinterpret_cast("; + } + + os_ << "*(ptr_ + " << next_dfa_index << ')'; + + if (pointers_) + { + os_ << "))"; + } + + os_ << ";\n"; + } + + if (internals_._features & bol_bit) + { + os_ << " end_bol_ = bol_;\n"; + } + + os_ << " end_token_ = curr_;\n"; + os_ << " }\n"; + os_ << " }\n"; + os_ << " }\n\n"; + } + + os_ << " if (end_state_)\n"; + os_ << " {\n"; + os_ << " // Return longest match\n"; + + if (internals_._features & recursive_bit) + { + os_ << " if (pop_)\n"; + os_ << " {\n"; + os_ << " start_state_ = results_." + "stack.top().first;\n"; + os_ << " results_.stack.pop();\n"; + os_ << " }\n"; + os_ << " else if (push_dfa_ != results_.npos())\n"; + os_ << " {\n"; + os_ << " results_.stack.push(typename results::" + "id_type_pair\n"; + os_ << " (push_dfa_, id_));\n"; + os_ << " }\n\n"; + } + + if (internals_._dfa->size() > 1) + { + os_ << " results_.state = start_state_;\n"; + } + + if (internals_._features & bol_bit) + { + os_ << " results_.bol = end_bol_;\n"; + } + + os_ << " results_.end = end_token_;\n"; + + if (internals_._features & skip_bit) + { + // We want a number regardless of id_type. + os_ << "\n if (id_ == results_.skip()) goto skip;\n"; + } + + if (internals_._features & again_bit) + { + // We want a number regardless of id_type. + os_ << "\n if (id_ == " + << static_cast(internals_._eoi); + + if (internals_._features & recursive_bit) + { + os_ << " || (pop_ && !results_.stack.empty() &&\n"; + // We want a number regardless of id_type. + os_ << " results_.stack.top().second == " + << static_cast(internals_._eoi) << ')'; + } + + os_ << ")\n"; + os_ << " {\n"; + os_ << " curr_ = end_token_;\n"; + os_ << " goto again;\n"; + os_ << " }\n"; + } + + os_ << " }\n"; + os_ << " else\n"; + os_ << " {\n"; + os_ << " // No match causes char to be skipped\n"; + os_ << " results_.end = end_token_;\n"; + + if (internals_._features & bol_bit) + { + os_ << " results_.bol = *results_.end == '\\n';\n"; + } + + os_ << " results_.start = results_.end;\n"; + os_ << " ++results_.end;\n"; + os_ << " id_ = results::npos();\n"; + os_ << " uid_ = results::npos();\n"; + os_ << " }\n\n"; + os_ << " results_.id = id_;\n"; + os_ << " results_.user_id = uid_;\n"; + os_ << "}\n"; + } + + template + static void dump_tables + (const basic_state_machine &sm_, + const std::size_t tabs_, const bool pointers_, std::ostream &os_) + { + const typename detail::basic_internals &internals_ = + sm_.data(); + const std::size_t lookup_divisor_ = 8; + // Lookup is always 256 entries long now + const std::size_t lookup_quotient_ = 256 / lookup_divisor_; + const std::size_t dfas_ = internals_._lookup->size(); + std::size_t col_ = 1; + std::size_t row_ = 1; + + output_tabs(tabs_, os_); + os_ << "static const id_type lookup"; + + if (dfas_ > 1) + { + os_ << "s_[][" << 256; + } + else + { + os_ << "_["; + } + + os_ << "] = \n"; + output_tabs(tabs_ + 1, os_); + + if (dfas_ > 1) + { + os_ << '{'; + } + + for (std::size_t l_ = 0; l_ < dfas_; ++l_) + { + const id_type *ptr_ = &internals_._lookup[l_]->front(); + + // We want numbers regardless of id_type. + os_ << "{0x" << std::hex << static_cast(*ptr_++); + + for (col_ = 1; col_ < lookup_divisor_; ++col_) + { + // We want numbers regardless of id_type. + os_ << ", 0x" << std::hex << static_cast(*ptr_++); + } + + for (row_ = 1; row_ < lookup_quotient_; ++row_) + { + os_ << ",\n"; + output_tabs(tabs_ + 1, os_); + // We want numbers regardless of id_type. + os_ << "0x" << std::hex << static_cast(*ptr_++); + + for (col_ = 1; col_ < lookup_divisor_; ++col_) + { + // We want numbers regardless of id_type. + os_ << ", 0x" << std::hex << + static_cast(*ptr_++); + } + } + + os_ << '}'; + + if (l_ + 1 < dfas_) + { + os_ << ",\n"; + output_tabs(tabs_ + 1, os_); + } + } + + if (dfas_ > 1) + { + os_ << '}'; + } + + os_ << ";\n"; + output_tabs(tabs_, os_); + os_ << "static const id_type dfa_alphabet"; + + if (dfas_ > 1) + { + os_ << "s_[" << dfas_ << "] = {"; + } + else + { + os_ << "_ = "; + } + + // We want numbers regardless of id_type. + os_ << "0x" << std::hex << static_cast + (internals_._dfa_alphabet[0]); + + for (col_ = 1; col_ < dfas_; ++col_) + { + // We want numbers regardless of id_type. + os_ << ", 0x" << std::hex << static_cast(internals_. + _dfa_alphabet[col_]); + } + + if (dfas_ > 1) + { + os_ << '}'; + } + + os_ << ";\n"; + + // DFAs are usually different sizes, so dump separately + for (std::size_t dfa_ = 0; dfa_ < dfas_; ++dfa_) + { + const id_type dfa_alphabet_ = internals_._dfa_alphabet[dfa_]; + const std::size_t rows_ = internals_._dfa[dfa_]->size() / + dfa_alphabet_; + const id_type *ptr_ = &internals_._dfa[dfa_]->front(); + std::string dfa_name_ = "dfa"; + + output_tabs(tabs_, os_); + os_ << "static const "; + + if (pointers_) + { + os_ << "void *"; + } + else + { + os_ << "id_type "; + } + + os_ << dfa_name_; + + if (dfas_ > 1) + { + std::ostringstream ss_; + + ss_ << dfa_; + dfa_name_ += ss_.str(); + os_ << dfa_; + } + + dfa_name_ += '_'; + os_ << "_[] = {"; + + for (std::size_t row_ = 0; row_ < rows_; ++row_) + { + dump_row(row_ == 0, ptr_, dfa_name_, dfa_alphabet_, + pointers_, os_); + + if (row_ + 1 < rows_) + { + os_ << ",\n"; + output_tabs(tabs_ + 1, os_); + } + } + + os_ << "};\n"; + } + + if (dfas_ > 1) + { + output_tabs(tabs_, os_); + os_ << "static const "; + + if (pointers_) + { + os_ << "void * const"; + } + else + { + os_ << "id_type"; + } + + os_ << " *dfas_[] = {dfa0_"; + + for (col_ = 1; col_ < dfas_; ++col_) + { + os_ << ", dfa" << col_ << '_'; + } + + os_ << "};\n"; + } + } + +protected: + template + static void dump_row(const bool first_, const id_type * &ptr_, + const std::string &dfa_name_, const id_type dfa_alphabet_, + const bool pointers_, std::ostream &os_) + { + if (pointers_) + { + bool zero_ = *ptr_ == 0; + + if (first_) + { + // We want numbers regardless of id_type. + os_ << dfa_name_ << " + 0x" << std::hex << + static_cast(*ptr_++) * dfa_alphabet_; + } + else if (!zero_) + { + os_ << "reinterpret_cast(0x" + // We want numbers regardless of id_type. + << std::hex << static_cast(*ptr_++) << ')'; + } + else + { + // We want numbers regardless of id_type. + os_ << "0x" << std::hex << static_cast(*ptr_++); + } + + for (id_type id_index_ = id_index; id_index_ < transitions_index; + ++id_index_, ++ptr_) + { + os_ << ", "; + zero_ = *ptr_ == 0; + + if (!zero_) + { + os_ << "reinterpret_cast("; + } + + // We want numbers regardless of id_type. + os_ << "0x" << std::hex << static_cast(*ptr_); + + if (!zero_) + { + os_ << ')'; + } + } + + for (id_type alphabet_ = transitions_index; + alphabet_ < dfa_alphabet_; ++alphabet_, ++ptr_) + { + // We want numbers regardless of id_type. + os_ << ", "; + + if (*ptr_ == 0) + { + os_ << 0; + } + else + { + // We want numbers regardless of id_type. + os_ << dfa_name_ + " + 0x" << std::hex << + static_cast(*ptr_) * dfa_alphabet_; + } + } + } + else + { + // We want numbers regardless of id_type. + os_ << "0x" << std::hex << static_cast(*ptr_++); + + for (id_type alphabet_ = 1; alphabet_ < dfa_alphabet_; + ++alphabet_, ++ptr_) + { + // We want numbers regardless of id_type. + os_ << ", 0x" << std::hex << static_cast(*ptr_); + } + } + } + + static void output_tabs(const std::size_t tabs_, std::ostream &os_) + { + for (std::size_t i_ = 0; i_ < tabs_; ++i_) + { + os_ << " "; + } + } + + template + static void output_char_loop(const id_type features_, + const std::size_t additional_tabs_, const bool pointers_, + std::ostream &os_, const false_ &) + { + output_tabs(additional_tabs_, os_); + os_ << " const typename results::char_type prev_char_ = " + "*curr_++;\n"; + output_tabs(additional_tabs_, os_); + os_ << " const "; + + if (pointers_) + { + os_ << "void * const *"; + } + else + { + os_ << "id_type "; + } + + os_ << "state_ = "; + + if (pointers_) + { + os_ << "reinterpret_cast\n "; + output_tabs(additional_tabs_, os_); + os_ << '('; + } + + os_ << "ptr_[lookup_"; + + if (!pointers_) + { + os_ << "\n "; + output_tabs(additional_tabs_, os_); + } + + os_ << "[static_cast"; + + if (pointers_) + { + os_ << "\n "; + output_tabs(additional_tabs_, os_); + } + + os_ << "(prev_char_)]]"; + + if (pointers_) + { + os_ << ')'; + } + + os_ << ";\n\n"; + + if (features_ & bol_bit) + { + output_tabs(additional_tabs_, os_); + os_ << " bol_ = prev_char_ == '\\n';\n\n"; + } + + output_tabs(additional_tabs_, os_); + os_ << " if (state_ == 0)\n"; + output_tabs(additional_tabs_, os_); + os_ << " {\n"; + + if (features_ & eol_bit) + { + output_tabs(additional_tabs_, os_); + os_ << " EOL_state_ = 0;\n"; + } + + output_tabs(additional_tabs_, os_); + os_ << " break;\n"; + output_tabs(additional_tabs_, os_); + os_ << " }\n\n"; + output_tabs(additional_tabs_, os_); + os_ << " ptr_ = "; + + if (pointers_) + { + os_ << "state_"; + } + else + { + os_ << "&dfa_[state_ * dfa_alphabet_]"; + } + + os_ << ";\n"; + } + + template + static void output_char_loop(const id_type features_, + const std::size_t additional_tabs_, const bool pointers_, + std::ostream &os_, const true_ &) + { + output_tabs(additional_tabs_, os_); + os_ << " const std::size_t bytes_ =\n"; + output_tabs(additional_tabs_, os_); + os_ << " sizeof(typename results::char_type) < 3 ?\n"; + output_tabs(additional_tabs_, os_); + os_ << " sizeof(typename results::char_type) : 3;\n"; + output_tabs(additional_tabs_, os_); + os_ << " const std::size_t shift_[] = {0, 8, 16};\n"; + output_tabs(additional_tabs_, os_); + os_ << " typename results::char_type prev_char_ = " + "*curr_++;\n\n"; + + if (features_ & bol_bit) + { + output_tabs(additional_tabs_, os_); + os_ << " bol_ = prev_char_ == '\\n';\n\n"; + } + + output_tabs(additional_tabs_, os_); + os_ << " for (std::size_t i_ = 0; i_ < bytes_; ++i_)\n"; + output_tabs(additional_tabs_, os_); + os_ << " {\n"; + output_tabs(additional_tabs_, os_); + os_ << " const "; + + if (pointers_) + { + os_ << "void * const *"; + } + else + { + os_ << "id_type "; + } + + os_ << "state_ = "; + + if (pointers_) + { + os_ << "reinterpret_cast\n "; + output_tabs(additional_tabs_, os_); + os_ << '('; + } + + os_ << "ptr_[lookup_[static_cast\n"; + output_tabs(additional_tabs_, os_); + os_ << " ((prev_char_ >>\n" + " shift_[bytes_ - 1 - i_]) & 0xff)]]"; + + if (pointers_) + { + os_ << ')'; + } + + os_ << ";\n\n"; + output_tabs(additional_tabs_, os_); + os_ << " if (state_ == 0)\n"; + output_tabs(additional_tabs_, os_); + os_ << " {\n"; + + if (features_ & eol_bit) + { + output_tabs(additional_tabs_, os_); + os_ << " EOL_state_ = 0;\n"; + } + + output_tabs(additional_tabs_, os_); + os_ << " goto quit;\n"; + output_tabs(additional_tabs_, os_); + os_ << " }\n\n"; + output_tabs(additional_tabs_, os_); + os_ << " ptr_ = "; + + if (pointers_) + { + os_ << "state_"; + } + else + { + os_ << "&dfa_[state_ * dfa_alphabet_]"; + } + + os_ << ";\n"; + output_tabs(additional_tabs_, os_); + os_ << " }\n"; + } + + static void output_quit(std::ostream &, const false_ &) + { + // Nothing to do + } + + static void output_quit(std::ostream &os_, const true_ &) + { + os_ << "quit:\n"; + } +}; +} + +#endif diff --git a/Puma/extern/lexertl/generator.hpp b/Puma/extern/lexertl/generator.hpp new file mode 100644 index 0000000..2e73f89 --- /dev/null +++ b/Puma/extern/lexertl/generator.hpp @@ -0,0 +1,793 @@ +// generator.hpp +// Copyright (c) 2005-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_GENERATOR_HPP +#define LEXERTL_GENERATOR_HPP + +#include +#include "bool.hpp" +#include "partition/charset.hpp" +#include "char_traits.hpp" +#include "partition/equivset.hpp" +#include +#include "parser/parser.hpp" +#include "containers/ptr_list.hpp" +#include "rules.hpp" +#include "size_t.hpp" +#include "state_machine.hpp" + +namespace lexertl +{ +template > +class basic_generator +{ +public: + typedef typename rules::id_type id_type; + typedef typename rules::rules_char_type rules_char_type; + typedef typename sm::traits sm_traits; + typedef detail::basic_parser parser; + typedef typename parser::charset_map charset_map; + typedef typename parser::node node; + typedef typename parser::node_ptr_vector node_ptr_vector; + + static void build(const rules &rules_, sm &sm_) + { + const std::size_t size_ = rules_.statemap().size(); + // Strong exception guarantee + // http://www.boost.org/community/exception_safety.html + internals internals_; + sm temp_sm_; + node_ptr_vector node_ptr_vector_; + + internals_._eoi = rules_.eoi(); + internals_.add_states(size_); + + for (id_type index_ = 0; index_ < size_; ++index_) + { + if (rules_.regexes()[index_].empty()) + { + std::ostringstream ss_; + + ss_ << "Lexer states with no rules are not allowed " + "(lexer state " << index_ << ".)"; + throw runtime_error(ss_.str()); + } + else + { + // Note that the following variables are per DFA. + // Map of regex charset tokens (strings) to index + charset_map charset_map_; + // Used to fix up $ and \n clashes. + id_type nl_id_ = sm_traits::npos(); + // Regex syntax tree + node *root_ = build_tree(rules_, index_, node_ptr_vector_, + charset_map_, nl_id_); + + build_dfa(charset_map_, root_, internals_, temp_sm_, index_, + nl_id_); + + if (internals_._dfa[index_]->size() / + internals_._dfa_alphabet[index_] >= sm_traits::npos()) + { + // Overflow + throw runtime_error("The data type you have chosen " + "cannot hold this many DFA rows."); + } + } + } + + // If you get a compile error here the id_type from rules and + // state machine do no match. + create(internals_, temp_sm_, rules_.features(), lookup()); + sm_.swap(temp_sm_); + } + + static node *build_tree(const rules &rules_, const std::size_t dfa_, + node_ptr_vector &node_ptr_vector_, charset_map &charset_map_, + id_type &nl_id_) + { + parser parser_(rules_.locale(), node_ptr_vector_, charset_map_, + rules_.eoi()); + const typename rules::token_deque_deque_deque ®exes_ = + rules_.regexes(); + typename rules::token_deque_deque::const_iterator regex_iter_ = + regexes_[dfa_].begin(); + typename rules::token_deque_deque::const_iterator regex_iter_end_ = + regexes_[dfa_].end(); + const typename rules::token_deque ®ex_ = *regex_iter_; + const typename rules::id_vector_deque &ids_ = rules_.ids(); + const typename rules::id_vector_deque &user_ids_ = + rules_.user_ids(); + typename rules::id_vector::const_iterator id_iter_ = + ids_[dfa_].begin(); + typename rules::id_vector::const_iterator user_id_iter_ = + user_ids_[dfa_].begin(); + const typename rules::id_vector_deque &next_dfas_ = + rules_.next_dfas(); + const typename rules::id_vector_deque &pushes_ = rules_.pushes(); + const typename rules::bool_vector_deque &pops_ = rules_.pops(); + typename rules::id_vector::const_iterator next_dfa_iter_ = + next_dfas_[dfa_].begin(); + typename rules::id_vector::const_iterator push_dfa_iter_ = + pushes_[dfa_].begin(); + typename rules::bool_vector::const_iterator pop_dfa_iter_ = + pops_[dfa_].begin(); + const bool seen_bol_ = (rules_.features()[dfa_] & bol_bit) != 0; + node *root_ = 0; + + root_ = parser_.parse(regex_, *id_iter_, *user_id_iter_, + *next_dfa_iter_, *push_dfa_iter_, *pop_dfa_iter_, + rules_.flags(), nl_id_, seen_bol_); + ++regex_iter_; + ++id_iter_; + ++user_id_iter_; + ++next_dfa_iter_; + ++push_dfa_iter_; + ++pop_dfa_iter_; + + // Build syntax trees + while (regex_iter_ != regex_iter_end_) + { + // Re-declare var, otherwise we perform an assignment..! + const typename rules::token_deque ®ex_ = *regex_iter_; + node *rhs_ = parser_.parse(regex_, *id_iter_, *user_id_iter_, + *next_dfa_iter_, *push_dfa_iter_, *pop_dfa_iter_, + rules_.flags(), nl_id_, + (rules_.features()[dfa_] & bol_bit) != 0); + + node_ptr_vector_->push_back + (static_cast(0)); + node_ptr_vector_->back() = new selection_node(root_, rhs_); + root_ = node_ptr_vector_->back(); + + ++regex_iter_; + ++id_iter_; + ++user_id_iter_; + ++next_dfa_iter_; + ++push_dfa_iter_; + ++pop_dfa_iter_; + } + + return root_; + } + +protected: + typedef bool_ compressed; + typedef detail::basic_equivset equivset; + typedef detail::ptr_list equivset_list; + typedef std::auto_ptr equivset_ptr; + typedef typename sm_traits::char_type sm_char_type; + typedef detail::basic_charset charset; + typedef std::auto_ptr charset_ptr; + typedef detail::ptr_list charset_list; + typedef detail::basic_internals internals; + typedef typename std::set id_type_set; + typedef typename internals::id_type_vector id_type_vector; + typedef typename charset::index_set index_set; + typedef std::vector index_set_vector; + typedef bool_ is_dfa; + typedef bool_ lookup; + typedef std::set node_set; + typedef detail::ptr_vector node_set_vector; + typedef typename node::node_vector node_vector; + typedef detail::ptr_vector node_vector_vector; + typedef typename parser::selection_node selection_node; + typedef typename std::vector size_t_vector; + typedef typename parser::string_token string_token; + + static void build_dfa(const charset_map &charset_map_, const node *root_, + internals &internals_, sm &sm_, const id_type dfa_index_, + id_type &nl_id_) + { + // partitioned charset list + charset_list charset_list_; + // vector mapping token indexes to partitioned token index sets + index_set_vector set_mapping_; + typename internals::id_type_vector &dfa_ = + *internals_._dfa[dfa_index_]; + std::size_t dfa_alphabet_ = 0; + const node_vector *followpos_ = &root_->firstpos(); + node_set_vector seen_sets_; + node_vector_vector seen_vectors_; + size_t_vector hash_vector_; + id_type zero_id_ = sm_traits::npos(); + id_type_set eol_set_; + + set_mapping_.resize(charset_map_.size()); + partition_charsets(charset_map_, charset_list_, is_dfa()); + build_set_mapping(charset_list_, internals_, dfa_index_, + set_mapping_); + + if (nl_id_ != sm_traits::npos()) + { + nl_id_ = *set_mapping_[nl_id_].begin(); + zero_id_ = sm_traits::compressed ? + *set_mapping_[charset_map_.find(string_token(0, 0))-> + second].begin() : sm_traits::npos(); + } + + dfa_alphabet_ = charset_list_->size() + transitions_index + + (nl_id_ == sm_traits::npos() ? 0 : 1); + + if (dfa_alphabet_ > sm_traits::npos()) + { + // Overflow + throw runtime_error("The data type you have chosen cannot hold " + "the dfa alphabet."); + } + + internals_._dfa_alphabet[dfa_index_] = dfa_alphabet_; + // 'jam' state + dfa_.resize(dfa_alphabet_, 0); + closure(followpos_, seen_sets_, seen_vectors_, hash_vector_, + dfa_alphabet_, dfa_); + + for (id_type index_ = 0; index_ < static_cast + (seen_vectors_->size()); ++index_) + { + equivset_list equiv_list_; + + build_equiv_list(seen_vectors_[index_], set_mapping_, + equiv_list_, is_dfa()); + + for (typename equivset_list::list::const_iterator iter_ = + equiv_list_->begin(), end_ = equiv_list_->end(); + iter_ != end_; ++iter_) + { + equivset *equivset_ = *iter_; + const id_type transition_ = closure + (&equivset_->_followpos, seen_sets_, seen_vectors_, + hash_vector_, dfa_alphabet_, dfa_); + + if (transition_ != sm_traits::npos()) + { + id_type *ptr_ = &dfa_.front() + ((index_ + 1) * + dfa_alphabet_); + + // Prune abstemious transitions from end states. + if (*ptr_ && !equivset_->_greedy) continue; + + for (typename equivset::index_vector::const_iterator + equiv_iter_ = equivset_->_index_vector.begin(), + equiv_end_ = equivset_->_index_vector.end(); + equiv_iter_ != equiv_end_; ++equiv_iter_) + { + const id_type i_ = *equiv_iter_; + + if (i_ == parser::bol_token()) + { + dfa_.front() = transition_; + } + else if (i_ == parser:: eol_token()) + { + ptr_[eol_index] = transition_; + eol_set_.insert(index_ + 1); + } + else + { + ptr_[i_ + transitions_index] = transition_; + } + } + } + } + } + + fix_clashes(eol_set_, nl_id_, zero_id_, dfa_, dfa_alphabet_, + compressed()); + append_dfa(charset_list_, internals_, sm_, dfa_index_, lookup()); + } + + // Uncompressed + static void fix_clashes(const id_type_set &eol_set_, + const id_type nl_id_, const id_type /*zero_id_*/, + typename internals::id_type_vector &dfa_, + const std::size_t dfa_alphabet_, const false_ &) + { + typename id_type_set::const_iterator eol_iter_ = + eol_set_.begin(); + typename id_type_set::const_iterator eol_end_ = + eol_set_.end(); + + for (; eol_iter_ != eol_end_; ++eol_iter_) + { + id_type *ptr_ = &dfa_.front() + *eol_iter_ * dfa_alphabet_; + const id_type eol_state_ = ptr_[eol_index]; + const id_type nl_state_ = ptr_[nl_id_ + transitions_index]; + + if (nl_state_) + { + ptr_[transitions_index + nl_id_] = 0; + ptr_ = &dfa_.front() + eol_state_ * dfa_alphabet_; + + if (ptr_[transitions_index + nl_id_] == 0) + { + ptr_[transitions_index + nl_id_] = nl_state_; + } + } + } + } + + // Compressed + static void fix_clashes(const id_type_set &eol_set_, + const id_type nl_id_, const id_type zero_id_, + typename internals::id_type_vector &dfa_, + const std::size_t dfa_alphabet_, const true_ &) + { + typename id_type_set::const_iterator eol_iter_ = + eol_set_.begin(); + typename id_type_set::const_iterator eol_end_ = + eol_set_.end(); + std::size_t i_ = 0; + + for (; eol_iter_ != eol_end_; ++eol_iter_) + { + id_type *ptr_ = &dfa_.front() + *eol_iter_ * dfa_alphabet_; + const id_type eol_state_ = ptr_[eol_index]; + id_type nl_state_ = 0; + + for (; i_ < (sm_traits::char_24_bit ? 2 : 1); ++i_) + { + ptr_ = &dfa_.front() + ptr_[transitions_index + zero_id_] * + dfa_alphabet_; + } + + nl_state_ = ptr_[transitions_index + nl_id_]; + + if (nl_state_) + { + ptr_ = &dfa_.front() + eol_state_ * dfa_alphabet_; + + if (ptr_[transitions_index + zero_id_] != 0) continue; + + ptr_[transitions_index + zero_id_] = dfa_.size() / + dfa_alphabet_; + dfa_.resize(dfa_.size() + dfa_alphabet_, 0); + + for (i_ = 0; i_ < (sm_traits::char_24_bit ? 1 : 0); ++i_) + { + ptr_ = &dfa_.front() + dfa_.size() - dfa_alphabet_; + ptr_[transitions_index + zero_id_] = dfa_.size() / + dfa_alphabet_; + dfa_.resize(dfa_.size() + dfa_alphabet_, 0); + } + + ptr_ = &dfa_.front() + dfa_.size() - dfa_alphabet_; + ptr_[transitions_index + nl_id_] = nl_state_; + } + } + } + + // char_state_machine version + static void append_dfa(const charset_list &charset_list_, + const internals &internals_, sm &sm_, const id_type dfa_index_, + const false_ &) + { + typename charset_list::list::const_iterator list_iter_ = + charset_list_->begin(); + std::size_t size_ = charset_list_->size(); + typename sm::string_token_vector token_vector_; + + token_vector_.reserve(size_); + + for (std::size_t i_ = 0; i_ < size_; ++i_, ++list_iter_) + { + const charset *charset_ = *list_iter_; + + token_vector_.push_back(charset_->_token); + } + + sm_.append(token_vector_, internals_, dfa_index_); + } + + // state_machine version + static void append_dfa(const charset_list &, + const internals &, sm &, const id_type, const true_ &) + { + // Nothing to do - will use create() instead + } + + // char_state_machine version + static void create(internals &, sm &, const id_type_vector &, + const false_ &) + { + // Nothing to do - will use append_dfa() instead + } + + // state_machine version + static void create(internals &internals_, sm &sm_, + const id_type_vector &features_, const true_ &) + { + for (std::size_t i_ = 0, size_ = internals_._dfa->size(); + i_ < size_; ++i_) + { + internals_._features |= features_[i_]; + } + + if (internals_._dfa->size() > 1) + { + internals_._features |= multi_state_bit; + } + + sm_.data().swap(internals_); + } + + // NFA version + static void partition_charsets(const charset_map &map_, + charset_list &lhs_, const false_ &) + { + fill_rhs_list(map_, lhs_); + } + + // DFA version + static void partition_charsets(const charset_map &map_, + charset_list &lhs_, const true_ &) + { + charset_list rhs_; + + fill_rhs_list(map_, rhs_); + + if (!rhs_->empty()) + { + typename charset_list::list::iterator iter_; + typename charset_list::list::iterator end_; + charset_ptr overlap_(new charset); + + lhs_->push_back(static_cast(0)); + lhs_->back() = rhs_->front(); + rhs_->pop_front(); + + while (!rhs_->empty()) + { + charset_ptr r_(rhs_->front()); + + rhs_->pop_front(); + iter_ = lhs_->begin(); + end_ = lhs_->end(); + + while (!r_->empty() && iter_ != end_) + { + typename charset_list::list::iterator l_iter_ = iter_; + + (*l_iter_)->intersect(*r_.get(), *overlap_.get()); + + if (overlap_->empty()) + { + ++iter_; + } + else if ((*l_iter_)->empty()) + { + delete *l_iter_; + *l_iter_ = overlap_.release(); + overlap_.reset(new charset); + ++iter_; + } + else if (r_->empty()) + { + delete r_.release(); + r_ = overlap_; + overlap_.reset(new charset); + break; + } + else + { + iter_ = lhs_->insert(++iter_, + static_cast(0)); + *iter_ = overlap_.release(); + overlap_.reset(new charset); + ++iter_; + end_ = lhs_->end(); + } + } + + if (!r_->empty()) + { + lhs_->push_back(static_cast(0)); + lhs_->back() = r_.release(); + } + } + } + } + + static void fill_rhs_list(const charset_map &map_, + charset_list &list_) + { + typename charset_map::const_iterator iter_ = map_.begin(); + typename charset_map::const_iterator end_ = map_.end(); + + for (; iter_ != end_; ++iter_) + { + list_->push_back(static_cast(0)); + list_->back() = new charset(iter_->first, iter_->second); + } + } + + static void build_set_mapping(const charset_list &charset_list_, + internals &internals_, const id_type dfa_index_, + index_set_vector &set_mapping_) + { + typename charset_list::list::const_iterator iter_ = + charset_list_->begin(); + typename charset_list::list::const_iterator end_ = + charset_list_->end(); + typename index_set::const_iterator set_iter_; + typename index_set::const_iterator set_end_; + + for (id_type index_ = 0; iter_ != end_; ++iter_, ++index_) + { + const charset *cs_ = *iter_; + + set_iter_ = cs_->_index_set.begin(); + set_end_ = cs_->_index_set.end(); + fill_lookup(cs_->_token, internals_._lookup[dfa_index_], + index_, lookup()); + + for (; set_iter_ != set_end_; ++set_iter_) + { + set_mapping_[*set_iter_].insert(index_); + } + } + } + + // char_state_machine version + static void fill_lookup(const string_token &, id_type_vector *, + const id_type, const false_ &) + { + // Do nothing (lookup not used) + } + + // state_machine version + static void fill_lookup(const string_token &charset_, + id_type_vector *lookup_, const id_type index_, const true_ &) + { + typename string_token::range_vector::const_iterator iter_ = + charset_._ranges.begin(); + typename string_token::range_vector::const_iterator end_ = + charset_._ranges.end(); + id_type *ptr_ = &lookup_->front(); + + for (; iter_ != end_; ++iter_) + { + for (typename char_traits::index_type char_ = iter_->first; + char_ < iter_->second; ++char_) + { + // Note char_ must be unsigned + ptr_[char_] = index_ + transitions_index; + } + + // Note iter_->second must be unsigned + ptr_[iter_->second] = index_ + transitions_index; + } + } + + static id_type closure(const node_vector *followpos_, + node_set_vector &seen_sets_, node_vector_vector &seen_vectors_, + size_t_vector &hash_vector_, const id_type size_, id_type_vector &dfa_) + { + bool end_state_ = false; + id_type id_ = 0; + id_type user_id_ = sm_traits::npos(); + id_type next_dfa_ = 0; + id_type push_dfa_ = sm_traits::npos(); + bool pop_dfa_ = false; + std::size_t hash_ = 0; + + if (followpos_->empty()) return sm_traits::npos(); + + id_type index_ = 0; + std::auto_ptr set_ptr_(new node_set); + std::auto_ptr vector_ptr_(new node_vector); + + for (typename node_vector::const_iterator iter_ = + followpos_->begin(), end_ = followpos_->end(); + iter_ != end_; ++iter_) + { + closure_ex(*iter_, end_state_, id_, user_id_, next_dfa_, + push_dfa_, pop_dfa_, set_ptr_.get(), + vector_ptr_.get(), hash_); + } + + bool found_ = false; + typename size_t_vector::const_iterator hash_iter_ = + hash_vector_.begin(); + typename size_t_vector::const_iterator hash_end_ = + hash_vector_.end(); + typename node_set_vector::vector::const_iterator set_iter_ = + seen_sets_->begin(); + + for (; hash_iter_ != hash_end_; ++hash_iter_, ++set_iter_) + { + found_ = *hash_iter_ == hash_ && *(*set_iter_) == *set_ptr_; + ++index_; + + if (found_) break; + } + + if (!found_) + { + seen_sets_->push_back(static_cast(0)); + seen_sets_->back() = set_ptr_.release(); + seen_vectors_->push_back(static_cast(0)); + seen_vectors_->back() = vector_ptr_.release(); + hash_vector_.push_back(hash_); + // State 0 is the jam state... + index_ = static_cast(seen_sets_->size()); + + const std::size_t old_size_ = dfa_.size(); + + dfa_.resize(old_size_ + size_, 0); + + if (end_state_) + { + dfa_[old_size_] |= end_state_bit; + + if (pop_dfa_) + { + dfa_[old_size_] |= pop_dfa_bit; + } + + dfa_[old_size_ + id_index] = id_; + dfa_[old_size_ + user_id_index] = user_id_; + dfa_[old_size_ + push_dfa_index] = push_dfa_; + dfa_[old_size_ + next_dfa_index] = next_dfa_; + } + } + + return index_; + } + + static void closure_ex(node *node_, bool &end_state_, + id_type &id_, id_type &user_id_, id_type &next_dfa_, + id_type &push_dfa_, bool &pop_dfa_, node_set *set_ptr_, + node_vector *vector_ptr_, std::size_t &hash_) + { + const bool temp_end_state_ = node_->end_state(); + + if (temp_end_state_) + { + if (!end_state_) + { + end_state_ = true; + id_ = node_->id(); + user_id_ = node_->user_id(); + next_dfa_ = node_->next_dfa(); + push_dfa_ = node_->push_dfa(); + pop_dfa_ = node_->pop_dfa(); + } + } + + if (set_ptr_->insert(node_).second) + { + vector_ptr_->push_back(node_); + hash_ += reinterpret_cast(node_); + } + } + + // NFA version + static void build_equiv_list(const node_vector *vector_, + const index_set_vector &set_mapping_, equivset_list &lhs_, + const false_ &) + { + fill_rhs_list(vector_, set_mapping_, lhs_); + } + + // DFA version + static void build_equiv_list(const node_vector *vector_, + const index_set_vector &set_mapping_, equivset_list &lhs_, + const true_ &) + { + equivset_list rhs_; + + fill_rhs_list(vector_, set_mapping_, rhs_); + + if (!rhs_->empty()) + { + typename equivset_list::list::iterator iter_; + typename equivset_list::list::iterator end_; + equivset_ptr overlap_(new equivset); + + lhs_->push_back(static_cast(0)); + lhs_->back() = rhs_->front(); + rhs_->pop_front(); + + while (!rhs_->empty()) + { + equivset_ptr r_(rhs_->front()); + + rhs_->pop_front(); + iter_ = lhs_->begin(); + end_ = lhs_->end(); + + while (!r_->empty() && iter_ != end_) + { + typename equivset_list::list::iterator l_iter_ = iter_; + + (*l_iter_)->intersect(*r_.get(), *overlap_.get()); + + if (overlap_->empty()) + { + ++iter_; + } + else if ((*l_iter_)->empty()) + { + delete *l_iter_; + *l_iter_ = overlap_.release(); + overlap_.reset(new equivset); + ++iter_; + } + else if (r_->empty()) + { + delete r_.release(); + r_ = overlap_; + overlap_.reset(new equivset); + break; + } + else + { + iter_ = lhs_->insert(++iter_, + static_cast(0)); + *iter_ = overlap_.release(); + overlap_.reset(new equivset); + ++iter_; + end_ = lhs_->end(); + } + } + + if (!r_->empty()) + { + lhs_->push_back(static_cast(0)); + lhs_->back() = r_.release(); + } + } + } + } + + static void fill_rhs_list(const node_vector *vector_, + const index_set_vector &set_mapping_, equivset_list &list_) + { + typename node_vector::const_iterator iter_ = + vector_->begin(); + typename node_vector::const_iterator end_ = + vector_->end(); + + for (; iter_ != end_; ++iter_) + { + const node *node_ = *iter_; + + if (!node_->end_state()) + { + const id_type token_ = node_->token(); + + if (token_ != node::null_token()) + { + list_->push_back(static_cast(0)); + + if (token_ == parser::bol_token() || + token_ == parser::eol_token()) + { + std::set index_set_; + + index_set_.insert(token_); + list_->back() = new equivset(index_set_, + token_, node_->greedy(), node_->followpos()); + } + else + { + list_->back() = new equivset(set_mapping_[token_], + token_, node_->greedy(), node_->followpos()); + } + } + } + } + } +}; + +typedef basic_generator generator; +typedef basic_generator wgenerator; +typedef basic_generator char_generator; +typedef basic_generator wchar_generator; +} + +#endif diff --git a/Puma/extern/lexertl/internals.hpp b/Puma/extern/lexertl/internals.hpp new file mode 100644 index 0000000..397cd18 --- /dev/null +++ b/Puma/extern/lexertl/internals.hpp @@ -0,0 +1,80 @@ +// internals.hpp +// Copyright (c) 2009-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_INTERNALS_HPP +#define LEXERTL_INTERNALS_HPP + +#include "enums.hpp" +#include "containers/ptr_vector.hpp" + +namespace lexertl +{ +namespace detail +{ +template +struct basic_internals +{ + typedef std::vector id_type_vector; + typedef ptr_vector id_type_vector_vector; + + id_type _eoi; + id_type_vector_vector _lookup; + id_type_vector _dfa_alphabet; + id_type _features; + id_type_vector_vector _dfa; + + basic_internals() : + _eoi(0), + _lookup(), + _dfa_alphabet(), + _features(0), + _dfa() + { + } + + void clear() + { + _eoi = 0; + _lookup.clear(); + _dfa_alphabet.clear(); + _features = 0; + _dfa.clear(); + } + + bool empty() const + { + return _dfa->empty(); + } + + void add_states(const std::size_t num_) + { + for (std::size_t index_ = 0; index_ < num_; ++index_) + { + _lookup->push_back(static_cast(0)); + // lookup *always* has a size 256 now. + _lookup->back() = new id_type_vector(256, dead_state_index); + _dfa_alphabet.push_back(0); + _dfa->push_back(static_cast(0)); + _dfa->back() = new id_type_vector; + } + } + + void swap(basic_internals &internals_) + { + std::swap(_eoi, internals_._eoi); + _lookup->swap(*internals_._lookup); + _dfa_alphabet.swap(internals_._dfa_alphabet); + std::swap(_features, internals_._features); + _dfa->swap(*internals_._dfa); + } + +private: + basic_internals(const basic_internals &); // No copy construction. + basic_internals &operator =(const basic_internals &); // No assignment. +}; +} +} + +#endif diff --git a/Puma/extern/lexertl/is_same.hpp b/Puma/extern/lexertl/is_same.hpp new file mode 100644 index 0000000..959c692 --- /dev/null +++ b/Puma/extern/lexertl/is_same.hpp @@ -0,0 +1,28 @@ +// is_same.hpp +// Copyright (c) 2010-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef LEXERTL_IS_SAME_HPP +#define LEXERTL_IS_SAME_HPP + +namespace lexertl +{ +namespace detail +{ +template +struct is_same +{ + enum {same = false}; +}; + +template +struct is_same +{ + enum {same = true}; +}; +} +} + +#endif diff --git a/Puma/extern/lexertl/iterator.hpp b/Puma/extern/lexertl/iterator.hpp new file mode 100644 index 0000000..9958221 --- /dev/null +++ b/Puma/extern/lexertl/iterator.hpp @@ -0,0 +1,123 @@ +// iterator.hpp +// Copyright (c) 2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef LEXERTL_ITERATOR_HPP +#define LEXERTL_ITERATOR_HPP + +#include +#include "lookup.hpp" + +namespace lexertl +{ +template +class iterator +{ +public: + typedef results value_type; + typedef ptrdiff_t difference_type; + typedef const value_type *pointer; + typedef const value_type &reference; + typedef std::forward_iterator_tag iterator_category; + + iterator() : + _results(iter(), iter()), + _sm(0) + { + } + + iterator(const iter &start_, const iter &end_, const sm_type &sm) : + _results(start_, end_), + _sm(&sm) + { + lookup(); + } + + // Only need this because of warnings with gcc with -Weffc++ + iterator(const iterator &rhs_) + { + _results = rhs_._results; + _sm = rhs_._sm; + } + + // Only need this because of warnings with gcc with -Weffc++ + iterator &operator =(const iterator &rhs_) + { + if (&rhs_ != this) + { + _results = rhs_._results; + _sm = rhs_._sm; + } + + return *this; + } + + iterator &operator ++() + { + lookup(); + return *this; + } + + iterator operator ++(int) + { + iterator iter_ = *this; + + lookup(); + return iter_; + } + + const value_type &operator *() const + { + return _results; + } + + const value_type *operator ->() const + { + return &_results; + } + + bool operator ==(const iterator &rhs_) const + { + return _sm == rhs_._sm && (_sm == 0 ? true : + _results == rhs_._results); + } + + bool operator !=(const iterator &rhs_) const + { + return !(*this == rhs_); + } + +private: + value_type _results; + const sm_type *_sm; + + void lookup() + { + lexertl::lookup(*_sm, _results); + + if (_results.start == _results.eoi) + { + _sm = 0; + } + } +}; + +typedef iterator + siterator; +typedef iterator citerator; +typedef iterator wsiterator; +typedef iterator wciterator; + +typedef iterator + sriterator; +typedef iterator criterator; +typedef iterator wsriterator; +typedef iterator + wcriterator; +} + +#endif diff --git a/Puma/extern/lexertl/licence_1_0.txt b/Puma/extern/lexertl/licence_1_0.txt new file mode 100644 index 0000000..d1c4c6c --- /dev/null +++ b/Puma/extern/lexertl/licence_1_0.txt @@ -0,0 +1,24 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + diff --git a/Puma/extern/lexertl/lookup.hpp b/Puma/extern/lexertl/lookup.hpp new file mode 100644 index 0000000..e651875 --- /dev/null +++ b/Puma/extern/lexertl/lookup.hpp @@ -0,0 +1,477 @@ +// lookup.hpp +// Copyright (c) 2009-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_LOOKUP_HPP +#define LEXERTL_LOOKUP_HPP + +#include +#include "bool.hpp" +#include "match_results.hpp" +#include "state_machine.hpp" + +namespace lexertl +{ +namespace detail +{ +template +struct bol_state +{ + bol_state(const bool) + { + } +}; + +template<> +struct bol_state +{ + bool _bol; + bool _end_bol; + + bol_state(const bool bol_) : + _bol(bol_), + _end_bol(bol_) + { + } +}; + +template +struct eol_state +{ +}; + +template +struct eol_state +{ + id_type _EOL_state; + + eol_state() : + _EOL_state(0) + { + } +}; + +template +struct multi_state_state +{ + multi_state_state(const id_type) + { + } +}; + +template +struct multi_state_state +{ + id_type _start_state; + + multi_state_state(const id_type state_) : + _start_state(state_) + { + } +}; + +template +struct recursive_state +{ + recursive_state(const id_type *) + { + } +}; + +template +struct recursive_state +{ + bool _pop; + id_type _push_dfa; + + recursive_state(const id_type *ptr_) : + _pop((*ptr_ & pop_dfa_bit) != 0), + _push_dfa(*(ptr_ + push_dfa_index)) + { + } +}; + +template +struct lookup_state +{ + typedef basic_internals internals; + + const id_type *_lookup; + id_type _dfa_alphabet; + const id_type *_dfa; + const id_type *_ptr; + bool _end_state; + id_type _id; + id_type _uid; + bol_state<(flags & bol_bit) != 0> _bol_state; + eol_state _eol_state; + multi_state_state + _multi_state_state; + recursive_state _recursive_state; + + lookup_state(const internals &internals_, const bool bol_, + const id_type state_) : + _lookup(&internals_._lookup[state_]->front()), + _dfa_alphabet(internals_._dfa_alphabet[state_]), + _dfa(&internals_._dfa[state_]->front()), + _ptr(_dfa + _dfa_alphabet), + _end_state(*_ptr != 0), + _id(*(_ptr + id_index)), + _uid(*(_ptr + user_id_index)), + _bol_state(bol_), + _eol_state(), + _multi_state_state(state_), + _recursive_state(_ptr) + { + } + + void reset_recursive(const false_ &) + { + // Do nothing + } + + void reset_recursive(const true_ &) + { + _recursive_state._pop = (*_ptr & pop_dfa_bit) != 0; + _recursive_state._push_dfa = *(_ptr + push_dfa_index); + } + + void bol_start_state(const false_ &) + { + // Do nothing + } + + void bol_start_state(const true_ &) + { + if (_bol_state._bol) + { + const id_type state_ = *_dfa; + + if (state_) + { + _ptr = &_dfa[state_ * _dfa_alphabet]; + } + } + } + + template + bool is_eol(const char_type, const false_ &) + { + return false; + } + + template + bool is_eol(const char_type curr_, const true_ &) + { + bool ret_ = false; + + _eol_state._EOL_state = _ptr[eol_index]; + ret_ = _eol_state._EOL_state && curr_ == '\n'; + + if (ret_) + { + _ptr = &_dfa[_eol_state._EOL_state * _dfa_alphabet]; + } + + return ret_; + } + + template + id_type next_char(const char_type prev_char_, const false_ &) + { + const id_type state_= _ptr[_lookup + [static_cast(prev_char_)]]; + + if (state_ != 0) + { + _ptr = &_dfa[state_ * _dfa_alphabet]; + } + + return state_; + } + + template + id_type next_char(const char_type prev_char_, const true_ &) + { + const std::size_t bytes_ = sizeof(char_type) < 3 ? + sizeof(char_type) : 3; + const std::size_t shift_[] = {0, 8, 16}; + id_type state_= 0; + + for (std::size_t i_ = 0; i_ < bytes_; ++i_) + { + state_ = _ptr[_lookup[static_cast((prev_char_ >> + shift_[bytes_ - 1 - i_]) & 0xff)]]; + + if (state_ == 0) + { + break; + } + + _ptr = &_dfa[state_ * _dfa_alphabet]; + } + + return state_; + } + + template + void bol(const char_type, const false_ &) + { + // Do nothing + } + + template + void bol(const char_type prev_char_, const true_ &) + { + _bol_state._bol = prev_char_ == '\n'; + } + + void eol(const id_type, const false_ &) + { + // Do nothing + } + + void eol(const id_type err_val_, const true_ &) + { + _eol_state._EOL_state = err_val_; + } + + void reset_start_state(const false_ &) + { + // Do nothing + } + + void reset_start_state(const true_ &) + { + _multi_state_state._start_state = *(_ptr + next_dfa_index); + } + + void reset_end_bol(const false_ &) + { + // Do nothing + } + + void reset_end_bol(const true_ &) + { + _bol_state._end_bol = _bol_state._bol; + } + + template + void end_state(iter_type &end_token_, iter_type &curr_) + { + if (*_ptr) + { + _end_state = true; + reset_end_bol(bool_<(flags & bol_bit) != 0>()); + _id = *(_ptr + id_index); + _uid = *(_ptr + user_id_index); + reset_recursive(bool_<(flags & recursive_bit) != 0>()); + reset_start_state(bool_<(flags & multi_state_bit) != 0>()); + end_token_ = curr_; + } + } + + template + void check_eol(iter_type &, iter_type &, const id_type, + const char_type, const false_ &) + { + // Do nothing + } + + template + void check_eol(iter_type &end_token_, iter_type &curr_, + const id_type npos, const char_type eoi_, const true_ &) + { + if (_eol_state._EOL_state != npos && curr_ == eoi_) + { + _eol_state._EOL_state = _ptr[eol_index]; + + if (_eol_state._EOL_state) + { + _ptr = &_dfa[_eol_state._EOL_state * _dfa_alphabet]; + end_state(end_token_, curr_); + } + } + } + + template + void pop(results &, const false_ &) + { + // Nothing to do + } + + template + void pop(results &results_, const true_ &) + { + if (_recursive_state._pop) + { + _multi_state_state._start_state = results_.stack.top().first; + results_.stack.pop(); + } + else if (_recursive_state._push_dfa != results::npos()) + { + results_.stack.push(typename results::id_type_pair + (_recursive_state._push_dfa, _id)); + } + } + + template + bool is_id_eoi(const id_type eoi_, const results &, const false_ &) + { + return _id == eoi_; + } + + template + bool is_id_eoi(const id_type eoi_, const results &results_, const true_ &) + { + return _id == eoi_ || (_recursive_state._pop && + !results_.stack.empty() && results_.stack.top().second == eoi_); + } + + void start_state(id_type &, const false_ &) + { + // Do nothing + } + + void start_state(id_type &start_state_, const true_ &) + { + start_state_ = _multi_state_state._start_state; + } + + void bol(bool &, const false_ &) + { + // Do nothing + } + + void bol(bool &end_bol_, const true_ &) + { + end_bol_ = _bol_state._end_bol; + } +}; + +template +void inc_end(results &, const false_ &) +{ + // Do nothing +} + +template +void inc_end(results &results_, const true_ &) +{ + ++results_.end; +} + +template +void next(const basic_state_machine::value_type, id_type> &sm_, + results &results_, const bool_ &compressed_, + const bool_ &recursive_) +{ + const basic_internals &internals_ = sm_.data(); + typename results::iter_type end_token_ = results_.end; + +skip: + typename results::iter_type curr_ = results_.end; + + results_.start = curr_; + +again: + if (curr_ == results_.eoi) + { + results_.id = internals_._eoi; + results_.user_id = results::npos(); + return; + } + + lookup_state lu_state_ + (internals_, results_.bol, results_.state); + lu_state_.bol_start_state(bool_<(flags & bol_bit) != 0>()); + + while (curr_ != results_.eoi) + { + if (!lu_state_.is_eol(*curr_, bool_<(flags & eol_bit) != 0>())) + { + const typename results::char_type prev_char_ = *curr_++; + const id_type state_ = lu_state_.next_char(prev_char_, + compressed_); + + lu_state_.bol(prev_char_, bool_<(flags & bol_bit) != 0>()); + + if (state_ == 0) + { + lu_state_.is_eol(results::npos(), + bool_<(flags & eol_bit) != 0>()); + break; + } + } + + lu_state_.end_state(end_token_, curr_); + } + + lu_state_.check_eol(end_token_, curr_, results::npos(), results_.eoi, + bool_<(flags & eol_bit) != 0>()); + + if (lu_state_._end_state) + { + // Return longest match + lu_state_.pop(results_, recursive_); + + lu_state_.start_state(results_.state, + bool_<(flags & multi_state_bit) != 0>()); + lu_state_.bol(results_.bol, bool_<(flags & bol_bit) != 0>()); + results_.end = end_token_; + + if (lu_state_._id == sm_.skip()) goto skip; + + if (lu_state_.is_id_eoi(internals_._eoi, results_, recursive_)) + { + curr_ = end_token_; + goto again; + } + } + else + { + results_.end = end_token_; + results_.bol = *results_.end == '\n'; + results_.start = results_.end; + // No match causes char to be skipped + inc_end(results_, bool_<(flags & advance_bit) != 0>()); + lu_state_._id = results::npos(); + lu_state_._uid = results::npos(); + } + + results_.id = lu_state_._id; + results_.user_id = lu_state_._uid; +} +} + +template +void lookup(const basic_state_machine::value_type, id_type> &sm_, + match_results &results_) +{ + // If this asserts, you have either not defined all the correct + // flags, or you should be using recursive_match_results instead + // of match_results. + assert((sm_.data()._features & flags) == sm_.data()._features); + detail::next(sm_, results_, bool_<(sizeof + (typename std::iterator_traits::value_type) > 1)>(), + false_()); +} + +template +void lookup(const basic_state_machine::value_type, id_type> &sm_, + recursive_match_results &results_) +{ + // If this asserts, you have not defined all the correct flags + assert((sm_.data()._features & flags) == sm_.data()._features); + detail::next(sm_, results_, + bool_<(sizeof(typename std::iterator_traits:: + value_type) > 1)>(), true_()); +} +} + +#endif diff --git a/Puma/extern/lexertl/match_results.hpp b/Puma/extern/lexertl/match_results.hpp new file mode 100644 index 0000000..a4e141f --- /dev/null +++ b/Puma/extern/lexertl/match_results.hpp @@ -0,0 +1,166 @@ +// match_results.hpp +// Copyright (c) 2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_MATCH_RESULTS_HPP +#define LEXERTL_MATCH_RESULTS_HPP + +#include "char_traits.hpp" +#include "enums.hpp" +#include +#include +#include + +namespace lexertl +{ +template +struct match_results +{ + typedef iter iter_type; + typedef typename std::iterator_traits::value_type char_type; + typedef typename basic_char_traits::index_type index_type; + typedef std::basic_string string; + + id_type id; + id_type user_id; + iter_type start; + iter_type end; + iter_type eoi; + bool bol; + id_type state; + + match_results() : + id(0), + user_id(npos()), + start(iter_type()), + end(iter_type()), + eoi(iter_type()), + bol(true), + state(0) + { + } + + match_results(const iter_type &start_, const iter_type &end_) : + id(0), + user_id(npos()), + start(start_), + end(start_), + eoi(end_), + bol(true), + state(0) + { + } + + virtual ~match_results() + { + } + + string str() const + { + return string(start, end); + } + + string substr(const std::size_t soffset_, const std::size_t eoffset_) const + { + return string(start + soffset_, end - eoffset_); + } + + virtual void clear() + { + id = 0; + user_id = npos(); + start = eoi; + end = eoi; + bol = true; + state = 0; + } + + virtual void reset(const iter_type &start_, const iter_type &end_) + { + id = 0; + user_id = npos(); + start = start_; + end = start_; + eoi = end_; + bol = true; + state = 0; + } + + static id_type npos() + { + return ~static_cast(0); + } + + static id_type skip() + { + return ~static_cast(1); + } + + bool operator ==(const match_results &rhs_) const + { + return id == rhs_.id && + user_id == rhs_.user_id && + start == rhs_.start && + end == rhs_.end && + eoi == rhs_.eoi && + bol == rhs_.bol && + state == rhs_.state; + } +}; + +template +struct recursive_match_results : public match_results +{ + typedef std::pair id_type_pair; + std::stack stack; + + recursive_match_results() : + match_results(), + stack() + { + } + + recursive_match_results(const iter &start_, const iter &end_) : + match_results(start_, end_), + stack() + { + } + + virtual ~recursive_match_results() + { + } + + virtual void clear() + { + match_results::clear(); + + while (!stack.empty()) stack.pop(); + } + + virtual void reset(const iter &start_, const iter &end_) + { + match_results::reset(start_, end_); + + while (!stack.empty()) stack.pop(); + } +}; + +typedef match_results smatch; +typedef match_results cmatch; +typedef match_results wsmatch; +typedef match_results wcmatch; + +typedef recursive_match_results + srmatch; +typedef recursive_match_results crmatch; +typedef recursive_match_results + wsrmatch; +typedef recursive_match_results wcrmatch; +} + +#endif diff --git a/Puma/extern/lexertl/memory_file.hpp b/Puma/extern/lexertl/memory_file.hpp new file mode 100644 index 0000000..6a4f784 --- /dev/null +++ b/Puma/extern/lexertl/memory_file.hpp @@ -0,0 +1,144 @@ +// memory_file.hpp +// Copyright (c) 2015 Ben Hanson (http://www.benhanson.net/) +// Inspired by http://en.wikibooks.org/wiki/Optimizing_C%2B%2B/ +// General_optimization_techniques/Input/Output#Memory-mapped_file +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef LEXERTL_MEMORY_FILE_H +#define LEXERTL_MEMORY_FILE_H + +#include + +#ifdef __unix__ +#include +#include +#include +#include +#elif defined _WIN32 +#include +#endif + +// Only files small enough to fit into memory are supported. +namespace lexertl +{ +template +class basic_memory_file +{ +public: + basic_memory_file(const char *pathname_) : + _data(0), + _size(0), +#ifdef __unix__ + _fh(0) +#else + _fh(0), + _fmh(0) +#endif + { + open(pathname_); + } + + ~basic_memory_file() + { + close(); + } + + void open(const char *pathname_) + { + if (_data) close(); + +#ifdef __unix__ + _fh = ::open(pathname_, O_RDONLY); + + if (_fh > -1) + { + struct stat sbuf_; + + if (::fstat(_fh, &sbuf_) > -1) + { + _data = static_cast + (::mmap(0, sbuf_.st_size, PROT_READ, MAP_SHARED, _fh, 0)); + + if (_data == MAP_FAILED) + { + _data = 0; + } + else + { + _size = sbuf_.st_size / sizeof(char_type); + } + } + } +#elif defined _WIN32 + _fh = ::CreateFileA(pathname_, GENERIC_READ, FILE_SHARE_READ, 0, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); + _fmh = 0; + + if (_fh != INVALID_HANDLE_VALUE) + { + _fmh = ::CreateFileMapping(_fh, 0, PAGE_READONLY, 0, 0, 0); + + if (_fmh != 0) + { + _data = static_cast(::MapViewOfFile + (_fmh, FILE_MAP_READ, 0, 0, 0)); + + if (_data) _size = ::GetFileSize(_fh, 0) / sizeof(char_type); + } + } +#endif + } + + const char_type *data() const + { + return _data; + } + + std::size_t size() const + { + return _size; + } + + void close() + { +#if defined(__unix__) + ::munmap(const_cast(_data), _size); + ::close(_fh); +#elif defined(_WIN32) + ::UnmapViewOfFile(_data); + ::CloseHandle(_fmh); + ::CloseHandle(_fh); +#endif + _data = 0; + _size = 0; + _fh = 0; +#ifndef __unix__ + _fmh = 0; +#endif + } + +private: + const char_type *_data; + std::size_t _size; +#ifdef __unix__ + int _fh; +#elif defined _WIN32 + HANDLE _fh; + HANDLE _fmh; +#else + #error Only Posix or Windows are supported. +#endif + + // No copy construction. + basic_memory_file(const basic_memory_file &); + // No assignment. + basic_memory_file &operator =(const basic_memory_file &); +}; + +typedef basic_memory_file memory_file; +typedef basic_memory_file wmemory_file; +} + +#endif diff --git a/Puma/extern/lexertl/narrow.hpp b/Puma/extern/lexertl/narrow.hpp new file mode 100644 index 0000000..cf64b74 --- /dev/null +++ b/Puma/extern/lexertl/narrow.hpp @@ -0,0 +1,25 @@ +// narrow.hpp +// Copyright (c) 2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_NARROW_HPP +#define LEXERTL_NARROW_HPP + +#include + +namespace lexertl +{ +template +void narrow(const char_type *str_, std::ostringstream &ss_) +{ + while (*str_) + { + // Safe to simply cast to char. + // when string only contains ASCII. + ss_ << static_cast(*str_++); + } +} +} + +#endif diff --git a/Puma/extern/lexertl/old/fast_filebuf.hpp b/Puma/extern/lexertl/old/fast_filebuf.hpp new file mode 100644 index 0000000..273487b --- /dev/null +++ b/Puma/extern/lexertl/old/fast_filebuf.hpp @@ -0,0 +1,45 @@ +// Quick hack... +// If you find this really is faster then using std::ifstream, let me know +// as I can always spend some more time to improve it. + +namespace lexertl +{ +template +class basic_fast_filebuf : public std::basic_streambuf +{ +public: + basic_fast_filebuf(const char *filename_) : + _fp(0) + { + _fp = ::fopen(filename_, "r"); + } + + virtual ~basic_fast_filebuf() + { + ::fclose(_fp); + _fp = 0; + } + +protected: + FILE *_fp; + + virtual std::streamsize xsgetn(CharT *ptr_, std::streamsize count_) + { + return ::fread(ptr_, sizeof(CharT), + static_cast(count_), _fp); + } +}; + +typedef basic_fast_filebuf > fast_filebuf; +typedef basic_fast_filebuf > wfast_filebuf; +} + +// Usage: +// lexertl::rules rules_; +// lexertl::state_machine state_machine_; +// fast_filebuf buf("Unicode/PropList.txt"); +// std::istream if_(&buf); +// lexertl::stream_shared_iterator iter_(if_); +// lexertl::stream_shared_iterator end_; +// lexertl::match_results +// results_(iter_, end_); diff --git a/Puma/extern/lexertl/old/string_token.hpp b/Puma/extern/lexertl/old/string_token.hpp new file mode 100644 index 0000000..fa142ce --- /dev/null +++ b/Puma/extern/lexertl/old/string_token.hpp @@ -0,0 +1,561 @@ +// string_token.hpp +// Copyright (c) 2005-2010 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_STRING_TOKEN_HPP +#define LEXERTL_STRING_TOKEN_HPP + +#include "../char_traits.hpp" +#include +#include +#include +#include +#include + +namespace lexertl +{ +template +struct basic_string_token +{ + typedef std::basic_string string; + + bool _negated; + string _chars; + + basic_string_token() : + _negated(false) + { + } + + basic_string_token(const bool negated_, const string &chars_) : + _negated(negated_), + _chars(chars_) + { + } + + void remove_duplicates() + { + const char_type *start_ = _chars.c_str(); + const char_type *end_ = start_ + _chars.size(); + + // Optimisation for very large charsets: + // sorting via pointers is much quicker than + // via iterators... + std::sort(const_cast(start_), const_cast + (end_)); + _chars.erase(std::unique(_chars.begin(), _chars.end()), + _chars.end()); + } + + void normalise() + { + const std::size_t max_chars_ = sizeof(char_type) == 1 ? + num_chars : num_wchar_ts; + + if (_chars.length() == max_chars_) + { + _negated = !_negated; + _chars.clear(); + } + else if (_chars.length() > max_chars_ / 2) + { + negate(); + } + } + + void negate() + { + const std::size_t max_chars_ = sizeof(char_type) == 1 ? + num_chars : num_wchar_ts; + char_type curr_char_ = std::numeric_limits::min(); + string temp_; + const char_type *curr_ = _chars.c_str(); + const char_type *chars_end_ = curr_ + _chars.size(); + + _negated = !_negated; + temp_.resize(max_chars_ - _chars.size()); + + char_type *ptr_ = const_cast(temp_.c_str()); + std::size_t i_ = 0; + + while (curr_ < chars_end_) + { + while (*curr_ > curr_char_) + { + *ptr_ = curr_char_; + ++ptr_; + ++curr_char_; + ++i_; + } + + ++curr_char_; + ++curr_; + ++i_; + } + + for (; i_ < max_chars_; ++i_) + { + *ptr_ = curr_char_; + ++ptr_; + ++curr_char_; + } + + _chars = temp_; + } + + bool operator <(const basic_string_token &rhs_) const + { + return _negated < rhs_._negated || + (_negated == rhs_._negated && _chars < rhs_._chars); + } + + bool operator ==(const basic_string_token &rhs_) const + { + return _negated == rhs_._negated && _chars == rhs_._chars; + } + + bool empty() const + { + return _chars.empty() && !_negated; + } + + bool any() const + { + return _chars.empty() && _negated; + } + + void clear() + { + _negated = false; + _chars.clear(); + } + + void intersect(basic_string_token &rhs_, basic_string_token &overlap_) + { + if ((any() && rhs_.any()) || (_negated == rhs_._negated && + !any() && !rhs_.any())) + { + intersect_same_types(rhs_, overlap_); + } + else + { + intersect_diff_types(rhs_, overlap_); + } + } + + void merge(const basic_string_token &rhs_, + basic_string_token &merged_) const + { + if ((any() && rhs_.any()) || (_negated == rhs_._negated && + !any() && !rhs_.any())) + { + merge_same_types(rhs_, merged_); + } + else + { + merge_diff_types(rhs_, merged_); + } + } + + static string escape_char(const char_type ch_) + { + string out_; + + switch (ch_) + { + case '\0': + out_ += '\\'; + out_ += '0'; + break; + case '\a': + out_ += '\\'; + out_ += 'a'; + break; + case '\b': + out_ += '\\'; + out_ += 'b'; + break; + case 27: + out_ += '\\'; + out_ += 'x'; + out_ += '1'; + out_ += 'b'; + break; + case '\f': + out_ += '\\'; + out_ += 'f'; + break; + case '\n': + out_ += '\\'; + out_ += 'n'; + break; + case '\r': + out_ += '\\'; + out_ += 'r'; + break; + case '\t': + out_ += '\\'; + out_ += 't'; + break; + case '\v': + out_ += '\\'; + out_ += 'v'; + break; + case '\\': + out_ += '\\'; + out_ += '\\'; + break; + case '"': + out_ += '\\'; + out_ += '"'; + break; + case '\'': + out_ += '\\'; + out_ += '\''; + break; + default: + { + if (ch_ < 32) + { + std::basic_stringstream ss_; + + out_ += '\\'; + out_ += 'x'; + ss_ << std::hex << + static_cast(ch_); + out_ += ss_.str(); + } + else + { + out_ += ch_; + } + + break; + } + } + + return out_; + } + +private: + void intersect_same_types(basic_string_token &rhs_, + basic_string_token &overlap_) + { + if (any()) + { + clear(); + overlap_._negated = true; + rhs_.clear(); + } + else + { + typename string::iterator iter_ = _chars.begin(); + typename string::iterator end_ = _chars.end(); + typename string::iterator rhs_iter_ = rhs_._chars.begin(); + typename string::iterator rhs_end_ = rhs_._chars.end(); + + overlap_._negated = _negated; + + while (iter_ != end_ && rhs_iter_ != rhs_end_) + { + if (*iter_ < *rhs_iter_) + { + ++iter_; + } + else if (*iter_ > *rhs_iter_) + { + ++rhs_iter_; + } + else + { + overlap_._chars += *iter_; + iter_ = _chars.erase(iter_); + end_ = _chars.end(); + rhs_iter_ = rhs_._chars.erase(rhs_iter_); + rhs_end_ = rhs_._chars.end(); + } + } + + if (_negated) + { + // duplicates already merged, so safe to merge + // using std lib. + + // src, dest + merge(_chars, overlap_._chars); + // duplicates already merged, so safe to merge + // using std lib. + + // src, dest + merge(rhs_._chars, overlap_._chars); + _negated = false; + rhs_._negated = false; + std::swap(_chars, rhs_._chars); + normalise(); + overlap_.normalise(); + rhs_.normalise(); + } + else if (!overlap_._chars.empty()) + { + normalise(); + overlap_.normalise(); + rhs_.normalise(); + } + } + } + + void intersect_diff_types(basic_string_token &rhs_, + basic_string_token &overlap_) + { + if (any()) + { + intersect_any(rhs_, overlap_); + } + else if (_negated) + { + intersect_negated(rhs_, overlap_); + } + else // _negated == false + { + intersect_charset(rhs_, overlap_); + } + } + + void intersect_any(basic_string_token &rhs_, basic_string_token &overlap_) + { + if (rhs_._negated) + { + rhs_.intersect_negated(*this, overlap_); + } + else // rhs._negated == false + { + rhs_.intersect_charset(*this, overlap_); + } + } + + void intersect_negated(basic_string_token &rhs_, + basic_string_token &overlap_) + { + if (rhs_.any()) + { + overlap_._negated = true; + overlap_._chars = _chars; + rhs_._negated = false; + rhs_._chars = _chars; + clear(); + } + else // rhs._negated == false + { + rhs_.intersect_charset(*this, overlap_); + } + } + + void intersect_charset(basic_string_token &rhs_, + basic_string_token &overlap_) + { + if (rhs_.any()) + { + overlap_._chars = _chars; + rhs_._negated = true; + rhs_._chars = _chars; + clear(); + } + else // rhs_._negated == true + { + typename string::iterator iter_ = _chars.begin(); + typename string::iterator end_ = _chars.end(); + typename string::iterator rhs_iter_ = rhs_._chars.begin(); + typename string::iterator rhs_end_ = rhs_._chars.end(); + + while (iter_ != end_ && rhs_iter_ != rhs_end_) + { + if (*iter_ < *rhs_iter_) + { + overlap_._chars += *iter_; + rhs_iter_ = rhs_._chars.insert(rhs_iter_, *iter_); + ++rhs_iter_; + rhs_end_ = rhs_._chars.end(); + iter_ = _chars.erase(iter_); + end_ = _chars.end(); + } + else if (*iter_ > *rhs_iter_) + { + ++rhs_iter_; + } + else + { + ++iter_; + ++rhs_iter_; + } + } + + if (iter_ != end_) + { + // nothing bigger in rhs_ than iter_, + // so safe to merge using std lib. + string temp_(iter_, end_); + + // src, dest + merge(temp_, overlap_._chars); + _chars.erase(iter_, end_); + } + + if (!overlap_._chars.empty()) + { + merge(overlap_._chars, rhs_._chars); + // possible duplicates, so check for any and erase. + rhs_._chars.erase(std::unique(rhs_._chars.begin(), + rhs_._chars.end()), rhs_._chars.end()); + normalise(); + overlap_.normalise(); + rhs_.normalise(); + } + } + } + + void merge(string &src_, string &dest_) + { + string tmp_(src_.size() + dest_.size(), 0); + + std::merge(src_.begin(), src_.end(), dest_.begin(), dest_.end(), + tmp_.begin()); + dest_ = tmp_; + } + + void merge_same_types(const basic_string_token &rhs_, + basic_string_token &merged_) const + { + if (any()) + { + merged_._negated = true; + } + else if (_negated) + { + typename string::const_iterator iter_ = _chars.begin(); + typename string::const_iterator end_ = _chars.end(); + typename string::const_iterator rhs_iter_ = rhs_._chars.begin(); + typename string::const_iterator rhs_end_ = rhs_._chars.end(); + + merged_._negated = _negated; + + while (iter_ != end_ && rhs_iter_ != rhs_end_) + { + if (*iter_ < *rhs_iter_) + { + ++iter_; + } + else if (*iter_ > *rhs_iter_) + { + ++rhs_iter_; + } + else + { + merged_._chars += *iter_; + ++iter_; + ++rhs_iter_; + } + } + + merged_.normalise(); + } + else + { + typename string::const_iterator iter_ = _chars.begin(); + typename string::const_iterator end_ = _chars.end(); + typename string::const_iterator rhs_iter_ = rhs_._chars.begin(); + typename string::const_iterator rhs_end_ = rhs_._chars.end(); + + while (iter_ != end_ && rhs_iter_ != rhs_end_) + { + if (*iter_ < *rhs_iter_) + { + merged_._chars += *iter_; + ++iter_; + } + else if (*iter_ > *rhs_iter_) + { + merged_._chars += *rhs_iter_; + ++rhs_iter_; + } + else + { + merged_._chars += *iter_; + ++iter_; + ++rhs_iter_; + } + } + + // Include any trailing chars + if (iter_ != end_) + { + string temp_(iter_, end_); + + merged_._chars += temp_; + } + else if (rhs_iter_ != rhs_end_) + { + string temp_(rhs_iter_, rhs_end_); + + merged_._chars += temp_; + } + + merged_.normalise(); + } + } + + void merge_diff_types(const basic_string_token &rhs_, + basic_string_token &merged_) const + { + if (_negated) + { + merge_negated(*this, rhs_, merged_); + } + else + { + merge_negated(rhs_, *this, merged_); + } + + merged_.normalise(); + } + + void merge_negated(const basic_string_token &lhs_, + const basic_string_token &rhs_, basic_string_token &merged_) const + { + typename string::const_iterator lhs_iter_ = lhs_._chars.begin(); + typename string::const_iterator lhs_end_ = lhs_._chars.end(); + typename string::const_iterator rhs_iter_ = rhs_._chars.begin(); + typename string::const_iterator rhs_end_ = rhs_._chars.end(); + + merged_._negated = true; + + while (lhs_iter_ != lhs_end_ && rhs_iter_ != rhs_end_) + { + if (*lhs_iter_ < *rhs_iter_) + { + merged_._chars += *lhs_iter_; + ++lhs_iter_; + } + else if (*lhs_iter_ > *rhs_iter_) + { + ++rhs_iter_; + } + else + { + ++lhs_iter_; + ++rhs_iter_; + } + } + + // Only interested in any remaining 'negated' chars + if (lhs_iter_ != lhs_end_) + { + string temp_(lhs_iter_, lhs_end_); + + merged_._chars += temp_; + } + } +}; +} + +#endif diff --git a/Puma/extern/lexertl/parser/parser.hpp b/Puma/extern/lexertl/parser/parser.hpp new file mode 100644 index 0000000..a002bd4 --- /dev/null +++ b/Puma/extern/lexertl/parser/parser.hpp @@ -0,0 +1,1030 @@ +// parser.hpp +// Copyright (c) 2005-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_PARSER_HPP +#define LEXERTL_PARSER_HPP + +#include +#include +#include "../bool.hpp" +#include "tree/end_node.hpp" +#include "tree/iteration_node.hpp" +#include "tree/leaf_node.hpp" +#include +#include "../containers/ptr_stack.hpp" +#include "tokeniser/re_tokeniser.hpp" +#include "../runtime_error.hpp" +#include "tree/selection_node.hpp" +#include "tree/sequence_node.hpp" +#include "../size_t.hpp" +#include + +namespace lexertl +{ +namespace detail +{ +/* + General principles of regex parsing: + - Every regex is a sequence of sub-regexes. + - Regexes consist of operands and operators + - All operators decompose to sequence, selection ('|') and iteration ('*') + - Regex tokens are stored on a stack. + - When a complete sequence of regex tokens is on the stack it is processed. + +Grammar: + + -> + -> | '|' + -> + -> | + -> + -> charset | macro | '('')' | + -> '?' | '??' | '*' | '*?' | '+' | '+?' | '{n[,[m]]}' | + '{n[,[m]]}?' +*/ + +template +class basic_parser +{ +public: + enum {char_24_bit = sm_traits::char_24_bit}; + typedef typename sm_traits::char_type char_type; + typedef typename sm_traits::id_type id_type; + typedef basic_end_node end_node; + typedef typename sm_traits::input_char_type input_char_type; + typedef basic_string_token input_string_token; + typedef basic_iteration_node iteration_node; + typedef basic_leaf_node leaf_node; + typedef basic_re_tokeniser + tokeniser; + typedef basic_node node; + typedef typename node::node_ptr_vector node_ptr_vector; + typedef std::basic_string string; + typedef basic_string_token string_token; + typedef basic_selection_node selection_node; + typedef basic_sequence_node sequence_node; + typedef std::map charset_map; + typedef std::pair charset_pair; + typedef bool_ compressed; + typedef basic_re_token token; + typedef std::deque token_deque; + + basic_parser(const std::locale &locale_, + node_ptr_vector &node_ptr_vector_, + charset_map &charset_map_, const id_type eoi_) : + _locale(locale_), + _node_ptr_vector(node_ptr_vector_), + _charset_map(charset_map_), + _eoi(eoi_), + _token_stack(), + _tree_node_stack() + { + } + + node *parse(const token_deque ®ex_, const id_type id_, + const id_type user_id_, const id_type next_dfa_, + const id_type push_dfa_, const bool pop_dfa_, + const std::size_t flags_, id_type &nl_id_, const bool seen_bol_) + { + typename token_deque::const_iterator iter_ = regex_.begin(); + typename token_deque::const_iterator end_ = regex_.end(); + node *root_ = 0; + token *lhs_token_ = 0; + // There cannot be less than 2 tokens + std::auto_ptr rhs_token_(new token(*iter_++)); + char action_ = 0; + + _token_stack->push(static_cast(0)); + _token_stack->top() = rhs_token_.release(); + rhs_token_.reset(new token(*iter_)); + + if (iter_ + 1 != end_) ++iter_; + + do + { + lhs_token_ = _token_stack->top(); + action_ = lhs_token_->precedence(rhs_token_->_type); + + switch (action_) + { + case '<': + case '=': + _token_stack->push(static_cast(0)); + _token_stack->top() = rhs_token_.release(); + rhs_token_.reset(new token(*iter_)); + + if (iter_ + 1 != end_) ++iter_; + + break; + case '>': + reduce(nl_id_); + break; + default: + { + std::ostringstream ss_; + + ss_ << "A syntax error occurred: '" << + lhs_token_->precedence_string() << + "' against '" << rhs_token_->precedence_string() << + " in rule id " << id_ << '.'; + throw runtime_error(ss_.str()); + break; + } + } + } while (!_token_stack->empty()); + + if (_tree_node_stack.empty()) + { + std::ostringstream ss_; + + ss_ << "Empty rules are not allowed in rule id " << + id_ << '.'; + throw runtime_error(ss_.str()); + } + + assert(_tree_node_stack.size() == 1); + + node *lhs_node_ = _tree_node_stack.top(); + + _tree_node_stack.pop(); + _node_ptr_vector->push_back(static_cast(0)); + + node *rhs_node_ = new end_node(id_, user_id_, next_dfa_, + push_dfa_, pop_dfa_); + + _node_ptr_vector->back() = rhs_node_; + _node_ptr_vector->push_back(static_cast(0)); + _node_ptr_vector->back() = new sequence_node + (lhs_node_, rhs_node_); + root_ = _node_ptr_vector->back(); + + if (seen_bol_) + { + fixup_bol(root_); + } + + if ((flags_ & match_zero_len) == 0) + { + const typename node::node_vector &firstpos_ = root_->firstpos(); + typename node::node_vector::const_iterator iter_ = + firstpos_.begin(); + typename node::node_vector::const_iterator end_ = + firstpos_.end(); + + for (; iter_ != end_; ++iter_) + { + const node *node_ = *iter_; + + if (node_->end_state()) + { + std::ostringstream ss_; + + ss_ << "Rules that match zero characters are not allowed " + "as this can cause an infinite loop in user code. The " + "match_zero_len flag overrides this check. Rule id " << + id_ << '.'; + throw runtime_error(ss_.str()); + } + } + } + + return root_; + } + + static id_type bol_token() + { + return ~static_cast(1); + } + + static id_type eol_token() + { + return ~static_cast(2); + } + +private: + typedef typename input_string_token::range input_range; + typedef typename string_token::range range; + typedef ptr_vector string_token_vector; + typedef ptr_stack token_stack; + typedef typename node::node_stack tree_node_stack; + + const std::locale &_locale; + node_ptr_vector &_node_ptr_vector; + charset_map &_charset_map; + id_type _eoi; + token_stack _token_stack; + tree_node_stack _tree_node_stack; + + struct find_functor + { + // Pointer to stop warning about cannot create assignment operator. + const string_token *_token; + + find_functor(const string_token &token_) : + _token(&token_) + { + } + + bool operator ()(const string_token *rhs_) + { + return *_token == *rhs_; + } + }; + + void reduce(id_type &nl_id_) + { + token *lhs_ = 0; + token *rhs_ = 0; + token_stack handle_; + char action_ = 0; + + do + { + rhs_ = _token_stack->top(); + handle_->push(static_cast(0)); + _token_stack->pop(); + handle_->top() = rhs_; + + if (!_token_stack->empty()) + { + lhs_ = _token_stack->top(); + action_ = lhs_->precedence(rhs_->_type); + } + } while (!_token_stack->empty() && action_ == '='); + + assert(_token_stack->empty() || action_ == '<'); + + switch (rhs_->_type) + { + case BEGIN: + // finished processing so exit + break; + case REGEX: + // finished parsing, nothing to do + break; + case OREXP: + orexp(handle_); + break; + case SEQUENCE: + _token_stack->push(static_cast(0)); + _token_stack->top() = new token(OREXP); + break; + case SUB: + sub(handle_); + break; + case EXPRESSION: + _token_stack->push(static_cast(0)); + _token_stack->top() = new token(SUB); + break; + case REPEAT: + repeat(handle_); + break; + case BOL: + bol(handle_); + break; + case EOL: + eol(handle_, nl_id_); + break; + case CHARSET: + charset(handle_, compressed()); + break; + case OPENPAREN: + openparen(handle_); + break; + case OPT: + case AOPT: + optional(rhs_->_type == OPT); + _token_stack->push(static_cast(0)); + _token_stack->top() = new token(DUP); + break; + case ZEROORMORE: + case AZEROORMORE: + zero_or_more(rhs_->_type == ZEROORMORE); + _token_stack->push(static_cast(0)); + _token_stack->top() = new token(DUP); + break; + case ONEORMORE: + case AONEORMORE: + one_or_more(rhs_->_type == ONEORMORE); + _token_stack->push(static_cast(0)); + _token_stack->top() = new token(DUP); + break; + case REPEATN: + case AREPEATN: + repeatn(rhs_->_type == REPEATN, handle_->top()); + _token_stack->push(static_cast(0)); + _token_stack->top() = new token(DUP); + break; + default: + throw runtime_error + ("Internal error in regex_parser::reduce."); + break; + } + } + + void orexp(token_stack &handle_) + { + assert(handle_->top()->_type == OREXP && + (handle_->size() == 1 || handle_->size() == 3)); + + if (handle_->size() == 1) + { + std::auto_ptr token_(new token(REGEX)); + + _token_stack->push(static_cast(0)); + _token_stack->top() = token_.release(); + } + else + { + token *token_ = handle_->top(); + + handle_->pop(); + delete token_; + token_ = 0; + assert(handle_->top()->_type == OR); + token_ = handle_->top(); + handle_->pop(); + delete token_; + token_ = 0; + assert(handle_->top()->_type == SEQUENCE); + perform_or(); + _token_stack->push(static_cast(0)); + _token_stack->top() = new token(OREXP); + } + } + + void perform_or() + { + // perform or + node *rhs_ = _tree_node_stack.top(); + + _tree_node_stack.pop(); + + node *lhs_ = _tree_node_stack.top(); + + _node_ptr_vector->push_back(static_cast(0)); + _node_ptr_vector->back() = new selection_node(lhs_, rhs_); + _tree_node_stack.top() = _node_ptr_vector->back(); + } + + void sub(token_stack &handle_) + { + assert((handle_->top()->_type == SUB && + handle_->size() == 1) || handle_->size() == 2); + + if (handle_->size() == 1) + { + _token_stack->push(static_cast(0)); + _token_stack->top() = new token(SEQUENCE); + } + else + { + token *token_ = handle_->top(); + + handle_->pop(); + delete token_; + token_ = 0; + assert(handle_->top()->_type == EXPRESSION); + // perform join + sequence(); + _token_stack->push(static_cast(0)); + _token_stack->top() = new token(SUB); + } + } + + void repeat(token_stack &handle_) + { + assert(handle_->top()->_type == REPEAT && + handle_->size() >= 1 && handle_->size() <= 3); + + if (handle_->size() == 1) + { + _token_stack->push(static_cast(0)); + _token_stack->top() = new token(EXPRESSION); + } + else + { + token *token_ = handle_->top(); + + handle_->pop(); + delete token_; + token_ = 0; + assert(handle_->top()->_type == DUP); + _token_stack->push(static_cast(0)); + _token_stack->top() = new token(REPEAT); + } + } + +#ifndef NDEBUG + void bol(token_stack &handle_) +#else + void bol(token_stack &) +#endif + { + assert(handle_->top()->_type == BOL && + handle_->size() == 1); + + // store charset + _node_ptr_vector->push_back(static_cast(0)); + _node_ptr_vector->back() = new leaf_node(bol_token(), true); + _tree_node_stack.push(_node_ptr_vector->back()); + _token_stack->push(static_cast(0)); + _token_stack->top() = new token(REPEAT); + } + +#ifndef NDEBUG + void eol(token_stack &handle_, id_type &nl_id_) +#else + void eol(token_stack &, id_type &nl_id_) +#endif + { + const string_token nl_('\n'); + const id_type temp_nl_id_ = lookup(nl_); + + assert(handle_->top()->_type == EOL && + handle_->size() == 1); + + if (temp_nl_id_ != ~static_cast(0)) + { + nl_id_ = temp_nl_id_; + } + + // store charset + _node_ptr_vector->push_back(static_cast(0)); + _node_ptr_vector->back() = new leaf_node(eol_token(), true); + _tree_node_stack.push(_node_ptr_vector->back()); + _token_stack->push(static_cast(0)); + _token_stack->top() = new token(REPEAT); + } + + // Uncompressed + void charset(token_stack &handle_, const false_ &) + { + assert(handle_->top()->_type == CHARSET && + handle_->size() == 1); + + const id_type id_ = lookup(handle_->top()->_str); + + // store charset + _node_ptr_vector->push_back(static_cast(0)); + _node_ptr_vector->back() = new leaf_node(id_, true); + _tree_node_stack.push(_node_ptr_vector->back()); + _token_stack->push(static_cast(0)); + _token_stack->top() = new token(REPEAT); + } + + // Compressed + void charset(token_stack &handle_, const true_ &) + { + assert(handle_->top()->_type == CHARSET && + handle_->size() == 1); + + std::auto_ptr token_(handle_->top()); + + handle_->pop(); + create_sequence(token_); + } + + // Slice wchar_t into sequence of char. + void create_sequence(std::auto_ptr &token_) + { + typename token::string_token::range_vector::iterator iter_ = + token_->_str._ranges.begin(); + typename token::string_token::range_vector::const_iterator end_ = + token_->_str._ranges.end(); + + string_token_vector data_[char_24_bit ? 3 : 2]; + + for (; iter_ != end_; ++iter_) + { + slice_range(*iter_, data_, bool_()); + } + + push_ranges(data_, bool_()); + + _token_stack->push(static_cast(0)); + _token_stack->top() = new token(OPENPAREN); + _token_stack->push(static_cast(0)); + _token_stack->top() = new token(REGEX); + _token_stack->push(static_cast(0)); + _token_stack->top() = new token(CLOSEPAREN); + } + + // 16 bit unicode + void slice_range(const input_range &range_, string_token_vector data_[2], + const false_ &) + { + const unsigned char first_msb_ = static_cast + ((range_.first >> 8) & 0xff); + const unsigned char first_lsb_ = static_cast + (range_.first & 0xff); + const unsigned char second_msb_ = static_cast + ((range_.second >> 8) & 0xff); + const unsigned char second_lsb_ = static_cast + (range_.second & 0xff); + + if (first_msb_ == second_msb_) + { + insert_range(first_msb_, first_msb_, first_lsb_, + second_lsb_, data_); + } + else + { + insert_range(first_msb_, first_msb_, first_lsb_, 0xff, data_); + + if (second_msb_ > first_msb_ + 1) + { + insert_range(first_msb_ + 1, second_msb_ - 1, 0, 0xff, data_); + } + + insert_range(second_msb_, second_msb_, 0, second_lsb_, data_); + } + } + + // 24 bit unicode + void slice_range(const input_range &range_, string_token_vector data_[3], + const true_ &) + { + const unsigned char first_msb_ = static_cast + ((range_.first >> 16) & 0xff); + const unsigned char first_mid_ = static_cast + ((range_.first >> 8) & 0xff); + const unsigned char first_lsb_ = static_cast + (range_.first & 0xff); + const unsigned char second_msb_ = static_cast + ((range_.second >> 16) & 0xff); + const unsigned char second_mid_ = static_cast + ((range_.second >> 8) & 0xff); + const unsigned char second_lsb_ = static_cast + (range_.second & 0xff); + + if (first_msb_ == second_msb_) + { + string_token_vector data2_[2]; + + // Re-use 16 bit slice function + slice_range(range_, data2_, false_()); + + for (std::size_t i_ = 0, size_ = data2_[0]->size(); + i_ < size_; ++i_) + { + insert_range(string_token(first_msb_, first_msb_), + *(*data2_[0])[i_], *(*data2_[1])[i_], data_); + } + } + else + { + insert_range(first_msb_, first_msb_, + first_mid_, first_mid_, + first_lsb_, 0xff, data_); + + if (first_mid_ != 0xff) + { + insert_range(first_msb_, first_msb_, + first_mid_ + 1, 0xff, + 0, 0xff, data_); + } + + if (second_msb_ > first_msb_ + 1) + { + insert_range(first_mid_ + 1, second_mid_ - 1, + 0, 0xff, + 0, 0xff, data_); + } + + if (second_mid_ != 0) + { + insert_range(second_msb_, second_msb_, + 0, second_mid_ - 1, + 0, 0xff, data_); + insert_range(second_msb_, second_msb_, + second_mid_, second_mid_, + 0, second_lsb_, data_); + } + else + { + insert_range(second_msb_, second_msb_, + 0, second_mid_, + 0, second_lsb_, data_); + } + } + } + + // 16 bit unicode + void insert_range(const unsigned char first_, const unsigned char second_, + const unsigned char first2_, const unsigned char second2_, + string_token_vector data_[2]) + { + const string_token token_(first_ > second_ ? second_ : first_, + first_ > second_ ? first_ : second_); + const string_token token2_(first2_ > second2_ ? second2_ : first2_, + first2_ > second2_ ? first2_ : second2_); + + insert_range(token_, token2_, data_); + } + + void insert_range(const string_token &token_, const string_token &token2_, + string_token_vector data_[2]) + { + typename string_token_vector::vector::const_iterator iter_ = + std::find_if(data_[0]->begin(), data_[0]->end(), + find_functor(token_)); + + if (iter_ == data_[0]->end()) + { + data_[0]->push_back(0); + data_[0]->back() = new string_token(token_); + data_[1]->push_back(0); + data_[1]->back() = new string_token(token2_); + } + else + { + const std::size_t index_ = iter_ - data_[0]->begin(); + + (*data_[1])[index_]->insert(token2_); + } + } + + // 24 bit unicode + void insert_range(const unsigned char first_, const unsigned char second_, + const unsigned char first2_, const unsigned char second2_, + const unsigned char first3_, const unsigned char second3_, + string_token_vector data_[3]) + { + const string_token token_(first_ > second_ ? second_ : first_, + first_ > second_ ? first_ : second_); + const string_token token2_(first2_ > second2_ ? second2_ : first2_, + first2_ > second2_ ? first2_ : second2_); + const string_token token3_(first3_ > second3_ ? second3_ : first3_, + first3_ > second3_ ? first3_ : second3_); + + insert_range(token_, token2_, token3_, data_); + } + + void insert_range(const string_token &token_, const string_token &token2_, + const string_token &token3_, string_token_vector data_[3]) + { + typename string_token_vector::vector::const_iterator iter_ = + data_[0]->begin(); + typename string_token_vector::vector::const_iterator end_ = + data_[0]->end(); + bool finished_ = false; + + do + { + iter_ = std::find_if(iter_, end_, find_functor(token_)); + + if (iter_ == end_) + { + data_[0]->push_back(0); + data_[0]->back() = new string_token(token_); + data_[1]->push_back(0); + data_[1]->back() = new string_token(token2_); + data_[2]->push_back(0); + data_[2]->back() = new string_token(token3_); + finished_ = true; + } + else + { + const std::size_t index_ = iter_ - data_[0]->begin(); + + if (*(*data_[1])[index_] == token2_) + { + (*data_[2])[index_]->insert(token3_); + finished_ = true; + } + else + { + ++iter_; + } + } + } while (!finished_); + } + + // 16 bit unicode + void push_ranges(string_token_vector data_[2], const false_ &) + { + typename string_token_vector::vector::const_iterator viter_ = + data_[0]->begin(); + typename string_token_vector::vector::const_iterator vend_ = + data_[0]->end(); + typename string_token_vector::vector::const_iterator viter2_ = + data_[1]->begin(); + + push_range(*viter_++); + push_range(*viter2_++); + sequence(); + + while (viter_ != vend_) + { + push_range(*viter_++); + push_range(*viter2_++); + sequence(); + perform_or(); + } + } + + // 24 bit unicode + void push_ranges(string_token_vector data_[3], const true_ &) + { + typename string_token_vector::vector::const_iterator viter_ = + data_[0]->begin(); + typename string_token_vector::vector::const_iterator vend_ = + data_[0]->end(); + typename string_token_vector::vector::const_iterator viter2_ = + data_[1]->begin(); + typename string_token_vector::vector::const_iterator viter3_ = + data_[2]->begin(); + + push_range(*viter_++); + push_range(*viter2_++); + sequence(); + push_range(*viter3_++); + sequence(); + + while (viter_ != vend_) + { + push_range(*viter_++); + push_range(*viter2_++); + sequence(); + push_range(*viter3_++); + sequence(); + perform_or(); + } + } + + void push_range(const string_token *token_) + { + const id_type id_ = lookup(*token_); + + _node_ptr_vector->push_back(static_cast(0)); + _node_ptr_vector->back() = new leaf_node(id_, true); + _tree_node_stack.push(_node_ptr_vector->back()); + } + + id_type lookup(const string_token &charset_) + { + // Converted to id_type below. + std::size_t id_ = sm_traits::npos(); + typename charset_map::const_iterator iter_ = + _charset_map.find(charset_); + + if (iter_ == _charset_map.end()) + { + id_ = _charset_map.size(); + _charset_map.insert(charset_pair(charset_, id_)); + } + else + { + id_ = iter_->second; + } + + if (static_cast(id_) < id_) + { + throw runtime_error("id_type is not large enough " + "to hold all ids."); + } + + return static_cast(id_); + } + + void openparen(token_stack &handle_) + { + token *token_ = handle_->top(); + + assert(token_->_type == OPENPAREN && + handle_->size() == 3); + + handle_->pop(); + delete token_; + token_ = handle_->top(); + assert(token_->_type == REGEX); + handle_->pop(); + delete token_; + token_ = 0; + assert(handle_->top()->_type == CLOSEPAREN); + _token_stack->push(static_cast(0)); + _token_stack->top() = new token(REPEAT); + } + + void sequence() + { + node *rhs_ = _tree_node_stack.top(); + + _tree_node_stack.pop(); + + node *lhs_ = _tree_node_stack.top(); + + _node_ptr_vector->push_back(static_cast(0)); + _node_ptr_vector->back() = new sequence_node(lhs_, rhs_); + _tree_node_stack.top() = _node_ptr_vector->back(); + } + + void optional(const bool greedy_) + { + // perform ? + node *lhs_ = _tree_node_stack.top(); + // Don't know if lhs_ is a leaf_node, so get firstpos. + typename node::node_vector &firstpos_ = lhs_->firstpos(); + + for (typename node::node_vector::iterator iter_ = firstpos_.begin(), + end_ = firstpos_.end(); iter_ != end_; ++iter_) + { + // These are leaf_nodes! + (*iter_)->greedy(greedy_); + } + + _node_ptr_vector->push_back(static_cast(0)); + + node *rhs_ = new leaf_node(node::null_token(), greedy_); + + _node_ptr_vector->back() = rhs_; + _node_ptr_vector->push_back(static_cast(0)); + _node_ptr_vector->back() = new selection_node(lhs_, rhs_); + _tree_node_stack.top() = _node_ptr_vector->back(); + } + + void zero_or_more(const bool greedy_) + { + // perform * + node *ptr_ = _tree_node_stack.top(); + + _node_ptr_vector->push_back(static_cast(0)); + _node_ptr_vector->back() = new iteration_node(ptr_, greedy_); + _tree_node_stack.top() = _node_ptr_vector->back(); + } + + void one_or_more(const bool greedy_) + { + // perform + + node *lhs_ = _tree_node_stack.top(); + node *copy_ = lhs_->copy(_node_ptr_vector); + + _node_ptr_vector->push_back(static_cast(0)); + + node *rhs_ = new iteration_node(copy_, greedy_); + + _node_ptr_vector->back() = rhs_; + _node_ptr_vector->push_back(static_cast(0)); + _node_ptr_vector->back() = new sequence_node(lhs_, rhs_); + _tree_node_stack.top() = _node_ptr_vector->back(); + } + + // perform {n[,[m]]} + // Semantic checks have already been performed. + // {0,} = * + // {0,1} = ? + // {1,} = + + // therefore we do not check for these cases. + void repeatn(const bool greedy_, const token *token_) + { + const rules_char_type *str_ = token_->_extra.c_str(); + std::size_t min_ = 0; + bool comma_ = false; + std::size_t max_ = 0; + + while (*str_>= '0' && *str_ <= '9') + { + min_ *= 10; + min_ += *str_ - '0'; + ++str_; + } + + comma_ = *str_ == ','; + + if (comma_) ++str_; + + while (*str_>= '0' && *str_ <= '9') + { + max_ *= 10; + max_ += *str_ - '0'; + ++str_; + } + + if (!(min_ == 1 && !comma_)) + { + const std::size_t top_ = min_ > 0 ? min_ : max_; + + if (min_ == 0) + { + optional(greedy_); + } + + node *prev_ = _tree_node_stack.top()-> + copy(_node_ptr_vector); + node *curr_ = 0; + + for (std::size_t i_ = 2; i_ < top_; ++i_) + { + node *temp_ = prev_->copy(_node_ptr_vector); + + curr_ = temp_; + _tree_node_stack.push(static_cast(0)); + _tree_node_stack.top() = prev_; + sequence(); + prev_ = curr_; + } + + if (comma_ && min_ > 0) + { + if (min_ > 1) + { + node *temp_ = prev_->copy(_node_ptr_vector); + + curr_ = temp_; + _tree_node_stack.push(static_cast(0)); + _tree_node_stack.top() = prev_; + sequence(); + prev_ = curr_; + } + + if (comma_ && max_) + { + _tree_node_stack.push(static_cast(0)); + _tree_node_stack.top() = prev_; + optional(greedy_); + + node *temp_ = _tree_node_stack.top(); + + _tree_node_stack.pop(); + prev_ = temp_; + + const std::size_t count_ = max_ - min_; + + for (std::size_t i_ = 1; i_ < count_; ++i_) + { + node *temp_ = prev_->copy(_node_ptr_vector); + + curr_ = temp_; + _tree_node_stack.push(static_cast(0)); + _tree_node_stack.top() = prev_; + sequence(); + prev_ = curr_; + } + } + else + { + _tree_node_stack.push(static_cast(0)); + _tree_node_stack.top() = prev_; + zero_or_more(greedy_); + + node *temp_ = _tree_node_stack.top(); + + prev_ = temp_; + _tree_node_stack.pop(); + } + } + + _tree_node_stack.push(static_cast(0)); + _tree_node_stack.top() = prev_; + sequence(); + } + } + + void fixup_bol(node * &root_)const + { + typename node::node_vector *first_ = &root_->firstpos(); + bool found_ = false; + typename node::node_vector::const_iterator iter_ = + first_->begin(); + typename node::node_vector::const_iterator end_ = + first_->end(); + + for (; iter_ != end_; ++iter_) + { + const node *node_ = *iter_; + + found_ = !node_->end_state() && node_->token() == bol_token(); + + if (found_) break; + } + + if (!found_) + { + _node_ptr_vector->push_back(static_cast(0)); + _node_ptr_vector->back() = new leaf_node(bol_token(), true); + + node *lhs_ = _node_ptr_vector->back(); + + _node_ptr_vector->push_back(static_cast(0)); + _node_ptr_vector->back() = new leaf_node + (node::null_token(), true); + + node *rhs_ = _node_ptr_vector->back(); + + _node_ptr_vector->push_back(static_cast(0)); + _node_ptr_vector->back() = new selection_node(lhs_, rhs_); + lhs_ = _node_ptr_vector->back(); + + _node_ptr_vector->push_back(static_cast(0)); + _node_ptr_vector->back() = new sequence_node(lhs_, root_); + root_ = _node_ptr_vector->back(); + } + } +}; +} +} + +#endif diff --git a/Puma/extern/lexertl/parser/tokeniser/re_token.hpp b/Puma/extern/lexertl/parser/tokeniser/re_token.hpp new file mode 100644 index 0000000..11c38c6 --- /dev/null +++ b/Puma/extern/lexertl/parser/tokeniser/re_token.hpp @@ -0,0 +1,108 @@ +// re_token.hpp +// Copyright (c) 2005-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_RE_TOKEN_HPP +#define LEXERTL_RE_TOKEN_HPP + +#include "../../string_token.hpp" + +namespace lexertl +{ +namespace detail +{ +// Note that tokens following END are never seen by parser.hpp. +enum token_type {BEGIN, REGEX, OREXP, SEQUENCE, SUB, EXPRESSION, REPEAT, + DUP, OR, CHARSET, BOL, EOL, MACRO, OPENPAREN, CLOSEPAREN, OPT, AOPT, + ZEROORMORE, AZEROORMORE, ONEORMORE, AONEORMORE, REPEATN, AREPEATN, + END, DIFF}; + +template +struct basic_re_token +{ + typedef basic_string_token string_token; + typedef std::basic_string string; + + token_type _type; + string _extra; + string_token _str; + + basic_re_token(const token_type type_ = BEGIN) : + _type(type_), + _extra(), + _str() + { + } + + void clear() + { + _type = BEGIN; + _extra.clear(); + _str.clear(); + } + + basic_re_token &operator =(const basic_re_token &rhs_) + { + _type = rhs_._type; + _extra = rhs_._extra; + _str = rhs_._str; + return *this; + } + + void swap(basic_re_token &rhs_) + { + std::swap(_type, rhs_._type); + _extra.swap(rhs_._extra); + _str.swap(rhs_._str); + } + + char precedence(const token_type type_) const + { + // Moved in here for Solaris compiler. + static const char precedence_table_[END + 1][END + 1] = { +// BEG, REG, ORE, SEQ, SUB, EXP, RPT, DUP, | , CHR, BOL, EOL, MCR, ( , ) , ? , ?? , * , *? , + , +?, {n}?, {n}, END +/*BEGIN*/{ ' ', '<', '<', '<', '<', '<', '<', ' ', ' ', '<', '<', '<', '<', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, +/*REGEX*/{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '=', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, +/*OREXP*/{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '=', '>', '>', '>', '>', ' ', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, +/* SEQ */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', ' ', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, +/* SUB */{ ' ', ' ', ' ', ' ', ' ', '=', '<', ' ', '>', '<', '<', '<', '<', '<', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, +/*EXPRE*/{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, +/* RPT */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', '=', '>', '>', '>', '>', '>', '>', '>', '<', '<', '<', '<', '<', '<', '<', '<', '>' }, +/*DUPLI*/{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, +/* | */{ ' ', ' ', ' ', '=', '<', '<', '<', ' ', ' ', '<', '<', '<', '<', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }, +/*CHARA*/{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>' }, +/* BOL */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>' }, +/* EOL */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>' }, +/*MACRO*/{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>' }, +/* ( */{ ' ', '=', '<', '<', '<', '<', '<', ' ', ' ', '<', '<', '<', '<', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }, +/* ) */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>' }, +/* ? */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, +/* ?? */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, +/* * */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, +/* *? */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, +/* + */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, +/* +? */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, +/*{n,m}*/{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, +/*{nm}?*/{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>' }, +/* END */{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' } +}; + + return precedence_table_[_type][type_]; + } + + const char *precedence_string() const + { + // Moved in here for Solaris compiler. + static const char *precedence_strings_[END + 1] = + {"BEGIN", "REGEX", "OREXP", "SEQUENCE", "SUB", "EXPRESSION", + "REPEAT", "DUPLICATE", "|", "CHARSET", "^", "$", "MACRO", "(", ")", + "?", "??", "*", "*?", "+", "+?", "{n[,[m]]}", "{n[,[m]]}?", "END"}; + + return precedence_strings_[_type]; + } +}; +} +} + +#endif diff --git a/Puma/extern/lexertl/parser/tokeniser/re_tokeniser.hpp b/Puma/extern/lexertl/parser/tokeniser/re_tokeniser.hpp new file mode 100644 index 0000000..84448bd --- /dev/null +++ b/Puma/extern/lexertl/parser/tokeniser/re_tokeniser.hpp @@ -0,0 +1,766 @@ +// tokeniser.hpp +// Copyright (c) 2005-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_RE_TOKENISER_HPP +#define LEXERTL_RE_TOKENISER_HPP + +#include +#include "re_token.hpp" +#include "../../runtime_error.hpp" +#include "../../size_t.hpp" +#include +#include "../../string_token.hpp" +#include "re_tokeniser_helper.hpp" + +namespace lexertl +{ +namespace detail +{ +template +class basic_re_tokeniser +{ +public: + typedef basic_re_token re_token; + typedef basic_re_tokeniser_helper + tokeniser_helper; + typedef typename tokeniser_helper::char_state char_state; + typedef typename tokeniser_helper::state state; + typedef basic_string_token string_token; + + static void next(re_token &lhs_, state &state_, re_token &token_) + { + rules_char_type ch_ = 0; + bool eos_ = state_.next(ch_); + bool skipped_ = false; + + token_.clear(); + + do + { + // string begin/end + while (!eos_ && ch_ == '"') + { + state_._in_string ^= 1; + eos_ = state_.next(ch_); + } + + if (eos_) break; + + // (?# ...) + skipped_ = comment(eos_, ch_, state_); + + if (eos_) break; + + // skip_ws set + skipped_ |= skip(eos_, ch_, state_); + } while (!eos_ && skipped_); + + if (eos_) + { + if (state_._in_string) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " (missing '\"')"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + if (state_._paren_count) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " (missing ')')"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + token_._type = END; + } + else + { + if (ch_ == '\\') + { + // Even if we are in a string, respect escape sequences... + token_._type = CHARSET; + escape(state_, token_._str); + } + else if (state_._in_string) + { + // All other meta characters lose their special meaning + // inside a string. + token_._type = CHARSET; + token_._str.insert(typename string_token::range(ch_, ch_)); + } + else + { + // Not an escape sequence and not inside a string, so + // check for meta characters. + switch (ch_) + { + case '(': + token_._type = OPENPAREN; + ++state_._paren_count; + read_options(state_); + break; + case ')': + --state_._paren_count; + + if (state_._paren_count < 0) + { + std::ostringstream ss_; + + ss_ << "Number of open parenthesis < 0 " + "at index " << state_.index() - 1; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + token_._type = CLOSEPAREN; + + if (!state_._flags_stack.empty()) + { + state_._flags = state_._flags_stack.top(); + state_._flags_stack.pop(); + } + + break; + case '?': + if (!state_.eos() && *state_._curr == '?') + { + token_._type = AOPT; + state_.increment(); + } + else + { + token_._type = OPT; + } + + break; + case '*': + if (!state_.eos() && *state_._curr == '?') + { + token_._type = AZEROORMORE; + state_.increment(); + } + else + { + token_._type = ZEROORMORE; + } + + break; + case '+': + if (!state_.eos() && *state_._curr == '?') + { + token_._type = AONEORMORE; + state_.increment(); + } + else + { + token_._type = ONEORMORE; + } + + break; + case '{': + open_curly(lhs_, state_, token_); + break; + case '|': + token_._type = OR; + break; + case '^': + if (!state_._macro_name && + state_._curr - 1 == state_._start) + { + token_._type = BOL; + } + else + { + token_._type = CHARSET; + token_._str.insert(typename string_token::range + (ch_, ch_)); + } + + break; + case '$': + if (!state_._macro_name && state_._curr == state_._end) + { + token_._type = EOL; + } + else + { + token_._type = CHARSET; + token_._str.insert(typename string_token::range + (ch_, ch_)); + } + + break; + case '.': + { + token_._type = CHARSET; + + if (state_._flags & dot_not_newline) + { + token_._str.insert(typename string_token::range + ('\n', '\n')); + } + + token_._str.negate(); + break; + } + case '[': + { + token_._type = CHARSET; + tokeniser_helper::charset(state_, token_._str); + break; + } + case '/': + { + std::ostringstream ss_; + + ss_ << "Lookahead ('/') is not supported yet"; + state_.error(ss_); + throw runtime_error(ss_.str()); + break; + } + default: + token_._type = CHARSET; + + if (state_._flags & icase) + { + typename string_token::range range_(ch_, ch_); + string_token folded_; + + token_._str.insert(range_); + tokeniser_helper::fold(range_, state_._locale, + folded_, typename tokeniser_helper::template + size()); + + if (!folded_.empty()) + { + token_._str.insert(folded_); + } + } + else + { + token_._str.insert(typename string_token::range + (ch_, ch_)); + } + + break; + } + } + } + } + +private: + static bool comment(bool &eos_, rules_char_type &ch_, state &state_) + { + bool skipped_ = false; + + if (!state_._in_string && ch_ == '(' && !state_.eos() && + *state_._curr == '?' && state_._curr + 1 < state_._end && + *(state_._curr + 1) == '#') + { + std::size_t paren_count_ = 1; + + state_.increment(); + state_.increment(); + + do + { + eos_ = state_.next(ch_); + + if (ch_ == '(') + { + ++paren_count_; + } + else if (ch_ == ')') + { + --paren_count_; + } + } while (!eos_ && !(ch_ == ')' && paren_count_ == 0)); + + if (eos_) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " (unterminated comment)"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + else + { + eos_ = state_.next(ch_); + } + + skipped_ = true; + } + + return skipped_; + } + + static bool skip(bool &eos_, rules_char_type &ch_, state &state_) + { + bool skipped_ = false; + + if ((state_._flags & skip_ws) && !state_._in_string) + { + bool c_comment_ = false; + bool skip_ws_ = false; + + do + { + c_comment_ = ch_ == '/' && !state_.eos() && + *state_._curr == '*'; + skip_ws_ = !c_comment_ && (ch_ == ' ' || ch_ == '\t' || + ch_ == '\n' || ch_ == '\r' || ch_ == '\f' || ch_ == '\v'); + + if (c_comment_) + { + state_.increment(); + eos_ = state_.next(ch_); + + while (!eos_ && !(ch_ == '*' && !state_.eos() && + *state_._curr == '/')) + { + eos_ = state_.next(ch_); + } + + if (eos_) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " (unterminated C style comment)"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + else + { + state_.increment(); + eos_ = state_.next(ch_); + } + + skipped_ = true; + } + else if (skip_ws_) + { + eos_ = state_.next(ch_); + skipped_ = true; + } + } while (!eos_ && (c_comment_ || skip_ws_)); + } + + return skipped_; + } + + static void read_options(state &state_) + { + if (!state_.eos() && *state_._curr == '?') + { + rules_char_type ch_ = 0; + bool eos_ = false; + bool negate_ = false; + + state_.increment(); + eos_ = state_.next(ch_); + state_._flags_stack.push(state_._flags); + + while (!eos_ && ch_ != ':') + { + switch (ch_) + { + case '-': + negate_ ^= 1; + break; + case 'i': + if (negate_) + { + state_._flags = state_._flags & ~icase; + } + else + { + state_._flags = state_._flags | icase; + } + + negate_ = false; + break; + case 's': + if (negate_) + { + state_._flags = state_._flags | dot_not_newline; + } + else + { + state_._flags = state_._flags & ~dot_not_newline; + } + + negate_ = false; + break; + case 'x': + if (negate_) + { + state_._flags = state_._flags & ~skip_ws; + } + else + { + state_._flags = state_._flags | skip_ws; + } + + negate_ = false; + break; + default: + { + std::ostringstream ss_; + + ss_ << "Unknown option at index " << + state_.index() - 1; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + } + + eos_ = state_.next(ch_); + } + + // End of string handler will handle early termination + } + else if (!state_._flags_stack.empty()) + { + state_._flags_stack.push(state_._flags); + } + } + + static void escape(state &state_, string_token &token_) + { + char_type ch_ = 0; + std::size_t str_len_ = 0; + const char *str_ = tokeniser_helper::escape_sequence(state_, + ch_, str_len_); + + if (str_) + { + char_state state2_(str_ + 1, str_ + str_len_, state_._id, + state_._flags, state_._locale, 0); + + tokeniser_helper::charset(state2_, token_); + } + else + { + token_.insert(typename string_token::range(ch_, ch_)); + } + } + + static void open_curly(re_token &lhs_, state &state_, + re_token &token_) + { + if (state_.eos()) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " (missing '}')"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + else if (*state_._curr == '-' || *state_._curr == '+') + { + rules_char_type ch_ = 0; + + if (lhs_._type != CHARSET) + { + std::ostringstream ss_; + + ss_ << "CHARSET must precede {" << + state_._curr << "} at index " << + state_.index() - 1; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + state_.next(ch_); + token_._type = DIFF; + token_._extra = ch_; + + if (state_.next(ch_)) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " (missing '}')"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + if (ch_ != '}') + { + std::ostringstream ss_; + + ss_ << "Missing '}' at index " << state_.index() - 1; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + } + else if (*state_._curr >= '0' && *state_._curr <= '9') + { + repeat_n(state_, token_); + } + else + { + macro(state_, token_); + } + } + + // SYNTAX: + // {n[,[n]]} + // SEMANTIC RULES: + // {0} - INVALID (throw exception) + // {0,} = * + // {0,0} - INVALID (throw exception) + // {0,1} = ? + // {1,} = + + // {min,max} where min == max - {min} + // {min,max} where max < min - INVALID (throw exception) + static void repeat_n(state &state_, re_token &token_) + { + rules_char_type ch_ = 0; + bool eos_ = state_.next(ch_); + std::size_t min_ = 0; + std::size_t max_ = 0; + + while (!eos_ && ch_ >= '0' && ch_ <= '9') + { + min_ *= 10; + min_ += ch_ - '0'; + token_._extra += ch_; + eos_ = state_.next(ch_); + } + + if (eos_) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " (missing repeat terminator '}')"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + bool min_max_ = false; + bool repeatn_ = true; + + if (ch_ == ',') + { + token_._extra += ch_; + eos_ = state_.next(ch_); + + if (eos_) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " (missing repeat terminator '}')"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + if (ch_ == '}') + { + // Small optimisation: Check for '*' equivalency. + if (min_ == 0) + { + token_._type = ZEROORMORE; + repeatn_ = false; + } + // Small optimisation: Check for '+' equivalency. + else if (min_ == 1) + { + token_._type = ONEORMORE; + repeatn_ = false; + } + } + else + { + if (ch_ < '0' || ch_ > '9') + { + std::ostringstream ss_; + + ss_ << "Missing repeat terminator '}' at index " << + state_.index() - 1; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + min_max_ = true; + + do + { + max_ *= 10; + max_ += ch_ - '0'; + token_._extra += ch_; + eos_ = state_.next(ch_); + } while (!eos_ && ch_ >= '0' && ch_ <= '9'); + + if (eos_) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " (missing repeat terminator '}')"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + // Small optimisation: Check for '?' equivalency. + if (min_ == 0 && max_ == 1) + { + token_._type = OPT; + repeatn_ = false; + } + // Small optimisation: if min == max, then min. + else if (min_ == max_) + { + token_._extra.erase(token_._extra.find(',')); + min_max_ = false; + max_ = 0; + } + } + } + + if (ch_ != '}') + { + std::ostringstream ss_; + + ss_ << "Missing repeat terminator '}' at index " << + state_.index() - 1; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + if (repeatn_) + { + // SEMANTIC VALIDATION follows: + // NOTE: {0,} has already become * + // therefore we don't check for a comma. + if (min_ == 0 && max_ == 0) + { + std::ostringstream ss_; + + ss_ << "Cannot have exactly zero repeats preceding index " << + state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + if (min_max_ && max_ < min_) + { + std::ostringstream ss_; + + ss_ << "Max less than min preceding index " << + state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + if (!state_.eos() && *state_._curr == '?') + { + token_._type = AREPEATN; + state_.increment(); + } + else + { + token_._type = REPEATN; + } + } + else if (token_._type == ZEROORMORE) + { + if (!state_.eos() && *state_._curr == '?') + { + token_._type = AZEROORMORE; + state_.increment(); + } + } + else if (token_._type == ONEORMORE) + { + if (!state_.eos() && *state_._curr == '?') + { + token_._type = AONEORMORE; + state_.increment(); + } + } + else if (token_._type == OPT) + { + if (!state_.eos() && *state_._curr == '?') + { + token_._type = AOPT; + state_.increment(); + } + } + } + + static void macro(state &state_, re_token &token_) + { + rules_char_type ch_ = 0; + bool eos_ = false; + + state_.next(ch_); + + if (ch_ != '_' && !(ch_ >= 'A' && ch_ <= 'Z') && + !(ch_ >= 'a' && ch_ <= 'z')) + { + std::ostringstream ss_; + + ss_ << "Invalid MACRO name at index " << state_.index() - 1; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + do + { + token_._extra += ch_; + eos_ = state_.next(ch_); + + if (eos_) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " (missing MACRO name terminator '}')"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + } while (ch_ == '_' || ch_ == '-' || (ch_ >= 'A' && ch_ <= 'Z') || + (ch_ >= 'a' && ch_ <= 'z') || (ch_ >= '0' && ch_ <= '9')); + + if (ch_ != '}') + { + std::ostringstream ss_; + + ss_ << "Missing MACRO name terminator '}' at index " << + state_.index() - 1; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + token_._type = MACRO; + } +}; +} +} + +#endif diff --git a/Puma/extern/lexertl/parser/tokeniser/re_tokeniser_helper.hpp b/Puma/extern/lexertl/parser/tokeniser/re_tokeniser_helper.hpp new file mode 100644 index 0000000..29988df --- /dev/null +++ b/Puma/extern/lexertl/parser/tokeniser/re_tokeniser_helper.hpp @@ -0,0 +1,2417 @@ +// tokeniser_helper.hpp +// Copyright (c) 2005-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_RE_TOKENISER_HELPER_H +#define LEXERTL_RE_TOKENISER_HELPER_H + +#include "../../bool.hpp" +#include "../../char_traits.hpp" +// strlen() +#include +#include "../../size_t.hpp" +#include "re_tokeniser_state.hpp" +#include "../../runtime_error.hpp" +#include +#include "../../string_token.hpp" + +namespace lexertl +{ +namespace detail +{ +template > +class basic_re_tokeniser_helper +{ +public: + typedef basic_re_tokeniser_state char_state; + typedef basic_re_tokeniser_state state; + typedef basic_string_token string_token; + + template + struct size + { + }; + + typedef size<1> one; + typedef size<2> two; + typedef size<4> four; + + template + static const char *escape_sequence(state_type &state_, + char_type &ch_, std::size_t &str_len_) + { + bool eos_ = state_.eos(); + + if (eos_) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " following '\\'"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + const char *str_ = charset_shortcut(state_, str_len_); + + if (str_) + { + state_.increment(); + } + else + { + ch_ = chr(state_); + } + + return str_; + } + + // This function can call itself. + template + static void charset(state_type &state_, string_token &token_) + { + bool negated_ = false; + typename state_type::char_type ch_ = 0; + bool eos_ = state_.next(ch_); + + if (eos_) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " following '['"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + negated_ = ch_ == '^'; + + if (negated_) + { + eos_ = state_.next(ch_); + + if (eos_) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " following '^'"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + } + + bool chset_ = false; + typename string_token::char_type prev_ = 0; + + do + { + if (ch_ == '\\') + { + std::size_t str_len_ = 0; + const char *str_ = escape_sequence(state_, prev_, + str_len_); + + chset_ = str_ != 0; + + if (chset_) + { + char_state temp_state_(str_ + 1, str_ + str_len_, + state_._id, state_._flags, state_._locale, 0); + string_token temp_token_; + + charset(temp_state_, temp_token_); + token_.insert(temp_token_); + } + } + else if (ch_ == '[' && !state_.eos() && *state_._curr == ':') + { + state_.increment(); + posix(state_, token_); + chset_ = true; + } + else + { + chset_ = false; + prev_ = ch_; + } + + eos_ = state_.next(ch_); + + // Covers preceding if, else if and else + if (eos_) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " (missing ']')"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + if (ch_ == '-' && *state_._curr != ']') + { + charset_range(chset_, state_, eos_, ch_, prev_, + token_); + } + else if (!chset_) + { + typename string_token::range range_(prev_, prev_); + + token_.insert(range_); + + if (state_._flags & icase) + { + string_token folded_; + + fold(range_, state_._locale, folded_, + size()); + + if (!folded_.empty()) + { + token_.insert(folded_); + } + } + } + } while (ch_ != ']'); + + if (negated_) + { + token_.negate(); + } + + if (token_.empty()) + { + std::ostringstream ss_; + + ss_ << "Empty charset not allowed preceding index " << + state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + } + + static void fold(const typename string_token::range &range_, + const std::locale &locale_, string_token &out_, const one &) + { + // If string_token::char_type is 16 bit may overflow, + // so use std::size_t. + std::size_t start_ = range_.first; + std::size_t end_ = range_.second; + + // In 8 bit char mode, use locale and therefore consider every char + // individually. + for (; start_ <= end_; ++start_) + { + const input_char_type upper_ = std::toupper + (static_cast(start_), locale_); + const input_char_type lower_ = std::tolower + (static_cast(start_), locale_); + + if (upper_ != static_cast(start_)) + { + out_.insert(typename string_token::range(upper_, upper_)); + } + + if (lower_ != static_cast(start_)) + { + out_.insert(typename string_token::range(lower_, lower_)); + } + } + } + + static void fold(const typename string_token::range &range_, + const std::locale &, string_token &out_, const two &) + { + static const fold_pair mapping_[] = + {{{0x0041, 0x005a}, {0x0061, 0x007a}}, + {{0x0061, 0x007a}, {0x0041, 0x005a}}, + {{0x00b5, 0x00b5}, {0x039c, 0x039c}}, + {{0x00c0, 0x00d6}, {0x00e0, 0x00f6}}, + {{0x00d8, 0x00de}, {0x00f8, 0x00fe}}, + {{0x00e0, 0x00f6}, {0x00c0, 0x00d6}}, + {{0x00f8, 0x0137}, {0x00d8, 0x0117}}, + {{0x0139, 0x0148}, {0x013a, 0x0149}}, + {{0x014a, 0x018c}, {0x014b, 0x018d}}, + {{0x018e, 0x019a}, {0x01dd, 0x01e9}}, + {{0x019c, 0x01a9}, {0x026f, 0x027c}}, + {{0x01ac, 0x01b9}, {0x01ad, 0x01ba}}, + {{0x01bc, 0x01bd}, {0x01bd, 0x01be}}, + {{0x01bf, 0x01bf}, {0x01f7, 0x01f7}}, + {{0x01c4, 0x01c4}, {0x01c6, 0x01c6}}, + {{0x01c6, 0x01c7}, {0x01c4, 0x01c5}}, + {{0x01c9, 0x01ca}, {0x01c7, 0x01c8}}, + {{0x01cc, 0x01ef}, {0x01ca, 0x01ed}}, + {{0x01f1, 0x01f1}, {0x01f3, 0x01f3}}, + {{0x01f3, 0x0220}, {0x01f1, 0x021e}}, + {{0x0222, 0x0233}, {0x0223, 0x0234}}, + {{0x023a, 0x0254}, {0x2c65, 0x2c7f}}, + {{0x0256, 0x0257}, {0x0189, 0x018a}}, + {{0x0259, 0x0259}, {0x018f, 0x018f}}, + {{0x025b, 0x025b}, {0x0190, 0x0190}}, + {{0x0260, 0x0260}, {0x0193, 0x0193}}, + {{0x0263, 0x0263}, {0x0194, 0x0194}}, + {{0x0265, 0x0265}, {0xa78d, 0xa78d}}, + {{0x0268, 0x0269}, {0x0197, 0x0198}}, + {{0x026b, 0x026b}, {0x2c62, 0x2c62}}, + {{0x026f, 0x026f}, {0x019c, 0x019c}}, + {{0x0271, 0x0272}, {0x2c6e, 0x2c6f}}, + {{0x0275, 0x0275}, {0x019f, 0x019f}}, + {{0x027d, 0x027d}, {0x2c64, 0x2c64}}, + {{0x0280, 0x0280}, {0x01a6, 0x01a6}}, + {{0x0283, 0x0283}, {0x01a9, 0x01a9}}, + {{0x0288, 0x028c}, {0x01ae, 0x01b2}}, + {{0x0292, 0x0292}, {0x01b7, 0x01b7}}, + {{0x0370, 0x0373}, {0x0371, 0x0374}}, + {{0x0376, 0x0377}, {0x0377, 0x0378}}, + {{0x037b, 0x037d}, {0x03fd, 0x03ff}}, + {{0x0386, 0x0386}, {0x03ac, 0x03ac}}, + {{0x0388, 0x038a}, {0x03ad, 0x03af}}, + {{0x038c, 0x038c}, {0x03cc, 0x03cc}}, + {{0x038e, 0x038f}, {0x03cd, 0x03ce}}, + {{0x0391, 0x03a1}, {0x03b1, 0x03c1}}, + {{0x03a3, 0x03af}, {0x03c3, 0x03cf}}, + {{0x03b1, 0x03d1}, {0x0391, 0x03b1}}, + {{0x03d5, 0x03f2}, {0x03a6, 0x03c3}}, + {{0x03f4, 0x03f5}, {0x03b8, 0x03b9}}, + {{0x03f7, 0x03fb}, {0x03f8, 0x03fc}}, + {{0x03fd, 0x0481}, {0x037b, 0x03ff}}, + {{0x048a, 0x0527}, {0x048b, 0x0528}}, + {{0x0531, 0x0556}, {0x0561, 0x0586}}, + {{0x0561, 0x0586}, {0x0531, 0x0556}}, + {{0x10a0, 0x10c5}, {0x2d00, 0x2d25}}, + {{0x1d79, 0x1d79}, {0xa77d, 0xa77d}}, + {{0x1d7d, 0x1d7d}, {0x2c63, 0x2c63}}, + {{0x1e00, 0x1e95}, {0x1e01, 0x1e96}}, + {{0x1e9b, 0x1e9b}, {0x1e60, 0x1e60}}, + {{0x1e9e, 0x1e9e}, {0x00df, 0x00df}}, + {{0x1ea0, 0x1f15}, {0x1ea1, 0x1f16}}, + {{0x1f18, 0x1f1d}, {0x1f10, 0x1f15}}, + {{0x1f20, 0x1f45}, {0x1f28, 0x1f4d}}, + {{0x1f48, 0x1f4d}, {0x1f40, 0x1f45}}, + {{0x1f51, 0x1f51}, {0x1f59, 0x1f59}}, + {{0x1f53, 0x1f53}, {0x1f5b, 0x1f5b}}, + {{0x1f55, 0x1f55}, {0x1f5d, 0x1f5d}}, + {{0x1f57, 0x1f57}, {0x1f5f, 0x1f5f}}, + {{0x1f59, 0x1f59}, {0x1f51, 0x1f51}}, + {{0x1f5b, 0x1f5b}, {0x1f53, 0x1f53}}, + {{0x1f5d, 0x1f5d}, {0x1f55, 0x1f55}}, + {{0x1f5f, 0x1f7d}, {0x1f57, 0x1f75}}, + {{0x1f80, 0x1f87}, {0x1f88, 0x1f8f}}, + {{0x1f90, 0x1f97}, {0x1f98, 0x1f9f}}, + {{0x1fa0, 0x1fa7}, {0x1fa8, 0x1faf}}, + {{0x1fb0, 0x1fb1}, {0x1fb8, 0x1fb9}}, + {{0x1fb3, 0x1fb3}, {0x1fbc, 0x1fbc}}, + {{0x1fb8, 0x1fbb}, {0x1fb0, 0x1fb3}}, + {{0x1fbe, 0x1fbe}, {0x0399, 0x0399}}, + {{0x1fc3, 0x1fc3}, {0x1fcc, 0x1fcc}}, + {{0x1fc8, 0x1fcb}, {0x1f72, 0x1f75}}, + {{0x1fd0, 0x1fd1}, {0x1fd8, 0x1fd9}}, + {{0x1fd8, 0x1fdb}, {0x1fd0, 0x1fd3}}, + {{0x1fe0, 0x1fe1}, {0x1fe8, 0x1fe9}}, + {{0x1fe5, 0x1fe5}, {0x1fec, 0x1fec}}, + {{0x1fe8, 0x1fec}, {0x1fe0, 0x1fe4}}, + {{0x1ff3, 0x1ff3}, {0x1ffc, 0x1ffc}}, + {{0x1ff8, 0x1ffb}, {0x1f78, 0x1f7b}}, + {{0x2126, 0x2126}, {0x03c9, 0x03c9}}, + {{0x212a, 0x212b}, {0x006b, 0x006c}}, + {{0x2132, 0x2132}, {0x214e, 0x214e}}, + {{0x214e, 0x214e}, {0x2132, 0x2132}}, + {{0x2183, 0x2184}, {0x2184, 0x2185}}, + {{0x2c00, 0x2c2e}, {0x2c30, 0x2c5e}}, + {{0x2c30, 0x2c5e}, {0x2c00, 0x2c2e}}, + {{0x2c60, 0x2c70}, {0x2c61, 0x2c71}}, + {{0x2c72, 0x2c73}, {0x2c73, 0x2c74}}, + {{0x2c75, 0x2c76}, {0x2c76, 0x2c77}}, + {{0x2c7e, 0x2ce3}, {0x023f, 0x02a4}}, + {{0x2ceb, 0x2cee}, {0x2cec, 0x2cef}}, + {{0x2d00, 0x2d25}, {0x10a0, 0x10c5}}, + {{0xa640, 0xa66d}, {0xa641, 0xa66e}}, + {{0xa680, 0xa697}, {0xa681, 0xa698}}, + {{0xa722, 0xa72f}, {0xa723, 0xa730}}, + {{0xa732, 0xa76f}, {0xa733, 0xa770}}, + {{0xa779, 0xa787}, {0xa77a, 0xa788}}, + {{0xa78b, 0xa78d}, {0xa78c, 0xa78e}}, + {{0xa790, 0xa791}, {0xa791, 0xa792}}, + {{0xa7a0, 0xa7a9}, {0xa7a1, 0xa7aa}}, + {{0xff21, 0xff3a}, {0xff41, 0xff5a}}, + {{0xff41, 0xff5a}, {0xff21, 0xff3a}}, + {{0, 0}, {0, 0}}}; + const fold_pair *ptr_ = mapping_; + + for (; ptr_->from.first != 0; ++ptr_) + { + if (range_.second < ptr_->from.first) break; + + if (range_.first >= ptr_->from.first && + range_.first <= ptr_->from.second) + { + out_.insert(typename string_token::range + (ptr_->to.first + (range_.first - ptr_->from.first), + range_.second > ptr_->from.second ? ptr_->to.second : + ptr_->to.first + (range_.second - ptr_->from.first))); + } + else if (range_.second >= ptr_->from.first && + range_.second <= ptr_->from.second) + { + out_.insert(typename string_token::range(ptr_->to.first, + ptr_->to.first + (range_.second - ptr_->from.first))); + } + // Either range fully encompasses from range or not at all. + else if (ptr_->from.first >= range_.first && + ptr_->from.first <= range_.second) + { + out_.insert(typename string_token::range(ptr_->to.first, + ptr_->to.second)); + } + } + } + + static void fold(const typename string_token::range &range_, + const std::locale &locale_, string_token &out_, const four &) + { + if (range_.first < 0x10000) + { + fold(range_, locale_, out_, two()); + } + + static const fold_pair mapping_[] = + {{{0x10400, 0x1044f}, {0x10428, 0x10477}}, + {{0, 0}, {0, 0}}}; + const fold_pair *ptr_ = mapping_; + + for (; ptr_->from.first != 0; ++ptr_) + { + if (range_.second < ptr_->from.first) break; + + if (range_.first >= ptr_->from.first && + range_.first <= ptr_->from.second) + { + out_.insert(typename string_token::range + (ptr_->to.first + (range_.first - ptr_->from.first), + range_.second > ptr_->from.second ? ptr_->to.second : + ptr_->to.first + (range_.second - ptr_->from.first))); + } + else if (range_.second >= ptr_->from.first && + range_.second <= ptr_->from.second) + { + out_.insert(typename string_token::range(ptr_->to.first, + ptr_->to.first + (range_.second - ptr_->from.first))); + } + // Either range fully encompasses from range or not at all. + else if (ptr_->from.first >= range_.first && + ptr_->from.first <= range_.second) + { + out_.insert(typename string_token::range(ptr_->to.first, + ptr_->to.second)); + } + } + } + + template + static input_char_type chr(state_type &state_) + { + input_char_type ch_ = 0; + + // eos_ has already been checked for. + switch (*state_._curr) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + ch_ = decode_octal(state_); + break; + case 'a': + ch_ = '\a'; + state_.increment(); + break; + case 'b': + ch_ = '\b'; + state_.increment(); + break; + case 'c': + ch_ = decode_control_char(state_); + break; + case 'e': + ch_ = 27; // '\e' not recognised by compiler + state_.increment(); + break; + case 'f': + ch_ = '\f'; + state_.increment(); + break; + case 'n': + ch_ = '\n'; + state_.increment(); + break; + case 'r': + ch_ = '\r'; + state_.increment(); + break; + case 't': + ch_ = '\t'; + state_.increment(); + break; + case 'v': + ch_ = '\v'; + state_.increment(); + break; + case 'x': + ch_ = decode_hex(state_); + break; + default: + ch_ = *state_._curr; + state_.increment(); + break; + } + + return ch_; + } + +private: + struct char_pair + { + input_char_type first; + input_char_type second; + }; + + struct fold_pair + { + char_pair from; + char_pair to; + }; + + template + static void posix(state_type &state_, string_token &token_) + { + bool negate_ = false; + + if (!state_.eos() && *state_._curr == '^') + { + negate_ = true; + state_.increment(); + } + + if (state_.eos()) + { + unterminated_posix(state_); + } + else + { + switch (*state_._curr) + { + case 'a': + // alnum + // alpha + alnum_alpha(state_, token_, negate_); + break; + case 'b': + // blank + blank(state_, token_, negate_); + break; + case 'c': + // cntrl + cntrl(state_, token_, negate_); + break; + case 'd': + // digit + digit(state_, token_, negate_); + break; + case 'g': + // graph + graph(state_, token_, negate_); + break; + case 'l': + // lower + lower(state_, token_, negate_); + break; + case 'p': + // print + // punct + print_punct(state_, token_, negate_); + break; + case 's': + // space + space(state_, token_, negate_); + break; + case 'u': + // upper + upper(state_, token_, negate_); + break; + case 'x': + // xdigit + xdigit(state_, token_, negate_); + break; + default: + unknown_posix(state_); + break; + } + } + } + + template + static void alnum_alpha(state_type &state_, string_token &token_, + const bool negate_) + { + enum {unknown, alnum, alpha}; + std::size_t type_ = unknown; + + state_.increment(); + + if (!state_.eos() && *state_._curr == 'l') + { + state_.increment(); + + if (!state_.eos()) + { + if (*state_._curr == 'n') + { + state_.increment(); + + if (!state_.eos() && *state_._curr == 'u') + { + state_.increment(); + + if (!state_.eos() && *state_._curr == 'm') + { + state_.increment(); + type_ = alnum; + } + } + } + else if (*state_._curr == 'p') + { + state_.increment(); + + if (!state_.eos() && *state_._curr == 'h') + { + state_.increment(); + + if (!state_.eos() && *state_._curr == 'a') + { + state_.increment(); + type_ = alpha; + } + } + } + } + } + + if (type_ == unknown) + { + unknown_posix(state_); + } + else + { + std::string str_; + + check_posix_termination(state_); + + if (type_ == alnum) + { + // alnum + str_ = sizeof(input_char_type) == 1 ? + make_alnum(state_._locale) : + std::string("[\\p{Ll}\\p{Lu}\\p{Nd}]"); + } + else + { + // alpha + str_ = sizeof(input_char_type) == 1 ? + make_alpha(state_._locale) : + std::string("[\\p{Ll}\\p{Lu}]"); + } + + insert_charset(str_.c_str(), state_, token_, negate_); + } + } + + static std::string make_alnum(std::locale &locale_) + { + std::string str_(1, '['); + + for (std::size_t i_ = 0; i_ < 256; ++i_) + { + if (std::use_facet >(locale_). + is(std::ctype_base::alnum, static_cast(i_))) + { + str_ += static_cast(i_); + } + } + + str_ += ']'; + return str_; + } + + static std::string make_alpha(std::locale &locale_) + { + std::string str_(1, '['); + + for (std::size_t i_ = 0; i_ < 256; ++i_) + { + if (std::use_facet >(locale_). + is(std::ctype_base::alpha, static_cast(i_))) + { + str_ += static_cast(i_); + } + } + + str_ += ']'; + return str_; + } + + template + static void blank(state_type &state_, string_token &token_, + const bool negate_) + { + const char *blank_ = "lank"; + + state_.increment(); + + // Casts to prevent warnings (VC++ 2012) + while (!state_.eos() && *blank_ && + static_cast(*state_._curr) == + static_cast(*blank_)) + { + state_.increment(); + ++blank_; + } + + if (*blank_) + { + unknown_posix(state_); + } + else + { + const char *str_ = sizeof(input_char_type) == 1 ? + "[ \t]" : "[\\p{Zs}\t]"; + + check_posix_termination(state_); + insert_charset(str_, state_, token_, negate_); + } + } + + template + static void cntrl(state_type &state_, string_token &token_, + const bool negate_) + { + const char *cntrl_ = "ntrl"; + + state_.increment(); + + // Casts to prevent warnings (VC++ 2012) + while (!state_.eos() && *cntrl_ && + static_cast(*state_._curr) == + static_cast(*cntrl_)) + { + state_.increment(); + ++cntrl_; + } + + if (*cntrl_) + { + unknown_posix(state_); + } + else + { + const char *str_ = sizeof(input_char_type) == 1 ? + "[\\x00-\x1f\x7f]" : "[\\p{Cc}]"; + + check_posix_termination(state_); + insert_charset(str_, state_, token_, negate_); + } + } + + template + static void digit(state_type &state_, string_token &token_, + const bool negate_) + { + const char *digit_ = "igit"; + + state_.increment(); + + // Casts to prevent warnings (VC++ 2012) + while (!state_.eos() && *digit_ && + static_cast(*state_._curr) == + static_cast(*digit_)) + { + state_.increment(); + ++digit_; + } + + if (*digit_) + { + unknown_posix(state_); + } + else + { + const char *str_ = sizeof(input_char_type) == 1 ? + "[0-9]" : "[\\p{Nd}]"; + + check_posix_termination(state_); + insert_charset(str_, state_, token_, negate_); + } + } + + template + static void graph(state_type &state_, string_token &token_, + const bool negate_) + { + const char *graph_ = "raph"; + + state_.increment(); + + // Casts to prevent warnings (VC++ 2012) + while (!state_.eos() && *graph_ && + static_cast(*state_._curr) == + static_cast(*graph_)) + { + state_.increment(); + ++graph_; + } + + if (*graph_) + { + unknown_posix(state_); + } + else + { + const char *str_ = sizeof(input_char_type) == 1 ? + "[\x21-\x7e]" : "[^\\p{Z}\\p{C}]"; + + check_posix_termination(state_); + insert_charset(str_, state_, token_, negate_); + } + } + + template + static void lower(state_type &state_, string_token &token_, + const bool negate_) + { + const char *lower_ = "ower"; + + state_.increment(); + + // Casts to prevent warnings (VC++ 2012) + while (!state_.eos() && *lower_ && + static_cast(*state_._curr) == + static_cast(*lower_)) + { + state_.increment(); + ++lower_; + } + + if (*lower_) + { + unknown_posix(state_); + } + else + { + std::string str_ = sizeof(input_char_type) == 1 ? + create_lower(state_._locale) : + std::string("[\\p{Ll}]"); + + check_posix_termination(state_); + insert_charset(str_.c_str(), state_, token_, negate_); + } + } + + static std::string create_lower(std::locale &locale_) + { + std::string str_(1, '['); + + for (std::size_t i_ = 0; i_ < 256; ++i_) + { + if (std::use_facet >(locale_). + is(std::ctype_base::lower, static_cast(i_))) + { + str_ += static_cast(i_); + } + } + + str_ += ']'; + return str_; + } + + template + static void print_punct(state_type &state_, string_token &token_, + const bool negate_) + { + enum {unknown, print, punct}; + std::size_t type_ = unknown; + + state_.increment(); + + if (!state_.eos()) + { + if (*state_._curr == 'r') + { + state_.increment(); + + if (!state_.eos() && *state_._curr == 'i') + { + state_.increment(); + + if (!state_.eos() && *state_._curr == 'n') + { + state_.increment(); + + if (!state_.eos() && *state_._curr == 't') + { + state_.increment(); + type_ = print; + } + } + } + } + else if (*state_._curr == 'u') + { + state_.increment(); + + if (!state_.eos() && *state_._curr == 'n') + { + state_.increment(); + + if (!state_.eos() && *state_._curr == 'c') + { + state_.increment(); + + if (!state_.eos() && *state_._curr == 't') + { + state_.increment(); + type_ = punct; + } + } + } + } + } + + if (type_ == unknown) + { + unknown_posix(state_); + } + else + { + const char *str_ = 0; + + check_posix_termination(state_); + + if (type_ == print) + { + // print + str_ = sizeof(input_char_type) == 1 ? + "[\x20-\x7e]" : "[\\p{C}]"; + } + else + { + // punct + str_ = sizeof(input_char_type) == 1 ? + "[!\"#$%&'()*+,\\-./:;<=>?@[\\\\\\]^_`{|}~]" : + "[\\p{P}\\p{S}]"; + } + + insert_charset(str_, state_, token_, negate_); + } + } + + template + static void space(state_type &state_, string_token &token_, + const bool negate_) + { + const char *space_ = "pace"; + + state_.increment(); + + // Casts to prevent warnings (VC++ 2012) + while (!state_.eos() && *space_ && + static_cast(*state_._curr) == + static_cast(*space_)) + { + state_.increment(); + ++space_; + } + + if (*space_) + { + unknown_posix(state_); + } + else + { + const char *str_ = sizeof(input_char_type) == 1 ? + "[ \t\r\n\v\f]" : "[\\p{Z}\t\r\n\v\f]"; + + check_posix_termination(state_); + insert_charset(str_, state_, token_, negate_); + } + } + + template + static void upper(state_type &state_, string_token &token_, + const bool negate_) + { + const char *upper_ = "pper"; + + state_.increment(); + + // Casts to prevent warnings (VC++ 2012) + while (!state_.eos() && *upper_ && + static_cast(*state_._curr) == + static_cast(*upper_)) + { + state_.increment(); + ++upper_; + } + + if (*upper_) + { + unknown_posix(state_); + } + else + { + std::string str_ = sizeof(input_char_type) == 1 ? + create_upper(state_._locale) : + std::string("[\\p{Lu}]"); + + check_posix_termination(state_); + insert_charset(str_.c_str(), state_, token_, negate_); + } + } + + static std::string create_upper(std::locale &locale_) + { + std::string str_(1, '['); + + for (std::size_t i_ = 0; i_ < 256; ++i_) + { + if (std::use_facet >(locale_). + is(std::ctype_base::upper, static_cast(i_))) + { + str_ += static_cast(i_); + } + } + + str_ += ']'; + return str_; + } + + template + static void xdigit(state_type &state_, string_token &token_, + const bool negate_) + { + const char *xdigit_ = "digit"; + + state_.increment(); + + // Casts to prevent warnings (VC++ 2012) + while (!state_.eos() && *xdigit_ && + static_cast(*state_._curr) == + static_cast(*xdigit_)) + { + state_.increment(); + ++xdigit_; + } + + if (*xdigit_) + { + unknown_posix(state_); + } + else + { + const char *str_ = "[0-9A-Fa-f]"; + + check_posix_termination(state_); + insert_charset(str_, state_, token_, negate_); + } + } + + template + static void check_posix_termination(state_type &state_) + { + if (state_.eos()) + { + unterminated_posix(state_); + } + + if (*state_._curr != ':') + { + std::ostringstream ss_; + + ss_ << "Missing ':' at index " << state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + state_.increment(); + + if (state_.eos()) + { + unterminated_posix(state_); + } + + if (*state_._curr != ']') + { + std::ostringstream ss_; + + ss_ << "Missing ']' at index " << state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + state_.increment(); + } + + template + static void unterminated_posix(state_type &state_) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " (unterminated POSIX charset)"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + template + static void unknown_posix(state_type &state_) + { + std::ostringstream ss_; + + ss_ << "Unknown POSIX charset at index " << + state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + template + static void insert_charset(const char *str_, state_type &state_, + string_token &token_, const bool negate_) + { + // Some systems have strlen in namespace std. + using namespace std; + + char_state temp_state_(str_ + 1, str_ + strlen(str_), + state_._id, state_._flags, state_._locale, 0); + string_token temp_token_; + + charset(temp_state_, temp_token_); + + if (negate_) temp_token_.negate(); + + token_.insert(temp_token_); + } + + template + static const char *charset_shortcut + (state_type &state_, std::size_t &str_len_) + { + const char *str_ = 0; + + switch (*state_._curr) + { + case 'd': + str_ = "[0-9]"; + break; + case 'D': + str_ = "[^0-9]"; + break; + case 'p': + str_ = unicode_escape(state_); + break; + case 's': + str_ = "[ \t\n\r\f\v]"; + break; + case 'S': + str_ = "[^ \t\n\r\f\v]"; + break; + case 'w': + str_ = "[_0-9A-Za-z]"; + break; + case 'W': + str_ = "[^_0-9A-Za-z]"; + break; + } + + if (str_) + { + // Some systems have strlen in namespace std. + using namespace std; + + str_len_ = strlen(str_); + } + else + { + str_len_ = 0; + } + + return str_; + } + + template + static const char *unicode_escape(state_type &state_) + { + const char *str_ = 0; + + state_.increment(); + + if (state_.eos()) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " following \\p"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + if (*state_._curr != '{') + { + std::ostringstream ss_; + + ss_ << "Missing '{' following \\p at index " << + state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + state_.increment(); + + if (state_.eos()) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " following \\p{"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + switch (*state_._curr) + { + case 'C': + state_.increment(); + + if (state_.eos()) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " following \\p{C"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + switch (*state_._curr) + { + case '}': + str_ = "[\\p{Cc}\\p{Cf}\\p{Co}\\p{Cs}]"; + break; + case 'c': + str_ = other_control(); + state_.increment(); + break; + case 'f': + str_ = other_format(); + state_.increment(); + break; +// case 'n': +// break; + case 'o': + str_ = other_private(); + state_.increment(); + break; + case 's': + str_ = other_surrogate(); + state_.increment(); + break; + default: + { + std::ostringstream ss_; + + ss_ << "Syntax error following \\p{C at index " << + state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + } + + break; + case 'L': + state_.increment(); + + if (state_.eos()) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " following \\p{L"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + switch (*state_._curr) + { + case '}': + str_ = "[\\p{Ll}\\p{Lm}\\p{Lo}\\p{Lt}\\p{Lu}]"; + break; + case 'C': + str_ = "[\\p{Ll}\\p{Lt}\\p{Lu}]"; + state_.increment(); + break; + case 'l': + str_ = letter_lowercase(); + state_.increment(); + break; + case 'm': + str_ = letter_modifier(); + state_.increment(); + break; + case 'o': + str_ = letter_other(); + state_.increment(); + break; + case 't': + str_ = letter_titlecase(); + state_.increment(); + break; + case 'u': + str_ = letter_uppercase(); + state_.increment(); + break; + default: + { + std::ostringstream ss_; + + ss_ << "Syntax error following \\p{L at index " << + state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + } + + break; + case 'M': + state_.increment(); + + if (state_.eos()) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " following \\p{M"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + switch (*state_._curr) + { + case '}': + str_ = "[\\p{Mc}\\p{Me}\\p{Mn}]"; + break; + case 'c': + str_ = mark_combining(); + state_.increment(); + break; + case 'e': + str_ = mark_enclosing(); + state_.increment(); + break; + case 'n': + str_ = mark_nonspacing(); + state_.increment(); + break; + default: + { + std::ostringstream ss_; + + ss_ << "Syntax error following \\p{M at index " << + state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + } + + break; + case 'N': + state_.increment(); + + if (state_.eos()) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " following \\p{N"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + switch (*state_._curr) + { + case '}': + str_ = "[\\p{Nd}\\p{Nl}\\p{No}]"; + break; + case 'd': + str_ = number_decimal(); + state_.increment(); + break; + case 'l': + str_ = number_letter(); + state_.increment(); + break; + case 'o': + str_ = number_other(); + state_.increment(); + break; + default: + { + std::ostringstream ss_; + + ss_ << "Syntax error following \\p{N at index " << + state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + } + + break; + case 'P': + state_.increment(); + + if (state_.eos()) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " following \\p{P"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + switch (*state_._curr) + { + case '}': + str_ = "[\\p{Pc}\\p{Pd}\\p{Pe}\\p{Pf}\\p{Pi}\\p{Po}" + "\\p{Ps}]"; + break; + case 'c': + str_ = punctuation_connector(); + state_.increment(); + break; + case 'd': + str_ = punctuation_dash(); + state_.increment(); + break; + case 'e': + str_ = punctuation_close(); + state_.increment(); + break; + case 'f': + str_ = punctuation_final(); + state_.increment(); + break; + case 'i': + str_ = punctuation_initial(); + state_.increment(); + break; + case 'o': + str_ = punctuation_other(); + state_.increment(); + break; + case 's': + str_ = punctuation_open(); + state_.increment(); + break; + default: + { + std::ostringstream ss_; + + ss_ << "Syntax error following \\p{P at index " << + state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + } + + break; + case 'S': + state_.increment(); + + if (state_.eos()) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " following \\p{S"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + switch (*state_._curr) + { + case '}': + str_ = "[\\p{Sc}\\p{Sk}\\p{Sm}\\p{So}]"; + break; + case 'c': + str_ = symbol_currency(); + state_.increment(); + break; + case 'k': + str_ = symbol_modifier(); + state_.increment(); + break; + case 'm': + str_ = symbol_math(); + state_.increment(); + break; + case 'o': + str_ = symbol_other(); + state_.increment(); + break; + default: + { + std::ostringstream ss_; + + ss_ << "Syntax error following \\p{S at index " << + state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + } + + break; + case 'Z': + state_.increment(); + + if (state_.eos()) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " following \\p{Z"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + switch (*state_._curr) + { + case '}': + str_ = "[\\p{Zl}\\p{Zp}\\p{Zs}]"; + break; + case 'l': + str_ = separator_line(); + state_.increment(); + break; + case 'p': + str_ = separator_paragraph(); + state_.increment(); + break; + case 's': + str_ = separator_space(); + state_.increment(); + break; + default: + { + std::ostringstream ss_; + + ss_ << "Syntax error following \\p{Z at index " << + state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + } + + break; + default: + { + std::ostringstream ss_; + + ss_ << "Syntax error following \\p{ at index " << + state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + } + + if (*state_._curr != '}') + { + std::ostringstream ss_; + + ss_ << "Missing '}' at index " << state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + return str_; + } + + static const char *letter_uppercase() + { + return "[\\x41-\\x5a\\xc0-\\xd6\\xd8-\\xde\\x100\\x102\\x104\\x106" + "\\x108\\x10a\\x10c\\x10e\\x110\\x112\\x114\\x116\\x118\\x11a" + "\\x11c\\x11e\\x120\\x122\\x124\\x126\\x128\\x12a\\x12c\\x12e" + "\\x130\\x132\\x134\\x136\\x139\\x13b\\x13d\\x13f\\x141\\x143" + "\\x145\\x147\\x14a\\x14c\\x14e\\x150\\x152\\x154\\x156\\x158" + "\\x15a\\x15c\\x15e\\x160\\x162\\x164\\x166\\x168\\x16a\\x16c" + "\\x16e\\x170\\x172\\x174\\x176\\x178\\x179\\x17b\\x17d\\x181" + "\\x182\\x184\\x186\\x187\\x189-\\x18b\\x18e-\\x191\\x193\\x194" + "\\x196-\\x198\\x19c\\x19d\\x19f\\x1a0\\x1a2\\x1a4\\x1a6\\x1a7" + "\\x1a9\\x1ac\\x1ae\\x1af\\x1b1-\\x1b3\\x1b5\\x1b7\\x1b8\\x1bc" + "\\x1c4\\x1c7\\x1ca\\x1cd\\x1cf\\x1d1\\x1d3\\x1d5\\x1d7\\x1d9" + "\\x1db\\x1de\\x1e0\\x1e2\\x1e4\\x1e6\\x1e8\\x1ea\\x1ec\\x1ee" + "\\x1f1\\x1f4\\x1f6-\\x1f8\\x1fa\\x1fc\\x1fe\\x200\\x202\\x204" + "\\x206\\x208\\x20a\\x20c\\x20e\\x210\\x212\\x214\\x216\\x218" + "\\x21a\\x21c\\x21e\\x220\\x222\\x224\\x226\\x228\\x22a\\x22c" + "\\x22e\\x230\\x232\\x23a\\x23b\\x23d\\x23e\\x241\\x243-\\x246" + "\\x248\\x24a\\x24c\\x24e\\x370\\x372\\x376\\x386\\x388-\\x38a" + "\\x38c\\x38e\\x38f\\x391-\\x3a1\\x3a3-\\x3ab\\x3cf\\x3d2-\\x3d4" + "\\x3d8\\x3da\\x3dc\\x3de\\x3e0\\x3e2\\x3e4\\x3e6\\x3e8\\x3ea" + "\\x3ec\\x3ee\\x3f4\\x3f7\\x3f9\\x3fa\\x3fd-\\x42f\\x460\\x462" + "\\x464\\x466\\x468\\x46a\\x46c\\x46e\\x470\\x472\\x474\\x476" + "\\x478\\x47a\\x47c\\x47e\\x480\\x48a\\x48c\\x48e\\x490\\x492" + "\\x494\\x496\\x498\\x49a\\x49c\\x49e\\x4a0\\x4a2\\x4a4\\x4a6" + "\\x4a8\\x4aa\\x4ac\\x4ae\\x4b0\\x4b2\\x4b4\\x4b6\\x4b8\\x4ba" + "\\x4bc\\x4be\\x4c0\\x4c1\\x4c3\\x4c5\\x4c7\\x4c9\\x4cb\\x4cd" + "\\x4d0\\x4d2\\x4d4\\x4d6\\x4d8\\x4da\\x4dc\\x4de\\x4e0\\x4e2" + "\\x4e4\\x4e6\\x4e8\\x4ea\\x4ec\\x4ee\\x4f0\\x4f2\\x4f4\\x4f6" + "\\x4f8\\x4fa\\x4fc\\x4fe\\x500\\x502\\x504\\x506\\x508\\x50a" + "\\x50c\\x50e\\x510\\x512\\x514\\x516\\x518\\x51a\\x51c\\x51e" + "\\x520\\x522\\x524\\x526\\x531-\\x556\\x10a0-\\x10c5\\x1e00" + "\\x1e02\\x1e04\\x1e06\\x1e08\\x1e0a\\x1e0c\\x1e0e\\x1e10\\x1e12" + "\\x1e14\\x1e16\\x1e18\\x1e1a\\x1e1c\\x1e1e\\x1e20\\x1e22\\x1e24" + "\\x1e26\\x1e28\\x1e2a\\x1e2c\\x1e2e\\x1e30\\x1e32\\x1e34\\x1e36" + "\\x1e38\\x1e3a\\x1e3c\\x1e3e\\x1e40\\x1e42\\x1e44\\x1e46\\x1e48" + "\\x1e4a\\x1e4c\\x1e4e\\x1e50\\x1e52\\x1e54\\x1e56\\x1e58\\x1e5a" + "\\x1e5c\\x1e5e\\x1e60\\x1e62\\x1e64\\x1e66\\x1e68\\x1e6a\\x1e6c" + "\\x1e6e\\x1e70\\x1e72\\x1e74\\x1e76\\x1e78\\x1e7a\\x1e7c\\x1e7e" + "\\x1e80\\x1e82\\x1e84\\x1e86\\x1e88\\x1e8a\\x1e8c\\x1e8e\\x1e90" + "\\x1e92\\x1e94\\x1e9e\\x1ea0\\x1ea2\\x1ea4\\x1ea6\\x1ea8\\x1eaa" + "\\x1eac\\x1eae\\x1eb0\\x1eb2\\x1eb4\\x1eb6\\x1eb8\\x1eba\\x1ebc" + "\\x1ebe\\x1ec0\\x1ec2\\x1ec4\\x1ec6\\x1ec8\\x1eca\\x1ecc\\x1ece" + "\\x1ed0\\x1ed2\\x1ed4\\x1ed6\\x1ed8\\x1eda\\x1edc\\x1ede\\x1ee0" + "\\x1ee2\\x1ee4\\x1ee6\\x1ee8\\x1eea\\x1eec\\x1eee\\x1ef0\\x1ef2" + "\\x1ef4\\x1ef6\\x1ef8\\x1efa\\x1efc\\x1efe\\x1f08-\\x1f0f" + "\\x1f18-\\x1f1d\\x1f28-\\x1f2f\\x1f38-\\x1f3f\\x1f48-\\x1f4d" + "\\x1f59\\x1f5b\\x1f5d\\x1f5f\\x1f68-\\x1f6f\\x1fb8-\\x1fbb" + "\\x1fc8-\\x1fcb\\x1fd8-\\x1fdb\\x1fe8-\\x1fec\\x1ff8-\\x1ffb" + "\\x2102\\x2107\\x210b-\\x210d\\x2110-\\x2112\\x2115" + "\\x2119-\\x211d\\x2124\\x2126\\x2128\\x212a-\\x212d" + "\\x2130-\\x2133\\x213e\\x213f\\x2145\\x2183\\x2c00-\\x2c2e" + "\\x2c60\\x2c62-\\x2c64\\x2c67\\x2c69\\x2c6b\\x2c6d-\\x2c70" + "\\x2c72\\x2c75\\x2c7e-\\x2c80\\x2c82\\x2c84\\x2c86\\x2c88\\x2c8a" + "\\x2c8c\\x2c8e\\x2c90\\x2c92\\x2c94\\x2c96\\x2c98\\x2c9a\\x2c9c" + "\\x2c9e\\x2ca0\\x2ca2\\x2ca4\\x2ca6\\x2ca8\\x2caa\\x2cac\\x2cae" + "\\x2cb0\\x2cb2\\x2cb4\\x2cb6\\x2cb8\\x2cba\\x2cbc\\x2cbe\\x2cc0" + "\\x2cc2\\x2cc4\\x2cc6\\x2cc8\\x2cca\\x2ccc\\x2cce\\x2cd0\\x2cd2" + "\\x2cd4\\x2cd6\\x2cd8\\x2cda\\x2cdc\\x2cde\\x2ce0\\x2ce2\\x2ceb" + "\\x2ced\\xa640\\xa642\\xa644\\xa646\\xa648\\xa64a\\xa64c\\xa64e" + "\\xa650\\xa652\\xa654\\xa656\\xa658\\xa65a\\xa65c\\xa65e\\xa660" + "\\xa662\\xa664\\xa666\\xa668\\xa66a\\xa66c\\xa680\\xa682\\xa684" + "\\xa686\\xa688\\xa68a\\xa68c\\xa68e\\xa690\\xa692\\xa694\\xa696" + "\\xa722\\xa724\\xa726\\xa728\\xa72a\\xa72c\\xa72e\\xa732\\xa734" + "\\xa736\\xa738\\xa73a\\xa73c\\xa73e\\xa740\\xa742\\xa744\\xa746" + "\\xa748\\xa74a\\xa74c\\xa74e\\xa750\\xa752\\xa754\\xa756\\xa758" + "\\xa75a\\xa75c\\xa75e\\xa760\\xa762\\xa764\\xa766\\xa768\\xa76a" + "\\xa76c\\xa76e\\xa779\\xa77b\\xa77d\\xa77e\\xa780\\xa782\\xa784" + "\\xa786\\xa78b\\xa78d\\xa790\\xa7a0\\xa7a2\\xa7a4\\xa7a6\\xa7a8" + "\\xff21-\\xff3a\\x10400-\\x10427\\x1d400-\\x1d419" + "\\x1d434-\\x1d44d\\x1d468-\\x1d481\\x1d49c\\x1d49e\\x1d49f" + "\\x1d4a2\\x1d4a5\\x1d4a6\\x1d4a9-\\x1d4ac\\x1d4ae-\\x1d4b5" + "\\x1d4d0-\\x1d4e9\\x1d504\\x1d505\\x1d507-\\x1d50a" + "\\x1d50d-\\x1d514\\x1d516-\\x1d51c\\x1d538\\x1d539" + "\\x1d53b-\\x1d53e\\x1d540-\\x1d544\\x1d546\\x1d54a-\\x1d550" + "\\x1d56c-\\x1d585\\x1d5a0-\\x1d5b9\\x1d5d4-\\x1d5ed" + "\\x1d608-\\x1d621\\x1d63c-\\x1d655\\x1d670-\\x1d689" + "\\x1d6a8-\\x1d6c0\\x1d6e2-\\x1d6fa\\x1d71c-\\x1d734" + "\\x1d756-\\x1d76e\\x1d790-\\x1d7a8\\x1d7ca]"; + } + + static const char *letter_lowercase() + { + return "[\\x61-\\x7a\\xaa\\xb5\\xba\\xdf-\\xf6\\xf8-\\xff\\x101" + "\\x103\\x105\\x107\\x109\\x10b\\x10d\\x10f\\x111\\x113\\x115" + "\\x117\\x119\\x11b\\x11d\\x11f\\x121\\x123\\x125\\x127\\x129" + "\\x12b\\x12d\\x12f\\x131\\x133\\x135\\x137\\x138\\x13a\\x13c" + "\\x13e\\x140\\x142\\x144\\x146\\x148\\x149\\x14b\\x14d\\x14f" + "\\x151\\x153\\x155\\x157\\x159\\x15b\\x15d\\x15f\\x161\\x163" + "\\x165\\x167\\x169\\x16b\\x16d\\x16f\\x171\\x173\\x175\\x177" + "\\x17a\\x17c\\x17e-\\x180\\x183\\x185\\x188\\x18c\\x18d\\x192" + "\\x195\\x199-\\x19b\\x19e\\x1a1\\x1a3\\x1a5\\x1a8\\x1aa\\x1ab" + "\\x1ad\\x1b0\\x1b4\\x1b6\\x1b9\\x1ba\\x1bd-\\x1bf\\x1c6\\x1c9" + "\\x1cc\\x1ce\\x1d0\\x1d2\\x1d4\\x1d6\\x1d8\\x1da\\x1dc\\x1dd" + "\\x1df\\x1e1\\x1e3\\x1e5\\x1e7\\x1e9\\x1eb\\x1ed\\x1ef\\x1f0" + "\\x1f3\\x1f5\\x1f9\\x1fb\\x1fd\\x1ff\\x201\\x203\\x205\\x207" + "\\x209\\x20b\\x20d\\x20f\\x211\\x213\\x215\\x217\\x219\\x21b" + "\\x21d\\x21f\\x221\\x223\\x225\\x227\\x229\\x22b\\x22d\\x22f" + "\\x231\\x233-\\x239\\x23c\\x23f\\x240\\x242\\x247\\x249\\x24b" + "\\x24d\\x24f-\\x293\\x295-\\x2af\\x371\\x373\\x377\\x37b-\\x37d" + "\\x390\\x3ac-\\x3ce\\x3d0\\x3d1\\x3d5-\\x3d7\\x3d9\\x3db\\x3dd" + "\\x3df\\x3e1\\x3e3\\x3e5\\x3e7\\x3e9\\x3eb\\x3ed\\x3ef-\\x3f3" + "\\x3f5\\x3f8\\x3fb\\x3fc\\x430-\\x45f\\x461\\x463\\x465\\x467" + "\\x469\\x46b\\x46d\\x46f\\x471\\x473\\x475\\x477\\x479\\x47b" + "\\x47d\\x47f\\x481\\x48b\\x48d\\x48f\\x491\\x493\\x495\\x497" + "\\x499\\x49b\\x49d\\x49f\\x4a1\\x4a3\\x4a5\\x4a7\\x4a9\\x4ab" + "\\x4ad\\x4af\\x4b1\\x4b3\\x4b5\\x4b7\\x4b9\\x4bb\\x4bd\\x4bf" + "\\x4c2\\x4c4\\x4c6\\x4c8\\x4ca\\x4cc\\x4ce\\x4cf\\x4d1\\x4d3" + "\\x4d5\\x4d7\\x4d9\\x4db\\x4dd\\x4df\\x4e1\\x4e3\\x4e5\\x4e7" + "\\x4e9\\x4eb\\x4ed\\x4ef\\x4f1\\x4f3\\x4f5\\x4f7\\x4f9\\x4fb" + "\\x4fd\\x4ff\\x501\\x503\\x505\\x507\\x509\\x50b\\x50d\\x50f" + "\\x511\\x513\\x515\\x517\\x519\\x51b\\x51d\\x51f\\x521\\x523" + "\\x525\\x527\\x561-\\x587\\x1d00-\\x1d2b\\x1d62-\\x1d77" + "\\x1d79-\\x1d9a\\x1e01\\x1e03\\x1e05\\x1e07\\x1e09\\x1e0b" + "\\x1e0d\\x1e0f\\x1e11\\x1e13\\x1e15\\x1e17\\x1e19\\x1e1b" + "\\x1e1d\\x1e1f\\x1e21\\x1e23\\x1e25\\x1e27\\x1e29\\x1e2b\\x1e2d" + "\\x1e2f\\x1e31\\x1e33\\x1e35\\x1e37\\x1e39\\x1e3b\\x1e3d\\x1e3f" + "\\x1e41\\x1e43\\x1e45\\x1e47\\x1e49\\x1e4b\\x1e4d\\x1e4f\\x1e51" + "\\x1e53\\x1e55\\x1e57\\x1e59\\x1e5b\\x1e5d\\x1e5f\\x1e61\\x1e63" + "\\x1e65\\x1e67\\x1e69\\x1e6b\\x1e6d\\x1e6f\\x1e71\\x1e73\\x1e75" + "\\x1e77\\x1e79\\x1e7b\\x1e7d\\x1e7f\\x1e81\\x1e83\\x1e85\\x1e87" + "\\x1e89\\x1e8b\\x1e8d\\x1e8f\\x1e91\\x1e93\\x1e95-\\x1e9d\\x1e9f" + "\\x1ea1\\x1ea3\\x1ea5\\x1ea7\\x1ea9\\x1eab\\x1ead\\x1eaf\\x1eb1" + "\\x1eb3\\x1eb5\\x1eb7\\x1eb9\\x1ebb\\x1ebd\\x1ebf\\x1ec1\\x1ec3" + "\\x1ec5\\x1ec7\\x1ec9\\x1ecb\\x1ecd\\x1ecf\\x1ed1\\x1ed3\\x1ed5" + "\\x1ed7\\x1ed9\\x1edb\\x1edd\\x1edf\\x1ee1\\x1ee3\\x1ee5\\x1ee7" + "\\x1ee9\\x1eeb\\x1eed\\x1eef\\x1ef1\\x1ef3\\x1ef5\\x1ef7\\x1ef9" + "\\x1efb\\x1efd\\x1eff-\\x1f07\\x1f10-\\x1f15\\x1f20-\\x1f27" + "\\x1f30-\\x1f37\\x1f40-\\x1f45\\x1f50-\\x1f57\\x1f60-\\x1f67" + "\\x1f70-\\x1f7d\\x1f80-\\x1f87\\x1f90-\\x1f97\\x1fa0-\\x1fa7" + "\\x1fb0-\\x1fb4\\x1fb6\\x1fb7\\x1fbe\\x1fc2-\\x1fc4\\x1fc6" + "\\x1fc7\\x1fd0-\\x1fd3\\x1fd6\\x1fd7\\x1fe0-\\x1fe7" + "\\x1ff2-\\x1ff4\\x1ff6\\x1ff7\\x210a\\x210e\\x210f\\x2113" + "\\x212f\\x2134\\x2139\\x213c\\x213d\\x2146-\\x2149\\x214e" + "\\x2184\\x2c30-\\x2c5e\\x2c61\\x2c65\\x2c66\\x2c68\\x2c6a" + "\\x2c6c\\x2c71\\x2c73\\x2c74\\x2c76-\\x2c7c\\x2c81\\x2c83" + "\\x2c85\\x2c87\\x2c89\\x2c8b\\x2c8d\\x2c8f\\x2c91\\x2c93\\x2c95" + "\\x2c97\\x2c99\\x2c9b\\x2c9d\\x2c9f\\x2ca1\\x2ca3\\x2ca5\\x2ca7" + "\\x2ca9\\x2cab\\x2cad\\x2caf\\x2cb1\\x2cb3\\x2cb5\\x2cb7\\x2cb9" + "\\x2cbb\\x2cbd\\x2cbf\\x2cc1\\x2cc3\\x2cc5\\x2cc7\\x2cc9\\x2ccb" + "\\x2ccd\\x2ccf\\x2cd1\\x2cd3\\x2cd5\\x2cd7\\x2cd9\\x2cdb\\x2cdd" + "\\x2cdf\\x2ce1\\x2ce3\\x2ce4\\x2cec\\x2cee\\x2d00-\\x2d25\\xa641" + "\\xa643\\xa645\\xa647\\xa649\\xa64b\\xa64d\\xa64f\\xa651\\xa653" + "\\xa655\\xa657\\xa659\\xa65b\\xa65d\\xa65f\\xa661\\xa663\\xa665" + "\\xa667\\xa669\\xa66b\\xa66d\\xa681\\xa683\\xa685\\xa687\\xa689" + "\\xa68b\\xa68d\\xa68f\\xa691\\xa693\\xa695\\xa697\\xa723\\xa725" + "\\xa727\\xa729\\xa72b\\xa72d\\xa72f-\\xa731\\xa733\\xa735\\xa737" + "\\xa739\\xa73b\\xa73d\\xa73f\\xa741\\xa743\\xa745\\xa747\\xa749" + "\\xa74b\\xa74d\\xa74f\\xa751\\xa753\\xa755\\xa757\\xa759\\xa75b" + "\\xa75d\\xa75f\\xa761\\xa763\\xa765\\xa767\\xa769\\xa76b\\xa76d" + "\\xa76f\\xa771-\\xa778\\xa77a\\xa77c\\xa77f\\xa781\\xa783" + "\\xa785\\xa787\\xa78c\\xa78e\\xa791\\xa7a1\\xa7a3\\xa7a5\\xa7a7" + "\\xa7a9\\xa7fa\\xfb00-\\xfb06\\xfb13-\\xfb17\\xff41-\\xff5a" + "\\x10428-\\x1044f\\x1d41a-\\x1d433\\x1d44e-\\x1d454" + "\\x1d456-\\x1d467\\x1d482-\\x1d49b\\x1d4b6-\\x1d4b9\\x1d4bb" + "\\x1d4bd-\\x1d4c3\\x1d4c5-\\x1d4cf\\x1d4ea-\\x1d503" + "\\x1d51e-\\x1d537\\x1d552-\\x1d56b\\x1d586-\\x1d59f" + "\\x1d5ba-\\x1d5d3\\x1d5ee-\\x1d607\\x1d622-\\x1d63b" + "\\x1d656-\\x1d66f\\x1d68a-\\x1d6a5\\x1d6c2-\\x1d6da" + "\\x1d6dc-\\x1d6e1\\x1d6fc-\\x1d714\\x1d716-\\x1d71b" + "\\x1d736-\\x1d74e\\x1d750-\\x1d755\\x1d770-\\x1d788" + "\\x1d78a-\\x1d78f\\x1d7aa-\\x1d7c2\\x1d7c4-\\x1d7c9\\x1d7cb]"; + } + + static const char *letter_titlecase() + { + return "[\\x1c5\\x1c8\\x1cb\\x1f2\\x1f88-\\x1f8f\\x1f98-\\x1f9f" + "\\x1fa8-\\x1faf\\x1fbc\\x1fcc\\x1ffc]"; + } + + static const char *letter_modifier() + { + return "[\\x2b0-\\x2c1\\x2c6-\\x2d1\\x2e0-\\x2e4\\x2ec\\x2ee\\x374" + "\\x37a\\x559\\x640\\x6e5\\x6e6\\x7f4\\x7f5\\x7fa\\x81a\\x824" + "\\x828\\x971\\xe46\\xec6\\x10fc\\x17d7\\x1843\\x1aa7" + "\\x1c78-\\x1c7d\\x1d2c-\\x1d61\\x1d78\\x1d9b-\\x1dbf\\x2071" + "\\x207f\\x2090-\\x209c\\x2c7d\\x2d6f\\x2e2f\\x3005" + "\\x3031-\\x3035\\x303b\\x309d\\x309e\\x30fc-\\x30fe\\xa015" + "\\xa4f8-\\xa4fd\\xa60c\\xa67f\\xa717-\\xa71f\\xa770\\xa788" + "\\xa9cf\\xaa70\\xaadd\\xff70\\xff9e\\xff9f]"; + } + + static const char *letter_other() + { + return "[\\x1bb\\x1c0-\\x1c3\\x294\\x5d0-\\x5ea\\x5f0-\\x5f2" + "\\x620-\\x63f\\x641-\\x64a\\x66e\\x66f\\x671-\\x6d3\\x6d5\\x6ee" + "\\x6ef\\x6fa-\\x6fc\\x6ff\\x710\\x712-\\x72f\\x74d-\\x7a5\\x7b1" + "\\x7ca-\\x7ea\\x800-\\x815\\x840-\\x858\\x904-\\x939\\x93d" + "\\x950\\x958-\\x961\\x972-\\x977\\x979-\\x97f\\x985-\\x98c\\x98f" + "\\x990\\x993-\\x9a8\\x9aa-\\x9b0\\x9b2\\x9b6-\\x9b9\\x9bd\\x9ce" + "\\x9dc\\x9dd\\x9df-\\x9e1\\x9f0\\x9f1\\xa05-\\xa0a\\xa0f\\xa10" + "\\xa13-\\xa28\\xa2a-\\xa30\\xa32\\xa33\\xa35\\xa36\\xa38\\xa39" + "\\xa59-\\xa5c\\xa5e\\xa72-\\xa74\\xa85-\\xa8d\\xa8f-\\xa91" + "\\xa93-\\xaa8\\xaaa-\\xab0\\xab2\\xab3\\xab5-\\xab9\\xabd\\xad0" + "\\xae0\\xae1\\xb05-\\xb0c\\xb0f\\xb10\\xb13-\\xb28\\xb2a-\\xb30" + "\\xb32\\xb33\\xb35-\\xb39\\xb3d\\xb5c\\xb5d\\xb5f-\\xb61\\xb71" + "\\xb83\\xb85-\\xb8a\\xb8e-\\xb90\\xb92-\\xb95\\xb99\\xb9a\\xb9c" + "\\xb9e\\xb9f\\xba3\\xba4\\xba8-\\xbaa\\xbae-\\xbb9\\xbd0" + "\\xc05-\\xc0c\\xc0e-\\xc10\\xc12-\\xc28\\xc2a-\\xc33" + "\\xc35-\\xc39\\xc3d\\xc58\\xc59\\xc60\\xc61\\xc85-\\xc8c" + "\\xc8e-\\xc90\\xc92-\\xca8\\xcaa-\\xcb3\\xcb5-\\xcb9\\xcbd" + "\\xcde\\xce0\\xce1\\xcf1\\xcf2\\xd05-\\xd0c\\xd0e-\\xd10" + "\\xd12-\\xd3a\\xd3d\\xd4e\\xd60\\xd61\\xd7a-\\xd7f\\xd85-\\xd96" + "\\xd9a-\\xdb1\\xdb3-\\xdbb\\xdbd\\xdc0-\\xdc6\\xe01-\\xe30\\xe32" + "\\xe33\\xe40-\\xe45\\xe81\\xe82\\xe84\\xe87\\xe88\\xe8a\\xe8d" + "\\xe94-\\xe97\\xe99-\\xe9f\\xea1-\\xea3\\xea5\\xea7\\xeaa\\xeab" + "\\xead-\\xeb0\\xeb2\\xeb3\\xebd\\xec0-\\xec4\\xedc\\xedd\\xf00" + "\\xf40-\\xf47\\xf49-\\xf6c\\xf88-\\xf8c\\x1000-\\x102a\\x103f" + "\\x1050-\\x1055\\x105a-\\x105d\\x1061\\x1065\\x1066" + "\\x106e-\\x1070\\x1075-\\x1081\\x108e\\x10d0-\\x10fa" + "\\x1100-\\x1248\\x124a-\\x124d\\x1250-\\x1256\\x1258" + "\\x125a-\\x125d\\x1260-\\x1288\\x128a-\\x128d\\x1290-\\x12b0" + "\\x12b2-\\x12b5\\x12b8-\\x12be\\x12c0\\x12c2-\\x12c5" + "\\x12c8-\\x12d6\\x12d8-\\x1310\\x1312-\\x1315\\x1318-\\x135a" + "\\x1380-\\x138f\\x13a0-\\x13f4\\x1401-\\x166c\\x166f-\\x167f" + "\\x1681-\\x169a\\x16a0-\\x16ea\\x1700-\\x170c\\x170e-\\x1711" + "\\x1720-\\x1731\\x1740-\\x1751\\x1760-\\x176c\\x176e-\\x1770" + "\\x1780-\\x17b3\\x17dc\\x1820-\\x1842\\x1844-\\x1877" + "\\x1880-\\x18a8\\x18aa\\x18b0-\\x18f5\\x1900-\\x191c" + "\\x1950-\\x196d\\x1970-\\x1974\\x1980-\\x19ab\\x19c1-\\x19c7" + "\\x1a00-\\x1a16\\x1a20-\\x1a54\\x1b05-\\x1b33\\x1b45-\\x1b4b" + "\\x1b83-\\x1ba0\\x1bae\\x1baf\\x1bc0-\\x1be5\\x1c00-\\x1c23" + "\\x1c4d-\\x1c4f\\x1c5a-\\x1c77\\x1ce9-\\x1cec\\x1cee-\\x1cf1" + "\\x2135-\\x2138\\x2d30-\\x2d65\\x2d80-\\x2d96\\x2da0-\\x2da6" + "\\x2da8-\\x2dae\\x2db0-\\x2db6\\x2db8-\\x2dbe\\x2dc0-\\x2dc6" + "\\x2dc8-\\x2dce\\x2dd0-\\x2dd6\\x2dd8-\\x2dde\\x3006\\x303c" + "\\x3041-\\x3096\\x309f\\x30a1-\\x30fa\\x30ff\\x3105-\\x312d" + "\\x3131-\\x318e\\x31a0-\\x31ba\\x31f0-\\x31ff\\x3400\\x4db5" + "\\x4e00\\x9fcb\\xa000-\\xa014\\xa016-\\xa48c\\xa4d0-\\xa4f7" + "\\xa500-\\xa60b\\xa610-\\xa61f\\xa62a\\xa62b\\xa66e" + "\\xa6a0-\\xa6e5\\xa7fb-\\xa801\\xa803-\\xa805\\xa807-\\xa80a" + "\\xa80c-\\xa822\\xa840-\\xa873\\xa882-\\xa8b3\\xa8f2-\\xa8f7" + "\\xa8fb\\xa90a-\\xa925\\xa930-\\xa946\\xa960-\\xa97c" + "\\xa984-\\xa9b2\\xaa00-\\xaa28\\xaa40-\\xaa42\\xaa44-\\xaa4b" + "\\xaa60-\\xaa6f\\xaa71-\\xaa76\\xaa7a\\xaa80-\\xaaaf\\xaab1" + "\\xaab5\\xaab6\\xaab9-\\xaabd\\xaac0\\xaac2\\xaadb\\xaadc" + "\\xab01-\\xab06\\xab09-\\xab0e\\xab11-\\xab16\\xab20-\\xab26" + "\\xab28-\\xab2e\\xabc0-\\xabe2\\xac00\\xd7a3\\xd7b0-\\xd7c6" + "\\xd7cb-\\xd7fb\\xf900-\\xfa2d\\xfa30-\\xfa6d\\xfa70-\\xfad9" + "\\xfb1d\\xfb1f-\\xfb28\\xfb2a-\\xfb36\\xfb38-\\xfb3c\\xfb3e" + "\\xfb40\\xfb41\\xfb43\\xfb44\\xfb46-\\xfbb1\\xfbd3-\\xfd3d" + "\\xfd50-\\xfd8f\\xfd92-\\xfdc7\\xfdf0-\\xfdfb\\xfe70-\\xfe74" + "\\xfe76-\\xfefc\\xff66-\\xff6f\\xff71-\\xff9d\\xffa0-\\xffbe" + "\\xffc2-\\xffc7\\xffca-\\xffcf\\xffd2-\\xffd7\\xffda-\\xffdc" + "\\x10000-\\x1000b\\x1000d-\\x10026\\x10028-\\x1003a\\x1003c" + "\\x1003d\\x1003f-\\x1004d\\x10050-\\x1005d\\x10080-\\x100fa" + "\\x10280-\\x1029c\\x102a0-\\x102d0\\x10300-\\x1031e" + "\\x10330-\\x10340\\x10342-\\x10349\\x10380-\\x1039d" + "\\x103a0-\\x103c3\\x103c8-\\x103cf\\x10450-\\x1049d" + "\\x10800-\\x10805\\x10808\\x1080a-\\x10835\\x10837\\x10838" + "\\x1083c\\x1083f-\\x10855\\x10900-\\x10915\\x10920-\\x10939" + "\\x10a00\\x10a10-\\x10a13\\x10a15-\\x10a17\\x10a19-\\x10a33" + "\\x10a60-\\x10a7c\\x10b00-\\x10b35\\x10b40-\\x10b55" + "\\x10b60-\\x10b72\\x10c00-\\x10c48\\x11003-\\x11037" + "\\x11083-\\x110af\\x12000-\\x1236e\\x13000-\\x1342e" + "\\x16800-\\x16a38\\x1b000\\x1b001\\x20000\\x2a6d6\\x2a700" + "\\x2b734\\x2b740\\x2b81d\\x2f800-\\x2fa1d]"; + } + + static const char *mark_nonspacing() + { + return "[\\x300-\\x36f\\x483-\\x487\\x591-\\x5bd\\x5bf\\x5c1\\x5c2" + "\\x5c4\\x5c5\\x5c7\\x610-\\x61a\\x64b-\\x65f\\x670\\x6d6-\\x6dc" + "\\x6df-\\x6e4\\x6e7\\x6e8\\x6ea-\\x6ed\\x711\\x730-\\x74a" + "\\x7a6-\\x7b0\\x7eb-\\x7f3\\x816-\\x819\\x81b-\\x823" + "\\x825-\\x827\\x829-\\x82d\\x859-\\x85b\\x900-\\x902\\x93a\\x93c" + "\\x941-\\x948\\x94d\\x951-\\x957\\x962\\x963\\x981\\x9bc" + "\\x9c1-\\x9c4\\x9cd\\x9e2\\x9e3\\xa01\\xa02\\xa3c\\xa41\\xa42" + "\\xa47\\xa48\\xa4b-\\xa4d\\xa51\\xa70\\xa71\\xa75\\xa81\\xa82" + "\\xabc\\xac1-\\xac5\\xac7\\xac8\\xacd\\xae2\\xae3\\xb01\\xb3c" + "\\xb3f\\xb41-\\xb44\\xb4d\\xb56\\xb62\\xb63\\xb82\\xbc0\\xbcd" + "\\xc3e-\\xc40\\xc46-\\xc48\\xc4a-\\xc4d\\xc55\\xc56\\xc62\\xc63" + "\\xcbc\\xcbf\\xcc6\\xccc\\xccd\\xce2\\xce3\\xd41-\\xd44\\xd4d" + "\\xd62\\xd63\\xdca\\xdd2-\\xdd4\\xdd6\\xe31\\xe34-\\xe3a" + "\\xe47-\\xe4e\\xeb1\\xeb4-\\xeb9\\xebb\\xebc\\xec8-\\xecd\\xf18" + "\\xf19\\xf35\\xf37\\xf39\\xf71-\\xf7e\\xf80-\\xf84\\xf86\\xf87" + "\\xf8d-\\xf97\\xf99-\\xfbc\\xfc6\\x102d-\\x1030\\x1032-\\x1037" + "\\x1039\\x103a\\x103d\\x103e\\x1058\\x1059\\x105e-\\x1060" + "\\x1071-\\x1074\\x1082\\x1085\\x1086\\x108d\\x109d" + "\\x135d-\\x135f\\x1712-\\x1714\\x1732-\\x1734\\x1752\\x1753" + "\\x1772\\x1773\\x17b7-\\x17bd\\x17c6\\x17c9-\\x17d3\\x17dd" + "\\x180b-\\x180d\\x18a9\\x1920-\\x1922\\x1927\\x1928\\x1932" + "\\x1939-\\x193b\\x1a17\\x1a18\\x1a56\\x1a58-\\x1a5e\\x1a60" + "\\x1a62\\x1a65-\\x1a6c\\x1a73-\\x1a7c\\x1a7f\\x1b00-\\x1b03" + "\\x1b34\\x1b36-\\x1b3a\\x1b3c\\x1b42\\x1b6b-\\x1b73\\x1b80" + "\\x1b81\\x1ba2-\\x1ba5\\x1ba8\\x1ba9\\x1be6\\x1be8\\x1be9\\x1bed" + "\\x1bef-\\x1bf1\\x1c2c-\\x1c33\\x1c36\\x1c37\\x1cd0-\\x1cd2" + "\\x1cd4-\\x1ce0\\x1ce2-\\x1ce8\\x1ced\\x1dc0-\\x1de6" + "\\x1dfc-\\x1dff\\x20d0-\\x20dc\\x20e1\\x20e5-\\x20f0" + "\\x2cef-\\x2cf1\\x2d7f\\x2de0-\\x2dff\\x302a-\\x302f\\x3099" + "\\x309a\\xa66f\\xa67c\\xa67d\\xa6f0\\xa6f1\\xa802\\xa806\\xa80b" + "\\xa825\\xa826\\xa8c4\\xa8e0-\\xa8f1\\xa926-\\xa92d" + "\\xa947-\\xa951\\xa980-\\xa982\\xa9b3\\xa9b6-\\xa9b9\\xa9bc" + "\\xaa29-\\xaa2e\\xaa31\\xaa32\\xaa35\\xaa36\\xaa43\\xaa4c\\xaab0" + "\\xaab2-\\xaab4\\xaab7\\xaab8\\xaabe\\xaabf\\xaac1\\xabe5\\xabe8" + "\\xabed\\xfb1e\\xfe00-\\xfe0f\\xfe20-\\xfe26\\x101fd" + "\\x10a01-\\x10a03\\x10a05\\x10a06\\x10a0c-\\x10a0f" + "\\x10a38-\\x10a3a\\x10a3f\\x11001\\x11038-\\x11046\\x11080" + "\\x11081\\x110b3-\\x110b6\\x110b9\\x110ba\\x1d167-\\x1d169" + "\\x1d17b-\\x1d182\\x1d185-\\x1d18b\\x1d1aa-\\x1d1ad" + "\\x1d242-\\x1d244\\xe0100-\\xe01ef]"; + } + + static const char *mark_combining() + { + return "[\\x903\\x93b\\x93e-\\x940\\x949-\\x94c\\x94e\\x94f\\x982" + "\\x983\\x9be-\\x9c0\\x9c7\\x9c8\\x9cb\\x9cc\\x9d7\\xa03" + "\\xa3e-\\xa40\\xa83\\xabe-\\xac0\\xac9\\xacb\\xacc\\xb02\\xb03" + "\\xb3e\\xb40\\xb47\\xb48\\xb4b\\xb4c\\xb57\\xbbe\\xbbf\\xbc1" + "\\xbc2\\xbc6-\\xbc8\\xbca-\\xbcc\\xbd7\\xc01-\\xc03\\xc41-\\xc44" + "\\xc82\\xc83\\xcbe\\xcc0-\\xcc4\\xcc7\\xcc8\\xcca\\xccb\\xcd5" + "\\xcd6\\xd02\\xd03\\xd3e-\\xd40\\xd46-\\xd48\\xd4a-\\xd4c\\xd57" + "\\xd82\\xd83\\xdcf-\\xdd1\\xdd8-\\xddf\\xdf2\\xdf3\\xf3e\\xf3f" + "\\xf7f\\x102b\\x102c\\x1031\\x1038\\x103b\\x103c\\x1056\\x1057" + "\\x1062-\\x1064\\x1067-\\x106d\\x1083\\x1084\\x1087-\\x108c" + "\\x108f\\x109a-\\x109c\\x17b6\\x17be-\\x17c5\\x17c7\\x17c8" + "\\x1923-\\x1926\\x1929-\\x192b\\x1930\\x1931\\x1933-\\x1938" + "\\x19b0-\\x19c0\\x19c8\\x19c9\\x1a19-\\x1a1b\\x1a55\\x1a57" + "\\x1a61\\x1a63\\x1a64\\x1a6d-\\x1a72\\x1b04\\x1b35\\x1b3b" + "\\x1b3d-\\x1b41\\x1b43\\x1b44\\x1b82\\x1ba1\\x1ba6\\x1ba7\\x1baa" + "\\x1be7\\x1bea-\\x1bec\\x1bee\\x1bf2\\x1bf3\\x1c24-\\x1c2b" + "\\x1c34\\x1c35\\x1ce1\\x1cf2\\xa823\\xa824\\xa827\\xa880\\xa881" + "\\xa8b4-\\xa8c3\\xa952\\xa953\\xa983\\xa9b4\\xa9b5\\xa9ba" + "\\xa9bb\\xa9bd-\\xa9c0\\xaa2f\\xaa30\\xaa33\\xaa34\\xaa4d\\xaa7b" + "\\xabe3\\xabe4\\xabe6\\xabe7\\xabe9\\xabea\\xabec\\x11000" + "\\x11002\\x11082\\x110b0-\\x110b2\\x110b7\\x110b8\\x1d165" + "\\x1d166\\x1d16d-\\x1d172]"; + } + + static const char *mark_enclosing() + { + return "[\\x488\\x489\\x20dd-\\x20e0\\x20e2-\\x20e4\\xa670-\\xa672]"; + } + + static const char *number_decimal() + { + return "[\\x30-\\x39\\x660-\\x669\\x6f0-\\x6f9\\x7c0-\\x7c9" + "\\x966-\\x96f\\x9e6-\\x9ef\\xa66-\\xa6f\\xae6-\\xaef" + "\\xb66-\\xb6f\\xbe6-\\xbef\\xc66-\\xc6f\\xce6-\\xcef" + "\\xd66-\\xd6f\\xe50-\\xe59\\xed0-\\xed9\\xf20-\\xf29" + "\\x1040-\\x1049\\x1090-\\x1099\\x17e0-\\x17e9\\x1810-\\x1819" + "\\x1946-\\x194f\\x19d0-\\x19d9\\x1a80-\\x1a89\\x1a90-\\x1a99" + "\\x1b50-\\x1b59\\x1bb0-\\x1bb9\\x1c40-\\x1c49\\x1c50-\\x1c59" + "\\xa620-\\xa629\\xa8d0-\\xa8d9\\xa900-\\xa909\\xa9d0-\\xa9d9" + "\\xaa50-\\xaa59\\xabf0-\\xabf9\\xff10-\\xff19\\x104a0-\\x104a9" + "\\x11066-\\x1106f\\x1d7ce-\\x1d7ff]"; + } + + static const char *number_letter() + { + return "[\\x16ee-\\x16f0\\x2160-\\x2182\\x2185-\\x2188\\x3007" + "\\x3021-\\x3029\\x3038-\\x303a\\xa6e6-\\xa6ef\\x10140-\\x10174" + "\\x10341\\x1034a\\x103d1-\\x103d5\\x12400-\\x12462]"; + } + + static const char *number_other() + { + return "[\\xb2\\xb3\\xb9\\xbc-\\xbe\\x9f4-\\x9f9\\xb72-\\xb77" + "\\xbf0-\\xbf2\\xc78-\\xc7e\\xd70-\\xd75\\xf2a-\\xf33" + "\\x1369-\\x137c\\x17f0-\\x17f9\\x19da\\x2070\\x2074-\\x2079" + "\\x2080-\\x2089\\x2150-\\x215f\\x2189\\x2460-\\x249b" + "\\x24ea-\\x24ff\\x2776-\\x2793\\x2cfd\\x3192-\\x3195" + "\\x3220-\\x3229\\x3251-\\x325f\\x3280-\\x3289\\x32b1-\\x32bf" + "\\xa830-\\xa835\\x10107-\\x10133\\x10175-\\x10178\\x1018a" + "\\x10320-\\x10323\\x10858-\\x1085f\\x10916-\\x1091b" + "\\x10a40-\\x10a47\\x10a7d\\x10a7e\\x10b58-\\x10b5f" + "\\x10b78-\\x10b7f\\x10e60-\\x10e7e\\x11052-\\x11065" + "\\x1d360-\\x1d371\\x1f100-\\x1f10a]"; + } + + static const char *punctuation_connector() + { + return "[\\x5f\\x203f\\x2040\\x2054\\xfe33\\xfe34\\xfe4d-\\xfe4f" + "\\xff3f]"; + } + + static const char *punctuation_dash() + { + return "[\\x2d\\x58a\\x5be\\x1400\\x1806\\x2010-\\x2015\\x2e17\\x2e1a" + "\\x301c\\x3030\\x30a0\\xfe31\\xfe32\\xfe58\\xfe63\\xff0d]"; + } + + static const char *punctuation_open() + { + return "[\\x28\\x5b\\x7b\\xf3a\\xf3c\\x169b\\x201a\\x201e\\x2045" + "\\x207d\\x208d\\x2329\\x2768\\x276a\\x276c\\x276e\\x2770\\x2772" + "\\x2774\\x27c5\\x27e6\\x27e8\\x27ea\\x27ec\\x27ee\\x2983\\x2985" + "\\x2987\\x2989\\x298b\\x298d\\x298f\\x2991\\x2993\\x2995\\x2997" + "\\x29d8\\x29da\\x29fc\\x2e22\\x2e24\\x2e26\\x2e28\\x3008\\x300a" + "\\x300c\\x300e\\x3010\\x3014\\x3016\\x3018\\x301a\\x301d\\xfd3e" + "\\xfe17\\xfe35\\xfe37\\xfe39\\xfe3b\\xfe3d\\xfe3f\\xfe41\\xfe43" + "\\xfe47\\xfe59\\xfe5b\\xfe5d\\xff08\\xff3b\\xff5b\\xff5f\\xff62]"; + } + + static const char *punctuation_close() + { + return "[\\x29\\x5d\\x7d\\xf3b\\xf3d\\x169c\\x2046\\x207e\\x208e" + "\\x232a\\x2769\\x276b\\x276d\\x276f\\x2771\\x2773\\x2775\\x27c6" + "\\x27e7\\x27e9\\x27eb\\x27ed\\x27ef\\x2984\\x2986\\x2988\\x298a" + "\\x298c\\x298e\\x2990\\x2992\\x2994\\x2996\\x2998\\x29d9\\x29db" + "\\x29fd\\x2e23\\x2e25\\x2e27\\x2e29\\x3009\\x300b\\x300d\\x300f" + "\\x3011\\x3015\\x3017\\x3019\\x301b\\x301e\\x301f\\xfd3f\\xfe18" + "\\xfe36\\xfe38\\xfe3a\\xfe3c\\xfe3e\\xfe40\\xfe42\\xfe44\\xfe48" + "\\xfe5a\\xfe5c\\xfe5e\\xff09\\xff3d\\xff5d\\xff60\\xff63]"; + } + + static const char *punctuation_initial() + { + return "[\\x00AB\\x2018\\x201B\\x201C\\x201F\\x2039\\x2E02\\x2E04" + "\\x2E09\\x2E0C\\x2E1C\\x2E20]"; + } + + static const char *punctuation_final() + { + return "[\\x00BB\\x2019\\x201D\\x203A\\x2E03\\x2E05\\x2E0A\\x2E0D" + "\\x2E1D\\x2E21]"; + } + + static const char *punctuation_other() + { + return "[\\x21-\\x23\\x25-\\x27\\x2a\\x2c\\x2e\\x2f\\x3a\\x3b\\x3f" + "\\x40\\x5c\\xa1\\xb7\\xbf\\x37e\\x387\\x55a-\\x55f\\x589\\x5c0" + "\\x5c3\\x5c6\\x5f3\\x5f4\\x609\\x60a\\x60c\\x60d\\x61b\\x61e" + "\\x61f\\x66a-\\x66d\\x6d4\\x700-\\x70d\\x7f7-\\x7f9\\x830-\\x83e" + "\\x85e\\x964\\x965\\x970\\xdf4\\xe4f\\xe5a\\xe5b\\xf04-\\xf12" + "\\xf85\\xfd0-\\xfd4\\xfd9\\xfda\\x104a-\\x104f\\x10fb" + "\\x1361-\\x1368\\x166d\\x166e\\x16eb-\\x16ed\\x1735\\x1736" + "\\x17d4-\\x17d6\\x17d8-\\x17da\\x1800-\\x1805\\x1807-\\x180a" + "\\x1944\\x1945\\x1a1e\\x1a1f\\x1aa0-\\x1aa6\\x1aa8-\\x1aad" + "\\x1b5a-\\x1b60\\x1bfc-\\x1bff\\x1c3b-\\x1c3f\\x1c7e\\x1c7f" + "\\x1cd3\\x2016\\x2017\\x2020-\\x2027\\x2030-\\x2038" + "\\x203b-\\x203e\\x2041-\\x2043\\x2047-\\x2051\\x2053" + "\\x2055-\\x205e\\x2cf9-\\x2cfc\\x2cfe\\x2cff\\x2d70\\x2e00" + "\\x2e01\\x2e06-\\x2e08\\x2e0b\\x2e0e-\\x2e16\\x2e18\\x2e19" + "\\x2e1b\\x2e1e\\x2e1f\\x2e2a-\\x2e2e\\x2e30\\x2e31" + "\\x3001-\\x3003\\x303d\\x30fb\\xa4fe\\xa4ff\\xa60d-\\xa60f" + "\\xa673\\xa67e\\xa6f2-\\xa6f7\\xa874-\\xa877\\xa8ce\\xa8cf" + "\\xa8f8-\\xa8fa\\xa92e\\xa92f\\xa95f\\xa9c1-\\xa9cd\\xa9de" + "\\xa9df\\xaa5c-\\xaa5f\\xaade\\xaadf\\xabeb\\xfe10-\\xfe16" + "\\xfe19\\xfe30\\xfe45\\xfe46\\xfe49-\\xfe4c\\xfe50-\\xfe52" + "\\xfe54-\\xfe57\\xfe5f-\\xfe61\\xfe68\\xfe6a\\xfe6b" + "\\xff01-\\xff03\\xff05-\\xff07\\xff0a\\xff0c\\xff0e\\xff0f" + "\\xff1a\\xff1b\\xff1f\\xff20\\xff3c\\xff61\\xff64\\xff65" + "\\x10100\\x10101\\x1039f\\x103d0\\x10857\\x1091f\\x1093f" + "\\x10a50-\\x10a58\\x10a7f\\x10b39-\\x10b3f\\x11047-\\x1104d" + "\\x110bb\\x110bc\\x110be-\\x110c1\\x12470-\\x12473]"; + } + + static const char *symbol_math() + { + return "[\\x2b\\x3c-\\x3e\\x7c\\x7e\\xac\\xb1\\xd7\\xf7\\x3f6" + "\\x606-\\x608\\x2044\\x2052\\x207a-\\x207c\\x208a-\\x208c" + "\\x2118\\x2140-\\x2144\\x214b\\x2190-\\x2194\\x219a\\x219b" + "\\x21a0\\x21a3\\x21a6\\x21ae\\x21ce\\x21cf\\x21d2\\x21d4" + "\\x21f4-\\x22ff\\x2308-\\x230b\\x2320\\x2321\\x237c" + "\\x239b-\\x23b3\\x23dc-\\x23e1\\x25b7\\x25c1\\x25f8-\\x25ff" + "\\x266f\\x27c0-\\x27c4\\x27c7-\\x27ca\\x27cc\\x27ce-\\x27e5" + "\\x27f0-\\x27ff\\x2900-\\x2982\\x2999-\\x29d7\\x29dc-\\x29fb" + "\\x29fe-\\x2aff\\x2b30-\\x2b44\\x2b47-\\x2b4c\\xfb29\\xfe62" + "\\xfe64-\\xfe66\\xff0b\\xff1c-\\xff1e\\xff5c\\xff5e\\xffe2" + "\\xffe9-\\xffec\\x1d6c1\\x1d6db\\x1d6fb\\x1d715\\x1d735\\x1d74f" + "\\x1d76f\\x1d789\\x1d7a9\\x1d7c3]"; + } + + static const char *symbol_currency() + { + return "[\\x24\\xa2-\\xa5\\x60b\\x9f2\\x9f3\\x9fb\\xaf1\\xbf9\\xe3f" + "\\x17db\\x20a0-\\x20b9\\xa838\\xfdfc\\xfe69\\xff04\\xffe0\\xffe1" + "\\xffe5\\xffe6]"; + } + + static const char *symbol_modifier() + { + return "[\\x5e\\x60\\xa8\\xaf\\xb4\\xb8\\x2c2-\\x2c5\\x2d2-\\x2df" + "\\x2e5-\\x2eb\\x2ed\\x2ef-\\x2ff\\x375\\x384\\x385\\x1fbd" + "\\x1fbf-\\x1fc1\\x1fcd-\\x1fcf\\x1fdd-\\x1fdf\\x1fed-\\x1fef" + "\\x1ffd\\x1ffe\\x309b\\x309c\\xa700-\\xa716\\xa720\\xa721" + "\\xa789\\xa78a\\xfbb2-\\xfbc1\\xff3e\\xff40\\xffe3]"; + } + + static const char *symbol_other() + { + return "[\\xa6\\xa7\\xa9\\xae\\xb0\\xb6\\x482\\x60e\\x60f\\x6de" + "\\x6e9\\x6fd\\x6fe\\x7f6\\x9fa\\xb70\\xbf3-\\xbf8\\xbfa\\xc7f" + "\\xd79\\xf01-\\xf03\\xf13-\\xf17\\xf1a-\\xf1f\\xf34\\xf36\\xf38" + "\\xfbe-\\xfc5\\xfc7-\\xfcc\\xfce\\xfcf\\xfd5-\\xfd8" + "\\x109e\\x109f\\x1360\\x1390-\\x1399\\x1940\\x19de-\\x19ff" + "\\x1b61-\\x1b6a\\x1b74-\\x1b7c\\x2100\\x2101\\x2103-\\x2106" + "\\x2108\\x2109\\x2114\\x2116\\x2117\\x211e-\\x2123\\x2125" + "\\x2127\\x2129\\x212e\\x213a\\x213b\\x214a\\x214c\\x214d\\x214f" + "\\x2195-\\x2199\\x219c-\\x219f\\x21a1\\x21a2\\x21a4\\x21a5" + "\\x21a7-\\x21ad\\x21af-\\x21cd\\x21d0\\x21d1\\x21d3" + "\\x21d5-\\x21f3\\x2300-\\x2307\\x230c-\\x231f\\x2322-\\x2328" + "\\x232b-\\x237b\\x237d-\\x239a\\x23b4-\\x23db\\x23e2-\\x23f3" + "\\x2400-\\x2426\\x2440-\\x244a\\x249c-\\x24e9\\x2500-\\x25b6" + "\\x25b8-\\x25c0\\x25c2-\\x25f7\\x2600-\\x266e\\x2670-\\x26ff" + "\\x2701-\\x2767\\x2794-\\x27bf\\x2800-\\x28ff\\x2b00-\\x2b2f" + "\\x2b45\\x2b46\\x2b50-\\x2b59\\x2ce5-\\x2cea\\x2e80-\\x2e99" + "\\x2e9b-\\x2ef3\\x2f00-\\x2fd5\\x2ff0-\\x2ffb\\x3004\\x3012" + "\\x3013\\x3020\\x3036\\x3037\\x303e\\x303f\\x3190\\x3191" + "\\x3196-\\x319f\\x31c0-\\x31e3\\x3200-\\x321e\\x322a-\\x3250" + "\\x3260-\\x327f\\x328a-\\x32b0\\x32c0-\\x32fe\\x3300-\\x33ff" + "\\x4dc0-\\x4dff\\xa490-\\xa4c6\\xa828-\\xa82b\\xa836\\xa837" + "\\xa839\\xaa77-\\xaa79\\xfdfd\\xffe4\\xffe8\\xffed\\xffee" + "\\xfffc\\xfffd\\x10102\\x10137-\\x1013f\\x10179-\\x10189" + "\\x10190-\\x1019b\\x101d0-\\x101fc\\x1d000-\\x1d0f5" + "\\x1d100-\\x1d126\\x1d129-\\x1d164\\x1d16a-\\x1d16c\\x1d183" + "\\x1d184\\x1d18c-\\x1d1a9\\x1d1ae-\\x1d1dd\\x1d200-\\x1d241" + "\\x1d245\\x1d300-\\x1d356\\x1f000-\\x1f02b\\x1f030-\\x1f093" + "\\x1f0a0-\\x1f0ae\\x1f0b1-\\x1f0be\\x1f0c1-\\x1f0cf" + "\\x1f0d1-\\x1f0df\\x1f110-\\x1f12e\\x1f130-\\x1f169" + "\\x1f170-\\x1f19a\\x1f1e6-\\x1f202\\x1f210-\\x1f23a" + "\\x1f240-\\x1f248\\x1f250\\x1f251\\x1f300-\\x1f320" + "\\x1f330-\\x1f335\\x1f337-\\x1f37c\\x1f380-\\x1f393" + "\\x1f3a0-\\x1f3c4\\x1f3c6-\\x1f3ca\\x1f3e0-\\x1f3f0" + "\\x1f400-\\x1f43e\\x1f440\\x1f442-\\x1f4f7\\x1f4f9-\\x1f4fc" + "\\x1f500-\\x1f53d\\x1f550-\\x1f567\\x1f5fb-\\x1f5ff" + "\\x1f601-\\x1f610\\x1f612-\\x1f614\\x1f616\\x1f618\\x1f61a" + "\\x1f61c-\\x1f61e\\x1f620-\\x1f625\\x1f628-\\x1f62b\\x1f62d" + "\\x1f630-\\x1f633\\x1f635-\\x1f640\\x1f645-\\x1f64f" + "\\x1f680-\\x1f6c5\\x1f700-\\x1f773]"; + } + + static const char *separator_space() + { + return "[\\x20\\xa0\\x1680\\x180e\\x2000-\\x200a\\x202f\\x205f" + "\\x3000]"; + } + + static const char *separator_line() + { + return "[\\x2028]"; + } + + static const char *separator_paragraph() + { + return "[\\x2029]"; + } + + static const char *other_control() + { + return "[\\x0-\\x1f\\x7f-\\x9f]"; + } + + static const char *other_format() + { + return "[\\xad\\x600-\\x603\\x6dd\\x70f\\x17b4\\x17b5\\x200b-\\x200f" + "\\x202a-\\x202e\\x2060-\\x2064\\x206a-\\x206f\\xfeff" + "\\xfff9-\\xfffb\\x110bd\\x1d173-\\x1d17a\\xe0001" + "\\xe0020-\\xe007f]"; + } + + static const char *other_surrogate() + { + return "[\\xD800\\xDB7F\\xDB80\\xDBFF\\xDC00\\xDFFF]"; + } + + static const char *other_private() + { + return "[\\xE000\\xF8FF\\xF0000\\xFFFFD\\x100000\\x10FFFD]"; + } + + template + static input_char_type decode_octal(state_type &state_) + { + std::size_t oct_ = 0; + typename state_type::char_type ch_ = *state_._curr; + unsigned short count_ = 3; + bool eos_ = false; + + for (;;) + { + oct_ *= 8; + oct_ += ch_ - '0'; + --count_; + state_.increment(); + eos_ = state_.eos(); + + if (!count_ || eos_) break; + + ch_ = *state_._curr; + + // Don't consume invalid chars! + if (ch_ < '0' || ch_ > '7') + { + break; + } + } + + if (oct_ > static_cast(char_traits::max_val())) + { + std::ostringstream ss_; + + ss_ << "Escape \\" << std::oct << oct_ << + " is too big for the state machine char type " + "preceding index " << std::dec << state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + return static_cast(oct_); + } + + template + static input_char_type decode_control_char(state_type &state_) + { + // Skip over 'c' + state_.increment(); + + typename state_type::char_type ch_ = 0; + bool eos_ = state_.next(ch_); + + if (eos_) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " following \\c"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + else + { + if (ch_ >= 'a' && ch_ <= 'z') + { + ch_ -= 'a' - 1; + } + else if (ch_ >= 'A' && ch_ <= 'Z') + { + ch_ -= 'A' - 1; + } + else if (ch_ == '@') + { + // Apparently... + ch_ = 0; + } + else + { + std::ostringstream ss_; + + ss_ << "Invalid control char at index " << + state_.index() - 1; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + } + + return ch_; + } + + template + static input_char_type decode_hex(state_type &state_) + { + // Skip over 'x' + state_.increment(); + + typename state_type::char_type ch_ = 0; + bool eos_ = state_.next(ch_); + + if (eos_) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " following \\x"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + if (!((ch_ >= '0' && ch_ <= '9') || (ch_ >= 'a' && ch_ <= 'f') || + (ch_ >= 'A' && ch_ <= 'F'))) + { + std::ostringstream ss_; + + ss_ << "Illegal char following \\x at index " << + state_.index() - 1; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + std::size_t hex_ = 0; + + do + { + hex_ *= 16; + + if (ch_ >= '0' && ch_ <= '9') + { + hex_ += ch_ - '0'; + } + else if (ch_ >= 'a' && ch_ <= 'f') + { + hex_ += 10 + (ch_ - 'a'); + } + else + { + hex_ += 10 + (ch_ - 'A'); + } + + eos_ = state_.eos(); + + if (!eos_) + { + ch_ = *state_._curr; + + // Don't consume invalid chars! + if (((ch_ >= '0' && ch_ <= '9') || + (ch_ >= 'a' && ch_ <= 'f') || (ch_ >= 'A' && ch_ <= 'F'))) + { + state_.increment(); + } + else + { + eos_ = true; + } + } + } while (!eos_); + + if (hex_ > static_cast(char_traits::max_val())) + { + std::ostringstream ss_; + + ss_ << "Escape \\x" << std::hex << hex_ << + " is too big for the state machine char type " << + "preceding index " << + std::dec << state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + return static_cast(hex_); + } + + template + static void charset_range(const bool chset_, state_type &state_, + bool &eos_, typename state_type::char_type &ch_, + const input_char_type prev_, string_token &chars_) + { + if (chset_) + { + std::ostringstream ss_; + + ss_ << "Charset cannot form start of range preceding " + "index " << state_.index() - 1; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + eos_ = state_.next(ch_); + + if (eos_) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " following '-'"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + input_char_type curr_ = 0; + + if (ch_ == '\\') + { + std::size_t str_len_ = 0; + + if (escape_sequence(state_, curr_, str_len_)) + { + std::ostringstream ss_; + + ss_ << "Charset cannot form end of range preceding index " + << state_.index(); + state_.error(ss_); + throw runtime_error(ss_.str()); + } + } + else if (ch_ == '[' && !state_.eos() && *state_._curr == ':') + { + std::ostringstream ss_; + + ss_ << "POSIX char class cannot form end of range at " + "index " << state_.index() - 1; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + else + { + curr_ = ch_; + } + + eos_ = state_.next(ch_); + + // Covers preceding if and else + if (eos_) + { + std::ostringstream ss_; + + // Pointless returning index if at end of string + state_.unexpected_end(ss_); + ss_ << " (missing ']')"; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + // Use index_type as char is generally signed + // and we want to ignore signedness. + typename char_traits::index_type start_ = + static_cast(prev_); + typename char_traits::index_type end_ = + static_cast(curr_); + + // Semanic check + if (end_ < start_) + { + std::ostringstream ss_; + + ss_ << "Max less than Min in charset range preceding index " << + state_.index() - 1; + state_.error(ss_); + throw runtime_error(ss_.str()); + } + + // Even though ranges are used now, we still need to consider + // each character if icase is set. + if (state_._flags & icase) + { + typename string_token::range range_(start_, end_); + string_token folded_; + + chars_.insert(range_); + fold(range_, state_._locale, folded_, + size()); + + if (!folded_.empty()) + { + chars_.insert(folded_); + } + } + else + { + chars_.insert(typename string_token::range(prev_, curr_)); + } + } +}; +} +} + +#endif diff --git a/Puma/extern/lexertl/parser/tokeniser/re_tokeniser_state.hpp b/Puma/extern/lexertl/parser/tokeniser/re_tokeniser_state.hpp new file mode 100644 index 0000000..8434ef1 --- /dev/null +++ b/Puma/extern/lexertl/parser/tokeniser/re_tokeniser_state.hpp @@ -0,0 +1,137 @@ +// tokeniser_state.hpp +// Copyright (c) 2005-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_RE_TOKENISER_STATE_HPP +#define LEXERTL_RE_TOKENISER_STATE_HPP + +#include "../../char_traits.hpp" +#include "../../enums.hpp" +#include +#include "../../narrow.hpp" +#include "../../size_t.hpp" +#include + +namespace lexertl +{ +namespace detail +{ +template +struct basic_re_tokeniser_state +{ + typedef ch_type char_type; + typedef typename basic_char_traits::index_type index_type; + + const char_type * const _start; + const char_type * const _end; + const char_type *_curr; + id_type _id; + std::size_t _flags; + std::stack _flags_stack; + std::locale _locale; + const char_type *_macro_name; + long _paren_count; + bool _in_string; + id_type _nl_id; + + basic_re_tokeniser_state(const char_type *start_, + const char_type * const end_, id_type id_, const std::size_t flags_, + const std::locale locale_, const char_type *macro_name_) : + _start(start_), + _end(end_), + _curr(start_), + _id(id_), + _flags(flags_), + _flags_stack(), + _locale(locale_), + _macro_name(macro_name_), + _paren_count(0), + _in_string(false), + _nl_id(~static_cast(0)) + { + } + + basic_re_tokeniser_state(const basic_re_tokeniser_state &rhs_) + { + assign(rhs_); + } + + // prevent VC++ 7.1 warning: + const basic_re_tokeniser_state &operator = + (const basic_re_tokeniser_state &rhs_) + { + assign(rhs_); + } + + void assign(const basic_re_tokeniser_state &rhs_) + { + _start = rhs_._start; + _end = rhs_._end; + _curr = rhs_._curr; + _id = rhs_._id; + _flags = rhs_._flags; + _flags_stack = rhs_._flags_stack; + _locale = rhs_._locale; + _macro_name = rhs_._macro_name; + _paren_count = rhs_._paren_count; + _in_string = rhs_._in_string; + _nl_id = rhs_._nl_id; + return this; + } + + inline bool next(char_type &ch_) + { + if (_curr >= _end) + { + ch_ = 0; + return true; + } + else + { + ch_ = *_curr; + increment(); + return false; + } + } + + inline void increment() + { + ++_curr; + } + + inline std::size_t index() + { + return _curr - _start; + } + + inline bool eos() + { + return _curr >= _end; + } + + inline void unexpected_end(std::ostringstream &ss_) + { + ss_ << "Unexpected end of regex"; + } + + inline void error(std::ostringstream &ss_) + { + ss_ << " in "; + + if (_macro_name) + { + ss_ << "MACRO '"; + narrow(_macro_name, ss_); + ss_ << "'."; + } + else + { + ss_ << "rule id " << _id << '.'; + } + } +}; +} +} + +#endif diff --git a/Puma/extern/lexertl/parser/tree/end_node.hpp b/Puma/extern/lexertl/parser/tree/end_node.hpp new file mode 100644 index 0000000..2379d8c --- /dev/null +++ b/Puma/extern/lexertl/parser/tree/end_node.hpp @@ -0,0 +1,112 @@ +// end_node.hpp +// Copyright (c) 2005-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_END_NODE_HPP +#define LEXERTL_END_NODE_HPP + +#include "node.hpp" +#include "../../size_t.hpp" + +namespace lexertl +{ +namespace detail +{ +template +class basic_end_node : public basic_node +{ +public: + typedef basic_node node; + typedef typename node::bool_stack bool_stack; + typedef typename node::const_node_stack const_node_stack; + typedef typename node::node_ptr_vector node_ptr_vector; + typedef typename node::node_stack node_stack; + typedef typename node::node_type node_type; + typedef typename node::node_vector node_vector; + + basic_end_node(const id_type id_, const id_type user_id_, + const id_type next_dfa_, const id_type push_dfa_, + const bool pop_dfa_) : + node(false), + _id(id_), + _user_id(user_id_), + _next_dfa(next_dfa_), + _push_dfa(push_dfa_), + _pop_dfa(pop_dfa_), + _followpos() + { + node::_firstpos.push_back(this); + node::_lastpos.push_back(this); + } + + virtual ~basic_end_node() + { + } + + virtual node_type what_type() const + { + return node::END; + } + + virtual bool traverse(const_node_stack &/*node_stack_*/, + bool_stack &/*perform_op_stack_*/) const + { + return false; + } + + virtual const node_vector &followpos() const + { + // _followpos is always empty..! + return _followpos; + } + + virtual bool end_state() const + { + return true; + } + + virtual id_type id() const + { + return _id; + } + + virtual id_type user_id() const + { + return _user_id; + } + + virtual id_type next_dfa() const + { + return _next_dfa; + } + + virtual id_type push_dfa() const + { + return _push_dfa; + } + + virtual bool pop_dfa() const + { + return _pop_dfa; + } + +private: + id_type _id; + id_type _user_id; + id_type _next_dfa; + id_type _push_dfa; + bool _pop_dfa; + node_vector _followpos; + + virtual void copy_node(node_ptr_vector &/*node_ptr_vector_*/, + node_stack &/*new_node_stack_*/, bool_stack &/*perform_op_stack_*/, + bool &/*down_*/) const + { + // Nothing to do, as end_nodes are not copied. + } +}; +} +} + +#endif diff --git a/Puma/extern/lexertl/parser/tree/iteration_node.hpp b/Puma/extern/lexertl/parser/tree/iteration_node.hpp new file mode 100644 index 0000000..c9a919e --- /dev/null +++ b/Puma/extern/lexertl/parser/tree/iteration_node.hpp @@ -0,0 +1,103 @@ +// iteration_node.hpp +// Copyright (c) 2005-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_ITERATION_NODE_HPP +#define LEXERTL_ITERATION_NODE_HPP + +#include "node.hpp" + +namespace lexertl +{ +namespace detail +{ +template +class basic_iteration_node : public basic_node +{ +public: + typedef basic_node node; + typedef typename node::bool_stack bool_stack; + typedef typename node::const_node_stack const_node_stack; + typedef typename node::node_ptr_vector node_ptr_vector; + typedef typename node::node_stack node_stack; + typedef typename node::node_type node_type; + typedef typename node::node_vector node_vector; + + basic_iteration_node(node *next_, const bool greedy_) : + node(true), + _next(next_), + _greedy(greedy_) + { + typename node_vector::iterator iter_; + typename node_vector::iterator end_; + + _next->append_firstpos(node::_firstpos); + _next->append_lastpos(node::_lastpos); + + for (iter_ = node::_lastpos.begin(), end_ = node::_lastpos.end(); + iter_ != end_; ++iter_) + { + (*iter_)->append_followpos(node::_firstpos); + } + + for (iter_ = node::_firstpos.begin(), end_ = node::_firstpos.end(); + iter_ != end_; ++iter_) + { + (*iter_)->greedy(greedy_); + } + } + + virtual ~basic_iteration_node() + { + } + + virtual node_type what_type() const + { + return node::ITERATION; + } + + virtual bool traverse(const_node_stack &node_stack_, + bool_stack &perform_op_stack_) const + { + perform_op_stack_.push(true); + node_stack_.push(_next); + return true; + } + +private: + // Not owner of this pointer... + node *_next; + bool _greedy; + + virtual void copy_node(node_ptr_vector &node_ptr_vector_, + node_stack &new_node_stack_, bool_stack &perform_op_stack_, + bool &down_) const + { + if (perform_op_stack_.top()) + { + node *ptr_ = new_node_stack_.top(); + + node_ptr_vector_->push_back + (static_cast *>(0)); + node_ptr_vector_->back() = new basic_iteration_node + (ptr_, _greedy); + new_node_stack_.top() = node_ptr_vector_->back(); + } + else + { + down_ = true; + } + + perform_op_stack_.pop(); + } + + // No copy construction. + basic_iteration_node(const basic_iteration_node &); + // No assignment. + const basic_iteration_node &operator =(const basic_iteration_node &); +}; +} +} + +#endif diff --git a/Puma/extern/lexertl/parser/tree/leaf_node.hpp b/Puma/extern/lexertl/parser/tree/leaf_node.hpp new file mode 100644 index 0000000..d7e8569 --- /dev/null +++ b/Puma/extern/lexertl/parser/tree/leaf_node.hpp @@ -0,0 +1,114 @@ +// leaf_node.hpp +// Copyright (c) 2005-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_LEAF_NODE_HPP +#define LEXERTL_LEAF_NODE_HPP + +#include "../../enums.hpp" // null_token +#include "node.hpp" +#include "../../size_t.hpp" + +namespace lexertl +{ +namespace detail +{ +template +class basic_leaf_node : public basic_node +{ +public: + typedef basic_node node; + typedef typename node::bool_stack bool_stack; + typedef typename node::const_node_stack const_node_stack; + typedef typename node::node_ptr_vector node_ptr_vector; + typedef typename node::node_stack node_stack; + typedef typename node::node_type node_type; + typedef typename node::node_vector node_vector; + + basic_leaf_node(const id_type token_, const bool greedy_) : + node(token_ == node::null_token()), + _token(token_), + _set_greedy(!greedy_), + _greedy(greedy_), + _followpos() + { + if (!node::_nullable) + { + node::_firstpos.push_back(this); + node::_lastpos.push_back(this); + } + } + + virtual ~basic_leaf_node() + { + } + + virtual void append_followpos(const node_vector &followpos_) + { + for (typename node_vector::const_iterator iter_ = followpos_.begin(), + end_ = followpos_.end(); iter_ != end_; ++iter_) + { + _followpos.push_back(*iter_); + } + } + + virtual node_type what_type() const + { + return node::LEAF; + } + + virtual bool traverse(const_node_stack &/*node_stack_*/, + bool_stack &/*perform_op_stack_*/) const + { + return false; + } + + virtual id_type token() const + { + return _token; + } + + virtual void greedy(const bool greedy_) + { + if (!_set_greedy) + { + _greedy = greedy_; + _set_greedy = true; + } + } + + virtual bool greedy() const + { + return _greedy; + } + + virtual const node_vector &followpos() const + { + return _followpos; + } + + virtual node_vector &followpos() + { + return _followpos; + } + +private: + id_type _token; + bool _set_greedy; + bool _greedy; + node_vector _followpos; + + virtual void copy_node(node_ptr_vector &node_ptr_vector_, + node_stack &new_node_stack_, bool_stack &/*perform_op_stack_*/, + bool &/*down_*/) const + { + node_ptr_vector_->push_back(static_cast(0)); + node_ptr_vector_->back() = new basic_leaf_node(_token, _greedy); + new_node_stack_.push(node_ptr_vector_->back()); + } +}; +} +} + +#endif diff --git a/Puma/extern/lexertl/parser/tree/node.hpp b/Puma/extern/lexertl/parser/tree/node.hpp new file mode 100644 index 0000000..613de95 --- /dev/null +++ b/Puma/extern/lexertl/parser/tree/node.hpp @@ -0,0 +1,241 @@ +// node.hpp +// Copyright (c) 2005-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_NODE_HPP +#define LEXERTL_NODE_HPP + +#include +#include "../../containers/ptr_vector.hpp" +#include "../../runtime_error.hpp" +#include "../../size_t.hpp" +#include +#include + +namespace lexertl +{ +namespace detail +{ +template +class basic_node +{ +public: + enum node_type {LEAF, SEQUENCE, SELECTION, ITERATION, END}; + + typedef std::stack bool_stack; + typedef std::stack node_stack; + // stack and vector not owner of node pointers + typedef std::stack const_node_stack; + typedef std::vector node_vector; + typedef ptr_vector node_ptr_vector; + + basic_node() : + _nullable(false), + _firstpos(), + _lastpos() + { + } + + basic_node(const bool nullable_) : + _nullable(nullable_), + _firstpos(), + _lastpos() + { + } + + virtual ~basic_node() + { + } + + static id_type null_token() + { + return ~static_cast(0); + } + + bool nullable() const + { + return _nullable; + } + + void append_firstpos(node_vector &firstpos_) const + { + firstpos_.insert(firstpos_.end(), + _firstpos.begin(), _firstpos.end()); + } + + void append_lastpos(node_vector &lastpos_) const + { + lastpos_.insert(lastpos_.end(), + _lastpos.begin(), _lastpos.end()); + } + + virtual void append_followpos(const node_vector &/*followpos_*/) + { + throw runtime_error("Internal error node::append_followpos()."); + } + + basic_node *copy(node_ptr_vector &node_ptr_vector_) const + { + basic_node *new_root_ = 0; + const_node_stack node_stack_; + bool_stack perform_op_stack_; + bool down_ = true; + node_stack new_node_stack_; + + node_stack_.push(this); + + while (!node_stack_.empty()) + { + while (down_) + { + down_ = node_stack_.top()->traverse(node_stack_, + perform_op_stack_); + } + + while (!down_ && !node_stack_.empty()) + { + const basic_node *top_ = node_stack_.top(); + + top_->copy_node(node_ptr_vector_, new_node_stack_, + perform_op_stack_, down_); + + if (!down_) node_stack_.pop(); + } + } + + assert(new_node_stack_.size() == 1); + new_root_ = new_node_stack_.top(); + new_node_stack_.pop(); + return new_root_; + } + + virtual node_type what_type() const = 0; + + virtual bool traverse(const_node_stack &node_stack_, + bool_stack &perform_op_stack_) const = 0; + + node_vector &firstpos() + { + return _firstpos; + } + + const node_vector &firstpos() const + { + return _firstpos; + } + + // _lastpos modified externally, so not const & + node_vector &lastpos() + { + return _lastpos; + } + + virtual bool end_state() const + { + return false; + } + + virtual id_type id() const + { + throw runtime_error("Internal error node::id()."); +#ifdef __SUNPRO_CC + // Stop bogus Solaris compiler warning + return id_type(); +#endif + } + + virtual id_type user_id() const + { + throw runtime_error("Internal error node::user_id()."); +#ifdef __SUNPRO_CC + // Stop bogus Solaris compiler warning + return id_type(); +#endif + } + + virtual id_type next_dfa() const + { + throw runtime_error("Internal error node::next_dfa()."); +#ifdef __SUNPRO_CC + // Stop bogus Solaris compiler warning + return id_type(); +#endif + } + + virtual id_type push_dfa() const + { + throw runtime_error("Internal error node::push_dfa()."); +#ifdef __SUNPRO_CC + // Stop bogus Solaris compiler warning + return id_type(); +#endif + } + + virtual bool pop_dfa() const + { + throw runtime_error("Internal error node::pop_dfa()."); +#ifdef __SUNPRO_CC + // Stop bogus Solaris compiler warning + return false; +#endif + } + + virtual id_type token() const + { + throw runtime_error("Internal error node::token()."); +#ifdef __SUNPRO_CC + // Stop bogus Solaris compiler warning + return id_type(); +#endif + } + + virtual void greedy(const bool /*greedy_*/) + { + throw runtime_error("Internal error node::greedy(bool)."); + } + + virtual bool greedy() const + { + throw runtime_error("Internal error node::greedy()."); +#ifdef __SUNPRO_CC + // Stop bogus Solaris compiler warning + return false; +#endif + } + + virtual const node_vector &followpos() const + { + throw runtime_error("Internal error node::followpos()."); +#ifdef __SUNPRO_CC + // Stop bogus Solaris compiler warning + return firstpos; +#endif + } + + virtual node_vector &followpos() + { + throw runtime_error("Internal error node::followpos()."); +#ifdef __SUNPRO_CC + // Stop bogus Solaris compiler warning + return firstpos; +#endif + } + +protected: + const bool _nullable; + node_vector _firstpos; + node_vector _lastpos; + + virtual void copy_node(node_ptr_vector &node_ptr_vector_, + node_stack &new_node_stack_, bool_stack &perform_op_stack_, + bool &down_) const = 0; + +private: + basic_node(const basic_node &); // No copy construction. + const basic_node &operator =(const basic_node &); // No assignment. +}; +} +} + +#endif diff --git a/Puma/extern/lexertl/parser/tree/selection_node.hpp b/Puma/extern/lexertl/parser/tree/selection_node.hpp new file mode 100644 index 0000000..a5c0a80 --- /dev/null +++ b/Puma/extern/lexertl/parser/tree/selection_node.hpp @@ -0,0 +1,105 @@ +// selection_node.hpp +// Copyright (c) 2005-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_SELECTION_NODE_HPP +#define LEXERTL_SELECTION_NODE_HPP + +#include "node.hpp" + +namespace lexertl +{ +namespace detail +{ +template +class basic_selection_node : public basic_node +{ +public: + typedef basic_node node; + typedef typename node::bool_stack bool_stack; + typedef typename node::const_node_stack const_node_stack; + typedef typename node::node_ptr_vector node_ptr_vector; + typedef typename node::node_stack node_stack; + typedef typename node::node_type node_type; + + basic_selection_node(node *left_, node *right_) : + node(left_->nullable() || right_->nullable()), + _left(left_), + _right(right_) + { + _left->append_firstpos(node::_firstpos); + _right->append_firstpos(node::_firstpos); + _left->append_lastpos(node::_lastpos); + _right->append_lastpos(node::_lastpos); + } + + virtual ~basic_selection_node() + { + } + + virtual node_type what_type() const + { + return node::SELECTION; + } + + virtual bool traverse(const_node_stack &node_stack_, + bool_stack &perform_op_stack_) const + { + perform_op_stack_.push(true); + + switch (_right->what_type()) + { + case node::SEQUENCE: + case node::SELECTION: + case node::ITERATION: + perform_op_stack_.push(false); + break; + default: + break; + } + + node_stack_.push(_right); + node_stack_.push(_left); + return true; + } + +private: + // Not owner of these pointers... + node *_left; + node *_right; + + virtual void copy_node(node_ptr_vector &node_ptr_vector_, + node_stack &new_node_stack_, bool_stack &perform_op_stack_, + bool &down_) const + { + if (perform_op_stack_.top()) + { + node *rhs_ = new_node_stack_.top(); + + new_node_stack_.pop(); + + node *lhs_ = new_node_stack_.top(); + + node_ptr_vector_->push_back + (static_cast(0)); + node_ptr_vector_->back() = new basic_selection_node(lhs_, rhs_); + new_node_stack_.top() = node_ptr_vector_->back(); + } + else + { + down_ = true; + } + + perform_op_stack_.pop(); + } + + // No copy construction. + basic_selection_node(const basic_selection_node &); + // No assignment. + const basic_selection_node &operator =(const basic_selection_node &); +}; +} +} + +#endif diff --git a/Puma/extern/lexertl/parser/tree/sequence_node.hpp b/Puma/extern/lexertl/parser/tree/sequence_node.hpp new file mode 100644 index 0000000..53b3133 --- /dev/null +++ b/Puma/extern/lexertl/parser/tree/sequence_node.hpp @@ -0,0 +1,126 @@ +// sequence_node.hpp +// Copyright (c) 2005-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_SEQUENCE_NODE_HPP +#define LEXERTL_SEQUENCE_NODE_HPP + +#include "node.hpp" + +namespace lexertl +{ +namespace detail +{ +template +class basic_sequence_node : public basic_node +{ +public: + typedef basic_node node; + typedef typename node::bool_stack bool_stack; + typedef typename node::const_node_stack const_node_stack; + typedef typename node::node_ptr_vector node_ptr_vector; + typedef typename node::node_stack node_stack; + typedef typename node::node_type node_type; + typedef typename node::node_vector node_vector; + + basic_sequence_node(node *left_, + node *right_) : + node(left_->nullable() && right_->nullable()), + _left(left_), + _right(right_) + { + _left->append_firstpos(node::_firstpos); + + if (_left->nullable()) + { + _right->append_firstpos(node::_firstpos); + } + + if (_right->nullable()) + { + _left->append_lastpos(node::_lastpos); + } + + _right->append_lastpos(node::_lastpos); + + node_vector &lastpos_ = _left->lastpos(); + const node_vector &firstpos_ = _right->firstpos(); + + for (typename node_vector::iterator iter_ = lastpos_.begin(), + end_ = lastpos_.end(); iter_ != end_; ++iter_) + { + (*iter_)->append_followpos(firstpos_); + } + } + + virtual ~basic_sequence_node() + { + } + + virtual node_type what_type() const + { + return node::SEQUENCE; + } + + virtual bool traverse(const_node_stack &node_stack_, + bool_stack &perform_op_stack_) const + { + perform_op_stack_.push(true); + + switch (_right->what_type()) + { + case node::SEQUENCE: + case node::SELECTION: + case node::ITERATION: + perform_op_stack_.push(false); + break; + default: + break; + } + + node_stack_.push(_right); + node_stack_.push(_left); + return true; + } + +private: + // Not owner of these pointers... + node *_left; + node *_right; + + virtual void copy_node(node_ptr_vector &node_ptr_vector_, + node_stack &new_node_stack_, bool_stack &perform_op_stack_, + bool &down_) const + { + if (perform_op_stack_.top()) + { + node *rhs_ = new_node_stack_.top(); + + new_node_stack_.pop(); + + node *lhs_ = new_node_stack_.top(); + + node_ptr_vector_->push_back + (static_cast *>(0)); + node_ptr_vector_->back() = new basic_sequence_node + (lhs_, rhs_); + new_node_stack_.top() = node_ptr_vector_->back(); + } + else + { + down_ = true; + } + + perform_op_stack_.pop(); + } + + // No copy construction. + basic_sequence_node(const basic_sequence_node &); + // No assignment. + const basic_sequence_node &operator =(const basic_sequence_node &); +}; +} +} + +#endif diff --git a/Puma/extern/lexertl/partition/charset.hpp b/Puma/extern/lexertl/partition/charset.hpp new file mode 100644 index 0000000..02f2402 --- /dev/null +++ b/Puma/extern/lexertl/partition/charset.hpp @@ -0,0 +1,73 @@ +// charset.hpp +// Copyright (c) 2005-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef LEXERTL_CHARSET_HPP +#define LEXERTL_CHARSET_HPP + +#include +#include +#include +#include "../size_t.hpp" +#include "../string_token.hpp" + +namespace lexertl +{ +namespace detail +{ +template +struct basic_charset +{ + typedef basic_string_token token; + typedef std::set index_set; + + token _token; + index_set _index_set; + + basic_charset() : + _token(), + _index_set() + { + } + + basic_charset(const token &token_, const std::size_t index_) : + _token(token_), + _index_set() + { + _index_set.insert(index_); + } + + bool empty() const + { + return _token.empty() && _index_set.empty(); + } + + void intersect(basic_charset &rhs_, basic_charset &overlap_) + { + _token.intersect(rhs_._token, overlap_._token); + + if (!overlap_._token.empty()) + { + std::merge(_index_set.begin(), _index_set.end(), + rhs_._index_set.begin(), rhs_._index_set.end(), + std::inserter(overlap_._index_set, + overlap_._index_set.end())); + + if (_token.empty()) + { + _index_set.clear(); + } + + if (rhs_._token.empty()) + { + rhs_._index_set.clear(); + } + } + } +}; +} +} + +#endif diff --git a/Puma/extern/lexertl/partition/equivset.hpp b/Puma/extern/lexertl/partition/equivset.hpp new file mode 100644 index 0000000..3f98284 --- /dev/null +++ b/Puma/extern/lexertl/partition/equivset.hpp @@ -0,0 +1,134 @@ +// equivset.hpp +// Copyright (c) 2005-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_EQUIVSET_HPP +#define LEXERTL_EQUIVSET_HPP + +#include +#include "../parser/tree/node.hpp" +#include + +namespace lexertl +{ +namespace detail +{ +template +struct basic_equivset +{ + typedef std::set index_set; + typedef std::vector index_vector; + // Not owner of nodes: + typedef basic_node node; + typedef std::vector node_vector; + + index_vector _index_vector; + id_type _id; + bool _greedy; + node_vector _followpos; + + basic_equivset() : + _index_vector(), + _id(0), + _greedy(true), + _followpos() + { + } + + basic_equivset(const index_set &index_set_, const id_type id_, + const bool greedy_, const node_vector &followpos_) : + _index_vector(index_set_.begin(), index_set_.end()), + _id(id_), + _greedy(greedy_), + _followpos(followpos_) + { + } + + bool empty() const + { + return _index_vector.empty() && _followpos.empty(); + } + + void intersect(basic_equivset &rhs_, basic_equivset &overlap_) + { + intersect_indexes(rhs_._index_vector, overlap_._index_vector); + + if (!overlap_._index_vector.empty()) + { + // Note that the LHS takes priority in order to + // respect rule ordering priority in the lex spec. + overlap_._id = _id; + overlap_._greedy = _greedy; + overlap_._followpos = _followpos; + + typename node_vector::const_iterator overlap_begin_ = + overlap_._followpos.begin(); + typename node_vector::const_iterator overlap_end_ = + overlap_._followpos.end(); + typename node_vector::const_iterator rhs_iter_ = + rhs_._followpos.begin(); + typename node_vector::const_iterator rhs_end_ = + rhs_._followpos.end(); + + for (; rhs_iter_ != rhs_end_; ++rhs_iter_) + { + node *node_ = *rhs_iter_; + + if (std::find(overlap_begin_, overlap_end_, node_) == + overlap_end_) + { + overlap_._followpos.push_back(node_); + overlap_begin_ = overlap_._followpos.begin(); + overlap_end_ = overlap_._followpos.end(); + } + } + + if (_index_vector.empty()) + { + _followpos.clear(); + } + + if (rhs_._index_vector.empty()) + { + rhs_._followpos.clear(); + } + } + } + +private: + void intersect_indexes(index_vector &rhs_, index_vector &overlap_) + { + typename index_vector::iterator iter_ = _index_vector.begin(); + typename index_vector::iterator end_ = _index_vector.end(); + typename index_vector::iterator rhs_iter_ = rhs_.begin(); + typename index_vector::iterator rhs_end_ = rhs_.end(); + + while (iter_ != end_ && rhs_iter_ != rhs_end_) + { + const id_type index_ = *iter_; + const id_type rhs_index_ = *rhs_iter_; + + if (index_ < rhs_index_) + { + ++iter_; + } + else if (index_ > rhs_index_) + { + ++rhs_iter_; + } + else + { + overlap_.push_back(index_); + iter_ = _index_vector.erase(iter_); + end_ = _index_vector.end(); + rhs_iter_ = rhs_.erase(rhs_iter_); + rhs_end_ = rhs_.end(); + } + } + } +}; +} +} + +#endif diff --git a/Puma/extern/lexertl/rules.hpp b/Puma/extern/lexertl/rules.hpp new file mode 100644 index 0000000..7f37ddb --- /dev/null +++ b/Puma/extern/lexertl/rules.hpp @@ -0,0 +1,1031 @@ +// rules.hpp +// Copyright (c) 2005-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_RULES_HPP +#define LEXERTL_RULES_HPP + +#include "compile_assert.hpp" +#include +#include "enums.hpp" +#include +#include +#include "narrow.hpp" +#include "parser/tokeniser/re_tokeniser.hpp" +#include "runtime_error.hpp" +#include +#include "size_t.hpp" +#include +#include +#include + +namespace lexertl +{ +template +class basic_rules +{ +public: + typedef std::vector bool_vector; + typedef std::deque bool_vector_deque; + typedef ch_type char_type; + typedef r_ch_type rules_char_type; + typedef id_ty id_type; + typedef std::vector id_vector; + typedef std::deque id_vector_deque; + typedef detail::basic_re_tokeniser_state re_state; + typedef std::basic_string string; + typedef basic_string_token string_token; + typedef std::deque string_deque; + typedef std::set string_set; + typedef std::pair string_pair; + typedef std::map string_id_type_map; + typedef std::pair string_id_type_pair; + typedef detail::basic_re_token token; + typedef std::deque token_deque; + typedef std::deque token_deque_deque; + typedef std::deque token_deque_deque_deque; + typedef std::map macro_map; + typedef std::pair macro_pair; + typedef detail::basic_re_tokeniser + tokeniser; + + // If you get a compile error here you have + // failed to define an unsigned id type. + compile_assert <(~static_cast(0) > 0)> _valid_id_type; + + basic_rules(const std::size_t flags_ = dot_not_newline) : + _valid_id_type(), + _statemap(), + _macro_map(), + _regexes(), + _features(), + _ids(), + _user_ids(), + _next_dfas(), + _pushes(), + _pops(), + _flags(flags_), + _locale(), + _lexer_state_names() + { + push_state(initial()); + } + + void clear() + { + _statemap.clear(); + _macro_map.clear(); + _regexes.clear(); + _features.clear(); + _ids.clear(); + _user_ids.clear(); + _next_dfas.clear(); + _pushes.clear(); + _pops.clear(); + _flags = dot_not_newline; + _locale = std::locale(); + _lexer_state_names.clear(); + push_state(initial()); + } + + void clear(const id_type dfa_) + { + if (_regexes.size() > dfa_) + { + _regexes[dfa_].clear(); + _features[dfa_] = 0; + _ids[dfa_].clear(); + _user_ids[dfa_].clear(); + _next_dfas[dfa_].clear(); + _pushes[dfa_].clear(); + _pops[dfa_].clear(); + } + } + + void flags(const std::size_t flags_) + { + _flags = flags_; + } + + std::size_t flags() const + { + return _flags; + } + + static id_type skip() + { + return ~static_cast(1); + } + + id_type eoi() const + { + return 0; + } + + static id_type npos() + { + return ~static_cast(0); + } + + std::locale imbue(const std::locale &locale_) + { + std::locale loc_ = _locale; + + _locale = locale_; + return loc_; + } + + const std::locale &locale() const + { + return _locale; + } + + const rules_char_type *state(const id_type index_) const + { + if (index_ == 0) + { + return initial(); + } + else + { + const id_type i_ = index_ - 1; + + if (_lexer_state_names.size() > i_) + { + return _lexer_state_names[i_].c_str(); + } + else + { + return 0; + } + } + } + + id_type state(const rules_char_type *name_) const + { + typename string_id_type_map::const_iterator iter_ = + _statemap.find(name_); + + if (iter_ == _statemap.end()) + { + return npos(); + } + else + { + return iter_->second; + } + } + + id_type push_state(const rules_char_type *name_) + { + validate(name_); + + if (_statemap.insert(string_id_type_pair(name_, + _statemap.size())).second) + { + _regexes.push_back(token_deque_deque()); + _features.push_back(0); + _ids.push_back(id_vector()); + _user_ids.push_back(id_vector()); + _next_dfas.push_back(id_vector()); + _pushes.push_back(id_vector()); + _pops.push_back(bool_vector()); + + if (string(name_) != initial()) + { + _lexer_state_names.push_back(name_); + } + } + else + { + return _statemap.find(name_)->second; + } + + if (_next_dfas.size() > npos()) + { + // Overflow + throw runtime_error("The data type you have chosen cannot hold " + "this many lexer start states."); + } + + // Initial is not stored, so no need to - 1. + return static_cast(_lexer_state_names.size()); + } + + void insert_macro(const rules_char_type *name_, + const rules_char_type *regex_) + { + insert_macro(name_, string(regex_)); + } + + void insert_macro(const rules_char_type *name_, + const rules_char_type *regex_start_, + const rules_char_type *regex_end_) + { + insert_macro(name_, string(regex_start_, regex_end_)); + } + + void insert_macro(const rules_char_type *name_, const string ®ex_) + { + validate(name_); + + typename macro_map::const_iterator iter_ = _macro_map.find(name_); + + if (iter_ == _macro_map.end()) + { + std::pair pair_ = + _macro_map.insert(macro_pair(name_, token_deque())); + + tokenise(regex_, pair_.first->second, npos(), name_); + } + else + { + std::ostringstream ss_; + + ss_ << "Attempt to redefine MACRO '"; + narrow(name_, ss_); + ss_ << "'."; + throw runtime_error(ss_.str()); + } + } + + // Add rule to INITIAL + void push(const rules_char_type *regex_, const id_type id_, + const id_type user_id_ = npos()) + { + push(string(regex_), id_, user_id_); + } + + void push(const rules_char_type *regex_start_, + const rules_char_type *regex_end_, + const id_type id_, const id_type user_id_ = npos()) + { + push(string(regex_start_, regex_end_), id_, user_id_); + } + + void push(const string ®ex_, const id_type id_, + const id_type user_id_ = npos()) + { + check_for_invalid_id(id_); + _regexes.front().push_back(token_deque()); + tokenise(regex_, _regexes.front().back(), id_, 0); + + if (regex_[0] == '^') + { + _features.front() |= bol_bit; + } + + if (regex_.size() > 0 && regex_[regex_.size() - 1] == '$') + { + _features.front() |= eol_bit; + } + + if (id_ == skip()) + { + _features.front() |= skip_bit; + } + else if (id_ == eoi()) + { + _features.front() |= again_bit; + } + + _ids.front().push_back(id_); + _user_ids.front().push_back(user_id_); + _next_dfas.front().push_back(0); + _pushes.front().push_back(npos()); + _pops.front().push_back(false); + } + + // Add rule with no id + void push(const rules_char_type *curr_dfa_, + const rules_char_type *regex_, const rules_char_type *new_dfa_) + { + push(curr_dfa_, string(regex_), new_dfa_); + } + + void push(const rules_char_type *curr_dfa_, + const rules_char_type *regex_start_, const rules_char_type *regex_end_, + const rules_char_type *new_dfa_) + { + push(curr_dfa_, string(regex_start_, regex_end_), new_dfa_); + } + + void push(const rules_char_type *curr_dfa_, const string ®ex_, + const rules_char_type *new_dfa_) + { + push(curr_dfa_, regex_, eoi(), new_dfa_, false); + } + + // Add rule with id + void push(const rules_char_type *curr_dfa_, + const rules_char_type *regex_, const id_type id_, + const rules_char_type *new_dfa_, const id_type user_id_ = npos()) + { + push(curr_dfa_, string(regex_), id_, new_dfa_, user_id_); + } + + void push(const rules_char_type *curr_dfa_, + const rules_char_type *regex_start_, + const rules_char_type *regex_end_, const id_type id_, + const rules_char_type *new_dfa_, const id_type user_id_ = npos()) + { + push(curr_dfa_, string(regex_start_, regex_end_), + id_, new_dfa_, user_id_); + } + + void push(const rules_char_type *curr_dfa_, const string ®ex_, + const id_type id_, const rules_char_type *new_dfa_, + const id_type user_id_ = npos()) + { + push(curr_dfa_, regex_, id_, new_dfa_, true, user_id_); + } + + void reverse() + { + typename token_deque_deque_deque::iterator state_iter_ = + _regexes.begin(); + typename token_deque_deque_deque::iterator state_end_ = + _regexes.end(); + typename macro_map::iterator macro_iter_ = _macro_map.begin(); + typename macro_map::iterator macro_end_ = _macro_map.end(); + + for (; state_iter_ != state_end_; ++state_iter_) + { + typename token_deque_deque::iterator regex_iter_ = + state_iter_->begin(); + typename token_deque_deque::iterator regex_end_ = + state_iter_->end(); + + for (; regex_iter_ != regex_end_; ++regex_iter_) + { + reverse(*regex_iter_); + } + } + + for (; macro_iter_ != macro_end_; ++macro_iter_) + { + reverse(macro_iter_->second); + } + } + + const string_id_type_map &statemap() const + { + return _statemap; + } + + const token_deque_deque_deque ®exes() const + { + return _regexes; + } + + const id_vector &features() const + { + return _features; + } + + const id_vector_deque &ids() const + { + return _ids; + } + + const id_vector_deque &user_ids() const + { + return _user_ids; + } + + const id_vector_deque &next_dfas() const + { + return _next_dfas; + } + + const id_vector_deque &pushes() const + { + return _pushes; + } + + const bool_vector_deque &pops() const + { + return _pops; + } + + bool empty() const + { + typename token_deque_deque_deque::const_iterator iter_ = + _regexes.begin(); + typename token_deque_deque_deque::const_iterator end_ = + _regexes.end(); + bool empty_ = true; + + for (; iter_ != end_; ++iter_) + { + if (!iter_->empty()) + { + empty_ = false; + break; + } + } + + return empty_; + } + + static const rules_char_type *initial() + { + static const rules_char_type initial_ [] = + { 'I', 'N', 'I', 'T', 'I', 'A', 'L', 0 }; + + return initial_; + } + + static const rules_char_type *dot() + { + static const rules_char_type dot_ [] = { '.', 0 }; + + return dot_; + } + + static const rules_char_type *all_states() + { + static const rules_char_type star_ [] = { '*', 0 }; + + return star_; + } + +private: + string_id_type_map _statemap; + macro_map _macro_map; + token_deque_deque_deque _regexes; + id_vector _features; + id_vector_deque _ids; + id_vector_deque _user_ids; + id_vector_deque _next_dfas; + id_vector_deque _pushes; + bool_vector_deque _pops; + std::size_t _flags; + std::locale _locale; + string_deque _lexer_state_names; + + void tokenise(const string ®ex_, token_deque &tokens_, + const id_type id_, const rules_char_type *name_) + { + re_state state_(regex_.c_str(), regex_.c_str() + regex_.size(), id_, + _flags, _locale, name_); + string macro_; + rules_char_type diff_ = 0; + + tokens_.push_back(token()); + + do + { + token *lhs_ = &tokens_.back(); + token rhs_; + + tokeniser::next(*lhs_, state_, rhs_); + + if (rhs_._type != detail::DIFF && + lhs_->precedence(rhs_._type) == ' ') + { + std::ostringstream ss_; + + ss_ << "A syntax error occurred: '" << + lhs_->precedence_string() << + "' against '" << rhs_.precedence_string() << + "' preceding index " << state_.index() << + " in "; + + if (name_ != 0) + { + ss_ << "macro "; + narrow(name_, ss_); + } + else + { + ss_ << "rule id " << state_._id; + } + + ss_ << '.'; + throw runtime_error(ss_.str()); + } + + if (rhs_._type == detail::MACRO) + { + typename macro_map::const_iterator iter_ = + _macro_map.find(rhs_._extra); + + macro_ = rhs_._extra; + + if (iter_ == _macro_map.end()) + { + const rules_char_type *name_ = rhs_._extra.c_str(); + std::ostringstream ss_; + + ss_ << "Unknown MACRO name '"; + narrow(name_, ss_); + ss_ << "'."; + throw runtime_error(ss_.str()); + } + else + { + const bool multiple_ = iter_->second.size() > 3; + + if (diff_) + { + if (multiple_) + { + std::ostringstream ss_; + + ss_ << "Single CHARSET must follow {-} or {+} at " + "index " << state_.index() - 1 << " in "; + + if (name_ != 0) + { + ss_ << "macro "; + narrow(name_, ss_); + } + else + { + ss_ << "rule id " << state_._id; + } + + ss_ << '.'; + throw runtime_error(ss_.str()); + } + else + { + rhs_ = iter_->second[1]; + } + } + + // Any macro with more than one charset (or quantifiers) + // requires bracketing. + if (multiple_) + { + token open_; + + open_._type = detail::OPENPAREN; + open_._str.insert('('); + tokens_.push_back(open_); + } + + // Don't need to store token if it is diff. + if (!diff_) + { + // Don't insert BEGIN or END tokens + tokens_.insert(tokens_.end(), iter_->second.begin() + 1, + iter_->second.end() - 1); + lhs_ = &tokens_.back(); + } + + if (multiple_) + { + token close_; + + close_._type = detail::CLOSEPAREN; + close_._str.insert(')'); + tokens_.push_back(close_); + } + } + } + else if (rhs_._type == detail::DIFF) + { + if (!macro_.empty()) + { + typename macro_map::const_iterator iter_ = + _macro_map.find(macro_); + + if (iter_->second.size() > 3) + { + std::ostringstream ss_; + + ss_ << "Single CHARSET must precede {-} or {+} at " + "index " << state_.index() - 1 << " in "; + + if (name_ != 0) + { + ss_ << "macro "; + narrow(name_, ss_); + } + else + { + ss_ << "rule id " << state_._id; + } + + ss_ << '.'; + throw runtime_error(ss_.str()); + } + } + + diff_ = rhs_._extra[0]; + macro_.clear(); + continue; + } + else if (!diff_) + { + tokens_.push_back(rhs_); + lhs_ = &tokens_.back(); + macro_.clear(); + } + + // diff_ may have been set by previous conditional. + if (diff_) + { + if (rhs_._type != detail::CHARSET) + { + std::ostringstream ss_; + + ss_ << "CHARSET must follow {-} or {+} at index " << + state_.index() - 1 << " in "; + + if (name_ != 0) + { + ss_ << "macro "; + narrow(name_, ss_); + } + else + { + ss_ << "rule id " << state_._id; + } + + ss_ << '.'; + throw runtime_error(ss_.str()); + } + + switch (diff_) + { + case '-': + lhs_->_str.remove(rhs_._str); + + if (lhs_->_str.empty()) + { + std::ostringstream ss_; + + ss_ << "Empty charset created by {-} at index " << + state_.index() - 1 << " in "; + + if (name_ != 0) + { + ss_ << "macro "; + narrow(name_, ss_); + } + else + { + ss_ << "rule id " << state_._id; + } + + ss_ << '.'; + throw runtime_error(ss_.str()); + } + + break; + case '+': + lhs_->_str.insert(rhs_._str); + break; + } + + diff_ = 0; + } + } while (tokens_.back()._type != detail::END); + + if (tokens_.size() == 2) + { + std::ostringstream ss_; + + ss_ << "Empty regex in "; + + if (name_ != 0) + { + ss_ << "macro "; + narrow(name_, ss_); + } + else + { + ss_ << "rule id " << state_._id; + } + + ss_ << " is not allowed."; + throw runtime_error(ss_.str()); + } + } + + void reverse(token_deque &deque_) + { + token_deque new_deque_(deque_.size(), token()); + typename token_deque::reverse_iterator iter_ = + deque_.rbegin(); + typename token_deque::reverse_iterator end_ = + deque_.rend(); + typename token_deque::iterator dest_ = new_deque_.begin(); + std::stack stack_; + + for (; iter_ != end_; ++iter_, ++dest_) + { + switch (iter_->_type) + { + case detail::BEGIN: + iter_->swap(*dest_); + dest_->_type = detail::END; + break; + case detail::BOL: + iter_->swap(*dest_); + dest_->_type = detail::EOL; + break; + case detail::EOL: + iter_->swap(*dest_); + dest_->_type = detail::BOL; + break; + case detail::OPENPAREN: + iter_->swap(*dest_); + dest_->_type = detail::CLOSEPAREN; + + if (stack_.top() != end_) + { + ++dest_; + dest_->swap(*stack_.top()); + } + + stack_.pop(); + break; + case detail::CLOSEPAREN: + iter_->swap(*dest_); + dest_->_type = detail::OPENPAREN; + stack_.push(end_); + break; + case detail::OPT: + case detail::AOPT: + case detail::ZEROORMORE: + case detail::AZEROORMORE: + case detail::ONEORMORE: + case detail::AONEORMORE: + case detail::REPEATN: + case detail::AREPEATN: + { + typename token_deque::reverse_iterator temp_ = iter_ + 1; + + if (temp_->_type == detail::CLOSEPAREN) + { + stack_.push(iter_); + ++iter_; + iter_->swap(*dest_); + dest_->_type = detail::OPENPAREN; + } + else + { + dest_->swap(*temp_); + ++dest_; + dest_->swap(*iter_); + ++iter_; + } + + break; + } + case detail::END: + iter_->swap(*dest_); + dest_->_type = detail::BEGIN; + break; + default: + // detail::OR + // detail::CHARSET + iter_->swap(*dest_); + break; + } + } + + new_deque_.swap(deque_); + } + + void push(const rules_char_type *curr_dfa_, const string ®ex_, + const id_type id_, const rules_char_type *new_dfa_, + const bool check_, const id_type user_id_ = npos()) + { + const bool star_ = *curr_dfa_ == '*' && *(curr_dfa_ + 1) == 0; + const bool dot_ = *new_dfa_ == '.' && *(new_dfa_ + 1) == 0; + const bool push_ = *new_dfa_ == '>'; + const rules_char_type *push_dfa_ = 0; + const bool pop_ = *new_dfa_ == '<'; + + if (push_ || pop_) + { + ++new_dfa_; + } + + if (check_) + { + check_for_invalid_id(id_); + } + + if (!dot_ && !pop_) + { + const rules_char_type *temp_ = new_dfa_; + + while (*temp_ && *temp_ != ':') + { + ++temp_; + } + + if (*temp_) push_dfa_ = temp_ + 1; + + validate(new_dfa_, *temp_ ? temp_ : 0); + + if (push_dfa_) + { + validate(push_dfa_); + } + } + + // npos means pop here + id_type new_dfa_id_ = npos(); + id_type push_dfa_id_ = npos(); + typename string_id_type_map::const_iterator iter_; + typename string_id_type_map::const_iterator end_ = _statemap.end(); + id_vector next_dfas_; + + if (!dot_ && !pop_) + { + if (push_dfa_) + { + iter_ = _statemap.find(string(new_dfa_, push_dfa_ - 1)); + } + else + { + iter_ = _statemap.find(new_dfa_); + } + + if (iter_ == end_) + { + std::ostringstream ss_; + + ss_ << "Unknown state name '"; + narrow(new_dfa_, ss_); + ss_ << "'."; + throw runtime_error(ss_.str()); + } + + new_dfa_id_ = iter_->second; + + if (push_dfa_) + { + iter_ = _statemap.find(push_dfa_); + + if (iter_ == end_) + { + std::ostringstream ss_; + + ss_ << "Unknown state name '"; + narrow(push_dfa_, ss_); + ss_ << "'."; + throw runtime_error(ss_.str()); + } + + push_dfa_id_ = iter_->second; + } + } + + if (star_) + { + const std::size_t size_ = _statemap.size(); + + for (id_type i_ = 0; i_ < size_; ++i_) + { + next_dfas_.push_back(i_); + } + } + else + { + const rules_char_type *start_ = curr_dfa_; + string next_dfa_; + + while (*curr_dfa_) + { + while (*curr_dfa_ && *curr_dfa_ != ',') + { + ++curr_dfa_; + } + + next_dfa_.assign(start_, curr_dfa_); + + if (*curr_dfa_) + { + ++curr_dfa_; + start_ = curr_dfa_; + } + + validate(next_dfa_.c_str()); + iter_ = _statemap.find(next_dfa_.c_str()); + + if (iter_ == end_) + { + std::ostringstream ss_; + + ss_ << "Unknown state name '"; + curr_dfa_ = next_dfa_.c_str(); + narrow(curr_dfa_, ss_); + ss_ << "'."; + throw runtime_error(ss_.str()); + } + + next_dfas_.push_back(iter_->second); + } + } + + for (std::size_t i_ = 0, size_ = next_dfas_.size(); + i_ < size_; ++i_) + { + const id_type curr_ = next_dfas_[i_]; + + _regexes[curr_].push_back(token_deque()); + tokenise(regex_, _regexes[curr_].back(), id_, 0); + + if (regex_[0] == '^') + { + _features[curr_] |= bol_bit; + } + + if (regex_[regex_.size() - 1] == '$') + { + _features[curr_] |= eol_bit; + } + + if (id_ == skip()) + { + _features[curr_] |= skip_bit; + } + else if (id_ == eoi()) + { + _features[curr_] |= again_bit; + } + + if (push_ || pop_) + { + _features[curr_] |= recursive_bit; + } + + _ids[curr_].push_back(id_); + _user_ids[curr_].push_back(user_id_); + _next_dfas[curr_].push_back(dot_ ? curr_ : new_dfa_id_); + _pushes[curr_].push_back(push_ ? (push_dfa_ ? + push_dfa_id_ : curr_) : npos()); + _pops[curr_].push_back(pop_); + } + } + + void validate(const rules_char_type *name_, + const rules_char_type *end_ = 0) const + { + const rules_char_type *start_ = name_; + + if (*name_ != '_' && !(*name_ >= 'A' && *name_ <= 'Z') && + !(*name_ >= 'a' && *name_ <= 'z')) + { + std::ostringstream ss_; + + ss_ << "Invalid name '"; + narrow(name_, ss_); + ss_ << "'."; + throw runtime_error(ss_.str()); + } + else if (*name_) + { + ++name_; + } + + while (*name_ && name_ != end_) + { + if (*name_ != '_' && *name_ != '-' && + !(*name_ >= 'A' && *name_ <= 'Z') && + !(*name_ >= 'a' && *name_ <= 'z') && + !(*name_ >= '0' && *name_ <= '9')) + { + std::ostringstream ss_; + + ss_ << "Invalid name '"; + name_ = start_; + narrow(name_, ss_); + ss_ << "'."; + throw runtime_error(ss_.str()); + } + + ++name_; + } + } + + void check_for_invalid_id(const id_type id_) const + { + if (id_ == eoi()) + { + throw runtime_error("Cannot resuse the id for eoi."); + } + + if (id_ == npos()) + { + throw runtime_error("The id npos is reserved for the " + "UNKNOWN token."); + } + } +}; + +typedef basic_rules rules; +typedef basic_rules wrules; +} + +#endif diff --git a/Puma/extern/lexertl/runtime_error.hpp b/Puma/extern/lexertl/runtime_error.hpp new file mode 100644 index 0000000..a296658 --- /dev/null +++ b/Puma/extern/lexertl/runtime_error.hpp @@ -0,0 +1,23 @@ +// runtime_error.hpp +// Copyright (c) 2005-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_RUNTIME_ERROR_HPP +#define LEXERTL_RUNTIME_ERROR_HPP + +#include + +namespace lexertl +{ +class runtime_error : public std::runtime_error +{ +public: + runtime_error(const std::string &what_arg_) : + std::runtime_error(what_arg_) + { + } +}; +} + +#endif diff --git a/Puma/extern/lexertl/serialise.hpp b/Puma/extern/lexertl/serialise.hpp new file mode 100644 index 0000000..d1f076f --- /dev/null +++ b/Puma/extern/lexertl/serialise.hpp @@ -0,0 +1,28 @@ +// serialise.hpp +// Copyright (c) 2007-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_SERIALISE_HPP +#define LEXERTL_SERIALISE_HPP + +#include "state_machine.hpp" +#include + +namespace lexertl +{ +// IMPORTANT! This won't work if you don't enable RTTI! +template +void serialise(basic_state_machine &sm_, Archive &ar_) +{ + detail::basic_internals &internals_ = sm_.data(); + + ar_ & internals_._eoi; + ar_ & *internals_._lookup; + ar_ & internals_._dfa_alphabet; + ar_ & internals_._features; + ar_ & *internals_._dfa; +} +} + +#endif diff --git a/Puma/extern/lexertl/size_t.hpp b/Puma/extern/lexertl/size_t.hpp new file mode 100644 index 0000000..504f56a --- /dev/null +++ b/Puma/extern/lexertl/size_t.hpp @@ -0,0 +1,12 @@ +// size_t.hpp +// Copyright (c) 2005-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_SIZE_T_H +#define LEXERTL_SIZE_T_H + +#include // ptrdiff_t +#include + +#endif diff --git a/Puma/extern/lexertl/sm_to_csm.hpp b/Puma/extern/lexertl/sm_to_csm.hpp new file mode 100644 index 0000000..c3cbb5d --- /dev/null +++ b/Puma/extern/lexertl/sm_to_csm.hpp @@ -0,0 +1,49 @@ +// sm_to_csm.hpp +// Copyright (c) 2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_SM_TO_CSM_HPP +#define LEXERTL_SM_TO_CSM_HPP + +namespace lexertl +{ +template +void sm_to_csm(const sm &sm_, char_state_machine &csm_) +{ + typedef typename sm::traits::id_type id_type; + typedef typename sm::internals internals; + typedef typename char_state_machine::state::string_token string_token; + typedef typename string_token::index_type index_type; + typedef typename char_state_machine::string_token_vector + string_token_vector; + const internals &internals_ = sm_.data(); + const std::size_t dfas_ = internals_._dfa->size(); + + for (id_type i_ = 0; i_ < dfas_; ++i_) + { + if (internals_._dfa_alphabet[i_] == 0) continue; + + const std::size_t alphabet_ = internals_._dfa_alphabet[i_] - + transitions_index; + string_token_vector token_vector_(alphabet_, string_token()); + id_type *ptr_ = &internals_._lookup[i_]->front(); + + for (std::size_t c_ = 0; c_ < 256; ++c_, ++ptr_) + { + if (*ptr_ >= transitions_index) + { + string_token &token_ = token_vector_ + [*ptr_ - transitions_index]; + + token_.insert(typename string_token::range + (index_type(c_), index_type(c_))); + } + } + + csm_.append(token_vector_, internals_, i_); + } +} +} + +#endif diff --git a/Puma/extern/lexertl/sm_traits.hpp b/Puma/extern/lexertl/sm_traits.hpp new file mode 100644 index 0000000..75d96d0 --- /dev/null +++ b/Puma/extern/lexertl/sm_traits.hpp @@ -0,0 +1,44 @@ +// sm_traits.hpp +// Copyright (c) 2005-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef LEXERTL_SM_TRAITS_H +#define LEXERTL_SM_TRAITS_H + +namespace lexertl +{ +template +struct basic_sm_traits +{ + enum {char_24_bit = sizeof(ch_type) > 2, compressed = comp, lookup = look, + is_dfa = dfa_nfa}; + typedef ch_type input_char_type; + typedef ch_type char_type; + typedef sm_type id_type; + + static id_type npos() + { + return ~static_cast(0); + } +}; + +template +struct basic_sm_traits +{ + enum {char_24_bit = sizeof(ch_type) > 2, compressed = true, lookup = look, + is_dfa = dfa_nfa}; + typedef ch_type input_char_type; + typedef unsigned char char_type; + typedef sm_type id_type; + + static id_type npos() + { + return ~static_cast(0); + } +}; +} + +#endif diff --git a/Puma/extern/lexertl/state_machine.hpp b/Puma/extern/lexertl/state_machine.hpp new file mode 100644 index 0000000..db2a1a5 --- /dev/null +++ b/Puma/extern/lexertl/state_machine.hpp @@ -0,0 +1,532 @@ +// state_machine.hpp +// Copyright (c) 2005-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_STATE_MACHINE_HPP +#define LEXERTL_STATE_MACHINE_HPP + +#include "compile_assert.hpp" +// memcmp() +#include +#include +#include "internals.hpp" +#include +#include +#include "sm_traits.hpp" +#include "string_token.hpp" + +namespace lexertl +{ +template +class basic_state_machine +{ +public: + typedef basic_sm_traits 1), true, true> traits; + typedef detail::basic_internals internals; + + // If you get a compile error here you have + // failed to define an unsigned id type. + // g++ 4.4.7 won't compile this: +#if !defined(__GNUC__) || __GNUC__ > 4 || __GNUC__ == 4 && __GNUC__MINIOR__ > 4 + compile_assert<(~static_cast(0) > 0)> _valid_id_type; +#endif + + basic_state_machine() : +#if !defined(__GNUC__) || __GNUC__ > 4 || __GNUC__ == 4 && __GNUC__MINIOR__ > 4 + _valid_id_type(), +#endif + _internals() + { + } + + void clear() + { + _internals.clear(); + } + + internals &data() + { + return _internals; + } + + const internals &data() const + { + return _internals; + } + + bool empty() const + { + return _internals.empty(); + } + + id_type eoi() const + { + return _internals._eoi; + } + + void minimise() + { + const id_type dfas_ = static_cast(_internals. + _dfa->size()); + + for (id_type i_ = 0; i_ < dfas_; ++i_) + { + const id_type dfa_alphabet_ = _internals._dfa_alphabet[i_]; + id_type_vector *dfa_ = _internals._dfa[i_]; + + if (dfa_alphabet_ != 0) + { + std::size_t size_ = 0; + + do + { + size_ = dfa_->size(); + minimise_dfa(dfa_alphabet_, *dfa_, size_); + } while (dfa_->size() != size_); + } + } + } + + static id_type npos() + { + return ~static_cast(0); + } + + static id_type skip() + { + return ~static_cast(1); + } + + void swap(basic_state_machine &rhs_) + { + _internals.swap(rhs_._internals); + } + +private: + typedef typename internals::id_type_vector id_type_vector; + typedef std::set index_set; + internals _internals; + + void minimise_dfa(const id_type dfa_alphabet_, + id_type_vector &dfa_, std::size_t size_) + { + const id_type *first_ = &dfa_.front(); + const id_type *end_ = first_ + size_; + id_type index_ = 1; + id_type new_index_ = 1; + id_type_vector lookup_(size_ / dfa_alphabet_, npos()); + id_type *lookup_ptr_ = &lookup_.front(); + index_set index_set_; + const id_type bol_index_ = dfa_.front(); + + *lookup_ptr_ = 0; + // Only one 'jam' state, so skip it. + first_ += dfa_alphabet_; + + for (; first_ < end_; first_ += dfa_alphabet_, ++index_) + { + const id_type *second_ = first_ + dfa_alphabet_; + + for (id_type curr_index_ = index_ + 1; second_ < end_; + ++curr_index_, second_ += dfa_alphabet_) + { + if (index_set_.find(curr_index_) != index_set_.end()) + { + continue; + } + + // Some systems have memcmp in namespace std. + using namespace std; + + if (memcmp(first_, second_, sizeof(id_type) * + dfa_alphabet_) == 0) + { + index_set_.insert(curr_index_); + lookup_ptr_[curr_index_] = new_index_; + } + } + + if (lookup_ptr_[index_] == npos()) + { + lookup_ptr_[index_] = new_index_; + ++new_index_; + } + } + + if (!index_set_.empty()) + { + const id_type *front_ = &dfa_.front(); + id_type_vector new_dfa_(front_, front_ + dfa_alphabet_); + typename index_set::const_iterator set_end_ = index_set_.end(); + const id_type *ptr_ = front_ + dfa_alphabet_; + id_type *new_ptr_ = 0; + + new_dfa_.resize(size_ - index_set_.size() * dfa_alphabet_, 0); + new_ptr_ = &new_dfa_.front() + dfa_alphabet_; + size_ /= dfa_alphabet_; + + if (bol_index_) + { + new_dfa_.front() = lookup_ptr_[bol_index_]; + } + + for (index_ = 1; index_ < size_; ++index_) + { + if (index_set_.find(index_) != set_end_) + { + ptr_ += dfa_alphabet_; + continue; + } + + new_ptr_[end_state_index] = ptr_[end_state_index]; + new_ptr_[id_index] = ptr_[id_index]; + new_ptr_[user_id_index] = ptr_[user_id_index]; + new_ptr_[push_dfa_index] = ptr_[push_dfa_index]; + new_ptr_[next_dfa_index] = ptr_[next_dfa_index]; + new_ptr_[eol_index] = lookup_ptr_[ptr_[eol_index]]; + new_ptr_ += transitions_index; + ptr_ += transitions_index; + + for (id_type i_ = transitions_index; i_ < dfa_alphabet_; ++i_) + { + *new_ptr_++ = lookup_ptr_[*ptr_++]; + } + } + + dfa_.swap(new_dfa_); + } + } +}; + +typedef basic_state_machine state_machine; +typedef basic_state_machine wstate_machine; + +template +struct basic_char_state_machine +{ + typedef basic_sm_traits traits; + typedef detail::basic_internals internals; + typedef typename internals::id_type_vector id_type_vector; + + struct state + { + typedef basic_string_token string_token; + typedef std::map id_type_string_token_map; + typedef std::pair id_type_string_token_pair; + enum push_pop_dfa {neither, push_dfa, pop_dfa}; + + bool _end_state; + push_pop_dfa _push_pop_dfa; + id_type _id; + id_type _user_id; + id_type _push_dfa; + id_type _next_dfa; + id_type _eol_index; + id_type_string_token_map _transitions; + + state() : + _end_state(false), + _push_pop_dfa(neither), + _id(0), + _user_id(traits::npos()), + _push_dfa(traits::npos()), + _next_dfa(0), + _eol_index(traits::npos()), + _transitions() + { + } + + bool operator ==(const state rhs_) const + { + return _end_state == rhs_._end_state && + _push_pop_dfa == rhs_._push_pop_dfa && + _id == rhs_._id && + _user_id == rhs_._user_id && + _push_dfa == rhs_._push_dfa && + _next_dfa == rhs_._next_dfa && + _eol_index == rhs_._eol_index && + _transitions == rhs_._transitions; + } + }; + + typedef typename state::string_token string_token; + typedef std::vector state_vector; + typedef std::vector string_token_vector; + typedef typename state::id_type_string_token_pair + id_type_string_token_pair; + + struct dfa + { + id_type _bol_index; + state_vector _states; + + dfa(const std::size_t size_) : + _bol_index(traits::npos()), + _states(state_vector(size_)) + { + } + + std::size_t size() const + { + return _states.size(); + } + + void swap(dfa &rhs_) + { + std::swap(_bol_index, rhs_._bol_index); + _states.swap(rhs_._states); + } + }; + + typedef std::deque dfa_deque; + + // g++ 4.4.7 won't compile this: +#if !defined(__GNUC__) || __GNUC__ > 4 || __GNUC__ == 4 && __GNUC__MINIOR__ > 4 + // If you get a compile error here you have + // failed to define an unsigned id type. + compile_assert<(~static_cast(0) > 0)> _valid_id_type; +#endif + dfa_deque _sm_deque; + + basic_char_state_machine() : +#if !defined(__GNUC__) || __GNUC__ > 4 || __GNUC__ == 4 && __GNUC__MINIOR__ > 4 + _valid_id_type(), +#endif + _sm_deque() + { + } + + void append(const string_token_vector &token_vector_, + const internals &internals_, const id_type dfa_index_) + { + const std::size_t dfa_alphabet_ = internals_._dfa_alphabet[dfa_index_]; + const std::size_t alphabet_ = dfa_alphabet_ - transitions_index; + const id_type_vector &source_dfa_ = *internals_._dfa[dfa_index_]; + const id_type *ptr_ = &source_dfa_.front(); + const std::size_t size_ = (source_dfa_.size() - dfa_alphabet_) / + dfa_alphabet_; + typename state::id_type_string_token_map::iterator trans_iter_; + + _sm_deque.push_back(dfa(size_)); + + dfa &dest_dfa_ = _sm_deque.back(); + + if (*ptr_) + { + dest_dfa_._bol_index = *ptr_ - 1; + } + + ptr_ += dfa_alphabet_; + + for (id_type i_ = 0; i_ < size_; ++i_) + { + state &state_ = dest_dfa_._states[i_]; + + state_._end_state = ptr_[end_state_index] != 0; + + if (ptr_[push_dfa_index] != npos()) + { + state_._push_pop_dfa = state::push_dfa; + } + else if (ptr_[end_state_index] & pop_dfa_bit) + { + state_._push_pop_dfa = state::pop_dfa; + } + + state_._id = ptr_[id_index]; + state_._user_id = ptr_[user_id_index]; + state_._push_dfa = ptr_[push_dfa_index]; + state_._next_dfa = ptr_[next_dfa_index]; + + if (ptr_[eol_index]) + { + state_._eol_index = ptr_[eol_index] - 1; + } + + ptr_ += transitions_index; + + for (id_type col_index_ = 0; col_index_ < alphabet_; + ++col_index_, ++ptr_) + { + const id_type next_ = *ptr_; + + if (next_ > 0) + { + trans_iter_ = state_._transitions.find(next_ - 1); + + if (trans_iter_ == state_._transitions.end()) + { + trans_iter_ = state_._transitions.insert + (id_type_string_token_pair(next_ - 1, + token_vector_[col_index_])).first; + } + else + { + trans_iter_->second.insert(token_vector_[col_index_]); + } + } + } + } + } + + void clear() + { + _sm_deque.clear(); + } + + bool empty() const + { + return _sm_deque.empty(); + } + + void minimise() + { + const id_type dfas_ = static_cast(_sm_deque.size()); + + for (id_type i_ = 0; i_ < dfas_; ++i_) + { + dfa *dfa_ = &_sm_deque[i_]; + + if (dfa_->size() > 0) + { + std::size_t size_ = 0; + + do + { + size_ = dfa_->size(); + minimise_dfa(*dfa_, size_); + } while (dfa_->size() != size_); + } + } + } + + static id_type npos() + { + return traits::npos(); + } + + id_type size() const + { + return static_cast(_sm_deque.size()); + } + + static id_type skip() + { + return ~static_cast(1); + } + + void swap(basic_char_state_machine &csm_) + { + _sm_deque.swap(csm_._sm_deque); + } + +private: + typedef std::set index_set; + + void minimise_dfa(dfa &dfa_, std::size_t size_) + { + const state *first_ = &dfa_._states.front(); + const state *end_ = first_ + size_; + id_type index_ = 0; + id_type new_index_ = 0; + id_type_vector lookup_(size_, npos()); + id_type *lookup_ptr_ = &lookup_.front(); + index_set index_set_; + + for (; first_ != end_; ++first_, ++index_) + { + const state *second_ = first_ + 1; + + for (id_type curr_index_ = index_ + 1; second_ != end_; + ++curr_index_, ++second_) + { + if (index_set_.find(curr_index_) != index_set_.end()) + { + continue; + } + + if (*first_ == *second_) + { + index_set_.insert(curr_index_); + lookup_ptr_[curr_index_] = new_index_; + } + } + + if (lookup_ptr_[index_] == npos()) + { + lookup_ptr_[index_] = new_index_; + ++new_index_; + } + } + + if (!index_set_.empty()) + { + const state *front_ = &dfa_._states.front(); + dfa new_dfa_(new_index_); + typename index_set::const_iterator set_end_ = index_set_.end(); + const state *ptr_ = front_; + state *new_ptr_ = &new_dfa_._states.front(); + + if (dfa_._bol_index != npos()) + { + new_dfa_._bol_index = lookup_ptr_[dfa_._bol_index]; + } + + for (index_ = 0; index_ < size_; ++index_) + { + if (index_set_.find(index_) != set_end_) + { + ++ptr_; + continue; + } + + new_ptr_->_end_state = ptr_->_end_state; + new_ptr_->_id = ptr_->_end_state; + new_ptr_->_user_id = ptr_->_user_id; + new_ptr_->_next_dfa = ptr_->_next_dfa; + + if (ptr_->_eol_index != npos()) + { + new_ptr_->_eol_index = lookup_ptr_[ptr_->_eol_index]; + } + + typename state::id_type_string_token_map::const_iterator + iter_ = ptr_->_transitions.begin(); + typename state::id_type_string_token_map::const_iterator end_ = + ptr_->_transitions.end(); + typename state::id_type_string_token_map::iterator find_; + + for (; iter_ != end_; ++iter_) + { + find_ = new_ptr_->_transitions.find + (lookup_ptr_[iter_->first]); + + if (find_ == new_ptr_->_transitions.end()) + { + new_ptr_->_transitions.insert + (id_type_string_token_pair + (lookup_ptr_[iter_->first], iter_->second)); + } + else + { + find_->second.insert(iter_->second); + } + } + + ++ptr_; + ++new_ptr_; + } + + dfa_.swap(new_dfa_); + } + } +}; + +typedef basic_char_state_machine char_state_machine; +typedef basic_char_state_machine wchar_state_machine; +} + +#endif diff --git a/Puma/extern/lexertl/stream_shared_iterator.hpp b/Puma/extern/lexertl/stream_shared_iterator.hpp new file mode 100644 index 0000000..9b472c8 --- /dev/null +++ b/Puma/extern/lexertl/stream_shared_iterator.hpp @@ -0,0 +1,350 @@ +// stream_shared_iterator.hpp +// Copyright (c) 2010-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef LEXERTL_STREAM_SHARED_ITERATOR_H +#define LEXERTL_STREAM_SHARED_ITERATOR_H + +#include +// memcpy +#include +#include +#include +#include +#include "runtime_error.hpp" +#include "size_t.hpp" +#include + +namespace lexertl +{ +template +class basic_stream_shared_iterator +{ +public: + typedef std::basic_istream istream; + typedef std::forward_iterator_tag iterator_category; + typedef std::size_t difference_type; + typedef char_type value_type; + typedef char_type *pointer; + typedef char_type &reference; + + basic_stream_shared_iterator() : + _master(false), + _live(false), + _index(shared::npos()), + _shared(0) + { + } + + basic_stream_shared_iterator(istream &stream_, + const std::size_t buff_size_ = 1024, + const std::size_t increment_ = 1024) : + _master(true), + _live(false), + _index(shared::npos()), + // For exception safety don't call new yet + _shared(0) + { + // Safe to call potentially throwing new now. + _shared = new shared(stream_, buff_size_, increment_); + ++_shared->_ref_count; + _iter = _shared->_clients.insert(_shared->_clients.end(), this); + } + + basic_stream_shared_iterator(const basic_stream_shared_iterator &rhs_) : + _master(false), + _live(false), + _index(rhs_._master ? rhs_._shared->lowest() : rhs_._index), + _shared(rhs_._shared) + { + if (_shared) + { + // New copy of an iterator. + // The assumption is that any copy must be live + // even if the rhs is not (otherwise we will never + // have a record of the start of the current range!) + ++_shared->_ref_count; + _iter = _shared->_clients.insert(_shared->_clients.end(), this); + _live = true; + } + } + + ~basic_stream_shared_iterator() + { + if (_shared) + { + --_shared->_ref_count; + _shared->erase(this); + + if (_shared->_ref_count == 0) + { + delete _shared; + _shared = 0; + } + } + } + + basic_stream_shared_iterator &operator = + (const basic_stream_shared_iterator &rhs_) + { + if (this != &rhs_) + { + _master = false; + _index = rhs_._master ? rhs_._shared->lowest() : rhs_._index; + + if (_live && !rhs_._live) + { + _shared->erase(this); + + if (!rhs_._shared) + { + --_shared->_ref_count; + } + } + else if (!_live && rhs_._live) + { + rhs_._iter = rhs_._shared->_clients.insert(rhs_._shared-> + _clients.end(), this); + + if (!_shared) + { + ++rhs_._shared->_ref_count; + } + } + + _live = rhs_._live; + _shared = rhs_._shared; + } + + return *this; + } + + bool operator ==(const basic_stream_shared_iterator &rhs_) const + { + return _index == rhs_._index && + (_shared == rhs_._shared || + (_index == shared::npos() || rhs_._index == shared::npos()) && + (!_shared || !rhs_._shared)); + } + + bool operator !=(const basic_stream_shared_iterator &rhs_) const + { + return !(*this == rhs_); + } + + const char_type &operator *() + { + check_master(); + return _shared->_buffer[_index]; + } + + basic_stream_shared_iterator &operator ++() + { + check_master(); + ++_index; + update_state(); + return *this; + } + + basic_stream_shared_iterator operator ++(int) + { + basic_stream_shared_iterator iter_ = *this; + + check_master(); + ++_index; + update_state(); + return iter_; + } + +private: + class shared + { + public: + std::size_t _ref_count; + typedef std::vector char_vector; + typedef std::list iter_list; + istream &_stream; + std::size_t _increment; + std::size_t _len; + char_vector _buffer; + iter_list _clients; + + shared(istream &stream_, const std::size_t buff_size_, + const std::size_t increment_) : + _ref_count(0), + _increment(increment_), + _stream(stream_) + { + _buffer.resize(buff_size_); + _stream.read(&_buffer.front(), _buffer.size()); + _len = static_cast(_stream.gcount()); + } + + bool reload_buffer() + { + const std::size_t lowest_ = lowest(); + std::size_t read_ = 0; + + if (lowest_ == 0) + { + // Resize buffer + const std::size_t old_size_ = _buffer.size(); + const std::size_t new_size_ = old_size_ + _increment; + + _buffer.resize(new_size_); + _stream.read(&_buffer.front() + old_size_, _increment); + read_ = static_cast(_stream.gcount()); + + if (read_) + { + read_ += old_size_; + _len = read_; + } + } + else + { + // Some systems have memcpy in namespace std + using namespace std; + const size_t start_ = _buffer.size() - lowest_; + const size_t len_ = _buffer.size() - start_; + + memcpy(&_buffer.front(), &_buffer[lowest_], start_ * + sizeof(char_type)); + _stream.read(&_buffer.front() + start_, len_); + read_ = static_cast(_stream.gcount()); + subtract(lowest_); + + if (read_) + { + read_ += start_; + _len = read_; + } + else + { + _len = highest(); + } + } + + return read_ != 0; + } + + void erase(basic_stream_shared_iterator *ptr_) + { + if (ptr_->_iter != _clients.end()) + { + _clients.erase(ptr_->_iter); + ptr_->_iter = _clients.end(); + } + } + + std::size_t lowest() const + { + std::size_t lowest_ = npos(); + typename iter_list::const_iterator iter_ = _clients.begin(); + typename iter_list::const_iterator end_ = _clients.end(); + + for (; iter_ != end_; ++iter_) + { + const basic_stream_shared_iterator *ptr_ = *iter_; + + if (ptr_->_index < lowest_) + { + lowest_ = ptr_->_index; + } + } + + if (lowest_ == npos()) + { + lowest_ = 0; + } + + return lowest_; + } + + std::size_t highest() const + { + std::size_t highest_ = 0; + typename iter_list::const_iterator iter_ = _clients.begin(); + typename iter_list::const_iterator end_ = _clients.end(); + + for (; iter_ != end_; ++iter_) + { + const basic_stream_shared_iterator *ptr_ = *iter_; + + if (ptr_->_index != npos() && ptr_->_index > highest_) + { + highest_ = ptr_->_index; + } + } + + return highest_; + } + + void subtract(const std::size_t lowest_) + { + typename iter_list::iterator iter_ = _clients.begin(); + typename iter_list::iterator end_ = _clients.end(); + + for (; iter_ != end_; ++iter_) + { + basic_stream_shared_iterator *ptr_ = *iter_; + + if (ptr_->_index != npos()) + { + ptr_->_index -= lowest_; + } + } + } + + static std::size_t npos() + { + return ~static_cast(0); + } + + private: + shared &operator =(const shared &rhs_); + }; + + bool _master; + bool _live; + std::size_t _index; + shared *_shared; + mutable typename shared::iter_list::iterator _iter; + + void check_master() + { + if (!_shared) + { + throw runtime_error("Cannot manipulate null (end) " + "stream_shared_iterators."); + } + + if (_master) + { + _master = false; + _live = true; + _index = _shared->lowest(); + } + } + + void update_state() + { + if (_index >= _shared->_len) + { + if (!_shared->reload_buffer()) + { + _shared->erase(this); + _index = shared::npos(); + _live = false; + } + } + } +}; + +typedef basic_stream_shared_iterator stream_shared_iterator; +typedef basic_stream_shared_iterator wstream_shared_iterator; +} + +#endif diff --git a/Puma/extern/lexertl/string_token.hpp b/Puma/extern/lexertl/string_token.hpp new file mode 100644 index 0000000..491ac3f --- /dev/null +++ b/Puma/extern/lexertl/string_token.hpp @@ -0,0 +1,421 @@ +// string_token.hpp +// Copyright (c) 2005-2015 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_STRING_TOKEN_HPP +#define LEXERTL_STRING_TOKEN_HPP + +#include "char_traits.hpp" +#include // Needed by GCC 4.4 +#include +#include +#include +#include + +namespace lexertl +{ +template +struct basic_string_token +{ + typedef ch_type char_type; + typedef basic_char_traits char_traits; + typedef typename char_traits::index_type index_type; + typedef std::pair range; + typedef std::vector range_vector; + typedef std::basic_string string; + typedef basic_string_token string_token; + + range_vector _ranges; + + basic_string_token() : + _ranges() + { + } + + basic_string_token(char_type ch_) : + _ranges() + { + insert(range(ch_, ch_)); + } + + basic_string_token(char_type first_, char_type second_) : + _ranges() + { + insert(range(first_, second_)); + } + + void clear() + { + _ranges.clear(); + } + + bool empty() const + { + return _ranges.empty(); + } + + bool any() const + { + return _ranges.size() == 1 && _ranges.front().first == 0 && + _ranges.front().second == char_traits::max_val(); + } + + bool operator <(const basic_string_token &rhs_) const + { + return _ranges < rhs_._ranges; + } + + bool operator ==(const basic_string_token &rhs_) const + { + return _ranges == rhs_._ranges; + } + + bool negatable() const + { + std::size_t size_ = 0; + typename range_vector::const_iterator iter_ = _ranges.begin(); + typename range_vector::const_iterator end_ = _ranges.end(); + + for (; iter_ != end_; ++iter_) + { + size_ += static_cast(iter_->second) + 1 - + static_cast(iter_->first); + } + + return size_ > static_cast(char_traits::max_val()) / 2; + } + + void swap(basic_string_token &rhs_) + { + _ranges.swap(rhs_._ranges); + } + + void insert(const basic_string_token &rhs_) + { + typename range_vector::const_iterator iter_ = rhs_._ranges.begin(); + typename range_vector::const_iterator end_ = rhs_._ranges.end(); + + for (; iter_ != end_; ++iter_) + { + insert(*iter_); + } + } + + // Deliberately pass by value - may modify + typename range_vector::iterator insert(range rhs_) + { + bool insert_ = true; + typename range_vector::iterator iter_ = _ranges.begin(); + typename range_vector::const_iterator end_ = _ranges.end(); + + while (iter_ != end_) + { + // follows current item + if (rhs_.first > iter_->second) + { + if (rhs_.first == iter_->second + 1) + { + // Auto normalise + rhs_.first = iter_->first; + } + else + { + // No intersection, consider next + ++iter_; + continue; + } + } + // Precedes current item + else if (rhs_.second < iter_->first) + { + if (rhs_.second == iter_->first - 1) + { + // Auto normalise + rhs_.second = iter_->second; + } + else + { + // insert here + break; + } + } + else + { + // overlap (under) + if (rhs_.first < iter_->first) + { + if (rhs_.second < iter_->second) + { + rhs_.second = iter_->second; + } + } + // overlap (over) + else if (rhs_.second > iter_->second) + { + if (rhs_.first > iter_->first) + { + rhs_.first = iter_->first; + } + } + // subset + else + { + insert_ = false; + iter_ = _ranges.end(); + break; + } + } + + // Code minimisation: this always applies unless we have already + // exited the loop, or "continue" executed. + iter_ = _ranges.erase(iter_); + end_ = _ranges.end(); + } + + if (insert_) + { + iter_ = _ranges.insert(iter_, rhs_); + } + + return iter_; + } + + void negate() + { + index_type next_ = 0; + const index_type max_ = char_traits::max_val(); + string_token temp_; + typename range_vector::iterator iter_ = _ranges.begin(); + typename range_vector::const_iterator end_ = _ranges.end(); + bool finished_ = false; + + for (; iter_ != end_; ++iter_) + { + if (next_ < iter_->first) + { + temp_.insert(range(next_, iter_->first - 1)); + } + + if (iter_->second < max_) + { + next_ = iter_->second + 1; + } + else + { + finished_ = true; + break; + } + } + + if (!finished_) + { + temp_.insert(range(next_, max_)); + } + + swap(temp_); + } + + void intersect(basic_string_token &rhs_, basic_string_token &overlap_) + { + typename range_vector::iterator lhs_iter_ = _ranges.begin(); + typename range_vector::const_iterator lhs_end_ = _ranges.end(); + typename range_vector::iterator rhs_iter_ = rhs_._ranges.begin(); + typename range_vector::const_iterator rhs_end_ = rhs_._ranges.end(); + + while (lhs_iter_ != lhs_end_ && rhs_iter_ != rhs_end_) + { + if (rhs_iter_->first > lhs_iter_->second) + { + ++lhs_iter_; + } + else if (rhs_iter_->second < lhs_iter_->first) + { + ++rhs_iter_; + } + else + { + range range_; + + if (rhs_iter_->first > lhs_iter_->first) + { + range_.first = rhs_iter_->first; + } + else + { + range_.first = lhs_iter_->first; + } + + if (rhs_iter_->second < lhs_iter_->second) + { + range_.second = rhs_iter_->second; + } + else + { + range_.second = lhs_iter_->second; + } + + adjust(range_, *this, lhs_iter_, lhs_end_); + adjust(range_, rhs_, rhs_iter_, rhs_end_); + overlap_.insert(range_); + } + } + } + + void remove(basic_string_token &rhs_) + { + typename range_vector::iterator lhs_iter_ = _ranges.begin(); + typename range_vector::const_iterator lhs_end_ = _ranges.end(); + typename range_vector::iterator rhs_iter_ = rhs_._ranges.begin(); + typename range_vector::const_iterator rhs_end_ = rhs_._ranges.end(); + + while (lhs_iter_ != lhs_end_ && rhs_iter_ != rhs_end_) + { + if (rhs_iter_->first > lhs_iter_->second) + { + ++lhs_iter_; + } + else if (rhs_iter_->second < lhs_iter_->first) + { + ++rhs_iter_; + } + else + { + range range_; + + if (rhs_iter_->first > lhs_iter_->first) + { + range_.first = rhs_iter_->first; + } + else + { + range_.first = lhs_iter_->first; + } + + if (rhs_iter_->second < lhs_iter_->second) + { + range_.second = rhs_iter_->second; + } + else + { + range_.second = lhs_iter_->second; + } + + adjust(range_, *this, lhs_iter_, lhs_end_); + } + } + } + + static string escape_char(const typename char_traits::index_type ch_) + { + string out_; + + switch (ch_) + { + case '\0': + out_ += '\\'; + out_ += '0'; + break; + case '\a': + out_ += '\\'; + out_ += 'a'; + break; + case '\b': + out_ += '\\'; + out_ += 'b'; + break; + case 27: + out_ += '\\'; + out_ += 'x'; + out_ += '1'; + out_ += 'b'; + break; + case '\f': + out_ += '\\'; + out_ += 'f'; + break; + case '\n': + out_ += '\\'; + out_ += 'n'; + break; + case '\r': + out_ += '\\'; + out_ += 'r'; + break; + case '\t': + out_ += '\\'; + out_ += 't'; + break; + case '\v': + out_ += '\\'; + out_ += 'v'; + break; + case '\\': + out_ += '\\'; + out_ += '\\'; + break; + case '"': + out_ += '\\'; + out_ += '"'; + break; + case '\'': + out_ += '\\'; + out_ += '\''; + break; + default: + { + if (ch_ < 32 || ch_ > 126) + { + std::basic_stringstream ss_; + + out_ += '\\'; + out_ += 'x'; + ss_ << std::hex << + static_cast(ch_); + out_ += ss_.str(); + } + else + { + out_ += ch_; + } + + break; + } + } + + return out_; + } + +private: + void adjust(const range &range_, basic_string_token &token_, + typename range_vector::iterator &iter_, + typename range_vector::const_iterator &end_) + { + if (range_.first > iter_->first) + { + const index_type second_ = iter_->second; + + iter_->second = range_.first - 1; + + if (range_.second < second_) + { + range new_range_(range_.second + 1, second_); + + iter_ = token_.insert(new_range_); + end_ = token_._ranges.end(); + } + } + else if (range_.second < iter_->second) + { + iter_->first = range_.second + 1; + } + else + { + iter_ = token_._ranges.erase(iter_); + end_ = token_._ranges.end(); + } + } +}; +} + +#endif diff --git a/Puma/extern/lexertl/utf_iterators.hpp b/Puma/extern/lexertl/utf_iterators.hpp new file mode 100644 index 0000000..0308d1d --- /dev/null +++ b/Puma/extern/lexertl/utf_iterators.hpp @@ -0,0 +1,486 @@ +// utf_iterators.hpp +// Copyright (c) 2015 Ben Hanson (http://www.benhanson.net/) +// Inspired by http://utfcpp.sourceforge.net/ +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef LEXERTL_UTF_ITERATORS_HPP +#define LEXERTL_UTF_ITERATORS_HPP + +#include + +namespace lexertl +{ +template +class basic_utf8_in_iterator : + public std::iterator +{ +public: + typedef char_type value_type; + typedef typename std::iterator_traits:: + difference_type difference_type; + typedef std::forward_iterator_tag iterator_category; + + basic_utf8_in_iterator() : + _it(char_iterator()), + _end(char_iterator()), + _char(0) + { + } + + explicit basic_utf8_in_iterator(const char_iterator &it_, + const char_iterator &end_) : + _it(it_), + _end(it_), + _char(0) + { + if (it_ != end_) + { + next(); + } + } + + char_type operator *() const + { + return _char; + } + + bool operator ==(const basic_utf8_in_iterator &rhs_) const + { + return _it == rhs_._it; + } + + bool operator !=(const basic_utf8_in_iterator &rhs_) const + { + return _it != rhs_._it; + } + + basic_utf8_in_iterator &operator ++() + { + _it = _end; + next(); + return *this; + } + + basic_utf8_in_iterator operator ++(int) + { + basic_utf8_in_iterator temp_ = *this; + + _it = _end; + next(); + return temp_; + } + + basic_utf8_in_iterator operator +(const std::size_t count_) const + { + basic_utf8_in_iterator temp_ = *this; + + for (std::size_t i_ = 0; i_ < count_; ++i_) + { + ++temp_; + } + + return temp_; + } + + basic_utf8_in_iterator operator -(const std::size_t count_) const + { + basic_utf8_in_iterator temp_ = *this; + + for (std::size_t i_ = 0; i_ < count_; ++i_) + { + temp_._end = temp_._it; + --temp_._it; + + while ((*temp_._it & 0xc0) == 0x80) --temp_._it; + } + + temp_.next(); + return temp_; + } + +private: + char_iterator _it; + char_iterator _end; + char_type _char; + + void next() + { + const char len_ = len(_it); + char_type ch_ = *_it & 0xff; + + switch (len_) + { + case 1: + _end = _it; + break; + case 2: + _end = _it; + ++_end; + ch_ = (ch_ << 6 & 0x7ff) | (*_end & 0x3f); + break; + case 3: + _end = _it; + ++_end; + ch_ = (ch_ << 12 & 0xffff) | ((*_end & 0xff) << 6 & 0xfff); + ++_end; + ch_ |= *_end & 0x3f; + break; + case 4: + _end = _it; + ++_end; + ch_ = (ch_ << 18 & 0x1fffff) | ((*_end & 0xff) << 12 & 0x3ffff); + ++_end; + ch_ |= (*_end & 0xff) << 6 & 0xfff; + ++_end; + ch_ |= *_end & 0x3f; + break; + } + + _char = ch_; + ++_end; + } + + char len(const char_iterator &it_) const + { + const unsigned char ch_ = *it_; + + return ch_ < 0x80 ? 1 : + ch_ >> 5 == 0x06 ? 2 : + ch_ >> 4 == 0x0e ? 3 : + ch_ >> 3 == 0x1e ? 4 : 0; + } +}; + +template +class basic_utf8_out_iterator : + public std::iterator +{ +public: + typedef char value_type; + typedef typename std::iterator_traits:: + difference_type difference_type; + typedef std::forward_iterator_tag iterator_category; + + basic_utf8_out_iterator() : + _count(0), + _index(0) + { + } + + explicit basic_utf8_out_iterator(const char_iterator &it_, + const char_iterator &end_) : + _it(it_), + _count(0), + _index(0) + { + if (it_ != end_) + { + next(); + } + } + + char operator *() const + { + return _bytes[_index]; + } + + bool operator ==(const basic_utf8_out_iterator &rhs_) const + { + return _it == rhs_._it; + } + + bool operator !=(const basic_utf8_out_iterator &rhs_) const + { + return _it != rhs_._it; + } + + basic_utf8_out_iterator &operator ++() + { + ++_index; + + if (_index >= _count) + { + ++_it; + next(); + } + + return *this; + } + + basic_utf8_out_iterator operator ++(int) + { + basic_utf8_out_iterator temp_ = *this; + + ++_index; + + if (_index >= _count) + { + ++_it; + next(); + } + + return temp_; + } + +private: + char_iterator _it; + char _bytes[4]; + unsigned char _count; + unsigned char _index; + + void next() + { + const std::size_t ch_ = *_it; + + _count = len(ch_); + _index = 0; + + switch (_count) + { + case 1: + _bytes[0] = static_cast(ch_); + break; + case 2: + _bytes[0] = static_cast((ch_ >> 6) | 0xc0); + _bytes[1] = (ch_ & 0x3f) | 0x80; + break; + case 3: + _bytes[0] = static_cast((ch_ >> 12) | 0xe0); + _bytes[1] = ((ch_ >> 6) & 0x3f) | 0x80; + _bytes[2] = (ch_ & 0x3f) | 0x80; + break; + case 4: + _bytes[0] = static_cast((ch_ >> 18) | 0xf0); + _bytes[1] = ((ch_ >> 12) & 0x3f) | 0x80; + _bytes[2] = ((ch_ >> 6) & 0x3f) | 0x80; + _bytes[3] = (ch_ & 0x3f) | 0x80; + break; + } + } + + char len(const std::size_t ch_) const + { + return ch_ < 0x80 ? 1 : + ch_ < 0x800 ? 2 : + ch_ < 0x10000 ? 3 : + 4; + } +}; + +template +class basic_utf16_in_iterator : + public std::iterator +{ +public: + typedef char_type value_type; + typedef typename std::iterator_traits:: + difference_type difference_type; + typedef std::forward_iterator_tag iterator_category; + + basic_utf16_in_iterator() : + _it(char_iterator()), + _end(char_iterator()), + _char(0) + { + } + + explicit basic_utf16_in_iterator(const char_iterator &it_, + const char_iterator &end_) : + _it(it_), + _end(it_), + _char(0) + { + if (it_ != end_) + { + next(); + } + } + + char_type operator *() const + { + return _char; + } + + bool operator ==(const basic_utf16_in_iterator &rhs_) const + { + return _it == rhs_._it; + } + + bool operator !=(const basic_utf16_in_iterator &rhs_) const + { + return _it != rhs_._it; + } + + basic_utf16_in_iterator &operator ++() + { + _it = _end; + next(); + return *this; + } + + basic_utf16_in_iterator operator ++(int) + { + basic_utf16_in_iterator temp_ = *this; + + _it = _end; + next(); + return temp_; + } + + basic_utf16_in_iterator operator +(const std::size_t count_) const + { + basic_utf16_in_iterator temp_ = *this; + + for (std::size_t i_ = 0; i_ < count_; ++i_) + { + ++temp_; + } + + return temp_; + } + + basic_utf16_in_iterator operator -(const std::size_t count_) const + { + basic_utf16_in_iterator temp_ = *this; + + for (std::size_t i_ = 0; i_ < count_; ++i_) + { + temp_._end = temp_._it; + --temp_._it; + + if (*temp_._it >= 0xdc00 && *temp_._it <= 0xdfff) --temp_._it; + } + + temp_.next(); + return temp_; + } + +private: + char_iterator _it; + char_iterator _end; + char_type _char; + + void next() + { + char_type ch_ = *_it & 0xffff; + + _end = _it; + + if (ch_ >= 0xd800 && ch_ <= 0xdbff) + { + const char_type surrogate_ = *++_end & 0xffff; + + ch_ = (((ch_ - 0xd800) << 10) | (surrogate_ - 0xdc00)) + 0x10000; + } + + _char = ch_; + ++_end; + } +}; + +template +class basic_utf16_out_iterator : + public std::iterator +{ +public: + typedef wchar_t value_type; + typedef typename std::iterator_traits:: + difference_type difference_type; + typedef std::forward_iterator_tag iterator_category; + + basic_utf16_out_iterator() : + _count(0), + _index(0) + { + } + + explicit basic_utf16_out_iterator(const char_iterator &it_, + const char_iterator &end_) : + _it(it_), + _count(0), + _index(0) + { + if (it_ != end_) + { + next(); + } + } + + wchar_t operator *() const + { + return _chars[_index]; + } + + bool operator ==(const basic_utf16_out_iterator &rhs_) const + { + return _it == rhs_._it; + } + + bool operator !=(const basic_utf16_out_iterator &rhs_) const + { + return _it != rhs_._it; + } + + basic_utf16_out_iterator &operator ++() + { + ++_index; + + if (_index >= _count) + { + ++_it; + next(); + } + + return *this; + } + + basic_utf16_out_iterator operator ++(int) + { + basic_utf16_out_iterator temp_ = *this; + + ++_index; + + if (_index >= _count) + { + ++_it; + next(); + } + + return temp_; + } + +private: + char_iterator _it; + wchar_t _chars[2]; + unsigned char _count; + unsigned char _index; + + void next() + { + const std::size_t ch_ = *_it; + + _count = len(ch_); + _index = 0; + + switch (_count) + { + case 1: + _chars[0] = static_cast(ch_); + break; + case 2: + _chars[0] = static_cast((ch_ >> 10) + 0xdc00u - + (0x10000 >> 10)); + _chars[1] = static_cast((ch_ & 0x3ff) + 0xdc00u); + break; + } + } + + char len(const std::size_t ch_) const + { + return ch_ > 0xffff ? 2 : 1; + } +}; +} + +#endif diff --git a/Puma/files.mk b/Puma/files.mk new file mode 100644 index 0000000..333ab19 --- /dev/null +++ b/Puma/files.mk @@ -0,0 +1,304 @@ +#------------------------------------------------- +# variables +#------------------------------------------------- + +ifneq ($(MINI),) + +# libMiniPuma subset of Puma + +SOURCES := \ + basics/DString.cc \ + basics/KeyboardSource.cc \ + basics/List.cc \ + basics/MemPool.cc \ + basics/Pipe.cc \ + basics/PipedCmd.cc \ + basics/RegComp.cc \ + basics/StrCol.cc \ + basics/StrHashTable.cc \ + basics/SysCall.cc \ + basics/TerminalSink.cc \ + basics/VerboseMgr.cc \ + basics/VoidPtrArray.cc \ + basics/WChar.cc + +SOURCES += \ + common/Config.cc \ + common/ErrorCollector.cc \ + common/ErrorSeverity.cc \ + common/ErrorSink.cc \ + common/ErrorStream.cc \ + common/FilenameInfo.cc \ + common/OptsParser.cc \ + common/PathInfo.cc \ + common/PathIterator.cc \ + common/PathManager.cc \ + common/SimpleParser.cc + +CSOURCES := + +ifeq ($(_TARGET),win32) +SOURCES += \ + basics/Heap.cc \ + win32/ptmalloc/sbrk.cc + +CSOURCES += \ + win32/ptmalloc/ptmalloc.c +endif + +DONTWEAVE := $(SOURCES) $(CSOURCES) + +else + +# full set of Puma source files + +ASPECTS := \ + aspects/CCExprResolveCC.ah \ + aspects/CCExprResolveH.ah \ + aspects/CExprResolveCC.ah \ + aspects/CExprResolveH.ah \ + parser/SyntaxState.ah \ + parser/SyntaxBuilder.ah \ + parser/LookAhead.ah \ + parser/cparser/CBuilderExtension.ah \ + parser/cparser/CLookAhead.ah \ + parser/cparser/CSemBinding.ah \ + parser/ccparser/CCBuilderExtension.ah \ + parser/ccparser/CCLookAhead.ah \ + parser/ccparser/CCSemBinding.ah + +SOURCES := \ + cpp/ImportHandler.cc \ + cpp/PreAnswer.cc \ + cpp/PreAssertionEvaluator.cc \ + cpp/PreMacro.cc \ + cpp/PreMacroExpander.cc \ + cpp/PreMacroManager.cc \ + cpp/PreParserState.cc \ + cpp/PrePredicate.cc \ + cpp/PrePredicateManager.cc \ + cpp/PrePrintVisitor.cc \ + cpp/PreTree.cc \ + cpp/PreTreeComposite.cc \ + cpp/PreFileIncluder.cc \ + cpp/PreprocessorParser.cc \ + common/OptsParser.cc \ + common/SimpleParser.cc \ + common/Config.cc \ + common/ErrorCollector.cc \ + common/ErrorSeverity.cc \ + common/ErrorSink.cc \ + common/ErrorStream.cc \ + common/FileUnit.cc \ + common/FilenameInfo.cc \ + common/PathInfo.cc \ + common/PathIterator.cc \ + common/PathManager.cc \ + common/Project.cc \ + common/Token.cc \ + common/TokenStream.cc \ + common/Unit.cc \ + common/MacroUnit.cc \ + common/UnitIterator.cc \ + common/UnitManager.cc \ + manip/ManipCommander.cc \ + manip/ManipController.cc \ + manip/Manipulators.cc \ + manip/RuleTable.cc \ + scanner/CScanner.cc \ + scanner/CLexer.cc \ + scanner/CCLexer.cc \ + basics/DString.cc \ + basics/KeyboardSource.cc \ + basics/List.cc \ + basics/MemPool.cc \ + basics/Pipe.cc \ + basics/PipedCmd.cc \ + basics/RegComp.cc \ + basics/StrCol.cc \ + basics/StrHashTable.cc \ + basics/SysCall.cc \ + basics/TerminalSink.cc \ + basics/VerboseMgr.cc \ + basics/VoidPtrArray.cc \ + basics/WChar.cc \ + basics/GPLHeader.cc \ + parser/ccparser/CCAssocScopes.cc \ + parser/ccparser/CCBuilder.cc \ + parser/ccparser/CCConvSeq.cc \ + parser/ccparser/CCConversion.cc \ + parser/ccparser/CCConversions.cc \ + parser/ccparser/CCNameLookup.cc \ + parser/ccparser/CCOverloading.cc \ + parser/ccparser/CCSemExpr.cc \ + parser/ccparser/CCSemVisitor.cc \ + parser/ccparser/CCSemantic.cc \ + parser/ccparser/CCSyntax.cc \ + parser/ccparser/instantiation/CCInstantiation.cc \ + parser/ccparser/instantiation/DeducedArgument.cc \ + parser/ccparser/instantiation/InstantiationCandidate.cc \ + parser/ccparser/instantiation/InstantiationParser.cc \ + parser/ccparser/instantiation/InstantiationSyntax.cc \ + parser/ccparser/instantiation/InstantiationSemantic.cc \ + parser/ccparser/instantiation/InstantiationTokenSource.cc \ + parser/ccparser/instantiation/InstantiationTokenProvider.cc \ + parser/cparser/CBuilder.cc \ + parser/cparser/CTree.cc \ + parser/cparser/CSemExpr.cc \ + parser/cparser/CSemDeclarator.cc \ + parser/cparser/CSyntax.cc \ + parser/cparser/CSemantic.cc \ + parser/cparser/CSemVisitor.cc \ + parser/cparser/CSemDeclSpecs.cc \ + parser/cparser/CProject.cc \ + parser/cparser/CPrintVisitor.cc \ + parser/cparser/CTranslationUnit.cc \ + parser/cparser/CUnit.cc \ + parser/cparser/Utf8.cc \ + parser/Syntax.cc \ + parser/Builder.cc \ + parser/CConstant.cc \ + parser/CVisitor.cc \ + parser/Parser.cc \ + parser/Semantic.cc \ + infos/CArgumentInfo.cc \ + infos/CAttributeInfo.cc \ + infos/CBaseClassInfo.cc \ + infos/CSemDatabase.cc \ + infos/CClassInfo.cc \ + infos/CEnumInfo.cc \ + infos/CEnumeratorInfo.cc \ + infos/CFunctionInfo.cc \ + infos/CFctInstance.cc \ + infos/CLabelInfo.cc \ + infos/CLocalScope.cc \ + infos/CMemberAliasInfo.cc \ + infos/CNamespaceInfo.cc \ + infos/CObjectInfo.cc \ + infos/CRecord.cc \ + infos/CScopeInfo.cc \ + infos/CSourceInfo.cc \ + infos/CStructure.cc \ + infos/CTemplateInfo.cc \ + infos/CTemplateInstance.cc \ + infos/CTemplateParamInfo.cc \ + infos/types/CTypeInfo.cc \ + infos/CTypedefInfo.cc \ + infos/CUnionInfo.cc \ + infos/CUsingInfo.cc + +CSOURCES := + +DONTWEAVE := \ + cpp/ImportHandler.cc \ + cpp/PreAnswer.cc \ + cpp/PreAssertionEvaluator.cc \ + cpp/PreMacro.cc \ + cpp/PreMacroExpander.cc \ + cpp/PreMacroManager.cc \ + cpp/PreParserState.cc \ + cpp/PrePredicate.cc \ + cpp/PrePredicateManager.cc \ + cpp/PreTree.cc \ + cpp/PreTreeComposite.cc \ + common/OptsParser.cc \ + common/Config.cc \ + common/SimpleParser.cc \ + common/ErrorCollector.cc \ + common/ErrorSeverity.cc \ + common/ErrorSink.cc \ + common/ErrorStream.cc \ + common/FileUnit.cc \ + common/FilenameInfo.cc \ + common/PathInfo.cc \ + common/PathIterator.cc \ + common/PathManager.cc \ + common/Project.cc \ + common/Token.cc \ + common/TokenStream.cc \ + common/Unit.cc \ + common/MacroUnit.cc \ + common/UnitIterator.cc \ + manip/ManipCommander.cc \ + manip/ManipController.cc \ + manip/Manipulators.cc \ + manip/RuleTable.cc \ + basics/DString.cc \ + basics/KeyboardSource.cc \ + basics/List.cc \ + basics/MemPool.cc \ + basics/Pipe.cc \ + basics/PipedCmd.cc \ + basics/RegComp.cc \ + basics/StrCol.cc \ + basics/StrHashTable.cc \ + basics/SysCall.cc \ + basics/TerminalSink.cc \ + basics/VerboseMgr.cc \ + basics/VoidPtrArray.cc \ + basics/WChar.cc \ + basics/GPLHeader.cc \ + parser/ccparser/CCAssocScopes.cc \ + parser/ccparser/CCConvSeq.cc \ + parser/ccparser/CCConversion.cc \ + parser/ccparser/CCConversions.cc \ + parser/ccparser/CCOverloading.cc \ + parser/ccparser/instantiation/CCInstantiation.cc \ + parser/ccparser/instantiation/DeducedArgument.cc \ + parser/ccparser/instantiation/InstantiationCandidate.cc \ + parser/ccparser/instantiation/InstantiationSemantic.cc \ + parser/ccparser/instantiation/InstantiationTokenSource.cc \ + parser/ccparser/instantiation/InstantiationTokenProvider.cc \ + parser/cparser/CSemDeclarator.cc \ + parser/cparser/CTranslationUnit.cc \ + parser/cparser/CUnit.cc \ + parser/cparser/Utf8.cc \ + parser/Builder.cc \ + parser/CConstant.cc \ + parser/CVisitor.cc \ + parser/Semantic.cc \ + infos/CArgumentInfo.cc \ + infos/CAttributeInfo.cc \ + infos/CBaseClassInfo.cc \ + infos/CClassInfo.cc \ + infos/CEnumInfo.cc \ + infos/CEnumeratorInfo.cc \ + infos/CFctInstance.cc \ + infos/CLabelInfo.cc \ + infos/CLocalScope.cc \ + infos/CMemberAliasInfo.cc \ + infos/CNamespaceInfo.cc \ + infos/CObjectInfo.cc \ + infos/CRecord.cc \ + infos/CScopeInfo.cc \ + infos/CSourceInfo.cc \ + infos/CStructure.cc \ + infos/CTemplateInfo.cc \ + infos/CTemplateInstance.cc \ + infos/CTemplateParamInfo.cc \ + infos/types/CTypeInfo.cc \ + infos/CTypedefInfo.cc \ + infos/CUnionInfo.cc \ + infos/CUsingInfo.cc + +LEMSOURCES := \ + cpp/PreExprParser.lem \ + cpp/PreParser.lem + +ifeq ($(_TARGET),win32) +SOURCES += \ + basics/Heap.cc \ + win32/ptmalloc/sbrk.cc + +CSOURCES += \ + win32/ptmalloc/ptmalloc.c +endif + +DONTWEAVE += \ + basics/Heap.cc \ + win32/ptmalloc/ptmalloc.c \ + win32/ptmalloc/sbrk.cc + +include extensions.mk + +endif diff --git a/Puma/src/Makefile b/Puma/src/Makefile new file mode 100644 index 0000000..bfb0f49 --- /dev/null +++ b/Puma/src/Makefile @@ -0,0 +1,71 @@ +ifeq ($(MAKELEVEL),0) +$(error Sorry, this makefile is not intended to be \ +used directly. Please use the makefile in the toplevel \ +directory of the PUMA source tree instead) +endif + +#------------------------------------------------- +# variables +#------------------------------------------------- + +AGXX ?= $(subst ac++,ag++,$(AC)) + +include $(ROOT)/vars.mk + +#------------------------------------------------- +# rules +#------------------------------------------------- + +all: weave compile_after_weave + +generate: config dirs + @+$(MAKE) -f generate.mk + +weave: generate + @+$(MAKE) -f weave.mk + +compile_after_weave: dirs weave + @+$(MAKE) -f compile.mk + +compile: dirs + @+$(MAKE) -f compile.mk + +dirs: + @mkdir -p $(OBJDIR) + @mkdir -p $(INCDIR) + @mkdir -p $(STEP1)/src + @mkdir -p $(STEP1)/dep + @mkdir -p $(STEP1)/aspects/Puma + @mkdir -p $(STEP1)/inc/Puma + @mkdir -p $(STEP2)/src + @mkdir -p $(STEP2)/dep + @mkdir -p $(STEP2)/inc/Puma + +config: +ifneq ($(ASPECTS),) + @echo "Generating ac++ config file..." + @mkdir -p $(dir $(CONFIG)) + @$(AGXX) --gen_config --c_compiler $(CXX) -o $(CONFIG) + @perl -i -pe "s/^-I [\"]?\.[\"]?$$//g" $(CONFIG) +endif + +clean: + @echo "Making sources clean..." + @rm -rf $(GENDIR) + +distclean: + @echo "Removing library, headers, and other generated files..." + @rm -rf $(LIBDIR) $(INCDIR) $(ROOT)/gen-* + +install: + # nothing to do for install + +dry: + @+$(MAKE) -f weave.mk showinfo + @+$(MAKE) -f compile.mk showinfo + +#------------------------------------------------- +# targets +#------------------------------------------------- + +.PHONY: all clean dirs generate weave compile dry install distclean config compile_after_weave diff --git a/Puma/src/aspects/CC1XTree.cc b/Puma/src/aspects/CC1XTree.cc new file mode 100644 index 0000000..0d2dd06 --- /dev/null +++ b/Puma/src/aspects/CC1XTree.cc @@ -0,0 +1,25 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CC1XTree.h" + +namespace Puma { + +const char *CT_StaticAssert::NodeId () { return "StaticAssert"; } + +} // namespace Puma diff --git a/Puma/src/aspects/CC1XTree.h b/Puma/src/aspects/CC1XTree.h new file mode 100644 index 0000000..9b5efbc --- /dev/null +++ b/Puma/src/aspects/CC1XTree.h @@ -0,0 +1,79 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CC1XTree_h__ +#define __CC1XTree_h__ + +#include "Puma/CTree.h" + +/** \file + * AspectC++ specific syntax tree classes. */ + +namespace Puma { + + +/** \class CT_StaticAssert CC1XTree.h Puma/CC1XTree.h + * Tree node representing a C++1X static_assert declaration. + * + * Example: + * + * \code + * static_assert(sizeof(long) > 4, "long is too long, haha") + * \endcode */ +class CT_StaticAssert : public CTree { + CTree *sons[6]; // static_assert, '(', const_expr, ',', cmpd_str, ')' + +public: + /** Constructor. + * \param sa The keyword 'static_assert'. + * \param op The opening bracket token. + * \param ce The constant expression. + * \param co The comma token. + * \param msg The error message. + * \param cl The closing bracket token. */ + CT_StaticAssert (CTree *sa, CTree *op, CTree *ce, CTree *co, CTree *msg, + CTree *cl) { + AddSon (sons[0], sa); AddSon (sons[1], op); + AddSon (sons[2], ce); AddSon (sons[3], co); + AddSon (sons[4], msg); AddSon (sons[5], cl); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 6; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 6, n); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 6, old_son, new_son); + } + /** Get the constant expression. */ + CT_Expression *Expr () const { return (CT_Expression*)sons[2]; } + /** Get the error message node. */ + CT_String *ErrorMessage () const { return (CT_String*) sons[4]; } +}; + +} // namespace Puma + +#endif /* __CC1XTree_h__ */ diff --git a/Puma/src/aspects/CCExprResolveCC.ah b/Puma/src/aspects/CCExprResolveCC.ah new file mode 100644 index 0000000..3b8ac6b --- /dev/null +++ b/Puma/src/aspects/CCExprResolveCC.ah @@ -0,0 +1,40 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CCExprResolveCC_ah__ +#define __CCExprResolveCC_ah__ + +// This aspect inserts resolve member functions into all syntax tree classes +// that represent expressions. As the function is virtual, an efficient +// run-time switch over the node type is implemented. + +#include "Puma/CCExprResolveH.ah" +#include "Puma/CCSemExpr.h" + +namespace Puma { + slice Puma::CTypeInfo *CCExprResolveCTree::resolve(Puma::CCSemExpr &sem_expr, Puma::CTree *base) { + return 0; + } +} + +slice Puma::CTypeInfo *Puma::CCExprResolveExpr::resolve(Puma::CCSemExpr &sem_expr, Puma::CTree *base) { + // this call is statically resolved with overload resolution, etc. + return sem_expr.resolve (this, base); +} + +#endif /* __CCExprResolveCC_ah__ */ diff --git a/Puma/src/aspects/CCExprResolveH.ah b/Puma/src/aspects/CCExprResolveH.ah new file mode 100644 index 0000000..ff5e707 --- /dev/null +++ b/Puma/src/aspects/CCExprResolveH.ah @@ -0,0 +1,48 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CCExprResolveH_ah__ +#define __CCExprResolveH_ah__ + +// This aspect inserts resolve member functions into all syntax tree classes +// that represent expressions. As the function is virtual, an efficient +// run-time switch over the node type is implemented. + +namespace Puma { + class CCSemExpr; +} + +namespace Puma { + slice class CCExprResolveCTree { + public: + virtual Puma::CTypeInfo *resolve(Puma::CCSemExpr &sem_expr, Puma::CTree *base); + }; + slice class CCExprResolveExpr { + public: + virtual Puma::CTypeInfo *resolve(Puma::CCSemExpr &sem_expr, Puma::CTree *base); + }; +} + +aspect CCExprResolve { + advice "Puma::CTree" : slice Puma::CCExprResolveCTree; + advice + derived ("Puma::CT_Expression"||"Puma::CT_SimpleName"||"Puma::CT_String") : + slice Puma::CCExprResolveExpr; +}; + +#endif /* __CCExprResolveH_ah__ */ diff --git a/Puma/src/aspects/CExprResolveCC.ah b/Puma/src/aspects/CExprResolveCC.ah new file mode 100644 index 0000000..53553d4 --- /dev/null +++ b/Puma/src/aspects/CExprResolveCC.ah @@ -0,0 +1,40 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CExprResolveCC_ah__ +#define __CExprResolveCC_ah__ + +// This aspect inserts resolve member functions into all syntax tree classes +// that represent expressions. As the function is virtual, an efficient +// run-time switch over the node type is implemented. + +#include "Puma/CExprResolveH.ah" +#include "Puma/CSemExpr.h" + +namespace Puma { + slice Puma::CTypeInfo *CExprResolveCTree::resolve(Puma::CSemExpr &sem_expr, Puma::CTree *base) { + return 0; + } +} + +slice Puma::CTypeInfo *Puma::CExprResolveExpr::resolve(Puma::CSemExpr &sem_expr, Puma::CTree *base) { + // this call is statically resolved with overload resolution, etc. + return sem_expr.resolve (this, base); +} + +#endif /* __CExprResolveCC_ah__ */ diff --git a/Puma/src/aspects/CExprResolveH.ah b/Puma/src/aspects/CExprResolveH.ah new file mode 100644 index 0000000..730e5e6 --- /dev/null +++ b/Puma/src/aspects/CExprResolveH.ah @@ -0,0 +1,48 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CExprResolveH_ah__ +#define __CExprResolveH_ah__ + +// This aspect inserts resolve member functions into all syntax tree classes +// that represent expressions. As the function is virtual, an efficient +// run-time switch over the node type is implemented. + +namespace Puma { + class CSemExpr; +} + +namespace Puma { + slice class CExprResolveCTree { + public: + virtual Puma::CTypeInfo *resolve(Puma::CSemExpr &sem_expr, Puma::CTree *base); + }; + slice class CExprResolveExpr { + public: + virtual Puma::CTypeInfo *resolve(Puma::CSemExpr &sem_expr, Puma::CTree *base); + }; +} + +aspect CExprResolve { + advice "Puma::CTree" : slice Puma::CExprResolveCTree; + advice + derived ("Puma::CT_Expression"||"Puma::CT_SimpleName"||"Puma::CT_String") : + slice Puma::CExprResolveExpr; +}; + +#endif /* __CExprResolveH_ah__ */ diff --git a/Puma/src/aspects/CMatchSyntax.ah b/Puma/src/aspects/CMatchSyntax.ah new file mode 100644 index 0000000..4ff4f03 --- /dev/null +++ b/Puma/src/aspects/CMatchSyntax.ah @@ -0,0 +1,599 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CMatchSyntax_ah__ +#define __CMatchSyntax_ah__ + +#include + +#include "Puma/CWildcardTokens.h" +#include "Puma/CTokens.h" +#include "Puma/StrCol.h" +#include "Puma/Config.h" + + +namespace Puma { + class CSyntax; + class CCSyntax; + class CBuilder; + class CSemantic; + class Container; + class CTree; + class CStrLiteral; + class CT_Any; + class CT_AnyList; + class CT_AnyExtension; + class CT_AnyCondition; + class CT_SimpleName; +} // namespace Puma + + +namespace Puma { + slice class CMatchCSyntax; + slice class CMatchCCSyntax; + slice class CMatchCBuilder; +} + +aspect CMatchSyntax { + pointcut csyntax () = "Puma::CSyntax"; + pointcut ccsyntax () = "Puma::CCSyntax"; + pointcut cbuilder () = "Puma::CBuilder"; + pointcut csemantic () = "Puma::CSemantic"; + +protected: + // flag to enable/disable parsing match expressions + bool match_expr; + +protected: + CMatchSyntax () : match_expr (false) {} + + // introduce wildcard rules to CSyntax and CCSyntax + advice csyntax () : slice Puma::CMatchCSyntax; + advice ccsyntax () : slice Puma::CMatchCCSyntax; + + // extend CBuilder + advice cbuilder () : slice Puma::CMatchCBuilder; + + // extend CSemantic + advice csemantic () : slice class { + public: + virtual CTree *wc_extension () { + Puma::CT_AnyExtension *ext = (Puma::CT_AnyExtension*)builder ().wc_extension (); + if (ext->String ()) { + char *name = Puma::StrCol::dup (ext->String ()->token ()->text ()); + name++; + name[strlen (name) - 1] = '\0'; + ext->SemValue ()->setValue (new Puma::CStrLiteral (name, strlen (name), 0)); + } + return ext; + } + }; + + // let first parse wildcards before parsing anything else + advice within (derived (csyntax ())) && + execution ("%::CTree * Puma::%::rule_trans_unit()") : around () { + if (match_expr && tjp->that ()->wildcards ()) + *tjp->result () = tjp->that ()->builder ().get_node (); + else + tjp->proceed (); + } + + // extend the syntax to parse ANYs + + advice within (derived (csyntax ())) && + execution ("%::CTree * Puma::%::rule_literal()") : around () { + if (match_expr && tjp->that ()->parse (Puma::TOK_ANY_EXPR)) { + tjp->that ()->wc_extension (); + *tjp->result () = tjp->that ()->builder ().any (); + } else + tjp->proceed (); + } + + advice within (derived (csyntax ())) && + execution ("%::CTree * Puma::%::rule_expr_list()") : around () { + if (match_expr && tjp->that ()->parse (Puma::TOK_ANY_EXPR_LIST)) { + tjp->that ()->wc_extension (); + *tjp->result () = tjp->that ()->builder ().any_list (); + } else + tjp->proceed (); + } + + advice within (derived (csyntax ())) && + execution ("%::CTree * Puma::%::rule_id_expr()") : around () { + if (match_expr && tjp->that ()->parse (Puma::TOK_ANY_ID_EXPR)) { + tjp->that ()->wc_extension (); + *tjp->result () = tjp->that ()->builder ().any (); + } else + tjp->proceed (); + } + + advice within (derived (csyntax ())) && + execution ("%::Puma::CTree * Puma::%::rule_identifier()") : around () { + if (match_expr && tjp->that ()->parse (Puma::TOK_ANY_IDENTIFIER)) { + tjp->that ()->wc_extension (); + *tjp->result () = tjp->that ()->builder ().any (); + } else + tjp->proceed (); + } + + advice within (derived (csyntax ())) && + execution ("bool Puma::%::init_decl_spec()") : after () { + tjp->that ()->_decl_spec_1.set (Puma::TOK_ANY_DECL_SPEC); + } + + advice within (derived (csyntax ())) && + execution ("%::Puma::CTree * Puma::%::rule_decl_spec()") : after () { + Puma::CTree *&result = *tjp->result (); + if (match_expr && !result && + tjp->that ()->parse (Puma::TOK_ANY_DECL_SPEC) && + tjp->that ()->wc_extension ()) { + result = tjp->that ()->builder().any (); + } + } + + advice within (derived (csyntax ())) && + execution ("%::Puma::CTree * Puma::%::rule_decl_spec_seq()") : around () { + if (match_expr && tjp->that ()->parse (Puma::TOK_ANY_DECL_SPEC_SEQ)) { + tjp->that ()->wc_extension (); + *tjp->result () = tjp->that ()->builder ().any_list (); + } else + tjp->proceed (); + } + + advice within (derived (csyntax ())) && + execution ("%::Puma::CTree * Puma::%::rule_init_declarator_list()") : around () { + if (match_expr && tjp->that ()->parse (Puma::TOK_ANY_INIT_DECLARATOR_LIST)) { + tjp->that ()->wc_extension (); + *tjp->result () = tjp->that ()->builder ().any_list (); + } else + tjp->proceed (); + } + + advice within (derived (csyntax ())) && + execution ("%::Puma::CTree * Puma::%::rule_init_declarator()") : around () { + if (match_expr && tjp->that ()->parse (Puma::TOK_ANY_INIT_DECLARATOR)) { + tjp->that ()->wc_extension (); + *tjp->result () = tjp->that ()->builder ().any (); + } else + tjp->proceed (); + } + + advice within (derived (csyntax ())) && + execution ("%::Puma::CTree * Puma::%::rule_declarator()") : around () { + if (match_expr && tjp->that ()->parse (Puma::TOK_ANY_DECLARATOR)) { + tjp->that ()->wc_extension (); + *tjp->result () = tjp->that ()->builder ().any (); + } else + tjp->proceed (); + } + + advice within (derived (csyntax ())) && + execution ("%::Puma::CTree * Puma::%::rule_init()") : around () { + if (match_expr && tjp->that ()->parse (Puma::TOK_ANY_INIT)) { + tjp->that ()->wc_extension (); + *tjp->result () = tjp->that ()->builder ().any (); + } else + tjp->proceed (); + } + + advice within (derived (csyntax ())) && + execution ("%::Puma::CTree * Puma::%::rule_arg_decl_seq()") : around () { + if (match_expr && tjp->that ()->parse (Puma::TOK_ANY_ARG_DECL_SEQ)) { + tjp->that ()->wc_extension (); + *tjp->result () = tjp->that ()->builder ().any_list (); + } else + tjp->proceed (); + } + + advice within (derived (csyntax ())) && + execution ("%::Puma::CTree * Puma::%::rule_fct_body()") : around () { + if (match_expr && tjp->that ()->parse (Puma::TOK_ANY_FCT_BODY)) { + tjp->that ()->wc_extension (); + *tjp->result () = tjp->that ()->builder ().any (); + } else + tjp->proceed (); + } + + advice within (derived (csyntax ())) && + execution ("%::Puma::CTree * Puma::%::rule_class_spec()") : around () { + if (match_expr && tjp->that ()->parse (Puma::TOK_ANY_CLASS_SPEC)) { + tjp->that ()->wc_extension (); + *tjp->result () = tjp->that ()->builder ().any (); + } else + tjp->proceed (); + } + + advice within (derived (csyntax ())) && + execution ("%::Puma::CTree * Puma::%::rule_member_spec()") : around () { + if (match_expr && tjp->that ()->parse (Puma::TOK_ANY_MEMBER_SPEC)) { + tjp->that ()->wc_extension (); + *tjp->result () = tjp->that ()->builder ().any_list (); + } else + tjp->proceed (); + } + + advice within (derived (csyntax ())) && + execution ("%::Puma::CTree * Puma::%::rule_member_decl()") : around () { + if (match_expr && tjp->that ()->parse (Puma::TOK_ANY_MEMBER_DECL)) { + tjp->that ()->wc_extension (); + *tjp->result () = tjp->that ()->builder ().any (); + } else + tjp->proceed (); + } + + advice within (derived (csyntax ())) && + execution ("%::Puma::CTree * Puma::%::rule_stmt()") : around () { + if (match_expr && tjp->that ()->parse (Puma::TOK_ANY_STMT)) { + tjp->that ()->wc_extension (); + *tjp->result () = tjp->that ()->builder ().any (); + } else + tjp->proceed (); + } + + advice within (derived (csyntax ())) && + execution ("%::Puma::CTree * Puma::%::rule_stmt_seq()") : around () { + if (match_expr && tjp->that ()->parse (Puma::TOK_ANY_STMT_SEQ)) { + tjp->that ()->wc_extension (); + *tjp->result () = tjp->that ()->builder ().any_list (); + } else + tjp->proceed (); + } + + advice within (derived (ccsyntax ())) && + execution ("%::Puma::CTree * Puma::%::rule_base_clause()") : around () { + if (match_expr && tjp->that ()->parse (Puma::TOK_ANY_BASE_CLAUSE)) { + tjp->that ()->wc_extension (); + *tjp->result () = tjp->that ()->builder ().any_list (); + } else + tjp->proceed (); + } + + advice within (derived (ccsyntax ())) && + execution ("%::Puma::CTree * Puma::%::rule_ctor_init()") : around () { + if (match_expr && tjp->that ()->parse (Puma::TOK_ANY_CTOR_INIT)) { + tjp->that ()->wc_extension (); + *tjp->result () = tjp->that ()->builder ().any (); + } else + tjp->proceed (); + } + + advice within (derived (ccsyntax ())) && + execution ("%::Puma::CTree * Puma::%::rule_mem_init()") : around () { + if (match_expr && tjp->that ()->parse (Puma::TOK_ANY_MEM_INIT)) { + tjp->that ()->wc_extension (); + *tjp->result () = tjp->that ()->builder ().any (); + } else + tjp->proceed (); + } + + // extend the syntax to be able to parse match trees + + advice within (derived (csyntax ())) && + execution ("%::Puma::CTree * Puma::%::rule_typedef_name()") : around () { + if (match_expr && tjp->that ()->parse (Puma::TOK_WC_IS_TYPEDEF)) { + *tjp->result () = + tjp->that ()->parse (Puma::TOK_ID) ? + tjp->that ()->builder ().is_name () : (Puma::CTree*)0; + } else + tjp->proceed (); + } + + advice within (derived (ccsyntax ())) && + execution ("%::Puma::CTree * Puma::%::rule_class_name()") : around () { + if (match_expr && tjp->that ()->parse (Puma::TOK_WC_IS_CLASS)) { + *tjp->result () = + tjp->that ()->parse (Puma::TOK_ID) ? + tjp->that ()->builder ().is_name () : (Puma::CTree*)0; + } else + tjp->proceed (); + } + + advice within (derived (ccsyntax ())) && + execution ("%::Puma::CTree * Puma::%::rule_enum_name()") : around () { + if (match_expr && tjp->that ()->parse (Puma::TOK_WC_IS_ENUM)) { + *tjp->result () = + tjp->that ()->parse (Puma::TOK_ID) ? + tjp->that ()->builder ().is_name () : (Puma::CTree*)0; + } else + tjp->proceed (); + } + + // configure parsing match expressions + + advice args (config) && within (derived ("Puma::Syntax")) && + execution ("void Puma::%::configure(...)") : before (Puma::Config &config) { + match_expr = (config.Option ("--match-expr")); + } +}; + +// introduce wildcard rules to CSyntax +slice class Puma::CMatchCSyntax { +public: + CTree * rule_wildcards (); + virtual bool wildcards (); + CTree * rule_wc_extension (); + virtual bool wc_extension (); + CTree * rule_wc_arguments (); + virtual bool wc_arguments (); + CTree * rule_wc_condition (); + virtual bool wc_condition (); + CTree * rule_wc_condition1 (); + virtual bool wc_condition1 (); + CTree * rule_wc_match (); + virtual bool wc_match (); + CTree * rule_wc_match_list (); + virtual bool wc_match_list (); + CTree * rule_wc_element (); + virtual bool wc_element (); +}; + +// introduce wildcard rules to CCSyntax +slice class Puma::CMatchCCSyntax { +public: + CTree * rule_wildcards (); + virtual bool wildcards (); +}; + +// extend CBuilder +slice class Puma::CMatchCBuilder { +public: + virtual Puma::CTree *any (); + virtual Puma::CTree *any_list (); + virtual Puma::CTree *is_name (); + virtual Puma::CTree *wildcards (); + virtual Puma::CTree *wc_extension (); + virtual Puma::CTree *wc_arguments (); + virtual Puma::CTree *wc_condition (); + virtual Puma::CTree *wc_condition1 (); + virtual Puma::CTree *wc_match (); + virtual Puma::CTree *wc_match_list (); + virtual Puma::CTree *wc_element (); +}; + +slice Puma::CTree *Puma::CMatchCSyntax::rule_wildcards () { + return (parse (Puma::TOK_DO_EXPR) ? expr () : + parse (Puma::TOK_DO_EXPR_LIST) ? expr_list () : + look_ahead (Puma::TOK_DO_ID_EXPR) ? consume () && id_expr () : + look_ahead (Puma::TOK_DO_IDENTIFIER) ? consume () && identifier () : + look_ahead (Puma::TOK_DO_DECL_SPEC) ? consume () && decl_spec () : + parse (Puma::TOK_DO_DECL_SPEC_SEQ) ? decl_spec_seq () : + parse (Puma::TOK_DO_INIT_DECLARATOR_LIST) ? init_declarator_list () : + parse (Puma::TOK_DO_INIT_DECLARATOR) ? init_declarator () : + parse (Puma::TOK_DO_DECLARATOR) ? declarator () : + parse (Puma::TOK_DO_INIT) ? init () : + parse (Puma::TOK_DO_ARG_DECL_SEQ) ? arg_decl_seq () : + parse (Puma::TOK_DO_FCT_BODY) ? fct_body () : + look_ahead (Puma::TOK_DO_CLASS_SPEC) ? consume () && class_spec () : + parse (Puma::TOK_DO_MEMBER_SPEC) ? member_spec () : + parse (Puma::TOK_DO_MEMBER_DECL) ? member_decl () : + parse (Puma::TOK_DO_STMT) ? stmt () : + parse (Puma::TOK_DO_STMT_SEQ) ? stmt_seq () : + false) ? + builder ().wildcards () : (Puma::CTree*)0; +} + +slice bool Puma::CMatchCSyntax::wildcards () { + return parse (&CMatchCSyntax::rule_wildcards); +} + +slice Puma::CTree *Puma::CMatchCCSyntax::rule_wildcards () { + bool DO_parsed = false; + if (parse (Puma::TOK_DO_BASE_CLAUSE) && (DO_parsed=true) ? + base_clause () : + parse (Puma::TOK_DO_CTOR_INIT) && (DO_parsed=true) ? + ctor_init () : + parse (Puma::TOK_DO_MEM_INIT) && (DO_parsed=true) ? + mem_init () : + false) + return builder ().wildcards (); + return ! DO_parsed ? + Puma::CSyntax::rule_wildcards () : (Puma::CTree*)0; +} + +slice bool Puma::CMatchCCSyntax::wildcards () { + return parse (&CMatchCCSyntax::rule_wildcards); +} + +slice Puma::CTree *Puma::CMatchCBuilder::wildcards () { + // ignore DO token und return parsed tree + delete get_node (0); + return get_node (1); +} + +slice Puma::CTree *Puma::CMatchCBuilder::any () { + if (nodes () == 1) + return new Puma::CT_Any (get_node (0)); + return new Puma::CT_Any (get_node (0), get_node (1)); +} + +slice Puma::CTree *Puma::CMatchCBuilder::any_list () { + if (nodes () == 1) + return new Puma::CT_AnyList (get_node (0)); + return new Puma::CT_AnyList (get_node (0), get_node (1)); +} + +slice Puma::CTree *Puma::CMatchCBuilder::is_name () { + delete get_node (0); + return new Puma::CT_SimpleName (get_node (1)); +} + +/*****************************************************************************/ +/* */ +/* wildcard rules */ +/* */ +/*****************************************************************************/ + +slice Puma::CTree *Puma::CMatchCSyntax::rule_wc_extension () { + return (parse (Puma::TOK_OPEN_ROUND) && + (wc_arguments (), parse (Puma::TOK_CLOSE_ROUND))) ? + semantic ().wc_extension () : (Puma::CTree*)0; +} + +slice bool Puma::CMatchCSyntax::wc_extension () { + return parse (&CMatchCSyntax::rule_wc_extension); +} + +slice Puma::CTree *Puma::CMatchCBuilder::wc_extension () { + if (nodes () == 2) + return new Puma::CT_AnyExtension (get_node (0), 0, 0, 0, get_node (1)); + else { + Puma::CTree *result; + Container *c = (Container*)get_node (1); + if (c->Sons () == 1) { + if (c->Son (0)->token ()->type () == Puma::TOK_STRING_VAL) + result = new Puma::CT_AnyExtension (get_node (0), c->Son (0), 0, 0, + get_node (2)); + else + result = new Puma::CT_AnyExtension (get_node (0), 0, 0, c->Son (0), + get_node (2)); + } else + result = new Puma::CT_AnyExtension (get_node (0), c->Son (0), c->Son (1), + c->Son (2), get_node (2)); + delete c; + return result; + } +} + +slice Puma::CTree *Puma::CMatchCSyntax::rule_wc_arguments () { + return (parse (Puma::TOK_STRING_VAL) ? + (parse (Puma::TOK_COMMA) ? wc_condition () : true) : + wc_condition ()) ? + builder ().wc_arguments () : (Puma::CTree*)0; +} + +slice bool Puma::CMatchCSyntax::wc_arguments () { + return parse (&CMatchCSyntax::rule_wc_arguments); +} + +slice Puma::CTree *Puma::CMatchCBuilder::wc_arguments () { + return container (); +} + +slice Puma::CTree *Puma::CMatchCSyntax::rule_wc_condition () { + static int ops[] = { Puma::TOK_WC_SEQ, Puma::TOK_WC_OR, Puma::TOK_WC_XOR, Puma::TOK_WC_AND, 0 }; + return list (&Puma::CSyntax::wc_condition1, ops) ? + builder ().wc_condition () : (Puma::CTree*)0; +} + +slice bool Puma::CMatchCSyntax::wc_condition () { + return parse (&CMatchCSyntax::rule_wc_condition); +} + +slice Puma::CTree *Puma::CMatchCBuilder::wc_condition () { + Puma::CTree *result = get_node (0); + for (int n = 1; n < nodes (); n += 2) + result = new Puma::CT_AnyCondition (result, get_node (n), get_node (n + 1)); + return result; +} + +slice Puma::CTree *Puma::CMatchCSyntax::rule_wc_condition1 () { + return (parse (Puma::TOK_WC_NOT) || parse (Puma::TOK_WC_COLLECT) ? + wc_condition () : + parse (Puma::TOK_WC_IF) ? + wc_condition () && + (parse (Puma::TOK_WC_ELIF) ? + wc_condition () : true) && + parse (Puma::TOK_WC_ENDIF) : + parse (Puma::TOK_WC_NODENAME) ? + parse (Puma::TOK_STRING_VAL) : + parse (Puma::TOK_OPEN_ROUND) ? + wc_condition () && parse (Puma::TOK_CLOSE_ROUND) : + wc_match ()) ? + builder ().wc_condition1 () : (Puma::CTree*)0; +} + +slice bool Puma::CMatchCSyntax::wc_condition1 () { + return parse (&CMatchCSyntax::rule_wc_condition1); +} + +slice Puma::CTree *Puma::CMatchCBuilder::wc_condition1 () { + if (nodes () == 1) + return get_node (); + if (nodes () == 2) + return new Puma::CT_AnyCondition (get_node (0), get_node (1)); + if (get_node ()->token ()->type () == Puma::TOK_OPEN_ROUND) + return new Puma::CT_AnyCondition (get_node (0), get_node (1), get_node (2)); + if (nodes () == 3) + return new Puma::CT_AnyCondition (get_node (0), get_node (1), get_node (2)); + return new Puma::CT_AnyCondition (get_node (0), get_node (1), + new Puma::CT_AnyCondition (get_node (2), get_node (3), get_node (4))); +} + +slice Puma::CTree *Puma::CMatchCSyntax::rule_wc_match () { + static int match_mode[] = { Puma::TOK_WC_EXACT, Puma::TOK_WC_FIRST, Puma::TOK_WC_LAST, + Puma::TOK_WC_LEAF, Puma::TOK_WC_PRUNE, 0 }; + return (wc_match_list (), parse (match_mode), wildcards ()) ? + builder ().wc_match () : (Puma::CTree*)0; +} + +slice bool Puma::CMatchCSyntax::wc_match () { + return parse (&CMatchCSyntax::rule_wc_match); +} + +slice Puma::CTree *Puma::CMatchCBuilder::wc_match () { + if (nodes () == 1) + return new Puma::CT_AnyCondition (get_node (0)); + if (nodes () == 2) + return new Puma::CT_AnyCondition (get_node (0), get_node (1)); + return new Puma::CT_AnyCondition (get_node (0), get_node (1), get_node (2)); +} + +slice Puma::CTree *Puma::CMatchCSyntax::rule_wc_match_list () { + return (parse (Puma::TOK_WC_ELEMENT) && + (parse (Puma::TOK_OPEN_ROUND) ? + (wc_element () ? + (parse (Puma::TOK_COMMA) ? + wc_element () : true) : true) && + parse (Puma::TOK_CLOSE_ROUND) : true)) ? + builder ().wc_match_list () : (Puma::CTree*)0; +} + +slice bool Puma::CMatchCSyntax::wc_match_list () { + return parse (&CMatchCSyntax::rule_wc_match_list); +} + +slice Puma::CTree *Puma::CMatchCBuilder::wc_match_list () { + if (nodes () == 1) + return new Puma::CT_AnyCondition (get_node (0)); + delete get_node (1); + delete get_node (nodes () - 1); + if (nodes () == 3) + return new Puma::CT_AnyCondition (get_node (0)); + if (nodes () == 4) + return new Puma::CT_AnyCondition (get_node (0), get_node (2)); + delete get_node (3); + return new Puma::CT_AnyCondition (get_node (0), get_node (2), get_node (4)); +} + +slice Puma::CTree *Puma::CMatchCSyntax::rule_wc_element () { + static int sign[] = { Puma::TOK_PLUS, Puma::TOK_MINUS, 0 }; + return (parse (sign), parse (Puma::TOK_INT)) ? + builder ().wc_element () : (Puma::CTree*)0; +} + +slice bool Puma::CMatchCSyntax::wc_element () { + return parse (&CMatchCSyntax::rule_wc_element); +} + +slice Puma::CTree *Puma::CMatchCBuilder::wc_element () { + if (nodes () == 1) + return new Puma::CT_AnyCondition (get_node (0)); + return new Puma::CT_AnyCondition (get_node (0), get_node (1)); +} + +#endif /* __CMatchSyntax_ah__ */ diff --git a/Puma/src/aspects/ExtAC.ah b/Puma/src/aspects/ExtAC.ah new file mode 100644 index 0000000..2dc4e68 --- /dev/null +++ b/Puma/src/aspects/ExtAC.ah @@ -0,0 +1,170 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __ext_ac_ah__ +#define __ext_ac_ah__ + +#include + +#include "Puma/CTokens.h" +#include "Puma/Syntax.h" +#include "Puma/CClassInfo.h" +#include "Puma/CFunctionInfo.h" +#include "Puma/CAttributeInfo.h" +#include "Puma/CArgumentInfo.h" +#include "Puma/CProtection.h" +#include "Puma/ACIntroducer.h" +#include "Puma/CCNameLookup.h" +#include "Puma/CProject.h" + +#include + +aspect ExtAC { + +protected: + + // ****************** + // C parser extension + // ****************** + pointcut parser () = "Puma::Parser"; + advice derived (parser ()) && !parser (): slice class { + public: + void introducer (Puma::ACIntroducer *i) { semantic ()._introducer = i; } + Puma::ACIntroducer *introducer () const { return semantic ()._introducer; } + }; + + // *************************** + // C and CC-Semantic extension + // *************************** + + pointcut csemantic () = "Puma::CSemantic"; + + advice csemantic () : slice class ACSemantic { + public: + Puma::ACIntroducer *_introducer; + private: + Puma::CStructure *_saved_scope; + + virtual void introduce_class_post (Puma::CT_ClassDef *cd); + }; + + pointcut ccsemantic () = "Puma::CCSemantic"; + + advice ccsemantic () : slice class ACCSemantic { + private: + virtual void introduce_class_post (Puma::CT_ClassDef *cd); + }; + + // initialize introduced attributes + advice construction (csemantic ()) : after () { + tjp->that ()->_introducer = 0; + } + + // extend the class handling + advice within (derived (csemantic ())) && + execution ("% ...::introduce_class(...)") : after () { + Puma::CT_ClassDef *cd = (Puma::CT_ClassDef*)*tjp->result (); + if (!cd) + return; + tjp->that ()->introduce_class_post (cd); + } + + // extend the class handling + advice call ("% ...::declareSpecialMembers()") && + within ("Puma::CTree *Puma::CCSemantic::class_spec()") : before () { + if (tjp->that ()->_introducer) { + Puma::CT_ClassDef *cd = (Puma::CT_ClassDef*) + tjp->that ()->current_scope->Structure ()->Tree (); + // enter introducer with well-defined protection stack + tjp->that ()->_protection.push (Puma::CProtection::PROT_PRIVATE); + // perform introduction and whatever the weave wants to do here + tjp->that ()->_introducer->class_end (cd); + // restore the old protection stack + tjp->that ()->_protection.pop (); + } + } + + // perform an additional check on base classes with aspects + advice within (derived (csemantic ())) && + execution ("% ...::add_base_classes(...)") : after () { + + // obtain the first argument + Puma::CT_ClassDef *cd = (Puma::CT_ClassDef*)*tjp->result(); + + // if necessary introduce base classes here + if (tjp->that ()->_introducer) { + tjp->that ()->_introducer->base_clause_end (cd, + tjp->that ()->syntax ().provider ()->current ()); + } + + // semantically handle introduced base classes + Puma::CT_BaseSpecList *bl = (Puma::CT_BaseSpecList*)cd->BaseIntros (); + if (cd->Object () && bl) { + int num = bl->Entries (); + for (int i = 0; i < num; i++) + tjp->that ()->addBaseClass (cd->Object ()->ClassInfo (), + (Puma::CT_BaseSpec*)bl->Entry (i)); + } + } + + // extend the translation unit handling -> finalization + advice within (derived (csemantic ())) && + execution ("% ...::trans_unit(...)") : after () { + if (tjp->that ()->_introducer) { + tjp->that ()->_introducer->trans_unit_end ((Puma::CT_Program*)*tjp->result ()); + } + } + + advice within (derived (csemantic ())) && + execution ("% ...::init(...)") : after () { + if (tjp->that ()->_introducer) { + tjp->that ()->_introducer->trans_unit_begin (); + } + } +}; + + +slice void ExtAC::ACSemantic::introduce_class_post (Puma::CT_ClassDef *cd) { + if (_introducer) { + // handle introductions before a class, they shall be parsed in global scope + Puma::CStructure *saved_scope = current_scope; + current_scope = _db->FileInfo (0); + _introducer->class_before (cd); + current_scope = saved_scope; + } +} + +slice void ExtAC::ACCSemantic::introduce_class_post (CT_ClassDef *cd) { + if (_introducer) { + // handle introductions before a class, they shall be parsed in global scope + Puma::CStructure *saved_scope = current_scope; + current_scope = _db->FileInfo (0); + _protection.push (Puma::CProtection::PROT_NONE); + _in_extern_decl.push (0); + CRecord* ocd = _outermost_class_def; + _outermost_class_def = 0; + _introducer->class_before (cd); + _outermost_class_def = ocd; + _in_extern_decl.pop (); + _protection.pop (); + current_scope = saved_scope; + } +} + + +#endif /* __ext_ac_h__ */ diff --git a/Puma/src/aspects/ExtACTree.ah b/Puma/src/aspects/ExtACTree.ah new file mode 100644 index 0000000..8dc6bd9 --- /dev/null +++ b/Puma/src/aspects/ExtACTree.ah @@ -0,0 +1,56 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __ExtACTree_ah__ +#define __ExtACTree_ah__ + +// TODO: +// this shall be introduced by the ExtAC aspect as soon as the include cycle +// problem is solved! + +namespace Puma { + class CTree; +} + +aspect ExtACTree { + pointcut members () = "Puma::CT_ClassDef"; + + // implemented in a separate .cc file, because Builder.h is needed! + void delete_tree (Puma::CTree *t); + + advice members () : slice class { + Puma::CTree *_intro_members; + Puma::CTree *_base_intros; + public: + Puma::CTree *IntroMembers () const { return _intro_members; } + void IntroMembers (Puma::CTree *members) { _intro_members = members; } + Puma::CTree *BaseIntros () const { return _base_intros; } + void BaseIntros (Puma::CTree *bases) { _base_intros = bases; } + }; + + advice construction (members ()) : after () { + tjp->that ()->_intro_members = 0; + tjp->that ()->_base_intros = 0; + } + advice destruction (members ()) : before () { + delete_tree (tjp->that ()->_intro_members); + delete_tree (tjp->that ()->_base_intros); + } +}; + +#endif // __ExtACTree_ah__ diff --git a/Puma/src/aspects/ExtACTree.cc b/Puma/src/aspects/ExtACTree.cc new file mode 100644 index 0000000..7332211 --- /dev/null +++ b/Puma/src/aspects/ExtACTree.cc @@ -0,0 +1,26 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/ExtACTree.ah" +#include "Puma/Builder.h" + +void ExtACTree::delete_tree (Puma::CTree *t) { + if (t) { + Puma::Builder::destroy (t); + } +} diff --git a/Puma/src/aspects/ExtCC1X.ah b/Puma/src/aspects/ExtCC1X.ah new file mode 100644 index 0000000..1920d6a --- /dev/null +++ b/Puma/src/aspects/ExtCC1X.ah @@ -0,0 +1,147 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __ext_cc1x_h__ +#define __ext_cc1x_h__ + +#include "Puma/Config.h" +#include "Puma/Lexer.h" +#include "Puma/Token.h" +#include "Puma/CTokens.h" + +namespace Puma { +slice class ExtCC1XSyntax; +slice class ExtCC1XBuilder; +slice class ExtCC1XSemantic; +} + +aspect ExtCC1X { + // flags to enable/disable certain C++1x features + bool _static_assert; + + // pointcut definitions + pointcut ccsyntax () = "Puma::CCSyntax"; + pointcut ccbuilder () = "Puma::CBuilder"; + pointcut ccsemantic () = "Puma::CCSemantic"; + + // ---------------------------------------------------- + // 'static_assert' + // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1720.html + // ---------------------------------------------------- + + // To clause 7, Declarations [dcl.dcl], paragraph 1, add an additional entry + // to block-declaration: + // + // static_assert-declaration + advice execution ("bool Puma::CCSyntax::BlockDecl::parse(...)") : after () { + // 1: static_assert_decl + JoinPoint::template Arg<0>::ReferredType &s = *tjp->arg<0>(); + bool &result = *tjp->result (); + if (_static_assert && !result && s.static_assert_decl ()) { + result = true; + } + } + + // To clause 9.2, Class members [class.mem], initial paragraph, add an + // additional entry to member-declaration + // + // static_assert-declaration + advice execution ("% Puma::CCSyntax::rule_member_decl()") : after () { + // 1: static_assert_decl + JoinPoint::Result &result = *tjp->result (); + if (_static_assert && !result && tjp->that ()->static_assert_decl ()) + result = tjp->that ()->builder ().member_decl(); + } + + + // To clause 7, Declarations [dcl.dcl], paragraph 1, add an additional + // outer level grammar element: + // + // static_assert-declaration: + // static_assert ( constant-expression , string-literal ) ; + advice ccsyntax() : slice Puma::ExtCC1XSyntax; + advice ccbuilder() : slice Puma::ExtCC1XBuilder; + advice ccsemantic() : slice Puma::ExtCC1XSemantic; + + // ---------------------------------------------------- + // get the configuration and check whether the C++1X mode is enabled + // ---------------------------------------------------- + + advice args (config) && within (derived ("Puma::Syntax")) && + execution ("void Puma::%::configure(...)"): before (Puma::Config &config) { + // check for the c++1x option, which enables *all* C++1X extensions + if (config.Option ("--c++1x")) { + _static_assert = true; + // ... more extensions to be implemented + } + + // these options can be explicitely set even without --c++1x + if (config.Option ("--c++1x-static-assert")) + _static_assert = true; + } + + + // ---------------------------------------------------- + // extend the scanner to recognize C++11 tokens + // ---------------------------------------------------- + + static const unsigned int _config_mask_cc1x = 4; + + advice "Puma::CScanner" : slice class { bool _config_cc1x; }; + + advice construction("Puma::CScanner") : after () { + tjp->that ()->_config_cc1x = false; + } + + advice args (config) && + execution("void Puma::CScanner::configure (...)"): + after (const Puma::Config &config) { + tjp->that()->_config_cc1x = _static_assert; + // check whether --c++1x was given and potentially enable C++1X keywords + if (config.Option ("--c++1x") || + config.Option ("--c++1x-static-assert")) { + tjp->that()->allow_cc1x (true); + tjp->that()->_config_cc1x = true; + } + } + + advice call ("% Puma::CCLexer::instance(...)") && + within ("Puma::CScanner"): before () { + if (tjp->that ()->_config_cc1x) + *tjp->arg<0>() |= _config_mask_cc1x; + } + + advice execution ("% Puma::CCLexer::add_keywords(...)") : after () { + if (tjp->that ()->_config_mask & _config_mask_cc1x) { + + lexertl::rules &rules = *tjp->arg<0>(); + + // C++1X keywords + rules.push ("static_assert", Puma::TOK_STATIC_ASSERT, LID(Puma::Token::keyword_id)); + } + } + +protected: + ExtCC1X () : _static_assert (false) {} + +public: + // interface for other extensions that include the static assert feature + void enable_static_assert (bool enable = true) { _static_assert = enable; } +}; + +#endif /* __ext_cc1x_h__ */ diff --git a/Puma/src/aspects/ExtCC1XBuilderCC.ah b/Puma/src/aspects/ExtCC1XBuilderCC.ah new file mode 100644 index 0000000..a92f504 --- /dev/null +++ b/Puma/src/aspects/ExtCC1XBuilderCC.ah @@ -0,0 +1,36 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __ext_cc1x_builder_cc_ah__ +#define __ext_cc1x_builder_cc_ah__ + +#include "Puma/ExtCC1XBuilderH.ah" +#include "Puma/CC1XTree.h" + +// *********************** +// C++1X-Builder extension +// *********************** + +slice +Puma::CTree *Puma::ExtCC1XBuilder::static_assert_decl () { + // 6: STATIC_ASSERT ( const_expr , cmpd_str ) + return new Puma::CT_StaticAssert(get_node (0), get_node(1), get_node (2), + get_node (3), get_node (4), get_node (5)); +} + +#endif /* __ext_cc1x_builder_cc_ah__ */ diff --git a/Puma/src/aspects/ExtCC1XBuilderH.ah b/Puma/src/aspects/ExtCC1XBuilderH.ah new file mode 100644 index 0000000..1618972 --- /dev/null +++ b/Puma/src/aspects/ExtCC1XBuilderH.ah @@ -0,0 +1,37 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __ext_cc1x_builder_h_ah__ +#define __ext_cc1x_builder_h_ah__ + +namespace Puma { + +// *********************** +// C++1X-Builder extension +// *********************** + +// new C++1X Builder member functions + +slice class ExtCC1XBuilder { +public: + virtual Puma::CTree *static_assert_decl (); +}; + +} // namespace Puma + +#endif /* __ext_cc1x_builder_h_ah__ */ diff --git a/Puma/src/aspects/ExtCC1XSemanticCC.ah b/Puma/src/aspects/ExtCC1XSemanticCC.ah new file mode 100644 index 0000000..dfaad30 --- /dev/null +++ b/Puma/src/aspects/ExtCC1XSemanticCC.ah @@ -0,0 +1,79 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __ext_cc1x_semantic_cc_ah__ +#define __ext_cc1x_semantic_cc_ah__ + +#include "Puma/ExtCC1XSemanticH.ah" +#include "Puma/CC1XTree.h" +#include "Puma/CCSemExpr.h" + +// ************************ +// C++1X-Semantic extension +// ************************ + +#ifndef HAVE_SEM_ERROR_MACROS +#define HAVE_SEM_ERROR_MACROS + +#define ASPECT_SEM_MSG(loc__,mesg__) \ + *_err << loc__->token ()->location () << mesg__ << endMessage + +#define ASPECT_SEM_ERROR(loc__,mesg__) \ + ASPECT_SEM_MSG (loc__, sev_error << mesg__) + +#define ASPECT_SEM_ERROR__duplicate(token__,type__,name__) \ + ASPECT_SEM_ERROR (token__, "duplicate " << type__ \ + << " `" << name__->Text () << "'") + +#endif // HAVE_SEM_ERROR_MACROS + +slice Puma::CTree *Puma::ExtCC1XSemantic::static_assert_decl () { + CT_StaticAssert *sa = (CT_StaticAssert*)builder ().static_assert_decl (); + // Ignore the static assertion if it depends on a template parameter + if (sa && sa->Expr () && !CCSemExpr::isDependent (sa->Expr())) { + // Check the expression type: + // The constant-expression shall be + // an integral constant expression (5.19 [expr.const]). + if (CCSemExpr::isConstIntegralExpr (sa->Expr ())) { + // If the value of the expression when converted to bool is true, + // the declaration has no effect. Otherwise, the program is ill-formed, + // causing the implementation to produce a diagnostic message + // (1.4 [intro.compliance]) that includes the text of the string-literal, + // except that characters not in the basic source character set + // (2.2 [lex.charset]) are not required to appear in the + // diagnostic message. + CCSemExpr::castToType (&CTYPE_BOOL, sa->Expr ()); + CExprValue *val = sa->Expr ()->Value (); + if (val && val->Constant () && sa->ErrorMessage ()) { + if (val->Constant ()->isNull ()) { + resolveExpr (sa->ErrorMessage ()); + CStrLiteral *msg = sa->ErrorMessage ()->Value ()->StrLiteral (); + if (msg) + ASPECT_SEM_ERROR(sa, "static assertion failed: " << msg->String ()); + } + } + else + ASPECT_SEM_ERROR(sa, "static assertion has invalid argument"); + } + else + ASPECT_SEM_ERROR(sa, "static assertion requires constant integral argument"); + } + return sa; +} + +#endif /* __ext_cc1x_semantic_cc_ah__ */ diff --git a/Puma/src/aspects/ExtCC1XSemanticH.ah b/Puma/src/aspects/ExtCC1XSemanticH.ah new file mode 100644 index 0000000..59ded46 --- /dev/null +++ b/Puma/src/aspects/ExtCC1XSemanticH.ah @@ -0,0 +1,36 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __ext_cc1x_semantic_h_ah__ +#define __ext_cc1x_semantic_h_ah__ + +namespace Puma { + +// ************************ +// C++1X-Semantic extension +// ************************ + +// new C++ Syntax member functions +slice class ExtCC1XSemantic { +public: + CTree *static_assert_decl (); +}; + +} // namespace Puma + +#endif /* __ext_cc1x_semantic_h_ah__ */ diff --git a/Puma/src/aspects/ExtCC1XSyntaxCC.ah b/Puma/src/aspects/ExtCC1XSyntaxCC.ah new file mode 100644 index 0000000..bcd61cc --- /dev/null +++ b/Puma/src/aspects/ExtCC1XSyntaxCC.ah @@ -0,0 +1,40 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __ext_cc1x_syntax_cc_ah__ +#define __ext_cc1x_syntax_cc_ah__ + +#include "Puma/ExtCC1XSyntaxH.ah" + +// ********************** +// C++1X-Syntax extension +// ********************** + +slice Puma::CTree *Puma::ExtCC1XSyntax::rule_static_assert_decl () { + return (parse (TOK_STATIC_ASSERT) && parse (TOK_OPEN_ROUND) && + const_expr () && parse(TOK_COMMA) && cmpd_str () && + parse (TOK_CLOSE_ROUND)) ? + semantic ().static_assert_decl () : (Puma::CTree*)0; +} + +slice bool Puma::ExtCC1XSyntax::static_assert_decl () { + return look_ahead (TOK_STATIC_ASSERT) && + parse (&ExtCC1XSyntax::rule_static_assert_decl); +} + +#endif /* __ext_cc1x_syntax_cc_ah__ */ diff --git a/Puma/src/aspects/ExtCC1XSyntaxH.ah b/Puma/src/aspects/ExtCC1XSyntaxH.ah new file mode 100644 index 0000000..52096a3 --- /dev/null +++ b/Puma/src/aspects/ExtCC1XSyntaxH.ah @@ -0,0 +1,37 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __ext_cc1x_syntax_h_ah__ +#define __ext_cc1x_syntax_h_ah__ + +namespace Puma { + +// ********************** +// C++1X-Syntax extension +// ********************** + +// new C++ Syntax member functions +slice class ExtCC1XSyntax { +protected: + CTree *rule_static_assert_decl (); + virtual bool static_assert_decl (); +}; + +} // namespace Puma + +#endif /* __ext_cc1x_syntax_h_ah__ */ diff --git a/Puma/src/aspects/ExtGnu.ah b/Puma/src/aspects/ExtGnu.ah new file mode 100644 index 0000000..31071d7 --- /dev/null +++ b/Puma/src/aspects/ExtGnu.ah @@ -0,0 +1,2820 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __ext_gnu_h__ +#define __ext_gnu_h__ + +#include +#include +#include +#include + +#include "Puma/GnuCTree.h" +#include "Puma/CFunctionInfo.h" +#include "Puma/CLabelInfo.h" +#include "Puma/CLocalScope.h" +#include "Puma/CSemVisitor.h" +#include "Puma/CSemDeclSpecs.h" +#include "Puma/PreMacro.h" +#include "Puma/PreMacroManager.h" +#include "Puma/Config.h" +#include "Puma/CConstant.h" +#include "Puma/TokenProvider.h" +#include "Puma/CLexer.h" + +#include "Puma/ExtGnuCSemDeclSpecs.ah" +#include "Puma/ExtGnuCInfos.ah" +#include "Puma/ExtGnuCSemantic.ah" +#include "Puma/ExtGnuCSemExpr.ah" + +namespace Puma { + class CCSyntax; + class CSyntax; +} + + +namespace Puma { + slice class ExtGnuAttributeSyntax; + slice class ExtGnuAttributeBuilder; + slice class ExtGnuAsmSyntax; + slice class ExtGnuAsmBuilder; + slice class ExtGnuLocalLabelStmtSyntax; + slice class ExtGnuLocalLabelStmtBuilder; + slice class ExtGnuTypeofSyntax; + slice class ExtGnuTypeofBuilder; + slice class ExtGnuTypeofSemantic; + slice class ExtGnuTypeofCCSemantic; + slice class ExtGnuBuiltinsSemantic; + slice class ExtGnuPIC24BuiltinsSemantic; + slice class ExtGnuStmtExprsBuilder; +} + +aspect ExtGnu { + + // flags to enable/disable certain Gnu features + bool extended_asm; + bool extended_cv_qual; + bool gnu_builtins; + bool std_hack; + bool typeof_keyword; + bool statement_exprs; + bool labels_as_values; + bool thread_local_storage_class; + bool friend_injection; + bool extern_inline; + bool pic24; + bool local_labels; + bool if_then_exprs; + bool case_ranges; + + // pointcut definitions + pointcut node () = "Puma::CT_AsmDef"; + pointcut syntax () = "Puma::CSyntax"; + pointcut builder () = "Puma::CBuilder"; + pointcut semantic () = "Puma::CSemantic"; + pointcut ccsemantic () = "Puma::CCSemantic"; + pointcut csemdeclspecs () = "Puma::CSemDeclSpecs"; + // TODO: shall we rely on the naming convention "is_%" here? + pointcut look_ahead_fcts () = "bool Puma::CSyntax::is_fct_def ()" || + "bool Puma::CSyntax::is_ass_expr ()" || + "bool Puma::CCSyntax::is_fct_def ()" || + "bool Puma::CCSyntax::is_nested_name ()" || + "bool Puma::CCSyntax::is_class_def ()" || + "bool Puma::CCSyntax::is_tpl_id ()" || + "bool Puma::CCSyntax::is_tpl_declarator_id ()" || + "bool Puma::CCSyntax::is_ptr_to_fct ()" || + "bool Puma::CCSyntax::is_nested (...)" || + "bool Puma::CCSyntax::is_ass_expr ()"; + + + // ---------------------------------------------------- + // the GNU 128-bit integer type + // ---------------------------------------------------- + + advice within (derived (syntax ())) && + execution ("% Puma::%::init_prim_types()") : after () { + tjp->that ()->_prim_types.set (Puma::TOK_INT128); + } + + // ---------------------------------------------------- + // the GNU extension keyword + // ---------------------------------------------------- + + // a helper function to collect extension keywords + template + void collect_extension_keywords (Syntax &s, std::list &nodes) { + while (s.parse (Puma::TOK_EXTENSION)) { + nodes.push_back (s.builder ().Top ()); + s.builder ().Pop (); + } + } + + // extended declarations and unary expressions => __extension__ before + advice call("bool Puma::CSyntax::BlockDecl::check (...)" || + "bool Puma::CCSyntax::BlockDecl::check (...)" || + "bool Puma::CSyntax::ForInitStmt::check (...)" || + "bool Puma::CCSyntax::NamespaceDef::check (...)" || + "bool Puma::CCSyntax::LinkageSpec::check (...)") : around () { + JoinPoint::template Arg<0>::ReferredType &s = *tjp->arg<0>(); + typedef Puma::CTree::CTreeList TL; + TL temp_prefix; + Puma::TokenProvider::State state = s.token_provider->get_state (); + collect_extension_keywords (s, temp_prefix); + tjp->proceed (); + bool discard = true; + if (*tjp->result ()) { + Puma::CTree *node = s.builder().Top(); + Puma::CTree::CTreeList *prefix = node->gnu_prefix (); + if (prefix) { + // copy the collected attributes as prefix into the + for (TL::iterator i = temp_prefix.begin (); i != temp_prefix.end (); ++i) + prefix->push_back (*i); + discard = false; + } + else if (temp_prefix.size () > 0) + std::cout << "no prefix memory on " << node->NodeName () << std::endl; + } + else + s.token_provider->set_state (state); + if (discard) { + for (TL::iterator i = temp_prefix.begin (); i != temp_prefix.end (); ++i) + s.builder ().destroy (*i); + } + } + + // extended unary expressions => __extension__ before + advice call("bool Puma::CSyntax::UnaryExpr::check (...)" || + "bool Puma::CCSyntax::UnaryExpr::check (...)") : around () { + JoinPoint::template Arg<0>::ReferredType &s = *tjp->arg<0>(); + typedef Puma::CTree::CTreeList TL; + TL temp_prefix; + Puma::TokenProvider::State state = s.token_provider->get_state (); + collect_extension_keywords (s, temp_prefix); + if (temp_prefix.size () > 0) + *tjp->result () = s.cast_expr (); + else + tjp->proceed (); + bool discard = true; + if (*tjp->result ()) { + Puma::CTree *node = s.builder().Top(); + Puma::CTree::CTreeList *prefix = node->gnu_prefix (); + if (prefix) { + // copy the collected attributes as prefix into the + for (TL::iterator i = temp_prefix.begin (); i != temp_prefix.end (); ++i) + prefix->push_back (*i); + discard = false; + } + else if (temp_prefix.size () > 0) + std::cout << "no prefix memory on " << node->NodeName () << std::endl; + } + else + s.token_provider->set_state (state); + if (discard) { + for (TL::iterator i = temp_prefix.begin (); i != temp_prefix.end (); ++i) + s.builder ().destroy (*i); + } + } + + // TODO: old-style syntax rule scheme => merge with code above + advice execution("% Puma::CSyntax::rule_member_decl ()" || + "% Puma::CCSyntax::rule_member_decl ()" || + "% Puma::CSyntax::fct_def ()" || + "% Puma::CCSyntax::fct_def ()" || + "% Puma::CCSyntax::explicit_specialization ()" || + "% Puma::CCSyntax::template_decl ()" || + "% Puma::CCSyntax::member_template_decl ()" || + "% Puma::CCSyntax::explicit_instantiation ()") : around () { + JoinPoint::That &s = *tjp->that(); + Puma::TokenProvider::State state = s.token_provider->get_state (); + typedef Puma::CTree::CTreeList TL; + TL temp_prefix; + collect_extension_keywords (s, temp_prefix); + tjp->proceed (); + bool discard = true; + if (*tjp->result ()) { + Puma::CTree *node = s.builder().Top(); + Puma::CTree::CTreeList *prefix = node->gnu_prefix (); + if (prefix) { + // copy the collected attributes as prefix into the + for (TL::iterator i = temp_prefix.begin (); i != temp_prefix.end (); ++i) + prefix->push_back (*i); + discard = false; + } + else if (temp_prefix.size () > 0) + std::cout << "no prefix memory on " << node->NodeName () << std::endl; + } + else + s.token_provider->set_state (state); + if (discard) { + for (TL::iterator i = temp_prefix.begin (); i != temp_prefix.end (); ++i) + s.builder ().destroy (*i); + } + } + + // let lookahead functions in the syntax classes igore extension keywords + advice call("Puma::Token *Puma::TokenProvider::current() const") && + within(look_ahead_fcts ()): after () { + while (*tjp->result () && (*tjp->result ())->type () == Puma::TOK_EXTENSION) { + tjp->that ()->skip (); + *tjp->result () = tjp->target ()->current (); + } + } + + // ---------------------------------------------------- + // the GNU attribute syntax + // ---------------------------------------------------- + + // structural extensions + advice syntax () : slice Puma::ExtGnuAttributeSyntax; + advice builder () : slice Puma::ExtGnuAttributeBuilder; + + // temporary store for collected attributes in infix nodes + std::list infix; + + // a helper function to collect attributes + template + void collect_attributes (Syntax &s, std::list &nodes, + bool asm_allowed = false) { + if (asm_allowed && s.gnu_asm_spec ()) { + nodes.push_back (s.builder ().Top ()); + s.builder ().Pop (); + } + while (s.look_ahead (Puma::TOK_ATTRIBUTE)) { + s.catch_gnu_attribute(); + nodes.push_back (s.builder ().Top ()); + s.builder ().Pop (); + } + } + + // extended init declarator syntax + advice call ("bool Puma::CSyntax::InitDeclarator1::check (...)") : after () { + if (!*tjp->result ()) + return; + JoinPoint::template Arg<0>::ReferredType &s = *tjp->arg<0>(); + Puma::CTree *node = s.builder().Top(); + Puma::CTree::CTreeList *infix = node->gnu_infix (); + if (!infix) { + std::cout << "no suffix memory on " << node->NodeName () << std::endl; + return; + } + collect_attributes (s, *infix, extended_asm); + } + + // attributes in member declarator + // TODO: old-style rule matched + advice call("bool Puma::CSyntax::Declarator::check (...)") && + within("Puma::CTree *Puma::CCSyntax::rule_member_declarator (...)" || + "Puma::CTree *Puma::CSyntax::rule_member_declarator (...)"): after () { + JoinPoint::That &s = *tjp->that(); + collect_attributes (s, infix, extended_asm); + } + + advice execution("Puma::CTree *Puma::CCSyntax::rule_member_declarator (...)" || + "Puma::CTree *Puma::CSyntax::rule_member_declarator (...)") : after () { + typedef Puma::CTree::CTreeList TL; + JoinPoint::That &s = *tjp->that(); + if (*tjp->result ()) { + if ((*tjp->result ())->gnu_infix ()) { + // attach the attribute nodes + for (TL::iterator i = infix.begin (); i != infix.end (); ++i) { + (*tjp->result ())->gnu_infix ()->push_back (*i); + } + } + } + else { + for (TL::iterator i = infix.begin (); i != infix.end (); ++i) + s.builder ().destroy (*i); + } + infix.clear (); + } + + // extended declarator in C++ condition + advice call("bool Puma::CSyntax::Declarator::check (...)") && + within("bool Puma::CCSyntax::Condition1::parse (...)"): after () { + if (*tjp->result ()) { + JoinPoint::template Arg<0>::ReferredType &s = *tjp->arg<0>(); + collect_attributes (s, infix); + } + } + + advice call("bool Puma::CCSyntax::Condition1::check (...)") : after () { + typedef Puma::CTree::CTreeList TL; + JoinPoint::template Arg<0>::ReferredType &s = *tjp->arg<0>(); + if (*tjp->result ()) { + Puma::CTree *node = s.builder().Top(); + if (node->gnu_infix ()) { + // attach the attribute nodes + for (TL::iterator i = infix.begin (); i != infix.end (); ++i) { + node->gnu_infix ()->push_back (*i); + } + } + } + else { + for (TL::iterator i = infix.begin (); i != infix.end (); ++i) + s.builder ().destroy (*i); + } + infix.clear (); + } + + // extended elaborated type specifiers + + // extended namespace definitions + // extended declaration specifier sequences => attributes after + // - attributes in front will be attached to the first specifier in the list + // extended enum specifiers: "(enum ... { ... } __attribute((foo))" + advice (call("bool Puma::CSyntax::Identifier::check (...)") && + within("bool Puma::CCSyntax::OriginalNsDef1::parse (...)")) || + (call("bool Puma::CCSyntax::OriginalNsName::check (...)") && + within("bool Puma::CCSyntax::ExtensionNsDef1::parse (...)")) || + (call("bool Puma::CSyntax::PrivateName::check (...)") && + within("bool Puma::CCSyntax::UnnamedNsDef1::parse (...)")) || + call("bool Puma::CSyntax::DeclSpecSeq::check (...)") || + call("bool Puma::CSyntax::EnumSpec::check (...)") : after () { + if (!*tjp->result ()) + return; + JoinPoint::template Arg<0>::ReferredType &s = *tjp->arg<0>(); + Puma::CTree *node = s.builder().Top(); + Puma::CTree::CTreeList *suffix = node->gnu_suffix (); + if (!suffix) { + std::cout << "no suffix memory on " << node->NodeName () << std::endl; + return; + } + collect_attributes (s, *suffix); + } + + // attributes after "enum", "class", "struct", or "union" + // extended using directives: "using namespace Foo __attribute__((strong));" + advice (call("bool Puma::CSyntax::ClassKey::check (...)" || + "bool Puma::CSyntax::EnumKey::check (...)") && + within("bool Puma::CSyntax::EnumSpec1::parse (...)" || + "bool Puma::CSyntax::ElaboratedTypeSpec::parse (...)" || + "bool Puma::CCSyntax::ElaboratedTypeSpec::parse (...)" || + "bool Puma::CSyntax::ClassHead::parse (...)" || + "bool Puma::CCSyntax::ClassHead1::parse (...)")) || + (call("bool Puma::CCSyntax::NamespaceName::check (...)") && + within("bool Puma::CCSyntax::UsingDirective::parse (...)")) : after () { + if (*tjp->result ()) { + JoinPoint::template Arg<0>::ReferredType &s = *tjp->arg<0>(); + collect_attributes (s, infix); + } + } + + advice call("bool Puma::CSyntax::EnumSpec1::check (...)" || + "bool Puma::CSyntax::ElaboratedTypeSpec::check (...)" || + "bool Puma::CCSyntax::ElaboratedTypeSpec::check (...)" || + "bool Puma::CSyntax::ClassHead::check (...)" || + "bool Puma::CCSyntax::ClassHead1::check (...)" || + "bool Puma::CCSyntax::UsingDirective::check (...)") : after () { + typedef Puma::CTree::CTreeList TL; + JoinPoint::template Arg<0>::ReferredType &s = *tjp->arg<0>(); + bool discard = true; + if (*tjp->result () && infix.size () > 0) { + if (s.builder ().Top()->gnu_infix ()) { + // attach the attribute nodes + for (TL::iterator i = infix.begin (); i != infix.end (); ++i) + ((Puma::CT_EnumDef*)s.builder ().Top())->gnu_infix ()->push_back (*i); + discard = false; + } + else { + std::cout << "no prefix memory on " << s.builder ().Top()->NodeName () << std::endl; + } + } + if (discard) { + for (TL::iterator i = infix.begin (); i != infix.end (); ++i) + s.builder ().destroy (*i); + } + infix.clear (); + } + + // extended declaration specifiers => attributes before + // extended conversion type ids => attributes before + // extended direct declarator => attributes before + advice call("bool Puma::CSyntax::DeclSpec::check (...)" || + "bool Puma::CSyntax::DirectDeclarator::check (...)" || + "bool Puma::CCSyntax::ConvTypeId::check (...)") : around () { + JoinPoint::template Arg<0>::ReferredType &s = *tjp->arg<0>(); + typedef Puma::CTree::CTreeList TL; + TL temp_prefix; + collect_attributes (s, temp_prefix); + tjp->proceed (); + bool discard = true; + if (*tjp->result ()) { + Puma::CTree *node = s.builder().Top(); + Puma::CTree::CTreeList *prefix = node->gnu_prefix (); + if (prefix) { + // copy the collected attributes as prefix into the + for (TL::iterator i = temp_prefix.begin (); i != temp_prefix.end (); ++i) + prefix->push_back (*i); + discard = false; + } + else { + std::cout << "no prefix memory on " << node->NodeName () << std::endl; + } + } + if (discard) { + for (TL::iterator i = temp_prefix.begin (); i != temp_prefix.end (); ++i) + s.builder ().destroy (*i); + } + } + + // extended parameter declarations + advice call("bool Puma::CSyntax::ParamDecl1::check (...)") : after () { + if (!*tjp->result ()) + return; + JoinPoint::template Arg<0>::ReferredType &s = *tjp->arg<0>(); + Puma::CTree *node = ((Puma::CT_ArgDecl*)s.builder().Top())->Declarator (); + Puma::CTree::CTreeList *suffix = node->gnu_suffix (); + if (!suffix) { + std::cout << "no suffix memory on " << node->NodeName () << std::endl; + return; + } + collect_attributes (s, *suffix); + } + + // extended labels + advice call("bool Puma::CSyntax::Stmt::check (...)") && + within("bool Puma::CSyntax::LabelStmt::parse (...)"): around () { + JoinPoint::template Arg<0>::ReferredType &s = *tjp->arg<0>(); + Puma::TokenProvider::State state = s.token_provider->get_state (); + typedef Puma::CTree::CTreeList TL; + TL temp_infix; + if (s.builder ().get_node (0)->IsSimpleName ()) + collect_attributes (s, temp_infix); + bool cplusplus = (s.grammar () == s.GRAMMAR_CPLUSPLUS); + bool undo = false; + if (cplusplus && !s.look_ahead (Puma::TOK_SEMI_COLON)) { + s.token_provider->set_state (state); + undo = true; + } + + tjp->proceed (); + + if (*tjp->result () && !undo) + infix = temp_infix; + else + undo = true; + + if (undo) { + for (TL::iterator i = temp_infix.begin (); i != temp_infix.end (); ++i) + s.builder().destroy (*i); + temp_infix.clear (); + } + } + + advice call("bool Puma::CSyntax::LabelStmt::check (...)") : after () { + JoinPoint::template Arg<0>::ReferredType &s = *tjp->arg<0>(); + if (!*tjp->result ()) + return; + typedef Puma::CTree::CTreeList TL; + if (s.builder ().Top()->gnu_infix ()) { + // attach the attribute nodes + for (TL::iterator i = infix.begin (); i != infix.end (); ++i) + ((Puma::CT_LabelStmt*)s.builder ().Top())->gnu_infix ()->push_back (*i); + } + else { +// normal: std::cout << "no infix memory on " << s.builder ().Top ()->NodeName () << std::endl; + for (TL::iterator i = infix.begin (); i != infix.end (); ++i) + s.builder().destroy (*i); + } + infix.clear (); + } + + // Make sure the print visitor regards this extension + + // handle gnu extension prefixes + advice execution("void Puma::CPrintVisitor::pre_visit (...)") && args (tree) : + before (Puma::CTree *tree) { + Puma::CTree *parent = tree->Parent (); + if (!parent) + return; + typedef Puma::CTree::CTreeList TL; + TL *tl = parent->gnu_prefix (); + if (tl && parent->Sons () > 0 && parent->Son(0) == tree) { + for (TL::iterator i = tl->begin (); i != tl->end (); ++i) + tjp->that ()->visit (*i); + } + } + + // handle infix and suffix extension + advice execution("void Puma::CPrintVisitor::post_visit (...)") && args (tree) : + after (Puma::CTree *tree) { + Puma::CTree *parent = tree->Parent (); + if (!parent) + return; + typedef Puma::CTree::CTreeList TL; + TL *tl = parent->gnu_infix (); + if (tl && parent->Sons () > parent->gnu_infix_pos () && + parent->Son(parent->gnu_infix_pos ()) == tree) { + for (TL::iterator i = tl->begin (); i != tl->end (); ++i) + tjp->that ()->visit (*i); + } + tl = parent->gnu_suffix (); + if (tl && parent->Sons () > 0 && parent->Son(parent->Sons () - 1) == tree) { + for (TL::iterator i = tl->begin (); i != tl->end (); ++i) + tjp->that ()->visit (*i); + } + } + + // let lookahead functions in the syntax classes igore attributes + advice call("Puma::Token *Puma::TokenProvider::current() const") && + within(look_ahead_fcts ()): after () { + while (*tjp->result () && (*tjp->result ())->type () == Puma::TOK_ATTRIBUTE) { + tjp->that ()->skip (); + tjp->that ()->skip_round_block (); + *tjp->result () = tjp->target ()->current (); + } + } + + // TODO: extend Builder::destroy in order to delete prefix or suffix sub-trees + + // ---------------------------------------------------- + // the GNU ASM syntax + // ---------------------------------------------------- + + // structural extensions + advice syntax () : slice Puma::ExtGnuAsmSyntax; + advice builder () : slice Puma::ExtGnuAsmBuilder; + + // extended asm statement + advice execution ("% Puma::CSyntax::asm_def()") : around () { + if (extended_asm) + *tjp->result () = tjp->that ()->gnu_asm_def (); + else + tjp->proceed (); + } + + // ---------------------------------------------------- + // redefinition of 'extern inline' functions + // ---------------------------------------------------- + + advice execution ("% Puma::CSemantic::isRedefinedFunction(...)") : around () { + // if previous function definition is declared 'extern inline' + // then it is no error to redefine it + Puma::CObjectInfo* fct = *tjp->arg<0>(); + if (extern_inline && fct->isExtern () && fct->isInline ()) + *(tjp->result ()) = false; + else + tjp->proceed (); + } + + // ---------------------------------------------------- + // the 'restrict' keyword + // ---------------------------------------------------- + + // extended cv qualifier + advice execution ("% Puma::CCSyntax::init_cv_quals()") : after () { + if (extended_cv_qual) + tjp->that ()->_cv_quals.set (Puma::TOK_RESTRICT); + } + + // ---------------------------------------------------- + // PIC24/dsPIC CV-qualifiers + // ---------------------------------------------------- + + // extended cv qualifier + advice execution ("% Puma::CCSyntax::init_cv_quals()" || + "% Puma::CSyntax::init_cv_quals()") : after () { + tjp->that ()->_cv_quals.set (Puma::TOK_PSV); + tjp->that ()->_cv_quals.set (Puma::TOK_PMP); + tjp->that ()->_cv_quals.set (Puma::TOK_EXTERNAL); + } + + // ------------------------- + // GNU statement expressions + // ------------------------- + + // pointcut definitions + pointcut csemexpr () = classes ("Puma::CSemExpr"); + pointcut ccsemexpr () = classes ("Puma::CCSemExpr"); + + // structural extensions + advice builder () : slice Puma::ExtGnuStmtExprsBuilder; + advice csemexpr () : slice Puma::ExtGnuStmtExprsCSemExpr; + advice ccsemexpr () : slice Puma::ExtGnuStmtExprsCCSemExpr; + + // extended primary expression syntax + advice execution ("bool Puma::CSyntax::PrimExpr::parse(...)") : around () { + JoinPoint::template Arg<0>::ReferredType &s = *tjp->arg<0>(); + if (statement_exprs && + s.look_ahead (Puma::TOK_OPEN_ROUND) && + s.look_ahead (Puma::TOK_OPEN_CURLY, 2)) { + s.consume (); + *tjp->result () = (s.cmpd_stmt () && s.parse (Puma::TOK_CLOSE_ROUND)); + } + else + tjp->proceed (); + } + + // extended primary expression syntax + advice within (derived (builder ())) && + execution ("% ...::prim_expr(...)") : around () { + if (statement_exprs && tjp->that ()->nodes () == 3 && + tjp->that ()->get_node (1)->NodeName () == Puma::CT_CmpdStmt::NodeId ()) + *tjp->result () = tjp->that ()->gnu_statement_expr (); + else + tjp->proceed (); + } + + // ------------------------------------ + // support for "local labels" extension + // ------------------------------------ + + // structural extensions + advice syntax () : slice Puma::ExtGnuLocalLabelStmtSyntax; + advice builder () : slice Puma::ExtGnuLocalLabelStmtBuilder; + advice semantic () : slice Puma::ExtGnuLocalLabelStmtSemantic; + advice "Puma::CFunctionInfo" : slice Puma::ExtGnuLocalLabelStmtInfo; + advice "Puma::CLabelInfo" : slice Puma::ExtGnuLocalLabelInfo; + + // extended syntax: "__label__ l1, l2;" -> allowed at beginning of compound statements + advice execution ("bool Puma::CSyntax::StmtSeq::parse(...)") || + execution ("bool Puma::CCSyntax::StmtSeq::parse(...)") : before () { + if (local_labels) { + JoinPoint::template Arg<0>::ReferredType &syntax = *tjp->arg<0>(); + while (syntax.look_ahead (Puma::TOK_LABEL)) { + syntax.gnu_local_label_stmt (); + } + } + } + + // semantic extension + advice execution("% Puma::CSyntax::GnuLocalLabelStmt::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().introduce_local_label(); + } + + advice execution("% Puma::CFunctionInfo::removeLabel (const Puma::CLabelInfo *)") : around () { + const Puma::CLabelInfo *info = *tjp->arg<0>(); + if (info->LocalScope ()) + tjp->that ()->unregisterLocalLabel (info->Name ().c_str (), info->LocalScope ()); + else + tjp->proceed (); + } + + advice execution("void Puma::CSemantic::introduce_label(Puma::CTree *&)") : around () { + if (!tjp->that ()->gnu_introduce_label (*tjp->arg<0>())) + tjp->proceed (); + } + + advice call("% Puma::CFunctionInfo::Label(const char *)") && + within("void ...::%CSemVisitor::check_goto_label(Puma::CTree*)" || + "% ...::%CSemExpr::resolveLabelAddr(...)") : around () { + *tjp->result () = tjp->target ()->findLocalLabel (*tjp->arg<0>(), tjp->that ()->current_scope, true); + if (*tjp->result ()) { + if (!(*tjp->result ())->Tree ()) // only *defined* (not only declared) local labels can be used! + *tjp->result () = 0; + } + else + tjp->proceed (); + } + + // ---------------------------------------- + // support for "labels as values" extension + // ---------------------------------------- + + // extended goto syntax + advice execution ("bool Puma::CSyntax::JumpStmt::parse(...)") || + execution ("bool Puma::CCSyntax::JumpStmt::parse(...)") : around () { + JoinPoint::template Arg<0>::ReferredType &syntax = *tjp->arg<0>(); + if (labels_as_values && + syntax.look_ahead (Puma::TOK_GOTO) && + syntax.look_ahead (Puma::TOK_MUL, 2)) { + syntax.consume (); // skip the 'goto' keyword + *tjp->result () = (syntax.expr () && + syntax.parse (Puma::TOK_SEMI_COLON)); + } + else + tjp->proceed (); + } + + // the address of a label + advice execution ("bool Puma::CSyntax::UnaryExpr::parse(...)") || + execution ("bool Puma::CCSyntax::UnaryExpr::parse(...)") : around () { + JoinPoint::template Arg<0>::ReferredType &s = *tjp->arg<0>(); + if (labels_as_values && s.look_ahead (Puma::TOK_AND_AND)) { + s.consume (); // consume the '&&' token, already checked + *tjp->result () = s.identifier (); + } + else + tjp->proceed (); + } + + advice within (derived (builder ())) && + execution ("% ...::unary_expr()") : around () { + if (labels_as_values && tjp->that ()->nodes () == 2 && + tjp->that ()->get_node (0)->NodeName () == Puma::CT_Token::NodeId () && + tjp->that ()->get_node (0)->token ()->type () == Puma::TOK_AND_AND) { + *tjp->result () = new Puma::CT_UnaryExpr (tjp->that ()->get_node (0), + tjp->that ()->get_node (1)); + } + else + tjp->proceed (); + } + + // extended semantic analysis + advice within ("Puma::%CSemVisitor") && + execution ("% ...::check_goto_label(...)") && + args (tree) : around (Puma::CTree *tree) { + if (tree->NodeName () == Puma::CT_SimpleName::NodeId ()) + tjp->proceed (); + else if (tree->NodeName () == Puma::CT_DerefExpr::NodeId ()) + tjp->that ()->resolveExpr (((Puma::CT_DerefExpr*)tree)->Expr (), tree); + } + + // label address has type void* + advice within ("Puma::%CSemExpr") && + execution ("% ...::resolve(Puma::CT_UnaryExpr *, Puma::CTree *)") : around () { + int oper = (*tjp->arg<0>())->token ()->type (); + if (oper == Puma::TOK_AND_AND && tjp->that ()->current_scope->LocalScope ()) { + *tjp->result () = tjp->that ()->resolveLabelAddr (*tjp->arg<0>()); + } + else + tjp->proceed (); + } + + // ---------------------------------------- + // Thread-local storage class (TLS) support + // ---------------------------------------- + + // extend storage class specifiers + advice within (derived (syntax ())) && + execution ("% Puma::%::init_storage_class_spec()") : after () { + if (thread_local_storage_class) + tjp->that ()->_storage_class_spec_1.set (Puma::TOK_THREAD); + } + + advice execution ("% Puma::CSyntax::StorageClassSpec::parse(...)") : after () { + JoinPoint::template Arg<0>::ReferredType &syntax = *tjp->arg<0>(); + bool &result = *tjp->result (); + if (typeof_keyword && !result) + result = syntax.parse (Puma::TOK_THREAD); + } + + // ---------------------- + // TYPEOF keyword support + // ---------------------- + + // structural extensions + advice syntax () : slice Puma::ExtGnuTypeofSyntax; + advice builder () : slice Puma::ExtGnuTypeofBuilder; + advice semantic () : slice Puma::ExtGnuTypeofSemantic; + advice ccsemantic () : slice Puma::ExtGnuTypeofCCSemantic; + + // introduce new state into CSemDeclSpecs + advice csemdeclspecs () : slice Puma::ExtGnuCSemDeclSpecs; + + // syntax extension + advice within (derived (syntax ())) && + execution ("% Puma::%::init_simple_type_spec()") : after () { + if (typeof_keyword) + tjp->that ()->_simple_type_spec_1.set (Puma::TOK_TYPEOF); + } + advice execution ("% Puma::CSyntax::SimpleTypeSpec::parse(...)") || + execution ("% Puma::CCSyntax::SimpleTypeSpec::parse(...)"): after () { + JoinPoint::template Arg<0>::ReferredType &syntax = *tjp->arg<0>(); + bool &result = *tjp->result (); + if (typeof_keyword && !result && syntax.look_ahead (Puma::TOK_TYPEOF)) + result = syntax.gnu_typeof (); + } + + // initialize the new state before an analysis starts + advice execution("bool Puma::%::analyze_seq()") && within (csemdeclspecs ()) && + that (csd) : before (Puma::CSemDeclSpecs &csd) { + csd._typeofs = 0; + csd._typeof_node = 0; + } + + // make the analysis function aware of 'typeof' + advice execution("bool Puma::%::analyze(...)") && within (csemdeclspecs ()) && + that (csd) && args (spec): after (Puma::CSemDeclSpecs &csd, Puma::CTree *spec) { + bool &result = *tjp->result (); + if (!result && spec->NodeName () == Puma::CT_GnuTypeof::NodeId ()) { + csd._typeofs++; + csd._typeof_node = (Puma::CT_GnuTypeof*)spec; + result = true; + } + } + + // make the check functions aware of 'typeof' + advice execution("bool Puma::%::check_complex_decl_specs(...)") && + within (csemdeclspecs ()) && that (csd) && args (have_type): + after (Puma::CSemDeclSpecs &csd, bool &have_type) { + bool &result = *tjp->result (); + if (result && !have_type && csd._typeofs) { + have_type = true; + result = true; + } + } + + advice execution("bool Puma::%::check_signed_unsigned()") && + within (csemdeclspecs ()) && that (csd) : after (Puma::CSemDeclSpecs &csd) { + bool &result = *tjp->result (); + if (result) { + if ((csd._prim_map[Puma::CT_PrimDeclSpec::PDS_SIGNED] || + csd._prim_map[Puma::CT_PrimDeclSpec::PDS_UNSIGNED]) && + csd._typeofs) { + *csd._err << Puma::sev_error << csd._dss->token ()->location () + << "`signed' or `unsigned' invalid for 'typeof'" + << Puma::endMessage; + result = false; + } + } + } + + advice execution("bool Puma::%::check_finally()") && + within (csemdeclspecs ()) && that (csd) : after (Puma::CSemDeclSpecs &csd) { + bool &result = *tjp->result (); + if (result && csd._typeofs > 0) { + *csd._err << Puma::sev_error << csd._dss->token ()->location () + << "invalid type specified in declaration" + << Puma::endMessage; + result = false; + } + } + + // make the type creation function aware of 'typeof' + advice execution("% Puma::%::create_type()") && within (csemdeclspecs ()) && + that (csd) : after (Puma::CSemDeclSpecs &csd) { + Puma::CTypeInfo *&result = *tjp->result (); + if (result->isUndefined () && csd._typeofs) { + csd._typeofs--; + if (csd._typeof_node->Type ()) { + Puma::CTypeInfo *arg_type = csd._typeof_node->Type (); + // in a template the argument type might be undefined + // -> set the node type to unknown_t, in order to make it 'dependent' + if (arg_type->isUndefined ()) + result = &Puma::CTYPE_UNKNOWN_T; + else + // otherwise copy the type + result = Puma::CTypeInfo::Duplicate (csd._typeof_node->Type ()); + } + } + } + + // ------------------------------------------ + // support for extended "if-then expressions" + // ------------------------------------------ + + // structural extensions + advice csemexpr () : slice Puma::ExtGnuCondExprCSemExpr; + + // extended syntax: "foo ? : bar" + advice call ("bool Puma::CSyntax::Expr::check(...)") && + within ("bool Puma::CSyntax::CondExpr::parse (...)") : around () { + JoinPoint::template Arg<0>::ReferredType &syntax = *tjp->arg<0>(); + if (if_then_exprs && syntax.look_ahead (Puma::TOK_COLON)) + *tjp->result () = true; + else + tjp->proceed (); + } + + advice within (derived (builder ())) && + execution ("% ...::cond_expr()") : around () { + if (if_then_exprs && tjp->that ()->nodes () == 4) { + *tjp->result () = new Puma::CT_IfThenExpr (tjp->that ()->get_node (0), + tjp->that ()->get_node (1), tjp->that ()->get_node (2), + tjp->that ()->get_node (3)); + } + else + tjp->proceed (); + } + + advice execution ("Puma::CTypeInfo *Puma::CSemExpr::resolve (Puma::CT_IfThenExpr *, Puma::CTree *)") : around () { + if (!(*tjp->arg<0>())->LeftOperand ()) + *tjp->result () = tjp->that ()->resolve_gnu (*tjp->arg<0>(), *tjp->arg<1>()); + else + tjp->proceed (); + } + + // ----------------------------------- + // support for "case ranges" extension + // ----------------------------------- + + // extended syntax: "case 10 ... 20 : bar=open;" + advice call ("bool Puma::CSyntax::ConstExpr::check(...)") && + within ("bool Puma::CSyntax::LabelStmt::parse (...)") : around () { + JoinPoint::template Arg<0>::ReferredType &syntax = *tjp->arg<0>(); + tjp->proceed (); + if (*tjp->result () && case_ranges && syntax.look_ahead (Puma::TOK_ELLIPSIS)) { + *tjp->result () = (syntax.parse (Puma::TOK_ELLIPSIS) && syntax.const_expr ()); + } + } + + advice within (derived (builder ())) && + execution ("% ...::label_stmt()") : around () { + // 5: identifier ... identifier : stmt + if (case_ranges && tjp->that ()->nodes () == 6) { + *tjp->result () = new Puma::CT_GnuCaseStmt (tjp->that ()->get_node (0), + tjp->that ()->get_node (1), tjp->that ()->get_node (2), + tjp->that ()->get_node (3), tjp->that ()->get_node (4), + tjp->that ()->get_node (5)); + } + else + tjp->proceed (); + } + + // ---------------------- + // GNU builtin functions + // ---------------------- + + advice within (derived (builder ())) && + execution ("% ...::cond_expr()") : around () { + if (if_then_exprs && tjp->that ()->nodes () == 4) { + *tjp->result () = new Puma::CT_IfThenExpr (tjp->that ()->get_node (0), + tjp->that ()->get_node (1), tjp->that ()->get_node (2), + tjp->that ()->get_node (3)); + } + else + tjp->proceed (); + } + + // structural extensions + advice semantic () : slice Puma::ExtGnuBuiltinsSemantic; + advice semantic () : slice Puma::ExtGnuPIC24BuiltinsSemantic; + + advice within (semantic ()) && execution ("void Puma::%::declareImplicitFcts()") : + after () { + if (gnu_builtins) { + tjp->that ()->define_gnu_builtins (); + if (pic24) + tjp->that ()->define_gnu_pic24_builtins (); + } + } + + // C implicit constant expressions + advice execution ("% Puma::CSemExpr::resolve(Puma::CT_CallExpr *, Puma::CTree *)") : after () { + Puma::CT_CallExpr *call = (*tjp->arg<0>()); + Puma::CObjectInfo *fct = call->Object (); + if (fct && fct->Name().c_str() && strncmp(fct->Name().c_str(), "__builtin_", 10) == 0) { + Puma::CT_ExprList *args = call->Arguments(); + if (strcmp(fct->Name(), "__builtin_types_compatible_p") == 0) { + if (args && args->Entries() == 2) { + Puma::U_LONG_LONG v = tjp->that ()->compatible(args->Entry(0)->Type(), args->Entry(1)->Type()) ? 1 : 0; + call->setValue(new Puma::CConstant(v, call->Type())); + } + } else if (strcmp(fct->Name(), "__builtin_constant_p") == 0) { + if (args && args->Entries() == 1) { + Puma::U_LONG_LONG v = tjp->that ()->isConstExpr(args->Entry(0)) ? 1 : 0; + call->setValue(new Puma::CConstant(v, call->Type())); + } + } else if (strcmp(fct->Name(), "__builtin_huge_val") == 0 || + strcmp(fct->Name(), "__builtin_huge_valf") == 0 || + strcmp(fct->Name(), "__builtin_huge_vall") == 0 || + strcmp(fct->Name(), "__builtin_inf") == 0 || + strcmp(fct->Name(), "__builtin_infd32") == 0 || + strcmp(fct->Name(), "__builtin_infd64") == 0 || + strcmp(fct->Name(), "__builtin_infd128") == 0 || + strcmp(fct->Name(), "__builtin_inff") == 0 || + strcmp(fct->Name(), "__builtin_infl") == 0) { + call->setValue(new Puma::CConstant((long double)DBL_MAX, call->Type())); + } + } + } + + // C++ implicit constant expressions + advice execution ("% Puma::CCSemExpr::resolve(Puma::CT_CallExpr *, Puma::CTree *)") : after () { + Puma::CT_CallExpr *call = (*tjp->arg<0>()); + Puma::CObjectInfo *fct = call->Object (); + if (fct && fct->Name().c_str() && strncmp(fct->Name().c_str(), "__builtin_", 10) == 0) { + Puma::CT_ExprList *args = call->Arguments(); + if (strcmp(fct->Name(), "__builtin_constant_p") == 0) { + if (args && args->Entries() == 1) { + Puma::U_LONG_LONG v = tjp->that ()->isConstExpr(args->Entry(0)) ? 1 : 0; + call->setValue(new Puma::CConstant(v, call->Type())); + } + } else if (strcmp(fct->Name(), "__builtin_huge_val") == 0 || + strcmp(fct->Name(), "__builtin_huge_valf") == 0 || + strcmp(fct->Name(), "__builtin_huge_vall") == 0 || + strcmp(fct->Name(), "__builtin_inf") == 0 || + strcmp(fct->Name(), "__builtin_infd32") == 0 || + strcmp(fct->Name(), "__builtin_infd64") == 0 || + strcmp(fct->Name(), "__builtin_infd128") == 0 || + strcmp(fct->Name(), "__builtin_inff") == 0 || + strcmp(fct->Name(), "__builtin_infl") == 0) { + call->setValue(new Puma::CConstant((long double)DBL_MAX, call->Type())); + } + } + } + + // ---------------------------------------------------- + // std hack: if a lookup in 'std' fails, look into '::' + // ---------------------------------------------------- + + advice execution ("% Puma::CCNameLookup::lookup(%::CStructure *,bool,bool)") : + before () { + if (std_hack) { + Puma::CStructure *&scope = *(Puma::CStructure**)tjp->arg (0); + bool &nested = *(bool*)tjp->arg (1); + if (scope->Parent ()->GlobalScope () && + strcmp (scope->Name (), "std") == 0) + nested = true; + } + } + + // ---------------------------------------------------- + // friend injection of GCC before version 4.1 + // ---------------------------------------------------- + + advice execution ("% Puma::CCNameLookup::invisibleFriend(...)") : around () { + if (friend_injection) + *tjp->result () = false; // friends are always visible + else + tjp->proceed (); + } + + // ---------------------------------------------------- + // get the configuration and check whether the GNU mode is enabled + // ---------------------------------------------------- + + bool get_gnu_version (const Puma::Config &config, + int &major, int &minor, int &patchlevel) { + const Puma::ConfOption *gnu_option = config.Option ("--gnu"); + if (!gnu_option) + return false; + major = -1; + minor = -1; + patchlevel = -1; + const char *gnu_version_str = + (gnu_option->Arguments() == 1) ? gnu_option->Argument (0) : 0; + if (gnu_version_str) { + char sep; + std::istringstream in (gnu_version_str); + if (in.good()) in >> major; + if (in.good()) in >> sep >> minor; + if (in.good()) in >> sep >> patchlevel; + } + return true; + } + + long int parse_size(const char* sizestr) { + long int size = 0; + std::istringstream in(sizestr); + in >> size; + return size * 8; // size in bits + } + + void adjust_primitive_type_sizes(const Puma::Config &config) { + unsigned num = config.Options(); + for (unsigned i = 0; i < num; i++) { + const Puma::ConfOption *o = config.Option(i); + if (o->Arguments() == 2 && strcmp(o->Name(), "-D") == 0) { + const char* macroName = o->Argument(0); + if (strncmp(macroName, "__SIZEOF_", 9) != 0) + continue; + + if (strcmp(macroName, "__SIZEOF_BOOL__") == 0) { + Puma::CTYPE_BOOL.Size(parse_size(o->Argument(1))); + Puma::CTYPE_C_BOOL.Size(Puma::CTYPE_BOOL.Size()); + } else if (strcmp(macroName, "__SIZEOF_CHAR__") == 0) { + Puma::CTYPE_CHAR.Size(parse_size(o->Argument(1))); + Puma::CTYPE_SIGNED_CHAR.Size(Puma::CTYPE_CHAR.Size()); + Puma::CTYPE_UNSIGNED_CHAR.Size(Puma::CTYPE_CHAR.Size()); + } else if (strcmp(macroName, "__SIZEOF_WCHAR_T__") == 0) { + Puma::CTYPE_WCHAR_T.Size(parse_size(o->Argument(1))); + } else if (strcmp(macroName, "__SIZEOF_SHORT__") == 0) { + Puma::CTYPE_SHORT.Size(parse_size(o->Argument(1))); + Puma::CTYPE_UNSIGNED_SHORT.Size(Puma::CTYPE_SHORT.Size()); + } else if (strcmp(macroName, "__SIZEOF_INT__") == 0) { + Puma::CTYPE_INT.Size(parse_size(o->Argument(1))); + Puma::CTYPE_UNSIGNED_INT.Size(Puma::CTYPE_INT.Size()); + } else if (strcmp(macroName, "__SIZEOF_LONG__") == 0) { + Puma::CTYPE_LONG.Size(parse_size(o->Argument(1))); + Puma::CTYPE_UNSIGNED_LONG.Size(Puma::CTYPE_LONG.Size()); + } else if (strcmp(macroName, "__SIZEOF_LONG_LONG__") == 0) { + Puma::CTYPE_LONG_LONG.Size(parse_size(o->Argument(1))); + Puma::CTYPE_UNSIGNED_LONG_LONG.Size(Puma::CTYPE_LONG_LONG.Size()); + } else if (strcmp(macroName, "__SIZEOF_FLOAT__") == 0) { + Puma::CTYPE_FLOAT.Size(parse_size(o->Argument(1))); + } else if (strcmp(macroName, "__SIZEOF_DOUBLE__") == 0) { + Puma::CTYPE_DOUBLE.Size(parse_size(o->Argument(1))); + } else if (strcmp(macroName, "__SIZEOF_LONG_DOUBLE__") == 0) { + Puma::CTYPE_LONG_DOUBLE.Size(parse_size(o->Argument(1))); + } + } + } + } + + advice args (config) && within (derived ("Puma::Syntax")) && + execution ("void Puma::%::configure(...)"): before (Puma::Config &config) { + int gnu_major, gnu_minor, gnu_patchlevel; + // call get_gnu_version to check whether --gnu was given + if (get_gnu_version (config, gnu_major, gnu_minor, gnu_patchlevel)) { + // settings for all gcc dialects + extended_asm = true; + extended_cv_qual = true; + gnu_builtins = true; + typeof_keyword = true; + statement_exprs = true; + local_labels = true; + if_then_exprs = !config.Option("--lang-c++"); // TODO: not supported in C++ mode, yet + labels_as_values = true; + extern_inline = true; + thread_local_storage_class = true; + case_ranges = true; + pic24 = false; // not enabled by default + + if (gnu_major >= 0 && gnu_major < 3) { + std_hack = true; + friend_injection = true; + } + + adjust_primitive_type_sizes(config); + } + // these options can be explicitely set even without --gnu + if (config.Option ("--gnu-extended-asm")) + extended_asm = true; + if (config.Option ("--gnu-std-hack")) + std_hack = true; + if (config.Option ("--gnu-friend-injection")) + friend_injection = true; + if (config.Option ("--gnu-pic24")) + pic24 = true; + } + + // -------------------------------------------------- + // support for unnamed and empty struct/union members + // -------------------------------------------------- + + advice execution ("% Puma::CSyntax::rule_member_decl()") : around () { + // 1: ; + // 2: type_spec_seq ; + // 3: type_spec_seq member_declarator_list ; + Puma::CTree *&result = *(Puma::CTree**)tjp->result (); + if (tjp->that ()->parse (Puma::TOK_SEMI_COLON) || + (tjp->that ()->type_spec_seq () && + tjp->that ()->opt(tjp->that ()->member_declarator_list ()) && + tjp->that ()->parse (Puma::TOK_SEMI_COLON))) { + tjp->that ()->semantic ().finish_decl (); + result = tjp->that ()->builder ().member_decl (); + } else { + result = (Puma::CTree*)0; + } + } + + // -------------------------------------------------- + // GNU defined macros + // -------------------------------------------------- + + advice execution ("void Puma::PreprocessorParser::defineGNUMacros()") : after () { + // GNU defines + tjp->that ()->defUndefinedMacro ("__GNUC__", "2"); + tjp->that ()->defUndefinedMacro ("__GNUC_MINOR__", "8"); + tjp->that ()->defUndefinedMacro ("_GLIBCPP_EXTERN_TEMPLATE", "0"); + tjp->that ()->defUndefinedMacro ("__null", "0"); +// tjp->that ()->defUndefinedMacro ("__extension__", " "); + //tjp->that ()->defUndefinedMacro ("_WCHAR_T_", " "); + // attributes + if (! tjp->that ()->_macroManager->getMacro ("__attribute__")) { + Puma::PreMacro *macro = new Puma::PreMacro ("__attribute__", " ", Puma::PreMacro::LOCK_MACRO); + macro->addArg ("par1"); + tjp->that ()->_macroManager->addMacro (macro); + } + if (! tjp->that ()->_macroManager->getMacro ("__attribute")) { + Puma::PreMacro *macro = new Puma::PreMacro ("__attribute", " ", Puma::PreMacro::LOCK_MACRO); + macro->addArg ("par1"); + tjp->that ()->_macroManager->addMacro (macro); + } + // variable argument list access + if (! tjp->that ()->_macroManager->getMacro ("__builtin_va_arg")) { + Puma::PreMacro *macro = new Puma::PreMacro ("__builtin_va_arg", "((par2)__builtin_va_arg_helper(par1))"); + macro->addArg ("par1"); + macro->addArg ("par2"); + tjp->that ()->_macroManager->addMacro (macro); + } + + // atomic memory access built-in functions + + // #define __sync_...(arg,...) *(typeof(arg))__generic_sync_...(arg, ## __VA_ARGS__) + #define __puma_defSyncMacro(opname) \ + if (! tjp->that ()->_macroManager->getMacro ("__sync_" opname)) { \ + Puma::PreMacro *macro = new Puma::PreMacro ("__sync_" opname, \ + "*(typeof(par1))__generic_sync_" opname "(par1, ## __VA_ARGS__)", \ + Puma::PreMacro::VAR_ARG_MACRO); \ + macro->addArg ("par1"); \ + macro->addArg ("__VA_ARGS__"); \ + tjp->that ()->_macroManager->addMacro (macro); \ + } + __puma_defSyncMacro("fetch_and_add"); + __puma_defSyncMacro("fetch_and_sub"); + __puma_defSyncMacro("fetch_and_or"); + __puma_defSyncMacro("fetch_and_and"); + __puma_defSyncMacro("fetch_and_xor"); + __puma_defSyncMacro("fetch_and_nand"); + __puma_defSyncMacro("add_and_fetch"); + __puma_defSyncMacro("sub_and_fetch"); + __puma_defSyncMacro("or_and_fetch"); + __puma_defSyncMacro("and_and_fetch"); + __puma_defSyncMacro("xor_and_fetch"); + __puma_defSyncMacro("nand_and_fetch"); + __puma_defSyncMacro("val_compare_and_swap"); + __puma_defSyncMacro("lock_test_and_set"); + + // #define __atomic_...(arg,...) *(typeof(arg))__generic_sync_...(arg, ## __VA_ARGS__) + #define __puma_defAtomicMacro(opname) \ + if (! tjp->that ()->_macroManager->getMacro ("__atomic_" opname)) { \ + Puma::PreMacro *macro = new Puma::PreMacro ("__atomic_" opname, \ + "*(typeof(par1))__generic_atomic_" opname "(par1, ## __VA_ARGS__)", \ + Puma::PreMacro::VAR_ARG_MACRO); \ + macro->addArg ("par1"); \ + macro->addArg ("__VA_ARGS__"); \ + tjp->that ()->_macroManager->addMacro (macro); \ + } + + // TODO: this list is still incomplete! + __puma_defAtomicMacro("fetch_add"); + __puma_defAtomicMacro("fetch_sub"); + __puma_defAtomicMacro("fetch_or"); + __puma_defAtomicMacro("fetch_and"); + __puma_defAtomicMacro("fetch_xor"); + __puma_defAtomicMacro("fetch_nand"); + __puma_defAtomicMacro("add_fetch"); + __puma_defAtomicMacro("sub_fetch"); + __puma_defAtomicMacro("or_fetch"); + __puma_defAtomicMacro("and_fetch"); + __puma_defAtomicMacro("xor_fetch"); + __puma_defAtomicMacro("nand_fetch"); + + // built-in versions of the ISO C99 floating point comparison macros + // map to its originals + tjp->that ()->defUndefinedMacro ("__builtin_isgreater", "isgreater"); + tjp->that ()->defUndefinedMacro ("__builtin_isgreaterequal", "isgreaterequal"); + tjp->that ()->defUndefinedMacro ("__builtin_isless", "isless"); + tjp->that ()->defUndefinedMacro ("__builtin_islessequal", "islessequal"); + tjp->that ()->defUndefinedMacro ("__builtin_islessgreater", "islessgreater"); + tjp->that ()->defUndefinedMacro ("__builtin_isunordered", "isunordered"); + + // implementation of ?: without side effects in not chosen alternative + // type __builtin_choose_expr (const_exp, exp1, exp2) + if (! tjp->that ()->_macroManager->getMacro ("__builtin_choose_expr")) { + Puma::PreMacro *macro = new Puma::PreMacro ("__builtin_choose_expr", "(exp1)"); + macro->addArg ("const_exp"); + macro->addArg ("exp1"); + macro->addArg ("exp2"); + tjp->that ()->_macroManager->addMacro (macro); + } + } + +protected: + ExtGnu () : + extended_asm (false), + extended_cv_qual (false), + gnu_builtins (false), + std_hack (false), + typeof_keyword (false), + statement_exprs (false), + labels_as_values (false), + thread_local_storage_class (false), + friend_injection (false), + extern_inline (false), + pic24 (false), + local_labels (false), + if_then_exprs (false), + case_ranges (false) + {} +}; + + +// ---------------------------------------------------- +// the Gnu attribute syntax +// ---------------------------------------------------- + +// add rules to the C Syntax +slice class Puma::ExtGnuAttributeSyntax { +public: + struct GnuAttribute { + static inline bool check (CSyntax &s) { return s.gnu_attribute (); } + static inline bool parse (CSyntax &); + static inline CTree *build(CSyntax &s); + }; + virtual bool gnu_attribute (); + bool catch_gnu_attribute (); +}; + +// simplistic parser: just collected all argument tokens +slice bool Puma::ExtGnuAttributeSyntax::GnuAttribute::parse (CSyntax &s) { + if (s.parse (Puma::TOK_ATTRIBUTE) && s.look_ahead (Puma::TOK_OPEN_ROUND)) { + return s.parse_round_block (); + } + return false; +} + +slice bool Puma::ExtGnuAttributeSyntax::gnu_attribute () { return GnuAttribute::parse (*this); } + +slice Puma::CTree * Puma::ExtGnuAttributeSyntax::GnuAttribute::build (CSyntax &s) { + return s.builder().gnu_attribute (); +} + +slice bool Puma::ExtGnuAttributeSyntax::catch_gnu_attribute () { + int skip[] = { Puma::TOK_SEMI_COLON, Puma::TOK_COMMA, 0 }; + int finish[] = { 0 }; + + return catch_error(*this, "invalid attribute", finish, skip); +} + +// extend the C Builder +slice class Puma::ExtGnuAttributeBuilder { +public: + Puma::CTree * gnu_attribute (); +}; + +slice Puma::CTree * Puma::ExtGnuAttributeBuilder::gnu_attribute () { + return list (new CT_GnuAttribute); +} + +// ---------------------------------------------------- +// the Gnu ASM syntax +// ---------------------------------------------------- + +// add rules to the C Syntax +slice class Puma::ExtGnuAsmSyntax { +public: + struct GnuAsmSpec { + static inline bool check (CSyntax &s) { return s.gnu_asm_spec (); } + static inline bool parse (CSyntax &); + static inline CTree *build(CSyntax &s); + }; + virtual bool gnu_asm_spec (); + + struct GnuAsmDef { + static inline bool check (CSyntax &s) { return s.gnu_asm_def (); } + static inline bool parse (CSyntax &); + static inline CTree *build(CSyntax &s); + }; + virtual bool gnu_asm_def (); + + struct GnuAsmOperands { + static inline bool check (CSyntax &s) { return s.gnu_asm_operands (); } + static inline bool parse (CSyntax &); + static inline CTree *build(CSyntax &s); + }; + virtual bool gnu_asm_operands (); + + struct GnuAsmEmptyOperands { + static inline bool check (CSyntax &s) { return s.gnu_asm_empty_operands (); } + static inline bool parse (CSyntax &); + static inline CTree *build(CSyntax &s); + }; + virtual bool gnu_asm_empty_operands (); + + struct GnuAsmOperand { + static inline bool check (CSyntax &s) { return s.gnu_asm_operand (); } + static inline bool parse (CSyntax &); + static inline CTree *build(CSyntax &s); + }; + virtual bool gnu_asm_operand (); + + struct GnuAsmClobbers { + static inline bool check (CSyntax &s) { return s.gnu_asm_clobbers (); } + static inline bool parse (CSyntax &); + static inline CTree *build(CSyntax &s); + }; + virtual bool gnu_asm_clobbers (); +}; + +slice bool Puma::ExtGnuAsmSyntax::GnuAsmSpec::parse (CSyntax &s) { + return (s.parse (Puma::TOK_ASM) && + s.parse (Puma::TOK_OPEN_ROUND) && + s.cmpd_str () && + s.parse (Puma::TOK_CLOSE_ROUND)); +} +slice bool Puma::ExtGnuAsmSyntax::gnu_asm_spec () { return GnuAsmSpec::parse (*this); } + +slice Puma::CTree * Puma::ExtGnuAsmSyntax::GnuAsmSpec::build (CSyntax &s) { + return s.builder().gnu_asm_spec (); +} + +slice bool Puma::ExtGnuAsmSyntax::GnuAsmDef::parse (CSyntax &s) { + return (s.parse (Puma::TOK_ASM) && s.opt (CvQual::check (s)) && + s.parse (Puma::TOK_OPEN_ROUND) && CmpdStr::check (s) && + s.opt ((s.look_ahead (Puma::TOK_COLON_COLON) ? + s.gnu_asm_empty_operands () && + s.gnu_asm_operands () : + s.gnu_asm_operands () && + s.look_ahead (Puma::TOK_COLON_COLON) ? + s.gnu_asm_empty_operands () : + s.gnu_asm_operands ()) && + s.gnu_asm_clobbers ()) && + s.parse (Puma::TOK_CLOSE_ROUND) && s.parse (Puma::TOK_SEMI_COLON)); +} +slice bool Puma::ExtGnuAsmSyntax::gnu_asm_def () { return GnuAsmDef::parse (*this); } + +slice Puma::CTree * Puma::ExtGnuAsmSyntax::GnuAsmDef::build (CSyntax &s) { + return s.builder().gnu_asm_def (); +} + +slice bool Puma::ExtGnuAsmSyntax::GnuAsmOperands::parse (CSyntax &s) { + return ((s.parse (Puma::TOK_COLON) || s.parse (Puma::TOK_COLON_COLON)) && + s.opt (s.list (&Puma::CSyntax::gnu_asm_operand, Puma::TOK_COMMA))); +} +slice bool Puma::ExtGnuAsmSyntax::gnu_asm_operands () { return GnuAsmOperands::parse (*this); } + +slice Puma::CTree * Puma::ExtGnuAsmSyntax::GnuAsmOperands::build (CSyntax &s) { + return s.builder().gnu_asm_operands (); +} + +slice bool Puma::ExtGnuAsmSyntax::GnuAsmEmptyOperands::parse (CSyntax &s) { + return true; +} +slice bool Puma::ExtGnuAsmSyntax::gnu_asm_empty_operands () { return GnuAsmEmptyOperands::parse (*this); } + +slice Puma::CTree * Puma::ExtGnuAsmSyntax::GnuAsmEmptyOperands::build (CSyntax &s) { + return s.builder().gnu_asm_empty_operands (); +} + +slice bool Puma::ExtGnuAsmSyntax::GnuAsmOperand::parse (CSyntax &s) { + if (s.parse (Puma::TOK_OPEN_SQUARE)) { // symbolic operand name? + if (!(s.parse (Puma::TOK_ID) && s.parse (Puma::TOK_CLOSE_SQUARE))) + return false; + } + return (CmpdStr::check (s) && s.parse (Puma::TOK_OPEN_ROUND) && + Expr::check (s) && s.parse (Puma::TOK_CLOSE_ROUND)); +} +slice bool Puma::ExtGnuAsmSyntax::gnu_asm_operand () { return GnuAsmOperand::parse (*this); } + +slice Puma::CTree * Puma::ExtGnuAsmSyntax::GnuAsmOperand::build (CSyntax &s) { + return s.builder().gnu_asm_operand (); +} + +slice bool Puma::ExtGnuAsmSyntax::GnuAsmClobbers::parse (CSyntax &s) { + return ((s.parse (Puma::TOK_COLON) || s.parse (Puma::TOK_COLON_COLON)) && + s.opt (list (s, Puma::TOK_COMMA))); +} +slice bool Puma::ExtGnuAsmSyntax::gnu_asm_clobbers () { return GnuAsmClobbers::parse (*this); } + +slice Puma::CTree * Puma::ExtGnuAsmSyntax::GnuAsmClobbers::build (CSyntax &s) { + return s.builder().gnu_asm_clobbers (); +} + +// extend the C Builder +slice class Puma::ExtGnuAsmBuilder { +public: + Puma::CTree * gnu_asm_spec (); + Puma::CTree * gnu_asm_def (); + Puma::CTree * gnu_asm_operands (); + Puma::CTree * gnu_asm_empty_operands (); + Puma::CTree * gnu_asm_operand (); + Puma::CTree * gnu_asm_clobbers (); +}; + +slice Puma::CTree * Puma::ExtGnuAsmBuilder::gnu_asm_spec () { + return new Puma::CT_GnuAsmSpec (get_node (0), get_node (1), get_node (2), + get_node (3)); +} + +slice Puma::CTree * Puma::ExtGnuAsmBuilder::gnu_asm_def () { + // just copied: this is a wrong implementation! + int have_cv = (get_node (1)->NodeName () == Puma::CT_Token::NodeId ()) ? 0 : 1; + int gnu_nodes = nodes () - have_cv - 5; + int gnu_first = 3 + have_cv; + Puma::CTree *cv = have_cv ? get_node (1) : (Puma::CTree*)0; + Puma::CTree *op0 = (gnu_nodes >= 1) ? get_node (gnu_first) : (Puma::CTree*)0; + Puma::CTree *op1 = (gnu_nodes >= 2) ? get_node (gnu_first + 1) : (Puma::CTree*)0; + Puma::CTree *clb = (gnu_nodes >= 3) ? get_node (gnu_first + 2) : (Puma::CTree*)0; + return new Puma::CT_GnuAsmDef (get_node (0), cv, get_node (1 + have_cv), + get_node (2 + have_cv), op0, op1, clb, + get_node (nodes () - 2),get_node (nodes () - 1)); +} + +slice Puma::CTree * Puma::ExtGnuAsmBuilder::gnu_asm_operands () { + return list (new Puma::CT_GnuAsmOperands); +} + +slice Puma::CTree * Puma::ExtGnuAsmBuilder::gnu_asm_empty_operands () { + return new Puma::CT_GnuAsmOperands; +} + +slice Puma::CTree * Puma::ExtGnuAsmBuilder::gnu_asm_operand () { + if (nodes () == 4) + return new Puma::CT_GnuAsmOperand (get_node (0), get_node (1), get_node (2), + get_node (3)); + else + return new Puma::CT_GnuAsmOperand (get_node (0), get_node (1), get_node (2), + get_node (3), get_node (4), get_node(5), get_node (6)); +} + +slice Puma::CTree * Puma::ExtGnuAsmBuilder::gnu_asm_clobbers () { + return list (new Puma::CT_GnuAsmClobbers); +} + +// ------------------------- +// Gnu statement expressions +// ------------------------- + +// C Builder extension +slice class Puma::ExtGnuStmtExprsBuilder { +public: + Puma::CTree * gnu_statement_expr (); +}; + +slice Puma::CTree * Puma::ExtGnuStmtExprsBuilder::gnu_statement_expr () { + return new Puma::CT_GnuStatementExpr (get_node (0), get_node (1), get_node (2)); +} + + +// ---------------------------------------------------- +// the Gnu local labels extension +// ---------------------------------------------------- + +// add rules to the C Syntax +slice class Puma::ExtGnuLocalLabelStmtSyntax { +public: + struct GnuLocalLabelStmt { + static inline bool check (CSyntax &s) { return s.gnu_local_label_stmt (); } + static inline bool parse (CSyntax &); + static inline CTree *build(CSyntax &s); + }; + virtual bool gnu_local_label_stmt (); +}; + +slice bool Puma::ExtGnuLocalLabelStmtSyntax::GnuLocalLabelStmt::parse (CSyntax &s) { + return (s.parse (Puma::TOK_LABEL) && list (s, Puma::TOK_COMMA) && s.parse (TOK_SEMI_COLON)); +} +slice Puma::CTree * Puma::ExtGnuLocalLabelStmtSyntax::GnuLocalLabelStmt::build (CSyntax &s) { + return s.builder().gnu_local_label_stmt (); +} +slice bool Puma::ExtGnuLocalLabelStmtSyntax::gnu_local_label_stmt () { return GnuLocalLabelStmt::parse (*this); } + +// C Builder extension +slice class Puma::ExtGnuLocalLabelStmtBuilder { +public: + Puma::CTree * gnu_local_label_stmt (); +}; + +slice Puma::CTree * Puma::ExtGnuLocalLabelStmtBuilder::gnu_local_label_stmt () { + return list (new Puma::CT_GnuLocalLabelStmt); +} + +// ---------------------- +// TYPEOF keyword support +// ---------------------- + +// add rules to the C Syntax for the Gnu Typeof syntax +slice class Puma::ExtGnuTypeofSyntax { +public: + CTree * rule_gnu_typeof (); + virtual bool gnu_typeof (); +}; + +slice Puma::CTree * Puma::ExtGnuTypeofSyntax::rule_gnu_typeof () { + return (parse (Puma::TOK_TYPEOF) && + (unary_expr1 () || unary_expr ())) ? + semantic ().gnu_typeof () : (Puma::CTree*)0; +} + +slice bool Puma::ExtGnuTypeofSyntax::gnu_typeof () { + return parse (&ExtGnuTypeofSyntax::rule_gnu_typeof); +} + +// add rules to the C Builder for the Gnu Typeof syntax +slice class Puma::ExtGnuTypeofBuilder { +public: + Puma::CTree * gnu_typeof (); +}; + +// builder extension +slice Puma::CTree * Puma::ExtGnuTypeofBuilder::gnu_typeof () { + Puma::CTree *result; + if (get_node (1)->NodeName () == Puma::Builder::Container::NodeId ()) { + Puma::Builder::Container *c = (Puma::Builder::Container*) get_node (1); + result = new Puma::CT_GnuTypeof (get_node (0), c->Son (0), c->Son (1), c->Son (2)); + delete c; + } else { + result = new Puma::CT_GnuTypeof (get_node (0), get_node (1)); + } + return result; +} + +// C semantic extension +slice class Puma::ExtGnuTypeofSemantic { +public: + virtual Puma::CTree * gnu_typeof (); +}; + +slice Puma::CTree * Puma::ExtGnuTypeofSemantic::gnu_typeof () { + Puma::CTree *result = builder ().gnu_typeof (); + if (result) { + Puma::CT_GnuTypeof *node = (Puma::CT_GnuTypeof*)result; + // if the GnuTypeof node has an expression, resolve it to get the type + if (node->Expr ()) { + Puma::CSemVisitor sem_visitor (*_err, current_scope); + Puma::CTypeInfo *expr_type = sem_visitor.resolveExpr (node->Expr (), node); + node->setTypeRef (expr_type); + } + Puma::CT_NamedType *named_type = node->TypeName (); + if (named_type && named_type->Object ()) { + node->setTypeRef (named_type->Object ()->TypeInfo ()); + } + } + return result; +} + +// C++ semantic extension +slice class Puma::ExtGnuTypeofCCSemantic { +public: + virtual Puma::CTree * gnu_typeof (); +}; + +slice Puma::CTree * Puma::ExtGnuTypeofCCSemantic::gnu_typeof () { + Puma::CTree *result = builder ().gnu_typeof (); + if (result) { + Puma::CT_GnuTypeof *node = (Puma::CT_GnuTypeof*)result; + // if the GnuTypeof node has an expression, resolve it to get the type + if (node->Expr ()) { + Puma::CTypeInfo *expr_type = resolveExpr (node->Expr ()); + node->setTypeRef (expr_type->NonReferenceType ()); + } + Puma::CT_NamedType *named_type = node->TypeName (); + if (named_type && named_type->Object ()) { + node->setTypeRef (named_type->Object ()->TypeInfo ()); + } + } + return result; +} + + +// ---------------------- +// Gnu builtin functions +// ---------------------- + +// extend the C/C++ semantic +slice class Puma::ExtGnuBuiltinsSemantic { +public: + void define_gnu_builtins (); +}; + +slice void Puma::ExtGnuBuiltinsSemantic::define_gnu_builtins () { + // declare GNU built-ins + + Puma::CFunctionInfo *info; + Puma::CTypeInfo *type; + Puma::CTypeList *args; + + + // function name constants + + Puma::CAttributeInfo *attr; + + // static const char __func__[] = "function-name"; + type = new Puma::CTypeQualified (&Puma::CTYPE_CHAR, true, false, false); + type = new Puma::CTypeArray (type); + type->TypeArray ()->Dimension (1); + attr = createAttribute ("__func__", current_scope, type, true); + + // static const char __FUNCTION__[] = "function-name"; + type = new Puma::CTypeQualified (&Puma::CTYPE_CHAR, true, false, false); + type = new Puma::CTypeArray (type); + type->TypeArray ()->Dimension (1); + attr = createAttribute ("__FUNCTION__", current_scope, type, true); + + // static const char __PRETTY_FUNCTION__[] = "function-name"; + type = new Puma::CTypeQualified (&Puma::CTYPE_CHAR, true, false, false); + type = new Puma::CTypeArray (type); + type->TypeArray ()->Dimension (1); + attr = createAttribute ("__PRETTY_FUNCTION__", current_scope, type, true); + + // builtin versions of C90 functions: + // The ISO C90 functions `abort', `abs', `acos', `asin', `atan2', `atan', + // `calloc', `ceil', `cosh', `cos', `exit', `exp', `fabs', `floor', `fmod', + // `fprintf', `fputs', `frexp', `fscanf', `isalnum', `isalpha', `iscntrl', + // `isdigit', `isgraph', `islower', `isprint', `ispunct', `isspace', + // `isupper', `isxdigit', `tolower', `toupper', `labs', `ldexp', `log10', + // `log', `malloc', `memchr', `memcmp', `memcpy', `memset', `modf', `pow', + // `printf', `putchar', `puts', `scanf', `sinh', `sin', `snprintf', + // `sprintf', `sqrt', `sscanf', `strcat', `strchr', `strcmp', `strcpy', + // `strcspn', `strlen', `strncat', `strncmp', `strncpy', `strpbrk', + // `strrchr', `strspn', `strstr', `tanh', `tan', `vfprintf', `vprintf' and + // `vsprintf' are all recognized as built-in functions + // (implementation still incomplete) + + // void *__builtin_memcpy(void *dest, const void *src, size_t n); + args = new Puma::CTypeList (3); + args->AddEntry (new Puma::CTypePointer (&Puma::CTYPE_VOID)); + args->AddEntry (new Puma::CTypePointer ( + new Puma::CTypeQualified (&Puma::CTYPE_VOID, true, false, false))); + args->AddEntry (Puma::CTypeInfo::CTYPE_SIZE_T); + type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + type = new Puma::CTypeFunction (type, args, true); + info = createFunction ("__builtin_memcpy", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + createParameter (info, args->Entry (2)); + + // void *__builtin_memset(void *s, int c, size_t n); + args = new Puma::CTypeList (3); + args->AddEntry (new Puma::CTypePointer (&Puma::CTYPE_VOID)); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (Puma::CTypeInfo::CTYPE_SIZE_T); + type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + type = new Puma::CTypeFunction (type, args, true); + info = createFunction ("__builtin_memset", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + createParameter (info, args->Entry (2)); + + // other stuff + + // void __builtin_unreachable (void) + args = new Puma::CTypeList (0); + type = new Puma::CTypeFunction (&Puma::CTYPE_VOID, args, true); + info = createFunction ("__builtin_unreachable", current_scope, type); + + // variable arguments access + + // void __builtin_stdarg_start(...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypeFunction (&Puma::CTYPE_VOID, args, true); + info = createFunction ("__builtin_stdarg_start", current_scope, type); + createParameter (info, args->Entry (0)); + + // void __builtin_va_start(...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypeFunction (&Puma::CTYPE_VOID, args, true); + info = createFunction ("__builtin_va_start", current_scope, type); + createParameter (info, args->Entry (0)); + + // hm, __builtin_va_arg is a problem as it has a variable result type + // I use int __builtin_va_start_helper(...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_va_arg_helper", current_scope, type); + createParameter (info, args->Entry (0)); + + // void __builtin_va_end(...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypeFunction (&Puma::CTYPE_VOID, args, true); + info = createFunction ("__builtin_va_end", current_scope, type); + createParameter (info, args->Entry (0)); + + // typedef void *__builtin_va_list + type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + createTypedef ("__builtin_va_list", current_scope, type); + + + // debug/frame access functions + + // void *__builtin_return_address(unsigned int c); + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_UNSIGNED_INT); // inr + type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + type = new Puma::CTypeFunction (type, args, true); + info = createFunction ("__builtin_return_address", current_scope, type); + createParameter (info, args->Entry (0)); + + // void *__builtin_frame_address(unsigned int c); + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_UNSIGNED_INT); // inr + type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + type = new Puma::CTypeFunction (type, args, true); + info = createFunction ("__builtin_frame_address", current_scope, type); + createParameter (info, args->Entry (0)); + + // void * __builtin_extract_return_address (void *ADDR); + // Name seems to be wrong!: __builtin_extract_return_addr + args = new Puma::CTypeList (1); + args->AddEntry (new Puma::CTypePointer (&Puma::CTYPE_VOID)); + type = new Puma::CTypeFunction (new Puma::CTypePointer (&Puma::CTYPE_VOID), args, true); + info = createFunction ("__builtin_extract_return_addr", current_scope, type); + createParameter (info, args->Entry (0)); + + // Object Size Checking Builtins + // size_t __builtin_object_size (void * PTR, int TYPE); + args = new Puma::CTypeList (2); + args->AddEntry (new Puma::CTypePointer (&Puma::CTYPE_VOID)); + args->AddEntry (&Puma::CTYPE_INT); + type = new Puma::CTypePointer (Puma::CTypeInfo::CTYPE_SIZE_T); + type = new Puma::CTypeFunction (type, args, true); + info = createFunction ("__builtin_object_size", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + + // limits + + // double __builtin_huge_val (void) + args = new Puma::CTypeList (0); + type = new Puma::CTypeFunction (&Puma::CTYPE_DOUBLE, args, true); + info = createFunction ("__builtin_huge_val", current_scope, type); + + // float __builtin_huge_valf (void) + args = new Puma::CTypeList (0); + type = new Puma::CTypeFunction (&Puma::CTYPE_FLOAT, args, true); + info = createFunction ("__builtin_huge_valf", current_scope, type); + + // long double __builtin_huge_vall (void) + args = new Puma::CTypeList (0); + type = new Puma::CTypeFunction (&Puma::CTYPE_LONG_DOUBLE, args, true); + info = createFunction ("__builtin_huge_vall", current_scope, type); + + // double __builtin_inf (void) + args = new Puma::CTypeList (0); + type = new Puma::CTypeFunction (&Puma::CTYPE_DOUBLE, args, true); + info = createFunction ("__builtin_inf", current_scope, type); + + // float __builtin_inff (void) + args = new Puma::CTypeList (0); + type = new Puma::CTypeFunction (&Puma::CTYPE_FLOAT, args, true); + info = createFunction ("__builtin_inff", current_scope, type); + + // long double __builtin_infl (void) + args = new Puma::CTypeList (0); + type = new Puma::CTypeFunction (&Puma::CTYPE_LONG_DOUBLE, args, true); + info = createFunction ("__builtin_infl", current_scope, type); + + // double __builtin_nan (const char *str) + args = new Puma::CTypeList (1); + type = new Puma::CTypeQualified (&Puma::CTYPE_CHAR, true, false, false); + type = new Puma::CTypePointer (type); + args->AddEntry (type); // const char* + type = new Puma::CTypeFunction (&Puma::CTYPE_DOUBLE, args, true); + info = createFunction ("__builtin_nan", current_scope, type); + createParameter (info, args->Entry (0)); + + // float __builtin_nanf (const char *str) + args = new Puma::CTypeList (1); + type = new Puma::CTypeQualified (&Puma::CTYPE_CHAR, true, false, false); + type = new Puma::CTypePointer (type); + args->AddEntry (type); // const char* + type = new Puma::CTypeFunction (&Puma::CTYPE_FLOAT, args, true); + info = createFunction ("__builtin_nanf", current_scope, type); + createParameter (info, args->Entry (0)); + + // double __builtin_nanl (const char *str) + args = new Puma::CTypeList (1); + type = new Puma::CTypeQualified (&Puma::CTYPE_CHAR, true, false, false); + type = new Puma::CTypePointer (type); + args->AddEntry (type); // const char* + type = new Puma::CTypeFunction (&Puma::CTYPE_LONG_DOUBLE, args, true); + info = createFunction ("__builtin_nanl", current_scope, type); + createParameter (info, args->Entry (0)); + + // double __builtin_nans (const char *str) + args = new Puma::CTypeList (1); + type = new Puma::CTypeQualified (&Puma::CTYPE_CHAR, true, false, false); + type = new Puma::CTypePointer (type); + args->AddEntry (type); // const char* + type = new Puma::CTypeFunction (&Puma::CTYPE_DOUBLE, args, true); + info = createFunction ("__builtin_nans", current_scope, type); + createParameter (info, args->Entry (0)); + + // float __builtin_nansf (const char *str) + args = new Puma::CTypeList (1); + type = new Puma::CTypeQualified (&Puma::CTYPE_CHAR, true, false, false); + type = new Puma::CTypePointer (type); + args->AddEntry (type); // const char* + type = new Puma::CTypeFunction (&Puma::CTYPE_FLOAT, args, true); + info = createFunction ("__builtin_nansf", current_scope, type); + createParameter (info, args->Entry (0)); + + // double __builtin_nansl (const char *str) + args = new Puma::CTypeList (1); + type = new Puma::CTypeQualified (&Puma::CTYPE_CHAR, true, false, false); + type = new Puma::CTypePointer (type); + args->AddEntry (type); // const char* + type = new Puma::CTypeFunction (&Puma::CTYPE_LONG_DOUBLE, args, true); + info = createFunction ("__builtin_nansl", current_scope, type); + createParameter (info, args->Entry (0)); + + // int __builtin_fpclassify (int, int, int, int, int, ...) + args = new Puma::CTypeList (6); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_fpclassify", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + createParameter (info, args->Entry (2)); + createParameter (info, args->Entry (3)); + createParameter (info, args->Entry (4)); + createParameter (info, args->Entry (5)); + + // compiler optimization + + // int __builtin_constant_p (...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_constant_p", current_scope, type); + createParameter (info, args->Entry (0)); + + // int __builtin_types_compatible_p (...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_types_compatible_p", current_scope, type); + createParameter (info, args->Entry (0)); + + // long __builtin_expect (long exp, long c) + args = new Puma::CTypeList (2); + args->AddEntry (&Puma::CTYPE_LONG); // long + args->AddEntry (&Puma::CTYPE_LONG); // long + type = new Puma::CTypeFunction (&Puma::CTYPE_LONG, args, true); + info = createFunction ("__builtin_expect", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + + // void __builtin_prefetch (const void *addr, ...) + args = new Puma::CTypeList (2); + type = new Puma::CTypeQualified (&Puma::CTYPE_VOID, true, false, false); + args->AddEntry (new Puma::CTypePointer (type)); // const void* + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypeFunction (&Puma::CTYPE_VOID, args, true); + info = createFunction ("__builtin_prefetch", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + + + // bit operations + + // int __builtin_ffs (unsigned int x) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_UNSIGNED_INT); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_ffs", current_scope, type); + createParameter (info, args->Entry (0)); + + // int __builtin_clz (unsigned int x) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_UNSIGNED_INT); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_clz", current_scope, type); + createParameter (info, args->Entry (0)); + + // int __builtin_ctz (unsigned int x) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_UNSIGNED_INT); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_ctz", current_scope, type); + createParameter (info, args->Entry (0)); + + // int __builtin_popcount (unsigned int x) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_UNSIGNED_INT); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_popcount", current_scope, type); + createParameter (info, args->Entry (0)); + + // int __builtin_parity (unsigned int x) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_UNSIGNED_INT); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_parity", current_scope, type); + createParameter (info, args->Entry (0)); + + // int __builtin_ffsl (unsigned long) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_UNSIGNED_LONG); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_ffsl", current_scope, type); + createParameter (info, args->Entry (0)); + + // int __builtin_clzl (unsigned long) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_UNSIGNED_LONG); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_clzl", current_scope, type); + createParameter (info, args->Entry (0)); + + // int __builtin_ctzl (unsigned long) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_UNSIGNED_LONG); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_ctzl", current_scope, type); + createParameter (info, args->Entry (0)); + + // int __builtin_popcountl (unsigned long) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_UNSIGNED_LONG); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_popcountl", current_scope, type); + createParameter (info, args->Entry (0)); + + // int __builtin_parityl (unsigned long) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_UNSIGNED_LONG); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_parityl", current_scope, type); + createParameter (info, args->Entry (0)); + + // int __builtin_ffsll (unsigned long long) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_UNSIGNED_LONG_LONG); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_ffsll", current_scope, type); + createParameter (info, args->Entry (0)); + + // int __builtin_clzll (unsigned long long) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_UNSIGNED_LONG_LONG); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_clzll", current_scope, type); + createParameter (info, args->Entry (0)); + + // int __builtin_ctzll (unsigned long long) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_UNSIGNED_LONG_LONG); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_ctzll", current_scope, type); + createParameter (info, args->Entry (0)); + + // int __builtin_popcountll (unsigned long long) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_UNSIGNED_LONG_LONG); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_popcountll", current_scope, type); + createParameter (info, args->Entry (0)); + + // int __builtin_parityll (unsigned long long) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_UNSIGNED_LONG_LONG); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_parityll", current_scope, type); + createParameter (info, args->Entry (0)); + + + // power calculation + + // double __builtin_powi (double, int) + args = new Puma::CTypeList (2); + args->AddEntry (&Puma::CTYPE_DOUBLE); // double + args->AddEntry (&Puma::CTYPE_INT); // int + type = new Puma::CTypeFunction (&Puma::CTYPE_DOUBLE, args, true); + info = createFunction ("__builtin_powi", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + + // float __builtin_powif (float, int) + args = new Puma::CTypeList (2); + args->AddEntry (&Puma::CTYPE_FLOAT); // float + args->AddEntry (&Puma::CTYPE_INT); // int + type = new Puma::CTypeFunction (&Puma::CTYPE_FLOAT, args, true); + info = createFunction ("__builtin_powif", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + + // long double __builtin_powil (long double, int) + args = new Puma::CTypeList (2); + args->AddEntry (&Puma::CTYPE_LONG_DOUBLE); // long double + args->AddEntry (&Puma::CTYPE_INT); // int + type = new Puma::CTypeFunction (&Puma::CTYPE_LONG_DOUBLE, args, true); + info = createFunction ("__builtin_powil", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + + + // atomic memory access + + // void __sync_synchronize (...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypeFunction (&Puma::CTYPE_VOID, args, true); + info = createFunction ("__sync_synchronize", current_scope, type); + createParameter (info, args->Entry (0)); + + // void __sync_lock_release (type *ptr, ...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypeFunction (&Puma::CTYPE_VOID, args, true); + info = createFunction ("__sync_lock_release", current_scope, type); + createParameter (info, args->Entry (0)); + + // bool __sync_bool_compare_and_swap (type *ptr, type oldval, type newval, ...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypeFunction (&Puma::CTYPE_BOOL, args, true); + info = createFunction ("__sync_bool_compare_and_swap", current_scope, type); + createParameter (info, args->Entry (0)); + + // type __sync_fetch_and_add (type *ptr, type value, ...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + type = new Puma::CTypeFunction (type, args, true); + info = createFunction ("__generic_sync_fetch_and_add", current_scope, type); + createParameter (info, args->Entry (0)); + + // type __sync_fetch_and_sub (type *ptr, type value, ...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + type = new Puma::CTypeFunction (type, args, true); + info = createFunction ("__generic_sync_fetch_and_sub", current_scope, type); + createParameter (info, args->Entry (0)); + + // type __sync_fetch_and_or (type *ptr, type value, ...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + type = new Puma::CTypeFunction (type, args, true); + info = createFunction ("__generic_sync_fetch_and_or", current_scope, type); + createParameter (info, args->Entry (0)); + + // type __sync_fetch_and_and (type *ptr, type value, ...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + type = new Puma::CTypeFunction (type, args, true); + info = createFunction ("__generic_sync_fetch_and_and", current_scope, type); + createParameter (info, args->Entry (0)); + + // type __sync_fetch_and_xor (type *ptr, type value, ...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + type = new Puma::CTypeFunction (type, args, true); + info = createFunction ("__generic_sync_fetch_and_xor", current_scope, type); + createParameter (info, args->Entry (0)); + + // type __sync_fetch_and_nand (type *ptr, type value, ...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + type = new Puma::CTypeFunction (type, args, true); + info = createFunction ("__generic_sync_fetch_and_nand", current_scope, type); + createParameter (info, args->Entry (0)); + + // type __sync_add_and_fetch (type *ptr, type value, ...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + type = new Puma::CTypeFunction (type, args, true); + info = createFunction ("__generic_sync_add_and_fetch", current_scope, type); + createParameter (info, args->Entry (0)); + + // type __sync_sub_and_fetch (type *ptr, type value, ...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + type = new Puma::CTypeFunction (type, args, true); + info = createFunction ("__generic_sync_sub_and_fetch", current_scope, type); + createParameter (info, args->Entry (0)); + + // type __sync_or_and_fetch (type *ptr, type value, ...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + type = new Puma::CTypeFunction (type, args, true); + info = createFunction ("__generic_sync_or_and_fetch", current_scope, type); + createParameter (info, args->Entry (0)); + + // type __sync_and_and_fetch (type *ptr, type value, ...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + type = new Puma::CTypeFunction (type, args, true); + info = createFunction ("__generic_sync_and_and_fetch", current_scope, type); + createParameter (info, args->Entry (0)); + + // type __sync_xor_and_fetch (type *ptr, type value, ...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + type = new Puma::CTypeFunction (type, args, true); + info = createFunction ("__generic_sync_xor_and_fetch", current_scope, type); + createParameter (info, args->Entry (0)); + + // type __sync_nand_and_fetch (type *ptr, type value, ...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + type = new Puma::CTypeFunction (type, args, true); + info = createFunction ("__generic_sync_nand_and_fetch", current_scope, type); + createParameter (info, args->Entry (0)); + + // type __sync_val_compare_and_swap (type *ptr, type oldval, type newval, ...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + type = new Puma::CTypeFunction (type, args, true); + info = createFunction ("__generic_sync_val_compare_and_swap", current_scope, type); + createParameter (info, args->Entry (0)); + + // type __sync_lock_test_and_set (type *ptr, type value, ...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + type = new Puma::CTypeFunction (type, args, true); + info = createFunction ("__generic_sync_lock_test_and_set", current_scope, type); + createParameter (info, args->Entry (0)); + + // atomic stuff + + // type __atomic_fetch_and_add (type *ptr, type value, ...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + type = new Puma::CTypeFunction (type, args, true); + info = createFunction ("__generic_atomic_fetch_add", current_scope, type); + createParameter (info, args->Entry (0)); + + // type __atomic_fetch_and_sub (type *ptr, type value, ...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + type = new Puma::CTypeFunction (type, args, true); + info = createFunction ("__generic_atomic_fetch_sub", current_scope, type); + createParameter (info, args->Entry (0)); + + // type __atomic_fetch_and_or (type *ptr, type value, ...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + type = new Puma::CTypeFunction (type, args, true); + info = createFunction ("__generic_atomic_fetch_or", current_scope, type); + createParameter (info, args->Entry (0)); + + // type __atomic_fetch_and_and (type *ptr, type value, ...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + type = new Puma::CTypeFunction (type, args, true); + info = createFunction ("__generic_atomic_fetch_and", current_scope, type); + createParameter (info, args->Entry (0)); + + // type __atomic_fetch_and_xor (type *ptr, type value, ...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + type = new Puma::CTypeFunction (type, args, true); + info = createFunction ("__generic_atomic_fetch_xor", current_scope, type); + createParameter (info, args->Entry (0)); + + // type __atomic_fetch_and_nand (type *ptr, type value, ...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + type = new Puma::CTypeFunction (type, args, true); + info = createFunction ("__generic_atomic_fetch_nand", current_scope, type); + createParameter (info, args->Entry (0)); + + // type __atomic_add_and_fetch (type *ptr, type value, ...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + type = new Puma::CTypeFunction (type, args, true); + info = createFunction ("__generic_atomic_add_fetch", current_scope, type); + createParameter (info, args->Entry (0)); + + // type __atomic_sub_and_fetch (type *ptr, type value, ...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + type = new Puma::CTypeFunction (type, args, true); + info = createFunction ("__generic_atomic_sub_fetch", current_scope, type); + createParameter (info, args->Entry (0)); + + // type __atomic_or_and_fetch (type *ptr, type value, ...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + type = new Puma::CTypeFunction (type, args, true); + info = createFunction ("__generic_atomic_or_fetch", current_scope, type); + createParameter (info, args->Entry (0)); + + // type __atomic_and_and_fetch (type *ptr, type value, ...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + type = new Puma::CTypeFunction (type, args, true); + info = createFunction ("__generic_atomic_and_fetch", current_scope, type); + createParameter (info, args->Entry (0)); + + // type __atomic_xor_and_fetch (type *ptr, type value, ...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + type = new Puma::CTypeFunction (type, args, true); + info = createFunction ("__generic_atomic_xor_fetch", current_scope, type); + createParameter (info, args->Entry (0)); + + // type __atomic_nand_and_fetch (type *ptr, type value, ...) + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_ELLIPSIS); // ... + type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + type = new Puma::CTypeFunction (type, args, true); + info = createFunction ("__generic_atomic_nand_fetch", current_scope, type); + createParameter (info, args->Entry (0)); + + // constructing function calls + + // void * __builtin_apply_args() + args = new Puma::CTypeList (0); + type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + type = new Puma::CTypeFunction (type, args, true); + info = createFunction ("__builtin_apply_args", current_scope, type); + + // void * __builtin_apply(void (*function)(), void *arguments, size_t size) + args = new Puma::CTypeList (3); + args->AddEntry (new Puma::CTypePointer (new Puma::CTypeFunction (&Puma::CTYPE_VOID, new Puma::CTypeList (0), true))); + args->AddEntry (new Puma::CTypePointer (&Puma::CTYPE_VOID)); + args->AddEntry (Puma::CTypeInfo::CTYPE_SIZE_T); + type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + type = new Puma::CTypeFunction (type, args, true); + info = createFunction ("__builtin_apply", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + createParameter (info, args->Entry (2)); + + // void __builtin_return(void *result) + args = new Puma::CTypeList (1); + args->AddEntry (new Puma::CTypePointer (&Puma::CTYPE_VOID)); + type = new Puma::CTypeFunction (&Puma::CTYPE_VOID, args, true); + info = createFunction ("__builtin_return", current_scope, type); + createParameter (info, args->Entry (0)); +} + +// extend the C/C++ semantic +slice class Puma::ExtGnuPIC24BuiltinsSemantic { +public: + void define_gnu_pic24_builtins (); +}; + +slice void Puma::ExtGnuPIC24BuiltinsSemantic::define_gnu_pic24_builtins () { + // declare GNU built-ins + + Puma::CFunctionInfo *info; + Puma::CTypeInfo *type; + Puma::CTypeList *args; + + // int __builtin_addab (void) + args = new Puma::CTypeList (0); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_addab", current_scope, type); + + // int __builtin_add(int value, const int shift); + args = new Puma::CTypeList (2); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (new Puma::CTypeQualified (&Puma::CTYPE_INT, true, false, false)); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_add", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + + // void __builtin_btg(unsigned int *, unsigned int 0xn); + args = new Puma::CTypeList (2); + args->AddEntry (new Puma::CTypePointer (&Puma::CTYPE_UNSIGNED_INT)); + args->AddEntry (&Puma::CTYPE_UNSIGNED_INT); + type = new Puma::CTypeFunction (&Puma::CTYPE_VOID, args, true); + info = createFunction ("__builtin_btg", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + + // int __builtin_clr(void); + args = new Puma::CTypeList (0); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_clr", current_scope, type); + + // int __builtin_clr_prefetch(int **xptr, int *xval, int xincr, + // int **yptr, int *yval, int yincr, int *AWB) + args = new Puma::CTypeList (7); + args->AddEntry (new Puma::CTypePointer (new Puma::CTypePointer (&Puma::CTYPE_INT))); + args->AddEntry (new Puma::CTypePointer (&Puma::CTYPE_INT)); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (new Puma::CTypePointer (new Puma::CTypePointer (&Puma::CTYPE_INT))); + args->AddEntry (new Puma::CTypePointer (&Puma::CTYPE_INT)); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (new Puma::CTypePointer (&Puma::CTYPE_INT)); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_clr_prefetch", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + createParameter (info, args->Entry (2)); + createParameter (info, args->Entry (3)); + createParameter (info, args->Entry (4)); + createParameter (info, args->Entry (5)); + createParameter (info, args->Entry (6)); + + // unsigned int __builtin_divf(unsigned int num, unsigned int den); + args = new Puma::CTypeList (2); + args->AddEntry (&Puma::CTYPE_UNSIGNED_INT); + args->AddEntry (&Puma::CTYPE_UNSIGNED_INT); + type = new Puma::CTypeFunction (&Puma::CTYPE_UNSIGNED_INT, args, true); + info = createFunction ("__builtin_divf", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + + // signed int __builtin_divmodsd(signed long dividend, signed int divisor, + // signed int *remainder); + args = new Puma::CTypeList (3); + args->AddEntry (&Puma::CTYPE_LONG); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (new Puma::CTypePointer (&Puma::CTYPE_INT)); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_divmodsd", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + createParameter (info, args->Entry (2)); + + // unsigned int __builtin_divmodud(unsigned long dividend, unsigned int divisor, + // unsigned int *remainder); + args = new Puma::CTypeList (3); + args->AddEntry (&Puma::CTYPE_UNSIGNED_LONG); + args->AddEntry (&Puma::CTYPE_UNSIGNED_INT); + args->AddEntry (new Puma::CTypePointer (&Puma::CTYPE_UNSIGNED_INT)); + type = new Puma::CTypeFunction (&Puma::CTYPE_UNSIGNED_INT, args, true); + info = createFunction ("__builtin_divmodud", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + createParameter (info, args->Entry (2)); + + // int __builtin_divsd(const long num, const int den); + args = new Puma::CTypeList (2); + args->AddEntry (new Puma::CTypeQualified (&Puma::CTYPE_LONG, true, false, false)); + args->AddEntry (new Puma::CTypeQualified (&Puma::CTYPE_INT, true, false, false)); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_divsd", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + + // unsigned int __builtin_divud(const unsigned long num, const unsigned int den); + args = new Puma::CTypeList (2); + args->AddEntry (new Puma::CTypeQualified (&Puma::CTYPE_UNSIGNED_LONG, true, false, false)); + args->AddEntry (new Puma::CTypeQualified (&Puma::CTYPE_UNSIGNED_INT, true, false, false)); + type = new Puma::CTypeFunction (&Puma::CTYPE_UNSIGNED_INT, args, true); + info = createFunction ("__builtin_divud", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + + // unsigned int __builtin_dmaoffset(const void *p); + args = new Puma::CTypeList (1); + args->AddEntry (new Puma::CTypePointer (new Puma::CTypeQualified (&Puma::CTYPE_VOID, true, false, false))); + type = new Puma::CTypeFunction (&Puma::CTYPE_UNSIGNED_INT, args, true); + info = createFunction ("__builtin_dmaoffset", current_scope, type); + createParameter (info, args->Entry (0)); + + // int __builtin_ed(int sqr, int **xptr, int xincr, + // int **yptr, int yincr, int *distance); + args = new Puma::CTypeList (6); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (new Puma::CTypePointer (new Puma::CTypePointer (&Puma::CTYPE_INT))); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (new Puma::CTypePointer (new Puma::CTypePointer (&Puma::CTYPE_INT))); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (new Puma::CTypePointer (&Puma::CTYPE_INT)); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_ed", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + createParameter (info, args->Entry (2)); + createParameter (info, args->Entry (3)); + createParameter (info, args->Entry (4)); + createParameter (info, args->Entry (5)); + + // int __builtin_edac(int sqr, int **xptr, int xincr, + // int **yptr, int yincr, int *distance); + args = new Puma::CTypeList (6); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (new Puma::CTypePointer (new Puma::CTypePointer (&Puma::CTYPE_INT))); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (new Puma::CTypePointer (new Puma::CTypePointer (&Puma::CTYPE_INT))); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (new Puma::CTypePointer (&Puma::CTYPE_INT)); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_edac", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + createParameter (info, args->Entry (2)); + createParameter (info, args->Entry (3)); + createParameter (info, args->Entry (4)); + createParameter (info, args->Entry (5)); + + // int __builtin_fbcl(int value); + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_INT); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_fbcl", current_scope, type); + createParameter (info, args->Entry (0)); + + // int __builtin_lac(int value, int shift); + args = new Puma::CTypeList (2); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (&Puma::CTYPE_INT); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_lac", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + + // int __builtin_mac(int a, int b, + // int **xptr, int *xval, int xincr, + // int **yptr, int *yval, int yincr, int *AWB); + args = new Puma::CTypeList (9); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (new Puma::CTypePointer (new Puma::CTypePointer (&Puma::CTYPE_INT))); + args->AddEntry (new Puma::CTypePointer (&Puma::CTYPE_INT)); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (new Puma::CTypePointer (new Puma::CTypePointer (&Puma::CTYPE_INT))); + args->AddEntry (new Puma::CTypePointer (&Puma::CTYPE_INT)); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (new Puma::CTypePointer (&Puma::CTYPE_INT)); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_mac", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + createParameter (info, args->Entry (2)); + createParameter (info, args->Entry (3)); + createParameter (info, args->Entry (4)); + createParameter (info, args->Entry (5)); + createParameter (info, args->Entry (6)); + createParameter (info, args->Entry (7)); + createParameter (info, args->Entry (8)); + + // signed int __builtin_modsd(signed long dividend, signed int divisor); + args = new Puma::CTypeList (2); + args->AddEntry (&Puma::CTYPE_LONG); + args->AddEntry (&Puma::CTYPE_INT); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_modsd", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + + // unsigned int __builtin_modud(unsigned long dividend, + // unsigned int divisor); + args = new Puma::CTypeList (2); + args->AddEntry (&Puma::CTYPE_UNSIGNED_LONG); + args->AddEntry (&Puma::CTYPE_UNSIGNED_INT); + type = new Puma::CTypeFunction (&Puma::CTYPE_UNSIGNED_INT, args, true); + info = createFunction ("__builtin_modud", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + + // int __builtin_movsac(int **xptr, int *xval, int xincr, + // int **yptr, int *yval, int yincr, int *AWB); + args = new Puma::CTypeList (7); + args->AddEntry (new Puma::CTypePointer (new Puma::CTypePointer (&Puma::CTYPE_INT))); + args->AddEntry (new Puma::CTypePointer (&Puma::CTYPE_INT)); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (new Puma::CTypePointer (new Puma::CTypePointer (&Puma::CTYPE_INT))); + args->AddEntry (new Puma::CTypePointer (&Puma::CTYPE_INT)); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (new Puma::CTypePointer (&Puma::CTYPE_INT)); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_movsac", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + createParameter (info, args->Entry (2)); + createParameter (info, args->Entry (3)); + createParameter (info, args->Entry (4)); + createParameter (info, args->Entry (5)); + createParameter (info, args->Entry (6)); + + // int __builtin_mpy(int a, int b, + // int **xptr, int *xval, int xincr, + // int **yptr, int *yval, int yincr); + args = new Puma::CTypeList (8); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (new Puma::CTypePointer (new Puma::CTypePointer (&Puma::CTYPE_INT))); + args->AddEntry (new Puma::CTypePointer (&Puma::CTYPE_INT)); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (new Puma::CTypePointer (new Puma::CTypePointer (&Puma::CTYPE_INT))); + args->AddEntry (new Puma::CTypePointer (&Puma::CTYPE_INT)); + args->AddEntry (&Puma::CTYPE_INT); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_mpy", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + createParameter (info, args->Entry (2)); + createParameter (info, args->Entry (3)); + createParameter (info, args->Entry (4)); + createParameter (info, args->Entry (5)); + createParameter (info, args->Entry (6)); + createParameter (info, args->Entry (7)); + + // int __builtin_mpyn(int a, int b, + // int **xptr, int *xval, int xincr, + // int **yptr, int *yval, int yincr); + args = new Puma::CTypeList (8); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (new Puma::CTypePointer (new Puma::CTypePointer (&Puma::CTYPE_INT))); + args->AddEntry (new Puma::CTypePointer (&Puma::CTYPE_INT)); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (new Puma::CTypePointer (new Puma::CTypePointer (&Puma::CTYPE_INT))); + args->AddEntry (new Puma::CTypePointer (&Puma::CTYPE_INT)); + args->AddEntry (&Puma::CTYPE_INT); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_mpyn", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + createParameter (info, args->Entry (2)); + createParameter (info, args->Entry (3)); + createParameter (info, args->Entry (4)); + createParameter (info, args->Entry (5)); + createParameter (info, args->Entry (6)); + createParameter (info, args->Entry (7)); + + // int __builtin_msc(int a, int b, + // int **xptr, int *xval, int xincr, + // int **yptr, int *yval, int yincr, int *AWB); + args = new Puma::CTypeList (9); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (new Puma::CTypePointer (new Puma::CTypePointer (&Puma::CTYPE_INT))); + args->AddEntry (new Puma::CTypePointer (&Puma::CTYPE_INT)); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (new Puma::CTypePointer (new Puma::CTypePointer (&Puma::CTYPE_INT))); + args->AddEntry (new Puma::CTypePointer (&Puma::CTYPE_INT)); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (new Puma::CTypePointer (&Puma::CTYPE_INT)); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_msc", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + createParameter (info, args->Entry (2)); + createParameter (info, args->Entry (3)); + createParameter (info, args->Entry (4)); + createParameter (info, args->Entry (5)); + createParameter (info, args->Entry (6)); + createParameter (info, args->Entry (7)); + createParameter (info, args->Entry (8)); + + // signed long __builtin_mulss(const signed int p0, const signed int p1); + args = new Puma::CTypeList (2); + args->AddEntry (new Puma::CTypeQualified (&Puma::CTYPE_INT, true, false, false)); + args->AddEntry (new Puma::CTypeQualified (&Puma::CTYPE_INT, true, false, false)); + type = new Puma::CTypeFunction (&Puma::CTYPE_LONG, args, true); + info = createFunction ("__builtin_mulss", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + + // signed long __builtin_mulsu(const signed int p0, const unsigned int p1); + args = new Puma::CTypeList (2); + args->AddEntry (new Puma::CTypeQualified (&Puma::CTYPE_INT, true, false, false)); + args->AddEntry (new Puma::CTypeQualified (&Puma::CTYPE_UNSIGNED_INT, true, false, false)); + type = new Puma::CTypeFunction (&Puma::CTYPE_LONG, args, true); + info = createFunction ("__builtin_mulsu", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + + // signed long __builtin_mulus(const unsigned int p0, const signed int p1); + args = new Puma::CTypeList (2); + args->AddEntry (new Puma::CTypeQualified (&Puma::CTYPE_UNSIGNED_INT, true, false, false)); + args->AddEntry (new Puma::CTypeQualified (&Puma::CTYPE_INT, true, false, false)); + type = new Puma::CTypeFunction (&Puma::CTYPE_LONG, args, true); + info = createFunction ("__builtin_mulus", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + + // unsigned long __builtin_muluu(const unsigned int p0, const unsigned int p1); + args = new Puma::CTypeList (2); + args->AddEntry (new Puma::CTypeQualified (&Puma::CTYPE_UNSIGNED_INT, true, false, false)); + args->AddEntry (new Puma::CTypeQualified (&Puma::CTYPE_UNSIGNED_INT, true, false, false)); + type = new Puma::CTypeFunction (&Puma::CTYPE_UNSIGNED_LONG, args, true); + info = createFunction ("__builtin_muluu", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + + // void __builtin_nop(void); + args = new Puma::CTypeList (0); + type = new Puma::CTypeFunction (&Puma::CTYPE_VOID, args, true); + info = createFunction ("__builtin_nop", current_scope, type); + + // unsigned int __builtin_psvpage(const void *p); + args = new Puma::CTypeList (1); + args->AddEntry (new Puma::CTypePointer (new Puma::CTypeQualified (&Puma::CTYPE_VOID, true, false, false))); + type = new Puma::CTypeFunction (&Puma::CTYPE_UNSIGNED_INT, args, true); + info = createFunction ("__builtin_psvpage", current_scope, type); + createParameter (info, args->Entry (0)); + + // unsigned int __builtin_psvoffset(const void *p); + args = new Puma::CTypeList (1); + args->AddEntry (new Puma::CTypePointer (new Puma::CTypeQualified (&Puma::CTYPE_VOID, true, false, false))); + type = new Puma::CTypeFunction (&Puma::CTYPE_UNSIGNED_INT, args, true); + info = createFunction ("__builtin_psvoffset", current_scope, type); + createParameter (info, args->Entry (0)); + + // unsigned int __builtin_readsfr(const void *p); + args = new Puma::CTypeList (1); + args->AddEntry (new Puma::CTypePointer (new Puma::CTypeQualified (&Puma::CTYPE_VOID, true, false, false))); + type = new Puma::CTypeFunction (&Puma::CTYPE_UNSIGNED_INT, args, true); + info = createFunction ("__builtin_readsfr", current_scope, type); + createParameter (info, args->Entry (0)); + + // int __builtin_return_address (const int level); + // => this function is alread defined for all gnu dialects + // it has a slightly different signature, but should be compatible + + // int __builtin_sac(int value, int shift); + args = new Puma::CTypeList (2); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (&Puma::CTYPE_INT); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_sac", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + + // int __builtin_sacr(int value, int shift); + args = new Puma::CTypeList (2); + args->AddEntry (&Puma::CTYPE_INT); + args->AddEntry (&Puma::CTYPE_INT); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_sacr", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + + // int __builtin_sftac(int shift); + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_INT); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_sftac", current_scope, type); + createParameter (info, args->Entry (0)); + + // int __builtin_subab(void); + args = new Puma::CTypeList (0); + type = new Puma::CTypeFunction (&Puma::CTYPE_INT, args, true); + info = createFunction ("__builtin_subab", current_scope, type); + + // unsigned int __builtin_tblpage(const void *p); + args = new Puma::CTypeList (1); + args->AddEntry (new Puma::CTypePointer (new Puma::CTypeQualified (&Puma::CTYPE_VOID, true, false, false))); + type = new Puma::CTypeFunction (&Puma::CTYPE_UNSIGNED_INT, args, true); + info = createFunction ("__builtin_tblpage", current_scope, type); + createParameter (info, args->Entry (0)); + + // unsigned int __builtin_tbloffset(const void *p); + args = new Puma::CTypeList (1); + args->AddEntry (new Puma::CTypePointer (new Puma::CTypeQualified (&Puma::CTYPE_VOID, true, false, false))); + type = new Puma::CTypeFunction (&Puma::CTYPE_UNSIGNED_INT, args, true); + info = createFunction ("__builtin_tbloffset", current_scope, type); + createParameter (info, args->Entry (0)); + + // unsigned int __builtin_tblrdh(unsigned int offset); + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_UNSIGNED_INT); + type = new Puma::CTypeFunction (&Puma::CTYPE_UNSIGNED_INT, args, true); + info = createFunction ("__builtin_tblrdh", current_scope, type); + createParameter (info, args->Entry (0)); + + // unsigned int __builtin_tblrdl(unsigned int offset); + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_UNSIGNED_INT); + type = new Puma::CTypeFunction (&Puma::CTYPE_UNSIGNED_INT, args, true); + info = createFunction ("__builtin_tblrdl", current_scope, type); + createParameter (info, args->Entry (0)); + + // void __builtin_tblwth(unsigned int offset, unsigned int data); + args = new Puma::CTypeList (2); + args->AddEntry (&Puma::CTYPE_UNSIGNED_INT); + args->AddEntry (&Puma::CTYPE_UNSIGNED_INT); + type = new Puma::CTypeFunction (&Puma::CTYPE_VOID, args, true); + info = createFunction ("__builtin_tblwth", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + + // void __builtin_tblwtl(unsigned int offset, unsigned int data); + args = new Puma::CTypeList (2); + args->AddEntry (&Puma::CTYPE_UNSIGNED_INT); + args->AddEntry (&Puma::CTYPE_UNSIGNED_INT); + type = new Puma::CTypeFunction (&Puma::CTYPE_VOID, args, true); + info = createFunction ("__builtin_tblwtl", current_scope, type); + createParameter (info, args->Entry (0)); + createParameter (info, args->Entry (1)); + + // void __builtin_write_NVM(void); + args = new Puma::CTypeList (0); + type = new Puma::CTypeFunction (&Puma::CTYPE_VOID, args, true); + info = createFunction ("__builtin_write_NVM", current_scope, type); + + // void __builtin_write_RTCWEN(void); + args = new Puma::CTypeList (0); + type = new Puma::CTypeFunction (&Puma::CTYPE_VOID, args, true); + info = createFunction ("__builtin_write_RTCWEN", current_scope, type); + + // void __builtin_write_OSCCONL(unsigned char value); + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_UNSIGNED_CHAR); + type = new Puma::CTypeFunction (&Puma::CTYPE_VOID, args, true); + info = createFunction ("__builtin_write_OSCCONL", current_scope, type); + createParameter (info, args->Entry (0)); + + // void __builtin_write_OSCCONH(unsigned char value); + args = new Puma::CTypeList (1); + args->AddEntry (&Puma::CTYPE_UNSIGNED_CHAR); + type = new Puma::CTypeFunction (&Puma::CTYPE_VOID, args, true); + info = createFunction ("__builtin_write_OSCCONH", current_scope, type); + createParameter (info, args->Entry (0)); + +} + +#endif /* __ext_gnu_h__ */ diff --git a/Puma/src/aspects/ExtGnuCInfos.ah b/Puma/src/aspects/ExtGnuCInfos.ah new file mode 100644 index 0000000..6bac648 --- /dev/null +++ b/Puma/src/aspects/ExtGnuCInfos.ah @@ -0,0 +1,95 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __ext_gnu_cinfos_ah__ +#define __ext_gnu_cinfos_ah__ + +#include +#include + +namespace Puma { + +slice class ExtGnuLocalLabelInfo { + CStructure *_LocalScope; +public: + void LocalScope (CStructure *ls) { _LocalScope = ls; } + CStructure *LocalScope () const { return _LocalScope; } +}; + +class CStructure; +class CLabelInfo; + +slice class ExtGnuLocalLabelStmtInfo { +public: + typedef std::pair LabelKey; + typedef std::map LabelMap; +private: + LabelMap _LocalLabels; +public: + + /** Find a local label declaration of a subscope of this function + * \param name The name of the local label + * \param scope The local scope, which should be searched + * \param recursive Search enclosing scopes until the function scope is reached + * \return NULL if the label has not been found, label info otherwise */ + CLabelInfo *findLocalLabel (std::string name, CStructure *scope, + bool recursive = false) const; + + /** Remember a local label declaration of a subscope in this function + * \param name The name of the local label + * \param scope The local scope, in which the label is declared + * \return pointer to the created label object or NULL of there is no sem-db */ + CLabelInfo *registerLocalLabel (std::string name, CStructure *scope); + + /** Remove a local label declaration of a subscope in this function + * \param name The name of the local label + * \param scope The local scope, in which the label is declared */ + void unregisterLocalLabel (std::string name, CStructure *scope); +}; + +} // namespace Puma + +slice +Puma::CLabelInfo *Puma::ExtGnuLocalLabelStmtInfo::findLocalLabel (std::string name, CStructure *scope, + bool recursive) const { + LabelMap::const_iterator iter = _LocalLabels.find (LabelKey (name, scope)); + if (iter != _LocalLabels.end ()) + return iter->second; + if (recursive && scope != this && scope->Parent () && scope->Parent ()->Structure ()) + return findLocalLabel (name, scope->Parent()->Structure (), recursive); + return 0; +} + +slice +Puma::CLabelInfo *Puma::ExtGnuLocalLabelStmtInfo::registerLocalLabel (std::string name, CStructure *scope) { + if (!SemDB ()) + return 0; + CLabelInfo *info = SemDB()->newLabel(); + info->Scope (this); + info->LocalScope (scope); + info->Name (name.c_str ()); + _LocalLabels.insert (LabelMap::value_type (LabelKey (name, scope), info)); + return info; +} + +slice +void Puma::ExtGnuLocalLabelStmtInfo::unregisterLocalLabel (std::string name, CStructure *scope) { + _LocalLabels.erase (LabelKey (name, scope)); +} + +#endif /* __ext_gnu_cinfos_ah__ */ diff --git a/Puma/src/aspects/ExtGnuCSemDeclSpecs.ah b/Puma/src/aspects/ExtGnuCSemDeclSpecs.ah new file mode 100644 index 0000000..6d7d255 --- /dev/null +++ b/Puma/src/aspects/ExtGnuCSemDeclSpecs.ah @@ -0,0 +1,32 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __ext_gnu_csem_decl_specs_ah__ +#define __ext_gnu_csem_decl_specs_ah__ + +#include "Puma/GnuCTree.h" + +namespace Puma { + slice class ExtGnuCSemDeclSpecs { + public: + int _typeofs; + CT_GnuTypeof *_typeof_node; + }; +} + +#endif /* __ext_gnu_csem_decl_specs_ah__ */ diff --git a/Puma/src/aspects/ExtGnuCSemExpr.ah b/Puma/src/aspects/ExtGnuCSemExpr.ah new file mode 100644 index 0000000..b5a0372 --- /dev/null +++ b/Puma/src/aspects/ExtGnuCSemExpr.ah @@ -0,0 +1,214 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __ext_gnu_csemexpr_ah__ +#define __ext_gnu_csemexpr_ah__ + +#include "Puma/GnuCTree.h" +#include "Puma/CLabelInfo.h" +#include "Puma/CLocalScope.h" + +#ifndef HAVE_SEMEXPR_ERROR_MACROS +#define HAVE_SEMEXPR_ERROR_MACROS + +#define ASPECT_SEMEXPR_MSG(node__,mesg__) \ + {if (node__->token ()) err << node__->token ()->location (); err << mesg__ << endMessage;} + +#define ASPECT_SEMEXPR_ERROR(node__, mesg__) \ + ASPECT_SEMEXPR_MSG (node__, sev_error << mesg__) + +#endif // HAVE_SEMEXPR_ERROR_MACROS + +namespace Puma { + +class CTypeInfo; + +// gnu statement expression extension + +// C semantic extension +slice class ExtGnuStmtExprsCSemExpr { +public: + Puma::CTypeInfo *resolve (Puma::CT_GnuStatementExpr *, Puma::CTree *); + Puma::CTypeInfo *resolveLabelAddr (Puma::CT_UnaryExpr *); +}; + +// C++ semantic extension +slice class ExtGnuStmtExprsCCSemExpr { +public: + Puma::CTypeInfo *resolve (Puma::CT_GnuStatementExpr *, Puma::CTree *); + Puma::CTypeInfo *resolveLabelAddr (Puma::CT_UnaryExpr *); +}; + +// gnu conditional expressions with two operands +slice class ExtGnuCondExprCSemExpr { +public: + Puma::CTypeInfo *resolve_gnu (Puma::CT_IfThenExpr *, Puma::CTree *); +}; + +} // namespace Puma + +slice Puma::CTypeInfo *Puma::ExtGnuStmtExprsCSemExpr::resolve ( + Puma::CT_GnuStatementExpr *node, Puma::CTree *) { + + Puma::CTypeInfo *result = &Puma::CTYPE_UNDEFINED; + + if (! current_scope->LocalScope ()) { + ASPECT_SEMEXPR_ERROR (node, + "braced-group within expression allowed only inside a function"); + } else { + + // first analyse the compound statement in this expression + Puma::CSemVisitor csv (err); + csv.run (node->Son (1), current_scope); + + // check the compound statement semantically + Puma::CT_CmpdStmt *cmpd = node->CmpdStmt (); + if (cmpd->Entries () >= 1 && + cmpd->Entry (cmpd->Entries () - 1)->NodeName () == + Puma::CT_ExprStmt::NodeId ()) { + Puma::CT_ExprStmt *expr_stmt = (Puma::CT_ExprStmt*)cmpd->Entry (cmpd->Entries () - 1); + result = expr_stmt->Expr ()->Type (); + } + else + // an empty statement expression or one that does not end with a + // statement expression has type void! + result = &Puma::CTYPE_VOID; + } + + node->setTypeRef (result); + return result; +} + +slice Puma::CTypeInfo *Puma::ExtGnuStmtExprsCSemExpr::resolveLabelAddr ( + CT_UnaryExpr *expr) { + Puma::CFunctionInfo *finfo = current_scope->LocalScope ()->Function (); + if (finfo) { + Puma::CT_SimpleName *label = (Puma::CT_SimpleName*) expr->Son (1); + Puma::CObjectInfo *linfo = finfo->Label (label->Text ()); + if (! linfo) { + ASPECT_SEMEXPR_ERROR (label, "label `" << label->Text () << "' used but not defined"); + } else { + label->Object (linfo); + label->setTypeRef (linfo->TypeInfo ()); + } + } + Puma::CTypeInfo *type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + expr->setType (type); + return type; +} + +slice Puma::CTypeInfo *Puma::ExtGnuStmtExprsCCSemExpr::resolve ( + Puma::CT_GnuStatementExpr *node, Puma::CTree *) { + + Puma::CTypeInfo *result = &Puma::CTYPE_UNDEFINED; + + if (! current_scope->LocalScope ()) { + ASPECT_SEMEXPR_ERROR (node, + "braced-group within expression allowed only inside a function"); + } else { + + // first analyse the compound statement in this expression + Puma::CCSemVisitor csv (err); + csv.run (node->Son (1), current_scope); + + // check the compound statement semantically + Puma::CT_CmpdStmt *cmpd = node->CmpdStmt (); + if (cmpd->Entries () >= 1 && + cmpd->Entry (cmpd->Entries () - 1)->NodeName () == + Puma::CT_ExprStmt::NodeId ()) { + Puma::CT_ExprStmt *expr_stmt = (Puma::CT_ExprStmt*)cmpd->Entry (cmpd->Entries () - 1); + result = expr_stmt->Expr ()->Type (); + } + else + // an empty statement expression or one that does not end with a + // statement expression has type void! + result = &Puma::CTYPE_VOID; + } + + node->setTypeRef (result); + return result; +} + +slice Puma::CTypeInfo *Puma::ExtGnuStmtExprsCCSemExpr::resolveLabelAddr ( + CT_UnaryExpr *expr) { + Puma::CFunctionInfo *finfo = current_scope->LocalScope ()->Function (); + if (finfo) { + Puma::CT_SimpleName *label = (Puma::CT_SimpleName*) expr->Son (1); + Puma::CObjectInfo *linfo = finfo->Label (label->Text ()); + if (! linfo) { + ASPECT_SEMEXPR_ERROR (label, "label `" << label->Text () << "' used but not defined"); + } else { + label->Object (linfo); + label->setTypeRef (linfo->TypeInfo ()); + } + } + Puma::CTypeInfo *type = new Puma::CTypePointer (&Puma::CTYPE_VOID); + expr->setType (type); + return type; +} + +slice Puma::CTypeInfo *Puma::ExtGnuCondExprCSemExpr::resolve_gnu (CT_IfThenExpr *node, CTree *base) { + CTypeInfo *result, *t1, *t2, *t3; + CTree *op1, *op2, *op3; + CConstant *v1; + + conv_to_ptr = 1; + + // resolve operands + t1 = resolveExpr (node->Condition (), node); + t2 = t1; + t3 = resolveExpr (node->RightOperand (), node); + op1 = node->Condition (); + op2 = op1; + op3 = node->RightOperand (); + + // determine the result type + result = cond_expr_type (node, t1, op1, t2, op2, t3, op3); + + // apply arithmetic conversions if needed + if (t2->isArithmetic () && t3->isArithmetic ()) { + if (*t2 > *t3) { + result = cast_to (t2, op3, node); + op3 = node->RightOperand (); + } else if (*t2 < *t3) { + result = t3; + } else + result = t2; + } + + // handle constants + v1 = op1->Value () ? op1->Value ()->Constant () : 0; + if (v1) { + if (v1->isNull ()) { + if (op3->Value ()) + node->setValueRef (op3->Value ()); + } else { + if (op2->Value ()) + node->setValue (op2->Value ()->Constant ()->cast_to (t2)); + } + } + + if (!result || result == t2 || result == t3 || *result == CTYPE_UNDEFINED) + node->setTypeRef (result); + else + node->setType (result); + return result; +} + + +#endif /* __ext_gnu_csemexpr_ah__ */ diff --git a/Puma/src/aspects/ExtGnuCSemantic.ah b/Puma/src/aspects/ExtGnuCSemantic.ah new file mode 100644 index 0000000..c5ec1e3 --- /dev/null +++ b/Puma/src/aspects/ExtGnuCSemantic.ah @@ -0,0 +1,113 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __ext_gnu_csemantic_ah__ +#define __ext_gnu_csemantic_ah__ + +#include "Puma/CTree.h" + +#ifndef HAVE_SEM_ERROR_MACROS +#define HAVE_SEM_ERROR_MACROS + +#define ASPECT_SEM_MSG(loc__,mesg__) \ + *_err << loc__->token ()->location () << mesg__ << endMessage + +#define ASPECT_SEM_ERROR(loc__,mesg__) \ + ASPECT_SEM_MSG (loc__, sev_error << mesg__) + +#define ASPECT_SEM_ERROR__duplicate(token__,type__,name__) \ + ASPECT_SEM_ERROR (token__, "duplicate " << type__ \ + << " `" << name__->Text () << "'") + +#endif // HAVE_SEM_ERROR_MACROS + +namespace Puma { + +// C Semantic extension +slice class ExtGnuLocalLabelStmtSemantic { +public: + CTree *introduce_local_label (); + bool gnu_introduce_label (CTree *&); +}; + +slice Puma::CTree * Puma::ExtGnuLocalLabelStmtSemantic::introduce_local_label () { + Puma::CTree *tree = builder ().gnu_local_label_stmt (); + if (tree->NodeName () != CT_GnuLocalLabelStmt::NodeId ()) + return tree; + + if (! current_scope->LocalScope ()) { + ASPECT_SEM_ERROR (tree, "label declaration outside of function"); + builder ().destroyNode (tree); + return (CTree*)0; + } + + CFunctionInfo *fct = current_scope->LocalScope ()->Function (); + // be careful: tricky casts necessary, because of multiple inheritance! + CT_GnuLocalLabelStmt *ls = (CT_GnuLocalLabelStmt *)(CT_List*)tree; + + for (int e = 0; e < ls->Entries (); e++) { + CT_SimpleName *sn = (CT_SimpleName*)ls->Entry (e); + const char *name = sn->Text (); + if (fct->findLocalLabel (name, current_scope)) { + ASPECT_SEM_ERROR__duplicate (tree, "local label declaration", sn); + } + else { + fct->registerLocalLabel (name, current_scope); + } + } + return tree; +} + +slice bool Puma::ExtGnuLocalLabelStmtSemantic::gnu_introduce_label (CTree *&tree) { + CFunctionInfo *fct; + CLabelInfo *info; + const char *name; + CT_LabelStmt *ls; + + ls = (CT_LabelStmt*) tree; + if (ls->NodeName () != CT_LabelStmt::NodeId ()) + return true; + + name = ls->Label ()->Text (); + if (! current_scope->LocalScope ()) { + ASPECT_SEM_ERROR (ls->Label (), "label `" << name << "' outside of function"); + builder ().destroyNode (ls); + tree = (CTree*)0; + return true; + } + + fct = current_scope->LocalScope ()->Function (); + if ((info = fct->findLocalLabel (name, current_scope, true)) != 0) { + if (info->Tree ()) { + ASPECT_SEM_ERROR__duplicate (ls, "local label", ls->Label ()); + builder ().destroyNode (ls); + tree = (CTree*)0; + return true; + } + info->Tree (ls); + } + else { + // do the standard label handling + return false; + } + return true; +} + +} // namespace Puma + +#endif /* __ext_gnu_csemantic_ah__ */ diff --git a/Puma/src/aspects/ExtGnuCTree.ah b/Puma/src/aspects/ExtGnuCTree.ah new file mode 100644 index 0000000..7371c31 --- /dev/null +++ b/Puma/src/aspects/ExtGnuCTree.ah @@ -0,0 +1,164 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __ext_gnu_ctree_ah__ +#define __ext_gnu_ctree_ah__ + +#include + +aspect ExtGnuCTree { + + // interface for accessing prefixes or suffixes on any syntax tree node + advice "Puma::CTree" : slice class { + public: + typedef std::list CTreeList; + virtual CTreeList *gnu_prefix () { return 0; } + virtual CTreeList *gnu_suffix () { return 0; } + virtual CTreeList *gnu_infix () { return 0; } + virtual const CTreeList *gnu_prefix () const { return 0; } + virtual const CTreeList *gnu_suffix () const { return 0; } + virtual const CTreeList *gnu_infix () const { return 0; } + virtual int gnu_infix_pos () const { return -1; } + }; + + // extended token/end_token functions that obey gnu extensions + // - needed for correct code transformation + advice execution("Puma::Token* Puma::CTree::token () const") : around() { + if (tjp->that ()->gnu_prefix () && tjp->that ()->gnu_prefix ()->size () > 0) + *tjp->result() = tjp->that ()->gnu_prefix ()->front ()->token (); + else + tjp->proceed (); + } + + advice execution("Puma::CT_Token* Puma::CTree::token_node () const") : around() { + if (tjp->that ()->gnu_prefix () && tjp->that ()->gnu_prefix ()->size () > 0) + *tjp->result() = tjp->that ()->gnu_prefix ()->front ()->token_node (); + else + tjp->proceed (); + } + + advice execution("Puma::Token* Puma::CTree::end_token () const") : around() { + if (tjp->that ()->gnu_suffix () && tjp->that ()->gnu_suffix ()->size () > 0) + *tjp->result() = tjp->that ()->gnu_suffix ()->back ()->end_token (); + else + tjp->proceed (); + } + + advice execution("Puma::CT_Token* Puma::CTree::end_token_node () const") : around() { + if (tjp->that ()->gnu_suffix () && tjp->that ()->gnu_suffix ()->size () > 0) + *tjp->result() = tjp->that ()->gnu_suffix ()->back ()->end_token_node (); + else + tjp->proceed (); + } + + // All node types that may have suffixes: + // SimpleName extension needed for attributes in namespace definitions + // Declarator extension needed for attributes after param declarations + // DeclSpeqSeq extension needed for attributes following such sequence + advice "Puma::CT_SimpleName" || + "Puma::CT_Declarator" || + "Puma::CT_DeclSpec" || + "Puma::CT_ClassDef" || + "Puma::CT_EnumDef" || + "Puma::CT_DeclSpecSeq" : slice class { + CTreeList _gnu_suffix; + public: + CTreeList *gnu_suffix () { return &_gnu_suffix; } + const CTreeList *gnu_suffix () const { return &_gnu_suffix; } + }; + + // All node types that may have prefixes: + // For the __extension__ keyword we need prefix memory on ... + // ObjDecl, FctDef, NamespaceDef, TemplateDecl, UsingDirective, LinkageSpec, + // UsingDecl, Expression, ExprStmt, NamespaceAliasDef, AsmDef, GnuAsmDef + // For attributes before a declaration specifier we need prefix memory in + // DeclSpec, SimpleName, ClassDef, EnumDef, and Declarator + advice "Puma::CT_ObjDecl" || + "Puma::CT_FctDef" || + "Puma::CT_NamespaceDef" || + "Puma::CT_TemplateDecl" || + "Puma::CT_UsingDirective" || + "Puma::CT_LinkageSpec" || + "Puma::CT_UsingDecl" || + "Puma::CT_Expression" || + "Puma::CT_ExprStmt" || + "Puma::CT_NamespaceAliasDef" || + "Puma::CT_AsmDef" || + "Puma::CT_GnuAsmDef" || + "Puma::CT_SimpleName" || + "Puma::CT_DeclSpec" || + "Puma::CT_ClassDef" || + "Puma::CT_EnumDef" || + "Puma::CT_Declarator" : slice class { + CTreeList _gnu_prefix; + public: + CTreeList *gnu_prefix () { return &_gnu_prefix; } + const CTreeList *gnu_prefix () const { return &_gnu_prefix; } + }; + + // All node types that may have infix attributes: + // LabelStmt + advice "Puma::CT_LabelStmt" : slice class { + CTreeList _gnu_infix; + public: + CTreeList *gnu_infix () { return &_gnu_infix; } + const CTreeList *gnu_infix () const { return &_gnu_infix; } + int gnu_infix_pos () const { return 1; } + }; + + // EnumDef + advice "Puma::CT_EnumDef" || + "Puma::CT_EnumSpec" || + "Puma::CT_ClassDef" || + "Puma::CT_ClassSpec": slice class { + CTreeList _gnu_infix; + public: + CTreeList *gnu_infix () { return &_gnu_infix; } + const CTreeList *gnu_infix () const { return &_gnu_infix; } + int gnu_infix_pos () const { return 0; } + }; + + // InitDeclarator + advice "Puma::CT_InitDeclarator" : slice class { + CTreeList _gnu_infix; + public: + CTreeList *gnu_infix () { return &_gnu_infix; } + const CTreeList *gnu_infix () const { return &_gnu_infix; } + int gnu_infix_pos () const { return 0; } + }; + + // Condition + advice "Puma::CT_Condition" : slice class { + CTreeList _gnu_infix; + public: + CTreeList *gnu_infix () { return &_gnu_infix; } + const CTreeList *gnu_infix () const { return &_gnu_infix; } + int gnu_infix_pos () const { return 1; } + }; + + // UsingDirective + advice "Puma::CT_UsingDirective" : slice class { + CTreeList _gnu_infix; + public: + CTreeList *gnu_infix () { return &_gnu_infix; } + const CTreeList *gnu_infix () const { return &_gnu_infix; } + int gnu_infix_pos () const { return 2; } + }; +}; + +#endif /* __ext_gnu_ctree_ah__ */ diff --git a/Puma/src/aspects/ExtGnuKeywords.ah b/Puma/src/aspects/ExtGnuKeywords.ah new file mode 100644 index 0000000..1ef3d4b --- /dev/null +++ b/Puma/src/aspects/ExtGnuKeywords.ah @@ -0,0 +1,176 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __ext_gnu_keywords_h__ +#define __ext_gnu_keywords_h__ + +#include "Puma/Config.h" +#include "Puma/CLexer.h" +#include "Puma/CCLexer.h" +#include + +aspect ExtGnuKeywords { + + static const unsigned int _config_mask_type_traits = 2; + static const unsigned int _config_mask_pic24 = 16; + static const unsigned int _config_mask_local_labels = 32; + static const unsigned int _config_mask_int128 = 64; + + advice "Puma::CScanner" : slice class { + bool _config_type_traits; + bool _config_pic24; + bool _config_local_labels; + bool _config_int128; + }; + + advice construction("Puma::CScanner") : after () { + tjp->that ()->_config_type_traits = false; + tjp->that ()->_config_pic24 = false; + tjp->that ()->_config_local_labels = false; + tjp->that ()->_config_int128 = false; + } + + advice args (config) && + execution("void Puma::CScanner::configure (...)"): + after (const Puma::Config &config) { + tjp->that ()->_config_type_traits = config.Option ("--builtin-type-traits"); + tjp->that ()->_config_pic24 = config.Option ("--gnu-pic24"); + tjp->that ()->_config_int128 = config.Option ("--gnu-int128"); + int gnu_major, gnu_minor, gnu_patchlevel; + // call get_gnu_version to check whether --gnu was given + if (get_gnu_version (config, gnu_major, gnu_minor, gnu_patchlevel)) { + // enabled by default + tjp->that ()->_config_local_labels = true; +#if defined(__SIZEOF_INT128__) + // enabled by default if target supports it + tjp->that ()->_config_int128 = true; +#endif + if (gnu_major == -1 || (gnu_major > 4) || (gnu_major == 4 && gnu_minor >= 3)) { + // set the builtin type traits option (implemented by g++ >= 4.3) + tjp->that ()->_config_type_traits = true; + } + } + } + + advice call ("% Puma::CLexer::instance(...)" || "% Puma::CCLexer::instance(...)") && + within ("Puma::CScanner"): before () { + if (tjp->that ()->_config_type_traits) + *tjp->arg<0>() |= _config_mask_type_traits; + if (tjp->that ()->_config_pic24) + *tjp->arg<0>() |= _config_mask_pic24; + if (tjp->that ()->_config_local_labels) + *tjp->arg<0>() |= _config_mask_local_labels; + if (tjp->that ()->_config_int128) + *tjp->arg<0>() |= _config_mask_int128; + } + + advice execution ("% Puma::CCLexer::add_keywords(...)") : after () { + if (tjp->that ()->_config_mask & _config_mask_type_traits) { + lexertl::rules &rules = *tjp->arg<0>(); + + // C++ type trait operators + rules.push ("__has_nothrow_assign", Puma::TOK_HAS_NOTHROW_ASSIGN, LID(Puma::Token::keyword_id)); + rules.push ("__has_nothrow_copy", Puma::TOK_HAS_NOTHROW_COPY, LID(Puma::Token::keyword_id)); + rules.push ("__has_nothrow_constructor", Puma::TOK_HAS_NOTHROW_CTOR, LID(Puma::Token::keyword_id)); + rules.push ("__has_trivial_assign", Puma::TOK_HAS_TRIVIAL_ASSIGN, LID(Puma::Token::keyword_id)); + rules.push ("__has_trivial_copy", Puma::TOK_HAS_TRIVIAL_COPY, LID(Puma::Token::keyword_id)); + rules.push ("__has_trivial_constructor", Puma::TOK_HAS_TRIVIAL_CTOR, LID(Puma::Token::keyword_id)); + rules.push ("__has_trivial_destructor", Puma::TOK_HAS_TRIVIAL_DTOR, LID(Puma::Token::keyword_id)); + rules.push ("__has_virtual_destructor", Puma::TOK_HAS_VIRTUAL_DTOR, LID(Puma::Token::keyword_id)); + rules.push ("__is_abstract", Puma::TOK_IS_ABSTRACT, LID(Puma::Token::keyword_id)); + rules.push ("__is_base_of", Puma::TOK_IS_BASE_OF, LID(Puma::Token::keyword_id)); + rules.push ("__is_class", Puma::TOK_IS_CLASS, LID(Puma::Token::keyword_id)); + rules.push ("__is_empty", Puma::TOK_IS_EMPTY, LID(Puma::Token::keyword_id)); + rules.push ("__is_enum", Puma::TOK_IS_ENUM, LID(Puma::Token::keyword_id)); + rules.push ("__is_pod", Puma::TOK_IS_POD, LID(Puma::Token::keyword_id)); + rules.push ("__is_trivial", Puma::TOK_IS_TRIVIAL, LID(Puma::Token::keyword_id)); + rules.push ("__is_polymorphic", Puma::TOK_IS_POLYMORPHIC, LID(Puma::Token::keyword_id)); + rules.push ("__is_union", Puma::TOK_IS_UNION, LID(Puma::Token::keyword_id)); + } + } + + advice execution ("% Puma::CLexer::add_c89_keywords(...)") : after () { + lexertl::rules &rules = *tjp->arg<0>(); + + // C compatibility keywords + rules.push ("__asm", Puma::TOK_ASM_2, LID(Puma::Token::keyword_id)); + rules.push ("__asm__", Puma::TOK_ASM_3, LID(Puma::Token::keyword_id)); + rules.push ("__const", Puma::TOK_CONST_2, LID(Puma::Token::keyword_id)); + rules.push ("__const__", Puma::TOK_CONST_3, LID(Puma::Token::keyword_id)); + rules.push ("__inline", Puma::TOK_INLINE_2, LID(Puma::Token::keyword_id)); + rules.push ("__inline__", Puma::TOK_INLINE_3, LID(Puma::Token::keyword_id)); + rules.push ("__signed", Puma::TOK_SIGNED_2, LID(Puma::Token::keyword_id)); + rules.push ("__signed__", Puma::TOK_SIGNED_3, LID(Puma::Token::keyword_id)); + rules.push ("__volatile", Puma::TOK_VOLATILE_2, LID(Puma::Token::keyword_id)); + rules.push ("__volatile__", Puma::TOK_VOLATILE_3, LID(Puma::Token::keyword_id)); + rules.push ("__wchar_t", Puma::TOK_WCHAR_T_2, LID(Puma::Token::keyword_id)); + rules.push ("__thread", Puma::TOK_THREAD, LID(Puma::Token::keyword_id)); + rules.push ("typeof", Puma::TOK_TYPEOF, LID(Puma::Token::keyword_id)); + rules.push ("__typeof", Puma::TOK_TYPEOF_2, LID(Puma::Token::keyword_id)); + rules.push ("__typeof__", Puma::TOK_TYPEOF_3, LID(Puma::Token::keyword_id)); + rules.push ("__decltype", Puma::TOK_TYPEOF_4, LID(Puma::Token::keyword_id)); + rules.push ("__alignof", Puma::TOK_ALIGNOF_2, LID(Puma::Token::keyword_id)); + rules.push ("__alignof__", Puma::TOK_ALIGNOF_3, LID(Puma::Token::keyword_id)); + rules.push ("__builtin_offsetof", Puma::TOK_OFFSETOF, LID(Puma::Token::keyword_id)); + rules.push ("__attribute__", Puma::TOK_ATTRIBUTE, LID(Puma::Token::keyword_id)); + rules.push ("__extension__", Puma::TOK_EXTENSION, LID(Puma::Token::keyword_id)); + rules.push ("__restrict", Puma::TOK_RESTRICT_2, LID(Puma::Token::keyword_id)); + rules.push ("__restrict__", Puma::TOK_RESTRICT_3, LID(Puma::Token::keyword_id)); + + // PIC24/dsPIC CV-qualifiers + if (tjp->that ()->_config_mask & _config_mask_pic24) { + rules.push ("__psv__", Puma::TOK_PSV, LID(Puma::Token::keyword_id)); + rules.push ("__pmp__", Puma::TOK_PMP, LID(Puma::Token::keyword_id)); + rules.push ("__external__", Puma::TOK_EXTERNAL, LID(Puma::Token::keyword_id)); + } + + // Local labels + if (tjp->that ()->_config_mask & _config_mask_local_labels) { + rules.push ("__label__", Puma::TOK_LABEL, LID(Puma::Token::keyword_id)); + } + + // 128-bit integer type + if (tjp->that ()->_config_mask & _config_mask_int128) { + rules.push ("__int128", Puma::TOK_INT128, LID(Puma::Token::keyword_id)); + } + } + + // ---------------------------------------------------- + // get the configuration and check whether the GNU mode is enabled + // ---------------------------------------------------- + + bool get_gnu_version (const Puma::Config &config, int &major, int &minor, int &patchlevel) { + const Puma::ConfOption *gnu_option = config.Option ("--gnu"); + if (!gnu_option) + return false; + major = -1; + minor = -1; + patchlevel = -1; + const char *gnu_version_str = (gnu_option->Arguments() == 1) ? gnu_option->Argument (0) : 0; + if (gnu_version_str) { + char sep; + std::istringstream in (gnu_version_str); + if (in.good()) in >> major; + if (in.good()) in >> sep >> minor; + if (in.good()) in >> sep >> patchlevel; + } + return true; + } +}; + +#endif /* __ext_gnu_keywords_h__ */ diff --git a/Puma/src/aspects/GenericProfiler.ah b/Puma/src/aspects/GenericProfiler.ah new file mode 100644 index 0000000..fd697e3 --- /dev/null +++ b/Puma/src/aspects/GenericProfiler.ah @@ -0,0 +1,197 @@ +#ifndef __genericprofiler_ah__ +#define __genericprofiler_ah__ + +#include +#include +#include +#include + + +// GenericProfiler - generic aspect to gather profiling information +// (Group, name and signature of each executed function, how often the function +// was executed and how many clock cycles were spent executing it.) +// While the names and signatures are determined automatically, the group +// is a user defined value that may be used to arbitrarily define a group +// of functions. Depending on the output format an overall execution time for +// each group will be summarized. +// For each group an own profiling aspect derived from GenericProfiler must be +// defined. +// +// The derived aspects must define a match expression for the functions +// to be profiled: +// +// pointcut virtual measureFct () = ... ; +// +// One of the derived aspects should also register a function to print the +// profiling information. The registration may be done for example as an +// after() advive for the main() function, or with help of the atexit() call. +// Example implementations of the statistic functions are print_group_stat() +// and csv_stat(). +// +// The GenericProfiler aspect uses the time stamp counter of the x86 +// processors to measure the execution time in clock cycles. +// When the profiling aspect should be used on other architectures +// the rdtsc() function and possibly the definition of the typedef +// ClockTicks and the function duration() must be replaced accordingly. + + + +namespace Profiler { + + typedef unsigned long long int ClockTicks; + + // rdtsc() - read the time stamp counter of x86 processors + extern inline ClockTicks rdtsc() { + unsigned long long int x; + __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x)); + return x; + } + + // duration() - calculate time spent between start and stop + extern inline ClockTicks duration(ClockTicks start, ClockTicks end) { + if (end > start) { + return (end - start); + } else { // counter overflow + return (ClockTicks)(-1LL) - end + start; + } + } + + // Data structure used to gather the profiling information + // New Data objects link themselves to existing ones at creation + // time. + struct Data { + static Data *&first () { static Data *data = 0; return data; } + struct Data *_next; + unsigned _calls; + ClockTicks _time; + const char *_name; + const char* _title; + unsigned _depth; + Data (const char* n, const char* t) : _calls(0), _time(0L), + _name (n), _title(t), _depth(0) { + Data *head = first (); + first () = this; + _next = head; + } + + static Profiler::ClockTicks& groupTime (const char* groupname) { + static map data; + return data[groupname]; + } + }; +} + + +// GenericProfiler aspect +aspect GenericProfiler { + + // user defined title for a group of functions + const char* _title; + int _grpdepth; + + GenericProfiler (const char* t = NULL) : _title(t), _grpdepth(0) {} + + // Do not measure the Profiler's own methods + pointcut dontMeasure () = "% Profiler::...::%(...)" || + "% GenericProfiler::...::%(...)"; + + // Pure virtual pointcut: to be specified in a derived aspect + pointcut virtual measureFct () = 0; + + // Execution advice for the functions that are to be measured. + // For each JoinPoint the advice code will be transformed into + // a new template function instantiation. Therefore a new Data object + // will be created whenever a function is executed the first time. + // Further executions of the same function will reuse this object, + // enabling it to count the number of invocations and the overall + // time consumed. + // When the function is called recursively, only measure the duration + // of the outmost invocation. + advice execution(measureFct() && !dontMeasure()) : around() { + static Profiler::Data data (JoinPoint::signature (), _title); + _grpdepth++; + data._depth++; + if (data._depth == 1) { + Profiler::ClockTicks start = Profiler::rdtsc(); + tjp->proceed(); + Profiler::ClockTicks end = Profiler::rdtsc(); + Profiler::ClockTicks duration = Profiler::duration (start, end); + data._time += duration; + if (_grpdepth == 1) + Profiler::Data::groupTime(data._title) += duration; + } else { + tjp->proceed(); + } + data._calls++; + data._depth--; + _grpdepth--; + }; + + + // Prints the profiling statistics gathered by *all* profiling aspects + // sorted by groups of functions. + static void print_group_stat () { + + // gather information about the different groups + set groups; + for (Profiler::Data *curr = Profiler::Data::first (); + curr; curr = curr->_next) { + if (curr->_title != NULL) + groups.insert(curr->_title); + } + + // print statistics about the groups and their members + for (set::iterator iter = groups.begin(); + iter != groups.end(); iter++) { + std::cout << "group: " << *iter << std::endl; + + for (Profiler::Data *curr = Profiler::Data::first (); + curr; curr = curr->_next) { + if (curr->_title == *iter) { + std::cout << " function: " << curr->_name << std::endl; + std::cout << " no of execs: " << curr->_calls << std::endl; + std::cout << " total time: " << curr->_time << std::endl << std::endl; + } + } + std::cout << "total time: " << Profiler::Data::groupTime(*iter) << std::endl; + std::cout << "---" << std::endl << std::endl; + } + + // print statistics about functions that do not belong to a group + for (Profiler::Data *curr = Profiler::Data::first (); + curr; curr = curr->_next) { + if (curr->_title == NULL) { + std::cout << "function: " << curr->_name << std::endl; + std::cout << "no of execs: " << curr->_calls << std::endl; + std::cout << "total time: " << curr->_time << std::endl << std::endl; + } + } + } + + + // Print an unsorted summary using the csv format + static void csv_stat () { + std::cout << "group ; group time (clock cycles) ;" + << "function ; number of executions ; " + << "total time (clock cycles)" << std::endl; + for (Profiler::Data *curr = Profiler::Data::first (); + curr; curr = curr->_next) { + if (curr->_title == NULL) { + std::cout << " ; ; "; + } else { + std::cout << curr->_title << " ; " ; + std::cout << Profiler::Data::groupTime (curr->_title) << " ; "; + } + std::cout << curr->_name << " ; " + << curr->_calls << " ; " + << curr->_time << std::endl; + } + } + + // Function that may be registered, when no summary is requested + static void no_stat() {} + +}; + + +#endif diff --git a/Puma/src/aspects/PragmaOnce.ah b/Puma/src/aspects/PragmaOnce.ah new file mode 100644 index 0000000..6ebb396 --- /dev/null +++ b/Puma/src/aspects/PragmaOnce.ah @@ -0,0 +1,98 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __PragmaOnce__ +#define __PragmaOnce__ + +/********************************************************/ +/* Win #pragma once support aspect */ +/********************************************************/ + +#include +#include + +#include "Puma/Unit.h" +#include "Puma/Token.h" + + +aspect PragmaOnce { + /******************************************************/ + /* detect #pragma once in the token stream of cpp */ + /******************************************************/ + + // pointcut definitions + pointcut preparser () = "Puma::PreprocessorParser"; + pointcut preincluder () = "Puma::PreFileIncluder"; + + // extend the preprocessor parser by the filter state + advice preparser () : slice class { Puma::Token * _pragma_token; }; + + // initialize the filter state + advice execution ("% Puma::PreprocessorParser::configure (...)") : after () { + // TODO: it would be better to have construction advice -> but in lem file + tjp->that ()->_pragma_token = 0; + } + + // filter #pragma once + advice call ("% Puma::PreprocessorParser::parseToken ()") : after () { + Puma::Token *tok = *tjp->result (); + JoinPoint::That &that = *tjp->that (); + if (!tok || !tok->is_directive ()) { + that._pragma_token = 0; + return; + } + if (strcmp ("#pragma", tok->text ()) == 0) { + that._pragma_token = tok; + } + else if (that._pragma_token && strcmp ("once", tok->text ()) == 0) { + Puma::Unit *unit = (Puma::Unit*)tok->belonging_to (); + assert (unit); + unit->state ().onlyOnce (true); + } + } + + /********************************************************/ + /* block the handling of pragma once files */ + /********************************************************/ + + // don't let file includer include files twice + // to be precise: the file is included again, but the inclusion produces + // no tokens + advice args (unit) && within (preincluder ()) && + execution ("void ...::pushOnStack(...)") : + around (Puma::Unit *unit) { + if (! unit || ! unit->state ().onlyOnce ()) + tjp->proceed (); + } + + // includeFile shall return 0 if the file was not included + advice within (preincluder ()) && + execution ("Puma::Unit * ...::includeFile(...)") : after () { + Puma::Unit *&unit = *tjp->result (); + if (unit && unit->state ().onlyOnce ()) + //unit = 0; + tjp->that ()->_guarded = true; + } + +protected: + // this aspect should never be instantiated directly + PragmaOnce () {} +}; + + +#endif /* __PragmaOnce__ */ diff --git a/Puma/src/aspects/PragmaOnceUnitState.ah b/Puma/src/aspects/PragmaOnceUnitState.ah new file mode 100644 index 0000000..6768f4d --- /dev/null +++ b/Puma/src/aspects/PragmaOnceUnitState.ah @@ -0,0 +1,59 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 PUMA_PragmaOnceUnitState_AH +#define PUMA_PragmaOnceUnitState_AH + +aspect PragmaOnceUnitState { + /******************************************************/ + /* specific #pragma once unit state */ + /******************************************************/ + + // pointcut definitions + pointcut unitstate () = "Puma::UnitState"; + + advice unitstate () : slice class { + // introduce new state flag + bool m_once; + public: + // introduce methods to access new state flag + bool onlyOnce () const { return m_once; } + void onlyOnce (bool v) { m_once = v; } + }; + + // initialize new state flag + advice construction (unitstate ()) : after () { + thisJoinPoint->that ()->m_once = false; + } + + // initialize new flag for all managed units + advice execution ("void Puma::UnitManager::init()") : after() { + // go through the whole unit hash table and reset the + // `#pragma once' state of the units + typename JoinPoint::That::UMapIter iter; + for (iter = tjp->that()->_umap.begin (); iter != tjp->that()->_umap.end (); ++iter) + (*iter).second->state ().onlyOnce (false); + } + +protected: + // this aspect should never be instantiated directly + PragmaOnceUnitState () {} +}; + + +#endif /* PUMA_PragmaOnceUnitState_AH */ diff --git a/Puma/src/aspects/Profiler.ah b/Puma/src/aspects/Profiler.ah new file mode 100644 index 0000000..e72e38c --- /dev/null +++ b/Puma/src/aspects/Profiler.ah @@ -0,0 +1,61 @@ +#ifndef __profiler_ah__ +#define __profiler_ah__ + +#include "Puma/GenericProfiler.ah" +#include + + // These functions cannot be woven due to ac++ problems: + // pointcut virtual measureFct () = "% ...::% (...)" && + // !"% CSVProfiler::%(...)" && + // !"% ...::operator new(...)" && + // !"% ...::operator delete(...)" && + // !"% ...::yy_%(...)" && + // !"% void PreExprParser(...)" && + // !"% void CMatchParser(...)"; + +//aspect PathManagerProfiler : public GenericProfiler { +// +// PathManagerProfiler() : GenericProfiler("PathManager") {} +// +// pointcut virtual measureFct () = "% Puma::PathManager::%(...)"; +//}; + +aspect SyscallProfiler : public GenericProfiler { + + SyscallProfiler() : GenericProfiler("SysCall") {} + + pointcut virtual measureFct () = "% Puma::SysCall::%(...)"; +}; + +aspect NameLookupProfiler : public GenericProfiler { + + NameLookupProfiler() : GenericProfiler("NameLookup") {} + + pointcut virtual measureFct () = "% Puma::CCNameLookup::lookup%(...)"; +}; + +aspect SemanticProfiler : public GenericProfiler { + + SemanticProfiler() : GenericProfiler("Semantic") {} + + pointcut virtual measureFct () = "Puma::CTree *Puma::CCSemantic::%(...)"; +}; + +aspect NoGroupProfiler : public GenericProfiler { + + NoGroupProfiler() { + atexit (csv_stat); + } + + pointcut virtual measureFct () = + "% Puma::CScanner::scan_all(...)" || + "% Puma::PreprocessorParser::next()" || + "% Puma::Parser::parse(...)" || + "% Puma::CCInstantiation::instantiate(...)" || + "% Puma::CScanner::make_token(...)" || + "% Puma::CRecognizer::recognize(...)" || + "% Puma::ManipCommander::commit(...)"; + +}; + +#endif diff --git a/Puma/src/aspects/TraceSyntax.ah b/Puma/src/aspects/TraceSyntax.ah new file mode 100644 index 0000000..c6d0654 --- /dev/null +++ b/Puma/src/aspects/TraceSyntax.ah @@ -0,0 +1,174 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __TraceSyntax_ah__ +#define __TraceSyntax_ah__ + +#ifndef NDEBUG +#define __PUMA_TRACING__ + +#include "Puma/Tracing.h" + + +namespace Puma { + class CTree; +} + + +aspect TraceSyntax : public Puma::Tracing { + int skipping; + + void trace_rule (const char *sig) { + char rule[256]; + while (*sig != ' ') + sig++; + sig += 1; + while (*sig != ':') + sig++; + sig += 2; + char *rptr = rule; + while (*sig != '(') + *rptr++ = *sig++; + *rptr = '\0'; + trace (rule); + } + + void trace_rule2 (const char *sig) { + char rule[256]; + while (*sig != ':') + sig++; + sig += 2; + char *rptr = rule; + while (*sig != ':') + *rptr++ = *sig++; + *rptr++ = *sig++; + *rptr++ = *sig++; + while (*sig != ':') + *rptr++ = *sig++; + *rptr = '\0'; + trace (rule); + } + +public: + TraceSyntax () : skipping (0) {} + + // Create instances an define locator function + static TraceSyntax* aspectOf () + { return thisJoinPoint->that ()->trace_aspect (); } + + // structural extensions + pointcut syntax () = "Puma::Syntax"; + pointcut parser () = "Puma::Parser"; + + advice syntax () : slice class { + TraceSyntax __trace; + public: + TraceSyntax *trace_aspect () { return &__trace; } + Puma::TokenProvider *__tp () { return token_provider; } + }; + + // add initialization function to Parser + advice parser () : slice class { + public: + void trace (std::ostream &out, bool tokens = false) { + syntax->trace_aspect ()->trace (out, tokens); + } + }; + + // advice code for rules + advice call ("bool Puma::%CSyntax::%::parse(...)") : + order ("TraceSyntax", !"TraceSyntax"); + + advice within (derived (syntax ())) && !within("Puma::%::...::%") && + call ("bool Puma::%CSyntax::%::parse(...)") : around () { + trace_rule2 (JoinPoint::signature ()); + tjp->proceed (); + trace (*tjp->result () ? "ACCEPT" : "FAILED", -1); + } + + advice within (derived (syntax ()) && ! syntax ()) && + execution ("%::CTree * Puma::%::%()") : before () + { trace_rule (JoinPoint::signature ()); } + + advice within (syntax ()) && args (res, "%::Syntax::State") && + execution ("bool Puma::%::accept(...)") : before (Puma::CTree *res) { + trace (res ? "ACCEPT" : "FAILED", -1); + } + + advice within (syntax ()) && args (res) && + execution ("% Puma::%::accept(...)") : before (Puma::CTree *res) { + trace (res ? "ACCEPT" : "FAILED", -1); + } + + advice within (syntax ()) && execution ("% Puma::%::locate_token()") : after () + { if (! skipping) this->trace (thisJoinPoint->that ()-> + __tp ()->current (), "INPUT", "INPUT END"); } + + // trace reset operations + // because of a problem in AspectC++ or PUMA we cannot expose 'state' here!!! fix me. + advice within (syntax ()) && call ("% Puma::TokenProvider::set_state(...)") /* && + args (state) */ : around (/* TokenProvider::State state */) { + bool diff = (*tjp->arg<0>() != tjp->target ()->get_state ()); + tjp->proceed (); + if (diff) { + Puma::TokenInfo& info = **tjp->arg<0>(); + trace (info._token, "RESET", "INPUT END"); + } + } + + // tracing for token provider calls within skip functions + advice within (syntax ()) && call ("% Puma::TokenProvider::next()") : before () + { if (skipping && trace_mode ()) + tos () << thisJoinPoint->target ()->current ()->text () << " "; } + + // trace token if required + advice within (syntax ()) && execution ("bool Puma::%::parse_token(...)") && + args (tok) : around (int tok) + { if (trace_mode () == 2) trace (tok); + thisJoinPoint->action ().trigger (); + if (trace_mode () == 2) + trace (*(bool*)thisJoinPoint->result () ? "ACCEPT" : "FAILED", -1);} + + // trace consumed tokens + advice within (syntax ()) && execution ("bool Puma::%::consume()") : before () { + if (trace_mode () == 2) { + trace (tjp->that ()->token_provider->current ()->type ()); + trace ("ACCEPT", -1); + } + } + + advice within (syntax ()) && execution ("% Puma::%::skip(...)") : around () { + skipping++; + if (trace_mode ()) tos () << "SKIP: "; + thisJoinPoint->action ().trigger (); + if (trace_mode ()) tos () << std::endl; + skipping--; + } + + advice within (syntax ()) && execution ("% Puma::%::skip_block()") : around () { + skipping++; + if (trace_mode ()) tos () << "SKIP_BLOCK: "; + thisJoinPoint->action ().trigger (); + if (trace_mode ()) tos () << std::endl; + skipping--; + } +}; + +#endif + +#endif /* __TraceSyntax_ah__ */ diff --git a/Puma/src/aspects/WinAsm.ah b/Puma/src/aspects/WinAsm.ah new file mode 100644 index 0000000..9361a01 --- /dev/null +++ b/Puma/src/aspects/WinAsm.ah @@ -0,0 +1,142 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __WinAsm__ +#define __WinAsm__ + +/********************************************************/ +/* Win asm support aspect */ +/********************************************************/ + +#include "Puma/WinCTree.h" + + +namespace Puma { + class CCSyntax; + class CCBuilder; +} + +namespace Puma { + slice class WinAsmSyntax; + slice class WinAsmBuilder; +} + +aspect WinAsm { + /********************************************************/ + /* Visual C++ asm statement */ + /********************************************************/ + + // pointcut definitions + pointcut syntax () = classes ("Puma::CSyntax"); + pointcut builder () = classes ("Puma::CBuilder"); + + // extend the builder + advice builder () : slice Puma::WinAsmBuilder; + + // add rules to the syntax + advice syntax () : slice Puma::WinAsmSyntax; + + // let first parse asm_block() and then stmt() if failed + advice within (derived (syntax ())) && execution ("% Puma::%::stmt()") : after () { + if (!*tjp->result () && tjp->that ()->asm_block ()) + *tjp->result () = tjp->that ()->builder().stmt (); + } + +protected: + WinAsm () {} +}; + +slice class Puma::WinAsmSyntax { +public: + virtual bool asm_block (); + Puma::CTree * rule_asm_block (); +}; + +slice bool Puma::WinAsmSyntax::asm_block () { + return look_ahead (Puma::TOK_ASM) && parse (&WinAsmSyntax::rule_asm_block); +} + +slice Puma::CTree *Puma::WinAsmSyntax::rule_asm_block () { + // 3: ASM { } + consume (); // Puma::TOK_ASM already checked by prediction + + // asm declaration + if ((CvQual::check (*this), parse (Puma::TOK_OPEN_ROUND))) + return (Puma::CTree*)0; + + Puma::Token *current, *asm_begin, *asm_end; + + asm_begin = token_provider->current (); + asm_end = 0; + + // ASM { ... } + if (look_ahead (Puma::TOK_OPEN_CURLY)) { + skip_curly_block (); + current = token_provider->current (); + while ((current = (Puma::Token*)current->belonging_to ()->prev (current)) && + ! current->is_core ()); + asm_end = current; + // ASM ... + } else { + int token; + static int stop_tokens[] = { Puma::TOK_CLOSE_CURLY, Puma::TOK_SEMI_COLON, 0 }; + + while ((current = token_provider->current ())) { + token = current->type (); + + if (is_in (token, stop_tokens)) { + asm_end = current; + break; + } else if (asm_begin->location () < current->location ()) { + while ((current = (Puma::Token*)current->belonging_to ()->prev (current)) && + ! current->is_core ()); + asm_end = current; + break; + } + + if (token == Puma::TOK_OPEN_CURLY) + skip_curly_block (); + else if (token == Puma::TOK_OPEN_ROUND) + skip_round_block (); + else { + token_provider->next (); + locate_token (); + } + } + } + + if (! asm_end) + return (Puma::CTree*)0; + + builder ().Push (builder ().token (asm_begin)); + builder ().Push (builder ().token (asm_end)); + return builder ().asm_block (); +} + +slice class Puma::WinAsmBuilder { +public: + virtual Puma::CTree * asm_block (); +}; + +slice Puma::CTree * Puma::WinAsmBuilder::asm_block () { + // 3: ASM { } + return new Puma::CT_AsmBlock (get_node (0), get_node (1), get_node (2)); +} + + +#endif /* __WinAsm__ */ diff --git a/Puma/src/aspects/WinDeclSpecs.ah b/Puma/src/aspects/WinDeclSpecs.ah new file mode 100644 index 0000000..1a2dfb8 --- /dev/null +++ b/Puma/src/aspects/WinDeclSpecs.ah @@ -0,0 +1,130 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __WinDeclSpecs__ +#define __WinDeclSpecs__ + +/********************************************************/ +/* Win declaration specifiers support aspect */ +/********************************************************/ + +#include "Puma/CTokens.h" + +namespace Puma { + class CCSyntax; + class CCBuilder; + class CTree; +} + +namespace Puma { + slice class WinDeclSpecsSyntax; + slice class WinDeclSpecsBuilder; +} + +aspect WinDeclSpecs { + /********************************************************/ + /* Win declaration specifiers */ + /********************************************************/ + + // pointcut definitions + pointcut syntax () = classes ("Puma::CSyntax"); + pointcut builder () = classes ("Puma::CBuilder"); + + advice syntax () : slice class Puma::WinDeclSpecsSyntax; + advice builder () : slice class Puma::WinDeclSpecsBuilder; + + // extended declaration specifiers + advice within (derived (syntax ())) && + execution ("void Puma::%::init_misc_spec()") : after () { + tjp->that ()->_misc_spec_1.set (Puma::TOK_CDECL); + tjp->that ()->_misc_spec_1.set (Puma::TOK_STDCALL); + tjp->that ()->_misc_spec_1.set (Puma::TOK_FASTCALL); + } + + // extended cv qualifier + advice within (derived (syntax ())) && + execution ("void Puma::%::init_cv_quals()") : after () { + tjp->that ()->_cv_quals.set (Puma::TOK_CDECL); + tjp->that ()->_cv_quals.set (Puma::TOK_STDCALL); + tjp->that ()->_cv_quals.set (Puma::TOK_FASTCALL); + } + + // let first parse the win declaration specifiers + advice execution ("% Puma::CSyntax::rule_direct_declarator()") : around () { + Puma::CTree *&result = *(Puma::CTree**)tjp->result (); + if ((tjp->that ()->declarator_id () || + (tjp->that ()->parse (Puma::TOK_OPEN_ROUND) && + (tjp->that ()->win_decl_spec (), + tjp->that ()->declarator ()) && + tjp->that ()->parse (Puma::TOK_CLOSE_ROUND))) && + tjp->that ()->opt ( + tjp->that ()->seq (&JoinPoint::That::direct_declarator1))) + result = tjp->that ()->builder ().direct_declarator (); + else + result = (Puma::CTree*)0; + } + + // let first parse the win declaration specifiers + advice execution ("% Puma::CSyntax::rule_direct_abst_declarator()") : around () { + Puma::CTree *&result = *(Puma::CTree**)tjp->result (); + if ((tjp->that ()->direct_abst_declarator1 () || + (tjp->that ()->parse (Puma::TOK_OPEN_ROUND) && + (tjp->that ()->win_decl_spec (), + tjp->that ()->abst_declarator ()) && + tjp->that ()->parse (Puma::TOK_CLOSE_ROUND))) && + tjp->that ()->opt ( + tjp->that ()->seq (&JoinPoint::That::direct_abst_declarator1))) + result = tjp->that ()->semantic ().direct_abst_declarator (); + else + result = (Puma::CTree*)0; + } + +protected: + WinDeclSpecs () {} +}; + +slice class Puma::WinDeclSpecsSyntax { +public: + // introduce new rule to class CSyntax + Puma::CTree * rule_win_decl_spec (); + virtual bool win_decl_spec (); +}; + +slice Puma::CTree * Puma::WinDeclSpecsSyntax::rule_win_decl_spec () { + static int win_decl_specs[] = { + Puma::TOK_CDECL, Puma::TOK_STDCALL, Puma::TOK_FASTCALL, 0 + }; + return parse (win_decl_specs) ? + builder ().win_decl_spec () : (Puma::CTree*)0; +} + +slice bool Puma::WinDeclSpecsSyntax::win_decl_spec () { + return parse (&WinDeclSpecsSyntax::rule_win_decl_spec); +} + +slice class Puma::WinDeclSpecsBuilder { +public: + // introduce new builder rule + virtual Puma::CTree * win_decl_spec (); +}; + +slice Puma::CTree * Puma::WinDeclSpecsBuilder::win_decl_spec () { + return get_node (); +} + +#endif /* __WinDeclSpecs__ */ diff --git a/Puma/src/aspects/WinFriend.ah b/Puma/src/aspects/WinFriend.ah new file mode 100644 index 0000000..6446751 --- /dev/null +++ b/Puma/src/aspects/WinFriend.ah @@ -0,0 +1,52 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __WinFriend__ +#define __WinFriend__ + +/********************************************************/ +/* Win friend declaration syntax without class key. */ +/********************************************************/ + +namespace Puma { + class CCSyntax; + class CCBuilder; + class CTree; +} // namespace Puma + +#include "Puma/CTokens.h" + +aspect WinFriend { + /********************************************************/ + /* Win friend declaration syntax */ + /********************************************************/ + + // parse the win friend declaration syntax + advice execution ("% Puma::CCSyntax::rule_member_decl1()") : around () { + tjp->proceed (); + Puma::CTree *&result = *(Puma::CTree**)tjp->result (); + // 3: FRIEND class_name ; + if (! result && + tjp->that ()->parse (Puma::TOK_FRIEND) && + tjp->that ()->class_name () && + tjp->that ()->parse (Puma::TOK_SEMI_COLON)) + result = tjp->that ()->semantic ().member_decl1 (); + } +}; + +#endif /* __WinFriend__ */ diff --git a/Puma/src/aspects/WinIfExists.ah b/Puma/src/aspects/WinIfExists.ah new file mode 100644 index 0000000..a05dee8 --- /dev/null +++ b/Puma/src/aspects/WinIfExists.ah @@ -0,0 +1,134 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __WinIfExists__ +#define __WinIfExists__ + +/********************************************************/ +/* Win __if_exists and __if_not_exists support aspect */ +/********************************************************/ + +#include "Puma/Stack.h" +#include "Puma/CTokens.h" +#include "Puma/Token.h" + +namespace Puma { + +slice class WinIfExistsCpp { +public: + // introduce data member into preprocessor + Puma::Stack _depth; + + // skip __if_exists resp. __if_not_exists statement + void skip_up_to (int end_token) { + unsigned parenthesis = 0, curlies = 0; + Puma::Token *token; + int type; + + // skip up to the first non-nested `{' + while ((token = parseToken ())) { + type = token->type (); + if (type == Puma::TOK_OPEN_CURLY) { + if (parenthesis == 0 && curlies == 0) + break; + curlies++; + } else if (type == Puma::TOK_CLOSE_CURLY) + curlies--; + else if (type == Puma::TOK_OPEN_ROUND) + parenthesis++; + else if (type == Puma::TOK_CLOSE_ROUND) + parenthesis--; + } + + // skip up to the first non-nested `}' + if (end_token == Puma::TOK_CLOSE_CURLY) { + parenthesis = curlies = 0; + while ((token = parseToken ())) { + type = token->type (); + if (type == Puma::TOK_OPEN_CURLY) + curlies++; + else if (type == Puma::TOK_CLOSE_CURLY) { + if (parenthesis == 0 && curlies == 0) + break; + curlies--; + } else if (type == Puma::TOK_OPEN_ROUND) + parenthesis++; + else if (type == Puma::TOK_CLOSE_ROUND) + parenthesis--; + } + } + } +}; + +} + +aspect WinIfExists { + /********************************************************/ + /* Win __if_exists and __if_not_exists */ + /********************************************************/ + + // pointcut definitions + pointcut cpp () = classes ("Puma::PreprocessorParser"); + + // structural extensions + advice cpp () : slice class Puma::WinIfExistsCpp; + + // preprocess __if_exists and __if_not_exists statements + advice execution ("% Puma::PreprocessorParser::next()") : around () { + Puma::Token *token; + int type; + JoinPoint::That *preparser; + + preparser = tjp->that (); + tjp->proceed (); // get the next token + token = *tjp->result (); + if (token) { + type = token->type (); + // __if_exists (...) { ... } + if (type == Puma::TOK_IF_EXISTS) { + preparser->skip_up_to (Puma::TOK_CLOSE_CURLY); + *(Puma::Token**)thisJoinPoint->result () = preparser->next (); + return; + // __if_not_exists (...) { ... } + } else if (type == Puma::TOK_IF_NOT_EXISTS) { + preparser->skip_up_to (Puma::TOK_OPEN_CURLY); + preparser->_depth.push (1); + *(Puma::Token**)thisJoinPoint->result () = preparser->next (); + return; + } + // skip closing `}' of __if_not_exists + if (preparser->_depth.length ()) { + if (type == Puma::TOK_OPEN_CURLY) + preparser->_depth.top () = preparser->_depth.top () + 1; + else if (type == Puma::TOK_CLOSE_CURLY) { + preparser->_depth.top () = preparser->_depth.top () - 1; + if (preparser->_depth.top () == 0) { + preparser->_depth.pop (); + *(Puma::Token**)thisJoinPoint->result () = preparser->next (); + return; + } + } + } + } + } + +protected: + WinIfExists () {} +}; + +#endif /* __WinIfExists__ */ diff --git a/Puma/src/aspects/WinImportHandler.ah b/Puma/src/aspects/WinImportHandler.ah new file mode 100644 index 0000000..f16f8c6 --- /dev/null +++ b/Puma/src/aspects/WinImportHandler.ah @@ -0,0 +1,65 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __WinImportHandler__ +#define __WinImportHandler__ + +/********************************************************/ +/* Win #import directive support */ +/********************************************************/ + +#include "Puma/Config.h" +#include + + +aspect WinImportHandler { + /********************************************************/ + /* Win #import directive */ + /********************************************************/ + + // pointcuts + pointcut cpp () = classes ("Puma::PreprocessorParser"); + + // handle --import-handler option + advice args (config, process_includes) && + execution ("void Puma::PreprocessorParser::configure(...)") : + before (const Puma::Config &config, bool process_includes) { + const Puma::ConfOption *opt; + char *tmp; + + if (process_includes) { + opt = config.Option ("--import-handler"); + if (opt && opt->Arguments ()) { + // delete old import handler + if (thisJoinPoint->that ()->_importHandler) + delete[] thisJoinPoint->that ()->_importHandler; + + // get new import handler + tmp = new char[strlen (opt->Argument (0))+1]; + strcpy (tmp, opt->Argument (0)); + thisJoinPoint->that ()->_importHandler = tmp; + } + } + } + +protected: + WinImportHandler () {} +}; + + +#endif /* __WinImportHandler__ */ diff --git a/Puma/src/aspects/WinKeywords.ah b/Puma/src/aspects/WinKeywords.ah new file mode 100644 index 0000000..ee5c080 --- /dev/null +++ b/Puma/src/aspects/WinKeywords.ah @@ -0,0 +1,76 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __win_keywords_ah__ +#define __win_keywords_ah__ + +#include "Puma/Config.h" +#include "Puma/CLexer.h" + +aspect WinKeywords { + + // ---------------------------------------------------- + // extend the scanner to recognize VC++ tokens + // ---------------------------------------------------- + + static const unsigned int _config_mask_visual_c = 8; + + advice "Puma::CScanner" : slice class { bool _config_visual_c; }; + + advice construction("Puma::CScanner") : after () { + tjp->that ()->_config_visual_c = false; + } + + advice args (config) && + execution("void Puma::CScanner::configure (...)"): + after (const Puma::Config &config) { + tjp->that()->_config_visual_c = false; + // check whether --vc was given and potentially enable VisualC++ keywords + if (config.Option ("--vc")) { + tjp->that()->_config_visual_c = true; + } + } + + advice call ("% Puma::CLexer::instance(...)" || + "% Puma::CCLexer::instance(...)") && + within ("Puma::CScanner"): before () { + if (tjp->that ()->_config_visual_c) + *tjp->arg<0>() |= _config_mask_visual_c; + } + + advice execution ("% Puma::CLexer::add_c89_keywords(...)") : after () { + if (tjp->that ()->_config_mask & _config_mask_visual_c) { + + lexertl::rules &rules = *tjp->arg<0>(); + + // C win specific keywords + rules.push ("__int64", Puma::TOK_INT64, LID(Puma::Token::keyword_id)); + rules.push ("_cdecl", Puma::TOK_CDECL, LID(Puma::Token::keyword_id)); + rules.push ("__cdecl", Puma::TOK_CDECL_2, LID(Puma::Token::keyword_id)); + rules.push ("_stdcall", Puma::TOK_STDCALL, LID(Puma::Token::keyword_id)); + rules.push ("__stdcall", Puma::TOK_STDCALL_2, LID(Puma::Token::keyword_id)); + rules.push ("_fastcall", Puma::TOK_FASTCALL, LID(Puma::Token::keyword_id)); + rules.push ("__fastcall", Puma::TOK_FASTCALL_2, LID(Puma::Token::keyword_id)); + rules.push ("__if_exists", Puma::TOK_IF_EXISTS, LID(Puma::Token::keyword_id)); + rules.push ("__if_not_exists", Puma::TOK_IF_NOT_EXISTS, LID(Puma::Token::keyword_id)); + } + } + +}; + +#endif /* __win_keywords_ah__ */ diff --git a/Puma/src/aspects/WinMacros.ah b/Puma/src/aspects/WinMacros.ah new file mode 100644 index 0000000..801f2cd --- /dev/null +++ b/Puma/src/aspects/WinMacros.ah @@ -0,0 +1,60 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __WinMacros__ +#define __WinMacros__ + +/********************************************************/ +/* Win predefined macros aspect */ +/********************************************************/ + +#include "Puma/PreMacro.h" +#include "Puma/Config.h" + + +aspect WinMacros { + /********************************************************/ + /* Win specific predefined macros */ + /********************************************************/ + + // predefine win specific macros + advice execution ("void Puma::PreprocessorParser::configure(...)") && + args (config, "bool") : before (const Puma::Config &config) { + if (config.Option ("--vc")) { + // constants + thisJoinPoint->that ()->defMacro ("__w64", " "); + thisJoinPoint->that ()->defMacro ("_inline", "inline"); + thisJoinPoint->that ()->defMacro ("__forceinline", "inline"); + thisJoinPoint->that ()->defMacro ("__interface", "class"); + thisJoinPoint->that ()->defMacro ("__try", "if(1)"); + thisJoinPoint->that ()->defMacro ("__except", "if"); + thisJoinPoint->that ()->defMacro ("__noop", " "); + + // function-like macros + Puma::PreMacro *declspec_macro = new Puma::PreMacro ("__declspec", " "); + declspec_macro->addArg ("__arg0"); + thisJoinPoint->that ()->macroManager ()->addMacro (declspec_macro); + } + } + +protected: + WinMacros () {} +}; + + +#endif /* __WinMacros__ */ diff --git a/Puma/src/aspects/WinMemberExplSpec.ah b/Puma/src/aspects/WinMemberExplSpec.ah new file mode 100644 index 0000000..7c68957 --- /dev/null +++ b/Puma/src/aspects/WinMemberExplSpec.ah @@ -0,0 +1,80 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __WinMemberExplSpec__ +#define __WinMemberExplSpec__ + +/********************************************************/ +/* Win member template explicit specialization */ +/* support aspect */ +/********************************************************/ + + +namespace Puma { + class CCSyntax; + class CTree; +} + +namespace Puma { + slice class WinMemberExplSpecSyntax; +} + +aspect WinMemberExplSpec { + /********************************************************/ + /* Win member template explicit specialization */ + /********************************************************/ + + // pointcut definitions + pointcut syntax () = classes ("Puma::CCSyntax"); + + // introduce new rule to class CCSyntax + advice syntax () : slice class Puma::WinMemberExplSpecSyntax; + + // try first to parse a member template explicit specialization + advice execution ("% Puma::CCSyntax::rule_member_template_decl()") : around () { + if (tjp->that ()->member_explicit_specialization ()) { + *tjp->result () = tjp->that ()->builder ().get_node (); + } else + tjp->proceed (); + } + +protected: + WinMemberExplSpec () {} +}; + +namespace Puma { + slice class WinMemberExplSpecSyntax { + CTree * rule_member_explicit_specialization (); + virtual bool member_explicit_specialization (); + }; +} + +slice Puma::CTree * Puma::WinMemberExplSpecSyntax::rule_member_explicit_specialization () { + // 4: TEMPLATE < > member_decl + if (! (parse (Puma::TOK_TEMPLATE) && parse (Puma::TOK_LESS) && parse (Puma::TOK_GREATER))) + return (CTree*)0; + semantic ().enter_template_param_list (0); + return member_decl () ? + semantic ().explicit_specialization () : (Puma::CTree*)0; +} + +slice bool Puma::WinMemberExplSpecSyntax::member_explicit_specialization () { + return parse (&WinMemberExplSpecSyntax::rule_member_explicit_specialization); +} + +#endif /* __WinMemberExplSpec__ */ diff --git a/Puma/src/aspects/WinTypeKeywords.ah b/Puma/src/aspects/WinTypeKeywords.ah new file mode 100644 index 0000000..989ef2c --- /dev/null +++ b/Puma/src/aspects/WinTypeKeywords.ah @@ -0,0 +1,42 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __WinTypeKeywords__ +#define __WinTypeKeywords__ + +/********************************************************/ +/* Win builtin types support aspect */ +/********************************************************/ + +#include "Puma/CTokens.h" + + +aspect WinTypeKeywords { + pointcut syntax () = classes ("Puma::CSyntax"); + + advice within (derived (syntax ())) && + execution ("% Puma::%::init_prim_types()") : after () { + tjp->that ()->_prim_types.set (Puma::TOK_INT64); + } + +protected: + WinTypeKeywords () {} +}; + + +#endif /* __WinTypeKeywords__ */ diff --git a/Puma/src/basics/Array.h b/Puma/src/basics/Array.h new file mode 100644 index 0000000..43212fd --- /dev/null +++ b/Puma/src/basics/Array.h @@ -0,0 +1,356 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_Array_H +#define PUMA_Array_H + +/** \file + * Variable length array implementation. */ + +#include + +namespace Puma { + +/** \class Array Array.h Puma/Array.h + * Variable length array implementation. Grows with an increasing increment. + * \tparam Item The array item type. + * \ingroup basics */ +template +class Array { + Item* data; + long size; + long count; + long increment; + + void grow(long wanted); + +protected: + /** Default array size. */ + static const long default_init_size = 5; + /** Default array size increment. */ + static const long default_increment = 5; + +public: + /** Constructor. + * \param is The default size of the array. + * \param incr The default increment value. */ + Array(long is = default_init_size, long incr = default_increment); + /** Copy-constructor. + * \param array The array to copy. */ + Array(const Array& array); + /** Assignment operator. + * \param copy The array to copy. */ + Array& operator=(const Array& copy); + /** Destructor. Destroys the array. */ + ~Array(); + /** Append an item to the array. + * \param item The item to append. */ + void append(const Item& item); + /** Insert an item at the given array index. + * \param index The array index. + * \param item The item to insert. */ + void insert(long index, const Item& item); + /** Prepend an item. + * \param item The item to prepend. */ + void prepend(const Item& item); + /** Remove the array item at the given array index. + * \param index The array index. */ + void remove(long index); + /** Reset the array. Destroys the current array. */ + void reset(); + /** Get a reference to the array item at the given + * array index. If the index exceeds the array + * bounds, then the array is reallocated accordingly. + * \param index The array index. + * \return A reference to the n-th array item. */ + Item& get(long index); + /** Get a reference to the array item at the given + * array index. If the index exceeds the array + * bounds, then the array is reallocated accordingly. + * \param index The array index. + * \return A reference to the n-th array item. */ + Item& operator[](long index); + /** Get the array item at the given array index. + * Does not return a reference, thus the item may + * be implicitely copied. + * \warning Does not validate the index! + * \param index The array index. + * \return The n-th array item. */ + Item fetch(long index) const; + /** Get a reference to the array item at the given + * array index. + * \warning Does not validate the index! + * \param index The array index. + * \return A reference to the n-th array item. */ + Item& lookup(long index) const; + /** Get the number of items in the array. + * \return The length of the array. */ + long length() const; +}; + +template +inline Array::Array(long is, long incr) { + count = 0; + size = is; + increment = incr; + data = 0; +} + +template +inline Array::Array(const Array& array) { + count = 0; + size = array.size; + increment = array.increment; + + if (size && array.data) { + data = new Item[size]; + for (; count < array.count; count++) { + data[count] = array.data[count]; + } + } else + data = 0; +} + +template +inline Array& Array::operator=(const Array& array) { + if (data) + delete[] data; + + count = 0; + size = array.size; + increment = array.increment; + + if (size && array.data) { + data = new Item[size]; + for (; count < array.count; count++) { + data[count] = array.data[count]; + } + } else + data = 0; + + return *this; +} + +template +inline Array::~Array() { + if (data) + delete[] data; +} + +template +inline void Array::grow(long wanted) { + do { + size += increment; + increment *= 2; + } while (wanted >= size); + + if (data) { + Item* new_data = new Item[size]; + for (long i = 0; i < count; i++) { + new_data[i] = data[i]; + } + delete[] data; + data = new_data; + } else + data = new Item[size]; +} + +template +inline void Array::append(const Item& item) { + if (count >= size || !data) { + grow(count); + } + data[count++] = item; +} + +template +inline void Array::prepend(const Item& item) { + insert(0, item); +} + +template +inline void Array::insert(long index, const Item& item) { + if (count >= size || !data) { + grow(count); + } + for (long i = count; i > index; i--) + data[i] = data[i - 1]; + data[index] = item; + count++; +} + +template +inline Item& Array::get(long index) { + if (index >= size || !data) { + grow(index); + } + if (index >= count) + count = index + 1; + return data[index]; +} + +template +inline Item& Array::operator[](long index) { + return get(index); +} + +template +inline Item Array::fetch(long index) const { + assert(index < count && data); + return data[index]; +} + +template +inline long Array::length() const { + return count; +} + +template +inline void Array::remove(long index) { + if (index < count && count > 0) { + for (long i = index; i < count - 1; i++) + data[i] = data[i + 1]; + count--; + } +} + +template<> +inline void Array::reset() { + count = 0; +} + +template +inline void Array::reset() { + if (data) + delete[] data; + + count = 0; + size = default_init_size; + increment = default_increment; + data = new Item[size]; +} + +template +inline Item& Array::lookup(long index) const { + assert(index >= 0 && index < count); + return data[index]; +} + +} // namespace Puma + +// Array specialization for pointer types sharing method definitions + +#include "Puma/VoidPtrArray.h" + +namespace Puma { + +/** Variable length array implementation specialized for pointer types. + * Grows with an increasing increment. + * \tparam Item The array item type. Needs to be a pointer type. + * \ingroup basics */ +template +class Array : private VoidPtrArray { + typedef VoidPtrArray Base; + +public: + /** Constructor. + * \param is The default size of the array. + * \param incr The default increment value. */ + Array(long is = default_init_size, long incr = default_increment) + : Base(is, incr) { + } + /** Copy-constructor. + * \param array The array to copy. */ + Array(const Array &array) + : Base(array) { + } + /** Destructor. Destroys the array. */ + ~Array() { + } + /** Assignment operator. + * \param array The array to copy. + * \return A reference to this array. */ + Array &operator=(const Array &array) { + return (Array&) Base::operator=(array); + } + /** Append an item to the array. + * \param item The item to append. */ + void append(const Item *item) { + Base::append((void*) item); + } + /** Insert an item at the given array index. + * \param idx The array index. + * \param item The item to insert. */ + void insert(long idx, const Item *item) { + Base::insert(idx, (void*) item); + } + /** Prepend an item. + * \param item The item to prepend. */ + void prepend(const Item *item) { + Base::prepend((void*) item); + } + /** Remove the array item at the given array index. + * \param idx The array index. */ + void remove(long idx) { + Base::remove(idx); + } + /** Reset the array. Destroys the current array. */ + void reset() { + Base::reset(); + } + /** Get a reference to the array item at the given + * array index. If the index exceeds the array + * bounds, then the array is reallocated accordingly. + * \param idx The array index. + * \return A reference to the n-th array item. */ + Item *&get(long idx) { + return (Item*&) Base::get(idx); + } + /** Get a reference to the array item at the given + * array index. If the index exceeds the array + * bounds, then the array is reallocated accordingly. + * \param idx The array index. + * \return A reference to the n-th array item. */ + Item *&operator[](long idx) { + return (Item*&) Base::operator[](idx); + } + /** Get the array item at the given array index. + * \warning Does not validate the index! + * \param idx The array index. + * \return The n-th array item. */ + Item *fetch(long idx) const { + return (Item*) Base::fetch(idx); + } + /** Get a reference to the array item at the given + * array index. + * \warning Does not validate the index! + * \param idx The array index. + * \return A reference to the n-th item. */ + Item *&lookup(long idx) const { + return (Item*&) Base::lookup(idx); + } + /** Get the number of items in the array. + * \return Length of the array. */ + long length() const { + return Base::length(); + } +}; + +} // namespace Puma + +#endif /* PUMA_Array_H */ diff --git a/Puma/src/basics/BCList.h b/Puma/src/basics/BCList.h new file mode 100644 index 0000000..25ff7db --- /dev/null +++ b/Puma/src/basics/BCList.h @@ -0,0 +1,249 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_BCList_H +#define PUMA_BCList_H + +/** \file + * Bucket list implementation. */ + +namespace Puma { + +/** \class BCList BCList.h Puma/BCList.h + * %List of fixed-size buckets. + * A bucket is a fixed-size array that is filled sequentially. Each bucket + * is linked with the previous and next buckets forming a double linked list. + * Random access to list items is not supported. + * + * \tparam Item The list item type. + * \tparam BUCKET_SIZE Optional size of each bucket. Defaults to 32. + * \ingroup basics */ +template +class BCList { + struct Bucket { + Bucket *m_prev; + Bucket *m_next; + Item *m_write_pos; + Item *m_end_pos; + Item m_data[BUCKET_SIZE]; // large amount of token pointers to avoid new + + Bucket() + : m_prev(0), m_next(0), m_write_pos(m_data), m_end_pos(m_data + BUCKET_SIZE) { + } + ~Bucket() { + if (m_next) + delete m_next; + } + void clear() { + if (m_next) + delete m_next; + m_next = 0; + m_write_pos = m_data; + } + Item *first() { + return m_data; + } + Item *pos() const { + return m_write_pos; + } + Item *end() const { + return m_end_pos; + } + bool full() const { + return m_write_pos == m_end_pos; + } + Bucket *new_bucket() { + m_next = new Bucket; + m_next->m_prev = this; + return m_next; + } + void add(Item token) { + *m_write_pos = token; + m_write_pos++; + } + }; + + Bucket *m_first_bucket; // the first bucket is part of the container + Bucket *m_last_bucket; // pointer to the last bucket for insertion + + void check() { + if (m_first_bucket == 0) { + m_first_bucket = new Bucket(); + m_last_bucket = m_first_bucket; + } + } + +public: + /** \class Iterator BCList.h Puma/BCList.h + * Bucket list sequential iterator. */ + class Iterator { + friend class BCList ; + + Item *m_item; + Bucket *m_bucket; + + Iterator(Item *item, Bucket *bucket) + : m_item(item), m_bucket(bucket) { + } + + public: + /** Construct an empty iterator. Do not use this iterator for + * other purposes than comparison. */ + Iterator() + : m_item(0), m_bucket(0) { + } + /** Check whether this iterator is in a valid state. If the + * iterator is not valid, it must not be used for other purposes + * than comparison. + * \return True if the iterator is valid. */ + operator bool() const { + return m_item != 0; + } + /** Compare two iterators. + * \param other The iterator to compare to. + * \return True if both iterators point to same list item. */ + bool operator==(const Iterator& other) const { + return m_item == other.m_item; + } + /** Compare two iterators. + * \param other The iterator to compare to. + * \return True if both iterators point to different list items. */ + bool operator!=(const Iterator &other) const { + return !(*this == other); + } + /** Unary increment operator. Lets point the iterator to the next + * item in the list. + * \return A reference to this iterator pointing to the next item. */ + Iterator &operator++() { + if (m_item != 0) { + m_item++; + if (m_item == m_bucket->pos()) { + m_bucket = m_bucket->m_next; + m_item = m_bucket ? m_bucket->first() : 0; + } + } + return *this; + } + /** Binary increment operator. Lets point the iterator to the next + * item in the list. + * \return An new iterator pointing to the same item before the iterator was incremented. */ + Iterator operator++(int) { + Iterator temp(*this); + ++(*this); + return temp; + } + /** Unary decrement operator. Lets point the iterator to the previous + * item in the list. + * \return A reference to this iterator pointing to the previous item. */ + Iterator &operator--() { + if (m_item == m_bucket->first()) { + m_bucket = m_bucket->m_prev; + if (m_bucket) { + m_item = m_bucket->pos(); + m_item--; + } else { + m_item = 0; + } + } else if (m_item != 0) { + m_item--; + } + return *this; + } + /** Binary decrement operator. Lets point the iterator to the previous + * item in the list. + * \return An new iterator pointing to the same item before the iterator was decremented. */ + Iterator operator--(int) { + Iterator temp(*this); + --(*this); + return temp; + } + /** Get the list item the iterator currently points to. + * Ensure the iterator is valid before calling this method. + * \return A reference to the current list item. */ + Item &operator*() const { + return *m_item; + } + /** Get a pointer to the list item the iterator currently points to. + * Ensure the iterator is valid before calling this method. + * \return A pointer to the current list item. */ + Item *operator->() const { + return m_item; + } + }; + + /** Construct an empty bucket list. */ + BCList() + : m_first_bucket(0), m_last_bucket(0) { + } + + /** Destroy the bucket list. Will not deleted the list items. */ + ~BCList() { + if (m_first_bucket != 0) + delete m_first_bucket; + } + + /** Get an iterator pointing to the beginning of the list. + * \return A new iterator pointing to the first list item. */ + Iterator begin() { + check(); + return Iterator(m_first_bucket->first(), m_first_bucket); + } + + /** Get an iterator pointing to the end of the list. This iterator + * does not point to the last list item. It is an empty iterator + * that is intended to be used for comparisons like this: + * + * \code + * BCList::Iterator idx = list.begin(); + * for (; idx != list.end(); ++idx) { + * // do something + * } + * \endcode + * \return A new empty iterator. */ + Iterator end() const { + return Iterator(); + } + + /** Add an item to the list. + * \param item Them item to add. + * \return An iterator pointing to the new list item. */ + Iterator add(Item item) { + check(); + // if the last bucket is full extend the bucket chain + if (m_last_bucket->full()) + m_last_bucket = m_last_bucket->new_bucket(); + // the result is the position of the inserted item + Item *result = m_last_bucket->pos(); + // add the item; the bucket is not full! + m_last_bucket->add(item); + // return an iterator for the new item + return Iterator(result, m_last_bucket); + } + + /** Reset the list. Will not delete the list items. */ + void reset() { + if (m_first_bucket != 0) { + m_first_bucket->clear(); + m_last_bucket = m_first_bucket; + } + } +}; + +} // namespace Puma + +#endif /* PUMA_BCList_H */ diff --git a/Puma/src/basics/BCStack.h b/Puma/src/basics/BCStack.h new file mode 100644 index 0000000..92863ca --- /dev/null +++ b/Puma/src/basics/BCStack.h @@ -0,0 +1,98 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_BCStack_H +#define PUMA_BCStack_H + +/** \file + * Bucket stack implementation. */ + +#include "Puma/BCList.h" + +namespace Puma { + +/** \class BCStack BCStack.h Puma/BCStack.h + * %Stack of fixed-size buckets. + * A bucket is a fixed-size array that is filled sequentially. Each bucket + * is linked with the previous and next buckets forming a double linked list. + * Items are accessed last-in first-out. No random access supported. + * + * \tparam Item The stack item type. + * \tparam BUCKET_SIZE Optional size of each bucket. Defaults to 32. + * \ingroup basics */ +template +class BCStack : private BCList { + typedef BCList List; + +public: + /** Iterator type for the bucket stack. */ + typedef typename List::Iterator Iterator; + +private: + Iterator m_tos; + long m_length; + +public: + /** Construct an empty bucket stack. */ + BCStack() + : m_length(0L) { + } + /** Get the length of the bucket stack. + * \return The current length. */ + long length() const { + return m_length; + } + /** Push a new item on top of the stack. + * \param item The item to add. */ + void push(Item item) { + if (m_tos) + ++m_tos; + if (!m_tos) + m_tos = this->add(item); + else + *m_tos = item; + m_length++; + } + /** Get the top item of the stack. + * \return A reference to the top item. */ + Item &top() const { + return *m_tos; + } + /** Remove the top item from the stack. */ + void pop() { + if (!empty()) { + --m_tos; + m_length--; + } + } + /** Reset the bucket stack. Does not delete the stack items. */ + void reset() { + List::reset(); + m_tos = typename List::Iterator(); + m_length = 0L; + } + /** Check if the stack is empty. + * \return True if the stack is empty. */ + bool empty() const { + return m_length == 0L; + } +}; + +} // namespace Puma + +#endif /* PUMA_BCStack_H */ diff --git a/Puma/src/basics/Chain.h b/Puma/src/basics/Chain.h new file mode 100644 index 0000000..70c6bc2 --- /dev/null +++ b/Puma/src/basics/Chain.h @@ -0,0 +1,69 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_Chain_H +#define PUMA_Chain_H + +/** \file + * Simple chain implementation. + */ + +namespace Puma { + +/** \class Chain Chain.h Puma/Chain.h + * Simple single-linked chain implementation. + * A chain consists of elements each linked to its direct follower element. + * \ingroup basics */ +class Chain { + Chain *next; + +public: + /** Construct a single chain element. */ + Chain() { + next = 0; + } + /** Select an element as the next element. + * \param element The next element. */ + void select(Chain *element) { + next = element; + } + /** Get the next element. + * \return A pointer to the next chain element. */ + Chain *select() const { + return next; + } + /** Unlink the next element from the chain. + * \return The unlinked next element. */ + Chain *unlink() { + Chain *res = next; + if (next) { + next = next->select(); + } + return res; + } + /** Insert an element in the chain as the next element. + * \param element The element to insert. */ + void insert(Chain *element) { + element->select(next); + next = element; + } +}; + +} // namespace Puma + +#endif /* PUMA_Chain_H */ diff --git a/Puma/src/basics/ConstSizeMemPool.h b/Puma/src/basics/ConstSizeMemPool.h new file mode 100644 index 0000000..2ce9efd --- /dev/null +++ b/Puma/src/basics/ConstSizeMemPool.h @@ -0,0 +1,146 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_ConstSizeMemPool_H +#define PUMA_ConstSizeMemPool_H + +/** \file + * Constant size memory block pool implementation. */ + +#include "Puma/Chain.h" +#include +#include + +#ifdef PROFILE_MEM +# include +#endif + +namespace Puma { + +/** \class ConstSizeMemPool ConstSizeMemPool.h Puma/ConstSizeMemPool.h + * Constant size memory block pool. Memory blocks are not freed + * before the pool is destroyed. Free blocks are inserted into + * a free list for reuse. + * + * Following global functions are defined that use a constant size + * memory pool: + * - Puma::malloc + * - Puma::free + * - Puma::clean + * + * \tparam N Number of bytes for each memory block to allocate. + * \ingroup basics */ +template +class ConstSizeMemPool { + Chain m_FreeList; + +#ifdef PROFILE_MEM + long long m_use, m_reuse; +#endif + +public: + /** Construct an empty memory pool. */ + ConstSizeMemPool() { +#ifdef PROFILE_MEM + m_use = 0; + m_reuse = 0; +#endif + } + /** Destroy the memory pool. Frees all memory blocks allocated. */ + ~ConstSizeMemPool() { +#ifdef PROFILE_MEM + std::cout << m_reuse << "(" << (100 * m_reuse / (m_use > 1 ? m_use : 1)) << "%)"; + std::cout << " of total " << m_use << " for size " << N <<" reused" << std::endl; +#endif + clean(); + } + /** Get the memory pool for this block size. + * There is only one memory pool for each block size. + * \return A reference to the memory pool. */ + static ConstSizeMemPool &inst() { + static ConstSizeMemPool instance; + return instance; + } + /** Get a block of memory. If no free block is available, + * a new block of memory is allocated. + * \return Pointer to the block of memory. */ + void *alloc(); + /** Insert a block of memory into the free list for reuse. + * The memory block is freed when the pool is destroyed. + * \param block Pointer to the memory block. */ + void free(void *block); + /** Free all allocated memory blocks. */ + void clean(); +}; + +template +inline void ConstSizeMemPool::clean() { + Chain *c = m_FreeList.unlink(); + while (c) { + ::free(c); + c = m_FreeList.unlink(); + } +} + +template +inline void *ConstSizeMemPool::alloc() { +#ifdef PROFILE_MEM + m_use++; +#endif + void *res = m_FreeList.unlink(); + if (res == 0) { + res = ::malloc(N); + } +#ifdef PROFILE_MEM + else m_reuse++; +#endif + return res; +} + +template +inline void ConstSizeMemPool::free(void *p) { + m_FreeList.insert((Chain*) p); +} + +/** Constant size memory block pool variant of malloc(). + * \tparam N The block size. + * \return A pointer to the memory block. */ +template +inline void *malloc() { + return ConstSizeMemPool::inst().alloc(); +} + +/** Constant size memory block pool variant of free(). + * \tparam N The block size. + * \param block Pointer to the memory block to free. */ +template +inline void free(void *block) { + ConstSizeMemPool::inst().free(block); +} + +/** Short-cut function for calling method clean() on the corresponding + * fixed size memory block pool instance. + * \tparam N The block size. */ +template +inline void clean() { + ConstSizeMemPool::inst().clean(); +} + +} // namespace Puma + +#endif /* PUMA_ConstSizeMemPool_H */ diff --git a/Puma/src/basics/DString.cc b/Puma/src/basics/DString.cc new file mode 100644 index 0000000..55d086e --- /dev/null +++ b/Puma/src/basics/DString.cc @@ -0,0 +1,26 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/DString.h" + +namespace Puma { + +/** Global dictionary for all strings. */ +StrHashTable DString::global_dictionary; + +} // namespace Puma diff --git a/Puma/src/basics/DString.h b/Puma/src/basics/DString.h new file mode 100644 index 0000000..02d674d --- /dev/null +++ b/Puma/src/basics/DString.h @@ -0,0 +1,127 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_DString_H +#define PUMA_DString_H + +/** \file + * Global hash table based string container. */ + +#include "StrHashTable.h" +#include + +namespace Puma { + +/** \class DString DString.h Puma/DString.h + * Global dictionary based string container. + * \ingroup basics */ +class DString { + static StrHashTable global_dictionary; + StrHashKey *m_Key; + +public: + /** Construct an empty string container. Refers to the empty string. */ + DString() { + m_Key = global_dictionary.empty(); + assert(m_Key); + } + /** Construct a new string container for the given string. + * If the string is not null, then it is inserted into the dictionary. + * \param str The string. */ + DString(const char *str) { + *this = str; + } + /** Copy a string container. + * \param copy The string container to copy. */ + DString(const DString ©) + : m_Key(copy.m_Key) { + assert(copy.m_Key); + } + /** Destroy the container. Does not delete the string. */ + ~DString() { + m_Key = 0; + } + /** Copy a string container. + * \param copy The string container to copy. */ + DString &operator=(const DString ©) { + assert(copy.m_Key); + m_Key = copy.m_Key; + return *this; + } + /** Assign a string to this string container. + * \param str The string. */ + DString &operator=(const char *str) { + if (str == 0) { + m_Key = global_dictionary.empty(); + } else { + m_Key = global_dictionary.insert(str); + } + assert(m_Key); + return *this; + } + /** Check if the given string equals this string. + * \param str The string to compare with. */ + bool operator==(const DString &str) const { + assert(m_Key && str.m_Key); + return m_Key == str.m_Key; + } + /** Check if the given string not equals this string. + * \param str The string to compare with. */ + bool operator!=(const DString &str) const { + assert(m_Key && str.m_Key); + return m_Key != str.m_Key; + } + /** Get the contained string. + * \return A pointer to the contained string. */ + const char *c_str() const { + assert(m_Key); + return m_Key->c_str(); + } + /** Get the length of the string. + * \return The length of the contained string. */ + unsigned int length() const { + assert(m_Key); + return m_Key->length(); + } + /** Check if the string is empty. The string is empty if its length is zero. + * \return True if the string is empty. */ + bool empty() const { + assert(m_Key); + return m_Key->length() == 0; + } + /** Get the magic number (hash) of the string. + * \return The magic number. */ + unsigned int magic() const { + assert(m_Key); + return m_Key->getMagic(); + } + /** Conversion operator returning the contained string. + * \return A pointer to the contained string. */ + operator const char *() const { + assert(m_Key); + return c_str(); + } + /** Clear the global dictionary. */ + static void clearDict() { + global_dictionary.clear(); + } +}; + +} // namespace Puma + +#endif /* PUMA_DString_H */ diff --git a/Puma/src/basics/FdSource.h b/Puma/src/basics/FdSource.h new file mode 100644 index 0000000..d8f453c --- /dev/null +++ b/Puma/src/basics/FdSource.h @@ -0,0 +1,76 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_FdSource_H +#define PUMA_FdSource_H + +/** \file + * File descriptor input source implementation. */ + +#include "Puma/Source.h" +#include "Puma/SysCall.h" + +namespace Puma { + +/** \class FdSource FdSource.h Puma/FdSource.h + * File descriptor wrapper implementing the Source interface. + * \ingroup basics */ +class FdSource : public Source { + int m_fd; + +public: + /** Construct a new file descriptor wrapper with invalid file descriptor. */ + FdSource() + : m_fd(-1) { + } + /** Construct a new wrapper for the given file descriptor. + * \param fdesc The file descriptor. */ + FdSource(int fdesc) + : m_fd(fdesc) { + } + /** Destroy the wrapper. Does not close the file descriptor. */ + virtual ~FdSource() { + } + /** Read n bytes from the file into the given string. + * \param dest The string used as buffer for the bytes read. + * \param n The number of bytes to read. + * \return The number of bytes read, or -1 in case of errors. */ + virtual int read(char *dest, int n) { + return SysCall::read(m_fd, dest, n); + } + /** Set the wrapped file descriptor. + * \param fdesc The file descriptor. */ + void fd(int fdesc) { + m_fd = fdesc; + } + /** Get the wrapped file descriptor. + * \return The file descriptor, or -1 if no file descriptor set. */ + int fd() { + return m_fd; + } + /** Get the size of the file. + * \return The size of the file, or -1 if size could not be determined. */ + int size() { + FileInfo fileinfo; + return (SysCall::fstat(m_fd, fileinfo)) ? fileinfo.size() : -1; + } +}; + +} // namespace Puma + +#endif /* PUMA_FdSource_H */ diff --git a/Puma/src/basics/FileSource.h b/Puma/src/basics/FileSource.h new file mode 100644 index 0000000..4105e89 --- /dev/null +++ b/Puma/src/basics/FileSource.h @@ -0,0 +1,59 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_FileSource_H +#define PUMA_FileSource_H + +/** \file + * File source wrapper. */ + +#include "Puma/ErrorSink.h" +#include "Puma/FdSource.h" +#include "Puma/SysCall.h" +#include + +namespace Puma { + +/** \class FileSource FileSource.h Puma/FileSource.h + * File wrapper implementing the Source interface. + * \ingroup basics */ +class FileSource : public FdSource { +public: + /** Construct a new file wrapper. + * Opens the given file in read-only mode. + * \param path The path to the file. + * \param err Optional error stream. */ + FileSource(const char *path, ErrorSink *err = (ErrorSink*) 0) { + fd(SysCall::open(path, O_RDONLY, err)); + } + /** Destroy the file wrapper. Closes the file opened in the constructor. */ + ~FileSource() { + SysCall::close(fd()); + } + /** Read n bytes from the file into the given string. + * \param dest The string used as buffer for the bytes read. + * \param n The number of bytes to read. + * \return The number of bytes read, or -1 in case of errors. */ + virtual int read(char *dest, int n) { + return FdSource::read(dest, n); + } +}; + +} // namespace Puma + +#endif /* PUMA_FileSource_H */ diff --git a/Puma/src/basics/GPLHeader.cc b/Puma/src/basics/GPLHeader.cc new file mode 100644 index 0000000..1853e99 --- /dev/null +++ b/Puma/src/basics/GPLHeader.cc @@ -0,0 +1,27 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 "Puma/version.h" + +namespace Puma { + +/** Header information for all files written by the PUMA library. */ +const char *GPL_HEADER = ""; // no header wanted in this version +//"/* This file was generated by the PUMA library, version "PUMA_VERSION". */\n\n"; + +} // namespace Puma diff --git a/Puma/src/basics/Heap.cc b/Puma/src/basics/Heap.cc new file mode 100644 index 0000000..5014f54 --- /dev/null +++ b/Puma/src/basics/Heap.cc @@ -0,0 +1,161 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 + +#if defined(WIN32) && !defined(_MSC_VER) + +#include "Puma/Heap.h" +#include "Puma/Chain.h" +#include +#include +#include + +namespace Puma { + + +class HeapPool : public Heap { + Chain m_Trash; + int m_Cnt; + +public: + HeapPool (int) : m_Cnt (0xff) {} + + void *alloc (size_t s) { + return Heap::malloc (s); + } + void dealloc (void *p) { + if (lowmem ()) + clean (); + m_Trash.insert ((Chain*)p); + } + void clean () { + long long num=0; + Chain *p; + while ((p = m_Trash.unlink ()) != 0) { + Heap::free (p); + num++; + } + } + bool lowmem () { + if (m_Trash.select () != 0 && --m_Cnt == 0 ) { + m_Cnt = 0xff; + MEMORYSTATUS stat; + GlobalMemoryStatus (&stat); + return stat.dwAvailPhys < (stat.dwTotalPhys / 50); + } + return false; + } +}; + + +#if PROFILE_MEM + +class __ProfileAlloc : public Heap { + long long Cnt[100]; + long long total; + long long totalMB; + +public: + __ProfileAlloc () { + total = totalMB = 0; + for (int x = 0; x < 100; x++) { + Cnt[x] = 0; + } + } + ~__ProfileAlloc () { + //for (int x = 8; x < 81; x += 4) { + // std::cout << x << ": " << Cnt[x] << std::endl; + //} + //std::cout << "Total new: " << total << std::endl; + //std::cout << "Total MB : " << totalMB / 1024 / 1024 << std::endl; + } + void *malloc (size_t s) { + if (s < 100) + Cnt[s]++; + total++; + totalMB += s; + return Heap::malloc (s); + } + void free (void *p) { + Heap::free (p); + } +}; + +static __ProfileAlloc __pool; + +#else /* PROFILE_MEM */ + +static Heap __pool; + +#endif /* PROFILE_MEM */ + + +} // namespace Puma + + +// replace the global new and delete operators + +void *operator new(std::size_t s) throw (std::bad_alloc) { + void *res = Puma::__pool.malloc(s); + if (res == 0) { + std::cerr << "FATAL: Out of memory! Aborting..." << std::endl; + exit(0); + } + return res; +} +void *operator new(std::size_t s, const std::nothrow_t &) throw () { + void *res = Puma::__pool.malloc(s); + if (res == 0) { + std::cerr << "FATAL: Out of memory! Aborting..." << std::endl; + exit(0); + } + return res; +} +void *operator new[](std::size_t s) throw (std::bad_alloc) { + void *res = Puma::__pool.malloc(s); + if (res == 0) { + std::cerr << "FATAL: Out of memory! Aborting..." << std::endl; + exit(0); + } + return res; +} +void *operator new[](std::size_t s, const std::nothrow_t &) throw () { + void *res = Puma::__pool.malloc(s); + if (res == 0) { + std::cerr << "FATAL: Out of memory! Aborting..." << std::endl; + exit(0); + } + return res; +} +void operator delete(void *p) throw () { + assert(p); + Puma::__pool.free(p); +} +void operator delete(void *p, const std::nothrow_t &) throw () { + assert(p); + Puma::__pool.free(p); +} +void operator delete[](void *p) throw () { + assert(p); + Puma::__pool.free(p); +} +void operator delete[](void *p, const std::nothrow_t &) throw () { + assert(p); + Puma::__pool.free(p); +} + +#endif /* defined(WIN32) && !defined(_MSC_VER) */ diff --git a/Puma/src/basics/Heap.h b/Puma/src/basics/Heap.h new file mode 100644 index 0000000..3f15bfe --- /dev/null +++ b/Puma/src/basics/Heap.h @@ -0,0 +1,95 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_Heap_H +#define PUMA_Heap_H + +/** \file + * Heap implementation. */ + +#include + +// use pt_malloc only for the cross-compiled mingw version! +#if defined(WIN32) && !defined(_MSC_VER) + +extern "C" void *pt_malloc(size_t); +extern "C" void pt_free(void *); + +namespace Puma { + +/** \class Heap Heap.h Puma/Heap.h + * Heap implementation using pt_malloc and pt_free. + * \warning This class is not used and may disappear without notice. + * \ingroup basics */ +class Heap { +public: + /** Constructor. */ + Heap() { + } + /** Destructor. */ + ~Heap() { + } + /** Allocate n bytes of memory. + * \param n The number of bytes to allocate. + * \return A pointer to memory allocated. */ + void *malloc(size_t s) { + return pt_malloc(s); + } + /** Free the given memory. + * \param p A pointer to the memory to free. */ + void free(void *p) { + pt_free(p); + } +}; + +} // namespace Puma + +#else /* defined(WIN32) && !defined(_MSC_VER) */ + +namespace Puma { + +/** \class Heap Heap.h Puma/Heap.h + * Heap implementation using standard malloc and free. + * \warning This class is not used and may disappear without notice. + * \ingroup basics */ +class Heap { +public: + /** Constructor. */ + Heap() { + } + /** Destructor. */ + ~Heap() { + } + /** Allocate n bytes of memory. + * \param n The number of bytes to allocate. + * \return A pointer to memory allocated. */ + void *malloc(size_t n) { + return ::malloc(n); + } + /** Free the given memory. + * \param p A pointer to the memory to free. */ + void free(void *p) { + ::free(p); + } +}; + +} // namespace Puma + +#endif /* defined(WIN32) && !defined(_MSC_VER) */ + +#endif /* PUMA_Heap_H */ diff --git a/Puma/src/basics/KeyboardSource.cc b/Puma/src/basics/KeyboardSource.cc new file mode 100644 index 0000000..bcd216c --- /dev/null +++ b/Puma/src/basics/KeyboardSource.cc @@ -0,0 +1,39 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 "Puma/KeyboardSource.h" +#include + +namespace Puma { + +int KeyboardSource::read(char *dest, int n) { + if (std::cin.eof() || std::cin.fail()) + return 0; + + std::cin.get(dest[0]); + + if (std::cin.eof()) + return 0; + + if (std::cin.bad()) + return -1; + + return 1; +} + +} // namespace Puma diff --git a/Puma/src/basics/KeyboardSource.h b/Puma/src/basics/KeyboardSource.h new file mode 100644 index 0000000..5fda3ab --- /dev/null +++ b/Puma/src/basics/KeyboardSource.h @@ -0,0 +1,43 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_KeyboardSource_H +#define PUMA_KeyboardSource_H + +/** \file + * Keyboard input source implementation. */ + +#include "Puma/Source.h" + +namespace Puma { + +/** \class KeyboardSource KeyboardSource.h Puma/KeyboardSource.h + * Keyboard input wrapper implementing the Source interface. + * \ingroup basics */ +class KeyboardSource : public Source { +public: + /** Read one byte from the keyboard into the given string. + * \param dest The string used as buffer for the bytes read. + * \param n The number of bytes to read. + * \return The number of bytes read, or -1 in case of errors. */ + virtual int read(char *dest, int n); +}; + +} // namespace Puma + +#endif /* PUMA_KeyboardSource_H */ diff --git a/Puma/src/basics/Limits.h b/Puma/src/basics/Limits.h new file mode 100644 index 0000000..9f09a4e --- /dev/null +++ b/Puma/src/basics/Limits.h @@ -0,0 +1,120 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_Limits_H +#define PUMA_Limits_H + +/** \file + * Type size limits. + * \ingroup basics */ + +#include + +namespace Puma { + +// type `long long' support + +#if defined(__GNUC__) || defined(_MSC_VER) +#if defined(__SIZEOF_INT128__) +/** Type `long long`. */ +typedef __int128 LONG_LONG; +/** Type `unsigned long long`. */ +typedef unsigned __int128 U_LONG_LONG; +#else /* __SIZEOF_INT128__ */ +/** Type `long long`. */ +typedef long long LONG_LONG; +/** Type `unsigned long long`. */ +typedef unsigned long long U_LONG_LONG; +#endif /* __SIZEOF_INT128__ */ +#else /* __GNUC__ */ +/** Type `long long`. */ +typedef long LONG_LONG; +/** Type `unsigned long long`. */ +typedef unsigned long U_LONG_LONG; +#endif /* __GNUC__ */ + +#ifndef LLONG_MAX +# if defined(__GNUC__) || defined(_MSC_VER) +# define LLONG_MAX 9223372036854775807LL +# define LLONG_MIN (-LLONG_MAX - 1LL) +# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL) +# else /* __GNUC__ */ +# define LLONG_MAX LONG_MAX +# define LLONG_MIN LONG_MIN +# define ULLONG_MAX ULONG_MAX +# endif /* __GNUC__ */ +#endif /* LLONG_MAX */ + +// type size (in bits) + +#define BOOL_SIZE 8 +#define CHAR_SIZE 8 +#define SCHAR_SIZE 8 +#define UCHAR_SIZE 8 +#define SHORT_SIZE 16 +#define USHORT_SIZE 16 +#define WCHAR_T_SIZE 32 +#define INT_SIZE 32 +#define UINT_SIZE 32 +#define LONG_SIZE 32 +#define ULONG_SIZE 32 +#define LLONG_SIZE 64 +#define ULLONG_SIZE 64 +#define INT128_SIZE 128 +#define UINT128_SIZE 128 + +#define FLOAT_SIZE 32 +#define DOUBLE_SIZE 64 +#define LDOUBLE_SIZE 96 + +#define PTR_SIZE 32 +#define MEMB_PTR_SIZE 64 + +#define ENUM_SIZE 32 + +} + // namespace Puma + +#if (defined(__GNUC__) || defined(_MSC_VER)) && defined(__SIZEOF_INT128__) + +#include + +namespace Puma { + +/** Output stream operator for type `long long` based on `__int128`. + * \param os The output stream. + * \param value The value to output. + * \return A reference to the output stream. */ +inline std::ostream &operator << (std::ostream &os, LONG_LONG value) { + os << (long long) value; + return os; +} +/** Output stream operator for type `unsigned long long` based on `__int128`. + * \param os The output stream. + * \param value The value to output. + * \return A reference to the output stream. */ +inline std::ostream &operator << (std::ostream &os, U_LONG_LONG value) { + os << (unsigned long long) value; + return os; +} + +} + +#endif /* __SIZEOF_INT128__ */ + +#endif /* PUMA_Limits_H */ diff --git a/Puma/src/basics/List.cc b/Puma/src/basics/List.cc new file mode 100644 index 0000000..248955b --- /dev/null +++ b/Puma/src/basics/List.cc @@ -0,0 +1,213 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 "Puma/List.h" +#include + +namespace Puma { + +List::List(const List &list) { + m_first = m_last = (ListElement*) 0; + *this = list; +} + +List::~List() { + clear(); +} + +List &List::operator =(const List &list) { + clear(); + return *this += list; +} + +List &List::operator +=(const List &list) { + ListElement *curr; + + curr = list.m_first; + while (curr) { + append(*curr->duplicate()); + curr = curr->m_next; + } + return *this; +} + +List List::operator +(const List &list) { + List result; + + result += *this; + result += list; + return result; +} + +void List::clear() { + ListElement *curr; + ListElement *next; + + curr = m_first; + while (curr) { + next = curr->m_next; + curr->m_prev = 0; + curr->m_next = 0; + assert(curr->m_belonging_to == this); + curr->m_belonging_to = 0; + delete curr; + curr = next; + } + m_first = m_last = (ListElement*) 0; +} + +List *List::copy(ListElement *from, ListElement *to) { + ListElement *curr = from ? from : m_first; + ListElement *the_end = to ? to->m_next : 0; + List *list = new List; + + while (curr && curr != the_end) { + list->append(*curr->duplicate()); + curr = curr->m_next; + } + return list; +} + +void List::cut(List &out, ListElement *from, ListElement *to) { + ListElement *next, *curr = from ? from : m_first; + ListElement *the_end = to ? to->m_next : from ? from->m_next : 0; + + while (curr && curr != the_end) { + next = curr->m_next; + remove(curr); + out.append(*curr); + curr = next; + } +} + +void List::paste(ListElement *at, const List &l) { + ListElement *curr = l.m_first; + ListElement *inspos = at ? at : m_last; + + while (curr) { + if (!inspos) { + append(*(curr->duplicate())); + } else { + insert(inspos, *(curr->duplicate())); + inspos = inspos->m_next; + } + curr = curr->m_next; + } +} + +void List::paste_before(ListElement *at, const List &l) { + if (at && at->m_prev) { + paste(at->m_prev, l); + } else { + ListElement *curr = l.m_last; + + while (curr) { + prepend(*(curr->duplicate())); + curr = curr->m_prev; + } + } +} + +void List::move(ListElement *at, List &l) { + ListElement *curr = l.m_first; + ListElement *inspos = at ? at : m_last; + + while (curr) { + l.remove(curr); + if (!inspos) { + append(*curr); + } else { + insert(inspos, *curr); + inspos = inspos->m_next; + } + curr = l.m_first; + } +} + +void List::move_before(ListElement *at, List &l) { + if (at && at->m_prev) { + move(at->m_prev, l); + } else { + ListElement *curr = l.m_last; + + while (curr) { + l.remove(curr); + prepend(*curr); + curr = l.m_last; + } + } +} + +void List::append(ListElement &element) { + assert(!element.m_belonging_to); + element.m_next = (ListElement*) 0; + element.m_prev = m_last; + element.m_belonging_to = this; + if (empty()) + m_first = &element; + else + m_last->m_next = &element; + m_last = &element; +} + +void List::prepend(ListElement &element) { + assert(!element.m_belonging_to); + element.m_prev = (ListElement*) 0; + element.m_next = m_first; + element.m_belonging_to = this; + if (empty()) + m_last = &element; + else + m_first->m_prev = &element; + m_first = &element; +} + +void List::insert(ListElement *at, ListElement &element) { + assert(!element.m_belonging_to); + element.m_prev = at; + element.m_next = at->m_next; + element.m_belonging_to = this; + if (at && at->m_next) + at->m_next->m_prev = &element; + else + m_last = &element; + if (at) + at->m_next = &element; +} + +void List::remove(ListElement *element) { + if (!element) + return; + + assert(element->m_belonging_to == this); + element->m_belonging_to = (List*) 0; + + if (!element->m_next) + m_last = element->m_prev; + else + element->m_next->m_prev = element->m_prev; + + if (!element->m_prev) + m_first = element->m_next; + else + element->m_prev->m_next = element->m_next; + + element->m_prev = element->m_next = (ListElement*) 0; +} + +} // namespace Puma diff --git a/Puma/src/basics/List.h b/Puma/src/basics/List.h new file mode 100644 index 0000000..3f8f99d --- /dev/null +++ b/Puma/src/basics/List.h @@ -0,0 +1,148 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_List_H +#define PUMA_List_H + +/** \file + * Double-linked list implementation. */ + +#include "Puma/ListElement.h" + +namespace Puma { + +/** \class List List.h Puma/List.h + * Double-linked list implementation. + * \ingroup basics */ +class List { + ListElement *m_first; + ListElement *m_last; + +public: + /** Constructor. */ + List() + : m_first((ListElement*) 0), m_last((ListElement*) 0) { + } + /** Copy-constructor. + * \param copy The list to copy. */ + List(const List ©); + /** Destructor. Destroys the list elements. */ + ~List(); + + /** Assignment operator. + * \param copy The list to copy. + * \return A reference to this list. */ + List &operator =(const List ©); + /** Append the given list. + * \param list The list to append. + * \return A reference to this list. */ + List &operator +=(const List &list); + /** Create a new list containing the elements of this + * list followed by the elements of the given list. + * \param list The other list. + * \return A new list containing the elements of both lists. */ + List operator +(const List &list); + + /** Destroy the list elements. */ + void clear(); + + /** Append an element to the list. + * \param element The element. */ + void append(ListElement &element); + /** Prepend an element to the list. + * \param element The element. */ + void prepend(ListElement &element); + /** Insert an element at the given list position. + * \param at A list element where to insert the element. + * \param element The element. */ + void insert(ListElement *at, ListElement &element); + /** Remove the given element from the list. + * \param element The list element. */ + void remove(ListElement *element); + /** Remove and destroy all elements between the + * given list elements. + * \param from The first list element to kill. + * \param to The last list element to kill. */ + void kill(ListElement *from, ListElement *to = (ListElement*) 0) { + List discard; + cut(discard, from, to); + } + /** Cut all elements between the given list elements. + * \param out The container for the cutted elements (are appended). + * \param from The first list element to cut. + * \param to The last list element to cut. */ + void cut(List &out, ListElement *from, ListElement *to = (ListElement*) 0); + /** Copy all elements between the given list elements. + * \param from The first list element to cut. + * \param to The last list element to cut. + * \return A new list containing the copied elements. */ + List *copy(ListElement *from = (ListElement*) 0, ListElement *to = (ListElement*) 0); + /** Insert copies of the elements of the given list at + * the given list position. + * \param at The list element at which to paste the list elements. + * \param l The list containing the elements to paste. */ + void paste(ListElement *at, const List &l); + /** Insert copies of the elements of the given list before + * the given list position. + * \param at The list element before which to paste the list elements. + * \param l The list containing the elements to paste. */ + void paste_before(ListElement *at, const List &l); + /** Insert the elements of the given list at the given + * list position. The elements are removed from the source + * list. + * \param at The list element at which to insert the list elements. + * \param l The list containing the elements to insert. */ + void move(ListElement *at, List &l); + /** Insert the elements of the given list before the given + * list position. The elements are removed from the source + * list. + * \param at The list element before which to insert the list elements. + * \param l The list containing the elements to insert. */ + void move_before(ListElement *at, List &l); + + /** Check if the list is empty. + * return True if the list is empty. */ + bool empty() const { + return m_first == (ListElement*) 0; + } + + /** Get the first element in the list. + * \return A pointer to the first element, or NULL if list is empty. */ + const ListElement *first() const { + return m_first; + } + /** Get the last element in the list. + * \return A pointer to the last element, or NULL if list is empty. */ + const ListElement *last() const { + return m_last; + } + /** Get the next element of the given element. + * \return A pointer to the next element, or NULL if the given element is NULL. */ + const ListElement *next(const ListElement *element) const { + return element ? element->m_next : 0; + } + /** Get the previous element of the given element. + * \return A pointer to the previous element, or NULL if the given element is NULL. */ + const ListElement *prev(const ListElement *element) const { + return element ? element->m_prev : 0; + } +}; + +} // namespace Puma + +#endif /* PUMA_List_H */ diff --git a/Puma/src/basics/ListElement.h b/Puma/src/basics/ListElement.h new file mode 100644 index 0000000..48e88aa --- /dev/null +++ b/Puma/src/basics/ListElement.h @@ -0,0 +1,64 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_ListElement_H +#define PUMA_ListElement_H + +/** \file + * Double-linked list element. */ + +#include + +namespace Puma { + +class List; + +/** \class ListElement ListElement.h Puma/ListElement.h + * Double-linked list element type to be used as elements + * for class List. To be derived for concrete list elements. + * \ingroup basics */ +class ListElement { + friend class List; + + List *m_belonging_to; + ListElement *m_next; + ListElement *m_prev; + +public: + /** Constructor. */ + ListElement() + : m_belonging_to(0), m_next(0), m_prev(0) { + } + /** Destructor. */ + virtual ~ListElement() { + assert(!m_belonging_to); + } + /** Get the list this element belongs to. + * \return A pointer to the list, or NULL if not belonging to any list. */ + List *belonging_to() const { + return m_belonging_to; + } + /** Duplicate this list element. To be implemented by concrete + * list element implementations. + * \return A pointer to the new list element. */ + virtual ListElement *duplicate() = 0; +}; + +} // namespace Puma + +#endif /* PUMA_ListElement_H */ diff --git a/Puma/src/basics/MemPool.cc b/Puma/src/basics/MemPool.cc new file mode 100644 index 0000000..5b700b0 --- /dev/null +++ b/Puma/src/basics/MemPool.cc @@ -0,0 +1,76 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 "Puma/MemPool.h" + +namespace Puma { + +MemPool::MemPool(unsigned long blocksize) { + m_block = (Link*) 0; + m_size = 0L; + m_used = 0L; + m_defsize = blocksize; + grow(m_defsize); +} + +MemPool::~MemPool() { + free(); +} + +unsigned long MemPool::align(unsigned long size) { + return (size + alignment - 1L) & ~(alignment - 1L); +} + +void MemPool::grow(unsigned long blocksize) { + Link *head = m_block; + + m_used = align((unsigned long) sizeof(Link)); + m_size = blocksize + m_used; + m_block = (Link*) Heap::malloc(m_size); + m_block->next = head; +} + +void *MemPool::alloc(unsigned long objectsize) { + void *objectptr; + + objectsize = align(objectsize); + + if (m_used + objectsize > m_size) + grow(objectsize > m_defsize ? objectsize : m_defsize); + + objectptr = (void*) ((char*) m_block + m_used); + m_used += objectsize; + + return objectptr; +} + +void MemPool::dealloc(void *) { +} + +void MemPool::free() { + Link *curr = m_block; + Link *next; + + while (curr) { + next = curr->next; + Heap::free(curr); + curr = next; + } +} + +} // namespace Puma diff --git a/Puma/src/basics/MemPool.h b/Puma/src/basics/MemPool.h new file mode 100644 index 0000000..9589fee --- /dev/null +++ b/Puma/src/basics/MemPool.h @@ -0,0 +1,73 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_MemPool_H +#define PUMA_MemPool_H + +/** \file + * Memory pool implementation. */ + +#include "Puma/Heap.h" + +namespace Puma { + +/** \class MemPool MemPool.h Puma/MemPool.h + * Memory pool implementation based on a linked list of memory blocks. + * Allocates large blocks of memory to reduce the overhead of memory + * allocation when a lot of small objects need to be allocated. Does not + * free any allocated memory until the pool is destroyed. + * \warning This class is not used and may disappear without notice. + * \ingroup basics */ +class MemPool : protected Heap { + static const unsigned long alignment = sizeof(long); // object alignment + + struct Link { + struct Link *next; + }; + + Link *m_block; + unsigned long m_size; + unsigned long m_used; + unsigned long m_defsize; + + void grow(unsigned long blocksize); + unsigned long align(unsigned long size); + +public: + /** Construct a new memory pool. + * \param blocksize Size of a memory block. Defaults to 128 KB.*/ + MemPool(unsigned long blocksize = 128L * 1024L); + /** Destroy the pool. Frees the allocated memory. */ + ~MemPool(); + /** Allocate memory for a new object of a given size. + * Usually no new memory needs to be allocated, but a chunk of + * previously allocated memory is returned. + * \param objectsize The size of the object in bytes. + * \return The allocated memory. */ + void *alloc(unsigned long objectsize); + /** De-allocate memory for a new object. Since no memory is + * freed until the pool is destroyed, this method does nothing. + * \param pointer Pointer to the chunk of memory to de-allocate. */ + void dealloc(void *pointer); + /** Free all the allocated memory in this pool. */ + void free(); +}; + +} // namespace Puma + +#endif /* PUMA_MemPool_H */ diff --git a/Puma/src/basics/Pipe.cc b/Puma/src/basics/Pipe.cc new file mode 100644 index 0000000..238a3a4 --- /dev/null +++ b/Puma/src/basics/Pipe.cc @@ -0,0 +1,75 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 "Puma/Pipe.h" + +namespace Puma { + +Pipe::Pipe(int buffer_size) { + m_size = buffer_size; + m_buffer = new char[m_size]; + m_wpos = m_buffer; + m_rpos = m_buffer; + m_empty = true; +} + +Pipe::~Pipe() { + delete[] m_buffer; +} + +int Pipe::read(char *dest, int n) { + int p; + + for (p = 0; p < n; p++) { + if (!m_empty) { + dest[p] = *m_rpos++; + if (m_rpos == m_buffer + m_size) + m_rpos = m_buffer; + if (m_rpos == m_wpos) + m_empty = true; + } else + break; + } + return p; +} + +int Pipe::write(const char *dest, int n) { + int p; + + for (p = 0; p < n; p++) { + if (m_rpos != m_wpos || m_empty) { + *m_wpos++ = dest[p]; + if (m_wpos == m_buffer + m_size) + m_wpos = m_buffer; + m_empty = false; + } else + break; + } + return p; +} + +int Pipe::free() { + if (m_wpos > m_rpos) + return m_size - (m_wpos - m_buffer) + (m_rpos - m_buffer); + else if (m_wpos == m_rpos) + return m_empty ? m_size : 0; + else + return (m_rpos - m_buffer) - (m_wpos - m_buffer); +} + +} // namespace Puma diff --git a/Puma/src/basics/Pipe.h b/Puma/src/basics/Pipe.h new file mode 100644 index 0000000..779cb51 --- /dev/null +++ b/Puma/src/basics/Pipe.h @@ -0,0 +1,69 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_Pipe_H +#define PUMA_Pipe_H + +/** \file + * Input/output pipe implementation. */ + +#include "Puma/Source.h" +#include "Puma/Sink.h" + +namespace Puma { + +/** \class Pipe Pipe.h Puma/Pipe.h + * Pipe between an input source and an output sink. + * \warning This class is not used and may disappear without notice. + * \ingroup basics */ +class Pipe : public Source, public Sink { + char *m_buffer; + char *m_rpos; + char *m_wpos; + int m_size; + bool m_empty; + +public: + /** Constructor. + * \param buffer_size Source buffer size. */ + Pipe(int buffer_size); + /** Destructor. */ + ~Pipe(); + /** Read n bytes from the internal buffer into the given string buffer. + * \param buffer The string used as buffer for the bytes read. + * \param n The number of bytes to read. + * \return The number of bytes read, or -1 in case of errors. */ + int read(char *buffer, int n); + /** Write n bytes from the given buffer into the internal source buffer. + * \param buffer The bytes to write. + * \param n The number of bytes to write. + * \return The number of bytes written. */ + int write(const char *buffer, int n); + /** Get the number of bytes left in the internal buffer. + * \return The free space in the internal buffer. */ + int free(); + /** Check if the internal buffer is full. + * \return True if no space left in the internal buffer. */ + bool full() { + return free() == 0; + } +}; + +} // namespace Puma + +#endif /* PUMA_Pipe_H */ diff --git a/Puma/src/basics/PipedCmd.cc b/Puma/src/basics/PipedCmd.cc new file mode 100644 index 0000000..cb841d8 --- /dev/null +++ b/Puma/src/basics/PipedCmd.cc @@ -0,0 +1,59 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 "Puma/PipedCmd.h" + +#ifdef _MSC_VER +#define popen _popen +#define pclose _pclose +#endif + +namespace Puma { + +void PipedCmd::readin(FILE *fin) { + static const int BUFSIZE = 1024; + + char buf[BUFSIZE]; + int len; + + while ((len = fread(buf, 1, BUFSIZE - 1, fin)) != 0) { + buf[len] = 0; + m_Output += buf; + } +} + +void PipedCmd::reset() { + fflush(stdout); + m_Output = ""; +} + +int PipedCmd::exec(const char *cmd) { + int res = -1; + + reset(); + + FILE *file = popen(cmd, "r"); + if (file != 0) { + readin(file); + res = pclose(file); + } + + return res; +} + +} // namespace Puma diff --git a/Puma/src/basics/PipedCmd.h b/Puma/src/basics/PipedCmd.h new file mode 100644 index 0000000..f86c75d --- /dev/null +++ b/Puma/src/basics/PipedCmd.h @@ -0,0 +1,58 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_PipedCmd_H +#define PUMA_PipedCmd_H + +/** \file + * External command execution implementation. */ + +#include +#include + +namespace Puma { + +/** \class PipedCmd PipedCmd.h Puma/PipedCmd.h + * Executes a shell command and gives access to the output of the command. + * \ingroup basics */ +class PipedCmd { + std::string m_Output; + + void reset(); + void readin(FILE *); + +public: + /** Constructor. */ + PipedCmd() { + } + + /** Execute the given shell command. + * \param cmd The shell command. + * \return The return code of the command. */ + int exec(const char* cmd); + + /** Get the output produced by the executed command. + * \return A reference to a string with the recored output. */ + const std::string &getOutput() const { + return m_Output; + } +}; + +} // namespace Puma + +#endif /* PUMA_PipedCmd_H */ diff --git a/Puma/src/basics/Printable.h b/Puma/src/basics/Printable.h new file mode 100644 index 0000000..1f0411d --- /dev/null +++ b/Puma/src/basics/Printable.h @@ -0,0 +1,71 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_Printable_H +#define PUMA_Printable_H + +/** \file + * Object printing. */ + +#include + +namespace Puma { + +/** \class Printable Printable.h Puma/Printable.h + * Provides that possibility for an object to be + * used with output streams (std::ostream). Derived + * classes have to implement method Printable::print(). + * + * Example: + * \code + * class Name : public Puma::Printable { + * const char* the_name; + * public: + * Name(const char* n) : the_name(n) {} + * void print(ostream &os) { + * os << "[name: " << the_name << "]"; + * } + * }; + * + * Name adam("adam"); + * std::cout << adam << std::endl; // prints "[name: adam]\n" + * \endcode + * \ingroup basics */ +class Printable { +public: + /** Destructor. */ + virtual ~Printable() { + } + /** Print object information on the given output stream. + * To be implemented by concrete objects. + * \param os The output stream. */ + virtual void print(std::ostream &os) const = 0; +}; + +/** Output stream operator for Printable objects. + * \param os The output stream. + * \param object The object to print. + * \return A reference to the output stream. */ +inline std::ostream &operator<<(std::ostream &os, const Printable &object) { + object.print(os); + return os; +} + +} // namespace Puma + +#endif /* PUMA_Printable_H */ diff --git a/Puma/src/basics/PtrStack.h b/Puma/src/basics/PtrStack.h new file mode 100644 index 0000000..35fd84d --- /dev/null +++ b/Puma/src/basics/PtrStack.h @@ -0,0 +1,193 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_PtrStack_H +#define PUMA_PtrStack_H + +/** \file + * Layered pointer stack implementation. */ + +#include "Puma/Stack.h" +#include "Puma/BCStack.h" + +namespace Puma { + +/** \class PtrStack PtrStack.h Puma/PtrStack.h + * Layered stack for pointers to objects. Each layer is a separate stack. + * Layers can be added, dropped, or destroyed. + * \ingroup basics */ +template +class PtrStack : private Array { + BCStack m_indices; // start indices + +public: + /** Construct a new layered stack. + * \param size The size of each layer. Defaults to 8192. + * \param incr The increment for the size of each layer. Defaults to 8192. */ + PtrStack(long size = 8192, long incr = 8192); + /** Destructor. */ + virtual ~PtrStack() { + } + + /** \name Stack operations */ + //@{ + /** Add a new item on the top of the current layer. + * \param item The item to add. */ + void Push(const T *item); + /** Remove the top item from the current layer. */ + void Pop(); + /** Get the top item from the current layer. + * \return The top item, or NULL if the current layer is empty. */ + T *Top() const; + /** Get the number of items added to the current layer. + * \return The number of items on the current layer. */ + long Length() const; + /** Get the n-th item on the current layer. + * \param n The index of the item to get. + * \return The n-th item, or NULL if the index is invalid. */ + T *Get(long n) const; + //@} + + /** \name Layer operations */ + //@{ + /** Create a new layer. */ + void New(); + /** Remove the top layer and add its items to the underlying layer. */ + void Forget(); + /** Remove the top layer. */ + void Reject(); + /** Remove the top layer and delete its items. */ + void Destroy(); + /** Get the number of layers. + * \return Number of the layers. */ + long Stacks() const; + /** Remove all layers. */ + void Reset(); + //@} + +protected: + /** Remove the top item of the current layer. */ + virtual void Remove(); + /** Remove and delete the top item of the current layer. */ + virtual void Delete(); + +private: + long Index() const; // return current index + long Bottom() const; // return start index of current stack +}; + +template +inline PtrStack::PtrStack(long is, long incr) + : Array(is, incr) { + New(); +} + +template +inline void PtrStack::Reset() { + m_indices.reset(); + Array::reset(); + New(); +} + +template +inline long PtrStack::Index() const { + return Array::length() - 1; +} + +template +inline long PtrStack::Bottom() const { + return m_indices.top(); +} + +template +inline long PtrStack::Stacks() const { + return m_indices.length(); +} + +template +inline long PtrStack::Length() const { + return Index() - Bottom(); +} + +template +inline T *PtrStack::Top() const { + if (Length() > 0) + return Array::lookup(Index()); + else + return (T*) 0; +} + +template +inline void PtrStack::Push(const T *item) { + this->append((T*) item); +} + +template +inline void PtrStack::Pop() { + if (Length() > 0) + Array::remove(Index()); +} + +template +inline T *PtrStack::Get(long idx) const { + if (Length() <= 0 || idx < 0 || (unsigned long) idx >= (unsigned long) Length()) + return (T*) 0; + return Array::lookup(Bottom() + 1 + idx); +} + +template +inline void PtrStack::New() { + m_indices.push(Index()); +} + +template +inline void PtrStack::Forget() { + m_indices.pop(); +} + +template +inline void PtrStack::Reject() { + while (Length() > 0) + Remove(); + Forget(); +} + +template +inline void PtrStack::Destroy() { + while (Length() > 0) { + Delete(); + Array::remove(Index()); // Pop() + } + Forget(); +} + +template +inline void PtrStack::Remove() { + Array::remove(Index()); // Same as Pop() +} + +template +inline void PtrStack::Delete() { + T *item = Top(); + if (item) + delete item; +} + +} // namespace Puma + +#endif /* PUMA_PtrStack_H */ diff --git a/Puma/src/basics/RegComp.cc b/Puma/src/basics/RegComp.cc new file mode 100644 index 0000000..a98ff04 --- /dev/null +++ b/Puma/src/basics/RegComp.cc @@ -0,0 +1,85 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 "Puma/RegComp.h" +#include "Puma/ErrorStream.h" + +#include "lexertl/rules.hpp" +#include "lexertl/generator.hpp" +#include "lexertl/lookup.hpp" + +namespace Puma { + +// Constructors +RegComp::RegComp(const std::string &expr) + : m_expr(expr), m_compiled(false) { +} + +RegComp::RegComp(const RegComp &rc) + : m_expr(rc.m_expr), m_compiled(false) { +} + +RegComp &RegComp::operator =(const RegComp &rc) { + m_expr = rc.m_expr; + m_error_msg.clear(); + m_compiled = false; + m_state.clear(); + return *this; +} + +// Compile the regular expression. +bool RegComp::compile(const std::string &expr) { + m_compiled = true; + lexertl::rules rules; + rules.push(m_expr, 1); // id is '1', because it is not needed; but != 0 + try { + lexertl::generator::build(rules, m_state); // gen. state machine representation + } catch (const std::exception &e) { + m_error_msg = e.what(); + return false; + } + return true; +} + +// Match against a string. +bool RegComp::match(const std::string &str) { + if (!m_compiled) + compile(m_expr); + + std::string input(str); + std::string::const_iterator iter = input.begin(); + std::string::const_iterator end = input.end(); + lexertl::match_results results(iter, end); + + try { + lexertl::lookup(m_state, results); + } catch (const std::exception &e) { + m_error_msg = e.what(); + m_error_msg += std::string("; matched '") + str + "' with regex '" + m_expr + "'"; + return false; + } + return (results.id == 1); +} + +// To be called on errors. +void RegComp::comperror(ErrorStream &err) const { + if (error()) + err << sev_error << "RegComp: " << m_error_msg.c_str() << endMessage; +} + +} // namespace Puma diff --git a/Puma/src/basics/RegComp.h b/Puma/src/basics/RegComp.h new file mode 100644 index 0000000..3cc4312 --- /dev/null +++ b/Puma/src/basics/RegComp.h @@ -0,0 +1,80 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_RegComp_H +#define PUMA_RegComp_H + +/** \file + * Wrapper for regular expression matching. */ + +#include +#include "lexertl/state_machine.hpp" +#include "Puma/ErrorStream.h" + +namespace Puma { + +/** \class RegComp RegComp.h Puma/RegComp.h + * Regular expression matching. This class compiles the + * expression when a string is matched for the first time. + * In case of an error, an error message can be printed on an + * error stream. + * \ingroup basics */ +class RegComp { + std::string m_expr; // the regular expression + std::string m_error_msg; // error message in case of problems + bool m_compiled; // determines whether the state machine is valid + lexertl::state_machine m_state; // internal: lexertl compiled regular expression + +public: + /** Constructor. + * \param expr The regular expression. */ + RegComp(const std::string &expr); + /** Copy-constructor. + * \param copy The regular expression to copy. */ + RegComp(const RegComp ©); + + /** Assign a regular expression. + * \param copy The regular expression. + * \return A reference to this object. */ + RegComp &operator =(const RegComp ©); + + /** Compile the regular expression. + * \param expr The regular expression. + * \return False in case of an errors. Use comperror() to print the error message. */ + bool compile(const std::string &expr); + + /** Match against a string. + * \param str String to be matched. + * \return True if the regular expression matches the string. */ + bool match(const std::string & str); + + /** Print a regular expression compilation error message on the + * given error stream. To be called when compile() fails. + * \param err Error stream on which to print the error message. */ + void comperror(ErrorStream &err) const; + + /** Check whether there was an error compiling the regular expression. + * \return True in case of an error. Use comperror to print it. */ + bool error() const { + return !m_error_msg.empty(); + } +}; + +} // namespace Puma + +#endif /* PUMA_RegComp_H */ diff --git a/Puma/src/basics/Sink.h b/Puma/src/basics/Sink.h new file mode 100644 index 0000000..9877158 --- /dev/null +++ b/Puma/src/basics/Sink.h @@ -0,0 +1,49 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_Sink_H +#define PUMA_Sink_H + +/** \file + * Output sink interface. */ + +namespace Puma { + +/** \class Sink Sink.h Puma/Sink.h + * Output sink interface. + * \warning This class is not used and may disappear without notice. + * \ingroup basics */ +class Sink { +public: + /** Destructor. */ + virtual ~Sink() {} + /** Write n bytes from the given buffer into the sink. + * \param buffer The bytes to write. + * \param n The number of bytes to write. + * \return The number of bytes written. */ + virtual int write(const char *buffer, int n) = 0; + /** Check if the output sink is full. + * \return This default implementation always returns false. */ + virtual bool full() { + return false; + } +}; + +} // namespace Puma + +#endif /* PUMA_Sink_H */ diff --git a/Puma/src/basics/SmartPtr.h b/Puma/src/basics/SmartPtr.h new file mode 100644 index 0000000..547e0d3 --- /dev/null +++ b/Puma/src/basics/SmartPtr.h @@ -0,0 +1,171 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_SmartPtr_H +#define PUMA_SmartPtr_H + +/** \file + * Smart pointer implementation. */ + +namespace Puma { + +/** \class SmartPtr SmartPtr.h Puma/SmartPtr.h + * Template based smart pointer implementation. Classes must + * be derived from SmartPtr::RefCnt to be compatible with + * this implementation. Example: + * + * \code + * class Object : public SmartPtr::RefCnt { + * //... + * }; + * SmartPtr object = new Object(); + * \endcode + * \ingroup basics */ +template +class SmartPtr { +public: + /** \class RefCnt SmartPtr.h Puma/SmartPtr.h + * Reference counter for objects used with SmartPtr. */ + class RefCnt { + int m_counter; + friend class SmartPtr ; + protected: + /** Constructor. */ + RefCnt() + : m_counter(0) { + } + }; + +private: + T *m_pointer; + +public: + /** Construct an empty smart pointer. */ + SmartPtr() + : m_pointer(0) { + } + /** Construct a new smart pointer. + * \param pointer A pointer to the object to manage. */ + SmartPtr(const RefCnt *pointer) + : m_pointer(0) { + *this = pointer; + } + /** Copy a smart pointer. Increases the reference count + * of the managed object. + * \param copy The smart pointer to copy. */ + SmartPtr(const SmartPtr ©) + : m_pointer(0) { + *this = copy.m_pointer; + } + /** Destroy the smart pointer. If this was the last + * smart pointer referencing the managed object, the + * object is destroyed too. */ + ~SmartPtr() { + clear(); + } + /** Clear this smart pointer. If this was the last + * smart pointer referencing the managed object, the + * object is destroyed. */ + void clear(); + /** Check whether the smart pointer is valid. A smart pointer + * is valid if the managed pointer isn't NULL. + * \return True if valid. */ + bool valid() const { + return m_pointer != 0; + } + /** Compare this smart pointer with another smart pointer. + * \param other The smart pointer to compare with. + * \return True if both smart pointers point to the same object. */ + bool operator==(const SmartPtr &other) const { + return m_pointer == other.m_pointer; + } + /** Assign a new object to this smart pointer. If this smart pointer + * already points to an object, then this object might be destroyed + * if not referenced by another smart pointer. + * \param copy The smart pointer to copy. + * \return A reference to this smart pointer. */ + SmartPtr &operator=(const SmartPtr ©) { + return *this = copy.m_pointer; + } + /** Assign a new object to this smart pointer. If this smart pointer + * already points to an object, then this object might be destroyed + * if not referenced by another smart pointer. + * \param copy The smart pointer to copy. + * \return A reference to this smart pointer. */ + SmartPtr &operator=(const RefCnt *copy); + /** Conversion operator to check whether the smart pointer is valid. + * \return True if valid. */ + operator bool() const { + return valid(); + } + /** Conversion operator for the managed object pointer type. + * \return A pointer to the managed object. */ + operator T*() const { + return m_pointer; + } + /** Conversion operator for the managed object pointer type. + * \return A constant pointer to the managed object. */ + operator const T*() const { + return m_pointer; + } + /** Dereference operator for the managed object pointer type. + * \return A pointer to the managed object. */ + T* operator->() { + return m_pointer; + } + /** Dereference operator for the managed object pointer type. + * \return A constant pointer to the managed object. */ + const T* operator->() const { + return m_pointer; + } + /** Indirection operator for the managed object pointer type. + * \return A pointer to the managed object. */ + T* operator*() { + return m_pointer; + } + /** Indirection operator for the managed object pointer type. + * \return A constant pointer to the managed object. */ + const T* operator*() const { + return m_pointer; + } +}; + +template +inline SmartPtr &SmartPtr::operator=(const RefCnt *copy) { + if (copy != m_pointer) { + clear(); + m_pointer = (T*) copy; + if (valid()) + m_pointer->m_counter++; + } + return *this; +} + +template +inline void SmartPtr::clear() { + if (valid()) { + m_pointer->m_counter--; + if (m_pointer->m_counter == 0) + delete m_pointer; + m_pointer = (T*) 0; + } +} + +} // namespace Puma + +#endif /* PUMA_SmartPtr_H */ diff --git a/Puma/src/basics/Source.h b/Puma/src/basics/Source.h new file mode 100644 index 0000000..d7cfa8f --- /dev/null +++ b/Puma/src/basics/Source.h @@ -0,0 +1,53 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_Source_H +#define PUMA_Source_H + +/** \file + * Input source interface. */ + +namespace Puma { + +/** \class Source Source.h Puma/Source.h + * Interface for all input sources. + * \ingroup basics */ +class Source { +public: + /** Constructs an empty source object. */ + Source() { + } + /** Destroys the source object. */ + virtual ~Source() { + } + /** Read n bytes from the source into the given string buffer. + * \param buffer The string used as buffer for the bytes read. + * \param n The number of bytes to read. + * \return The number of bytes read, or -1 in case of errors. */ + virtual int read(char *buffer, int n) = 0; + /** Get the size of the source. To be implemented if a specific + * source supports asking for its size. + * \return This default implementation always returns -1 to indicate that the size is unknown. */ + virtual int size() { + return -1; + } +}; + +} // namespace Puma + +#endif /* PUMA_Source_H */ diff --git a/Puma/src/basics/Stack.h b/Puma/src/basics/Stack.h new file mode 100644 index 0000000..1d1937c --- /dev/null +++ b/Puma/src/basics/Stack.h @@ -0,0 +1,70 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_Stack_H +#define PUMA_Stack_H + +/** \file + * Stack implementation. */ + +#include "Puma/Array.h" + +namespace Puma { + +/** \class Stack Stack.h Puma/Stack.h + * Stack implementation based on a variable length array. + * \tparam Item The stack item type. + * \ingroup basics */ +template +class Stack : private Array { +public: + /** Construct a new stack. + * \param is The default size of the stack. + * \param incr The default increment value for the stack size. */ + Stack(long is = 8192, long incr = 8192) + : Array(is, incr) { + } + /** Add a new item on top of the stack. + * \param item The item to add. */ + void push(Item item) { + Array::append(item); + } + /** Get the top item from the stack. + * \return A reference to the top stack item. */ + Item &top() const { + long len = Array::length() - 1; + return Array::lookup(len >= 0 ? len : 0); + } + /** Remove the top item from the stack. */ + void pop() { + Array::remove(Array::length() - 1); + } + /** Get the number of items on the stack. + * \return The number of items. */ + long length() const { + return Array::length(); + } + /** Reset the stack. */ + void reset() { + Array::reset(); + } +}; + +} // namespace Puma + +#endif /* __stack_h__ */ diff --git a/Puma/src/basics/StrCol.cc b/Puma/src/basics/StrCol.cc new file mode 100644 index 0000000..570c140 --- /dev/null +++ b/Puma/src/basics/StrCol.cc @@ -0,0 +1,195 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 "Puma/Unit.h" +#include "Puma/Token.h" +#include "Puma/StrCol.h" +#include +#include + +namespace Puma { + +char *StrCol::dup(const char *str, int len) { + char *res = new char[len + 1]; + memcpy(res, str, len); + res[len] = '\0'; + return res; +} + +char *StrCol::dup(const char *str) { + return dup(str, strlen(str)); +} + +// Return true if character is a white space. +bool StrCol::isSpace(const char c) { + if (c == ' ' || c == '\n' || c == '\t' || c == '\f' || c == '\v' || c == '\b' || c == '\r') + return true; + return false; +} + +// Return true if the string consists only of spaces. +bool StrCol::onlySpaces(const char *str) { + if (!str) + return false; + + while (*str != '\0') { + if (!isSpace(*str)) + return false; + str++; + } + return true; +} + +// Return true if the two strings differ not only in spaces. +bool StrCol::effectivelyDifferent(const char *str1, const char *str2) { + if (!str1 || !str2) + return true; + + // Skip the leading white spaces. + while (isSpace(*str1)) + str1++; + while (isSpace(*str2)) + str2++; + + while (true) { + // Skip white spaces if there are some at these position + // in both strings or if we are at the end of a string. + if ((isSpace(*str1) && isSpace(*str2)) || (*str1 == '\0' || *str2 == '\0')) { + while (isSpace(*str1)) + str1++; + while (isSpace(*str2)) + str2++; + } + + // Found a difference. Strings are different. + if (*str1 != *str2) + return true; + + // Stop comparison at end of string. + if (*str1 == '\0' || *str2 == '\0') + break; + + str1++; + str2++; + } + + // Can only be reached if both strings are not + // effectively different. + return false; +} + +// Calculate a hash for a string +unsigned int StrCol::hash(const char *data) { + return hash(data, strlen(data)); +} + +#undef get16bits +#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) +#define get16bits(d) (*((const uint16_t *) (d))) +#endif +#if !defined (get16bits) +#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)+(uint32_t)(((const uint8_t *)(d))[0]) ) +#endif + +// Calculate a hash for a string (Hsieh algorithm) +unsigned int StrCol::hash(const char *data, int len) { + uint32_t hash = len, tmp; + int rem; + + if (len <= 0 || data == NULL) + return 0; + + rem = len & 3; + len >>= 2; + + for (; len > 0; len--) { + hash += get16bits(data); + tmp = (get16bits (data+2) << 11) ^ hash; + hash = (hash << 16) ^ tmp; + data += 2 * sizeof(uint16_t); + hash += hash >> 11; + } + + switch (rem) { + case 3: + hash += get16bits(data); + hash ^= hash << 16; + hash ^= data[sizeof(uint16_t)] << 18; + hash += hash >> 11; + break; + case 2: + hash += get16bits(data); + hash ^= hash << 11; + hash += hash >> 17; + break; + case 1: + hash += *data; + hash ^= hash << 10; + hash += hash >> 1; + } + + hash ^= hash << 3; + hash += hash >> 5; + hash ^= hash << 4; + hash += hash >> 17; + hash ^= hash << 25; + hash += hash >> 6; + + return hash; +} + +// replace environment variables of the form ${ENVVAR} +std::string& StrCol::replaceEnvironmentVariables(std::string& s) { + std::string::size_type varbegin = 0, varend = 0; + + // find first opening parenthesis + varbegin = s.find("${", 0); + while (varbegin != std::string::npos) { + + // find closing parenthesis + varend = s.find("}", varbegin + 2); + if (varend != std::string::npos) { + + // check if '$' is protected by a backslash + std::string::size_type pos = varbegin, even = 1; + while (pos > 0 ? s.at(--pos) == '\\' : (even = 0)) + ; + if ((varbegin - pos) % 2 != even) { + // odd number of backslashes, do not replace, but remove last backslash + s.erase(varbegin - 1, 1); + varend = varbegin; + } else { + // get the value of the environment variable + const char* vstr = getenv(s.substr(varbegin + 2, varend - varbegin - 2).c_str()); + std::string value = vstr ? vstr : ""; + // replace the variable with its value + s.replace(varbegin, varend - varbegin + 1, value); + varend = varbegin + value.length(); + } + // find next variable + varbegin = s.find("${", varend); + + } else { + // end of string + varbegin = std::string::npos; + } + } + return s; +} + +} // namespace Puma diff --git a/Puma/src/basics/StrCol.h b/Puma/src/basics/StrCol.h new file mode 100644 index 0000000..e9f2985 --- /dev/null +++ b/Puma/src/basics/StrCol.h @@ -0,0 +1,86 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_StrCol_H +#define PUMA_StrCol_H + +/** \file + * Collection of string helper functions. */ + +#include + +namespace Puma { + +/** \class StrCol StrCol.h Puma/StrCol.h + * Collection of string helper functions. + * \ingroup basics */ +struct StrCol { + /** Check if the given character is one of: + * - white space + * - horizontal tab + * - vertical tab + * - form feed + * - line feed + * - carriage return + * - backspace + * + * \param c The character to check. + * \return True if it is a space character. */ + static bool isSpace(const char c); + + /** Check if the given string only contains space + * characters as recognized by isSpace(). + * \param str The string to check. + * \return True if there are only space characters in that string. */ + static bool onlySpaces(const char *str); + + /** Check if the two strings differ not only in spaces. + * \param str1 The first string. + * \param str2 The second string. + * \return True if there are differences other than spaces. */ + static bool effectivelyDifferent(const char *str1, const char *str2); + + /** Copy a string. + * \param str The string to copy. + * \return A newly allocated copy of the input string. */ + static char *dup(const char *str); + /** Copy the first n characters of a string. + * \param str The string to copy. + * \param n The number of characters to copy. + * \return A newly allocated string containing the first n characters of the input string. */ + static char *dup(const char *str, int n); + + /** Calculate a hash value for a string using the Hsieh algorithm. + * \param str The input string. + * \return The hash value. */ + static unsigned int hash(const char *str); + /** Calculate a hash value for the first n characters of a string using the Hsieh algorithm. + * \param str The input string. + * \param n The number of characters to consider for the hash value. + * \return The hash value. */ + static unsigned int hash(const char *str, int n); + + /** Replace environment variables of the form ${ENVVAR} in the given string. + * \param str A reference to the string containing the environment variables. + * \return A reference to the input string with environment variables replaced by their values. */ + static std::string& replaceEnvironmentVariables(std::string& str); +}; + +} // namespace Puma + +#endif /* PUMA_StrCol_H */ diff --git a/Puma/src/basics/StrHashKey.h b/Puma/src/basics/StrHashKey.h new file mode 100644 index 0000000..4c02137 --- /dev/null +++ b/Puma/src/basics/StrHashKey.h @@ -0,0 +1,71 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_StrHashKey_H +#define PUMA_StrHashKey_H + +/** \file + * String hash table key implementation. */ + +#include "Puma/StrCol.h" +#include "Puma/Chain.h" + +namespace Puma { + +/** \class StrHashKey StrHashKey.h Puma/StrHashKey.h + * String hash table key. + * \ingroup basics */ +class StrHashKey : public Chain { + unsigned int m_Magic; + unsigned int m_Len; + const char *m_Str; + +public: + /** Construct a new string hash table key. + * The input string is copied. + * \param magic The hash value. + * \param str The string. + * \param len The length of the string. */ + StrHashKey(int magic, const char *str, int len) + : m_Magic(magic), m_Len(len), m_Str(StrCol::dup(str, len)) { + } + /** Destroy the hash table key. Frees the string copy. */ + ~StrHashKey() { + if (m_Str) + delete[] m_Str; + } + /** Get the hash value of the string. + * \return The hash value. */ + unsigned int getMagic() const { + return m_Magic; + } + /** Get the length of the string. + * \return The string's length. */ + unsigned int length() const { + return m_Len; + } + /** Get the string. + * \return The string. */ + const char *c_str() const { + return m_Str; + } +}; + +} // namespace Puma + +#endif /* PUMA_StrHashKey_H */ diff --git a/Puma/src/basics/StrHashTable.cc b/Puma/src/basics/StrHashTable.cc new file mode 100644 index 0000000..7060f9e --- /dev/null +++ b/Puma/src/basics/StrHashTable.cc @@ -0,0 +1,78 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 "Puma/StrHashTable.h" +#include +#include + +namespace Puma { + +unsigned long StrHashTable::hash(const char *str, unsigned long& len) { + unsigned long h = 0; + const char* p = str; + while (*p) { + h = *p + (h << 6) + (h << 16) - h; + p++; + } + len = p - str; + return h % STRHASHTABLE_SIZE; +} + +StrHashKey *StrHashTable::find(unsigned long magic, const char *str, unsigned long len) { + StrHashKey *key = (StrHashKey*) m_table[magic].select(); + + while (key) { + if (key->length() == len && memcmp(key->c_str(), str, len) == 0) { + return key; + } + key = (StrHashKey*) key->select(); + } + return 0; +} + +void StrHashTable::clear() { + // delete all dynamically created hash keys + for (long i = 0; i < STRHASHTABLE_SIZE; i++) { + StrHashKey *key = (StrHashKey*) m_table[i].select(); + while (key) { + StrHashKey *curr = key; + key = (StrHashKey*) key->select(); + // don't need to unlink since the whole chain + // is deleted and unlinked below + delete curr; + } + // unlink the whole chain + m_table[i].select(0); + } + // restore valid state + m_emptyKey = insert(""); + assert(m_emptyKey); +} + +StrHashKey *StrHashTable::insert(const char *str) { + unsigned long len; + unsigned long magic = hash(str, len); + StrHashKey *key = find(magic, str, len); + if (key == 0) { + key = new StrHashKey(magic, str, len); + m_table[magic].insert(key); + } + return key; +} + +} // namespace Puma diff --git a/Puma/src/basics/StrHashTable.h b/Puma/src/basics/StrHashTable.h new file mode 100644 index 0000000..be22a70 --- /dev/null +++ b/Puma/src/basics/StrHashTable.h @@ -0,0 +1,69 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_StrHashTable_H +#define PUMA_StrHashTable_H + +/** \file + * String hash table implementation. */ + +#include "Puma/StrHashKey.h" +#include + +namespace Puma { + +/** \class StrHashTable StrHashTable.h Puma/StrHashTable.h + * String hash table backed by a fixed size array of + * single-linked chains. + * \ingroup basics */ +class StrHashTable { + enum { + /** Size of hash table array. */ + STRHASHTABLE_SIZE = 0xffff + }; + + StrHashKey *m_emptyKey; + Chain m_table[STRHASHTABLE_SIZE]; + + StrHashKey *find(unsigned long magic, const char *str, unsigned long len); + unsigned long hash(const char *str, unsigned long &len); + +public: + /** Construct a new empty hash table. */ + StrHashTable() { + m_emptyKey = insert(""); + assert(m_emptyKey); + } + /** Get the empty hash table item used for comparison purposes. + * \return The empty hash table item. */ + StrHashKey *empty() const { + assert(m_emptyKey); + return m_emptyKey; + } + /** Add a string to the hash table. Does not add strings + * twice. Added strings are copied. + * \param str The string to add. + * \return The hash table item for the string. */ + StrHashKey *insert(const char *str); + /** Clear the hash table and free all copied strings. */ + void clear(); +}; + +} // namespace Puma + +#endif /* PUMA_StrHashTable_H */ diff --git a/Puma/src/basics/StringSource.h b/Puma/src/basics/StringSource.h new file mode 100644 index 0000000..a262ba0 --- /dev/null +++ b/Puma/src/basics/StringSource.h @@ -0,0 +1,84 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_StringSource_H +#define PUMA_StringSource_H + +/** \file + * String input source implementation. */ + +#include "Puma/Source.h" +#include + +namespace Puma { + +/** \class StringSource StringSource.h Puma/StringSource.h + * String input source implementation implementing the Source interface. + * \ingroup basics */ +class StringSource : public Source { + const char *m_string; + int m_delivered; + int m_len; + +public: + /** Construct an empty string input source. */ + StringSource() + : m_string(0), m_delivered(0), m_len(-1) { + } + /** Construct an input source for the given string. + * \param string The string from which to read. */ + StringSource(const char *string) + : m_string(string) { + m_delivered = 0; + m_len = strlen(string); + } + /** Read n bytes from the input string into the given string. + * \param dest The string used as buffer for the bytes read. + * \param n The number of bytes to read. + * \return The number of bytes read, or -1 in case of errors. */ + virtual int read(char *dest, int n) { + int to_copy; + if (!m_string || m_delivered == m_len) + return 0; + to_copy = (n < m_len - m_delivered) ? n : m_len - m_delivered; + memcpy(dest, m_string + m_delivered, to_copy); + m_delivered += to_copy; + return to_copy; + } + /** Set the input string to read from. + * \param string The input string. */ + void string(const char *string) { + m_string = string; + m_delivered = 0; + m_len = strlen(m_string); + } + /** Get the input string. + * \return The input string, or null if no input string set. */ + const char *string() { + return m_string; + } + /** Get the size of the input string. + * \return The size of the input string, or -1 if no input string set. */ + int size() { + return m_len; + } +}; + +} // namespace Puma + +#endif /* PUMA_StringSource_H */ diff --git a/Puma/src/basics/SysCall.cc b/Puma/src/basics/SysCall.cc new file mode 100644 index 0000000..cce7c91 --- /dev/null +++ b/Puma/src/basics/SysCall.cc @@ -0,0 +1,569 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 "Puma/SysCall.h" +#include "Puma/StrCol.h" +#include "Puma/ErrorSink.h" +#include +#include +#include + +#ifdef _MSC_VER +# include +# include +#else +# include +# include +#endif // _MSC_VER + +#ifdef WIN32 +# include +# include +#endif // WIN32 + +#include +#include + +#ifndef MAX_PATH +#define MAX_PATH PATH_MAX +#endif // MAX_PATH + +namespace Puma { + +void SysCall::MakeUnixPath(char *path) { + if (!path) + return; + char *s = path; + while (*s) { + if (*s == '\\') + *s = '/'; + s++; + } +} + +void SysCall::MakeDosPath(char *path) { +#if defined (WIN32) + if (!path) + return; + char *s = path; + while (*s) { + if (*s == '/') + *s = '\\'; + s++; + } +#endif +} + +void SysCall::printerror(ErrorSink *err, const char *cmd, const char *path) { + if (err) { + *err << sev_fatal << path << ": command '" << cmd << "' failed, " << strerror(errno) << endMessage; + } +} + +void SysCall::printerror(ErrorSink *err, const char *cmd, int fd) { + if (err) { + *err << sev_fatal << fd << ": command '" << cmd << "' failed, " << strerror(errno) << endMessage; + } +} + +const char *SysCall::mktemp(const char *prefix, ErrorSink *err) { +#ifdef WIN32 + // get the system directory for temporary files + char tempdir[MAX_PATH+1]; + if (!::GetTempPath(MAX_PATH, tempdir)) { + printerror(err, "mktemp", "cannot get temp directory"); + tempdir[0] = '.'; + tempdir[1] = '\0'; + } + + // get the temp file name + char filename[MAX_PATH+1]; + if (!::GetTempFileName(tempdir, prefix, 0, filename)) { + printerror(err, "mktemp", "cannot create temp file name"); + filename[0] = '\0'; + } + + // needs to be freed by called + return strdup(filename); + +#else + + // create filename template + char const *sys_tempdir = ::getenv("TMPDIR"); + if (!sys_tempdir) { + sys_tempdir = "/tmp"; + } + std::string tempdir(sys_tempdir); + if (tempdir.length() > 0 && tempdir[tempdir.length() - 1] != '/') { + tempdir += "/"; + } + tempdir += prefix; + tempdir += "XXXXXX"; + char *filename = strdup(tempdir.c_str()); + + // create file with restrictive permissions 600 + mode_t old_mode = umask(077); + // create the temp file + int fd = mkstemp(filename); + // reset permissions + umask(old_mode); + + // close file descriptor + if (fd == -1 || ::close(fd) == -1) { + printerror(err, "mktemp", filename); + } + + // needs to be freed by called + return filename; +#endif +} + +int SysCall::open(const char *file, int flags, ErrorSink *err) { + int fd = -1; +#if defined(WIN32) + char *n = StrCol::dup(file); + if (n) { + MakeDosPath(n); + fd = ::open(n, flags | O_BINARY); + delete[] n; + } +#else + fd = ::open(file, flags); +#endif + if (fd == -1) + printerror(err, "open", file); + return fd; +} + +int SysCall::open_excl(const char *file, int flags, ErrorSink *err) { + int fd = open(file, flags, err); +#if defined(__GLIBC__) + if (fd >= 0) { + flock lock; + memset(&lock, 0, sizeof lock); + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + if (fcntl(fd, F_SETLKW, &lock) == -1) + printerror(err, "fcntl lock", file); + } +#endif + return fd; +} + +int SysCall::create(const char *file, int mode, ErrorSink *err) { + int fd = -1; +#if defined(WIN32) + char *n = StrCol::dup(file); + if (n) { + MakeDosPath(n); + fd = ::open(n, O_CREAT | O_WRONLY | O_TRUNC | O_BINARY, mode); + delete[] n; + } +#else + fd = ::open(file, O_CREAT | O_WRONLY | O_TRUNC, mode); +#endif + if (fd == -1) + printerror(err, "create", file); + return fd; +} + +int SysCall::create_excl(const char *file, int mode, ErrorSink *err) { + int fd = create(file, mode, err); +#if defined(__GLIBC__) + if (!(fd < 0)) { + flock lock; + memset(&lock, 0, sizeof lock); + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + if (fcntl(fd, F_SETLKW, &lock) == -1) + printerror(err, "fcntl lock", file); + } +#endif + return fd; +} + +bool SysCall::close(int fd, ErrorSink *err) { + int ret = ::close(fd); + if (ret == -1) { + printerror(err, "close", fd); + return false; + } + return true; +} + +bool SysCall::close_excl(int fd, ErrorSink *err) { +#if defined(__GLIBC__) + flock lock; + memset(&lock, 0, sizeof lock); + lock.l_type = F_UNLCK; + lock.l_whence = SEEK_SET; + if (fcntl(fd, F_SETLKW, &lock) == -1) { + printerror(err, "fcntl unlock", fd); + return false; + } +#endif + return close(fd, err); +} + +long SysCall::read(int fd, void *buffer, size_t n, ErrorSink *err) { + long bytes = ::read(fd, buffer, n); + if (bytes == -1) + printerror(err, "read", fd); + return bytes; +} + +bool SysCall::chdir(const char *dir, ErrorSink *err) { + int ret = -1; +#if defined(WIN32) + char *n = StrCol::dup(dir); + if (n) { + MakeDosPath(n); +#ifdef _MSC_VER + ret = ::_chdir(n); +#else + ret = ::chdir(n); +#endif // _MSC_VER + delete[] n; + } +#else + ret = ::chdir(dir); +#endif + if (ret == -1) { + printerror(err, "chdir", dir); + return false; + } + return true; +} + +char *SysCall::getcwd(char *buffer, size_t len, ErrorSink *err) { +#ifdef _MSC_VER + char *cwd = ::_getcwd(buffer, len); +#else + char *cwd = ::getcwd(buffer, len); +#endif // _MSC_VER +#if defined(WIN32) + if (cwd != 0) + MakeUnixPath(cwd); +#endif + if (!cwd) + printerror(err, "getcwd"); + return cwd; +} + +// Get the current working directory. +char *SysCall::readlink(const char *link, char *buffer, size_t len, ErrorSink *err) { +#if defined(WIN32) + buffer = 0; +#else + int pos = ::readlink(link, buffer, len); + if (pos == -1) { + printerror(err, "readlink", link); + return (char*) 0; + } + buffer[pos] = '\0'; +#endif + return buffer; +} + +time_t SysCall::time(time_t *t, ErrorSink *err) { + time_t curtime = ::time(t); + if (curtime == ((time_t) -1)) + printerror(err, "time"); + return curtime; +} + +bool SysCall::fstat(int fd, FileInfo &fi, ErrorSink *err) { +#ifdef _MSC_VER + int ret = ::_fstat(fd, &fi.info); +#else + int ret = ::fstat(fd, &fi.info); +#endif + if (ret == -1) { + printerror(err, "fstat", fd); + return false; + } + return true; +} + +bool SysCall::mkdir(const char *dir, ErrorSink *err) { + int ret = -1; +#if defined(WIN32) + char *n = StrCol::dup(dir); + if (n) { + MakeDosPath(n); + ret = ::mkdir(n); + delete[] n; + } +#else + mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO; + ret = ::mkdir(dir, mode); +#endif + if (ret == -1) { + printerror(err, "mkdir", dir); + return false; + } + return true; +} + +DirHandle SysCall::opendir(const char *dir, ErrorSink *err) { + DirHandle dp = NULL; +#if defined(WIN32) + char *n = StrCol::dup(dir); + if (n) { + MakeDosPath(n); +#ifdef _MSC_VER + std::string find_pattern(n); + if (find_pattern[find_pattern.length() - 1] != '\\') + find_pattern += "\\"; + find_pattern += "*"; + struct _finddata_t find_data; + long hdl = _findfirst(find_pattern.c_str(), &find_data); + if (hdl != -1L) + dp = new DIR(hdl); +#else + dp = ::opendir(n); +#endif // _MSC_VER + delete[] n; + } +#else + dp = ::opendir(dir); +#endif + if (!dp) + printerror(err, "opendir", dir); + return dp; +} + +#ifdef _MSC_VER +const char *SysCall::readdir(DirHandle dp, DirEntryType *det, ErrorSink *err) { + // try to get the next entry + static struct _finddata_t find_data; + const char *entry_name = 0; + while (!entry_name) { + if (_findnext(dp->handle, &find_data) == -1) + break; + if (strcmp(find_data.name, ".") != 0 && strcmp(find_data.name, "..") != 0) + entry_name = find_data.name; + } + if (det && entry_name) { + switch (find_data.attrib) { + case _A_NORMAL: *det = DET_REGULAR; break; + case _A_SUBDIR: *det = DET_DIRECTORY; break; + default: *det = DET_OTHER; + } + } + return entry_name; +} +#else +const char *SysCall::readdir(DirHandle dp, DirEntryType *det, ErrorSink *err) { + struct dirent *entry; + while (true) { + entry = ::readdir(dp); + // Ignore the `.' and `..' entries. + if (!entry || !(strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)) + break; + } + if (det && entry) { +#ifdef _DIRENT_HAVE_D_TYPE + switch (entry->d_type) { + case DT_REG: + *det = DET_REGULAR; + break; + case DT_DIR: + *det = DET_DIRECTORY; + break; + case DT_LNK: + *det = DET_LINK; + break; + default: + *det = DET_OTHER; + } +#else + *det = DET_NOT_IMPLEMENTED; +#endif + } + return entry ? entry->d_name : 0; +} +#endif // _MSC_VER + +bool SysCall::closedir(DirHandle dp, ErrorSink *err) { +#ifdef _MSC_VER + int ret = ::_findclose(dp->handle); + delete dp; +#else + int ret = ::closedir(dp); +#endif // _MSC_VER + if (ret == -1) { + printerror(err, "closedir"); + return false; + } + return true; +} + +bool SysCall::stat(const char *file, FileInfo &fi, ErrorSink *err) { + int ret = -1; +#if defined(WIN32) + char *n = StrCol::dup(file); + if (n) { + MakeDosPath(n); +#ifdef _MSC_VER + ret = ::_stat(n, &fi.info); +#else + ret = ::stat(n, &fi.info); +#endif + delete[] n; + } +#else + ret = ::stat(file, &fi.info); +#endif + if (ret == -1) { + if (errno == ENOMEM) + printerror(err, "stat", file); + return false; + } + return true; +} + +bool SysCall::fclose(FileHandle fstr, ErrorSink *err) { + int ret = ::fclose(fstr); + if (ret == EOF) { + printerror(err, "fclose"); + return false; + } + return true; +} + +FileHandle SysCall::fopen(const char *file, const char *mode, ErrorSink *err) { + FileHandle fstr = NULL; +#if defined(WIN32) + char *n = StrCol::dup(file); + if (n) { + MakeDosPath (n); + fstr = ::fopen(n, mode); + delete[] n; + } +#else + fstr = ::fopen(file, mode); +#endif + if (fstr == NULL) + printerror(err, "fopen", file); + return fstr; +} + +#ifdef WIN32 +bool SysCall::normalize(Filename filename, Filename &norm, ErrorSink *err) { + const char *name = filename.name(); + std::string result; + + assert(strlen(name) >= 2); + // first check for the end of the recursion: + if (strlen(name) == 2 && name[1] == ':' && isalpha(name[0])) { + result = toupper(name[0]); + result += ":"; + } else { + // normalize the directory part recursively ... + Filename norm_path; + if (!canonical(filename.path(), norm_path, err)) { + return false; + } + // .. and find the normlized filename with _findfirst + struct _finddata_t find_data; + long hdl = _findfirst(name, &find_data); + if (hdl == -1L) { + return false; + } + result = norm_path.name(); + result += "/"; + result += find_data.name; + _findclose(hdl); + } + norm.name(result.c_str()); + return true; +} +#endif // WIN32 + +typedef std::map FilenameMap; +typedef FilenameMap::value_type FilenameMapPair; +FilenameMap canonical_cache; + +bool SysCall::canonical(Filename filename, Filename &result, ErrorSink *err) { + // first check if the searched canonical name is already cached + FilenameMap::iterator fn = canonical_cache.find(filename.name()); + if (fn != canonical_cache.end()) { + result = fn->second; + return true; + } + + // build a canonical path name + const char *file_abs = filename.name(); + char file_buf[MAX_PATH]; + +#if defined (WIN32) + if ((strlen(file_abs) == 2 && file_abs[1] == ':' && isalpha(file_abs[0])) || + (file_abs = _fullpath(file_buf, file_abs, MAX_PATH))) { + Filename abs(file_abs); + if (!normalize(abs, result, err)) { + file_abs = 0; + } + } +#else + file_abs = realpath(file_abs, file_buf); + if (file_abs) { + result.name(file_abs); + } +#endif + + if (!file_abs) { + printerror(err, "canonical", filename.name()); + return false; + } + + canonical_cache.insert(FilenameMapPair(filename.name(), result)); + return true; +} + +char *SysCall::absolute(const char *filename, ErrorSink *err) { + char link_buf[4096]; + + char *link = SysCall::readlink(filename, link_buf, sizeof(link_buf), err); + + // no link return simple absolute path + if (!link) { + Filename result; + if (!SysCall::canonical(filename, result, err)) + return 0; + return StrCol::dup(result.name()); + } + + // an absolute link, resolve this file/link again + if (link[0] == '/') + return absolute(link, err); + + // relative name, concatenate directory with link and resolve + char name_buf[4096]; + strcpy(name_buf, filename); + char *delim = strrchr(name_buf, (int) '/'); + if (!delim) { + strcpy(name_buf, link); + } else { + *(delim + 1) = '\0'; + strcat(name_buf, link); + } + return absolute(name_buf, err); +} + +} // namespace Puma diff --git a/Puma/src/basics/SysCall.h b/Puma/src/basics/SysCall.h new file mode 100644 index 0000000..102d0bf --- /dev/null +++ b/Puma/src/basics/SysCall.h @@ -0,0 +1,269 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_SysCall_H +#define PUMA_SysCall_H + +/** \file + * Encapsulation of system dependent file system operations. */ + +// System includes +#include +#include +#include +#include +#include +#include +#ifdef _MSC_VER +#include +#else +#include +#endif // _MSVC + +// PUMA includes +#include "Puma/Filename.h" + +namespace Puma { + +class ErrorSink; +class SysCall; + +/** \class FileInfo SysCall.h Puma/SysCall.h + * File information. */ +class FileInfo { + friend class SysCall; +#ifndef _MSC_VER + struct stat info; +#else + struct _stat info; +#endif + +public: + /** Check if the file is a directory. + * \return True if it is a directory. */ + bool is_dir() const { +#ifdef _MSC_VER + return _S_IFDIR & info.st_mode; +#else + return S_ISDIR(info.st_mode); +#endif // _MSC_VER + } + /** Get the last modification time of the file. + * \return The last modification time. */ + time_t modi_time() const { + return info.st_mtime; + } + /** Get the size of the file. + * \return The file size. */ + int size() const { + return info.st_size; + } +}; + +#ifdef _MSC_VER +/** \cond internal */ +struct DIR { + long handle; + DIR(long h) : handle(h) {} +}; +/** \endcond */ +#endif // _MSC_VER + +/** Directory handle type. */ +typedef DIR *DirHandle; +/** File handle type. */ +typedef FILE *FileHandle; + +/** \enum DirEntryType SysCall.h Puma/SysCall.h + * Directory entry types. */ +enum DirEntryType { + /** Regular file. */ + DET_REGULAR, + /** Directory. */ + DET_DIRECTORY, + /** Symbolic link. */ + DET_LINK, + /** Other kind of directory entry. */ + DET_OTHER, + /** Not implemented directory entry type. */ + DET_NOT_IMPLEMENTED +}; + +/** \class SysCall SysCall.h Puma/SysCall.h + * Encapsulates system dependent file system operations. + * \ingroup basics */ +class SysCall { + static void printerror(ErrorSink *err, const char *cmd, const char *path = (const char *) 0); + static void printerror(ErrorSink *err, const char *cmd, int fd); + +public: + /** Create a temporary file name, needs to be freed by the caller. + * \param prefix The file name prefix. + * \param err Optional error reporting stream. */ + static const char* mktemp(const char *prefix, ErrorSink *err = (ErrorSink *) 0); + + /** Open a file in exclusive file locking mode. + * \param path The path to the file. + * \param flags The file open flags. + * \param err Optional error reporting stream. + * \return The file descriptor of the opened file. */ + static int open_excl(const char *path, int flags, ErrorSink *err = (ErrorSink *) 0); + /** Create and open a file in exclusive file locking mode. + * \param path The path to the file. + * \param mode The file creation mode. + * \param err Optional error reporting stream. + * \return The file descriptor of the opened file. */ + static int create_excl(const char *path, int mode, ErrorSink *err = (ErrorSink *) 0); + /** Close a file opened in exclusive file locking mode. + * \param fd The file descriptor of the file to close. + * \param err Optional error reporting stream. + * \return True if closing the file succeeded. */ + static bool close_excl(int fd, ErrorSink *err = (ErrorSink *) 0); + + /** Open a file in non-exclusive mode. + * \param path The path to the file. + * \param flags The file open flags. + * \param err Optional error reporting stream. + * \return The file descriptor of the opened file. */ + static int open(const char *path, int flags, ErrorSink *err = (ErrorSink *) 0); + /** Create and open a file in non-exclusive mode. + * \param path The path to the file. + * \param mode The file creation mode. + * \param err Optional error reporting stream. + * \return The file descriptor of the opened file. */ + static int create(const char *path, int mode, ErrorSink *err = (ErrorSink *) 0); + /** Close a file opened in non-exclusive mode. + * \param fd The file descriptor of the file to close. + * \param err Optional error reporting stream. + * \return True if closing the file succeeded. */ + static bool close(int fd, ErrorSink *err = (ErrorSink *) 0); + + /** Read n bytes from a file into the given buffer. + * \param fd The file descriptor of the file to read. + * \param buffer The buffer to fill with the bytes read. + * \param n The number of bytes to read. + * \param err Optional error reporting stream. + * \return The number of bytes read. */ + static long read(int fd, void *buffer, size_t n, ErrorSink *err = (ErrorSink *) 0); + + /** Get information about a file. + * \param path The path to the file. + * \param info The file information object to fill. + * \param err Optional error reporting stream. + * \return True if succeeded. */ + static bool stat(const char *path, FileInfo &info, ErrorSink *err = (ErrorSink *) 0); + /** Get information about a file. + * \param fd The file descriptor of the file. + * \param info The file information object to fill. + * \param err Optional error reporting stream. + * \return True if succeeded. */ + static bool fstat(int fd, FileInfo &info, ErrorSink *err = (ErrorSink *) 0); + /** Get the path to the file the given link points to. + * \param path The path to the link. + * \param buffer The buffer to fill with the result. + * \param len The size of the buffer. + * \param err Optional error reporting stream. + * \return The buffer containing the path to the linked file. */ + static char* readlink(const char *path, char *buffer, size_t len, ErrorSink *err = (ErrorSink *) 0); + + /** Open a file stream. + * \param path The path to the file to open. + * \param mode The file open mode. + * \param err Optional error reporting stream. + * \return A handle to the file stream. */ + static FileHandle fopen(const char *path, const char *mode, ErrorSink *err = (ErrorSink *) 0); + /** Close a file stream. + * \param fh The handle to the file stream. + * \param err Optional error reporting stream. + * \return True if succeeded. */ + static bool fclose(FileHandle fh, ErrorSink *err = (ErrorSink *) 0); + + /** Open a directory stream. + * \param path The path to the directory to open. + * \param err Optional error reporting stream. + * \return A handle to the directory stream. */ + static DirHandle opendir(const char *path, ErrorSink *err = (ErrorSink *) 0); + /** Close a directory stream. + * \param dh The handle to the directory stream. + * \param err Optional error reporting stream. + * \return True if succeeded. */ + static bool closedir(DirHandle dh, ErrorSink *err = (ErrorSink *) 0); + + // read from directory stream + // Pass a pointer to a DirEntryType object if you are interested whether the entry + // is a regular file, link, directory, or other. + static const char *readdir(DirHandle dh, DirEntryType *type = 0, ErrorSink *err = (ErrorSink *) 0); + + /** Change the current working directory. + * \param path The path to the new working directory. + * \param err Optional error reporting stream. + * \return True if succeeded. */ + static bool chdir(const char *path, ErrorSink *err = (ErrorSink *) 0); + + /** Create a directory. + * \param path The path to the new directory. + * \param err Optional error reporting stream. + * \return True if succeeded. */ + static bool mkdir(const char *path, ErrorSink *err = (ErrorSink *) 0); + + /** Get the current working directory. + * \param buffer A buffer to be filled with the path to the current working directory. + * \param len The size of the buffer. + * \param err Optional error reporting stream. + * \return The buffer containing the path to the current working directory. */ + static char *getcwd(char *buffer, size_t len, ErrorSink *err = (ErrorSink *) 0); + + /** Get the current time. + * \param buffer The buffer to be filled with the current time. + * \param err Optional error reporting stream. + * \return The current time, or -1 in case of error. */ + static time_t time(time_t *buffer, ErrorSink *err = (ErrorSink *) 0); + + /** Transform the given path into a Unix path by replacing all backslashes with slashes. + * \param path The path to transform. */ + static void MakeUnixPath(char *path); + /** Transform the given path into a MS-DOS path by replacing all slashes with backslashes. + * \param path The path to transform. */ + static void MakeDosPath(char *path); + +#ifdef WIN32 + /** Normalize an absolute Win32 filename of an existing file. + * \param filename The filename to normalize. + * \param result The resulting normalized filename. + * \param err Optional error reporting stream. + * \return True if succeeded. */ + static bool normalize(Filename filename, Filename &result, ErrorSink *err = 0); +#endif // WIN32 + + /** Get the canonical path name for an existing file. + * \param filename The filename of the file. + * \param result The resulting canonical path name. + * \param err Optional error reporting stream. + * \return True if succeeded. */ + static bool canonical(Filename filename, Filename &result, ErrorSink *err = 0); + + /** Get the absolute path name for an existing file. + * \param filename The filename of the file. + * \param err Optional error reporting stream. + * \return A newly allocated string containing the absolute path name. */ + static char *absolute(const char *filename, ErrorSink *err = (ErrorSink *) 0); +}; + +} // namespace Puma + +#endif /* PUMA_SysCall_H */ diff --git a/Puma/src/basics/TerminalSink.cc b/Puma/src/basics/TerminalSink.cc new file mode 100644 index 0000000..695fe1a --- /dev/null +++ b/Puma/src/basics/TerminalSink.cc @@ -0,0 +1,29 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 "Puma/TerminalSink.h" +#include + +namespace Puma { + +int TerminalSink::write(const char *buffer, int n) { + std::cout.write(buffer, n); + return n; +} + +} // namespace Puma diff --git a/Puma/src/basics/TerminalSink.h b/Puma/src/basics/TerminalSink.h new file mode 100644 index 0000000..127a549 --- /dev/null +++ b/Puma/src/basics/TerminalSink.h @@ -0,0 +1,44 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_TerminalSink_H +#define PUMA_TerminalSink_H + +/** \file + * Standard output to terminal sink. */ + +#include "Puma/Sink.h" + +namespace Puma { + +/** \class TerminalSink TerminalSink.h Puma/TerminalSink.h + * Terminal sink implementation. + * \warning This class is not used and may disappear without notice. + * \ingroup basics */ +class TerminalSink : public Sink { +public: + /** Write n bytes from the given buffer onto the terminal. + * \param buffer The bytes to write. + * \param n The number of bytes to write. + * \return The number of bytes written. */ + virtual int write(const char *buffer, int n); +}; + +} // namespace Puma + +#endif /* PUMA_TerminalSink_H */ diff --git a/Puma/src/basics/TokenSource.h b/Puma/src/basics/TokenSource.h new file mode 100644 index 0000000..e93b31d --- /dev/null +++ b/Puma/src/basics/TokenSource.h @@ -0,0 +1,45 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_TokenSource_H +#define PUMA_TokenSource_H + +/** \file + * Token source interface. */ + +namespace Puma { + +class Token; + +/** \class TokenSource TokenSource.h Puma/TokenSource.h + * Token source interface. To be implemented by all + * sources providing lexical tokens. + * \ingroup basics */ +class TokenSource { +public: + /** Destructor. */ + virtual ~TokenSource() { + } + /** Get the next token. + * \return The next token from the source, or NULL if no more tokens. */ + virtual Token *next() = 0; +}; + +} // namespace Puma + +#endif /* PUMA_TokenSource_H */ diff --git a/Puma/src/basics/VerboseMgr.cc b/Puma/src/basics/VerboseMgr.cc new file mode 100644 index 0000000..b205575 --- /dev/null +++ b/Puma/src/basics/VerboseMgr.cc @@ -0,0 +1,41 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 "Puma/VerboseMgr.h" +#include + +namespace Puma { + +void VerboseMgr::endl() { + *this << std::endl; + + if (m_level < m_verbose) { + for (int l = 0; l < m_level; l++) + m_out << " "; + if (m_level == 0) + m_out << "* "; + else if (m_level == 1) + m_out << "- "; + m_out << str().c_str(); + } + + std::ostringstream::str(""); + std::ostringstream::clear(); +} + +} // namespace Puma diff --git a/Puma/src/basics/VerboseMgr.h b/Puma/src/basics/VerboseMgr.h new file mode 100644 index 0000000..7fa5949 --- /dev/null +++ b/Puma/src/basics/VerboseMgr.h @@ -0,0 +1,87 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_VerboseMgr_H +#define PUMA_VerboseMgr_H + +/** \file + * Manager for verbose manager. */ + +#include +#include + +namespace Puma { + +/** \class VerboseMgr VerboseMgr.h Puma/VerboseMgr.h + * Indented output stream with a adjustable verbosity level. + * If the level reaches the verbosity level, all messages + * printed on the stream are ignored. Use the stream manipulator + * Puma::endvm to finish a message on the stream. + * \ingroup basics */ +class VerboseMgr : public std::ostringstream { + int m_level; + int m_verbose; + std::ostream &m_out; + +public: + /** Constructor. Default verbosity level is 10. + * \param out The destination output stream. */ + VerboseMgr(std::ostream &out) + : m_level(0), m_verbose(10), m_out(out) { + } + /** Construct a new verbosity manager. + * \param out The destination output stream. + * \param verbose The default verbosity level. */ + VerboseMgr(std::ostream &out, int verbose) + : m_level(0), m_verbose(verbose), m_out(out) { + } + /** Set the verbosity level. + * \param verbose The verbosity level. */ + void verbose(int verbose) { + m_verbose = verbose; + } + /** Get the verbosity level. + * \return The verbosity level. */ + int verbose() { + return m_verbose; + } + /** Increase the current level starting at 0. */ + void operator ++(int) { + m_level++; + } + /** Decrease the current level starting at 0. */ + void operator --(int) { + m_level--; + } + /** Finish the message and write it on the destination + * output stream if the verbosity level is not yet reached. */ + void endl(); +}; + +/** Finish a VerboseMgr message and write it on the destination + * output stream if the verbosity level is not yet reached. + * \param outs The VerboseMgr stream. + * \return A reference to the input VerboseMgr stream. */ +inline std::ostream &endvm(std::ostream &outs) { + ((VerboseMgr&) outs).endl(); + return outs; +} + +} // namespace Puma + +#endif /* PUMA_VerboseMgr_H */ diff --git a/Puma/src/basics/VoidPtrArray.cc b/Puma/src/basics/VoidPtrArray.cc new file mode 100644 index 0000000..f5eee25 --- /dev/null +++ b/Puma/src/basics/VoidPtrArray.cc @@ -0,0 +1,26 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 "Puma/VoidPtrArray.h" + +namespace Puma { + +const long VoidPtrArray::default_init_size = 5; +const long VoidPtrArray::default_increment = 5; + +} // namespace Puma diff --git a/Puma/src/basics/VoidPtrArray.h b/Puma/src/basics/VoidPtrArray.h new file mode 100644 index 0000000..fccad7f --- /dev/null +++ b/Puma/src/basics/VoidPtrArray.h @@ -0,0 +1,226 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_VoidPtrArray_H +#define PUMA_VoidPtrArray_H + +/** \file + * Array of void pointers. */ + +#include +#include +#include + +namespace Puma { + +/** \class VoidPtrArray VoidPtrArray.h Puma/VoidPtrArray.h + * Array implementation specialized for void pointers. + * \ingroup basics */ +class VoidPtrArray { + void** data; + long size; + long count; + long increment; + + void grow(long wanted); + +protected: + /** Default array size. */ + static const long default_init_size; + /** Default array size increment. */ + static const long default_increment; + +protected: + /** Constructor. + * \param is The default size of the array. + * \param incr The default increment value. */ + VoidPtrArray(long is = default_init_size, long incr = default_increment); + /** Copy-constructor. + * \param array The array to copy. */ + VoidPtrArray(const VoidPtrArray &array); + /** Assignment operator. + * \param array The array to copy. + * \return A reference to this array. */ + VoidPtrArray &operator =(const VoidPtrArray &array); + /** Destructor. Destroys the array. */ + ~VoidPtrArray(); + /** Append an item to the array. + * \param item The item to append. */ + void append(const void *item); + /** Insert an item at the given array index. + * \param index The array index. + * \param item The item to insert. */ + void insert(long index, const void *item); + /** Prepend an item. + * \param item The item to prepend. */ + void prepend(const void *item); + /** Remove the array item at the given array index. + * \param index The array index. */ + void remove(long index); + /** Reset the array. Destroys the current array. */ + void reset(); + /** Get a reference to the array item at the given + * array index. If the index exceeds the array + * bounds, then the array is reallocated accordingly. + * \param index The array index. + * \return A reference to the n-th array item. */ + void *&get(long index); + /** Get a reference to the array item at the given + * array index. If the index exceeds the array + * bounds, then the array is reallocated accordingly. + * \param index The array index. + * \return A reference to the n-th array item. */ + void *&operator[](long index); + /** Get the array item at the given array index. + * Does not return a reference, thus the item may + * be implicitely copied. + * \warning Does not validate the index! + * \param index The array index. + * \return The n-th array item. */ + void *fetch(long index) const; + /** Get a reference to the array item at the given + * array index. + * \warning Does not validate the index! + * \param index The array index. + * \return A reference to the n-th array item. */ + void *&lookup(long index) const; + /** Get the number of items in the array. + * \return The length of the array. */ + long length() const; +}; + +inline VoidPtrArray::VoidPtrArray(long is, long incr) { + count = 0; + size = 0; + increment = incr; + data = 0; +} + +inline VoidPtrArray::VoidPtrArray(const VoidPtrArray &array) { + count = array.count; + size = array.size; + increment = array.increment; + + if (size) { + data = (void**) ::malloc(size * sizeof(void*)); + ::memcpy(data, array.data, count * sizeof(void*)); + } else + data = 0; +} + +inline VoidPtrArray &VoidPtrArray::operator =(const VoidPtrArray &array) { + if (data) + ::free(data); + + count = array.count; + size = array.size; + increment = array.increment; + + if (size) { + data = (void**) ::malloc(size * sizeof(void*)); + ::memcpy(data, array.data, count * sizeof(void*)); + } else + data = 0; + + return *this; +} + +inline VoidPtrArray::~VoidPtrArray() { + if (data) + ::free(data); +} + +inline void VoidPtrArray::append(const void *item) { + if (count >= size) { + grow(count); + } + data[count++] = (void*) item; +} + +inline void VoidPtrArray::prepend(const void *item) { + insert(0, item); +} + +inline void VoidPtrArray::insert(long index, const void *item) { + if (count >= size) { + grow(count); + } + for (int pos = count; pos > index; pos--) + data[pos] = data[pos - 1]; + data[index] = (void*) item; + count++; +} + +inline void *&VoidPtrArray::get(long index) { + if (index >= size) { + grow(index); + } + if (index >= count) + count = index + 1; + return data[index]; +} + +inline void *&VoidPtrArray::operator[](long index) { + return get(index); +} + +inline void *VoidPtrArray::fetch(long index) const { + return data[index]; +} + +inline long VoidPtrArray::length() const { + return count; +} + +inline void VoidPtrArray::grow(long wanted) { + do { + size += increment; + increment *= 2; + } while (wanted >= size); + + if (data) + data = (void**) ::realloc(data, size * sizeof(void*)); + else + data = (void**) ::malloc(size * sizeof(void*)); +} + +inline void VoidPtrArray::remove(long index) { + if (index < count && count > 0) { + for (int pos = index; pos < count - 1; pos++) + data[pos] = data[pos + 1]; + count--; + } +} + +inline void VoidPtrArray::reset() { + count = 0; + if (data) + ::free(data); + size = 0; + data = 0; + increment = default_increment; +} + +inline void *&VoidPtrArray::lookup(long index) const { + assert(index >= 0 && index < count); + return data[index]; +} + +} // namespace Puma + +#endif /* PUMA_VoidPtrArray_H */ diff --git a/Puma/src/basics/WChar.cc b/Puma/src/basics/WChar.cc new file mode 100644 index 0000000..7e74ff5 --- /dev/null +++ b/Puma/src/basics/WChar.cc @@ -0,0 +1,32 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 + +#ifdef __APPLE__ +#include "Puma/WChar.h" + +namespace Puma { + +size_t wcslen(const wchar_t *s) { + const wchar_t *p = s; + while (*p++); + return p - s - 1; +} + +} // namespace Puma + +#endif /* __APPLE__ */ diff --git a/Puma/src/basics/WChar.h b/Puma/src/basics/WChar.h new file mode 100644 index 0000000..808651e --- /dev/null +++ b/Puma/src/basics/WChar.h @@ -0,0 +1,42 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_WChar_H +#define PUMA_WChar_H + +/** \file + * Wide character string support. */ + +#ifndef __APPLE__ +# include +#else /* __APPLE__ */ +# include + +namespace Puma { + +/** Get the length of a wide character string. + * \param s The string. + * \return The length of the string. + * \ingroup basics */ +size_t wcslen(const wchar_t *s); + +} // namespace Puma + +#endif /* __APPLE__ */ + +#endif /* PUMA_WChar_H */ diff --git a/Puma/src/basics/version.h b/Puma/src/basics/version.h new file mode 100644 index 0000000..2200eab --- /dev/null +++ b/Puma/src/basics/version.h @@ -0,0 +1,136 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 PUMA_version_H +#define PUMA_version_H + +/** \defgroup basics Basics + * Basic abstractions and utility classes. */ + +/** \defgroup common Common + * Common abstractions for source projects and parsing. */ + +/** \defgroup cpp Preprocessor + * Preprocessor implementation classes. */ + +/** \defgroup infos Semantic Information + * Semantic information classes. */ + +/** \defgroup types Type Information + * Type information classes. + * \ingroup infos */ + +/** \defgroup manip Transformation + * Source transformation classes. */ + +/** \defgroup parser Parsing + * Basic parsing classes. */ + +/** \defgroup cparser C Parsing + * C parsing classes. + * \ingroup parser */ + +/** \defgroup ccparser C++ Parsing + * C++ parsing classes. + * \ingroup parser */ + +/** \defgroup acparser AspectC++ Parsing + * AspectC++ parsing classes. + * \ingroup parser */ + +/** \defgroup instantiation Template Instantiation + * C++ template instantiation classes. + * \ingroup ccparser */ + +/** \defgroup scanner Scanning + * Lexical analysis classes. */ + +/** \file + * Library version information. + * \ingroup basics */ + +/** Library major version number. */ +#define PUMA_MAJOR_VERSION 1 +/** Library minor version number. */ +#define PUMA_MINOR_VERSION 5 + +/** \cond internal */ +#define __PUMA_STR(arg) #arg +#define __PUMA_VERSION(major,minor) __PUMA_STR(major) "." __PUMA_STR(minor) +/** \endcond */ + +/** Library version string. */ +#define PUMA_VERSION __PUMA_VERSION(PUMA_MAJOR_VERSION,PUMA_MINOR_VERSION) + +namespace Puma { + +/** Get the library version string in the format "major.minor". + * \return The version string. */ +static inline const char *puma_version() { return PUMA_VERSION; } + +} // namespace Puma + +/** \mainpage PUMA Library Reference Manual + * + * This is the class documentation of the PUMA library. PUMA is an extensible + * C/C++ source code analysis and transformation library written in C++. + * + * See [puma.aspectc.org](http://puma.aspectc.org) for more information. + * + * The main classes of the library are the following. + * + * ### Source directory, error, and configuration handling + * + * - Puma::ErrorStream - Error output stream + * - Puma::Config - Library configuration + * - Puma::Project - Source directory operations + * + * ### Lexical analysis + * + * - Puma::Lexer - Base class for language specific source code tokenizers + * - Puma::Token - Language token + * - Puma::Unit - Tokenized source file or code snippet + * + * ### Preprocessing + * + * - Puma::PreprocessorParser - The C preprocessor parser + * - Puma::PreTree - Base class for C preprocessor syntax tree nodes + * + * ### Syntactic analysis + * + * - Puma::Syntax - Base class for language specific syntax analyses + * - Puma::Builder - Base class for language specific syntax tree builders + * - Puma::CTree - Base class for syntax tree nodes for C, C++ and derived languages + * + * ### Semantic analysis + * + * - Puma::Semantic - Base class for language specific semantic analyses + * - Puma::CSemDatabase - Semantic information database + * + * ### Parsing (chaining of lexical, syntactic, and semantic analysis) + * + * - Puma::Parser - Base class for language specific parsers + * - Puma::CTranslationUnit - Translation unit for C, C++ and derived languages + * + * ### Transformation (source code manipulation) + * + * - Puma::CVisitor - Puma::CTree syntax tree visitor + * - Puma::ManipCommander - Token chain manipulation + */ + +#endif /* PUMA_version_H */ diff --git a/Puma/src/common/ConfOption.h b/Puma/src/common/ConfOption.h new file mode 100644 index 0000000..aaceceb --- /dev/null +++ b/Puma/src/common/ConfOption.h @@ -0,0 +1,135 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_ConfOption_H +#define PUMA_ConfOption_H + +/** \file + * Configuration option abstraction. */ + +#include "Puma/Array.h" +#include "Puma/StrCol.h" +#include + +namespace Puma { + +/** \class ConfOption ConfOption.h Puma/ConfOption.h + * Configuration option abstraction. A configuration option has + * a name and an optional list of arguments. System priority + * configuration options have a lower priority than non-system + * options. + * \ingroup common */ +class ConfOption { + const char *m_name; + unsigned int m_hash; + Array m_args; + bool m_system; + +public: + /** Constructor. + * \param option The full name of the option. + * \param system Has system priority or not. */ + ConfOption(const char *option, bool system = false); + /** Constructor. + * \param option The full name of the option. + * \param arg The argument value of the option. + * \param system Has system priority or not. */ + ConfOption(const char *option, const char *arg, bool system = false); + /** Constructor. + * \param option The full name of the option. + * \param arg1 The first argument value of the option. + * \param arg2 The second argument value of the option. + * \param system Has system priority or not. */ + ConfOption(const char *option, const char *arg1, const char *arg2, bool system = false); + /** Destroy this option. */ + ~ConfOption(); + + /** Check if the option is an system priority option. + * \return True if a system priority option. */ + bool isSystem() const; + + /** Get the name of the option. + * \return The full name of the option. */ + const char *Name() const; + /** Get the hash value of the option's name. + * Allows faster comparison when searching for this option. + * \return The hash value. */ + unsigned int Hash() const; + + /** Get the number of option arguments. + * \return The number of arguments. */ + unsigned Arguments() const; + /** Get the n-th option argument. + * \param n The index of the argument to get. + * \return The n-th argument. */ + const char *Argument(unsigned n) const; + /** Add a further option argument. + * \param arg The argument value. */ + void addArgument(const char *arg); +}; + +inline ConfOption::ConfOption(const char *n, bool system) : + m_args(1, 1), m_system(system) { + m_name = StrCol::dup(n); + m_hash = StrCol::hash(n); +} +inline ConfOption::ConfOption(const char *n, const char *a1, bool system) : + m_args(1, 1), m_system(system) { + m_name = StrCol::dup(n); + m_hash = StrCol::hash(n); + addArgument(a1); +} +inline ConfOption::ConfOption(const char *n, const char *a1, const char *a2, bool system) : + m_args(2, 1), m_system(system) { + m_name = StrCol::dup(n); + m_hash = StrCol::hash(n); + addArgument(a1); + addArgument(a2); +} + +inline ConfOption::~ConfOption() { + delete[] m_name; + for (unsigned i = 0; i < Arguments(); i++) + delete[] Argument(i); +} + +inline bool ConfOption::isSystem() const { + return m_system; +} +inline const char *ConfOption::Name() const { + return m_name; +} +inline unsigned int ConfOption::Hash() const { + return m_hash; +} +inline unsigned ConfOption::Arguments() const { + return m_args.length(); +} +inline const char *ConfOption::Argument(unsigned i) const { + return m_args.lookup(i); +} + +inline void ConfOption::addArgument(const char *arg) { + if (arg) { + m_args.append(StrCol::dup(arg)); + } +} + +} // namespace Puma + +#endif /* PUMA_ConfOption_H */ diff --git a/Puma/src/common/Config.cc b/Puma/src/common/Config.cc new file mode 100644 index 0000000..b9af574 --- /dev/null +++ b/Puma/src/common/Config.cc @@ -0,0 +1,595 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 "Puma/Config.h" +#include "Puma/SysCall.h" +#include "Puma/StrCol.h" +#include "Puma/OptsParser.h" +#include +#include +#include +#include +#include + +namespace Puma { + +// print error messages + +#define ERROR_CONFIG_FILE \ + m_err << sev_error << "in config file `" << file << "': " + +#define ERROR_COMMAND_LINE \ + m_err << sev_error << "at command line: " + +#define ERROR_MSG(__mesg) \ + m_err << __mesg << endMessage + +#define ERROR__missing(__name) \ + ERROR_COMMAND_LINE; \ + ERROR_MSG ("missing `" << __name << "' for `-A'") + +#define ERROR__empty(__what,__name) \ + ERROR_COMMAND_LINE; \ + ERROR_MSG ("no " << __what << " given for `" << __name << "'") + +unsigned int Config::OPT_I_HASH = StrCol::hash("-I"); +unsigned int Config::OPT_ISYSTEM_HASH = StrCol::hash("--isystem"); + +OptsParser::Option pumaOpts[] = { + {Config::PRE_ASSERT, "A", NULL, "Assert a preprocessor predicate", OptsParser::AT_MANDATORY}, + {Config::PRE_DEFINE, "D", NULL, "Define a preprocessor macro", OptsParser::AT_MANDATORY}, + {Config::PRE_UNDEFINE, "U", NULL, "Undefine a preprocessor macro", OptsParser::AT_MANDATORY}, + {Config::PRE_LOCK_MACRO, NULL, "lock-macro", "Define an immutable preprocessor macro", OptsParser::AT_MANDATORY}, + {Config::SET_OPTION_ARG, NULL, "inhibit-macro", "Add the name of a macro whose definition will be ignored", OptsParser::AT_MANDATORY}, + {Config::PRE_INCLUDE, "I", NULL, "Add a non-system include directory", OptsParser::AT_MANDATORY}, + {Config::PROJ_PATH, "p", "path", "Add a project source directory", OptsParser::AT_MANDATORY}, + {Config::PROJ_DESTINATION, "d", "dest", "Add a destination folder for modified sources", OptsParser::AT_MANDATORY}, + {Config::SET_SUFFIX, "s", "suffix", "Set the suffix for output files", OptsParser::AT_MANDATORY}, + {Config::SET_EXTENSION, "e", "extension", "Set the extension for source files", OptsParser::AT_MANDATORY}, + {Config::SET_WRITE_PROTECTED, "w", "write-protected", "Add a write protected project directory", OptsParser::AT_MANDATORY}, + {Config::CFG_FILE, NULL, "config", "Load configuration options from a file", OptsParser::AT_MANDATORY}, + {Config::SYS_CFG_FILE, NULL, "system-config", "Load low precedence configuration options from a file", OptsParser::AT_MANDATORY}, + {Config::SET_OPTION, NULL, "save-overwrite", "Overwrite existing files when saving", OptsParser::AT_NONE}, + {Config::SET_OPTION, NULL, "save-rename-old", "Rename existing files when saving", OptsParser::AT_NONE}, + {Config::SET_OPTION, NULL, "save-new-suffix", "Append new suffix on existing files when saving", OptsParser::AT_NONE}, + {Config::SET_OPTION, NULL, "lang-c", "Set input language to C", OptsParser::AT_NONE}, + {Config::SET_OPTION, NULL, "lang-ec++", "Set input language to EC++", OptsParser::AT_NONE}, + {Config::SET_OPTION, NULL, "lang-c++", "Set input language to C++", OptsParser::AT_NONE}, + {Config::SET_OPTION, NULL, "vc", "Enable Visual C++ extensions", OptsParser::AT_NONE}, + {Config::GNU, NULL, "gnu", "Enable GNU extensions", OptsParser::AT_OPTIONAL}, + {Config::SET_OPTION, NULL, "gnu-nested-fct", "Enable GNU nested functions extension", OptsParser::AT_NONE}, + {Config::SET_OPTION, NULL, "gnu-condition-scope", "Enable GNU condition scope extension", OptsParser::AT_NONE}, + {Config::SET_OPTION, NULL, "gnu-param-decl", "Enable GNU parameter declaration extension", OptsParser::AT_NONE}, + {Config::SET_OPTION, NULL, "gnu-fct-decl", "Enable GNU function declaration extension", OptsParser::AT_NONE}, + {Config::SET_OPTION, NULL, "gnu-param-scope", "Enable GNU parameter scope extension", OptsParser::AT_NONE}, + {Config::SET_OPTION, NULL, "gnu-default-args", "Enable GNU default arguments extension", OptsParser::AT_NONE}, + {Config::SET_OPTION, NULL, "gnu-extended-asm", "Enable GNU extended asm declaration extension", OptsParser::AT_NONE}, + {Config::SET_OPTION, NULL, "gnu-extended-expr", "Enable GNU extended expression extension", OptsParser::AT_NONE}, + {Config::SET_OPTION, NULL, "gnu-long-long", "Enable GNU type long long extension", OptsParser::AT_NONE}, + {Config::SET_OPTION, NULL, "gnu-int128", "Enable GNU type __int128 extension", OptsParser::AT_NONE}, + {Config::SET_OPTION, NULL, "gnu-name-scope", "Enable GNU name scope extension", OptsParser::AT_NONE}, + {Config::SET_OPTION, NULL, "gnu-implicit-int", "Enable GNU implicit int extension", OptsParser::AT_NONE}, + {Config::SET_OPTION, NULL, "gnu-fct-attribute", "Enable GNU function attributes extension", OptsParser::AT_NONE}, + {Config::SET_OPTION, NULL, "gnu-if-then-expr", "Enable GNU if-then expression extension", OptsParser::AT_NONE}, + {Config::SET_OPTION, NULL, "gnu-std-hack", "Enable GNU std namespace extension", OptsParser::AT_NONE}, + {Config::SET_OPTION, NULL, "gnu-friend-injection", "Enable GNU friend injection extension", OptsParser::AT_NONE}, + {Config::SET_OPTION, NULL, "gnu-pic24", "Enable GNU PIC24 and dsPIC extension", OptsParser::AT_NONE}, + {Config::SET_OPTION, NULL, "builtin-type-traits", "Enable built-in type traits", OptsParser::AT_NONE}, + {Config::SET_OPTION, NULL, "c++1x", "Enable C++1X extensions", OptsParser::AT_OPTIONAL}, + {Config::SET_OPTION, NULL, "c++1x-static-assert", "Enable C++1X static assertions", OptsParser::AT_NONE}, + {Config::SET_OPTION, NULL, "skip-bodies-all", "Skip parsing function bodies", OptsParser::AT_NONE}, + {Config::SET_OPTION, NULL, "skip-bodies-tpl", "Skip parsing function bodies of templates", OptsParser::AT_NONE}, + {Config::SET_OPTION, NULL, "skip-bodies-non-prj", "Skip parsing non-project function bodies", OptsParser::AT_NONE}, + {Config::SET_OPTION, NULL, "skip-bodies-non-prim", "Skip parsing function bodies in non-primary files", OptsParser::AT_NONE}, + {Config::SET_OPTION, NULL, "real-instances", "Enable template instantiation", OptsParser::AT_NONE}, + {Config::SET_OPTION, NULL, "pseudo-instances", "Simplified template instantiation scheme (deprecated)", OptsParser::AT_NONE}, + {Config::SET_OPTION, NULL, "inst-fct-bodies", "Enable function template body instantiation", OptsParser::AT_NONE}, + {Config::SET_OPTION_ARG, NULL, "template-depth", "Set the maximum instantiation depth for templates", OptsParser::AT_MANDATORY}, + {Config::SET_OPTION, NULL, "verbose-errors", "Enable verbose error messages", OptsParser::AT_NONE}, + {Config::SET_OPTION, NULL, "match-expr", "Enable parsing match expressions", OptsParser::AT_NONE}, + {Config::SET_OPTION_ARG, NULL, "import-handler", "Set handler for Visual C++ #import directives", OptsParser::AT_MANDATORY}, + {Config::SET_OPTION_ARG, NULL, "include", "Add file to be included at the beginning of every source file", OptsParser::AT_MANDATORY}, + {Config::SET_OPTION_ARG, NULL, "size-type", "Set type for size_t", OptsParser::AT_MANDATORY}, + {Config::SET_OPTION_ARG, NULL, "ptrdiff-type", "Set type for ptrdiff_t", OptsParser::AT_MANDATORY}, + {Config::SET_OPTION_ARG, NULL, "target", "Set target triple, which determines sizes and alignments for built-in types", OptsParser::AT_MANDATORY}, + {Config::SET_OPTION_ARG, NULL, "isystem", "Add a system include directory", OptsParser::AT_MANDATORY}, + {0, 0, 0, 0, OptsParser::AT_NONE} +}; + +// print the options +void Config::PrintOptions(std::ostream& os) const { + // first print short options with description + for (int i = 0; pumaOpts[i].number > 0; i++) { + if (pumaOpts[i].shortName && pumaOpts[i].desc && strlen(pumaOpts[i].desc)) { + PrintOption(pumaOpts[i], os); + } + } + // then print long options with description + for (int i = 0; pumaOpts[i].number > 0; i++) { + if (!pumaOpts[i].shortName && pumaOpts[i].desc && strlen(pumaOpts[i].desc)) { + PrintOption(pumaOpts[i], os); + } + } + // then print options without description + for (int i = 0; pumaOpts[i].number > 0; i++) { + if (!pumaOpts[i].desc || strlen(pumaOpts[i].desc) == 0) { + PrintOption(pumaOpts[i], os); + } + } +} + +// print a single option +void Config::PrintOption(OptsParser::Option& o, std::ostream& os) const { + if (o.shortName) { + os << " -" << o.shortName; + } + if (o.longName) { + if (o.shortName) { + os << "|"; + } else { + os << " "; + } + os << "--" << o.longName; + } + if (o.argType == OptsParser::AT_MANDATORY) { + os << " "; + } + if (o.argType == OptsParser::AT_OPTIONAL) { + os << " [ARG]"; + } + if (o.desc) { + os << "\033[35G" << o.desc; + } + os << std::endl; +} + +Config::~Config() { + OptionList::iterator idx = m_sysopts.begin(); + for (; idx != m_sysopts.end(); ++idx) { + delete *idx; + } + for (idx = m_useropts.begin(); idx != m_useropts.end(); ++idx) { + delete *idx; + } + for (idx = m_sysincls.begin(); idx != m_sysincls.end(); ++idx) { + delete *idx; + } +} + +void Config::Add(const ConfOption *o) { + m_optnamemap[o->Hash()] = o; + if (o->isSystem()) { + if (o->Hash() == OPT_I_HASH || o->Hash() == OPT_ISYSTEM_HASH) + m_sysincls.push_back(o); + else + m_sysopts.push_back(o); + } else { + m_useropts.push_back(o); + } +} + +unsigned Config::Options() const { + return m_sysopts.size() + m_useropts.size() + m_sysincls.size(); +} + +const ConfOption *Config::Option(unsigned i) const { + OptionList::size_type s = m_sysopts.size(); + if (i < s) + return m_sysopts[i]; + i -= s; + s = m_useropts.size(); + if (i < s) + return m_useropts[i]; + i -= s; + s = m_sysincls.size(); + if (i < s) + return m_sysincls[i]; + return 0; +} + +void Config::Read(const char *file) { + // file not given, read from $PUMA_CONFIG or /etc/puma.config + bool default_loc = false; + if (!file) + file = getenv("PUMA_CONFIG"); + if (!file) { + file = "/etc/puma.config"; // default location + default_loc = true; + } + + std::ifstream in(file); + if (!in) { + if (!default_loc) { + ERROR_MSG("cannot open config file `" << file << "'"); + } + return; + } + + std::ostringstream optstr; + std::string line; + while (!in.eof()) { + std::getline(in, line); + // skip comments and empty lines + if (!line.empty() && line[0] != '#') { + optstr << " " << StrCol::replaceEnvironmentVariables(line); + } + } + in.close(); + + OptsParser optp(optstr.str(), pumaOpts); + + // process the given options + while (optp.getOption() != OptsParser::FINISH) { + Process(optp, true); + } +} + +// read options from command line +void Config::Read(int &argc, char **&argv) { + OptsParser optp(argc, argv, pumaOpts); + char** newargv = new char*[argc]; + int newargc = 1; + + // process the given options + while (optp.getOption() != OptsParser::FINISH) { + if (Process(optp) == false) { + // this is not processed by PUMA - copy + newargv[newargc++] = argv[optp.getCurrentArgNum()]; + } + } + + // make argv point to new argv and set argc to value of new argc + argc = newargc; + for (int i = 1; i < argc; i++) + argv[i] = newargv[i]; + delete[] newargv; +} + +// check if a config file is given on command line +bool Config::CustomConfigFile(int argc, char **argv) { + OptsParser optp(argc, argv, pumaOpts); + while (optp.getOption() != OptsParser::FINISH) + if (optp.getResult() == CFG_FILE) + return true; + return false; +} + +// check if a system config file is given on command line +// for lower priority options +bool Config::CustomSystemConfigFile(int argc, char **argv) { + OptsParser optp(argc, argv, pumaOpts); + while (optp.getOption() != OptsParser::FINISH) + if (optp.getResult() == SYS_CFG_FILE) + return true; + return false; +} + +bool Config::Process(OptsParser &parser, bool unescape) { + bool res = true; + std::string arg = parser.getArgument(); + if (!arg.empty() && unescape) + arg = Unescape(arg); + + switch (parser.getResult()) { + case PRE_ASSERT: + ProcessAssert(arg); + break; + case PRE_DEFINE: + ProcessDefine(arg); + break; + case PRE_LOCK_MACRO: + ProcessLockMacro(arg); + break; + case PRE_UNDEFINE: + ProcessUndefine(arg); + break; + case PRE_INCLUDE: + ProcessPathArgument("-I", arg); + break; + case PROJ_PATH: + ProcessPathArgument("-p", arg); + break; + case PROJ_DESTINATION: + ProcessPathArgument("-d", arg); + break; + case CFG_FILE: + ProcessConfigFile("--config", arg); + break; + case SYS_CFG_FILE: + ProcessSystemConfigFile("--system-config", arg); + break; + case SET_SUFFIX: + ProcessArgument("-s", arg); + break; + case SET_EXTENSION: + ProcessArgument("-e", arg); + break; + case SET_WRITE_PROTECTED: + ProcessArgument("-w", arg); + break; + case GNU: + ProcessOptionalArgument("--gnu", arg); + break; + case SET_OPTION: + Add(parser.getOptionName().c_str(), m_system); + break; + case SET_OPTION_ARG: + Add(parser.getOptionName().c_str(), arg.c_str(), m_system); + break; + case OptsParser::UNKNOWN: + case OptsParser::NOOPTION: + res = false; + break; + default: + case OptsParser::ERR: + break; + } + return res; +} + +bool Config::ProcessConfigFile(const std::string &opt, const std::string &arg) { + bool res = false; + + if (arg.empty() == false) { + Read(arg.c_str()); + res = true; + } else { + ERROR__empty("file name", opt.c_str()); + } + + return res; +} + +bool Config::ProcessSystemConfigFile(const std::string &opt, const std::string &arg) { + bool res = false; + bool system_old = m_system; + + m_system = true; + + if (arg.empty() == false) { + Read(arg.c_str()); + res = true; + } else { + ERROR__empty("file name", opt.c_str()); + } + + m_system = system_old; + + return res; +} + +bool Config::ProcessArgument(const std::string &opt, const std::string &arg) { + bool res = false; + + if (arg.empty() == false) { + Add(opt.c_str(), arg.c_str(), m_system); + res = true; + } else { + ERROR__empty("argument", opt.c_str()); + } + return res; +} + +bool Config::ProcessOptionalArgument(const std::string &opt, const std::string &arg) { + if (arg.empty()) { + Add(opt.c_str(), m_system); + } else { + Add(opt.c_str(), arg.c_str(), m_system); + } + return true; +} + +bool Config::ProcessPathArgument(const std::string &opt, const std::string &arg) { + bool res = false; + + if (arg.empty() == false) { +#if defined (WIN32) + char *tmp = StrCol::dup(arg.c_str()); + if (tmp != 0) { + SysCall::MakeUnixPath(tmp); + Add(opt.c_str(), tmp, m_system); + delete[] tmp; + } +#else + Add(opt.c_str(), arg.c_str(), m_system); + res = true; +#endif + } else { + ERROR__empty("argument", opt.c_str()); + } + + return res; +} + +bool Config::ProcessUndefine(const std::string &arg) { + bool res = false; + + if (Valid(arg.c_str())) { + Add("-U", arg.c_str(), m_system); + res = true; + } else { + ERROR_MSG("invalid name for -U"); + } + + return res; +} + +bool Config::ProcessDefine(const std::string &arg) { + bool res = false; + std::string::size_type pos; + std::string name, body; + + if ((pos = arg.find_first_of('=', 0)) != std::string::npos) { + body = arg.substr(pos + 1, arg.length() - pos); + name = arg.substr(0, pos); + } else { + body = "1"; + name = arg; + } + + if (Valid(name.c_str())) { + Add("-D", name.c_str(), body.c_str(), m_system); + res = true; + } else { + ERROR_MSG("invalid name for -D"); + } + + return res; +} + +bool Config::ProcessLockMacro(const std::string &arg) { + bool res = false; + std::string::size_type pos; + std::string name, body; + + if ((pos = arg.find_first_of('=', 0)) != std::string::npos) { + body = arg.substr(pos + 1, arg.length() - pos); + name = arg.substr(0, pos); + } else { + body = "1"; + name = arg; + } + + if (Valid(name.c_str())) { + Add("--lock-macro", name.c_str(), body.c_str(), m_system); + res = true; + } else { + ERROR_MSG("invalid name for --lock-macro"); + } + + return res; +} + +bool Config::ProcessAssert(const std::string &arg) { + bool res = false; + std::string::size_type pos, end; + std::string name, body; + + if ((pos = arg.find_first_of('(', 0)) != std::string::npos) { + if ((end = arg.find_first_of(')', pos)) != std::string::npos) { + name = arg.substr(0, pos); + body = arg.substr(pos + 1, end - pos - 1); + if (StrCol::onlySpaces(body.c_str()) == false) { + if (Valid(name.c_str())) { + Add("-A", name.c_str(), body.c_str(), m_system); + res = true; + } else { + ERROR_MSG("invalid name for -A"); + } + } else { + ERROR__empty("answer text", "-A"); + } + } else { + ERROR__missing(")"); + } + } else { + ERROR__missing("("); + } + + return res; +} + +bool Config::Valid(const char *name, const char *file) const { + if (name) { + const char *reject = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$0123456789"; + if (strlen(name) && !strcspn(name, reject) && !(*name >= '0' && *name <= '9')) + return true; + } + if (file) + ERROR_CONFIG_FILE; + else + ERROR_COMMAND_LINE; + ERROR_MSG("`" << name << "' is not a valid C identifier"); + return false; +} + +void Config::Join(const Config &c) { + unsigned num = c.Options(); + for (unsigned i = 0; i < num; i++) + Add(c.Option(i)); +} + +const ConfOption *Config::Option(const char *name) const { + const ConfOption* co = 0; + if (name) { + OptionMap::const_iterator idx = m_optnamemap.find(StrCol::hash(name)); + if (idx != m_optnamemap.end()) { + co = idx->second; + } + } + return co; +} + +std::string Config::Unescape(const std::string& arg) { + // Replacement rules: + // 1. '\' '"' => '"' + // 2. '\' '\' => '\' + // 3. '"' => '' + std::ostringstream res; + bool escaped = false; + for (std::string::size_type i = 0; i < arg.length(); i++) { + char c = arg[i]; + if (c == '"') { + if (escaped) { + escaped = false; + res << c; + } + } else if (c == '\\') { + if (escaped) { + escaped = false; + res << c; + } else { + escaped = true; + } + } else { + if (escaped) { + escaped = false; + res << "\\"; + } + res << c; + } + } + return res.str(); +} + +void Config::Remove(const ConfOption *o) { + if (o->isSystem()) { + if (o->Hash() == OPT_I_HASH || o->Hash() == OPT_ISYSTEM_HASH) + Remove(o, m_sysincls); + else + Remove(o, m_sysopts); + } else { + Remove(o, m_useropts); + } + + OptionMap::iterator idx = m_optnamemap.find(o->Hash()); + if (idx != m_optnamemap.end() && idx->second == o) { + m_optnamemap.erase(idx); + } + + delete o; +} + +void Config::Remove(const ConfOption *o, OptionList& options) { + OptionList::iterator idx = std::find(options.begin(), options.end(), o); + if (idx != options.end()) { + options.erase(idx); + } +} + +} // namespace Puma diff --git a/Puma/src/common/Config.h b/Puma/src/common/Config.h new file mode 100644 index 0000000..107dd7d --- /dev/null +++ b/Puma/src/common/Config.h @@ -0,0 +1,381 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_Config_H +#define PUMA_Config_H + +/** \file + * Configuration information from file or command line. */ + +/** \page configuration Configuration Options + * + * Several aspects of the functionality of PUMA can be configured using command line + * options or a configuration file. The following configuration options are understood + * by the library. + * + * ### File Handling Options + * + * | Option | Description + * |----------------------|----------------------- + * | -p, --path PATH | Add a project source directory + * | -d, --dest PATH | Add a destination folder for modified sources + * | -w, --write-protected PATH | Add a write protected project directory + * | -e, --extension STRING | Set the extension for source files + * | -s, --suffix STRING | Set the suffix for output files + * | --config FILE | Load configuration options from a file + * | --system-config FILE | Load low precedence configuration options from a file + * | --save-new-suffix | Append new suffix on existing files when saving + * | --save-overwrite | Overwrite existing files when saving + * | --save-rename-old | Rename existing files when saving + * + * ### Preprocessor Options + * + * | Option | Description + * |----------------------|----------------------- + * | -A PREDICATE(ANSWER) | Assert a preprocessor predicate, e.g. -Asystem(linux) + * | -D NAME[=BODY] | Define a preprocessor macro, e.g. -DSYSTEM=linux or -D DEBUG + * | -U NAME | Undefine a preprocessor macro, e.g. -U SYSTEM + * | -I PATH | Add a non-system include directory + * | --isystem PATH | Add a system include directory + * | --include FILE | Include the given file at the beginning of each source file + * | --lock-macro NAME[=BODY] | Define an immutable preprocessor macro + * | --inhibit-macro NAME | Add the name of a macro whose definition will be ignored + * + * ### General %Parser Options + * + * | Option | Description + * |----------------------|----------------------- + * | --lang-c | Set input language to C + * | --lang-ec++ | Set input language to Embedded C++ + * | --lang-c++ | Set input language to C++ + * | --size-type TYPE | Set the internal type for size_t + * | --ptrdiff-type TYPE | Set the internal type for ptrdiff_t + * | --target TRIPLE | Set target triple which determines sizes and alignments for built-in types + * | --builtin-type-traits | Enable built-in type traits + * | --verbose-errors | Enable verbose error messages + * | --match-expr | Enable match expression language extensions + * + * ### Extended %Parser Options + * + * | Option | Description + * |----------------------|----------------------- + * | --skip-bodies-all | Don't parse function bodies + * | --skip-bodies-tpl | Don't parse function bodies of templates + * | --skip-bodies-non-prj | Don't parse function bodies in non-project files + * | --skip-bodies-non-prim | Don't parse function bodies in non-primary files + * | --pseudo-instances | Simplified template instantiation scheme (deprecated) + * | --inst-fct-bodies | Enable function template body instantiation + * | --template-depth DEPTH | Set the maximum instantiation depth for templates + * + * ### VisualC++ Extension Options + * + * | Option | Description + * |----------------------|----------------------- + * | --vc | Enable VisualC++ language extensions + * | --import-handler FILE | Set a handler for resolving \#import directives + * + * ### GNU C/C++ Extension Options + * + * | Option | Description + * |----------------------|----------------------- + * | --gnu [VERSION] | Enable all GNU C/C++ language extensions (optionally version dependent) + * | --gnu-nested-fct | Enable GNU C/C++ nested functions + * | --gnu-condition-scope | Enable GNU C/C++ condition scope + * | --gnu-param-decl | Enable GNU C/C++ parameter declarator + * | --gnu-fct-decl | Enable GNU C/C++ function declarator + * | --gnu-param-scope | Enable GNU C/C++ function parameter scope + * | --gnu-default-args | Enable GNU C/C++ function default arguments + * | --gnu-extended-asm | Enable GNU C/C++ extended asm syntax + * | --gnu-extended-expr | Enable GNU C/C++ extended expressions + * | --gnu-long-long | Enable GNU C/C++ long long type + * | --gnu-int128 | Enable GNU type __int128 extension + * | --gnu-name-scope | Enable GNU C/C++ name scope + * | --gnu-implicit-int | Enable GNU implicit int extension + * | --gnu-fct-attribute | Enable GNU C/C++ function attributes + * | --gnu-if-then-expr | Enable GNU C/C++ if-then expression syntax + * | --gnu-std-hack | Enable GNU C/C++ implicit namespace std hack + * | --gnu-friend-injection | Enable GNU friend injection extension + * | --gnu-pic24 | Enable GNU PIC24 and dsPIC extension + * + * ### C++1x Extension Options + * + * | Option | Description + * |----------------------|----------------------- + * | --c++1x | Enable all C++1x language extensions + * | --c++1x-static-assert | Enable C++1x static assertions + * + * ### Configuration Files + * + * All command line options can also be specified in a configuration file. + * Each option in the configuration file has to start on a new line. + * + * \code{.py} + * -D i386 + * -D linux + * -I /usr/include + * \endcode + * + * Lines beginning with # are interpreted as comments and will be ignored. + * + * \code{.py} + * ### defines + * -D i386 + * -D linux + * ### includes + * -I /usr/include + * -I /usr/local/include + * \endcode + * + * Arguments of options containing spaces have to be enclosed in double-quotes. + * Double-quotes in the argument have to be escaped. + * + * \code{.py} + * -D __PTRDIFF_TYPE__=int + * -D "__SIZE_TYPE__=unsigned int" + * -D "__VERSION__=\"4.1.0 (Linux)\"" + * \endcode + * + * All occurrences of ${Name} in the configuration file are interpreted as environment + * variables and replaced by their values, or by nothing if the variable is not defined. + * To avoid variable replacement, $ has to be escaped. + * + * \code{.py} + * -I ${LIBDIR}/include + * -D OS_STR=\"${OSTYPE}\" + * ### same as: #define OS_STR "linux" + * -D OS_VAR=\"\${OSTYPE}\" + * ### same as: #define OS_VAR "${OSTYPE}" + * \endcode + * + * The default PUMA configuration file location is /etc/puma.config. It can be overwritten + * by setting the environment variable PUMA_CONFIG like this: + * + * \code{.py} + * export PUMA_CONFIG=/usr/local/lib/Puma/puma.config + * \endcode + * + * Use class Puma::Config to load the configuration in the correct order from the + * command line or a configuration file. + */ + +#include "Puma/ConfOption.h" +#include "Puma/ErrorStream.h" +#include "Puma/OptsParser.h" +#include "Puma/StrCol.h" +#include +#include +#include +#include + +namespace Puma { + +/** \class Config Config.h Puma/Config.h + * Load and hold PUMA configuration options in the correct order + * from the command line or a configuration file. + * \ingroup common */ +class Config { + typedef std::vector OptionList; + typedef std::map OptionMap; + + ErrorStream &m_err; + OptionList m_sysopts; + OptionList m_useropts; + OptionList m_sysincls; + OptionMap m_optnamemap; + bool m_system; + + static unsigned int OPT_I_HASH; + static unsigned int OPT_ISYSTEM_HASH; + +public: + /** Configuration option types. */ + enum OPTIONS { + /** \cond internal */ + PRE_ASSERT = 1, + PRE_DEFINE, + PRE_UNDEFINE, + PRE_LOCK_MACRO, + PRE_INCLUDE, + CFG_FILE, + SYS_CFG_FILE, + PROJ_PATH, + PROJ_DESTINATION, + SET_SUFFIX, + SET_EXTENSION, + SET_WRITE_PROTECTED, + GNU, + /** \endcond */ + /** Option without argument. */ + SET_OPTION, + /** Option with argument. */ + SET_OPTION_ARG + }; + +public: + /** Constructor. + * \param err The error stream to use. */ + Config(ErrorStream &err); + /** Constructor. Read the given configuration file. See Read() + * for details. + * \param err The error stream to use. + * \param path Path to the configuration file, or NULL. */ + Config(ErrorStream &err, const char *path); + /** Constructor. Read configuration options from the command + * line. See Read() for details. + * \param err The error stream to use. + * \param argc The number of command line arguments. + * \param argv The command line arguments. */ + Config(ErrorStream &err, int &argc, char **&argv); + /** Constructor. Read the configuration from a configuration + * file and the command line. See Read() for details. + * \param err The error stream to use. + * \param path Path to the configuration file, or NULL. + * \param argc The number of command line arguments. + * \param argv The command line arguments. */ + Config(ErrorStream &err, const char *path, int &argc, char **&argv); + /** Copy-constructor. + * \param copy The configuration to copy. */ + Config(const Config ©); + /** Destroy this configuration object. */ + ~Config(); + + /** Join this configuration with another. + * \param other The configuration to join with. */ + void Join(const Config &other); + + /** Read the given configuration file, or the file given in + * PUMA_CONFIG environment variable if path is NULL, or + * /etc/puma.config otherwise. + * \param path The path to the configuration file, or NULL. */ + void Read(const char *path = (const char *) 0); + /** Read configuration options from the command line and remove + * all recognized options from the command line. + * \param argc The number of command line arguments. + * \param argv The command line arguments. */ + void Read(int &argc, char **&argv); + + /** Add a configuration option to the configuration. + * \param option The option to add. */ + void Add(const ConfOption *option); + /** Add a configuration option to the configuration. + * \param option The option to add. + * \param system True if this option shall be added as a system priority option. */ + void Add(const char *option, bool system = false); + /** Add a configuration option to the configuration. + * \param option The option to add. + * \param arg The argument or the option. + * \param system True if this option shall be added as a system priority option. */ + void Add(const char *option, const char *arg, bool system = false); + /** Add a configuration option to the configuration. + * \param option The option to add. + * \param arg1 The first argument or the option. + * \param arg2 The second argument or the option. + * \param system True if this option shall be added as a system priority option. */ + void Add(const char *option, const char *arg1, const char *arg2, bool system = false); + + /** Remove an option from the configuration. + * \param option The option to remove. */ + void Remove(const ConfOption *option); + + /** Get the number options collected. + * \return The number of options in this configuration. */ + unsigned Options() const; + /** Get the n-th option in this configuration. + * \param n The index of the option to get. + * \return A pointer to the option. */ + const ConfOption *Option(unsigned n) const; + /** Get a specific option in this configuration. + * \param option The name of the option to get. + * \return A pointer to the option. */ + const ConfOption *Option(const char *option) const; + + /** Check if a configuration file is given on the command line. + * \param argc The number of command line arguments. + * \param argv The command line arguments. + * \return True if a custom configuration file is given on the command line. */ + bool CustomConfigFile(int argc, char **argv); + + /** Check if a system configuration file (lower priority options) is given + * on the command line. + * \param argc The number of command line arguments. + * \param argv The command line arguments. + * \return True if a system custom configuration file is given on the command line. */ + bool CustomSystemConfigFile(int argc, char **argv); + + /** Print the given option on an output stream. + * \param option The option to print. + * \param os The output stream. */ + void PrintOption(OptsParser::Option& option, std::ostream& os) const; + /** Print the collected options on the given output stream. + * \param os The output stream. */ + void PrintOptions(std::ostream& os) const; + +private: + bool Valid(const char *, const char * = (const char *) 0) const; + + bool Process(OptsParser&, bool unescape = false); + bool ProcessAssert(const std::string&); + bool ProcessDefine(const std::string&); + bool ProcessLockMacro(const std::string&); + bool ProcessUndefine(const std::string&); + bool ProcessConfigFile(const std::string&, const std::string&); + bool ProcessSystemConfigFile(const std::string&, const std::string&); + bool ProcessArgument(const std::string&, const std::string&); + bool ProcessOptionalArgument(const std::string&, const std::string&); + bool ProcessPathArgument(const std::string&, const std::string&); + + std::string Unescape(const std::string&); + + void Remove(const ConfOption *, OptionList& options); +}; + +inline Config::Config(ErrorStream &e) : + m_err(e), m_system(false) { +} +inline Config::Config(const Config &c) : + m_err(c.m_err), m_system(false) { + Join(c); +} + +inline Config::Config(ErrorStream &e, const char *file) : + m_err(e), m_system(false) { + Read(file); +} +inline Config::Config(ErrorStream &e, int &argc, char **&argv) : + m_err(e), m_system(false) { + Read(argc, argv); +} +inline Config::Config(ErrorStream &e, const char *file, int &argc, char **&argv) : + m_err(e), m_system(false) { + Read(file); + Read(argc, argv); +} + +inline void Config::Add(const char *n, bool system) { + Add(new ConfOption(n, system)); +} +inline void Config::Add(const char *n, const char *a1, bool system) { + Add(new ConfOption(n, a1, system)); +} +inline void Config::Add(const char *n, const char *a1, const char *a2, bool system) { + Add(new ConfOption(n, a1, a2, system)); +} + +} // namespace Puma + +#endif /* PUMA_Config_H */ diff --git a/Puma/src/common/ErrorCollector.cc b/Puma/src/common/ErrorCollector.cc new file mode 100644 index 0000000..b2a13dd --- /dev/null +++ b/Puma/src/common/ErrorCollector.cc @@ -0,0 +1,168 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 "Puma/ErrorCollector.h" +#include + +namespace Puma { + +ErrorCollector::Message::Message(const ErrorSeverity &s, Location l, const char *m) : + m_severity(s), m_location(l), m_haveLocation(true) { + m_message = new char[strlen(m) + 1]; + strcpy(m_message, m); +} + +ErrorCollector::Message::Message(const ErrorSeverity &s, const char *m) : + m_severity(s), m_haveLocation(false) { + m_message = new char[strlen(m) + 1]; + strcpy(m_message, m); +} + +ErrorCollector::Message::~Message() { + delete[] m_message; +} + +bool ErrorCollector::Message::operator ==(const Message& msg) const { + if (m_haveLocation != msg.m_haveLocation) + return false; + if (m_haveLocation) + if (m_location != msg.m_location) + return false; + if (m_severity != msg.m_severity) + return false; + if (strcmp(m_message, msg.m_message) != 0) + return false; + return true; +} + +void ErrorCollector::Message::print(ErrorSink &e) { + if (m_haveLocation) + e << m_location; + e << m_severity << m_message << Puma::endMessage; +} + +ErrorCollector& ErrorCollector::operator <<(const char *v) { + m_msg << v; + return *this; +} + +ErrorCollector& ErrorCollector::operator <<(long v) { + m_msg << v; + return *this; +} + +ErrorCollector& ErrorCollector::operator <<(unsigned v) { + m_msg << v; + return *this; +} + +ErrorCollector& ErrorCollector::operator <<(int v) { + m_msg << v; + return *this; +} + +ErrorCollector& ErrorCollector::operator <<(short v) { + m_msg << v; + return *this; +} + +ErrorCollector& ErrorCollector::operator <<(char v) { + m_msg << v; + return *this; +} + +ErrorCollector& ErrorCollector::operator <<(double v) { + m_msg << v; + return *this; +} + +ErrorCollector& ErrorCollector::operator <<(const ErrorSeverity& sev) { + if (m_severity < sev) + m_severity = sev; + return *this; +} + +ErrorCollector& ErrorCollector::operator <<(Location v) { + m_location = v; + m_haveLocation = true; + return *this; +} + +ErrorCollector& ErrorCollector::operator <<(const Printable& v) { + m_msg << v; + return *this; +} + +ErrorCollector& ErrorCollector::operator <<(void (*f)(ErrorSink&)) { + (*f)(*(ErrorSink*) this); + return *this; +} + +void ErrorCollector::endMessage() { + Message *msg; + if (m_haveLocation) + msg = new Message(m_severity, m_location, m_msg.str().c_str()); + else + msg = new Message(m_severity, m_msg.str().c_str()); + + bool found = false; + for (int m = 0; m < m_messages.length(); m++) + if (*m_messages.lookup(m) == *msg) + found = true; + + if (!found) + m_messages.append(msg); + else + delete msg; + + clear(); +} + +void ErrorCollector::clear() { + m_severity = sev_none; + m_haveLocation = false; + m_msg.str(""); + m_msg.clear(); +} + +int ErrorCollector::index() { + return (int) m_messages.length(); +} + +void ErrorCollector::index(int n) { + while (n >= 0 && m_messages.length() > n) { + delete m_messages.lookup(m_messages.length() - 1); + m_messages.remove(m_messages.length() - 1); + } +} + +void ErrorCollector::shift(ErrorSink &e) { + for (int m = 0; m < m_messages.length(); m++) + m_messages.lookup(m)->print(e); + index(0); +} + +const ErrorSeverity &ErrorCollector::severity() const { + const ErrorSeverity *max_sev = &sev_none; + for (int m = 0; m < m_messages.length(); m++) + if (*max_sev < m_messages.lookup(m)->severity()) + max_sev = &m_messages.lookup(m)->severity(); + return *max_sev; +} + +} // namespace Puma diff --git a/Puma/src/common/ErrorCollector.h b/Puma/src/common/ErrorCollector.h new file mode 100644 index 0000000..6666c13 --- /dev/null +++ b/Puma/src/common/ErrorCollector.h @@ -0,0 +1,146 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_ErrorCollector_H +#define PUMA_ErrorCollector_H + +/** \file + * Error stream implementation. */ + +#include "Puma/ErrorSink.h" +#include "Puma/Array.h" +#include "Puma/Location.h" +#include "Puma/ErrorSeverity.h" +#include + +namespace Puma { + +/** \class ErrorCollector ErrorCollector.h Puma/ErrorCollector.h + * Error stream implementation that collects all messages in an + * internal message stack. Messages are finished with the Puma::endMessage + * stream manipulator. Collected messages can be shifted to another + * ErrorSink. + * \ingroup common */ +class ErrorCollector : public ErrorSink { + class Message { + ErrorSeverity m_severity; + Location m_location; + bool m_haveLocation; + char *m_message; + + public: + Message(const ErrorSeverity &s, Location l, const char *m); + Message(const ErrorSeverity &s, const char *m); + ~Message(); + bool operator ==(const Message&) const; + void print(ErrorSink &e); + const ErrorSeverity &severity() const { + return m_severity; + } + }; + + Array m_messages; + Location m_location; + bool m_haveLocation; + ErrorSeverity m_severity; + std::ostringstream m_msg; + + void clear(); + +public: + /** Constructor. */ + ErrorCollector() { + clear(); + } + /** Destructor. */ + virtual ~ErrorCollector() { + } + + /** Add given string to current error message. + * \param str The string to add. + * \return A reference to this error stream. */ + ErrorCollector& operator <<(const char *str); + /** Add given long integer value to current error message. + * \param value The value to add. + * \return A reference to this error stream. */ + ErrorCollector& operator <<(long value); + /** Add given unsigned integer value to current error message. + * \param value The value to add. + * \return A reference to this error stream. */ + ErrorCollector& operator <<(unsigned value); + /** Add given signed integer value to current error message. + * \param value The value to add. + * \return A reference to this error stream. */ + ErrorCollector& operator <<(int value); + /** Add given short integer value to current error message. + * \param value The value to add. + * \return A reference to this error stream. */ + ErrorCollector& operator <<(short value); + /** Add given character to current error message. + * \param c The character to add. + * \return A reference to this error stream. */ + ErrorCollector& operator <<(char c); + /** Add given floating point value to current error message. + * \param value The value to add. + * \return A reference to this error stream. */ + ErrorCollector& operator <<(double value); + /** Change the severity of the current error message. + * \param severity The new severity. + * \return A reference to this error stream. */ + ErrorCollector& operator <<(const ErrorSeverity& severity); + /** Set the location the error occurred. + * \param location The error location. + * \return A reference to this error stream. */ + ErrorCollector& operator <<(Location location); + /** Add the serialized value of the given object to the current error message. + * \param obj The object to serialize. + * \return A reference to this error stream. */ + ErrorCollector& operator <<(const Printable& obj); + /** Apply the given stream manipulator. + * \param fct The stream manipulator function. + * \return A reference to this error stream. */ + ErrorCollector& operator <<(void (*fct)(ErrorSink&)); + + /** Finish the current error message. */ + void endMessage(); + + /** Get the index of the current error message on the + * message stack. + * \return The index of the current error message. */ + int index(); + /** Set the index of the current error message on the + * message stack. If the new index is less than the current + * number of messages on the stack, all messages with an + * index greater than the given index are dropped. If the new + * index is 0 then all previously collected messages are + * dropped. + * \param idx The new index. */ + void index(int idx); + + /** Shift all collected messages to the destination error sink. + * \param dest The destination error sink. */ + void shift(ErrorSink &dest); + + /** Get the current error severity of the stream. + * \return A reference to the current error severity. */ + const ErrorSeverity &severity() const; +}; + +} // namespace Puma + +#endif /* PUMA_ErrorCollector_H */ diff --git a/Puma/src/common/ErrorSeverity.cc b/Puma/src/common/ErrorSeverity.cc new file mode 100644 index 0000000..31906f1 --- /dev/null +++ b/Puma/src/common/ErrorSeverity.cc @@ -0,0 +1,29 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 "Puma/ErrorSeverity.h" + +namespace Puma { + +const ErrorSeverity sev_none(0, "none"); +const ErrorSeverity sev_message(100, "message"); +const ErrorSeverity sev_warning(200, "warning"); +const ErrorSeverity sev_error(300, "error"); +const ErrorSeverity sev_fatal(400, "fatal"); + +} // namespace Puma diff --git a/Puma/src/common/ErrorSeverity.h b/Puma/src/common/ErrorSeverity.h new file mode 100644 index 0000000..edcbbd5 --- /dev/null +++ b/Puma/src/common/ErrorSeverity.h @@ -0,0 +1,120 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_ErrorSeverity_H +#define PUMA_ErrorSeverity_H + +/** \file + * Severity of errors. */ + +namespace Puma { + +/** \class ErrorSeverity ErrorSeverity.h Puma/ErrorSeverity.h + * Severity of errors represented by a short integer and a textual + * representation. Following error severities are defined (in + * ascending order): + * - Puma::sev_none + * - Puma::sev_message + * - Puma::sev_warning + * - Puma::sev_error + * - Puma::sev_fatal + * + * \ingroup common */ +class ErrorSeverity { + unsigned short m_severity; + const char *m_text; + +public: + /** Constructor. + * \param severity The severity value. + * \param text The textual representation. */ + ErrorSeverity(unsigned short severity = 0, const char* text = (const char*) 0) : + m_severity(severity), m_text(text) { + } + /** Copy-constructor. + * \param copy The error severity to copy. */ + ErrorSeverity(const ErrorSeverity ©) : + m_severity(copy.m_severity), m_text(copy.m_text) { + } + /** Assign another severity. + * \param severity The severity to assign. + * \return A reference to this. */ + ErrorSeverity &operator =(const ErrorSeverity &severity) { + m_severity = severity.m_severity; + m_text = severity.m_text; + return *this; + } + + /** Check if this severity is lower than the given. + * \param other The severity to compare with. + * \return 1 if true, 0 otherwise. */ + int operator <(const ErrorSeverity &other) const { + return m_severity < other.m_severity; + } + /** Check if this severity is higher than the given. + * \param other The severity to compare with. + * \return 1 if true, 0 otherwise. */ + int operator >(const ErrorSeverity &other) const { + return m_severity > other.m_severity; + } + /** Check if this severity is lower than or the same as the given. + * \param other The severity to compare with. + * \return 1 if true, 0 otherwise. */ + int operator <=(const ErrorSeverity &other) const { + return m_severity < other.m_severity || m_severity == other.m_severity; + } + /** Check if this severity is higher than or the same as the given. + * \param other The severity to compare with. + * \return 1 if true, 0 otherwise. */ + int operator >=(const ErrorSeverity &other) const { + return m_severity > other.m_severity || m_severity == other.m_severity; + } + /** Check if this severity is the same as the given. + * \param other The severity to compare with. + * \return 1 if true, 0 otherwise. */ + int operator ==(const ErrorSeverity &other) const { + return m_severity == other.m_severity; + } + /** Check if this severity is not the same as the given. + * \param other The severity to compare with. + * \return 1 if true, 0 otherwise. */ + int operator !=(const ErrorSeverity &other) const { + return m_severity != other.m_severity; + } + + /** Get the textual representation of this severity. + * \return The textual representation. */ + const char *text() const { + return m_text; + } +}; + +/** Error has no severity. */ +extern const ErrorSeverity sev_none; +/** Informal message. */ +extern const ErrorSeverity sev_message; +/** A warning. */ +extern const ErrorSeverity sev_warning; +/** An error. */ +extern const ErrorSeverity sev_error; +/** A fatal error. */ +extern const ErrorSeverity sev_fatal; + +} // namespace Puma + +#endif /* PUMA_ErrorSeverity_H */ diff --git a/Puma/src/common/ErrorSink.cc b/Puma/src/common/ErrorSink.cc new file mode 100644 index 0000000..211cbd4 --- /dev/null +++ b/Puma/src/common/ErrorSink.cc @@ -0,0 +1,27 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 "Puma/ErrorSink.h" + +namespace Puma { + +void endMessage(ErrorSink &err) { + err.endMessage(); +} + +} // namespace Puma diff --git a/Puma/src/common/ErrorSink.h b/Puma/src/common/ErrorSink.h new file mode 100644 index 0000000..37ef908 --- /dev/null +++ b/Puma/src/common/ErrorSink.h @@ -0,0 +1,108 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_ErrorSink_H +#define PUMA_ErrorSink_H + +/** \file + * Error sink interface. */ + +#include "Puma/ErrorSeverity.h" +#include "Puma/Printable.h" +#include "Puma/Location.h" + +namespace Puma { + +/** \class ErrorSink ErrorSink.h Puma/ErrorSink.h + * This is an interface for classes that may be used to consume error + * messages during a process where many errors can occur like parsing + * a program. + * + * The error information is handed over to the ErrorSink in stream-like + * style. Different severities of errors are predefined and can be used + * to classify error information that follows. Also a location can be + * handed over to the ErrorSink to specify where the error was found + * (filename, line, etc.). The error information itself can be of any + * standard data type or anything that implements the Printable interface. + * An error message is finished with the Puma::endMessage stream manipulator. + * + * Specializations of this class could either build and print error + * messages or collect them for a later processing. + * \ingroup common */ +class ErrorSink { +public: + /** Destructor. */ + virtual ~ErrorSink() { + } + + /** Add given string to current error message. + * \param str The string to add. + * \return A reference to this error stream. */ + virtual ErrorSink &operator <<(const char *str) = 0; + /** Add given long integer value to current error message. + * \param value The value to add. + * \return A reference to this error stream. */ + virtual ErrorSink &operator <<(long value) = 0; + /** Add given unsigned integer value to current error message. + * \param value The value to add. + * \return A reference to this error stream. */ + virtual ErrorSink &operator <<(unsigned value) = 0; + /** Add given signed integer value to current error message. + * \param value The value to add. + * \return A reference to this error stream. */ + virtual ErrorSink &operator <<(int value) = 0; + /** Add given short integer value to current error message. + * \param value The value to add. + * \return A reference to this error stream. */ + virtual ErrorSink &operator <<(short value) = 0; + /** Add given character to current error message. + * \param c The character to add. + * \return A reference to this error stream. */ + virtual ErrorSink &operator <<(char c) = 0; + /** Add given floating point value to current error message. + * \param value The value to add. + * \return A reference to this error stream. */ + virtual ErrorSink &operator <<(double value) = 0; + /** Change the severity of the current error message. + * \param severity The new severity. + * \return A reference to this error stream. */ + virtual ErrorSink &operator <<(const ErrorSeverity &severity) = 0; + /** Set the location the error occurred. + * \param location The error location. + * \return A reference to this error stream. */ + virtual ErrorSink &operator <<(Location location) = 0; + /** Add the serialized value of the given object to the current error message. + * \param obj The object to serialize. + * \return A reference to this error stream. */ + virtual ErrorSink &operator <<(const Printable &obj) = 0; + /** Apply the given stream manipulator. + * \param fct The stream manipulator function. + * \return A reference to this error stream. */ + virtual ErrorSink &operator <<(void (*fct)(ErrorSink &)) = 0; + + /** Finish the current error message. */ + virtual void endMessage() = 0; +}; + +/** Finish the current error message on the given error sink. + * \param err The error sink. */ +void endMessage(ErrorSink &err); + +} // namespace Puma + +#endif /* PUMA_ErrorSink_H */ diff --git a/Puma/src/common/ErrorStream.cc b/Puma/src/common/ErrorStream.cc new file mode 100644 index 0000000..ad6910e --- /dev/null +++ b/Puma/src/common/ErrorStream.cc @@ -0,0 +1,136 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 "Puma/ErrorStream.h" +#include "Puma/Location.h" +#include + +namespace Puma { + +ErrorStream &ErrorStream::operator <<(const char *v) { + if (!m_silently) + *m_msg << v; + return *this; +} + +ErrorStream &ErrorStream::operator <<(long v) { + if (!m_silently) + *m_msg << v; + return *this; +} + +ErrorStream &ErrorStream::operator <<(unsigned v) { + if (!m_silently) + *m_msg << v; + return *this; +} + +ErrorStream &ErrorStream::operator <<(int v) { + if (!m_silently) + *m_msg << v; + return *this; +} + +ErrorStream &ErrorStream::operator <<(short v) { + if (!m_silently) + *m_msg << v; + return *this; +} + +ErrorStream &ErrorStream::operator <<(char v) { + if (!m_silently) + *m_msg << v; + return *this; +} + +ErrorStream &ErrorStream::operator <<(double v) { + if (!m_silently) + *m_msg << v; + return *this; +} + +ErrorStream &ErrorStream::operator <<(const ErrorSeverity &sev) { + m_currSeverity = sev; + if (m_currSeverity > m_maxSeverity) + m_maxSeverity = m_currSeverity; + return *this; +} + +ErrorStream &ErrorStream::operator <<(Location v) { + if (!m_silently) { + m_location = v; + m_haveLocation = (v.filename().is_defined() && v.filename().name()); + } + return *this; +} + +ErrorStream &ErrorStream::operator <<(const Printable &v) { + if (!m_silently) + *m_msg << v; + return *this; +} + +ErrorStream &ErrorStream::operator <<(void (*f)(ErrorSink &)) { + (*f)(*(ErrorSink*) this); + return *this; +} + +void ErrorStream::endMessage() { + output(); + clear(); +} + +void ErrorStream::reset() { + m_maxSeverity = sev_none; + clear(); +} + +bool ErrorStream::silent() { + bool was_silent = m_silently; + m_silently = true; + return was_silent; +} + +bool ErrorStream::loud() { + bool was_loud = !m_silently; + m_silently = false; + return was_loud; +} + +void ErrorStream::clear() { + m_currSeverity = sev_none; + m_haveLocation = false; + if (m_msg) + delete m_msg; + m_msg = new std::ostringstream; +} + +void ErrorStream::output() { + if (m_silently) + return; + + if (m_haveLocation) + *m_out << m_location << ": "; + + if (m_currSeverity != sev_none) + *m_out << m_currSeverity.text() << ": "; + + *m_out << m_msg->str().c_str() << std::endl; +} + +} // namespace Puma diff --git a/Puma/src/common/ErrorStream.h b/Puma/src/common/ErrorStream.h new file mode 100644 index 0000000..b4d533d --- /dev/null +++ b/Puma/src/common/ErrorStream.h @@ -0,0 +1,134 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_ErrorStream_H +#define PUMA_ErrorStream_H + +/** \file + * Error stream implementation. */ + +#include +#include "Puma/ErrorSink.h" +#include "Puma/ErrorSeverity.h" +#include "Puma/Location.h" + +namespace Puma { + +/** \class ErrorStream ErrorStream.h Puma/ErrorStream.h + * An error stream is a special ErrorSink that prints out an error message + * as soon as it is complete. It also stores the maximum error severity. + * The error stream can be reset to its initial state. + * \ingroup common */ +class ErrorStream : public ErrorSink { + std::ostream *m_out; + ErrorSeverity m_maxSeverity; + ErrorSeverity m_currSeverity; + Location m_location; + bool m_haveLocation; + std::ostringstream *m_msg; + bool m_silently; + + void output(); + void clear(); + +public: + /** Constructor. + * \param out The output stream to use. Defaults to std::cerr. */ + ErrorStream(std::ostream &out = std::cerr) : + m_out(&out), m_msg(0) { + reset(); + m_silently = false; + } + /** Destructor. */ + virtual ~ErrorStream() { + delete m_msg; + } + + /** Add given string to current error message. + * \param str The string to add. + * \return A reference to this error stream. */ + ErrorStream &operator <<(const char *str); + /** Add given long integer value to current error message. + * \param value The value to add. + * \return A reference to this error stream. */ + ErrorStream &operator <<(long value); + /** Add given unsigned integer value to current error message. + * \param value The value to add. + * \return A reference to this error stream. */ + ErrorStream &operator <<(unsigned value); + /** Add given signed integer value to current error message. + * \param value The value to add. + * \return A reference to this error stream. */ + ErrorStream &operator <<(int value); + /** Add given short integer value to current error message. + * \param value The value to add. + * \return A reference to this error stream. */ + ErrorStream &operator <<(short value); + /** Add given character to current error message. + * \param c The character to add. + * \return A reference to this error stream. */ + ErrorStream &operator <<(char c); + /** Add given floating point value to current error message. + * \param value The value to add. + * \return A reference to this error stream. */ + ErrorStream &operator <<(double value); + /** Change the severity of the current error message. + * \param sev The new severity. + * \return A reference to this error stream. */ + ErrorStream &operator <<(const ErrorSeverity &sev); + /** Set the location the error occurred. + * \param location The error location. + * \return A reference to this error stream. */ + ErrorStream &operator <<(Location location); + /** Add the serialized value of the given object to the current error message. + * \param obj The object to serialize. + * \return A reference to this error stream. */ + ErrorStream &operator <<(const Printable &obj); + /** Apply the given stream manipulator. + * \param fct The stream manipulator function. + * \return A reference to this error stream. */ + ErrorStream &operator <<(void (*fct)(ErrorSink &)); + + /** Finish the current error message. */ + void endMessage(); + /** Reset the error stream to its initial state. */ + void reset(); + /** Turn to silent mode. In silent mode no message is printed + * on the output stream. + * \return True if the previous mode was silent already. */ + bool silent(); + /** Turn to loud mode. In loud mode messages are printed + * on the output stream. This is the default mode. + * \return True if the previous mode was loud already. */ + bool loud(); + + /** Get the current error severity. + * \return The error severity. */ + ErrorSeverity severity() const { + return m_maxSeverity; + } + /** Set a new severity for all following messages. + * \param sev The new severity. */ + void severity(ErrorSeverity& sev) { + m_maxSeverity = sev; + } +}; + +} // namespace Puma + +#endif /* PUMA_ErrorStream_H */ diff --git a/Puma/src/common/FileUnit.cc b/Puma/src/common/FileUnit.cc new file mode 100644 index 0000000..f9ff27f --- /dev/null +++ b/Puma/src/common/FileUnit.cc @@ -0,0 +1,55 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 "Puma/FileUnit.h" +#include "Puma/ErrorStream.h" +#include "Puma/SysCall.h" +#include "Puma/StrCol.h" +#include "Puma/Project.h" +#include +#include + +namespace Puma { + +// File belongs to given project? +bool FileUnit::belongsTo(Project &p) { + // same project yields same status, of course + if (m_project == &p) + return m_isBelow; + + m_project = &p; + m_isBelow = p.isBelow(Unit::name()); + return m_isBelow; +} + +void FileUnit::setLocation(const char *location) { + if (m_lastLocation) + delete[] m_lastLocation; + m_lastLocation = StrCol::dup(location); +} + +void FileUnit::name(const char *n) { + Unit::name(n); + if (m_absolutePath) + delete[] m_absolutePath; + m_absolutePath = SysCall::absolute(n); + if (!m_absolutePath) + m_absolutePath = n ? StrCol::dup(n) : (char*) 0; +} + +} // namespace Puma diff --git a/Puma/src/common/FileUnit.h b/Puma/src/common/FileUnit.h new file mode 100644 index 0000000..f843862 --- /dev/null +++ b/Puma/src/common/FileUnit.h @@ -0,0 +1,101 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_FileUnit_H +#define PUMA_FileUnit_H + +/** \file + * Unit for files. */ + +#include "Puma/Unit.h" + +namespace Puma { + +class Project; + +/** \class FileUnit FileUnit.h Puma/FileUnit.h + * Special Unit for files. Holds its last save location, the + * absolute path of the file, and the source project the file + * belongs to. + * \ingroup common */ +class FileUnit : public Unit { + char *m_lastLocation; + char *m_absolutePath; + Project *m_project; + bool m_isBelow; + +public: + /** Constructor. */ + FileUnit(); + /** Constructor. + * \param unit The unit representing the file. */ + FileUnit(Unit &unit); + /** Copy-constructor. + * \param list The list of tokens representing the file. */ + FileUnit(const List &list); + /** Destructor. Frees the tokens. */ + virtual ~FileUnit(); + /** Set the name of the unit, i.e. the filename. + * \param filename The name of the unit. */ + virtual void name(const char *filename); + /** Set the last save location of the file in the file system. + * \param location The location in the file system. */ + void setLocation(const char *location); + /** Get the last save location of the file in the file system. + * \return The location of the file. */ + char *lastLocation() const; + /** Get the absolute version of the filename. + * \return The absolute filename. */ + char *absolutePath() const; + /** Check if this unit refers to a file. + * \return Always returns true. */ + bool isFile() const; + /** Check if the file belongs to the given source project. + * \param project The source project. */ + bool belongsTo(Project &project); +}; + +inline FileUnit::FileUnit() + : Unit(), m_lastLocation(0), m_absolutePath(0), m_project(0), m_isBelow(false) { +} +inline FileUnit::FileUnit(Unit &unit) + : Unit(unit), m_lastLocation(0), m_absolutePath(0), m_project(0), m_isBelow(false) { +} +inline FileUnit::FileUnit(const List &list) + : Unit(list), m_lastLocation(0), m_absolutePath(0), m_project(0), m_isBelow(false) { +} +inline FileUnit::~FileUnit() { + if (m_lastLocation) + delete[] m_lastLocation; + if (m_absolutePath) + delete[] m_absolutePath; +} + +inline char *FileUnit::lastLocation() const { + return m_lastLocation; +} +inline char *FileUnit::absolutePath() const { + return m_absolutePath; +} +inline bool FileUnit::isFile() const { + return true; +} + +} // namespace Puma + +#endif /* PUMA_FileUnit_H */ diff --git a/Puma/src/common/Filename.h b/Puma/src/common/Filename.h new file mode 100644 index 0000000..49b4cc3 --- /dev/null +++ b/Puma/src/common/Filename.h @@ -0,0 +1,134 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_Filename_H +#define PUMA_Filename_H + +/** \file + * Filename abstraction. */ + +#include "Puma/SmartPtr.h" +#include "Puma/Printable.h" +#include "Puma/FilenameInfo.h" + +namespace Puma { + +/** \class Filename Filename.h Puma/Filename.h + * Abstraction of a filename using a smart pointer for automatic + * memory allocation / deallocation. It encapsulates often needed + * operations like separating the path portion of the filename or + * the check whether the filename is absolute. + * \ingroup common */ +class Filename : public Printable { + SmartPtr m_info; + +public: + /** Constructor. */ + Filename() { + } + /** Constructor. + * \param filename The filename. */ + Filename(const char *filename) { + name(filename); + } + /** Assign a new filename. + * \param filename The filename. + * \return A reference to this filename. */ + Filename &operator=(const char *filename) { + name(filename); + return *this; + } + /** Check if the filename is not NULL. + * \return True if the filename is valid. */ + bool operator~() const { + return m_info.valid(); + } + /** Check if the filename is not NULL. + * \return True if the filename is valid. */ + bool is_defined() const { + return m_info.valid(); + } + /** Set a new filename. + * \param filename The new filename. */ + inline void name(const char *filename); + /** Get the filename. + * \return The filename. */ + inline const char *name() const; + /** Get the path portion of the filename. + * \return The path to the file. */ + inline const char *path(); + /** Get the root of an absolute filename, i.e. everything + * up to the first path delimiter. This is for instance the + * drive portion of the filename on Windows (c:\). On Unix systems + * this is simply a slash (/). + * \return The root or NULL if filename is not absolute. */ + inline const char *root(); + /** Check whether the filename is absolute, i.e. starts at the + * root of the file system. + * \return True if the filename is absolute. */ + inline bool is_absolute() const; + /** Check if this filename equals the given. + * \param filename The other filename. + * \return True if both filenames are equal. */ + inline bool operator==(const Filename &filename) const; + /** Check if this filename not equals the given. + * \param filename The other filename. + * \return True if both filenames are not equal. */ + bool operator!=(const Filename &filename) const { + return !(*this == filename); + } + /** Print this filename on the given output stream. + * \param out The output stream. */ + virtual void print(std::ostream &out) const { + if (m_info) + out << name(); + } +}; + +inline void Filename::name(const char *n) { + m_info = new FilenameInfo; + m_info->name(n); +} + +inline const char *Filename::name() const { + return m_info->name(); +} + +inline const char *Filename::path() { + return m_info->path(); +} + +inline const char *Filename::root() { + return m_info->root(); +} + +inline bool Filename::is_absolute() const { + return m_info->is_absolute(); +} + +inline bool Filename::operator==(const Filename &f) const { + if (m_info == f.m_info) + return true; + if (!m_info || !f.m_info) + return false; + return **m_info == **f.m_info; +} + +} // namespace Puma + +#endif /* PUMA_Filename_H */ diff --git a/Puma/src/common/FilenameInfo.cc b/Puma/src/common/FilenameInfo.cc new file mode 100644 index 0000000..a70716f --- /dev/null +++ b/Puma/src/common/FilenameInfo.cc @@ -0,0 +1,107 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/FilenameInfo.h" +#include +#include + +namespace Puma { + +FilenameInfo::~FilenameInfo() { + if (m_path) + delete[] m_path; + if (m_root) + delete[] m_root; +} + +void FilenameInfo::name(const char *n) { + m_name = n; + + // check if the name ends with '/' or '\\' + if (n) { + int len = strlen(n); + bool have_trailing_delim = false; + while (len >= 1 && (n[len - 1] == '/' || n[len - 1] == '\\')) { + have_trailing_delim = true; + len--; + } + len++; + if (have_trailing_delim) { + // assign _name with a stripped temporary name + char * new_name = new char[len + 1]; + strcpy(new_name, n); + new_name[len - 1] = '\0'; + m_name = new_name; + delete[] new_name; + } + } + + if (m_path) + delete[] m_path; + m_path = (const char*) 0; + if (m_root) + delete[] m_root; + m_root = (const char*) 0; +} + +const char *FilenameInfo::path() { + if (m_name.empty()) + return (const char*) 0; + if (m_path) + return m_path; + + const char *cname = m_name.c_str(); + const char *delim = cname + strlen(cname) - 1; + while (delim >= cname && *delim != '/' && *delim != '\\' && *delim != ':') + delim--; + if (delim < cname) + return ""; + + int len = delim - cname; + if (len == 0) + len = 1; + + m_path = new char[len + 1]; + strncpy((char*) m_path, cname, len); + ((char*) m_path)[len] = '\0'; + return m_path; +} + +const char *FilenameInfo::root() { + if (m_name.empty() || !is_absolute()) + return 0; + if (m_root) + return m_root; + + const char *cname = m_name.c_str(); + int len = 0; + while (cname[len] != '/' && cname[len] != '\\') + len++; + m_root = new char[len + 2]; + strncpy((char*) m_root, cname, len + 1); + ((char*) m_root)[len + 1] = '\0'; + return m_root; +} + +bool FilenameInfo::is_absolute() const { + const char *cname = m_name.c_str(); + int len = strlen(cname); + return (len >= 1 && (cname[0] == '/' || cname[0] == '\\')) || (len >= 3 && cname[1] == ':' && (cname[2] == '/' || cname[2] == '\\') && isalpha(cname[0])); +} + +} // namespace Puma diff --git a/Puma/src/common/FilenameInfo.h b/Puma/src/common/FilenameInfo.h new file mode 100644 index 0000000..ebaee1d --- /dev/null +++ b/Puma/src/common/FilenameInfo.h @@ -0,0 +1,78 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_FilenameInfo_H +#define PUMA_FilenameInfo_H + +/** \file + * Filename information. */ + +#include "Puma/SmartPtr.h" +#include "Puma/DString.h" + +namespace Puma { + +/** \class FilenameInfo FilenameInfo.h Puma/FilenameInfo.h + * Information about a filename supporting Puma::SmartPtr. + * This object stores the name of the file, its path portion, + * and the root portion if the filename is absolute. + * \ingroup common */ +class FilenameInfo : public SmartPtr::RefCnt { + DString m_name; + const char *m_path; + const char *m_root; + +public: + /** Constructor. */ + FilenameInfo() + : m_path(0), m_root(0) { + } + /** Destructor. Frees the allocated strings. */ + ~FilenameInfo(); + /** Set a new filename. + * \param filename The new filename. */ + void name(const char *filename); + /** Get the filename. + * \return The filename. */ + const char *name() const { + return m_name.c_str(); + } + /** Get the path portion of the filename. + * \return The path to the file. */ + const char *path(); + /** Get the root of an absolute filename, i.e. everything + * up to the first path delimiter. This is for instance the + * drive portion of the filename on Windows (c:\). On Unix systems + * this is simply a slash (/). + * \return The root or NULL if filename is not absolute. */ + const char *root(); + /** Check whether the filename is absolute, i.e. starts at the + * root of the file system. + * \return True if the filename is absolute. */ + bool is_absolute() const; + /** Check if this filename equals the given. + * \param filename The other filename. + * \return True if both filenames are equal. */ + bool operator==(const FilenameInfo &filename) const { + return m_name == filename.m_name; + } +}; + +} // namespace Puma + +#endif /* PUMA_FilenameInfo_H */ diff --git a/Puma/src/common/LanguageID.h b/Puma/src/common/LanguageID.h new file mode 100644 index 0000000..30efb03 --- /dev/null +++ b/Puma/src/common/LanguageID.h @@ -0,0 +1,60 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_LanguageID_H +#define PUMA_LanguageID_H + +/** \file + * Language identifier implementation. */ + +namespace Puma { + +/** \class LanguageID LanguageID.h Puma/LanguageID.h + * A language ID is a unique identifier for a language. + * It is used to group tokens, like identifiers, keywords, + * preprocessor directives, comments, and so on. + * \ingroup common */ +class LanguageID { + const char *m_id; + +public: + /** Construct an empty object. */ + LanguageID() + : m_id(0) { + } + /** Constructor. + * \param id The identifier. */ + LanguageID(const char *id) + : m_id(id) { + } + /** Conversion operator. + * \return The identifier string. */ + operator const char *() const { + return m_id; + } + /** Compare with another language identifier. + * \param id The other language identifier. + * \return True if it is the same language identifier object. */ + bool operator ==(const LanguageID &id) const { + return m_id == (const char*) id; + } +}; + +} // namespace Puma + +#endif /* PUMA_LanguageID_H */ diff --git a/Puma/src/common/Location.h b/Puma/src/common/Location.h new file mode 100644 index 0000000..a0ab7da --- /dev/null +++ b/Puma/src/common/Location.h @@ -0,0 +1,110 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_Location_H +#define PUMA_Location_H + +/** \file + * Token location implementation. */ + +#include "Puma/Filename.h" + +namespace Puma { + +/** \class Location Location.h Puma/Location.h + * Location of a token in a source file. + * \ingroup common */ +class Location { + Filename m_filename; + int m_line; + int m_column; + +public: + /** Construct an empty location. */ + Location() + : m_filename(), m_line(0), m_column(0) { + } + /** Construct a token location. + * \param filename The name of the file the token is located in. + * \param line The line number. + * \param column The optional column number. Defaults to 0. */ + Location(Filename filename, int line, int column = 0) { + setup(filename, line, column); + } + /** Initialize a token location. + * \param filename The name of the file the token is located in. + * \param line The line number. + * \param column The optional column number. Defaults to 0. */ + void setup(Filename filename, int line, int column = 0) { + m_filename = filename; + m_line = line; + m_column = column; + } + /** Get the name of the file the token is located in. + * \return A reference to the file name. */ + const Filename &filename() const { + return m_filename; + } + /** Get the number of the line in the file. + * \return The line number. */ + int line() const { + return m_line; + } + /** Get the number of the column in the file. + * \return The column number. */ + int column() const { + return m_column; + } + /** Compare with another location. + * \param location The other location. + * \return True if both locations are equal. */ + bool operator ==(const Location &location) const { + return filename() == location.filename() && line() == location.line() && column() == location.column(); + } + /** Compare with another location. + * \param location The other location. + * \return True if both locations differ. */ + bool operator !=(const Location &location) const { + return !(*this == location); + } + /** Compare with another location in the same file. + * \param location The other location. + * \return True if this location is before the given location in the same file. */ + bool operator <(const Location &location) const { + if (filename() != location.filename()) + return false; + return line() < location.line() && column() < location.column(); + } +}; + +/** Output stream operator to print the given location on the given output stream. + * \param out The output stream. + * \param location The location to print. + * \return A reference to the output stream. */ +inline std::ostream &operator <<(std::ostream &out, const Location &location) { +#ifdef VISUAL_STUDIO + out << location.filename() << "(" << location.line() << ")"; +#else + out << location.filename() << ":" << location.line(); +#endif + return out; +} + +} // namespace Puma + +#endif /* PUMA_Location_H */ diff --git a/Puma/src/common/MacroUnit.cc b/Puma/src/common/MacroUnit.cc new file mode 100644 index 0000000..5374669 --- /dev/null +++ b/Puma/src/common/MacroUnit.cc @@ -0,0 +1,56 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 "Puma/MacroUnit.h" +#include "Puma/Token.h" + +namespace Puma { + +Token *MacroUnit::ExpansionBegin(Token *token) const { + if (token && token == (Token*) first() && MacroBegin()) { + // macro generated macro call + if (MacroBegin()->is_macro_generated()) { + Unit *unit = (Unit*) MacroBegin()->belonging_to(); + if (unit && unit->isMacroExp()) { + return ((MacroUnit*) unit)->ExpansionBegin(MacroBegin()); + } + // initial macro call - this is what we searched for + } else { + return MacroBegin(); + } + } + return 0; +} + +Token *MacroUnit::ExpansionEnd(Token *token) const { + if (token && token == (Token*) last() && MacroEnd()) { + // macro generated macro call + if (MacroEnd()->is_macro_generated()) { + Unit *unit = (Unit*) MacroEnd()->belonging_to(); + if (unit && unit->isMacroExp()) { + return ((MacroUnit*) unit)->ExpansionEnd(MacroEnd()); + } + // initial macro call - this is what we searched for + } else { + return MacroEnd(); + } + } + return 0; +} + +} // namespace Puma diff --git a/Puma/src/common/MacroUnit.h b/Puma/src/common/MacroUnit.h new file mode 100644 index 0000000..4b173e1 --- /dev/null +++ b/Puma/src/common/MacroUnit.h @@ -0,0 +1,102 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_MacroUnit_H +#define PUMA_MacroUnit_H + +/** \file + * Macro expansion unit implementation. */ + +#include "Puma/Unit.h" +#include "Puma/Token.h" + +namespace Puma { + +/** \class MacroUnit MacroUnit.h Puma/MacroUnit.h + * Specialized unit for preprocessor macro expansions. + * \ingroup common */ +class MacroUnit : public Unit { + Unit *m_callingUnit; + Token *m_startToken; + Token *m_endToken; + +public: + /** Construct an empty macro unit. */ + MacroUnit() + : m_callingUnit(0), m_startToken(0), m_endToken(0) { + } + /** Construct a macro unit. + * \param unit The unit containing the macro expansion. */ + MacroUnit(const Unit &unit) + : Unit(unit), m_callingUnit(0), m_startToken(0), m_endToken(0) { + } + /** Destructor. */ + virtual ~MacroUnit() { + } + /** Check if this is a macro expansion unit. + * \return Always returns true. */ + virtual bool isMacroExp() const { + return true; + } + /** Set the unit containing the macro call. + * \param unit The unit. */ + void CallingUnit(Unit *unit) { + m_callingUnit = unit; + } + /** Get the unit containing the macro call. + * \return A pointer to the unit, or NULL if not set. */ + Unit *CallingUnit() const { + return (Unit*) m_callingUnit; + } + /** Set the first token of the macro call in the calling unit. + * \param token The first token. */ + void MacroBegin(Token *token) { + m_startToken = token; + } + /** Set the last token of the macro call in the calling unit. + * \param token The last token. */ + void MacroEnd(Token *token) { + m_endToken = token; + } + /** Get the first token of the macro call in the calling unit. + * \return A pointer to the token. */ + Token *MacroBegin() const { + return m_startToken; + } + /** Get the last token of the macro call in the calling unit. + * \return A pointer to the token. */ + Token *MacroEnd() const { + return m_endToken; + } + /** Get the first token of the whole macro expansion in the source + * file if the given token is the first token of this expansion or + * nested expansion (macro generated macro call). + * \param token The token. + * \return The first token, or NULL otherwise. */ + Token *ExpansionBegin(Token *token) const; + /** Get the last token of the whole macro expansion in the source + * file if the given token is the last token of this expansion or + * nested expansion (macro generated macro call). + * \param token The token. + * \return The last token, or NULL otherwise. */ + Token *ExpansionEnd(Token *token) const; +}; + +} // namespace Puma + +#endif /* PUMA_MacroUnit_H */ diff --git a/Puma/src/common/OptsParser.cc b/Puma/src/common/OptsParser.cc new file mode 100644 index 0000000..c2b0ab2 --- /dev/null +++ b/Puma/src/common/OptsParser.cc @@ -0,0 +1,204 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 "Puma/OptsParser.h" +#include "Puma/ParserKey.h" +#include +#include + +namespace Puma { + +OptsParser::OptsParser(int argc, char **argv, const Option *opts) + : m_opts(opts) { + for (int idx = 0; idx < argc; idx++) { + m_argv.push_back(argv[idx]); + } + m_curarg = 1; + m_tonext = 0; + m_number = 0; +} + +OptsParser::OptsParser(const std::string &line, const Option *opts) + : m_opts(opts) { + tokenize(line, m_argv, " \t\n\r"); + m_curarg = m_tonext = m_number = 0; +} + +int OptsParser::getOption() { + m_number = FINISH; + m_curarg += m_tonext; + + if (m_curarg < m_argv.size()) { + bool isLong = false; + const std::string &arg(m_argv[m_curarg]); + const Option* curOpt; + + m_tonext = 1; + m_opt = m_arg = ""; + + if (ParserKey::isLongKey(arg) && (arg.length() > ParserKey::getLongKeyLength())) { + isLong = true; + } else if ((ParserKey::isKey(arg)) && (arg.length() > ParserKey::getKeyLength())) { + isLong = false; + } else { + m_number = NOOPTION; + m_arg = arg; + } + + if (m_number != NOOPTION) { + // search options in argument string + curOpt = findOption(arg, isLong); + + // if we found an option go on with processing + if ((curOpt != NULL) && (curOpt->number != 0)) { + if (processOption(arg, curOpt, isLong) == false) { + m_number = NOARG; + } else { + m_number = curOpt->number; + } + } else { + //cout << "no option: " << arg << endl; + m_arg = arg; + m_number = UNKNOWN; + } + } + } + return m_number; +} + +int OptsParser::getRawOption() { + m_number = FINISH; + m_curarg += m_tonext; + if (m_curarg < m_argv.size()) { + m_tonext = 1; + m_opt = m_arg = ""; + m_arg = m_argv[m_curarg]; + m_number = NOOPTION; + } + return m_number; +} + +const Puma::OptsParser::Option* OptsParser::findOption(const std::string &arg, bool isLong) { + unsigned int keyLen; + std::string curName; + const Option *curOpt = m_opts; + const Option *selOpt = NULL; + unsigned int selOptLength = 0; + + // search for long option name in arg + while (curOpt->number != 0) { + if ((isLong == true) && (curOpt->longName != NULL)) { + keyLen = ParserKey::getLongKeyLength(); + curName = curOpt->longName; + } else if (curOpt->shortName != NULL) { + keyLen = ParserKey::getKeyLength(); + curName = curOpt->shortName; + } else { + curName = ""; + keyLen = 0; + } + /* Select option if: + * - name is not null AND + * - selected option is either null OR shorter than + * the currently analyzed option AND + * - the current option receives a parameter OR is exactly as long + * as passed argument AND + * - the string passed as argument starts at the position after + * the option key + */ + if ((!curName.empty()) && ((selOpt == NULL) || (selOptLength <= curName.length())) + && ((curOpt->argType != AT_NONE) || ((arg.length() - keyLen) == curName.length())) && (arg.find(curName) == keyLen)) { + selOpt = curOpt; + selOptLength = curName.length(); + } + curOpt++; + } + return selOpt; +} + +// process option and option argument. +// there can AT_NONE, a AT_MANDATORY or an AT_OPTIONAL option argument. +bool OptsParser::processOption(const std::string &arg, const Option* curOpt, bool isLong) { + unsigned int len; + + if (isLong == true) { + len = (ParserKey::getLongKeyLength() + strlen(curOpt->longName)); + } else { + len = (ParserKey::getKeyLength() + strlen(curOpt->shortName)); + } + + // set current option + m_opt = arg.substr(0, len); + + // if there should be no argument provided do not proceed + if (curOpt->argType == AT_NONE) { + return true; + } + + // if there are characters behind the end of the option name, + // treat them as option parameter + if (arg.length() > len) { + m_arg = arg.substr(len, arg.length() - len); + } + // if ARGV contains at least one more element + // check if it is an option argument + else if ((m_curarg + 1) < m_argv.size()) { + // if the next element of ARGV is NOT an other option treat it as option argument + // otherwise m_arg will continue containing an empty string + const std::string &next_argv(m_argv[m_curarg + 1]); + if (!((ParserKey::isLongKey(next_argv) && next_argv.length() > ParserKey::getLongKeyLength()) + || (ParserKey::isKey(next_argv) && next_argv.length() > ParserKey::getKeyLength()))) { + m_arg = next_argv; + ++m_tonext; + } + } + + // return false if there should be an argument + if (m_arg.empty() && curOpt->argType == AT_MANDATORY) { + return false; + } + + return true; +} + +int OptsParser::getResult() const { + return m_number; +} + +const std::string &OptsParser::getArgument() { + m_arg = strip(m_arg); + return m_arg; +} + +const std::string &OptsParser::getUnstrippedArgument() const { + return m_arg; +} + +const std::string &OptsParser::getOptionName() const { + return m_opt; +} + +int OptsParser::getCurrentArgNum() const { + return m_curarg; +} + +int OptsParser::getNextArgNum() const { + return m_curarg + m_tonext; +} + +} // namespace Puma diff --git a/Puma/src/common/OptsParser.h b/Puma/src/common/OptsParser.h new file mode 100644 index 0000000..8a49b47 --- /dev/null +++ b/Puma/src/common/OptsParser.h @@ -0,0 +1,176 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_OptsParser_H +#define PUMA_OptsParser_H + +/** \file + * Command line options parser. */ + +#include "Puma/SimpleParser.h" +#include +#include + +namespace Puma { + +/** \class OptsParser OptsParser.h Puma/OptsParser.h + * The options parser searches command line parameters for options and + * handles their option arguments, if applicable. + * \ingroup common */ +class OptsParser : public SimpleParser { + /** Vector holding the command line parameters. + * This vector is filled in the constructor */ + std::vector m_argv; + + /** Position of current parameter analyzed by the + * options parser. */ + unsigned int m_curarg; + + /** The increment added to m_curarg used to get to the next + * entry of m_argv which shall be analyzed. */ + unsigned int m_tonext; + + /** %Option number of currently processed element of m_argv. */ + int m_number; + + /** Name of current option. */ + std::string m_opt; + + /** Value of current option argument. */ + std::string m_arg; + +public: + /** Return codes for OptsParser::getOption() and OptsParser::getArgument(). */ + enum { + NOARG = -4, /**< %Option has no argument. */ + ERR = -3, /**< Error when parsing option. */ + NOOPTION = -2, /**< Command line parameter is not an option. */ + UNKNOWN = -1, /**< Parameter is an unknown option. */ + FINISH = 0 /**< All options are handled. */ + }; + + /** Type of argument associated to an option. */ + enum ArgType { + AT_NONE = 0, /**< %Option receives no argument. */ + AT_MANDATORY = 1, /**< %Option requires an argument. */ + AT_OPTIONAL = 2 /**< %Option has optionally an argument. */ + }; + + /** Type for specifying an array of options recognized by the %Option %Parser. + * An array of this type has to be passed to the constructor OptsParser::OptsParser() */ + struct Option { + int number; /**< Number associated with this option. */ + const char *shortName; /**< Short name of this option. Should ideally not contain more than one character */ + const char *longName; /**< Long name of this option. */ + const char *desc; /**< Description of this option. */ + ArgType argType; /**< Type of argument for this option. */ + }; + +private: + /** Pointer to array of available options. This value is set to the value of the + * parameter passed to the constructor OptsParser::OptsParser() */ + const Option *m_opts; + +public: + /** Constructor. + * \param argc Number of parameters to be analyzed. + * \param argv Parameters to be analyzed. + * \param opts Pointer to array of options which shall be recognized by the options parser. */ + OptsParser(int argc, char **argv, const Option *opts); + + /** Constructor. + * \param line Reference to string with parameters to analyze. + * The parameters are extracted from the string by splitting it up + * into tokens at: + * - space character + * - tabs + * - newline + * - carriage return + * \param opts Pointer to array of options which shall be + * recognized by the options parser */ + OptsParser(const std::string &line, const Option *opts); + + /** Get next parameter without modification. + * No option parsing is done. + * \return OptsParser::NOOPTION or OptsParser::FINISH. */ + int getRawOption(); + + /** Get next option. + * This function processes the next parameter passed to the constructor + * OptsParser::OptsParser(). + * That is, search for options and eventually process + * option and option argument. + * \return Number of options recognized by the options parser or + * OptsParser::NOARG, OptsParser::ERR, OptsParser::NOOPTION, + * OptsParser::UNKNOWN or OptsParser::FINISH. */ + int getOption(); + + /** Get result of last processed parameter. + * The number returned by this function is identical to the number + * returned by the last call of OptsParser::getOption. + * \return Number of options recognized by the options parser or + * OptsParser::NOARG, OptsParser::ERR, OptsParser::NOOPTION, + * OptsParser::UNKNOWN or OptsParser::FINISH. */ + int getResult() const; + + /** Get option argument of last processed parameter. + * This function returns the argument of the option processed during + * OptsParser::getOption. If the option does not provide any argument + * the string will be empty. + * If OptsParser::getOption or respectively OptsParser::getResult returns with + * OptsParser::NOOPTION this function (OptsParser::getArgument) returns the last processed parameter, + * which is no option, of course. + * \return Argument of last processed parameter */ + const std::string &getArgument(); + + /** Get option argument of last processed parameter without stripping. + * This function returns the argument of the option processed during + * OptsParser::getOption. If the option does not provide any argument + * the string will be empty. + * If OptsParser::getOption or respectively OptsParser::getResult returns with + * OptsParser::NOOPTION this function (OptsParser::getArgument) returns the last processed parameter, + * which is no option, of course. + * \return Argument of last processed parameter */ + const std::string &getUnstrippedArgument() const; + + /** Get option name of last processed parameter. + * If the last processed parameter did not contain an option the string + * returned by this function is empty. + * \return Name of last processed parameter */ + const std::string &getOptionName() const; + + /** Get position of current argument. + * \return Position of currently processed parameter previously passed to OptsParser::OptsParser() */ + int getCurrentArgNum() const; + + /** Get position of next argument. + * \return Position of next parameter which will be processed by the options parser */ + int getNextArgNum() const; + +private: + /** Search for an option in m_argv at position m_curarg. + * \param arg Currently processed parameter */ + const Option* findOption(const std::string &arg, bool isLong); + + /** Process an option found by OptsParser::findOption(). */ + bool processOption(const std::string &arg, const Option* curOpt, bool isLong); +}; + +} // namespace Puma + +#endif /* PUMA_OptsParser_H */ diff --git a/Puma/src/common/ParserKey.h b/Puma/src/common/ParserKey.h new file mode 100644 index 0000000..519a5ed --- /dev/null +++ b/Puma/src/common/ParserKey.h @@ -0,0 +1,73 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_ParserKey_H +#define PUMA_ParserKey_H + +/** \file + * Options parser key helper. */ + +#include + +namespace Puma { + +/** \class ParserKey ParserKey.h Puma/ParserKey.h + * Options parser key helper. Supports Unix-like short key '-' + * and long key '--'. + * \ingroup common */ +class ParserKey { +public: + /** Get the short key character. + * \return The short key character. */ + static char getKey() { + return '-'; + } + /** Get the long key character sequence. + * \return The long key character sequence. */ + static const char *getLongKey() { + return "--"; + } + /** Get the length of the short key. + * \return The length. */ + static unsigned int getKeyLength() { + return 1; + } + /** Get the length of the long key. + * \return The length. */ + static unsigned int getLongKeyLength() { + return 2; + } + /** Check if the given string starts with the short key. + * The string may still start with a long key, so check + * this first. + * \param str The string to check. + * \return True if it starts with the short key. */ + static bool isKey(const std::string &str) { + return str.length() > 0 && str[0] == getKey(); + } + /** Check if the given string starts with the long key. + * \param str The string to check. + * \return True if it starts with the long key. */ + static bool isLongKey(const std::string &str) { + return str.find(getLongKey()) == 0; + } +}; + +} // namespace Puma + +#endif /* PUMA_ParserKey_H */ diff --git a/Puma/src/common/PathInfo.cc b/Puma/src/common/PathInfo.cc new file mode 100644 index 0000000..c29f764 --- /dev/null +++ b/Puma/src/common/PathInfo.cc @@ -0,0 +1,74 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 "Puma/PathInfo.h" +#include "Puma/StrCol.h" +#include +#include + +namespace Puma { + +PathInfo::PathInfo(const PathInfo &pi) { + *this = pi; +} + +PathInfo::~PathInfo() { + if (m_srcPath) + delete[] m_srcPath; + if (m_srcPathCanonical) + delete[] m_srcPathCanonical; + if (m_destPath) + delete[] m_destPath; +} + +// Needed for class Array. +PathInfo &PathInfo::operator =(const PathInfo &pi) { + src(pi.src()); + srcCanonical(pi.srcCanonical()); + dest(pi.dest()); + return *this; +} + +// Set the source path. +void PathInfo::src(const char *path) { + if (!path) + return; + if (m_srcPath) + delete[] m_srcPath; + m_srcPath = StrCol::dup(path); +} + +// Set the canonical source path. +void PathInfo::srcCanonical(const char *path) { + if (!path) + return; + if (m_srcPathCanonical) + delete[] m_srcPathCanonical; + m_srcPathCanonical = StrCol::dup(path); +} + +// Set the destination path. +void PathInfo::dest(const char *path) { + if (m_destPath) + delete[] m_destPath; + m_destPath = (const char*) 0; + if (path) + m_destPath = StrCol::dup(path); +} + +} // namespace Puma diff --git a/Puma/src/common/PathInfo.h b/Puma/src/common/PathInfo.h new file mode 100644 index 0000000..a492eea --- /dev/null +++ b/Puma/src/common/PathInfo.h @@ -0,0 +1,79 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_PathInfo_H +#define PUMA_PathInfo_H + +/** \file + * Path information implementation. */ + +namespace Puma { + +/** \class PathInfo PathInfo.h Puma/PathInfo.h + * A path information object consists of a source and optionally + * its destination path. For comparison purposes the canonical version + * of the source path can be stored. + * \ingroup common */ +class PathInfo { + const char *m_srcPath; + const char *m_srcPathCanonical; + const char *m_destPath; + +public: + /** Contruct a new empty path information object. */ + PathInfo() + : m_srcPath(0), m_srcPathCanonical(0), m_destPath(0) { + } + /** Copy-constructor. + * \param other The other path information object to copy. */ + PathInfo(const PathInfo &other); + /** Destroy this object and free the stored paths. */ + ~PathInfo(); + + /** Assign another path information object to this one. + * \param other The other path information object to copy. + * \return A reference to this object. */ + PathInfo &operator =(const PathInfo &other); + + /** Set the source path.*/ + void src(const char *path); + /** Set the canonical variant of the source path.*/ + void srcCanonical(const char *path); + /** Set the destination path.*/ + void dest(const char *path); + + /** Get the source path. + * \return The source path. */ + const char *src() const { + return m_srcPath; + } + /** Get the canonical variant of the source path. + * \return The canonical source path. */ + const char *srcCanonical() const { + return m_srcPathCanonical; + } + /** Get the destination path. + * \return The destination path. */ + const char *dest() const { + return m_destPath; + } +}; + +} // namespace Puma + +#endif /* PUMA_PathInfo_H */ diff --git a/Puma/src/common/PathIterator.cc b/Puma/src/common/PathIterator.cc new file mode 100644 index 0000000..b0297a8 --- /dev/null +++ b/Puma/src/common/PathIterator.cc @@ -0,0 +1,48 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 "Puma/PathIterator.h" +#include "Puma/ErrorStream.h" +#include "Puma/RegComp.h" + +namespace Puma { + +PathIterator::PathIterator(const char *pat) { + ErrorStream err; + m_searchPattern = new RegComp(pat ? pat : (const char*) ".*"); + m_searchPattern->comperror(err); +} + +PathIterator::~PathIterator() { + if (m_searchPattern) + delete m_searchPattern; +} + +// Set the search pattern. +void PathIterator::pattern(const char *pat) { + if (m_searchPattern) + delete m_searchPattern; // Match anything. + m_searchPattern = new RegComp(pat ? pat : (const char*) ".*"); +} + +// retrieve information about the currently matching file +const char *PathIterator::file() const { + return m_currentFile.c_str(); +} + +} // namespace Puma diff --git a/Puma/src/common/PathIterator.h b/Puma/src/common/PathIterator.h new file mode 100644 index 0000000..e470af3 --- /dev/null +++ b/Puma/src/common/PathIterator.h @@ -0,0 +1,69 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_PathIterator_H +#define PUMA_PathIterator_H + +/** \file + * Iterator implementation for paths. */ + +#include +#include + +namespace Puma { + +class PathManager; +class RegComp; + +// A path iterator is used to iterate the contents of the paths +// a project is managing. But only files matching a given pattern +// are iterated. + +/** \class PathIterator PathIterator.h Puma/PathIterator.h + * A path iterator is used to iterate the contents of the paths + * a project is managing. Only files matching a given pattern + * are found. + * To be used with PathManager::iterate(). + * \ingroup common */ +class PathIterator { + friend class PathManager; + + RegComp *m_searchPattern; + std::list m_matchingFiles; + std::list::const_iterator m_fileIterator; + std::string m_currentFile; + +public: + /** Construct a new iterator. + * \param pattern Regular expression for the files to match. */ + PathIterator(const char *pattern); + /** Destroy the iterator. */ + ~PathIterator(); + + /** Set the regular expression for the files to match. + * \param pattern The regular expression. */ + void pattern(const char *pattern); + + /** Get the current file matched. + * \return The path to the file. */ + const char *file() const; +}; + +} // namespace Puma + +#endif /* PUMA_PathIterator_H */ diff --git a/Puma/src/common/PathManager.cc b/Puma/src/common/PathManager.cc new file mode 100644 index 0000000..b0089c6 --- /dev/null +++ b/Puma/src/common/PathManager.cc @@ -0,0 +1,424 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 "Puma/Config.h" +#include "Puma/PathIterator.h" +#include "Puma/ErrorStream.h" +#include "Puma/PathManager.h" +#include "Puma/RegComp.h" +#include "Puma/SysCall.h" +#include +#include + +#ifdef _MSC_VER +#define PATH_MAX _MAX_PATH +#endif + +// ensure that maximal path length is at least 65536 characters +#if !defined(PATH_MAX) || PATH_MAX < 65536 +#undef PATH_MAX +#define PATH_MAX 65536 +#endif + +namespace Puma { + +PathManager::~PathManager() { + for (int i = numProts() - 1; i >= 0; i--) + delete m_writeProtectedPathPatterns[i]; +} + +// Join the paths of the given manager with the paths +// of this path manager. +void PathManager::join(PathManager &pm) { + for (int i = 0; i < pm.numPaths(); i++) + addPath(pm.src(i), pm.dest(i)); + for (int i = 0; i < pm.numProts(); i++) + m_writeProtectedPathPatterns.append(new RegComp(*pm.prot(i))); +} + +// Add the separator '/' to the copy of the given string. +char *PathManager::addSeparator(const char *s) const { + if (!s) + return (char*) 0; + int pos = strlen(s); + + char *str = new char[pos + 2]; + strcpy(str, s); + if (str[pos - 1] != '/') // Add a trailing '/'. + strcat(str, "/"); + return str; +} + +// Add the separator '/' to the copy of the given string. +char *PathManager::addSeparator(const char *s, char *buf) const { + if (!s) + return (char*) 0; + int len = strlen(s); + if (len >= PATH_MAX) + len = PATH_MAX - 2; + memcpy(buf, s, len); + if (s[len - 1] != '/') { + buf[len] = '/'; // Add a trailing '/'. + len++; + } + buf[len] = '\0'; + return buf; +} + +// Add a new source directory. +void PathManager::addPath(const char *source, const char *destination) { + if (source) { + char newsrc[PATH_MAX]; + addSeparator(source, newsrc); + + // Don't add a source directory twice. + // Don't add a sub-directory of an existing source directory. + for (int pos = numPaths() - 1; pos >= 0 && src(pos); pos--) + if (strncmp(src(pos), newsrc, strlen(src(pos))) == 0) + return; + + // Add canonical filename representation + Filename dir_abs; + if (!canonFilename(newsrc, dir_abs)) + return; + m_paths[numPaths()].srcCanonical(dir_abs.name()); + + // Add the source path. + m_paths[numPaths() - 1].src(newsrc); + + if (destination) { + // Add the destination path. + char newdest[PATH_MAX]; + addSeparator(destination, newdest); + m_paths[numPaths() - 1].dest(newdest); + } + } else if (destination) { + // Add the destination path. + char newdest[PATH_MAX]; + addSeparator(destination, newdest); + m_paths[numPaths()].dest(newdest); + m_paths[numPaths() - 1].src(0); + } +} + +// find the canonical filename representation for a file +bool PathManager::canonFilename(Filename name, Filename &abs_name) const { + std::string file_abs = ""; + const char *path = name.path(); + if (strcmp(path, "") == 0) + path = "."; + + Filename canon_file, canon_dir; + if (SysCall::canonical(name, canon_file)) + file_abs = canon_file.name(); + else if (SysCall::canonical(name.path(), canon_dir)) { + file_abs = canon_dir.name(); + const char *nodir = strrchr(name.name(), '/'); + if (!nodir) + nodir = strrchr(name.name(), '\\'); + if (nodir) + file_abs += nodir; + } else + return false; // neither file nor directory exist + + abs_name.name(file_abs.c_str()); + return true; +} + +// checks if a give file (by name) is a registered file of this path manager +// In case of success (found!) the an iterator is returned, which can be +// used to access more information about the file. +bool PathManager::isBelow(const char *file, ProjectFile::MapConstIter &iter) const { + // determine the canonical name (which has to exist) + Filename file_abs; + if (!canonFilename(file, file_abs)) + return false; + + // search for the name and return the result + iter = m_files.find(std::string(file_abs.name())); + + // all files stored in the map belong to the project + if (iter != m_files.end()) + return true; + + // otherwise check if any project path is a prefix of the canonical filename + bool found = false; + for (int pos = numPaths() - 1; pos >= 0 && src(pos); pos--) { + int prefix_len = strlen(src_canon(pos)); + if ((strncmp(src_canon(pos), file_abs.name(), prefix_len) == 0) && (file_abs.name()[prefix_len] == '/' || file_abs.name()[prefix_len] == '\\')) { + found = true; + break; + } + } + + // if the file does not belong to the project, return false + if (!found) + return false; + + // otherwise store it in the list and return true + std::pair insert_result = m_files.insert(ProjectFile::MapPair(std::string(file_abs.name()), ProjectFile(file))); + iter = insert_result.first; + return true; +} + +// Add a new file to the project file list +ProjectFile::MapConstIter PathManager::addFile(const ProjectFile &file) { + Filename file_abs; + bool have_canon = canonFilename(file.name(), file_abs); + if (!have_canon) { + assert(false); + return m_files.end(); + } + + // insert the file with its canonical name as the key + std::pair insert_result = m_files.insert(ProjectFile::MapPair(std::string(file_abs.name()), file)); + + // return the iterator + return insert_result.first; +} + +// Add a new file to the project file list +ProjectFile::MapConstIter PathManager::addFile(Filename file) { + return addFile(ProjectFile(file)); +} + +// Add a new file to the project file list with destination path +ProjectFile::MapConstIter PathManager::addFile(Filename name, Filename dest) { + return addFile(ProjectFile(name, dest)); +} + +// Set the destination directory of the given source directory. +void PathManager::setDest(const char *source, const char *destination) { + if (!source) + return; + + // Search the corresponding path info object. + int pos; + for (pos = numPaths() - 1; pos >= 0 && src(pos); pos--) + if (strcmp(src(pos), source) == 0) + break; + if (pos < 0) + return; // Source path doesn't exist. + if (destination) { + // Set the destination path. + char newdest[PATH_MAX]; + addSeparator(destination, newdest); + m_paths[pos].dest(newdest); + } else + m_paths[pos].dest(destination); +} + +// Configure the project from the command line or a file. +void PathManager::configure(const Config &c) { + const ConfOption *d = 0, *p = 0; + + unsigned num = c.Options(); + for (unsigned i = 0; i < num; i++) { + const ConfOption *o = c.Option(i); + bool new_p = false, new_d = false; + + if (!strcmp(o->Name(), "-w")) { + if (o->Arguments() != 1) + continue; + protect(o->Argument(0)); + } else if (!strcmp(o->Name(), "-p")) { + if (o->Arguments() != 1) + continue; + new_p = true; + } else if (!strcmp(o->Name(), "-d")) { + if (o->Arguments() != 1) + continue; + new_d = true; + } + + if (new_p) { + if (p) { + addPath(p->Argument(0), d ? d->Argument(0) : 0); + if (d) + d = 0; + } + p = o; + } + + if (new_d) { + if (d) { + addPath(p ? p->Argument(0) : 0, d->Argument(0)); + if (p) + p = 0; + } + d = o; + } + } + + if (p || d) + addPath(p ? p->Argument(0) : 0, d ? d->Argument(0) : 0); +} + +// Initial globbing implementation. +void PathManager::glob(char *pattern) { + // Explore the source directories of the manager and for + // any file matching the given pattern call the method + // action(filename). The default pattern is ".*". + PathIterator iter(pattern); + while (iterate(iter)) + action(iter); +} + +// Iterate the contents of the paths. +bool PathManager::iterate(PathIterator &iter) const { + // a new iterator should start at the beginning + if (iter.m_currentFile.empty()) { + char path[PATH_MAX + 1]; + for (int pos = numPaths() - 1; pos >= 0 && src(pos); pos--) { + strcpy(path, src(pos)); + traverse(path, strlen(path), iter.m_searchPattern, iter.m_matchingFiles); + } + iter.m_fileIterator = iter.m_matchingFiles.begin(); + } + + bool result = false; + if (iter.m_fileIterator == iter.m_matchingFiles.end()) { + iter.m_currentFile = std::string(); + } else { + iter.m_currentFile = *iter.m_fileIterator; + ++(iter.m_fileIterator); + result = true; + } + return result; +} + +// find all files of a directory tree and add them to _files +void PathManager::traverse(char *path, size_t pathLength, RegComp *filenamePattern, std::list &hits) const { + // Prepare the current path prefix + if (path[pathLength - 1] != '/') { + if (pathLength >= PATH_MAX - 1) { + err() << sev_error << "path name too long: " << path << endMessage; + return; + } + path[pathLength] = '/'; + pathLength++; + path[pathLength] = '\0'; + } + + // open the current directory + DirHandle dp = SysCall::opendir(path, &err()); + if (!dp) { // Skip the directory, may be an access problem. + err() << sev_error << "Couldn't open directory `" << path << "'." << endMessage; + return; + } + + // Read the current directory entries. + const char *entry; + DirEntryType det; + while ((entry = SysCall::readdir(dp, &det, &err()))) { + // Create the full name of the current entry, e.g. /tmp/file.c. + size_t l = strlen(entry); + if (pathLength + l >= PATH_MAX) { + err() << sev_error << "path name too long: " << path << entry << endMessage; + continue; + } + memcpy(path + pathLength, entry, l); + path[pathLength + l] = '\0'; + + // Read the attributes of the current entry. + if (det == DET_NOT_IMPLEMENTED || det == DET_OTHER) { + FileInfo fi; + if (!SysCall::stat(path, fi, &err())) + continue; + if (fi.is_dir()) + det = DET_DIRECTORY; + else + det = DET_REGULAR; + } + + // Test whether entry is a directory. + if (det == DET_DIRECTORY) { + traverse(path, pathLength + l, filenamePattern, hits); // Dive into the sub-directory. + } else { + const char *filename = path; + // File entry found. + if (pathLength + l > 1 && *path == '.' && *(path + 1) == '/') + filename += 2; + if (filenamePattern->match(filename)) { + hits.push_back(filename); + } + } + } + + // Close the current directory and go one up. + SysCall::closedir(dp, &err()); +} + +// Add a regular pattern specifying a path that has to be +// protected from writing. +void PathManager::protect(const char *path) { + if (path) + m_writeProtectedPathPatterns.append(new RegComp(path)); +} + +// Return true if the given file or path is protected +// from writing or if it isn't located within one of the +// source directories, because then it's protected, too. +bool PathManager::isProtected(const char *file) const { + if (!file) + return false; + + // Protected by protect patterns? + for (int i = numProts() - 1; i >= 0; i--) { + if (prot(i)->match(file)) + return true; + } + + // From outside the source directories? + return !isBelow(file); +} + +const char *PathManager::getDestination(Filename file, std::ostream *name) const { + // determine the canonical name (which has to exist) + Filename file_abs; + if (!canonFilename(file, file_abs)) + return 0; + + for (int i = numPaths() - 1; i >= 0 && src(i); i--) { + // get the canonical filename representation of the current path + const char* dir_abs = src_canon(i); + // is it a prefix of the filename? + int len = strlen(dir_abs); + if (strncmp(dir_abs, file_abs.name(), len) == 0 && *(file_abs.name() + len) == '/') { + if (name) + *name << file_abs.name() + len + 1; + return dest(i); + } + } + return 0; +} + +bool PathManager::getDestinationPath(const char *filename, std::ostream &out) const { + std::ostringstream rest; + const char *dir = getDestination(filename, &rest); + if (dir) { + out << dir; + if (dir[strlen(dir) - 1] != '/') + out << "/"; + out << rest.str().c_str(); + return true; + } + return false; +} + +} // namespace Puma diff --git a/Puma/src/common/PathManager.h b/Puma/src/common/PathManager.h new file mode 100644 index 0000000..0f9619f --- /dev/null +++ b/Puma/src/common/PathManager.h @@ -0,0 +1,227 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2016 The PUMA developer team. +// +// 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 PUMA_PathManager_H +#define PUMA_PathManager_H + +/** \file + * Source and destination path and file management. */ + +#include "Puma/Array.h" +#include "Puma/PathInfo.h" +#include "Puma/Filename.h" +#include "Puma/ErrorStream.h" +#include "Puma/PathIterator.h" +#include "Puma/ProjectFile.h" +#include +#include + +namespace Puma { + +class RegComp; +class Config; +class Unit; + +/** \class PathManager PathManager.h Puma/PathManager.h + * Source and destination path and file management. Source paths are + * mapped to their destination paths. The source tree can be iterated + * and new files can be added. + * \ingroup common */ +class PathManager { + ErrorStream *m_err; + Array m_paths; + Array m_writeProtectedPathPatterns; + mutable ProjectFile::Map m_files; + +private: + /** Find all files of a directory tree matching the given pattern + * and add them to the project file map. + * \param path The path to the directory to traverse. + * \param pathLength The length of the path name. + * \param filenamePattern Regular expression for the filenames to match. + * \param hits List of files found. */ + void traverse(char *path, size_t pathLength, RegComp *filenamePattern, std::list &hits) const; + + /** Calculate the canonical filename representation for a file + * and write it into abs_name. + * \param name The filename. + * \param abs_name Container for the calculated canonical filename. */ + bool canonFilename(Filename name, Filename &abs_name) const; + + /** Add a new file to the project file list. + * \param file The file to add. + * \return An iterator pointing to the added file. */ + ProjectFile::MapConstIter addFile(const ProjectFile &file); + +protected: + /** Get the destination path for a given source path. + * \param sourcePath The source path. + * \param destinationPath Optional output stream for the destination path. + * \return The destination path. */ + const char *getDestination(Filename sourcePath, std::ostream *destinationPath = 0) const; + + /** Called for every matched file when traversing a source path. + * \param iterator The path iterator pointing to the current file. */ + virtual void action(PathIterator &iterator) { + } + + /** Add the separator '/' to the end of the given path. + * \param path The path. + * \return A copy of the path followed by the separator. */ + char *addSeparator(const char *path) const; + /** Add the separator '/' to the end of the given path + * and store the resulting path in the given buffer. + * \param path The path. + * \param buffer The buffer. + * \return The buffer containing the path followed by the separator. */ + char *addSeparator(const char *path, char *buffer) const; + +public: + /** Constructor. + * \param err Error stream used to report errors. */ + PathManager(ErrorStream &err) + : m_err(&err) { + } + /** Copy-constructor. + * \param other The other path manager to copy. */ + PathManager(PathManager &other) { + m_err = other.m_err; + join(other); + } + /** Destructor. */ + virtual ~PathManager(); + + /** Search files in the managed path matching the given filename pattern or every + * file if no pattern is given. Calls action() for every match. + * \param filenamePattern Optional regular expression for the filenames to match. */ + void glob(char *filenamePattern = 0); + + /** Iterate the contents of the managed paths. Calls action() for every file found. + * \param iterator The path iterator to use. */ + bool iterate(PathIterator &iterator) const; + + /** Add a source and destination paths pair. + * \param srcPath The source path. + * \param destPath The corresponding destination path. */ + virtual void addPath(const char *srcPath, const char *destPath = 0); + + /** Add a new file to the project file list + * \param filename The filename. + * \return An iterator pointing to the file added. */ + ProjectFile::MapConstIter addFile(Filename filename); + + /** Add a new file to the project file list + * \param filename The filename. + * \param destPath The corresponding destination path. + * \return An iterator pointing to the file added. */ + ProjectFile::MapConstIter addFile(Filename filename, Filename destPath); + + /** Set the destination path of the given source path. + * \param srcPath The source path. + * \param destPath The destination path. */ + void setDest(const char *srcPath, const char *destPath); + + /** Add a pattern for a write-protected path. + * \param pathPattern Regular expression for a path to write-protect. */ + void protect(const char *pathPattern); + + /** Get the number of managed paths. + * \return The number of managed paths. */ + long numPaths() const { + return m_paths.length(); + } + /** Get the number of managed write-protected paths. + * \return The number of write-protected paths. */ + long numProts() const { + return m_writeProtectedPathPatterns.length(); + } + /** Get the n-th managed source path. + * \param n The position of the path in the path list. + * \return The source path. */ + const char *src(long n) const { + return m_paths.lookup(n).src(); + } + /** Get canonical version of the n-th managed source path. + * \param n The position of the path in the path list. + * \return The canonical source path. */ + const char *src_canon(long n) const { + return m_paths.lookup(n).srcCanonical(); + } + /** Get the n-th managed destination path. + * \param n The position of the path in the path list. + * \return The destination path. */ + const char *dest(long n) const { + return m_paths.lookup(n).dest(); + } + /** Get the n-th managed write-protected path pattern. + * \param n The position of the path pattern in the path pattern list. + * \return The write-protected path pattern. */ + RegComp *prot(long n) const { + return m_writeProtectedPathPatterns.lookup(n); + } + + /** Check if the given path is write-protected. + * \param path The path. + * \return True if the path is write-protected. */ + bool isProtected(const char *path) const; + + /** Check if a given file is directly managed by this path manager or + * is found below any of the managed paths. If the file is found then + * its position is stored in the given iterator. + * \param filename The filename. + * \param iterator The iterator to store the position of the file. + * \return True if the file was found. */ + bool isBelow(const char *filename, ProjectFile::MapConstIter &iterator) const; + + /** Check if a given file is directly managed by this path manager or + * is found below any of the managed paths. + * \param filename The filename. + * \return True if the file was found. */ + virtual bool isBelow(const char *filename) const; + + /** Configure the path manager. + * \param config The configuration. */ + virtual void configure(const Config &config); + + /** Join the paths of the given manager with the paths + * of this path manager. + * \param other The other path manager. */ + virtual void join(PathManager &other); + + /** Get the error stream used by this path manager. + * \return A reference to the error stream. */ + ErrorStream &err() const { + return *m_err; + } + + /** Get the destination path of a given source path and write + * it on the given output stream. + * \param sourcePath The source path. + * \param out The output stream. + * \return True if the destination path was found. */ + bool getDestinationPath(const char *sourcePath, std::ostream &out) const; +}; + +inline bool PathManager::isBelow(const char *file) const { + ProjectFile::MapConstIter iter; + return isBelow(file, iter); +} + +} // namespace Puma + +#endif /* PUMA_PathManager_H */ diff --git a/Puma/src/common/Project.cc b/Puma/src/common/Project.cc new file mode 100644 index 0000000..f6baca4 --- /dev/null +++ b/Puma/src/common/Project.cc @@ -0,0 +1,462 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2016 The PUMA developer team. +// +// 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 "Puma/ErrorStream.h" +#include "Puma/FileSource.h" +#include "Puma/FileUnit.h" +#include "Puma/MacroUnit.h" +#include "Puma/RegComp.h" +#include "Puma/Project.h" +#include "Puma/SysCall.h" +#include "Puma/StrCol.h" +#include "Puma/Config.h" +#include "Puma/Unit.h" +#include +#include +#ifdef _MSC_VER +#include +#define PATH_MAX _MAX_PATH +#endif + +namespace Puma { + +extern const char *GPL_HEADER; + +Project::Project(ErrorStream &e) + : PathManager(e), m_unitManager(e), m_filenameSuffix((const char*) 0), m_saveMode(OVERWRITE) { +} + +Project::~Project() { + if (m_filenameSuffix) + delete[] m_filenameSuffix; +} + +// Configure the project from the command line or a file. +void Project::configure(const Config &c) { + const char *suffix = m_filenameSuffix; + Mode mode = m_saveMode; + + unsigned num = c.Options(); + for (unsigned i = 0; i < num; i++) { + const ConfOption *o = c.Option(i); + if (!strcmp(o->Name(), "--save-overwrite")) + mode = OVERWRITE; + else if (!strcmp(o->Name(), "--save-rename-old")) + mode = RENAME_OLD; + else if (!strcmp(o->Name(), "--save-new-suffix")) + mode = NEW_SUFFIX; + else if (!strcmp(o->Name(), "-s") || !strcmp(o->Name(), "--suffix")) { + if (o->Arguments()) + suffix = o->Argument(0); + } + } + saveMode(mode, suffix); + + // Configure the basic path manager, too. + PathManager::configure(c); +} + +// Set the mode for saving a unit. +void Project::saveMode(Mode mode, const char *suffix) { + if (suffix) { + if (m_filenameSuffix) + delete[] m_filenameSuffix; + m_filenameSuffix = StrCol::dup(suffix); + + if (mode == OVERWRITE || mode == RENAME_OLD || mode == NEW_SUFFIX) + m_saveMode = mode; + } else + m_saveMode = OVERWRITE; +} + +// Save a unit to a file. +bool Project::makeDirHierarchy(Filename path) const { + + // Remember where we are. + char cwd[PATH_MAX]; + if (SysCall::getcwd(cwd, PATH_MAX, &err()) == 0) + return false; + + // Change into the directory and create every missing one + char *path_copy = StrCol::dup(path.name()); + char *p = path_copy; + + // TODO: here is a problem with different drives on Windows!!! + if (path.is_absolute()) { + SysCall::chdir(path.root(), &err()); + p += strlen(path.root()); + } + + char *curr = p; + while (*p != '\0') { + if (*p == '/') { + *p = '\0'; + if (strlen(curr) && !makeDir(curr)) { + delete[] path_copy; + return false; + } + curr = p + 1; + } + p++; + } + + delete[] path_copy; + + // Go back + SysCall::chdir(cwd, &err()); + + return true; +} + +// Save a unit to a file. +void Project::save(Unit *unit, bool only_modified) const { + if (!unit) + return; + if (!unit->name()) + return; + + // Save only units that have changed, or all if allowed. + if (!unit->state().isModified() && only_modified) + return; + + // Do not write files to protected paths or files from outside the + // source directories. + if (isProtected(unit->name())) + return; + + // determine the destination path of the file + ProjectFile::MapConstIter iter; + if (!PathManager::isBelow(unit->name(), iter)) { + assert(false); // if we came here, the file should be registered + return; + } + ProjectFile &project_file = (ProjectFile&) iter->second; + Filename dest = project_file.dest(); + if (!dest.is_defined()) { + // determine the destination path + std::ostringstream path; + if (!getDestinationPath(unit->name(), path)) + return; + std::string dest_path = path.str(); + project_file.dest(dest_path.c_str()); + dest = project_file.dest(); + } + + // make sure that the directory for the file exists + if (!makeDirHierarchy(dest)) + return; + + char *file = (char*) dest.name(); + bool release_file = false; + + // A suffix is given. + if (m_filenameSuffix && m_saveMode != OVERWRITE) { + char *newname, *dot; + + // Rename the old file by adding the suffix to the + // name of that file. + if (m_saveMode == RENAME_OLD) { + newname = new char[strlen(file) + strlen(m_filenameSuffix) + 1]; + sprintf(newname, "%s%s", file, m_filenameSuffix); + rename(file, newname); + } + + // Save the file with a new suffix. + else { + newname = StrCol::dup(file); + dot = strrchr(newname, '.'); + if (dot) + *dot = '\0'; + file = new char[strlen(newname) + strlen(m_filenameSuffix) + 2]; + release_file = true; + sprintf(file, "%s.%s", newname, m_filenameSuffix); + } + + delete[] newname; + } + + // Check whether the file has to be updated. + if (isFileOutdated(file, unit)) { + // Write the file to disk. + std::ofstream out(file, std::ios::out); + write(unit, out); + } + + // Update the state of the unit (modification flag, + // last modification time, last save location). + updateUnitState(file, unit); + + if (release_file) + delete[] file; +} + +bool Project::isFileOutdated(const char *file, Unit *unit) const { + if (unit->state().lastModified()) { + FileInfo fileinfo; + if (SysCall::stat(file, fileinfo) && unit->state().lastModified() <= fileinfo.modi_time()) { + return false; + } + } + return true; +} + +// Write the unit to the file. +void Project::write(Unit *unit, std::ofstream &out) const { + if (unit) { + out << GPL_HEADER; + unit->print(out); + } +} + +// Update the state of the given unit. +void Project::updateUnitState(const char *file, Unit *unit) const { + unit->state().unmodified(); + FileInfo fileinfo; + if (SysCall::stat(file, fileinfo, &err())) + unit->state().lastModified(fileinfo.modi_time()); + + if (unit->isFile()) { + // Remember the save location. + char buf[PATH_MAX]; + char *cwd = SysCall::getcwd(buf, PATH_MAX, &err()); + if (!cwd) + return; + + char *location = new char[strlen(cwd) + strlen(file) + 5]; + + if (cwd[strlen(cwd) - 1] == '/') + sprintf(location, "%s%s", cwd, file); + else + sprintf(location, "%s/%s", cwd, file); + + ((FileUnit*) unit)->setLocation(location); + + delete[] location; + } +} + +// Change to the directory, or create it if necessary. +bool Project::makeDir(const char *directory) const { + while (!SysCall::chdir(directory)) + if (!SysCall::mkdir(directory, &err())) { + err() << sev_error << "unable to create directory \"" << directory << "\"." << endMessage; + return false; + } + return true; +} + +// Save a FileUnit (or all) to a file (or files). +void Project::save(const char *file, bool only_modified, bool is_reg_ex) const { + UnitManager::UMap &umap = m_unitManager.getTable(); + + // No file name is given. Save ALL units. + if (!file) { + for (UnitManager::UMapIter iter = umap.begin(); iter != umap.end(); ++iter) { + Unit *unit = (*iter).second; + if (unit->isFile()) + save(unit, only_modified); + } + // A file name or a name pattern is given. + } else { + RegComp *regcomp = 0; + if (is_reg_ex) + regcomp = new RegComp(file); + + for (UnitManager::UMapIter iter = umap.begin(); iter != umap.end(); ++iter) { + Unit *unit = (*iter).second; + if (unit->isFile()) { + if (regcomp) { + if (regcomp->match(unit->name())) + save(unit, only_modified); + else + regcomp->comperror(err()); + } else if (strcmp(unit->name(), file) == 0) + save(unit, only_modified); + } + } + + if (regcomp) + delete regcomp; + } +} + +// Print an unit, regular expression for more units. +void Project::print(const char *name, std::ostream &out, bool is_reg_ex) const { + if (!name) + name = ".*"; + + RegComp *regcomp = 0; + if (is_reg_ex) + regcomp = new RegComp(name); + + UnitManager::UMap &umap = m_unitManager.getTable(); + + for (UnitManager::UMapIter iter = umap.begin(); iter != umap.end(); ++iter) { + Unit *unit = (*iter).second; + if (regcomp) { + if (regcomp->match(unit->name())) + unit->print(out); + else + regcomp->comperror(err()); + } else if (strcmp(unit->name(), name) == 0) + unit->print(out); + } + + if (regcomp) + delete regcomp; +} + +// Close a unit, regular expression for more units. +void Project::close(const char *name, bool destroy, bool is_reg_ex) const { + if (!name) { + if (destroy) + m_unitManager.discardAll(); + else + m_unitManager.discardAll(false); + return; + } + + RegComp *regcomp = 0; + if (is_reg_ex) + regcomp = new RegComp(name); + + UnitManager::UMap &umap = m_unitManager.getTable(); + + for (UnitManager::UMapIter iter = umap.begin(); iter != umap.end();) { + UnitManager::UMapIter entry = iter; + ++iter; + Unit *unit = (*entry).second; + if (regcomp) { + if (regcomp->match(unit->name())) + m_unitManager.discard(unit->name(), unit->isFile(), destroy); + else + regcomp->comperror(err()); + } else if (strcmp(unit->name(), name) == 0) { + m_unitManager.discard(unit->name(), unit->isFile(), destroy); + } + } + + if (regcomp) + delete regcomp; +} + +// Add a new file with destination filename to the project. +Unit *Project::addFile(Filename file, Filename dest) { + Unit *new_unit = new FileUnit; + new_unit->name(file.name()); + m_unitManager.add(new_unit); + PathManager::addFile(file, dest); + return new_unit; +} + +// Add a new file with destination filename to the project. +Unit *Project::addFile(Filename file) { + Unit *new_unit = new FileUnit; + new_unit->name(file.name()); + m_unitManager.add(new_unit); + PathManager::addFile(file); + return new_unit; +} + +bool Project::isNewer(const char *file) const { + if (!file) + return false; + + FileInfo fileinfo; + long last_modified; + + // 1. Get the last modification time of the source file. + + Unit *unit = m_unitManager.get(file, true); + // File already known and scanned. + if (unit) { + last_modified = unit->state().lastModified(); + if (!last_modified) + return true; // Manipulated unit. + // File not scanned up to now. Examine the file itself. + } else { + if (!SysCall::stat(file, fileinfo)) + return false; // File does not exists. + last_modified = fileinfo.modi_time(); + } + + // 2. Compare it with the last modification time of the file + // in the destination directory. + + // determine the destination path of the file + ProjectFile::MapConstIter iter; + if (!PathManager::isBelow(file, iter)) { + assert(false); // if we came here, the file should be registered + return false; + } + + ProjectFile &project_file = (ProjectFile&) iter->second; + Filename dest = project_file.dest(); + if (!dest.is_defined()) { + // determine the destination path + std::ostringstream path; + if (!getDestinationPath(file, path)) + return false; + std::string dest_path = path.str(); + project_file.dest(dest_path.c_str()); + dest = project_file.dest(); + } + + char *fullname = StrCol::dup(dest.name()); + + if (m_filenameSuffix && m_saveMode == RENAME_OLD) { + char *dot = strrchr(fullname, '.'); + if (dot) + *dot = '\0'; + char *tmp = new char[strlen(fullname) + strlen(m_filenameSuffix) + 2]; + sprintf(tmp, "%s.%s", fullname, m_filenameSuffix); + delete[] fullname; + fullname = tmp; + } + + bool newer = true; + if (SysCall::stat(fullname, fileinfo)) + if (last_modified <= fileinfo.modi_time()) + newer = false; + + delete[] fullname; + return newer; +} + +bool Project::isBelow(Unit *unit) const { + FileUnit *funit; + + if (unit) { + // if macro expansion unit, get the file containing the macro call + while (unit && unit->isMacroExp()) + unit = ((MacroUnit*) unit)->CallingUnit(); + + // must be a file unit + if (unit && unit->isFile()) { + funit = (FileUnit*) unit; + + // file belongs to project? + if (funit->belongsTo(*(Project*) this)) + return true; + } + } + + return false; +} + +} // namespace Puma diff --git a/Puma/src/common/Project.h b/Puma/src/common/Project.h new file mode 100644 index 0000000..9b00507 --- /dev/null +++ b/Puma/src/common/Project.h @@ -0,0 +1,161 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2016 The PUMA developer team. +// +// 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 PUMA_Project_H +#define PUMA_Project_H + +/** \file + * Project file handling. */ + +/** \page project File Handling + */ + +#include "Puma/PathManager.h" +#include "Puma/UnitManager.h" +#include "Puma/SaveMode.h" +#include +#include + +namespace Puma { + +/** \class Project Project.h Puma/Project.h + * A project is a set of source directories. It provides + * methods for searching and writing files. + * \ingroup common */ +class Project : public PathManager, public SaveMode { + UnitManager m_unitManager; + const char *m_filenameSuffix; + Mode m_saveMode; + +private: + /** Change current directory to the given, or create it if necessary. + * \param path The path to the directory. + * \return True if successfully changed the current directory. */ + bool makeDir(const char *path) const; + /** Create the directory hierarchy as given by path. + * \param path The path to the directory. + * \return True if directory created successfully. */ + bool makeDirHierarchy(Filename path) const; + /** Check if the given file needs to be updated. + * \param file The path to the file. + * \param unit The unit containing the contents of the file. + * \return True if the file needs to be updated. */ + bool isFileOutdated(const char *file, Unit *unit) const; + /** Update the modification state and save location of the given unit. + * \param file The path to the file. + * \param unit The unit containing the contents of the file. */ + void updateUnitState(const char *file, Unit *unit) const; + +protected: + /** Write a unit on the given file output stream. + * \param unit The input unit. + * \param file The output file. */ + virtual void write(Unit *unit, std::ofstream &file) const; + +public: + /** Constructor. + * \param err An error stream for reporting errors. */ + Project(ErrorStream &err); + /** Destructor. */ + virtual ~Project(); + + /** Set the mode for saving an unit. + * Mode OVERWRITE: Save the unit under its name and overwrite existing + * files. + * Mode RENAME_OLD: An existing file will be renamed. A suffix will be + * added to the name of the file, like 'main.cc.old' + * for the file 'main.cc' and the suffix '.old'. + * Mode NEW_SUFFIX: The unit will be saved with a new suffix, like + * 'main.cpp' for the unit 'main.cc' and the suffix + * 'cpp'. + * \param mode The save mode. + * \param suffix Optional filename suffix. */ + void saveMode(Mode mode = OVERWRITE, const char *suffix = 0); + + /** Save a unit using the name of the unit to get the full + * name of the file and path to save to. The save location + * must not be protected by a protect pattern and the original + * file must be located in one of the source directories. + * \param unit The unit to save. + * \param only_modified If true only modified units are saved. */ + virtual void save(Unit *unit, bool only_modified = false) const; + + /** Save one, all or all matching files. + * \param file Optional file name or file name pattern. + * \param only_modified If true only modified files are saved. + * \param is_reg_ex If true the given filename is a regular expression. */ + virtual void save(const char *file = 0, bool only_modified = false, bool is_reg_ex = false) const; + + /** Print one, all or all matching units. + * \param name Optional unit name or unit name pattern. + * \param out Output stream on which to print the unit(s), defaults to std::cout. + * \param is_reg_ex If true the given unit name is a regular expression. */ + void print(const char *name = 0, std::ostream &out = std::cout, bool is_reg_ex = false) const; + + /** Close one, all or all matching units. + * \param name Optional unit name or unit name pattern. + * \param destroy If true destroy the units when closed. + * \param is_reg_ex If true the given unit name is a regular expression. */ + void close(const char *name = 0, bool destroy = false, bool is_reg_ex = false) const; + + /** Add a new file to the project. + * \param file The path to the file to add. + * \return An empty file unit for the file to add. */ + Unit *addFile(Filename file); + /** Add a new file to the project. + * \param srcFile The path to the source file to add. + * \param destFile The path to the destination file. + * \return An empty file unit for the file to add. */ + Unit *addFile(Filename srcFile, Filename destFile); + + /** Configure the project from the command line or a file. + * \param config The configuration. */ + virtual void configure(const Config &config); + + /** Get the unit manager. + * \return A reference to the unit manager. */ + UnitManager &unitManager(); + + /** Check if the given file in the source directory + * or the unit is newer than the corresponding + * file in the destination directory. + * \param file The path to the file. + * \return True if destination file is older. */ + bool isNewer(const char *file) const; + + /** Check if a given file is found below any of the source paths of this project. + * \param file The file. + * \return True if the file was found. */ + virtual bool isBelow(const char *file) const; + /** Check if a given file is found below any of the source paths of this project. + * \param file The file. + * \return True if the file was found. */ + virtual bool isBelow(Unit *file) const; +}; + +inline UnitManager &Project::unitManager() { + return m_unitManager; +} + +inline bool Project::isBelow(const char *file) const { + return PathManager::isBelow(file); +} + +} // namespace Puma + +#endif /* PUMA_Project_H */ diff --git a/Puma/src/common/ProjectFile.h b/Puma/src/common/ProjectFile.h new file mode 100644 index 0000000..4e7aed1 --- /dev/null +++ b/Puma/src/common/ProjectFile.h @@ -0,0 +1,80 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2016 The PUMA developer team. +// +// 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 PUMA_ProjectFile_H +#define PUMA_ProjectFile_H + +/** \file + * Project file information. */ + +#include +#include + +#include "Puma/Filename.h" + +namespace Puma { + +/** \class ProjectFile ProjectFile.h Puma/ProjectFile.h + * Project file abstraction used to store all filenames relevant + * for a specific file. + * \ingroup common */ +class ProjectFile { + Filename m_name; + Filename m_destPath; + +public: + /** Project file's name to ProjectFile map type. */ + typedef std::map Map; + /** Project file's name to ProjectFile map pair type. */ + typedef Map::value_type MapPair; + /** Project file's name to ProjectFile map constant iterator type. */ + typedef Map::const_iterator MapConstIter; + +public: + /** Construct a project file from the given filename. + * \param filename The filename. */ + ProjectFile(const Filename &filename) + : m_name(filename) { + } + /** Construct a project file from the given filename + * and destination path. + * \param filename The filename. + * \param destPath The destination path. */ + ProjectFile(const Filename &filename, const Filename &destPath) + : m_name(filename), m_destPath(destPath) { + } + /** Set the project file destination path. + * \param destPath The destination path. */ + void dest(const Filename &destPath) { + m_destPath = destPath; + } + /** Get the project file's name. + * \return The filename information. */ + Filename name() const { + return m_name; + } + /** Get the project file's destination path. + * \return The destination path information. */ + Filename dest() const { + return m_destPath; + } +}; + +} // namespace Puma + +#endif // PUMA_ProjectFile_H diff --git a/Puma/src/common/SaveMode.h b/Puma/src/common/SaveMode.h new file mode 100644 index 0000000..a8d0735 --- /dev/null +++ b/Puma/src/common/SaveMode.h @@ -0,0 +1,44 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2016 The PUMA developer team. +// +// 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 PUMA_SaveMode_H +#define PUMA_SaveMode_H + +/** \file + * File save modes. */ + +namespace Puma { + +/** \class SaveMode SaveMode.h Puma/SaveMode.h + * Project file save modes. + * \ingroup common */ +struct SaveMode { + /** Save modes. */ + enum Mode { + /** Overwrite existing file. */ + OVERWRITE = 1, + /** Rename existing file. */ + RENAME_OLD, + /** Save file with a new suffix. */ + NEW_SUFFIX + }; +}; + +} // namespace Puma + +#endif /* PUMA_SaveMode_H */ diff --git a/Puma/src/common/SimpleParser.cc b/Puma/src/common/SimpleParser.cc new file mode 100644 index 0000000..5c7064a --- /dev/null +++ b/Puma/src/common/SimpleParser.cc @@ -0,0 +1,98 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2016 The PUMA developer team. +// +// 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 "Puma/SimpleParser.h" + +namespace Puma { + +std::string SimpleParser::strip(const std::string &str) { + if (str[0] == '"' && str[str.length() - 1] == '"') + return str.substr(1, str.length() - 2); + return str; +} + +std::string::size_type SimpleParser::findBeginOfNextToken(const std::string& line, const std::string& delimiters, std::string::size_type pos) { + bool escaped = false; + std::string::size_type lastPos = std::string::npos; + if (pos != std::string::npos) { + for (std::string::size_type i = pos; i < line.length() && lastPos == std::string::npos; i++) { + char c = line[i]; + if (delimiters.find(c) == std::string::npos) { + lastPos = escaped ? i - 1 : i; + } + if (c == '\\') { + escaped = !escaped; + } else { + escaped = false; + } + } + } + return lastPos; +} + +std::string::size_type SimpleParser::findEndOfNextToken(const std::string& line, const std::string& delimiters, std::string::size_type lastPos) { + bool in_string = false, escaped = false; + std::string::size_type endpos = line.length(); + if (lastPos != std::string::npos) { + for (std::string::size_type i = lastPos; i < line.length(); i++) { + char c = line[i]; + if (!in_string && delimiters.find(c) != std::string::npos) { + endpos = i; + break; + } + if (!escaped && c == '"') { + in_string = !in_string; + } + if (c == '\\') { + escaped = !escaped; + } else { + escaped = false; + } + } + } + return endpos; +} + +std::string::size_type SimpleParser::next(const std::string& line, const std::string& delimiters, std::string::size_type pos, std::string::size_type& lastPos) { + // find begin of next token + lastPos = findBeginOfNextToken(line, delimiters, pos); + // find end of the token + return findEndOfNextToken(line, delimiters, lastPos); +} + +int SimpleParser::tokenize(const std::string& line, std::vector& words, const std::string& delimiters) { + int res = 0; + std::string::size_type pos = 0, lastPos = 0; + + // get first token position + pos = next(line, delimiters, 0, lastPos); + + // while not at the end of the line + while (pos != std::string::npos && lastPos != std::string::npos) { + // get current token + std::string token = line.substr(lastPos, pos - lastPos); + // add current token to vector + words.push_back(token); + res++; + // get next token position + pos = next(line, delimiters, pos, lastPos); + } + return res; +} + +} // namespace Puma diff --git a/Puma/src/common/SimpleParser.h b/Puma/src/common/SimpleParser.h new file mode 100644 index 0000000..cd6733b --- /dev/null +++ b/Puma/src/common/SimpleParser.h @@ -0,0 +1,71 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2016 The PUMA developer team. +// +// 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 PUMA_SimpleParser_H +#define PUMA_SimpleParser_H + +/** \file + * Simple string tokenizer. */ + +#include +#include + +namespace Puma { + +/** \class SimpleParser SimpleParser.h Puma/SimpleParser.h + * Simple string tokenizer taking a string and providing + * a list of the tokens recognized. + * \ingroup common */ +class SimpleParser { +public: + /** Remove enclosing double-quotes from a string. + * \param str The string to strip. + * \return String without the enclosing double-quotes.*/ + static std::string strip(const std::string& str); + /** Splits a given string into tokens recognized by the given delimiters. + * \param str The string to split. + * \param tokens The container for the resulting tokens. + * \param delimiters A string with the delimiters. Defaults to a single space. + * \return Number of recognized tokens. */ + static int tokenize(const std::string& str, std::vector& tokens, const std::string& delimiters = " "); + +private: + /** Get the position of the next token. + * \param line The string to tokenize. + * \param delimiters A string with the token delimiters. + * \param pos The current position in the string. + * \param lastPos The last position in the string. + * \return The position of the next token. */ + static std::string::size_type next(const std::string& line, const std::string& delimiters, std::string::size_type pos, std::string::size_type& lastPos); + /** Get the begin of the next token. + * \param line The string to tokenize. + * \param delimiters A string with the token delimiters. + * \param pos The current position in the string. + * \return The begin of the next token. */ + static std::string::size_type findBeginOfNextToken(const std::string& line, const std::string& delimiters, std::string::size_type pos); + /** Get the end of the next token. + * \param line The string to tokenize. + * \param delimiters A string with the token delimiters. + * \param lastPos The last position in the string, i.e. the begin of the next token. + * \return The end of the next token. */ + static std::string::size_type findEndOfNextToken(const std::string& line, const std::string& delimiters, std::string::size_type lastPos); +}; + +} // namespace Puma + +#endif /* PUMA_SimpleParser_H */ diff --git a/Puma/src/common/Token.cc b/Puma/src/common/Token.cc new file mode 100644 index 0000000..aeb52e6 --- /dev/null +++ b/Puma/src/common/Token.cc @@ -0,0 +1,486 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 "Puma/Token.h" +#include "Puma/CTokens.h" +#include "Puma/CCommentTokens.h" +#include "Puma/CWildcardTokens.h" +#include "Puma/PreMacroOpTokens.h" +#include "Puma/PreParser.h" +#include "Puma/PreExprParser.h" +#include "Puma/Chain.h" +#include "Puma/StrCol.h" +#include "Puma/ConstSizeMemPool.h" +#include "Puma/Unit.h" +#include +#include +#include + +namespace Puma { + +LanguageID Token::comment_id = "Comment"; +LanguageID Token::pre_id = "Preprocessor"; +LanguageID Token::macro_op_id = "Pre macro op"; +LanguageID Token::dir_id = "Directive"; +LanguageID Token::cpp_id = "C++"; +LanguageID Token::keyword_id = "C++ keyword"; +LanguageID Token::identifier_id = "C++ identifier"; +LanguageID Token::white_id = "Whitespace"; +LanguageID Token::wildcard_id = "Wildcard"; +LanguageID Token::open_id = "("; +LanguageID Token::comma_id = ","; +LanguageID Token::close_id = ")"; + +void *Token::operator new(size_t n) { + assert(n == sizeof(Token)); + return malloc(); +} + +void Token::operator delete(void *p) { + free(p); +} + +Token::Token(int t, LanguageID lang, const char *txt) { + m_language = lang; + m_flags = 0; + m_continuousLines = 0; + m_realType = t; + m_type = get_general_type(); + determine_is_comment(); + determine_is_core(); + const char *static_text = get_static_text(); + if (static_text || !txt) + m_text = 0; + else + m_text = StrCol::dup(txt); +} + +Token::Token(const Token &t) { + m_language = t.m_language; + m_location = t.m_location; + m_flags = t.m_flags; + m_type = t.m_type; + m_realType = t.m_realType; + if (t.m_text) + m_text = StrCol::dup(t.m_text); + else + m_text = 0; + m_continuousLines = t.m_continuousLines ? new Array(*t.m_continuousLines) : 0; +} + +Token::~Token() { + if (m_continuousLines) { + delete m_continuousLines; + m_continuousLines = 0; + } + if (m_text) { + delete[] m_text; + m_text = 0; + } +} + +DString &Token::dtext() const { + if (m_dictText.empty()) + m_dictText = text(); + return m_dictText; +} + +const char *Token::text() const { + return m_text ? m_text : get_static_text(); +} + +int Token::get_general_type() const { + switch (m_realType) { + case TOK_AND_AND_ISO_646: return TOK_AND_AND; + case TOK_AND_EQ_ISO_646: return TOK_AND_EQ; + case TOK_AND_ISO_646: return TOK_AND; + case TOK_OR_ISO_646: return TOK_OR; + case TOK_TILDE_ISO_646: return TOK_TILDE; + case TOK_NOT_ISO_646: return TOK_NOT; + case TOK_NEQ_ISO_646: return TOK_NEQ; + case TOK_OR_OR_ISO_646: return TOK_OR_OR; + case TOK_IOR_EQ_ISO_646: return TOK_IOR_EQ; + case TOK_ROOF_ISO_646: return TOK_ROOF; + case TOK_XOR_EQ_ISO_646: return TOK_XOR_EQ; + case TOK_ASM_2: return TOK_ASM; + case TOK_ASM_3: return TOK_ASM; + case TOK_CONST_2: return TOK_CONST; + case TOK_CONST_3: return TOK_CONST; + case TOK_INLINE_2: return TOK_INLINE; + case TOK_INLINE_3: return TOK_INLINE; + case TOK_RESTRICT_2: return TOK_RESTRICT; + case TOK_RESTRICT_3: return TOK_RESTRICT; + case TOK_SIGNED_2: return TOK_SIGNED; + case TOK_SIGNED_3: return TOK_SIGNED; + case TOK_VOLATILE_2: return TOK_VOLATILE; + case TOK_VOLATILE_3: return TOK_VOLATILE; + case TOK_WCHAR_T_2: return TOK_WCHAR_T; + case TOK_TYPEOF_2: return TOK_TYPEOF; + case TOK_TYPEOF_3: return TOK_TYPEOF; + case TOK_TYPEOF_4: return TOK_TYPEOF; + case TOK_ALIGNOF_2: return TOK_ALIGNOF; + case TOK_ALIGNOF_3: return TOK_ALIGNOF; + case TOK_CDECL_2: return TOK_CDECL; + case TOK_STDCALL_2: return TOK_STDCALL; + case TOK_FASTCALL_2: return TOK_FASTCALL; + default: return m_realType; + } +} + +void Token::reset(int t, const char *txt, LanguageID id) { + if (m_continuousLines) { + delete m_continuousLines; + } + if (m_text) { + delete[] m_text; + } + + m_language = id; + m_continuousLines = 0; + m_realType = t; + m_type = get_general_type(); + determine_is_comment(); + determine_is_core(); + const char *static_text = get_static_text(); + m_text = static_text || !txt ? 0 : StrCol::dup(txt); +} + +char *Token::get_static_text() const { + if (!(is_core() || is_wildcard()) || (is_identifier() && !is_keyword())) + return 0; + return get_static_text(m_realType); +} + +char *Token::get_static_text(int token_type) { + switch (token_type) { + case TOK_COMMA: return (char*) ","; + case TOK_ASSIGN: return (char*) "="; + case TOK_AT: return (char*) "@"; + case TOK_QUESTION: return (char*) "?"; + case TOK_OR: return (char*) "|"; + case TOK_ROOF: return (char*) "^"; + case TOK_AND: return (char*) "&"; + case TOK_PLUS: return (char*) "+"; + case TOK_MINUS: return (char*) "-"; + case TOK_MUL: return (char*) "*"; + case TOK_DIV: return (char*) "/"; + case TOK_MODULO: return (char*) "%"; + case TOK_LESS: return (char*) "<"; + case TOK_GREATER: return (char*) ">"; + case TOK_OPEN_ROUND: return (char*) "("; + case TOK_CLOSE_ROUND: return (char*) ")"; + case TOK_OPEN_SQUARE: return (char*) "["; + case TOK_CLOSE_SQUARE: return (char*) "]"; + case TOK_OPEN_CURLY: return (char*) "{"; + case TOK_CLOSE_CURLY: return (char*) "}"; + case TOK_SEMI_COLON: return (char*) ";"; + case TOK_COLON: return (char*) ":"; + case TOK_NOT: return (char*) "!"; + case TOK_TILDE: return (char*) "~"; + case TOK_DOT: return (char*) "."; + case TOK_MUL_EQ: return (char*) "*="; + case TOK_DIV_EQ: return (char*) "/="; + case TOK_MOD_EQ: return (char*) "%="; + case TOK_ADD_EQ: return (char*) "+="; + case TOK_SUB_EQ: return (char*) "-="; + case TOK_LSH_EQ: return (char*) "<<="; + case TOK_RSH_EQ: return (char*) ">>="; + case TOK_AND_EQ: return (char*) "&="; + case TOK_XOR_EQ: return (char*) "^="; + case TOK_IOR_EQ: return (char*) "|="; + case TOK_OR_OR: return (char*) "||"; + case TOK_AND_AND: return (char*) "&&"; + case TOK_EQL: return (char*) "=="; + case TOK_NEQ: return (char*) "!="; + case TOK_LEQ: return (char*) "<="; + case TOK_GEQ: return (char*) ">="; + case TOK_LSH: return (char*) "<<"; + case TOK_RSH: return (char*) ">>"; + case TOK_DOT_STAR: return (char*) ".*"; + case TOK_PTS_STAR: return (char*) "->*"; + case TOK_INCR: return (char*) "++"; + case TOK_DECR: return (char*) "--"; + case TOK_PTS: return (char*) "->"; + case TOK_COLON_COLON: return (char*) "::"; + case TOK_ELLIPSIS: return (char*) "..."; + case TOK_ZERO_VAL: return (char*) "0"; + case TOK_AUTO: return (char*) "auto"; + case TOK_BREAK: return (char*) "break"; + case TOK_CASE: return (char*) "case"; + case TOK_CHAR: return (char*) "char"; + case TOK_CONTINUE: return (char*) "continue"; + case TOK_DEFAULT: return (char*) "default"; + case TOK_DO: return (char*) "do"; + case TOK_DOUBLE: return (char*) "double"; + case TOK_ELSE: return (char*) "else"; + case TOK_ENUM: return (char*) "enum"; + case TOK_EXTERN: return (char*) "extern"; + case TOK_FLOAT: return (char*) "float"; + case TOK_FOR: return (char*) "for"; + case TOK_GOTO: return (char*) "goto"; + case TOK_IF: return (char*) "if"; + case TOK_INT: return (char*) "int"; + case TOK_INT128: return (char*) "__int128"; + case TOK_INT64: return (char*) "__int64"; + case TOK_LONG: return (char*) "long"; + case TOK_REGISTER: return (char*) "register"; + case TOK_RETURN: return (char*) "return"; + case TOK_SHORT: return (char*) "short"; + case TOK_SIZEOF: return (char*) "sizeof"; + case TOK_STATIC: return (char*) "static"; + case TOK_THREAD: return (char*) "__thread"; + case TOK_STRUCT: return (char*) "struct"; + case TOK_SWITCH: return (char*) "switch"; + case TOK_TYPEDEF: return (char*) "typedef"; + case TOK_UNION: return (char*) "union"; + case TOK_UNSIGNED: return (char*) "unsigned"; + case TOK_VOID: return (char*) "void"; + case TOK_WHILE: return (char*) "while"; + case TOK_CATCH: return (char*) "catch"; + case TOK_CLASS: return (char*) "class"; + case TOK_CONST_CAST: return (char*) "const_cast"; + case TOK_DELETE: return (char*) "delete"; + case TOK_DYN_CAST: return (char*) "dynamic_cast"; + case TOK_EXPLICIT: return (char*) "explicit"; + case TOK_EXPORT: return (char*) "export"; + case TOK_FRIEND: return (char*) "friend"; + case TOK_MUTABLE: return (char*) "mutable"; + case TOK_NAMESPACE: return (char*) "namespace"; + case TOK_NEW: return (char*) "new"; + case TOK_OPERATOR: return (char*) "operator"; + case TOK_PRIVATE: return (char*) "private"; + case TOK_PROTECTED: return (char*) "protected"; + case TOK_PUBLIC: return (char*) "public"; + case TOK_REINT_CAST: return (char*) "reinterpret_cast"; + case TOK_STAT_CAST: return (char*) "static_cast"; + case TOK_TEMPLATE: return (char*) "template"; + case TOK_THIS: return (char*) "this"; + case TOK_THROW: return (char*) "throw"; + case TOK_TRY: return (char*) "try"; + case TOK_TYPEID: return (char*) "typeid"; + case TOK_TYPENAME: return (char*) "typename"; + case TOK_USING: return (char*) "using"; + case TOK_VIRTUAL: return (char*) "virtual"; + case TOK_POINTCUT: return (char*) "pointcut"; + case TOK_ASPECT: return (char*) "aspect"; + case TOK_ADVICE: return (char*) "advice"; + case TOK_SLICE: return (char*) "slice"; + case TOK_UNKNOWN_T: return (char*) "__unknown_t"; + case TOK_CCSINGLE: return (char*) "//"; + case TOK_CCMULTIBEGIN: return (char*) "/*"; + case TOK_CCMULTIEND: return (char*) "*/"; + case TOK_WC_AND: return (char*) "\\and"; + case TOK_WC_OR: return (char*) "\\or"; + case TOK_WC_XOR: return (char*) "\\xor"; + case TOK_WC_SEQ: return (char*) "\\seq"; + case TOK_WC_IF: return (char*) "\\if"; + case TOK_WC_ELIF: return (char*) "\\elif"; + case TOK_WC_ENDIF: return (char*) "\\endif"; + case TOK_WC_NOT: return (char*) "\\not"; + case TOK_WC_EXACT: return (char*) "\\exact"; + case TOK_WC_FIRST: return (char*) "\\first"; + case TOK_WC_LAST: return (char*) "\\last"; + case TOK_WC_LEAF: return (char*) "\\leaf"; + case TOK_WC_PRUNE: return (char*) "\\prune"; + case TOK_WC_COLLECT: return (char*) "\\collect"; + case TOK_WC_NODENAME: return (char*) "\\nodename"; + case TOK_WC_ELEMENT: return (char*) "\\element"; + case TOK_DO_EXPR: return (char*) "\\do-expression"; + case TOK_DO_EXPR_LIST: return (char*) "\\do-expression-list"; + case TOK_DO_ID_EXPR: return (char*) "\\do-id-expression"; + case TOK_DO_IDENTIFIER: return (char*) "\\do-identifier"; + case TOK_DO_DECL_SPEC: return (char*) "\\do-decl-specifier"; + case TOK_DO_DECL_SPEC_SEQ: return (char*) "\\do-decl-specifier-seq"; + case TOK_DO_INIT_DECLARATOR: return (char*) "\\do-init-declarator"; + case TOK_DO_INIT_DECLARATOR_LIST: return (char*) "\\do-init-declarator-list"; + case TOK_DO_DECLARATOR: return (char*) "\\do-declarator"; + case TOK_DO_INIT: return (char*) "\\do-initializer"; + case TOK_DO_ARG_DECL_SEQ: return (char*) "\\do-parameter-declaration-clause"; + case TOK_DO_FCT_BODY: return (char*) "\\do-function-body"; + case TOK_DO_CLASS_SPEC: return (char*) "\\do-class-specifier"; + case TOK_DO_MEMBER_SPEC: return (char*) "\\do-member-specification"; + case TOK_DO_MEMBER_DECL: return (char*) "\\do-member-declaration"; + case TOK_DO_BASE_CLAUSE: return (char*) "\\do-base-clause"; + case TOK_DO_CTOR_INIT: return (char*) "\\do-ctor-initializer"; + case TOK_DO_MEM_INIT: return (char*) "\\do-mem-initializer"; + case TOK_DO_STMT: return (char*) "\\do-statement"; + case TOK_DO_STMT_SEQ: return (char*) "\\do-statement-seq"; + case TOK_ANY_EXPR: return (char*) "\\any-expression"; + case TOK_ANY_EXPR_LIST: return (char*) "\\any-expression-list"; + case TOK_ANY_ID_EXPR: return (char*) "\\any-id-expression"; + case TOK_ANY_IDENTIFIER: return (char*) "\\any-identifier"; + case TOK_ANY_DECL_SPEC: return (char*) "\\any-decl-specifier"; + case TOK_ANY_DECL_SPEC_SEQ: return (char*) "\\any-decl-specifier-seq"; + case TOK_ANY_INIT_DECLARATOR_LIST: return (char*) "\\any-init-declarator-list"; + case TOK_ANY_INIT_DECLARATOR: return (char*) "\\any-init-declarator"; + case TOK_ANY_DECLARATOR: return (char*) "\\any-declarator"; + case TOK_ANY_INIT: return (char*) "\\any-initializer"; + case TOK_ANY_ARG_DECL_SEQ: return (char*) "\\any-parameter-declaration-clause"; + case TOK_ANY_FCT_BODY: return (char*) "\\any-function-body"; + case TOK_ANY_CLASS_SPEC: return (char*) "\\any-class-specifier"; + case TOK_ANY_MEMBER_SPEC: return (char*) "\\any-member-specification"; + case TOK_ANY_MEMBER_DECL: return (char*) "\\any-member-declaration"; + case TOK_ANY_BASE_CLAUSE: return (char*) "\\any-base-clause"; + case TOK_ANY_CTOR_INIT: return (char*) "\\any-ctor-initializer"; + case TOK_ANY_MEM_INIT: return (char*) "\\any-mem-initializer"; + case TOK_ANY_STMT: return (char*) "\\any-statement"; + case TOK_ANY_STMT_SEQ: return (char*) "\\any-statement-seq"; + case TOK_WC_IS_TYPEDEF: return (char*) "\\is-typedef"; + case TOK_WC_IS_CLASS: return (char*) "\\is-class"; + case TOK_WC_IS_ENUM: return (char*) "\\is-enum"; + case TOK_MO_HASH: return (char*) "#"; + case TOK_MO_HASHHASH: return (char*) "##"; + case ID_END_OF_FILE: + case ID_ERROR: + case ID_UNKNOWN: + case ID_WARNING: return (char*) ""; + case TOK_AND_AND_ISO_646: return (char*) "and"; + case TOK_AND_EQ_ISO_646: return (char*) "and_eq"; + case TOK_AND_ISO_646: return (char*) "bitand"; + case TOK_OR_ISO_646: return (char*) "bitor"; + case TOK_TILDE_ISO_646: return (char*) "compl"; + case TOK_NOT_ISO_646: return (char*) "not"; + case TOK_NEQ_ISO_646: return (char*) "not_eq"; + case TOK_OR_OR_ISO_646: return (char*) "or"; + case TOK_IOR_EQ_ISO_646: return (char*) "or_eq"; + case TOK_ROOF_ISO_646: return (char*) "xor"; + case TOK_XOR_EQ_ISO_646: return (char*) "xor_eq"; + case TOK_ASM: return (char*) "asm"; + case TOK_ASM_2: return (char*) "__asm"; + case TOK_ASM_3: return (char*) "__asm__"; + case TOK_BOOL: return (char*) "bool"; + case TOK_C_BOOL: return (char*) "_Bool"; + case TOK_CONST: return (char*) "const"; + case TOK_CONST_2: return (char*) "__const"; + case TOK_CONST_3: return (char*) "__const__"; + case TOK_INLINE: return (char*) "inline"; + case TOK_INLINE_2: return (char*) "__inline"; + case TOK_INLINE_3: return (char*) "__inline__"; + case TOK_RESTRICT: return (char*) "restrict"; + case TOK_RESTRICT_2: return (char*) "__restrict"; + case TOK_RESTRICT_3: return (char*) "__restrict__"; + case TOK_SIGNED: return (char*) "signed"; + case TOK_SIGNED_2: return (char*) "__signed"; + case TOK_SIGNED_3: return (char*) "__signed__"; + case TOK_VOLATILE: return (char*) "volatile"; + case TOK_VOLATILE_2: return (char*) "__volatile"; + case TOK_VOLATILE_3: return (char*) "__volatile__"; + case TOK_WCHAR_T: return (char*) "wchar_t"; + case TOK_WCHAR_T_2: return (char*) "__wchar_t"; + case TOK_TYPEOF: return (char*) "typeof"; + case TOK_TYPEOF_2: return (char*) "__typeof"; + case TOK_TYPEOF_3: return (char*) "__typeof__"; + case TOK_TYPEOF_4: return (char*) "__decltype"; + case TOK_ALIGNOF: + case TOK_ALIGNOF_2: return (char*) "__alignof"; + case TOK_ALIGNOF_3: return (char*) "__alignof__"; + case TOK_CDECL: return (char*) "_cdecl"; + case TOK_CDECL_2: return (char*) "__cdecl"; + case TOK_STDCALL: return (char*) "_stdcall"; + case TOK_STDCALL_2: return (char*) "__stdcall"; + case TOK_FASTCALL: return (char*) "_fastcall"; + case TOK_FASTCALL_2: return (char*) "__fastcall"; + case TOK_IF_EXISTS: return (char*) "__if_exists"; + case TOK_IF_NOT_EXISTS: return (char*) "__if_not_exists"; + case TOK_HAS_NOTHROW_ASSIGN: return (char*) "__has_nothrow_assign"; + case TOK_HAS_NOTHROW_COPY: return (char*) "__has_nothrow_copy"; + case TOK_HAS_NOTHROW_CTOR: return (char*) "__has_nothrow_constructor"; + case TOK_HAS_TRIVIAL_ASSIGN: return (char*) "__has_trivial_assign"; + case TOK_HAS_TRIVIAL_COPY: return (char*) "__has_trivial_copy"; + case TOK_HAS_TRIVIAL_CTOR: return (char*) "__has_trivial_constructor"; + case TOK_HAS_TRIVIAL_DTOR: return (char*) "__has_trivial_destructor"; + case TOK_HAS_VIRTUAL_DTOR: return (char*) "__has_virtual_destructor"; + case TOK_IS_ABSTRACT: return (char*) "__is_abstract"; + case TOK_IS_BASE_OF: return (char*) "__is_base_of"; + case TOK_IS_CLASS: return (char*) "__is_class"; + case TOK_IS_EMPTY: return (char*) "__is_empty"; + case TOK_IS_ENUM: return (char*) "__is_enum"; + case TOK_IS_POD: return (char*) "__is_pod"; + case TOK_IS_TRIVIAL: return (char*) "__is_trivial"; + case TOK_IS_POLYMORPHIC: return (char*) "__is_polymorphic"; + case TOK_IS_UNION: return (char*) "__is_union"; +// case TOK_EXPR_QUESTION: return (char*)"?"; +// case TOK_EXPR_BITOR: return (char*)"|"; +// case TOK_EXPR_BITXOR: return (char*)"^"; +// case TOK_EXPR_BITAND: return (char*)"&"; +// case TOK_EXPR_PLUS: return (char*)"+"; +// case TOK_EXPR_MINUS: return (char*)"-"; +// case TOK_EXPR_STAR: return (char*)"*"; +// case TOK_EXPR_DIV: return (char*)"/"; +// case TOK_EXPR_MOD: return (char*)"%"; +// case TOK_EXPR_LESS: return (char*)"<"; +// case TOK_EXPR_GREATER: return (char*)">"; +// case TOK_EXPR_LPAREN: return (char*)"("; +// case TOK_EXPR_RPAREN: return (char*)")"; +// case TOK_EXPR_COLON: return (char*)":"; +// case TOK_EXPR_NOT: return (char*)"!"; +// case TOK_EXPR_TILDE: return (char*)"~"; +// case TOK_EXPR_OR: return (char*)"||"; +// case TOK_EXPR_AND: return (char*)"&&"; +// case TOK_EXPR_EQ: return (char*)"=="; +// case TOK_EXPR_NOTEQ: return (char*)"!="; +// case TOK_EXPR_LEQ: return (char*)"<="; +// case TOK_EXPR_GEQ: return (char*)">="; +// case TOK_EXPR_SHIFTL: return (char*)"<<"; +// case TOK_EXPR_SHIFTR: return (char*)">>"; + default: return 0; + } +} + +void Token::print(std::ostream &os) const { + // If m_continuousLines isn't NULL the real token text contains + // continuation lines. + const char *txt = text(); + if (m_continuousLines) { + int pos = 0; + for (int cl = 0; cl < m_continuousLines->length(); cl++) { + for (int c = 0; c < m_continuousLines->fetch(cl); c++) + os << txt[pos++]; + os << "\\\n"; + } + if (txt[pos]) + os << txt + pos; + } else if (txt) { + os << txt; + } +} + +int Token::line_breaks() const { + int result = 0; + if (m_continuousLines) + result += m_continuousLines->length(); + if (!is_core()) { + const char *curr = text(); + while (*curr) { + if (*curr == '\n') + result++; + curr++; + } + } + return result; +} + +bool Token::is_macro_generated() const { + return unit()->isMacroExp(); +} + +Unit* Token::unit() const { + return (Unit*) belonging_to(); +} + +} // namespace Puma diff --git a/Puma/src/common/Token.h b/Puma/src/common/Token.h new file mode 100644 index 0000000..8b6af83 --- /dev/null +++ b/Puma/src/common/Token.h @@ -0,0 +1,314 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_Token_H +#define PUMA_Token_H + +/** \file + * Token abstraction. */ + +#include "Puma/LanguageID.h" +#include "Puma/Location.h" +#include "Puma/Printable.h" +#include "Puma/ListElement.h" +#include "Puma/Array.h" +#include "Puma/DString.h" + +namespace Puma { + +class Unit; + +/** \class Token Token.h Puma/Token.h + * Abstraction of a lexical token. A token is created by a + * scanner (see Puma::CScanner). It is part a token chain + * (see Puma::Unit) and encapsulates a lexical unit of the + * scanned text. + * + * The information provided about a lexical unit is: + * - token type + * - location in the scanned text + * - portion of the scanned text represented by this token + * - language of the token + * + * \ingroup common */ +class Token : public ListElement { + int m_type; + int m_realType; + + Location m_location; + LanguageID m_language; + + const char *m_text; + mutable DString m_dictText; + + Array *m_continuousLines; + + enum TK_Flags { + TK_COMMENT = (0x01 << 0), + TK_CORE = (0x01 << 1), + TK_MACRO_CALL = (0x01 << 2) + }; + unsigned short m_flags; + +public: + /** Special token types. */ + enum { + /** End-of-file token. */ + ID_END_OF_FILE = -1, + /** Unknown token type. */ + ID_UNKNOWN = -2, + /** Error token type. */ + ID_ERROR = -3, + /** Warning token type. */ + ID_WARNING = -4 + }; + + /** Comment tokens. */ + static LanguageID comment_id; + /** Preprocessor tokens. */ + static LanguageID pre_id; + /** Compiler directives. */ + static LanguageID dir_id; + /** C/C++ core language tokens. */ + static LanguageID cpp_id; + /** White-spaces. */ + static LanguageID white_id; + /** Wildcards. */ + static LanguageID wildcard_id; + /** Keywords. */ + static LanguageID keyword_id; + /** Left parenthesis. */ + static LanguageID open_id; + /** Function-like macro operands. */ + static LanguageID macro_op_id; + /** Identifiers. */ + static LanguageID identifier_id; + /** Comma. */ + static LanguageID comma_id; + /** Right parenthesis. */ + static LanguageID close_id; + +public: + /** Constructor. + * \param type The token type. + * \param lang The language of the token. + * \param text The optional token text (defaults to the empty string). */ + Token(int type = 0, LanguageID lang = LanguageID(0), const char *text = ""); + /** Copy-constructor. + * \param copy The token to copy. */ + Token(const Token ©); + /** Destructor. Frees the token text. */ + virtual ~Token(); + + /** Print the token text on the given stream. + * \param os The output stream. */ + void print(std::ostream &os) const; + /** Duplicate this token. + * \return A copy of this token. Has to be destroyed by the caller. */ + virtual ListElement *duplicate() { + return new Token(*this); + } + + /** Get the unit this token belongs to. + * \return A pointer to the unit. */ + Unit* unit() const; + + /** Reset the token object optionally providing new content. + * \param type The new token type. + * \param text The new token text. + * \param lang The new token language. */ + void reset(int type = 0, const char *text = 0, LanguageID lang = LanguageID(0)); + + /** Set the location of the token (usually the line and column in a file). + * \param loc The location. */ + void location(const Location &loc) { + m_location = loc; + } + + /** Set the continuous lines appeared in this token. + * \param lines The continuous line array. */ + void cont_lines(Array *lines) { + m_continuousLines = lines; + } + + /** Count the number of line breaks in the text of this token. + * \return The number of line breaks found. */ + int line_breaks() const; + + /** Set the token to be a macro call. + * \param is_call Is a macro call or not. */ + void macro_call(bool is_call = true); + + /** Get the token text. + * \return The constant token text. */ + const char *text() const; + + /** Get the token text from the global dictionary. + * \return A reference to the global dictionary managed version of the token text. */ + DString &dtext() const; + + /** Get the static token text. Only for keywords, operators, and other tokens + * with a constant token text. + * \return The static text, or NULL for tokens with dynamic text (like identifiers). */ + char *get_static_text() const; + + /** Get the static token text for the given token type. Only for keywords, + * operators, and other tokens with a constant token text. + * \param token_type The token type. + * \return The static text, or NULL for tokens with dynamic text (like identifiers). */ + static char *get_static_text(int token_type); + + /** Get the type of the token (see Puma::CTokens). + * \return The numerical value of the token type. */ + int type() const { + return m_type; + } + + /** Get the location of the token (usually the line and column in a file). + * \return A reference to the token location. */ + const Location &location() const { + return m_location; + } + + /** Check if the token is macro generated. + * \return True if macro generated. */ + bool is_macro_generated() const; + /** Check if the token is a macro call. + * \return True if it is a macro call. */ + bool is_macro_call() const { + return (m_flags & TK_MACRO_CALL) != 0; + } + /** Check if this is a core language token. + * \return True if this is core language token. */ + bool is_core() const; + /** Check if the token is an identifier. Subset of core tokens. + * \return True if this is an identifier. */ + bool is_identifier() const; + /** Check if the token is a keyword. Subset of identifiers. + * \return True if this is a keyword. */ + bool is_keyword() const; + /** Check if this is a comma. Subset of core tokens. + * \return True if this is a comma. */ + bool is_comma() const; + /** Check if this is a left parenthesis. Subset of core tokens. + * \return True if this is a left parenthesis. */ + bool is_open() const; + /** Check if this is a right parenthesis. Subset of core tokens. + * \return True if this is a right parenthesis. */ + bool is_close() const; + /** Check if this is a white-space token. + * \return True if this is a white space. */ + bool is_whitespace() const; + /** Check if this is a comment. + * \return True if this is a comment token. */ + bool is_comment() const; + /** Check if this is a preprocessor token. + * \return True if this is a preprocessor token. */ + bool is_preprocessor() const; + /** Check if this is function-like macro operand. + * \return True if this is an operand of a function-like macro. */ + bool is_macro_op() const; + /** Check if this is a compiler directive token. + * \return True if this is compiler directive token. */ + bool is_directive() const; + /** Check if this is a wildcard token. Subset of core tokens. + * \return True if this is a wildcard token. */ + bool is_wildcard() const; + + /** Overwrite operator new for better performance. Tokens are allocated + * very often. To reduce the overhead of allocating a lot of small portions + * of memory, this implementation reuses already allocated memory + * by using a constant size memory pool (see Puma::ConstSizeMemPool). + * \param size The size of the memory to allocate in byte. + * \return A pointer to the allocated memory. */ + void *operator new(size_t size); + /** Free the memory allowed with the Token's own operator new. The memory is + * not freed but kept back for reuse. + * \param ptr A pointer to the memory to free. */ + void operator delete(void *ptr); + +private: + int get_general_type() const; + LanguageID language() const { + return m_language; + } + void determine_is_comment(); + void determine_is_core(); +}; + +inline void Token::macro_call(bool is_call) { + if (is_call) + m_flags |= TK_MACRO_CALL; + else + m_flags &= ~TK_MACRO_CALL; +} + +inline void Token::determine_is_core() { + if (m_language == cpp_id || m_language == wildcard_id || m_language == open_id || m_language == comma_id || m_language == close_id || is_identifier()) + m_flags |= TK_CORE; +} +inline void Token::determine_is_comment() { + if (m_language == comment_id) + m_flags |= TK_COMMENT; +} + +inline bool Token::is_core() const { + return (m_flags & TK_CORE) != 0; +} +inline bool Token::is_identifier() const { + return m_language == identifier_id || is_keyword(); +} +inline bool Token::is_keyword() const { + return m_language == keyword_id; +} +inline bool Token::is_wildcard() const { + return m_language == wildcard_id; +} +inline bool Token::is_preprocessor() const { + return m_language == pre_id; +} +inline bool Token::is_directive() const { + return m_language == dir_id; +} +inline bool Token::is_whitespace() const { + return m_language == white_id; +} +inline bool Token::is_comment() const { + return (m_flags & TK_COMMENT) != 0; +} +inline bool Token::is_macro_op() const { + return m_language == macro_op_id; +} +inline bool Token::is_open() const { + return m_language == open_id; +} +inline bool Token::is_comma() const { + return m_language == comma_id; +} +inline bool Token::is_close() const { + return m_language == close_id; +} + +inline std::ostream &operator <<(std::ostream &os, const Token &object) { + object.print(os); + return os; +} + +} // namespace Puma + +#endif /* PUMA_Token_H */ diff --git a/Puma/src/common/TokenStream.cc b/Puma/src/common/TokenStream.cc new file mode 100644 index 0000000..81fab65 --- /dev/null +++ b/Puma/src/common/TokenStream.cc @@ -0,0 +1,84 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2016 The PUMA developer team. +// +// 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 "Puma/TokenStream.h" +#include "Puma/Token.h" + +namespace Puma { + +// Push a unit on stack. +void TokenStream::push(Unit *unit, Token *curr) { + if (unit) { + UnitTokenSrc *src = new UnitTokenSrc(*unit); + append(src); + if (curr) { + src->current(curr); + } + } +} + +// Get the top unit on stack. +Unit *TokenStream::top() const { + if (length()) { + return lookup(length() - 1)->unit(); + } + return (Unit*) 0; +} + +// Get the current token of the top unit. +Token *TokenStream::current() const { + if (length()) { + return lookup(length() - 1)->current(); + } + return (Token*) 0; +} + +// Get the next token of the top unit. +Token *TokenStream::next() { + long pos = length() - 1; + + // No more units left. Return NULL to show it the caller. + if (pos < 0) + return (Token*) 0; + + // Get the next token. + Token *token = lookup(pos)->next(); + if (token) + return token; + + // Top unit is done. Take it from stack. + delete get(pos); + remove(pos); + + // Get the next token of the "new" top unit. + return next(); +} + +// Check if there are more tokens in the current top unit. +bool TokenStream::topHasMore() const { + long pos = length() - 1; + + // No more units left. + if (pos < 0) + return false; + + // Return true if there is a next token in the top unit. + return lookup(pos)->hasNext(); +} + +} // namespace Puma diff --git a/Puma/src/common/TokenStream.h b/Puma/src/common/TokenStream.h new file mode 100644 index 0000000..22338f2 --- /dev/null +++ b/Puma/src/common/TokenStream.h @@ -0,0 +1,72 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2016 The PUMA developer team. +// +// 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 PUMA_TokenStream_H +#define PUMA_TokenStream_H + +/** \file + * Input token stream. */ + +#include "Puma/Array.h" +#include "Puma/Unit.h" +#include "Puma/UnitTokenSrc.h" + +namespace Puma { + +/** \class TokenStream TokenStream.h Puma/TokenStream.h + * Continuous token stream from a stack of token units, such + * as include files and files included by these files (nested + * includes). + * \ingroup common */ +class TokenStream : public TokenSource, public Array { +public: + /** Constructor. */ + TokenStream() + : Array(20) { + } + /** Destructor. */ + ~TokenStream() { + } + + /** Push a token unit on the token unit stack. + * \param unit The token unit. + * \param curr Optional current token in the token unit, defaults to the first token in the unit. */ + void push(Unit *unit, Token *curr = 0); + + /** Get the top token unit on token unit stack. + * \return The unit on top of the stack, or NULL if stack is empty. */ + Unit *top() const; + + /** Get the next token from the top token unit. If the end of the top token + * unit is reached, that token unit is removed from the stack and the + * next token in the new top token unit is returned. + * \return A pointer to the token, or NULL if stack is empty. */ + Token *next(); + + /** Get the current token of the top token unit. + * \return A pointer to the token, or NULL if stack is empty. */ + Token *current() const; + + /** Check if there are tokens after the current token in the top unit. + * \return True, if the end of the top unit isn't reached yet. */ + bool topHasMore() const; +}; + +} // namespace Puma + +#endif /* PUMA_TokenStream_H */ diff --git a/Puma/src/common/Tokenizer.h b/Puma/src/common/Tokenizer.h new file mode 100644 index 0000000..6f6fa02 --- /dev/null +++ b/Puma/src/common/Tokenizer.h @@ -0,0 +1,47 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2016 The PUMA developer team. +// +// 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 PUMA_Tokenizer_H +#define PUMA_Tokenizer_H + +/** \file + * String tokenizer interface. */ + +#include "Puma/Source.h" +#include "Puma/Unit.h" + +namespace Puma { + +/** \class Tokenizer Tokenizer.h Puma/Tokenizer.h + * Tokenizers read input from a Source to form tokens + * which are stored in a Unit. + * \ingroup common */ +class Tokenizer { +public: + /** Destructor. */ + virtual ~Tokenizer() { + } + /** Fill a unit from the given source. + * \param in The input source. + * \param unit The output unit. */ + virtual void fill_unit(Source &in, Unit &unit) = 0; +}; + +} // namespace Puma + +#endif /* PUMA_Tokenizer_H */ diff --git a/Puma/src/common/Unit.cc b/Puma/src/common/Unit.cc new file mode 100644 index 0000000..7c8125e --- /dev/null +++ b/Puma/src/common/Unit.cc @@ -0,0 +1,61 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 "Puma/Unit.h" +#include "Puma/Token.h" +#include "Puma/StrCol.h" +#include +#include + +namespace Puma { + +Unit::~Unit() { + if (m_name) + delete[] m_name; + clear(); +} + +void Unit::name(const char *n) { + if (m_name) + delete[] m_name; + m_name = n ? StrCol::dup(n) : (char*) 0; +} + +void Unit::print(std::ostream &os) const { + const Token *token = (const Token*) first(); + + while (token) { + os << *token; + token = (const Token*) next(token); + } +} + +// Build a string from an unit. +char *Unit::toString() const { + Token *token; + std::ostringstream str; + + // Fill the return string buffer. + for (token = (Token*) first(); token; token = (Token*) next(token)) + str << token->text(); + + // Duplicate and return the string. + return StrCol::dup(str.str().c_str()); +} + +} // namespace Puma diff --git a/Puma/src/common/Unit.h b/Puma/src/common/Unit.h new file mode 100644 index 0000000..9855583 --- /dev/null +++ b/Puma/src/common/Unit.h @@ -0,0 +1,134 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_Unit_H +#define PUMA_Unit_H + +/** \file + * Token chain abstraction. */ + +#include "Puma/List.h" +#include "Puma/Printable.h" +#include "Puma/UnitState.h" + +namespace Puma { + +class Token; + +/** \class Unit Unit.h Puma/Unit.h + * Token chain abstraction of a source file or string. + * + * A unit is the result of scanning a file or string + * containing recognizable source code. The unit consists + * of a list of tokens that directly map to the characters + * and words of the source code. + * + * A unit can have different states, such as being modified. + * After changing something on a unit, its state + * should be set to being modified. + * + * All source code manipulations resp. transformations provided + * by PUMA are based on manipulating the token chain. Tokens + * can be added, moved, removed, and so on. + * + * Translating the token chain back to the source code text is + * done by printing the unit using method Puma::Unit::print() + * or as shown in the following example. + * \code + * ... + * std::ofstream file("code.cc"); + * file << unit; + * file.close(); + * \endcode + * \ingroup common */ +class Unit : public List, public Printable { + char *m_name; + UnitState m_state; + +public: + /** Constructor. */ + Unit() : + List(), m_name((char*) 0) { + } + /** Copy-constructor. + * \param list The token chain to copy. */ + Unit(const List &list) : + List(list), m_name((char*) 0) { + } + /** Destructor. Destroys the tokens. */ + virtual ~Unit(); + /** Set the name of the unit (usually the file name). + * \param name The name. */ + virtual void name(const char *name); + /** Get the name of the unit (usually the file name). + * \return The name of the unit. */ + char *name() const { + return m_name; + } + /** Print the tokens of the unit on the given stream. + * \param os The output stream. */ + virtual void print(std::ostream &os) const; + /** Check if this is a unit for a file. + * \return True if the tokens belong to a file. */ + virtual bool isFile() const { + return false; + } + /** Check if this is a unit for a macro expansion. + * \return True if the tokens belong to a macro expansion. */ + virtual bool isMacroExp() const { + return false; + } + /** Check if this is a unit for a template instance. + * \return True if the tokens belong to a template instance. */ + virtual bool isTemplateInstance() const { + return false; + } + /** Get the state of the unit. + * \return A reference to the unit state. */ + UnitState &state() { + return m_state; + } + /** Serialize the tokens of the unit. + * \return A new string containing the tokens of the unit. */ + char *toString() const; + + /** Get the first token in the unit. + * \return The first token, or NULL if unit is empty. */ + Token *first() const { + return (Token*) List::first(); + } + /** Get the last token in the unit. + * \return The last token or NULL if unit is empty. */ + Token *last() const { + return (Token*) List::last(); + } + /** Get the next token of the given token. + * \return The next token, or NULL if the given token is NULL. */ + Token *next(const Token *token) const { + return (Token*) List::next((const ListElement*) token); + } + /** Get the previous token of the given token. + * \return The previous token, or NULL if the given token is NULL. */ + Token *prev(const Token *token) const { + return (Token*) List::prev((const ListElement*) token); + } +}; + +} // namespace Puma + +#endif /* PUMA_Unit_H */ diff --git a/Puma/src/common/UnitIterator.cc b/Puma/src/common/UnitIterator.cc new file mode 100644 index 0000000..64820f0 --- /dev/null +++ b/Puma/src/common/UnitIterator.cc @@ -0,0 +1,74 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2016 The PUMA developer team. +// +// 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 "Puma/UnitIterator.h" +#include "Puma/Token.h" +#include "Puma/Unit.h" +#include + +namespace Puma { + +UnitIterator::UnitIterator() { + _unit = (Unit*) 0; + _current = (Token*) 0; +} + +UnitIterator::UnitIterator(ListElement &token) { + _current = (Token*) &token; + _unit = (Unit*) token.belonging_to(); +} + +UnitIterator::UnitIterator(Unit &unit) { + _current = (Token*) unit.first(); + _unit = &unit; +} + +Token *UnitIterator::operator *() const { + return _current; +} + +Token *UnitIterator::operator ->() const { + assert(_current); + return _current; +} + +UnitIterator &UnitIterator::operator =(ListElement& token) { + _current = (Token*) &token; + _unit = (Unit*) token.belonging_to(); + return *this; +} + +UnitIterator &UnitIterator::operator =(Unit &unit) { + _current = (Token*) unit.first(); + _unit = &unit; + return *this; +} + +UnitIterator &UnitIterator::operator ++() { + if (_unit && _current) + _current = (Token*) _unit->next(_current); + return *this; +} + +UnitIterator &UnitIterator::operator --() { + if (_unit && _current) + _current = (Token*) _unit->prev(_current); + return *this; +} + +} // namespace Puma diff --git a/Puma/src/common/UnitIterator.h b/Puma/src/common/UnitIterator.h new file mode 100644 index 0000000..75bd5be --- /dev/null +++ b/Puma/src/common/UnitIterator.h @@ -0,0 +1,76 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2016 The PUMA developer team. +// +// 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 PUMA_UnitIterator_H +#define PUMA_UnitIterator_H + +/** \file + * Token unit iterator. */ + +#include "Puma/Unit.h" +#include "Puma/ListElement.h" + +namespace Puma { + +class Token; + +/** \class UnitIterator UnitIterator.h Puma/UnitIterator.h + * Token unit iterator supporting iteration from the beginning + * of a unit or any token within that unit. + * \ingroup common */ +class UnitIterator { + Unit *_unit; // Unit to iterate. + Token *_current; // The current token. + +public: + /** Construct an empty iterator. */ + UnitIterator(); + /** Constructor. Iterates a unit starting at its first token. + * \param unit The unit to iterate. */ + UnitIterator(Unit &unit); + /** Constructor. Iterates a unit starting at the given token. + * \param token The token from which to start to iterate. */ + UnitIterator(ListElement &token); + + /** Reset the iterator to iterate a unit starting at its first token. + * \param unit The unit to iterate. + * \return A reference to this iterator. */ + UnitIterator &operator =(Unit &unit); + /** Reset the iterator to iterate a unit starting at the given token. + * \param token The token from which to start to iterate. + * \return A reference to this iterator. */ + UnitIterator &operator =(ListElement &token); + + /** Move on to the next token in the unit. + * \return A reference to this iterator. */ + UnitIterator &operator ++(); + /** Go back to the previous token in the unit. + * \return A reference to this iterator. */ + UnitIterator &operator --(); + + /** Get the current token in the unit. + * \return A pointer to the current token. */ + Token *operator *() const; + /** Call a member on the current token. + * \return A pointer to the current token on which the member is called. */ + Token *operator ->() const; +}; + +} // namespace Puma + +#endif /* PUMA_UnitIterator_H */ diff --git a/Puma/src/common/UnitManager.cc b/Puma/src/common/UnitManager.cc new file mode 100644 index 0000000..597fd7f --- /dev/null +++ b/Puma/src/common/UnitManager.cc @@ -0,0 +1,208 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2016 The PUMA developer team. +// +// 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 "Puma/Unit.h" +#include "Puma/Source.h" +#include "Puma/SysCall.h" +#include "Puma/FileUnit.h" +#include "Puma/FileSource.h" +#include "Puma/ErrorStream.h" +#include "Puma/UnitManager.h" +#include "Puma/Tokenizer.h" +#include +#include + +namespace Puma { + +// Destructor: Delete all units. +UnitManager::~UnitManager() { + discardNonames(); + discardAll(); +} + +// Destroy all noname units. +void UnitManager::discardNonames() { + for (std::list::iterator iter = _nonames.begin(); iter != _nonames.end(); ++iter) + delete *iter; + _nonames.clear(); +} + +// Get a unit by its name. +Unit *UnitManager::get(const char *name, bool is_file) const { + if (!name) + return (Unit*) 0; + + char *abs_name = (char*) 0; + if (is_file) + abs_name = SysCall::absolute(name); + + UMapIter entry = _umap.find(abs_name ? abs_name : name); + Unit *unit = 0; + if (entry != _umap.end()) + unit = (*entry).second; + + if (abs_name) + delete[] abs_name; + + // If that unit is a closed file unit, return NULL, because + // it has to be filled again. + if (unit && unit->isFile() && unit->empty()) + return (Unit*) 0; + + return unit; +} + +// Add a unit to manager. +void UnitManager::add(Unit *unit) { + if (!unit) + return; + + // Noname units will be stored separately. + if (!unit->name()) + _nonames.push_back(unit); + else { + const char *abs_name = 0; + if (unit->isFile()) + abs_name = SysCall::absolute(unit->name()); + + _umap.insert(UMapEntry(abs_name ? abs_name : unit->name(), unit)); + + if (abs_name) + delete[] abs_name; + } +} + +// Remove a unit from manager. +void UnitManager::discard(const char *name, bool is_file, bool destroy) const { + char *abs_name = (char*) 0; + if (is_file) + abs_name = SysCall::absolute(name); + + UMapIter entry = _umap.find(abs_name ? abs_name : name); + if (entry != _umap.end()) { + Unit *unit = (*entry).second; + if (destroy) { + delete unit; + _umap.erase(entry); + } else + unit->clear(); + } + if (abs_name) + delete[] abs_name; +} + +// Remove all units from manager. +void UnitManager::discardAll(bool destroy) const { + for (UMapIter iter = _umap.begin(); iter != _umap.end(); ++iter) { + if (destroy) + delete (*iter).second; + else + (*iter).second->clear(); + } + if (destroy) + _umap.clear(); +} + +// Build a new unit. The source will be deleted. +Unit *UnitManager::scanSource(const char *name, Source *in, bool is_file) { + Unit *unit; + + // Bad arguments. + if (!name && !in) + return (Unit*) 0; + + if (name) { + char *abs_name = (char*) 0; + if (is_file) + abs_name = SysCall::absolute(name); + + UMapIter entry = _umap.find(abs_name ? abs_name : name); + Unit *unit = 0; + if (entry != _umap.end()) + unit = (*entry).second; + char *location = (char*) 0; + + // If that unit is a closed file unit, it has to be + // filled again but from its last location. + if (unit && unit->isFile() && unit->empty()) + if (((FileUnit*) unit)->lastLocation()) + location = ((FileUnit*) unit)->lastLocation(); + + if (location && in) { + delete in; + in = (Source*) 0; + } + + if (!in) { + if (!location) + location = (char*) name; + in = new FileSource(location); + } + + // Destroy the old version of that very unit. + if (unit) { + delete unit; + _umap.erase(abs_name ? abs_name : name); + } + + if (abs_name) + delete[] abs_name; + } + + if (is_file) { + unit = new FileUnit(); + + // Remember the last modification time of the file. + FileInfo fileinfo; + if (SysCall::fstat(((FdSource*) in)->fd(), fileinfo, _err)) + unit->state().lastModified(fileinfo.modi_time()); + } else + unit = new Unit(); + + if (name) + unit->name(name); + + assert(_tokenizer); + _tokenizer->fill_unit(*in, *unit); + + add(unit); + + delete in; + return unit; +} + +// Print units. +void UnitManager::print(const char *name, bool is_file, std::ostream &out) const { + if (name) { + char *abs_name = (char*) 0; + if (is_file) + abs_name = SysCall::absolute(name); + + UMapIter entry = _umap.find(abs_name ? abs_name : name); + if (entry != _umap.end()) + (*entry).second->print(out); + + if (abs_name) + delete[] abs_name; + } +} + +void UnitManager::init() { +} + +} // namespace Puma diff --git a/Puma/src/common/UnitManager.h b/Puma/src/common/UnitManager.h new file mode 100644 index 0000000..92fea04 --- /dev/null +++ b/Puma/src/common/UnitManager.h @@ -0,0 +1,127 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2016 The PUMA developer team. +// +// 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 PUMA_UnitManager_H +#define PUMA_UnitManager_H + +/** \file + * Token unit management. */ + +#include +#include +#include +#include +#include "Puma/ErrorStream.h" + +namespace Puma { + +class Unit; +class Source; +class Tokenizer; + +/** \class UnitManager UnitManager.h Puma/UnitManager.h + * Class to manage the units built to parse the files of + * the source project. + * \ingroup common */ +class UnitManager { +public: + /** Name to unit map type. */ + typedef std::map UMap; + /** Name to unit map entry type. */ + typedef UMap::value_type UMapEntry; + /** Name to unit map iterator type. */ + typedef UMap::iterator UMapIter; + +private: + ErrorStream *_err; + std::list _nonames; + mutable UMap _umap; + Tokenizer *_tokenizer; + +public: + /** Constructor. + * \param err Error stream to use for reporting errors. */ + UnitManager(ErrorStream &err) + : _err(&err), _tokenizer(0) { + } + /** Destructor. Deletes all managed units. */ + virtual ~UnitManager(); + + /** Get the unit management table. + * \return A reference to the unit table. */ + UMap &getTable() const { + return _umap; + } + + /** Get the tokenizer (scanner) that is used by scanSource() + * to tokenize sources. + * \return A pointer to the tokenizer used. */ + Tokenizer *tokenizer() const { + return _tokenizer; + } + /** Set the tokenizer (scanner) to be used by scanSource() + * to tokenize sources. + * \param tokenizer The tokenizer to use. */ + void tokenizer(Tokenizer *tokenizer) { + _tokenizer = tokenizer; + } + + /** Add a token unit to the manager. + * \param unit The unit to add. */ + void add(Unit *unit); + + /** Get a managed unit by name. + * \param name The name of the unit to get. + * \param isfile True to indicate that the given name refers to a file (defaults to false). + * \return A pointer to the unit. */ + Unit *get(const char *name, bool isfile = false) const; + + /** Discard a unit managed by this unit manager. + * \param name The name of the unit to remove. + * \param isfile True to indicate that the given name refers to a file (defaults to false). + * \param destroy True to indicate that the unit shall be destroyed (defaults to true). */ + void discard(const char *name, bool isfile = false, bool destroy = true) const; + + /** Discard all named units managed by this unit manager. + * \param destroy True to indicate that the units shall be destroyed (defaults to true). */ + void discardAll(bool destroy = true) const; + + /** Discard all no-name units managed by this unit manager. */ + void discardNonames(); + + /** Scan the tokens from the given input source and create a unit from it. + * The new unit is added to the unit manager. + * \param name The name of the unit to create. + * \param in The input source. + * \param isfile True to indicate that the given name refers to a file (defaults to false). + * \return A pointer to the new unit created. */ + Unit *scanSource(const char *name, Source *in = 0, bool isfile = false); + + /** Print a named unit on the given output stream. + * \param name The name of the unit to print. + * \param isfile True to indicate that the given name refers to a file (defaults to false). + * \param out The output stream, defaults to std::cout. */ + void print(const char *name, bool isfile = false, std::ostream &out = std::cout) const; + + /** Initialize the unit manager and the managed units for the next parse process. */ + void init(); +}; + +} // namespace Puma + +#endif /* PUMA_UnitManager_H */ diff --git a/Puma/src/common/UnitState.h b/Puma/src/common/UnitState.h new file mode 100644 index 0000000..15aad0d --- /dev/null +++ b/Puma/src/common/UnitState.h @@ -0,0 +1,78 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2015 The PUMA developer team. +// +// 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 PUMA_UnitState_H +#define PUMA_UnitState_H + +/** \file + * Unit modification state. */ + +namespace Puma { + +/** \class UnitState UnitState.h Puma/UnitState.h + * Unit state information, like modification state + * and time of last modification. + * \ingroup common */ +class UnitState { + bool m_modified; + long m_lastModified; + +public: + /** Constructor. */ + UnitState(); + /** Check if the unit was marked as modified. + * \return True if unit was modified. */ + bool isModified() const; + /** Get the last modification time of the unit. + * \return The last modification time or 0 if not set. */ + long lastModified() const; + /** Mark the unit as being modified. */ + void modified(); + /** Set a last modification time for the unit. + * \param time The last modification time as returned by stat(). */ + void lastModified(long time); + /** Mark the unit as not being modified. */ + void unmodified(); +}; + +inline UnitState::UnitState() { + m_modified = false; + m_lastModified = 0; +} + +inline bool UnitState::isModified() const { + return m_modified; +} +inline long UnitState::lastModified() const { + return m_lastModified; +} + +inline void UnitState::modified() { + m_modified = true; + m_lastModified = 0; +} +inline void UnitState::unmodified() { + m_modified = false; +} +inline void UnitState::lastModified(long when) { + m_lastModified = when; +} + +} // namespace Puma + +#endif /* PUMA_UnitState_H */ diff --git a/Puma/src/common/UnitTokenSrc.h b/Puma/src/common/UnitTokenSrc.h new file mode 100644 index 0000000..d0aa256 --- /dev/null +++ b/Puma/src/common/UnitTokenSrc.h @@ -0,0 +1,95 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2016 The PUMA developer team. +// +// 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 PUMA_UnitTokenSrc_H +#define PUMA_UnitTokenSrc_H + +/** \file + * Token source for source files. */ + +#include "Puma/TokenSource.h" +#include "Puma/Token.h" +#include "Puma/Unit.h" + +namespace Puma { + +/** \class UnitTokenSrc UnitTokenSrc.h Puma/UnitTokenSrc.h + * Token unit iterator implementing the token source interface. + * \ingroup common */ +class UnitTokenSrc : public TokenSource { + Unit &_unit; + Token *_curr; + bool _first; + +public: + /** Constructor. + * \param unit The unit to iterate. */ + UnitTokenSrc(Unit &unit); + /** Set the current token in the unit that is iterated. + * \param token The new current token. */ + void current(Token* token); + /** Get the next token in the unit. + * \return A pointer to the next token. */ + Token *next(); + /** Get the current token in the unit. + * \return A pointer to the current token. */ + Token *current() const; + /** Get the token being iterated. + * \return A pointer to the unit. */ + Unit *unit() const; + /** Check if the current token is not the last in the unit. + * \return True, if the end of the unit isn't reached yet. */ + bool hasNext() const; +}; + +inline UnitTokenSrc::UnitTokenSrc(Unit &u) + : _unit(u) { + _curr = (Token*) 0; + _first = true; +} + +inline void UnitTokenSrc::current(Token* c) { + _curr = c; + _first = !c; +} + +inline Token *UnitTokenSrc::next() { + if (_curr) { + _curr = (Token*) _unit.next(_curr); + } else if (_first) { + _curr = (Token*) _unit.first(); + _first = false; + } + return _curr; +} + +inline Token *UnitTokenSrc::current() const { + return _curr; +} + +inline Unit *UnitTokenSrc::unit() const { + return &_unit; +} + +inline bool UnitTokenSrc::hasNext() const { + return (bool) (_curr ? _unit.next(_curr) : _first ? _unit.first() : 0); +} + +} // namespace Puma + +#endif /* PUMA_UnitTokenSrc_H */ diff --git a/Puma/src/compile.mk b/Puma/src/compile.mk new file mode 100644 index 0000000..35e0004 --- /dev/null +++ b/Puma/src/compile.mk @@ -0,0 +1,98 @@ +ifeq ($(MAKELEVEL),0) +$(error Sorry, this makefile is not intended to be \ +used directly. Please use the makefile in the toplevel \ +directory of the PUMA source tree instead) +endif + +#------------------------------------------------- +# variables +#------------------------------------------------- + +include $(ROOT)/vars.mk + +ifeq ($(_TARGET),win32) + CFLAGS := $(CFLAGS) -DHAVE_STRING_H -DSTDC_HEADERS + vpath %.c $(ROOT)/src/win32/regex + vpath %.cc $(ROOT)/src/win32/ptmalloc + vpath %.c $(ROOT)/src/win32/ptmalloc +endif + +OBJECTS += $(notdir $(SOURCES:.cc=.o)) +OBJECTS += $(notdir $(CSOURCES:.c=.o)) +OBJECTS += $(notdir $(LEMSOURCES:.lem=.o)) +OBJECTS := $(addprefix $(OBJDIR)/, $(OBJECTS)) + +DEPDIR := $(STEP2)/dep +DEPFILES := $(addprefix $(DEPDIR)/, $(notdir $(SOURCES:.cc=.d))) + +LIBRARY := $(LIBDIR)/$(LIBNAME).a +# disable building of shared library, we link statically +# SHARED := $(LIBDIR)/$(LIBNAME).so + +LIBRARIES := $(LIBRARY) +ifeq ($(_TARGET),linux) +LIBRARIES := $(LIBRARIES) $(SHARED) +endif + +CPPFLAGS += -I $(EXTDIR) -I $(STEP2)/inc + +#------------------------------------------------- +# rules +#------------------------------------------------- + +vpath %.cc $(STEP2)/src +vpath %.d $(DEPDIR) +vpath %.h $(INCDIR)/Puma +vpath %.o $(OBJDIR) + +all: showinfo $(OBJECTS) $(LIBDIR) $(LIBRARIES) + +showinfo: + @echo + @echo "---" + @echo "Compiling PUMA for TARGET=$(TARGET)" + @echo " Compiler = $(CXX) $(CPPFLAGS) $(CXXFLAGS)" + @echo " Linker = $(CXX) $(CXXFLAGS) $(LDFLAGS)" + @echo "---" + @echo + +$(LIBDIR): + @mkdir -p $(LIBDIR) + +$(LIBRARY): $(OBJECTS) + @echo "Making the static library $(LIBRARY)..." + @$(AR) rcs $(LIBRARY) $? + +$(SHARED): $(OBJECTS) + @echo "Making the shared library $(SHARED)..." + @$(CXX) -shared -o $(SHARED) $(OBJECTS) + +#------------------------------------------------- +# targets +#------------------------------------------------- + +$(OBJDIR)/%.o : %.cc + @echo "Compiling $(notdir $<)..." + @$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $(OBJDIR)/$(@F) -c $< + +$(OBJDIR)/%.o : %.c + @echo "Compiling $(notdir $<)..." + @$(CC) $(CPPFLAGS) $(CFLAGS) -o $(OBJDIR)/$(@F) -c $< + +$(DEPDIR)/%.d : %.cc + @echo "Generating dependencies for $(notdir $<)..." + @$(CXX) $(CPPFLAGS) -MM $(filter %.cc,$^) | \ + sed -e "s@$(*F)\.o@$(OBJDIR)/& $(DEPDIR)/$(*F).d@g" > $@ + + +.PHONY: all showinfo + +#------------------------------------------------- +# includes +#------------------------------------------------- + +ifeq ($(MAKECMDGOALS),) +ifneq ($(DEPFILES),) +-include $(DEPFILES) +endif +endif diff --git a/Puma/src/cpp/ImportHandler.cc b/Puma/src/cpp/ImportHandler.cc new file mode 100644 index 0000000..a7881df --- /dev/null +++ b/Puma/src/cpp/ImportHandler.cc @@ -0,0 +1,131 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/PreprocessorParser.h" +#include "Puma/PreFileIncluder.h" +#include "Puma/PreParserState.h" +#include "Puma/UnitManager.h" +#include "Puma/TokenStream.h" +#include "Puma/PipedCmd.h" +#include "Puma/ImportHandler.h" +#include +#include + +namespace Puma { + + +ImportHandler::ImportHandler (PreprocessorParser &cpp, const char *args) : + parser (cpp), header (0) { + const char *p; + unsigned len, l; + + // can't do an import without import handler + if (! parser.importHandler () || ! args) { + *parser.parserState ()->err << sev_error + << "using #import without import handler given" << endMessage; + return; + } + + // construct a handler call of the form: + // [-I""]* "#import " "" + + std::ostringstream cmd, name; + + // + cmd << parser.importHandler () << " "; + + // [-I""]* + const std::list &paths = parser.fileIncluder ()->getIncludePaths (); + std::list::const_iterator pathIdx = paths.begin(); + for (; pathIdx != paths.end(); ++pathIdx) + cmd << "-I\"" << *pathIdx << "\" "; + + p = args; + len = strlen (p); + + // "#import args" + cmd << "\"#import "; + // copy arguments + for (l = len; l > 0; l--) { + if (*p == '\"') + cmd << "\\"; + cmd << *p; + p++; + } + cmd << "\" "; + p = args; + + // "" + name << "%"; + cmd << "\""; + // skip white spaces + while (isspace (*p)) + p++; + // skip leading '<' resp. '"' + if (*p == '<' || *p == '\"') + p++; + // copy imported file name + for (l = len; l > 0; l--) { + if (*p == '>' || *p == '\"') + break; + cmd << *p; + name << *p; + p++; + } + // command line finished + cmd << "\" "; + + callHandler (cmd.str ().c_str (), name.str ().c_str ()); +} + + +Unit *ImportHandler::IncludeFile () const { + return header; +} + + +void ImportHandler::callHandler (const char *cmd, const char *name) { + // already imported + header = parser.unitManager ()->get (name); + if (header) + return; + + // import header + PipedCmd pcmd; + if (pcmd.exec (cmd) != 0) { + *parser.parserState ()->err << sev_error + << "#import failed, (using this information:" << endMessage; + *parser.parserState ()->err << cmd << ")" << endMessage; + return; + } + + // scan generated header file + header = new Unit; + header->name (name); +#ifdef VISUAL_STUDIO + header->state ().onlyOnce (true); +#endif /* VISUAL_STUDIO */ + parser.cscanner ().fill_unit (pcmd.getOutput ().c_str (), *header); + + // push header on token stack (like an ordinary include file) + parser.unitManager ()->add (header); + ((TokenStream*)(parser.scanner ()))->push (header); +} + + +} // namespace Puma diff --git a/Puma/src/cpp/ImportHandler.h b/Puma/src/cpp/ImportHandler.h new file mode 100644 index 0000000..c719f7b --- /dev/null +++ b/Puma/src/cpp/ImportHandler.h @@ -0,0 +1,46 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __ImportHandler__ +#define __ImportHandler__ + +// #import directive handler + +namespace Puma { + + +class PreprocessorParser; +class Unit; + +class ImportHandler { + PreprocessorParser &parser; + Unit *header; + +public: + ImportHandler (PreprocessorParser &, const char *); + + Unit *IncludeFile () const; + +private: + void callHandler (const char *, const char *); +}; + + +} // namespace Puma + +#endif /* __ImportHandler__ */ diff --git a/Puma/src/cpp/PreAnswer.cc b/Puma/src/cpp/PreAnswer.cc new file mode 100644 index 0000000..e3089c8 --- /dev/null +++ b/Puma/src/cpp/PreAnswer.cc @@ -0,0 +1,40 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/PreAnswer.h" +#include + +namespace Puma { + + +PreAnswer::PreAnswer (const char *answer) { + if (answer) { + _text = new char[strlen (answer) + 1]; + strcpy (_text, answer); + } else + _text = (char*) 0; +} + + +PreAnswer::~PreAnswer () { + if (_text) + delete[] _text; +} + + +} // namespace Puma diff --git a/Puma/src/cpp/PreAnswer.h b/Puma/src/cpp/PreAnswer.h new file mode 100644 index 0000000..edeffbc --- /dev/null +++ b/Puma/src/cpp/PreAnswer.h @@ -0,0 +1,45 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __pre_answer__ +#define __pre_answer__ + +// Preprocessor predicate answer. + +#include "Puma/ListElement.h" + +namespace Puma { + + +class PreAnswer : public ListElement { + char *_text; + +public: + PreAnswer (const char*); + virtual ~PreAnswer (); + + ListElement *duplicate () + { return new PreAnswer (_text); } + + const char *text () const { return _text; } +}; + + +} // namespace Puma + +#endif /* __pre_answer__ */ diff --git a/Puma/src/cpp/PreArgDesc.h b/Puma/src/cpp/PreArgDesc.h new file mode 100644 index 0000000..81d7cf7 --- /dev/null +++ b/Puma/src/cpp/PreArgDesc.h @@ -0,0 +1,54 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __pre_arg_desc__ +#define __pre_arg_desc__ + +#include "Puma/Array.h" +#include "Puma/MacroUnit.h" + +namespace Puma { + + +class PreArgDesc { + // Collected arguments of a function-like macro. + Array m_Args; + // Begin token of the macro call. + Token *m_Begin; + // End token of the macro call. + Token *m_End; + +public: + // Constructor. + PreArgDesc () : m_Begin (0), m_End (0) {} + + Token *beginToken () const { return m_Begin; } + Token *endToken () const { return m_End; } + void beginToken (Token *t) { m_Begin = t; } + void endToken (Token *t) { m_End = t; } + + int numArgs () const { return m_Args.length (); } + void newArg () { m_Args[numArgs ()]; } + MacroUnit &currArg () const { return (MacroUnit&)m_Args.lookup (numArgs ()-1); } + MacroUnit &getArg (int i) const { return (MacroUnit&)m_Args.lookup (i); } +}; + + +} // namespace Puma + +#endif /* __pre_arg_desc__ */ diff --git a/Puma/src/cpp/PreAssertionEvaluator.cc b/Puma/src/cpp/PreAssertionEvaluator.cc new file mode 100644 index 0000000..89048a5 --- /dev/null +++ b/Puma/src/cpp/PreAssertionEvaluator.cc @@ -0,0 +1,189 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/PreAssertionEvaluator.h" +#include "Puma/PrePredicateManager.h" +#include "Puma/PreprocessorParser.h" +#include "Puma/PreMacroManager.h" +#include "Puma/PreParserState.h" +#include "Puma/PrePredicate.h" +#include "Puma/TokenStream.h" +#include "Puma/ErrorStream.h" +#include "Puma/CScanner.h" +#include "Puma/CTokens.h" +#include "Puma/PreMacro.h" +#include "Puma/Token.h" +#include "Puma/Unit.h" +#include +#include + +namespace Puma { + + +PreAssertionEvaluator::PreAssertionEvaluator (PreprocessorParser &parser, + TokenStream *stream) { + _scanner = stream; + _macroManager = parser.macroManager (); + _predicateManager = parser.predicateManager (); + _err = parser.parserState ()->err; + _parser = &parser; +} + + +// Evaluate an assertion. +void PreAssertionEvaluator::evaluateAssertion (Unit *unit) const { + if (! unit) return; + + Token *token; + PrePredicate *predicate = 0; + + // Skip white spaces and comments after the `#'. + while ((token = _scanner->next ())) + if (! token->is_whitespace () && ! token->is_comment ()) + break; + + // Now get the predicate identifier. + if (token) { + if (! token->is_identifier ()) + token = (Token*) 0; + else + predicate = _predicateManager->getPredicate (token->text ()); + } + + // No identifier found -> parse error. + if (! token) { + *_err << (_macroManager->getMacro ("defined"))->location () + << sev_error << "Missing predicate after `#'" + << endMessage; + replaceWith ("0", unit); + return; + } + + // Now look for a left parenthesis, an answer text and a right + // parenthesis like `(answer)'. If there really is an answer + // return its size. + int size = checkForAnswer (token->text ()); + + // There is no answer so our task is only to test whether the + // given predicate exists. Depending on the result of this test + // the assertion will be replaced by the integer constant `0' + // or `1'. + if (size == 0) { + if (predicate) + replaceWith ("1", unit); + else + replaceWith ("0", unit); + return; + } + + // There is an unterminated answer and that has to be skipped. + if (size == -1) { + while ((token = _scanner->next ())); + replaceWith ("0", unit); + return; + } + + // Skip white spaces and comments. + while ((token = _scanner->next ())) + if (token->is_open ()) + break; + + // Collect the answer text. + std::ostringstream answer; + while ((token = _scanner->next ())) { + if (token->is_close ()) + break; + answer << token->text (); + } + + // Now we have a predicate and a answer for that predicate. + // If the predicate exists and if the answer is valid replace + // the assertion with a `1' else with `0'. + if (predicate) { + if (predicate->isAnswer (answer.str ().c_str ())) + replaceWith ("1", unit); + else + replaceWith ("0", unit); + } else + replaceWith ("0", unit); +} + + +// Replace the assertion with the integer constant `1' or `0'. +void PreAssertionEvaluator::replaceWith (const char *value, Unit *unit) const { + _parser->cscanner ().fill_unit (value, *unit); +} + + +// Test whether there is an answer for the predicate. +int PreAssertionEvaluator::checkForAnswer (const char *predicate) const { + int size = 0; + int pos = _scanner->length () - 1; + + // Get the top token source. + UnitTokenSrc *src = _scanner->lookup (pos); + + // Get the unit and the current token. + Token *token = src->current (); + Unit *unit = src->unit (); + + // Skip white spaces and comments. + do { + while (! (token = (Token*) unit->next (token))) { + if (! ((--pos >= 0) && (src = _scanner->lookup (pos)))) + return 0; + unit = src->unit (); + token = src->current (); + } + } while (token->is_whitespace () || token->is_comment ()); + + // Look for the left parenthesis. + if (! token->is_open ()) + return 0; + + // Look for the right parenthesis and count the answer size. + do { + while (! (token = (Token*) unit->next (token))) { + if (! ((--pos >= 0) && (src = _scanner->lookup (pos)))) { + // There is no token left to scan. A left parenthesis does + // not exist. That isn't allowed and causes a parse error. + *_err << (_macroManager->getMacro ("defined"))->location () + << sev_error << "Missing `)' after answer for " + << "predicate `" << predicate << "'" << endMessage; + return -1; + } + unit = src->unit (); + token = src->current (); + } + size += strlen (token->text ()); + + // Left parenthesis aren't allowed within the answer text. + if (token->is_open ()) { + *_err << (_macroManager->getMacro ("defined"))->location () + << sev_error << "Missing `)' after answer for " + << "predicate `" << predicate << "'" << endMessage; + return -1; + } + } while (! token->is_close ()); + + // Can only be reached if an answer was found. + return size; +} + + +} // namespace Puma diff --git a/Puma/src/cpp/PreAssertionEvaluator.h b/Puma/src/cpp/PreAssertionEvaluator.h new file mode 100644 index 0000000..ec1b169 --- /dev/null +++ b/Puma/src/cpp/PreAssertionEvaluator.h @@ -0,0 +1,60 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __pre_assertion_evaluator__ +#define __pre_assertion_evaluator__ + +// The assertion evaluator provides methods to evaluate an assertion. + +#include "Puma/PreprocessorParser.h" + +namespace Puma { + + +class PrePredicateManager; +class PreMacroManager; +class TokenStream; +class ErrorStream; +class Unit; + +class PreAssertionEvaluator { + TokenStream *_scanner; + PreMacroManager *_macroManager; + PrePredicateManager *_predicateManager; + ErrorStream *_err; + PreprocessorParser *_parser; + + // Test whether there is an answer for the predicate. + int checkForAnswer (const char *) const; + + // Replace the assertion with the integer constant `1' or `0'. + void replaceWith (const char *, Unit *) const; + +public: + // Constructor. + PreAssertionEvaluator (PreprocessorParser &, TokenStream *); + ~PreAssertionEvaluator () {} + + // Evaluate the given assertion. + void evaluateAssertion (Unit*) const; +}; + + +} // namespace Puma + +#endif /* __pre_assertion_evaluator__ */ diff --git a/Puma/src/cpp/PreExpr.h b/Puma/src/cpp/PreExpr.h new file mode 100644 index 0000000..157e575 --- /dev/null +++ b/Puma/src/cpp/PreExpr.h @@ -0,0 +1,66 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __pre_expr__ +#define __pre_expr__ + +// Node class for the preprocessor expression parser. + +#include "Puma/Location.h" +#include "Puma/Limits.h" + +namespace Puma { + + +class ErrorStream; + +class PreExpr { + bool _result; + +public: + long double val; + + // Public constructor. + PreExpr (ErrorStream *, Location); + + // Do not use these contructors outside of the + // C preprocessor expression parser. + PreExpr () {}; + ~PreExpr () {}; + PreExpr (long double v) : val (v) {}; + + // Evaluate the given expression string. + void evaluatePreExpr (char *expression_string); + + // Return value of evaluated expression. + bool value () const { return _result; } + + // String conversion method. + static long double convertChar (char *value); + + // Return value converted to unsigned integer. + U_LONG_LONG toUnsignedInt() { return (U_LONG_LONG)val; } + + // Return value converted to signed integer. + LONG_LONG toSignedInt() { return (LONG_LONG)val; } +}; + + +} // namespace Puma + +#endif /* __pre_expr__ */ diff --git a/Puma/src/cpp/PreExprLexer.h b/Puma/src/cpp/PreExprLexer.h new file mode 100644 index 0000000..0f62ffd --- /dev/null +++ b/Puma/src/cpp/PreExprLexer.h @@ -0,0 +1,163 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __pre_expr_lexer_h__ +#define __pre_expr_lexer_h__ + +#include "lexertl/generator.hpp" +#include "lexertl/lookup.hpp" +#include "lexertl/rules.hpp" +#include "lexertl/state_machine.hpp" + +#include "Puma/PreExprParser.h" +#include "Puma/LexerBuffer.h" +#include "Puma/LexerMap.h" + +#include + +namespace Puma { + +class PreExprLexer { + + // implementation of the lexer: a lexertl state machine + lexertl::state_machine _state_machine; + +protected: + + // create the state machine that is needed to scan + // the preprocessor expression tokens (to be done only once!) + void setup () { + lexertl::rules rules; + add_rules (rules); + lexertl::generator::build (rules, _state_machine); + } + +public: + + typedef lexertl::rules::id_type IdType; + + // This type is needed to run the lexer and get the tokens + // one by one + class State { + PreExprLexer &_lexer; + LexerBuffer::ConstIterator _iter; + LexerBuffer::ConstIterator _end; + lexertl::match_results _results; + bool _error; + + public: + + State (PreExprLexer &lexer, LexerBuffer &buffer) : _lexer (lexer), + _iter (buffer.begin ()), _end (buffer.end ()), + _results (_iter, _end), _error (false) {} + + bool error () const { return _error; } + IdType id () const { return _results.id; } + int len () const { return &*_results.end - &*_results.start; } + std::string text () const { return std::string (_results.start, _results.end); } + + bool next () { + _error = false; + lexertl::lookup (_lexer._state_machine, _results); + if (_results.id == 0) + return false; + if (_results.id == _results.npos()) + _error = true; + return true; + } + }; + friend class State; + + // virtual destructor needed to avoid warning + virtual ~PreExprLexer () {} + + // singleton pattern; only one instance + static PreExprLexer &instance() { + + typedef LexerMap Map; + static Map lexer_map; + Map::iterator elem = lexer_map.find (0); //only one config used for cpp + if (elem == lexer_map.end ()) { + elem = lexer_map.create (0); + elem->second->setup (); + } + return *(elem->second); + } + + // define all regular expressions for the C tokens + virtual void add_rules (lexertl::rules &rules) { + // macros + rules.insert_macro("Dec0", "[0-9]"); + rules.insert_macro("Dec", "[1-9]"); + rules.insert_macro("Oct", "[0-7]"); + rules.insert_macro("Hex", "[0-9a-fA-F]"); + rules.insert_macro("U", "[uU]"); + rules.insert_macro("L", "[lL]"); + rules.insert_macro("Exp", "[Ee]"); + rules.insert_macro("F", "[fF]"); + + // operators + rules.push ("\"?\"", TOK_EXPR_QUESTION); + rules.push ("\"|\"", TOK_EXPR_BITOR); + rules.push ("\"^\"", TOK_EXPR_BITXOR); + rules.push ("\"&\"", TOK_EXPR_BITAND); + rules.push ("\"+\"", TOK_EXPR_PLUS); + rules.push ("\"-\"", TOK_EXPR_MINUS); + rules.push ("\"*\"", TOK_EXPR_STAR); + rules.push ("\"/\"", TOK_EXPR_DIV); + rules.push ("\"%\"", TOK_EXPR_MOD); + rules.push ("\"<\"", TOK_EXPR_LESS); + rules.push ("\">\"", TOK_EXPR_GREATER); + rules.push ("\"(\"", TOK_EXPR_LPAREN); + rules.push ("\")\"", TOK_EXPR_RPAREN); + rules.push ("\":\"", TOK_EXPR_COLON); + rules.push ("\"!\"", TOK_EXPR_NOT); + rules.push ("\"~\"", TOK_EXPR_TILDE); + rules.push ("\"||\"", TOK_EXPR_OR); + rules.push ("\"&&\"", TOK_EXPR_AND); + rules.push ("\"==\"", TOK_EXPR_EQ); + rules.push ("\"!=\"", TOK_EXPR_NOTEQ); + rules.push ("\"<=\"", TOK_EXPR_LEQ); + rules.push ("\">=\"", TOK_EXPR_GEQ); + rules.push ("\"<<\"", TOK_EXPR_SHIFTL); + rules.push ("\">>\"", TOK_EXPR_SHIFTR); + + // an integer constant: + rules.push ("({Dec}{Dec0}*|(0))({U}|{L}|{L}{U}|{U}{L}|{L}{L}|{U}{L}{L}|{L}{U}{L}|{L}{L}{U})?", TOK_EXPR_DEC); + rules.push ("0{Oct}+({U}|{L}|{L}{U}|{U}{L}|{L}{L}|{U}{L}{L}|{L}{U}{L}|{L}{L}{U})?", TOK_EXPR_OCT); + rules.push ("0[xX]{Hex}+({U}|{L}|{L}{U}|{U}{L}|{L}{L}|{U}{L}{L}|{L}{U}{L}|{L}{L}{U})?", TOK_EXPR_HEX); + + // a floating point constant: + rules.push ("{Dec0}+(\\.{Dec0}*)?({Exp}([\\+\\-])?{Dec0}+)?({L}|{F})?", TOK_EXPR_FLOAT); + rules.push ("\\.{Dec0}+({Exp}([\\+\\-])?{Dec0}+)?({L}|{F})?", TOK_EXPR_FLOAT); + + // a hex floating point constant: + rules.push ("0[xX]{Hex}+(\\.{Hex}*)?[pP]([\\+\\-])?{Dec0}+({L}|{F})?", TOK_EXPR_FLOAT); + rules.push ("0[xX]\\.{Hex}+[pP]([\\+\\-])?{Dec0}+({L}|{F})?", TOK_EXPR_FLOAT); + + // a character constant: + rules.push ("(L)?\\\'([^\\\\\\\']|\\\\.)*\\\'", TOK_EXPR_CHAR); + + // whitespace + rules.push ("\\s+", TOK_EXPR_WSPACE); + } +}; + +} // namespace Puma + +#endif /* __pre_expr_lexer_h__ */ diff --git a/Puma/src/cpp/PreExprParser.lem b/Puma/src/cpp/PreExprParser.lem new file mode 100644 index 0000000..2fa763f --- /dev/null +++ b/Puma/src/cpp/PreExprParser.lem @@ -0,0 +1,540 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 + +/* C preprocessor expression parser */ + +%name PreExprParser +%extra_argument {int *result} + +%token_type {char*} +%type primary_expression {PreExpr*} +%type unary_expression {PreExpr*} +%type constant_expression {PreExpr*} +%type conditional_expression {PreExpr*} +%type pre_expression {PreExpr*} +/* +%token_destructor {delete $$;} +%destructor primary_expression {delete $$;} +%destructor unary_expression {delete $$;} +%destructor constant_expression {delete $$;} +%destructor conditional_expression {delete $$;} +%destructor pre_expression {delete $$;} +*/ +%right TOK_EXPR_QUESTION TOK_EXPR_COLON. +%left TOK_EXPR_OR. +%left TOK_EXPR_AND. +%left TOK_EXPR_BITOR. +%left TOK_EXPR_BITXOR. +%left TOK_EXPR_BITAND. +%left TOK_EXPR_EQ TOK_EXPR_NOTEQ. +%left TOK_EXPR_LESS TOK_EXPR_GREATER TOK_EXPR_LEQ TOK_EXPR_GEQ. +%left TOK_EXPR_SHIFTL TOK_EXPR_SHIFTR. +%left TOK_EXPR_PLUS TOK_EXPR_MINUS. +%left TOK_EXPR_STAR TOK_EXPR_DIV TOK_EXPR_MOD. +%left TOK_PRE_UNARY. + +%nonassoc TOK_EXPR_WSPACE. + +%include { +#include +#include +#include +#include "Puma/Limits.h" +#include "Puma/PreExpr.h" +#include "Puma/Location.h" +#include "Puma/ErrorStream.h" +#include "Puma/PreExprParser.h" +#include "Puma/PreExprLexer.h" + +#ifdef _MSC_VER +#define strtoull(nptr,endptr,base) _strtoui64(nptr,endptr,base) +#define strtold(nptr,endptr) strtod(nptr,endptr) +#endif + +using namespace Puma; + +void *PreExprParserAlloc (void *(*mallocProc)(size_t)); +void PreExprParser (void *pParser, int TokenID, char *TokenValue, int *result); +void PreExprParserFree (void *pParser, void (*freeProc)(void*)); +void PreExprParserTrace (FILE *TraceFILE, char *zTracePrompt); + +namespace Puma { + +extern int TRACE_CPP; +static bool parse_error; +static bool at_eos; +static char *current_token; +static ErrorStream *err; +static Location location; + +// Constructor. +PreExpr::PreExpr (ErrorStream *_err, Location _location) { + err = _err; + location = _location; + _result = false; +} + +// Convert char to integer. +long double PreExpr::convertChar(char *value) { + long double cval; + + char *p = value; + if (*++p == '\\') { + p++; + if (*p == 'x' || *p == 'X') { + char *copy = new char[strlen (value) + 1]; + strcpy (copy, value); + *(copy + 1) = '0'; + cval = strtoull (copy + 1, NULL, 16); + delete[] copy; + } + else if (*p >= '0' && *p <= '9') { + cval = strtoull (p, NULL, 8); + if (cval > 255) cval = 255; + } + else { + switch (*p) { + case 'a': cval = 7; break; + case 'b': cval = 8; break; + case 't': cval = 9; break; + case 'n': cval = 10; break; + case 'v': cval = 11; break; + case 'f': cval = 12; break; + case 'r': cval = 13; break; + default: cval = *p; + } + } + } else + cval = (long double) value[1]; + + return cval; +} + +// Evaluate the given expression string. +void PreExpr::evaluatePreExpr (char *token_list) { + parse_error = false; + at_eos = false; + int result = 0, token = 0; + bool empty_expr = true; + + // Generate the Lemon parser. + void *pParser = PreExprParserAlloc (::malloc); + +#ifndef NDEBUG + // Enable tracing if requested. + if (TRACE_CPP) + PreExprParserTrace (stdout, "CPP_EXPR_TRACE: "); +#endif + + // Initialize the scan buffer with the expression string. + PreExprLexer &lexer = PreExprLexer::instance (); + LexerBuffer lexer_buffer; + lexer_buffer.init (token_list); + PreExprLexer::State lexer_state (lexer, lexer_buffer); + + while (lexer_state.next ()) { + if (lexer_state.error ()) { + *err << sev_error << location + << "Invalid token '" << lexer_state.text ().c_str () << "' in preprocessor expression" << endMessage; + break; + } + else { + token = lexer_state.id(); + if (token != TOK_EXPR_WSPACE) { + empty_expr = false; + current_token = StrCol::dup(lexer_state.text().c_str()); + // Parse the current token. + if (TRACE_CPP) + printf ("%sToken '%s' %i\n", "CPP_EXPR_TRACE: ", current_token, token); + PreExprParser (pParser, token, current_token, &result); + } + } + } + + // Finish and then free the parser. + if (! parse_error && ! empty_expr) { + at_eos = true; // Catch EOS parse errors + PreExprParser (pParser, 0, (char*) 0, &result); + } + PreExprParserFree (pParser, ::free); + + if (empty_expr) { + *err << location << sev_warning + << "empty expression in conditional" + << endMessage; + } + + if (result && ! parse_error) + _result = true; + else + _result = false; +} + +// Handle positive and negative value overflow +long double overflow(long double value) { + if (value > ULLONG_MAX) + { + value = overflow(value - ULLONG_MAX); + } + else if (value < LLONG_MIN) + { + value = overflow(LLONG_MAX - (-value + LLONG_MIN - 1)); + } + return value; +} + +} // namespace Puma +} + +%stack_size 1000 + +%stack_overflow { + *err << location << sev_fatal + << "giving up, preprocessor expression parser stack overflow (>1000)" + << endMessage; + parse_error = true; +} + +%syntax_error { + *err << location << sev_error; + if (at_eos) + *err << "unexpected end of conditional"; + else + *err << "unexpected token `" << current_token << "' in conditional"; + *err << endMessage; + parse_error = true; +} + + +/***********************************************************************/ +/* preprocessor expression *********************************************/ +/***********************************************************************/ + +pre_expression ::= conditional_expression(cde). + { + if (cde->val > 0) + *result = 1; + else + *result = 0; + delete cde; + } + +/***********************************************************************/ +/* conditional expression **********************************************/ +/***********************************************************************/ + +conditional_expression(cde) ::= constant_expression(ce). + { + cde = ce; + } +conditional_expression(cde) ::= constant_expression(ce) TOK_EXPR_QUESTION(qm) + conditional_expression(cde1) + TOK_EXPR_COLON(c) conditional_expression(cde2). + { + if (ce->val > 0) { + cde = cde1; + delete cde2; + } else { + cde = cde2; + delete cde1; + } + delete ce; + delete[] qm; + delete[] c; + } + +/***********************************************************************/ +/* constant expression *************************************************/ +/***********************************************************************/ + +constant_expression(ce) ::= constant_expression(ce1) TOK_EXPR_OR(o) constant_expression(ce2). + { + ce = new PreExpr (); + if (ce1->val > 0 || ce2->val > 0) + ce->val = 1; + else + ce->val = 0; + delete ce1; + delete ce2; + delete[] o; + } +constant_expression(ce) ::= constant_expression(ce1) TOK_EXPR_AND(a) constant_expression(ce2). + { + ce = new PreExpr (); + if (ce1->val > 0 && ce2->val > 0) + ce->val = 1; + else + ce->val = 0; + delete ce1; + delete ce2; + delete[] a; + } +constant_expression(ce) ::= constant_expression(ce1) TOK_EXPR_BITOR(b) constant_expression(ce2). + { + if (ce1->val < 0 && ce2->val < 0) + ce = new PreExpr (overflow(ce1->toSignedInt() | ce2->toSignedInt())); + else if (ce1->val < 0) + ce = new PreExpr (overflow(ce1->toSignedInt() | ce2->toUnsignedInt())); + else if (ce2->val < 0) + ce = new PreExpr (overflow(ce1->toUnsignedInt() | ce2->toSignedInt())); + else + ce = new PreExpr (overflow(ce1->toUnsignedInt() | ce2->toUnsignedInt())); + delete ce1; + delete ce2; + delete[] b; + } +constant_expression(ce) ::= constant_expression(ce1) TOK_EXPR_BITXOR(b) constant_expression(ce2). + { + if (ce1->val < 0 && ce2->val < 0) + ce = new PreExpr (overflow(ce1->toSignedInt() ^ ce2->toSignedInt())); + else if (ce1->val < 0) + ce = new PreExpr (overflow(ce1->toSignedInt() ^ ce2->toUnsignedInt())); + else if (ce2->val < 0) + ce = new PreExpr (overflow(ce1->toUnsignedInt() ^ ce2->toSignedInt())); + else + ce = new PreExpr (overflow(ce1->toUnsignedInt() ^ ce2->toUnsignedInt())); + delete ce1; + delete ce2; + delete[] b; + } +constant_expression(ce) ::= constant_expression(ce1) TOK_EXPR_BITAND(a) constant_expression(ce2). + { + if (ce1->val < 0 && ce2->val < 0) + ce = new PreExpr (overflow(ce1->toSignedInt() & ce2->toSignedInt())); + else if (ce1->val < 0) + ce = new PreExpr (overflow(ce1->toSignedInt() & ce2->toUnsignedInt())); + else if (ce2->val < 0) + ce = new PreExpr (overflow(ce1->toUnsignedInt() & ce2->toSignedInt())); + else + ce = new PreExpr (overflow(ce1->toUnsignedInt() & ce2->toUnsignedInt())); + delete ce1; + delete ce2; + delete[] a; + } +constant_expression(ce) ::= constant_expression(ce1) TOK_EXPR_EQ(e) constant_expression(ce2). + { + ce = new PreExpr (); + if (ce1->val == ce2->val) + ce->val = 1; + else + ce->val = 0; + delete ce1; + delete ce2; + delete[] e; + } +constant_expression(ce) ::= constant_expression(ce1) TOK_EXPR_NOTEQ(n) constant_expression(ce2). + { + ce = new PreExpr (); + if (ce1->val != ce2->val) + ce->val = 1; + else + ce->val = 0; + delete ce1; + delete ce2; + delete[] n; + } +constant_expression(ce) ::= constant_expression(ce1) TOK_EXPR_LESS(l) constant_expression(ce2). + { + ce = new PreExpr (); + if (ce1->val < ce2->val) + ce->val = 1; + else + ce->val = 0; + delete ce1; + delete ce2; + delete[] l; + } +constant_expression(ce) ::= constant_expression(ce1) TOK_EXPR_GREATER(g) constant_expression(ce2). + { + ce = new PreExpr (); + if (ce1->val > ce2->val) + ce->val = 1; + else + ce->val = 0; + delete ce1; + delete ce2; + delete[] g; + } +constant_expression(ce) ::= constant_expression(ce1) TOK_EXPR_LEQ(l) constant_expression(ce2). + { + ce = new PreExpr (); + if (ce1->val <= ce2->val) + ce->val = 1; + else + ce->val = 0; + delete ce1; + delete ce2; + delete[] l; + } +constant_expression(ce) ::= constant_expression(ce1) TOK_EXPR_GEQ(g) constant_expression(ce2). + { + ce = new PreExpr (); + if (ce1->val >= ce2->val) + ce->val = 1; + else + ce->val = 0; + delete ce1; + delete ce2; + delete[] g; + } +constant_expression(ce) ::= constant_expression(ce1) TOK_EXPR_PLUS(p) constant_expression(ce2). + { + ce = new PreExpr (overflow(ce1->val + ce2->val)); + delete ce1; + delete ce2; + delete[] p; + } +constant_expression(ce) ::= constant_expression(ce1) TOK_EXPR_MINUS(m) constant_expression(ce2). + { + ce = new PreExpr (overflow(ce1->val - ce2->val)); + delete ce1; + delete ce2; + delete[] m; + } +constant_expression(ce) ::= constant_expression(ce1) TOK_EXPR_STAR(s) constant_expression(ce2). + { + ce = new PreExpr (overflow(ce1->val * ce2->val)); + delete ce1; + delete ce2; + delete[] s; + } +constant_expression(ce) ::= constant_expression(ce1) TOK_EXPR_DIV(d) constant_expression(ce2). + { + ce = new PreExpr (floorl(ce1->val / ce2->val)); + delete ce1; + delete ce2; + delete[] d; + } +constant_expression(ce) ::= constant_expression(ce1) TOK_EXPR_MOD(m) constant_expression(ce2). + { + if (ce1->val < 0 && ce2->val < 0) + ce = new PreExpr (overflow(ce1->toSignedInt() % ce2->toSignedInt())); + else if (ce1->val < 0) + ce = new PreExpr (overflow(ce1->toSignedInt() % ce2->toUnsignedInt())); + else if (ce2->val < 0) + ce = new PreExpr (overflow(ce1->toUnsignedInt() % ce2->toSignedInt())); + else + ce = new PreExpr (overflow(ce1->toUnsignedInt() % ce2->toUnsignedInt())); + delete ce1; + delete ce2; + delete[] m; + } +constant_expression(ce) ::= constant_expression(ce1) TOK_EXPR_SHIFTL(sl) constant_expression(ce2). + { + if (ce1->val < 0 && ce2->val < 0) + ce = new PreExpr (overflow(ce1->toSignedInt() << ce2->toSignedInt())); + else if (ce1->val < 0) + ce = new PreExpr (overflow(ce1->toSignedInt() << ce2->toUnsignedInt())); + else if (ce2->val < 0) + ce = new PreExpr (overflow(ce1->toUnsignedInt() << ce2->toSignedInt())); + else + ce = new PreExpr (overflow(ce1->toUnsignedInt() << ce2->toUnsignedInt())); + delete ce1; + delete ce2; + delete[] sl; + } +constant_expression(ce) ::= constant_expression(ce1) TOK_EXPR_SHIFTR(sr) constant_expression(ce2). + { + if (ce1->val < 0 && ce2->val < 0) + ce = new PreExpr (overflow(ce1->toSignedInt() >> ce2->toSignedInt())); + else if (ce1->val < 0) + ce = new PreExpr (overflow(ce1->toSignedInt() >> ce2->toUnsignedInt())); + else if (ce2->val < 0) + ce = new PreExpr (overflow(ce1->toUnsignedInt() >> ce2->toSignedInt())); + else + ce = new PreExpr (overflow(ce1->toUnsignedInt() >> ce2->toUnsignedInt())); + delete ce1; + delete ce2; + delete[] sr; + } +constant_expression(ce) ::= unary_expression(ue). + { + ce = ue; + } + +/***********************************************************************/ +/* unary expression ****************************************************/ +/***********************************************************************/ + +unary_expression(ue) ::= primary_expression(pe). + { + ue = pe; + } +unary_expression(ue) ::= TOK_EXPR_PLUS(p) unary_expression(uex). [TOK_PRE_UNARY] + { + uex->val = overflow(+uex->val); ue = uex; + delete[] p; + } +unary_expression(ue) ::= TOK_EXPR_MINUS(m) unary_expression(uex). [TOK_PRE_UNARY] + { + uex->val = overflow(-uex->val); ue = uex; + delete[] m; + } +unary_expression(ue) ::= TOK_EXPR_TILDE(t) unary_expression(uex). [TOK_PRE_UNARY] + { + if (uex->val < 0) + uex->val = ~uex->toSignedInt(); + else + uex->val = ~uex->toUnsignedInt(); + ue = uex; + delete[] t; + } +unary_expression(ue) ::= TOK_EXPR_NOT(n) unary_expression(uex). [TOK_PRE_UNARY] + { + uex->val = !uex->val; ue = uex; + delete[] n; + } + +/***********************************************************************/ +/* primary expression **************************************************/ +/***********************************************************************/ + +primary_expression(pe) ::= TOK_EXPR_OCT(v). + { + pe = new PreExpr (strtoull (v, NULL, 8)); + delete[] v; + } +primary_expression(pe) ::= TOK_EXPR_DEC(v). + { + pe = new PreExpr (strtoull (v, NULL, 10)); + delete[] v; + } +primary_expression(pe) ::= TOK_EXPR_HEX(v). + { + pe = new PreExpr (strtoull (v, NULL, 16)); + delete[] v; + } +primary_expression(pe) ::= TOK_EXPR_CHAR(v). + { + pe = new PreExpr (overflow(PreExpr::convertChar (v))); + delete[] v; + } +primary_expression(pe) ::= TOK_EXPR_FLOAT(v). + { + *err << location << sev_warning + << "floating constant in preprocessor expression, truncate to integer" + << endMessage; + pe = new PreExpr (overflow(floorl(strtold (v, NULL)))); + delete[] v; + } +primary_expression(pe) ::= TOK_EXPR_LPAREN(lp) conditional_expression(cp) TOK_EXPR_RPAREN(rp). + { + pe = cp; + delete[] lp; + delete[] rp; + } diff --git a/Puma/src/cpp/PreFileIncluder.cc b/Puma/src/cpp/PreFileIncluder.cc new file mode 100644 index 0000000..37b1d77 --- /dev/null +++ b/Puma/src/cpp/PreFileIncluder.cc @@ -0,0 +1,569 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/TokenStream.h" +#include "Puma/Unit.h" +#include "Puma/Token.h" +#include "Puma/StrCol.h" +#include "Puma/SysCall.h" +#include "Puma/CScanner.h" +#include "Puma/FdSource.h" +#include "Puma/CTokens.h" +#include "Puma/Filename.h" +#include "Puma/PreParser.h" +#include "Puma/UnitManager.h" +#include "Puma/ErrorStream.h" +#include "Puma/PreParserState.h" +#include "Puma/PreFileIncluder.h" +#include "Puma/PreprocessorParser.h" +#include +#include +#include +#include +#include + +namespace Puma { + + +PreFileIncluder::PreFileIncluder (PreprocessorParser& parser) { + // Set the assigned preprocessor and remember dependent objects + preprocessor (&parser); + + // Search for include files in all known include directories. + // Needed for the #include_next directive to tell the FileIncluder + // which directories should be skipped. + _skip = 0; + + _firstIncludeDir = _includeDirs.end(); +} + +// Set the associated preprocessor parser +void PreFileIncluder::preprocessor (PreprocessorParser *pp) { + _parser = pp; + _state = pp->parserState (); + _unitManager = pp->unitManager (); + _err = _state->err; +} + +// Add a new non-system include path. +void PreFileIncluder::addIncludePath (const char* path) { + // do not add include paths twice! + if (path && ! isIncludePath(path)) { + // add before the first non-system include dir (as last non-system include dir searched) + _includeDirs.insert(_firstIncludeDir, path); + --_firstIncludeDir; + _includeDirLookup[path] = false; + } +} + +// Add a new system include path. +void PreFileIncluder::addSystemIncludePath (const char *path) { + if (path) { + std::map::iterator sysDir = _includeDirLookup.find(path); + if (sysDir != _includeDirLookup.end()) { + // already known system include path? + if (sysDir->second == true) + return; // ignore + + // previously added as non-system include path; remove it + std::list::iterator dirsIdx = _includeDirs.end(); + for (--dirsIdx; dirsIdx != _includeDirs.begin(); --dirsIdx) { + if (*dirsIdx == path) { + _includeDirs.erase(dirsIdx); + break; + } + } + } + + // add as first path in list (as last searched include dir) + _includeDirs.push_front (path); + _includeDirLookup[path] = true; // mark as system include dir + } +} + +// Check if the given include directory is a system include directory. +bool PreFileIncluder::isSystemIncludePath(const char *path) const { + if (path) { + const std::map::const_iterator &lookupIdx = _includeDirLookup.find(path); + return (lookupIdx != _includeDirLookup.end() && lookupIdx->second == true); + } + return false; +} + +// Check if the given directory is a known include directory. +bool PreFileIncluder::isIncludePath(const char *path) const { + return (path && _includeDirLookup.find(path) != _includeDirLookup.end()); +} + +// Include a file. +Unit* PreFileIncluder::handleIncludeOption (const char* string) + { + Unit *unit = 0; + if (! string) return unit; + + // If file name isn't empty try to locate the file, else + // we have a syntax error. + if (strlen (string)) + unit = searchFile (string, true); + else { + unit = (Unit*)0; + *_err << sev_error + << "empty file name in `--include'" + << endMessage; + } + + return unit; + } + + +// Include a file. +Unit* PreFileIncluder::includeFile (const char* string) + { + if (! string) return (Unit*) 0; + + // Build the token unit from string. + Unit* unit = buildUnit (string); + + Token* first = (Token*) unit->first (); + Token* last = (Token*) unit->last (); + + if (first && last) + { + // Pattern "..." found. Include from cwd. + if (first->is_core () && first->type () == TOK_STRING_VAL) + { + return includeFromCwd (unit); + } + + // Pattern <...> found. Include from system. + else if (first->is_core () && first->type () == TOK_LESS && + last->is_core () && last->type () == TOK_GREATER) + { + return includeFromSystem (unit); + } + } + + // Only reached in case of a syntax error. + if (_state->currToken) + *_err << _state->currToken->location (); + *_err << sev_error << "`#include' expects \"filename\" or " + << endMessage; + + // Return an empty unit. + return (Unit*)0; + } + + +// Include the next file of the given name. +Unit* PreFileIncluder::includeNextFile (const char* string) + { + if (! string) return (Unit*) 0; + + // Get the name of the current file. + const char* location = _state->currToken->location ().filename ().name (); + char* path = StrCol::dup (location ? location : ""); + + // Get the current path only. + char* backslash = strrchr (path, '/'); + + if (backslash) + { + *backslash = '\0'; + + // Calculate the paths to skip. + std::list::reverse_iterator dirsIdx = _includeDirs.rbegin(); + for (_skip = 1; dirsIdx != _includeDirs.rend() && *dirsIdx != path; ++_skip, ++dirsIdx); + } + + // Now include the file. + Unit* unit = includeFile (string); + + // Reset to search in all paths. + _skip = 0; + + delete[] path; + return unit; + } + + +// Try to include a file from current working directory. +Unit* PreFileIncluder::includeFromCwd (Unit* unit) + { + // At first get the name of the file. + int size = strlen (((Token*) unit->first ())->text ()); + char* name = new char[size + 5]; + + strncpy (name, ((Token*) unit->first ())->text (), size-1); + name[size-1] = '\0'; + delete unit; + + // If file name isn't empty try to locate the file, else + // we have a syntax error. + if (strlen (name + 1)) + unit = searchFile (name + 1, true); + else { + unit = (Unit*)0; + *_err << _state->currToken->location () << sev_error + << "empty file name in `#include'" + << endMessage; + } + + delete[] name; + return unit; + } + + +// Try to include the file from system include directories. +Unit* PreFileIncluder::includeFromSystem (Unit* unit) + { + Token* token = (Token*) unit->first (); + std::ostringstream file; + + // Get the file name. + for (token = (Token*) unit->next ((Token*) unit->first ()); ; + token = (Token*) unit->next (token)) { + if (token->is_core () && token->type () == TOK_GREATER) + break; + file << token->text (); + } + + delete unit; + + // If file name is empty we have a syntax error. + if (! file.str ().length ()) { + *_err << _state->currToken->location () << sev_error + << "empty file name in `#include'" + << endMessage; + return (Unit*)0; + } + + // Try to locate the file. + unit = searchFile (file.str ().c_str (), false); + + return unit; + } + + +// Try to locate the file. +Unit* PreFileIncluder::searchFile (const char* file, bool search_in_cwd) + { + Unit *unit = (Unit*) 0; + + // check if this is an absolute path + Filename filename (file); + if (filename.is_absolute ()) { + unit = doInclude (file, file, true); + return unit; + } + + // If pattern `#include "..."' found try to include the file + // from current working directory first. + if (search_in_cwd) + { + // Get the current working directory. + const char* path = _state->currToken ? _state->currToken->location ().filename ().name () : 0; + char* cwd = StrCol::dup (path ? path : ""); + char* backslash = strrchr (cwd, '/'); + + // Combine the current working directory with the file + // to include to the full filename. + if (backslash) { + *backslash = '\0'; + char* fullname = new char[strlen (cwd) + strlen (file) + 3]; + sprintf (fullname, "%s/%s", cwd, file); + if (! path || strcmp(fullname, path) != 0) + unit = doInclude (fullname, file, false); + delete[] fullname; + } else if (! path || strcmp(file, path) != 0) + unit = doInclude (file, file, false); + + delete[] cwd; + } + + if (! unit) + { + // If there are no include paths left it's an error case. + if (_includeDirs.size() - _skip <= 0) + { + if (_state->currToken) + *_err << _state->currToken->location (); + *_err << sev_error + << "no include path in which to find `" + << file << "'" << endMessage; + } + else + { + // Go through the include directories and try to + // include the file. + std::list::reverse_iterator dirsIdx = _includeDirs.rbegin(); + for (int i = 0; i < _skip && dirsIdx != _includeDirs.rend(); ++i, ++dirsIdx); + + while (dirsIdx != _includeDirs.rend()) + { + // Build file name like `path/file' + std::string fullname = *dirsIdx + "/" + file; + ++dirsIdx; + + // Now try to include the file from current system + // include directory. If this is not the last directory + // in list report no errors. + if (dirsIdx != _includeDirs.rend()) + unit = doInclude (fullname.c_str(), file, false); + else + unit = doInclude (fullname.c_str(), file, true); + + if (unit) + break; // File found. + } + } + } + + // Return filled unit or a empty unit if file not found. + return unit; + } + + +// Include the file. +Unit* PreFileIncluder::doInclude (const char* fullname, const char* file, + bool report_errors) + { + int fd; + Unit *unit; + + if (fullname[0] == '.' && fullname[1] == '/') + { + fullname += 2; + } + + // If we already have included the file sometime before, + // we don't need to scan it again and use the old one. + if (! (unit = _unitManager->get (fullname, true))) + { + // Open the file. If not there report the error or return silently. + if ((fd = SysCall::open (fullname, O_RDONLY)) == -1) + { + if (report_errors) + { + if (_state->currToken) + *_err << _state->currToken->location (); + *_err << file << ": " + << sev_error << "no such file or directory" + << endMessage; + } + return (Unit*) 0; + } + + // If file is a directory an error occured. + FileInfo fi; + if (SysCall::fstat (fd, fi, _err) && fi.is_dir ()) + { + if (report_errors) + { + if (_state->currToken) + *_err << _state->currToken->location (); + *_err << sev_error << "input file `" << file + << "' is a directory" << endMessage; + } + SysCall::close (fd, _err); + return (Unit*) 0; + } + + // It's the first time we include this file, so we have + // to build a new unit of it. + unit = _unitManager->scanSource (fullname, new FdSource (fd), true); + SysCall::close (fd, _err); + + if (! unit) return (Unit*) 0; + } + + // Push the unit on token stack. + pushOnStack (unit); + + return unit; + } + + +// check if this file has an include guard that is already active +bool PreFileIncluder::hasActiveIncludeGuard (Unit *unit) { + // first check if this unit was already included + _guarded = false; + std::map::iterator iter = _includedUnits.find (unit); + if (iter != _includedUnits.end ()) { + Token *guard = (*iter).second; + // iff the file has a guard variable and it is defined, true is returned + if (guard && _parser->macroManager ()->getMacro (guard->text ())) + _guarded = true; + } + else { + _includedUnits.insert (std::pair (unit, hasIncludeGuard (unit))); + } + return _guarded; +} + + +// check if this file has an include guard +Token *PreFileIncluder::hasIncludeGuard (Unit *unit) { + Token *guard = 0; + Token *tok = (Token*)unit->first (); + // skip comments and whitespace + while (tok && (tok->is_whitespace () || tok->is_comment ())) + tok = (Token*)unit->next (tok); + // the next token has to be #ifndef + if (!(tok && tok->is_preprocessor () && tok->type () == TOK_PRE_IFNDEF)) + return 0; + tok = (Token*)unit->next (tok); + // now whitespace + if (!(tok && tok->is_whitespace ())) + return 0; + tok = (Token*)unit->next (tok); + // the next has be an identifier => the name of the guard macro + if (!(tok && tok->is_identifier ())) + return 0; + guard = tok; + tok = (Token*)unit->next (tok); + // skip comments and whitespace + while (tok && (tok->is_whitespace () || tok->is_comment ())) + tok = (Token*)unit->next (tok); + // the next token has to be #define + if (!(tok && tok->is_preprocessor () && tok->type () == TOK_PRE_DEFINE)) + return 0; + tok = (Token*)unit->next (tok); + // now whitespace + if (!(tok && tok->is_whitespace ())) + return 0; + tok = (Token*)unit->next (tok); + // the next has be an identifier => the name of the guard macro + if (!(tok && tok->is_identifier ())) + return 0; + // check if the identifier is our guard variable + if (strcmp (tok->text (), guard->text ()) != 0) + return 0; + tok = (Token*)unit->next (tok); + // find the corresponding #endif + int level = 1; + while (tok) { + if (tok->is_preprocessor ()) { + if (tok->type () == TOK_PRE_IF || tok->type () == TOK_PRE_IFDEF || + tok->type () == TOK_PRE_IFNDEF) + level++; + else if (tok->type () == TOK_PRE_ENDIF) { + level--; + if (level == 0) + break; + } + } + tok = (Token*)unit->next (tok); + } + if (level > 0) + return 0; + tok = (Token*)unit->next (tok); + // skip comments and whitespace + while (tok && (tok->is_whitespace () || tok->is_comment ())) + tok = (Token*)unit->next (tok); + // here we should have reached the end of the unit! + if (tok) + return 0; + + // at this point we are sure that there is an include guard in this file + return guard; +} + + +// Push the unit on token stack. +void PreFileIncluder::pushOnStack (Unit *unit) { + if (!hasActiveIncludeGuard (unit)) + ((TokenStream*) (_parser->scanner ()))->push (unit); +} + + +// Return true if string is not of format "..." or <...>. +bool PreFileIncluder::assumeMacroCalls (const char* string) const + { + if (! string) return true; + + // Skip leading white spaces. + while (StrCol::isSpace (*string)) string++; + + // Now there has to be a '"' or '<'. + if (*string != '"' && *string != '<') + return true; + + // Skip trailing white spaces. + int i = strlen (string) - 1; + for (; i >= 1; i--) + if (! StrCol::isSpace (string[i])) + break; + + if (i < 1) return true; + + // Now there has to be a '"' or '>'. + if (*string == '"' && string[i] == '"') return false; + if (*string == '<' && string[i] == '>') return false; + + return true; + } + + +// Build a macro expanded unit from a string. +Unit* PreFileIncluder::buildUnit (const char* string) + { + Token* token, *tmp; + Unit* unit = new Unit (); + + // Macro operations (# and ##) are allowed + _parser->cscanner ().allow_macro_ops (); + + // Reset the macro expander and component scanner. + _expander.reset (_parser); + + // Scan the string. + if (assumeMacroCalls (string)) { + _expander.inInclude (true); + char *mstr = _expander.expandMacros (string); + _expander.inInclude (false); + _parser->cscanner ().fill_unit (mstr, *unit); + delete[] mstr; + } else + _parser->cscanner ().fill_unit (string, *unit); + + // Remove spaces at begin of unit. + for (token = (Token*) unit->first (); token; ) + { + if (!token->is_whitespace ()) + break; + tmp = token; + token = (Token*) unit->next (token); + unit->kill (tmp); + } + + // Remove spaces at end of unit. + for (token = (Token*) unit->last (); token; ) + { + if (! token->is_whitespace ()) + break; + tmp = token; + token = (Token*) unit->prev (token); + unit->kill (tmp); + } + + _parser->cscanner ().allow_macro_ops (false); + return unit; + } + + +} // namespace Puma diff --git a/Puma/src/cpp/PreFileIncluder.h b/Puma/src/cpp/PreFileIncluder.h new file mode 100644 index 0000000..8180ca8 --- /dev/null +++ b/Puma/src/cpp/PreFileIncluder.h @@ -0,0 +1,127 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __pre_file_includer__ +#define __pre_file_includer__ + +// Preprocessor class to handle includes. + +#include "Puma/PreprocessorParser.h" +#include "Puma/PreMacroExpander.h" +#include "Puma/Filename.h" +#include "Puma/Array.h" + +#include +#include +#include + +namespace Puma { + + +class PreParserState; +class TokenStream; +class UnitManager; +class Unit; + +class PreFileIncluder { + int _skip; + PreParserState *_state; + ErrorStream *_err; + UnitManager *_unitManager; + PreprocessorParser *_parser; + + PreMacroExpander _expander; + + // Ordered list of include paths. + std::list _includeDirs; + std::list::iterator _firstIncludeDir; + + // Include paths lookup and system/non-system include path status map. + std::map _includeDirLookup; + + // true if the last included file was protected by an active include guard + bool _guarded; + + // the set of included units, the Token is 0 or the name of an include guard + std::map _includedUnits; + + // Builds a macro expanded unit from a string. + Unit *buildUnit (const char *); + + // Prepare to include a file from current working directory. + Unit *includeFromCwd (Unit *); + + // Prepare to include a file from system include directories. + Unit *includeFromSystem (Unit *); + + // Try to locate the include file. + Unit *searchFile (const char *, bool); + + // Include the file. + Unit *doInclude (const char *, const char *, bool); + + // check if this file has an include guard that is already active + bool hasActiveIncludeGuard (Unit *unit); + + // check if this file has an include guard + static Token *hasIncludeGuard (Unit *unit); + + // Return true if string is not of format "..." or <...>. + bool assumeMacroCalls (const char *) const; + +public: + PreFileIncluder (PreprocessorParser &); + + // Push unit on token stack. + void pushOnStack (Unit *); + + // Set and get the associated preprocessor parser + void preprocessor (PreprocessorParser *pp); + PreprocessorParser *preprocessor () const { return _parser; } + + // Include a file. + Unit *includeFile (const char *name); + Unit *handleIncludeOption (const char *name); + + // Include the next file of the given name. + Unit *includeNextFile (const char *name); + + // returns true if the last included file was protected by an active + // include guard + bool guarded () const { return _guarded; } + + // Add a new non-system include path to list of include paths. + void addIncludePath (const char *path); + + // Add a new system include path to list of include paths. + void addSystemIncludePath (const char *path); + + // Get the system and non-system include directories. + std::list &getIncludePaths () { return _includeDirs; } + + // Check if the given directory is a known include directory. + bool isIncludePath(const char *path) const; + + // Check if the given include directory is a system include directory. + bool isSystemIncludePath(const char *path) const; +}; + + +} // namespace Puma + +#endif /* __pre_file_includer__ */ diff --git a/Puma/src/cpp/PreLevelState.h b/Puma/src/cpp/PreLevelState.h new file mode 100644 index 0000000..7d9167f --- /dev/null +++ b/Puma/src/cpp/PreLevelState.h @@ -0,0 +1,71 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __pre_level_state__ +#define __pre_level_state__ + +// Store the current state of nested conditionals. A nested conditional +// is a conditional group within a conditional group, and such a state +// consists of informations about the depth of nesting (the level) and +// the current value of the conditional group at this level. It is used +// to controll which source code will be ignored. + +#include "Puma/Array.h" + +namespace Puma { + + +class PreLevelState { + long _level; + + // The state structure. + struct _state { + bool state; // The level value. + bool passOn; // Decide whether code will be not ignored. + }; + + // Array to store the state information of every level. + Array<_state> _levels; + +public: + PreLevelState () { reset (); } + + // Return to level 0, that means no nesting. + void reset () { _level = 0; _levels[0].state = true; + _levels[0].passOn = true; } + + // Return from a subconditional. + void higher () { if (--_level < 0) _level = 0; } + + // Enter a subconditional. + void deeper () { _levels[++_level].state = true; + _levels[_level].passOn = true; } + + // Set the state of the current level. + void setState (bool state) { _levels[_level].state = state; } + void setPassOn (bool state) { _levels[_level].passOn = state; } + + // Get the state of the current level. + bool state () { return _levels[_level].state; } + bool passOn () { return _levels[_level].passOn; } +}; + + +} // namespace Puma + +#endif /* __pre_level_state__ */ diff --git a/Puma/src/cpp/PreMacro.cc b/Puma/src/cpp/PreMacro.cc new file mode 100644 index 0000000..a4f6436 --- /dev/null +++ b/Puma/src/cpp/PreMacro.cc @@ -0,0 +1,133 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/PreTreeToken.h" +#include "Puma/PreTree.h" +#include "Puma/PreMacro.h" +#include "Puma/StrCol.h" +#include "Puma/CScanner.h" + + +namespace Puma { + + +// Constructor for function-like macros. +PreMacro::PreMacro (const DString &name, PreTree *args, const char *body, char flags) { + const char *text; + + // Get the macro name and body. + _name = name; + _body = body ? StrCol::dup (body) : (const char*)0; + + // It's a function-like macro. + _flags = (char)FUNCTION_MACRO | flags; + + // Copy macro arguments. + if (args) { + _arguments = new MacroArgs; + for (int i = 0; i < args->sons (); i++) { + text = ((PreTreeToken*) args->son (i))->token ()->text (); + // Because the commas between the arguments are collected too + // they have to be filtered out. + if (*text != ',') + _arguments->push_back (text); + } + + // It's a function-like macro without any arguments. + } else { + _arguments = (MacroArgs*)0; + } +} + + +// Constructor for function-like macros. +PreMacro::PreMacro (const DString &name, MacroArgs *args, const char *body, char flags) { + // Get the macro name, arguments, and body. + _name = name; + _arguments = (args ? args : (MacroArgs*)0); + _body = body ? StrCol::dup (body) : (const char*)0; + + // It's a function-like macro. + _flags = (char)FUNCTION_MACRO | flags; +} + + +// Constructor for simple macros (constants). +PreMacro::PreMacro (const DString &name, const char *body, char flags) { + _flags = flags; + + _arguments = (MacroArgs*)0; + + // Get name and body. + _name = name; + _body = body ? StrCol::dup (body) : (const char*)0; +} + + +// Copy-constructor. +PreMacro::PreMacro (const PreMacro ¯o) { + // Copy macro name and body. + _name = macro._name; + _body = macro._body ? StrCol::dup (macro._body) : (const char*)0; + + // Copy macro attributes. + _flags = macro._flags; + _location = macro._location; + + // Copy the arguments. + _arguments = (macro._arguments ? new MacroArgs (*macro._arguments) : (MacroArgs*)0); +} + +PreMacro::~PreMacro () { + if (_body) + delete[] _body; + if (_arguments) + delete _arguments; +} + +void PreMacro::addArg (const std::string &arg_name) { + if (! _arguments) { + _arguments = new MacroArgs; + // It's a function-like macro. + _flags |= (char)FUNCTION_MACRO; + } + _arguments->push_back (arg_name); +} + +void PreMacro::setBody (const char *s) { + if (_body) + delete[] _body; + _body = StrCol::dup(s); + _body_unit.clear (); +} + +void PreMacro::buildUnit (CScanner &scanner) { + int i; + const char *string = _body; + + // Skip leading white spaces. + for (i = 0; StrCol::isSpace (string[i]); i++); + string = &string[i]; + + // Scan the string and fill the unit. + scanner.allow_macro_ops (); + scanner.fill_unit (string, _body_unit); + scanner.allow_macro_ops (false); +} + +} // namespace Puma diff --git a/Puma/src/cpp/PreMacro.h b/Puma/src/cpp/PreMacro.h new file mode 100644 index 0000000..68eac64 --- /dev/null +++ b/Puma/src/cpp/PreMacro.h @@ -0,0 +1,107 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __pre_macro__ +#define __pre_macro__ + +// Preprocessor macro class. There are two types of macros. The first +// is called a simple macro or a symbolic constant macro. It consists +// only of a macro name and the macro body. The second type of macros +// is called a function-like macro. In addition it consists of a list +// of arguments. + +#include "Puma/ListElement.h" +#include "Puma/Location.h" +#include "Puma/DString.h" +#include "Puma/Chain.h" +#include "Puma/Unit.h" + +#include +#include + +namespace Puma { + + +class PreTree; +class CScanner; + +class PreMacro : public Chain { +public: + typedef std::list MacroArgs; + + enum { + FUNCTION_MACRO = 1, // Function-like macro. + VAR_ARG_MACRO = 2, // Variable number of arguments. + LOCK_MACRO = 4, // Macro cannot be redefined or undefined. + INHIBIT_MACRO = 8 // Macro cannot be defined. + }; + +private: + const char* _body; // Macro body. + DString _name; + char _flags; // Macro flags. + Location _location; // Location of the #define directive. + MacroArgs *_arguments; // The arguments array. + Unit _body_unit; // The unit representation of the body + +public: + // Constructors for function-like macros. + PreMacro (const DString &, PreTree *, const char *, char = 0); + PreMacro (const DString &, MacroArgs *, const char *, char = 0); + + // Constructor for simple macros (constants). + PreMacro (const DString &, const char *, char = 0); + + PreMacro (const PreMacro &); + virtual ~PreMacro (); + + // Get macro attributes. + const DString &getName () const { return _name; } + const char *getBody () const { return _body; } + const Unit &getBodyUnit (CScanner &scanner) { + if (_body_unit.empty ()) + buildUnit (scanner); + return _body_unit; + } + short numArgs () const { return _arguments ? _arguments->size () : 0; } + const MacroArgs *getArgs () const { return _arguments; } + // add an argument: the string is still owned by the caller and not copied! + void addArg (const std::string &arg_name); + + // Set macro attributes + void setBody (const char *); + + // Query macro flags. + bool varArgs () const { return _flags & VAR_ARG_MACRO; } + bool isFunction () const { return _flags & FUNCTION_MACRO; } + bool isInhibited () const { return _flags & INHIBIT_MACRO; } + bool isLocked () const { return _flags & LOCK_MACRO; } + + // Set/get #define location. + Location location () const { return _location; } + void location (Location l) { _location = l; } + +private: + // create the unit representation + void buildUnit (CScanner &scanner); +}; + + +} // namespace Puma + +#endif /* __pre_macro__ */ diff --git a/Puma/src/cpp/PreMacroExpander.cc b/Puma/src/cpp/PreMacroExpander.cc new file mode 100644 index 0000000..e12c7d3 --- /dev/null +++ b/Puma/src/cpp/PreMacroExpander.cc @@ -0,0 +1,944 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/PreAssertionEvaluator.h" +#include "Puma/PreprocessorParser.h" +#include "Puma/PreMacroExpander.h" +#include "Puma/PreMacroOpTokens.h" +#include "Puma/PreMacroManager.h" +#include "Puma/PreParserState.h" +#include "Puma/StringSource.h" +#include "Puma/ErrorStream.h" +#include "Puma/TokenStream.h" +#include "Puma/UnitManager.h" +#include "Puma/CScanner.h" +#include "Puma/CTokens.h" +#include "Puma/PreMacro.h" +#include "Puma/StrCol.h" +#include "Puma/Token.h" +#include "Puma/MacroUnit.h" +#include +#include +#include + +namespace Puma { + + +PreMacroExpander::PreMacroExpander (PreprocessorParser* parser) + { + _preexpander = new PreMacroExpander (); + _in_include = false; + reset (parser); + } + + +PreMacroExpander::PreMacroExpander () + { + _in_include = false; + _preexpander = (PreMacroExpander*) 0; + } + + +// Reset the expander to the initial state. +void PreMacroExpander::reset (PreprocessorParser* parser) + { + if (! _preexpander) + _preexpander = new PreMacroExpander (); + _macroManager = parser->macroManager (); + _unitManager = parser->locals (); + _macroStack = parser->macroStack (); + _err = parser->parserState ()->err; + _parser = parser; + _in_include = false; + } + + +// Reset the expander to a special initial state. +void PreMacroExpander::reset (PreprocessorParser* parser, + Array* stack) + { + reset (parser); + _macroStack = stack; + } + + +// Prescan an argument. +Unit& PreMacroExpander::prescanArgument (Unit* arg) const + { + int i; + + // Create a new macro stack. + Array macroStack; + + // Copy the old macro stack to the new macro stack. + for (i = 0; i < _macroStack->length (); i++) + macroStack.append (_macroStack->get (i)); + + // Create a new macro expander for the argument, to expand + // the macros of the argument unit separately. + _preexpander->reset (_parser, ¯oStack); + + // Expand the macros and get an unit as result again. + Unit *unit = _preexpander->expandMacros (arg); + + // Ensure that the macros on the macro stack will not + // be deleted. + for (i = 0; i < macroStack.length (); i++) + macroStack[i] = (PreMacro*) 0; + + return *unit; + } + + +// Expand all macros of the given unit. +Unit* PreMacroExpander::expandMacros (Unit* expandUnit) + { + if (! expandUnit) return (Unit*) 0; + + Token* token; + PreMacro* macro; + Unit* unit = new MacroUnit (); // Create an empty unit. + + PreParserState state; // Create a new parser state object. + TokenStream stream; // Create a new token stream object. + + PreAssertionEvaluator evaluator (*_parser, &stream); + + // If the special macro `defined' is defined we want to expand + // all macros of an expression and at the same time there are + // some special things to observe. + bool isExpression = _macroManager->getMacro ("defined") ? true : false; + + // Ensure that we scan for tokens from our own token stream. + _scanner = &stream; + + // Push the unit to expand on stream. + pushUnit (stream, expandUnit); + + // Scan the unit for macros and assertions. + while ((token = stream.next ())) + { + // Recognize end of macro expansion and adjust macro stack accordingly. + state.updateMacroStack (*_macroStack, stream.length ()); + + // An assertion was found and will be evaluated. + if (token->type () == TOK_MO_HASH && isExpression && token->is_macro_op ()) + evaluator.evaluateAssertion (unit); + + // Search for C++ identifiers and check whether it is a macro. + else if (token->is_core ()) + { + if ((macro = _macroManager->getMacro (token->dtext ()))) + { + // Check whether a macro is allowed to expand. + if (! state.isSelfReferentialMacro (macro, *_macroStack)) + { + // Try to expand the macro. + if (expandMacro (macro, token)) + { + // Remember the expanded macro to prevent for + // expanding the macro twice. + state.putMacroOnStack (*_macroStack, macro, stream.length ()); + + // Scan the next token. + continue; + } + } + } + + // Identifier isn't a macro call. So append it unchanged to + // return unit. + if (! token->is_identifier () || ! isExpression) + unit->append (*((Token*) token->duplicate ())); + + // But if the special macro `defined' is defined we are + // expanding macros in an expression and therefore every + // identifier that is not a macro has to be replaced by a + // single 0. + else + _parser->cscanner ().fill_unit ("0", *unit); + } + + // Every other token will be putted unchanged into the + // return unit. + else + unit->append (*((Token*) token->duplicate ())); + } + + // Recognize end of macro expansion and adjust macro stack accordingly. + state.updateMacroStack (*_macroStack, stream.length ()); + + // Return the macro expanded unit. + return unit; + } + + +// Expand all macros of the given string. +char* PreMacroExpander::expandMacros (const char* string) + { + if (! string) return (char*) 0; + + // To expand macros within a string we simply build an unit from + // the string and call the method to expand macros within an unit + // with that very unit as argument. + Unit *in = buildUnit (string); + Unit *out = expandMacros (in); + + // Now we have a macro expanded unit and want to return a string + // again. So we build a string from that unit and return it. + char *result = (out ? out->toString () : 0); + delete in; + delete out; + + return result; + } + + +// Check whether there really is a function-like macro call. +bool PreMacroExpander::checkForGoOn (bool mode) const + { + // Here it is not possible to call next() to get the next tokens to + // check whether this is really a macro call or something else, due to + // next() returns a token from the stream and cannot go back to this + // token at end of the function. But we have to reach the tokens again + // to evaluate the macro call if it is one. So we have to go through + // the unit independently. + long pos = _scanner->length () - 1; + + // Get the top token source. + UnitTokenSrc *src = _scanner->lookup (pos); + + // Get the unit and the current token. + Token* token = src->current (); + Unit* unit = src->unit (); + + // Skip white spaces and comments. + do { + // If the end of an unit is reached we have to go to the next + // unit on stack and scan that unit too. + while (! (token = (Token*) unit->next (token))) + { + // If there is no unit left on stack, it's not a macro call. + if (! ((--pos >= 0) && (src = _scanner->lookup (pos)))) + return false; + unit = src->unit (); + token = src->current (); + } + } while (token->is_whitespace () || token->is_comment ()); + + if (token->is_core ()) + { + // If there is a left parenthesis it is a function-like macro. + if (mode) { + if (token->is_open ()) + return true; + } + + // This is the special `defined' mode. After the `defined' keyword + // there can be either a left parenthesis OR immediatelly an identifier. + // This is the case of an identifier on which we also return true. + else if (token->is_identifier ()) + return true; + } + + // It was not a call to a funtion-like macro. + return false; + } + + +// Build a unit from a string. +Unit* PreMacroExpander::buildUnit (const char* string) const + { + // Create the component scanner and an empty unit. + Unit *unit = new MacroUnit (); + + // Allow macro concatenation and stringification operators + _parser->cscanner ().allow_macro_ops (); + + // Skip leading white spaces. + while (StrCol::isSpace(*string)) string++; + + int len = strlen(string); + if (StrCol::isSpace(string[len-1])) + { + // Skip trailing white spaces. + while (len > 1 && StrCol::isSpace(string[len-1])) len--; + char* buf = StrCol::dup (string, len); + + // Scan the string and fill the unit. + _parser->cscanner ().fill_unit (buf, *unit); + delete[] buf; + } + else + { + // Scan the string and fill the unit. + _parser->cscanner ().fill_unit (string, *unit); + } + + // Reset scanner + _parser->cscanner ().allow_macro_ops (false); + + // Return the filled unit. + return unit; + } + + +// Compare two macro argument identifier. +bool PreMacroExpander::equal (const char* str1, const char* str2) const + { + if (! str1 || ! str2) return false; + + int i; + + // Skip leading white spaces. + while (StrCol::isSpace (*str1)) str1++; + + // Go to the end of the identifier. + for (i = 0; ! StrCol::isSpace (str1[i]) && str1[i] != '\0'; i++); + + // Compare the two identifiers. + if (strncmp (str1, str2, i) == 0 && str2[i] == '\0') + return true; + + return false; + } + + +// Test whether a string is an argument of a macro. +int PreMacroExpander::isArg (const char* string, PreMacro* macro) const + { + const PreMacro::MacroArgs *args = macro->getArgs (); + if (!args) return -1; // -> no args, no hit + + // Go through the argument list of the macro and compare the + // string with the arguments. + int i = 0; + for (PreMacro::MacroArgs::const_iterator iter = args->begin (); + iter != args->end (); ++iter) + { + // Return the index of the argument in argument array + // if found. + if (equal (string, (*iter).c_str ())) + return i; + i++; + } + + // -1 signals that it`s not an argument. + return -1; + } + + +// Replace an argument unchanged. +void PreMacroExpander::replaceUnchangedArg (int index, Unit* argUnit, + PreArgDesc &args, Unit* unit, Token *token, bool varnargs) const + { + Token* prev = prevPreprocessingToken (token, unit); + Token* next = nextPreprocessingToken (token, unit); + + // It's not an empty argument or an additional argument. + if (index <= args.numArgs ()-1) + { + MacroUnit& arg = args.getArg (index); + + // If no concatenation operator was found the argument has + // to be prescanned before it will be inserted into the unit. + // During prescan all macros in the argument will be expanded. + + if (prev && prev->is_macro_op () && prev->type () == TOK_MO_HASHHASH) + { + // The argument has to be inserted in unit as it is. + *argUnit += arg; + + // If the argument consists only of spaces and comments, + // then the concat operator can be deleted. Concating X + // with spaces and comments results in X. + if (onlySpacesAndComments (arg)) + { + // The concat operator has a special meaning when placed + // between a comma and a variable argument. If the variable + // argument is left out when the macro is used, then the + // comma before the concat operator will be deleted. + if (varnargs && index == args.numArgs ()-1) + { + // Search the comma. + Token* comma = prevPreprocessingToken (prev, unit); + if (comma && comma->type () == TOK_COMMA) + { + unit->kill (comma); // Delete the comma. + } + } + unit->kill (prev); // Delete the concat operator. + } + // The concat operator is removed when placed between a + // comma and a variable argument. + else if (varnargs && index == args.numArgs ()-1) + { + // Search the comma. + Token* comma = prevPreprocessingToken (prev, unit); + if (comma && comma->type () == TOK_COMMA) + { + unit->kill (prev); // Delete the concat operator. + } + } + } + else if (next && next->is_macro_op () && next->type () == TOK_MO_HASHHASH) + { + // The argument has to be inserted in unit as it is. + *argUnit += arg; + + // If the argument consists only of spaces and comments, + // then the concat operator can be deleted. Concating X + // with spaces and comments results in X. + if (onlySpacesAndComments (args.getArg (index))) + { + unit->kill (next); // Delete the concat operator. + } + } + else + { + // Concatenation operator not found. Prescan the argument. + Unit* unit = &prescanArgument (&arg); + argUnit->move ((Token*)argUnit->last (), *unit); + delete unit; + } + } + // Rest argument of a variadic macro. + else if (varnargs && prev) + { + // The concat operator has a special meaning when placed + // between a comma and a variable argument. If the variable + // argument is left out when the macro is used, then the + // comma before the concat operator will be deleted. + if (prev->is_macro_op () && prev->type () == TOK_MO_HASHHASH) + { + // Search the comma. + Token* comma = prevPreprocessingToken (prev, unit); + if (comma && comma->type () == TOK_COMMA) + { + unit->kill (comma); // Delete the comma. + } + unit->kill (prev); // Delete the concat operator. + } + } + } + + +// Get the next non-whitespace non-comment token +Token* PreMacroExpander::nextPreprocessingToken (Token* token, Unit* unit) const { + for (token = (Token*) unit->next (token); token; token = (Token*) unit->next (token)) + if (! token->is_whitespace () && ! token->is_comment ()) + break; + return token; +} + + +// Get the previous non-whitespace non-comment token +Token* PreMacroExpander::prevPreprocessingToken (Token* token, Unit* unit) const { + for (token = (Token*) unit->prev (token); token; token = (Token*) unit->prev (token)) + if (! token->is_whitespace () && ! token->is_comment ()) + break; + return token; +} + + +// Check if the given unit contains only spaces and comments. +bool PreMacroExpander::onlySpacesAndComments (MacroUnit& unit) const { + for (Token* token = (Token*) unit.first (); token; token = (Token*) unit.next (token)) + if (! token->is_whitespace () && ! token->is_comment ()) + return false; + return true; +} + + +// Stringify and replace an argument. +void PreMacroExpander::replaceStringifiedArg (int index, Unit* unit, PreArgDesc &args) const + { + Unit* argUnit; + Token* token; + + // If valid index stringify the argument. + if (index <= args.numArgs ()-1) + { + // Get the argument. + argUnit = &args.getArg (index); + + // If it is an empty unit build an empty string token. + if (argUnit->empty ()) + _parser->cscanner ().fill_unit ("\"\"", *unit); + + // If not an empty unit concatenate all tokens to + // a single string constant token. + else + { + std::ostringstream str; + + // Build the string constant. + str << "\""; + for (token = (Token*) argUnit->first (); token; + token = (Token*) argUnit->next (token)) + { + // Escape double quotes and backslashes in strings or character constants + if (token->type () == TOK_STRING_VAL || token->type () == TOK_CHAR_VAL) + { + const char *strval = (const char*) token->text (); + unsigned int len = (unsigned int) strlen (strval); + for (unsigned int i = 0; i < len; i++) + { + if (strval[i] == '"' || strval[i] == '\\') + str << "\\"; + str << strval[i]; + } + } + + // Add non white spaces unchanged. + else if (! token->is_whitespace ()) + str << token->text (); + + // Reduce several white spaces to a single space. + else if (argUnit->next (token) && argUnit->prev (token)) + str << " "; + } + str << "\""; + + // Create a new string constant token. + _parser->cscanner ().fill_unit (str.str ().c_str (), *unit); + } + } + + // Not a valid index (an empty argument), build an empty + // string constant. + else + _parser->cscanner ().fill_unit ("\"\"", *unit); + } + + +// Process the stringification macro operator `#'. +void PreMacroExpander::processStringOp (PreMacro* macro, Unit* unit, PreArgDesc &args) const + { + Token* token = (Token*) unit->first (); + Token* hash = (Token*) 0; + Unit tmpUnit; + int index; + + // Scan the unit. + for (; token; token = (Token*) unit->next (token)) + { + // Recognize the stringification operator `#'. + if (token->is_macro_op () && token->type () == TOK_MO_HASH) + { + if (! hash) hash = token; // Remember a single hashmark. + else hash = (Token*) 0; + } + + // Recognize a C++ identifier. + else if (token->is_identifier ()) + { + // Test whether the identifier is an argument and has to be + // replaced with the text given at macro call. + if ((index = isArg (token->text (), macro)) != -1 && args.numArgs ()) + { + // Add a single space before the argument text. + //if (!_in_include) + // _parser->cscanner ().fill_unit (" ", tmpUnit); + + // Replace the argument. + if (hash) + replaceStringifiedArg (index, &tmpUnit, args); + else + replaceUnchangedArg (index, &tmpUnit, args, unit, token, macro->varArgs ()); + + // Add a single space behind the argument text. + //if (!_in_include) + // _parser->cscanner ().fill_unit (" ", tmpUnit); + + // Insert the replaced text into unit. + unit->move_before (token, tmpUnit); + + // Remove the recognized argument identifier from unit. + token = (Token*) unit->prev (token); + unit->kill ((Token*) unit->next (token)); + } + + // Remove the stringification operator `#'. + if (hash) { + unit->kill (hash); + hash = (Token*) 0; + } + } + } + } + + +// Process the concatenation macro operator `##'. +void PreMacroExpander::processConcatOp (Unit* unit) const { + Token *token = unit->first (); + Token *last = (Token*)0; + Token *op = (Token*)0; + Token *curr, *next; + + // Scan the unit. + for (; token; token = unit->next (token)) { + + if (token->is_whitespace ()) + continue; + + // handle the ## operator + if (token->is_macro_op () && token->type () == TOK_MO_HASHHASH) { + // no problem, if there is no token on the left side; there might have + // been an empty argument expansion + if (!last) + last = op; + op = token; + continue; + } + + // handle the normal non-whitespace, non-## tokens + if (op) { + // transform: concatenate and re-scan the tokens before and after the operator + std::string conc; + + // tokens before ## until the next whitespace + for (curr = last; curr && !curr->is_whitespace (); curr = unit->prev (curr)) { + conc = curr->text () + conc; + last = curr; + } + + // tokens after ## until the next whitespace + for (curr = token; curr && !curr->is_whitespace (); curr = unit->next (curr)) { + conc += curr->text (); + token = curr; + } + + // re-scan the concatenated tokens + Unit tmp; + _parser->cscanner ().allow_macro_ops (); + _parser->cscanner ().fill_unit (conc.c_str (), tmp); + _parser->cscanner ().allow_macro_ops (false); + + // handle problems + if (!tmp.first ()) { + *_err << op->location () << sev_error << "pasting \"" + << last->text () << "\" and \"" << token->text () + << "\" does not give a valid preprocessing token" << endMessage; + return; + } + + // mark all tokens as macro-generated + next = tmp.first (); + for (curr = next; curr; curr = tmp.next (curr)) { + curr->location (op->location ()); + } + + // move the generated tokens behind the expression ## + unit->move (token, tmp); + // remove the expression + unit->kill (last, token); + + // go into the right state for further replacements + token = last = next; + op = (Token*)0; + } + else { + // remember that the current token is the 'last' non-whitespace now + last = token; + } + } + + // if 'op' is still set, the right argument was missing + if (op) { + // remove the ## operator; there might have been an empty argument expansion + unit->kill (op); + } +} + + +// Substitutes a macro. +void PreMacroExpander::substituteMacro (PreMacro* macro, PreArgDesc &args) const + { + // Build a unit from the macro body. + Unit* unit = new MacroUnit (macro->getBodyUnit (_parser->cscanner ())); + + // Process the stringification macro operator `#' if this is a + // function-like macro. + if (macro->isFunction ()) + processStringOp (macro, unit, args); + + // Set the location of every token in unit to the location of the + // macro call. + for (Token* token = (Token*) unit->first (); token; + token = (Token*) unit->next (token)) { + token->location (args.beginToken ()->location ()); + } + + // Process the concatenation macro operator `##'. + processConcatOp (unit); + + // Set the macro begin and end tokens. + ((MacroUnit*)unit)->MacroBegin (args.beginToken ()); + ((MacroUnit*)unit)->MacroEnd (args.endToken ()); + + // Push the macro expanded unit on token stack so that the parsers + // can parse it (and maybe find some new macro calls). + pushUnit (*_scanner, unit); + + // Add the unit to the unit manager. + _unitManager->add (unit); + } + + +// Process the special keyword `defined'. +void PreMacroExpander::processDefined (PreMacro* macro, PreArgDesc &args) const + { + Token* token = (Token*) 0; + bool error = false; + + // If we recognize the form "defined (MACRO)" evaluate the arguments. + if (args.numArgs ()) + { + // If the argument isn't empty get the argument, else we have + // a syntax error. + if (! args.getArg (0).empty ()) + { + // Skip white-spaces and comments. + MacroUnit& arg = args.getArg (0); + for (token = (Token*) arg.first (); token; token = (Token*) arg.next (token)) + if (! token->is_whitespace () && ! token->is_comment ()) + break; + } + else + error = true; + } + + // If we recognize the form "defined MACRO" check if there is really + // a following macro name identifier. + else if (checkForGoOn (false)) + { + // Skip whitespaces and comments. + while ((token = _scanner->next ())) + if (! token->is_whitespace () && ! token->is_comment ()) + break; + } + + // Append token to a new unit. It's either a white space or one + // of the integer constants 0 or 1. + Unit* unit = new MacroUnit (); + + // If the macro name is found check if the macro is defined. + if (token) + { + // Build a new integer constant token with the value 1 + // if the macro is defined else 0. + if (_macroManager->getMacro (token->dtext ())) + _parser->cscanner ().fill_unit ("1", *unit); + else + _parser->cscanner ().fill_unit ("0", *unit); + + // Set the macro begin and end tokens. + ((MacroUnit*)unit)->MacroBegin (args.beginToken ()); + ((MacroUnit*)unit)->MacroEnd (args.endToken ()); + } + else + error = true; + + // If a syntax error appeared report it and replace the identifier + // with a white space. + if (error) { + *_err << macro->location () << sev_error + << "`defined' used without macro name" + << endMessage; + + _parser->cscanner ().fill_unit (" ", *unit); + } + + // Push the unit on token stack so that the parsers can parse + // it (and maybe find some new macro calls). + pushUnit (*_scanner, unit); + + // Add the unit to the unit manager. + _unitManager->add (unit); + } + + +// Expand a macro. +bool PreMacroExpander::expandMacro (PreMacro* macro) + { + _scanner = (TokenStream*) (_parser->scanner ()); + Token* token = _scanner->current () ? _scanner->current () : _scanner->next (); + return expandMacro (macro, token); + } + + +// Expand the given macro. +bool PreMacroExpander::expandMacro (PreMacro* macro, Token *token) const + { + if (! macro || ! token) return false; + + PreArgDesc args; + args.beginToken (token); + args.endToken (token); + + // Function-like macro (maybe). + if (macro->isFunction ()) + { + // Special keyword `defined' recognized. + if (strcmp (macro->getName (), "defined") == 0) + { + // Process the keyword. + if (checkForGoOn ()) + collectArgs (macro, args); + processDefined (macro, args); + } + // Check whether the macro name is followed by a left parenthesis. + // If found substitute the macro call, else it isn't a macro call. + else if (! checkForGoOn ()) + { + return false; + } + else + { + collectArgs (macro, args); + substituteMacro (macro, args); + } + } + + // Substitute a simple macro. + else + substituteMacro (macro, args); + + return true; + } + + +// Collect arguments of a function-like macro call. +void PreMacroExpander::collectArgs (PreMacro* macro, PreArgDesc &args) const + { + int depth = 1, numArgs = 0; + bool args_found, has_args = (macro->numArgs () != 0); + Unit* unit; + Token* token, *dup; + Location location; + + // Get the current location. + PreMacro* defined = _macroManager->getMacro ("defined"); + if (defined != 0) + location = defined->location (); + else + location = _scanner->current ()->location (); + + // Skip whitespaces and comments. + while ((token =_scanner->next ())) + if (token->is_core ()) + break; + + // Get the arguments. + while (token && depth) + { + args_found = false; + unit = 0; + + // Scan for the arguments. + while ((token = _scanner->next ())) + { + // Recognize the commas and parenthesis. + if (token->is_core ()) + { + // Another argument found. + if (token->is_comma () && depth == 1 && + ! (macro->varArgs () && numArgs == (macro->numArgs () - 1))) { + if (! args_found && has_args) { + args_found = true; + if (! unit) { + args.newArg (); + unit = &args.currArg (); + } + } + break; + } + + // Maybe a macro call, ignore the following commas. + else if (token->is_open ()) { + depth++; + } + + // Maybe the end of a macro call found. + else if (token->is_close ()) { + if (! --depth) { // All done ? + if (! args_found && has_args) { + args_found = true; + if (! unit) { + args.newArg (); + unit = &args.currArg (); + } + } + args.endToken (token); + break; + } + } + } + + // Collect all tokens of current argument. + args_found = true; + if (has_args) { + if (! unit) { + args.newArg (); + unit = &args.currArg (); + } + if (token->is_comment ()) { + // Reduce a comment to a single space + _parser->cscanner ().fill_unit (" ", *unit); + } else { + dup = (Token*) token->duplicate (); + unit->append (*dup); + } + } + } + + // Increment argument counter. + if (args_found) + numArgs++; + } + + // Report the errors occured. + if (numArgs < macro->numArgs () && ! (macro->varArgs () && + numArgs == (macro->numArgs () - 1))) { + *_err << location << sev_warning << "macro `" + << macro->getName () << "' called with too few (" + << numArgs << ") arguments" << endMessage; + } else if (numArgs > macro->numArgs () && ! macro->varArgs ()) { + *_err << location << sev_warning << "macro `" + << macro->getName () << "' called with too many (" + << numArgs << ") arguments" << endMessage; + } + if (depth) + *_err << location << sev_warning << "unterminated call to macro `" + << macro->getName () << "'" << endMessage; + } + + +// Push unit on token stream. +void PreMacroExpander::pushUnit (TokenStream &stream, Unit *unit) const + { + if (unit) { + if (unit->isMacroExp ()) + ((MacroUnit*)unit)->CallingUnit (stream.top ()); + stream.push (unit); + } + } + + +} // namespace Puma diff --git a/Puma/src/cpp/PreMacroExpander.h b/Puma/src/cpp/PreMacroExpander.h new file mode 100644 index 0000000..761d9b8 --- /dev/null +++ b/Puma/src/cpp/PreMacroExpander.h @@ -0,0 +1,136 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __pre_macro_expander__ +#define __pre_macro_expander__ + +// The macro expander provides methods to expand a single macro or +// all macros of a given string or unit. + +#include + +#include "Puma/Location.h" +#include "Puma/Array.h" +#include "Puma/PreArgDesc.h" + +namespace Puma { + + +class PreprocessorParser; +class PreMacroExpander; +class PreMacroManager; +class UnitManager; +class TokenStream; +class ErrorStream; +class PreMacro; + +class PreMacroExpander { + TokenStream *_scanner; + PreMacroManager *_macroManager; + UnitManager *_unitManager; + ErrorStream *_err; + Array *_macroStack; + + PreprocessorParser *_parser; + + PreMacroExpander *_preexpander; + + bool _in_include; // true if an include directive is scanned + + // Check whether there is really a macro. + bool checkForGoOn (bool mode = true) const; + + // Process the macro operator `##'. + void processConcatOp (Unit *) const; + + // Process the macro operator `#'. + void processStringOp (PreMacro *, Unit *, PreArgDesc &) const; + + // Stringify and replace an argument. + void replaceStringifiedArg (int, Unit *, PreArgDesc &) const; + + // Replace an argument unchanged. + void replaceUnchangedArg (int, Unit *, PreArgDesc &, Unit *, Token *, bool) const; + + // Test whether a string is an argument of a macro. + int isArg (const char *, PreMacro *) const; + + // Compare two macro argument identifier. + bool equal (const char *, const char *) const; + + // Build an unit from a string. + Unit *buildUnit (const char *) const; + + // Collect the arguments of a function-like macro. + void collectArgs (PreMacro *, PreArgDesc &) const; + + // Expand a function-like macro. + void substituteMacro (PreMacro *, PreArgDesc &) const; + + // Process the special keyword `defined'. + void processDefined (PreMacro *, PreArgDesc &) const; + + // Prescan an argument of a macro call. + Unit& prescanArgument (Unit *) const; + + // Expand the given macro. + bool expandMacro (PreMacro *, Token *) const; + + // Reset the expander to a special initial state. + void reset (PreprocessorParser *, Array *); + + // Expand all macros of the given unit. + Unit *expandMacros (Unit *); + + // Push unit on token stream. + void pushUnit (TokenStream &, Unit *) const; + + // Get the next non-whitespace non-comment token + Token* nextPreprocessingToken (Token*, Unit*) const; + + // Get the previous non-whitespace non-comment token + Token* prevPreprocessingToken (Token*, Unit*) const; + + // Check if the given unit contains only spaces and comments. + bool onlySpacesAndComments (MacroUnit&) const; + +public: + // Special constructor. Call reset() before using the expander. + PreMacroExpander (); + + PreMacroExpander (PreprocessorParser *); + ~PreMacroExpander () { if (_preexpander) delete _preexpander; } + + // Reset the expander to the initial state. + void reset (PreprocessorParser *); + + // Set a flag that is used to check whether a macro is expanded in a + // #include directive + void inInclude (bool ii) { _in_include = ii; } + + // Expand the given macro. + bool expandMacro (PreMacro *); + + // Expand all macros of the given string. + char *expandMacros (const char *); +}; + + +} // namespace Puma + +#endif /* __pre_macro_expander__ */ diff --git a/Puma/src/cpp/PreMacroManager.cc b/Puma/src/cpp/PreMacroManager.cc new file mode 100644 index 0000000..4808ebf --- /dev/null +++ b/Puma/src/cpp/PreMacroManager.cc @@ -0,0 +1,185 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/PreMacroManager.h" +#include "Puma/ErrorStream.h" +#include "Puma/PreMacro.h" +#include "Puma/StrCol.h" +#include +#include + +namespace Puma { + + +void PreMacroManager::clear () { + MacrosByName::iterator macro = _Macros.begin(); + for (; macro != _Macros.end(); ++macro) + delete macro->second; + _Macros.clear(); +} + +void PreMacroManager::add (PreMacro* m) { + _Macros[m->getName().c_str()] = m; +} + +PreMacro* PreMacroManager::get (const DString& name) const { + MacrosByName::const_iterator macro = _Macros.find(name.c_str()); + if (macro != _Macros.end()) + return (PreMacro*) macro->second; + return 0; +} + +void PreMacroManager::kill (const DString& name) { + MacrosByName::iterator macro = _Macros.find(name.c_str()); + if (macro != _Macros.end()) { + PreMacro* m = macro->second; + _Macros.erase(macro); + delete m; + } +} + +// Initialize the macro manager. +void PreMacroManager::init (const char* file) + { + // Add special predefined macros to macro table. + _Line = new PreMacro ("__LINE__", ""); + add (_Line); + _Date = new PreMacro ("__DATE__", ""); + add (_Date); + _Time = new PreMacro ("__TIME__", ""); + add (_Time); + _IncLevel = new PreMacro ("__INCLUDE_LEVEL__", "0"); + add (_IncLevel); + + if (! file) { + _File = new PreMacro ("__FILE__", ""); + _BaseFile = new PreMacro ("__BASE_FILE__", ""); + } + else { + char* basefile = new char[strlen (file) + 10]; + sprintf (basefile, "\"%s\"", file); + + _File = new PreMacro ("__FILE__", basefile); + _BaseFile = new PreMacro ("__BASE_FILE__", basefile); + + delete[] basefile; + } + add (_File); + add (_BaseFile); + } + + +// Add a new macro to macro manager. +void PreMacroManager::addMacro (PreMacro *macro) //const + { + if (! macro) return; + + // Search for the macro. If found it's a redefinition of the macro. + if (PreMacro* prev = (PreMacro*) get (macro->getName ())) + { + // Special macro that cannot be (re)defined in the program. + if (prev->isInhibited () || prev->isLocked ()) + return; + + // A redefinition normally causes a warning. But if the body + // of the previous version of the macro is empty or not + // effectively different from the current macro body, the + // redefinition is accepted silently. + if (! StrCol::onlySpaces (prev->getBody ())) + { + // Effectively different means, that the two bodies differ + // only in white spaces. It is not allowed to remove white + // spaces completely or to add white spaces where no one have + // been before. + if (StrCol::effectivelyDifferent (macro->getBody (), + prev->getBody ())) { + *_err << macro->location () << sev_warning + << "redefinition of macro `" + << macro->getName () << "'" << endMessage; + if (~(prev->location ().filename ())) + *_err << prev->location () << "previous definition here" + << endMessage; + } + } + + // Remove the previous version of the macro. + kill (macro->getName ()); + } + + // Add the macro to the macro table. + add (macro); + } + + +// Remove macro `name' from macro table. +void PreMacroManager::removeMacro (const DString& name, const Location& location) + { + if (name.empty()) + return; + + PreMacro *macro = get (name); + + if (macro) { + // Macro protected against undefining + if (macro->isLocked () || macro->isInhibited ()) { + *_err << location << sev_warning + << "can not undefine macro `" << macro->getName () + << "'" << endMessage; + return; + } + + // Undefine special calculated macro + if (macro == getLineMacro() || macro == getIncLevelMacro() || + macro == getDateMacro() || macro == getTimeMacro() || + macro == getFileMacro() || macro == getBaseFileMacro()) { + + *_err << location << sev_warning + << "undefining special macro `" << macro->getName () + << "'" << endMessage; + + if (macro == getLineMacro()) _Line = 0; + if (macro == getIncLevelMacro()) _IncLevel = 0; + if (macro == getDateMacro()) _Date = 0; + if (macro == getTimeMacro()) _Time = 0; + if (macro == getFileMacro()) _File = 0; + if (macro == getBaseFileMacro()) _BaseFile = 0; + } + } + + kill (name); + } + + +// Get macro `name' from macro table. +PreMacro* PreMacroManager::getMacro (const DString& name) const + { + if (name.empty()) + return (PreMacro*) 0; + + PreMacro *macro = get (name); + + // Special macro that cannot be defined and + // therefore also not be found. + if (macro && macro->isInhibited ()) + return (PreMacro*) 0; + + return macro; + } + + +} // namespace Puma diff --git a/Puma/src/cpp/PreMacroManager.h b/Puma/src/cpp/PreMacroManager.h new file mode 100644 index 0000000..99f350f --- /dev/null +++ b/Puma/src/cpp/PreMacroManager.h @@ -0,0 +1,86 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __pre_macro_manager__ +#define __pre_macro_manager__ + +// The macro manager manages all defined macros. + +#include "Puma/Chain.h" +#include "Puma/Location.h" +#include "Puma/StrHashTable.h" +#include "Puma/PreMacro.h" +#include +#include + + +namespace Puma { + + +class ErrorStream; + +class PreMacroManager { + PreMacro *_Line; + PreMacro *_Date; + PreMacro *_Time; + PreMacro *_IncLevel; + PreMacro *_File; + PreMacro *_BaseFile; + ErrorStream *_err; + + /** Map type for macro name to macro object mapping. */ + typedef std::map MacrosByName; + MacrosByName _Macros; + +private: + void add (PreMacro *); + void kill (const DString &); + PreMacro *get (const DString &) const; + void clear (); + +public: + PreMacroManager (ErrorStream *err) : _err (err) {} + + // Destroy the predicates too. + ~PreMacroManager () { clear (); } + + // Initialize the macro manager. + void init (const char *filename); + + // Add given macro to macro table. + void addMacro (PreMacro *macro); + + // Remove macro `name' from macro table. + void removeMacro (const DString &name, const Location& location = Location()); + + // Get macro `name' from macro table. + PreMacro *getMacro (const DString &name) const; + + // Get pointers to some special macros + PreMacro *getLineMacro () const { return _Line; } + PreMacro *getDateMacro () const { return _Date; } + PreMacro *getTimeMacro () const { return _Time; } + PreMacro *getIncLevelMacro () const { return _IncLevel; } + PreMacro *getFileMacro () const { return _File; } + PreMacro *getBaseFileMacro () const { return _BaseFile; } +}; + + +} // namespace Puma + +#endif /* __pre_macro_manager__ */ diff --git a/Puma/src/cpp/PreMacroOpTokens.h b/Puma/src/cpp/PreMacroOpTokens.h new file mode 100644 index 0000000..a9d909b --- /dev/null +++ b/Puma/src/cpp/PreMacroOpTokens.h @@ -0,0 +1,33 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __PRE_MACRO_OP_TOKENS__ +#define __PRE_MACRO_OP_TOKENS__ + +namespace Puma { + + +enum PreMacroOpTokens { + TOK_MO_HASH = 450, + TOK_MO_HASHHASH +}; + + +} // namespace Puma + +#endif /* __PRE_MACRO_OP_TOKENS__ */ diff --git a/Puma/src/cpp/PreParser.lem b/Puma/src/cpp/PreParser.lem new file mode 100644 index 0000000..80dcfe1 --- /dev/null +++ b/Puma/src/cpp/PreParser.lem @@ -0,0 +1,1726 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 + +// C Compatible Compiler Preprocessor Syntax Parser. + +%name PreParser + +%token_type {PreTree*} + +%left TOK_PRE_COMMA. + +%include { +#include "Puma/List.h" +#include "Puma/Token.h" +#include "Puma/StrCol.h" +#include "Puma/PreExpr.h" +#include "Puma/CScanner.h" +#include "Puma/PreMacro.h" +#include "Puma/CTokens.h" +#include "Puma/PreParser.h" +#include "Puma/PreTree.h" +#include "Puma/MacroUnit.h" +#include "Puma/UnitManager.h" +#include "Puma/TokenStream.h" +#include "Puma/ErrorStream.h" +#include "Puma/PrePredicate.h" +#include "Puma/ImportHandler.h" +#include "Puma/PreLevelState.h" +#include "Puma/CCommentTokens.h" +#include "Puma/PreParserState.h" +#include "Puma/PreMacroManager.h" +#include "Puma/PreFileIncluder.h" +#include "Puma/PreTreeToken.h" +#include "Puma/PreMacroExpander.h" +#include "Puma/PreprocessorParser.h" +#include "Puma/PreTreeNodes.h" +#include "Puma/PrePredicateManager.h" +#include +#include +#include + + +using namespace Puma; + +// Definition of the Lemon generated parser interface. +void *PreParserAlloc (void *(*mallocProc)(size_t)); +void PreParser (void *pParser, int TokenID, PreTree *TokenValue); +void PreParserFree (void *pParser, void (*freeProc)(void*)); +void PreParserTrace (FILE *TraceFILE, char *zTracePrompt); + +namespace Puma { + +int TRACE_CPP = 0; // Tracing + +static PreprocessorParser* parser; // Current preprocessor parser. +static PreParserState* state; // Current parser. +static PreLevelState* level; // Current level state. +static ErrorStream* err; // Current error stream. + +// Build a string from a subtree of the preprocessor syntax tree. +char* buildString (const PreTree* node) + { + if (! node) return (char*) 0; + + char *result; + std::ostringstream s; + Token* token; + + // If subtree isn't empty concatenate all tokens to a single string. + if (node->sons ()) { + PreTokenListPart* list = (PreTokenListPart*) node->son (0); + + // Fill the buffer. + for (unsigned int i = 0; i < (unsigned int) list->sons (); i++) { + token = ((PreTreeToken*) list->son (i))->token (); + if (token->is_comment ()) + s << " "; // reduce a comment to a single space + else + s << token->text (); + } + } + + std::string str = s.str(); + + // Skip leading white spaces. + int offset = 0; + while (StrCol::isSpace(str[offset])) offset++; + + // Skip trailing white spaces. + int len = str.length(); + while (len > 0 && StrCol::isSpace(str[len-1])) len--; + + // Create the return string buffer. + result = new char[1 + ((len-offset) < 0 ? 0 : (len-offset))]; + + // Copy the buffer into the return buffer but skip newlines. + int copied = 0; + for (int i = offset; i < len; i++) + if (str[i] != '\n') + result[copied++] = str[i]; + + // Finish return buffer. + result[copied] = '\0'; + + return result; + } + + +// Evaluate a special answer string. +char* evalAnswerString (char* string, bool mode, PreParserState& state) + { + if (! string) return (char*) 0; + + // Scan the token string and build an unit. + Unit *unit = new Unit (); + parser->cscanner ().allow_macro_ops (); + parser->cscanner ().fill_unit (string, *unit); + parser->cscanner ().allow_macro_ops (false); + + // The call to an #assert (#unassert) directive expects the + // form: #assert PREDICATENAME (ANSWERTEXT). This function + // evaluates the answer token text to get the real answer text. + + Token* token; + + // Search the right parenthesis. + for (token = (Token*) unit->first (); token; + token = (Token*) unit->next (token)) + if (token->is_core () && token->type () == TOK_OPEN_ROUND) + break; + + // No right parenthesis found -> parse error. + if (! token) { + if (mode) { + *(state.err) << state.currToken->location () << sev_error + << "Missing token list in `#assert'" + << endMessage; + return (char*) 0; + } else { + string = new char[1]; + *string = '\0'; + return string; + } + } + + // Delete all tokens before the right parenthesis. + unit->kill ((Token*) unit->first (), token); + + // Search the left parenthesis. + for (token = (Token*) unit->first (); token; + token = (Token*) unit->next (token)) + if (token->is_core () && token->type () == TOK_CLOSE_ROUND) + break; + + // No left parenthesis found -> parse error. + if (! token) { + *(state.err) << state.currToken->location () + << sev_error << "Unterminated token list in "; + if (mode) *(state.err) << "`#assert'"; + else *(state.err) << "`#unassert'"; + *(state.err) << endMessage; + return (char*)0; + } + + // Delete all tokens after the left parenthesis. + unit->kill (token, (Token*) unit->last ()); + + // Get the text between the parenthesis. + char* answer = unit->toString (); + delete unit; + + // An empty answer causes a parse error. + if (StrCol::onlySpaces (answer)) { + *(state.err) << state.currToken->location () + << sev_error << "Empty token list in "; + if (mode) *(state.err) << "`#assert'"; + else *(state.err) << "`#unassert'"; + *(state.err) << endMessage; + delete[] answer; + return (char*) 0; + } + + // Return the real answer text. + return answer; + } + + +// Update the bodies of some predefined macros. +void updatePredefined () + { + TokenStream* scanner = parser->scanner (); + PreMacroManager* mm = parser->macroManager (); + + if (scanner->length ()) { + state->checkPredefined (mm->getIncLevelMacro (), scanner, *mm); + state->checkPredefined (mm->getLineMacro (), scanner, *mm); + state->checkPredefined (mm->getDateMacro (), scanner, *mm); + state->checkPredefined (mm->getTimeMacro (), scanner, *mm); + state->checkPredefined (mm->getFileMacro (), scanner, *mm); + } + } + + +// Send a newline token to the parser. +void sendNLToken () + { + Token* token = state->newline; + token->location (state->lastToken->location ()); + state->lastType = TOK_PRE_NEWLINE; + PreTreeToken* synToken = new PreTreeToken (token); + PreParser (state->pParser, state->lastType, synToken); + PreParser (state->pParser, TOK_PRE_DIRECTIVE_END, (PreTree*) 0); + } + + +// Return true if we are at the end of a directive. +bool atEndOfDirective (PreprocessorParser::PreMode mode) + { + int type = state->lastType; + if (mode != PreprocessorParser::DEFINING && + mode != PreprocessorParser::ASSERT && + mode != PreprocessorParser::DIRECTIVE && + mode != PreprocessorParser::MACRO) + if (type == TOK_PRE_ELSE || type == TOK_PRE_ENDIF || + type == TOK_PRE_ERROR || type == TOK_PRE_WARNING || + type == TOK_PRE_TOKEN_LIST || type == TOK_PRE_RPAREN || + type == TOK_PRE_ID) + return true; + return false; + } + + +// Prevent a special kind of parse error. +void preventEOFError (PreprocessorParser::PreMode mode) + { + // If the parser is parsing a directive and the next token + // isn't a preprocessor token like expected there may be an + // EOF at end of the directive. But the parser can't recognize + // EOFs within directives, it would cause a parse error. But + // it should be allowed to finish a directive with an EOF too + // and not only with a newline. So a newline is sent to the + // parser if such an EOF is suspected. + if (! state->currToken->is_comment () && state->lastToken) + if (atEndOfDirective (mode)) + sendNLToken (); + } + + +// Prevent a special kind of parse error. +void preventInclEOFError (PreprocessorParser::PreMode mode) + { + // If an included file ends with a preprocessor directive the parser + // would expect that after the #include (that has included the file) + // is a newline. But if there is no newline but a new preprocessor + // directive a parse error would occur. In such a case we simply give + // the parser the expected newline token to prevent the error. + if (state->lastToken) + if (atEndOfDirective (mode)) + { + int type = state->currType; + if (type == TOK_PRE_DEFINE || type == TOK_PRE_UNDEF || + type == TOK_PRE_ASSERT || type == TOK_PRE_UNASSERT || + type == TOK_PRE_WARNING || type == TOK_PRE_ERROR || + type == TOK_PRE_IFDEF || type == TOK_PRE_IFNDEF || + type == TOK_PRE_IF || type == TOK_PRE_ELIF || + type == TOK_PRE_ELSE || type == TOK_PRE_ENDIF || + type == TOK_PRE_INCLUDE || type == TOK_PRE_INCLUDE_NEXT) + sendNLToken (); + } + } + + +// Prevent a special kind of parse error. +bool directiveAtEOF () + { + // An EOF within a directive is suspected. It's the same problem + // like above. + if (state->lastToken) + if (parser->pre_mode () != PreprocessorParser::INITIAL) + { + state->currToken = state->lastToken; + state->currType = state->lastType; + sendNLToken (); + if (((TokenStream*) parser->scanner ())->length ()) + { + // The last token of the main input file belongs to an + // `#include' directive and nothing but EOF is following. + // And now it is one more file to parse so the parser has + // to be called again. + state->lastToken = state->newline; + state->lastToken->location (state->currToken->location ()); + state->lastType = TOK_PRE_NEWLINE; + return true; + } + } + return false; + } + + +// Constructor of the preprocessor parser class. +PreprocessorParser::PreprocessorParser (ErrorStream* err, UnitManager* unitManager, + UnitManager* locals, std::ostream& out, int max_depth) : _scanner (*err) + { +#ifndef NDEBUG + if (TRACE_CPP) + PreParserTrace (stdout, "CPP_TRACE: "); +#endif + _parserState = new PreParserState (); + _parserState->maxIncludeDepth = max_depth; + _parserState->err = err; + _parserState->pParser = PreParserAlloc ((void* (*)(size_t))malloc); + _silentMode = false; + _out = &out; + _unitManager = unitManager; + _locals = locals; + _levelState = new PreLevelState (); + _macroStack = new Array (); + _predicateManager = new PrePredicateManager (); + _macroManager = new PreMacroManager (err); + _fileIncluder = new PreFileIncluder (*this); + _pre_mode = INITIAL; + _support_gnu = true; + _importHandler = 0; + } + + +PreprocessorParser::~PreprocessorParser () + { + // Free the lemon generated parser. + PreParserFree (_parserState->pParser, (void (*)(void*))::free); + delete _macroManager; + delete _fileIncluder; + delete _levelState; + delete _parserState; + delete _predicateManager; + delete _macroStack; + if (_importHandler) + delete[] _importHandler; + } + + +// Constructor of the preprocessor parser class. +void PreprocessorParser::reset (ErrorStream* err, UnitManager* unitManager, + UnitManager* locals, std::ostream& out, int max_depth) + { + delete _macroManager; + delete _fileIncluder; + delete _levelState; + delete _parserState; + delete _predicateManager; + delete _macroStack; + if (_importHandler) + delete[] _importHandler; + + _parserState = new PreParserState (); + _silentMode = false; + _out = &out; + _unitManager = unitManager; + _locals = locals; + _parserState->maxIncludeDepth = max_depth; + _parserState->err = err; + _parserState->pParser = PreParserAlloc ((void* (*)(size_t))malloc); + _macroManager = new PreMacroManager (err); + _fileIncluder = new PreFileIncluder (*this); + _levelState = new PreLevelState (); + _macroStack = new Array (); + _predicateManager = new PrePredicateManager (); + _pre_mode = INITIAL; + _support_gnu = true; + _importHandler = 0; + } + + +// Map scanner token types to parser token types +int PreprocessorParser::map_token (Token *token, bool &parse) { + // default: + int type = token->type (); + parse = true; + + if (token->is_comment ()) { + parse = false; + return type; + } + + // If the scope changes to another file, the mapping mode + // must be reset due to a missing NEWLINE at end of the + // previous file (In this case the mapping mode wouldn't + // change correctly). + if (state->lastToken) + if (token->location ().filename ().name () != + state->lastToken->location ().filename ().name ()) + _pre_mode = INITIAL; + + if (_pre_mode == INITIAL) { + if (token->is_preprocessor ()) { + switch (type) { + case TOK_PRE_DEFINE: + _pre_mode = DEFINING; + break; + case TOK_PRE_ASSERT: + case TOK_PRE_UNASSERT: + _pre_mode = ASSERT; + break; + case TOK_PRE_IF: + case TOK_PRE_ELIF: + case TOK_PRE_WARNING: + case TOK_PRE_ERROR: + case TOK_PRE_INCLUDE: + case TOK_PRE_INCLUDE_NEXT: + case TOK_ELSE: + case TOK_PRE_ENDIF: + _pre_mode = TOKENLIST; + break; + case TOK_PRE_IFDEF: + case TOK_PRE_IFNDEF: + case TOK_PRE_UNDEF: + _pre_mode = DIRECTIVE; + break; + } + } else { + parse = false; + } + } else { + if (token->is_whitespace ()) { + const char *c = token->text (); + for (; *c && *c != '\n'; c++); + + if (*c == '\n') { + type = TOK_PRE_NEWLINE; + _pre_mode = INITIAL; + } else if (_pre_mode == TOKENLIST) { + type = TOK_PRE_TOKEN_LIST; + } else if (_pre_mode == MAYBEMACRO) { + type = TOK_PRE_TOKEN_LIST; + _pre_mode = TOKENLIST; + } else { + parse = false; + } + } else { + bool is_id = token->is_identifier (); + + type = Token::ID_UNKNOWN; + switch (_pre_mode) { + case TOKENLIST: + type = TOK_PRE_TOKEN_LIST; + break; + case ASSERT: + case DIRECTIVE: + if (! state->passOnToken) { + type = TOK_PRE_TOKEN_LIST; + _pre_mode = TOKENLIST; + } else if (is_id) { + type = TOK_PRE_ID; + _pre_mode = TOKENLIST; + } + break; + case DEFINING: + if (! state->passOnToken) { + type = TOK_PRE_TOKEN_LIST; + _pre_mode = TOKENLIST; + } else if (is_id) { + type = TOK_PRE_ID; + _pre_mode = MAYBEMACRO; + } + break; + case MAYBEMACRO: + if (token->is_open ()) { + type = TOK_PRE_LPAREN; + _pre_mode = MACRO; + } + break; + case MACRO: + if (is_id) { + type = TOK_PRE_ID; + } else if (token->is_comma ()) { + type = TOK_PRE_COMMA; + } else if (token->is_close ()) { + type = TOK_PRE_RPAREN; + _pre_mode = TOKENLIST; + } else if (token->type () == TOK_ELLIPSIS) { + if (supportGNU ()) { + type = TOK_PRE_REST; + } + } + break; + case INITIAL: // to avoid compiler warnings + break; + } + if (type == Token::ID_UNKNOWN) { + _pre_mode = INITIAL; + } + } + } + return type; +} + + +// Finish the parse process. +void PreprocessorParser::finishParsing () { + // Create an EOF token needed if the EOF is within a directive + // and caused a parse error. So the parser can print a error + // message that report this error. + state->currToken = new Token (Token::ID_END_OF_FILE); + + // Send the parser the signal to finish the parse process. + PreParser (state->pParser, 0, (PreTree*) 0); + + delete state->currToken; +} + + +// Parse a generated single line comment. +bool PreprocessorParser::parseGeneratedSingleLineCommentToken (Token*& sl_comment, Unit*& comment_unit, bool& last_in_expansion) { + TokenStream* stream = (TokenStream*) scanner (); + bool in_expansion = state->inMacroExpansion (*_macroStack); + + if (last_in_expansion && ! in_expansion) { + // handle generated single line comments + if (! sl_comment && state->sl_token && + (state->sl_token->type () == TOK_CCOMMENT || + state->sl_token->type () == TOK_CCSINGLE)) { + sl_comment = state->sl_token; + comment_unit = new Unit; + } + } + + last_in_expansion = in_expansion; + + if (sl_comment) { + if (state->currToken->location ().line () > sl_comment->location ().line ()) { + // Single line comment finished, append the current token. + Token *token = (Token*)state->currToken->duplicate (); + comment_unit->append (*token); + sl_comment = 0; + + // Push the unit containing the comment tokens on token stack. + stream->push (comment_unit); + // Add the unit to the unit manager. + _unitManager->add (comment_unit); + } else { + // Copy current token and mark it as comment token + Token *token = state->currToken; + token = new Token (TOK_CCOMMENT, Token::comment_id, token->text ()); + token->location (sl_comment->location ()); + comment_unit->append (*token); + } + return true; + } + return false; +} + + +// Check if the current token is a macro call +bool PreprocessorParser::isMacroCall (bool specialDefinedMacro) { + // Get the top token source. + long pos = scanner ()->length () - 1; + UnitTokenSrc *src = scanner ()->lookup (pos); + + // Get the unit and the current token. + Token* token = src->current (); + Unit* unit = src->unit (); + + // Skip white spaces and comments. + do { + // If the end of an unit is reached get the next + // unit on stack and continue with that unit. + while (! (token = (Token*) unit->next (token))) { + // If there is no unit left on stack, it's not a macro call. + if (! ((--pos >= 0) && (src = scanner ()->lookup (pos)))) + return false; + + unit = src->unit (); + token = src->current (); + } + } while (token->is_whitespace () || token->is_comment ()); + + // If there is a left parenthesis it is a function-like macro. + if (token->is_open ()) + return true; + + // After the `defined' keyword there can also be an identifier. + if (specialDefinedMacro && token->is_identifier ()) + return true; + + // This is not a call to a funtion-like macro. + return false; +} + + +// Collect the tokens of the macro call for expansion. +bool PreprocessorParser::collectMacroCallTokens (PreMacro* macro) { + // Macro 'defined'? + bool specialDefinedMacro = strcmp (macro->getName (), "defined") == 0; + + // Check if this is really a call to a function-like macro + if (macro->isFunction () && ! isMacroCall (specialDefinedMacro)) + return false; + + // Collect macro arguments + if (macro->isFunction ()) { + int depth = 0; + Token* token; + + // Unit containing the macro call tokens + MacroUnit* call = new MacroUnit (); + call->MacroBegin (state->currToken); + call->CallingUnit (state->currToken->unit ()); + call->append (*((Token*) state->currToken->duplicate ())); // the macro name + + // Save old macro argument parsing parser state + bool oldParseMacroArgs = state->parseMacroArgs; + state->parseMacroArgs = true; + + while ((token = parseToken ())) { + call->MacroEnd (token); + if (token->is_open ()) { + depth++; + } else if (token->is_close ()) { + depth--; + if (depth == 0) { + // End of argument list + call->append (*((Token*) token->duplicate ())); + break; + } + } else if (depth == 0 && specialDefinedMacro && token->is_identifier ()) { + // define MACRO_NAME + call->append (*((Token*) token->duplicate ())); + break; + } + + if (token->is_comment ()) { + // Reduce a comment to a single space + parser->cscanner ().fill_unit (" ", *call); + } else { + // Copy argument token + call->append (*((Token*) token->duplicate ())); + } + } + + state->parseMacroArgs = oldParseMacroArgs; + + // Push the arguments unit on token stack + TokenStream* stream = (TokenStream*) scanner (); + stream->push (call); + + // Add the unit to the unit manager + _unitManager->add (call); + + // all tokens in the generated unit are "macro generated" + // -> no longer needed: now automatically detected if a token is part of a MacroUnit! + // for (Token *curr = (Token*)call->first (); curr; curr = (Token*)call->next (curr)) + // curr->macro_generated (); + } + + return true; +} + + +// Expand a macro call. +bool PreprocessorParser::expandMacroCall (PreMacroExpander& expander) { + // If parsing macro arguments, don't expand macros in normal + // programm code. + if (state->parseMacroArgs && _pre_mode == INITIAL) + return false; + + TokenStream* stream = (TokenStream*) scanner (); + + // Get the macro definition if the current token is the name of a macro, + PreMacro* macro = _macroManager->getMacro (state->currToken->dtext ()); + if (macro) { + + // Check whether a special predefined macro was called + // and update it if necessary. + macro = state->checkPredefined (macro, scanner (), *_macroManager); + + // Now it must be checked whether the macro is allowed + // to be expanded. If it is a `self-referential' macro + // call it will stay untouched. + if (! state->isSelfReferentialMacro (macro, *_macroStack)) { + + // Try to expand the macro. It also could be that + // this isn't a macro call at all, if so ignore it. + if (collectMacroCallTokens (macro) && expander.expandMacro (macro)) { + + // After expansion the expanded text is pushed + // on the input stream. Now we must ensure to + // not expand again this macro inside of the + // expanded text (self-referential macro call). + state->putMacroOnStack (*_macroStack, macro, stream->length ()); + + return true; + } + } + } + return false; +} + + +// Get and parse the next token. +void PreprocessorParser::parseNextToken (Token*& sl_comment, Unit*& comment_unit, bool& last_in_expansion) { + TokenStream* stream = (TokenStream*) scanner (); + PreTreeToken* synToken; + PreMode mode; + + while ((state->currToken = stream->next ())) { + // Recognize end of macro expansion and adjust macro stack accordingly. + state->updateMacroStack (*_macroStack, stream->length ()); + + // Parse single line comments + if (parseGeneratedSingleLineCommentToken (sl_comment, comment_unit, last_in_expansion)) + continue; + + // Recognize next preprocessor state + bool parse = true; + mode = parser->pre_mode (); + int type = map_token (state->currToken, parse); + + state->sl_token = state->currToken; + state->currType = type; + + // If the scanned token isn't a preprocessor token, or a macro + // is getting expanded and therefore preprocessor tokens have to + // be ignored, do not parse the token. + if (! parse || state->inMacroExpansion (*_macroStack)) { + preventEOFError (mode); + break; + } + + // Allow an included file to end with a preprocessor directive + // and not only with a newline. + preventInclEOFError (mode); + + // Remember the current token. + state->lastToken = state->currToken; + state->lastType = state->currType; + + // Pass the current token to the parser. + synToken = new PreTreeToken (state->currToken); + if (TRACE_CPP) + printf ("%sToken '%s' %i\n", "CPP_TRACE: ", state->currToken->text (), state->currToken->type ()); + PreParser (state->pParser, type, synToken); + + // After a newline was parsed the parser has to wait until the + // next token was parsed to be able to decide whether the end + // of a directive really is reached (to be able to reduce the + // current rule). But we have to do our work now, for example + // after an #include directive we can't wait for the next + // directive to include the file, we have to include it now. + // Therefore a very special token will be send to the parser + // after parsing a newline token. The parser recognizes this + // very special token and the body of the #include-rule will + // be executed right now. + if (type == TOK_PRE_NEWLINE) + PreParser (state->pParser, TOK_PRE_DIRECTIVE_END, (PreTree*) 0); + // Same as above for EOF directly after a directive. + else if (stream->length () > 1 && ! stream->topHasMore ()) + sendNLToken (); + } + + // Recognize end of macro expansion and adjust macro stack accordingly. + state->updateMacroStack (*_macroStack, stream->length ()); +} + + +// Parse a single token. +Token* PreprocessorParser::parseToken () { + // Set the parser as the current parser. + parser = this; + state = _parserState; + level = _levelState; + err = state->err; + + Unit *comment_unit = 0; + Token *result = 0, *sl_comment = 0; + bool done = false, last_in_expansion = false; + + // Macro call expander. + PreMacroExpander expander (parser); + + while (! done) { + done = true; // default: run once + + // Scan the input files. Get the next token. + parseNextToken (sl_comment, comment_unit, last_in_expansion); + + if (state->currToken) { + // Go on only if not within a `false' conditional branch and + // no #error directive was parsed. + if (state->passOnToken && ! state->errorDirective) { + // Check every identifier for macro calls. + if (state->currToken->is_identifier () && expandMacroCall (expander)) { + // Skip the call and parse the expanded tokens. + done = false; + } else { + // Pass current token to the next parser. + result = state->currToken; + } + // Skip the current token. + } else + done = false; + } + + // End of input. Check if there is a directive at EOF (missing newline). + else if ((done = ! directiveAtEOF ())) { + // Send the parser the signal to finish the parse process. + finishParsing (); + + // Return NULL to signal all other parsers to finish their + // parse processes. + result = (Token*) 0; + } + } + + return result; +} + + +} // namespace Puma +} + +%stack_size 1000 + +%stack_overflow { + state->syntaxError = true; + *err << state->lastToken->location () << sev_fatal + << "Giving up. Preprocessor stack overflow (>1000)" << endMessage; +} + +%syntax_error { + // Prevent the parser to report an error twice. + if (state->syntaxError) { + state->syntaxError = false; + } + + // Report the syntax error. + else { + Unit u; + state->syntaxError = true; + + if (state->currType == Token::ID_END_OF_FILE) { + *err << state->lastToken->location () << sev_error + << "End of file within directive" + << endMessage; + } else if (state->lastType == TOK_PRE_NEWLINE) { + Token* token = (Token*) (u.prev (state->lastToken)); + while (! token->is_preprocessor ()) + token = (Token*) (u.prev (token)); + *err << state->lastToken->location () << sev_error + << "Unterminated `" << token->text () + << "' directive" << endMessage; + } else { + *err << state->lastToken->location () << sev_error + << "Unexpected token `" + << state->lastToken->text () << "'" << endMessage; + } + } +} + + +/***********************************************************************/ +/* preprocessor_program */ +/***********************************************************************/ + +preprocessor_program ::= directive_groups(dg). + { + state->syntaxTree = new PreProgram (dg); + } + +/***********************************************************************/ +/* directive_groups */ +/***********************************************************************/ + +directive_groups(dg) ::= /* empty */. + { + dg = new PreDirectiveGroups (); + } +directive_groups(dg) ::= directive_groups(odg) directive_group(d). + { + odg->add_son (d); + dg = odg; + } +directive_groups(dg) ::= directive_groups(odg) error. + { + odg->add_son (new PreError ()); + dg = odg; + } + +/***********************************************************************/ +/* directive_group */ +/***********************************************************************/ + +directive_group(dg) ::= control_line(cl). + { + dg = cl; + } +directive_group(dg) ::= conditional_group(cg). + { + dg = cg; + } + +/***********************************************************************/ +/* conditional_group */ +/***********************************************************************/ + +conditional_group(cg) ::= if_part(ip) directive_groups(dg) endif_part(ep). + { + cg = new PreConditionalGroup (ip, dg, ep); + } +conditional_group(cg) ::= if_part(ip) elif_part(eip) directive_groups(dg) + endif_part(ep). + { + cg = new PreConditionalGroup (ip, eip, dg, ep); + } +conditional_group(cg) ::= if_part(ip) else_part(ep) directive_groups(dg) + endif_part(eip). + { + cg = new PreConditionalGroup (ip, ep, dg, eip); + } + +/***********************************************************************/ +/* if_part */ +/***********************************************************************/ + +if_part(ip) ::= if_line(il) TOK_PRE_DIRECTIVE_END. + { + ip = il; + } +if_part(ip) ::= ifdef_line(idl) TOK_PRE_DIRECTIVE_END. + { + ip = idl; + } +if_part(ip) ::= ifndef_line(indl) TOK_PRE_DIRECTIVE_END. + { + ip = indl; + } + +/***********************************************************************/ +/* else_part */ +/***********************************************************************/ + +else_part(ep) ::= directive_groups(dg) else_line(el) TOK_PRE_DIRECTIVE_END. + { + ep = new PreElsePart (dg, el); + } +else_part(ep) ::= elif_part(eip) directive_groups(dg) else_line(el) + TOK_PRE_DIRECTIVE_END. + { + ep = new PreElsePart (eip, dg, el); + } + +/***********************************************************************/ +/* elif_part */ +/***********************************************************************/ + +elif_part(eip) ::= directive_groups(dg) elif_line(eil) TOK_PRE_DIRECTIVE_END. + { + eip = new PreElifPart (); + ((PreElifPart*) (eip))->addSons (dg, eil); + } +elif_part(eip) ::= elif_part(oeip) directive_groups(dg) elif_line(eil) + TOK_PRE_DIRECTIVE_END. + { + ((PreElifPart*) (oeip))->addSons (dg, eil); + eip = oeip; + } + +/***********************************************************************/ +/* endif_part */ +/***********************************************************************/ + +endif_part(eip) ::= endif_line(eil) TOK_PRE_DIRECTIVE_END. + { + eip = eil; + } + +/***********************************************************************/ +/* if_line */ +/***********************************************************************/ + +if_line(il) ::= TOK_PRE_IF(i) token_list(tl). + { + il = new PreIfDirective (i, tl); + + // A new conditional group starts, so go one level deeper. + level->deeper (); + + if (! state->errorDirective) { + if (state->passOnToken) + { + // Create a new macro expander to expand the macros that could + // be part of the expression. + PreMacroExpander expander (parser); + + Location location = ((PreTreeToken*) i)->token ()->location (); + + // Create a new expression evaluator. + PreExpr expr (err, location); + + // Now add the special macro `defined' to the macro manager. + PreTree* idl = new PreIdentifierList (i); + PreMacro* macro = new PreMacro ("defined", idl, "\n"); + delete idl; + macro->location (location); + parser->macroManager ()->addMacro (macro); + + // Update the predefined macros. + updatePredefined (); + + // Build the expression string and then expand all macros within it. + // Then we should have a string consisting only of 0s, 1s and some + // operators like || or &&. Evaluate the string. + char* str = buildString (tl); + char* exprstr = expander.expandMacros (str); + expr.evaluatePreExpr (exprstr); + delete[] exprstr; + delete[] str; + + // Remove the special macro `defined' from macro manager. + state->removeMacroFromStack (*parser->macroStack (), "defined"); + parser->macroManager ()->removeMacro ("defined", location); + + // Add a daughter node containing the value of the expression. + il->add_daughter (new PreCondSemNode (expr.value ())); + + // Now decide whether to go on or to ignore following C++ code. + if (expr.value ()) level->setState (false); + else state->passOnToken = false; + } + else // Ignore further tokens. + { + level->setPassOn (false); + level->setState (false); + } + } + } + +/***********************************************************************/ +/* ifdef_line */ +/***********************************************************************/ + +ifdef_line(idl) ::= TOK_PRE_IFDEF(ifd) token_list(tl). + { + idl = new PreIfdefDirective (ifd, tl); + + // A new conditional group starts, so go one level deeper. + level->deeper (); + + // Ignore further tokens. + if (! state->errorDirective) + { + level->setPassOn (false); + level->setState (false); + } + } +ifdef_line(idl) ::= TOK_PRE_IFDEF(ifd) TOK_PRE_ID(id) token_list(tl). + { + idl = new PreIfdefDirective (ifd, id, tl); + + // A new conditional group starts, so go one level deeper. + level->deeper (); + + if (! state->errorDirective) { + if (state->passOnToken) + { + const char* name = ((PreTreeToken*) id)->token ()->text (); + PreMacro* macro = parser->macroManager ()->getMacro (name); + + // Search the given macro name. If found the value of the + // conditional is true else it's false. Add a daughter node + // containing the value of the conditonal. + if (macro) + idl->add_daughter (new PreCondSemNode (true)); + else + idl->add_daughter (new PreCondSemNode (false)); + + // Now decide whether to go on or to ignore following C++ code. + if (macro) level->setState (false); + else state->passOnToken = false; + } + else // Ignore further tokens. + { + level->setPassOn (false); + level->setState (false); + } + } + } + +/***********************************************************************/ +/* ifndef_line */ +/***********************************************************************/ + +ifndef_line(indl) ::= TOK_PRE_IFNDEF(ind) token_list(tl). + { + indl = new PreIfndefDirective (ind, tl); + + // A new conditional group starts, so go one level deeper. + level->deeper (); + + // Ignore further tokens. + if (! state->errorDirective) + { + level->setPassOn (false); + level->setState (false); + } + } +ifndef_line(indl) ::= TOK_PRE_IFNDEF(ind) TOK_PRE_ID(id) token_list(tl). + { + indl = new PreIfndefDirective (ind, id, tl); + + // A new conditional group starts, so go one level deeper. + level->deeper (); + + if (! state->errorDirective) { + if (state->passOnToken) + { + const char* name = ((PreTreeToken*) id)->token ()->text (); + PreMacro* macro = parser->macroManager ()->getMacro (name); + + // Search the given macro name. If found the value of the + // conditional is false else it's true. Add a daughter node + // containing the value of the conditonal. + if (! macro) + indl->add_daughter (new PreCondSemNode (true)); + else + indl->add_daughter (new PreCondSemNode (false)); + + // Now decide whether to go on or to ignore following C++ code. + if (! macro) level->setState (false); + else state->passOnToken = false; + } + else // Ignore further tokens. + { + level->setPassOn (false); + level->setState (false); + } + } + } + +/***********************************************************************/ +/* elif_line */ +/***********************************************************************/ + +elif_line(eil) ::= TOK_PRE_ELIF(ei) token_list(tl). + { + eil = new PreElifDirective (ei, tl); + + if (! state->errorDirective) { + if (state->passOnToken && ! level->state ()) + state->passOnToken = false; + else if (! state->passOnToken && level->state ()) + { + // Create a new macro expander to expand the macros that could + // be part of the expression. + PreMacroExpander expander (parser); + + Location location = ((PreTreeToken*) ei)->token ()->location (); + + // Create a new expression evaluator. + PreExpr expr (err, location); + + // Now add the special macro `defined' to the macro manager. + PreTree* idl = new PreIdentifierList (ei); + PreMacro* macro = new PreMacro ("defined", idl, "\n"); + delete idl; + macro->location (location); + parser->macroManager ()->addMacro (macro); + + // Update the predefined macros. + updatePredefined (); + + // Build the expression string and then expand all macros within it. + // Then we should have a string consisting only of 0s, 1s and some + // operators like || or &&. Evaluate the string. + char* str = buildString (tl); + char* exprstr = expander.expandMacros (str); + expr.evaluatePreExpr (exprstr); + delete[] exprstr; + delete[] str; + + // Remove the special macro `defined' from macro manager. + state->removeMacroFromStack (*parser->macroStack (), "defined"); + parser->macroManager ()->removeMacro ("defined", location); + + // Add a daughter node containing the value of the expression. + eil->add_daughter (new PreCondSemNode (expr.value ())); + + // Now decide whether to go on or to ignore following C++ code. + if (expr.value ()) + { + state->passOnToken = true; + level->setState (false); + } + } + } + } + +/***********************************************************************/ +/* else_line */ +/***********************************************************************/ + +else_line(el) ::= TOK_PRE_ELSE(e) token_list(tl). + { + el = new PreElseDirective (e, tl); + + // Decide whether to go on or to ignore following C++ code. + if (! state->errorDirective) { + if (state->passOnToken && ! level->state ()) + state->passOnToken = false; + else if (! state->passOnToken && level->state ()) { + state->passOnToken = true; + level->setState (false); + } + } + } + +/***********************************************************************/ +/* endif_line */ +/***********************************************************************/ + +endif_line(eil) ::= TOK_PRE_ENDIF(ei) token_list(tl). + { + eil = new PreEndifDirective (ei, tl); + + // A conditional group ends. If no #error was parsed befor + // go one level higher. + + // Decide whether to go on or to ignore following C++ code. + if (! state->errorDirective) { + if (level->passOn ()) + state->passOnToken = true; + level->higher (); + } + } + +/***********************************************************************/ +/* control_line */ +/***********************************************************************/ + +control_line(cl) ::= include_line(il) TOK_PRE_DIRECTIVE_END. + { + cl = il; + } +control_line(cl) ::= include_next_line(inl) TOK_PRE_DIRECTIVE_END. + { + cl = inl; + } +control_line(cl) ::= assert_line(al) TOK_PRE_DIRECTIVE_END. + { + cl = al; + } +control_line(cl) ::= unassert_line(ual) TOK_PRE_DIRECTIVE_END. + { + cl = ual; + } +control_line(cl) ::= define_line(dl) TOK_PRE_DIRECTIVE_END. + { + cl = dl; + } +control_line(cl) ::= undef_line(udl) TOK_PRE_DIRECTIVE_END. + { + cl = udl; + } +control_line(cl) ::= warning_line(el) TOK_PRE_DIRECTIVE_END. + { + cl = el; + } +control_line(cl) ::= error_line(el) TOK_PRE_DIRECTIVE_END. + { + cl = el; + } + +/***********************************************************************/ +/* include_line */ +/***********************************************************************/ + +include_line(il) ::= TOK_PRE_INCLUDE(i) token_list(tl). + { + il = new PreIncludeDirective (i, tl); + + if (! state->errorDirective && state->passOnToken) + { + // Calculate the number of files included. + int num = state->getIncludeLevel ((TokenStream*)(parser->scanner ())); + + if (((PreIncludeDirective*)il)->is_forced ()) + state->forcedIncludes = true; + else if (!((PreIncludeDirective*)il)->is_forced () && num == 0) + state->forcedIncludes = false; + + if (state->forcedIncludes && num > 0) + num--; + + // Save current include depth. + ((PreIncludeDirective*)il)->depth (num); + + // If the number of files included is higher than a maximal + // count of maxIncludeDepth we should report an error and + // ignore the file to include. + if (num >= state->maxIncludeDepth) { + *err << ((PreTreeToken*) i)->token ()->location () + << sev_error << "Include recursion too deep (" + << num << ")" << endMessage; + } + + // Include the given file. + else + { // Update the predefined macros. + updatePredefined (); + + // Include the file and add a daughter node with a + // reference to that file to the syntax tree. + char* str = buildString (tl); + Unit* unit = 0; + bool guarded = false; + + const char *txt = ((PreTreeToken*)i)->token ()->text (); + + // compare last character of directive token to decide + // whether this is an #include or #import directive + if (txt && txt[strlen (txt)-1] == 't') { + // call the import handler with the arguments + // given at the #import line + ImportHandler ih (*parser, str); + unit = ih.IncludeFile (); + // do an ordinary #include + } else { + unit = parser->fileIncluder ()->includeFile (str); + guarded = parser->fileIncluder ()->guarded (); + } + + il->add_daughter (new PreInclSemNode (unit, guarded)); + delete[] str; + } + } + } + +/***********************************************************************/ +/* include_next_line */ +/***********************************************************************/ + +include_next_line(inl) ::= TOK_PRE_INCLUDE_NEXT(in) token_list(tl). + { + inl = new PreIncludeDirective (in, tl); + + if (! state->errorDirective && state->passOnToken) + { + // Calculate the number of files included. + int num = state->getIncludeLevel ((TokenStream*)(parser->scanner ())); + + // Save current include depth. + ((PreIncludeDirective*)inl)->depth (num); + + // If the number of files included is higher than a maximal + // count of maxIncludeDepth we should report an error and + // ignore the file to include. + if (num >= state->maxIncludeDepth) { + *err << ((PreTreeToken*) in)->token ()->location () + << sev_error << "Include recursion too deep (" + << num << ")" << endMessage; + } + + // Include the next file with the given filename. + else + { // Update the predefined macros. + updatePredefined (); + + // Include the next file and add a daughter node with + // a reference to that file to the syntax tree. + char* str = buildString (tl); + Unit *unit = parser->fileIncluder ()->includeNextFile (str); + bool guarded = parser->fileIncluder ()->guarded (); + inl->add_daughter (new PreInclSemNode (unit, guarded)); + delete[] str; + } + } + } + +/***********************************************************************/ +/* assert_line */ +/***********************************************************************/ + +assert_line(al) ::= TOK_PRE_ASSERT(a) token_list(tl). + { + al = new PreAssertDirective (a, tl); + } +assert_line(al) ::= TOK_PRE_ASSERT(a) TOK_PRE_ID(id) token_list(tl). + { + al = new PreAssertDirective (a, id, tl); + + if (! state->errorDirective && state->passOnToken) + { + // Get the answer text. + char* str = buildString (tl); + char* answer = evalAnswerString (str, true, *state); + delete[] str; + + // If the answer isn't NULL get the name of the predicate. + // If the predicate already exists add a new answer to that + // predicate otherwise create a new predicate. + if (answer) { + const char* name = ((PreTreeToken*) id)->token ()->text (); + if (PrePredicate* predicate = parser->predicateManager ()-> + getPredicate (name)) + predicate->addAnswer (answer); + else + parser->predicateManager ()->addPredicate ( + new PrePredicate (name, answer)); + delete[] answer; + } + } + } + +/***********************************************************************/ +/* unassert_line */ +/***********************************************************************/ + +unassert_line(ual) ::= TOK_PRE_UNASSERT(ua) token_list(tl). + { + ual = new PreUnassertDirective (ua, tl); + } +unassert_line(ual) ::= TOK_PRE_UNASSERT(ua) TOK_PRE_ID(id) token_list(tl). + { + ual = new PreUnassertDirective (ua, id, tl); + + if (! state->errorDirective && state->passOnToken) + { + // Get the answer text. + char* str = buildString (tl); + char* answer = evalAnswerString (str, false, *state); + delete[] str; + + // If the answer string is empty remove the whole predicate. + // Otherwise remove the answer for the predicate. + if (answer) { + const char* name = ((PreTreeToken*) id)->token ()->text (); + PrePredicate* predicate = parser->predicateManager ()-> + getPredicate (name); + + if (! strlen (answer)) + parser->predicateManager ()->removePredicate (name); + else if (predicate) + predicate->removeAnswer (answer); + + delete[] answer; + } + } + } + +/***********************************************************************/ +/* define_line */ +/***********************************************************************/ + +define_line(dl) ::= TOK_PRE_DEFINE(d) token_list(tl). + { + dl = new PreDefineConstantDirective (d, tl); + } +define_line(dl) ::= TOK_PRE_DEFINE(d) TOK_PRE_ID(fid) TOK_PRE_LPAREN(l) + TOK_PRE_RPAREN(r) token_list(tl). + { + dl = new PreDefineFunctionDirective (d, fid, l, r, tl); + + if (! state->errorDirective && state->passOnToken) + { + // Build a new function-like macro without arguments. + char* str = buildString (tl); + PreMacro* macro = new PreMacro (((PreTreeToken*) fid)-> + token ()->dtext (), (PreTree*) 0, str); + delete[] str; + macro->location (((PreTreeToken*) d)->token ()->location ()); + + // Add the macro to the macro manager if its name is a valid + // macro name. + if (state->checkMacroName (macro)) + parser->macroManager ()->addMacro (macro); + else + delete macro; + } + } +define_line(dl) ::= TOK_PRE_DEFINE(d) TOK_PRE_ID(fid) TOK_PRE_LPAREN(l) + TOK_PRE_REST(rest) TOK_PRE_RPAREN(r) token_list(tl). + { + dl = new PreDefineFunctionDirective (d, fid, l, rest, r, tl); + + if (! state->errorDirective && state->passOnToken) + { + // Build a new function-like macro with variable number + // of arguments. + char* str = buildString (tl); + PreMacro* macro = new PreMacro (((PreTreeToken*) fid)-> + token ()->dtext (), (PreTree*) 0, str, + PreMacro::VAR_ARG_MACRO); + delete[] str; + macro->addArg ("__VA_ARGS__"); + macro->location (((PreTreeToken*) d)->token ()->location ()); + + // Add the macro to the macro manager if its name is a valid + // macro name. + if (state->checkMacroName (macro)) + parser->macroManager ()->addMacro (macro); + else + delete macro; + } + } +define_line(dl) ::= TOK_PRE_DEFINE(d) TOK_PRE_ID(fid) TOK_PRE_LPAREN(l) + identifier_list(il) + TOK_PRE_RPAREN(r) token_list(tl). + { + dl = new PreDefineFunctionDirective (d, fid, l, il, r, tl); + + if (! state->errorDirective && state->passOnToken) + { + // Build a new function-like macro with arguments. + char* str = buildString (tl); + PreMacro* macro = new PreMacro (((PreTreeToken*) fid)-> + token ()->dtext (), il, str); + delete[] str; + macro->location (((PreTreeToken*) d)->token ()->location ()); + + // Add the macro to the macro manager if its name is a valid + // macro name. + if (state->checkMacroName (macro)) + parser->macroManager ()->addMacro (macro); + else + delete macro; + } + } +define_line(dl) ::= TOK_PRE_DEFINE(d) TOK_PRE_ID(fid) TOK_PRE_LPAREN(l) + identifier_list(il) TOK_PRE_REST(rest) + TOK_PRE_RPAREN(r) token_list(tl). + { + dl = new PreDefineFunctionDirective (d, fid, l, il, rest, r, tl); + + if (! state->errorDirective && state->passOnToken) + { + // Build a new function-like macro with arguments. + char* str = buildString (tl); + PreMacro* macro = new PreMacro (((PreTreeToken*) fid)-> + token ()->dtext (), il, str, + PreMacro::VAR_ARG_MACRO); + delete[] str; + macro->location (((PreTreeToken*) d)->token ()->location ()); + + // Add the macro to the macro manager if its name is a valid + // macro name. + if (state->checkMacroName (macro)) + parser->macroManager ()->addMacro (macro); + else + delete macro; + } + } +define_line(dl) ::= TOK_PRE_DEFINE(d) TOK_PRE_ID(fid) TOK_PRE_LPAREN(l) + identifier_list(il) TOK_PRE_COMMA(c) TOK_PRE_REST(rest) + TOK_PRE_RPAREN(r) token_list(tl). + { + dl = new PreDefineFunctionDirective (d, fid, l, il, c, rest, r, tl); + + if (! state->errorDirective && state->passOnToken) + { + // Build a new function-like macro with arguments. + char* str = buildString (tl); + PreMacro* macro = new PreMacro (((PreTreeToken*) fid)-> + token ()->dtext (), il, str, + PreMacro::VAR_ARG_MACRO); + delete[] str; + macro->addArg ("__VA_ARGS__"); + macro->location (((PreTreeToken*) d)->token ()->location ()); + + // Add the macro to the macro manager if its name is a valid + // macro name. + if (state->checkMacroName (macro)) + parser->macroManager ()->addMacro (macro); + else + delete macro; + } + } +define_line(dl) ::= TOK_PRE_DEFINE(d) TOK_PRE_ID(id) token_list(tl). + { + dl = new PreDefineConstantDirective (d, id, tl); + + if (! state->errorDirective && state->passOnToken) + { + // Build a new simple macro. + char* str = buildString (tl); + PreMacro* macro = new PreMacro (((PreTreeToken*) id)-> + token ()->dtext (), str); + delete[] str; + macro->location (((PreTreeToken*) d)->token ()->location ()); + + // Add the macro to the macro manager if its name is a valid + // macro name. + if (state->checkMacroName (macro)) + parser->macroManager ()->addMacro (macro); + else + delete macro; + } + } + +/***********************************************************************/ +/* undef_line */ +/***********************************************************************/ + +undef_line(ul) ::= TOK_PRE_UNDEF(ud) token_list(tl). + { + ul = new PreUndefDirective (ud, tl); + } +undef_line(ul) ::= TOK_PRE_UNDEF(ud) TOK_PRE_ID(id) token_list(tl). + { + ul = new PreUndefDirective (ud, id, tl); + + // Remove the macro given by its name from macro manager. + if (! state->errorDirective && state->passOnToken) { + Token* token = ((PreTreeToken*) id)->token ();; + state->removeMacroFromStack (*parser->macroStack (), token->text ()); + parser->macroManager ()->removeMacro (token->dtext (), token->location ()); + } + } + +/***********************************************************************/ +/* warning_line */ +/***********************************************************************/ + +warning_line(wl) ::= TOK_PRE_WARNING(w) token_list(tl). + { + wl = new PreWarningDirective (w, tl); + + if (! state->errorDirective && state->passOnToken) + { + // Print a warning message containing the text given as + // argument of the #warning directive. + char* message = buildString (tl); + *err << ((PreTreeToken*) w)->token ()->location () + << sev_warning << message << endMessage; + delete[] message; + } + } + +/***********************************************************************/ +/* error_line */ +/***********************************************************************/ + +error_line(el) ::= TOK_PRE_ERROR(e) token_list(tl). + { + el = new PreErrorDirective (e, tl); + + if (! state->errorDirective && state->passOnToken) + { + // Tell the parser to hide all following tokens from + // other parsers in chain. + state->errorDirective = true; + + // Print the text given as argument of the #error + // directive. + char* message = buildString (tl); + *err << ((PreTreeToken*) e)->token ()->location () + << sev_error << message << endMessage; + delete[] message; + } + } + +/***********************************************************************/ +/* identifier_list */ +/***********************************************************************/ + +identifier_list(idl) ::= TOK_PRE_ID(id). + { + idl = new PreIdentifierList (id); + } +identifier_list(idl) ::= identifier_list(oidl) TOK_PRE_COMMA(c) TOK_PRE_ID(id). + { + ((PreIdentifierList*) (oidl))->addSons (c, id); + idl = oidl; + } + +/************************************************************************/ +/* special token_list e.g. with macros that have to be expanded */ +/************************************************************************/ + +token_list(tl) ::= TOK_PRE_NEWLINE(nl). + { + if (nl->startToken () == state->newline) + { + delete nl; + tl = new PreTokenList (); + } + else + tl = nl; + } +token_list(tl) ::= token_list_part(tlp) TOK_PRE_NEWLINE(nl). + { + if (nl->startToken () == state->newline) + { + delete nl; + tl = new PreTokenList (tlp); + } + else + tl = new PreTokenList (tlp, nl); + } + +/************************************************************************/ +/* token list part */ +/************************************************************************/ + +token_list_part(tlp) ::= TOK_PRE_TOKEN_LIST(ttl). + { + tlp = new PreTokenListPart (ttl); + } +token_list_part(tlp) ::= token_list_part(tlpo) TOK_PRE_TOKEN_LIST(ttl). + { + tlpo->add_son (ttl); + tlp = tlpo; + } diff --git a/Puma/src/cpp/PreParserState.cc b/Puma/src/cpp/PreParserState.cc new file mode 100644 index 0000000..aeebf85 --- /dev/null +++ b/Puma/src/cpp/PreParserState.cc @@ -0,0 +1,212 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/Unit.h" +#include "Puma/Token.h" +#include "Puma/SysCall.h" +#include "Puma/PreMacro.h" +#include "Puma/PreTree.h" +#include "Puma/TokenStream.h" +#include "Puma/ErrorStream.h" +#include "Puma/PreParserState.h" +#include "Puma/PreMacroManager.h" +#include "Puma/CCommentTokens.h" +#include +#include +#include + +namespace Puma { + + +PreParserState::PreParserState () : + _Line("__LINE__"), _File("__FILE__"), + _Date("__DATE__"), _Time("__TIME__"), + _IncLevel("__INCLUDE_LEVEL__"), + _Defined("defined"), _Defined1("defined("), + _LastDay(-1) { + noFILE = noLINE = noDATE = false; + noTIME = noINCLUDE_LEVEL = false; + syntaxError = errorDirective = false; + syntaxTree = (PreTree*) 0; + sl_token = (Token*) 0; + lastToken = currToken = (Token*) 0; + lastType = currType = Token::ID_UNKNOWN; + passOnToken = true; + forcedIncludes = false; + parseMacroArgs = false; + newline = new Token (TOK_WSPACE, "\n"); +} + + +// Check whether the macro name is valid. +bool PreParserState::checkMacroName (PreMacro* macro) { + // Some predefined macros can be redefined. If so they are not + // computed anymore by the preprocessor. + if (macro->getName () == _IncLevel) { + noINCLUDE_LEVEL = true; + } else if (macro->getName () == _Line) { + noLINE = true; + } else if (macro->getName () == _Date) { + noDATE = true; + } else if (macro->getName () == _File) { + noFILE = true; + } else if (macro->getName () == _Time) { + noTIME = true; + + // The special name `defined' can't be used for a macro. + } else if (macro->getName () == _Defined || + macro->getName () == _Defined1) { + *err << macro->location () << sev_error + << "`defined' is not a valid macro name" + << endMessage; + return false; + } + return true; +} + + +// Calculate the number of files on the input stream. +int PreParserState::getIncludeLevel (TokenStream* stream) { + int len = stream->length (), level = 0; + for (int i = 0; i < len; i++) + if (stream->fetch (i)->unit ()->isFile ()) + level++; + // don't count the primary input file + return level > 0 ? level-1 : 0; +} + + +// Check whether macro is one of the special predefined macros. +PreMacro* PreParserState::checkPredefined (PreMacro* macro, TokenStream* scanner, PreMacroManager& manager) { + if (! macro) + return 0; + + // Integer constant representing the depth of nesting in include files. + if (macro == manager.getIncLevelMacro() && ! noINCLUDE_LEVEL) { + char value[12]; + snprintf (value, 12, "%i", getIncludeLevel (scanner)); + macro->setBody(value); + } + + // String constant representing the current input file. + else if (macro == manager.getFileMacro() && ! noFILE) { + Unit* unit = 0; + for (int i = scanner->length () - 1; !unit && i >= 0; i--) + if (scanner->fetch (i)->unit ()->isFile ()) + unit = scanner->fetch (i)->unit (); + if (unit) { + char* buffer = unit->name (); + char* value = new char[strlen (buffer) + 3]; + sprintf (value, "\"%s\"", buffer); + macro->setBody(value); + delete [] value; + } + } + + // Integer constant representing the current input line number. + else if (macro == manager.getLineMacro() && ! noLINE) { + char value[12]; + sprintf (value, "%i", currToken->location ().line ()); + macro->setBody(value); + } + + // String constant representing the current date of the form + // "Apr 1 1999". + else if (macro == manager.getDateMacro() && ! noDATE) { + time_t curtime = SysCall::time (NULL, err); + tm* loctime = localtime (&curtime); + if (_LastDay != loctime->tm_mday) { + char buffer[16]; + char value[16]; + _LastDay = loctime->tm_mday; + strftime (buffer, 12, "%b %d %Y", loctime); + sprintf (value, "\"%s\"", buffer); + macro->setBody(value); + } + } + + // String constant representing the current time of the form + // "12:30:45". + else if (macro == manager.getTimeMacro() && ! noTIME) { + char buffer[16]; + char value[16]; + time_t curtime = SysCall::time (NULL, err); + tm* loctime = localtime (&curtime); + strftime (buffer, 9, "%H:%M:%S", loctime); + sprintf (value, "\"%s\"", buffer); + macro->setBody(value); + } + + return macro; +} + + +// Check whether macro is a "self-referential" macro. +bool PreParserState::isSelfReferentialMacro (PreMacro* macro, Array& macroStack) { + // A special feature of ANSI Standard C is that the self-reference + // is not considered a macro call, it is passed to the preprocessor + // output unchanged. + + // Search macro on stack. If found it is a self-referential macro. + for (int i = macroStack.length () - 1; i >= 0; i--) { + PreMacro* current = macroStack.fetch (i); + if (current == macro) + return true; + } + return false; +} + + +// Put a macro on the macro stack +void PreParserState::putMacroOnStack (Array ¯oStack, PreMacro *macro, int stream_len) { + for (int i = macroStack.length (); i < stream_len; i++) + macroStack[i] = 0; + macroStack[stream_len-1] = macro; +} + + +// Remove macro from macro stack. +void PreParserState::removeMacroFromStack (Array ¯oStack, const char* name) { + for (int i = macroStack.length () - 1; i >= 0; i--) { + PreMacro* macro = macroStack.fetch (i); + if (macro && strcmp(name, macro->getName ()) == 0) { + macroStack[i] = 0; + break; + } + } +} + + +// Update the macro stack. +void PreParserState::updateMacroStack (Array& macroStack, int stream_len) { + // Shrink macro stack according to the input stream. + for (int i = macroStack.length () - 1; i > (stream_len-1); i--) + macroStack.remove (i); +} + + +// Check if current parsing code of a macro expansion. +bool PreParserState::inMacroExpansion (Array& macroStack) { + for (int i = macroStack.length () - 1; i >= 0; i--) + if (macroStack.fetch (i) != 0) + return true; + return false; +} + + +} // namespace Puma diff --git a/Puma/src/cpp/PreParserState.h b/Puma/src/cpp/PreParserState.h new file mode 100644 index 0000000..d2d23ed --- /dev/null +++ b/Puma/src/cpp/PreParserState.h @@ -0,0 +1,103 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __pre_parser_state__ +#define __pre_parser_state__ + +// The state of a preprocessor parser. It contains all variable +// parts of the preprocessor parser belonging not to the generated +// lemon parser. + +#include + +#include "Puma/Array.h" +#include "Puma/Token.h" +#include "Puma/PreMacroManager.h" + +namespace Puma { + + +class ErrorStream; +class PreTree; +class PreMacro; +class TokenStream; + +class PreParserState { + // some constant strings + DString _Line, _File, _Date, _Time, _IncLevel; + DString _Defined, _Defined1; + + int _LastDay; + +public: + PreParserState (); + ~PreParserState () { delete newline; } + + // Check whether a macro name is valid. + bool checkMacroName (PreMacro *); + + // Check whether macro is one of the special `predefined' macros. + PreMacro *checkPredefined (PreMacro *, TokenStream *, PreMacroManager &); + + // Check whether macro is a `self-referential' macro. + bool isSelfReferentialMacro (PreMacro *, Array &); + + // Put a macro on the macro stack. + void putMacroOnStack (Array &, PreMacro *, int stream_len); + + // Remove macro from macro stack. + void removeMacroFromStack (Array ¯oStack, const char* name); + + // Update the macro stack position. + void updateMacroStack (Array ¯oStack, int stream_len); + + // Calculate the number of files on the input stream. + int getIncludeLevel (TokenStream* stream); + + // Check if current parsing code of a macro expansion. + bool inMacroExpansion (Array& macroStack); + +public: + int maxIncludeDepth; // Maximal include depth. + + // Are true if the special macros FILE, LINE ... has been redefined. + bool noFILE, noLINE, noDATE, noTIME, noINCLUDE_LEVEL; + + bool syntaxError; // True if a syntax error occured. + bool errorDirective; // True if a #error directive has been parsed. + bool passOnToken; // If false, following C++ code will be ignored. + bool forcedIncludes; // True as long as we are parsing forced include files. + bool parseMacroArgs; // True if parsing macro arguments. + + Token *sl_token; // Single line comment start token. + Token *currToken; // The current token to parse. + Token *lastToken; // Last parsed token. + int currType; // The type of the current token to parse. + int lastType; // The type of the last parsed token. + + void *pParser; // Pointer to the Lemon generated parser. + ErrorStream *err; // Error stream. + PreTree *syntaxTree; // Preprocessor syntax tree. + + Token *newline; // Token to trick the parser. +}; + + +} // namespace Puma + +#endif /* __pre_parser_state__ */ diff --git a/Puma/src/cpp/PrePredicate.cc b/Puma/src/cpp/PrePredicate.cc new file mode 100644 index 0000000..0964f8a --- /dev/null +++ b/Puma/src/cpp/PrePredicate.cc @@ -0,0 +1,94 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/PrePredicate.h" +#include "Puma/PreAnswer.h" +#include "Puma/StrCol.h" +#include +#include + +namespace Puma { + + +PrePredicate::PrePredicate (const char* name, const char* firstAnswer) + { + // Copy the predicate name. + _name = name ? StrCol::dup (name) : (char*) 0; + + // Add the first answer for the predicate. + append (*(new PreAnswer (firstAnswer))); + _numAnswers = 1; + } + + +// Destructor. +PrePredicate::~PrePredicate () + { + if (_name) delete[] _name; + clear (); + } + + +// Add a new answer for the predicate. +void PrePredicate::addAnswer (const char* answerText) + { + // Add the new answer only if this answer don't yet exist. + if (! isAnswer (answerText)) + { + append (*(new PreAnswer (answerText))); + _numAnswers++; + } + } + + +// Remove the given answer from the answer array. +void PrePredicate::removeAnswer (const char* answerText) + { + PreAnswer* answer = (PreAnswer*) first (); + + // Search the given answer and remove it if found. + for (; answer; answer = (PreAnswer*) next (answer)) + if (! StrCol::effectivelyDifferent (answer->text (), answerText)) + { + kill (answer); + //List* l = cut (answer); l->clear (); delete l; + _numAnswers--; + break; + } + } + + +// Return true if the given answer is a answer to the predicate. +bool PrePredicate::isAnswer (const char* answerText) const + { + PreAnswer* answer = (PreAnswer*) first (); + + // If the given answer differs only in spaces from an existing + // answer return true. White spaces can be added or removed at + // the begin and the end of the answer. In the middle of the + // answer spaces can only be added where spaces has been before, + // but it isn't allowed to remove spaces completely. + for (; answer; answer = (PreAnswer*) next (answer)) + if (! StrCol::effectivelyDifferent (answer->text (), answerText)) + return true; + + return false; + } + + +} // namespace Puma diff --git a/Puma/src/cpp/PrePredicate.h b/Puma/src/cpp/PrePredicate.h new file mode 100644 index 0000000..b1cfd5d --- /dev/null +++ b/Puma/src/cpp/PrePredicate.h @@ -0,0 +1,60 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __pre_predicate__ +#define __pre_predicate__ + +// Preprocessor predicate class. A predicate has a set of answers. +// Answers can be added to or remove from a predicate. You can +// assert an answer for a predicate within a conditional and it +// will be checked whether this is a right answer to the predicate. +// That makes predicates to an alternative for the use of macros +// within conditionals. + +#include "Puma/List.h" + +namespace Puma { + + +class PrePredicate : public List { + char *_name; // The name of the predicate. + int _numAnswers; // The number of arguments. + +public: + // Constructor for a new predicate. + PrePredicate (const char *name, const char *answer); + virtual ~PrePredicate (); + + // Add a new answer for the predicate. + void addAnswer (const char *answer); + + // Remove an answer for the predicate. + void removeAnswer (const char *answer); + + // Return if given answer is an answer for the predicate. + bool isAnswer (const char *answer) const; + + // Get several informations of the predicate. + char *getName () const { return _name; } + int numAnswers () const { return _numAnswers; } +}; + + +} // namespace Puma + +#endif /* __pre_predicate__ */ diff --git a/Puma/src/cpp/PrePredicateManager.cc b/Puma/src/cpp/PrePredicateManager.cc new file mode 100644 index 0000000..d8d7115 --- /dev/null +++ b/Puma/src/cpp/PrePredicateManager.cc @@ -0,0 +1,56 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/PrePredicateManager.h" +#include "Puma/PrePredicate.h" + +namespace Puma { + +// Destroy the predicates too. +PrePredicateManager::~PrePredicateManager () { + // iterate over all stored predicates and delete the objects + for (iterator iter = begin (); iter != end (); ++iter) + delete (*iter).second; +} + + +// Add given predicate to predicate table. +void PrePredicateManager::addPredicate (PrePredicate* predicate) { + assert (predicate); + insert (PMap::value_type (predicate->getName (), predicate)); +} + + +// Remove predicate `name' from predicate table. +void PrePredicateManager::removePredicate (const char *name) { + assert (name); + iterator entry = find (name); + if (entry != end ()) { + delete (*entry).second; + erase (entry); + } +} + +// Get predicate `name'. +PrePredicate* PrePredicateManager::getPredicate (const char* name) const { + const_iterator entry = find (name); + return entry == end () ? 0 : (*entry).second; +} + + +} // namespace Puma diff --git a/Puma/src/cpp/PrePredicateManager.h b/Puma/src/cpp/PrePredicateManager.h new file mode 100644 index 0000000..94d7399 --- /dev/null +++ b/Puma/src/cpp/PrePredicateManager.h @@ -0,0 +1,55 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __pre_predicate_manager__ +#define __pre_predicate_manager__ + +// The predicate manager manages all preprocessor predicates defined +// through the `#assert' directive in the source code. + +#include +#include + +namespace Puma { + + +class PrePredicate; + +class PrePredicateManager : private std::map { + + typedef std::map PMap; + +public: + + // Destroy the predicates too. + ~PrePredicateManager (); + + // Add given predicate to predicate table. + void addPredicate (PrePredicate *); + + // Remove predicate `name' from predicate table. + void removePredicate (const char *name); + + // Get predicate `name'. + PrePredicate *getPredicate (const char *) const; +}; + + +} // namespace Puma + +#endif /* __pre_predicate_manager__ */ diff --git a/Puma/src/cpp/PrePrintVisitor.cc b/Puma/src/cpp/PrePrintVisitor.cc new file mode 100644 index 0000000..5a7bfa7 --- /dev/null +++ b/Puma/src/cpp/PrePrintVisitor.cc @@ -0,0 +1,449 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/PreSemIterator.h" +#include "Puma/PrePrintVisitor.h" +#include "Puma/PreTreeNodes.h" +#include "Puma/PreTreeToken.h" +#include "Puma/PreSonIterator.h" +#include "Puma/PreTree.h" +#include "Puma/PreParser.h" +#include "Puma/Token.h" +#include +#include + + +namespace Puma { + + +// Print the memory address of the current node object and some +// white spaces depending on the tree position. +void PrePrintVisitor::prologue (PreTree* memaddr) + { + _depth++; + /* warning! the type cast swallows bits */ + *_os << std::hex << std::setfill('0') << std::setw(8) + << (unsigned long)(size_t) memaddr << " " << std::dec; + for (int i = 0; i < _depth; i++) + *_os << " "; + } + + +// Print the number of sons and daughters and the scope of the node. +void PrePrintVisitor::mainPart (PreTree* node) + { + Token* token; + + *_os << "\t### " << node->sons () << " " << node->daughters (); + if ((token = node->startToken ())) { + *_os << " from: '"; + if (token->type () == TOK_PRE_NEWLINE) + *_os << "\\n"; + else + printWithoutNewlines (token->text ()); + *_os << "'"; + } + if ((token = node->endToken ())) { + *_os << " to: '"; + if (token->type () == TOK_PRE_NEWLINE) + *_os << "\\n"; + else + printWithoutNewlines (token->text ()); + *_os << "'"; + } + *_os << std::endl; + + if (node->daughters ()) { + // Create the daughter iterator. + PreTreeIterator* i = new PreSemIterator (node); + + // Go through the daughters. + for (i->first (); ! i->isDone (); i->next ()) + i->currentItem ()->accept (*this); + } +} + + +// Print the token text without newlines. +void PrePrintVisitor::printWithoutNewlines (const char* text) { + size_t len = strlen(text); + for (size_t i = 0; i < len; i++) { + if (text[i] == '\n') { + *_os << "\\n"; + } else { + *_os << text[i]; + } + } +} + + +// Visit the daughters if exist. +void PrePrintVisitor::epilogue (PreTree* node) + { + _depth--; + } + + +// Go through the nodes. +void PrePrintVisitor::iterateNodes (PreTree* node) + { + PreTreeIterator* i; + + if (_what == SONS) + i = new PreSonIterator (node); + else + i = new PreSemIterator (node); + + for (i->first (); ! i->isDone (); i->next ()) + i->currentItem ()->accept (*this); + + delete i; + } + + +void PrePrintVisitor::visitPreTreeToken (PreTreeToken* node) + { + prologue (node); + *_os << "Token '"; + if (node->token ()->type () == TOK_PRE_NEWLINE) + *_os << "\\n"; + else + printWithoutNewlines (node->token ()->text ()); + *_os << "'\t### " << node->sons () << " " << node->daughters () << std::endl; + _depth--; + } + + +void PrePrintVisitor::visitPreError (PreError* node) + { + prologue (node); + *_os << "Error"; + mainPart (node); + epilogue (node); + } + + +void PrePrintVisitor::visitPreCondSemNode (PreCondSemNode* node) + { + prologue (node); + *_os << "=> Value '"; + if (node->value ()) + *_os << "true"; + else + *_os << "false"; + *_os << "'"; + mainPart (node); + epilogue (node); + } + +void PrePrintVisitor::visitPreInclSemNode (PreInclSemNode* node) + { + prologue (node); + *_os << "=> File '" << node->unit ()->name () << "'"; + mainPart (node); + epilogue (node); + } + + +void PrePrintVisitor::visitPreProgram_Pre (PreProgram* node) + { + prologue (node); + *_os << "Program"; + mainPart (node); + } + +void PrePrintVisitor::visitPreProgram_Post (PreProgram* node) + { + epilogue (node); + } + + +void PrePrintVisitor::visitPreDirectiveGroups_Pre (PreDirectiveGroups* node) + { + prologue (node); + *_os << "DirectiveGroups"; + mainPart (node); + } + +void PrePrintVisitor::visitPreDirectiveGroups_Post (PreDirectiveGroups* node) + { + epilogue (node); + } + + +void PrePrintVisitor::visitPreConditionalGroup_Pre (PreConditionalGroup* node) + { + prologue (node); + *_os << "ConditionalGroup"; + mainPart (node); + } + +void PrePrintVisitor::visitPreConditionalGroup_Post (PreConditionalGroup* node) + { + epilogue (node); + } + + +void PrePrintVisitor::visitPreElsePart_Pre (PreElsePart* node) + { + prologue (node); + *_os << "ElsePart"; + mainPart (node); + } + +void PrePrintVisitor::visitPreElsePart_Post (PreElsePart* node) + { + epilogue (node); + } + + +void PrePrintVisitor::visitPreElifPart_Pre (PreElifPart* node) + { + prologue (node); + *_os << "ElifPart"; + mainPart (node); + } + +void PrePrintVisitor::visitPreElifPart_Post (PreElifPart* node) + { + epilogue (node); + } + + +void PrePrintVisitor::visitPreIfDirective_Pre (PreIfDirective* node) + { + prologue (node); + *_os << "IfDirective"; + mainPart (node); + } + +void PrePrintVisitor::visitPreIfDirective_Post (PreIfDirective* node) + { + epilogue (node); + } + + +void PrePrintVisitor::visitPreIfdefDirective_Pre (PreIfdefDirective* node) + { + prologue (node); + *_os << "IfdefDirective"; + mainPart (node); + } + +void PrePrintVisitor::visitPreIfdefDirective_Post (PreIfdefDirective* node) + { + epilogue (node); + } + + +void PrePrintVisitor::visitPreIfndefDirective_Pre (PreIfndefDirective* node) + { + prologue (node); + *_os << "IfndefDirective"; + mainPart (node); + } + +void PrePrintVisitor::visitPreIfndefDirective_Post (PreIfndefDirective* node) + { + epilogue (node); + } + + +void PrePrintVisitor::visitPreElifDirective_Pre (PreElifDirective* node) + { + prologue (node); + *_os << "ElifDirective"; + mainPart (node); + } + +void PrePrintVisitor::visitPreElifDirective_Post (PreElifDirective* node) + { + epilogue (node); + } + + +void PrePrintVisitor::visitPreElseDirective_Pre (PreElseDirective* node) + { + prologue (node); + *_os << "ElseDirective"; + mainPart (node); + } + +void PrePrintVisitor::visitPreElseDirective_Post (PreElseDirective* node) + { + epilogue (node); + } + + +void PrePrintVisitor::visitPreEndifDirective_Pre (PreEndifDirective* node) + { + prologue (node); + *_os << "EndifDirective"; + mainPart (node); + } + +void PrePrintVisitor::visitPreEndifDirective_Post (PreEndifDirective* node) + { + epilogue (node); + } + + +void PrePrintVisitor::visitPreIncludeDirective_Pre (PreIncludeDirective* node) + { + prologue (node); + *_os << (node->is_forced () ? "Forced" : "" ) << "IncludeDirective"; + mainPart (node); + } + +void PrePrintVisitor::visitPreIncludeDirective_Post (PreIncludeDirective* node) + { + epilogue (node); + } + + +void PrePrintVisitor::visitPreAssertDirective_Pre (PreAssertDirective* node) + { + prologue (node); + *_os << "AssertDirective"; + mainPart (node); + } + +void PrePrintVisitor::visitPreAssertDirective_Post (PreAssertDirective* node) + { + epilogue (node); + } + + +void PrePrintVisitor::visitPreUnassertDirective_Pre (PreUnassertDirective* node) + { + prologue (node); + *_os << "UnassertDirective"; + mainPart (node); + } + +void PrePrintVisitor::visitPreUnassertDirective_Post (PreUnassertDirective* node) + { + epilogue (node); + } + + +void PrePrintVisitor::visitPreDefineFunctionDirective_Pre (PreDefineFunctionDirective* node) + { + prologue (node); + *_os << "DefineFunctionDir"; + mainPart (node); + } + +void PrePrintVisitor::visitPreDefineFunctionDirective_Post (PreDefineFunctionDirective* node) + { + epilogue (node); + } + + +void PrePrintVisitor::visitPreDefineConstantDirective_Pre (PreDefineConstantDirective* node) + { + prologue (node); + *_os << "DefineConstantDir"; + mainPart (node); + } + +void PrePrintVisitor::visitPreDefineConstantDirective_Post (PreDefineConstantDirective* node) + { + epilogue (node); + } + + +void PrePrintVisitor::visitPreUndefDirective_Pre (PreUndefDirective* node) + { + prologue (node); + *_os << "UndefDirective"; + mainPart (node); + } + +void PrePrintVisitor::visitPreUndefDirective_Post (PreUndefDirective* node) + { + epilogue (node); + } + + +void PrePrintVisitor::visitPreWarningDirective_Pre (PreWarningDirective* node) + { + prologue (node); + *_os << "WarningDirective"; + mainPart (node); + } + +void PrePrintVisitor::visitPreWarningDirective_Post (PreWarningDirective* node) + { + epilogue (node); + } + + +void PrePrintVisitor::visitPreErrorDirective_Pre (PreErrorDirective* node) + { + prologue (node); + *_os << "ErrorDirective"; + mainPart (node); + } + +void PrePrintVisitor::visitPreErrorDirective_Post (PreErrorDirective* node) + { + epilogue (node); + } + + +void PrePrintVisitor::visitPreIdentifierList_Pre (PreIdentifierList* node) + { + prologue (node); + *_os << "IdentifierList"; + mainPart (node); + } + +void PrePrintVisitor::visitPreIdentifierList_Post (PreIdentifierList* node) + { + epilogue (node); + } + + +void PrePrintVisitor::visitPreTokenList_Pre (PreTokenList* node) + { + prologue (node); + *_os << "TokenList"; + *_os << "\t### " << node->sons () << " " << node->daughters () << std::endl; + } + +void PrePrintVisitor::visitPreTokenList_Post (PreTokenList* node) + { + _depth--; + } + + +void PrePrintVisitor::visitPreTokenListPart_Pre (PreTokenListPart* node) + { + prologue (node); + *_os << "TokenListPart"; + *_os << "\t### " << node->sons () << " " << node->daughters () << std::endl; + } + +void PrePrintVisitor::visitPreTokenListPart_Post (PreTokenListPart* node) + { + _depth--; + } + + +} // namespace Puma diff --git a/Puma/src/cpp/PrePrintVisitor.h b/Puma/src/cpp/PrePrintVisitor.h new file mode 100644 index 0000000..a37ff8a --- /dev/null +++ b/Puma/src/cpp/PrePrintVisitor.h @@ -0,0 +1,135 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __pre_print_visitor__ +#define __pre_print_visitor__ + +// Visitor to print the preprocessor syntax tree on given stream. + +#include "Puma/PreVisitor.h" +#include + +namespace Puma { + + +class PrePrintVisitor : public PreVisitor { + std::ostream *_os; // The given output stream. + long _depth; // The recursion depth. + int _what; // Decide whether to print sons or daughters. + + // Things to do befor visiting sons or daughters. + void prologue (PreTree *); + void mainPart (PreTree *); + + // Things to do after visited sons or daughters. + void epilogue (PreTree *); + + // Print the token text without newlines. + void printWithoutNewlines (const char* text); + +public: + static const int SONS = 1; + static const int DAUGHTERS = 2; + + PrePrintVisitor (std::ostream &os = std::cout, long depth = 0, int what = SONS) : + _os (&os), _depth (depth), _what (what) {}; + + // Go through the nodes of the syntax tree. + void iterateNodes (PreTree *); + +public: + // Visiting the parts of the preprocessor syntax tree. + + void visitPreTreeToken (PreTreeToken *); + + void visitPreError (PreError *); + + void visitPreCondSemNode (PreCondSemNode *); + void visitPreInclSemNode (PreInclSemNode *); + + void visitPreProgram_Pre (PreProgram *); + void visitPreProgram_Post (PreProgram *); + + void visitPreDirectiveGroups_Pre (PreDirectiveGroups *); + void visitPreDirectiveGroups_Post (PreDirectiveGroups *); + + void visitPreConditionalGroup_Pre (PreConditionalGroup *); + void visitPreConditionalGroup_Post (PreConditionalGroup *); + + void visitPreElsePart_Pre (PreElsePart *); + void visitPreElsePart_Post (PreElsePart *); + + void visitPreElifPart_Pre (PreElifPart *); + void visitPreElifPart_Post (PreElifPart *); + + void visitPreIfDirective_Pre (PreIfDirective *); + void visitPreIfDirective_Post (PreIfDirective *); + + void visitPreIfdefDirective_Pre (PreIfdefDirective *); + void visitPreIfdefDirective_Post (PreIfdefDirective *); + + void visitPreIfndefDirective_Pre (PreIfndefDirective *); + void visitPreIfndefDirective_Post (PreIfndefDirective *); + + void visitPreElifDirective_Pre (PreElifDirective *); + void visitPreElifDirective_Post (PreElifDirective *); + + void visitPreElseDirective_Pre (PreElseDirective *); + void visitPreElseDirective_Post (PreElseDirective *); + + void visitPreEndifDirective_Pre (PreEndifDirective *); + void visitPreEndifDirective_Post (PreEndifDirective *); + + void visitPreIncludeDirective_Pre (PreIncludeDirective *); + void visitPreIncludeDirective_Post (PreIncludeDirective *); + + void visitPreAssertDirective_Pre (PreAssertDirective *); + void visitPreAssertDirective_Post (PreAssertDirective *); + + void visitPreUnassertDirective_Pre (PreUnassertDirective *); + void visitPreUnassertDirective_Post (PreUnassertDirective *); + + void visitPreDefineFunctionDirective_Pre (PreDefineFunctionDirective *); + void visitPreDefineFunctionDirective_Post (PreDefineFunctionDirective *); + + void visitPreDefineConstantDirective_Pre (PreDefineConstantDirective *); + void visitPreDefineConstantDirective_Post (PreDefineConstantDirective *); + + void visitPreUndefDirective_Pre (PreUndefDirective *); + void visitPreUndefDirective_Post (PreUndefDirective *); + + void visitPreWarningDirective_Pre (PreWarningDirective *); + void visitPreWarningDirective_Post (PreWarningDirective *); + + void visitPreErrorDirective_Pre (PreErrorDirective *); + void visitPreErrorDirective_Post (PreErrorDirective *); + + void visitPreIdentifierList_Pre (PreIdentifierList *); + void visitPreIdentifierList_Post (PreIdentifierList *); + + void visitPreTokenList_Pre (PreTokenList *); + void visitPreTokenList_Post (PreTokenList *); + + void visitPreTokenListPart_Pre (PreTokenListPart *); + void visitPreTokenListPart_Post (PreTokenListPart *); +}; + + +} // namespace Puma + +#endif /* __pre_print_visitor__ */ diff --git a/Puma/src/cpp/PreSemIterator.h b/Puma/src/cpp/PreSemIterator.h new file mode 100644 index 0000000..a8e85a3 --- /dev/null +++ b/Puma/src/cpp/PreSemIterator.h @@ -0,0 +1,48 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __daughter_iterator__ +#define __daughter_iterator__ + +// An iterator for daughters in a syntax tree. + +#include "Puma/PreTreeIterator.h" + +namespace Puma { + + +class PreSemIterator : public PreTreeIterator { +public: + PreSemIterator (PreTree *node, bool dir = true) : + PreTreeIterator (node, dir) {}; + + ~PreSemIterator () {}; + + // Return true if iterator has all done. + bool isDone () const + { return _dir ? (_current >= _tree->daughters ()) : (_current < 0); } + + // Return current item or NULL if iterator has all done. + PreTree *currentItem () const + { return isDone () ? (PreTree*) 0 : _tree->daughter (_current); } +}; + + +} // namespace Puma + +#endif /* __daughter_iterator__ */ diff --git a/Puma/src/cpp/PreSonIterator.h b/Puma/src/cpp/PreSonIterator.h new file mode 100644 index 0000000..c7ea336 --- /dev/null +++ b/Puma/src/cpp/PreSonIterator.h @@ -0,0 +1,48 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __son_iterator__ +#define __son_iterator__ + +// An iterator for sons in a syntax tree. + +#include "Puma/PreTreeIterator.h" + +namespace Puma { + + +class PreSonIterator : public PreTreeIterator { +public: + PreSonIterator (PreTree *node, bool dir = true) : + PreTreeIterator (node, dir) {} + + ~PreSonIterator () {} + + // Return true if the iterator has all done. + bool isDone () const + { return _dir ? (_current >= _tree->sons ()) : (_current < 0); } + + // Return the current item or NULL if all is done. + PreTree *currentItem () const + { return isDone () ? (PreTree*) 0 : _tree->son (_current); } +}; + + +} // namespace Puma + +#endif /* __son_iterator__ */ diff --git a/Puma/src/cpp/PreTree.cc b/Puma/src/cpp/PreTree.cc new file mode 100644 index 0000000..df83792 --- /dev/null +++ b/Puma/src/cpp/PreTree.cc @@ -0,0 +1,83 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/PreTree.h" +#include + +namespace Puma { + + +void PreTree::add_son (PreTree*) + { + std::cerr << "internal error: Attempt to add son to none-composite syntax tree node\n"; + } + +void PreTree::replace_son (int, PreTree*) + { + std::cerr << "internal error: Attempt to replace son at none-composite syntax tree node\n"; + } + +PreTree* PreTree::son (int) const + { + std::cerr << "internal error: Attempt to get a son to none-composite syntax tree node\n"; + return (PreTree*) 0; + } + +int PreTree::sons () const + { + return 0; + } + +void PreTree::add_daughter (PreTree*) + { + std::cerr << "internal error: Attempt to add daughter to none-composite syntax tree node\n"; + } + +void PreTree::replace_daughter (int, PreTree*) + { + std::cerr << "internal error: Attempt to replace daughter at none-composite syntax tree node\n"; + } + +PreTree* PreTree::daughter (int) const + { + std::cerr << "internal error: Attempt to get a daughter to none-composite syntax tree node\n"; + return (PreTree*) 0; + } + +int PreTree::daughters () const + { + return 0; + } + +bool PreTree::isLeaf () const + { + return sons () == 0 && daughters () == 0; + } + +Token* PreTree::startToken () const + { + return (Token*) 0; + }; + +Token* PreTree::endToken () const + { + return (Token*) 0; + }; + + +} // namespace Puma diff --git a/Puma/src/cpp/PreTree.h b/Puma/src/cpp/PreTree.h new file mode 100644 index 0000000..0a207b3 --- /dev/null +++ b/Puma/src/cpp/PreTree.h @@ -0,0 +1,85 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __pre_syntax_tree__ +#define __pre_syntax_tree__ + +/** \file + * Base preprocessor syntax tree class. */ + +#include "Puma/PreVisitor.h" +#include "Puma/Token.h" + +namespace Puma { + + +/** \class PreTree PreTree.h Puma/PreTree.h + * Base class for all C preprocessor syntax tree nodes. */ +class PreTree { +protected: + /** Constructor. */ + PreTree () {}; + +public: + /** Destructor. */ + virtual ~PreTree() {} + + /** Check if the node is a leaf, i.e. it has no child nodes. */ + virtual bool isLeaf () const; + /** Part of the tree visitor pattern. Calls the node + * visiting function suitable for the actual node type. */ + virtual void accept (PreVisitor &) = 0; + + /** Add a son (syntactic child node). + * \param s The son to add. */ + virtual void add_son (PreTree *s); + /** Replace the n-th son. + * \param n The index of the son to replace. + * \param new_s The new son. */ + virtual void replace_son (int n, PreTree *new_s); + /** Get the n-th son. + * \param n The index of the son. */ + virtual PreTree *son (int n) const; + /** Get the number of sons. */ + virtual int sons () const; + + /** Add a daughter (semantic child node). + * \param d The daughter to add. */ + virtual void add_daughter (PreTree *d); + /** Replace the n-th daughter. + * \param n The index of the daughter. + * \param new_d The new daughter. */ + virtual void replace_daughter (int n, PreTree *new_d); + /** Get the n-th daughter. + * \param n The index of the daughter. */ + virtual PreTree *daughter (int n) const; + /** Get the number of daughters. */ + virtual int daughters () const; + + /** Get the first token of the syntactic construct + * represented by the sub-tree. */ + virtual Token *startToken () const; + /** Get the last token of the syntactic construct + * represented by the sub-tree. */ + virtual Token *endToken () const; +}; + + +} // namespace Puma + +#endif /* __pre_syntax_tree__ */ diff --git a/Puma/src/cpp/PreTreeComposite.cc b/Puma/src/cpp/PreTreeComposite.cc new file mode 100644 index 0000000..d8bdca6 --- /dev/null +++ b/Puma/src/cpp/PreTreeComposite.cc @@ -0,0 +1,157 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/PreTreeComposite.h" +#include + +namespace Puma { + + +PreTreeComposite::PreTreeComposite (int s, int d) + { + max_sons = s; + if (max_sons > 0) + son_array = new Array (max_sons); + else if (max_sons == DYNAMIC) + son_array = new Array (3, 3); + else + son_array = (Array *)0; + + max_daughters = d; + if (max_daughters > 0) + daughter_array = new Array (max_daughters); + else if (max_daughters == DYNAMIC) + daughter_array = new Array (3, 3); + else + daughter_array = (Array *)0; + } + +PreTreeComposite::~PreTreeComposite () + { + if (son_array) delete son_array; + if (daughter_array) delete daughter_array; + } + +void PreTreeComposite::add_son (PreTree* s) + { + if (max_sons == 0) + std::cerr << "internal error: Attempt to add a son to a node that can't have sons\n"; + else if (max_sons == DYNAMIC || son_array->length () < max_sons) + son_array->append (s); + else + std::cerr << "internal error: Attempt to add more than " << max_sons << " sons\n"; + } + +void PreTreeComposite::replace_son (int index, PreTree* s) + { + if (max_sons == 0) + std::cerr << "internal error: Attempt to replace a son of a node that can't have sons\n"; + else if (index < son_array->length ()) + (*son_array)[index] = s; + else + std::cerr << "internal error: Attempt to replace non-existant node " << index << std::endl; + } + +PreTree* PreTreeComposite::son (int index) const + { + if (max_sons == 0) + return (PreTree*)0; + else if (index < son_array->length ()) + return (*son_array)[index]; + else + return (PreTree*)0; + } + +int PreTreeComposite::sons () const + { + return max_sons == 0 ? 0 : son_array->length (); + } + +void PreTreeComposite::add_daughter (PreTree* s) + { + if (max_daughters == 0) + std::cerr << "internal error: Attempt to add a daughter to a node that can't have daughters\n"; + else if (max_daughters == DYNAMIC || daughter_array->length () < max_daughters) + daughter_array->append (s); + else + std::cerr << "internal error: Attempt to add more than " << max_daughters << " daughters\n"; + } + +void PreTreeComposite::replace_daughter (int index, PreTree* s) + { + if (max_daughters == 0) + std::cerr << "internal error: Attempt to replace a daughter of a node that can't have daughters\n"; + else if (index < daughter_array->length ()) + (*daughter_array)[index] = s; + else + std::cerr << "internal error: Attempt to replace non-existant node " << index << std::endl; + } + +PreTree* PreTreeComposite::daughter (int index) const + { + if (max_daughters == 0) + return (PreTree*)0; + else if (index < daughter_array->length ()) + return (*daughter_array)[index]; + else + return (PreTree*)0; + } + +int PreTreeComposite::daughters () const + { + return max_daughters == 0 ? 0 : daughter_array->length (); + } + +// Return the first token of current subtree +Token* PreTreeComposite::startToken () const + { + Token *tok; + PreTree *s; + unsigned num = sons (); + + for (unsigned i = 0; i < num; i++) + { + s = son (i); + tok = s ? s->startToken () : (Token*)0; + if (tok) + return tok; + } + + return (Token*)0; + } + +// Return the last token of current subtree +Token* PreTreeComposite::endToken () const + { + Token *tok; + PreTree *s; + unsigned num = sons (); + + for (unsigned i = num; i > 0; i--) + { + s = son (i-1); + tok = s ? s->endToken () : (Token*)0; + if (tok) + return tok; + } + + return (Token*)0; + } + + +} // namespace Puma diff --git a/Puma/src/cpp/PreTreeComposite.h b/Puma/src/cpp/PreTreeComposite.h new file mode 100644 index 0000000..693d51f --- /dev/null +++ b/Puma/src/cpp/PreTreeComposite.h @@ -0,0 +1,95 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __syntax_tree_composite__ +#define __syntax_tree_composite__ + +#include "Puma/PreTree.h" +#include "Puma/Array.h" +#include "Puma/PreVisitor.h" + +/** \file + * Base preprocessor syntax tree composite class. */ + +namespace Puma { + + +/** \class PreTreeComposite PreTreeComposite.h Puma/PreTreeComposite.h + * Base class for all C preprocessor syntax tree composite nodes. */ +class PreTreeComposite : public PreTree { +private: + Array *son_array; + Array *daughter_array; + int max_sons; + int max_daughters; + +protected: + /** Constructor. + * \param s Number of sons (syntactic child nodes). + * \param d Number of daughters (semantic child nodes). */ + PreTreeComposite (int s, int d); + +public: + /** Dynamic number of sons and daughters. */ + static const int DYNAMIC = -1; + + /** Destructor. */ + virtual ~PreTreeComposite (); + + /** Part of the tree visitor pattern. Calls the node + * visiting function suitable for the actual node type. */ + virtual void accept (PreVisitor &) = 0; + + /** Add a son (syntactic child node). + * \param s The son to add. */ + virtual void add_son (PreTree *s); + /** Replace the n-th son. + * \param n The index of the son to replace. + * \param new_s The new son. */ + virtual void replace_son (int n, PreTree *new_s); + /** Get the n-th son. + * \param n The index of the son. */ + virtual PreTree *son (int n) const; + /** Get the number of sons. */ + virtual int sons () const; + + /** Add a daughter (semantic child node). + * \param d The daughter to add. */ + virtual void add_daughter (PreTree *d); + /** Replace the n-th daughter. + * \param n The index of the daughter. + * \param new_d The new daughter. */ + virtual void replace_daughter (int n, PreTree *new_d); + /** Get the n-th daughter. + * \param n The index of the daughter. */ + virtual PreTree *daughter (int n) const; + /** Get the number of daughters. */ + virtual int daughters () const; + + /** Get the first token of the syntactic construct + * represented by the sub-tree. */ + virtual Token *startToken () const; + /** Get the last token of the syntactic construct + * represented by the sub-tree. */ + virtual Token *endToken () const; +}; + + +} // namespace Puma + +#endif /* __syntax_tree_composite__ */ diff --git a/Puma/src/cpp/PreTreeIterator.h b/Puma/src/cpp/PreTreeIterator.h new file mode 100644 index 0000000..7bd66fa --- /dev/null +++ b/Puma/src/cpp/PreTreeIterator.h @@ -0,0 +1,57 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __syntax_tree_iterator__ +#define __syntax_tree_iterator__ + +// Abstract base class of an iterator for syntax trees. + +#include "Puma/PreTree.h" + +namespace Puma { + + +class PreTreeIterator { +protected: + PreTree *_tree; + long _current; + bool _dir; + + PreTreeIterator (PreTree *node, bool dir = true) : + _tree (node), _current (0), _dir (dir) {} + +public: + virtual ~PreTreeIterator () {}; + + // Initialize iterator. + void first () { _current = _dir ? 0 : _tree->sons (); } + + // Go to next item. + void next () { _current = _dir ? _current + 1 : _current - 1; } + + // Return true if current item is the last item. + virtual bool isDone () const = 0; + + // Return the current item or NULL if iterator has all done. + virtual PreTree *currentItem () const = 0; +}; + + +} // namespace Puma + +#endif /* __syntax_tree_iterator__ */ diff --git a/Puma/src/cpp/PreTreeNodes.h b/Puma/src/cpp/PreTreeNodes.h new file mode 100644 index 0000000..688dbd0 --- /dev/null +++ b/Puma/src/cpp/PreTreeNodes.h @@ -0,0 +1,767 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __pre_syntax_tree_nodes__ +#define __pre_syntax_tree_nodes__ + +/** \file + * Preprocessor syntax tree classes. */ + +#include "Puma/Unit.h" +#include "Puma/PreVisitor.h" +#include "Puma/PreTreeToken.h" +#include "Puma/PreTreeComposite.h" + +namespace Puma { + + +/** \class PreProgram PreTreeNodes.h Puma/PreTreeNodes.h + * The root node of the preprocessor syntax tree. */ +class PreProgram : public PreTreeComposite { +public: + /** Constructor. + * \param g The group of preprocessor directives. */ + PreProgram (PreTree* g) : PreTreeComposite (1, 0) { + add_son (g); + } + + /** Part of the tree visitor pattern. Calls the node + * visiting functions suitable for this node type. + * \param v The visitor object on which to call the + * visiting functions. */ + void accept (PreVisitor &v) { + v.visitPreProgram_Pre (this); + v.iterateNodes (this); + v.visitPreProgram_Post (this); + } +}; + + +/** \class PreDirectiveGroups PreTreeNodes.h Puma/PreTreeNodes.h + * Preprocessor tree node representing the directive groups in the program. */ +class PreDirectiveGroups : public PreTreeComposite { +public: + /** Constructor. */ + PreDirectiveGroups () : PreTreeComposite (-1, 0) {} + + /** Part of the tree visitor pattern. Calls the node + * visiting functions suitable for this node type. + * \param v The visitor object on which to call the + * visiting functions. */ + void accept (PreVisitor& v) { + v.visitPreDirectiveGroups_Pre (this); + v.iterateNodes (this); + v.visitPreDirectiveGroups_Post (this); + } +}; + + +/** \class PreConditionalGroup PreTreeNodes.h Puma/PreTreeNodes.h + * Preprocessor tree node representing a group of conditional directives. + * Example: \code #if ... #elif ... #else ... #endif \endcode */ +class PreConditionalGroup : public PreTreeComposite { +public: + /** Constructor. + * \param i The \#if part. + * \param dg The directive group. + * \param ei The \#endif part. */ + PreConditionalGroup (PreTree* i, PreTree* dg, PreTree* ei) : PreTreeComposite (3, 0) { + add_son (i); add_son (dg); add_son (ei); + } + /** Constructor. + * \param i The \#if part. + * \param e The \#elif or \#else part. + * \param dg The directive group. + * \param ei The \#endif part. */ + PreConditionalGroup (PreTree* i, PreTree* e, PreTree* dg, PreTree* ei) : PreTreeComposite (4, 0) { + add_son (i); add_son (e); add_son (dg); add_son (ei); + } + + /** Part of the tree visitor pattern. Calls the node + * visiting functions suitable for this node type. + * \param v The visitor object on which to call the + * visiting functions. */ + void accept (PreVisitor& v) { + v.visitPreConditionalGroup_Pre (this); + v.iterateNodes (this); + v.visitPreConditionalGroup_Post (this); + } +}; + + +/** \class PreElsePart PreTreeNodes.h Puma/PreTreeNodes.h + * Preprocessor tree node representing a group of directives + * in the \#else part of an \#if conditional. */ +class PreElsePart : public PreTreeComposite { +public: + /** Constructor. + * \param dg The directive group. + * \param el The \#else directive. */ + PreElsePart (PreTree* dg, PreTree* el) : PreTreeComposite (2, 0) { + add_son (dg); add_son (el); + } + /** Constructor. + * \param ei The preceding \#elif part. + * \param dg The directive group. + * \param el The \#else directive. */ + PreElsePart (PreTree* ei, PreTree* dg, PreTree* el) : PreTreeComposite (3, 0) { + add_son (ei); add_son (dg); add_son (el); + } + + /** Part of the tree visitor pattern. Calls the node + * visiting functions suitable for this node type. + * \param v The visitor object on which to call the + * visiting functions. */ + void accept (PreVisitor& v) { + v.visitPreElsePart_Pre (this); + v.iterateNodes (this); + v.visitPreElsePart_Post (this); + } +}; + + +/** \class PreElifPart PreTreeNodes.h Puma/PreTreeNodes.h + * Preprocessor tree node representing a group of directives + * in the \#elif part of an \#if conditional. */ +class PreElifPart : public PreTreeComposite { +public: + /** Constructor. */ + PreElifPart () : PreTreeComposite (-1, 0) {} + + /** Add two sons, a directive group and a \#elif directive. + * \param dg The directive group. + * \param el The \#elif directive. */ + void addSons (PreTree* dg, PreTree* el) { + add_son (dg); add_son (el); + } + + /** Part of the tree visitor pattern. Calls the node + * visiting functions suitable for this node type. + * \param v The visitor object on which to call the + * visiting functions. */ + void accept (PreVisitor& v) { + v.visitPreElifPart_Pre (this); + v.iterateNodes (this); + v.visitPreElifPart_Post (this); + } +}; + + +/** \class PreIfDirective PreTreeNodes.h Puma/PreTreeNodes.h + * Preprocessor tree node representing an \#if directive. + * Example: \code #if OSTYPE==Linux \endcode */ +class PreIfDirective : public PreTreeComposite { +public: + /** Constructor. + * \param i The \#if token. + * \param c The condition. */ + PreIfDirective (PreTree* i, PreTree* c) : PreTreeComposite (2, 1) { + add_son (i); add_son (c); + } + + /** Part of the tree visitor pattern. Calls the node + * visiting functions suitable for this node type. + * \param v The visitor object on which to call the + * visiting functions. */ + void accept (PreVisitor& v) { + v.visitPreIfDirective_Pre (this); + v.iterateNodes (this); + v.visitPreIfDirective_Post (this); + } +}; + + +/** \class PreIfdefDirective PreTreeNodes.h Puma/PreTreeNodes.h + * Preprocessor tree node representing an \#ifdef directive. + * Example: \code #ifdef Linux \endcode */ +class PreIfdefDirective : public PreTreeComposite { +public: + /** Constructor. + * \param i The \#ifdef token. + * \param n The name of the macro. + * \param tl The remaining tokens of the line. */ + PreIfdefDirective (PreTree* i, PreTree* n, PreTree* tl) : PreTreeComposite (3, 1) { + add_son (i); add_son (n); add_son (tl); + } + /** Constructor. + * \param i The \#ifdef token. + * \param tl The remaining tokens of the line. */ + PreIfdefDirective (PreTree* i, PreTree* tl) : PreTreeComposite (2, 0) { + add_son (i); add_son (tl); + } + + /** Part of the tree visitor pattern. Calls the node + * visiting functions suitable for this node type. + * \param v The visitor object on which to call the + * visiting functions. */ + void accept (PreVisitor& v) { + v.visitPreIfdefDirective_Pre (this); + v.iterateNodes (this); + v.visitPreIfdefDirective_Post (this); + } +}; + + +/** \class PreIfndefDirective PreTreeNodes.h Puma/PreTreeNodes.h + * Preprocessor tree node representing an \#ifndef directive. + * Example: \code #ifndef Linux \endcode */ +class PreIfndefDirective : public PreTreeComposite { +public: + /** Constructor. + * \param i The \#ifndef token. + * \param n The name of the macro. + * \param tl The remaining tokens of the line. */ + PreIfndefDirective (PreTree* i, PreTree* n, PreTree* tl) : PreTreeComposite (3, 1) { + add_son (i); add_son (n); add_son (tl); + } + /** Constructor. + * \param i The \#ifndef token. + * \param tl The remaining tokens of the line. */ + PreIfndefDirective (PreTree* i, PreTree* tl) : PreTreeComposite (2, 0) { + add_son (i); add_son (tl); + } + + /** Part of the tree visitor pattern. Calls the node + * visiting functions suitable for this node type. + * \param v The visitor object on which to call the + * visiting functions. */ + void accept (PreVisitor& v) { + v.visitPreIfndefDirective_Pre (this); + v.iterateNodes (this); + v.visitPreIfndefDirective_Post (this); + } +}; + + +/** \class PreElifDirective PreTreeNodes.h Puma/PreTreeNodes.h + * Preprocessor tree node representing an \#elif directive. + * Example: \code #elif OSTYPE==linux \endcode */ +class PreElifDirective : public PreTreeComposite { +public: + /** Constructor. + * \param e The \#elif token. + * \param c The condition. */ + PreElifDirective (PreTree* e, PreTree* c) : PreTreeComposite (2, 1) { + add_son (e); add_son (c); + } + + /** Part of the tree visitor pattern. Calls the node + * visiting functions suitable for this node type. + * \param v The visitor object on which to call the + * visiting functions. */ + void accept (PreVisitor& v) { + v.visitPreElifDirective_Pre (this); + v.iterateNodes (this); + v.visitPreElifDirective_Post (this); + } +}; + + +/** \class PreElseDirective PreTreeNodes.h Puma/PreTreeNodes.h + * Preprocessor tree node representing an \#else directive. + * Example: \code #else \endcode */ +class PreElseDirective : public PreTreeComposite { +public: + /** Constructor. + * \param e The \#else token. + * \param tl The remaining tokens of the line. */ + PreElseDirective (PreTree* e, PreTree* tl) : PreTreeComposite (2, 0) { + add_son (e); add_son (tl); + } + + /** Part of the tree visitor pattern. Calls the node + * visiting functions suitable for this node type. + * \param v The visitor object on which to call the + * visiting functions. */ + void accept (PreVisitor& v) { + v.visitPreElseDirective_Pre (this); + v.iterateNodes (this); + v.visitPreElseDirective_Post (this); + } +}; + + +/** \class PreEndifDirective PreTreeNodes.h Puma/PreTreeNodes.h + * Preprocessor tree node representing an \#endif directive. + * Example: \code #endif \endcode */ +class PreEndifDirective : public PreTreeComposite { +public: + /** Constructor. + * \param e The \#endif token. + * \param tl The remaining tokens of the line. */ + PreEndifDirective (PreTree* e, PreTree* tl) : PreTreeComposite (2, 0) { + add_son (e); add_son (tl); + } + + /** Part of the tree visitor pattern. Calls the node + * visiting functions suitable for this node type. + * \param v The visitor object on which to call the + * visiting functions. */ + void accept (PreVisitor& v) { + v.visitPreEndifDirective_Pre (this); + v.iterateNodes (this); + v.visitPreEndifDirective_Post (this); + } +}; + + +/** \class PreIncludeDirective PreTreeNodes.h Puma/PreTreeNodes.h + * Preprocessor tree node representing an \#include or \#include_next directive. + * Example: \code #include \endcode */ +class PreIncludeDirective : public PreTreeComposite { + int _depth; // depth of nested includes + +public: + /** Constructor. + * \param i The \#include or \#include_next token. + * \param tl The remaining tokens of the line containing the file to include. */ + PreIncludeDirective (PreTree* i, PreTree* tl) : PreTreeComposite (2, 1) { + add_son (i); add_son (tl); + _depth = -1; + } + + /** Part of the tree visitor pattern. Calls the node + * visiting functions suitable for this node type. + * \param v The visitor object on which to call the + * visiting functions. */ + void accept (PreVisitor& v) { + v.visitPreIncludeDirective_Pre (this); + v.iterateNodes (this); + v.visitPreIncludeDirective_Post (this); + } + + /** Get the depth of nested inclusion. + * \return The depth or -1 for a top-level include. */ + int depth () const { + return _depth; + } + /** Set the depth of nested inclusion. + * \param d The depth of inclusion. */ + void depth (int d) { + _depth = d; + } + + /** Check if this is a forced include (given by command line). */ + bool is_forced () const { + return !((Unit*)startToken ()->belonging_to ())->isFile (); + } +}; + + +/** \class PreAssertDirective PreTreeNodes.h Puma/PreTreeNodes.h + * Preprocessor tree node representing an \#assert directive. + * Example: \code #assert OSTYPE (linux) \endcode */ +class PreAssertDirective : public PreTreeComposite { +public: + /** Constructor. + * \param a The \#assert token. + * \param p The predicate name. + * \param an The answer to the predicate. */ + PreAssertDirective (PreTree* a, PreTree* p, PreTree* an) : PreTreeComposite (3, 0) { + add_son (a); add_son (p); add_son (an); + } + /** Constructor. + * \param a The \#assert token. + * \param tl The remaining tokens of the line. */ + PreAssertDirective (PreTree* a, PreTree* tl) : PreTreeComposite (2, 0) { + add_son (a); add_son (tl); + } + + /** Part of the tree visitor pattern. Calls the node + * visiting functions suitable for this node type. + * \param v The visitor object on which to call the + * visiting functions. */ + void accept (PreVisitor& v) { + v.visitPreAssertDirective_Pre (this); + v.iterateNodes (this); + v.visitPreAssertDirective_Post (this); + } +}; + + +/** \class PreUnassertDirective PreTreeNodes.h Puma/PreTreeNodes.h + * Preprocessor tree node representing an \#unassert directive. + * Example: \code #unassert OSTYPE \endcode */ +class PreUnassertDirective : public PreTreeComposite { +public: + /** Constructor. + * \param ua The \#unassert token. + * \param n The name of the predicate. + * \param tl The remaining tokens of the line. */ + PreUnassertDirective (PreTree* ua, PreTree* n, PreTree* tl) : PreTreeComposite (3, 0) { + add_son (ua); add_son (n); add_son (tl); + } + /** Constructor. + * \param ua The \#unassert token. + * \param tl The remaining tokens of the line. */ + PreUnassertDirective (PreTree* ua, PreTree* tl) : PreTreeComposite (2, 0) { + add_son (ua); add_son (tl); + } + + /** Part of the tree visitor pattern. Calls the node + * visiting functions suitable for this node type. + * \param v The visitor object on which to call the + * visiting functions. */ + void accept (PreVisitor& v) { + v.visitPreUnassertDirective_Pre (this); + v.iterateNodes (this); + v.visitPreUnassertDirective_Post (this); + } +}; + + +/** \class PreDefineFunctionDirective PreTreeNodes.h Puma/PreTreeNodes.h + * Preprocessor tree node representing a \#define directive for function-like macros. + * Example: \code #define MUL(a,b) (a * b) \endcode */ +class PreDefineFunctionDirective : public PreTreeComposite { +public: + /** Constructor. + * \param a The \#define token. + * \param b The macro name. + * \param c Left parenthesis before the parameter list. + * \param d The macro parameter list. + * \param e Comma before the last parameter. + * \param f The token '...'. + * \param g Right parenthesis behind the parameter list. + * \param h The macro body. */ + PreDefineFunctionDirective (PreTree* a, PreTree* b, PreTree* c, PreTree* d, + PreTree* e, PreTree* f, PreTree* g, PreTree* h) : PreTreeComposite (8, 0) { + add_son (a); add_son (b); add_son (c); add_son (d); + add_son (e); add_son (f); add_son (g); add_son (h); + } + + /** Constructor. + * \param a The \#define token. + * \param b The macro name. + * \param c Left parenthesis before the parameter list. + * \param d The macro parameter list. + * \param e The token '...'. + * \param f Right parenthesis behind the parameter list. + * \param g The macro body. */ + PreDefineFunctionDirective (PreTree* a, PreTree* b, PreTree* c, PreTree* d, + PreTree* e, PreTree* f, PreTree* g) : PreTreeComposite (7, 0) { + add_son (a); add_son (b); add_son (c); add_son (d); + add_son (e); add_son (f); add_son (g); + } + + /** Constructor. + * \param a The \#define token. + * \param b The macro name. + * \param c Left parenthesis before the parameter list. + * \param d The macro parameter list. + * \param e Right parenthesis behind the parameter list. + * \param f The macro body. */ + PreDefineFunctionDirective (PreTree* a, PreTree* b, PreTree* c, PreTree* d, + PreTree* e, PreTree* f) : PreTreeComposite (6, 0) { + add_son (a); add_son (b); add_son (c); + add_son (d); add_son (e); add_son (f); + } + + /** Constructor. + * \param a The \#define token. + * \param b The macro name. + * \param c Left parenthesis before the parameter list. + * \param d Right parenthesis behind the parameter list. + * \param e The macro body. */ + PreDefineFunctionDirective (PreTree* a, PreTree* b, PreTree* c, + PreTree* d, PreTree* e) : PreTreeComposite (5, 0) { + add_son (a); add_son (b); add_son (c); add_son (d); add_son (e); + } + + /** Part of the tree visitor pattern. Calls the node + * visiting functions suitable for this node type. + * \param v The visitor object on which to call the + * visiting functions. */ + void accept (PreVisitor& v) { + v.visitPreDefineFunctionDirective_Pre (this); + v.iterateNodes (this); + v.visitPreDefineFunctionDirective_Post (this); + } +}; + + +/** \class PreDefineConstantDirective PreTreeNodes.h Puma/PreTreeNodes.h + * Preprocessor tree node representing a \#define directive for constants. + * Example: \code #define CONSTANT 1 \endcode */ +class PreDefineConstantDirective : public PreTreeComposite { +public: + /** Constructor. + * \param d The \#define token. + * \param n The name of the constant. + * \param v The constant value. */ + PreDefineConstantDirective (PreTree* d, PreTree* n, PreTree* v) : PreTreeComposite (3, 0) { + add_son (d); add_son (n); add_son (v); + } + /** Constructor. + * \param d The \#define token. + * \param tl The remaining tokens of the line. */ + PreDefineConstantDirective (PreTree* d, PreTree* tl) : PreTreeComposite (2, 0) { + add_son (d); add_son (tl); + } + + /** Part of the tree visitor pattern. Calls the node + * visiting functions suitable for this node type. + * \param v The visitor object on which to call the + * visiting functions. */ + void accept (PreVisitor& v) { + v.visitPreDefineConstantDirective_Pre (this); + v.iterateNodes (this); + v.visitPreDefineConstantDirective_Post (this); + } +}; + + +/** \class PreUndefDirective PreTreeNodes.h Puma/PreTreeNodes.h + * Preprocessor tree node representing an \#undef directive. + * Example: \code #undef MACRO \endcode */ +class PreUndefDirective : public PreTreeComposite { +public: + /** Constructor. + * \param u The \#undef token. + * \param m The name of the macro to undefine. + * \param tl The remaining tokens of the line. */ + PreUndefDirective (PreTree* u, PreTree* m, PreTree* tl) : PreTreeComposite (3, 0) { + add_son (u); add_son (m); add_son (tl); + } + /** Constructor. + * \param u The \#undef token. + * \param tl The remaining tokens of the line. */ + PreUndefDirective (PreTree* u, PreTree* tl) : PreTreeComposite (2, 0) { + add_son (u); add_son (tl); + } + + /** Part of the tree visitor pattern. Calls the node + * visiting functions suitable for this node type. + * \param v The visitor object on which to call the + * visiting functions. */ + void accept (PreVisitor& v) { + v.visitPreUndefDirective_Pre (this); + v.iterateNodes (this); + v.visitPreUndefDirective_Post (this); + } +}; + + +/** \class PreWarningDirective PreTreeNodes.h Puma/PreTreeNodes.h + * Preprocessor tree node representing a \#warning directive. + * Example: \code #warning This is a warning. \endcode */ +class PreWarningDirective : public PreTreeComposite { +public: + /** Constructor. + * \param w The \#warning token. + * \param m The warning message. */ + PreWarningDirective (PreTree* w, PreTree* m) : PreTreeComposite (2, 0) { + add_son (w); add_son (m); + } + + /** Part of the tree visitor pattern. Calls the node + * visiting functions suitable for this node type. + * \param v The visitor object on which to call the + * visiting functions. */ + void accept (PreVisitor& v) { + v.visitPreWarningDirective_Pre (this); + v.iterateNodes (this); + v.visitPreWarningDirective_Post (this); + } +}; + + +/** \class PreErrorDirective PreTreeNodes.h Puma/PreTreeNodes.h + * Preprocessor tree node representing an \#error directive. + * Example: \code #error This is an error. \endcode */ +class PreErrorDirective : public PreTreeComposite { +public: + /** Constructor. + * \param e The \#error token. + * \param m The error message. */ + PreErrorDirective (PreTree* e, PreTree* m) : PreTreeComposite (2, 0) { + add_son (e); add_son (m); + } + + /** Part of the tree visitor pattern. Calls the node + * visiting functions suitable for this node type. + * \param v The visitor object on which to call the + * visiting functions. */ + void accept (PreVisitor& v) { + v.visitPreErrorDirective_Pre (this); + v.iterateNodes (this); + v.visitPreErrorDirective_Post (this); + } +}; + + +/** \class PreIdentifierList PreTreeNodes.h Puma/PreTreeNodes.h + * Preprocessor tree node representing the identifier list of a + * function-like macro definition. + * Example: \code a,b,c \endcode */ +class PreIdentifierList : public PreTreeComposite { +public: + /** Constructor. + * \param id An identifier. */ + PreIdentifierList (PreTree* id) : PreTreeComposite (-1, 0) { + add_son (id); + } + + /** Add two sons, a comma and an identifier. + * \param c A comma. + * \param id An identifier. */ + void addSons (PreTree* c, PreTree* id) { + add_son (c); add_son (id); + } + + /** Part of the tree visitor pattern. Calls the node + * visiting functions suitable for this node type. + * \param v The visitor object on which to call the + * visiting functions. */ + void accept (PreVisitor& v) { + v.visitPreIdentifierList_Pre (this); + v.iterateNodes (this); + v.visitPreIdentifierList_Post (this); + } +}; + + +/** \class PreTokenList PreTreeNodes.h Puma/PreTreeNodes.h + * Preprocessor tree node representing the token list of a macro body. */ +class PreTokenList : public PreTreeComposite { +public: + /** Constructor. */ + PreTokenList () : PreTreeComposite (0, 0) {} + /** Constructor. + * \param tl The token list. + * \param nl The newline token. */ + PreTokenList (PreTree* tl, PreTree* nl) : PreTreeComposite (2, 0) { + add_son (tl); add_son (nl); + } + /** Constructor. + * \param tl The token list. */ + PreTokenList (PreTree* tl) : PreTreeComposite (1, 0) { + add_son (tl); + } + + /** Part of the tree visitor pattern. Calls the node + * visiting functions suitable for this node type. + * \param v The visitor object on which to call the + * visiting functions. */ + void accept (PreVisitor& v) { + v.visitPreTokenList_Pre (this); + v.iterateNodes (this); + v.visitPreTokenList_Post (this); + } +}; + + +/** \class PreTokenListPart PreTreeNodes.h Puma/PreTreeNodes.h + * Preprocessor tree node representing a part of the token list of a macro body. */ +class PreTokenListPart : public PreTreeComposite { +public: + /** Constructor. + * \param tl The token list. */ + PreTokenListPart (PreTree* tl) : PreTreeComposite (-1, 0) { + add_son (tl); + } + + /** Part of the tree visitor pattern. Calls the node + * visiting functions suitable for this node type. + * \param v The visitor object on which to call the + * visiting functions. */ + void accept (PreVisitor& v) { + v.visitPreTokenListPart_Pre (this); + v.iterateNodes (this); + v.visitPreTokenListPart_Post (this); + } +}; + + +/** \class PreCondSemNode PreTreeNodes.h Puma/PreTreeNodes.h + * Preprocessor semantic tree node for conditions. */ +class PreCondSemNode : public PreTree { + // The calculated value of the condition. + bool _value; + +public: + /** Constructor. + * \param value The calculated value of the condition. */ + PreCondSemNode (bool value) : _value (value) {} + + /** Part of the tree visitor pattern. Calls the node + * visiting functions suitable for this node type. + * \param v The visitor object on which to call the + * visiting functions. */ + void accept (PreVisitor& v) { + v.visitPreCondSemNode (this); + } + + /** Get the calculated value of the condition. */ + bool value () const { return _value; } +}; + + +/** \class PreInclSemNode PreTreeNodes.h Puma/PreTreeNodes.h + * Preprocessor semantic tree node for the \#include directive + * containing the unit to include. */ +class PreInclSemNode : public PreTree { + // Pointer to the included file unit. + Unit* _unit; + + // True if the inclusion was not done, because of an active include guard. + bool _guarded; + +public: + /** Constructor. + * \param unit The unit containing the tokens of the include file. + * \param guarded True if the inclusion was not done due to an include guard. */ + PreInclSemNode (Unit* unit, bool guarded) : + _unit (unit), _guarded (guarded) {} + + /** Part of the tree visitor pattern. Calls the node + * visiting functions suitable for this node type. + * \param v The visitor object on which to call the + * visiting functions. */ + void accept (PreVisitor& v) { + v.visitPreInclSemNode (this); + } + + /** Get the token unit of the included file. */ + Unit* unit () const { return _unit; } + + /** Check if the inclusion was not done due to an include guard. */ + bool guarded () const { return _guarded; } +}; + + +/** \class PreError PreTreeNodes.h Puma/PreTreeNodes.h + * Preprocessor tree node representing a parse error. */ +class PreError : public PreTree { +public: + /** Constructor. */ + PreError () {} + + /** Part of the tree visitor pattern. Calls the node + * visiting functions suitable for this node type. + * \param v The visitor object on which to call the + * visiting functions. */ + void accept (PreVisitor& v) { + v.visitPreError (this); + } +}; + + +} // namespace Puma + +#endif /* __pre_syntax_tree_nodes__ */ diff --git a/Puma/src/cpp/PreTreeToken.h b/Puma/src/cpp/PreTreeToken.h new file mode 100644 index 0000000..3b65053 --- /dev/null +++ b/Puma/src/cpp/PreTreeToken.h @@ -0,0 +1,63 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __syntax_tree_token__ +#define __syntax_tree_token__ + +// Class PreTreeToken makes it possible to let tokens be +// a part of a syntax tree. + +#include "Puma/PreTree.h" +#include "Puma/Token.h" + +/** \file + * Preprocessor syntax tree leaf class (representing a token). */ + +namespace Puma { + + +/** \class PreTreeToken PreTreeToken.h Puma/PreTreeToken.h + * Preprocessor syntax tree leaf class representing a token. */ +class PreTreeToken : public PreTree { + Token *_token; + +public: + /** Constructor. + * \param token The preprocessor token. */ + PreTreeToken (Token *token) : _token (token) {} + + /** Part of the tree visitor pattern. Calls the node + * visiting function for PreTreeToken nodes. */ + void accept (PreVisitor &v) + { v.visitPreTreeToken (this); } + + /** Get the first token of the syntactic construct + * represented by the sub-tree. */ + Token *startToken () const { return _token; } + /** Get the last token of the syntactic construct + * represented by the sub-tree. */ + Token *endToken () const { return _token; } + + /** Get the token represented by this node. */ + Token *token () const { return _token; } +}; + + +} // namespace Puma + +#endif /*__syntax_tree_token__ */ diff --git a/Puma/src/cpp/PreVisitor.h b/Puma/src/cpp/PreVisitor.h new file mode 100644 index 0000000..e41496e --- /dev/null +++ b/Puma/src/cpp/PreVisitor.h @@ -0,0 +1,143 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __pre_visitor_h__ +#define __pre_visitor_h__ + +// Visitor for the preprocessor syntax tree. + +namespace Puma { + + +class PreTree; +class PreTreeToken; +class PreCondSemNode; +class PreInclSemNode; +class PreError; +class PreProgram; +class PreDirectiveGroups; +class PreConditionalGroup; +class PreElsePart; +class PreElifPart; +class PreIfDirective; +class PreIfdefDirective; +class PreIfndefDirective; +class PreElifDirective; +class PreElseDirective; +class PreEndifDirective; +class PreIncludeDirective; +class PreAssertDirective; +class PreUnassertDirective; +class PreDefineFunctionDirective; +class PreDefineConstantDirective; +class PreUndefDirective; +class PreWarningDirective; +class PreErrorDirective; +class PreIdentifierList; +class PreTokenList; +class PreTokenListPart; +class PreForcedInclude; + + +class PreVisitor { +protected: + PreVisitor () {}; + virtual ~PreVisitor () {} + +public: + virtual void iterateNodes (PreTree *) {}; + +public: + virtual void visitPreTreeToken (PreTreeToken *) {}; + + virtual void visitPreError (PreError *) {}; + + virtual void visitPreCondSemNode (PreCondSemNode *) {}; + virtual void visitPreInclSemNode (PreInclSemNode *) {}; + + virtual void visitPreProgram_Pre (PreProgram *) {}; + virtual void visitPreProgram_Post (PreProgram *) {}; + + virtual void visitPreDirectiveGroups_Pre (PreDirectiveGroups *) {}; + virtual void visitPreDirectiveGroups_Post (PreDirectiveGroups *) {}; + + virtual void visitPreConditionalGroup_Pre (PreConditionalGroup *) {}; + virtual void visitPreConditionalGroup_Post (PreConditionalGroup *) {}; + + virtual void visitPreElsePart_Pre (PreElsePart *) {}; + virtual void visitPreElsePart_Post (PreElsePart *) {}; + + virtual void visitPreElifPart_Pre (PreElifPart *) {}; + virtual void visitPreElifPart_Post (PreElifPart *) {}; + + virtual void visitPreIfDirective_Pre (PreIfDirective *) {}; + virtual void visitPreIfDirective_Post (PreIfDirective *) {}; + + virtual void visitPreIfdefDirective_Pre (PreIfdefDirective *) {}; + virtual void visitPreIfdefDirective_Post (PreIfdefDirective *) {}; + + virtual void visitPreIfndefDirective_Pre (PreIfndefDirective *) {}; + virtual void visitPreIfndefDirective_Post (PreIfndefDirective *) {}; + + virtual void visitPreElifDirective_Pre (PreElifDirective *) {}; + virtual void visitPreElifDirective_Post (PreElifDirective *) {}; + + virtual void visitPreElseDirective_Pre (PreElseDirective *) {}; + virtual void visitPreElseDirective_Post (PreElseDirective *) {}; + + virtual void visitPreEndifDirective_Pre (PreEndifDirective *) {}; + virtual void visitPreEndifDirective_Post (PreEndifDirective *) {}; + + virtual void visitPreIncludeDirective_Pre (PreIncludeDirective *) {}; + virtual void visitPreIncludeDirective_Post (PreIncludeDirective *) {}; + + virtual void visitPreAssertDirective_Pre (PreAssertDirective *) {}; + virtual void visitPreAssertDirective_Post (PreAssertDirective *) {}; + + virtual void visitPreUnassertDirective_Pre (PreUnassertDirective *) {}; + virtual void visitPreUnassertDirective_Post (PreUnassertDirective *) {}; + + virtual void visitPreDefineFunctionDirective_Pre (PreDefineFunctionDirective *) {}; + virtual void visitPreDefineFunctionDirective_Post (PreDefineFunctionDirective *) {}; + + virtual void visitPreDefineConstantDirective_Pre (PreDefineConstantDirective *) {}; + virtual void visitPreDefineConstantDirective_Post (PreDefineConstantDirective *) {}; + + virtual void visitPreUndefDirective_Pre (PreUndefDirective *) {}; + virtual void visitPreUndefDirective_Post (PreUndefDirective *) {}; + + virtual void visitPreWarningDirective_Pre (PreWarningDirective *) {}; + virtual void visitPreWarningDirective_Post (PreWarningDirective *) {}; + + virtual void visitPreErrorDirective_Pre (PreErrorDirective *) {}; + virtual void visitPreErrorDirective_Post (PreErrorDirective *) {}; + + virtual void visitPreIdentifierList_Pre (PreIdentifierList *) {}; + virtual void visitPreIdentifierList_Post (PreIdentifierList *) {}; + + virtual void visitPreTokenList_Pre (PreTokenList *) {}; + virtual void visitPreTokenList_Post (PreTokenList *) {}; + + virtual void visitPreTokenListPart_Pre (PreTokenListPart *) {}; + virtual void visitPreTokenListPart_Post (PreTokenListPart *) {}; +}; + + +} // namespace Puma + +#endif /* __pre_visitor_h__ */ diff --git a/Puma/src/cpp/PreprocessorParser.cc b/Puma/src/cpp/PreprocessorParser.cc new file mode 100644 index 0000000..c3109be --- /dev/null +++ b/Puma/src/cpp/PreprocessorParser.cc @@ -0,0 +1,306 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/Token.h" +#include "Puma/CTokens.h" +#include "Puma/CCommentTokens.h" +#include "Puma/PreMacro.h" +#include "Puma/PreAnswer.h" +#include "Puma/PreTree.h" +#include "Puma/ErrorStream.h" +#include "Puma/UnitManager.h" +#include "Puma/PrePredicate.h" +#include "Puma/PreTreeNodes.h" +#include "Puma/PreLevelState.h" +#include "Puma/PreParserState.h" +#include "Puma/PreMacroManager.h" +#include "Puma/PreFileIncluder.h" +#include "Puma/PreprocessorParser.h" +#include "Puma/PrePredicateManager.h" + +#include +#include +#include + + +namespace Puma { + + +// Get the next token to parse. +Token *PreprocessorParser::next () { + return parseToken (); +} + + +// Free the preprocessor syntax tree. +void PreprocessorParser::freeSyntaxTree (PreTree *node) { + int i; + + if (! node) return; + + for (i = 0; i < node->sons (); i++) + freeSyntaxTree (node->son (i)); + + for (i = 0; i < node->daughters (); i++) + delete node->daughter (i); + + delete node; +} + + +// Free the preprocessor syntax tree. +void PreprocessorParser::freeSyntaxTree () { + freeSyntaxTree (_parserState->syntaxTree); + _parserState->syntaxTree = (PreTree*)0; +} + + +// Invoke the parse process. +void PreprocessorParser::parse () { + // Do not parse more than one time. + if (_parserState->syntaxTree) + return; + + Token *token, *last = 0; + + // Print the result of the parse process if not in silent mode. + while ((token = parseToken ())) + if (! _silentMode) { + if (last && + ((last->type () == TOK_CCOMMENT && + token->type () != TOK_CCOMMENT) || + (last->location ().filename ().name () != + token->location ().filename ().name ()))) + *_out << "\n"; + + last = token; + *_out << token->text () << std::flush; + } +} + + +// Configure the preprocessor. +void PreprocessorParser::configure (const Config &c, bool process_includes) { + _scanner.configure (c); + + unsigned num = c.Options (); + for (unsigned i = 0; i < num; i++) { + const ConfOption *o = c.Option (i); + if (!strcmp (o->Name (), "--gnu") || !strcmp (o->Name (), "--gnu-2.95")) { + supportGNU (true); + } else if (! strcmp (o->Name (), "--lang-c")) { + undefMacro ("__cplusplus"); + } else if (! strcmp (o->Name (), "-D")) { + if (o->Arguments () < 1) continue; + undefMacro (o->Argument (0)); + if (o->Arguments () == 2) + defMacro (o->Argument (0), o->Argument (1)); + else + defMacro (o->Argument (0)); + } else if (! strcmp (o->Name (), "-U")) { + if (o->Arguments () != 1) continue; + undefMacro (o->Argument (0)); + } else if (! strcmp (o->Name (), "-I")) { + if (o->Arguments () != 1) continue; + addInclPath (o->Argument (0)); + } else if (! strcmp (o->Name (), "--isystem")) { + if (o->Arguments () != 1) continue; + addSysInclPath (o->Argument (0)); + } else if (! strcmp (o->Name (), "-A")) { + if (o->Arguments () != 2) continue; + defPredicate (o->Argument (0), o->Argument (1)); + } else if (! strcmp (o->Name (), "--lock-macro")) { + if (o->Arguments () < 1) continue; + undefMacro (o->Argument (0)); + if (o->Arguments () == 2) + defMacro (o->Argument (0), o->Argument (1), PreMacro::LOCK_MACRO); + else + defMacro (o->Argument (0), 0, PreMacro::LOCK_MACRO); + } else if (! strcmp (o->Name (), "--inhibit-macro")) { + if (o->Arguments () != 1) continue; + defMacro (o->Argument (0), 0, PreMacro::INHIBIT_MACRO); + } + } + + // C99 _Pragma operator, same as #pragma + PreMacro *pragma_macro = _macroManager->getMacro ("_Pragma"); + if (! (pragma_macro && pragma_macro->numArgs () == 1)) + defMacro ("_Pragma(x)", " ", PreMacro::LOCK_MACRO); + + if (process_includes) { + CUnit *forced_includes = new CUnit (*parserState ()->err); + forced_includes->name (""); + _locals->add (forced_includes); + for (unsigned i = 0; i < num; i++) { + const ConfOption *o = c.Option (i); + if (! strcmp (o->Name (), "--include")) { + if (o->Arguments () != 1) continue; + const char *filename = o->Argument (0); + *forced_includes << "#include "; + if (filename[0] == '\"' || filename[0] == '<') + *forced_includes << filename; + else + *forced_includes << "\"" << filename << "\""; + *forced_includes << std::endl; + //Unit *unit = fileIncluder ()->handleIncludeOption (o->Argument (0)); + } + } + *forced_includes << endu; + fileIncluder ()->pushOnStack (forced_includes); + } +} + + +// Check if macro name has format "name(args)". +bool PreprocessorParser::hasArguments(const char *name) const { + int len = strlen(name); + return len != 0 && name[len-1] == ')'; +} + + +// Extract the name of macro given as "name(args)". +std::string PreprocessorParser::getMacroName(const char *nameAndArgs) const { + std::string name = nameAndArgs; + return name.substr(0, name.find('(')); +} + + +// Extract the arguments of macro given as "name(args)". +void PreprocessorParser::getMacroArgs(const char *nameAndArgs, std::list& args) const { + std::string work = nameAndArgs; + std::string::size_type arg_pos = work.find('('); + if (arg_pos != std::string::npos) { + // check if there are characters in front of '(' + if (arg_pos == 0) + return; // syntax error + + std::string::size_type pos = arg_pos+1; // skip opening brace, begin of the argument list + while ((arg_pos = work.find_first_of(",)", pos)) != std::string::npos) { + std::string arg = work.substr(pos, arg_pos-pos); + if (arg[0] == ' ' || arg[arg.length()-1] == ' ') + return; // syntax error + + args.push_back(arg); + pos = arg_pos+1; // skip comma or closing brace + } + } +} + + +// Define a new macro. +void PreprocessorParser::defMacro (const char *name, const char *body, char flags) const { + if (! name) + return; + + // empty macro body defaults to integer 1 + if (! body) + body = "1"; + + if (! hasArguments(name)) { + _macroManager->addMacro(new PreMacro(name, body, flags)); + } + else { + // "name(args)" format given, extract name and arguments first + std::string macro_name = getMacroName(name); + std::list args; getMacroArgs(name, args); + PreMacro *macro = new PreMacro(macro_name.c_str(), body, flags); + for (std::list::iterator i = args.begin(); i != args.end(); ++i) + macro->addArg(*i); + _macroManager->addMacro(macro); + } +} + + +// Undefine a macro. +void PreprocessorParser::undefMacro(const char *name) const { + if (! name) + return; + + if (! hasArguments(name)) { + _parserState->removeMacroFromStack(*_macroStack, name); + _macroManager->removeMacro(name); + } + else { + // "name(args)" format given, extract name first + std::string macro_name = getMacroName(name); + _parserState->removeMacroFromStack(*_macroStack, macro_name.c_str()); + _macroManager->removeMacro(macro_name.c_str()); + } +} + + +// Define a new predicate. +void PreprocessorParser::defPredicate (const char *name, const char *answer) const { + if (! name || ! answer) + return; + + PrePredicate *predicate; + + if ((predicate = _predicateManager->getPredicate (name))) + predicate->addAnswer (answer); + else { + predicate = new PrePredicate (name, answer); + _predicateManager->addPredicate (predicate); + } +} + + +// Undefine a predicate. +void PreprocessorParser::undefPredicate (const char *name) const { + _predicateManager->removePredicate (name); +} + + +// Return the preprocessor syntax tree. +PreTree *PreprocessorParser::syntaxTree () const { + return _parserState->syntaxTree; +} + + +// Add a new non-system include path. +void PreprocessorParser::addInclPath (const char *path) const { + _fileIncluder->addIncludePath (path); +} + + +// Add a new system include path. +void PreprocessorParser::addSysInclPath (const char *path) const { + _fileIncluder->addSystemIncludePath (path); +} + + +void PreprocessorParser::supportGNU (bool v) { + _support_gnu = v; + if (_support_gnu) { + defineGNUMacros (); + } +} + + +void PreprocessorParser::defUndefinedMacro (const char *name, const char *body, char flags) const { + if (! _macroManager->getMacro (name)) + defMacro (name, body, flags); +} + + +void PreprocessorParser::defineGNUMacros () { + // GNU aspect may add more +} + + +} // namespace Puma diff --git a/Puma/src/cpp/PreprocessorParser.h b/Puma/src/cpp/PreprocessorParser.h new file mode 100644 index 0000000..72a6898 --- /dev/null +++ b/Puma/src/cpp/PreprocessorParser.h @@ -0,0 +1,212 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __preprocessor_parser__ +#define __preprocessor_parser__ + +// Preprocessor parser class. !!! The preprocessor parser has to +// be added last to the composite parser of a translation unit !!! + +/** \page preprocessing Preprocessing + */ + +#include "Puma/Stack.h" +#include "Puma/Config.h" +#include "Puma/CScanner.h" +#include "Puma/CUnit.h" +#include "Puma/TokenSource.h" +#include "Puma/PreMacroExpander.h" +#include +#include +#include +#include + +namespace Puma { + + +class PreTree; +class ErrorStream; +class UnitManager; +class PrePredicate; +class PreLevelState; +class PreParserState; +class PreMacroManager; +class PreFileIncluder; +class PrePredicateManager; + +class PreprocessorParser : public TokenSource { +public: + // The current mode for token preprocessing + typedef enum { + INITIAL, + DEFINING, + MAYBEMACRO, + ASSERT, + TOKENLIST, + DIRECTIVE, + MACRO + } PreMode; + +private: + // Do not print the result of the parse process. + bool _silentMode; + + // If the preprocessor parser is the last in chain, + // the result of the parse process will be putted on + // the given stream. + std::ostream *_out; + + // Stack for the macro expansion. + Array *_macroStack; + + PreLevelState *_levelState; + PreParserState *_parserState; + PreMacroManager *_macroManager; + PreFileIncluder *_fileIncluder; + PrePredicateManager *_predicateManager; + UnitManager *_unitManager; + UnitManager *_locals; + + PreMacroExpander _expander; + PreMacroExpander _macroExpander; + + PreMode _pre_mode; + bool _support_gnu; + + CScanner _scanner; + TokenStream *_stream; + + const char *_importHandler; + +private: + // Parse a single token. + Token* parseToken (); + + // Free the preprocessor syntax tree. + void freeSyntaxTree (PreTree*); + + // Define GNU macros + void defineGNUMacros (); + + // Get and parse the next token. + void parseNextToken (Token*& sl_comment, Unit*& comment_unit, bool& last_in_expansion); + + // Check if the current token is a macro call + bool isMacroCall (bool specialDefinedMacro); + + // Collect the tokens of the macro call for expansion. + bool collectMacroCallTokens (PreMacro* macro); + + // Expand a macro call. + bool expandMacroCall (PreMacroExpander& expander); + + // Parse a generated single line comment. + bool parseGeneratedSingleLineCommentToken (Token*& sl_comment, Unit*& comment_unit, bool& last_in_expansion); + + // Finish the parse process. + void finishParsing (); + + // Check if macro name has format "name(args)". + bool hasArguments(const char *name) const; + + // Extract the name of macro given as "name(args)". + std::string getMacroName(const char *nameAndArgs) const; + + // Extract the arguments of macro given as "name(args)". + void getMacroArgs(const char *nameAndArgs, std::list& args) const; + +public: + // Get several preprocessor informations. + Array *macroStack () const { return _macroStack; } + PreLevelState *levelState () const { return _levelState; } + PreParserState *parserState () const { return _parserState; } + PreMacroManager *macroManager () const { return _macroManager; } + PreFileIncluder *fileIncluder () const { return _fileIncluder; } + PrePredicateManager *predicateManager () const { return _predicateManager; } + UnitManager *unitManager () const { return _unitManager; } + UnitManager *locals () const { return _locals; } + PreMode pre_mode () const { return _pre_mode; } + bool supportGNU () const { return _support_gnu; } + CScanner &cscanner () const { return (CScanner&) _scanner; } + const char *importHandler () const { return _importHandler; } + void macroManager (PreMacroManager *m) { _macroManager = m; } + void fileIncluder (PreFileIncluder *f) { _fileIncluder = f; } + void predicateManager (PrePredicateManager *p) { _predicateManager = p; } + + // Return the preprocessor syntax tree. + PreTree *syntaxTree () const; + +public: + PreprocessorParser (ErrorStream *, UnitManager *, UnitManager *, + std::ostream &out = std::cout, int max_depth = 400); + + ~PreprocessorParser (); + + // Reset the preprocessor parser. + void reset (ErrorStream *, UnitManager *, UnitManager *, + std::ostream &out = std::cout, int max_depth = 400); + + // Free the preprocessor syntax tree. + void freeSyntaxTree (); + + // Configure the preprocessor. + void configure (const Config &, bool = true); + + // Get the next token to parse. + Token *next (); + + TokenStream *scanner () const { return _stream; } + void stream (TokenStream *s) { _stream = s; } + + // Map scanner token types to parser token types + int map_token (Token *token, bool &parse); + + // Invoke the parse process. + void parse (); + + // Switch to silent mode. + void silentMode (bool mode = true) { _silentMode = mode; } + + // Define a new macro. + void defMacro (const char *, const char * = (const char*)0, char = 0) const; + + // Define a macro if it is not yet defined. + void defUndefinedMacro (const char *, const char * = (const char*)0, char = 0) const; + + // Undefine a macro. + void undefMacro (const char *) const; + + // Define a new predicate. + void defPredicate (const char *, const char *) const; + + // Undefine a predicate. + void undefPredicate (const char *) const; + + // Add a new non-system include path. + void addInclPath (const char *) const; + + // Add a new system include path. + void addSysInclPath (const char *) const; + + void supportGNU (bool); +}; + + +} // namespace Puma + +#endif /* __preprocessor_parser__ */ diff --git a/Puma/src/generate.mk b/Puma/src/generate.mk new file mode 100644 index 0000000..1275405 --- /dev/null +++ b/Puma/src/generate.mk @@ -0,0 +1,40 @@ +ifeq ($(MAKELEVEL),0) +$(error Sorry, this makefile is not intended to be \ +used directly. Please use the makefile in the toplevel \ +directory of the PUMA source tree instead) +endif + +#------------------------------------------------- +# variables +#------------------------------------------------- + +LEMOBJECTS := $(addprefix $(STEP1)/src/, \ + $(patsubst %.lem,%.cc, $(notdir $(LEMSOURCES)))) +SRCTOCOPY := $(SOURCES) + +FINDINCS = $(wildcard $(dir)*.h) $(wildcard $(dir)*.inc) +SRCDIRS = $(sort $(dir $(SOURCES))) +INCTOCOPY = $(foreach dir,$(SRCDIRS),$(FINDINCS)) $(LEMOBJECTS:.cc=.h) + +#------------------------------------------------- +# rules +#------------------------------------------------- + +vpath %.lem $(dir $(LEMSOURCES)) + +all: $(LEMOBJECTS) + @cp -p $(INCTOCOPY) $(STEP1)/inc/Puma/ + @cp -p $(SRCTOCOPY) $(STEP1)/src +ifneq ($(ASPECTS),) + @cp -p $(ASPECTS) $(STEP1)/aspects/Puma/ +endif + +#------------------------------------------------- +# targets +#------------------------------------------------- + +$(STEP1)/src/%.cc : %.lem + @echo "Generating parser from $<..." + @$(ROOT)/tools/lemon/lemon -q $< $(STEP1)/src/; true + +.PHONY: all diff --git a/Puma/src/infos/CArgumentInfo.cc b/Puma/src/infos/CArgumentInfo.cc new file mode 100644 index 0000000..a628b5a --- /dev/null +++ b/Puma/src/infos/CArgumentInfo.cc @@ -0,0 +1,30 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CArgumentInfo.h" +#include "Puma/CFunctionInfo.h" +#include "Puma/CTree.h" + +namespace Puma { + + +CArgumentInfo::~CArgumentInfo () { +} + + +} // namespace Puma diff --git a/Puma/src/infos/CArgumentInfo.h b/Puma/src/infos/CArgumentInfo.h new file mode 100644 index 0000000..5517bdc --- /dev/null +++ b/Puma/src/infos/CArgumentInfo.h @@ -0,0 +1,61 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CArgumentInfo_h__ +#define __CArgumentInfo_h__ + +/** \file + * Semantic information about a function parameter. */ + +#include "Puma/CScopeRequest.h" + +namespace Puma { + + +/** \class CArgumentInfo CArgumentInfo.h Puma/CArgumentInfo.h + * Semantic information about a function parameter. */ +class CArgumentInfo : public CScopeRequest { + bool _hasDefaultArg; // can be set to true even without an init tree + // (needed for inline member functions) +public: + /** Constructor. */ + CArgumentInfo (); + /** Destructor. If the object type is CObjectInfo::ARGUMENT_INFO, + * then CObjectInfo::CleanUp() is called. */ + ~CArgumentInfo (); + + /** Return \e true if the parameter has a default argument. */ + bool hasDefaultArg () const; + /** Set whether the parameter has a default argument. + * \param v True for yes, false for no. */ + void hasDefaultArg (bool v); +}; + +inline CArgumentInfo::CArgumentInfo () : + CScopeRequest (CObjectInfo::ARGUMENT_INFO), _hasDefaultArg (false) + {} + +inline bool CArgumentInfo::hasDefaultArg () const + { return (_hasDefaultArg || Init ()); } + +inline void CArgumentInfo::hasDefaultArg (bool has_arg) + { _hasDefaultArg = has_arg; } + +} // namespace Puma + +#endif /* __CArgumentInfo_h__ */ diff --git a/Puma/src/infos/CAttributeInfo.cc b/Puma/src/infos/CAttributeInfo.cc new file mode 100644 index 0000000..910d181 --- /dev/null +++ b/Puma/src/infos/CAttributeInfo.cc @@ -0,0 +1,66 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CAttributeInfo.h" +#include "Puma/CTemplateInfo.h" +#include "Puma/CStructure.h" +#include "Puma/CTree.h" + +namespace Puma { + + +CAttributeInfo::~CAttributeInfo () { +} + +CAttributeInfo *CAttributeInfo::DefObject () const { + CAttributeInfo *ainfo = (CAttributeInfo*)this; + do { + if (ainfo->Init ()) + return ainfo; + ainfo = ainfo->NextObject ()->AttributeInfo (); + } while (ainfo != (CAttributeInfo*)this); + return (CAttributeInfo*)this; +} + +CT_InitDeclarator *CAttributeInfo::Tree () const { + return (CT_InitDeclarator*)CObjectInfo::Tree (); +} + +CTree *CAttributeInfo::Init () { + if (! _Init && CObjectInfo::Tree ()) { + CTree* tree = CObjectInfo::Tree (); + CT_ExprList* el = 0; + if (tree->NodeName () == CT_InitDeclarator::NodeId ()) + el = ((CT_InitDeclarator*)tree)->Initializer (); + else if (tree->NodeName () == CT_Enumerator::NodeId ()) + el = ((CT_Enumerator*)tree)->Initializer (); + _Init = el && el->Entries () > 0 ? el->Entry (0) : 0; + } + return _Init; +} + +CRecord *CAttributeInfo::Record () const { + return CObjectInfo::QualifiedScope () ? CObjectInfo::QualifiedScope ()->Record () : (CRecord*)0; +} + +CNamespaceInfo *CAttributeInfo::Namespace () const { + return CObjectInfo::QualifiedScope () ? CObjectInfo::QualifiedScope ()->NamespaceInfo () : (CNamespaceInfo*)0; +} + + +} // namespace Puma diff --git a/Puma/src/infos/CAttributeInfo.h b/Puma/src/infos/CAttributeInfo.h new file mode 100644 index 0000000..4380982 --- /dev/null +++ b/Puma/src/infos/CAttributeInfo.h @@ -0,0 +1,112 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CAttributeInfo_h__ +#define __CAttributeInfo_h__ + +/** \file + * Semantic information about local/global objects and class data members. */ + +#include "Puma/CScopeRequest.h" + +namespace Puma { + + +class CT_InitDeclarator; +class CT_ExprList; +class CTemplateInfo; +class CRecord; +class CNamespaceInfo; +class CTree; + +/** \class CAttributeInfo CAttributeInfo.h Puma/CAttributeInfo.h + * Semantic information about a local or global object or a + * class data member. */ +class CAttributeInfo : public CScopeRequest { + CTemplateInfo *_TemplateInfo; + CTree *_Init; + +protected: + /** Constructor. + * \param id The object type. */ + CAttributeInfo (ObjectId id); + +public: + /** Constructor. */ + CAttributeInfo (); + /** Destructor. If the object type is CObjectInfo::ATTRIBUTE_INFO, + * then CObjectInfo::CleanUp() is called. */ + ~CAttributeInfo (); + + /** Get the semantic object for the object definition. + * \see CObjectInfo::DefObject() */ + CAttributeInfo *DefObject () const; + /** Get the syntax tree node of the object. */ + CT_InitDeclarator *Tree () const; + /** Get the syntax tree node of the initializer. */ + CTree *Init (); + /** Set the syntax tree node of the initializer. */ + void Init (CTree*); + + /** Get the template information object if this is a static + * data member of a class template. + * \return The template information object or NULL. */ + CTemplateInfo *TemplateInfo () const; + /** Set the template information object of a static data + * member of a class template. + * \param info The semantic object of the template. */ + void TemplateInfo (CTemplateInfo *info); + + /** Get the class or union if this is a data member of a class or union. + * \return The class or union, or NULL if not a member. */ + CRecord *Record () const; + /** Get the namespace if the object is declared in a namespace. + * \return The namespace or NULL if not declared in a namespace. */ + CNamespaceInfo *Namespace () const; + /** Set the qualification scope of the object. This can be a namespace + * for objects declared in a namespace or a class/union for data + * members of a class/union. + * \param scope The qualification scope. */ + void QualifiedScope (CStructure *scope); +}; + +inline CAttributeInfo::CAttributeInfo () : + CScopeRequest (CObjectInfo::ATTRIBUTE_INFO), + _TemplateInfo ((CTemplateInfo*)0), + _Init (0) + {} +inline CAttributeInfo::CAttributeInfo (CObjectInfo::ObjectId id) : + CScopeRequest (id), + _TemplateInfo ((CTemplateInfo*)0), + _Init (0) + {} + +inline CTemplateInfo *CAttributeInfo::TemplateInfo () const + { return _TemplateInfo; } +inline void CAttributeInfo::TemplateInfo (CTemplateInfo *info) + { _TemplateInfo = info; } + +inline void CAttributeInfo::QualifiedScope (CStructure *s) + { _QualScope = s; } + +inline void CAttributeInfo::Init (CTree* init) + { _Init = init; } + +} // namespace Puma + +#endif /* __CAttributeInfo_h__ */ diff --git a/Puma/src/infos/CBaseClassInfo.cc b/Puma/src/infos/CBaseClassInfo.cc new file mode 100644 index 0000000..d3c561e --- /dev/null +++ b/Puma/src/infos/CBaseClassInfo.cc @@ -0,0 +1,54 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CBaseClassInfo.h" +#include "Puma/CClassInfo.h" +#include "Puma/CTree.h" +#include "Puma/CTemplateInstance.h" + +namespace Puma { + + +CBaseClassInfo::~CBaseClassInfo () { +} + +CT_BaseSpec *CBaseClassInfo::Tree () const { + return (CT_BaseSpec*)CObjectInfo::Tree (); +} + +void CBaseClassInfo::Class (CClassInfo *c) { +// TEMPORARY HACK ---> + // in the --pseudo-instances mode the base class might be + // a template pseudo instance. In this case the template is returned instead + // of the (pseudo) template instance. However, the pseudo instance is + // available, too + if (c && c->TemplateInstance () && ! c->TemplateInstance ()->canInstantiate ()) { + _Class = c->TemplateInstance ()->Template ()->ObjectInfo ()-> + TypeInfo ()->TypeClass ()->ClassInfo (); + _ClassPseudoInstance = c; + } + else { +// TEMPORARY HACK <--- + _Class = c; + _ClassPseudoInstance = 0; +// TEMPORARY HACK ---> + } +// TEMPORARY HACK <--- +} + +} // namespace Puma diff --git a/Puma/src/infos/CBaseClassInfo.h b/Puma/src/infos/CBaseClassInfo.h new file mode 100644 index 0000000..8c67f8e --- /dev/null +++ b/Puma/src/infos/CBaseClassInfo.h @@ -0,0 +1,80 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CBaseClassInfo_h__ +#define __CBaseClassInfo_h__ + +/** \file + * Semantic information about a base class of a class. */ + +#include "Puma/CScopeRequest.h" +#include "Puma/CProtection.h" + +namespace Puma { + +class CClassInfo; +class CT_BaseSpec; + +/** \class CBaseClassInfo CBaseClassInfo.h Puma/CBaseClassInfo.h + * Semantic information about a base class of a class. The base + * class is specified by a base class specifier in the base class + * list of a class definition. It can have several qualifiers + * like \e virtual, \e public, and so on. */ +class CBaseClassInfo : public CScopeRequest { + /** The semantic object of the base class. */ + CClassInfo *_Class; + /** The semantic object of the pseudo instance + * if the base class is a pseudo instance. */ + CClassInfo *_ClassPseudoInstance; + +public: + /** Constructor. */ + CBaseClassInfo (); + /** Destructor. If the object type is CObjectInfo::BASECLASS_INFO, + * then CObjectInfo::CleanUp() is called. */ + ~CBaseClassInfo (); + + /** Get the semantic information for the base class. */ + CClassInfo *Class () const; + /** Get the semantic information for the template pseudo instance + * if the base class is a template pseudo instance. */ + CClassInfo *ClassPseudoInstance () const; + /** Set the semantic information for the base class. */ + void Class (CClassInfo *); + + /** Get the syntax tree node representing the base class specifier. */ + CT_BaseSpec *Tree () const; +}; + +inline CBaseClassInfo::CBaseClassInfo () : + CScopeRequest (CObjectInfo::BASECLASS_INFO), + _Class ((CClassInfo*)0) + {} + + +inline CClassInfo *CBaseClassInfo::Class () const { + return _Class; +} + +inline CClassInfo *CBaseClassInfo::ClassPseudoInstance () const { + return _ClassPseudoInstance; +} + +} // namespace Puma + +#endif /* __CBaseClassInfo_h__ */ diff --git a/Puma/src/infos/CCandidateInfo.h b/Puma/src/infos/CCandidateInfo.h new file mode 100644 index 0000000..690f1fe --- /dev/null +++ b/Puma/src/infos/CCandidateInfo.h @@ -0,0 +1,145 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CCandidateInfo_h__ +#define __CCandidateInfo_h__ + +/** \internal Internal part of the overload resolution mechanism. */ + +/** \file + * Representation of a C++ overload resolution candidate. */ + +#include "Puma/CCConvSeq.h" +#include "Puma/Array.h" + +namespace Puma { + +class CFunctionInfo; + +/** \class CCandidateInfo CCandidateInfo.h Puma/CCandidateInfo.h + * Representation of a candidate for the C++ function overload + * resolution mechanism. Such a candidate stores the candidate + * function and the conversion sequences of the function call + * arguments needed to match the function parameter types of + * the overloaded function. + * In special situations it is possible that the overload + * resolution selects a function that hasn't been parsed, yet, + * because of delayed parsing of member functions and the + * initializers of their arguments. Here is an example: + * + * \code + * struct has_deref { + * template static long test(Type *, Type * = 42); + * static char test(void *); + * static const int value = sizeof(test((long *) 0)); + * }; + * \endcode + * + * Here the first 'test' is selected, but an error message will + * have to be issued. This is not considered as a substitution + * fault, which would have to be ignored ("SFINAE"). + * The '_delayed' attribute indicates this situation. */ + +class CCandidateInfo { + Array _ConvSequences; + CFunctionInfo *_Function; + CCConvSeq *_SecondConvSeq; + bool _delayed; + +public: + /** Constructor. + * \param fi The candidate function. */ + CCandidateInfo (CFunctionInfo *fi); + /** Destructor. */ + ~CCandidateInfo (); + + /** Get the candidate function. */ + CFunctionInfo *Function () const; + /** Set the candidate function. + * \param fi The candidate function. */ + void Function (CFunctionInfo *fi); + + /** Mark the candidate as erroneous due to delayed parsing. */ + void markDelayedParseProblem (); + + /** Get the delayed parsing problem flag. */ + bool hasDelayedParseProblem () const; + + /** Add a conversion sequence for a function argument. + * The conversion sequences are added in the order of + * the arguments of the function call. + * \param seq The conversion sequence. */ + void addConvSequence (CCConvSeq *seq); + + /** Get the number of the conversion sequences. */ + unsigned ConvSequences () const; + /** Get the n-th conversion sequence. The n-th conversion sequence + * corresponds to the n-th function call argument. + * \param n The conversion sequence or NULL if \e n is invalid. */ + CCConvSeq *ConvSequence (unsigned n); + + /** Set the \e second conversion sequence. This is a user-defined + * conversion by means of a user-defined conversion function. + * \param seq The conversion sequence. */ + void SecondConvSeq (CCConvSeq *seq); + /** Get the \e second conversion sequence. */ + CCConvSeq *SecondConvSeq () const; +}; + +inline CCandidateInfo::CCandidateInfo (CFunctionInfo *f) : + _Function (f), + _SecondConvSeq ((CCConvSeq*)0), + _delayed (false) + {} +inline CCandidateInfo::~CCandidateInfo () + { + for (long i = 0; i < _ConvSequences.length (); i++) { + if (_ConvSequences.fetch (i)) + delete _ConvSequences.fetch (i); + } + if (_SecondConvSeq) delete _SecondConvSeq; + } + +inline CFunctionInfo *CCandidateInfo::Function () const + { return _Function; } +inline void CCandidateInfo::Function (CFunctionInfo *f) + { _Function = f; } + +inline void CCandidateInfo::markDelayedParseProblem () + { _delayed = true; } + +inline bool CCandidateInfo::hasDelayedParseProblem () const + { return _delayed; } + +inline void CCandidateInfo::addConvSequence (CCConvSeq *s) + { _ConvSequences.append (s); } + +inline unsigned CCandidateInfo::ConvSequences () const + { return (unsigned)_ConvSequences.length (); } +inline CCConvSeq *CCandidateInfo::ConvSequence (unsigned s) + { return _ConvSequences.lookup (s); } + +inline void CCandidateInfo::SecondConvSeq (CCConvSeq *s) + { _SecondConvSeq = s; } +inline CCConvSeq *CCandidateInfo::SecondConvSeq () const + { return _SecondConvSeq; } + + +} // namespace Puma + +#endif /* __CCandidateInfo_h__ */ diff --git a/Puma/src/infos/CClassDatabase.h b/Puma/src/infos/CClassDatabase.h new file mode 100644 index 0000000..048f8a7 --- /dev/null +++ b/Puma/src/infos/CClassDatabase.h @@ -0,0 +1,36 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CClassDatabase_h__ +#define __CClassDatabase_h__ + +/** \file + * Alias for CSemDatabase. */ + +#include "Puma/CSemDatabase.h" + +namespace Puma { + + +/** Backward compatibility alias for CSemDatabase. */ +typedef CSemDatabase CClassDatabase; + + +} // namespace Puma + +#endif /* __CClassDatabase_h__ */ diff --git a/Puma/src/infos/CClassInfo.cc b/Puma/src/infos/CClassInfo.cc new file mode 100644 index 0000000..8232a64 --- /dev/null +++ b/Puma/src/infos/CClassInfo.cc @@ -0,0 +1,319 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CClassInfo.h" +#include "Puma/CFunctionInfo.h" +#include "Puma/CFctInstance.h" +#include "Puma/CAttributeInfo.h" +#include "Puma/CClassInstance.h" +#include "Puma/CTemplateInfo.h" +#include "Puma/CTemplateInstance.h" +#include "Puma/CTokens.h" +#include "Puma/CTree.h" +#include "Puma/Token.h" +#include "Puma/CSemDatabase.h" +#include + +namespace Puma { + + +CClassInfo::~CClassInfo () { +} + +CBaseClassInfo *CClassInfo::BaseClass (const char *name) const { + for (unsigned i = 0; i < BaseClasses (); i++) + if (! strcmp (BaseClass (i)->Class ()->Name (), name)) + return BaseClass (i); + return (CBaseClassInfo*)0; +} + +CClassInfo *CClassInfo::DerivedClass (const char *name) const { + for (unsigned i = 0; i < DerivedClasses (); i++) + if (! strcmp (DerivedClass (i)->Name (), name)) + return DerivedClass (i); + return (CClassInfo*)0; +} + +void CClassInfo::addBaseClass (CBaseClassInfo *info) { + for (unsigned i = 0; i < BaseClasses (); i++) + if (BaseClass (i) == info) + return; + info->Class ()->addDerivedClass ((CClassInfo*)this); + _BaseClasses.append (info); +} + +void CClassInfo::addDerivedClass (CClassInfo *info) { + for (unsigned i = 0; i < DerivedClasses (); i++) + if (DerivedClass (i) == info) + return; + _Derived.append (info); +} + +void CClassInfo::removeBaseClass (const CBaseClassInfo *info) { + for (unsigned i = 0; i < BaseClasses (); i++) + if (BaseClass (i) == info) { + BaseClass (i)->Scope ((CScopeInfo*)0); + //delete _BaseClasses[i]; + _BaseClasses.remove (i); + break; + } +} + +void CClassInfo::removeBaseClass (const CClassInfo *info) { + for (unsigned i = 0; i < BaseClasses (); i++) + if (BaseClass (i)->Class () == info) { + BaseClass (i)->Scope ((CScopeInfo*)0); + //delete _BaseClasses[i]; + _BaseClasses.remove (i); + } +} + +void CClassInfo::removeDerivedClass (const CClassInfo *info) { + for (unsigned i = 0; i < DerivedClasses (); i++) + if (DerivedClass (i) == info) { + _Derived.remove (i); + break; + } +} + +bool CClassInfo::isBaseClass (const CClassInfo *info, bool recursive) const { + for (unsigned i = 0; i < BaseClasses (); i++) + if (BaseClass (i)->Class () == info || + (recursive && BaseClass (i)->Class ()->isBaseClass (info, true))) + return true; + return false; +} + +bool CClassInfo::isDerivedClass (const CClassInfo *info, bool recursive) const { + for (unsigned i = 0; i < DerivedClasses (); i++) + if (DerivedClass (i) == info || + (recursive && DerivedClass (i)->isDerivedClass (info, true))) + return true; + return false; +} + +CBaseClassInfo *CClassInfo::newBaseClass (CClassInfo *cinfo) { + CBaseClassInfo *info = SemDB() ? SemDB()->newBaseClass() : new CBaseClassInfo; + info->Scope (this); + info->Class (cinfo); + if (cinfo) + info->Class ()->addDerivedClass ((CClassInfo*)this); + _BaseClasses.append (info); + return info; +} + +bool CClassInfo::isStruct () const { + if (Tree ()) { + Token *token = Tree ()->token (); + return token && token->type () == TOK_STRUCT; + } + return false; +} + +CClassInfo *CClassInfo::DefObject () const { + CObjectInfo *o = (CObjectInfo*)this; + if (o->NextObject() != o) { + do { + CTree* tree = o->Tree(); + if (tree && tree->NodeName () == CT_ClassDef::NodeId ()) { + CClassInstance* ci = o->ClassInstance(); + if (! ci || ci->TemplateInstance ()->canInstantiate ()) { + return o->ClassInfo (); + } + } + o = o->NextObject (); + } while (o != (CObjectInfo*)this); + } + return (CClassInfo*)this; +} + +CProtection::Type CClassInfo::Accessibility (CObjectInfo *oi) const { + + // oi should be the declaration if there is a separate definition + if (oi->NextObject () != oi && oi == oi->DefObject ()) + oi = oi->NextObject (); + + // TODO: Check for using declarations etc., which change the accessibility + CProtection::Type result = CProtection::PROT_NONE; + + // lookup the object info in this class + CScopeInfo *scope = oi->Scope (); + if (oi->isTemplateInstance ()) + scope = oi->TemplateInstance ()->Template ()->Scope (); + if (scope == this) { + // found it here, the accessibility is the protection of the declaration + result = oi->Protection (); + } + else { + // no success in this class, let's try the base classes + for (unsigned i = 0; i < BaseClasses (); i++) { + CBaseClassInfo *base = BaseClass (i); + // 11.2 Accessibility of base classes and base class members + // If a class is declared to be a base class (clause 10) for another + // class using the public access specifier, the public members of the + // base class are accessible as public members of the derived class and + // protected members of the base class are accessible as protected + // members of the derived class. If a class is declared to be a base + // class for another class using the protected access specifier, the + // public and protected members of the base class are accessible as + // protected members of the derived class. If a class is declared to be + // a base class for another class using the private access specifier, + // the public and protected members of the base class are accessible as + // private members of the derived class99). + CProtection::Type inheritance = base->Protection (); + CProtection::Type base_access = base->Class ()->Accessibility (oi); + if (base_access == CProtection::PROT_PRIVATE) { + base_access = CProtection::PROT_NONE; + } + else if (base_access == CProtection::PROT_PROTECTED) { + if (inheritance == CProtection::PROT_PRIVATE) + base_access = CProtection::PROT_PRIVATE; + } + else if (base_access == CProtection::PROT_PUBLIC) { + if (inheritance == CProtection::PROT_PRIVATE) + base_access = CProtection::PROT_PRIVATE; + else if (inheritance == CProtection::PROT_PROTECTED) + base_access = CProtection::PROT_PROTECTED; + } + + // 11.7.1 Multiple access + // If a name can be reached by several paths through a multiple + // inheritance graph, the access is that of the path that gives most + // access. + if (result == CProtection::PROT_NONE) + result = base_access; + else if (base_access < result) + result = base_access; + } + } + return result; +} + +bool CClassInfo::overridesVirtual (const CFunctionInfo *fi) const { + // first check all member functions of this class + for (unsigned f = 0; f < Functions (); f++) { + CFunctionInfo *tested = Function (f); + if (tested->isVirtual () && tested->hasSameNameAndArgs (fi)) + return true; + } + // if we were not successful, the base classes have to be searched + for (unsigned b = 0; b < BaseClasses (); b++) { + if (BaseClass (b)->Class ()->overridesVirtual (fi)) + return true; + } + // nothing found + return false; +} + +// 8.5.1 Aggregates +// An aggregate is an array or a class (clause 9) with no userdeclared +// constructors (12.1), no private or protected nonstatic data members +// (clause 11), no base classes (clause 10), and no virtual functions (10.3). +bool CClassInfo::isAggregate () const { + // check for base classes + if (BaseClasses () > 0) + return false; + + // check the functions + for (unsigned f = 0; f < Functions (); f++) { + CFunctionInfo *func = Function (f); + if (func->isConstructor () && !func->isBuiltin ()) + return false; + if (func->isVirtual ()) + return false; + } + + // check the attributes + for (unsigned a = 0; a < Attributes(); a++) { + CAttributeInfo *attr = Attribute (a); + if (!attr->isStatic () && + (attr->Protection () == CProtection::PROT_PRIVATE || + attr->Protection () == CProtection::PROT_PROTECTED)) + return false; + } + + // this IS an aggregate + return true; +} + +/** Yields true if the class has no non-static data members other than + * bit-fields of length 0, no virtual member functions, no virtual + * base classes, and no base class B for which isEmpty() is false. + * \return true if empty class. */ +bool CClassInfo::isEmpty () const { + unsigned num = Attributes (); + for (unsigned i = 0; i < num; i++) { + CAttributeInfo* ai = Attribute (i); + if (! ai->isStatic ()) { + CTypeBitField* type = ai->TypeInfo ()->TypeBitField (); + if (! type || type->Dimension () != 0) + return false; + } + } + num = Functions (); + for (unsigned i = 0; i < num; i++) { + if (Function (i)->isVirtual ()) + return false; + } + num = BaseClasses (); + for (unsigned i = 0; i < num; i++) { + CBaseClassInfo* bc = BaseClass (i); + if (bc->isVirtual () || ! bc->Class ()->isEmpty ()) + return false; + } + return true; +} + +/** Yields true if the class declares or inherits a virtual function. */ +bool CClassInfo::isPolymorphic () const { + unsigned num = Functions (); + for (unsigned i = 0; i < num; i++) { + if (Function (i)->isVirtual ()) + return true; + } + num = BaseClasses (); + for (unsigned i = 0; i < num; i++) { + if (BaseClass (i)->Class ()->isPolymorphic ()) + return true; + } + return false; +} + +/** Yields true if the class has a pure virtual function. */ +bool CClassInfo::isAbstract () const { + unsigned num = Functions (); + for (unsigned i = 0; i < num; i++) { + if (Function (i)->isPureVirtual ()) + return true; + } + return false; +} + +/** Yields true if the class has a virtual destructor. */ +bool CClassInfo::hasVirtualDtor () const { + unsigned num = Functions (); + for (unsigned i = 0; i < num; i++) { + CFunctionInfo* mf = Function (i); + if (mf->isVirtual () && mf->isDestructor ()) + return true; + } + return false; +} + + +} // namespace Puma diff --git a/Puma/src/infos/CClassInfo.h b/Puma/src/infos/CClassInfo.h new file mode 100644 index 0000000..ec7cdc5 --- /dev/null +++ b/Puma/src/infos/CClassInfo.h @@ -0,0 +1,185 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CClassInfo_h__ +#define __CClassInfo_h__ + +/** \file + * Semantic information about a class. */ + +#include "Puma/CRecord.h" +#include "Puma/CBaseClassInfo.h" +#include "Puma/CProtection.h" + +namespace Puma { + +class CTypeClass; + + +/** \class CClassInfo CClassInfo.h Puma/CClassInfo.h + * Semantic information about a class. Note that 'struct's + * are ordinary classes where the member access type + * defaults to \e public. Note also that a 'union', + * although syntactically very similar, is not a class + * and thus not represented by CClassInfo. */ +class CClassInfo : public CRecord { + Array _BaseClasses; + Array _Derived; + // True if class has dependent base classes + bool _DepBaseClass; + +protected: + /** Constructor. + * \param id The object type. */ + CClassInfo (ObjectId id); + +public: + /** Constructor. */ + CClassInfo (); + /** Destructor. If the object type is CObjectInfo::CLASS_INFO, + * then CObjectInfo::CleanUp() is called. */ + ~CClassInfo (); + + /** Get the semantic object of the class definition. + * \see CObjectInfo::DefObject() */ + CClassInfo *DefObject () const; + /** Get the type information for the class. */ + CTypeClass *TypeInfo () const; + + /** Get the number of the base classes of the class. */ + unsigned BaseClasses () const; + /** Get the number of classes derived from the class. */ + unsigned DerivedClasses() const; + /** Get the n-th base class. + * \param n The index of the base class. + * \return The base class or if \e n is not valid. */ + CBaseClassInfo *BaseClass (unsigned n) const; + /** Get the base class with the given name. + * \param name The name of the base class. + * \return The base class or NULL if there is no base + * class with the given name. */ + CBaseClassInfo *BaseClass (const char *name) const; + /** Get the n-th derived class. + * \param n The index of the derived class. + * \return The derived class or NULL if \e n is not valid. */ + CClassInfo *DerivedClass (unsigned n) const; + /** Get the derived class with the given name. + * \param name The name of the derived class. + * \return The derived class or NULL if there is no derived + * class with the given name. */ + CClassInfo *DerivedClass (const char *name) const; + + /** Check if the given class is a base class of this class. + * \param base The base class. + * \param recursive If \e false then only the direct base classes + * are considered. */ + bool isBaseClass (const CClassInfo *base, bool recursive = false) const; + /** Check if the given class is derived from this class. + * \param dc The derived class. + * \param recursive If \e false then only the directly derived classes + * are considered. */ + bool isDerivedClass (const CClassInfo *dc, bool recursive = false) const; + /** Set that this class has a base class that depends on template + * parameters. + * \param depends \e true if there is a dependent base class. */ + void hasDepBaseClass (bool depends); + /** Check if this class has a base class that depends on + * template parameters. */ + bool hasDepBaseClass () const; + + /** Add a base class to this class. + * \param bc The base class. */ + void addBaseClass (CBaseClassInfo *bc); + /** Add a derived class to this class. + * \param dc The derived class. */ + void addDerivedClass (CClassInfo *dc); + /** Remove the given base class from this class. + * \param bc The base class. */ + void removeBaseClass (const CBaseClassInfo *bc); + /** Remove the given base class from this class. + * \param bc The base class. */ + void removeBaseClass (const CClassInfo *bc); + /** Remove the given derived class from this class. + * \param dc The derived class. */ + void removeDerivedClass (const CClassInfo *dc); + + /** Create a new base class semantic object. + * \param bc The semantic information about the of the base class + * or NULL to create an empty base class semantic object. */ + CBaseClassInfo *newBaseClass (CClassInfo *bc = 0); + + /** Get the accessibility of a particular member or base class member. + * \param oi The semantic object for the member. */ + CProtection::Type Accessibility (CObjectInfo *oi) const; + + /** Check if the given function overrides any virtual function + * defined in this class or any of its base classes. + * \param fi The function. */ + bool overridesVirtual (const CFunctionInfo *fi) const; + + /** Check if the class is declared using keyword 'struct'. */ + bool isStruct () const; + /** Check if this class is an aggregate according to + * paragraph 8.5.1-1 of the ISO C++ standard. */ + bool isAggregate () const; + /** Yields true if the class has no non-static data members other than + * bit-fields of length 0, no virtual member functions, no virtual + * base classes, and no base class B for which isEmpty() is false. + * \return true if empty class. */ + bool isEmpty () const; + /** Yields true if the class declares or inherits a virtual function. */ + bool isPolymorphic () const; + /** Yields true if the class has a pure virtual function. */ + bool isAbstract () const; + /** Yields true if the class has a virtual destructor. */ + bool hasVirtualDtor () const; +}; + +inline CClassInfo::CClassInfo (ObjectId id) : + CRecord (id), + _BaseClasses (1, 2), + _Derived (1, 2), + _DepBaseClass (false) + {} +inline CClassInfo::CClassInfo () : + CRecord (CObjectInfo::CLASS_INFO), + _BaseClasses (1, 2), + _Derived (1, 2), + _DepBaseClass (false) + {} + +inline CTypeClass *CClassInfo::TypeInfo () const + { return (CTypeClass*)CObjectInfo::TypeInfo (); } + +inline unsigned CClassInfo::BaseClasses () const + { return _BaseClasses.length (); } +inline unsigned CClassInfo::DerivedClasses () const + { return _Derived.length (); } +inline CBaseClassInfo *CClassInfo::BaseClass (unsigned n) const + { return _BaseClasses.lookup (n); } +inline CClassInfo *CClassInfo::DerivedClass (unsigned n) const + { return _Derived.lookup (n); } + +inline bool CClassInfo::hasDepBaseClass () const + { return _DepBaseClass; } +inline void CClassInfo::hasDepBaseClass (bool v) + { _DepBaseClass = v; } + +} // namespace Puma + +#endif /* __CClassInfo_h__ */ diff --git a/Puma/src/infos/CClassInstance.h b/Puma/src/infos/CClassInstance.h new file mode 100644 index 0000000..7dafe31 --- /dev/null +++ b/Puma/src/infos/CClassInstance.h @@ -0,0 +1,59 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CClassInstance_h__ +#define __CClassInstance_h__ + +/** \file + * Semantic information about an instance of a class template. */ + +#include "Puma/CTemplateInstance.h" +#include "Puma/CClassInfo.h" + +namespace Puma { + + +/** \class CClassInstance CClassInstance.h Puma/CClassInstance.h + * Semantic information about an instance of a class template. */ +class CClassInstance : public CClassInfo { + CTemplateInstance _InstanceInfo; + +public: + /** Constructor. */ + CClassInstance (); + /** Destructor. If the object type is CObjectInfo::CLASS_INSTANCE_INFO, + * then CObjectInfo::CleanUp() is called. */ + ~CClassInstance (); + + /** Get the semantic information about the template instance. */ + CTemplateInstance *TemplateInstance () const; +}; + +inline CClassInstance::CClassInstance () : + CClassInfo (CObjectInfo::CLASS_INSTANCE_INFO) + {} +inline CClassInstance::~CClassInstance () + {} + +inline CTemplateInstance *CClassInstance::TemplateInstance () const + { return (CTemplateInstance*)(&_InstanceInfo); } + + +} // namespace Puma + +#endif /* __CClassInstance_h__ */ diff --git a/Puma/src/infos/CEnumInfo.cc b/Puma/src/infos/CEnumInfo.cc new file mode 100644 index 0000000..2cd9888 --- /dev/null +++ b/Puma/src/infos/CEnumInfo.cc @@ -0,0 +1,107 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CEnumInfo.h" +#include "Puma/CEnumeratorInfo.h" +#include "Puma/CTemplateInstance.h" +#include "Puma/CStructure.h" +#include "Puma/CTree.h" +#include "Puma/CSemDatabase.h" +#include "Puma/CTypeInfo.h" +#include + +namespace Puma { + + +CEnumInfo::CEnumInfo () : + CScopeRequest (CObjectInfo::ENUM_INFO), + _UnderlyingType (&CTYPE_INT) { +} + + +CEnumInfo::~CEnumInfo () { +} + +CEnumeratorInfo *CEnumInfo::Enumerator (const char *name) const { + for (unsigned i = 0; i < Enumerators (); i++) + if (! strcmp (Enumerator (i)->Name (), name)) + return Enumerator (i); + return (CEnumeratorInfo*)0; +} + +void CEnumInfo::addEnumerator (CEnumeratorInfo *info) { + for (unsigned i = Enumerators (); i > 0; i--) + if (Enumerator (i-1) == info) + return; + _Enumerators.append (info); +} + +void CEnumInfo::removeEnumerator (const CEnumeratorInfo *info) { + for (unsigned i = Enumerators (); i > 0; i--) + if (Enumerator (i-1) == info) { + _Enumerators.remove (i-1); + break; + } +} + +CEnumeratorInfo *CEnumInfo::newEnumerator () { + CEnumeratorInfo *info = SemDB() ? SemDB()->newEnumerator() : new CEnumeratorInfo; + info->Enum (this); + addEnumerator (info); + return info; +} + +void CEnumInfo::deleteEnumerator (const CEnumeratorInfo *info) { + for (unsigned i = Enumerators (); i > 0; i--) + if (Enumerator (i-1) == info) { + Enumerator (i-1)->Enum (0); + delete (CEnumeratorInfo*)_Enumerators[i-1]; + _Enumerators.remove (i-1); + break; + } +} + +bool CEnumInfo::isComplete (unsigned long pos) const { + CEnumInfo *info = (CEnumInfo*)DefObject (); + if (info->isDefined ()) { + if (pos == 0) + return true; + CT_Token *token = info->Tree ()->token_node (); + if (token && token->Number () <= pos) + return true; + } + return false; +} + +bool CEnumInfo::isDefined () const { + return Tree () && Tree ()->NodeName () == CT_EnumDef::NodeId (); +} + +CEnumInfo *CEnumInfo::DefObject () const { + CObjectInfo *o = (CObjectInfo*)this; + do { + if (o->Tree () && o->Tree ()->NodeName () == CT_EnumDef::NodeId ()) + if (! o->TemplateInstance () || o->TemplateInstance ()->canInstantiate ()) + return o->EnumInfo (); + o = o->NextObject (); + } while (o != (CObjectInfo*)this); + return (CEnumInfo*)this; +} + + +} // namespace Puma diff --git a/Puma/src/infos/CEnumInfo.h b/Puma/src/infos/CEnumInfo.h new file mode 100644 index 0000000..12f4d42 --- /dev/null +++ b/Puma/src/infos/CEnumInfo.h @@ -0,0 +1,115 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CEnumInfo_h__ +#define __CEnumInfo_h__ + +/** \file + * Semantic information about an enumeration. */ + +#include "Puma/CEnumeratorInfo.h" +#include "Puma/Array.h" +#include "Puma/CScopeRequest.h" + +namespace Puma { + +class CTypeEnum; + + +/** \class CEnumInfo CEnumInfo.h Puma/CEnumInfo.h + * Semantic information about an enumeration. */ +class CEnumInfo : public CScopeRequest { + Array _Enumerators; + CTypeInfo *_UnderlyingType; + +public: + /** Constructor. */ + CEnumInfo (); + /** Destructor. If the object type is CObjectInfo::ENUM_INFO, + * then CObjectInfo::CleanUp() is called. */ + ~CEnumInfo (); + + /** Get the number of enumerators in this enumeration. */ + unsigned Enumerators () const; + /** Get the n-th enumerator. + * \param n The index of the enumerator. + * \return The enumerator or NULL if \e n is invalid. */ + CEnumeratorInfo *Enumerator (unsigned n) const; + /** Get the enumerator with the given name. + * \param name The name of the enumerator. + * \return The enumerator or NULL if no enumerator with that name. */ + CEnumeratorInfo *Enumerator (const char *name) const; + + /** Get the semantic object of the enumeration definition. + * \see CObjectInfo::DefObject() */ + CEnumInfo *DefObject () const; + /** Get the type information for the enumeration. */ + CTypeEnum *TypeInfo () const; + + /** Add a new enumerator to the enumeration. + * \param ei The enumerator. */ + void addEnumerator (CEnumeratorInfo *ei); + /** Remove the given enumerator from the enumeration. + * \param ei The enumerator. */ + void removeEnumerator (const CEnumeratorInfo *ei); + + /** Create a semantic object for an enumerator. The new + * enumerator is added to the enumeration. */ + CEnumeratorInfo *newEnumerator (); + /** Destroy the given enumerator. The enumerator is + * removed from the enumeration. + * \param ei The enumerator. */ + void deleteEnumerator (const CEnumeratorInfo *ei); + + /** Check if the enumeration is defined. */ + bool isDefined () const; + /** Check if the enumeration is complete (defined) + * at the given source code position. The position + * is specified by the unique number of the CT_Token + * tree node representing the name of the enumeration. + * \param pos The source code position. */ + bool isComplete (unsigned long pos = 0) const; + + /** Return the underlying data type of the enumeration. + * This is implementation-defined and defaults to \e int. */ + CTypeInfo *UnderlyingType () const; + /** Set the underlying data type of the enumeration. + * This is implementation-defined and defaults to \e int. + * \param type The underlying type. */ + void UnderlyingType (CTypeInfo *type); +}; + +inline unsigned CEnumInfo::Enumerators () const + { return _Enumerators.length (); } +inline CEnumeratorInfo *CEnumInfo::Enumerator (unsigned n) const + { return _Enumerators.lookup (n); } + +inline CTypeEnum *CEnumInfo::TypeInfo () const + { return (CTypeEnum*)CObjectInfo::TypeInfo (); } +//inline CT_EnumSpec *CEnumInfo::Tree () const +// { return (CT_EnumSpec*)CObjectInfo::Tree (); } + +inline CTypeInfo *CEnumInfo::UnderlyingType () const + { return (CTypeInfo*)_UnderlyingType; } +inline void CEnumInfo::UnderlyingType (CTypeInfo *type) + { _UnderlyingType = type; } + + +} // namespace Puma + +#endif /* __CEnumInfo_h__ */ diff --git a/Puma/src/infos/CEnumeratorInfo.cc b/Puma/src/infos/CEnumeratorInfo.cc new file mode 100644 index 0000000..47c45f0 --- /dev/null +++ b/Puma/src/infos/CEnumeratorInfo.cc @@ -0,0 +1,39 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CEnumeratorInfo.h" +#include "Puma/CEnumInfo.h" +#include "Puma/CTypeInfo.h" +#include "Puma/CTree.h" + +namespace Puma { + + +CEnumeratorInfo::~CEnumeratorInfo () { +} + +CT_Enumerator *CEnumeratorInfo::Tree () const { + return (CT_Enumerator*)CObjectInfo::Tree (); +} + +CTypeInfo *CEnumeratorInfo::UnderlyingType () const { + return _Enum ? _Enum->UnderlyingType () : &CTYPE_INT; +} + + +} // namespace Puma diff --git a/Puma/src/infos/CEnumeratorInfo.h b/Puma/src/infos/CEnumeratorInfo.h new file mode 100644 index 0000000..300451c --- /dev/null +++ b/Puma/src/infos/CEnumeratorInfo.h @@ -0,0 +1,102 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CEnumeratorInfo_h__ +#define __CEnumeratorInfo_h__ + +/** \file + * Semantic information about an enumeration constant. */ + +#include "Puma/CAttributeInfo.h" +#include "Puma/Limits.h" + +namespace Puma { + + +class CEnumInfo; +class CT_Enumerator; +class CT_ExprList; + + +/** \class CEnumeratorInfo CEnumeratorInfo.h Puma/CEnumeratorInfo.h + * Semantic information about an enumeration constant. + * An enumeration constant also is called enumerator. */ +class CEnumeratorInfo : public CAttributeInfo { + CEnumInfo *_Enum; + LONG_LONG _Value; + bool _HasValue; + +public: + /** Constructor. */ + CEnumeratorInfo (); + /** Destructor. If the object type is CObjectInfo::ENUMERATOR_INFO, + * then CObjectInfo::CleanUp() is called. */ + ~CEnumeratorInfo (); + + /** Get the syntax tree node of the enumerator constant. */ + CT_Enumerator *Tree () const; + + /** Get the underlying value type. This is implementation-defined + * and defaults to \e int.*/ + CTypeInfo *UnderlyingType () const; + + /** Get the enumeration containing this enumerator. */ + CEnumInfo *Enum () const; + /** Set the enumeration containing this enumerator. + * \param ei The enumeration. */ + void Enum (CEnumInfo *ei); + + /** Check if enumerator has a value. */ + bool hasValue () const; + /** Set whether enumerator has a value. + * \param has True or false. */ + void hasValue (bool has); + + /** Get the value of the enumerator. */ + LONG_LONG Value () const; + /** Set the value of the enumerator. + * \param v The value. */ + void Value (LONG_LONG v); +}; + +inline CEnumeratorInfo::CEnumeratorInfo () : + CAttributeInfo (CObjectInfo::ENUMERATOR_INFO), + _Enum ((CEnumInfo*)0), + _Value (0), + _HasValue (false) + {} + +inline void CEnumeratorInfo::Enum (CEnumInfo *e) + { _Enum = e; } +inline void CEnumeratorInfo::Value (LONG_LONG v) + { _Value = v; } + +inline CEnumInfo *CEnumeratorInfo::Enum () const + { return _Enum; } +inline LONG_LONG CEnumeratorInfo::Value () const + { return _Value; } + +inline bool CEnumeratorInfo::hasValue () const + { return _HasValue; } +inline void CEnumeratorInfo::hasValue (bool has) + { _HasValue = has; } + + +} // namespace Puma + +#endif /* __CEnumeratorInfo_h__ */ diff --git a/Puma/src/infos/CFctInstance.cc b/Puma/src/infos/CFctInstance.cc new file mode 100644 index 0000000..6528321 --- /dev/null +++ b/Puma/src/infos/CFctInstance.cc @@ -0,0 +1,37 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CFctInstance.h" +#include "Puma/CTypeInfo.h" + +namespace Puma { + + +CFctInstance::~CFctInstance () { + if (_PseudoType) + CTypeInfo::Destroy (_PseudoType); +} + + +void CFctInstance::RealTypeInfo (CTypeInfo* type) { + _PseudoType = TypeInfo (); + ObjectInfo ()->TypeInfo (type); +} + + +} // namespace Puma diff --git a/Puma/src/infos/CFctInstance.h b/Puma/src/infos/CFctInstance.h new file mode 100644 index 0000000..a225b9b --- /dev/null +++ b/Puma/src/infos/CFctInstance.h @@ -0,0 +1,63 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CFctInstance_h__ +#define __CFctInstance_h__ + +/** \file + * Semantic information about an instance of a function template. */ + +#include "Puma/CTemplateInstance.h" +#include "Puma/CFunctionInfo.h" + +namespace Puma { + + +/** \class CFctInstance CFctInstance.h Puma/CFctInstance.h + * Semantic information about an instance of a function template. */ +class CFctInstance : public CFunctionInfo { + CTemplateInstance _InstanceInfo; + CTypeInfo* _PseudoType; // pseudo instance type, replaced by type of real instantiation + +public: + /** Constructor. */ + CFctInstance (); + /** Destructor. If the object type is CObjectInfo::FCT_INSTANCE_INFO, + * then CObjectInfo::CleanUp() is called. */ + ~CFctInstance (); + + /** Get the semantic information for the template instance. */ + CTemplateInstance *TemplateInstance () const; + + /** Set the type of the real instantiation. + * \param type The function type. */ + void RealTypeInfo (CTypeInfo* type); +}; + +inline CFctInstance::CFctInstance () : + CFunctionInfo (CObjectInfo::FCT_INSTANCE_INFO), + _PseudoType (0) + {} + +inline CTemplateInstance *CFctInstance::TemplateInstance () const + { return (CTemplateInstance*)(&_InstanceInfo); } + + +} // namespace Puma + +#endif /* __CFctInstance_h__ */ diff --git a/Puma/src/infos/CFileInfo.h b/Puma/src/infos/CFileInfo.h new file mode 100644 index 0000000..ac0d695 --- /dev/null +++ b/Puma/src/infos/CFileInfo.h @@ -0,0 +1,96 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CFileInfo_h__ +#define __CFileInfo_h__ + +/** \file + * Semantic information about a source file (translation unit). */ + +#include "Puma/CNamespaceInfo.h" + +namespace Puma { + + +class Unit; + +/** \class CFileInfo CFileInfo.h Puma/CFileInfo.h + * Semantic information about a source file (translation unit). + * A source file has its own scope, the so-called file scope. */ +class CFileInfo : public CNamespaceInfo { + Unit *_Primary; + bool _haveCBuiltins; + bool _haveCCBuiltins; + +public: + /** Constructor. */ + CFileInfo (); + /** Destructor. If the object type is CObjectInfo::FILE_INFO, + * then CObjectInfo::CleanUp() is called. */ + ~CFileInfo (); + + /** Get the token chain of the source file. */ + Unit *Primary () const; + /** Set the token chain of the source file. + * \param unit The token chain. */ + void Primary (Unit *unit); + + /** Check if C compiler build-in functions are defined + * for the source file. */ + bool haveCBuiltins () const; + /** Check if C++ compiler build-in functions are defined + * for the source file. */ + bool haveCCBuiltins () const; + + /** Set whether C compiler build-in functions are defined + * for the source file. + * \param v \e true if C build-in functions are defined. */ + void haveCBuiltins (bool v); + /** Set whether C++ compiler build-in functions are defined + * for the source file. + * \param v \e true if C++ build-in functions are defined. */ + void haveCCBuiltins (bool v); +}; + +inline CFileInfo::CFileInfo () : + CNamespaceInfo (CObjectInfo::FILE_INFO), + _Primary (0), + _haveCBuiltins (false), + _haveCCBuiltins (false) + {} +inline CFileInfo::~CFileInfo () + {} + +inline Unit *CFileInfo::Primary () const + { return _Primary; } +inline void CFileInfo::Primary (Unit *unit) + { _Primary = unit; } + +inline bool CFileInfo::haveCBuiltins () const + { return _haveCBuiltins; } +inline void CFileInfo::haveCBuiltins (bool v) + { _haveCBuiltins = v; } +inline bool CFileInfo::haveCCBuiltins () const + { return _haveCCBuiltins; } +inline void CFileInfo::haveCCBuiltins (bool v) + { _haveCCBuiltins = v; } + + +} // namespace Puma + +#endif /* __CFileInfo_h__ */ diff --git a/Puma/src/infos/CFunctionInfo.cc b/Puma/src/infos/CFunctionInfo.cc new file mode 100644 index 0000000..f95e960 --- /dev/null +++ b/Puma/src/infos/CFunctionInfo.cc @@ -0,0 +1,278 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CFunctionInfo.h" +#include "Puma/CClassInfo.h" +#include "Puma/CTemplateInfo.h" +#include "Puma/CTemplateInstance.h" +#include "Puma/CArgumentInfo.h" +#include "Puma/CLabelInfo.h" +#include "Puma/CTypeInfo.h" +#include "Puma/CConstant.h" +#include "Puma/CTree.h" +#include "Puma/CSemDatabase.h" +#include + +namespace Puma { + + +CFunctionInfo::~CFunctionInfo () { +} + +bool CFunctionInfo::isPureVirtual () const { + CTree* init = Init (); + return init && init->Value () && init->Value ()->Constant () && + init->Value ()->Constant ()->isNull (); +} + +CTypeInfo *CFunctionInfo::ReturnType () const { + return TypeInfo ()->ReturnType (); +} + +bool CFunctionInfo::hasEllipsis () const { + CTypeList *atl = TypeInfo ()->ArgTypes (); + return (atl->Entries () && atl->Entry (atl->Entries ()-1)->is_ellipsis ()); +} + +CArgumentInfo *CFunctionInfo::Argument (const char *name) const { + for (unsigned i = 0; i < Arguments (); i++) + if (Argument (i)->Name ()) + if (! strcmp (Argument (i)->Name (), name)) + return Argument (i); + return (CArgumentInfo*)0; +} + +CLabelInfo *CFunctionInfo::Label (const char *name) const { + for (unsigned i = 0; i < Labels (); i++) + if (Label (i)->Name ()) + if (! strcmp (Label (i)->Name (), name)) + return Label (i); + return (CLabelInfo*)0; +} + +void CFunctionInfo::addArgument (CArgumentInfo *info) { + if (! info) return; + _Arguments.append (info); + addObject (info); +} + +void CFunctionInfo::addLabel (CLabelInfo *info) { + if (! info) return; + _Labels.append (info); +} + +void CFunctionInfo::removeArgument (const CArgumentInfo *info) { + for (unsigned i = Arguments (); i > 0; i--) + if (Argument (i-1) == info) { + _Arguments.remove (i-1); + removeObject (info); + break; + } +} + +void CFunctionInfo::removeLabel (const CLabelInfo *info) { + for (unsigned i = Labels (); i > 0; i--) + if (Label (i-1) == info) { + _Labels.remove (i-1); + break; + } +} + +CArgumentInfo *CFunctionInfo::newArgument () { + CArgumentInfo *info = SemDB () ? SemDB ()->newArgument () : new CArgumentInfo; + info->Scope (this); + addArgument (info); + return info; +} + +CLabelInfo *CFunctionInfo::newLabel () { + CLabelInfo *info = SemDB() ? SemDB()->newLabel() : new CLabelInfo; + info->Scope (this); + addLabel (info); + return info; +} + +void CFunctionInfo::deleteArgument (const CArgumentInfo *info) { + for (unsigned i = Arguments (); i > 0; i--) + if (Argument (i-1) == info) { + removeObject (info); + Argument (i-1)->Scope (0); + delete (CArgumentInfo*)_Arguments[i-1]; + _Arguments.remove (i-1); + break; + } +} + +void CFunctionInfo::deleteLabel (const CLabelInfo *info) { + for (unsigned i = Labels (); i > 0; i--) + if (Label (i-1) == info) { + Label (i-1)->Scope (0); + delete (CLabelInfo*)_Labels[i-1]; + _Labels.remove (i-1); + break; + } +} + +bool CFunctionInfo::isDefined () const { + CFunctionInfo *info = DefObject (); + return (info->Tree () && info->Tree ()->NodeName () == CT_FctDef::NodeId ()); +} + +bool CFunctionInfo::isFctDef () const { + return (Tree () && Tree ()->NodeName () == CT_FctDef::NodeId ()); +} + +CFunctionInfo *CFunctionInfo::DefObject () const { + CObjectInfo *o = (CObjectInfo*)this; + do { + if (o->Tree () && o->Tree ()->NodeName () == CT_FctDef::NodeId ()) + if (! o->TemplateInstance () || o->TemplateInstance ()->canInstantiate ()) + return o->FunctionInfo (); + o = o->NextObject (); + } while (o != (CObjectInfo*)this); + return (CFunctionInfo*)this; +} + +CTree *CFunctionInfo::DefaultArgument (unsigned pos) const { + CFunctionInfo *f = (CFunctionInfo*)this; + do { + if (f->Arguments () > pos && f->Argument (pos)->hasDefaultArg ()) + return f->Argument (pos)->Init (); + f = f->NextObject ()->FunctionInfo (); + } while (f != (CFunctionInfo*)this); + return (CTree*)0; +} + +bool CFunctionInfo::hasDefaultArgument (unsigned a) const { + CFunctionInfo *f = (CFunctionInfo*)this; + do { + if (f->Arguments () > a && f->Argument (a)->hasDefaultArg ()) + return true; + f = f->NextObject ()->FunctionInfo (); + } while (f != (CFunctionInfo*)this); + return false; +} + +CRecord *CFunctionInfo::Record () const { + return CObjectInfo::QualifiedScope () ? CObjectInfo::QualifiedScope ()->Record () : (CRecord*)0; +} + +CNamespaceInfo *CFunctionInfo::Namespace () const { + return CObjectInfo::QualifiedScope () ? CObjectInfo::QualifiedScope ()->NamespaceInfo () : (CNamespaceInfo*)0; +} + +bool CFunctionInfo::hasSameNameAndArgs (const CFunctionInfo *fi) const { + // first the names are compared + if (Name () != fi->Name ()) + return false; + + // now the argument types are checked + CTypeList *my_types = TypeInfo ()->TypeFunction ()->ArgTypes (); + CTypeList *other_types = fi->TypeInfo ()->TypeFunction ()->ArgTypes (); + if (my_types->Entries () != other_types->Entries ()) + return false; + for (unsigned i = 0; i < my_types->Entries (); i++) { + if (*my_types->Entry (i) != *other_types->Entry (i)) + return false; + } + // all argument types are identical and the function name as well! + return true; +} + +bool CFunctionInfo::overridesVirtual () const { + // the function has to be a non-static member function + if (!isMethod () || isStaticMethod ()) + return false; + + CClassInfo *cls = TypeInfo ()->TypeFunction ()->Record ()->ClassInfo (); + return cls->overridesVirtual (this); +} + +/** Check if this is a default constructor. */ +bool CFunctionInfo::isDefaultConstructor () const { + // §12.1p5 + // A default constructor for a class X is a constructor of class X + // that can be called without an argument. + if (! isConstructor ()) + return false; + // check the parameters + for (unsigned i = 0; i < Arguments (); i++) + if (! Argument (i)->hasDefaultArg ()) + return false; + return true; +} + +/** Check if this is a copy constructor. */ +bool CFunctionInfo::isCopyConstructor () const { + // §12.8p2 + // A non-template constructor for class X is a copy constructor if its + // first parameter is of type X&, const X&, volatile X& or const volatile X&, + // and either there are no other parameters or else all other parameters have + // default arguments. + if (! isConstructor () || isTemplate () || Arguments () == 0) + return false; + + // get class + CRecord* c = Record (); + if (! c) + return false; + + // check first parameter + CTypeInfo* arg = Argument ((unsigned)0)->TypeInfo (); + if (! arg->isAddress () || + ! arg->isClassOrUnion () || + *arg->VirtualType ()->TypeRecord () != *c->TypeInfo ()) + return false; + + // check the other parameters + for (unsigned i = 1; i < Arguments (); i++) + if (! Argument (i)->hasDefaultArg ()) + return false; + return true; +} + +/** Check if this is a copy assignment operator. */ +bool CFunctionInfo::isCopyAssignOperator () const { + // 12.8p9 + // A copy assignment operator X::operator= is a non-static non-template + // member function of class X with exactly one parameter of type X, X&, + // const X&, volatile X& or const volatile X&. + if (! isOperator () || isStatic () || isTemplate () || Arguments () != 1) + return false; + + // assignment operator + if (Name ().c_str () && strcmp (Name ().c_str (), "operator =") != 0) + return false; + + // get class + CRecord* c = Record (); + if (! c) + return false; + + // check parameter + CTypeInfo* arg = Argument ((unsigned)0)->TypeInfo (); + if (! arg->isClassOrUnion ()) + return false; + if (arg->isAddress () && *arg->VirtualType ()->TypeRecord () == *c->TypeInfo ()) + return true; + if (arg->TypeRecord () && *arg->TypeRecord () == *c->TypeInfo ()) + return true; + return false; +} + +} // namespace Puma diff --git a/Puma/src/infos/CFunctionInfo.h b/Puma/src/infos/CFunctionInfo.h new file mode 100644 index 0000000..e2fdd5d --- /dev/null +++ b/Puma/src/infos/CFunctionInfo.h @@ -0,0 +1,289 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CFunctionInfo_h__ +#define __CFunctionInfo_h__ + +/** \file + * Semantic information about a function. */ + +#include "Puma/CStructure.h" +#include "Puma/Array.h" + +namespace Puma { + + +class CArgumentInfo; +class CLabelInfo; +class CRecord; +class CNamespaceInfo; +class CTemplateInfo; +class CTypeFunction; + + +/** \class CFunctionInfo CFunctionInfo.h Puma/CFunctionInfo.h + * Semantic information about a function, method, overloaded + * operator, or user conversion function. */ +class CFunctionInfo : public CStructure { + Array _Arguments; + Array _Labels; + + CTypeInfo *_ConversionType; + CTemplateInfo *_TemplateInfo; + bool _isTemplate; + + enum MethodType { + NONE, + CONSTRUCTOR, + DESTRUCTOR, + OPERATOR, + CONVERSION + } _MethodType; + +protected: + /** Constructor. + * \param id The object type. */ + CFunctionInfo (ObjectId id); + +public: + /** Constructor. */ + CFunctionInfo (); + /** Destructor. If the object type is CObjectInfo::FUNCTION_INFO, + * then CObjectInfo::CleanUp() is called. */ + ~CFunctionInfo (); + + /** Get the semantic object of the function definition. + * \see CObjectInfo::DefObject() */ + CFunctionInfo *DefObject () const; + /** Get the type information for the function. */ + CTypeFunction *TypeInfo () const; + /** Get the conversion type if this is a conversion function. + * \return The conversion type or NULL if not a conversion function. */ + CTypeInfo *ConversionType () const; + /** Get the return type of the function. */ + CTypeInfo *ReturnType () const; + /** Get the template information if this is a function template. + * \return The template information or NULL if not a function template. */ + CTemplateInfo *TemplateInfo () const; + /** Get the class or union if this is a method of a class or union. + * \return The class/union or NULL if not a method. */ + CRecord *Record () const; + /** Get the namespace if this function is declared in a namespace. + * \return The namespace or NULL if not declared in a namespace. */ + CNamespaceInfo *Namespace () const; + + /** Get the number of jump labels defined in the function body. */ + unsigned Labels () const; + /** Get the number of function parameters. */ + unsigned Arguments () const; + /** Get the n-th jump label. + * \param n The index of the jump label. + * \return The label or NULL if \e n is invalid. */ + CLabelInfo *Label (unsigned n) const; + /** Get the jump label with the given name. + * \param name The name of the jump label. + * \return The label or NULL if no such label. */ + CLabelInfo *Label (const char *name) const; + /** Get the n-th function parameter. + * \param n The index of the function parameter. + * \return The function parameter or NULL if \e n is invalid. */ + CArgumentInfo *Argument (unsigned n) const; + /** Get the function parameter with the given name. + * \param name The name of the function parameter. + * \return The function parameter or NULL if no such parameter. */ + CArgumentInfo *Argument (const char *name) const; + /** Get the default argument of the n-th function parameter. + * \param n The index of the function parameter. + * \return The syntax tree node of the default argument or + * NULL if the n-th parameter has no default argument. */ + CTree *DefaultArgument (unsigned n) const; + + /** Set the conversion type of a conversion function. + * \param type The conversion type. */ + void ConversionType (CTypeInfo *type); + /** Set the qualification scope of a class/union method or + * function declared in a namespace. + * \param scope The qualification scope. */ + void QualifiedScope (CStructure *scope); + /** Add a function parameter. + * \param info The function parameter. */ + void addArgument (CArgumentInfo *info); + /** Add a jump label. + * \param label The jump label. */ + void addLabel (CLabelInfo *label); + /** Remove the given function parameter. + * \param info The function parameter. */ + void removeArgument (const CArgumentInfo *info); + /** Remove the given jump label. + * \param label The jump label. */ + void removeLabel (const CLabelInfo *label); + /** Set the template information of a function template. + * \param info The template information. */ + void TemplateInfo (CTemplateInfo *info); + /** Set whether the function is a function template. + * \param v \c true if the function is a template. */ + void isTemplate (bool v); + + /** Create a new function parameter. The new function parameter + * is added to the function. */ + CArgumentInfo *newArgument (); + /** Create a new jump label. The new jump label is added + * to the function. */ + CLabelInfo *newLabel (); + /** Remove and destroy the given function parameter. + * \param info The function parameter. */ + void deleteArgument (const CArgumentInfo *info); + /** Remove and destroy the given jump label. + * \param info The jump label. */ + void deleteLabel (const CLabelInfo *info); + + /** Check if the function accepts a variable argument list. */ + bool hasEllipsis () const; + /** Check if the n-th function parameter has a default argument. + * \param n The index of the function parameter. */ + bool hasDefaultArgument (unsigned n) const; + + /** Check if this is a function definition. */ + bool isFctDef () const; + /** Check if this is a method of a class or union. */ + bool isMethod () const; + /** Check if this is a static method of a class or union. */ + bool isStaticMethod () const; + /** Check if this is a function template. */ + bool isTemplate () const; + /** Check if the function is defined. */ + bool isDefined () const; + /** Check if this is a destructor. */ + bool isDestructor () const; + /** Check if this is a constructor. */ + bool isConstructor () const; + /** Check if this is an overloaded operator. */ + bool isOperator () const; + /** Check if this is a conversion function. */ + bool isConversion () const; + /** Check if the function is pure virtual. */ + bool isPureVirtual () const; + /** Check if this is a default constructor. */ + bool isDefaultConstructor () const; + /** Check if this is a copy constructor. */ + bool isCopyConstructor () const; + /** Check if this is a copy assignment operator. */ + bool isCopyAssignOperator () const; + + /** Set whether the function is a destructor. + * \param v \e true if the function is a destructor. */ + void isDestructor (bool v); + /** Set whether the function is a constructor. + * \param v \e true if the function is a constructor. */ + void isConstructor (bool v); + /** Set whether the function is an overloaded operator. + * \param v \e true if the function is an overloaded operator. */ + void isOperator (bool v); + /** Set whether the function is a conversion function. + * \param v \e true if the function is a conversion function. */ + void isConversion (bool v); + + /** Check if the given function has the same name and + * parameter types as this function. + * \param fi The function to compare with. */ + bool hasSameNameAndArgs (const CFunctionInfo *fi) const; + + /** Check if the function is a non-static member function and if + * in any of the base classes there is a function definition of a + * virtual function with the same name and argument types. */ + bool overridesVirtual () const; +}; + +inline CFunctionInfo::CFunctionInfo (ObjectId id) : + CStructure (id), + _Arguments (1, 2), + _Labels (1, 2), + _ConversionType ((CTypeInfo*)0), + _TemplateInfo ((CTemplateInfo*)0), + _isTemplate (false), + _MethodType (NONE) + {} +inline CFunctionInfo::CFunctionInfo () : + CStructure (CObjectInfo::FUNCTION_INFO), + _Arguments (1, 2), + _Labels (1, 2), + _ConversionType ((CTypeInfo*)0), + _TemplateInfo ((CTemplateInfo*)0), + _isTemplate (false), + _MethodType (NONE) + {} + +inline CTypeInfo *CFunctionInfo::ConversionType () const + { return _ConversionType; } +inline void CFunctionInfo::ConversionType (CTypeInfo *t) + { _ConversionType = t; } + +inline CTypeFunction *CFunctionInfo::TypeInfo () const + { return (CTypeFunction*)CObjectInfo::TypeInfo (); } + +inline unsigned CFunctionInfo::Arguments () const + { return _Arguments.length (); } +inline CArgumentInfo *CFunctionInfo::Argument (unsigned n) const + { return _Arguments.lookup (n); } +inline unsigned CFunctionInfo::Labels () const + { return _Labels.length (); } +inline CLabelInfo *CFunctionInfo::Label (unsigned n) const + { return _Labels.lookup (n); } + +inline void CFunctionInfo::QualifiedScope (CStructure *s) + { _QualScope = s; } + +inline bool CFunctionInfo::isDestructor () const + { return _MethodType == DESTRUCTOR; } +inline bool CFunctionInfo::isConstructor () const + { return _MethodType == CONSTRUCTOR; } +inline bool CFunctionInfo::isOperator () const + { return _MethodType == OPERATOR; } +inline bool CFunctionInfo::isConversion () const + { return _MethodType == CONVERSION; } +inline bool CFunctionInfo::isMethod () const + { return (Record ()); } +inline bool CFunctionInfo::isStaticMethod () const + { return (isMethod () && isStatic ()); } + +inline void CFunctionInfo::isDestructor (bool v) + { if (v) _MethodType = DESTRUCTOR; } +inline void CFunctionInfo::isConstructor (bool v) + { if (v) _MethodType = CONSTRUCTOR; } +inline void CFunctionInfo::isOperator (bool v) + { if (v) _MethodType = OPERATOR; } +inline void CFunctionInfo::isConversion (bool v) + { if (v) _MethodType = CONVERSION; } + +inline bool CFunctionInfo::isTemplate () const + { return _isTemplate; } +inline void CFunctionInfo::isTemplate (bool v) + { _isTemplate = v; } + +inline CTemplateInfo *CFunctionInfo::TemplateInfo () const + { return _TemplateInfo; } +inline void CFunctionInfo::TemplateInfo (CTemplateInfo *info) + { _TemplateInfo = info; } + +//inline bool CFunctionInfo::isRedefined () const +// { return BaseObject () && ! isInherited (); } + + +} // namespace Puma + +#endif /* __CFunctionInfo_h__ */ diff --git a/Puma/src/infos/CLabelInfo.cc b/Puma/src/infos/CLabelInfo.cc new file mode 100644 index 0000000..edfcf08 --- /dev/null +++ b/Puma/src/infos/CLabelInfo.cc @@ -0,0 +1,29 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CLabelInfo.h" +#include "Puma/CFunctionInfo.h" + +namespace Puma { + + +CLabelInfo::~CLabelInfo () { +} + + +} // namespace Puma diff --git a/Puma/src/infos/CLabelInfo.h b/Puma/src/infos/CLabelInfo.h new file mode 100644 index 0000000..df89cfe --- /dev/null +++ b/Puma/src/infos/CLabelInfo.h @@ -0,0 +1,49 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CLabelInfo_h__ +#define __CLabelInfo_h__ + +/** \file + * Semantic information about a jump label. */ + +#include "Puma/CScopeRequest.h" + +namespace Puma { + + +/** \class CLabelInfo CLabelInfo.h Puma/CLabelInfo.h + * Semantic information about a jump label. Jump labels + * are used as argument of goto-statements. */ +class CLabelInfo : public CScopeRequest { +public: + /** Constructor. */ + CLabelInfo (); + /** Destructor. If the object type is CObjectInfo::LABEL_INFO, + * CObjectInfo::CleanUp() is called. */ + ~CLabelInfo (); +}; + +inline CLabelInfo::CLabelInfo () : + CScopeRequest (CObjectInfo::LABEL_INFO) + {} + + +} // namespace Puma + +#endif /* __CLabelInfo_h__ */ diff --git a/Puma/src/infos/CLocalScope.cc b/Puma/src/infos/CLocalScope.cc new file mode 100644 index 0000000..6527462 --- /dev/null +++ b/Puma/src/infos/CLocalScope.cc @@ -0,0 +1,41 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CLocalScope.h" +#include "Puma/CFunctionInfo.h" + +namespace Puma { + + +CLocalScope *CLocalScope::Top () const { + CLocalScope *ls = (CLocalScope*)this; + while (ls->Parent () && ls->Parent () != (CScopeInfo*)this && + ls->Parent ()->LocalScope ()) + ls = ls->Parent ()->LocalScope (); + return ls; +} + +CFunctionInfo *CLocalScope::Function () const { + CLocalScope *top = Top (); + if (top && top->Parent ()) + return top->Parent ()->FunctionInfo (); + return (CFunctionInfo*)0; +} + + +} // namespace Puma diff --git a/Puma/src/infos/CLocalScope.h b/Puma/src/infos/CLocalScope.h new file mode 100644 index 0000000..98864fc --- /dev/null +++ b/Puma/src/infos/CLocalScope.h @@ -0,0 +1,67 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CLocalScope_h__ +#define __CLocalScope_h__ + +/** \file + * Semantic information about a local scope in a function body. */ + +#include "Puma/CStructure.h" + +namespace Puma { + + +class CFunctionInfo; + +/** \class CLocalScope CLocalScope.h Puma/CLocalScope.h + * Semantic information about a local scope in a function + * body, also called block scope. + * + * Examples for local scopes: + * \code + * { } + * if (...) ; + * while (...) { } + * \endcode */ +class CLocalScope : public CStructure { +public: + /** Constructor. */ + CLocalScope (); + /** Destructor. If the object type is CObjectInfo::LOCAL_INFO, + * then CObjectInfo::CleanUp() is called. */ + ~CLocalScope (); + + /** Get the outermost local scope in a nested hierarchy + * of local scopes. */ + CLocalScope* Top () const; + /** Get the function containing the local scope. + * \return The function or NULL if no function found. */ + CFunctionInfo* Function () const; +}; + +inline CLocalScope::CLocalScope () : + CStructure (CObjectInfo::LOCAL_INFO) + {} +inline CLocalScope::~CLocalScope () + {} + + +} // namespace Puma + +#endif /* __CLocalScope_h__ */ diff --git a/Puma/src/infos/CMemberAliasInfo.cc b/Puma/src/infos/CMemberAliasInfo.cc new file mode 100644 index 0000000..0248782 --- /dev/null +++ b/Puma/src/infos/CMemberAliasInfo.cc @@ -0,0 +1,29 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CMemberAliasInfo.h" +#include "Puma/CStructure.h" + +namespace Puma { + + +CMemberAliasInfo::~CMemberAliasInfo () { +} + + +} // namespace Puma diff --git a/Puma/src/infos/CMemberAliasInfo.h b/Puma/src/infos/CMemberAliasInfo.h new file mode 100644 index 0000000..1951806 --- /dev/null +++ b/Puma/src/infos/CMemberAliasInfo.h @@ -0,0 +1,64 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CMemberAliasInfo_h__ +#define __CMemberAliasInfo_h__ + +/** \file + * Semantic information about a member alias. */ + +#include "Puma/CScopeRequest.h" + +namespace Puma { + + +/** \class CMemberAliasInfo CMemberAliasInfo.h Puma/infos/CMemberAliasInfo.h + * Semantic information about a member alias. A member alias + * is created by a using-declaration. */ +class CMemberAliasInfo : public CScopeRequest { + CObjectInfo *_Member; + +public: + /** Constructor. */ + CMemberAliasInfo (); + /** Destructor. If the object type is CObjectInfo::MEMBERALIAS_INFO, + * then CObjectInfo::CleanUp() is called. */ + ~CMemberAliasInfo (); + + /** Get the semantic information about the original member + * for which this is an alias. */ + CObjectInfo *Member () const; + /** Set the original member for which this is an alias. + * \param info The original member. */ + void Member (CObjectInfo *info); +}; + +inline CMemberAliasInfo::CMemberAliasInfo () : + CScopeRequest (CObjectInfo::MEMBERALIAS_INFO), + _Member ((CObjectInfo*)0) + {} + +inline CObjectInfo *CMemberAliasInfo::Member () const + { return _Member; } +inline void CMemberAliasInfo::Member (CObjectInfo *m) + { _Member = m; } + + +} // namespace Puma + +#endif /* __CMemberAliasInfo_h__ */ diff --git a/Puma/src/infos/CNamespaceInfo.cc b/Puma/src/infos/CNamespaceInfo.cc new file mode 100644 index 0000000..dc24cbd --- /dev/null +++ b/Puma/src/infos/CNamespaceInfo.cc @@ -0,0 +1,28 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CNamespaceInfo.h" + +namespace Puma { + + +CNamespaceInfo::~CNamespaceInfo () { +} + + +} // namespace Puma diff --git a/Puma/src/infos/CNamespaceInfo.h b/Puma/src/infos/CNamespaceInfo.h new file mode 100644 index 0000000..c5b68f1 --- /dev/null +++ b/Puma/src/infos/CNamespaceInfo.h @@ -0,0 +1,89 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CNamespaceInfo_h__ +#define __CNamespaceInfo_h__ + +/** \file + * Semantic information about a namespace. */ + +#include "Puma/CStructure.h" + +namespace Puma { + + +/** \class CNamespaceInfo CNamespaceInfo.h Puma/CNamespaceInfo.h + * Semantic information about a user-defined namespace. + * There are two kinds of namespaces, original namespaces and + * namespace aliases. */ +class CNamespaceInfo : public CStructure { + bool _isAlias; + bool _aroundInstantiation; + +protected: + /** Constructor. + * \param id The object type. */ + CNamespaceInfo (ObjectId id); + +public: + /** Constructor. */ + CNamespaceInfo (); + /** Destructor. If the object type is CObjectInfo::NAMESPACE_INFO, + * then CObjectInfo::CleanUp() is called. */ + ~CNamespaceInfo (); + + /** Check if this is a namespace alias. */ + bool isAlias () const; + /** Set whether this is a namespace alias. + * \param v \e true if it is a namespace alias. */ + void isAlias (bool v); + + /** Check if this is a special internal namespace + * around template instantiations. */ + bool aroundInstantiation () const; + /** Set whether this is a special internal namespace around + * template instantiations. + * \param v \e true if it is such an internal namespace. */ + void aroundInstantiation (bool v); +}; + +inline CNamespaceInfo::CNamespaceInfo (CObjectInfo::ObjectId id) : + CStructure (id), + _isAlias (false), + _aroundInstantiation (false) + {} +inline CNamespaceInfo::CNamespaceInfo () : + CStructure (CObjectInfo::NAMESPACE_INFO), + _isAlias (false), + _aroundInstantiation (false) + {} + +inline bool CNamespaceInfo::isAlias () const + { return _isAlias; } +inline void CNamespaceInfo::isAlias (bool v) + { _isAlias = v; } + +inline bool CNamespaceInfo::aroundInstantiation () const + { return _aroundInstantiation; } +inline void CNamespaceInfo::aroundInstantiation (bool v) + { _aroundInstantiation = v; } + + +} // namespace Puma + +#endif /* __CNamespaceInfo_h__ */ diff --git a/Puma/src/infos/CObjectInfo.cc b/Puma/src/infos/CObjectInfo.cc new file mode 100644 index 0000000..e322d1f --- /dev/null +++ b/Puma/src/infos/CObjectInfo.cc @@ -0,0 +1,433 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CObjectInfo.h" +#include "Puma/CScopeInfo.h" +#include "Puma/CTypeInfo.h" +#include "Puma/CFileInfo.h" +#include "Puma/CClassInfo.h" +#include "Puma/CUnionInfo.h" +#include "Puma/CEnumInfo.h" +#include "Puma/CLabelInfo.h" +#include "Puma/CLocalScope.h" +#include "Puma/CTypedefInfo.h" +#include "Puma/CEnumInfo.h" +#include "Puma/CEnumeratorInfo.h" +#include "Puma/CAttributeInfo.h" +#include "Puma/CArgumentInfo.h" +#include "Puma/CFunctionInfo.h" +#include "Puma/CTemplateInfo.h" +#include "Puma/CClassInstance.h" +#include "Puma/CFctInstance.h" +#include "Puma/CUnionInstance.h" +#include "Puma/CTemplateParamInfo.h" +#include "Puma/CMemberAliasInfo.h" +#include "Puma/CBaseClassInfo.h" +#include "Puma/CUsingInfo.h" +#include "Puma/CNamespaceInfo.h" +#include "Puma/CTree.h" +#include "Puma/Array.h" +#include "Puma/StrCol.h" +#include +#include +#include +#include + +namespace Puma { + + +CObjectInfo::~CObjectInfo () { + CTypeInfo::Destroy (_TypeInfo); + if (_QualName) + delete[] _QualName; +} + +void CObjectInfo::Unregister (CStructure *scope) { + for (unsigned i = 0; i < (unsigned)_Registered.length (); i++) + if (_Registered.lookup (i) == scope) + _Registered.remove (i); +} + +bool CObjectInfo::isRegistered (const CStructure *scope) const { + for (unsigned i = 0; i < (unsigned)_Registered.length (); i++) + if (_Registered.lookup (i) == scope) + return true; + return false; +} + +void CObjectInfo::NextObject (CObjectInfo *o) { + if (o && o != this) { + o->_Next = _Next; + o->_Prev = this; + _Next->_Prev = o; + _Next = o; + } +} + +void CObjectInfo::PrevObject (CObjectInfo *o) { + if (o && o != this) { + o->_Prev = _Prev; + o->_Next = this; + _Prev->_Next = o; + _Prev = o; + } +} + +void CObjectInfo::Unlink () { + // remove from qualified scope + if (QualifiedScope ()) { + QualifiedScope ()->removeObject (this); + } + // remove from assigned scope + if (AssignedScope ()) { + AssignedScope ()->removeObject (this); + } + + // cleanup template instance + if (TemplateInstance () && TemplateInstance ()->Template ()) { + TemplateInstance ()->Template ()->removeInstance (this); + } + // cleanup CArgumentInfo + if (ArgumentInfo ()) { + if (ArgumentInfo ()->Scope () && ArgumentInfo ()->Scope ()->FunctionInfo ()) + ArgumentInfo ()->Scope ()->FunctionInfo ()->removeArgument (ArgumentInfo ()); + } + // cleanup CAttributeInfo + if (AttributeInfo ()) { + if (AttributeInfo ()->Scope () && AttributeInfo ()->Scope ()->Structure ()) + AttributeInfo ()->Scope ()->Structure ()->removeAttribute (AttributeInfo ()); + } + // cleanup CBaseClassInfo + if (BaseClassInfo ()) { + if (BaseClassInfo ()->Scope () && BaseClassInfo ()->Scope ()->ClassInfo ()) { + CClassInfo *cinfo = BaseClassInfo ()->Scope ()->ClassInfo (); + if (BaseClassInfo ()->Class ()) + BaseClassInfo ()->Class ()->removeDerivedClass (cinfo); + cinfo->removeBaseClass (BaseClassInfo ()); + } + } + // cleanup CClassInfo + if (ClassInfo ()) { + for (unsigned i = 0; i < ClassInfo ()->BaseClasses (); i++) { + CBaseClassInfo *info = ClassInfo ()->BaseClass (i); + info->Class ()->removeDerivedClass (ClassInfo ()); + } + for (unsigned i = 0; i < ClassInfo ()->DerivedClasses (); i++) + ClassInfo ()->DerivedClass (i)->removeBaseClass (ClassInfo ()); + } + // cleanup CEnumInfo + if (EnumInfo ()) { + if (EnumInfo ()->Scope () && EnumInfo ()->Scope ()->Structure ()) + EnumInfo ()->Scope ()->Structure ()->removeType (EnumInfo ()); + } + // cleanup CEnumeratorInfo + if (EnumeratorInfo ()) { + if (EnumeratorInfo ()->Enum ()) + EnumeratorInfo ()->Enum ()->removeEnumerator (EnumeratorInfo ()); + } + // cleanup CFunctionInfo + if (FunctionInfo ()) { + CScopeInfo *parent = FunctionInfo ()->Parent (); + if (parent && parent->Structure ()) + parent->Structure ()->removeFunction (FunctionInfo ()); + if (FunctionInfo ()->AssignedScope ()) + FunctionInfo ()->AssignedScope ()->removeFunction (FunctionInfo ()); + } + // cleanup CLabelInfo + if (LabelInfo ()) { + if (LabelInfo ()->Scope () && LabelInfo ()->Scope ()->FunctionInfo ()) + LabelInfo ()->Scope ()->FunctionInfo ()->removeLabel (LabelInfo ()); + } + // cleanup CMemberAliasInfo + if (MemberAliasInfo ()) { + if (MemberAliasInfo ()->Scope () && MemberAliasInfo ()->Scope ()->Structure ()) + MemberAliasInfo ()->Scope ()->Structure ()->removeMemberAlias (MemberAliasInfo ()); + } + // cleanup CTypedefInfo + if (TypedefInfo ()) { + if (TypedefInfo ()->Scope () && TypedefInfo ()->Scope ()->Structure ()) + TypedefInfo ()->Scope ()->Structure ()->removeType (TypedefInfo ()); + } + // cleanup CUsingInfo + if (UsingInfo ()) { + if (UsingInfo ()->Scope () && UsingInfo ()->Scope ()->Structure ()) + UsingInfo ()->Scope ()->Structure ()->removeUsing (UsingInfo ()); + } + // cleanup CTemplateParamInfo + if (TemplateParamInfo ()) { + if (TemplateParamInfo ()->TemplateInfo ()) + TemplateParamInfo ()->TemplateInfo ()->removeTemplateParam (TemplateParamInfo ()); + } + // cleanup CTemplateInfo + if (TemplateInfo ()) { + CTemplateInfo *templ = TemplateInfo (); + if (templ->isSpecialization () && templ->BaseTemplate ()) + templ->BaseTemplate ()->removeSpecialization (templ); + } + // cleanup CRecord + if (Record ()) { + CScopeInfo *parent = Record ()->Parent (); + if (parent && parent->Structure ()) + parent->Structure ()->removeType (Record ()); + if (Record ()->AssignedScope ()) + Record ()->AssignedScope ()->removeType (Record ()); + } + // cleanup CNamespaceInfo + if (NamespaceInfo ()) { + CScopeInfo *parent = NamespaceInfo ()->Parent (); + if (parent && parent->Structure ()) + parent->Structure ()->removeNamespace (NamespaceInfo ()); + } + // cleanup CScopeInfo + if (ScopeInfo ()) { + if (ScopeInfo ()->Parent () && ScopeInfo ()->Parent () != ScopeInfo ()) + ScopeInfo ()->Parent ()->removeChild (ScopeInfo ()); + } + // cleanup CStructure + if (Structure ()) + Structure ()->removeRegisterEntry (); + + // cleanup CObjectInfo + _Prev->_Next = _Next; + _Next->_Prev = _Prev; + _Next = this; + _Prev = this; + _Tree = 0; + + // cleanup symbol table + if (! Name().empty()) + for (unsigned i = _Registered.length (); i > 0; i--) + _Registered.lookup (i-1)->removeNamedObject (Name (), this); +} + +CTemplateInstance *CObjectInfo::TemplateInstance () const { + if (ClassInstance ()) + return ClassInstance ()->TemplateInstance (); + else if (FctInstance ()) + return FctInstance ()->TemplateInstance (); + else if (UnionInstance ()) + return UnionInstance ()->TemplateInstance (); + else if (TemplateParamInfo ()) + return TemplateParamInfo ()->TemplateInstance (); + return (CTemplateInstance*)0; +} + +bool CObjectInfo::isTemplateInstance () const { + return (ClassInstance () || UnionInstance () || FctInstance () || + (TemplateParamInfo () && TemplateParamInfo ()->TemplateInstance ())); +} + +bool CObjectInfo::isClassMember () const { + return AttributeInfo () ? AttributeInfo ()->Record () : + FunctionInfo () ? FunctionInfo ()->Record () : (CRecord*)0; +} + +CRecord *CObjectInfo::ClassScope () const { + if (AttributeInfo ()) + return AttributeInfo ()->Record (); + if (FunctionInfo ()) + return FunctionInfo ()->Record (); + return (CRecord*)0; +} + +bool CObjectInfo::operator ==(const CObjectInfo &info) const { + CObjectInfo *oi1, *oi2; + oi1 = (CObjectInfo*)this; + oi2 = (CObjectInfo*)(&info); + do { + if (oi1 == oi2) + return true; + oi1 = oi1->NextObject (); + } while (oi1 != (CObjectInfo*)this); + return false; +} + +CScopeInfo *CObjectInfo::Scope () const { + if (ScopeInfo ()) + return ScopeInfo ()->Parent (); + else + return TypedefInfo () ? TypedefInfo ()->Scope () : + EnumInfo () ? EnumInfo ()->Scope () : + MemberAliasInfo () ? MemberAliasInfo ()->Scope () : + EnumeratorInfo () ? EnumeratorInfo ()->Scope () : + AttributeInfo () ? AttributeInfo ()->Scope () : + TemplateParamInfo () ? TemplateParamInfo ()->TemplateInfo () : + ArgumentInfo () ? ArgumentInfo ()->Scope () : + LabelInfo () ? LabelInfo ()->Scope () : + (CScopeInfo*)0; // Should never be reached. +} + +bool CObjectInfo::isTemplate () const { + return Record () ? Record ()->isTemplate () : + FunctionInfo () ? FunctionInfo ()->isTemplate () : + TemplateParamInfo () ? TemplateParamInfo ()->isTemplate () : false; +} + +void CObjectInfo::TypeInfo (CTypeInfo *info) { + _TypeInfo = info; +} + +void CObjectInfo::Name (const DString& name) { + CObjectInfo *scope = this->AssignedScope (); + if (! scope) { + scope = this->Scope (); + } + CStructure *scopeStruct = 0; + if (scope) { + scopeStruct = scope->Structure (); + } + + if (scopeStruct && ! _Name.empty ()) { + scopeStruct->removeNamedObject (name, this); + } + _Name = name; + if (scopeStruct) { + scopeStruct->addNamedObject (this); + } +} + +const char *CObjectInfo::QualName (bool abs, bool tdef, bool unnamed) { + if ((! _QualName && ! _Name.empty()) || abs != _abs || tdef != _tdef || unnamed != _unnamed) { + CObjectInfo *obj = this; + // get the scope object + CScopeInfo *info = obj->QualifiedScope (); + if (!info) info = obj->AssignedScope (); + if (!info) info = obj->Scope (); + + // if this an anonymous (generated) template scope, skip it + while (info && info->isNamespace () && info->isAnonymous () && + !info->GlobalScope () && + (!unnamed || strcmp(info->Name (), "") != 0)) { + info = info->Scope (); + } + + std::ostringstream qname; + if (info->TypeInfo () && info->TypeInfo ()->isRecord ()) { + // if the scope has an associated type we can use CTypeInfo::TypeText () + info->TypeInfo ()->TypeText (qname, 0, abs, tdef, false, unnamed); + qname << "::"; + } + else { + // if the scope is not a type we run through all the namespace + Array scopes; + while (info && ((unnamed && strcmp(info->Name(), "") == 0) || + ! info->isAnonymous ()) && + (info->Record () || + (info->NamespaceInfo () && ! info->FileInfo ()))) { + scopes.append (info->Name ()); + info = info->Scope (); + } + if (abs) + qname << "::"; + for (long i = scopes.length () - 1; i >= 0; i--) + qname << scopes.lookup (i) << "::"; + } + qname << _Name.c_str (); + _QualName = StrCol::dup (qname.str ().c_str ()); + + // remember these parameters, because on a different request the name + // has to be regenerated + _abs = abs; + _tdef = tdef; + _unnamed = unnamed; + } + return _QualName; +} + +CObjectInfo *CObjectInfo::DefObject () const { + if (ClassInfo ()) + return ClassInfo ()->DefObject (); + else if (UnionInfo ()) + return UnionInfo ()->DefObject (); + else if (FunctionInfo ()) + return FunctionInfo ()->DefObject (); + else if (EnumInfo ()) + return EnumInfo ()->DefObject (); + return ObjectInfo (); +} + +CTemplateInfo *CObjectInfo::Template () const { + return Record () ? Record ()->TemplateInfo () : + FunctionInfo () ? FunctionInfo ()->TemplateInfo () : + TemplateParamInfo () ? TemplateParamInfo ()->TemplateInfo () : + (CTemplateInfo*)0; +} + +bool CObjectInfo::isType () const { + if (_Id == MEMBERALIAS_INFO) + return MemberAliasInfo ()->Member () && + MemberAliasInfo ()->Member ()->isType (); + if (_Id == TEMPLATE_PARAM_INFO) + return TemplateParamInfo ()->isTemplate () || + TemplateParamInfo ()->isTypeParam (); + return _Id == UNION_INFO || + _Id == CLASS_INFO || + _Id == ENUM_INFO || + _Id == TYPEDEF_INFO || + _Id == CLASS_INSTANCE_INFO || + _Id == UNION_INSTANCE_INFO; +} + +bool CObjectInfo::isObject () const { + if (_Id == MEMBERALIAS_INFO) + return MemberAliasInfo ()->Member () && + MemberAliasInfo ()->Member ()->isObject (); + if (_Id == TEMPLATE_PARAM_INFO) + return ! TemplateParamInfo ()->isTemplate () && + ! TemplateParamInfo ()->isTypeParam (); + return _Id == FUNCTION_INFO || + _Id == ENUMERATOR_INFO || + _Id == ATTRIBUTE_INFO || + _Id == FCT_INSTANCE_INFO || + _Id == ARGUMENT_INFO; +} + +/** Check if the entity is local. An entity is local if it was + * declared in a local scope. */ +bool CObjectInfo::isLocal () const { + if (LocalScope ()) + return true; + if (FileInfo ()) + return false; + CScopeInfo* scope = Scope (); + return scope && scope->isLocal (); +} + +CTree *CObjectInfo::Init () const { + if (_Id == ATTRIBUTE_INFO) + return ((CAttributeInfo*)this)->Init (); + + CT_ExprList* el = 0; + CTree* tree = Tree (); + if (tree) { + if (_Id == FUNCTION_INFO || _Id == FCT_INSTANCE_INFO) { + if (tree->NodeName () == CT_InitDeclarator::NodeId ()) + el = ((CT_InitDeclarator*)tree)->Initializer (); + } else if (_Id == ENUMERATOR_INFO) { + if (tree->NodeName () == CT_Enumerator::NodeId ()) + el = ((CT_Enumerator*)tree)->Initializer (); + } else if (_Id == ARGUMENT_INFO) { + if (tree->NodeName () == CT_ArgDecl::NodeId ()) + el = ((CT_ArgDecl*)tree)->Initializer (); + } + } + return el && el->Entries () > 0 ? el->Entry (0) : 0; +} + + +} // namespace Puma diff --git a/Puma/src/infos/CObjectInfo.h b/Puma/src/infos/CObjectInfo.h new file mode 100644 index 0000000..d612657 --- /dev/null +++ b/Puma/src/infos/CObjectInfo.h @@ -0,0 +1,825 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CObjectInfo_h__ +#define __CObjectInfo_h__ + +/** \file + * Basic semantic information class. */ + +#include "Puma/CSourceInfo.h" +#include "Puma/CProtection.h" +#include "Puma/CStorage.h" +#include "Puma/CLinkage.h" +#include "Puma/CLanguage.h" +#include "Puma/CSpecifiers.h" +#include "Puma/Array.h" +#include "Puma/DString.h" + +namespace Puma { + + +class CRecord; +class CStructure; +class CFileInfo; +class CClassInfo; +class CBaseClassInfo; +class CMemberAliasInfo; +class CTypeInfo; +class CScopeInfo; +class CLabelInfo; +class CUnionInfo; +class CLocalScope; +class CEnumInfo; +class CUsingInfo; +class CEnumeratorInfo; +class CTypedefInfo; +class CFunctionInfo; +class CArgumentInfo; +class CAttributeInfo; +class CTemplateParamInfo; +class CTemplateInfo; +class CNamespaceInfo; +class CClassInstance; +class CUnionInstance; +class CFctInstance; +class CSemDatabase; +class CTree; +class CT_ExprList; +class CTemplateInstance; + + +/** \class CObjectInfo CObjectInfo.h Puma/CObjectInfo.h + * Abstract base class of all semantic information classes. + * Provides all semantic information about an entity (class, + * function, object, etc). + * + * A semantic object is identified by its object ID. %Semantic + * information objects for the same kind of entity have the + * same object ID (like object ID CObjectInfo::FUNCTION_INFO + * for all semantic objects of functions). + * + * Example: + * + * \code + * // check if sem_obj is a semantic object for a function + * if (sem_obj.Id() == Puma::CObjectInfo::FUNCTION_INFO) { + * ... + * } + * // same check + * if (sem_obj.FunctionInfo()) { + * ... + * } + * \endcode + * + * %Semantic information objects are created by the semantic + * analysis component of %Puma (see Puma::Semantic) during + * the parse process and are collected in the semantic + * information database (see Puma::CSemDatabase). + * + * There are several relations between the semantic objects + * forming the semantic tree. There is one semantic tree for + * each translation unit. + * + * The root of the semantic tree usually is the semantic + * object for the file scope (see Puma::CFileInfo). It contains + * all the other scopes of the analysed source file, such + * as namespaces and class definitions, function definitions, + * global variables, and so on. The semantic tree is destroyed + * by destroying the root object of the tree. This recursively + * destroys all sub-objects of the tree. */ +class CObjectInfo { +public: + /** %Semantic information object types. */ + enum ObjectId { + /** %Semantic information about the file scope. */ + FILE_INFO, + /** %Semantic information about a union. */ + UNION_INFO, + /** %Semantic information about a class. */ + CLASS_INFO, + /** %Semantic information about a base class specifier. */ + BASECLASS_INFO, + /** %Semantic information about class/namespace member alias. */ + MEMBERALIAS_INFO, + /** %Semantic information about an enumeration. */ + ENUM_INFO, + /** %Semantic information about a typedef. */ + TYPEDEF_INFO, + /** %Semantic information about a function, method, or overloaded operator. */ + FUNCTION_INFO, + /** %Semantic information about a label. */ + LABEL_INFO, + /** %Semantic information about an enumerator constant. */ + ENUMERATOR_INFO, + /** %Semantic information about an object (variables etc). */ + ATTRIBUTE_INFO, + /** %Semantic information about a template parameter. */ + TEMPLATE_PARAM_INFO, + /** %Semantic information about a class or function template. */ + TEMPLATE_INFO, + /** %Semantic information about an instance of a class template. */ + CLASS_INSTANCE_INFO, + /** %Semantic information about an instance of a union template. */ + UNION_INSTANCE_INFO, + /** %Semantic information about an instance of a function template. */ + FCT_INSTANCE_INFO, + /** %Semantic information about a function parameter. */ + ARGUMENT_INFO, + /** %Semantic information about a local scope (block scope). */ + LOCAL_INFO, + /** %Semantic information about a named or anonymous namespace. */ + NAMESPACE_INFO, + /** %Semantic information about a using declaration. */ + USING_INFO + }; + +private: + DString _Name; + const char *_QualName; // Full qualified name + bool _abs, _tdef, + _unnamed; // Flags that were used for QualName() + CTypeInfo *_TypeInfo; + CObjectInfo *_BaseObject; // corresponding object of base class + CObjectInfo *_Next; // next linked object + CObjectInfo *_Prev; // previous linked object + CSemDatabase *_SemDB; + CTree *_Tree; // corresponding syntax tree + ObjectId _Id; // object type + CSpecifiers _Specifiers; + CSourceInfo _SourceInfo; // location in source file + CProtection::Type _Protection; + CLinkage::Type _Linkage; + CStorage::Type _Storage; + CLanguage _Language; + +protected: + /** Qualified name scope. Set only for CAttributeInfo, + * CFunctionInfo, and CRecord. */ + CStructure *_QualScope; + /** The scope of a friend class or function. This is not + * the scope in which the friend class or function + * was declared. A friend function of a class may be declared + * first inside the scope of a class definition. But the + * declared function does not belong to this scope. In fact + * it belongs to the nearest non-class scope (usually the + * file scope). This is the assigned scope. */ + CStructure *_AssignedScope; + /** Set of semantic objects connected to this object in + * any way. */ + Array _Registered; + +public: + /** Destructor. */ + ~CObjectInfo (); + + /** Compare the addresses of this object and all objects + * linked to this object with the address of the given + * object. + * \return True if the addresses are the same and thus + * the given object describes the same entity. */ + bool operator ==(const CObjectInfo &) const; + /** Compare the addresses of this object and all objects + * linked to this object with the address of the given + * object. + * \return True if the addresses are different and thus + * the given object does not describe the same entity. */ + bool operator !=(const CObjectInfo &) const; + + /** Get a pointer to CObjectInfo for any semantic object type. */ + CObjectInfo *ObjectInfo () const; + /** Return a pointer to CLabelInfo if the entity is a label. + * The object type has to be one of: + * \li CObjectInfo::LABEL_INFO + * + * \return The valid pointer or NULL. */ + CLabelInfo *LabelInfo () const; + /** Return a pointer to CMemberAliasInfo if the entity is a member alias. + * The object type has to be one of: + * \li CObjectInfo::MEMBERALIAS_INFO + * + * \return The valid pointer or NULL. */ + CMemberAliasInfo *MemberAliasInfo () const; + /** Return a pointer to CBaseClassInfo if the entity is a base class specifier. + * The object type has to be one of: + * \li CObjectInfo::BASECLASS_INFO + * + * \return The valid pointer or NULL. */ + CBaseClassInfo *BaseClassInfo () const; + /** Return a pointer to CUsingInfo if the entity is a using-directive. + * The object type has to be one of: + * \li CObjectInfo::USING_INFO + * + * \return The valid pointer or NULL. */ + CUsingInfo *UsingInfo () const; + /** Return a pointer to CTypedefInfo if the entity is a typedef. + * The object type has to be one of: + * \li CObjectInfo::TYPEDEF_INFO + * + * \return The valid pointer or NULL. */ + CTypedefInfo *TypedefInfo () const; + /** Return a pointer to CArgumentInfo if the entity is a function parameter. + * The object type has to be one of: + * \li CObjectInfo::ARGUMENT_INFO + * + * \return The valid pointer or NULL. */ + CArgumentInfo *ArgumentInfo () const; + /** Return a pointer to CAttributeInfo if the entity is an object or + * enumeration constant. + * The object type has to be one of: + * \li CObjectInfo::ATTRIBUTE_INFO + * \li CObjectInfo::ENUMERATOR_INFO + * + * \return The valid pointer or NULL. */ + CAttributeInfo *AttributeInfo () const; + /** Return a pointer to CTemplateParemInfo if the entity is a template parameter. + * The object type has to be one of: + * \li CObjectInfo::TEMPLATE_PARAM_INFO + * + * \return The valid pointer or NULL. */ + CTemplateParamInfo *TemplateParamInfo () const; + /** Return a pointer to CStructure if the entity is a namespace, class, + * function, or any other construct that can contain other entities. + * The object type has to be one of: + * \li CObjectInfo::NAMESPACE_INFO + * \li CObjectInfo::FILE_INFO + * \li CObjectInfo::CLASS_INFO + * \li CObjectInfo::CLASS_INSTANCE_INFO + * \li CObjectInfo::UNION_INFO + * \li CObjectInfo::UNION_INSTANCE_INFO + * \li CObjectInfo::FUNCTION_INFO, + * \li CObjectInfo::FCT_INSTANCE_INFO + * \li CObjectInfo::TEMPLATE_INFO + * \li CObjectInfo::LOCAL_INFO + * + * \return The valid pointer or NULL. */ + CStructure *Structure () const; + /** Return a pointer to CFileInfo if this is the file scope. + * The object type has to be one of: + * \li CObjectInfo::FILE_INFO + * + * \return The valid pointer or NULL. */ + CFileInfo *FileInfo () const; + /** Return a pointer to CRecord if the entity is a class or union. + * The object type has to be one of: + * \li CObjectInfo::CLASS_INFO + * \li CObjectInfo::CLASS_INSTANCE_INFO + * \li CObjectInfo::UNION_INFO + * \li CObjectInfo::UNION_INSTANCE_INFO + * + * \return The valid pointer or NULL. */ + CRecord *Record () const; + /** Return a pointer to CLocalScope if the entity is a local scope + * (block scope). + * The object type has to be one of: + * \li CObjectInfo::LOCAL_INFO + * + * \return The valid pointer or NULL. */ + CLocalScope *LocalScope () const; + /** Return a pointer to CScopeInfo if the entity defines a scope. + * The object type has to be one of: + * \li CObjectInfo::NAMESPACE_INFO + * \li CObjectInfo::FILE_INFO + * \li CObjectInfo::CLASS_INFO + * \li CObjectInfo::CLASS_INSTANCE_INFO + * \li CObjectInfo::UNION_INFO + * \li CObjectInfo::UNION_INSTANCE_INFO + * \li CObjectInfo::FUNCTION_INFO + * \li CObjectInfo::FCT_INSTANCE_INFO + * \li CObjectInfo::TEMPLATE_INFO + * \li CObjectInfo::LOCAL_INFO + * + * \return The valid pointer or NULL. */ + CScopeInfo *ScopeInfo () const; + /** Return a pointer to CClassInfo if the entity is a class. + * The object type has to be one of: + * \li CObjectInfo::CLASS_INFO + * \li CObjectInfo::CLASS_INSTANCE_INFO + * + * \return The valid pointer or NULL. */ + CClassInfo *ClassInfo () const; + /** Return a pointer to CUnionInfo if the entity is a union. + * The object type has to be one of: + * \li CObjectInfo::UNION_INFO + * \li CObjectInfo::UNION_INSTANCE_INFO + * + * \return The valid pointer or NULL. */ + CUnionInfo *UnionInfo () const; + /** Return a pointer to CEnumInfo if the entity is an enumeration. + * The object type has to be one of: + * \li CObjectInfo::ENUM_INFO + * + * \return The valid pointer or NULL. */ + CEnumInfo *EnumInfo () const; + /** Return a pointer to CFunctionInfo if the entity is a function, + * method, or overloaded operator. + * The object type has to be one of: + * \li CObjectInfo::FUNCTION_INFO + * \li CObjectInfo::FCT_INSTANCE_INFO + * + * \return The valid pointer or NULL. */ + CFunctionInfo *FunctionInfo () const; + /** Return a pointer to CNamespaceInfo if the entity is a namespace. + * The object type has to be one of: + * \li CObjectInfo::NAMESPACE_INFO + * \li CObjectInfo::FILE_INFO + * + * \return The valid pointer or NULL. */ + CNamespaceInfo *NamespaceInfo () const; + /** Return a pointer to CEnumeratorInfo if the entity is an + * enumeration constant. + * The object type has to be one of: + * \li CObjectInfo::ENUMERATOR_INFO + * + * \return The valid pointer or NULL. */ + CEnumeratorInfo *EnumeratorInfo () const; + /** Return a pointer to CTemplateInfo if the entity is a template. + * The object type has to be one of: + * \li CObjectInfo::TEMPLATE_INFO + * + * \return The valid pointer or NULL. */ + CTemplateInfo *TemplateInfo () const; + /** Return a pointer to CClassInstance if the entity is an instance + * of a class template. + * The object type has to be one of: + * \li CObjectInfo::CLASS_INSTANCE_INFO + * + * \return The valid pointer or NULL. */ + CClassInstance *ClassInstance () const; + /** Return a pointer to CFctInstance if the entity is an instance + * of a function template. + * The object type has to be one of: + * \li CObjectInfo::FCT_INSTANCE_INFO + * + * \return The valid pointer or NULL. */ + CFctInstance *FctInstance () const; + /** Return a pointer to CUnionInstance if the entity is an instance + * of a union template. + * The object type has to be one of: + * \li CObjectInfo::UNION_INSTANCE_INFO + * + * \return The valid pointer or NULL. */ + CUnionInstance *UnionInstance () const; + + /** Return a pointer to CTemplateInfo if the entity is a template. + * The object type has to be one of: + * \li CObjectInfo::CLASS_INFO + * \li CObjectInfo::UNION_INFO + * \li CObjectInfo::FUNCTION_INFO + * \li CObjectInfo::TEMPLATE_PARAM_INFO + * + * \return The valid pointer or NULL. */ + CTemplateInfo *Template () const; + /** Return a pointer to CTemplateInstance if the entity is an + * instance of a class or function template. + * The object type has to be one of: + * \li CObjectInfo::CLASS_INSTANCE_INFO + * \li CObjectInfo::UNION_INSTANCE_INFO + * \li CObjectInfo::FCT_INSTANCE_INFO + * + * \return The valid pointer or NULL. */ + CTemplateInstance *TemplateInstance () const; + + /** Get the scope in which the entity was declared. */ + CScopeInfo *Scope () const; + /** Get the scope of qualified names. The scope of a class member + * for instance is the corresponding class. If a function is declared + * in a namespace, then the qualified scope is that namespace. */ + CStructure *QualifiedScope () const; + /** Get the class containing the class member described by this object. + * The object type has to be one of: + * \li CObjectInfo::FUNCTION_INFO + * \li CObjectInfo::FCT_INSTANCE_INFO + * \li CObjectInfo::ATTRIBUTE_INFO + * \li CObjectInfo::ENUMERATOR_INFO + * + * \return The class or union, or NULL if not a member of a class or union. */ + CRecord *ClassScope () const; + /** Get the scope of a friend class or function. This is not + * the scope in which the friend class or function + * was declared. A friend function of a class may be declared + * first inside the scope of a class definition. But the + * declared function does not belong to this scope. In fact + * it belongs to the nearest non-class scope (usually the + * file scope). This is the assigned scope. + * \return The assigned scope or NULL. */ + CStructure *AssignedScope () const; + + /** Get the type of this semantic object. */ + ObjectId Id () const; + /** Get the name of entity described by this semantic object. */ + const DString& Name () const; + /** Get the qualified name of the entity described by this semantic object. + * \param abs Create root qualified name (like \::X\::Y\::Z). + * \param tdef Insert the name of a typedef instead of the named type. + * \param unnamed Don't ignore unnamed namespaces (like \\::foo). */ + const char *QualName (bool abs = false, bool tdef = false, + bool unnamed = false); + /** Get the semantic information object for the definition of an entity. + * Some entities, like functions and classes, can be declared several + * times before a definition of the entity appears. The semantic objects + * for the definition and declarations are linked. This method searches + * the linked semantic objects for the semantic object of the definition + * of the entity. + * \return The semantic object for the definition or this object if + * no definition found. */ + CObjectInfo *DefObject () const; + /** Get the data type of the entity. */ + CTypeInfo *TypeInfo () const; + /** Get the source file information. Contains the position and token + * of the entity in the source file. */ + CSourceInfo *SourceInfo () const; + /** Get the semantic information database object containing this + * semantic object. + * \deprecated Use CObjectInfo::SemDB() instead. */ + CSemDatabase *ClassDB () const; + /** Get the semantic information database object containing this + * semantic object. */ + CSemDatabase *SemDB () const; + /** Get the syntax tree node for the entity described by this + * semantic object. */ + CTree *Tree () const; + /** Get the next semantic object linked with this object. Usually + * the definition and the declarations of an entity are linked. */ + CObjectInfo *NextObject () const; + /** Get the previous semantic object linked with this object. Usually + * the definition and the declarations of an entity are linked. */ + CObjectInfo *PrevObject () const; + /** Get the semantic object for the base class entity this entity + * is overloading. + * \note Not yet implemented! + * \return Always returns NULL. */ + CObjectInfo *BaseObject () const; + /** Get the initializer of the entity. + * \return The initializer expression or NULL if no initializer. */ + CTree *Init () const; + /** Get the member protection of the entity, if it is a class member. */ + CProtection::Type Protection () const; + /** Get the linkage of the entity. */ + CLinkage::Type Linkage () const; + /** Get the storage class of the entity. */ + CStorage::Type Storage () const; + /** Get the entity encoding language. */ + const CLanguage &Language () const; + /** Get the entity encoding language. */ + CLanguage &Language (); + /** Get the declaration specifiers. */ + const CSpecifiers &Specifiers () const; + + /** Check if the entity is a type. */ + bool isType () const; + /** Check if the entity is an object. */ + bool isObject () const; + /** Check if the entity is anonymous (has no explicit name). */ + bool isAnonymous () const; + /** Check if the entity is a class or function template, or a + * template template parameter. */ + bool isTemplate () const; + /** Check if the entity is a class or function template instance. */ + bool isTemplateInstance () const; + /** Check if the entity describes a built-in type or function. + * In this case the entity has no syntax tree (Tree() returns NULL). */ + bool isBuiltin () const; + /** Check if the entity is a method or data member of a class. */ + bool isClassMember () const; + /** Check if the entity is declared \e virtual. */ + bool isVirtual () const; + /** Check if the entity is declared \e static. */ + bool isStatic () const; + /** Check if the entity is declared \e __thread. */ + bool isThreadLocal () const; + /** Check if the entity is declared \e extern. */ + bool isExtern () const; + /** Check if the entity is declared \e mutable. */ + bool isMutable () const; + /** Check if the entity is declared \e register. */ + bool isRegister () const; + /** Check if the entity is declared \e explicit. */ + bool isExplicit () const; + /** Check if the entity is declared \e inline. */ + bool isInline () const; + /** Check if the entity is declared \e auto. */ + bool isAuto () const; + /** Check if the given semantic object is registered as + * being connected to this semantic object in any way. + * \param s The semantic object. */ + bool isRegistered (const CStructure* s) const; + /** Check if the entity is local. An entity is local if it was + * declared in a local scope. */ + bool isLocal () const; + + /** Set the name of the entity. + * \param s The name. */ + void Name (const char* s) { Name(DString(s==0?"":s)); } + /** Set the name of the entity. + * \param ds The name. */ + void Name (const DString& ds); + /** Set the type of the entity. + * \param type The type information. */ + void TypeInfo (CTypeInfo *type); + /** Set the base class object for the entity this entity overloads. + * \param base The base object. */ + void BaseObject (CObjectInfo *base); + /** Set the member access protection of the entity. + * \param p The protection. */ + void Protection (CProtection::Type p); + /** Set the linkage of the entity. + * \param l The linkage. */ + void Linkage (CLinkage::Type l); + /** Set the storage class of the entity. + * \param s The storage class. */ + void Storage (CStorage::Type s); + /** Set the declaration specifiers. */ + void Specifiers (const CSpecifiers&); + /** Set the source file information for the entity. + * \param finfo The file information. */ + void FileInfo (CFileInfo *finfo); + /** Set the syntax tree node of the entity. + * \param tree The syntax tree node. */ + void Tree (CTree *tree); + /** Set the semantic information database object containing + * this semantic object. + * \deprecated Use CObjectInfo::SemDB(CSemDatabase*) instead. + * \param db The semantic database. */ + void ClassDB (CSemDatabase *db); + /** Set the semantic information database object containing + * this semantic object. + * \param db The semantic database. */ + void SemDB (CSemDatabase *db); + /** Set the link to next semantic object. Usually the semantic objects + * for the definition and declaration of an entity are linked. + * \param obj The next object in the chain. */ + void NextObject (CObjectInfo *obj); + /** Set the link to next semantic object. Usually the semantic objects + * for the definition and declaration of an entity are linked. + * \param obj The previous object in the chain. */ + void PrevObject (CObjectInfo *obj); + /** Unlink this semantic object. Usually the semantic objects + * for the definition and declaration of an entity are linked. + * This method removes this object from the chain. */ + void Unlink (); + /** Register the given semantic object as being connected to + * this semantic object in any way. + * \param s The semantic object. */ + void Register (CStructure *s); + /** Unregister the given semantic object as being connected to + * this semantic object in any way. + * \param s The semantic object. */ + void Unregister (CStructure *s); + /** Set whether the entity was declared \e virtual. + * \param v True for yes, false for no. */ + void isVirtual (bool v); + /** Set whether the entity was declared \e static. + * \param v True for yes, false for no. */ + void isStatic (bool v); + /** Set whether the entity was declared \e __thread. + * \param v True for yes, false for no. */ + void isThreadLocal (bool v); + /** Set whether the entity was declared \e extern. + * \param v True for yes, false for no. */ + void isExtern (bool v); + /** Set whether the entity was declared \e mutable. + * \param v True for yes, false for no. */ + void isMutable (bool v); + /** Set whether the entity was declared \e register. + * \param v True for yes, false for no. */ + void isRegister (bool v); + /** Set whether the entity was declared \e explicit. + * \param v True for yes, false for no. */ + void isExplicit (bool v); + /** Set whether the entity was declared \e inline. + * \param v True for yes, false for no. */ + void isInline (bool v); + /** Set whether the entity was declared \e auto. + * \param v True for yes, false for no. */ + void isAuto (bool v); + /** Set the assigned scope of the entity. This is the scope of + * a friend class or function. It is not the scope in which the + * friend class or function was declared. A friend function of + * a class may be declared first inside the scope of a class + * definition. But the declared function does not belong to + * this scope. In fact it belongs to the nearest non-class scope + * (usually the file scope). This is the assigned scope. + * \param s The assigned scope. */ + void AssignedScope (CStructure *s); + +protected: + /** Constructor. + * \param id The semantic object type. */ + CObjectInfo (ObjectId id); +}; + +inline CObjectInfo::CObjectInfo (CObjectInfo::ObjectId id) : + _Name (), + _QualName ((const char*)0), + _abs (false), + _tdef (false), + _unnamed (false), + _TypeInfo ((CTypeInfo*)0), + _BaseObject ((CObjectInfo*)0), + _Next ((CObjectInfo*)this), + _Prev ((CObjectInfo*)this), + _SemDB ((CSemDatabase*)0), + _Tree ((CTree*)0), + _Id (id), + _Protection (CProtection::PROT_NONE), + _Linkage (CLinkage::LINK_NONE), + _Storage (CStorage::CLASS_NONE), + _QualScope ((CStructure*)0), + _AssignedScope ((CStructure*)0), + _Registered (1, 10) + {} + +inline CObjectInfo::ObjectId CObjectInfo::Id () const + { return _Id; } + +inline bool CObjectInfo::operator !=(const CObjectInfo &info) const + { return ! (*this == info); } + +inline const DString& CObjectInfo::Name () const + { return _Name; } +inline CTypeInfo *CObjectInfo::TypeInfo () const + { return _TypeInfo; } +inline CSourceInfo *CObjectInfo::SourceInfo () const + { return (CSourceInfo*)&_SourceInfo; } +inline CProtection::Type CObjectInfo::Protection () const + { return _Protection; } +inline CLinkage::Type CObjectInfo::Linkage () const + { return _Linkage; } +inline CStorage::Type CObjectInfo::Storage () const + { return _Storage; } +inline CLanguage &CObjectInfo::Language () + { return _Language; } +inline const CLanguage &CObjectInfo::Language () const + { return _Language; } +inline CObjectInfo *CObjectInfo::BaseObject () const + { return _BaseObject; } +inline CTree *CObjectInfo::Tree () const + { return _Tree; } +inline CSemDatabase *CObjectInfo::ClassDB () const + { return _SemDB; } +inline CSemDatabase *CObjectInfo::SemDB () const + { return _SemDB; } + +inline void CObjectInfo::Protection (CProtection::Type s) + { _Protection = s; } +inline void CObjectInfo::Linkage (CLinkage::Type s) + { _Linkage = s; } +inline void CObjectInfo::Storage (CStorage::Type s) + { _Storage = s; } +inline void CObjectInfo::BaseObject (CObjectInfo *info) + { _BaseObject = info; } +inline void CObjectInfo::Tree (CTree *t) + { _Tree = t; } +inline void CObjectInfo::ClassDB (CSemDatabase *db) + { _SemDB = db; } +inline void CObjectInfo::SemDB (CSemDatabase *db) + { _SemDB = db; } + +inline void CObjectInfo::Register (CStructure *scope) + { _Registered.append (scope); } + +inline bool CObjectInfo::isAnonymous () const + { return (Name ().empty () || *Name ().c_str () == '%' || + *Name ().c_str () == '<'); // the last one is for namespaces + } +inline bool CObjectInfo::isBuiltin () const + { return ! Tree (); } + +inline const CSpecifiers &CObjectInfo::Specifiers () const + { return _Specifiers; } +inline void CObjectInfo::Specifiers (const CSpecifiers& specs) + { _Specifiers = specs; } + +inline bool CObjectInfo::isVirtual () const + { return _Specifiers == CSpecifiers::SPEC_VIRTUAL; } +inline bool CObjectInfo::isStatic () const + { return _Specifiers == CSpecifiers::SPEC_STATIC; } +inline bool CObjectInfo::isThreadLocal () const + { return _Specifiers == CSpecifiers::SPEC_THREAD; } +inline bool CObjectInfo::isExtern () const + { return _Specifiers == CSpecifiers::SPEC_EXTERN; } +inline bool CObjectInfo::isMutable () const + { return _Specifiers == CSpecifiers::SPEC_MUTABLE; } +inline bool CObjectInfo::isRegister () const + { return _Specifiers == CSpecifiers::SPEC_REGISTER; } +inline bool CObjectInfo::isExplicit () const + { return _Specifiers == CSpecifiers::SPEC_EXPLICIT; } +inline bool CObjectInfo::isInline () const + { return _Specifiers == CSpecifiers::SPEC_INLINE; } +inline bool CObjectInfo::isAuto () const + { return _Specifiers == CSpecifiers::SPEC_AUTO; } + +inline void CObjectInfo::isVirtual (bool v) + { if (v) _Specifiers += CSpecifiers::SPEC_VIRTUAL; + else _Specifiers -= CSpecifiers::SPEC_VIRTUAL; } +inline void CObjectInfo::isStatic (bool v) + { if (v) _Specifiers += CSpecifiers::SPEC_STATIC; + else _Specifiers -= CSpecifiers::SPEC_STATIC; } +inline void CObjectInfo::isThreadLocal (bool v) + { if (v) _Specifiers += CSpecifiers::SPEC_THREAD; + else _Specifiers -= CSpecifiers::SPEC_THREAD; } +inline void CObjectInfo::isExtern (bool v) + { if (v) _Specifiers += CSpecifiers::SPEC_EXTERN; + else _Specifiers -= CSpecifiers::SPEC_EXTERN; } +inline void CObjectInfo::isMutable (bool v) + { if (v) _Specifiers += CSpecifiers::SPEC_MUTABLE; + else _Specifiers -= CSpecifiers::SPEC_MUTABLE; } +inline void CObjectInfo::isRegister (bool v) + { if (v) _Specifiers += CSpecifiers::SPEC_REGISTER; + else _Specifiers -= CSpecifiers::SPEC_REGISTER; } +inline void CObjectInfo::isExplicit (bool v) + { if (v) _Specifiers += CSpecifiers::SPEC_EXPLICIT; + else _Specifiers -= CSpecifiers::SPEC_EXPLICIT; } +inline void CObjectInfo::isInline (bool v) + { if (v) _Specifiers += CSpecifiers::SPEC_INLINE; + else _Specifiers -= CSpecifiers::SPEC_INLINE; } +inline void CObjectInfo::isAuto (bool v) + { if (v) _Specifiers += CSpecifiers::SPEC_AUTO; + else _Specifiers -= CSpecifiers::SPEC_AUTO; } + +// link objects + +inline CObjectInfo *CObjectInfo::NextObject () const + { return _Next; } +inline CObjectInfo *CObjectInfo::PrevObject () const + { return _Prev; } + +inline CMemberAliasInfo *CObjectInfo::MemberAliasInfo () const + { return _Id == MEMBERALIAS_INFO ? (CMemberAliasInfo*)this : (CMemberAliasInfo*)0; } +inline CBaseClassInfo *CObjectInfo::BaseClassInfo () const + { return _Id == BASECLASS_INFO ? (CBaseClassInfo*)this : (CBaseClassInfo*)0; } +inline CClassInfo *CObjectInfo::ClassInfo () const + { return _Id == CLASS_INFO || _Id == CLASS_INSTANCE_INFO ? (CClassInfo*)this : (CClassInfo*)0; } +inline CUnionInfo *CObjectInfo::UnionInfo () const + { return _Id == UNION_INFO || _Id == UNION_INSTANCE_INFO ? (CUnionInfo*)this : (CUnionInfo*)0; } +inline CEnumInfo *CObjectInfo::EnumInfo () const + { return _Id == ENUM_INFO ? (CEnumInfo*)this : (CEnumInfo*)0; } +inline CUsingInfo *CObjectInfo::UsingInfo () const + { return _Id == USING_INFO ? (CUsingInfo*)this : (CUsingInfo*)0; } +inline CEnumeratorInfo *CObjectInfo::EnumeratorInfo () const + { return _Id == ENUMERATOR_INFO ? (CEnumeratorInfo*)this : (CEnumeratorInfo*)0; } +inline CTypedefInfo *CObjectInfo::TypedefInfo () const + { return _Id == TYPEDEF_INFO ? (CTypedefInfo*)this : (CTypedefInfo*)0; } +inline CFunctionInfo *CObjectInfo::FunctionInfo () const + { return _Id == FUNCTION_INFO || _Id == FCT_INSTANCE_INFO ? (CFunctionInfo*)this : (CFunctionInfo*)0; } +inline CArgumentInfo *CObjectInfo::ArgumentInfo () const + { return _Id == ARGUMENT_INFO ? (CArgumentInfo*)this : (CArgumentInfo*)0; } +inline CAttributeInfo *CObjectInfo::AttributeInfo () const + { return _Id == ATTRIBUTE_INFO || _Id == ENUMERATOR_INFO ? (CAttributeInfo*)this : (CAttributeInfo*)0; } +inline CNamespaceInfo *CObjectInfo::NamespaceInfo () const + { return _Id == NAMESPACE_INFO || _Id == FILE_INFO ? (CNamespaceInfo*)this : (CNamespaceInfo*)0; } +inline CLabelInfo *CObjectInfo::LabelInfo () const + { return _Id == LABEL_INFO ? (CLabelInfo*)this : (CLabelInfo*)0; } +inline CFileInfo *CObjectInfo::FileInfo () const + { return _Id == FILE_INFO ? (CFileInfo*)this : (CFileInfo*)0; } +inline CStructure *CObjectInfo::Structure () const + { return NamespaceInfo () || ClassInfo () || UnionInfo () || + FunctionInfo () || TemplateInfo () || LocalScope () ? + (CStructure*)this : (CStructure*)0; } +inline CRecord *CObjectInfo::Record () const + { return ClassInfo () || UnionInfo () ? (CRecord*)this : (CRecord*)0; } +inline CLocalScope *CObjectInfo::LocalScope () const + { return _Id == LOCAL_INFO ? (CLocalScope*)this : (CLocalScope*)0; } +inline CTemplateParamInfo *CObjectInfo::TemplateParamInfo () const + { return _Id == TEMPLATE_PARAM_INFO ? (CTemplateParamInfo*)this : (CTemplateParamInfo*)0; } +inline CTemplateInfo *CObjectInfo::TemplateInfo () const + { return _Id == TEMPLATE_INFO ? (CTemplateInfo*)this : (CTemplateInfo*)0; } +inline CScopeInfo *CObjectInfo::ScopeInfo () const + { return /*_Id == SCOPE_INFO ||*/ Structure () ? (CScopeInfo*)this : (CScopeInfo*)0; } +inline CObjectInfo *CObjectInfo::ObjectInfo () const + { return (CObjectInfo*)this; } +inline CClassInstance *CObjectInfo::ClassInstance () const + { return _Id == CLASS_INSTANCE_INFO ? (CClassInstance*)this : (CClassInstance*)0; } +inline CUnionInstance *CObjectInfo::UnionInstance () const + { return _Id == UNION_INSTANCE_INFO ? (CUnionInstance*)this : (CUnionInstance*)0; } +inline CFctInstance *CObjectInfo::FctInstance () const + { return _Id == FCT_INSTANCE_INFO ? (CFctInstance*)this : (CFctInstance*)0; } + +inline CStructure *CObjectInfo::QualifiedScope () const + { return _QualScope; } + +inline void CObjectInfo::AssignedScope (CStructure *s) + { _AssignedScope = s; } +inline CStructure *CObjectInfo::AssignedScope () const + { return _AssignedScope; } + + +} // namespace Puma + +#endif /* __CObjectInfo_h__ */ diff --git a/Puma/src/infos/CRecord.cc b/Puma/src/infos/CRecord.cc new file mode 100644 index 0000000..e1b73c1 --- /dev/null +++ b/Puma/src/infos/CRecord.cc @@ -0,0 +1,298 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CRecord.h" +#include "Puma/CClassInfo.h" +#include "Puma/CUnionInfo.h" +#include "Puma/CFunctionInfo.h" +#include "Puma/CTemplateInfo.h" +#include "Puma/CAttributeInfo.h" +#include "Puma/CTemplateInstance.h" +#include "Puma/CBaseClassInfo.h" +#include "Puma/CTree.h" +#include "Puma/CSemDatabase.h" +#include + +namespace Puma { + + +CRecord::~CRecord () { +//// for (unsigned i = 0; i < Users (); i++) +//// User (i)->removeType (this); +// CScopeInfo *parent = Parent (); +// if (parent && parent->Structure ()) +// parent->Structure ()->removeType (this); +// if (AssignedScope ()) +// AssignedScope ()->removeType (this); +// if (_TemplateInfo) +// _TemplateInfo->ObjectInfo ((CObjectInfo*)0); +} + +bool CRecord::isComplete (unsigned long pos) const { + CRecord *record = (CRecord*)DefObject (); + if (record->isDefined ()) { + if (pos == 0) + return true; + CObjectInfo *info = record; + if (info->isTemplateInstance ()) { + info = info->TemplateInstance ()->Template ()->ObjectInfo (); + } + CT_Token *token = info->Tree ()->token_node (); + if (token && token->Number () <= pos) + return true; + } + return false; +} + +bool CRecord::isDefined () const { + return Tree () && (Tree ()->NodeName () == CT_ClassDef::NodeId () || + Tree ()->NodeName () == CT_UnionDef::NodeId ()); +} + +/** Check if this is a trivial class/union */ +bool CRecord::isTrivial () const { + return hasTrivialCtor () && hasTrivialCopy (); +} + +/** Yields true if the class has a trivial copy assignment operator. */ +bool CRecord::hasTrivialAssign () const { + // §12.8p11 + // A copy assignment operator for class X is trivial if it is implicitly declared and if: + // — class X has no virtual functions (10.3) and no virtual base classes (10.1), and + // — each direct base class of X has a trivial copy assignment operator, and + // — for all the nonstatic data members of X that are of class type (or array thereof), + // each such class type has a trivial copy assignment operator. + bool oper_found = false; + unsigned i, num = Functions (); + for (i = 0; i < num; i++) { + CFunctionInfo* mf = Function (i); + // virtual function + if (mf->isVirtual ()) + return false; + // implicit assignment operator + if (! oper_found && mf->isBuiltin () && mf->isCopyAssignOperator ()) + oper_found = true; + } + // no implicit assignment operator found + if (! oper_found) + return false; + + // check if base classes have a trivial assignment operator and are not virtual + CClassInfo* c = ClassInfo (); + num = c ? c->BaseClasses () : 0; + for (i = 0; i < num; i++) { + CBaseClassInfo* bc = c->BaseClass (i); + if (bc->isVirtual () || ! bc->Class ()->hasTrivialAssign ()) + return false; + } + + // check non-static data members + num = Attributes (); + for (i = 0; i < num; i++) { + CAttributeInfo* ai = Attribute (i); + if (! ai->isStatic ()) { + CTypeInfo* type = ai->TypeInfo (); + // get underlying type of array + while (type->isArray ()) + type = type->VirtualType ()->BaseType (); + // check if data member has trivial assignment operator + if (type->isClassOrUnion ()) { + CTypeRecord* tr = type->VirtualType ()->TypeRecord (); + if (tr && tr->Record () && ! tr->Record ()->hasTrivialAssign ()) { + // data member with non-trivial assignment operator found + return false; + } + } + } + } + return true; +} + +/** Yields true if the class has a trivial copy constructor. */ +bool CRecord::hasTrivialCopy () const { + // §12.8p6 + // A copy constructor for class X is trivial if it is implicitly declared and if: + // — class X has no virtual functions (10.3) and no virtual base classes (10.1), and + // — each direct base class of X has a trivial copy constructor, and + // — for all the non-static data members of X that are of class type (or array thereof), + // each such class type has trivial copy constructor. + bool ctor_found = false; + unsigned i, num = Functions (); + for (i = 0; i < num; i++) { + CFunctionInfo* mf = Function (i); + // virtual function + if (mf->isVirtual ()) + return false; + // implicit copy constructor + if (! ctor_found && mf->isBuiltin () && mf->isCopyConstructor ()) + ctor_found = true; + } + // no implicit default ctor found + if (! ctor_found) + return false; + + // check if base classes have a trivial copy constructor and are not virtual + CClassInfo* c = ClassInfo (); + num = c ? c->BaseClasses () : 0; + for (i = 0; i < num; i++) { + CBaseClassInfo* bc = c->BaseClass (i); + if (bc->isVirtual () || ! bc->Class ()->hasTrivialCopy ()) + return false; + } + + // check non-static data members + num = Attributes (); + for (i = 0; i < num; i++) { + CAttributeInfo* ai = Attribute (i); + if (! ai->isStatic ()) { + CTypeInfo* type = ai->TypeInfo (); + // get underlying type of array + while (type->isArray ()) + type = type->VirtualType ()->BaseType (); + // check if data member has trivial copy ctor + if (type->isClassOrUnion ()) { + CTypeRecord* tr = type->VirtualType ()->TypeRecord (); + if (tr && tr->Record () && ! tr->Record ()->hasTrivialCopy ()) { + // data member with non-trivial copy constructor found + return false; + } + } + } + } + return true; +} + +/** Yields true if the class has a trivial default constructor. */ +bool CRecord::hasTrivialCtor () const { + // §12.1p5 + // A constructor is trivial if it is an implicitly-declared default constructor and if: + // — its class has no virtual functions (10.3) and no virtual base classes (10.1), and + // — all the direct base classes of its class have trivial constructors, and + // — for all the nonstatic data members of its class that are of class type (or array + // thereof), each such class has a trivial constructor. + bool ctor_found = false; + unsigned i, num = Functions (); + for (i = 0; i < num; i++) { + CFunctionInfo* mf = Function (i); + // virtual function + if (mf->isVirtual ()) + return false; + // implicit default constructor + if (! ctor_found && mf->isBuiltin () && mf->isDefaultConstructor ()) + ctor_found = true; + } + // no implicit default ctor found + if (! ctor_found) + return false; + + // check if base classes have a trivial constructor and are not virtual + CClassInfo* c = ClassInfo (); + num = c ? c->BaseClasses () : 0; + for (i = 0; i < num; i++) { + CBaseClassInfo* bc = c->BaseClass (i); + if (bc->isVirtual () || ! bc->Class ()->hasTrivialCtor ()) + return false; + } + + // check non-static data members + num = Attributes (); + for (i = 0; i < num; i++) { + CAttributeInfo* ai = Attribute (i); + if (! ai->isStatic ()) { + CTypeInfo* type = ai->TypeInfo (); + // get underlying type of array + while (type->isArray ()) + type = type->VirtualType ()->BaseType (); + // check if data member has trivial ctor + if (type->isClassOrUnion ()) { + CTypeRecord* tr = type->VirtualType ()->TypeRecord (); + if (tr && tr->Record () && ! tr->Record ()->hasTrivialCtor ()) { + // data member with non-trivial constructor found + return false; + } + } + } + } + return true; +} + +/** Yields true if the class has a trivial destructor. */ +bool CRecord::hasTrivialDtor () const { + // §12.4p3 + // A destructor is trivial if it is an implicitly-declared destructor and if: + // — all of the direct base classes of its class have trivial destructors and + // — for all of the non-static data members of its class that are of class type + // (or array thereof), each such class has a trivial destructor. + unsigned i, num = Functions (); + for (i = 0; i < num; i++) { + CFunctionInfo* mf = Function (i); + if (mf->isDestructor () && mf->isBuiltin ()) + break; + } + // no implicit destructor found + if (i == num) + return false; + + // check if base classes have a trivial destructor + CClassInfo* c = ClassInfo (); + num = c ? c->BaseClasses () : 0; + for (i = 0; i < num; i++) + if (! c->BaseClass (i)->Class ()->hasTrivialDtor ()) + return false; + + // check non-static data members + num = Attributes (); + for (i = 0; i < num; i++) { + CAttributeInfo* ai = Attribute (i); + if (! ai->isStatic ()) { + CTypeInfo* type = ai->TypeInfo (); + // get underlying type of array + while (type->isArray ()) + type = type->VirtualType ()->BaseType (); + // check if data member has trivial dtor + if (type->isClassOrUnion ()) { + CTypeRecord* tr = type->VirtualType ()->TypeRecord (); + if (tr && tr->Record () && ! tr->Record ()->hasTrivialDtor ()) { + // data member with non-trivial destructor found + return false; + } + } + } + } + return true; +} + +void CRecord::rejectParseDelayed () { + long n = _DelayedLength.top (); + for (long i = _Delayed.length (); i > n; i--) + _Delayed.remove (i-1); + _DelayedLength.pop (); +} + +void CRecord::removeDelayed (CTree* tree) { + _InstantiateDelayed.erase (tree->token()); + for (long i = 0; i < _Delayed.length (); i++) { + if (_Delayed.lookup (i) == tree) { + _Delayed.remove (i); + break; + } + } +} + + +} // namespace Puma diff --git a/Puma/src/infos/CRecord.h b/Puma/src/infos/CRecord.h new file mode 100644 index 0000000..93819ee --- /dev/null +++ b/Puma/src/infos/CRecord.h @@ -0,0 +1,202 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CRecord_h__ +#define __CRecord_h__ + +/** \file + * Semantic information about a class or union. */ + +#include "Puma/CStructure.h" +#include "Puma/Stack.h" +#include +#include + +namespace Puma { + + +class CTemplateInfo; + + +/** \class CRecord CRecord.h Puma/CRecord.h + * Semantic information about a class or union. */ +class CRecord : public CStructure { +public: + typedef std::list TreeList; + typedef std::map InstantiateDelayedMap; + +private: + CTemplateInfo *_TemplateInfo; + bool _isTemplate; + bool _hiddenFwdDecl; + + // Parts of record to parse delayed (function bodies, initializers, ...) + Array _Delayed; + // Stack used to reject delayed parsing of record parts + Stack _DelayedLength; + // Delayed record parts instantiation map + InstantiateDelayedMap _InstantiateDelayed; + // True if complete parsed + bool _CompleteParsed; + +protected: + /** Constructor. + * \param id The object type. */ + CRecord (ObjectId id); + +public: + /** Destructor. */ + ~CRecord (); + + /** Get the template information if this is a class or union template. + * \return The template information or NULL if not a template. */ + CTemplateInfo *TemplateInfo () const; + /** Set the template information of a class/union template. + * \param info The template information. */ + void TemplateInfo (CTemplateInfo *info); + + /** Set the qualification scope of a nested class or union + * or class/union declared in a namespace. + * \param scope The qualification scope. */ + void QualifiedScope (CStructure *scope); + + /** Check if the class/union is complete (defined) + * at the given source code position. The position + * is specified by the unique number of the CT_Token + * tree node representing the name of the class/union. + * \param pos The source code position. */ + bool isComplete (unsigned long pos = 0) const; + /** Check if the class/union is defined. */ + bool isDefined () const; + /** Check if the class/union is a template. */ + bool isTemplate () const; + /** Check if this is a class/union forward declaration + * hidden by another declaration in the same scope. */ + bool isHiddenForwardDecl () const; + /** Check if this is a trivial class/union */ + bool isTrivial () const; + + /** Yields true if the class has a trivial copy assignment operator. */ + bool hasTrivialAssign () const; + /** Yields true if the class has a trivial copy constructor. */ + bool hasTrivialCopy () const; + /** Yields true if the class has a trivial default constructor. */ + bool hasTrivialCtor () const; + /** Yields true if the class has a trivial destructor. */ + bool hasTrivialDtor () const; + + /** Set whether this class/union is a template. + * \param v \e true if it is a template. */ + void isTemplate (bool v); + /** Set whether this is a class/union forward declaration + * hidden by another declaration in the same scope. + * \param v \e true if it is a hidden forward declaration. */ + void isHiddenForwardDecl (bool v); + +public: // Parse helper + /** Return true if record is complete parsed. */ + bool isCompleteParsed () const; + /** Set if record is complete parsed. */ + void isCompleteParsed (bool v); + + /** Add a part of record to be parse delayed. */ + void addParseDelayed (CTree* tree); + /** Get the number of parts of record to be parsed delayed. */ + unsigned ParseDelayed () const; + /** Get the n-th part of record to be parsed delayed. */ + CTree* ParseDelayed (unsigned n) const; + + /** Save the current length of the delayed record parts list. */ + void saveParseDelayedListLength (); + /** Forget the last saved length of the delayed record parts list. */ + unsigned forgetParseDelayedListLength (); + /** Reject all parts of record to be parsed delayed added behind + * the last saved position in the list. */ + void rejectParseDelayed (); + + /** Add a part of record to be instantiated delayed. */ + void addInstantiateDelayed (Token* start, CTree* tree); + /** Return true if there are template instances for which to instantiate the record part. */ + bool haveInstantiateDelayed (Token* start) const; + /** Get the list of instances in which to instantiate the record part. */ + const TreeList& InstantiateDelayed (Token* start) const; + + /** Reset the list of parts of record to be parsed or instantiated delayed. */ + void resetDelayed (); + /** Remove the part of record to be parsed or instantiated delayed. */ + void removeDelayed (CTree* tree); +}; + +inline CRecord::CRecord (CObjectInfo::ObjectId id) : + CStructure (id), + _TemplateInfo ((CTemplateInfo*)0), + _isTemplate (false), + _hiddenFwdDecl (false), + _Delayed (5, 5), + _DelayedLength (1, 2), + _CompleteParsed (false) + {} + +inline bool CRecord::isTemplate () const + { return _isTemplate; } +inline void CRecord::isTemplate (bool v) + { _isTemplate = v; } + +inline bool CRecord::isHiddenForwardDecl () const + { return _hiddenFwdDecl; } +inline void CRecord::isHiddenForwardDecl (bool v) + { _hiddenFwdDecl = v; } + +inline CTemplateInfo *CRecord::TemplateInfo () const + { return _TemplateInfo; } +inline void CRecord::TemplateInfo (CTemplateInfo *info) + { _TemplateInfo = info; } + +inline void CRecord::QualifiedScope (CStructure *s) + { _QualScope = s; } + +inline bool CRecord::isCompleteParsed () const + { return _CompleteParsed; } +inline void CRecord::isCompleteParsed (bool v) + { _CompleteParsed = v; } + +inline void CRecord::addParseDelayed (CTree* tree) + { _Delayed.append (tree); } +inline unsigned CRecord::ParseDelayed () const + { return _Delayed.length (); } +inline CTree* CRecord::ParseDelayed (unsigned n) const + { return _Delayed.lookup (n); } + +inline void CRecord::saveParseDelayedListLength () + { _DelayedLength.push (_Delayed.length ()); } +inline unsigned CRecord::forgetParseDelayedListLength () + { unsigned len = _DelayedLength.top(); _DelayedLength.pop (); return len; } + +inline void CRecord::addInstantiateDelayed (Token* start, CTree* tree) + { _InstantiateDelayed[start].push_back (tree); } +inline bool CRecord::haveInstantiateDelayed (Token* start) const + { return _InstantiateDelayed.find (start) != _InstantiateDelayed.end (); } +inline const CRecord::TreeList& CRecord::InstantiateDelayed (Token* start) const + { return _InstantiateDelayed.find (start)->second; } + +inline void CRecord::resetDelayed () + { _Delayed.reset (); _DelayedLength.reset (); _InstantiateDelayed.clear (); } + +} // namespace Puma + +#endif /* __CRecord_h__ */ diff --git a/Puma/src/infos/CScopeInfo.cc b/Puma/src/infos/CScopeInfo.cc new file mode 100644 index 0000000..224ee70 --- /dev/null +++ b/Puma/src/infos/CScopeInfo.cc @@ -0,0 +1,182 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CScopeInfo.h" +#include "Puma/CFunctionInfo.h" +#include "Puma/CNamespaceInfo.h" +#include "Puma/CClassInfo.h" +#include "Puma/CUnionInfo.h" +#include "Puma/CFctInstance.h" +#include "Puma/CClassInstance.h" +#include "Puma/CUnionInstance.h" +#include "Puma/CLocalScope.h" +#include "Puma/CTemplateInfo.h" +#include "Puma/CSemDatabase.h" + +namespace Puma { + + +CScopeInfo::~CScopeInfo () { +} + +bool CScopeInfo::isMethod () const { + return FunctionInfo () && FunctionInfo ()->Record (); +} + +bool CScopeInfo::isClassTemplate () const { + return TemplateInfo () && (TemplateInfo ()->isClass () || + TemplateInfo ()->isAttribute ()); +} + +bool CScopeInfo::isFctTemplate () const { + return TemplateInfo () && TemplateInfo ()->isFunction (); +} + +void CScopeInfo::Parent (const CScopeInfo *info) { + if (_Parent != info) { + if (info != 0) { + ((CScopeInfo*)info)->addChild (this); + } + _Parent = (CScopeInfo*)info; + } +} + +void CScopeInfo::addChild (CScopeInfo *info) { + _Children.append (info); +} + +void CScopeInfo::removeChild (const CScopeInfo *info) { + for (unsigned i = Children (); i > 0; i--) + if (Child (i-1) == info) { + _Children.remove (i-1); + break; + } +} + +CLocalScope *CScopeInfo::newLocalScope () { + CLocalScope *info = SemDB() ? SemDB()->newLocalScope() : new CLocalScope; + info->Parent (this); + return info; +} + +CNamespaceInfo *CScopeInfo::newNamespace () { + CNamespaceInfo *info = SemDB() ? SemDB()->newNamespace() : new CNamespaceInfo; + info->Parent (this); + if (Structure ()) + Structure ()->addNamespace (info); + return info; +} + +CTemplateInfo *CScopeInfo::newTemplate () { + CTemplateInfo *info = SemDB() ? SemDB()->newTemplate() : new CTemplateInfo; + info->Parent (this); + return info; +} + +CFunctionInfo *CScopeInfo::newFunction (bool inst) { + CFunctionInfo *info; + if (inst) + info = SemDB() ? SemDB()->newFctInstance() : new CFctInstance; + else + info = SemDB() ? SemDB()->newFunction() : new CFunctionInfo; + info->Parent (this); + if (Structure ()) + Structure ()->addFunction (info); + return info; +} + +CClassInfo *CScopeInfo::newClass (bool inst) { + CClassInfo *info; + if (inst) + info = SemDB() ? SemDB()->newClassInstance() : new CClassInstance; + else + info = SemDB() ? SemDB()->newClass() : new CClassInfo; + info->Parent (this); + if (Structure ()) + Structure ()->addType (info); + return info; +} + +CUnionInfo *CScopeInfo::newUnion (bool inst) { + CUnionInfo *info; + if (inst) + info = SemDB() ? SemDB()->newUnionInstance() : new CUnionInstance; + else + info = SemDB() ? SemDB()->newUnion() : new CUnionInfo; + info->Parent (this); + if (Structure ()) + Structure ()->addType (info); + return info; +} + +void CScopeInfo::deleteLocalScope (const CLocalScope *info) { + for (unsigned i = Children (); i > 0; i--) + if (Child (i-1) == (CScopeInfo*)info) { + delete (CLocalScope*)_Children[i-1]; + _Children.remove (i-1); + break; + } +} + +void CScopeInfo::deleteNamespace (const CNamespaceInfo *info) { + for (unsigned i = Children (); i > 0; i--) + if (Child (i-1) == (CScopeInfo*)info) { + delete (CNamespaceInfo*)_Children[i-1]; + _Children.remove (i-1); + break; + } +} + +void CScopeInfo::deleteTemplate (const CTemplateInfo *info) { + for (unsigned i = Children (); i > 0; i--) + if (Child (i-1) == (CScopeInfo*)info) { + delete (CTemplateInfo*)_Children[i-1]; + _Children.remove (i-1); + break; + } +} + +void CScopeInfo::deleteFunction (const CFunctionInfo *info) { + for (unsigned i = Children (); i > 0; i--) + if (Child (i-1) == (CScopeInfo*)info) { + delete (CFunctionInfo*)_Children[i-1]; + _Children.remove (i-1); + break; + } +} + +void CScopeInfo::deleteClass (const CClassInfo *info) { + for (unsigned i = Children (); i > 0; i--) + if (Child (i-1) == (CScopeInfo*)info) { + delete (CClassInfo*)_Children[i-1]; + _Children.remove (i-1); + break; + } +} + +void CScopeInfo::deleteUnion (const CUnionInfo *info) { + for (unsigned i = Children (); i > 0; i--) + if (Child (i-1) == (CScopeInfo*)info) { + delete (CUnionInfo*)_Children[i-1]; + _Children.remove (i-1); + break; + } +} + + +} // namespace Puma diff --git a/Puma/src/infos/CScopeInfo.h b/Puma/src/infos/CScopeInfo.h new file mode 100644 index 0000000..16dd706 --- /dev/null +++ b/Puma/src/infos/CScopeInfo.h @@ -0,0 +1,218 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CScopeInfo_h__ +#define __CScopeInfo_h__ + +/** \file + * Semantic information about a scope. */ + +#include "Puma/CObjectInfo.h" +#include "Puma/Array.h" + +namespace Puma { + + +class CLocalScope; +class CFunctionInfo; +class CNamespaceInfo; +class CClassInfo; +class CUnionInfo; +class CTemplateInfo; + +/** \class CScopeInfo CScopeInfo.h Puma/CScopeInfo.h + * Semantic information about a scope. Several syntactic + * constructs have its own scope, such as class definitions, + * functions, and compound statements. */ +class CScopeInfo : public CObjectInfo { + Array _Children; // child scopes + CScopeInfo *_Parent; // parent scope + +protected: + /** Constructor. + * \param id The object type. */ + CScopeInfo (ObjectId id); + +public: + /** Destructor. */ + ~CScopeInfo (); + + /** Get the number of child scopes (nested scopes). */ + unsigned Children () const; + /** Get the n-th child scope. + * \param n The index of the child scope. + * \return The n-th child scope or NULL. */ + CScopeInfo *Child (unsigned) const; + /** Get the parent scope of this scope. The top + * scope is the file scope. + * \return The parent scope, or this scope if no parent. */ + CScopeInfo *Parent () const; + /** Check if this is a file (file scope). */ + bool isFile () const; + /** Check if this is namespace. */ + bool isNamespace () const; + /** Check if this is class or union. */ + bool isRecord () const; + /** Check if this is a class. */ + bool isClass () const; + /** Check if this is a union. */ + bool isUnion () const; + /** Check if this is a function. */ + bool isFunction () const; + /** Check if this is a class method. */ + bool isMethod () const; + /** Check if this is a class template. */ + bool isClassTemplate () const; + /** Check if this is a function template. */ + bool isFctTemplate () const; + /** Check if this is a local scope. */ + bool isLocalScope () const; + /** Check if this is a local class or union. */ + bool isLocalRecord () const; + /** Check if this is a local class. */ + bool isLocalClass () const; + /** Check if this is a local union. */ + bool isLocalUnion () const; + /** Check if this is the global (file) scope. */ + bool GlobalScope () const; + + /** Check if this scope is inside a class or + * function template scope. */ + bool insideTemplate () const; + /** Check if this scope is inside a class or + * union scope. */ + bool insideRecord () const; + /** Check if this scope is inside a class scope. */ + bool insideClass () const; + /** Check if this scope is inside a union scope. */ + bool insideUnion () const; + /** Check if this scope is inside a function scope. */ + bool insideFunction () const; + /** Check if this scope is inside a class method scope. */ + bool insideMethod () const; + + /** Set the parent scope of this scope. + * \param scope The parent scope. */ + void Parent (const CScopeInfo *scope); + /** Add a child scope to this scope. + * \param scope The child scope. */ + void addChild (CScopeInfo *scope); + /** Remove a child scope. + * \param scope The child scope. */ + void removeChild (const CScopeInfo *scope); + + /** Create a new local scope information object. */ + CLocalScope *newLocalScope (); + /** Create a new function or function template + * instance semantic object. + * \param inst \e true if to a function template instance. */ + CFunctionInfo *newFunction (bool inst = false); + /** Create a new class or class template + * instance semantic object. + * \param inst \e true if to a class template instance. */ + CClassInfo *newClass (bool inst = false); + /** Create a new union or union template + * instance semantic object. + * \param inst \e true if to a union template instance. */ + CUnionInfo *newUnion (bool inst = false); + /** Create a new namespace semantic object. */ + CNamespaceInfo *newNamespace (); + /** Create a new template semantic object. */ + CTemplateInfo *newTemplate (); + + /** Delete the given local scope semantic object. + * \param scope The local scope. */ + void deleteLocalScope (const CLocalScope *scope); + /** Delete the given function semantic object. + * \param fct The function. */ + void deleteFunction (const CFunctionInfo *fct); + /** Delete the given class semantic object. + * \param c The class. */ + void deleteClass (const CClassInfo *c); + /** Delete the given union semantic object. + * \param u The union. */ + void deleteUnion (const CUnionInfo *u); + /** Delete the given namespace semantic object. + * \param ns The namespace. */ + void deleteNamespace (const CNamespaceInfo *ns); + /** Delete the given template semantic object. + * \param tpl The template. */ + void deleteTemplate (const CTemplateInfo *tpl); +}; + + +inline CScopeInfo::CScopeInfo (CObjectInfo::ObjectId id) : + CObjectInfo (id), + _Children (1, 20), + _Parent ((CScopeInfo*)this) + {} + +inline unsigned CScopeInfo::Children () const + { return _Children.length (); } +inline CScopeInfo *CScopeInfo::Child (unsigned n) const + { return _Children.lookup (n); } +inline CScopeInfo *CScopeInfo::Parent () const + { return _Parent; } + +inline bool CScopeInfo::isLocalScope () const + { return LocalScope (); } +inline bool CScopeInfo::isFile () const + { return FileInfo (); } +inline bool CScopeInfo::isNamespace () const + { return NamespaceInfo (); } +inline bool CScopeInfo::isRecord () const + { return Record (); } +inline bool CScopeInfo::isClass () const + { return ClassInfo (); } +inline bool CScopeInfo::isUnion () const + { return UnionInfo (); } +inline bool CScopeInfo::isFunction () const + { return FunctionInfo (); } +inline bool CScopeInfo::GlobalScope () const + { return FileInfo (); } + +inline bool CScopeInfo::insideFunction () const + { return isFunction () || (Parent () && Parent () != this && + Parent ()->insideFunction ()); } +inline bool CScopeInfo::insideMethod () const + { return isMethod () || (Parent () && Parent () != this && + Parent ()->insideMethod ()); } +inline bool CScopeInfo::insideRecord () const + { return isRecord () || (Parent () && Parent () != this && + Parent ()->insideRecord ()); } +inline bool CScopeInfo::insideTemplate () const + { return isTemplate () || (Parent () && Parent () != this && + Parent ()->insideTemplate ()); } +inline bool CScopeInfo::insideClass () const + { return isClass () || (Parent () && Parent () != this && + Parent ()->insideClass ()); } +inline bool CScopeInfo::insideUnion () const + { return isUnion () || (Parent () && Parent () != this && + Parent ()->insideUnion ()); } + +inline bool CScopeInfo::isLocalClass () const + { return isClass () && insideFunction (); } +inline bool CScopeInfo::isLocalUnion () const + { return isUnion () && insideFunction (); } +inline bool CScopeInfo::isLocalRecord () const + { return isRecord () && insideFunction (); } + + +} // namespace Puma + +#endif /* __CScopeInfo_h__ */ diff --git a/Puma/src/infos/CScopeRequest.h b/Puma/src/infos/CScopeRequest.h new file mode 100644 index 0000000..ae0c739 --- /dev/null +++ b/Puma/src/infos/CScopeRequest.h @@ -0,0 +1,70 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CScopeRequest_h__ +#define __CScopeRequest_h__ + +/** \file + * Additional scope information. */ + +#include "Puma/CObjectInfo.h" + +namespace Puma { + + +class CScopeInfo; + + +/** \class CScopeRequest CScopeRequest.h Puma/CScopeRequest.h + * Provides additional scope information for semantic + * objects that are not scopes itself (like objects). */ +class CScopeRequest : public CObjectInfo { + CScopeInfo *_Scope; + +protected: + /** Constructor. + * \param id The object type. */ + CScopeRequest (ObjectId id); + +public: + /** Destructor. */ + ~CScopeRequest (); + + /** Get the enclosing scope. */ + CScopeInfo *Scope () const; + /** Set the enclosing scope. + * \param scope The scope. */ + void Scope (CScopeInfo *scope); +}; + +inline CScopeRequest::CScopeRequest (CObjectInfo::ObjectId id) : + CObjectInfo (id), + _Scope ((CScopeInfo*)0) + {} +inline CScopeRequest::~CScopeRequest () + {} + +inline CScopeInfo *CScopeRequest::Scope () const + { return _Scope; } +inline void CScopeRequest::Scope (CScopeInfo *s) + { _Scope = s; } + + +} // namespace Puma + +#endif /* __CScopeRequest_h__ */ diff --git a/Puma/src/infos/CSemDatabase.cc b/Puma/src/infos/CSemDatabase.cc new file mode 100644 index 0000000..21758fb --- /dev/null +++ b/Puma/src/infos/CSemDatabase.cc @@ -0,0 +1,776 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CEnumeratorInfo.h" +#include "Puma/CTemplateParamInfo.h" +#include "Puma/CSemDatabase.h" +#include "Puma/CAttributeInfo.h" +#include "Puma/CFunctionInfo.h" +#include "Puma/CArgumentInfo.h" +#include "Puma/CAttributeInfo.h" +#include "Puma/CBaseClassInfo.h" +#include "Puma/CTypedefInfo.h" +#include "Puma/CTemplateInstance.h" +#include "Puma/CTemplateInfo.h" +#include "Puma/CObjectInfo.h" +#include "Puma/CScopeInfo.h" +#include "Puma/CUnionInfo.h" +#include "Puma/CClassInfo.h" +#include "Puma/CFileInfo.h" +#include "Puma/CEnumInfo.h" +#include "Puma/CTypeInfo.h" +#include "Puma/CUsingInfo.h" +#include "Puma/CNamespaceInfo.h" +#include "Puma/CClassInstance.h" +#include "Puma/CFctInstance.h" +#include "Puma/CLabelInfo.h" +#include "Puma/CLocalScope.h" +#include "Puma/CMemberAliasInfo.h" +#include "Puma/CTemplateInstance.h" +#include "Puma/CUnionInstance.h" +#include "Puma/ErrorStream.h" +#include "Puma/CProject.h" +#include "Puma/Token.h" +#include "Puma/Unit.h" +#include +#include +#include +#include + +namespace Puma { + + +CSemDatabase::~CSemDatabase () { + ObjectSet::iterator i = _Objects.begin(); + for (; i != _Objects.end(); ++i) { + CObjectInfo* o = *i; + switch (o->Id()) { + case CObjectInfo::FILE_INFO: delete (CFileInfo*)o; break; + case CObjectInfo::UNION_INFO: delete (CUnionInfo*)o; break; + case CObjectInfo::CLASS_INFO: delete (CClassInfo*)o; break; + case CObjectInfo::BASECLASS_INFO: delete (CBaseClassInfo*)o; break; + case CObjectInfo::MEMBERALIAS_INFO: delete (CMemberAliasInfo*)o; break; + case CObjectInfo::ENUM_INFO: delete (CEnumInfo*)o; break; + case CObjectInfo::TYPEDEF_INFO: delete (CTypedefInfo*)o; break; + case CObjectInfo::FUNCTION_INFO: delete (CFunctionInfo*)o; break; + case CObjectInfo::LABEL_INFO: delete (CLabelInfo*)o; break; + case CObjectInfo::ENUMERATOR_INFO: delete (CEnumeratorInfo*)o; break; + case CObjectInfo::ATTRIBUTE_INFO: delete (CAttributeInfo*)o; break; + case CObjectInfo::TEMPLATE_PARAM_INFO: delete (CTemplateParamInfo*)o; break; + case CObjectInfo::TEMPLATE_INFO: delete (CTemplateInfo*)o; break; + case CObjectInfo::CLASS_INSTANCE_INFO: delete (CClassInstance*)o; break; + case CObjectInfo::UNION_INSTANCE_INFO: delete (CUnionInstance*)o; break; + case CObjectInfo::FCT_INSTANCE_INFO: delete (CFctInstance*)o; break; + case CObjectInfo::ARGUMENT_INFO: delete (CArgumentInfo*)o; break; + case CObjectInfo::LOCAL_INFO: delete (CLocalScope*)o; break; + case CObjectInfo::NAMESPACE_INFO: delete (CNamespaceInfo*)o; break; + case CObjectInfo::USING_INFO: delete (CUsingInfo*)o; break; + default: break; + } + } +} + +void CSemDatabase::Insert (CObjectInfo *info) { + if (! info) + return; + + _Objects.insert (info); + info->SemDB (this); + + if (info->Name ()) { + if (info->ClassInfo ()) + _Classes.append (info); + else if (info->UnionInfo ()) + _Unions.append (info); + else if (info->EnumInfo ()) + _Enums.append (info); + else if (info->TypedefInfo ()) + _Typedefs.append (info); + else if (info->FunctionInfo ()) + _Functions.append (info); + else if (info->FileInfo ()) + _Files.append (info); + } +} + +void CSemDatabase::Remove (CObjectInfo *info) { + if (! info) + return; + + _Objects.erase (info); + + if (info->ClassInfo ()) { + for (long i = ClassInfos (); i > 0; i--) + if (_Classes.fetch (i-1) == info) + _Classes.remove (i-1); + } else if (info->UnionInfo ()) { + for (long i = UnionInfos (); i > 0; i--) + if (_Unions.fetch (i-1) == info) + _Unions.remove (i-1); + } else if (info->EnumInfo ()) { + for (long i = EnumInfos (); i > 0; i--) + if (_Enums.fetch (i-1) == info) + _Enums.remove (i-1); + } else if (info->TypedefInfo ()) { + for (long i = TypedefInfos (); i > 0; i--) + if (_Typedefs.fetch (i-1) == info) + _Typedefs.remove (i-1); + } else if (info->FunctionInfo ()) { + for (long i = FunctionInfos (); i > 0; i--) + if (_Functions.fetch (i-1) == info) + _Functions.remove (i-1); + } else if (info->FileInfo ()) { + for (long i = FileInfos (); i > 0; i--) + if (_Files.fetch (i-1) == info) + _Files.remove (i-1); + } + + return; // Unknown! +} + +CFunctionInfo *CSemDatabase::BuiltinOperator (const char *name, int tok, + CTypeInfo *rtype, CTypeInfo *t0, CTypeInfo *t1) { + CFunctionInfo *info; + CTypeList *args; + CTypeInfo *type; + + // first check if this built-in operator already exists ... + std::multimap::iterator iter, lower, upper; + lower = _builtin_ops.lower_bound (tok); + upper = _builtin_ops.upper_bound (tok); + // check all exisiting operators with the right token type + for (iter = lower; iter != upper; ++iter) { + info = iter->second; + args = info->TypeInfo ()->ArgTypes (); + // same number of arguments? + if (args->Entries () == (unsigned)((t0?1:0) + (t1?1:0))) { + // same parameter type list + if ((t0 ? *t0 == *args->Entry (0) : true) && + (t1 ? *t1 == *args->Entry (1) : true)) { + if (t0) CTypeInfo::Destroy (t0); + if (t1) CTypeInfo::Destroy (t1); + if (rtype) CTypeInfo::Destroy (rtype); + return info; // operator already exists + } + } + } + + // the operator object has to be created ... + // return type + if (! rtype) + rtype = &CTYPE_UNDEFINED; + + // parameter type list + args = new CTypeList ((t0?1:0)+(t1?1:0)); + if (t0) args->AddEntry (t0); + if (t1) args->AddEntry (t1); + + // operator function type + type = new CTypeFunction (rtype, args, true); + + // operator function + info = newFunction(); + info->Name (name); + info->isOperator (true); + info->ObjectInfo ()->TypeInfo (type); + type->VirtualType ()->TypeFunction ()->FunctionInfo (info); + + // create function parameters + if (t0) CreateParameter (info, t0); + if (t1) CreateParameter (info, t1); + + // insert the object into the map + _builtin_ops.insert (std::multimap::value_type (tok, info)); + + return info; +} + +void CSemDatabase::CreateParameter (CFunctionInfo *fi, CTypeInfo *type) const { + CArgumentInfo *info; + info = fi->newArgument (); + info->Name (""); + info->Storage (CStorage::CLASS_AUTOMATIC); + info->TypeInfo (type->Duplicate ()); +} + +CObjectInfo *CSemDatabase::ObjectInfo (Token *token) const { + ObjectSet::const_iterator i = _Objects.begin(); + for (; i != _Objects.end(); ++i) { + CObjectInfo *info = (CObjectInfo*)*i; + if (! info->FileInfo ()) + if (*info->SourceInfo () == token) + return info; + } + return (CObjectInfo*)0; +} + +CObjectInfo *CSemDatabase::ObjectInfo (CT_Token *token) const { + ObjectSet::const_iterator i = _Objects.begin(); + for (; i != _Objects.end(); ++i) { + CObjectInfo *info = (CObjectInfo*)*i; + if (! info->FileInfo ()) + if (*info->SourceInfo () == token) + return info; + } + return (CObjectInfo*)0; +} + +CObjectInfo *CSemDatabase::ObjectInfo (unsigned i) const { + ObjectSet::const_iterator o = _Objects.begin(); + for (unsigned j = 0; j != i && o != _Objects.end(); ++j, ++o); + return (o != _Objects.end()) ? (CObjectInfo*)*o : (CObjectInfo*)0; +} + + +void CSemDatabase::Dump (std::ostream &out, int level, bool dump_builtins) const { + unsigned files = FileInfos (); + CStructure *file; + int count = 0; + + for (unsigned i = 0; i < files; i++) { + file = FileInfo (i); + out << "file " << count++ << " : " << file->Name () << std::endl; + Dump (out, file, 0, level, dump_builtins); + } + + if (dump_builtins) { + out << "built-in operators" << std::endl; + std::multimap::const_iterator iter; + for (iter = _builtin_ops.begin(); iter != _builtin_ops.end(); ++iter) { + DumpFunction (out, (CFunctionInfo*) iter->second, 0, level); + } + } +} + +void CSemDatabase::Dump (std::ostream &out, CStructure *scope, int ind, int level, bool dump_builtins) const { + unsigned num; + + if (! scope || (ind / 4) > level) + return; + + // Template parameter (print on template scope only) + num = scope->TemplateParams (); + if (num && scope->TemplateInfo ()) { + indent (out, ind+2); out << num << " template parameters:" << std::endl; + for (unsigned j = 0; j < num; j++) { + CTemplateParamInfo* param = scope->TemplateParam (j); + if (param && (dump_builtins || ! param->isBuiltin ())) + DumpTemplateParam (out, param, ind); + } + } + + // Template instances (print on template scope only) + if (scope->TemplateInfo ()) { + num = scope->TemplateInfo ()->Instances (); + indent (out, ind+2); out << num << " template instances:" << std::endl; + for (unsigned j = 0; j < num; j++) { + CObjectInfo* inst = scope->TemplateInfo ()->Instance (j); + if (inst) + DumpTemplateInstance (out, inst, ind); + } + } + + // Types + num = scope->Types (); + if (num) { + indent (out, ind+2); out << num << " types:" << std::endl; + for (unsigned j = 0; j < num; j++) { + CObjectInfo* type = scope->Type (j); + if (type && (dump_builtins || ! type->isBuiltin ())) + DumpType (out, type, ind); + } + } + + // Namespaces + num = scope->Namespaces (); + if (num) { + indent (out, ind+2); out << num << " namespaces:" << std::endl; + for (unsigned j = 0; j < num; j++) { + CNamespaceInfo* ns = scope->Namespace (j); + if (ns && (dump_builtins || ! ns->isBuiltin () || (ns->Name () && *ns->Name ().c_str() == '%'))) + DumpNamespace (out, ns, ind); + } + } + + // Usings + num = scope->Usings (); + if (num) { + indent (out, ind+2); out << num << " usings:" << std::endl; + for (unsigned j = 0; j < num; j++) { + CUsingInfo* ui = scope->Using (j); + if (ui && (dump_builtins || ! ui->isBuiltin ())) + DumpUsing (out, ui, ind); + } + } + + // Attributes + num = scope->Attributes (); + if (num) { + indent (out, ind+2); out << num << " attributes: " << std::endl; + for (unsigned j = 0; j < num; j++) { + CAttributeInfo* attr = scope->Attribute (j); + if (attr && (dump_builtins || ! attr->isBuiltin ())) + DumpAttribute (out, attr, ind); + } + } + + // Functions + num = scope->Functions (); + if (num) { + indent (out, ind+2); out << num << " functions:" << std::endl; + for (unsigned j = 0; j < num; j++) { + CFunctionInfo* fct = scope->Function (j); + if (fct && (dump_builtins || ! fct->isBuiltin ())) + DumpFunction (out, fct, ind, level); + } + } + + // Local scopes + num = scope->Children (); + if (num) { + indent (out, ind+2); out << num << " scopes:" << std::endl; + for (unsigned j = 0; j < num; j++) { + CStructure *ls = scope->Child (j)->Structure (); + if (ls && (dump_builtins || ! ls->isBuiltin () || + (ls->NamespaceInfo () && ls->Name () && *ls->Name ().c_str() == '%'))) { + DumpLocalScope (out, ls, ind); + Dump (out, ls, ind+4, level, dump_builtins); + } + } + } +} + +void CSemDatabase::DumpLocalScope (std::ostream &out, CObjectInfo *info, int ind) const { + indent (out, ind+4); + if (info->Record () || info->NamespaceInfo () || + info->FunctionInfo () || info->TemplateInfo ()) { + if (info->UnionInfo ()) + out << "union"; + else if (info->ClassInfo ()) + out << (info->ClassInfo ()->isStruct () ? "struct" : "class"); + else if (info->NamespaceInfo ()) + out << "namespace"; + else if (info->FunctionInfo ()) + out << "function"; + else if (info->TemplateInfo ()) + out << "template"; + out << " : " << info->Name (); + } else + out << "block"; + out << "\t"; + if (info->ClassInfo ()) { + unsigned base_classes = info->ClassInfo ()->BaseClasses (); + if (base_classes) { + out << "[base classes: "; + for (unsigned i = 0; i < base_classes; i++) { + CClassInfo *cinfo = info->ClassInfo ()->BaseClass (i)->Class (); + if (cinfo && cinfo->TypeInfo ()) { + cinfo->TypeInfo ()->TypeText (out); + if (i+1 < base_classes) + out << ","; + } + } + out << "] "; + } + } + DumpQualities (out, info); + out << std::endl; +} + +void CSemDatabase::DumpFunction (std::ostream &out, CFunctionInfo *info, int ind, int level) const { + indent (out, ind+4); + out << info->Name () << "\t (type: "; + info->TypeInfo ()->TypeText (out); + out << ") "; + + if (info->ObjectInfo()->QualifiedScope () && info->ObjectInfo()->QualifiedScope () != info->Scope ()) { + out << " [member of "; + DumpScopeName (out, info->ObjectInfo()->QualifiedScope ()); + out << "]"; + } + DumpFriends (out, info); + if (info->isDestructor ()) + out << " [destructor]"; + else if (info->isConstructor ()) + out << " [constructor]"; + if (! info->isDefined () && ! info->isBuiltin ()) + out << " [undefined]"; + if (info->isOperator () || info->isConversion ()) + out << " [operator]"; + + DumpQualities (out, info); + out << std::endl; + + if (level == 0) + return; +} + +void CSemDatabase::DumpFriends (std::ostream &out, CStructure *info) const { + CStructure* sinfo = info; + do { + unsigned friends = sinfo->Friends (); + if (friends) { + out << " [friend of "; + for (unsigned i = 0; i < friends; i++) { + CRecord *friend_class = sinfo->Friend (i); + if (friend_class && friend_class->TypeInfo ()) { + DumpScopeName (out, friend_class); + if (i+1 < friends) + out << ","; + } + } + out << "]"; + } + sinfo = sinfo->NextObject () ? sinfo->NextObject ()->Structure () : 0; + } while (sinfo && sinfo != info); +} + +void CSemDatabase::DumpAttribute (std::ostream &out, CAttributeInfo *info, int ind) const { + indent (out, ind+4); + out << info->Name () << "\t (type: "; + info->TypeInfo ()->TypeText (out); + out << ") "; + + if (info->ObjectInfo()->QualifiedScope () && info->ObjectInfo()->QualifiedScope () != info->Scope ()) { + out << " [member of "; + DumpScopeName (out, info->ObjectInfo()->QualifiedScope ()); + out << "]"; + } + if (info->TypeInfo ()->isVarArray ()) + out << " [dim: variable]"; + else if ((info->TypeInfo ()->isArray () || info->TypeInfo ()->isBitField ()) && + info->TypeInfo ()->Dimension () != -1) + out << " [dim: " << info->TypeInfo ()->Dimension () << "]"; + else if (info->EnumeratorInfo ()) + out << " [value: " << info->EnumeratorInfo ()->Value () << "]"; + + DumpQualities (out, info); + out << std::endl; +} + +void CSemDatabase::DumpType (std::ostream &out, CObjectInfo *info, int ind) const { + indent (out, ind+4); + if (info->TypedefInfo ()) + out << "typedef "; + else if (info->UnionInfo ()) + out << "union "; + else if (info->EnumInfo ()) + out << "enum "; + else if (info->ClassInfo ()) + out << (info->ClassInfo ()->isStruct () ? "struct " : "class "); + out << ": " << info->Name () << "\t"; + if (info->EnumInfo ()) { + out << " (underlying type: "; + info->EnumInfo ()->TypeInfo ()->UnderlyingType ()->TypeText (out); + out << ") "; + } else if (info->TypedefInfo ()) { + out << " (type: "; + info->TypeInfo ()->TypeText (out); + out << ") "; + } else if (info->ClassInfo ()) { + unsigned base_classes = info->ClassInfo ()->BaseClasses (); + if (base_classes) { + out << "[base classes: "; + for (unsigned i = 0; i < base_classes; i++) { + CClassInfo *cinfo = info->ClassInfo ()->BaseClass (i)->Class (); + if (cinfo && cinfo->TypeInfo ()) { + cinfo->TypeInfo ()->TypeText (out); + if (i+1 < base_classes) + out << ","; + } + } + out << "]"; + } + DumpFriends (out, info->ClassInfo ()); + } + DumpQualities (out, info); + out << std::endl; +} + +void CSemDatabase::DumpTemplateParam (std::ostream &out, CTemplateParamInfo *info, int ind) const { + indent (out, ind+4); + out << info->Name () << "\t"; + if (info->isTemplate ()) + out << " [template] "; + else if (info->isTypeParam ()) + out << " [type] "; + else + out << " [non-type] "; + out << std::endl; +} + +void CSemDatabase::DumpTemplateInstance (std::ostream &out, CObjectInfo *info, int ind) const { + indent (out, ind+4); + out << info->Name (); + CTemplateInstance *instance = info->TemplateInstance (); + out << "<"; + std::ostringstream os; + for (unsigned i = 0; i < instance->InstantiationArgs (); i++) { + DeducedArgument *arg = instance->InstantiationArg (i); + if (arg->isDefaultArg ()) + break; + os << (i ? "," : "") << *arg; + } + std::string args = os.str (); + out << args; + if (args.size () && args.at (args.size () - 1) == '>') + out << " "; + out << ">\t"; + if (instance->isPseudoInstance ()) + out << " [pseudo] "; + if (instance->isInstantiated ()) + out << " [instantiated] "; + else if (instance->canInstantiate ()) + out << " [instantiable] "; + out << " [" << (void*)info << "]"; + out << std::endl; +} + +void CSemDatabase::DumpNamespace (std::ostream &out, CNamespaceInfo *info, int ind) const { + CNamespaceInfo *nsinfo; + indent (out, ind+4); + out << "namespace : " << info->Name () << "\t"; + if (info->isAlias ()) { + nsinfo = info; + while (nsinfo->isAlias ()) { + nsinfo = (CNamespaceInfo*)nsinfo->NextObject (); + if (nsinfo == info) // should never be true + break; + } + out << " [alias of "; + DumpScopeName (out, nsinfo); + out << "]"; + } + DumpQualities (out, info); + out << std::endl; +} + +void CSemDatabase::DumpUsing (std::ostream &out, CUsingInfo *info, int ind) const { + CNamespaceInfo *nsinfo = info->Namespace (); + indent (out, ind+4); + out << "using namespace " << ": "; + DumpScopeName (out, nsinfo); + out << std::endl; +} + +void CSemDatabase::DumpQualities (std::ostream &out, CObjectInfo *info) const { + if (info->isTemplate ()) + out << " [template]"; + if (info->TemplateInfo () && ! info->TemplateInfo ()->isBaseTemplate ()) + out << " [specialization of " << (void*)info->TemplateInfo ()->BaseTemplate () << "]"; + if (info->NamespaceInfo () && info->Name () && *info->Name ().c_str() == '%') + out << " [instance scope]"; + if (info->isTemplateInstance ()) { + if (info->TemplateInstance ()->isPseudoInstance ()) + out << " [pseudo instance]"; + else + out << " [instance of " + << (void*)info->TemplateInstance ()->Template () << "]"; + } + + // dump member access level + if (info->Protection () == CProtection::PROT_PROTECTED) + out << " [protected]"; + else if (info->Protection () == CProtection::PROT_PRIVATE) + out << " [private]"; +// else if (info->Protection () == CProtection::PROT_PUBLIC) +// out << " [public]"; + + // dump linkage + if (! (info->Language () == CLanguage::LANG_UNDEFINED)) + out << " [language: " << info->Language ().Text () << "]"; + + // dump type qualities + if (info->TypeInfo () && info->TypeInfo ()->isVolatile ()) + out << " [volatile]"; + if (info->TypeInfo () && info->TypeInfo ()->isConst ()) + out << " [const]"; + + if (info->isBuiltin ()) + out << " [built-in]"; + if (info->isInline ()) + out << " [inline]"; + if (info->isAnonymous ()) + out << " [anonymous]"; + + if (info->isVirtual ()) + out << " [virtual]"; + if (info->isStatic ()) + out << " [static]"; + if (info->isExtern () || info->Linkage () == CLinkage::LINK_EXTERNAL) + out << " [extern]"; + if (info->isMutable ()) + out << " [mutable]"; + if (info->isRegister ()) + out << " [register]"; + + // dump storage class + if (info->Storage () == CStorage::CLASS_DYNAMIC) + out << " [dynamic]"; + else if (info->Storage () == CStorage::CLASS_THREAD) + out << " [thread-local]"; +// else if (info->Storage () == CStorage::CLASS_STATIC) +// out << " [static]"; +// else if (info->Storage () == CStorage::CLASS_AUTOMATIC) +// out << " [automatic]"; + + // dump address + out << " [" << (void*)info << "]"; + // dump next linked object + if (info->NextObject () != info) + out << " [next: " << (void*)info->NextObject () << "]"; +} + +void CSemDatabase::DumpScopeName (std::ostream &out, CStructure *scope) const { + if (scope->FileInfo ()) + return; + + CStructure *parent = scope->Parent ()->Structure (); + if (parent->isRecord () || parent->isNamespace ()) { + DumpScopeName (out, parent); + out << "::" << scope->Name (); + } else + out << scope->Name (); +} + +void CSemDatabase::indent (std::ostream &out, int ind) const { + for (int i = 0; i < ind; i++) + out << " "; +} + +CArgumentInfo *CSemDatabase::newArgument () { + CArgumentInfo *info = new CArgumentInfo(); + Insert (info); + return info; +} + +CAttributeInfo *CSemDatabase::newAttribute () { + CAttributeInfo *info = new CAttributeInfo(); + Insert (info); + return info; +} + +CBaseClassInfo *CSemDatabase::newBaseClass () { + CBaseClassInfo *info = new CBaseClassInfo(); + Insert (info); + return info; +} + +CClassInfo *CSemDatabase::newClass () { + CClassInfo *info = new CClassInfo(); + Insert (info); + return info; +} + +CClassInstance *CSemDatabase::newClassInstance () { + CClassInstance *info = new CClassInstance(); + Insert (info); + return info; +} + +CEnumInfo *CSemDatabase::newEnum () { + CEnumInfo *info = new CEnumInfo(); + Insert (info); + return info; +} + +CEnumeratorInfo *CSemDatabase::newEnumerator () { + CEnumeratorInfo *info = new CEnumeratorInfo(); + Insert (info); + return info; +} + +CFunctionInfo *CSemDatabase::newFunction () { + CFunctionInfo *info = new CFunctionInfo(); + Insert (info); + return info; +} + +CFctInstance *CSemDatabase::newFctInstance () { + CFctInstance *info = new CFctInstance(); + Insert (info); + return info; +} + +CLabelInfo *CSemDatabase::newLabel () { + CLabelInfo *info = new CLabelInfo(); + Insert (info); + return info; +} + +CLocalScope *CSemDatabase::newLocalScope () { + CLocalScope *info = new CLocalScope(); + Insert (info); + return info; +} + +CMemberAliasInfo *CSemDatabase::newMemberAlias () { + CMemberAliasInfo *info = new CMemberAliasInfo(); + Insert (info); + return info; +} + +CNamespaceInfo *CSemDatabase::newNamespace () { + CNamespaceInfo *info = new CNamespaceInfo(); + Insert (info); + return info; +} + +CTemplateInfo *CSemDatabase::newTemplate () { + CTemplateInfo *info = new CTemplateInfo(); + Insert (info); + return info; +} + +CTemplateParamInfo *CSemDatabase::newTemplateParam () { + CTemplateParamInfo *info = new CTemplateParamInfo(); + Insert (info); + return info; +} + +CTypedefInfo *CSemDatabase::newTypedef () { + CTypedefInfo *info = new CTypedefInfo(); + Insert (info); + return info; +} + +CUnionInfo *CSemDatabase::newUnion () { + CUnionInfo *info = new CUnionInfo(); + Insert (info); + return info; +} + +CUnionInstance *CSemDatabase::newUnionInstance () { + CUnionInstance *info = new CUnionInstance(); + Insert (info); + return info; +} + +CUsingInfo *CSemDatabase::newUsing () { + CUsingInfo *info = new CUsingInfo(); + Insert (info); + return info; +} + +CFileInfo *CSemDatabase::newFile () { + CFileInfo *info = new CFileInfo(); + Insert (info); + return info; +} + +} // namespace Puma diff --git a/Puma/src/infos/CSemDatabase.h b/Puma/src/infos/CSemDatabase.h new file mode 100644 index 0000000..406f108 --- /dev/null +++ b/Puma/src/infos/CSemDatabase.h @@ -0,0 +1,259 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CSemDatabase_h__ +#define __CSemDatabase_h__ + +/** \file + * Semantic information database. */ + +#include "Puma/CScopeInfo.h" +#include "Puma/CProject.h" +#include +#include +#include + +namespace Puma { + + +class CObjectInfo; +class CArgumentInfo; +class CAttributeInfo; +class CBaseClassInfo; +class CClassInfo; +class CClassInstance; +class CEnumInfo; +class CEnumeratorInfo; +class CFunctionInfo; +class CFctInstance; +class CLabelInfo; +class CLocalScope; +class CMemberAliasInfo; +class CNamespaceInfo; +class CTemplateInfo; +class CTemplateInstance; +class CTemplateParamInfo; +class CTypedefInfo; +class CUnionInfo; +class CUnionInstance; +class CTypeInfo; +class CFileInfo; +class Token; + + +/** \class CSemDatabase CSemDatabase.h Puma/CSemDatabase.h + * Semantic information database. Contains all semantic objects + * created during the semantic analysis for one translation + * unit. */ +class CSemDatabase { +public: + typedef std::set ObjectSet; + +private: + Array _Classes; // index of classes + Array _Unions; // index of unions + Array _Enums; // index of enums + Array _Typedefs; // index of typedefs + Array _Functions; // index of functions + Array _Files; // index of files + + CProject *_Project; // associated project + + ObjectSet _Objects; // set of all semantic objects + std::multimap _builtin_ops; // map for built-in operator lookup + +public: + /** Constructor. + * \param prj The project information. + * \param size Initial size of the database (not yet used!). */ + CSemDatabase (CProject &prj, int size = 997); + /** Destructor. Destroys all semantic information objects in + * the database. */ + virtual ~CSemDatabase (); + + /** Get the set of all semantic objects. */ + ObjectSet& Objects(); + + /** Get the number of semantic objects. */ + unsigned ObjectInfos () const; + /** Get the number of semantic objects for classes. */ + unsigned ClassInfos () const; + /** Get the number of semantic objects for unions. */ + unsigned UnionInfos () const; + /** Get the number of semantic objects for enumerations. */ + unsigned EnumInfos () const; + /** Get the number of semantic objects for typedefs. */ + unsigned TypedefInfos () const; + /** Get the number of semantic objects for functions. */ + unsigned FunctionInfos () const; + /** Get the number of semantic objects for translation units (file scope). */ + unsigned FileInfos () const; + + /** Get the n-th semantic object. + * \param n The index of the object. + * \return The object or NULL if \e n is invalid. */ + CObjectInfo *ObjectInfo (unsigned n) const; + /** Get the n-th semantic object for classes. + * \param n The index of the object. + * \return The object or NULL if \e n is invalid. */ + CClassInfo *ClassInfo (unsigned n) const; + /** Get the n-th semantic object for unions. + * \param n The index of the object. + * \return The object or NULL if \e n is invalid. */ + CUnionInfo *UnionInfo (unsigned n) const; + /** Get the n-th semantic object for enumerations. + * \param n The index of the object. + * \return The object or NULL if \e n is invalid. */ + CEnumInfo *EnumInfo (unsigned n) const; + /** Get the n-th semantic object for typedefs. + * \param n The index of the object. + * \return The object or NULL if \e n is invalid. */ + CTypedefInfo *TypedefInfo (unsigned n) const; + /** Get the n-th semantic object for functions. + * \param n The index of the object. + * \return The object or NULL if \e n is invalid. */ + CFunctionInfo *FunctionInfo (unsigned n) const; + /** Get the n-th semantic object for translation units (file scope). + * \param n The index of the object. + * \return The object or NULL if \e n is invalid. */ + CFileInfo *FileInfo (unsigned n) const; + + /** Get the semantic object for the entity at the given + * source code position (token). + * \param pos The token of the entity. + * \return The semantic object or NULL. */ + CObjectInfo *ObjectInfo (Token *pos) const; + /** Get the semantic object for the entity at the given + * source code position (token). + * \param pos The token of the entity. + * \return The semantic object or NULL. */ + CObjectInfo *ObjectInfo (CT_Token *pos) const; + +public: + CArgumentInfo *newArgument (); + CAttributeInfo *newAttribute (); + CBaseClassInfo *newBaseClass (); + CClassInfo *newClass (); + CClassInstance *newClassInstance (); + CEnumInfo *newEnum (); + CEnumeratorInfo *newEnumerator (); + CFunctionInfo *newFunction (); + CFctInstance *newFctInstance (); + CLabelInfo *newLabel (); + CLocalScope *newLocalScope (); + CMemberAliasInfo *newMemberAlias (); + CNamespaceInfo *newNamespace (); + CTemplateInfo *newTemplate (); + CTemplateParamInfo *newTemplateParam (); + CTypedefInfo *newTypedef (); + CUnionInfo *newUnion (); + CUnionInstance *newUnionInstance (); + CUsingInfo *newUsing (); + CFileInfo *newFile (); + +public: + /** Insert a new semantic object into the database. + * \param info The semantic object. */ + void Insert (CObjectInfo *info); + /** Remove the given semantic object from the database. + * \param info The semantic object. */ + void Remove (CObjectInfo *info); + /** Get the semantic object for the given built-in operator. + * \param name The operator name/symbol. + * \param tok The operator token type. + * \param rtype The result type of the operator. + * \param t0 Type of the first operand. + * \param t1 Type of the second operand, or NULL if only one operand. */ + CFunctionInfo *BuiltinOperator (const char *name, int tok, CTypeInfo *rtype, CTypeInfo *t0, CTypeInfo *t1); + /** Dump the contents of the database. The dump is indented as + * tree corresponding to the nesting of the semantic objects. + * \param out The output stream. + * \param depth The maximum indentation depth (0 means infinite). + * \param dump_builtins Dump or ignore builtin function, types and objects. */ + void Dump (std::ostream &out, int depth = 0, bool dump_builtins = true) const; + + /** Get the project information. */ + CProject *Project () const; + +private: + void CreateParameter (CFunctionInfo *fi, CTypeInfo *type) const; + + void Dump (std::ostream &, CStructure *, int, int, bool) const; + void DumpType (std::ostream &, CObjectInfo *, int) const; + void DumpUsing (std::ostream &, CUsingInfo *, int) const; + void DumpFriends (std::ostream &, CStructure *) const; + void DumpFunction (std::ostream &, CFunctionInfo *, int, int) const; + void DumpAttribute (std::ostream &, CAttributeInfo *, int) const; + void DumpNamespace (std::ostream &, CNamespaceInfo *, int) const; + void DumpQualities (std::ostream &, CObjectInfo *) const; + void DumpScopeName (std::ostream &, CStructure *) const; + void DumpLocalScope (std::ostream &, CObjectInfo *, int) const; + void DumpTemplateParam (std::ostream &, CTemplateParamInfo *, int) const; + void DumpTemplateInstance (std::ostream &, CObjectInfo *, int) const; + void indent (std::ostream &, int) const; +}; + +inline CSemDatabase::CSemDatabase (CProject &p, int size) : + _Classes (20, 50), + _Unions (20, 50), + _Enums (20, 50), + _Typedefs (20, 50), + _Functions (20, 50), + _Files (5, 20), + _Project (&p) + {} + +inline CSemDatabase::ObjectSet& CSemDatabase::Objects() + { return _Objects; } + +inline unsigned CSemDatabase::ObjectInfos () const + { return ClassInfos () + UnionInfos () + EnumInfos () + + TypedefInfos () + FunctionInfos () + FileInfos (); } +inline unsigned CSemDatabase::ClassInfos () const + { return _Classes.length (); } +inline unsigned CSemDatabase::UnionInfos () const + { return _Unions.length (); } +inline unsigned CSemDatabase::EnumInfos () const + { return _Enums.length (); } +inline unsigned CSemDatabase::TypedefInfos () const + { return _Typedefs.length (); } +inline unsigned CSemDatabase::FunctionInfos () const + { return _Functions.length (); } +inline unsigned CSemDatabase::FileInfos () const + { return _Files.length (); } + +inline CClassInfo *CSemDatabase::ClassInfo (unsigned i) const + { return (CClassInfo*)_Classes.lookup (i); } +inline CUnionInfo *CSemDatabase::UnionInfo (unsigned i) const + { return (CUnionInfo*)_Unions.lookup (i); } +inline CEnumInfo *CSemDatabase::EnumInfo (unsigned i) const + { return (CEnumInfo*)_Enums.lookup (i); } +inline CTypedefInfo *CSemDatabase::TypedefInfo (unsigned i) const + { return (CTypedefInfo*)_Typedefs.lookup (i); } +inline CFunctionInfo *CSemDatabase::FunctionInfo (unsigned i) const + { return (CFunctionInfo*)_Functions.lookup (i); } +inline CFileInfo *CSemDatabase::FileInfo (unsigned i) const + { return (CFileInfo*)_Files.lookup (i); } + +inline CProject *CSemDatabase::Project () const + { return _Project; } + + +} // namespace Puma + +#endif /* __CSemDatabase_h__ */ diff --git a/Puma/src/infos/CSourceInfo.cc b/Puma/src/infos/CSourceInfo.cc new file mode 100644 index 0000000..2d7e514 --- /dev/null +++ b/Puma/src/infos/CSourceInfo.cc @@ -0,0 +1,121 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CSourceInfo.h" +#include "Puma/MacroUnit.h" +#include "Puma/Unit.h" +#include "Puma/CTree.h" +#include "Puma/Token.h" +#include + +namespace Puma { + + +Unit *CSourceInfo::SrcUnit () const { + if (! StartToken ()) + return (Unit*)0; + + Token *token = StartToken ()->token (); + if (! token) + return (Unit*)0; + + Unit *unit = (Unit*)token->belonging_to (); + while (unit && unit->isMacroExp ()) { + unit = ((MacroUnit*)unit)->CallingUnit (); + } + return unit; +} + +const char *CSourceInfo::FileName () const { + if (! StartToken ()) + return (const char*)0; + return StartToken ()->token ()->location ().filename ().name (); +} + +int CSourceInfo::Line () const { + if (! StartToken ()) + return 0; + return StartToken ()->token ()->location ().line (); +} + +int CSourceInfo::Column () const { + if (! StartToken ()) + return 0; + return StartToken ()->token ()->location ().column (); +} + +bool CSourceInfo::operator ==(const Token *token) const { + if (StartToken () && StartToken ()->token () == token) + return true; + return false; +} + +bool CSourceInfo::operator ==(const CT_Token *token) const { + if (StartToken () && token && StartToken ()->Number () == token->Number ()) + return true; + return false; +} + +bool CSourceInfo::operator <(const CT_Token *token) const { + if (StartToken () && token && StartToken ()->Number () < token->Number ()) + return true; + return false; +} + +bool CSourceInfo::operator >(const CT_Token *token) const { + if (StartToken () && token && StartToken ()->Number () > token->Number ()) + return true; + return false; +} + +bool CSourceInfo::operator ==(const CSourceInfo &info) const { + if (! (*this == info.StartToken ()->token ())) + if (Line () != info.Line () || + Column () != info.Column () || + ! FileName () || ! info.FileName () || + strcmp (FileName (), info.FileName ()) != 0) + return false; + return true; +} + +bool CSourceInfo::operator <(const CSourceInfo &info) const { + if (Line () >= info.Line ()) + return false; + if (Column () >= info.Column ()) + return false; + if (! FileName () || ! info.FileName ()) + return false; + if (strcmp (FileName (), info.FileName ()) != 0) + return false; + return true; +} + +bool CSourceInfo::operator >(const CSourceInfo &info) const { + if (Line () <= info.Line ()) + return false; + if (Column () <= info.Column ()) + return false; + if (! FileName () || ! info.FileName ()) + return false; + if (strcmp (FileName (), info.FileName ()) != 0) + return false; + return true; +} + + +} // namespace Puma diff --git a/Puma/src/infos/CSourceInfo.h b/Puma/src/infos/CSourceInfo.h new file mode 100644 index 0000000..bb494e0 --- /dev/null +++ b/Puma/src/infos/CSourceInfo.h @@ -0,0 +1,146 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CSourceInfo_h__ +#define __CSourceInfo_h__ + +/** \file + * Source file information. */ + +namespace Puma { + + +class CFileInfo; +class CT_Token; +class Token; +class Unit; + + +/** \class CSourceInfo CSourceInfo.h Puma/CSourceInfo.h + * Source file information for an entity. Stores the + * file information and start token of the entity in + * the source file. */ +class CSourceInfo { + CFileInfo *_FileInfo; + CT_Token *_StartToken; + +public: + /** Constructor. */ + CSourceInfo (); + /** Destructor. */ + ~CSourceInfo (); + + /** Check if the source file locations are equal. + * \param si The source file location to compare with. */ + bool operator ==(const CSourceInfo &si) const; + /** Check if the source file locations are not equal. + * \param si The source file location to compare with. */ + bool operator !=(const CSourceInfo &si) const; + /** Check if this source file location is before the given location. + * \param si The source file location to compare with. */ + bool operator <(const CSourceInfo &si) const; + /** Check if this source file location is behind the given location. + * \param si The source file location to compare with. */ + bool operator >(const CSourceInfo &si) const; + /** Check if this source file location equals or is before the given location. + * \param si The source file location to compare with. */ + bool operator <=(const CSourceInfo &si) const; + /** Check if this source file location equals or is behind the given location. + * \param si The source file location to compare with. */ + bool operator >=(const CSourceInfo &si) const; + + /** Check if the source file locations are equal. + * \param token The token in the source file to compare with. */ + bool operator ==(const CT_Token *token) const; + /** Check if the source file locations are not equal. + * \param token The token in the source file to compare with. */ + bool operator !=(const CT_Token *token) const; + /** Check if this source file location is before the given location. + * \param token The token in the source file to compare with. */ + bool operator <(const CT_Token *token) const; + /** Check if this source file location is behind the given location. + * \param token The token in the source file to compare with. */ + bool operator >(const CT_Token *token) const; + /** Check if this source file location equals or is before the given location. + * \param token The token in the source file to compare with. */ + bool operator <=(const CT_Token *token) const; + /** Check if this source file location equals or is behind the given location. + * \param token The token in the source file to compare with. */ + bool operator >=(const CT_Token *token) const; + + /** Check if the source file locations are equal. + * \param token The token in the source file to compare with. */ + bool operator ==(const Token *token) const; + + /** Get the source file information. */ + CFileInfo *FileInfo () const; + /** Get the start token of the entity in the source file. */ + CT_Token *StartToken () const; + /** Get name of the source file. */ + const char *FileName () const; + /** Get the line number of the entity in the source file. */ + int Line () const; + /** Get the column number of the entity in the source file. */ + int Column () const; + /** Get the token unit of the source file. */ + Unit *SrcUnit () const; + + /** Set the source file information. + * \param file The source file. */ + void FileInfo (CFileInfo *file); + /** Set the start token of the entity in the source file. + * \param token The start token. */ + void StartToken (CT_Token *token); +}; + +inline CSourceInfo::CSourceInfo () : + _FileInfo ((CFileInfo*)0), + _StartToken ((CT_Token*)0) + {} + +inline CSourceInfo::~CSourceInfo () + {} + +inline bool CSourceInfo::operator !=(const CSourceInfo &info) const + { return ! (*this == info); } +inline bool CSourceInfo::operator <=(const CSourceInfo &info) const + { return ! (*this > info); } +inline bool CSourceInfo::operator >=(const CSourceInfo &info) const + { return ! (*this < info); } + +inline bool CSourceInfo::operator !=(const CT_Token *token) const + { return ! (*this == token); } +inline bool CSourceInfo::operator <=(const CT_Token *token) const + { return ! (*this > token); } +inline bool CSourceInfo::operator >=(const CT_Token *token) const + { return ! (*this < token); } + +inline CFileInfo *CSourceInfo::FileInfo () const + { return _FileInfo; } +inline CT_Token *CSourceInfo::StartToken () const + { return _StartToken; } + +inline void CSourceInfo::FileInfo (CFileInfo *info) + { _FileInfo = info; } +inline void CSourceInfo::StartToken (CT_Token *token) + { _StartToken = token; } + + +} // namespace Puma + +#endif /* __CSourceInfo_h__ */ diff --git a/Puma/src/infos/CStructure.cc b/Puma/src/infos/CStructure.cc new file mode 100644 index 0000000..ee6b028 --- /dev/null +++ b/Puma/src/infos/CStructure.cc @@ -0,0 +1,641 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CStructure.h" +#include "Puma/CFunctionInfo.h" +#include "Puma/CAttributeInfo.h" +#include "Puma/CTemplateInfo.h" +#include "Puma/CTemplateParamInfo.h" +#include "Puma/CEnumInfo.h" +#include "Puma/CClassInfo.h" +#include "Puma/CUnionInfo.h" +#include "Puma/CTypedefInfo.h" +#include "Puma/CTypeInfo.h" +#include "Puma/CNamespaceInfo.h" +#include "Puma/CArgumentInfo.h" +#include "Puma/CFileInfo.h" +#include "Puma/CNamespaceInfo.h" +#include "Puma/CMemberAliasInfo.h" +#include "Puma/CUsingInfo.h" +#include "Puma/CSemDatabase.h" + +#include +#include +#include + +namespace Puma { + + +void CStructure::setShared (CStructure *info) { + _Shared = info->_Shared; +} + +void CStructure::removeRegisterEntry () { + ObjectsByName::iterator i; + ObjectInfoList::iterator j; + + for (i = _Shared->_ObjectMap.begin (); i != _Shared->_ObjectMap.end (); ++i) { + ObjectInfoList &entry = i->second; + for (j = entry.begin(); j != entry.end(); ++j) + (*j)->Unregister (_Shared); + } +} + +void CStructure::removeNamedObject (const DString& name, CObjectInfo *info) { + CStructure::ObjectsByName::iterator sameNameListIter = _Shared->_ObjectMap.find(name); + if (sameNameListIter != _Shared->_ObjectMap.end()) { + CStructure::ObjectInfoList& sameNameList = sameNameListIter->second; + for (CStructure::ObjectInfoList::iterator iter = sameNameList.begin(); iter != sameNameList.end(); iter++) { + if (*iter == info) { + sameNameList.erase(iter); + break; + } + } + } +} + +void CStructure::addNamedObject (CObjectInfo *info) { + // This check is only needed if called externally from CObjectInfo->Name(..) + if (_Shared->_ObjectSet.find(info) != _Shared->_ObjectSet.end()) { + if (! info->Name().empty()) { + _Shared->_ObjectMap[info->Name()].push_back(info); + } + if (! info->isRegistered(_Shared)) + info->Register (_Shared); + } +} + +void CStructure::addObject (CObjectInfo *info) { + _Shared->_ObjectSet.insert(info); + _Objects.append (info); + _Shared->addNamedObject(info); +} + +CStructure::~CStructure () { +} + +unsigned CStructure::Functions (const DString& name) const { + unsigned n = 0; + ObjectsByName::const_iterator objs = _Shared->_ObjectMap.find(name); + if (objs != _Shared->_ObjectMap.end()) { + CStructure::ObjectInfoList::const_reverse_iterator obj = objs->second.rbegin(); + for (; obj != objs->second.rend(); ++obj) + if ((*obj)->FunctionInfo()) + n++; + } + return n; +} + +unsigned CStructure::Types (const DString& name) const { + unsigned n = 0; + ObjectsByName::const_iterator objs = _Shared->_ObjectMap.find(name); + if (objs != _Shared->_ObjectMap.end()) { + CStructure::ObjectInfoList::const_reverse_iterator obj = objs->second.rbegin(); + for (; obj != objs->second.rend(); ++obj) + if ((*obj)->TypedefInfo () || (*obj)->Record () || (*obj)->EnumInfo ()) + n++; + } + return n; +} + +unsigned CStructure::Objects (const DString& name) const { + unsigned n = 0; + ObjectsByName::const_iterator objs = _Shared->_ObjectMap.find(name); + if (objs != _Shared->_ObjectMap.end()) + n = objs->second.size(); + return n; +} + +unsigned CStructure::Attributes (const DString& name) const { + unsigned n = 0; + ObjectsByName::const_iterator objs = _Shared->_ObjectMap.find(name); + if (objs != _Shared->_ObjectMap.end()) { + CStructure::ObjectInfoList::const_reverse_iterator obj = objs->second.rbegin(); + for (; obj != objs->second.rend(); ++obj) + if ((*obj)->AttributeInfo()) + n++; + } + return n; +} + +unsigned CStructure::TemplateParams (const DString& name) const { + unsigned n = 0; + ObjectsByName::const_iterator objs = _Shared->_ObjectMap.find(name); + if (objs != _Shared->_ObjectMap.end()) { + CStructure::ObjectInfoList::const_reverse_iterator obj = objs->second.rbegin(); + for (; obj != objs->second.rend(); ++obj) + if ((*obj)->TemplateParamInfo()) + n++; + } + return n; +} + +unsigned CStructure::Usings (const DString& name) const { + unsigned n = 0; + ObjectsByName::const_iterator objs = _Shared->_ObjectMap.find(name); + if (objs != _Shared->_ObjectMap.end()) { + CStructure::ObjectInfoList::const_reverse_iterator obj = objs->second.rbegin(); + for (; obj != objs->second.rend(); ++obj) + if ((*obj)->UsingInfo()) + n++; + } + return n; +} + +unsigned CStructure::Namespaces (const DString& name) const { + unsigned n = 0; + ObjectsByName::const_iterator objs = _Shared->_ObjectMap.find(name); + if (objs != _Shared->_ObjectMap.end()) { + CStructure::ObjectInfoList::const_reverse_iterator obj = objs->second.rbegin(); + for (; obj != objs->second.rend(); ++obj) + if ((*obj)->NamespaceInfo()) + n++; + } + return n; +} + +unsigned CStructure::Friends (const DString& name) const { + unsigned n = 0; + for (unsigned i = 0; i < Friends (); i++) { + CObjectInfo* info = Friend (i); + if (! info->Name ().empty() && info->Name () == name) + n++; + } + return n; +} + +CFunctionInfo *CStructure::Function (const DString& name, unsigned pos) const { + ObjectsByName::const_iterator objs = _Shared->_ObjectMap.find(name); + if (objs != _Shared->_ObjectMap.end()) { + CStructure::ObjectInfoList::const_reverse_iterator obj = objs->second.rbegin(); + for (unsigned n = 0; obj != objs->second.rend(); ++obj) { + if ((*obj)->FunctionInfo()) { + if (n == pos) + return (CFunctionInfo*)*obj; + n++; + } + } + } + return (CFunctionInfo*)0; +} + +CObjectInfo *CStructure::Type (const DString& name, unsigned pos) const { + ObjectsByName::const_iterator objs = _Shared->_ObjectMap.find(name); + if (objs != _Shared->_ObjectMap.end()) { + CStructure::ObjectInfoList::const_reverse_iterator obj = objs->second.rbegin(); + for (unsigned n = 0; obj != objs->second.rend(); ++obj) { + if ((*obj)->TypedefInfo () || (*obj)->Record () || (*obj)->EnumInfo ()) { + if (n == pos) + return (CObjectInfo*)*obj; + n++; + } + } + } + return (CObjectInfo*)0; +} + +CTypedefInfo *CStructure::Typedef (const DString& name, unsigned pos) const { + ObjectsByName::const_iterator objs = _Shared->_ObjectMap.find(name); + if (objs != _Shared->_ObjectMap.end()) { + CStructure::ObjectInfoList::const_reverse_iterator obj = objs->second.rbegin(); + for (unsigned n = 0; obj != objs->second.rend(); ++obj) { + if ((*obj)->TypedefInfo ()) { + if (n == pos) + return (CTypedefInfo*)*obj; + n++; + } + } + } + return (CTypedefInfo*)0; +} + +CObjectInfo *CStructure::Object (const DString& name, unsigned pos) const { + ObjectsByName::const_iterator objs = _Shared->_ObjectMap.find(name); + if (objs != _Shared->_ObjectMap.end()) { + CStructure::ObjectInfoList::const_reverse_iterator obj = objs->second.rbegin(); + for (unsigned n = 0; obj != objs->second.rend(); ++obj, ++n) + if (n == pos) + return *obj; + } + return (CObjectInfo*)0; +} + +CAttributeInfo *CStructure::Attribute (const DString& name, unsigned pos) const { + ObjectsByName::const_iterator objs = _Shared->_ObjectMap.find(name); + if (objs != _Shared->_ObjectMap.end()) { + CStructure::ObjectInfoList::const_reverse_iterator obj = objs->second.rbegin(); + for (unsigned n = 0; obj != objs->second.rend(); ++obj) { + if ((*obj)->AttributeInfo()) { + if (n == pos) + return (CAttributeInfo*)*obj; + n++; + } + } + } + return (CAttributeInfo*)0; +} + +CTemplateParamInfo *CStructure::TemplateParam (const DString& name, unsigned pos) const { + ObjectsByName::const_iterator objs = _Shared->_ObjectMap.find(name); + if (objs != _Shared->_ObjectMap.end()) { + CStructure::ObjectInfoList::const_reverse_iterator obj = objs->second.rbegin(); + for (unsigned n = 0; obj != objs->second.rend(); ++obj) { + if ((*obj)->TemplateParamInfo()) { + if (n == pos) + return (CTemplateParamInfo*)*obj; + n++; + } + } + } + return (CTemplateParamInfo*)0; +} + +CUsingInfo *CStructure::Using (const DString& name, unsigned pos) const { + unsigned n = 0; + for (unsigned i = Usings (); i > 0; i--) { + CUsingInfo* info = Using (i-1); + if (! info->Name ().empty() && info->Name () == name) { + if (n == pos) + return info; + n++; + } + } + return (CUsingInfo*)0; +} + +CNamespaceInfo *CStructure::Namespace (const DString& name, unsigned pos) const { + ObjectsByName::const_iterator objs = _Shared->_ObjectMap.find(name); + if (objs != _Shared->_ObjectMap.end()) { + CStructure::ObjectInfoList::const_reverse_iterator obj = objs->second.rbegin(); + for (unsigned n = 0; obj != objs->second.rend(); ++obj) { + if ((*obj)->NamespaceInfo()) { + if (n == pos) + return (CNamespaceInfo*)*obj; + n++; + } + } + } + return (CNamespaceInfo*)0; +} + +CRecord *CStructure::Friend (const DString& name, unsigned pos) const { + unsigned n = 0; + for (unsigned i = Friends (); i > 0; i--) { + CRecord* info = Friend (i-1); + if (! info->Name ().empty() && info->Name () == name) { + if (n == pos) + return info; + n++; + } + } + return (CRecord*)0; +} + +CFunctionInfo *CStructure::Function (const DString& name, CTypeInfo *type) const { + ObjectsByName::const_iterator objs = _Shared->_ObjectMap.find(name); + if (objs != _Shared->_ObjectMap.end()) { + CStructure::ObjectInfoList::const_reverse_iterator obj = objs->second.rbegin(); + for (; obj != objs->second.rend(); ++obj) + if ((*obj)->FunctionInfo() && *(*obj)->TypeInfo() == *type) + return (CFunctionInfo*)*obj; + } + return (CFunctionInfo*)0; +} + +void CStructure::addUsing (CUsingInfo *info) { + for (unsigned i = Usings (); i > 0; i--) + if (Using (i-1) == info) + return; + _Usings.append (info); +} + +void CStructure::addNamespace (CNamespaceInfo *info) { + if (info->isRegistered(Structure())) + return; + _Namespaces.append (info); + addObject (info); +} + +void CStructure::addFriend (CRecord *info) { + for (unsigned i = Friends (); i > 0; i--) + if (Friend (i-1) == info) + return; + _Friends.append (info); +} + +void CStructure::addType (CObjectInfo *info) { + if (info->isRegistered(Structure())) + return; + _Types.append (info); + addObject (info); +} + +void CStructure::addAttribute (CAttributeInfo *info) { + if (info->isRegistered(Structure())) + return; + _Attributes.append (info); + addObject (info); +} + +void CStructure::addTemplateParam (CTemplateParamInfo *info) { + if (info->isRegistered(Structure())) + return; + _TemplateParams.append (info); + addObject (info); +} + +void CStructure::addFunction (CFunctionInfo *info) { + if (info->isRegistered(Structure())) + return; + _Functions.append (info); + addObject (info); +} + +void CStructure::removeAttribute (const CAttributeInfo *info) { + CMemberAliasInfo *mainfo; + if ((mainfo = MemberAlias (info))) + removeMemberAlias (mainfo); + else + for (unsigned i = Attributes (); i > 0; i--) + if (Attribute (i-1) == info) { + _Attributes.remove (i-1); + removeObject (info); + break; + } +} + +void CStructure::removeTemplateParam (const CTemplateParamInfo *info) { + for (unsigned i = TemplateParams (); i > 0; i--) + if (TemplateParam (i-1) == info) { + _TemplateParams.remove (i-1); + removeObject (info); + break; + } +} + +void CStructure::removeFunction (const CFunctionInfo *info) { + CMemberAliasInfo *mainfo; + if ((mainfo = MemberAlias (info))) + removeMemberAlias (mainfo); + else + for (unsigned i = Functions (); i > 0; i--) + if (Function (i-1) == info) { + _Functions.remove (i-1); + removeObject (info); + break; + } +} + +void CStructure::removeType (const CObjectInfo *info) { + CMemberAliasInfo *mainfo; + if ((mainfo = MemberAlias (info))) + removeMemberAlias (mainfo); + else + for (unsigned i = Types (); i > 0; i--) + if (Type (i-1) == info) { + _Types.remove (i-1); + removeObject (info); + break; + } +} + +void CStructure::removeObject (const CObjectInfo *info) { + for (unsigned i = Objects (); i > 0; i--) { + if (Object (i-1) == info) { + const CObjectInfo* real = (info->MemberAliasInfo() != 0) ? info->MemberAliasInfo()->Member() : info; + if (real->Name()) { + ObjectsByName::iterator iter = _Shared->_ObjectMap.find(real->Name()); + if (iter != _Shared->_ObjectMap.end()) { + for (ObjectInfoList::iterator liter = iter->second.begin(); liter != iter->second.end(); liter++) { + if (*liter == info) { + iter->second.erase(liter); + break; + } + } + } + } + _Shared->_ObjectSet.erase((CObjectInfo*)info); + _Objects.remove (i-1); + ((CObjectInfo*)info)->Unregister(Structure()); + break; + } + } +} + +void CStructure::removeUsing (const CUsingInfo *info) { + for (unsigned i = Usings (); i > 0; i--) + if (Using (i-1) == info) { + _Usings.remove (i-1); + break; + } +} + +void CStructure::removeNamespace (const CNamespaceInfo *info) { + for (unsigned i = Namespaces (); i > 0; i--) + if (Namespace (i-1) == info) { + _Namespaces.remove (i-1); + removeObject (info); + break; + } +} + +void CStructure::removeFriend (const CRecord *info) { + for (unsigned i = Friends (); i > 0; i--) + if (Friend (i-1) == info) { + _Friends.remove (i-1); + break; + } +} + +void CStructure::removeMemberAlias (const CMemberAliasInfo *info) { + for (unsigned i = Objects (); i > 0; i--) + if (Object (i-1) == info->ObjectInfo ()) { + removeObject (Object (i-1)); + for (unsigned j = (unsigned)_Aliases.length (); j > 0; j--) + if (_Aliases.lookup (j-1) == info) { + _Aliases.remove (j-1); + break; + } + if (info->Member ()) { + if (info->Member ()->FunctionInfo ()) { + for (unsigned j = Functions (); j > 0; j--) + if (Function (j-1) == info->Member ()) { + _Functions.remove (j-1); + break; + } + } else if (info->Member ()->AttributeInfo ()) { + for (unsigned j = Attributes (); j > 0; j--) + if (Attribute (j-1) == info->Member ()) { + _Attributes.remove (j-1); + break; + } + } else if (info->Member ()->TypedefInfo () || + info->Member ()->Record () || + info->Member ()->EnumInfo ()) { + for (unsigned j = Types (); j > 0; j--) + if (Type (j-1) == info->Member ()) { + _Types.remove (j-1); + break; + } + } + } + break; + } +} + +CAttributeInfo *CStructure::newAttribute () { + CAttributeInfo *info = SemDB() ? SemDB()->newAttribute() : new CAttributeInfo; + info->Scope (this); + addAttribute (info); + return info; +} + +CEnumInfo *CStructure::newEnum () { + CEnumInfo *info = SemDB() ? SemDB()->newEnum() : new CEnumInfo; + info->Scope (this); + addType (info); + return info; +} + +CUsingInfo *CStructure::newUsing () { + CUsingInfo *info = SemDB() ? SemDB()->newUsing() : new CUsingInfo; + info->Scope (this); + addUsing (info); + return info; +} + +CTypedefInfo *CStructure::newTypedef () { + CTypedefInfo *info = SemDB() ? SemDB()->newTypedef() : new CTypedefInfo; + info->Scope (this); + addType (info); + return info; +} + +CMemberAliasInfo *CStructure::newMemberAlias (CObjectInfo *oinfo, bool direct_member) { + CMemberAliasInfo *info = SemDB() ? SemDB()->newMemberAlias() : new CMemberAliasInfo; + info->Scope (this); + addObject (info); + _Aliases.append (info); + if (direct_member) { + if (oinfo->FunctionInfo ()) + _Functions.append (oinfo->FunctionInfo ()); + else if (oinfo->AttributeInfo ()) + _Attributes.append (oinfo->AttributeInfo ()); + else if (oinfo->TypedefInfo () || oinfo->Record () || oinfo->EnumInfo ()) + _Types.append (oinfo); + addObject (oinfo); + } + return info; +} + +void CStructure::deleteAttribute (const CAttributeInfo *info) { + for (unsigned i = Attributes (); i > 0; i--) + if (Attribute (i-1) == info) { + removeObject (info); + Attribute (i-1)->Scope (0); + if (! Attribute (i-1)->EnumeratorInfo ()) + delete (CAttributeInfo*)_Attributes[i-1]; + _Attributes.remove (i-1); + break; + } +} + +void CStructure::deleteEnum (const CEnumInfo *info) { + for (unsigned i = Types (); i > 0; i--) + if (Type (i-1) == (CObjectInfo*)info) { + removeObject (info); + ((CEnumInfo*)Type (i-1))->Scope (0); + delete (CEnumInfo*)_Types[i-1]; + _Types.remove (i-1); + break; + } +} + +void CStructure::deleteUsing (const CUsingInfo *info) { + for (unsigned i = Usings (); i > 0; i--) + if (Using (i-1) == (CUsingInfo*)info) { + Using (i-1)->Scope (0); + delete (CUsingInfo*)_Usings[i-1]; + _Usings.remove (i-1); + break; + } +} + +void CStructure::deleteTypedef (const CTypedefInfo *info) { + for (unsigned i = Types (); i > 0; i--) + if (Type (i-1) == (CObjectInfo*)info) { + removeObject (info); + ((CTypedefInfo*)Type (i-1))->Scope (0); + delete (CTypedefInfo*)_Types[i-1]; + _Types.remove (i-1); + break; + } +} + +void CStructure::deleteMemberAlias (const CMemberAliasInfo *info) { + CMemberAliasInfo *mainfo; + for (unsigned k = Objects (); k > 0; k--) + if (Object (k-1) == (CObjectInfo*)info) { + mainfo = (CMemberAliasInfo*)Object (k-1); + mainfo->Scope (0); + if (mainfo->Member ()) { + if (mainfo->Member ()->FunctionInfo ()) { + for (unsigned i = Functions (); i > 0; i--) + if (Function (i-1) == mainfo->Member ()) { + _Functions.remove (i-1); + break; + } + } else if (mainfo->Member ()->AttributeInfo ()) { + for (unsigned i = Attributes (); i > 0; i--) + if (Attribute (i-1) == mainfo->Member ()) { + _Attributes.remove (i-1); + break; + } + } else if (mainfo->Member ()->TypedefInfo () || + mainfo->Member ()->Record () || + mainfo->Member ()->EnumInfo ()) { + for (unsigned i = Types (); i > 0; i--) + if (Type (i-1) == mainfo->Member ()) { + _Types.remove (i-1); + break; + } + } + } + removeObject (Object (k-1)); + for (unsigned j = (unsigned)_Aliases.length (); j > 0; j--) + if (_Aliases.lookup (j-1) == info) { + _Aliases.remove (j-1); + break; + } + delete mainfo; + break; + } +} + +CMemberAliasInfo *CStructure::MemberAlias (const CObjectInfo *info) const { + CMemberAliasInfo *mainfo; + for (unsigned i = (unsigned)_Aliases.length (); i > 0; i--) { + mainfo = _Aliases.lookup (i-1); + if (mainfo->Member () == (CObjectInfo*)info) + return mainfo; + } + return (CMemberAliasInfo*)0; +} + + +} // namespace Puma diff --git a/Puma/src/infos/CStructure.h b/Puma/src/infos/CStructure.h new file mode 100644 index 0000000..9447672 --- /dev/null +++ b/Puma/src/infos/CStructure.h @@ -0,0 +1,387 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CStructure_h__ +#define __CStructure_h__ + +/** \file + * Semantic information about entities that can contain other entity declarations. */ + +#include "Puma/CScopeInfo.h" +#include "Puma/Array.h" + +#include +#include +#include +#include +#include "Puma/DString.h" + +namespace Puma { + + +class CAttributeInfo; +class CTemplateParamInfo; +class CFunctionInfo; +class CClassInfo; +class CUnionInfo; +class CEnumInfo; +class CTypedefInfo; +class CNamespaceInfo; +class CUsingInfo; +class CMemberAliasInfo; + + +/** \class CStructure CStructure.h Puma/CStructure.h + * Base class of all semantic information classes for + * entities that can contain other entity declarations + * (like classes, namespaces, functions). */ +class CStructure : public CScopeInfo { +public: + /** List type for semantic objects. */ + typedef std::list ObjectInfoList; + /** Map type for entity name to semantic object mapping. */ + typedef std::map ObjectsByName; + /** Set type for semantic objects. */ + typedef std::set ObjectInfoSet; + +private: + CStructure *_Shared; + Array _Objects; // ALL objects (mixed, in the order added to) + Array _Attributes; + Array _TemplateParams; + Array _Functions; + Array _Types; + Array _Usings; + Array _Friends; + Array _Namespaces; + Array _Aliases; + ObjectsByName _ObjectMap; + ObjectInfoSet _ObjectSet; + +protected: + /** Constructor. + * \param id The object type. */ + CStructure (ObjectId id); + +public: + /** Destructor. */ + ~CStructure (); + + /** Get the entity name to semantic object map. */ + ObjectsByName& ObjectInfoMap(); + /** Get the entity name to semantic object map. */ + const ObjectInfoSet& ObjectInfos() const; + + /** Get the number of contained semantic objects. */ + unsigned Objects () const; + /** Get the number of contained semantic objects for + * entities with the given name. + * \param name The name of the entity. */ + unsigned Objects (const DString& name) const; + /** Get the number of contained semantic objects for + * type declarations. */ + unsigned Types () const; + /** Get the number of contained semantic objects for + * declarations of types with the given name. + * \param name The name of the type. */ + unsigned Types (const DString& name) const; + /** Get the number of contained semantic objects for + * object declarations. */ + unsigned Attributes () const; + /** Get the number of contained semantic objects for + * declarations of objects with the given name. + * \param name The name of the object. */ + unsigned Attributes (const DString& name) const; + /** Get the number of contained semantic objects for + * template parameter declarations. */ + unsigned TemplateParams () const; + /** Get the number of contained semantic objects for + * declarations of template parameters with the given name. + * \param name The name of the template parameter. */ + unsigned TemplateParams (const DString& name) const; + /** Get the number of contained semantic objects for + * function declarations. */ + unsigned Functions () const; + /** Get the number of contained semantic objects for + * declarations of functions with the given name. + * \param name The name of the function. */ + unsigned Functions (const DString& name) const; + /** Get the number of contained semantic objects for + * used members. */ + unsigned Usings () const; + /** Get the number of contained semantic objects for + * used members with the given name. + * \param name The name of the member. */ + unsigned Usings (const DString& name) const; + /** Get the number of contained semantic objects for + * namespace declarations. */ + unsigned Namespaces () const; + /** Get the number of contained semantic objects for + * declarations of namespaces with the given name. + * \param name The name of the namespace. */ + unsigned Namespaces (const DString& name) const; + /** Get the number of contained semantic objects for + * friend declarations. */ + unsigned Friends () const; + /** Get the number of contained semantic objects for + * declarations of friends with the given name. + * \param name The name of the friend. */ + unsigned Friends (const DString& name) const; + + /** Get the n-th contained semantic object. + * \param n The index of the semantic object. */ + CObjectInfo *Object (unsigned n) const; + /** Get the n-th contained semantic object for + * entities with the given name. + * \param name The name of the entity. + * \param n Optional index of the semantic object (defaults to 0). */ + CObjectInfo *Object (const DString& name, unsigned n = 0) const; + /** Get the n-th contained semantic object for a type. + * \param n The index of the semantic object. */ + CObjectInfo *Type (unsigned n) const; + /** Get the n-th contained semantic object for + * types with the given name. + * \param name The name of the type. + * \param n Optional index of the semantic object (defaults to 0). */ + CObjectInfo *Type (const DString& name, unsigned n = 0) const; + /** Get the n-th contained semantic object for + * typedefs with the given name. + * \param name The name of the typedef. + * \param n Optional index of the semantic object (defaults to 0). */ + CTypedefInfo *Typedef (const DString& name, unsigned n = 0) const; + /** Get the n-th contained semantic object for a using-directive. + * \param n The index of the semantic object. */ + CUsingInfo *Using (unsigned n) const; + /** Get the n-th contained semantic object for + * used members with the given name. + * \param name The name of the member. + * \param n Optional index of the semantic object (defaults to 0). */ + CUsingInfo *Using (const DString& name, unsigned n = 0) const; + /** Get the n-th contained semantic object for a namespace. + * \param n The index of the semantic object. */ + CNamespaceInfo *Namespace (unsigned n) const; + /** Get the n-th contained semantic object for + * namespaces with the given name. + * \param name The name of the namespace. + * \param n Optional index of the semantic object (defaults to 0). */ + CNamespaceInfo *Namespace (const DString& name, unsigned n = 0) const; + /** Get the n-th contained semantic object for a friend. + * \param n The index of the semantic object. */ + CRecord *Friend (unsigned n) const; + /** Get the n-th contained semantic object for + * friends with the given name. + * \param name The name of the friend. + * \param n Optional index of the semantic object (defaults to 0). */ + CRecord *Friend (const DString& name, unsigned n = 0) const; + /** Get the n-th contained semantic object for an object. + * \param n The index of the semantic object. */ + CAttributeInfo *Attribute (unsigned n) const; + /** Get the n-th contained semantic object for + * objects with the given name. + * \param name The name of the object. + * \param n Optional index of the semantic object (defaults to 0). */ + CAttributeInfo *Attribute (const DString& name, unsigned n = 0) const; + /** Get the n-th contained semantic object for a template parameter. + * \param n The index of the semantic object. */ + CTemplateParamInfo *TemplateParam (unsigned n) const; + /** Get the n-th contained semantic object for + * template parameters with the given name. + * \param name The name of the template parameter. + * \param n Optional index of the semantic object (defaults to 0). */ + CTemplateParamInfo *TemplateParam (const DString& name, unsigned n = 0) const; + /** Get the n-th contained semantic object for a function. + * \param n The index of the semantic object. */ + CFunctionInfo *Function (unsigned n) const; + /** Get the n-th contained semantic object for + * functions with the given name. + * \param name The name of the function. + * \param n Optional index of the semantic object (defaults to 0). */ + CFunctionInfo *Function (const DString& name, unsigned n = 0) const; + /** Get the contained semantic object for functions with the + * given name and type. + * \param name The name of the function. + * \param type The type of the function. */ + CFunctionInfo *Function (const DString& name, CTypeInfo *type) const; + + /** Check if an alias exists for the given entity in this scope. + * \param info The semantic object of the entity. */ + bool isMemberAlias (const CObjectInfo *info) const; + /** Get the member alias information for the aliased entity. + * \param info The semantic object of the entity. */ + CMemberAliasInfo *MemberAlias (const CObjectInfo *info) const; + + /** Set a common data object for the linked semantic objects. + * \param share The common data object. */ + void setShared (CStructure *share); + + /** Add a semantic object. + * \param info The semantic object. */ + void addObject (CObjectInfo *info); + /** Add a semantic object for an object. + * \param info The semantic object. */ + void addAttribute (CAttributeInfo *info); + /** Add a semantic object for a template parameter. + * \param info The semantic object. */ + void addTemplateParam (CTemplateParamInfo *info); + /** Add a semantic object for a function. + * \param info The semantic object. */ + void addFunction (CFunctionInfo *info); + /** Add a semantic object for a type. + * \param info The semantic object. */ + void addType (CObjectInfo *info); + /** Add a semantic object for a using-directive. + * \param info The semantic object. */ + void addUsing (CUsingInfo *info); + /** Add a semantic object for a namespace. + * \param info The semantic object. */ + void addNamespace (CNamespaceInfo *info); + /** Add a semantic object for a friend. + * \param info The semantic object. */ + void addFriend (CRecord *info); + + /** Remove the semantic object. + * \param info The semantic object. */ + void removeObject (const CObjectInfo *info); + /** Remove the semantic object for an object. + * \param info The semantic object. */ + void removeAttribute (const CAttributeInfo *info); + /** Remove the semantic object for a template parameter. + * \param info The semantic object. */ + void removeTemplateParam (const CTemplateParamInfo *info); + /** Remove the semantic object for a function. + * \param info The semantic object. */ + void removeFunction (const CFunctionInfo *info); + /** Remove the semantic object for a type. + * \param info The semantic object. */ + void removeType (const CObjectInfo *info); + /** Remove the semantic object for a using-directive. + * \param info The semantic object. */ + void removeUsing (const CUsingInfo *info); + /** Remove the semantic object for a namespace. + * \param info The semantic object. */ + void removeNamespace (const CNamespaceInfo *info); + /** Remove the semantic object for a friend. + * \param info The semantic object. */ + void removeFriend (const CRecord *info); + /** Remove the semantic object for a member alias. + * \param info The semantic object. */ + void removeMemberAlias (const CMemberAliasInfo *info); + + /** Unregister this semantic object at all contained + * semantic objects. */ + void removeRegisterEntry (); + + /** Add a semantic object to the name map. + * \warning For internal use only! + * \param info The semantic object. */ + void addNamedObject (CObjectInfo* info); + /** Remove the given semantic object for the entity + * with the given name from the name map. + * \warning For internal use only! + * \param name The name of the entity. + * \param info The semantic object. */ + void removeNamedObject (const DString& name, CObjectInfo* info); + + /** Create a new semantic object for an object declaration. */ + CAttributeInfo *newAttribute (); + /** Create a new semantic object for an enumeration. */ + CEnumInfo *newEnum (); + /** Create a new semantic object for a using-directive. */ + CUsingInfo *newUsing (); + /** Create a new semantic object for a typedef. */ + CTypedefInfo *newTypedef (); + /** Create a new semantic object for a member alias. + * \param member The aliased member. + * \param direct_member Add as direct member. */ + CMemberAliasInfo *newMemberAlias (CObjectInfo *member, bool direct_member = false); + + /** Remove and destroy the given semantic object for an object. + * \param info The semantic object. */ + void deleteAttribute (const CAttributeInfo *info); + /** Remove and destroy the given semantic object for an enumeration. + * \param info The semantic object. */ + void deleteEnum (const CEnumInfo *info); + /** Remove and destroy the given semantic object for a using-directive. + * \param info The semantic object. */ + void deleteUsing (const CUsingInfo *info); + /** Remove and destroy the given semantic object for a typedef. + * \param info The semantic object. */ + void deleteTypedef (const CTypedefInfo *info); + /** Remove and destroy the given semantic object for a member alias. + * \param info The semantic object. */ + void deleteMemberAlias (const CMemberAliasInfo *info); +}; + +inline CStructure::CStructure (CObjectInfo::ObjectId id) : + CScopeInfo (id), + _Shared (this), + _Objects (5, 20), + _Attributes (5, 10), + _TemplateParams (1, 2), + _Functions (5, 20), + _Types (5, 20), + _Usings (1, 20), + _Friends (1, 10), + _Namespaces (1, 10), + _Aliases (1, 20) + {} + +inline unsigned CStructure::Objects () const + { return _Objects.length (); } +inline unsigned CStructure::Types () const + { return _Types.length (); } +inline unsigned CStructure::Attributes () const + { return _Attributes.length (); } +inline unsigned CStructure::TemplateParams () const + { return _TemplateParams.length (); } +inline unsigned CStructure::Functions () const + { return _Functions.length (); } +inline unsigned CStructure::Usings () const + { return _Usings.length (); } +inline unsigned CStructure::Namespaces () const + { return _Namespaces.length (); } +inline unsigned CStructure::Friends () const + { return _Friends.length (); } +inline CObjectInfo *CStructure::Object (unsigned n) const + { return _Objects.lookup (n); } +inline CObjectInfo *CStructure::Type (unsigned n) const + { return _Types.lookup (n); } +inline CAttributeInfo *CStructure::Attribute (unsigned n) const + { return _Attributes.lookup (n); } +inline CTemplateParamInfo *CStructure::TemplateParam (unsigned n) const + { return _TemplateParams.lookup (n); } +inline CFunctionInfo *CStructure::Function (unsigned n) const + { return _Functions.lookup (n); } +inline CUsingInfo *CStructure::Using (unsigned n) const + { return _Usings.lookup (n); } +inline CNamespaceInfo *CStructure::Namespace (unsigned n) const + { return _Namespaces.lookup (n); } +inline CRecord *CStructure::Friend (unsigned n) const + { return _Friends.lookup (n); } + +inline bool CStructure::isMemberAlias (const CObjectInfo *info) const + { return (MemberAlias (info)); } + +inline CStructure::ObjectsByName& CStructure::ObjectInfoMap() + { return _Shared->_ObjectMap; } +inline const CStructure::ObjectInfoSet& CStructure::ObjectInfos() const + { return _Shared->_ObjectSet; } + +} // namespace Puma + +#endif /* __CStructure_h__ */ diff --git a/Puma/src/infos/CTemplateInfo.cc b/Puma/src/infos/CTemplateInfo.cc new file mode 100644 index 0000000..3a28231 --- /dev/null +++ b/Puma/src/infos/CTemplateInfo.cc @@ -0,0 +1,194 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CTemplateParamInfo.h" +#include "Puma/CTemplateInfo.h" +#include "Puma/CClassInfo.h" +#include "Puma/CFunctionInfo.h" +#include "Puma/CAttributeInfo.h" +#include "Puma/CStructure.h" +#include "Puma/CTemplateInstance.h" +#include "Puma/CSemDatabase.h" +#include "Puma/CNamespaceInfo.h" +#include "Puma/Builder.h" + +namespace Puma { + + +CTemplateInfo::~CTemplateInfo () { + for (unsigned i = _TreeFragments.length (); i > 0; i--) + Builder::destroy (_TreeFragments.lookup (i-1)); +} + +void CTemplateInfo::addTreeFragment (CTree* fragment) { + if (fragment) + _TreeFragments.append (fragment); +} + +void CTemplateInfo::BaseTemplate (CTemplateInfo *info) { + _Base = info; + info->addSpecialization ((CTemplateInfo*)this); +} + +void CTemplateInfo::addSpecialization (CTemplateInfo *info) { + if (! info) + return; + + for (unsigned i = Specializations (); i > 0; i--) + if (Specialization (i-1) == info) + return; + _Specializations.append (info); +} + +void CTemplateInfo::removeSpecialization (const CTemplateInfo *info) { + for (unsigned i = Specializations (); i > 0; i--) + if (Specialization (i-1) == info) { + _Specializations.remove (i-1); + break; + } +} + +void CTemplateInfo::removeLinks () { + CStructure *scope; + + if (_ObjectInfo) { + scope = Parent ()->Structure (); + while (scope && scope->TemplateInfo () && scope != this) + scope = scope->Parent ()->Structure (); + if (_ObjectInfo->Record ()) { + _ObjectInfo->Record ()->TemplateInfo ((CTemplateInfo*)0); + if (scope) + scope->removeType (_ObjectInfo); + } else if (_ObjectInfo->FunctionInfo ()) { + _ObjectInfo->FunctionInfo ()->TemplateInfo ((CTemplateInfo*)0); + if (scope) + scope->removeFunction (_ObjectInfo->FunctionInfo ()); + } else if (_ObjectInfo->AttributeInfo ()) { + _ObjectInfo->AttributeInfo ()->TemplateInfo ((CTemplateInfo*)0); + if (scope) + scope->removeAttribute (_ObjectInfo->AttributeInfo ()); + } + } +} + +CTree *CTemplateInfo::DefaultArgument (unsigned n) const { + CTemplateParamInfo *pinfo = Parameter (n); + if (pinfo && pinfo->DefaultArgument ()) + return pinfo->DefaultArgument (); + return 0; +} + +CTemplateParamInfo *CTemplateInfo::newTemplateParam (bool add) { + CTemplateParamInfo *info = SemDB() ? SemDB()->newTemplateParam() : new CTemplateParamInfo; + info->TemplateInfo (this); + addTemplateParam (info); + if (add) { + _Params.append (info); + } + return info; +} + +void CTemplateInfo::deleteTemplateParam (const CTemplateParamInfo *info) { + CTemplateParamInfo *tinfo; + for (unsigned i = TemplateParams (); i > 0; i--) + if (TemplateParam (i-1) == info) { + tinfo = TemplateParam (i-1); + removeTemplateParam (tinfo); + if (tinfo->TemplateInfo () == this) { + for (unsigned j = Parameters (); j > 0; j--) + if (Parameter (j) == tinfo) { + _Params.remove (j); + break; + } + tinfo->TemplateInfo (0); + delete tinfo; + } + break; + } +} + +void CTemplateInfo::removeInstance (const CObjectInfo *info) { + for (unsigned i = Instances (); i > 0; i--) { + CObjectInfo* instance = Instance (i-1); + if (instance == info) { + _Instances.remove (i-1); + Parent ()->Structure ()->removeNamespace (instance->Scope ()->NamespaceInfo ()); + instance->TemplateInstance ()->isInstantiated (false); + instance->TemplateInstance ()->canInstantiate (false); + //instance->Tree (0); + //instance->Template (0); + //instance->Object (0); + break; + } + } +} + +void CTemplateInfo::linkInstance (CObjectInfo *info) { + CObjectInfo *obj; + CTemplateInfo *curr; + CTemplateInstance *inst1 = info->TemplateInstance (), *inst2; + if (! inst1) + return; + + curr = this; + do { + for (unsigned i = curr->Instances (); i > 0; i--) { + obj = curr->Instance (i-1); + inst2 = obj->TemplateInstance (); + if (inst2 && inst1 != inst2 && equalArguments (inst1, inst2)) { + obj->NextObject (info); + return; + } + } + curr = nextTemplate (curr); + } while (curr && curr != this); +} + +bool CTemplateInfo::equalArguments (CTemplateInstance *inst1, CTemplateInstance *inst2, bool matchTemplateParams) { + if (inst1 && inst2 && inst1->InstantiationArgs () == inst2->InstantiationArgs ()) { + for (unsigned i = inst1->InstantiationArgs (); i > 0; i--) + if (! inst1->InstantiationArg (i-1)->equals (*inst2->InstantiationArg (i-1), matchTemplateParams)) + return false; + return true; + } + return false; +} + +bool CTemplateInfo::equalParameters (CTemplateInfo *t1, CTemplateInfo *t2) { + if (t1 && t2 && t1->Parameters () == t2->Parameters ()) { + for (unsigned i = t1->Parameters (); i > 0; i--) + if (! t1->Parameter (i-1)->match (*t2->Parameter (i-1))) + return false; + return true; + } + return false; +} + +CTemplateInfo *CTemplateInfo::nextTemplate (CTemplateInfo *tinfo) const { + CObjectInfo *next = tinfo->ObjectInfo ()->NextObject (); + if (next->TemplateInstance ()) + return next->TemplateInstance ()->Template (); + // pseudo instance + return next->Record () ? next->Record ()->TemplateInfo () : + next->FunctionInfo () ? next->FunctionInfo ()->TemplateInfo () : + next->TemplateParamInfo () ? next->TemplateParamInfo ()->TemplateInfo () : + (CTemplateInfo*)0; +} + + +} // namespace Puma diff --git a/Puma/src/infos/CTemplateInfo.h b/Puma/src/infos/CTemplateInfo.h new file mode 100644 index 0000000..8292c33 --- /dev/null +++ b/Puma/src/infos/CTemplateInfo.h @@ -0,0 +1,244 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CTemplateInfo_h__ +#define __CTemplateInfo_h__ + +/** \file + * Semantic information about a template declaration. */ + +#include "Puma/CStructure.h" + +namespace Puma { + + +class CT_TemplateDecl; +class CTemplateParamInfo; +class CT_ExprList; +class CT_TemplateName; +class CTree; + + +/** \class CTemplateInfo CTemplateInfo.h Puma/CTemplateInfo.h + * Semantic information about a template declaration. + * Contains information about the parameters, specializations, + * and instances of the template. */ +class CTemplateInfo : public CStructure { + CObjectInfo *_ObjectInfo; + CTemplateInfo *_Base; + bool _isSpecial; + CT_TemplateName *_SpecializationName; + unsigned _Depth; + + Array _Params; + Array _Instances; + Array _Specializations; + Array _TreeFragments; + +public: + /** Constructor. */ + CTemplateInfo (); + /** Destructor. Unlinks itself from the specializations + * and instances of this template. If the object type + * is CObjectInfo::TEMPLATE_INFO, CObjectInfo::CleanUp() + * is called. */ + ~CTemplateInfo (); + + /** Remove all links from other semantic objects to + * this semantic object. */ + void removeLinks (); + + /** Check if this is a function template definition. */ + bool isFunction () const; + /** Check if this is a class template definition. */ + bool isClass () const; + /** Check if this is the definition of a static + * template class date member. */ + bool isAttribute () const; + /** Check if this is a base template and not a + * specialization of another template. */ + bool isBaseTemplate () const; + /** Check if this is a specialization of another template. */ + bool isSpecialization () const; + + /** Increase the instantiation depth (for nested template + * instantiations). */ + void increaseDepth (); + /** Decrease the instantiation depth (for nested template + * instantiations). */ + void decreaseDepth (); + /** Get the current instantiation depth (for nested template + * instantiations). */ + unsigned Depth () const; + + /** Get the semantic information for the entity. */ + CObjectInfo *ObjectInfo () const; + /** Get the syntax tree node for the template declaration. */ + CT_TemplateDecl *Tree () const; + /** Get the base template if this is template specialization. */ + CTemplateInfo *BaseTemplate () const; + /** Create a new template parameter. + * \param add If \e true, add the created parameter to the template. */ + CTemplateParamInfo *newTemplateParam (bool add = true); + + /** Get the number of template parameters. */ + unsigned Parameters () const; + /** Get the n-th template parameter. + * \param n The index of the template parameter. + * \return The template parameter or NULL if \e n is invalid. */ + CTemplateParamInfo *Parameter (unsigned n) const; + /** Get the default argument of the n-th template parameter. + * \param n The index of the template parameter. + * \return The default argument expression or NULL if + * the parameter has no default argument. */ + CTree *DefaultArgument (unsigned n) const; + + /** Get the number of instances of this template. */ + unsigned Instances () const; + /** Get the n-th instance of this template. + * \param n The index of the instance. + * \return The template instance or NULL if \e n is invalid. */ + CObjectInfo *Instance (unsigned n); + /** Add the given instance to the template. + * \param info The semantic object of the template instance. */ + void addInstance (CObjectInfo *info); + /** Remove the given template instance. + * \param info The template instance. */ + void removeInstance (const CObjectInfo *info); + + /** Get the number of specializations of this template. */ + unsigned Specializations () const; + /** Get the n-th specialization of this template. + * \param n The index of the specialization. + * \return The specialization or NULL if \e n is invalid. */ + CTemplateInfo *Specialization (unsigned n); + /** Add the given specialization of the template. + * \param info The semantic object of the specialization. */ + void addSpecialization (CTemplateInfo *info); + /** Remove the given specialization of the template. + * \param info The template specialization. */ + void removeSpecialization (const CTemplateInfo *info); + /** Set whether this is a specialization of a template. + * \param v \e true if this is a specialization. */ + void isSpecialization (bool v); + /** Set the template specialization name (template id). + * \param name The template specialization name. */ + void SpecializationName (CT_TemplateName *name); + /** Get the template specialization name. + * \return The template specialization name or NULL if not a specialization. */ + CT_TemplateName *SpecializationName () const; + + /** Remove and destroy the given template parameter. + * \param p The template parameter. */ + void deleteTemplateParam (const CTemplateParamInfo *p); + /** Set the semantic object of the entity (class, function, etc). + * \param info The semantic object. */ + void ObjectInfo (CObjectInfo *info); + /** Set the base template if this is a template specialization. + * \param info The base template. */ + void BaseTemplate (CTemplateInfo *info); + + /** Check if the given template instances have the + * same instantiation arguments. + * \param i1 A template instance. + * \param i2 Another template instance. + * \param matchTemplateParams Template parameter compare mode. */ + static bool equalArguments (CTemplateInstance *i1, CTemplateInstance *i2, bool matchTemplateParams = false); + + /** Check if the given templates have equals parameters. + * \param t1 A template. + * \param t2 Another template. */ + static bool equalParameters (CTemplateInfo *t1, CTemplateInfo *t2); + + /** Add a tree fragment created during template instantiation. */ + void addTreeFragment (CTree* fragment); + +private: + void linkInstance (CObjectInfo *); + CTemplateInfo *nextTemplate (CTemplateInfo *tinfo) const; +}; + +inline CTemplateInfo::CTemplateInfo () : + CStructure (CObjectInfo::TEMPLATE_INFO), + _ObjectInfo ((CObjectInfo*)0), + _Base ((CTemplateInfo*)0), + _isSpecial (false), + _SpecializationName ((CT_TemplateName*)0), + _Depth (0), + _Params (1, 2), + _Instances (1, 5), + _Specializations (1, 5), + _TreeFragments (2, 5) + {} + +inline void CTemplateInfo::increaseDepth () + { _Depth++; } +inline void CTemplateInfo::decreaseDepth () + { if (_Depth) _Depth--; } +inline unsigned CTemplateInfo::Depth () const + { return _Depth; } + +inline unsigned CTemplateInfo::Instances () const + { return _Instances.length (); } +inline CObjectInfo *CTemplateInfo::Instance (unsigned i) + { return _Instances.lookup (i); } +inline void CTemplateInfo::addInstance (CObjectInfo *inst) + { _Instances.append (inst); linkInstance (inst); } + +inline unsigned CTemplateInfo::Specializations () const + { return _Specializations.length (); } +inline CTemplateInfo *CTemplateInfo::Specialization (unsigned i) + { return _Specializations.lookup (i); } +inline void CTemplateInfo::isSpecialization (bool v) + { _isSpecial = v; } +inline CT_TemplateName *CTemplateInfo::SpecializationName () const + { return _SpecializationName; } +inline void CTemplateInfo::SpecializationName (CT_TemplateName *name) + { _SpecializationName = name; } + +inline unsigned CTemplateInfo::Parameters () const + { return _Params.length (); } +inline CTemplateParamInfo *CTemplateInfo::Parameter (unsigned i) const + { return _Params.lookup (i); } + +inline CObjectInfo *CTemplateInfo::ObjectInfo () const + { return _ObjectInfo; } +inline void CTemplateInfo::ObjectInfo (CObjectInfo *info) + { if (info && (void*)info < (void*)0x10) *(int*)info = 0; + _ObjectInfo = info; } +inline CTemplateInfo *CTemplateInfo::BaseTemplate () const + { return _Base; } + +inline bool CTemplateInfo::isFunction () const + { return ObjectInfo () && ObjectInfo ()->FunctionInfo (); } +inline bool CTemplateInfo::isClass () const + { return ObjectInfo () && ObjectInfo ()->ClassInfo (); } +inline bool CTemplateInfo::isAttribute () const + { return ObjectInfo () && ObjectInfo ()->AttributeInfo (); } +inline bool CTemplateInfo::isBaseTemplate () const + { return ! _isSpecial && ! (_Base); } +inline bool CTemplateInfo::isSpecialization () const + { return _Base || _isSpecial; } + +inline CT_TemplateDecl *CTemplateInfo::Tree () const + { return (CT_TemplateDecl*)CObjectInfo::Tree (); } + + +} // namespace Puma + +#endif /* __CTemplateInfo_h__ */ diff --git a/Puma/src/infos/CTemplateInstance.cc b/Puma/src/infos/CTemplateInstance.cc new file mode 100644 index 0000000..c039382 --- /dev/null +++ b/Puma/src/infos/CTemplateInstance.cc @@ -0,0 +1,48 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CTemplateInstance.h" +#include "Puma/CCInstantiation.h" +#include "Puma/CSemDatabase.h" +#include "Puma/Builder.h" + +namespace Puma { + + +CTemplateInstance::~CTemplateInstance () { + if (_IsSpecialization) + for (unsigned i = 0; i < InstantiationArgs (); i++) + delete InstantiationArg (i); + for (unsigned i = 0; i < DeducedArgs (); i++) + delete DeducedArg (i); +} + + +bool CTemplateInstance::instantiate (CStructure *scope) { + if (_Pseudo && _CanInstantiate) { + CCInstantiation inst(_TemplateInfo->ClassDB()->Project()->err()); + _Pseudo = false; + inst.instantiate(this, scope); + hasDelayedParseProblem (inst.detectedDelayedParseProblem ()); + _Pseudo = ! isInstantiated(); + } + return ! _Pseudo; +} + + +} // namespace Puma diff --git a/Puma/src/infos/CTemplateInstance.h b/Puma/src/infos/CTemplateInstance.h new file mode 100644 index 0000000..c75e87c --- /dev/null +++ b/Puma/src/infos/CTemplateInstance.h @@ -0,0 +1,236 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CTemplateInstance_h__ +#define __CTemplateInstance_h__ + +/** \file + * Semantic information about a template instance. */ + +#include "Puma/DeducedArgument.h" +#include "Puma/CTemplateInfo.h" + +namespace Puma { + + +class CT_SimpleName; + + +/** \class CTemplateInstance CTemplateInstance.h Puma/CTemplateInstance.h + * Semantic information about a template instance. + * Contains the point of instantiation, the instantiated template, + * the instantiation arguments, and the deduced template arguments. + * + * The point of instantiation (POI) is the corresponding template-id. + * \code X x; // X is the POI \endcode + * + * The instantiation arguments are the arguments of the template-id + * at the POI. + * \code Y y; // 'int' and '1' are the instantiation arguments \endcode + * + * The deduced template arguments are calculated from the instantiation + * arguments and the template default arguments. + * + * \code + * template + * struct Foo { + * template + * T1 foo(T2,T3,T4*); + * }; + * + * void bar(bool b, char* s) { + * Foo f; // deduced arguments: T1=int, T2=float + * f.foo(1,b,s); // deduced arguments: T3=bool, T4=char + * } + * \endcode + * + * If a template instance is not yet created (maybe because real template + * instantiation is disabled or due to late template instantiation), then + * this template instance is called a pseudo instance. */ +class CTemplateInstance { +protected: + /** The semantic information about the template. */ + CTemplateInfo *_TemplateInfo; + /** The semantic information about the instance. */ + CObjectInfo *_ObjectInfo; + /** The point of instantiation. */ + CTree *_PointOfInstantiation; + /** The scope in which the template was instantiated. */ + CScopeInfo *_PointOfInstantiationScope; + /** The list of deduced template arguments. */ + Array _DeducedArgs; + /** The list of instantiation arguments. */ + Array _InstantiationArgs; + /** True if this is not a real template instance. */ + bool _Pseudo; + /** True if this pseudo instance can be instantiated. */ + bool _CanInstantiate; + /** True if instantiated. */ + bool _IsInstantiated; + /** True if this is the instance of a template specialization. */ + bool _IsSpecialization; + /** True if this node had a delayed parse problem. */ + bool _HasDelayedParseProblem; + +public: + /** Constructor. */ + CTemplateInstance (); + /** Destructor. Destroys the instantiation and deduced arguments. + * Optionally destroys the translation unit of the instance code. */ + ~CTemplateInstance (); + + /** If this is a pseudo instance, instantiate the template. + * \param scope The scope in which to instantiate the template. + * \return true if instantiation succeeded. */ + bool instantiate (CStructure *scope); + + /** Get the semantic information about the instantiated template. */ + CTemplateInfo *Template () const; + /** Get the semantic information about the class or function. */ + CObjectInfo *Object () const; + /** Set the semantic information about the instantiated template. + * \param info The template that was instantiated. */ + void Template (CTemplateInfo *info); + /** Set the semantic information about the instance. + * \param info The instance object. */ + void Object (CObjectInfo *info); + + /** Get the point of instantiation (e.g. the template-id). */ + CTree *PointOfInstantiation () const; + /** Get the scope in which the template was instantiated. */ + CScopeInfo *PointOfInstantiationScope () const; + /** Set the point of instantiation (e.g. the template-id). + * \param poi The template-id used to instantiate the template. + * \param scope The scope in which the template was instantiated. */ + void PointOfInstantiation (CTree *poi, CScopeInfo *scope); + + /** Set that the pseudo instance can be instantiated. */ + void canInstantiate (bool can); + + /** Return true if the pseudo instance can be instantiated. */ + bool canInstantiate (); + + /** Set whether this is a pseudo template instance. + * \param v True for yes, false for no. */ + void isPseudoInstance (bool v); + /** Check if this is a pseudo template instance. */ + bool isPseudoInstance () const; + + /** Set whether this template instance really is instantiated. + * \param is True for yes, false for no. */ + void isInstantiated (bool is); + /** Check if this template instance really is instantiated. */ + bool isInstantiated () const; + + /** Indicate a delayed parse problem during instantiation. + * \param has True for yes, false for no. */ + void hasDelayedParseProblem (bool has); + + /** Check whether this instance had a delayed parse problem. */ + bool hasDelayedParseProblem () const; + + /** Get the number of instantiation arguments. */ + unsigned InstantiationArgs () const; + /** Get the n-th instantiation argument. + * \param n The index of the instantiation argument. */ + DeducedArgument *InstantiationArg (unsigned n) const; + /** Add an instantiation argument. + * \param arg The instantiation argument. */ + void addInstantiationArg (DeducedArgument *arg); + + /** Get the number of deduced arguments. */ + unsigned DeducedArgs () const; + /** Get the n-th deduced template argument. + * \param n The index of the template argument. */ + DeducedArgument *DeducedArg (unsigned n) const; + /** Add a deduced template argument. + * \param arg The deduced template argument. */ + void addDeducedArg (DeducedArgument *arg); + /** Discard the deduced template arguments. */ + void clearDeducedArgs (); +}; + +inline CTemplateInstance::CTemplateInstance () : + _TemplateInfo ((CTemplateInfo*)0), + _ObjectInfo ((CObjectInfo*)0), + _PointOfInstantiation ((CTree*)0), + _DeducedArgs (1, 2), + _InstantiationArgs (1, 2), + _Pseudo (false), + _CanInstantiate (true), + _IsInstantiated (false), + _IsSpecialization (false) + {} + +inline void CTemplateInstance::canInstantiate (bool can) + { _CanInstantiate = can; } +inline bool CTemplateInstance::canInstantiate () + { return _CanInstantiate; } + +inline void CTemplateInstance::isPseudoInstance (bool v) + { _Pseudo = v; } +inline bool CTemplateInstance::isPseudoInstance () const + { return _Pseudo; } + +inline void CTemplateInstance::isInstantiated (bool is) + { _IsInstantiated = is; } +inline bool CTemplateInstance::isInstantiated () const + { return _IsInstantiated; } + +inline void CTemplateInstance::hasDelayedParseProblem (bool has) + { _HasDelayedParseProblem = has; } +inline bool CTemplateInstance::hasDelayedParseProblem () const + { return _HasDelayedParseProblem; } + +inline void CTemplateInstance::addDeducedArg (DeducedArgument *a) + { _DeducedArgs.append (a); } +inline DeducedArgument *CTemplateInstance::DeducedArg (unsigned i) const + { return _DeducedArgs.lookup (i); } +inline unsigned CTemplateInstance::DeducedArgs () const + { return _DeducedArgs.length (); } +inline void CTemplateInstance::addInstantiationArg (DeducedArgument *a) + { _InstantiationArgs.append (a); } +inline DeducedArgument *CTemplateInstance::InstantiationArg (unsigned i) const + { return _InstantiationArgs.lookup (i); } +inline unsigned CTemplateInstance::InstantiationArgs () const + { return _InstantiationArgs.length (); } +inline void CTemplateInstance::clearDeducedArgs () + { _DeducedArgs.reset (); _InstantiationArgs.reset (); } + +inline CTemplateInfo *CTemplateInstance::Template () const + { return _TemplateInfo; } +inline void CTemplateInstance::Template (CTemplateInfo *info) + { _TemplateInfo = info; _IsSpecialization = info && info->isSpecialization(); } +inline CObjectInfo *CTemplateInstance::Object () const + { return _ObjectInfo; } +inline void CTemplateInstance::Object (CObjectInfo *info) + { _ObjectInfo = info; } + +inline CTree *CTemplateInstance::PointOfInstantiation () const + { return _PointOfInstantiation; } +inline CScopeInfo *CTemplateInstance::PointOfInstantiationScope () const + { return _PointOfInstantiationScope; } +inline void CTemplateInstance::PointOfInstantiation (CTree *poi, CScopeInfo *pois) + { _PointOfInstantiation = poi; + _PointOfInstantiationScope = pois; + } + + +} // namespace Puma + +#endif /* __CTemplateInstance_h__ */ diff --git a/Puma/src/infos/CTemplateParamInfo.cc b/Puma/src/infos/CTemplateParamInfo.cc new file mode 100644 index 0000000..7b2a1d7 --- /dev/null +++ b/Puma/src/infos/CTemplateParamInfo.cc @@ -0,0 +1,98 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CTemplateParamInfo.h" +#include "Puma/CTemplateInstance.h" +#include "Puma/CTemplateInfo.h" +#include "Puma/CStructure.h" +#include "Puma/CTree.h" + +namespace Puma { + + +CTemplateParamInfo::~CTemplateParamInfo () { + if (_ValueType) + CTypeInfo::Destroy (_ValueType); + if (_InstanceInfo) + delete _InstanceInfo; +} + +bool CTemplateParamInfo::match (const CTemplateParamInfo& tp) const { + if (isTemplate () != tp.isTemplate ()) + return false; + if (isTypeParam () != tp.isTypeParam ()) + return false; + if (ValueType () && tp.ValueType () && *ValueType () != *tp.ValueType ()) + return false; + + if (isTemplate ()) { + CTemplateInfo *t1 = TemplateTemplate (); + CTemplateInfo *t2 = tp.TemplateTemplate (); + if (! t1 || ! t2 || (t1->Parameters () != t2->Parameters ())) + return false; + for (unsigned i = 0; i < t1->Parameters (); i++) { + if (! t1->Parameter (i)->match (*t2->Parameter (i))) + return false; + } + } + return true; +} + +CTree *CTemplateParamInfo::DefaultArgument () const { + CTemplateInfo *tpl = _TemplateInfo; + int pos = getPosition (); + if (tpl && pos != -1) { + do { + if ((int)tpl->Parameters () > pos) { + CTemplateParamInfo *param = tpl->Parameter (pos); + if (param) { + CT_TemplateParamDecl *tpd = param->Tree (); + if (tpd && tpd->DefaultArgument ()) + return tpd->DefaultArgument ()->Entry (0); + } + } + CObjectInfo *obj = tpl->ObjectInfo (), *first = obj; + tpl = 0; + if (obj) { + obj = obj->NextObject (); + while (obj && obj != first) { + if ((tpl = obj->Template ())) + break; + obj = obj->NextObject (); + } + } + } while (tpl && tpl != _TemplateInfo); + } else { + // fallback + CT_TemplateParamDecl *tpd = Tree (); + if (tpd && tpd->DefaultArgument ()) + return tpd->DefaultArgument ()->Entry (0); + } + return (CTree*)0; +} + +int CTemplateParamInfo::getPosition () const { + if (_TemplateInfo) + for (unsigned i = 0; i < _TemplateInfo->Parameters (); i++) + if (*this == *_TemplateInfo->Parameter (i)) + return i; + return -1; +} + + +} // namespace Puma diff --git a/Puma/src/infos/CTemplateParamInfo.h b/Puma/src/infos/CTemplateParamInfo.h new file mode 100644 index 0000000..de0f3a7 --- /dev/null +++ b/Puma/src/infos/CTemplateParamInfo.h @@ -0,0 +1,157 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CTemplateParamInfo_h__ +#define __CTemplateParamInfo_h__ + +/** \file + * Semantic information about a template parameter. */ + +#include "Puma/CObjectInfo.h" + +namespace Puma { + + +class CT_TemplateParamDecl; +class CTypeTemplateParam; +class CTemplateInstance; +class CTemplateInfo; +class CTree; + + +/** \class CTemplateParamInfo CTemplateParamInfo.h Puma/CTemplateParamInfo.h + * Semantic information about a template parameter. There are + * three kinds of template parameter: type, non-type, and template + * template parameter. + * + * \code + * // T is a type template parameter + * // I is a non-type template parameter + * // TT is a template template parameter + * template class TT> + * class X { + * TT x; + * }; + * \endcode */ +class CTemplateParamInfo : public CObjectInfo { + CTemplateInfo *_TemplateInfo; + CTemplateInfo *_TemplateTemplate; + CTemplateInstance *_InstanceInfo; + CTypeInfo *_ValueType; + bool _TypeParam; + +public: + /** Constructor. */ + CTemplateParamInfo (); + /** Destructor. If the object type is CObjectInfo::TEMPLATE_PARAM_INFO, + * then CObjectInfo::CleanUp() is called and the template instance + * information object of a template template parameter is destroyed. */ + ~CTemplateParamInfo (); + + /** Check if this template parameter matches the given. + * Must be same kind of parameter, same type and value. */ + bool match(const CTemplateParamInfo& tp) const; + + /** Check if this is a template template parameter. */ + bool isTemplate () const; + /** Check if this is a type template parameter. */ + bool isTypeParam () const; + /** Get the template this parameter belongs to. */ + CTemplateInfo *TemplateInfo () const; + /** Get the template information of a template template parameter. */ + CTemplateInfo *TemplateTemplate () const; + /** Get the syntax tree node representing the template parameter. */ + CT_TemplateParamDecl *Tree () const; + /** Get the default argument of the template parameter. + * \return The default argument expression or NULL if no default argument. */ + CTree *DefaultArgument () const; + /** Get the template parameter type. */ + CTypeTemplateParam *TypeInfo () const; + /** Get the value type of a type template parameter. */ + CTypeInfo *ValueType () const; + /** Get the template instance information for an instantiated + * template template parameter. */ + CTemplateInstance *TemplateInstance () const; + /** Get the position/index of this parameter in the template parameter list. */ + int getPosition () const; + + /** Set whether this is a type template parameter. + * \param v True for yes, false for no. */ + void isTypeParam (bool v); + /** Set the value type of a type template parameter. + * \param type The value type. */ + void ValueType (CTypeInfo *type); + /** Set the template parameter list information for + * a template template parameter. + * \param info The template parameter list information. */ + void TemplateInfo (CTemplateInfo *info); + /** Set the template information for a template template parameter. + * \param info The template information. */ + void TemplateTemplate (CTemplateInfo *info); + /** Set the template instance information for an instantiated template + * template parameter. + * \param inst The template instance. */ + void TemplateInstance (CTemplateInstance *inst); +}; + +inline CTemplateParamInfo::CTemplateParamInfo () : + CObjectInfo (CObjectInfo::TEMPLATE_PARAM_INFO), + _TemplateInfo ((CTemplateInfo*)0), + _TemplateTemplate ((CTemplateInfo*)0), + _InstanceInfo ((CTemplateInstance*)0), + _ValueType ((CTypeInfo*)0), + _TypeParam (false) + {} + +inline void CTemplateParamInfo::isTypeParam (bool tp) + { _TypeParam = tp; } +inline bool CTemplateParamInfo::isTypeParam () const + { return _TypeParam; } + +inline bool CTemplateParamInfo::isTemplate () const + { return (_TemplateTemplate); } + +inline void CTemplateParamInfo::ValueType (CTypeInfo *vt) + { _ValueType = vt; } +inline CTypeInfo *CTemplateParamInfo::ValueType () const + { return _ValueType; } + +inline CTemplateInfo *CTemplateParamInfo::TemplateInfo () const + { return _TemplateInfo; } +inline CTemplateInfo *CTemplateParamInfo::TemplateTemplate () const + { return _TemplateTemplate; } +inline void CTemplateParamInfo::TemplateInfo (CTemplateInfo *info) + { _TemplateInfo = info; } +inline void CTemplateParamInfo::TemplateTemplate (CTemplateInfo *info) + { _TemplateTemplate = info; } +inline void CTemplateParamInfo::TemplateInstance (CTemplateInstance *info) + { _InstanceInfo = info; } + +inline CT_TemplateParamDecl *CTemplateParamInfo::Tree () const + { return (CT_TemplateParamDecl*)CObjectInfo::Tree (); } + +inline CTypeTemplateParam *CTemplateParamInfo::TypeInfo () const + { return (CTypeTemplateParam*)CObjectInfo::TypeInfo (); } + +inline CTemplateInstance *CTemplateParamInfo::TemplateInstance () const + { return _InstanceInfo; } + + +} // namespace Puma + +#endif /* __CTemplateParamInfo_h__ */ diff --git a/Puma/src/infos/CTypedefInfo.cc b/Puma/src/infos/CTypedefInfo.cc new file mode 100644 index 0000000..83b75bc --- /dev/null +++ b/Puma/src/infos/CTypedefInfo.cc @@ -0,0 +1,30 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CTypedefInfo.h" +#include "Puma/CStructure.h" +#include "Puma/CSemDatabase.h" + +namespace Puma { + + +CTypedefInfo::~CTypedefInfo () { +} + + +} // namespace Puma diff --git a/Puma/src/infos/CTypedefInfo.h b/Puma/src/infos/CTypedefInfo.h new file mode 100644 index 0000000..2e0f566 --- /dev/null +++ b/Puma/src/infos/CTypedefInfo.h @@ -0,0 +1,50 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CTypedefInfo_h__ +#define __CTypedefInfo_h__ + +/** \file + * Semantic information about a typedef. */ + +#include "Puma/CScopeRequest.h" + +namespace Puma { + + +/** \class CTypedefInfo CTypedefInfo.h Puma/CTypedefInfo.h + * Semantic information about a typedef. A typedef is a + * named type for any underlying type. The type of a typedef + * is the underlying type. */ +class CTypedefInfo : public CScopeRequest { +public: + /** Constructor. */ + CTypedefInfo (); + /** Destructor. If the object type is CObjectInfo::TYPEDEF_INFO, + * then CObjectInfo::CleanUp() is called. */ + ~CTypedefInfo (); +}; + +inline CTypedefInfo::CTypedefInfo () : + CScopeRequest (CObjectInfo::TYPEDEF_INFO) + {} + + +} // namespace Puma + +#endif /* __CTypedefInfo_h__ */ diff --git a/Puma/src/infos/CUnionInfo.cc b/Puma/src/infos/CUnionInfo.cc new file mode 100644 index 0000000..58f241b --- /dev/null +++ b/Puma/src/infos/CUnionInfo.cc @@ -0,0 +1,38 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CUnionInfo.h" +#include "Puma/CTemplateInstance.h" +#include "Puma/CTree.h" + +namespace Puma { + + +CUnionInfo *CUnionInfo::DefObject () const { + CObjectInfo *o = (CObjectInfo*)this; + do { + if (o->Tree () && o->Tree ()->NodeName () == CT_UnionDef::NodeId ()) + if (! o->TemplateInstance () || o->TemplateInstance ()->canInstantiate ()) + return o->UnionInfo (); + o = o->NextObject (); + } while (o != (CObjectInfo*)this); + return (CUnionInfo*)this; +} + + +} // namespace Puma diff --git a/Puma/src/infos/CUnionInfo.h b/Puma/src/infos/CUnionInfo.h new file mode 100644 index 0000000..6cbe81b --- /dev/null +++ b/Puma/src/infos/CUnionInfo.h @@ -0,0 +1,73 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CUnionInfo_h__ +#define __CUnionInfo_h__ + +/** \file + * Semantic information about a union. */ + +#include "Puma/CRecord.h" + +namespace Puma { + + +class CTypeUnion; + + +/** \class CUnionInfo CUnionInfo.h Puma/CUnionInfo.h + * Semantic information about a union. */ +class CUnionInfo : public CRecord { +protected: + /** Constructor. + * \param id The object type. */ + CUnionInfo (ObjectId id); + +public: + /** Constructor. */ + CUnionInfo (); + /** Destructor. If the object type is CObjectInfo::UNION_INFO, + * then CObjectInfo::CleanUp() is called. */ + ~CUnionInfo (); + + /** Get the semantic object of the union definition. + * \see CObjectInfo::DefObject() */ + CUnionInfo *DefObject () const; + /** Get the type information for the union. */ + CTypeUnion *TypeInfo () const; +// CT_UnionDef *Tree () const; +}; + +inline CUnionInfo::CUnionInfo (ObjectId id) : + CRecord (id) + {} +inline CUnionInfo::CUnionInfo () : + CRecord (CObjectInfo::UNION_INFO) + {} +inline CUnionInfo::~CUnionInfo () + {} + +inline CTypeUnion *CUnionInfo::TypeInfo () const + { return (CTypeUnion*)CObjectInfo::TypeInfo (); } +//inline CT_UnionDef *CUnionInfo::Tree () const +// { return (CT_UnionDef*)CObjectInfo::Tree (); } + + +} // namespace Puma + +#endif /* __CUnionInfo_h__ */ diff --git a/Puma/src/infos/CUnionInstance.h b/Puma/src/infos/CUnionInstance.h new file mode 100644 index 0000000..fd9d3f7 --- /dev/null +++ b/Puma/src/infos/CUnionInstance.h @@ -0,0 +1,59 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CUnionInstance_h__ +#define __CUnionInstance_h__ + +/** \file + * Semantic information about an instance of a union template. */ + +#include "Puma/CTemplateInstance.h" +#include "Puma/CUnionInfo.h" + +namespace Puma { + + +/** \class CUnionInstance CUnionInstance.h Puma/CUnionInstance.h + * Semantic information about an instance of a union template. */ +class CUnionInstance : public CUnionInfo { + CTemplateInstance _InstanceInfo; + +public: + /** Constructor. */ + CUnionInstance (); + /** Destructor. If the object type is CObjectInfo::UNION_INSTANCE_INFO, + * then CObjectInfo::CleanUp() is called. */ + ~CUnionInstance (); + + /** Get the semantic information about the template instance. */ + CTemplateInstance *TemplateInstance () const; +}; + +inline CUnionInstance::CUnionInstance () : + CUnionInfo (CObjectInfo::UNION_INSTANCE_INFO) + {} +inline CUnionInstance::~CUnionInstance () + {} + +inline CTemplateInstance *CUnionInstance::TemplateInstance () const + { return (CTemplateInstance*)(&_InstanceInfo); } + + +} // namespace Puma + +#endif /* __CUnionInstance_h__ */ diff --git a/Puma/src/infos/CUsingInfo.cc b/Puma/src/infos/CUsingInfo.cc new file mode 100644 index 0000000..1d01d55 --- /dev/null +++ b/Puma/src/infos/CUsingInfo.cc @@ -0,0 +1,29 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CUsingInfo.h" +#include "Puma/CStructure.h" + +namespace Puma { + + +CUsingInfo::~CUsingInfo () { +} + + +} // namespace Puma diff --git a/Puma/src/infos/CUsingInfo.h b/Puma/src/infos/CUsingInfo.h new file mode 100644 index 0000000..f272bc0 --- /dev/null +++ b/Puma/src/infos/CUsingInfo.h @@ -0,0 +1,78 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CUsingInfo_h__ +#define __CUsingInfo_h__ + +/** \file + * Semantic information about a using-directive. */ + +#include "Puma/CScopeRequest.h" + +namespace Puma { + + +class CNamespaceInfo; + + +/** \class CUsingInfo CUsingInfo.h Puma/CUsingInfo.h + * Semantic information about a using-directive. + * The using-directive makes names from a namespace + * visible in another namespace or scope. + * + * Example: + * \code + * namespace A { + * class X {}; + * } + * using namespace A; // make A::X visible in global scope + * X x; // resolves to A::X + * \endcode */ +class CUsingInfo : public CScopeRequest { + CNamespaceInfo *_Namespace; + +public: + /** Constructor. */ + CUsingInfo (); + /** Destructor. If the object type is CObjectInfo::USING_INFO, + * then CObjectInfo::CleanUp() is called. */ + ~CUsingInfo (); + + /** Get the semantic information for the namespace whose + * names are made visible. */ + CNamespaceInfo *Namespace () const; + /** Set the semantic information for the namespace whose + * names are made visible. + * \param info The namespace. */ + void Namespace (CNamespaceInfo *info); +}; + +inline CUsingInfo::CUsingInfo () : + CScopeRequest (CObjectInfo::USING_INFO), + _Namespace (0) + {} + +inline CNamespaceInfo *CUsingInfo::Namespace () const + { return _Namespace; } +inline void CUsingInfo::Namespace (CNamespaceInfo *nsinfo) + { _Namespace = nsinfo; } + + +} // namespace Puma + +#endif /* __CUsingInfo_h__ */ diff --git a/Puma/src/infos/types/CTypeAddress.inc b/Puma/src/infos/types/CTypeAddress.inc new file mode 100644 index 0000000..ddf3da0 --- /dev/null +++ b/Puma/src/infos/types/CTypeAddress.inc @@ -0,0 +1,66 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CTypeAddress_h__ +#define __CTypeAddress_h__ + +/** \file + * Type of a reference. */ + +#ifndef __CTypeInfo_h__ +#warning !!! DO NOT INCLUDE THIS FILE !!! +#warning !!! INCLUDE FILE "CTypeInfo.h" INSTEAD !!! +#endif + +namespace Puma { + + +/** \class CTypeAddress CTypeAddress.inc Puma/CTypeInfo.h + * Type of a reference. + * Examples: + * \code + * int& i = i0; // i has type 'reference to int' + * // type structure: + * // CTypeAddress + * // CTypePrimitive int + * const X& x = x0; // x has type 'reference to const X' + * // type structure: + * // CTypeAddress + * // CTypeQualified const + * // CTypeClass X + * \endcode + * \ingroup types */ +class CTypeAddress : public CTypeInfo { +public: + /** Constructor. Type has id CTypeInfo::TYPE_ADDRESS. + * \param base The base type. */ + CTypeAddress (CTypeInfo *base); + /** Destructor. */ + ~CTypeAddress (); +}; + +inline CTypeAddress::CTypeAddress (CTypeInfo *base) : + CTypeInfo (base, CTypeInfo::TYPE_ADDRESS) + {} +inline CTypeAddress::~CTypeAddress () + {} + + +} // namespace Puma + +#endif /* __CTypeAddress_h__ */ diff --git a/Puma/src/infos/types/CTypeArray.inc b/Puma/src/infos/types/CTypeArray.inc new file mode 100644 index 0000000..15d3698 --- /dev/null +++ b/Puma/src/infos/types/CTypeArray.inc @@ -0,0 +1,146 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CTypeArray_h__ +#define __CTypeArray_h__ + +/** \file + * Type of an array. */ + +#ifndef __CTypeInfo_h__ +#warning !!! DO NOT INCLUDE THIS FILE !!! +#warning !!! INCLUDE FILE "CTypeInfo.h" INSTEAD !!! +#endif + +namespace Puma { + + +/** \class CTypeArray CTypeArray.inc Puma/CTypeInfo.h + * Type of an array. + * Examples: + * \code + * int i[10]; // i has type 'array of int' + * // type structure: + * // CTypeArray dim=10 + * // CTypePrimitive int + * char* sa[5]; // sa has type 'array of pointer to char' + * // type structure: + * // CTypeArray dim=5 + * // CTypePointer + * // CTypePrimitive char + * \endcode + * \ingroup types */ +class CTypeArray : public CTypeInfo { + long int _Size; + bool _isFixed; + CTypeQualified *_Quals; + CTypeTemplateParam *_DepDim; + bool _hasDim; + +protected: + /** Constructor. + * \param base The base type of the array. + * \param quals The type qualifiers. + * \param id The type identifier. */ + CTypeArray (CTypeInfo *base, CTypeQualified *quals, TypeId id); + +public: + /** Constructor. Type has id CTypeInfo::TYPE_ARRAY. + * \param base The base type of the array. + * \param quals The type qualifiers. + * \param has_dimension The array was declared with a constant dimension. */ + CTypeArray (CTypeInfo *base, CTypeQualified *quals = 0, bool has_dimension = false); + /** Destructor. */ + ~CTypeArray (); + + /** Set the dimension of the array. + * \param dim The dimension. */ + void Dimension (long int dim); + /** Get the dimension of the array. */ + long int Dimension () const; + /** Set whether the array was declared with a constant dimension. + * \param constant Array has constant dimension. */ + void hasDimension (bool constant); + /** Check if the array has a constant dimension. */ + bool hasDimension () const; + + /** Set whether the array has a fixed length. + * \param fixed Has fixed length. */ + void isFixed (bool fixed); + /** Check if the array has a fixed length. */ + bool isFixed () const; + + /** Get the array type qualifiers. */ + CTypeQualified *Qualifiers () const; + + /** Set the template parameter information if the dimension + * of the array depends on this template parameter. + * \param param The template parameter. */ + void DepDim (CTypeTemplateParam *param); + /** Get the template parameter information if the dimension + * of the array depends on a template parameter. + * \return The template parameter or NULL. */ + CTypeTemplateParam *DepDim () const; +}; + +inline CTypeArray::CTypeArray (CTypeInfo *base, CTypeQualified *quals, bool has_dimension) : + CTypeInfo (base, CTypeInfo::TYPE_ARRAY), + _Size (0), + _isFixed (false), + _Quals (quals), + _DepDim (0), + _hasDim (has_dimension) + {} +inline CTypeArray::CTypeArray (CTypeInfo *base, CTypeQualified *quals, CTypeInfo::TypeId id) : + CTypeInfo (base, id), + _Size (0), + _isFixed (false), + _Quals (quals), + _DepDim (0), + _hasDim (false) + {} +inline CTypeArray::~CTypeArray () + {} + +inline void CTypeArray::Dimension (long int d) + { _Size = d; } +inline long int CTypeArray::Dimension () const + { return _Size; } + +inline void CTypeArray::isFixed (bool v) + { _isFixed = v; } +inline bool CTypeArray::isFixed () const + { return _isFixed; } + +inline void CTypeArray::hasDimension (bool v) + { _hasDim = v; } +inline bool CTypeArray::hasDimension () const + { return _hasDim || _Size != 0; } + +inline CTypeQualified *CTypeArray::Qualifiers () const + { return _Quals; } + +inline void CTypeArray::DepDim (CTypeTemplateParam *tp) + { _DepDim = tp; } +inline CTypeTemplateParam *CTypeArray::DepDim () const + { return _DepDim; } + + +} // namespace Puma + +#endif /* __CTypeArray_h__ */ diff --git a/Puma/src/infos/types/CTypeBitField.inc b/Puma/src/infos/types/CTypeBitField.inc new file mode 100644 index 0000000..a0705bf --- /dev/null +++ b/Puma/src/infos/types/CTypeBitField.inc @@ -0,0 +1,77 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CTypeBitField_h__ +#define __CTypeBitField_h__ + +/** \file + * Type of a bit-field. */ + +#ifndef __CTypeInfo_h__ +#warning !!! DO NOT INCLUDE THIS FILE !!! +#warning !!! INCLUDE FILE "CTypeInfo.h" INSTEAD !!! +#endif + +namespace Puma { + + +/** \class CTypeBitField CTypeBitField.inc Puma/CTypeInfo.h + * Type of a bit-field. + * Example: + * \code + * class X { + * int i : 10; // i has type 'bit-field of size 10' + * // type structure: + * // CTypeBitField dim=10 + * // CTypePrimitive int + * }; + * \endcode + * \ingroup types */ +class CTypeBitField : public CTypeInfo { + long int _Size; + +public: + /** Constructor. Type has id CTypeInfo::TYPE_BIT_FIELD. + * \param base The base type. */ + CTypeBitField (CTypeInfo *base); + /** Destructor. */ + ~CTypeBitField (); + + /** Set the dimension of the bit-field. + * \param dim The dimension. */ + void Dimension (long int dim); + /** Get the dimension of the bit-field. */ + long int Dimension () const; +}; + +inline CTypeBitField::CTypeBitField (CTypeInfo *base) : + CTypeInfo (base, CTypeInfo::TYPE_BIT_FIELD), + _Size (0) + {} +inline CTypeBitField::~CTypeBitField () + {} + +inline void CTypeBitField::Dimension (long int v) + { _Size = v; } +inline long int CTypeBitField::Dimension () const + { return _Size; } + + +} // namespace Puma + +#endif /* __CTypeBitField_h__ */ diff --git a/Puma/src/infos/types/CTypeClass.inc b/Puma/src/infos/types/CTypeClass.inc new file mode 100644 index 0000000..b4eb58f --- /dev/null +++ b/Puma/src/infos/types/CTypeClass.inc @@ -0,0 +1,73 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CTypeClass_h__ +#define __CTypeClass_h__ + +/** \file + * Type of a class. */ + +#ifndef __CTypeInfo_h__ +#warning !!! DO NOT INCLUDE THIS FILE !!! +#warning !!! INCLUDE FILE "CTypeInfo.h" INSTEAD !!! +#endif + +namespace Puma { + + +class CClassInfo; +class CRecord; +class CStructure; + + +/** \class CTypeClass CTypeClass.inc Puma/CTypeInfo.h + * Type of a class. + * Examples: + * \code + * class X x; // x has type 'class X' + * struct Y y; // y has type 'class Y' + * \endcode + * \ingroup types */ +class CTypeClass : public CTypeRecord { +public: + /** Constructor. Type has id CTypeInfo::TYPE_CLASS. + * \param c The semantic information about the class. */ + CTypeClass (CRecord *c); + /** Destructor. */ + ~CTypeClass (); + + /** Get the semantic information about the class. */ + CClassInfo *ClassInfo () const; + + /** If this is the type of a pseudo class instance, + * create a real instance of the corresponding template. + * \param scope The scope in which to instantiate the template. + * \return true if instantiation succeeded. */ + bool instantiate (CStructure *scope); +}; + +inline CTypeClass::CTypeClass (CRecord *c) : + CTypeRecord (CTypeInfo::TYPE_CLASS, c) + {} +inline CTypeClass::~CTypeClass () + {} + + +} // namespace Puma + +#endif /* __CTypeClass_h__ */ diff --git a/Puma/src/infos/types/CTypeEnum.inc b/Puma/src/infos/types/CTypeEnum.inc new file mode 100644 index 0000000..38f6100 --- /dev/null +++ b/Puma/src/infos/types/CTypeEnum.inc @@ -0,0 +1,79 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CTypeEnum_h__ +#define __CTypeEnum_h__ + +/** \file + * Type of an enumeration. */ + +#ifndef __CTypeInfo_h__ +#warning !!! DO NOT INCLUDE THIS FILE !!! +#warning !!! INCLUDE FILE "CTypeInfo.h" INSTEAD !!! +#endif + +namespace Puma { + + +class CEnumInfo; + + +/** \class CTypeEnum CTypeEnum.inc Puma/CTypeInfo.h + * Type of an enumeration. + * Examples: + * \code + * enum E { A,B } e; // e has type 'enum E' + * enum { C,D } a; // a has type 'enum ' + * \endcode + * \ingroup types */ +class CTypeEnum : public CTypeInfo { + CEnumInfo *_Enum; + +public: + /** Constructor. Type has id CTypeInfo::TYPE_ENUM. + * \param e The semantic information about the enumeration. */ + CTypeEnum (CEnumInfo *e); + /** Destructor. */ + ~CTypeEnum (); + + /** Get the semantic information about the enumeration. */ + CEnumInfo *EnumInfo () const; + + /** Check if the enumeration is complete. + * \param pos Optional source code position. */ + bool isComplete (unsigned long pos = 0) const; + + /** Get the implementation-defined underlying data + * type of the enumeration (defaults to \e int). */ + CTypeInfo *UnderlyingType () const; +}; + +inline CTypeEnum::CTypeEnum (CEnumInfo *e) : + CTypeInfo (&CTYPE_EMPTY, CTypeInfo::TYPE_ENUM), + _Enum (e) + {} +inline CTypeEnum::~CTypeEnum () + {} + +inline CEnumInfo *CTypeEnum::EnumInfo () const + { return _Enum; } + + +} // namespace Puma + +#endif /* __CTypeEnum_h__ */ diff --git a/Puma/src/infos/types/CTypeFunction.inc b/Puma/src/infos/types/CTypeFunction.inc new file mode 100644 index 0000000..3378968 --- /dev/null +++ b/Puma/src/infos/types/CTypeFunction.inc @@ -0,0 +1,107 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CTypeFunction_h__ +#define __CTypeFunction_h__ + +/** \file + * Type of a function. */ + +#ifndef __CTypeInfo_h__ +#warning !!! DO NOT INCLUDE THIS FILE !!! +#warning !!! INCLUDE FILE "CTypeInfo.h" INSTEAD !!! +#endif + +#include "Puma/CTypeList.inc" + +namespace Puma { + + +class CFunctionInfo; +class CRecord; + + +/** \class CTypeFunction CTypeFunction.inc Puma/CTypeInfo.h + * Type of a function. + * Example: + * \code + * void foo(int); // foo has type 'function returning void with one argument int' + * // type structure: + * // CTypeFunction args=int + * // CTypePrimitive void + * \endcode + * \ingroup types */ +class CTypeFunction : public CTypeQualified { + CTypeList *_ArgTypes; + CFunctionInfo *_Function; + bool _hasPrototype; + +public: + /** Constructor. Type has id CTypeInfo::TYPE_FUNCTION. + * \param base The base type (return type). + * \param args The argument type list. + * \param prototype Function has prototype. */ + CTypeFunction (CTypeInfo *base, CTypeList *args, bool prototype); + /** Destructor. */ + ~CTypeFunction (); + + /** Get the argument type list. */ + CTypeList *ArgTypes () const; + /** Get the return type. */ + CTypeInfo *ReturnType () const; + + /** Get the semantic information about the function. */ + CFunctionInfo *FunctionInfo () const; + /** Get the semantic information about the class if + * the function is a class method. */ + CRecord *Record () const; + + /** Set the semantic information about the function. */ + void FunctionInfo (CFunctionInfo *); + + /** Check if the function is declared \e static. */ + bool isStatic () const; + /** Check if the function has a prototype. */ + bool hasPrototype () const; +}; + +inline CTypeFunction::CTypeFunction (CTypeInfo *base, CTypeList *l, + bool prototype) : + CTypeQualified (base, false, false, false, CTypeInfo::TYPE_FUNCTION), + _ArgTypes (l), + _Function (0), + _hasPrototype (prototype) + {} +inline CTypeFunction::~CTypeFunction () + {} + +inline bool CTypeFunction::hasPrototype () const + { return _hasPrototype; } +inline CTypeList *CTypeFunction::ArgTypes () const + { return _ArgTypes; } +inline CTypeInfo *CTypeFunction::ReturnType () const + { return BaseType (); } +inline CFunctionInfo *CTypeFunction::FunctionInfo () const + { return _Function; } +inline void CTypeFunction::FunctionInfo (CFunctionInfo *info) + { _Function = info; } + + +} // namespace Puma + +#endif /* __CTypeFunction_h__ */ diff --git a/Puma/src/infos/types/CTypeInfo.cc b/Puma/src/infos/types/CTypeInfo.cc new file mode 100644 index 0000000..47c5ac0 --- /dev/null +++ b/Puma/src/infos/types/CTypeInfo.cc @@ -0,0 +1,1143 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CTypeInfo.h" +#include "Puma/CClassInfo.h" +#include "Puma/CUnionInfo.h" +#include "Puma/CEnumInfo.h" +#include "Puma/CConstant.h" +#include "Puma/CFileInfo.h" +#include "Puma/CFunctionInfo.h" +#include "Puma/CSemDatabase.h" +#include "Puma/CClassInfo.h" +#include "Puma/CUnionInfo.h" +#include "Puma/CClassInstance.h" +#include "Puma/CUnionInstance.h" +#include "Puma/CFctInstance.h" +#include "Puma/CObjectInfo.h" +#include "Puma/CTemplateInfo.h" +#include "Puma/CArgumentInfo.h" +#include "Puma/CAttributeInfo.h" +#include "Puma/DeducedArgument.h" +#include "Puma/CEnumeratorInfo.h" +#include "Puma/CTemplateParamInfo.h" +#include "Puma/Limits.h" +#include "Puma/CTree.h" +#include +#include +#include + +namespace Puma { + + +// The empty type /////////////////////////////////////////////// + +CTypeInfo CTYPE_EMPTY ((CTypeInfo*)0, CTypeInfo::TYPE_EMPTY); + +// Basic types ////////////////////////////////////////////////// + +CTypePrimitive CTYPE_BOOL ("bool", CTypeInfo::TYPE_BOOL, BOOL_SIZE); +CTypePrimitive CTYPE_C_BOOL ("_Bool", CTypeInfo::TYPE_C_BOOL, BOOL_SIZE); +CTypePrimitive CTYPE_CHAR ("char", CTypeInfo::TYPE_CHAR, CHAR_SIZE); +CTypePrimitive CTYPE_SIGNED_CHAR ("signed char", CTypeInfo::TYPE_SIGNED_CHAR, SCHAR_SIZE); +CTypePrimitive CTYPE_UNSIGNED_CHAR ("unsigned char", CTypeInfo::TYPE_UNSIGNED_CHAR, UCHAR_SIZE); +CTypePrimitive CTYPE_WCHAR_T ("wchar_t", CTypeInfo::TYPE_WCHAR_T, WCHAR_T_SIZE); +CTypePrimitive CTYPE_SHORT ("short int", CTypeInfo::TYPE_SHORT, SHORT_SIZE); +CTypePrimitive CTYPE_UNSIGNED_SHORT ("unsigned short int", CTypeInfo::TYPE_UNSIGNED_SHORT, USHORT_SIZE); +CTypePrimitive CTYPE_INT ("int", CTypeInfo::TYPE_INT, INT_SIZE); +CTypePrimitive CTYPE_UNSIGNED_INT ("unsigned int", CTypeInfo::TYPE_UNSIGNED_INT, UINT_SIZE); +CTypePrimitive CTYPE_LONG ("long int", CTypeInfo::TYPE_LONG, LONG_SIZE); +CTypePrimitive CTYPE_UNSIGNED_LONG ("unsigned long int", CTypeInfo::TYPE_UNSIGNED_LONG, ULONG_SIZE); +CTypePrimitive CTYPE_LONG_LONG ("long long int", CTypeInfo::TYPE_LONG_LONG, LLONG_SIZE); +CTypePrimitive CTYPE_UNSIGNED_LONG_LONG ("unsigned long long int", CTypeInfo::TYPE_UNSIGNED_LONG_LONG, ULLONG_SIZE); +CTypePrimitive CTYPE_INT128 ("__int128", CTypeInfo::TYPE_INT128, INT128_SIZE); +CTypePrimitive CTYPE_UNSIGNED_INT128 ("unsigned __int128", CTypeInfo::TYPE_UNSIGNED_INT128, UINT128_SIZE); +CTypePrimitive CTYPE_FLOAT ("float", CTypeInfo::TYPE_FLOAT, FLOAT_SIZE); +CTypePrimitive CTYPE_DOUBLE ("double", CTypeInfo::TYPE_DOUBLE, DOUBLE_SIZE); +CTypePrimitive CTYPE_LONG_DOUBLE ("long double", CTypeInfo::TYPE_LONG_DOUBLE, LDOUBLE_SIZE); +CTypePrimitive CTYPE_VOID ("void", CTypeInfo::TYPE_VOID, 0); +CTypePrimitive CTYPE_UNKNOWN_T ("__unknown_t", CTypeInfo::TYPE_UNKNOWN_T, 0); +CTypePrimitive CTYPE_UNDEFINED ("", CTypeInfo::TYPE_UNDEFINED, 0); +CTypePrimitive CTYPE_ELLIPSIS ("...", CTypeInfo::TYPE_ELLIPSIS, 0); + +// Internal representation of size_t and ptrdiff_t types //////// + +CTypeInfo *CTypeInfo::CTYPE_SIZE_T = &CTYPE_UNSIGNED_INT; // default type +CTypeInfo *CTypeInfo::CTYPE_PTRDIFF_T = &CTYPE_INT; // default type + +bool CTypeInfo::equals(const CTypeInfo &type, bool matchTemplateParams, bool noDependentFctParams) const { + if (! (_Id == type._Id)) { + return false; + } else if (TypeEmpty () || TypePrimitive ()) { + return true; + } else if (TypeTemplateParam ()) { + CTemplateParamInfo *p1 = TypeTemplateParam ()->TemplateParamInfo (); + CTemplateParamInfo *p2 = type.TypeTemplateParam ()->TemplateParamInfo (); + return p1 && p2 && (matchTemplateParams ? p1->match(*p2) : *p1 == *p2); + } else if (TypeClass ()) { + CClassInfo *c1 = TypeClass ()->ClassInfo (); + CClassInfo *c2 = type.TypeClass ()->ClassInfo (); + if (! c1 || ! c2) { + return false; + } else if (c1->isTemplate () && c2->isTemplate ()) { + CTemplateInfo* t1 = c1->TemplateInfo (); + CTemplateInfo* t2 = c2->TemplateInfo (); + if (t1 && t2 && ! CTemplateInfo::equalParameters (t1, t2)) + return false; + } else if (isTemplateInstance () && type.isTemplateInstance ()) { + CTemplateInstance *t1 = c1->ClassInstance ()->TemplateInstance (); + CTemplateInstance *t2 = c2->ClassInstance ()->TemplateInstance (); + if (t1 && t2 && t1->isPseudoInstance () && t2->isPseudoInstance ()) { + // compare template arguments + if (! CTemplateInfo::equalArguments (t1, t2, matchTemplateParams)) + return false; + c1 = t1->Template ()->ObjectInfo ()->ClassInfo (); + c2 = t2->Template ()->ObjectInfo ()->ClassInfo (); + } + } + return (*c1 == *c2); + } else if (TypeUnion ()) { + CUnionInfo *u1 = TypeUnion ()->UnionInfo (); + CUnionInfo *u2 = type.TypeUnion ()->UnionInfo (); + return (u1 && u2 && *u1 == *u2); + } else if (TypeEnum ()) { + CEnumInfo *e1 = TypeEnum ()->EnumInfo (); + CEnumInfo *e2 = type.TypeEnum ()->EnumInfo (); + return (e1 && e2 && *e1 == *e2); + } else if (TypeArray ()) { + if (! TypeVarArray () && ! TypeArray ()->DepDim () && ! type.TypeArray ()->DepDim ()) + if (TypeArray ()->hasDimension () && type.TypeArray ()->hasDimension () && Dimension () != type.Dimension ()) + return false; + } else if (TypeQualified ()) { + if (TypeQualified ()->isConst () != type.TypeQualified ()->isConst ()) + return false; + if (TypeQualified ()->isVolatile () != type.TypeQualified ()->isVolatile ()) + return false; + } else if (TypeMemberPointer ()) { + if (TypeMemberPointer ()->Record () && + *TypeMemberPointer ()->Record () != *type.TypeMemberPointer ()->Record ()) + return false; + } else if (TypeFunction ()) { + CTypeList *atl = TypeFunction ()->ArgTypes (); + CTypeList *tatl = type.TypeFunction ()->ArgTypes (); + if (atl && tatl && atl->Entries () != tatl->Entries ()) + return false; + for (unsigned i = 0; i < atl->Entries (); i++) + if (! atl->Entry (i)->equals(*tatl->Entry (i), matchTemplateParams, noDependentFctParams) || + (noDependentFctParams && (atl->Entry (i)->isDependent () || tatl->Entry (i)->isDependent ()))) + return false; + if ((TypeFunction ()->isConst () != type.TypeFunction ()->isConst ()) || + (TypeFunction ()->isVolatile () != type.TypeFunction ()->isVolatile ())) + return false; + if (TypeFunction ()->Record () && type.TypeFunction ()->Record ()) + if (*TypeFunction ()->Record () != *type.TypeFunction ()->Record ()) + return false; + CFunctionInfo* f1 = TypeFunction ()->FunctionInfo (); + CFunctionInfo* f2 = type.TypeFunction ()->FunctionInfo (); + if (f1 && f2 && f1->isTemplate () && f2->isTemplate ()) { + CTemplateInfo* t1 = f1->TemplateInfo (); + CTemplateInfo* t2 = f2->TemplateInfo (); + if (t1 && t2 && ! CTemplateInfo::equalParameters (t1, t2)) + return false; + } + } + return BaseType ()->equals(*type.BaseType (), matchTemplateParams, noDependentFctParams); +} + +bool CTypeInfo::equalsUnqualified (const CTypeInfo &type) const { + CTypeInfo* t1 = UnqualType (); + CTypeInfo* t2 = type.UnqualType (); + CTypeArray* a1 = t1->TypeArray (); + CTypeArray* a2 = t2->TypeArray (); + while (a1 && a2) { + if (! a1->DepDim () && ! a2->DepDim () && a1->hasDimension () && a2->hasDimension () && a1->Dimension () != a2->Dimension ()) + return false; + t1 = a1->BaseType ()->VirtualType (); + t2 = a2->BaseType ()->VirtualType (); + a1 = t1->TypeArray (); + a2 = t2->TypeArray (); + } + return (*t1 == *t2); +} + +CTypeInfo *CTypeInfo::TypedefInfo (CObjectInfo *info) { + // duplicate primitive types only + if (TypePrimitive () && ! isTypedef ()) { + CTypeInfo *type = new CTypePrimitive (TypePrimitive ()->TypeName (), Id (), TypePrimitive ()->Size ()); + type->_TypedefInfo = info; + return type; + } + _TypedefInfo = info; + return (CTypeInfo*)this; +} + +CTypeFunction *CTypeInfo::PtrToFct () const { + if (TypeFunction ()) return TypeFunction (); + if (TypeEmpty ()) return (CTypeFunction*)0; + return BaseType ()->PtrToFct (); +} + +CTypeArray *CTypeInfo::PtrToArray () const { + if (TypeArray ()) return TypeArray (); + if (TypeEmpty ()) return (CTypeArray*)0; + return BaseType ()->PtrToArray (); +} + +bool CTypeInfo::isArithmetic () const { + CTypeInfo *base = VirtualType (); + if (base->_Id < TYPE_VOID || base->TypeEnum ()) + return true; + if (base->TypeBitField ()) + return BaseType ()->isArithmetic (); + return false; +} + +bool CTypeInfo::isTemplateInstanceArg () const { + bool result = false; + if (_TypedefInfo) { + CScopeInfo* scope = _TypedefInfo->Scope (); + if (strcmp (_TypedefInfo->Name (), "__puma_redirect") == 0) + scope = scope->Parent (); + if (scope->isNamespace () && + ((scope->isAnonymous () && strstr (scope->Name (), "<")) || + strcmp (scope->Name (), "__puma_dargs") == 0)) + result = true; + } + return result; +} + +void CTypeInfo::TypeText (char state, std::ostream &out, const char *t) const { + // check for prefix, save and clear the flag + bool prefix = state & PRINT_PRE; + state = state & ~PRINT_PRE; + + if (isTypedef () && ! isTemplateInstanceArg () && + ((state & PRINT_TDN) || + (TypeEnum () && EnumInfo ()->isAnonymous ()) || + (TypeRecord () && Record ()->isAnonymous ()))) { + // print TYPEDEFS + printScope (state, out, TypedefInfo ()); + out << TypedefInfo ()->Name (); + } else if (TypeQualified ()) { + // print QUALIFIED TYPES + std::ostringstream qualifiers; + if (TypeQualified ()->isConst ()) { + qualifiers << "const"; + if (TypeQualified ()->isVolatile ()) + qualifiers << " "; + } + if (TypeQualified ()->isVolatile ()) + qualifiers << "volatile"; + if (BaseType ()->TypePointer () || BaseType ()->TypeAddress ()) { + if (t) qualifiers << " " << t; + BaseType ()->TypeText (state, out, qualifiers.str ().c_str ()); + } + else { + out << qualifiers.str ().c_str () << " "; + BaseType ()->TypeText (state, out, t); + } + return; + } else if (TypePointer () || TypeAddress ()) { + // print POINTERS or REFERENCES + std::ostringstream inner; + if (TypeMemberPointer ()) { + if (TypeMemberPointer ()->Record () || TypeMemberPointer ()->TemplateParam ()) { + CTypeFunction *fctptr = BaseType ()->TypeFunction (); + if (!fctptr || !fctptr->Record () || !fctptr->FunctionInfo () || + fctptr->FunctionInfo ()->isStaticMethod ()) { + if (TypeMemberPointer ()->Record ()) { + printScope (state, inner, TypeMemberPointer ()->Record ()); + printName (state, inner, TypeMemberPointer ()->Record ()); + } else + printName (state, inner, TypeMemberPointer ()->TemplateParam ()); + inner << "::*"; + } else + inner << "*"; + } else + inner << " ::*"; + } else if (TypePointer ()) inner << "*"; + else if (TypeAddress ()) inner << "&"; + if (t) inner << t; + BaseType ()->TypeText (state | PRINT_PRE, out, inner.str ().c_str ()); + return; + } else if (TypeFunction ()) { + // print FUNCTION TYPES + // first put "[scope::][name]([arg-types])[ const][ volatile]" in a buffer + CTypeFunction *this_type = TypeFunction (); + std::ostringstream name_and_args; + if (prefix) name_and_args << "("; + if (this_type->Record () && this_type->FunctionInfo () && + !this_type->FunctionInfo ()->isStaticMethod ()) { + printScope (state, name_and_args, this_type->Record ()); + printName (state, name_and_args, this_type->Record ()); + name_and_args << "::"; + } + if (t) name_and_args << t; + if (prefix) name_and_args << ")"; + name_and_args << "("; + CTypeList *argtypes = this_type->ArgTypes (); + for (unsigned i = 0; i < argtypes->Entries (); i++) { + if (i > 0) name_and_args << ","; + CTypeInfo *argtype = argtypes->Entry (i); + argtype->TypeText ((state & PRINT_ELA) ? (state & ~PRINT_INE) : state, + name_and_args); + } + name_and_args << ")"; + if (this_type->isConst ()) + name_and_args << " const"; + if (this_type->isVolatile ()) + name_and_args << " volatile"; + + // now write the generated embedded into its base type + if (BaseType ()->is_undefined ()) + out << name_and_args.str ().c_str (); + else + BaseType ()->TypeText (state, out, name_and_args.str ().c_str ()); + return; + } else if (TypeBitField ()) { + BaseType ()->TypeText (state, out); + //out << " : " << TypeBitField ()->Dimension (); // ??? + } else if (TypeArray ()) { + // print ARRAY TYPES + std::ostringstream name_and_dim; + if (prefix) name_and_dim << "("; + if (t) name_and_dim << t; + if (prefix) name_and_dim << ")"; + name_and_dim << "["; + if (TypeVarArray ()) + name_and_dim << "*"; + else if (Dimension ()) + name_and_dim << Dimension (); + name_and_dim << "]"; + BaseType ()->TypeText (state, out, name_and_dim.str ().c_str ()); + return; + } else if (TypeClass ()) { + // print CLASSES + if ((state & PRINT_ELA) && !(state & PRINT_INE)) { + CRecord* record = TypeClass ()->Record (); + if (record && record->ClassInfo ()->isStruct ()) { + out << "struct "; + } else { + out << "class "; + } + } + printScope (state, out, TypeClass ()->Record ()); + printName (state, out, TypeClass ()->Record ()); + } else if (TypeUnion ()) { + // print UNIONS + if ((state & PRINT_ELA) && !(state & PRINT_INE)) { + out << "union "; + } + printScope (state, out, TypeUnion ()->Record ()); + printName (state, out, TypeUnion ()->Record ()); + } else if (TypeEnum ()) { + // print ENUMS + if ((state & PRINT_ELA) && !(state & PRINT_INE)) { + out << "enum "; + } + printScope (state, out, TypeEnum ()->EnumInfo ()); + printName (state, out, TypeEnum ()->EnumInfo ()); + } else if (TypeTemplateParam ()) { + // print TEMPLATE PARAMS + printName (state, out, TypeTemplateParam ()->TemplateParamInfo ()); + } else if (TypePrimitive ()) { + // print PRIMITIVE TYPES + out << TypePrimitive ()->TypeName (); + } else + return; + + if (t) out << " " << t; +} + +void CTypeInfo::printScope (char state, std::ostream &out, CObjectInfo *info) const { + if (info->TemplateInstance ()) { + CTemplateInfo *tpl = info->TemplateInstance ()->Template (); + if (tpl && tpl->ObjectInfo ()) { + info = tpl->ObjectInfo (); + } + } + CScopeInfo *scope = info->QualifiedScope (); + if (! scope) scope = info->AssignedScope (); + if (! scope) scope = info->Scope (); + while (scope && scope->TemplateInfo ()) { + scope = scope->Parent (); + } + if (scope) { + if ((state & PRINT_ABS) && scope->GlobalScope ()) { + out << "::"; + } else if (! scope->isAnonymous () || + ((state & PRINT_UNN) && strcmp(scope->Name(), "") == 0)) { + if (scope->Record ()) { + // print the scope name, but don't use elaborated type specifier + scope->TypeInfo ()->TypeText (state | PRINT_INE, out); + out << "::"; + } else if (scope->NamespaceInfo () && ! scope->GlobalScope ()) { + if (state & PRINT_ABS) + out << "::"; + out << scope->NamespaceInfo ()->QualName (false, false, + state & PRINT_UNN) << "::"; + } + } + } +} + +void CTypeInfo::printName (char state, std::ostream &out, CObjectInfo *info) const { + CTemplateInstance *instance; + DeducedArgument *arg; + + if (! info->Name ()/* || info->isAnonymous ()*/) + out << ""; + else + out << info->Name (); + + instance = info->TemplateInstance (); + if (! instance) + return; + + out << "<"; + std::ostringstream os; + for (unsigned i = 0; i < instance->InstantiationArgs (); i++) { + arg = instance->InstantiationArg (i); + // do not list default arguments + if (arg->isDefaultArg ()) + break; + if (i > 0) os << ","; + arg->print (os, state & PRINT_ABS); + } + std::string args = os.str(); + // avoid misinterpretation of "<::" as digraph "<:" by adding whitespace + if (args.size () && args.at (0) == ':') + out << " "; + out << args; + if (args.size() && args.at(args.size()-1) == '>') + out << " "; + out << ">"; +} + +CTypeInfo *CTypeInfo::Duplicate (const CTypeInfo *type) { + if (! type) return &CTYPE_EMPTY; + + CTypeInfo *copy = (CTypeInfo*)0; + if (type->TypeEmpty ()) { + copy = &CTYPE_EMPTY; + } else if (type->TypePrimitive ()) { + // copy primitive type only if it contains typedef information + if (type->isTypedef ()) + copy = new CTypePrimitive (type->TypePrimitive ()->TypeName (), type->Id (), type->TypePrimitive ()->Size ()); + else + copy = (CTypeInfo*)type; + } else if (type->TypeTemplateParam ()) { + copy = new CTypeTemplateParam ( + type->TypeTemplateParam ()->TemplateParamInfo ()); + } else if (type->TypeEnum ()) { + copy = new CTypeEnum (type->EnumInfo ()); + } else if (type->TypeRecord ()) { + if (type->TypeUnion ()) + copy = new CTypeUnion (type->UnionInfo ()); + else // TypeClass + copy = new CTypeClass (type->ClassInfo ()); + } + + if (copy) { + if (type->isTypedef ()) + copy->_TypedefInfo = type->_TypedefInfo; + return copy; + } + + CTypeInfo *base = Duplicate (type->BaseType ()); + if (type->TypeMemberPointer ()) { + if (type->TypeMemberPointer ()->TemplateParam ()) + copy = new CTypeMemberPointer (base, + type->TypeMemberPointer ()->TemplateParam ()); + else + copy = new CTypeMemberPointer (base, + type->TypeMemberPointer ()->Record ()); + } else if (type->TypeBitField ()) { + copy = new CTypeBitField (base); + copy->TypeBitField ()->Dimension (type->Dimension ()); + } else if (type->TypeAddress ()) { + copy = new CTypeAddress (base); + } else if (type->TypeFunction ()) { + CTypeList *args = new CTypeList; + args->ArgumentList (type->ArgTypes ()->ArgumentList ()); + for (unsigned i = 0; i < type->ArgTypes ()->Entries (); i++) + args->AddEntry (Duplicate (type->ArgTypes ()->Entry (i))); + copy = new CTypeFunction (base, args, + type->TypeFunction ()->hasPrototype ()); + copy->TypeFunction ()->FunctionInfo (type->FunctionInfo ()); + copy->TypeFunction ()->isConst (type->TypeFunction ()->isConst ()); + copy->TypeFunction ()->isVolatile (type->TypeFunction ()->isVolatile ()); + copy->TypeFunction ()->isRestrict (type->TypeFunction ()->isRestrict ()); + } else if (type->TypePointer ()) { + copy = new CTypePointer (base); + } else if (type->TypeVarArray ()) { + if (type->TypeVarArray ()->Qualifiers ()) + copy = Duplicate (type->TypeVarArray ()->Qualifiers ()); + else + copy = 0; + copy = new CTypeVarArray (base, (CTypeQualified*)copy); + } else if (type->TypeArray ()) { + if (type->TypeArray ()->Qualifiers ()) + copy = Duplicate (type->TypeArray ()->Qualifiers ()); + else + copy = 0; + copy = new CTypeArray (base, (CTypeQualified*)copy); + copy->TypeArray ()->Dimension (type->Dimension ()); + copy->TypeArray ()->DepDim (type->TypeArray ()->DepDim ()); + copy->TypeArray ()->hasDimension (type->TypeArray ()->hasDimension ()); + } else if (type->TypeQualified ()) { + copy = new CTypeQualified (base, type->isConst (), type->isVolatile (), + type->isRestrict ()); + } else + Destroy (base); + + if (type->isTypedef ()) + copy->_TypedefInfo = type->_TypedefInfo; + return copy; +} + +void CTypeInfo::Destroy (CTypeInfo *type) { + if (! type || type->TypeEmpty ()) return; + if (type->TypePrimitive ()) { + if (type->isTypedef ()) + delete type->TypePrimitive (); + return; + } + if (type->TypeClass ()) delete type->TypeClass (); + else if (type->TypeTemplateParam ()) delete type->TypeTemplateParam (); + else if (type->TypeEnum ()) delete type->TypeEnum (); + else if (type->TypeUnion ()) delete type->TypeUnion (); + else { + if (! type->BaseType ()->TypeEmpty ()) + Destroy (type->BaseType ()); + if (type->TypeQualified ()) delete type->TypeQualified (); + else if (type->TypePointer ()) delete type->TypePointer (); + else if (type->TypeMemberPointer ()) delete type->TypeMemberPointer (); + else if (type->TypeAddress ()) delete type->TypeAddress (); + else if (type->TypeBitField ()) delete type->TypeBitField (); + else if (type->TypeArray ()) { + if (type->TypeArray ()->Qualifiers ()) + Destroy (type->TypeArray ()->Qualifiers ()); + if (type->TypeVarArray ()) delete type->TypeVarArray (); + else delete type->TypeArray (); + } else if (type->TypeFunction ()) { + CTypeList *args = type->TypeFunction ()->ArgTypes (); + if (args) { + for (unsigned i = 0; i < args->Entries (); i++) + Destroy (args->Entry (i)); + delete args; + } + delete type->TypeFunction (); + } + } +} + +// rank C++ arithmetic types +unsigned CTypeInfo::rank () const { + switch (Id ()) { + case TYPE_BOOL : return 1; + case TYPE_C_BOOL : return 1; + case TYPE_CHAR : return 2; + case TYPE_SIGNED_CHAR : return 2; + case TYPE_UNSIGNED_CHAR : return 3; + case TYPE_SHORT : return 4; + case TYPE_UNSIGNED_SHORT : return 5; + case TYPE_WCHAR_T : return 6; + case TYPE_ENUM : return 7; + case TYPE_INT : return 8; + case TYPE_UNSIGNED_INT : return 9; + case TYPE_LONG : return 10; + case TYPE_UNSIGNED_LONG : return 11; + case TYPE_LONG_LONG : return 12; + case TYPE_UNSIGNED_LONG_LONG : return 13; + case TYPE_INT128 : return 14; + case TYPE_UNSIGNED_INT128 : return 15; + case TYPE_FLOAT : return 16; + case TYPE_DOUBLE : return 17; + case TYPE_LONG_DOUBLE : return 18; + default: break; + } + return 0; +} + +// arithmetic conversion rank (C only) +unsigned CTypeInfo::conv_rank () const { + if (is_bool ()) return 1; + else if (is_char ()) return 2; + else if (is_signed_char ()) return 2; + else if (is_unsigned_char ()) return 2; + else if (is_unsigned_short ()) return 3; + else if (is_short ()) return 4; + else if (is_unsigned_int ()) return 5; + else if (is_wchar_t ()) return 6; + else if (is_int ()) return 6; + else if (is_unsigned_long ()) return 7; + else if (is_long ()) return 8; + else if (is_unsigned_long_long ()) return 9; + else if (is_long_long ()) return 10; + else if (is_unsigned_int128 ()) return 11; + else if (is_int128 ()) return 12; + else if (is_float ()) return 13; + else if (is_double ()) return 14; + else if (is_long_double ()) return 15; + return 0; +} + +bool CTypeInfo::operator >(const CTypeInfo &type) const { + CTypeInfo *t1 = VirtualType (); + CTypeInfo *t2 = type.VirtualType (); + if (t1 == t2) return false; + + if (t1->is_long_double ()) return true; + else if (t2->is_long_double ()) return false; + else if (t1->is_double ()) return true; + else if (t2->is_double ()) return false; + else if (t1->is_float ()) return true; + else if (t2->is_float ()) return false; + + bool t1_is_signed = t1->is_signed (); + bool t2_is_signed = t2->is_signed (); + int t1_rank = t1->conv_rank (); + int t2_rank = t2->conv_rank (); + if (t1_is_signed == t2_is_signed) + return t1_rank >= t2_rank; + else if (t1_is_signed && t1_rank < t2_rank) + return false; + else if (t2_is_signed && t2_rank < t1_rank) + return true; + else if (t1_is_signed && t1_rank >= (t2_rank+2)) + return true; + else if (t2_is_signed && t2_rank >= (t1_rank+2)) + return false; + else + return ! t1_is_signed; +} + +bool CTypeInfo::operator <(const CTypeInfo &type) const { + CTypeInfo *t1 = VirtualType (); + CTypeInfo *t2 = type.VirtualType (); + return t1 != t2 && *t1 <= *t2; +} + +// signed integer type? +bool CTypeInfo::is_signed () const { + if (is_char () || + is_signed_char () || + is_short () || + is_int () || + is_wchar_t () || + is_long () || + is_long_long () || + is_int128 ()) + return true; + return false; +} + +// unsigned integer type? +bool CTypeInfo::is_unsigned () const { + if (is_bool () || // ??? + is_unsigned_char () || + is_unsigned_short () || + is_unsigned_int () || + is_unsigned_long () || + is_unsigned_long_long () || + is_unsigned_int128 ()) + return true; + return false; +} + +// complete type (at this source position)? +bool CTypeInfo::isComplete (unsigned long pos) const { + if (isUndefined () || isVoid () || + (isArray () && ! isVarArray () && ! VirtualType ()->TypeArray ()->hasDimension ()) || + (isRecord () && ! VirtualType ()->TypeRecord ()->isComplete (pos)) || + (isEnum () && ! VirtualType ()->TypeEnum ()->isComplete (pos))) + return false; + return true; +} + +bool CTypeEnum::isComplete (unsigned long pos) const { + return _Enum && _Enum->DefObject ()->EnumInfo ()->isComplete (pos); +} + +bool CTypeRecord::isComplete (unsigned long pos) const { + return _Record && _Record->DefObject ()->Record ()->isComplete (pos); +} + +long int CTypeInfo::Size () const { + if (TypeQualified () || TypeAddress () || TypeBitField ()) + return BaseType ()->Size (); + else if (TypeArray ()) + return BaseType ()->Size () * Dimension (); + else if (TypeMemberPointer ()) + return MEMB_PTR_SIZE; + else if (TypePointer ()) + return PTR_SIZE; + else if (TypeEnum ()) + return ENUM_SIZE; + else if (TypeClass () || TypeUnion ()) + return TypeRecord ()->Size (); + else if (TypePrimitive ()) + return TypePrimitive ()->Size (); + return 0; +} + +long int CTypeRecord::Size () { + CObjectInfo *info; + CStructure *cinfo; + long int align, s; + CTypeInfo *type; + + if (_Size) + return _Size; + + _Size = 0; + _Align = 32; + + cinfo = Record ()->DefObject ()->Record (); + if (cinfo) { + for (unsigned i = cinfo->Attributes (); i > 0; i--) { + info = cinfo->Attribute (i-1); + if (info->EnumeratorInfo () || + info->Storage () == CStorage::CLASS_STATIC || + info->Storage () == CStorage::CLASS_THREAD) + continue; + type = info->TypeInfo (); + align = type->Align (); + if (! TypeUnion () && align != 0 && (_Size % align) != 0) + _Size = _Size + align - (_Size % align); + if (align > _Align) + _Align = align; + s = type->Size (); + if (TypeUnion ()) + _Size = s > _Size ? s : _Size; + else + _Size += s; + } + if (cinfo->ClassInfo ()) + for (unsigned i = 0; i < cinfo->ClassInfo ()->BaseClasses (); i++) + _Size += (cinfo->ClassInfo ()->BaseClass (i)-> + Class ()->TypeInfo ()->Size ()); + } + + if (! _Size) + _Size = 8; + + return _Size; +} + +bool CTypeInfo::isTemplate () const { + return TypeRecord () && TypeRecord ()->Record () ? + TypeRecord ()->Record ()->isTemplate () : + TypeFunction () && TypeFunction ()->FunctionInfo () ? + TypeFunction ()->FunctionInfo ()->isTemplate () : false; +} + +bool CTypeInfo::isTemplateInstance () const { + return TypeRecord () && TypeRecord ()->Record () ? + TypeRecord ()->Record ()->isTemplateInstance () : + TypeFunction () && TypeFunction ()->FunctionInfo () ? + TypeFunction ()->FunctionInfo ()->isTemplateInstance () : false; +} + +CRecord *CTypeFunction::Record () const { + return _Function ? _Function->Record () : (CRecord*)0; +} + +CClassInfo *CTypeInfo::ClassInfo () const { + return Record () ? Record ()->DefObject ()->ClassInfo () : (CClassInfo*)0; +} + +CUnionInfo *CTypeInfo::UnionInfo () const { + return Record () ? Record ()->DefObject ()->UnionInfo () : (CUnionInfo*)0; +} + +CClassInfo *CTypeClass::ClassInfo () const { + return Record () ? (CClassInfo*)Record ()->DefObject () : (CClassInfo*)0; +} + +CUnionInfo *CTypeUnion::UnionInfo () const { + return Record () ? (CUnionInfo*)Record ()->DefObject () : (CUnionInfo*)0; +} + + +bool CTypeTemplateParam::isType () const { + return TemplateParamInfo () && TemplateParamInfo ()->isTypeParam (); +} + +bool CTypeInfo::isDependent (bool consider_unknown_t, bool is_named_type) const { + if (consider_unknown_t && is_unknown_t ()) + return true; + if (TypeTemplateParam ()) + return true; + if (TypeFunction () && TypeFunction ()->ArgTypes ()->isDependent ()) + return true; + if (TypeMemberPointer () && TypeMemberPointer ()->TemplateParam ()) + return true; + if (isTemplateInstance ()) { + if ((TypeRecord () && + ! TypeRecord ()->Record ()->TemplateInstance ()->canInstantiate ()) || + (TypeFunction () && + ! TypeFunction ()->FunctionInfo ()->TemplateInstance ()->canInstantiate ())) + return true; + } + if (TypeClass () && TypeClass ()->ClassInfo ()) { + CClassInfo* ci = TypeClass ()->ClassInfo (); + if (! ci->isTemplate () && ci->hasDepBaseClass ()) + return true; + if (! is_named_type && ci->isTemplate () && ci->hasDepBaseClass ()) + return true; + if (ci->isTemplate ()) + return true; + } + return BaseType () && this != BaseType () && + BaseType ()->isDependent (consider_unknown_t, is_named_type); +} + +bool CTypeList::isDependent () const { + for (unsigned i = Entries (); i > 0; i--) + if (Entry (i-1) && Entry (i-1)->isDependent ()) + return true; + return false; +} + +static void MangleTemplateArguments (CTemplateInstance *instance, + std::ostream &out) { + DeducedArgument *arg; + + out << "I"; + for (unsigned i = 0; i < instance->InstantiationArgs (); i++) { + arg = instance->InstantiationArg (i); + if (arg->isDefaultArg ()) + continue; + + if (arg->Type ()) { + arg->Type ()->Mangled (out); + } else if (arg->Value ()) { // some types are missing here, but CConstant.. + if (arg->Value ()->isSigned ()) { + CTYPE_INT.Mangled (out); + if (arg->Value ()->convert_to_int () < 0) + out << "n"; // a negative value is prececed by 'n' + out << arg->Value ()->convert_to_int (); + } + else if (arg->Value ()->isUnsigned ()) { + CTYPE_UNSIGNED_INT.Mangled (out); + out << arg->Value ()->convert_to_uint (); + } + else if (arg->Value ()->isFloat ()) { + CTYPE_FLOAT.Mangled (out); + long double val = arg->Value ()->convert_to_float (); + // does not 100% conform with the standard (byte order) + out.width (2); + out.fill ('0'); + out << std::hex; + for (int p = 0; p < (int)sizeof(long double); p++) + out << (unsigned int) *(((unsigned char*)&val) + p); + out.width (0); + out << std::dec; + } + } + } + out << "E"; +} + +static void MangleScopedName (const CObjectInfo *info, std::ostream &out, bool first = true) { + CScopeInfo *scope; + if (! info || ! info->Name ()) + return; + + if (! info->Record () && ! info->NamespaceInfo () && + ! info->FunctionInfo () && ! info->EnumInfo () && + ! info->TypedefInfo ()) + out << "9"; + else { + scope = info->Scope (); + CTemplateInstance *instance = info->TemplateInstance (); + // if this is a template instance, there is always an exclosing scope + if (instance) + scope = scope->Scope (); + + if (scope && ! scope->GlobalScope ()) { + if (first) + out << "N"; + + if (scope->Record () || scope->NamespaceInfo ()) + MangleScopedName (scope, out, false); + + + if (first) + out << "E"; + } + + if (strcmp (info->Name (), "") == 0) + out << "12_GLOBAL__N_1"; + else + out << strlen (info->Name ()) << info->Name (); + + // if this is a template instance, mangle the argument types + if (instance) + MangleTemplateArguments (instance, out); + } +} + +// C++ V3 ABI mangling: see http://www.codesourcery.com/cxx-abi/abi.html#mangling for details +void CTypeInfo::Mangled (std::ostream &out) const { + + // g++ uses a typedef name for anonymous structs, enums, etc. if one exists + if (isTypedef ()) { + CObjectInfo *obj = Record (); + if (! obj) obj = EnumInfo (); + if (obj && obj->isAnonymous ()) { + MangleScopedName (TypedefInfo (), out); + return; + } + } + + if (TypeAddress ()) { + out << "R"; + BaseType ()->Mangled (out); + } else if (TypeQualified ()) { + if (TypeQualified ()->isConst ()) out << "K"; + if (TypeQualified ()->isVolatile ()) out << "V"; + if (TypeQualified ()->isRestrict ()) out << "r"; + BaseType ()->Mangled (out); + } else if (TypeRecord ()) { + MangleScopedName (TypeRecord ()->Record (), out); + } else if (TypeEnum ()) { + MangleScopedName (TypeEnum ()->EnumInfo (), out); + } else if (TypeArray ()) { + out << "A"; + if (! TypeVarArray () && TypeArray ()->Dimension () > 0) + out << TypeArray ()->Dimension (); + out << "_"; + BaseType ()->Mangled (out); + } else if (TypePointer ()) { + if (TypeMemberPointer () && TypeMemberPointer ()->Record ()) { + out << "M"; + MangleScopedName (TypeMemberPointer ()->Record (), out); + } else + out << "P"; + BaseType ()->Mangled (out); + } else if (TypeFunction ()) { + out << "F"; + MangleScopedName (TypeFunction ()->Record (), out); + TypeFunction ()->BaseType ()->Mangled (out); + if (TypeFunction ()->ArgTypes () && TypeFunction ()->ArgTypes ()->Entries ()) { + for (unsigned i = 0; i < TypeFunction ()->ArgTypes ()->Entries (); i++) + TypeFunction ()->ArgTypes ()->Entry (i)->Mangled (out); + } else + out << "v"; + out << "E"; + } else if (TypeBitField ()) { + // ??? + BaseType ()->Mangled (out); + } else if (TypePrimitive ()) { + switch (_Id) { + case TYPE_BOOL: out << "b"; break; + case TYPE_C_BOOL: out << "b"; break; + case TYPE_CHAR: out << "c"; break; + case TYPE_WCHAR_T: out << "w"; break; + case TYPE_SHORT: out << "s"; break; + case TYPE_INT: out << "i"; break; + case TYPE_LONG: out << "l"; break; + case TYPE_LONG_LONG: out << "x"; break; // __int64 + case TYPE_INT128: out << "n"; break; // __int128 + case TYPE_SIGNED_CHAR: out << "a"; break; + case TYPE_UNSIGNED_CHAR: out << "h"; break; + case TYPE_UNSIGNED_SHORT: out << "t"; break; + case TYPE_UNSIGNED_INT: out << "j"; break; + case TYPE_UNSIGNED_LONG: out << "m"; break; + case TYPE_UNSIGNED_LONG_LONG: out << "y"; break; // __int64 + case TYPE_UNSIGNED_INT128: out << "o"; break; // __int128 + case TYPE_FLOAT: out << "f"; break; + case TYPE_DOUBLE: out << "d"; break; + //case TYPE_FLOAT128: out << "g"; break; + case TYPE_LONG_DOUBLE: out << "e"; break; + case TYPE_VOID: out << "v"; break; + case TYPE_ELLIPSIS: out << "z"; break; + case TYPE_UNDEFINED: + break; + default: // vendor extended type := u + out << "u" << strlen (TypePrimitive ()->TypeName ()) + << TypePrimitive ()->TypeName (); + } + } +} + +CRecord *CTypeMemberPointer::Record () const { + return _Class ? _Class->Record () : (CRecord*)0; +} + +CTemplateParamInfo *CTypeMemberPointer::TemplateParam () const { + return _Class ? _Class->TemplateParamInfo () : (CTemplateParamInfo*)0; +} + +CTypeInfo *CTypeEnum::UnderlyingType () const { + return _Enum ? _Enum->UnderlyingType() : &CTYPE_INT; +} + +bool CTypeClass::instantiate (CStructure *scope) { + // If this is the type of a pseudo class instance, + // create a real instance of the corresponding template. + // Return true if instantiation succeeded. + CClassInfo* ci = ClassInfo (); + if (ci) { + CTemplateInstance* ti = ci->TemplateInstance (); + if (ti && ! ti->isInstantiated () && ti->canInstantiate ()) { + // instantiate + return ti->instantiate (scope); + } + } + return true; +} + +/** Check if this is a plain old data (POD) type. */ +bool CTypeInfo::isPOD () const { + // ��3.9p10 + // Arithmetic types (3.9.1), enumeration types, pointer types, and pointer + // to member types (3.9.2), and cv-qualified versions of these types (3.9.3) are + // collectively called scalar types. Scalar types, POD-struct types, POD-union + // types (clause 9), arrays of such types and cv-qualified versions of these + // types (3.9.3) are collectively called POD types. + if (isScalar ()) + return true; + + // ��9p4 + // A POD-struct is an aggregate class that has no non-static data members of + // type pointer to member, non-POD-struct, non-POD-union, or array of such types, + // or reference, and has no user-defined copy assignment operator and no user-defined + // destructor. Similarly, a POD-union is an aggregate union that has no non-static + // data members of type pointer to member, non-POD-struct, non-POD-union, or array + // of such types, or reference, and has no user-defined copy assignment operator + // and no user-defined destructor. A POD class is a class that is either a POD-struct + // or a POD-union. + // + // $8.5.1p1 + // An aggregate is an array or a class (clause 9) with no user-declared constructors + // (12.1), no private or protected non-static data members (clause 11), no base + // classes (clause 10), and no virtual functions (10.3). + CRecord* c = isClassOrUnion () ? VirtualType ()->TypeRecord ()->Record () : 0; + + // class or union without base classes + if (c && (! c->ClassInfo () || ! c->ClassInfo ()->BaseClasses ())) { + + // check data members + unsigned i, num = c->Attributes (); + for (i = 0; i < num; i++) { + CAttributeInfo* member = c->Attribute (i); + // private or protected data member + if (member->Protection () == CProtection::PROT_PRIVATE || + member->Protection () == CProtection::PROT_PROTECTED) + break; + // static members don't matter + if (! member->isStatic ()) { + CTypeInfo* type = member->TypeInfo (); + // reference type + if (type->isAddress ()) + break; + // get underlying type of array + while (type->isArray ()) + type = type->VirtualType ()->BaseType (); + // pointer to member + if (type->isMemberPointer ()) + break; + // non-POD class + if (type->isClassOrUnion () && ! type->isPOD ()) + break; + } + } + // non-POD member found + if (i != num) + return false; + + // check member functions + num = c->Functions (); + for (i = 0; i < num; i++) { + CFunctionInfo* member = c->Function (i); + // virtual function + if (member->isVirtual ()) + break; + // user-defined + if (! member->isBuiltin ()) { + // user-defined constructor or destructor + if (member->isConstructor () || member->isDestructor ()) + break; + // copy assignment operator + if (member->isCopyAssignOperator ()) + break; + } + } + + // POD class + if (i == num) + return true; + } + + return false; +} + +/** Check if this is a trivial type: + * (1) a scalar type + * (2) a trivial class type + * (3) an array of (1), (2), or (3) + */ +bool CTypeInfo::isTrivial () const { + if (isScalar ()) + return true; + if (isArray ()) + return VirtualType ()->BaseType ()->isTrivial (); + if (isClassOrUnion ()) + return TypeRecord ()->isTrivial (); + return false; +} + +long int CTypeInfo::Align () const { + // TODO: Calculation of alignment not yet implemented + // except for class and union types. + return 1; +} + +/** Check if this is a local type. A type is local if it was + * declared in a local scope. */ +bool CTypeInfo::isLocal () const { + if (TypeEmpty () || TypePrimitive ()) { + return false; + } + CObjectInfo* info = 0; + if (TypeTemplateParam ()) { + info = TypeTemplateParam ()->TemplateParamInfo (); + } else if (TypeEnum ()) { + info = TypeEnum ()->EnumInfo (); + } else if (TypeRecord ()) { + info = TypeRecord ()->Record (); + } else if (TypeMemberPointer ()) { + if (TypeMemberPointer ()->TemplateParam ()) + info = TypeMemberPointer ()->TemplateParam (); + else + info = TypeMemberPointer ()->Record (); + } else if (TypeFunction ()) { + info = TypeFunction ()->FunctionInfo (); + } + if (info) { + return info->isLocal (); + } + return BaseType () && this != BaseType () && BaseType ()->isLocal (); +} + + +} // namespace Puma diff --git a/Puma/src/infos/types/CTypeInfo.h b/Puma/src/infos/types/CTypeInfo.h new file mode 100644 index 0000000..7b42b88 --- /dev/null +++ b/Puma/src/infos/types/CTypeInfo.h @@ -0,0 +1,782 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CTypeInfo_h__ +#define __CTypeInfo_h__ + +/** \file + * Entity type information. */ + +#include "Puma/Printable.h" + +namespace Puma { + + +class CSemDatabase; +class CRecord; +class CClassInfo; +class CUnionInfo; +class CEnumInfo; +class CFunctionInfo; +class CTypeList; +class CTypeQualified; +class CTypeFunction; +class CTypeBitField; +class CTypePointer; +class CTypeMemberPointer; +class CTypeTemplateParam; +class CTypeAddress; +class CTypeArray; +class CTypeVarArray; +class CTypeClass; +class CTypeUnion; +class CTypeEnum; +class CTypePrimitive; +class CTypeRecord; +class CT_ExprList; +class CObjectInfo; +class CScopeInfo; +class CTemplateParamInfo; + + +/** \class CTypeInfo CTypeInfo.h Puma/CTypeInfo.h + * Type information for an entity (class, function, object, etc). + * There are two kinds of types: fundamental types like 'int', + * and compound types like 'class X {int i;}'. Types describe + * objects, references, or functions. + * + * A type is identified by its ID. + * \code + * // check if type is a function type + * if (type.Id() == Puma::CTypeInfo::TYPE_FUNCTION) { + * ... + * } + * // same check + * if (type.TypeFunction()) { + * ... + * } + * // same check + * if (type.isFunction()) { + * ... + * } + * \endcode + * \ingroup types */ +class CTypeInfo : public Printable { + // needed for type printing + enum PrintState { + PRINT_STD = 0, // standard + PRINT_PRE = 1, // printing a declarator prefix like '*' or '&' + PRINT_ABS = 2, // printing absolute names + PRINT_TPL = 4, // printing template argument list + PRINT_TDN = 8, // print typedef names instead of defined type + PRINT_ELA = 16, // print elaborated type specifiers (struct, enum, union) + PRINT_INE = 32, // elaborated type speficier already issued ("in elaborated") + PRINT_UNN = 64 // print unnamed namespace as '' + }; + +public: + /** Type identifiers. */ + enum TypeId { + // DO NOT CHANGE THIS ORDER!!! + /** bool */ + TYPE_BOOL, + /** _Bool */ + TYPE_C_BOOL, + /** signed char */ + TYPE_SIGNED_CHAR, + /** unsiged char */ + TYPE_UNSIGNED_CHAR, + /** char */ + TYPE_CHAR, + /** unsigned short */ + TYPE_UNSIGNED_SHORT, + /** short */ + TYPE_SHORT, + /** unsigned int */ + TYPE_UNSIGNED_INT, + /** wchar_t */ + TYPE_WCHAR_T, + /** int */ + TYPE_INT, + /** unsigned long */ + TYPE_UNSIGNED_LONG, + /** long */ + TYPE_LONG, + /** unsigned long long */ + TYPE_UNSIGNED_LONG_LONG, + /** long long */ + TYPE_LONG_LONG, + /** unsigned __int128 */ + TYPE_UNSIGNED_INT128, + /** __int128 */ + TYPE_INT128, + /** float */ + TYPE_FLOAT, + /** double */ + TYPE_DOUBLE, + /** long double */ + TYPE_LONG_DOUBLE, + + /** void */ + TYPE_VOID, + /** Undefined type. */ + TYPE_UNDEFINED, + /** unknown_t */ + TYPE_UNKNOWN_T, + /** Any type. */ + TYPE_ELLIPSIS, + + /** Class type. */ + TYPE_CLASS, + /** Union type. */ + TYPE_UNION, + /** Enumeration type. */ + TYPE_ENUM, + /** Pointer type. */ + TYPE_POINTER, + /** Reference type. */ + TYPE_ADDRESS, + /** Member pointer type. */ + TYPE_MEMBER_POINTER, + /** Function type. */ + TYPE_FUNCTION, + /** Array type. */ + TYPE_ARRAY, + /** Variable length array type. */ + TYPE_VAR_ARRAY, + /** Qualified type. */ + TYPE_QUALIFIED, + /** Bit field type. */ + TYPE_BIT_FIELD, + + /** Template parameter type. */ + TYPE_TEMPLATE_PARAM, + /** No type. */ + TYPE_EMPTY + }; + + /** Internal representation of size_t. */ + static CTypeInfo *CTYPE_SIZE_T; + /** Internal representation of ptrdiff_t. */ + static CTypeInfo *CTYPE_PTRDIFF_T; + +private: + CTypeInfo *_Base; + TypeId _Id; + CObjectInfo *_TypedefInfo; + +public: + /** Constructor. + * \param base The base type of a compound type. + * \param id The type ID. */ + CTypeInfo (CTypeInfo *base, TypeId id); + /** Destructor. */ + ~CTypeInfo (); + + /** Check if this type equals the given type. + * \param type The type to compare with. */ + bool operator ==(const CTypeInfo &type) const; + /** Check if this type not equals the given type. + * \param type The type to compare with. */ + bool operator !=(const CTypeInfo &type) const; + /** Check if this type equals the given type. + * \param type The type to compare with. + * \param matchTemplateParams True if template parameters are matched. + * \param noDependentFctParams True if dependent function params do not match. */ + bool equals (const CTypeInfo &type, bool matchTemplateParams = false, bool noDependentFctParams = false) const; + /** Check if this type equals the given type if both types top-level qualifiers removed. + * \param type The type to compare with. */ + bool equalsUnqualified (const CTypeInfo &type) const; + + /** Print the textual representation of this + * type on the given stream. + * \param os The output stream. */ + void print (std::ostream& os) const; + /** Print the textual representation of this + * type on the given stream. + * \param os The output stream. + * \param name Optional name of the entity to print. + * \param abs Print qualified names with root qualifier. + * \param tdef Print the name of a typedef instead of the underlying type. + * \param elaborated_type_spec Print elaborated type specifier before + * class, union, and enumeration types. + * \param unnamed Print unnamed namespaces as '\' */ + void TypeText (std::ostream &os, const char *name = (const char*)0, + bool abs = false, bool tdef = false, + bool elaborated_type_spec = false, + bool unnamed = false) const; + + /** Get the dimension of an array type. */ + long int Dimension () const; + /** Get the size in bits of a type. */ + long int Size () const; + /** Get the alignment of a type. */ + long int Align () const; + + /** Get the type identifier. */ + TypeId Id () const; + + /** Get the base type of a compound type. + * \return The base type or this if not a compound type. */ + CTypeInfo *BaseType () const; + /** Set the base type of a compount type. + * \param base The base type. */ + void BaseType (CTypeInfo *base); + + /** Check if this is a typedef type. */ + bool isTypedef () const; + /** Get the typedef information if this is a typedef type. */ + CObjectInfo *TypedefInfo () const; + /** Set the typedef information if this is a typedef type. */ + CTypeInfo *TypedefInfo (CObjectInfo *); + + /** Check if this is a complete type. Optionally limited to + * a specific source code position. A type is complete + * if it is not undefined, not void, not an fixed length + * array without dimension, and not a class or enumeration + * that is only declared but not defined. + * \param pos Optional source code position. */ + bool isComplete (unsigned long pos = 0) const; + + /** Check if this type or one of its base types depends on + * a template parameter. + * \param consider_unknown_t Consider unknown_t as dependent. + * \param is_named_type Type of named type. */ + bool isDependent (bool consider_unknown_t = true, bool is_named_type = false) const; + + /** Check if this is a local type. A type is local if it was + * declared in a local scope. */ + bool isLocal () const; + + /** Check if this type is \e const qualified. */ + bool isConst () const; + /** Check if this type is \e volatile qualified. */ + bool isVolatile () const; + /** Check if this type is \e restrict qualified. */ + bool isRestrict () const; + + /** Get the class or union of a class or union type. + * \return The class or union, or NULL if not such a type. */ + CRecord *Record () const; + /** Get the class information if this is a class type. + * \return The class information or NULL if not a class type. */ + CClassInfo *ClassInfo () const; + /** Get the union information if this is a union type. + * \return The union information or NULL if not a union type. */ + CUnionInfo *UnionInfo () const; + /** Get the enumeration information if this is an enumeration type. + * \return The enumeration information or NULL if not an enumeration type. */ + CEnumInfo *EnumInfo () const; + /** Get the function information if this is a function type. + * \return The function information or NULL if not a function type. */ + CFunctionInfo *FunctionInfo () const; + + /** Get the base type of a pointer type. */ + CTypeInfo *PtrBaseType () const; + /** Get the argument type list of a function or qualified type. */ + CTypeList *ArgTypes () const; + /** Get the virtual type of this type. If this type is a qualified, + * bit-field, or reference type then the virtual type is the + * virtual type of the base type of this type. + * \return The base type or this. */ + CTypeInfo *VirtualType () const; + /** Get the unqualified version of this type. + * \return The unqualified type or this if not qualified. */ + CTypeInfo *UnqualType () const; + /** Get the non-reference type version of this type. + * \return The non-reference type or this if not a reference type. */ + CTypeInfo *NonReferenceType () const; + + /** Get the function type of a pointer-to-function type. + * \return The function type or NULL if not a pointer to function. */ + CTypeFunction *PtrToFct () const; + /** Get the array type of a pointer-to-array type. + * \return The array type or NULL if not a pointer to array. */ + CTypeArray *PtrToArray () const; + + /** Get the pointer to CTypeQualified if this is a qualified type. + * \return The valid pointer or NULL. */ + CTypeQualified *TypeQualified () const; + /** Get the pointer to CTypeFunction if this is a function type. + * \return The valid pointer or NULL. */ + CTypeFunction *TypeFunction () const; + /** Get the pointer to CTypeBitField if this is a bit-field type. + * \return The valid pointer or NULL. */ + CTypeBitField *TypeBitField () const; + /** Get the pointer to CTypePointer if this is a pointer type. + * \return The valid pointer or NULL. */ + CTypePointer *TypePointer () const; + /** Get the pointer to CTypeMemberPointer if this is a member pointer type. + * \return The valid pointer or NULL. */ + CTypeMemberPointer *TypeMemberPointer () const; + /** Get the pointer to CTypeAddress if this is a reference type. + * \return The valid pointer or NULL. */ + CTypeAddress *TypeAddress () const; + /** Get the pointer to CTypeArray if this is an array type. + * \return The valid pointer or NULL. */ + CTypeArray *TypeArray () const; + /** Get the pointer to CTypeVarArray if this is a variable length array type. + * \return The valid pointer or NULL. */ + CTypeVarArray *TypeVarArray () const; + /** Get the pointer to CTypeClass if this is a class type. + * \return The valid pointer or NULL. */ + CTypeClass *TypeClass () const; + /** Get the pointer to CTypeUnion if this is a union type. + * \return The valid pointer or NULL. */ + CTypeUnion *TypeUnion () const; + /** Get the pointer to CTypeRecord if this is a class or union type. + * \return The valid pointer or NULL. */ + CTypeRecord *TypeRecord () const; + /** Get the pointer to CTypeEnum if this is an enumeration type. + * \return The valid pointer or NULL. */ + CTypeEnum *TypeEnum () const; + /** Get the pointer to CTypePrimitive if this is a primitive type. + * \return The valid pointer or NULL. */ + CTypePrimitive *TypePrimitive () const; + /** Get the pointer to CTypeInfo if this is type Puma::CTYPE_EMPTY. + * \return The valid pointer or NULL. */ + CTypeInfo *TypeEmpty () const; + /** Get the pointer to CTypeTemplateParam if this is a template parameter type. + * \return The valid pointer or NULL. */ + CTypeTemplateParam *TypeTemplateParam () const; + + /** Check if this is a qualified type. */ + bool isQualified () const; + /** Check if this is a pointer type. */ + bool isPointer () const; + /** Check if this is a pointer or array type. */ + bool isPointerOrArray () const; + /** Check if this is a reference type. */ + bool isAddress () const; + /** Check if this is a class or union type. */ + bool isRecord () const; + /** Check if this is a class type. */ + bool isClass () const; + /** Check if this is a union type. */ + bool isUnion () const; + /** Check if this is a class or union type. */ + bool isClassOrUnion () const; + /** Check if this is an array type. */ + bool isArray () const; + /** Check if this is a fixed length array type. */ + bool isFixedArray () const; + /** Check if this is a variable length type. */ + bool isVarArray () const; + /** Check if this is an arithmetic type. */ + bool isArithmetic () const; + /** Check if this is a pointer or arithmetic type. */ + bool isScalar () const; + /** Check if this is an array, class, or union type. */ + bool isAggregate () const; + /** Check if this is an integer type. */ + bool isInteger () const; + /** Check if this is type \e void. */ + bool isVoid () const; + /** Check if this is an enumeration type. */ + bool isEnum () const; + /** Check if this is a floating point type. */ + bool isReal () const; + /** Check if this is a member pointer type. */ + bool isMemberPointer () const; + /** Check if this is an undefined type. */ + bool isUndefined () const; + /** Check if this is a function type. */ + bool isFunction () const; + /** Check if this is a bit-field type. */ + bool isBitField () const; + /** Check if this is a class member function type. */ + bool isMethod () const; + /** Check if this is a non-class-member function type. */ + bool isStdFunction () const; + /** Check if this is a template type. */ + bool isTemplate () const; + /** Check if this is a template instance type. */ + bool isTemplateInstance () const; + /** Check if this is a template parameter type. */ + bool isTemplateParam () const; + /** Check if this is a type template parameter type. */ + bool isTypeParam () const; + /** Check if this is a non-type template parameter type. */ + bool isNonTypeParam () const; + /** Check if this is an object type. An object type is a + * complete non-function type. + * \param pos Optional source code position. */ + bool isObject (unsigned long pos = 0) const; + /** Check if this is a plain old data (POD) type. */ + bool isPOD () const; + /** Check if this is a trivial type: + * (1) a scalar type + * (2) a trivial class type + * (3) an array of (1), (2), or (3) + */ + bool isTrivial () const; + + // Primitive types. + /** Check if the ID of this type is CTypeInfo::TYPE_BOOL or CTypeInfo::TYPE_C_BOOL. */ + bool is_bool () const; + /** Check if the ID of this type is CTypeInfo::TYPE_CHAR. */ + bool is_char () const; + /** Check if the ID of this type is CTypeInfo::TYPE_WCHAR_T. */ + bool is_wchar_t () const; + /** Check if the ID of this type is CTypeInfo::TYPE_SHORT. */ + bool is_short () const; + /** Check if the ID of this type is CTypeInfo::TYPE_INT. */ + bool is_int () const; + /** Check if the ID of this type is CTypeInfo::TYPE_LONG. */ + bool is_long () const; + /** Check if the ID of this type is CTypeInfo::TYPE_LONG_LONG. */ + bool is_long_long () const; + /** Check if the ID of this type is CTypeInfo::TYPE_INT128. */ + bool is_int128 () const; + /** Check if the ID of this type is CTypeInfo::TYPE_SIGNED_CHAR. */ + bool is_signed_char () const; + /** Check if the ID of this type is CTypeInfo::TYPE_UNSIGNED_CHAR. */ + bool is_unsigned_char () const; + /** Check if the ID of this type is CTypeInfo::TYPE_UNSIGNED_SHORT. */ + bool is_unsigned_short () const; + /** Check if the ID of this type is CTypeInfo::TYPE_UNSIGNED_INT. */ + bool is_unsigned_int () const; + /** Check if the ID of this type is CTypeInfo::TYPE_UNSIGNED_LONG. */ + bool is_unsigned_long () const; + /** Check if the ID of this type is CTypeInfo::TYPE_UNSIGNED_LONG_LONG. */ + bool is_unsigned_long_long () const; + /** Check if the ID of this type is CTypeInfo::TYPE_UNSIGNED_INT128. */ + bool is_unsigned_int128 () const; + /** Check if the ID of this type is CTypeInfo::TYPE_FLOAT. */ + bool is_float () const; + /** Check if the ID of this type is CTypeInfo::TYPE_DOUBLE. */ + bool is_double () const; + /** Check if the ID of this type is CTypeInfo::TYPE_LONG_DOUBLE. */ + bool is_long_double () const; + /** Check if the ID of this type is CTypeInfo::TYPE_VOID. */ + bool is_void () const; + /** Check if the ID of this type is CTypeInfo::TYPE_UNDEFINED. */ + bool is_undefined () const; + /** Check if the ID of this type is CTypeInfo::TYPE_UNKNOWN_T. */ + bool is_unknown_t () const; + /** Check if the ID of this type is CTypeInfo::TYPE_ELLIPSIS. */ + bool is_ellipsis () const; + + /** Check if this is a signed integer type. */ + bool is_signed () const; + /** Check if this is an unsigned integer type. */ + bool is_unsigned () const; + + /** Get the arithmetic conversion rank of the type. + * \note Language C only! */ + unsigned conv_rank () const; + /** Check if the conversion rank of this type is greater + * than the conversion rank of the given type. + * \note Language C only! + * \param type The type to compare with. */ + bool operator >(const CTypeInfo &type) const; + /** Check if the conversion rank of this type equals or + * is greater than the conversion rank of the given type. + * \note Language C only! + * \param type The type to compare with. */ + bool operator >=(const CTypeInfo &type) const; + /** Check if the conversion rank of this type equals or + * is greater than the conversion rank of the given type. + * \note Language C only! + * \param type The type to compare with. */ + bool operator <=(const CTypeInfo &type) const; + /** Check if the conversion rank of this type is less + * than the conversion rank of the given type. + * \note Language C only! + * \param type The type to compare with. */ + bool operator <(const CTypeInfo &type) const; + + /** Get the rank of this type if it is an arithmetic type. + * \note Language C++ only! + * \return The rank or 0 if not an arithmetic type. */ + unsigned rank () const; + + /** Check if this is the type of a template instance argument + * declaration. These declarations are generated and have + * to be handled special. */ + bool isTemplateInstanceArg () const; + +public: + /** Make a duplicate of the given type. + * \param type The type to duplicate. */ + static CTypeInfo *Duplicate (const CTypeInfo *type); + /** Maka a duplicate of this type. */ + CTypeInfo *Duplicate () const; + + /** Destroy the given type. + * \param type The type to destroy. */ + static void Destroy (CTypeInfo *type); + + /** Print the mangled textual representation of + * the type on the given stream. According to the + * C++ V3 ABI mangling (see http://www.codesourcery.com/cxx-abi/abi.html). + * \param os The output stream. */ + void Mangled (std::ostream &os) const; + +private: + void TypeText (char, std::ostream &, const char * = (const char*)0) const; + void printName (char, std::ostream &, CObjectInfo *) const; + void printScope (char, std::ostream &, CObjectInfo *) const; +}; + +/** Empty type. */ +extern CTypeInfo CTYPE_EMPTY; + +} // namespace Puma + + +#include "Puma/CTypePrimitive.inc" +#include "Puma/CTypeQualified.inc" +#include "Puma/CTypeAddress.inc" +#include "Puma/CTypeBitField.inc" +#include "Puma/CTypeArray.inc" +#include "Puma/CTypeVarArray.inc" +#include "Puma/CTypePointer.inc" +#include "Puma/CTypeMemberPointer.inc" +#include "Puma/CTypeFunction.inc" +#include "Puma/CTypeEnum.inc" +#include "Puma/CTypeRecord.inc" +#include "Puma/CTypeClass.inc" +#include "Puma/CTypeUnion.inc" +#include "Puma/CTypeTemplateParam.inc" + + +namespace Puma { + +inline CTypeInfo::CTypeInfo (CTypeInfo *info, CTypeInfo::TypeId id) : + _Base (info ? info : this), + _Id (id), + _TypedefInfo (0) + {} +inline CTypeInfo::~CTypeInfo () + {} + +inline CTypeInfo *CTypeInfo::Duplicate () const + { +return Duplicate (this); + } + +inline CTypeInfo::TypeId CTypeInfo::Id () const + { return _Id; } + +inline bool CTypeInfo::operator !=(const CTypeInfo &type) const + { return ! (*this == type); } + +inline void CTypeInfo::print (std::ostream& out) const + { TypeText ((char)PRINT_STD, out); } +inline void CTypeInfo::TypeText (std::ostream &out, const char *t, bool abs, + bool tdef, bool elaborated_type_spec, bool unnamed) const + { char flags = (char)(abs ? PRINT_ABS : PRINT_STD); + if (tdef) flags |= (char)PRINT_TDN; + if (elaborated_type_spec) flags |= (char)PRINT_ELA; + if (unnamed) flags |= (char)PRINT_UNN; + TypeText (flags, out, t); } + +inline long int CTypeInfo::Dimension () const + { return TypeArray () ? TypeArray ()->Dimension () : + TypeBitField () ? TypeBitField ()->Dimension () : -1; } + +inline bool CTypeInfo::isTypedef () const + { return (bool)_TypedefInfo; } +inline CObjectInfo *CTypeInfo::TypedefInfo () const + { return _TypedefInfo; } + +inline bool CTypeInfo::isConst () const + { return TypeQualified () && TypeQualified ()->isConst (); } +inline bool CTypeInfo::isVolatile () const + { return TypeQualified () && TypeQualified ()->isVolatile (); } +inline bool CTypeInfo::isRestrict () const + { return TypeQualified () && TypeQualified ()->isRestrict (); } + +inline CRecord *CTypeInfo::Record () const + { return TypeRecord () ? TypeRecord ()->Record () : + TypeFunction () ? TypeFunction ()->Record () : + TypeMemberPointer () ? TypeMemberPointer ()->Record () : (CRecord*)0; } +inline CEnumInfo *CTypeInfo::EnumInfo () const + { return TypeEnum () ? TypeEnum ()->EnumInfo () : (CEnumInfo*)0; } +inline CFunctionInfo *CTypeInfo::FunctionInfo () const + { return TypeFunction () ? TypeFunction ()->FunctionInfo () : (CFunctionInfo*)0; } + +inline CTypeInfo *CTypeInfo::BaseType () const + { assert(_Base); return _Base; } +inline void CTypeInfo::BaseType (CTypeInfo *type) + { _Base = type; } +inline CTypeInfo *CTypeInfo::PtrBaseType () const + { return VirtualType ()->BaseType (); } + +inline CTypeList *CTypeInfo::ArgTypes () const + { return TypeFunction () ? TypeFunction ()->ArgTypes () : + TypeQualified () ? TypeQualified ()->ArgTypes () : (CTypeList*)0; } + +inline CTypePrimitive *CTypeInfo::TypePrimitive () const + { return _Id < TYPE_CLASS ? (CTypePrimitive*)this : (CTypePrimitive*)0; } +inline CTypeQualified *CTypeInfo::TypeQualified () const + { return _Id == TYPE_QUALIFIED ? (CTypeQualified*)this : (CTypeQualified*)0; } +inline CTypeFunction *CTypeInfo::TypeFunction () const + { return _Id == TYPE_FUNCTION ? (CTypeFunction*)this : (CTypeFunction*)0; } +inline CTypeBitField *CTypeInfo::TypeBitField () const + { return _Id == TYPE_BIT_FIELD ? (CTypeBitField*)this : (CTypeBitField*)0; } +inline CTypePointer *CTypeInfo::TypePointer () const + { return _Id == TYPE_POINTER || _Id == TYPE_MEMBER_POINTER ? (CTypePointer*)this : (CTypePointer*)0; } +inline CTypeMemberPointer* CTypeInfo::TypeMemberPointer () const + { return _Id == TYPE_MEMBER_POINTER ? (CTypeMemberPointer*)this : (CTypeMemberPointer*)0; } +inline CTypeAddress *CTypeInfo::TypeAddress () const + { return _Id == TYPE_ADDRESS ? (CTypeAddress*)this : (CTypeAddress*)0; } +inline CTypeArray *CTypeInfo::TypeArray () const + { return _Id == TYPE_ARRAY || _Id == TYPE_VAR_ARRAY ? (CTypeArray*)this : (CTypeArray*)0; } +inline CTypeVarArray *CTypeInfo::TypeVarArray () const + { return _Id == TYPE_VAR_ARRAY ? (CTypeVarArray*)this : (CTypeVarArray*)0; } +inline CTypeRecord *CTypeInfo::TypeRecord () const + { return _Id == TYPE_CLASS || _Id == TYPE_UNION ? (CTypeRecord*)this : (CTypeRecord*)0; } +inline CTypeClass *CTypeInfo::TypeClass () const + { return _Id == TYPE_CLASS ? (CTypeClass*)this : (CTypeClass*)0; } +inline CTypeUnion *CTypeInfo::TypeUnion () const + { return _Id == TYPE_UNION ? (CTypeUnion*)this : (CTypeUnion*)0; } +inline CTypeEnum *CTypeInfo::TypeEnum () const + { return _Id == TYPE_ENUM ? (CTypeEnum*)this : (CTypeEnum*)0; } +inline CTypeInfo *CTypeInfo::TypeEmpty () const + { return _Id == TYPE_EMPTY ? (CTypeInfo*)this : (CTypeInfo*)0; } +inline CTypeTemplateParam *CTypeInfo::TypeTemplateParam () const + { return _Id == TYPE_TEMPLATE_PARAM ? (CTypeTemplateParam*)this : (CTypeTemplateParam*)0; } + +inline CTypeInfo *CTypeInfo::VirtualType () const + { return TypeQualified () || TypeBitField () || TypeAddress () ? + BaseType ()->VirtualType () : (CTypeInfo*)this; } +inline CTypeInfo *CTypeInfo::UnqualType () const + { return TypeQualified () ? BaseType ()->UnqualType () : (CTypeInfo*)this; } +inline CTypeInfo *CTypeInfo::NonReferenceType () const + { return TypeAddress () ? BaseType ()->NonReferenceType () : (CTypeInfo*)this; } + +inline bool CTypeInfo::isQualified () const + { return TypeQualified (); } +inline bool CTypeInfo::isTemplateParam () const + { return VirtualType ()->TypeTemplateParam (); } +inline bool CTypeInfo::isPointer () const + { return VirtualType ()->TypePointer (); } +inline bool CTypeInfo::isMemberPointer () const + { return VirtualType ()->TypeMemberPointer (); } +inline bool CTypeInfo::isClass () const + { return VirtualType ()->TypeClass (); } +inline bool CTypeInfo::isUnion () const + { return VirtualType ()->TypeUnion (); } +inline bool CTypeInfo::isClassOrUnion () const + { return isRecord (); } +inline bool CTypeInfo::isArray () const + { return VirtualType ()->TypeArray (); } +inline bool CTypeInfo::isFixedArray () const + { return VirtualType ()->TypeArray () && + VirtualType ()->TypeArray ()->isFixed (); } +inline bool CTypeInfo::isVarArray () const + { return VirtualType ()->TypeVarArray (); } +inline bool CTypeInfo::isEnum () const + { return VirtualType ()->TypeEnum (); } +inline bool CTypeInfo::isFunction () const + { return VirtualType ()->TypeFunction (); } +inline bool CTypeInfo::isBitField () const + { return TypeBitField (); } +inline bool CTypeInfo::isUndefined () const + { return VirtualType ()->is_undefined (); } +inline bool CTypeInfo::isInteger () const + { return VirtualType ()->_Id < TYPE_FLOAT || VirtualType ()->isEnum (); } +inline bool CTypeInfo::isReal () const + { CTypeInfo *base = VirtualType (); + return base->is_float () || base->is_double () || base->is_long_double (); } +inline bool CTypeInfo::isMethod () const + { CTypeInfo *base = VirtualType (); + return base->TypeFunction () && base->TypeFunction ()->Record (); } +inline bool CTypeInfo::isStdFunction () const + { return VirtualType ()->TypeFunction () && ! isMethod (); } +inline bool CTypeInfo::isPointerOrArray () const + { CTypeInfo *base = VirtualType (); + return base->TypePointer () || base->TypeArray (); } +inline bool CTypeInfo::isAddress () const + { return TypeAddress () || ((TypeQualified () || TypeBitField ()) && + BaseType ()->isAddress ()); } +inline bool CTypeInfo::isRecord () const + { return VirtualType ()->TypeRecord (); } +inline bool CTypeInfo::isScalar () const + { return isArithmetic () || isPointer (); } +inline bool CTypeInfo::isAggregate () const + { return isArray () || isClass () || isUnion (); } +inline bool CTypeInfo::isVoid () const + { return VirtualType ()->is_void (); } +inline bool CTypeInfo::isObject (unsigned long pos) const + { return ! isFunction () && (pos ? isComplete (pos) : true); } +inline bool CTypeInfo::isTypeParam () const + { return isTemplateParam () && + VirtualType ()->TypeTemplateParam ()->isType (); } +inline bool CTypeInfo::isNonTypeParam () const + { return isTemplateParam () && + ! VirtualType ()->TypeTemplateParam ()->isType (); } + +inline bool CTypeInfo::is_bool () const + { return _Id == TYPE_BOOL || _Id == TYPE_C_BOOL; } +inline bool CTypeInfo::is_char () const + { return _Id == TYPE_CHAR; } +inline bool CTypeInfo::is_wchar_t () const + { return _Id == TYPE_WCHAR_T; } +inline bool CTypeInfo::is_short () const + { return _Id == TYPE_SHORT; } +inline bool CTypeInfo::is_int () const + { return _Id == TYPE_INT; } +inline bool CTypeInfo::is_long () const + { return _Id == TYPE_LONG; } +inline bool CTypeInfo::is_long_long () const + { return _Id == TYPE_LONG_LONG; } +inline bool CTypeInfo::is_int128 () const + { return _Id == TYPE_INT128; } +inline bool CTypeInfo::is_signed_char () const + { return _Id == TYPE_SIGNED_CHAR; } +inline bool CTypeInfo::is_unsigned_char () const + { return _Id == TYPE_UNSIGNED_CHAR; } +inline bool CTypeInfo::is_unsigned_short () const + { return _Id == TYPE_UNSIGNED_SHORT; } +inline bool CTypeInfo::is_unsigned_int () const + { return _Id == TYPE_UNSIGNED_INT; } +inline bool CTypeInfo::is_unsigned_long () const + { return _Id == TYPE_UNSIGNED_LONG; } +inline bool CTypeInfo::is_unsigned_long_long () const + { return _Id == TYPE_UNSIGNED_LONG_LONG; } +inline bool CTypeInfo::is_unsigned_int128 () const + { return _Id == TYPE_UNSIGNED_INT128; } +inline bool CTypeInfo::is_float () const + { return _Id == TYPE_FLOAT; } +inline bool CTypeInfo::is_double () const + { return _Id == TYPE_DOUBLE; } +inline bool CTypeInfo::is_long_double () const + { return _Id == TYPE_LONG_DOUBLE; } +inline bool CTypeInfo::is_void () const + { return _Id == TYPE_VOID; } +inline bool CTypeInfo::is_unknown_t () const + { return _Id == TYPE_UNKNOWN_T; } +inline bool CTypeInfo::is_undefined () const + { return _Id == TYPE_UNDEFINED; } +inline bool CTypeInfo::is_ellipsis () const + { return _Id == TYPE_ELLIPSIS; } + +inline bool CTypeInfo::operator <=(const CTypeInfo &type) const + { return ! (*this > type); } +inline bool CTypeInfo::operator >=(const CTypeInfo &type) const + { return ! (*this < type); } +inline bool CTypeInfo::operator ==(const CTypeInfo &type) const + { return equals(type); } + + +} // namespace Puma + +#endif /* __CTypeInfo_h__ */ diff --git a/Puma/src/infos/types/CTypeList.inc b/Puma/src/infos/types/CTypeList.inc new file mode 100644 index 0000000..1914fb3 --- /dev/null +++ b/Puma/src/infos/types/CTypeList.inc @@ -0,0 +1,104 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CTypeList_h__ +#define __CTypeList_h__ + +/** \file + * Type list. */ + +#ifndef __CTypeFunction_h__ +#warning !!! DO NOT INCLUDE THIS FILE !!! +#warning !!! INCLUDE FILE "CTypeInfo.h" INSTEAD !!! +#endif + +#include "Puma/Array.h" + +namespace Puma { + + +class CTypeInfo; +class CT_ArgDeclList; + + +/** \class CTypeList CTypeList.inc Puma/CTypeList.h + * %List of types. Used for instance for the list of function + * parameter types. + * \ingroup types */ +class CTypeList { + Array _List; + CT_ArgDeclList *_ArgumentList; + +public: + /** Constructor. + * \param len The initial length of the list. */ + CTypeList (int len = 1); + /** Destructor. */ + ~CTypeList (); + + /** Get the number of types in the list. */ + unsigned Entries () const; + /** Get the n-th type. + * \param n The index of the type. */ + CTypeInfo *Entry (unsigned n) const; + /** Replace the n-th type in the list by the given type. + * \param n The index of the type to replace. + * \param type The new type. */ + void ReplaceEntry (unsigned n, CTypeInfo *type); + + /** Get the argument declaration list for K&R functions. */ + CT_ArgDeclList *ArgumentList () const; + /** Set the argument declaration list for K&R functions. + * \param args The argument declaration list. */ + void ArgumentList (CT_ArgDeclList *args); + + /** Add a type to the list. + * \param type The type to add. */ + void AddEntry (CTypeInfo *type); + + /** Check if one of the types in the list depends on + * a template parameter. */ + bool isDependent () const; +}; + +inline CTypeList::CTypeList (int len) : + _List (len, 2), + _ArgumentList ((CT_ArgDeclList*)0) + {} +inline CTypeList::~CTypeList () + {} + +inline CT_ArgDeclList *CTypeList::ArgumentList () const + { return _ArgumentList; } +inline void CTypeList::ArgumentList (CT_ArgDeclList *al) + { _ArgumentList = al; } + +inline unsigned CTypeList::Entries () const + { return _List.length (); } +inline CTypeInfo *CTypeList::Entry (unsigned i) const + { return _List.lookup (i); } + +inline void CTypeList::AddEntry (CTypeInfo *info) + { if (info) _List.append (info); } +inline void CTypeList::ReplaceEntry (unsigned i, CTypeInfo *info) + { if (info && (i < Entries ())) _List[i] = info; } + + +} // namespace Puma + +#endif /* __CTypeList_h__ */ diff --git a/Puma/src/infos/types/CTypeMemberPointer.inc b/Puma/src/infos/types/CTypeMemberPointer.inc new file mode 100644 index 0000000..680261d --- /dev/null +++ b/Puma/src/infos/types/CTypeMemberPointer.inc @@ -0,0 +1,82 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CTypeMemberPointer_h__ +#define __CTypeMemberPointer_h__ + +/** \file + * Type of a member pointer. */ + +#ifndef __CTypeInfo_h__ +#warning !!! DO NOT INCLUDE THIS FILE !!! +#warning !!! INCLUDE FILE "CTypeInfo.h" INSTEAD !!! +#endif + +namespace Puma { + + +class CObjectInfo; +class CRecord; +class CTemplateParamInfo; + + +/** \class CTypeMemberPointer CTypeMemberPointer.inc Puma/CTypeInfo.h + * Type of a member pointer. + * Examples: + * \code + * struct X { int a; void f(int); }; + * int X::* aptr = &X::a; // aptr has type 'member pointer to int' + * // type structure: + * // CTypeMemberPointer class=X + * // CTypePrimitive int + * void (X::*fptr)(int) = &X::f; // fptr has type 'member pointer to function returning void with one argument int' + * // type structure: + * // CTypeMemberPointer class=X + * // CTypeFunction args=int + * // CTypePrimitive void + * \endcode + * \ingroup types */ +class CTypeMemberPointer : public CTypePointer { + CObjectInfo *_Class; + +public: + /** Constructor. Type has id CTypeInfo::TYPE_MEMBER_POINTER. + * \param base The base type (type of the member). + * \param info The class containing the member. */ + CTypeMemberPointer (CTypeInfo *base, CObjectInfo *info); + /** Destructor. */ + ~CTypeMemberPointer (); + + /** Get the class or union containing the member. */ + CRecord *Record () const; + /** Get the template parameter information if the member's + * class is a type template parameter. */ + CTemplateParamInfo *TemplateParam () const; +}; + +inline CTypeMemberPointer::CTypeMemberPointer (CTypeInfo *base, CObjectInfo *c) : + CTypePointer (base, CTypeInfo::TYPE_MEMBER_POINTER), + _Class (c) + {} +inline CTypeMemberPointer::~CTypeMemberPointer () + {} + + +} // namespace Puma + +#endif /* __CTypeMemberPointer_h__ */ diff --git a/Puma/src/infos/types/CTypePointer.inc b/Puma/src/infos/types/CTypePointer.inc new file mode 100644 index 0000000..52d13cb --- /dev/null +++ b/Puma/src/infos/types/CTypePointer.inc @@ -0,0 +1,75 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CTypePointer_h__ +#define __CTypePointer_h__ + +/** \file + * Type of a pointer. */ + +#ifndef __CTypeInfo_h__ +#warning !!! DO NOT INCLUDE THIS FILE !!! +#warning !!! INCLUDE FILE "CTypeInfo.h" INSTEAD !!! +#endif + +namespace Puma { + + +/** \class CTypePointer CTypePointer.inc Puma/CTypeInfo.h + * Type of a pointer. + * Examples: + * \code + * int* ip = 0; // ip has type 'pointer to int' + * // type structure: + * // CTypePointer + * // CTypePrimitive int + * const char* s = 0; // s has type 'pointer to const char' + * // type structure: + * // CTypePointer + * // CTypeQualified const + * // CTypePrimitive char + * \endcode + * \ingroup types */ +class CTypePointer : public CTypeInfo { +protected: + /** Constructor. + * \param base The base type. + * \param id The type identifier. */ + CTypePointer (CTypeInfo *base, CTypeInfo::TypeId id); + +public: + /** Constructor. Type has id CTypeInfo::TYPE_POINTER. + * \param base The base type. */ + CTypePointer (CTypeInfo *base); + /** Destructor. */ + ~CTypePointer (); +}; + +inline CTypePointer::CTypePointer (CTypeInfo *base) : + CTypeInfo (base, CTypeInfo::TYPE_POINTER) + {} +inline CTypePointer::CTypePointer (CTypeInfo *base, CTypeInfo::TypeId id) : + CTypeInfo (base, id) + {} +inline CTypePointer::~CTypePointer () + {} + + +} // namespace Puma + +#endif /* __CTypePointer_h__ */ diff --git a/Puma/src/infos/types/CTypePrimitive.inc b/Puma/src/infos/types/CTypePrimitive.inc new file mode 100644 index 0000000..2e46961 --- /dev/null +++ b/Puma/src/infos/types/CTypePrimitive.inc @@ -0,0 +1,143 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CTypePrimitive_h__ +#define __CTypePrimitive_h__ + +/** \file + * Primitive types. */ + +#ifndef __CTypeInfo_h__ +#warning !!! DO NOT INCLUDE THIS FILE !!! +#warning !!! INCLUDE FILE "CTypeInfo.h" INSTEAD !!! +#endif + +namespace Puma { + + +/** \class CTypePrimitive CTypePrimitive.inc Puma/CTypeInfo.h + * Primitive type. Fundamental arithmetic types and + * type void are called primitive types. + * \ingroup types */ +class CTypePrimitive : public CTypeInfo { + const char *_Text; + long int _Size; + +public: + /** Constructor. + * \param name The type name. + * \param id The type identifier. + * \param size The size of the type in bits. */ + CTypePrimitive (const char *name, TypeId id, long int size); + /** Destructor. */ + ~CTypePrimitive (); + + /** Get the type name. */ + const char *TypeName () const; + + /** Get the size of the primitive type in bits. */ + long int Size() const; + /** Set the size of the primitive type in bits. + * @param size The size of the type in bits. */ + void Size(long int size); + + /** Count the number of bits required for the given number. + * @param number The number. */ + template + static long int SizeOfNumber(T number); +}; + +inline CTypePrimitive::CTypePrimitive (const char *t, CTypeInfo::TypeId id, long int size) : + CTypeInfo (&CTYPE_EMPTY, id), + _Text (t), + _Size (size) + {} +inline CTypePrimitive::~CTypePrimitive () + {} + +inline const char *CTypePrimitive::TypeName () const + { return _Text; } + +inline long int CTypePrimitive::Size () const + { return _Size; } + +inline void CTypePrimitive::Size (long int size) + { _Size = size; } + +template +inline long int CTypePrimitive::SizeOfNumber(T number) + { if (number == 0) return 1; + if (number < 0) number -= number; + long int size; + for (size = 0; number != 0; number >>= 1, size++); + return size; + } + +// Basic types ////////////////////////////////////////////////// + +/** bool */ +extern CTypePrimitive CTYPE_BOOL; +/** _Bool */ +extern CTypePrimitive CTYPE_C_BOOL; +/** char */ +extern CTypePrimitive CTYPE_CHAR; +/** signed char */ +extern CTypePrimitive CTYPE_SIGNED_CHAR; +/** unsigned char */ +extern CTypePrimitive CTYPE_UNSIGNED_CHAR; +/** wchar_t */ +extern CTypePrimitive CTYPE_WCHAR_T; +/** short */ +extern CTypePrimitive CTYPE_SHORT; +/** unsigned short */ +extern CTypePrimitive CTYPE_UNSIGNED_SHORT; +/** int */ +extern CTypePrimitive CTYPE_INT; +/** unsigned int */ +extern CTypePrimitive CTYPE_UNSIGNED_INT; +/** long */ +extern CTypePrimitive CTYPE_LONG; +/** unsigned long */ +extern CTypePrimitive CTYPE_UNSIGNED_LONG; +/** long long */ +extern CTypePrimitive CTYPE_LONG_LONG; +/** unsigned long long */ +extern CTypePrimitive CTYPE_UNSIGNED_LONG_LONG; +/** __int128 */ +extern CTypePrimitive CTYPE_INT128; +/** unsigned __int128 */ +extern CTypePrimitive CTYPE_UNSIGNED_INT128; +/** float */ +extern CTypePrimitive CTYPE_FLOAT; +/** double */ +extern CTypePrimitive CTYPE_DOUBLE; +/** long double */ +extern CTypePrimitive CTYPE_LONG_DOUBLE; +/** void */ +extern CTypePrimitive CTYPE_VOID; +/** unknown_t */ +extern CTypePrimitive CTYPE_UNKNOWN_T; +/** Undefined type. */ +extern CTypePrimitive CTYPE_UNDEFINED; +/** Any type. */ +extern CTypePrimitive CTYPE_ELLIPSIS; + + +} // namespace Puma + +#endif /* __CTypePrimitive_h__ */ diff --git a/Puma/src/infos/types/CTypeQualified.inc b/Puma/src/infos/types/CTypeQualified.inc new file mode 100644 index 0000000..52faa66 --- /dev/null +++ b/Puma/src/infos/types/CTypeQualified.inc @@ -0,0 +1,124 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CTypeQualified_h__ +#define __CTypeQualified_h__ + +/** \file + * Type qualification. */ + +#ifndef __CTypeInfo_h__ +#warning !!! DO NOT INCLUDE THIS FILE !!! +#warning !!! INCLUDE FILE "CTypeInfo.h" INSTEAD !!! +#endif + +namespace Puma { + + +/** \class CTypeQualified CTypeQualified.inc Puma/CTypeInfo.h + * Type qualification. There are three type qualifier: + * \e const, \e volatile, and \e restrict. + * Examples: + * \code + * const int i = 0; // i has type 'const int' + * // type structure: + * // CTypeQualified const + * // CTypePrimitive int + * char * const s = 0; // s has type 'const pointer to char' + * // type structure: + * // CTypeQualified const + * // CTypePointer + * // CTypePrimitive char + * \endcode + * \ingroup types */ +class CTypeQualified : public CTypeInfo { + bool _QualConst; + bool _QualVolatile; + bool _QualRestrict; + +protected: + /** Constructor. + * \param base The base type. + * \param c Type has qualifier \e const. + * \param v Type has qualifier \e volatile. + * \param r Type has qualifier \e restrict. + * \param id The type identifier. */ + CTypeQualified (CTypeInfo *base, bool c, bool v, bool r, TypeId id); + +public: + /** Constructor. Type has id CTypeInfo::TYPE_QUALIFIED. + * \param base The base type. + * \param c Type has qualifier \e const. + * \param v Type has qualifier \e volatile. + * \param r Type has qualifier \e restrict. */ + CTypeQualified (CTypeInfo *base, bool c, bool v, bool r); + /** Destructor. */ + ~CTypeQualified (); + + /** Check if the type has qualifier \e const. */ + bool isConst () const; + /** Check if the type has qualifier \e volatile. */ + bool isVolatile () const; + /** Check if the type has qualifier \e restrict. */ + bool isRestrict () const; + + /** Set whether the type has qualifier \e const. + * \param v True if qualified. */ + void isConst (bool v); + /** Set whether the type has qualifier \e volatile. + * \param v True if qualified. */ + void isVolatile (bool v); + /** Set whether the type has qualifier \e restrict. + * \param v True if qualified. */ + void isRestrict (bool v); +}; + +inline CTypeQualified::CTypeQualified (CTypeInfo *base, bool c, bool v, bool r, + CTypeInfo::TypeId id) : + CTypeInfo (base, id), + _QualConst (c), + _QualVolatile (v), + _QualRestrict (r) + {} +inline CTypeQualified::CTypeQualified (CTypeInfo *base, bool c, bool v, bool r) : + CTypeInfo (base, CTypeInfo::TYPE_QUALIFIED), + _QualConst (c), + _QualVolatile (v), + _QualRestrict (r) + {} +inline CTypeQualified::~CTypeQualified () + {} + +inline bool CTypeQualified::isConst () const + { return _QualConst; } +inline bool CTypeQualified::isVolatile () const + { return _QualVolatile; } +inline bool CTypeQualified::isRestrict () const + { return _QualRestrict; } + +inline void CTypeQualified::isConst (bool v) + { _QualConst = v; } +inline void CTypeQualified::isVolatile (bool v) + { _QualVolatile = v; } +inline void CTypeQualified::isRestrict (bool v) + { _QualRestrict = v; } + + +} // namespace Puma + +#endif /* __CTypeQualified_h__ */ diff --git a/Puma/src/infos/types/CTypeRecord.inc b/Puma/src/infos/types/CTypeRecord.inc new file mode 100644 index 0000000..b54b30f --- /dev/null +++ b/Puma/src/infos/types/CTypeRecord.inc @@ -0,0 +1,105 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CTypeRecord_h__ +#define __CTypeRecord_h__ + +/** \file + * Type of a class or union. */ + +#ifndef __CTypeInfo_h__ +#warning !!! DO NOT INCLUDE THIS FILE !!! +#warning !!! INCLUDE FILE "CTypeInfo.h" INSTEAD !!! +#endif + +namespace Puma { + + +class CRecord; + +/** \class CTypeRecord CTypeRecord.inc Puma/CTypeInfo.h + * Type of a class or union. + * \ingroup types */ +class CTypeRecord : public CTypeInfo { + bool _hasConstMember; + + long int _Size; + long int _Align; + + CRecord *_Record; + +protected: + /** Constructor. + * \param id The type identifier. + * \param cu The class or union. */ + CTypeRecord (TypeId id, CRecord *cu); + +public: + /** Destructor. */ + ~CTypeRecord (); + + /** Get the size of the class or union in bits. */ + long int Size (); + /** Get the alignment of the type. */ + long int Align (); + + /** Set whether the class or union has a + * const member and thus is not modifiable. + * \param v True if it has a const member. */ + void hasConstMember (bool v); + /** Check if the class or union type has a + * const member and thus is not modifiable. */ + bool hasConstMember () const; + + /** Check if the class or union is complete. + * \param pos Optional source code position. */ + bool isComplete (unsigned long pos = 0) const; + + /** Get the class or union. */ + CRecord *Record () const; + /** Set the class or union. */ + void Record (CRecord *); +}; + +inline CTypeRecord::CTypeRecord (CTypeInfo::TypeId id, CRecord *r) : + CTypeInfo (&CTYPE_EMPTY, id), + _hasConstMember (false), + _Size (0), + _Align (0), + _Record (r) + {} +inline CTypeRecord::~CTypeRecord () + {} + +inline CRecord *CTypeRecord::Record () const + { return _Record; } +inline void CTypeRecord::Record (CRecord *r) + { _Record = r; } + +inline long int CTypeRecord::Align () + { return (Size (), _Align); } + +inline bool CTypeRecord::hasConstMember () const + { return _hasConstMember; } +inline void CTypeRecord::hasConstMember (bool v) + { _hasConstMember = v; } + + +} // namespace Puma + +#endif /* __CTypeRecord_h__ */ diff --git a/Puma/src/infos/types/CTypeTemplateParam.inc b/Puma/src/infos/types/CTypeTemplateParam.inc new file mode 100644 index 0000000..f57a46c --- /dev/null +++ b/Puma/src/infos/types/CTypeTemplateParam.inc @@ -0,0 +1,78 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CTypeTemplateParam_h__ +#define __CTypeTemplateParam_h__ + +/** \file + * Type of a template parameter. */ + +#ifndef __CTypeInfo_h__ +#warning !!! DO NOT INCLUDE THIS FILE !!! +#warning !!! INCLUDE FILE "CTypeInfo.h" INSTEAD !!! +#endif + +namespace Puma { + + +class CTemplateParamInfo; + + +/** \class CTypeTemplateParam CTypeTemplateParam.inc Puma/CTypeInfo.h + * Type of a template parameter. + * \ingroup types */ +class CTypeTemplateParam : public CTypeInfo { + CTemplateParamInfo *_TemplateParam; + +public: + /** Constructor. The type ID is CTypeInfo::TYPE_TEMPLATE_PARAM. + * \param info The template parameter. */ + CTypeTemplateParam (CTemplateParamInfo *info); + /** Destructor. */ + ~CTypeTemplateParam (); + + /** Get the template parameter information. */ + CTemplateParamInfo *TemplateParamInfo () const; + /** Set the template parameter information. + * \param info The template parameter. */ + void TemplateParamInfo (CTemplateParamInfo *info); + /** Check if this is the type of a type template parameter. */ + bool isType () const; + /** Check if this is the type of a non-type template parameter. */ + bool isNonType () const; +}; + +inline CTypeTemplateParam::CTypeTemplateParam (CTemplateParamInfo *t) : + CTypeInfo (&CTYPE_EMPTY, CTypeInfo::TYPE_TEMPLATE_PARAM), + _TemplateParam (t) + {} +inline CTypeTemplateParam::~CTypeTemplateParam () + {} + +inline CTemplateParamInfo *CTypeTemplateParam::TemplateParamInfo () const + { return _TemplateParam; } + +inline bool CTypeTemplateParam::isNonType () const + { return (! isType ()); } + +inline void CTypeTemplateParam::TemplateParamInfo (CTemplateParamInfo *info) + { _TemplateParam = info; } + +} // namespace Puma + +#endif /* __CTypeTemplateParam_h__ */ diff --git a/Puma/src/infos/types/CTypeUnion.inc b/Puma/src/infos/types/CTypeUnion.inc new file mode 100644 index 0000000..93ed4d1 --- /dev/null +++ b/Puma/src/infos/types/CTypeUnion.inc @@ -0,0 +1,65 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CTypeUnion_h__ +#define __CTypeUnion_h__ + +/** \file + * Type of a union. */ + +#ifndef __CTypeInfo_h__ +#warning !!! DO NOT INCLUDE THIS FILE !!! +#warning !!! INCLUDE FILE "CTypeInfo.h" INSTEAD !!! +#endif + +namespace Puma { + + +class CUnionInfo; +class CRecord; + + +/** \class CTypeUnion CTypeUnion.inc Puma/CTypeInfo.h + * Type of a union. + * Example: + * \code + * union X x; // x has type 'union X' + * \endcode + * \ingroup types */ +class CTypeUnion : public CTypeRecord { +public: + /** Constructor. Type has id CTypeInfo::TYPE_UNION. + * \param c The semantic information about the union. */ + CTypeUnion (CRecord *c); + /** Destructor. */ + ~CTypeUnion (); + + /** Get the semantic information about the union. */ + CUnionInfo *UnionInfo () const; +}; + +inline CTypeUnion::CTypeUnion (CRecord *u) : + CTypeRecord (CTypeInfo::TYPE_UNION, u) + {} +inline CTypeUnion::~CTypeUnion () + {} + + +} // namespace Puma + +#endif /* __CTypeUnion_h__ */ diff --git a/Puma/src/infos/types/CTypeVarArray.inc b/Puma/src/infos/types/CTypeVarArray.inc new file mode 100644 index 0000000..7f62d52 --- /dev/null +++ b/Puma/src/infos/types/CTypeVarArray.inc @@ -0,0 +1,61 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CTypeVarArray_h__ +#define __CTypeVarArray_h__ + +/** \file + * Type of a variable length array. */ + +#ifndef __CTypeInfo_h__ +#warning !!! DO NOT INCLUDE THIS FILE !!! +#warning !!! INCLUDE FILE "CTypeInfo.h" INSTEAD !!! +#endif + +namespace Puma { + + +/** \class CTypeVarArray CTypeVarArray.inc Puma/CTypeInfo.h + * Type of a variable length array. + * Example: + * \code + * void foo(int len) { + * int i[len]; // i has type 'variable length array of int' + * } + * \endcode + * \ingroup types */ +class CTypeVarArray : public CTypeArray { +public: + /** Constructor. Type has id CTypeInfo::TYPE_VAR_ARRAY. + * \param base The base type of the array. + * \param quals The type qualifiers. */ + CTypeVarArray (CTypeInfo *base, CTypeQualified *quals = 0); + /** Destructor. */ + ~CTypeVarArray (); +}; + +inline CTypeVarArray::CTypeVarArray (CTypeInfo *base, CTypeQualified *quals) : + CTypeArray (base, quals, CTypeInfo::TYPE_VAR_ARRAY) + {} +inline CTypeVarArray::~CTypeVarArray () + {} + + +} // namespace Puma + +#endif /* __CTypeVarArray_h__ */ diff --git a/Puma/src/manip/CMatch.cc b/Puma/src/manip/CMatch.cc new file mode 100644 index 0000000..c5f74c7 --- /dev/null +++ b/Puma/src/manip/CMatch.cc @@ -0,0 +1,109 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CMatch.h" +#include +#include + +namespace Puma { + + +// delete the sub-matches +CMatch::~CMatch () { + for (int i = 0; i < _matches.length (); i++) + delete _matches.get (i); +} + +// clear the object +void CMatch::clear () { + for (int i = 0; i < _matches.length (); i++) + delete _matches.get (i); + + _matches.reset (); +} + +// combine two CMatch objects +void CMatch::combine (CMatch *matchObj, bool root) { + if (! matchObj) + return; + + Array &matches = matchObj->matches (); + int start = 0; + if (! _root && ! root) + if (matches.length ()) + if (strcmp (matches[0]->name (), "root") == 0) + start = 1; + + for (int i = start; i < matches.length (); i++) + for (int j = 0; j < (int)matches[i]->Trees (); j++) + add (matches[i]->Tree (j), matches[i]->name ()); +} + +// get the index of the named sub-tree +int CMatch::index (const char *name) const { + if (! name) + return -1; + + int len = _matches.length (); + + for (int i = 0; i < len; i++) + if (_matches.lookup (i)->name ()) + if (strcmp (_matches.lookup (i)->name (), name) == 0) + return i; + + return -1; +} + +// get a sub-tree by its associated name +Array &CMatch::get (const char *name) const { + int pos = index (name); + + if (pos == -1) + return (Array&)_empty; + + return _matches.lookup (pos)->trees (); +} + +// get the named sub-match +CSubMatch *CMatch::SubMatch (const char *name) const { + int pos = index (name); + + if (pos == -1) + return (CSubMatch*)0; + + return _matches.lookup (pos); +} + +// add a new sub-tree +void CMatch::add (CTree *tree, const char *name) { + int pos; + + if (! tree || ! name) + return; + + if (! get (name).length ()) { + pos = _matches.length (); + _matches.get (pos) = new CSubMatch (name); + } else + pos = index (name); + + _matches.get (pos)->trees ().append (tree); +} + + +} // namespace Puma diff --git a/Puma/src/manip/CMatch.h b/Puma/src/manip/CMatch.h new file mode 100644 index 0000000..7d6f642 --- /dev/null +++ b/Puma/src/manip/CMatch.h @@ -0,0 +1,66 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CMatch__ +#define __CMatch__ + +// A match consists of a list of matched trees + +#include "Puma/CSubMatch.h" +#include "Puma/Array.h" + +namespace Puma { + + +class CMatch { + bool _root; + + Array _matches; // sub-matches + Array _empty; // to return in error case + +public: + CMatch (bool root = false) : _root (root) {} + ~CMatch (); + + // combine two CMatch objects + void combine (CMatch *, bool = false); + + // get the sub-trees with the given name + Array &get (const char *) const; + + // add a new sub-tree + void add (CTree *, const char *); + + // get the sub-matches + Array &matches () { return (Array&) _matches; } + unsigned SubMatches () const { return _matches.length (); } + CSubMatch *SubMatch (unsigned i) const { return _matches.lookup (i); } + CSubMatch *SubMatch (const char *) const; + + // clear the object + void clear (); + +private: + // get the index of the named sub-trees + int index (const char *) const; +}; + + +} // namespace Puma + +#endif /* __CMatch__ */ diff --git a/Puma/src/manip/CMatchChecker.cc b/Puma/src/manip/CMatchChecker.cc new file mode 100644 index 0000000..ce3a4c4 --- /dev/null +++ b/Puma/src/manip/CMatchChecker.cc @@ -0,0 +1,117 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CMatchChecker.h" +#include "Puma/CTree.h" + +namespace Puma { + + +// A match is found. +void CMatchChecker::action (CMatch *matchObj) { + if (! matchObj) return; + CTree *currRoot; + + if (_mode == CTreeMatcher::MATCH_ALL) { + // Save all matches. + _foundMatch = true; + _matchObj->combine (matchObj); + } else if (_mode == CTreeMatcher::MATCH_FIRST) { + // First match found. + _foundMatch = true; + _correct = false; + _matchObj->combine (matchObj); + } else if (_mode == CTreeMatcher::MATCH_LAST) { + // First match found. + if (! _foundMatch) { + _foundMatch = true; + _last.clear (); + _last.combine (_matchObj, true); + // Next match found, could be the last. + } else { + _matchObj->clear (); + _matchObj->combine (&_last, true); + } + + _matchObj->combine (matchObj); + } else if (_mode == CTreeMatcher::MATCH_PRUNE) { + // Match found. + _foundMatch = true; + _matchObj->combine (matchObj); + + // Don't dive into the sons. + if (matchObj->get ("root").length ()) + prune (); + } else if (_mode == CTreeMatcher::MATCH_LEAF) { + if (matchObj->get ("root").length ()) + currRoot = matchObj->get ("root")[0]; + else + currRoot = (CTree*)0; + + // Match found. Check whether the current match is + // a sub-match of a "higher" match. If so, eject the + // "higher" match. + if (_foundMatch) + if (deeper (currRoot, _lastRoot)) { // Match in sub-tree? + _matchObj->clear (); + _matchObj->combine (&_last, true); + } + + _lastRoot = currRoot; + _foundMatch = true; + _last.clear (); + _last.combine (_matchObj, true); + _matchObj->combine (matchObj); + } + + // Don't need it anymore. + delete matchObj; +} + + +// Return true if the first node lays "under" the second. +bool CMatchChecker::deeper (CTree *first, CTree *second) { + if (! second) + return false; + + if (first == second) + return true; + + for (int i = 0; i < second->Sons (); i++) + if (deeper (first, second->Son (i))) + return true; + return false; +} + + +// Stop visiting the sons on MATCH_FIRST, otherwise return true. +bool CMatchChecker::correct (CTree *node) { + if (! _correct) + prune (); + + return _correct; +} + + +// Has the tree matched? +bool CMatchChecker::matchFound () const { + return _foundMatch; +} + + +} // namespace Puma diff --git a/Puma/src/manip/CMatchChecker.h b/Puma/src/manip/CMatchChecker.h new file mode 100644 index 0000000..6632aea --- /dev/null +++ b/Puma/src/manip/CMatchChecker.h @@ -0,0 +1,54 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CMatchChecker__ +#define __CMatchChecker__ + +// Specialized CTreeMatcher implementing action() to +// check whether a syntax tree is matching. + +#include "Puma/CTreeMatcher.h" + +namespace Puma { + + +class CMatchChecker : public CTreeMatcher { + int _mode; + bool _foundMatch; + bool _correct; + CMatch *_matchObj; + CMatch _last; + CTree *_lastRoot; + +private: + void action (CMatch *); + bool correct (CTree *); + bool deeper (CTree *, CTree *); + +public: + CMatchChecker (int mode, CTree *matchTree, CMatch *matchObj) : + CTreeMatcher (matchTree), _mode (mode), _foundMatch (false), + _correct (true), _matchObj (matchObj) {} + + bool matchFound () const; +}; + + +} // namespace Puma + +#endif /* __CMatchChecker__ */ diff --git a/Puma/src/manip/CMatchParser.lem b/Puma/src/manip/CMatchParser.lem new file mode 100644 index 0000000..e82540d --- /dev/null +++ b/Puma/src/manip/CMatchParser.lem @@ -0,0 +1,336 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 + +/* Match-conditionals parser. */ + +%name CMatchParser +%extra_argument {CTreeMatcher::match_state *mstate} + +%token_type {CTree *} +%type conditional {int} +%type tree_match {int} +%type selection {int} +%type match_condition {int} +%type match_mode {int} + +%left M_ELIF. +%left M_OR. +%left M_AND. +%left M_XOR. +%left M_SEQ. +%left M_IF. +%left M_UNARY. + +%include { +#include "Puma/CTreeMatcher.h" +#include "Puma/CMatchParser.h" +#include "Puma/CWildcardTokens.h" +#include "Puma/CTokens.h" +#include "Puma/CTree.h" +#include + +using namespace Puma; + +void *CMatchParserAlloc (void *(*mallocProc)(size_t)); +void CMatchParser (void *pParser, int tokenID, CTree *token, + CTreeMatcher::match_state *mstate); +void CMatchParserFree (void *pParser, void (*freeProc)(void*)); +void CMatchParserTrace (FILE *TraceFILE, char *zTracePrompt); + +namespace Puma { + + +// Traverse the match-condition tree. +void CTreeMatcher::travConditionTree (CTree *node, void *pParser, + match_state *mstate) const { + if (! node || ! pParser || ! mstate) return; + + int id; + CTree *son; + const char *type; + bool element_node = false; + + for (int i = 0; i < node->Sons () && mstate->value != -1; i++) { + son = node->Son (i); + if (! son) + continue; + type = son->NodeName (); + id = MATCHTREE; + + // Visit the current son. + if (type == CT_AnyCondition::NodeId ()) { + if (element_node) + id = M_ELEMENT_NO; + else { + travConditionTree (son, pParser, mstate); + continue; + } + } else if (type == CT_Token::NodeId ()) { + if (! son->token ()) + continue; + + if (son->token ()->is_wildcard ()) { + switch (son->token ()->type ()) { + case TOK_WC_EXACT : id = M_EXACT; break; + case TOK_WC_FIRST : id = M_FIRST; break; + case TOK_WC_LAST : id = M_LAST; break; + case TOK_WC_PRUNE : id = M_PRUNE; break; + case TOK_WC_LEAF : id = M_LEAF; break; + case TOK_WC_COLLECT : id = M_COLLECT; break; + case TOK_WC_NODENAME: id = M_NODENAME; break; + case TOK_WC_NOT : id = M_NOT; break; + case TOK_WC_AND : id = M_AND; break; + case TOK_WC_XOR : id = M_XOR; break; + case TOK_WC_OR : id = M_OR; break; + case TOK_WC_SEQ : id = M_SEQ; break; + case TOK_WC_ELEMENT : id = M_ELEMENT; + element_node = true; + break; + case TOK_WC_ELIF : id = M_ELIF; break; + case TOK_WC_ENDIF : id = M_ENDIF; break; + case TOK_WC_IF : id = M_IF; + mstate->depth++; + mstate->selected[mstate->depth] = 0; + break; + default : id = 0; break; + } + } else if (son->token ()->is_core ()) { + switch (son->token ()->type ()) { + case TOK_OPEN_ROUND : id = M_OPEN_ROUND; break; + case TOK_CLOSE_ROUND: id = M_CLOSE_ROUND; break; + default : id = MATCHTREE; break; + } + } else + id = son->token ()->type (); + } + + // Parse the current node. + CMatchParser (pParser, id, son, mstate); + } +} + +// Evaluate the given match-condition. +bool CTreeMatcher::evalMatchCondition (CTree *tree, CTree *condition, + CMatch *matchObj, int mode) const { + if (! tree || ! condition || ! matchObj) + return false; + + Array selected; + selected[0] = 0; + match_state mstate = {0, tree, matchObj, mode, 0, selected, + (CTreeMatcher*)this}; + + // Generate the Lemon parser. + void *pParser = CMatchParserAlloc ((void* (*)(size_t))malloc); + //CMatchParserTrace(stdout, "TRACE: "); + + // Parse the match-condition tree. + travConditionTree (condition, pParser, &mstate); + + // Finish and then free the parser. + CMatchParser (pParser, 0, (CTree*)0, &mstate); + CMatchParserFree (pParser, (void (*)(void*))::free); + + return (mstate.value <= 0) ? false : true; +} + + +} // namespace Puma +} + +%syntax_error { + mstate->value = -1; +} + +/***********************************************************************/ +/* match-condition ****************************************************/ +/***********************************************************************/ + +match_condition ::= conditional(c). + { + mstate->value = c; + } + +/***********************************************************************/ +/* conditionals ********************************************************/ +/***********************************************************************/ + +conditional(c) ::= M_OPEN_ROUND conditional(co) M_CLOSE_ROUND. + { + c = co; + } +conditional(c) ::= conditional M_SEQ conditional(co2). + { + /* The sequence or implication. */ + /* A B | seq */ + /* ----+----- */ + /* 1 1 | 1 */ + /* 1 0 | 0 */ + /* 0 1 | 1 */ + /* 0 0 | 0 (!) */ + c = co2; + } +conditional(c) ::= conditional(co1) M_OR conditional(co2). + { + /* The alternative. */ + /* A B | or */ + /* ----+----- */ + /* 1 1 | 1 */ + /* 1 0 | 1 */ + /* 0 1 | 1 */ + /* 0 0 | 0 */ + c = (co1 || co2) ? 1 : 0; + } +conditional(c) ::= conditional(co1) M_XOR conditional(co2). + { + /* The exclusive alternative. */ + /* A B | xor */ + /* ----+----- */ + /* 1 1 | 0 */ + /* 1 0 | 1 */ + /* 0 1 | 1 */ + /* 0 0 | 0 */ + c = ((co1 && ! co2) || (! co1 && co2)) ? 1 : 0; + } +conditional(c) ::= conditional(co1) M_AND conditional(co2). + { + /* The conjunction. */ + /* A B | and */ + /* ----+----- */ + /* 1 1 | 1 */ + /* 1 0 | 0 */ + /* 0 1 | 0 */ + /* 0 0 | 0 */ + c = (co1 && co2) ? 1 : 0; + } +conditional(c) ::= M_NOT conditional(co). [M_UNARY] + { + /* The negation. */ + /* A | not */ + /* --+----- */ + /* 1 | 0 */ + /* 0 | 1 */ + c = ! co; + } +conditional(c) ::= M_COLLECT conditional. [M_UNARY] + { + /* The collector. */ + /* A | collect */ + /* --+----- */ + /* 1 | 1 */ + /* 0 | 1 */ + c = 1; + } +conditional(c) ::= M_IF selection(s) M_ENDIF. + { + /* The selection. */ + /* E.g.: if */ + /* elif */ + /* elif */ + /* endif */ + /* The conditionals are evaluated till the first */ + /* true conditional is found. The following elifs */ + /* are skipped and their conditionals are not */ + /* evaluated anymore. */ + c = s; + mstate->depth--; + } +conditional(c) ::= M_NODENAME MATCHTREE(mt). [M_UNARY] + { + /* It's checked whether the root node of the */ + /* current syntax tree has the given name. */ + /* Regular expressions are allowed, too. */ + if (mstate->selected[mstate->depth]) + c = 0; + else + c = mstate->matcher->matchNodeName (mstate->tree, mt); + } +conditional(c) ::= tree_match(tm). + { + c = tm; + } + +/***********************************************************************/ +/* selections **********************************************************/ +/***********************************************************************/ + +selection(s) ::= conditional(c). + { + if (! mstate->selected[mstate->depth]) + s = mstate->selected[mstate->depth] = c; + else + s = 1; + } +selection(s) ::= selection M_ELIF conditional(c). + { + if (! mstate->selected[mstate->depth]) + s = mstate->selected[mstate->depth] = c; + else + s = 1; + } + +/***********************************************************************/ +/* tree matches ********************************************************/ +/***********************************************************************/ + +tree_match(tm) ::= match_mode(m) MATCHTREE(mt). [M_UNARY] + { + if (mstate->selected[mstate->depth]) + tm = 0; + else + tm = mstate->matcher->matchTree (m, *mstate, mstate->tree, mt); + } +tree_match(tm) ::= M_ELEMENT match_mode(m) MATCHTREE(mt). [M_UNARY] + { + if (mstate->selected[mstate->depth]) + tm = 0; + else if (mstate->mode == CTreeMatcher::ANY_LIST) + tm = mstate->matcher->matchList (m, *mstate, mt); + else + tm = mstate->matcher->matchTree (m, *mstate, mstate->tree, mt); + } +tree_match(tm) ::= M_ELEMENT M_ELEMENT_NO(f) match_mode(m) MATCHTREE(mt). [M_UNARY] + { + if (mstate->selected[mstate->depth]) + tm = 0; + else if (mstate->mode == CTreeMatcher::ANY_LIST) + tm = mstate->matcher->matchList (m, *mstate, mt, f); + else + tm = mstate->matcher->matchTree (m, *mstate, mstate->tree, mt); + } +tree_match(tm) ::= M_ELEMENT M_ELEMENT_NO(f) M_ELEMENT_NO(l) match_mode(m) + MATCHTREE(mt). [M_UNARY] + { + if (mstate->selected[mstate->depth]) + tm = 0; + else if (mstate->mode == CTreeMatcher::ANY_LIST) + tm = mstate->matcher->matchList (m, *mstate, mt, f, l); + else + tm = mstate->matcher->matchTree (m, *mstate, mstate->tree, mt); + } + +/***********************************************************************/ +/* match modes *********************************************************/ +/***********************************************************************/ + +match_mode(m) ::= /* empty */. { m = CTreeMatcher::MATCH_ALL; } +match_mode(m) ::= M_EXACT. { m = CTreeMatcher::MATCH_EXACT; } +match_mode(m) ::= M_FIRST. { m = CTreeMatcher::MATCH_FIRST; } +match_mode(m) ::= M_LAST. { m = CTreeMatcher::MATCH_LAST; } +match_mode(m) ::= M_LEAF. { m = CTreeMatcher::MATCH_LEAF; } +match_mode(m) ::= M_PRUNE. { m = CTreeMatcher::MATCH_PRUNE; } diff --git a/Puma/src/manip/CSubMatch.cc b/Puma/src/manip/CSubMatch.cc new file mode 100644 index 0000000..3c5322b --- /dev/null +++ b/Puma/src/manip/CSubMatch.cc @@ -0,0 +1,30 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CSubMatch.h" +#include "Puma/StrCol.h" + +namespace Puma { + + +CSubMatch::CSubMatch (const char *name) { + _name = name ? StrCol::dup (name) : StrCol::dup ("no name"); +} + + +} // namespace Puma diff --git a/Puma/src/manip/CSubMatch.h b/Puma/src/manip/CSubMatch.h new file mode 100644 index 0000000..962dc0a --- /dev/null +++ b/Puma/src/manip/CSubMatch.h @@ -0,0 +1,50 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CSubMatch__ +#define __CSubMatch__ + +// A sub-match consists of a list of matched trees and a name. + +#include "Puma/CTree.h" +#include "Puma/Array.h" + +namespace Puma { + + +class CSubMatch { + Array _trees; // matched sub-trees + const char *_name; // associated name for the sub-match + +public: + CSubMatch (const char *); + ~CSubMatch () { delete[] _name; } + + // get the matched sub-trees + Array &trees () const { return (Array &)_trees; } + unsigned Trees () const { return _trees.length (); } + CTree *Tree (unsigned i) const { return _trees.lookup (i); } + + // get the name of the sub-match + const char *name () const { return _name; } +}; + + +} // namespace Puma + +#endif /* __CSubMatch__ */ diff --git a/Puma/src/manip/CTreeMatcher.cc b/Puma/src/manip/CTreeMatcher.cc new file mode 100644 index 0000000..c07833c --- /dev/null +++ b/Puma/src/manip/CTreeMatcher.cc @@ -0,0 +1,262 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CTranslationUnit.h" +#include "Puma/CTreeMatcher.h" +#include "Puma/CMatchChecker.h" +//#include "Puma/CRankTable.h" +#include "Puma/RegComp.h" +#include "Puma/CTree.h" +#include "Puma/StrCol.h" +#include +#include + +namespace Puma { + + +void CTreeMatcher::init (CTree *matchTree, unsigned int max) { + _max_mobjs = max; + _num_mobjs = 0; + + // Set the current match tree. + _matchTree = matchTree; +} + +void CTreeMatcher::pre_visit (CTree *node) { + // Do nothing on visit if no match tree is given. + if (! _matchTree || ! node) + return; + + // Check whether this node is really the expected node and not + // maybe someone that only looks like it. + if (! correct (node)) + return; + + // If the match tree can't be a sub tree of the current C++ syntax + // tree node, trying to match this node and its sons is skipped. +// if (CRankTable::Rank (node->astName ()) < +// CRankTable::Rank (_matchTree->astName ())) +// return; + + // Create CMatch object and add the current node to it. + CMatch *matchObj = new CMatch; + matchObj->add (node, "root"); + + // If the current sub-tree is matching the match tree, call + // action() with the current node and the nodes that correspond + // with the any-nodes of the match tree as arguments. + if (match (node, _matchTree, matchObj)) { + _num_mobjs++; + action (matchObj); + if (_max_mobjs <= _num_mobjs && _max_mobjs != 0) + abort (); // Abort traversing the syntax tree! + } + // Not matching. Delete the match object. + else + delete matchObj; +} + +// Return true if the current sub-tree is matching the match tree. +bool CTreeMatcher::match (CTree *currTree, CTree *matchTree, + CMatch* matchObj) const { + if (! currTree || ! matchTree || ! matchObj) + return false; + + // Don't compare against CT_ImplicitCast nodes. + while (currTree->NodeName () == CT_ImplicitCast::NodeId ()) + currTree = currTree->Son (0); + + // The current node of the match tree is an Any node. + if (matchTree->NodeName () == CT_Any::NodeId () || + matchTree->NodeName () == CT_AnyList::NodeId ()) { + CT_AnyExtension *ext = ((CT_Any*)matchTree)->Extension (); + CTree *condition = ext ? ext->Condition () : (CTree*)0; + const char *name = ext ? ext->Name () : (const char*)0; + Array *old = &matchObj->get (name); + + // If there already is an Any node with that name, it has + // to be checked whether the two trees are the same. + if (old->length ()) + if (! match (old->get (0), currTree, matchObj)) + return false; + + // If there is no extra condition for matching with this + // any-node, the current tree node always is matching. + if (condition) { + int mode = 0; + + // Tell the match-parser which condition keywords are allowed. + if (matchTree->NodeName () == CT_Any::NodeId ()) + mode = ANY; + else if (matchTree->NodeName () == CT_AnyList::NodeId ()) + mode = ANY_LIST; + + if (! evalMatchCondition (currTree, condition, matchObj, mode)) + return false; + } + + // Remember anys with a name only. + if (name) + matchObj->add (currTree, name); + + return true; + } + + // If the current node of the match tree isn't an any-node + // the two current nodes must be of the same type and must + // have the same number of sons. + if (currTree->NodeName () != matchTree->NodeName () || + currTree->Sons () != matchTree->Sons ()) + return false; + + // The current nodes are tokens. The text of the tokens + // must be the same. + if (currTree->NodeName () == CT_Token::NodeId ()) { + if (! currTree->token () || ! matchTree->token ()) + return false; + if (! currTree->token ()->text () || ! matchTree->token ()->text ()) + return false; + if (strcmp (currTree->token ()->text (), + matchTree->token ()->text ()) != 0) + return false; + } + + // Now call match() for every son of the current node. + for (int i = 0; i < currTree->Sons (); i++) + if (! match (currTree->Son (i), matchTree->Son (i), matchObj)) + return false; + + // The current C++ sub-tree is matching the current sub-tree + // of the match tree. + return true; +} + +// Match any node-list. +int CTreeMatcher::matchList (int mode, match_state &mstate, + CTree *mt, CTree *f, CTree *l) const { + bool matched = false; + CT_List *list = (CT_List*)mstate.tree; + int elements = list->Entries (); + int sign_f = 0, sign_l = 0; + + if (f) { + sign_f = (f->token ()->text ()[0] == '-') ? -1 : 1; + f = f->Son (f->Sons () - 1); + } + if (l) { + sign_l = (l->token ()->text ()[0] == '-') ? -1 : 1; + l = l->Son (l->Sons () - 1); + } + + // Get the arguments. + int first = (f) ? (sign_f * (int) strtol (f->token ()->text (), NULL, 10)) : 1; + int last = (l) ? (sign_l * (int) strtol (l->token ()->text (), NULL, 10)) : elements; + + // Compute the real element number. + if (first < 0) first = elements + first + 1; + if (last < 0) last = elements + last + 1; + + // Wrong arguments? + if (first <= 0 || last <= 0) + return 0; + + // The current list has too few elements. + if (first > elements || last > elements) + return 0; + + // If the two arguments have the same value, the user wanted + // to match lists that have exact the given number of elements. + if (first == last && f && l) { + if (first != elements) + return 0; + + first = 1; + last = elements; + } + + // Match a single element. + if (f && ! l) + last = first; + + // Match the list elements. + for (int i = first; i <= last; i++) + if (matchTree (mode, mstate, list->Entry (i - 1), mt)) + matched = true; + + // Return the success value. + return matched ? 1 : 0; +} + +// Match any node. +int CTreeMatcher::matchTree (int mode, match_state &mstate, CTree *tree, + CTree *mt) const { + int matched = 0; + CMatch tmp; + + if (mode == MATCH_ALL || + mode == MATCH_FIRST || + mode == MATCH_LAST || + mode == MATCH_PRUNE || + mode == MATCH_LEAF) { + CMatchChecker check (mode, mt, &tmp); + check.visit (tree); + matched = (check.matchFound ()) ? 1 : 0; + } + else if (mode == MATCH_EXACT) + matched = (match (tree, mt, &tmp)) ? 1 : 0; + + // Remember all the matches. + if (matched) + mstate.matchObj->combine (&tmp); + + return matched; +} + +// Match a node by its name. Regular expressions are allowed. +int CTreeMatcher::matchNodeName (CTree *tree, CTree *mt) const { + if (! mt || ! tree) + return 0; + if (mt->NodeName () != CT_String::NodeId ()) + return 0; + + char *string = StrCol::dup (mt->token ()->text () + 1); + string[strlen (string) - 1] = '\0'; + + RegComp compare (string); + bool matching = compare.match ((const char*)tree->NodeName ()); + delete[] string; + return matching ? 1 : 0; +} + +// Start the match process. +void CTreeMatcher::match (CTranslationUnit &tUnit, + CTranslationUnit &matchUnit, CTree *syntaxtree) { + // Do the manipulations only if there really is a syntax tree. + CTree *matchtree = matchUnit.tree (); + if (! syntaxtree) + syntaxtree = tUnit.tree (); + if (syntaxtree) { + init (matchtree); +// tUnit.cppTree ()->context ().push (); + visit (syntaxtree); +// tUnit.cppTree ()->context ().pop (); + } +} + + +} // namespace Puma diff --git a/Puma/src/manip/CTreeMatcher.h b/Puma/src/manip/CTreeMatcher.h new file mode 100644 index 0000000..67cc1eb --- /dev/null +++ b/Puma/src/manip/CTreeMatcher.h @@ -0,0 +1,111 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CTreeMatcher__ +#define __CTreeMatcher__ + +// Base class for syntax tree match visitors. + +#include "Puma/CTranslationUnit.h" +#include "Puma/CVisitor.h" +#include "Puma/CMatch.h" +#include "Puma/Array.h" + +namespace Puma { + + +class CTree; +class CT_AnyExtension; + +class CTreeMatcher : public CVisitor { + CTree *_matchTree; + int _num_mobjs; + int _max_mobjs; + +public: + enum { + ANY = 1, // Shows the match-parser which keywords + ANY_LIST, // are allowed. + MATCH_ALL, // Possible match modes. + MATCH_EXACT, + MATCH_FIRST, + MATCH_LAST, + MATCH_LEAF, + MATCH_PRUNE + }; + + // Match-condition parser state. + struct match_state { + int value; // Value of the condition (-1 on errors). + CTree *tree; // The tree to match with. + CMatch *matchObj; // To fill with the anys of the condition. + int mode; // Is ANY or ANY_LIST. + int depth; // Selection depth. + Array &selected; // Selection state. + CTreeMatcher *matcher; // To call match() on it. + }; + +public: + CTreeMatcher (unsigned int max = 0) : + _num_mobjs (0), _max_mobjs (max) {} + CTreeMatcher (CTree *matchTree, unsigned int max = 0) + { init (matchTree, max); } + virtual ~CTreeMatcher () {} + + // Initialize the matcher. + void init (CTree *matchTree, unsigned int max = 0); + + // Check whether the two trees are matching. + bool match (CTree *, CTree *, CMatch *) const; + + // Should be specialized by derived classes. + virtual void action (CMatch *match) + { if (match) delete match; } + + // Make a first check whether the current visited node is the + // expected root node of the tree to match. + virtual bool correct (CTree *node) + { return true; } + + // Start the match process. + virtual void match (CTranslationUnit &, CTranslationUnit &, + CTree * = (CTree*)0); + + // Match any node, a list of nodes, or a node by its name. + // !!! TO BE USED BY THE MATCH PARSER ONLY !!! + int matchTree (int, match_state &, CTree *, CTree *) const; + int matchList (int, match_state &, CTree *, CTree * = (CTree*)0, + CTree * = (CTree*)0) const; + int matchNodeName (CTree *, CTree *) const; + +private: + // Traverses the match-condition tree. + void travConditionTree (CTree *, void *, match_state *) const; + + // Evaluates the given match-condition. + bool evalMatchCondition (CTree *, CTree *, CMatch *, int) const; + + // Is called on visit before visiting the sons. + // Starts the matching action. + void pre_visit (CTree *node); +}; + + +} // namespace Puma + +#endif /* __CTreeMatcher__ */ diff --git a/Puma/src/manip/ManipCommander.cc b/Puma/src/manip/ManipCommander.cc new file mode 100644 index 0000000..6d77789 --- /dev/null +++ b/Puma/src/manip/ManipCommander.cc @@ -0,0 +1,376 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/ManipCommander.h" +#include "Puma/MacroUnit.h" +#include "Puma/CTree.h" +#include + +namespace Puma { + + +ManipCommander::~ManipCommander () { + clear (); +} + + +ManipError ManipCommander::valid () const { + return _commands.valid (_manip_mode); +} + + +void ManipCommander::clear () { + for (std::list::iterator iter = _buffers.begin (); iter != _buffers.end (); + ++iter) + delete *iter; + _buffers.clear (); + _commands.clear (); + _ignore = MIM_NONE; + _expanded_macro_units.clear (); +} + + +Unit *ManipCommander::newBuffer () { + Unit *buffer = new Unit (); + addBuffer (buffer); + return buffer; +} + + +void ManipCommander::addBuffer (Unit *buffer) { + assert (buffer); + _buffers.push_back (buffer); +} + + +Token *ManipCommander::getStartToken (Token *token) { + if (token && token->is_macro_generated ()) { + MacroUnit *macro = (MacroUnit*)token->belonging_to (); + if (macro) { + if (_manip_mode != MM_EXPAND_MACROS) { + Token *macro_call_start = macro->ExpansionBegin (token); + if (macro_call_start) + token = macro_call_start; + } + else if (token->is_macro_generated ()) + auto_expand_macro (macro); + } + } + return token; +} + + +Token *ManipCommander::getEndToken (Token *token) { + if (token && token->is_macro_generated ()) { + MacroUnit *macro = (MacroUnit*)token->belonging_to (); + if (macro) { + if (_manip_mode != MM_EXPAND_MACROS) { + Token *macro_call_end = macro->ExpansionEnd (token); + if (macro_call_end) + token = macro_call_end; + } + else if (token->is_macro_generated ()) + auto_expand_macro (macro); + } + } + return token; +} + + +void ManipCommander::auto_expand_macro (MacroUnit *macro) { + std::pair::iterator,bool> ret = _expanded_macro_units.insert (macro); + if (!ret.second) return; // macro has already been expanded + + // expand enclosing macros recursively + Token *macro_call_begin = macro->MacroBegin (); + Token *macro_call_end = macro->MacroEnd (); + if (macro_call_begin->is_macro_generated ()) { + MacroUnit *macro_call_unit = (MacroUnit*)macro_call_begin->belonging_to (); + auto_expand_macro (macro_call_unit); + } + + // issue tranformation commands that replace the macro call by the macro expansion unit + add (new CMoveBeforeManipulator ((Token*)macro->first (), + (Token*)macro->last (), macro_call_begin)); + if (macro_call_begin->unit () == macro_call_end->unit ()) + add (new KillManipulator (macro_call_begin, macro->MacroEnd ())); + else { + // The macro name was generated; arguments are from somewhere else + Unit *caller = macro_call_begin->unit (); + // Remove start of macro call + add (new KillManipulator (macro_call_begin, (Token*)caller->last ())); + // Remove end of macro call + while (caller->isMacroExp () && + ((MacroUnit*)caller)->MacroEnd ()->unit () != macro_call_end->unit ()) + caller = ((MacroUnit*)caller)->MacroBegin ()->unit (); + add (new KillManipulator (macro_call_end->unit ()->next (((MacroUnit*)caller)->MacroEnd ()), + macro_call_end)); + } +} + + +void ManipCommander::commit () { + _commands.manipulate (); + clear (); +} + + +void ManipCommander::commit (ManipController &mc) { + Manipulator *curr = (Manipulator*) _commands.first (); + Array *arguments; + const char *op; + + for (; curr; curr = (Manipulator*) _commands.next (curr)) { + op = curr->op (); + arguments = &curr->args (); + + if (op && arguments) { + if (op == Manipulator::paste_op || + op == Manipulator::paste_before_op) { + if (! mc.permitted (arguments->get (0))) continue; + } else if (op == Manipulator::cpp_copy_op || + op == Manipulator::cpp_copy_before_op) { + if (! mc.permitted (arguments->get (2))) continue; + } else if (op == Manipulator::cut_op || + op == Manipulator::kill_op || + op == Manipulator::cpp_kill_op) { + if (! mc.permitted (arguments->get (0))) continue; + if (! mc.permitted (arguments->get (1))) continue; + } else if (op == Manipulator::cpp_move_op || + op == Manipulator::cpp_move_before_op) { + if (! mc.permitted (arguments->get (0))) continue; + if (! mc.permitted (arguments->get (1))) continue; + if (! mc.permitted (arguments->get (2))) continue; + } else if (op == Manipulator::cpp_replace_op || + op == Manipulator::cpp_swap_op) { + if (! mc.permitted (arguments->get (0))) continue; + if (! mc.permitted (arguments->get (1))) continue; + if (! mc.permitted (arguments->get (2))) continue; + if (! mc.permitted (arguments->get (3))) continue; + } + } + + // Do the manipulation. + curr->manipulate (); + } + + clear (); +} + + +void ManipCommander::add (Manipulator *manip) { + assert (manip); + if (manip_mode () == MM_EXPAND_MACROS) + manip->ignore_mask ((ManipIgnoreMask)(_ignore | MIM_MACRO)); + else + manip->ignore_mask (_ignore); + _commands.append (manip); +} + + +////////////////////////////////////////////////////////////////////// +// Low level manipulators (may use extern buffers too). ////////////// +////////////////////////////////////////////////////////////////////// + + +void ManipCommander::cut (Unit *buffer, Token *from, Token *to) { + from = getStartToken (from); + to = getEndToken (to); + Manipulator *cut = new CutManipulator (buffer, from, to ? to : from); + add (cut); +} + + +void ManipCommander::copy (Unit *buffer, Token *from, Token *to) { + from = getStartToken (from); + to = getEndToken (to); + Manipulator *copy = new CopyManipulator (buffer, from, to ? to : from); + add (copy); +} + + +void ManipCommander::kill (Token *from, Token *to) { + from = getStartToken (from); + to = getEndToken (to); + Manipulator *kill = new KillManipulator (from, to ? to : from); + add (kill); +} + + +void ManipCommander::paste (Token *at, Unit *buffer) { + at = getEndToken (at); + Manipulator *paste = new PasteManipulator (buffer, at); + add (paste); +} + + +void ManipCommander::paste_before (Token *at, Unit *buffer) { + at = getStartToken (at); + Manipulator *paste_before = new PasteBeforeManipulator (buffer, at); + add (paste_before); +} + + +////////////////////////////////////////////////////////////////////// +// Composed manipulators. //////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// + + +void ManipCommander::paste (Token *at, Token *which) { + copy (which, which, at); +} + + +void ManipCommander::paste_before (Token *at, Token *which) { + copy_before (which, which, at); +} + + +void ManipCommander::replace (Token *which, Token *with) { + paste (which, with); + kill (which); +} + + +void ManipCommander::copy (Token *from, Token *to, Token *at) { + from = getStartToken (from); + to = getEndToken (to); + at = getEndToken (at); + Manipulator *copy = new CCopyManipulator (from, to, at); + add (copy); +} + + +void ManipCommander::copy_before (Token *from, Token *to, Token *at) { + from = getStartToken (from); + to = getEndToken (to); + at = getStartToken (at); + Manipulator *copy_before = new CCopyBeforeManipulator (from, to, at); + add (copy_before); +} + + +void ManipCommander::move (Token *from, Token *to, Token *at) { + from = getStartToken (from); + to = getEndToken (to); + at = getEndToken (at); + Manipulator *move = new CMoveManipulator (from, to, at); + add (move); +} + + +void ManipCommander::move_before (Token *from, Token *to, Token *at) { + from = getStartToken (from); + to = getEndToken (to); + at = getStartToken (at); + Manipulator *move_before = new CMoveBeforeManipulator (from, to, at); + add (move_before); +} + + +void ManipCommander::replace (Token *wf, Token *wt, Token *tf, Token *tt) { + wf = getStartToken (wf); + wt = getEndToken (wt); + tf = getStartToken (tf); + tt = getEndToken (tt); + Manipulator *replace = new CReplaceManipulator (wf, wt, tf, tt); + add (replace); +} + + +void ManipCommander::swap (Token *wf, Token *wt, Token *tf, Token *tt) { + wf = getStartToken (wf); + wt = getEndToken (wt); + tf = getStartToken (tf); + tt = getEndToken (tt); + Manipulator *swap = new CSwapManipulator (wf, wt, tf, tt); + add (swap); +} + + + +////////////////////////////////////////////////////////////////////// +// Special C++ syntax tree manipulator interfaces. /////////////////// +////////////////////////////////////////////////////////////////////// + + +void ManipCommander::kill (CTree *what) { + Token *f = getStartToken (what ? what->token () : (Token*)0); + Token *t = getEndToken (what ? what->end_token () : (Token*)0); + Manipulator *kill = new CKillManipulator (f, t); + add (kill); +} + + +void ManipCommander::copy (CTree *from, CTree *to) { + Token *f = getStartToken (from ? from->token () : (Token*)0); + Token *t = getEndToken (from ? from->end_token () : (Token*)0); + Token *a = getEndToken (to ? to->end_token () : (Token*)0); + Manipulator *copy = new CCopyManipulator (f, t, a); + add (copy); +} + + +void ManipCommander::copy_before (CTree *from, CTree *to) { + Token *f = getStartToken (from ? from->token () : (Token*)0); + Token *t = getEndToken (from ? from->end_token () : (Token*)0); + Token *a = getStartToken (to ? to->token () : (Token*)0); + Manipulator *copy_before = new CCopyBeforeManipulator (f, t, a); + add (copy_before); +} + + +void ManipCommander::move (CTree *from, CTree *to) { + Token *f = getStartToken (from ? from->token () : (Token*)0); + Token *t = getEndToken (from ? from->end_token () : (Token*)0); + Token *a = getEndToken (to ? to->end_token () : (Token*)0); + Manipulator *move = new CMoveManipulator (f, t, a); + add (move); +} + + +void ManipCommander::move_before (CTree *from, CTree *to) { + Token *f = getStartToken (from ? from->token () : (Token*)0); + Token *t = getEndToken (from ? from->end_token () : (Token*)0); + Token *a = getStartToken (to ? to->token () : (Token*)0); + Manipulator *move_before = new CMoveBeforeManipulator (f, t, a); + add (move_before); +} + + +void ManipCommander::replace (CTree *what, CTree *with) { + Token *wf = getStartToken (what ? what->token () : (Token*)0); + Token *wt = getEndToken (what ? what->end_token () : (Token*)0); + Token *tf = getStartToken (with ? with->token () : (Token*)0); + Token *tt = getEndToken (with ? with->end_token () : (Token*)0); + Manipulator *replace = new CReplaceManipulator (wf, wt, tf, tt); + add (replace); +} + + +void ManipCommander::swap (CTree *what, CTree *with) { + Token *wf = getStartToken (what ? what->token () : (Token*)0); + Token *wt = getEndToken (what ? what->end_token () : (Token*)0); + Token *tf = getStartToken (with ? with->token () : (Token*)0); + Token *tt = getEndToken (with ? with->end_token () : (Token*)0); + Manipulator *swap = new CSwapManipulator (wf, wt, tf, tt); + add (swap); +} + + +} // namespace Puma diff --git a/Puma/src/manip/ManipCommander.h b/Puma/src/manip/ManipCommander.h new file mode 100644 index 0000000..45d2c9b --- /dev/null +++ b/Puma/src/manip/ManipCommander.h @@ -0,0 +1,103 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __ManipCommander__ +#define __ManipCommander__ + +/** \file + * Token chain manipulation. */ + +/** \page transformation Transformation + */ + +#include +#include + +#include "Puma/ManipController.h" +#include "Puma/Manipulators.h" + +namespace Puma { + +class MacroUnit; + +class ManipCommander { + ManipulatorSequence _commands; + std::list _buffers; + ManipIgnoreMask _ignore; + std::set _expanded_macro_units; + ManipMode _manip_mode; + +public: + ManipCommander () : _ignore (MIM_NONE), _manip_mode (MM_NO_MACRO_MANIP) {} + ~ManipCommander (); + + Unit *newBuffer (); + void addBuffer (Unit *); + + ManipError valid () const; + void commit (); + void commit (ManipController &); + void add (Manipulator *); + void clear (); + + // set/get the ignore mask + void ignore_mask (ManipIgnoreMask mim) { _ignore = mim; } + ManipIgnoreMask ignore_mask () const { return _ignore; } + + // set/get the manipulation mode + void manip_mode (ManipMode mm) { _manip_mode = mm; } + ManipMode manip_mode () const { return _manip_mode; } + + // Low level manipulators using named intern buffers + // (or a no-name shared buffer). Some may use extern buffers too. + void cut (Unit *buffer, Token *from, Token *to = (Token*) 0); + void copy (Unit *buffer, Token *from, Token *to = (Token*) 0); + void kill (Token *from, Token *to = (Token*) 0); + void paste (Token *behind, Unit*); + void paste_before (Token *before, Unit*); + + // Composed manipulators. + void paste (Token *behind, Token *which); + void paste_before (Token *before, Token *which); + void replace (Token *which, Token *with); + void copy (Token *from, Token *to, Token *behind); + void move (Token *from, Token *to, Token *behind); + void copy_before (Token *from, Token *to, Token *before); + void move_before (Token *from, Token *to, Token *before); + void replace (Token *from1, Token *to1, Token *from2, Token *to2); + void swap (Token *from1, Token *to1, Token *from2, Token *to2); + + // Special C++ syntax tree manipulator interfaces. + void kill (CTree *what); + void copy (CTree *what, CTree *behind); + void move (CTree *what, CTree *behind); + void copy_before (CTree *what, CTree *before); + void move_before (CTree *what, CTree *before); + void replace (CTree *what, CTree *with); + void swap (CTree *what, CTree *with); + +private: + Token *getStartToken (Token *); + Token *getEndToken (Token *); + void auto_expand_macro (MacroUnit *macro); +}; + + +} // namespace Puma + +#endif /* __ManipCommander__ */ diff --git a/Puma/src/manip/ManipController.cc b/Puma/src/manip/ManipController.cc new file mode 100644 index 0000000..36689bd --- /dev/null +++ b/Puma/src/manip/ManipController.cc @@ -0,0 +1,59 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/ManipController.h" +#include "Puma/Token.h" +#include "Puma/Unit.h" + +namespace Puma { + + +// Reset the controller for the next run. +void ManipController::reset () { + _excluded.reset (); + _in_progress.reset (); +} + +// All manipulated units are excluded to be manipulated again. +void ManipController::exclude () { + for (long i = 0; i < _in_progress.length (); i++) + _excluded.append (_in_progress[i]); + _in_progress.reset (); +} + +// Is the unit, the token belongs to, permitted to be manipulated? +bool ManipController::permitted (Token *token) { + if (! token) return true; + Unit *unit = (Unit*)token->belonging_to (); + if (! unit) return true; + + for (long i = 0; i < _excluded.length (); i++) + if (unit == _excluded[i]) + return false; + + // Do not add a unit twice. + for (long i = 0; i < _in_progress.length (); i++) + if (unit == _in_progress[i]) + return true; + + _in_progress.append (unit); + return true; +} + + +} // namespace Puma diff --git a/Puma/src/manip/ManipController.h b/Puma/src/manip/ManipController.h new file mode 100644 index 0000000..87d2639 --- /dev/null +++ b/Puma/src/manip/ManipController.h @@ -0,0 +1,50 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __ManipController__ +#define __ManipController__ + +// Decide whether a manipulation is allowed to be executed or not. + +#include "Puma/Array.h" + +namespace Puma { + + +class Unit; +class Token; + +class ManipController { + Array _excluded; + Array _in_progress; + +public: + // Reset the controller for the next run. + void reset (); + + // All manipulated units are excluded to be manipulated again. + void exclude (); + + // Is the unit, the token belongs to, permitted to be manipulated? + bool permitted (Token *); +}; + + +} // namespace Puma + +#endif /* __ManipController__ */ diff --git a/Puma/src/manip/Manipulators.cc b/Puma/src/manip/Manipulators.cc new file mode 100644 index 0000000..6b9bd34 --- /dev/null +++ b/Puma/src/manip/Manipulators.cc @@ -0,0 +1,1087 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/Manipulators.h" +#include "Puma/MacroUnit.h" +#include "Puma/PreParser.h" +#include + +namespace Puma { + + +////////////////////////////////////////////////////////////////////// +// Manipulator identification constants. ///////////////////////////// +////////////////////////////////////////////////////////////////////// + +const char *Manipulator::sequence_op = "sequence"; +const char *Manipulator::copy_op = "copy"; +const char *Manipulator::cut_op = "cut"; +const char *Manipulator::paste_op = "paste"; +const char *Manipulator::paste_before_op = "paste_before"; +const char *Manipulator::move_op = "move"; +const char *Manipulator::move_before_op = "move_before"; +const char *Manipulator::kill_op = "kill"; +const char *Manipulator::cpp_copy_op = "cpp_copy"; +const char *Manipulator::cpp_copy_before_op = "cpp_copy_before"; +const char *Manipulator::cpp_kill_op = "cpp_kill"; +const char *Manipulator::cpp_move_op = "cpp_move"; +const char *Manipulator::cpp_move_before_op = "cpp_move_before"; +const char *Manipulator::cpp_replace_op = "cpp_replace"; +const char *Manipulator::cpp_swap_op = "cpp_swap"; + + +// I hope there is a first arg ... +Location ManipError::location () { + if (faulty () && faulty ()->args ().length ()) + if (faulty ()->args ()[0]) + return faulty ()->args ()[0]->location (); + + static Location loc; + return loc; +} + + +// Print a manipulation error code +void ManipError::print (std::ostream &os) const { + switch (errorno ()) { + case FATAL: + os << "fatal error: Can't do `" << (faulty () ? faulty ()->op () : "") + << "' manipulation"; break; + case MACRO_GEN: + os << "error: Can't `" << (faulty () ? faulty ()->op () : "") + << "' if start/end token is macro generated"; break; + case BAD_ARG: + os << "error: Bad argument(s) for the `" + << (faulty () ? faulty ()->op () : "") + << "' manipulator"; break; + case UNBALANCED: + os << "error: Unbalanced preprocessor directive(s) " + << "found. Can't do `" << (faulty () ? faulty ()->op () : "") + << "' manipulation"; break; + } + + if (faulty ()) { + os << " (Args: "; + for (int a = 0; a < faulty ()->args ().length (); a++) { + Token *tok = faulty ()->args ().get (a); + if (!tok) continue; + if (a > 0) os << ", "; + Unit *unit = (Unit*)tok->belonging_to (); + if (unit->isMacroExp ()) { +// MacroUnit *munit = (MacroUnit*)unit; +// tok = munit->ExpansionBegin ((Token*)munit->first ()); + os << "macro at "; + } + os << tok->location (); + } + os << ")."; + } +} + + +// Return positiv value if the tokens between start and end are +// valid, that means: +// - start token is not NULL +// - start and end token belong to the same unit and aren't result +// of a macro expansion +// - only balanced preprocessor directives inside of the manipulation +// range + +int Manipulator::valid (Token *start, Token *end, ManipMode mode) const { + if (! start) return ManipError::BAD_ARG; + if (!(_ignore & MIM_MACRO) && start->is_macro_generated ()) return ManipError::MACRO_GEN; + if (! end) return ManipError::OK; + if (!(_ignore & MIM_MACRO) && end->is_macro_generated ()) return ManipError::MACRO_GEN; + if (start == end) return ManipError::OK; + + if (_ignore & MIM_UNBALANCED || mode == MM_EXPAND_MACROS) + return ManipError::OK; + + int balance = 0; + Token *token = start; + Unit *unit = token->unit (); + while (token) { + if (token->is_preprocessor ()) { + switch (token->type ()) { + case TOK_PRE_IF: + case TOK_PRE_IFDEF: + case TOK_PRE_IFNDEF: + balance++; + break; + case TOK_PRE_ELIF: + if (! balance) + return ManipError::UNBALANCED; + break; + case TOK_PRE_ELSE: + if (! balance) + return ManipError::UNBALANCED; + break; + case TOK_PRE_ENDIF: + balance--; + break; + } + } + + if (token == end) { + if (balance == 0) + return ManipError::OK; + else + return ManipError::UNBALANCED; + } + + token = (Token*) unit->next (token); + } + + // Should only be reached on fatal errors (maybe start and end + // token belong to different units). + return ManipError::FATAL; +} + + +////////////////////////////////////////////////////////////////////// +// The manipulator sequence. ///////////////////////////////////////// +////////////////////////////////////////////////////////////////////// + + +ListElement *ManipulatorSequence::duplicate () { + ManipulatorSequence *dup = new ManipulatorSequence (); + *dup += *this; + dup->_rules += _rules; + return dup; +} + + +// Ask every manipulator of the sequence whether its manipulation +// can be done. + +ManipError ManipulatorSequence::valid (ManipMode mode) const { + ManipError error; + Manipulator *curr = (Manipulator*) first (); + + for (; curr; curr = (Manipulator*) next (curr)) + if (curr->valid (mode).errorno () != ManipError::OK) + return curr->valid (mode); + + error.errorno (error.OK); + return error; +} + + +// Special manipulator class that manages a sequence of +// manipulator commands. + +void ManipulatorSequence::manipulate () { + Manipulator *curr = (Manipulator*) first (); + Array *arguments; + ManipError error; + const char *op; + + for (; curr; curr = (Manipulator*) next (curr)) { + // Check the arguments of a manipulator. + checkArgs (error, curr); + if (error.errorno () != error.OK) + continue; + + // Do the manipulation. + curr->manipulate (); + + arguments = &curr->args (); + op = curr->op (); + + if (! op || ! arguments) continue; + + // Update the rule table. + if (op == cut_op || op == kill_op || op == cpp_kill_op) { + _rules.add (arguments->get (0)/*, arguments->get (2)*/); + _rules.add (arguments->get (1)/*, arguments->get (3)*/); + //} else if (op == cpp_move_op || op == cpp_move_before_op) { + //_rules.add (arguments->get (0), arguments->get (3)); + //_rules.add (arguments->get (1), arguments->get (4)); + } else if (op == cpp_replace_op) { + _rules.add (arguments->get (0), arguments->get (4)); + _rules.add (arguments->get (1), arguments->get (5)); + } else if (op == cpp_swap_op) { + _rules.add (arguments->get (0), arguments->get (4)); + _rules.add (arguments->get (1), arguments->get (5)); + _rules.add (arguments->get (2), arguments->get (6)); + _rules.add (arguments->get (3), arguments->get (7)); + } + } + clear (); + _rules.clear (); +} + + +// Check the arguments of a manipulator. + +void ManipulatorSequence::checkArgs (ManipError &error, Manipulator *curr) { + Token *arg, *back; + Array array (4); + int length = curr->args ().length (); + + // Check every argument of the current manipulator. + for (int i = 0; i < length; i++) { + // Get the current argument. + arg = curr->args ()[i]; + + // Check the current argument. + back = _rules.get (arg); + + // If we've got a NULL pointer, the manipulation would + // be done on a not existing token => fatal error. + if (! back) { + error.faulty (curr); + error.errorno (ManipError::BAD_ARG); + return; + } + + // Build the correction argument array. + array.append (back); + } + + // Correct the arguments. + curr->args (array); + + // All is right. + error.errorno (ManipError::OK); +} + + +////////////////////////////////////////////////////////////////////// +// The `copy' manipulator. /////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// + + +void CopyManipulator::args (Array &arguments) { + _from = arguments[0]; + _to = arguments[1]; + _arguments[0] = _from; + _arguments[1] = _to; +} + +CopyManipulator::CopyManipulator (Unit *buffer, Token *from, Token *to) { + _buffer = buffer; + _from = from; + _to = to; + _arguments.append (_from); + _arguments.append (_to); +} + +ManipError CopyManipulator::valid (ManipMode mode) const { + ManipError error; + error.faulty ((CopyManipulator*) this); + + if (! _buffer) { // Error, illegal buffer. + error.errorno (error.FATAL); + return error; + } + + error.errorno (Manipulator::valid (_from, _to, mode)); + return error; +} + +void CopyManipulator::manipulate () { + assert (_buffer); + assert (_from); + assert (_to); + + List *l = _from->belonging_to (); + if (! l) l = _buffer; + List *res = l->copy (_from, _to); + ((Unit*) l)->state ().modified (); + + assert (res); + + *_buffer += *res; + delete res; +} + + +////////////////////////////////////////////////////////////////////// +// The `cut' manipulator. //////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// + + +void CutManipulator::args (Array &arguments) { + _from = arguments[0]; + _to = arguments[1]; + _arguments[0] = _from; + _arguments[1] = _to; + assert (_from->belonging_to ()); + assert (_to->belonging_to ()); +} + +CutManipulator::CutManipulator (Unit *buffer, Token *from, Token *to) { + _buffer = buffer; + _from = from; + _to = to; + _arguments.append (_from); + _arguments.append (_to); + assert (_from->belonging_to ()); + assert (_to->belonging_to ()); +} + +ManipError CutManipulator::valid (ManipMode mode) const { + ManipError error; + error.faulty ((CutManipulator*) this); + + if (! _buffer) { // Error, illegal buffer. + error.errorno (error.FATAL); + return error; + } + + error.errorno (Manipulator::valid (_from, _to, mode)); + return error; +} + +void CutManipulator::manipulate () { + assert (_buffer); + assert (_from); + assert (_to); + + List *l = _from->belonging_to (); + if (! l) l = _buffer; + +// _arguments[2] = (Token*) l->prev (_from); +// if (! _arguments[2]) +// _arguments[2] = (Token*) l->next (_from); +// _arguments[3] = (Token*) l->next (_to); +// if (! _arguments[3]) +// _arguments[3] = (Token*) l->prev (_to); + + l->cut (*_buffer, _from, _to); + ((Unit*) l)->state ().modified (); +} + + +////////////////////////////////////////////////////////////////////// +// The `kill' manipulator. /////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// + + +void KillManipulator::args (Array &arguments) { + _from = arguments[0]; + _to = arguments[1]; + _arguments[0] = _from; + _arguments[1] = _to; + assert (_from->belonging_to ()); + assert (_to->belonging_to ()); +} + +KillManipulator::KillManipulator (Token *from, Token *to) { + _from = from; + _to = to; + _arguments.append (_from); + _arguments.append (_to); + assert (_from->belonging_to ()); + assert (_to->belonging_to ()); +} + +ManipError KillManipulator::valid (ManipMode mode) const { + ManipError error; + error.faulty ((KillManipulator*) this); + + error.errorno (Manipulator::valid (_from, _to, mode)); + return error; +} + +void KillManipulator::manipulate () { + assert (_from); + assert (_to); + + List *l = _from->belonging_to (); + if (l) { + //_arguments[2] = (Token*) l->prev (_from); + //if (! _arguments[2]) + // _arguments[2] = (Token*) l->next (_from); + //_arguments[3] = (Token*) l->next (_to); + //if (! _arguments[3]) + // _arguments[3] = (Token*) l->prev (_to); + + l->kill (_from, _to); + ((Unit*) l)->state ().modified (); + } else { + //_arguments[2] = (Token*) 0; + //_arguments[3] = (Token*) 0; + + Unit unit; + unit.kill (_from, _to); + } +} + + +////////////////////////////////////////////////////////////////////// +// The `paste' manipulator. ////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// + + +void PasteManipulator::args (Array &arguments) { + _at = arguments[0]; + _arguments[0] = _at; +} + +PasteManipulator::PasteManipulator (Unit *buffer, Token *at) { + _buffer = buffer; + _at = at; + _arguments.append (_at); +} + +ManipError PasteManipulator::valid (ManipMode mode) const { + ManipError error; + error.faulty ((PasteManipulator*) this); + + if (! _buffer) { // Error, illegal buffer. + error.errorno (error.FATAL); + return error; + } + + error.errorno (Manipulator::valid (_at, (Token*) 0, mode)); + return error; +} + +void PasteManipulator::manipulate () { + assert (_buffer); + assert (_at); + + List *l = _at->belonging_to (); + if (! l) l = _buffer; + + l->paste (_at, (const Unit&) *_buffer); + ((Unit*) l)->state ().modified (); +} + + +////////////////////////////////////////////////////////////////////// +// The `paste_before' manipulator. /////////////////////////////////// +////////////////////////////////////////////////////////////////////// + + +void PasteBeforeManipulator::args (Array &arguments) { + _at = arguments[0]; + _arguments[0] = _at; +} + +PasteBeforeManipulator::PasteBeforeManipulator (Unit *buffer, Token *at) { + _buffer = buffer; + _at = at; + _arguments.append (_at); +} + +ManipError PasteBeforeManipulator::valid (ManipMode mode) const { + ManipError error; + error.faulty ((PasteBeforeManipulator*) this); + + if (! _buffer) { // Error, illegal buffer. + error.errorno (error.FATAL); + return error; + } + + error.errorno (Manipulator::valid (_at, (Token*) 0, mode)); + return error; +} + +void PasteBeforeManipulator::manipulate () { + assert (_buffer); + assert (_at); + + List *l = _at->belonging_to (); + if (! l) l = _buffer; + + l->paste_before (_at, (const Unit&) *_buffer); + ((Unit*) l)->state ().modified (); +} + + +////////////////////////////////////////////////////////////////////// +// The `move' manipulator. /////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// + + +void MoveManipulator::args (Array &arguments) { + _at = arguments[0]; + _arguments[0] = _at; +} + +MoveManipulator::MoveManipulator (Unit *buffer, Token *at) { + _buffer = buffer; + _at = at; + _arguments.append (_at); +} + +ManipError MoveManipulator::valid (ManipMode mode) const { + ManipError error; + error.faulty ((MoveManipulator*) this); + + if (! _buffer) { // Error, illegal buffer. + error.errorno (error.FATAL); + return error; + } + + error.errorno (Manipulator::valid (_at, (Token*) 0, mode)); + return error; +} + +void MoveManipulator::manipulate () { + assert (_buffer); + assert (_at); + + List *l = _at->belonging_to (); + if (! l) l = _buffer; + + l->move (_at, (Unit&) *_buffer); + ((Unit*) l)->state ().modified (); +} + + +////////////////////////////////////////////////////////////////////// +// The `move_before' manipulator. //////////////////////////////////// +////////////////////////////////////////////////////////////////////// + + +void MoveBeforeManipulator::args (Array &arguments) { + _at = arguments[0]; + _arguments[0] = _at; +} + +MoveBeforeManipulator::MoveBeforeManipulator (Unit *buffer, Token *at) { + _buffer = buffer; + _at = at; + _arguments.append (_at); +} + +ManipError MoveBeforeManipulator::valid (ManipMode mode) const { + ManipError error; + error.faulty ((MoveBeforeManipulator*) this); + + if (! _buffer) { // Error, illegal buffer. + error.errorno (error.FATAL); + return error; + } + + error.errorno (Manipulator::valid (_at, (Token*) 0, mode)); + return error; +} + +void MoveBeforeManipulator::manipulate () { + assert (_buffer); + assert (_at); + + List *l = _at->belonging_to (); + if (! l) l = _buffer; + + l->move_before (_at, (Unit&) *_buffer); + ((Unit*) l)->state ().modified (); +} + + +////////////////////////////////////////////////////////////////////// +// The C++ syntax tree `kill' manipulator. /////////////////////////// +////////////////////////////////////////////////////////////////////// + + +void CKillManipulator::args (Array &arguments) { + _from = arguments[0]; + _to = arguments[1]; + _arguments[0] = _from; + _arguments[1] = _to; + assert (_from); + assert (_to); + assert (_from->belonging_to ()); + assert (_to->belonging_to ()); +} + +CKillManipulator::CKillManipulator (CTree *what) { + _from = what ? what->token () : (Token*) 0; + _to = what ? what->end_token () : (Token*) 0; + _arguments.append (_from); + _arguments.append (_to); + assert (_from); + assert (_to); + assert (_from->belonging_to ()); + assert (_to->belonging_to ()); +} + +CKillManipulator::CKillManipulator (Token *from, Token *to) { + _from = from; + _to = to; + _arguments.append (_from); + _arguments.append (_to); + assert (_from); + assert (_to); + assert (_from->belonging_to ()); + assert (_to->belonging_to ()); +} + +ManipError CKillManipulator::valid (ManipMode mode) const { + ManipError error; + error.faulty ((CKillManipulator*) this); + + error.errorno (Manipulator::valid (_from, _to, mode)); + return error; +} + +void CKillManipulator::manipulate () { + assert (_from); + + KillManipulator kill (_from, _to); + kill.manipulate (); +} + + +////////////////////////////////////////////////////////////////////// +// The C++ syntax tree `copy' manipulator. /////////////////////////// +////////////////////////////////////////////////////////////////////// + + +void CCopyManipulator::args (Array &arguments) { + _from_from = arguments[0]; + _from_to = arguments[1]; + _to = arguments[2]; + _arguments[0] = _from_from; + _arguments[1] = _from_to; + _arguments[2] = _to; +} + +CCopyManipulator::CCopyManipulator (CTree *from, CTree *to) { + _from_from = from ? from->token () : (Token*) 0; + _from_to = from ? from->end_token () : (Token*) 0; + _to = to ? to->end_token () : (Token*) 0; + _arguments.append (_from_from); + _arguments.append (_from_to); + _arguments.append (_to); +} + +CCopyManipulator::CCopyManipulator (Token *from, Token *to, Token *at) { + _from_from = from; + _from_to = to; + _to = at; + _arguments.append (_from_from); + _arguments.append (_from_to); + _arguments.append (_to); +} + +ManipError CCopyManipulator::valid (ManipMode mode) const { + ManipError error; + error.faulty ((CCopyManipulator*) this); + + if (! _to) { // Error, illegal token. + error.errorno (error.BAD_ARG); + return error; + } + + error.errorno (Manipulator::valid (_from_from, _from_to, mode)); + return error; +} + +void CCopyManipulator::manipulate () { + assert (_from_from); + assert (_to); + + Unit buffer; + + CopyManipulator copy (&buffer, _from_from, _from_to); + copy.manipulate (); + + PasteManipulator paste (&buffer, _to); + paste.manipulate (); +} + + +////////////////////////////////////////////////////////////////////// +// The C++ syntax tree `copy_before' manipulator. //////////////////// +////////////////////////////////////////////////////////////////////// + + +void CCopyBeforeManipulator::args (Array &arguments) { + _from_from = arguments[0]; + _from_to = arguments[1]; + _to = arguments[2]; + _arguments[0] = _from_from; + _arguments[1] = _from_to; + _arguments[2] = _to; +} + +CCopyBeforeManipulator::CCopyBeforeManipulator (CTree *from, CTree *to) { + _from_from = from ? from->token () : (Token*) 0; + _from_to = from ? from->end_token () : (Token*) 0; + _to = to ? to->token () : (Token*) 0; + _arguments.append (_from_from); + _arguments.append (_from_to); + _arguments.append (_to); +} + +CCopyBeforeManipulator::CCopyBeforeManipulator (Token *from, Token *to, Token *at) { + _from_from = from; + _from_to = to; + _to = at; + _arguments.append (_from_from); + _arguments.append (_from_to); + _arguments.append (_to); +} + +ManipError CCopyBeforeManipulator::valid (ManipMode mode) const { + ManipError error; + error.faulty ((CCopyBeforeManipulator*) this); + + if (! _to) { // Error, illegal token. + error.errorno (error.BAD_ARG); + return error; + } + + error.errorno (Manipulator::valid (_from_from, _from_to, mode)); + return error; +} + +void CCopyBeforeManipulator::manipulate () { + assert (_from_from); + assert (_to); + + Unit buffer; + + CopyManipulator copy (&buffer, _from_from, _from_to); + copy.manipulate (); + + PasteBeforeManipulator paste_before (&buffer, _to); + paste_before.manipulate (); +} + + +////////////////////////////////////////////////////////////////////// +// The C++ syntax tree `move' manipulator. /////////////////////////// +////////////////////////////////////////////////////////////////////// + + +void CMoveManipulator::args (Array &arguments) { + _from_from = arguments[0]; + _from_to = arguments[1]; + _to = arguments[2]; + _arguments[0] = _from_from; + _arguments[1] = _from_to; + _arguments[2] = _to; +} + +CMoveManipulator::CMoveManipulator (CTree *from, CTree *to) { + _from_from = from ? from->token () : (Token*) 0; + _from_to = from ? from->end_token () : (Token*) 0; + _to = to ? to->end_token () : (Token*) 0; + _arguments.append (_from_from); + _arguments.append (_from_to); + _arguments.append (_to); +} + +CMoveManipulator::CMoveManipulator (Token *from, Token *to, Token *at) { + _from_from = from; + _from_to = to; + _to = at; + _arguments.append (_from_from); + _arguments.append (_from_to); + _arguments.append (_to); +} + +ManipError CMoveManipulator::valid (ManipMode mode) const { + ManipError error; + error.faulty ((CMoveManipulator*) this); + + if (! _to) { // Error, illegal token. + error.errorno (error.BAD_ARG); + return error; + } + + error.errorno (Manipulator::valid (_from_from, _from_to, mode)); + return error; +} + +void CMoveManipulator::manipulate () { + assert (_from_from); + assert (_to); + + Unit buffer; + + CutManipulator cut (&buffer, _from_from, _from_to); + cut.manipulate (); + + MoveManipulator move (&buffer, _to); + move.manipulate (); +} + + +////////////////////////////////////////////////////////////////////// +// The C++ syntax tree `move_before' manipulator. //////////////////// +////////////////////////////////////////////////////////////////////// + + +void CMoveBeforeManipulator::args (Array &arguments) { + _from_from = arguments[0]; + _from_to = arguments[1]; + _to = arguments[2]; + _arguments[0] = _from_from; + _arguments[1] = _from_to; + _arguments[2] = _to; +} + +CMoveBeforeManipulator::CMoveBeforeManipulator (CTree *from, CTree *to) { + _from_from = from ? from->token () : (Token*) 0; + _from_to = from ? from->end_token () : (Token*) 0; + _to = to ? to->token () : (Token*) 0; + _arguments.append (_from_from); + _arguments.append (_from_to); + _arguments.append (_to); +} + +CMoveBeforeManipulator::CMoveBeforeManipulator (Token *from, Token *to, Token *at) { + _from_from = from; + _from_to = to; + _to = at; + _arguments.append (_from_from); + _arguments.append (_from_to); + _arguments.append (_to); +} + +ManipError CMoveBeforeManipulator::valid (ManipMode mode) const { + ManipError error; + error.faulty ((CMoveBeforeManipulator*) this); + + if (! _to) { // Error, illegal token. + error.errorno (error.BAD_ARG); + return error; + } + + error.errorno (Manipulator::valid (_from_from, _from_to, mode)); + return error; +} + +void CMoveBeforeManipulator::manipulate () { + assert (_from_from); + assert (_to); + + Unit buffer; + + CutManipulator cut (&buffer, _from_from, _from_to); + cut.manipulate (); + + MoveBeforeManipulator move_before (&buffer, _to); + move_before.manipulate (); +} + + +////////////////////////////////////////////////////////////////////// +// The C++ syntax tree `replace' manipulator. //////////////////////// +////////////////////////////////////////////////////////////////////// + + +void CReplaceManipulator::args (Array &arguments) { + _what_from = arguments[0]; + _what_to = arguments[1]; + _with_from = arguments[2]; + _with_to = arguments[3]; + _arguments[0] = _what_from; + _arguments[1] = _what_to; + _arguments[2] = _with_from; + _arguments[3] = _with_to; + assert (_with_from); + assert (_with_from->belonging_to ()); + assert (_what_from); + assert (_what_from->belonging_to ()); + assert (_what_to); + assert (_what_to->belonging_to ()); +} + +CReplaceManipulator::CReplaceManipulator (CTree *what, CTree *with) { + _what_from = what ? what->token () : (Token*) 0; + _what_to = what ? what->end_token () : (Token*) 0; + _with_from = with ? with->token () : (Token*) 0; + _with_to = with ? with->end_token () : (Token*) 0; + _arguments.append (_what_from); + _arguments.append (_what_to); + _arguments.append (_with_from); + _arguments.append (_with_to); + assert (_with_from); + assert (_with_from->belonging_to ()); + assert (_what_from); + assert (_what_from->belonging_to ()); + assert (_what_to); + assert (_what_to->belonging_to ()); +} + +CReplaceManipulator::CReplaceManipulator (Token *wf, Token *wt, Token *tf, Token *tt) { + _what_from = wf; + _what_to = wt; + _with_from = tf; + _with_to = tt; + _arguments.append (_what_from); + _arguments.append (_what_to); + _arguments.append (_with_from); + _arguments.append (_with_to); + assert (_with_from); + assert (_with_from->belonging_to ()); + assert (_with_to); + assert (_with_to->belonging_to ()); + assert (_what_from); + assert (_what_from->belonging_to ()); + assert (_what_to); + assert (_what_to->belonging_to ()); +} + +ManipError CReplaceManipulator::valid (ManipMode mode) const { + ManipError error; + error.faulty ((CReplaceManipulator*) this); + + error.errorno (Manipulator::valid (_what_from, _what_to, mode)); + if (error.errorno () == ManipError::OK) + error.errorno (Manipulator::valid (_with_from, _with_to, mode)); + return error; +} + +void CReplaceManipulator::manipulate () { + assert (_with_from); + assert (_what_from); + assert (_what_to); + + Unit buffer; + List *l = _what_to->belonging_to (); + assert (l); + if (! l) l = &buffer; + Token *new_to = (Token*) l->next (_what_to); + + CopyManipulator copy (&buffer, _with_from, _with_to); + copy.manipulate (); + + PasteManipulator paste (&buffer, _what_to); + paste.manipulate (); + + _arguments[4] = (Token*) l->next (_what_to); + + if (! new_to) { + for (new_to = _what_to; l->next (new_to); + new_to = (Token*) l->next (new_to)); + if (new_to == _what_to) + _arguments[5] = (Token*) 0; + else + _arguments[5] = new_to; + } else + _arguments[5] = (Token*) l->prev (new_to); + + KillManipulator kill (_what_from, _what_to); + kill.manipulate (); +} + + +////////////////////////////////////////////////////////////////////// +// The C++ syntax tree `swap' manipulator. /////////////////////////// +////////////////////////////////////////////////////////////////////// + + +void CSwapManipulator::args (Array &arguments) { + _what_from = arguments[0]; + _what_to = arguments[1]; + _with_from = arguments[2]; + _with_to = arguments[3]; + _arguments[0] = _what_from; + _arguments[1] = _what_to; + _arguments[2] = _with_from; + _arguments[3] = _with_to; +} + +CSwapManipulator::CSwapManipulator (CTree *what, CTree *with) { + _what_from = what ? what->token () : (Token*) 0; + _what_to = what ? what->end_token () : (Token*) 0; + _with_from = with ? with->token () : (Token*) 0; + _with_to = with ? with->end_token () : (Token*) 0; + _arguments.append (_what_from); + _arguments.append (_what_to); + _arguments.append (_with_from); + _arguments.append (_with_to); +} + +CSwapManipulator::CSwapManipulator (Token *wf, Token *wt, Token *tf, Token *tt) { + _what_from = wf; + _what_to = wt; + _with_from = tf; + _with_to = tt; + _arguments.append (_what_from); + _arguments.append (_what_to); + _arguments.append (_with_from); + _arguments.append (_with_to); +} + +ManipError CSwapManipulator::valid (ManipMode mode) const { + ManipError error; + error.faulty ((CSwapManipulator*) this); + + error.errorno (Manipulator::valid (_what_from, _what_to, mode)); + if (error.errorno () == ManipError::OK) + error.errorno (Manipulator::valid (_with_from, _with_to, mode)); + return error; +} + +void CSwapManipulator::manipulate () { + assert (_with_from); + assert (_with_to); + assert (_what_from); + assert (_what_to); + + Unit buffer; + List *l = _what_to->belonging_to (); + if (! l) l = &buffer; + Token *new_to = (Token*) l->next (_what_to); + + CopyManipulator copy (&buffer, _with_from, _with_to); + copy.manipulate (); + + PasteManipulator paste (&buffer, _what_to); + paste.manipulate (); + + _arguments[4] = (Token*) l->next (_what_to); + + if (! new_to) { + for (new_to = _what_to; l->next (new_to); + new_to = (Token*) l->next (new_to)); + if (new_to == _what_to) + _arguments[5] = (Token*) 0; + else + _arguments[5] = new_to; + } else + _arguments[5] = (Token*) l->prev (new_to); + + l = _with_to->belonging_to (); + if (! l) l = &buffer; + new_to = (Token*) l->next (_with_to); + + buffer.clear (); + copy.manipulate (&buffer, _what_from, _what_to); + paste.manipulate (&buffer, _with_to); + + _arguments[6] = (Token*) l->next (_with_to); + + if (! new_to) { + for (new_to = _with_to; l->next (new_to); + new_to = (Token*) l->next (new_to)); + if (new_to == _with_to) + _arguments[7] = (Token*) 0; + else + _arguments[7] = new_to; + } else + _arguments[7] = (Token*) l->prev (new_to); + + KillManipulator kill (_what_from, _what_to); + kill.manipulate (); + kill.manipulate (_with_from, _with_to); +} + + +} // namespace Puma diff --git a/Puma/src/manip/Manipulators.h b/Puma/src/manip/Manipulators.h new file mode 100644 index 0000000..22e6e7a --- /dev/null +++ b/Puma/src/manip/Manipulators.h @@ -0,0 +1,602 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __puma_manipulator_classes__ +#define __puma_manipulator_classes__ + +// Puma manipulator classes. +// +// ManipError..................Error reporting class for manipulators. +// Manipulator.................Abstract base class for manipulators. +// ManipulatorSequence.........A sequence of manipulator objects. +// +// CopyManipulator.............Copy one or more tokens into buffer. +// CutManipulator..............Remove one or more tokens and copy in buffer. +// KillManipulator.............Remove one or more tokens permanently. +// PasteManipulator............Insert a list of tokens at given position. +// PasteBeforeManipulator......Insert a list of tokens before given position. +// MoveManipulator.............Shift a list of tokens at given position. +// MoveBeforeManipulator.......Shift a list of tokens before given position. +// +// CKillManipulator..........Remove all tokens of a tree permanently. +// CCopyManipulator..........Copy a tree after the last token of a 2nd tree. +// CCopyBeforeManipulator....Copy a tree before the first token of a 2nd tree. +// CMoveManipulator..........Move a tree after the last token of a 2nd tree. +// CMoveBeforeManipulator....Move a tree before the first token of a 2nd tree. +// CReplaceManipulator.......Replace a tree with an other tree. +// CSwapManipulator..........Swap two trees. + +#include "Puma/Unit.h" +#include "Puma/List.h" +#include "Puma/CTree.h" +#include "Puma/Array.h" +#include "Puma/Token.h" +#include "Puma/Printable.h" +#include "Puma/RuleTable.h" + +namespace Puma { + + +// Manipulator error structure. + +class Manipulator; + +class ManipError : public Printable { + int _errorno; // The error number. See below. + Manipulator *_faulty; // The faulty manipulator. + +public: + enum { + UNBALANCED = -3, // Unbalanced preprocessor directives found. + MACRO_GEN, // Wanted to manipulate macro generated tokens. + BAD_ARG, // Bad arguments has been given to manipulator. + FATAL, // Fatal errors, like NULL pointer buffer. + OK // Everything seems to be correct. + }; + + ManipError () : _faulty(0) {} + + // Get ... + int errorno () const { return _errorno; } + Manipulator *faulty () const { return _faulty; } + // An error is true if there really was an error. + operator bool () const { return _errorno != OK; } + + // Set ... + void errorno (int number) { _errorno = number; } + void faulty (Manipulator *manip) { _faulty = manip; } + + // Print ... + void print (std::ostream &os) const; + + // There has to be a first arg ... + Location location (); +}; + + +// Enum for checks which should NOT be performed on a Manipulator +enum ManipIgnoreMask { MIM_NONE = 0, MIM_UNBALANCED = 1, MIM_MACRO = 2 }; + + +enum ManipMode { + MM_NO_MACRO_MANIP, // Macro-generated tokens are not transformed unless they are at the end/begin of an + // expansion. In this case the token is replace by the macro call end/begin. + MM_EXPAND_MACROS // Macros are expanded on demand. +}; + + +// Abstract base class for manipulator classes. + +class Manipulator : public ListElement { + + ManipIgnoreMask _ignore; + +protected: + Manipulator () : _ignore (MIM_NONE) {} + + int valid (Token *, Token *, ManipMode) const; + +public: + // Manipulator identifiers used to identify a manipulator typ. + static const char *copy_op; + static const char *cut_op; + static const char *paste_op; + static const char *paste_before_op; + static const char *move_op; + static const char *move_before_op; + static const char *kill_op; + static const char *cpp_copy_op; + static const char *cpp_copy_before_op; + static const char *cpp_kill_op; + static const char *cpp_move_op; + static const char *cpp_move_before_op; + static const char *sequence_op; + static const char *cpp_replace_op; + static const char *cpp_swap_op; + + virtual ~Manipulator () {} + + virtual ManipError valid (ManipMode) const = 0; + virtual void manipulate () = 0; + + virtual Array &args () = 0; + virtual void args (Array&) = 0; + + virtual const char *op () const = 0; + virtual ListElement *duplicate () = 0; + + // set/get the ignore mask + void ignore_mask (ManipIgnoreMask mim) { _ignore = mim; } + ManipIgnoreMask ignore_mask () const { return _ignore; } +}; + + +// Special manipulator class that manages a sequence of +// manipulator commands. + +class ManipulatorSequence : public Manipulator, public List { + RuleTable _rules; + Array _empty; // Not really used. + + void checkArgs (ManipError&, Manipulator*); + +public: + ManipulatorSequence () {} + + Array &args () { return _empty; } + void args (Array &empty) {} + + const char *op () const { return sequence_op; } + ListElement *duplicate (); + + ManipError valid (ManipMode mode) const; + void manipulate (); + + void append (Manipulator *manip) + { List::append (*manip); } +}; + + +// The `copy' manipulator. + +class CopyManipulator : public Manipulator { + Token *_from; + Token *_to; + Unit * _buffer; + Array _arguments; + +public: + CopyManipulator (Unit *buffer, Token *from, Token *to = (Token*) 0); + ~CopyManipulator () {} + + const char *op () const { return copy_op; } + ListElement *duplicate () + { return new CopyManipulator (_buffer, _from, _to); } + + Array &args () { return _arguments; } + void args (Array&); + + ManipError valid (ManipMode) const; + void manipulate (); + + void manipulate (Unit *buffer, Token *from, Token *to = (Token*) 0) + { _buffer = buffer; _from = from; _to = to; manipulate (); } +}; + + +// The `cut' manipulator. + +class CutManipulator : public Manipulator { + Token *_from; + Token *_to; + Unit * _buffer; + Array _arguments; + +public: + CutManipulator (Unit *buffer, Token *from, Token *to = (Token*) 0); + ~CutManipulator () {} + + const char *op () const { return cut_op; } + ListElement *duplicate () + { return new CutManipulator (_buffer, _from, _to); } + + Array &args () { return _arguments; } + void args (Array&); + + ManipError valid (ManipMode) const; + void manipulate (); + + void manipulate (Unit *buffer, Token *from, Token *to = (Token*) 0) + { _buffer = buffer; _from = from; _to = to; manipulate (); } +}; + + +// The `kill' manipulator. + +class KillManipulator : public Manipulator { + Token *_from; + Token *_to; + Array _arguments; + +public: + KillManipulator (Token *from, Token *to = (Token*) 0); + ~KillManipulator () {} + + const char *op () const { return kill_op; } + ListElement *duplicate () + { return new KillManipulator (_from, _to); } + + Array &args () { return _arguments; } + void args (Array&); + + ManipError valid (ManipMode) const; + void manipulate (); + + void manipulate (Token *from, Token *to = (Token*) 0) + { _from = from; _to = to; manipulate (); } +}; + + +// The `paste' manipulator. + +class PasteManipulator : public Manipulator { + Token *_at; + Unit * _buffer; + Array _arguments; + +public: + PasteManipulator (Unit *buffer, Token *at); + ~PasteManipulator () {} + + const char *op () const { return paste_op; } + ListElement *duplicate () + { return new PasteManipulator (_buffer, _at); } + + Array &args () { return _arguments; } + void args (Array&); + + ManipError valid (ManipMode) const; + void manipulate (); + + void manipulate (Unit *buffer, Token *at) + { _buffer = buffer; _at = at; manipulate (); } +}; + + +// The `paste_before' manipulator. + +class PasteBeforeManipulator : public Manipulator { + Token *_at; + Unit * _buffer; + Array _arguments; + +public: + PasteBeforeManipulator (Unit *buffer, Token *at); + ~PasteBeforeManipulator () {} + + const char *op () const { return paste_before_op; } + ListElement *duplicate () + { return new PasteBeforeManipulator (_buffer, _at); } + + Array &args () { return _arguments; } + void args (Array&); + + ManipError valid (ManipMode) const; + void manipulate (); + + void manipulate (Unit *buffer, Token *at) + { _buffer = buffer; _at = at; manipulate (); } +}; + + +// The `move' manipulator. + +class MoveManipulator : public Manipulator { + Token *_at; + Unit * _buffer; + Array _arguments; + +public: + MoveManipulator (Unit *buffer, Token *at); + ~MoveManipulator () {} + + const char *op () const { return move_op; } + ListElement *duplicate () + { return new MoveManipulator (_buffer, _at); } + + Array &args () { return _arguments; } + void args (Array&); + + ManipError valid (ManipMode) const; + void manipulate (); + + void manipulate (Unit *buffer, Token *at) + { _buffer = buffer; _at = at; manipulate (); } +}; + + +// The `move_before' manipulator. + +class MoveBeforeManipulator : public Manipulator { + Token *_at; + Unit * _buffer; + Array _arguments; + +public: + MoveBeforeManipulator (Unit *buffer, Token *at); + ~MoveBeforeManipulator () {} + + const char *op () const { return move_before_op; } + ListElement *duplicate () + { return new MoveBeforeManipulator (_buffer, _at); } + + Array &args () { return _arguments; } + void args (Array&); + + ManipError valid (ManipMode) const; + void manipulate (); + + void manipulate (Unit *buffer, Token *at) + { _buffer = buffer; _at = at; manipulate (); } +}; + + +// The C++ syntax tree `kill' manipulator. + +class CKillManipulator : public Manipulator { + Token *_from; + Token *_to; + Array _arguments; + +public: + CKillManipulator (CTree *what); + CKillManipulator (Token*, Token*); + ~CKillManipulator () {} + + const char *op () const { return cpp_kill_op; } + ListElement *duplicate () + { return new CKillManipulator (_from, _to); } + + Array &args () { return _arguments; } + void args (Array&); + + ManipError valid (ManipMode) const; + void manipulate (); + + void manipulate (CTree *what) + { _from = what ? what->token () : (Token*) 0; + _to = what ? what->end_token () : (Token*) 0; + manipulate (); } +}; + + +// The C++ syntax tree `copy' manipulator. + +class CCopyManipulator : public Manipulator { + Token *_from_from; + Token *_from_to; + Token *_to; + Array _arguments; + +public: + CCopyManipulator (CTree *from, CTree *to); + CCopyManipulator (Token*, Token*, Token*); + ~CCopyManipulator () {} + + const char *op () const { return cpp_copy_op; } + ListElement *duplicate () + { return new CCopyManipulator (_from_from, _from_to, _to); } + + Array &args () { return _arguments; } + void args (Array&); + + ManipError valid (ManipMode) const; + void manipulate (); + + void manipulate (CTree *from, CTree *to) + { _from_from = from ? from->token () : (Token*) 0; + _from_to = from ? from->end_token () : (Token*) 0; + _to = to ? to->end_token () : (Token*) 0; + manipulate (); } + + void manipulate (Token *from, Token *to, Token *at) + { _from_from = from; _from_to = to; _to = at; manipulate (); } +}; + + +// The C++ syntax tree `copy_before' manipulator. + +class CCopyBeforeManipulator : public Manipulator { + Token *_from_from; + Token *_from_to; + Token *_to; + Array _arguments; + +public: + CCopyBeforeManipulator (CTree *from, CTree *to); + CCopyBeforeManipulator (Token*, Token*, Token*); + ~CCopyBeforeManipulator () {} + + const char *op () const { return cpp_copy_before_op; } + ListElement *duplicate () + { return new CCopyBeforeManipulator (_from_from, _from_to, _to); } + + Array &args () { return _arguments; } + void args (Array&); + + ManipError valid (ManipMode) const; + void manipulate (); + + void manipulate (CTree *from, CTree *to) + { _from_from = from ? from->token () : (Token*) 0; + _from_to = from ? from->end_token () : (Token*) 0; + _to = to ? to->token () : (Token*) 0; + manipulate (); } + + void manipulate (Token *from, Token *to, Token *at) + { _from_from = from; _from_to = to; _to = at; manipulate (); } +}; + + +// The C++ syntax tree `move' manipulator. + +class CMoveManipulator : public Manipulator { + Token *_from_from; + Token *_from_to; + Token *_to; + Array _arguments; + +public: + CMoveManipulator (CTree *from, CTree *to); + CMoveManipulator (Token*, Token*, Token*); + ~CMoveManipulator () {} + + const char *op () const { return cpp_move_op; } + ListElement *duplicate () + { return new CMoveManipulator (_from_from, _from_to, _to); } + + Array &args () { return _arguments; } + void args (Array&); + + ManipError valid (ManipMode) const; + void manipulate (); + + void manipulate (CTree *from, CTree *to) + { _from_from = from ? from->token () : (Token*) 0; + _from_to = from ? from->end_token () : (Token*) 0; + _to = to ? to->end_token () : (Token*) 0; + manipulate (); } + + void manipulate (Token *from, Token *to, Token *at) + { _from_from = from; _from_to = to; _to = at; manipulate (); } +}; + + +// The C++ syntax tree `move_before' manipulator. + +class CMoveBeforeManipulator : public Manipulator { + Token *_from_from; + Token *_from_to; + Token *_to; + Array _arguments; + +public: + CMoveBeforeManipulator (CTree *from, CTree *to); + CMoveBeforeManipulator (Token*, Token*, Token*); + ~CMoveBeforeManipulator () {} + + const char *op () const { return cpp_move_before_op; } + ListElement *duplicate () + { return new CMoveBeforeManipulator (_from_from, _from_to, _to); } + + Array &args () { return _arguments; } + void args (Array&); + + ManipError valid (ManipMode) const; + void manipulate (); + + void manipulate (CTree *from, CTree *to) + { _from_from = from ? from->token () : (Token*) 0; + _from_to = from ? from->end_token () : (Token*) 0; + _to = to ? to->token () : (Token*) 0; + manipulate (); } + + void manipulate (Token *from, Token *to, Token *at) + { _from_from = from; _from_to = to; _to = at; manipulate (); } +}; + + +// The C++ syntax tree `replace' manipulator. + +class CReplaceManipulator : public Manipulator { + Token *_what_from; + Token *_what_to; + Token *_with_from; + Token *_with_to; + Array _arguments; + +public: + CReplaceManipulator (CTree *what, CTree *with); + CReplaceManipulator (Token*, Token*, Token*, Token*); + ~CReplaceManipulator () {} + + const char *op () const { return cpp_replace_op; } + ListElement *duplicate () + { return new CReplaceManipulator (_what_from, _what_to, + _with_from, _with_to); } + + Array &args () { return _arguments; } + void args (Array&); + + ManipError valid (ManipMode) const; + void manipulate (); + + void manipulate (CTree *what, CTree *with) + { _what_from = what ? what->token () : (Token*) 0; + _what_to = what ? what->end_token () : (Token*) 0; + _with_from = with ? with->token () : (Token*) 0; + _with_to = with ? with->end_token () : (Token*) 0; + manipulate (); } + + void manipulate (Token *wf, Token *wt, Token *tf, Token *tt) + { _what_from = wf; _what_to = wt; _with_from = tf; + _with_to = tt; manipulate (); } +}; + + +// The C++ syntax tree `swap' manipulator. + +class CSwapManipulator : public Manipulator { + Token *_what_from; + Token *_what_to; + Token *_with_from; + Token *_with_to; + Array _arguments; + +public: + CSwapManipulator (CTree *what, CTree *with); + CSwapManipulator (Token*, Token*, Token*, Token*); + ~CSwapManipulator () {} + + const char *op () const { return cpp_swap_op; } + ListElement *duplicate () + { return new CSwapManipulator (_what_from, _what_to, + _with_from, _with_to); } + + Array &args () { return _arguments; } + void args (Array&); + + ManipError valid (ManipMode) const; + void manipulate (); + + void manipulate (CTree *what, CTree *with) + { _what_from = what ? what->token () : (Token*) 0; + _what_to = what ? what->end_token () : (Token*) 0; + _with_from = with ? with->token () : (Token*) 0; + _with_to = with ? with->end_token () : (Token*) 0; + manipulate (); } + + void manipulate (Token *wf, Token *wt, Token *tf, Token *tt) + { _what_from = wf; _what_to = wt; _with_from = tf; + _with_to = tt; manipulate (); } +}; + + +} // namespace Puma + +#endif /* __puma_manipulator_classes__ */ diff --git a/Puma/src/manip/MatchCollector.cc b/Puma/src/manip/MatchCollector.cc new file mode 100644 index 0000000..c505d6f --- /dev/null +++ b/Puma/src/manip/MatchCollector.cc @@ -0,0 +1,135 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/MatchCollector.h" +#include "Puma/ErrorStream.h" +#include "Puma/CCParser.h" +#include "Puma/Config.h" +#include "Puma/CUnit.h" + +namespace Puma { + + +MatchCollector::MatchCollector (const char *match_pattern) { + if (! match_pattern) + return; + + ErrorStream err; + CUnit *unit; + + unit = new CUnit (err); + *unit << match_pattern; + unit->scan (); + unit->name ("%match pattern%"); + + own_pattern = true; + pattern = unit; + + own_parser = true; + parser = new CCParser; +} + + +MatchCollector::MatchCollector (Parser &p, const char *match_pattern) { + if (! match_pattern) + return; + + ErrorStream err; + CUnit *unit; + + unit = new CUnit (err); + *unit << match_pattern; + unit->scan (); + unit->name ("%match pattern%"); + + own_pattern = true; + pattern = unit; + + own_parser = false; + parser = &p; +} + + +MatchCollector::MatchCollector (Unit &unit) { + own_pattern = false; + pattern = &unit; + + own_parser = true; + parser = new CCParser; +} + + +MatchCollector::MatchCollector (Parser &p, Unit &unit) { + own_pattern = false; + pattern = &unit; + + own_parser = false; + parser = &p; +} + + +MatchCollector::~MatchCollector () { + for (int i = 0; i < matches.length (); i++) + delete matches[i]; + if (own_parser) + delete parser; + if (own_pattern) + delete pattern; +} + + +void MatchCollector::action (CMatch *match) { + matches.append (match); +} + + +void MatchCollector::collect (CProject &p, CTranslationUnit &tu, CTree *node) { + // reset match array + for (int i = 0; i < matches.length (); i++) + delete matches[i]; + matches.reset (); + + // configure parser + ErrorStream err; + Config c (err); + c.Add ("--match-expr"); + parser->configure (c); + + // parse match pattern + CTranslationUnit *mtu; + mtu = parser->parse (*pattern, p); + + // start matching + match (tu, *mtu, node); + + delete mtu; +} + + +void MatchCollector::defMacro (const char *name, const char *body) { + if (! name) + return; + + ErrorStream err; + Config c (err); + c.Add ("-D", name, body); + parser->configure (c); +} + + +} // namespace Puma diff --git a/Puma/src/manip/MatchCollector.h b/Puma/src/manip/MatchCollector.h new file mode 100644 index 0000000..3fcae28 --- /dev/null +++ b/Puma/src/manip/MatchCollector.h @@ -0,0 +1,62 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __MatchCollector__ +#define __MatchCollector__ + +// Specialized CTreeMatcher implementing the action +// method. Collects all matches found. + +#include "Puma/Unit.h" +#include "Puma/Array.h" +#include "Puma/Parser.h" +#include "Puma/CProject.h" +#include "Puma/CTreeMatcher.h" + +namespace Puma { + + +class MatchCollector : public CTreeMatcher { + Unit *pattern; // match pattern + Parser *parser; // for parsing the match pattern + Array matches; // collected matches + + bool own_parser; + bool own_pattern; + +public: + MatchCollector (Unit &); + MatchCollector (const char *); + MatchCollector (Parser &, Unit &); + MatchCollector (Parser &, const char *); + virtual ~MatchCollector (); + + void defMacro (const char *, const char *); + void collect (CProject &, CTranslationUnit &, CTree * = (CTree*)0); + + unsigned int Matches () const { return matches.length (); } + CMatch *Match (unsigned int i) const { return matches.lookup (i); } + +private: + void action (CMatch*); +}; + + +} // namespace Puma + +#endif /* __MatchCollector__ */ diff --git a/Puma/src/manip/Rule.h b/Puma/src/manip/Rule.h new file mode 100644 index 0000000..f93c759 --- /dev/null +++ b/Puma/src/manip/Rule.h @@ -0,0 +1,50 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __Rule__ +#define __Rule__ + +// A rule of the rule table. Consists of two pointers. +// The first is an invalid pointer to a token and the +// second the valid one that shall be used instead. + +#include "Puma/Token.h" +#include "Puma/ListElement.h" + +namespace Puma { + + +class RuleTable; + +class Rule : public ListElement { + friend class RuleTable; + + Token *_old; + Token *_new; + +public: + Rule (Token *o, Token *n) : _old (o), _new (n) {} + virtual ~Rule () {} + + ListElement *duplicate () { return new Rule (_old, _new); } +}; + + +} // namespace Puma + +#endif /* __Rule__ */ diff --git a/Puma/src/manip/RuleTable.cc b/Puma/src/manip/RuleTable.cc new file mode 100644 index 0000000..cd9dc9b --- /dev/null +++ b/Puma/src/manip/RuleTable.cc @@ -0,0 +1,96 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/RuleTable.h" +#include "Puma/Token.h" +#include "Puma/Rule.h" +#include + +namespace Puma { + + +// add a new rule to the table (or update an existing) +void RuleTable::add (Token *oldT, Token *newT) { + assert (oldT); + Rule *curr = (Rule*) first (); + Rule *nextr = 0; + + // search for an existing rule + for (; curr; curr = nextr) { + nextr = (Rule*) next(curr); + + // existing rule found + if (curr->_old == oldT) { + // delete the rule if the old and new tokens + // are the same, to avoid endless loops + if (oldT == newT) + kill (curr); + else // update the rule + curr->_new = newT; + return; + } + } + + // create a new rule + append (*(new Rule (oldT, newT))); +} + +// get the valid pointer to the token depending on the rules +Token *RuleTable::get (Token *token) { + // Get the corresponding token. + token = getToken (token); + + _checked.reset(); + if (token) + assert (token->belonging_to ()); + return token; +} + +// get the valid pointer to the token depending on the rules +Token *RuleTable::getToken (Token *oldT) { + if (! oldT || checked (oldT)) + return oldT; + + Rule *curr = (Rule*) first (); + + // get the wanted rule + for (; curr; curr = (Rule*) next (curr)) { + // rule found + if (curr->_old == oldT) { + // mark the token as already checked + _checked.append (oldT); + + // now check whether there is a rule for the new token too + // example: a->b && b->c => a->c + return get (curr->_new); + } + } + + return oldT; +} + +// return true if the token is already checked +bool RuleTable::checked (Token *token) const { + for (int i = 0; i < _checked.length (); i++) + if (_checked.lookup (i) == token) + return true; + return false; +} + + +} // namespace Puma diff --git a/Puma/src/manip/RuleTable.h b/Puma/src/manip/RuleTable.h new file mode 100644 index 0000000..a0a0e95 --- /dev/null +++ b/Puma/src/manip/RuleTable.h @@ -0,0 +1,61 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __RuleTable__ +#define __RuleTable__ + +// Tokens can be deleted or moved by a manipulation so that +// another manipulation trying to manipulate this token may +// fail. This class implements a table of rules describing +// how to get the right (valid) pointer to the token (if +// moved) or NULL (if deleted). + +#include "Puma/Array.h" +#include "Puma/List.h" + +namespace Puma { + + +class Token; + +class RuleTable : public List { + // array of tokens that are already checked + Array _checked; + +public: + // Destructor: delete the arrays too. + ~RuleTable () { clear (); } + + // add a new rule to the table (or update an existing) + void add (Token *, Token * = (Token*)0); + + // get the valid pointer to the token depending on the rules + Token *get (Token *); + +private: + // return true if the token is already checked + bool checked (Token *) const; + + // get the valid pointer to the token recursively + Token *getToken (Token *); +}; + + +} // namespace Puma + +#endif /* __RuleTable__ */ diff --git a/Puma/src/parser/Builder.cc b/Puma/src/parser/Builder.cc new file mode 100644 index 0000000..480874c --- /dev/null +++ b/Puma/src/parser/Builder.cc @@ -0,0 +1,76 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/Builder.h" +#include "Puma/CObjectInfo.h" +#include "Puma/CScopeInfo.h" + +namespace Puma { + + +unsigned long int Builder::token_counter = 0; + +const char *Builder::Container::NodeId () { + return "Container"; +} + +void Builder::destroy (CTree *t, bool recursive) { + if (t) { + if (recursive) + for (int s = 0; s < t->Sons (); s++) + destroy (t->Son (s), true); + delete t; + } +} + +void Builder::destroyNode (CTree *node) { + if (node) + delete node; +} + +void Builder::Delete () { + CTree *tree = Top (); + if (tree) + destroy (tree); +} + +// put all children into a list node +CTree *Builder::list (CT_List *l) const { + for (int n = 0; n < nodes (); n++) + l->AddSon (get_node (n)); + return l; +} + +// put all sons of the container into a list node +CTree *Builder::copy_list (CT_List *l, Container* c) const { + for (int n = 0; n < c->Sons (); n++) + l->AddSon (c->Son (n)); + return l; +} + +// Helper functions +CTree *Builder::error () { + return new CT_Error; +} + +CTree *Builder::token (Token *t) { + return new CT_Token (t, ++token_counter); +} + + +} // namespace Puma diff --git a/Puma/src/parser/Builder.h b/Puma/src/parser/Builder.h new file mode 100644 index 0000000..4374796 --- /dev/null +++ b/Puma/src/parser/Builder.h @@ -0,0 +1,160 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __Builder_h__ +#define __Builder_h__ + +/** \file + * Basic syntax tree builder component. */ + +#include "Puma/ErrorCollector.h" +#include "Puma/ErrorSink.h" +#include "Puma/PtrStack.h" +#include "Puma/CTree.h" + +namespace Puma { + + +class Token; + + +/** \class Builder Builder.h Puma/Builder.h + * %Syntax tree builder base class. Implements the basic infrastructure + * for building CTree based syntax trees. + * + * Tree builders are used in the syntax analysis to create the nodes + * of the syntax tree according to the accepted grammar (see class + * Syntax). A syntax tree shall be destroyed using the tree builder + * that has created it by calling its method Builder::destroy(CTree*) + * with the root node of the syntax tree as its argument. + * + * The builder is organized as a multi-level stack. If a grammar rule + * is parsed then a new stack level is created. The sub-trees of the + * syntax tree representing the parsed grammer rule are pushed on this + * level of the stack. If the grammar rule is parsed successfully then + * these sub-trees are used to build the syntax tree representing the + * parsed grammar rule (and thus the corresponding source code). The + * current stack level is then discarded and the created syntax tree + * is pushed on the stack of the previous level (which is now the top + * level of the stack). If the grammar rule could not be parsed + * successfully then the current stack level is discarded and all + * the sub-trees pushed on it are destroyed. */ +class Builder : public PtrStack { +protected: + /** The error collector object. */ + ErrorCollector ec; + /** Counter for the created CT_Token object. */ + static unsigned long int token_counter; + +public: + /** Container class for collecting a set of + * syntax tree nodes. */ + class Container : public CT_List { + public: + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + }; + +protected: + /** Constructor. */ + Builder () {} + +public: + /** Destroy the given syntax tree recursively. + * \param tree The root node of the syntax tree. + * \param recursive Delete sub tree too. */ + static void destroy (CTree *tree, bool recursive = true); + + /** Destroy the given syntax tree node. Child nodes are not destroyed. + * \param node The node. */ + virtual void destroyNode (CTree *node); + + /** Print the collected error messages on the + * given error output stream. + * \param e The error output stream. */ + void errors (ErrorSink &e); + + /** Get the collected errors. */ + ErrorSink &err () const; + /** Save the current state. */ + void save_state (); + /** Discard the saved state. */ + void forget_state (); + /** Restore the saved state. */ + void restore_state (); + + /** Create a new CT_Token object for the given token. + * \param t The token. */ + CTree *token (Token *t); + /** Create a new CT_Error object. */ + CTree *error (); + + /** Get the current number of nodes on the builder stack. */ + int nodes () const; + /** Get the n-th node from the builder stack. + * \param n The index of the node. */ + CTree *get_node (int n = 0) const; + + /** Reset the token counter. + * \param v The new counter value. */ + void setTokenCounter (unsigned long v); + /** Get the current token count. */ + unsigned long getTokenCounter () const; + +protected: + /** Destroy the top tree node of the builder stack. */ + void Delete (); + + /** Put all nodes on the builder stack into a Container object. */ + CTree *container () const; + + /** Add all nodes on the builder stack to the given list node. + * \param l The list node. */ + CTree *list (CT_List *l) const; + /** Add all nodes of the given container to the given list node. + * \param l The list node. + * \param c The node container. */ + CTree *copy_list (CT_List *l, Container *c) const; +}; + +inline int Builder::nodes () const + { return (int)Length (); } + +inline CTree *Builder::get_node (int i) const + { return (CTree*)Get (i); } + +inline CTree *Builder::container () const + { return list (new Container); } + +inline ErrorSink &Builder::err () const { return (ErrorSink&)ec; } +inline void Builder::errors (ErrorSink &e) { ec.shift (e); } + +inline void Builder::save_state () { New (); } +inline void Builder::forget_state () { Reject (); } +inline void Builder::restore_state () { Destroy (); } + +inline void Builder::setTokenCounter (unsigned long num) + { token_counter = num; } +inline unsigned long Builder::getTokenCounter () const + { return token_counter; } + +} // namespace Puma + +#endif /* __Builder_h__ */ diff --git a/Puma/src/parser/CConstant.cc b/Puma/src/parser/CConstant.cc new file mode 100644 index 0000000..4b21d02 --- /dev/null +++ b/Puma/src/parser/CConstant.cc @@ -0,0 +1,305 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CConstant.h" +#include "Puma/CTokens.h" + +namespace Puma { + + +bool CConstant::operator== (const CConstant &other) const { + return value_type == INT_VAL ? (value.int_val == other.convert_to_int ()) : + value_type == UINT_VAL ? (value.uint_val == other.convert_to_uint ()) : + (value.float_val == other.convert_to_float ()); +} + + +bool CConstant::operator!= (const CConstant &other) const { + return ! (*this == other); +} + + +CConstant *CConstant::duplicate () const { + if (value_type == INT_VAL) + return new CConstant (value.int_val, Type ()); + else if (value_type == UINT_VAL) + return new CConstant (value.uint_val, Type ()); + else + return new CConstant (value.float_val, Type ()); +} + +CConstant *CConstant::compute (int oper) const { + CConstant *result; + if (value_type == INT_VAL) + result = new CConstant (cast_to_real_type ( + compute (oper, value.int_val), Type ()), Type ()); + else if (value_type == UINT_VAL) + result = new CConstant (cast_to_real_type ( + compute (oper, value.uint_val), Type ()), Type ()); + else + result = new CConstant (cast_to_real_type ( + compute (oper, value.float_val), Type ()), Type ()); + return result; +} + +CConstant *CConstant::compute (int oper, const CConstant *v) const { + CConstant *result; + CTypeInfo *type = *Type () > *v->Type () ? Type () : v->Type (); + if (type->is_signed ()) + result = new CConstant (cast_to_real_type ( + compute (convert_to_int (), oper, v->convert_to_int ()), type), type); + else if (type->is_unsigned ()) + result = new CConstant (cast_to_real_type ( + compute (convert_to_uint (), oper, v->convert_to_uint ()), type), type); + else + result = new CConstant (cast_to_real_type ( + compute (convert_to_float (), oper, v->convert_to_float ()), type), type); + return result; +} + +CConstant *CConstant::cast_to (CTypeInfo *type) const { + CConstant *result; + if (value_type == INT_VAL) + result = new CConstant (cast_to_real_type (value.int_val, type), type); + else if (value_type == UINT_VAL) + result = new CConstant (cast_to_real_type (value.uint_val, type), type); + else + result = new CConstant (cast_to_real_type (value.float_val, type), type); + return result; +} + +LONG_LONG CConstant::convert_to_int () const { + if (value_type == INT_VAL) + return value.int_val; + else if (value_type == UINT_VAL) + return (LONG_LONG) value.uint_val; + else + return (LONG_LONG) value.float_val; +} + +U_LONG_LONG CConstant::convert_to_uint () const { + if (value_type == INT_VAL) + return (U_LONG_LONG) value.int_val; + else if (value_type == UINT_VAL) + return value.uint_val; + else + return (U_LONG_LONG) value.float_val; +} + +long double CConstant::convert_to_float () const { + if (value_type == INT_VAL) + return (long double) value.int_val; + else if (value_type == UINT_VAL) + return (long double) value.uint_val; + else + return value.float_val; +} + +LONG_LONG CConstant::compute (int oper, LONG_LONG v) const { + switch (oper) { + case TOK_NOT: return !v; + case TOK_PLUS: return +v; + case TOK_MINUS: return -v; + case TOK_TILDE: return ~v; + default: return v; /* error */ + } +} + +U_LONG_LONG CConstant::compute (int oper, U_LONG_LONG v) const { + switch (oper) { + case TOK_NOT: return !v; + case TOK_PLUS: return +v; + case TOK_MINUS: return -(LONG_LONG)v; + case TOK_TILDE: return ~v; + default: return v; /* error */ + } +} + +long double CConstant::compute (int oper, long double v) const { + switch (oper) { + case TOK_NOT: return !v; + case TOK_PLUS: return +v; + case TOK_MINUS: return -v; + default: return v; /* error */ + } +} + +LONG_LONG CConstant::compute (LONG_LONG v1, int oper, LONG_LONG v2) const { + switch (oper) { + case TOK_AND: return v1 & v2; + case TOK_MUL: return v1 * v2; + case TOK_DIV: return (v1 && v2) ? v1 / v2 : (LONG_LONG)0; + case TOK_EQL: return v1 == v2; + case TOK_NEQ: return v1 != v2; + case TOK_LEQ: return v1 <= v2; + case TOK_GEQ: return v1 >= v2; + case TOK_LSH: return v1 << v2; + case TOK_RSH: return v1 >> v2; + case TOK_OR: return v1 | v2; + case TOK_LESS: return v1 < v2; + case TOK_PLUS: return v1 + v2; + case TOK_ROOF: return v1 ^ v2; + case TOK_MINUS: return v1 - v2; + case TOK_OR_OR: return v1 || v2; + case TOK_MODULO: return (v1 && v2) ? v1 % v2 : (LONG_LONG)0; + case TOK_GREATER: return v1 > v2; + case TOK_AND_AND: return v1 && v2; + default: return v1; /* error */ + } +} + +U_LONG_LONG CConstant::compute (U_LONG_LONG v1, int oper, U_LONG_LONG v2) const { + switch (oper) { + case TOK_AND: return v1 & v2; + case TOK_MUL: return v1 * v2; + case TOK_DIV: return (v1 && v2) ? v1 / v2 : (U_LONG_LONG)0; + case TOK_EQL: return v1 == v2; + case TOK_NEQ: return v1 != v2; + case TOK_LEQ: return v1 <= v2; + case TOK_GEQ: return v1 >= v2; + case TOK_LSH: return v1 << v2; + case TOK_RSH: return v1 >> v2; + case TOK_OR: return v1 | v2; + case TOK_LESS: return v1 < v2; + case TOK_PLUS: return v1 + v2; + case TOK_ROOF: return v1 ^ v2; + case TOK_MINUS: return v1 - v2; + case TOK_OR_OR: return v1 || v2; + case TOK_MODULO: return (v1 && v2) ? v1 % v2 : (U_LONG_LONG)0; + case TOK_GREATER: return v1 > v2; + case TOK_AND_AND: return v1 && v2; + default: return v1; /* error */ + } +} + +long double CConstant::compute (long double v1, int oper, long double v2) const { + switch (oper) { + case TOK_MUL: return v1 * v2; + case TOK_DIV: return (v1 && v2) ? v1 / v2 : (long double)0.0; + case TOK_EQL: return v1 == v2; + case TOK_NEQ: return v1 != v2; + case TOK_LEQ: return v1 <= v2; + case TOK_GEQ: return v1 >= v2; + case TOK_LESS: return v1 < v2; + case TOK_PLUS: return v1 + v2; + case TOK_MINUS: return v1 - v2; + case TOK_OR_OR: return v1 || v2; + case TOK_GREATER: return v1 > v2; + case TOK_AND_AND: return v1 && v2; + default: return v1; /* error */ + } +} + +LONG_LONG CConstant::cast_to_real_type (LONG_LONG v, CTypeInfo *t) const { + CTypeInfo *type = t->VirtualType (); + if (type->is_bool ()) return (LONG_LONG)((bool)v); + else if (type->is_char ()) return (LONG_LONG)((char)v); + else if (type->is_wchar_t ()) return (LONG_LONG)((wchar_t)v); + else if (type->is_short ()) return (LONG_LONG)((short)v); + else if (type->is_int ()) return (LONG_LONG)((int)v); + else if (type->is_long ()) return (LONG_LONG)((long)v); + else if (type->is_long_long ()) return (LONG_LONG)((long long)v); + else if (type->is_signed_char ()) return (LONG_LONG)((signed char)v); + else if (type->is_unsigned_char ()) return (LONG_LONG)((unsigned char)v); + else if (type->is_unsigned_short ()) return (LONG_LONG)((unsigned short)v); + else if (type->is_unsigned_int ()) return (LONG_LONG)((unsigned int)v); + else if (type->is_unsigned_long ()) return (LONG_LONG)((unsigned long)v); + else if (type->is_unsigned_long_long ()) return (LONG_LONG)((unsigned long long)v); + else if (type->is_float ()) return (LONG_LONG)((float)v); + else if (type->is_double ()) return (LONG_LONG)((double)v); + else if (type->is_long_double ()) return (LONG_LONG)((long double)v); + return v; +} + +U_LONG_LONG CConstant::cast_to_real_type (U_LONG_LONG v, CTypeInfo *t) const { + CTypeInfo *type = t->VirtualType (); + if (type->is_bool ()) return (U_LONG_LONG)((bool)v); + else if (type->is_char ()) return (U_LONG_LONG)((char)v); + else if (type->is_wchar_t ()) return (U_LONG_LONG)((wchar_t)v); + else if (type->is_short ()) return (U_LONG_LONG)((short)v); + else if (type->is_int ()) return (U_LONG_LONG)((int)v); + else if (type->is_long ()) return (U_LONG_LONG)((long)v); + else if (type->is_long_long ()) return (U_LONG_LONG)((long long)v); + else if (type->is_signed_char ()) return (U_LONG_LONG)((signed char)v); + else if (type->is_unsigned_char ()) return (U_LONG_LONG)((unsigned char)v); + else if (type->is_unsigned_short ()) return (U_LONG_LONG)((unsigned short)v); + else if (type->is_unsigned_int ()) return (U_LONG_LONG)((unsigned int)v); + else if (type->is_unsigned_long ()) return (U_LONG_LONG)((unsigned long)v); + else if (type->is_unsigned_long_long ()) return (U_LONG_LONG)((unsigned long long)v); + else if (type->is_float ()) return (U_LONG_LONG)((float)v); + else if (type->is_double ()) return (U_LONG_LONG)((double)v); + else if (type->is_long_double ()) return (U_LONG_LONG)((long double)v); + return v; +} + +long double CConstant::cast_to_real_type (long double v, CTypeInfo *t) const { + CTypeInfo *type = t->VirtualType (); + if (type->is_bool ()) return (long double)((bool)v); + else if (type->is_char ()) return (long double)((char)v); + else if (type->is_wchar_t ()) return (long double)((wchar_t)v); + else if (type->is_short ()) return (long double)((short)v); + else if (type->is_int ()) return (long double)((int)v); + else if (type->is_long ()) return (long double)((long)v); + else if (type->is_long_long ()) return (long double)((long long)v); + else if (type->is_signed_char ()) return (long double)((signed char)v); + else if (type->is_unsigned_char ()) return (long double)((unsigned char)v); + else if (type->is_unsigned_short ()) return (long double)((unsigned short)v); + else if (type->is_unsigned_int ()) return (long double)((unsigned int)v); + else if (type->is_unsigned_long ()) return (long double)((unsigned long)v); + else if (type->is_unsigned_long_long ()) return (long double)((unsigned long long)v); + else if (type->is_float ()) return (long double)((float)v); + else if (type->is_double ()) return (long double)((double)v); + else if (type->is_long_double ()) return (long double)((long double)v); + return v; +} + +bool CConstant::isNull () const { + if ((value_type == INT_VAL && value.int_val == 0) || + (value_type == UINT_VAL && value.uint_val == 0) || + (value_type == FLOAT_VAL && value.float_val == 0.0)) + return true; + return false; +} + +bool CConstant::isPositive () const { + if ((value_type == UINT_VAL) || + (value_type == INT_VAL && value.int_val >= 0) || + (value_type == FLOAT_VAL && value.float_val >= 0.0)) + return true; + return false; +} + +bool CConstant::isNegative () const { + if ((value_type == INT_VAL && value.int_val < 0) || + (value_type == FLOAT_VAL && value.float_val < 0.0)) + return true; + return false; +} + +void CConstant::print (std::ostream &out) const { + if (Type ()->VirtualType ()->is_bool ()) + out << (convert_to_int () ? "true" : "false"); + else if (isSigned ()) + out << convert_to_int (); + else if (isUnsigned ()) + out << convert_to_uint (); + else if (isFloat ()) + out << convert_to_float (); +} + +} // namespace Puma diff --git a/Puma/src/parser/CConstant.h b/Puma/src/parser/CConstant.h new file mode 100644 index 0000000..313a52b --- /dev/null +++ b/Puma/src/parser/CConstant.h @@ -0,0 +1,145 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CConstant_h__ +#define __CConstant_h__ + +/** \file + * Semantic information for arithmetic constants. */ + +#include "Puma/Limits.h" +#include "Puma/CTypeInfo.h" +#include "Puma/CExprValue.h" + +namespace Puma { + + +/** \class CConstant CConstant.h Puma/CConstant.h + * Semantic information object for arithmetic constants. */ +class CConstant : public CExprValue { + union Value { + LONG_LONG int_val; // [signed] char|wchar_t|short|int|long|long long + U_LONG_LONG uint_val; // bool|unsigned (char|short|int|long|long long) + long double float_val; // float|double|long double + Value () { int_val = 0; uint_val = 0; float_val = 0.0; } + } value; + + enum { + INT_VAL, + UINT_VAL, + FLOAT_VAL + } value_type; + +public: + /** Constructor. + * \param v The value. + * \param t The type of the value. */ + CConstant (LONG_LONG v, CTypeInfo *t) : CExprValue (t) + { value.int_val = v; value_type = INT_VAL; } + /** Constructor. + * \param v The value. + * \param t The type of the value. */ + CConstant (U_LONG_LONG v, CTypeInfo *t) : CExprValue (t) + { value.uint_val = v; value_type = UINT_VAL; } + /** Constructor. + * \param v The value. + * \param t The type of the value. */ + CConstant (long double v, CTypeInfo *t) : CExprValue (t) + { value.float_val = v; value_type = FLOAT_VAL; } + /** Destructor. */ + virtual ~CConstant () {} + + /** Cast the value to the given type. + * \param t The type to which to cast. + * \return A new object with the casted value. + * Has to be destroyed by the caller. */ + CConstant *cast_to (CTypeInfo *t) const; + + /** Compute the resulting value when applying the given + * unary operator to the value. + * \param oper The operator to apply to the value (token type). + * \return A new object with the computed value. + * Has to be destroyed by the caller. */ + CConstant *compute (int oper) const; + /** Compute the resulting value when applying the given + * binary operator to this and the given value. + * \param oper The operator to apply to the values (token type). + * \param v The other operand to the operator. + * \return A new object with the computed value. + * Has to be destroyed by the caller. */ + CConstant *compute (int oper, const CConstant *v) const; + + /** Convert the value to a signed integer. */ + LONG_LONG convert_to_int () const; + /** Convert the value to an unsiged integer. */ + U_LONG_LONG convert_to_uint () const; + /** Convert the value to floating point. */ + long double convert_to_float () const; + + /** Get this. */ + CConstant *Constant () const { return (CConstant*)this; } + /** Duplicate this. + * \return A newly allocated duplicate of this. + * Has to be destroyed by the caller. */ + CConstant *duplicate () const; + + /** Compare the value of this and the given constant. + * Does not compare the types. + * \param c The value to compare to. + * \return True if the values are equal. */ + bool operator== (const CConstant &c) const; + /** Compare the value of this and the given constant. + * Does not compare the types. + * \param c The value to compare to. + * \return True if the values are not equal. */ + bool operator!= (const CConstant &c) const; + + /** Check if the constant value is 0, regardless of the type. */ + bool isNull () const; + /** Check if the value is positive (>= 0). */ + bool isPositive () const; + /** Check if the value is negative (< 0). */ + bool isNegative () const; + /** Check if the value is signed. */ + bool isSigned () const { return value_type == INT_VAL; } + /** Check if the value is unsigned. */ + bool isUnsigned () const { return value_type == UINT_VAL; } + /** Check is the value is a floating point value. */ + bool isFloat () const { return value_type == FLOAT_VAL; } + + /** Print the value on the given output stream. + * \param out The output stream. */ + virtual void print (std::ostream &out) const; + +private: + LONG_LONG compute (int, LONG_LONG) const; + LONG_LONG compute (LONG_LONG, int, LONG_LONG) const; + U_LONG_LONG compute (int, U_LONG_LONG) const; + U_LONG_LONG compute (U_LONG_LONG, int, U_LONG_LONG) const; + long double compute (int, long double) const; + long double compute (long double, int, long double) const; + + LONG_LONG cast_to_real_type (LONG_LONG, CTypeInfo *) const; + U_LONG_LONG cast_to_real_type (U_LONG_LONG, CTypeInfo *) const; + long double cast_to_real_type (long double, CTypeInfo *) const; +}; + + +} // namespace Puma + +#endif /* __CConstant_h__ */ diff --git a/Puma/src/parser/CExprValue.h b/Puma/src/parser/CExprValue.h new file mode 100644 index 0000000..4ab5fcd --- /dev/null +++ b/Puma/src/parser/CExprValue.h @@ -0,0 +1,72 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CExprValue_h__ +#define __CExprValue_h__ + +/** \file + * Semantic information for constant expression values in the syntax tree. */ + +#include + +namespace Puma { + + +class CTypeInfo; +class CConstant; +class CStrLiteral; +class CWStrLiteral; + +/** \class CExprValue CExprValue.h Puma/CExprValue.h + * Base class for syntax tree nodes representing + * expressions that can be resolved to a constant value + * (arithmetic constants and string literals). */ +class CExprValue { + CTypeInfo *_type; + +protected: + /** Constructor. + * \param t The type of the value. */ + CExprValue (CTypeInfo *t) : _type (t) {} + +public: + /** Destructor. */ + virtual ~CExprValue () {} + + /** Get the type of the value. */ + CTypeInfo *Type () const { return _type; } + /** Print the value on the given output stream. + * \param out The stream on which to print. */ + virtual void print (std::ostream &out) const = 0; + + /** Get a pointer to CConstant if this is an arithmetic constant. */ + virtual CConstant *Constant () const { return (CConstant*)0; } + /** Get a pointer to CStrLiteral if this is a string literal. */ + virtual CStrLiteral *StrLiteral () const { return (CStrLiteral*)0; } + /** Get a pointer to CWStrLiteral if this is a wide string literal. */ + virtual CWStrLiteral *WStrLiteral () const { return (CWStrLiteral*)0; } +}; + +inline std::ostream& operator << (std::ostream &out, const CExprValue &ev) { + ev.print (out); + return out; +} + +} // namespace Puma + +#endif /* __CExprValue_h__ */ diff --git a/Puma/src/parser/CSemObject.h b/Puma/src/parser/CSemObject.h new file mode 100644 index 0000000..1490810 --- /dev/null +++ b/Puma/src/parser/CSemObject.h @@ -0,0 +1,50 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CSemObject_h__ +#define __CSemObject_h__ + +/** \file + * Semantic information about entity definitions. */ + +namespace Puma { + + +class CObjectInfo; + + +/** \class CSemObject CSemObject.h Puma/CSemObject.h + * Semantic information for syntax tree nodes + * referencing objects, classes, or any other entity. */ +class CSemObject { + CObjectInfo *_obj; + +public: + /** Constructor. */ + CSemObject () : _obj ((CObjectInfo*)0) {} + /** Set the semantic information object for the entity. + * \param o The semantic information object. */ + void Object (CObjectInfo *o) { _obj = o; } + /** Get the semantic information object. */ + CObjectInfo *Object () const { return _obj; } +}; + + +} // namespace Puma + +#endif /* __CSemObject_h__ */ diff --git a/Puma/src/parser/CSemScope.h b/Puma/src/parser/CSemScope.h new file mode 100644 index 0000000..0aafb8b --- /dev/null +++ b/Puma/src/parser/CSemScope.h @@ -0,0 +1,51 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CSemScope_h__ +#define __CSemScope_h__ + +/** \file + * Scope information for the syntax tree. */ + +namespace Puma { + + +class CStructure; + +/** \class CSemScope CSemScope.h Puma/CSemScope.h + * Scope information object for syntax tree nodes. + * Some syntactic constructs open own scopes, e.g. + * class definitions, function bodies, and compound + * statements. */ +class CSemScope { + CStructure *_scope; + +public: + /** Constructor. */ + CSemScope () : _scope ((CStructure*)0) {} + /** Set the scope. + * \param s The scope. */ + void Scope (CStructure *s) { _scope = s; } + /** Get the scope. */ + CStructure *Scope () const { return _scope; } +}; + + +} // namespace Puma + +#endif /* __CSemScope_h__ */ diff --git a/Puma/src/parser/CSemValue.h b/Puma/src/parser/CSemValue.h new file mode 100644 index 0000000..9951f54 --- /dev/null +++ b/Puma/src/parser/CSemValue.h @@ -0,0 +1,100 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CSemValue_h__ +#define __CSemValue_h__ + +/** \file + * Semantic value information for the syntax tree. */ + +#include "Puma/CExprValue.h" +#include "Puma/CTypeInfo.h" + +namespace Puma { + + +/** \class CSemValue CSemValue.h Puma/CSemValue.h + * Semantic information object about values in the syntax + * tree. Provides the value and type of an expression or + * entity (name). */ +class CSemValue { + bool value_ref; + bool type_ref; + +protected: + /** The semantic value information object. */ + CExprValue *value; + /** The type information object. */ + CTypeInfo *type; + +public: + /** Constructor. */ + CSemValue (); + /** Destructor. Frees the type and value. */ + virtual ~CSemValue (); + + /** Set the semantic value information object. + * Will be freed in the destructor. + * \param v The value info object. */ + void setValue (CExprValue *v); + /** Set the semantic value information object as reference. + * Will not be destroyed in the destructor. + * \param v The value info object. */ + void setValueRef (CExprValue *v); + /** Set the type information object. + * Will be freed in the destructor. + * \param t The type info object. */ + void setType (CTypeInfo *t); + /** Set the type information object as reference. + * Will not be destroyed in the destructor. + * \param t The type info object. */ + void setTypeRef (CTypeInfo *t); + /** Get the semantic information about the value. */ + CExprValue* getValue() { return value; } + /** Get the type of the value. */ + CTypeInfo* getType() { return type; } +}; + +inline CSemValue::CSemValue () : + value_ref (false), + type_ref (true), + value ((CExprValue*)0), + type (&CTYPE_UNDEFINED) + {} +inline CSemValue::~CSemValue () + { if (value && ! value_ref) delete value; + if (type && ! type_ref) CTypeInfo::Destroy (type); } + +inline void CSemValue::setValue (CExprValue *v) + { if (value && ! value_ref) delete value; + value = v; value_ref = false; } +inline void CSemValue::setValueRef (CExprValue *v) + { if (value && ! value_ref) delete value; + value = v; value_ref = true; } + +inline void CSemValue::setType (CTypeInfo *t) + { if (type && ! type_ref) CTypeInfo::Destroy (type); + type = t; type_ref = false; } +inline void CSemValue::setTypeRef (CTypeInfo *t) + { if (type && ! type_ref) CTypeInfo::Destroy (type); + type = t; type_ref = true; } + + +} // namespace Puma + +#endif /* __CSemValue_h__ */ diff --git a/Puma/src/parser/CVisitor.cc b/Puma/src/parser/CVisitor.cc new file mode 100644 index 0000000..6b79626 --- /dev/null +++ b/Puma/src/parser/CVisitor.cc @@ -0,0 +1,63 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CVisitor.h" +#include "Puma/CTree.h" + +namespace Puma { + + +void CVisitor::visit (CTree *node) { + if (! node) + return; + + pre_visit (node); + + if (_pruned) { + _pruned = false; + return; + } + if (_aborted) + return; + + visit_sons (node); + + if (_aborted) + return; + + post_visit (node); +} + +void CVisitor::visit_sons (CTree *node) { + for (int i = 0; i < node->Sons (); i++) { + if (_aborted) + return; + visit (node->Son (i)); + } +} + +void CVisitor::pre_visit (CTree *node) { + // do something +} + +void CVisitor::post_visit (CTree *node) { + // do something +} + + +} // namespace Puma diff --git a/Puma/src/parser/CVisitor.h b/Puma/src/parser/CVisitor.h new file mode 100644 index 0000000..f7cfb69 --- /dev/null +++ b/Puma/src/parser/CVisitor.h @@ -0,0 +1,82 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CVisitor_h__ +#define __CVisitor_h__ + +/** \file + * CTree based tree visitor. */ + +namespace Puma { + + +class CTree; + +/** \class CVisitor CVisitor.h Puma/CVisitor.h + * Tree visitor implementation for CTree based syntax trees. To be derived + * for visiting concrete syntax trees. + * + * This class performs depth-first tree-traversal based on CTree tree + * structures. The traversal is started by calling CVisitor::visit() + * with the root node of the tree to traverse as its argument. + * For every node of the tree CVisitor::pre_visit() is called + * before its child nodes are visited, and CVisitor::post_visit() + * is called after its child nodes are visited. To perform actions + * on the visited nodes, CVisitor::pre_visit() and CVisitor::post_visit() + * have to be overloaded. */ +class CVisitor { + bool _aborted; + bool _pruned; + + void visit_sons (CTree *node); + +public: + /** Constructor. */ + CVisitor () : _aborted (false), _pruned (false) {} + /** Destructor. */ + virtual ~CVisitor () {} + + /** Set the aborted state. + * \param v True for aborted, false for not aborted. */ + void abort (bool v = true) { _aborted = v; } + /** Set the pruned state (don't visit the sub-tree). + * \param v True for pruned, false for not pruned. */ + void prune (bool v = true) { _pruned = v; } + /** Check if the node visiting is aborted. */ + bool aborted () const { return _aborted; } + /** Check if the visiting the sub-tree is aborted. */ + bool pruned () const { return _pruned; } + + /** Visit the given syntax tree node. + * \param node The node to visit. */ + void visit (CTree *node); + + /** Apply actions before the given node is visited. + * To be implemented by derived visitors. + * \param node The node to visit. */ + virtual void pre_visit (CTree *node); + /** Apply actions after the given node is visited. + * To be implemented by derived visitors. + * \param node The node to visit. */ + virtual void post_visit (CTree *node); +}; + + +} // namespace Puma + +#endif /* __CVisitor_h__ */ diff --git a/Puma/src/parser/CWStrLiteral.h b/Puma/src/parser/CWStrLiteral.h new file mode 100644 index 0000000..675df04 --- /dev/null +++ b/Puma/src/parser/CWStrLiteral.h @@ -0,0 +1,62 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CWStrLiteral_h__ +#define __CWStrLiteral_h__ + +/** \file + * Wide string literal abstraction. */ + +#include "Puma/CExprValue.h" + +namespace Puma { + + +/** \class CWStrLiteral CWStrLiteral.h Puma/CWStrLiteral.h + * Wide string literal abstraction. Holds the wide string + * value, its length, and the string type. */ +class CWStrLiteral : public CExprValue { + const wchar_t *_string; + unsigned long _len; + +public: + /** Constructor. + * \param s The wide string array. + * \param len The length of the string. + * \param t The type of the string. */ + CWStrLiteral (const wchar_t *s, unsigned long len, CTypeInfo *t) : + CExprValue (t), _string (s), _len (len) {} + /** Destructor. Frees the string. */ + virtual ~CWStrLiteral () { if (_string) delete[] _string; } + + /** Print the wide string on the given output stream. + * \param out The output stream. */ + virtual void print (std::ostream &out) const { out << "\"??L\""; } + /** Get the wide string. */ + const wchar_t *String () const { return _string; } + /** Get the length of the string. */ + unsigned long Length () const { return _len; } + + /** Get this. */ + CWStrLiteral *WStrLiteral () const { return (CWStrLiteral*)this; } +}; + + +} // namespace Puma + +#endif /* __CWStrLiteral_h__ */ diff --git a/Puma/src/parser/LookAhead.ah b/Puma/src/parser/LookAhead.ah new file mode 100644 index 0000000..83cf715 --- /dev/null +++ b/Puma/src/parser/LookAhead.ah @@ -0,0 +1,34 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __LookAhead_ah__ +#define __LookAhead_ah__ + +#include "Puma/Syntax.h" + +aspect LookAhead { + + advice Puma::Syntax::rule_check() : around () { + if (JoinPoint::That::lookahead(tjp->arg<0>())) + tjp->proceed (); + else + *tjp->result() = false; + } +}; + +#endif /* __LookAhead_ah__ */ diff --git a/Puma/src/parser/Parser.cc b/Puma/src/parser/Parser.cc new file mode 100644 index 0000000..32be882 --- /dev/null +++ b/Puma/src/parser/Parser.cc @@ -0,0 +1,78 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/Unit.h" +#include "Puma/Parser.h" +#include "Puma/TokenStream.h" +#include "Puma/UnitManager.h" +#include "Puma/CSemDatabase.h" +#include "Puma/PreMacroManager.h" +#include "Puma/CTranslationUnit.h" +#include "Puma/PreprocessorParser.h" +#include + +namespace Puma { + + +void Parser::configure (Config &c) { + syntax->configure (c); + semantic->configure (c); +} + +CTranslationUnit *Parser::parse (Unit &unit, CProject &p, int pre_mode, std::ostream& os) { + CTranslationUnit *tu = new CTranslationUnit (unit, p); + + // configure syntax and semantic object + configure (p.config ()); + + // prepare C preprocessor + TokenStream stream; // linearize tokens from several files + stream.push (&unit); + p.unitManager ().init (); + PreprocessorParser cpp (&p.err (), &p.unitManager (), &tu->local_units (), os); + cpp.macroManager ()->init (unit.name ()); + cpp.stream (&stream); + cpp.configure (p.config ()); + + // prepare semantic analysis + semantic->init (tu->db (), unit); + ((ErrorCollector&)builder->err ()).index (0); + semantic->error_sink (builder->err ()); + + // run only C preprocessor + if (pre_mode > 0) { + if (pre_mode == 2) + cpp.silentMode (); + cpp.parse (); + } else { + TokenProvider provider (cpp); // look ahead token buffer + tu->tree (syntax->run (provider)); + Token *after_program = provider.current(); + if (after_program) { // error, e.g. too many closing brackets + p.err() << sev_error << after_program->location() + << "tokens after end of program (too many closing brackets?)" + << endMessage; + } + } + tu->cpp_tree (cpp.syntaxTree ()); + builder->errors (p.err ()); + return tu; +} + + +} // namespace Puma diff --git a/Puma/src/parser/Parser.h b/Puma/src/parser/Parser.h new file mode 100644 index 0000000..449965c --- /dev/null +++ b/Puma/src/parser/Parser.h @@ -0,0 +1,83 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __Parser__ +#define __Parser__ + +/** \file + * Generic parser abstraction. */ + +#include "Puma/Unit.h" +#include "Puma/Syntax.h" +#include "Puma/Builder.h" +#include "Puma/Semantic.h" +#include "Puma/CProject.h" +#include + +namespace Puma { + + +class CTranslationUnit; + + +/** \class Parser Parser.h Puma/Parser.h + * Generic parser abstraction. Setups the parser components + * ready to be used for parsing an input file (see class + * Puma::Syntax, Puma::Builder, and Puma::Semantic). + * + * The result of parsing a source file is the so-called + * translation unit (see class Puma::CTranslationUnit). It + * encapsulates the result of the syntactic and semantic + * analyses (syntax tree, semantic information database, + * preprocessor tree). */ +class Parser { + Syntax *syntax; + Builder *builder; + Semantic *semantic; + +public: + /** Constructor. + * \param x The syntax analysis component. + * \param b The syntax tree builder. + * \param s The semantic analysis component. */ + Parser (Syntax &x, Builder &b, Semantic &s) : + syntax (&x), builder (&b), semantic (&s) {} + + /** Parse the given input file. Supports different preprocessing + * modes. 0 means to pass the preprocessed tokens to the parser. + * 1 means to print the preprocessed tokens on stdout and to not + * parse at all. Mode 2 means the same as mode 1 except that the + * preprocessed tokens are not printed to stdout. + * \param file The input file. + * \param p The source project information. + * \param pre_mode The preprocessing mode (0-2). + * \param os Preprocessor output stream if mode is 1. + * \return A newly created object containing the parse results. + * To be destroyed by the caller. */ + CTranslationUnit *parse (Unit &file, CProject &p, int pre_mode = 0, std::ostream& os = std::cout); + + /** Configure the parser components. Calls the corresponding + * configure methods of the parser components. + * \param c The configuration settings. */ + void configure (Config &c); +}; + + +} // namespace Puma + +#endif /* __Parser__ */ diff --git a/Puma/src/parser/Semantic.cc b/Puma/src/parser/Semantic.cc new file mode 100644 index 0000000..988b03f --- /dev/null +++ b/Puma/src/parser/Semantic.cc @@ -0,0 +1,261 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/Unit.h" +#include "Puma/CTree.h" +#include "Puma/Array.h" +#include "Puma/PtrStack.h" +#include "Puma/ErrorSink.h" +#include "Puma/Semantic.h" +#include "Puma/ErrorSeverity.h" +#include "Puma/CSemDeclarator.h" +#include "Puma/CSemDeclSpecs.h" +#include "Puma/CFileInfo.h" +#include "Puma/CEnumInfo.h" +#include "Puma/CTypeInfo.h" +#include "Puma/CClassInstance.h" +#include "Puma/CUnionInstance.h" +#include "Puma/CFctInstance.h" +#include "Puma/CClassInfo.h" +#include "Puma/CUnionInfo.h" +#include "Puma/CLabelInfo.h" +#include "Puma/CLocalScope.h" +#include "Puma/CTypedefInfo.h" +#include "Puma/CTemplateInfo.h" +#include "Puma/CFunctionInfo.h" +#include "Puma/CArgumentInfo.h" +#include "Puma/CAttributeInfo.h" +#include "Puma/CEnumeratorInfo.h" +#include "Puma/CMemberAliasInfo.h" +#include "Puma/CSemDatabase.h" + +#include +#include +#include +#include + +namespace Puma { + + +/*DEBUG*/int TRACE_UNDO=0; +/*DEBUG*/int TRACE_OBJS=0; +/*DEBUG*/int TRACE_FCT=0; +/*DEBUG*/int TRACE_SCOPES=0; +/*DEBUG*/int TRACE_TYPE=0; +/*DEBUG*/int SEM_DECL_SPECS=0; + +Semantic::~Semantic () { + while (in_decl ()) + decl_end (); +} + +void Semantic::init (CSemDatabase &db, Unit &unit) { + _db = &db; + _Anonymous = 0; + _sem_decl_specs.reset (); + _decl_specs.reset (); + _in_decl.reset (); + _in_decl.push (false); + _in_param_decl_clause.reset (); + _in_param_decl_clause.push (false); + current_enum = (CEnumInfo*)0; + current_fct = (CStructure*)0; +/*DEBUG*/if (TRACE_FCT) std::cout<<"FCT NIL(0): "<<(void*)current_fct<Name (), name) == 0) + break; + if (f < db.FileInfos ()) // File already parsed!? + _file = db.FileInfo (f); + else { + _file = db.newFile (); + _file->SourceInfo ()->FileInfo (_file); + _file->Primary (&unit); + _file->ScopeInfo ()->Parent (_file); + _file->Name (name); + } + delete[] name; + current_scope = _file; + enter_scope (_file); +} + +/*DEBUG*/void Semantic::Push (CObjectInfo *info) { +/*DEBUG*/ if (TRACE_OBJS) { +/*DEBUG*/ std::cerr<<"INSERT: "<<(void*)info<<" (" +/*DEBUG*/ <<(info->LocalScope()?"LocalScope":info->FunctionInfo()?"Function": +/*DEBUG*/ info->ClassInfo()?"Class":info->UnionInfo()?"Union": +/*DEBUG*/ info->AttributeInfo()?"Attribute":info->ArgumentInfo()?"Argument": +/*DEBUG*/ info->EnumInfo()?"Enum":info->EnumeratorInfo()?"Enumerator": +/*DEBUG*/ info->LabelInfo()?"Label":info->TypedefInfo()?"Typedef": +/*DEBUG*/ info->MemberAliasInfo()?"MemberAlias":info->TemplateInfo()?"Template": +/*DEBUG*/ info->FileInfo()?"File":"Namespace") +/*DEBUG*/ <<" "<Name()<<")"<::Push (info); +/*DEBUG*/} + +void Semantic::Delete () { + // Unlink the top semantic object + CObjectInfo* info = Top (); + if (info) + info->Unlink (); +} + +// Generate and create a new private (anonymous) name. +CTree *Semantic::PrivateName () { + char name[100]; + sprintf (name, "%%anon%ld", _Anonymous); + _Anonymous++; + return new CT_PrivateName (name); +} + +void Semantic::undo (CTree *tree) { + if (! tree) return; + for (int i = 0; i < tree->Sons (); i++) + undo (tree->Son (i)); + + /*DEBUG*/if (TRACE_UNDO) { + /*DEBUG*/ std::cerr<<"UNDO: "<NodeName(); + /*DEBUG*/ if (tree->NodeName()==CT_Token::NodeId() && tree->token()) + /*DEBUG*/ std::cerr<<" '"<token()->text()<<"'"; + /*DEBUG*/ std::cerr<<" ("<<(void*)tree<<")"<NodeName () == CT_DeclSpecSeq::NodeId ()) { + if (in_decl () && (sem_decl_specs ()->DeclSpecSeq () == tree)) + decl_end (); + } +} + +void Semantic::common_settings (CObjectInfo *info, CTree *tree) { + info->SourceInfo ()->FileInfo (_file); + info->SourceInfo ()->StartToken (tree->token_node ()); + info->Tree (tree); +} + +void Semantic::common_settings (CObjectInfo *info, CTree *tree, CSemDeclarator *csd) { + common_settings (info, tree); + if (info->Name ().empty () || info->Name () != DString(csd->Name ()->Text ())) + info->Name (csd->Name ()->Text ()); + if (info->FctInstance ()) + info->FctInstance ()->RealTypeInfo (csd->Type ()); + else + info->TypeInfo (csd->Type ()); + csd->Name ()->Object (info); + csd->Name ()->setTypeRef (info->TypeInfo ()); + csd->Type ((CTypeInfo*)0); +} + +/*****************************************************************************/ +/* */ +/* State information */ +/* */ +/*****************************************************************************/ + +void Semantic::decl_begin (CSemDeclSpecs *dss) { + /*DEBUG*/SEM_DECL_SPECS++; + _sem_decl_specs.push (dss); + _in_decl.push (true); +} + +void Semantic::decl_end () { + /*DEBUG*/SEM_DECL_SPECS--; + delete sem_decl_specs (); + _sem_decl_specs.pop (); + _in_decl.pop (); +} + +void Semantic::finish_declarator () { + if (! _in_param_decl_clause.top ()) { +/*DEBUG*/if (TRACE_FCT) std::cout<<"FCT NIL(4): "<<(void*)current_fct<TemplateInfo()?"Template":scp->LocalScope()?"Local":scp->FunctionInfo()?"Function": + /*DEBUG*/ scp->ClassInfo()?"Class":scp->UnionInfo()?"Union":"File") + /*DEBUG*/ <<(scp->isTemplateInstance()?"Instance ":" ")<<(scp->Name()?scp->Name().c_str():"")<<")"<Parent (current_scope); + current_scope = scp; + Push (scp); +} + +void Semantic::reenter_scope (CStructure *scp) { + /*DEBUG*/if (TRACE_SCOPES) std::cerr<<(void*)this<<": +SCOPE: "<<(void*)scp<<" (" + /*DEBUG*/ <<(scp->TemplateInfo()?"Template":scp->LocalScope()?"Local":scp->FunctionInfo()?"Function": + /*DEBUG*/ scp->ClassInfo()?"Class":scp->UnionInfo()?"Union":"File") + /*DEBUG*/ <<(scp->isTemplateInstance()?"Instance ":" ")<<(scp->Name()?scp->Name().c_str():"")<<")"<ScopeInfo () && info == current_scope) { + /*DEBUG*/if (TRACE_SCOPES) std::cerr<<(void*)this<<": -SCOPE: "<<(void*)info<<" (" + /*DEBUG*/ <<(info->TemplateInfo()?"Template":info->LocalScope()?"Local":info->FunctionInfo()?"Function": + /*DEBUG*/ info->ClassInfo()?"Class":info->UnionInfo()?"Union":"File") + /*DEBUG*/ <<(info->isTemplateInstance()?"Instance ":" ")<<(info->Name()?info->Name().c_str():"")<<")"<ScopeInfo ()->Parent ()->Structure (); + break; // outermost scope found + } + } + Forget (); +} + +void Semantic::enter_local_scope () { + // create and enter new local (block) scope + CLocalScope *info = _db->newLocalScope(); + enter_scope (info); +} + +void Semantic::enter_param_decl_clause () { + // create and enter new function prototype scope + CFunctionInfo *info = _db->newFunction(); + enter_scope (info); + _in_param_decl_clause.push (true); +} + +void Semantic::leave_param_decl_clause () { + // save function prototype scope if this + // is the outermost param_decl_clause + _in_param_decl_clause.pop (); + if (! _in_param_decl_clause.top () && ! current_fct) { + current_fct = current_scope; + /*DEBUG*/if (TRACE_FCT) std::cout<<"FCT SET(0): "<<(void*)current_fct< { +protected: + /** Database of all semantic objects of the semantic tree. */ + CSemDatabase *_db; + /** Top level semantic object representing the file scope. */ + CFileInfo *_file; + /** Error output stream. */ + ErrorSink *_err; + /** Counter for generating anonymous (private) names. */ + long _Anonymous; + + /** The current enumeration, if inside the definition of an enumeration. */ + CEnumInfo *current_enum; + /** The current function, if inside the definition of a function. */ + CStructure *current_fct; + /** The current scope. */ + CStructure *current_scope; + + /** Stack for the type analysis of declarations. */ + BCStack _sem_decl_specs; + /** Stack for collecting declaration specifiers. */ + BCStack _decl_specs; + /** Stack for the state of analysing a function parameter list. */ + BCStack _in_param_decl_clause; + /** Stack for the state of analysing a declaration. */ + BCStack _in_decl; + +protected: + /** Constructor. */ + Semantic () {} + /** Destructor. */ + virtual ~Semantic (); + +public: + /** Initialize the semantic analysis. + * \param db The semantic object database. + * \param file The input file. */ + virtual void init (CSemDatabase &db, Unit &file); + /** Configure the semantic analysis. + * \param c The configuration settings. */ + virtual void configure (Config &c) {} + + /** Set the error output stream object. + * \param e The error output stream. */ + void error_sink (ErrorSink &e); + /** Undo the declaration analysis of the given syntax tree node. + * \param tree The syntax tree node. */ + void undo (CTree *tree); + /** Create a new anonymous (private) name. + * \return A newly allocated node of type CT_PrivateName. + * Has to be destroyed by the caller. */ + CTree *PrivateName (); + + /** Save the current semantic analysis state. */ + void save_state (); + /** Discard the saved semantic analysis state. */ + void forget_state (); + /** Restore the saved semantic analysis state. */ + void restore_state (); + + /** Get the root node of the semantic tree. */ + CFileInfo* getFile (); + +public: + /** Enter a local scope. Creates a new CLocalScope and pushes + * it on the scope stack. */ + void enter_local_scope (); + /** Leave all scopes entered up to the current scope. Make + * the parent scope of the current scope to the current + * scope. */ + virtual void leave_scopes (); + /** Enter a function parameter declaration clause. */ + virtual void enter_param_decl_clause (); + /** Leave a function parameter declaration clause. */ + virtual void leave_param_decl_clause (); + /** Check if in the declaration of a function parameter clause. */ + bool in_param_decl_clause (); + +public: + /** Finish the analysis of the current declaration. */ + void finish_decl (); + /** Finish the analysis of the current declarator. */ + void finish_declarator (); + +protected: + /** Apply command settings on the given semantic object. + * That is setting the semantic database, the source file, + * the start token of the analysed syntactic construct, and + * the syntax tree node. + * \param info The semantic information object. + * \param tree The analysed syntax tree. */ + void common_settings (CObjectInfo *info, CTree *tree); + /** Apply command settings on the given semantic object. + * That is setting the semantic database, the source file, + * the start token of the analysed syntactic construct, + * the syntax tree node, the type, and the name. + * \param info The semantic information object. + * \param tree The analysed syntax tree. + * \param d Declarator information object. */ + void common_settings (CObjectInfo *info, CTree *tree , CSemDeclarator *d); + /** Delete the top item on the semantic stack. + * To be implemented by derived classes. */ + virtual void Delete (); + /** Push the given semantic information object on the semantic stack. + * \param info The semantic object. */ + void Push (CObjectInfo* info); + + /** Check if currently analysing a declaration. */ + bool in_decl () const; + /** Begin analysing a declaration. + * \param ds The declaration specifiers. */ + void decl_begin (CSemDeclSpecs *ds); + /** Finish analysing a declaration. */ + void decl_end (); + /** Begin analysing a declaration specifier sequence. + * \param dss Empty object for the declaration specifiers. */ + void decl_specs_begin (CT_DeclSpecSeq *dss); + /** Finish analysing a declaration specifier sequence. */ + void decl_specs_end (); + + /** Get the semantic information for the currently analysed + * declaration specifier sequence. */ + CSemDeclSpecs *sem_decl_specs () const; + /** Get the currently analysed declaration specifier sequence. */ + CT_DeclSpecSeq *decl_specs () const; + + /** Enter the given scope. Sets the parent of the entered + * scope to the current scope. + * \param scope The scope to enter. */ + virtual void enter_scope (CStructure *scope); + /** Reenter the given scope. Does not reset the parent of + * entered scope. + * \param scope The scope to reenter. */ + virtual void reenter_scope (CStructure *scope); +}; + +inline CFileInfo* Semantic::getFile () + { return _file; } + +inline void Semantic::save_state () + { New (); } +inline void Semantic::forget_state () + { leave_scopes (); } +inline void Semantic::restore_state () + { Destroy (); } + +inline bool Semantic::in_decl () const +// { return _in_decl.length () > 0 ? _in_decl.top () : false; } + { return _in_decl.empty () ? false : _in_decl.top (); } +inline void Semantic::finish_decl () + { if (in_decl ()) decl_end (); } + +inline void Semantic::error_sink (ErrorSink &e) + { _err = &e; } + +inline CSemDeclSpecs *Semantic::sem_decl_specs () const + { return _sem_decl_specs.top (); } +inline CT_DeclSpecSeq *Semantic::decl_specs () const + { return _decl_specs.top (); } +inline void Semantic::decl_specs_begin (CT_DeclSpecSeq *dss) + { _decl_specs.push (dss); } +inline void Semantic::decl_specs_end () + { _decl_specs.pop (); } + + +} // namespace Puma + +#endif /* __Semantic_h__ */ diff --git a/Puma/src/parser/Syntax.cc b/Puma/src/parser/Syntax.cc new file mode 100644 index 0000000..16d0033 --- /dev/null +++ b/Puma/src/parser/Syntax.cc @@ -0,0 +1,309 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/Syntax.h" +#include "Puma/CTree.h" +#include "Puma/CTokens.h" +#include "Puma/Semantic.h" + +namespace Puma { + + +void Syntax::configure (Config &config) { + if (config.Option ("--verbose-errors")) + _verbose_errors = true; +} + + +CTree *Syntax::run (TokenProvider &tp) { + token_provider = &tp; + token_provider->init(); + _have_error = false; + _problem_token = (Token*)0; + locate_token (); + return trans_unit () ? builder ().Top () : (CTree*)0; +} + + +Token *Syntax::locate_token () { + Token *token; + while ((token = token_provider->current ()) && ! token->is_core ()) { + if (token->is_directive ()) + handle_directive (); + else + token_provider->next (); + } + return token; +} + +bool Syntax::look_ahead (int token_type, unsigned n) { + Token *token; + State state; + bool result; + + result = false; + if (n == 1) { + token = token_provider->current (); + result = (token && token->type () == token_type); + } else { + state = token_provider->get_state (); + while ((--n) > 0) { + token_provider->next (); + locate_token (); + } + token = token_provider->current (); + result = (token && token->type () == token_type); + token_provider->set_state (state); + } + return result; +} + +bool Syntax::look_ahead (int *token_types, unsigned n) { + Token *token; + State state; + bool result; + + result = false; + if (n == 1) { + token = token_provider->current (); + if (token) { + while (*token_types) { + if (*token_types == token->type ()) { + result = true; + break; + } + ++token_types; + } + } + } else { + state = token_provider->get_state (); + while ((--n) > 0) { + token_provider->next (); + locate_token (); + } + token = token_provider->current (); + if (token) { + while (*token_types) { + if (*token_types == token->type ()) { + result = true; + break; + } + ++token_types; + } + } + token_provider->set_state (state); + } + return result; +} + +Syntax::State Syntax::save_state () { + semantic ().save_state (); + return token_provider->get_state (); +} + +void Syntax::forget_state () { + semantic ().forget_state (); +} + +void Syntax::restore_state () { + for (long i = builder ().Length () - 1; i >= 0; i--) + semantic ().undo (builder ().Get (i)); + semantic ().restore_state (); +} + +void Syntax::restore_state (State state) { + token_provider->set_state (state); + for (long i = builder ().Length () - 1; i >= 0; i--) + semantic ().undo (builder ().Get (i)); + semantic ().restore_state (); +} + +void Syntax::set_state (State state) { + token_provider->set_state (state); +} + +bool Syntax::accept (CTree *result, State s) { + if (result) { + forget_state (); + builder ().forget_state (); + builder ().Push (result); + return true; + } else { + set_state (s); + restore_state (); + return false; + } +} + +CTree* Syntax::accept (CTree *result) { + return result; +} + +bool Syntax::parse_token (int token_type) { + Token *t = token_provider->current (); + if (t && t->type () == token_type) { + _problem_token = (Token*)0; + token_provider->next (); + locate_token (); + builder ().Push (builder ().token (t)); + return true; + } else { + if (! _problem_token) + _problem_token = token_provider->current (); + return false; + } +} + +bool Syntax::parse (int *token) { + while (*token) { + if (parse (*token)) + return true; + token++; + } + return false; +} + +void Syntax::skip_block (int open, int close, bool inclusive) { + Token *current; + int token; + int depth = 0; + + while ((current = token_provider->current ())) { + token = current->type (); + + if (token == open) + depth++; + else if (token == close) + depth--; + else if (depth > 0 && token == TOK_OPEN_ROUND) { + skip_round_block (); + continue; + } + + if (depth == 0 && !inclusive) + break; + + token_provider->next (); + locate_token (); + + if (depth == 0) + break; + } +} + +void Syntax::skip_round_block () { + skip_block (TOK_OPEN_ROUND, TOK_CLOSE_ROUND); +} + +void Syntax::skip_curly_block () { + skip_block (TOK_OPEN_CURLY, TOK_CLOSE_CURLY); +} + +bool Syntax::parse_block (int open, int close) { + int depth = 0; + int token; + while ((token = look_ahead ())) { + consume (); + if (token == open) + depth++; + else if (token == close) + depth--; + if (depth == 0) + return true; + } + return false; +} + +bool Syntax::parse_round_block () { + return parse_block (TOK_OPEN_ROUND, TOK_CLOSE_ROUND); +} + +bool Syntax::parse_curly_block () { + return parse_block (TOK_OPEN_CURLY, TOK_CLOSE_CURLY); +} + +bool Syntax::skip (int *stop_tokens, bool inclusive) { + Token *current; + int token; + + while ((current = token_provider->current ())) { + token = current->type (); + + if (is_in (token, stop_tokens)) + break; + + if (token == TOK_OPEN_CURLY) + skip_curly_block (); + else if (token == TOK_OPEN_ROUND) + skip_round_block (); + else { + token_provider->next (); + locate_token (); + } + } + + if (current && inclusive && current->type () != TOK_CLOSE_CURLY) { + token_provider->next (); + locate_token (); + } + + return false; +} + +bool Syntax::skip (int stop_token, bool inclusive) { + Token *current; + int token; + + while ((current = token_provider->current ())) { + token = current->type (); + + if (token == stop_token) + break; + + if (token == TOK_OPEN_CURLY) + skip_curly_block (); + else if (token == TOK_OPEN_ROUND) + skip_round_block (); + else { + token_provider->next (); + locate_token (); + } + } + + if (current && inclusive && current->type () != TOK_CLOSE_CURLY) { + token_provider->next (); + locate_token (); + } + + return false; +} + +void Syntax::skip () { + token_provider->next (); + locate_token (); +} + +bool Syntax::is_in (int token, int *set) const { + int i = 0; + while (set[i] && set[i] != token) + i++; + return (set[i] != 0); +} + + +} // namespace Puma diff --git a/Puma/src/parser/Syntax.h b/Puma/src/parser/Syntax.h new file mode 100644 index 0000000..8792230 --- /dev/null +++ b/Puma/src/parser/Syntax.h @@ -0,0 +1,606 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __Syntax_h__ +#define __Syntax_h__ + +/** \file + * Basic syntactic analysis component. */ + +/** \page syntax Syntactic Analysis + */ + +#include "Puma/Unit.h" +#include "Puma/Token.h" +#include "Puma/Builder.h" +#include "Puma/ErrorSink.h" +#include "Puma/TokenProvider.h" + +#include + +namespace Puma { + +class Semantic; +class Config; +class CTree; + + +/** \class Syntax Syntax.h Puma/Syntax.h + * Syntactic analysis base class. + * + * Implements the top-down parsing algorithm (recursive descend parser). + * To be derived to implement parsers for specific grammars. Provides + * infinite look-ahead. + * + * This class uses a tree builder object (see Builder) to create the + * syntax tree, and a semantic analysis object (see Semantic) to perform + * required semantic analyses of the parsed code. + * + * The parse process is started by calling Syntax::run() with a token + * provider as argument. Using the token provider this method reads the + * first core language token from the input source code and tries to parse + * it by applying the top grammar rule. + * + * \code return parse(&Puma::Syntax::trans_unit) ? builder().Top() : (Puma::CTree*)0; \endcode + * + * The top grammar rule has to be provided by reimplementing method + * Syntax::trans_unit(). It may call sub-rules according to the implemented + * language-specific grammar. Example: + * + * \code + * Puma::CTree *MySyntax::trans_unit() { + * return parse(&MySyntax::block_seq) ? builder().block_seq() : (Puma::CTree*)0; + * } + * \endcode + * + * For context-sensitive grammars it may be necessary in the rules of + * the grammar to perform first semantic analyses of the parsed code + * (to differentiate ambigous syntactic constructs, resolve names, + * detect errors, and so one). Example: + * + * \code + * Puma::CTree *MySyntax::block() { + * // '{' instruction instruction ... '}' + * if (parse(TOK_OPEN_CURLY)) { // parse '{' + * semantic().enter_block(); // enter block scope + * seq(&MySyntax::instruction); // parse sequence of instructions + * semantic().leave_block(); // leave block scope + * if (parse(TOK_CLOSE_CURLY)) { // parse '}' + * return builder().block(); // build syntax tree for the block + * } + * } + * return (CTree*)0; // rule failed + * } + * \endcode + * + * If a rule could be parsed successfully the tree builder is used to + * create a CTree based syntax tree (fragment) for the parsed rule. Failing + * grammar rules shall return NULL. The result of the top grammar rule is + * the root node of the abstract syntax tree for the whole input source code. */ +class Syntax { + Token *_problem_token; + bool _have_error; + bool _verbose_errors; + + Builder &_builder; + Semantic &_semantic; + +public: + /** Token provider for getting the tokens to parse. */ + TokenProvider *token_provider; + + /** Interface for aspects that affect the syntax and parsing process */ + pointcut parse_fct() = "bool Puma::%::%::parse(%)"; + pointcut check_fct() = "bool Puma::%::%::check(%)"; + pointcut in_syntax() = within(member(derived("Puma::Syntax"))); + pointcut rule_exec() = execution(parse_fct()) && in_syntax(); + pointcut rule_call() = call(parse_fct()) && in_syntax() && !within("Puma::%::...::%"); + pointcut rule_check() = execution(check_fct()) && in_syntax(); + +public: + /** \class State Syntax.h Puma/Syntax.h + * Parser state, the current position in the token stream. */ + struct State : public TokenProvider::State { + /** Constructor. */ + State () {} + /** Constructor. */ + State (int) {} + /** Copy constructor. + * \param s The parser state to copy. */ + State (const TokenProvider::State &s) : TokenProvider::State (s) {} + }; + +protected: + /** Constructor. + * \param b The syntax tree builder. + * \param s The semantic analysis object. */ + Syntax (Builder &b, Semantic &s); + /** Destructor. */ + virtual ~Syntax () {} + +public: + /** Start the parse process. + * \param tp The token provider from where to get the tokens to parse. + * \return The resulting syntax tree. */ + CTree *run (TokenProvider &tp); + /** Start the parse process at a specific grammar rule. + * \param tp The token provider from where to get the tokens to parse. + * \param rule The grammar rule where to start. + * \return The resulting syntax tree. */ + template CTree *run (TokenProvider &tp, bool (T::*rule)()); + /** Configure the syntactic analysis object. + * \param c The configuration object. */ + virtual void configure (Config &c); + /** Get the token provider from which the parsed tokens are read. */ + TokenProvider *provider () const { return token_provider; } + /** Get the last token that could not be parsed. */ + Token *problem () const; + /** Check if errors occured during the parse process. */ + bool error () const; + /** Look-ahead n core language tokens and check if + * the n-th token has the given type. + * \param token_type The type of the n-th token. + * \param n The number of tokens to look-ahead. + * \return True if the n-th token has the given type. */ + bool look_ahead (int token_type, unsigned n = 1); + /** Look-ahead n core language tokens and check if + * the n-th token has one of the given types. + * \param token_types The possible types of the n-th token. + * \param n The number of tokens to look-ahead. + * \return True if the n-th token has one of the given types. */ + bool look_ahead (int* token_types, unsigned n = 1); + /** Look-ahead one core language token. + * \param n The number of tokens to look-ahead. + * \return The type of the next core language token. */ + int look_ahead (unsigned n = 1); + /** Consume all tokens until the next core language token. */ + bool consume (); + + typedef std::bitset tokenset; + + // check if the current token is in FIRST set 'ts' + inline bool predict_1 (const tokenset &ts) { + return ts[look_ahead ()]; + } + + /** Parse the given grammar rule. Saves the current state of + * the builder, semantic, and token provider objects. + * \param rule The rule to parse. + * \return True if parsed successfully. */ + template bool parse (CTree *(T::*rule)()); + /** Parse a sequence of the given grammar rule. + * \param rule The rule to parse at least once. + * \return True if parsed successfully. */ + template bool seq (CTree *(T::*rule)()); + /** Parse a sequence of the given grammar rule. + * \param rule The rule to parse at least once. + * \return True if parsed successfully. */ + template bool seq (bool (T::*rule)()); + /** Parse a sequence of the given grammar rule by calling RULE::check() in a loop. + * \param s A pointer to the syntax object on which the rule should be executed + * \tparam SYNTAX The type of syntax + * \tparam RULE The class that represents the grammar rule + * \return True if parsed successfully. */ + template static bool seq (SYNTAX &s); + /** Parse a sequence of rule-separator pairs. + * \param rule The rule to parse at least once. + * \param separator The separator token. + * \param trailing_separator True if a trailing separator token is allowed. + * \return True if parsed successfully. */ + template bool list (CTree *(T::*rule)(), int separator, bool trailing_separator = false); + /** Parse a sequence of rule-separator pairs. + * \param rule The rule to parse at least once. + * \param separators The separator tokens. + * \param trailing_separator True if a trailing separator token is allowed. + * \return True if parsed successfully. */ + template bool list (CTree *(T::*rule)(), int* separators, bool trailing_separator = false); + /** Parse a sequence of rule-separator pairs. + * \param rule The rule to parse at least once. + * \param separator The separator token. + * \param trailing_separator True if a trailing separator token is allowed. + * \return True if parsed successfully. */ + template bool list (bool (T::*rule)(), int separator, bool trailing_separator = false); + /** Parse a sequence of rule-separator pairs. + * \param rule The rule to parse at least once. + * \param separators The separator tokens. + * \param trailing_separator True if a trailing separator token is allowed. + * \return True if parsed successfully. */ + template bool list (bool (T::*rule)(), int* separators, bool trailing_separator = false); + /** Parse a sequence of rule-separator pairs by calling RULE::check() in a loop. + * \param s A pointer to the syntax object on which the rule should be executed + * \tparam SYNTAX The type of syntax + * \tparam RULE The class that represents the grammar rule + * \param sep The separator token + * \param trailing_sep True if a trailing separator token is allowed. + * \return True if parsed successfully. */ + template + static bool list (SYNTAX &s, int sep, bool trailing_sep = false); + /** Parse a sequence of rule-separator pairs by calling RULE::check() in a loop. + * \param s A pointer to the syntax object on which the rule should be executed + * \tparam SYNTAX The type of syntax + * \tparam RULE The class that represents the grammar rule + * \param separators The separator tokens + * \param trailing_sep True if a trailing separator token is allowed. + * \return True if parsed successfully. */ + template + static bool list (SYNTAX &s, int *separators, bool trailing_sep = false); + /** Parse a grammar rule automatically catching parse errors. + * \param rule The rule to parse. + * \param msg The error message to show if the rule fails. + * \param finish_tokens Set of token types that abort parsing the rule. + * \param skip_tokens If the rule fails skip all tokens until a token is read + * that has one of the types given here. + * \return False if at EOF or a finish_token is read, true otherwise. */ + template bool catch_error (bool (T::*rule)(), const char* msg, int* finish_tokens, int* skip_tokens); + /** Parse a grammar rule automatically catching parse errors. + * \tparam SYNTAX The type of syntax + * \tparam RULE The class that represents the grammar rule + * \param s A pointer to the syntax object on which the rule should be executed + * \param msg The error message to show if the rule fails. + * \param finish_tokens Set of token types that abort parsing the rule. + * \param skip_tokens If the rule fails skip all tokens until a token is read + * that has one of the types given here. + * \return False if at EOF or a finish_token is read, true otherwise. */ + template + static bool catch_error (SYNTAX &s, const char *msg, int *finish_tokens, int *skip_tokens); + /** First parse rule1 and if that rule fails discard all errors and parse the rule2. + * \tparam RULE1 The class that represents the first grammar rule + * \tparam RULE2 The class that represents the second grammar rule + * \tparam SYNTAX The type of syntax + * \param s The syntax object on which the rules should be executed */ + template + static bool ambiguous (SYNTAX &s); + /** Parse a token with the given type. + * \param token_type The token type. + * \return True a corresponding token was parsed. */ + bool parse (int token_type); + /** Parse a token with one of the given types. + * \param token_types The token types. + * \return True a corresponding token was parsed. */ + bool parse (int *token_types); + /** Parse a token with the given type. + * \param token_type The token type. + * \return True a corresponding token was parsed. */ + bool parse_token (int token_type); + /** Optional rule parsing. Always succeeds regardless + * of the argument. + * \param dummy Dummy parameter, is not evaluated. + * \return True. */ + bool opt (bool dummy) const; + + /** Get the syntax tree builder. */ + Builder &builder () const; + /** Get the semantic analysis object. */ + Semantic &semantic () const; + + /** Top parse rule to be reimplemented for a specific grammar. + * \return The root node of the syntax tree, or NULL. */ + virtual bool trans_unit (); + + /** Handle a compiler directive token. The default handling is + * to skip the compiler directive. */ + virtual void handle_directive (); + + /** Save the current parser state. Calls save_state() on the + * builder, semantic, and token provider objects. + * \return The current parser state. */ + State save_state (); + /** Forget the saved parser state. */ + void forget_state (); + /** Restore the saved parser state. Triggers restoring the + * syntax and semantic trees to the saved state. */ + void restore_state (); + /** Restore the saved parser state to the given state. + * Triggers restoring the syntax and semantic trees. + * \param state The state to which to restore. */ + void restore_state (State state); + /** Overwrite the parser state with the given state. + * \param state The new parser state. */ + void set_state (State state); + + /** Accept the given syntax tree node. If the node is NULL + * then the parser state is restored to the given state. + * Otherwise all saved states are discarded. + * \param tree Tree to accept. + * \param state The saved state. */ + bool accept (CTree *tree, State state); + /** Accept the given syntax tree node. Returns the given node. + * \param tree Tree to accept. */ + CTree* accept (CTree *tree); + + /** Skip all non-core language tokens until the next + * core-language token is read. + * \return The next core-language token. */ + Token *locate_token (); + /** Skip the current token. */ + void skip (); + /** Skip all tokens between start and end, including + * start and end token. + * \param start The start token type. + * \param end The end token type. + * \param inclusive If true, the stop token is skipped too. */ + void skip_block (int start, int end, bool inclusive = true); + /** Skip all tokens between '{' and '}', including + * '{' and '}'. */ + void skip_curly_block (); + /** Skip all tokens between '(' and ')', including + * '(' and ')'. */ + void skip_round_block (); + /** Parse all tokens between start and end, including + * start and end token. + * \param start The start token type. + * \param end The end token type. + * \return False if the stop token is not found, true otherwise. */ + bool parse_block (int start, int end); + /** Parse all tokens between '{' and '}', including + * '{' and '}'. + * \return False if the stop token '}' is not found, true otherwise. */ + bool parse_curly_block (); + /** Parse all tokens between '(' and ')', including + * '(' and ')'. + * \return False if the stop token ')' is not found, true otherwise. */ + bool parse_round_block (); + /** Skip all tokens until a token with the given type is read. + * \param stop_token The type of the token to stop. + * \param inclusive If true, the stop token is skipped too. + * \return False if the stop token is not found, true otherwise. */ + bool skip (int stop_token, bool inclusive = true); + /** Skip all tokens until a token with one of the given types is read. + * \param stop_tokens The types of the token to stop. + * \param inclusive If true, the stop token is skipped too. + * \return False if the stop token is not found, true otherwise. */ + bool skip (int *stop_tokens, bool inclusive = true); + /** Check if the given token type is in the set of given token types. + * \param token_type The token type to check. + * \param token_types The set of token types. */ + bool is_in (int token_type, int *token_types) const; +}; + +inline Syntax::Syntax (Builder &b, Semantic &s) : + _problem_token ((Token*)0), + _have_error (false), + _verbose_errors (false), + _builder (b), + _semantic (s) { +} + +template +CTree *Syntax::run (TokenProvider &tp, bool (T::*rule)()) { + TokenProvider *tp_save = token_provider; + token_provider = &tp; + token_provider->init(); + _have_error = false; + _problem_token = (Token*)0; + locate_token (); + CTree *result = (((T*)this)->*rule)() ? builder ().Top () : (CTree*)0; + if (result) builder ().Pop (); + token_provider = tp_save; + return result; +} + + +inline int Syntax::look_ahead (unsigned n) { + Token *token = token_provider->current (); + if (n > 1) { + State s = token_provider->get_state (); + for (unsigned i = 1; i < n; i++) { + token_provider->next (); + locate_token (); + } + token = token_provider->current (); + token_provider->set_state (s); + } + return token ? token->type () : 0; +} + +inline bool Syntax::consume () { + Token *t = token_provider->current (); + _problem_token = (Token*)0; + token_provider->next (); + locate_token (); + builder ().Push (builder ().token (t)); + return true; +} + + +inline bool Syntax::parse (int token_type) { return parse_token (token_type); } +inline bool Syntax::opt (bool) const { return true; } +inline bool Syntax::error () const { return _have_error; } +inline Token *Syntax::problem () const { return _problem_token; } +inline Builder &Syntax::builder () const { return _builder; } +inline Semantic &Syntax::semantic () const { return _semantic; } + +inline bool Syntax::trans_unit () { return false; } + +inline void Syntax::handle_directive () { + while (token_provider->current () && + token_provider->current ()->is_directive ()) + token_provider->next (); +} + +template +inline bool Syntax::parse (CTree *(T::*rule)()) { + State s = save_state (); + return accept ((((T*)this)->*rule) (), s); +} + +template +inline bool Syntax::seq (CTree *(T::*rule)()) { + if (! parse (rule)) + return false; + while (parse (rule)); + return true; +} + +template +inline bool Syntax::seq ( bool (T::*rule)()) { + if (!(((T*)this)->*rule) ()) + return false; + while ((((T*)this)->*rule) ()); + return true; +} + +template bool Syntax::seq (SYNTAX &s) { + if (!RULE::check (s)) + return false; + while (RULE::check (s)); + return true; +} + +template +inline bool Syntax::list (CTree *(T::*rule)(), int token_type, bool end_sep) { + if (! parse (rule)) + return false; + while (parse (token_type)) + if (! parse (rule)) + return end_sep ? true : false; + return true; +} + +template +inline bool Syntax::list (bool (T::*rule)(), int token_type, bool end_sep) { + if (! (((T*)this)->*rule) ()) + return false; + while (parse (token_type)) + if (! (((T*)this)->*rule) ()) + return end_sep ? true : false; + return true; +} + +template +inline bool Syntax::list (SYNTAX &s, int separator, bool trailing_sep) { + if (!RULE::check (s)) + return false; + while (s.parse (separator)) + if (!RULE::check (s)) + return trailing_sep ? true : false; + return true; +} + +template +inline bool Syntax::list (SYNTAX &s, int *separators, bool trailing_sep) { + if (!RULE::check (s)) + return false; + while (s.parse (separators)) + if (!RULE::check (s)) + return trailing_sep ? true : false; + return true; +} + +template +inline bool Syntax::list (CTree *(T::*rule)(), int *token_type_set, bool end_sep) { + if (! parse (rule)) + return false; + while (parse (token_type_set)) + if (! parse (rule)) + return end_sep ? true : false; + return true; +} + +template +inline bool Syntax::list (bool (T::*rule)(), int *token_type_set, bool end_sep) { + if (! (((T*)this)->*rule) ()) + return false; + while (parse (token_type_set)) + if (! (((T*)this)->*rule) ()) + return end_sep ? true : false; + return true; +} + +template +bool Syntax::catch_error (bool (T::*rule)(), const char *msg, + int *finish_tokens, int *skip_tokens) { + Token *current_pos, *token; + int index; + + current_pos = token_provider->current (); + if (! current_pos || is_in (current_pos->type (), finish_tokens)) + return false; + + index = ((ErrorCollector&)builder ().err ()).index (); + if ((((T*)this)->*rule)()) + return true; + + _have_error = true; + token = problem () ? problem () : current_pos; + builder ().Push (builder ().error ()); + + // if there is no detailed error message generate a standard message + if (index == ((ErrorCollector&)builder ().err ()).index ()) { + builder ().err () << sev_error << token->location () << msg + << " near token `" << token->text () << "'" << endMessage; + // if the error is located in not a file unit, print the whole unit + if (_verbose_errors && token->unit () && !token->unit ()->isFile ()) { + builder ().err () << token->location () << "located in the following non-file unit:\n" + << *token->unit() << endMessage; + } + } + + skip (skip_tokens, false); + return true; +} + +template +bool Syntax::catch_error (SYNTAX &s, const char *msg, + int *finish_tokens, int *skip_tokens) { + + Token *current_pos, *token; + int index; + Builder &builder = ((Syntax&)s).builder (); + + current_pos = s.token_provider->current (); + if (! current_pos || s.is_in (current_pos->type (), finish_tokens)) + return false; + + index = ((ErrorCollector&)builder.err ()).index (); + if (RULE::check (s)) + return true; + + s._have_error = true; + token = s.problem () ? s.problem () : current_pos; + builder.Push (builder.error ()); + + // if there is no detailed error message generate a standard message + if (index == ((ErrorCollector&)builder.err ()).index ()) { + builder.err () << sev_error << token->location () << msg + << " near token `" << token->text () << "'" << endMessage; + // if the error is located in not a file unit, print the whole unit + if (s._verbose_errors && token->unit () && !token->unit ()->isFile ()) { + builder.err () << token->location () << "located in the following non-file unit:\n" + << *token->unit() << endMessage; + } + } + + s.skip (skip_tokens, false); + return true; +} + +template +inline bool Syntax::ambiguous (SYNTAX &s) { + Builder& builder = ((Syntax&)s).builder (); + ErrorCollector& ec = (ErrorCollector&) builder.err (); + int index = ec.index (); + if (RULE1::check (s)) + return true; + ec.index (index); // restore error state for ambiguous rule + return RULE2::check (s);; +} + +} // namespace Puma + +#endif /* __Syntax_h__ */ diff --git a/Puma/src/parser/SyntaxBuilder.ah b/Puma/src/parser/SyntaxBuilder.ah new file mode 100644 index 0000000..4ebd6f9 --- /dev/null +++ b/Puma/src/parser/SyntaxBuilder.ah @@ -0,0 +1,51 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __SyntaxBuilder_ah__ +#define __SyntaxBuilder_ah__ + +#include "Puma/Syntax.h" +//#include "Puma/Builder.h" + +aspect SyntaxBuilder { + + advice Puma::Syntax::rule_call() : order ("SyntaxState", "SyntaxBuilder"); + + advice Puma::Syntax::rule_call() : around () { + tjp->proceed (); + if (*tjp->result ()) { + Puma::CTree *tree = JoinPoint::Target::build (*tjp->arg<0>()); + if (tree) { + tjp->that()->builder().forget_state(); + tjp->that()->builder().Push(tree); + } + else + *tjp->result () = false; + } + } + + advice execution("Puma::Syntax::State Puma::Syntax::save_state ()") : after() { + tjp->that()->builder().save_state(); + } + + advice execution("void Puma::Syntax::restore_state (...)") : after() { + tjp->that()->builder().restore_state(); + } +}; + +#endif /* __SyntaxBuilder_ah__ */ diff --git a/Puma/src/parser/SyntaxState.ah b/Puma/src/parser/SyntaxState.ah new file mode 100644 index 0000000..f57a48f --- /dev/null +++ b/Puma/src/parser/SyntaxState.ah @@ -0,0 +1,44 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __SyntaxState_ah__ +#define __SyntaxState_ah__ + +#include "Puma/Syntax.h" +#include "Puma/Semantic.h" + +// This aspect automatically save the parser state before a new rule is +// check. If the rule fails, the state is restored. + +aspect SyntaxState { + + advice Puma::Syntax::rule_call() : around () { + Puma::Syntax &s = *tjp->arg<0>(); + Puma::Syntax::State state = s.save_state (); + tjp->proceed (); + if (*tjp->result()) { + s.forget_state (); + } else { + s.set_state (state); + s.restore_state (); + } + } + +}; + +#endif /* __SyntaxState_ah__ */ diff --git a/Puma/src/parser/TokenProvider.h b/Puma/src/parser/TokenProvider.h new file mode 100644 index 0000000..9e77e41 --- /dev/null +++ b/Puma/src/parser/TokenProvider.h @@ -0,0 +1,105 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __TokenProvider__ +#define __TokenProvider__ + +/** \file + * Token provider abstraction. */ + +#include "Puma/Token.h" +#include "Puma/TokenSource.h" +#include "Puma/BCList.h" + +namespace Puma { + +/** \class TokenInfo TokenProvider.h Puma/TokenProvider.h + * Provides information about a token as it is needed by the parser. + * Especially the instantiation parser needs not only the token + * pointer but also the pointer to the syntax tree, in which the + * token is located. */ +struct TokenInfo { + Token *_token; + void *_context; +}; + + +/** \class TokenProvider TokenProvider.h Puma/TokenProvider.h + * Reads tokens from a token source. Supports unlimited look ahead. + * A token source can be a file, a string, a token preprocessor, + * and so on. */ +class TokenProvider { +protected: + typedef BCList TokenStore; + + TokenSource &_source; + TokenStore _tokens; + TokenStore::Iterator _read_pos; + + /** Read next token. */ + virtual TokenInfo read () { TokenInfo ti; ti._token = _source.next(); ti._context = 0; return ti; } + + /** Get the current token. */ + Token* token () const { return (*_read_pos)._token; } + +public: + /** Read position. */ + typedef TokenStore::Iterator State; + + /** Constructor. + * \param s The token source from which to read the tokens. */ + TokenProvider (TokenSource &s) : _source (s) {} + + /** Destructor. + * The compiler complains if we done define a virtual destrcutor. */ + virtual ~TokenProvider () {} + + /** Initialize the token provider by reading the first token. */ + void init() { _read_pos = _tokens.add (read ()); } + + /** Get the token source. */ + TokenSource& source() const { return (TokenSource&)_source; } + + /** Read the next token from the token source. */ + Token *next () { + // go to the next read position + ++_read_pos; + // did we reach the end of the list? + if (! _read_pos) { + // get next token and add it to the list + _read_pos = _tokens.add (read ()); + } + return current (); + } + + /** Get the last token read from the token source. */ + Token *current () const { return token (); } + + /** Get the context information for the current token. */ + void *current_context () const { return (*_read_pos)._context; } + + /** Get the current read position. */ + State get_state () { return _read_pos; } + /** Restore the read position. + * \param restored_pos The new read position. */ + void set_state (State restored_pos) { _read_pos = restored_pos; } +}; + +} // namespace Puma + +#endif /* __TokenProvider__ */ diff --git a/Puma/src/parser/Tracing.cc b/Puma/src/parser/Tracing.cc new file mode 100644 index 0000000..e269fbb --- /dev/null +++ b/Puma/src/parser/Tracing.cc @@ -0,0 +1,64 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/Tracing.h" +#include "Puma/CTokens.h" +#include "Puma/Token.h" +#include "Puma/CTree.h" +#include + +namespace Puma { + + +std::ostream &Tracing::tos () const { + return *_tos; +} + +void Tracing::trace (std::ostream &os, bool trace_tokens) { + _tos = &os; + _trace = trace_tokens ? 2 : 1; +} + +void Tracing::trace (const char *rule, int n, bool quote) { + if (! _trace) return; + if (n == -1) _tdepth += n; + for (int i = 0; i < _tdepth; i++) + *_tos << "| "; + if (quote) *_tos << "`"; + *_tos << rule; + if (quote) *_tos << "'"; + *_tos << std::endl; + if (n == 1) _tdepth += n; +} + +void Tracing::trace (Token *token, const char *ok, const char *failed) { + if (! _trace) return; + if (token) { + *_tos << token->location () << ": " << ok + << ": " << token->text () << std::endl; + } else + *_tos << failed << std::endl; +} + +const char *Tracing::token_text (int token_type) const { + const char* text = Token::get_static_text (token_type); + return text ? text : ""; +} + + +} // namespace Puma diff --git a/Puma/src/parser/Tracing.h b/Puma/src/parser/Tracing.h new file mode 100644 index 0000000..2c08672 --- /dev/null +++ b/Puma/src/parser/Tracing.h @@ -0,0 +1,84 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __Tracing__ +#define __Tracing__ + +/** \file + * Tracing support for the parser. */ + +#include + +namespace Puma { + + +class Token; + +/** \class Tracing Tracing.h Puma/Tracing.h + * Implements tracing support for the parser. */ +class Tracing { + int _trace; + int _tdepth; + std::ostream *_tos; + +protected: + /** Constructor. */ + Tracing (); + +public: + /** Setup the tracer. + * \param os The output stream on which to write the tracing output. + * \param trace_tokens Turn on/off token level tracing. */ + void trace (std::ostream& os, bool trace_tokens = false); + +protected: + /** Trace the given token. + * \param token The token type. */ + void trace (int token); + /** Trace the given parser rule. + * \param rule The rule name. + * \param n The indentation depth. + * \param quote Quote the rule name. */ + void trace (const char *rule, int n = 1, bool quote = false); + /** Trace the given token. + * \param token The token to trace. + * \param ok The message if the token is not NULL. + * \param failed The message if the token is NULL. */ + void trace (Token *token, const char *ok, const char *failed); + /** Get the current tracing mode. 0 means tracing is disabled, + * 1 means rule level tracing, 2 means token level tracing. */ + int trace_mode () const; + /** Get the tracing output stream. */ + std::ostream &tos () const; + +private: + const char *token_text (int) const; +}; + +inline Tracing::Tracing () : + _trace (0), + _tdepth (0), + _tos ((std::ostream*)0) {} + +inline void Tracing::trace (int token) { trace (token_text (token), 1, true); } +inline int Tracing::trace_mode () const { return _trace; } + + +} // namespace Puma + +#endif /* __Tracing__ */ diff --git a/Puma/src/parser/acparser/ACIntroducer.h b/Puma/src/parser/acparser/ACIntroducer.h new file mode 100644 index 0000000..105026a --- /dev/null +++ b/Puma/src/parser/acparser/ACIntroducer.h @@ -0,0 +1,61 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __ACIntroducer_h__ +#define __ACIntroducer_h__ + +// Interface class that is used for introductions during a parser run. +// The semantics object has a reference to an ACIntroducer and uses +// the interface at some well defined (join) points. + +namespace Puma { + class CT_ClassDef; + class CT_Program; + class Token; +} + +namespace Puma { + +class ACIntroducer { +public: + virtual ~ACIntroducer () {} + + // called when a new class/union/struct/aspect is created, current scope + // is the global scope + virtual void class_before (CT_ClassDef*) {} + + // called when a new class/union/struct/aspect body is parsed + virtual void class_begin (CT_ClassDef*) {} + + // called when a new class/union/struct/aspect definition ends + // (still in the class scope) + virtual void class_end (CT_ClassDef*) {} + + // called after the parser tried to parse a base clause + virtual void base_clause_end (CT_ClassDef*, Token*) {} + + // called at the beginning of the parse process + virtual void trans_unit_begin () {} + + // called after the program has been parsed completely + virtual void trans_unit_end (CT_Program*) {} +}; + +} // namespace Puma + +#endif /* __ACIntroducer_h__ */ diff --git a/Puma/src/parser/acparser/ACIntroducer_dummy.cc b/Puma/src/parser/acparser/ACIntroducer_dummy.cc new file mode 100644 index 0000000..e69de29 diff --git a/Puma/src/parser/ccparser/CCAssocScopes.cc b/Puma/src/parser/ccparser/CCAssocScopes.cc new file mode 100644 index 0000000..e7272da --- /dev/null +++ b/Puma/src/parser/ccparser/CCAssocScopes.cc @@ -0,0 +1,206 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CCAssocScopes.h" +#include "Puma/CTree.h" +#include "Puma/CTypeInfo.h" +#include "Puma/CEnumInfo.h" +#include "Puma/CUnionInfo.h" +#include "Puma/CRecord.h" +#include "Puma/CTemplateInfo.h" +#include "Puma/CTemplateParamInfo.h" +#include "Puma/CNamespaceInfo.h" +#include "Puma/CClassInfo.h" +#include "Puma/CClassInstance.h" +#include "Puma/CUnionInstance.h" +#include "Puma/CFctInstance.h" + +namespace Puma { + + +// 3.4.2 argument-dependent name lookup +void CCAssocScopes::determineAssocScopes (CT_ExprList *args) { + CTypeInfo *type; + int num; + + num = args->Entries (); + for (int i = 0; i < num; i++) { + type = args->Entry (i)->Type (); + if (type) + determineAssocScopes (type); + } +} + + +// 3.4.2.2 determine associated classes and namespaces +void CCAssocScopes::determineAssocScopes (CTypeInfo *type) { + CTypeFunction *ftype; + CTemplateInfo *tinfo; + CStructure *info; + CEnumInfo *einfo; + long num; + + if (type->isPointerOrArray ()) + type = type->VirtualType ()->BaseType (); + type = type->VirtualType (); + if (type->isClass ()) { + info = type->TypeClass ()->ClassInfo (); + if (info) { + if (info->ClassInstance ()) { + tinfo = info->TemplateInstance ()->Template (); + if (tinfo) { + if (tinfo->Parent ()->ClassInfo ()) + classes.append (tinfo->Parent ()->ClassInfo ()); + determineAssocScopes (tinfo, info->TemplateInstance ()->PointOfInstantiation ()); + } + } else { + num = classes.length (); + addBaseClasses (info->ClassInfo ()); + for (int i = num; i < classes.length (); i++) + addEnclosingNamespace (classes[i]); + } + } + } else if (type->isUnion ()) { + info = type->TypeUnion ()->UnionInfo (); + if (info) { + if (info->UnionInstance ()) { + tinfo = info->TemplateInstance ()->Template (); + if (tinfo->Parent ()->ClassInfo ()) + classes.append (tinfo->Parent ()->ClassInfo ()); + determineAssocScopes (tinfo, info->TemplateInstance ()->PointOfInstantiation ()); + return; + } else if (info->Parent ()->ClassInfo ()) + classes.append (info->Parent ()->ClassInfo ()); + addEnclosingNamespace (info); + } + } else if (type->isEnum ()) { + einfo = type->TypeEnum ()->EnumInfo (); + if (einfo) { + info = einfo->Scope ()->Structure (); + if (info->ClassInfo ()) + classes.append (info->ClassInfo ()); + addEnclosingNamespace (info); + } + } else if (type->isFunction ()) { + ftype = type->TypeFunction (); + info = ftype->FunctionInfo (); + if (info && info->FctInstance ()) { + tinfo = info->TemplateInstance ()->Template (); + if (tinfo->ObjectInfo ()->FunctionInfo ()->Record ()) + classes.append (tinfo->ObjectInfo ()->FunctionInfo ()->Record ()); + determineAssocScopes (tinfo, info->TemplateInstance ()->PointOfInstantiation ()); + return; + } + determineAssocScopes (ftype->ReturnType ()); + determineAssocScopes (ftype->ArgTypes ()); + } else if (type->isMemberPointer ()) { + info = type->TypeMemberPointer ()->Record (); + if (info) + determineAssocScopes (info->TypeInfo ()); + determineAssocScopes (type->VirtualType ()-> + TypeMemberPointer ()->BaseType ()); + } +} + + +// 3.4.2.2 determine associated scopes of template-ids +void CCAssocScopes::determineAssocScopes (CTemplateInfo *tinfo, CTree *n) { + CTemplateParamInfo *tpinfo; + CT_TemplateArgList *al; + CTemplateInfo *ttpinfo; + CT_TemplateName *name; + CTypeInfo *type; + unsigned num; + + addEnclosingNamespace (tinfo); + + if (n->NodeName () != CT_TemplateName::NodeId ()) + return; + + name = (CT_TemplateName*)n; + al = name->Arguments (); + num = (unsigned)al->Entries (); + for (unsigned i = 0; i < tinfo->TemplateParams (); i++) { + tpinfo = tinfo->TemplateParam (i); + if (num > i) + type = al->Entry ((int)i)->Type (); + else if (tpinfo->DefaultArgument ()) + type = tpinfo->DefaultArgument ()->Type (); + else + continue; + if (! type) + continue; + + // template template argument + if (tpinfo->isTemplate ()) { + ttpinfo = type->TypeRecord ()->Record ()->TemplateInfo (); + addEnclosingNamespace (ttpinfo); + if (ttpinfo->Parent ()->ClassInfo ()) + classes.append (ttpinfo->Parent ()->ClassInfo ()); + // type template argument + } else if (tpinfo->isTypeParam ()) + determineAssocScopes (type); + } +} + + +void CCAssocScopes::determineAssocScopes (CTypeList *argtypes) { + for (unsigned i = 0; i < argtypes->Entries (); i++) + determineAssocScopes (argtypes->Entry (i)); +} + + +void CCAssocScopes::addEnclosingNamespace (CStructure *info) { + if (info != 0) { + while (! info->isNamespace () || info->NamespaceInfo ()->aroundInstantiation ()) + info = info->Parent ()->Structure (); + addNamespace (info->NamespaceInfo ()); + } +} + + +void CCAssocScopes::addNamespace (CNamespaceInfo *info, bool add_inline_parent) { + for (unsigned i = 0; i < Namespaces (); i++) + if (Namespace (i) == info) + return; + + namespaces.append (info); + + // In argument-dependent lookup, when a namespace is added to the set of + // associated namespaces, its inline namespaces are added as well, and if + // an inline namespace is added to the list of associated namespaces, its + // enclosing namespace is added as well. + if (info->isInline ()) { + if (add_inline_parent) + addEnclosingNamespace (info->Parent ()->Structure ()); + } else { + for (unsigned i = 0; i < info->Namespaces (); i++) + if (info->Namespace (i)->isInline ()) + addNamespace (info->Namespace (i), false); + } +} + + +void CCAssocScopes::addBaseClasses (CClassInfo *info) { + classes.append (info); + for (unsigned i = 0; i < info->BaseClasses (); i++) + addBaseClasses (info->BaseClass (i)->Class ()); +} + + +} // namespace Puma diff --git a/Puma/src/parser/ccparser/CCAssocScopes.h b/Puma/src/parser/ccparser/CCAssocScopes.h new file mode 100644 index 0000000..ca74d2c --- /dev/null +++ b/Puma/src/parser/ccparser/CCAssocScopes.h @@ -0,0 +1,84 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CCAssocScopes__ +#define __CCAssocScopes__ + +// determine classes and namespaces associated with the +// arguments of an unqualified function call (3.4.2) + +#include "Puma/Array.h" +#include "Puma/ErrorSink.h" + +namespace Puma { + + +class CStructure; +class CT_ExprList; +class CClassInfo; +class CNamespaceInfo; +class CTypeInfo; +class CTypeList; +class CTemplateInfo; +class CT_SimpleName; +class CRecord; +class CTree; + +class CCAssocScopes { + Array classes; // associated classes + Array namespaces; // associated namespaces + +public: + CCAssocScopes (CT_ExprList * = 0); + ~CCAssocScopes (); + + void determineAssocScopes (CTypeInfo *); + + // associated classes and namespaces + unsigned Classes () const; + unsigned Namespaces () const; + CRecord *Class (unsigned); + CNamespaceInfo *Namespace (unsigned); + +private: + void determineAssocScopes (CT_ExprList *); + void determineAssocScopes (CTemplateInfo *, CTree *); + void determineAssocScopes (CTypeList *); + void addNamespace (CNamespaceInfo *, bool add_inline_parent = true); + void addEnclosingNamespace (CStructure *); + void addBaseClasses (CClassInfo *); +}; + +inline CCAssocScopes::CCAssocScopes (CT_ExprList *argument_list) + { if (argument_list) determineAssocScopes (argument_list); } +inline CCAssocScopes::~CCAssocScopes () + {} + +inline unsigned CCAssocScopes::Classes () const + { return (unsigned)classes.length (); } +inline unsigned CCAssocScopes::Namespaces () const + { return (unsigned)namespaces.length (); } +inline CRecord *CCAssocScopes::Class (unsigned c) + { return classes.lookup (c); } +inline CNamespaceInfo *CCAssocScopes::Namespace (unsigned n) + { return namespaces.lookup (n); } + + +} // namespace Puma + +#endif /* __CCAssocScopes__ */ diff --git a/Puma/src/parser/ccparser/CCBuilder.cc b/Puma/src/parser/ccparser/CCBuilder.cc new file mode 100644 index 0000000..47acfec --- /dev/null +++ b/Puma/src/parser/ccparser/CCBuilder.cc @@ -0,0 +1,1407 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CCBuilder.h" +#include "Puma/CCSyntax.h" +#include "Puma/CTokens.h" +#include "Puma/CTemplateInstance.h" +#include "Puma/DelayedParseTree.h" + +namespace Puma { + + +void CCBuilder::cleanup(CTree* tree) { + if (! tree) + return; + + for (int i = tree->Sons()-1; i >= 0; i--) + cleanup(tree->Son(i)); + + if (tree->NodeName() == CT_TemplateName::NodeId()) { + // remove the template instance from the template + CObjectInfo* obj = tree->SemObject()->Object(); + if (obj) { + CTemplateInstance* instance = obj->TemplateInstance(); + if (instance && instance->PointOfInstantiation() == tree && instance->Template()) { + instance->Template()->removeInstance(instance->Object()); + } + } + } else if (tree->IsDelayedParse()) { + // remove the delayed parse node from the corresponding class + CT_DelayedParse* dp = (CT_DelayedParse*)tree; + if (dp->Class()) + dp->Class()->removeDelayed(dp); + } +} + + +void CCBuilder::Delete() { + cleanup(Top()); + CBuilder::Delete(); +} + + + +/*****************************************************************************/ +/* */ +/* A . 1 K e y w o r d s */ +/* */ +/*****************************************************************************/ + +CTree *CCBuilder::namespace_name () { + // 1: original_ns_name + // 1: namespace_alias + return get_node (); +} + +/*****************************************************************************/ +/* */ +/* A . 4 E x p r e s s i o n s */ +/* */ +/*****************************************************************************/ + +CTree *CCBuilder::prim_expr () { + // 1: literal => node + // 1: THIS => token + // 1: id_expr => node + // 3: ( expr ) => token node token + if (nodes () == 3) + return new CT_BracedExpr (get_node (0), get_node (1), get_node (2)); + else if (get_node ()->token ()->type () == TOK_THIS) + return simple_name (); + else + return get_node (); +} + +CTree *CCBuilder::id_expr () { + return get_node (); +} + +CTree *CCBuilder::unqual_id () { + // 1: template_id + // 1: identifier + // 1: oper_fct_id + // 1: conv_fct_id + // 2: ~ class_name + if (nodes () == 2) + return new CT_DestructorName (get_node (0), get_node (1)); + else + return get_node (); +} + +CTree *CCBuilder::qual_id () { + // 2: :: identifier + // 2: :: oper_fct_id + // 2: :: template_id + // 2: nested_name_spec unqual_id + // 3: :: nested_name_spec unqual_id + // 3: nested_name_spec template_key unqual_id + // 4: :: nested_name_spec template_key unqual_id + CT_QualName *result; + int root = 0, num = nodes (); + if (get_node (0)->NodeName () != Container::NodeId ()) { + root = 1; + if (num == 2) { + result = new CT_RootQualName (2); + result->AddSon (get_node (0)); + result->AddSon (get_node (1)); + return result; + } + } + + Container *nns = (Container*)get_node (root); + CT_SimpleName *sn = (CT_SimpleName*)get_node (num-1); + // name prefixed by `template' + if (get_node (num-2)->NodeName () != Container::NodeId ()) + sn->PrefixSon (get_node (num-2)); + if (root == 1) { + result = new CT_RootQualName (nns->Sons ()+2); + result->AddSon (get_node (0)); + } else + result = new CT_QualName (nns->Sons ()+1); + copy_list (result, nns); + result->AddSon (sn); + delete nns; + return result; +} + +CTree *CCBuilder::nested_name_spec () { + Container *c, *nns = (Container*)get_node (); + CT_SimpleName *sn; + int sons; + + for (int i = 1; i < nodes (); i++) { + c = (Container*)get_node (i); + sons = c->Sons (); + sn = (CT_SimpleName*)c->Son (sons-2); + if (sons == 3) + sn->PrefixSon (c->Son (0)); + nns->AddSon (sn); + nns->AddSon (c->Son (sons-1)); + delete c; + } + return nns; +} + +CTree *CCBuilder::nested_name_spec1 () { + return container (); +} + +CTree *CCBuilder::class_or_ns_name () { + // 1: class_name + // 1: namespace_name + return get_node (); +} + +CTree *CCBuilder::postfix_expr (CTree *postfix) { + // 1 : postfix_expr2 + // 1+: postfix_expr2 postfix_expr1.. + CTree *result = postfix; + if (nodes () == 1) { + result = get_node (0); + } else { + Container *c = (Container*)get_node (nodes ()-1); + // 1: -- + // 1: ++ + // 2: . id_expr + // 2: -> id_expr + // 2: . pseudo_dtor_name + // 2: -> pseudo_dtor_name + // 2: ( ) + // 3: . template_key id_expr + // 3: -> template_key id_expr + // 3: ( expr_list ) + // 3: [ expr ] + int token = c->token ()->type (); + if (token == TOK_DECR || token == TOK_INCR) + result = new CT_PostfixExpr (result, c->Son (0)); + else if (token == TOK_OPEN_SQUARE) + result = new CT_IndexExpr (result, c->Son (0), c->Son (1), c->Son (2)); + else if (token == TOK_DOT || token == TOK_PTS) { + CT_SimpleName *sn = (CT_SimpleName*)c->Son (c->Sons ()-1); + // name prefixed by `template' + if (c->Sons () == 3) + sn->PrefixSon (c->Son (1)); + if (token == TOK_DOT) + result = new CT_MembRefExpr (result, c->Son (0), sn); + else + result = new CT_MembPtrExpr (result, c->Son (0), sn); + } else if (token == TOK_OPEN_ROUND) { + bool args = (c->Sons () == 3); + CT_ExprList *el = args ? (CT_ExprList*)c->Son (1) : new CT_ExprList; + el->AddProperties (CT_List::OPEN_CLOSE); + el->PrefixSon (c->Son (0)); + el->AddSon (c->Son (args ? 2 : 1)); + result = new CT_CallExpr (result, el); + } + delete c; + } + return result; +} + +CTree *CCBuilder::postfix_expr2 () { + // 1 : cmpd_literal + // 1 : prim_expr + // 1 : construct_expr + // 4 : TYPEID ( expr ) + // 4 : TYPEID ( type_id ) + // 7 : CONST_CAST < type_id > ( expr ) + // 7 : REINT_CAST < type_id > ( expr ) + // 7 : STATIC_CAST < type_id > ( expr ) + // 7 : DYNAMIC_CAST < type_id > ( expr ) + int num = nodes (); + // typeid ( ... ) + if (num == 4) { + return new CT_TypeidExpr (get_node (0), get_node (1), + get_node (2), get_node (3)); + } + // new style casts + else if (num == 7) { + int type = get_node (0)->token ()->type (); + CTree* expr = new CT_BracedExpr (get_node (4), get_node (5), get_node (6)); + if (type == TOK_REINT_CAST) + return new CT_ReintCast (get_node (0), get_node (1), get_node (2), + get_node (3), expr); + else if (type == TOK_CONST_CAST) + return new CT_ConstCast (get_node (0), get_node (1), get_node (2), + get_node (3), expr); + else if (type == TOK_STAT_CAST) + return new CT_StaticCast (get_node (0), get_node (1), get_node (2), + get_node (3), expr); + else if (type == TOK_DYN_CAST) + return new CT_DynamicCast (get_node (0), get_node (1), get_node (2), + get_node (3), expr); + } + return get_node (0); +} + +CTree *CCBuilder::construct_expr () { + // 3 : simple_type_spec ( ) + // 4 : simple_type_spec ( expr_list ) + // 5 : TYPENAME nested_name_spec identifier ( ) + // 5 : TYPENAME nested_name_spec template_id ( ) + // 6 : TYPENAME nested_name_spec identifier ( expr_list ) + // 6 : TYPENAME nested_name_spec template_id ( expr_list ) + // 6 : TYPENAME nested_name_spec template_key template_id ( ) + // 6 : TYPENAME :: nested_name_spec identifier ( ) + // 6 : TYPENAME :: nested_name_spec template_id ( ) + // 7 : TYPENAME :: nested_name_spec identifier ( expr_list ) + // 7 : TYPENAME :: nested_name_spec template_id ( expr_list ) + // 7 : TYPENAME :: nested_name_spec template_key template_id ( ) + // 7 : TYPENAME nested_name_spec template_key template_id ( expr_list ) + // 8 : TYPENAME :: nested_name_spec template_key template_id ( expr_list ) + CT_ExprList *el; + int num = nodes (); + // TYPENAME ... + if (num > 4) { + int offset = 0; + if (get_node (num-2)->NodeName () == CT_ExprList::NodeId ()) { + el = (CT_ExprList*)get_node (num-2); + el->PrefixSon (get_node (num-3)); + offset = 1; + } else { + el = new CT_ExprList; + el->PrefixSon (get_node (num-2)); + } + el->AddSon (get_node (num-1)); + el->AddProperties (CT_List::OPEN_CLOSE); + + CT_SimpleName *name = (CT_SimpleName*)get_node (num-3-offset); + // name prefixed by `template' + if (get_node (num-4-offset)->token ()->type () == TOK_TEMPLATE) + name->PrefixSon (get_node (num-4-offset)); + CT_QualName *qn; + int root = (get_node (1)->NodeName () == Container::NodeId ()) ? 0 : 1; + Container *nns = (Container*)get_node (root+1); + if (root) { + qn = new CT_RootQualName (nns->Sons ()+2); + qn->AddSon (get_node (1)); + } else + qn = new CT_QualName (nns->Sons ()+1); + copy_list (qn, nns); + qn->AddSon (name); + return new CT_ConstructExpr (new CT_ClassSpec (get_node (0), qn), el); + } + // simple_type_spec ... + else { + CT_ExprList *el = (num == 4) ? (CT_ExprList*)get_node (2) : new CT_ExprList; + el->PrefixSon (get_node (1)); + el->AddSon (get_node (num - 1)); + el->AddProperties (CT_List::OPEN_CLOSE); + return new CT_ConstructExpr (get_node (0), el); + } +} + +CTree *CCBuilder::pseudo_dtor_name () { + // 2: ~ type_name + // 3: :: ~ type_name + // 3: nested_name_spec ~ type_name + // 4: :: nested_name_spec ~ type_name + // 4: type_name :: ~ type_name + // 5: :: type_name :: ~ type_name + // 5: nested_name_spec type_name :: ~ type_name + // 6: :: nested_name_spec type_name :: ~ type_name + // 6: nested_name_spec template_key template_id :: ~ type_name + // 7: :: nested_name_spec template_key template_id :: ~ type_name + int num = nodes (); + CTree *dtor = new CT_DestructorName (get_node (num-2), get_node (num-1)); + if (num == 2) + return dtor; + + CT_QualName *result; + int root = (get_node (0)->token ()->type () == TOK_COLON_COLON) ? 1 : 0; + if (get_node (root)->NodeName () == Container::NodeId ()) { + Container *nns = (Container*)get_node (root); + if (root == 1) { + result = new CT_RootQualName (nns->Sons () + (num > 4 ? 4 : 2)); + result->AddSon (get_node (0)); + } else + result = new CT_QualName (nns->Sons () + (num > 4 ? 3 : 1)); + copy_list (result, nns); + delete nns; + } else { + if (root == 1) { + result = new CT_RootQualName (num > 3 ? 4 : 2); + result->AddSon (get_node (0)); + } else + result = new CT_QualName (3); + } + if (num > (get_node (root)->NodeName () == Container::NodeId () ? 4 : 3)) { + CT_SimpleName *sn = (CT_SimpleName*)get_node (num-4); + // name prefixed by `template' + if ((num == 6 && ! root) || num == 7) + sn->PrefixSon (get_node (num-5)); + result->AddSon (sn); + result->AddSon (get_node (num-3)); + } + result->AddSon (dtor); + return result; +} + +CTree *CCBuilder::type_trait_expr () { + // 4: any_unary_type_trait_op ( type_id ) + // 6: any_binary_type_trait_op ( type_id , type_id ) + int num = nodes (); + if (num == 4) { + return new CT_TypeTraitExpr (get_node (0), + get_node (1), get_node (2), get_node (3)); + } + else if (num == 6) { + return new CT_TypeTraitExpr (get_node (0), get_node (1), + get_node (2), get_node (3), get_node (4), get_node (5)); + } + return 0; +} + +CTree *CCBuilder::new_expr () { + // 2: NEW new_type_id + // 3: NEW new_type_id new_init + // 3: NEW new_placement new_type_id + // 3: :: NEW new_type_id + // 4: :: NEW new_type_id new_init + // 4: :: NEW new_placement new_type_id + // 4: NEW new_placement new_type_id new_init + // 4: NEW ( type_id ) + // 5: NEW ( type_id ) new_init + // 5: NEW new_placement ( type_id ) + // 5: :: NEW new_placement new_type_id new_init + // 5: :: NEW ( type_id ) + // 6: :: NEW ( type_id ) new_init + // 6: NEW new_placement ( type_id ) new_init + // 6: :: NEW new_placement ( type_id ) + // 7: :: NEW new_placement ( type_id ) new_init + int root = (get_node ()->token ()->type () == TOK_COLON_COLON) ? 2 : 1; + CTree *opn = new CT_OperatorName (get_node (root-1)); + if (root == 2) { + CT_RootQualName *rqn = new CT_RootQualName (2); + rqn->AddSon (get_node (0)); + rqn->AddSon (opn); + opn = rqn; + } + int np = (get_node (root)->NodeName () == CT_ExprList::NodeId ()) ? 1 : 0; + int el = (get_node (root+np)->token ()->type () == TOK_OPEN_ROUND) ? 2 : 0; + int num = nodes (); + return new CT_NewExpr (opn, + np ? get_node (root) : 0, + el ? get_node (root+np) : 0, + el ? get_node (root+np+1) : get_node (root+np), + el ? get_node (root+np+2) : 0, + (num-root-np-el) == 2 ? get_node (num-1) : 0); +} + +CTree *CCBuilder::new_placement () { + // 3: ( expr_list ) + CT_ExprList *result = (CT_ExprList*)get_node (1); + result->PrefixSon (get_node (0)); + result->AddSon (get_node (2)); + result->AddProperties (CT_List::OPEN_CLOSE); + return result; +} + +CTree *CCBuilder::direct_new_declarator () { + // 3 : [ expr ] + // 4+: [ expr ] direct_new_declarator1... + int num = nodes ()-1; + CTree *result = get_node (num); // PrivateName, pushed by semantic + result = new CT_ArrayDeclarator (result, get_node (0), + new CT_ArrayDelimiter (0, 0, 0, get_node (1)), get_node (2)); + + for (int i = 3; i < num; i++) { + Container *d1 = (Container*)get_node (i); + result = new CT_ArrayDeclarator (result, d1->Son (0), + new CT_ArrayDelimiter (0, 0, 0, d1->Son (1)), d1->Son (2)); + delete d1; + } + return result; +} + +CTree *CCBuilder::direct_new_declarator1 () { + // 3: [ const_expr ] + return container (); +} + +CTree *CCBuilder::new_init () { + // 2: ( ) + // 3: ( expr_list ) + CT_ExprList *result = (nodes () == 3) ? + (CT_ExprList*)get_node (1) : new CT_ExprList; + result->PrefixSon (get_node (0)); + result->AddSon (get_node (nodes () - 1)); + result->AddProperties (CT_List::OPEN_CLOSE); + return result; +} + +CTree *CCBuilder::delete_expr () { + // 2: DELETE cast_expr + // 3: :: DELETE cast_expr + // 4: DELETE [ ] cast_expr + // 5: :: DELETE [ ] cast_expr + int num = nodes (), root = (num == 3 || num == 5) ? 1 : 0; + CTree *result; + if (num > 3) + result = new CT_OperatorName (0, get_node (root), get_node (root+1), + get_node (root+2)); + else + result = new CT_OperatorName (get_node (root)); + if (root == 1) { + CT_RootQualName *rqn = new CT_RootQualName; + rqn->AddSon (get_node ()); + rqn->AddSon (result); + result = rqn; + } + return new CT_DeleteExpr (result, get_node (num-1)); +} + +CTree *CCBuilder::pm_expr () { + return lr_bin_expr (); +} + +/*****************************************************************************/ +/* */ +/* A . 5 S t a t e m e n t s */ +/* */ +/*****************************************************************************/ + +CTree *CCBuilder::condition () { + // 1: expr + // 1: condition2 + // 2: type_spec_seq declarator + // 3: condition1 = ass_expr + if (nodes () == 1) + return get_node (); + else if (nodes () == 2) + return new CT_Condition (get_node (0), get_node (1)); + else if (nodes () == 3) { + CT_ExprList *el = new CT_ExprList; + el->AddSon (get_node (1)); + el->AddSon (get_node (2)); + el->AddProperties (CT_List::INTRO); + CTree *cond = get_node (); + ((CT_Condition*)cond)->Initializer (el); + return cond; + } + else + return (CTree*)0; +} + +CTree *CCBuilder::decl_stmt () { + // 1: block_decl + return new CT_DeclStmt (get_node ()); +} + +/*****************************************************************************/ +/* */ +/* A . 6 D e c l a r a t i o n s */ +/* */ +/*****************************************************************************/ + +CTree *CCBuilder::decl () { + // 1: block_decl + // 1: fct_def + // 1: explicit_specialization + // 1: template_decl + // 1: explicit_instantiation + // 1: linkage_spec + // 1: namespace_def + return get_node (); +} + +CTree *CCBuilder::simple_type_spec () { + // 1: prim_types + // 1: type_name + // 2: nested_name_spec type_name + // 2: :: type_name + // 3: :: nested_name_spec type_name + // 3: nested_name_spec template_key template_id + // 4: :: nested_name_spec template_key template_id + int num = nodes (); + if (num == 1) { + if (get_node ()->NodeName () == CT_Token::NodeId ()) + return prim_ds (); + else + return get_node (); + } + + CT_SimpleName *sn = (CT_SimpleName*)get_node (num-1); + // name prefixed by `template' + if (get_node (num-2)->token ()->type () == TOK_TEMPLATE) + sn->PrefixSon (get_node (num-2)); + + int root = (get_node ()->NodeName () == Container::NodeId ()) ? 0 : 1; + CT_QualName *result; + if (num == 2 && root) { + result = new CT_RootQualName (2); + result->AddSon (get_node (0)); + } else { + Container *nns = (Container*)get_node (root); + if (root) { + result = new CT_RootQualName (nns->Sons ()+2); + result->AddSon (get_node (0)); + } else + result = new CT_QualName (nns->Sons ()+1); + copy_list (result, nns); + delete nns; + } + result->AddSon (sn); + return result; +} + +CTree *CCBuilder::elaborated_type_spec () { + // 2: TYPENAME template_id + // 2: class_key identifier + // 2: ENUM identifier + // 3: class_key :: identifier + // 3: ENUM :: identifier + // 3: class_key nested_name_spec identifier + // 3: ENUM nested_name_spec identifier + // 3: TYPENAME nested_name_spec identifier + // 3: TYPENAME nested_name_spec template_id + // 4: class_key :: nested_name_spec identifier + // 4: ENUM :: nested_name_spec identifier + // 4: TYPENAME nested_name_spec template_key template_id + // 4: TYPENAME :: nested_name_spec identifier + // 4: TYPENAME :: nested_name_spec template_id + // 5: TYPENAME :: nested_name_spec template_key template_id + int num = nodes (); + CT_SimpleName *name = (CT_SimpleName*)get_node (num-1); + if (num > 2) { + // name prefixed by `template' + if (get_node (num-2)->token ()->type () == TOK_TEMPLATE) + name->PrefixSon (get_node (num-2)); + CT_QualName *qn; + int root = (get_node (1)->NodeName () == Container::NodeId ()) ? 0 : 1; + if (root && num == 3) { + qn = new CT_RootQualName (2); + qn->AddSon (get_node (1)); + } else { + Container *nns = (Container*)get_node (root+1); + if (root) { + qn = new CT_RootQualName (nns->Sons ()+2); + qn->AddSon (get_node (1)); + } else + qn = new CT_QualName (nns->Sons ()+1); + copy_list (qn, nns); + } + qn->AddSon (name); + name = qn; + } + int key = get_node ()->token ()->type (); + if (key == TOK_CLASS || key == TOK_STRUCT || key == TOK_TYPENAME) + return new CT_ClassSpec (get_node (0), name); + else if (key == TOK_UNION) + return new CT_UnionSpec (get_node (0), name); + else // TOK_ENUM + return new CT_EnumSpec (get_node (0), name); +} + +CTree *CCBuilder::linkage_spec () { + // 4+: (EXTERN str_literal)+ { } + // 5+: (EXTERN str_literal)+ { decl_seq } + // 3+: (EXTERN str_literal)+ decl + CT_DeclSpecSeq *dss = new CT_DeclSpecSeq (); + int i = 0, key; + do { + dss->AddSon (get_node (i++)); + dss->AddSon (get_node (i++)); + key = get_node (i)->token ()->type (); + } while (key == TOK_EXTERN); + // now the three cases from above ... + int n = nodes (); + if (i == n - 2) + return new CT_LinkageSpec (dss, get_node (n-2), new CT_DeclList (1), get_node (n-1)); + else if (i == n - 3) { + Container *decls = (Container*)get_node (n-2); + CT_DeclList *dl = new CT_DeclList (decls->Sons ()); + copy_list (dl, decls); + delete decls; + return new CT_LinkageSpec (dss, get_node (n-3), dl, get_node (n-1)); + } + else // i == n - 1 + return new CT_LinkageSpec (dss, 0, get_node (nodes () - 1), 0); +} + +/*****************************************************************************/ +/* */ +/* A . 6 . 1 N a m e s p a c e s */ +/* */ +/*****************************************************************************/ + +CTree *CCBuilder::namespace_def () { + // 1: named_ns_def + // 1: unamed_ns_def + return get_node (); +} + +CTree *CCBuilder::named_ns_def () { + // 1: original_ns_def + // 1: extension_ns_def + return get_node (); +} + +CTree *CCBuilder::orig_namespace_def () { + // 4: orig_ns_def1 { namespace_body } + CT_MembList *ml; + ml = (nodes () == 4) ? (CT_MembList*)get_node (2) : new CT_MembList (1); + ml->AddProperties (CT_List::OPEN_CLOSE); + ml->PrefixSon (get_node (1)); + ml->AddSon (get_node (nodes ()-1)); + CT_NamespaceDef *nsd = (CT_NamespaceDef*)get_node (0); + nsd->Members (ml); + return nsd; +} + +CTree *CCBuilder::orig_namespace_def1 () { + // 2: NAMESPACE identifier + // 3: INLINE NAMESPACE identifier + if (nodes() == 3) + return new CT_NamespaceDef (get_node (0), get_node (1), get_node (2)); + else + return new CT_NamespaceDef (0, get_node (0), get_node (1)); +} + +CTree *CCBuilder::namespace_body () { + // 0: + // 1: decl_seq + CT_MembList *ml; + if (nodes ()) { + Container *decls = (Container*)get_node (); + ml = new CT_MembList (decls->Sons ()); + copy_list (ml, decls); + delete decls; + } else + ml = new CT_MembList (1); + return ml; +} + +CTree *CCBuilder::ns_alias_def () { + // 5: NAMESPACE identifier = qual_ns_spec ; + return new CT_NamespaceAliasDef (get_node (0), get_node (1), get_node (2), + get_node (3), get_node (4)); +} + +CTree *CCBuilder::qual_ns_spec () { + // 1: namespace_name + // 2: nested_name_spec namespace_name + // 2: colon_colon namespace_name + // 3: colon_colon nested_name_spec namespace_name + int num = nodes (); + if (num == 1) + return get_node (); + + CT_QualName *result; + int root = 0; + if (get_node (0)->NodeName () != Container::NodeId ()) { + root = 1; + if (nodes () == 2) { + result = new CT_RootQualName (2); + result->AddSon (get_node (0)); + result->AddSon (get_node (1)); + return result; + } + } + + Container *nns = (Container*)get_node (root); + if (root == 1) { + result = new CT_RootQualName (nns->Sons ()+2); + result->AddSon (get_node (0)); + } else + result = new CT_QualName (nns->Sons ()+1); + copy_list (result, nns); + result->AddSon (get_node (1+root)); + delete nns; + return result; +} + +CTree *CCBuilder::using_decl () { + // 4: USING :: unqual_id ; + // 4: USING nested_name_spec unqual_id ; + // 5: USING :: nested_name_spec unqual_id ; + // 5: USING TYPENAME nested_name_spec unqual_id ; + // 6: USING TYPENAME :: nested_name_spec unqual_id ; + CT_QualName *qn; + int root = 0, num = nodes (); + if (get_node (1)->token ()->type () == TOK_TYPENAME) + root++; + if (get_node (root+1)->NodeName () != Container::NodeId ()) + root = 2; + if (root == 2 && num == 4) { + qn = new CT_RootQualName (2); + qn->AddSon (get_node (1)); + qn->AddSon (get_node (num-2)); + } else { + Container *nns = (Container*)get_node (num-3); + if (root == 2) { + qn = new CT_RootQualName (nns->Sons ()+2); + qn->AddSon (get_node (num-4)); + } else + qn = new CT_QualName (nns->Sons ()+1); + copy_list (qn, nns); + qn->AddSon (get_node (num-2)); + } + if (root && get_node (1)->token ()->type () == TOK_TYPENAME) + return new CT_UsingDecl (get_node (0), get_node (1), qn, get_node (num-1)); + return new CT_UsingDecl (get_node (0), qn, get_node (num-1)); +} + +CTree *CCBuilder::using_directive () { + // 4: USING NAMESPACE namespace_name ; + // 5: USING NAMESPACE :: namespace_name ; + // 5: USING NAMESPACE nested_name_spec namespace_name ; + // 6: USING NAMESPACE :: nested_name_spec namespace_name ; + CTree *n; + int root = 0, num = nodes (); + if (get_node (2)->NodeName () != Container::NodeId ()) + root = 1; + if (num == 4) { + n = get_node (2); + } else if (num == 5 && root) { + n = new CT_RootQualName (2); + ((CT_QualName*)n)->AddSon (get_node (2)); + ((CT_QualName*)n)->AddSon (get_node (3)); + } else { + Container *nns = (Container*)get_node (num-3); + if (root) { + n = new CT_RootQualName (nns->Sons ()+2); + ((CT_QualName*)n)->AddSon (get_node (2)); + } else + n = new CT_QualName (nns->Sons ()+1); + copy_list ((CT_QualName*)n, nns); + ((CT_QualName*)n)->AddSon (get_node (num-2)); + } + return new CT_UsingDirective (get_node (0), get_node (1), n, get_node (num-1)); +} + +/*****************************************************************************/ +/* */ +/* A . 7 D e c l a r a t o r s */ +/* */ +/*****************************************************************************/ + +CTree *CCBuilder::declarator () { + // 1 : direct_declarator + // 2+: ptr_operator.. direct_declarator + int num = nodes (); + CTree *result = get_node (num-1); + for (int i = num-1; i > 0; i--) { + // 1: & + // 1: * + // 2: * cv_qual_seq + // 2: nested_name_spec * + // 3: nested_name_spec * cv_qual_seq + // 3: :: nested_name_spec * + // 4: :: nested_name_spec * cv_qual_seq + Container *p = (Container*)get_node (i-1); // ptr-operator + int type = p->Son (0)->token ()->type (); + if (type == TOK_AND) + result = new CT_RefDeclarator (p->Son (0), result); + else if (type == TOK_MUL && p->Sons () == 1) + result = new CT_PtrDeclarator (p->Son (0), 0, result); + else if (type == TOK_MUL && p->Sons () == 2) + result = new CT_PtrDeclarator (p->Son (0), p->Son (1), result); + else { + int root = (type == TOK_COLON_COLON) ? 1 : 0; + Container *nns = (Container*)p->Son (root); + CT_QualName *qn = 0; + if (root) { + qn = new CT_RootQualName (nns->Sons ()); + qn->AddSon (p->Son (0)); + } else if (nns->Sons () > 2) + qn = new CT_QualName (nns->Sons ()-1); + + if (nns->Sons () == 2) + qn = (CT_QualName*)nns->Son (0); + else { + for (int i = 0; i < nns->Sons ()-1; i++) + qn->AddSon (nns->Son (i)); + } + + result = new CT_MembPtrDeclarator (qn, + nns->Son (nns->Sons ()-1), p->Son (root+1), + (p->Sons () == (root+3)) ? p->Son (root+2) : 0, result); + delete nns; + } + delete p; + } + return result; +} + +CTree *CCBuilder::declarator_id () { + // 1: id_expr => node + // 1: type_name => node + // 2: nest_name type_name => cont node + // 2: :: type_name => node node + // 3: :: nest_name type_name => node cont node + int num = nodes (); + if (num == 1) + return get_node (); + + CT_QualName *result; + int root = (get_node (0)->NodeName () == CT_Token::NodeId ()) ? 1 : 0; + if ((num-root) == 2) { + Container *nns = (Container*)get_node (root); + if (root) { + result = new CT_RootQualName (nns->Sons ()+2); + result->AddSon (get_node (0)); + } else + result = new CT_QualName (nns->Sons ()+1); + copy_list (result, nns); + delete nns; + } else { + result = new CT_RootQualName (2); + result->AddSon (get_node (0)); + } + result->AddSon (get_node (num-1)); + return result; +} + +CTree *CCBuilder::param_init () { + // 2: = ass_expr + CT_ExprList *el = new CT_ExprList; + el->AddSon (get_node (0)); + el->AddSon (get_node (1)); + el->AddProperties (CT_List::INTRO); + return el; +} + +/*****************************************************************************/ +/* */ +/* A . 8 C l a s s e s */ +/* */ +/*****************************************************************************/ + +CTree *CCBuilder::class_head1 () { + // 1: class_key private_name + // 2: class_key identifier + // 2: class_key template_id + // 3: class_key nested_name_spec identifier + // 3: class_key nested_name_spec template_id + // ... base_clause not yet parsed + CTree *result = get_node (1); + // nested (qualified) name + if (result->NodeName () == Container::NodeId ()) { + Container *nns = (Container*)result; + CT_QualName *qn = new CT_QualName (nns->Sons ()+1); + copy_list (qn, nns); + qn->AddSon (get_node (2)); + result = qn; + } + if (get_node (0)->token ()->type () == TOK_UNION) + result = new CT_UnionDef (get_node (0), result, 0); + else + result = new CT_ClassDef (get_node (0), result, 0); + return result; +} + +CTree *CCBuilder::class_head () { + // 1: class_head1 + // 2: class_head1 base_clause + if (nodes () == 2) + ((CT_ClassDef*)get_node ())->BaseClasses (get_node (1)); + return get_node (); +} + +CTree *CCBuilder::class_spec () { + // 3: class_head { } + // 4: class_head { member_spec } + int num = nodes (); + CT_MembList *ml = (num == 4) ? + (CT_MembList*)get_node (2) : new CT_MembList; + ml->PrefixSon (get_node (1)); + ml->AddSon (get_node (num-1)); + ml->AddProperties (CT_List::OPEN_CLOSE); + CT_ClassDef *result = (CT_ClassDef*)get_node (0); + result->Members (ml); + return result; +} + +CTree *CCBuilder::member_decl () { + // 1: member_decl1 + // 1: fct_def + // 1: access_decl + // 2: access_spec : + if (nodes () == 1) + return get_node (); + else + return new CT_AccessSpec (get_node (0), get_node (1)); +} + +CTree *CCBuilder::member_decl1 () { + // 1: ; + // 2: decl_spec_seq ; + // 2: member_declarator_list ; + // 3: decl_spec_seq member_declarator_list ; + int num = nodes (); + if (num == 1) + return new CT_ObjDecl (new CT_DeclSpecSeq, new CT_DeclaratorList, get_node (0)); + else if (num == 2) { + if (get_node (0)->NodeName () == CT_DeclSpecSeq::NodeId ()) + return new CT_ObjDecl (get_node (0), new CT_DeclaratorList, get_node (1)); + else + return new CT_ObjDecl (new CT_DeclSpecSeq, get_node (0), get_node (1)); + } else // if (num == 3) + return new CT_ObjDecl (get_node (0), get_node (1), get_node (2)); +} + +CTree *CCBuilder::access_decl () { + // 3: nested_name_spec unqual_id ; + // 4: :: nested_name_spec unqual_id ; + // 4: nested_name_spec template_key unqual_id ; + // 5: :: nested_name_spec template_key unqual_id ; + int num = nodes (); + int root = (get_node ()->NodeName () != Container::NodeId ()) ? 1 : 0; + Container *nns = (Container*)get_node (root); + CT_QualName *qn; + if (root) { + qn = new CT_RootQualName (nns->Sons ()+2); + qn->AddSon (get_node (0)); + } else + qn = new CT_QualName (nns->Sons ()+1); + copy_list (qn, nns); + CT_SimpleName *sn = (CT_SimpleName*)get_node (num-2); + // name prefixed by `template' + if (get_node (num-3)->token ()->type () == TOK_TEMPLATE) + sn->PrefixSon (get_node (num-3)); + qn->AddSon (sn); + delete nns; + return new CT_AccessDecl (qn, get_node (num-1)); +} + +CTree *CCBuilder::member_declarator () { + // 3: identifier : const_expr + // 3: private_name : const_expr + // 1: declarator + // 2: declarator pure_spec + // 2: declarator const_init + int num = nodes (); + bool bitfield = (num >= 2 && get_node (1)->token ()->type () == TOK_COLON); + if (bitfield) { + if (num == 3) + return new CT_BitFieldDeclarator (get_node (0), get_node (1), get_node (2)); + else if (num == 2) + return new CT_BitFieldDeclarator (get_node (0), get_node (1)); + } + else { + if (num == 1) + return new CT_InitDeclarator (get_node (0)); + else + return new CT_InitDeclarator (get_node (0), get_node (1)); + } + return 0; +} + +CTree *CCBuilder::pure_spec () { + CT_ExprList *el = new CT_ExprList; + el->AddSon (get_node (0)); + el->AddSon (new CT_Integer (get_node (1))); + el->AddProperties (CT_List::INTRO); + return el; +} + +CTree *CCBuilder::const_init () { + CT_ExprList *el = new CT_ExprList; + el->AddSon (get_node (0)); + el->AddSon (get_node (1)); + el->AddProperties (CT_List::INTRO); + return el; +} + +/*****************************************************************************/ +/* */ +/* A . 9 D e r i v e d c l a s s e s */ +/* */ +/*****************************************************************************/ + +CTree *CCBuilder::base_clause () { + // 2: : base_spec_list + CT_BaseSpecList *bsl = (CT_BaseSpecList*)get_node (1); + bsl->PrefixSon (get_node (0)); + return bsl; +} + +CTree *CCBuilder::base_spec_list () { + return list (new CT_BaseSpecList); +} + +CTree *CCBuilder::base_spec () { + // 1: class_name + // 2: :: class_name + // 2: VIRTUAL class_name + // 2: access_spec class_name + // 2: nested_name_spec class_name + // 3: nested_name_spec template_key class_name + // 3: :: nested_name_spec class_name + // 3: VIRTUAL :: class_name + // 3: access_spec :: class_name + // 3: VIRTUAL nested_name_spec class_name + // 3: access_spec nested_name_spec class_name + // 3: VIRTUAL access_spec class_name + // 3: access_spec VIRTUAL class_name + // 4: :: nested_name_spec template_key class_name + // 4: VIRTUAL nested_name_spec template_key class_name + // 4: access_spec nested_name_spec template_key class_name + // 4: VIRTUAL :: nested_name_spec class_name + // 4: access_spec :: nested_name_spec class_name + // 4: VIRTUAL access_spec nested_name_spec class_name + // 4: access_spec VIRTUAL nested_name_spec class_name + // 4: VIRTUAL access_spec :: class_name + // 4: access_spec VIRTUAL :: class_name + // 5: VIRTUAL :: nested_name_spec template_key class_name + // 5: access_spec :: nested_name_spec template_key class_name + // 5: VIRTUAL access_spec nested_name_spec template_key class_name + // 5: access_spec VIRTUAL nested_name_spec template_key class_name + // 5: VIRTUAL access_spec :: nested_name_spec class_name + // 5: access_spec VIRTUAL :: nested_name_spec class_name + // 6: VIRTUAL access_spec :: nested_name_spec template_key class_name + // 6: access_spec VIRTUAL :: nested_name_spec template_key class_name + int num = nodes (), i, offset = 0; + CTree *t, *v, *a = t = v = (CTree*)0; + CTree *n = get_node (num-1); + if (num > 1) { + if ((i = 0, get_node (i)->token ()->type () == TOK_VIRTUAL) || + (i = 1, get_node (i)->token ()->type () == TOK_VIRTUAL)) + v = get_node (i); + if ((i = 0, get_node (i)->token ()->type () == TOK_PUBLIC || + get_node (i)->token ()->type () == TOK_PRIVATE || + get_node (i)->token ()->type () == TOK_PROTECTED) || + (i = 1, get_node (i)->token ()->type () == TOK_PUBLIC || + get_node (i)->token ()->type () == TOK_PRIVATE || + get_node (i)->token ()->type () == TOK_PROTECTED)) + a = get_node (i); + if (get_node (num-2)->token ()->type () == TOK_TEMPLATE) { + // name prefixed by `template' + offset = 1; + ((CT_SimpleName*)n)->PrefixSon (get_node (num-2)); + } + + CT_QualName *qn; + if (get_node (num-2-offset)->NodeName () == Container::NodeId ()) { + Container *nns = (Container*)get_node (num-2-offset); + if (num > (2+offset) && get_node (num-3-offset)->token ()->type () == TOK_COLON_COLON) { + qn = new CT_RootQualName (nns->Sons ()+2); + qn->AddSon (get_node (num-3-offset)); + } else + qn = new CT_QualName (nns->Sons ()+1); + copy_list (qn, nns); + qn->AddSon (n); + delete nns; + n = qn; + } else if (get_node (num-2-offset)->token ()->type () == TOK_COLON_COLON) { + qn = new CT_RootQualName (2); + qn->AddSon (get_node (num-2-offset)); + qn->AddSon (n); + n = qn; + } + } + return new CT_BaseSpec (v, a, n); +} + +CTree *CCBuilder::access_spec () { + return get_node (); +} + +/*****************************************************************************/ +/* */ +/* A . 1 0 S p e c i a l m e m b e r f u n c t i o n s */ +/* */ +/*****************************************************************************/ + +CTree *CCBuilder::conv_fct_id () { + // 2: OPERATOR conv_type_id + return new CT_ConversionName (get_node (0), get_node (1)); +} + +CTree *CCBuilder::ctor_init () { + // 2: : mem_init_list + CT_MembInitList *mil = (CT_MembInitList*)get_node (1); + mil->PrefixSon (get_node (0)); + return mil; +} + +CTree *CCBuilder::mem_init_list () { + return list (new CT_MembInitList); +} + +CTree *CCBuilder::mem_init () { + // 3: mem_init_id ( ) + // 4: mem_init_id ( expr_list ) + int num = nodes (); + CT_ExprList *el = (num == 4) ? (CT_ExprList*)get_node (2) : new CT_ExprList; +// if (num != 4) +// Push (el); + el->PrefixSon (get_node (1)); + el->AddSon (get_node (num-1)); + el->AddProperties (CT_List::OPEN_CLOSE); + return new CT_MembInit (get_node (0), el); +} + +CTree *CCBuilder::mem_init_id () { + // 1: identifier + // 1: class_name + // 2: nested_name_spec class_name + // 2: :: class_name + // 3: :: nested_name_spec class_name + int num = nodes (); + if (num == 1) + return get_node (); + CT_QualName *result; + if (get_node (num-2)->NodeName () == Container::NodeId ()) { + Container *nns = (Container*)get_node (num-2); + if (num == 3) { + result = new CT_RootQualName (nns->Sons ()+2); + result->AddSon (get_node (0)); + } else + result = new CT_QualName (nns->Sons ()+1); + copy_list (result, nns); + delete nns; + } else { + result = new CT_RootQualName (2); + result->AddSon (get_node (0)); + } + result->AddSon (get_node (num-1)); + return result; +} + +/*****************************************************************************/ +/* */ +/* A . 1 1 O v e r l o a d i n g */ +/* */ +/*****************************************************************************/ + +CTree *CCBuilder::oper_fct_id () { + // 2: OPERATOR any_operator + // 2: OPERATOR NEW + // 2: OPERATOR DELETE + // 3: OPERATOR ( ) + // 3: OPERATOR [ ] + // 4: OPERATOR NEW [ ] + // 4: OPERATOR DELETE [ ] + int num = nodes (); + if (num == 2) + return new CT_OperatorName (get_node (0), get_node (1), 0, 0); + else if (num == 3) + return new CT_OperatorName (get_node (0), 0, get_node (1), get_node (2)); + else // if (num == 4) + return new CT_OperatorName (get_node (0), get_node (1), get_node (2), + get_node (3)); +} + +/*****************************************************************************/ +/* */ +/* A . 1 2 T e m p l a t e s */ +/* */ +/*****************************************************************************/ + +CTree *CCBuilder::template_decl () { + // 5: TEMPLATE < template_param_list > decl + // 6: EXPORT TEMPLATE < template_param_list > decl + int offset = (nodes () == 6) ? 1 : 0; + CT_TemplateParamList *pl = (CT_TemplateParamList*) get_node (2 + offset); + pl->AddSon (get_node (3 + offset)); + pl->PrefixSon (get_node (1 + offset)); + pl->PrefixSon (get_node (0 + offset)); + return new CT_TemplateDecl (offset ? get_node (0) : (CTree*)0, + pl, get_node (4 + offset)); +} + +CTree *CCBuilder::template_param_list () { + // 1 : template_param + // 3+: template_param , template_param .. + return list (new CT_TemplateParamList); +} + +CTree *CCBuilder::template_param () { + // 1: type_param + // 1: non_type_param + return get_node (); +} + +CTree *CCBuilder::type_param () { + // 2: CLASS identifier + // 2: TYPENAME identifier + // 4: CLASS identifier = type_id + // 4: TYPENAME identifier = type_id + // 6: TEMPLATE < template_param_list > CLASS identifier + // 8: TEMPLATE < template_param_list > CLASS identifier = id_expr + CT_TemplateParamList *pl = (CT_TemplateParamList*)0; + if (nodes () >= 6) { + pl = (CT_TemplateParamList*)get_node (2); + pl->AddSon (get_node (3)); + pl->PrefixSon (get_node (1)); + pl->PrefixSon (get_node (0)); + } + int num = nodes (); + if (num == 2 || num == 6) + return new CT_TypeParamDecl (pl, get_node (num-2), get_node (num-1)); + CT_ExprList *el = new CT_ExprList; + el->AddSon (get_node (num-2)); + el->AddSon (get_node (num-1)); + el->AddProperties (CT_List::INTRO); + return new CT_TypeParamDecl (pl, get_node (num-4), get_node (num-3), el); +} + +CTree *CCBuilder::non_type_param (CTree *result) { + // 2: decl_spec_seq private_name + // 2: decl_spec_seq abst_declarator + // 2: decl_spec_seq declarator + // 3: decl_spec_seq private_name param_init + // 3: decl_spec_seq abst_declarator param_init + // 3: decl_spec_seq declarator param_init + if (! result) + result = new CT_NonTypeParamDecl (get_node (0), get_node (1)); + else if (nodes () == 3) + ((CT_NonTypeParamDecl*)result)->Initializer (get_node (2)); + return result; +} + +CTree *CCBuilder::template_id () { + // 3: template_name < > + // 4: template_name < template_arg_list > + CT_TemplateArgList *tal; + if (nodes () == 3) + tal = new CT_TemplateArgList; + else + tal = (CT_TemplateArgList*)get_node (2); + tal->PrefixSon (get_node (1)); + tal->AddSon (get_node (nodes ()-1)); + return new CT_TemplateName (get_node (0), tal); +} + +CTree *CCBuilder::template_arg_list () { + // 1 : template_arg + // 3+: template_arg , template_arg .. + return list (new CT_TemplateArgList); +} + +CTree *CCBuilder::template_arg () { + // 1: template_type_arg + // 1: template_non_type_arg + // 1: template_template_arg + return get_node (); +} + +CTree *CCBuilder::template_type_arg () { + // 1: type_id + return get_node (); +} + +CTree *CCBuilder::template_non_type_arg () { + // 1: ass_expr + return get_node (); +} + +CTree *CCBuilder::template_template_arg () { + // 1: id_expr + return get_node (); +} + +CTree *CCBuilder::explicit_instantiation () { + // 2: TEMPLATE decl + // 3: EXTERN TEMPLATE decl => GCC EXTENSION!!! + CT_TemplateParamList *tpl = new CT_TemplateParamList; + tpl->AddSon (get_node (nodes ()-2)); + if (nodes () == 3) { + CT_DeclSpecSeq *dss = new CT_DeclSpecSeq (); + dss->AddSon (get_node (0)); + return new CT_LinkageSpec (dss, 0, + new CT_TemplateDecl (0, tpl, get_node (nodes ()-1)), 0); + } + return new CT_TemplateDecl (0, tpl, get_node (nodes ()-1)); +} + +CTree *CCBuilder::explicit_specialization () { + // 4: TEMPLATE < > decl + CT_TemplateParamList *tpl = new CT_TemplateParamList; + tpl->AddSon (get_node (0)); + tpl->AddSon (get_node (1)); + tpl->AddSon (get_node (2)); + return new CT_TemplateDecl (0, tpl, get_node (3)); +} + +/*****************************************************************************/ +/* */ +/* A . 1 3 E x c e p t i o n h a n d l i n g */ +/* */ +/*****************************************************************************/ + +CTree *CCBuilder::try_block () { + // 3: TRY cmpd_stmt handler_seq + return new CT_TryStmt (get_node (0), get_node (1), get_node (2)); +} + +CTree *CCBuilder::fct_try_block () { + // 3+: TRY fct_body handler_seq + // 4+: TRY ctor_init fct_body handler_seq + return container (); +} + +CTree *CCBuilder::handler_seq () { + // 1+: handler.. + return list (new CT_HandlerSeq); +} + +CTree *CCBuilder::handler () { + // 5: CATCH ( exception_decl ) cmpd_stmt + CT_ArgDeclList *adl = new CT_ArgDeclList (3); + adl->AddSon (get_node (1)); + adl->AddSon (get_node (2)); + adl->AddSon (get_node (3)); + return new CT_Handler (get_node (0), adl, get_node (4)); +} + +CTree *CCBuilder::exception_decl () { + // 1: ... + // 1: type_spec_seq + // 2: type_spec_seq abst_declarator + // 2: type_spec_seq declarator + if (nodes () == 2) + return new CT_ArgDecl (get_node (0), get_node (1)); + return new CT_ArgDecl (get_node (0)); +} + +CTree *CCBuilder::throw_expr () { + // 1: THROW + // 2: THROW ass_expr + if (nodes () == 1) + return new CT_ThrowExpr (get_node (0)); + return new CT_ThrowExpr (get_node (0), get_node (1)); +} + +CTree *CCBuilder::exception_spec () { + // 3: THROW ( ) + // 4: THROW ( ... ) + // 4: THROW ( type_id_list ) + CT_ArgDeclList *adl; + if (nodes () == 3 || get_node (2)->NodeName () != CT_ArgDeclList::NodeId ()) { + adl = new CT_ArgDeclList; + if (nodes () == 4) + adl->AddSon (get_node (2)); + } else + adl = (CT_ArgDeclList*)get_node (2); + adl->PrefixSon (get_node (1)); + adl->AddSon (get_node (nodes ()-1)); + return new CT_ExceptionSpec (get_node (0), adl); +} + +CTree *CCBuilder::type_id_list () { + // 1 : type_id + // 3+: type_id , type_id .. + return list (new CT_ArgDeclList (3)); +} + + +} // namespace Puma diff --git a/Puma/src/parser/ccparser/CCBuilder.h b/Puma/src/parser/ccparser/CCBuilder.h new file mode 100644 index 0000000..cfebede --- /dev/null +++ b/Puma/src/parser/ccparser/CCBuilder.h @@ -0,0 +1,143 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CCBuilder_h__ +#define __CCBuilder_h__ + +#include "Puma/CBuilder.h" + +namespace Puma { + + +class CCBuilder : public CBuilder { +public: + CCBuilder () {} + + // functions to create several kinds of syntax trees + + // A.1 Keywords + virtual CTree *namespace_name (); + + // A.4 Expression + virtual CTree *prim_expr (); + virtual CTree *id_expr (); + virtual CTree *unqual_id (); + virtual CTree *qual_id (); + virtual CTree *nested_name_spec (); + virtual CTree *nested_name_spec1 (); + virtual CTree *class_or_ns_name (); + virtual CTree *postfix_expr (CTree * = (CTree*)0); + virtual CTree *postfix_expr2 (); + virtual CTree *construct_expr (); + virtual CTree *pseudo_dtor_name (); + virtual CTree *type_trait_expr (); + virtual CTree *new_expr (); + virtual CTree *new_placement (); + virtual CTree *direct_new_declarator (); + virtual CTree *direct_new_declarator1 (); + virtual CTree *new_init (); + virtual CTree *delete_expr (); + virtual CTree *pm_expr (); + + // A.5 Statements + virtual CTree *condition (); + virtual CTree *decl_stmt (); + + // A.6 Declarations + virtual CTree *decl (); + virtual CTree *simple_type_spec (); + virtual CTree *elaborated_type_spec (); + virtual CTree *linkage_spec (); + + // A.6.1 Namespaces + virtual CTree *namespace_def (); + virtual CTree *named_ns_def (); + virtual CTree *orig_namespace_def (); + virtual CTree *orig_namespace_def1 (); + virtual CTree *namespace_body (); + virtual CTree *ns_alias_def (); + virtual CTree *qual_ns_spec (); + virtual CTree *using_decl (); + virtual CTree *using_directive (); + + // A.7 Declarators + virtual CTree *declarator (); + virtual CTree *declarator_id (); + virtual CTree *param_init (); + + // A.8 Classes + virtual CTree *class_head (); + virtual CTree *class_head1 (); + virtual CTree *class_spec (); + virtual CTree *member_decl (); + virtual CTree *member_decl1 (); + virtual CTree *access_decl (); + virtual CTree *member_declarator (); + virtual CTree *pure_spec (); + virtual CTree *const_init (); + + // A.9 Derived classes + virtual CTree *base_clause (); + virtual CTree *base_spec_list (); + virtual CTree *base_spec (); + virtual CTree *access_spec (); + + // A.10 Special member functions + virtual CTree *conv_fct_id (); + virtual CTree *ctor_init (); + virtual CTree *mem_init_list (); + virtual CTree *mem_init (); + virtual CTree *mem_init_id (); + + // A.11 Overloading + virtual CTree *oper_fct_id (); + + // A.12 Templates + virtual CTree *template_decl (); + virtual CTree *template_param_list (); + virtual CTree *template_param (); + virtual CTree *type_param (); + virtual CTree *non_type_param (CTree * = (CTree*)0); + virtual CTree *template_id (); + virtual CTree *template_arg_list (); + virtual CTree *template_arg (); + virtual CTree *template_type_arg (); + virtual CTree *template_non_type_arg (); + virtual CTree *template_template_arg (); + virtual CTree *explicit_instantiation (); + virtual CTree *explicit_specialization (); + + // A.13 Exception handling + virtual CTree *try_block (); + virtual CTree *fct_try_block (); + virtual CTree *handler_seq (); + virtual CTree *handler (); + virtual CTree *exception_decl (); + virtual CTree *throw_expr (); + virtual CTree *exception_spec (); + virtual CTree *type_id_list (); + +protected: + void cleanup(CTree* tree); + void Delete(); +}; + + +} // namespace Puma + +#endif /* __CCBuilder_h__ */ diff --git a/Puma/src/parser/ccparser/CCBuilderExtension.ah b/Puma/src/parser/ccparser/CCBuilderExtension.ah new file mode 100644 index 0000000..7800d26 --- /dev/null +++ b/Puma/src/parser/ccparser/CCBuilderExtension.ah @@ -0,0 +1,690 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CCBuilderExtension_ah__ +#define __CCBuilderExtension_ah__ + +#include "Puma/CCBuilder.h" + +namespace Puma { + + slice class CCClassNameBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().simple_name (); + } + }; + + slice class CCEnumNameBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().simple_name (); + } + }; + + slice class CCTemplateNameBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().simple_name (); + } + }; + + slice class CCClassTemplateNameBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().simple_name (); + } + }; + + slice class CCNamespaceNameBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().namespace_name (); + } + }; + + slice class CCOriginalNsNameBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().simple_name (); + } + }; + + slice class CCNamespaceAliasBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().simple_name (); + } + }; + + slice class CCLiteralBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().literal (); + } + }; + + slice class CCPrimExprBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().prim_expr (); + } + }; + + slice class CCIdExprBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().id_expr (); + } + }; + + slice class CCQualIdBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().qual_id (); + } + }; + + slice class CCUnqualIdBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().unqual_id (); + } + }; + + slice class CCColonColonBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().get_node (); + } + }; + + slice class CCNestedNameSpecBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().nested_name_spec (); + } + }; + + slice class CCNestedNameSpec1Builder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().nested_name_spec1 (); + } + }; + + slice class CCClassOrNsNameBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().class_or_ns_name (); + } + }; + + slice class CCPostfixExprBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + // calling this does not make real sense. CCSemantic advice needed! + return s.builder().postfix_expr (); + } + }; + + slice class CCPostfixExpr1Builder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().postfix_expr1 (); + } + }; + + slice class CCPostfixExpr2Builder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().postfix_expr2 (); + } + }; + + slice class CCConstructExprBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().construct_expr (); + } + }; + + slice class CCPseudoDtorNameBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().pseudo_dtor_name (); + } + }; + + slice class CCUnaryExprBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().unary_expr (); + } + }; + + slice class CCTypeTraitExprBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().type_trait_expr (); + } + }; + + slice class CCNewExprBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().new_expr (); + } + }; + + slice class CCNewPlacementBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().new_placement (); + } + }; + + slice class CCNewTypeIdBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().type_id (); + } + }; + + slice class CCNewDeclaratorBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().abst_declarator (); + } + }; + + slice class CCDirectNewDeclaratorBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().direct_new_declarator (); + } + }; + + slice class CCDirectNewDeclarator1Builder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().direct_new_declarator1 (); + } + }; + + slice class CCNewInitBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().new_init (); + } + }; + + slice class CCDeleteExprBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().delete_expr (); + } + }; + + slice class CCPmExprBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().pm_expr (); + } + }; + + slice class CCMulExprBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().mul_expr (); + } + }; + + slice class CCRelExprBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().rel_expr (); + } + }; + + slice class CCCondExprBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().cond_expr (); + } + }; + + slice class CCAssExprBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().ass_expr (); + } + }; + + slice class CCAssExpr1Builder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().ass_expr1 (); + } + }; + + slice class CCConstExprBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().const_expr (); + } + }; + + slice class CCStmtBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().stmt (); + } + }; + + slice class CCStmtSeqBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().stmt_seq (); + } + }; + + slice class CCSubStmtBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().sub_stmt (); + } + }; + + slice class CCConditionBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().condition (); + } + }; + + slice class CCCondition1Builder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().condition (); + } + }; + + slice class CCCondition2Builder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().condition (); + } + }; + + slice class CCDeclStmtBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().decl_stmt (); + } + }; + + slice class CCDeclBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().decl (); + } + }; + + slice class CCBlockDeclBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().block_decl (); + } + }; + + slice class CCSimpleDeclBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().simple_decl (); + } + }; + + slice class CCDeclSpecSeq1Builder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().decl_spec_seq1 (); + } + }; + + slice class CCMiscSpecBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().misc_spec (); + } + }; + + slice class CCStorageClassSpecBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().storage_class_spec (); + } + }; + + slice class CCFctSpecBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().fct_spec (); + } + }; + + slice class CCSimpleTypeSpecBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().simple_type_spec (); + } + }; + + slice class CCTypeNameBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().type_name (); + } + }; + + slice class CCElaboratedTypeSpecBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().elaborated_type_spec (); + } + }; + + slice class CCEnumeratorListBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().enumerator_list (); + } + }; + + slice class CCEnumeratorDefBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().enumerator_def (); + } + }; + + slice class CCLinkageSpecBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().linkage_spec (); + } + }; + + slice class CCNamespaceDefBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().namespace_def (); + } + }; + + slice class CCNamedNsDefBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().named_ns_def (); + } + }; + + slice class CCOriginalNsDefBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().orig_namespace_def (); + } + }; + + slice class CCOriginalNsDef1Builder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().orig_namespace_def1 (); + } + }; + + slice class CCExtensionNsDefBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().orig_namespace_def (); + } + }; + + slice class CCExtensionNsDef1Builder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().orig_namespace_def1 (); + } + }; + + slice class CCUnnamedNsDefBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().orig_namespace_def (); + } + }; + + slice class CCUnnamedNsDef1Builder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().orig_namespace_def1 (); + } + }; + + slice class CCNamespaceBodyBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().namespace_body (); + } + }; + + slice class CCNsAliasDefBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().ns_alias_def (); + } + }; + + slice class CCQualNsSpecBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().qual_ns_spec (); + } + }; + + slice class CCUsingDeclBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().using_decl (); + } + }; + + slice class CCUsingDirectiveBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().using_directive (); + } + }; + + slice class CCInitDeclaratorBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().init_declarator (); + } + }; + + slice class CCDirectDeclarator1Builder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().direct_declarator1 (); + } + }; + + slice class CCArrayDelimBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().array_delim (); + } + }; + + slice class CCPtrOperatorBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().ptr_operator (); + } + }; + + slice class CCDeclaratorIdBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().declarator_id (); + } + }; + + slice class CCDirectAbstDeclaratorBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().direct_abst_declarator (); + } + }; + + slice class CCParamDeclClauseBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().param_decl_clause (); + } + }; + + slice class CCClassHeadBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().class_head (); + } + }; + + slice class CCClassHead1Builder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().class_head1 (); + } + }; + + slice class CCConvFctIdBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().conv_fct_id (); + } + }; + + slice class CCConvTypeIdBuilder { + public: + static CTree *build(Puma::CCSyntax &s) { + return s.builder().type_id (); + } + }; +} + +aspect CCBuilderExtension { + + // create the corresponding syntax tree nodes for the rules + advice "Puma::CCSyntax::ClassName": slice Puma::CCClassNameBuilder; + advice "Puma::CCSyntax::EnumName": slice Puma::CCEnumNameBuilder; + advice "Puma::CCSyntax::TemplateName": slice Puma::CCTemplateNameBuilder; + advice "Puma::CCSyntax::ClassTemplateName": slice Puma::CCClassTemplateNameBuilder; + advice "Puma::CCSyntax::NamespaceName": slice Puma::CCNamespaceNameBuilder; + advice "Puma::CCSyntax::OriginalNsName": slice Puma::CCOriginalNsNameBuilder; + advice "Puma::CCSyntax::NamespaceAlias": slice Puma::CCNamespaceAliasBuilder; + advice "Puma::CCSyntax::Literal": slice Puma::CCLiteralBuilder; + advice "Puma::CCSyntax::PrimExpr": slice Puma::CCPrimExprBuilder; + advice "Puma::CCSyntax::IdExpr": slice Puma::CCIdExprBuilder; + advice "Puma::CCSyntax::QualId": slice Puma::CCQualIdBuilder; + advice "Puma::CCSyntax::UnqualId": slice Puma::CCUnqualIdBuilder; + advice "Puma::CCSyntax::ColonColon": slice Puma::CCColonColonBuilder; + advice "Puma::CCSyntax::NestedNameSpec": slice Puma::CCNestedNameSpecBuilder; + advice "Puma::CCSyntax::NestedNameSpec1": slice Puma::CCNestedNameSpec1Builder; + advice "Puma::CCSyntax::ClassOrNsName": slice Puma::CCClassOrNsNameBuilder; + advice "Puma::CCSyntax::PostfixExpr": slice Puma::CCPostfixExprBuilder; + advice "Puma::CCSyntax::PostfixExpr1": slice Puma::CCPostfixExpr1Builder; + advice "Puma::CCSyntax::PostfixExpr2": slice Puma::CCPostfixExpr2Builder; + advice "Puma::CCSyntax::ConstructExpr": slice Puma::CCConstructExprBuilder; + advice "Puma::CCSyntax::PseudoDtorName": slice Puma::CCPseudoDtorNameBuilder; + advice "Puma::CCSyntax::UnaryExpr": slice Puma::CCUnaryExprBuilder; + advice "Puma::CCSyntax::TypeTraitExpr": slice Puma::CCTypeTraitExprBuilder; + advice "Puma::CCSyntax::NewExpr": slice Puma::CCNewExprBuilder; + advice "Puma::CCSyntax::NewPlacement": slice Puma::CCNewPlacementBuilder; + advice "Puma::CCSyntax::NewTypeId": slice Puma::CCNewTypeIdBuilder; + advice "Puma::CCSyntax::NewDeclarator": slice Puma::CCNewDeclaratorBuilder; + advice "Puma::CCSyntax::DirectNewDeclarator": slice Puma::CCDirectNewDeclaratorBuilder; + advice "Puma::CCSyntax::DirectNewDeclarator1": slice Puma::CCDirectNewDeclarator1Builder; + advice "Puma::CCSyntax::NewInit": slice Puma::CCNewInitBuilder; + advice "Puma::CCSyntax::DeleteExpr": slice Puma::CCDeleteExprBuilder; + advice "Puma::CCSyntax::PmExpr": slice Puma::CCPmExprBuilder; + advice "Puma::CCSyntax::MulExpr": slice Puma::CCMulExprBuilder; + advice "Puma::CCSyntax::RelExpr": slice Puma::CCRelExprBuilder; + advice "Puma::CCSyntax::CondExpr": slice Puma::CCCondExprBuilder; + advice "Puma::CCSyntax::AssExpr": slice Puma::CCAssExprBuilder; + advice "Puma::CCSyntax::AssExpr1": slice Puma::CCAssExpr1Builder; + advice "Puma::CCSyntax::ConstExpr": slice Puma::CCConstExprBuilder; + advice "Puma::CCSyntax::Stmt": slice Puma::CCStmtBuilder; + advice "Puma::CCSyntax::StmtSeq": slice Puma::CCStmtSeqBuilder; + advice "Puma::CCSyntax::SubStmt": slice Puma::CCSubStmtBuilder; + advice "Puma::CCSyntax::Condition": slice Puma::CCConditionBuilder; + advice "Puma::CCSyntax::Condition1": slice Puma::CCCondition1Builder; + advice "Puma::CCSyntax::Condition2": slice Puma::CCCondition2Builder; + advice "Puma::CCSyntax::DeclStmt": slice Puma::CCDeclStmtBuilder; + advice "Puma::CCSyntax::Decl": slice Puma::CCDeclBuilder; + advice "Puma::CCSyntax::BlockDecl": slice Puma::CCBlockDeclBuilder; + advice "Puma::CCSyntax::SimpleDecl": slice Puma::CCSimpleDeclBuilder; + advice "Puma::CCSyntax::DeclSpecSeq1": slice Puma::CCDeclSpecSeq1Builder; + advice "Puma::CCSyntax::MiscSpec": slice Puma::CCMiscSpecBuilder; + advice "Puma::CCSyntax::StorageClassSpec": slice Puma::CCStorageClassSpecBuilder; + advice "Puma::CCSyntax::FctSpec": slice Puma::CCFctSpecBuilder; + advice "Puma::CCSyntax::SimpleTypeSpec": slice Puma::CCSimpleTypeSpecBuilder; + advice "Puma::CCSyntax::TypeName": slice Puma::CCTypeNameBuilder; + advice "Puma::CCSyntax::ElaboratedTypeSpec": slice Puma::CCElaboratedTypeSpecBuilder; + advice "Puma::CCSyntax::EnumeratorList": slice Puma::CCEnumeratorListBuilder; + advice "Puma::CCSyntax::EnumeratorDef": slice Puma::CCEnumeratorDefBuilder; + advice "Puma::CCSyntax::LinkageSpec": slice Puma::CCLinkageSpecBuilder; + advice "Puma::CCSyntax::NamespaceDef": slice Puma::CCNamespaceDefBuilder; + advice "Puma::CCSyntax::NamedNsDef": slice Puma::CCNamedNsDefBuilder; + advice "Puma::CCSyntax::OriginalNsDef": slice Puma::CCOriginalNsDefBuilder; + advice "Puma::CCSyntax::OriginalNsDef1": slice Puma::CCOriginalNsDef1Builder; + advice "Puma::CCSyntax::ExtensionNsDef": slice Puma::CCExtensionNsDefBuilder; + advice "Puma::CCSyntax::ExtensionNsDef1": slice Puma::CCExtensionNsDef1Builder; + advice "Puma::CCSyntax::UnnamedNsDef": slice Puma::CCUnnamedNsDefBuilder; + advice "Puma::CCSyntax::UnnamedNsDef1": slice Puma::CCUnnamedNsDef1Builder; + advice "Puma::CCSyntax::NamespaceBody": slice Puma::CCNamespaceBodyBuilder; + advice "Puma::CCSyntax::NsAliasDef": slice Puma::CCNsAliasDefBuilder; + advice "Puma::CCSyntax::QualNsSpec": slice Puma::CCQualNsSpecBuilder; + advice "Puma::CCSyntax::UsingDecl": slice Puma::CCUsingDeclBuilder; + advice "Puma::CCSyntax::UsingDirective": slice Puma::CCUsingDirectiveBuilder; + advice "Puma::CCSyntax::InitDeclarator": slice Puma::CCInitDeclaratorBuilder; + advice "Puma::CCSyntax::DirectDeclarator1": slice Puma::CCDirectDeclarator1Builder; + advice "Puma::CCSyntax::ArrayDelim": slice Puma::CCArrayDelimBuilder; + advice "Puma::CCSyntax::PtrOperator": slice Puma::CCPtrOperatorBuilder; + advice "Puma::CCSyntax::DeclaratorId": slice Puma::CCDeclaratorIdBuilder; + advice "Puma::CCSyntax::DirectAbstDeclarator": slice Puma::CCDirectAbstDeclaratorBuilder; + advice "Puma::CCSyntax::ParamDeclClause": slice Puma::CCParamDeclClauseBuilder; + advice "Puma::CCSyntax::ClassHead": slice Puma::CCClassHeadBuilder; + advice "Puma::CCSyntax::ClassHead1": slice Puma::CCClassHead1Builder; + advice "Puma::CCSyntax::ConvFctId": slice Puma::CCConvFctIdBuilder; + advice "Puma::CCSyntax::ConvTypeId": slice Puma::CCConvTypeIdBuilder; + +}; + +#endif /* __CCBuilderExtension_ah__ */ diff --git a/Puma/src/parser/ccparser/CCConvSeq.cc b/Puma/src/parser/ccparser/CCConvSeq.cc new file mode 100644 index 0000000..4334589 --- /dev/null +++ b/Puma/src/parser/ccparser/CCConvSeq.cc @@ -0,0 +1,38 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CCConvSeq.h" + +namespace Puma { + + +void CCConvSeq::Apply () { + CCConversion *conv, *last; + + last = 0; + for (unsigned i = 0; i < Conversions (); i++) { + conv = Conversion (i); + if (last) + conv->Update (last->Expr ()); + conv->Apply (); + last = conv; + } +} + + +} // namespace Puma diff --git a/Puma/src/parser/ccparser/CCConvSeq.h b/Puma/src/parser/ccparser/CCConvSeq.h new file mode 100644 index 0000000..505c816 --- /dev/null +++ b/Puma/src/parser/ccparser/CCConvSeq.h @@ -0,0 +1,96 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CCConvSeq__ +#define __CCConvSeq__ + +#include "Puma/CCConversion.h" +#include "Puma/Array.h" + +namespace Puma { + + +class CCConvSeq : public CCConversion { + Array _Conversions; + bool _isReferenceBinding; + +protected: + CCConvSeq (ConvId); + +public: + virtual ~CCConvSeq (); + + void Apply (); + + void addConversion (CCConversion *); + + CCConversion *Conversion (unsigned); + unsigned Conversions () const; + + bool isReferenceBinding () const; + void isReferenceBinding (bool); +}; + +inline CCConvSeq::CCConvSeq (ConvId id) : + CCConversion (id), + _Conversions (3, 1), + _isReferenceBinding (false) + {} +inline CCConvSeq::~CCConvSeq () + { for (long i = 0; i < _Conversions.length (); i++) + if (_Conversions.fetch (i)) + delete _Conversions.fetch (i); + } + +inline void CCConvSeq::addConversion (CCConversion *c) + { _Conversions.append (c); } + +inline CCConversion *CCConvSeq::Conversion (unsigned c) + { return _Conversions.lookup (c); } +inline unsigned CCConvSeq::Conversions () const + { return (unsigned)_Conversions.length (); } + +inline bool CCConvSeq::isReferenceBinding () const + { return _isReferenceBinding; } +inline void CCConvSeq::isReferenceBinding (bool v) + { _isReferenceBinding = v; } + +// the actual conversion sequences + +class CCStandardConvSeq : public CCConvSeq { +public: + CCStandardConvSeq () : + CCConvSeq (STANDARD_SEQ) {} +}; + +class CCUserDefinedConvSeq : public CCConvSeq { +public: + CCUserDefinedConvSeq () : + CCConvSeq (USER_DEFINED_SEQ) {} +}; + +class CCEllipsisConvSeq : public CCConvSeq { +public: + CCEllipsisConvSeq () : + CCConvSeq (ELLIPSIS_SEQ) {} +}; + + +} // namespace Puma + +#endif /* __CCConvSeq__ */ diff --git a/Puma/src/parser/ccparser/CCConversion.cc b/Puma/src/parser/ccparser/CCConversion.cc new file mode 100644 index 0000000..3a3d910 --- /dev/null +++ b/Puma/src/parser/ccparser/CCConversion.cc @@ -0,0 +1,129 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CCConversion.h" +#include "Puma/CFunctionInfo.h" +#include "Puma/CTypeInfo.h" +#include "Puma/CConstant.h" +#include "Puma/CRecord.h" +#include "Puma/CTree.h" + +namespace Puma { + + +CCConversion::CCConversion (ConvId id, CTypeInfo *p, CTypeInfo *a, CTree *e, CTree *b) { + _Id = id; + _ToType = p->Duplicate (); + _FromType = a->Duplicate (); + _Expr = 0; + _Base = b; + + if (b) + for (unsigned i = b->Sons (); i > 0; i--) + if (b->Son (i-1) == e) { + _Expr = e; + _Base = b; + break; + } +} + +CCConversion::~CCConversion () { + if (_ToType) + CTypeInfo::Destroy (_ToType); + if (_FromType) + CTypeInfo::Destroy (_FromType); +} + +void CCConversion::Update (CTree *e) { + if (_Base && _Expr != e) + for (unsigned i = _Base->Sons (); i > 0; i--) + if (_Base->Son (i-1) == e) { + _Expr = e; + if (e->Type ()) { + CTypeInfo::Destroy (_FromType); + _FromType = _Expr->Type ()->Duplicate (); + } + break; + } +} + +CFunctionInfo *CCConversion::ConvFunction () const { + return isUserDefinedConv () ? ((CCUserDefinedConv*)this)->ConvFunction () : 0; +} + + +// apply conversion + + +// standard implementation +void CCConversion::Apply () { + CT_ImplicitCast *cast; + CExprValue *value; + + // apply conversion only if types differ + if (_Expr && _Base && _FromType && _ToType && *_FromType != *_ToType) { + cast = new CT_ImplicitCast (_Expr); + cast->setType (_ToType->Duplicate ()); + _Base->ReplaceSon (_Expr, cast); + + // cast constant value if any + value = _Expr->Value (); + if (value) { + if (value->Constant ()) { + value = value->Constant ()->cast_to (_ToType); + cast->setValue (value); + } else + cast->setValueRef (value); + } + + _Expr = cast; + } +} + +void CCUserDefinedConv::Apply () { + CT_ImplicitCall *call; + CTypeInfo *type; + + if (! _ConvFunction) + CCConversion::Apply (); + else if (_Expr && _Base && _ToType) { + if (_ConvFunction->isConversion ()) + type = _ConvFunction->ConversionType (); + else if (_ConvFunction->isConstructor () && _ConvFunction->Record ()) + type = _ConvFunction->Record ()->TypeInfo (); + else if (_ConvFunction->ReturnType () && + ! _ConvFunction->ReturnType ()->is_undefined ()) + type = _ConvFunction->ReturnType (); + else + type = _ToType; + + if (type) { + call = new CT_ImplicitCall (_Expr); + call->Object (_ConvFunction); + if (type == _ToType) + call->setType (type->Duplicate ()); + else + call->setTypeRef (type); + _Base->ReplaceSon (_Expr, call); + _Expr = call; + } + } +} + + +} // namespace Puma diff --git a/Puma/src/parser/ccparser/CCConversion.h b/Puma/src/parser/ccparser/CCConversion.h new file mode 100644 index 0000000..7bf1450 --- /dev/null +++ b/Puma/src/parser/ccparser/CCConversion.h @@ -0,0 +1,262 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CCConversion__ +#define __CCConversion__ + +namespace Puma { + + +class CFunctionInfo; +class CTypeInfo; +class CTree; + +class CCConversion { +public: + enum ConvId { + IDENTITY, + LVALUE_TO_RVALUE, + ARRAY_TO_POINTER, + FUNCTION_TO_POINTER, + BOOLEAN, + INTEGRAL, + INTEGRAL_PROMOTION, + FLOATING, + FLOATING_PROMOTION, + FLOATING_INTEGRAL, + POINTER, + POINTER_TO_MEMBER, + DERIVED_TO_BASE, + QUALIFICATION, + USER_DEFINED, + + STANDARD_SEQ, + USER_DEFINED_SEQ, + ELLIPSIS_SEQ + }; + +protected: + ConvId _Id; + CTypeInfo *_ToType; + CTypeInfo *_FromType; + CTree *_Expr; + CTree *_Base; + +protected: + CCConversion (ConvId); + CCConversion (ConvId, CTypeInfo *, CTypeInfo *, CTree * = 0, CTree * = 0); + +public: + virtual ~CCConversion (); + + ConvId Id () const; + CTypeInfo *ToType () const; + CTypeInfo *FromType () const; + CTree *Expr () const; + CTree *Base () const; + CFunctionInfo *ConvFunction () const; + + virtual void Apply (); + void Update (CTree *); + + bool isIdentityConv () const; + bool isLvalueToRvalueConv () const; + bool isArrayToPointerConv () const; + bool isFunctionToPointerConv () const; + bool isBooleanConv () const; + bool isIntegralConv () const; + bool isIntegralPromotion () const; + bool isFloatingPointConv () const; + bool isFloatingPointPromotion () const; + bool isFloatingIntegralConv () const; + bool isPointerConv () const; + bool isPointerToMemberConv () const; + bool isDerivedToBaseConv () const; + bool isQualificationConv () const; + bool isUserDefinedConv () const; + + bool isStandardConvSeq () const; + bool isUserDefinedConvSeq () const; + bool isEllipsisConvSeq () const; +}; + +inline CCConversion::CCConversion (ConvId id) : + _Id (id), + _ToType ((CTypeInfo*)0), + _FromType ((CTypeInfo*)0), + _Expr ((CTree*)0), + _Base ((CTree*)0) + {} + +inline CCConversion::ConvId CCConversion::Id () const + { return _Id; } + +inline CTypeInfo *CCConversion::ToType () const + { return _ToType; } +inline CTypeInfo *CCConversion::FromType () const + { return _FromType; } +inline CTree *CCConversion::Expr () const + { return _Expr; } +inline CTree *CCConversion::Base () const + { return _Base; } + +inline bool CCConversion::isIdentityConv () const + { return _Id == IDENTITY; } +inline bool CCConversion::isLvalueToRvalueConv () const + { return _Id == LVALUE_TO_RVALUE; } +inline bool CCConversion::isArrayToPointerConv () const + { return _Id == ARRAY_TO_POINTER; } +inline bool CCConversion::isFunctionToPointerConv () const + { return _Id == FUNCTION_TO_POINTER; } +inline bool CCConversion::isBooleanConv () const + { return _Id == BOOLEAN; } +inline bool CCConversion::isIntegralConv () const + { return _Id == INTEGRAL; } +inline bool CCConversion::isIntegralPromotion () const + { return _Id == INTEGRAL_PROMOTION; } +inline bool CCConversion::isFloatingPointConv () const + { return _Id == FLOATING; } +inline bool CCConversion::isFloatingPointPromotion () const + { return _Id == FLOATING_PROMOTION; } +inline bool CCConversion::isFloatingIntegralConv () const + { return _Id == FLOATING_INTEGRAL; } +inline bool CCConversion::isPointerConv () const + { return _Id == POINTER; } +inline bool CCConversion::isPointerToMemberConv () const + { return _Id == POINTER_TO_MEMBER; } +inline bool CCConversion::isDerivedToBaseConv () const + { return _Id == DERIVED_TO_BASE; } +inline bool CCConversion::isQualificationConv () const + { return _Id == QUALIFICATION; } +inline bool CCConversion::isUserDefinedConv () const + { return _Id == USER_DEFINED; } + +inline bool CCConversion::isStandardConvSeq () const + { return _Id == STANDARD_SEQ; } +inline bool CCConversion::isUserDefinedConvSeq () const + { return _Id == USER_DEFINED_SEQ; } +inline bool CCConversion::isEllipsisConvSeq () const + { return _Id == ELLIPSIS_SEQ; } + +// the conversions + +class CCIdentityConv : public CCConversion { +public: + CCIdentityConv (CTypeInfo *p, CTypeInfo *a, CTree *e = 0, CTree *b = 0) : + CCConversion (IDENTITY, p, a, e, b) {} + + void Apply () { /* nothing to be applied */ } +}; + +class CCLvalueToRvalueConv : public CCConversion { +public: + CCLvalueToRvalueConv (CTypeInfo *p, CTypeInfo *a, CTree *e = 0, CTree *b = 0) : + CCConversion (LVALUE_TO_RVALUE, p, a, e, b) {} +}; + +class CCArrayToPointerConv : public CCConversion { +public: + CCArrayToPointerConv (CTypeInfo *p, CTypeInfo *a, CTree *e = 0, CTree *b = 0) : + CCConversion (ARRAY_TO_POINTER, p, a, e, b) {} +}; + +class CCFunctionToPointerConv : public CCConversion { +public: + CCFunctionToPointerConv (CTypeInfo *p, CTypeInfo *a, CTree *e = 0, CTree *b = 0) : + CCConversion (FUNCTION_TO_POINTER, p, a, e, b) {} +}; + +class CCBooleanConv : public CCConversion { +public: + CCBooleanConv (CTypeInfo *p, CTypeInfo *a, CTree *e = 0, CTree *b = 0) : + CCConversion (BOOLEAN, p, a, e, b) {} +}; + +class CCIntegralConv : public CCConversion { +public: + CCIntegralConv (CTypeInfo *p, CTypeInfo *a, CTree *e = 0, CTree *b = 0) : + CCConversion (INTEGRAL, p, a, e, b) {} +}; + +class CCIntegralPromotion : public CCConversion { +public: + CCIntegralPromotion (CTypeInfo *p, CTypeInfo *a, CTree *e = 0, CTree *b = 0) : + CCConversion (INTEGRAL_PROMOTION, p, a, e, b) {} +}; + +class CCFloatingPointConv : public CCConversion { +public: + CCFloatingPointConv (CTypeInfo *p, CTypeInfo *a, CTree *e = 0, CTree *b = 0) : + CCConversion (FLOATING, p, a, e, b) {} +}; + +class CCFloatingPointPromotion : public CCConversion { +public: + CCFloatingPointPromotion (CTypeInfo *p, CTypeInfo *a, CTree *e = 0, CTree *b = 0) : + CCConversion (FLOATING_PROMOTION, p, a, e, b) {} +}; + +class CCFloatingIntegralConv : public CCConversion { +public: + CCFloatingIntegralConv (CTypeInfo *p, CTypeInfo *a, CTree *e = 0, CTree *b = 0) : + CCConversion (FLOATING_INTEGRAL, p, a, e, b) {} +}; + +class CCPointerConv : public CCConversion { +public: + CCPointerConv (CTypeInfo *p, CTypeInfo *a, CTree *e = 0, CTree *b = 0) : + CCConversion (POINTER, p, a, e, b) {} +}; + +class CCPointerToMemberConv : public CCConversion { +public: + CCPointerToMemberConv (CTypeInfo *p, CTypeInfo *a, CTree *e = 0, CTree *b = 0) : + CCConversion (POINTER_TO_MEMBER, p, a, e, b) {} +}; + +class CCDerivedToBaseConv : public CCConversion { +public: + CCDerivedToBaseConv (CTypeInfo *p, CTypeInfo *a, CTree *e = 0, CTree *b = 0) : + CCConversion (DERIVED_TO_BASE, p, a, e, b) {} +}; + +class CCQualificationConv : public CCConversion { +public: + CCQualificationConv (CTypeInfo *p, CTypeInfo *a, CTree *e = 0, CTree *b = 0) : + CCConversion (QUALIFICATION, p, a, e, b) {} +}; + +class CCUserDefinedConv : public CCConversion { + CFunctionInfo *_ConvFunction; + +public: + CCUserDefinedConv (CTypeInfo *p, CTypeInfo *a, CFunctionInfo *cf, CTree *e = 0, CTree *b = 0) : + CCConversion (USER_DEFINED, p, a, e, b), + _ConvFunction (cf) {} + + CFunctionInfo *ConvFunction () const; + void Apply (); +}; + +inline CFunctionInfo *CCUserDefinedConv::ConvFunction () const + { return _ConvFunction; } + + +} // namespace Puma + +#endif /* __CCConversion__ */ diff --git a/Puma/src/parser/ccparser/CCConversions.cc b/Puma/src/parser/ccparser/CCConversions.cc new file mode 100644 index 0000000..a960112 --- /dev/null +++ b/Puma/src/parser/ccparser/CCConversions.cc @@ -0,0 +1,954 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CCConversions.h" +#include "Puma/CCOverloading.h" +#include "Puma/CFunctionInfo.h" +#include "Puma/CClassInfo.h" +#include "Puma/CTypeInfo.h" +#include "Puma/CCConvSeq.h" +#include "Puma/CCSemExpr.h" +#include "Puma/CConstant.h" +#include "Puma/CTree.h" + +namespace Puma { + + +//////////////////////////////////////////////////////////// +// arithmetic promotions/conversions /////////////////////// +//////////////////////////////////////////////////////////// + + +// �4.5 integral promotion +CTypeInfo *CCConversions::integralPromotion (CTypeInfo *type) { + CTypeInfo *t = type->UnqualType (); + + if (t->isInteger ()) { + if (t->is_char () || t->is_signed_char () || t->is_unsigned_char () || + t->is_short () || t->is_unsigned_short () || t->is_wchar_t () || + t->is_bool ()) + return &CTYPE_INT; + else if (t->isEnum ()) + return t->VirtualType ()->TypeEnum ()->UnderlyingType (); + else if (t->isBitField () && t->BaseType ()->isInteger () && + (*t->BaseType ()->UnqualType () < CTYPE_INT)) + return &CTYPE_INT; + return type; + } + + return 0; +} + + +// �4.5, �4.6 integral/floating point promotion +CTypeInfo *CCConversions::arithmeticPromotion (CTypeInfo *type) { + CTypeInfo *t = type->UnqualType (); + + // �4.6 floating point promotion + if (t->isReal ()) { + if (t->is_float ()) + return &CTYPE_DOUBLE; + return type; + } + + // �4.5 integral promotion + return integralPromotion (type); +} + + +// �5.9 usual arithmetic conversions +CTypeInfo *CCConversions::usualArithmeticConv (CTypeInfo *type1, CTypeInfo *type2) { + CTypeInfo *t1 = type1->UnqualType (); + CTypeInfo *t2 = type2->UnqualType (); + + if (! t1->isArithmetic () || ! t2->isArithmetic ()) + return 0; + if (*t1 == *t2) + return t1; + + if (t1->is_long_double () && ! t2->is_long_double ()) + t2 = &CTYPE_LONG_DOUBLE; + else if (t2->is_long_double () && ! t1->is_long_double ()) + t1 = &CTYPE_LONG_DOUBLE; + else if (t1->is_double () && ! t2->is_double ()) + t2 = &CTYPE_DOUBLE; + else if (t2->is_double () && ! t1->is_double ()) + t1 = &CTYPE_DOUBLE; + else if (t1->is_float () && ! t2->is_float ()) + t2 = &CTYPE_FLOAT; + else if (t2->is_float () && ! t1->is_float ()) + t1 = &CTYPE_FLOAT; + else { // integral promotion of both operands + t1 = integralPromotion (t1); + t2 = integralPromotion (t2); + } + + if ((t1->is_long () && t2->is_unsigned_int ()) || + (t2->is_long () && t1->is_unsigned_int ())) { + t1 = &CTYPE_UNSIGNED_LONG; + t2 = &CTYPE_UNSIGNED_LONG; + } else if (t1->is_long () && ! t2->is_long ()) + t2 = &CTYPE_LONG; + else if (t2->is_long () && ! t1->is_long ()) + t1 = &CTYPE_LONG; + else if (t1->is_unsigned_int () && ! t2->is_unsigned_int ()) + t2 = &CTYPE_UNSIGNED_INT; + else if (t2->is_unsigned_int () && ! t1->is_unsigned_int ()) + t1 = &CTYPE_UNSIGNED_INT; + + return t1; +} + + +//////////////////////////////////////////////////////////// +// �13.3.3.1 implicit conversion sequences ///////////////// +//////////////////////////////////////////////////////////// + + +// �8.5.14 initialization +CCConvSeq *CCConversions::implicitConversions (CTypeInfo *ptype, + CTypeInfo *atype, CTree *arg_expr, CTree *base, bool user_def) { + if (! atype || ! ptype) + return 0; + + // argument passing is a copy-initialization + if (atype->isAddress ()) + atype = atype->BaseType (); + if (ptype->isAddress ()) + return referenceBinding (ptype, atype, arg_expr, base, user_def); + if (user_def && (ptype->isRecord () || atype->isRecord ())) + return userDefinedConversions (ptype, atype, arg_expr, base); + return standardConversions (ptype, atype, arg_expr, base); +} + + +// �13.3.3.1.1 (and �4) standard conversions +CCConvSeq *CCConversions::standardConversions (CTypeInfo *ptype, + CTypeInfo *atype, CTree *arg_expr, CTree *base) { + CTypeInfo *param = ptype->UnqualType (); + CCConvSeq *seq = new CCStandardConvSeq; + bool conv = false, is_lvalue, null_ptr_conv = false, del = false; + + // �4.7 a bit field is converted according to its type + atype = atype->isBitField () ? atype->BaseType () : atype; + CTypeInfo *arg = atype; + arg = arg->UnqualType (); + + is_lvalue = arg_expr ? CCSemExpr::isLvalue (arg_expr) : arg->isAddress (); + + // �4.1 lvalue-to-rvalue conversion + if (is_lvalue && ! arg->isFunction () && ! arg->isArray ()) { + seq->addConversion (new CCLvalueToRvalueConv (param, arg, arg_expr, base)); + // �4.2 array-to-pointer conversion + } else if (arg->isArray ()) { + if (arg_expr && (arg_expr->NodeName () == CT_String::NodeId () || + arg_expr->NodeName () == CT_WideString::NodeId ())) { + // string and wide-string constants shall only be converted + // when an appropriated target type exists + if (param->isPointer () && + (param->BaseType ()->UnqualType ()->is_void () || + (arg_expr->NodeName () == CT_String::NodeId () && + param->BaseType ()->UnqualType ()->is_char ()) || + (arg_expr->NodeName () == CT_WideString::NodeId () && + param->BaseType ()->UnqualType ()->is_wchar_t ()))) { + // convert to "pointer to char" resp. to "pointer to wchar_t" + seq->addConversion (new CCArrayToPointerConv (param, arg, arg_expr, base)); + seq->addConversion (new CCQualificationConv (param, arg, arg_expr, base)); + arg = arg->BaseType ()->UnqualType (); + arg = new CTypePointer (arg->Duplicate ()); del = true; + } + } else { + seq->addConversion (new CCArrayToPointerConv (param, arg, arg_expr, base)); + arg = arg->BaseType (); + arg = new CTypePointer (arg->Duplicate ()); del = true; + } + // �4.3 function-to-pointer conversion + } else if (is_lvalue && arg->isFunction ()) { + seq->addConversion (new CCFunctionToPointerConv (param, arg, arg_expr, base)); + arg = new CTypePointer (arg->Duplicate ()); del = true; + } + + // same types, ignoring top level qualification + if (arg->equalsUnqualified (*param)) { + seq->addConversion (new CCIdentityConv (param, arg, arg_expr, base)); conv = true; + // base and derived class objects considered equal + } else if (param->isClass () && arg->isClass () && baseClass (param, arg)) { + seq->addConversion (new CCQualificationConv (param, arg, arg_expr, base)); conv = true; + } + + if (conv) { + if (del) CTypeInfo::Destroy (arg); + return seq; + } + + // �4.12 boolean conversion + if (param->is_bool () && arg->isScalar ()) { + seq->addConversion (new CCBooleanConv (param, arg, arg_expr, base)); conv = true; + // �4.5 integral promotions + } else if (arg->isInteger () && param->isInteger ()) { + // promote only if argument type is less precise than parameter type + if (*param == CTYPE_INT && arg->rank () <= CTYPE_WCHAR_T.rank ()) { + seq->addConversion (new CCIntegralPromotion (param, arg, arg_expr, base)); conv = true; + if (del) CTypeInfo::Destroy (arg); + arg = &CTYPE_INT; del = false; + // promote enumeration type + } else if (arg->isEnum () && *param == *arg->VirtualType ()->TypeEnum ()->UnderlyingType ()) { + seq->addConversion (new CCIntegralPromotion (param, arg, arg_expr, base)); conv = true; + if (del) CTypeInfo::Destroy (arg); + arg = param; del = false; + // �4.7 integral conversion + } else if (! param->isEnum ()) { + seq->addConversion (new CCIntegralConv (param, arg, arg_expr, base)); conv = true; + } + // �4.6 floating point promotion + } else if (arg->isReal () && param->isReal ()) { + if (arg->is_float ()) { + seq->addConversion (new CCFloatingPointPromotion (param, arg, arg_expr, base)); conv = true; + if (del) CTypeInfo::Destroy (arg); + arg = &CTYPE_DOUBLE; del = false; + // �4.8 floating point conversion + } else { + seq->addConversion (new CCFloatingPointConv (param, arg, arg_expr, base)); conv = true; + } + // �4.9 floating-integral conversion + } else if ((arg->isReal () && param->isInteger ()) || + (arg->isInteger () && param->isReal ())) { + if (! param->isEnum ()) { + seq->addConversion (new CCFloatingIntegralConv (param, arg, arg_expr, base)); conv = true; + } + // �4.10 pointer conversions + } else if (param->isPointer () && (arg->isPointer () || arg->isInteger ())) { + CClassInfo *ci1, *ci2; + bool null_ptr = (! is_lvalue && arg_expr && arg_expr->Value () && + arg_expr->Value ()->Constant () && + arg_expr->Value ()->Constant ()->isNull ()); + if (! param->isMemberPointer () && (null_ptr || + (arg->isPointer () && ! arg->isMemberPointer ()))) { + if (null_ptr && (! arg->isPointer () || similarTypes (param, arg))) { + seq->addConversion (new CCPointerConv (param, arg, arg_expr, base)); conv = null_ptr_conv = true; + } else if (param->BaseType ()->UnqualType ()->is_void ()) { + seq->addConversion (new CCPointerConv (param, arg, arg_expr, base)); conv = true; + if (del) CTypeInfo::Destroy (arg); + arg = &CTYPE_VOID; + if (! null_ptr && param->BaseType ()->isQualified ()) { + arg = new CTypeQualified (arg, param->BaseType ()->isConst (), + param->BaseType ()->isVolatile (), + param->BaseType ()->isRestrict ()); + } + arg = new CTypePointer (arg); del = true; + } else if (param->BaseType ()->UnqualType ()->TypeClass () && + arg->BaseType ()->UnqualType ()->TypeClass ()) { + ci1 = param->BaseType ()->UnqualType ()->TypeClass ()->ClassInfo (); + ci2 = arg->BaseType ()->UnqualType ()->TypeClass ()->ClassInfo (); + if (baseClass (ci1, ci2)) { + seq->addConversion (new CCPointerConv (param, arg, arg_expr, base)); conv = true; + } + } + // �4.11 pointer to member conversion + } else if (param->isMemberPointer () && (null_ptr || arg->isMemberPointer ())) { + if (null_ptr) { + seq->addConversion (new CCPointerToMemberConv (param, arg, arg_expr, base)); conv = true; + } else if (param->TypeMemberPointer ()->Record () && + arg->TypeMemberPointer ()->Record ()) { + ci1 = param->TypeMemberPointer ()->Record ()->ClassInfo (); + ci2 = arg->TypeMemberPointer ()->Record ()->ClassInfo (); + if (baseClass (ci2, ci1) && *param->BaseType () == *arg->BaseType ()) { + seq->addConversion (new CCPointerToMemberConv (param, arg, arg_expr, base)); conv = true; + } + } + } + } + + // �4.4 qualification conversion + if (! null_ptr_conv && similarTypes (param, arg)) { + seq->addConversion (new CCQualificationConv (param, arg, arg_expr, base)); conv = true; + } + + if (! conv) { + delete seq; + seq = (CCStandardConvSeq*)0; + } + if (del) CTypeInfo::Destroy (arg); + return seq; +} + + +// �13.3.3.1.2 (and �8.5.14) user-defined conversions +CCConvSeq *CCConversions::userDefinedConversions (CTypeInfo *ptype, + CTypeInfo *atype, CTree *arg_expr, CTree *base) { + CCConvSeq *seq2, *seq = 0; + CTypeInfo *arg = atype->UnqualType (); + CTypeInfo *param = ptype->UnqualType (); + CTypeInfo *ctype; + CRecord *c1, *c2; + + c1 = arg->isRecord () ? + arg->VirtualType ()->TypeRecord ()->Record () : (CRecord*)0; + c2 = param->UnqualType ()->TypeRecord () ? + param->UnqualType ()->TypeRecord ()->Record () : (CRecord*)0; + if (c1) + c1 = c1->DefObject ()->Record (); + if (c2) + c2 = c2->DefObject ()->Record (); + + if (c2) { + // �13.3.3.1.6 initialization of class type T with T + if (c1 && *c1 == *c2) { + seq = new CCStandardConvSeq; + seq->addConversion (new CCIdentityConv (param, arg, arg_expr, base)); + // �13.3.1.3 initialization of class type T class derived from T + } else { + CCOverloading ovl (err); + if (c1 && baseClass (c2->ClassInfo (), c1->ClassInfo ())) { + // candidates are converting constructors of c2 + ovl.collectConstructors (c2); + // select the best constructor + ovl.resolve (base, arg_expr); + if (isValidConversion (arg_expr, ptype, atype, ovl)) { + seq = new CCUserDefinedConvSeq; + // 1. initial standard conversion sequence + seq->addConversion (new CCDerivedToBaseConv (param, arg, arg_expr, base)); + // 2. user-defined conversion + seq->addConversion (new CCUserDefinedConv (param, arg, ovl.Function (), arg_expr, base)); + // 3. second standard conversion sequence + seq2 = new CCStandardConvSeq; + seq2->addConversion (new CCIdentityConv (param, arg, arg_expr, base)); + seq->addConversion (seq2); + } + // �13.3.1.4 initialization of class type with a (non-)class type + } else { + if (c1) { + // candidates are conversion functions of c1 and its base + // classes that are visible in c1 and yield a type whose + // cv-unqualified version is the same type as c2 or is a + // derived class thereof (including functions returning + // "reference to c2" => treated as "c2") + ovl.collectConvFunctions (c1); + ovl.ObjectType (arg); + for (unsigned i = ovl.Candidates (); i > 0; i--) { + ctype = ovl.Candidate (i-1)->Function ()->ConversionType (); + if (! (*param->UnqualType () == *ctype->VirtualType () || + (ctype->isClass () && baseClass (param, ctype)))) + ovl.removeCandidate (i-1); + } + } + // candidates are converting constructors of c2 + ovl.collectConstructors (c2); + // select the best conversion function (no user-defined conversions) + ovl.resolve (base, arg_expr, false); + if (isValidConversion (arg_expr, ptype, atype, ovl)) { + seq = new CCUserDefinedConvSeq; + // 1. initial standard conversion sequence (need not to + // be correct, not relevant to the algorithm at all) + seq->addConversion (new CCIdentityConv (param, arg, arg_expr, base)); + // 2. user-defined conversion + seq->addConversion (new CCUserDefinedConv (param, arg, ovl.Function (), arg_expr, base)); + // 3. second standard conversion sequence + seq2 = new CCStandardConvSeq; + if (! ovl.Function ()->isConstructor () && + baseClass (param, ovl.Function ()->ConversionType ())) + seq2->addConversion (new CCDerivedToBaseConv (param, + ovl.Function ()->ConversionType (), arg_expr, base)); + else + seq2->addConversion (new CCIdentityConv (param, + ovl.Function ()->ConversionType (), arg_expr, base)); + seq->addConversion (seq2); + } + } + } + // �13.3.1.5 initialization of non-class type with a class type + } else if (c1) { + // candidates are conversion functions of c1 and its base + // classes that are visible in c1 and yield a type whose + // cv-unqualified version is the same type as c2 or can be + // standard converted to c2 (including functions returning + // "reference to c2" => treated as "c2") + CCOverloading ovl (err, true); + ovl.ObjectType (arg); + ovl.collectConvFunctions (c1); + for (unsigned i = ovl.Candidates (); i > 0; i--) { + ctype = ovl.Candidate (i-1)->Function ()->ConversionType (); + seq2 = standardConversions (param, ctype->VirtualType (), 0, base); + if (! seq2) + ovl.removeCandidate (i-1); + else + ovl.Candidate (i-1)->SecondConvSeq (seq2); + } + // select the best conversion function (no user-defined conversions) + ovl.resolve (base, arg_expr, false); + if (isValidConversion (arg_expr, ptype, atype, ovl)) { + seq = new CCUserDefinedConvSeq; + // 1. initial standard conversion sequence (need not to + // be correct, not relevant to the algorithm at all) + seq->addConversion (new CCIdentityConv (param, arg, arg_expr, base)); + // 2. user-defined conversion + seq->addConversion (new CCUserDefinedConv (param, arg, ovl.Function (), arg_expr, base)); + // 3. second standard conversion sequence + seq2 = standardConversions (param, ovl.Function ()->ConversionType ()-> + VirtualType (), 0, base); + seq->addConversion (seq2); + } + } + + return seq; +} + + +// �13.3.3.1.3 ellipsis conversions +CCConvSeq *CCConversions::ellipsisConversions () { + CCConvSeq *seq = new CCEllipsisConvSeq; + return seq; +} + + +// �13.3.3.1.4 (and �8.5.3) reference binding +CCConvSeq *CCConversions::referenceBinding (CTypeInfo *ptype, + CTypeInfo *atype, CTree *arg_expr, CTree *base, bool user_def) { + CTypeInfo *param = ptype->UnqualType (); + CTypeInfo *arg = atype; + CCConvSeq *seq = 0, *seq2; + bool conv = false; + CTypeInfo *ctype; + CRecord *c; + + if (param->isAddress ()) { + param = param->BaseType (); + + // �8.5.3.5 direct reference binding to argument expression lvalue + if (CCSemExpr::isLvalue (arg_expr) && ! arg->isBitField () && + referenceCompatible (param, arg)) { + seq = new CCStandardConvSeq; + // �13.3.3.1.4.1 + if ((param->isClass () && arg->isClass () && baseClass (param, arg))) + seq->addConversion (new CCDerivedToBaseConv (param, arg, arg_expr, base)); + else if (arg->isConst () != param->isConst () || arg->isVolatile () != param->isVolatile ()) + seq->addConversion (new CCQualificationConv (param, arg, arg_expr, base)); + else + seq->addConversion (new CCIdentityConv (param, arg, arg_expr, base)); + conv = true; + } else if (arg->UnqualType ()->TypeRecord ()) { + CCOverloading ovl (err); + c = arg->UnqualType ()->TypeRecord ()->Record (); + // candidates are conversion functions of c and its + // base classes that are visible in c and yield a type + // "reference to T" where underlying parameter type is + // reference-compatible with T + ovl.ObjectType (arg); + ovl.collectConvFunctions (c); + for (unsigned i = ovl.Candidates (); i > 0; i--) { + ctype = ovl.Candidate (i-1)->Function ()->ConversionType (); + if (! ctype->isAddress () || + ! referenceCompatible (param, ctype->UnqualType ()->BaseType ())) + ovl.removeCandidate (i-1); + } + // select the best conversion function + ovl.resolve (base, arg_expr); + if (isValidConversion (arg_expr, ptype, atype, ovl)) { + seq = new CCUserDefinedConvSeq; + // 1. initial standard conversion sequence (need not to + // be correct, not relevant to the algorithm at all) + seq->addConversion (new CCIdentityConv (param, arg, arg_expr, base)); + // 2. user-defined conversion + seq->addConversion (new CCUserDefinedConv (param, arg, ovl.Function (), arg_expr, base)); + // 3. second standard conversion sequence + seq2 = new CCStandardConvSeq; + ctype = ovl.Function ()->ConversionType (); + if (param->isClass () && ctype->isClass () && baseClass (param, ctype)) + seq2->addConversion (new CCDerivedToBaseConv (param, ctype, arg_expr, base)); + else + seq2->addConversion (new CCIdentityConv (param, ctype, arg_expr, base)); + seq2->isReferenceBinding (true); + seq->addConversion (seq2); + conv = true; + } + } + + // �8.5.3.5 parameter type is reference to non-volatile const type + if (! conv && param->isQualified () && param->isConst () && + ! param->isVolatile ()) { + if (CCSemExpr::isRvalue (arg_expr) && arg->UnqualType ()->TypeRecord () && + referenceCompatible (param, arg)) { + seq = new CCStandardConvSeq; + // �13.3.3.1.4.2 not really clear which kind of conversion + // this is; is it right to distinguish like above? + if ((param->isClass () && arg->isClass () && baseClass (param, arg))) + seq->addConversion (new CCDerivedToBaseConv (param, arg, arg_expr, base)); + else if (arg->isConst () != param->isConst () || arg->isVolatile () != param->isVolatile ()) + seq->addConversion (new CCQualificationConv (param, arg, arg_expr, base)); + else + seq->addConversion (new CCIdentityConv (param, arg, arg_expr, base)); + // �13.3.3.1.4.2 reference not bound directly to argument expression + } else if (! (referenceRelated (param, arg) && + ! equalOrMoreQualified (param, arg))) { + // 1. create temporary of underlying parameter type + // 2. non-reference copy-initialization of temporary + // 3. temporary is bound to reference + seq = implicitConversions (param, arg, arg_expr, base, user_def); + } + } + } + if (seq) + seq->isReferenceBinding (true); + return seq; +} + + +// �8.5.3.4 reference-related types +bool CCConversions::referenceRelated (CTypeInfo *t1, CTypeInfo *t2) { + // compare unqualified types (top-level qualifiers removed) + t1 = t1->VirtualType (); + t2 = t2->VirtualType (); + if (t1->equalsUnqualified (*t2)) + return true; + return (t1->isClass () && t2->isClass () && baseClass (t1, t2)); +} + + +// �8.5.3.4 reference-compatible types +bool CCConversions::referenceCompatible (CTypeInfo *t1, CTypeInfo *t2) { + if (! referenceRelated (t1, t2)) + return false; + return (equalOrMoreQualified (t1, t2)); +} + + +bool CCConversions::equalOrMoreQualified (CTypeInfo *t1, CTypeInfo *t2) { + unsigned t1_qualification, t2_qualification; + CTypeQualified *tq; + + while (t1->TypeArray () && t2->TypeArray ()) { + t1 = t1->BaseType (); + t2 = t2->BaseType (); + } + + if (! t2->isQualified ()) + return true; + else if (! t1->isQualified ()) + return false; + + tq = t1->TypeQualified (); + t1_qualification = (tq->isConst ()?2:0) + (tq->isVolatile ()?1:0); + tq = t2->TypeQualified (); + t2_qualification = (tq->isConst ()?2:0) + (tq->isVolatile ()?1:0); + if (t1_qualification >= t2_qualification) + return true; + return false; +} + + +bool CCConversions::baseClass (CTypeInfo *t1, CTypeInfo *t2) { + t1 = t1->VirtualType ()->TypeClass (); + t2 = t2->VirtualType ()->TypeClass (); + if (t1 && t2) + return baseClass (t1->TypeClass ()->ClassInfo (), + t2->TypeClass ()->ClassInfo ()); + return false; +} + + +bool CCConversions::baseClass (CClassInfo *c1, CClassInfo *c2) { + CClassInfo *binfo; + if (! (c1 && c2)) + return false; + + c2 = c2->DefObject ()->ClassInfo (); + for (unsigned i = 0; i < c2->BaseClasses (); i++) { + binfo = c2->BaseClass (i)->Class (); + if (*c1 == *binfo || baseClass (c1, binfo)) + return true; + } + return false; +} + + +// �4.4.4 qualification conversion; similar pointer types +bool CCConversions::similarTypes (CTypeInfo *t1, CTypeInfo *t2) { + bool all_const = true; + CTypeInfo *p1, *p2; + CClassInfo *ci1, *ci2; + + if ((t1->isMemberPointer () && t2->isMemberPointer ()) || + (t1->isPointer () && t2->isPointer ())) { + p1 = t2->VirtualType ()->TypePointer (); + p2 = t1->VirtualType ()->TypePointer (); + while (true) { + if ((p1->isMemberPointer () && ! p2->isMemberPointer ()) || + (p2->isMemberPointer () && ! p1->isMemberPointer ())) + break; + if (p1->isMemberPointer () && + p1->TypeMemberPointer ()->Record () && + p2->TypeMemberPointer ()->Record () && + ! (*p1->TypeMemberPointer ()->Record () == + *p2->TypeMemberPointer ()->Record ())) + break; + p1 = p1->BaseType (); + p2 = p2->BaseType (); + if ((p1->UnqualType ()->isPointer () && ! p2->UnqualType ()->isPointer ()) || + (p2->UnqualType ()->isPointer () && ! p1->UnqualType ()->isPointer ())) + break; + + if (p1->isQualified () && ! p2->isQualified ()) + break; + if (p1->isQualified ()) { // => p2->isQualified () + if ((p1->isVolatile () && ! p2->isVolatile ()) || + (p1->isConst () && ! p2->isConst ())) + break; + if (((p1->isVolatile ()?1:0)+(p1->isConst ()?2:0)) != + ((p2->isVolatile ()?1:0)+(p2->isConst ()?2:0)) && + ! all_const) + break; + } else if (p2->isQualified () && ! all_const) + break; + if (! p2->isQualified () || ! p2->isConst ()) + all_const = false; + + if (! p1->UnqualType ()->isPointer ()) { + if (p1->equalsUnqualified (*p2)) + return true; // types are similar + if (p1->UnqualType ()->TypeClass () && p2->UnqualType ()->TypeClass ()) { + ci1 = p1->UnqualType ()->TypeClass ()->ClassInfo (); + ci2 = p2->UnqualType ()->TypeClass ()->ClassInfo (); + if (baseClass (ci2, ci1)) + return true; // types are similar + } + break; + } + + if (p1->isQualified ()) + p1 = p1->BaseType (); + if (p2->isQualified ()) + p2 = p2->BaseType (); + } + } + return false; +} + + +bool CCConversions::isValidConversion (CTree *arg_expr, CTypeInfo *to, + CTypeInfo *from, CCOverloading &ovl) const { + if (ovl.isAmbiguous ()) + return false; + // no candidates + else if (! ovl.Function ()) + return false; + return true; +} + + +//////////////////////////////////////////////////////////// +// �13.3.3.2 ranking implicit conversion sequences ///////// +//////////////////////////////////////////////////////////// + + +// �13.3.3.2 ranking implicit conversion sequences +// return 1 if seq1 is better than seq2 +// return 0 if seq1 and seq2 are indistinguishable +// return -1 if seq1 is worse than seq2 +int CCConversions::compareConvSeq (CCConvSeq *seq1, CCConvSeq *seq2) { + CCConversion *c1, *c2; + unsigned rank1, rank2; + bool v1, v2; + + // �13.3.3.2.2 compare basic forms of conversion sequences + if (seq1->isStandardConvSeq () || seq2->isStandardConvSeq ()) { + if (seq1->isStandardConvSeq () && ! seq2->isStandardConvSeq ()) + return 1; + if (seq2->isStandardConvSeq () && ! seq1->isStandardConvSeq ()) + return -1; + } else if (seq1->isUserDefinedConvSeq () || seq2->isUserDefinedConvSeq ()) { + if (seq1->isUserDefinedConvSeq () && ! seq2->isUserDefinedConvSeq ()) + return 1; + if (seq2->isUserDefinedConvSeq () && ! seq1->isUserDefinedConvSeq ()) + return -1; + // ellipsis conversion sequences are indistinguishable + } else // if (seq1->isEllipsisConvSeq () && seq2->isEllipsisConvSeq ()) + return 0; + + // �13.3.3.2.3 ranking conversion sequences of the same form + if (seq1->isStandardConvSeq ()) { // => seq2->isStandardConvSeq () + // a sequence is better than another if it is + // a proper subsequence of that sequence + if (properSubsequence (seq1, seq2)) + return 1; + if (properSubsequence (seq2, seq1)) + return -1; + + // compare conversion sequence ranks + rank1 = convSequenceRank (seq1); + rank2 = convSequenceRank (seq2); + if (rank1 > rank2) + return 1; + if (rank2 > rank1) + return -1; + + // compare conversion sequences with the same rank + rank1 = compareSameRankConvSeq (seq1, seq2); + if (rank1 != 0) + return rank1; + + // compare qualification signature + c1 = seq1->Conversion (seq1->Conversions ()-1); + c2 = seq2->Conversion (seq2->Conversions ()-1); + if (c1->isQualificationConv () || c2->isQualificationConv ()) { + v1 = similarTypes (c2->ToType (), c1->ToType ()); // c1 similar to c2? + v2 = similarTypes (c1->ToType (), c2->ToType ()); // c2 similar to c1? + if (v1 && ! v2) + return 1; + if (v2 && ! v1) + return -1; + if (c1->isQualificationConv () && ! c2->isQualificationConv ()) + return -1; + if (c2->isQualificationConv () && ! c1->isQualificationConv ()) + return 1; + } + + // compare reference bindings + if (seq1->isReferenceBinding () && seq2->isReferenceBinding ()) { + c1 = seq1->Conversion (0); + c2 = seq2->Conversion (0); + if (*c1->ToType ()->UnqualType () == + *c2->ToType ()->UnqualType ()) { + v1 = equalOrMoreQualified (c1->ToType (), c2->ToType ()); + v2 = equalOrMoreQualified (c2->ToType (), c1->ToType ()); + if (! v1 && v2) + return 1; + if (! v2 && v1) + return -1; + } + } + } else if (seq1->isUserDefinedConvSeq ()) { // => seq2->isUserDefinedConvSeq () + // same user-defined conversion function/constructor used + if ((*seq1->Conversion (1)->ConvFunction () == *seq2->Conversion (1)->ConvFunction ()) || + (seq1->Conversion (1)->ConvFunction ()->isConstructor () && + seq1->Conversion (1)->ConvFunction ()->isConstructor ())) + // compare second standard conversion sequences + return compareConvSeq ((CCConvSeq*)seq1->Conversion (2), (CCConvSeq*)seq2->Conversion (2)); + } + + return 0; +} + + +// �13.3.3.1.1.3 determine rank of a standard conversion sequence +// return 3 if exact match rank +// return 2 if promotion rank +// return 1 if conversion rank +unsigned CCConversions::convSequenceRank (CCConvSeq *seq) { + bool promo = false, conv = false; + CCConversion *c; + + for (unsigned i = 0; i < seq->Conversions (); i++) { + c = seq->Conversion (i); + + if (c->isIntegralPromotion () || c->isFloatingPointPromotion ()) + promo = true; + else if (c->isFloatingPointConv () || c->isIntegralConv () || + c->isFloatingIntegralConv () || c->isPointerConv () || + c->isPointerToMemberConv () || c->isBooleanConv () || + c->isDerivedToBaseConv ()) + conv = true; + } + + return conv ? 1 : promo ? 2 : 3; +} + + +// �13.3.3.2.4 compare standard conversion sequences with the same rank +// return 1 if seq1 is better than seq2 +// return 0 if seq1 and seq2 are indistinguishable +// return -1 if seq1 is worse than seq2 +int CCConversions::compareSameRankConvSeq (CCConvSeq *seq1, CCConvSeq *seq2) { + CCConversion *c1 = 0, *c2 = 0; + CClassInfo *f1 = 0, *f2 = 0, *t1 = 0, *t2 = 0; + CTypeInfo *param1, *param2, *arg1, *arg2; + + for (unsigned i = 0; i < seq1->Conversions (); i++) { + c1 = seq1->Conversion (i); + if (! c1->isLvalueToRvalueConv () && + ! c1->isArrayToPointerConv () && + ! c1->isFunctionToPointerConv ()) + break; + } + for (unsigned i = 0; i < seq2->Conversions (); i++) { + c2 = seq2->Conversion (i); + if (! c2->isLvalueToRvalueConv () && + ! c2->isArrayToPointerConv () && + ! c2->isFunctionToPointerConv ()) + break; + } + + arg1 = c1->FromType (); + arg2 = c2->FromType (); + + // any conversion is better than conversion from pointer, or + // pointer to member, to bool + if ((c2->isBooleanConv () && arg2->isPointer ()) && + (! c1->isBooleanConv () || ! arg1->isPointer ())) + return 1; + if ((c1->isBooleanConv () && arg1->isPointer ()) && + (! c2->isBooleanConv () || ! arg2->isPointer ())) + return -1; + + param1 = c1->ToType ()->UnqualType (); + param2 = c2->ToType ()->UnqualType (); + + f1 = extractClass (arg1, seq1->isReferenceBinding ()); + f2 = extractClass (arg2, seq2->isReferenceBinding ()); + t1 = extractClass (param1, seq1->isReferenceBinding ()); + t2 = extractClass (param2, seq2->isReferenceBinding ()); + + // B is derived from A and C is derived from B => C->B->A + + if (c1->isPointerConv () && c2->isPointerConv ()) { + // B* to A* better than B* to void* + if (f1 && f2 && *f1 == *f2) { + if (! t2 && param2->BaseType ()->isVoid () && baseClass (t1, f1)) + return 1; + if (! t1 && param1->BaseType ()->isVoid () && baseClass (t2, f2)) + return -1; + } + + // A* to void* better than B* to void* + if (! t1 && param1->BaseType ()->isVoid () && + ! t2 && param2->BaseType ()->isVoid ()) { + if (baseClass (f1, f2)) + return 1; + if (baseClass (f2, f1)) + return -1; + } + } + + if (! (f1 && f2 && t1 && t2)) + return 0; // indistinguishable + + if (c1->isPointerToMemberConv () && c2->isPointerToMemberConv ()) { + // A::* to B::* better than A::* to C::* + if (*f1 == *f2) { + if (baseClass (f1, t1) && baseClass (t1, t2)) + return 1; + if (baseClass (f2, t2) && baseClass (t2, t1)) + return -1; + } + // B::* to C::* better than A::* to C::* + if (*t1 == *t2) { + if (baseClass (f1, t1) && baseClass (f2, f1)) + return 1; + if (baseClass (f2, t2) && baseClass (f1, f2)) + return -1; + } + } else { + // C* to B* better than C* to A* + // C to B& better than C to A& + // C to B better than C to A + if (*f1 == *f2) { + if (baseClass (t1, f1) && baseClass (t2, t1)) + return 1; + if (baseClass (t2, f2) && baseClass (t1, t2)) + return -1; + } + + // B* to A* better than C* to A* + // B to A& better than C to A& + // B to A better than C to A + if (*t1 == *t2) { + if (baseClass (t1, f1) && baseClass (f1, f2)) + return 1; + if (baseClass (t2, f2) && baseClass (f2, f1)) + return -1; + } + } + + return 0; // indistinguishable +} + + +CClassInfo *CCConversions::extractClass (CTypeInfo *type, bool ref_bind) { + type = type->VirtualType (); + if (! ref_bind) { + if (type->TypeMemberPointer () && type->TypeMemberPointer ()->Record ()) + return type->TypeMemberPointer ()->Record ()->ClassInfo (); + else if (type->TypePointer ()) + type = type->BaseType ()->UnqualType (); + } + return type->TypeClass () ? type->TypeClass ()->ClassInfo () : (CClassInfo*)0; +} + + +// return true if seq1 is a proper subsequence of seq2 +bool CCConversions::properSubsequence (CCConvSeq *seq1, CCConvSeq *seq2) { + CCConversion *c1, *c2; + unsigned num_conv1 = seq1->Conversions (); + unsigned num_conv2 = seq2->Conversions (); + + // ignore any lvalue-to-rvalue conversions + for (unsigned i = 0; i < num_conv2; i++) { + c1 = seq1->Conversion (i); + if (c1->isLvalueToRvalueConv () || + c1->isArrayToPointerConv () || + c1->isFunctionToPointerConv ()) + continue; + + // ignore any lvalue-to-rvalue conversions + for (unsigned j = 0; j < num_conv2; j++) { + c2 = seq2->Conversion (j); + if (c2->isLvalueToRvalueConv () || + c2->isArrayToPointerConv () || + c2->isFunctionToPointerConv ()) + continue; + + // the identity conversion sequence is a subsequence + // of any other non-identity conversion sequence + if ((++j) < num_conv2 && c1->isIdentityConv ()) + return true; + + // now compare the subsequences + for (unsigned k = j; k < num_conv2; k++) { + // subsequence of seq2 is longer than subsequence of seq1 + if ((num_conv2-k) > (num_conv1-i)) + continue; + + // subsequence of seq2 is shorter than subsequence of seq1 + // so it cannot be a proper subsequence of seq2 + if ((num_conv2-k) < (num_conv1-i)) + return false; + + // compare seq1 with the remainder of seq2; must be equal + for (unsigned l = k; l < num_conv2; l++) { + c2 = seq2->Conversion (l); + + // not the same type of conversion + if (c1->Id () != c2->Id ()) + return false; + + // same type of conversions; but also same parameter + // and argument types? + if (*c1->FromType () != *c2->FromType () || + *c1->ToType () != *c2->ToType ()) + return false; + } + return true; + } + return false; + } + return false; + } + return false; +} + + +} // namespace Puma diff --git a/Puma/src/parser/ccparser/CCConversions.h b/Puma/src/parser/ccparser/CCConversions.h new file mode 100644 index 0000000..fb3125c --- /dev/null +++ b/Puma/src/parser/ccparser/CCConversions.h @@ -0,0 +1,80 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CCConversions_h__ +#define __CCConversions_h__ + +// 4, 13.3.3.1 implicit conversion sequences + +#include "Puma/ErrorSink.h" + +namespace Puma { + + +class CTree; +class CTypeInfo; +class CCConvSeq; +class CClassInfo; +class CCOverloading; + +class CCConversions { + ErrorSink &err; + +public: + // usage: (error stream, is_operator_overloading) + CCConversions (ErrorSink &); + + // determine conversions + CCConvSeq *implicitConversions (CTypeInfo *, CTypeInfo *, CTree *, CTree *, bool = true); + CCConvSeq *standardConversions (CTypeInfo *, CTypeInfo *, CTree *, CTree *); + CCConvSeq *userDefinedConversions (CTypeInfo *, CTypeInfo *, CTree *, CTree *); + CCConvSeq *referenceBinding (CTypeInfo *, CTypeInfo *, CTree *, CTree *, bool = true); + CCConvSeq *ellipsisConversions (); + + static CTypeInfo *integralPromotion (CTypeInfo *); + static CTypeInfo *arithmeticPromotion (CTypeInfo *); + static CTypeInfo *usualArithmeticConv (CTypeInfo *, CTypeInfo *); + + // compare conversion sequences + static int compareConvSeq (CCConvSeq *, CCConvSeq *); + + // conversion related operations on types + static bool similarTypes (CTypeInfo *, CTypeInfo *); + static bool referenceCompatible (CTypeInfo *, CTypeInfo *); + static bool referenceRelated (CTypeInfo *, CTypeInfo *); + static bool equalOrMoreQualified (CTypeInfo *, CTypeInfo *); + +protected: + // compare conversions + static int compareSameRankConvSeq (CCConvSeq *, CCConvSeq *); + static unsigned convSequenceRank (CCConvSeq *); + static bool properSubsequence (CCConvSeq *, CCConvSeq *); + + // helper + bool isValidConversion (CTree *, CTypeInfo *, CTypeInfo *, CCOverloading &) const; + static bool baseClass (CTypeInfo *, CTypeInfo *); + static bool baseClass (CClassInfo *, CClassInfo *); + static CClassInfo *extractClass (CTypeInfo *, bool); +}; + +inline CCConversions::CCConversions (ErrorSink &e) : err (e) {} + + +} // namespace Puma + +#endif /* __CCConversions_h__ */ diff --git a/Puma/src/parser/ccparser/CCExprResolveCC.ah b/Puma/src/parser/ccparser/CCExprResolveCC.ah new file mode 100644 index 0000000..d071801 --- /dev/null +++ b/Puma/src/parser/ccparser/CCExprResolveCC.ah @@ -0,0 +1,40 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CCExprResolveCC_ah__ +#define __CCExprResolveCC_ah__ + +// This aspect inserts resolve member functions into all syntax tree classes +// that represent expressions. As the function is virtual, an efficient +// run-time switch over the node type is implemented. + +#include "Puma/CCExprResolveH.ah" +#include "Puma/CCSemExpr.h" + +namespace Puma { + slice CTypeInfo *CCExprResolveCTree::resolve(CCSemExpr &sem_expr, CTree *base) { + return 0; + } + + slice CTypeInfo *CCExprResolveExpr::resolve (CCSemExpr &sem_expr, CTree *base) { + // this call is statically resolved with overload resolution, etc. + return sem_expr.resolve (this, base); + } +} + +#endif /* __CCExprResolveCC_ah__ */ diff --git a/Puma/src/parser/ccparser/CCExprResolveH.ah b/Puma/src/parser/ccparser/CCExprResolveH.ah new file mode 100644 index 0000000..a2280f8 --- /dev/null +++ b/Puma/src/parser/ccparser/CCExprResolveH.ah @@ -0,0 +1,50 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CCExprResolveH_ah__ +#define __CCExprResolveH_ah__ + +// This aspect inserts resolve member functions into all syntax tree classes +// that represent expressions. As the function is virtual, an efficient +// run-time switch over the node type is implemented. + +namespace Puma { + class CCSemExpr; +} + +using namespace Puma; + +namespace Puma { + slice class CCExprResolveCTree { + public: + virtual CTypeInfo *resolve(CCSemExpr &sem_expr, CTree *base); + }; + slice class CCExprResolveExpr { + public: + virtual CTypeInfo *resolve (CCSemExpr &sem_expr, CTree *base); + }; +} + +aspect CCExprResolve { + advice "Puma::CTree" : slice Puma::CCExprResolveCTree; + advice + derived ("Puma::CT_Expression"||"Puma::CT_SimpleName"||"Puma::CT_String") : + slice Puma::CCExprResolveExpr; +}; + +#endif /* __CCExprResolveH_ah__ */ diff --git a/Puma/src/parser/ccparser/CCLookAhead.ah b/Puma/src/parser/ccparser/CCLookAhead.ah new file mode 100644 index 0000000..d0f8e33 --- /dev/null +++ b/Puma/src/parser/ccparser/CCLookAhead.ah @@ -0,0 +1,524 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CCLookAhead_ah__ +#define __CCLookAhead_ah__ + +#include +#include + +aspect CCLookAhead { + + // FIRST sets and init functions + advice "Puma::CCSyntax": slice struct { + protected: + + // FIRST sets + tokenset _class_name_1; + tokenset _enum_name_1; + tokenset _template_name_1; + tokenset _class_template_name_1; + tokenset _namespace_name_1; + tokenset _original_ns_name_1; + tokenset _namespace_alias_1; + tokenset _qual_id_1; + tokenset _unqual_id_1; + tokenset _colon_colon_1; + tokenset _nested_name_spec_1; + tokenset _nested_name_spec1_1; + tokenset _class_or_ns_name_1; + tokenset _construct_expr_1; + tokenset _type_trait_expr_1; + tokenset _new_expr_1; + tokenset _new_placement_1; + tokenset _direct_new_declarator_1; + tokenset _direct_new_declarator1_1; + tokenset _new_init_1; + tokenset _delete_expr_1; + tokenset _namespace_def_1; + tokenset _named_ns_def_1; + tokenset _original_ns_def_1; + + tokenset _explicit_instantiation_1; + tokenset _explicit_specialization_1; + tokenset _access_spec_1; + tokenset _conv_fct_id_1; + tokenset _oper_fct_id_1; + tokenset _template_key_1; + tokenset _template_id_1; + tokenset _extension_ns_def_1; + tokenset _unnamed_ns_def_1; + + virtual void init_class_name () { + init_class_template_id (); + _class_name_1 = _template_id_1; + _class_name_1.set (TOK_ID); + } + + virtual void init_enum_name () { + _enum_name_1.set (TOK_ID); + } + + virtual void init_template_name () { + _template_name_1.set (TOK_ID); + } + + virtual void init_class_template_name () { + _class_template_name_1.set (TOK_ID); + } + + virtual void init_namespace_name () { + init_original_ns_name (); + init_namespace_alias (); + _namespace_name_1 = _original_ns_name_1; + _namespace_name_1 |= _namespace_alias_1; + } + + virtual void init_original_ns_name () { + _original_ns_name_1.set (TOK_ID); + } + + virtual void init_namespace_alias () { + _namespace_alias_1.set (TOK_ID); + } + + virtual void init_literal () { + CSyntax::init_literal (); + _literal_1.set (TOK_BOOL_VAL); + } + + virtual void init_prim_expr () { + CSyntax::init_prim_expr (); + _prim_expr_1.set (TOK_THIS); + } + + virtual void init_id_expr () { + // no call to CSyntax::init_id_expr()! This is completely different + init_qual_id (); + init_unqual_id (); + _id_expr_1 = _qual_id_1; + _id_expr_1 |= _unqual_id_1; + } + + virtual void init_qual_id () { + init_colon_colon (); + init_nested_name_spec (); + _qual_id_1 = _colon_colon_1; + _qual_id_1 |= _nested_name_spec_1; + } + + virtual void init_unqual_id () { + init_identifier (); + init_oper_fct_id (); + init_conv_fct_id (); + init_template_id (); + _unqual_id_1 = _identifier_1; + _unqual_id_1 |= _oper_fct_id_1; + _unqual_id_1 |= _conv_fct_id_1; + _unqual_id_1 |= _template_id_1; + _unqual_id_1.set (TOK_TILDE); + } + + virtual void init_colon_colon () { + _colon_colon_1.set (TOK_COLON_COLON); + } + + virtual void init_nested_name_spec () { + init_nested_name_spec1 (); + _nested_name_spec_1 = _nested_name_spec1_1; + } + + virtual void init_nested_name_spec1 () { + init_class_or_ns_name (), + init_template_key (); + _nested_name_spec1_1 = _class_or_ns_name_1; + _nested_name_spec1_1 |= _template_key_1; + } + + virtual void init_class_or_ns_name () { + init_class_name (); + init_namespace_name (); + _class_or_ns_name_1 = _class_name_1; + _class_or_ns_name_1 |= _namespace_name_1; + } + + virtual void init_postfix_expr1 () { + CSyntax::init_postfix_expr1 (); + } + + virtual void init_simple_type_spec () { + init_prim_types (); + init_type_name (); + init_nested_name_spec (); + init_colon_colon (); + _simple_type_spec_1 = _prim_types; + _simple_type_spec_1 |= _type_name_1; + _simple_type_spec_1 |= _nested_name_spec_1; + _simple_type_spec_1 |= _colon_colon_1; + } + + virtual void init_construct_expr () { + init_simple_type_spec (); + _construct_expr_1 = _simple_type_spec_1; + _construct_expr_1.set (TOK_TYPENAME); + } + + virtual void init_type_trait_expr () { + _type_trait_expr_1.set (TOK_HAS_NOTHROW_ASSIGN); + _type_trait_expr_1.set (TOK_HAS_NOTHROW_COPY); + _type_trait_expr_1.set (TOK_HAS_NOTHROW_CTOR); + _type_trait_expr_1.set (TOK_HAS_TRIVIAL_ASSIGN); + _type_trait_expr_1.set (TOK_HAS_TRIVIAL_COPY); + _type_trait_expr_1.set (TOK_HAS_TRIVIAL_CTOR); + _type_trait_expr_1.set (TOK_HAS_TRIVIAL_DTOR); + _type_trait_expr_1.set (TOK_HAS_VIRTUAL_DTOR); + _type_trait_expr_1.set (TOK_IS_ABSTRACT); + _type_trait_expr_1.set (TOK_IS_CLASS); + _type_trait_expr_1.set (TOK_IS_EMPTY); + _type_trait_expr_1.set (TOK_IS_ENUM); + _type_trait_expr_1.set (TOK_IS_POD); + _type_trait_expr_1.set (TOK_IS_TRIVIAL); + _type_trait_expr_1.set (TOK_IS_POLYMORPHIC); + _type_trait_expr_1.set (TOK_IS_UNION); + _type_trait_expr_1.set (TOK_IS_BASE_OF); + } + + virtual void init_new_expr () { + _new_expr_1.set (TOK_NEW); + _new_expr_1.set (TOK_COLON_COLON); + } + + virtual void init_new_placement () { + _new_placement_1.set (TOK_OPEN_ROUND); + } + + virtual void init_direct_new_declarator () { + _direct_new_declarator_1.set (TOK_OPEN_SQUARE); + } + + virtual void init_direct_new_declarator1 () { + _direct_new_declarator1_1.set (TOK_OPEN_SQUARE); + } + + virtual void init_new_init () { + _new_init_1.set (TOK_OPEN_ROUND); + } + + virtual void init_delete_expr () { + _delete_expr_1.set (TOK_DELETE); + _delete_expr_1.set (TOK_COLON_COLON); + } + + virtual void init_misc_spec () { + CSyntax::init_misc_spec (); + _misc_spec_1.set (TOK_FRIEND); + } + + virtual void init_storage_class_spec () { + CSyntax::init_storage_class_spec (); + _storage_class_spec_1.set (TOK_MUTABLE); + } + + virtual void init_fct_spec () { + CSyntax::init_fct_spec (); + _fct_spec_1.set (TOK_VIRTUAL); + _fct_spec_1.set (TOK_EXPLICIT); + } + + virtual void init_type_name () { + init_class_name (); + init_enum_name (); + init_typedef_name (); + _type_name_1 = _class_name_1; + _type_name_1 |= _enum_name_1; + _type_name_1 |= _typedef_name_1; + } + + virtual void init_elaborated_type_spec () { + init_class_key (); + _elaborated_type_spec_1 = _class_key_1; + _elaborated_type_spec_1.set (TOK_ENUM); + _elaborated_type_spec_1.set (TOK_TYPENAME); + } + + virtual void init_namespace_def () { + init_named_ns_def (); + init_unnamed_ns_def (); + _namespace_def_1 = _named_ns_def_1; + _namespace_def_1 |= _unnamed_ns_def_1; + } + + virtual void init_named_ns_def () { + init_original_ns_def (); + init_extension_ns_def (); + _named_ns_def_1 = _original_ns_def_1; + _named_ns_def_1 |= _extension_ns_def_1; + } + + // TODO: should call init_original_ns_def1 + virtual void init_original_ns_def () { + _original_ns_def_1.set (TOK_NAMESPACE); + _original_ns_def_1.set (TOK_INLINE); + } + + // TODO: should call init_extension_ns_def1 + virtual void init_extension_ns_def () { + _extension_ns_def_1.set (TOK_NAMESPACE); + _extension_ns_def_1.set (TOK_INLINE); + } + + // TODO: should call init_extension_ns_def1 + virtual void init_unnamed_ns_def () { + _unnamed_ns_def_1.set (TOK_NAMESPACE); + _unnamed_ns_def_1.set (TOK_INLINE); + } + + virtual void init_class_key () { + CSyntax::init_class_key (); + _class_key_1.set (TOK_CLASS); + } + + virtual void init_conv_fct_id () { + _conv_fct_id_1.set (TOK_OPERATOR); + } + +}; + + // dedicated lookahead rules + advice "Puma::CCSyntax::ClassName": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_class_name_1); + } + }; + advice "Puma::CCSyntax::EnumName": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_enum_name_1); + } + }; + advice "Puma::CCSyntax::TemplateName": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_template_name_1); + } + }; + advice "Puma::CCSyntax::ClassTemplateName": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_class_template_name_1); + } + }; + advice "Puma::CCSyntax::NamespaceName": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_namespace_name_1); + } + }; + advice "Puma::CCSyntax::OriginalNsName": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_original_ns_name_1); + } + }; + advice "Puma::CCSyntax::NamespaceAlias": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_namespace_alias_1); + } + }; + advice "Puma::CCSyntax::Literal": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_literal_1); + } + }; + advice "Puma::CCSyntax::PrimExpr": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_prim_expr_1); + } + }; + advice "Puma::CCSyntax::IdExpr": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_id_expr_1); + } + }; + advice "Puma::CCSyntax::QualId": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_qual_id_1); + } + }; + advice "Puma::CCSyntax::UnqualId": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_unqual_id_1); + } + }; + advice "Puma::CCSyntax::ColonColon": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_colon_colon_1); + } + }; + advice "Puma::CCSyntax::NestedNameSpec": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->is_nested_name (); + } + }; + advice "Puma::CCSyntax::NestedNameSpec1": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->is_nested_name (); + } + }; + advice "Puma::CCSyntax::ClassOrNsName": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_class_or_ns_name_1); + } + }; + advice "Puma::CCSyntax::PostfixExpr1": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_postfix_expr1_1); + } + }; + advice "Puma::CCSyntax::ConstructExpr": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_construct_expr_1); + } + }; + advice "Puma::CCSyntax::TypeTraitExpr": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_type_trait_expr_1); + } + }; + advice "Puma::CCSyntax::NewExpr": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_new_expr_1); + } + }; + advice "Puma::CCSyntax::NewPlacement": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_new_placement_1); + } + }; + advice "Puma::CCSyntax::DirectNewDeclarator": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_direct_new_declarator_1); + } + }; + advice "Puma::CCSyntax::DirectNewDeclarator1": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_direct_new_declarator1_1); + } + }; + advice "Puma::CCSyntax::NewInit": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_new_init_1); + } + }; + advice "Puma::CCSyntax::DeleteExpr": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_delete_expr_1); + } + }; + advice "Puma::CCSyntax::MiscSpec": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_misc_spec_1); + } + }; + advice "Puma::CCSyntax::StorageClassSpec": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_storage_class_spec_1); + } + }; + advice "Puma::CCSyntax::FctSpec": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_fct_spec_1); + } + }; + advice "Puma::CCSyntax::TypeName": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_type_name_1); + } + }; + advice "Puma::CCSyntax::ElaboratedTypeSpec": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_elaborated_type_spec_1); + } + }; + advice "Puma::CCSyntax::NamespaceDef": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_namespace_def_1); + } + }; + advice "Puma::CCSyntax::NamedNsDef": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_named_ns_def_1); + } + }; + advice "Puma::CCSyntax::OriginalNsDef": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_original_ns_def_1); + } + }; + advice "Puma::CCSyntax::ExtensionNsDef": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_extension_ns_def_1); + } + }; + advice "Puma::CCSyntax::UnnamedNsDef": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_unnamed_ns_def_1); + } + }; + advice "Puma::CCSyntax::DirectDeclarator1": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_direct_declarator1_1); + } + }; + advice "Puma::CCSyntax::ClassHead": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_class_head_1); + } + }; + advice "Puma::CCSyntax::ConvFctId": slice struct { + static inline bool lookahead(CCSyntax *s) { + return s->predict_1 (s->_conv_fct_id_1); + } + }; + + // default lookahead -> yields true for all rules + advice "Puma::CCSyntax::%" : slice struct { + static inline bool lookahead(void *) { return true; } + }; + + // make sure the FIRST sets are properly initialized + advice execution ("void Puma::CCSyntax::configure(...)") : after() { + // FIRST set initialization + tjp->that()->init_namespace_def (); + tjp->that()->init_explicit_instantiation (); + tjp->that()->init_explicit_specialization (); + tjp->that()->init_qual_id (); + tjp->that()->init_unqual_id (); + tjp->that()->init_access_spec (); + tjp->that()->init_enum_name(); + tjp->that()->init_template_name(); + tjp->that()->init_class_template_name(); + tjp->that()->init_colon_colon(); + tjp->that()->init_class_or_ns_name(); + tjp->that()->init_construct_expr(); + tjp->that()->init_type_trait_expr(); + tjp->that()->init_new_expr(); + tjp->that()->init_new_placement(); + tjp->that()->init_direct_new_declarator(); + tjp->that()->init_direct_new_declarator1(); + tjp->that()->init_new_init(); + tjp->that()->init_delete_expr(); + } +}; + +#endif /* __CCLookAhead_ah__ */ diff --git a/Puma/src/parser/ccparser/CCNameLookup.cc b/Puma/src/parser/ccparser/CCNameLookup.cc new file mode 100644 index 0000000..76d512b --- /dev/null +++ b/Puma/src/parser/ccparser/CCNameLookup.cc @@ -0,0 +1,624 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CCNameLookup.h" +#include "Puma/CTemplateParamInfo.h" +#include "Puma/CTemplateInstance.h" +#include "Puma/CNamespaceInfo.h" +#include "Puma/CFunctionInfo.h" +#include "Puma/CClassInfo.h" +#include "Puma/CSemDatabase.h" +#include "Puma/CUnionInfo.h" +#include "Puma/CTemplateInfo.h" +#include "Puma/CEnumInfo.h" +#include "Puma/CUsingInfo.h" +#include "Puma/CMemberAliasInfo.h" +#include "Puma/CTree.h" +#include /* strcmp(), strncmp() */ +#include /* cerr */ +#include /* assert() */ + +namespace Puma { + + + +CCNameLookup::CCNameLookup (ErrorSink &e, CStructure* curr_scope, bool allow_inst) : err(e) { + pos = 0; + name = 0; + sname = 0; + flags = 0; + virtualbase = 0; + current_scope = curr_scope; + allow_instantiate = allow_inst; +} + + + +bool CCNameLookup::isAnonymous () const { + return name && strncmp(name, "%anon", 5) == 0; +} + + + +/////////////////////////////////////////////////////// +// §3.4 name lookup /////////////////////////////////// +/////////////////////////////////////////////////////// + + + +void CCNameLookup::lookup (CT_SimpleName *sn, CStructure *scope, + bool nested, bool base_usings) { + virtualbase = 0; + unsigned long num = Objects (); + + // §3.4.3 qualified name lookup + if (sn->NodeName () == CT_QualName::NodeId () || + sn->NodeName () == CT_RootQualName::NodeId ()) { + sname = sn->Name (); + name = sname->Text (); + pos = sname->token_node () ? sname->token_node ()->Number () : 0; + CStructure *name_scope = getNameScope (sn, scope); + if (!isAnonymous()) + lookup (name_scope, false, true); + // §3.4.1 unqualified name lookup + } else { + sname = sn; + name = sname->Text (); + pos = sname->token_node () ? sname->token_node ()->Number () : 0; + if (!isAnonymous()) + lookup (scope, nested, base_usings); + } + + // filter names hidden by dominating declarations + // (§10.1.4 virtual inheritance) + findMostDominant (num); + + // clean up + flags = 0; + virtualbase = 0; +} + + + +// §10.1.4 virtual inheritance, find most dominant name +void CCNameLookup::findMostDominant (unsigned long num) { + // start a simple tournament to filter names dominated by others + for (long i = (long)Objects (); i > (long)num; i--) { + CObjectInfo *champion = Object (i-1); + CClassInfo *champion_vb = virtualbases.lookup (i-1); + // let the champion face all other candidates + if (champion_vb && champion->isClassMember ()) { + for (long j = (long)Objects (); j > (long)num; j--) { + CObjectInfo *challenger = Object (j-1); + CObjectInfo *challenger_os = objscopes.lookup (j-1); + // check if challenger dominates the champion + if (challenger != champion && challenger_os && + challenger_os->ClassInfo () && challenger->isClassMember ()) { + if (dominates (challenger_os, champion_vb)) { + // challenger has won, remove the champion + objects.remove (i-1); + virtualbases.remove (i-1); + objscopes.remove (i-1); + i--; j--; + break; + } + } + } + } + } +} + + + +// check if the first candidate dominates the second +bool CCNameLookup::dominates (CObjectInfo *object_scope, CObjectInfo *virtual_base) { + // if the second candidate is in a subobject of the first + // candidate, the first candidate hides the second + if (isSameSubObject ((CClassInfo*)object_scope, (CClassInfo*)virtual_base)) { + return true; + } + return false; +} + + + +bool CCNameLookup::isSameSubObject (CClassInfo *ci, CClassInfo *bc1) { + if (ci && bc1) { + for (unsigned i = ci->BaseClasses (); i > 0; i--) { + CBaseClassInfo *bci = ci->BaseClass (i-1); + CClassInfo *bc2 = bci->Class (); + if (bc2) { + if (bci->isVirtual () && (*bc1 == *bc2)) { + return true; + } else if (isSameSubObject (bc2, bc1)) { + return true; + } + } + } + } + return false; +} + + + +CStructure *CCNameLookup::getNameScope (CT_SimpleName *sn, CStructure *scope) const { + CObjectInfo *info; + int entries = sn->Entries (); + if (entries > 1) { // class or namespace scope + info = ((CT_SimpleName*)sn->Entry (entries-2))->Object (); + if (info) { + if (info->isTemplateInstance () && ! info->TemplateInstance ()->canInstantiate ()) + info = info->TemplateInstance ()->Template ()->ObjectInfo (); + if (info->Record () || info->NamespaceInfo ()) + scope = (CStructure*)info->DefObject (); + else if (info->TypedefInfo () && info->TypeInfo ()->VirtualType ()->TypeRecord ()) + scope = (CStructure*)info->TypeInfo ()->VirtualType ()->TypeRecord ()->Record ()->DefObject (); + } + } else { // file scope + while (scope->Parent () != scope) + scope = scope->Parent ()->Structure (); + } + return scope; +} + + + +// §3.4.1 unqualified name lookup +void CCNameLookup::lookup (CStructure *scope, bool nested, bool base_usings) { + CClassInfo *cinfo, *bcinfo; + CBaseClassInfo *baseclass; + CObjectInfo *info; + unsigned num; + + // consider scopes that are pseudo template instances + CTemplateInstance* inst = scope->TemplateInstance (); + if (inst && inst->isPseudoInstance () && inst->Template ()->ObjectInfo ()->Structure ()) { + if (inst->canInstantiate () && allow_instantiate) { + inst->instantiate (current_scope ? current_scope : scope); + } else { + scope = inst->Template ()->ObjectInfo ()->Structure (); + } + } + + // lookup unqualified name in current scope + num = Objects (); + unqualifiedLookup (scope, nested, base_usings); + + // handle template scope as if it wouldn't be an own scope + if (scope->TemplateInfo ()) + num = Objects (); + // name found, stop here + else if (Objects () > num) + return; + + // §9.1.2 the name of a class or union is also considered + // a member of that class or union + if (! (flags & IS_NAMESPACE) && scope->isRecord () && + ! scope->Name ().empty () && scope->Name () == name) { + // template instances are not found by name lookup, + // so add the template instead of the instance + if (scope->isTemplateInstance ()) + scope = scope->TemplateInstance ()->Template ()->ObjectInfo ()->Structure (); + addObject (scope, scope); + } + + // §10.2 member name lookup + // §10.2.2 lookup in base classes (if any) only if there + // is no declaration in current scope that hides potential + // declarations in base class sub-objects + else if (scope->isClass () && base_usings) { + // each of the base classes is looked up; the result is + // the set of declarations found in one or more base classes + cinfo = scope->DefObject ()->ClassInfo (); + for (unsigned i = cinfo->BaseClasses (); i > 0; i--) { + baseclass = cinfo->BaseClass (i-1); + // §10.1.4 virtual base classes, do not lookup twice + // in the same subobject + if (isDistinctSubObject(baseclass) && + (! (flags & IS_FRIEND) || ! baseclass->ClassPseudoInstance ())) { + bcinfo = baseclass->Class (); + if (bcinfo != cinfo) { + CClassInfo *oldvirtualbase = virtualbase; + if (baseclass->isVirtual ()) { + virtualbase = bcinfo; + } + lookup (bcinfo, false, base_usings); + virtualbase = oldvirtualbase; + } + } + } + } + + if (Objects () == num) { + // §9.3.5 lookup in member function's class/namespace if function + // is defined outside of the class/namespace's body + if (scope->QualifiedScope () && scope->QualifiedScope () != scope && nested) + lookup (scope->QualifiedScope (), true, base_usings); + } + + if (Objects () == num) { + // §14.6.1.7 template parameters can be hidden only by names + // of base classes or (direct and inherited) class members + info = scope->TemplateParam (name); + if (! (flags & IS_NAMESPACE) && info) + addObject (info, scope); + } + + // continue in parent scopes if nested and nothing was found here + if (Objects () == num && nested) { + info = scope; scope = scope->Parent ()->Structure (); + if (scope && scope != info) + // if looking up a friend search only until the nearest + // non-class non-template scope + if (! (flags & IS_FRIEND) || info->Record () || info->TemplateInfo () || + (info->NamespaceInfo () && info->NamespaceInfo ()->aroundInstantiation ())) + lookup (scope, nested, base_usings); + } +} + + + +// §10.1.4 virtual base classes +bool CCNameLookup::isDistinctSubObject (CBaseClassInfo *bcinfo) { + // check if the base class is a distinct sub-object of a class, + // i.e. there is at least one non-virtual base class of the + // same class type + bool is_virtual = bcinfo->isVirtual (); + CClassInfo *cinfo = bcinfo->Class (); + // get the previous base class declaration (if there is any) + BaseClassMap::iterator prev = baseclasses.find (cinfo); + if (prev != baseclasses.end ()) { + if (is_virtual) { + // if both, this and the previous base class declaration, + // are virtual, this sub-object is not distinct but + // the same as for the previous base class declaration + if (prev->second == true) { + // sub-object not distinct + return false; + } + // remember that there is already a virtual base class + // of that class type + prev->second = true; + } + } else { + // first occurrence of this base class during lookup + baseclasses[cinfo] = is_virtual; + } + // sub-object is distinct + return true; +} + + + +/////////////////////////////////////////////////////// +// usual unqualified name lookup in current scope ///// +/////////////////////////////////////////////////////// + + + +void CCNameLookup::unqualifiedLookup (CStructure *scope, bool nested, bool base_usings) { + CObjectInfo *last = 0, *tmp; + CStructure *ns; + unsigned num; + + num = Objects (); + if (flags & IS_TYPE) { + unqualTypeLookup (scope); + } else { + if (scope->isNamespace ()) { + tmp = unqualLookup (scope, nested); + // name hiding mechanism + if (Objects () > num) + last = 0; + else if (! last) + last = tmp; + } else + last = unqualLookup (scope, nested); + + // visible class, union, or enum name + if (last) + addObject (last, scope); + } + + // §3.4.1.2 consider declarations in namespaces nominated + // by using-directives (if any) in namespace and local scope + if (base_usings) { + if (scope->isNamespace ()) { + ns = scope; + do { // consider the namespace extensions too + lookupUsings (ns); + ns = (CStructure*)ns->NextObject (); + } while (ns != scope); + } else if (scope->isLocalScope ()) + lookupUsings (scope); + } +} + + + +// usual unqualified lookup +CObjectInfo *CCNameLookup::unqualLookup (CStructure *scope, bool nested) { + CObjectInfo *info, *last = 0, *pinfo; + CFunctionInfo *finfo; + CTemplateInfo *tpl; + bool is_class; + + is_class = scope->isClass (); + tpl = scope->TemplateInfo (); + scope = scope->DefObject ()->Structure (); + + ObjectsIter sameNameListIter = scope->ObjectInfoMap ().find (name); + + if (sameNameListIter != scope->ObjectInfoMap ().end ()) { + CStructure::ObjectInfoList &sameNameList = sameNameListIter->second; + + for (ObjectListRIter riter = sameNameList.rbegin (); + riter != sameNameList.rend (); riter++) { + info = pinfo = *riter; + + // template instances are never found by name lookup + if (info->isTemplateInstance ()) + continue; + + // do not find templates in template scope; templates are introduced + // e.g. into the surrounding scope and will be found there + if (tpl && tpl->ObjectInfo () == info) + continue; + + // §7.3.3.12 base class member functions introduced in a derived + // class by a using declaration can be hidden by direct member + // functions of the derived class that have the same name and + // parameter types + if (info->MemberAliasInfo ()) { + if (flags & NO_MEMBER_ALIAS) + continue; + + info = info->MemberAliasInfo ()->Member (); + if (is_class && info->FunctionInfo ()) { + // check for direct member functions with the same parameter types + bool hidden = false; + for (ObjectListRIter rfiter = sameNameList.rbegin (); rfiter != sameNameList.rend (); rfiter++) { + finfo = (*rfiter)->FunctionInfo (); + if (finfo && finfo->hasSameNameAndArgs ((CFunctionInfo*)info)) { + hidden = true; + break; + } + } + if (hidden) + continue; + } + // members defined qualified in a scope will not be introduced + // in this scope, i.e. they are not visible here + } else if (info->QualifiedScope () && *info->QualifiedScope () != *scope) + continue; + + if (info->Name ().empty () || /*info->Name () != name ||*/ ! knownHere (pinfo)) + continue; + + // §3.3.7 name hiding + if (! info->Record () && ! info->EnumInfo ()) { + last = 0; + + if (! info->FunctionInfo ()) { + // match namespaces only if searching for a namespace + if ((flags & IS_NAMESPACE) && ! info->NamespaceInfo ()) + continue; + + // lookup succeeded; break + addObject (info, scope); + break; + // don't break due to be possibly overloaded by other + // function declarations + // §12.1.2 constructors (and destructors) have no name + // and therefore are never found by name lookup + // §13.3.1.2.3 ignore class member functions when looking + // up unqualified operator names (non-member candidates) + } else if (! info->FunctionInfo ()->isConstructor () && + /*! info->FunctionInfo ()->isDestructor () &&*/ + ! ((flags & NO_MEMBER_FCTS) && info->isClassMember ())) { + // §7.3.1.2.3 friend functions declared first in class scope + // are not found unless explicitly declared in namespace scope + // except if a previous declaration is looked up (=> ! nested) + // or associated namespaces are considered + if (((flags & ASS_NS_LOOKUP) && ! nested && scope->NamespaceInfo ()) || + ! invisibleFriend (info)) { + addObject (info, scope); + } + } + // don't break due to be possibly hidden by an object, + // function, or enumerator + // skip forward declarations of the form `... class-key identifier ...' + // because they don't hide entities declared in enclosing scopes + } else if (! last && (info->Record () ? + ! info->Record ()->isHiddenForwardDecl () : true)) { + last = info; + } + } + } + + return last; +} + + + +// unqualified lookup for type names +void CCNameLookup::unqualTypeLookup (CStructure *scope) { + if (flags & IS_NAMESPACE) + return; + + CObjectInfo *info, *pinfo; + bool is_class = scope->isClass (); + + scope = scope->DefObject ()->Structure (); + + ObjectsIter sameNameListIter = scope->ObjectInfoMap ().find (name); + if (sameNameListIter != scope->ObjectInfoMap ().end ()) { + CStructure::ObjectInfoList& sameNameList = sameNameListIter->second; + + for (ObjectListRIter riter = sameNameList.rbegin (); + riter != sameNameList.rend (); riter++) { + info = pinfo = *riter; + + // §7.3.3.12 names of base class members introduced in a derived + // class by a using declaration can be hidden by direct members + // of the derived class + if (info->MemberAliasInfo ()) { + if (is_class) + continue; + info = info->MemberAliasInfo ()->Member (); + // members defined qualified in a scope will not be introduced + // in this scope, i.e. they are not visible here + } else if (info->QualifiedScope () && info->QualifiedScope () != scope) + continue; + + // consider types only + if (! (info->Record () || info->EnumInfo () || info->TypedefInfo ())) + continue; + if (! info->Name ()) + continue; + if (info->Name () != name) + continue; + if (! knownHere (pinfo)) + continue; + + // §3.3.7 name hiding; names of types otherwise hidden + // are successfully looked up by not consider non-type + // declarations + addObject (info, scope); + return; + } + } + + // §7.3.3.12 lookup member alias names (introduced by using + // declarations) if not hidden by direct class members + if (is_class) { + + if (sameNameListIter != scope->ObjectInfoMap ().end ()) { + CStructure::ObjectInfoList &sameNameList = sameNameListIter->second; + + for (ObjectListRIter riter = sameNameList.rbegin (); + riter != sameNameList.rend (); riter++) { + info = pinfo = *riter; + + // consider member aliases only + if (! info->MemberAliasInfo ()) + continue; + + info = info->MemberAliasInfo ()->Member (); + if ((info->Record () || info->EnumInfo () || info->TypedefInfo ()) && + ! info->Name ().empty () && info->Name () == name && + knownHere (pinfo)) { + addObject (info, scope); + return; + } + } + } + + } +} + + + +CStructure* CCNameLookup::getNonTemplateScope (CStructure* scope) const { + // skip all template and template instance scopes + scope = scope->Parent ()->Structure (); + while (scope->TemplateInfo () || + (scope->NamespaceInfo () && scope->NamespaceInfo ()->aroundInstantiation ())) + scope = scope->Parent ()->Structure (); + return scope; +} + + + +bool CCNameLookup::invisibleFriend (CObjectInfo *info) const { + // §7.3.1.2.3 friend functions declared first in class scope + // are not found unless explicitly declared in namespace scope + CFunctionInfo *finfo = (CFunctionInfo*)info; + bool is_friend = false, visible = false; + do { + if (getNonTemplateScope (finfo)->isNamespace ()) + visible = true; + if (finfo->AssignedScope ()) + is_friend = true; + finfo = (CFunctionInfo*)finfo->NextObject (); + } while (finfo != info); + return is_friend && !visible; +} + + + +bool CCNameLookup::knownHere (CObjectInfo *info) const { + CT_Token *token; + // if in template instance, then it is known + CObjectInfo *curr = info; + while (curr) { + if (curr->isTemplateInstance ()) + return true; + if (curr == curr->Scope ()) + break; + curr = curr->Scope (); + } + // is known if declared before the current position + if (pos && info->Tree ()) { + token = info->Tree ()->token_node (); + if (token && token->Number () > pos) + return false; + } + return true; +} + + + +/////////////////////////////////////////////////////// +// §3.4.1.2 namespace member lookup /////////////////// +/////////////////////////////////////////////////////// + + + +void CCNameLookup::lookupUsings (CStructure *scope) { + CObjectInfo *info; + CUsingInfo *uinfo; + + // §7.3.4.4 lookup name in ALL nominated namespaces + for (unsigned i = scope->Usings (); i > 0; i--) { + uinfo = scope->Using (i-1); + if (! knownHere (uinfo)) + continue; + + info = uinfo->Namespace (); + if (! namespaceVisited (info)) + lookup (info->Structure (), false, true); + + // same name declared in different namespaces and not all + // of it are functions => ambiguous use of that name + // !!! CORRELATING CHECK TO BE IMPLEMENTED !!! + } +} + + + +bool CCNameLookup::namespaceVisited (CObjectInfo *nsinfo) { + for (long i = namespaces.length (); i > 0; i--) + if (namespaces[i-1] == nsinfo) + return true; + namespaces.append (nsinfo); + return false; +} + + +} // namespace Puma diff --git a/Puma/src/parser/ccparser/CCNameLookup.h b/Puma/src/parser/ccparser/CCNameLookup.h new file mode 100644 index 0000000..cda1d23 --- /dev/null +++ b/Puma/src/parser/ccparser/CCNameLookup.h @@ -0,0 +1,179 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CCNameLookup_h__ +#define __CCNameLookup_h__ + +#include "Puma/Array.h" +#include "Puma/ErrorSink.h" +#include "Puma/DString.h" +#include "Puma/CStructure.h" +#include +#include + +namespace Puma { + + +class CT_SimpleName; +class CBaseClassInfo; + +class CCNameLookup { + typedef std::map BaseClassMap; + + Array objects; + Array namespaces; + BaseClassMap baseclasses; + CClassInfo* virtualbase; + Array virtualbases; + Array objscopes; + CT_SimpleName * sname; + DString name; + ErrorSink & err; + unsigned int pos; + unsigned char flags; + CStructure* current_scope; + bool allow_instantiate; + + typedef CStructure::ObjectsByName::iterator ObjectsIter; + typedef CStructure::ObjectInfoList::reverse_iterator ObjectListRIter; + +public: + enum Flags { + IS_TYPE = 1, // lookup a type name ignoring all non-types + IS_NAMESPACE = 2, // lookup a namespace name ignoring everything else + ASS_NS_LOOKUP = 4, // lookup in associated namespace (overload resolution) + NO_MEMBER_FCTS = 8, + NO_MEMBER_ALIAS = 16, + IS_FRIEND = 32 // lookup until nearest non-class scope + }; + +public: + CCNameLookup (ErrorSink &, CStructure* curr_scope = 0, bool allow_inst = true); + + // usage: lookup(name, scope, nested, base classes & usings) + void lookup (const DString&, CStructure *, bool = false, bool = false, int = 0); + void lookup (CT_SimpleName *, CStructure *, bool = false, bool = false); + void lookupType (const DString&, CStructure *, bool = false, bool = false, int = 0); + void lookupType (CT_SimpleName *, CStructure *, bool = false, bool = false); + void lookupNamespace (const DString&, CStructure *, int = 0); + void lookupNamespace (CT_SimpleName *, CStructure *); + void lookupInAssNs (const DString&, CStructure *, int = 0); + void lookupInAssNs (CT_SimpleName *, CStructure *); + void lookupOpName (const DString&, CStructure *, int = 0); + void lookupOpName (CT_SimpleName *, CStructure *); + void lookupFunction (const DString&, CStructure *, int = 0); + void lookupFunction (CT_SimpleName *, CStructure *); + void lookupFriendClass (const DString&, CStructure *, int = 0); + void lookupFriendClass (CT_SimpleName *, CStructure *); + + // resulting set of object infos + unsigned Objects () const; + CObjectInfo *Object (unsigned = 0) const; + + // reset the internal state and reject + // the result of previous lookups + void reset (CStructure* curr_scope = 0, bool allow_inst = true); + +private: + void lookup (CStructure *, bool, bool); + void unqualifiedLookup (CStructure *, bool, bool base_usings); + CObjectInfo *unqualLookup (CStructure *, bool); + void unqualTypeLookup (CStructure *); + void lookupUsings (CStructure *); + bool namespaceVisited (CObjectInfo *); + void addObject (CObjectInfo *, CStructure *); + bool invisibleFriend (CObjectInfo *) const; + bool knownHere (CObjectInfo *) const; + CStructure *getNameScope (CT_SimpleName *, CStructure *) const; + CStructure *getNonTemplateScope (CStructure* scope) const; + bool isDistinctSubObject (CBaseClassInfo *bcinfo); + void findMostDominant (unsigned long num); + bool dominates (CObjectInfo *cand1, CObjectInfo *cand2); + bool isSameSubObject (CClassInfo *ci, CClassInfo *bc1); + bool isAnonymous () const; +}; + +inline unsigned CCNameLookup::Objects () const + { return objects.length (); } +inline CObjectInfo *CCNameLookup::Object (unsigned i) const + { return objects.lookup (i); } + +inline void CCNameLookup::addObject (CObjectInfo *info, CStructure *scope) + { objects.append (info); virtualbases.append (virtualbase); + objscopes.append (scope); } +inline void CCNameLookup::reset (CStructure* curr_scope, bool allow_inst) + { objects.reset (); namespaces.reset (); baseclasses.clear (); objscopes.reset (); + virtualbase = 0; virtualbases.reset (); flags = 0; + current_scope = curr_scope; allow_instantiate = allow_inst; } + +inline void CCNameLookup::lookup (const DString& sn, CStructure *scope, + bool nested, bool base_usings, int p) + { sname = 0; name = sn; pos = p; if (!isAnonymous()) lookup (scope, nested, base_usings); flags = 0; } + +inline void CCNameLookup::lookupType (const DString& sn, + CStructure *scope, bool nested, bool base_usings, int p) + { flags = IS_TYPE; lookup (sn, scope, nested, base_usings, p); } + +inline void CCNameLookup::lookupType (CT_SimpleName *sn, + CStructure *scope, bool nested, bool base_usings) + { flags = IS_TYPE; lookup (sn, scope, nested, base_usings); } + +inline void CCNameLookup::lookupFriendClass (const DString& sn, + CStructure *scope, int p) + { flags = IS_TYPE | IS_FRIEND; lookup (sn, scope, true, true, p); } + +inline void CCNameLookup::lookupFriendClass (CT_SimpleName *sn, + CStructure *scope) + { flags = IS_TYPE | IS_FRIEND; lookup (sn, scope, true, true); } + +inline void CCNameLookup::lookupNamespace (const DString& sn, + CStructure *scope, int p) + { flags = IS_NAMESPACE; lookup (sn, scope, true, true, p); } + +inline void CCNameLookup::lookupNamespace (CT_SimpleName *sn, + CStructure *scope) + { flags = IS_NAMESPACE; lookup (sn, scope, true, true); } + +inline void CCNameLookup::lookupFunction (const DString& sn, + CStructure *scope, int p) + { flags = NO_MEMBER_ALIAS; lookup (sn, scope, false, false, p); } + +inline void CCNameLookup::lookupFunction (CT_SimpleName *sn, + CStructure *scope) + { flags = NO_MEMBER_ALIAS; lookup (sn, scope, false, false); } + +inline void CCNameLookup::lookupInAssNs (const DString& sn, + CStructure *scope, int p) + { flags = ASS_NS_LOOKUP; lookup (sn, scope, false, false, p); } + +inline void CCNameLookup::lookupInAssNs (CT_SimpleName *sn, + CStructure *scope) + { flags = ASS_NS_LOOKUP; lookup (sn, scope, false, false); } + +inline void CCNameLookup::lookupOpName (const DString& sn, + CStructure *scope, int p) + { flags = NO_MEMBER_FCTS; lookup (sn, scope, true, true, p); } + +inline void CCNameLookup::lookupOpName (CT_SimpleName *sn, + CStructure *scope) + { flags = NO_MEMBER_FCTS; lookup (sn, scope, true, true); } + + +} // namespace Puma + +#endif /* __CCNameLookup_h__ */ diff --git a/Puma/src/parser/ccparser/CCOverloading.cc b/Puma/src/parser/ccparser/CCOverloading.cc new file mode 100644 index 0000000..fd3fdbf --- /dev/null +++ b/Puma/src/parser/ccparser/CCOverloading.cc @@ -0,0 +1,1565 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CTemplateParamInfo.h" +#include "Puma/CCInstantiation.h" +#include "Puma/CClassInstance.h" +#include "Puma/CUnionInstance.h" +#include "Puma/CNamespaceInfo.h" +#include "Puma/CSemDatabase.h" +#include "Puma/CCOverloading.h" +#include "Puma/CFunctionInfo.h" +#include "Puma/CArgumentInfo.h" +#include "Puma/CTemplateInfo.h" +#include "Puma/CCNameLookup.h" +#include "Puma/CFctInstance.h" +#include "Puma/CUnionInfo.h" +#include "Puma/CClassInfo.h" +#include "Puma/CEnumInfo.h" +#include "Puma/CTypeInfo.h" +#include "Puma/CCSemExpr.h" +#include "Puma/CTree.h" + +#include + +namespace Puma { + + +#define INTERNAL_ERROR(loc__,mesg__) \ + err << sev_fatal << loc__->token ()->location () \ + << "internal error: " << mesg__ << endMessage + + +//////////////////////////////////////////////////////////// +// �13.3 overload resolution /////////////////////////////// +//////////////////////////////////////////////////////////// + + +void CCOverloading::resolve (CTree *args, bool allow_user_defined) { + CT_CallExpr *call; + + if (! Candidates () || ! args) + return; + + user_def = allow_user_defined; + _Poi = args; + if (args->NodeName () == CT_CallExpr::NodeId ()) { + call = (CT_CallExpr*)args; + args = call->Arguments (); + _Poi = call->Son (0); + } else if (args->NodeName () != CT_ExprList::NodeId ()) + return; + + _Base = args; + _Arguments = args; + _NumArgs = ((CT_ExprList*)args)->Entries (); + + // start overload resolution algorithm + chooseViableFcts (); + chooseBestViableFct (); +} + + +void CCOverloading::resolve (CTree *base, CTree *arg0, bool allow_user_defined) { + if (! Candidates () || ! base || ! arg0) + return; + + user_def = allow_user_defined; + _Base = base; + _Arg0 = arg0; + _NumArgs = 1; + _Poi = arg0; + + // start overload resolution algorithm + chooseViableFcts (); + chooseBestViableFct (); +} + + +void CCOverloading::resolve (CTree *base, CTree *arg0, CTree *arg1, bool allow_user_defined) { + if (! Candidates () || ! base || ! arg0 || ! arg1) + return; + + user_def = allow_user_defined; + _Base = base; + _Arg0 = arg0; + _Arg1 = arg1; + _NumArgs = 2; + _Poi = arg0; + + // start overload resolution algorithm + chooseViableFcts (); + chooseBestViableFct (); +} + + +void CCOverloading::resolveMember (CTree *args, CTree *member) { + CT_CallExpr *call; + + if (! Candidates () || ! args) + return; + + user_def = true; + if (args->NodeName () == CT_CallExpr::NodeId ()) { + call = (CT_CallExpr*)args; + args = call->Arguments (); + } else if (args->NodeName () != CT_ExprList::NodeId ()) + return; + + _Poi = member; + _Base = args; + _Arguments = args; + _NumArgs = ((CT_ExprList*)args)->Entries (); + + // start overload resolution algorithm + chooseViableFcts (); + chooseBestViableFct (); +} + + +// �13.3.2 viable functions +void CCOverloading::chooseViableFcts () { + bool has_ellipsis, is_method, implicit_this, real_inst, was_silent; + CTree *arg_expr, *param_expr; + unsigned num_params, offset; + ErrorSeverity old_severity; + CTypeInfo *ptype, *atype; + CCConvSeq *seq, *seq2; + CCandidateInfo *ci; + CFunctionInfo *cf; + CObjectInfo *info; + CTypeList *params; + CProject *project; + + // turn off error reporting + project = 0; + unsigned i = Candidates (); + if (i) { + project = Candidate (0)->Function ()->SemDB ()->Project (); + was_silent = project->err ().silent (); + old_severity = project->err ().severity (); + } + + // check for each candidate if it is viable for the function call arguments + for (; i > 0; i--) { + ci = Candidate (i-1); // current candidate function + cf = ci->Function (); + real_inst = !cf->SemDB ()->Project ()->config ().Option ("--pseudo-instances"); + bool delayed_parse_problem = false; + + if (cf->isTemplate () && _Poi) { + // instantiate function template + implicit_this = cf->isMethod () && cf->isOperator (); + CCInstantiation cci (err, false); + for (unsigned j = (implicit_this ? 1 : 0); j < Arguments (); j++) + cci.addArgument (Argument (j)); + info = cci.instantiate (_Poi, cf, true, 0, true); + if (info && info->FunctionInfo ()) { + cf = info->FunctionInfo (); + ci->Function (cf); + if (info->TemplateInstance()->hasDelayedParseProblem ()) { + delayed_parse_problem = true; + } + if (! real_inst) + dependent = true; + // instantiation failed; not a viable function template + } else { + removeCandidate (i-1); + continue; + } + } + + if (! real_inst && cf->TypeInfo ()->isDependent (false)) + dependent = true; + + params = cf->TypeInfo ()->ArgTypes (); + is_method = false; + offset = 0; + + // �13.3.1 contrive implicit object parameter (if necessary) + if (cf->isMethod () && ! cf->isConstructor ()) { + // skip all candidates that are less qualified than + // the object they shall be called on + // (exception: for static methods the qualifiers don't have to be checked) + if (! cf->isStaticMethod () && obj_type && + ! equalOrMoreQualified (cf->TypeInfo (), obj_type)) { + removeCandidate (i-1); + continue; + } + + atype = cf->Record ()->TypeInfo (); + is_method = true; + + if (cf->isConversion ()) { + ptype = cf->ConversionType (); + if (! real_inst && ptype->isDependent (false)) + dependent = true; + + // �13.3.1.1.2.2 surrogate call function + if ((ptype->isPointer () && + ptype->VirtualType ()->BaseType ()->isFunction ()) || + (ptype->isAddress () && ptype->isFunction ())) { + // implicit object parameter conversion + seq = new CCUserDefinedConvSeq; + // 1. initial standard conversion sequence + seq->addConversion (new CCIdentityConv (atype, atype)); + // 2. user-defined conversion + seq->addConversion (new CCUserDefinedConv (ptype, atype, cf)); + // 3. second standard conversion sequence + seq2 = implicitThisConv (ptype, cf); + seq->addConversion (seq2); + ci->addConvSequence (seq); + ptype = ptype->isPointer () ? ptype->VirtualType ()->BaseType () : ptype; + params = ptype->VirtualType ()->TypeFunction ()->ArgTypes (); + cf = 0; + // usual conversion function + } else { + // conversion functions do not have parameters + // (except the implicit object parameter) + seq = implicitThisConv (atype, cf); + ci->addConvSequence (seq); + continue; + } + // non-conversion functions + } else { + seq = implicitThisConv (atype, cf); + ci->addConvSequence (seq); + } + } + + // �13.3.2.2 the number of parameters shall agree in + // number of arguments of the function call; + // in case of operator overloading the implicit object + // parameter is considered to be a regular parameter + // of the overloaded operator + if (operator_ovl && is_method) + offset = 1; + num_params = params->Entries (); + has_ellipsis = (num_params && params->Entry (num_params-1)->is_ellipsis ()); + num_params = has_ellipsis ? num_params-1 : num_params; + if (! ((num_params+offset) == Arguments () || + // operators neither have variable number nor default arguments + (! operator_ovl && + ((num_params < Arguments () && has_ellipsis) || + (hasDefaultArgument (cf, params, num_params)))))) { + removeCandidate (i-1); + continue; + } + + // Remember that this candidate has a delayed parse problem with + // an initializer of a default argument if a default argument had to + // be used + if (delayed_parse_problem && + hasDefaultArgument (cf, params, num_params)) + ci->markDelayedParseProblem (); + + // dependent call + if (params->isDependent ()) + dependent = true; + + // �13.3.2.3 for each argument shall exist an implicit conversion + // sequence converting that argument to the corresponding parameter type + for (unsigned j = 0; j < (Arguments ()-offset); j++) { + // argument matches ellipsis parameter + if (j >= num_params) { + ci->addConvSequence (cvs.ellipsisConversions ()); + continue; + } + + param_expr = cf->Arguments () > j ? cf->Argument (j)->Tree () : 0; + ptype = params->Entry (j); + arg_expr = Argument (j+offset); + atype = arg_expr->Type (); + if (! atype) { // for debugging purposes + INTERNAL_ERROR (arg_expr, "missing type of argument expression"); + removeCandidate (i-1); + break; + } + + // try to convert argument expression implicitly to parameter type + seq = implicitConversions (ptype, param_expr, atype, arg_expr); + + // no conversion applicable; not viable + if (! seq) { + removeCandidate (i-1); + break; + // implicit conversion sequence found + } else + ci->addConvSequence (seq); + } + } + + // turn on error reporting if it was enabled before + if (project) { + if (! was_silent) + project->err ().loud (); + project->err ().severity (old_severity); + } +} + + +// Check if tree is address of function expression and return the function name +CT_SimpleName* CCOverloading::isAddressOfFct (CTree* tree, bool address) const { + if (! tree) + return 0; + else if (tree->NodeName () == CT_BracedExpr::NodeId ()) + return isAddressOfFct (((CT_BracedExpr*)tree)->Expr (), address); + else if (tree->NodeName () == CT_AddrExpr::NodeId () && !address) + return isAddressOfFct (((CT_AddrExpr*)tree)->Expr (), true); + else if (tree->IsSimpleName () && address) + return tree->Type () && tree->Type ()->TypeFunction () ? (CT_SimpleName*)tree : 0; + return 0; +} + + +// Get the argument list of the function type parameter +CT_ArgDeclList* CCOverloading::getArgumentList (CTree* tree) const { + if (tree && tree->NodeName () == CT_ArgDecl::NodeId ()) { + tree = ((CT_ArgDecl*)tree)->Declarator (); + if (tree && tree->NodeName () == CT_FctDeclarator::NodeId ()) { + return ((CT_FctDeclarator*)tree)->Arguments (); + } + } + return 0; +} + + +// Try to convert the function argument to the function parameter type +CCConvSeq *CCOverloading::implicitConversions (CTypeInfo *ptype, CTree *param_expr, CTypeInfo *atype, CTree *arg_expr) { + CT_SimpleName* fctname = ptype->isPointer () && ptype->PtrToFct () ? isAddressOfFct (arg_expr) : 0; + if (! fctname) + return cvs.implicitConversions (ptype, atype, arg_expr, _Base, user_def); + + // argument is address of function; type of argument depends on parameter type + // and a matching function in current or qualified scope + + // get current scope + CStructure* scope = 0; + CTree* tree = arg_expr; + while (tree && (! tree->SemScope () || ! (scope = tree->SemScope ()->Scope ()))) + tree = tree->Parent (); + if (! scope && fctname->Name ()->Object () && fctname->Name ()->Object ()->Scope ()) + scope = fctname->Name ()->Object ()->Scope ()->Structure (); + if (! scope) + return 0; + + // lookup function name in current scope and above + CCNameLookup nl (err, scope); + nl.lookup (fctname, scope, true, true); + + // check each function found + CCConvSeq *last_seq = 0, *seq; + CFunctionInfo *info, *last_info = 0; + for (unsigned i = 0; i < nl.Objects (); i++) { + info = nl.Object (i)->FunctionInfo (); + + if (last_info && *info == *last_info) + continue; // same function + last_info = info; + + if (info && info->isTemplate ()) { + // instantiate function template + CT_ArgDeclList* args = getArgumentList (param_expr); + if (! args) + continue; + + CCInstantiation cci (err, false); + int entries = args->Entries (); + for (int j = 0; j < entries; j++) + cci.addArgument (args->Entry (j)); + + CObjectInfo* oinfo = cci.instantiate (fctname, info, true, 0, true); + info = oinfo ? oinfo->FunctionInfo () : 0; + } + + if (! info) + continue; + + if (info->isClassMember() && ! info->isStatic ()) { + // method + CTypeMemberPointer ptrToMembFct(info->TypeInfo (), info->Record ()); + seq = cvs.implicitConversions (ptype, &ptrToMembFct, arg_expr, _Base, user_def); + } else { + // function + CTypePointer ptrToFct(info->TypeInfo ()); + seq = cvs.implicitConversions (ptype, &ptrToFct, arg_expr, _Base, user_def); + } + + if (seq) { + if (last_seq) { + // ambiguous, can not resolve + delete seq; + last_seq = 0; + break; + } else { + last_seq = seq; + } + } + } + return last_seq; +} + + +// �13.3.3 best viable function +void CCOverloading::chooseBestViableFct () { + CCandidateInfo *challenger, *champion; + unsigned candidates; + + candidates = Candidates (); + if (candidates <= 1) + return; + + // �13.3.3.1 run a simple tournament + champion = Candidate (candidates-1); + for (unsigned i = candidates-1; i > 0; i--) { + challenger = Candidate (i-1); // current challenger candidate function + + // same candidate functions do not face each other + if (*challenger->Function () == *champion->Function ()) { + removeCandidate (i-1); + continue; + } + + // let champion face the challenger + switch (compareCandidates (champion, challenger)) { + // champion has won the round + case 1: + // elliminate challenger + removeCandidate (i-1); + break; + // challenger has won the round + case -1: + // elliminate old champion + removeCandidate (i); + // challenger is the new champion + champion = challenger; + break; + // challenger and champion are equal + default: + // case 0: overload resolution ambiguous up till now + champion = challenger; + break; + } + } + + // verify that the champion is better than all other remaining + // candidates (the champion did not yet faced) + for (unsigned i = Candidates (); i > 0; i--) { + challenger = Candidate (i-1); + if (challenger == champion) + continue; + + if (*challenger->Function () == *champion->Function () || + compareCandidates (champion, challenger) == 1) { + removeCandidate (i-1); + } + } +} + + +// �13.3.3.1 compare two viable functions F1 and F2 +// return 1 if F1 is a better candidate than F2 +// return 0 if F1 is neither better nor worse than F2 +// return -1 if F1 is a worse candidate than F2 +int CCOverloading::compareCandidates (CCandidateInfo *c1, CCandidateInfo *c2) const { + unsigned num_ics1, num_ics2, first_ics; + CFunctionInfo *f1, *f2; + bool c1_better, c2_better; + + c1_better = c2_better = false; + f1 = c1->Function (); + f2 = c2->Function (); + num_ics1 = c1->ConvSequences (); + num_ics2 = c2->ConvSequences (); + + // ??? compare member with non-member or constructor ??? + if (num_ics1 != num_ics2) { + INTERNAL_ERROR (Argument (0), "comparing member with non-member or constructor"); + return 0; + } + + // comparison with implicit object parameter of static member + // function always yields 0 so skip it + if (f1->isStaticMethod () || f2->isStaticMethod ()) + first_ics = 1; + else + first_ics = 0; + + // compare conversion sequences of the arguments + for (unsigned i = first_ics; i < num_ics1; i++) { + switch (cvs.compareConvSeq (c1->ConvSequence (i), c2->ConvSequence (i))) { + case 1: + c1_better = true; + break; + case -1: + // worse + c2_better = true; + break; + default: + // case 0: not worse + break; + } + } + if (c1_better && ! c2_better) + return 1; + if (! c1_better && c2_better) + return -1; + + // non-template functions are better than template functions + if (! f1->FctInstance () && f2->FctInstance ()) + return 1; + if (f1->FctInstance () && ! f2->FctInstance ()) + return -1; + + // a more specialized template function is better than a less + // specialized template function + if (f1->FctInstance () && f2->FctInstance ()) { + switch (moreSpecialized (f1, f2)) { + case 1: + // f1 more specialized + return 1; + case -1: + // f2 more specialized + return -1; + default: + // case 0: equal specialized + break; + } + } + + // context is initialization by user-defined conversion (�13.3.1.5) + // F1 is better than F2 if second standard conversion sequence of + // F1 is better than second standard conversion sequence of F2 + if (c1->SecondConvSeq ()) + return cvs.compareConvSeq (c1->SecondConvSeq (), c2->SecondConvSeq ()); + + return 0; +} + + +// create conversion for implicit function parameter +CCStandardConvSeq *CCOverloading::implicitThisConv (CTypeInfo *ptype, CFunctionInfo *cf) const { + CCStandardConvSeq *seq; + CTypeFunction *ft; + bool c, v; + + c = v = false; + ft = cf->TypeInfo (); + + if (! obj_type || (! obj_type->isConst () && ! obj_type->isVolatile ())) { + // add const and volatile qualification + if (ft->isConst () && ft->isVolatile ()) + v = c = true; + // add const qualification + else if (ft->isConst ()) + c = true; + // add volatile qualification + else if (ft->isVolatile ()) + v = true; + } else if (obj_type) { + if (obj_type->isConst () && obj_type->isVolatile ()) { + // identity conversion + } else if (obj_type->isConst ()) { + // add volatile qualification + if (ft->isVolatile ()) + v = true; + } else if (obj_type->isVolatile ()) { + // add const qualification + if (ft->isConst ()) + c = true; + } + } + + ptype = ptype->Duplicate (); + + if (obj_type && (obj_type->isConst () || obj_type->isVolatile ())) { + if (! ptype->TypeQualified ()) { + ptype = new CTypeQualified (ptype, false, false, false); + } + ptype->TypeQualified ()->isConst (obj_type->isConst ()); + ptype->TypeQualified ()->isVolatile (obj_type->isVolatile ()); + } + + seq = new CCStandardConvSeq; + seq->isReferenceBinding (true); + + if (c || v) { + if (! ptype->TypeQualified ()) { + ptype = new CTypeQualified (ptype, false, false, false); + } + if (c) + ptype->TypeQualified ()->isConst (true); + if (v) + ptype->TypeQualified ()->isVolatile (true); + seq->addConversion (new CCQualificationConv (ptype, obj_type)); + } else { + seq->addConversion (new CCIdentityConv (ptype, obj_type)); + } + + CTypeInfo::Destroy (ptype); + return seq; +} + + +bool CCOverloading::equalOrMoreQualified (CTypeFunction *t1, CTypeInfo *t2) const { + unsigned t1_qual, t2_qual; + t1_qual = (t1->isConst ()?2:0) + (t1->isVolatile ()?1:0); + t2_qual = (t2->isConst ()?2:0) + (t2->isVolatile ()?1:0); + if (t1_qual == t2_qual || t1_qual == 3 || t2_qual == 0) + return true; + return false; +} + + +CTree *CCOverloading::Argument (unsigned a) const { + if (_Arguments) + return ((CT_ExprList*)_Arguments)->Entry (a); + else switch (a) { + case 0: return _Arg0; + case 1: return _Arg1; + case 2: return _Arg2; + default: return (CTree*)0; + } +} + + +// collect conversion functions of cu (class or union) +// and its base classes that are visible in cu +void CCOverloading::collectConvFunctions (CRecord *cu) { + collectConvFunctions (cu, Candidates ()); +} + + +void CCOverloading::collectConvFunctions (CRecord *cu, unsigned first) { + CFunctionInfo *fct; + CClassInfo *cinfo; + bool hidden; + + // ensure this class is fully instantiated + if (cu->ClassInfo()) + cu->TypeInfo()->TypeClass()->instantiate(cu->Parent()->Structure()); + + for (unsigned i = 0; i < cu->Functions (); i++) { + fct = cu->Function (i); + + if (fct->isConversion ()) { + // apply name hiding rules + hidden = false; + for (unsigned j = Candidates (); j > first; j--) { + if (*Candidate (j-1)->Function ()->ConversionType () == + *fct->ConversionType ()) { + hidden = true; + break; + } + } + if (! hidden) + addCandidate (fct); + } + } + + // also consider base classes + cinfo = cu->ClassInfo (); + if (cinfo) + for (unsigned i = 0; i < cinfo->BaseClasses (); i++) + collectConvFunctions (cinfo->BaseClass (i)->Class (), first); +} + + +// collect converting constructors of cu (class or union) +void CCOverloading::collectConstructors (CRecord *cu, bool default_constr) { + CFunctionInfo *fct; + + // ensure this class is fully instantiated + if (cu->ClassInfo()) + cu->TypeInfo()->TypeClass()->instantiate(cu->Parent()->Structure()); + + cu = cu->DefObject ()->Record (); + for (unsigned i = 0; i < cu->Functions (); i++) { + fct = cu->Function (i); + // non-default non-explicit constructors are converting + // constructors (i.e. constructors with parameters) + if (fct->isConstructor () && ! fct->isExplicit () && + (default_constr || fct->Arguments () > 0)) + addCandidate (fct); + } +} + + +void CCOverloading::addCandidates (CCNameLookup &nl) { + CObjectInfo *info; + for (unsigned i = 0; i < nl.Objects (); i++) { + info = nl.Object (i); + if (! info->FunctionInfo ()) + continue; + addCandidate (info->FunctionInfo ()); + } +} + + +void CCOverloading::addCandidate (CFunctionInfo *fi) { + bool is_template = fi->isTemplate (); + for (unsigned i = Candidates (); i > 0; i--) { + CFunctionInfo* f = Candidate (i-1)->Function (); + if (f == fi) + return; + if (! is_template && *f == *fi) { + if (f->isFctDef () || ! fi->isFctDef ()) + return; + removeCandidate (i-1); + break; + } + } + _Candidates.append (new CCandidateInfo (fi)); +} + + +bool CCOverloading::hasDefaultArgument (CFunctionInfo *finfo, + CTypeList *params, unsigned num_params) const { + if (num_params <= Arguments ()) + return false; + + if (finfo) { + if (finfo->FctInstance ()) + // In case of a function template's instance, we have to check + // whether the function template has a default argument (and not + // the instance), because the default argument might have been + // hidden from the instance parser, because the initializer was + // a delayed parse tree. + return finfo->FctInstance()->TemplateInstance()->Template ()->ObjectInfo()->FunctionInfo ()->hasDefaultArgument (Arguments ()); + else + return (finfo->hasDefaultArgument (Arguments ())); + } + + // in case of surrogate call function + return params->ArgumentList () && + ((CT_ArgDecl*)params->ArgumentList ()-> + Entry (Arguments ()))->Initializer (); +} + + +void CCOverloading::ObjectType (CTypeInfo *t) { + obj_type = t; + while (obj_type && obj_type->TypeAddress ()) + obj_type = obj_type->BaseType (); +} + + +int CCOverloading::moreSpecialized (CFunctionInfo *f1, CFunctionInfo *f2) const { + CTemplateInstance *inst1 = f1->TemplateInstance (); + CTemplateInstance *inst2 = f2->TemplateInstance (); + f1 = inst1->Template ()->ObjectInfo ()->FunctionInfo (); + f2 = inst2->Template ()->ObjectInfo ()->FunctionInfo (); + + InstantiationCandidate cand1; + cand1.initialize (inst1->PointOfInstantiation (), f1, inst1->Template ()); + unsigned numargs = Arguments () > f2->Arguments () ? f2->Arguments () : Arguments (); + unsigned offset = f2->isMethod () && ! f1->isMethod () ? 1 : 0; + for (unsigned i = offset; i < numargs; i++) + cand1.addArgument (f2->Argument (i)->Tree ()); + + InstantiationCandidate cand2; + cand2.initialize (inst2->PointOfInstantiation (), f2, inst2->Template ()); + numargs = Arguments () > f1->Arguments () ? f1->Arguments () : Arguments (); + offset = f1->isMethod () && ! f2->isMethod () ? 1 : 0; + for (unsigned i = offset; i < numargs; i++) + cand2.addArgument (f1->Argument (i)->Tree ()); + + // perform argument deduction against the other function + bool f1_at_least_as_specialized = cand2.deduceArgumentsFromFctCall (0, false, true); + bool f2_at_least_as_specialized = cand1.deduceArgumentsFromFctCall (0, false, true); + + // equal specialized + if (f1_at_least_as_specialized && f2_at_least_as_specialized) + return 0; + // f2 more specialized + if (f2_at_least_as_specialized) + return -1; + // f1 more specialized + if (f1_at_least_as_specialized) + return 1; + // equal specialized + return 0; +} + + +//////////////////////////////////////////////////////////// +// �13.6 built-in operators //////////////////////////////// +//////////////////////////////////////////////////////////// + + +// create built-in operators used as candidates for operator overloading +void CCOverloading::createBuiltinOperators (CSemDatabase *db, + const char *opname, int oper, CTree *arg0, CTree *arg1) { + unsigned len0, len1; + CTypeInfo *t0, *t1; + CRecord *record; + + // do not create operators if not in operator overloading mode + if (! operator_ovl) + return; + + // �13.3.1.2.3 for the operators ',', '->', and unary '&' the set is empty + if (oper == TOK_COMMA || oper == TOK_PTS || + (oper == TOK_AND && ! arg1)) + return; + + // for all other operators, the built-in candidates include all of + // the candidate operator functions defined in �13.6 that, compared + // to the given operator, + // - have the same operator name, and + // - accept the same number of operands, and + // - accept operand types to which the given operand or operands + // can be converted according to �13.3.3.1 (implicit conversion + // sequences), and + // - do not have the same parameter type list as any non-template + // non-member candidate + + t0 = arg0 ? arg0->Type () : 0; + t1 = arg1 ? arg1->Type () : 0; + t0 = t0 ? t0->UnqualType () : t0; + t1 = t1 ? t1->UnqualType () : t1; + if (! t0) + return; + + // �13.6 set of built-in operator candidate funtions + + // operator ||, operator &&, operator ! + // (these operators are always the same) + if (oper == TOK_OR_OR || oper == TOK_AND_AND || oper == TOK_NOT) + createLogOp (db, oper, opname, t0, t1); + else { + // collect the types for the operands of the operators to be created + Array types0; types0.append (t0); + Array types1; types1.append (t1); + + // collect the types the first operand type can be converted to + if (t0->isRecord ()) { + record = t0->VirtualType ()->TypeRecord ()->Record (); + collectConvTypes (record, types0); + } + // collect the types the second operand type can be converted to + if (t1 && t1->isRecord ()) { + record = t1->VirtualType ()->TypeRecord ()->Record (); + collectConvTypes (record, types1); + } + + len0 = types0.length (); + len1 = types1.length (); + for (unsigned i = 0; i < len0; i++) { + t0 = types0[i]; + if (t0->TypeAddress ()) { + t0 = t0->BaseType (); + } + + for (unsigned j = 0; j < len1; j++) { + t1 = types1[j]; + if (t1 && t1->TypeAddress ()) { + t1 = t1->BaseType (); + } + + // operator ++ + if (oper == TOK_INCR) + createIncrOp (db, oper, opname, t0, t1); + // operator -- + else if (oper == TOK_DECR) + createDecrOp (db, oper, opname, t0, t1); + // operator * + else if (oper == TOK_MUL) + createMulOp (db, oper, opname, t0, t1); + // operator + + else if (oper == TOK_PLUS) + createPlusOp (db, oper, opname, t0, t1); + // operator - + else if (oper == TOK_MINUS) + createMinusOp (db, oper, opname, t0, t1); + // operator ~ + else if (oper == TOK_TILDE) + createTildeOp (db, oper, opname, t0, t1); + // operator ->* + else if (oper == TOK_PTS_STAR) + createMembPtrOp (db, oper, opname, t0, t1); + // operator [] + else if (oper == TOK_OPEN_SQUARE) // first token of [] + createIndexOp (db, oper, opname, t0, t1); + // operator ? + else if (oper == TOK_QUESTION) // cannot be overloaded! see �13.6.24 + createIfThenOp (db, oper, opname, t0, t1); + // operator <, operator >, operator <=, operator >= + else if (oper == TOK_LESS || oper == TOK_GREATER || + oper == TOK_LEQ || oper == TOK_GEQ) + createRelOp (db, oper, opname, t0, t1); + // operator %, operator &, operator ^, operator |, operator <<, operator >> + else if (oper == TOK_MODULO || oper == TOK_AND || oper == TOK_ROOF || + oper == TOK_OR || oper == TOK_LSH || oper == TOK_RSH) + createBinOp (db, oper, opname, t0, t1); + // operator %=, operator &=, operator ^=, operator |=, operator <<=, operator >>= + else if (oper == TOK_MOD_EQ || oper == TOK_AND_EQ || oper == TOK_XOR_EQ || + oper == TOK_IOR_EQ || oper == TOK_LSH_EQ || oper == TOK_RSH_EQ) + createEqAssOp (db, oper, opname, t0, t1); + // operator = + else if (oper == TOK_ASSIGN) + createAssOp (db, oper, opname, t0, t1); + // operator / + else if (oper == TOK_DIV) + createDivOp (db, oper, opname, t0, t1); + // operator ==, operator != + else if (oper == TOK_EQL || oper == TOK_NEQ) + createEqOp (db, oper, opname, t0, t1); + // operator *=, operator /= + else if (oper == TOK_MUL_EQ || oper == TOK_DIV_EQ) + createMulAssOp (db, oper, opname, t0, t1); + // operator +=, operator -= + else if (oper == TOK_ADD_EQ || oper == TOK_SUB_EQ) + createAddAssOp (db, oper, opname, t0, t1); + } + } + } +} + + +// operator ++ +void CCOverloading::createIncrOp (CSemDatabase *db, int oper, + const char *opname, CTypeInfo *t0, CTypeInfo *t1) { + CTypeInfo *t; + + if (t1) // unary operators do not have two operands + return; + + if (t0->isConst ()) + return; + + // 3. For every pair (T, VQ), where T is an arithmetic type, and VQ is either + // volatile or empty, there exist candidate operator functions of the form + // VQ T& operator++(VQ T&); + // T operator++(VQ T&, int); + if (t0->isArithmetic ()) { + t = new CTypeAddress (t0->Duplicate ()); + createOperator (db, oper, opname, t->Duplicate (), t->Duplicate ()); + createOperator (db, oper, opname, t0->UnqualType ()->Duplicate (), + t, &CTYPE_INT); + } + + // 5. For every pair (T, VQ), where T is a cv-qualified or cv-unqualified + // object type, and VQ is either volatile or empty, there exist candidate + // operator functions of the form + // T*VQ& operator++(T*VQ&); + // T* operator++(T*VQ&, int); + if (t0->isObject () && t0->isPointer ()) { + t = t0->UnqualType ()->Duplicate (); + if (t0->isVolatile ()) + t = new CTypeQualified (t, false, true, false); + t = new CTypeAddress (t); + t0 = t0->UnqualType ()->Duplicate (); + createOperator (db, oper, opname, t->Duplicate (), t->Duplicate ()); + createOperator (db, oper, opname, t0, t, &CTYPE_INT); + } +} + + +// operator -- +void CCOverloading::createDecrOp (CSemDatabase *db, int oper, + const char *opname, CTypeInfo *t0, CTypeInfo *t1) { + CTypeInfo *t; + + if (t1) // unary operators do not have two operands + return; + + if (t0->isConst ()) + return; + + // 4. For every pair (T, VQ), where T is an arithmetic type other than bool, + // and VQ is either volatile or empty, there exist candidate operator + // functions of the form + // VQ T& operator--(VQ T&); + // T operator--(VQ T&, int); + if (t0->isArithmetic () && ! t0->UnqualType ()->is_bool ()) { + t = new CTypeAddress (t0->Duplicate ()); + createOperator (db, oper, opname, t->Duplicate (), t->Duplicate ()); + createOperator (db, oper, opname, t0->UnqualType ()->Duplicate (), + t, &CTYPE_INT); + } + + // 5. For every pair (T, VQ), where T is a cv-qualified or cv-unqualified + // object type, and VQ is either volatile or empty, there exist candidate + // operator functions of the form + // T*VQ& operator--(T*VQ&); + // T* operator--(T*VQ&, int); + if (t0->isObject () && t0->isPointer ()) { + t = t0->UnqualType ()->Duplicate (); + if (t0->isVolatile ()) + t = new CTypeQualified (t, false, true, false); + t = new CTypeAddress (t); + t0 = t0->UnqualType ()->Duplicate (); + createOperator (db, oper, opname, t->Duplicate (), t->Duplicate ()); + createOperator (db, oper, opname, t0, t, &CTYPE_INT); + } +} + + +// operator * +void CCOverloading::createMulOp (CSemDatabase *db, int oper, + const char *opname, CTypeInfo *t0, CTypeInfo *t1) { + CTypeInfo *t; + + // 6. For every cv-qualified or cv-unqualified object type T, there exist + // candidate operator functions of the form + // T& operator*(T*); + // 7. For every function type T, there exist candidate operator functions + // of the form + // T& operator*(T*); + if (! t1 && t0->isPointer ()) { + t = new CTypeAddress (t0->PtrBaseType ()->Duplicate ()); + createOperator (db, oper, opname, t, t0->Duplicate ()); + } + + // 12. For every pair of promoted arithmetic types L and R, there exist + // candidate operator functions of the form (where LR is the result of the + // usual arithmetic conversions between types L and R) + // LR operator*(L, R); + if (t1 && t0->isArithmetic () && t1->isArithmetic ()) { + t0 = cvs.arithmeticPromotion (t0); + t1 = cvs.arithmeticPromotion (t1); + t = cvs.usualArithmeticConv (t0, t1); + createOperator (db, oper, opname, t->Duplicate (), t0->Duplicate (), t1->Duplicate ()); + } +} + + +// operator + +void CCOverloading::createPlusOp (CSemDatabase *db, int oper, + const char *opname, CTypeInfo *t0, CTypeInfo *t1) { + CTypeInfo *t = 0; + + // 8. For every type T, there exist candidate operator functions of the form + // T* operator+(T*); + if (! t1 && t0->isPointer ()) { + createOperator (db, oper, opname, t0->Duplicate (), t0->Duplicate ()); + } + + // 13. For every cv-qualified or cv-unqualified object type T there exist + // candidate operator functions of the form + // T* operator+(T*, ptrdiff_t); + // T* operator+(ptrdiff_t, T*); + if (t1 && t0->isObject () && t0->isPointer ()) { + t = CTypeInfo::CTYPE_PTRDIFF_T; // ptrdiff_t + createOperator (db, oper, opname, t0->Duplicate (), t0->Duplicate (), t); + createOperator (db, oper, opname, t0->Duplicate (), t, t0->Duplicate ()); + } + + // 9. For every promoted arithmetic type T, there exist candidate operator + // functions of the form + // T operator+(T); + if (! t1 && t0->isArithmetic ()) { + t0 = cvs.arithmeticPromotion (t0); + createOperator (db, oper, opname, t0->Duplicate (), t0->Duplicate ()); + } + + // 12. For every pair of promoted arithmetic types L and R, there exist + // candidate operator functions of the form (where LR is the result of the + // usual arithmetic conversions between types L and R) + // LR operator+(L, R); + if (t1 && t0->isArithmetic () && t1->isArithmetic ()) { + t0 = cvs.arithmeticPromotion (t0); + t1 = cvs.arithmeticPromotion (t1); + t = cvs.usualArithmeticConv (t0, t1); + createOperator (db, oper, opname, t->Duplicate (), t0->Duplicate (), t1->Duplicate ()); + } +} + + +// operator - +void CCOverloading::createMinusOp (CSemDatabase *db, int oper, + const char *opname, CTypeInfo *t0, CTypeInfo *t1) { + CTypeInfo *t = 0; + + // 13. For every cv-qualified or cv-unqualified object type T there exist + // candidate operator functions of the form + // T* operator-(T*, ptrdiff_t); + if (t1 && t0->isObject () && t0->isPointer ()) { + t = CTypeInfo::CTYPE_PTRDIFF_T; // ptrdiff_t + createOperator (db, oper, opname, t0->Duplicate (), t0->Duplicate (), t); + } + + // 14. For every T, where T is a pointer to object type, there exist candidate + // operator functions of the form + // ptrdiff_t operator-(T, T); + if (t1 && t0->isPointer () && t0->PtrBaseType ()->isObject ()) { + t = CTypeInfo::CTYPE_PTRDIFF_T; // ptrdiff_t + createOperator (db, oper, opname, t, t0->Duplicate (), t0->Duplicate ()); + } + if (t1 && t1->isPointer () && t1->PtrBaseType ()->isObject ()) { + t = CTypeInfo::CTYPE_PTRDIFF_T; // ptrdiff_t + createOperator (db, oper, opname, t, t1->Duplicate (), t1->Duplicate ()); + } + + // 9. For every promoted arithmetic type T, there exist candidate operator + // functions of the form + // T operator-(T); + if (! t1 && t0->isArithmetic ()) { + t0 = cvs.arithmeticPromotion (t0); + createOperator (db, oper, opname, t0->Duplicate (), t0->Duplicate ()); + } + + // 12. For every pair of promoted arithmetic types L and R, there exist + // candidate operator functions of the form (where LR is the result of the + // usual arithmetic conversions between types L and R) + // LR operator-(L, R); + if (t1 && t0->isArithmetic () && t1->isArithmetic ()) { + t0 = cvs.arithmeticPromotion (t0); + t1 = cvs.arithmeticPromotion (t1); + t = cvs.usualArithmeticConv (t0, t1); + createOperator (db, oper, opname, t->Duplicate (), t0->Duplicate (), t1->Duplicate ()); + } +} + + +// operator ~ +void CCOverloading::createTildeOp (CSemDatabase *db, int oper, + const char *opname, CTypeInfo *t0, CTypeInfo *t1) { + if (t1) // unary operators do not have two operands + return; + + // 10. For every promoted integral type T, there exist candidate operator + // functions of the form + // T operator~(T); + if (t0->isInteger ()) { + t0 = cvs.integralPromotion (t0); + createOperator (db, oper, opname, t0->Duplicate (), t0->Duplicate ()); + } +} + + +// operator ->* +void CCOverloading::createMembPtrOp (CSemDatabase *db, int oper, + const char *opname, CTypeInfo *t0, CTypeInfo *t1) { + CTypeInfo *t; + CRecord *c0, *c1; + + if (! t1) // binary operators must have two operands + return; + + // 11. For every quintuple (C1, C2, T, CV1, CV2), where C2 is a class type, + // C1 is the same type as C2 or is a derived class of C2, T is an object + // type or a function type, and CV1 and CV2 are cv-qualifier-seqs, there + // exist candidate operator functions of the form (where CV12 is the union + // of CV1 and CV2) + // CV12 T& operator->*(CV1 C1*, CV2 T C2::*); + if (t1->TypeMemberPointer () && t0->isPointer () && t0->PtrBaseType ()->isRecord ()) { + c1 = t1->TypeMemberPointer ()->Record (); + c0 = t0->PtrBaseType ()->VirtualType ()->TypeRecord ()->Record (); + if (CCSemExpr::sameOrBaseClass (c1, c0)) { + t = t1->VirtualType ()->BaseType ()->Duplicate (); + if (t0->PtrBaseType ()->isQualified ()) { + if (t->isQualified ()) { + if (t0->PtrBaseType ()->isConst ()) + t->TypeQualified ()->isConst (true); + if (t0->PtrBaseType ()->isVolatile ()) + t->TypeQualified ()->isVolatile (true); + } else { + t = new CTypeQualified (t, t0->PtrBaseType ()->isConst (), + t0->PtrBaseType ()->isVolatile (), false); + } + } + t = new CTypeAddress (t); + createOperator (db, oper, opname, t, t0->Duplicate (), t1->Duplicate ()); + } + } +} + + +// operator [] +void CCOverloading::createIndexOp (CSemDatabase *db, int oper, + const char *opname, CTypeInfo *t0, CTypeInfo *t1) { + CTypeInfo *rt, *pt, *t; + + if (! t1) // binary operators must have two operands + return; + + // 13. For every cv-qualified or cv-unqualified object type T there exist + // candidate operator functions of the form + // T& operator[](T*, ptrdiff_t); + // T& operator[](ptrdiff_t, T*); + if (t0->isObject () && t0->isPointer ()) { + rt = new CTypeAddress (t0->PtrBaseType ()->Duplicate ()); + pt = t0->Duplicate (); + t = CTypeInfo::CTYPE_PTRDIFF_T; // ptrdiff_t + createOperator (db, oper, opname, rt->Duplicate (), pt->Duplicate (), t); + createOperator (db, oper, opname, rt, t, pt); + } +} + + +// operator ? +void CCOverloading::createIfThenOp (CSemDatabase *db, int oper, + const char *opname, CTypeInfo *t0, CTypeInfo *t1) { + CTypeInfo *t; + + if (! t1) // binary operators must have two operands + return; + + // 25. For every type T, where T is a pointer or pointer-to-member type, there exist + // candidate operator functions of the form + // T operator?(bool, T, T); // first operand skipped!!! + if (t0->isMemberPointer () || t0->isPointer ()) { + createOperator (db, oper, opname, t0->Duplicate (), t0->Duplicate (), t0->Duplicate ()); + } + if (t1->isMemberPointer () || t1->isPointer ()) { + createOperator (db, oper, opname, t1->Duplicate (), t1->Duplicate (), t1->Duplicate ()); + } + + // 24. For every pair of promoted arithmetic types L and R, there exist candidate + // operator functions of the form (where LR is the result of the usual arithmetic + // conversions between types L and R) + // LR operator?(bool, L, R); // first operand skipped!!! + if (t0->isArithmetic () && t1->isArithmetic ()) { + t0 = cvs.arithmeticPromotion (t0); + t1 = cvs.arithmeticPromotion (t1); + t = cvs.usualArithmeticConv (t0, t1); + createOperator (db, oper, opname, t->Duplicate (), t0->Duplicate (), t1->Duplicate ()); + } +} + + +// operator ||, operator &&, operator ! +void CCOverloading::createLogOp (CSemDatabase *db, int oper, + const char *opname, CTypeInfo *t0, CTypeInfo *t1) { + // 23. There also exist candidate operator functions of the form + // bool operator!(bool); + // bool operator&&(bool, bool); + // bool operator||(bool, bool); + if (! t1) { + createOperator (db, oper, opname, &CTYPE_BOOL, &CTYPE_BOOL); + } else { + createOperator (db, oper, opname, &CTYPE_BOOL, &CTYPE_BOOL, &CTYPE_BOOL); + } +} + + +// operator <, operator >, operator <=, operator >= +void CCOverloading::createRelOp (CSemDatabase *db, int oper, + const char *opname, CTypeInfo *t0, CTypeInfo *t1) { + if (! t1) // binary operators must have two operands + return; + + // 15. For every pointer or enumeration type T, there exist candidate operator + // functions of the form + // bool operator<(T, T); + // bool operator>(T, T); + // bool operator<=(T, T); + // bool operator>=(T, T); + if (t0->isPointer () || t0->isEnum ()) { + createOperator (db, oper, opname, &CTYPE_BOOL, t0->Duplicate (), t0->Duplicate ()); + } + if (t1->isPointer () || t1->isEnum ()) { + createOperator (db, oper, opname, &CTYPE_BOOL, t1->Duplicate (), t1->Duplicate ()); + } + + // 12. For every pair of promoted arithmetic types L and R, there exist + // candidate operator functions of the form (where LR is the result of the + // usual arithmetic conversions between types L and R) + // bool operator<(L, R); + // bool operator>(L, R); + // bool operator<=(L, R); + // bool operator>=(L, R); + if (t0->isArithmetic () && t1->isArithmetic ()) { + t0 = cvs.arithmeticPromotion (t0); + t1 = cvs.arithmeticPromotion (t1); + createOperator (db, oper, opname, &CTYPE_BOOL, t0->Duplicate (), t1->Duplicate ()); + } +} + + +// operator %, operator &, operator ^, operator |, operator <<, operator >> +void CCOverloading::createBinOp (CSemDatabase *db, int oper, + const char *opname, CTypeInfo *t0, CTypeInfo *t1) { + CTypeInfo *t; + + if (! t1) // binary operators must have two operands + return; + + // 17. For every pair of promoted integral types L and R, there exist candidate + // operator functions of the form (where LR is the result of the usual arithmetic + // conversions between types L and R) + // LR operator%(L, R); + // LR operator&(L, R); + // LR operator^(L, R); + // LR operator|(L, R); + // L operator<<(L, R); + // L operator>>(L, R); + if (t0->isInteger () && t1->isInteger ()) { + t0 = cvs.integralPromotion (t0); + t1 = cvs.integralPromotion (t1); + if (*(opname+9) == '<' || *(opname+9) == '>') { + createOperator (db, oper, opname, t0->Duplicate (), t0->Duplicate (), t1->Duplicate ()); + } else { + t = cvs.usualArithmeticConv (t0, t1); + createOperator (db, oper, opname, t->Duplicate (), t0->Duplicate (), t1->Duplicate ()); + } + } +} + + +// operator %=, operator &=, operator ^=, operator |=, operator <<=, operator >>= +void CCOverloading::createEqAssOp (CSemDatabase *db, int oper, + const char *opname, CTypeInfo *t0, CTypeInfo *t1) { + if (! t1) // binary operators must have two operands + return; + + // 22. For every triple (L, VQ, R), where L is an integral type, VQ is either + // volatile or empty, and R is a promoted integral type, there exist candidate + // operator functions of the form + // VQ L& operator%=(VQ L&, R); + // VQ L& operator<<=(VQ L&, R); + // VQ L& operator>>=(VQ L&, R); + // VQ L& operator&=(VQ L&, R); + // VQ L& operator^=(VQ L&, R); + // VQ L& operator|=(VQ L&, R); + if (t0->isInteger () && t1->isInteger () && ! t0->isConst ()) { + t1 = cvs.integralPromotion (t1); + t0 = new CTypeAddress (t0->Duplicate ()); + createOperator (db, oper, opname, t0, t0->Duplicate (), t1->Duplicate ()); + } +} + + +// operator = +void CCOverloading::createAssOp (CSemDatabase *db, int oper, + const char *opname, CTypeInfo *t0, CTypeInfo *t1) { + CTypeInfo *t; + + if (! t1) // binary operators must have two operands + return; + + if (t0->isConst ()) + return; + + // 19. For every pair (T, VQ), where T is any type and VQ is either volatile or + // empty, there exist candidate operator functions of the form + // T*VQ& operator=(T*VQ&, T*); + if (t0->isPointer ()) { + t = t0->UnqualType ()->Duplicate (); + if (t0->isVolatile ()) + t = new CTypeQualified (t, false, true, false); + t = new CTypeAddress (t); + createOperator (db, oper, opname, t, t->Duplicate (), t0->UnqualType ()->Duplicate ()); + } + + // 20. For every pair (T, VQ), where T is an enumeration or pointer to member type + // and VQ is either volatile or empty, there exist candidate operator functions + // of the form + // VQ T& operator=(VQ T&, T); + if (t0->isMemberPointer () || t0->isEnum ()) { + t = new CTypeAddress (t0->Duplicate ()); + createOperator (db, oper, opname, t, t->Duplicate (), t0->UnqualType ()->Duplicate ()); + } + + // 18. For every triple (L, VQ, R), where L is an arithmetic type, VQ is either + // volatile or empty, and R is a promoted arithmetic type, there exist candidate + // operator functions of the form + // VQ L& operator=(VQ L&, R); + if (t0->isArithmetic () && t1->isArithmetic ()) { + t = new CTypeAddress (t0->Duplicate ()); + t1 = cvs.arithmeticPromotion (t1); + createOperator (db, oper, opname, t, t->Duplicate (), t1->Duplicate ()); + } +} + + +// operator / +void CCOverloading::createDivOp (CSemDatabase *db, int oper, + const char *opname, CTypeInfo *t0, CTypeInfo *t1) { + CTypeInfo *t; + + if (! t1) // binary operators must have two operands + return; + + // 12. For every pair of promoted arithmetic types L and R, there exist + // candidate operator functions of the form (where LR is the result of the + // usual arithmetic conversions between types L and R) + // LR operator/(L, R); + if (t0->isArithmetic () && t1->isArithmetic ()) { + t0 = cvs.arithmeticPromotion (t0); + t1 = cvs.arithmeticPromotion (t1); + t = cvs.usualArithmeticConv (t0, t1); + createOperator (db, oper, opname, t->Duplicate (), t0->Duplicate (), t1->Duplicate ()); + } +} + + +// operator ==, operator != +void CCOverloading::createEqOp (CSemDatabase *db, int oper, + const char *opname, CTypeInfo *t0, CTypeInfo *t1) { + if (! t1) // binary operators must have two operands + return; + + // 15. For every pointer or enumeration type T, there exist candidate operator + // functions of the form + // bool operator==(T, T); + // bool operator!=(T, T); + // 16. For every pointer to member type T, there exist candidate operator + // functions of the form + // bool operator==(T, T); + // bool operator!=(T, T); + if (t0->isMemberPointer () || t0->isPointer () || t0->isEnum ()) { + createOperator (db, oper, opname, &CTYPE_BOOL, t0->Duplicate (), t0->Duplicate ()); + } + if (t1->isMemberPointer () || t1->isPointer () || t1->isEnum ()) { + createOperator (db, oper, opname, &CTYPE_BOOL, t1->Duplicate (), t1->Duplicate ()); + } + + // 12. For every pair of promoted arithmetic types L and R, there exist + // candidate operator functions of the form (where LR is the result of the + // usual arithmetic conversions between types L and R) + // bool operator==(L, R); + // bool operator!=(L, R); + if (t0->isArithmetic () && t1->isArithmetic ()) { + t0 = cvs.arithmeticPromotion (t0); + t1 = cvs.arithmeticPromotion (t1); + createOperator (db, oper, opname, &CTYPE_BOOL, t0->Duplicate (), t1->Duplicate ()); + } +} + + +// operator *=, operator /= +void CCOverloading::createMulAssOp (CSemDatabase *db, int oper, + const char *opname, CTypeInfo *t0, CTypeInfo *t1) { + CTypeInfo *t; + + if (! t1) // binary operators must have two operands + return; + + // 18. For every triple (L, VQ, R), where L is an arithmetic type, VQ is either + // volatile or empty, and R is a promoted arithmetic type, there exist candidate + // operator functions of the form + // VQ L& operator*=(VQ L&, R); + // VQ L& operator/=(VQ L&, R); + if (! t0->isConst () && t0->isArithmetic () && t1->isArithmetic ()) { + t = new CTypeAddress (t0->Duplicate ()); + t1 = cvs.arithmeticPromotion (t1); + createOperator (db, oper, opname, t, t->Duplicate (), t1->Duplicate ()); + } +} + + +// operator +=, operator -= +void CCOverloading::createAddAssOp (CSemDatabase *db, int oper, + const char *opname, CTypeInfo *t0, CTypeInfo *t1) { + CTypeInfo *t; + + if (! t1) // binary operators must have two operands + return; + + if (t0->isConst ()) + return; + + // 21. For every pair (T, VQ), where T is a cv-qualified or cv-unqualified object + // type and VQ is either volatile or empty, there exist candidate operator functions + // of the form + // T*VQ& operator+=(T*VQ&, ptrdiff_t); + // T*VQ& operator-=(T*VQ&, ptrdiff_t); + if (t0->isObject () && t0->isPointer ()) { + t = t0->UnqualType ()->Duplicate (); + if (t0->isVolatile ()) + t = new CTypeQualified (t, false, true, false); + t = new CTypeAddress (t); /* ptrdiff_t */ + createOperator (db, oper, opname, t, t->Duplicate (), CTypeInfo::CTYPE_PTRDIFF_T); + } + + // 18. For every triple (L, VQ, R), where L is an arithmetic type, VQ is either + // volatile or empty, and R is a promoted arithmetic type, there exist candidate + // operator functions of the form + // VQ L& operator+=(VQ L&, R); + // VQ L& operator-=(VQ L&, R); + if (t0->isArithmetic () && t1->isArithmetic ()) { + t = new CTypeAddress (t0->Duplicate ()); + t1 = cvs.arithmeticPromotion (t1); + createOperator (db, oper, opname, t, t->Duplicate (), t1->Duplicate ()); + } +} + + +void CCOverloading::createOperator (CSemDatabase *db, int oper, + const char *name, CTypeInfo *rtype, CTypeInfo *t0, CTypeInfo *t1) { + CTypeList *args; + CFunctionInfo *info; + + // add operator function to candidate set only if there is no + // other non-template non-member candidate with the same parameter + // type list + + for (unsigned i = Candidates (); i > 0; i--) { + info = Candidate (i-1)->Function (); + args = info->TypeInfo ()->ArgTypes (); + + // same number of arguments + if (args->Entries () == (unsigned)((t0?1:0) + (t1?1:0))) + // non-template non-member function + if (! info->isTemplateInstance () && ! info->isMethod ()) + // same name/operator + if (info->Name () && strcmp (info->Name (), name) == 0) + // same parameter type list + if ((t0 ? *t0 == *args->Entry (0) : true) && + (t1 ? *t1 == *args->Entry (1) : true)) { + if (t0) CTypeInfo::Destroy (t0); + if (t1) CTypeInfo::Destroy (t1); + if (rtype) CTypeInfo::Destroy (rtype); + return; // operator already exists + } + } + + // get the built-in operator object from the class the and add it as a + // candidate + addCandidate (db->BuiltinOperator (name, oper, rtype, t0, t1)); +} + + +void CCOverloading::collectConvTypes (CRecord *cu, Array &types) { + CFunctionInfo *fct; + CClassInfo *cinfo; + bool skip; + + // ensure this class is fully instantiated + if (cu->ClassInfo()) + cu->TypeInfo()->TypeClass()->instantiate(cu->Parent()->Structure()); + + for (unsigned i = 0; i < cu->Functions (); i++) { + fct = cu->Function (i); + + if (fct->isConversion ()) { + // don't add the same type twice + skip = false; + for (unsigned j = types.length (); j > 0; j--) { + if (*types[j-1] == *fct->ConversionType ()) { + skip = true; + break; + } + } + if (! skip) + types.append (fct->ConversionType ()); + } + } + + // also consider base classes + cinfo = cu->ClassInfo (); + if (cinfo) + for (unsigned i = 0; i < cinfo->BaseClasses (); i++) + collectConvTypes (cinfo->BaseClass (i)->Class (), types); +} + + +} // namespace Puma diff --git a/Puma/src/parser/ccparser/CCOverloading.h b/Puma/src/parser/ccparser/CCOverloading.h new file mode 100644 index 0000000..7abd216 --- /dev/null +++ b/Puma/src/parser/ccparser/CCOverloading.h @@ -0,0 +1,179 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CCOverloading_h__ +#define __CCOverloading_h__ + +#include "Puma/Array.h" +#include "Puma/ErrorSink.h" +#include "Puma/CCConversions.h" +#include "Puma/CCandidateInfo.h" + +namespace Puma { + + +class CTree; +class CRecord; +class CTypeList; +class CFunctionInfo; +class CCNameLookup; +class CTypeFunction; +class CSemDatabase; +class CT_SimpleName; +class CT_ArgDeclList; + +class CCOverloading { + Array _Candidates; + CTree *_Arguments; // ordinary function argument list + CTree *_Arg0; // operator arguments + CTree *_Arg1; + CTree *_Arg2; + CTree *_Base; + CTree *_Poi; + unsigned _NumArgs; + + ErrorSink &err; + bool user_def; // user-defined conversions allowed + bool operator_ovl; // operator overloading + bool dependent; // dependent call + + CCConversions cvs; // implicit conversions + + CTypeInfo *obj_type; + +public: + // usage: (error stream, is_operator_overloading) + inline CCOverloading (ErrorSink &, bool = false); + + // destructor: delete all CCandidateInfos + inline ~CCOverloading (); + + // set qualifiers + void ObjectType (CTypeInfo *); + void PointOfInst (CTree *); + + // usage: resolve(argument(s), allow_user_defined_conversions) + void resolve (CTree *, bool = true); + void resolve (CTree *, CTree *, bool = true); + void resolve (CTree *, CTree *, CTree *, bool = true); + void resolveMember (CTree *, CTree *); + + // the resulting function to call + CFunctionInfo *Function () const; + bool isAmbiguous () const; + bool isDependent () const; + + unsigned Candidates () const; + CCandidateInfo *Candidate (unsigned) const; + void addCandidate (CFunctionInfo *); + void removeCandidate (unsigned); + + void collectConvFunctions (CRecord *); + void collectConstructors (CRecord *, bool default_constr = false); + void addCandidates (CCNameLookup &); + + // create built-in operators used as candidates for + // operator overloading, operator overloading mode + // must be enabled (else nothing is done) + void createBuiltinOperators (CSemDatabase *db, const char *, + int, CTree *, CTree *); + + unsigned Arguments () const; + CTree *Argument (unsigned) const; + +private: // built-in operators + void createIncrOp (CSemDatabase *, int, const char *, CTypeInfo *, CTypeInfo *); + void createDecrOp (CSemDatabase *, int, const char *, CTypeInfo *, CTypeInfo *); + void createMulOp (CSemDatabase *, int, const char *, CTypeInfo *, CTypeInfo *); + void createPlusOp (CSemDatabase *, int, const char *, CTypeInfo *, CTypeInfo *); + void createMinusOp (CSemDatabase *, int, const char *, CTypeInfo *, CTypeInfo *); + void createTildeOp (CSemDatabase *, int, const char *, CTypeInfo *, CTypeInfo *); + void createMembPtrOp (CSemDatabase *, int, const char *, CTypeInfo *, CTypeInfo *); + void createIndexOp (CSemDatabase *, int, const char *, CTypeInfo *, CTypeInfo *); + void createIfThenOp (CSemDatabase *, int, const char *, CTypeInfo *, CTypeInfo *); + void createLogOp (CSemDatabase *, int, const char *, CTypeInfo *, CTypeInfo *); + void createRelOp (CSemDatabase *, int, const char *, CTypeInfo *, CTypeInfo *); + void createBinOp (CSemDatabase *, int, const char *, CTypeInfo *, CTypeInfo *); + void createEqAssOp (CSemDatabase *, int, const char *, CTypeInfo *, CTypeInfo *); + void createAssOp (CSemDatabase *, int, const char *, CTypeInfo *, CTypeInfo *); + void createDivOp (CSemDatabase *, int, const char *, CTypeInfo *, CTypeInfo *); + void createEqOp (CSemDatabase *, int, const char *, CTypeInfo *, CTypeInfo *); + void createMulAssOp (CSemDatabase *, int, const char *, CTypeInfo *, CTypeInfo *); + void createAddAssOp (CSemDatabase *, int, const char *, CTypeInfo *, CTypeInfo *); + +private: + void chooseViableFcts (); + void chooseBestViableFct (); + int compareCandidates (CCandidateInfo *, CCandidateInfo *) const; + + int moreSpecialized (CFunctionInfo *, CFunctionInfo *) const; + bool equalOrMoreQualified (CTypeFunction *, CTypeInfo *) const; + bool hasDefaultArgument (CFunctionInfo *, CTypeList *, unsigned) const; + void collectConvFunctions (CRecord *, unsigned); + void collectConvTypes (CRecord *, Array &); + CCStandardConvSeq *implicitThisConv (CTypeInfo *, CFunctionInfo *) const; + CCConvSeq *implicitConversions (CTypeInfo *, CTree *, CTypeInfo *, CTree *); + CT_SimpleName* isAddressOfFct (CTree *, bool = false) const; + CT_ArgDeclList* getArgumentList (CTree* tree) const; + + void createOperator (CSemDatabase *, int, const char *, CTypeInfo *, CTypeInfo *, CTypeInfo * = 0); +}; + +inline CCOverloading::CCOverloading (ErrorSink &e, bool oovl) : + _Arguments (0), + _Arg0 (0), + _Arg1 (0), + _Arg2 (0), + _Poi (0), + _NumArgs (0), + err (e), + user_def (true), + operator_ovl (oovl), + dependent (false), + cvs (e), + obj_type (0) + {} + +inline CCOverloading::~CCOverloading () { + for (int c = (int)Candidates () - 1; c >= 0; c--) + removeCandidate ((unsigned)c); +} + +inline CFunctionInfo *CCOverloading::Function () const + { return Candidates () ? Candidate (0)->Function () : (CFunctionInfo*)0; } +inline unsigned CCOverloading::Arguments () const + { return _NumArgs; } + +inline bool CCOverloading::isAmbiguous () const + { return (Candidates () > 1); } +inline bool CCOverloading::isDependent () const + { return dependent; } + +inline unsigned CCOverloading::Candidates () const + { return (unsigned)_Candidates.length (); } +inline CCandidateInfo *CCOverloading::Candidate (unsigned c) const + { return _Candidates.lookup (c); } +inline void CCOverloading::removeCandidate (unsigned c) { + delete _Candidates.lookup (c); + _Candidates.remove (c); +} + + +} // namespace Puma + +#endif /* __CCOverloading_h__ */ diff --git a/Puma/src/parser/ccparser/CCParser.h b/Puma/src/parser/ccparser/CCParser.h new file mode 100644 index 0000000..e2fba93 --- /dev/null +++ b/Puma/src/parser/ccparser/CCParser.h @@ -0,0 +1,66 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CCParser__ +#define __CCParser__ + +#include "Puma/Parser.h" +#include "Puma/CCSyntax.h" +#include "Puma/CCBuilder.h" +#include "Puma/CCSemantic.h" + +namespace Puma { + + +class CCParser : public Parser { + CCSyntax _syntax; + CCBuilder _builder; + CCSemantic _semantic; + + unsigned _options; + +public: + + // public parser options + enum { SKIP_FCT_BODY = 0x01 }; + + // parser functions + CCParser () : Parser (_syntax, _builder, _semantic), + _syntax (_builder, _semantic), + _semantic (_syntax, _builder), + _options (0) {} + + // parse a unit of a project + CTranslationUnit *parse (Unit &u, CProject &p, int m = 0, std::ostream& os = std::cout) { + syntax ().config_skip_fct_body (_options & SKIP_FCT_BODY); + return Parser::parse (u, p, m, os); + } + + // set and get parser options + unsigned Options () const { return _options; } + void Options (unsigned o) { _options = o; } + + CCSyntax &syntax () const { return (CCSyntax&)_syntax; } + CCBuilder &builder () const { return (CCBuilder&)_builder; } + CCSemantic &semantic () const { return (CCSemantic&)_semantic; } +}; + + +} // namespace Puma + +#endif /* __CCParser__ */ diff --git a/Puma/src/parser/ccparser/CCSemBinding.ah b/Puma/src/parser/ccparser/CCSemBinding.ah new file mode 100644 index 0000000..41ff1fc --- /dev/null +++ b/Puma/src/parser/ccparser/CCSemBinding.ah @@ -0,0 +1,328 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CCSemBinding_ah__ +#define __CCSemBinding_ah__ + +#include "Puma/CCSemantic.h" + +// This aspect controls the parsing process on the C++ code level +// by maintaining semantic information. + +aspect CCSemBinding { + + advice execution("% Puma::CCSyntax::ClassName::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().class_name(); + } + + advice execution("% Puma::CCSyntax::EnumName::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().enum_name(); + } + + advice execution("% Puma::CCSyntax::TemplateName::build(...)") || + execution("% Puma::CCSyntax::ClassTemplateName::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().template_name(); + } + + advice execution("% Puma::CCSyntax::OriginalNsName::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().original_ns_name(); + } + + advice execution("% Puma::CCSyntax::NamespaceAlias::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().namespace_alias(); + } + + advice execution("% Puma::CCSyntax::ColonColon::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().colon_colon(); + } + + advice execution("% Puma::CCSyntax::NestedNameSpec::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().nested_name_spec(); + } + + advice execution("% Puma::CCSyntax::NestedNameSpec::parse(...)") : around () { + tjp->arg<0>()->semantic().enter_nested_name(); + tjp->proceed(); + tjp->arg<0>()->semantic().leave_nested_name(); + } + + advice execution("% Puma::CCSyntax::NestedNameSpec1::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().nested_name_spec1(); + } + + advice call("% Puma::CCSyntax::PostfixExpr2::check(...)") && + within("% Puma::CCSyntax::PostfixExpr::parse(...)") : after () { + if (*tjp->result ()) { + tjp->arg<0>()->semantic ().enter_postfix_expr (); + tjp->arg<0>()->semantic ().postfix_expr (); + } + } + + advice call("% Puma::CCSyntax::PostfixExpr1::check(...)") && + within("% Puma::CCSyntax::PostfixExpr::parse(...)") : after () { + if (*tjp->result ()) + tjp->arg<0>()->semantic ().postfix_expr (); + } + + advice execution("% Puma::CCSyntax::PostfixExpr::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().valid_id_expr (); + tjp->arg<0>()->semantic ().leave_postfix_expr (); + } + + advice execution("% Puma::CCSyntax::PostfixExpr1::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().postfix_expr1(); + } + + advice execution("% Puma::CCSyntax::PostfixExpr1::parse(...)") : around () { + Puma::CCSemantic::MemberAccessOperator mao = Puma::CCSemantic::MAO_NONE; + if (tjp->arg<0>()->look_ahead (Puma::TOK_DOT)) + mao = Puma::CCSemantic::MAO_DOT; + else if (tjp->arg<0>()->look_ahead (Puma::TOK_PTS)) + mao = Puma::CCSemantic::MAO_PTS; + if (mao) + tjp->arg<0>()->semantic ().enter_member_access (mao); + tjp->proceed(); + if (mao) + tjp->arg<0>()->semantic ().leave_member_access (); + } + + advice execution("% Puma::CCSyntax::PostfixExpr2::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().postfix_expr2(); + } + + advice execution("% Puma::CCSyntax::PseudoDtorName::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().pseudo_dtor_name(); + } + + advice execution("% Puma::CCSyntax::NewTypeId::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().introduce_named_type (); + } + + advice execution("% Puma::CCSyntax::NewTypeId::parse(...)") : after () { + tjp->arg<0>()->semantic().finish_declarator (); + } + + advice execution("% Puma::CCSyntax::NewDeclarator::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().abst_declarator(); + } + + advice execution("% Puma::CCSyntax::DirectNewDeclarator::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().direct_new_declarator(); + } + + advice execution("% Puma::CCSyntax::AssExpr::parse(...)") || + execution("% Puma::CCSyntax::ConstExpr::parse(...)"): around () { + tjp->arg<0>()->semantic().enter_expr(); + tjp->proceed(); + tjp->arg<0>()->semantic().leave_expr(); + } + + advice execution("% Puma::CCSyntax::ConstExpr::build(...)"): around () { + *tjp->result() = tjp->arg<0>()->semantic().const_expr(); + } + + advice execution("% Puma::CCSyntax::Condition1::parse(...)") : after () { + tjp->arg<0>()->semantic().finish_declarator (); + } + + advice execution("% Puma::CCSyntax::Condition1::build(...)"): around () { + *tjp->result() = tjp->arg<0>()->semantic().condition(); + } + + advice execution("% Puma::CCSyntax::SimpleDecl::build(...)"): after () { + if (*tjp->result ()) + tjp->arg<0>()->semantic().obj_decl (*tjp->result()); + } + + advice execution("% Puma::CCSyntax::DeclSpecSeq1::build(...)"): around () { + *tjp->result() = tjp->arg<0>()->semantic().decl_spec_seq1(); + } + + advice execution("% Puma::CCSyntax::SimpleTypeSpec::parse(...)") : after () { + tjp->arg<0>()->semantic().reset_search_scope (true); + } + + advice execution("% Puma::CCSyntax::SimpleTypeSpec::build(...)"): around () { + *tjp->result() = tjp->arg<0>()->semantic().simple_type_spec (); + } + + advice execution("% Puma::CCSyntax::ElaboratedTypeSpec::parse(...)") : after () { + tjp->arg<0>()->semantic().reset_search_scope (); + } + + advice execution("% Puma::CCSyntax::ElaboratedTypeSpec::build(...)"): around () { + *tjp->result() = tjp->arg<0>()->semantic().introduce_tag (); + } + + advice execution("% Puma::CCSyntax::EnumeratorDef::build(...)"): around () { + *tjp->result() = tjp->arg<0>()->semantic().enumerator_def (); + } + + advice call("% Puma::CCSyntax::Decl::check(...)") && + within("% Puma::CCSyntax::LinkageSpec::parse(...)") : around () { + ((Puma::CCSyntax*)tjp->arg<0>())->semantic ().enter_extern_decl (false); + tjp->proceed (); + ((Puma::CCSyntax*)tjp->arg<0>())->semantic ().leave_extern_decl (); + } + + advice call("% Puma::CSyntax::DeclSeq::check(...)") && + within("% Puma::CCSyntax::LinkageSpec::parse(...)") : around () { + ((Puma::CCSyntax*)tjp->arg<0>())->semantic ().enter_extern_decl (true); + tjp->proceed (); + ((Puma::CCSyntax*)tjp->arg<0>())->semantic ().leave_extern_decl (); + } + + advice execution("% Puma::CCSyntax::OriginalNsDef::build(...)") || + execution("% Puma::CCSyntax::ExtensionNsDef::build(...)") || + execution("% Puma::CCSyntax::UnnamedNsDef::build(...)"): around () { + *tjp->result() = tjp->arg<0>()->semantic().namespace_def (); + } + + advice (within("% Puma::CCSyntax::OriginalNsDef::parse(...)") || + within("% Puma::CCSyntax::ExtensionNsDef::parse(...)") || + within("% Puma::CCSyntax::UnnamedNsDef::parse(...)")) && + call("% Puma::CCSyntax::NamespaceBody::check(...)"): before () { + Puma::CCSyntax *s = (Puma::CCSyntax*)tjp->arg<0>(); + s->semantic().enter_scope (((Puma::CT_NamespaceDef*)(s->builder ().get_node()))->Object ()->Structure ()); + } + + advice execution("% Puma::CCSyntax::OriginalNsDef1::build(...)"): around () { + *tjp->result() = tjp->arg<0>()->semantic().introduce_orig_ns (); + } + + advice execution("% Puma::CCSyntax::ExtensionNsDef1::build(...)"): around () { + *tjp->result() = tjp->arg<0>()->semantic().introduce_ns_extension (); + } + + advice execution("% Puma::CCSyntax::UnnamedNsDef1::build(...)"): around () { + *tjp->result() = tjp->arg<0>()->semantic().introduce_unnamed_ns (); + } + + advice execution("% Puma::CCSyntax::NsAliasDef::build(...)"): around () { + *tjp->result() = tjp->arg<0>()->semantic().introduce_ns_alias (); + } + + advice execution("% Puma::CCSyntax::QualNsSpec::parse(...)") : after () { + tjp->arg<0>()->semantic().reset_search_scope (); + } + + advice execution("% Puma::CCSyntax::UsingDecl::parse(...)") : after () { + tjp->arg<0>()->semantic().reset_search_scope (); + } + + advice execution("% Puma::CCSyntax::UsingDecl::build(...)"): around () { + *tjp->result() = tjp->arg<0>()->semantic().using_decl (); + } + + advice execution("% Puma::CCSyntax::UsingDirective::parse(...)") : after () { + tjp->arg<0>()->semantic().reset_search_scope (); + } + + advice execution("% Puma::CCSyntax::UsingDirective::build(...)"): around () { + *tjp->result() = tjp->arg<0>()->semantic().using_directive (); + } + + advice execution("% Puma::CCSyntax::InitDeclarator::parse(...)") : after () { + // leave possibly entered class scope + if (!*tjp->result ()) + tjp->arg<0>()->semantic().finish_init_declarator (); + } + + advice execution("% Puma::CCSyntax::InitDeclarator::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().init_declarator (); + tjp->arg<0>()->semantic().finish_init_declarator (); + } + + advice execution("% Puma::CCSyntax::ArrayDelim::parse(...)") : around () { + Puma::CStructure *scope = tjp->arg<0>()->semantic ().array_delim (); + tjp->proceed(); + tjp->arg<0>()->semantic ().array_delim (scope); + } + + advice execution("% Puma::CCSyntax::PtrOperator::parse(...)") : after () { + tjp->arg<0>()->semantic().reset_search_scope (); + } + + advice execution("% Puma::CCSyntax::DeclaratorId::parse(...)") : around () { + tjp->arg<0>()->semantic ().enter_entity_name (); + tjp->proceed(); + tjp->arg<0>()->semantic ().reset_search_scope (); + tjp->arg<0>()->semantic ().leave_entity_name (); + } + + advice within("% Puma::CCSyntax::DeclaratorId::parse(...)") && + call("% Puma::CCSyntax::TypeName::check(...)") : after () { + tjp->arg<0>()->semantic().declarator_id (*tjp->result()); + } + + advice execution("% Puma::CCSyntax::DirectAbstDeclarator::build(...)"): around () { + *tjp->result() = tjp->arg<0>()->semantic().direct_abst_declarator (); + } + + advice execution("% Puma::CCSyntax::ParamDeclClause::parse(...)") : around () { + tjp->arg<0>()->semantic().enter_param_decl_clause (); + tjp->proceed (); + tjp->arg<0>()->semantic().leave_param_decl_clause (); + } + + advice execution("% Puma::CCSyntax::ParamDeclClause::build(...)"): around () { + *tjp->result() = tjp->arg<0>()->semantic().param_decl_clause (); + } + + advice execution("% Puma::CCSyntax::ClassHead::build(...)"): around () { + *tjp->result() = tjp->arg<0>()->semantic().add_base_classes (); + } + + // TODO: base_clause is old style! + advice call("% Puma::CCSyntax::base_clause()") && + within("% Puma::CCSyntax::ClassHead::parse(...)"): before () { + tjp->target()->semantic().reenter_class_scope (); + } + + advice execution("% Puma::CCSyntax::ClassHead1::build(...)"): around () { + *tjp->result() = tjp->arg<0>()->semantic().introduce_class (); + } + + advice execution("% Puma::CCSyntax::ConvFctId::parse(...)") : around () { + typename JoinPoint::template Arg<0>::ReferredType::SearchScope sc; + tjp->arg<0>()->get_search_scope (sc); + tjp->arg<0>()->semantic ().reset_search_scope (); + Puma::CStructure *scope = tjp->arg<0>()->semantic ().conv_fct_id (); + tjp->proceed(); + tjp->arg<0>()->semantic ().conv_fct_id (scope); + tjp->arg<0>()->set_search_scope (sc); + } + + advice call("% Puma::CSyntax::type_spec_seq()") && + within("% Puma::CCSyntax::ConvTypeId::parse(...)") : around () { + ((Puma::CCSyntax*)tjp->target())->semantic ().enter_conv_type_id (); + tjp->proceed (); + ((Puma::CCSyntax*)tjp->target())->semantic ().leave_conv_type_id (); + } + + advice call("% Puma::CCSyntax::conv_declarator()") && + within("% Puma::CCSyntax::ConvTypeId::parse(...)") : after () { + tjp->target()->semantic ().finish_declarator (); + } + + advice execution("% Puma::CCSyntax::ConvTypeId::build(...)"): around () { + *tjp->result() = tjp->arg<0>()->semantic().introduce_named_type (); + } +}; + +#endif /* __CCSemBinding_ah__ */ diff --git a/Puma/src/parser/ccparser/CCSemDeclarator.h b/Puma/src/parser/ccparser/CCSemDeclarator.h new file mode 100644 index 0000000..2d7d1e6 --- /dev/null +++ b/Puma/src/parser/ccparser/CCSemDeclarator.h @@ -0,0 +1,36 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CCSemDeclarator_h__ +#define __CCSemDeclarator_h__ + +#include "Puma/CSemDeclarator.h" + +namespace Puma { + + +class CCSemDeclarator : public CSemDeclarator { +public: + CCSemDeclarator (ErrorSink *err, CTypeInfo *t, CTree *d) : + CSemDeclarator (err, t, d, /*lang_c=false*/false) {} +}; + + +} // namespace Puma + +#endif /* __CCSemDeclarator_h__ */ diff --git a/Puma/src/parser/ccparser/CCSemExpr.cc b/Puma/src/parser/ccparser/CCSemExpr.cc new file mode 100644 index 0000000..6e3b7fe --- /dev/null +++ b/Puma/src/parser/ccparser/CCSemExpr.cc @@ -0,0 +1,3825 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CTree.h" +#include "Puma/CSemDatabase.h" +#include "Puma/CFileInfo.h" +#include "Puma/CCSemExpr.h" +#include "Puma/CStructure.h" +#include "Puma/CTypeInfo.h" +#include "Puma/CCNameLookup.h" +#include "Puma/CCOverloading.h" +#include "Puma/CCAssocScopes.h" +#include "Puma/CConstant.h" +#include "Puma/CFunctionInfo.h" +#include "Puma/CClassInfo.h" +#include "Puma/CUnionInfo.h" +#include "Puma/CLocalScope.h" +#include "Puma/CArgumentInfo.h" +#include "Puma/CEnumeratorInfo.h" +#include "Puma/CTemplateInfo.h" +#include "Puma/CNamespaceInfo.h" +#include "Puma/CTemplateParamInfo.h" +#include "Puma/CTemplateInstance.h" +#include "Puma/CWStrLiteral.h" +#include "Puma/CStrLiteral.h" +#include "Puma/CCConversions.h" +#include "Puma/Utf8.h" + +// this include shall be removed as soon as ac++ can better deal with +// the include cycle problem +#include "Puma/CCSemVisitor.h" + +#include +#include +#include "Puma/WChar.h" /* wcslen() */ +#include /* isdigit(), isxdigit() */ +#include /* sprintf() */ +#include +#include /* strtod() */ +#include + + +namespace Puma { + + +// print semantic error messages + +#define SEM_MSG(node__,mesg__) \ + {if (node__->token ()) err << node__->token ()->location (); err << mesg__ << endMessage;} + +#define SEM_ERROR(node__, mesg__) \ + SEM_MSG (node__, sev_error << mesg__) + +#define SEM_WARNING(node__, mesg__) \ + SEM_MSG (node__, sev_warning << mesg__) + +#define SEM_WARNING__out_of_range(node__,what__) \ + SEM_WARNING (node__, what__ << " out of range") + +#define SEM_WARNING__is_unsigned(node__) \ + SEM_WARNING (node__, \ + "decimal constant is so large that it is unsigned") + +#define SEM_ERROR__invalid_op(node__,type__,op__) \ + SEM_ERROR (node__, "invalid operand to " << type__ << " `" << op__ << "'") + +#define SEM_ERROR__left_op(node__,op__,what__) \ + SEM_ERROR (node__, "left operand of `" << op__ << "' " << what__) + +#define SEM_ERROR__right_op(node__,op__,what__) \ + SEM_ERROR (node__, "right operand of `" << op__ << "' " << what__) + +#define SEM_ERROR__comp_between(node__,what__) \ + SEM_ERROR (node__, "comparison between " << what__) + +#define SEM_ERROR__undeclared(name__) \ + SEM_ERROR (name__, "`" << *name__ << "' undeclared here") + +#define SEM_ERROR__must_include(node__,file__,what__) \ + SEM_ERROR (node__, "must #include " << file__ << " before using " << what__) + + +/////////////////////////////////////////////////////// +// basic operations on expressions //////////////////// +/////////////////////////////////////////////////////// + + +bool CCSemExpr::isRvalue (CTree *expr) { + // §3.10 any expression is either an lvalue or an rvalue, + // so everything that is not an lvalue is an rvalue + return (! isLvalue (expr)); +} + + +bool CCSemExpr::isLvalue (CTree *expr) { + CObjectInfo *info; + CTypeInfo *type; + const char *id; + int oper; + + if (! expr || ! expr->Type ()) + return false; + + type = expr->Type (); + id = expr->NodeName (); + + if (type->isVoid ()) + return false; + if (type->isAddress () || type->isTemplateParam ()) + return true; + if (id == CT_String::NodeId () || + id == CT_WideString::NodeId () || + id == CT_CmpdLiteral::NodeId () || + id == CT_IndexExpr::NodeId () || + id == CT_TypeidExpr::NodeId () || + id == CT_DerefExpr::NodeId ()) + return true; + if (id == CT_Integer::NodeId () || + id == CT_Character::NodeId () || + id == CT_WideCharacter::NodeId () || + id == CT_Float::NodeId () || + id == CT_Bool::NodeId ()) + return false; + if (id == CT_CallExpr::NodeId () && type->isAddress ()) + return true; + if (id == CT_MembRefExpr::NodeId () || id == CT_MembPtrExpr::NodeId ()) { + info = ((CT_SimpleName*)expr->Son (2))->Name ()->Object (); + if (info) { + if (info->EnumeratorInfo ()) + return false; + if (info->AttributeInfo ()) { + //if (info->isStatic ()) + return true; + //return isLvalue (expr->Son (0)); + } + if (info->FunctionInfo () && info->isStatic ()) + return true; + } + return false; + } + if (id == CT_UnaryExpr::NodeId ()) { + oper = expr->Son (0)->token ()->type (); + if (oper == TOK_INCR || oper == TOK_DECR) + return true; + return false; + } + if (id == CT_BinaryExpr::NodeId ()) { + oper = expr->Son (1)->token ()->type (); + if (oper == TOK_DOT_STAR || oper == TOK_PTS_STAR) { + type = expr->Son (2)->Type (); + if (! type->isFunction ()) { + if (oper == TOK_DOT_STAR && ! isLvalue (expr->Son (0))) + return false; + return true; + } + } + if (oper == TOK_ASSIGN || oper == TOK_MUL_EQ || oper == TOK_DIV_EQ || + oper == TOK_MOD_EQ || oper == TOK_ADD_EQ || oper == TOK_SUB_EQ || + oper == TOK_RSH_EQ || oper == TOK_LSH_EQ || oper == TOK_AND_EQ || + oper == TOK_XOR_EQ || oper == TOK_IOR_EQ) + return true; + if (oper == TOK_COMMA) + return isLvalue (expr->Son (2)); + return false; + } + if (id == CT_SimpleName::NodeId ()) { + info = ((CT_SimpleName*)expr)->Name ()->Object (); + if (info) + return (type->isFunction () || info->ArgumentInfo () || + (info->AttributeInfo () && ! info->EnumeratorInfo ())); + return false; + } + if (id == CT_BracedExpr::NodeId ()) + return isLvalue (expr->Son (1)); + if (id == CT_IfThenExpr::NodeId ()) + return (isLvalue (expr->Son (2)) && isLvalue (expr->Son (4))); + if (id == CT_QualName::NodeId () || id == CT_RootQualName::NodeId ()) + return isLvalue (((CT_QualName*)expr)->Name ()); + if (id == CT_CastExpr::NodeId ()) + return isLvalue (expr->Son (3)); + if (id == CT_ImplicitCast::NodeId ()) + return isLvalue (expr->Son (0)); + return false; +} + + +CTypeInfo *CCSemExpr::castToType (CTypeInfo *type, CTree *node, bool ref) { + CSemValue *cast = 0; + CExprValue *value; + + // cast implicitly if types differ + if (*node->Type () != *type) { + if (node->Parent ()) { + CTree* base = node->Parent (); + CT_ImplicitCast *cast_node = new CT_ImplicitCast (node); + base->ReplaceSon (node, cast_node); + cast = cast_node; + } else if (node->SemValue ()) { + cast = node->SemValue (); + } + + if (cast) { + if (ref) + cast->setTypeRef (type); // refer to a shared type + else + cast->setType (type); // type is new (to be deleted by this node) + + // cast constant value if any + value = node->Value (); + if (value) { + if (value->Constant ()) { + value = value->Constant ()->cast_to (type); + cast->setValue (value); + } else + cast->setValueRef (value); + } + } + } + return type; +} + + +bool CCSemExpr::isModifiable (CTypeInfo *type, unsigned long pos) { + // error checks not yet implemented! + // too simple yet! + if (type->isFunction ()) + return false; + return true; +} + + +void CCSemExpr::passOnConstant (CTree *node, CTypeInfo *t1) const { + CTypeInfo *t2; + CConstant *value; + CTree* base; + + t2 = node->Type (); + base = node->Parent (); + value = node->Value () ? node->Value ()->Constant () : 0; + if (value && base && base->SemValue ()) { + if (t1 && t2 && *t1 != *t2) { + value = value->cast_to (t1); + base->SemValue ()->setValue (value); + } else + base->SemValue ()->setValueRef (value); + } +} + + +CTree *CCSemExpr::baseTree (CTree *node) const { + while (true) { + if (node->NodeName () == CT_BracedExpr::NodeId ()) + node = node->Son (1); + else if (node->NodeName () == CT_ImplicitCast::NodeId ()) + node = node->Son (0); + else + break; + } + return node; +} + + +bool CCSemExpr::isAddrExpr (CTree *node) { + if (node->NodeName () == CT_AddrExpr::NodeId ()) + return true; + else if (node->NodeName () == CT_BracedExpr::NodeId ()) + return isAddrExpr (((CT_BracedExpr*)node)->Expr ()); + else if (node->NodeName () == CT_ImplicitCast::NodeId ()) + return isAddrExpr (((CT_ImplicitCast*)node)->Expr ()); + return false; +} + + +CObjectInfo *CCSemExpr::findObject (CTree *node) { + const char *id = node->NodeName (); + if (id == CT_BracedExpr::NodeId () || + id == CT_DerefExpr::NodeId () || + id == CT_AddrExpr::NodeId () || + id == CT_UnaryExpr::NodeId ()) { + return findObject (node->Son (1)); + } else if (id == CT_ImplicitCast::NodeId () || + id == CT_PostfixExpr::NodeId () || + id == CT_IndexExpr::NodeId ()) { + return findObject (node->Son (0)); + } else if (id == CT_CastExpr::NodeId ()) { + return findObject (node->Son (3)); + } else if (id == CT_BinaryExpr::NodeId ()) { + int oper = node->Son (1)->token ()->type (); + if (oper == TOK_COMMA) + return findObject (node->Son (2)); + if (oper == TOK_ASSIGN || oper == TOK_MUL_EQ || oper == TOK_DIV_EQ || + oper == TOK_MOD_EQ || oper == TOK_ADD_EQ || oper == TOK_SUB_EQ || + oper == TOK_RSH_EQ || oper == TOK_LSH_EQ || oper == TOK_AND_EQ || + oper == TOK_XOR_EQ || oper == TOK_IOR_EQ) + return findObject (node->Son (0)); + } else if (id == CT_QualName::NodeId () || + id == CT_RootQualName::NodeId ()) { + return findObject (((CT_QualName*)node)->Name ()); + } else if (id == CT_SimpleName::NodeId () || + id == CT_OperatorName::NodeId () || + id == CT_DestructorName::NodeId () || + id == CT_ConversionName::NodeId () || + id == CT_TemplateName::NodeId () || + id == CT_PrivateName::NodeId ()) { + return ((CT_SimpleName*)node)->Name ()->Object (); + } else if (id == CT_MembPtrExpr::NodeId () || + id == CT_MembRefExpr::NodeId ()) { + return ((CT_MembPtrExpr*)node)->Object (); + } else if (id == CT_CallExpr::NodeId ()) { + return ((CT_CallExpr*)node)->Object (); + } else if (id == CT_NewExpr::NodeId ()) { + return ((CT_NewExpr*)node)->Object (); + } else if (id == CT_ConstructExpr::NodeId ()) { + return ((CT_ConstructExpr*)node)->Object (); + } else if (id == CT_StaticCast::NodeId () || + id == CT_ConstCast::NodeId () || + id == CT_DynamicCast::NodeId () || + id == CT_ReintCast::NodeId ()) { + return findObject (((CT_StaticCast*)node)->Expr ()); + } + return (CObjectInfo*)0; +} + + +/////////////////////////////////////////////////////// +// implicit conversions /////////////////////////////// +/////////////////////////////////////////////////////// + + +// ���5.9 usual arithmetic conversions +CTypeInfo *CCSemExpr::usualArithmeticConv (CTree *op1, CTree *op2) { + CTypeInfo *t1, *t2; + + t1 = op1->Type (); + t2 = op2->Type (); + if (! t1 || ! t2) + return t1; + + CTree* oldp1 = op1->Parent (); + CTree* oldp2 = op2->Parent (); + + if (t1->is_long_double () && ! t2->is_long_double ()) + t2 = castToType (&CTYPE_LONG_DOUBLE, op2, true); + else if (t2->is_long_double () && ! t1->is_long_double ()) + t1 = castToType (&CTYPE_LONG_DOUBLE, op1, true); + else if (t1->is_double () && ! t2->is_double ()) + t2 = castToType (&CTYPE_DOUBLE, op2, true); + else if (t2->is_double () && ! t1->is_double ()) + t1 = castToType (&CTYPE_DOUBLE, op1, true); + else if (t1->is_float () && ! t2->is_float ()) + t2 = castToType (&CTYPE_FLOAT, op2, true); + else if (t2->is_float () && ! t1->is_float ()) + t1 = castToType (&CTYPE_FLOAT, op1, true); + else { // integral promotion of both operands + t1 = intPromotion (op1); + t2 = intPromotion (op2); + } + + if (oldp1 != op1->Parent ()) + op1 = op1->Parent (); + if (oldp2 != op2->Parent ()) + op2 = op2->Parent (); + + if (t1->is_unsigned_int128 () && ! t2->is_unsigned_int128 ()) + t2 = castToType (&CTYPE_UNSIGNED_INT128, op2, true); + else if (t2->is_unsigned_int128 () && ! t1->is_unsigned_int128 ()) + t1 = castToType (&CTYPE_UNSIGNED_INT128, op1, true); + else if (t1->is_int128 () && ! t2->is_int128 ()) + t2 = castToType (&CTYPE_INT128, op2, true); + else if (t2->is_int128 () && ! t1->is_int128 ()) + t1 = castToType (&CTYPE_INT128, op1, true); + else if (t1->is_unsigned_long_long () && ! t2->is_unsigned_long_long ()) + t2 = castToType (&CTYPE_UNSIGNED_LONG_LONG, op2, true); + else if (t2->is_unsigned_long_long () && ! t1->is_unsigned_long_long ()) + t1 = castToType (&CTYPE_UNSIGNED_LONG_LONG, op1, true); + else if (t1->is_long_long () && ! t2->is_long_long ()) + t2 = castToType (&CTYPE_LONG_LONG, op2, true); + else if (t2->is_long_long () && ! t1->is_long_long ()) + t1 = castToType (&CTYPE_LONG_LONG, op1, true); + else if (t1->is_unsigned_long () && ! t2->is_unsigned_long ()) + t2 = castToType (&CTYPE_UNSIGNED_LONG, op2, true); + else if (t2->is_unsigned_long () && ! t1->is_unsigned_long ()) + t1 = castToType (&CTYPE_UNSIGNED_LONG, op1, true); + else if ((t1->is_long () && t2->is_unsigned_int ()) || + (t2->is_long () && t1->is_unsigned_int ())) { + t1 = castToType (&CTYPE_UNSIGNED_LONG, op1, true); + t2 = castToType (&CTYPE_UNSIGNED_LONG, op2, true); + } + else if (t1->is_long () && ! t2->is_long ()) + t2 = castToType (&CTYPE_LONG, op2, true); + else if (t2->is_long () && ! t1->is_long ()) + t1 = castToType (&CTYPE_LONG, op1, true); + else if (t1->is_unsigned_int () && ! t2->is_unsigned_int ()) + t2 = castToType (&CTYPE_UNSIGNED_INT, op2, true); + else if (t2->is_unsigned_int () && ! t1->is_unsigned_int ()) + t1 = castToType (&CTYPE_UNSIGNED_INT, op1, true); + + return t1; +} + + +// ���4.5 integral promotion +CTypeInfo *CCSemExpr::intPromotion (CTree *expr) { + CTypeInfo *result = expr->Type (); + if (! result) + return result; + + while (result->TypeAddress ()) + result = result->BaseType (); + + if (result->is_char () || result->is_short () || + result->is_signed_char () || result->is_unsigned_char () || + result->is_unsigned_short () || result->is_wchar_t () || + result->is_bool ()) { + result = castToType (&CTYPE_INT, expr, true); + } else if (result->isEnum ()) { + result = castToType (result->VirtualType ()->TypeEnum ()->UnderlyingType (), expr, true); + } else if (result->TypeBitField ()) { + if (result->BaseType ()->isEnum () || + (result->BaseType ()->isInteger () && + (*result->BaseType () < CTYPE_INT))) + result = castToType (&CTYPE_INT, expr, true); + } + + return result; +} + + +// ���4.1, ���4.2, ���4.3 lvalue to rvalue conversions +CTypeInfo *CCSemExpr::convLvalueToRvalue (CTree *expr, CTree *dest) { + CTypeInfo *result/*, *target*/; + bool is_lvalue; + + result = expr->Type (); + is_lvalue = isLvalue (expr); + + // ���4.1 lvalue-to-rvalue conversion + if (is_lvalue && ! result->isFunction () && ! result->isArray ()) { + CTypeInfo *qt = result; + while (qt->isAddress ()) + qt = qt->BaseType (); + if (! qt->isRecord () && qt->isQualified ()) + result = castToType (qt->UnqualType (), expr, true); + // ���4.2 array-to-pointer conversion + } else if (result->isArray ()) { + result = result->VirtualType ()->BaseType (); + result = new CTypePointer (result->Duplicate ()); + castToType (result, expr, false); + // ���4.3 function-to-pointer conversion + } else if (is_lvalue && result->isFunction ()) { + CFunctionInfo* fct = result->VirtualType ()->TypeFunction ()->FunctionInfo (); + if (fct && fct->isMethod () && ! fct->isStaticMethod ()) { + result = new CTypeMemberPointer (result->Duplicate (), fct->Record ()); + } else { + result = new CTypePointer (result->Duplicate ()); + } + castToType (result, expr, false); + } + + return result; +} + + +/////////////////////////////////////////////////////// +// expression evaluation ////////////////////////////// +/////////////////////////////////////////////////////// + + +CTypeInfo *CCSemExpr::resolveExpr (CTree *node, CTree *base) { + CTypeInfo *result; + + // resolve expression + result = resolve (node, base); + + return result; +} + + +CTypeInfo *CCSemExpr::resolve (CTree *node, CTree *base) { + const char *id = node->NodeName (); + CTypeInfo *result = 0, *type; + + // do not analyse an expression twice + type = node->Type (); + if (type && ! type->is_undefined ()) { + if (type->isDependent ()) + dependent = true; + if (dependent || ! (id == CT_ConstructExpr::NodeId ())) + return type; + } + + if (! (id == CT_BracedExpr::NodeId () || + id == CT_AddrExpr::NodeId () || + id == CT_MembPtrExpr::NodeId () || + id == CT_MembRefExpr::NodeId () || + id == CT_SimpleName::NodeId () || + id == CT_OperatorName::NodeId () || + id == CT_DestructorName::NodeId () || + id == CT_ConversionName::NodeId () || + id == CT_TemplateName::NodeId () || + id == CT_QualName::NodeId () || + id == CT_RootQualName::NodeId ())) { + fct_call = 0; + dependent_args = false; + } + + // call the node type specific resolve function + if (!(result = node->resolve (*this, base))) { + SEM_ERROR ((node->token () ? node : base), "expression expected"); + result = &CTYPE_UNDEFINED; + if (node->SemValue ()) + node->SemValue ()->setTypeRef (result); + } + + // recognize dependent result types + type = node->Type (); + if (type) { + // ignore return type of function types + if (type->TypeFunction ()) { + if (type->TypeFunction ()->ArgTypes ()->isDependent ()) + dependent = true; + // type depends on template parameter + } else if (type->isDependent ()) { + dependent = true; + // if result type is a class object type, ensure + // that the class is really instantiated + } else if (type->UnqualType()->TypeClass()) { + type->UnqualType()->TypeClass()->instantiate(current_scope); + } + } + + return result; +} + + +// fallback: unhandled kind of expression +CTypeInfo *CCSemExpr::resolve (CT_Expression *node, CTree *base) { + SEM_ERROR (node, "illegal expression"); + CTypeInfo *result = &CTYPE_UNDEFINED; + if (node->SemValue ()) + node->SemValue ()->setTypeRef (result); + return result; +} + + +// ���5.2.2 function call +CTypeInfo *CCSemExpr::resolve (CT_CallExpr *node, CTree *base) { + bool dep_base, dep_args; + CTypeInfo *t1, *result; + CCandidateInfo *cand; + CT_ExprList *args; + CObjectInfo *info; + unsigned entries; + CRecord *sinfo; + + info = 0; + dep_args = false; + dep_base = resetDependent (); + result = &CTYPE_UNDEFINED; + args = node->Arguments (); + entries = args->Entries (); + + // resolve arguments first + for (unsigned i = 0; i < entries; i++) { + resolve (args->Entry (i), args); + + // handle dependent arguments + if (dependent) { + dep_args = true; + dependent = false; + } + } + + if (dep_args) + dependent = true; + + // resolve postfix expression + fct_call = node; + dependent_args = dep_args; + t1 = resolve (node->Expr (), node); + dependent_args = false; + fct_call = 0; + + // handle dependent expressions + if (isDependent (node, dep_base)) + return result; + + // function call: op1 ( op2 , .. ) + if (t1->isFunction ()) { + info = t1->VirtualType ()->TypeFunction ()->FunctionInfo (); + if (! info) + result = t1->VirtualType ()->TypeFunction ()->ReturnType (); + } else if (t1->isPointer () && t1->PtrBaseType ()->isFunction ()) { + info = t1->PtrBaseType ()->VirtualType ()->TypeFunction ()->FunctionInfo (); + if (! info) + result = t1->PtrBaseType ()->VirtualType ()->TypeFunction ()->ReturnType (); + // ���13.3.1.1.2 call to object of class type + // ���13.5.4 function call operator overloading + } else if (t1->isRecord ()) { + sinfo = t1->VirtualType ()->TypeRecord ()->Record (); + if (sinfo) { + // ensure that class is instantiated + if (sinfo->ClassInfo ()) + sinfo->TypeInfo ()->TypeClass ()->instantiate (current_scope); + + // candidates are at least the function call operators + // (operator ()) of the object's class, and all conversion + // functions of this class and its base classes that yield + // "pointer to function", "reference to pointer to function", + // or "reference to function" + CCNameLookup nl (err, current_scope); + nl.lookup ("operator ()", sinfo, false, true); + + CCOverloading ovl (err); + ovl.ObjectType (t1); + ovl.collectConvFunctions (sinfo); + + // filter the conversion functions + for (unsigned i = ovl.Candidates (); i > 0; i--) { + t1 = ovl.Candidate (i-1)->Function ()->ConversionType (); + if (! (t1->isFunction () || (t1->isPointer () && + t1->PtrBaseType ()->isFunction ()))) + ovl.removeCandidate (i-1); + } + + ovl.addCandidates (nl); + ovl.resolve (args); + + // check result of function overload resolution + if (ovl.Function ()) { + if (validOvlFctSet (node, "overloaded operator", "operator ()", ovl)) { + info = ovl.Function (); + cand = ovl.Candidate (0); + + // apply the function argument conversions determined by + // overload resolution + for (unsigned i = 0; i < cand->ConvSequences (); i++) + cand->ConvSequence (i)->Apply (); + } + } else + SEM_ERROR (node, "non-function in function call"); + } + } else if (! t1->isUndefined ()) + SEM_ERROR (node, "non-function in function call"); + + if (info && info->FunctionInfo ()) { + node->Object (info); + result = info->FunctionInfo ()->ReturnType (); + } + + node->setTypeRef (result); + return result; +} + + +// ���5.2.5 class member access +CTypeInfo *CCSemExpr::resolve (CT_MembPtrExpr *node, CTree *base) { + CTypeInfo *t1, *t2, *result, *obj_type; + CT_CallExpr *fct_call_args; + bool dep_base, dep_args, new_type; + CObjectInfo *info, *obj; + CT_SimpleName *member; + unsigned long pos; + const char *op; + CRecord *sinfo; + LONG_LONG v; + CTree *init; + int oper; + + dep_base = resetDependent (); + op = node->Son (1)->token ()->text (); + oper = node->Son (1)->token ()->type (); + member = (CT_SimpleName*)node->Son (2); + result = &CTYPE_UNDEFINED; + fct_call_args = fct_call; + dep_args = dependent_args; + dependent_args = false; + new_type = false; + fct_call = 0; + sinfo = 0; + info = 0; + obj_type = 0; + + // resolve only the first operand + t1 = resolve (node->Son (0), node); + + // handle dependent expressions + if (isDependent (node, dep_base)) { + member->setTypeRef (result); + if (member != member->Name ()) + member->Name ()->setTypeRef (result); + return result; + } + + // apply lvalue-to-rvalue conversions + t1 = convLvalueToRvalue (node->Son (0)); + t2 = 0; + + // error diagnostics not yet complete! + + // op1 -> op2 + if (oper == TOK_PTS) { + // operator may be overloaded + dep_base = resetDependent (); + CTypeInfo *ovl_type = 0; + do { + // repeat resolving operator->() + ovl_type = overloadedOperator (node->Son (0), node, op, oper, node->Son (0)); + } while (ovl_type); + if (isDependent (node, dep_base)) { + member->setTypeRef (result); + if (member != member->Name ()) + member->Name ()->setTypeRef (result); + return result; + } + + t1 = node->Son (0)->Type (); + if (! (t1->isPointer () && t1->VirtualType ()->BaseType ()->isRecord ())) { + SEM_ERROR__left_op (node, op, "not pointer to class object"); + } else { + obj_type = t1->VirtualType ()->BaseType (); + t2 = obj_type->VirtualType (); + } + // op1 . op2 + } else { + if (! t1->isRecord ()) { + SEM_ERROR__left_op (node, op, "not a class object"); + } else { + obj_type = t1; + t2 = t1->VirtualType (); + } + } + + // get the class info + if (t2) { + sinfo = t2->TypeRecord ()->Record (); + pos = node->Son (1)->token_node ()->Number (); + // ensure that class is instantiated + if (sinfo && sinfo->ClassInfo ()) + sinfo->TypeInfo ()->TypeClass ()->instantiate (current_scope); + if (! t2->isComplete (pos)) { + sinfo = 0; + SEM_ERROR__left_op (node, op, "not a complete object type"); + } + } + + // lookup the class member + if (sinfo) { + sinfo = sinfo->DefObject ()->Record (); + // ensure that class is instantiated + if (sinfo->ClassInfo ()) + sinfo->TypeInfo ()->TypeClass ()->instantiate (current_scope); + + // explicit destructor call + if (member->Name ()->NodeName () == CT_DestructorName::NodeId ()) { + // get the type name after the tilde + obj = ((CT_SimpleName*)member->Name ()->Son (1))->Object (); + // destructor name must match type of expression + if (! obj || ! obj->TypeInfo () || ! obj->TypeInfo ()->TypeRecord () || + ! obj->TypeInfo ()->TypeRecord ()->Record () || ! sinfo->TypeInfo ()) { + SEM_ERROR (node, "destructor name `" << *member + << "' does not match type `" << sinfo->Name () << "' of expression"); + } else { + CRecord *dinfo = obj->TypeInfo ()->TypeRecord ()->Record (); + if (! (*sinfo->TypeInfo () == *obj->TypeInfo () || + (dinfo->ClassInfo () && sinfo->ClassInfo () && + sinfo->ClassInfo ()->isBaseClass (dinfo->ClassInfo (), true)))) { + SEM_ERROR (node, "destructor name `" << *member + << "' does not match type `" << sinfo->Name () << "' of expression"); + } else { + // valid call to destructor + std::string dtor_name = "~"; + dtor_name = dtor_name + dinfo->Name ().c_str (); + info = dinfo->Function (dtor_name.c_str ()); + } + } + // call to ordinary member + } else { + // do a class member name lookup + CCNameLookup nl (err, current_scope); + nl.lookup (member, sinfo, false, true); + + // no member found + if (! nl.Objects ()) { + SEM_ERROR (node, "`" << sinfo->Name () << "' has no member named `" + << *member << "'"); + // validate name lookup result + } else if (checkDeclsFound (node, nl)) { + // possibly overloaded function; resolve it + if (nl.Object (0)->FunctionInfo ()) { + if (! fct_call_args) { + // 13.4 address of overloaded function + // TODO: Not yet implemented! + if (nl.Objects () > 1) { + SEM_WARNING (node, "cannot resolve overloaded function"); + } else + info = nl.Object (0); + } else if (dep_args) { + dependent = true; + } else { + CCOverloading ovl (err); + ovl.ObjectType (obj_type); + ovl.addCandidates (nl); + ovl.resolveMember (fct_call_args, member); + + // check result of function overload resolution + if (validOvlFctSet (node, "function", member->Text (), ovl)) + info = ovl.Function (); + } + // non-function member + } else { + info = nl.Object (0); + if (info->Record () || info->TypedefInfo () || info->EnumInfo ()) { + SEM_ERROR (node, "`" << *member << + "' does not refer to object or function"); + info = 0; + } + } + } + } + } + + // member found + if (info) { + // determine result type + result = info->TypeInfo (); + if (info->AttributeInfo () && ! info->isStatic () && + ! info->isMutable () && ! result->isAddress ()) { + obj_type = obj_type->NonReferenceType (); + if (obj_type->isConst () || obj_type->isVolatile ()) { + // class data member called on a const/volatile class object + // the resulting type of the data member is changed to be const/volatile + new_type = true; + + // 3.9.3.2 CVqualifiers: Any cvqualifiers applied to an array type affect + // the array element type, not the array type (8.3.4). + std::stack array_nodes; + while (result->isArray ()) { // skip array nodes + array_nodes.push (result); + result = result->BaseType (); + } + + // add qualifiers if necessary + CTypeQualified *qt = result->TypeQualified (); + if (qt) { + qt = new CTypeQualified (qt->BaseType ()->Duplicate (), + (obj_type->isConst () || qt->isConst ()), (obj_type->isVolatile () || qt->isVolatile ()), false); + } else { + qt = new CTypeQualified (result->Duplicate (), + obj_type->isConst (), obj_type->isVolatile (), false); + } + + // duplicate array nodes if neccessary + result = qt; + while (!array_nodes.empty ()) { + CTypeArray *at = (CTypeArray*)array_nodes.top (); + bool has_dim = at->hasDimension (); + long int dim = at->Dimension (); + bool is_fixed = at->isFixed (); + at = new CTypeArray (result, (CTypeQualified*)(at->Qualifiers () ? at->Qualifiers ()->Duplicate () : 0)); + at->hasDimension (has_dim); + at->Dimension (dim); + at->isFixed (is_fixed); + result = at; + array_nodes.pop (); + } + } + } + + node->Object (info); + member->Object (info); + if (member != member->Name ()) + member->Name ()->Object (info); + + // name of an enumeration constant + if (info->EnumeratorInfo ()) { + if (info->EnumeratorInfo ()->hasValue ()) { + v = info->EnumeratorInfo ()->Value (); + member->setValue (new CConstant (v, result)); + if (member != member->Name ()) + member->Name ()->setValue (new CConstant (v, result)); + node->setValueRef (member->Value ()->Constant ()); + } + else if (isDependent (info->Init ())) { + dependent = true; + } + // name of a constant variable or class data member + } else if (info->AttributeInfo () && info->TypeInfo ()->isConst ()) { + init = info->AttributeInfo ()->Init (); + if (init && init->Value () && init->Value ()->Constant ()) { + member->setValueRef (init->Value ()->Constant ()); + if (member != member->Name ()) + member->Name ()->setValueRef (init->Value ()->Constant ()); + node->setValueRef (member->Value ()->Constant ()); + } + else if (isDependent (init)) { + dependent = true; + } + } + } + + if (new_type) { + member->setType (result); + if (member != member->Name ()) + member->Name ()->setType (result->Duplicate ()); + node->setType (result->Duplicate ()); + } else { + member->setTypeRef (result); + if (member != member->Name ()) + member->Name ()->setTypeRef (result); + node->setTypeRef (result); + } + return result; +} + + +// ���5.1 unqualified and qualified names +CTypeInfo *CCSemExpr::resolve (CT_SimpleName *node, CTree *base) { + bool arg_dep_lookup, new_type, is_type_name; + CTypeInfo *result, *type; + CT_TemplateArgList *tal; + CTree *init, *arg; + CObjectInfo *info; + unsigned args; + LONG_LONG v; + + result = &CTYPE_UNDEFINED; + arg_dep_lookup = false; + new_type = false; + info = 0; + + // error diagnostics not yet complete! + + // handle dependent names + if (node->NodeName () == CT_QualName::NodeId () || + (node->NodeName () == CT_RootQualName::NodeId () && + node->Entries () > 1)) { + info = ((CT_SimpleName*)node->Entry (node->Entries ()-2))->Object (); + if (! info || (info->TypeInfo () && info->TypeInfo ()->isDependent ())) + dependent = true; + } + if (node->Name ()->NodeName () == CT_TemplateName::NodeId ()) { + info = node->Name ()->Object (); + if (info && info->FunctionInfo () && info->FunctionInfo ()->isTemplate ()) { + tal = ((CT_TemplateName*)node->Name ())->Arguments (); + args = tal->Entries (); + for (unsigned i = 0; i < args; i++) { + arg = tal->Entry (i); + is_type_name = arg->NodeName () == CT_NamedType::NodeId () && + arg->SemObject ()->Object (); + if (is_type_name) + type = arg->SemObject ()->Object ()->TypeInfo (); + else + type = arg->Type (); + + if (type && type->isDependent (true, is_type_name)) { + dependent = true; + break; + } + } + } + } + + // check function call arguments (if any) + if (fct_call && dependent_args) + dependent = true; + + if (dependent) { + node->setTypeRef (result); + if (node != node->Name ()) + node->Name ()->setTypeRef (result); + return result; + } + + // do an ordinary name lookup in current scope + // (unqualified name) or scope denoted by the + // scope resolution operator (qualified name) + CCNameLookup nl (err, current_scope); + nl.lookup (node, current_scope, true, true); + + // name not found, could be a built-in function + if (! nl.Objects () && ! lookupBuiltin (node, nl)) { + // is a built-in but no corresponding declaration found, + // handle like a dependent name + dependent = true; + node->setTypeRef (result); + if (node != node->Name ()) + node->Name ()->setTypeRef (result); + return result; + } + + // name not found + if (! nl.Objects ()) { + // handle dependent class scope, i.e. classes derived + // from template parameters + if (depBaseClass ()) { + dependent = true; + node->setTypeRef (result); + if (node != node->Name ()) + node->Name ()->setTypeRef (result); + return result; + } + + // may be the name of a function that can only be found + // using argument-dependent name lookup + if (fct_call && + node->NodeName () != CT_QualName::NodeId () && + node->NodeName () != CT_RootQualName::NodeId ()) { + // collect scopes associated with the function call arguments + CCAssocScopes scopes (fct_call->Arguments ()); + + if (! scopes.Namespaces ()) { + SEM_ERROR__undeclared (node); + } else { + arg_dep_lookup = true; + + // lookup name in associated namespaces as if + // the name was qualified by the namespace's name + for (unsigned i = 0; i < scopes.Namespaces (); i++) + nl.lookupInAssNs (node, scopes.Namespace (i)); + + // name is definitely not known here + if (! nl.Objects ()) { + SEM_ERROR__undeclared (node); + } else { + if (nl.Objects () == 1 && ! nl.Object (0)->FunctionInfo ()) + nl.reset (current_scope); + else + checkDeclsFound (node, nl); + } + } + } else + SEM_ERROR__undeclared (node); + } + + // validate name lookup result + checkDeclsFound (node, nl); + + // name found + if (nl.Objects ()) { + info = nl.Object (0); + + // not yet complete! (see ���13.4 etc) + + // possibly overloaded function; resolve it + if (fct_call && info->FunctionInfo ()) { + // do an argument-dependent name lookup + // if function is not a class member + if (! arg_dep_lookup && ! info->isClassMember ()) { + CCAssocScopes scopes (fct_call->Arguments ()); + if (scopes.Namespaces ()) { + for (unsigned i = 0; i < scopes.Namespaces (); i++) + nl.lookupInAssNs (node, scopes.Namespace (i)); + + if (! checkDeclsFound (node, nl)) + info = 0; // to show the algorithm that there's something wrong + } + } + + // do overload resolution + if (info) { + CCOverloading ovl (err); + ovl.addCandidates (nl); + ovl.resolve (fct_call); + + // check result of function overload resolution + if (validOvlFctSet (node, "function", node->Text (), ovl)) + info = ovl.Function (); + else + info = 0; + } + } + } + + // name found + if (info) { + // determine result type: if the name occured in the scope of a + // const/volatile method and it's the name of a class member + // that is not a reference nor static or mutable, its type also + // becomes const/volatile + result = info->TypeInfo (); + if (current_scope->LocalScope () && info->AttributeInfo () && + ! info->isStatic () && ! info->isMutable () && ! result->isAddress ()) { + CFunctionInfo *fct = current_scope->LocalScope ()->Function (); + if (fct) { + CTypeFunction *ft = fct->TypeInfo (); + if (fct->isMethod () && (ft->isConst () || ft->isVolatile ())) { + CRecord *ac = info->AttributeInfo ()->Record (); + CClassInfo *fc = fct->Record ()->ClassInfo (); + if (ac && fc && (*ac == *fc || fc->isBaseClass (ac->ClassInfo (), true))) { + // class data member used in a const/volatile method of the same or derived class + // the type of the data member is changed to be const/volatile + new_type = true; + CTypeQualified *qt = result->TypeQualified (); + if (qt) { + qt = new CTypeQualified (qt->BaseType ()->Duplicate (), + (ft->isConst () || qt->isConst ()), (ft->isVolatile () || qt->isVolatile ()), false); + } else { + qt = new CTypeQualified (result->Duplicate (), + ft->isConst (), ft->isVolatile (), false); + } + result = qt; + } + } + } + } + + node->Object (info); + if (node != node->Name ()) + node->Name ()->Object (info); + + // name of an enumeration constant + if (info->EnumeratorInfo ()) { + if (info->EnumeratorInfo ()->hasValue ()) { + v = info->EnumeratorInfo ()->Value (); + node->setValue (new CConstant (v, result)); + if (node != node->Name ()) + node->Name ()->setValue (new CConstant (v, result)); + } + else if (isDependent (info->Init ())) { + dependent = true; + } + // name of a constant variable or class data member + } else if (info->AttributeInfo () && info->TypeInfo ()->isConst ()) { + init = info->AttributeInfo ()->Init (); + if (init && init->Value () && init->Value ()->Constant ()) { + node->setValueRef (init->Value ()->Constant ()); + if (node != node->Name ()) + node->Name ()->setValueRef (init->Value ()->Constant ()); + } + else if (isDependent (init)) { + dependent = true; + } + } + + // name of a template parameter or type depends on a + // template parameter => expression is dependent + if (info->TemplateParamInfo () || + (info->TypeInfo () && info->TypeInfo ()->isDependent ())) + dependent = true; + } + + if (new_type) { + node->setType (result); + if (node != node->Name ()) + node->Name ()->setType (result->Duplicate ()); + } else { + node->setTypeRef (result); + if (node != node->Name ()) + node->Name ()->setTypeRef (result); + } + return result; +} + + +// binary expressions +CTypeInfo *CCSemExpr::resolve (CT_BinaryExpr *node, CTree *base) { + CTypeInfo *result, *oop; + const char *op; + bool dep_base; + int oper; + + dep_base = resetDependent (); + op = node->Son (1)->token ()->text (); + oper = node->Son (1)->token ()->type (); + result = &CTYPE_UNDEFINED; + + // resolve operands + resolve (node->Son (0), node); + resolve (node->Son (2), node); + + // handle dependent expressions + if (isDependent (node, dep_base)) + return result; + + // apply lvalue-to-rvalue conversions + if (oper != TOK_COMMA) // see ���5.18 comma operator + convLvalueToRvalue (node->Son (0)); + convLvalueToRvalue (node->Son (2)); + + // operator may be overloaded (���13.5 pointer-to-member + // operator ".*" cannot be overloaded) + if (oper != TOK_DOT_STAR) { + dep_base = resetDependent (); + oop = overloadedOperator (node, base, op, oper, node->Son (0), node->Son (2)); + if (isDependent (node, dep_base)) { + return result; + } else if (oop) + return oop; + } + + // ���5.5 pointer-to-member operators: op1 .* op2; op1 ->* op2 + if (oper == TOK_DOT_STAR || oper == TOK_PTS_STAR) + result = binary_ptm (node, base); + // ���5.6 multiplicative operators: op1 * op2; op1 / op2; op1 % op2 + else if (oper == TOK_MUL || oper == TOK_DIV || oper == TOK_MODULO) + result = binary_mul (node, base); + // ���5.7 additive operators: op1 + op2; op1 - op2 + else if (oper == TOK_PLUS || oper == TOK_MINUS) + result = binary_add (node, base); + // ���5.8 shift operators: op1 << op2; op1 >> op2 + else if (oper == TOK_LSH || oper == TOK_RSH) + result = binary_shift (node, base); + // ���5.9 relational operators: op1 < op2; op1 > op2; op1 <= op2; op1 >= op2 + else if (oper == TOK_LESS || oper == TOK_GREATER || + oper == TOK_LEQ || oper == TOK_GEQ) + result = binary_rel (node, base); + // ���5.10 equality operators: op1 == op2; op1 != op2 + else if (oper == TOK_EQL || oper == TOK_NEQ) + result = binary_equ (node, base); + // ���5.11 bitwise AND operator: op1 & op2 + // ���5.12 bitwise exclusive OR operator: op1 ^ op2 + // ���5.13 bitwise inclusive OR operator: op1 | op2 + else if (oper == TOK_AND || oper == TOK_ROOF || oper == TOK_OR) + result = binary_bit (node, base); + // ���5.14 logical AND operator: op1 && op2 + // ���5.15 logical OR operator: op1 || op2 + else if (oper == TOK_AND_AND || oper == TOK_OR_OR) + result = binary_log (node, base); + // ���5.18 comma operator: op1 , op2 + else if (oper == TOK_COMMA) + result = binary_comma (node, base); + // ���5.17 assignment operators: op1 = op2; op1 *= op2; op1 /= op2; + // op1 %= op2; op1 += op2; op1 -= op2; op1 >>= op2; + // op1 <<= op2; op1 &= op2; op1 ^= op2; op1 |= op2 + else if (oper == TOK_ASSIGN || oper == TOK_MUL_EQ || oper == TOK_DIV_EQ || + oper == TOK_MOD_EQ || oper == TOK_ADD_EQ || oper == TOK_SUB_EQ || + oper == TOK_RSH_EQ || oper == TOK_LSH_EQ || oper == TOK_AND_EQ || + oper == TOK_XOR_EQ || oper == TOK_IOR_EQ) + result = binary_ass (node, base); + + node->setTypeRef (result); + + // transform the expression into a call expression with a built-in operator + // as the target function + CTypeInfo *t1 = node->Son (0)->Type (); + CTypeInfo *t2 = node->Son (2)->Type (); + builtinOpExpr (node, base, op, oper, result, t1, t2); + + return result; +} + + +// ���5.17 assignment operators +CTypeInfo *CCSemExpr::binary_ass (CT_BinaryExpr *node, CTree *base) { + CTypeInfo *t1, *result; + unsigned long pos; + const char *op; + CConstant *v2; + int oper; + + op = node->Son (1)->token ()->text (); + oper = node->Son (1)->token ()->type (); + pos = node->Son (1)->token_node ()->Number (); + result = t1 = node->Son (0)->Type (); + + // error diagnostics not yet complete! + + if (! isLvalue (node->Son (0))) { + SEM_ERROR (node, "non-lvalue in assignment"); + } else { + if (! isModifiable (t1, pos)) + SEM_WARNING (node, "assignment of unmodifiable location"); + if (! t1->isRecord ()) + result = t1->UnqualType (); + else if (! t1->VirtualType ()->isComplete (pos)) + SEM_ERROR (node, "assignment to incomplete type"); + + if (oper == TOK_ADD_EQ || oper == TOK_SUB_EQ) { + if (! t1->isScalar ()) + SEM_ERROR__left_op (node, op, "not a scalar type"); + } else if (oper != TOK_ASSIGN) { + if (! t1->isArithmetic ()) + SEM_ERROR__left_op (node, op, "not an arithmetic type"); + } + + v2 = node->Son (2)->Value () ? node->Son (2)->Value ()->Constant () : 0; + if (v2) { + if ((oper == TOK_MOD_EQ || oper == TOK_DIV_EQ) && v2->isNull ()) { + SEM_WARNING (node, "division by zero"); + } else if ((oper == TOK_RSH_EQ || oper == TOK_LSH_EQ) && v2->isNegative ()) { + SEM_WARNING (node, "negative shift count"); + } + } + } + + return result; +} + + +// ���5.18 comma operator +CTypeInfo *CCSemExpr::binary_comma (CT_BinaryExpr *node, CTree *base) { + return node->Son (2)->Type (); +} + + +// ���5.14 logical AND operator +// ���5.15 logical OR operator +CTypeInfo *CCSemExpr::binary_log (CT_BinaryExpr *node, CTree *base) { + CTypeInfo *t1, *t2; + const char *op; + int oper; + + op = node->Son (1)->token ()->text (); + oper = node->Son (1)->token ()->type (); + t1 = node->Son (0)->Type (); + t2 = node->Son (2)->Type (); + + // error diagnostics not yet complete! + + if (! (t1->isScalar () && t2->isScalar ())) { + SEM_ERROR__invalid_op (node, "binary", op); + } else { + if (! t1->VirtualType ()->is_bool ()) + castToType (&CTYPE_BOOL, node->Son (0), true); + if (! t2->VirtualType ()->is_bool ()) + castToType (&CTYPE_BOOL, node->Son (2), true); + + apply_binary_op (node, oper); + } + + return &CTYPE_BOOL; +} + + +// ���5.11 bitwise AND operator +// ���5.12 bitwise exclusive OR operator +// ���5.13 bitwise inclusive OR operator +CTypeInfo *CCSemExpr::binary_bit (CT_BinaryExpr *node, CTree *base) { + CTypeInfo *t1, *t2, *result; + const char *op; + int oper; + + result = &CTYPE_UNDEFINED; + op = node->Son (1)->token ()->text (); + oper = node->Son (1)->token ()->type (); + t1 = node->Son (0)->Type (); + t2 = node->Son (2)->Type (); + + // error diagnostics not yet complete! + + if (! (t1->isInteger () && t2->isInteger ())) { + SEM_ERROR__invalid_op (node, "binary", op); + } else { + // apply usual arithmetic conversions + result = usualArithmeticConv (node->Son (0), node->Son (2)); + result = result->NonReferenceType (); // yields an r-value + apply_binary_op (node, oper); + } + return result; +} + + +// ���5.10 equality operators +CTypeInfo *CCSemExpr::binary_equ (CT_BinaryExpr *node, CTree *base) { + CTypeInfo *t1, *t2; + const char *op; + CConstant *v1; + int oper; + bool l; + + op = node->Son (1)->token ()->text (); + oper = node->Son (1)->token ()->type (); + t1 = node->Son (0)->Type (); + t2 = node->Son (2)->Type (); + + // error diagnostics not yet complete! + + if (t1->isArithmetic () && t2->isArithmetic ()) { + // apply usual arithmetic conversions + usualArithmeticConv (node->Son (0), node->Son (2)); + } else if ((t1->isInteger () && t2->isPointer ()) || + (t2->isInteger () && t1->isPointer ())) { + l = (t1->isInteger ()); + v1 = node->Son (l?0:2)->Value () ? node->Son (l?0:2)->Value ()->Constant () : 0; + if (! (v1 && v1->isNull ())) { + // not a null pointer constant + SEM_ERROR__comp_between (node, "pointer and integer"); + } else { + // implicitly cast integer constant to pointer type + castToType (l?t2:t1, node->Son (l?0:2), true); + } + } else if (! (t1->isScalar () && t2->isScalar ())) + SEM_ERROR__invalid_op (node, "binary", op); + + apply_binary_op (node, oper); + return &CTYPE_BOOL; +} + + +// ���5.9 relational operators +CTypeInfo *CCSemExpr::binary_rel (CT_BinaryExpr *node, CTree *base) { + CTypeInfo *t1, *t2; + const char *op; + int oper; + + op = node->Son (1)->token ()->text (); + oper = node->Son (1)->token ()->type (); + t1 = node->Son (0)->Type (); + t2 = node->Son (2)->Type (); + + // error diagnostics not yet complete! + + if (t1->isArithmetic () && t2->isArithmetic ()) + // apply usual arithmetic conversions + usualArithmeticConv (node->Son (0), node->Son (2)); + else if (! (t1->isScalar () && t2->isScalar ())) + SEM_ERROR__invalid_op (node, "binary", op); + + apply_binary_op (node, oper); + return &CTYPE_BOOL; +} + + +// ���5.8 shift operators +CTypeInfo *CCSemExpr::binary_shift (CT_BinaryExpr *node, CTree *base) { + CTypeInfo *t1, *t2, *result; + const char *op; + CConstant *v2; + int oper; + + result = &CTYPE_UNDEFINED; + op = node->Son (1)->token ()->text (); + oper = node->Son (1)->token ()->type (); + t1 = node->Son (0)->Type (); + t2 = node->Son (2)->Type (); + + // error diagnostics not yet complete! + + if (! (t1->isInteger () && t2->isInteger ())) { + SEM_ERROR__invalid_op (node, "binary", op); + } else { + // apply integral promotions on both operands + t1 = intPromotion (node->Son (0)); + t2 = intPromotion (node->Son (2)); + result = t1->NonReferenceType (); // yields an r-value + + v2 = node->Son (2)->Value () ? node->Son (2)->Value ()->Constant () : 0; + if (v2 && v2->isNegative ()) + SEM_WARNING (node, "negative shift count"); + + apply_binary_op (node, oper); + } + + return result; +} + + +// ���5.7 additive operators +CTypeInfo *CCSemExpr::binary_add (CT_BinaryExpr *node, CTree *base) { + CTypeInfo *t1, *t2, *result; + int oper; + + result = &CTYPE_UNDEFINED; + oper = node->Son (1)->token ()->type (); + t1 = node->Son (0)->Type (); + t2 = node->Son (2)->Type (); + + // error diagnostics not yet complete! + + if (t1->isArithmetic () && t2->isArithmetic ()) { + // apply usual arithmetic conversions + result = usualArithmeticConv (node->Son (0), node->Son (2)); + } else if (oper == TOK_PLUS) { + if (! (t1->isArithmetic () && t2->isPointer ()) && + ! (t2->isArithmetic () && t1->isPointer ())) { + SEM_ERROR__invalid_op (node, "binary", "+"); + } else { + result = t1->isPointer () ? t1 : t2; + } + } else { // oper == TOK_MINUS + if (! (t1->isPointer () && t2->isInteger ()) && + ! (t1->isPointer () && t2->isPointer () && sameUnqualBaseType (t1, t2))) { + SEM_ERROR__invalid_op (node, "binary", "-"); + } else { /* ptrdiff_t */ + result = t2->isPointer () ? CTypeInfo::CTYPE_PTRDIFF_T : t1; + } + } + + result = result->NonReferenceType (); // yields a non-reference type + + apply_binary_op (node, oper); + return result; +} + + +// ���5.6 multiplicative operators +CTypeInfo *CCSemExpr::binary_mul (CT_BinaryExpr *node, CTree *base) { + CTypeInfo *t1, *t2, *result; + const char *op; + CConstant *v2; + int oper; + + result = &CTYPE_UNDEFINED; + op = node->Son (1)->token ()->text (); + oper = node->Son (1)->token ()->type (); + t1 = node->Son (0)->Type (); + t2 = node->Son (2)->Type (); + + // error diagnostics not yet complete! + + if (oper == TOK_MODULO ? ! (t1->isInteger () && t2->isInteger ()) : + ! (t1->isArithmetic () && t2->isArithmetic ())) { + SEM_ERROR__invalid_op (node, "binary", op); + } else { + // apply usual arithmetic conversions + result = usualArithmeticConv (node->Son (0), node->Son (2)); + result = result->NonReferenceType (); // yields an r-value + + v2 = node->Son (2)->Value () ? node->Son (2)->Value ()->Constant () : 0; + if ((oper == TOK_MODULO || oper == TOK_DIV) && v2 && v2->isNull ()) + SEM_WARNING (node, "division by zero"); + apply_binary_op (node, oper); + } + + return result; +} + + +// ���5.5 pointer-to-member operators +CTypeInfo *CCSemExpr::binary_ptm (CT_BinaryExpr *node, CTree *base) { + CTypeInfo *t1, *t2, *result; + CRecord *pclass, *oclass; + const char *op; + int oper; + + op = node->Son (1)->token ()->text (); + oper = node->Son (1)->token ()->type (); + t1 = node->Son (0)->Type (); + t2 = node->Son (2)->Type (); + + result = &CTYPE_UNDEFINED; + if (t2->TypeMemberPointer ()) + result = t2->BaseType (); + + // error diagnostics not yet complete! + + if (! t2->TypeMemberPointer ()) { + SEM_ERROR__right_op (node, op, "not pointer to member"); + } else if (oper == TOK_DOT_STAR && ! t1->isRecord ()) { + SEM_ERROR__left_op (node, op, "not of class type"); + } else if (oper == TOK_PTS_STAR && ! (t1->isPointer () && + t1->VirtualType ()->BaseType ()->isRecord ())) { + SEM_ERROR__left_op (node, op, "not pointer to class type"); + } else { + pclass = t2->TypeMemberPointer ()->Record (); + if (oper == TOK_DOT_STAR) + oclass = t1->VirtualType ()->TypeRecord ()->Record (); + else + oclass = t1->VirtualType ()->BaseType ()->VirtualType ()-> + TypeRecord ()->Record (); + if (! sameOrBaseClass (pclass, oclass)) + SEM_ERROR (node, "member type `" + << (pclass ? pclass->Name ().c_str () : "") << "' " + << "incompatible with object type `" << oclass->Name () << "'"); + } + + return result; +} + + +// ���5.3 unary expression +CTypeInfo *CCSemExpr::resolve (CT_UnaryExpr *node, CTree *base) { + CTypeInfo *result, *t1, *oop; + unsigned long pos; + const char *op; + bool dep_base; + CConstant *v1; + int oper; + + dep_base = resetDependent (); + result = &CTYPE_UNDEFINED; + op = node->Son (0)->token ()->text (); + oper = node->Son (0)->token ()->type (); + pos = node->Son (1)->token_node ()->Number (); + + // resolve operands + t1 = resolve (node->Son (1), node); + + // handle dependent expressions + if (isDependent (node, dep_base)) + return result; + + // apply lvalue-to-rvalue conversions + t1 = convLvalueToRvalue (node->Son (1)); + + // operator may be overloaded + dep_base = resetDependent (); + oop = overloadedOperator (node, base, op, oper, node->Son (1)); + if (isDependent (node, dep_base)) { + if (oper == TOK_NOT) { + result = &CTYPE_BOOL; + node->setTypeRef (result); + } + return result; + } else if (oop) { + return oop; + } else + t1 = node->Son (1)->Type (); + + // prefix in-/decrement: ++ op1; -- op1 + if (oper == TOK_DECR || oper == TOK_INCR) { + if (! isLvalue (node->Son (1))) { + SEM_ERROR (node, "non-lvalue in prefix increment/decrement"); + } else { + if (! isModifiable (t1, pos)) { + if (oper == TOK_DECR) { + SEM_WARNING (node, "decrement of unmodifiable location"); + } else { + SEM_WARNING (node, "increment of unmodifiable location"); + } + } + if (! t1->isScalar () || + (oper == TOK_DECR && t1->VirtualType ()->is_bool ())) { + SEM_ERROR__invalid_op (node, "unary", op); + } + } + result = t1->UnqualType (); + // + op1; - op1; ~ op1 + } else if (oper == TOK_PLUS || oper == TOK_MINUS || oper == TOK_TILDE) { + if ((oper == TOK_PLUS && t1->isScalar ()) || + (oper == TOK_MINUS && t1->isArithmetic ()) || + (oper == TOK_TILDE && t1->isInteger ())) { + if (t1->isInteger ()) + t1 = intPromotion (node->Son (1)); + v1 = node->Son (1)->Value () ? node->Son (1)->Value ()->Constant () : 0; + if (v1 && ! t1->isPointer ()) + node->setValue (v1->compute (oper)); + } else { + SEM_ERROR__invalid_op (node, "unary", op); + } + result = t1; + // ! op1 + } else if (oper == TOK_NOT) { + if (! t1->isScalar ()) { + SEM_ERROR__invalid_op (node, "unary", op); + } else { + if (! t1->VirtualType ()->is_bool ()) + t1 = castToType (&CTYPE_BOOL, node->Son (1), true); + v1 = node->Son (1)->Value () ? node->Son (1)->Value ()->Constant () : 0; + if (v1) + node->setValue (v1->compute (oper)); + } + result = &CTYPE_BOOL; + } + + node->setTypeRef (result); + + // transform the expression into a call expression with a built-in operator + // as the target function + t1 = node->Son (1)->Type (); + builtinOpExpr (node, base, op, oper, result, t1); + + return result; +} + + +// ���5.2.6 postfix increment and decrement +CTypeInfo *CCSemExpr::resolve (CT_PostfixExpr *node, CTree *base) { + CTypeInfo *result, *t1, *oop; + CT_Integer *second; + unsigned long pos; + const char *op; + bool dep_base; + int oper; + + dep_base = resetDependent (); + op = node->Son (1)->token ()->text (); + oper = node->Son (1)->token ()->type (); + pos = node->Son (1)->token_node ()->Number (); + + // resolve operand + t1 = resolve (node->Son (0), node); + + // handle dependent expressions + if (isDependent (node, dep_base)) + return &CTYPE_UNDEFINED; + + // apply lvalue-to-rvalue conversions + t1 = convLvalueToRvalue (node->Son (0)); + + // operator may be overloaded + if (isClassOrEnum (t1)) { + // postfix increment and decrement operators have an + // imlicit second operand of type int and value 0, + // create this operand (a little bit tricky :( ) + second = new CT_Integer (node->Son (1)); + second->setTypeRef (&CTYPE_INT); + second->setValue (new CConstant ((U_LONG_LONG)0, &CTYPE_INT)); + dep_base = resetDependent (); + oop = overloadedOperator (node, base, op, oper, node->Son (0), second); + delete second; + // restore parent pointer + node->ReplaceSon (node->Son (1), node->Son (1)); + if (isDependent (node, dep_base)) + return &CTYPE_UNDEFINED; + else if (oop) + return oop; + else + t1 = node->Son (0)->Type (); + } + + // postfix in-/decrement: op1 ++; op1 -- + if (! isLvalue (node->Son (0))) { + SEM_ERROR (node, "non-lvalue in postfix increment/decrement"); + } else { + if (! isModifiable (t1, pos)) { + if (oper == TOK_DECR) { + SEM_WARNING (node, "decrement of unmodifiable location"); + } else { + SEM_WARNING (node, "increment of unmodifiable location"); + } + } + if (! t1->isScalar () || + (oper == TOK_DECR && t1->VirtualType ()->is_bool ())) { + SEM_ERROR__invalid_op (node, "unary", op); + } + } + + result = t1->UnqualType (); + node->setTypeRef (result); + + // transform the expression into a call expression with a built-in operator + // as the target function + builtinOpExpr (node, base, op, oper, result, t1); + + return result; +} + + +// ���5.2.3 explicit type conversion (functional notation) +CTypeInfo *CCSemExpr::resolve (CT_ConstructExpr *node, CTree *base) { + CTypeInfo *result; + CT_ExprList *init; + unsigned entries; + bool dep_base; + + dep_base = resetDependent (); + + // resolve initializer + init = node->Initializer (); + entries = init->Entries (); + for (unsigned i = 0; i < entries; i++) + resolve (init->Entry (i), init); + + // handle dependent expressions + //if (isDependent (node, dep_base)) + // return &CTYPE_UNDEFINED; + + // error diagnostics not yet implemented! + + if (node->TypeName ()->Object ()) + result = node->TypeName ()->Object ()->TypeInfo (); + else + result = &CTYPE_UNDEFINED; + + if (result) { + // constructor call + if (result->isRecord ()) { + // to be implemented! + // cast expression (functional notation) + } else if (entries == 1) { + if (! dependent) { + // apply lvalue-to-rvalue conversions + convLvalueToRvalue (init->Entry (0)); + + // handle constants + passOnConstant (init->Entry (0), result); + passOnConstant (init, result); + } + } + } + + if (isDependent (node->TypeName ())) { + // if the type of the object to be constructed is dependent on a template + // parameter, the construct expression is dependent as well + result = &CTYPE_UNDEFINED; + dependent = true; + } + + // reset dependent state + if (dep_base) + dependent = true; + + node->setTypeRef (result); + return result; +} + + +// GNU C/C++ extension +CTypeInfo *CCSemExpr::resolve (CT_CmpdLiteral *node, CTree *base) { + CTypeInfo *result; +// bool dep_base; + +// dep_base = resetDependent (); + + // handle dependent expressions +// if (isDependent (node, dep_base)) +// return &CTYPE_UNDEFINED; + + // evaluation not yet complete! + + if (node->TypeName ()->Object ()) + result = node->TypeName ()->Object ()->TypeInfo (); + else + result = &CTYPE_UNDEFINED; + + node->setTypeRef (result); + return result; +} + + +// ���5.3.4 new expression +CTypeInfo *CCSemExpr::resolve (CT_NewExpr *node, CTree *base) { + CTypeInfo *result; + unsigned entries; + bool dep_base; + + dep_base = resetDependent (); + result = &CTYPE_UNDEFINED; + + // resolve placement + if (node->Placement ()) { + entries = node->Placement ()->Entries (); + for (unsigned i = 0; i < entries; i++) + resolve (node->Placement ()->Entry (i), node->Placement ()); + } + + // resolve initializer + if (node->Initializer ()) { + entries = node->Initializer ()->Entries (); + for (unsigned i = 0; i < entries; i++) + resolve (node->Initializer ()->Entry (i), node->Initializer ()); + } + + // handle dependent expressions + if (isDependent (node, dep_base)) + return result; + + // error diagnostics not yet implemented! + + if (node->TypeName ()->Object ()) { + result = node->TypeName ()->Object ()->TypeInfo (); + if (result->isArray ()) + result = result->VirtualType ()->BaseType (); + else if (result->UnqualType()->TypeClass()) + result->UnqualType()->TypeClass()->instantiate(current_scope); + result = new CTypePointer (result->Duplicate ()); + node->setType (result); + } else + node->setTypeRef (result); + + return result; +} + + +// ���5.3.5 delete expression +CTypeInfo *CCSemExpr::resolve (CT_DeleteExpr *node, CTree *base) { + CTypeInfo *result, *t1; + bool dep_base; + + dep_base = resetDependent (); + result = &CTYPE_VOID; + + // resolve operands + t1 = resolve (node->Expr (), node); + + // handle dependent expressions + if (isDependent (node, dep_base)) { + node->setTypeRef (result); + return result; + } + + // error diagnostics not yet implemented! + + node->setTypeRef (result); + return result; +} + + +// ���5.16 conditional operator +CTypeInfo *CCSemExpr::resolve (CT_IfThenExpr *node, CTree *base) { + CTypeInfo *result, *t1, *t2, *t3; + CTree *op1, *op2, *op3; + CConstant *v1, *v2; + bool dep_base; + + dep_base = resetDependent (); + result = &CTYPE_UNDEFINED; + + // resolve operands + t1 = resolve (node->Son (0), node); + t2 = resolve (node->Son (2), node); + t3 = resolve (node->Son (4), node); + op1 = node->Son (0); + op2 = node->Son (2); + op3 = node->Son (4); + + // handle dependent expressions + if (isDependent (node, dep_base)) + return result; + + // error diagnostics not yet complete! + + if (! t1->is_bool ()) { + t1 = castToType (&CTYPE_BOOL, op1, true); + op1 = node->Son (0); + } + + // either of the operands has type void + if (t2->UnqualType ()->is_void () || t3->UnqualType ()->is_void ()) { + // apply lvalue-to-rvalue conversions + t2 = convLvalueToRvalue (op2); + t3 = convLvalueToRvalue (op3); + op2 = node->Son (2); + op3 = node->Son (4); + + if (baseTree (op2)->NodeName () == CT_ThrowExpr::NodeId ()) + result = t3; + else if (baseTree (op3)->NodeName () == CT_ThrowExpr::NodeId ()) + result = t2; + else if (t2->UnqualType ()->is_void () && t3->UnqualType ()->is_void ()) + result = &CTYPE_VOID; + else + SEM_ERROR__invalid_op (node, "conditional", "?:"); + node->setTypeRef (result); + // equal types and operands are lvalues + } else if (*t2->VirtualType () == *t3->VirtualType () && + isLvalue (op2) && isLvalue (op3)) { + result = t2; + node->setTypeRef (result); + // types are different and one is a class type + } else if (*t2 != *t3 && (t2->isRecord () || t3->isRecord ())) { + // ���5.16.3,5 convert the second operand to the third and vice versa + CCConversions cvs(err); + CCConvSeq *seq1 = cvs.implicitConversions (t2, t3, op3, node, true); + CCConvSeq *seq2 = cvs.implicitConversions (t3, t2, op2, node, true); + if (seq1 && !seq2) { + seq1->Apply (); + result = t2; + node->setTypeRef (result); + } else if (!seq1 && seq2) { + seq2->Apply (); + result = t3; + node->setTypeRef (result); + } + if (seq1) delete seq1; + if (seq2) delete seq2; + } + + // ���5.16.6 + if (result == &CTYPE_UNDEFINED) { + // apply lvalue-to-rvalue conversions + t2 = convLvalueToRvalue (op2); + t3 = convLvalueToRvalue (op3); + op2 = node->Son (2); + op3 = node->Son (4); + + // types are equal; result is t2 + if (*t2->VirtualType () == *t3->VirtualType ()) { + result = t2; + node->setTypeRef (result); + // arithmetic operands + } else if (t2->isArithmetic () && t3->isArithmetic ()) { + result = usualArithmeticConv (op2, op3); + op2 = node->Son (2); + op3 = node->Son (4); + node->setTypeRef (result); + // pointer types + } else { + v1 = op2->Value () ? op2->Value ()->Constant () : 0; + v2 = op3->Value () ? op3->Value ()->Constant () : 0; + + // pointer to pointer conversion + if (t2->isPointer () && t3->isPointer ()) { + // not yet implemented! + result = t2; + // pointer to null pointer conversion + } else if (t2->isPointer () && t3->isArithmetic () && v2 && v2->isNull ()) { + result = castToType (t2, op3, true); + op3 = node->Son (4); + } else if (t3->isPointer () && t2->isArithmetic () && v1 && v1->isNull ()) { + result = castToType (t3, op2, true); + op2 = node->Son (2); + } else + SEM_ERROR__invalid_op (node, "conditional", "?:"); + node->setTypeRef (result); + } + } + + // handle constants + v1 = op1->Value () ? op1->Value ()->Constant () : 0; + if (v1) { + if (v1->isNull ()) + passOnConstant (op3, result); + else + passOnConstant (op2, result); + } + + return result; +} + + +// ���5.3.1.2 indirection operator +CTypeInfo *CCSemExpr::resolve (CT_DerefExpr *node, CTree *base) { + CTypeInfo *result, *t1, *oop; + bool dep_base; + + dep_base = resetDependent (); + + // resolve operands + t1 = resolve (node->Son (1), node); + + // handle dependent expressions + if (isDependent (node, dep_base)) + return &CTYPE_UNDEFINED; + + // apply lvalue-to-rvalue conversions + t1 = convLvalueToRvalue (node->Son (1)); + + // operator may be overloaded + dep_base = resetDependent (); + oop = overloadedOperator (node, base, "*", node->Son (0)->token ()->type (), node->Son (1)); + if (isDependent (node, dep_base)) + return &CTYPE_UNDEFINED; + else if (oop) + return oop; + else + t1 = node->Son (1)->Type (); + + // error diagnostics not yet complete! + + bool error = true; + if (! t1->isPointer ()) { + SEM_ERROR__invalid_op (node, "unary", "*"); + result = &CTYPE_UNDEFINED; + } else { + if (t1->VirtualType ()->BaseType ()->isVoid ()) { + SEM_ERROR (node, "dereferencing pointer to void"); + result = &CTYPE_UNDEFINED; + } + else + error = false; + } + + if (error) + node->setTypeRef (result); + else { + // if type is a class object type, ensure + // that the class is really instantiated + t1 = t1->VirtualType ()->BaseType ()->Duplicate (); + if (t1->UnqualType()->TypeClass()) { + t1->UnqualType()->TypeClass()->instantiate(current_scope); + } + result = new CTypeAddress (t1); + node->setType (result); + // transform the expression into a call expression with a built-in operator + // as the target function + t1 = node->Son (1)->Type (); + builtinOpExpr (node, base, "*", node->Son (0)->token ()->type (), result, t1); + } + return result; +} + + +// ���5.3.1.2 address operator +CTypeInfo *CCSemExpr::resolve (CT_AddrExpr *node, CTree *base) { + CTypeInfo *result, *t1, *oop; + CObjectInfo *info; + bool dep_base; + CTree *op1; + + dep_base = resetDependent (); + result = &CTYPE_UNDEFINED; + + // resolve operand + t1 = resolve (node->Son (1), node); + op1 = node->Son (1); + + // handle dependent expressions + if (isDependent (node, dep_base)) + return result; + + // operator may be overloaded + dep_base = resetDependent (); + oop = overloadedOperator (node, base, "&", node->Son (0)->token ()->type (), node->Son (1)); + if (isDependent (node, dep_base)) + return result; + else if (oop) + return oop; + else { + op1 = node->Son (1); + t1 = op1->Type (); + } + + // error diagnostics not yet complete! + + // address of class member + bool error = false; + if ((op1->NodeName () == CT_QualName::NodeId () || + op1->NodeName () == CT_RootQualName::NodeId ()) && + (info = ((CT_QualName*)op1)->Name ()->Object ()) && + info->isClassMember ()) { + if (info->isStatic ()) + result = new CTypePointer (t1->Duplicate ()); + else if (info->FunctionInfo ()) + result = new CTypeMemberPointer (t1->Duplicate (), + info->FunctionInfo ()->Record ()); + else if (info->AttributeInfo ()) + result = new CTypeMemberPointer (t1->Duplicate (), + info->AttributeInfo ()->Record ()); + node->setType (result); + // address of lvalue + } else if (isLvalue (op1)) { + if (t1->isAddress ()) + t1 = t1->BaseType (); + result = new CTypePointer (t1->Duplicate ()); + node->setType (result); + // neither class member nor lvalue + } else { + SEM_ERROR__invalid_op (node, "unary", "&"); + result = &CTYPE_UNDEFINED; + node->setTypeRef (result); + error = true; + } + + if (!error) { + // transform the expression into a call expression with a built-in operator + // as the target function + builtinOpExpr (node, base, "&", node->Son (0)->token ()->type (), result, t1); + } + + return result; +} + + +// ���5.4 explicit type conversion (cast notation) +CTypeInfo *CCSemExpr::resolve (CT_CastExpr *node, CTree *base) { + CTypeInfo *result, *t1; + bool dep_base; + + dep_base = resetDependent (); + + // resolve operands + t1 = resolve (node->Expr (), node); + + // let casts yield a type independently of the + // dependence of its operand (_not_ standard + // conform but safe to do) + + // handle dependent expressions + //if (isDependent (node, dep_base)) + // return &CTYPE_UNDEFINED; + + // apply lvalue-to-rvalue conversions + if (! dependent) + t1 = convLvalueToRvalue (node->Expr ()); + + // error diagnostics not yet implemented! + + if (node->TypeName ()->Object ()) + result = node->TypeName ()->Object ()->TypeInfo (); + else + result = &CTYPE_UNDEFINED; + + // handle constants + if (! dependent) + passOnConstant (node->Expr (), result); + + // reset dependent state + if (dep_base) + dependent = true; + + node->setTypeRef (result); + return result; +} + + +// ���5.2.7 dynamic cast +CTypeInfo *CCSemExpr::resolve (CT_DynamicCast *node, CTree *base) { + CTypeInfo *result, *t1; + bool dep_base; + + dep_base = resetDependent (); + + // resolve operands + t1 = resolve (node->Expr (), node); + + // let casts yield a type independently of the + // dependence of its operand (_not_ standard + // conform but safe to do) + + // handle dependent expressions + //if (isDependent (node, dep_base)) + // return &CTYPE_UNDEFINED; + + // apply lvalue-to-rvalue conversions + + if (! dependent) + t1 = convLvalueToRvalue (node->Expr ()); + + // error diagnostics not yet implemented! + + if (node->TypeName ()->Object ()) + result = node->TypeName ()->Object ()->TypeInfo (); + else + result = &CTYPE_UNDEFINED; + + // reset dependent state + if (dep_base) + dependent = true; + + node->setTypeRef (result); + return result; +} + + +// ���5.2.9 static cast +CTypeInfo *CCSemExpr::resolve (CT_StaticCast *node, CTree *base) { + CTypeInfo *result, *t1; + bool dep_base; + + dep_base = resetDependent (); + + // resolve operands + t1 = resolve (node->Expr (), node); + + // let casts yield a type independently of the + // dependence of its operand (_not_ standard + // conform but safe to do) + + // handle dependent expressions + //if (isDependent (node, dep_base)) + // return &CTYPE_UNDEFINED; + + // apply lvalue-to-rvalue conversions + if (! dependent) + t1 = convLvalueToRvalue (node->Expr ()); + + // error diagnostics not yet implemented! + + if (node->TypeName ()->Object ()) + result = node->TypeName ()->Object ()->TypeInfo (); + else + result = &CTYPE_UNDEFINED; + + // handle constants + if (! dependent) + passOnConstant (node->Expr (), result); + + // reset dependent state + if (dep_base) + dependent = true; + + node->setTypeRef (result); + return result; +} + + +// ���5.2.10 reinterpret cast +CTypeInfo *CCSemExpr::resolve (CT_ReintCast *node, CTree *base) { + CTypeInfo *result, *t1; + bool dep_base; + + dep_base = resetDependent (); + + // resolve operands + t1 = resolve (node->Expr (), node); + + // let casts yield a type independently of the + // dependence of its operand (_not_ standard + // conform but safe to do) + + // handle dependent expressions + //if (isDependent (node, dep_base)) + // return &CTYPE_UNDEFINED; + + // apply lvalue-to-rvalue conversions + if (! dependent) + t1 = convLvalueToRvalue (node->Expr ()); + + // error diagnostics not yet implemented! + + if (node->TypeName ()->Object ()) + result = node->TypeName ()->Object ()->TypeInfo (); + else + result = &CTYPE_UNDEFINED; + + // handle constants + if (! dependent) + passOnConstant (node->Expr (), result); + + // reset dependent state + if (dep_base) + dependent = true; + + node->setTypeRef (result); + return result; +} + + +// ���5.2.11 const cast +CTypeInfo *CCSemExpr::resolve (CT_ConstCast *node, CTree *base) { + CTypeInfo *result, *t1; + bool dep_base; + + dep_base = resetDependent (); + + // resolve operands + t1 = resolve (node->Expr (), node); + + // let casts yield a type independently of the + // dependence of its operand (_not_ standard + // conform but safe to do) + + // handle dependent expressions + //if (isDependent (node, dep_base)) + // return &CTYPE_UNDEFINED; + + // apply lvalue-to-rvalue conversions + if (! dependent) + t1 = convLvalueToRvalue (node->Expr ()); + + // error diagnostics not yet implemented! + + if (node->TypeName ()->Object ()) + result = node->TypeName ()->Object ()->TypeInfo (); + else + result = &CTYPE_UNDEFINED; + + // handle constants + if (! dependent) + passOnConstant (node->Expr (), result); + + // reset dependent state + if (dep_base) + dependent = true; + + node->setTypeRef (result); + return result; +} + + +// ���15.1 throw expression +CTypeInfo *CCSemExpr::resolve (CT_ThrowExpr *node, CTree *base) { + CTypeInfo *result, *t1; + //unsigned long pos; + bool dep_base; + + result = &CTYPE_VOID; // a throw expression is of type void + + if (node->Expr ()) { + dep_base = resetDependent (); + + // resolve operands + t1 = resolve (node->Expr (), node); + + // handle dependent expressions + if (isDependent (node, dep_base)) { + node->setTypeRef (result); + return result; + } + + // apply lvalue-to-rvalue conversions + t1 = convLvalueToRvalue (node->Expr ()); + + // error diagnostics not yet complete! + + // if the exception type is a class object type, ensure + // that the class is really instantiated + if (t1->UnqualType()->TypeClass()) { + t1->UnqualType()->TypeClass()->instantiate(current_scope); + } + + //pos = node->token_node ()->Number (); + //if (! t1->isComplete (pos)) + // SEM_ERROR (node, "incomplete type in throw expression"); + } + + node->setTypeRef (result); + return result; +} + + +// ��5.2.8 type identification +CTypeInfo *CCSemExpr::resolve (CT_TypeidExpr *node, CTree *base) { + CTypeInfo *result, *t1; + + bool found_type_info = false; + CCNameLookup nl (err, current_scope); + // search namespace std + nl.lookupNamespace ("std", current_scope->SemDB ()->FileInfo (0)); + if (nl.Objects () == 1) { + CNamespaceInfo *std = (CNamespaceInfo*)nl.Object (0); + nl.reset (current_scope); + // search class type_info in namespace std + nl.lookupType ("type_info", std); + if (nl.Objects () == 1) + found_type_info = true; + } + + if (found_type_info) { + // get std::type_info's type + CTypeInfo *type_info = CTypeInfo::Duplicate (nl.Object ()->TypeInfo ()); + // qualify the type with 'const' + result = new CTypeQualified (type_info, true, false, false); + } else { + SEM_ERROR__must_include (node, "", "typeid"); + result = &CTYPE_UNDEFINED; + } + + // remember and reset the current dependent expression state + bool dep_base = resetDependent (); + + // resolve the sub-expression + if (node->Arg ()->NodeName () != CT_NamedType::NodeId ()) { + resolve (node->Arg (), node); + } + + // ensure that the type gets instantiated + t1 = node->Arg ()->Type (); + if (t1 && t1->UnqualType()->TypeClass()) { + t1->UnqualType()->TypeClass()->instantiate(current_scope); + } + + // reset dependent state + if (dep_base) + dependent = true; + + node->setTypeRef (result); + return result; +} + + +// ���5.3.3 sizeof expression +CTypeInfo *CCSemExpr::resolve (CT_SizeofExpr *node, CTree *base) { + U_LONG_LONG size; + CTypeInfo *result, *t1, *unqual; + CObjectInfo *info; + bool dep_base; + + dep_base = resetDependent (); + result = CTypeInfo::CTYPE_SIZE_T; // size_t + size = 0; + + // resolve operand; can be either expression or named type + if (node->TypeName ()) { // named type + info = node->TypeName ()->Object (); + t1 = info ? info->TypeInfo () : 0; + if (t1 && t1->isDependent ()) + dependent = true; + } else { + t1 = resolve (node->Expr (), node); + } + + // handle dependent expressions + if (isDependent (node, dep_base)) { + node->setTypeRef (result); + return result; + } + + // evaluation not yet complete! + + // sizeof op1; sizeof ( op1 ) + if (! t1 || t1->isFunction ()/* || ! t1->isComplete (pos)*/) { + SEM_ERROR__invalid_op (node, "unary", "sizeof"); + } else { + unqual = t1->UnqualType(); + if (unqual->is_char() || unqual->is_signed_char() || unqual->is_unsigned_char()) { + size = 1; // always 1 byte + } else { + if (unqual->TypeClass()) + unqual->TypeClass()->instantiate(current_scope); + size = t1->Size () / 8; // size in bytes + } + } + + node->setValue (new CConstant (size, result)); + node->setTypeRef (result); + return result; +} + + +// alignof expression +CTypeInfo *CCSemExpr::resolve (CT_AlignofExpr *node, CTree *base) { + unsigned long align; + CTypeInfo *result, *t1; + CObjectInfo *info; + bool dep_base; + + dep_base = resetDependent (); + result = CTypeInfo::CTYPE_SIZE_T; // size_t + align = 0; + + // resolve operand; can be either expression or named type + if (node->TypeName ()) { // named type + info = node->TypeName ()->Object (); + t1 = info ? info->TypeInfo () : 0; + } else { + t1 = resolve (node->Expr (), node); + //info = findObject (node->Expr ()); + } + + // handle dependent expressions + if (isDependent (node, dep_base)) { + node->setTypeRef (result); + return result; + } + + // evaluation not yet complete! + + // sizeof op1; sizeof ( op1 ) + if (! t1 || t1->isFunction ()/* || ! t1->isComplete (pos)*/) { + SEM_ERROR__invalid_op (node, "unary", "alignof"); + } else { + if (t1->UnqualType()->TypeClass()) + t1->UnqualType()->TypeClass()->instantiate(current_scope); + align = t1->Align (); // alignment in bytes + } + + // NOT CORRECT! TO BE FIXED! + if (! align) + align = 1; + + node->setValue (new CConstant ((LONG_LONG)align, result)); + node->setTypeRef (result); + return result; +} + + +// type trait expression +CTypeInfo *CCSemExpr::resolve (CT_TypeTraitExpr *node, CTree *base) { + CTypeInfo *result, *t1, *t2; + CObjectInfo *info; + bool value = false; + + result = &CTYPE_BOOL; + value = false; + + // get the type(s) + info = node->FirstType ()->Object (); + t1 = info ? info->TypeInfo () : 0; + t2 = 0; + if (node->SecondType ()) { + info = node->SecondType ()->Object (); + t2 = info ? info->TypeInfo () : 0; + } + + // evaluation not yet complete! + + // type_trait ( op1 ); type_trait ( op1 , op2 ) + if (! t1 /* || ! t1->isComplete (pos)*/) { + SEM_ERROR__invalid_op (node, "unary", Token::get_static_text (node->Operator ())); + } else { + CRecord* c1 = t1->isClassOrUnion () ? t1->VirtualType ()->TypeRecord ()->Record () : 0; + CRecord* c2 = t2 && t2->isClassOrUnion () ? t2->VirtualType ()->TypeRecord ()->Record () : 0; + switch (node->Operator ()) { + case TOK_HAS_NOTHROW_ASSIGN: + // TODO: No-throw not checked! Too expensive analysis! Also functions + // called in the operator shall not throw exceptions! + value = ! t1->isConst () && ! t1->isAddress () && + (t1->isPOD () || (c1 && c1->hasTrivialAssign ())); + break; + case TOK_HAS_NOTHROW_COPY: + // TODO: No-throw not checked! Too expensive analysis! Also functions + // called in the constructor shall not throw exceptions! + value = t1->isPOD () || t1->isAddress () || (c1 && c1->hasTrivialCopy ()); + break; + case TOK_HAS_NOTHROW_CTOR: + // TODO: No-throw not checked! Too expensive analysis! Also functions + // called in the constructor shall not throw exceptions! + value = t1->isPOD () || (c1 && c1->hasTrivialCtor ()); + break; + case TOK_HAS_TRIVIAL_ASSIGN: + value = ! t1->isConst () && ! t1->isAddress () && + (t1->isPOD () || (c1 && c1->hasTrivialAssign ())); + break; + case TOK_HAS_TRIVIAL_COPY: + value = t1->isPOD () || t1->isAddress () || (c1 && c1->hasTrivialCopy ()); + break; + case TOK_HAS_TRIVIAL_CTOR: + value = t1->isPOD () || (c1 && c1->hasTrivialCtor ()); + break; + case TOK_HAS_TRIVIAL_DTOR: + value = t1->isPOD () || t1->isAddress () || (c1 && c1->hasTrivialDtor ()); + break; + case TOK_HAS_VIRTUAL_DTOR: + value = c1 && c1->ClassInfo () && c1->ClassInfo ()->hasVirtualDtor (); + break; + case TOK_IS_ABSTRACT: + value = c1 && c1->ClassInfo () && c1->ClassInfo ()->isAbstract (); + break; + case TOK_IS_BASE_OF: + value = c1 && c2 && c1->ClassInfo () && c2->ClassInfo () && + ((*c1 == *c2) || c2->ClassInfo ()->isBaseClass (c1->ClassInfo (), true)); + break; + case TOK_IS_CLASS: + value = t1->isClass (); + break; + case TOK_IS_EMPTY: + value = c1 && c1->ClassInfo () && c1->ClassInfo ()->isEmpty (); + break; + case TOK_IS_ENUM: + value = t1->isEnum (); + break; + case TOK_IS_POD: + value = t1->isPOD (); + break; + case TOK_IS_TRIVIAL: + value = t1->isTrivial (); + break; + case TOK_IS_POLYMORPHIC: + value = c1 && c1->ClassInfo () && c1->ClassInfo ()->isPolymorphic (); + break; + case TOK_IS_UNION: + value = t1->isUnion (); + break; + default: + break; + } + } + + node->setValue (new CConstant ((LONG_LONG)value, result)); + node->setTypeRef (result); + return result; +} + + +// offsetof expression +CTypeInfo *CCSemExpr::resolve (CT_OffsetofExpr *node, CTree *base) { + unsigned long offset; + CTypeInfo *result; + + // TODO: calculate the offset in bytes of the given member + offset = 0; + result = CTypeInfo::CTYPE_SIZE_T; + + node->setValue (new CConstant ((LONG_LONG)offset, result)); + node->setTypeRef (result); + return result; +} + + +// ���5.2.1 subscripting +CTypeInfo *CCSemExpr::resolve (CT_IndexExpr *node, CTree *base) { + CTypeInfo *result, *t1, *t2, *oop; + bool dep_base; + int oper; + + oper = node->Son (1)->token ()->type (); + dep_base = resetDependent (); + + // resolve operands + t1 = resolve (node->Son (0), node); + t2 = resolve (node->Son (2), node); + + // handle dependent expressions + if (isDependent (node, dep_base)) + return &CTYPE_UNDEFINED; + + // apply lvalue-to-rvalue conversions + t1 = convLvalueToRvalue (node->Son (0)); + + // operator may be overloaded + dep_base = resetDependent (); + oop = overloadedOperator (node, base, "[]", oper, node->Son (0), node->Son (2)); + if (isDependent (node, dep_base)) + return &CTYPE_UNDEFINED; + else if (oop) + return oop; + else { + t1 = node->Son (0)->Type (); + t2 = node->Son (2)->Type (); + } + + // subscripting: op1 [ op2 ] + bool error = true; + if (! t1->isPointer () || ! t2->isInteger ()) { + SEM_ERROR__invalid_op (node, "array subscript", "[]"); + result = &CTYPE_UNDEFINED; + } else + error = false; + + if (error) + node->setTypeRef (result); + else { + result = new CTypeAddress (t1->VirtualType ()->BaseType ()->Duplicate ()); + node->setType (result); + // transform the expression into a call expression with a built-in operator + // as the target function + t1 = node->Son (0)->Type (); + builtinOpExpr (node, base, "[]", oper, result, t1, t2); + } + return result; +} + + +// ���5.1.5 parenthesized expression +CTypeInfo *CCSemExpr::resolve (CT_BracedExpr *node, CTree *base) { + CTypeInfo *result; + bool dep_base; + + dep_base = resetDependent (); + + // resolve operands + result = resolve (node->Expr (), node); + + // handle dependent expressions + if (isDependent (node, dep_base)) + return &CTYPE_UNDEFINED; + + // handle constants + passOnConstant (node->Expr (), result); + + node->setTypeRef (result); + return result; +} + + +// ���2.13.5 boolean literal +CTypeInfo *CCSemExpr::resolve (CT_Bool *node, CTree *base) { + CTypeInfo *result; + U_LONG_LONG v; + + v = (strcmp (node->Son (0)->token ()->text (), "true") == 0) ? 1 : 0; + result = &CTYPE_BOOL; + + node->setValue (new CConstant (v, result)); + node->setTypeRef (result); + return result; +} + + +// ���2.13.2 character literal +CTypeInfo *CCSemExpr::resolve (CT_Character *node, CTree *base) { + CTypeInfo *result; + LONG_LONG v; + int chars; + + chars = scanCharacter (node, v); + if (chars == 1) { // character constant + result = &CTYPE_CHAR; + v = (char)v; + } else { // integer character constant + if (chars > 4) { + SEM_ERROR (node, "integer character constant too long"); + } else { + SEM_WARNING (node, "multi-character character constant"); + } + result = &CTYPE_INT; + v = (int)v; + } + + node->setValue (new CConstant (v, result)); + node->setTypeRef (result); + return result; +} + + +// ���2.13.2 wide character literal +CTypeInfo *CCSemExpr::resolve (CT_WideCharacter *node, CTree *base) { + CTypeInfo *result; + LONG_LONG v; + int chars; + + chars = scanCharacter (node, v); + if (chars == 1) { + result = &CTYPE_WCHAR_T; + v = (wchar_t)v; + } else { + if (chars > 4) { + SEM_ERROR (node, "integer character constant too long"); + } else { + SEM_WARNING (node, "multi-character character constant"); + } + result = &CTYPE_INT; + v = (int)v; + } + + node->setValue (new CConstant (v, result)); + node->setTypeRef (result); + return result; +} + + +// ���2.13.4 string literal +CTypeInfo *CCSemExpr::resolve (CT_String *node, CTree *base) { + CTypeInfo *result; + const char *s, *e; + char *p, *buf; + long int ct; + LONG_LONG i; + bool ucs; + + // create string buffer + i = 0; + for (int t = 0; t < node->Sons (); t++) { + s = node->Son (t)->token ()->text (); + i += strlen (s) - 2; + } + buf = new char[i+10]; + + // collect the string characters from all tokens + buf[0] = '\0'; + ct = 0; + for (int t = 0; t < node->Sons (); t++) { + s = node->Son (t)->token ()->text (); + + i = strlen (s); + if (s[0] == '"') { + s++; + i--; + if (s[i-1] == '"') + i--; + } + e = &s[i]; + + p = buf + strlen (buf); + while (s && *s && s != e) { + i = nextCharacter (s, ucs); + if (ucs && i == (LONG_LONG)-1) { + SEM_ERROR (node, "incomplete universal character"); + break; + } + if (ucs) { + // turn the char value into a utf-8 octet stream + utf8_encode (i, p, ct); + } + else { + if (i > UCHAR_MAX) + SEM_WARNING__out_of_range (node, "escape sequence"); + *p++ = (char)(i&0xff); + ct++; + } + } + + *p++ = 0; + *p = 0; + } + + // type `array of const char' + result = new CTypeQualified (&CTYPE_CHAR, true, false, false); + result = new CTypeArray (result); + result->TypeArray ()->Dimension (ct+1); + node->setValue (new CStrLiteral (buf, ct, result)); + node->setType (result); + + return result; +} + + +// ���2.13.4 wide string literal +CTypeInfo *CCSemExpr::resolve (CT_WideString *node, CTree *base) { + CTypeInfo *result; + const char *s, *e; + wchar_t *p, *buf; + long int ct; + LONG_LONG i; + bool ucs; + + // create string buffer + i = 0; + for (int t = 0; t < node->Sons (); t++) { + s = node->Son (t)->token ()->text (); + if (*s == 'L') + s++; + i += strlen (s) - 2; + } + buf = new wchar_t[i+2]; + + // collect the string characters from all tokens + buf[0] = L'\0'; + ct = 0; + for (int t = 0; t < node->Sons (); t++) { + s = node->Son (t)->token ()->text (); + if (*s == 'L') + s++; + + i = strlen (s); + if (s[0] == '"') { + s++; + i--; + if (s[i-1] == '"') + i--; + } + e = &s[i]; + + p = buf + wcslen (buf); + while (s && *s && s != e) { + i = nextCharacter (s, ucs); + if (ucs && i == (LONG_LONG)-1) { + SEM_ERROR (node, "incomplete universal character"); + break; + } + if (i > ULONG_MAX) + SEM_WARNING__out_of_range (node, "escape sequence"); + *p++ = (wchar_t)(i&0xffffffff); + ct++; + } + + *p++ = 0; + *p = 0; + } + + // type `array of const wchar_t' + result = new CTypeQualified (&CTYPE_WCHAR_T, true, false, false); + result = new CTypeArray (result); + result->TypeArray ()->Dimension (ct+1); + node->setValue (new CWStrLiteral (buf, ct, result)); + node->setType (result); + + return result; +} + + +// ���2.13.1 integer literal +CTypeInfo *CCSemExpr::resolve (CT_Integer *node, CTree *base_node) { + bool uns, lng, lnglng, trunc; + U_LONG_LONG val, max, i; + CTypeInfo *result; + const char *s; + int base; + + s = node->Son (0)->token ()->text (); + if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) { + base = 16; + s += 2; + } else if (s[0] == '0' && isdigit (s[1])) { + base = 8; + s++; + } else + base = 10; + + val = 0; + max = (ULLONG_MAX / base) + (ULLONG_MAX % base); + uns = lng = lnglng = trunc = false; + + while (isxdigit (*s)) { + if (isdigit (*s)) + i = *s - '0'; + else if (*s >= 'A' && *s <= 'F') + i = *s - 'A' + 10; + else + i = *s - 'a' + 10; + s++; + if (! trunc && ((val + i) > max || ((val + i) == max && isxdigit (*s)))) { + trunc = true; + SEM_WARNING (node, "integer constant is too large" << + " - truncated to " << CTYPE_UNSIGNED_LONG_LONG.Size() << " bits"); + } + val = (val * base) + i; + } + + while (*s != 0) { + if (*s == 'u' || *s == 'U') + uns = true; + else if (*s == 'l' || *s == 'L') { + if (lng) { + lng = false; + lnglng = true; + } else + lng = true; + } + s++; + } + + // determine type and handle overflows + long int size = CTypePrimitive::SizeOfNumber (val); + if (lnglng) { + if (! uns && size > CTYPE_LONG_LONG.Size()) + overflow (node, base, uns); + } else if (uns && lng) { + if (size > CTYPE_UNSIGNED_LONG.Size()) { + lng = false; + lnglng = true; + } + } else if (lng) { + if (size > CTYPE_LONG_LONG.Size()) + overflow (node, base, uns); + else if ((base != 10 && size > CTYPE_UNSIGNED_LONG.Size()) || + (base == 10 && size > CTYPE_LONG.Size())) { + lng = false; + lnglng = true; + } else if (base != 10 && size > CTYPE_LONG.Size()) + overflow (node, base, uns); + } else if (uns) { + if (size > CTYPE_UNSIGNED_LONG.Size()) + lnglng = true; + else if (size > CTYPE_UNSIGNED_INT.Size()) + lng = true; + } else { + if (size > CTYPE_LONG_LONG.Size()) { + overflow (node, base, uns); + if (base != 10) + lnglng = true; + } else if ((base != 10 && size > CTYPE_UNSIGNED_LONG.Size()) || + (base == 10 && size > CTYPE_LONG.Size())) { + lnglng = true; + } else if (base != 10 && size > CTYPE_LONG.Size()) { + overflow (node, base, uns); + lng = true; + } else if ((base != 10 && size > CTYPE_UNSIGNED_INT.Size()) || + (base == 10 && size > CTYPE_INT.Size())) { + lng = true; + } else if (size > CTYPE_INT.Size()) + overflow (node, base, uns); + } + + // set type + if (uns && lnglng) + result = &CTYPE_UNSIGNED_LONG_LONG; + else if (lnglng) + result = &CTYPE_LONG_LONG; + else if (uns && lng) + result = &CTYPE_UNSIGNED_LONG; + else if (lng) + result = &CTYPE_LONG; + else if (uns) + result = &CTYPE_UNSIGNED_INT; + else + result = &CTYPE_INT; + + node->setValue (uns ? new CConstant ((U_LONG_LONG)val, result) : + new CConstant ((LONG_LONG)val, result)); + node->setTypeRef (result); + return result; +} + + +void CCSemExpr::overflow (CTree *node, int base, bool &uns) const { + if (base == 10) + SEM_WARNING__is_unsigned (node); + uns = true; +} + + +// ���2.13.3 floating literal +CTypeInfo *CCSemExpr::resolve (CT_Float *node, CTree *base) { + CTypeInfo *result; + long double v; + bool lng, flt; + const char *s; + int ln; + + s = node->Son (0)->token ()->text (); + ln = strlen (s); + + lng = (s[ln-1] == 'l' || s[ln-1] == 'L'); + flt = (s[ln-1] == 'f' || s[ln-1] == 'F'); + + v = strtod(s, NULL); + + if (lng) + result = &CTYPE_LONG_DOUBLE; + else if (flt) + result = &CTYPE_FLOAT; + else + result = &CTYPE_DOUBLE; + + node->setValue (new CConstant (v, result)); + node->setTypeRef (result); + return result; +} + + +/////////////////////////////////////////////////////// +// ���8.5 initializers ////////////////////////////////// +/////////////////////////////////////////////////////// + + +CTypeInfo *CCSemExpr::resolveInit (CTree *node, CTree *base) { + CTypeInfo *result; + bool dep_base; + + // evaluation not yet complete! + // error diagnostics not yet implemented! + + // get object type + CObjectInfo* obj = base->SemObject () ? base->SemObject ()->Object () : 0; + CTypeInfo* otype = &CTYPE_UNDEFINED; + if (obj && obj->TypeInfo ()) { + otype = obj->TypeInfo (); + } + + if (node->NodeName () == CT_ExprList::NodeId ()) { + CT_ExprList *list = (CT_ExprList*)node; + unsigned entries = list->Entries (); + + // = { init_list } + if (node->end_token ()->type () == TOK_CLOSE_CURLY) { + dep_base = resetDependent (); + // handle arrays of unknown size; count the top-level elements + // (all but the first array dimension must be given) + CTypeArray* array = otype->VirtualType ()->TypeArray (); + if (array && ! array->hasDimension ()) { + // set the first dimension of the array + // also update type of linked objects + CObjectInfo* curr = obj; + do { + array = curr->TypeInfo ()->VirtualType ()->TypeArray (); + if (array) + array->Dimension (entries); + curr = curr->NextObject (); + } while (curr != obj); + } + // has target type + result = otype; + if (node->SemValue ()) + node->SemValue ()->setTypeRef (result); + // reset dependent state + if (dep_base) + dependent = true; + // ( expr_list ) + } else if (node->token ()->type () == TOK_OPEN_ROUND) { + dep_base = resetDependent (); + // resolve initializer arguments + for (unsigned i = 0; i < entries; i++) + resolveExpr (list->Entry (i), list); + // has target type + result = otype; + if (node->SemValue ()) + node->SemValue ()->setTypeRef (result); + // reset dependent state + if (dep_base) + dependent = true; + // = ass_expr + } else { + dep_base = resetDependent (); + // resolve initializer arguments + for (unsigned i = 0; i < entries; i++) + resolveExpr (list->Entry (i), list); + // handle dependent expressions + if (isDependent (node, dep_base)) + return &CTYPE_UNDEFINED; + + // set type and value + CTree *last = list->Entry (entries-1); + passOnConstant (last, 0); + if (last->Type ()) + result = last->Type (); + else + result = &CTYPE_UNDEFINED; + if (node->SemValue ()) + node->SemValue ()->setTypeRef (result); + } + // ass_expr + } else { + dep_base = resetDependent (); + result = resolveExpr (node, base); + // handle dependent expressions + if (isDependent (node, dep_base)) + return &CTYPE_UNDEFINED; + } + + return result; +} + + +/////////////////////////////////////////////////////// +// ���13.3.1.2 operator overloading ///////////////////// +/////////////////////////////////////////////////////// + + +// ���13.3.1.2 operator overloading +CTypeInfo *CCSemExpr::overloadedOperator (CTree *node, CTree *base, + const char *op, int oper, CTree *arg0, CTree *arg1) { + CTypeInfo *t0, *t1 = 0, *type = 0; + CCandidateInfo *cand; + CFunctionInfo *finfo; + CRecord *cinfo; + char opname[1000]; // enough space for every possible operator name + + t0 = arg0->Type (); + if (arg1) + t1 = arg1->Type (); + + // ���13.3.1.2.2 at least one operand must have class or enumeration type + if (! isClassOrEnum (t0) && ! isClassOrEnum (t1)) + return 0; + + // operator call depends on dependent operators + if (t0->isDependent () || (t1 && t1->isDependent ())) { + dependent = true; + return 0; + } + + // operator may be overloaded; collect the candidates + // for overload resolution + CCOverloading ovl (err, true); + + // create the full operator name for name lookup purposes + sprintf (opname, "operator %s", op); + + // ���13.3.1.2.3 if first operand has class type, overloaded + // operator may be a class member (member candidates) + if (t0->isRecord () && oper != TOK_QUESTION) { + cinfo = t0->VirtualType ()->TypeRecord ()->Record (); + if (cinfo) { + // ensure that class is instantiated + if (cinfo->ClassInfo ()) + cinfo->TypeInfo ()->TypeClass ()->instantiate (current_scope); + // lookup operator name in object's class + CCNameLookup nl (err, current_scope); + nl.lookup (opname, cinfo, false, true); + // add candidates looked up + ovl.addCandidates (nl); + } + } + + // collect non-member candidates doing a special unqualified + // name lookup ignoring all member functions + unsigned curr_pos = node->token_node ()->Number (); + CCNameLookup nl (err, current_scope); + nl.lookupOpName (opname, current_scope, curr_pos); + + // additionally do an argument-dependent name lookup + CCAssocScopes scopes; + scopes.determineAssocScopes (t0); + if (t1) + scopes.determineAssocScopes (t1); + if (scopes.Namespaces ()) + for (unsigned i = 0; i < scopes.Namespaces (); i++) + nl.lookupInAssNs (opname, scopes.Namespace (i), curr_pos); + + if (nl.Objects () && oper != TOK_QUESTION) { + // if no operand has a class type, only those functions that + // have a first parameter of type "t0" or "reference to cv t0" + // (when enumeration type), or a second parameter of type "t1" + // or type "reference to cv t1" + if (! t0->isRecord () && (! t1 || ! t1->isRecord ())) { + for (unsigned i = 0; i < nl.Objects (); i++) { + finfo = nl.Object (i)->FunctionInfo (); + if (finfo) { + if (! finfo->Arguments ()) + continue; + if (t0->isEnum ()) { + type = finfo->Argument ((unsigned)0)->TypeInfo (); + if (*type->VirtualType () == *t0->VirtualType ()) + ovl.addCandidate (finfo); + } else if (t1 && t1->isEnum () && finfo->Arguments () > 1) { + type = finfo->Argument ((unsigned)1)->TypeInfo (); + if (*type->VirtualType () == *t1->VirtualType ()) + ovl.addCandidate (finfo); + } + } + } + } else + ovl.addCandidates (nl); + } + + // create and add built-in candidates + CSemDatabase *db = current_scope->SemDB (); + ovl.createBuiltinOperators (db, opname, oper, arg0, arg1); + + // let overload resolution know the qualification + // of the object the operator is called on + CTypeInfo *qt0 = t0; + while (qt0->isAddress ()) + qt0 = qt0->BaseType (); + if (qt0->isRecord () && qt0->isQualified ()) + ovl.ObjectType (t0); + + // do overload resolution + if (arg1) // base node of arguments + ovl.resolve ((node == arg0 && base ? base : node), arg0, arg1); + else + ovl.resolve ((node == arg0 && base ? base : node), arg0); + + // check result of overload resolution + if (ovl.Function ()) { + // operator call is overloaded + if (validOvlFctSet (node, "overloaded operator", opname, ovl)) { + finfo = ovl.Function (); + type = finfo->ReturnType (); + if (!type || *type == CTYPE_EMPTY) // no return type??? + type = &CTYPE_UNDEFINED; + + // apply the operand conversions determined by + // overload resolution + cand = ovl.Candidate (0); + for (unsigned i = 0; i < cand->ConvSequences (); i++) + cand->ConvSequence (i)->Apply (); + + // if not resolved to a built-in operator + if (! finfo->isBuiltin ()) { + if (base && base->NodeName () == CT_MembPtrExpr::NodeId ()) { + // A member pointer expr can trigger a sequence of operator->() calls. + // In order to avoid loss of information ImplicitCall nodes are created. + CT_ImplicitCall *call = new CT_ImplicitCall (node); + call->Object (finfo); + call->setTypeRef (type); + base->ReplaceSon (node, call); + } + else { + if (node->SemValue ()) { + node->SemValue ()->setTypeRef (type); + } + if (node->SemObject ()) { + node->SemObject ()->Object (finfo); + } + } + return type; + } + } + // overloaded operator depends on a template parameter + } else if (ovl.isDependent ()) + dependent = true; + + // operator call is not overloaded + return 0; +} + + +/////////////////////////////////////////////////////// +// constant expression //////////////////////////////// +/////////////////////////////////////////////////////// + + +// ���5.19 integer constant expression +bool CCSemExpr::isConstIntExpr (CTree *node) { + if (isConstIntegralExpr (node) && + node->Type () && node->Type ()->isInteger () && + node->Value () && node->Value ()->Constant ()) + return true; + return false; +} + + +// ���5.19 integer constant expression +bool CCSemExpr::isConstIntegralExpr (CTree *node) { + const char *id = node->NodeName (); + CObjectInfo *info; + int oper; + + // - literals + if (id == CT_Bool::NodeId () || + id == CT_Character::NodeId () || + id == CT_WideCharacter::NodeId () || + id == CT_Integer::NodeId () || + // not correct: only allowed if casted to integral + // or enumeration type; to be corrected!!! + id == CT_Float::NodeId ()) { + return true; + // - enumerators + // - const variables + // - static data members of intergral or enumeration type + // initialized with const expression + // - non-type template parameters of integral or enumeration type + // - no functions, class objects, pointers, and references + } else if (id == CT_SimpleName::NodeId () || + id == CT_OperatorName::NodeId () || + id == CT_DestructorName::NodeId () || + id == CT_ConversionName::NodeId () || + id == CT_TemplateName::NodeId ()) { + info = ((CT_SimpleName*)node)->Name ()->Object (); + if (info) { + if (info->EnumeratorInfo ()) + return true; + if (info->TemplateParamInfo () && + ! info->TemplateParamInfo ()->isTypeParam () && + info->TypeInfo ()->isInteger ()) + return true; + if (info->AttributeInfo () && + ! info->TypeInfo ()->isPointer () && + ! info->TypeInfo ()->isAddress ()) { + if (! info->AttributeInfo ()->Record () && + info->TypeInfo ()->isConst ()) + return true; + if (info->AttributeInfo ()->Record () && + info->isStatic () && info->TypeInfo ()->isInteger ()) { + CTree* init = info->AttributeInfo ()->DefObject ()->Init (); + if (init && isConstIntegralExpr (init)) + return true; + } + } + } + } else if (id == CT_QualName::NodeId () || + id == CT_RootQualName::NodeId ()) { + return isConstIntegralExpr (((CT_QualName*)node)->Name ()); + } else if (id == CT_SizeofExpr::NodeId () || + id == CT_AlignofExpr::NodeId () || + id == CT_TypeTraitExpr::NodeId () || + id == CT_OffsetofExpr::NodeId ()) { + return true; + // - no assignment and comma operators + } else if (id == CT_BinaryExpr::NodeId ()) { + oper = node->Son (1)->token ()->type (); + if (oper == TOK_ASSIGN || oper == TOK_MUL_EQ || oper == TOK_DIV_EQ || + oper == TOK_MOD_EQ || oper == TOK_ADD_EQ || oper == TOK_SUB_EQ || + oper == TOK_RSH_EQ || oper == TOK_LSH_EQ || oper == TOK_AND_EQ || + oper == TOK_XOR_EQ || oper == TOK_IOR_EQ || oper == TOK_COMMA) + return false; + return isConstIntegralExpr (node->Son (0)) && + isConstIntegralExpr (node->Son (2)); + // no increment and decrement operators + } else if (id == CT_PostfixExpr::NodeId ()) { + oper = node->Son (1)->token ()->type (); + if (oper == TOK_DECR || oper == TOK_INCR) + return false; + return isConstIntegralExpr (node->Son (0)); + // no increment and decrement operators + } else if (id == CT_UnaryExpr::NodeId ()) { + oper = node->Son (0)->token ()->type (); + if (oper == TOK_DECR || oper == TOK_INCR) + return false; + return isConstIntegralExpr (node->Son (1)); + } else if (id == CT_IfThenExpr::NodeId ()) { + CT_IfThenExpr *ite = (CT_IfThenExpr*)node; + return isConstIntegralExpr (ite->Condition ()) && + (ite->LeftOperand () ? + isConstIntegralExpr (ite->LeftOperand ()) : true) && + isConstIntegralExpr (ite->RightOperand ()); + } else if (id == CT_CastExpr::NodeId ()) { + return isConstIntegralExpr (node->Son (3)); + } else if (id == CT_ConstructExpr::NodeId ()) { + CT_ConstructExpr *ce = (CT_ConstructExpr*)node; + CObjectInfo *info = ce->TypeName ()->Object (); + if (info && info->TypeInfo () && ! info->TypeInfo ()->isRecord () && + ce->Initializer ()->Entries () == 1) + return isConstIntegralExpr (ce->Initializer ()->Entry (0)); + } else if (id == CT_BracedExpr::NodeId ()) { + return isConstIntegralExpr (node->Son (1)); + } else if (id == CT_ImplicitCast::NodeId ()) { + return isConstIntegralExpr (node->Son (0)); + } else if (id == CT_StaticCast::NodeId () || + id == CT_ReintCast::NodeId ()) + return isConstIntegralExpr (node->Son (4)); + return false; +} + + +// ���5.19 constant expressions +bool CCSemExpr::isConstExpr (CTree *node) { + return isConstIntegralExpr (node); +} + + +/////////////////////////////////////////////////////// +// helper ///////////////////////////////////////////// +/////////////////////////////////////////////////////// + + +void CCSemExpr::apply_binary_op (CTree *node, int oper) { + CConstant *v1, *v2; + CTree *op1, *op2; + + op1 = node->Son (0); + op2 = node->Son (2); + + // apply operator on constant values if any + v1 = op1->Value () ? op1->Value ()->Constant () : (CConstant*)0; + v2 = op2->Value () ? op2->Value ()->Constant () : (CConstant*)0; + if (v1 && v2 && node->SemValue ()) + node->SemValue ()->setValue (v1->compute (oper, v2)); +} + + +int CCSemExpr::scanCharacter (CTree *node, LONG_LONG &v) const { + const char *s; + const char *t; + LONG_LONG ch; + int i, j; + int wid = 8; + bool ucs; + + s = node->Son (0)->token ()->text (); + if (*s == 'L') { + wid = MB_LEN_MAX; + s++; + } + + i = strlen (s); + if (s[0] == '\'') { + s++; + i--; + if (s[i-1] == '\'') + i--; + } + t = &s[i]; + + v = 0; + for (j = 0; j < 4; j++) { + ch = nextCharacter (s, ucs); + if (ucs && i == (LONG_LONG)-1) { + SEM_ERROR (node, "incomplete universal character"); + break; + } + if ((wid == 8 && ch > UCHAR_MAX) || + (wid == MB_LEN_MAX && ch > ULONG_MAX)) + SEM_WARNING__out_of_range (node, "escape sequence"); + v = (v << wid) | ch; + if (s == NULL || *s == 0 || s == t) + break; + } + + return j + 1; +} + + +LONG_LONG CCSemExpr::nextCharacter (const char *&s, bool &ucs) const { + LONG_LONG ch, v; + ucs = false; + + ch = *s++; + if (ch == '\\') { + ch = *s++; + if (ch >= '0' && ch <= '7') { + v = ch - '0'; + if (*s >= '0' && *s <= '7') { + v = (v<<3) + *s++ - '0'; + if (*s >= '0' && *s <= '7') + v = (v<<3) + *s++ - '0'; + } + ch = v; + } else if (ch == 'x') { + v = 0; + while (true) { + if (isdigit (*s)) + v = (v<<4) + *s++ - '0'; + else if (*s >= 'a' && *s <= 'f') + v = (v<<4) + *s++ - 'a' + 10; + else if (*s >= 'A' && *s <= 'F') + v = (v<<4) + *s++ - 'A' + 10; + else + break; + } + ch = v; + } else if (ch == 'u' || ch == 'U') { + ucs = true; + ch = utf8_scan (s, ch == 'U'); + } else { + switch (ch) { + case 'n': ch = '\n'; break; + case 'b': ch = '\b'; break; + case 'r': ch = '\r'; break; + case 't': ch = '\t'; break; + case 'f': ch = '\f'; break; + case 'v': ch = '\v'; break; + case 'a': ch = '\a'; break; + default : break; + } + } + } + return ch; +} + + +bool CCSemExpr::sameOrBaseClass (CRecord *c1, CRecord *c2) { + if (! (c1 && c2)) + return false; + if (*c1 == *c2) + return true; + return baseClass (c1->ClassInfo (), c2->ClassInfo ()); +} + + +bool CCSemExpr::baseClass (CClassInfo *c1, CClassInfo *c2) { + CClassInfo *baseclass; + if (! (c1 && c2)) + return false; + + c2 = c2->DefObject ()->ClassInfo (); + for (unsigned i = 0; i < c2->BaseClasses (); i++) { + baseclass = c2->BaseClass (i)->Class (); + if (*c1 == *baseclass || baseClass (c1, baseclass)) + return true; + } + return false; +} + + +bool CCSemExpr::sameUnqualBaseType (CTypeInfo *t1, CTypeInfo *t2) const { + return *t1->VirtualType ()->BaseType ()->UnqualType () == + *t2->VirtualType ()->BaseType ()->UnqualType (); +} + + +// check result of function overload resolution +bool CCSemExpr::validOvlFctSet (CTree *node, const char *what, + const char *name, CCOverloading &ovl) { + CTemplateInstance *inst; + CObjectInfo *info; + CTree *arg = 0; + + // more than one candidate left + if (ovl.isAmbiguous () && ! ovl.isDependent ()) { + std::ostringstream fname; + fname << name << " ("; + for (unsigned i = 0; i < ovl.Arguments (); i++) { + arg = ovl.Argument (i); + if (arg && arg->Type ()) + arg->Type ()->TypeText (fname); + else + fname << ""; + if (i+1 < ovl.Arguments ()) + fname << ","; + } + fname << ")"; + + SEM_ERROR (node, "call to " << what << " `" << fname.str ().c_str () << "' is ambiguous"); + + for (unsigned i = 0; i < ovl.Candidates (); i++) { + info = ovl.Candidate (i)->Function (); + inst = info->TemplateInstance (); + if (inst) { + info = inst->Template ()->ObjectInfo (); + } + if (info->Tree () && info->Tree ()->token ()) + err << info->Tree ()->token ()->location (); + else if (node->token ()) + err << node->token ()->location (); + if (i == 0) + err << "candidates are: "; + else + err << " "; + std::ostringstream sig; + info->TypeInfo ()->TypeText (sig, info->Name ()); + if (inst) { + sig << " [with "; + for (unsigned j = 0; j < inst->DeducedArgs (); j++) { + DeducedArgument *darg = inst->DeducedArg (j); + if (j != 0) + sig << ", "; + if (darg->Type ()) + darg->TemplateParam ()->TypeInfo ()->TypeText (sig); + else + darg->TemplateParam ()->ValueType ()->TypeText (sig, darg->TemplateParam ()->Name ()); + sig << " = "; + if (darg->Type ()) + darg->Type ()->TypeText (sig); + else if (darg->Value ()) + darg->Value ()->print (sig); + else + sig << ""; + } + sig << "]"; + } + err << sig.str ().c_str (); + if (info->isBuiltin ()) + err << " "; + err << endMessage; + } + return false; + // no matching function + } else if (! ovl.Function () && ! ovl.isDependent ()) { + SEM_ERROR (node, "no matching function for call to `" << name << "'"); + return false; + // dependent call + } else if (ovl.isDependent ()) { + dependent = true; + return false; + // delayed parse problem + } else if (ovl.Function () && ovl.Candidate(0)->hasDelayedParseProblem ()) { + SEM_ERROR (node, "a default argument of called template function instance '" << ovl.Function()->Name () + << "' has not yet been parsed"); + return false; + } + return true; +} + + +// check result of looking up a name +bool CCSemExpr::checkDeclsFound (CTree *node, CCNameLookup &nl) const { + CObjectInfo *info; + + // ���3.4.1 if more than one declaration was + // found they shall all belong to functions + if (false && nl.Objects () > 1) { + for (unsigned i = 0; i < nl.Objects (); i++) { + info = nl.Object (i); + if (info->FunctionInfo ()) + continue; + + SEM_ERROR (node, "`" << *info->TypeInfo () + << "' is not a function,"); + for (unsigned j = 0; j < nl.Objects (); j++) { + if (j == i) + continue; + info = nl.Object (j); + if (info->Tree () && info->Tree ()->token ()) + err << info->Tree ()->token ()->location (); + if (i == 0) + err << "conflict with "; + else + err << " "; + err << "`" << *info->TypeInfo () << "'" << endMessage; + } + nl.reset (current_scope); + return false; + } + } + return true; +} + + +bool CCSemExpr::isClassOrEnum (CTypeInfo *type) const { + return type && (type->isRecord () || type->isEnum ()); +} + + +// check if any sub expression of a given expression +// depends on a template parameter +static bool isDependentInternal (CTree *expr, std::set& inits) { + CObjectInfo* info; + unsigned sons; + CTree* init; + + if (! expr) + return false; + + // expression has dependent type + if (expr->Type () && expr->Type ()->isDependent ()) + return true; + + // value of variable is dependent + if (expr->NodeName () == CT_SimpleName::NodeId ()) { + info = ((CT_SimpleName*)expr)->Name ()->Object (); + if (info && info->AttributeInfo ()) { + init = info->AttributeInfo ()->DefObject ()->Init (); + if (init && inits.count(init)==0) { + inits.insert(init); + if (isDependentInternal (init, inits)) + return true; + } + } + } + + sons = expr->Sons (); + for (unsigned i = 0; i < sons; i++) + if (isDependentInternal (expr->Son (i), inits)) + return true; + + return false; +} + + +bool CCSemExpr::isDependent (CTree *expr) { + std::set inits; + return isDependentInternal (expr, inits); +} + + +bool CCSemExpr::isDependent (CTree *node, bool dependent_base) { + if (dependent) { + node->SemValue ()->setTypeRef (&CTYPE_UNDEFINED); + return true; + } + dependent = dependent_base; + return false; +} + + +// reset `dependent' status attribute and return former value +bool CCSemExpr::resetDependent () { + bool dep = dependent; + dependent = false; + return dep; +} + + +// return true if class is derived from a template parameter +bool CCSemExpr::depBaseClass () const { + CStructure *scope = current_scope; + while (! scope->FileInfo ()) { + if (scope->ClassInfo () && scope->ClassInfo ()->hasDepBaseClass ()) + return true; + if (scope->QualifiedScope () && scope->QualifiedScope ()->ClassInfo () && + scope->QualifiedScope ()->ClassInfo ()->hasDepBaseClass ()) + return true; + scope = scope->Parent ()->Structure (); + } + return false; +} + + +// transform the expression into a call expression with a built-in operator +// as the target function +void CCSemExpr::builtinOpExpr (CTree *node, CTree *base, const char *op, int oper, CTypeInfo *result, + CTypeInfo *t1, CTypeInfo *t2) const { + CT_Call *call = node->IsCall (); + if (! call) { + SEM_WARNING(node, "internal error, " << node->NodeName () << " is no CT_Call node, but builtin operator"); + } + else if (!result || *result == CTYPE_UNDEFINED || + !t1 || *t1 == CTYPE_UNDEFINED || + (t2 && *t2 == CTYPE_UNDEFINED)) { + SEM_ERROR(node, "undefined type"); + } + else { + char name[1000]; + sprintf (name, "operator %s", op); + CFunctionInfo *fi = current_scope->SemDB ()->BuiltinOperator (name, oper, + result->Duplicate (), t1->Duplicate (), t2 ? t2->Duplicate () : 0); + call->Object (fi); + } +} + + +bool CCSemExpr::lookupBuiltin (CT_SimpleName* sn, CCNameLookup& nl) { + // if name prefixed with "__builtin_" then lookup without this prefix + const char* name = sn->Name ()->Text (); + if (! nl.Objects () && name && strncmp (name, "__builtin_", 10) == 0) { + nl.lookup (name+10, current_scope, true, true); + return nl.Objects (); + } + return true; +} + + +} // namespace Puma diff --git a/Puma/src/parser/ccparser/CCSemExpr.h b/Puma/src/parser/ccparser/CCSemExpr.h new file mode 100644 index 0000000..320cc6a --- /dev/null +++ b/Puma/src/parser/ccparser/CCSemExpr.h @@ -0,0 +1,171 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CCSemExpr_h__ +#define __CCSemExpr_h__ + +#include "Puma/ErrorSink.h" +#include "Puma/Limits.h" +#include "Puma/Config.h" +#include "Puma/CTree.h" + +namespace Puma { + +class CStructure; +class CObjectInfo; +class CClassInfo; +class CTypeInfo; +class CCNameLookup; +class CCOverloading; +class CRecord; + + +class CCSemExpr { +protected: + ErrorSink &err; // error stream + CStructure *current_scope; + CT_CallExpr *fct_call; // when evaluating first operand of function call + bool dependent_args; + bool dependent; // expression dependent on template parameter + +public: // public interface + CCSemExpr (ErrorSink &, CStructure *scope); + + CTypeInfo *resolveExpr (CTree *expr, CTree *base = (CTree*)0); + CTypeInfo *resolveInit (CTree *node, CTree *base); + + void configure (Config &) {} + +public: // basic expression operations + static bool isLvalue (CTree *); + static bool isRvalue (CTree *); + static bool isModifiable (CTypeInfo *, unsigned long = 0); + static bool isAddrExpr (CTree *); + + // constant expressions + static bool isConstIntExpr (CTree *); + // not yet implemented! always returns true! + static bool isConstExpr (CTree *); + // constant integral expressions + static bool isConstIntegralExpr (CTree *); + + // type conversions + static CTypeInfo *usualArithmeticConv (CTree *, CTree *); + static CTypeInfo *convLvalueToRvalue (CTree *, CTree * = (CTree*)0); + static CTypeInfo *castToType (CTypeInfo *, CTree *, bool = true); + static CTypeInfo *intPromotion (CTree *); + + static CObjectInfo *findObject (CTree *); + static bool sameOrBaseClass (CRecord *, CRecord *); + static bool baseClass (CClassInfo *, CClassInfo *); + + // return true if evaluated expression + // depend on template parameter + bool isDependent () const; + // (for a given expression) + static bool isDependent (CTree *); + + // expression evaluation + CTypeInfo *resolve (CTree *, CTree *); + CTypeInfo *resolve (CT_Expression *, CTree *); + CTypeInfo *resolve (CT_CallExpr *, CTree *); + CTypeInfo *resolve (CT_MembPtrExpr *, CTree *); + CTypeInfo *resolve (CT_SimpleName *, CTree *); + CTypeInfo *resolve (CT_BinaryExpr *, CTree *); + CTypeInfo *resolve (CT_UnaryExpr *, CTree *); + CTypeInfo *resolve (CT_PostfixExpr *, CTree *); + CTypeInfo *resolve (CT_ConstructExpr *, CTree *); + CTypeInfo *resolve (CT_CmpdLiteral *, CTree *); + CTypeInfo *resolve (CT_NewExpr *, CTree *); + CTypeInfo *resolve (CT_DeleteExpr *, CTree *); + CTypeInfo *resolve (CT_IfThenExpr *, CTree *); + CTypeInfo *resolve (CT_DerefExpr *, CTree *); + CTypeInfo *resolve (CT_AddrExpr *, CTree *); + CTypeInfo *resolve (CT_CastExpr *, CTree *); + CTypeInfo *resolve (CT_DynamicCast *, CTree *); + CTypeInfo *resolve (CT_StaticCast *, CTree *); + CTypeInfo *resolve (CT_ReintCast *, CTree *); + CTypeInfo *resolve (CT_ConstCast *, CTree *); + CTypeInfo *resolve (CT_TypeidExpr *, CTree *); + CTypeInfo *resolve (CT_ThrowExpr *, CTree *); + CTypeInfo *resolve (CT_SizeofExpr *, CTree *); + CTypeInfo *resolve (CT_AlignofExpr *, CTree *); + CTypeInfo *resolve (CT_TypeTraitExpr *, CTree *); + CTypeInfo *resolve (CT_OffsetofExpr *, CTree *); + CTypeInfo *resolve (CT_IndexExpr *, CTree *); + CTypeInfo *resolve (CT_BracedExpr *, CTree *); + CTypeInfo *resolve (CT_Bool *, CTree *); + CTypeInfo *resolve (CT_Character *, CTree *); + CTypeInfo *resolve (CT_WideCharacter *, CTree *); + CTypeInfo *resolve (CT_String *, CTree *); + CTypeInfo *resolve (CT_WideString *, CTree *); + CTypeInfo *resolve (CT_Integer *, CTree *); + CTypeInfo *resolve (CT_Float *, CTree *); + +protected: + // binary expressions + CTypeInfo *binary_ass (CT_BinaryExpr *, CTree *); + CTypeInfo *binary_comma (CT_BinaryExpr *, CTree *); + CTypeInfo *binary_log (CT_BinaryExpr *, CTree *); + CTypeInfo *binary_bit (CT_BinaryExpr *, CTree *); + CTypeInfo *binary_equ (CT_BinaryExpr *, CTree *); + CTypeInfo *binary_rel (CT_BinaryExpr *, CTree *); + CTypeInfo *binary_shift (CT_BinaryExpr *, CTree *); + CTypeInfo *binary_add (CT_BinaryExpr *, CTree *); + CTypeInfo *binary_mul (CT_BinaryExpr *, CTree *); + CTypeInfo *binary_ptm (CT_BinaryExpr *, CTree *); + void apply_binary_op (CTree *, int); + + // operator overloading + CTypeInfo *overloadedOperator (CTree *, CTree *, const char *, int, + CTree *, CTree * = 0); + + // literal evaluation + void overflow (CTree *, int, bool &) const; + int scanCharacter (CTree *, LONG_LONG &) const; + LONG_LONG nextCharacter (const char *&, bool &) const; + + // helper + bool depBaseClass () const; + CTree *baseTree (CTree *) const; + bool isDependent (CTree *, bool); + bool resetDependent (); + bool isClassOrEnum (CTypeInfo *) const; + bool sameUnqualBaseType (CTypeInfo *, CTypeInfo *) const; + bool checkDeclsFound (CTree *, CCNameLookup &) const; + void passOnConstant (CTree *, CTypeInfo *) const; + bool validOvlFctSet (CTree *, const char *, const char *, CCOverloading &); + void builtinOpExpr (CTree *, CTree *, const char *, int, CTypeInfo *, CTypeInfo *, CTypeInfo * = 0) const; + bool lookupBuiltin (CT_SimpleName* sn, CCNameLookup& nl); +}; + +inline CCSemExpr::CCSemExpr (ErrorSink &e, CStructure *s) : + err (e), + current_scope (s), + fct_call (0), + dependent_args (false), + dependent (false) + {} + +inline bool CCSemExpr::isDependent () const + { return dependent; } + + +} // namespace Puma + +#endif /* __CCSemExpr_h__ */ diff --git a/Puma/src/parser/ccparser/CCSemVisitor.cc b/Puma/src/parser/ccparser/CCSemVisitor.cc new file mode 100644 index 0000000..1764edf --- /dev/null +++ b/Puma/src/parser/ccparser/CCSemVisitor.cc @@ -0,0 +1,662 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CCSemVisitor.h" +#include "Puma/CCSemExpr.h" +#include "Puma/CStructure.h" +#include "Puma/CLocalScope.h" +#include "Puma/CFunctionInfo.h" +#include "Puma/CTemplateInfo.h" +#include "Puma/CAttributeInfo.h" +#include "Puma/CRecord.h" + +namespace Puma { + + +// print semantic error messages + +#define SEM_MSG(node__,mesg__) \ + err << node__->token ()->location () << mesg__ << endMessage + +#define SEM_ERROR(node__,mesg__) \ + SEM_MSG (node__, sev_error << mesg__) + +#define SEM_WARNING(node__,mesg__) \ + SEM_MSG (node__, sev_warning << mesg__) + + +void CCSemVisitor::run (CTree *node, CStructure *scope) { + current_scope = scope; + if (! current_scope && node->NodeName () == CT_Program::NodeId ()) + current_scope = ((CT_Program*)node)->Scope (); + if (current_scope) + visit (node); +} + + +CTypeInfo *CCSemVisitor::resolveExpr (CTree *expr, CTree *node) const { + CCSemExpr cse (err, current_scope); + return cse.resolveExpr (expr, node); +} + + +CTypeInfo *CCSemVisitor::resolveInit (CTree *expr, CTree *node) const { + CCSemExpr cse (err, current_scope); + return cse.resolveInit (expr, node); +} + + +void CCSemVisitor::pre_visit (CTree *node) { + if (! node) + return; + + const char *id = node->NodeName (); + if (id == CT_Program::NodeId ()) + pre_action ((CT_Program*)node); + else if (id == CT_ArgDeclList::NodeId ()) + pre_action ((CT_ArgDeclList*)node); + else if (id == CT_ArgNameList::NodeId ()) + pre_action ((CT_ArgNameList*)node); + else if (id == CT_ArgDeclSeq::NodeId ()) + pre_action ((CT_ArgDeclSeq*)node); + else if (id == CT_MembList::NodeId ()) + pre_action ((CT_MembList*)node); + else if (id == CT_MembInitList::NodeId ()) + pre_action ((CT_MembInitList*)node); + else if (id == CT_MembInit::NodeId ()) + pre_action ((CT_MembInit*)node); + else if (id == CT_CmpdStmt::NodeId ()) + pre_action ((CT_CmpdStmt*)node); + else if (id == CT_IfStmt::NodeId ()) + pre_action ((CT_IfStmt*)node); + else if (id == CT_IfElseStmt::NodeId ()) + pre_action ((CT_IfElseStmt*)node); + else if (id == CT_SwitchStmt::NodeId ()) + pre_action ((CT_SwitchStmt*)node); + else if (id == CT_ForStmt::NodeId ()) + pre_action ((CT_ForStmt*)node); + else if (id == CT_WhileStmt::NodeId ()) + pre_action ((CT_WhileStmt*)node); + else if (id == CT_DoStmt::NodeId ()) + pre_action ((CT_DoStmt*)node); + else if (id == CT_Handler::NodeId ()) + pre_action ((CT_Handler*)node); + else if (id == CT_TemplateDecl::NodeId ()) + pre_action ((CT_TemplateDecl*)node); + else if (id == CT_ExprStmt::NodeId ()) + pre_action ((CT_ExprStmt*)node); + else if (id == CT_CaseStmt::NodeId ()) + pre_action ((CT_CaseStmt*)node); + else if (id == CT_GotoStmt::NodeId ()) + pre_action ((CT_GotoStmt*)node); + else if (id == CT_ReturnStmt::NodeId ()) + pre_action ((CT_ReturnStmt*)node); + else if (id == CT_InitDeclarator::NodeId ()) + pre_action ((CT_InitDeclarator*)node); + else if (id == CT_ArgDecl::NodeId ()) + pre_action ((CT_ArgDecl*)node); + else if (id == CT_Condition::NodeId ()) + pre_action ((CT_Condition*)node); + else if (id == CT_ArrayDeclarator::NodeId ()) + pre_action ((CT_ArrayDeclarator*)node); + else if (id == CT_BitFieldDeclarator::NodeId ()) + pre_action ((CT_BitFieldDeclarator*)node); + else if (id == CT_CmpdLiteral::NodeId ()) + pre_action ((CT_CmpdLiteral*)node); + else if (id == CT_ExprList::NodeId ()) + pre_action ((CT_ExprList*)node); +} + + +void CCSemVisitor::post_visit (CTree *node) { + if (! node) + return; + + const char *id = node->NodeName (); + if (id == CT_Program::NodeId ()) + post_action ((CT_Program*)node); + else if (id == CT_ArgDeclList::NodeId ()) + post_action ((CT_ArgDeclList*)node); + else if (id == CT_ArgNameList::NodeId ()) + post_action ((CT_ArgNameList*)node); + else if (id == CT_ArgDeclSeq::NodeId ()) + post_action ((CT_ArgDeclSeq*)node); + else if (id == CT_MembList::NodeId ()) + post_action ((CT_MembList*)node); + else if (id == CT_MembInitList::NodeId ()) + post_action ((CT_MembInitList*)node); + else if (id == CT_CmpdStmt::NodeId ()) + post_action ((CT_CmpdStmt*)node); + else if (id == CT_IfStmt::NodeId ()) + post_action ((CT_IfStmt*)node); + else if (id == CT_IfElseStmt::NodeId ()) + post_action ((CT_IfElseStmt*)node); + else if (id == CT_SwitchStmt::NodeId ()) + post_action ((CT_SwitchStmt*)node); + else if (id == CT_ForStmt::NodeId ()) + post_action ((CT_ForStmt*)node); + else if (id == CT_WhileStmt::NodeId ()) + post_action ((CT_WhileStmt*)node); + else if (id == CT_Handler::NodeId ()) + post_action ((CT_Handler*)node); + else if (id == CT_TemplateDecl::NodeId ()) + post_action ((CT_TemplateDecl*)node); +} + + +/////////////////////////////////////////////////////// +// pre_action functions /////////////////////////////// +/////////////////////////////////////////////////////// + + +void CCSemVisitor::pre_action (CT_Program *node) { + if (node->Scope ()) + current_scope = node->Scope (); +} + + +void CCSemVisitor::pre_action (CT_ArgDeclList *node) { + if (node->Scope ()) + current_scope = node->Scope (); +} + + +void CCSemVisitor::pre_action (CT_ArgNameList *node) { + if (node->Scope ()) + current_scope = node->Scope (); +} + + +void CCSemVisitor::pre_action (CT_ArgDeclSeq *node) { + if (node->Scope ()) + current_scope = node->Scope (); +} + + +void CCSemVisitor::pre_action (CT_MembList *node) { + if (node->Scope ()) + current_scope = node->Scope (); +} + + +void CCSemVisitor::pre_action (CT_MembInitList *node) { + if (node->Scope ()) + current_scope = node->Scope (); +} + + +void CCSemVisitor::pre_action (CT_MembInit *node) { + CT_ExprList *init = node->Initializer (); + if (init) { + unsigned entries = init->Entries (); + // resolve initializer arguments + for (unsigned i = 0; i < entries; i++) + resolveExpr (init->Entry (i), init); + } + prune (); +} + + +void CCSemVisitor::pre_action (CT_CmpdStmt *node) { + if (node->Scope ()) + current_scope = node->Scope (); +} + + +void CCSemVisitor::pre_action (CT_IfStmt *node) { + CTypeInfo *type; + CTree *expr; + + if (node->Scope ()) + current_scope = node->Scope (); + + // evaluation not yet complete! + + expr = node->Condition (); + if (expr) { + if (expr->NodeName () != CT_Condition::NodeId ()) { + type = resolveExpr (expr, node); +// if (! type->isScalar ()) +// SEM_ERROR (node, "controlling expression of `if' statement not scalar"); + } + } +} + + +void CCSemVisitor::pre_action (CT_IfElseStmt *node) { + CTypeInfo *type; + CTree *expr; + + if (node->Scope ()) + current_scope = node->Scope (); + + // evaluation not yet complete! + + expr = node->Condition (); + if (expr) { + if (expr->NodeName () != CT_Condition::NodeId ()) { + type = resolveExpr (expr, node); +// if (! type->isScalar ()) +// SEM_ERROR (node, "controlling expression of `if' statement not scalar"); + } + } +} + + +void CCSemVisitor::pre_action (CT_SwitchStmt *node) { + CTypeInfo *type; + CTree *expr; + + if (node->Scope ()) + current_scope = node->Scope (); + + // evaluation not yet complete! + + expr = node->Condition (); + if (expr) { + if (expr->NodeName () != CT_Condition::NodeId ()) { + type = resolveExpr (expr, node); +// type = promote (node->Condition (), node); +// if (! type->isInteger ()) +// SEM_ERROR (node, +// "controlling expression of `switch' statement not an integer"); + } + } +} + + +void CCSemVisitor::pre_action (CT_ForStmt *node) { + CTypeInfo *type; + CTree *expr; + + if (node->Scope ()) + current_scope = node->Scope (); + + // evaluation not yet complete! + + expr = node->Condition (); + if (expr) { + if (expr->NodeName () != CT_Condition::NodeId ()) { + type = resolveExpr (expr, node); +// if (! type->isScalar ()) +// SEM_ERROR (node, "controlling expression of `for' statement not scalar"); + } + } + expr = node->Expr (); + if (expr) + // there are no further constraints on this expression + resolveExpr (expr, node); +} + + +void CCSemVisitor::pre_action (CT_WhileStmt *node) { + CTypeInfo *type; + CTree *expr; + + if (node->Scope ()) + current_scope = node->Scope (); + + // evaluation not yet complete! + + expr = node->Condition (); + if (expr) { + if (expr->NodeName () != CT_Condition::NodeId ()) { + type = resolveExpr (expr, node); +// if (! type->isScalar ()) +// SEM_ERROR (node, "controlling expression of `while' statement not scalar"); + } + } +} + + +void CCSemVisitor::pre_action (CT_Handler *node) { + if (node->Scope ()) + current_scope = node->Scope (); +} + + +void CCSemVisitor::pre_action (CT_TemplateDecl *node) { + if (node->Scope ()) + current_scope = node->Scope (); +} + + +void CCSemVisitor::pre_action (CT_DoStmt *node) { + CTypeInfo *type; + CTree *expr; + + // evaluation not yet complete! + + expr = node->Expr (); + if (expr) { + type = resolveExpr (expr, node); +// if (! type->isScalar ()) +// SEM_ERROR (node, "controlling expression of `do' statement not scalar"); + } +} + + +void CCSemVisitor::pre_action (CT_ExprStmt *node) { + if (node->Expr ()) + resolveExpr (node->Expr (), node); + prune (); +} + + +void CCSemVisitor::pre_action (CT_CaseStmt *node) { + if (node->Expr ()) { +// if (! isConstIntExpr (node->Expr ())) +// SEM_ERROR (node, "label of `case' statement not a valid integer constant"); + } +} + + +void CCSemVisitor::pre_action (CT_GotoStmt *node) { + if (! current_scope->LocalScope ()) + SEM_ERROR (node, "`goto' outside of function"); + else + check_goto_label (node->Label ()); +} + +void CCSemVisitor::check_goto_label (CTree *tree) { + CFunctionInfo *finfo; + const char *name; + + finfo = current_scope->LocalScope ()->Function (); + if (finfo) { + CT_SimpleName *label = (CT_SimpleName *)tree; + name = label->Text (); + if (! finfo->Label (name)) + SEM_ERROR (label, "label `" << name << "' used but not defined"); + } +} + +void CCSemVisitor::pre_action (CT_ReturnStmt *node) { + CFunctionInfo *finfo = 0; + CTypeInfo *t2 = 0, *t1 = 0; +// CConstant *v = 0; +// CTree *expr = 0; + + // evaluation not yet complete! + + if (! current_scope->LocalScope ()) + SEM_ERROR (node, "`return' outside of function"); + else { + finfo = current_scope->LocalScope ()->Function (); + if (finfo) + t1 = finfo->TypeInfo ()->ReturnType (); + else + t1 = &CTYPE_UNDEFINED; + } + + if (node->Expr ()) { + t2 = resolveExpr (node->Expr (), node); + if (t1->isVoid ()) { + if (t2 && ! (t2->isVoid () || t2->is_undefined ())) + SEM_WARNING (node, "`return' with a value, in function returning void"); +// } else { +// expr = node->Expr (); +// v = expr->Value () ? expr->Value ()->Constant () : 0; +// if (t1->isScalar ()) { +// if (t1->isArithmetic () && t2->isArithmetic ()) { +// if (! compatible (t1, t2)) +// cast_to (t1, expr, node); +// } else if (! (t1->isPointer () && t2->isPointer () && +// (compatibleBase (t1, t2) || +// t1->VirtualType ()->BaseType ()->isVoid () || +// t2->VirtualType ()->BaseType ()->isVoid ()) && +// (t2->isConst () ? t1->isConst () : true) && +// (t2->isVolatile () ? t1->isVolatile () : true) && +// (t2->isRestrict () ? t1->isRestrict () : true)) && +// ! (t1->isPointer () && t2->isInteger () && v && v->isNull ()) && +// ! (t1->VirtualType ()->is_bool () && t2->isPointer ())) { +// SEM_ERROR (node, "incompatible types in `return' statement"); +// } else if (! compatible (t1, t2)) +// cast_to (t1, expr, node); +// } else if (t1->isRecord ()) { +// if (! compatible (t1, t2)) +// SEM_ERROR (node, "incompatible types in `return' statement"); +// } else +// SEM_ERROR (node, "invalid return type"); +// } + } + } else if (t1 && ! (t1->isVoid () || t1->is_undefined ())) + SEM_WARNING (node, "`return' with no value, in function returning non-void"); + + prune (); +} + + +void CCSemVisitor::pre_action (CT_InitDeclarator *node) { + CObjectInfo *info; + CStructure *scope; + CTree *init; + + scope = current_scope; + info = node->Object (); + + // �8.5.10 the initializer of a static member + // is in the scope of the member's class + if (info && info->AttributeInfo () && info->isClassMember () && + ! info->Scope ()->isRecord ()) + current_scope = info->AttributeInfo ()->Record (); + + init = node->Initializer (); + if (init && (! init->Type () || init->Type ()->is_undefined ())) + resolveInit (init, node); + + current_scope = scope; + prune (); +} + + +void CCSemVisitor::pre_action (CT_ArgDecl *node) { + CTree *init = node->Initializer (); + if (init) + resolveInit (init, node); + prune (); +} + + +void CCSemVisitor::pre_action (CT_Condition *node) { + // TODO: evaluation not complete! => type conversions etc. + CTree *init = node->Initializer (); + if (init) + resolveInit (init, node); + prune (); +} + + +void CCSemVisitor::pre_action (CT_ArrayDeclarator *node) { + // error diagnostics not yet implemented! + +// CT_SimpleName *name; +// const char *array; +// CTypeInfo *type; +// CConstant *v; +// CTree *expr; +// +// expr = node->Delimiter ()->Expr (); +// if (expr) { +// name = findName (node); +// array = name ? name->Text () : ""; +// type = resolveExpr (expr, node->Delimiter ()); +// expr = node->Delimiter ()->Expr (); +// +// if (! type->isInteger ()) +// SEM_ERROR (node, "size of array `" << array << "' has non-integer type"); +// else if (isConstIntExpr (expr)) { +// v = expr->Value ()->Constant (); +// if (/*v->isNull () ||*/ v->isNegative ()) +// SEM_ERROR (node, "array `" << array << "' has invalid size"); +// else if (node->Type ()->TypeArray ()) +// node->Type ()->TypeArray ()->Dimension (v->convert_to_uint ()); +// } +// } +} + + +void CCSemVisitor::pre_action (CT_BitFieldDeclarator *node) { + // error diagnostics not yet implemented! + +// CObjectInfo *info; +// const char *name; +// CConstant *v; +// CTree *expr; +// +// expr = node->Expr (); +// if (expr) { +// resolveExpr (expr, node); +// expr = node->Expr (); +// info = node->Object (); +// name = info ? info->Name () : ""; +// +// if (! isConstIntExpr (expr)) +// SEM_ERROR (node, "width of bit-field `" << name +// << "' isn't integer constant expression"); +// else { +// v = expr->Value ()->Constant (); +// if (v->isNegative ()) +// SEM_ERROR (node, "negative width in bit-field `" << name << "'"); +// else if (info && info->TypeInfo () && info->TypeInfo ()->TypeBitField ()) +// info->TypeInfo ()->TypeBitField ()->Dimension (v->convert_to_uint ()); +// } +// } +} + + +void CCSemVisitor::pre_action (CT_ExprList *node) { + // do not visit the expression list + // it's evaluated when the init declarator is visited + prune (); +} + + +void CCSemVisitor::pre_action (CT_CmpdLiteral *node) { + // do not visit the compound literal + // it's evaluated when the init declarator is visited + prune (); +} + + +/////////////////////////////////////////////////////// +// post_action functions ////////////////////////////// +/////////////////////////////////////////////////////// + + +void CCSemVisitor::post_action (CT_Program *node) { + if (node->Scope ()) + current_scope = node->Scope (); +} + + +void CCSemVisitor::post_action (CT_ArgDeclList *node) { + if (node->Scope ()) + current_scope = node->Scope ()->Parent ()->Structure (); +} + + +void CCSemVisitor::post_action (CT_ArgNameList *node) { + if (node->Scope ()) + current_scope = node->Scope ()->Parent ()->Structure (); +} + + +void CCSemVisitor::post_action (CT_ArgDeclSeq *node) { + if (node->Scope ()) + current_scope = node->Scope ()->Parent ()->Structure (); +} + + +void CCSemVisitor::post_action (CT_MembList *node) { + if (node->Scope ()) + current_scope = node->Scope ()->Parent ()->Structure (); +} + + +void CCSemVisitor::post_action (CT_MembInitList *node) { + if (node->Scope ()) + current_scope = node->Scope ()->Parent ()->Structure (); +} + + +void CCSemVisitor::post_action (CT_CmpdStmt *node) { + if (node->Scope ()) + current_scope = node->Scope ()->Parent ()->Structure (); +} + + +void CCSemVisitor::post_action (CT_IfStmt *node) { + if (node->Scope ()) + current_scope = node->Scope ()->Parent ()->Structure (); +} + + +void CCSemVisitor::post_action (CT_IfElseStmt *node) { + if (node->Scope ()) + current_scope = node->Scope ()->Parent ()->Structure (); +} + + +void CCSemVisitor::post_action (CT_SwitchStmt *node) { + if (node->Scope ()) + current_scope = node->Scope ()->Parent ()->Structure (); +} + + +void CCSemVisitor::post_action (CT_ForStmt *node) { + if (node->Scope ()) + current_scope = node->Scope ()->Parent ()->Structure (); +} + + +void CCSemVisitor::post_action (CT_WhileStmt *node) { + if (node->Scope ()) + current_scope = node->Scope ()->Parent ()->Structure (); +} + + +void CCSemVisitor::post_action (CT_Handler *node) { + if (node->Scope ()) + current_scope = node->Scope ()->Parent ()->Structure (); +} + + +void CCSemVisitor::post_action (CT_TemplateDecl *node) { + // visit template instance code + if (node->Scope ()) { + current_scope = node->Scope (); + + /*CTemplateInfo *tinfo = current_scope->TemplateInfo (); + if (tinfo) { + for (unsigned i = 0; i < tinfo->Instances (); i++) { + CObjectInfo *instance = tinfo->Instance (i); + CTree *tree = instance->Tree (); + if (tree) { + visit (tree); + } + } + }*/ + } + + if (node->Scope ()) + current_scope = node->Scope ()->Parent ()->Structure (); +} + + +} // namespace Puma diff --git a/Puma/src/parser/ccparser/CCSemVisitor.h b/Puma/src/parser/ccparser/CCSemVisitor.h new file mode 100644 index 0000000..9341932 --- /dev/null +++ b/Puma/src/parser/ccparser/CCSemVisitor.h @@ -0,0 +1,111 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CCSemVisitor_h__ +#define __CCSemVisitor_h__ + +#include "Puma/ErrorSink.h" +#include "Puma/CVisitor.h" +#include "Puma/CTree.h" + +namespace Puma { + + +class CStructure; +class CObjectInfo; +class CTypeInfo; +class Config; + +class CCSemVisitor : private CVisitor { +protected: + CStructure *current_scope; + ErrorSink &err; + +public: + CCSemVisitor (ErrorSink &); + + void run (CTree *, CStructure * = (CStructure*)0); + void configure (Config &) {} + +protected: + void pre_visit (CTree *); + void post_visit (CTree *); + +protected: + void pre_action (CT_Program *); + void pre_action (CT_ArgDeclList *); + void pre_action (CT_ArgNameList *); + void pre_action (CT_ArgDeclSeq *); + void pre_action (CT_MembList *); + void pre_action (CT_MembInitList *); + void pre_action (CT_MembInit *); + void pre_action (CT_CmpdStmt *); + void pre_action (CT_IfStmt *); + void pre_action (CT_IfElseStmt *); + void pre_action (CT_SwitchStmt *); + void pre_action (CT_ForStmt *); + void pre_action (CT_WhileStmt *); + void pre_action (CT_Handler *); + void pre_action (CT_TemplateDecl *); + void pre_action (CT_DoStmt *); + void pre_action (CT_ExprStmt *); + void pre_action (CT_CaseStmt *); + void pre_action (CT_GotoStmt *); + void pre_action (CT_ReturnStmt *); + void pre_action (CT_InitDeclarator *); + void pre_action (CT_ArgDecl *); + void pre_action (CT_Condition *); + void pre_action (CT_ArrayDeclarator *); + void pre_action (CT_BitFieldDeclarator *); + void pre_action (CT_ExprList *); + void pre_action (CT_CmpdLiteral *); + +protected: + void post_action (CT_Program *); + void post_action (CT_ArgDeclList *); + void post_action (CT_ArgNameList *); + void post_action (CT_ArgDeclSeq *); + void post_action (CT_MembList *); + void post_action (CT_MembInitList *); + void post_action (CT_CmpdStmt *); + void post_action (CT_IfStmt *); + void post_action (CT_IfElseStmt *); + void post_action (CT_SwitchStmt *); + void post_action (CT_ForStmt *); + void post_action (CT_WhileStmt *); + void post_action (CT_Handler *); + void post_action (CT_TemplateDecl *); + +protected: + CTypeInfo *resolveExpr (CTree *, CTree *) const; + CTypeInfo *resolveInit (CTree *, CTree *) const; + +private: + void check_goto_label (CTree *); + +}; + +inline CCSemVisitor::CCSemVisitor (ErrorSink &e) : + current_scope ((CStructure*)0), + err (e) + {} + + +} // namespace Puma + +#endif /* __CCSemVisitor_h__ */ diff --git a/Puma/src/parser/ccparser/CCSemantic.cc b/Puma/src/parser/ccparser/CCSemantic.cc new file mode 100644 index 0000000..7694a5e --- /dev/null +++ b/Puma/src/parser/ccparser/CCSemantic.cc @@ -0,0 +1,4734 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CTree.h" +#include "Puma/DelayedParseTree.h" +#include "Puma/Unit.h" +#include "Puma/Array.h" +#include "Puma/PtrStack.h" +#include "Puma/ErrorSink.h" +#include "Puma/ErrorSeverity.h" +#include "Puma/CCSemDeclarator.h" +#include "Puma/CSemDeclSpecs.h" +#include "Puma/CFileInfo.h" +#include "Puma/CEnumInfo.h" +#include "Puma/CTypeInfo.h" +#include "Puma/CClassInfo.h" +#include "Puma/CUnionInfo.h" +#include "Puma/CUsingInfo.h" +#include "Puma/CLabelInfo.h" +#include "Puma/CLocalScope.h" +#include "Puma/CTypedefInfo.h" +#include "Puma/CFunctionInfo.h" +#include "Puma/CArgumentInfo.h" +#include "Puma/CAttributeInfo.h" +#include "Puma/CEnumeratorInfo.h" +#include "Puma/CTemplateInfo.h" +#include "Puma/CTemplateParamInfo.h" +#include "Puma/CClassInstance.h" +#include "Puma/CUnionInstance.h" +#include "Puma/CFctInstance.h" +#include "Puma/CSyntax.h" +#include "Puma/CCSyntax.h" +#include "Puma/CCSemantic.h" +#include "Puma/CSemDatabase.h" +#include "Puma/CCNameLookup.h" +#include "Puma/CMemberAliasInfo.h" +#include "Puma/CNamespaceInfo.h" +#include "Puma/CCSemExpr.h" +#include "Puma/CConstant.h" +#include "Puma/CCInstantiation.h" +#include "Puma/FileUnit.h" +#include "Puma/MacroUnit.h" +#include "Puma/InstantiationParser.h" +#include "Puma/InstantiationBuilder.h" +#include "Puma/InstantiationSyntax.h" + +#include +#include +#include +#include + +namespace Puma { + + +/*DEBUG*/extern int TRACE_FCT; +/*DEBUG*/extern int TRACE_OBJS; +/*DEBUG*/extern int TRACE_SCOPES; + +// print semantic error messages + +#define SEM_MSG(loc__,mesg__) \ + *_err << loc__->token ()->location () << mesg__ << endMessage + +#define SEM_ERROR(loc__,mesg__) \ + SEM_MSG (loc__, sev_error << mesg__) + +#define SEM_WARNING(loc__,mesg__) \ + SEM_MSG (loc__, sev_warning << mesg__) + +#define SEM_MSG__prev_loc(info__) \ + if (info__->SourceInfo ()->StartToken ()) \ + *_err << info__->SourceInfo ()->StartToken ()->token ()->location () \ + << "previously defined here" << endMessage + +#define SEM_ERROR__already_defined(loc__,name__,info__) \ + SEM_ERROR (loc__, "`" << *name__ << "' already defined"); \ + SEM_MSG__prev_loc(info__) + +#define SEM_ERROR__duplicate(loc__,type__,name__) \ + SEM_ERROR (loc__, "duplicate " << type__ << " `" << *name__ << "'") + +#define SEM_ERROR__invalid_in_param(loc__,what__,name__) \ + SEM_ERROR (loc__, what__ << " invalid in declaration of parameter `" \ + << *name__ << "'") + +#define SEM_ERROR__redefinition(loc__,name__,info__) \ + SEM_ERROR (loc__, "redefinition of `" << *name__ << "'"); \ + SEM_MSG__prev_loc(info__) + +#define SEM_ERROR__not_member(loc__,name__,class__) \ + SEM_ERROR (loc__, "`" << *name__ \ + << "' is not a member of `" << class__ << "'") + +#define SEM_ERROR__no_matching_decl(loc__,name__,class__) \ + SEM_ERROR (loc__, "no matching declaration found for `" << *name__ \ + << "' in class `" << class__ << "'") + +#define SEM_ERROR__unknown_ns(loc__,name__) \ + SEM_ERROR (loc__, "unknown namespace `" << *name__ << "'") + +#define SEM_ERROR__not_class(loc__,name__) \ + SEM_ERROR (loc__, "base type `" << *name__ \ + << "' fails to be a struct or class type") + +#define SEM_ERROR__invalid_param(loc__,what__,name__) \ + SEM_ERROR (loc__, "invalid " << what__ << \ + " in declaration of parameter `" << *name__ << "'") + +#define SEM_ERROR__ambiguous_use(loc__,name__) \ + SEM_ERROR (loc__, "use of `" << *name__ << "' is ambiguous") + +#define SEM_ERROR__cannot_declare(loc__,name__,scope__) \ + SEM_ERROR (loc__, "cannot declare `" << *name__ << \ + "' within `" << scope__->Name () << "'") + +#define SEM_ERROR__conflicting_types(loc__,info__) \ + SEM_ERROR (loc__, "conflicting types for `" << \ + info__->Name () << "'"); \ + SEM_MSG__prev_loc(info__) + +#define SEM_ERROR__not_base_class(loc__,class__) \ + SEM_ERROR (loc__, "`" << class__->Name () << \ + "' is not a base class of `" << current_scope->Name () << "'") + +#define STACK_INIT 5 +#define STACK_INCR 5 + + +CCSemantic::CCSemantic (CCSyntax &s, CCBuilder &b) : + CSemantic (s, b), + _syntax (s), + _in_base_spec (STACK_INIT, STACK_INCR), + _in_nested_name (STACK_INIT, STACK_INCR), + _in_conv_type_id (STACK_INIT, STACK_INCR), + _in_extern_decl (STACK_INIT, STACK_INCR), + _protection (STACK_INIT, STACK_INCR), + shared_nl (*_err), + _in_template_arg_list (STACK_INIT, STACK_INCR), + _in_template_param_list (STACK_INIT, STACK_INCR), + parsing_entity_name (STACK_INIT, STACK_INCR), + _in_expr (STACK_INIT, STACK_INCR), + _postfix_expr (STACK_INIT, STACK_INCR), + _in_memb_access_expr (STACK_INIT, STACK_INCR) { + last_scope = 0; + search_scope = 0; + last_search_scope = 0; + last_token_nl.tok = 0; + last_token_nl.scope = 0; + last_token_nl.nested = false; + last_token_nl.nested_name = false; + last_token_nl.base_spec = false; + expect_template = false; + dep_nested_name = false; + _outermost_class_def = 0; + _postfix_expr.push (0); + _in_expr.push (false); + _in_base_spec.push (false); + _in_extern_decl.push (0); + _in_nested_name.push (false); + _in_conv_type_id.push (false); + _in_memb_access_expr.push (MAO_NONE); + _in_template_arg_list.push (0); + _in_template_param_list.push (0); + _protection.push (CProtection::PROT_NONE); + parsing_class_inst = false; + parsing_fct_inst = false; + parsing_entity_name.push (false); + tpl_inst = 0; + _last_unit = 0; + _last_body_skipped = false; + real_inst = false; + support_implicit_int = false; +} + + +void CCSemantic::init (CSemDatabase &db, Unit &unit) { + CSemantic::init (db, unit); + if (! _file->haveCCBuiltins ()) { + _file->haveCCBuiltins (true); + declareImplicitFcts (); + declareNamespaceStd (); + } + if (!db.Project ()->config ().Option ("--pseudo-instances")) + real_inst = true; +} + + +void CCSemantic::init (CSemDatabase &db, Unit &unit, + CStructure *scope, bool fi, bool ci, CCInstantiation *cci) { + CSemantic::init (db, unit); + if (scope) + current_scope = scope; + parsing_fct_inst = fi; + parsing_class_inst = ci; + tpl_inst = cci; + if (!db.Project ()->config ().Option ("--pseudo-instances")) + real_inst = true; +} + + +/*****************************************************************************/ +/* */ +/* Linkage and storage class determination */ +/* */ +/*****************************************************************************/ + + +void CCSemantic::enter_extern_decl (bool block_decl) { + // language string is at the end of the parsed tokens + CTree *lang = builder ().get_node (builder ().nodes () - (block_decl ? 2 : 1)); + if (lang && lang->token ()) { + const char *str = lang->token ()->text (); + unsigned len = strlen (++str); + if (len) { + char *literal = new char[len]; + strncpy (literal, str, len-1); + literal[len-1] = '\000'; + _in_extern_decl.push (literal); + return; + } + } + _in_extern_decl.push (0); +} + + +// ���3.5 name linkage +CLinkage::Type CCSemantic::determine_linkage (CSemDeclSpecs *dss, + SemObjType type, CObjectInfo *prev) const { + // special: global: enumerator of external enum => external + // special: global: named class/enum => external + // special: global: unnamed class/enum in typedef => external + // special: global: data member of anon union => internal + // special: class: method|static data member| + // nested class/enum & external class => external + // special: unnamed union on namespace scope: data member => internal + if (in_extern_decl ()) + return CLinkage::LINK_EXTERNAL; + + bool def_extern = dss->declared (CT_PrimDeclSpec::PDS_EXTERN); + bool def_const = dss->declared (CT_PrimDeclSpec::PDS_CONST); + if (type == ATTRIB || type == FCT) { + if (current_scope->isNamespace ()) { + if (dss->declared (CT_PrimDeclSpec::PDS_STATIC) || + (type == ATTRIB && def_const && ! def_extern && + (prev ? prev->Linkage () != CLinkage::LINK_EXTERNAL : true))) + return CLinkage::LINK_INTERNAL; + return CLinkage::LINK_EXTERNAL; + } else if (current_scope->LocalScope () && + ! (type == ATTRIB && ! def_extern)) { + if (prev && prev->Linkage () != CLinkage::LINK_NONE) + return prev->Linkage (); + else + return CLinkage::LINK_EXTERNAL; + } else if (current_scope->Record ()) { + return CLinkage::LINK_EXTERNAL; + } + } + return CLinkage::LINK_NONE; +} + + +// ���3.7 storage duration +CStorage::Type CCSemantic::determine_storage_class (CSemDeclSpecs *dss) const { + // ���3.7.2 automatic storage duration + if (current_scope->LocalScope ()) + if (! dss->declared (CT_PrimDeclSpec::PDS_STATIC) && + ! dss->declared (CT_PrimDeclSpec::PDS_EXTERN)) + return CStorage::CLASS_AUTOMATIC; + // ���3.7.1 static storage duration + return dss->declared (CT_PrimDeclSpec::PDS_THREAD) ? + CStorage::CLASS_THREAD : CStorage::CLASS_STATIC; +} + + +// set the entity encoding +void CCSemantic::setLanguage (CObjectInfo *info) const { + if (in_extern_decl ()) { + const char *l = _in_extern_decl.top (); + if (strcmp (l, "C") == 0) { + info->Language ().Type (CLanguage::LANG_C); + } else if (strcmp (l, "C++") == 0) { + info->Language ().Type (CLanguage::LANG_CPLUSPLUS); + } else { + info->Language ().Type (CLanguage::LANG_OTHER, l); + } + } +} + + +/*****************************************************************************/ +/* */ +/* Helper */ +/* */ +/*****************************************************************************/ + + +bool CCSemantic::isClassOrEnum (CObjectInfo *info) const { + return info && (info->Record () || info->EnumInfo ()); +} + + +void CCSemantic::deleteContainer (int p) { + CTree *node = builder ().get_node (builder ().nodes () - p); + if (node->NodeName () == Builder::Container::NodeId ()) + delete (Builder::Container*)node; +} + + +CStructure *CCSemantic::getNameScope (CT_SimpleName *name, bool ps) const { + CStructure *scope = current_scope; + int entries = name->Entries (); + if (isQualName (name) && entries > 1) + scope = getScope (((CT_SimpleName*)name->Entry (entries-2))->Object ()); + else if (name->NodeName () == CT_RootQualName::NodeId ()) + scope = _file; + if (ps && scope && scope->TemplateInstance () && + ! scope->TemplateInstance ()->canInstantiate ()) + scope = scope->TemplateInstance ()->Template ()->ObjectInfo ()->Structure (); + return scope ? scope : current_scope; +} + + +CStructure *CCSemantic::getFriendScope (bool skip_tpl_scope) const { + CStructure *scope = current_scope; + // nearest non-class, non-template-instance scope + // Note: if skip_tpl_scope is false, then do not skip template + // scopes because friends declared in a template scope are not + // introduced into the enclosing non-template scope until the + // template is instantiated + while (scope->Record () || + (skip_tpl_scope && scope->TemplateInfo ()) || + (scope->NamespaceInfo () && scope->NamespaceInfo ()->aroundInstantiation ())) + scope = scope->Parent ()->Structure (); + return scope; +} + + +CStructure *CCSemantic::getScope (CObjectInfo *info) const { + if (! info) + return 0; + if (info->isTemplateInstance () && ! info->TemplateInstance ()->canInstantiate ()) + info = info->TemplateInstance ()->Template ()->ObjectInfo (); + if (info->Record () || info->NamespaceInfo ()) + return (CStructure*)info->DefObject (); + if (info->TypedefInfo () && ! realTypedef (info)) + return (CStructure*)info->TypeInfo ()->UnqualType ()-> + TypeRecord ()->Record ()->DefObject (); + return 0; +} + + +CStructure *CCSemantic::getNonTplScope (bool consider_instance_scope) const { + CStructure *scope = current_scope; + while (scope && (scope->TemplateInfo () || + (consider_instance_scope && + scope->NamespaceInfo () && + scope->NamespaceInfo ()->aroundInstantiation ()))) + scope = scope->Parent ()->Structure (); + return scope; +} + + +CStructure *CCSemantic::getQualifiedScope (CStructure *scope) const { + CObjectInfo *oinfo; + if (scope && scope->isTemplateInstance () && ! scope->TemplateInstance ()->canInstantiate ()) { + oinfo = scope->TemplateInstance ()->Template ()->ObjectInfo (); + if (oinfo && oinfo->Structure ()) + return oinfo->Structure (); + } + return scope; +} + + +bool CCSemantic::isQualName (CT_SimpleName *name) const { + return name->NodeName () == CT_QualName::NodeId () || + name->NodeName () == CT_RootQualName::NodeId (); +} + + +void CCSemantic::qualifiedScopeName (CT_SimpleName *name, std::ostringstream &qn) const { + if (name->NodeName () == CT_RootQualName::NodeId ()) + qn << "::"; + if (isQualName (name)) { + int entries = name->Entries () - 1; + for (int i = 0; i < entries; i++) { + qn << ((CT_SimpleName*)name->Entry (i))->Text (); + if (i+1 < entries) + qn << "::"; + } + } else + qn << name->Text (); +} + + +bool CCSemantic::isBaseClass (CClassInfo *info, CClassInfo *base) const { + if (info == base) + return true; + for (unsigned i = 0; i < info->BaseClasses (); i++) + if (isBaseClass (info->BaseClass (i)->Class (), base)) + return true; + return false; +} + + +// ���3.4.3 typedefs to classes are classes +bool CCSemantic::realTypedef (CObjectInfo *info) const { + return info && ! info->TypeInfo ()->UnqualType ()->TypeRecord (); +} + + +void CCSemantic::enter_scope (CStructure *scp) { + CStructure *scope; + bool propagate = true; + + // propagate template parameters to nested scope (if any) + // (to simplify identification of template parameter names) + // ���14.6.1.5-7 do not propagate if scope belongs to definition + // of a class template member outside of the template definition + if (current_scope->TemplateInfo () && ! scp->TemplateInfo ()) { + scope = current_scope; + while (scope->TemplateInfo () && scope->Parent () && scope != scope->Parent ()) + scope = scope->Parent ()->Structure (); + if (! scope->Record ()) + propagate = false; + } + + if (propagate) + for (unsigned i = 0; i < current_scope->TemplateParams (); i++) + scp->addTemplateParam (current_scope->TemplateParam (i)); + + // enter nested scope + Semantic::enter_scope (scp); +} + + +bool CCSemantic::non_project_loc () { + FileUnit *funit; + Token *token; + Unit *unit; + + token = syntax ().token_provider->current (); + if (token) { + unit = (Unit*)token->belonging_to (); + if (unit) { + // same unit, so return last decision + if (unit == _last_unit) + return _last_body_skipped; + _last_unit = unit; + + // if macro expansion, get the file containing the macro call + while (unit && unit->isMacroExp ()) + unit = ((MacroUnit*)unit)->CallingUnit (); + + // must be a file unit + if (unit && unit->isFile ()) { + funit = (FileUnit*)unit; + + // file doesn't belong to project? + if (! funit->belongsTo (*_db->Project ())) { + _last_body_skipped = true; + return true; + } + } + } + } + + _last_body_skipped = false; + return false; +} + + +bool CCSemantic::non_primary_loc () { + Token* token = syntax ().token_provider->current (); + if (token) { + Unit* unit = (Unit*)token->belonging_to (); + if (unit) { + // if macro expansion, get the file containing the macro call + while (unit && unit->isMacroExp ()) + unit = ((MacroUnit*)unit)->CallingUnit (); + + // not the primary file? + if (unit != _file->Primary ()) { + return true; + } + } + } + return false; +} + + +/*****************************************************************************/ +/* */ +/* Names */ +/* */ +/*****************************************************************************/ + + +// lookup type-names and class-or-original-names more efficient +void CCSemantic::lookupName (const Token *tok, CStructure *scope, + bool nested) { + bool nested_name = in_nested_name (); + bool base_spec = in_base_spec (); + + // if same lookup as before, don't lookup again + if (//(shared_nl.Objects ()) && + (tok == last_token_nl.tok) && // => same token!!! + (scope == last_token_nl.scope) && + (nested == last_token_nl.nested) && + (nested_name == last_token_nl.nested_name) && + (base_spec == last_token_nl.base_spec)) + return; + + // not the same lookup as before, start new lookup + shared_nl.reset (current_scope, !is_entity_name()); + if (nested_name || base_spec) { + shared_nl.lookupType (tok->dtext (), scope, nested, true); + if (! shared_nl.Objects ()) { + shared_nl.reset (current_scope, !is_entity_name()); + shared_nl.lookupNamespace (tok->dtext (), scope); + } + if (! shared_nl.Objects ()) { + shared_nl.reset (current_scope, !is_entity_name()); + shared_nl.lookup (tok->dtext (), scope, nested, true); + } + } else + shared_nl.lookup (tok->dtext (), scope, nested, true); + + // remember the parameters of the last lookup + last_token_nl.tok = tok; + last_token_nl.scope = scope; + last_token_nl.nested = nested; + last_token_nl.nested_name = nested_name; + last_token_nl.base_spec = base_spec; +} + + +CTree *CCSemantic::typedef_name () { + CT_SimpleName *result = 0; + CObjectInfo *info; +// const char *name; + const Token *tok; + + if (! search_scope) + last_search_scope = 0; + +// name = builder ().get_node ()->token ()->text (); + tok = builder ().get_node ()->token (); + + if (search_scope) // qualified + lookupName (tok, search_scope, false); + else // unqualified + lookupName (tok, current_scope, true); + + if (shared_nl.Objects ()) { + info = shared_nl.Object (); + if (realTypedef (info->TypedefInfo ())) { + result = (CT_SimpleName*)builder ().simple_name (); + result->Object (info); + result->setTypeRef (info->TypeInfo ()); + } + } + + expect_template = false; + return result; +} + + +CTree *CCSemantic::class_name () { + CT_SimpleName *result = 0; + bool is_dep, tpl_param; + CObjectInfo *info; + CStructure *scope; + Token* tok; + CTypeInfo *type; + + // implicit `typename' hack + is_dep = dep_nested_name; + if (! in_nested_name ()) + dep_nested_name = false; + if (! search_scope) + last_search_scope = 0; + + // handle template-id + if (builder ().get_node ()->NodeName () == CT_TemplateName::NodeId ()) { + expect_template = false; + result = (CT_SimpleName*)builder ().get_node (); + info = result->Object (); + if (info && info->FunctionInfo()) + return (CTree*)0; + if (! search_scope && is_dep) + return result; + if (info && (info->Record() || info->TemplateParamInfo())) + return result; + if (result->Type() == &CTYPE_UNDEFINED) // dependent + return result; + return (CTree*)0; + } + + // part of a nested name that depends on a template parameter + if (is_dep && ! search_scope) { + result = (CT_SimpleName*)builder ().simple_name (); + result->setTypeRef (&CTYPE_UNDEFINED); + // dirty hack to support implicit `typename' :( + } else if (! in_expr () && search_scope && search_scope->TemplateInstance () && + ! search_scope->TemplateInstance ()->canInstantiate ()) { + result = (CT_SimpleName*)builder ().simple_name (); + info = search_scope; + result->Object (info); + result->setTypeRef (info->TypeInfo ()); + } else { + tok = builder ().get_node ()->token (); + scope = search_scope; + + // in case of "expr.id" or "expr->id" + if (! scope && _in_memb_access_expr.top ()) { + if (_postfix_expr.top ()->Type () && + ! _postfix_expr.top ()->Type ()->is_undefined ()) { + type = _postfix_expr.top ()->Type (); + is_dep = CCSemExpr::isDependent (_postfix_expr.top ()); + } else { + CCSemExpr cse (*_err, current_scope); + type = cse.resolveExpr (_postfix_expr.top ()); + is_dep = cse.isDependent (); + } + if (is_dep && expect_template) { + result = (CT_SimpleName*)builder ().simple_name (); + result->setTypeRef (&CTYPE_UNDEFINED); + expect_template = false; + return result; + } + + // get the member's class + if (type->isPointer ()) // "expr->id" + type = type->VirtualType ()->BaseType (); + if (type->isRecord ()) { + type = type->VirtualType (); + if (type->TypeRecord ()->Record ()) + scope = type->TypeRecord ()->Record ()->DefObject ()->Record (); + } + } + + if (scope) { // qualified + lookupName (tok, scope, false); + // in case of a qualified member name in a member access expression + // the member name is first looked up in the member's class and then, + // if name lookup fails, in the scope of the expression (current_scope) + if (scope != search_scope && ! shared_nl.Objects ()) + lookupName (tok, current_scope, true); + } else // unqualified + lookupName (tok, current_scope, true); + + if (shared_nl.Objects ()) { + info = shared_nl.Object (); + tpl_param = ((info->Record () || info->TemplateInfo () || + info->TypedefInfo () || info->TemplateParamInfo ()) && + info->TypeInfo () && // type template parameter + ((info->TypeInfo ()->is_unknown_t ()) || + (info->TypeInfo ()->TypeTemplateParam () && + info->TypeInfo ()->TypeTemplateParam ()->isType ()))); + if (info->Record () || tpl_param || + (info->TypedefInfo () && ! realTypedef (info))) { // typedef naming class + result = (CT_SimpleName*)builder ().simple_name (); + result->Object (info); + result->setTypeRef (info->TypeInfo ()); + } + } else if (is_dep && search_scope && search_scope->isTemplate ()) { + result = (CT_SimpleName*)builder ().simple_name (); + result->setTypeRef (&CTYPE_UNDEFINED); + } + } + + expect_template = false; + return result; +} + + +CTree *CCSemantic::template_name (bool class_only) { + CT_SimpleName *result = 0; + CTemplateInfo *tpinfo = 0; + CObjectInfo *info = 0; + CStructure *scope; + Token* tok; + CTypeInfo *type; + bool is_dep; + + if (syntax ().look_ahead (TOK_LESS)) { + // implicit `typename' hack + is_dep = dep_nested_name; + if (! in_nested_name ()) + dep_nested_name = false; + if (! search_scope) + last_search_scope = 0; + + // part of a nested name that depends on a template parameter + if (is_dep && ! search_scope) { + // name is prefixed by keyword `template' + if (expect_template || ! in_expr ()) { + result = (CT_SimpleName*)builder ().simple_name (); + result->setTypeRef (&CTYPE_UNDEFINED); + } + } else { + tok = builder ().get_node ()->token (); + scope = search_scope; + + // in case of "expr.id <" or "expr->id <" + MemberAccessOperator mao = _in_memb_access_expr.top (); + if (! scope && mao) { + if (_postfix_expr.top ()->Type () && + ! _postfix_expr.top ()->Type ()->is_undefined ()) { + type = _postfix_expr.top ()->Type (); + is_dep = CCSemExpr::isDependent (_postfix_expr.top ()); + } else { + CCSemExpr cse (*_err, current_scope); + type = cse.resolveExpr (_postfix_expr.top ()); + is_dep = cse.isDependent (); + } + if (is_dep && (expect_template || type == &CTYPE_UNDEFINED)) { + result = (CT_SimpleName*)builder ().simple_name (); + result->setTypeRef (&CTYPE_UNDEFINED); + expect_template = false; + return result; + } + + // get the member's class + bool pointer_type = type->isPointer (); + if (pointer_type) // "expr->id <" + type = type->VirtualType ()->BaseType (); + if (type->isRecord ()) { + type = type->VirtualType (); + if (type->TypeRecord ()->Record ()) { + scope = type->TypeRecord ()->Record ()->DefObject ()->Record (); + // check for and handle operator ->() + if (!pointer_type && mao == MAO_PTS) { + shared_nl.reset (current_scope, !is_entity_name()); + shared_nl.lookup ("operator ->", scope, false, true); + if (shared_nl.Objects () == 0) { + SEM_ERROR (_postfix_expr.top (), + "base operand of '->' has non-pointer type '" << *type << "'"); + return (CTree*)0; + } + else if (shared_nl.Objects () > 1) { + CObjectInfo *err_obj = shared_nl.Object (1); + SEM_ERROR (err_obj->Tree (), + "'" << err_obj->QualName () << "()' cannot be overloaded"); + return (CTree*)0; + } + else { + // search the template name in the class reference by the result + // type of the operator ->() + if (shared_nl.Object (0)->FunctionInfo ()) { + CTypeInfo *res_type = shared_nl.Object (0)->TypeInfo ()->BaseType (); + if (res_type && res_type->isPointer ()) { + type = res_type->VirtualType ()->BaseType ()->VirtualType (); + scope = type->TypeRecord ()->Record ()->DefObject ()->Record (); + } + } + } + } + } + } + } + + if (scope) // qualified + lookupName (tok, scope, false); + else // unqualified + lookupName (tok, current_scope, true); + + if (shared_nl.Objects ()) { + for (unsigned i = shared_nl.Objects (); i > 0; i--) { + info = shared_nl.Object (i-1); + tpinfo = 0; + + // template instance + if (info->isTemplateInstance ()) { + tpinfo = info->TemplateInstance ()->Template (); + if (tpinfo) + info = tpinfo->ObjectInfo (); + // base template or template template parameter + } else if (info->isTemplate () && + (info->TemplateParamInfo () ? ! search_scope : true)) { + if (info->TemplateParamInfo ()) + tpinfo = info->TemplateParamInfo ()->TemplateTemplate (); + else + tpinfo = info->Template (); + } else + continue; + break; + } + + if (tpinfo) { + // get the object of the base template + if (tpinfo->BaseTemplate ()) + info = tpinfo->BaseTemplate ()->ObjectInfo (); + + // reject function templates if not allowed at this point + if (! class_only || ! info->FunctionInfo ()) { + result = (CT_SimpleName*)builder ().simple_name (); + result->Object (info); + result->setTypeRef (info->TypeInfo ()); + } + } + } else if (is_dep && search_scope && search_scope->isTemplate ()) { + result = (CT_SimpleName*)builder ().simple_name (); + result->setTypeRef (&CTYPE_UNDEFINED); + } + } + } + + expect_template = false; + return result; +} + + +CTree *CCSemantic::enum_name () { + CT_SimpleName *result = 0; + CObjectInfo *info; +// const char *name; + Token *tok; + + if (! search_scope) + last_search_scope = 0; + + tok = builder ().get_node ()->token (); + + if (search_scope) // qualified + lookupName (tok, search_scope, false); + else // unqualified + lookupName (tok, current_scope, true); + + if (shared_nl.Objects ()) { + info = shared_nl.Object (); + if (info->EnumInfo ()) { + result = (CT_SimpleName*)builder ().simple_name (); + result->Object (info); + result->setTypeRef (info->TypeInfo ()); + } + } + + expect_template = false; + return result; +} + + +CTree *CCSemantic::original_ns_name () { + CT_SimpleName *result = 0; + CObjectInfo *info; +// const char *name; + Token *tok; + + if (! search_scope) + last_search_scope = 0; + + tok = builder ().get_node ()->token (); + + if (search_scope) // qualified + lookupName (tok, search_scope, false); + else // unqualified + lookupName (tok, current_scope, true); + + if (shared_nl.Objects ()) { + info = shared_nl.Object (); + if (info->NamespaceInfo () && ! info->NamespaceInfo ()->isAlias ()) { + result = (CT_SimpleName*)builder ().simple_name (); + result->Object (info); + result->setTypeRef (info->TypeInfo ()); + } + } + + expect_template = false; + return result; +} + + +CTree *CCSemantic::namespace_alias () { + CT_SimpleName *result = 0; + CObjectInfo *info; +// const char *name; + Token* tok; + + if (! search_scope) + last_search_scope = 0; + + tok = builder ().get_node ()->token (); + + if (search_scope) // qualified + lookupName (tok, search_scope, false); + else // unqualified + lookupName (tok, current_scope, true); + + if (shared_nl.Objects ()) { + info = shared_nl.Object (); + if (info->NamespaceInfo () && info->NamespaceInfo ()->isAlias ()) { + result = (CT_SimpleName*)builder ().simple_name (); + result->Object (info); + result->setTypeRef (info->TypeInfo ()); + } + } + + expect_template = false; + return result; +} + + +CTree *CCSemantic::nested_name_spec () { + if (is_entity_name ()) + dep_nested_name = false; + + // shall not be prefixed by `template' + if (builder ().get_node ()->token ()->type () == TOK_TEMPLATE) + return (CTree*)0; + + return builder ().nested_name_spec (); +} + + +CTree *CCSemantic::nested_name_spec1 () { + CT_SimpleName *name; + + name = (CT_SimpleName*)builder ().get_node (builder ().nodes ()-2); + // dependent nested name specifier of the form `T::...' + // suppress further semantic analysis +// if (! dep_nested_name) { +// if (! search_scope && +// name->Object () && +// name->Object ()->TypeInfo () && +// name->Object ()->TypeInfo ()->isDependent ()) +// dep_nested_name = true; +// else +// last_search_scope = search_scope = getScope (name->Object ()); +// } + if (name->Object ()) { + if (name->Object ()->TypeInfo () && + name->Object ()->TypeInfo ()->isDependent ()) + dep_nested_name = true; + last_search_scope = search_scope = getScope (name->Object ()); + } + return builder ().nested_name_spec1 (); +} + + +CTree *CCSemantic::colon_colon () { + search_scope = _file; + return builder ().get_node (); +} + + +bool CCSemantic::reset_search_scope (bool also_last) { + search_scope = 0; + if (also_last) + last_search_scope = 0; + dep_nested_name = false; + return true; +} + + +/*****************************************************************************/ +/* */ +/* Functions */ +/* */ +/*****************************************************************************/ + + +CTree *CCSemantic::introduce_function () { + CStructure *scope, *lookup_scope; + bool is_friend, is_qual_name, is_special; + CTypeInfo *type; + CTemplateInfo *tinfo; + CT_DeclSpecSeq *dss; + CFunctionInfo *info; + CSemDeclSpecs *dsi; + CT_Declarator *d; + + if (! current_fct) + return (CTree*)0; // Fatal internal error + + // determine function return type + dss = (CT_DeclSpecSeq*)(builder ().nodes () == 2 ? builder ().get_node (0) : 0); + d = (CT_Declarator*)(dss ? builder ().get_node (1) : builder ().get_node (0)); + if (dss && ! in_decl ()) + return (CTree*)0; + + // determine function type + dsi = sem_decl_specs (); + CCSemDeclarator csd (_err, dsi->make_type (), d); + if (! csd.Name () || ! csd.Type () || ! csd.Type ()->VirtualType ()->TypeFunction ()) + return (CTree*)0; + + // determine function attributes + type = csd.Type (); + is_qual_name = isQualName (csd.Name ()); + is_friend = (dsi->declared (CT_PrimDeclSpec::PDS_FRIEND)); + is_special = isSpecialization (csd.Name ()); + info = (CFunctionInfo*)current_fct; + lookup_scope = is_special ? current_scope : getNonTplScope (true); + + // lookup name + CCNameLookup nl (*_err, current_scope, false); + if (! is_friend || is_qual_name) { + scope = is_qual_name ? getNameScope (csd.Name ()) : lookup_scope; + if (is_qual_name && scope == lookup_scope) { + // ignore extra qualification if it refers to current class scope + // lookup as if no qualification is given + is_qual_name = false; + nl.lookupFunction (csd.Name ()->Name (), lookup_scope); + } else { + if (is_qual_name) { + // definition of member function inside class def of another class + if (! is_friend && lookup_scope->Record ()) { + SEM_ERROR__cannot_declare (d, csd.Name (), lookup_scope); + return (CTree*)0; + } + lookup_scope = scope; + } + nl.lookupFunction (csd.Name (), lookup_scope); + } + } else { // friend && unqualified + scope = lookup_scope = getFriendScope (false); + nl.lookupFunction (csd.Name (), lookup_scope); + if (! nl.Objects ()) { + // lookup in non-template scope + scope = lookup_scope = getFriendScope (true); + nl.lookupFunction (csd.Name (), lookup_scope); + } + } + + // handle function templates + tinfo = current_scope->TemplateInfo (); + if (tinfo) { + setSpecializationName (csd.Name (), tinfo); + setTemplateScope (nl, info, csd.Type (), tinfo, is_qual_name); + } + + // definition of class or namespace member + if ((! is_friend || is_qual_name) && + (lookup_scope->Record () || (is_qual_name && lookup_scope->NamespaceInfo ()))) { + info->QualifiedScope (getQualifiedScope (lookup_scope)); + // class member (method) + if (lookup_scope->Record ()) { + // definition of class constructor? + if (lookup_scope->Name () && + ! strcmp (lookup_scope->Name (), csd.Name ()->Text ())) + info->isConstructor (true); + + // determine member protection + setProtection (info); + + // create implicit `this' parameter + addImplicitThisObject (info, type, d); + } + } + + // determine member function category + if (csd.Name ()->Name ()->NodeName () == CT_DestructorName::NodeId ()) + info->isDestructor (true); + else if (csd.Name ()->Name ()->NodeName () == CT_OperatorName::NodeId ()) + info->isOperator (true); + else if (csd.Name ()->Name ()->NodeName () == CT_ConversionName::NodeId ()) { + info->isConversion (true); + info->ConversionType (((CT_ConversionName*)csd.Name ()->Name ())-> + TypeName ()->Object ()->TypeInfo ()); + } + + // determine member function specifiers such as `virtual' + if (! is_friend) { + setLanguage (info); + setSpecifiers (info, dsi); + if (current_scope->Record ()) + info->isInline (true); + // add friend to class + } else { + info->AssignedScope (lookup_scope); + if (current_scope->Record ()) + info->addFriend (current_scope->Record ()); + } + + // check name lookup results + if (! check_function_lookup (nl, lookup_scope, dsi, csd, d, is_qual_name)) + return (CTree*)0; + + // enter function scope (re-used function prototype scope) +/*DEBUG*/if (TRACE_FCT) std::cout<<"FCT ENT(1): "<<(void*)current_fct<VirtualType ()->TypeFunction ()->FunctionInfo (info); + info->Name (csd.Name ()->Text ()); + info->SourceInfo ()->FileInfo (_file); + info->ObjectInfo ()->TypeInfo (type); + + // add function to surrounding scope + if (! is_friend) + info->Parent ()->Structure ()->addFunction (info); + else if (! is_qual_name) + lookup_scope->addFunction (info); + + // handle template declarations + if (current_scope->Parent ()->TemplateInfo ()) + introduceTemplate (info, current_scope->Parent ()->TemplateInfo (), is_friend); + + // link function with previous declarations + if (! is_special) + linkFctDecls (nl, info); + if (info->isConstructor ()) + linkCtorDecls (info); + + // clean up + csd.Type ((CTypeInfo*)0); + csd.Name ()->Object (info); + csd.Name ()->setTypeRef (type); + if (! csd.Name ()->Name ()->Object ()) { + csd.Name ()->Name ()->Object (info); + csd.Name ()->Name ()->setTypeRef (type); + } + + // if return type or a parameter type is class object type, + // ensure that the class is really instantiated + /* + CTypeFunction* ftype = type->VirtualType()->TypeFunction(); + if (ftype->ReturnType()->UnqualType()->TypeClass()) { + ftype->ReturnType()->UnqualType()->TypeClass()->instantiate(current_scope); + } + CTypeList *ptypes = ftype->ArgTypes(); + if (ptypes) { + for (unsigned i = 0; i < ptypes->Entries(); i++) { + CTypeInfo* ptype = ptypes->Entry(i); + if (ptype && ptype->UnqualType()->TypeClass()) { + ptype->UnqualType()->TypeClass()->instantiate(current_scope); + } + } + }*/ + + if (dss) decl_end (); + return d; +} + + +bool CCSemantic::check_function_lookup (CCNameLookup &nl, CStructure *lookup_scope, + CSemDeclSpecs *dsi, CCSemDeclarator &csd, CTree *d, bool is_qual_name) { + CFunctionInfo *info; + CT_SimpleName *name; + CObjectInfo *oinfo; + CStructure *scope; + CTypeInfo *type; + unsigned i = 0; + bool is_friend, is_special; + + info = (CFunctionInfo*)current_fct; + name = csd.Name (); + type = csd.Type (); + is_friend = (dsi->declared (CT_PrimDeclSpec::PDS_FRIEND)); + is_special = isSpecialization (csd.Name ()); + scope = getNonTplScope (); + + // check all functions looked up + if (nl.Objects ()) { + oinfo = nl.Object (); + if (oinfo->FunctionInfo ()) { + do { + if (oinfo && (oinfo->isTemplate () == info->isTemplate ()) && ! is_special && + (oinfo->Template () ? ! oinfo->Template ()->isSpecialization () : true)) { + if (equalType (type, oinfo->TypeInfo ()) && (!oinfo->Template () || + CTemplateInfo::equalParameters(info->TemplateInfo (), oinfo->TemplateInfo ()))) { + if (oinfo->FunctionInfo ()->isDefined ()) { + SEM_ERROR__redefinition (d, name, oinfo); + return false; + } else if (is_qual_name && ! is_friend && scope->Record ()) { + SEM_ERROR__already_defined (d, name, oinfo); + return false; + } + } + + // definition of member function outside of class body + if (equalType (type, oinfo->TypeInfo (), false)) { + info->Protection (oinfo->Protection ()); + info->isVirtual (oinfo->isVirtual ()); + info->isStatic (oinfo->isStatic ()); + oinfo->isInline (info->isInline ()); + } + } + } while (++i < nl.Objects () && (oinfo = nl.Object (i))); + // constructors are never found by name lookup + } else if (! (info->isConstructor () || isClassOrEnum (oinfo))) + return false; + // qualified function name not found + } else if (is_qual_name) { + std::ostringstream qname; qualifiedScopeName (name, qname); + SEM_ERROR__not_member (d, name->Name (), qname.str ().c_str ()); + return false; + } + + // check function properties + if (scope->isLocalScope () && scope->insideFunction ()) { + SEM_ERROR (d, "nested function `" << *name << "'"); + return false; + } else if (dsi->declared (CT_PrimDeclSpec::PDS_TYPEDEF)) { + SEM_ERROR (d, "typedef declaration invalid in definition of function `" + << *name << "'"); + return false; + } else if (dsi->declared (CT_PrimDeclSpec::PDS_AUTO) || + dsi->declared (CT_PrimDeclSpec::PDS_REGISTER)) { + SEM_ERROR (d, "wrong storage class specifier in definition of function `" + << *name << "'"); + return false; + } else if (! type->isFunction ()) + return false; + return true; +} + + +void CCSemantic::addImplicitThisObject(CFunctionInfo* info, CTypeInfo* type, CTree* tree) { + // create implicit `this' object + CRecord *record = info->Record(); + if (record && ! info->isStatic()) { + CTypeInfo *thistype = record->TypeInfo()->Duplicate(); + if (type->VirtualType()->TypeFunction()->isConst() || + type->VirtualType()->TypeFunction()->isVolatile()) + thistype = new CTypeQualified(thistype, + type->VirtualType()->TypeFunction()->isConst(), + type->VirtualType()->TypeFunction()->isVolatile(), false); + thistype = new CTypePointer(thistype); + + CObjectInfo *oinfo = info->newAttribute(); + oinfo->Name("this"); + oinfo->Storage(CStorage::CLASS_AUTOMATIC); + oinfo->SourceInfo()->FileInfo(_file); + oinfo->SourceInfo()->StartToken(tree->token_node()); + oinfo->TypeInfo(thistype); + Push(oinfo); + } +} + + +CTree *CCSemantic::introduce_parameter () { + CArgumentInfo *info; + CSemDeclSpecs *dsi; + CT_ArgDecl *ad; + + if (! in_decl ()) + return (CTree*)0; + + // determine parameter type + ad = (CT_ArgDecl*)builder ().param_decl1 (); + dsi = sem_decl_specs (); + CCSemDeclarator csd (_err, dsi->make_type (), ad->Declarator ()); + if (! csd.Name ()) { + delete ad; + return (CTree*)0; + } + + // check function parameter properties + bool error = true; + if (current_scope->FunctionInfo ()->Argument (csd.Name ()->Text ())) { + SEM_ERROR__duplicate (ad, "function parameter", csd.Name ()); + } else if (dsi->declared (CT_PrimDeclSpec::PDS_STATIC) || + dsi->declared (CT_PrimDeclSpec::PDS_EXTERN)) { + SEM_ERROR__invalid_in_param (ad, "storage class specifier", csd.Name ()); + } else if (dsi->declared (CT_PrimDeclSpec::PDS_TYPEDEF)) { + SEM_ERROR__invalid_in_param (ad, "typedef declaration", csd.Name ()); + } else if (csd.Name ()->NodeName () != CT_QualName::NodeId () && + csd.Name ()->NodeName () != CT_RootQualName::NodeId ()) + error = false; + if (error) { + delete ad; + return (CTree*)0; + } + + // complete semantic information about the function parameter + info = current_scope->FunctionInfo ()->newArgument (); + common_settings (info, ad, &csd); + info->Storage (CStorage::CLASS_AUTOMATIC); + setLanguage (info); + setSpecifiers (info, dsi); + Push (info); + ad->Object (info); + ad->setTypeRef (info->TypeInfo ()); + + return ad; +} + + +void CCSemantic::enter_param_decl_clause () { + // create and enter new function prototype scope + CObjectInfo* instance = tpl_inst ? tpl_inst->Instance () : 0; + if (parsing_fct_inst && instance && + ! instance->TemplateInstance ()->isInstantiated () && + current_scope->isNamespace ()) { + tpl_inst->insertInstance (instance); + // to be left if param decl clause is done + reenter_scope (instance->Structure ()); + } else { + CFunctionInfo *info = _db->newFunction(); + enter_scope (info); + } + _in_param_decl_clause.push (true); + // qualified function name + if (last_search_scope) + current_scope->FunctionInfo ()->QualifiedScope (getQualifiedScope (last_search_scope)); +} + + +void CCSemantic::leave_param_decl_clause () { + last_search_scope = (CStructure*)0; + CSemantic::leave_param_decl_clause (); + + CObjectInfo* instance = tpl_inst ? tpl_inst->Instance () : 0; + if (parsing_fct_inst && instance && current_scope == instance) { + // reentered the scope of function instance, now reenter + // the parent scope + reenter_scope (current_scope->Parent ()->Structure ()); + } +} + + +CTree *CCSemantic::condition () { + CSemDeclSpecs *dsi; + CT_Condition *cond; + CObjectInfo *info; + CTypeInfo *type; + + if (! in_decl ()) + return (CTree*)0; + + // determine type of condition declaration + cond = (CT_Condition*)builder ().condition (); + dsi = sem_decl_specs (); + CCSemDeclarator csd (_err, dsi->make_type (), cond->Declarator ()); + if (! csd.Name ()) { + delete cond; + return (CTree*)0; + } + + // check properties of the condition declaration + bool error = true; + type = csd.Type (); + if (type->isFunction () || type->isArray ()) { + SEM_ERROR (cond, "function or array type in condition"); + } else if (dsi->declared (CT_PrimDeclSpec::PDS_TYPEDEF)) { + SEM_ERROR (cond, "typedef in condition"); + } else if (dsi->defClass () || dsi->defEnum ()) { + SEM_ERROR (cond, "class or enumeration defined in condition"); + } else if (isQualName (csd.Name ())) { // qualified name + CCNameLookup nl (*_err, current_scope, false); + nl.lookup (csd.Name (), current_scope); + if (! nl.Objects ()) { + if (current_scope != getNameScope (csd.Name ())) { + std::ostringstream name; qualifiedScopeName (csd.Name (), name); + SEM_ERROR__not_member (cond, csd.Name ()->Name (), name.str ().c_str ()); + } + } else { + SEM_ERROR__redefinition (cond, csd.Name (), nl.Object ()); + } + } else + error = false; + if (error) { + delete cond; + return (CTree*)0; + } + + // complete semantic information about the condition + info = current_scope->newAttribute (); + common_settings (info, cond, &csd); + setLanguage (info); + setSpecifiers (info, dsi); + info->Linkage (determine_linkage (dsi, ATTRIB)); + info->Storage (determine_storage_class (dsi)); + Push (info); + cond->Object (info); + decl_end (); + return cond; +} + + +bool CCSemantic::equalType (CTypeInfo *t1, CTypeInfo *t2, bool consider_dependent) const { + if (t1->isFunction () && t2->isFunction ()) + return t1->equals (*t2, true, consider_dependent); + else + return *t1 == *t2; +} + + +void CCSemantic::linkFctDecls (CCNameLookup &nl, CObjectInfo *info) const { + CObjectInfo *oinfo; + + for (unsigned i = 0; i < nl.Objects (); i++) { + oinfo = nl.Object (i); + if (oinfo && oinfo->FunctionInfo () && + oinfo->isTemplate () == info->isTemplate () && + (oinfo->Template () ? ! oinfo->Template ()->isSpecialization () : true) && + equalType (info->TypeInfo (), oinfo->TypeInfo (), false)) { + oinfo->NextObject (info); + info->Language () = oinfo->Language (); + break; + } + } +} + + +void CCSemantic::linkCtorDecls (CObjectInfo *info) const { + CObjectInfo *oinfo; + + if (info && info->QualifiedScope ()) { + CStructure *scope = info->QualifiedScope (); + for (unsigned i = 0; i < scope->Functions (); i++) { + oinfo = scope->Function (i); + if (oinfo && oinfo->FunctionInfo ()->isConstructor () && + oinfo->isTemplate () == info->isTemplate () && + (oinfo->Template () ? ! oinfo->Template ()->isSpecialization () : true) && + equalType (info->TypeInfo (), oinfo->TypeInfo (), false)) { + oinfo->NextObject (info); + info->Language () = oinfo->Language (); + break; + } + } + } +} + + +bool CCSemantic::implicit_int () { + if (! current_scope->isNamespace () && ! current_scope->TemplateInfo ()) + return false; + + CT_DeclSpecSeq *dss = new CT_DeclSpecSeq; + decl_specs_begin (dss); + begin_decl (); + //CT_PrimDeclSpec *pds = new CT_PrimDeclSpec (CT_PrimDeclSpec::PDS_INT); + //dss->AddSon (pds); + //builder ().Push (pds); + builder ().Push (dss); + return true; +} + + +/*****************************************************************************/ +/* */ +/* Enumerations */ +/* */ +/*****************************************************************************/ + + +CTree *CCSemantic::introduce_enum () { + CObjectInfo *info; + CT_EnumDef *ed; + + ed = (CT_EnumDef*)builder ().enum_spec1 (); + + // lookup name in current scope + CCNameLookup nl (*_err, current_scope, false); + nl.lookupType (ed->Name (), current_scope); + if (nl.Objects ()) { + info = nl.Object (); + // enum already defined in current scope + if (info->EnumInfo () && info->EnumInfo ()->isDefined ()) { + SEM_ERROR__redefinition (ed, ed->Name (), info); + delete ed; + return (CTree*)0; + // conflicting declaration in current scope + } else if (! info->EnumInfo ()) { + SEM_ERROR__already_defined (ed, ed->Name (), info); + delete ed; + return (CTree*)0; + } + } + + // complete semantic information about the enum + info = current_scope->newEnum (); + setProtection (info); + common_settings (info, ed); + info->TypeInfo (new CTypeEnum (info->EnumInfo ())); + info->Name (ed->Name ()->Text ()); + current_enum = info->EnumInfo (); + Push (info); + + // link forward declarations with this definition + if (nl.Objects ()) + nl.Object ()->NextObject (info); + + // attribute syntax tree + ed->Name ()->Object (info); + ed->Name ()->setTypeRef (info->TypeInfo ()); + ed->Object (info); + return ed; +} + + +CTree *CCSemantic::introduce_enumerator () { + CT_Enumerator *result; + CT_SimpleName *name; + CObjectInfo *info; + + name = (CT_SimpleName*)builder ().get_node (); + + // lookup name in current scope + CCNameLookup nl (*_err, current_scope, false); + nl.lookup (name, current_scope); + if (nl.Objects ()) { + info = nl.Object (); + // conflicting declaration in current scope + if (! (info->Record () || info->EnumInfo ())) { + SEM_ERROR__already_defined (name, name, info); + return (CTree*)0; + } + } + + // complete semantic information about enumerator + result = (CT_Enumerator*)builder ().enumerator (); + info = current_enum->newEnumerator (); + common_settings (info, result); + info->EnumeratorInfo ()->Scope (current_scope); + info->Name (name->Text ()); + info->Storage (CStorage::CLASS_AUTOMATIC); + current_scope->addAttribute (info->EnumeratorInfo ()); + info->TypeInfo (current_enum->TypeInfo ()->Duplicate ()); + setProtection (info); + Push (info); + + // attribute syntax tree + result->Object (info); + result->Name ()->Object (info); + result->Name ()->setTypeRef (current_enum->TypeInfo ()); + return result; +} + + +CTree *CCSemantic::enumerator_def () { + CEnumeratorInfo *einfo; + CEnumInfo *enuminfo; + CT_Enumerator *e; + CTypeInfo *type; + CConstant *v; + CTree *init; + LONG_LONG value = 0; + unsigned numenums; + + e = (CT_Enumerator*)builder ().enumerator_def (); + + if (e && e->Object ()) { + einfo = e->Object ()->EnumeratorInfo (); + enuminfo = einfo->Enum (); + numenums = enuminfo->Enumerators (); + + // if the enumerator has an initializer, get the value + // from this constant expression + init = e->Initializer (); + if (init) { + type = init->Son (1)->Type (); + init = init->Son (1); + + if (! CCSemExpr::isConstIntExpr (init)) { + if (! CCSemExpr::isDependent (init)) { + SEM_ERROR (e, "value for enumerator `" << e->Name ()->Text () + << "' isn't integer constant expression"); + } + return e; + } else { + v = init->Value ()->Constant (); + if (type->VirtualType ()->is_signed ()) { + value = v->convert_to_int (); + } else { + value = v->convert_to_uint (); + } + } + // else get the value from the predecessor enumerator incremented by 1 + } else if (numenums > 1) { + if (! enuminfo->Enumerator (numenums - 2)->hasValue ()) + return e; + value = enuminfo->Enumerator (numenums - 2)->Value (); + value++; + // else this is the first enumerator, so the value is 0 + } else { + value = 0; + } + + // set the value + einfo->Value (value); + einfo->hasValue (true); + + // determine the underlying type of the enumeration, + // must be big enough to hold all enumerator values + type = enuminfo->UnderlyingType (); + bool long_gt_int = CTYPE_LONG.Size() > CTYPE_INT.Size(); + long int size = CTypePrimitive::SizeOfNumber (value); + if (value < 0) { + // signed type + if (type->is_unsigned ()) { + type = long_gt_int && *type == CTYPE_UNSIGNED_INT ? &CTYPE_LONG : &CTYPE_LONG_LONG; + } else if (size > CTYPE_LONG_LONG.Size()) { + type = &CTYPE_INT128; + } else if (size > CTYPE_LONG.Size()) { + type = &CTYPE_LONG_LONG; + } else if (size > CTYPE_INT.Size()) { + type = long_gt_int && *type == CTYPE_INT ? &CTYPE_LONG : &CTYPE_LONG_LONG; + } + } else { + // unsigned, if value cannot be represented by a + // signed type and no other value is signed + bool is_unsigned = numenums == 1 || type->is_unsigned (); + if (size <= CTYPE_INT.Size()) { + type = &CTYPE_INT; + } else if (size <= CTYPE_UNSIGNED_INT.Size()) { + type = is_unsigned ? &CTYPE_UNSIGNED_INT : long_gt_int ? &CTYPE_LONG : &CTYPE_LONG_LONG; + } else if (size <= CTYPE_LONG.Size()) { + type = &CTYPE_LONG; + } else if (size <= CTYPE_UNSIGNED_LONG.Size()) { + type = is_unsigned ? &CTYPE_UNSIGNED_LONG : &CTYPE_LONG_LONG; + } else if (size <= CTYPE_LONG_LONG.Size()) { + type = &CTYPE_LONG_LONG; + } else if (size <= CTYPE_UNSIGNED_LONG_LONG.Size()) { + type = &CTYPE_UNSIGNED_LONG_LONG; + } else { + type = is_unsigned ? &CTYPE_UNSIGNED_INT128 : &CTYPE_INT128; + } + } + if (enuminfo->UnderlyingType ()->rank () < type->rank ()) { + enuminfo->UnderlyingType (type); + } + } + + return e; +} + + +/*****************************************************************************/ +/* */ +/* Classes */ +/* */ +/*****************************************************************************/ + + +void CCSemantic::enter_class_def () { + if (! _outermost_class_def) { + // find the outermost not complete parsed class or union + CScopeInfo* scope = current_scope; + while (scope && !scope->isFile()) { + if (scope->Record() && !scope->Record()->isCompleteParsed()) + _outermost_class_def = (CRecord*)scope; + scope = scope->Parent(); + } + } + // save list position to be able to reject delayed function + // bodies and initializers of this class if parsing the + // class definition fails + _outermost_class_def->saveParseDelayedListLength(); +} + + +void CCSemantic::leave_class_def (bool reject) { + // mark as complete parsed and clean up + current_scope->Record()->isCompleteParsed(true); + + // if parsing the class failed, reject the function bodies and + // initializers of this class noted to be parsed at the end of + // the outermost class definition + if (reject) + _outermost_class_def->rejectParseDelayed(); + else + _outermost_class_def->forgetParseDelayedListLength(); + + // leaving outermost class def? + if (_outermost_class_def == current_scope) { + // now parse function bodies and several initializers not parsed due + // to potential use of names of members that could not be resolved + // untill the end of the class definition + parseDelayed(); + _outermost_class_def = 0; + } + + // clean up + if (current_scope->Record()->ParseDelayed()) + current_scope->Record()->resetDelayed(); +} + + +CTree *CCSemantic::introduce_class () { + bool error, is_special; + CStructure *lookup_scope; + CTemplateInfo *tinfo; + CObjectInfo *info, *prev; + CT_ClassDef *cs; + + // determine class properties + cs = (CT_ClassDef*) builder ().class_head1 (); + is_special = isSpecialization (cs->Name ()); + + // implicit template scope around class template explicit specialization + if (is_special && ! current_scope->TemplateInfo ()) { + info = cs->Name ()->Object (); + if (info && info->TemplateInfo ()) + reenter_scope (info->Structure ()); + } + + prev = 0; + info = 0; + + // lookup name + CCNameLookup nl (*_err, current_scope, false); + lookup_scope = is_special ? current_scope : getNonTplScope (); + nl.lookupType (cs->Name (), lookup_scope); + error = true; + + if (nl.Objects ()) { + prev = nl.Object (); + // class already defined in lookup scope + if (prev->Record () && prev->Record ()->isDefined () && ! is_special) { + SEM_ERROR__redefinition (cs, cs->Name (), prev); + // conflicting declaration in lookup scope + } else if (! prev->Record () || + (cs->NodeName () == CT_ClassDef::NodeId () && ! prev->ClassInfo ()) || + (cs->NodeName () == CT_UnionDef::NodeId () && ! prev->UnionInfo ())) { + SEM_ERROR__already_defined (cs, cs->Name (), prev); + } else + error = false; + // class defined using qualified name but class does not exist + } else if (isQualName (cs->Name ())) { + std::ostringstream name; qualifiedScopeName (cs->Name (), name); + SEM_ERROR__not_member (cs, cs->Name ()->Name (), name.str ().c_str ()); + } else + error = false; + + if (error) { + delete cs; + return (CTree*)0; + } + + // union definition + if (cs->NodeName () == CT_UnionDef::NodeId ()) { + info = current_scope->newUnion (); + info->TypeInfo (new CTypeUnion (info->UnionInfo ())); + setProtection (info); + // set member access + _protection.push (CProtection::PROT_PUBLIC); + // class definition + } else { + info = current_scope->newClass (); + info->TypeInfo (new CTypeClass (info->ClassInfo ())); + setProtection (info); + // set member access + if (cs->token ()->type () == TOK_STRUCT) + _protection.push (CProtection::PROT_PUBLIC); + else + _protection.push (CProtection::PROT_PRIVATE); + } + + // complete semantic information about class or union + info->Name (cs->Name ()->Text ()); + enter_scope (info->Structure ()); + setLanguage (info); + common_settings (info, cs); + cs->Name ()->Object (info); + cs->Name ()->setTypeRef (info->TypeInfo ()); + cs->Object (info); + + // link forward declarations with this definition + if (prev) + prev->NextObject (info); + + // handle class templates + tinfo = current_scope->Parent ()->TemplateInfo (); + if (tinfo) { + setSpecializationName (cs->Name (), tinfo); + setTemplateScope (nl, info, info->TypeInfo (), tinfo, isQualName (cs->Name ())); + introduceTemplate (info, tinfo); + } + + // set qualified scope if this is the definition of a nested class + // outside of the class definition + if (isQualName (cs->Name ()) && prev && prev->Structure ()) { + info->Record ()->QualifiedScope (getQualifiedScope ( + prev->Structure ()->Parent ()->Structure ())); + } + + // semantic state to let parse function bodies and several initializers + // later due to potential use of names of members that could not be + // resolved untill the end of the class definition + enter_class_def (); + + return cs; +} + + +CTree *CCSemantic::add_base_classes () { + CT_ClassDef *cd = (CT_ClassDef*)builder ().class_head (); + addBaseClasses (current_scope->ClassInfo (), cd); + return cd; +} + + +void CCSemantic::addBaseClasses (CClassInfo *cinfo, CT_ClassDef *cd) { + CT_BaseSpecList *bl = cd->BaseClasses (); + if (cinfo && bl) { + int num = bl->Entries (); + for (int i = 0; i < num; i++) + addBaseClass (cinfo, (CT_BaseSpec*)bl->Entry (i)); + } +} + + +void CCSemantic::addBaseClass (CClassInfo *cinfo, CT_BaseSpec *bs) { + CBaseClassInfo *bcinfo; + CObjectInfo *info; + CTypeClass *type; + CTypeInfo *otype; + int access_level; + CTree *access; + + info = bs->Name ()->Name ()->Object (); + if (! info) { + // must depend on a template parameter + cinfo->hasDepBaseClass (true); + return; + } + + // handle typedefs + if (info->TypedefInfo ()) + otype = info->TypedefInfo ()->TypeInfo (); + else + otype = info->TypeInfo (); + + type = otype->TypeClass (); + if (! type) { + // if not class type this must be a template type param type + if (! otype->TypeTemplateParam () || + ! otype->TypeTemplateParam ()->isType ()) { + SEM_ERROR__not_class (bs, bs->Name ()); + } + cinfo->hasDepBaseClass (true); + return; + } + + if (type->ClassInfo ()->TemplateInstance () && + ! type->ClassInfo ()->TemplateInstance ()->canInstantiate ()) { + cinfo->hasDepBaseClass (true); + } + else if (type->ClassInfo ()->hasDepBaseClass ()) { + cinfo->hasDepBaseClass (true); + } + + // create new base class semantic info object + bcinfo = cinfo->newBaseClass (type->ClassInfo ()); + common_settings (bcinfo, bs); + bcinfo->Scope (cinfo); + bcinfo->TypeInfo (&CTYPE_UNDEFINED); + Push (bcinfo); + bs->Name ()->Object (type->ClassInfo ()); + bs->Name ()->setTypeRef (type); + + // determine properties of base class + if (bs->Virtual ()) + bcinfo->isVirtual (true); + access = bs->AccessSpec (); + if (access) { + access_level = access->token ()->type (); + if (access_level == TOK_PUBLIC) + bcinfo->Protection (CProtection::PROT_PUBLIC); + else if (access_level == TOK_PROTECTED) + bcinfo->Protection (CProtection::PROT_PROTECTED); + else // if (access_level == TOK_PRIVATE) + bcinfo->Protection (CProtection::PROT_PRIVATE); + // ���11.2.2 no access specifier given: the base class is assumed + // to be PUBLIC when derived class is declared >struct< + // otherwise base class is PRIVATE + } else { + if (cinfo->isStruct ()) + bcinfo->Protection (CProtection::PROT_PUBLIC); + else + bcinfo->Protection (CProtection::PROT_PRIVATE); + } +} + + +CTree *CCSemantic::access_spec () { + CT_AccessSpec *as = (CT_AccessSpec*)builder ().member_decl (); + if (as->Access () == TOK_PUBLIC) + _protection.top () = CProtection::PROT_PUBLIC; + else if (as->Access () == TOK_PROTECTED) + _protection.top () = CProtection::PROT_PROTECTED; + else if (as->Access () == TOK_PRIVATE) + _protection.top () = CProtection::PROT_PRIVATE; + return as; +} + + +CTree *CCSemantic::class_spec () { + CObjectInfo *info, *oinfo; + CMemberAliasInfo *minfo; + CT_ClassDef *result; + CStructure *scope; + + // switch to enclosing member access level + _protection.pop (); + + result = (CT_ClassDef*)builder ().class_spec (); + result->Members ()->Scope (current_scope); + + // ���12.1 implicitly declare default constructor, copy constructor, + // copy assignment operator, and destructor if not explicitly + // declared by the program + declareSpecialMembers (); + + // finished parsing a class or union definition; now parse + // function bodies and several initializers not parsed due to + // potential use of names of members that could not be resolved + // untill the end of the class definition + leave_class_def (); + + // ���9.5.2 if this is an anonymous union and no instance of + // this union is created, then the data members of that union are + // introduced in the enclosing scope + // as an extension to the C++ language standard anonymous structs + // are supported too + if (! (current_scope->isAnonymous () && syntax ().look_ahead (TOK_SEMI_COLON) && + (current_scope->isUnion () || (current_scope->isClass () && + current_scope->ClassInfo ()->isStruct ())))) + return result; + + scope = current_scope->Parent ()->Structure (); + for (unsigned i = 0; i < current_scope->/*Objects*/Attributes (); i++) { + info = current_scope->/*Object*/Attribute (i); + + //// skip implicitly declared member functions + //if (info->isBuiltin ()) + // continue; + // + //// ���9.5.2 only non-static data members shall be defined in + //// an anonymous union + //if (! info->AttributeInfo ()) { + // SEM_ERROR (result, + // "anonymous unions can only have non-static data members"); + // continue; + //} + + // introduce member in enclosing scope; there shall be + // no other entity with the same name + CCNameLookup nl (*_err, current_scope, !is_entity_name()); + nl.lookup (info->Name (), scope); + if (nl.Objects ()) { + oinfo = nl.Object (); + if (! (oinfo->Record () || oinfo->EnumInfo ())) { + SEM_ERROR (info->Tree (), "redefinition of `" << info->Name () << "'"); + SEM_MSG__prev_loc (oinfo); + continue; + } + } + + // create new member alias in enclosing scope + minfo = scope->newMemberAlias (info, true); + minfo->Name (info->Name ()); + minfo->Member (info); + minfo->TypeInfo (info->TypeInfo ()->Duplicate ()); + setProtection (minfo); // adjust member access + Push (minfo); + common_settings (minfo, info->Tree ()); + } + return result; +} + + +CTree *CCSemantic::class_spec_err () { + // finished parsing a class or union definition; reject parsing + // function bodies and several initializers not parsed due to + // potential use of names of members that could not be resolved + // untill the end of the class definition + leave_class_def (true); + + // switch to enclosing member access level + _protection.pop (); + + return 0; +} + + +void CCSemantic::declareImplicitFcts () { + CFunctionInfo *info; + CTypeInfo *type; + CTypeList *args; + + // ���3.7.3 declare global allocation and deallocation + // functions new and delete + + // allocation functions + // void *operator new(std::size_t) throw(std::bad_alloc); + args = new CTypeList (1); + args->AddEntry (CTypeInfo::CTYPE_SIZE_T); + type = new CTypePointer (&CTYPE_VOID); + type = new CTypeFunction (type, args, true); + info = createFunction ("operator new", current_scope, type); + info->isOperator (true); + createParameter (info, args->Entry (0)); + // void *operator new[](std::size_t) throw(std::bad_alloc); + args = new CTypeList (1); + args->AddEntry (CTypeInfo::CTYPE_SIZE_T); + type = new CTypePointer (&CTYPE_VOID); + type = new CTypeFunction (type, args, true); + info = createFunction ("operator new[]", current_scope, type); + info->isOperator (true); + createParameter (info, args->Entry (0)); + + // deallocation functions + // void operator delete(void *) throw(); + type = new CTypePointer (&CTYPE_VOID); + args = new CTypeList (1); + args->AddEntry (type); + type = new CTypeFunction (&CTYPE_VOID, args, true); + info = createFunction ("operator delete", current_scope, type); + info->isOperator (true); + createParameter (info, args->Entry (0)); + // void operator delete[](void *) throw(); + type = new CTypePointer (&CTYPE_VOID); + args = new CTypeList (1); + args->AddEntry (type); + type = new CTypeFunction (&CTYPE_VOID, args, true); + info = createFunction ("operator delete[]", current_scope, type); + info->isOperator (true); + createParameter (info, args->Entry (0)); +} + + +void CCSemantic::declareSpecialMembers () { + bool has_ctor, has_copy, has_assign, has_dtor; + CFunctionInfo *info; + CTypeInfo *type; + CTypeList *args; + CRecord *scope; + + scope = current_scope->Record (); + if (! scope) + return; + + // check explicit declarations + has_ctor = has_copy = has_assign = has_dtor = false; + for (unsigned i = 0; i < scope->Functions (); i++) { + info = scope->Function (i); + + if (info->isConstructor ()) { + has_ctor = true; + if (info->Arguments () == 1 || + (info->Arguments () > 1 && info->Argument (1)->hasDefaultArg ())) { + type = info->Argument ((unsigned)0)->TypeInfo (); + if (isRefToClass (type, scope)) + has_copy = true; + } + } else if (info->isOperator ()) { + if (strcmp (info->Name (), "operator =") == 0 && + info->Arguments () == 1) { + type = info->Argument ((unsigned)0)->TypeInfo (); + if (isRefToClass (type, scope)) + has_assign = true; + } + } else if (info->isDestructor ()) + has_dtor = true; + } + + // create implicit members + + // implicit destructor + if (! has_dtor) { + std::ostringstream name; + name << "~" << scope->Name (); + type = new CTypeFunction (&CTYPE_UNDEFINED, new CTypeList (1), true); + info = createMethod (name.str ().c_str (), scope, type); + info->isDestructor (true); + } + // implicit default constructor + if (! has_ctor) { + type = new CTypeFunction (&CTYPE_UNDEFINED, new CTypeList (1), true); + info = createMethod (scope->Name (), scope, type); + info->isConstructor (true); + } + // implicit copy constructor + if (! has_copy) { + type = scope->TypeInfo ()->Duplicate (); + type = new CTypeAddress (new CTypeQualified (type, true, false, false)); + args = new CTypeList (1); + args->AddEntry (type); + type = new CTypeFunction (&CTYPE_UNDEFINED, args, true); + info = createMethod (scope->Name (), scope, type); + info->isConstructor (true); + createParameter (info, args->Entry (0)); + } + // implicit assignment operator + if (! has_assign) { + type = scope->TypeInfo ()->Duplicate (); + type = new CTypeAddress (new CTypeQualified (type, true, false, false)); + args = new CTypeList (1); + args->AddEntry (type); + type = scope->TypeInfo ()->Duplicate (); + type = new CTypeAddress (type); + type = new CTypeFunction (type, args, true); + info = createMethod ("operator =", scope, type); + info->isOperator (true); + createParameter (info, args->Entry (0)); + } +} + + +CFunctionInfo *CCSemantic::createMethod (const char *name, CRecord *scope, + CTypeInfo *type) { + CFunctionInfo *info; + info = createFunction (name, scope, type); + info->Protection (CProtection::PROT_PUBLIC); + info->isInline (true); + info->QualifiedScope (getQualifiedScope (scope)); + return info; +} + + +bool CCSemantic::isRefToClass (CTypeInfo *type, CRecord *record) const { + // ���12.8.9 type must be X, X&, const X&, volatile X&, or const volatile X& + if (type) { + type = type->UnqualType (); + if (type->TypeAddress ()) { + type = type->BaseType ()->UnqualType (); + } + if (type->TypeRecord () && type->TypeRecord ()->Record () == record) + return true; + } + return false; +} + + +CTree *CCSemantic::ctor_init () { + CT_MembInitList *result; + result = (CT_MembInitList*)builder ().ctor_init (); + result->Scope (current_scope); + return result; +} + + +CTree *CCSemantic::introduce_member () { + bool is_fct, is_friend, is_typedef, is_qual_name, redef_typedef, is_special, new_fct; + CStructure *scope, *lookup_scope; + CObjectInfo *info, *oinfo = 0; + CTemplateInfo *tinfo; + CSemDeclSpecs *dsi; + CTree *d; + + // check declaration parse state + info = current_fct; + finish_declarator (); + if (! in_decl ()) + return (CTree*)0; + + // determine member type + d = builder ().member_declarator (); + dsi = sem_decl_specs (); + CCSemDeclarator csd (_err, dsi->make_type (), d); + if (! csd.Name ()) { + delete d; + return (CTree*)0; + } + + // determine member properties + is_friend = (dsi->declared (CT_PrimDeclSpec::PDS_FRIEND)); + is_typedef = (dsi->declared (CT_PrimDeclSpec::PDS_TYPEDEF)); + is_fct = (! is_typedef && csd.Type ()->isFunction () && ! csd.Type ()->isAddress ()); + is_qual_name = isQualName (csd.Name ()); + is_special = isSpecialization (csd.Name ()); + lookup_scope = is_special ? current_scope : getNonTplScope (); + new_fct = false; + + // lookup name + CCNameLookup nl (*_err, current_scope, false); + if (! is_friend || ! is_fct || is_qual_name) { + scope = getNameScope (csd.Name ()); + if (is_qual_name && scope == lookup_scope) { + // ignore extra qualification if it refers to current class scope + // lookup as if no qualification is given + is_qual_name = false; + nl.lookupFunction (csd.Name ()->Name (), lookup_scope); + } else { + if (is_qual_name) { + // method of another class declared in enclosing class + if (! is_friend) { + SEM_ERROR__cannot_declare (d, csd.Name (), lookup_scope); + delete d; + return (CTree*)0; + } + lookup_scope = scope; + } + nl.lookupFunction (csd.Name (), lookup_scope); + } + } else { // friend && fct && unqualified + scope = lookup_scope = getFriendScope (false); + nl.lookupFunction (csd.Name (), lookup_scope); + if (! nl.Objects ()) { + // lookup in non-template scope + scope = lookup_scope = getFriendScope (true); + nl.lookupFunction (csd.Name (), lookup_scope); + } + } + + // check member name lookup + if (! check_member_lookup (nl, lookup_scope, dsi, csd, d, redef_typedef, is_qual_name)) { + delete d; + return (CTree*)0; + } + + // friend declaration for member of another class, find the + // matching member + if (is_friend && is_qual_name) { + info = 0; + + for (unsigned i = 0; ! info && i < nl.Objects (); i++) { + CObjectInfo* oinfo = nl.Object (i); + // TODO: handle templates and specializations correctly + if (oinfo && (current_scope->TemplateInfo () || oinfo->isTemplate () || + equalType (csd.Type (), oinfo->TypeInfo (), false))) { + info = oinfo; + } + } + + if (! info) { + std::ostringstream qname; qualifiedScopeName (csd.Name (), qname); + SEM_ERROR__no_matching_decl (d, csd.Name ()->Name (), qname.str ().c_str ()); + delete d; + return (CTree*)0; + } + } + + // member typedef declaration + if (is_typedef) { + info = current_scope->newTypedef (); + Push (info); + // member function declaration + } else if (is_fct) { + if (! info) { + if (is_friend) + current_fct = lookup_scope->newFunction (); + else + current_fct = current_scope->newFunction (); + info = current_fct; + new_fct = true; + } else if (! is_friend) { + current_scope->addFunction (info->FunctionInfo ()); + new_fct = true; + } + + // handle template functions + if (new_fct && current_scope->TemplateInfo ()) + setTemplateScope (nl, info, csd.Type (), current_scope->TemplateInfo (), is_qual_name); + + if (! is_friend || ! is_qual_name) { + // determine member function category + if (lookup_scope->Name () && + strcmp (lookup_scope->Name (), csd.Name ()->Text ()) == 0) + info->FunctionInfo ()->isConstructor (true); + else if (csd.Name ()->Name ()->NodeName () == CT_DestructorName::NodeId ()) + info->FunctionInfo ()->isDestructor (true); + else if (csd.Name ()->Name ()->NodeName () == CT_OperatorName::NodeId ()) + info->FunctionInfo ()->isOperator (true); + else if (csd.Name ()->Name ()->NodeName () == CT_ConversionName::NodeId ()) { + info->FunctionInfo ()->isConversion (true); + info->FunctionInfo ()->ConversionType ( + ((CT_ConversionName*)csd.Name ()->Name ())->TypeName ()->Object ()->TypeInfo ()); + } + + // determine further function properties + info->Linkage (determine_linkage (dsi, FCT)); + } + + // add friend to enclosing class + if (is_friend) { + info->FunctionInfo ()->addFriend (current_scope->Record ()); + if (! is_qual_name && new_fct) + info->FunctionInfo ()->AssignedScope (lookup_scope); + } else { + info->FunctionInfo ()->QualifiedScope (getQualifiedScope (lookup_scope)); + + // create implicit `this' parameter + addImplicitThisObject (info->FunctionInfo (), csd.Type (), d); + } + + csd.Type ()->VirtualType ()->TypeFunction ()->FunctionInfo (info->FunctionInfo ()); + // data member declaration + } else { + info = current_scope->newAttribute (); + info->Linkage (determine_linkage (dsi, ATTRIB)); + if (dsi->declared (CT_PrimDeclSpec::PDS_STATIC)) + info->Storage (dsi->declared (CT_PrimDeclSpec::PDS_THREAD) ? + CStorage::CLASS_THREAD : CStorage::CLASS_STATIC); + else + info->Storage (determine_storage_class (dsi)); + info->AttributeInfo ()->QualifiedScope (getQualifiedScope (lookup_scope)); + Push (info); + } + + // determine common properties of the member + if (! is_friend) + setProtection (info); + + if (! is_friend || ! is_fct || new_fct) { + setLanguage (info); + setSpecifiers (info, dsi); + common_settings (info, d, &csd); + + // handle "redefining" typedefs such as `typedef class X X;' + if (redef_typedef) { + char aname[100]; + sprintf (aname, "%%anon%ld", _Anonymous); + _Anonymous++; + info->Name (aname); + + // link previous declarations with this one + if (oinfo && oinfo->TypedefInfo ()) + oinfo->NextObject (info); + } + else if (info->TypedefInfo ()) { + CTypeInfo *type = info->TypeInfo ()->TypedefInfo (info); + info->TypeInfo (type); + } + + if (is_fct && ! is_special) + linkFctDecls (nl, info); + } + + // handle template declarations + tinfo = current_scope->TemplateInfo (); + if (tinfo) { + setSpecializationName (csd.Name (), tinfo); + introduceTemplate (info, tinfo, is_friend); + } + + // attribute syntax tree + if (d->NodeName () == CT_InitDeclarator::NodeId ()) + ((CT_InitDeclarator*)d)->Object (info); + else + ((CT_BitFieldDeclarator*)d)->Object (info); + + if (is_fct) + current_fct = 0; + + // if an attribute with class object type, ensure + // that the class is really instantiated + CTypeInfo* type = info->TypeInfo(); + if (info->AttributeInfo() && type->UnqualType()->TypeClass()) { + type->UnqualType()->TypeClass()->instantiate(current_scope); + } + + return d; +} + + +bool CCSemantic::check_member_lookup (CCNameLookup &nl, CStructure *lookup_scope, + CSemDeclSpecs *dsi, CCSemDeclarator &csd, CTree *d, bool &redef_typedef, + bool is_qual_name) { + bool is_friend, is_typedef, is_fct; + CObjectInfo *oinfo; + + is_friend = (dsi->declared (CT_PrimDeclSpec::PDS_FRIEND)); + is_typedef = (dsi->declared (CT_PrimDeclSpec::PDS_TYPEDEF)); + is_fct = (! is_typedef && csd.Type ()->isFunction () && ! csd.Type ()->isAddress ()); + redef_typedef = false; + + // member declared using qualified name but member not exists + if (! nl.Objects () && is_qual_name) { + std::ostringstream name; qualifiedScopeName (csd.Name (), name); + SEM_ERROR__not_member (d, csd.Name ()->Name (), name.str ().c_str ()); + // check all members looked up + } else if (nl.Objects ()) { + oinfo = nl.Object (); + // ���7.1.3.2 typedef redefining same type + if (is_typedef && + ((oinfo->TypedefInfo () && + (equalType (csd.Type (), oinfo->TypeInfo ()) || + (! real_inst && csd.Type ()->isTemplateInstance () && + oinfo->TypeInfo ()->isTemplateInstance ()))) || + (oinfo->TypeInfo ()->TypeRecord () && + csd.Type ()->TypeRecord () && + *csd.Type ()->TypeRecord ()->Record () == + *oinfo->TypeInfo ()->TypeRecord ()->Record ()) || + (oinfo->TypeInfo ()->TypeEnum () && + csd.Type ()->TypeEnum () && + *csd.Type ()->TypeEnum ()->EnumInfo () == + *oinfo->TypeInfo ()->TypeEnum ()->EnumInfo ()))) + redef_typedef = true; + + // conflicting declaration in lookup scope + if (is_typedef && ! redef_typedef) { + SEM_ERROR__duplicate (d, "nested type", csd.Name ()); + // check all functions looked up + } else if (is_fct && oinfo->FunctionInfo ()) { + unsigned i = 0; + do { + // duplicate member function + if (! is_friend && + (current_fct ? oinfo->isTemplate () == + current_fct->isTemplate () : + current_scope ? oinfo->isTemplate () == + (current_scope->TemplateInfo ()?true:false) : true) && + equalType (csd.Type (), oinfo->TypeInfo ())) { + SEM_ERROR__already_defined (d, csd.Name (), oinfo); + return false; + } + } while (++i < nl.Objects () && (oinfo = nl.Object (i))); + return true; + // conflicting member declarations + } else if (is_fct && ! oinfo->FunctionInfo () && + ! (oinfo == lookup_scope || isClassOrEnum (oinfo))) { + SEM_ERROR__duplicate (d, "member", csd.Name ()); + } else + return true; + } else + return true; + return false; +} + + +CTree *CCSemantic::member_decl1 () { + CT_ObjDecl *od; + + od = (CT_ObjDecl*)builder ().member_decl1 (); + obj_decl (od); // link object decl and init declarators + + if (od && ! od->Declarators ()->Entries ()) { + // ���9.2.7 the member-declarator-list can be ommited only after a + // class- or enum-specifier, or a decl-specifier-seq of the form + // `friend elaborated-type-specifier' + CT_DeclSpecSeq *dss = od->DeclSpecs (); + int entries = dss->Entries (); + if (! entries) // nothing declared + return od; + const char *entry = dss->Entry (0)->NodeName (); + if (entries == 1 && + (entry == CT_ClassSpec::NodeId () || entry == CT_ClassDef::NodeId () || + entry == CT_UnionSpec::NodeId () || entry == CT_UnionDef::NodeId () || + entry == CT_EnumSpec::NodeId () || entry == CT_EnumDef::NodeId ())) + return od; + entry = dss->Entry (1)->NodeName (); + if (entries == 2 && dss->Entry (0)->token ()->type () == TOK_FRIEND && + (entry == CT_ClassSpec::NodeId () || + entry == CT_UnionSpec::NodeId () || + entry == CT_EnumSpec::NodeId ())) + return od; + return (CTree*)0; + } + return od; +} + + +CTree *CCSemantic::member_declarator_err () { + finish_declarator (); + return (CTree*)0; +} + + +bool CCSemantic::inTemplateDecl (CScopeInfo* scope) const { + if (! scope) + return false; + if (scope->TemplateInfo ()) + return true; +// if (scope->NamespaceInfo () && scope->NamespaceInfo ()->aroundInstantiation ()) +// return true; + return scope->Parent () != scope && inTemplateDecl (scope->Parent ()); +} + + +CTree *CCSemantic::introduce_tag () { + bool is_friend, is_typename, is_special, do_lookup, is_decl, is_qual_name, in_tpl_decl; + CStructure *lookup_scope, *scope; + CObjectInfo *info, *dinfo, *prev; + CTemplateInfo *tinfo; + CT_SimpleName *name; + CT_DeclSpecSeq *dss; + CT_ClassSpec *tag; + + // determine class properties + tag = (CT_ClassSpec*) builder ().elaborated_type_spec (); + info = prev = 0; + name = tag->Name (); + is_qual_name = isQualName(name); + is_typename = (tag->token ()->type () == TOK_TYPENAME); + in_tpl_decl = inTemplateDecl (current_scope); + is_friend = false; + is_special = isSpecialization (name); + do_lookup = true; + dss = decl_specs (); + lookup_scope = getNonTplScope (); + + // get correct name object + //while (name->NodeName () == CT_RootQualName::NodeId ()) + // name = (CT_SimpleName*)name->Son (1); + + // declarations of the form `class-key identifier ;' + is_decl = syntax().look_ahead(TOK_SEMI_COLON, syntax().look_ahead(TOK_FRIEND) ? 2 : 1); + + // get friend status + // declarations of the form `friend class-key identifier ;' + if (is_decl && lookup_scope->isRecord ()) { + if (tag->NodeName () != CT_EnumSpec::NodeId ()) { + if (dss->Sons () == 1 && dss->token ()->type () == TOK_FRIEND) { + is_friend = true; + } + else if (dss->Sons () == 0 && syntax ().look_ahead (TOK_FRIEND)) { + is_friend = true; + } + } + } + + // handle forward declaration of template instance + if (is_special && ! current_scope->TemplateInfo ()) { + info = name->Name ()->Object (); + if (info) { + if (is_friend && info->Structure () && current_scope->Record ()) + info->Structure ()->addFriend (current_scope->Record ()); + deleteContainer (2); + name->Object (info); + name->setTypeRef (info->TypeInfo ()); + tag->Object (info); + return tag; + } + } + + // check whether this is a dependent nested name and + // therefore name lookup need not to be performed + if (is_typename && in_tpl_decl && is_qual_name && name->Entries () > 1) { + dinfo = ((CT_SimpleName*)name->Entry (name->Entries ()-2))->Object (); + if (! dinfo || (dinfo->TypeInfo () && + (dinfo->TypeInfo ()->TypeTemplateParam () || + dinfo->TypeInfo ()->is_unknown_t ()))) + do_lookup = false; + } + + // lookup name + CCNameLookup nl (*_err, current_scope); + if (do_lookup) { + if (! is_friend) { + nl.lookupType (name, lookup_scope, !is_decl, !is_decl); + } else { + nl.lookupFriendClass (name, lookup_scope); + } + } + + // check name lookup results + if (nl.Objects ()) { + prev = info = nl.Object (); + // class key used with wrong type name + if (! is_typename && + ((tag->NodeName () == CT_ClassSpec::NodeId () && ! info->ClassInfo ()) || + (tag->NodeName () == CT_UnionSpec::NodeId () && ! info->UnionInfo ()) || + (tag->NodeName () == CT_EnumSpec::NodeId () && ! info->EnumInfo ()))) { + SEM_ERROR (tag, "wrong use of `" << *name << "'"); + return (CTree*)0; + } + // handle `typename' keyword + } else if (is_typename && in_tpl_decl) { + info = getLastResolvedName (name); + if (! info) + return 0; + // qualified name must name a type + } else if (is_qual_name) { + std::ostringstream qname; qualifiedScopeName (name, qname); + SEM_ERROR__not_member (tag, name->Name (), qname.str ().c_str ()); + return (CTree*)0; + } + + // delete possibly created container object because it would + // be deleted by the builder only when the rule fails + deleteContainer (2); + + // create tag + if (! is_qual_name && ! is_typename && (! prev || (! is_friend && prev->isTemplate ()))) { + bool is_instance = parsing_class_inst && tpl_inst->Instance () && + ! tpl_inst->Instance ()->TemplateInstance ()->isInstantiated () && + current_scope->isNamespace (); + // forward class declaration + if (tag->NodeName () == CT_ClassSpec::NodeId ()) { + if (is_instance) { + info = tpl_inst->Instance (); + tpl_inst->insertInstance (info); + } else { + info = _db->newClass(); + info->TypeInfo (new CTypeClass (info->ClassInfo ())); + } + // forward union declaration + } else if (tag->NodeName () == CT_UnionSpec::NodeId ()) { + if (is_instance) { + info = tpl_inst->Instance (); + tpl_inst->insertInstance (info); + } else { + info = _db->newUnion(); + info->TypeInfo (new CTypeUnion (info->UnionInfo ())); + } + // forward enum declaration + } else { + info = current_scope->newEnum (); + info->TypeInfo (new CTypeEnum (info->EnumInfo ())); + } + + // ���3.3.1 introduce name into enclosing non-class, non-function + // prototype scope if declaration has the form `.. class-key identifier ..' + scope = current_scope; + if (is_friend || ! syntax ().look_ahead (TOK_SEMI_COLON)) { + if (prev && info->Record ()) { + info->Record ()->isHiddenForwardDecl (true); + } + while (scope->isRecord () || scope->isFunction () || scope->TemplateInfo () || + (scope->NamespaceInfo () && scope->NamespaceInfo ()->aroundInstantiation ())) + scope = scope->Parent ()->Structure (); + } else { + setProtection (info); + } + + if (! info->EnumInfo ()) + info->ScopeInfo ()->Parent (scope); + + scope->addType (info); + common_settings (info, tag); + + if (! info->isTemplateInstance ()) { + // complete semantic information about the forward declaration + info->Name (name->Text ()); + Push (info); + + // link with previous declarations + if (prev) + prev->NextObject (info); + } + + // handle template declarations + tinfo = current_scope->TemplateInfo (); + if (tinfo && is_decl) { + setSpecializationName (name, tinfo); + setTemplateScope (nl, info, info->TypeInfo (), tinfo, is_qual_name); + introduceTemplate (info, tinfo, is_friend); + } + } + + if (is_friend) { + scope = getNonTplScope (); + if (scope && scope->Record ()) + info->Structure ()->addFriend (scope->Record ()); + } + + // attribute syntax tree + name->Object (info); + name->setTypeRef (info->TypeInfo ()); + tag->Object (info); + return tag; +} + + +CObjectInfo *CCSemantic::getLastResolvedName (CT_SimpleName *name) const { + CObjectInfo *info = 0; + int entries; + + if (name->NodeName () == CT_TemplateName::NodeId ()) + info = name->Object (); + else if (name->NodeName () == CT_QualName::NodeId () || + name->NodeName () == CT_RootQualName::NodeId ()) { + entries = name->Entries (); + for (unsigned i = entries; i > 0; i--) { + info = ((CT_SimpleName*)name->Entry (i-1))->Object (); + if (info) + return info; + } + } else + info = name->Name ()->Object (); + return info; +} + + +// parsing class definitions + + +void CCSemantic::Delete () { + CObjectInfo *info = Top (); // get item to delete + if (! info) + return; + + // parsing template instance failed + if (tpl_inst && info == tpl_inst->Instance ()) + tpl_inst->removeInstance (); + + if (info->Id () == CObjectInfo::BASECLASS_INFO) { +#ifndef NDEBUG + /*DEBUG*/if (TRACE_OBJS) std::cerr<<"DELETE: "<<(void*)info<<" (BaseClass "<Name()<<")"<Id () == CObjectInfo::TEMPLATE_PARAM_INFO) { +#ifndef NDEBUG + /*DEBUG*/if (TRACE_OBJS) std::cerr<<"DELETE: "<<(void*)info<<" (TemplateParam "<Name()<<")"<Id () == CObjectInfo::USING_INFO) { +#ifndef NDEBUG + /*DEBUG*/if (TRACE_OBJS) std::cerr<<"DELETE: "<<(void*)info<<" (Using "<Name()<<")"<Id () == CObjectInfo::NAMESPACE_INFO) { +#ifndef NDEBUG + /*DEBUG*/if (TRACE_OBJS) std::cerr<<"DELETE: "<<(void*)info<<" (Namespace "<Name()<<")"<Name()<<")"<Id () == CObjectInfo::TEMPLATE_INFO) { +#ifndef NDEBUG + /*DEBUG*/if (TRACE_OBJS) std::cerr<<"DELETE: "<<(void*)info<<" (Template "<Name()<<")"<Name()<<")"<Id () == CObjectInfo::UNION_INSTANCE_INFO) { +#ifndef NDEBUG + /*DEBUG*/if (TRACE_OBJS) std::cerr<<"DELETE: "<<(void*)info<<" (Union instance "<Name()<<")"<Name()<<")"<Id () == CObjectInfo::CLASS_INSTANCE_INFO) { +#ifndef NDEBUG + /*DEBUG*/if (TRACE_OBJS) std::cerr<<"DELETE: "<<(void*)info<<" (Class instance "<Name()<<")"<Name()<<")"<Id () == CObjectInfo::FCT_INSTANCE_INFO) { +#ifndef NDEBUG + /*DEBUG*/if (TRACE_OBJS) std::cerr<<"DELETE: "<<(void*)info<<" (Function instance "<Name()<<")"<Name()<<")"<get_state (); + syntax ().skip_block (TOK_OPEN_CURLY, TOK_CLOSE_CURLY, false); + Token* closeCurly = syntax ().provider ()->current (); + syntax ().provider ()->set_state (state); + return closeCurly; +} + + +CTree* CCSemantic::createDelayedParse (bool (CCSyntax::*rule)(), CTree *tree) { + Token *token = syntax ().provider ()->current (); + CT_DelayedParse* dp = 0; + + if (rule == &CCSyntax::param_init) { + dp = new CT_DelayedParseParamInit (token); + CT_ArgDecl *ad = (CT_ArgDecl*)tree; + ad->Initializer (dp); + // if we skipped a default argument of a function this fact should be + // stored in the function info, because then the overload resolution already + // works, even without knowing the actual default value + if (ad && ad->Object ()) + ad->Object ()->ArgumentInfo ()->hasDefaultArg (true); + } else if (rule == &CCSyntax::fct_try_block) { + dp = new CT_DelayedParseFctTryBlock (token); + CT_FctDef *fd = (CT_FctDef*)tree; + fd->Handlers (dp); + } else if (rule == &CCSyntax::ctor_init) { + dp = new CT_DelayedParseCtorInit (token); + CT_FctDef *fd = (CT_FctDef*)tree; + fd->CtorInit (dp); + } else if (rule == &CCSyntax::pure_spec) { + dp = new CT_DelayedParsePureSpec (token); + CT_FctDef *fd = (CT_FctDef*)tree; + fd->CtorInit (dp); + } else if (rule == &CCSyntax::fct_body) { + dp = new CT_DelayedParseFctBody (token, getCloseCurly ()); + CT_FctDef *fd = (CT_FctDef*)tree; + fd->Body (dp); + } else if (rule == &CCSyntax::skipped_fct_body) { + dp = new CT_DelayedParseSkippedFctBody (token, getCloseCurly ()); + CT_FctDef *fd = (CT_FctDef*)tree; + fd->Body (dp); + } else if (rule == &CCSyntax::const_init) { + dp = new CT_DelayedParseConstInit (token); + CT_InitDeclarator *id = (CT_InitDeclarator*)tree; + id->Initializer (dp); + } + + dp->Class (_outermost_class_def); + dp->Scope (current_scope); + dp->State (syntax ().provider ()->get_state ()); + + return dp; +} + + +void CCSemantic::parse_delayed (bool (CCSyntax::*rule)(), CTree *tree) { + CT_DelayedParse* dp = (CT_DelayedParse*) createDelayedParse (rule, tree); + // add to the outermost class def + _outermost_class_def->addParseDelayed (dp); +} + + +void CCSemantic::parseDelayed() { + // parse function bodies and several initializers not parsed due + // to potential use of names of members that could not be resolved + // untill the end of the class definition + + CT_DelayedParse* dp; + const char* id; + bool accepted = false; + CTree* parent; + CTree* result; + + CCSyntax::State old_state = syntax().provider()->get_state(); + CStructure* old_scope = current_scope; + + for (unsigned i = 0; i < _outermost_class_def->ParseDelayed(); i++) { + dp = (CT_DelayedParse*) _outermost_class_def->ParseDelayed(i); + id = dp->NodeName(); + parent = dp->Parent(); + + // setup parser for the current delayed code fragment + current_scope = dp->Scope(); + syntax().provider()->set_state(dp->State()); + builder().save_state(); + + // parse the code fragment now + if (id == CT_DelayedParseParamInit::NodeId()) + accepted = syntax().param_init(); + else if (id == CT_DelayedParseFctTryBlock::NodeId()) + accepted = syntax().fct_try_block(); + else if (id == CT_DelayedParseCtorInit::NodeId()) + accepted = syntax().ctor_init(); + else if (id == CT_DelayedParsePureSpec::NodeId()) + accepted = syntax().pure_spec(); + else if (id == CT_DelayedParseFctBody::NodeId()) + accepted = syntax().fct_body(); + else if (id == CT_DelayedParseSkippedFctBody::NodeId()) + accepted = syntax().skipped_fct_body(); + else if (id == CT_DelayedParseConstInit::NodeId()) + accepted = syntax().const_init(); + + // get tree fragment + if (accepted) { + result = builder().get_node(builder().nodes()-1); + builder().forget_state(); + + // instantiate result tree if needed + if (_outermost_class_def->haveInstantiateDelayed(dp->token())) + instantiateDelayed(dp, result); + + } else { + // failed, clean up + builder().restore_state(); + result = builder().error(); + } + + // complete the syntax tree + if (id == CT_DelayedParseFctBody::NodeId() || id == CT_DelayedParseSkippedFctBody::NodeId()) { + CT_FctDef *fd = (CT_FctDef*)parent; + fd->Body(result); + } else if (id == CT_DelayedParseCtorInit::NodeId() || id == CT_DelayedParsePureSpec::NodeId()) { + CT_FctDef *fd = (CT_FctDef*)parent; + fd->CtorInit(result); + } else if (id == CT_DelayedParseFctTryBlock::NodeId()) { + CT_FctDef *fd = (CT_FctDef*)parent; + if (accepted) { + Builder::Container *c = (Builder::Container*)result; + int offset = (c->Son(1)->NodeName() == CT_MembInitList::NodeId()) ? 1 : 0; + fd->FctTryBlock(c->Son(0), offset ? c->Son(1) : (CTree*)0, c->Son(1+offset), c->Son(2+offset)); + delete c; + } else { + fd->Handlers(result); + } + } else if (id == CT_DelayedParseParamInit::NodeId()) { + CT_ArgDecl *ad = (CT_ArgDecl*)parent; + ad->Initializer(result); + } else if (id == CT_DelayedParseConstInit::NodeId()) { + CT_InitDeclarator *idl = (CT_InitDeclarator*)parent; + idl->Initializer(result); + } + + // delete the CT_DelayedParse tree + dp->Class(0); + builder().destroy(dp); + } + + syntax().provider()->set_state(old_state); + current_scope = old_scope; +} + + +void CCSemantic::instantiateDelayed(CT_DelayedParse* odp, CTree* tree) { + // instantiate function bodies and several initializers not instantiated + // due to potential use of names of members that could not be resolved + // untill the end of the class definition + + CTemplateInstance* instance; + CT_DelayedParse* dp; + CTemplateInfo *tpl; + CScopeInfo* scope; + const char* id; + CTree* parent; + CTree* result = 0; + + InstantiationParser parser; + + const CRecord::TreeList& list = _outermost_class_def->InstantiateDelayed(odp->token()); + CRecord::TreeList::const_iterator i = list.begin(); + for (; i != list.end(); ++i) { + dp = (CT_DelayedParse*) *i; + id = dp->NodeName(); + parent = dp->Parent(); + + // initialize the parser + scope = dp->Scope(); + while (!scope->isTemplateInstance()) + scope = scope->Parent(); + instance = scope->TemplateInstance(); + tpl = instance->Template(); + parser.init(instance->Object(), tpl, dp->Scope()); + + // parse the code fragment now + bool delayed = false; + if (id == CT_DelayedParseParamInit::NodeId()) + result = parser.parse(tpl, tree, &InstantiationSyntax::param_init, delayed, false); + else if (id == CT_DelayedParseFctTryBlock::NodeId()) + result = parser.parse(tpl, tree, &InstantiationSyntax::fct_try_block, delayed, false); + else if (id == CT_DelayedParseCtorInit::NodeId()) + result = parser.parse(tpl, tree, &InstantiationSyntax::ctor_init, delayed, false); + else if (id == CT_DelayedParsePureSpec::NodeId()) + result = parser.parse(tpl, tree, &InstantiationSyntax::pure_spec, delayed, false); + else if (id == CT_DelayedParseFctBody::NodeId()) + result = parser.parse(tpl, tree, &InstantiationSyntax::fct_body, delayed, false); + else if (id == CT_DelayedParseSkippedFctBody::NodeId()) + result = parser.parse(tpl, tree, &InstantiationSyntax::skipped_fct_body, delayed, false); + else if (id == CT_DelayedParseConstInit::NodeId()) + result = parser.parse(tpl, tree, &InstantiationSyntax::const_init, delayed, false); + + // semantic expression analysis + if (result) + parser.resolve(tpl, dp->Scope(), result); + + // report errors + if (parser.failed()) { + //First().printInstantiationErrorHeader(getPoiToken()); + parser.builder().errors(*_err); + } + if (!result) + result = builder().error(); + + // complete the syntax tree + if (id == CT_DelayedParseFctBody::NodeId() || id == CT_DelayedParseSkippedFctBody::NodeId()) { + CT_FctDef *fd = (CT_FctDef*)parent; + fd->Body(result); + } else if (id == CT_DelayedParseCtorInit::NodeId() || id == CT_DelayedParsePureSpec::NodeId()) { + CT_FctDef *fd = (CT_FctDef*)parent; + fd->CtorInit(result); + } else if (id == CT_DelayedParseFctTryBlock::NodeId()) { + CT_FctDef *fd = (CT_FctDef*)parent; + if (result->NodeName() == Builder::Container::NodeId()) { + Builder::Container *c = (Builder::Container*)result; + int offset = (c->Son(1)->NodeName() == CT_MembInitList::NodeId()) ? 1 : 0; + fd->FctTryBlock(c->Son(0), offset ? c->Son(1) : (CTree*)0, c->Son(1+offset), c->Son(2+offset)); + delete c; + } else { + fd->Handlers(result); + } + } else if (id == CT_DelayedParseParamInit::NodeId()) { + CT_ArgDecl *ad = (CT_ArgDecl*)parent; + ad->Initializer(result); + } else if (id == CT_DelayedParseConstInit::NodeId()) { + CT_InitDeclarator *idl = (CT_InitDeclarator*)parent; + idl->Initializer(result); + } + + // delete the CT_DelayedParse tree + dp->Class(0); + builder().destroy(dp); + } +} + + +/*****************************************************************************/ +/* */ +/* Exceptions */ +/* */ +/*****************************************************************************/ + + +CTree *CCSemantic::handler () { + CT_Handler *result; + result = (CT_Handler*)builder ().handler (); + result->Scope (current_scope); + current_scope->Tree (result); + return result; +} + + +CTree *CCSemantic::exception_spec () { + CT_ExceptionSpec *es; + + es = (CT_ExceptionSpec*)builder ().exception_spec (); + es->Arguments ()->Scope (current_scope); + + leave_exception_spec (); + return es; +} + + +CTree *CCSemantic::introduce_exception () { + CAttributeInfo *info; + CSemDeclSpecs *dsi; + CT_ArgDecl *ad; + + if (! in_decl ()) + return (CTree*)0; + + // determine exception type + ad = (CT_ArgDecl*)builder ().exception_decl (); + dsi = sem_decl_specs (); + CCSemDeclarator csd (_err, dsi->make_type (), ad->Declarator ()); + if (! csd.Name ()) { + delete ad; + return (CTree*)0; + } + + // complete semantic information about the exception + info = current_scope->newAttribute (); + info->Storage (CStorage::CLASS_AUTOMATIC); + setLanguage (info); + setSpecifiers (info, dsi); + common_settings (info, ad, &csd); + Push (info); + + // attribute syntax tree + ad->Object (info); + return ad; +} + + +void CCSemantic::enter_exception_spec () { + // prevent the parser from rejecting the current function; + // this always happens when a declarator was parsed and we + // are no longer in the scope of a function parameter clause + _in_param_decl_clause.push (true); + // search in scope of function first + reenter_scope (current_fct); +} + + +void CCSemantic::leave_exception_spec () { + _in_param_decl_clause.pop (); + // leave scope of function + reenter_scope (current_scope->Parent ()->Structure ()); +} + + +/*****************************************************************************/ +/* */ +/* Templates */ +/* */ +/*****************************************************************************/ + + +bool CCSemantic::isSpecialization (CTree *name) const { + if (name && name->IsSimpleName () && + name->IsSimpleName ()->Name ()->NodeName () == CT_TemplateName::NodeId ()) + return true; + if (current_scope->TemplateInfo () && + current_scope->TemplateInfo ()->isSpecialization ()) + return true; + return false; +} + + +void CCSemantic::setSpecializationName (CTree *tree, CTemplateInfo *tinfo) const { + if (tree->IsSimpleName ()) { + CT_SimpleName *name = tree->IsSimpleName ()->Name (); + if (name && name->NodeName () == CT_TemplateName::NodeId ()) { + tinfo->SpecializationName ((CT_TemplateName*)name); + } + } +} + + +bool CCSemantic::skip_tpl_fct_bodies () const { + CStructure *scope = current_scope; + while (! scope->FileInfo ()) { + if (scope->TemplateInfo ()) + return true; + scope = scope->Parent ()->Structure (); + } + return false; +} + + +CTree *CCSemantic::template_key () { + // next identifier is expected to be a template name + expect_template = true; + return builder ().get_node (); +} + + +CTree *CCSemantic::introduce_template_instance () { + bool instantiate, pseudo, is_special; + CScopeInfo *scope, *class_or_fct; + CTemplateInfo *tpinfo, *tpl; + CT_TemplateArgList *args; + CT_TemplateName *tn; + CObjectInfo *info; + unsigned numargs; + CTypeInfo *type; + CTree *arg; + + tn = (CT_TemplateName*)builder ().template_id (); + info = tn->TemplateName ()->Object (); + if (! info) // ??? + return tn; + + info = info->DefObject (); + pseudo = is_entity_name (); + instantiate = ! info->FunctionInfo (); + is_special = (is_entity_name () ? (! syntax ().look_ahead (TOK_OPEN_ROUND)) : + (current_scope->TemplateInfo () && syntax ().look_ahead (TOK_COLON_COLON))) && + (! in_conv_type_id () && ! in_nested_name ()); + args = tn->Arguments (); + numargs = args->Entries (); + + // compare number of parameters and arguments of + // non-function templates + if (info->TemplateParamInfo ()) { + tpinfo = info->TemplateParamInfo ()->TemplateTemplate (); + } + else + tpinfo = info->Template (); + if (real_inst) { + if (tpinfo && ! info->FunctionInfo () && ! is_special) { + if (numargs > tpinfo->Parameters () || + (numargs < tpinfo->Parameters () && + ! tpinfo->DefaultArgument (numargs))) { + SEM_ERROR (tn, "wrong number of template arguments (" + << numargs << ", should be " << tpinfo->Parameters () << ")"); + args->RemoveSon (args->Sons ()-1); + args->RemoveSon (0); + delete tn; + return 0; + } + } + } + + // apply implicit conversions to the template non-type arguments + for (unsigned i = 0; i < numargs; i++) { + arg = args->Entry (i); + + // template type argument + if (arg->NodeName () == CT_NamedType::NodeId ()) { + if (arg->SemObject () && arg->SemObject ()->Object () && + arg->SemObject ()->Object ()->TypeInfo ()) { + type = arg->SemObject ()->Object ()->TypeInfo (); + if (type->isDependent (true, true) || + (type->isTemplate () && i < tpinfo->Parameters () && + ! tpinfo->Parameter (i)->isTemplate ())) + pseudo = true; + } + continue; + } + + // resolve template non-type argument (expression) + CCSemExpr cse (*_err, current_scope); + type = cse.resolveExpr (arg, args); + if (cse.isDependent () || cse.isDependent (arg)) + pseudo = true; + + // ��14.3.2 address as non-type template argument + if ((type->isArray () || type->isFunction ()) || CCSemExpr::isAddrExpr (arg)) + calculateAddress (arg); + + // ��14.3.2.5 implicit template argument conversions + if (type->isAddress ()) + type = type->NonReferenceType (); + + // array-to-pointer and function-to-pointer conversions + if (type->isArray () || type->isFunction ()) { + type = CCSemExpr::convLvalueToRvalue (arg); + } else { + // qualification conversion + if (type->TypeQualified ()) + type = CCSemExpr::castToType (type->UnqualType (), arg); + // integral promotion and conversion + if (type->isInteger ()) + type = CCSemExpr::intPromotion (arg); + } + } + + // handle recursive template instantiation + if (instantiate) { + scope = current_scope; + class_or_fct = 0; + do { + // inside class or function + if (scope->isRecord () || scope->isFunction ()) + class_or_fct = scope; + + // local scope? + if (! scope->TemplateInfo () || ! class_or_fct) + continue; + + // compare scope with template to instantiate + if (*class_or_fct != *info) { + bool matched = false; + + // if specialization scope we have to compare against + // the registered specializations of the template + if (class_or_fct->Template () && + class_or_fct->Template ()->isSpecialization ()) { + for (unsigned i = 0; i < tpinfo->Specializations (); i++) { + tpl = tpinfo->Specialization (i); + if (*tpl->ObjectInfo () == *class_or_fct) { + matched = matchArguments(tn, tpl->SpecializationName ()); + if (matched) + break; + } + } + } + if (! matched) + continue; + } + + pseudo = true; + break; + } while (scope != scope->Parent () && (scope = scope->Parent ())); + } + + // handle explicit specialization + if (is_special && instantiate) { + // enclose in template scope + if (info->Record () && ! current_scope->TemplateInfo ()) { + scope = _db->newTemplate(); + scope->Name (info->Name ()); + scope->SourceInfo ()->FileInfo (_file); + enter_scope (scope->Structure ()); + //Push (scope); + + if (! tpinfo && info->FunctionInfo ()) + scope->TemplateInfo ()->BaseTemplate (info->FunctionInfo ()->TemplateInfo ()); + else if (tpinfo) + scope->TemplateInfo ()->BaseTemplate (tpinfo); + + tn->Name (scope->Name ()); + tn->Object (scope); + //tn->setTypeRef (info->TypeInfo ()); + tn->TemplateName ()->Object (info); + tn->TemplateName ()->setTypeRef (info->TypeInfo ()); + return tn; + } else if (current_scope->TemplateInfo ()) { + if (! tpinfo && info->FunctionInfo ()) + current_scope->TemplateInfo ()->BaseTemplate (info->FunctionInfo ()->TemplateInfo ()); + else if (tpinfo) + current_scope->TemplateInfo ()->BaseTemplate (tpinfo); + } + instantiate = false; + } + + // function templates are instantiated later + if (info->FunctionInfo ()) { + tn->Object (info); + tn->Name (info->Name ()); + return tn; + } + + // don't instantiate entity names, and non-base templates + if ((is_entity_name () && ! in_nested_name ()) || + (tpinfo && ! tpinfo->isBaseTemplate ())) { + instantiate = false; + // template template parameter + } else if (info->TemplateParamInfo ()) { + instantiate = true; + pseudo = true; + } + + // instantiate non-function templates + if (instantiate) { + // instantiate now + CCInstantiation cci (*_err); + info = cci.instantiate (tn, info, ! pseudo, current_scope); + + if (! info) { + args->RemoveSon (args->Sons ()-1); + args->RemoveSon (0); + delete tn; + return 0; + } + } + + // attribute syntax tree + tn->Name (info->Name ()); + tn->Object (info); + tn->setTypeRef (info->TypeInfo ()); + tn->TemplateName ()->Object (info); + tn->TemplateName ()->setTypeRef (info->TypeInfo ()); + return tn; +} + + +bool CCSemantic::matchArguments (CT_TemplateName *n1, CT_TemplateName *n2) const { + // template names + if (! n1 || ! n2) + return false; + + // template arguments + CT_TemplateArgList *args1 = n1->Arguments (); + CT_TemplateArgList *args2 = n2->Arguments (); + if (! args1 || ! args2) + return false; + + // number of arguments + unsigned entries1 = args1->Entries (); + unsigned entries2 = args2->Entries (); + if (entries1 != entries2) + return false; + + // compare arguments (not yet complete) + for (unsigned i = 0; i < entries1; i++) { + CTree *arg1 = args1->Entry (i); + CTree *arg2 = args2->Entry (i); + + // match values + CConstant *value; + if (arg1->Value () && arg1->Value ()->Constant ()) { + if (arg2->Value () && (value = arg2->Value ()->Constant ()) && + (*value == *arg1->Value ()->Constant ())) + continue; + return false; + } + + // match types + CTypeInfo *type1 = 0, *type2 = 0; + if (arg1->NodeName () == CT_NamedType::NodeId () && + arg1->SemObject () && arg1->SemObject ()->Object ()) + type1 = arg1->SemObject ()->Object ()->TypeInfo (); + if (arg2->NodeName () == CT_NamedType::NodeId () && + arg2->SemObject () && arg2->SemObject ()->Object ()) + type2 = arg2->SemObject ()->Object ()->TypeInfo (); + if (! type1) + type1 = arg1->Type (); + if (! type2) + type2 = arg2->Type (); + if (! type1 || ! type2 || *type1 != *type2) + return false; + } + + return true; +} + + +void CCSemantic::calculateAddress (CTree *node) const { + CObjectInfo *info; + LONG_LONG value; + + if (node->Value () || ! node->SemValue ()) + return; + + info = CCSemExpr::findObject (node); + if (info && info->Tree () && info->Tree ()->token_node ()) { + value = info->Tree ()->token_node ()->Number (); + node->SemValue ()->setValue (new CConstant (value, node->Type ())); + } +} + + +void CCSemantic::enter_template_decl () { + CT_TemplateParamList *tpl; + + // let the following declaration be in template scope + tpl = (CT_TemplateParamList*)builder ().get_node (builder ().nodes ()-2); + reenter_scope (tpl->Scope ()->Structure ()); +} + + +CTree *CCSemantic::template_decl () { + CT_TemplateDecl *td; + CTemplateInfo *info; + CObjectInfo *oinfo; + CT_ObjDecl *od; + CTree *decl; + + // parsing template declaration failed? + if (builder ().get_node (builder ().nodes ()-3)->NodeName () != + CT_TemplateParamList::NodeId ()) + return (CTree*)0; + + td = (CT_TemplateDecl*)builder ().template_decl (); + td->Scope (current_scope); + current_scope->Tree (td); + current_scope->SourceInfo ()->StartToken (td->token_node ()); + + info = current_scope->TemplateInfo (); + decl = td->Declaration (); + + // ���14.1 + oinfo = 0; + if (decl->NodeName () == CT_TemplateDecl::NodeId ()) + oinfo = ((CT_TemplateDecl*)decl)->Scope (); + else if (decl->NodeName () == CT_ObjDecl::NodeId ()) { + od = (CT_ObjDecl*)decl; + if (od->Declarators ()->Entries () > 1) { + SEM_ERROR (td, "multiple declarators in template declaration"); + } + } + + if (oinfo && ! info->ObjectInfo ()) + info->ObjectInfo (oinfo); + + return td; +} + + +void CCSemantic::introduceTemplate (CObjectInfo *oinfo, CTemplateInfo *info, bool is_friend) { + CStructure *scope; + + info->ObjectInfo (oinfo); + + // introduce declared class/union/function/static member into + // enclosing non-template scope for name lookup purposes only + scope = info->Parent ()->Structure (); + while (scope && scope != info && (scope->TemplateInfo () || + (is_friend && (scope->isRecord () || + (scope->NamespaceInfo () && scope->NamespaceInfo ()->aroundInstantiation ()))))) + scope = scope->Parent ()->Structure (); + + if (oinfo->Record ()) { + if (scope) { + // handle template specialization + if (info->isBaseTemplate ()) + scope->addType (oinfo); + setQualName (oinfo, info); + } else + info->Name (oinfo->Name ()); + } else if (oinfo->FunctionInfo ()) { + if (scope) { + // handle template specializations + if (info->isBaseTemplate ()) + scope->addFunction (oinfo->FunctionInfo ()); + setQualName (oinfo, info); + } else + info->Name (oinfo->Name ()); + } else if (oinfo->AttributeInfo ()) { + if (scope) { + // handle template specializations + if (info->isBaseTemplate ()) + scope->addAttribute (oinfo->AttributeInfo ()); + setQualName (oinfo, info); + } else + info->Name (oinfo->Name ()); + } +} + + +void CCSemantic::setTemplateScope (CCNameLookup &nl, CObjectInfo *oinfo, + CTypeInfo *type, CTemplateInfo *info, bool is_qual_name) { + CObjectInfo *prev; + bool is_template = ! is_qual_name; + + // is this a template definition or the definition of + // a non-template class template member? + if (is_qual_name) { + is_template = nl.Objects () ? false : true; + for (unsigned i = 0; i < nl.Objects (); i++) { + prev = nl.Object (i); + if (prev && prev->isTemplate () && equalType (prev->TypeInfo (), type, false)) { + is_template = true; + break; + } + } + } + + if (is_template) { + if (oinfo->Record ()) { + oinfo->Record ()->TemplateInfo (info); + oinfo->Record ()->isTemplate (true); + } else if (oinfo->FunctionInfo ()) { + oinfo->FunctionInfo ()->TemplateInfo (info); + oinfo->FunctionInfo ()->isTemplate (true); + } else if (oinfo->AttributeInfo ()) { + oinfo->AttributeInfo ()->TemplateInfo (info); + } + } +} + + +void CCSemantic::setQualName (CObjectInfo *oinfo, CObjectInfo *info) const { + CStructure *scope; + std::ostringstream name; + + if (! oinfo->Record ()) + scope = oinfo->QualifiedScope (); + else + scope = 0; + + if (scope && scope->Name ()) + name << scope->Name () << "::"; + name << oinfo->Name (); + info->Name (name.str ().c_str ()); +} + + +CTree *CCSemantic::explicit_instantiation () { + CT_TemplateDecl *td; + CTemplateInfo *info; + CObjectInfo *oinfo; + CTree *decl, *node; + CT_ObjDecl *od; + + node = builder ().explicit_instantiation (); + if (node->NodeName () == CT_LinkageSpec::NodeId ()) // => GCC EXTENSION!!! + td = (CT_TemplateDecl*)((CT_LinkageSpec*)node)->Decls (); + else + td = (CT_TemplateDecl*)node; + td->Scope (current_scope); + current_scope->Tree (td); + current_scope->SourceInfo ()->StartToken (td->token_node ()); + + info = current_scope->TemplateInfo (); + decl = td->Declaration (); + + // ���14.1 + oinfo = 0; + if (decl->NodeName () == CT_TemplateDecl::NodeId ()) + oinfo = ((CT_TemplateDecl*)decl)->Scope (); + else if (decl->NodeName () == CT_ObjDecl::NodeId ()) { + od = (CT_ObjDecl*)decl; + if (od->Declarators ()->Entries () > 1) { + SEM_ERROR (td, "multiple declarators in template declaration"); + } + } + + if (oinfo && ! info->ObjectInfo ()) + info->ObjectInfo (oinfo); + + return node; +} + + +CTree *CCSemantic::explicit_specialization () { + CT_TemplateDecl *td; + CTemplateInfo *info; + CObjectInfo *oinfo; + CT_ObjDecl *od; + CTree *decl; + + td = (CT_TemplateDecl*)builder ().explicit_specialization (); + td->Scope (current_scope); + current_scope->Tree (td); + current_scope->SourceInfo ()->StartToken (td->token_node ()); + + info = current_scope->TemplateInfo (); + decl = td->Declaration (); + + // ���14.1 + oinfo = 0; + if (decl->NodeName () == CT_TemplateDecl::NodeId ()) + oinfo = ((CT_TemplateDecl*)decl)->Scope (); + else if (decl->NodeName () == CT_ObjDecl::NodeId ()) { + od = (CT_ObjDecl*)decl; + if (od->Declarators ()->Entries () > 1) { + SEM_ERROR (td, "multiple declarators in template declaration"); + } + } + + if (oinfo && ! info->ObjectInfo ()) + info->ObjectInfo (oinfo); + + return td; +} + + +void CCSemantic::enter_template_param_list (Syntax::State state) { + // create and enter new template scope + CTemplateInfo *info = _db->newTemplate(); + info->SourceInfo ()->FileInfo (_file); + enter_scope (info); + if (state) + _in_template_param_list.push (state); + // state==0 means that this is an explicit specialization or + // instantiation (no template parameter list given) + else + info->isSpecialization (true); +} + + +CTree *CCSemantic::template_param_list () { + CT_TemplateParamList *tpl; + tpl = (CT_TemplateParamList*)builder ().template_param_list (); + tpl->Scope (current_scope); + return tpl; +} + + +CTree *CCSemantic::template_param () { + CT_TemplateParamDecl *tpd; + CT_ExprList *da; + CTree *arg; + + tpd = (CT_TemplateParamDecl*)builder ().template_param (); + da = tpd->DefaultArgument (); + + // resolve default template argument + if (da && da->Entries ()) { + arg = da->Entry (0); + if (arg->NodeName () != CT_NamedType::NodeId ()) { + resolveExpr (arg, da); + } + } + + return tpd; +} + + +CTree *CCSemantic::introduce_type_param () { + CTemplateParamInfo *info; + CT_TypeParamDecl *td; + + td = (CT_TypeParamDecl*)builder ().type_param (); + + // analysis not yet complete! + + info = current_scope->TemplateInfo ()->newTemplateParam (); + info->ObjectInfo ()->TypeInfo (new CTypeTemplateParam (info)); + info->isTypeParam (true); + Push (info); + + // template template parameter + if (td->Parameters ()) { + info->TemplateTemplate (td->Parameters ()->Scope ()->TemplateInfo ()); + info->TemplateTemplate ()->ObjectInfo (info); + } + + common_settings (info, td); + info->Name (td->Name ()->Text ()); + td->Name ()->Object (info); + td->Name ()->setTypeRef (info->TypeInfo ()); + td->Object (info); + return td; +} + + +CTree *CCSemantic::introduce_non_type_param () { + CTemplateParamInfo *info; + CT_NonTypeParamDecl *td; + CSemDeclSpecs *dsi; + CTypeInfo *type; + + finish_declarator (); + if (! in_decl ()) + return (CTree*)0; + + td = (CT_NonTypeParamDecl*)builder ().non_type_param (); + dsi = sem_decl_specs (); + CCSemDeclarator csd (_err, dsi->make_type (), td->Declarator ()); + if (! csd.Name ()) { + delete td; + return (CTree*)0; + } + + type = csd.Type (); + bool error = true; + if (current_scope->TemplateParams (csd.Name ()->Text ())) { + SEM_ERROR__duplicate (td, "template parameter", csd.Name ()); + } else if (dsi->declared (CT_PrimDeclSpec::PDS_STATIC) || + dsi->declared (CT_PrimDeclSpec::PDS_THREAD) || + dsi->declared (CT_PrimDeclSpec::PDS_EXTERN) || + dsi->declared (CT_PrimDeclSpec::PDS_AUTO) || + dsi->declared (CT_PrimDeclSpec::PDS_REGISTER) || + dsi->declared (CT_PrimDeclSpec::PDS_MUTABLE)) { + SEM_ERROR__invalid_in_param (td, "storage class specifier", csd.Name ()); + } else if (dsi->declared (CT_PrimDeclSpec::PDS_TYPEDEF)) { + SEM_ERROR__invalid_in_param (td, "typedef declaration", csd.Name ()); + } else if (type->isFunction () || type->isArray ()) { + // template non-type parameter adjustment + csd.Type (new CTypePointer ( + type->isArray () ? type->VirtualType ()->BaseType () : type)); + error = false; + } else if (! (type->isInteger () || type->isPointer () || + type->isAddress () || type->isMemberPointer () || + type->isTemplateParam ())) { + SEM_ERROR__invalid_param (td, "type", csd.Name ()); + } else + error = false; + if (error) { + delete td; + return (CTree*)0; + } + + info = current_scope->TemplateInfo ()->newTemplateParam (); + Push (info); + + setLanguage (info); + setSpecifiers (info, dsi); + common_settings (info, td); + info->Name (csd.Name ()->Text ()); + info->ObjectInfo ()->TypeInfo (new CTypeTemplateParam (info)); + info->ValueType (csd.Type ()); + csd.Type ((CTypeInfo*)0); + csd.Name ()->Object (info); + csd.Name ()->setTypeRef (info->TypeInfo ()); + td->Object (info); + if (dsi) decl_end (); + return td; +} + + +/*****************************************************************************/ +/* */ +/* Objects */ +/* */ +/*****************************************************************************/ + + +CTree *CCSemantic::obj_decl (CTree *node) { + CT_DeclaratorList *dl; + CT_DeclSpecSeq *dss; + CTree *d; + + if (! node || node->NodeName () != CT_ObjDecl::NodeId ()) + return node; + + // attribute init declarators and class defs + + dl = ((CT_ObjDecl*)node)->Declarators (); + if (dl) { + for (unsigned i = dl->Entries (); i > 0; i--) { + d = dl->Entry (i-1); + if (d->NodeName () == CT_InitDeclarator::NodeId ()) + ((CT_InitDeclarator*)d)->ObjDecl (node); + } + } + + dss = ((CT_ObjDecl*)node)->DeclSpecs (); + if (dss) { + for (unsigned i = dss->Entries (); i > 0; i--) { + d = dss->Entry (i-1); + if (d->NodeName () == CT_ClassDef::NodeId () || + d->NodeName () == CT_UnionDef::NodeId ()) + ((CT_ClassDef*)d)->ObjDecl (node); + } + } + + return node; +} + + +CTree *CCSemantic::introduce_object (CTree* tree) { + bool is_typedef, is_fct, is_attr, redef_typedef, is_special, is_qual_name; + CStructure *scope, *lookup_scope; + CObjectInfo *info, *prev = 0; + CT_InitDeclarator *id; + CTemplateInfo *tinfo; + CSemDeclSpecs *dsi; + CTypeInfo *type; + + if (! in_decl ()) + return (CTree*)0; + + // determine type of declaration + id = (CT_InitDeclarator*)(tree ? tree : builder ().init_declarator1 ()); + dsi = sem_decl_specs (); + CCSemDeclarator csd (_err, dsi->make_type (), id); + if (! csd.Name ()) { + delete id; + return (CTree*)0; + } + + // determine properties of declarations + type = csd.Type (); + is_typedef = dsi->declared (CT_PrimDeclSpec::PDS_TYPEDEF); + is_fct = (! is_typedef && type->isFunction () && ! type->isAddress ()); + is_attr = ! (is_typedef || is_fct); + is_special = isSpecialization (csd.Name ()); + is_qual_name = isQualName (csd.Name ()); + lookup_scope = is_special ? current_scope : getNonTplScope (true); + scope = getNameScope (csd.Name ()); + if (is_qual_name && scope != lookup_scope) + lookup_scope = scope; + + // lookup name + CCNameLookup nl (*_err, current_scope, false); + nl.lookup (csd.Name (), lookup_scope); + + // check name lookup results + if (! check_object_lookup (nl, lookup_scope, dsi, csd, id, redef_typedef, prev)) { + delete id; + return (CTree*)0; + } + + // typedef declaration + if (is_typedef) { + info = current_scope->newTypedef (); + Push (info); + // function prototype declaration + } else if (is_fct) { +/*DEBUG*/if (TRACE_FCT) std::cout<<"FCT DEC(1): "<<(void*)current_fct<newFunction (); + else + current_fct->ScopeInfo ()->Parent ()->Structure ()-> + addFunction (current_fct->FunctionInfo ()); + info = current_fct; + // determine function category + if (lookup_scope->Record () && lookup_scope->Name () && + strcmp (lookup_scope->Name (), csd.Name ()->Name ()->Text ()) == 0) + info->FunctionInfo ()->isConstructor (true); + else if (csd.Name ()->Name ()->NodeName () == CT_DestructorName::NodeId ()) + info->FunctionInfo ()->isDestructor (true); + else if (csd.Name ()->Name ()->NodeName () == CT_OperatorName::NodeId ()) + info->FunctionInfo ()->isOperator (true); + else if (csd.Name ()->Name ()->NodeName () == CT_ConversionName::NodeId ()) { + info->FunctionInfo ()->isConversion (true); + info->FunctionInfo ()->ConversionType ( + ((CT_ConversionName*)csd.Name ()->Name ())-> + TypeName ()->Object ()->TypeInfo ()); + } + info->Linkage (determine_linkage (dsi, FCT, prev)); + if (is_qual_name || lookup_scope->Record ()) + info->FunctionInfo ()->QualifiedScope (getQualifiedScope (lookup_scope)); + type->VirtualType ()->TypeFunction ()->FunctionInfo (info->FunctionInfo ()); + // handle template declaration + if (current_scope->TemplateInfo ()) + setTemplateScope (nl, info, csd.Type (), current_scope->TemplateInfo (), is_qual_name); + // non-fct non-type declaration + } else { + info = current_scope->newAttribute (); + info->Linkage (determine_linkage (dsi, ATTRIB, prev)); + info->Storage (determine_storage_class (dsi)); + Push (info); + // enter scope of class if definition of static class member + if (is_qual_name) { + last_scope = current_scope; + reenter_scope (lookup_scope); + info->AttributeInfo ()->QualifiedScope (getQualifiedScope (lookup_scope)); + if (prev) + info->Protection (prev->Protection ()); + } + } + + // complete semantic information about the declaration + setLanguage (info); + setSpecifiers (info, dsi); + common_settings (info, id, &csd); + id->Object (info); + + // handle "redefining" typedefs + if (redef_typedef) { + char aname[100]; + sprintf (aname, "%%anon%ld", _Anonymous); + _Anonymous++; + info->Name (aname); + } else if (info->TypedefInfo ()) { + type = info->TypeInfo ()->TypedefInfo (info); + info->TypeInfo (type); + } + + // link former declarations with this one + if (prev) { + if ((is_attr && prev->AttributeInfo ()) || (! is_fct && redef_typedef && prev->TypedefInfo ())) + prev->NextObject (info); + } + if (is_fct) { + if (! is_special) + linkFctDecls (nl, info); + if (info->FunctionInfo ()->isConstructor ()) + linkCtorDecls (info->FunctionInfo ()); + } + + // handle template declarations + tinfo = current_scope->TemplateInfo (); + if (tinfo) { + setSpecializationName (csd.Name (), tinfo); + introduceTemplate (info, tinfo); + } + + if (is_fct) + current_fct = 0; + + // if an attribute with class object type, ensure + // that the class is really instantiated + if (info->AttributeInfo() && type->UnqualType()->TypeClass()) { + type->UnqualType()->TypeClass()->instantiate(current_scope); + } + + return id; +} + + +bool CCSemantic::check_object_lookup (CCNameLookup &nl, CStructure *lookup_scope, + CSemDeclSpecs *dsi, CCSemDeclarator &csd, CTree *id, bool &redef_typedef, + CObjectInfo *& prev) { + bool is_typedef, is_fct, is_attr, error; + CTypeInfo *type; + + type = csd.Type (); + is_typedef = dsi->declared (CT_PrimDeclSpec::PDS_TYPEDEF); + is_fct = (! is_typedef && type->isFunction () && ! type->isAddress ()); + is_attr = ! (is_typedef || is_fct); + error = true; + redef_typedef = false; + + // check lookup results + if (nl.Objects ()) { + prev = nl.Object (); + // ���7.1.3.2 typedef redefining same type + if (is_typedef && + ((prev->TypedefInfo () && equalType (type, prev->TypeInfo ())) || + (prev->Record () && type->TypeRecord () && + *type->TypeRecord ()->Record () == *prev) || + (prev->EnumInfo () && type->TypeEnum () && + *type->TypeEnum ()->EnumInfo () == *prev))) + redef_typedef = true; + + // conflicting declarations in lookup scope + if (is_typedef && ! redef_typedef) { + SEM_ERROR__conflicting_types (id, prev); + // conflicting declarations in lookup scope + } else if ((is_attr && ! (prev->AttributeInfo () || isClassOrEnum (prev))) || + (is_fct && ! (prev->FunctionInfo () || isClassOrEnum (prev)))) { + SEM_ERROR__already_defined (id, csd.Name (), prev); + // conflicting declarations in lookup scope + } else if (is_attr && prev->AttributeInfo () && + prev->Linkage () != CLinkage::LINK_EXTERNAL && + ! ((prev->Storage () == CStorage::CLASS_STATIC || + prev->Storage () == CStorage::CLASS_THREAD) && + prev->Scope ()->Record ())) { + SEM_ERROR__redefinition (id, csd.Name (), prev); + } else + error = false; + // declaration using qualified name but entity not exists + } else if (isQualName (csd.Name ())) { + std::ostringstream name; qualifiedScopeName (csd.Name (), name); + SEM_ERROR__not_member (id, csd.Name ()->Name (), name.str ().c_str ()); + } else + error = false; + return ! error; +} + + +CTree *CCSemantic::introduce_named_type () { + CSemDeclSpecs *dsi; + CObjectInfo *info; + CT_NamedType *nt; + + if (! in_decl ()) + return (CTree*)0; + + nt = (CT_NamedType*)builder ().type_id (); + dsi = sem_decl_specs (); + CCSemDeclarator csd (_err, dsi->make_type (), nt->Declarator ()); + if (! csd.Name ()) { + delete nt; + return (CTree*)0; + } + + info = current_scope->newAttribute (); + info->Linkage (determine_linkage (dsi, ATTRIB)); + info->Storage (determine_storage_class (dsi)); + Push (info); + + setLanguage (info); + setSpecifiers (info, dsi); + common_settings (info, nt, &csd); + nt->Object (info); + decl_end (); + return nt; +} + + +CTree *CCSemantic::decl_spec_seq1 () { + CT_PrimDeclSpec::Type type; + CObjectInfo* info, *scope; + CT_DeclSpecSeq *dss; + CT_SimpleName *name; + Token *token; + CTree *ds; + bool ctor; + + // handle the ambiguity between parsing a name in a + // declaration as a type-name or as a declarator-id + + dss = decl_specs (); + ds = builder ().decl_spec_seq1 (); + + // here no ambiguity exist + if (in_conv_type_id ()) { + /* nothing to do :) */ + // type-name + } else if (ds->NodeName () == CT_SimpleName::NodeId () || + ds->NodeName () == CT_TemplateName::NodeId () || + ds->NodeName () == CT_QualName::NodeId () || + ds->NodeName () == CT_RootQualName::NodeId ()) { + name = (CT_SimpleName*)ds; + info = name->Name ()->Object (); + ctor = info && info->Record () && syntax ().look_ahead (TOK_OPEN_ROUND); + + // ambiguous situation? + if (ctor || (info && dss->Sons () && + (info->Record () || info->EnumInfo () || info->TypedefInfo ()))) { + // are there already type specifiers? + for (int i = 0; i < dss->Sons (); i++) { + if (dss->Son (i)->NodeName () == CT_PrimDeclSpec::NodeId ()) { + type = ((CT_PrimDeclSpec*)dss->Son (i))->SpecType (); + if (type == CT_PrimDeclSpec::PDS_CHAR || + type == CT_PrimDeclSpec::PDS_WCHAR_T || + type == CT_PrimDeclSpec::PDS_BOOL || + type == CT_PrimDeclSpec::PDS_SHORT || + type == CT_PrimDeclSpec::PDS_INT || + type == CT_PrimDeclSpec::PDS_LONG || + type == CT_PrimDeclSpec::PDS_SIGNED || + type == CT_PrimDeclSpec::PDS_UNSIGNED || + type == CT_PrimDeclSpec::PDS_FLOAT || + type == CT_PrimDeclSpec::PDS_DOUBLE || + type == CT_PrimDeclSpec::PDS_INT64 || + type == CT_PrimDeclSpec::PDS_INT128 || + type == CT_PrimDeclSpec::PDS_UNKNOWN_T || + type == CT_PrimDeclSpec::PDS_VOID) + return (CTree*)0; + } else + return (CTree*)0; + } + + // constructor name? + if (ctor) { + scope = getNameScope (name, false); + if (! isQualName (name)) + while (scope->TemplateInfo () || (scope->NamespaceInfo () && scope->NamespaceInfo ()->aroundInstantiation ())) + scope = scope->ScopeInfo ()->Parent (); + + CTemplateInstance *instance = info->TemplateInstance (); + if (instance && (! scope->isTemplateInstance () || ! instance->canInstantiate ())) + info = instance->Template ()->ObjectInfo (); + instance = scope->TemplateInstance (); + if (instance && (! info->isTemplateInstance () || ! instance->canInstantiate ())) + scope = instance->Template ()->ObjectInfo (); + + if (*info == *scope) + return (CTree*)0; + } + } + } else if (ds->NodeName () == CT_PrimDeclSpec::NodeId () && + ((CT_PrimDeclSpec*)ds)->SpecType () == CT_PrimDeclSpec::PDS_BOOL && + dss->Sons () && ! current_scope->GlobalScope ()) { + // is there already a complete type? + for (int i = 0; i < dss->Sons (); i++) { + if (dss->Son (i)->NodeName () == CT_PrimDeclSpec::NodeId ()) { + type = ((CT_PrimDeclSpec*)dss->Son (i))->SpecType (); + if (! (type == CT_PrimDeclSpec::PDS_CHAR || + type == CT_PrimDeclSpec::PDS_WCHAR_T || + type == CT_PrimDeclSpec::PDS_BOOL || + type == CT_PrimDeclSpec::PDS_SHORT || + type == CT_PrimDeclSpec::PDS_INT || + type == CT_PrimDeclSpec::PDS_LONG || + type == CT_PrimDeclSpec::PDS_SIGNED || + type == CT_PrimDeclSpec::PDS_UNSIGNED || + type == CT_PrimDeclSpec::PDS_FLOAT || + type == CT_PrimDeclSpec::PDS_DOUBLE || + type == CT_PrimDeclSpec::PDS_INT64 || + type == CT_PrimDeclSpec::PDS_INT128 || + type == CT_PrimDeclSpec::PDS_UNKNOWN_T || + type == CT_PrimDeclSpec::PDS_VOID)) + continue; + } + token = ds->token (); + if (token) + token->reset (TOK_ID, "bool", Token::identifier_id); + return (CTree*)0; + } + } + + dss->AddSon (ds); + return ds; +} + + +CTree *CCSemantic::valid_id_expr() { + CTree* expr = _postfix_expr.top (); + if (expr && expr->IsSimpleName() && !CCSemExpr::isDependent(expr)) { + // if name denotes a type, then this is not a valid id-expression + CT_SimpleName* name = (CT_SimpleName*)expr; + Token *token = name->Name()->token(); + + // get the name's scope + CStructure *scope = current_scope; + int entries = name->Entries (); + if (isQualName(name) && entries > 1) + scope = getScope(((CT_SimpleName*)name->Entry(entries-2))->Object()); + else if (name->NodeName() == CT_RootQualName::NodeId()) + scope = _file; + + if (scope) { + // lookup the name + lookupName(token, scope, true); + if (shared_nl.Objects()) { + CObjectInfo *info = shared_nl.Object(); + if (info->isType()) { + return 0; + } + } + } + } + return expr; +} + + +CTree *CCSemantic::postfix_expr () { + if (!_postfix_expr.top ()) + _postfix_expr.top () = builder ().postfix_expr (); + else + _postfix_expr.top () = builder ().postfix_expr (_postfix_expr.top ()); + return _postfix_expr.top (); +} + + +CTree *CCSemantic::postfix_expr2 () { + CT_ConstructExpr *ce; + CTree *result, *name; + CT_DeclSpecSeq *dss; + CObjectInfo *info; + CT_NamedType *nt; + + result = builder ().postfix_expr2 (); + if (result && result->NodeName () == CT_ConstructExpr::NodeId ()) { + name = PrivateName (); + dss = new CT_DeclSpecSeq; + dss->AddSon (result->Son (0)); + nt = new CT_NamedType (dss, name); + CSemDeclSpecs dsi (_err, dss); + CCSemDeclarator csd (_err, dsi.make_type (), name); + + info = current_scope->newAttribute (); + info->Linkage (determine_linkage (&dsi, ATTRIB)); + info->Storage (determine_storage_class (&dsi)); + Push (info); + + setSpecifiers (info, &dsi); + setLanguage (info); + common_settings (info, nt, &csd); + nt->Object (info); + ce = (CT_ConstructExpr*)result; + ce->ReplaceSon (result->Son (0), nt); + ce->Object (info); + ce->setTypeRef (info->TypeInfo ()); + + // resolve initializer arguments + CT_ExprList *init = ce->Initializer (); + if (init) { + unsigned entries = init->Entries (); + for (unsigned i = 0; i < entries; i++) + resolveExpr (init->Entry (i), init); + } + } + + return result; +} + + +CTree *CCSemantic::postfix_expr1 () { + CT_SimpleName *sn; + + if (builder ().nodes () == 3) { + // member name prefixed by `template'? + switch (builder ().get_node (0)->token ()->type ()) { + case TOK_DOT: + case TOK_PTS: + // in a postfix-expression only unqualified + // member names may be prefixed by `template' + sn = (CT_SimpleName*)builder ().get_node (2); + if (sn->NodeName () == CT_QualName::NodeId () || + sn->NodeName () == CT_RootQualName::NodeId ()) + return (CTree*)0; + default: + break; + } + } + + return builder ().postfix_expr1 (); +} + + +CTree *CCSemantic::pseudo_dtor_name () { + int num = builder ().nodes (); + + // `template' may only be used after a nested_name_spec + if ((num == 5 && + builder ().get_node (0)->token ()->type () == TOK_TEMPLATE) || + (num == 6 && + builder ().get_node (1)->token ()->type () == TOK_TEMPLATE && + builder ().get_node (0)->token ()->type () == TOK_COLON_COLON)) + return (CTree*)0; + + return builder ().pseudo_dtor_name (); +} + + +CTree *CCSemantic::simple_type_spec () { + int num = builder ().nodes (); + + // `template' may only be used after a nested_name_spec + if ((num == 2 && + builder ().get_node (0)->token ()->type () == TOK_TEMPLATE) || + (num == 3 && + builder ().get_node (1)->token ()->type () == TOK_TEMPLATE && + builder ().get_node (0)->token ()->type () == TOK_COLON_COLON)) + return (CTree*)0; + + return builder ().simple_type_spec (); +} + + +CTree *CCSemantic::direct_new_declarator () { + builder ().Push (PrivateName ()); + return builder ().direct_new_declarator (); +} + + +void CCSemantic::declarator_id (bool tname) { + // handle parameter declaration ambiguity + if (in_arg_decl) + is_type_name = tname; +} + + +CTree *CCSemantic::finish_init_declarator () { + if (last_scope) + reenter_scope (last_scope); + last_scope = 0; + return (CTree*)0; +} + + +/*****************************************************************************/ +/* */ +/* Namespaces */ +/* */ +/*****************************************************************************/ + + +void CCSemantic::declareNamespaceStd () { + CNamespaceInfo *info; + + info = _file->newNamespace (); + info->TypeInfo (&CTYPE_UNDEFINED); + info->Name ("std"); + info->SourceInfo ()->FileInfo (_file); + Push (info); +} + + +CTree *CCSemantic::introduce_orig_ns () { + CUsingInfo *uinfo; + CNamespaceInfo *info; + CT_NamespaceDef *nd; + + nd = (CT_NamespaceDef*)builder ().orig_namespace_def1 (); + + CCNameLookup nl (*_err, current_scope, false); + nl.lookup (nd->Name (), current_scope); + if (nl.Objects ()) { + // ���7.3.1.2 namespace name shall be undefined in this scope + // (for gcc3.2 compatibility there can also be a type with + // the same name in this scope) + SEM_ERROR__already_defined (nd, nd->Name (), nl.Object ()); + delete nd; + return (CTree*)0; + } + + info = current_scope->newNamespace (); + info->TypeInfo (&CTYPE_UNDEFINED); + info->Name (nd->Name ()->Text ()); + + if (nd->isInline ()) { + // C++11 inline namespace + info->isInline (true); + // A using-directive that names the inline namespace is implicitly + // inserted in the enclosing namespace (similar to the implicit + // using-directive for the unnamed namespace) + uinfo = current_scope->newUsing (); + uinfo->TypeInfo (&CTYPE_UNDEFINED); + uinfo->Name (info->Name ()); + uinfo->Namespace (info); + Push (uinfo); + } + + // common settings + enter_scope (info); + common_settings (info, nd); + nd->Name ()->Object (info); + nd->Object (info); + + return nd; +} + + +CTree *CCSemantic::introduce_ns_extension () { + CNamespaceInfo *info, *prev; + CT_NamespaceDef *nd; + + // this is only an extension if the scope of the namespace name is + // equivalent with the current scope. However, as original_ns_name only + // guarantees that the name *exists*, we have to check this here. + int isinline = builder ().get_node (0)->token ()->type () == TOK_INLINE; + CT_SimpleName *name = (CT_SimpleName*)builder ().get_node (isinline ? 2 : 1); + if (*name->Object ()->Scope () != *current_scope) + return 0; // will become a new namespace, not an extension! + + nd = (CT_NamespaceDef*)builder ().orig_namespace_def1 (); + prev = (CNamespaceInfo*)nd->Name ()->Object (); + + info = current_scope->newNamespace (); + info->setShared (prev); + info->TypeInfo (&CTYPE_UNDEFINED); + info->Name (prev->Name ()); + info->isInline (prev->isInline ()); +// Push (info); // pushed by enter_scope()!!! + + // link it together + prev->NextObject (info); + + // common settings + enter_scope (info); + common_settings (info, nd); + nd->Name ()->Object (info); + nd->Object (info); + return nd; +} + + +CTree *CCSemantic::introduce_unnamed_ns () { + CUsingInfo *uinfo; + CNamespaceInfo *info, *prev; + CT_NamespaceDef *nd; + + nd = (CT_NamespaceDef*)builder ().orig_namespace_def1 (); + + // check whether there is already an unnamed namespace in the + // current scope + prev = (CNamespaceInfo*)0; + CCNameLookup nl (*_err, current_scope, false); + nl.lookup ("", current_scope); + if (nl.Objects ()) { + // yes, this is an extension. + // connect the namespaces and share a symbol table + prev = (CNamespaceInfo*)nl.Object (0); + } + + info = current_scope->newNamespace (); + info->TypeInfo (&CTYPE_UNDEFINED); + info->Name (""); // all unnamed namespaces get the same name + if (nd->isInline ()) { + // C++11 inline namespace + info->isInline (true); + } +// info->Name (nd->Name ()->Text ()); +// Push (info); // pushed by enter_scope()!!! + + // connect with original definition + if (prev) { + info->setShared (prev); + prev->NextObject (info); + } + else { + // ���7.3.1.1 an unnamed namespace definition behaves as if + // it were replaced by: + // namespace %unique-name { /* empty body */ } + // using namespace %unique-name; + // namespace %unique-name { /* namespace-body */ } + uinfo = current_scope->newUsing (); + uinfo->TypeInfo (&CTYPE_UNDEFINED); + uinfo->Name (info->Name ()); + uinfo->Namespace (info); + Push (uinfo); + } + // common settings + enter_scope (info); + common_settings (info, nd); + nd->Name ()->Object (info); + nd->Object (info); + return nd; +} + + +CTree *CCSemantic::namespace_def () { + CT_NamespaceDef *result = (CT_NamespaceDef*)builder ().orig_namespace_def (); + result->Members ()->Scope (current_scope); + return result; +} + + +CTree *CCSemantic::introduce_ns_alias () { + CNamespaceInfo *info, *orig; + CT_NamespaceAliasDef *nd; + CObjectInfo *prev = 0; + + nd = (CT_NamespaceAliasDef*)builder ().ns_alias_def (); + + // lookup original namespace name + CCNameLookup nl (*_err, current_scope, false); + nl.lookupNamespace (nd->Name (), current_scope); + if (! nl.Objects ()) { + SEM_ERROR__unknown_ns (nd, nd->Name ()); + delete nd; + return (CTree*)0; + } else + orig = (CNamespaceInfo*)nl.Object (); + + // lookup namespace alias name + nl.reset (); + nl.lookupType (nd->Alias (), current_scope); + if (nl.Objects ()) { + prev = nl.Object (); + // ���7.3.2.3 namespace aliases can be redefined + if (! prev->NamespaceInfo () || ! prev->NamespaceInfo ()->isAlias ()) { + SEM_ERROR__already_defined (nd, nd->Alias (), prev); + delete nd; + return (CTree*)0; + } + // the original alias has to be an alias of the same namespace + // as specified in the current namespace alias definition + info = prev->NamespaceInfo (); + while (true) { + info = (CNamespaceInfo*)info->NextObject (); + if (info == orig) // ok, alias of the same namespace + break; + if (info == prev) { + SEM_ERROR__redefinition (nd, nd->Alias (), prev); + delete nd; + return (CTree*)0; + } + } + } + + info = current_scope->newNamespace (); + info->setShared (orig); + info->TypeInfo (&CTYPE_UNDEFINED); + info->Name (nd->Alias ()->Text ()); + info->isAlias (true); + Push (info); + + // link alias and original namespace + orig->NextObject (info); + + // common settings + common_settings (info, nd); + nd->Alias ()->Object (info); + nd->Object (info); + return nd; +} + + +CTree *CCSemantic::using_directive () { + CUsingInfo *info; + CNamespaceInfo *nsinfo; + CT_UsingDirective *ud; + + ud = (CT_UsingDirective*)builder ().using_directive (); + if (isQualName (ud->Name ())) + nsinfo = (CNamespaceInfo*)ud->Name ()->Name ()->Object (); + else + nsinfo = (CNamespaceInfo*)ud->Name ()->Object (); + + // ���7.3.4 a using directive shall only appear in namespace + // or local scope + if (! (current_scope->isNamespace () || current_scope->isLocalScope ())) { + SEM_ERROR (ud, "using directive only allowed in block or namespace scope"); + delete ud; + return (CTree*)0; + } + + // delete possibly created container object because it would + // be deleted by the builder only when the rule fails + deleteContainer (3); + + info = current_scope->newUsing (); + info->TypeInfo (&CTYPE_UNDEFINED); + info->Name (nsinfo->Name ()); + info->Namespace (nsinfo); + Push (info); + + // common settings + common_settings (info, ud); + return ud; +} + + +CTree *CCSemantic::using_decl () { + CMemberAliasInfo *minfo; + CObjectInfo *info; + CT_UsingDecl *ud; + + ud = (CT_UsingDecl*)builder ().using_decl (); + if (current_scope->ClassInfo ()) + return access_decl (ud); + + // check for dependent name + info = getLastResolvedName (ud->Member ()); + if (info && info->TypeInfo () && info->TypeInfo ()->isDependent ()) { + deleteContainer (3); + return ud; + } + + // using declaration in block or namespace scope + + CCNameLookup nl (*_err, current_scope, !is_entity_name()); + nl.lookup (ud->Member (), current_scope); + if (! nl.Objects ()) { + // report error + std::ostringstream name; qualifiedScopeName (ud->Member (), name); + SEM_ERROR__not_member (ud, ud->Member ()->Name (), name.str ().c_str ()); + delete ud; + return (CTree*)0; + } + + // delete possibly created container object because it would + // be deleted by the builder only when the rule fails + deleteContainer (3); + + // check for duplicates in current scope +// CCNameLookup onl (*_err, current_scope, !is_entity_name()); +// if (nl.Objects ()) { +// info = nl.Object (); +// if (info->Record () || info->EnumInfo ()) +// onl.lookupType (info->Name (), current_scope); +// else +// onl.lookup (info->Name (), current_scope); +// } + + // introduce aliases into the current scope + for (unsigned i = 0; i < nl.Objects (); i++) { + info = nl.Object (i); + + // handle redefined typedefs -> we might have found an anonymous object + CObjectInfo *start = info; + while (info->TypedefInfo () && info->isAnonymous ()) { + info = info->NextObject (); + if (info == start) + break; // TODO: error message? + } + +// error checks: not yet implemented +// if (info->Record () || info->EnumInfo () || info->TypedefIndo () || +// info->isNamespace ()) && onl.Objects ()) +// if (info->isFunction () && onl.Objects () && +// ((onl->areFunctions && equalTypes()) || !onl->isType)) +// if (info->isAttrib && +// ((onl->isAttrib && !onl->isExtern && !info->isExtern) || !onl->isType)) + + minfo = current_scope->newMemberAlias (info); + minfo->TypeInfo (info->TypeInfo ()->Duplicate ()); + minfo->Name (info->Name ()); + minfo->Member (info); + setProtection (minfo); + Push (minfo); + common_settings (minfo, ud); + } + return ud; +} + + +CTree *CCSemantic::access_decl (CTree *d) { + CMemberAliasInfo *minfo; + CT_AccessDecl *ad; + CObjectInfo *info; + CRecord *cinfo; + + ad = (CT_AccessDecl*)(d ? d : builder ().access_decl ()); + + // check for dependent name + info = getLastResolvedName (ad->Member ()); + if (info && info->TypeInfo () && info->TypeInfo ()->isDependent ()) { + return ad; + } + + CCNameLookup nl (*_err, current_scope, !is_entity_name()); + nl.lookup (ad->Member (), current_scope); + if (! nl.Objects ()) { + std::ostringstream name; qualifiedScopeName (ad->Member (), name); + SEM_ERROR__not_member (ad, ad->Member ()->Name (), name.str ().c_str ()); + delete ad; + return (CTree*)0; + } else { + info = nl.Object (); + cinfo = (info->FunctionInfo () ? info->FunctionInfo ()->Record () : + info->Scope ()->Record ()); + if (! cinfo || + ! isBaseClass (current_scope->ClassInfo (), cinfo->ClassInfo ())) { + if (! cinfo) { + SEM_ERROR (ad, "`" << *ad->Member () << "' is not a class member"); + } else { + SEM_ERROR__not_base_class (ad, cinfo); + } + delete ad; + return (CTree*)0; + } + } + + // introduce aliases of the base class members looked up + // into the current scope + for (unsigned i = 0; i < nl.Objects (); i++) { + info = nl.Object (i); + minfo = current_scope->newMemberAlias (info); + minfo->TypeInfo (info->TypeInfo ()->Duplicate ()); + minfo->Name (info->Name ()); + minfo->Member (info); + setProtection (minfo); + Push (minfo); + common_settings (minfo, ad); + } + return ad; +} + + +/*****************************************************************************/ +/* */ +/* constant expression evaluation */ +/* */ +/*****************************************************************************/ + + +CTree *CCSemantic::const_expr () { + CTree *result = builder ().const_expr (); + if (result) + resolveExpr (result); + return result; +} + + +CStructure *CCSemantic::array_delim (CStructure *scope) { + // enter class scope to find class scope members + if (scope) + reenter_scope (scope); + else { + scope = current_scope; + if (last_search_scope) + reenter_scope (last_search_scope); + } + return scope; +} + + +CStructure *CCSemantic::conv_fct_id (CStructure *scope) { + // enter class scope to find class scope members + if (scope) + reenter_scope (scope); + else { + scope = current_scope; + if (last_search_scope) { + CFunctionInfo *info = _db->newFunction(); + info->Name("%conv_type_id"); + info->QualifiedScope (getQualifiedScope (last_search_scope)); + enter_scope (info); + } + } + return scope; +} + + +CTypeInfo *CCSemantic::resolveExpr (CTree *expr, CTree *base) const { + if (expr) { + CCSemExpr cse (*_err, current_scope); + return cse.resolveExpr (expr, base); + } + return (CTypeInfo*)0; +} + + +CTree *CCSemantic::init_declarator () { + CT_InitDeclarator *node; + CObjectInfo *info; + CTree *init; + + node = (CT_InitDeclarator*)builder ().init_declarator (); + info = node->Object (); + + // evaluate the initializer of constant variables and + // class members before its further use + if (info && info->TypeInfo ()->isConst ()) { + init = node->Initializer (); + if (init) { + CCSemExpr cse (*_err, current_scope); + cse.resolveInit (init, node); + } + } + + return node; +} + + +CTree *CCSemantic::pure_spec () { + CT_ExprList *el; + CTree *expr; + + el = (CT_ExprList*)builder ().pure_spec (); + if (el->Entries ()) { + expr = el->Entry (0); + resolveExpr (expr, el); + expr = el->Entry (0); + if (expr->Type ()) + el->setTypeRef (expr->Type ()); + else + el->setTypeRef (&CTYPE_UNDEFINED); + + if (expr->Value ()) + el->setValueRef (expr->Value ()); + } + return el; +} + + +CTree *CCSemantic::const_init () { + CT_ExprList *el; + CTree *expr; + + el = (CT_ExprList*)builder ().const_init (); + if (el->Entries ()) { + expr = el->Entry (0); + if (expr->Type ()) + el->setTypeRef (expr->Type ()); + else + el->setTypeRef (&CTYPE_UNDEFINED); + + if (expr->Value ()) + el->setValueRef (expr->Value ()); + } + return el; +} + + +} // namespace Puma diff --git a/Puma/src/parser/ccparser/CCSemantic.h b/Puma/src/parser/ccparser/CCSemantic.h new file mode 100644 index 0000000..9ee0ebe --- /dev/null +++ b/Puma/src/parser/ccparser/CCSemantic.h @@ -0,0 +1,366 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CCSemantic_h__ +#define __CCSemantic_h__ + +#include "Puma/CSemantic.h" +#include "Puma/CCBuilder.h" +#include "Puma/CCSyntax.h" +#include "Puma/CLinkage.h" +#include "Puma/CProtection.h" +#include "Puma/Stack.h" +#include "Puma/CTree.h" +#include "Puma/CCNameLookup.h" + +namespace Puma { + + +class CFunctionInfo; +class CRecord; +class CCSemDeclarator; +class CCInstantiation; +class CTemplateInfo; +class CT_DelayedParse; + +class CCSemantic : public CSemantic { + CCSyntax &_syntax; + +protected: + CRecord* _outermost_class_def; + + Stack _in_base_spec; + Stack _in_nested_name; + Stack _in_conv_type_id; + Stack _in_extern_decl; + Stack _protection; + +public: + // for parsing nested names + CStructure *search_scope; + CStructure *last_search_scope; + CStructure *last_scope; + bool dep_nested_name; + + // different kinds of member access operators; MAO_NONE shall remain 0! + enum MemberAccessOperator { MAO_NONE = 0, MAO_PTS, MAO_DOT }; + +protected: + // for looking up type-names and class-or-namespace-names + CCNameLookup shared_nl; + struct { const Token *tok; CStructure *scope; bool nested, nested_name, base_spec; } last_token_nl; + + // for parsing templates + Stack _in_template_arg_list; + Stack _in_template_param_list; + Stack parsing_entity_name; + Stack _in_expr; + Stack _postfix_expr; + Stack _in_memb_access_expr; + bool expect_template; + bool parsing_fct_inst; + bool parsing_class_inst; + bool real_inst; + CCInstantiation *tpl_inst; + + // last function body skip state + Unit *_last_unit; + bool _last_body_skipped; + +public: + CCSemantic (CCSyntax &, CCBuilder &); + + void init (CSemDatabase &, Unit &); + void init (CSemDatabase &, Unit &, CStructure *, bool, bool, CCInstantiation *); + + CCInstantiation* Instantiation() const; + +protected: + virtual CCBuilder &builder () const; + virtual CCSyntax &syntax () const; + virtual void Delete (); + +public: + // control parse process + virtual CTree *access_spec (); + virtual CTree *typedef_name (); + virtual CTree *class_name (); + virtual CTree *enum_name (); + virtual CTree *condition (); + virtual CTree *colon_colon (); + virtual CTree *decl_spec_seq1 (); + virtual CTree *nested_name_spec (); + virtual CTree *nested_name_spec1 (); + virtual CTree *valid_id_expr (); + virtual CTree *postfix_expr1 (); + virtual CTree *postfix_expr2 (); + virtual CTree *pseudo_dtor_name (); + virtual CTree *simple_type_spec (); + virtual CTree *direct_new_declarator (); + virtual CTree *class_spec_err (); + virtual CTree *member_decl1 (); + virtual CTree *member_declarator_err (); + virtual void declarator_id (bool); + virtual CTree *finish_init_declarator (); + virtual CTree *obj_decl (CTree *); + virtual bool implicit_int (); + + // constant expression evaluation + virtual CTree *init_declarator (); + virtual CTree *const_expr (); + virtual CTree *enumerator_def (); + virtual CTree *pure_spec (); + virtual CTree *const_init (); + virtual CTree *template_param (); + + // add scope information to tree nodes + virtual CTree *class_spec (); + virtual CTree *ctor_init (); + virtual CTree *handler (); + virtual CTree *exception_spec (); + + // namespaces + virtual CTree *introduce_orig_ns (); + virtual CTree *introduce_ns_extension (); + virtual CTree *introduce_unnamed_ns (); + virtual CTree *introduce_ns_alias (); + virtual CTree *namespace_def (); + virtual CTree *original_ns_name (); + virtual CTree *namespace_alias (); + virtual CTree *using_directive (); + virtual CTree *using_decl (); + virtual CTree *access_decl (CTree* = 0); + + // templates + virtual CTree *introduce_type_param (); + virtual CTree *introduce_non_type_param (); + virtual CTree *introduce_template_instance (); + virtual CTree *template_param_list (); + virtual CTree *template_decl (); + virtual CTree *template_name (bool class_only = false); + virtual CTree *template_key (); + virtual CTree *explicit_instantiation (); + virtual CTree *explicit_specialization (); + + // introduce names... add new entries to the class database + virtual CTree *introduce_enum (); + virtual CTree *introduce_enumerator (); + virtual CTree *introduce_object (CTree* = 0); + virtual CTree *introduce_named_type (); + virtual CTree *introduce_function (); + virtual CTree *introduce_parameter (); + virtual CTree *introduce_class (); + virtual CTree *introduce_member (); + virtual CTree *introduce_tag (); + virtual CTree *introduce_exception (); + +public: // syntactic scope information + void enter_param_decl_clause (); + void enter_template_param_list (Syntax::State); + void enter_base_spec (); + void enter_class_def (); + void enter_template_decl (); + void enter_member_access (MemberAccessOperator); + void enter_postfix_expr (); + void enter_exception_spec (); + void enter_template_arg_list (Syntax::State); + void enter_conv_type_id (); + void enter_entity_name (bool v = true); + void enter_nested_name (); + bool enter_expr (); + void enter_extern_decl (bool block_decl); + + void leave_param_decl_clause (); + void leave_template_param_list (); + void leave_base_spec (); + void leave_class_def (bool reject = false); + void leave_member_access (); + void leave_postfix_expr (); + void leave_exception_spec (); + void leave_template_arg_list (); + void leave_conv_type_id (); + void leave_entity_name (); + void leave_nested_name (); + bool leave_expr (); + void leave_extern_decl (); + + bool in_base_spec () const; + bool in_class_def () const; + bool in_conv_type_id () const; + bool in_nested_name () const; + bool in_expr () const; + bool in_extern_decl () const; + bool is_entity_name () const; + Syntax::State in_template_param_list () const; + Syntax::State in_template_arg_list () const; + virtual CProtection::Type protection () const; + + bool non_project_loc (); + bool non_primary_loc (); + bool skip_tpl_fct_bodies () const; + bool reset_search_scope (bool = false); + CStructure *array_delim (CStructure * = 0); + CStructure *conv_fct_id (CStructure * = 0); + CTree *postfix_expr (); + +public: // class definition parsing + virtual void parse_delayed (bool (CCSyntax::*)(), CTree *); + virtual CTree *add_base_classes (); + +protected: + CTree* createDelayedParse (bool (CCSyntax::*)(), CTree *); + void parseDelayed (); + void instantiateDelayed (CT_DelayedParse*, CTree*); + + void enter_scope (CStructure *); + void deleteContainer (int); + void setQualName (CObjectInfo *, CObjectInfo *) const; + CStructure *getQualifiedScope (CStructure *scope) const; + + CTypeInfo *resolveExpr (CTree *, CTree * = (CTree*)0) const; + void calculateAddress (CTree *) const; + + CObjectInfo *getLastResolvedName (CT_SimpleName *) const; + CStructure *getNameScope (CT_SimpleName *, bool = true) const; + CStructure *getScope (CObjectInfo *obj) const; + CStructure *getFriendScope (bool skip_tpl_scope = false) const; + CStructure *getNonTplScope (bool consider_instance_scope = false) const; + CClassInfo *getOutermostIncompleteParsedRecord (); + Token* getCloseCurly (); + + void qualifiedScopeName (CT_SimpleName *, std::ostringstream &) const; + bool isQualName (CT_SimpleName *) const; + bool realTypedef (CObjectInfo *) const; + bool equalType (CTypeInfo *, CTypeInfo *, bool = true) const; + void lookupName (const Token*, CStructure *, bool); + bool isClassOrEnum (CObjectInfo *) const; + + bool inTemplateDecl (CScopeInfo* scope) const; + void introduceTemplate (CObjectInfo *, CTemplateInfo *, bool is_friend = false); + void setTemplateScope (CCNameLookup &, CObjectInfo *, CTypeInfo *, CTemplateInfo *, bool); + bool isSpecialization (CTree *) const; + void setSpecializationName (CTree *, CTemplateInfo *) const; + bool matchArguments (CT_TemplateName *n1, CT_TemplateName *n2) const; + + CLinkage::Type determine_linkage (CSemDeclSpecs *, SemObjType, + CObjectInfo * = (CObjectInfo*)0) const; + CStorage::Type determine_storage_class (CSemDeclSpecs *) const; + void setLanguage (CObjectInfo *) const; + void setProtection (CObjectInfo *) const; + void linkFctDecls (CCNameLookup &, CObjectInfo *) const; + void linkCtorDecls (CObjectInfo *) const; + void addImplicitThisObject (CFunctionInfo *, CTypeInfo *, CTree *); + + void declareNamespaceStd (); + void declareImplicitFcts (); + void declareSpecialMembers (); + CFunctionInfo *createMethod (const char *, CRecord *, CTypeInfo *); + bool isRefToClass (CTypeInfo *, CRecord *) const; + + bool isBaseClass (CClassInfo *, CClassInfo *) const; + void addBaseClasses (CClassInfo *, CT_ClassDef *); + void addBaseClass (CClassInfo *, CT_BaseSpec *); + + virtual bool check_function_lookup (CCNameLookup &, CStructure *, + CSemDeclSpecs *, CCSemDeclarator &, CTree *, bool); + virtual bool check_member_lookup (CCNameLookup &, CStructure *, + CSemDeclSpecs *, CCSemDeclarator &, CTree *, bool &, bool); + virtual bool check_object_lookup (CCNameLookup &, CStructure *, + CSemDeclSpecs *, CCSemDeclarator &, CTree *, bool &, CObjectInfo *&); +}; + +inline CCBuilder &CCSemantic::builder () const + { return (CCBuilder&) CSemantic::builder (); } +inline CCSyntax &CCSemantic::syntax () const + { return (CCSyntax&) _syntax; } + +inline bool CCSemantic::in_class_def () const + { return _outermost_class_def; } + +inline bool CCSemantic::in_base_spec () const + { return _in_base_spec.top (); } +inline void CCSemantic::enter_base_spec () + { _in_base_spec.push (true); } +inline void CCSemantic::leave_base_spec () + { _in_base_spec.pop (); } + +inline bool CCSemantic::in_nested_name () const + { return _in_nested_name.top (); } +inline void CCSemantic::enter_nested_name () + { _in_nested_name.push (true); dep_nested_name = false; } +inline void CCSemantic::leave_nested_name () + { _in_nested_name.pop (); } + +inline bool CCSemantic::in_conv_type_id () const + { return _in_conv_type_id.top (); } +inline void CCSemantic::enter_conv_type_id () + { _in_conv_type_id.push (true); } +inline void CCSemantic::leave_conv_type_id () + { _in_conv_type_id.pop (); } + +inline bool CCSemantic::in_expr () const + { return _in_expr.top (); } +inline bool CCSemantic::enter_expr () + { _in_expr.push (true); return true; } +inline bool CCSemantic::leave_expr () + { _in_expr.pop (); return true; } + +inline void CCSemantic::enter_member_access (MemberAccessOperator mao) + { _in_memb_access_expr.push (mao); } +inline void CCSemantic::leave_member_access () + { _in_memb_access_expr.pop (); } +inline void CCSemantic::enter_postfix_expr () + { _postfix_expr.push (0); _in_memb_access_expr.push (MAO_NONE); } +inline void CCSemantic::leave_postfix_expr () + { _postfix_expr.pop (); _in_memb_access_expr.pop (); } + +inline void CCSemantic::setProtection (CObjectInfo *info) const + { info->Protection (_protection.top ()); } +inline CProtection::Type CCSemantic::protection () const + { return _protection.top (); } + +inline void CCSemantic::enter_template_arg_list (Syntax::State state) + { _in_template_arg_list.push (state); enter_postfix_expr (); } +inline void CCSemantic::leave_template_arg_list () + { _in_template_arg_list.pop (); leave_postfix_expr (); } +inline Syntax::State CCSemantic::in_template_arg_list () const + { return _in_template_arg_list.top (); } +inline void CCSemantic::leave_template_param_list () + { _in_template_param_list.pop (); } +inline Syntax::State CCSemantic::in_template_param_list () const + { return _in_template_param_list.top (); } + +inline void CCSemantic::enter_entity_name (bool v) + { parsing_entity_name.push (v); } +inline void CCSemantic::leave_entity_name () + { parsing_entity_name.pop (); } +inline bool CCSemantic::is_entity_name () const + { return parsing_entity_name.top (); } + +inline void CCSemantic::leave_extern_decl () + { if (_in_extern_decl.top ()) delete[] _in_extern_decl.top (); _in_extern_decl.pop (); } +inline bool CCSemantic::in_extern_decl () const + { return _in_extern_decl.top (); } + +inline CCInstantiation* CCSemantic::Instantiation() const + { return tpl_inst; } + + +} // namespace Puma + +#endif /* __CCSemantic_h__ */ diff --git a/Puma/src/parser/ccparser/CCSyntax.cc b/Puma/src/parser/ccparser/CCSyntax.cc new file mode 100644 index 0000000..b3f1ec1 --- /dev/null +++ b/Puma/src/parser/ccparser/CCSyntax.cc @@ -0,0 +1,2475 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CCSyntax.h" +#include "Puma/CCSemantic.h" +#include "Puma/CCBuilder.h" +#include "Puma/CTokens.h" +#include "Puma/CTree.h" + +namespace Puma { + + +CCSyntax::CCSyntax (CCBuilder &b, CCSemantic &s) : + CSyntax (b, s), _skip_bodies (SKIP_BODIES_NONE) { +} + +CCBuilder &CCSyntax::builder () const { + return (CCBuilder&)Syntax::builder (); +} + +CCSemantic &CCSyntax::semantic () const { + return (CCSemantic&)Syntax::semantic (); +} + +void CCSyntax::configure (Config &config) { + // configure the C syntax + CSyntax::configure (config); + + // configure C++ syntax options + if (config.Option ("--pseudo-instances")) + _skip_bodies |= SKIP_BODIES_TPL; + if (config.Option ("--skip-bodies-all")) + _skip_bodies |= SKIP_BODIES_ALL; + else if (config.Option ("--skip-bodies-tpl")) + _skip_bodies |= SKIP_BODIES_TPL; + else if (config.Option ("--skip-bodies-non-prj")) + _skip_bodies |= SKIP_BODIES_NON_PRJ; + else if (config.Option ("--skip-bodies-non-prim")) + _skip_bodies |= SKIP_BODIES_NON_PRIM; +} + +void CCSyntax::init_prim_types () { + _prim_types.set (TOK_BOOL); + _prim_types.set (TOK_CHAR); + _prim_types.set (TOK_SHORT); + _prim_types.set (TOK_INT); + _prim_types.set (TOK_LONG); + _prim_types.set (TOK_SIGNED); + _prim_types.set (TOK_UNSIGNED); + _prim_types.set (TOK_FLOAT); + _prim_types.set (TOK_DOUBLE); + _prim_types.set (TOK_WCHAR_T); + _prim_types.set (TOK_VOID); + _prim_types.set (TOK_UNKNOWN_T); +} + +void CCSyntax::init_cv_quals () { + // CSyntax::init_cv_quals is not called, because TOK_RESTRICT is not wanted! + _cv_quals.set (TOK_CONST); + _cv_quals.set (TOK_VOLATILE); +} + + +void CCSyntax::get_search_scope (SearchScope &sc) { + sc.scope = semantic ().search_scope; + sc.last_scope = semantic ().last_search_scope; + sc.dep = semantic ().dep_nested_name; +} + +void CCSyntax::set_search_scope (SearchScope &sc) { + semantic ().search_scope = sc.scope; + semantic ().last_search_scope = sc.last_scope; + semantic ().dep_nested_name = sc.dep; +} + +void CCSyntax::skip_fct_try_block () { + static int stop[] = { TOK_OPEN_ROUND, 0 }; + skip_ctor_init (); + skip_fct_body (); + + // skip handler sequence + while (look_ahead (TOK_CATCH)) { + skip (stop, false); // CATCH + skip_round_block (); // (...) + skip_curly_block (); // {...} + } +} + +void CCSyntax::skip_ctor_init () { + static int stop_tokens[] = { TOK_OPEN_CURLY, 0 }; + skip (stop_tokens, false); +} + +void CCSyntax::skip_fct_body () { + skip_curly_block (); +} + +void CCSyntax::skip_param_init () { + static int stop_tokens[] = { TOK_COMMA, TOK_CLOSE_ROUND, TOK_ELLIPSIS, 0 }; + skip (stop_tokens, false); +} + +void CCSyntax::skip_const_expr () { + static int stop_tokens[] = { TOK_COMMA, TOK_SEMI_COLON, 0 }; + skip (stop_tokens, false); +} + +void CCSyntax::skip_const_init () { + static int stop_tokens[] = { TOK_COMMA, TOK_SEMI_COLON, 0 }; + skip (stop_tokens, false); +} + +bool CCSyntax::is_fct_def () { + State s = token_provider->get_state (); + bool result = false, braces = false, stop = false; + Token *current; + int token; + + while (!stop && (current = token_provider->current ())) { + token = current->type (); + + // function body + if (braces && (token == TOK_OPEN_CURLY || token == TOK_COLON)) { + result = true; + break; + } else if (!braces && token == TOK_ASSIGN) { + break; + // class definition in function return type + } else if (!braces && token == TOK_OPEN_CURLY) { + skip_curly_block (); + } else switch (token) { + // only declaration + case TOK_SEMI_COLON: + case TOK_COMMA: + case TOK_TYPEDEF: + // TODO: checking the AspectC++ tokens here is really bad style + case TOK_ADVICE: + case TOK_POINTCUT: + case TOK_SLICE: + stop = true; + break; + // operator name + case TOK_OPERATOR: + skip (TOK_OPEN_ROUND, false); + break; + // function `try' block, function body.. + case TOK_TRY: + result = true; + stop = true; + break; + // array delimiter + case TOK_OPEN_SQUARE: + skip_block (TOK_OPEN_SQUARE, TOK_CLOSE_SQUARE); + break; + // template-id + case TOK_LESS: + skip_block (TOK_LESS, TOK_GREATER); + break; + // function parameter list + case TOK_OPEN_ROUND: + skip_round_block (); + braces = true; + break; + // throw expression + case TOK_THROW: + skip (); + skip_round_block (); + break; + // asm declaration specifier + case TOK_ASM: + skip (); + skip_round_block (); + break; + // names etc. + default: + skip (); + break; + } + } + + token_provider->set_state (s); + return result; +} + +bool CCSyntax::is_nested (State first) { + int token, braces, curlies, squares; + Token *current; + + if (! first) + return false; + + State s = token_provider->get_state (); + token_provider->set_state (first); + + braces = curlies = squares = 0; + while ((current = token_provider->current ())) { + token = current->type (); + + switch (token) { + case TOK_OPEN_ROUND: braces++; break; + case TOK_CLOSE_ROUND: braces--; break; + case TOK_OPEN_CURLY: curlies++; break; + case TOK_CLOSE_CURLY: curlies--; break; + case TOK_OPEN_SQUARE: squares++; break; + case TOK_CLOSE_SQUARE: squares--; break; + default: break; + } + + if (token_provider->get_state () == s) + break; + + skip (); + } + + token_provider->set_state (s); + return (braces + curlies + squares) > 0; +} + +bool CCSyntax::is_nested_name () { + // result cache! + static Token *last_token = 0; + static bool last_result = false; + + State s = token_provider->get_state (); + Token *current = token_provider->current (); + if (! current) { + token_provider->set_state (s); + return false; + } + + // return the last result if we check the same token + if (last_token == current) + return last_result; + + last_token = current; + last_result = false; + int token, depth = 0; + + // keyword `template'? + if (current->type () == TOK_TEMPLATE) + skip (); + + // identifier? + current = token_provider->current (); + if (current && current->type () == TOK_ID) { + skip (); + + // template id? + if (token_provider->current () && + token_provider->current ()->type () == TOK_LESS) { + skip (); + + bool stop = false; + while (!stop && (current = token_provider->current ())) { + token = current->type (); + + switch (token) { + case TOK_SEMI_COLON: + case TOK_CLOSE_ROUND: + case TOK_CLOSE_SQUARE: + case TOK_CLOSE_CURLY: + stop = true; + break; + case TOK_OPEN_ROUND: + skip_round_block (); + continue; + case TOK_OPEN_CURLY: + skip_curly_block (); + continue; + case TOK_OPEN_SQUARE: + skip_block (TOK_OPEN_SQUARE, TOK_CLOSE_SQUARE); + continue; + case TOK_LESS: + depth++; + break; + case TOK_GREATER: + if (depth == 0) { + skip (); + stop = true; + } else { + depth--; + } + default: + break; + } + + if (!stop) + skip (); + } + } + + // scope operator => nested name + if (token_provider->current () && + token_provider->current ()->type () == TOK_COLON_COLON) + last_result = true; + } + + token_provider->set_state (s); + return last_result; +} + +bool CCSyntax::is_class_def () { + // result cache! + static Token *last_token = 0; + static bool last_result = false; + + State s = token_provider->get_state (); + Token *current = token_provider->current (); + if (! current) { + token_provider->set_state (s); + return false; + } + + // return the last result if we check the same token + if (last_token == current) + return last_result; + + last_token = current; + last_result = false; + int token; + + bool stop = false; + while (!stop && (current = token_provider->current ())) { + token = current->type (); + + switch (token) { + case TOK_SEMI_COLON: + stop = true; + break; + case TOK_OPEN_CURLY: + last_result = true; + stop = true; + break; + case TOK_OPEN_ROUND: + skip_round_block (); + continue; + case TOK_OPEN_SQUARE: + skip_block (TOK_OPEN_SQUARE, TOK_CLOSE_SQUARE); + continue; + default: + break; + } + + if (!stop) + skip (); + } + + token_provider->set_state (s); + return last_result; +} + +bool CCSyntax::is_tpl_id () { + int token, depth = 0, roundDepth = 0, curlyDepth = 0, squareDepth = 0; + State s = token_provider->get_state (); + Token *current; + + while ((current = token_provider->current ())) { + token = current->type (); + + switch (token) { + case TOK_LESS: depth++; break; + case TOK_GREATER: depth--; break; + case TOK_OPEN_ROUND: roundDepth++; break; + case TOK_CLOSE_ROUND: roundDepth--; break; + case TOK_OPEN_CURLY: curlyDepth++; break; + case TOK_CLOSE_CURLY: curlyDepth--; break; + case TOK_OPEN_SQUARE: squareDepth++; break; + case TOK_CLOSE_SQUARE: squareDepth--; break; + default: break; + } + + if ((depth == 0 || roundDepth < 0 || squareDepth < 0 || curlyDepth < 0) || + (token == TOK_SEMI_COLON && curlyDepth == 0)) { + break; + } + + skip (); + } + + token_provider->set_state (s); + return depth == 0; +} + +// find out if a qualified name is a template declarator id +// rather than a declaration specifier, this is used to +// decide when to instantiate a template id +bool CCSyntax::is_tpl_declarator_id () { + // doesn't matter in parameter declaration + if (semantic().in_param_decl_clause() || + semantic().in_template_param_list()) { + return false; + } + + // hack: This is save here (and not later), because an aspect might + // skip tokens while executing token_provider->current(). + State s = token_provider->get_state (); + + // only consider names + if (! token_provider->current () || + token_provider->current ()->type() != TOK_ID) { + token_provider->set_state (s); // see comment above + return false; + } + + bool result = false, tpl_id = false; + + while (token_provider->current ()) { + int token = token_provider->current ()->type (); + + // match names only + if (token != TOK_ID) { + // operator name is a declarator id + result = (token == TOK_OPERATOR); + break; + } + // skip name + skip(); + + // skip template ids + if (token_provider->current () && + token_provider->current ()->type () == TOK_LESS && + is_tpl_id ()) { + tpl_id = true; + skip_block (TOK_LESS, TOK_GREATER); + } + + // nested name, go on to next name part + if (token_provider->current () && + token_provider->current ()->type () == TOK_COLON_COLON) { + skip(); + continue; + } + + // not a nested name, now check for declarator id + token = token_provider->current () ? token_provider->current ()->type () : 0; + if (token == TOK_OPEN_ROUND) { + if (is_ptr_to_fct ()) { + // pointer to function or reference to function + break; + } else { + skip_round_block (); + } + token = token_provider->current () ? token_provider->current ()->type () : 0; + // not a function or array pointer decl? + result = (token != TOK_OPEN_ROUND && token != TOK_OPEN_SQUARE); + } else { + result = (token == TOK_ASSIGN || token == TOK_SEMI_COLON || token == TOK_OPEN_SQUARE); + } + break; + } + + token_provider->set_state (s); + return tpl_id && result; +} + +bool CCSyntax::is_ptr_to_fct () { + State s = token_provider->get_state (); + bool result = false; + + // skip all open parentheses + while (token_provider->current () && token_provider->current ()->type () == TOK_OPEN_ROUND) { + skip(); + } + + if (token_provider->current ()) { + // expect * or & + result = token_provider->current ()->type () == TOK_MUL || + token_provider->current ()->type () == TOK_AND; + } + + token_provider->set_state (s); + return result; +} + +bool CCSyntax::is_ass_expr () { + State s = token_provider->get_state (); + Token *current = token_provider->current (); + if (! current) { + token_provider->set_state (s); + return false; + } + + // return the last result if we check the same token + if (last_look_ahead_token == current) + return last_look_ahead_result; + + last_look_ahead_token = current; + last_look_ahead_result = false; + + int token; + bool id_found = false; + + bool stop = false; + while (!stop && (current = token_provider->current ())) { + token = current->type (); + + if (token == TOK_ID) { + id_found = true; + skip (); + continue; + } + + if (id_found && token == TOK_LESS) { + // skip_block (TOK_LESS, TOK_GREATER); + last_look_ahead_result = true; + stop = true; + break; + } else switch (token) { + case TOK_SEMI_COLON: + case TOK_COMMA: + case TOK_CLOSE_CURLY: + case TOK_CLOSE_ROUND: + case TOK_CLOSE_SQUARE: + case TOK_COLON: + case TOK_QUESTION: + case TOK_WHILE: + case TOK_DO: + case TOK_FOR: + case TOK_IF: + case TOK_ELSE: + case TOK_SWITCH: + case TOK_CASE: + stop = true; + break; + case TOK_OPEN_CURLY: + skip_curly_block (); + break; + case TOK_OPEN_ROUND: + skip_round_block (); + break; + case TOK_OPEN_SQUARE: + skip_block (TOK_OPEN_SQUARE, TOK_CLOSE_SQUARE); + break; + case TOK_ASSIGN: + case TOK_MUL_EQ: + case TOK_DIV_EQ: + case TOK_MOD_EQ: + case TOK_ADD_EQ: + case TOK_SUB_EQ: + case TOK_RSH_EQ: + case TOK_LSH_EQ: + case TOK_AND_EQ: + case TOK_XOR_EQ: + case TOK_IOR_EQ: + last_look_ahead_result = true; + stop = true; + break; + default: + skip (); + break; + } + + if (!stop) + id_found = false; + } + + token_provider->set_state (s); + return last_look_ahead_result; +} + +/*****************************************************************************/ +/* */ +/* C + + G r a m m a r */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* This grammar is derived from: */ +/* */ +/* International Standard */ +/* ISO/IEC 9899-1999(E) */ +/* Second edition 1999-04-01 */ +/* Programming languages - C */ +/* */ +/* and */ +/* */ +/* International Standard */ +/* ISO/IEC 14882:1998(E) */ +/* First edition 1998-09-01 */ +/* Programming languages - C++ */ +/* */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* */ +/* A . 1 K e y w o r d s */ +/* */ +/*****************************************************************************/ + +bool CCSyntax::ClassName::parse (CCSyntax &s) { + // 1: template_id + // 1: ID + return s.template_id () || s.parse (TOK_ID); // TODO: should be TemplateId::check(s) +} +bool CCSyntax::class_name () { return ClassName::parse (*this); } + +bool CCSyntax::EnumName::parse (CCSyntax &s) { + // 1: ID + return s.parse (TOK_ID); +} +bool CCSyntax::enum_name () { return EnumName::parse (*this); } + +bool CCSyntax::TemplateName::parse (CCSyntax &s) { + // 1: ID + return s.parse (TOK_ID); +} +bool CCSyntax::template_name () { return TemplateName::parse (*this); } + +bool CCSyntax::ClassTemplateName::parse (CCSyntax &s) { + // 1: ID + return s.parse (TOK_ID); +} +bool CCSyntax::class_template_name () { return ClassTemplateName::parse (*this); } + +bool CCSyntax::NamespaceName::parse (CCSyntax &s) { + // 1: original_ns_name + // 1: namespace_alias + return (OriginalNsName::check (s) || NamespaceAlias::check (s)); +} +bool CCSyntax::namespace_name () { return NamespaceName::parse (*this); } + +bool CCSyntax::OriginalNsName::parse (CCSyntax &s) { + // 1: ID + return s.parse (TOK_ID); +} +bool CCSyntax::original_ns_name () { return OriginalNsName::parse (*this); } + +bool CCSyntax::NamespaceAlias::parse (CCSyntax &s) { + // 1: ID + return s.parse (TOK_ID); +} +bool CCSyntax::namespace_alias () { return NamespaceAlias::parse (*this); } + +/*****************************************************************************/ +/* */ +/* A . 2 L e x i c a l c o n v e n t i o n s */ +/* */ +/*****************************************************************************/ + +bool CCSyntax::Literal::parse (CCSyntax &s) { + // 1: cmpd_str + // 1: TOK_INT_VAL (e.g. 4711) + // 1: TOK_ZERO_VAL (0) + // 1: TOK_CHAR_VAL (e.g. 'x') + // 1: TOK_FLT_VAL (e.g. 3.14) + // 1: TOK_BOOL_VAL (e.g. true) + return CSyntax::Literal::parse (s) || s.parse (TOK_BOOL_VAL); +} +bool CCSyntax::literal () { return Literal::parse (*this); } + +/*****************************************************************************/ +/* */ +/* A . 4 E x p r e s s i o n s */ +/* */ +/*****************************************************************************/ + +bool CCSyntax::PrimExpr::parse (CCSyntax &s) { + // 1: literal + // 1: THIS + // 1: id_expr + // 3: ( expr ) + return (s.parse (TOK_THIS) || + CSyntax::PrimExpr::parse (s)); +} +bool CCSyntax::prim_expr () { return PrimExpr::parse (*this); } + +bool CCSyntax::IdExpr::parse (CCSyntax &s) { + // 1: qual_id + // 1: unqual_id + return (QualId::check (s) || + UnqualId::check (s)); +} +bool CCSyntax::id_expr () { return IdExpr::parse (*this); } + +bool CCSyntax::QualId::parse (CCSyntax &s) { + // 2: colon_colon identifier + // 2: colon_colon oper_fct_id + // 2: colon_colon template_id + // 2: nested_name_spec unqual_id + // 3: nested_name_spec template_key unqual_id + // 3: colon_colon nested_name_spec unqual_id + // 4: colon_colon nested_name_spec template_key unqual_id + bool root = ColonColon::check (s); + bool nested = NestedNameSpec::check (s); + bool ok = (nested ? + (s.template_key (), + UnqualId::check (s)) : + (root && + (s.template_id () || + Identifier::check (s) || + s.oper_fct_id ()))); + if (root || nested) // TODO: move this into an aspect + s.semantic ().reset_search_scope (); + return ok; +} +bool CCSyntax::qual_id () { return QualId::parse (*this); } + +bool CCSyntax::UnqualId::parse (CCSyntax &s) { + // 1: identifier + // 1: oper_fct_id + // 1: conv_fct_id + // 1: template_id + // 2: ~ class_name + return (s.template_id () || + Identifier::check (s) || + s.oper_fct_id () || + ConvFctId::check (s) || + (s.parse (TOK_TILDE) && ClassName::check (s))); +} +bool CCSyntax::unqual_id () { return UnqualId::parse (*this); } + +bool CCSyntax::ColonColon::parse (CCSyntax &s) { + // 1: :: + return s.parse (TOK_COLON_COLON); +} +bool CCSyntax::colon_colon () { return ColonColon::parse (*this); } + +bool CCSyntax::NestedNameSpec::parse (CCSyntax &s) { + // 1+: nested_name_spec1.. + return seq (s); +} +bool CCSyntax::nested_name_spec () { return NestedNameSpec::parse (*this); } + +bool CCSyntax::NestedNameSpec1::parse (CCSyntax &s) { + // 2: class_or_ns_name :: + // 3: template_key class_or_ns_name :: + return ((s.template_key (), ClassOrNsName::check (s)) && s.parse (TOK_COLON_COLON)); +} +bool CCSyntax::nested_name_spec1 () { return NestedNameSpec1::parse (*this); } + +bool CCSyntax::ClassOrNsName::parse (CCSyntax &s) { + // 1: class_name + // 1: namespace_name + return (ClassName::check (s) || NamespaceName::check (s)); +} +bool CCSyntax::class_or_ns_name () { return ClassOrNsName::parse (*this); } + +bool CCSyntax::PostfixExpr::parse (CCSyntax &s) { + // 1 : postfix_expr2 + // 1+: postfix_expr2 postfix_expr1.. + if (! PostfixExpr2::check (s)) + return false; + + // TODO: be careful! don't use seq here. There is call advice. + while (PostfixExpr1::check (s)); + return true; +} +bool CCSyntax::postfix_expr () { return PostfixExpr::parse (*this); } + +bool CCSyntax::PostfixExpr2::parse (CCSyntax &s) { + // 1 : cmpd_literal + // 1 : prim_expr + // 1 : construct_expr + // 4 : TYPEID ( expr ) + // 4 : TYPEID ( type_id ) + // 7 : CONST_CAST < type_id > ( expr ) + // 7 : REINT_CAST < type_id > ( expr ) + // 7 : STATIC_CAST < type_id > ( expr ) + // 7 : DYNAMIC_CAST < type_id > ( expr ) + static int any_new_cast[] = { TOK_DYN_CAST, TOK_REINT_CAST, + TOK_STAT_CAST, TOK_CONST_CAST, 0 }; + // new-style casts + if (s.parse (any_new_cast)) { + return (s.parse (TOK_LESS) && s.type_id () && + s.parse (TOK_GREATER) && + s.parse (TOK_OPEN_ROUND) && Expr::check (s) && + s.parse (TOK_CLOSE_ROUND)); + } + // construct expression, compound literal, member access expression + else if (ConstructExpr::check (s) || CmpdLiteral::check (s) || PrimExpr::check (s)) { + return true; + } + // typeid (RTTI) + else if (s.parse (TOK_TYPEID)) { + return (s.parse (TOK_OPEN_ROUND) && + (Expr::check (s) || s.type_id ()) && + s.parse (TOK_CLOSE_ROUND)); + } + return false; +} +bool CCSyntax::postfix_expr2() { return PostfixExpr2::parse (*this); } + +bool CCSyntax::ConstructExpr::parse (CCSyntax &s) { + // 3 : simple_type_spec ( ) + // 4 : simple_type_spec ( expr_list ) + // 5 : TYPENAME nested_name_spec identifier ( ) + // 5 : TYPENAME nested_name_spec template_id ( ) + // 6 : TYPENAME nested_name_spec identifier ( expr_list ) + // 6 : TYPENAME nested_name_spec template_id ( expr_list ) + // 6 : TYPENAME nested_name_spec template_key template_id ( ) + // 6 : TYPENAME :: nested_name_spec identifier ( ) + // 6 : TYPENAME :: nested_name_spec template_id ( ) + // 7 : TYPENAME nested_name_spec template_key template_id ( expr_list ) + // 7 : TYPENAME :: nested_name_spec identifier ( expr_list ) + // 7 : TYPENAME :: nested_name_spec template_id ( expr_list ) + // 7 : TYPENAME :: nested_name_spec template_key template_id ( ) + // 8 : TYPENAME :: nested_name_spec template_key template_id ( expr_list ) + if (s.parse (TOK_TYPENAME)) { + return (s.parse (TOK_COLON_COLON), NestedNameSpec::check (s) && + (s.template_key () ? s.template_id () : + s.template_id () || Identifier::check (s)) && + s.semantic ().reset_search_scope () && // TODO: remove sem stuff here + s.parse (TOK_OPEN_ROUND) && + (ExprList::check (s), s.parse (TOK_CLOSE_ROUND))); + } + return (s.simple_type_spec () && s.parse (TOK_OPEN_ROUND) && + (ExprList::check (s), s.parse (TOK_CLOSE_ROUND))); +} +bool CCSyntax::construct_expr() { return ConstructExpr::parse (*this); } + +bool CCSyntax::PostfixExpr1::parse (CCSyntax &s) { + // 1: -- + // 1: ++ + // 2: . id_expr + // 2: -> id_expr + // 2: . pseudo_dtor_name + // 2: -> pseudo_dtor_name + // 2: ( ) + // 3: . template_key id_expr + // 3: -> template_key id_expr + // 3: ( expr_list ) + // 3: [ expr ] + return + (s.parse (TOK_OPEN_ROUND) ? + (ExprList::check (s), s.parse (TOK_CLOSE_ROUND)) : + s.parse (TOK_OPEN_SQUARE) ? + (Expr::check (s) && s.parse (TOK_CLOSE_SQUARE)) : + (s.parse (TOK_DECR) || s.parse (TOK_INCR) || + ((s.parse (TOK_DOT) || s.parse (TOK_PTS)) && + (PseudoDtorName::check (s) || + (s.template_key (), IdExpr::check (s)))))); +} +bool CCSyntax::postfix_expr1() { return PostfixExpr1::parse (*this); } + +bool CCSyntax::PseudoDtorName::parse (CCSyntax &s) { + // 2: ~ type_name + // 3: :: ~ type_name + // 3: nested_name_spec ~ type_name + // 4: :: nested_name_spec ~ type_name + // 4: type_name :: ~ type_name + // 5: :: type_name :: ~ type_name + // 5: nested_name_spec type_name :: ~ type_name + // 6: :: nested_name_spec type_name :: ~ type_name + // 6: nested_name_spec template_key template_id :: ~ type_name + // 7: :: nested_name_spec template_key template_id :: ~ type_name + bool ok = ((ColonColon::check (s), NestedNameSpec::check (s), + (s.template_key () ? s.template_id () : TypeName::check (s))) && + ! s.parse (TOK_COLON_COLON)); + s.semantic ().reset_search_scope (); // TODO: remove sem stuff here + if (! ok) + return false; + return (s.parse (TOK_TILDE) && TypeName::check (s)); +} +bool CCSyntax::pseudo_dtor_name() { return PseudoDtorName::parse (*this); } + +bool CCSyntax::UnaryExpr::parse (CCSyntax &s) { + // 1: new_expr + // 1: delete_expr + // 1: postfix_expr + // 1: offsetof_expr + // 1: typetrait_expr + // 2: any_unary_op cast_expr + // 2: SIZEOF unary_expr + // 2: ALIGNOF unary_expr + // 4: SIZEOF unary_expr1 + // 4: ALIGNOF unary_expr1 + static int any_unary_op[] = { TOK_AND, TOK_MUL, TOK_PLUS, TOK_MINUS, + TOK_TILDE, TOK_NOT, TOK_DECR, TOK_INCR, 0 }; + return (s.parse (any_unary_op) ? + CastExpr::check (s) : + (s.parse (TOK_SIZEOF) || s.parse (TOK_ALIGNOF)) ? + (UnaryExpr1::check (s) || UnaryExpr::check (s)) : + (NewExpr::check (s) || + DeleteExpr::check (s) || + OffsetofExpr::check (s) || + TypeTraitExpr::check (s) || + PostfixExpr::check (s))); +} +bool CCSyntax::unary_expr () { return UnaryExpr::parse (*this); } + +bool CCSyntax::TypeTraitExpr::parse (CCSyntax &s) { + // 4: any_unary_type_trait_op ( type_id ) + // 6: any_binary_type_trait_op ( type_id , type_id ) + static int any_unary_type_trait_op[] = { + TOK_HAS_NOTHROW_ASSIGN, TOK_HAS_NOTHROW_COPY, TOK_HAS_NOTHROW_CTOR, + TOK_HAS_TRIVIAL_ASSIGN, TOK_HAS_TRIVIAL_COPY, TOK_HAS_TRIVIAL_CTOR, + TOK_HAS_TRIVIAL_DTOR, TOK_HAS_VIRTUAL_DTOR, TOK_IS_ABSTRACT, + TOK_IS_CLASS, TOK_IS_EMPTY, TOK_IS_ENUM, TOK_IS_POD, TOK_IS_TRIVIAL, + TOK_IS_POLYMORPHIC, TOK_IS_UNION, 0 }; + static int any_binary_type_trait_op[] = { + TOK_IS_BASE_OF, 0 }; + return (s.parse (any_unary_type_trait_op) ? + s.parse (TOK_OPEN_ROUND) && + s.type_id () && + s.parse (TOK_CLOSE_ROUND) : + s.parse (any_binary_type_trait_op) && + s.parse (TOK_OPEN_ROUND) && + s.type_id () && + s.parse (TOK_COMMA) && + s.type_id () && + s.parse (TOK_CLOSE_ROUND)); +} +bool CCSyntax::type_trait_expr () { return TypeTraitExpr::parse (*this); } + +bool CCSyntax::NewExpr::parse (CCSyntax &s) { + // 2: NEW new_type_id + // 3: NEW new_type_id new_init + // 3: NEW new_placement new_type_id + // 3: :: NEW new_type_id + // 4: :: NEW new_type_id new_init + // 4: :: NEW new_placement new_type_id + // 4: NEW new_placement new_type_id new_init + // 4: NEW ( type_id ) + // 5: NEW ( type_id ) new_init + // 5: NEW new_placement ( type_id ) + // 5: :: NEW new_placement new_type_id new_init + // 5: :: NEW ( type_id ) + // 6: :: NEW ( type_id ) new_init + // 6: NEW new_placement ( type_id ) new_init + // 6: :: NEW new_placement ( type_id ) + // 7: :: NEW new_placement ( type_id ) new_init + return ((s.parse (TOK_COLON_COLON), s.parse (TOK_NEW)) && + s.opt (NewPlacement::check (s)) && + (NewTypeId::check (s) || + (s.parse (TOK_OPEN_ROUND) && + s.type_id () && + s.parse (TOK_CLOSE_ROUND))) && + s.opt (NewInit::check (s))); +} +bool CCSyntax::new_expr () { return NewExpr::parse (*this); } + +bool CCSyntax::NewPlacement::parse (CCSyntax &s) { + // 3: ( expr_list ) + return (s.parse (TOK_OPEN_ROUND) && + ExprList::check (s) && + s.parse (TOK_CLOSE_ROUND)); +} +bool CCSyntax::new_placement () { return NewPlacement::parse (*this); } + +bool CCSyntax::NewTypeId::parse (CCSyntax &s) { + // 2: type_spec_seq new_declarator + // 2: type_spec_seq private_name + return s.type_spec_seq () && + (NewDeclarator::check (s) || PrivateName::check (s)); +} +bool CCSyntax::new_type_id () { return NewTypeId::parse (*this); } + +bool CCSyntax::NewDeclarator::parse (CCSyntax &s) { + // 1 : direct_new_declarator + // 1+: ptr_operator.. + // 2+: ptr_operator.. direct_new_declarator + return (DirectNewDeclarator::check (s) || + (seq (s) && + s.opt (DirectNewDeclarator::check (s)))); +} +bool CCSyntax::new_declarator () { return NewDeclarator::parse (*this); } + +bool CCSyntax::DirectNewDeclarator::parse (CCSyntax &s) { + // 3 : [ expr ] + // 4+: [ expr ] direct_new_declarator1... + return ((s.parse (TOK_OPEN_SQUARE) && Expr::check (s) && + s.parse (TOK_CLOSE_SQUARE)) && + s.opt (seq(s))); +} +bool CCSyntax::direct_new_declarator () { return DirectNewDeclarator::parse (*this); } + +bool CCSyntax::DirectNewDeclarator1::parse (CCSyntax &s) { + // 3: [ const_expr ] + return (s.parse (TOK_OPEN_SQUARE) && ConstExpr::check (s) && + s.parse (TOK_CLOSE_SQUARE)); +} +bool CCSyntax::direct_new_declarator1 () { return DirectNewDeclarator1::parse (*this); } + +bool CCSyntax::NewInit::parse (CCSyntax &s) { + // 2: ( ) + // 3: ( expr_list ) + return (s.parse (TOK_OPEN_ROUND) && (ExprList::check (s), + s.parse (TOK_CLOSE_ROUND))); +} +bool CCSyntax::new_init () { return NewInit::parse (*this); } + +bool CCSyntax::DeleteExpr::parse (CCSyntax &s) { + // 2: DELETE cast_expr + // 3: :: DELETE cast_expr + // 4: DELETE [ ] cast_expr + // 5: :: DELETE [ ] cast_expr + return ((s.parse (TOK_COLON_COLON), s.parse (TOK_DELETE)) && + (s.parse (TOK_OPEN_SQUARE) ? s.parse (TOK_CLOSE_SQUARE) : true) && + CastExpr::check (s)); +} +bool CCSyntax::delete_expr () { return DeleteExpr::parse (*this); } + +bool CCSyntax::PmExpr::parse (CCSyntax &s) { + // 1 : cast_expr + // 3+: cast_expr any_pm_op cast_expr .. + static int any_pm_op[] = { TOK_DOT_STAR, TOK_PTS_STAR, 0 }; + return list (s, any_pm_op); +} +bool CCSyntax::pm_expr () { return PmExpr::parse (*this); } + +bool CCSyntax::MulExpr::parse (CCSyntax &s) { + // 1 : pm_expr + // 3+: pm_expr any_mul_op pm_expr .. + static int any_mul_op[] = { TOK_MUL, TOK_DIV, TOK_MODULO, 0 }; + return list (s, any_mul_op); +} +bool CCSyntax::mul_expr () { return MulExpr::parse (*this); } + +bool CCSyntax::RelExpr::parse (CCSyntax &s) { + // 1 : shift_expr + // 3+: shift_expr any_rel_op shift_expr ... + static int any_rel_op[] = { TOK_LESS, TOK_GREATER, TOK_LEQ, TOK_GEQ, 0 }; + if (! ShiftExpr::check (s)) + return false; + while (true) { + // ���14.2.3 check if this is the end of a template argument list + if (s.look_ahead (TOK_GREATER)) { + if ((s.semantic ().in_template_arg_list () && + ! s.is_nested (s.semantic ().in_template_arg_list ())) || + (s.semantic ().in_template_param_list () && + ! s.is_nested (s.semantic ().in_template_param_list ()))) + break; + } + if (! s.parse (any_rel_op)) + break; + if (! ShiftExpr::check (s)) + return false; + } + return true; +} +bool CCSyntax::rel_expr () { return RelExpr::parse (*this); } + +bool CCSyntax::CondExpr::parse (CCSyntax &s) { + // 1: log_or_expr + // 5: log_or_expr ? expr : ass_expr + return (LogOrExpr::check (s) && + (s.parse (TOK_QUESTION) ? (Expr::check (s) && + s.parse (TOK_COLON) && AssExpr::check (s)) : true)); +} +bool CCSyntax::cond_expr () { return CondExpr::parse (*this); } + +bool CCSyntax::AssExpr::parse (CCSyntax &s) { + // 1 : cond_expr + // 1 : throw_expr + // 2+: ass_expr1.. cond_expr + // 2+: ass_expr1.. throw_expr + return (seq (s), + (s.throw_expr () || CondExpr::check (s))); +} +bool CCSyntax::ass_expr () { return AssExpr::parse (*this); } + +bool CCSyntax::AssExpr1::parse (CCSyntax &s) { + // 2: log_or_expr any_ass_op + static int any_ass_op[] = { TOK_ASSIGN, TOK_MUL_EQ, TOK_DIV_EQ, TOK_MOD_EQ, + TOK_ADD_EQ, TOK_SUB_EQ, TOK_RSH_EQ, TOK_LSH_EQ, + TOK_AND_EQ, TOK_XOR_EQ, TOK_IOR_EQ, 0 }; + return (s.is_ass_expr () && LogOrExpr::check (s) && s.parse (any_ass_op)); +} +bool CCSyntax::ass_expr1 () { return AssExpr1::parse (*this); } + +bool CCSyntax::ConstExpr::parse (CCSyntax &s) { + // 1: cond_expr + return CondExpr::check (s); +} +bool CCSyntax::const_expr () { return ConstExpr::parse (*this); } + +/*****************************************************************************/ +/* */ +/* A . 5 S t a t e m e n t s */ +/* */ +/*****************************************************************************/ + +bool CCSyntax::Stmt::parse (CCSyntax &s) { + // 1: label_stmt + // 1: decl_stmt + // 1: expr_stmt + // 1: cmpd_stmt + // 1: select_stmt + // 1: iter_stmt + // 1: jump_stmt + // 1: try_block + return (LabelStmt::check (s) || + ambiguous (s) || + CmpdStmt::check (s) || + SelectStmt::check (s) || + IterStmt::check (s) || + JumpStmt::check (s) || + s.try_block ()); +} +bool CCSyntax::stmt () { return Stmt::parse (*this); } + +bool CCSyntax::StmtSeq::parse (CCSyntax &s) { + // 1+: stmt.. + static int skip[] = { TOK_SEMI_COLON, TOK_CLOSE_CURLY, 0 }; + static int finish[] = { TOK_CLOSE_CURLY, 0 }; + if (! catch_error (s, "invalid statement", finish, skip)) + return false; + while (catch_error (s, "invalid statement", finish, skip)); + return true; +} +bool CCSyntax::stmt_seq () { return StmtSeq::parse (*this); } + +bool CCSyntax::SubStmt::parse (CCSyntax &s) { + // 1: stmt + // a substatement that is not a compound-statement is as if it + // would be a compound-statement containing the original statement; + // in this case it implicitly defines a local scope + if (! s.look_ahead (TOK_OPEN_CURLY)) + s.semantic ().enter_local_scope (); // enter local (block) scope + return Stmt::check (s); +} +bool CCSyntax::sub_stmt () { return SubStmt::parse (*this); } + +bool CCSyntax::Condition::parse (CCSyntax &s) { + // 1: expr + // 1: condition2 + return (Expr::check (s) || Condition2::check (s)); +} +bool CCSyntax::condition () { return Condition::parse (*this); } + +bool CCSyntax::Condition1::parse (CCSyntax &s) { + // 2: type_spec_seq declarator + return (s.type_spec_seq () && Declarator::check (s)); +} +bool CCSyntax::condition1 () { return Condition1::parse (*this); } + +bool CCSyntax::Condition2::parse (CCSyntax &s) { + // 3: condition1 = ass_expr + return (Condition1::check (s) && s.parse (TOK_ASSIGN) && AssExpr::check (s)); +} +bool CCSyntax::condition2 () { return Condition2::parse (*this); } + +bool CCSyntax::DeclStmt::parse (CCSyntax &s) { + // 1: block_decl + return BlockDecl::check (s); +} +bool CCSyntax::decl_stmt () { return DeclStmt::parse (*this); } + +/*****************************************************************************/ +/* */ +/* A . 6 D e c l a r a t i o n s */ +/* */ +/*****************************************************************************/ + +bool CCSyntax::Decl::parse (CCSyntax &s) { + // 1: block_decl + // 1: fct_def + // 1: explicit_specialization + // 1: template_decl + // 1: explicit_instantiation + // 1: linkage_spec + // 1: namespace_def + bool parsed = (s.explicit_specialization () || + s.template_decl () || + s.explicit_instantiation () || + NamespaceDef::check (s) || + LinkageSpec::check (s) || + (s.is_fct_def () ? + (s.fct_def () || BlockDecl::check (s)) : + (BlockDecl::check (s) || s.fct_def ()))); + return parsed; +} +bool CCSyntax::decl () { return Decl::parse (*this); } +bool CCSyntax::decl_check () { return Decl::check (*this); } + +bool CCSyntax::BlockDecl::parse (CCSyntax &s) { + // 1: simple_decl + // 1: asm_def + // 1: ns_alias_def + // 1: using_decl + // 1: using_directive + return (SimpleDecl::check (s) || + AsmDef::check (s) || + NsAliasDef::check (s) || + UsingDirective::check (s) || + UsingDecl::check (s)); +} +bool CCSyntax::block_decl () { return BlockDecl::parse (*this); } + +bool CCSyntax::SimpleDecl::parse (CCSyntax &s) { + // 1: ; + // 2: decl_spec_seq ; + // 3: decl_spec_seq init_declarator_list ; + return CSyntax::SimpleDecl::parse (s); +} +bool CCSyntax::simple_decl () { return SimpleDecl::parse (*this); } + +bool CCSyntax::MiscSpec::parse (CCSyntax &s) { + // 1: TYPEDEF + // 1: FRIEND + return (CSyntax::MiscSpec::parse (s) || s.parse (TOK_FRIEND)); +} +bool CCSyntax::misc_spec () { return MiscSpec::parse (*this); } + +bool CCSyntax::StorageClassSpec::parse (CCSyntax &s) { + // 1: MUTABLE + // 1: ... + return (CSyntax::StorageClassSpec::parse (s) || s.parse (TOK_MUTABLE)); +} +bool CCSyntax::storage_class_spec () { return StorageClassSpec::parse (*this); } + +bool CCSyntax::FctSpec::parse (CCSyntax &s) { + // 1: VIRTUAL + // 1: EXPLICIT + // 1: ... + return (CSyntax::FctSpec::parse (s) || + s.parse (TOK_VIRTUAL) || + s.parse (TOK_EXPLICIT)); +} +bool CCSyntax::fct_spec () { return FctSpec::parse (*this); } + +bool CCSyntax::SimpleTypeSpec::parse (CCSyntax &s) { + // 1: prim_types + // 1: type_name + // 2: nested_name_spec type_name + // 2: :: type_name + // 3: :: nested_name_spec type_name + // 3: nested_name_spec template_key template_id + // 4: :: nested_name_spec template_key template_id + return ((s.is_prim_type () && s.consume ()) || + (ColonColon::check (s), + ((NestedNameSpec::check (s), + (s.template_key () ? s.class_template_id () : TypeName::check (s)))))); +} +bool CCSyntax::simple_type_spec () { return SimpleTypeSpec::parse (*this); } + +bool CCSyntax::TypeName::parse (CCSyntax &s) { + // 1: class_name + // 1: enum_name + // 1: typedef_name + return (ClassName::check (s) || + EnumName::check (s) || + TypedefName::check (s)); +} +bool CCSyntax::type_name () { return TypeName::parse (*this); } + +bool CCSyntax::ElaboratedTypeSpec::parse (CCSyntax &s) { + // 2: class_key identifier + // 2: enum_key identifier + // 2: TYPENAME template_id + // 3: class_key :: identifier + // 3: enum_key :: identifier + // 3: class_key nested_name_spec identifier + // 3: enum_key nested_name_spec identifier + // 3: TYPENAME nested_name_spec identifier + // 3: TYPENAME nested_name_spec template_id + // 4: class_key :: nested_name_spec identifier + // 4: enum_key :: nested_name_spec identifier + // 4: TYPENAME nested_name_spec template_key template_id + // 4: TYPENAME :: nested_name_spec identifier + // 4: TYPENAME :: nested_name_spec template_id + // 5: TYPENAME :: nested_name_spec template_key template_id + return + ((ClassKey::check (s) || EnumKey::check (s)) ? + (ColonColon::check (s), NestedNameSpec::check (s), + s.template_id () || Identifier::check (s)) : + (s.parse (TOK_TYPENAME) && + (ColonColon::check (s), NestedNameSpec::check (s), + (s.template_key () ? s.template_id () : + s.template_id () || Identifier::check (s))))); +} +bool CCSyntax::elaborated_type_spec () { return ElaboratedTypeSpec::parse (*this); } + +bool CCSyntax::DeclSpecSeq1::parse (CCSyntax &s) { + // 1: decl_spec + // if the current template id is part of a declarator id, then it is no + // declaration specifier; declarator ids are not instantiated whereas + // declaration specifiers are instantiated + return s.is_tpl_declarator_id () ? false : CSyntax::DeclSpecSeq1::parse (s); +} +bool CCSyntax::decl_spec_seq1 () { return DeclSpecSeq1::parse (*this); } + +bool CCSyntax::EnumeratorList::parse (CCSyntax &s) { + // 1 : enumerator_def + // 3+: enumerator_def , enumerator_def .. + return s.opt (list (s, TOK_COMMA, true)); +} +bool CCSyntax::enumerator_list () { return EnumeratorList::parse (*this); } + +bool CCSyntax::EnumeratorDef::parse (CCSyntax &s) { + // 1: enumerator + // 3: enumerator = const_expr + return CSyntax::EnumeratorDef::parse (s); // the same as for C +} +bool CCSyntax::enumerator_def () { return EnumeratorDef::parse (*this); } + +bool CCSyntax::LinkageSpec::parse (CCSyntax &s) { + // 4+: (EXTERN str_literal)+ { } + // 5+: (EXTERN str_literal)+ { decl_seq } + // 3+: (EXTERN str_literal)+ decl + bool parsed = false; + // parse common prefix: sequence of more or more 'EXTERN "C"' + while (s.parse (TOK_EXTERN) && (parsed = StrLiteral::check (s))); + if (! parsed) + return false; + + return + ((s.parse (TOK_OPEN_CURLY) && s.opt (DeclSeq::check (s)) && s.parse (TOK_CLOSE_CURLY)) || + Decl::check (s)); +} +bool CCSyntax::linkage_spec () { return LinkageSpec::parse (*this); } + +/*****************************************************************************/ +/* */ +/* A . 6 . 1 N a m e s p a c e s */ +/* */ +/*****************************************************************************/ + +bool CCSyntax::NamespaceDef::parse (CCSyntax &s) { + // 1: named_ns_def + // 1: unnamed_ns_def + return (NamedNsDef::check (s) || UnnamedNsDef::check (s)); +} +bool CCSyntax::namespace_def () { return NamespaceDef::parse (*this); } + +bool CCSyntax::NamedNsDef::parse (CCSyntax &s) { + // 1: original_ns_def + // 1: extension_ns_def + return (ExtensionNsDef::check (s) || OriginalNsDef::check (s)); +} +bool CCSyntax::named_ns_def () { return NamedNsDef::parse (*this); } + +bool CCSyntax::OriginalNsDef::parse (CCSyntax &s) { + // 4: original_ns_def1 { namespace_body } + return (OriginalNsDef1::check (s) && s.parse (TOK_OPEN_CURLY) && + NamespaceBody::check (s) && s.parse (TOK_CLOSE_CURLY)); +} +bool CCSyntax::original_ns_def () { return OriginalNsDef::parse (*this); } + +bool CCSyntax::OriginalNsDef1::parse (CCSyntax &s) { + // 2: NAMESPACE identifier + // 3: INLINE NAMESPACE identifier + return ((s.parse (TOK_INLINE), s.parse (TOK_NAMESPACE)) && Identifier::check (s) && + s.look_ahead (TOK_OPEN_CURLY)); +} +bool CCSyntax::original_ns_def1 () { return OriginalNsDef1::parse (*this); } + +bool CCSyntax::ExtensionNsDef::parse (CCSyntax &s) { + // 4: extension_ns_def1 { namespace_body } + return (ExtensionNsDef1::check (s) && s.parse (TOK_OPEN_CURLY) && + NamespaceBody::check (s) && s.parse (TOK_CLOSE_CURLY)); +} +bool CCSyntax::extension_ns_def () { return ExtensionNsDef::parse (*this); } + +bool CCSyntax::ExtensionNsDef1::parse (CCSyntax &s) { + // 2: NAMESPACE original_ns_name + // 3: INLINE NAMESPACE original_ns_name + return ((s.parse (TOK_INLINE), s.parse (TOK_NAMESPACE)) && OriginalNsName::check (s) && + s.look_ahead (TOK_OPEN_CURLY)); +} +bool CCSyntax::extension_ns_def1 () { return ExtensionNsDef1::parse (*this); } + +bool CCSyntax::UnnamedNsDef::parse (CCSyntax &s) { + // 4: unnamed_ns_def1 { namespace_body } + return (UnnamedNsDef1::check (s) && s.parse (TOK_OPEN_CURLY) && + NamespaceBody::check (s) && s.parse (TOK_CLOSE_CURLY)); +} +bool CCSyntax::unnamed_ns_def () { return UnnamedNsDef::parse (*this); } + +bool CCSyntax::UnnamedNsDef1::parse (CCSyntax &s) { + // 2: NAMESPACE private_name + // 3: INLINE NAMESPACE private_name + return ((s.parse (TOK_INLINE), s.parse (TOK_NAMESPACE)) && PrivateName::check (s) && + s.look_ahead (TOK_OPEN_CURLY)); +} +bool CCSyntax::unnamed_ns_def1 () { return UnnamedNsDef1::parse (*this); } + +bool CCSyntax::NamespaceBody::parse (CCSyntax &s) { + // 1: decl_seq + return s.opt (DeclSeq::check (s)); +} +bool CCSyntax::namespace_body () { return NamespaceBody::parse (*this); } + +bool CCSyntax::NsAliasDef::parse (CCSyntax &s) { + // 5: NAMESPACE identifier = qual_ns_spec ; + return (s.parse (TOK_NAMESPACE) && Identifier::check (s) && + s.parse (TOK_ASSIGN) && QualNsSpec::check (s) && + s.parse (TOK_SEMI_COLON)); +} +bool CCSyntax::ns_alias_def () { return NsAliasDef::parse (*this); } + +bool CCSyntax::QualNsSpec::parse (CCSyntax &s) { + // 1: namespace_name + // 2: nested_name_spec namespace_name + // 2: colon_colon namespace_name + // 3: colon_colon nested_name_spec namespace_name + return (ColonColon::check (s), NestedNameSpec::check (s), NamespaceName::check (s)); +} +bool CCSyntax::qual_ns_spec () { return QualNsSpec::parse (*this); } + +bool CCSyntax::UsingDecl::parse (CCSyntax &s) { + // 4: USING :: unqual_id ; + // 4: USING nested_name_spec unqual_id ; + // 5: USING :: nested_name_spec unqual_id ; + // 5: USING TYPENAME nested_name_spec unqual_id ; + // 6: USING TYPENAME :: nested_name_spec unqual_id ; + if (! s.parse (TOK_USING)) + return false; + bool is_type = s.parse (TOK_TYPENAME); + bool is_root = ColonColon::check (s); + return ((NestedNameSpec::check (s) || (! is_type && is_root)) && + UnqualId::check (s) && s.parse (TOK_SEMI_COLON)); +} +bool CCSyntax::using_decl () { return UsingDecl::parse (*this); } + +bool CCSyntax::UsingDirective::parse (CCSyntax &s) { + // 4: USING NAMESPACE namespace_name ; + // 5: USING NAMESPACE :: namespace_name ; + // 5: USING NAMESPACE nested_name_spec namespace_name ; + // 6: USING NAMESPACE :: nested_name_spec namespace_name ; + return + (s.parse (TOK_USING) && s.parse (TOK_NAMESPACE) && + (ColonColon::check (s), NestedNameSpec::check (s), + (NamespaceName::check (s) && s.parse (TOK_SEMI_COLON)))); +} +bool CCSyntax::using_directive () { return UsingDirective::parse (*this); } + +/*****************************************************************************/ +/* */ +/* A . 7 D e c l a r a t o r s */ +/* */ +/*****************************************************************************/ + +bool CCSyntax::InitDeclarator::parse (CCSyntax &s) { + return CSyntax::InitDeclarator::parse (s); +} +bool CCSyntax::init_declarator () { return InitDeclarator::parse (*this); } + +bool CCSyntax::DirectDeclarator1::parse (CCSyntax &s) { + // 3: [ array_delim ] + // 3: ( param_decl_clause ) + // 4: ( param_decl_clause ) cv_qual_seq + // 4: ( param_decl_clause ) exception_spec + // 5: ( param_decl_clause ) cv_qual_seq exception_spec + return (s.parse (TOK_OPEN_ROUND) ? + (ParamDeclClause::check (s) && + s.parse (TOK_CLOSE_ROUND) && + s.opt (CvQualSeq::check (s)) && + s.opt (s.exception_spec ())) : + (s.parse (TOK_OPEN_SQUARE) && + ArrayDelim::check (s) && + s.parse (TOK_CLOSE_SQUARE))); +} +bool CCSyntax::direct_declarator1 () { return DirectDeclarator1::parse (*this); } + +bool CCSyntax::ArrayDelim::parse (CCSyntax &s) { + // 0: + // 1: const_expr + return s.opt (ConstExpr::check (s)); +} +bool CCSyntax::array_delim () { return ArrayDelim::parse (*this); } + +bool CCSyntax::PtrOperator::parse (CCSyntax &s) { + // 1: & + // 1: * + // 2: * cv_qual_seq + // 2: nested_name_spec * + // 3: nested_name_spec * cv_qual_seq + // 3: :: nested_name_spec * + // 4: :: nested_name_spec * cv_qual_seq + bool ok = // Win __cdecl hack :( + ((s.parse (TOK_AND) && s.opt (CvQualSeq::check (s))) || + ((ColonColon::check (s) ? + NestedNameSpec::check (s) : + s.opt (NestedNameSpec::check (s))) && + s.parse (TOK_MUL) && s.opt (CvQualSeq::check (s)))); + return ok; +// semantic ().reset_search_scope (); +// return ok ? builder ().ptr_operator () : (CTree*)0; +} +bool CCSyntax::ptr_operator () { return PtrOperator::parse (*this); } + +bool CCSyntax::DeclaratorId::parse (CCSyntax &s) { + // 1: id_expr + // 1: type_name + // 2: nested_name_spec type_name + // 2: :: type_name + // 3: :: nested_name_spec type_name + return ((ColonColon::check (s), NestedNameSpec::check (s), TypeName::check (s)) || IdExpr::check (s)); +} +bool CCSyntax::declarator_id () { return DeclaratorId::parse (*this); } + +bool CCSyntax::DirectAbstDeclarator::parse (CCSyntax &s) { + // 1+: direct_declarator1... + // 3 : ( abst_declarator ) + // 3+: ( abst_declarator ) direct_declarator1... + return ((DirectDeclarator1::check (s) || + (s.parse (TOK_OPEN_ROUND) && + AbstDeclarator::check (s) && + s.parse (TOK_CLOSE_ROUND))) && + s.opt (seq (s))); +} +bool CCSyntax::direct_abst_declarator () { return DirectAbstDeclarator::parse (*this); } + +bool CCSyntax::ParamDeclClause::parse (CCSyntax &s) { + // 0: + // 1: ... + // 1: param_decl_list + // 3: param_decl_list ... + return s.opt ((s.param_decl_list (), s.parse (TOK_ELLIPSIS))); +} +bool CCSyntax::param_decl_clause () { return ParamDeclClause::parse (*this); } + +CTree *CCSyntax::rule_param_decl () { + // 1: param_decl1 + // 3: param_decl1 = ass_expr + if (! ParamDecl1::check (*this)) + return (CTree*)0; + semantic ().finish_decl (); + // parse param_init later due to potential use of names of members + // that could not be resolved till the end of the class definition + if (semantic ().in_class_def () && look_ahead (TOK_ASSIGN)) { + CTree *pd = builder ().param_decl (); + semantic ().parse_delayed (&CCSyntax::param_init, pd); + skip_param_init (); + return pd; + // not in class definition, so parse as usual + } else { + param_init (); + return builder ().param_decl (); + } +} + +bool CCSyntax::param_decl () { + return parse (&CCSyntax::rule_param_decl); +} + +CTree *CCSyntax::rule_param_init () { + // 2: = ass_expr + return (parse (TOK_ASSIGN) && AssExpr::check (*this)) ? + builder ().param_init () : (CTree*)0; +} + +bool CCSyntax::param_init () { + return parse (&CCSyntax::rule_param_init); +} + +CTree *CCSyntax::rule_fct_def () { + // 2: declarator fct_body + // 2: declarator fct_try_block + // 3: declarator ctor_init fct_body + // 3: decl_spec_seq declarator fct_body + // 3: decl_spec_seq declarator fct_try_block + // 4: decl_spec_seq declarator ctor_init fct_body + if (! ((DeclSpecSeq::check (*this) || + semantic ().empty_decl_spec_seq ()), + semantic ().reset_search_scope (true), + Declarator::check (*this))) { + semantic ().finish_declarator (); + return (CTree*)0; + } + + // introduce name and check scope; functions shall be + // defined only in namespace or class scope + if (! semantic ().introduce_function ()) + return (CTree*)0; + + // skip function bodies on demand + bool skip_fct_bodies = false; + if ((_skip_bodies & SKIP_BODIES_ALL) || + ((_skip_bodies & SKIP_BODIES_TPL) && semantic ().skip_tpl_fct_bodies ()) || + ((_skip_bodies & SKIP_BODIES_NON_PRJ) && semantic ().non_project_loc ()) || + ((_skip_bodies & SKIP_BODIES_NON_PRIM) && semantic ().non_primary_loc ())) + skip_fct_bodies = true; + + // parse fct_body and ctor_init later due to potential use of names + // of members that could not be resolved till the end of the class + // definition + if (semantic ().in_class_def ()) { + CTree *fd = semantic ().finish_fct_def (); + if (look_ahead (TOK_TRY)) { + semantic ().parse_delayed (&CCSyntax::fct_try_block, fd); + skip_fct_try_block (); + } else { + if (look_ahead (TOK_COLON)) { + semantic ().parse_delayed (&CCSyntax::ctor_init, fd); + skip_ctor_init (); + } else if (look_ahead (TOK_ASSIGN)) { + semantic ().parse_delayed (&CCSyntax::pure_spec, fd); + skip_ctor_init (); + } + if (look_ahead (TOK_OPEN_CURLY)) { + semantic ().parse_delayed (skip_fct_bodies ? &CCSyntax::skipped_fct_body : &CCSyntax::fct_body, fd); + skip_fct_body (); + } else { + delete fd; + fd = (CTree*)0; + } + } + return fd; + // not in class definition, so parse as usual + } else + return (fct_try_block () || + ((ctor_init () || pure_spec ()), + skip_fct_bodies ? skipped_fct_body() : fct_body ())) ? + semantic ().finish_fct_def () : (CTree*)0; +} + +bool CCSyntax::fct_def () { + return parse (&CCSyntax::rule_fct_def); +} + +CTree *CCSyntax::rule_skipped_fct_body () { + static int stop_tokens[] = { TOK_CLOSE_CURLY, 0 }; + + if (!parse (TOK_OPEN_CURLY)) return (CTree*)0; + semantic ().enter_local_scope (); // enter local (block) scope + skip (stop_tokens, false); + if (!parse (TOK_CLOSE_CURLY)) return (CTree*)0; + return semantic ().cmpd_stmt (); +} + +bool CCSyntax::skipped_fct_body () { + return parse (&CCSyntax::rule_skipped_fct_body); +} + +CTree *CCSyntax::rule_fct_body () { + // 1: cmpd_stmt + return cmpd_stmt () ? + builder ().fct_body () : (CTree*)0; +} + +bool CCSyntax::fct_body () { + return parse (&CCSyntax::rule_fct_body); +} + +CTree *CCSyntax::rule_init () { + // 2: = init_clause + // 3: ( expr_list ) + return (parse (TOK_ASSIGN) ? init_clause () : + (parse (TOK_OPEN_ROUND) && expr_list () && + parse (TOK_CLOSE_ROUND))) ? + builder ().init () : (CTree*)0; +} + +bool CCSyntax::init () { + return parse (&CCSyntax::rule_init); +} + +CTree *CCSyntax::rule_init_clause () { + // 1: ass_expr + // 2: { } + // 3: { init_list } + return (AssExpr::check (*this) || + (parse (TOK_OPEN_CURLY) && + (init_list (), parse (TOK_CLOSE_CURLY)))) ? + builder ().init_clause () : (CTree*)0; +} + +bool CCSyntax::init_clause () { + return parse (&CCSyntax::rule_init_clause); +} + +/*****************************************************************************/ +/* */ +/* A . 8 C l a s s e s */ +/* */ +/*****************************************************************************/ + +CTree *CCSyntax::rule_class_spec () { + // 3: class_head { } + // 4: class_head { member_spec } + if (! (is_class_def () && ClassHead::check (*this))) + return (CTree*)0; + semantic ().reenter_class_scope (); + return (parse (TOK_OPEN_CURLY) && + (member_spec (), parse (TOK_CLOSE_CURLY))) ? + semantic ().class_spec () : semantic ().class_spec_err (); +} + +bool CCSyntax::class_spec () { + return predict_1 (_class_spec_1) && parse (&CCSyntax::rule_class_spec); +} + +bool CCSyntax::ClassHead::parse (CCSyntax &s) { + // 1: class_head1 + // 2: class_head1 base_clause + return (ClassHead1::check (s) && s.opt (s.base_clause ())); +} +bool CCSyntax::class_head () { return ClassHead::parse (*this); } + +bool CCSyntax::ClassHead1::parse (CCSyntax &s) { + // 1: class_key + // 2: class_key identifier + // 2: class_key template_id + // 3: class_key nested_name_spec identifier + // 3: class_key nested_name_spec template_id + s.semantic ().enter_entity_name (); + bool parsed = + (ClassKey::check (s) && + (NestedNameSpec::check (s) ? + (s.template_id () || Identifier::check (s)) : + (s.template_id () || Identifier::check (s) || PrivateName::check (s)))); + s.semantic ().reset_search_scope (); + s.semantic ().leave_entity_name (); + return (parsed && (s.look_ahead (TOK_OPEN_CURLY) || s.look_ahead (TOK_COLON))); +} +bool CCSyntax::class_head1 () { return ClassHead1::parse (*this); } + +CTree *CCSyntax::rule_member_decl () { + // 1: member_decl1 + // 1: fct_def + // 1: using_decl + // 1: member_template_decl + // 1: access_decl + // 2: access_spec : + if (access_spec ()) { + if (parse (TOK_COLON)) + return semantic ().access_spec (); + else + return (CTree*)0; + } + if (! (UsingDecl::check (*this) || + access_decl () || + member_template_decl () || + (is_fct_def () ? fct_def () : + member_decl1 () /*|| + parse (&CCSyntax::fct_def)*/))) + return (CTree*)0; + semantic ().finish_decl (); + return builder ().member_decl (); +} + +bool CCSyntax::member_decl () { + return parse (&CCSyntax::rule_member_decl); +} + +CTree *CCSyntax::rule_member_decl1 () { + // 1: ; + // 2: decl_spec_seq ; + // 2: member_declarator_list ; + // 3: decl_spec_seq member_declarator_list ; + return ((DeclSpecSeq::check (*this) || + semantic ().empty_decl_spec_seq ()), + member_declarator_list (), + parse (TOK_SEMI_COLON)) ? + semantic ().member_decl1 () : (CTree*)0; +} + +bool CCSyntax::member_decl1 () { + return parse (&CCSyntax::rule_member_decl1); +} + +CTree *CCSyntax::rule_access_decl () { + // 3: nested_name_spec unqual_id ; + // 4: nested_name_spec template_key unqual_id ; + // 4: :: nested_name_spec unqual_id ; + // 5: :: nested_name_spec template_key unqual_id ; + bool ok = + ((ColonColon::check (*this), NestedNameSpec::check (*this)) && + (template_key (), + unqual_id ()) && + parse (TOK_SEMI_COLON)); + semantic ().reset_search_scope (); + return ok ? semantic ().access_decl () : (CTree*)0; +} + +bool CCSyntax::access_decl () { + return parse (&CCSyntax::rule_access_decl); +} + +CTree *CCSyntax::rule_member_declarator () { + // 1: declarator + // 2: declarator pure_spec + // 2: declarator const_init + // 3: identifier : const_expr + // 3: private_name : const_expr + CT_InitDeclarator *md; + + // lookahead: check if this is a bitfield declarator + State s = save_state (); + bool bitfield = (Identifier::check (*this), parse (TOK_COLON)); + restore_state (s); + + // parse const_expr and const_init later due to potential use of names + // of members that could not be resolved till the end of the class + // definition + if (semantic ().in_class_def () && ! bitfield) { + if (Declarator::check (*this)) { + // optional extensions + // InitDeclaratorExt::check (*this); + // constant initializer + if (! pure_spec () && look_ahead (TOK_ASSIGN)) { + md = (CT_InitDeclarator*)semantic ().introduce_member (); + // initializers of const members are evaluated immediately + if (md && md->Object () && md->Object ()->TypeInfo ()->isConst ()) { + if (const_init ()) + md->Initializer (builder ().get_node (builder ().nodes ()-1)); + // initializers of non-const members are evaluated later + } else if (md) { + semantic ().parse_delayed (&CCSyntax::const_init, md); + skip_const_init (); + } + // pure specifier; always is "0" + } else + md = (CT_InitDeclarator*)semantic ().introduce_member (); + return md; + } + // not in class definition scope, so parse as usual + } else { + if (bitfield) { + if ((Identifier::check (*this) || + PrivateName::check (*this)) && parse (TOK_COLON) && + ConstExpr::check (*this)) + return semantic ().introduce_member (); + } else { + if (Declarator::check (*this) && /*opt (InitDeclaratorExt::check (*this)) &&*/ + opt (pure_spec () || const_init ())) + return semantic ().introduce_member (); + } + } + return semantic ().member_declarator_err (); +} + +bool CCSyntax::member_declarator () { + return parse (&CCSyntax::rule_member_declarator); +} + +CTree *CCSyntax::rule_pure_spec () { + // 2: = 0 + return (parse (TOK_ASSIGN) && parse (TOK_ZERO_VAL)) ? + semantic ().pure_spec () : (CTree*)0; +} + +bool CCSyntax::pure_spec () { + return parse (&CCSyntax::rule_pure_spec); +} + +CTree *CCSyntax::rule_const_init () { + // 2: = const_expr + return (parse (TOK_ASSIGN) && ConstExpr::check (*this)) ? + semantic ().const_init () : (CTree*)0; +} + +bool CCSyntax::const_init () { + return parse (&CCSyntax::rule_const_init); +} + +/*****************************************************************************/ +/* */ +/* A . 9 D e r i v e d c l a s s e s */ +/* */ +/*****************************************************************************/ + +CTree *CCSyntax::rule_base_clause () { + // 2: : base_spec_list + return (parse (TOK_COLON) && base_spec_list ()) ? + builder ().base_clause () : (CTree*)0; +} + +bool CCSyntax::base_clause () { + return parse (&CCSyntax::rule_base_clause); +} + +CTree *CCSyntax::rule_base_spec_list () { + // 1 : base_spec + // 3+: base_spec , base_spec .. + return list (&CCSyntax::base_spec, TOK_COMMA) ? + builder ().base_spec_list () : (CTree*)0; +} + +bool CCSyntax::base_spec_list () { + return parse (&CCSyntax::rule_base_spec_list); +} + +CTree *CCSyntax::rule_base_spec () { + // 1: class_name + // 2: :: class_name + // 2: VIRTUAL class_name + // 2: access_spec class_name + // 2: nested_name_spec class_name + // 3: nested_name_spec template_key class_name + // 3: :: nested_name_spec class_name + // 3: VIRTUAL :: class_name + // 3: access_spec :: class_name + // 3: VIRTUAL nested_name_spec class_name + // 3: access_spec nested_name_spec class_name + // 3: VIRTUAL access_spec class_name + // 3: access_spec VIRTUAL class_name + // 4: :: nested_name_spec template_key class_name + // 4: VIRTUAL nested_name_spec template_key class_name + // 4: access_spec nested_name_spec template_key class_name + // 4: VIRTUAL :: nested_name_spec class_name + // 4: access_spec :: nested_name_spec class_name + // 4: VIRTUAL access_spec nested_name_spec class_name + // 4: access_spec VIRTUAL nested_name_spec class_name + // 4: VIRTUAL access_spec :: class_name + // 4: access_spec VIRTUAL :: class_name + // 5: VIRTUAL :: nested_name_spec template_key class_name + // 5: access_spec :: nested_name_spec template_key class_name + // 5: VIRTUAL access_spec nested_name_spec template_key class_name + // 5: access_spec VIRTUAL nested_name_spec template_key class_name + // 5: VIRTUAL access_spec :: nested_name_spec class_name + // 5: access_spec VIRTUAL :: nested_name_spec class_name + // 6: VIRTUAL access_spec :: nested_name_spec template_key class_name + // 6: access_spec VIRTUAL :: nested_name_spec template_key class_name + bool ok = false; + if (parse (TOK_VIRTUAL) ? opt (access_spec ()) : + (access_spec () ? opt (parse (TOK_VIRTUAL)) : true)) { + ColonColon::check (*this); + NestedNameSpec::check (*this); + template_key (); + semantic ().enter_base_spec (); + ok = class_name (); + semantic ().leave_base_spec (); + } + semantic ().reset_search_scope (); + return ok ? builder ().base_spec () : (CTree*)0; +} + +bool CCSyntax::base_spec () { + return parse (&CCSyntax::rule_base_spec); +} + +void CCSyntax::init_access_spec () { + _access_spec_1.set (TOK_PRIVATE); + _access_spec_1.set (TOK_PROTECTED); + _access_spec_1.set (TOK_PUBLIC); +} + +CTree *CCSyntax::rule_access_spec () { + // 1: PUBLIC + // 1: PRIVATE + // 1: PROTECTED + consume (); // already checked by look ahead + return builder ().access_spec (); +} + +bool CCSyntax::access_spec () { + return predict_1 (_access_spec_1) && parse (&CCSyntax::rule_access_spec); +} + +/*****************************************************************************/ +/* */ +/* A . 1 0 S p e c i a l m e m b e r f u n c t i o n s */ +/* */ +/*****************************************************************************/ + +bool CCSyntax::ConvFctId::parse (CCSyntax &s) { + // 2: OPERATOR conv_type_id + return s.consume () && // TOK_OPERATOR checked during prediction + ConvTypeId::check (s); +} +bool CCSyntax::conv_fct_id () { return ConvFctId::parse (*this); } + +bool CCSyntax::ConvTypeId::parse (CCSyntax &s) { + // 2: type_spec_seq conv_declarator + // 2: type_spec_seq private_name + return s.type_spec_seq () && + (s.conv_declarator () || PrivateName::check (s)); +} +bool CCSyntax::conv_type_id () { return ConvTypeId::parse (*this); } + +CTree *CCSyntax::rule_conv_declarator () { + // 1+: ptr_operator.. + return seq (&CCSyntax::ptr_operator) ? + semantic ().abst_declarator () : (CTree*)0; +} + +bool CCSyntax::conv_declarator () { + return parse (&CCSyntax::rule_conv_declarator); +} + +CTree *CCSyntax::rule_ctor_init () { + // 2: : mem_init_list + return (parse (TOK_COLON) && mem_init_list ()) ? + semantic ().ctor_init () : (CTree*)0; +} + +bool CCSyntax::ctor_init () { + return parse (&CCSyntax::rule_ctor_init); +} + +CTree *CCSyntax::rule_mem_init_list () { + // 1 : mem_init + // 3+: mem_init , mem_init .. + return list (&CCSyntax::mem_init, TOK_COMMA) ? + builder ().mem_init_list () : (CTree*)0; +} + +bool CCSyntax::mem_init_list () { + return parse (&CCSyntax::rule_mem_init_list); +} + +CTree *CCSyntax::rule_mem_init () { + // 3: mem_init_id ( ) + // 4: mem_init_id ( expr_list ) + return (mem_init_id () && parse (TOK_OPEN_ROUND) && + (expr_list (), parse (TOK_CLOSE_ROUND))) ? + builder ().mem_init () : (CTree*)0; +} + +bool CCSyntax::mem_init () { + return parse (&CCSyntax::rule_mem_init); +} + +CTree *CCSyntax::rule_mem_init_id () { + // 1: identifier + // 1: class_name + // 2: nested_name_spec class_name + // 2: :: class_name + // 3: :: nested_name_spec class_name + bool ok = + ((ColonColon::check (*this), NestedNameSpec::check (*this), + class_name ()) || + Identifier::check (*this)); + semantic ().reset_search_scope (); + return ok ? builder ().mem_init_id () : (CTree*)0; +} + +bool CCSyntax::mem_init_id () { + return parse (&CCSyntax::rule_mem_init_id); +} + +/*****************************************************************************/ +/* */ +/* A . 1 1 O v e r l o a d i n g */ +/* */ +/*****************************************************************************/ + +void CCSyntax::init_oper_fct_id () { + _oper_fct_id_1.set (TOK_OPERATOR); +} + +CTree *CCSyntax::rule_oper_fct_id () { + // 2: OPERATOR any_operator + // 2: OPERATOR NEW + // 2: OPERATOR DELETE + // 3: OPERATOR ( ) + // 3: OPERATOR [ ] + // 4: OPERATOR NEW [ ] + // 4: OPERATOR DELETE [ ] + static int any_operator[] = { + TOK_PLUS, TOK_MINUS, TOK_MUL, TOK_DIV, TOK_MODULO, TOK_ROOF, + TOK_AND, TOK_OR, TOK_TILDE, TOK_NOT, TOK_LESS, TOK_GREATER, + TOK_EQL, TOK_GEQ, TOK_LEQ, TOK_NEQ, TOK_AND_AND, TOK_OR_OR, + TOK_LSH, TOK_RSH, TOK_DECR, TOK_INCR, TOK_ASSIGN, TOK_COMMA, + TOK_ADD_EQ, TOK_SUB_EQ, TOK_MUL_EQ, TOK_DIV_EQ, TOK_MOD_EQ, + TOK_AND_EQ, TOK_IOR_EQ, TOK_LSH_EQ, TOK_RSH_EQ, TOK_XOR_EQ, + TOK_PTS_STAR, TOK_PTS, 0 }; + return (parse (TOK_OPERATOR) && + ((parse (TOK_NEW) || parse (TOK_DELETE)) ? + (parse (TOK_OPEN_SQUARE) ? parse (TOK_CLOSE_SQUARE) : true) : + parse (TOK_OPEN_ROUND) ? parse (TOK_CLOSE_ROUND) : + parse (TOK_OPEN_SQUARE) ? parse (TOK_CLOSE_SQUARE) : + parse (any_operator))) ? + builder ().oper_fct_id () : (CTree*)0; +} + +bool CCSyntax::oper_fct_id () { + return predict_1 (_oper_fct_id_1) && parse (&CCSyntax::rule_oper_fct_id); +} + +/*****************************************************************************/ +/* */ +/* A . 1 2 T e m p l a t e s */ +/* */ +/*****************************************************************************/ + +void CCSyntax::init_template_key () { + _template_key_1.set (TOK_TEMPLATE); +} + +CTree *CCSyntax::rule_template_key () { + // 1: TEMPLATE + consume (); + return semantic ().template_key (); +} + +bool CCSyntax::template_key () { + return look_ahead () == TOK_TEMPLATE && parse (&CCSyntax::rule_template_key); +} + + +CTree *CCSyntax::rule_template_decl () { + // 5: TEMPLATE < template_param_list > decl + // 6: EXPORT TEMPLATE < template_param_list > decl + if (! ((parse (TOK_EXPORT), parse (TOK_TEMPLATE)) && parse (TOK_LESS) && + template_param_list () && parse (TOK_GREATER))) + return (CTree*)0; + semantic ().enter_template_decl (); + decl (); + return semantic ().template_decl (); +} + +bool CCSyntax::template_decl () { + return parse (&CCSyntax::rule_template_decl); +} + +CTree *CCSyntax::rule_member_template_decl () { + // 5: TEMPLATE < template_param_list > member_decl + // 6: EXPORT TEMPLATE < template_param_list > member_decl + if (! ((parse (TOK_EXPORT), parse (TOK_TEMPLATE)) && parse (TOK_LESS) && + template_param_list () && parse (TOK_GREATER))) + return (CTree*)0; + semantic ().enter_template_decl (); + member_decl (); + return semantic ().template_decl (); +} + +bool CCSyntax::member_template_decl () { + return parse (&CCSyntax::rule_member_template_decl); +} + +CTree *CCSyntax::rule_template_param_list () { + // 1 : template_param + // 3+: template_param , template_param .. + semantic ().enter_template_param_list (token_provider->get_state ()); + bool success = list (&CCSyntax::template_param, TOK_COMMA); + semantic ().leave_template_param_list (); + return success ? + semantic ().template_param_list () : (CTree*)0; +} + +bool CCSyntax::template_param_list () { + return parse (&CCSyntax::rule_template_param_list); +} + +CTree *CCSyntax::rule_template_param () { + // 1: type_param + // 1: non_type_param + return (type_param () || non_type_param ()) ? + semantic ().template_param () : (CTree*)0; +} + +bool CCSyntax::template_param () { + return parse (&CCSyntax::rule_template_param); +} + +CTree *CCSyntax::rule_type_param () { + // 1: CLASS + // 1: TYPENAME + // 2: CLASS identifier + // 2: TYPENAME identifier + // 3: CLASS = type_id + // 3: TYPENAME = type_id + // 4: CLASS identifier = type_id + // 4: TYPENAME identifier = type_id + // 5: TEMPLATE < template_param_list > CLASS + // 6: TEMPLATE < template_param_list > CLASS identifier + // 7: TEMPLATE < template_param_list > CLASS = id_expr + // 8: TEMPLATE < template_param_list > CLASS identifier = id_expr + return (((parse (TOK_CLASS) || parse (TOK_TYPENAME)) ? + (Identifier::check (*this) || PrivateName::check (*this), + parse (TOK_ASSIGN) ? type_id () : true) : + parse (TOK_TEMPLATE) && + parse (TOK_LESS) && template_param_list () && + parse (TOK_GREATER) && parse (TOK_CLASS) && + (Identifier::check (*this) || PrivateName::check (*this), + parse (TOK_ASSIGN) ? + (semantic ().enter_expr (), + (id_expr () ? semantic ().leave_expr () : + (semantic ().leave_expr (), false))) : true)) && + (look_ahead (TOK_COMMA) || look_ahead (TOK_GREATER))) ? + semantic ().introduce_type_param () : (CTree*)0; +} + +bool CCSyntax::type_param () { + return parse (&CCSyntax::rule_type_param); +} + +CTree *CCSyntax::rule_non_type_param () { + // 1: decl_spec_seq + // 2: decl_spec_seq abst_declarator + // 2: decl_spec_seq declarator + // 2: decl_spec_seq param_init + // 3: decl_spec_seq abst_declarator param_init + // 3: decl_spec_seq declarator param_init + if (! (DeclSpecSeq::check (*this) && + (Declarator::check (*this) || + abst_declarator () || + PrivateName::check (*this)))) { + semantic ().finish_declarator (); + return (CTree*)0; + } + CTree *result = semantic ().introduce_non_type_param (); + if (! result) + return (CTree*)0; + param_init (); + return builder ().non_type_param (result); +} + +bool CCSyntax::non_type_param () { + return parse (&CCSyntax::rule_non_type_param); +} + +void CCSyntax::init_template_id () { + init_oper_fct_id (); + init_conv_fct_id (); + _template_id_1.set (TOK_ID); + _template_id_1 |= _oper_fct_id_1; + _template_id_1 |= _conv_fct_id_1; +} + +CTree *CCSyntax::rule_template_id () { + // 3: template_name < > + // 4: template_name < template_arg_list > + if (! ((template_name () || + oper_fct_id () || + ConvFctId::check (*this)) && parse (TOK_LESS))) + return (CTree*)0; + SearchScope sc; + get_search_scope (sc); + semantic ().reset_search_scope (); + semantic ().enter_entity_name (false); + template_arg_list (); + semantic ().leave_entity_name (); + set_search_scope (sc); + return parse (TOK_GREATER) ? + semantic ().introduce_template_instance () : (CTree*)0; +} + +bool CCSyntax::template_id () { + return predict_1 (_template_id_1) && parse (&CCSyntax::rule_template_id); +} + +void CCSyntax::init_class_template_id () { + _template_id_1.set (TOK_ID); +} + +CTree *CCSyntax::rule_class_template_id () { + // 3: template_name < > + // 4: template_name < template_arg_list > + if (! (class_template_name () && parse (TOK_LESS))) + return (CTree*)0; + SearchScope sc; + get_search_scope (sc); + semantic ().reset_search_scope (); + semantic ().enter_entity_name (false); + template_arg_list (); + semantic ().leave_entity_name (); + set_search_scope (sc); + return parse (TOK_GREATER) ? + semantic ().introduce_template_instance () : (CTree*)0; +} + +bool CCSyntax::class_template_id () { + return predict_1 (_template_id_1) && parse (&CCSyntax::rule_class_template_id); +} + +CTree *CCSyntax::rule_template_arg_list () { + // 1 : template_arg + // 3+: template_arg , template_arg .. + semantic ().enter_template_arg_list (token_provider->get_state ()); + bool success = list (&CCSyntax::template_arg, TOK_COMMA); + semantic ().leave_template_arg_list (); + return success ? + builder ().template_arg_list () : (CTree*)0; +} + +bool CCSyntax::template_arg_list () { + return parse (&CCSyntax::rule_template_arg_list); +} + +CTree *CCSyntax::rule_template_arg () { + // 1: template_type_arg + // 1: template_non_type_arg + // 1: template_template_arg + return (template_type_arg () || + template_non_type_arg () || + template_template_arg ()) ? + builder ().template_arg () : (CTree*)0; +} + +bool CCSyntax::template_arg () { + return parse (&CCSyntax::rule_template_arg); +} + +CTree *CCSyntax::rule_template_type_arg () { + // 1: type_id + static int argsep[] = { TOK_COMMA, TOK_GREATER, 0 }; + return (type_id () && look_ahead (argsep)) ? + builder ().template_type_arg () : (CTree*)0; +} + +bool CCSyntax::template_type_arg () { + return parse (&CCSyntax::rule_template_type_arg); +} + +CTree *CCSyntax::rule_template_non_type_arg () { + // 1: ass_expr + static int argsep[] = { TOK_COMMA, TOK_GREATER, 0 }; + return (AssExpr::check (*this) && look_ahead (argsep)) ? + builder ().template_non_type_arg () : (CTree*)0; +} + +bool CCSyntax::template_non_type_arg () { + return parse (&CCSyntax::rule_template_non_type_arg); +} + +CTree *CCSyntax::rule_template_template_arg () { + // 1: id_expr + static int argsep[] = { TOK_COMMA, TOK_GREATER, 0 }; + semantic ().enter_expr (); + bool parsed = id_expr () && look_ahead (argsep); + semantic ().leave_expr (); + return parsed ? builder ().template_template_arg () : (CTree*)0; +} + +bool CCSyntax::template_template_arg () { + return parse (&CCSyntax::rule_template_template_arg); +} + +void CCSyntax::init_explicit_instantiation () { + _explicit_instantiation_1.set (TOK_TEMPLATE); + _explicit_instantiation_1.set (TOK_EXTERN); +} + +CTree *CCSyntax::rule_explicit_instantiation () { + // 2: TEMPLATE decl + // 3: EXTERN TEMPLATE decl => GCC EXTENSION!!! + if (! (parse (TOK_EXTERN), parse (TOK_TEMPLATE))) + return (CTree*)0; + semantic ().enter_template_param_list (0); + return decl () ? semantic ().explicit_instantiation () : (CTree*)0; +} + +bool CCSyntax::explicit_instantiation () { + return predict_1 (_explicit_instantiation_1) && + parse (&CCSyntax::rule_explicit_instantiation); +} + +void CCSyntax::init_explicit_specialization () { + _explicit_specialization_1.set (TOK_TEMPLATE); +} + +CTree *CCSyntax::rule_explicit_specialization () { + // 4: TEMPLATE < > decl + if (! (consume () && parse (TOK_LESS) && parse (TOK_GREATER))) + return (CTree*)0; + semantic ().enter_template_param_list (0); + return decl () ? + semantic ().explicit_specialization () : (CTree*)0; +} + +bool CCSyntax::explicit_specialization () { + return predict_1 (_explicit_specialization_1) && + parse (&CCSyntax::rule_explicit_specialization); +} + +/*****************************************************************************/ +/* */ +/* A . 1 3 E x c e p t i o n h a n d l i n g */ +/* */ +/*****************************************************************************/ + +CTree *CCSyntax::rule_try_block () { + // 3+: TRY cmpd_stmt handler_seq + return (parse (TOK_TRY) && cmpd_stmt () && + handler_seq ()) ? + builder ().try_block () : (CTree*)0; +} + +bool CCSyntax::try_block () { + return parse (&CCSyntax::rule_try_block); +} + +CTree *CCSyntax::rule_fct_try_block () { + // 3+: TRY fct_body handler_seq + // 4+: TRY ctor_init fct_body handler_seq + bool skip_fct_bodies = false; + if ((_skip_bodies & SKIP_BODIES_ALL) || + ((_skip_bodies & SKIP_BODIES_TPL) && semantic ().skip_tpl_fct_bodies ()) || + ((_skip_bodies & SKIP_BODIES_NON_PRJ) && semantic ().non_project_loc ()) || + ((_skip_bodies & SKIP_BODIES_NON_PRIM) && semantic ().non_primary_loc ())) + skip_fct_bodies = true; + return (parse (TOK_TRY) && opt (ctor_init ()) && + (skip_fct_bodies ? skipped_fct_body() : fct_body()) && + handler_seq ()) ? + builder ().fct_try_block () : (CTree*)0; +} + +bool CCSyntax::fct_try_block () { + return parse (&CCSyntax::rule_fct_try_block); +} + +CTree *CCSyntax::rule_handler_seq () { + // 1+: handler.. + return seq (&CCSyntax::handler) ? + builder ().handler_seq () : (CTree*)0; +} + +bool CCSyntax::handler_seq () { + return parse (&CCSyntax::rule_handler_seq); +} + +CTree *CCSyntax::rule_handler () { + // 5: CATCH ( exception_decl ) cmpd_stmt + if (! parse (TOK_CATCH)) + return (CTree*)0; + semantic ().enter_local_scope (); // enter local (block) scope + return (parse (TOK_OPEN_ROUND) && exception_decl () && + parse (TOK_CLOSE_ROUND) && cmpd_stmt ()) ? + semantic ().handler () : (CTree*)0; +} + +bool CCSyntax::handler () { + return parse (&CCSyntax::rule_handler); +} + +CTree *CCSyntax::rule_exception_decl () { + // 1: ... + // 1: type_spec_seq + // 2: type_spec_seq abst_declarator + // 2: type_spec_seq declarator + if (parse (TOK_ELLIPSIS)) + return builder ().exception_decl (); + bool parsed = (type_spec_seq () && + (Declarator::check (*this) || + abst_declarator () || + PrivateName::check (*this))); + semantic ().finish_declarator (); + return parsed ? + semantic ().introduce_exception () : (CTree*)0; +} + +bool CCSyntax::exception_decl () { + return parse (&CCSyntax::rule_exception_decl); +} + +CTree *CCSyntax::rule_throw_expr () { + // 1: THROW + // 2: THROW ass_expr + return (parse (TOK_THROW) && opt (AssExpr::check (*this))) ? + builder ().throw_expr () : (CTree*)0; +} + +bool CCSyntax::throw_expr () { + return parse (&CCSyntax::rule_throw_expr); +} + +CTree *CCSyntax::rule_exception_spec () { + // 3: THROW ( ) + // 4: THROW ( ... ) // MS VC++ extension :( + // 4: THROW ( type_id_list ) + if (! (parse (TOK_THROW) && parse (TOK_OPEN_ROUND))) + return (CTree*)0; + semantic ().enter_exception_spec (); + if ((parse (TOK_ELLIPSIS) || type_id_list (), + parse (TOK_CLOSE_ROUND))) + return semantic ().exception_spec (); + semantic ().leave_exception_spec (); + return (CTree*)0; +} + +bool CCSyntax::exception_spec () { + return parse (&CCSyntax::rule_exception_spec); +} + +CTree *CCSyntax::rule_type_id_list () { + // 1 : type_id + // 3+: type_id , type_id .. + return list (&CCSyntax::type_id, TOK_COMMA) ? + builder ().type_id_list () : (CTree*)0; +} + +bool CCSyntax::type_id_list () { + return parse (&CCSyntax::rule_type_id_list); +} + +} // namespace Puma diff --git a/Puma/src/parser/ccparser/CCSyntax.h b/Puma/src/parser/ccparser/CCSyntax.h new file mode 100644 index 0000000..ed57024 --- /dev/null +++ b/Puma/src/parser/ccparser/CCSyntax.h @@ -0,0 +1,715 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CCSyntax_h__ +#define __CCSyntax_h__ + +// Parser for the C++ programming language + +#include "Puma/CSyntax.h" + +namespace Puma { + + +class CCSemantic; +class CCBuilder; +class CStructure; + +class CCSyntax : public CSyntax { + friend class CCSemantic; + int _skip_bodies; + + enum { + SKIP_BODIES_NONE = 0x0, // don't skip function bodies + SKIP_BODIES_ALL = 0x1, // skip all function bodies + SKIP_BODIES_TPL = 0x2, // skip function bodies of templates + SKIP_BODIES_NON_PRJ = 0x4, // skip bodies of non-project functions + SKIP_BODIES_NON_PRIM = 0x8 // skip bodies in non-primary files + }; + +public: + CCSyntax (CCBuilder &, CCSemantic &); + + virtual Grammar grammar () const { return GRAMMAR_CPLUSPLUS; } + + virtual void configure (Config &); + + void config_skip_fct_body (bool s) { + if (s) _skip_bodies |= SKIP_BODIES_ALL; + else _skip_bodies ^= (_skip_bodies & SKIP_BODIES_ALL); + } + +protected: + CCBuilder &builder () const; + CCSemantic &semantic () const; + + // TODO: no idea why this can't be introduce by CCLookAhead.ah + // Specific look-ahead functions + virtual bool is_fct_def (); + virtual bool is_nested_name (); + virtual bool is_class_def (); + virtual bool is_tpl_id (); + virtual bool is_tpl_declarator_id (); + virtual bool is_ptr_to_fct (); + virtual bool is_nested (State); + virtual bool is_ass_expr (); + + virtual void init_prim_types (); + virtual void init_cv_quals (); + + virtual void init_explicit_instantiation (); + virtual void init_explicit_specialization (); + virtual void init_access_spec (); + virtual void init_oper_fct_id (); + virtual void init_template_key (); + virtual void init_template_id (); + virtual void init_class_template_id (); + + // Grammar rules +public: + + // A.1 Keywords + struct ClassName { + static inline bool check (CCSyntax &s) { return s.class_name (); } + static inline bool parse (CCSyntax &); + }; + virtual bool class_name (); + + struct EnumName { + static inline bool check (CCSyntax &s) { return s.enum_name (); } + static inline bool parse (CCSyntax &); + }; + virtual bool enum_name (); + + struct TemplateName { + static inline bool check (CCSyntax &s) { return s.template_name (); } + static inline bool parse (CCSyntax &); + }; + virtual bool template_name (); + + struct ClassTemplateName { + static inline bool check (CCSyntax &s) { return s.class_template_name (); } + static inline bool parse (CCSyntax &); + }; + virtual bool class_template_name (); + + struct NamespaceName { + static inline bool check (CCSyntax &s) { return s.namespace_name (); } + static inline bool parse (CCSyntax &); + }; + virtual bool namespace_name (); + + struct OriginalNsName { + static inline bool check (CCSyntax &s) { return s.original_ns_name (); } + static inline bool parse (CCSyntax &); + }; + virtual bool original_ns_name (); + + struct NamespaceAlias { + static inline bool check (CCSyntax &s) { return s.namespace_alias (); } + static inline bool parse (CCSyntax &); + }; + virtual bool namespace_alias (); + + // A.2 Lexical conventions + struct Literal { + static inline bool check (CCSyntax &s) { return s.literal (); } + static inline bool parse (CCSyntax &); + }; + virtual bool literal (); + + // A.4 Expression + struct PrimExpr { + static inline bool check (CCSyntax &s) { return s.prim_expr (); } + static inline bool parse (CCSyntax &); + }; + virtual bool prim_expr (); + + struct IdExpr { + static inline bool check (CCSyntax &s) { return s.id_expr (); } + static inline bool parse (CCSyntax &); + }; + virtual bool id_expr (); + + struct QualId { + static inline bool check (CCSyntax &s) { return s.qual_id (); } + static inline bool parse (CCSyntax &); + }; + virtual bool qual_id (); + + struct UnqualId { + static inline bool check (CCSyntax &s) { return s.unqual_id (); } + static inline bool parse (CCSyntax &); + }; + virtual bool unqual_id (); + + struct ColonColon { + static inline bool check (CCSyntax &s) { return s.colon_colon (); } + static inline bool parse (CCSyntax &); + }; + virtual bool colon_colon (); + + struct NestedNameSpec { + static inline bool check (CCSyntax &s) { return s.nested_name_spec (); } + static inline bool parse (CCSyntax &); + }; + virtual bool nested_name_spec (); + + struct NestedNameSpec1 { + static inline bool check (CCSyntax &s) { return s.nested_name_spec1 (); } + static inline bool parse (CCSyntax &); + }; + virtual bool nested_name_spec1 (); + + struct ClassOrNsName { + static inline bool check (CCSyntax &s) { return s.class_or_ns_name (); } + static inline bool parse (CCSyntax &); + }; + virtual bool class_or_ns_name (); + + struct PostfixExpr { + static inline bool check (CCSyntax &s) { return s.postfix_expr (); } + static inline bool parse (CCSyntax &); + }; + virtual bool postfix_expr (); + + struct PostfixExpr1 { + static inline bool check (CCSyntax &s) { return s.postfix_expr1 (); } + static inline bool parse (CCSyntax &); + }; + virtual bool postfix_expr1 (); + + struct PostfixExpr2 { + static inline bool check (CCSyntax &s) { return s.postfix_expr2 (); } + static inline bool parse (CCSyntax &); + }; + virtual bool postfix_expr2 (); + + struct ConstructExpr { + static inline bool check (CCSyntax &s) { return s.construct_expr (); } + static inline bool parse (CCSyntax &); + }; + virtual bool construct_expr (); + + struct PseudoDtorName { + static inline bool check (CCSyntax &s) { return s.pseudo_dtor_name (); } + static inline bool parse (CCSyntax &); + }; + virtual bool pseudo_dtor_name (); + + struct UnaryExpr { + static inline bool check (CCSyntax &s) { return s.unary_expr (); } + static inline bool parse (CCSyntax &); + }; + virtual bool unary_expr (); + + struct TypeTraitExpr { + static inline bool check (CCSyntax &s) { return s.type_trait_expr (); } + static inline bool parse (CCSyntax &); + }; + virtual bool type_trait_expr (); + + struct NewExpr { + static inline bool check (CCSyntax &s) { return s.new_expr (); } + static inline bool parse (CCSyntax &); + }; + virtual bool new_expr (); + + struct NewPlacement { + static inline bool check (CCSyntax &s) { return s.new_placement (); } + static inline bool parse (CCSyntax &); + }; + virtual bool new_placement (); + + struct NewTypeId { + static inline bool check (CCSyntax &s) { return s.new_type_id (); } + static inline bool parse (CCSyntax &); + }; + virtual bool new_type_id (); + + struct NewDeclarator { + static inline bool check (CCSyntax &s) { return s.new_declarator (); } + static inline bool parse (CCSyntax &); + }; + virtual bool new_declarator (); + + struct DirectNewDeclarator { + static inline bool check (CCSyntax &s) { return s.direct_new_declarator (); } + static inline bool parse (CCSyntax &); + }; + virtual bool direct_new_declarator (); + + struct DirectNewDeclarator1 { + static inline bool check (CCSyntax &s) { return s.direct_new_declarator1 (); } + static inline bool parse (CCSyntax &); + }; + virtual bool direct_new_declarator1 (); + + struct NewInit { + static inline bool check (CCSyntax &s) { return s.new_init (); } + static inline bool parse (CCSyntax &); + }; + virtual bool new_init (); + + struct DeleteExpr { + static inline bool check (CCSyntax &s) { return s.delete_expr (); } + static inline bool parse (CCSyntax &); + }; + virtual bool delete_expr (); + + struct PmExpr { + static inline bool check (CCSyntax &s) { return s.pm_expr (); } + static inline bool parse (CCSyntax &); + }; + virtual bool pm_expr (); + + struct MulExpr { + static inline bool check (CCSyntax &s) { return s.mul_expr (); } + static inline bool parse (CCSyntax &); + }; + virtual bool mul_expr (); + + struct RelExpr { + static inline bool check (CCSyntax &s) { return s.rel_expr (); } + static inline bool parse (CCSyntax &); + }; + virtual bool rel_expr (); + + struct CondExpr { + static inline bool check (CCSyntax &s) { return s.cond_expr (); } + static inline bool parse (CCSyntax &); + }; + virtual bool cond_expr (); + + struct AssExpr { + static inline bool check (CCSyntax &s) { return s.ass_expr (); } + static inline bool parse (CCSyntax &); + }; + virtual bool ass_expr (); + + struct AssExpr1 { + static inline bool check (CCSyntax &s) { return s.ass_expr1 (); } + static inline bool parse (CCSyntax &); + }; + virtual bool ass_expr1 (); + + struct ConstExpr { + static inline bool check (CCSyntax &s) { return s.const_expr (); } + static inline bool parse (CCSyntax &); + }; + virtual bool const_expr (); + + // A.5 Statements + struct Stmt { + static inline bool check (CCSyntax &s) { return s.stmt (); } + static inline bool parse (CCSyntax &); + }; + virtual bool stmt (); + + struct StmtSeq { + static inline bool check (CCSyntax &s) { return s.stmt_seq (); } + static inline bool parse (CCSyntax &); + }; + virtual bool stmt_seq (); + + struct SubStmt { + static inline bool check (CCSyntax &s) { return s.sub_stmt (); } + static inline bool parse (CCSyntax &); + }; + virtual bool sub_stmt (); + + struct Condition { + static inline bool check (CCSyntax &s) { return s.condition (); } + static inline bool parse (CCSyntax &); + }; + virtual bool condition (); + + struct Condition1 { + static inline bool check (CCSyntax &s) { return s.condition1 (); } + static inline bool parse (CCSyntax &); + }; + virtual bool condition1 (); + + struct Condition2 { + static inline bool check (CCSyntax &s) { return s.condition2 (); } + static inline bool parse (CCSyntax &); + }; + virtual bool condition2 (); + + struct DeclStmt { + static inline bool check (CCSyntax &s) { return s.decl_stmt (); } + static inline bool parse (CCSyntax &); + }; + virtual bool decl_stmt (); + + // A.6 Declarations + + struct Decl { + static inline bool check (CCSyntax &s) { return s.decl (); } + static inline bool parse (CCSyntax &); + }; + virtual bool decl (); + // helper function, which is needed, because ac++ can't weave in templates :-( + virtual bool decl_check (); + + struct BlockDecl { + static inline bool check (CCSyntax &s) { return s.block_decl (); } + static inline bool parse (CCSyntax &); + }; + virtual bool block_decl (); + + struct SimpleDecl { + static inline bool check (CCSyntax &s) { return s.simple_decl (); } + static inline bool parse (CCSyntax &); + }; + virtual bool simple_decl (); + + struct DeclSpecSeq1 { + static inline bool check (CCSyntax &s) { return s.decl_spec_seq1 (); } + static inline bool parse (CCSyntax &); + }; + virtual bool decl_spec_seq1 (); + + struct MiscSpec { + static inline bool check (CCSyntax &s) { return s.misc_spec (); } + static inline bool parse (CCSyntax &); + }; + virtual bool misc_spec (); + + struct StorageClassSpec { + static inline bool check (CCSyntax &s) { return s.storage_class_spec (); } + static inline bool parse (CCSyntax &); + }; + virtual bool storage_class_spec (); + + struct FctSpec { + static inline bool check (CCSyntax &s) { return s.fct_spec (); } + static inline bool parse (CCSyntax &); + }; + virtual bool fct_spec (); + + struct SimpleTypeSpec { + static inline bool check (CCSyntax &s) { return s.simple_type_spec (); } + static inline bool parse (CCSyntax &); + }; + virtual bool simple_type_spec (); + + struct TypeName { + static inline bool check (CCSyntax &s) { return s.type_name (); } + static inline bool parse (CCSyntax &); + }; + virtual bool type_name (); + + struct ElaboratedTypeSpec { + static inline bool check (CCSyntax &s) { return s.elaborated_type_spec (); } + static inline bool parse (CCSyntax &); + }; + virtual bool elaborated_type_spec (); + + struct EnumeratorList { + static inline bool check (CCSyntax &s) { return s.enumerator_list (); } + static inline bool parse (CCSyntax &); + }; + virtual bool enumerator_list (); + + struct EnumeratorDef { + static inline bool check (CCSyntax &s) { return s.enumerator_def (); } + static inline bool parse (CCSyntax &); + }; + virtual bool enumerator_def (); + + struct LinkageSpec { + static inline bool check (CCSyntax &s) { return s.linkage_spec (); } + static inline bool parse (CCSyntax &); + }; + virtual bool linkage_spec (); + + // A.6.1 Namespaces + struct NamespaceDef { + static inline bool check (CCSyntax &s) { return s.namespace_def (); } + static inline bool parse (CCSyntax &); + }; + virtual bool namespace_def (); + + struct NamedNsDef { + static inline bool check (CCSyntax &s) { return s.named_ns_def (); } + static inline bool parse (CCSyntax &); + }; + virtual bool named_ns_def (); + + struct OriginalNsDef { + static inline bool check (CCSyntax &s) { return s.original_ns_def (); } + static inline bool parse (CCSyntax &); + }; + virtual bool original_ns_def (); + + struct OriginalNsDef1 { + static inline bool check (CCSyntax &s) { return s.original_ns_def1 (); } + static inline bool parse (CCSyntax &); + }; + virtual bool original_ns_def1 (); + + struct ExtensionNsDef { + static inline bool check (CCSyntax &s) { return s.extension_ns_def (); } + static inline bool parse (CCSyntax &); + }; + virtual bool extension_ns_def (); + + struct ExtensionNsDef1 { + static inline bool check (CCSyntax &s) { return s.extension_ns_def1 (); } + static inline bool parse (CCSyntax &); + }; + virtual bool extension_ns_def1 (); + + struct UnnamedNsDef { + static inline bool check (CCSyntax &s) { return s.unnamed_ns_def (); } + static inline bool parse (CCSyntax &); + }; + virtual bool unnamed_ns_def (); + + struct UnnamedNsDef1 { + static inline bool check (CCSyntax &s) { return s.unnamed_ns_def1 (); } + static inline bool parse (CCSyntax &); + }; + virtual bool unnamed_ns_def1 (); + + struct NamespaceBody { + static inline bool check (CCSyntax &s) { return s.namespace_body (); } + static inline bool parse (CCSyntax &); + }; + virtual bool namespace_body (); + + struct NsAliasDef { + static inline bool check (CCSyntax &s) { return s.ns_alias_def (); } + static inline bool parse (CCSyntax &); + }; + virtual bool ns_alias_def (); + + struct QualNsSpec { + static inline bool check (CCSyntax &s) { return s.qual_ns_spec (); } + static inline bool parse (CCSyntax &); + }; + virtual bool qual_ns_spec (); + + struct UsingDecl { + static inline bool check (CCSyntax &s) { return s.using_decl (); } + static inline bool parse (CCSyntax &); + }; + virtual bool using_decl (); + + struct UsingDirective { + static inline bool check (CCSyntax &s) { return s.using_directive (); } + static inline bool parse (CCSyntax &); + }; + virtual bool using_directive (); + + // A.7 Declarators + struct InitDeclarator { + static inline bool check (CCSyntax &s) { return s.init_declarator (); } + static inline bool parse (CCSyntax &); + }; + virtual bool init_declarator (); + + struct DirectDeclarator1 { + static inline bool check (CCSyntax &s) { return s.direct_declarator1 (); } + static inline bool parse (CCSyntax &); + }; + virtual bool direct_declarator1 (); + + struct ArrayDelim { + static inline bool check (CCSyntax &s) { return s.array_delim (); } + static inline bool parse (CCSyntax &); + }; + virtual bool array_delim (); + + struct PtrOperator { + static inline bool check (CCSyntax &s) { return s.ptr_operator (); } + static inline bool parse (CCSyntax &); + }; + virtual bool ptr_operator (); + + struct DeclaratorId { + static inline bool check (CCSyntax &s) { return s.declarator_id (); } + static inline bool parse (CCSyntax &); + }; + virtual bool declarator_id (); + + struct DirectAbstDeclarator { + static inline bool check (CCSyntax &s) { return s.direct_abst_declarator (); } + static inline bool parse (CCSyntax &); + }; + virtual bool direct_abst_declarator (); + + struct ParamDeclClause { + static inline bool check (CCSyntax &s) { return s.param_decl_clause (); } + static inline bool parse (CCSyntax &); + }; + virtual bool param_decl_clause (); + + CTree * rule_param_decl (); + virtual bool param_decl (); + CTree * rule_param_init (); + virtual bool param_init (); + CTree * rule_fct_def (); + virtual bool fct_def (); + CTree * rule_skipped_fct_body (); + virtual bool skipped_fct_body (); + CTree * rule_fct_body (); + virtual bool fct_body (); + CTree * rule_init (); + virtual bool init (); + CTree * rule_init_clause (); + virtual bool init_clause (); + + // A.8 Classes + CTree *rule_class_spec (); + virtual bool class_spec (); + + struct ClassHead { + static inline bool check (CCSyntax &s) { return s.class_head (); } + static inline bool parse (CCSyntax &); + }; + virtual bool class_head (); + + struct ClassHead1 { + static inline bool check (CCSyntax &s) { return s.class_head1 (); } + static inline bool parse (CCSyntax &); + }; + virtual bool class_head1 (); + + CTree * rule_member_decl (); + virtual bool member_decl (); + CTree * rule_member_decl1 (); + virtual bool member_decl1 (); + CTree * rule_access_decl (); + virtual bool access_decl (); + CTree * rule_member_declarator (); + virtual bool member_declarator (); + CTree * rule_pure_spec (); + virtual bool pure_spec (); + CTree * rule_const_init (); + virtual bool const_init (); + + // A.9 Derived classes + CTree * rule_base_clause (); + virtual bool base_clause (); + CTree * rule_base_spec_list (); + virtual bool base_spec_list (); + CTree * rule_base_spec (); + virtual bool base_spec (); + CTree * rule_access_spec (); + virtual bool access_spec (); + + // A.10 Special member functions + struct ConvFctId { + static inline bool check (CCSyntax &s) { return s.conv_fct_id (); } + static inline bool parse (CCSyntax &); + }; + virtual bool conv_fct_id (); + + struct ConvTypeId { + static inline bool check (CCSyntax &s) { return s.conv_type_id (); } + static inline bool parse (CCSyntax &); + }; + virtual bool conv_type_id (); + + CTree * rule_conv_declarator (); + virtual bool conv_declarator (); + CTree * rule_ctor_init (); + virtual bool ctor_init (); + CTree * rule_mem_init_list (); + virtual bool mem_init_list (); + CTree * rule_mem_init (); + virtual bool mem_init (); + CTree * rule_mem_init_id (); + virtual bool mem_init_id (); + + // A.11 Overloading + CTree *rule_oper_fct_id (); + virtual bool oper_fct_id (); + + // A.12 Templates + CTree * rule_template_key (); + virtual bool template_key (); + CTree * rule_template_decl (); + virtual bool template_decl (); + CTree * rule_member_template_decl (); + virtual bool member_template_decl (); + CTree * rule_template_param_list (); + virtual bool template_param_list (); + CTree * rule_template_param (); + virtual bool template_param (); + CTree * rule_type_param (); + virtual bool type_param (); + CTree * rule_non_type_param (); + virtual bool non_type_param (); + CTree *rule_template_id (); + virtual bool template_id (); + CTree *rule_class_template_id (); + virtual bool class_template_id (); + CTree * rule_template_arg_list (); + virtual bool template_arg_list (); + CTree * rule_template_arg (); + virtual bool template_arg (); + CTree * rule_template_type_arg (); + virtual bool template_type_arg (); + CTree * rule_template_non_type_arg (); + virtual bool template_non_type_arg (); + CTree * rule_template_template_arg (); + virtual bool template_template_arg (); + CTree * rule_explicit_instantiation (); + virtual bool explicit_instantiation (); + CTree * rule_explicit_specialization (); + virtual bool explicit_specialization (); + + // A.13 Exception handling + CTree * rule_try_block (); + virtual bool try_block (); + CTree * rule_fct_try_block (); + virtual bool fct_try_block (); + CTree * rule_handler_seq (); + virtual bool handler_seq (); + CTree * rule_handler (); + virtual bool handler (); + CTree * rule_exception_decl (); + virtual bool exception_decl (); + CTree * rule_throw_expr (); + virtual bool throw_expr (); + CTree * rule_exception_spec (); + virtual bool exception_spec (); + CTree * rule_type_id_list (); + virtual bool type_id_list (); + +protected: + void skip_param_init (); + void skip_ctor_init (); + void skip_fct_body (); + void skip_fct_try_block (); + void skip_const_expr (); + void skip_const_init (); + +protected: + struct SearchScope { CStructure *scope, *last_scope; bool dep; }; + void get_search_scope (SearchScope &); + void set_search_scope (SearchScope &); +}; + + +} // namespace Puma + +#endif /* __CCSyntax_h__ */ diff --git a/Puma/src/parser/ccparser/DelayedParseTree.h b/Puma/src/parser/ccparser/DelayedParseTree.h new file mode 100644 index 0000000..70efb6c --- /dev/null +++ b/Puma/src/parser/ccparser/DelayedParseTree.h @@ -0,0 +1,213 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __delayed_parse_tree_h__ +#define __delayed_parse_tree_h__ + +/** \file + * Delayed parse syntax tree classes. */ + +namespace Puma { + + +// Syntax tree node hierarchy: +class CTree; +class CT_DelayedParse; +class CT_DelayedParseParamInit; +class CT_DelayedParseFctTryBlock; +class CT_DelayedParseCtorInit; +class CT_DelayedParsePureSpec; +class CT_DelayedParseFctBody; +class CT_DelayedParseSkippedFctBody; +class CT_DelayedParseConstInit; + + +} // namespace Puma + +#include "Puma/CTree.h" +#include "Puma/TokenProvider.h" +#include "Puma/CRecord.h" +#include "Puma/CStructure.h" + +namespace Puma { + + +/** \class CT_DelayedParse DelayedParseTree.h Puma/DelayedParseTree.h + * Tree node representing a piece of code to be parsed delayed. */ +class CT_DelayedParse : public CTree { + CRecord* _Class; + CStructure* _Scope; + TokenProvider::State _State; + CTree* sons[2]; + +protected: + /** Constructor. + * \param s Start token. */ + CT_DelayedParse (Token* s) : _Class(0), _Scope(0) { + AddSon (sons[0], new CT_Token(s)); + AddSon (sons[1], 0); + } + /** Constructor. + * \param s Start token. + * \param e End token. */ + CT_DelayedParse (Token* s, Token* e) : _Class(0), _Scope(0) { + AddSon (sons[0], new CT_Token(s)); + AddSon (sons[1], new CT_Token(e)); + } + +public: + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get a pointer to this CT_DelayedParse. + * \return The CT_DelayedParse pointer. */ + CT_DelayedParse *IsDelayedParse () { return this; } + /** Get the number of sons. */ + int Sons () const { return sons[1] ? 2 : 1; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 2, n); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 2, old_son, new_son); + } + /** Get the outermost class for this delayed code fragment. */ + CRecord* Class () const { return (CRecord*)_Class; } + /** Get the scope of the delayed code fragment. */ + CStructure* Scope () const { return (CStructure*)_Scope; } + /** Get the token stream state of the delayed code fragment. */ + TokenProvider::State State() const { return (TokenProvider::State&)_State; } + /** Set the outermost class for this delayed code fragment. + * \param record The outermost class. */ + void Class (CRecord* record) { _Class = record; } + /** Set the scope of the delayed code fragment. + * \param scope The scope. */ + void Scope (CStructure* scope) { _Scope = scope; } + /** Set the token stream state of the delayed code fragment. + * \param state The token stream state. */ + void State (TokenProvider::State state) { _State = state; } +}; + + +/** \class CT_DelayedParseParamInit DelayedParseTree.h Puma/DelayedParseTree.h + * Tree node representing a delayed parameter initializer. */ +class CT_DelayedParseParamInit : public CT_DelayedParse { +public: + /** Constructor. + * \param s Start token. */ + CT_DelayedParseParamInit (Token* s) : CT_DelayedParse (s) {} + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } +}; + + +/** \class CT_DelayedParseFctTryBlock DelayedParseTree.h Puma/DelayedParseTree.h + * Tree node representing a delayed function try-block. */ +class CT_DelayedParseFctTryBlock : public CT_DelayedParse, CT_HandlerSeq { +public: + /** Constructor. + * \param s Start token. */ + CT_DelayedParseFctTryBlock (Token* s) : CT_DelayedParse (s) {} + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } +}; + + +/** \class CT_DelayedParseCtorInit DelayedParseTree.h Puma/DelayedParseTree.h + * Tree node representing a delayed constructor initializer. */ +class CT_DelayedParseCtorInit : public CT_DelayedParse { +public: + /** Constructor. + * \param s Start token. */ + CT_DelayedParseCtorInit (Token* s) : CT_DelayedParse (s) {} + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } +}; + + +/** \class CT_DelayedParsePureSpec DelayedParseTree.h Puma/DelayedParseTree.h + * Tree node representing a delayed pure specifier. */ +class CT_DelayedParsePureSpec : public CT_DelayedParse { +public: + /** Constructor. + * \param s Start token. */ + CT_DelayedParsePureSpec (Token* s) : CT_DelayedParse (s) {} + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } +}; + + +/** \class CT_DelayedParseFctBody DelayedParseTree.h Puma/DelayedParseTree.h + * Tree node representing a delayed function body. */ +class CT_DelayedParseFctBody : public CT_DelayedParse, CT_CmpdStmt { +public: + /** Constructor. + * \param s Start token. + * \param e End token. */ + CT_DelayedParseFctBody (Token* s, Token* e) : CT_DelayedParse (s, e) {} + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } +}; + + +/** \class CT_DelayedParseSkippedFctBody DelayedParseTree.h Puma/DelayedParseTree.h + * Tree node representing a delayed skipped function body. */ +class CT_DelayedParseSkippedFctBody : public CT_DelayedParse, CT_CmpdStmt { +public: + /** Constructor. + * \param s Start token. + * \param e End token. */ + CT_DelayedParseSkippedFctBody (Token* s, Token* e) : CT_DelayedParse (s, e) {} + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } +}; + + +/** \class CT_DelayedParseConstInit DelayedParseTree.h Puma/DelayedParseTree.h + * Tree node representing a delayed constant initializer. */ +class CT_DelayedParseConstInit : public CT_DelayedParse, CT_ExprList { +public: + /** Constructor. + * \param s Start token. */ + CT_DelayedParseConstInit (Token* s) : CT_DelayedParse (s) {} + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } +}; + + +} // namespace Puma + +#endif /* __delayed_parse_tree_h__ */ diff --git a/Puma/src/parser/ccparser/instantiation/CCInstantiation.cc b/Puma/src/parser/ccparser/instantiation/CCInstantiation.cc new file mode 100644 index 0000000..1b4131e --- /dev/null +++ b/Puma/src/parser/ccparser/instantiation/CCInstantiation.cc @@ -0,0 +1,513 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CCInstantiation.h" +#include "Puma/CCSemVisitor.h" +#include "Puma/CStructure.h" +#include "Puma/CClassInstance.h" +#include "Puma/CUnionInstance.h" +#include "Puma/CFctInstance.h" +#include "Puma/CNamespaceInfo.h" +#include "Puma/CTemplateInfo.h" +#include "Puma/CTemplateParamInfo.h" +#include "Puma/CTree.h" +#include "Puma/PreTreeNodes.h" +#include "Puma/CCOverloading.h" +#include "Puma/CConstant.h" +#include "Puma/CCConversions.h" +#include "Puma/CCParser.h" +#include "Puma/TokenStream.h" +#include "Puma/UnitManager.h" +#include "Puma/CSemDatabase.h" +#include "Puma/PreMacroManager.h" +#include "Puma/PreprocessorParser.h" +#include "Puma/CFileInfo.h" +#include "Puma/CSourceInfo.h" +#include "Puma/CCConversions.h" +#include "Puma/InstantiationParser.h" + +#include /* sprintf() */ +#include /* strtol() */ +#include /* ostringstream */ + +namespace Puma { + + +#define SEM_ERROR(loc__,mesg__) \ + {if (report) {\ + err << sev_error << loc__->token ()->location () \ + << mesg__ << endMessage;}} + + +CCInstantiation::CCInstantiation (ErrorSink &e, bool rep) : err (e) { + instance = 0; + last_instance = 0; + report = rep; + current_scope = 0; + + base_candidate = new InstantiationCandidate; + candidates[0] = base_candidate; + base_candidate->initialize (rep ? &e : (ErrorSink*)0); +} + + +CCInstantiation::~CCInstantiation () { + for (long i = 0; i < candidates.length (); i++) { + InstantiationCandidate *candidate = candidates.lookup (i); + if (candidate == base_candidate) + base_candidate = 0; + delete candidate; + } + if (base_candidate) + delete base_candidate; +} + + +// start instantiation process +CObjectInfo *CCInstantiation::instantiate (CTree *node, + CObjectInfo *binfo, bool real_inst, CStructure *cs, bool inst_immediately) { + // don't call twice + if (instance || ! binfo || ! node) + return instance; + + First ().initialize (node, binfo); + current_scope = cs; + + if (real_inst && ! First ().canBeInstantiated ()) + real_inst = false; + + // §14.8.2 deduce template arguments + if (! First ().deduceArguments (real_inst)) { + return instance; + } + + // choose the appropriate template specialization (if any) + if (! chooseSpecialization ()) { + return instance; + } + + // instantiate template if not already done before + if (! alreadyInstantiated (real_inst)) { + // create an instance of the template + createPseudoInstance (); + + if (instance) { + instance->TemplateInstance ()->canInstantiate (real_inst); + if (real_inst && inst_immediately) { + instance = instance->TemplateInstance ()->instantiate (cs) ? instance : 0; + } + } + } + + return instance; +} + + +// §14.5.4.1 matching of template partial specializations +bool CCInstantiation::chooseSpecialization () { + bool no_default; + unsigned entries; + CObjectInfo *info; + CTemplateInfo *tinfo; + CT_TemplateName *name; + CT_TemplateArgList *args; + + // only class templates can be partially specialized + if (ObjectInfo ()->FunctionInfo ()) + return true; + + // there are no known specializations if we are parsing a template + // and access a template template parameter + if (ObjectInfo ()->TemplateParamInfo ()) + return true; + + // find all specializations + std::list specializations; + CTemplateInfo *curr_template = TemplateInfo (); + do { + for (unsigned i = 0; i < curr_template->Specializations (); i++) { + tinfo = curr_template->Specialization (i); + specializations.push_back(tinfo); + } + // find next connected template declaration/definition + if (!curr_template->ObjectInfo ()) { + break; + } + CObjectInfo *next = curr_template->ObjectInfo ()->NextObject (); + if (!next || next->TemplateInstance () || !next->ClassInfo () || !next->Template ()) { + break; + } + curr_template = next->Template (); + } while (curr_template != TemplateInfo ()); + + // handle each specialization + for (std::list::iterator i = specializations.begin(); + i != specializations.end (); ++i) { + tinfo = *i; + if (! tinfo->ObjectInfo ()) // internal error + continue; + info = tinfo->ObjectInfo ()->DefObject (); + name = tinfo->SpecializationName (); + if (! name) // internal error + continue; + args = name->Arguments (); + if (! args) // internal error + continue; + + // create new instantiation candidate + InstantiationCandidate *cand = new InstantiationCandidate; + cand->initialize (PointOfInstantiation (), info, tinfo, report ? &err : (ErrorSink*)0); + + // add the template arguments of the partial specialization + entries = args->Entries (); + for (unsigned j = 0; j < entries; j++) + cand->addArgument (args->Entry (j)); + + // add default arguments of the base template if not overwritten + no_default = false; + for (unsigned j = entries; j < TemplateInfo ()->Parameters (); j++) { + // no default argument? this is an error + if (! TemplateInfo ()->Parameter (j)->DefaultArgument ()) { + no_default = true; + cand->reset (); + delete cand; + break; + } + CTree* arg = (j < DeducedArgs () ? DeducedArg (j)->TemplateArg () : 0); + cand->addArgument (arg ? arg : TemplateInfo ()->Parameter (j)->DefaultArgument ()); + } + if (no_default) + continue; + + // §14.5.4.1.2 try to match the partial specialization + // against the actual template argument list + if (! cand->match (First())) { + // does not match, not a candidate for instantiation + cand->reset (); + delete cand; + } else { + candidates[candidates.length ()] = cand; + } + } + + // if exactly one matching specialization is found, the + // instantiation is generated from that specialization + if (candidates.length () == 2) { + // remove the base template as candidate + candidates.remove (0); + // if more than one specialization is matching, the + // best specialization is chosen using the partial + // ordering rules (§14.5.4.2 and §14.5.5.2) + } else if (candidates.length () > 2) { + return chooseBestSpecialization (); + } + + return true; +} + + +bool CCInstantiation::chooseBestSpecialization () { + // run a tournament to choose the best specialization + // comparing two specializations using the partial + // ordering rules (§14.5.4.2 and §14.5.5.2) + InstantiationCandidate *challenger, *champion; + unsigned num; + + num = candidates.length (); + champion = candidates.lookup (num-1); + for (unsigned i = num-1; i > 1; i--) { + // current challenger + challenger = candidates.lookup (i-1); + + // let the champion face the challenger + switch (champion->compare (*challenger)) { + // champion has won the round + case 1: + // elliminate challenger + delete candidates.lookup (i-1); + candidates.remove (i-1); + break; + // challenger has won the round + case -1: + // elliminate old champion + delete candidates.lookup (i); + candidates.remove (i); + // challenger is the new champion + champion = challenger; + break; + // challenger and champion are equal + default: + // case 0: ambiguous up till now + champion = challenger; + break; + } + } + + // verify that the champion is better than all other remaining + // candidates (the champion did not yet faced) + for (unsigned i = candidates.length (); i > 1; i--) { + challenger = candidates.lookup (i-1); + if (challenger == champion) + continue; + + if (champion->compare (*challenger) == 1) { + delete candidates.lookup (i-1); + candidates.remove (i-1); + } + } + + // if exactly one specialization left over, the + // instantiation is generated from that specialization + if (candidates.length () == 2) { + // remove the base template as candidate + candidates.remove (0); + return true; + } + + // more than one specialization left over, + // so the instantiation is ambiguous + if (report) { + std::ostringstream name; + name << ObjectInfo ()->Name (); + base_candidate->printArgumentList (name); + err << sev_error << getPoiToken()->location () + << "Instantiation of `" << name.str ().c_str () + << "' is ambiguous" << endMessage; + for (int i = 1; i < candidates.length (); i++) { + InstantiationCandidate *cand = candidates[i]; + if (cand->ObjectInfo ()->Tree () && cand->ObjectInfo ()->Tree ()->token ()) + err << cand->ObjectInfo ()->Tree ()->token ()->location (); + if (i == 1) + err << "candidates are: "; + else + err << " "; + err << name.str ().c_str () << endMessage; + } + } + + return false; +} + + +bool CCInstantiation::alreadyInstantiated (bool real_inst) { + last_instance = 0; + for (unsigned i = 0; i < TemplateInfo ()->Instances (); i++) { + CObjectInfo *ti = TemplateInfo ()->Instance (i); + bool cont = false; + + if ((TemplateInfo ()->isBaseTemplate () == + ti->TemplateInstance ()->Template ()->isBaseTemplate ()) && + (DeducedArgs () == ti->TemplateInstance ()->DeducedArgs ())) { + for (unsigned j = 0; j < ti->TemplateInstance ()->DeducedArgs (); j++) + if (*DeducedArg (j) != *ti->TemplateInstance ()->DeducedArg (j)) + cont = true; + } else + cont = true; + + if (! cont) { + instance = ti; + if ((ti->FunctionInfo () && ti->FunctionInfo ()->isFctDef ()) || + (ti->Record () && ti->Record ()->isDefined ())) { + last_instance = 0; + return true; + } else + last_instance = ti; + } + } + + instance = 0; + if (last_instance) { + if (real_inst && + ((ObjectInfo ()->FunctionInfo () && ObjectInfo ()->FunctionInfo ()->isFctDef ()) || + (ObjectInfo ()->Record () && ObjectInfo ()->Record ()->isDefined ()))) + return false; + instance = last_instance; + last_instance = 0; + return true; + } + return false; +} + + +void CCInstantiation::createPseudoInstance () { + CTemplateInstance *ti = 0; + CStructure* scope = InstanceScope () ? InstanceScope () : First ().createInstanceScope (); + + if (ObjectInfo ()->FunctionInfo ()) { + instance = scope->newFunction (true); + instance->FunctionInfo ()->isConstructor (ObjectInfo ()->FunctionInfo ()->isConstructor ()); + instance->FunctionInfo ()->isDestructor (ObjectInfo ()->FunctionInfo ()->isDestructor ()); + instance->FunctionInfo ()->isOperator (ObjectInfo ()->FunctionInfo ()->isOperator ()); + instance->FunctionInfo ()->isConversion (ObjectInfo ()->FunctionInfo ()->isConversion ()); + if (instance->FunctionInfo ()->isConversion ()) { + instance->FunctionInfo ()->ConversionType (ObjectInfo ()->FunctionInfo ()->ConversionType ()); + } + ti = instance->TemplateInstance (); + } else if (ObjectInfo ()->UnionInfo ()) { + instance = scope->newUnion (true); + ti = instance->TemplateInstance (); + } else if (ObjectInfo ()->ClassInfo ()) { + instance = scope->newClass (true); + ti = instance->TemplateInstance (); + } else if (ObjectInfo ()->TemplateParamInfo ()) { + instance = ObjectInfo ()->TemplateParamInfo ()->TemplateTemplate ()->newTemplateParam (false); + instance->TemplateParamInfo ()->TemplateInfo (ObjectInfo ()->TemplateParamInfo ()->TemplateInfo ()); + instance->TemplateParamInfo ()->TemplateInstance (new CTemplateInstance); + instance->TemplateParamInfo ()->isTypeParam (ObjectInfo ()->TemplateParamInfo ()->isTypeParam ()); + instance->TemplateParamInfo ()->ValueType (ObjectInfo ()->TemplateParamInfo ()->ValueType ()->Duplicate ()); + instance->TemplateParamInfo ()->TemplateTemplate (ObjectInfo ()->TemplateParamInfo ()->TemplateTemplate ()); + ObjectInfo ()->NextObject (instance); + ti = instance->TemplateParamInfo ()->TemplateInstance (); + } else { + return; // unsupported object type + } + + instance->Name (ObjectInfo ()->Name ()); + instance->SourceInfo ()->FileInfo (ObjectInfo ()->SourceInfo ()->FileInfo ()); + instance->SourceInfo ()->StartToken (PointOfInstantiation ()->token_node ()); + instance->TypeInfo (ObjectInfo ()->TypeInfo ()->Duplicate ()); + instance->Specifiers (ObjectInfo ()->Specifiers ()); + instance->Protection (ObjectInfo ()->Protection ()); + instance->Linkage (ObjectInfo ()->Linkage ()); + instance->Storage (ObjectInfo ()->Storage ()); + instance->Language ().Type (ObjectInfo ()->Language ().Type ()); + instance->isVirtual (ObjectInfo ()->isVirtual ()); + instance->isStatic (ObjectInfo ()->isStatic ()); + instance->isThreadLocal (ObjectInfo ()->isThreadLocal ()); + instance->isExtern (ObjectInfo ()->isExtern ()); + instance->isMutable (ObjectInfo ()->isMutable ()); + instance->isRegister (ObjectInfo ()->isRegister ()); + instance->isExplicit (ObjectInfo ()->isExplicit ()); + instance->isInline (ObjectInfo ()->isInline ()); + instance->isAuto (ObjectInfo ()->isAuto ()); + instance->AssignedScope (ObjectInfo ()->AssignedScope ()); + + if (ObjectInfo ()->QualifiedScope ()) { + if (instance->FunctionInfo ()) + instance->FunctionInfo ()->QualifiedScope (ObjectInfo ()->QualifiedScope ()); + else if (instance->Record ()) + instance->Record ()->QualifiedScope (ObjectInfo ()->QualifiedScope ()); + } + + ti->PointOfInstantiation (PointOfInstantiation (), current_scope); + ti->Template (TemplateInfo ()); + ti->Object (instance); + ti->isPseudoInstance (true); + + if (instance->FunctionInfo ()) + instance->TypeInfo ()->TypeFunction ()->FunctionInfo (instance->FunctionInfo ()); + else if (instance->TemplateParamInfo ()) + instance->TypeInfo ()->TypeTemplateParam ()->TemplateParamInfo (instance->TemplateParamInfo ()); + else + instance->TypeInfo ()->TypeRecord ()->Record (instance->Record ()); + + for (unsigned i = 0; i < DeducedArgs (); i++) + ti->addDeducedArg (DeducedArg (i)); + for (unsigned i = 0; i < base_candidate->DeducedArgs (); i++) + ti->addInstantiationArg (base_candidate->DeducedArg (i)); + + First ().TemplateInstance (ti); + First ().forgetDeducedArgs (); + + if (base_candidate != &First ()) { + base_candidate->forgetDeducedArgs (); + } + + TemplateInfo ()->addInstance (instance); +} + + +void CCInstantiation::setupFromPseudoInstance (CTemplateInstance* instinfo, CStructure* scope) { + instance = instinfo->Object (); + current_scope = (scope && scope == instance) ? scope->Parent ()->Structure () : scope; + CObjectInfo* obj = instinfo->Template ()->ObjectInfo (); + if (! obj->FunctionInfo ()) + obj = obj->DefObject (); + base_candidate->initialize (instinfo->PointOfInstantiation (), obj, obj->Template ()); + for (unsigned i = 0; i < instinfo->DeducedArgs (); i++) + base_candidate->addDeducedArg (instinfo->DeducedArg (i)); + for (unsigned i = 0; i < instinfo->InstantiationArgs (); i++) + base_candidate->addInstantiationArg (instinfo->InstantiationArg (i)); + base_candidate->TemplateInstance (instinfo); +} + + +bool CCInstantiation::instantiate (CTemplateInstance* instinfo, CStructure* instscope) { + // setup from the pseudo instance information to + // reset the correct instantiation information + setupFromPseudoInstance(instinfo, instscope); + + // check maximal instantiation depth + if (First().maxInstDepthReached()) { + First().forgetDeducedArgs(); + removeInstance(); + return false; + } + + // instantiate now + CTree* tree = First().instantiate(this); + + // report errors and clean up + if (!tree || First().getParser().failed()) { + if (report && First().getParser().failed()) { + First().printInstantiationErrorHeader(getPoiToken()); + First().getParser().builder().errors(err); + } + removeInstance(); + } + + First().forgetDeducedArgs(); + return instance; +} + + +Token* CCInstantiation::getPoiToken(CTemplateInstance* ti) { + Token* tok = 0; + if (ti) { + CTree* poi = ti->PointOfInstantiation(); + do { + tok = poi->token(); + } while (! tok && (poi = poi->Parent())); + } + else { + tok = First().getPointOfInstantiationToken(); + } + return tok; +} + + +void CCInstantiation::insertInstance (CObjectInfo *info) { + if (info && info->TemplateInstance ()) { + instance = info; + instance->TemplateInstance ()->isInstantiated (true); + if (last_instance && last_instance != instance) + instance->NextObject (last_instance); + } +} + + +void CCInstantiation::removeInstance () { + if (instance && TemplateInfo()) { + instance->TemplateInstance ()->isInstantiated (false); + TemplateInfo()->removeInstance(instance); + } + instance = 0; +} + + +} // namespace Puma diff --git a/Puma/src/parser/ccparser/instantiation/CCInstantiation.h b/Puma/src/parser/ccparser/instantiation/CCInstantiation.h new file mode 100644 index 0000000..b845926 --- /dev/null +++ b/Puma/src/parser/ccparser/instantiation/CCInstantiation.h @@ -0,0 +1,138 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CCInstantiation__ +#define __CCInstantiation__ + +#include "Puma/Array.h" +#include "Puma/ErrorSink.h" +#include "Puma/DeducedArgument.h" +#include "Puma/InstantiationCandidate.h" +#include + +namespace Puma { + + +class Token; +class CTree; +class CTypeInfo; +class CConstant; +class CStructure; +class CT_Program; +class CT_ExprList; +class CObjectInfo; +class CT_SimpleName; +class CT_TemplateName; +class CTemplateInfo; +class CTemplateParamInfo; +class CCOverloading; + +class CCInstantiation { + typedef Array CandArray; + + ErrorSink &err; + CObjectInfo *instance; + CObjectInfo *last_instance; + bool report; + CStructure *current_scope; + CandArray candidates; + InstantiationCandidate *base_candidate; + +public: + CCInstantiation (ErrorSink &, bool = true); + ~CCInstantiation (); + + CObjectInfo *instantiate (CTree *, CObjectInfo *, bool = true, CStructure * = 0, bool inst_immediately = false); + + bool instantiate (CTemplateInstance *pseudo_instance, CStructure* scope); + bool detectedDelayedParseProblem (); + + CObjectInfo *ObjectInfo (); + CStructure *InstanceScope (); + CObjectInfo *Instance () const; + CStructure *Scope () const; + void addArgument (CTree *); + + void insertInstance (CObjectInfo *); + void removeInstance (); + + void printInstantiationHeader(); + +private: + InstantiationCandidate &First (); + CTemplateInfo *TemplateInfo (); + CTree *PointOfInstantiation (); + Token *getPoiToken(CTemplateInstance* ti = 0); + + unsigned Arguments (); + unsigned DeducedArgs (); + CTree *Argument (unsigned); + DeducedArgument *DeducedArg (unsigned); + + bool deduceArguments (bool); + bool deduceArguments (unsigned); + void deduceArguments (CTypeInfo *, CTypeInfo *, Array &); + + bool chooseSpecialization (); + bool chooseBestSpecialization (); + + void setupFromPseudoInstance (CTemplateInstance* pseudo_instance, CStructure* scope); + void createPseudoInstance (); + bool alreadyInstantiated (bool); + + int getPosition (CTemplateParamInfo *); + + bool maxInstDepthReached (); +}; + +inline CObjectInfo *CCInstantiation::Instance () const + { return instance; } +inline CStructure *CCInstantiation::Scope () const + { return current_scope; } + +inline InstantiationCandidate &CCInstantiation::First () + { return *candidates.lookup (0); } +inline CObjectInfo *CCInstantiation::ObjectInfo () + { return First ().ObjectInfo (); } +inline CTemplateInfo *CCInstantiation::TemplateInfo () + { return First ().TemplateInfo (); } +inline CStructure *CCInstantiation::InstanceScope () + { return First ().InstanceScope (); } +inline CTree *CCInstantiation::PointOfInstantiation () + { return First ().PointOfInstantiation (); } +inline bool CCInstantiation::detectedDelayedParseProblem () + { return First ().detectedDelayedParseNode (); } + +inline unsigned CCInstantiation::Arguments () + { return First ().Arguments (); } +inline unsigned CCInstantiation::DeducedArgs () + { return First ().DeducedArgs (); } +inline CTree *CCInstantiation::Argument (unsigned i) + { return First ().Argument (i); } +inline DeducedArgument *CCInstantiation::DeducedArg (unsigned i) + { return First ().DeducedArg (i); } + +inline void CCInstantiation::addArgument (CTree *a) + { First ().addArgument (a); } + +inline void CCInstantiation::printInstantiationHeader() + { First().printInstantiationHeader(); } + +} // namespace Puma + +#endif /* __CCInstantiation__ */ diff --git a/Puma/src/parser/ccparser/instantiation/DeducedArgument.cc b/Puma/src/parser/ccparser/instantiation/DeducedArgument.cc new file mode 100644 index 0000000..38871cf --- /dev/null +++ b/Puma/src/parser/ccparser/instantiation/DeducedArgument.cc @@ -0,0 +1,100 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/DeducedArgument.h" +#include "Puma/CTemplateParamInfo.h" +#include "Puma/CCSemExpr.h" + +namespace Puma { + + +DeducedArgument::DeducedArgument (CTemplateParamInfo *p, CTypeInfo *t, CTree *a, bool da, bool dia) { + del = false; + type = t->Duplicate (); + value = 0; + param = p; + arg = a; + default_arg = da; + direct_arg = dia; +} + +DeducedArgument::DeducedArgument (CTemplateParamInfo *p, CConstant *v, CTree *a, bool da, bool dia) { + del = false; + type = 0; + value = p->ValueType () ? v->cast_to (p->ValueType ()) : v->duplicate (); + param = p; + arg = a; + default_arg = da; + direct_arg = dia; +} + +DeducedArgument::DeducedArgument (CTemplateParamInfo *p, long val) { + del = false; + type = 0; + param = p; + value = new CConstant ((LONG_LONG)val, &CTYPE_LONG); + arg = 0; + default_arg = false; + direct_arg = false; +} + +DeducedArgument::~DeducedArgument () { + if (type) + CTypeInfo::Destroy (type); + if (value) + delete value; +} + +bool DeducedArgument::equals (const DeducedArgument &a, bool matchTemplateParams) { + if ((((bool)Type ()) != ((bool)a.Type ())) || + (((bool)Value ()) != ((bool)a.Value ()))) + return false; + if (Type () && ! Type ()->equals (*a.Type (), matchTemplateParams)) + return false; + if (Value () && *Value () != *a.Value ()) + return false; + return true; +} + +void DeducedArgument::print(std::ostream &os) const { + print (os, true); +} + +void DeducedArgument::print(std::ostream &os, bool abs) const { + if (Type()) { + Type()->TypeText(os, 0, abs); + } + else if (Value()) { + CTree* arg = TemplateArg(); + CTypeInfo* type = arg ? arg->Type() : 0; + bool addr = arg ? CCSemExpr::isAddrExpr(arg) : false; + if (addr || (type && (type->isArray() || type->isFunction()))) { + // ��14.3.2 address as non-type template argument + CObjectInfo* obj = CCSemExpr::findObject(arg); + if (obj) + os << (addr ? "&" : "") << obj->QualName(abs); + else + os << *Value(); + } else { + os << *Value(); + } + } +} + + +} // namespace Puma diff --git a/Puma/src/parser/ccparser/instantiation/DeducedArgument.h b/Puma/src/parser/ccparser/instantiation/DeducedArgument.h new file mode 100644 index 0000000..b27b746 --- /dev/null +++ b/Puma/src/parser/ccparser/instantiation/DeducedArgument.h @@ -0,0 +1,89 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __DeducedArgument__ +#define __DeducedArgument__ + +#include "Puma/CTypeInfo.h" +#include "Puma/CConstant.h" +#include "Puma/Printable.h" +#include + +namespace Puma { + + +class CTemplateParamInfo; +class CTree; + +struct DeducedArgument : public Printable { + CTypeInfo *type; + CConstant *value; + CTemplateParamInfo *param; + CTree *arg; + bool del; + bool default_arg; + bool direct_arg; + +public: + DeducedArgument (CTemplateParamInfo *, CTypeInfo *, CTree * = 0, bool = false, bool = false); + DeducedArgument (CTemplateParamInfo *, CConstant *, CTree * = 0, bool = false, bool = false); + DeducedArgument (CTemplateParamInfo *, long); + ~DeducedArgument (); + + bool operator ==(const DeducedArgument &); + bool operator !=(const DeducedArgument &); + bool equals (const DeducedArgument &, bool matchTemplateParams = false); + + CTypeInfo *Type () const; + CConstant *Value () const; + CTemplateParamInfo *TemplateParam () const; + CTree *TemplateArg () const; + bool isDefaultArg () const; + bool isDirectArg () const; + + /** Print the deduced argument, i.e. the type or constant value. + * \param os The output stream. */ + virtual void print (std::ostream &os) const; + + /** Print the deduced argument, i.e. the type or constant value. + * \param os The output stream. + * \param abs If 'true' names are printed with absolute names (leading '::')*/ + void print (std::ostream &os, bool abs) const; +}; + +inline CTypeInfo *DeducedArgument::Type () const + { return type; } +inline CConstant *DeducedArgument::Value () const + { return value; } +inline CTemplateParamInfo *DeducedArgument::TemplateParam () const + { return param; } +inline CTree *DeducedArgument::TemplateArg () const + { return arg; } +inline bool DeducedArgument::isDefaultArg () const + { return default_arg; } +inline bool DeducedArgument::isDirectArg () const + { return direct_arg; } +inline bool DeducedArgument::operator ==(const DeducedArgument &d) + { return equals (d); } +inline bool DeducedArgument::operator !=(const DeducedArgument &d) + { return ! equals (d); } + + +} // namespace Puma + +#endif /* __DeducedArgument__ */ diff --git a/Puma/src/parser/ccparser/instantiation/InstantiationBuilder.h b/Puma/src/parser/ccparser/instantiation/InstantiationBuilder.h new file mode 100644 index 0000000..ed8e7c5 --- /dev/null +++ b/Puma/src/parser/ccparser/instantiation/InstantiationBuilder.h @@ -0,0 +1,35 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __InstantiationBuilder_h__ +#define __InstantiationBuilder_h__ + +#include "Puma/CCBuilder.h" + +namespace Puma { + + +class InstantiationBuilder : public CCBuilder { +public: + InstantiationBuilder () {} +}; + + +} // namespace Puma + +#endif /* __InstantiationBuilder_h__ */ diff --git a/Puma/src/parser/ccparser/instantiation/InstantiationCandidate.cc b/Puma/src/parser/ccparser/instantiation/InstantiationCandidate.cc new file mode 100644 index 0000000..399734d --- /dev/null +++ b/Puma/src/parser/ccparser/instantiation/InstantiationCandidate.cc @@ -0,0 +1,1956 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/InstantiationCandidate.h" +#include "Puma/InstantiationParser.h" +#include "Puma/CStructure.h" +#include "Puma/CClassInstance.h" +#include "Puma/CUnionInstance.h" +#include "Puma/CFctInstance.h" +#include "Puma/CNamespaceInfo.h" +#include "Puma/CTemplateInfo.h" +#include "Puma/CTemplateParamInfo.h" +#include "Puma/CTree.h" +#include "Puma/CCOverloading.h" +#include "Puma/CConstant.h" +#include "Puma/CCConversions.h" +#include "Puma/CCParser.h" +#include "Puma/TokenStream.h" +#include "Puma/UnitManager.h" +#include "Puma/CSemDatabase.h" +#include "Puma/PreMacroManager.h" +#include "Puma/PreprocessorParser.h" +#include "Puma/CFileInfo.h" +#include "Puma/CSourceInfo.h" +#include "Puma/CCConversions.h" +#include "Puma/CCSemExpr.h" +#include "Puma/CAttributeInfo.h" +#include "Puma/CTypedefInfo.h" +#include "Puma/CMemberAliasInfo.h" +#include "Puma/CArgumentInfo.h" +#include +#include + +namespace Puma { + + +/*DEBUG*/int TRACE_INSTANCE_CODE = 0; +/*DEBUG*/int TRACE_PARSE_INSTANCE = 0; + + +#define SEM_ERROR(loc__,mesg__) \ + { \ + if (err) { \ + (*err) << sev_error << loc__->token ()->location () \ + << mesg__ << endMessage; \ + } \ + } + + +InstantiationCandidate::InstantiationCandidate () { + obj_info = 0; + tpl_info = 0; + poi = 0; + err = 0; + inst_scope = 0; + instance = 0; + parser = 0; + detected_delayed_parse_node = false; +} + + +InstantiationCandidate::~InstantiationCandidate () { + for (long i = 0; i < darguments.length (); i++) + if (darguments[i]) + delete darguments[i]; + if (parser) + delete parser; +} + + +void InstantiationCandidate::reset () { + obj_info = 0; + tpl_info = 0; + poi = 0; + err = 0; + inst_scope = 0; + + if (parser) { + delete parser; + parser = 0; + } + + for (long i = 0; i < darguments.length (); i++) + if (darguments[i]) + delete darguments[i]; + + arguments.reset (); + darguments.reset (); + iarguments.reset (); + detected_delayed_parse_node = false; +} + + +void InstantiationCandidate::initialize (ErrorSink *e) { + err = e; +} + + +void InstantiationCandidate::initialize (CTree *p, CObjectInfo *o) { + poi = p; + obj_info = o; +} + + +void InstantiationCandidate::initialize (CTree *p, CObjectInfo *o, CTemplateInfo *t, ErrorSink *e) { + poi = p; + obj_info = o; + tpl_info = t; + err = e ? e : err; +} + + +void InstantiationCandidate::TemplateInstance (CTemplateInstance *i) { + instance = i; + if (instance) + inst_scope = instance->Object()->Scope()->Structure(); +} + + +int InstantiationCandidate::getPosition (CTemplateParamInfo *param) const { + for (unsigned i = 0; i < tpl_info->Parameters (); i++) + if (*param == *tpl_info->Parameter (i)) + return i; + return -1; +} + + +CProject* InstantiationCandidate::getProject() { + return obj_info->SemDB()->Project(); +} + + +CTemplateParamInfo* InstantiationCandidate::getMatchingParameter (CTemplateParamInfo *param) { + if (tpl_info && param && param->TemplateInfo () != tpl_info) { + int pos = param->getPosition (); + if (pos >= 0 && pos < (int)tpl_info->Parameters ()) + param = tpl_info->Parameter (pos); + else + param = 0; + } + return param; +} + + +bool InstantiationCandidate::canBeInstantiated () { + // template instantiation disabled? + if (getProject()->config().Option("--pseudo-instances")) + return false; + // point of instantiation depends on template parameter? + CTree* name = poi; + if (name->NodeName () == CT_QualName::NodeId () || + name->NodeName () == CT_RootQualName::NodeId ()) + name = ((CT_QualName*)name)->Name (); + if (name->NodeName () == CT_TemplateName::NodeId ()) + if (CCSemExpr::isDependent(((CT_TemplateName*)name)->Arguments ())) + return false; + // everything OK + return true; +} + + +// ��14.8.2 deduce template arguments (if necessary) +bool InstantiationCandidate::deduceArguments (bool real_inst) { + // check if template really can be instantiated + if (real_inst && ! canBeInstantiated()) + real_inst = false; + + CTree* name = poi; + if (name->NodeName () == CT_QualName::NodeId () || + name->NodeName () == CT_RootQualName::NodeId ()) + name = ((CT_QualName*)name)->Name (); + + // template arguments + CT_TemplateArgList *args; + unsigned numargs; + if (name->NodeName () == CT_TemplateName::NodeId ()) { + args = ((CT_TemplateName*)name)->Arguments (); + numargs = args->Entries (); + } else { + args = 0; + numargs = 0; + } + + // get template parameter list information + if (obj_info->TemplateParamInfo ()) + tpl_info = obj_info->TemplateParamInfo ()->TemplateTemplate (); + else + tpl_info = obj_info->Template (); + if (! tpl_info) { + if (real_inst) { + SEM_ERROR (poi, "fatal error: missing template parameter information"); + return false; + } + return true; + } + + // check number of template arguments for function templates + if (obj_info->FunctionInfo () && numargs > tpl_info->Parameters ()) { + if (real_inst) { + SEM_ERROR (poi, "wrong number of template arguments (" + << numargs << ", should be " << tpl_info->Parameters () << ")"); + return false; + } + return true; + } + + // calculate index of first parameter for which no direct template + // argument or default template argument is given + unsigned pos = 0; + for (; pos < tpl_info->Parameters(); pos++) { + CTemplateParamInfo *param = tpl_info->Parameter(pos); + if (pos >= numargs) { + // no direct template argument for the current parameter, + // check default template arguments for non-function templates + if (! obj_info->FunctionInfo()) { + // not a function template, check default argument + if (! param->DefaultArgument()) { + // no default argument + if (real_inst) { + SEM_ERROR(poi, "missing default argument for parameter " << pos+1); + return false; + } + return true; + } + } else { + // function template parameters do not have default arguments, + // ommited arguments must be deduced from the function call + // argument list + break; + } + } + } + + // deduce the direct and default arguments + if (! (real_inst ? parseDirectArguments(pos, numargs, args) : + matchDirectArguments(pos, numargs, args))) { + return false; + } + + if (pos < tpl_info->Parameters()) { + // deduce remaining arguments from function call + return deduceArgumentsFromFctCall(pos); + } + return true; +} + + +bool InstantiationCandidate::matchDirectArguments (unsigned pos, unsigned numargs, CT_TemplateArgList *args) { + // match direct and default template arguments + for (unsigned i = 0; i < pos; i++) { + CTemplateParamInfo *param = tpl_info->Parameter (i); + bool is_default_arg = (i >= numargs); + CObjectInfo* oinfo = 0; + CTree *arg; + + if (is_default_arg) { + // default template argument + arg = param->DefaultArgument (); + } else { + // direct template argument + arg = args->Entry (i); + } + + // template template parameter: expect name of class base template + if (param->isTemplate ()) { + if (arg->SemObject () && (oinfo = arg->SemObject ()->Object ()) && oinfo->TypeInfo ()) + darguments.append (new DeducedArgument (param, + oinfo->TypeInfo ()->VirtualType (), arg, is_default_arg, !is_default_arg)); + } + // template type parameter: expect type-id + else if (param->isTypeParam ()) { + if (arg->SemObject () && (oinfo = arg->SemObject ()->Object ()) && oinfo->TypeInfo ()) + darguments.append (new DeducedArgument (param, + oinfo->TypeInfo ()->VirtualType (), arg, is_default_arg, !is_default_arg)); + } + // template non-type parameter: expect constant expression + else { + if (arg->Type () && arg->Type ()->TypeTemplateParam () && + arg->Type ()->TypeTemplateParam ()->isNonType ()) { + // template non-type parameter as argument + darguments.append (new DeducedArgument (param, + arg->Type (), arg, is_default_arg, !is_default_arg)); + } + else if (arg->Value () && arg->Value ()->Constant ()) { + darguments.append (new DeducedArgument (param, + arg->Value ()->Constant (), arg, is_default_arg, !is_default_arg)); + } + } + } + return true; +} + + +// ��14.8.2 deduce template arguments from function call +bool InstantiationCandidate::deduceArgumentsFromFctCall (unsigned skip, bool exact_match, bool partial_ordering) { + DeducedArgumentList dargs (tpl_info->Parameters ()); + CTypeInfo *atype, *ptype; + CFunctionInfo *finfo; + CTypeList *fargs; + unsigned numargs; + bool succeeded; + CTree *arg; + int ret; + + succeeded = true; + finfo = obj_info->FunctionInfo (); + fargs = finfo->TypeInfo ()->ArgTypes (); + numargs = Arguments (); + + // compare number of function arguments and parameters + if (fargs->Entries () > numargs) { + if (! partial_ordering) + numargs = fargs->Entries (); + } + else if (fargs->Entries () < numargs) { + if (finfo->hasEllipsis ()) { + numargs = fargs->Entries () - 1; + } + else { + if (! partial_ordering) { + SEM_ERROR (poi, "too many arguments in call to function `" + << finfo->Name () << "'"); + return false; + } + numargs = fargs->Entries (); + } + } + + // prepare temporary deduced argument container + for (unsigned i = 0; i < tpl_info->Parameters (); i++) + dargs.append (0); + + // iterate and analyse arguments + for (unsigned i = 0; i < numargs && succeeded; i++) { + // consider default arguments for function parameters + if (i >= Arguments ()) { + if (! finfo->hasDefaultArgument (i)) { + if (! partial_ordering) { + SEM_ERROR (poi, "too few arguments in call to function `" + << finfo->Name () << "'"); + return false; + } + break; // ignore default arguments when doing partial ordering + } + else { + arg = finfo->Argument(i)->Tree (); + // arg = finfo->DefaultArgument (i); + } + } else + arg = Argument (i); + + atype = arg->Type () ? arg->Type () : arg->SemObject ()->Object ()->TypeInfo (); + ptype = fargs->Entry (i); + + if (atype->TypeAddress ()) { + atype = atype->NonReferenceType (); + } + if (ptype->TypeAddress ()) { + ptype = ptype->NonReferenceType (); + } else { + // ��14.3.2.5 implicit argument type conversions + atype = atype->VirtualType (); + ptype = ptype->VirtualType (); + // array-to-pointer and function-to-pointer conversions + if (atype->isArray () || atype->isFunction ()) { + atype = atype->isArray () ? atype->VirtualType ()->BaseType () : atype; + // TODO: Delete this type if done and not used! + atype = new CTypePointer (atype->Duplicate ()); + } + } + + ret = deduceArguments (ptype, atype, dargs, exact_match, partial_ordering); + if (ret == 1 || ret == 3) { + succeeded = false; + } + } + + for (unsigned i = skip; i < (unsigned)dargs.length () && succeeded; i++) { + if (! dargs[i]) { + SEM_ERROR (poi, "could not deduce argument for parameter " << i+1); + succeeded = false; + } else + darguments.append (dargs[i]); + } + + return succeeded; +} + + +// return 0 if all ok, 1 if ambiguous type for parameter, 2 if types don't match, 3 if more specialized +int InstantiationCandidate::deduceArguments (CTypeInfo *ftype, CTypeInfo *atype, DeducedArgumentList &dargs, bool exact_match, bool partial_ordering) { + int ret; + + if (atype->TypeTemplateParam ()) { + for (unsigned i = 0; i < (unsigned)dargs.length (); i++) { + if (dargs[i] && *dargs[i]->TemplateParam ()->TypeInfo () == *atype) { + atype = dargs[i]->Type (); + } + } + } + + // template parameter + if (ftype->TypeTemplateParam ()) { + return deduceTemplateParam (ftype, atype, dargs, exact_match, partial_ordering); + } + + // deduce from qualified type + if (ftype->TypeQualified ()) { + return deduceFromQualifiedType (ftype, atype, dargs, exact_match, partial_ordering); + } + + // types must be equal to deduce template arguments + if (ftype->Id () != atype->Id ()) { + return exact_match ? 2 : (partial_ordering && atype->TypeTemplateParam ()) ? 3 : ftype->isDependent () ? 1 : 0; + } + + // nothing to deduce + if (ftype->TypeEmpty () || ftype->TypePrimitive ()) { + return 0; + } + + // deduce from pointer to class member + if (ftype->TypeMemberPointer ()) { + return deduceFromMemberPointer (ftype, atype, dargs, exact_match, partial_ordering); + + // deduce from class or union type + } else if (ftype->TypeRecord ()) { + return deduceFromRecord (ftype, atype, dargs, exact_match, partial_ordering); + + // deduce from array type + } else if (ftype->TypeArray ()) { + if ((ret = deduceFromArray (ftype, atype, dargs, exact_match, partial_ordering)) != 0) { + return ret; + } + + // deduce from function type + } else if (ftype->TypeFunction ()) { + if ((ret = deduceFromFunction (ftype, atype, dargs, exact_match, partial_ordering)) != 0) { + return ret; + } + } + + // deduce from the base types, types must match exactly + return deduceArguments (ftype->BaseType (), atype->BaseType (), dargs, exact_match, partial_ordering); +} + + +CTypeQualified* InstantiationCandidate::getQualifiers (CTypeInfo* type) { + if (type->UnqualType ()->TypeArray ()) { + do { + type = type->UnqualType ()->BaseType (); + } while (type->UnqualType ()->TypeArray ()); + } + return type->TypeQualified (); +} + + +CTypeInfo* InstantiationCandidate::setQualification (CTypeInfo* type, bool is_const, bool is_volatile, bool is_restrict) { + CTypeQualified* qual = type->TypeQualified (); + CTypeInfo* parent = 0; + if (type->UnqualType ()->TypeArray ()) { + parent = type->UnqualType (); + while (parent->BaseType ()->UnqualType ()->TypeArray ()) + parent = parent->BaseType ()->UnqualType (); + qual = parent->BaseType ()->TypeQualified (); + } + if (!is_const && !is_volatile && !is_restrict) { + // remove all qualifiers + type = type->UnqualType (); + if (parent && qual) + parent->BaseType (qual->BaseType ()); + if (qual) + delete qual; + } + else if (! qual) { + // create qualifiers + qual = new CTypeQualified (parent ? parent->BaseType () : type, is_const, is_volatile, is_restrict); + if (parent) + parent->BaseType (qual); + else + type = qual; + } + else { + // set qualifiers + qual->isConst (is_const); + qual->isVolatile (is_volatile); + qual->isRestrict (is_restrict); + } + return type; +} + + +// return 0 if all ok, 1 if ambiguous type for parameter, 2 if types don't match, 3 if more specialized +int InstantiationCandidate::deduceFromQualifiedType (CTypeInfo *ftype, CTypeInfo *atype, DeducedArgumentList &dargs, bool exact_match, bool partial_ordering) { + CTypeQualified* fqt = ftype->TypeQualified (); + CTypeQualified* aqt = atype->TypeQualified (); + + bool ftype_is_tpl_param = ftype->UnqualType ()->TypeTemplateParam (); + + // get qualifiers of array element type, if an array + if (ftype_is_tpl_param) + aqt = getQualifiers (atype); + + // exact match required: qualifiers must be the same + if (exact_match) { + if (! aqt || fqt->isConst () != aqt->isConst () || fqt->isVolatile () != aqt->isVolatile ()) { + return 2; + } + + atype = atype->UnqualType (); + if (atype->TypeArray ()) { + atype = setQualification (atype->Duplicate (), false, false, false); + int ret = deduceArguments (ftype->UnqualType (), atype, dargs, exact_match, partial_ordering); + CTypeInfo::Destroy (atype); + return ret; + } else + return deduceArguments (ftype->UnqualType (), atype, dargs, exact_match, partial_ordering); + } + + // ordinary parameter type + if (! ftype_is_tpl_param) { + // only matches if equal or more qualified than the argument type + if (! CCConversions::equalOrMoreQualified (ftype, atype)) { + return 0; + } + + // deduce from the unqualified versions of the types + return deduceArguments (ftype->UnqualType (), atype->UnqualType (), dargs, exact_match, partial_ordering); + } + // more specialized + else if (partial_ordering && atype->UnqualType ()->TypeTemplateParam () && + ! CCConversions::equalOrMoreQualified (atype, ftype)) { + return 3; + } + + // qualified template parameter type, remove all equal qualifiers + // from the argument type + + bool only_arg_has_const = aqt && aqt->isConst () && ! fqt->isConst (); + bool only_arg_has_volatile = aqt && aqt->isVolatile () && ! fqt->isVolatile (); + + // argument type is less or equal unqualified than parameter type + // remove all qualifiers from argument type + if (! only_arg_has_const && ! only_arg_has_volatile) { + atype = atype->UnqualType (); + if (atype->TypeArray ()) { + atype = setQualification (atype->Duplicate (), false, false, false); + int ret = deduceArguments (ftype->UnqualType (), atype, dargs, exact_match, partial_ordering); + CTypeInfo::Destroy (atype); + return ret; + } else + return deduceArguments (ftype->UnqualType (), atype, dargs, exact_match, partial_ordering); + } + + // argument type is not full qualified but more qualified than parameter type + // remove no qualifier from argument type + else if (! (aqt->isConst () && aqt->isVolatile ())) { + return deduceArguments (ftype->UnqualType (), atype, dargs, exact_match, partial_ordering); + } + + // argument type is full qualified and more qualified than parameter type + // remove the qualifier from argument type that also the parameter type has + else { + atype = setQualification (atype->Duplicate (), only_arg_has_const, only_arg_has_volatile, aqt->isRestrict ()); + int ret = deduceArguments (ftype->UnqualType (), atype, dargs, exact_match, partial_ordering); + CTypeInfo::Destroy (atype); + return ret; + } +} + + +// return 0 if all ok, 1 if ambiguous type for parameter, 2 if types don't match, 3 if more specialized +int InstantiationCandidate::deduceFromFunction (CTypeInfo *ftype, CTypeInfo *atype, DeducedArgumentList &dargs, bool exact_match, bool partial_ordering) { + CTypeFunction *fft = ftype->TypeFunction (); + CTypeFunction *aft = atype->TypeFunction (); + + // number of function parameters must be equal + if (fft && aft && fft->ArgTypes ()->Entries () == aft->ArgTypes ()->Entries ()) { + CTypeList *ftl = fft->ArgTypes (); + CTypeList *atl = aft->ArgTypes (); + + bool matching_args = true; + bool ambiguous_type = false; + bool more_specialized = false; + DeducedArgumentList curr_dargs; + + // prepare temporary deduced argument container + for (unsigned i = 0; i < tpl_info->Parameters (); i++) { + curr_dargs.append (0); + } + + // deduce from the function parameters + for (unsigned i = 0; i < ftl->Entries () && matching_args && ! ambiguous_type; i++) { + switch (deduceArguments (ftl->Entry (i), atl->Entry (i), dargs, true, partial_ordering)) { + case 3: more_specialized = true; break; + case 2: matching_args = false; break; + case 1: ambiguous_type = true; break; + default: break; + } + } + + // join the deduced template arguments if possible + if (! joinDeducedArguments (dargs, curr_dargs, matching_args, ambiguous_type)) { + return matching_args && ambiguous_type ? 1 : + exact_match && ! matching_args ? 2 : + more_specialized ? 3 : 0; + } + + // different number of function parameters + } else if (exact_match) { + return 2; + } + + return partial_ordering && atype->TypeTemplateParam () ? 3 : 0; +} + + +bool InstantiationCandidate::joinDeducedArguments (DeducedArgumentList &dargs, DeducedArgumentList &curr_dargs, bool &matching_args, bool &ambiguous_type) { + // check if the current deduced template arguments are valid + if (! matching_args || ambiguous_type) { + // discard the deduced template arguments + for (long i = 0; i < curr_dargs.length (); i++) { + DeducedArgument *darg = curr_dargs.fetch (i); + if (darg) delete darg; + } + } + // if not ambiguous, add the deduced arguments to dargs + if (matching_args) { + // join the deduced template arguments + if (! ambiguous_type) { + for (long i = 0; i < curr_dargs.length (); i++) { + DeducedArgument *darg = curr_dargs.fetch (i); + if (darg && ! setDeducedArgument (dargs, i, darg)) { + ambiguous_type = true; + } + } + } + } + return matching_args && ! ambiguous_type; +} + + +// return 0 if all ok, 1 if ambiguous type for parameter, 2 if types don't match, 3 if more specialized +int InstantiationCandidate::deduceFromArray (CTypeInfo *ftype, CTypeInfo *atype, DeducedArgumentList &dargs, bool exact_match, bool partial_ordering) { + CTypeArray *array = ftype->TypeArray (); + + // array size depends on a template parameter + if (array->DepDim ()) { + CTemplateParamInfo *param = array->DepDim ()->TemplateParamInfo (); + + if (param) { + int pos = getPosition (param); + + // non-type template parameter + if (pos != -1 && ! param->isTypeParam ()) { + array = atype->TypeArray (); + + // array has dimension + if (array->Dimension ()) { + if (! setDeducedArgument (dargs, pos, new DeducedArgument (param, array->Dimension ()))) { + return 1; + } + + // match non-type template parameter for partial ordering of function templates + } else if (array->DepDim ()) { + CTemplateParamInfo *aparam = array->DepDim ()->TemplateParamInfo (); + if (aparam && + ! aparam->isTypeParam () && + ! setDeducedArgument (dargs, pos, new DeducedArgument (param, atype))) { + return 1; + } + } + } + } + + // ordinary types must be an exact match + } else if (exact_match && (*ftype != *atype)) { + return 2; + } + + return partial_ordering && atype->TypeTemplateParam () ? 3 : 0; +} + + +// return 0 if all ok, 1 if ambiguous type for parameter, 2 if types don't match, 3 if more specialized +int InstantiationCandidate::deduceTemplateParam (CTypeInfo *ftype, CTypeInfo *atype, DeducedArgumentList &dargs, bool exact_match, bool partial_ordering) { + CTemplateParamInfo *param = ftype->TypeTemplateParam ()->TemplateParamInfo (); + int ret, pos = getPosition (param); + + if (pos != -1) { + // template template parameter + if (param->isTemplate ()) { + CObjectInfo *ainfo = atype->TypeRecord () ? (CObjectInfo*)atype->TypeRecord ()->Record () : + atype->TypeTemplateParam () ? (CObjectInfo*)atype->TypeTemplateParam ()->TemplateParamInfo () : 0; + + // template parameter list must match + if (! matchingTemplateParameters (param, ainfo)) { + return exact_match ? 2 : 0; + } + + // get the template instance info of the argument, if it is an template instance + CTemplateInstance *ti = ainfo->Record () ? ainfo->TemplateInstance () : ainfo->TemplateParamInfo ()->TemplateInstance (); + CTemplateInfo *tpl = getTemplateInfo (ainfo); + + // match template instance + if (param->TemplateInstance ()) { + if (! ti) { + // not a template instance + return exact_match ? 2 : 0; + } + + // deduce from the argument list + ret = deduceArgumentsFromTemplateArgList (param->TemplateInstance (), ti, dargs, partial_ordering); + if (ret != 0) { + return ret; + } + + // matches the template itself + if (! setDeducedArgument (dargs, pos, new DeducedArgument (param, tpl->ObjectInfo ()->TypeInfo ()))) { + return 1; + } + + // template template parameter does not match template instances + } else if (ti) { + return exact_match ? 2 : 0; + + // match template itself (template name) + } else { + if (! setDeducedArgument (dargs, pos, new DeducedArgument (param, tpl->ObjectInfo ()->TypeInfo ()))) { + return 1; + } + } + + // type template parameter, matches any type + } else if (param->isTypeParam ()) { + if (! setDeducedArgument (dargs, pos, new DeducedArgument (param, atype))) { + return 1; + } + + // non-type template parameter, matches any value or non-type template parameter, + // for partial ordering of function templates + } else if (! param->isTypeParam ()) { + if (atype->TypeTemplateParam ()) { + CTemplateParamInfo *aparam = atype->TypeTemplateParam ()->TemplateParamInfo (); + if (aparam && + ! aparam->isTypeParam () && + ! setDeducedArgument (dargs, pos, new DeducedArgument (param, atype))) { + return 1; + } + } + } + } + + return 0; +} + + +bool InstantiationCandidate::matchingTemplateParameters (CTemplateParamInfo *param, CObjectInfo *ainfo) { + if (! ainfo) + return false; + + CTemplateInfo *atpl = getTemplateInfo (ainfo); + CTemplateInfo *ftpl = param->TemplateTemplate (); + + if (! ftpl && ! atpl) + return true; + if (! ftpl || ! atpl || ftpl->Parameters () != atpl->Parameters ()) + return false; + + for (unsigned i = 0; i < ftpl->Parameters (); i++) { + CTemplateParamInfo *fparam = ftpl->Parameter (i); + CTemplateParamInfo *aparam = atpl->Parameter (i); + + if (! fparam->match (*aparam)) + return false; + } + + return true; +} + + +CTemplateInfo *InstantiationCandidate::getTemplateInfo (CObjectInfo *info) { + CTemplateInfo *tpl = 0; + if (info->TemplateInstance ()) + tpl = info->TemplateInstance ()->Template (); + else if (info->Record ()) + tpl = info->Record ()->TemplateInfo (); + else if (info->TemplateParamInfo ()) + tpl = info->TemplateParamInfo ()->TemplateTemplate (); + return tpl; +} + + +// return 0 if all ok, 1 if ambiguous type for parameter, 2 if types don't match, 3 if more specialized +int InstantiationCandidate::deduceFromMemberPointer (CTypeInfo *ftype, CTypeInfo *atype, DeducedArgumentList &dargs, bool exact_match, bool partial_ordering) { + CTemplateParamInfo *param = ftype->TypeMemberPointer ()->TemplateParam (); + + // member pointer of form T::member where T is a type template parameter + if (param) { + int pos = getPosition (param); + if (pos != -1 && param->isTypeParam ()) { + + CRecord *record = atype->TypeMemberPointer ()->Record (); + + // argument type is class or union, can be deduced + if (record) { + if (! setDeducedArgument (dargs, pos, new DeducedArgument (param, record->TypeInfo ()))) { + return 1; + } + + // argument member pointer type contains template parameter, handled as unique type for + // partial ordering of function templates + } else { + CTemplateParamInfo *tp = atype->TypeMemberPointer ()->TemplateParam (); + if (tp && tp->isTypeParam () && ! setDeducedArgument (dargs, pos, new DeducedArgument (param, atype))) { + return 1; + } + } + } + + // ordinary types must match, if not the top level types + } else if (exact_match && (*ftype != *atype)) { + return 2; + } + + return partial_ordering && atype->TypeTemplateParam () ? 3 : 0; +} + + +// return 0 if all ok, 1 if ambiguous type for parameter, 2 if types don't match, 3 if more specialized +int InstantiationCandidate::deduceFromRecord (CTypeInfo *ftype, CTypeInfo *atype, DeducedArgumentList &dargs, bool exact_match, bool partial_ordering) { + CRecord *finfo = ftype->TypeRecord ()->Record (); + CRecord *ainfo = atype->TypeRecord ()->Record (); + + if (finfo && ainfo) { + // types must have same record type, i.e. either class or union + if ((finfo->ClassInfo () && ! ainfo->ClassInfo ()) || + (finfo->UnionInfo () && ! ainfo->UnionInfo ())) { + return exact_match ? 2 : partial_ordering && atype->TypeTemplateParam () ? 3 : 0; + } + + // parameter type is template instance + if (finfo->isTemplateInstance ()) { + // deduce template arguments from the type arguments of the template instances, + // the template used to instantiate finfo must be equal to the template used + // to instantiate ainfo or one of its base classes + + CTemplateInstance *fi = finfo->TemplateInstance (); + Array instances; + getTemplateInstances (ainfo, instances); // search the class hierarchy of ainfo + + bool at_least_one_match = false; + for (long j = 0; j < instances.length (); j++) { + CTemplateInstance *ai = instances.fetch (j); + + // same template and same number of template arguments + CTemplateInfo *ft = fi->Template ()->BaseTemplate () ? fi->Template ()->BaseTemplate () : fi->Template (); + CTemplateInfo *at = ai->Template ()->BaseTemplate () ? ai->Template ()->BaseTemplate () : ai->Template (); + if (*ft->ObjectInfo () != *at->ObjectInfo () || fi->InstantiationArgs () != ai->InstantiationArgs ()) { + continue; + } + + // deduce from the template arguments + int ret = deduceArgumentsFromTemplateArgList (fi, ai, dargs, partial_ordering); + if (ret == 1) { + return 1; + } + at_least_one_match = at_least_one_match || (ret == 0); + } + + // require exact match + if (! at_least_one_match) { + return 2; + } + + // ordinary types must match, if not the top level types + } else if (exact_match && (*finfo != *ainfo)) { + return 2; + } + } + + return partial_ordering && atype->TypeTemplateParam () ? 3 : 0; +} + + +// return 0 if all ok, 1 if ambiguous type for parameter, 2 if types don't match, 3 if more specialized +int InstantiationCandidate::deduceArgumentsFromTemplateArgList (CTemplateInstance *fi, CTemplateInstance *ai, DeducedArgumentList &dargs, bool partial_ordering) { + bool matching_args = true; + bool ambiguous_type = false; + bool more_specialized = false; + DeducedArgumentList curr_dargs; + + // number of template arguments must match + if (fi->InstantiationArgs () != ai->InstantiationArgs ()) { + return 2; + } + + // prepare temporary deduced argument container + for (unsigned i = 0; i < tpl_info->Parameters (); i++) { + curr_dargs.append (0); + } + + // now try to deduce from the template arguments, must match exactly + // for a successful deduction + for (unsigned i = 0; i < fi->InstantiationArgs () && matching_args && ! ambiguous_type; i++) { + CTypeInfo *fdtype = fi->InstantiationArg (i)->Type (); + CTypeInfo *adtype = ai->InstantiationArg (i)->Type (); + CConstant *fvalue = fi->InstantiationArg (i)->Value (); + CConstant *avalue = ai->InstantiationArg (i)->Value (); + + if (fdtype) { + // type template arguments + if (adtype) { + switch (deduceArguments (fdtype, adtype, curr_dargs, true, partial_ordering)) { + case 3: more_specialized = true; break; + case 2: matching_args = false; break; + case 1: ambiguous_type = true; break; + default: break; + } + + // non-type template arguments + } else if (avalue && + fdtype->TypeTemplateParam () && + ! fdtype->TypeTemplateParam ()->isTypeParam ()) { + CTemplateParamInfo *param = fdtype->TypeTemplateParam ()->TemplateParamInfo (); + if (param) { + int pos = getPosition (param); + if (pos != -1 && ! setDeducedArgument (curr_dargs, pos, new DeducedArgument (param, avalue))) { + ambiguous_type = true; + } + } + + } else { + matching_args = false; + } + + // non-type template arguments + } else if (fvalue && (! avalue || (*fvalue != *avalue))) { + matching_args = false; + } + } + + // check if deduced template arguments are valid + if (! matching_args || ambiguous_type) { + // discard the deduced template arguments + for (long i = 0; i < curr_dargs.length (); i++) { + DeducedArgument *darg = curr_dargs.fetch (i); + if (darg) delete darg; + } + } + // if not ambiguous, add the deduced arguments to dargs + if (matching_args) { + // add the deduced template arguments + if (! ambiguous_type) { + for (long i = 0; i < curr_dargs.length (); i++) { + DeducedArgument *darg = curr_dargs.fetch (i); + if (darg && ! setDeducedArgument (dargs, i, darg)) { + ambiguous_type = true; + } + } + } + return ambiguous_type ? 1 : more_specialized ? 3 : 0; + } + return 2; +} + + +void InstantiationCandidate::getTemplateInstances(CRecord* c, Array& instances) { + if (c->isTemplateInstance ()) { + instances.append (c->TemplateInstance ()); + } + CClassInfo *cl = c->ClassInfo (); + if (cl) { + for (unsigned i = 0; i < cl->BaseClasses (); i++) { + getTemplateInstances (cl->BaseClass (i)->Class (), instances); + } + } +} + + +// ��14.5.4.1.2 try to match a partial specialization +// against a given template argument list +bool InstantiationCandidate::match (InstantiationCandidate& other) { + CT_TemplateArgList *args; + CTemplateInfo *base; + CTree *arg, *parg, *name; + unsigned numargs; + + // template argument list + name = poi; + if (name->NodeName () == CT_QualName::NodeId () || + name->NodeName () == CT_RootQualName::NodeId ()) + name = ((CT_QualName*)name)->Name (); + if (name->NodeName () == CT_TemplateName::NodeId ()) { + args = ((CT_TemplateName*)name)->Arguments (); + numargs = args->Entries (); + } else { + args = 0; + numargs = 0; + } + + // prepare deduced argument container + darguments.reset (); + for (unsigned i = 0; i < tpl_info->Parameters (); i++) + darguments.append (0); + + // compare argument lists + base = tpl_info->BaseTemplate (); + for (unsigned i = 0; i < Arguments (); i++) { + // current partial specialization argument + parg = Argument (i); + + // more partial specialization arguments than arguments + // given at point of instantiation => consider default arguments + if (i >= numargs) { + if (base && base->Parameters () > i && base->Parameter (i)->DefaultArgument ()) { + if (other.DeducedArgs () > i && other.DeducedArg (i)->TemplateArg ()) + arg = other.DeducedArg (i)->TemplateArg (); + else + arg = base->Parameter (i)->DefaultArgument (); + } else { + // oops, no default argument? this is an error + return false; + } + } else + arg = args->Entry (i); + + // try to match the current argument, must be an exact match! + if (! matchArgument (parg, arg)) + return false; + } + + // check if all template parameters could be deduced while matching + for (unsigned i = 0; i < DeducedArgs (); i++) + if (! DeducedArg (i)) + return false; + + return true; +} + + +bool InstantiationCandidate::sameType (int pos, CTypeInfo *type) { + DeducedArgument *darg = darguments[pos]; + if (darg && darg->Value ()) + return false; // not a type + CTypeInfo *otype = darg ? darg->Type () : 0; + if (! type) + return false; + if (otype) { + if (otype->TypeTemplateParam () && type->TypeTemplateParam ()) { + CTemplateParamInfo *p1 = otype->TypeTemplateParam ()->TemplateParamInfo (); + CTemplateParamInfo *p2 = type->TypeTemplateParam ()->TemplateParamInfo (); + if (! p1 || ! p2 || *p1 != *p2) + return false; + } else if (*otype != *type) + return false; + } + return true; +} + + +bool InstantiationCandidate::sameValue (int pos, CConstant *value) { + DeducedArgument *darg = darguments[pos]; + if (darg && darg->Type ()) + return false; // not a value + CConstant *ovalue = darg ? darg->Value () : 0; + if (! value || (ovalue && (*ovalue != *value))) + return false; + return true; +} + + +bool InstantiationCandidate::matchArgument (CTree *pexpr, CTree *aexpr) { + CConstant *value; + + // match against value, must be equal + if (pexpr->Value () && pexpr->Value ()->Constant ()) { + if (aexpr->Value () && (value = aexpr->Value ()->Constant ()) && + (*value == *pexpr->Value ()->Constant ())) + return true; + return false; + } + + CTypeInfo *ptype = 0, *atype = 0; + if (pexpr->NodeName () == CT_NamedType::NodeId () && + pexpr->SemObject () && pexpr->SemObject ()->Object ()) + ptype = pexpr->SemObject ()->Object ()->TypeInfo (); + if (aexpr->NodeName () == CT_NamedType::NodeId () && + aexpr->SemObject () && aexpr->SemObject ()->Object ()) + atype = aexpr->SemObject ()->Object ()->TypeInfo (); + if (! ptype) + ptype = pexpr->Type (); + if (! atype) + atype = aexpr->Type (); + if (! ptype || ! atype) + return false; + + return matchArgument (ptype, atype, aexpr); +} + + +bool InstantiationCandidate::matchArgument (CTypeInfo *ptype, CTypeInfo *atype, CTree *aexpr) { + CTemplateInstance *pti, *ati; + CTemplateInfo *ptinfo, *atinfo; + CObjectInfo *pinfo, *ainfo; + CTemplateParamInfo *param, *param2; + CTypeList *ptl, *atl; + CConstant *value, *value2; + CTypeInfo *type, *type2; + CRecord *prec, *arec; + long pdim, adim; + int pos; + + // match against template parameter + if (ptype->TypeTemplateParam ()) { + param = ptype->TypeTemplateParam ()->TemplateParamInfo (); + pos = getPosition (param); + if (pos != -1) { + // template template parameter + if (param->isTemplate ()) { + if (atype->TypeTemplateParam ()) { + if (sameType (pos, atype)) { + darguments[pos] = new DeducedArgument (param, atype); + return true; + } + } else if (atype->TypeRecord ()) { + ainfo = atype->TypeRecord ()->Record (); + type = ainfo->TypeInfo (); + if (ainfo->isTemplateInstance ()) { + type = ainfo->TemplateInstance ()->Template ()->ObjectInfo ()->TypeInfo (); + } + // template parameter must always deduce to the same type + if (sameType (pos, type)) { + darguments[pos] = new DeducedArgument (param, type); + return true; + } + } + // type template parameter + } else if (param->isTypeParam ()) { + if (sameType (pos, atype)) { + darguments[pos] = new DeducedArgument (param, atype); + return true; + } + // non-type template parameter + } else if (atype->TypeTemplateParam ()) { + if (atype->TypeTemplateParam ()->isNonTypeParam ()) { + if (sameType (pos, atype)) { + darguments[pos] = new DeducedArgument (param, atype); + return true; + } + } + // non-type template parameter + } else if (aexpr) { + if (aexpr->Value () && (value = aexpr->Value ()->Constant ()) && + sameValue (pos, value)) { + darguments[pos] = new DeducedArgument (param, value); + return true; + } + } + } + return false; + } + + // non-template parameter arguments and non-value arguments + // must be equal in type + if (ptype->Id () != atype->Id ()) + return false; + + // match against primitive type, no further analyses needed + if (ptype->TypeEmpty () || ptype->TypePrimitive ()) + return true; + + // match against class or union + if (ptype->TypeRecord ()) { + pinfo = ptype->TypeRecord ()->Record (); + ainfo = atype->TypeRecord ()->Record (); + if (pinfo && ainfo) { + if (pinfo->isTemplateInstance () && ainfo->isTemplateInstance ()) { + pti = pinfo->TemplateInstance (); + ati = ainfo->TemplateInstance (); + if (pti && ati && pti->DeducedArgs () == ati->DeducedArgs ()) { + ptinfo = pti->Template (); + atinfo = ati->Template (); + if (! ptinfo || ! atinfo) + return false; + ptinfo = ptinfo->BaseTemplate () ? ptinfo->BaseTemplate () : ptinfo; + atinfo = atinfo->BaseTemplate () ? atinfo->BaseTemplate () : atinfo; + if (*ptinfo != *atinfo) + return false; + for (unsigned i = 0; i < pti->DeducedArgs (); i++) { + type = pti->DeducedArg (i)->Type (); + type2 = ati->DeducedArg (i)->Type (); + value = pti->DeducedArg (i)->Value (); + value2 = ati->DeducedArg (i)->Value (); + if (type) { + if (type->TypeTemplateParam () && + type->TypeTemplateParam ()->isNonTypeParam ()) { + param = type->TypeTemplateParam ()->TemplateParamInfo (); + if (! param || (pos = getPosition (param)) == -1) + return false; + if (type2 && type2->TypeTemplateParam ()) { + if (! type2->TypeTemplateParam ()->isNonTypeParam () || + ! sameType (pos, type2)) + return false; + darguments[pos] = new DeducedArgument (param, type2); + continue; + } else if (! value2 || ! sameValue (pos, value2)) + return false; + darguments[pos] = new DeducedArgument (param, value2); + } else if (! type2 || ! matchArgument (type, type2, 0)) + return false; + } else if (! value || ! value2 || *value != *value2) + return false; + } + return true; + } + } else if (*pinfo == *ainfo) + return true; + } + return false; + // match against pointer to class member + } else if (ptype->TypeMemberPointer ()) { + prec = ptype->TypeMemberPointer ()->Record (); + arec = atype->TypeMemberPointer ()->Record (); + param = ptype->TypeMemberPointer ()->TemplateParam (); + if (param) { + if (! arec) + return false; + type = arec->TypeInfo (); + pos = getPosition (param); + if (pos == -1 || ! param->isTypeParam () || ! sameType (pos, type)) + return false; + darguments[pos] = new DeducedArgument (param, type); + return true; + } + if ((bool)prec != (bool)arec || *prec != *arec) + return false; + // match against array + } else if (ptype->TypeArray ()) { + pdim = ptype->TypeArray ()->Dimension (); + adim = atype->TypeArray ()->Dimension (); + if (ptype->TypeArray ()->DepDim ()) { + CConstant dim ((LONG_LONG)adim, &CTYPE_LONG); + param = ptype->TypeArray ()->DepDim ()->TemplateParamInfo (); + if (! param || param->isTypeParam () || + (pos = getPosition (param)) == -1) + return false; + if (atype->TypeArray ()->DepDim ()) { + param2 = atype->TypeArray ()->DepDim ()->TemplateParamInfo (); + if (! param2 || param2->isTypeParam () || + ! sameType (pos, param2->TypeInfo ())) + return false; + darguments[pos] = new DeducedArgument (param, param2->TypeInfo ()); + } else if (sameValue (pos, &dim)) { + darguments[pos] = new DeducedArgument (param, adim); + } else + return false; + } else if (pdim != adim) + return false; + // match against function + } else if (ptype->TypeFunction ()) { + ptl = ptype->TypeFunction ()->ArgTypes (); + atl = atype->TypeFunction ()->ArgTypes (); + if (ptl->Entries () != atl->Entries ()) + return false; + for (unsigned i = 0; i < ptl->Entries (); i++) + if (! matchArgument (ptl->Entry (i), atl->Entry (i), 0)) + return false; + } + + // match base types + return matchArgument (ptype->BaseType (), atype->BaseType (), aexpr); +} + + +// ��14.5.5.2 partial ordering rules +// return 0 if equal, 1 if more, and -1 if less specialized than other +int InstantiationCandidate::compare (InstantiationCandidate &other) { + InstantiationCandidate cand1; + cand1.initialize (other.TemplateInfo ()->SpecializationName (), ObjectInfo (), TemplateInfo ()); + for (unsigned i = 0; i < Arguments (); i++) + cand1.addArgument (Argument (i)); + + InstantiationCandidate cand2; + cand2.initialize (TemplateInfo ()->SpecializationName (), other.ObjectInfo (), other.TemplateInfo ()); + for (unsigned i = 0; i < other.Arguments (); i++) + cand2.addArgument (other.Argument (i)); + + // match against the other + bool matches1 = cand1.match (cand2); + bool matches2 = cand2.match (cand1); + + // equal specialized + if (matches1 && matches2) + return 0; + // more specialized + if (matches1) + return -1; + // less specialized + if (matches2) + return 1; + // equal specialized + return 0; +} + + +bool InstantiationCandidate::setDeducedArgument (DeducedArgumentList &args, int pos, DeducedArgument *arg) { + bool res = true; + DeducedArgument *old = args[pos]; + if (! old) { + args[pos] = arg; + } else { + res = (*arg == *old); + delete arg; + } + return res; +} + + +void InstantiationCandidate::printArgumentList (std::ostream &out, bool print_default_args) const { + out << "<"; + unsigned i = 0; + for (; i < DeducedArgs (); i++) { + DeducedArgument *arg = DeducedArg (i); + + // do not list default arguments + if (! print_default_args && arg->isDefaultArg ()) + break; + + if (i) out << ","; + out << *arg; + } + for (; i < InstantiationArgs (); i++) { + DeducedArgument *arg = InstantiationArg (i); + + // do not list default arguments + if (! print_default_args && arg->isDefaultArg ()) + break; + + if (i) out << ","; + out << *arg; + } + out << ">"; +} + + +Token* InstantiationCandidate::getPointOfInstantiationToken(CTree* p) const { + Token* token = 0; + CTree* point = p ? p : poi; + if (point) { + do { + token = point->token(); + } while (! token && (point = point->Parent())); + } + return token; +} + + +bool InstantiationCandidate::maxInstDepthReached () { + // ISO says not more than 17 + unsigned max_depth = 17; + // maximum set by user? + const ConfOption *opt = getProject ()->config ().Option ("--template-depth"); + if (opt && opt->Arguments () > 0) { + max_depth = strtol (opt->Argument (0), NULL, 10); + } + if (tpl_info->Depth () > max_depth) { + *err << sev_error << getPointOfInstantiationToken()->location () + << "maximum instantiation depth (" + << max_depth << ") reached" << endMessage; + return true; + } + return false; +} + + +void InstantiationCandidate::printCodeLine (Token* token) const { + int line = token->location().line(); + Unit* u = token->unit(); + for (token = u->first(); token; token = u->next(token)) { + if (token->location().line() == line) { + if (token->is_whitespace() && strchr(token->text(), '\n')) + break; + *err << token->text(); + } + } + *err << endMessage; +} + + +void InstantiationCandidate::printInstantiationErrorHeader (Token* token) const { + if (token) { + CObjectInfo* obj = obj_info; + if (! obj && instance) + obj = instance->Object(); + + if (obj) { + bool verbose = obj->SemDB()->Project()->config().Option("--verbose-errors"); + *err << token->location() + << "In instantiation of `" << *obj->TypeInfo(); + if (!obj->TemplateInstance()) { + std::ostringstream args; + printArgumentList(args); + *err << args.str().c_str(); + } + *err << "'" << endMessage; + if (verbose) + printCodeLine(token); + + /* TODO: provide a way to get this information + Unit* unit = token->unit(); + if (unit->isTemplateInstance()) { + unit = ((TemplateInstanceUnit*)unit)->ContainingUnit(); + + while (unit->isTemplateInstance()) { + TemplateInstanceUnit* tiunit = (TemplateInstanceUnit*)unit; + CTemplateInstance* inst = tiunit->TemplateInstance(); + CTree* poi = inst ? inst->PointOfInstantiation() : 0; + token = poi ? poi->token() : 0; + + if (token && inst->Object()) { + *err << token->location() + << " instantiated from `" << *inst->Object()->TypeInfo() + << "'" << endMessage; + if (verbose) + printCodeLine(token); + } + + unit = tiunit->ContainingUnit(); + } + }*/ + } + } +} + + +CStructure *InstantiationCandidate::createInstanceScope() { + CStructure *scope = tpl_info->Parent()->newNamespace(); + scope->NamespaceInfo()->aroundInstantiation(true); + scope->Name("%"); + scope->TypeInfo(&CTYPE_UNDEFINED); + scope->SemDB(obj_info->SemDB()); + scope->SourceInfo()->FileInfo(obj_info->SourceInfo()->FileInfo()); + scope->SourceInfo()->StartToken(PointOfInstantiation()->token_node()); + return scope; +} + + +bool InstantiationCandidate::parseDirectArguments (unsigned pos, unsigned numargs, CT_TemplateArgList *args) { + // check maximal instantiation depth + if (maxInstDepthReached()) + return false; + + // create new template instance scope + inst_scope = createInstanceScope(); + + // parse the arguments + return parseArguments(pos, numargs, args); +} + + +InstantiationParser& InstantiationCandidate::getParser() { + if (! parser) { + parser = new InstantiationParser(); + parser->init(obj_info, tpl_info, inst_scope); + } + return *parser; +} + + +bool InstantiationCandidate::parseArguments (unsigned pos, unsigned numargs, CT_TemplateArgList *args) { + unsigned i = 0; + + // parse each direct or default argument + for (; i < pos; i++) { + CTemplateParamInfo *param = tpl_info->Parameter(i); + bool is_default_arg = (i >= numargs); + CTree *arg; + + if (is_default_arg) { + // default template argument + arg = param->DefaultArgument(); + } else { + // direct template argument + arg = args->Entry(i); + } + + if (param->isTemplate()) { + // template-template parameter + CTypeInfo* type = 0; + if (!is_default_arg) { + // get the template type + CObjectInfo* oinfo; + CTree* sn = arg; + if (sn->NodeName() == CT_NamedType::NodeId()) + sn = sn->Son(0)->Son(0); + if (!(sn->NodeName() == CT_SimpleName::NodeId() || + sn->NodeName() == CT_RootQualName::NodeId() || + sn->NodeName() == CT_QualName::NodeId()) || + !sn->SemObject() || + !(oinfo = sn->SemObject()->Object()) || + !(oinfo->Record() && oinfo->Record()->isTemplate())) { + SEM_ERROR(arg, "expected a class template as argument " << i+1); + break; + } + type = oinfo->TypeInfo()->VirtualType(); + } + if (!parseTemplateTemplateArgument(param, arg, type)) { + SEM_ERROR(arg, "invalid template argument " << i+1); + break; + } + } + else if (param->isTypeParam()) { + // template type parameter + CTypeInfo* type = 0; + if (!is_default_arg) { + // get the type + CObjectInfo* oinfo; + if (!(arg->NodeName() == CT_NamedType::NodeId()) || + !arg->SemObject() || + !(oinfo = arg->SemObject()->Object())) { + SEM_ERROR(arg, "expected a type as argument " << i+1); + break; + } + // if the type in the argument list is a bitfield type, + // take the base type. Otherwise take it as it is. + type = oinfo->TypeInfo(); + if (type->isBitField ()) + type = type->BaseType(); + } + if (!parseTypeTemplateArgument(param, arg, type)) { + SEM_ERROR(arg, "invalid template argument " << i+1); + break; + } + } + else { + // template non-type parameter + CConstant* value = 0; + if (!is_default_arg) { + // not a non-type argument + if (arg->NodeName() == CT_NamedType::NodeId()) { + SEM_ERROR(arg, "expected a constant as argument " << i+1); + break; + } + // need value of constant + if (!arg->Value() || !arg->Value()->Constant()) { + SEM_ERROR(arg, "expected a constant as argument " << i+1); + break; + } + value = arg->Value()->Constant(); + } + if (!parseNonTypeTemplateArgument(param, arg, value)) { + SEM_ERROR(arg, "invalid template argument " << i+1); + break; + } + } + } + + // return true if all arguments could be successfully parsed + return i == pos; +} + + +bool InstantiationCandidate::parseNonTypeTemplateArgument(CTemplateParamInfo* param, CTree* tree, CConstant* value) { + bool is_default_arg = !value; + + if (is_default_arg && !CCSemExpr::isDependent(tree)) { + // default argument does not depend on template parameters, get its value + if (tree->Value()) + value = tree->Value()->Constant(); + } + + if (!value && tree) { + // dependent default argument, parse it again to determine the real value + bool delayed = false; + tree = getParser().parse(tpl_info, tree, &InstantiationSyntax::ass_expr, delayed); + + if (tree && !parser->failed()) { + // resolve the expression and calculate the value + CCSemExpr cse(parser->builder().err(), inst_scope); + cse.resolveExpr(tree); + + if (tree->Value()) + value = tree->Value()->Constant(); + } + } + + if (!value) + return false; + + // introduce constant with template argument as value + CObjectInfo* info = introduceObjectForNonTypeTemplateArgument(param, tree, value); + if (!info) + return false; + + // successfully deduced + darguments.append(new DeducedArgument(param, value, tree, is_default_arg, !is_default_arg)); + + return true; +} + + +CObjectInfo* InstantiationCandidate::introduceObjectForNonTypeTemplateArgument(CTemplateParamInfo* param, CTree* tree, CConstant* value) { + // no value type given + CTypeInfo* type = param->ValueType(); + if (!type || type->isDependent()) { + // dependent parameter type, parse it again to determine real type + bool delayed = false; + CT_NonTypeParamDecl* ntpd = (CT_NonTypeParamDecl*) getParser().parse(tpl_info, param->Tree(), &InstantiationSyntax::non_type_param_without_init, delayed); + + if (ntpd && !parser->failed()) { + CT_SimpleName* name = findName(ntpd->Declarator()); + if (name) + type = name->Type(); + } + } + if (!type) + return 0; + + type = type->Duplicate(); + if (!type->isConst()) { + // need to make type const to be accepted as constant + if (type->TypeQualified()) + type->TypeQualified()->isConst(true); + else + type = new CTypeQualified(type, true, false, false); + } + + // TODO: Double check memory management for syntax trees of template instances + // The Init-Expression of a non-type template parameter had referenced a deleted + // node. Therefore, I (Olaf) removed the following condition: +// if (!tree) { + // no syntax tree given + tree = new CT_Expression(); + tree->SemValue()->setValueRef(value); + tpl_info->addTreeFragment(tree); +// } + + // introduce constant with template argument as value + CAttributeInfo* info = inst_scope->newAttribute(); + info->Init(tree); + info->Name(param->Name()); + info->TypeInfo(type); + info->SourceInfo()->FileInfo(param->SourceInfo()->FileInfo()); + CT_Token* token_node = tree->token_node(); + info->SourceInfo()->StartToken(token_node ? token_node : param->SourceInfo()->StartToken()); + + return info; +} + + +bool InstantiationCandidate::parseTypeTemplateArgument(CTemplateParamInfo* param, CTree* tree, CTypeInfo* type) { + bool is_default_arg = !type; + + if (is_default_arg && !CCSemExpr::isDependent(tree)) { + // default argument does not depend on template parameters, get its type + CT_SimpleName* name = findPrivateName(tree); + if (name) + type = name->Type(); + } + + if (!type && tree) { + // dependent default argument, parse it again to determine final type + bool delayed = false; + tree = getParser().parse(tpl_info, tree, &InstantiationSyntax::type_id, delayed); + + if (tree && !parser->failed()) { + CT_SimpleName* name = findPrivateName(tree); + if (name) + type = name->Type(); + } + } + + if (!type) + return false; + + // introduce typedef for argument type with template parameter name + CObjectInfo* info = introduceObjectForTypeTemplateArgument(param, tree, type->Duplicate()); + if (!info) + return false; + + // successfully deduced + darguments.append(new DeducedArgument(param, info->TypeInfo()->VirtualType(), tree, is_default_arg, !is_default_arg)); + + return true; +} + + +CObjectInfo* InstantiationCandidate::introduceObjectForTypeTemplateArgument(CTemplateParamInfo* param, CTree* tree, CTypeInfo* type) { + // introduce typedef for argument type with template parameter name + CObjectInfo* info = inst_scope->newTypedef(); + info->Name(param->Name()); + info->TypeInfo(type); + info->TypeInfo(info->TypeInfo()->TypedefInfo(info)); + info->SourceInfo()->FileInfo(param->SourceInfo()->FileInfo()); + info->SourceInfo()->StartToken(tree ? tree->token_node() : param->SourceInfo()->StartToken()); + return info; +} + + +bool InstantiationCandidate::parseTemplateTemplateArgument(CTemplateParamInfo* param, CTree* tree, CTypeInfo* type) { + bool is_default_arg = !type; + + if (is_default_arg && !CCSemExpr::isDependent(tree)) { + // default argument does not depend on template parameters, get its type + CT_SimpleName* name = findName(tree); + if (name) + type = name->Type(); + } + + if (!type && tree) { + // default argument depends on template parameters, parse it again + getParser().semantic().enter_expr(); + bool delayed = false; + tree = parser->parse(tpl_info, tree, &InstantiationSyntax::id_expr, delayed); + parser->semantic().leave_expr(); + + if (tree && !parser->failed()) { + // resolve the expression and calculate the value + CCSemExpr cse(parser->builder().err(), inst_scope); + cse.resolveExpr(tree); + + CT_SimpleName* name = findName(tree); + if (name) + type = name->Type(); + } + } + + if (!type) + return false; + + // introduce member alias for template with template parameter name + CObjectInfo* info = introduceObjectForTemplateTemplateArgument(param, tree, type->Duplicate()); + if (!info) + return false; + + // successfully deduced + darguments.append(new DeducedArgument(param, info->TypeInfo(), tree, is_default_arg, !is_default_arg)); + + return true; +} + + +bool InstantiationCandidate::isDependent(CTemplateInfo* tpl) const { + for (unsigned i = 0; i < tpl->Parameters(); i++) { + CTemplateParamInfo* param = tpl->Parameter(i); + if (param && isDependent((CT_TemplateParamDecl*) param->Tree())) + return true; + } + return false; +} + + +bool InstantiationCandidate::isDependent(CT_TemplateParamDecl* pd) const { + if (!pd) + return false; + + if (pd->DefaultArgument() && CCSemExpr::isDependent(pd->DefaultArgument())) + return true; + + if (pd->NodeName() == CT_NonTypeParamDecl::NodeId()) { + CObjectInfo* obj = pd->SemObject()->Object(); + if (obj && obj->TemplateParamInfo()) { + CTypeInfo* type = obj->TemplateParamInfo()->ValueType(); + return type && type->isDependent(); + } + } else if (pd->NodeName() == CT_TypeParamDecl::NodeId()) { + CT_TypeParamDecl* tpd = (CT_TypeParamDecl*)pd; + if (tpd->Parameters() && tpd->Parameters()->Scope()) + return isDependent(tpd->Parameters()->Scope()->TemplateInfo()); + } + + return false; +} + +CObjectInfo* InstantiationCandidate::introduceObjectForTemplateTemplateArgument(CTemplateParamInfo* param, CTree* tree, CTypeInfo* type) { + if (!type->TypeRecord()) + return 0; + + CTemplateInfo* ttpl = param->TemplateTemplate(); + if (isDependent(ttpl)) { + // template template depends on other template parameters, parse again + bool delayed = false; + CT_TypeParamDecl* tpd = (CT_TypeParamDecl*) getParser().parse(tpl_info, param->Tree(), &InstantiationSyntax::type_param_without_init, delayed); + + if (tpd && !parser->failed()) { + if (tpd->Parameters()) + ttpl = tpd->Parameters()->Scope()->TemplateInfo(); + } + } + + // check if template parameter lists match + CRecord* record = type->TypeRecord()->Record(); + if (!CTemplateInfo::equalParameters(ttpl, record->TemplateInfo())) + return 0; + + // introduce member alias for template with template parameter name + CObjectInfo* info = inst_scope->newMemberAlias(type->TypeRecord()->Record()); + info->Name(param->Name()); + info->MemberAliasInfo()->Member(type->TypeRecord()->Record()); + info->TypeInfo(type); + info->SourceInfo()->FileInfo(param->SourceInfo()->FileInfo()); + info->SourceInfo()->StartToken(tree ? tree->token_node() : param->SourceInfo()->StartToken()); + + return info; +} + + +CTree* InstantiationCandidate::instantiate(CCInstantiation* inst) { + // add all non-direct non-default arguments + for (unsigned i = 0; i < DeducedArgs(); i++) { + DeducedArgument *arg = DeducedArg(i); + CTemplateParamInfo *param = getMatchingParameter(arg->TemplateParam()); + if (!param) { + continue; + } + + // direct or default argument + if ((arg->isDefaultArg() || arg->isDirectArg()) && arg->TemplateParam()->Template() == tpl_info) { + // nothing to do + continue; + } + + if (param->isTemplate()) { + // deduced template-template argument + if (!introduceObjectForTemplateTemplateArgument(param, 0, arg->Type()->Duplicate())) + return (CTree*)0; + } else if (param->isTypeParam()) { + // deduced type argument + if (!introduceObjectForTypeTemplateArgument(param, 0, arg->Type()->Duplicate())) + return (CTree*)0; + } else { + // deduced non-type argument + if (!introduceObjectForNonTypeTemplateArgument(param, 0, arg->Value())) + return (CTree*)0; + } + } + + // parse the template without the template header + CTree* tree = 0; + if (TemplateInfo()->Tree()) { + // create new parser for parsing the instance + if (parser) + delete parser; + parser = new InstantiationParser(); + parser->init(obj_info, tpl_info, inst_scope, inst); + + // parse the template instance + CTree* decl = TemplateInfo()->Tree()->Declaration(), *son; + bool delayed = false; + if (decl->NodeName() == CT_FctDef::NodeId()) + tree = parser->parse(tpl_info, decl, &InstantiationSyntax::fct_def, delayed); + else if (decl->NodeName() == CT_ObjDecl::NodeId() && + decl->Sons() && (son = decl->Son(0)) && + son->Sons() && (son = son->Son(0)) && + son->NodeName() == CT_ClassDef::NodeId()) + tree = parser->parse(tpl_info, decl, &InstantiationSyntax::class_spec, delayed); + else { + tree = parser->parse(tpl_info, decl, &InstantiationSyntax::decl, delayed); + } + if (delayed) + detected_delayed_parse_node = true; + + // semantic expression analysis, only if instantiating function bodies, + // not needed otherwise + if (tree && getProject()->config().Option("--inst-fct-bodies")) + parser->resolve(tpl_info, inst_scope, tree); + } + return tree; +} + + +void InstantiationCandidate::printInstantiationHeader() const { + std::cout << std::endl; + if (PointOfInstantiation()) { + std::cout << getPointOfInstantiationToken()->location() << ": "; + } + std::cout << obj_info->Name(); + printArgumentList(std::cout); + std::cout << ": instantiated here" << std::endl; + if (tpl_info->Tree() && tpl_info->Tree()->token() && tpl_info->ObjectInfo()) { + std::cout << tpl_info->Tree()->token()->location() + << ": instantiation of template " + << tpl_info->ObjectInfo()->QualName(true) << std::endl; + } +} + + +CT_SimpleName *InstantiationCandidate::findPrivateName (CTree *node) { + const char *id = node->NodeName (); + if (id == CT_PrivateName::NodeId ()) + return (CT_SimpleName*)node; + else if (id == CT_NamedType::NodeId ()) + return findPrivateName (((CT_NamedType*)node)->Declarator ()); + else if (id == CT_FctDeclarator::NodeId ()) + return findPrivateName (((CT_FctDeclarator*)node)->Declarator ()); + else if (id == CT_ArrayDeclarator::NodeId ()) + return findPrivateName (((CT_ArrayDeclarator*)node)->Declarator ()); + else if (id == CT_PtrDeclarator::NodeId ()) + return findPrivateName (((CT_PtrDeclarator*)node)->Declarator ()); + else if (id == CT_MembPtrDeclarator::NodeId ()) + return findPrivateName (((CT_MembPtrDeclarator*)node)->Declarator ()); + else if (id == CT_BracedDeclarator::NodeId ()) + return findPrivateName (((CT_BracedDeclarator*)node)->Declarator ()); + else if (id == CT_BitFieldDeclarator::NodeId ()) + return findPrivateName (((CT_BitFieldDeclarator*)node)->Declarator ()); + else if (id == CT_RefDeclarator::NodeId ()) + return findPrivateName (((CT_RefDeclarator*)node)->Declarator ()); + else if (id == CT_InitDeclarator::NodeId ()) + return findPrivateName (((CT_InitDeclarator*)node)->Declarator ()); + return (CT_SimpleName*)0; +} + + +CT_SimpleName *InstantiationCandidate::findName (CTree *node) { + const char *id = node->NodeName (); + if (node->IsSimpleName ()) + return (CT_SimpleName*)node; + else if (id == CT_NamedType::NodeId ()) + return findName (((CT_NamedType*)node)->Declarator ()); + else if (id == CT_FctDeclarator::NodeId ()) + return findName (((CT_FctDeclarator*)node)->Declarator ()); + else if (id == CT_ArrayDeclarator::NodeId ()) + return findName (((CT_ArrayDeclarator*)node)->Declarator ()); + else if (id == CT_PtrDeclarator::NodeId ()) + return findName (((CT_PtrDeclarator*)node)->Declarator ()); + else if (id == CT_MembPtrDeclarator::NodeId ()) + return findName (((CT_MembPtrDeclarator*)node)->Declarator ()); + else if (id == CT_BracedDeclarator::NodeId ()) + return findName (((CT_BracedDeclarator*)node)->Declarator ()); + else if (id == CT_BitFieldDeclarator::NodeId ()) + return findName (((CT_BitFieldDeclarator*)node)->Declarator ()); + else if (id == CT_RefDeclarator::NodeId ()) + return findName (((CT_RefDeclarator*)node)->Declarator ()); + else if (id == CT_InitDeclarator::NodeId ()) + return findName (((CT_InitDeclarator*)node)->Declarator ()); + return (CT_SimpleName*)0; +} + + +} // namespace Puma diff --git a/Puma/src/parser/ccparser/instantiation/InstantiationCandidate.h b/Puma/src/parser/ccparser/instantiation/InstantiationCandidate.h new file mode 100644 index 0000000..3041e61 --- /dev/null +++ b/Puma/src/parser/ccparser/instantiation/InstantiationCandidate.h @@ -0,0 +1,190 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __InstantiationCandidate__ +#define __InstantiationCandidate__ + +#include "Puma/Array.h" +#include "Puma/ErrorSink.h" +#include "Puma/DeducedArgument.h" + +namespace Puma { + + +class CTree; +class Token; +class CRecord; +class CProject; +class CTypeInfo; +class CConstant; +class CStructure; +class CT_ExprList; +class CObjectInfo; +class CT_SimpleName; +class CTemplateInfo; +class CT_TemplateName; +class CCInstantiation; +class CTemplateInstance; +class CT_TemplateArgList; +class CTemplateParamInfo; +class InstantiationParser; +class CT_TemplateParamDecl; + +class InstantiationCandidate { + typedef Array ArgumentList; + typedef Array DeducedArgumentList; + + ArgumentList arguments; + DeducedArgumentList darguments; + DeducedArgumentList iarguments; + CObjectInfo *obj_info; + CTemplateInfo *tpl_info; + CTree *poi; + ErrorSink *err; + CStructure *inst_scope; + CTemplateInstance *instance; + InstantiationParser *parser; + char anon_name_buf[100]; + bool detected_delayed_parse_node; + +public: + InstantiationCandidate (); + ~InstantiationCandidate (); + + CTree* instantiate(CCInstantiation* inst); + InstantiationParser& getParser(); + + void reset (); + void initialize (ErrorSink *e); + void initialize (CTree *p, CObjectInfo *o); + void initialize (CTree *p, CObjectInfo *o, CTemplateInfo *t, ErrorSink *e = 0); + void addArgument (CTree *); + void addDeducedArg (DeducedArgument *); + void addInstantiationArg (DeducedArgument *); + void forgetDeducedArgs (); + void TemplateInstance (CTemplateInstance *); + + bool deduceArguments (bool real_inst); + bool deduceArgumentsFromFctCall (unsigned skip = 0, bool exact_match = false, bool partial_ordering = false); + bool match (InstantiationCandidate &); + int compare (InstantiationCandidate &); + + bool canBeInstantiated (); + + CObjectInfo *ObjectInfo () const; + CTemplateInfo *TemplateInfo () const; + CTree *PointOfInstantiation () const; + CStructure *InstanceScope () const; + CTemplateInstance *TemplateInstance () const; + + CStructure *createInstanceScope(); + + unsigned Arguments () const; + unsigned DeducedArgs () const; + unsigned InstantiationArgs () const; + CTree *Argument (unsigned) const; + DeducedArgument *DeducedArg (unsigned) const; + DeducedArgument *InstantiationArg (unsigned) const; + + int getPosition (CTemplateParamInfo *) const; + Token* getPointOfInstantiationToken(CTree* point_of_inst = 0) const; + + void printInstantiationHeader() const; + void printInstantiationErrorHeader (Token* token) const; + void printArgumentList (std::ostream &out, bool print_default_args = false) const; + bool maxInstDepthReached (); + bool detectedDelayedParseNode () const; + +private: + int deduceArguments (CTypeInfo *ftype, CTypeInfo *atype, DeducedArgumentList &dargs, bool exact_match, bool partial_ordering); + int deduceFromQualifiedType (CTypeInfo *ftype, CTypeInfo *atype, DeducedArgumentList &dargs, bool exact_match, bool partial_ordering); + int deduceFromArray (CTypeInfo *ftype, CTypeInfo *atype, DeducedArgumentList &dargs, bool exact_match, bool partial_ordering); + int deduceFromFunction (CTypeInfo *ftype, CTypeInfo *atype, DeducedArgumentList &dargs, bool exact_match, bool partial_ordering); + int deduceFromMemberPointer (CTypeInfo *ftype, CTypeInfo *atype, DeducedArgumentList &dargs, bool exact_match, bool partial_ordering); + int deduceFromRecord (CTypeInfo *ftype, CTypeInfo *atype, DeducedArgumentList &dargs, bool exact_match, bool partial_ordering); + int deduceTemplateParam (CTypeInfo *ftype, CTypeInfo *atype, DeducedArgumentList &dargs, bool exact_match, bool partial_ordering); + int deduceArgumentsFromTemplateArgList (CTemplateInstance *fi, CTemplateInstance *ai, DeducedArgumentList &dargs, bool partial_ordering); + bool matchDirectArguments (unsigned pos, unsigned numargs, CT_TemplateArgList *args); + bool parseDirectArguments (unsigned pos, unsigned numargs, CT_TemplateArgList *args); + bool parseArguments (unsigned pos, unsigned numargs, CT_TemplateArgList *args); + bool joinDeducedArguments (DeducedArgumentList &dargs, DeducedArgumentList &curr_dargs, bool &matching_args, bool &ambiguous_type); + void getTemplateInstances(CRecord* c, Array& instances); + bool matchArgument (CTree *pexpr, CTree *aexpr); + bool matchArgument (CTypeInfo *ptype, CTypeInfo *atype, CTree *aexpr); + bool sameValue (int pos, CConstant *value); + bool sameType (int pos, CTypeInfo *type); + bool setDeducedArgument (DeducedArgumentList &args, int pos, DeducedArgument *arg); + bool matchingTemplateParameters (CTemplateParamInfo *param, CObjectInfo *ainfo); + CTemplateInfo *getTemplateInfo (CObjectInfo *info); + CT_SimpleName *findName (CTree *node); + CT_SimpleName *findPrivateName (CTree *node); + bool parseNonTypeTemplateArgument(CTemplateParamInfo* param, CTree* tree, CConstant* value); + bool parseTypeTemplateArgument(CTemplateParamInfo* param, CTree* tree, CTypeInfo* type); + bool parseTemplateTemplateArgument(CTemplateParamInfo* param, CTree* tree, CTypeInfo* type); + CTemplateParamInfo* getMatchingParameter(CTemplateParamInfo *param); + void dumpInstanceHeader(); + void calculateDesturbing(Array& desturbing); + CProject* getProject(); + void printCodeLine(Token* token) const; + CTypeQualified* getQualifiers(CTypeInfo* type); + CTypeInfo* setQualification(CTypeInfo* type, bool is_const, bool is_volatile, bool is_restrict); + CObjectInfo* introduceObjectForNonTypeTemplateArgument(CTemplateParamInfo* param, CTree* tree, CConstant* value); + CObjectInfo* introduceObjectForTypeTemplateArgument(CTemplateParamInfo* param, CTree* tree, CTypeInfo* type); + CObjectInfo* introduceObjectForTemplateTemplateArgument(CTemplateParamInfo* param, CTree* tree, CTypeInfo* type); + bool isDependent(CTemplateInfo* tpl) const; + bool isDependent(CT_TemplateParamDecl* pd) const; +}; + +inline CTemplateInstance *InstantiationCandidate::TemplateInstance () const + { return instance; } +inline CObjectInfo *InstantiationCandidate::ObjectInfo () const + { return obj_info; } +inline CTemplateInfo *InstantiationCandidate::TemplateInfo () const + { return tpl_info; } +inline CTree *InstantiationCandidate::PointOfInstantiation () const + { return poi; } +inline CStructure *InstantiationCandidate::InstanceScope () const + { return inst_scope; } + +inline unsigned InstantiationCandidate::Arguments () const + { return arguments.length (); } +inline unsigned InstantiationCandidate::DeducedArgs () const + { return darguments.length (); } +inline unsigned InstantiationCandidate::InstantiationArgs () const + { return iarguments.length (); } +inline CTree *InstantiationCandidate::Argument (unsigned i) const + { return arguments.lookup (i); } +inline DeducedArgument *InstantiationCandidate::DeducedArg (unsigned i) const + { return darguments.lookup (i); } +inline DeducedArgument *InstantiationCandidate::InstantiationArg (unsigned i) const + { return iarguments.lookup (i); } + +inline void InstantiationCandidate::addArgument (CTree *a) + { arguments.append (a); } +inline void InstantiationCandidate::addDeducedArg (DeducedArgument *darg) + { darguments.append (darg); } +inline void InstantiationCandidate::addInstantiationArg (DeducedArgument *darg) + { iarguments.append (darg); } +inline void InstantiationCandidate::forgetDeducedArgs () + { darguments.reset (); } +inline bool InstantiationCandidate::detectedDelayedParseNode () const + { return detected_delayed_parse_node; } + +} // namespace Puma + +#endif /* __InstantiationCandidate__ */ diff --git a/Puma/src/parser/ccparser/instantiation/InstantiationParser.cc b/Puma/src/parser/ccparser/instantiation/InstantiationParser.cc new file mode 100644 index 0000000..a1006cd --- /dev/null +++ b/Puma/src/parser/ccparser/instantiation/InstantiationParser.cc @@ -0,0 +1,126 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/InstantiationParser.h" +#include "Puma/CTree.h" +#include "Puma/CObjectInfo.h" +#include "Puma/CTemplateInfo.h" +#include "Puma/CStructure.h" +#include "Puma/CFileInfo.h" +#include "Puma/CCInstantiation.h" +#include "Puma/InstantiationTokenProvider.h" +#include "Puma/InstantiationTokenSource.h" +#include "Puma/CCSemVisitor.h" +#include "Puma/CPrintVisitor.h" + +namespace Puma { + + +extern int TRACE_INSTANCE_CODE; +extern int TRACE_PARSE_INSTANCE; + + + +// initialize the parser +void InstantiationParser::init(CObjectInfo* obj, CTemplateInfo* tpl, CStructure* instance_scope, CCInstantiation* inst) { + // configure the parser + configure(obj->SemDB()->Project()->config()); + + // initialize semantic analyzer + bool is_fct = obj->FunctionInfo(); + Unit* primary = obj->SourceInfo()->FileInfo()->Primary(); + semantic().init(*obj->SemDB(), *primary, instance_scope, is_fct, !is_fct, inst); + ((ErrorCollector&) builder().err()).index(0); + semantic().error_sink(builder().err()); + + if (TRACE_PARSE_INSTANCE) { +#ifdef __PUMA_TRACING__ + trace(std::cout); +#endif + } +} + + +// parse a template instance +CTree *InstantiationParser::parse(CTemplateInfo* tpl, CTree* tree, bool (InstantiationSyntax::*rule)(), bool &delayed_parse_node, bool add_tree) { + if (TRACE_PARSE_INSTANCE && semantic().Instantiation()) + semantic().Instantiation()->printInstantiationHeader(); + + // increase instantiation depth + tpl->increaseDepth(); + + // parse the template or template argument + InstantiationTokenSource source(tree); + InstantiationTokenProvider provider(source); + tree = syntax().run(provider, rule); + if (add_tree) + tpl->addTreeFragment(tree); + + // decrease instantiation depth + tpl->decreaseDepth (); + + if (!tree && !failed()) { + // failed with no error message + builder().err() << sev_error; + if (provider.current()) + builder().err() << provider.current()->location(); + builder().err() << "invalid declaration"; + if (provider.current()) + builder().err() << " near token `" << provider.current()->text() << "'"; + builder().err() << endMessage; + } + + // if a delayed parse node was part of the syntax tree, + // this information has to be returned to the called here. + // It might be necessary to issue an error message later. + delayed_parse_node = source.detectedDelayedParseNode (); + + if (tree && TRACE_INSTANCE_CODE) { + if (semantic().Instantiation()) + semantic().Instantiation()->printInstantiationHeader(); + // dump tree + CPrintVisitor printer; + printer.configure(tpl->SemDB()->Project()->config()); + printer.print(tree, std::cout); + } + + return tree; +} + + +// resolve expressions +void InstantiationParser::resolve(CTemplateInfo* tpl, CStructure* scope, CTree* tree) { + // increase instantiation depth + tpl->increaseDepth(); + + // do semantic expression analysis + CCSemVisitor resolver(builder().err()); + resolver.run(tree, scope); + + // decrease instantiation depth + tpl->decreaseDepth (); +} + + +// check for parse errors +bool InstantiationParser::failed() { + return ((ErrorCollector&)builder().err()).severity() > sev_warning; +} + + +} // namespace Puma diff --git a/Puma/src/parser/ccparser/instantiation/InstantiationParser.h b/Puma/src/parser/ccparser/instantiation/InstantiationParser.h new file mode 100644 index 0000000..a039bf6 --- /dev/null +++ b/Puma/src/parser/ccparser/instantiation/InstantiationParser.h @@ -0,0 +1,68 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __InstantiationParser__ +#define __InstantiationParser__ + +#include "Puma/Parser.h" +#include "Puma/InstantiationSyntax.h" +#include "Puma/InstantiationBuilder.h" +#include "Puma/InstantiationSemantic.h" + +namespace Puma { + + +class CTree; +class CObjectInfo; +class CTemplateInfo; +class CStructure; +class CCInstantiation; + +class InstantiationParser : public Parser { + InstantiationSyntax _syntax; + InstantiationBuilder _builder; + InstantiationSemantic _semantic; + +public: + InstantiationParser() : + Parser(_syntax, _builder, _semantic), + _syntax(_builder, _semantic), + _semantic(_syntax, _builder) { + } + + // initialize the parser + void init(CObjectInfo* obj, CTemplateInfo* tpl, CStructure* instance_scope, CCInstantiation* inst = 0); + + // parse a template instance or template argument + CTree *parse(CTemplateInfo* tpl, CTree* tree, bool (InstantiationSyntax::*rule)(), bool &delayed_parse_node, bool add_tree = true); + + // do semantic expression analysis + void resolve(CTemplateInfo* tpl, CStructure* scope, CTree* tree); + + // check for parse errors + bool failed(); + + InstantiationSyntax &syntax() const { return (InstantiationSyntax&) _syntax; } + InstantiationBuilder &builder() const { return (InstantiationBuilder&) _builder; } + InstantiationSemantic &semantic() const { return (InstantiationSemantic&) _semantic; } +}; + + +} // namespace Puma + +#endif /* __InstantiationParser__ */ diff --git a/Puma/src/parser/ccparser/instantiation/InstantiationSemantic.cc b/Puma/src/parser/ccparser/instantiation/InstantiationSemantic.cc new file mode 100644 index 0000000..4d2cedf --- /dev/null +++ b/Puma/src/parser/ccparser/instantiation/InstantiationSemantic.cc @@ -0,0 +1,417 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/InstantiationSemantic.h" +#include "Puma/CTree.h" +#include "Puma/DelayedParseTree.h" +#include "Puma/Unit.h" +#include "Puma/Array.h" +#include "Puma/PtrStack.h" +#include "Puma/ErrorSink.h" +#include "Puma/ErrorSeverity.h" +#include "Puma/CCSemDeclarator.h" +#include "Puma/CSemDeclSpecs.h" +#include "Puma/CFileInfo.h" +#include "Puma/CEnumInfo.h" +#include "Puma/CTypeInfo.h" +#include "Puma/CClassInfo.h" +#include "Puma/CUnionInfo.h" +#include "Puma/CUsingInfo.h" +#include "Puma/CLabelInfo.h" +#include "Puma/CLocalScope.h" +#include "Puma/CTypedefInfo.h" +#include "Puma/CFunctionInfo.h" +#include "Puma/CArgumentInfo.h" +#include "Puma/CAttributeInfo.h" +#include "Puma/CEnumeratorInfo.h" +#include "Puma/CTemplateInfo.h" +#include "Puma/CTemplateParamInfo.h" +#include "Puma/CClassInstance.h" +#include "Puma/CUnionInstance.h" +#include "Puma/CFctInstance.h" +#include "Puma/CSyntax.h" +#include "Puma/CCSyntax.h" +#include "Puma/CSemDatabase.h" +#include "Puma/CCNameLookup.h" +#include "Puma/CMemberAliasInfo.h" +#include "Puma/CNamespaceInfo.h" +#include "Puma/CCSemExpr.h" +#include "Puma/CConstant.h" +#include "Puma/CCInstantiation.h" +#include "Puma/FileUnit.h" +#include "Puma/MacroUnit.h" + +#include +#include +#include +#include + +namespace Puma { + +///*DEBUG*/extern int TRACE_FCT; +///*DEBUG*/extern int TRACE_OBJS; +///*DEBUG*/extern int TRACE_SCOPES; + +// print semantic error messages + +#define SEM_MSG(loc__,mesg__) \ + *_err << loc__->token ()->location () << mesg__ << endMessage + +#define SEM_ERROR(loc__,mesg__) \ + SEM_MSG (loc__, sev_error << mesg__) + +#define SEM_WARNING(loc__,mesg__) \ + SEM_MSG (loc__, sev_warning << mesg__) + +#define SEM_MSG__prev_loc(info__) \ + if (info__->SourceInfo ()->StartToken ()) \ + *_err << info__->SourceInfo ()->StartToken ()->token ()->location () \ + << "previously defined here" << endMessage + +#define SEM_ERROR__already_defined(loc__,name__,info__) \ + SEM_ERROR (loc__, "`" << *name__ << "' already defined"); \ + SEM_MSG__prev_loc(info__) + +#define SEM_ERROR__duplicate(loc__,type__,name__) \ + SEM_ERROR (loc__, "duplicate " << type__ << " `" << *name__ << "'") + +#define SEM_ERROR__invalid_in_param(loc__,what__,name__) \ + SEM_ERROR (loc__, what__ << " invalid in declaration of parameter `" \ + << *name__ << "'") + +#define SEM_ERROR__redefinition(loc__,name__,info__) \ + SEM_ERROR (loc__, "redefinition of `" << *name__ << "'"); \ + SEM_MSG__prev_loc(info__) + +#define SEM_ERROR__not_member(loc__,name__,class__) \ + SEM_ERROR (loc__, "`" << *name__ \ + << "' is not a member of `" << class__ << "'") + +#define SEM_ERROR__no_matching_decl(loc__,name__,class__) \ + SEM_ERROR (loc__, "no matching declaration found for `" << *name__ \ + << "' in class `" << class__ << "'") + +#define SEM_ERROR__unknown_ns(loc__,name__) \ + SEM_ERROR (loc__, "unknown namespace `" << *name__ << "'") + +#define SEM_ERROR__not_class(loc__,name__) \ + SEM_ERROR (loc__, "base type `" << *name__ \ + << "' fails to be a struct or class type") + +#define SEM_ERROR__invalid_param(loc__,what__,name__) \ + SEM_ERROR (loc__, "invalid " << what__ << \ + " in declaration of parameter `" << *name__ << "'") + +#define SEM_ERROR__ambiguous_use(loc__,name__) \ + SEM_ERROR (loc__, "use of `" << *name__ << "' is ambiguous") + +#define SEM_ERROR__cannot_declare(loc__,name__,scope__) \ + SEM_ERROR (loc__, "cannot declare `" << *name__ << \ + "' within `" << scope__->Name () << "'") + +#define SEM_ERROR__conflicting_types(loc__,info__) \ + SEM_ERROR (loc__, "conflicting types for `" << \ + info__->Name () << "'"); \ + SEM_MSG__prev_loc(info__) + +#define SEM_ERROR__not_base_class(loc__,class__) \ + SEM_ERROR (loc__, "`" << class__->Name () << \ + "' is not a base class of `" << current_scope->Name () << "'") + + + +void InstantiationSemantic::parse_delayed(bool (CCSyntax::*rule)(), CTree *tree) { +// CTree* node = getParent(syntax().provider().node()); + CTree* node = getParent((CTree*) syntax().provider().current_context()); + if (node && node->IsDelayedParse()) { + CT_DelayedParse* dp = (CT_DelayedParse*) createDelayedParse (rule, tree); + _outermost_class_def->addInstantiateDelayed(syntax().provider().current(), dp); + } else { + CCSemantic::parse_delayed(rule, tree); + } +} + +CTree* InstantiationSemantic::getParent(CTree* node, int n) { + for (int i = 0; i < n && node; i++) + node = node->Parent(); + return node; +} + +CTree *InstantiationSemantic::non_type_param_without_init() { + finish_declarator(); + if (!in_decl()) + return (CTree*)0; + + CT_NonTypeParamDecl *td = (CT_NonTypeParamDecl*) builder().non_type_param(); + CSemDeclSpecs *dsi = sem_decl_specs(); + CCSemDeclarator csd(_err, dsi->make_type(), td->Declarator()); + if (!csd.Name()) { + builder().destroyNode(td); + return (CTree*)0; + } + + CTypeInfo *type = csd.Type(); + if (type->isFunction() || type->isArray()) { + // template non-type parameter adjustment + csd.Type(new CTypePointer(type->isArray() ? type->VirtualType()->BaseType() : type)); + } + else if (! (type->isInteger() || type->isPointer() || + type->isAddress() || type->isMemberPointer() || + type->isTemplateParam())) { + SEM_ERROR__invalid_param(td, "type", csd.Name()); + builder().destroyNode(td); + return (CTree*)0; + } + + csd.Name()->setType(csd.Type()); + csd.Type(0); + + if (dsi) + decl_end(); + + return td; +} + +bool InstantiationSemantic::is_class_name() { +// CTree* node = getParent(syntax().provider().node()); + CTree* node = getParent((CTree*) syntax().provider().current_context()); + if (is(node)) { + CObjectInfo* obj = node->SemObject()->Object(); + if (obj && !obj->Record() && !obj->TypedefInfo() && + !(obj->TemplateParamInfo() && obj->TemplateParamInfo()->isTypeParam())) + return false; + } + return true; +} + +bool InstantiationSemantic::is_enum_name() { +// CTree* node = getParent(syntax().provider().node()); + CTree* node = getParent((CTree*) syntax().provider().current_context()); + if (is(node)) { + CObjectInfo* obj = node->SemObject()->Object(); + if (obj && !obj->EnumInfo()) + return false; + } + return true; +} + +bool InstantiationSemantic::is_typedef_name() { +// CTree* node = getParent(syntax().provider().node()); + CTree* node = getParent((CTree*) syntax().provider().current_context()); + if (is(node)) { + CObjectInfo* obj = node->SemObject()->Object(); + if (obj && !obj->TypedefInfo() && + !(obj->TemplateParamInfo() && obj->TemplateParamInfo()->isTypeParam())) + return false; + } + return true; +} + +bool InstantiationSemantic::is_template_name() { +// CTree* node = getParent(syntax().provider().node()); + CTree* node = getParent((CTree*) syntax().provider().current_context()); + if (is(node)) { + CObjectInfo* obj = node->SemObject()->Object(); + if (obj && !obj->isTemplate() && !obj->isTemplateInstance()) + return false; + } + return true; +} + +bool InstantiationSemantic::is_class_template_name() { +// CTree* node = getParent(syntax().provider().node()); + CTree* node = getParent((CTree*) syntax().provider().current_context()); + if (is(node)) { + CObjectInfo* obj = node->SemObject()->Object(); + if (obj && ((!obj->isTemplate() && !obj->isTemplateInstance()) || obj->FunctionInfo())) + return false; + } + return true; +} + +bool InstantiationSemantic::is_namespace_name() { +// CTree* node = getParent(syntax().provider().node()); + CTree* node = getParent((CTree*) syntax().provider().current_context()); + if (is(node)) { + CObjectInfo* obj = node->SemObject()->Object(); + if (obj && !obj->NamespaceInfo()) + return false; + } + return true; +} + +bool InstantiationSemantic::is_this_instance() { + if (tpl_inst) { +// CTree* node = getParent(syntax().provider().node()); + CTree* node = getParent((CTree*) syntax().provider().current_context()); + if (is(node)) { + CObjectInfo* obj = node->SemObject()->Object(); + if (obj && obj == tpl_inst->ObjectInfo()) + return true; + } + } + return false; +} + +void InstantiationSemantic::set_this_instance() { + CTree* node = builder().Top(); + if (is(node)) { + CT_SimpleName* sn = (CT_SimpleName*)node; + sn->Object(tpl_inst->Instance()); + sn->setTypeRef(tpl_inst->Instance()->TypeInfo()); + } +} + +bool InstantiationSemantic::is_this_specialization() { + if (tpl_inst) { +// CTree* node = getParent(syntax().provider().node(), 3); + CTree* node = getParent((CTree*) syntax().provider().current_context(), 3); + if (node) { + if (is(node) || is(node)) + node = getParent(node); + if (is(node)) + node = getParent(node); + if (is(node) || is(node)) { + if (is(node)) + node = getParent(node, 2); + if (node == syntax().source().root()) + return true; + } + } + } + return false; +} + +CTree *InstantiationSemantic::introduce_function() { + if (! parsing_fct_inst || ! tpl_inst || tpl_inst->Instance() != current_fct) + return CCSemantic::introduce_function(); + + // determine function return type + CT_DeclSpecSeq *dss = (CT_DeclSpecSeq*)(builder().nodes() == 2 ? builder().get_node(0) : 0); + CT_Declarator *d = (CT_Declarator*)(dss ? builder().get_node(1) : builder().get_node(0)); + if (dss && ! in_decl()) + return (CTree*)0; + + // determine function type + CSemDeclSpecs *dsi = sem_decl_specs(); + CCSemDeclarator csd(_err, dsi->make_type(), d); + if (! csd.Name() || ! csd.Type() || ! csd.Type()->VirtualType()->TypeFunction()) + return (CTree*)0; + + CFunctionInfo *info = (CFunctionInfo*)current_fct; + CTypeInfo *type = csd.Type(); + type->VirtualType()->TypeFunction()->FunctionInfo(info); + info->FctInstance()->RealTypeInfo(type); + + // create implicit `this' parameter + addImplicitThisObject(info, type, d); + + CTree* name = csd.Name()->Name(); + if (info->isConversion() && name->NodeName() == CT_ConversionName::NodeId()) + info->ConversionType(((CT_ConversionName*)name)->TypeName()->Object()->TypeInfo()); + + // enter function scope (re-used function prototype scope) + reenter_scope(current_fct); + current_fct = 0; + + csd.Name()->Object(info); + csd.Name()->setTypeRef(type); + if (! csd.Name()->Name()->Object()) { + csd.Name()->Name()->Object(info); + csd.Name()->Name()->setTypeRef(type); + } + csd.Type((CTypeInfo*)0); + + if (dss) decl_end(); + return d; +} + +CTree *InstantiationSemantic::introduce_object (CTree*) { + if (! parsing_fct_inst || ! tpl_inst || tpl_inst->Instance() != current_fct) + return CCSemantic::introduce_object(); + + if (! in_decl()) + return (CTree*)0; + + // determine type of declaration + CT_InitDeclarator *id = (CT_InitDeclarator*)builder().init_declarator1(); + CSemDeclSpecs *dsi = sem_decl_specs(); + CCSemDeclarator csd(_err, dsi->make_type(), id); + if (! csd.Name()) { + delete id; + return (CTree*)0; + } + + // check if this is a function declaration + CTypeInfo *type = csd.Type(); + if (dsi->declared(CT_PrimDeclSpec::PDS_TYPEDEF) || !type->isFunction() || type->isAddress()) + return CCSemantic::introduce_object(id); + + CFunctionInfo *info = (CFunctionInfo*)current_fct; + type->VirtualType()->TypeFunction()->FunctionInfo(info); + common_settings(info, id, &csd); + + // create implicit `this' parameter + addImplicitThisObject(info, type, id); + + CTree* name = csd.Name()->Name(); + if (info->isConversion() && name->NodeName() == CT_ConversionName::NodeId()) + info->ConversionType(((CT_ConversionName*)name)->TypeName()->Object()->TypeInfo()); + + id->Object(info); + current_fct = 0; + + return id; +} + +CTree *InstantiationSemantic::introduce_class() { + if (! parsing_class_inst || ! tpl_inst || ! tpl_inst->Instance() || ! current_scope->isNamespace() || + tpl_inst->Instance()->TemplateInstance()->isInstantiated()) + return CCSemantic::introduce_class(); + + CObjectInfo *info = tpl_inst->Instance(); + tpl_inst->insertInstance(info); + + // determine member access + CT_ClassDef *cs = (CT_ClassDef*) builder().class_head1(); + if (cs->NodeName() == CT_UnionDef::NodeId()) { + _protection.push(CProtection::PROT_PUBLIC); + } else { + if (cs->token()->type() == TOK_STRUCT) + _protection.push(CProtection::PROT_PUBLIC); + else + _protection.push(CProtection::PROT_PRIVATE); + } + + reenter_scope(info->Structure()); + + common_settings(info, cs); + cs->Name()->Object(info); + cs->Name()->setTypeRef(info->TypeInfo()); + cs->Object(info); + + // semantic state to let parse function bodies and several initializers + // later due to potential use of names of members that could not be + // resolved untill the end of the class definition + enter_class_def(); + + return cs; +} + + +} // namespace Puma diff --git a/Puma/src/parser/ccparser/instantiation/InstantiationSemantic.h b/Puma/src/parser/ccparser/instantiation/InstantiationSemantic.h new file mode 100644 index 0000000..28b488e --- /dev/null +++ b/Puma/src/parser/ccparser/instantiation/InstantiationSemantic.h @@ -0,0 +1,82 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __InstantiationSemantic_h__ +#define __InstantiationSemantic_h__ + +#include "Puma/CCSemantic.h" +#include "Puma/InstantiationBuilder.h" +#include "Puma/InstantiationSyntax.h" +#include "Puma/CTree.h" + +namespace Puma { + + +class InstantiationSemantic : public CCSemantic { + InstantiationSyntax &_syntax; + +public: + InstantiationSemantic(InstantiationSyntax &, InstantiationBuilder &); + +protected: + virtual InstantiationBuilder &builder() const; + virtual InstantiationSyntax &syntax() const; + +public: + void parse_delayed(bool (CCSyntax::*rule)(), CTree *tree); + + CTree *non_type_param_without_init(); + CTree *introduce_function(); + CTree *introduce_class(); + CTree *introduce_object(CTree* = 0); + + bool is_class_name(); + bool is_enum_name(); + bool is_typedef_name(); + bool is_template_name(); + bool is_class_template_name(); + bool is_namespace_name(); + + bool is_this_specialization(); + bool is_this_instance(); + void set_this_instance(); + +private: + CTree* getParent(CTree* node, int n = 1); + + template + bool is(CTree* node) const; +}; + +inline InstantiationSemantic::InstantiationSemantic(InstantiationSyntax &s, InstantiationBuilder &b) : + CCSemantic(s, b), _syntax(s) {} + +inline InstantiationBuilder &InstantiationSemantic::builder() const + { return (InstantiationBuilder&) CCSemantic::builder(); } + +inline InstantiationSyntax &InstantiationSemantic::syntax() const + { return (InstantiationSyntax&) _syntax; } + +template +inline bool InstantiationSemantic::is(CTree* node) const + { return node && node->NodeName() == NODE::NodeId(); } + + +} // namespace Puma + +#endif /* __InstantiationSemantic_h__ */ diff --git a/Puma/src/parser/ccparser/instantiation/InstantiationSyntax.cc b/Puma/src/parser/ccparser/instantiation/InstantiationSyntax.cc new file mode 100644 index 0000000..83e7eb3 --- /dev/null +++ b/Puma/src/parser/ccparser/instantiation/InstantiationSyntax.cc @@ -0,0 +1,182 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/InstantiationSyntax.h" +#include "Puma/InstantiationSemantic.h" +#include "Puma/InstantiationBuilder.h" +#include "Puma/InstantiationTokenProvider.h" +#include "Puma/InstantiationTokenSource.h" +#include "Puma/CTokens.h" +#include "Puma/CTree.h" + +namespace Puma { + + +InstantiationSyntax::InstantiationSyntax(InstantiationBuilder &b, InstantiationSemantic &s) : CCSyntax(b, s) { +} + +InstantiationBuilder &InstantiationSyntax::builder() const { + return (InstantiationBuilder&) Syntax::builder(); +} + +InstantiationSemantic &InstantiationSyntax::semantic() const { + return (InstantiationSemantic&) Syntax::semantic(); +} + +InstantiationTokenSource &InstantiationSyntax::source() const { + return (InstantiationTokenSource&)((InstantiationTokenProvider*)token_provider)->source(); +} + +InstantiationTokenProvider &InstantiationSyntax::provider() const { + return (InstantiationTokenProvider&) *token_provider; +} + +void InstantiationSyntax::configure(Config &config) { + // configure the CC syntax + CCSyntax::configure(config); + + // instance function bodies or not + config_skip_fct_body(!config.Option("--inst-fct-bodies")); +} + +bool InstantiationSyntax::isRoot(int up) const { +// CTree* node = provider().node(); + CTree* node = (CTree*)provider().current_context(); + for (int i = 0; i < up && node; i++) + node = node->Parent(); + return node == source().root(); +} + +bool InstantiationSyntax::type_param_without_init() { + return parse(&InstantiationSyntax::rule_type_param_without_init); +} + +CTree *InstantiationSyntax::rule_type_param_without_init() { + // 1: CLASS + // 1: TYPENAME + // 2: CLASS identifier + // 2: TYPENAME identifier + // 5: TEMPLATE < template_param_list > CLASS + // 6: TEMPLATE < template_param_list > CLASS identifier + return ((parse(TOK_CLASS) || + parse(TOK_TYPENAME) || + (parse(TOK_TEMPLATE) && + parse(TOK_LESS) && template_param_list() && parse(TOK_GREATER) && + parse(TOK_CLASS))) && + (Identifier::check(*this) || PrivateName::check(*this))) ? + builder().type_param() : (CTree*)0; +} + +bool InstantiationSyntax::non_type_param_without_init() { + return parse(&InstantiationSyntax::rule_non_type_param_without_init); +} + +CTree *InstantiationSyntax::rule_non_type_param_without_init() { + // 1: decl_spec_seq + // 2: decl_spec_seq abst_declarator + // 2: decl_spec_seq declarator + if (!(DeclSpecSeq::check(*this) && + (Declarator::check(*this) || + abst_declarator() || + PrivateName::check(*this)))) { + semantic().finish_declarator(); + return (CTree*)0; + } + return semantic().non_type_param_without_init(); +} + +bool InstantiationSyntax::class_name() { + // 1: template_id + // 1: ID + if (!semantic().is_class_name()) + return false; + if (!is(2) && semantic().is_this_instance()) { + if (CCSyntax::identifier()) { + semantic().set_this_instance(); + return true; + } + } + return CCSyntax::class_name(); +} + +bool InstantiationSyntax::enum_name() { + // 1: ID + if (!semantic().is_enum_name()) + return false; + return CCSyntax::enum_name(); +} + +bool InstantiationSyntax::typedef_name() { + // 1: ID + if (!semantic().is_typedef_name()) + return false; + return CCSyntax::typedef_name(); +} + +bool InstantiationSyntax::template_name() { + // 1: ID + if (!semantic().is_template_name()) + return false; + return CCSyntax::template_name(); +} + +bool InstantiationSyntax::class_template_name() { + // 1: ID + if (!semantic().is_class_template_name()) + return false; + return CCSyntax::class_template_name(); +} + +bool InstantiationSyntax::namespace_name() { + // 1: ID + if (!semantic().is_namespace_name()) + return false; + return CCSyntax::namespace_name(); +} + +bool InstantiationSyntax::template_id() { + // 3: template_name < > + // 4: template_name < template_arg_list > + if (!is(2)) + return false; + if (semantic().is_this_specialization()) { + if (CCSyntax::identifier()) { + skip_block(TOK_LESS, TOK_GREATER); + return true; + } + } + return CCSyntax::template_id(); +} + + +bool InstantiationSyntax::class_template_id() { + // 3: template_name < > + // 4: template_name < template_arg_list > + if (!is(2)) + return false; + if (semantic().is_this_specialization()) { + if (CCSyntax::identifier()) { + skip_block(TOK_LESS, TOK_GREATER); + return true; + } + } + return CCSyntax::class_template_id(); +} + + +} // namespace Puma diff --git a/Puma/src/parser/ccparser/instantiation/InstantiationSyntax.h b/Puma/src/parser/ccparser/instantiation/InstantiationSyntax.h new file mode 100644 index 0000000..ee9e4c4 --- /dev/null +++ b/Puma/src/parser/ccparser/instantiation/InstantiationSyntax.h @@ -0,0 +1,250 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __InstantiationSyntax_h__ +#define __InstantiationSyntax_h__ + +// Parser for template instances + +#include "Puma/CCSyntax.h" +#include "Puma/CTree.h" +#include "Puma/InstantiationTokenSource.h" +#include "Puma/InstantiationTokenProvider.h" + +namespace Puma { + + +class InstantiationBuilder; +class InstantiationSemantic; + +class InstantiationSyntax : public CCSyntax { +public: + InstantiationSyntax (InstantiationBuilder &, InstantiationSemantic &); + + virtual void configure (Config &); + + InstantiationTokenSource &source () const; + InstantiationTokenProvider &provider () const; + +protected: + InstantiationBuilder &builder () const; + InstantiationSemantic &semantic () const; + +protected: // Optimized parse way helper + bool isRoot(int up) const; + + template + bool is(int up) const; + +protected: // Look-ahead +// virtual bool is_fct_def (); +// virtual bool is_nested_name (); +// virtual bool is_class_def (); +// virtual bool is_tpl_id (); +// virtual bool is_tpl_declarator_id (); +// virtual bool is_ptr_to_fct (); +// virtual bool is_nested (State); +// virtual bool is_ass_expr (); +// +// virtual void init_prim_types (); +// virtual void init_cv_quals (); +// +// virtual void init_explicit_instantiation (); +// virtual void init_explicit_specialization (); +// virtual void init_access_spec (); +// virtual void init_oper_fct_id (); +// virtual void init_template_key (); +// virtual void init_template_id (); +// virtual void init_class_template_id (); + +public: // Grammar rules + + // A.1 Keywords + virtual bool class_name (); + virtual bool enum_name (); + virtual bool template_name (); + virtual bool class_template_name (); + virtual bool namespace_name (); + virtual bool typedef_name (); +// virtual bool original_ns_name (); +// virtual bool namespace_alias (); +// +// // A.2 Lexical conventions +// virtual bool literal (); +// +// // A.4 Expression +// virtual bool prim_expr (); +// virtual bool id_expr (); +// virtual bool qual_id (); +// virtual bool unqual_id (); +// virtual bool colon_colon (); +// virtual bool nested_name_spec (); +// virtual bool nested_name_spec1 (); +// virtual bool class_or_ns_name (); +// virtual bool postfix_expr (); +// virtual bool postfix_expr1 (); +// virtual bool postfix_expr2 (); +// virtual bool construct_expr (); +// virtual bool pseudo_dtor_name (); +// virtual bool unary_expr (); +// virtual bool type_trait_expr (); +// virtual bool new_expr (); +// virtual bool new_placement (); +// virtual bool new_type_id (); +// virtual bool new_declarator (); +// virtual bool direct_new_declarator (); +// virtual bool direct_new_declarator1 (); +// virtual bool new_init (); +// virtual bool delete_expr (); +// virtual bool pm_expr (); +// virtual bool mul_expr (); +// virtual bool rel_expr (); +// virtual bool cond_expr (); +// virtual bool ass_expr (); +// virtual bool ass_expr1 (); +// virtual bool const_expr (); +// virtual bool stmt (); +// virtual bool stmt_seq (); +// virtual bool sub_stmt (); +// virtual bool condition (); +// virtual bool condition1 (); +// virtual bool condition2 (); +// virtual bool decl_stmt (); +// +// // A.6 Declarations +// virtual bool decl (); +// virtual bool decl_check (); +// virtual bool block_decl (); +// virtual bool simple_decl (); +// virtual bool decl_spec_seq1 (); +// virtual bool misc_spec (); +// virtual bool storage_class_spec (); +// virtual bool fct_spec (); +// virtual bool simple_type_spec (); +// virtual bool type_name (); +// virtual bool elaborated_type_spec (); +// virtual bool enumerator_list (); +// virtual bool enumerator_def (); +// virtual bool linkage_spec (); +// +// // A.6.1 Namespaces +// virtual bool namespace_def (); +// virtual bool named_ns_def (); +// virtual bool original_ns_def (); +// virtual bool original_ns_def1 (); +// virtual bool extension_ns_def (); +// virtual bool extension_ns_def1 (); +// virtual bool unnamed_ns_def (); +// virtual bool unnamed_ns_def1 (); +// virtual bool namespace_body (); +// virtual bool ns_alias_def (); +// virtual bool qual_ns_spec (); +// virtual bool using_decl (); +// virtual bool using_directive (); +// +// // A.7 Declarators +// virtual bool init_declarator (); +// virtual bool direct_declarator1 (); +// virtual bool array_delim (); +// virtual bool ptr_operator (); +// virtual bool declarator_id (); +// virtual bool direct_abst_declarator (); +// virtual bool param_decl_clause (); +// virtual bool param_decl (); +// virtual bool param_init (); +// virtual bool fct_def (); +// virtual bool skipped_fct_body (); +// virtual bool fct_body (); +// virtual bool init (); +// virtual bool init_clause (); +// +// // A.8 Classes +// virtual bool class_spec (); +// virtual bool class_head (); +// virtual bool class_head1 (); +// virtual bool member_decl (); +// virtual bool member_decl1 (); +// virtual bool access_decl (); +// virtual bool member_declarator (); +// virtual bool pure_spec (); +// virtual bool const_init (); +// +// // A.9 Derived classes +// virtual bool base_clause (); +// virtual bool base_spec_list (); +// virtual bool base_spec (); +// virtual bool access_spec (); +// +// // A.10 Special member functions +// virtual bool conv_fct_id (); +// virtual bool conv_type_id (); +// virtual bool conv_declarator (); +// virtual bool ctor_init (); +// virtual bool mem_init_list (); +// virtual bool mem_init (); +// virtual bool mem_init_id (); +// +// // A.11 Overloading +// virtual bool oper_fct_id (); +// +// // A.12 Templates +// virtual bool template_key (); +// virtual bool template_decl (); +// virtual bool member_template_decl (); +// virtual bool template_param_list (); +// virtual bool template_param (); +// virtual bool type_param (); +// virtual bool non_type_param (); + virtual bool template_id (); + virtual bool class_template_id (); +// virtual bool template_arg_list (); +// virtual bool template_arg (); +// virtual bool explicit_instantiation (); +// virtual bool explicit_specialization (); + + // Special rules for template parameter instantiation + bool type_param_without_init(); + CTree *rule_type_param_without_init(); + bool non_type_param_without_init(); + CTree *rule_non_type_param_without_init(); + +// // A.13 Exception handling +// virtual bool try_block (); +// virtual bool fct_try_block (); +// virtual bool handler_seq (); +// virtual bool handler (); +// virtual bool exception_decl (); +// virtual bool throw_expr (); +// virtual bool exception_spec (); +// virtual bool type_id_list (); +}; + + +template +inline bool InstantiationSyntax::is(int up) const { +// CTree* node = provider().node(); + CTree* node = (CTree*)provider().current_context(); + for (int i = 0; i < up && node; i++) + node = node->Parent(); + return node ? node->NodeName() == NODE::NodeId() : false; +} + + +} // namespace Puma + +#endif /* __InstantiationSyntax_h__ */ diff --git a/Puma/src/parser/ccparser/instantiation/InstantiationTokenProvider.cc b/Puma/src/parser/ccparser/instantiation/InstantiationTokenProvider.cc new file mode 100644 index 0000000..67e3da1 --- /dev/null +++ b/Puma/src/parser/ccparser/instantiation/InstantiationTokenProvider.cc @@ -0,0 +1,37 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 + +/** \file + * Instantiation token provider implementation. */ + +#include "Puma/InstantiationTokenProvider.h" +#include "Puma/CTree.h" + +namespace Puma { + + +/** Read next token. */ +TokenInfo InstantiationTokenProvider::read() { + TokenInfo ti; + ti._token = _source.next(); + ti._context = ((InstantiationTokenSource&) _source).node(); + return ti; +} + + +} // namespace Puma diff --git a/Puma/src/parser/ccparser/instantiation/InstantiationTokenProvider.h b/Puma/src/parser/ccparser/instantiation/InstantiationTokenProvider.h new file mode 100644 index 0000000..708bda3 --- /dev/null +++ b/Puma/src/parser/ccparser/instantiation/InstantiationTokenProvider.h @@ -0,0 +1,47 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __InstantiationTokenProvider__ +#define __InstantiationTokenProvider__ + +/** \file + * Instantiation token provider. */ + +#include "Puma/TokenProvider.h" +#include "Puma/InstantiationTokenSource.h" + +namespace Puma { + +/** \class InstantiationTokenProvider InstantiationTokenProvider.h Puma/InstantiationTokenProvider.h + * Provides token infos (token pointer + context) from a syntax tree. The context is set to + * the syntax tree node in which the token was found. */ +class InstantiationTokenProvider : public TokenProvider { +protected: + /** Read next token info. */ + virtual TokenInfo read(); + +public: + /** Constructor. + * \param s The token source from which to read the tokens. */ + InstantiationTokenProvider(InstantiationTokenSource &s) : TokenProvider(s) {} +}; + + +} // namespace Puma + +#endif /* __InstantiationTokenProvider__ */ diff --git a/Puma/src/parser/ccparser/instantiation/InstantiationTokenSource.cc b/Puma/src/parser/ccparser/instantiation/InstantiationTokenSource.cc new file mode 100644 index 0000000..4fbde88 --- /dev/null +++ b/Puma/src/parser/ccparser/instantiation/InstantiationTokenSource.cc @@ -0,0 +1,92 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/InstantiationTokenSource.h" +#include "Puma/Token.h" +#include "Puma/CTree.h" +#include "Puma/DelayedParseTree.h" + +namespace Puma { + + +InstantiationTokenSource::InstantiationTokenSource(CTree* root) { + _root = root; + _current = 0; + _first = true; + _detected_delayed_parse_node = false; +} + + +CTree *InstantiationTokenSource::findToken(CTree* node) { + if (! node) + return 0; + const char *node_name = node->NodeName(); + if (node_name == CT_Token::NodeId()) + return node; + else if (node_name == CT_DelayedParseParamInit::NodeId ()) { + _detected_delayed_parse_node = true; + return 0; + } + + CTree* token = 0; + unsigned sons = node->Sons(); + for (unsigned i = 0; i < sons && ! token; i++) + token = findToken(node->Son(i)); + return token; +} + + +Token *InstantiationTokenSource::next() { + if (_first) { + _first = false; + _current = _root ? _root->token_node() : 0; + } + else { + CTree *node = _current, *last = _current, *son; + int sons, idx; + + _current = 0; + + while (node) { + sons = node->Sons(); + if (sons > 1) { + idx = 0; + if (node->IsList()) { + idx = ((CT_List*)node)->Index(last) + 1; + } else { + for (int i = 0; i < sons; i++) { + son = node->Son(i); + if (son == last && (i+1) < sons) { + idx = i + 1; + break; + } + } + } + for (int i = idx; i > 0 && i < sons && !_current; i++) + _current = findToken(node->Son(i)); + } + if (_current || node == _root) + break; + last = node; + node = node->Parent(); + } + } + return (_current ? _current->token () : 0); +} + +} // namespace Puma diff --git a/Puma/src/parser/ccparser/instantiation/InstantiationTokenSource.h b/Puma/src/parser/ccparser/instantiation/InstantiationTokenSource.h new file mode 100644 index 0000000..1b419d8 --- /dev/null +++ b/Puma/src/parser/ccparser/instantiation/InstantiationTokenSource.h @@ -0,0 +1,54 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __Instantiation_Token_Source__ +#define __Instantiation_Token_Source__ + +#include "Puma/TokenSource.h" + +namespace Puma { + + +class Token; +class CT_Token; +class CTree; + +class InstantiationTokenSource : public TokenSource { + CTree* _root; + CTree* _current; + bool _first; + bool _detected_delayed_parse_node; + +private: + CTree *findToken(CTree* node); + +public: + InstantiationTokenSource(CTree* root); + ~InstantiationTokenSource() {} + + Token *next(); + + CTree *root() const { return _root; } + CTree *node() const { return _current; } + bool detectedDelayedParseNode () const { return _detected_delayed_parse_node; } +}; + + +} // namespace Puma + +#endif /* __Instantiation_Token_Source__ */ diff --git a/Puma/src/parser/cparser/CBuilder.cc b/Puma/src/parser/cparser/CBuilder.cc new file mode 100644 index 0000000..276ad47 --- /dev/null +++ b/Puma/src/parser/cparser/CBuilder.cc @@ -0,0 +1,1088 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CBuilder.h" +#include "Puma/CSyntax.h" +#include "Puma/CTokens.h" + +namespace Puma { + + +/*****************************************************************************/ +/* */ +/* A . 1 K e y w o r d s */ +/* */ +/*****************************************************************************/ + +CTree *CBuilder::simple_name () { + return new CT_SimpleName (get_node ()); +} + +/*****************************************************************************/ +/* */ +/* A . 2 L e x i c a l c o n v e n t i o n s */ +/* */ +/*****************************************************************************/ + +CTree *CBuilder::literal () { + if (get_node (0)->NodeName () == CT_String::NodeId () || + get_node (0)->NodeName () == CT_WideString::NodeId ()) + return get_node (); + + CTree *result; + const char *txt = get_node (0)->token ()->text (); + switch (get_node (0)->token ()->type ()) { + case TOK_INT_VAL: + case TOK_ZERO_VAL: + result = new CT_Integer ((CT_Token*)get_node (0)); break; + case TOK_CHAR_VAL: + result = (txt[0] == 'L') ? + (CTree*)new CT_WideCharacter ((CT_Token*)get_node (0)) : + (CTree*)new CT_Character ((CT_Token*)get_node (0)); + break; + case TOK_FLT_VAL: + result = new CT_Float ((CT_Token*)get_node (0)); break; + case TOK_BOOL_VAL: + result = new CT_Bool ((CT_Token*)get_node (0)); break; + default: + result = (CTree*)0; + }; + return result; +} + +CTree *CBuilder::cmpd_str () { + bool wide = false; + for (int i = 0; (i < nodes ()) && ! wide; i++) + if (*(get_node (i)->token ()->text ()) == 'L') + wide = true; + + return (wide) ? list (new CT_WideString (nodes ())) : + list (new CT_String (nodes ())); +} + +CTree *CBuilder::str_literal () { + return get_node (); +} + +/*****************************************************************************/ +/* */ +/* A . 3 B a s i c c o n c e p t s */ +/* */ +/*****************************************************************************/ + +CTree *CBuilder::trans_unit () { + Container *declarations = (Container*)get_node (); + CT_Program *result = new CT_Program (declarations->Sons ()); + copy_list (result, declarations); + delete declarations; + return result; +} + +/*****************************************************************************/ +/* */ +/* A . 4 E x p r e s s i o n s */ +/* */ +/*****************************************************************************/ + +CTree *CBuilder::prim_expr () { + // 1: literal => node + // 1: id_expr => node + // 3: ( expr ) => token node token + if (nodes () == 3) + return new CT_BracedExpr (get_node (0), get_node (1), get_node (2)); + else + return get_node (); +} + +CTree *CBuilder::cmpd_literal () { + // 5 : ( type_id ) { init_list } + // 6 : ( type_id ) { init_list } + CT_ExprList *el; + int num = nodes (); + if (num == 5) { + el = new CT_ExprList (); + } else { + el = (CT_ExprList*)get_node (4); + if ((el->Sons () % 2) == 0) + el->AddProperties (CT_List::END_SEP); + } + el->PrefixSon (get_node (3)); + el->AddSon (get_node (num-1)); + el->AddProperties (CT_List::OPEN_CLOSE); + return new CT_CmpdLiteral (get_node (0), get_node (1), get_node (2), el); +} + +CTree *CBuilder::postfix_expr () { + // 1 : prim_expr + // 1 : cmpd_literal + // 1+: prim_expr postfix_expr1... + // 1+: cmpd_literal postfix_expr1... + CTree *result = get_node (0); + int num = nodes (); + for (int n = 1; n < num; n++) { + Container *c = (Container*)get_node (n); + // 1: -- + // 1: ++ + // 2: . identifier + // 2: -> identifier + // 2: ( ) + // 3: ( expr_list ) + // 3: [ expr ] + int token = c->token ()->type (); + if (token == TOK_DECR || token == TOK_INCR) + result = new CT_PostfixExpr (result, c->Son (0)); + else if (token == TOK_DOT) + result = new CT_MembRefExpr (result, c->Son (0), c->Son (1)); + else if (token == TOK_PTS) + result = new CT_MembPtrExpr (result, c->Son (0), c->Son (1)); + else if (token == TOK_OPEN_SQUARE) + result = new CT_IndexExpr (result, c->Son (0), c->Son (1), c->Son (2)); + else if (token == TOK_OPEN_ROUND) { + bool args = (c->Sons () == 3); + CT_ExprList *el = args ? (CT_ExprList*)c->Son (1) : new CT_ExprList; + if (! args) + Push (el); + el->AddProperties (CT_List::OPEN_CLOSE); + el->PrefixSon (c->Son (0)); + el->AddSon (c->Son (args ? 2 : 1)); + result = new CT_CallExpr (result, el); + } + delete c; + } + return result; +} + +CTree *CBuilder::postfix_expr1 () { + return container (); +} + +CTree *CBuilder::expr_list () { + return list (new CT_ExprList); +} + +CTree *CBuilder::unary_expr () { + // 1: postfix_expr + // 1: offsetof_expr + // 2: -- unary_expr + // 2: ++ unary_expr + // 2: any_unary_op cast_expr + // 2: sizeof unary_expr + // 2: sizeof unary_expr1 + // 2: alignof unary_expr + // 2: alignof unary_expr1 + if (nodes () == 1) + return get_node (); + int token = get_node ()->token ()->type (); + if (token == TOK_AND) + return new CT_AddrExpr (get_node (0), get_node (1)); + if (token == TOK_MUL) + return new CT_DerefExpr (get_node (0), get_node (1)); + if (token == TOK_SIZEOF) { + if (get_node (1)->NodeName () == Container::NodeId ()) { + Container *c = (Container*) get_node (1); + CTree *result = new CT_SizeofExpr (get_node (0), + c->Son (0), c->Son (1), c->Son (2)); + delete c; + return result; + } else + return new CT_SizeofExpr (get_node (0), get_node (1)); + } + if (token == TOK_ALIGNOF) { + if (get_node (1)->NodeName () == Container::NodeId ()) { + Container *c = (Container*) get_node (1); + CTree *result = new CT_AlignofExpr (get_node (0), + c->Son (0), c->Son (1), c->Son (2)); + delete c; + return result; + } else + return new CT_AlignofExpr (get_node (0), get_node (1)); + } + return new CT_UnaryExpr (get_node (0), get_node (1)); +} + +CTree *CBuilder::unary_expr1 () { + // 3: ( type_id ) + return container (); +} + +CTree *CBuilder::cast_expr () { + // 1: cast_expr1 + // 1: unary_expr + return get_node (); +} + +CTree *CBuilder::cast_expr1 () { + // 2+: cast_expr2... unary_expr + int num = nodes (); + CTree *result = get_node (num - 1); + for (int i = num - 2; i >= 0; i--) { + Container *c = (Container*) get_node (i); + result = new CT_CastExpr (c->Son (0), c->Son (1), c->Son (2), result); + delete c; + } + return result; +} + +CTree *CBuilder::cast_expr2 () { + // 3: ( type_id ) + return container (); +} + +CTree *CBuilder::offsetof_expr () { + // 6: OFFSETOF ( type_spec , memb_designator ) + return new CT_OffsetofExpr (get_node (0), get_node (1), + get_node (2), get_node (3), get_node (4), get_node (5)); +} + +CTree *CBuilder::memb_designator () { + // 1 : identifier + // 2+: identifier designator... + CT_DesignatorSeq *result = new CT_DesignatorSeq (nodes ()); + for (int i = 0; i < nodes (); i++) + result->AddSon (get_node (i)); + return result; +} + +// helper function for binary expression +CTree *CBuilder::lr_bin_expr () { + CTree *result = get_node (0); + for (int n = 1; n < nodes (); n += 2) + result = new CT_BinaryExpr (result, get_node (n), get_node (n + 1)); + return result; +} + +CTree *CBuilder::mul_expr () { return lr_bin_expr (); } +CTree *CBuilder::add_expr () { return lr_bin_expr (); } +CTree *CBuilder::shift_expr () { return lr_bin_expr (); } +CTree *CBuilder::rel_expr () { return lr_bin_expr (); } +CTree *CBuilder::equ_expr () { return lr_bin_expr (); } +CTree *CBuilder::and_expr () { return lr_bin_expr (); } +CTree *CBuilder::excl_or_expr () { return lr_bin_expr (); } +CTree *CBuilder::incl_or_expr () { return lr_bin_expr (); } +CTree *CBuilder::log_and_expr () { return lr_bin_expr (); } +CTree *CBuilder::log_or_expr () { return lr_bin_expr (); } +CTree *CBuilder::expr () { return lr_bin_expr (); } + +CTree *CBuilder::cond_expr () { + CTree *result = get_node (0); + if (nodes () == 5) + result = new CT_IfThenExpr (result, get_node (1), get_node (2), + get_node (3), get_node (4)); + return result; +} + +CTree *CBuilder::ass_expr () { + // 1 : cond_expr + // 2+: ass_expr1... cond_expr + int num = nodes (); + CTree *result = get_node (num - 1); + for (int i = num - 2; i >= 0; i--) { + Container *c = (Container*) get_node (i); + result = new CT_BinaryExpr (c->Son (0), c->Son (1), result); + delete c; + } + return result; +} + +CTree *CBuilder::ass_expr1 () { + return container (); +} + +CTree *CBuilder::const_expr () { + return get_node (); +} + +/*****************************************************************************/ +/* */ +/* A . 5 S t a t e m e n t s */ +/* */ +/*****************************************************************************/ + +CTree *CBuilder::stmt () { + return get_node (); +} + +CTree *CBuilder::label_stmt () { + // 3: identifier : stmt => node token node + // 3: DEFAULT : stmt => token token node + // 4: CASE const_expr : stmt => token node token node + if (nodes () == 3) { + if (get_node (0)->NodeName () == CT_SimpleName::NodeId ()) { + return new CT_LabelStmt (get_node (0), get_node (1), get_node (2)); + } else + return new CT_DefaultStmt (get_node (0), get_node (1), get_node (2)); + } else + return new CT_CaseStmt (get_node (0), get_node (1), get_node (2), + get_node (3)); +} + +CTree *CBuilder::expr_stmt () { + // 1: ; + // 2: expr ; + if (nodes () == 1) + return new CT_ExprStmt ((CTree*)0, get_node (0)); + else + return new CT_ExprStmt (get_node (0), get_node (1)); +} + +CTree *CBuilder::cmpd_stmt () { + // 2: { } => token token + // 3: { stmt_seq } => token cont token + CT_CmpdStmt *result = new CT_CmpdStmt; + result->AddSon (get_node (0)); + if (nodes () == 3) { + Container *container = (Container*)get_node (1); + for (int i = 0; i < container->Sons (); i++) + result->AddSon (container->Son (i)); + delete container; + result->AddSon (get_node (2)); + } else + result->AddSon (get_node (1)); + return result; +} + +CTree *CBuilder::stmt_seq () { + return container (); +} + +CTree *CBuilder::select_stmt () { + // 5: SWITCH ( condition ) sub_stmt + // 5: IF ( condition ) sub_stmt + // 7: IF ( condition ) sub_stmt ELSE sub_stmt + if (get_node (0)->token ()->type () == TOK_SWITCH) + return new CT_SwitchStmt (get_node (0), get_node (1), get_node (2), + get_node (3), get_node (4)); + else if (nodes () == 5) + return new CT_IfStmt (get_node (0), get_node (1), get_node (2), + get_node (3), get_node (4)); + else + return new CT_IfElseStmt (get_node (0), get_node (1), get_node (2), + get_node (3), get_node (4), get_node (5), get_node (6)); +} + +CTree *CBuilder::sub_stmt () { + return get_node (); +} + +CTree *CBuilder::condition (CTree *) { + return get_node (); +} + +CTree *CBuilder::iter_stmt () { + // 5: WHILE ( condition ) sub_stmt + // 6: FOR ( for_init_stmt ; ) sub_stmt + // 7: DO sub_stmt WHILE ( expr ) ; + // 7: FOR ( for_init_stmt ; expr ) sub_stmt + // 7: FOR ( for_init_stmt condition ; ) sub_stmt + // 8: FOR ( for_init_stmt condition ; expr ) sub_stmt + if (nodes () == 5) { + return new CT_WhileStmt (get_node (0), get_node (1), get_node (2), + get_node (3), get_node (4)); + } else if (nodes () == 6) { + return new CT_ForStmt (get_node (0), get_node (1), get_node (2), + (CTree*)0, get_node (3), (CTree*)0, + get_node (4), get_node (5)); + } else if (nodes () == 7) { + if (get_node (0)->token ()->type () == TOK_DO) { + return new CT_DoStmt (get_node (0), get_node (1), get_node (2), + get_node (3), get_node (4), get_node (5), + get_node (6)); + } else if (get_node (3)->token ()->type () == TOK_SEMI_COLON) { + return new CT_ForStmt (get_node (0), get_node (1), get_node (2), + (CTree*)0, get_node (3), get_node (4), + get_node (5), get_node (6)); + } else { + return new CT_ForStmt (get_node (0), get_node (1), get_node (2), + get_node (3), get_node (4), (CTree*)0, + get_node (5), get_node (6)); + } + } else { // nodes () == 8 + return new CT_ForStmt (get_node (0), get_node (1), get_node (2), + get_node (3), get_node (4), get_node (5), + get_node (6), get_node (7)); + } +} + +CTree *CBuilder::for_init_stmt () { + // 1: expr_stmt + // 1: simple_decl + return get_node (); +} + +CTree *CBuilder::jump_stmt () { + // 2: BREAK ; + // 2: CONTINUE ; + // 2: RETURN ; + // 3: RETURN expression ; + // 3: GOTO identifier ; + CT_Token *token = (CT_Token*)get_node (0); + if (token->token ()->type () == TOK_BREAK) + return new CT_BreakStmt (token, get_node (1)); + else if (token->token ()->type () == TOK_CONTINUE) + return new CT_ContinueStmt (token, get_node (1)); + else if (token->token ()->type () == TOK_GOTO) + return new CT_GotoStmt (token, get_node (1), get_node (2)); + else { // RETURN + if (nodes () == 2) { + return new CT_ReturnStmt (token, (CTree*)0, get_node (1)); + } else { + return new CT_ReturnStmt (token, get_node (1), get_node (2)); + } + } +} + +/*****************************************************************************/ +/* */ +/* A . 6 D e c l a r a t i o n s */ +/* */ +/*****************************************************************************/ + +CTree *CBuilder::decl_seq () { + return container (); +} + +CTree *CBuilder::decl () { + return get_node (); +} + +CTree *CBuilder::block_decl () { + return get_node (); +} + +CTree *CBuilder::simple_decl () { + int offset = 0; + CT_DeclSpecSeq *dss; + if (get_node ()->NodeName () == CT_DeclSpecSeq::NodeId ()) + dss = (CT_DeclSpecSeq*)get_node (offset++); + else //{ + dss = new CT_DeclSpecSeq; +// Push (dss); +// } + CT_DeclaratorList *dl; + if (offset + 1 < nodes ()) + dl = (CT_DeclaratorList*)get_node (offset++); + else //{ + dl = new CT_DeclaratorList; +// Push (dl); +// } + return new CT_ObjDecl (dss, dl, get_node (offset)); +} + +CTree *CBuilder::decl_spec () { + return get_node (); +} + +CTree *CBuilder::decl_spec_seq () { + return list (new CT_DeclSpecSeq); +} + +CTree *CBuilder::decl_spec_seq1 () { + return get_node (); +} + +// helper function for primitive declaration specifiers +CTree *CBuilder::prim_ds () { + return new CT_PrimDeclSpec ((CT_Token*)get_node ()); +} + +CTree *CBuilder::misc_spec () { return prim_ds (); } +CTree *CBuilder::storage_class_spec () { return prim_ds (); } +CTree *CBuilder::fct_spec () { return prim_ds (); } + +CTree *CBuilder::type_spec () { + return get_node (); +} + +CTree *CBuilder::simple_type_spec () { + return (get_node ()->NodeName () == CT_Token::NodeId ()) ? + prim_ds () : get_node (); +} + +CTree *CBuilder::type_name () { + return get_node (); +} + +CTree *CBuilder::elaborated_type_spec () { + // 2: class_key identifier + // 2: ENUM identifier + int token = get_node ()->token ()->type (); + if (token == TOK_CLASS || token == TOK_STRUCT) + return new CT_ClassSpec (get_node (0), get_node (1)); + if (token == TOK_UNION) + return new CT_UnionSpec (get_node (0), get_node (1)); + else // TOK_ENUM + return new CT_EnumSpec (get_node (0), get_node (1)); +} + +CTree *CBuilder::enum_key () { + return get_node (); +} + +CTree *CBuilder::enum_spec () { + // 4: enum_spec1 { enumerator_list } + CT_EnumeratorList *el = (CT_EnumeratorList*)get_node (2); + if (el->Sons () > 0 && (el->Sons () % 2) == 0) + el->AddProperties (CT_List::END_SEP); + el->PrefixSon (get_node (1)); + el->AddSon (get_node (3)); + CT_EnumDef *result = (CT_EnumDef*)get_node (0); + result->Enumerators (el); + return result; +} + +CTree *CBuilder::enum_spec1 () { + // 2: ENUM identifier + // 2: ENUM private_name + return new CT_EnumDef (get_node (0), get_node (1)); +} + +CTree *CBuilder::enumerator_list () { + return list (new CT_EnumeratorList); +} + +CTree *CBuilder::enumerator_def () { + // 1: enumerator + // 3: enumerator = const_expr + CT_Enumerator *e = (CT_Enumerator*)get_node (0); + if (nodes () == 3) { + CT_ExprList *el = new CT_ExprList; +// Push (el); + el->AddSon (get_node (1)); + el->AddSon (get_node (2)); + el->AddProperties (CT_List::INTRO); + e->Initializer (el); + } + return e; +} + +CTree *CBuilder::enumerator () { + return new CT_Enumerator (get_node ()); +} + +CTree *CBuilder::asm_def () { + // 1: ASM ( str_literal ) ; + return new CT_AsmDef (get_node (0), get_node (1), get_node (2), + get_node (3), get_node (4)); +} + + +/*****************************************************************************/ +/* */ +/* A . 7 D e c l a r a t o r s */ +/* */ +/*****************************************************************************/ + +CTree *CBuilder::init_declarator_list () { + return list (new CT_DeclaratorList); +} + +CTree *CBuilder::init_declarator () { + CTree *id = get_node (); + if (nodes () == 2 && get_node (1)->NodeName () == CT_ExprList::NodeId ()) + ((CT_InitDeclarator*)id)->Initializer (get_node (1)); + return id; +} + +CTree *CBuilder::init_declarator1 () { + return new CT_InitDeclarator (get_node (0)); +} + +CTree *CBuilder::declarator () { + // 1 : direct_declarator + // 2+: ptr_operator.. direct_declarator + int num = nodes (); + CTree *result = get_node (num-1); + for (int i = num-1; i > 0; i--) { + Container *p = (Container*)get_node (i-1); // ptr-operator + if (p->Sons () == 1) + result = new CT_PtrDeclarator (p->Son (0), (CTree*)0, result); + else if (p->Sons () == 2) + result = new CT_PtrDeclarator (p->Son (0), p->Son (1), result); + delete p; + } + return result; +} + +CTree *CBuilder::direct_declarator () { + // 1 : declarator_id => node + // 2+: declarator_id direct_declarator1... => node cont... + // 3 : ( declarator ) => token node token + // 3+: ( declarator ) direct_declarator1... => token node token cont... + if (nodes () == 1) + return get_node (0); + + CTree *result; + int braced = (get_node (0)->token ()->type () == TOK_OPEN_ROUND) ? 2 : 0; + if (! braced) + result = get_node (0); + else { + // win specific declaration specifier + if (get_node (2)->token ()->type () != TOK_CLOSE_ROUND) { + braced++; + result = new CT_BracedDeclarator (get_node (0), get_node (1), get_node (2), get_node (3)); + } else + result = new CT_BracedDeclarator (get_node (0), get_node (1), get_node (2)); + // braced declarator only + if (nodes () == braced+1) + return result; + } + + for (int i = 1 + braced; i < nodes (); i++) { + Container *d1 = (Container*)get_node (i); + if (d1->Son (0)->token ()->type () == TOK_OPEN_SQUARE) + result = new CT_ArrayDeclarator (result, d1->Son (0), d1->Son (1), + d1->Son (2)); + else { + CT_ArgDeclList *args = (CT_ArgDeclList*)d1->Son (1); + args->PrefixSon (d1->Son (0)); + args->AddSon (d1->Son (2)); + if (d1->Sons () == 4) { + if (d1->Son (3)->NodeName () == CT_DeclSpecSeq::NodeId ()) + result = new CT_FctDeclarator (result, args, d1->Son (3), 0); + else + result = new CT_FctDeclarator (result, args, 0, d1->Son (3)); + } else if (d1->Sons () == 5) { + result = new CT_FctDeclarator (result, args, d1->Son (3), d1->Son (4)); + } else + result = new CT_FctDeclarator (result, args, 0, 0); + } + delete d1; + } + return result; +} + +CTree *CBuilder::direct_declarator1 () { + // 3: [ array_delim ] + // 3: ( param_decl_clause ) + // 3: ( identifier_list ) + return container (); +} + +CTree *CBuilder::identifier_list () { + return list (new CT_ArgNameList); +} + +CTree *CBuilder::array_delim () { + // 0: + // 1: * + // 1: ass_expr + // 1: cv_qual_seq + // 2: cv_qual_seq * + // 2: cv_qual_seq ass_expr + // 2: STATIC ass_expr + // 3: STATIC cv_qual_seq ass_expr + // 3: cv_qual_seq STATIC ass_expr + bool pos0 = false; + CTree *star, *stat, *quals, *expr = star = stat = quals = (CTree*)0; + if (nodes () == 1) { + if (get_node (0)->NodeName () == CT_DeclSpecSeq::NodeId ()) + quals = get_node (0); + else if (get_node (0)->NodeName () == CT_Token::NodeId () && + get_node (0)->token ()->type () == TOK_MUL) + star = get_node (0); + else + expr = get_node (0); + } else if (nodes () == 2) { + if (get_node (0)->NodeName () == CT_Token::NodeId ()) { + stat = get_node (0); + expr = get_node (1); + } else { + quals = get_node (0); + if (get_node (1)->NodeName () == CT_Token::NodeId () && + get_node (1)->token ()->type () == TOK_MUL) + star = get_node (1); + else + expr = get_node (1); + } + } else if (nodes () == 3) { + if (get_node (0)->NodeName () == CT_Token::NodeId ()) { + stat = get_node (0); + quals = get_node (1); + } else { + quals = get_node (0); pos0 = true; + stat = get_node (1); + } + expr = get_node (2); + } + if (pos0) + return new CT_ArrayDelimiter (star, quals, stat, expr, pos0); + return new CT_ArrayDelimiter (star, stat, quals, expr, pos0); +} + +CTree *CBuilder::ptr_operator () { + return container (); +} + +CTree *CBuilder::cv_qual_seq () { + return list (new CT_DeclSpecSeq); +} + +CTree *CBuilder::cv_qual () { + return prim_ds (); +} + +CTree *CBuilder::declarator_id () { + return get_node (); +} + +CTree *CBuilder::type_id () { + return new CT_NamedType (get_node (0), get_node (1)); +} + +CTree *CBuilder::abst_declarator () { + // 1 : direct_abst_declarator + // 1+: ptr_operator.. + // 2+: ptr_operator.. direct_abst_declarator + return declarator (); +} + +CTree *CBuilder::direct_abst_declarator () { + // 1 : direct_abst_declarator1 => cont + // 2+: direct_abst_declarator1 direct_abst_declarator1... => cont cont... + // 3 : ( abst_declarator ) => token node token + // 3+: ( abst_declarator ) direct_abst_declarator1... => token node token cont... + CTree *result; + int braced = (get_node (0)->NodeName () != Container::NodeId ()) ? 3 : 0; + if (! braced) + result = get_node (nodes () - 1); // PrivateName, pushed by semantic + else { + // win specific declaration specifier + if (get_node (2)->token ()->type () != TOK_CLOSE_ROUND) { + braced++; + result = new CT_BracedDeclarator (get_node (0), get_node (1), get_node (2), get_node (3)); + } else + result = new CT_BracedDeclarator (get_node (0), get_node (1), get_node (2)); + // braced declarator only + if (nodes () == braced) + return result; + } + + int num = nodes () - (braced ? 0 : 1); + for (int i = 0 + braced; i < num; i++) { + Container *d1 = (Container*)get_node (i); + if (d1->Son (0)->token ()->type () == TOK_OPEN_SQUARE) { + if (d1->Son (1)->NodeName () == CT_ArrayDelimiter::NodeId ()) { + result = new CT_ArrayDeclarator (result, d1->Son (0), d1->Son (1), d1->Son (2)); + } else if (d1->Son (1)->token ()->type () == TOK_CLOSE_SQUARE) { + result = new CT_ArrayDeclarator (result, d1->Son (0), + new CT_ArrayDelimiter (0, 0, 0, 0), d1->Son (1)); + } else if (d1->Son (1)->NodeName () == CT_Token::NodeId () && + d1->Son (1)->token ()->type () == TOK_MUL) { + result = new CT_ArrayDeclarator (result, d1->Son (0), + new CT_ArrayDelimiter (d1->Son (1), 0, 0, 0), d1->Son (2)); + } else { + result = new CT_ArrayDeclarator (result, d1->Son (0), + new CT_ArrayDelimiter (0, 0, 0, d1->Son (1)), d1->Son (2)); + } + } else { + CT_ArgDeclList *args = (CT_ArgDeclList*)d1->Son (1); + args->PrefixSon (d1->Son (0)); + args->AddSon (d1->Son (2)); + if (d1->Sons () == 4) { + if (d1->Son (3)->NodeName () == CT_DeclSpecSeq::NodeId ()) + result = new CT_FctDeclarator (result, args, d1->Son (3), 0); + else + result = new CT_FctDeclarator (result, args, 0, d1->Son (3)); + } else if (d1->Sons () == 5) { + result = new CT_FctDeclarator (result, args, d1->Son (3), d1->Son (4)); + } else + result = new CT_FctDeclarator (result, args, 0, 0); + } + delete d1; + } + return result; +} + +CTree *CBuilder::direct_abst_declarator1 () { + // 2: [ ] + // 3: [ * ] + // 3: [ ass_expr ] + // 3: ( param_decl_clause ) + return container (); +} + +CTree *CBuilder::param_decl_clause () { + // 0: => + // 1: ... => token + // 1: param_decl_list => cont + // 2: param_decl_list ... => cont token + if (nodes () == 0) + return new CT_ArgDeclList (); + + CT_ArgDeclList *result; + if (get_node (0)->NodeName () != Container::NodeId ()) { + result = new CT_ArgDeclList (); + result->AddSon (new CT_ArgDecl (get_node (0))); + return result; + } + + Container *al = (Container*)get_node (0); + int add_args = (nodes () == 2) ? 1 : 0; + result = new CT_ArgDeclList (al->Sons () + add_args); + copy_list (result, al); + if (add_args) { + if ((al->Sons () % 2) == 1) + result->AddProperties (CT_List::NO_LAST_SEP); + result->AddSon (new CT_ArgDecl (get_node (nodes ()-1))); // ... + } + + delete al; + return result; +} + +CTree *CBuilder::param_decl_list () { + return container (); +} + +CTree *CBuilder::param_decl () { + // 1: param_decl1 + // 3: param_decl1 param_init + CT_ArgDecl *ad = (CT_ArgDecl*)get_node (0); + if (nodes () == 2) + ad->Initializer (get_node (1)); + return ad; +} + +CTree *CBuilder::param_decl1 () { + // 2: decl_spec_seq abst_declarator + // 2: decl_spec_seq declarator + // 2: decl_spec_seq private_name + return new CT_ArgDecl (get_node (0), get_node (1)); +} + +CTree *CBuilder::fct_def () { + // 2: declarator fct_body + // 2: declarator fct_try_block + // 3: declarator ctor_init fct_body + // 3: declarator arg_decl_seq fct_body + // 3: decl_spec_seq declarator fct_body + // 3: decl_spec_seq declarator fct_try_block + // 4: decl_spec_seq declarator ctor_init fct_body + // 4: decl_spec_seq declarator arg_decl_seq fct_body + CTree *dss, *hs, *ci, *as, *t = dss = hs = ci = as = (CTree*)0; + CTree *d, *b = 0; + if (get_node (0)->NodeName () == CT_DeclSpecSeq::NodeId ()) + dss = get_node (0); + int offset = dss ? 1 : 0; + d = get_node (offset); + if (nodes () == 1 || (nodes () == 2 && + get_node (1)->NodeName () != CT_CmpdStmt::NodeId () && + get_node (1)->NodeName () != Container::NodeId ())) { + b = 0; // parse delayed + } else if (get_node (1+offset)->NodeName () == CT_CmpdStmt::NodeId ()) { + b = get_node (1+offset); + } else if (get_node (1+offset)->NodeName () == CT_MembInitList::NodeId () || + get_node (1+offset)->NodeName () == CT_ExprList::NodeId ()) { + ci = get_node (1+offset); + b = get_node (2+offset); + } else if (get_node (1+offset)->NodeName () == CT_ArgDeclSeq::NodeId ()) { + as = get_node (1+offset); + b = get_node (2+offset); + } else { + Container *cont = (Container*)get_node (1+offset); + t = cont->Son (0); + if (cont->Son (1)->NodeName () == CT_MembInitList::NodeId ()) + ci = cont->Son (1); + offset = ci ? 1 : 0; + b = cont->Son (1+offset); + hs = cont->Son (2+offset); + delete cont; + } + return new CT_FctDef (dss, d, t, ci, as, b, hs); +} + +CTree *CBuilder::arg_decl_seq () { + return list (new CT_ArgDeclSeq (nodes ())); +} + +CTree *CBuilder::fct_body () { + // 1: cmpd_stmt + return get_node (0); +} + +CTree *CBuilder::init () { + // 2: = init_clause + // 3: ( expr_list ) + CT_ExprList *result; + if (get_node (1)->NodeName () != CT_ExprList::NodeId ()) { + result = new CT_ExprList; + result->AddSon (get_node (1)); + } else + result = (CT_ExprList*)get_node (1); + + result->PrefixSon (get_node (0)); + if (nodes () == 2) // = init_clause + result->AddProperties (CT_List::INTRO); + else { // ( expr_list ) + result->AddSon (get_node (2)); + result->AddProperties (CT_List::OPEN_CLOSE); + } + return result; +} + +CTree *CBuilder::init_clause () { + // 1: ass_expr + // 2: { } + // 3: { init_list } + if (nodes () == 1) + return get_node (0); + + CT_ExprList *result = 0; + if (nodes () == 2) { // "{ }" + result = new CT_ExprList; + result->AddSon (get_node (0)); + result->AddSon (get_node (1)); + } else if (nodes () == 3) { // "{ init_list }" + result = (CT_ExprList*)get_node (1); + if ((result->Sons () % 2) == 0) + result->AddProperties (CT_List::END_SEP); + result->PrefixSon (get_node (0)); + result->AddSon (get_node (2)); + } + result->AddProperties (CT_List::OPEN_CLOSE); + return result; +} + +CTree *CBuilder::init_list () { + return list (new CT_ExprList); +} + +CTree *CBuilder::init_list_item () { + // 1: init_clause + // 2: designation init_clause + if (nodes () == 1) + return get_node (); + Container *c = (Container*)get_node (0); + CTree *result = new CT_BinaryExpr (c->Son (0), c->Son (1), get_node (1)); + delete c; + return result; +} + +CTree *CBuilder::designation () { + // 2+: designator... = + CT_DesignatorSeq *ds = new CT_DesignatorSeq (nodes () - 1); + for (int i = 0; i < nodes () - 1; i++) + ds->AddSon (get_node (i)); + Container *result = new Container; + result->AddSon (ds); + result->AddSon (get_node (nodes () - 1)); + return result; +} + +CTree *CBuilder::designator () { + // 2: . identifier + // 3: [ const_expr ] + if (nodes () == 2) + return new CT_MembDesignator (get_node (0), get_node (1)); + else + return new CT_IndexDesignator (get_node (0), get_node (1), get_node (2)); +} + +/*****************************************************************************/ +/* */ +/* A . 8 C l a s s e s */ +/* */ +/*****************************************************************************/ + +CTree *CBuilder::class_spec () { + CT_ClassDef *result = (CT_ClassDef*)get_node (0); + CT_MembList *ml = nodes () == 4 ? + (CT_MembList*)get_node (2) : new CT_MembList; + ml->PrefixSon (get_node (1)); + ml->AddSon (get_node (nodes () - 1)); + ml->AddProperties (CT_List::OPEN_CLOSE); + result->Members (ml); + return result; +} + +CTree *CBuilder::class_head () { + CT_ClassDef *result; + if (get_node (0)->token ()->type () == TOK_UNION) + result = new CT_UnionDef (get_node (0), get_node (1)); + else + result = new CT_ClassDef (get_node (0), get_node (1)); + return result; +} + +CTree *CBuilder::class_key () { + return get_node (); +} + +CTree *CBuilder::member_spec () { + return list (new CT_MembList); +} + +CTree *CBuilder::member_decl () { + // 1: ; + // 2: type_spec_seq ; + // 3: type_spec_seq member_declarator_list ; + if (nodes () == 1) { + return new CT_ObjDecl (new CT_DeclSpecSeq, new CT_DeclaratorList, get_node (0)); + } + else if (nodes () == 2) + return new CT_ObjDecl (get_node (0), new CT_DeclaratorList, get_node (1)); + else + return new CT_ObjDecl (get_node (0), get_node (1), get_node (2)); +} + +CTree *CBuilder::member_declarator_list () { + return list (new CT_DeclaratorList); +} + +CTree *CBuilder::member_declarator () { + // 1: declarator + // 3: declarator : const_expr + // 3: private_name : const_expr + if (nodes () == 1) + return new CT_InitDeclarator (get_node (0)); + else + return new CT_BitFieldDeclarator (get_node (0), get_node (1), get_node (2)); +} + +/*****************************************************************************/ +/* */ +/* A . 9 D e r i v e d c l a s s e s */ +/* */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* */ +/* A . 1 0 S p e c i a l m e m b e r f u n c t i o n s */ +/* */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* */ +/* A . 1 1 O v e r l o a d i n g */ +/* */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* */ +/* A . 1 2 T e m p l a t e s */ +/* */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* */ +/* A . 1 3 E x c e p t i o n h a n d l i n g */ +/* */ +/*****************************************************************************/ + + +} // namespace Puma diff --git a/Puma/src/parser/cparser/CBuilder.h b/Puma/src/parser/cparser/CBuilder.h new file mode 100644 index 0000000..e731b5b --- /dev/null +++ b/Puma/src/parser/cparser/CBuilder.h @@ -0,0 +1,159 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CBuilder_h__ +#define __CBuilder_h__ + +#include "Puma/Builder.h" + +namespace Puma { + + +class CBuilder : public Builder { +public: + CBuilder () {} + +public: + // functions to create several kinds of syntax trees + + // A.1 Keywords + virtual CTree *simple_name (); + + // A.2 Lexical conventions + virtual CTree *literal (); + virtual CTree *cmpd_str (); + virtual CTree *str_literal (); + + // A.3 Basic concepts + virtual CTree *trans_unit (); + + // A.4 Expression + virtual CTree *prim_expr (); + virtual CTree *cmpd_literal (); + virtual CTree *postfix_expr (); + virtual CTree *postfix_expr1 (); + virtual CTree *expr_list (); + virtual CTree *unary_expr (); + virtual CTree *unary_expr1 (); + virtual CTree *cast_expr (); + virtual CTree *cast_expr1 (); + virtual CTree *cast_expr2 (); + virtual CTree *offsetof_expr (); + virtual CTree *memb_designator (); + virtual CTree *mul_expr (); + virtual CTree *add_expr (); + virtual CTree *shift_expr (); + virtual CTree *rel_expr (); + virtual CTree *equ_expr (); + virtual CTree *and_expr (); + virtual CTree *excl_or_expr (); + virtual CTree *incl_or_expr (); + virtual CTree *log_and_expr (); + virtual CTree *log_or_expr (); + virtual CTree *cond_expr (); + virtual CTree *ass_expr (); + virtual CTree *ass_expr1 (); + virtual CTree *expr (); + virtual CTree *const_expr (); + + // A.5 Statements + virtual CTree *stmt (); + virtual CTree *label_stmt (); + virtual CTree *expr_stmt (); + virtual CTree *cmpd_stmt (); + virtual CTree *stmt_seq (); + virtual CTree *select_stmt (); + virtual CTree *sub_stmt (); + virtual CTree *condition (CTree * = (CTree*)0); + virtual CTree *iter_stmt (); + virtual CTree *for_init_stmt (); + virtual CTree *jump_stmt (); + + // A.6 Declarations + virtual CTree *decl_seq (); + virtual CTree *decl (); + virtual CTree *block_decl (); + virtual CTree *simple_decl (); + virtual CTree *decl_spec (); + virtual CTree *misc_spec (); + virtual CTree *decl_spec_seq (); + virtual CTree *decl_spec_seq1 (); + virtual CTree *storage_class_spec (); + virtual CTree *fct_spec (); + virtual CTree *type_spec (); + virtual CTree *simple_type_spec (); + virtual CTree *type_name (); + virtual CTree *elaborated_type_spec (); + virtual CTree *enum_key (); + virtual CTree *enum_spec (); + virtual CTree *enum_spec1 (); + virtual CTree *enumerator_list (); + virtual CTree *enumerator_def (); + virtual CTree *enumerator (); + virtual CTree *asm_def (); + + // A.7 Declarators + virtual CTree *init_declarator_list (); + virtual CTree *init_declarator (); + virtual CTree *init_declarator1 (); + virtual CTree *declarator (); + virtual CTree *direct_declarator (); + virtual CTree *direct_declarator1 (); + virtual CTree *identifier_list (); + virtual CTree *array_delim (); + virtual CTree *ptr_operator (); + virtual CTree *cv_qual_seq (); + virtual CTree *cv_qual (); + virtual CTree *declarator_id (); + virtual CTree *type_id (); + virtual CTree *abst_declarator (); + virtual CTree *direct_abst_declarator (); + virtual CTree *direct_abst_declarator1 (); + virtual CTree *param_decl_clause (); + virtual CTree *param_decl_list (); + virtual CTree *param_decl (); + virtual CTree *param_decl1 (); + virtual CTree *fct_def (); + virtual CTree *arg_decl_seq (); + virtual CTree *fct_body (); + virtual CTree *init (); + virtual CTree *init_clause (); + virtual CTree *init_list (); + virtual CTree *init_list_item (); + virtual CTree *designation (); + virtual CTree *designator (); + + // A.8 Classes + virtual CTree *class_spec (); + virtual CTree *class_head (); + virtual CTree *class_key (); + virtual CTree *member_spec (); + virtual CTree *member_decl (); + virtual CTree *member_declarator_list (); + virtual CTree *member_declarator (); + +protected: + // helper functions + CTree *lr_bin_expr (); + CTree *prim_ds (); +}; + + +} // namespace Puma + +#endif /* __CBuilder_h__ */ diff --git a/Puma/src/parser/cparser/CBuilderExtension.ah b/Puma/src/parser/cparser/CBuilderExtension.ah new file mode 100644 index 0000000..bdd942e --- /dev/null +++ b/Puma/src/parser/cparser/CBuilderExtension.ah @@ -0,0 +1,760 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CBuilderExtension_ah__ +#define __CBuilderExtension_ah__ + +// TODO: For now the semantic analysis binding is integrated here. This is +// due to a problem with ac++ 1.0pre3, which has problems with advice on +// introduced code. Later this should be implemented by advice. + +namespace Puma { + +slice class CPrivateNameBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.semantic().PrivateName(); + } + }; + +slice class CTypedefNameBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.semantic().typedef_name(); + } + }; + + slice class CIdentifierBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().simple_name (); + } + }; + + slice class CLiteralBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().literal (); + } + }; + + slice class CStrLiteralBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().str_literal (); + } + }; + + slice class CCmpdStrBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().cmpd_str (); + } + }; + + slice class CTransUnitBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().trans_unit (); + } + }; + + slice class CPrimExprBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().prim_expr (); + } + }; + + slice class CIdExprBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().simple_name (); + } + }; + + slice class CCmpdLiteralBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().cmpd_literal (); + } + }; + + slice class CPostfixExprBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().postfix_expr (); + } + }; + + slice class CPostfixExpr1Builder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().postfix_expr1 (); + } + }; + + slice class CExprListBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().expr_list (); + } + }; + + slice class CUnaryExprBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().unary_expr (); + } + }; + + slice class CUnaryExpr1Builder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().unary_expr1 (); + } + }; + + slice class CCastExprBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().cast_expr (); + } + }; + + slice class CCastExpr1Builder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().cast_expr1 (); + } + }; + + slice class CCastExpr2Builder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().cast_expr2 (); + } + }; + + slice class COffsetofExprBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().offsetof_expr (); + } + }; + + slice class CMembDesignatorBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().memb_designator (); + } + }; + + slice class CMulExprBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().mul_expr (); + } + }; + + slice class CAddExprBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().add_expr (); + } + }; + + slice class CShiftExprBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().shift_expr (); + } + }; + + slice class CRelExprBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().rel_expr (); + } + }; + + slice class CEquExprBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().equ_expr (); + } + }; + + slice class CAndExprBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().and_expr (); + } + }; + + slice class CExclOrExprBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().excl_or_expr (); + } + }; + + slice class CInclOrExprBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().incl_or_expr (); + } + }; + + slice class CLogAndExprBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().log_and_expr (); + } + }; + + slice class CLogOrExprBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().log_or_expr (); + } + }; + + slice class CCondExprBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().cond_expr (); + } + }; + + slice class CAssExprBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().ass_expr (); + } + }; + + slice class CAssExpr1Builder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().ass_expr1 (); + } + }; + + slice class CExprBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().expr (); + } + }; + + slice class CConstExprBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().const_expr (); + } + }; + + slice class CStmtBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().stmt (); + } + }; + + slice class CLabelStmtBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().label_stmt (); + } + }; + + slice class CExprStmtBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().expr_stmt (); + } + }; + + slice class CCmpdStmtBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().cmpd_stmt (); + } + }; + + slice class CStmtSeqBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().stmt_seq (); + } + }; + + slice class CSelectStmtBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().select_stmt (); + } + }; + + slice class CSubStmtBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().sub_stmt (); + } + }; + + slice class CConditionBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().condition (); + } + }; + + slice class CIterStmtBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().iter_stmt (); + } + }; + + slice class CForInitStmtBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().for_init_stmt (); + } + }; + + slice class CJumpStmtBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().jump_stmt (); + } + }; + + slice class CDeclSeqBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().decl_seq (); + } + }; + + slice class CDeclBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().decl (); + } + }; + + slice class CBlockDeclBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().block_decl (); + } + }; + + slice class CSimpleDeclBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().simple_decl (); + } + }; + + slice class CDeclSpecBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().decl_spec (); + } + }; + + slice class CDeclSpecSeqBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return 0; // impossible with semantic analysis :-( + } + }; + + slice class CDeclSpecSeq1Builder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().decl_spec_seq1 (); + } + }; + + slice class CMiscSpecBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().misc_spec (); + } + }; + + slice class CStorageClassSpecBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().storage_class_spec (); + } + }; + + slice class CFctSpecBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().fct_spec (); + } + }; + + slice class CTypeSpecBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().type_spec (); + } + }; + + slice class CSimpleTypeSpecBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().simple_type_spec (); + } + }; + + slice class CTypeNameBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().type_name (); + } + }; + + slice class CElaboratedTypeSpecBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().elaborated_type_spec (); + } + }; + + slice class CEnumKeyBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder ().enum_key (); + } + }; + + slice class CEnumSpecBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().enum_spec (); + } + }; + + slice class CEnumSpec1Builder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().enum_spec1 (); + } + }; + + slice class CEnumeratorListBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().enumerator_list (); + } + }; + + slice class CEnumeratorDefBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().enumerator_def (); + } + }; + + slice class CEnumeratorBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().enumerator (); + } + }; + + slice class CAsmDefBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().asm_def (); + } + }; + + slice class CInitDeclaratorListBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().init_declarator_list (); + } + }; + + slice class CInitDeclaratorBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().init_declarator (); + } + }; + + slice class CInitDeclarator1Builder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().init_declarator1 (); + } + }; + + slice class CDeclaratorBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().declarator (); + } + }; + + slice class CDirectDeclaratorBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().direct_declarator (); + } + }; + + slice class CDirectDeclarator1Builder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().direct_declarator1 (); + } + }; + + slice class CIdentifierListBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().identifier_list (); + } + }; + + slice class CArrayDelimBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().array_delim (); + } + }; + + slice class CPtrOperatorBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().ptr_operator (); + } + }; + + slice class CCvQualSeqBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().cv_qual_seq (); + } + }; + + slice class CCvQualBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().cv_qual (); + } + }; + + slice class CDeclaratorIdBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().declarator_id (); + } + }; + + slice class CTypeIdBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder().type_id (); + } + }; + + slice class CTypeSpecSeqBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return 0; // TODO: better structure needed. Why is there no builder? + } + }; + + slice class CTypeSpecSeq1Builder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder ().decl_spec_seq1 (); + } + }; + + slice class CAbstDeclaratorBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder ().abst_declarator (); + } + }; + + slice class CDirectAbstDeclaratorBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder ().direct_abst_declarator (); + } + }; + + slice class CDirectAbstDeclarator1Builder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder ().direct_abst_declarator1 (); + } + }; + + slice class CParamDeclClauseBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder ().param_decl_clause (); + } + }; + + slice class CParamDeclListBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder ().param_decl_list (); + } + }; + + // some stuff missing here ... + + slice class CParamDecl1Builder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder ().param_decl1 (); + } + }; + + // some stuff missing here ... + + slice class CClassHeadBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder ().class_head (); + } + }; + + slice class CClassKeyBuilder { + public: + static CTree *build(Puma::CSyntax &s) { + return s.builder ().class_key (); + } + }; +} + +aspect CBuilderExtension { + + // create the corresponding syntax tree nodes for the rules + advice "Puma::CSyntax::PrivateName": slice Puma::CPrivateNameBuilder; + advice "Puma::CSyntax::TypedefName": slice Puma::CTypedefNameBuilder; + advice "Puma::CSyntax::Identifier": slice Puma::CIdentifierBuilder; + advice "Puma::CSyntax::Literal": slice Puma::CLiteralBuilder; + advice "Puma::CSyntax::CmpdStr": slice Puma::CCmpdStrBuilder; + advice "Puma::CSyntax::StrLiteral": slice Puma::CStrLiteralBuilder; + advice "Puma::CSyntax::TransUnit": slice Puma::CTransUnitBuilder; + advice "Puma::CSyntax::PrimExpr": slice Puma::CPrimExprBuilder; + advice "Puma::CSyntax::IdExpr": slice Puma::CIdExprBuilder; + advice "Puma::CSyntax::CmpdLiteral": slice Puma::CCmpdLiteralBuilder; + advice "Puma::CSyntax::PostfixExpr": slice Puma::CPostfixExprBuilder; + advice "Puma::CSyntax::PostfixExpr1": slice Puma::CPostfixExpr1Builder; + advice "Puma::CSyntax::ExprList": slice Puma::CExprListBuilder; + advice "Puma::CSyntax::UnaryExpr": slice Puma::CUnaryExprBuilder; + advice "Puma::CSyntax::UnaryExpr1": slice Puma::CUnaryExpr1Builder; + advice "Puma::CSyntax::CastExpr": slice Puma::CCastExprBuilder; + advice "Puma::CSyntax::CastExpr1": slice Puma::CCastExpr1Builder; + advice "Puma::CSyntax::CastExpr2": slice Puma::CCastExpr2Builder; + advice "Puma::CSyntax::OffsetofExpr": slice Puma::COffsetofExprBuilder; + advice "Puma::CSyntax::MembDesignator": slice Puma::CMembDesignatorBuilder; + advice "Puma::CSyntax::MulExpr": slice Puma::CMulExprBuilder; + advice "Puma::CSyntax::AddExpr": slice Puma::CAddExprBuilder; + advice "Puma::CSyntax::ShiftExpr": slice Puma::CShiftExprBuilder; + advice "Puma::CSyntax::RelExpr": slice Puma::CRelExprBuilder; + advice "Puma::CSyntax::EquExpr": slice Puma::CEquExprBuilder; + advice "Puma::CSyntax::AndExpr": slice Puma::CAndExprBuilder; + advice "Puma::CSyntax::ExclOrExpr": slice Puma::CExclOrExprBuilder; + advice "Puma::CSyntax::InclOrExpr": slice Puma::CInclOrExprBuilder; + advice "Puma::CSyntax::LogAndExpr": slice Puma::CLogAndExprBuilder; + advice "Puma::CSyntax::LogOrExpr": slice Puma::CLogOrExprBuilder; + advice "Puma::CSyntax::CondExpr": slice Puma::CCondExprBuilder; + advice "Puma::CSyntax::AssExpr": slice Puma::CAssExprBuilder; + advice "Puma::CSyntax::AssExpr1": slice Puma::CAssExpr1Builder; + advice "Puma::CSyntax::Expr": slice Puma::CExprBuilder; + advice "Puma::CSyntax::ConstExpr": slice Puma::CConstExprBuilder; + advice "Puma::CSyntax::Stmt": slice Puma::CStmtBuilder; + advice "Puma::CSyntax::LabelStmt": slice Puma::CLabelStmtBuilder; + advice "Puma::CSyntax::ExprStmt": slice Puma::CExprStmtBuilder; + advice "Puma::CSyntax::CmpdStmt": slice Puma::CCmpdStmtBuilder; + advice "Puma::CSyntax::StmtSeq": slice Puma::CStmtSeqBuilder; + advice "Puma::CSyntax::SelectStmt": slice Puma::CSelectStmtBuilder; + advice "Puma::CSyntax::SubStmt": slice Puma::CSubStmtBuilder; + advice "Puma::CSyntax::Condition": slice Puma::CConditionBuilder; + advice "Puma::CSyntax::IterStmt": slice Puma::CIterStmtBuilder; + advice "Puma::CSyntax::ForInitStmt": slice Puma::CForInitStmtBuilder; + advice "Puma::CSyntax::JumpStmt": slice Puma::CJumpStmtBuilder; + advice "Puma::CSyntax::DeclSeq": slice Puma::CDeclSeqBuilder; + advice "Puma::CSyntax::Decl": slice Puma::CDeclBuilder; + advice "Puma::CSyntax::BlockDecl": slice Puma::CBlockDeclBuilder; + advice "Puma::CSyntax::SimpleDecl": slice Puma::CSimpleDeclBuilder; + advice "Puma::CSyntax::DeclSpec": slice Puma::CDeclSpecBuilder; + advice "Puma::CSyntax::DeclSpecSeq": slice Puma::CDeclSpecSeqBuilder; + advice "Puma::CSyntax::DeclSpecSeq1": slice Puma::CDeclSpecSeq1Builder; + advice "Puma::CSyntax::MiscSpec": slice Puma::CMiscSpecBuilder; + advice "Puma::CSyntax::StorageClassSpec": slice Puma::CStorageClassSpecBuilder; + advice "Puma::CSyntax::FctSpec": slice Puma::CFctSpecBuilder; + advice "Puma::CSyntax::TypeSpec": slice Puma::CTypeSpecBuilder; + advice "Puma::CSyntax::SimpleTypeSpec": slice Puma::CSimpleTypeSpecBuilder; + advice "Puma::CSyntax::TypeName": slice Puma::CTypeNameBuilder; + advice "Puma::CSyntax::ElaboratedTypeSpec": slice Puma::CElaboratedTypeSpecBuilder; + advice "Puma::CSyntax::EnumKey": slice Puma::CEnumKeyBuilder; + advice "Puma::CSyntax::EnumSpec": slice Puma::CEnumSpecBuilder; + advice "Puma::CSyntax::EnumSpec1": slice Puma::CEnumSpec1Builder; + advice "Puma::CSyntax::EnumeratorList": slice Puma::CEnumeratorListBuilder; + advice "Puma::CSyntax::EnumeratorDef": slice Puma::CEnumeratorDefBuilder; + advice "Puma::CSyntax::Enumerator": slice Puma::CEnumeratorBuilder; + advice "Puma::CSyntax::AsmDef": slice Puma::CAsmDefBuilder; + advice "Puma::CSyntax::InitDeclaratorList": slice Puma::CInitDeclaratorListBuilder; + advice "Puma::CSyntax::InitDeclarator": slice Puma::CInitDeclaratorBuilder; + advice "Puma::CSyntax::InitDeclarator1": slice Puma::CInitDeclarator1Builder; + advice "Puma::CSyntax::Declarator": slice Puma::CDeclaratorBuilder; + advice "Puma::CSyntax::DirectDeclarator": slice Puma::CDirectDeclaratorBuilder; + advice "Puma::CSyntax::DirectDeclarator1": slice Puma::CDirectDeclarator1Builder; + advice "Puma::CSyntax::IdentifierList": slice Puma::CIdentifierListBuilder; + advice "Puma::CSyntax::ArrayDelim": slice Puma::CArrayDelimBuilder; + advice "Puma::CSyntax::PtrOperator": slice Puma::CPtrOperatorBuilder; + advice "Puma::CSyntax::CvQualSeq": slice Puma::CCvQualSeqBuilder; + advice "Puma::CSyntax::CvQual": slice Puma::CCvQualBuilder; + advice "Puma::CSyntax::DeclaratorId": slice Puma::CDeclaratorIdBuilder; + advice "Puma::CSyntax::TypeId": slice Puma::CTypeIdBuilder; + advice "Puma::CSyntax::TypeSpecSeq": slice Puma::CTypeSpecSeqBuilder; + advice "Puma::CSyntax::TypeSpecSeq1": slice Puma::CTypeSpecSeq1Builder; + advice "Puma::CSyntax::AbstDeclarator": slice Puma::CAbstDeclaratorBuilder; + advice "Puma::CSyntax::DirectAbstDeclarator": slice Puma::CDirectAbstDeclaratorBuilder; + advice "Puma::CSyntax::DirectAbstDeclarator1": slice Puma::CDirectAbstDeclarator1Builder; + advice "Puma::CSyntax::ParamDeclClause": slice Puma::CParamDeclClauseBuilder; + advice "Puma::CSyntax::ParamDeclList": slice Puma::CParamDeclListBuilder; + // some stuff missing here ... + advice "Puma::CSyntax::ParamDecl1": slice Puma::CParamDecl1Builder; + // some stuff missing here ... + advice "Puma::CSyntax::ClassHead": slice Puma::CClassHeadBuilder; + advice "Puma::CSyntax::ClassKey": slice Puma::CClassKeyBuilder; +}; + +#endif /* __CBuilderExtension_ah__ */ diff --git a/Puma/src/parser/cparser/CExprResolveCC.ah b/Puma/src/parser/cparser/CExprResolveCC.ah new file mode 100644 index 0000000..f991386 --- /dev/null +++ b/Puma/src/parser/cparser/CExprResolveCC.ah @@ -0,0 +1,40 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CExprResolveCC_ah__ +#define __CExprResolveCC_ah__ + +// This aspect inserts resolve member functions into all syntax tree classes +// that represent expressions. As the function is virtual, an efficient +// run-time switch over the node type is implemented. + +#include "Puma/CExprResolveH.ah" +#include "Puma/CSemExpr.h" + +namespace Puma { + slice CTypeInfo *CExprResolveCTree::resolve(CSemExpr &sem_expr, CTree *base) { + return 0; + } + + slice CTypeInfo *CExprResolveExpr::resolve (CSemExpr &sem_expr, CTree *base) { + // this call is statically resolved with overload resolution, etc. + return sem_expr.resolve (this, base); + } +} + +#endif /* __CExprResolveCC_ah__ */ diff --git a/Puma/src/parser/cparser/CExprResolveH.ah b/Puma/src/parser/cparser/CExprResolveH.ah new file mode 100644 index 0000000..dffa5d5 --- /dev/null +++ b/Puma/src/parser/cparser/CExprResolveH.ah @@ -0,0 +1,50 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CExprResolveH_ah__ +#define __CExprResolveH_ah__ + +// This aspect inserts resolve member functions into all syntax tree classes +// that represent expressions. As the function is virtual, an efficient +// run-time switch over the node type is implemented. + +namespace Puma { + class CSemExpr; +} + +using namespace Puma; + +namespace Puma { + slice class CExprResolveCTree { + public: + virtual CTypeInfo *resolve(CSemExpr &sem_expr, CTree *base); + }; + slice class CExprResolveExpr { + public: + virtual CTypeInfo *resolve (CSemExpr &sem_expr, CTree *base); + }; +} + +aspect CExprResolve { + advice "Puma::CTree" : slice Puma::CExprResolveCTree; + advice + derived ("Puma::CT_Expression"||"Puma::CT_SimpleName"||"Puma::CT_String") : + slice Puma::CExprResolveExpr; +}; + +#endif /* __CExprResolveH_ah__ */ diff --git a/Puma/src/parser/cparser/CLanguage.h b/Puma/src/parser/cparser/CLanguage.h new file mode 100644 index 0000000..23ff944 --- /dev/null +++ b/Puma/src/parser/cparser/CLanguage.h @@ -0,0 +1,95 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CLanguage_h__ +#define __CLanguage_h__ + +/** \file + * Entity name encoding. */ + +#include "Puma/DString.h" + +namespace Puma { + + +/** \class CLanguage CLanguage.h Puma/CLanguage.h + * Language specific encoding of entity names. The language + * is specified using the 'extern' linkage specifier. + * + * Following languages are supported: "C", "C++". C entity + * names are not encoded. C++ entity names usually are encoded + * according to the C++ V3 ABI mangling (see + * http://www.codesourcery.com/cxx-abi/abi.html#mangling). + * + * Example: + * \code + * void foo(char); // encoded as: _Z3fooc + * extern "C" void bar(int); // encoded as: bar + * \endcode */ +class CLanguage { +public: + /** Entity language encoding types. */ + enum LangType { + /** Language C. */ + LANG_C, + /** Language C++. */ + LANG_CPLUSPLUS, + /** Neither C nor C++. */ + LANG_OTHER, + /** No explicit language encoding. */ + LANG_UNDEFINED + }; + +private: + LangType m_Type; + DString m_Text; + +public: + /** Constructor. */ + CLanguage () : m_Type (LANG_UNDEFINED), m_Text ("") {} + + /** Set the language encoding type. + * \param lt The language type. */ + void Type (LangType lt) { + m_Type = lt; m_Text = (lt==LANG_C)?"C":(lt==LANG_CPLUSPLUS)?"C++":""; + } + /** Set the language encoding type. + * \param lt The language type. + * \param txt The language identifier for languages other than C or C++. */ + void Type (LangType lt, const char *txt) { + m_Type = lt; m_Text = (lt==LANG_C)?"C":(lt==LANG_CPLUSPLUS)?"C++":(lt==LANG_OTHER)?txt:""; + } + + /** Get the language type. */ + LangType Type () const { return m_Type; } + /** Get the language identifier like "C" or "C++". + * \return The language identifier or the empty string. */ + const DString &Text () const { return m_Text; } + + /** Compare two language encodings. + * \param lang The language encoding to compare with. */ + bool operator== (const CLanguage &lang) { return (m_Type == lang.Type ()) && (m_Text == lang.Text ()); } + /** Compare two language encodings. + * \param lt The language encoding type to compare with. */ + bool operator== (LangType lt) { return (m_Type == lt); } +}; + + +} // namespace Puma + +#endif /* __CLanguage_h__ */ diff --git a/Puma/src/parser/cparser/CLinkage.h b/Puma/src/parser/cparser/CLinkage.h new file mode 100644 index 0000000..86f7401 --- /dev/null +++ b/Puma/src/parser/cparser/CLinkage.h @@ -0,0 +1,55 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CLinkage_h__ +#define __CLinkage_h__ + +/** \file + * Entity name linkage. */ + +namespace Puma { + + +/** \class CLinkage CLinkage.h Puma/CLinkage.h + * Linkage of an entity name (object, function, etc). The + * linkage controls where a name is visible. There are + * three types of linkage: internal, external, and + * no linkage. Names with external linkage are visible outside + * the object file where they occur. Names with internal or + * no linkage are only visible in one object file. + * + * The linkage is implicitely defined by the scope in which + * the entity is declared. With the linkage specifier 'extern' + * an entity name can be explicitely declared to have external + * linkage. */ +struct CLinkage { + /** The linkage types. */ + enum Type { + /** Internal linkage. */ + LINK_INTERNAL, + /** External linkage. */ + LINK_EXTERNAL, + /** No linkage. */ + LINK_NONE + }; +}; + + +} // namespace Puma + +#endif /* __CLinkage_h__ */ diff --git a/Puma/src/parser/cparser/CLookAhead.ah b/Puma/src/parser/cparser/CLookAhead.ah new file mode 100644 index 0000000..4fcee02 --- /dev/null +++ b/Puma/src/parser/cparser/CLookAhead.ah @@ -0,0 +1,440 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CLookAhead_ah__ +#define __CLookAhead_ah__ + +#include +#include + +aspect CLookAhead { + + // FIRST sets and init functions + advice "Puma::CSyntax": slice struct { + tokenset _typedef_name_1; + tokenset _identifier_1; + tokenset _literal_1; + tokenset _cmpd_str_1; + tokenset _str_literal_1; + tokenset _prim_expr_1; + tokenset _id_expr_1; + tokenset _cmpd_literal_1; + tokenset _postfix_expr_1; + tokenset _postfix_expr1_1; + tokenset _cast_expr1_1; + tokenset _cast_expr2_1; + tokenset _label_stmt_1; + tokenset _cmpd_stmt_1; + tokenset _select_stmt_1; + tokenset _iter_stmt_1; + tokenset _jump_stmt_1; + tokenset _decl_spec_1; + tokenset _misc_spec_1; + tokenset _storage_class_spec_1; + tokenset _fct_spec_1; + tokenset _type_spec_1; + tokenset _simple_type_spec_1; + tokenset _type_name_1; + tokenset _elaborated_type_spec_1; + tokenset _enum_spec_1; + tokenset _enum_spec1_1; + tokenset _direct_declarator1_1; + tokenset _cv_qual_seq_1; + tokenset _cv_qual_1; + tokenset _class_head_1; + tokenset _class_key_1; + tokenset _enum_key_1; + + virtual void init_typedef_name () { + _typedef_name_1.set (TOK_ID); + } + virtual void init_identifier () { + _identifier_1.set (TOK_ID); + } + virtual void init_literal () { + init_cmpd_str (); + _literal_1 = _cmpd_str_1; + _literal_1.set (TOK_INT_VAL); + _literal_1.set (TOK_ZERO_VAL); + _literal_1.set (TOK_CHAR_VAL); + _literal_1.set (TOK_FLT_VAL); + } + virtual void init_cmpd_str () { + init_str_literal (); + _cmpd_str_1 = _str_literal_1; + } + virtual void init_str_literal () { + _str_literal_1.set (TOK_STRING_VAL); + } + virtual void init_prim_expr () { + init_literal (); + init_id_expr (); + _prim_expr_1 = _literal_1; + _prim_expr_1 |= _id_expr_1; + _prim_expr_1.set (TOK_OPEN_ROUND); + } + virtual void init_id_expr () { + _id_expr_1.set (TOK_ID); + } + virtual void init_cmpd_literal () { + _cmpd_literal_1.set (TOK_OPEN_ROUND); + } + virtual void init_postfix_expr () { + init_prim_expr (); + init_cmpd_literal (); + _postfix_expr_1 = _prim_expr_1; + _postfix_expr_1 |= _cmpd_literal_1; + } + virtual void init_postfix_expr1 () { + _postfix_expr1_1.set (TOK_DECR); + _postfix_expr1_1.set (TOK_INCR); + _postfix_expr1_1.set (TOK_DOT); + _postfix_expr1_1.set (TOK_PTS); + _postfix_expr1_1.set (TOK_OPEN_ROUND); + _postfix_expr1_1.set (TOK_OPEN_SQUARE); + } + + virtual void init_cast_expr1 () { + init_cast_expr2 (); + _cast_expr1_1 = _cast_expr2_1; + } + + virtual void init_cast_expr2 () { + _cast_expr2_1.set (TOK_OPEN_ROUND); + } + + virtual void init_label_stmt () { + init_identifier (); + _label_stmt_1 = _identifier_1; + _label_stmt_1.set (TOK_CASE); + _label_stmt_1.set (TOK_DEFAULT); + } + + virtual void init_cmpd_stmt () { + _cmpd_stmt_1.set (TOK_OPEN_CURLY); + } + + virtual void init_select_stmt () { + _select_stmt_1.set (TOK_SWITCH); + _select_stmt_1.set (TOK_IF); + } + + virtual void init_iter_stmt () { + _iter_stmt_1.set (TOK_FOR); + _iter_stmt_1.set (TOK_WHILE); + _iter_stmt_1.set (TOK_DO); + } + + virtual void init_jump_stmt () { + _jump_stmt_1.set (TOK_BREAK); + _jump_stmt_1.set (TOK_CONTINUE); + _jump_stmt_1.set (TOK_RETURN); + _jump_stmt_1.set (TOK_GOTO); + } + + virtual void init_decl_spec () { + init_storage_class_spec (); + init_type_spec (); + init_fct_spec (); + init_misc_spec (); + _decl_spec_1 = _storage_class_spec_1; + _decl_spec_1 |= _type_spec_1; + _decl_spec_1 |= _fct_spec_1; + _decl_spec_1 |= _misc_spec_1; + } + + virtual void init_misc_spec () { + _misc_spec_1.set (TOK_TYPEDEF); + } + + virtual void init_storage_class_spec () { + _storage_class_spec_1.set (TOK_AUTO); + _storage_class_spec_1.set (TOK_REGISTER); + _storage_class_spec_1.set (TOK_STATIC); + _storage_class_spec_1.set (TOK_EXTERN); + } + + virtual void init_fct_spec () { + _fct_spec_1.set (TOK_INLINE); + } + + virtual void init_type_spec () { + init_simple_type_spec (); + init_class_spec (); + init_enum_spec (); + init_elaborated_type_spec (); + init_cv_qual (); + _type_spec_1 = _simple_type_spec_1; + _type_spec_1 |= _class_spec_1; + _type_spec_1 |= _enum_spec_1; + _type_spec_1 |= _elaborated_type_spec_1; + _type_spec_1 |= _cv_qual_1; + } + + virtual void init_simple_type_spec () { + init_type_name (); + // init_prim_types (); <-- done by CSyntax::configure() + _simple_type_spec_1 = _type_name_1; + _simple_type_spec_1 |= _prim_types; + } + + virtual void init_type_name () { + init_typedef_name (); + _type_name_1 = _typedef_name_1; + } + + virtual void init_elaborated_type_spec () { + init_class_key (); + _elaborated_type_spec_1 = _class_key_1; + _elaborated_type_spec_1.set (TOK_ENUM); + } + + virtual void init_enum_key () { + _enum_key_1.set (TOK_ENUM); + } + + virtual void init_enum_spec () { + init_enum_spec1 (); + _enum_spec_1 = _enum_spec1_1; + } + + virtual void init_enum_spec1 () { + init_enum_key (); + _enum_spec1_1 = _enum_key_1; + } + + virtual void init_direct_declarator1 () { + _direct_declarator1_1.set (TOK_OPEN_SQUARE); + _direct_declarator1_1.set (TOK_OPEN_ROUND); + } + + virtual void init_cv_qual_seq () { + init_cv_qual (); + _cv_qual_seq_1 = _cv_qual_1; + } + + virtual void init_cv_qual () { + _cv_qual_1 = _cv_quals; + } + + virtual void init_class_head () { + init_class_key (); + _class_head_1 = _class_key_1; + } + + virtual void init_class_key () { + _class_key_1.set (TOK_STRUCT); + _class_key_1.set (TOK_UNION); + } + }; + + // dedicated lookahead rules + advice "Puma::CSyntax::TypedefName": slice struct { + static inline bool lookahead(CSyntax *s) { + return s->predict_1 (s->_typedef_name_1); + } + }; + advice "Puma::CSyntax::Identifier": slice struct { + static inline bool lookahead(CSyntax *s) { + return s->predict_1 (s->_identifier_1); + } + }; + advice "Puma::CSyntax::Literal": slice struct { + static inline bool lookahead(CSyntax *s) { + return s->predict_1 (s->_literal_1); + } + }; + advice "Puma::CSyntax::CmpdStr": slice struct { + static inline bool lookahead(CSyntax *s) { + return s->predict_1 (s->_cmpd_str_1); + } + }; + advice "Puma::CSyntax::StrLiteral": slice struct { + static inline bool lookahead(CSyntax *s) { + return s->predict_1 (s->_str_literal_1); + } + }; + advice "Puma::CSyntax::PrimExpr": slice struct { + static inline bool lookahead(CSyntax *s) { + return s->predict_1 (s->_prim_expr_1); + } + }; + advice "Puma::CSyntax::IdExpr": slice struct { + static inline bool lookahead(CSyntax *s) { + return s->predict_1 (s->_id_expr_1); + } + }; + advice "Puma::CSyntax::PostfixExpr": slice struct { + static inline bool lookahead(CSyntax *s) { + return s->predict_1 (s->_postfix_expr_1); + } + }; + advice "Puma::CSyntax::PostfixExpr1": slice struct { + static inline bool lookahead(CSyntax *s) { + return s->predict_1 (s->_postfix_expr1_1); + } + }; + advice "Puma::CSyntax::CastExpr1": slice struct { + static inline bool lookahead(CSyntax *s) { + return s->predict_1 (s->_cast_expr1_1); + } + }; + advice "Puma::CSyntax::CastExpr2": slice struct { + static inline bool lookahead(CSyntax *s) { + return s->predict_1 (s->_cast_expr2_1); + } + }; + advice "Puma::CSyntax::AssExpr1": slice struct { + static inline bool lookahead(CSyntax *s) { + return s->is_ass_expr (); + } + }; + advice "Puma::CSyntax::LabelStmt": slice struct { + static inline bool lookahead(CSyntax *s) { + return s->predict_1 (s->_label_stmt_1); + } + }; + advice "Puma::CSyntax::CmpdStmt": slice struct { + static inline bool lookahead(CSyntax *s) { + return s->predict_1 (s->_cmpd_stmt_1); + } + }; + advice "Puma::CSyntax::SelectStmt": slice struct { + static inline bool lookahead(CSyntax *s) { + return s->predict_1 (s->_select_stmt_1); + } + }; + advice "Puma::CSyntax::IterStmt": slice struct { + static inline bool lookahead(CSyntax *s) { + return s->predict_1 (s->_iter_stmt_1); + } + }; + advice "Puma::CSyntax::JumpStmt": slice struct { + static inline bool lookahead(CSyntax *s) { + return s->predict_1 (s->_jump_stmt_1); + } + }; + advice "Puma::CSyntax::DeclSpec": slice struct { + static inline bool lookahead(CSyntax *s) { + return s->predict_1 (s->_decl_spec_1); + } + }; + advice "Puma::CSyntax::MiscSpec": slice struct { + static inline bool lookahead(CSyntax *s) { + return s->predict_1 (s->_misc_spec_1); + } + }; + advice "Puma::CSyntax::StorageClassSpec": slice struct { + static inline bool lookahead(CSyntax *s) { + return s->predict_1 (s->_storage_class_spec_1); + } + }; + advice "Puma::CSyntax::FctSpec": slice struct { + static inline bool lookahead(CSyntax *s) { + return s->predict_1 (s->_fct_spec_1); + } + }; + advice "Puma::CSyntax::SimpleTypeSpec": slice struct { + static inline bool lookahead(CSyntax *s) { + return s->predict_1 (s->_simple_type_spec_1); + } + }; + advice "Puma::CSyntax::TypeName": slice struct { + static inline bool lookahead(CSyntax *s) { + return s->predict_1 (s->_type_name_1); + } + }; + advice "Puma::CSyntax::ElaboratedTypeSpec": slice struct { + static inline bool lookahead(CSyntax *s) { + return s->predict_1 (s->_elaborated_type_spec_1); + } + }; + advice "Puma::CSyntax::EnumKey": slice struct { + static inline bool lookahead(CSyntax *s) { + return s->predict_1 (s->_enum_key_1); + } + }; + advice "Puma::CSyntax::EnumSpec": slice struct { + static inline bool lookahead(CSyntax *s) { + return s->predict_1 (s->_enum_spec_1); + } + }; + advice "Puma::CSyntax::EnumSpec1": slice struct { + static inline bool lookahead(CSyntax *s) { + return s->predict_1 (s->_enum_spec1_1); + } + }; + advice "Puma::CSyntax::DirectDeclarator1": slice struct { + static inline bool lookahead(CSyntax *s) { + return s->predict_1 (s->_direct_declarator1_1); + } + }; + advice "Puma::CSyntax::CvQualSeq": slice struct { + static inline bool lookahead(CSyntax *s) { + return s->predict_1 (s->_cv_qual_seq_1); + } + }; + advice "Puma::CSyntax::CvQual": slice struct { + static inline bool lookahead(CSyntax *s) { + return s->predict_1 (s->_cv_qual_1); + } + }; + advice "Puma::CSyntax::ParamDeclList": slice struct { + static inline bool lookahead(CSyntax *s) { + return !s->look_ahead (TOK_CLOSE_ROUND) && !s->look_ahead (TOK_ELLIPSIS); + } + }; + advice "Puma::CSyntax::ClassHead": slice struct { + static inline bool lookahead(CSyntax *s) { + return s->predict_1 (s->_class_head_1); + } + }; + advice "Puma::CSyntax::ClassKey": slice struct { + static inline bool lookahead(CSyntax *s) { + return s->predict_1 (s->_class_key_1); + } + }; + + // default lookahead -> yields true for all rules + advice "Puma::CSyntax::%" : slice struct { + static bool lookahead(void *) { return true; } + }; + + // make sure the FIRST sets are properly initialized + advice execution ("void Puma::CSyntax::configure(...)") : after() { + // later (when all rules have an init function) it should be sufficient + // to call init_translation_unit() + tjp->that()->init_postfix_expr(); + tjp->that()->init_postfix_expr1(); + tjp->that()->init_cast_expr1(); + tjp->that()->init_label_stmt(); + tjp->that()->init_cmpd_stmt(); + tjp->that()->init_select_stmt(); + tjp->that()->init_iter_stmt(); + tjp->that()->init_jump_stmt(); + tjp->that()->init_decl_spec(); + tjp->that()->init_simple_type_spec(); + tjp->that()->init_type_name(); + tjp->that()->init_elaborated_type_spec(); + tjp->that()->init_enum_spec(); + tjp->that()->init_direct_declarator1 (); + tjp->that()->init_cv_qual_seq (); + } +}; + +#endif /* __CLookAhead_ah__ */ diff --git a/Puma/src/parser/cparser/CParser.h b/Puma/src/parser/cparser/CParser.h new file mode 100644 index 0000000..47a9b8e --- /dev/null +++ b/Puma/src/parser/cparser/CParser.h @@ -0,0 +1,59 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CParser__ +#define __CParser__ + +/** \file + * C parser abstraction. */ + +#include "Puma/Parser.h" +#include "Puma/CSyntax.h" +#include "Puma/CBuilder.h" +#include "Puma/CSemantic.h" + +namespace Puma { + + +/** \class CParser CParser.h Puma/CParser.h + * C parser abstraction. Setups the C parser components + * ready to be used for parsing C input files (see class + * Puma::CSyntax, Puma::CBuilder, and Puma::CSemantic). */ +class CParser : public Parser { + CSyntax _syntax; + CBuilder _builder; + CSemantic _semantic; + +public: + /** Constructor. */ + CParser () : Parser (_syntax, _builder, _semantic), + _syntax (_builder, _semantic), + _semantic (_syntax, _builder) {} + + /** Get the C syntactic analysis object. */ + CSyntax &syntax () const { return (CSyntax&)_syntax; } + /** Get the C tree builder object. */ + CBuilder &builder () const { return (CBuilder&)_builder; } + /** Get the C semantic analysis object. */ + CSemantic &semantic () const { return (CSemantic&)_semantic; } +}; + + +} // namespace Puma + +#endif /* __CParser__ */ diff --git a/Puma/src/parser/cparser/CPrintVisitor.cc b/Puma/src/parser/cparser/CPrintVisitor.cc new file mode 100644 index 0000000..df7831c --- /dev/null +++ b/Puma/src/parser/cparser/CPrintVisitor.cc @@ -0,0 +1,245 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CPrintVisitor.h" +#include "Puma/CWStrLiteral.h" +#include "Puma/CStrLiteral.h" +#include "Puma/CConstant.h" +#include "Puma/CTypeInfo.h" +#include "Puma/CObjectInfo.h" +#include "Puma/CStructure.h" +#include "Puma/CScopeInfo.h" +#include "Puma/CTree.h" +#include "Puma/WChar.h" + +#include +#include +#include +#include + +namespace Puma { + + +CPrintVisitor::CPrintVisitor () : out (0), indent (0), linecol (0) { + setPrintLoc(true); +} + +CPrintVisitor::~CPrintVisitor () { + if (linecol) + delete[] linecol; +} + +void CPrintVisitor::setPrintLoc (bool enable, int len) { + print_loc = len > 0 ? enable : false; + loc_len = len; + if (linecol) { + delete[] linecol; + linecol = 0; + } + if (print_loc) + linecol = new char[loc_len]; +} + +void CPrintVisitor::configure (Config& config) { +} + +void CPrintVisitor::print (CTree *node, std::ostream &os) { + out = &os; + indent = 0; + visit (node); +} + +void CPrintVisitor::pre_visit (CTree *node) { + if (! node) + return; + + if (print_loc) { + Token* t = node->token(); + int n = 0; + if (t) { + const Location& l = t->location(); + snprintf(linecol, loc_len, ":%i:%i", l.line(), l.column()); + const char* filename = l.filename().name(); + int avail = loc_len - strlen(linecol); + int flen = strlen(filename); + if (flen > avail) + filename += flen - avail; + n = flen + (loc_len - avail); + *out << filename << linecol; + } + for (; n < loc_len; n++) + *out << " "; + *out << " "; + } + + /* warning: On Windows/64bit the cast loses bits! */ + *out << std::hex << std::setfill('0') << std::setw(8) + << (unsigned long)(size_t)node << " " << std::dec; + for (int i = 0; i < indent; i++) + *out << " "; + + print_node (node); + + *out << "\t### " << node->Sons (); + if (node->token ()) + *out << " from:" << node->token ()->text (); + if (node->end_token ()) + *out << " to:" << node->end_token ()->text (); + + CTypeInfo *type = node->Type (); + CExprValue *value = node->Value (); + + if (type && ! type->is_undefined ()) { + *out << " ("; + type->TypeText (*out); + + if (value && ! value->WStrLiteral ()) { + *out << " "; + if (value->StrLiteral ()) + *out << "\"" << value->StrLiteral ()->String () << "\""; + else if (type->isInteger ()) { + if (type->VirtualType ()->is_signed ()) + *out << value->Constant ()->convert_to_int (); + else + *out << value->Constant ()->convert_to_uint (); + } else + *out << value->Constant ()->convert_to_float (); + } + *out << ")"; + } + *out << std::endl; + + indent++; +} + +void CPrintVisitor::post_visit (CTree *node) { + indent--; +} + +void CPrintVisitor::print_node (CTree *node) const { + if (! node) + return; + + const char *id = node->NodeName (); + *out << id; + + if (id == CT_Token::NodeId ()) { + *out << " \"" << node->token ()->text () << "\""; + } else if (node->IsCall ()) { + CObjectInfo *obj = node->IsCall ()->Object (); + if (obj) + print_qual_name (obj); + } else if (id == CT_ConstructExpr::NodeId ()) { + CObjectInfo *obj = ((CT_ConstructExpr*)node)->Object (); + if (obj) + print_qual_name (obj); + } else if (id == CT_SimpleName::NodeId () || + id == CT_PrivateName::NodeId () || + id == CT_QualName::NodeId () || + id == CT_RootQualName::NodeId () || + id == CT_DestructorName::NodeId () || + id == CT_OperatorName::NodeId () || + id == CT_ConversionName::NodeId ()) { + *out << " " << *(CT_SimpleName*)node; + } else if (id == CT_Integer::NodeId ()) { + CT_Integer *val = (CT_Integer*) node; + if (val->Value () && val->Value ()->Constant ()) { + if (val->Value ()->Type ()->VirtualType ()->is_signed ()) + *out << " " << val->Value ()->Constant ()->convert_to_int (); + else + *out << " " << val->Value ()->Constant ()->convert_to_uint (); + } + } else if (id == CT_Float::NodeId ()) { + CT_Float *val = (CT_Float*) node; + if (val->Value () && val->Value ()->Constant ()) + *out << " " << val->Value ()->Constant ()->convert_to_float (); + } else if (id == CT_Character::NodeId ()) { + CT_Character *val = (CT_Character*) node; + if (val->Value () && val->Value ()->Constant ()) { + if (val->Type ()->VirtualType ()->is_int ()) + *out << " " << (int)val->Value ()->Constant ()->convert_to_int (); + else + *out << " " << (char)val->Value ()->Constant ()->convert_to_int (); + } + } else if (id == CT_WideCharacter::NodeId ()) { + CT_Character *val = (CT_Character*) node; + if (val->Value () && val->Value ()->Constant ()) { + if (val->Type ()->VirtualType ()->is_int ()) + *out << " " << (int)val->Value ()->Constant ()->convert_to_int (); + else + *out << " " << (wchar_t)val->Value ()->Constant ()->convert_to_int (); + } + } else if (id == CT_Bool::NodeId ()) { + CT_Bool *val = (CT_Bool*) node; + if (val->Value () && val->Value ()->Constant ()) + *out << " " << (val->Value ()->Constant ()-> + convert_to_uint () ? "true" : "false"); + } else if (id == CT_String::NodeId ()) { + CT_String *val = (CT_String*) node; + *out << " \""; + if (val->Value () && val->Value ()->StrLiteral ()) { + const char *str = val->Value ()->StrLiteral ()->String (); + unsigned len = strlen (str); + len = (len > 10) ? 10 : len; + for (unsigned i = 0; i < len; i++) + *out << str[i]; + *out << "\""; + if (strlen (str) > len) + *out << "..."; + *out << " [" << val->Value ()->StrLiteral ()->Length () << "]"; + } else + *out << "\""; + } else if (id == CT_WideString::NodeId ()) { + CT_WideString *val = (CT_WideString*) node; + *out << " \""; + if (val->Value () && val->Value ()->WStrLiteral ()) { + const wchar_t *str = val->Value ()->WStrLiteral ()->String (); + unsigned len = wcslen (str); + len = (len > 10) ? 10 : len; + for (unsigned i = 0; i < len; i++) + *out << (char)str[i]; + *out << "\""; + if (wcslen (str) > len) + *out << "..."; + *out << " [" << val->Value ()->WStrLiteral ()->Length () << "]"; + } else + *out << "\""; + } +} + +void CPrintVisitor::print_qual_name (CObjectInfo *oinfo) const { + Array scopes; + CObjectInfo *info; + + *out << " "; + + info = oinfo->AssignedScope (); + if (! info) info = oinfo->Scope (); + while (info && ! info->isAnonymous () && + (info->Record () || (info->NamespaceInfo () && ! info->FileInfo ()))) { + scopes.append (info->Name ()); + info = info->Scope (); + } + + for (long i = scopes.length () - 1; i >= 0; i--) + *out << scopes.lookup (i) << "::"; + *out << oinfo->Name (); +} + + +} // namespace Puma diff --git a/Puma/src/parser/cparser/CPrintVisitor.h b/Puma/src/parser/cparser/CPrintVisitor.h new file mode 100644 index 0000000..34dea62 --- /dev/null +++ b/Puma/src/parser/cparser/CPrintVisitor.h @@ -0,0 +1,79 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CPrintVisitor_h__ +#define __CPrintVisitor_h__ + +/** \file + * CTree based syntax tree printing. */ + +#include "Puma/CVisitor.h" +#include "Puma/Config.h" + +#include + +namespace Puma { + + +class CObjectInfo; + + +/** \class CPrintVisitor CPrintVisitor.h Puma/CPrintVisitor.h + * Tree visitor for printing the C/C++ syntax tree. Prints the + * indented tree structure supplemented with type information, + * calculated constant values, implicit casts, and resolved + * function calls. */ +class CPrintVisitor : private CVisitor { + std::ostream *out; + int indent; + bool print_loc; + int loc_len; + char* linecol; + +public: + /** Constructor. */ + CPrintVisitor (); + /** Destructor. */ + ~CPrintVisitor (); + + /** Configure the visitor. + * \param config The configuration options. */ + void configure (Config &config); + + /** Start printing the given tree on the given output stream. + * \param tree The syntax tree to print. + * \param os The output stream. */ + void print (CTree *tree, std::ostream &os); + + /** Set printing the token location. + * \param enable Enable/disable printing the location. + * \param len The length of the location prefix. */ + void setPrintLoc (bool enable, int len = 20); + +private: + void pre_visit (CTree *node); + void post_visit (CTree *node); + + void print_node (CTree *node) const; + void print_qual_name (CObjectInfo *) const; +}; + + +} // namespace Puma + +#endif /* __CPrintVisitor_h__ */ diff --git a/Puma/src/parser/cparser/CProject.cc b/Puma/src/parser/cparser/CProject.cc new file mode 100644 index 0000000..902a00b --- /dev/null +++ b/Puma/src/parser/cparser/CProject.cc @@ -0,0 +1,235 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/PreprocessorParser.h" +#include "Puma/PathIterator.h" +#include "Puma/StringSource.h" +#include "Puma/ErrorStream.h" +#include "Puma/FileSource.h" +#include "Puma/CProject.h" +#include "Puma/Unit.h" +#include "Puma/CUnit.h" +#include "Puma/UnitIterator.h" +#include "Puma/CTokens.h" +#include "Puma/CTypeInfo.h" +#include +#include + +namespace Puma { + + +CProject::CProject (ErrorStream &e) : + Project (e), _config (e), _scanner (e) { + unitManager ().tokenizer (&_scanner); +} + +// Constructor: Add some source directories. +CProject::CProject (ErrorStream &e, const char *defs, const char *decls) : + Project (e), _config (e), _scanner (e) { + unitManager ().tokenizer (&_scanner); + if (defs) addPath (defs); + if (decls) addPath (decls); +} + +// Constructor: Setup preprocessor configuration according to +// command line parameter and the global config file and +// add some source directories +CProject::CProject (ErrorStream &e, int &argc, char **&argv, + const char *defs, const char *decls) : + Project (e), _config (e), _scanner (e) { + if (! config ().CustomSystemConfigFile (argc, argv)) + config ().Read (); // read global config file + config ().Read (argc, argv); + configure (config ()); + _scanner.configure (config ()); + unitManager ().tokenizer (&_scanner); + if (defs) addPath (defs); + if (decls) addPath (decls); +} + +// Configure the C++ project from the command line or a file. +void CProject::configure (Config &c) { + // Configure the basic project. + Project::configure (c); + + // Configure the CScanner + _scanner.configure (c); + + // Configure size_t and ptrdiff_t types + unsigned num = c.Options (); + for (unsigned i = 0; i < num; i++) { + const ConfOption *o = c.Option (i); + // Set the internal representation of size_t + if (! strcmp (o->Name (), "--size-type")) { + if (o->Arguments () < 1) continue; + CTypeInfo *type = mapType (o->Argument (0)); + if (type) { + CTypeInfo::CTYPE_SIZE_T = type; + } + // Set the internal representation of ptrdiff_t + } else if (! strcmp (o->Name (), "--ptrdiff-type")) { + if (o->Arguments () < 1) continue; + CTypeInfo *type = mapType (o->Argument (0)); + if (type) { + CTypeInfo::CTYPE_PTRDIFF_T = type; + } + } + } +} + +// Scan the file `file' or the source if given. When +// scanning a source the resulting unit gets the name `file'. +Unit *CProject::scanFile (const char *file, Source *in, bool isFile) { + if (! file && ! in) + return (Unit*)0; + Unit *unit = (Unit*)0; + + // this line must be removed from here + _scanner.allow_wildcards (true); + if (isFile) { + // If unit has already been built, return that unit. + if (! (unit = unitManager ().get (file, true))) { + if (! in) { + in = new FileSource (file, &err ()); + if (((FdSource*)in)->fd () == -1) { + delete in; + return unit; // NULL + } + } + unit = unitManager ().scanSource (file, in, true); + } + } else if (in) { + unit = new Unit; + unit->name (file); + _scanner.fill_unit (*in, *unit); + delete in; + } + return unit; +} + +// Scan a string. The resulting unit gets the name `name'. +// (and will not be registered at the unit manager!) +Unit *CProject::scanString (const char *str, const char *name) { + if (! str) + return (Unit*)0; + Source* in = new StringSource (str); + return scanFile (name, in, false); +} + +// Add a new file to the project. +Unit* CProject::addFile (Filename file) { + Unit* result = Project::addFile (file); + return result; +} + +// Give the string needed to include a particular header file +Filename CProject::getInclString (Filename filename) { + Filename canon_file; + if (!SysCall::canonical (filename, canon_file)) + return filename; + + for (unsigned i = config ().Options (); i > 0; i--) { + const ConfOption *o = config ().Option (i-1); + if (! strcmp (o->Name (), "-I")) { + if (! o->Arguments ()) + continue; + Filename canon_inc_dir; + if (!SysCall::canonical (o->Argument (0), canon_inc_dir)) + continue; + + int len = strlen (canon_inc_dir.name ()); + if (strncmp (canon_inc_dir.name (), canon_file.name (), len) == 0) + if (*(canon_file.name () + len) == '/') + return canon_file.name () +len + 1; + } + } + return filename; +} + + +// Map the type string from --size-type and --ptrdiff-type to real Puma type. +CTypeInfo *CProject::mapType (const char *ttxt) const { + if (! ttxt) + return 0; + + // cut off surrounding quotes + if (*ttxt == '"') + ttxt++; + char *txt = StrCol::dup (ttxt); + if (txt[strlen(txt)-1] == '"') + txt[strlen(txt)-1] = '\0'; + + // parse type string + ErrorStream err; + CUnit unit (err); + unit << txt << endu; + delete[] txt; + + int types[TOK_NO], type; + memset ((void*)types, 0, sizeof (types)); + + UnitIterator iter (unit); + for (; *iter; ++iter) { + type = iter->type (); + if (type < TOK_NO) + types[type]++; + } + + if (types[TOK_INT128] == 1) { + if (types[TOK_UNSIGNED] == 1) + return &CTYPE_UNSIGNED_INT128; + else + return &CTYPE_INT128; + } else if (types[TOK_LONG] == 2) { + if (types[TOK_UNSIGNED] == 1) + return &CTYPE_UNSIGNED_LONG_LONG; + else + return &CTYPE_LONG_LONG; + } else if (types[TOK_LONG] == 1) { + if (types[TOK_UNSIGNED] == 1) + return &CTYPE_UNSIGNED_LONG; + else + return &CTYPE_LONG; + } else if (types[TOK_SHORT] == 1) { + if (types[TOK_UNSIGNED] == 1) + return &CTYPE_UNSIGNED_SHORT; + else + return &CTYPE_SHORT; + } else if (types[TOK_INT] == 1) { + if (types[TOK_UNSIGNED] == 1) + return &CTYPE_UNSIGNED_INT; + else + return &CTYPE_INT; + } else if (types[TOK_CHAR] == 1) { + if (types[TOK_UNSIGNED] == 1) + return &CTYPE_UNSIGNED_CHAR; + else if (types[TOK_SIGNED] == 1) + return &CTYPE_SIGNED_CHAR; + else + return &CTYPE_CHAR; + } else if (types[TOK_UNSIGNED] == 1) { + return &CTYPE_UNSIGNED_INT; + } else if (types[TOK_SIGNED] == 1) { + return &CTYPE_INT; + } + + return 0; +} + + +} // namespace Puma diff --git a/Puma/src/parser/cparser/CProject.h b/Puma/src/parser/cparser/CProject.h new file mode 100644 index 0000000..46f7a8f --- /dev/null +++ b/Puma/src/parser/cparser/CProject.h @@ -0,0 +1,96 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CProject_h__ +#define __CProject_h__ + +// Special project derivation for C++ sources. + +#include "Puma/Config.h" +#include "Puma/Project.h" +#include "Puma/CScanner.h" +#include "Puma/ErrorStream.h" + +namespace Puma { + + +class Source; +class CTypeInfo; + +class CProject : public Project { + Config _config; + CScanner _scanner; + +public: + CProject (ErrorStream &e); + + // Constructor: Add some source directories. + CProject (ErrorStream &, const char *defs, + const char *decls = (const char*)0); + + // Constructor: Setup preprocessor configuration according to + // command line parameter and the global config file and + // add some source directories. + CProject (ErrorStream &, int &argc, char **&argv, + const char *defs = (const char*)0, + const char *decls = (const char*)0); + +public: // Project configuration + // Get the preprocessor configuration. + Config &config (); + + // Configure the project from the command line or a file. + virtual void configure (Config &); + + // Add a new file to the project. + Unit *addFile (Filename file); + +public: // Scanner interface + // Get the scanner. + CScanner &scanner (); + + // Scan the file `file' or the source if given. When + // scanning a source the resulting unit gets the name `file'. + virtual Unit *scanFile (const char *file, Source * = (Source*)0, + bool isFile = true); + + // Scan a string. The resulting unit gets the name `name'. + // (and will not be registered at the unit manager!) + virtual Unit *scanString (const char *str, + const char *name = (const char*)0); + +public: // Miscellaneous Functions + + // Give the filename needed to include a particular header file + Filename getInclString (Filename filename); + +private: + // Map the type string from --size-type and --ptrdiff-type + // to real Puma type. + CTypeInfo *mapType (const char *) const; +}; + +inline Config &CProject::config () + { return _config; } +inline CScanner &CProject::scanner () + { return _scanner; } + + +} // namespace Puma + +#endif /* __CProject_h__ */ diff --git a/Puma/src/parser/cparser/CProtection.h b/Puma/src/parser/cparser/CProtection.h new file mode 100644 index 0000000..1549dc6 --- /dev/null +++ b/Puma/src/parser/cparser/CProtection.h @@ -0,0 +1,51 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CProtection_h__ +#define __CProtection_h__ + +/** \file + * C++ class member protection. */ + +namespace Puma { + + +/** \class CProtection CProtection.h Puma/CProtection.h + * Access protection of C++ class members for the purpose + * of member access control. There are three kinds of + * protection: private, public, and protected. The + * protection either is defined implicitely or explicitely + * using member access specifiers. */ +struct CProtection { + /** The member access types. */ + enum Type { + /** Public member access. */ + PROT_PUBLIC, + /** Protected member access. */ + PROT_PROTECTED, + /** Private member access. */ + PROT_PRIVATE, + /** Undefined member access. */ + PROT_NONE + }; +}; + + +} // namespace Puma + +#endif /* __CProtection_h__ */ diff --git a/Puma/src/parser/cparser/CSemBinding.ah b/Puma/src/parser/cparser/CSemBinding.ah new file mode 100644 index 0000000..61359e4 --- /dev/null +++ b/Puma/src/parser/cparser/CSemBinding.ah @@ -0,0 +1,181 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CSemBinding_ah__ +#define __CSemBinding_ah__ + +#include "Puma/CSemantic.h" + +// This aspect controls the parsing process on the C code level +// by maintaining semantic information. + +aspect CSemBinding { + + advice execution("% Puma::CSyntax::PrivateName::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().PrivateName(); + } + + advice execution("% Puma::CSyntax::TypedefName::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().typedef_name(); + } + + advice execution("% Puma::CSyntax::TransUnit::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().trans_unit(); + } + + advice execution("% Puma::CSyntax::IdExpr::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().id_expr(); + } + + advice execution("% Puma::CSyntax::LabelStmt::build(...)") : after () { + if (*tjp->result ()) + tjp->arg<0>()->semantic().introduce_label(*tjp->result ()); + } + + advice execution("% Puma::CSyntax::CmpdStmt::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().cmpd_stmt(); + } + + advice execution("% Puma::CSyntax::SelectStmt::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().select_stmt(); + } + + advice execution("% Puma::CSyntax::IterStmt::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().iter_stmt(); + } + + advice execution("% Puma::CSyntax::DeclSpecSeq::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().begin_decl (); + } + + advice execution("% Puma::CSyntax::DeclSpecSeq::parse(...)") : around () { + tjp->arg<0>()->semantic().decl_spec_seq (); + tjp->proceed (); + if (!*tjp->result ()) + tjp->arg<0>()->semantic().decl_spec_seq_err (); + } + + advice execution("% Puma::CSyntax::DeclSpecSeq1::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().decl_spec_seq1(); + } + + advice execution("% Puma::CSyntax::ElaboratedTypeSpec::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().introduce_tag (); + } + + advice execution("% Puma::CSyntax::EnumSpec1::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().introduce_enum (); + } + + advice execution("% Puma::CSyntax::EnumeratorDef::build(...)"): around () { + *tjp->result() = tjp->arg<0>()->semantic().enumerator_def (); + } + + advice execution("% Puma::CSyntax::Enumerator::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().introduce_enumerator (); + } + + advice execution("% Puma::CSyntax::InitDeclarator::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().init_declarator (); + } + + advice execution("% Puma::CSyntax::InitDeclarator1::parse(...)") : after () { + if (!*tjp->result ()) + tjp->arg<0>()->semantic().finish_declarator (); + } + + advice execution("% Puma::CSyntax::InitDeclarator1::build(...)") : around () { + Puma::CTree *result; + if (tjp->arg<0>()->semantic ().in_arg_decl_seq ()) + result = tjp->arg<0>()->semantic ().declare_parameter (); + else + result = tjp->arg<0>()->semantic ().introduce_object (); + tjp->arg<0>()->semantic().finish_declarator (); + *tjp->result () = result; + } + + advice execution("% Puma::CSyntax::IdentifierList::parse(...)") || + execution("% Puma::CSyntax::ParamDeclClause::parse(...)"): around () { + tjp->arg<0>()->semantic().enter_param_decl_clause (); + tjp->proceed (); + tjp->arg<0>()->semantic().leave_param_decl_clause (); + } + + advice execution("% Puma::CSyntax::IdentifierList::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().identifier_list (); + } + + advice execution("% Puma::CSyntax::ParamDeclClause::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().param_decl_clause (); + } + + advice execution("% Puma::CSyntax::ArrayDelim::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().array_delim (); + } + + advice execution("% Puma::CSyntax::TypeId::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().introduce_named_type (); + } + + advice execution("% Puma::CSyntax::TypeId::parse(...)") : after () { + tjp->arg<0>()->semantic().finish_declarator (); + } + + advice execution("% Puma::CSyntax::TypeSpecSeq::parse(...)") : around () { + tjp->arg<0>()->semantic().decl_spec_seq (); + tjp->proceed (); + if (!*tjp->result()) + tjp->arg<0>()->semantic().decl_spec_seq_err (); + } + + advice execution("% Puma::CSyntax::TypeSpecSeq::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().begin_decl (); + } + + advice execution("% Puma::CSyntax::TypeSpecSeq1::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().decl_spec_seq1 (); + } + + advice execution("% Puma::CSyntax::AbstDeclarator::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().abst_declarator (); + } + + advice execution("% Puma::CSyntax::DirectAbstDeclarator::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().direct_abst_declarator (); + } + + advice execution("% Puma::CSyntax::ParamDecl1::build(...)") : around () { + *tjp->result() = tjp->arg<0>()->semantic().introduce_parameter (); + } + + advice call("% Puma::CSyntax::Declarator::check(...)") && + within("% Puma::CSyntax::ParamDecl1::parse(...)") : around () { + tjp->arg<0>()->semantic ().begin_param_check (); // ambiguity check + tjp->proceed(); + // The following check runs *after* the syntax tree node has been built! + // It is possible that it has to be deleted (if result is false). + *tjp->result() = tjp->arg<0>()->semantic ().finish_param_check (*tjp->result()); + } + + advice execution("% Puma::CSyntax::ClassHead::build(...)"): around () { + *tjp->result() = tjp->arg<0>()->semantic().introduce_class (); + } + +}; + +#endif /* __CSemBinding_ah__ */ diff --git a/Puma/src/parser/cparser/CSemDeclSpecs.cc b/Puma/src/parser/cparser/CSemDeclSpecs.cc new file mode 100644 index 0000000..46b0b10 --- /dev/null +++ b/Puma/src/parser/cparser/CSemDeclSpecs.cc @@ -0,0 +1,528 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CSemDeclSpecs.h" +#include "Puma/CObjectInfo.h" +#include "Puma/CEnumInfo.h" +#include "Puma/ErrorSink.h" +#include "Puma/CRecord.h" +#include "Puma/CTree.h" + +namespace Puma { + + +CSemDeclSpecs::CSemDeclSpecs (ErrorSink *err, CT_DeclSpecSeq *dss, bool support_implicit_int) : + _err (err), _dss (dss) { + + bool no_error = true, have_type = false; + + // first gather information about all nodes in the sequence + no_error = (analyze_seq () && no_error); + + // check for errors + no_error = (check_prim_decl_specs (have_type) && no_error); + no_error = (check_complex_decl_specs (have_type) && no_error); + no_error = (check_storage_class () && no_error); + no_error = (check_signed_unsigned () && no_error); + no_error = (check_long_short () && no_error); + + // implicit int + if (! have_type && support_implicit_int) { + _prim_map[CT_PrimDeclSpec::PDS_INT]++; + have_type = true; + } + + // now create the type + _type = &CTYPE_UNDEFINED; + if (have_type && no_error) { + CTypeInfo *type = create_qualifiers (create_type ()); + // assign the type if the final check is also ok + if (check_finally ()) + _type = type; + else + CTypeInfo::Destroy (type); + } +} + + +// analyses the syntax tree nodes of the decl-spec sequence. Return false +// if an error was detected. +bool CSemDeclSpecs::analyze_seq () { + _names = 0, _class_specs = 0, _union_specs = 0, _enum_specs = 0; + _def_class = _def_union = _def_enum = false; + _name = 0; + for (int i = 0; i < CT_PrimDeclSpec::NumTypes; i++) + _prim_map[i] = 0; // clear the array + + // Gather information about the declaration specifiers + for (int s = 0; s < _dss->Sons (); s++) { + CTree *spec = _dss->Son (s); + if (!analyze (spec)) { + Token *token = spec->token (); + if (token) *_err << token->location (); + *_err << sev_fatal << "unknown declaration specifier `" + << spec->NodeName () << "'" << endMessage; + return false; + } + } + return true; +} + + +// analyzes the current declaration specifier in the sequence and set some +// attributes according to the result. Returns false if the specifier type +// is unknown. +bool CSemDeclSpecs::analyze (CTree *spec) { + const char *id = spec->NodeName (); + if (id == CT_PrimDeclSpec::NodeId ()) { + CT_PrimDeclSpec *pds = (CT_PrimDeclSpec*)spec; + _prim_map[pds->SpecType ()]++; + _prim_token[pds->SpecType ()] = pds->token (); + } else if (id == CT_SimpleName::NodeId () || + id == CT_TemplateName::NodeId () || + id == CT_QualName::NodeId () || + id == CT_RootQualName::NodeId ()) { + _names++; + _name = (CT_SimpleName*)spec; + } else if (id == CT_ClassSpec::NodeId ()) { + _class_specs++; + _name = (CT_SimpleName*)spec->Son (1); + _def_class = (_name && _name->Object () && + _name->Object ()->Record () && + _name->Object ()->Record ()->isDefined ()); + } else if (id == CT_ClassDef::NodeId ()) { + _class_specs++; + _name = (CT_SimpleName*)spec->Son (1); + _def_class = true; + } else if (id == CT_UnionSpec::NodeId ()) { + _union_specs++; + _name = (CT_SimpleName*)spec->Son (1); + _def_union = (_name && _name->Object () && + _name->Object ()->Record ()->isDefined ()); + } else if (id == CT_UnionDef::NodeId ()) { + _union_specs++; + _name = (CT_SimpleName*)spec->Son (1); + _def_union = true; + } else if (id == CT_EnumSpec::NodeId ()) { + _enum_specs++; + _name = (CT_SimpleName*)spec->Son (1); + _def_enum = (_name && _name->Object () && + _name->Object ()->EnumInfo ()->isDefined ()); + } else if (id == CT_EnumDef::NodeId ()) { + _enum_specs++; + _name = (CT_SimpleName*)spec->Son (1); + _def_enum = true; + } else + return false; + return true; +} + + +bool CSemDeclSpecs::check_prim_decl_specs (bool &have_type) { + bool have_error = false; + for (int s = 0; s < CT_PrimDeclSpec::NumTypes; s++) { + int count = _prim_map[s]; + switch (s) { // be careful, some break statement are missing! + case CT_PrimDeclSpec::PDS_LONG: + if (count > 0) have_type = true; + if (count > 2) { + *_err << sev_error << _prim_token[s]->location () << count + << " times `long' is too long" << endMessage; + have_error = true; + } + break; + case CT_PrimDeclSpec::PDS_CHAR: + case CT_PrimDeclSpec::PDS_WCHAR_T: + case CT_PrimDeclSpec::PDS_BOOL: + case CT_PrimDeclSpec::PDS_C_BOOL: + case CT_PrimDeclSpec::PDS_INT: + case CT_PrimDeclSpec::PDS_INT64: + case CT_PrimDeclSpec::PDS_INT128: + case CT_PrimDeclSpec::PDS_FLOAT: + case CT_PrimDeclSpec::PDS_DOUBLE: + case CT_PrimDeclSpec::PDS_VOID: + case CT_PrimDeclSpec::PDS_UNKNOWN_T: + if (count > 0) have_type = true; + if (count > 1) { + *_err << sev_error << _prim_token[s]->location () + << "two or more `" << _prim_token[s]->text () + << "' in declaration" << endMessage; + have_error = true; + } + break; + case CT_PrimDeclSpec::PDS_SIGNED: + if (count > 0 && _prim_map[CT_PrimDeclSpec::PDS_UNSIGNED] > 0) { + *_err << sev_error << _prim_token[s]->location () + << "signed and unsigned given together" << endMessage; + have_error = true; + } + case CT_PrimDeclSpec::PDS_UNSIGNED: + case CT_PrimDeclSpec::PDS_SHORT: + if (count > 0) have_type = true; + default: + if (count > 1) { + *_err << sev_warning << _prim_token[s]->location () + << "duplicate `" << _prim_token[s]->text () << "'" + << endMessage; + have_error = true; + } + } + } + return !have_error; +} + + +bool CSemDeclSpecs::check_complex_decl_specs (bool &have_type) { + if (_names || _class_specs || _union_specs || _enum_specs) { + have_type = true; + } + return true; +} + + +bool CSemDeclSpecs::check_storage_class () { + if (_prim_map[CT_PrimDeclSpec::PDS_TYPEDEF] + + _prim_map[CT_PrimDeclSpec::PDS_AUTO] + + _prim_map[CT_PrimDeclSpec::PDS_REGISTER] + + _prim_map[CT_PrimDeclSpec::PDS_STATIC] + + _prim_map[CT_PrimDeclSpec::PDS_EXTERN] + + _prim_map[CT_PrimDeclSpec::PDS_MUTABLE] > 1) { + *_err << sev_error << _dss->token ()->location () + << "multiple storage classes in declaration" << endMessage; + return false; + } + return true; +} + + +bool CSemDeclSpecs::check_signed_unsigned () { + if ((_prim_map[CT_PrimDeclSpec::PDS_SIGNED] || + _prim_map[CT_PrimDeclSpec::PDS_UNSIGNED]) && + (_prim_map[CT_PrimDeclSpec::PDS_BOOL] || + _prim_map[CT_PrimDeclSpec::PDS_C_BOOL] || + _prim_map[CT_PrimDeclSpec::PDS_FLOAT] || + _prim_map[CT_PrimDeclSpec::PDS_DOUBLE] || + _prim_map[CT_PrimDeclSpec::PDS_VOID] || + _prim_map[CT_PrimDeclSpec::PDS_UNKNOWN_T] || + _prim_map[CT_PrimDeclSpec::PDS_WCHAR_T] || + _class_specs || _union_specs || _enum_specs)) { + *_err << sev_error << _dss->token ()->location () + << "`signed' or `unsigned' invalid for given type" + << endMessage; + return false; + } + return true; +} + + +bool CSemDeclSpecs::check_long_short () { + if (_prim_map[CT_PrimDeclSpec::PDS_LONG] && + _prim_map[CT_PrimDeclSpec::PDS_SHORT]) { + *_err << sev_error << _dss->token ()->location () + << "`long' and `short' specified together" + << endMessage; + return false; + } + return true; +} + + +// makes a type object according to the state of this object after analysis +CTypeInfo *CSemDeclSpecs::create_type () { + // --------------------------------------------- // + // type specifier(s) | specified type // + // --------------------------------------------- // + // void | "void" // + // bool | "bool" // + // _Bool | "_Bool" // + // wchar_t | "wchar_t" // + // | // + // char | "char" // + // unsigned char | "unsigned char" // + // signed char | "signed char" // + // | // + // unsigned | "unsigned int" // + // unsigned int | "unsigned int" // + // signed | "int" // + // signed int | "int" // + // int | "int" // + // unsigned short int | "unsigned short int" // + // unsigned short | "unsigned short int" // + // unsigned long int | "unsigned long int" // + // unsigned long | "unsigned long int" // + // signed long int | "long int" // + // signed long | "long int" // + // long int | "long int" // + // long | "long int" // + // signed short int | "short int" // + // signed short | "short int" // + // short int | "short int" // + // short | "short int" // + // | // + // float | "float" // + // double | "double" // + // long double | "long double" // + // --------------------------------------------- // + CObjectInfo *info; + CTypeInfo *type = &CTYPE_UNDEFINED; + // handle 'bool' + if (_prim_map[CT_PrimDeclSpec::PDS_BOOL]) { + _prim_map[CT_PrimDeclSpec::PDS_BOOL] = 0; + type = &CTYPE_BOOL; + } + // handle '_Bool' + else if (_prim_map[CT_PrimDeclSpec::PDS_C_BOOL]) { + _prim_map[CT_PrimDeclSpec::PDS_C_BOOL] = 0; + type = &CTYPE_C_BOOL; + } + // handle 'float' + else if (_prim_map[CT_PrimDeclSpec::PDS_FLOAT]) { + _prim_map[CT_PrimDeclSpec::PDS_FLOAT] = 0; + type = &CTYPE_FLOAT; + } + // handle 'double' <= must be handled before 'long' + else if (_prim_map[CT_PrimDeclSpec::PDS_DOUBLE]) { + _prim_map[CT_PrimDeclSpec::PDS_DOUBLE] = 0; + if (_prim_map[CT_PrimDeclSpec::PDS_LONG]) { + type = &CTYPE_LONG_DOUBLE; + _prim_map[CT_PrimDeclSpec::PDS_LONG] = 0; + } else + type = &CTYPE_DOUBLE; + } + // handle 'char' + else if (_prim_map[CT_PrimDeclSpec::PDS_CHAR]) { + _prim_map[CT_PrimDeclSpec::PDS_CHAR] = 0; + if (_prim_map[CT_PrimDeclSpec::PDS_UNSIGNED]) { + type = &CTYPE_UNSIGNED_CHAR; + _prim_map[CT_PrimDeclSpec::PDS_UNSIGNED] = 0; + } else if (_prim_map[CT_PrimDeclSpec::PDS_SIGNED]) { + type = &CTYPE_SIGNED_CHAR; + _prim_map[CT_PrimDeclSpec::PDS_SIGNED] = 0; + } else + type = &CTYPE_CHAR; + } + // handle 'wchar_t' + else if (_prim_map[CT_PrimDeclSpec::PDS_WCHAR_T]) { + _prim_map[CT_PrimDeclSpec::PDS_WCHAR_T] = 0; + type = &CTYPE_WCHAR_T; + } + // handle 'short' + else if (_prim_map[CT_PrimDeclSpec::PDS_SHORT]) { + _prim_map[CT_PrimDeclSpec::PDS_SHORT] = 0; + _prim_map[CT_PrimDeclSpec::PDS_INT] = 0; + if (_prim_map[CT_PrimDeclSpec::PDS_UNSIGNED]) { + type = &CTYPE_UNSIGNED_SHORT; + _prim_map[CT_PrimDeclSpec::PDS_UNSIGNED] = 0; + } else if (_prim_map[CT_PrimDeclSpec::PDS_SIGNED]) { + type = &CTYPE_SHORT; + _prim_map[CT_PrimDeclSpec::PDS_SIGNED] = 0; + } else + type = &CTYPE_SHORT; + } + // handle 'long long' <= be careful, this must be before 'int'! + else if (_prim_map[CT_PrimDeclSpec::PDS_LONG] == 2) { + _prim_map[CT_PrimDeclSpec::PDS_LONG] = 0; + _prim_map[CT_PrimDeclSpec::PDS_INT] = 0; + if (_prim_map[CT_PrimDeclSpec::PDS_UNSIGNED]) { + type = &CTYPE_UNSIGNED_LONG_LONG; + _prim_map[CT_PrimDeclSpec::PDS_UNSIGNED] = 0; + } else if (_prim_map[CT_PrimDeclSpec::PDS_SIGNED]) { + type = &CTYPE_LONG_LONG; + _prim_map[CT_PrimDeclSpec::PDS_SIGNED] = 0; + } else + type = &CTYPE_LONG_LONG; + } + // handle 'long' <= be careful, this must be before 'int'! + else if (_prim_map[CT_PrimDeclSpec::PDS_LONG] == 1) { + _prim_map[CT_PrimDeclSpec::PDS_LONG] = 0; + _prim_map[CT_PrimDeclSpec::PDS_INT] = 0; + if (_prim_map[CT_PrimDeclSpec::PDS_UNSIGNED]) { + type = &CTYPE_UNSIGNED_LONG; + _prim_map[CT_PrimDeclSpec::PDS_UNSIGNED] = 0; + } else if (_prim_map[CT_PrimDeclSpec::PDS_SIGNED]) { + type = &CTYPE_LONG; + _prim_map[CT_PrimDeclSpec::PDS_SIGNED] = 0; + } else + type = &CTYPE_LONG; + } + // handle 'int' + else if (_prim_map[CT_PrimDeclSpec::PDS_INT]) { + _prim_map[CT_PrimDeclSpec::PDS_INT] = 0; + if (_prim_map[CT_PrimDeclSpec::PDS_UNSIGNED]) { + type = &CTYPE_UNSIGNED_INT; + _prim_map[CT_PrimDeclSpec::PDS_UNSIGNED] = 0; + } else if (_prim_map[CT_PrimDeclSpec::PDS_SIGNED]) { + type = &CTYPE_INT; + _prim_map[CT_PrimDeclSpec::PDS_SIGNED] = 0; + } else + type = &CTYPE_INT; + } + // handle '__int64' + else if (_prim_map[CT_PrimDeclSpec::PDS_INT64]) { + _prim_map[CT_PrimDeclSpec::PDS_INT64] = 0; + if (_prim_map[CT_PrimDeclSpec::PDS_UNSIGNED]) { + type = &CTYPE_UNSIGNED_LONG_LONG; + _prim_map[CT_PrimDeclSpec::PDS_UNSIGNED] = 0; + } else if (_prim_map[CT_PrimDeclSpec::PDS_SIGNED]) { + type = &CTYPE_LONG_LONG; + _prim_map[CT_PrimDeclSpec::PDS_SIGNED] = 0; + } else + type = &CTYPE_LONG_LONG; + } + // handle '__int128' + else if (_prim_map[CT_PrimDeclSpec::PDS_INT128]) { + _prim_map[CT_PrimDeclSpec::PDS_INT128] = 0; + if (_prim_map[CT_PrimDeclSpec::PDS_UNSIGNED]) { + type = &CTYPE_UNSIGNED_INT128; + _prim_map[CT_PrimDeclSpec::PDS_UNSIGNED] = 0; + } else if (_prim_map[CT_PrimDeclSpec::PDS_SIGNED]) { + type = &CTYPE_INT128; + _prim_map[CT_PrimDeclSpec::PDS_SIGNED] = 0; + } else + type = &CTYPE_INT128; + } + // handle 'signed' + else if (_prim_map[CT_PrimDeclSpec::PDS_SIGNED]) { + _prim_map[CT_PrimDeclSpec::PDS_SIGNED] = 0; + type = &CTYPE_INT; + } + // handle 'unsigned' + else if (_prim_map[CT_PrimDeclSpec::PDS_UNSIGNED]) { + _prim_map[CT_PrimDeclSpec::PDS_UNSIGNED] = 0; + type = &CTYPE_UNSIGNED_INT; + } + // handle 'void' + else if (_prim_map[CT_PrimDeclSpec::PDS_VOID]) { + _prim_map[CT_PrimDeclSpec::PDS_VOID] = 0; + type = &CTYPE_VOID; + } + // handle '__unknown_t' + else if (_prim_map[CT_PrimDeclSpec::PDS_UNKNOWN_T]) { + _prim_map[CT_PrimDeclSpec::PDS_UNKNOWN_T] = 0; + type = &CTYPE_UNKNOWN_T; + } + else if (_names) { + _names--; + if (_name) { + info = 0; + if (_name->NodeName () == CT_TemplateName::NodeId ()) + info = _name->Object (); + else if (_name->NodeName () == CT_QualName::NodeId () || + _name->NodeName () == CT_RootQualName::NodeId ()) { + for (unsigned i = _name->Entries (); i > 0; i--) + if ((info = ((CT_SimpleName*)_name->Entry (i-1))->Object ())) + break; + } else + info = _name->Name ()->Object (); + if (info && (info->Record () || info->EnumInfo () || + info->TypedefInfo () || info->TemplateParamInfo ())) + type = info->TypeInfo ()->Duplicate (); + } + } + else if (_class_specs) { + _class_specs--; + if (_name) { + info = _name->Object (); + if (info) + type = CTypeInfo::Duplicate (info->TypeInfo ()); + } + } + else if (_union_specs) { + _union_specs--; + if (_name) { + info = _name->Object (); + if (info) + type = CTypeInfo::Duplicate (info->TypeInfo ()); + } + } + else if (_enum_specs) { + _enum_specs--; + if (_name) { + info = _name->Object (); + if (info) + type = CTypeInfo::Duplicate (info->TypeInfo ()); + } + } + return type; +} + + +CTypeInfo *CSemDeclSpecs::create_qualifiers (CTypeInfo *type) { + // handle 'const', 'volatile' and 'restrict' + if (_prim_map[CT_PrimDeclSpec::PDS_CONST] || + _prim_map[CT_PrimDeclSpec::PDS_VOLATILE] || + _prim_map[CT_PrimDeclSpec::PDS_RESTRICT]) { + if (type->TypeQualified ()) { + if (_prim_map[CT_PrimDeclSpec::PDS_CONST]) + ((CTypeQualified*)type)->isConst (true); + if (_prim_map[CT_PrimDeclSpec::PDS_VOLATILE]) + ((CTypeQualified*)type)->isVolatile (true); + if (_prim_map[CT_PrimDeclSpec::PDS_RESTRICT]) + ((CTypeQualified*)type)->isRestrict (true); + } else if (type->TypeArray ()) { + CTypeInfo* base = type->BaseType (); + if (base->TypeQualified ()) { + if (_prim_map[CT_PrimDeclSpec::PDS_CONST]) + ((CTypeQualified*)base)->isConst (true); + if (_prim_map[CT_PrimDeclSpec::PDS_VOLATILE]) + ((CTypeQualified*)base)->isVolatile (true); + if (_prim_map[CT_PrimDeclSpec::PDS_RESTRICT]) + ((CTypeQualified*)base)->isRestrict (true); + } else { + base = new CTypeQualified (base, + _prim_map[CT_PrimDeclSpec::PDS_CONST], + _prim_map[CT_PrimDeclSpec::PDS_VOLATILE], + _prim_map[CT_PrimDeclSpec::PDS_RESTRICT]); + type->BaseType (base); + } + } else { + type = new CTypeQualified (type, + _prim_map[CT_PrimDeclSpec::PDS_CONST], + _prim_map[CT_PrimDeclSpec::PDS_VOLATILE], + _prim_map[CT_PrimDeclSpec::PDS_RESTRICT]); + } + } + return type; +} + + +bool CSemDeclSpecs::check_finally () { + if (_prim_map[CT_PrimDeclSpec::PDS_CHAR] + + _prim_map[CT_PrimDeclSpec::PDS_WCHAR_T] + + _prim_map[CT_PrimDeclSpec::PDS_BOOL] + + _prim_map[CT_PrimDeclSpec::PDS_C_BOOL] + + _prim_map[CT_PrimDeclSpec::PDS_SHORT] + + _prim_map[CT_PrimDeclSpec::PDS_INT] + + _prim_map[CT_PrimDeclSpec::PDS_LONG] + + _prim_map[CT_PrimDeclSpec::PDS_SIGNED] + + _prim_map[CT_PrimDeclSpec::PDS_UNSIGNED] + + _prim_map[CT_PrimDeclSpec::PDS_FLOAT] + + _prim_map[CT_PrimDeclSpec::PDS_DOUBLE] + + _prim_map[CT_PrimDeclSpec::PDS_INT64] + + _prim_map[CT_PrimDeclSpec::PDS_INT128] + + _prim_map[CT_PrimDeclSpec::PDS_UNKNOWN_T] + + _prim_map[CT_PrimDeclSpec::PDS_VOID] + + _names + _class_specs + _union_specs + _enum_specs > 0) { + *_err << sev_error << _dss->token ()->location () + << "invalid type specified in declaration" << endMessage; + return false; + } + return true; +} + +} // namespace Puma diff --git a/Puma/src/parser/cparser/CSemDeclSpecs.h b/Puma/src/parser/cparser/CSemDeclSpecs.h new file mode 100644 index 0000000..ae66014 --- /dev/null +++ b/Puma/src/parser/cparser/CSemDeclSpecs.h @@ -0,0 +1,128 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __c_sem_decl_specs_h__ +#define __c_sem_decl_specs_h__ + +/** \file + * Semantic declaration specifier analysis. */ + +#include "Puma/CTypeInfo.h" +#include "Puma/CTree.h" + +namespace Puma { + + +class ErrorSink; + + +/** \class CSemDeclSpecs CSemDeclSpecs.h Puma/CSemDeclSpecs.h + * Class for analysing a sequence of declaration specifiers. + * The result of the analysis is a type, i.e. the type of + * the declared entity (function, object, etc). */ +class CSemDeclSpecs { + // initialization context + ErrorSink *_err; + CT_DeclSpecSeq *_dss; + + // analysis results: + // ----------------- + // counters + int _names; + int _class_specs; + int _union_specs; + int _enum_specs; + // nodes/objects + int _prim_map[CT_PrimDeclSpec::NumTypes]; + Token *_prim_token[CT_PrimDeclSpec::NumTypes]; + CT_SimpleName *_name; + + // final results after all checks: + // ------------------------------- + CTypeInfo *_type; + bool _def_class, _def_union, _def_enum; + + // analyses the syntax tree nodes of the decl-spec sequence. Return false + // if an error was detected. + bool analyze_seq (); + + // analyzes the current declaration specifier in the sequence and set some + // attributes according to the result. Returns false if the specifier type + // is unknown. + bool analyze (CTree *spec); + + // check functions (used after analyse_seq() + bool check_prim_decl_specs (bool &have_type); + bool check_complex_decl_specs (bool &have_type); + bool check_storage_class (); + bool check_signed_unsigned (); + bool check_long_short (); + bool check_finally (); + + // type creation code + CTypeInfo *create_type (); + CTypeInfo *create_qualifiers (CTypeInfo *type); + +public: + /** Constructor. + * \param es The error stream on which to report errors. + * \param dss The declaration specifier sequence to be analysed. + * \param support_implicit_int True if implicit type int shall be supported. */ + CSemDeclSpecs (ErrorSink *es, CT_DeclSpecSeq *dss, bool support_implicit_int = false); + /** Destructor. Destroys the created type. */ + ~CSemDeclSpecs (); + + /** Get a copy of the resulting type. + * \return The copy of the type. Has to be destroyed by the caller. */ + CTypeInfo *make_type () const; + /** Get the declaration specifier sequence. */ + CT_DeclSpecSeq *DeclSpecSeq () const; + + /** Check if the given declaration specifier was declared. + * \param dst The declaration specifier type. */ + bool declared (CT_PrimDeclSpec::Type dst) const; + /** Check if a class was defined in the declaration specifier sequence. */ + bool defClass () const; + /** Check if an union was defined in the declaration specifier sequence. */ + bool defUnion () const; + /** Check if an enumeration was defined in the declaration specifier sequence. */ + bool defEnum () const; +}; + +inline CSemDeclSpecs::~CSemDeclSpecs () + { if (_type) CTypeInfo::Destroy (_type); } + +inline CTypeInfo *CSemDeclSpecs::make_type () const + { return CTypeInfo::Duplicate (_type); } +inline CT_DeclSpecSeq *CSemDeclSpecs::DeclSpecSeq () const + { return _dss; } + +inline bool CSemDeclSpecs::declared (CT_PrimDeclSpec::Type as) const + { return _prim_map[as] > 0; } + +inline bool CSemDeclSpecs::defClass () const + { return _def_class; } +inline bool CSemDeclSpecs::defUnion () const + { return _def_union; } +inline bool CSemDeclSpecs::defEnum () const + { return _def_enum; } + + +} // namespace Puma + +#endif /* __c_sem_decl_specs_h__ */ diff --git a/Puma/src/parser/cparser/CSemDeclarator.cc b/Puma/src/parser/cparser/CSemDeclarator.cc new file mode 100644 index 0000000..0f0daab --- /dev/null +++ b/Puma/src/parser/cparser/CSemDeclarator.cc @@ -0,0 +1,266 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CSemDeclarator.h" +#include "Puma/CObjectInfo.h" +#include "Puma/ErrorSink.h" +#include "Puma/CTree.h" +#include "Puma/CTypeInfo.h" +#include "Puma/CTypedefInfo.h" +#include "Puma/CClassInfo.h" +#include "Puma/CUnionInfo.h" +#include "Puma/CEnumInfo.h" +#include "Puma/CFunctionInfo.h" +#include "Puma/CConstant.h" + +namespace Puma { + + +/*DEBUG*/extern int TRACE_TYPE; + +void TypeText (std::ostream &out, CTypeInfo *t, int d) { + for (int i = 0; i < d; i++) + out << "| "; + if (t) { + if (t->TypeQualified ()) { + out<<"TypeQualified"; + if (t->TypeQualified ()->isConst ()) out<<" const"; + if (t->TypeQualified ()->isVolatile ()) out<<" volatile"; + if (t->TypeQualified ()->isRestrict ()) out<<" restrict"; + out<TypeFunction ()) { + out<<"TypeFunction"; + if (t->TypeFunction ()->isConst ()) out<<" const"; + if (t->TypeFunction ()->isVolatile ()) out<<" volatile"; + if (t->TypeFunction ()->isRestrict ()) out<<" restrict"; + out<TypePointer ()) { + if (t->TypeMemberPointer ()) + out<<"TypeMemberPointer"<TypeAddress ()) { + out<<"TypeAddress"<TypeBitField ()) { + out<<"TypeBitField "<TypeBitField ()->Dimension ()<TypeArray ()) { + if (t->TypeVarArray ()) + out<<"TypeVarArray"<TypeArray ()->Dimension ()<TypeClass ()) { + out<<"TypeClass"<TypeUnion ()) { + out<<"TypeUnion"<TypeEnum ()) { + out<<"TypeEnum"<TypePrimitive ()) { + out<<"TypePrimitive "<TypePrimitive ()->TypeName ()<TypeEmpty ()) { + out<<"TypeEmpty"<TypeTemplateParam ()) { + out<<"TypeTemplateParam"<"<BaseType () && t != t->BaseType ()) + TypeText (out, t->BaseType (), d + 1); + } else + out<<"NULL"<NodeName () == CT_InitDeclarator::NodeId ()) { + node = ((CT_InitDeclarator*)node)->Declarator (); + } else if (node->NodeName () == CT_RefDeclarator::NodeId ()) { + _type = new CTypeAddress (_type); + node = ((CT_RefDeclarator*)node)->Declarator (); + } else if (node->NodeName () == CT_PtrDeclarator::NodeId ()) { + _type = new CTypePointer (_type); + HandleQualifiers (((CT_PtrDeclarator*)node)->Qualifier ()); + node = ((CT_PtrDeclarator*)node)->Declarator (); + } else if (node->NodeName () == CT_MembPtrDeclarator::NodeId ()) { + CObjectInfo *cinfo = ((CT_MembPtrDeclarator*)node)->Name ()->Object (); + if (cinfo && cinfo->TypedefInfo ()) { + CTypeInfo* realtype = cinfo->TypedefInfo ()->TypeInfo (); + if (realtype) { + realtype = realtype->VirtualType (); + if (realtype->TypeRecord () && realtype->TypeRecord ()->Record ()) { + cinfo = realtype->TypeRecord ()->Record (); + } + } + } + _type = new CTypeMemberPointer (_type, cinfo); + HandleQualifiers (((CT_MembPtrDeclarator*)node)->Qualifier ()); + node = ((CT_MembPtrDeclarator*)node)->Declarator (); + } else if (node->NodeName () == CT_BitFieldDeclarator::NodeId ()) { + _type = new CTypeBitField (_type); + CT_BitFieldDeclarator *bfd = (CT_BitFieldDeclarator*)node; + if (bfd->Expr () && bfd->Expr ()->Value ()) + if ((v = bfd->Expr ()->Value ()->Constant ())) + _type->TypeBitField ()->Dimension (v->convert_to_uint ()); + node = bfd->Declarator (); + } else if (node->NodeName () == CT_BracedDeclarator::NodeId ()) { + node = ((CT_BracedDeclarator*)node)->Declarator (); + } else if (node->NodeName () == CT_ArrayDeclarator::NodeId ()) { + CT_ArrayDeclarator *ad = (CT_ArrayDeclarator*)node; + CT_ArrayDelimiter *delim = ad->Delimiter (); + bool is_const = false, is_volatile = false, is_restrict = false; + if (delim->Qualifier ()) + for (int i = delim->Qualifier ()->Sons () - 1; i >= 0; i--) { + if (delim->Qualifier ()->Son (i)->token ()->type () == TOK_CONST) + is_const = true; + else if (delim->Qualifier ()->Son (i)->token ()->type () == TOK_VOLATILE) + is_volatile = true; + else if (delim->Qualifier ()->Son (i)->token ()->type () == TOK_RESTRICT) + is_restrict = true; + } + CTypeQualified *quals = 0; + if (is_const || is_volatile || is_restrict) + quals = new CTypeQualified (&CTYPE_EMPTY, is_const, is_volatile, is_restrict); + if (delim->Star ()) + _type = new CTypeVarArray (_type, quals); // variable length array + else { + if (_type->TypeArray () && ! _type->TypeArray ()->hasDimension () && ! _type->TypeVarArray ()) { + if (node->token ()) + *_err << node->token ()->location (); + *_err << sev_error << "multidimensional array must have bounds for all dimensions except the first" + << endMessage; + } + _type = new CTypeArray (_type, quals, delim->Expr ()); + if (delim->Expr ()) { + if (delim->Expr ()->Value ()) { + if ((v = delim->Expr ()->Value ()->Constant ())) + _type->TypeArray ()->Dimension (v->convert_to_uint ()); + } else if (delim->Expr ()->Type () && + delim->Expr ()->Type ()->TypeTemplateParam ()) { + _type->TypeArray ()->DepDim ( + delim->Expr ()->Type ()->TypeTemplateParam ()); + } + } + } + node = ad->Declarator (); + } else if (node->NodeName () == CT_FctDeclarator::NodeId ()) { + CT_FctDeclarator *fd = (CT_FctDeclarator*)node; + CT_ArgDeclList *adl = fd->Arguments (); + int args = adl->Entries (); + CTypeList *tl = new CTypeList (args ? args : 1); + tl->ArgumentList (adl); + bool prototype = (adl->NodeName () != CT_ArgNameList::NodeId ()); + if (prototype) { + for (int i = 0; i < args; i++) { + CT_ArgDecl *arg = (CT_ArgDecl*) adl->Entry (i); + if (arg->Ellipsis ()) { + tl->AddEntry (&CTYPE_ELLIPSIS); + break; + } + // 8.3.5.3 adjust parameter type + CTypeInfo *argtype = arg->Object ()->TypeInfo (); + // any cv-qualifier modifying a parameter is deleted + if (argtype->TypeQualified ()) + argtype = argtype->UnqualType (); + // 8.3.5.2 the parameter list `(void)' is equivalent to + // the empty parameter list + if (argtype->is_void () && args == 1) + break; + // type `function returning T' is adjusted to be + // `pointer to function returning T' + if (argtype->TypeFunction ()) + argtype = new CTypePointer (argtype->Duplicate ()); + // type `array of T' is adjusted to be `pointer to T' + else if (argtype->TypeArray ()) { + CTypeInfo *quals = argtype->TypeArray ()->Qualifiers (); + argtype = argtype->BaseType (); + argtype = new CTypePointer (argtype->Duplicate ()); + if (quals) + argtype = new CTypeQualified (argtype, quals->isConst (), + quals->isVolatile (), quals->isRestrict ()); + } else + argtype = argtype->Duplicate (); + tl->AddEntry (argtype); + } + } + _type = new CTypeFunction (_type, tl, prototype); + HandleQualifiers (fd->Qualifier (), true); + node = fd->Declarator (); + } else if (node->NodeName () == CT_SimpleName::NodeId () || + node->NodeName () == CT_TemplateName::NodeId () || + node->NodeName () == CT_PrivateName::NodeId () || + node->NodeName () == CT_DestructorName::NodeId () || + node->NodeName () == CT_ConversionName::NodeId () || + node->NodeName () == CT_OperatorName::NodeId () || + node->NodeName () == CT_QualName::NodeId () || + node->NodeName () == CT_RootQualName::NodeId ()) { + _name = (CT_SimpleName*)node; + break; + } else { + if (node->token ()) + *_err << node->token ()->location (); + *_err << sev_fatal << "unknown declarator `" + << (const char*)node->NodeName () << "'" + << endMessage; + break; + } + } + if (_type && TRACE_TYPE) + TypeText (std::cout, _type, 0); +} + +void CSemDeclarator::HandleQualifiers (CT_DeclSpecSeq *dss, bool is_fct) { + if (dss) { + CTypeQualified* qt = _type->TypeQualified (); + int c_count = qt && qt->isConst () ? 1 : 0; + int v_count = qt && qt->isVolatile () ? 1 : 0; + int r_count = qt && qt->isRestrict () ? 1 : 0; + for (int s = 0; s < dss->Sons (); s++) { + CT_PrimDeclSpec *pds = (CT_PrimDeclSpec*)dss->Son (s); + if (pds->SpecType () == CT_PrimDeclSpec::PDS_CONST) { + c_count++; + if (c_count > 1) + *_err << sev_warning << pds->token ()->location () + << "duplicate `const'" << endMessage; + } else if (pds->SpecType () == CT_PrimDeclSpec::PDS_VOLATILE) { + v_count++; + if (v_count > 1) + *_err << sev_warning << pds->token ()->location () + << "duplicate `volatile'" << endMessage; + } else if (pds->SpecType () == CT_PrimDeclSpec::PDS_RESTRICT) { + r_count++; + if (r_count > 1) + *_err << sev_warning << pds->token ()->location () + << "duplicate `restrict'" << endMessage; + } + } + if (c_count || v_count || r_count) { + if (is_fct || qt) { + ((CTypeQualified*)_type)->isConst ((c_count)); + ((CTypeQualified*)_type)->isVolatile ((v_count)); + ((CTypeQualified*)_type)->isRestrict ((r_count)); + } else { + _type = new CTypeQualified (_type, (c_count), (v_count), (r_count)); + } + } + } +} + + +} // namespace Puma diff --git a/Puma/src/parser/cparser/CSemDeclarator.h b/Puma/src/parser/cparser/CSemDeclarator.h new file mode 100644 index 0000000..b169c52 --- /dev/null +++ b/Puma/src/parser/cparser/CSemDeclarator.h @@ -0,0 +1,70 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CSemDeclarator_h__ +#define __CSemDeclarator_h__ + +/** \file + * Semantic declarator analysis. */ + +#include "Puma/CTypeInfo.h" + +namespace Puma { + + +class CTree; +class ErrorSink; +class CT_SimpleName; +class CT_DeclSpecSeq; + + +/** \class CSemDeclarator CSemDeclarator.h Puma/CSemDeclarator.h + * Class for analysing an entity declarator. The result of the + * analysis is a type and the name of the declared entity + * (name and type of function, object, etc). */ +class CSemDeclarator { + ErrorSink *_err; + CTypeInfo *_type; + CT_SimpleName *_name; + +public: + /** Constructor. + * \param err The error stream on which to report errors. + * \param t The base type of the declared entity (function return type, data type, etc). + * \param d The declarator to analyse. + * \param lang_c Support language C. */ + CSemDeclarator (ErrorSink *err, CTypeInfo *t, CTree *d, bool lang_c = true); + /** Destructor. Destroys the resulting type. */ + ~CSemDeclarator () { if (_type) CTypeInfo::Destroy (_type); } + /** Get the name of the declared entity. */ + CT_SimpleName *Name () const { return _name; } + /** Get the resulting type. */ + CTypeInfo *Type () const { return _type; } + /** Set the type of the declared entity. This type will be + * destroyed in the destructor of this class. + * \param t The type. */ + void Type (CTypeInfo *t) { _type = t; } + +private: + void HandleQualifiers (CT_DeclSpecSeq *, bool = false); +}; + + +} // namespace Puma + +#endif /* __CSemDeclarator_h__ */ diff --git a/Puma/src/parser/cparser/CSemExpr.cc b/Puma/src/parser/cparser/CSemExpr.cc new file mode 100644 index 0000000..0779c50 --- /dev/null +++ b/Puma/src/parser/cparser/CSemExpr.cc @@ -0,0 +1,2703 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CAttributeInfo.h" +#include "Puma/CFunctionInfo.h" +#include "Puma/CArgumentInfo.h" +#include "Puma/CTypedefInfo.h" +#include "Puma/CWStrLiteral.h" +#include "Puma/CStrLiteral.h" +#include "Puma/CObjectInfo.h" +#include "Puma/CUnionInfo.h" +#include "Puma/CStructure.h" +#include "Puma/CClassInfo.h" +#include "Puma/CScopeInfo.h" +#include "Puma/CEnumInfo.h" +#include "Puma/CFileInfo.h" +#include "Puma/CTypeInfo.h" +#include "Puma/CConstant.h" +#include "Puma/CSemExpr.h" +#include "Puma/CTree.h" +#include "Puma/Limits.h" +#include "Puma/Utf8.h" + +// this include shall be removed as soon as ac++ can better deal with +// the include cycle problem +#include "Puma/CSemVisitor.h" + +#include +#include "Puma/WChar.h" /* wcslen() */ +#include /* isdigit(), isxdigit() */ +#include +#include /* strtod() */ + + +namespace Puma { + + +// print semantic error messages + +#define SEM_MSG(node__,mesg__) \ + {if (node__->token ()) err << node__->token ()->location (); err << mesg__ << endMessage;} + +#define SEM_ERROR(node__, mesg__) \ + SEM_MSG (node__, sev_error << mesg__) + +#define SEM_WARNING(node__, mesg__) \ + SEM_MSG (node__, sev_warning << mesg__) + +#define SEM_ERROR__undeclared(name__) \ + SEM_ERROR (name__, "`" << name__->token ()->text () << "' undeclared here") + +#define SEM_WARNING__out_of_range(node__,what__) \ + SEM_WARNING (node__, what__ << " out of range") + +#define SEM_WARNING__is_unsigned(node__) \ + SEM_WARNING (node__, \ + "decimal constant is so large that it is unsigned") + +#define SEM_WARNING__incompatible_assign(node__) \ + SEM_WARNING (node__, \ + "assignment from incompatible pointer type") + +#define SEM_WARNING__init(node__,name__,type__) \ + SEM_WARNING (node__, type__ << " object `" << name__->Name () \ + << "' may not be initialized") + +#define SEM_WARNING__type_mismatch(node__,where__) \ + SEM_WARNING (node__, "type mismatch in " << where__) + +#define SEM_ERROR__invalid_op(node__,type__,op__) \ + SEM_ERROR (node__, "invalid operand to " << type__ << " `" << op__ << "'") + +#define SEM_WARNING__comp_between(node__,what__) \ + SEM_WARNING (node__, "comparison between " << what__) + +#define SEM_ERROR__non_lvalue(node__) \ + SEM_ERROR (node__, "non-lvalue in assignment") + +#define SEM_ERROR__num_args_too(node__,what__,num__,info__) \ + SEM_ERROR (node__, "too " << what__ << " arguments (" << num__ << ") in call to function `" \ + << info__->Name () << "'") + +#define SEM_ERROR__invalid_arg(node__,pos__,info__) \ + SEM_ERROR (node__, "invalid argument " << pos__ \ + << " in call to function `" << info__->Name () << "'") + +#define SEM_WARNING__incompatible_arg(node__,pos__,info__) \ + SEM_WARNING (node__, "passing argument " << pos__ \ + << " of `" << info__->Name () << "' from incompatible type") + + +/////////////////////////////////////////////////////// +// expression evaluation ////////////////////////////// +/////////////////////////////////////////////////////// + + +CTypeInfo *CSemExpr::resolveExpr (CTree *expr, CTree *base) { + CTypeInfo *result = expr->Type (); + + // ensure not to evaluate twice + if (! result || *result == CTYPE_UNDEFINED || + expr->IsSimpleName () || + expr->NodeName () == CT_BracedExpr::NodeId ()) { + // call the node type specific resolve function + if (!(result = expr->resolve (*this, base))) { + SEM_ERROR (expr, "expression expected"); + result = &CTYPE_UNDEFINED; + if (expr->SemValue ()) + expr->SemValue ()->setTypeRef (result); + } + } + + // implicit lvalue, array and function type conversions + result = applyImplicitConv (expr, base, result); + + return result; +} + + +// fallback: unhandled kind of expression +CTypeInfo *CSemExpr::resolve (CTree *node, CTree *base) { + SEM_ERROR (node, "illegal expression"); + CTypeInfo *result = &CTYPE_UNDEFINED; + if (node->SemValue ()) + node->SemValue ()->setTypeRef (result); + return result; +} + + +/////////////////////////////////////////////////////// +// boolean constant /////////////////////////////////// +/////////////////////////////////////////////////////// + + + +CTypeInfo *CSemExpr::resolve (CT_Bool *node, CTree *base) { + CTypeInfo *result; + U_LONG_LONG v; + + v = (strcmp (node->token ()->text (), "true") == 0) ? 1 : 0; + result = &CTYPE_C_BOOL; + + node->setValue (new CConstant (v, result)); + node->setTypeRef (result); + return result; +} + + + +/////////////////////////////////////////////////////// +// character constant ///////////////////////////////// +/////////////////////////////////////////////////////// + + + +CTypeInfo *CSemExpr::resolve (CT_Character *node, CTree *base) { + CTypeInfo *result; + LONG_LONG v; + int chars; + + chars = scan_character (node, v); + if (chars == 1) { // character constant + result = &CTYPE_CHAR; + v = (char)v; + } else { // integer character constant + if (chars > 4) { + SEM_ERROR (node, "integer character constant too long"); + } else { + SEM_WARNING (node, "multi-character character constant"); + } + result = &CTYPE_INT; + v = (int)v; + } + + node->setValue (new CConstant (v, result)); + node->setTypeRef (result); + return result; +} + + + +/////////////////////////////////////////////////////// +// wide character constant //////////////////////////// +/////////////////////////////////////////////////////// + + + +CTypeInfo *CSemExpr::resolve (CT_WideCharacter *node, CTree *base) { + CTypeInfo *result; + LONG_LONG v; + int chars; + + chars = scan_character (node, v); + if (chars == 1) { + result = &CTYPE_WCHAR_T; + v = (wchar_t)v; + } else { + if (chars > 4) { + SEM_ERROR (node, "integer character constant too long"); + } else { + SEM_WARNING (node, "multi-character character constant"); + } + result = &CTYPE_INT; + v = (int)v; + } + + node->setValue (new CConstant (v, result)); + node->setTypeRef (result); + return result; +} + + + +/////////////////////////////////////////////////////// +// string constant //////////////////////////////////// +/////////////////////////////////////////////////////// + + +CTypeInfo *CSemExpr::resolve (CT_String *node, CTree *base) { + CTypeInfo *result; + const char *s, *e; + char *p, *buf; + long int ct; + LONG_LONG i; + bool ucs; + + // create string buffer + i = 0; + for (int t = 0; t < node->Sons (); t++) { + s = node->Son (t)->token ()->text (); + i += strlen (s) - 2; + } + buf = new char[i+10]; + + // collect the string characters from all tokens + buf[0] = '\0'; + ct = 0; + for (int t = 0; t < node->Sons (); t++) { + s = node->Son (t)->token ()->text (); + + i = strlen (s); + if (s[0] == '"') { + s++; + i--; + if (s[i-1] == '"') + i--; + } + e = &s[i]; + + p = buf + strlen (buf); + while (s && *s && s != e) { + i = next_character (s, ucs); + if (ucs && i == (LONG_LONG)-1) { + SEM_ERROR (node, "incomplete universal character"); + break; + } + if (ucs) { + // turn the char value into a utf-8 octet stream + utf8_encode (i, p, ct); + } + else { + if (i > UCHAR_MAX) + SEM_WARNING__out_of_range (node, "escape sequence"); + *p++ = (char)(i&0xff); + ct++; + } + } + + *p++ = 0; + *p = 0; + } + + // type `array of char' + result = new CTypeArray (&CTYPE_CHAR); + result->TypeArray ()->Dimension (ct+1); + node->setValue (new CStrLiteral (buf, ct, result)); + node->setType (result); + + return result; +} + + + +/////////////////////////////////////////////////////// +// wide string constant /////////////////////////////// +/////////////////////////////////////////////////////// + + + +CTypeInfo *CSemExpr::resolve (CT_WideString *node, CTree *base) { + CTypeInfo *result; + const char *s, *e; + wchar_t *p, *buf; + long int ct; + LONG_LONG i; + bool ucs; + + // create string buffer + i = 0; + for (int t = 0; t < node->Sons (); t++) { + s = node->Son (t)->token ()->text (); + if (*s == 'L') + s++; + i += strlen (s) - 2; + } + buf = new wchar_t[i+2]; + + // collect the string characters from all tokens + buf[0] = L'\0'; + ct = 0; + for (int t = 0; t < node->Sons (); t++) { + s = node->Son (t)->token ()->text (); + if (*s == 'L') + s++; + + i = strlen (s); + if (s[0] == '"') { + s++; + i--; + if (s[i-1] == '"') + i--; + } + e = &s[i]; + + p = buf + wcslen (buf); + while (s && *s && s != e) { + i = next_character (s, ucs); + if (ucs && i == (LONG_LONG)-1) { + SEM_ERROR (node, "incomplete universal character"); + break; + } + if (i > ULONG_MAX) + SEM_WARNING__out_of_range (node, "escape sequence"); + *p++ = (wchar_t)(i&0xffffffff); + ct++; + } + + *p++ = 0; + *p = 0; + } + + // type `array of wchar_t' + result = new CTypeArray (&CTYPE_WCHAR_T); + result->TypeArray ()->Dimension (ct+1); + node->setValue (new CWStrLiteral (buf, ct, result)); + node->setType (result); + + return result; +} + + + +/////////////////////////////////////////////////////// +// integer constant /////////////////////////////////// +/////////////////////////////////////////////////////// + + + +CTypeInfo *CSemExpr::resolve (CT_Integer *node, CTree *) { + bool uns, lng, lnglng, trunc; + U_LONG_LONG val, max, i; + CTypeInfo *result; + const char *s; + int base; + + s = node->Son (0)->token ()->text (); + if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) { + base = 16; + s += 2; + } else if (s[0] == '0' && isdigit (s[1])) { + base = 8; + s++; + } else + base = 10; + + val = 0; + max = (ULLONG_MAX / base) + (ULLONG_MAX % base); + uns = lng = lnglng = trunc = false; + + while (isxdigit (*s)) { + if (isdigit (*s)) + i = *s - '0'; + else if (*s >= 'A' && *s <= 'F') + i = *s - 'A' + 10; + else + i = *s - 'a' + 10; + s++; + if (! trunc && ((val + i) > max || ((val + i) == max && isxdigit (*s)))) { + trunc = true; + SEM_WARNING (node, "integer constant is too large" << + " - truncated to " << CTYPE_UNSIGNED_LONG_LONG.Size() << " bits"); + } + val = (val * base) + i; + } + + while (*s != 0) { + if (*s == 'u' || *s == 'U') + uns = true; + else if (*s == 'l' || *s == 'L') { + if (lng) { + lng = false; + lnglng = true; + } else + lng = true; + } + s++; + } + + // determine type and handle overflows + long int size = CTypePrimitive::SizeOfNumber(val); + if (lnglng) { + if (! uns && size > CTYPE_LONG_LONG.Size()) + overflow (node, base, uns); + } else if (uns && lng) { + if (size > CTYPE_UNSIGNED_LONG.Size()) { + lng = false; + lnglng = true; + } + } else if (lng) { + if (size > CTYPE_LONG_LONG.Size()) + overflow (node, base, uns); + else if ((base != 10 && size > CTYPE_UNSIGNED_LONG.Size()) || + (base == 10 && size > CTYPE_LONG.Size())) { + lng = false; + lnglng = true; + } else if (base != 10 && size > CTYPE_LONG.Size()) + overflow (node, base, uns); + } else if (uns) { + if (size > CTYPE_UNSIGNED_LONG.Size()) + lnglng = true; + else if (size > CTYPE_UNSIGNED_INT.Size()) + lng = true; + } else { + if (size > CTYPE_LONG_LONG.Size()) { + overflow (node, base, uns); + if (base != 10) + lnglng = true; + } else if ((base != 10 && size > CTYPE_UNSIGNED_LONG.Size()) || + (base == 10 && size > CTYPE_LONG.Size())) { + lnglng = true; + } else if (base != 10 && size > CTYPE_LONG.Size()) { + overflow (node, base, uns); + lng = true; + } else if ((base != 10 && size > CTYPE_UNSIGNED_INT.Size()) || + (base == 10 && size > CTYPE_INT.Size())) { + lng = true; + } else if (size > CTYPE_INT.Size()) + overflow (node, base, uns); + } + + // set type + if (uns && lnglng) + result = &CTYPE_UNSIGNED_LONG_LONG; + else if (lnglng) + result = &CTYPE_LONG_LONG; + else if (uns && lng) + result = &CTYPE_UNSIGNED_LONG; + else if (lng) + result = &CTYPE_LONG; + else if (uns) + result = &CTYPE_UNSIGNED_INT; + else + result = &CTYPE_INT; + + node->setValue (uns ? new CConstant ((U_LONG_LONG)val, result) : + new CConstant ((LONG_LONG)val, result)); + node->setTypeRef (result); + return result; +} + + + +/////////////////////////////////////////////////////// +// floating point constant //////////////////////////// +/////////////////////////////////////////////////////// + + + +CTypeInfo *CSemExpr::resolve (CT_Float *node, CTree *base) { + CTypeInfo *result; + long double v; + bool lng, flt; + const char *s; + int ln; + + s = node->Son (0)->token ()->text (); + ln = strlen (s); + + lng = (s[ln-1] == 'l' || s[ln-1] == 'L'); + flt = (s[ln-1] == 'f' || s[ln-1] == 'F'); + + v = strtod(s, NULL); + + if (lng) + result = &CTYPE_LONG_DOUBLE; + else if (flt) + result = &CTYPE_FLOAT; + else + result = &CTYPE_DOUBLE; + + node->setValue (new CConstant (v, result)); + node->setTypeRef (result); + return result; +} + + + +/////////////////////////////////////////////////////// +// name /////////////////////////////////////////////// +/////////////////////////////////////////////////////// + + + +CTypeInfo *CSemExpr::resolve (CT_SimpleName *node, CTree *base) { + CObjectInfo *info; + CTypeInfo *result; + LONG_LONG v; + + // find semantic object to name + info = lookup (node, NON_TAG, true); + if (! info || info->TypedefInfo ()) { + // typedef name or not a implicitely declared function + if (info || base->NodeName () != CT_CallExpr::NodeId ()) { + SEM_ERROR__undeclared (node); + } + node->setTypeRef (&CTYPE_UNDEFINED); + return &CTYPE_UNDEFINED; + } + + result = info->TypeInfo (); + node->Object (info); + node->setTypeRef (result); + + // name of a constant, refer to its value + if (info->EnumeratorInfo () && info->EnumeratorInfo ()->hasValue ()) { + v = info->EnumeratorInfo ()->Value (); + node->setValue (new CConstant (v, result)); + } + + return result; +} + + + +/////////////////////////////////////////////////////// +// braced expression ////////////////////////////////// +/////////////////////////////////////////////////////// + + + +CTypeInfo *CSemExpr::resolve (CT_BracedExpr *node, CTree *base) { + CTypeInfo* result = resolveExpr (node->Expr (), node); + + // handle constants + passOnConstant (node->Expr (), node, result); + + node->setTypeRef (result); + return result; +} + + + +/////////////////////////////////////////////////////// +// binary expression ////////////////////////////////// +/////////////////////////////////////////////////////// + + + +CTypeInfo *CSemExpr::resolve (CT_BinaryExpr *node, CTree *base) { + CTypeInfo *result; + int ctp_old, oper; + + result = &CTYPE_UNDEFINED; + oper = node->Son (1)->token ()->type (); + + ctp_old = conv_to_ptr; + conv_to_ptr = 1; + + // don't apply lvalue-to-rvalue conversion if left operand of assignment + if (oper == TOK_ASSIGN || oper == TOK_MUL_EQ || oper == TOK_DIV_EQ || + oper == TOK_MOD_EQ || oper == TOK_ADD_EQ || oper == TOK_SUB_EQ || + oper == TOK_RSH_EQ || oper == TOK_LSH_EQ || oper == TOK_AND_EQ || + oper == TOK_XOR_EQ || oper == TOK_IOR_EQ) + conv_to_ptr = 3; + + // resolve operands + resolveExpr (node->Son (0), node); + if (conv_to_ptr == 3) + conv_to_ptr = 1; + if (oper == TOK_COMMA) + conv_to_ptr = ctp_old; + resolveExpr (node->Son (2), node); + + // assignment expression: op1 = op2; op1 *= op2; op1 /= op2; + // op1 %= op2; op1 += op2; op1 -= op2; op1 >>= op2; + // op1 <<= op2; op1 &= op2; op1 ^= op2; op1 |= op2 + if (oper == TOK_ASSIGN || oper == TOK_MUL_EQ || oper == TOK_DIV_EQ || + oper == TOK_MOD_EQ || oper == TOK_ADD_EQ || oper == TOK_SUB_EQ || + oper == TOK_RSH_EQ || oper == TOK_LSH_EQ || oper == TOK_AND_EQ || + oper == TOK_XOR_EQ || oper == TOK_IOR_EQ) + result = binary_ass (node); + // additive expression: op1 + op2; op1 - op2 + else if (oper == TOK_PLUS || oper == TOK_MINUS) + result = binary_add (node); + // multiplicative expression: op1 * op2; op1 / op2; op1 % op2 + else if (oper == TOK_MUL || oper == TOK_DIV || oper == TOK_MODULO) + result = binary_mul (node); + // shift expression: op1 << op2; op1 >> op2 + else if (oper == TOK_LSH || oper == TOK_RSH) + result = binary_shift (node); + // relational expression: op1 < op2; op1 > op2; op1 <= op2; op1 >= op2 + else if (oper == TOK_LESS || oper == TOK_GREATER || + oper == TOK_LEQ || oper == TOK_GEQ) + result = binary_rel (node); + // equality expression: op1 == op2; op1 != op2 + else if (oper == TOK_EQL || oper == TOK_NEQ) + result = binary_equ (node); + // AND expression: op1 & op2 + // exclusive-OR expression: op1 ^ op2 + // inclusive-OR expression: op1 | op2 + else if (oper == TOK_AND || oper == TOK_ROOF || oper == TOK_OR) + result = binary_and (node); + // logical-AND expression: op1 && op2 + // logical-OR expression: op1 || op2 + else if (oper == TOK_AND_AND || oper == TOK_OR_OR) + result = binary_log (node); + // comma expression: op1 , op2 + else if (oper == TOK_COMMA) + result = binary_comma (node); + + node->setTypeRef (result); + return result; +} + +CTypeInfo *CSemExpr::binary_add (CT_BinaryExpr *node) { + CTypeInfo *t1, *t2; + unsigned long pos; + int oper; + + oper = node->Son (1)->token ()->type (); + pos = node->Son (1)->token_node ()->Number (); + + // apply integer promotions on operands + t1 = promote (node->Son (0), node); + t2 = promote (node->Son (2), node); + + if (t1->isArithmetic () && t2->isArithmetic ()) { + return apply_binary_op (node, oper); + } else if (oper == TOK_PLUS) { + if (! (t1->isArithmetic () && isPtrToObj (t2, pos)) && + ! (t2->isArithmetic () && isPtrToObj (t1, pos))) { + SEM_ERROR__invalid_op (node, "binary", "+"); + } else + return t1->isPointer () ? t1 : t2; + } else { // TOK_MINUS + if (! (isPtrToObj (t1, pos) && t2->isInteger ()) && + ! (isPtrToObj (t1, pos) && isPtrToObj (t2, pos) && compatibleBase (t1, t2))) { + SEM_ERROR__invalid_op (node, "binary", "-"); + } else /* ptrdiff_t */ + return t1->isPointer () && t2->isPointer () ? CTypeInfo::CTYPE_PTRDIFF_T : t1; + } + return &CTYPE_UNDEFINED; +} + +CTypeInfo *CSemExpr::binary_mul (CT_BinaryExpr *node) { + CTypeInfo *t1, *t2; + const char *op; + CConstant *v2; + int oper; + + op = node->Son (1)->token ()->text (); + oper = node->Son (1)->token ()->type (); + + // apply integer promotions on operands + t1 = promote (node->Son (0), node); + t2 = promote (node->Son (2), node); + + if (! (t1->isArithmetic () && t2->isArithmetic ()) && + ! (oper == TOK_MODULO && t1->isInteger () && t2->isInteger ())) { + SEM_ERROR__invalid_op (node, "binary", op); + } else { + v2 = node->Son (2)->Value () ? node->Son (2)->Value ()->Constant () : 0; + if ((oper == TOK_MODULO || oper == TOK_DIV) && v2 && v2->isNull ()) + SEM_WARNING (node, "division by zero"); + return apply_binary_op (node, oper); + } + return &CTYPE_UNDEFINED; +} + +CTypeInfo *CSemExpr::binary_shift (CT_BinaryExpr *node) { + CTypeInfo *t1, *t2; + const char *op; + CConstant *v2; + int oper; + + op = node->Son (1)->token ()->text (); + oper = node->Son (1)->token ()->type (); + + // apply integer promotions on operands + t1 = promote (node->Son (0), node); + t2 = promote (node->Son (2), node); + + if (! (t1->isInteger () && t2->isInteger ())) { + SEM_ERROR__invalid_op (node, "binary", op); + } else { + v2 = node->Son (2)->Value () ? node->Son (2)->Value ()->Constant () : 0; + if (v2 && v2->isNegative ()) + SEM_WARNING (node, "negative shift count"); + + t2 = apply_binary_op (node, oper); + v2 = node->Value () ? node->Value ()->Constant () : 0; + if (v2 && t2 != t1) // must have type of promoted first operand + node->setValue (v2->cast_to (t1)); + return t1; + } + return &CTYPE_UNDEFINED; +} + +CTypeInfo *CSemExpr::binary_rel (CT_BinaryExpr *node) { + CTypeInfo *t1, *t2; + const char *op; + CConstant *v1; + int oper; + + op = node->Son (1)->token ()->text (); + oper = node->Son (1)->token ()->type (); + + // apply integer promotions on operands + t1 = promote (node->Son (0), node); + t2 = promote (node->Son (2), node); + + if (t1->isArithmetic () && t2->isArithmetic ()) { + t1 = apply_binary_op (node, oper); + v1 = node->Value () ? node->Value ()->Constant () : 0; + if (v1 && *t1 != CTYPE_INT) // must have type `int' + node->setValue (v1->cast_to (&CTYPE_INT)); + } else if (! (t1->isPointer () && t2->isPointer () && + compatibleBase (t1, t2))) + SEM_ERROR__invalid_op (node, "binary", op); + return &CTYPE_INT; +} + +CTypeInfo *CSemExpr::binary_equ (CT_BinaryExpr *node) { + CTypeInfo *t1, *t2; + const char *op; + CConstant *v1; + int oper; + bool l; + + op = node->Son (1)->token ()->text (); + oper = node->Son (1)->token ()->type (); + + // apply integer promotions on operands + t1 = promote (node->Son (0), node); + t2 = promote (node->Son (2), node); + + if (t1->isArithmetic () && t2->isArithmetic ()) { + t1 = apply_binary_op (node, oper); + v1 = node->Value () ? node->Value ()->Constant () : 0; + if (v1 && *t1 != CTYPE_INT) // must have type `int' + node->setValue (v1->cast_to (&CTYPE_INT)); + } else if ((t1->isInteger () && t2->isPointer ()) || + (t2->isInteger () && t1->isPointer ())) { + l = t1->isInteger () ? true : false; + v1 = node->Son (l?0:2)->Value () ? node->Son (l?0:2)->Value ()->Constant () : 0; + if (v1 && v1->isNull ()) // null pointer constant + cast_to (l?t2:t1, node->Son (l?0:2), node); + else + SEM_WARNING__comp_between (node, "pointer and integer"); + } else if (t1->isPointer () && t2->isPointer () && + (t1->VirtualType ()->BaseType ()->isVoid () || + t2->VirtualType ()->BaseType ()->isVoid ())) { + if (*t1 != *t2) { + l = t1->VirtualType ()->BaseType ()->isVoid () ? true : false; + cast_to (l?t1:t2, node->Son (l?2:0), node); + } + } else if (t1->isPointer () && t2->isPointer ()) { + if (! compatibleBase (t1, t2)) + SEM_WARNING__comp_between (node, "distinct pointer types"); + } else + SEM_ERROR__invalid_op (node, "binary", op); + return &CTYPE_INT; +} + +CTypeInfo *CSemExpr::binary_and (CT_BinaryExpr *node) { + CTypeInfo *t1, *t2; + const char *op; + int oper; + + op = node->Son (1)->token ()->text (); + oper = node->Son (1)->token ()->type (); + + // apply integer promotions on operands + t1 = promote (node->Son (0), node); + t2 = promote (node->Son (2), node); + + if (! (t1->isInteger () && t2->isInteger ())) { + SEM_ERROR__invalid_op (node, "binary", op); + } else + return apply_binary_op (node, oper); + return &CTYPE_UNDEFINED; +} + +CTypeInfo *CSemExpr::binary_log (CT_BinaryExpr *node) { + CTypeInfo *t1, *t2; + const char *op; + CConstant *v1; + int oper; + + op = node->Son (1)->token ()->text (); + oper = node->Son (1)->token ()->type (); + + // apply integer promotions on operands + t1 = promote (node->Son (0), node); + t2 = promote (node->Son (2), node); + + if (! (t1->isScalar () && t2->isScalar ())) { + SEM_ERROR__invalid_op (node, "binary", op); + } else if (t1->isArithmetic () && t2->isArithmetic ()) { + t1 = apply_binary_op (node, oper); + v1 = node->Value () ? node->Value ()->Constant () : 0; + if (v1 && *t1 != CTYPE_INT) // must have type `int' + node->setValue (v1->cast_to (&CTYPE_INT)); + } + return &CTYPE_INT; +} + +CTypeInfo *CSemExpr::binary_comma (CT_BinaryExpr *node) { +// CExprValue *value; + +// value = node->Son (2)->Value (); +// if (value) +// node->setValueRef (value); + return node->Son (2)->Type (); +} + +CTypeInfo *CSemExpr::binary_ass (CT_BinaryExpr *node) { + CTypeInfo *t1, *t2; + unsigned long pos; + const char *op; + CConstant *v2; + int oper; + + op = node->Son (1)->token ()->text (); + oper = node->Son (1)->token ()->type (); + pos = node->Son (1)->token_node ()->Number (); + t1 = node->Son (0)->Type (); + t2 = node->Son (2)->Type (); + v2 = node->Son (2)->Value () ? node->Son (2)->Value ()->Constant () : 0; + + if (! isLvalue (node->Son (0))) { + SEM_ERROR__non_lvalue (node); + } else { + if (! isModifiable (t1, pos)) + SEM_WARNING (node, "assignment of unmodifiable location"); + if (t1->isArithmetic () && t2->isArithmetic ()) { + if (oper == TOK_ASSIGN) { + if (*t1 != *t2) + cast_to (t1->VirtualType (), node->Son (2), node); + } else { + if ((oper == TOK_RSH_EQ || oper == TOK_LSH_EQ || + oper == TOK_MOD_EQ || oper == TOK_AND || + oper == TOK_ROOF || oper == TOK_OR) && + ! (t1->isInteger () && t2->isInteger ())) + SEM_ERROR__invalid_op (node, "binary", op); + if (v2) { + if ((oper == TOK_MOD_EQ || oper == TOK_DIV_EQ) && v2->isNull ()) { + SEM_WARNING (node, "division by zero"); + } else if ((oper == TOK_RSH_EQ || oper == TOK_LSH_EQ) && + v2->isNegative ()) { + SEM_WARNING (node, "negative shift count"); + } + } + } + return t1->VirtualType (); + } else if (oper == TOK_ASSIGN) { + if (! compatible (t1, t2, v2)) + SEM_WARNING__incompatible_assign (node); + if (*t1 != *t2) + cast_to (t1->VirtualType (), node->Son (2), node); + return t1->VirtualType (); + } else if (oper == TOK_ADD_EQ || oper == TOK_SUB_EQ) { + if (! (isPtrToObj (t1, pos) && t2->isInteger ())) { + SEM_ERROR__invalid_op (node, "binary", op); + } else + return t1->VirtualType (); + } else + SEM_ERROR__invalid_op (node, "binary", op); + } + return &CTYPE_UNDEFINED; +} + +// apply binary operator +CTypeInfo *CSemExpr::apply_binary_op (CTree *node, int oper) { + CTypeInfo *t1, *t2, *result; + CConstant *v1, *v2; + CTree *op1, *op2; + + op1 = node->Son (0); + op2 = node->Son (2); + t1 = op1->Type (); + t2 = op2->Type (); + + // cast operands if needed + result = t1; + if (*t1 > *t2) { + cast_to (t1, op2, node); + op2 = node->Son (2); + } else if (*t1 < *t2) { + result = cast_to (t2, op1, node); + op1 = node->Son (0); + } + + // apply operator on constant values if any + v1 = op1->Value () ? op1->Value ()->Constant () : (CConstant*)0; + v2 = op2->Value () ? op2->Value ()->Constant () : (CConstant*)0; + if (v1 && v2 && node->SemValue ()) + node->SemValue ()->setValue (v1->compute (oper, v2)); + + return result; +} + + + +/////////////////////////////////////////////////////// +// unary expression /////////////////////////////////// +/////////////////////////////////////////////////////// + + + +CTypeInfo *CSemExpr::resolve (CT_UnaryExpr *node, CTree *base) { + CTypeInfo *result, *t1; + unsigned long pos; + const char *op; + CConstant *v1; + CTree *op1; + int oper; + + result = &CTYPE_UNDEFINED; + op = node->Son (0)->token ()->text (); + oper = node->Son (0)->token ()->type (); + + conv_to_ptr = 1; + + // don't apply lvalue-to-rvalue conversion + if (oper == TOK_DECR || oper == TOK_INCR) + conv_to_ptr = 3; + + // resolve operands + t1 = resolveExpr (node->Son (1), node); + op1 = node->Son (1); + pos = node->Son (1)->token_node ()->Number (); + v1 = op1->Value () ? op1->Value ()->Constant () : (CConstant*)0; + + // ++ op1; -- op1 + if (oper == TOK_DECR || oper == TOK_INCR) { + if (! isLvalue (op1)) { + SEM_ERROR__non_lvalue (node); + } else { + if (! isModifiable (t1, pos)) { + if (oper == TOK_DECR) { + SEM_WARNING (node, "decrement of unmodifiable location"); + } else { + SEM_WARNING (node, "increment of unmodifiable location"); + } + } + if (! t1->isScalar ()) { + SEM_ERROR__invalid_op (node, "unary", op); + } else + result = t1->VirtualType (); + } + } + // + op1; - op1; ~ op1 + else if (oper == TOK_PLUS || oper == TOK_MINUS || oper == TOK_TILDE) { + t1 = promote (op1, node); + if (! t1->isArithmetic () || (oper == TOK_TILDE && ! t1->isInteger ())) { + SEM_ERROR__invalid_op (node, "unary", op); + } else { + if (v1) + node->setValue (v1->compute (oper)); + result = t1; + } + } + // ! op1 + else if (oper == TOK_NOT) { + if (! t1->isScalar ()) { + SEM_ERROR__invalid_op (node, "unary", op); + } else { + if (v1) { + node->setValue (v1->compute (oper)); + if (*t1 != CTYPE_INT) // must have type `int' + node->setValue (v1->cast_to (&CTYPE_INT)); + } + result = &CTYPE_INT; + } + } + + node->setTypeRef (result); + return result; +} + +CTypeInfo *CSemExpr::resolve (CT_AddrExpr *node, CTree *) { + CTypeInfo *result, *t1; + CObjectInfo *info; + CTree *op1, *base; + + result = &CTYPE_UNDEFINED; + + // do not apply standard array and function type conversions + conv_to_ptr = 0; + + // resolve operand + t1 = resolveExpr (node->Son (1), node); + op1 = node->Son (1); + + base = op1; + while (true) { + if (base->NodeName () == CT_BracedExpr::NodeId ()) + base = base->Son (1); + else if (base->NodeName () == CT_ImplicitCast::NodeId ()) + base = base->Son (0); + else + break; + } + + info = findObject (op1); + if (t1->isFunction () || + t1->isArray () || + base->NodeName () == CT_DerefExpr::NodeId () || + base->NodeName () == CT_IndexExpr::NodeId () || + (isLvalue (op1) && (info ? ! info->TypeInfo ()->TypeBitField () : true))) { + result = new CTypePointer (t1->Duplicate ()); + cast_to (result, op1, node, false); + } else { + SEM_ERROR__invalid_op (node, "unary", "&"); + } + + node->setTypeRef (result); + return result; +} + +CTypeInfo *CSemExpr::resolve (CT_DerefExpr *node, CTree *base) { + CTypeInfo *result, *t1; + unsigned long pos; + int ctp_old; + + result = &CTYPE_UNDEFINED; + + ctp_old = conv_to_ptr; + conv_to_ptr = 1; + + // resolve operand + t1 = resolveExpr (node->Son (1), node); + conv_to_ptr = ctp_old; + pos = node->Son (1)->token_node ()->Number (); + + if (! t1->isPointer ()) { + SEM_ERROR__invalid_op (node, "unary", "*"); + } else { + if (! isPtrToObj (t1, pos)) + SEM_WARNING (node, "dereferencing pointer to incomplete type"); + result = t1->VirtualType ()->BaseType (); + } + + node->setTypeRef (result); + return result; +} + + + +/////////////////////////////////////////////////////// +// postfix expression ///////////////////////////////// +/////////////////////////////////////////////////////// + + + +CTypeInfo *CSemExpr::resolve (CT_PostfixExpr *node, CTree *base) { + CTypeInfo *result, *t1; + unsigned long pos; + const char *op; + int oper; + + conv_to_ptr = 1; + + result = &CTYPE_UNDEFINED; + op = node->Son (1)->token ()->text (); + oper = node->Son (1)->token ()->type (); + pos = node->Son (1)->token_node ()->Number (); + + // don't apply lvalue-to-rvalue conversion + if (oper == TOK_DECR || oper == TOK_INCR) + conv_to_ptr = 3; + + // resolve operand + t1 = resolveExpr (node->Son (0), node); + + // postfix in-/decrement: op1 ++; op1 -- + if (! isLvalue (node->Son (0))) { + SEM_ERROR__non_lvalue (node); + } else { + if (! isModifiable (t1, pos)) { + if (oper == TOK_DECR) { + SEM_WARNING (node, "decrement of unmodifiable location"); + } else { + SEM_WARNING (node, "increment of unmodifiable location"); + } + } + if (! t1->isScalar ()) { + SEM_ERROR__invalid_op (node, "unary", op); + } else + result = t1->VirtualType (); + } + + node->setTypeRef (result); + return result; +} + + + +/////////////////////////////////////////////////////// +// index expression /////////////////////////////////// +/////////////////////////////////////////////////////// + + + +CTypeInfo *CSemExpr::resolve (CT_IndexExpr *node, CTree *base) { + CTypeInfo *result, *t1, *t2; + unsigned long pos; + int ctp_old; + + result = &CTYPE_UNDEFINED; + + ctp_old = conv_to_ptr; + conv_to_ptr = 1; + + // resolve operands + t1 = resolveExpr (node->Son (0), node); + t2 = resolveExpr (node->Son (2), node); + conv_to_ptr = ctp_old; + pos = node->Son (0)->token_node ()->Number (); + + // array subscripting: op1 [ op2 ] + if (! (isPtrToObj (t1, pos) && t2->isInteger ())) { + SEM_ERROR__invalid_op (node, "array subscript", "[]"); + } else + result = t1->VirtualType ()->BaseType (); + + node->setTypeRef (result); + return result; +} + + + +/////////////////////////////////////////////////////// +// sizeof expression ////////////////////////////////// +/////////////////////////////////////////////////////// + + + +CTypeInfo *CSemExpr::resolve (CT_SizeofExpr *node, CTree *base) { + CTypeInfo *result, *t1, *unqual; + CObjectInfo *info; + U_LONG_LONG size; + + result = CTypeInfo::CTYPE_SIZE_T; // size_t + size = 0; + + // resolve operand; can be either expression or named type + if (node->TypeName ()) { // named type + info = node->TypeName ()->Object (); + t1 = info ? info->TypeInfo () : 0; + } else { + // do not convert array/function type to pointer type + conv_to_ptr = 0; + t1 = resolveExpr (node->Expr (), node); + info = findObject (node->Expr ()); + } + + // sizeof op1; sizeof ( op1 ) + if (! t1 || t1->isFunction () || (info && info->TypeInfo ()->TypeBitField ())) { + SEM_ERROR__invalid_op (node, "unary", "sizeof"); + } else { + unqual = t1->UnqualType(); + if (unqual->is_char() || unqual->is_signed_char() || unqual->is_unsigned_char()) { + size = 1; // always 1 byte + } else { + size = t1->Size () / 8; // size in bytes + node->setValue (new CConstant (size, result)); + } + } + + node->setTypeRef (result); + return result; +} + + + +/////////////////////////////////////////////////////// +// alignof expression ////////////////////////////////// +/////////////////////////////////////////////////////// + + + +CTypeInfo *CSemExpr::resolve (CT_AlignofExpr *node, CTree *base) { + CTypeInfo *result, *t1; + CObjectInfo *info; + U_LONG_LONG align; + + result = CTypeInfo::CTYPE_SIZE_T; // size_t + + // resolve operand; can be either expression or named type + if (node->TypeName ()) { // named type + info = node->TypeName ()->Object (); + t1 = info ? info->TypeInfo () : 0; + } else { + // do not convert array/function type to pointer type + conv_to_ptr = 0; + t1 = resolveExpr (node->Expr (), node); + //info = findObject (node->Expr ()); + } + + // alignof op1; alignof ( op1 ) + if (! t1) { + SEM_ERROR__invalid_op (node, "unary", "alignof"); + } else { + align = t1->Align (); // alignment in bytes + if (align) { + node->setValue (new CConstant (align, result)); + } + } + + node->setTypeRef (result); + return result; +} + + + +/////////////////////////////////////////////////////// +// offsetof expression //////////////////////////////// +/////////////////////////////////////////////////////// + + + +CTypeInfo *CSemExpr::resolve (CT_OffsetofExpr *node, CTree *base) { + CTypeInfo *result; + U_LONG_LONG offset; + + // TODO: calculate the offset in bytes of the given member + offset = 0; + result = CTypeInfo::CTYPE_SIZE_T; // size_t + + node->setValue (new CConstant (offset, result)); + node->setTypeRef (result); + return result; +} + + + +/////////////////////////////////////////////////////// +// if-then expression ///////////////////////////////// +/////////////////////////////////////////////////////// + + + +CTypeInfo *CSemExpr::cond_expr_type (CT_IfThenExpr *node, + CTypeInfo *t1, CTree *op1, CTypeInfo *t2, CTree *op2, + CTypeInfo *t3, CTree *op3) { + + bool l; + CConstant *v1; + CTypeInfo *result = &CTYPE_UNDEFINED; + + if (! t1->isScalar ()) { + SEM_ERROR__invalid_op (node, "conditional", "?:"); + } else if ((t2->isVoid () && t3->isVoid ()) || + (t2->isRecord () && t3->isRecord () && compatible (t2, t3))) { + result = t2; + } else if ((t2->isInteger () && t3->isPointer ()) || + (t3->isInteger () && t2->isPointer ())) { + l = t2->isInteger () ? true : false; + v1 = (l?op2:op3)->Value () ? (l?op2:op3)->Value ()->Constant () : 0; + if (! v1 || ! v1->isNull ()) // null pointer constant + SEM_WARNING__type_mismatch (node, "conditional expression"); + result = l?t3:t2; + } else if (t2->isPointer () && t3->isPointer () && + ((t2->VirtualType ()->BaseType ()->isVoid () && + ! t3->VirtualType ()->BaseType ()->isVoid ()) || + (t3->VirtualType ()->BaseType ()->isVoid () && + ! t2->VirtualType ()->BaseType ()->isVoid ()))) { + l = t2->VirtualType ()->BaseType ()->isVoid () ? false : true; + if (t2->isConst () != t3->isConst () || + t2->isVolatile () != t3->isVolatile () || + t2->isRestrict () != t3->isRestrict ()) + result = new CTypeQualified ((l?t3:t2)->VirtualType ()->BaseType ()->Duplicate (), + t2->isConst () || t3->isConst (), + t2->isVolatile () || t3->isVolatile (), + t2->isRestrict () || t3->isRestrict ()); + else + result = (l?t3:t2); + } else if (t2->isPointer () && t3->isPointer ()) { + if (! compatibleBase (t2, t3)) { + SEM_WARNING__type_mismatch (node, "conditional expression"); + result = t2; + } else if (t2->isConst () != t3->isConst () || + t2->isVolatile () != t3->isVolatile () || + t2->isRestrict () != t3->isRestrict ()) { + result = new CTypeQualified (t2->VirtualType ()->BaseType ()->Duplicate (), + t2->isConst () || t3->isConst (), + t2->isVolatile () || t3->isVolatile (), + t2->isRestrict () || t3->isRestrict ()); + } else if (t2->PtrToFct () && t3->PtrToFct ()) { + result = t2->PtrToFct ()->ArgTypes ()->Entries () ? t2 : t3; + } else { + result = t2; + } + } else if (t2->isArithmetic () && t3->isArithmetic ()) { + result = t2; + if (*t2 < *t3) { + result = t3; + } + } else + SEM_ERROR__invalid_op (node, "conditional", "?:"); + + return result; +} + +CTypeInfo *CSemExpr::resolve (CT_IfThenExpr *node, CTree *base) { + CTypeInfo *result, *t1, *t2, *t3; + CTree *op1, *op2, *op3; + CConstant *v1; + + conv_to_ptr = 1; + + // resolve operands + t1 = resolveExpr (node->Son (0), node); + t2 = resolveExpr (node->Son (2), node); + t3 = resolveExpr (node->Son (4), node); + op1 = node->Son (0); + op2 = node->Son (2); + op3 = node->Son (4); + + // determine the result type + result = cond_expr_type (node, t1, op1, t2, op2, t3, op3); + + // apply arithmetic conversions if needed + if (t2->isArithmetic () && t3->isArithmetic ()) { + if (*t2 > *t3) { + result = cast_to (t2, op3, node); + op3 = node->Son (4); + } else if (*t2 < *t3) { + result = cast_to (t3, op2, node); + op2 = node->Son (2); + } else + result = t2; + } + + // handle constants + v1 = op1->Value () ? op1->Value ()->Constant () : 0; + if (v1) { + if (v1->isNull ()) { + if (op3->Value ()) + node->setValueRef (op3->Value ()); + } else { + if (op2->Value ()) + node->setValueRef (op2->Value ()); + } + } + + if (!result || result == t2 || result == t3 || *result == CTYPE_UNDEFINED) + node->setTypeRef (result); + else + node->setType (result); + return result; +} + + +/////////////////////////////////////////////////////// +// cast expression //////////////////////////////////// +/////////////////////////////////////////////////////// + + + +CTypeInfo *CSemExpr::resolve (CT_CastExpr *node, CTree *base) { + CTypeInfo *result, *t1, *t2; + CExprValue *value; + + conv_to_ptr = 1; + result = &CTYPE_UNDEFINED; + + // resolve operands + t1 = node->TypeName ()->Object () ? + node->TypeName ()->Object ()->TypeInfo () : 0; + t2 = resolveExpr (node->Expr (), node); + + // cast operator; ( op1 ) op2 + if (t1 && ((t1->isScalar () && t2->isScalar ()) || t1->isVoid ())) { + // cast constant value if any + value = node->Expr ()->Value (); + if (value) { + if (value->Constant () && *t1 != *t2) { + value = value->Constant ()->cast_to (t1); + node->setValue (value); + } else + node->setValueRef (value); + } + result = t1; + // cast to union: ( union ) op2 + } else if (t1 && t1->isUnion ()) { + // as an extension to ISO C, the cast is valid if the + // union has a member with exactly the type of op2 + CUnionInfo* u = t1->VirtualType ()->TypeUnion ()->UnionInfo (); + if (u) { + unsigned n = u->Attributes (); + for (unsigned i = 0; i < n; i++) { + if (*u->Attribute (i)->TypeInfo () == *t2) { + result = t1; + break; + } + } + } + } + + if (result == &CTYPE_UNDEFINED) + SEM_ERROR (node, "invalid cast"); + + node->setTypeRef (result); + return result; +} + + + +/////////////////////////////////////////////////////// +// structure/union member access expression /////////// +/////////////////////////////////////////////////////// + + + +CTypeInfo *CSemExpr::resolve (CT_MembPtrExpr *node, CTree *base) { + CT_SimpleName *member; + CTypeInfo *t1, *t2; + CObjectInfo *info; + CStructure *sinfo; + unsigned long pos; + const char *name; + int ctp_old, oper; + + oper = node->Son (1)->token ()->type (); + pos = node->Son (1)->token_node ()->Number (); + sinfo = 0; + + ctp_old = conv_to_ptr; + conv_to_ptr = 1; + + // don't apply lvalue-to-rvalue conversion + if (oper == TOK_DOT) + conv_to_ptr = 3; + + // resolve operands + t1 = resolveExpr (node->Son (0), node); + conv_to_ptr = ctp_old; + + // op1 -> op2 + if (oper == TOK_PTS) { + if (! (isPtrToObj (t1, pos) && t1->VirtualType ()->BaseType ()->isRecord ())) { + SEM_ERROR__invalid_op (node, "binary", "->"); + } else { + t2 = t1->VirtualType ()->BaseType ()->VirtualType (); + sinfo = t2->TypeRecord ()->Record (); + } + // op1 . op2 + } else { + if (! (t1->isRecord () && t1->isComplete (pos))) { + SEM_ERROR__invalid_op (node, "binary", "."); + } else { + t2 = t1->VirtualType (); + sinfo = t2->TypeRecord ()->Record (); + } + } + + if (sinfo) { + sinfo = sinfo->DefObject ()->Record (); + member = (CT_SimpleName*)node->Son (2); + name = member->token ()->text (); + info = sinfo->Attribute (name); + if (! info) { + SEM_ERROR (node, (sinfo->ClassInfo () ? "`struct ": "`union ") << + sinfo->Name () << "' has no member named `" << name << "'"); + node->setTypeRef (&CTYPE_UNDEFINED); + } else { + t2 = info->TypeInfo (); + if (t1->TypeQualified () && + (t1->isConst () != t2->isConst () || + t1->isVolatile () != t2->isVolatile () || + t1->isRestrict () != t2->isRestrict ())) + node->setType (new CTypeQualified (t2->VirtualType ()->Duplicate (), + t1->isConst () || t2->isConst (), + t1->isVolatile () || t2->isVolatile (), + t1->isRestrict () || t2->isRestrict ())); + else + node->setTypeRef (t2); + + member->setTypeRef (t2); + member->Object (info); + node->Object (info); + if (t2->isConst ()) { + CTree *init = info->Init (); + if (init && init->Value ()) + member->setValueRef (init->Value ()); + } + } + } else + node->setTypeRef (&CTYPE_UNDEFINED); + + return node->Type (); +} + + + +/////////////////////////////////////////////////////// +// call expression //////////////////////////////////// +/////////////////////////////////////////////////////// + + + +CTypeInfo *CSemExpr::resolve (CT_CallExpr *node, CTree *base) { + CTypeInfo *result, *t1, *ta, *tp; + int pnum, anum, ctp_old; + CTypeFunction *ftype; + CFunctionInfo *finfo; + CTypeList *ptypes; + CT_ExprList *args; + CConstant *v; + CTree *arg; + bool skip; + + result = &CTYPE_UNDEFINED; + args = node->Arguments (); + anum = args->Entries (); + + ctp_old = conv_to_ptr; + conv_to_ptr = 1; + + // resolve operands + t1 = resolveExpr (node->Expr (), node); + // resolve arguments + for (int i = 0; i < anum; i++) + resolveExpr (args->Entry (i), args); + conv_to_ptr = ctp_old; + + // function call: op1 ( op2 , .. ) + if (t1->isPointer () && t1->VirtualType ()->BaseType ()->isFunction ()) { + ftype = t1->VirtualType ()->BaseType ()->VirtualType ()->TypeFunction (); + result = ftype->ReturnType (); + ptypes = ftype->ArgTypes (); + finfo = ftype->FunctionInfo (); + skip = false; + + if (finfo && ptypes) { // should always be true ;-) + node->Object (finfo); + pnum = ptypes->Entries (); + // compare number of arguments and number of parameters + if (ftype->hasPrototype ()) { + if (pnum) { + if (ptypes->Entry (0)->isVoid ()) { + if (anum) + SEM_ERROR__num_args_too (node, "many", anum, finfo); + } else if (anum < (pnum - (ptypes->Entry (pnum-1)->is_ellipsis () ? 1 : 0))) + SEM_ERROR__num_args_too (node, "few", anum, finfo); + } else + skip = true; + } else + skip = true; + + // analyse argument types + for (int i = 0; i < anum; i++) { + arg = args->Entry (i); + ta = arg->Type (); + + // apply the default argument promotions + if (skip || ! ftype->hasPrototype ()) { + ta = promote (arg, args); + if (ta->VirtualType ()->is_float ()) + ta = cast_to (&CTYPE_DOUBLE, arg, args); + } + + // validate argument type + if (! skip) { + // argument excess + if (pnum < i+1) { + SEM_ERROR__num_args_too (node, "many", (i+1), finfo); + skip = true; + continue; + } + tp = ptypes->Entry (i); + // variable number of arguments + if (tp->is_ellipsis ()) { + skip = true; // types of trailing arguments are not checked + continue; + } + + // convert argument type to the unqualified parameter type + v = arg->Value () ? arg->Value ()->Constant () : 0; + if (tp->isScalar ()) { + if (! compatible (tp, ta, v)) + SEM_WARNING__incompatible_arg (arg, i+1, finfo); + if (*tp != *ta) + cast_to (tp->VirtualType (), arg, args); + } else if (tp->isRecord ()) { + if (! compatible (tp, ta, v)) + SEM_ERROR__invalid_arg (arg, i+1, finfo); + } else + SEM_ERROR__invalid_arg (arg, i+1, finfo); + } + } + } + } else if (t1->is_undefined ()) { + // object not resolved, so it is an implicitely + // declared function; the return type defaults + // to int + result = &CTYPE_INT; + } else { + // object could be resolved but is not a function, + SEM_ERROR (node, "called object is not a function"); + } + + node->setTypeRef (result); + return result; +} + + + +/////////////////////////////////////////////////////// +// compound literal /////////////////////////////////// +/////////////////////////////////////////////////////// + + + +CTypeInfo *CSemExpr::resolve (CT_CmpdLiteral *node, CTree *base) { + bool const_init, ctp_old; + CObjectInfo *info; + CExprValue *value; + CTypeInfo *result; + + ctp_old = conv_to_ptr; + conv_to_ptr = 1; + + result = &CTYPE_UNDEFINED; + info = node->TypeName ()->Object (); + if (info) { + result = info->TypeInfo (); + const_init = (! info->Scope ()->insideFunction ()); + resolveInit (info, node->Initializer (), node, const_init); + + // handle constants + value = node->Initializer ()->Value (); + if (value) + node->setValueRef (value); + } + node->setTypeRef (result); + + conv_to_ptr = ctp_old; + + return result; +} + + +/////////////////////////////////////////////////////// +// initializer evaluation ///////////////////////////// +/////////////////////////////////////////////////////// + + +void CSemExpr::resolveInit (CObjectInfo *info, CTree *node, CTree *base, + bool is_const) { + Stack objs; + objs.push (SubObj (info, info->TypeInfo (), 0)); + resolveInit (info, node, base, is_const, objs); +} + +void CSemExpr::resolveInit (CObjectInfo *info, CTree *node, CTree *base, + bool is_const, Stack &objs) { + bool braced, designations; + CObjectInfo *curr, *obj; + CT_DesignatorSeq *ds; + CStructure *sinfo; + unsigned long pos; + const char *name; + CT_ExprList *el; + CTypeInfo *type; + CTree *item, *d; + int items, size; + CConstant *v; + + if (objs.length () == 0) + return; + + // validate type of object to be initialized + curr = obj = info; + type = objs.top ().type; + pos = node->token_node ()->Number (); + if (type->isVarArray () || (! type->isObject (pos) && + ! (type->isArray () && ! type->isComplete () && + type->VirtualType ()->BaseType ()->isObject (pos)))) { + if (type->isFunction ()) { + SEM_WARNING__init (node, info, "function-type"); + } else if (! type->isComplete (pos)) { + SEM_WARNING__init (node, info, "incomplete-type"); + } else { + SEM_WARNING__init (node, info, "variable-sized"); + } + } + + // init_clause: [=] { init_list } + if (node->NodeName () == CT_ExprList::NodeId () && + node->end_token ()->type () == TOK_CLOSE_CURLY) { + el = (CT_ExprList*)node; + el->setTypeRef (type); + designations = false; + + // init_list: init_list_item [, init_list_item]* + items = el->Entries (); + for (int i = 0; i < items; i++) { + item = el->Entry (i); + base = el; + + // init_list_item: designation init_clause + if (item->NodeName () == CT_BinaryExpr::NodeId () && + item->Son (0)->NodeName () == CT_DesignatorSeq::NodeId ()) { + designations = true; + ds = (CT_DesignatorSeq*)item->Son (0); + base = item; + item = item->Son (2); // init_clause + braced = (item->NodeName () == CT_ExprList::NodeId ()); + + curr = obj = info; + while (objs.top ().info != info && objs.length () > 0) + objs.pop (); + if (objs.top ().info != info) { + SEM_WARNING(node, "designators not analyzed"); + return; + } + type = objs.top ().type; + + // designation: [designator]+ = + for (int j = 0; j < ds->Sons (); j++) { + d = ds->Son (j); + if (obj != curr) + curr = obj; + + // designator: . identifier + if (d->Sons () == 2) { + name = d->Son (1)->token ()->text (); + if (! type->isRecord ()) { + SEM_WARNING (d, "`" << curr->Name () + << "' is not a struct or union type object"); + SEM_MSG (d, "and cannot be used to access a member named `" + << name << "'"); + break; + } + sinfo = type->VirtualType ()->TypeRecord ()->Record (); + sinfo = sinfo->DefObject ()->Record (); + obj = sinfo->Attribute (name); + if (! obj) { + SEM_WARNING (d, "`" << name << "' is not a member of `" + << (sinfo->ClassInfo () ? "struct " : "union ") + << sinfo->Name () << "'"); + break; + } + type = obj->TypeInfo (); + objs.push (SubObj (obj, type, 0)); + ((CT_MembDesignator*)d)->setTypeRef (type); + ((CT_SimpleName*)d->Son (1))->setTypeRef (type); + // designator: [ const_expr ] + } else { + resolveExpr (d->Son (1), d); // compute element index + if (! type->isArray ()) { + SEM_WARNING (d, "`" << curr->Name () << "' is not an array type object"); + SEM_MSG (d, "and cannot be initialized like array type objects"); + break; + } + if (! isConstIntExpr (d)) { + SEM_WARNING (d, "element index is not a valid integer constant expression"); + break; + } + v = d->Son (1)->Value ()->Constant (); + if (v->isNegative ()) { + SEM_WARNING (d, "negative element index"); + break; + } + size = v->convert_to_uint () + 1; + if (objs.top ().size < size) + objs.top ().size = size; + if (type->isFixedArray () && type->Dimension () < size) { + SEM_WARNING (d, "element index out of range for fixed-size array `" + << curr->Name () << "'"); + break; + } else if (! type->isFixedArray () && type->Dimension () < size) { + type->VirtualType ()->TypeArray ()->Dimension (size); + } + pushSubObj (type, obj, objs); + ((CT_IndexDesignator*)d)->setTypeRef (type); + } + } + ds->setTypeRef (ds->Son (ds->Sons () - 1)->Type ()); + base->SemValue ()->setTypeRef (ds->Type ()); + // init_list_item: init_clause + } else { + braced = (item->NodeName () == CT_ExprList::NodeId ()); + if (! designations && braced) { + while (objs.top ().info != info) + objs.pop (); + type = objs.top ().type; + curr = obj = info; + } + } + + // initialize first member + if (i == 0) + findFirst (item, type, curr, obj, info, objs, braced); + // initialize next member + else + findNext (item, type, curr, obj, info, objs, braced); + + // initialize subobject + resolveInit (obj, item, base, is_const, objs); + } + + if (el->Type ()->isScalar () && el->Entry (0)->Value ()) + el->setValueRef (el->Entry (0)->Value ()); + // = ass_expr + } else if (node->NodeName () == CT_ExprList::NodeId ()) { + singleExprInit (node->Son (1), node, type, is_const); + node->SemValue ()->setTypeRef (type); + if (node->Son (1)->Value ()) + node->SemValue ()->setValueRef (node->Son (1)->Value ()); + // init_clause: ass_expr + } else + singleExprInit (node, base, type, is_const); +} + +void CSemExpr::findFirst (CTree *item, CTypeInfo *&type, CObjectInfo *&curr, + CObjectInfo *&obj, CObjectInfo *info, Stack &objs, bool braced) const { + CStructure *sinfo; + int pos, size; + unsigned num; + + if (objs.length () == 0) + return; + + if (type->isScalar ()) { + if (braced) { + size = objs.top ().size; + //SEM_WARNING (item, "too many braces around scalar initializer"); + } else + size = ++objs.top ().size; + //if (size > 1) + // SEM_WARNING (item, "too many elements in scalar initializer"); + return; + } else if (type->isArray ()) { + if ((type->VirtualType ()->BaseType ()->VirtualType ()->is_char () && + (braced?item->Son (1):item)->NodeName () == CT_String::NodeId ()) || + (type->VirtualType ()->BaseType ()->VirtualType ()->is_wchar_t () && + (braced?item->Son (1):item)->NodeName () == CT_WideString::NodeId ())) { + //if (braced) + // SEM_WARNING (item, "too many braces around initializer-string"); + return; + } else { + size = ++objs.top ().size; + if (type->isFixedArray () && type->Dimension () < size) { + //SEM_WARNING (item, "too many elements in fixed-size array initializer"); + } else if (! type->isFixedArray () && type->Dimension () < size) + type->VirtualType ()->TypeArray ()->Dimension (size); + pushSubObj (type, obj, objs); + } + if (braced) + return; + } else if (type->isRecord ()) { + // unnamed union members are not initialized + if (type->isUnion ()) { + pos = -1; + sinfo = type->VirtualType ()->TypeUnion ()->UnionInfo ()->DefObject (); + num = sinfo->Attributes (); + for (unsigned i = 0; i < num; i++) + if (! sinfo->Attribute (i)->isAnonymous ()) { + pos = i; + break; + } + } else { + pos = 0; + sinfo = type->VirtualType ()->TypeClass ()->ClassInfo ()->DefObject (); + } + if (type->isUnion () ? pos >= 0 : sinfo->Attributes ()) { + curr = obj; + obj = sinfo->Attribute ((unsigned)pos); + type = obj->TypeInfo (); + objs.push (SubObj (obj, type, 0)); + if (braced) + return; + } else { // curr has no members (?) + if (*type->VirtualType () == *info->TypeInfo ()->VirtualType ()) { + //SEM_WARNING (item, "too many elements in record initializer"); + } else { + popSubObj (type, curr, obj, objs); + findNext (item, type, curr, obj, info, objs, braced); + } + return; + } + } else + return; + + findFirst (item, type, curr, obj, info, objs, braced); +} + +void CSemExpr::findNext (CTree *item, CTypeInfo *&otype, CObjectInfo *&curr, + CObjectInfo *&obj, CObjectInfo *info, Stack &objs, bool braced) const { + CObjectInfo *tmp = 0; + CStructure *sinfo; + CTypeInfo *type; + int size; + + if (objs.length () == 0) + return; + + type = objs.top ().type; + if (type->isScalar ()) { + //if (braced) + // SEM_WARNING (item, "too many braces around scalar initializer"); + // TODO: the following line produces masses of warnings even if the code + // is correct -> needs to be fixed + // SEM_WARNING (item, "excess elements in scalar initializer"); + objs.pop (); + } else if (type->isArray ()) { + /*if (braced && + ((type->VirtualType ()->BaseType ()->VirtualType ()->is_char () && + item->Son (1)->NodeName () == CT_String::NodeId ()) || + (type->VirtualType ()->BaseType ()->VirtualType ()->is_wchar_t () && + item->Son (1)->NodeName () == CT_WideString::NodeId ()))) + SEM_WARNING (item, "too many braces around initializer-string");*/ + size = objs.top ().size + 1; + if (type->isFixedArray () && type->Dimension () < size) { + if (*type->VirtualType () == *info->TypeInfo ()->VirtualType ()) { + //SEM_WARNING (item, "too many elements in fixed-size array initializer"); + return; + } else + popSubObj (otype, curr, obj, objs); + } else { + objs.top ().size = size; + if (! type->isFixedArray () && type->Dimension () < size) + type->VirtualType ()->TypeArray ()->Dimension (size); + pushSubObj (type, obj, objs); + otype = objs.top ().type; + if (! braced) + findFirst (item, otype, curr, obj, info, objs, braced); + return; + } + } else if (type->isRecord ()) { + // only the first member of a union is initialized + if (! type->isUnion ()) { + sinfo = type->VirtualType ()->TypeRecord ()->Record (); + sinfo = sinfo->DefObject ()->Record (); + tmp = nextMember (/*obj->Scope ()->Structure ()*/sinfo, obj); + } + if (tmp) { + obj = tmp; + otype = obj->TypeInfo (); + objs.push (SubObj (obj, otype, 0)); + if (! braced) + findFirst (item, otype, curr, obj, info, objs, braced); + return; + } else { // all members of curr initialized + if (*type->VirtualType () == *info->TypeInfo ()->VirtualType ()) { + //SEM_WARNING (item, "too many elements in record initializer"); + return; + } else + popSubObj (otype, curr, obj, objs); + } + } else + return; + + findNext (item, otype, curr, obj, info, objs, braced); +} + +void CSemExpr::singleExprInit (CTree *node, CTree *base, CTypeInfo *type, bool is_const) { + CTypeInfo *t2; + CConstant *v; + + // do not convert a (wide) string constant to pointer to char/wchar_t + if (type->isArray ()) + conv_to_ptr = 2; + else + conv_to_ptr = 1; + + unsigned idx = (base->Sons () > 0) ? base->Sons () - 1 : 0; + for (; idx > 0 && base->Son (idx) != node; idx--); + + t2 = resolveExpr (node, base); + conv_to_ptr = 1; + + // get node, could have been replaced due to implicit conversions + node = base->Son (idx); + + //if (is_const && ! isConstExpr (node)) + // SEM_WARNING (node, "initializer element is not constant"); + + v = node->Value () ? node->Value ()->Constant () : 0; + if (type->isScalar ()) { + if (type->isArithmetic () && t2->isArithmetic ()) { + if (*type != *t2) + cast_to (type->VirtualType (), node, base); + } else if (! compatible (type, t2, v)) { + //SEM_WARNING (node, "invalid initializer"); + } else if (*type != *t2) + cast_to (type->VirtualType (), node, base); + } else if (type->isArray ()) { + t2 = t2->VirtualType (); + if (t2->isArray () && t2->Dimension () && + ((t2->BaseType ()->VirtualType ()->is_char () && + node->NodeName () == CT_String::NodeId ()) || + (t2->BaseType ()->VirtualType ()->is_wchar_t () && + node->NodeName () == CT_WideString::NodeId ()))) { + if (type->isFixedArray ()) { + //if (type->Dimension () < t2->Dimension ()) + // SEM_WARNING (node, "initializer-string for array is too long"); + } else + type->VirtualType ()->TypeArray ()->Dimension (t2->Dimension ()); + } //else + //SEM_WARNING (node, "invalid initializer"); + } else if (type->isRecord ()) { + //if (! compatible (type, t2, v)) + //SEM_WARNING (node, "invalid initializer"); + } //else + //SEM_WARNING (node, "invalid initializer"); +} + +void CSemExpr::popSubObj (CTypeInfo *&type, CObjectInfo *&curr, CObjectInfo *&obj, Stack &objs) const { + obj = objs.top ().info; + type = objs.top ().type; + objs.pop (); + curr = objs.top ().info; +} + +void CSemExpr::pushSubObj (CTypeInfo *&type, CObjectInfo *&obj, Stack &objs) const { + type = type->BaseType (); + if (type->isRecord ()) + obj = type->VirtualType ()->TypeRecord ()->Record ()->DefObject ()->Record (); + objs.push (SubObj (obj, type, 0)); +} + +CObjectInfo *CSemExpr::nextMember (CStructure *info, CObjectInfo *curr) const { + unsigned members = info->Attributes (); + for (unsigned i = 0; i < members; i++) + if (info->Attribute (i) == curr) { + if (i+1 < members) + return info->Attribute (i+1); + break; + } + return (CObjectInfo*)0; +} + + + +/////////////////////////////////////////////////////// +// constant expression //////////////////////////////// +/////////////////////////////////////////////////////// + + + +// integer constant expression +bool CSemExpr::isConstIntExpr (CTree *node) { + if (isConstExpr (node, true)) + if (node->Type () && node->Type ()->isInteger () && + node->Value () && node->Value ()->Constant ()) + return true; + return false; +} + +bool CSemExpr::isConstExpr (CTree *node, bool integer) { + const char *id = node->NodeName (); + int oper; + + if (id == CT_BinaryExpr::NodeId ()) { + oper = node->Son (1)->token ()->type (); + if (oper == TOK_ASSIGN && + node->Son (0)->NodeName () == CT_DesignatorSeq::NodeId ()) + return isConstExpr (node->Son (2), integer); + if (oper == TOK_ASSIGN || oper == TOK_MUL_EQ || oper == TOK_DIV_EQ || + oper == TOK_MOD_EQ || oper == TOK_ADD_EQ || oper == TOK_SUB_EQ || + oper == TOK_RSH_EQ || oper == TOK_LSH_EQ || oper == TOK_AND_EQ || + oper == TOK_XOR_EQ || oper == TOK_IOR_EQ || oper == TOK_COMMA) + return false; + return isConstExpr (node->Son (0), integer) && + isConstExpr (node->Son (2), integer); + } else if (id == CT_PostfixExpr::NodeId ()) { + oper = node->Son (1)->token ()->type (); + if (oper == TOK_DECR || oper == TOK_INCR) + return false; + return isConstExpr (node->Son (0), integer); + } else if (id == CT_UnaryExpr::NodeId ()) { + oper = node->Son (0)->token ()->type (); + if (oper == TOK_DECR || oper == TOK_INCR) + return false; + return isConstExpr (node->Son (1), integer); + } else if (id == CT_QualName::NodeId () || + id == CT_RootQualName::NodeId ()) { + return isConstExpr (((CT_QualName*)node)->Name (), integer); + } else if (id == CT_BracedExpr::NodeId ()) { + return isConstExpr (node->Son (1), integer); + } else if (id == CT_ExprList::NodeId ()) { + int n = ((CT_ExprList*)node)->Entries (); + for (int i = 0; i < n; i++) { + CTree* expr = ((CT_ExprList*)node)->Entry (i); + if (! isConstExpr (expr, integer)) + return false; + } + } else if (id == CT_IfThenExpr::NodeId ()) { + if (isConstIntExpr (node->Son (0))) + return (node->Son (0)->Value ()->Constant ()->isNull () ? + isConstExpr (node->Son (4), integer) : + isConstExpr (node->Son (2), integer)); + return false; + } else if (id == CT_ImplicitCast::NodeId ()) { + return isConstExpr (node->Son (0), integer); + } else if (id == CT_CastExpr::NodeId ()) { + CT_CastExpr *cast = (CT_CastExpr*)node; + return isConstExpr (cast->Expr (), integer); + } else if (id == CT_CmpdLiteral::NodeId ()) { + CT_CmpdLiteral *cmpd_literal = (CT_CmpdLiteral*)node; + return isConstExpr (cmpd_literal->Initializer (), integer); + } else if (id == CT_AddrExpr::NodeId ()) { + CT_AddrExpr *ae = (CT_AddrExpr*)node; + CTypeInfo *type = ae->Type (); + if (integer || ! type->isPointerOrArray ()) + return false; + if (type->isPointer () && type->VirtualType ()->BaseType ()->isFunction ()) + return true; + if (isConstantMembPtr (ae->Expr ())) + return true; + CObjectInfo *info = findObject (ae->Expr (), true); + if (! info || (info->Storage () != CStorage::CLASS_STATIC && + info->Storage () != CStorage::CLASS_THREAD)) + return false; + return info->TypeInfo ()->isArray () || isLvalue (ae->Expr ()); + } else if (id == CT_SimpleName::NodeId ()) { + CT_SimpleName *name = (CT_SimpleName*)node; + CTypeInfo *type = node->Type (); + CObjectInfo *obj = name->Object (); + return ((obj && (obj->EnumeratorInfo () || obj->LabelInfo ())) || + (! integer && (type->PtrToFct () || type->PtrToArray () || + type->isFunction () || type->isArray ()))); + } else if (id == CT_SizeofExpr::NodeId () || + id == CT_AlignofExpr::NodeId () || + id == CT_OffsetofExpr::NodeId ()) { + return true; + } else if (id == CT_Bool::NodeId () || + id == CT_Character::NodeId () || + id == CT_WideCharacter::NodeId () || + id == CT_Integer::NodeId () || + id == CT_Float::NodeId ()) { + return true; + } else if (id == CT_String::NodeId () || + id == CT_WideString::NodeId ()) { + return ! integer; + } else if (id == CT_CallExpr::NodeId ()) { + return node->Value(); // implicit constant expression + } else if (id == CT_MembPtrExpr::NodeId () || + id == CT_MembRefExpr::NodeId ()) { + return isConstExpr (node->Son (0), integer); + } else + return false; + return true; +} + +bool CSemExpr::isConstantMembPtr (CTree *node) { + const char *id = node->NodeName (); + if (id == CT_BracedExpr::NodeId () || + id == CT_DerefExpr::NodeId () || + id == CT_AddrExpr::NodeId ()) { + return isConstantMembPtr (node->Son (1)); + } else if (id == CT_ImplicitCast::NodeId ()) { + return isConstantMembPtr (node->Son (0)); + } else if (id == CT_CastExpr::NodeId ()) { + return isConstantMembPtr (node->Son (3)); + } else if (id == CT_BinaryExpr::NodeId ()) { + int oper = node->Son (1)->token ()->type (); + if (oper == TOK_COMMA) + return isConstantMembPtr (node->Son (2)); + } else if (id == CT_MembPtrExpr::NodeId () || + id == CT_MembRefExpr::NodeId ()) { + if (node->Son(0)->Value()) + return true; + return isConstantMembPtr (node->Son (0)); + } + return false; +} + + + +/////////////////////////////////////////////////////// +// helper ///////////////////////////////////////////// +/////////////////////////////////////////////////////// + + + +bool CSemExpr::compatible (CTypeInfo *t1, CTypeInfo *t2, CConstant* value) { + if (! t1 || ! t2) + return false; + + t1 = t1->VirtualType (); + t2 = t2->VirtualType (); + + if (t1->isArithmetic () && t2->isArithmetic ()) { + // arithmetic types are compatible + return true; + } + if (t1->is_bool () && t2->isScalar ()) { + // boolean and scalar types are compatible + return true; + } + if ((t1->isPointer () && t2->isInteger ()) || + (t1->isInteger () && t2->isPointer ())) { + // pointer and integer types are compatible + return true; + } + if (t1->isPointer () && t2->isPointer ()) { + // null pointer constant is compatible to any pointer + if (value && value->isNull ()) { + return true; + } + // pointer to void is compatible to pointer to char type + if ((t1->BaseType ()->isVoid () && t2->BaseType ()->VirtualType ()->is_char ()) || + (t2->BaseType ()->isVoid () && t1->BaseType ()->VirtualType ()->is_char ())) { + return true; + } + // other pointer types are compatible to pointer to void + if (t1->BaseType ()->isVoid () || t2->BaseType ()->isVoid ()) { + return true; + } + // base types and qualifier have to be compatible + return compatibleBase (t1, t2) && + (t2->isConst () ? t1->isConst () : true) && + (t2->isVolatile () ? t1->isVolatile () : true) && + (t2->isRestrict () ? t1->isRestrict () : true); + } + if (t1->isFunction () && t2->isFunction ()) { + // return type and parameter list have to be compatible + // NO FUNCTION PARAMETER PROMOTION AT THE MOMENT + unsigned nargs1 = t1->TypeFunction ()->ArgTypes ()->Entries (); + unsigned nargs2 = t2->TypeFunction ()->ArgTypes ()->Entries (); + return compatibleBase (t1, t2) && (nargs1 == 0 || nargs2 == 0 || nargs1 == nargs2); + } + if (*t1 == *t2) { + // types are equal + return true; + } + + return false; +} + + +CTypeInfo* CSemExpr::applyImplicitConv (CTree* expr, CTree* base, CTypeInfo* type) { + // conv_to_ptr is 0 if argument of address or sizeof expression + // conv_to_ptr is 2 if initializer of array + // conv_to_ptr is 3 if left operand of assignment, ++, --, or . operator + // conv_to_ptr is 1 otherwise + const char *id = expr->NodeName (); + + // implicit array and function type conversions + if (type->isArray () || type->isFunction ()) { + if (conv_to_ptr > 0 && ! (conv_to_ptr == 2 && + (id == CT_String::NodeId () || id == CT_WideString::NodeId ()))) { + type = type->isArray () ? type->VirtualType ()->BaseType () : type; + type = new CTypePointer (type->Duplicate ()); + cast_to (type, expr, base, false); + conv_to_ptr = 1; + } + // implicit lvalue to rvalue conversions + } else if (conv_to_ptr != 3) { + if (type->isQualified ()) { + type = type->UnqualType ()->Duplicate (); + cast_to (type, expr, base, false); + } + conv_to_ptr = 1; + } else + conv_to_ptr = 1; + + return type; +} + + + +void CSemExpr::passOnConstant (CTree *node, CTree *base, CTypeInfo *t1) { + CTypeInfo *t2; + CConstant *value; + + t2 = node->Type (); + value = node->Value () ? node->Value ()->Constant () : 0; + if (value && base->SemValue ()) { + if (t1 && t2 && *t1 != *t2) { + value = value->cast_to (t1); + base->SemValue ()->setValue (value); + } else + base->SemValue ()->setValueRef (value); + } +} + + + +CTypeInfo *CSemExpr::cast_to (CTypeInfo *type, CTree *node, CTree *base, bool ref) { + CT_ImplicitCast *cast; + CExprValue *value; + + // cast implicitly if types differ + if (*node->Type () != *type) { + cast = new CT_ImplicitCast (node); + if (ref) + cast->setTypeRef (type); // refer to a shared type + else + cast->setType (type); // type is new (to be deleted by this node) + base->ReplaceSon (node, cast); + + // cast constant value if any + value = node->Value (); + if (value) { + if (value->Constant ()) { + value = value->Constant ()->cast_to (type); + cast->setValue (value); + } else + cast->setValueRef (value); + } + } + return type; +} + +bool CSemExpr::isLvalue (CTree *node) { + CObjectInfo *info; + CTypeInfo *type; + const char *id; + + id = node->NodeName (); + type = node->Type (); + if (type->isUndefined () || type->isVoid () || type->isFunction () || type->isArray ()) + return false; + if (type->isPointer () && type->VirtualType ()->BaseType ()->isArray ()) { + CTree *tn = node; + while (true) { + if (tn->NodeName () == CT_BracedExpr::NodeId ()) + tn = tn->Son (1); + else if (tn->NodeName () == CT_ImplicitCast::NodeId ()) + return false; + else + break; + } + } + + if (id == CT_SimpleName::NodeId ()) { + info = ((CT_SimpleName*)node)->Object (); + if (info) { + if (info->ArgumentInfo ()) + return true; + if (info->EnumeratorInfo ()) + return false; + type = info->TypeInfo (); + return type && ! type->isFunction (); + } + } else if (id == CT_QualName::NodeId () || id == CT_RootQualName::NodeId ()) { + return isLvalue (((CT_QualName*)node)->Name ()); + } else if (id == CT_BracedExpr::NodeId ()) { + return isLvalue (node->Son (1)); + } else if (id == CT_MembRefExpr::NodeId ()) { + return isLvalue (node->Son (0)); + } else if (id == CT_BinaryExpr::NodeId ()) { + int oper = node->Son (1)->token ()->type (); + if (oper == TOK_ASSIGN || oper == TOK_MUL_EQ || oper == TOK_DIV_EQ || + oper == TOK_MOD_EQ || oper == TOK_ADD_EQ || oper == TOK_SUB_EQ || + oper == TOK_RSH_EQ || oper == TOK_LSH_EQ || oper == TOK_AND_EQ || + oper == TOK_XOR_EQ || oper == TOK_IOR_EQ || oper == TOK_COMMA) + return false; + } else if (id == CT_DerefExpr::NodeId ()) { + unsigned long pos = node->token_node ()->Number (); + if (node->Type ()->isObject (pos)) + return true; + } else if (id == CT_String::NodeId () || + id == CT_WideString::NodeId () || + id == CT_MembPtrExpr::NodeId () || + id == CT_CmpdLiteral::NodeId () || + id == CT_IndexExpr::NodeId ()) { + return true; +// } else if (id == CT_AddrExpr::NodeId () || +// id == CT_CastExpr::NodeId () || +// id == CT_IfThenExpr::NodeId () || +// id == CT_SizeofExpr::NodeId () || +// id == CT_AlignofExpr::NodeId () || +// id == CT_OffsetofExpr::NodeId () || +// id == CT_Integer::NodeId () || +// id == CT_Character::NodeId () || +// id == CT_WideCharacter::NodeId () || +// id == CT_Float::NodeId () || +// id == CT_Bool::NodeId () || +// id == CT_CallExpr::NodeId ()) { +// return false; + } else if (id == CT_ImplicitCast::NodeId ()) { + return isLvalue (node->Son (0)); + } + return false; +} + +CObjectInfo *CSemExpr::findObject (CTree *node, bool const_expr) { + const char *id = node->NodeName (); + if (id == CT_BracedExpr::NodeId () || + id == CT_DerefExpr::NodeId () || + id == CT_AddrExpr::NodeId () || + id == CT_UnaryExpr::NodeId ()) { + return findObject (node->Son (1), const_expr); + } else if (id == CT_ImplicitCast::NodeId () || + id == CT_PostfixExpr::NodeId () || + id == CT_IndexExpr::NodeId ()) { + return findObject (node->Son (0), const_expr); + } else if (id == CT_CastExpr::NodeId ()) { + return findObject (node->Son (3), const_expr); + } else if (id == CT_BinaryExpr::NodeId ()) { + int oper = node->Son (1)->token ()->type (); + if (oper == TOK_COMMA) + return findObject (node->Son (2), const_expr); + if (oper == TOK_ASSIGN || oper == TOK_MUL_EQ || oper == TOK_DIV_EQ || + oper == TOK_MOD_EQ || oper == TOK_ADD_EQ || oper == TOK_SUB_EQ || + oper == TOK_RSH_EQ || oper == TOK_LSH_EQ || oper == TOK_AND_EQ || + oper == TOK_XOR_EQ || oper == TOK_IOR_EQ) + return findObject (node->Son (0), const_expr); + } else if (id == CT_QualName::NodeId () || + id == CT_RootQualName::NodeId ()) { + return findObject (((CT_QualName*)node)->Name (), const_expr); + } else if (id == CT_SimpleName::NodeId () || + id == CT_PrivateName::NodeId ()) { + return ((CT_SimpleName*)node)->Object (); + } else if (id == CT_MembPtrExpr::NodeId ()) { + return ((CT_MembPtrExpr*)node)->Object (); + } else if (id == CT_MembRefExpr::NodeId ()) { + if (const_expr) + return findObject (node->Son (0), const_expr); + return ((CT_MembPtrExpr*)node)->Object (); + } else if (id == CT_CallExpr::NodeId ()) { + return ((CT_CallExpr*)node)->Object (); + } + return (CObjectInfo*)0; +} + +// apply integer promotions if needed +CTypeInfo *CSemExpr::promote (CTree *expr, CTree *base) { + CT_ImplicitCast *cast; + CExprValue *v; + CTypeInfo *t; + + t = expr->Type ()->VirtualType (); + if (! t->isInteger () || (t->conv_rank () >= CTYPE_INT.conv_rank ())) + return t; + + // apply integer promotions + if (! t->is_unsigned_int () && ! t->is_int ()) { + t = &CTYPE_INT; + v = expr->Value (); + cast = new CT_ImplicitCast (expr); + if (v && v->Constant ()) + cast->setValue (v->Constant ()->cast_to (t)); + cast->setTypeRef (t); + base->ReplaceSon (expr, cast); + } + return t; +} + +int CSemExpr::scan_character (CTree *node, LONG_LONG &v) const { + const char *s; + const char *t; + LONG_LONG ch; + int i, j; + int wid = 8; + bool ucs; + + s = node->Son (0)->token ()->text (); + if (*s == 'L') { + wid = MB_LEN_MAX; + s++; + } + + i = strlen (s); + if (s[0] == '\'') { + s++; + i--; + if (s[i-1] == '\'') + i--; + } + t = &s[i]; + + v = 0; + for (j = 0; j < 4; j++) { + ch = next_character (s, ucs); + if (ucs && i == (LONG_LONG)-1) { + SEM_ERROR (node, "incomplete universal character"); + break; + } + if ((wid == 8 && ch > UCHAR_MAX) || + (wid == MB_LEN_MAX && ch > ULONG_MAX)) + SEM_WARNING__out_of_range (node, "escape sequence"); + v = (v << wid) | ch; + if (s == NULL || *s == 0 || s == t) + break; + } + + return j + 1; +} + +LONG_LONG CSemExpr::next_character (const char *&s, bool &ucs) const { + LONG_LONG ch, v; + + ucs = false; + ch = *s++; + if (ch == '\\') { + ch = *s++; + if (ch >= '0' && ch <= '7') { + v = ch - '0'; + if (*s >= '0' && *s <= '7') { + v = (v<<3) + *s++ - '0'; + if (*s >= '0' && *s <= '7') + v = (v<<3) + *s++ - '0'; + } + ch = v; + } else if (ch == 'x') { + v = 0; + while (true) { + if (isdigit (*s)) + v = (v<<4) + *s++ - '0'; + else if (*s >= 'a' && *s <= 'f') + v = (v<<4) + *s++ - 'a' + 10; + else if (*s >= 'A' && *s <= 'F') + v = (v<<4) + *s++ - 'A' + 10; + else + break; + } + ch = v; + } else if (ch == 'u' || ch == 'U') { + ucs = true; + ch = utf8_scan (s, ch == 'U'); + } else { + switch (ch) { + case 'n': ch = '\n'; break; + case 'b': ch = '\b'; break; + case 'r': ch = '\r'; break; + case 't': ch = '\t'; break; + case 'f': ch = '\f'; break; + case 'v': ch = '\v'; break; + case 'a': ch = '\a'; break; + default : break; + } + } + } + return ch; +} + +void CSemExpr::overflow (CTree *node, int base, bool &uns) const { + if (base == 10) + SEM_WARNING__is_unsigned (node); + uns = true; +} + + +/////////////////////////////////////////////////////// +// name lookup //////////////////////////////////////// +/////////////////////////////////////////////////////// + + +CObjectInfo *CSemExpr::lookup (CT_SimpleName *id, SemObjType type, + bool nested) const { + return lookup (id->Text (), current_scope, type, nested, + id->Sons () ? ((CT_Token*)id->Son (0))->Number () : 0); +} + + +CObjectInfo *CSemExpr::lookup (const char *id, CStructure *scope, + SemObjType type, bool nested, unsigned long int pos) const { + CObjectInfo *result = (CObjectInfo*)0; + switch (type) { + case CLASS: + case UNION: + case ENUM: + case TYPEDEF: + case TAG: + result = Type (id, scope, type, pos); + break; + case FCT: + result = Function (id, scope, pos); + break; + case ATTRIB: + result = Attribute (id, scope, pos); + break; + case ARG: + if (scope->FunctionInfo ()) + result = scope->FunctionInfo ()->Argument (id); + if (result && ! known_here (result, pos)) + result = (CObjectInfo*)0; + break; + case NON_TAG: + { + CStructure::ObjectsByName::iterator objs = scope->ObjectInfoMap().find(id); + if (objs != scope->ObjectInfoMap().end()) { + CStructure::ObjectInfoList::reverse_iterator obj = objs->second.rbegin(); + for (; obj != objs->second.rend(); ++obj) { + result = *obj; + if (! result->Record () && ! result->EnumInfo () && known_here (result, pos)) + break; + result = (CObjectInfo*)0; + } + } + } + break; + case ANY: + break; + } + + if (nested && ! result && scope != scope->Parent ()) + return lookup (id, scope->Parent ()->Structure (), type, nested, pos); + return result; +} + +CObjectInfo *CSemExpr::Type (const char *id, CStructure *scope, + SemObjType type, unsigned long int pos) const { + CObjectInfo *result; + for (unsigned i = scope->Types (); i > 0; i--) { + result = scope->Type (i-1); + // correct type? + if ((type == CLASS && ! result->ClassInfo ()) || + (type == UNION && ! result->UnionInfo ()) || + (type == ENUM && ! result->EnumInfo ()) || + (type == TYPEDEF && ! result->TypedefInfo ()) || + (type == TAG && result->TypedefInfo ())) + continue; + // correct name? + if (strcmp (result->Name (), id) != 0) + continue; + // correct declaration? + if (! known_here (result, pos)) + continue; + return result; + } + return (CObjectInfo*)0; +} + +CObjectInfo *CSemExpr::Attribute (const char *id, CStructure *scope, + unsigned long int pos) const { + CObjectInfo *result; + for (unsigned i = scope->Attributes (); i > 0; i--) { + result = scope->Attribute (i-1); + // correct name? + if (strcmp (result->Name (), id) != 0) + continue; + // correct declaration? + if (! known_here (result, pos)) + continue; + return result; + } + return (CObjectInfo*)0; +} + +CObjectInfo *CSemExpr::Function (const char *id, CStructure *scope, + unsigned long int pos) const { + CObjectInfo *result; + for (unsigned i = scope->Functions (); i > 0; i--) { + result = scope->Function (i-1); + // correct name? + if (strcmp (result->Name (), id) != 0) + continue; + // correct declaration? + if (! known_here (result, pos)) + continue; + return result; + } + return (CObjectInfo*)0; +} + +bool CSemExpr::known_here (CObjectInfo *info, unsigned long int pos) const { + if (pos && + info->Tree () && + info->Tree ()->token_node () && + info->Tree ()->token_node ()->Number () > pos) + return false; + return true; +} + + + +} // namespace Puma diff --git a/Puma/src/parser/cparser/CSemExpr.h b/Puma/src/parser/cparser/CSemExpr.h new file mode 100644 index 0000000..da58bc3 --- /dev/null +++ b/Puma/src/parser/cparser/CSemExpr.h @@ -0,0 +1,178 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CSemExpr_h__ +#define __CSemExpr_h__ + +#include "Puma/CTypeInfo.h" +#include "Puma/ErrorSink.h" +#include "Puma/Limits.h" +#include "Puma/Config.h" +#include "Puma/Stack.h" +#include "Puma/CTree.h" + +namespace Puma { + +class CStructure; +class CObjectInfo; + + +class CSemExpr { +protected: + ErrorSink &err; // error stream + CStructure *current_scope; + +protected: // expression evaluation + int conv_to_ptr; // convert array/function type to pointer type + + enum SemObjType { + CLASS, UNION, ENUM, + TYPEDEF, FCT, + ATTRIB, ARG, + TAG, NON_TAG, + ANY + }; + +public: // public interface + CSemExpr (ErrorSink &, CStructure *scope); + + CTypeInfo *resolveExpr (CTree *expr, CTree *base = (CTree*)0); + void resolveInit (CObjectInfo *, CTree *, CTree *, bool = false); + +public: + CTypeInfo *resolve (CTree *, CTree *); + CTypeInfo *resolve (CT_SimpleName *, CTree *); + CTypeInfo *resolve (CT_String *, CTree *); + CTypeInfo *resolve (CT_WideString *, CTree *); + CTypeInfo *resolve (CT_CmpdLiteral *, CTree *); + CTypeInfo *resolve (CT_Bool *, CTree *); + CTypeInfo *resolve (CT_Character *, CTree *); + CTypeInfo *resolve (CT_WideCharacter *, CTree *); + CTypeInfo *resolve (CT_Integer *, CTree *); + CTypeInfo *resolve (CT_Float *, CTree *); + CTypeInfo *resolve (CT_BracedExpr *, CTree *); + CTypeInfo *resolve (CT_BinaryExpr *, CTree *); + CTypeInfo *resolve (CT_UnaryExpr *, CTree *); + CTypeInfo *resolve (CT_AddrExpr *, CTree *); + CTypeInfo *resolve (CT_DerefExpr *, CTree *); + CTypeInfo *resolve (CT_PostfixExpr *, CTree *); + CTypeInfo *resolve (CT_IndexExpr *, CTree *); + CTypeInfo *resolve (CT_SizeofExpr *, CTree *); + CTypeInfo *resolve (CT_AlignofExpr *, CTree *); + CTypeInfo *resolve (CT_OffsetofExpr *, CTree *); + CTypeInfo *resolve (CT_IfThenExpr *, CTree *); + CTypeInfo *resolve (CT_CastExpr *, CTree *); + CTypeInfo *resolve (CT_CallExpr *, CTree *); + CTypeInfo *resolve (CT_MembPtrExpr *, CTree *); + + // binary expressions + CTypeInfo *binary_rel (CT_BinaryExpr *); + CTypeInfo *binary_ass (CT_BinaryExpr *); + CTypeInfo *binary_log (CT_BinaryExpr *); + CTypeInfo *binary_and (CT_BinaryExpr *); + CTypeInfo *binary_equ (CT_BinaryExpr *); + CTypeInfo *binary_mul (CT_BinaryExpr *); + CTypeInfo *binary_add (CT_BinaryExpr *); + CTypeInfo *binary_shift (CT_BinaryExpr *); + CTypeInfo *binary_comma (CT_BinaryExpr *); + CTypeInfo *apply_binary_op (CTree *, int); + + // constant expression + static bool isConstExpr (CTree *, bool = false); + static bool isConstIntExpr (CTree *); + static bool isConstantMembPtr (CTree *node); + + // helper + static bool isLvalue (CTree *); + CTypeInfo* applyImplicitConv (CTree* expr, CTree* base, CTypeInfo* type); + void overflow (CTree *, int, bool &) const; + int scan_character (CTree *, LONG_LONG &) const; + LONG_LONG next_character (const char *&, bool &) const; + static void passOnConstant (CTree *node, CTree *base, CTypeInfo *t1); + static CTypeInfo *cast_to (CTypeInfo *, CTree *, CTree *, bool = true); + static CTypeInfo *promote (CTree *, CTree *); + static CObjectInfo *findObject (CTree *, bool const_expr = false); + CTypeInfo *cond_expr_type (CT_IfThenExpr *node, + CTypeInfo *t1, CTree *op1, CTypeInfo *t2, CTree *op2, + CTypeInfo *t3, CTree *op3); + +protected: // initializer evaluation + struct SubObj { + CObjectInfo *info; + CTypeInfo *type; + int size; + + SubObj () + { info = 0; type = 0; size = 0; } + SubObj (CObjectInfo *i, CTypeInfo *t, int s) + { info = i; type = t; size = s; } + SubObj &operator =(const SubObj& s) + { info = s.info; type = s.type; size = s.size; return *this; } + }; + + void resolveInit (CObjectInfo *, CTree *, CTree *, bool, Stack &); + void singleExprInit (CTree *, CTree *, CTypeInfo *, bool); + void findFirst (CTree *, CTypeInfo *&, CObjectInfo *&, CObjectInfo *&, + CObjectInfo *, Stack &, bool) const; + void findNext (CTree *, CTypeInfo *&, CObjectInfo *&, CObjectInfo *&, + CObjectInfo *, Stack &, bool) const; + + // helper + void pushSubObj (CTypeInfo *&, CObjectInfo *&, Stack &) const; + void popSubObj (CTypeInfo *&, CObjectInfo *&, CObjectInfo *&, + Stack &) const; + CObjectInfo *nextMember (CStructure *, CObjectInfo *) const; + +protected: // name lookup + CObjectInfo *lookup (CT_SimpleName *, SemObjType, bool = false) const; + CObjectInfo *lookup (const char *, CStructure *, SemObjType, bool, + unsigned long int) const; + + // helper + CObjectInfo *Type (const char *, CStructure *, SemObjType, unsigned long int) const; + CObjectInfo *Attribute (const char *, CStructure *, unsigned long int) const; + CObjectInfo *Function (const char *, CStructure *, unsigned long int) const; + bool known_here (CObjectInfo *, unsigned long int) const; + +public: // common helper, also for CSemVisitor + static bool isPtrToObj (CTypeInfo *, unsigned long = 0); + static bool isModifiable (CTypeInfo *, unsigned long = 0); + static bool compatible (CTypeInfo *, CTypeInfo *, CConstant* value = 0); + static bool compatibleBase (CTypeInfo *, CTypeInfo *, CConstant* value = 0); +}; + +inline CSemExpr::CSemExpr (ErrorSink &e, CStructure *s) : + err (e), current_scope (s), conv_to_ptr (1) { +} +inline bool CSemExpr::isPtrToObj (CTypeInfo *type, unsigned long pos) { + CTypeInfo* base = type->VirtualType ()->BaseType (); + return type->isPointer () && base && (base->VirtualType ()->is_void () || base->isComplete (pos)); +} +inline bool CSemExpr::isModifiable (CTypeInfo *type, unsigned long pos) { + return ! (! type->isComplete (pos) || type->isArray () || type->isConst () || + (type->isRecord () && type->VirtualType ()->TypeRecord ()-> + hasConstMember ())); +} +inline bool CSemExpr::compatibleBase (CTypeInfo *t1, CTypeInfo *t2, CConstant* value) { + return compatible (t1->VirtualType ()->BaseType (), t2->VirtualType ()->BaseType (), value); +} + + +} // namespace Puma + +#endif /* __CSemExpr_h__ */ diff --git a/Puma/src/parser/cparser/CSemVisitor.cc b/Puma/src/parser/cparser/CSemVisitor.cc new file mode 100644 index 0000000..844e9ad --- /dev/null +++ b/Puma/src/parser/cparser/CSemVisitor.cc @@ -0,0 +1,547 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CAttributeInfo.h" +#include "Puma/CFunctionInfo.h" +#include "Puma/CArgumentInfo.h" +#include "Puma/CTypedefInfo.h" +#include "Puma/CWStrLiteral.h" +#include "Puma/CStrLiteral.h" +#include "Puma/CObjectInfo.h" +#include "Puma/CSemVisitor.h" +#include "Puma/CLocalScope.h" +#include "Puma/CUnionInfo.h" +#include "Puma/CStructure.h" +#include "Puma/CClassInfo.h" +#include "Puma/CScopeInfo.h" +#include "Puma/CEnumInfo.h" +#include "Puma/CFileInfo.h" +#include "Puma/CTypeInfo.h" +#include "Puma/CConstant.h" +#include "Puma/CSemExpr.h" +#include "Puma/Limits.h" +#include "Puma/CTree.h" + +namespace Puma { + + +// print semantic error messages + +#define SEM_MSG(node__,mesg__) \ + err << node__->token ()->location () << mesg__ << endMessage + +#define SEM_ERROR(node__,mesg__) \ + SEM_MSG (node__, sev_error << mesg__) + +#define SEM_WARNING(node__,mesg__) \ + SEM_MSG (node__, sev_warning << mesg__) + + +CSemVisitor::CSemVisitor (ErrorSink &e, CStructure *scope) : err (e) { + current_scope = scope; +} + +CTypeInfo *CSemVisitor::resolveExpr (CTree *expr, CTree *node) const { + CSemExpr cse (err, current_scope); + return cse.resolveExpr (expr, node); +} + +void CSemVisitor::resolveInit (CObjectInfo *info, CTree *expr, + CTree *node) const { + CSemExpr cse (err, current_scope); + cse.resolveInit (info, expr, node); +} + +void CSemVisitor::run (CTree *node, CStructure *scope) { + current_scope = scope; + if (! current_scope && node->NodeName () == CT_Program::NodeId ()) + current_scope = ((CT_Program*)node)->Scope (); + if (current_scope) + visit (node); +} + +void CSemVisitor::pre_visit (CTree *node) { + if (! node) + return; + + const char *id = node->NodeName (); + if (id == CT_Program::NodeId ()) + pre_action ((CT_Program*)node); + else if (id == CT_ArgDeclList::NodeId ()) + pre_action ((CT_ArgDeclList*)node); + else if (id == CT_ArgNameList::NodeId ()) + pre_action ((CT_ArgNameList*)node); + else if (id == CT_ArgDeclSeq::NodeId ()) + pre_action ((CT_ArgDeclSeq*)node); + else if (id == CT_MembList::NodeId ()) + pre_action ((CT_MembList*)node); + else if (id == CT_CmpdStmt::NodeId ()) + pre_action ((CT_CmpdStmt*)node); + else if (id == CT_IfStmt::NodeId ()) + pre_action ((CT_IfStmt*)node); + else if (id == CT_IfElseStmt::NodeId ()) + pre_action ((CT_IfElseStmt*)node); + else if (id == CT_SwitchStmt::NodeId ()) + pre_action ((CT_SwitchStmt*)node); + else if (id == CT_ForStmt::NodeId ()) + pre_action ((CT_ForStmt*)node); + else if (id == CT_WhileStmt::NodeId ()) + pre_action ((CT_WhileStmt*)node); + else if (id == CT_DoStmt::NodeId ()) + pre_action ((CT_DoStmt*)node); + else if (id == CT_ExprStmt::NodeId ()) + pre_action ((CT_ExprStmt*)node); + else if (id == CT_CaseStmt::NodeId ()) + pre_action ((CT_CaseStmt*)node); + else if (id == CT_GotoStmt::NodeId ()) + pre_action ((CT_GotoStmt*)node); + else if (id == CT_ReturnStmt::NodeId ()) + pre_action ((CT_ReturnStmt*)node); + else if (id == CT_InitDeclarator::NodeId ()) + pre_action ((CT_InitDeclarator*)node); + else if (id == CT_ArrayDeclarator::NodeId ()) + pre_action ((CT_ArrayDeclarator*)node); + else if (id == CT_BitFieldDeclarator::NodeId ()) + pre_action ((CT_BitFieldDeclarator*)node); + else if (id == CT_CmpdLiteral::NodeId ()) + pre_action ((CT_CmpdLiteral*)node); + else if (id == CT_ExprList::NodeId ()) + pre_action ((CT_ExprList*)node); +} + +void CSemVisitor::post_visit (CTree *node) { + if (! node) + return; + + const char *id = node->NodeName (); + if (id == CT_Program::NodeId ()) + post_action ((CT_Program*)node); + else if (id == CT_ArgDeclList::NodeId ()) + post_action ((CT_ArgDeclList*)node); + else if (id == CT_ArgNameList::NodeId ()) + post_action ((CT_ArgNameList*)node); + else if (id == CT_ArgDeclSeq::NodeId ()) + post_action ((CT_ArgDeclSeq*)node); + else if (id == CT_MembList::NodeId ()) + post_action ((CT_MembList*)node); + else if (id == CT_CmpdStmt::NodeId ()) + post_action ((CT_CmpdStmt*)node); + else if (id == CT_IfStmt::NodeId ()) + post_action ((CT_IfStmt*)node); + else if (id == CT_IfElseStmt::NodeId ()) + post_action ((CT_IfElseStmt*)node); + else if (id == CT_SwitchStmt::NodeId ()) + post_action ((CT_SwitchStmt*)node); + else if (id == CT_ForStmt::NodeId ()) + post_action ((CT_ForStmt*)node); + else if (id == CT_WhileStmt::NodeId ()) + post_action ((CT_WhileStmt*)node); +} + + + +/////////////////////////////////////////////////////// +// pre_action functions /////////////////////////////// +/////////////////////////////////////////////////////// + + + +void CSemVisitor::pre_action (CT_Program *node) { + current_scope = node->Scope (); +} + +void CSemVisitor::pre_action (CT_ArgDeclList *node) { + current_scope = node->Scope (); +} + +void CSemVisitor::pre_action (CT_ArgNameList *node) { + current_scope = node->Scope (); +} + +void CSemVisitor::pre_action (CT_ArgDeclSeq *node) { + current_scope = node->Scope (); +} + +void CSemVisitor::pre_action (CT_MembList *node) { + current_scope = node->Scope (); +} + +void CSemVisitor::pre_action (CT_CmpdStmt *node) { + current_scope = node->Scope (); +} + +void CSemVisitor::pre_action (CT_IfStmt *node) { + CTypeInfo *type; + CTree *expr; + + current_scope = node->Scope (); + + expr = node->Condition (); + if (expr) { + type = resolveExpr (expr, node); + if (! type->isScalar ()) + SEM_ERROR (node, "controlling expression of `if' statement not scalar"); + } +} + +void CSemVisitor::pre_action (CT_IfElseStmt *node) { + CTypeInfo *type; + CTree *expr; + + current_scope = node->Scope (); + + expr = node->Condition (); + if (expr) { + type = resolveExpr (expr, node); + if (! type->isScalar ()) + SEM_ERROR (node, "controlling expression of `if' statement not scalar"); + } +} + +void CSemVisitor::pre_action (CT_SwitchStmt *node) { + CTypeInfo *type; + CTree *expr; + + current_scope = node->Scope (); + + expr = node->Condition (); + if (expr) { + type = resolveExpr (expr, node); + type = CSemExpr::promote (node->Condition (), node); + if (! type->isInteger ()) + SEM_ERROR (node, + "controlling expression of `switch' statement not an integer"); + } +} + +void CSemVisitor::pre_action (CT_ForStmt *node) { + CTypeInfo *type; + CTree *expr; + + current_scope = node->Scope (); + + expr = node->Condition (); + if (expr) { + type = resolveExpr (expr, node); + if (! type->isScalar ()) + SEM_ERROR (node, "controlling expression of `for' statement not scalar"); + } + expr = node->Expr (); + if (expr) + // there are no further constraints on this expression + resolveExpr (expr, node); +} + +void CSemVisitor::pre_action (CT_WhileStmt *node) { + CTypeInfo *type; + CTree *expr; + + current_scope = node->Scope (); + + expr = node->Condition (); + if (expr) { + type = resolveExpr (expr, node); + if (! type->isScalar ()) + SEM_ERROR (node, "controlling expression of `while' statement not scalar"); + } +} + +void CSemVisitor::pre_action (CT_DoStmt *node) { + CTypeInfo *type; + CTree *expr; + + expr = node->Expr (); + if (expr) { + type = resolveExpr (expr, node); + if (! type->isScalar ()) + SEM_ERROR (node, "controlling expression of `do' statement not scalar"); + } +} + +void CSemVisitor::pre_action (CT_ExprStmt *node) { + if (node->Expr ()) + resolveExpr (node->Expr (), node); + prune (); +} + +void CSemVisitor::pre_action (CT_CaseStmt *node) { + if (node->Expr ()) { + resolveExpr (node->Expr (), node); + if (! CSemExpr::isConstIntExpr (node->Expr ())) + SEM_ERROR (node, "label of `case' statement not a valid integer constant"); + } +} + +void CSemVisitor::pre_action (CT_GotoStmt *node) { + if (! current_scope->LocalScope ()) + SEM_ERROR (node, "`goto' outside of function"); + else + check_goto_label (node->Label ()); +} + +void CSemVisitor::check_goto_label (CTree *tree) { + CFunctionInfo *finfo; + const char *name; + + finfo = current_scope->LocalScope ()->Function (); + if (finfo) { + CT_SimpleName *label = (CT_SimpleName *)tree; + name = label->Text (); + if (! finfo->Label (name)) + SEM_ERROR (label, "label `" << name << "' used but not defined"); + } +} + +void CSemVisitor::pre_action (CT_ReturnStmt *node) { + CFunctionInfo *finfo = 0; + CTypeInfo *t2 = 0, *t1 = 0; + CConstant *v = 0; + CTree *expr = 0; + + if (! current_scope->LocalScope ()) + SEM_ERROR (node, "`return' outside of function"); + else { + finfo = current_scope->LocalScope ()->Function (); + if (finfo) + t1 = finfo->TypeInfo ()->ReturnType (); + else + t1 = &CTYPE_UNDEFINED; + } + + if (node->Expr ()) { + t2 = resolveExpr (node->Expr (), node); + expr = node->Expr (); + if (t1->isVoid ()) + SEM_WARNING (node, "`return' with a value, in function returning void"); + else { + v = expr->Value () ? expr->Value ()->Constant () : 0; + if (t1->isScalar ()) { + if (t1->isArithmetic () && t2->isArithmetic ()) { + if (! CSemExpr::compatible (t1, t2)) + CSemExpr::cast_to (t1, expr, node); + } else if (! (t1->isPointer () && t2->isPointer () && + (CSemExpr::compatibleBase (t1, t2) || + t1->VirtualType ()->BaseType ()->isVoid () || + t2->VirtualType ()->BaseType ()->isVoid ()) && + (t2->isConst () ? t1->isConst () : true) && + (t2->isVolatile () ? t1->isVolatile () : true) && + (t2->isRestrict () ? t1->isRestrict () : true)) && + ! (t1->isPointer () && t2->isInteger () && v && v->isNull ()) && + ! (t1->VirtualType ()->is_bool () && t2->isPointer ())) { + SEM_WARNING (node, "incompatible types in `return' statement"); + } else if (! CSemExpr::compatible (t1, t2)) + CSemExpr::cast_to (t1, expr, node); + } else if (t1->isRecord ()) { + if (! CSemExpr::compatible (t1, t2)) + SEM_WARNING (node, "incompatible types in `return' statement"); + } else + SEM_ERROR (node, "invalid return type"); + } + } else if (! t1->isVoid ()) + SEM_WARNING (node, "`return' with no value, in function returning non-void"); + + prune (); +} + +void CSemVisitor::pre_action (CT_InitDeclarator *node) { + CT_ExprList *init = node->Initializer (); + if (init) { + CObjectInfo* obj = node->Object (); + resolveInit (obj, init, node); + if (obj && obj->isStatic ()) + for (int i = init->Entries () - 1; i >= 0; i--) + if (! CSemExpr::isConstExpr (init->Entry (i))) + SEM_ERROR (node, "initializer is not constant"); + } +} + +void CSemVisitor::pre_action (CT_ArrayDeclarator *node) { + CT_SimpleName *name; + CObjectInfo *info; + const char *array; + CTypeArray *atype; + CTypeInfo *type; + CConstant *v; + CTree *expr; + + name = findName (node); + if (name) { + array = name->Text (); + info = name->Object (); + } else { + array = ""; + info = 0; + } + expr = node->Delimiter ()->Expr (); + + if (expr) { + type = expr->Type (); + if (! type->isInteger ()) + SEM_ERROR (node, "size of array `" << array << "' has non-integer type"); + else if (CSemExpr::isConstIntExpr (expr)) { + v = expr->Value ()->Constant (); + if (/*v->isNull () ||*/ v->isNegative ()) + SEM_ERROR (node, "array `" << array << "' has invalid size"); + } + } + + // check the array size on the top level array declarator only + // to avoid redundant error messages, extern arrays can have + // unspecified dimension + if (info && ! info->isExtern () && + node->Parent ()->NodeName () != CT_ArrayDeclarator::NodeId ()) { + atype = name->Object ()->TypeInfo ()->VirtualType ()->TypeArray (); + if (atype && ! atype->isVarArray ()) { + if (! atype->BaseType ()->isArray () && ! atype->hasDimension ()) { + // assume dimension 1 + SEM_WARNING (node, "array `" << array << "' assumed to have one element"); + atype->Dimension (1); + } else do { + if (! atype->hasDimension ()) { + SEM_ERROR (node, "array size missing in `" << array << "'"); + break; + } + atype = atype->BaseType ()->VirtualType ()->TypeArray (); + } while (atype && ! atype->isVarArray ()); + } + } +} + +void CSemVisitor::pre_action (CT_BitFieldDeclarator *node) { + CObjectInfo *info; + const char *name; + CConstant *v; + CTree *expr; + + expr = node->Expr (); + if (expr) { + resolveExpr (expr, node); + expr = node->Expr (); + info = node->Object (); + name = info ? info->Name ().c_str () : ""; + + if (! CSemExpr::isConstIntExpr (expr)) + SEM_ERROR (node, "width of bit-field `" << name + << "' isn't integer constant expression"); + else { + v = expr->Value ()->Constant (); + if (v->isNegative ()) + SEM_ERROR (node, "negative width in bit-field `" << name << "'"); + else if (info && info->TypeInfo () && info->TypeInfo ()->TypeBitField ()) + info->TypeInfo ()->TypeBitField ()->Dimension (v->convert_to_uint ()); + } + } +} + +void CSemVisitor::pre_action (CT_ExprList *node) { + // do not visit the expression list + // it's evaluated when the init declarator is visited + prune (); +} + +void CSemVisitor::pre_action (CT_CmpdLiteral *node) { + // do not visit the compound literal + // it's evaluated when the init declarator is visited + prune (); +} + + + +/////////////////////////////////////////////////////// +// post_action functions ////////////////////////////// +/////////////////////////////////////////////////////// + + + +void CSemVisitor::post_action (CT_Program *node) { + current_scope = node->Scope (); +} + +void CSemVisitor::post_action (CT_ArgDeclList *node) { + current_scope = node->Scope ()->Parent ()->Structure (); +} + +void CSemVisitor::post_action (CT_ArgNameList *node) { + current_scope = node->Scope ()->Parent ()->Structure (); +} + +void CSemVisitor::post_action (CT_ArgDeclSeq *node) { + current_scope = node->Scope ()->Parent ()->Structure (); +} + +void CSemVisitor::post_action (CT_MembList *node) { + current_scope = node->Scope ()->Parent ()->Structure (); +} + +void CSemVisitor::post_action (CT_CmpdStmt *node) { + current_scope = node->Scope ()->Parent ()->Structure (); +} + +void CSemVisitor::post_action (CT_IfStmt *node) { + current_scope = node->Scope ()->Parent ()->Structure (); +} + +void CSemVisitor::post_action (CT_IfElseStmt *node) { + current_scope = node->Scope ()->Parent ()->Structure (); +} + +void CSemVisitor::post_action (CT_SwitchStmt *node) { + current_scope = node->Scope ()->Parent ()->Structure (); +} + +void CSemVisitor::post_action (CT_ForStmt *node) { + current_scope = node->Scope ()->Parent ()->Structure (); +} + +void CSemVisitor::post_action (CT_WhileStmt *node) { + current_scope = node->Scope ()->Parent ()->Structure (); +} + + + +/////////////////////////////////////////////////////// +// common helper ////////////////////////////////////// +/////////////////////////////////////////////////////// + + + +CT_SimpleName *CSemVisitor::findName (CTree *node) const { + const char *id = node->NodeName (); + if (id == CT_InitDeclarator::NodeId ()) + return findName (((CT_InitDeclarator*)node)->Declarator ()); + else if (id == CT_FctDeclarator::NodeId ()) + return findName (((CT_FctDeclarator*)node)->Declarator ()); + else if (id == CT_ArrayDeclarator::NodeId ()) + return findName (((CT_ArrayDeclarator*)node)->Declarator ()); + else if (id == CT_BracedDeclarator::NodeId ()) + return findName (((CT_BracedDeclarator*)node)->Declarator ()); + else if (id == CT_BitFieldDeclarator::NodeId ()) + return findName (((CT_BitFieldDeclarator*)node)->Declarator ()); + else if (id == CT_RefDeclarator::NodeId ()) + return findName (((CT_RefDeclarator*)node)->Declarator ()); + else if (id == CT_PtrDeclarator::NodeId ()) + return findName (((CT_PtrDeclarator*)node)->Declarator ()); + else if (id == CT_MembPtrDeclarator::NodeId ()) + return findName (((CT_MembPtrDeclarator*)node)->Declarator ()); + else if (id == CT_SimpleName::NodeId () || id == CT_PrivateName::NodeId ()) + return (CT_SimpleName*)node; + return (CT_SimpleName*)0; +} + + +} // namespace Puma diff --git a/Puma/src/parser/cparser/CSemVisitor.h b/Puma/src/parser/cparser/CSemVisitor.h new file mode 100644 index 0000000..b043f9f --- /dev/null +++ b/Puma/src/parser/cparser/CSemVisitor.h @@ -0,0 +1,98 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CSemVisitor_h__ +#define __CSemVisitor_h__ + +#include "Puma/ErrorSink.h" +#include "Puma/CVisitor.h" +#include "Puma/Limits.h" +#include "Puma/Config.h" +#include "Puma/CTree.h" + +namespace Puma { + + +class CStructure; +class CObjectInfo; +class CTypeInfo; + +class CSemVisitor : private CVisitor { +protected: + CStructure *current_scope; + ErrorSink &err; + +public: + CSemVisitor (ErrorSink &, CStructure * = (CStructure*)0); + + void run (CTree *, CStructure * = (CStructure*)0); + void configure (Config &) {} + + CTypeInfo *resolveExpr (CTree *, CTree *) const; + void resolveInit (CObjectInfo *info, CTree *, CTree *) const; + +protected: + void pre_visit (CTree *); + void post_visit (CTree *); + +protected: + void pre_action (CT_Program *); + void pre_action (CT_ArgDeclList *); + void pre_action (CT_ArgNameList *); + void pre_action (CT_ArgDeclSeq *); + void pre_action (CT_MembList *); + void pre_action (CT_CmpdStmt *); + void pre_action (CT_IfStmt *); + void pre_action (CT_IfElseStmt *); + void pre_action (CT_SwitchStmt *); + void pre_action (CT_ForStmt *); + void pre_action (CT_WhileStmt *); + void pre_action (CT_DoStmt *); + void pre_action (CT_ExprStmt *); + void pre_action (CT_CaseStmt *); + void pre_action (CT_GotoStmt *); + void pre_action (CT_ReturnStmt *); + void pre_action (CT_InitDeclarator *); + void pre_action (CT_ArrayDeclarator *); + void pre_action (CT_BitFieldDeclarator *); + void pre_action (CT_ExprList *); + void pre_action (CT_CmpdLiteral *); + +protected: + void post_action (CT_Program *); + void post_action (CT_ArgDeclList *); + void post_action (CT_ArgNameList *); + void post_action (CT_ArgDeclSeq *); + void post_action (CT_MembList *); + void post_action (CT_CmpdStmt *); + void post_action (CT_IfStmt *); + void post_action (CT_IfElseStmt *); + void post_action (CT_SwitchStmt *); + void post_action (CT_ForStmt *); + void post_action (CT_WhileStmt *); + + CT_SimpleName *findName (CTree *) const; + +private: + void check_goto_label (CTree *); + +}; + +} // namespace Puma + +#endif /* __CSemVisitor_h__ */ diff --git a/Puma/src/parser/cparser/CSemantic.cc b/Puma/src/parser/cparser/CSemantic.cc new file mode 100644 index 0000000..ba0e994 --- /dev/null +++ b/Puma/src/parser/cparser/CSemantic.cc @@ -0,0 +1,1703 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CTree.h" +#include "Puma/CUnit.h" +#include "Puma/UnitIterator.h" +#include "Puma/Array.h" +#include "Puma/PtrStack.h" +#include "Puma/ErrorSink.h" +#include "Puma/CSyntax.h" +#include "Puma/CSemantic.h" +#include "Puma/ErrorSeverity.h" +#include "Puma/CSemDeclarator.h" +#include "Puma/CSemDeclSpecs.h" +#include "Puma/CFileInfo.h" +#include "Puma/CEnumInfo.h" +#include "Puma/CTypeInfo.h" +#include "Puma/CClassInfo.h" +#include "Puma/CUnionInfo.h" +#include "Puma/CLabelInfo.h" +#include "Puma/CLocalScope.h" +#include "Puma/CTypedefInfo.h" +#include "Puma/CFunctionInfo.h" +#include "Puma/CArgumentInfo.h" +#include "Puma/CAttributeInfo.h" +#include "Puma/CEnumeratorInfo.h" +#include "Puma/CMemberAliasInfo.h" +#include "Puma/CSemDatabase.h" +#include "Puma/CSemExpr.h" +#include "Puma/CConstant.h" + +#include +#include +#include + +namespace Puma { + + +/*DEBUG*/extern int TRACE_FCT; +/*DEBUG*/extern int TRACE_OBJS; +/*DEBUG*/extern int TRACE_SCOPES; + +// print semantic error messages + +#define SEM_MSG(loc__,mesg__) \ + *_err << loc__->token ()->location () << mesg__ << endMessage + +#define SEM_ERROR(loc__,mesg__) \ + SEM_MSG (loc__, sev_error << mesg__) + +#define SEM_WARNING(loc__,mesg__) \ + SEM_MSG (loc__, sev_warning << mesg__) + +#define SEM_WARNING__implicit_fct(loc__,name__) \ + SEM_MSG (loc__, sev_warning << "implicit declaration of function ‘" \ + << name__ << "'") + +#define SEM_MSG__prev_loc(info__) \ + *_err << info__->SourceInfo ()->StartToken ()->token ()->location () \ + << "previously defined here" << endMessage + +#define SEM_WARNING__redefinition(token__,type__,info__) \ + SEM_WARNING (token__, "redefinition of " << type__ \ + << "`" << info__->Name () << "'"); \ + SEM_MSG__prev_loc(info__) + +#define SEM_ERROR__redefinition(token__,type__,info__) \ + SEM_ERROR (token__, "redefinition of " << type__ \ + << "`" << info__->Name () << "'"); \ + SEM_MSG__prev_loc(info__) + +#define SEM_ERROR__already_defined(token__,info__) \ + SEM_ERROR (token__, "`" << info__->Name () \ + << "' already defined"); \ + SEM_MSG__prev_loc(info__) + +#define SEM_ERROR__conflicting_types(token__,info__) \ + SEM_ERROR (token__, "conflicting types for `" \ + << info__->Name () << "'"); \ + SEM_MSG__prev_loc(info__) + +#define SEM_ERROR__duplicate(token__,type__,name__) \ + SEM_ERROR (token__, "duplicate " << type__ \ + << " `" << name__->Text () << "'") + +#define SEM_ERROR__wrong_storage_class(token__,type__,name__) \ + SEM_ERROR (token__, "wrong storage class specified for " \ + << type__ << " `" << name__->Text () << "'") + +#define SEM_ERROR__static_follows_non_static(token__,info__) \ + SEM_ERROR (token__, "static declaration of `" << info__->Name () \ + << "' follows non-static declaration"); \ + SEM_MSG__prev_loc(info__) + + +void CSemantic::init (CSemDatabase &db, Unit &u) { + Semantic::init (db, u); + if (! _file->haveCBuiltins ()) { + _file->haveCBuiltins (true); + declareImplicitFcts (); + } +} + + +void CSemantic::configure (Config &c) { + Semantic::configure (c); +} + + +void CSemantic::enter_scope (CStructure *scp) { + Semantic::enter_scope(scp); + if (current_scope && ! current_scope->Record()) + non_record_scopes.Push(current_scope); +} + + +void CSemantic::reenter_scope (CStructure *scp) { + Semantic::reenter_scope(scp); + if (current_scope && ! current_scope->Record()) + non_record_scopes.Push(current_scope); +} + + +void CSemantic::leave_scopes () { + CStructure* scope = current_scope; + Semantic::leave_scopes(); + if (scope != current_scope && scope == non_record_scopes.Top()) + non_record_scopes.Pop(); +} + + +CAttributeInfo *CSemantic::createAttribute (const char *name, + CStructure *scope, CTypeInfo *type, bool is_static) { + CAttributeInfo *info; + info = scope->newAttribute (); + info->Name (name); + info->ObjectInfo ()->TypeInfo (type); + info->SourceInfo ()->FileInfo (_file); + info->isStatic (is_static); + Push (info); + return info; +} + + +CTypedefInfo *CSemantic::createTypedef (const char *name, + CStructure *scope, CTypeInfo *type) { + CTypedefInfo *info; + info = scope->newTypedef (); + type = type->TypedefInfo (info); + info->Name (name); + info->ObjectInfo ()->TypeInfo (type); + info->SourceInfo ()->FileInfo (_file); + Push (info); + return info; +} + + +CFunctionInfo *CSemantic::createFunction (const char *name, + CStructure *scope, CTypeInfo *type) { + CFunctionInfo *info; + info = scope->newFunction (); + info->Linkage (CLinkage::LINK_EXTERNAL); + info->Name (name); + info->ObjectInfo ()->TypeInfo (type); + info->SourceInfo ()->FileInfo (_file); + type->VirtualType ()->TypeFunction ()->FunctionInfo (info); + Push (info); + return info; +} + + +void CSemantic::createParameter (CFunctionInfo *finfo, + CTypeInfo *argtype) { + CArgumentInfo *info; + info = finfo->newArgument (); + std::ostringstream name; name << "%anon" << _Anonymous; _Anonymous++; + info->Name (name.str ().c_str ()); + info->Storage (CStorage::CLASS_AUTOMATIC); + info->SourceInfo ()->FileInfo (_file); + info->TypeInfo (argtype->Duplicate ()); + Push (info); +} + + +void CSemantic::Delete () { + CObjectInfo *info = Top (); // get item to delete + if (! info) + return; + + if (info->Id () == CObjectInfo::ATTRIBUTE_INFO) { +#ifndef NDEBUG + /*DEBUG*/if (TRACE_OBJS) std::cerr<<"DELETE: "<<(void*)info<<" (Attribute "<Name()<<")"<Id () == CObjectInfo::MEMBERALIAS_INFO) { +#ifndef NDEBUG + /*DEBUG*/if (TRACE_OBJS) std::cerr<<"DELETE: "<<(void*)info<<" (Member alias "<Name()<<")"<Id () == CObjectInfo::ARGUMENT_INFO) { +#ifndef NDEBUG + /*DEBUG*/if (TRACE_OBJS) std::cerr<<"DELETE: "<<(void*)info<<" (Argument "<Name()<<")"<Id () == CObjectInfo::ENUMERATOR_INFO) { +#ifndef NDEBUG + /*DEBUG*/if (TRACE_OBJS) std::cerr<<"DELETE: "<<(void*)info<<" (Enumerator "<Name()<<")"<Id () == CObjectInfo::LABEL_INFO) { +#ifndef NDEBUG + /*DEBUG*/if (TRACE_OBJS) std::cerr<<"DELETE: "<<(void*)info<<" (Label "<Name()<<")"<Id () == CObjectInfo::TYPEDEF_INFO) { +#ifndef NDEBUG + /*DEBUG*/if (TRACE_OBJS) std::cerr<<"DELETE: "<<(void*)info<<" (Typedef "<Name()<<")"<Id () == CObjectInfo::ENUM_INFO) { +#ifndef NDEBUG + /*DEBUG*/if (TRACE_OBJS) std::cerr<<"DELETE: "<<(void*)info<<" (Enum "<Name()<<")"<Id () == CObjectInfo::LOCAL_INFO) { +#ifndef NDEBUG + /*DEBUG*/if (TRACE_OBJS) std::cerr<<"DELETE: "<<(void*)info<<" (LocalScope "<Name()<<")"<Id () == CObjectInfo::UNION_INFO) { +#ifndef NDEBUG + /*DEBUG*/if (TRACE_OBJS) std::cerr<<"DELETE: "<<(void*)info<<" (Union "<Name()<<")"<Name()<<")"<Id () == CObjectInfo::CLASS_INFO) { +#ifndef NDEBUG + /*DEBUG*/if (TRACE_OBJS) std::cerr<<"DELETE: "<<(void*)info<<" (Class "<Name()<<")"<Name()<<")"<Id () == CObjectInfo::FUNCTION_INFO) { +#ifndef NDEBUG + /*DEBUG*/if (TRACE_OBJS) std::cerr<<"DELETE: "<<(void*)info<<" (Function "<Name()<<")"<Name()<<")"<ScopeInfo () && info->ScopeInfo () == current_scope) { + if (current_scope == non_record_scopes.Top()) + non_record_scopes.Pop(); + CScopeInfo* parent = info->ScopeInfo ()->Parent (); + assert (parent && parent->Structure ()); + current_scope = parent->Structure (); + } + + Semantic::Delete (); +} + + + +/*****************************************************************************/ +/* */ +/* Name lookup */ +/* */ +/*****************************************************************************/ + + + +CObjectInfo *CSemantic::lookup (const char *id, CStructure *scope, SemObjType type, bool nested) const { + CObjectInfo *result = (CObjectInfo*)0; + + if (id && strncmp(id, "%anon", 5) == 0) + return result; + + switch (type) { + case CLASS: + result = scope->Type (id); + if (result && ! result->ClassInfo ()) + result = (CObjectInfo*)0; + break; + case UNION: + result = scope->Type (id); + if (result && ! result->UnionInfo ()) + result = (CObjectInfo*)0; + break; + case ENUM: + result = scope->Type (id); + if (result && ! result->EnumInfo ()) + result = (CObjectInfo*)0; + break; + case FCT: + result = scope->Function (id); + break; + case TYPEDEF: + result = scope->Typedef (id); + break; + case ATTRIB: + result = scope->Attribute (id); + break; + case ARG: + if (scope->FunctionInfo ()) + result = scope->FunctionInfo ()->Argument (id); + break; + case TAG: + result = scope->Type (id); + if (result && ! result->Record () && ! result->EnumInfo ()) { + // if searching for a struct or enum type of a tag (struct X) + // consider also typedefs to find struct or enum types hidden + // by redefining typedefs (typedef struct X X;) + CTypedefInfo* tdef = result->TypedefInfo (); + if (tdef && (tdef->TypeInfo ()->Record () || tdef->TypeInfo ()->EnumInfo ())) { + result = tdef; + } else { + result = (CObjectInfo*)0; + } + } + break; + case NON_TAG: + { + CStructure::ObjectsByName::iterator objs = scope->ObjectInfoMap().find(id); + if (objs != scope->ObjectInfoMap().end()) { + CStructure::ObjectInfoList::reverse_iterator obj = objs->second.rbegin(); + for (; obj != objs->second.rend(); ++obj) { + result = *obj; + if (! result->Record () && ! result->EnumInfo ()) + break; + result = (CObjectInfo*)0; + } + } + } + break; + case ANY: + result = scope->Object (id); + break; + } + + if ((nested || (! scope->FunctionInfo () && + scope->Parent ()->FunctionInfo ())) && + ! result && scope != scope->Parent ()) + return lookup (id, scope->Parent ()->Structure (), type, nested); + else + return result; +} + + + +CObjectInfo* CSemantic::lookupBuiltin (const char* name) const { + CObjectInfo* info = 0; + if (strncmp (name, "__builtin_", 10) == 0) { + info = lookup (name+10, NON_TAG, true); + } + return info; +} + + + +/*****************************************************************************/ +/* */ +/* Linkage and storage class determination */ +/* */ +/*****************************************************************************/ + + + +CLinkage::Type CSemantic::determine_linkage (CSemDeclSpecs *dss, + SemObjType type, CObjectInfo *prev_decl) const { + bool extern_fct = false; + if (type == ATTRIB || type == FCT) { + if (type == ATTRIB) { + if (current_scope->FileInfo ()) { + if (dss->declared (CT_PrimDeclSpec::PDS_STATIC)) + return CLinkage::LINK_INTERNAL; + if (! dss->declared (CT_PrimDeclSpec::PDS_STATIC) && + ! dss->declared (CT_PrimDeclSpec::PDS_EXTERN) && + ! dss->declared (CT_PrimDeclSpec::PDS_AUTO) && + ! dss->declared (CT_PrimDeclSpec::PDS_REGISTER)) + return CLinkage::LINK_EXTERNAL; + } else if (current_scope->LocalScope ()) { + if (! dss->declared (CT_PrimDeclSpec::PDS_EXTERN)) + return CLinkage::LINK_NONE; + } + } else if (type == FCT) { + if (current_scope->FileInfo ()) + if (dss->declared (CT_PrimDeclSpec::PDS_STATIC)) + return CLinkage::LINK_INTERNAL; + if (! dss->declared (CT_PrimDeclSpec::PDS_STATIC) && + ! dss->declared (CT_PrimDeclSpec::PDS_EXTERN) && + ! dss->declared (CT_PrimDeclSpec::PDS_AUTO) && + ! dss->declared (CT_PrimDeclSpec::PDS_REGISTER)) + extern_fct = true; + } + if (extern_fct || dss->declared (CT_PrimDeclSpec::PDS_EXTERN)) { + if (prev_decl && (prev_decl->Linkage () == CLinkage::LINK_INTERNAL || + prev_decl->Linkage () == CLinkage::LINK_EXTERNAL)) + return prev_decl->Linkage (); + else + return CLinkage::LINK_EXTERNAL; + } + } + return CLinkage::LINK_NONE; +} + + + +CStorage::Type CSemantic::determine_storage_class (CSemDeclSpecs *dss, + SemObjType type, CLinkage::Type linkage) const { + if (type == ATTRIB) { + bool def_static = dss->declared (CT_PrimDeclSpec::PDS_STATIC); + bool def_thread = dss->declared (CT_PrimDeclSpec::PDS_THREAD); + if (linkage == CLinkage::LINK_EXTERNAL || + linkage == CLinkage::LINK_INTERNAL || def_static) { + return def_thread ? CStorage::CLASS_THREAD : CStorage::CLASS_STATIC; + } else if (linkage == CLinkage::LINK_NONE) { + if (! def_static) + return CStorage::CLASS_AUTOMATIC; + } + } + return CStorage::CLASS_NONE; +} + + + +/*****************************************************************************/ +/* */ +/* Node analysis */ +/* */ +/*****************************************************************************/ + + + +CTree *CSemantic::typedef_name () { + CObjectInfo *info; + info = lookup (builder ().get_node ()->token ()->text (), NON_TAG, true); + if (info && info->TypedefInfo ()) { + CT_SimpleName *result = (CT_SimpleName*)builder ().simple_name (); + result->Object (info); + result->setTypeRef (info->TypeInfo ()); + return result; + } else + return (CTree*)0; +} + + + +CTree *CSemantic::id_expr () { + CT_SimpleName *result = 0; + const char* name = builder ().get_node ()->token ()->text (); + CObjectInfo *info = lookup (name, NON_TAG, true); + if (! info) + info = lookupBuiltin (name); + if (info && ! info->TypedefInfo ()) { + result = (CT_SimpleName*)builder ().simple_name (); + result->Object (info); + result->setTypeRef (info->TypeInfo ()); + } else if (syntax ().look_ahead () == TOK_OPEN_ROUND) { + // call to undeclared function + result = (CT_SimpleName*)builder ().simple_name (); + SEM_WARNING__implicit_fct (result, name); + } + return result; +} + + + +CTree *CSemantic::introduce_object (CTree* tree) { + bool is_typedef, is_fct, is_attr; + CObjectInfo *info, *prev; + CT_InitDeclarator *id; + CSemDeclSpecs *dsi; + CTypeInfo *type; + + if (! in_decl ()) + return (CTree*)0; + + id = (CT_InitDeclarator*) (tree ? tree : builder ().init_declarator1 ()); + dsi = sem_decl_specs (); + CSemDeclarator csd (_err, dsi->make_type (), id); + if (! csd.Name ()) { + builder ().destroyNode (id); + return (CTree*)0; + } + + type = csd.Type (); + is_typedef = dsi->declared (CT_PrimDeclSpec::PDS_TYPEDEF); + is_fct = (! is_typedef && type->isFunction () && ! type->isAddress ()); + is_attr = ! (is_typedef || is_fct); + + prev = lookup (csd.Name ()->Text (), NON_TAG, false); + if (prev) { + bool error = true; + if ((is_typedef && ! prev->TypedefInfo ()) || + (is_attr && ! prev->AttributeInfo ()) || + (is_fct && ! prev->FunctionInfo ())) { + SEM_ERROR__already_defined (id, prev); + } else if (! typeMatch (type, prev->TypeInfo ())) { + SEM_ERROR__conflicting_types (id, prev); + } else if (is_typedef) { + // for compatibility only issue a warning + SEM_WARNING__redefinition (id, "typedef ", prev); + id->Object (prev); + return id; + } else if (is_attr && (prev->Linkage () == CLinkage::LINK_NONE || + determine_linkage (dsi, ATTRIB, prev) == CLinkage::LINK_NONE)) { + SEM_ERROR__redefinition (id, "", prev); + } else if (is_fct && dsi->declared (CT_PrimDeclSpec::PDS_STATIC) && + !prev->isStatic () && + !(prev->isExtern () && prev->isInline ())) { + SEM_ERROR__static_follows_non_static (id, prev); + error = false; // it is sufficient to mark the error stream + } else + error = false; + if (error) { + builder ().destroyNode (id); + return (CTree*)0; + } + } + + if (is_typedef) { + info = current_scope->newTypedef (); + Push (info); + } else if (is_fct) { + if (! current_fct) + current_fct = current_scope->newFunction (); +/*DEBUG*/if (TRACE_FCT) std::cout<<"FCT DEC(2): "<<(void*)current_fct<Linkage (determine_linkage (dsi, FCT, prev)); + info->ScopeInfo ()->Parent ()->Structure ()-> + addFunction (info->FunctionInfo ()); + } else { + info = current_scope->newAttribute (); + info->Linkage (determine_linkage (dsi, ATTRIB, prev)); + info->Storage (determine_storage_class (dsi, ATTRIB, info->Linkage ())); + Push (info); + } + + // common settings + setSpecifiers (info, dsi); + common_settings (info, id, &csd); + if (is_typedef) { + type = info->TypeInfo ()->TypedefInfo (info); + info->TypeInfo (type); + } else if (is_fct) { + info->TypeInfo ()->VirtualType ()->TypeFunction ()->FunctionInfo (info->FunctionInfo ()); + } + if (prev) + prev->NextObject (info); + id->Object (info); + if (is_fct) + current_fct = 0; + return id; +} + + + +void CSemantic::introduce_label (CTree *&tree) { + CFunctionInfo *fct; + CT_LabelStmt *ls; + CLabelInfo *info; + const char *name; + + // build label statement + ls = (CT_LabelStmt*) tree; + if (ls->NodeName () != CT_LabelStmt::NodeId ()) + return; + + // check syntactical position of label statement + name = ls->Label ()->Text (); + if (! current_scope->LocalScope ()) { + SEM_ERROR (ls->Label (), "label `" << name << "' outside of function"); + builder ().destroyNode (ls); + tree = (CTree*)0; + return; + } + + // check if label name already used as a label in this function + fct = current_scope->LocalScope ()->Function (); + if (fct->Label (name)) { + SEM_ERROR__duplicate (ls, "label", ls->Label ()); + builder ().destroyNode (ls); + tree = (CTree*)0; + return; + } + + // complete semantic information about the label + info = fct->newLabel (); + info->Name (name); + info->TypeInfo (&CTYPE_UNDEFINED); + common_settings (info, ls); + ls->Label ()->Object (info); + Push (info); + return; +} + + + +CTree *CSemantic::enumerator_def () { + CEnumeratorInfo *einfo; + CEnumInfo *enuminfo; + CT_Enumerator *e; + CTypeInfo *type; + CConstant *v; + CTree *init; + LONG_LONG value; + unsigned numenums; + + e = (CT_Enumerator*)builder ().enumerator_def (); + + if (e && e->Object ()) { + einfo = e->Object ()->EnumeratorInfo (); + enuminfo = einfo->Enum (); + numenums = enuminfo->Enumerators (); + value = 0; + + // if the enumerator has an initializer, get the value + // from this constant expression + init = e->Initializer (); + if (init) { + type = resolveExpr (init->Son (1), init); + init = init->Son (1); + + if (! CSemExpr::isConstIntExpr (init)) { + SEM_ERROR (e, "value for enumerator `" << e->Name ()->Text () + << "' isn't integer constant expression"); + return e; + } else { + v = init->Value ()->Constant (); + if (type->VirtualType ()->is_signed ()) { + value = v->convert_to_int (); + } else { + value = v->convert_to_uint (); + } + } + // else get the value from the predecessor enumerator incremented by 1 + } else if (numenums > 1) { + if (! enuminfo->Enumerator (numenums - 2)->hasValue ()) + return e; + value = enuminfo->Enumerator (numenums - 2)->Value (); + value++; + // else this is the first enumerator, so the value is 0 + } else { + value = 0; + } + + // set the value + einfo->Value (value); + einfo->hasValue (true); + + // determine the underlying type of the enumeration, + // must be big enough to hold all enumerator values + type = enuminfo->UnderlyingType (); + bool long_gt_int = CTYPE_LONG.Size () > CTYPE_INT.Size (); + long int size = CTypePrimitive::SizeOfNumber (value); + if (value < 0) { + // signed type + if (type->is_unsigned ()) { + type = long_gt_int && *type == CTYPE_UNSIGNED_INT ? &CTYPE_LONG : &CTYPE_LONG_LONG; + } else if (size > CTYPE_LONG_LONG.Size()) { + type = &CTYPE_INT128; + } else if (size > CTYPE_LONG.Size()) { + type = &CTYPE_LONG_LONG; + } else if (size > CTYPE_INT.Size()) { + type = long_gt_int && *type == CTYPE_INT ? &CTYPE_LONG : &CTYPE_LONG_LONG; + } + } else { + // unsigned, if value cannot be represented by a + // signed type and no other value is signed + bool is_unsigned = numenums == 1 || type->is_unsigned (); + if (size <= CTYPE_INT.Size()) { + type = &CTYPE_INT; + } else if (size <= CTYPE_UNSIGNED_INT.Size()) { + type = is_unsigned ? &CTYPE_UNSIGNED_INT : long_gt_int ? &CTYPE_LONG : &CTYPE_LONG_LONG; + } else if (size <= CTYPE_LONG.Size()) { + type = &CTYPE_LONG; + } else if (size <= CTYPE_UNSIGNED_LONG.Size()) { + type = is_unsigned ? &CTYPE_UNSIGNED_LONG : &CTYPE_LONG_LONG; + } else if (size <= CTYPE_LONG_LONG.Size()) { + type = &CTYPE_LONG_LONG; + } else if (size <= CTYPE_UNSIGNED_LONG_LONG.Size()) { + type = &CTYPE_UNSIGNED_LONG_LONG; + } else { + type = is_unsigned ? &CTYPE_UNSIGNED_INT128 : &CTYPE_INT128; + } + } + if (enuminfo->UnderlyingType ()->rank () < type->rank ()) { + enuminfo->UnderlyingType (type); + } + } + + return e; +} + + + +CTree *CSemantic::introduce_enum () { + CObjectInfo *info, *oi; + CT_SimpleName *name; + CStructure *scope; + CT_EnumDef *ed; + + // OS: I don't understand what this is/was good for! +// if (builder ().nodes () == 2) +// builder ().Push (PrivateName ()); + + ed = (CT_EnumDef*)builder ().enum_spec1 (); + name = (CT_SimpleName*)ed->Name (); + scope = findParent (); + oi = lookup (name->Text (), scope, TAG, false); + + if (oi) { + if (isRedefiningTypedef (oi, CTypeInfo::TYPE_ENUM)) { + oi = oi->TypeInfo ()->TypeEnum ()->EnumInfo (); + } else if (oi->TypedefInfo ()) { + oi = 0; + } + } + if (oi) { + if (oi->EnumInfo () && oi->EnumInfo ()->isDefined ()) { + SEM_ERROR__redefinition (ed, "enum ", oi); + builder ().destroyNode (ed); + return (CTree*)0; + } else if (! oi->EnumInfo ()) { + SEM_ERROR__already_defined (ed, oi); + builder ().destroyNode (ed); + return (CTree*)0; + } + } + + info = scope->newEnum (); + info->TypeInfo (new CTypeEnum (info->EnumInfo ())); + info->Name (name->Text ()); + if (scope != current_scope) + info->AssignedScope (scope); + Push (info); + + current_enum = info->EnumInfo (); + common_settings (info, ed); + name->Object (info); + name->setTypeRef (info->TypeInfo ()); + if (oi) + oi->NextObject (info); + ed->Object (info); + + return ed; +} + + + +CTree *CSemantic::introduce_enumerator () { + CEnumeratorInfo *info; + CStructure *scope; + CT_Enumerator *e; + CObjectInfo *oi; + Token *name; + + name = builder ().get_node ()->token (); + scope = findParent (); + oi = lookup (name->text (), scope, NON_TAG, false); + if (oi) { + SEM_ERROR__already_defined (builder ().get_node (), oi); + return (CTree*)0; + } + + e = (CT_Enumerator*) builder ().enumerator (); + info = current_enum->newEnumerator (); + info->Scope (scope); + info->Name (name->dtext ()); + info->Storage (CStorage::CLASS_STATIC); + Push (info); + + common_settings (info, e); + scope->addAttribute (info); + e->Object (info); + e->Name ()->Object (info); + e->Name ()->setTypeRef (&CTYPE_LONG); + info->ObjectInfo ()->TypeInfo (&CTYPE_LONG); + return e; +} + + + +CTree *CSemantic::introduce_named_type () { + CSemDeclSpecs *dsi; + CObjectInfo *info; + CT_NamedType *nt; + + if (! in_decl ()) + return (CTree*)0; + + nt = (CT_NamedType*)builder ().type_id (); + dsi = sem_decl_specs (); + CSemDeclarator csd (_err, dsi->make_type (), nt->Declarator ()); + if (! csd.Name ()) { + builder ().destroyNode (nt); + return (CTree*)0; + } + + info = current_scope->newAttribute (); + info->Linkage (determine_linkage (dsi, ATTRIB)); + info->Storage (determine_storage_class (dsi, ATTRIB, info->Linkage ())); + Push (info); + + setSpecifiers (info, dsi); + common_settings (info, nt, &csd); + nt->Object (info); + decl_end (); + return nt; +} + + + +CTree *CSemantic::introduce_parameter () { + CArgumentInfo *info; + CSemDeclSpecs *dsi; + CT_ArgDecl *ad; + bool error; + + if (! in_decl ()) + return (CTree*)0; + if (builder ().nodes () == 1) + builder ().Push (PrivateName ()); + + ad = (CT_ArgDecl*)builder ().param_decl1 (); + dsi = sem_decl_specs (); + CSemDeclarator csd (_err, dsi->make_type (), ad->Declarator ()); + + error = true; + if (! csd.Name ()) { + /* internal error */ + } else if (lookup (csd.Name ()->Text (), ARG, false)) { + SEM_ERROR__duplicate (ad, "function parameter", csd.Name ()); + } else if (dsi->declared (CT_PrimDeclSpec::PDS_TYPEDEF) || + dsi->declared (CT_PrimDeclSpec::PDS_AUTO) || + dsi->declared (CT_PrimDeclSpec::PDS_STATIC) || + dsi->declared (CT_PrimDeclSpec::PDS_THREAD) || + dsi->declared (CT_PrimDeclSpec::PDS_EXTERN)) { + SEM_ERROR__wrong_storage_class (ad, "function parameter", csd.Name ()); + } else + error = false; + + if (error) { + builder ().destroyNode (ad); + return (CTree*)0; + } + + info = current_scope->FunctionInfo ()->newArgument (); + info->Storage (CStorage::CLASS_AUTOMATIC); + Push (info); + + // adjust parameter type + CTypeInfo* type = csd.Type (); + + // any cv-qualifier modifying a parameter is deleted + if (type->TypeQualified ()) { + CTypeInfo* tmp = type; + type = type->UnqualType ()->Duplicate (); + CTypeInfo::Destroy (tmp); + } + // type `function returning T' is adjusted to be + // `pointer to function returning T' + if (type->TypeFunction ()) { + type = new CTypePointer (type); + // type `array of T' is adjusted to be `pointer to T' + } else if (type->TypeArray ()) { + CTypeInfo* quals = type->TypeArray ()->Qualifiers (); + CTypeInfo* tmp = type; + type = new CTypePointer (type->BaseType ()->Duplicate ()); + if (quals) { + type = new CTypeQualified (type, + quals->isConst (), quals->isVolatile (), quals->isRestrict ()); + } + CTypeInfo::Destroy (tmp); + } + + setSpecifiers (info, dsi); + common_settings (info, ad); + info->Name (csd.Name ()->Text ()); + info->TypeInfo (type); + csd.Name ()->Object (info); + csd.Name ()->setTypeRef (info->TypeInfo ()); + csd.Type ((CTypeInfo*)0); + ad->Object (info); + return ad; +} + + + +CTree *CSemantic::introduce_function () { + CFunctionInfo *info; + CT_DeclSpecSeq *dss; + CSemDeclSpecs *dsi; + CStructure *scope; + CT_Declarator *d; + CObjectInfo *oi; + CTypeInfo *type; + const char *name; + + if (! current_fct) + return (CTree*)0; // Fatal internal error + + dss = (CT_DeclSpecSeq*) (builder ().nodes () == 2 ? builder ().get_node (0) : 0); + d = (CT_Declarator*) (dss ? builder ().get_node (1) : builder ().get_node (0)); + if (dss && ! in_decl ()) + return (CTree*)0; + + dsi = dss ? sem_decl_specs () : (CSemDeclSpecs*)0; + CSemDeclarator csd (_err, dsi ? dsi->make_type () : &CTYPE_UNDEFINED, d); + if (! csd.Name ()) + return (CTree*)0; + + type = csd.Type (); + name = csd.Name ()->Text (); + oi = lookup (name, NON_TAG, false); + if (oi && (! oi->FunctionInfo () || ! typeMatch (type, oi->TypeInfo ()))) + return (CTree*)0; + + // re-use function prototype scope +/*DEBUG*/if (TRACE_FCT) std::cout<<"FCT ENT(2): "<<(void*)current_fct<Parent (); + + if (! type->isFunction ()) + return (CTree*)0; // ill-formed + type->VirtualType ()->TypeFunction ()->FunctionInfo (info); + + if (! scope->GlobalScope ()) { + if (scope->insideFunction ()) + SEM_ERROR (d, "nested function `" << name << "'"); + return (CTree*)0; + } + + if (dsi->declared (CT_PrimDeclSpec::PDS_TYPEDEF) || + dsi->declared (CT_PrimDeclSpec::PDS_REGISTER) || + dsi->declared (CT_PrimDeclSpec::PDS_AUTO)) { + SEM_ERROR__wrong_storage_class (d, "function", csd.Name ()); + return (CTree*)0; + } + + if (oi) { + if (dsi->declared (CT_PrimDeclSpec::PDS_STATIC) && !oi->isStatic () && + !(oi->isExtern () && oi->isInline ())) { + SEM_ERROR__static_follows_non_static (d, oi); + return (CTree*)0; + } + else if (isRedefinedFunction (oi->FunctionInfo ())) { + SEM_ERROR__redefinition (d, "function ", oi); + return (CTree*)0; + } else + oi->NextObject (info); + } + + if (dsi) + setSpecifiers (info, dsi); + info->Name (csd.Name ()->Text ()); + info->SourceInfo ()->FileInfo (_file); + info->ObjectInfo ()->TypeInfo (type); + csd.Name ()->Object (info); + csd.Name ()->setTypeRef (type); + csd.Type ((CTypeInfo*)0); + scope->addFunction (info); + if (dss) decl_end (); + return d; +} + + +bool CSemantic::isRedefinedFunction (CFunctionInfo* fct) const { + return fct->isDefined (); +} + + +CTree *CSemantic::introduce_class () { + CObjectInfo *info, *oi; + CStructure *scope; + CT_ClassDef *cs; + + cs = (CT_ClassDef*) builder ().class_head (); + scope = findParent (); + oi = lookup (cs->Name ()->Text (), scope, TAG, false); + + if (oi) { + if (isRedefiningTypedef (oi, CTypeInfo::TYPE_CLASS)) { + oi = oi->TypeInfo ()->TypeClass ()->ClassInfo (); + } else if (oi->TypedefInfo ()) { + oi = 0; + } + } + if (oi) { + if ((oi->ClassInfo () && oi->ClassInfo ()->isDefined ()) || + (oi->UnionInfo () && oi->UnionInfo ()->isDefined ())) { + SEM_ERROR__redefinition (cs, + (oi->ClassInfo () ? "struct " : "union "), oi); + builder ().destroyNode (cs); + return (CTree*)0; + } else if (! oi->Record () || + (cs->NodeName () == CT_ClassDef::NodeId () && ! oi->ClassInfo ()) || + (cs->NodeName () == CT_UnionDef::NodeId () && ! oi->UnionInfo ())) { + SEM_ERROR__already_defined (cs, oi); + builder ().destroyNode (cs); + return (CTree*)0; + } + } + + if (cs->NodeName () == CT_ClassDef::NodeId ()) { + info = scope->newClass (); + info->TypeInfo (new CTypeClass (info->ClassInfo ())); + } else { + info = scope->newUnion (); + info->TypeInfo (new CTypeUnion (info->UnionInfo ())); + } + info->Name (cs->Name ()->Text ()); + if (scope != current_scope) + info->AssignedScope (scope); + + // common settings + enter_scope (info->Structure ()); + common_settings (info, cs); + cs->Name ()->Object (info); + cs->Name ()->setTypeRef (info->TypeInfo ()); + cs->Object (info); + if (oi) + oi->NextObject (info); + + return cs; +} + + + +CTree *CSemantic::introduce_member () { + CAttributeInfo *info; + CSemDeclSpecs *dsi; + CTree *d; + + if (! in_decl ()) + return (CTree*)0; + + d = builder ().member_declarator (); + dsi = sem_decl_specs (); + CSemDeclarator csd (_err, dsi->make_type (), d); + + if (! csd.Name ()) { + builder ().destroyNode (d); + return (CTree*)0; + } else if (lookup (csd.Name ()->Text (), ATTRIB, false)) { + SEM_ERROR__duplicate (d, "member", csd.Name ()); + builder ().destroyNode (d); + return (CTree*)0; + } + + info = current_scope->newAttribute (); + info->Linkage (determine_linkage (dsi, ATTRIB)); + info->Storage (determine_storage_class (dsi, ATTRIB, info->Linkage ())); + Push (info); + + setSpecifiers (info, dsi); + common_settings (info, d, &csd); + if (d->NodeName () == CT_InitDeclarator::NodeId ()) + ((CT_InitDeclarator*)d)->Object (info); + else + ((CT_BitFieldDeclarator*)d)->Object (info); + return d; +} + + + +CTree *CSemantic::introduce_tag () { + CObjectInfo *info, *oi; + CT_ClassSpec *tag; + CStructure *scope; + + tag = (CT_ClassSpec*) builder ().elaborated_type_spec (); + oi = lookup (tag->Name ()->Text (), TAG, true); + + // check for redefining typedef (typedef struct X X;) + if (oi && oi->TypedefInfo ()) { + CTypeInfo* t = oi->TypedefInfo ()->TypeInfo (); + if (t->TypeRecord ()) + oi = t->TypeRecord ()->Record (); + else if (t->TypeEnum ()) + oi = t->TypeEnum ()->EnumInfo (); + if (oi && oi->Name () != DString(tag->Name ()->Text ())) + oi = (CObjectInfo*)0; + } + if (oi) { + if ((tag->NodeName () == CT_ClassSpec::NodeId () && ! oi->ClassInfo ()) || + (tag->NodeName () == CT_UnionSpec::NodeId () && ! oi->UnionInfo ()) || + (tag->NodeName () == CT_EnumSpec::NodeId () && ! oi->EnumInfo ())) { + SEM_ERROR (tag, "wrong use of `" << *tag->Name () << "'"); + return (CTree*)0; + } + } + + scope = findParent (); + if (tag->NodeName () == CT_ClassSpec::NodeId ()) { + info = scope->newClass (); + info->TypeInfo (new CTypeClass (info->ClassInfo ())); + } else if (tag->NodeName () == CT_UnionSpec::NodeId ()) { + info = scope->newUnion (); + info->TypeInfo (new CTypeUnion (info->UnionInfo ())); + } else { + info = scope->newEnum (); + info->TypeInfo (new CTypeEnum (info->EnumInfo ())); + } + if (scope != current_scope) + info->AssignedScope (scope); + + // common settings + common_settings (info, tag); + info->Name (tag->Name ()->end_token ()->dtext ()); + tag->Name ()->Object (info); + tag->Name ()->setTypeRef (info->TypeInfo ()); + Push (info); + if (oi) + oi->NextObject (info); + + return tag; +} + + + +CTree *CSemantic::identifier_list () { + CT_ArgNameList *result; + CT_SimpleName *arg; + CFunctionInfo *fct; + CObjectInfo *info; + int num; + + fct = (CFunctionInfo*) current_scope; + result = (CT_ArgNameList*) builder ().identifier_list (); + num = result->Sons (); + + for (int i = 0; i < num; i += 2) { + arg = (CT_SimpleName*) result->Son (i); + info = lookup (arg->Text (), NON_TAG, true); + if (info && info->TypedefInfo ()) { + // typedef names shall not be redeclared as parameters + // in an identifier list + builder ().destroyNode (result); + return (CTree*)0; + } else if (fct->Argument (arg->Text ())) { + SEM_ERROR__duplicate (result, "function parameter", arg); + builder ().destroyNode (result); + return (CTree*)0; + } + info = fct->newArgument (); + info->TypeInfo (&CTYPE_INT); // implicit int + info->Name (arg->Text ()); + arg->Object (info); + common_settings (info, arg); + Push (info); + } + + result->Scope (current_scope); + return result; +} + + + +CTree *CSemantic::declare_parameter () { + CT_InitDeclarator *id; + CSemDeclSpecs *dsi; + CObjectInfo *info; + CTypeInfo *type; + bool error; + + if (! in_decl ()) + return (CTree*)0; + + id = (CT_InitDeclarator*) builder ().init_declarator1 (); + dsi = sem_decl_specs (); + CSemDeclarator csd (_err, dsi->make_type (), id); + if (! csd.Type () || ! csd.Name () || ! current_scope->FunctionInfo ()) { + builder ().destroyNode (id); + return (CTree*)0; + } + + info = current_scope->FunctionInfo ()->Argument (csd.Name ()->Text ()); + error = true; + if (! info) { + SEM_ERROR (id, "declaration for unknown parameter `" + << csd.Name ()->Text () << "'"); + } else if (! info->Tree ()->IsSimpleName ()) { + SEM_ERROR__redefinition (id, "function parameter ", info); + } else if (id->Sons () == 2) { + SEM_ERROR (id, "parameter `" << csd.Name ()->Text () + << "' is initialized"); + } else if (dsi->declared (CT_PrimDeclSpec::PDS_TYPEDEF) || + dsi->declared (CT_PrimDeclSpec::PDS_EXTERN) || + dsi->declared (CT_PrimDeclSpec::PDS_STATIC) || + dsi->declared (CT_PrimDeclSpec::PDS_THREAD) || + dsi->declared (CT_PrimDeclSpec::PDS_AUTO)) { + SEM_ERROR__wrong_storage_class (id, "function parameter", csd.Name ()); + } else + error = false; + + if (error) { + builder ().destroyNode (id); + return (CTree*)0; + } + + // adjust parameter type + type = csd.Type (); + if (type->isFunction ()) { + type = new CTypePointer (type->Duplicate ()); + } else if (type->isArray ()) { + CTypeQualified *quals = type->VirtualType ()->TypeArray ()->Qualifiers (); + type = type->VirtualType ()->BaseType (); + type = new CTypePointer (type->Duplicate ()); + if (quals) { + type = new CTypeQualified (type, quals->isConst (), quals->isVolatile (), quals->isRestrict ()); + } + } + csd.Type (type); + + setSpecifiers (info, dsi); + ((CT_SimpleName*)info->Tree ())->setTypeRef (type); + common_settings (info, id, &csd); + id->Object (info); + return id; +} + + + +bool CSemantic::empty_decl_spec_seq () { + CT_DeclSpecSeq *dss = new CT_DeclSpecSeq; + decl_specs_begin (dss); + begin_decl (); + builder ().Push (dss); + return true; +} + + + +bool CSemantic::decl_spec_seq () { + decl_specs_begin (new CT_DeclSpecSeq); + return true; +} + + + +CTree *CSemantic::decl_spec_seq_err () { + builder ().destroyNode (decl_specs ()); + decl_specs_end (); + return (CTree*)0; +} + + + +CTree *CSemantic::decl_spec_seq1 () { + CT_PrimDeclSpec::Type type; + CTree *cds, *ds; + + // check whether to parse an identifier in a declaration + // as type specifier or declarator identifier + + cds = builder ().decl_spec_seq1 (); + if (decl_specs ()->Sons () && // not first specifier? + cds->NodeName () == CT_SimpleName::NodeId () && // identifier? + lookup (cds->token ()->text (), TYPEDEF, true)) { // typedef name? + + for (int i = decl_specs ()->Sons () - 1; i >= 0; i--) { + ds = decl_specs ()->Son (i); + if (ds->NodeName () == CT_SimpleName::NodeId () || + ds->NodeName () == CT_ClassSpec::NodeId () || + ds->NodeName () == CT_ClassDef::NodeId () || + ds->NodeName () == CT_UnionSpec::NodeId () || + ds->NodeName () == CT_UnionDef::NodeId () || + ds->NodeName () == CT_EnumSpec::NodeId () || + ds->NodeName () == CT_EnumDef::NodeId ()) { + return (CTree*)0; + } + if (ds->NodeName () == CT_PrimDeclSpec::NodeId ()) { + type = ((CT_PrimDeclSpec*)ds)->SpecType (); + if (type == CT_PrimDeclSpec::PDS_CHAR || + type == CT_PrimDeclSpec::PDS_WCHAR_T || + type == CT_PrimDeclSpec::PDS_BOOL || + type == CT_PrimDeclSpec::PDS_C_BOOL || + type == CT_PrimDeclSpec::PDS_SHORT || + type == CT_PrimDeclSpec::PDS_INT || + type == CT_PrimDeclSpec::PDS_LONG || + type == CT_PrimDeclSpec::PDS_SIGNED || + type == CT_PrimDeclSpec::PDS_UNSIGNED || + type == CT_PrimDeclSpec::PDS_FLOAT || + type == CT_PrimDeclSpec::PDS_DOUBLE || + type == CT_PrimDeclSpec::PDS_INT64 || + type == CT_PrimDeclSpec::PDS_INT128 || + type == CT_PrimDeclSpec::PDS_UNKNOWN_T || + type == CT_PrimDeclSpec::PDS_VOID) + return (CTree*)0; + } + } + } + + decl_specs ()->AddSon (cds); + return cds; +} + + + +CTree *CSemantic::begin_decl () { + CT_DeclSpecSeq *dss = decl_specs (); + decl_specs_end (); + decl_begin (new CSemDeclSpecs (_err, dss, support_implicit_int)); + return dss; +} + + + +CTree *CSemantic::abst_declarator () { + if (builder ().get_node (builder ().nodes () - 1)->NodeName () == + Builder::Container::NodeId ()) + builder ().Push (PrivateName ()); + return builder ().abst_declarator (); +} + + + +CTree *CSemantic::direct_abst_declarator () { + if (builder ().get_node (0)->NodeName () == Builder::Container::NodeId ()) + builder ().Push (PrivateName ()); + CTree *declarator = builder ().direct_abst_declarator (); + + // calculate delimiter of array declarator + if (declarator && declarator->NodeName () == CT_ArrayDeclarator::NodeId ()) { + CT_ArrayDelimiter *delim = ((CT_ArrayDeclarator*)declarator)->Delimiter (); + if (delim && delim->Expr ()) { + resolveExpr (delim->Expr (), delim); + } + } + + return declarator; +} + + + +bool CSemantic::typeMatch (CTypeInfo *t1, CTypeInfo *t2) const { + CTypeFunction *f1, *f2; + if (t1->isFunction () && t2->isFunction ()) { + f1 = t1->VirtualType ()->TypeFunction (); + f2 = t2->VirtualType ()->TypeFunction (); + // do not compare parameter types + if (! (f1->ArgTypes ()->Entries () && f2->ArgTypes ()->Entries ())) + return (*f1->ReturnType () == *f2->ReturnType ()); + } + return *t1 == *t2; +} + + + +CTree *CSemantic::array_delim () { + CT_ArrayDelimiter *delim = (CT_ArrayDelimiter*) builder ().array_delim (); + if (delim && delim->Expr ()) { + resolveExpr (delim->Expr (), delim); + } + return delim; +} + + + +CTypeInfo *CSemantic::resolveExpr (CTree *expr, CTree *base) const { + if (expr) { + CSemExpr cse (*_err, current_scope); + return cse.resolveExpr (expr, base); + } + return (CTypeInfo*)0; +} + + + +CTree *CSemantic::param_decl_clause () { + CT_ArgDeclList *result; + int nodes = builder ().nodes (); + if (nodes) { + CTree *pl = builder ().get_node (0); + if (pl->NodeName () == Builder::Container::NodeId () && + (pl->Sons () % 2) == 0 && nodes != 2) + return (CTree*)0; // trailing separator => ill-formed + } + result = (CT_ArgDeclList*) builder ().param_decl_clause (); + result->Scope (current_scope); + return result; +} + + + +void CSemantic::begin_param_check () { + in_arg_decl = true; + is_type_name = false; +} + + + +bool CSemantic::finish_param_check (bool result) { + // reset the state + in_arg_decl = false; + is_type_name = false; + + // return if the rule wasn't parsed successfully anyway + if (!result) + return false; + + // if no ambiguity is possible here, return as well + bool ambiguity = in_arg_decl && is_type_name; + if (! ambiguity) + return true; + + // Handle the ambiguity between the declaration of a parameter + // of type pointer to function and the declaration of a parameter + // with redundant parentheses around the declarator-id. + // The resolution is to consider the type-name as a simple-type- + // specifier rather than a declarator-id. [Example: + // + // class C { }; + // void f(int(C)); // void f(int (*__fp)(C __parm)); + // // not: void f(int C); + // void g(int *(C[10])); // void g(int *(*__fp)(C __parm[10])); + // // not: void g(int *C[10]); + // -end example] + + CTree *d = builder ().Top (); + // if (! d) return d; + + while (d->NodeName () == CT_PtrDeclarator::NodeId () || + d->NodeName () == CT_RefDeclarator::NodeId () || + d->NodeName () == CT_MembPtrDeclarator::NodeId ()) + d = ((CT_Declarator*)d)->Declarator (); + + // check declarator => ( type-name ... ) + if (d->NodeName () == CT_BracedDeclarator::NodeId ()) { + d = ((CT_Declarator*)d)->Declarator (); + if (! (d->NodeName () == CT_SimpleName::NodeId () || + d->NodeName () == CT_QualName::NodeId () || + d->NodeName () == CT_RootQualName::NodeId ())) + d = d->Son (0); + if (d->NodeName () == CT_SimpleName::NodeId () || + d->NodeName () == CT_QualName::NodeId () || + d->NodeName () == CT_RootQualName::NodeId ()) { + // delete the node and all allocated semantic objects + undo (builder ().Top ()); + Builder::destroy (builder ().Top ()); + return false; // don't accept it => pointer to function + } + } + return true; +} + + + +CTree *CSemantic::finish_fct_def () { + CT_FctDef *fd = (CT_FctDef*) builder ().fct_def (); + common_settings (current_scope, fd); + fd->Object (current_scope); + return fd; +} + + + +CTree *CSemantic::arg_decl_seq () { + CT_ArgDeclSeq *result; + CTypeList *argtypes; + CTypeInfo *argtype; + CFunctionInfo *fct; + CObjectInfo *arg; + unsigned num; + + fct = (CFunctionInfo*) current_scope; + argtypes = fct->TypeInfo ()->ArgTypes (); + + num = fct->Arguments (); + for (unsigned i = 0; i < num; i++) { + arg = fct->Argument (i); + argtype = arg->TypeInfo (); + if (! argtype->is_undefined ()) { + argtypes->AddEntry (argtype->Duplicate ()); + } else { + argtypes->AddEntry (&CTYPE_UNDEFINED); + SEM_ERROR (arg->Tree (), "missing declaration for parameter `" + << arg->Name () << "'"); + } + } + + result = (CT_ArgDeclSeq*) builder ().arg_decl_seq (); + result->Scope (current_scope); + return result; +} + + + +CTree *CSemantic::class_spec () { + CT_ClassDef *result; + + result = (CT_ClassDef*) builder ().class_spec (); + result->Members ()->Scope (current_scope); + + // anonymous struct or union declared within another struct or union + // and no object is declared with it + if (current_scope->isAnonymous () && + current_scope->Parent ()->isRecord () && + syntax ().look_ahead (TOK_SEMI_COLON)) { + + // introduce the members of the struct or union into the nearest + // named parent struct or union, if it exists, otherwise into the + // outermost parent struct or union + + // find the parent struct or union + CStructure *targetScope = current_scope; + while (targetScope->isAnonymous () && targetScope->Parent ()->isRecord ()) + targetScope = (CStructure*) targetScope->Parent (); + + // introduce the members into the target scope, check for each member + // if there is already a member with that name in the target scope and + // issue an error if so + CMemberAliasInfo *alias; + CObjectInfo *member; + for (unsigned i = 0; i < current_scope->Attributes (); i++) { + // next member, ignore anonymous members + member = current_scope->Attribute (i); + if (member->isAnonymous ()) + continue; + + // check for duplicates in target scope + if (targetScope->Attribute (member->Name ())) { + SEM_ERROR (member->Tree (), "duplicate member '" << member->Name () << "'"); + continue; + } + + // create an alias for this member in the target scope + alias = targetScope->newMemberAlias (member, true); + alias->Name (member->Name ()); + alias->Member (member); + alias->TypeInfo (member->TypeInfo ()->Duplicate ()); + alias->Linkage (member->Linkage ()); + alias->Storage (member->Storage ()); + alias->Specifiers (member->Specifiers ()); + common_settings (alias, member->Tree ()); + Push (alias); + } + } + + return result; +} + + +void CSemantic::reenter_class_scope () { + CObjectInfo *info; + CT_ClassDef *cd; + + cd = (CT_ClassDef*)builder ().get_node (0); + info = cd->Object (); + + if (info && info->Record ()) + reenter_scope (info->Record ()); +} + + +CTree *CSemantic::trans_unit () { + CT_Program *result; + result = (CT_Program*) builder ().trans_unit (); + if (! result) + result = new CT_Program (1); + result->Scope (_file); + _file->Tree (result); + return result; +} + + + +CTree *CSemantic::cmpd_stmt () { + CT_CmpdStmt *result; + result = (CT_CmpdStmt*) builder ().cmpd_stmt (); + result->Scope (current_scope); + current_scope->Tree (result); + return result; +} + + + +CTree *CSemantic::select_stmt () { + CTree *result; + result = builder ().select_stmt (); + if (result->NodeName () == CT_SwitchStmt::NodeId ()) + ((CT_SwitchStmt*) result)->Scope (current_scope); + else if (result->NodeName () == CT_IfStmt::NodeId ()) + ((CT_IfStmt*) result)->Scope (current_scope); + else + ((CT_IfElseStmt*) result)->Scope (current_scope); + current_scope->Tree (result); + return result; +} + + + +CTree *CSemantic::iter_stmt () { + CTree *result; + result = builder ().iter_stmt (); + if (result->NodeName () == CT_DoStmt::NodeId ()) + return result; + if (result->NodeName () == CT_WhileStmt::NodeId ()) + ((CT_WhileStmt*) result)->Scope (current_scope); + else + ((CT_ForStmt*) result)->Scope (current_scope); + current_scope->Tree (result); + return result; +} + + + +CStructure *CSemantic::findParent () const { + return (CStructure*) non_record_scopes.Top(); +} + + + +void CSemantic::setSpecifiers (CObjectInfo *info, CSemDeclSpecs *dsi) const { + if (! info || ! dsi) + return; + + if (dsi->declared (CT_PrimDeclSpec::PDS_VIRTUAL)) + info->isVirtual (true); + if (dsi->declared (CT_PrimDeclSpec::PDS_STATIC)) + info->isStatic (true); + if (dsi->declared (CT_PrimDeclSpec::PDS_EXTERN)) + info->isExtern (true); + if (dsi->declared (CT_PrimDeclSpec::PDS_MUTABLE)) + info->isMutable (true); + if (dsi->declared (CT_PrimDeclSpec::PDS_REGISTER)) + info->isRegister (true); + if (dsi->declared (CT_PrimDeclSpec::PDS_EXPLICIT)) + info->isExplicit (true); + if (dsi->declared (CT_PrimDeclSpec::PDS_INLINE)) + info->isInline (true); + if (dsi->declared (CT_PrimDeclSpec::PDS_AUTO)) + info->isAuto (true); + if (dsi->declared (CT_PrimDeclSpec::PDS_THREAD)) + info->isThreadLocal (true); +} + + + +bool CSemantic::implicit_int () { + if (! support_implicit_int || ! current_scope->isNamespace ()) + return false; + + CT_DeclSpecSeq *dss = new CT_DeclSpecSeq; + CT_PrimDeclSpec *pds = new CT_PrimDeclSpec (CT_PrimDeclSpec::PDS_INT); + dss->AddSon (pds); + decl_specs_begin (dss); + begin_decl (); + //builder ().Push (pds); + builder ().Push (dss); + return true; +} + + + +CTree *CSemantic::init_declarator () { + return builder ().init_declarator (); +} + + +bool CSemantic::isRedefiningTypedef (CObjectInfo* info, int obj_type) const { + CTypedefInfo* tdef = info->TypedefInfo (); + if (! tdef) + return false; + CTypeInfo* type = tdef->TypeInfo (); + if (! type) + return false; + CObjectInfo* oinfo = 0; + switch (obj_type) { + case CTypeInfo::TYPE_CLASS: + oinfo = type->TypeClass () ? type->TypeClass ()->ClassInfo () : 0; + break; + case CTypeInfo::TYPE_UNION: + oinfo = type->TypeUnion () ? type->TypeUnion ()->UnionInfo () : 0; + break; + case CTypeInfo::TYPE_ENUM: + oinfo = type->TypeEnum () ? type->TypeEnum ()->EnumInfo () : 0; + break; + default: + break; + } + if (oinfo && oinfo->Name () == tdef->Name ()) + return true; + return false; +} + + +} // namespace Puma diff --git a/Puma/src/parser/cparser/CSemantic.h b/Puma/src/parser/cparser/CSemantic.h new file mode 100644 index 0000000..7191605 --- /dev/null +++ b/Puma/src/parser/cparser/CSemantic.h @@ -0,0 +1,178 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CSemantic_h__ +#define __CSemantic_h__ + +#include "Puma/Semantic.h" +#include "Puma/CBuilder.h" +#include "Puma/CLinkage.h" +#include "Puma/CProtection.h" +#include "Puma/CTree.h" +#include "Puma/PtrStack.h" + +namespace Puma { + class CSyntax; +} + +namespace Puma { + +class CSemantic : public Semantic { + CSyntax &_syntax; + CBuilder &_builder; + +protected: + enum SemObjType { + CLASS, UNION, ENUM, TYPEDEF, FCT, ATTRIB, ARG, TAG, NON_TAG, ANY + }; + + bool in_arg_decl; + bool _in_arg_decl_seq; + bool is_type_name; + bool support_implicit_int; + PtrStack non_record_scopes; + + void declareImplicitFcts () {} // builtin functions + +public: + CSemantic (CSyntax &, CBuilder &); + + virtual void init (CSemDatabase &, Unit &); + void configure (Config &); + +protected: + virtual CBuilder &builder () const; + virtual CSyntax &syntax () const; + virtual void Delete (); + +public: + // control parse process + virtual CTree *id_expr (); + virtual CTree *typedef_name (); + virtual CTree *init_declarator (); + virtual CTree *abst_declarator (); + virtual CTree *direct_abst_declarator (); + virtual CTree *param_decl_clause (); + virtual CTree *finish_fct_def (); + virtual CTree *arg_decl_seq (); + virtual CTree *decl_spec_seq1 (); + virtual CTree *decl_spec_seq_err (); + virtual CTree *declare_parameter (); + virtual CTree *identifier_list (); + virtual bool finish_param_check (bool); + virtual CTree *begin_decl (); + virtual CTree *array_delim (); + virtual CTree *enumerator_def (); + + // add scope information to tree nodes + virtual CTree *trans_unit (); + virtual CTree *class_spec (); + virtual CTree *cmpd_stmt (); + virtual CTree *select_stmt (); + virtual CTree *iter_stmt (); + + // introduce names... add new entries to the class database + virtual void introduce_label (CTree *&); + virtual CTree *introduce_object (CTree* = 0); + virtual CTree *introduce_named_type (); + virtual CTree *introduce_enum (); + virtual CTree *introduce_enumerator (); + virtual CTree *introduce_function (); + virtual CTree *introduce_parameter (); + virtual CTree *introduce_class (); + virtual CTree *introduce_member (); + virtual CTree *introduce_tag (); + +public: // change or get semantic state information + void enter_arg_decl_seq (); + void leave_arg_decl_seq (); + void begin_param_check (); + bool in_arg_decl_seq () const; + bool decl_spec_seq (); + bool empty_decl_spec_seq (); + virtual bool implicit_int (); + virtual CProtection::Type protection () const; + +public: + void reenter_class_scope (); + void enter_scope (CStructure *scp); + void reenter_scope (CStructure *scp); + void leave_scopes (); + +protected: + CObjectInfo *lookup (const char *, SemObjType, bool = false) const; + CObjectInfo *lookup (CT_SimpleName *, SemObjType, bool = false) const; + CObjectInfo *lookup (const char *, CStructure *, SemObjType, bool) const; + CObjectInfo *lookupBuiltin (const char* name) const; + + CLinkage::Type determine_linkage (CSemDeclSpecs *, SemObjType, + CObjectInfo * = (CObjectInfo*)0) const; + CStorage::Type determine_storage_class (CSemDeclSpecs *, SemObjType, + CLinkage::Type) const; + + // helper + bool typeMatch (CTypeInfo *, CTypeInfo *) const; + CStructure *findParent () const; + void setSpecifiers (CObjectInfo *, CSemDeclSpecs *) const; + bool isRedefiningTypedef (CObjectInfo*, int obj_type) const; + bool isRedefinedFunction (CFunctionInfo*) const; + + // create class DB objects + CAttributeInfo *createAttribute (const char *, CStructure *, CTypeInfo *, + bool = false); + CTypedefInfo *createTypedef (const char *, CStructure *, CTypeInfo *); + void createParameter (CFunctionInfo *, CTypeInfo *); + CFunctionInfo *createFunction (const char *, CStructure *, CTypeInfo *); + + CTypeInfo *resolveExpr (CTree *expr, CTree *base) const; +}; + +inline CSemantic::CSemantic (CSyntax &s, CBuilder &b) : + _syntax (s), _builder (b), + in_arg_decl (false), + _in_arg_decl_seq (false), + is_type_name (false), + support_implicit_int (true) + {} + +inline CBuilder &CSemantic::builder () const + { return _builder; } + +inline CSyntax &CSemantic::syntax () const + { return _syntax; } + +inline CObjectInfo *CSemantic::lookup (const char *id, SemObjType type, + bool nested) const + { return lookup (id, current_scope, type, nested); } +inline CObjectInfo *CSemantic::lookup (CT_SimpleName *id, SemObjType type, + bool nested) const + { return lookup (id->Text (), current_scope, type, nested); } + +inline bool CSemantic::in_arg_decl_seq () const + { return _in_arg_decl_seq; } +inline void CSemantic::enter_arg_decl_seq () + { _in_arg_decl_seq = true; _in_param_decl_clause.push (true); } +inline void CSemantic::leave_arg_decl_seq () + { _in_arg_decl_seq = false; _in_param_decl_clause.pop (); } + +inline CProtection::Type CSemantic::protection () const + { return CProtection::PROT_NONE; } + +} // namespace Puma + +#endif /* __CSemantic_h__ */ diff --git a/Puma/src/parser/cparser/CSpecifiers.h b/Puma/src/parser/cparser/CSpecifiers.h new file mode 100644 index 0000000..b18d15f --- /dev/null +++ b/Puma/src/parser/cparser/CSpecifiers.h @@ -0,0 +1,105 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CSpecifiers__ +#define __CSpecifiers__ + +/** \file + * C/C++ declaration specifiers. */ + +namespace Puma { + + +/** \class CSpecifiers CSpecifiers.h Puma/CSpecifiers.h + * C/C++ declaration specifiers for the declaration + * of an entity. */ +class CSpecifiers { +public: + /** Declaration specifiers. */ + enum Spec { + /** No declaration specifier. */ + SPEC_NONE = 0x0, + /** Declaration specifier \c virtual. */ + SPEC_VIRTUAL = 0x1, + /** Declaration specifier \c static. */ + SPEC_STATIC = 0x2, + /** Declaration specifier \c extern. */ + SPEC_EXTERN = 0x4, + /** Declaration specifier \c mutable. */ + SPEC_MUTABLE = 0x8, + /** Declaration specifier \c register. */ + SPEC_REGISTER = 0x10, + /** Declaration specifier \c explicit. */ + SPEC_EXPLICIT = 0x20, + /** Declaration specifier \c auto. */ + SPEC_AUTO = 0x40, + /** Declaration specifier \c inline. */ + SPEC_INLINE = 0x80, + /** Declaration specifier \c __thread. */ + SPEC_THREAD = 0x100 + }; + +private: + Spec _specs; + +public: + /** Constructor. */ + CSpecifiers (); + /** Copy-constructor. + * \param copy The declaration specifiers to copy. */ + CSpecifiers (const CSpecifiers ©); + /** Assignment operator. + * \param s The assigned declaration specifiers. */ + CSpecifiers &operator =(const CSpecifiers &s); + + /** Add a declaration specifier. + * \param s The declaration specifier. */ + CSpecifiers &operator +=(Spec s); + /** Remove a declaration specifier. + * \param s The declaration specifier. */ + CSpecifiers &operator -=(Spec s); + + /** Check if the given declaration specifier was specified. + * \param s The declaration specifier. */ + bool operator ==(Spec) const; + /** Check if the given declaration specifier was not specified. + * \param s The declaration specifier. */ + bool operator !=(Spec) const; +}; + +inline CSpecifiers::CSpecifiers () : _specs (SPEC_NONE) + {} +inline CSpecifiers::CSpecifiers (const CSpecifiers &s) + { _specs = s._specs; } +inline CSpecifiers &CSpecifiers::operator =(const CSpecifiers &s) + { _specs = s._specs; return *(CSpecifiers*)this; } + +inline CSpecifiers &CSpecifiers::operator +=(CSpecifiers::Spec s) + { _specs = (Spec)(_specs | s); return *(CSpecifiers*)this; } +inline CSpecifiers &CSpecifiers::operator -=(CSpecifiers::Spec s) + { _specs = (Spec)(_specs ^ (_specs & s)); return *(CSpecifiers*)this; } + +inline bool CSpecifiers::operator ==(CSpecifiers::Spec s) const + { return (_specs & s); } +inline bool CSpecifiers::operator !=(CSpecifiers::Spec s) const + { return ! (_specs & s); } + + +} // namespace Puma + +#endif /* __CSpecifiers__ */ diff --git a/Puma/src/parser/cparser/CStorage.h b/Puma/src/parser/cparser/CStorage.h new file mode 100644 index 0000000..29e1acb --- /dev/null +++ b/Puma/src/parser/cparser/CStorage.h @@ -0,0 +1,52 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CStorage_h__ +#define __CStorage_h__ + +/** \file + * C/C++ object storage classes. */ + +namespace Puma { + + +/** \class CStorage CStorage.h Puma/CStorage.h + * Storage class of an object. Defines the minimum potential + * lifetime of the storage containing the object. There are + * three resp. four different storage classes: static, automatic, + * thread, and dynamic. */ +struct CStorage { + /** The storage classes. */ + enum Type { + /** Static storage class. */ + CLASS_STATIC, + /** Automatic storage class. */ + CLASS_AUTOMATIC, + /** Dynamic storage class. */ + CLASS_DYNAMIC, + /** Thread local storage (TLS) class. */ + CLASS_THREAD, + /** Undefined storage class. */ + CLASS_NONE + }; +}; + + +} // namespace Puma + +#endif /* __CStorage_h__ */ diff --git a/Puma/src/parser/cparser/CStrLiteral.h b/Puma/src/parser/cparser/CStrLiteral.h new file mode 100644 index 0000000..bc2c201 --- /dev/null +++ b/Puma/src/parser/cparser/CStrLiteral.h @@ -0,0 +1,62 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CStrLiteral_h__ +#define __CStrLiteral_h__ + +/** \file + * String literal abstraction. */ + +#include "Puma/CExprValue.h" + +namespace Puma { + + +/** \class CStrLiteral CStrLiteral.h Puma/CStrLiteral.h + * String literal abstraction. Holds the string value, + * its length, and the string type. */ +class CStrLiteral : public CExprValue { + const char *_string; + unsigned long _len; + +public: + /** Constructor. + * \param s The string array. + * \param len The length of the string. + * \param t The type of the string. */ + CStrLiteral (const char *s, unsigned long len, CTypeInfo *t) : + CExprValue (t), _string (s), _len (len) {} + /** Destructor. Frees the string. */ + virtual ~CStrLiteral () { if (_string) delete[] _string; } + + /** Print the string on the given output stream. + * \param out The output stream. */ + virtual void print (std::ostream &out) const { out << "\"" << String () << "\""; } + /** Get the wide string. */ + const char *String () const { return _string; } + /** Get the length of the string. */ + unsigned long Length () const { return _len; } + + /** Get this. */ + CStrLiteral *StrLiteral () const { return (CStrLiteral*)this; } +}; + + +} // namespace Puma + +#endif /* __CStrLiteral_h__ */ diff --git a/Puma/src/parser/cparser/CSyntax.cc b/Puma/src/parser/cparser/CSyntax.cc new file mode 100644 index 0000000..7a8a8f1 --- /dev/null +++ b/Puma/src/parser/cparser/CSyntax.cc @@ -0,0 +1,1311 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CSyntax.h" +#include "Puma/CStructure.h" +#include "Puma/CTokens.h" +#include "Puma/CTree.h" + +namespace Puma { + + +void CSyntax::configure (Config &config) { + Syntax::configure (config); + init_prim_types (); + init_cv_quals (); +} + +void CSyntax::init_prim_types () { + _prim_types.set (TOK_C_BOOL); + _prim_types.set (TOK_CHAR); + _prim_types.set (TOK_SHORT); + _prim_types.set (TOK_INT); + _prim_types.set (TOK_LONG); + _prim_types.set (TOK_SIGNED); + _prim_types.set (TOK_UNSIGNED); + _prim_types.set (TOK_FLOAT); + _prim_types.set (TOK_DOUBLE); + _prim_types.set (TOK_WCHAR_T); + _prim_types.set (TOK_VOID); + _prim_types.set (TOK_UNKNOWN_T); +} + +void CSyntax::init_cv_quals () { + _cv_quals.set (TOK_CONST); + _cv_quals.set (TOK_VOLATILE); + _cv_quals.set (TOK_RESTRICT); +} + +bool CSyntax::is_fct_def () { + State s = token_provider->get_state (); + bool result = false, braces = false, stop = false; + Token *current; + int token; + + while (!stop && (current = token_provider->current ())) { + token = current->type (); + + // before function parameter list + if (! braces) { + switch (token) { + // only declaration + case TOK_SEMI_COLON: + case TOK_COMMA: + case TOK_ASSIGN: + case TOK_TYPEDEF: + stop = true; + break; + // structure definition in function return type + case TOK_OPEN_CURLY: + skip_curly_block (); + break; + // array delimiter in return type + case TOK_OPEN_SQUARE: + skip_block (TOK_OPEN_SQUARE, TOK_CLOSE_SQUARE); + break; + // function parameter list + case TOK_OPEN_ROUND: + skip_round_block (); + braces = true; + break; + // names etc. + default: + token_provider->next (); + locate_token (); + break; + } + // after function parameter list + } else { + switch (token) { + // only declaration + case TOK_SEMI_COLON: + case TOK_COMMA: + case TOK_OPEN_ROUND: + stop = true; + break; + // asm declaration specifier + case TOK_ASM: + skip (); + skip_round_block (); + break; + // function body.. + case TOK_OPEN_CURLY: + result = true; + stop = true; + break; + // K&R function parameter declaration + default: + { + static int stop_tokens[] = { TOK_SEMI_COLON, 0 }; + skip (stop_tokens, true); + break; + } + } + } + } + + token_provider->set_state (s); + return result; +} + +bool CSyntax::is_ass_expr () { + State s = token_provider->get_state (); + Token *current = token_provider->current (); + if (! current) { + // This might look useless, but an aspect skips tokens in "current" + token_provider->set_state (s); + return false; + } + + // return the last result if we check the same token + if (last_look_ahead_token == current) + return last_look_ahead_result; + + last_look_ahead_token = current; + last_look_ahead_result = false; + + int token; + + bool stop = false; + while (!stop && (current = token_provider->current ())) { + token = current->type (); + + switch (token) { + case TOK_SEMI_COLON: + case TOK_COMMA: + case TOK_CLOSE_CURLY: + case TOK_CLOSE_ROUND: + case TOK_CLOSE_SQUARE: + case TOK_COLON: + case TOK_QUESTION: + stop = true; + break; + case TOK_OPEN_CURLY: + skip_curly_block (); + break; + case TOK_OPEN_ROUND: + skip_round_block (); + break; + case TOK_OPEN_SQUARE: + skip_block (TOK_OPEN_SQUARE, TOK_CLOSE_SQUARE); + break; + case TOK_ASSIGN: + case TOK_MUL_EQ: + case TOK_DIV_EQ: + case TOK_MOD_EQ: + case TOK_ADD_EQ: + case TOK_SUB_EQ: + case TOK_RSH_EQ: + case TOK_LSH_EQ: + case TOK_AND_EQ: + case TOK_XOR_EQ: + case TOK_IOR_EQ: + last_look_ahead_result = true; + stop = true; + break; + default: + skip (); + break; + } + } + + token_provider->set_state (s); + return last_look_ahead_result; +} + +/*****************************************************************************/ +/* */ +/* C G r a m m a r */ +/* */ +/*---------------------------------------------------------------------------*/ +/* */ +/* This grammar is derived from: */ +/* */ +/* International Standard */ +/* ISO/IEC 9899-1999(E) */ +/* Second edition 1999-04-01 */ +/* Programming languages - C */ +/* */ +/* and */ +/* */ +/* International Standard */ +/* ISO/IEC 14882:1998(E) */ +/* First edition 1998-09-01 */ +/* Programming languages - C++ */ +/* */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* */ +/* A . 1 K e y w o r d s */ +/* */ +/*****************************************************************************/ + +bool CSyntax::TypedefName::parse (CSyntax &s) { + // 1: ID + return s.parse (TOK_ID); +} +bool CSyntax::typedef_name () { return TypedefName::parse (*this); } + +bool CSyntax::PrivateName::parse (CSyntax &s) { + return true; +} +bool CSyntax::private_name () { return PrivateName::parse (*this); } + +/*****************************************************************************/ +/* */ +/* A . 2 L e x i c a l c o n v e n t i o n s */ +/* */ +/*****************************************************************************/ + +bool CSyntax::Identifier::parse (CSyntax &s) { + // 1: ID + return s.parse (TOK_ID); +} +bool CSyntax::identifier () { return Identifier::parse (*this); } + +bool CSyntax::Literal::parse (CSyntax &s) { + // 1: cmpd_str + // 1: TOK_INT_VAL (e.g. 4711) + // 1: TOK_ZERO_VAL (0) + // 1: TOK_CHAR_VAL (e.g. 'x') + // 1: TOK_FLT_VAL (e.g. 3.14) + static int literal_token[] = { TOK_INT_VAL, TOK_ZERO_VAL, TOK_CHAR_VAL, TOK_FLT_VAL, 0 }; + return CmpdStr::check (s) || s.parse (literal_token); +} +bool CSyntax::literal () { return Literal::parse (*this); } + +bool CSyntax::CmpdStr::parse (CSyntax &s) { + // 1+: str_literal... + return seq (s); +} +bool CSyntax::cmpd_str () { return CmpdStr::parse(*this); } + +bool CSyntax::StrLiteral::parse (CSyntax &s) { + // 1: STRING_VAL + return s.parse (TOK_STRING_VAL); +} +bool CSyntax::str_literal () { return StrLiteral::parse(*this); } + +/*****************************************************************************/ +/* */ +/* A . 3 B a s i c c o n c e p t s */ +/* */ +/*****************************************************************************/ + +bool CSyntax::TransUnit::parse (CSyntax &s) { + // 1: decl_seq + return DeclSeq::check (s); +} +bool CSyntax::trans_unit () { return TransUnit::parse(*this); } + +/*****************************************************************************/ +/* */ +/* A . 4 E x p r e s s i o n s */ +/* */ +/*****************************************************************************/ + +bool CSyntax::PrimExpr::parse (CSyntax &s) { + // 1: literal + // 1: id_expr + // 3: ( expr ) + return (Literal::check (s) || + IdExpr::check (s) || + (s.parse (TOK_OPEN_ROUND) && Expr::check (s) && s.parse (TOK_CLOSE_ROUND))); +} +bool CSyntax::prim_expr () { return PrimExpr::parse (*this); } + +bool CSyntax::IdExpr::parse (CSyntax &s) { + // 1: ID + return s.parse (TOK_ID); +} +bool CSyntax::id_expr () { return IdExpr::parse (*this); } + +bool CSyntax::CmpdLiteral::parse (CSyntax &s) { + // 5 : ( type_id ) { } + // 6 : ( type_id ) { init_list } + return (s.parse (TOK_OPEN_ROUND) && TypeId::check (s) && + s.parse (TOK_CLOSE_ROUND) && + s.parse (TOK_OPEN_CURLY) && s.opt (s.init_list()) && + s.parse (TOK_CLOSE_CURLY)); +} +bool CSyntax::cmpd_literal () { return CmpdLiteral::parse (*this); } + +bool CSyntax::PostfixExpr::parse (CSyntax &s) { + // 1 : cmpd_literal + // 1+: cmpd_literal postfix_expr1... + // 1 : prim_expr + // 1+: prim_expr postfix_expr1... + return ((CmpdLiteral::check (s) || + PrimExpr::check (s)) && + s.opt (seq (s))); +} +bool CSyntax::postfix_expr () { return PostfixExpr::parse (*this); } + +bool CSyntax::PostfixExpr1::parse (CSyntax &s) { + // 1: -- + // 1: ++ + // 2: . identifier + // 2: -> identifier + // 2: ( ) + // 3: ( expr_list ) + // 3: [ expr ] + return (s.parse (TOK_OPEN_ROUND) ? + (ExprList::check (s), s.parse (TOK_CLOSE_ROUND)) : + s.parse (TOK_OPEN_SQUARE) ? + (s.expr() && s.parse (TOK_CLOSE_SQUARE)) : + (s.parse (TOK_DECR) || s.parse (TOK_INCR) || + ((s.parse (TOK_DOT) || s.parse (TOK_PTS)) && + Identifier::check (s)))); +} +bool CSyntax::postfix_expr1 () { return PostfixExpr1::parse (*this); } + +bool CSyntax::ExprList::parse (CSyntax &s) { + // 1 : ass_expr + // 3+: ass_expr , ass_expr ... + return s.list (&CSyntax::ass_expr, TOK_COMMA); +} +bool CSyntax::expr_list () { return ExprList::parse (*this); } + +bool CSyntax::UnaryExpr::parse (CSyntax &s) { + // 1: postfix_expr + // 1: offsetof_expr + // 2: -- unary_expr + // 2: ++ unary_expr + // 2: any_unary_op cast_expr + // 2: SIZEOF unary_expr + // 2: ALIGNOF unary_expr + // 4: SIZEOF unary_expr1 + // 4: ALIGNOF unary_expr1 + static int any_unary_op[] = { TOK_AND, TOK_MUL, TOK_PLUS, TOK_MINUS, + TOK_TILDE, TOK_NOT, 0 }; + return (PostfixExpr::check (s) || + ((s.parse (TOK_DECR) || s.parse (TOK_INCR)) ? + UnaryExpr::check (s) : + s.parse (any_unary_op) ? + CastExpr::check (s) : + (s.parse (TOK_SIZEOF) || s.parse (TOK_ALIGNOF)) ? + (UnaryExpr1::check (s) || + UnaryExpr::check (s)) : + OffsetofExpr::check (s))); +} +bool CSyntax::unary_expr () { return UnaryExpr::parse (*this); } + +bool CSyntax::UnaryExpr1::parse (CSyntax &s) { + // 3: ( type_id ) + return (s.parse (TOK_OPEN_ROUND) && TypeId::check (s) && s.parse (TOK_CLOSE_ROUND)); +} +bool CSyntax::unary_expr1 () { return UnaryExpr1::parse (*this); } + +bool CSyntax::CastExpr::parse (CSyntax &s) { + // 1: cast_expr1 + // 1: unary_expr + return (CastExpr1::check (s) || UnaryExpr::check (s)); +} +bool CSyntax::cast_expr () { return CastExpr::parse (*this); } + +bool CSyntax::CastExpr1::parse (CSyntax &s) { + // 2+: cast_expr2... unary_expr + return (seq (s) && UnaryExpr::check (s)); +} +bool CSyntax::cast_expr1 () { return CastExpr1::parse (*this); } + +bool CSyntax::CastExpr2::parse (CSyntax &s) { + // 3: ( type_id ) + return (s.parse (TOK_OPEN_ROUND) && TypeId::check (s) && s.parse (TOK_CLOSE_ROUND)); +} +bool CSyntax::cast_expr2 () { return CastExpr2::parse (*this); } + +bool CSyntax::OffsetofExpr::parse (CSyntax &s) { + // 6: OFFSETOF ( type_spec , memb_designator ) + return (s.parse (TOK_OFFSETOF) && s.parse (TOK_OPEN_ROUND) && + s.type_spec () && s.parse (TOK_COMMA) && MembDesignator::check (s) && + s.parse (TOK_CLOSE_ROUND)); +} +bool CSyntax::offsetof_expr () { return OffsetofExpr::parse (*this); } + +bool CSyntax::MembDesignator::parse (CSyntax &s) { + // 1 : identifier + // 2+: identifier designator... + return (Identifier::check (s) && s.opt (s.seq (&CSyntax::designator))); +} +bool CSyntax::memb_designator () { return MembDesignator::parse (*this); } + +bool CSyntax::MulExpr::parse (CSyntax &s) { + // 1 : cast_expr + // 3+: cast_expr any_mul_op cast_expr ... + static int any_mul_op[] = { TOK_MUL, TOK_DIV, TOK_MODULO, 0 }; + return list (s, any_mul_op); +} +bool CSyntax::mul_expr () { return MulExpr::parse (*this); } + +bool CSyntax::AddExpr::parse (CSyntax &s) { + // 1 : mul_expr + // 3+: mul_expr any_add_op mul_expr ... + static int any_add_op[] = { TOK_PLUS, TOK_MINUS, 0 }; + return list (s, any_add_op); +} +bool CSyntax::add_expr () { return AddExpr::parse (*this); } + +bool CSyntax::ShiftExpr::parse (CSyntax &s) { + // 1 : add_expr + // 3+: add_expr any_shift_op add_expr ... + static int any_shift_op[] = { TOK_LSH, TOK_RSH, 0 }; + return list (s, any_shift_op); +} +bool CSyntax::shift_expr () { return ShiftExpr::parse (*this); } + +bool CSyntax::RelExpr::parse (CSyntax &s) { + // 1 : shift_expr + // 3+: shift_expr any_rel_op shift_expr ... + static int any_rel_op[] = { TOK_LESS, TOK_GREATER, TOK_LEQ, TOK_GEQ, 0 }; + return list (s, any_rel_op); +} +bool CSyntax::rel_expr () { return RelExpr::parse (*this); } + +bool CSyntax::EquExpr::parse (CSyntax &s) { + // 1 : rel_expr + // 3+: rel_expr any_equ_op rel_expr ... + static int any_equ_op[] = { TOK_EQL, TOK_NEQ, 0 }; + return list (s, any_equ_op); +} +bool CSyntax::equ_expr () { return EquExpr::parse (*this); } + +bool CSyntax::AndExpr::parse (CSyntax &s) { + // 1 : equ_expr + // 3+: equ_expr & equ_expr ... + return list (s, TOK_AND); +} +bool CSyntax::and_expr () { return AndExpr::parse (*this); } + +bool CSyntax::ExclOrExpr::parse (CSyntax &s) { + // 1 : and_expr + // 3+: and_expr ^ and_expr ... + return list (s, TOK_ROOF); +} +bool CSyntax::excl_or_expr () { return ExclOrExpr::parse (*this); } + +bool CSyntax::InclOrExpr::parse (CSyntax &s) { + // 1 : excl_or_expr + // 3+: excl_or_expr | excl_or_expr ... + return list (s, TOK_OR); +} +bool CSyntax::incl_or_expr () { return InclOrExpr::parse (*this); } + +bool CSyntax::LogAndExpr::parse (CSyntax &s) { + // 1 : incl_or_expr + // 3+: incl_or_expr && incl_or_expr ... + return list (s, TOK_AND_AND); +} +bool CSyntax::log_and_expr () { return LogAndExpr::parse (*this); } + +bool CSyntax::LogOrExpr::parse (CSyntax &s) { + // 1 : log_and_expr + // 3+: log_and_expr || log_and_expr ... + return list (s, TOK_OR_OR); +} +bool CSyntax::log_or_expr () { return LogOrExpr::parse (*this); } + +bool CSyntax::CondExpr::parse (CSyntax &s) { + // 1: log_or_expr + // 5: log_or_expr ? expr : cond_expr + return (LogOrExpr::check (s) && + (s.parse (TOK_QUESTION) ? (Expr::check (s) && + s.parse (TOK_COLON) && + CondExpr::check (s)) : true)); +} +bool CSyntax::cond_expr () { return CondExpr::parse (*this); } + +bool CSyntax::AssExpr::parse (CSyntax &s) { + // 1 : cond_expr + // 2+: ass_expr1... cond_expr + return (seq (s), CondExpr::check (s)); +} +bool CSyntax::ass_expr () { return AssExpr::parse (*this); } + +bool CSyntax::AssExpr1::parse (CSyntax &s) { + // 2: unary_expr any_ass_op + static int any_ass_op[] = { TOK_ASSIGN, TOK_MUL_EQ, TOK_DIV_EQ, TOK_MOD_EQ, + TOK_ADD_EQ, TOK_SUB_EQ, TOK_RSH_EQ, TOK_LSH_EQ, + TOK_AND_EQ, TOK_XOR_EQ, TOK_IOR_EQ, 0 }; + return (UnaryExpr::check (s) && s.parse (any_ass_op)); +} +bool CSyntax::ass_expr1 () { return AssExpr1::parse (*this); } + +bool CSyntax::Expr::parse (CSyntax &s) { + // 1 : ass_expr + // 3+: ass_expr , ass_expr ... + return list (s, TOK_COMMA); +} +bool CSyntax::expr () { return Expr::parse (*this); } + +bool CSyntax::ConstExpr::parse (CSyntax &s) { + // 1: cond_expr + return CondExpr::check (s); +} +bool CSyntax::const_expr () { return ConstExpr::parse (*this); } + +/*****************************************************************************/ +/* */ +/* A . 5 S t a t e m e n t s */ +/* */ +/*****************************************************************************/ + +bool CSyntax::Stmt::parse (CSyntax &s) { + // 1: label_stmt + // 1: expr_stmt + // 1: cmpd_stmt + // 1: select_stmt + // 1: iter_stmt + // 1: jump_stmt + // 1: asm_def + return (LabelStmt::check (s) || + ExprStmt::check (s) || + CmpdStmt::check (s) || + SelectStmt::check (s) || + IterStmt::check (s) || + JumpStmt::check (s) || + AsmDef::check (s)); +} +bool CSyntax::stmt () { return Stmt::parse (*this); } + +bool CSyntax::LabelStmt::parse (CSyntax &s) { + // 3: identifier : stmt + // 3: DEFAULT : stmt + // 4: CASE const_expr : stmt + return ((Identifier::check (s) || + s.parse (TOK_DEFAULT) || + (s.parse (TOK_CASE) && ConstExpr::check (s))) && + s.parse (TOK_COLON) && Stmt::check (s)); +} +bool CSyntax::label_stmt () { return LabelStmt::parse (*this); } + +bool CSyntax::ExprStmt::parse (CSyntax &s) { + // 1: ; + // 2: expr ; + return (Expr::check (s), s.parse (TOK_SEMI_COLON)); +} +bool CSyntax::expr_stmt () { return ExprStmt::parse (*this); } + +bool CSyntax::CmpdStmt::parse (CSyntax &s) { + // 2: { } + // 3: { stmt_seq } + if (! s.parse (TOK_OPEN_CURLY)) + return false; + s.semantic ().enter_local_scope (); // enter local (block) scope + return (StmtSeq::check (s), s.parse (TOK_CLOSE_CURLY)); +} +bool CSyntax::cmpd_stmt () { return CmpdStmt::parse (*this); } + +bool CSyntax::StmtSeq::parse (CSyntax &s) { + // 1+: stmt.. + int skip[] = { TOK_SEMI_COLON, TOK_CLOSE_CURLY, 0 }; + int finish[] = { TOK_CLOSE_CURLY, 0 }; + + if (! (BlockDecl::check (s) || catch_error (s, + "invalid statement or declaration", finish, skip))) + return false; + + while (BlockDecl::check (s) || catch_error (s, + "invalid statement or declaration", finish, skip)); + return true; +} +bool CSyntax::stmt_seq () { return StmtSeq::parse (*this); } + +bool CSyntax::SelectStmt::parse (CSyntax &s) { + // 5: SWITCH ( condition ) sub_stmt + // 5: IF ( condition ) sub_stmt + // 7: IF ( condition ) sub_stmt ELSE sub_stmt + bool is_if_stmt = s.parse (TOK_IF); + if (! ((is_if_stmt || s.parse (TOK_SWITCH)) && s.parse (TOK_OPEN_ROUND))) + return false; + s.semantic ().enter_local_scope (); // enter statement scope + return (Condition::check (s) && s.parse (TOK_CLOSE_ROUND) && + SubStmt::check (s) && + ((is_if_stmt && s.parse (TOK_ELSE)) ? // 'else' part + SubStmt::check (s) : true)); +} +bool CSyntax::select_stmt () { return SelectStmt::parse (*this); } + +bool CSyntax::SubStmt::parse (CSyntax &s) { + // 1: stmt + return Stmt::check (s); +} +bool CSyntax::sub_stmt () { return SubStmt::parse (*this); } + +bool CSyntax::Condition::parse (CSyntax &s) { + // 1: expr + return Expr::check (s); +} +bool CSyntax::condition () { return Condition::parse (*this); } + +bool CSyntax::IterStmt::parse (CSyntax &s) { + // 5: WHILE ( condition ) sub_stmt + // 6: FOR ( for_init_stmt ; ) sub_stmt + // 7: DO sub_stmt WHILE ( expr ) ; + // 7: FOR ( for_init_stmt ; expr ) sub_stmt + // 7: FOR ( for_init_stmt condition ; ) sub_stmt + // 8: FOR ( for_init_stmt condition ; expr ) sub_stmt + if (s.parse (TOK_DO)) + return (SubStmt::check (s) && + s.parse (TOK_WHILE) && s.parse (TOK_OPEN_ROUND) && + Expr::check (s) && s.parse (TOK_CLOSE_ROUND) && + s.parse (TOK_SEMI_COLON)); + s.semantic ().enter_local_scope (); // enter statement scope + return ((s.parse (TOK_WHILE) ? + (s.parse (TOK_OPEN_ROUND) && Condition::check (s)) : + (s.parse (TOK_FOR) && s.parse (TOK_OPEN_ROUND) && + ForInitStmt::check (s) && + s.opt (Condition::check (s)) && + s.parse (TOK_SEMI_COLON) && s.opt (Expr::check (s)))) && + s.parse (TOK_CLOSE_ROUND) && SubStmt::check (s)); +} +bool CSyntax::iter_stmt () { return IterStmt::parse (*this); } + +bool CSyntax::ForInitStmt::parse (CSyntax &s) { + // 1: simple_decl + // 1: expr_stmt + return (SimpleDecl::check (s) || ExprStmt::check (s)); +} +bool CSyntax::for_init_stmt () { return ForInitStmt::parse (*this); } + +bool CSyntax::JumpStmt::parse (CSyntax &s) { + // 2: BREAK ; + // 2: CONTINUE ; + // 2: RETURN ; + // 3: RETURN expression ; + // 3: GOTO identifier ; + return ((s.parse (TOK_BREAK) || + s.parse (TOK_CONTINUE) || + (s.parse (TOK_RETURN) && s.opt (Expr::check (s))) || + (s.parse (TOK_GOTO) && Identifier::check (s))) && + s.parse (TOK_SEMI_COLON)); +} +bool CSyntax::jump_stmt () { return JumpStmt::parse (*this); } + +/*****************************************************************************/ +/* */ +/* A . 6 D e c l a r a t i o n s */ +/* */ +/*****************************************************************************/ + +bool CSyntax::DeclSeq::parse (CSyntax &s) { + // 1+: decl + int skip[] = { TOK_SEMI_COLON, TOK_CLOSE_CURLY, 0 }; + int finish[] = { TOK_CLOSE_CURLY, 0 }; + + if (! s.catch_error (&CSyntax::decl_check, "invalid declaration", finish, skip)) + return false; + + while (s.catch_error (&CSyntax::decl_check, "invalid declaration", finish, skip)); + return true; +} +bool CSyntax::decl_seq () { return DeclSeq::parse (*this); } + +bool CSyntax::Decl::parse (CSyntax &s) { + // 1: block_decl + // 1: fct_def + return (s.is_fct_def () ? s.fct_def () : (BlockDecl::check (s) || s.fct_def ())); +} +bool CSyntax::decl () { return Decl::parse (*this); } +bool CSyntax::decl_check () { return Decl::check (*this); } + +bool CSyntax::BlockDecl::parse (CSyntax &s) { + // 1: simple_decl + return SimpleDecl::check (s); +} +bool CSyntax::block_decl () { return BlockDecl::parse (*this); } + +bool CSyntax::SimpleDecl::parse (CSyntax &s) { + // 1: ; + // 2: decl_spec_seq ; + // 3: decl_spec_seq init_declarator_list ; + if (s.parse (TOK_SEMI_COLON) || + ((DeclSpecSeq::check (s) || s.semantic ().implicit_int ()) && + ((! s.look_ahead (TOK_SEMI_COLON) && + InitDeclaratorList::check (s)), + s.parse (TOK_SEMI_COLON)))) { + s.semantic ().finish_decl (); + return true; + } + return false; +} +bool CSyntax::simple_decl () { return SimpleDecl::parse (*this); } + +bool CSyntax::DeclSpec::parse (CSyntax &s) { + // 1: storage_class_spec + // 1: type_spec + // 1: fct_spec + // 1: misc_spec + return (StorageClassSpec::check (s) || + s.type_spec () || + FctSpec::check (s) || + MiscSpec::check (s)); +} +bool CSyntax::decl_spec () { return DeclSpec::parse (*this); } + +bool CSyntax::MiscSpec::parse (CSyntax &s) { + // 1: TYPEDEF + return s.parse (TOK_TYPEDEF); +} +bool CSyntax::misc_spec () { return MiscSpec::parse (*this); } + +bool CSyntax::DeclSpecSeq::parse (CSyntax &s) { + // 1+: decl_spec_seq1... + return seq (s); +} +bool CSyntax::decl_spec_seq () { return DeclSpecSeq::parse (*this); } + +bool CSyntax::DeclSpecSeq1::parse (CSyntax &s) { + // 1: decl_spec + return DeclSpec::check (s); +} +bool CSyntax::decl_spec_seq1 () { return DeclSpecSeq1::parse (*this); } + +bool CSyntax::StorageClassSpec::parse (CSyntax &s) { + // 1: storage_class_specs + return (s.parse (TOK_EXTERN) || + s.parse (TOK_STATIC) || + s.parse (TOK_REGISTER) || + s.parse (TOK_AUTO)); +} +bool CSyntax::storage_class_spec () { return StorageClassSpec::parse (*this); } + +bool CSyntax::FctSpec::parse (CSyntax &s) { + // 1: INLINE + return s.parse (TOK_INLINE); +} +bool CSyntax::fct_spec () { return FctSpec::parse (*this); } + +bool CSyntax::TypeSpec::parse (CSyntax &s) { + // 1: simple_type_spec + // 1: class_spec + // 1: enum_spec + // 1: elaborated_type_spec + // 1: cv_qual + return (SimpleTypeSpec::check (s) || + s.class_spec () || + EnumSpec::check (s) || + ElaboratedTypeSpec::check (s) || + CvQual::check (s)); +} +bool CSyntax::type_spec () { return TypeSpec::parse (*this); } + +bool CSyntax::SimpleTypeSpec::parse (CSyntax &s) { + // 1: type_name + // 1: prim_types + return ((s.is_prim_type () && s.consume ()) || TypeName::check (s)); +} +bool CSyntax::simple_type_spec () { return SimpleTypeSpec::parse (*this); } + +bool CSyntax::TypeName::parse (CSyntax &s) { + // 1: typedef_name + return TypedefName::check (s); +} +bool CSyntax::type_name () { return TypeName::parse (*this); } + +bool CSyntax::ElaboratedTypeSpec::parse (CSyntax &s) { + // 2: class_key identifier + // 2: enum_key identifier + return ((ClassKey::check (s) || EnumKey::check (s)) && Identifier::check (s)); +} +bool CSyntax::elaborated_type_spec () { return ElaboratedTypeSpec::parse (*this); } + +bool CSyntax::EnumKey::parse (CSyntax &s) { + // 1: ENUM + // single token already checked by lookahead! + return s.consume (); +} +bool CSyntax::enum_key () { return EnumKey::parse (*this); } + +bool CSyntax::EnumSpec::parse (CSyntax &s) { + // 4: enum_spec1 { enumerator_list } + return (EnumSpec1::check (s) && s.parse (TOK_OPEN_CURLY) && + EnumeratorList::check (s) && s.parse (TOK_CLOSE_CURLY)); +} +bool CSyntax::enum_spec () { return EnumSpec::parse (*this); } + +bool CSyntax::EnumSpec1::parse (CSyntax &s) { + // 2: enum_key identifier + // 2: enum_key private_name + return (EnumKey::check (s) && + (Identifier::check (s) || PrivateName::check (s)) && + s.look_ahead (TOK_OPEN_CURLY)); +} +bool CSyntax::enum_spec1 () { return EnumSpec1::parse (*this); } + +bool CSyntax::EnumeratorList::parse (CSyntax &s) { + // 1 : enumerator_def + // 2 : enumerator_def , + // 3+: enumerator_def , enumerator_def ... + // 4+: enumerator_def , enumerator_def ... , + return list (s, TOK_COMMA, true); +} +bool CSyntax::enumerator_list () { return EnumeratorList::parse (*this); } + +bool CSyntax::EnumeratorDef::parse (CSyntax &s) { + // 1: enumerator + // 3: enumerator = const_expr + return (Enumerator::check (s) && + (s.parse (TOK_ASSIGN) ? ConstExpr::check (s) : true)); +} +bool CSyntax::enumerator_def () { return EnumeratorDef::parse (*this); } + +bool CSyntax::Enumerator::parse (CSyntax &s) { + // 1: identifier + return Identifier::check (s); +} +bool CSyntax::enumerator () { return Enumerator::parse (*this); } + +bool CSyntax::AsmDef::parse (CSyntax &s) { + // 1: ASM ( str_literal ) ; + return (s.parse (TOK_ASM) && + s.parse (TOK_OPEN_ROUND) && StrLiteral::check (s) && + s.parse (TOK_CLOSE_ROUND) && s.parse (TOK_SEMI_COLON)); +} +bool CSyntax::asm_def () { return AsmDef::parse (*this); } + +/*****************************************************************************/ +/* */ +/* A . 7 D e c l a r a t o r s */ +/* */ +/*****************************************************************************/ + +bool CSyntax::InitDeclaratorList::parse (CSyntax &s) { + // 1 : init_declarator + // 3+: init_declarator , init_declarator ... + return list (s, TOK_COMMA); +} +bool CSyntax::init_declarator_list () { return InitDeclaratorList::parse (*this); } + +bool CSyntax::InitDeclarator::parse (CSyntax &s) { + // 1: init_declarator1 + // 2: init_declarator1 init + return (InitDeclarator1::check (s) && s.opt (s.init ())); +} +bool CSyntax::init_declarator () { return InitDeclarator::parse (*this); } + +// TODO: do we really need this rule? (init_declarator_ext has been removed!) +bool CSyntax::InitDeclarator1::parse (CSyntax &s) { + // 1: declarator + return Declarator::check (s); +} +bool CSyntax::init_declarator1 () { return InitDeclarator1::parse (*this); } + +bool CSyntax::Declarator::parse (CSyntax &s) { + // 1 : direct_declarator + // 2+: ptr_operator.. direct_declarator + return (s.opt (seq (s)) && + DirectDeclarator::check (s)); +} +bool CSyntax::declarator () { return Declarator::parse (*this); } + +bool CSyntax::DirectDeclarator::parse (CSyntax &s) { + // 1 : declarator_id + // 2+: declarator_id direct_declarator1... + // 3 : ( declarator ) + // 3+: ( declarator ) direct_declarator1... + return ((DeclaratorId::check (s) || + (s.parse (TOK_OPEN_ROUND) && Declarator::check (s) && + s.parse (TOK_CLOSE_ROUND) && ! s.look_ahead (TOK_DOT))) && + s.opt (s.seq (&CSyntax::direct_declarator1))); +} +bool CSyntax::direct_declarator () { return DirectDeclarator::parse (*this); } + +bool CSyntax::DirectDeclarator1::parse (CSyntax &s) { + // 3: [ array_delim ] + // 3: ( identifier_list ) + // 3: ( param_decl_clause ) + return (s.parse (TOK_OPEN_ROUND) ? + ((IdentifierList::check (s) || ParamDeclClause::check (s)) && + s.parse (TOK_CLOSE_ROUND)) : + (s.parse (TOK_OPEN_SQUARE) && + ArrayDelim::check (s) && + s.parse (TOK_CLOSE_SQUARE))); +} +bool CSyntax::direct_declarator1 () { return DirectDeclarator1::parse (*this); } + +bool CSyntax::IdentifierList::parse (CSyntax &s) { + // 1 : identifier + // 3+: identifier , identifier ... + return list (s, TOK_COMMA); +} +bool CSyntax::identifier_list () { return IdentifierList::parse (*this); } + +bool CSyntax::ArrayDelim::parse (CSyntax &s) { + // 0: + // 1: * + // 1: ass_expr + // 1: cv_qual_seq + // 2: cv_qual_seq * + // 2: cv_qual_seq ass_expr + // 2: STATIC ass_expr + // 3: STATIC cv_qual_seq ass_expr + // 3: cv_qual_seq STATIC ass_expr + bool in_param_decl = s.semantic ().in_param_decl_clause (); + bool have_cv_qual = in_param_decl && CvQualSeq::check (s); + bool is_static = in_param_decl && s.parse (TOK_STATIC); + if (s.parse (TOK_MUL)) + return true; + if (! have_cv_qual && is_static) + CvQualSeq::check (s); + return (AssExpr::check (s) || ! is_static); +} +bool CSyntax::array_delim () { return ArrayDelim::parse (*this); } + +bool CSyntax::PtrOperator::parse (CSyntax &s) { + // 1: * + // 2: * cv_qual_seq + return (s.parse (TOK_MUL) && s.opt (CvQualSeq::check (s))); +} +bool CSyntax::ptr_operator () { return PtrOperator::parse (*this); } + +bool CSyntax::CvQualSeq::parse (CSyntax &s) { + // 1+: cv_qual... + return seq (s); +} +bool CSyntax::cv_qual_seq () { return CvQualSeq::parse (*this); } + +bool CSyntax::CvQual::parse (CSyntax &s) { + // 1: cv_quals + return s.is_cv_qual () && s.consume (); +} +bool CSyntax::cv_qual () { return CvQual::parse (*this); } + +bool CSyntax::DeclaratorId::parse (CSyntax &s) { + // 1: identifier + return Identifier::check (s); +} +bool CSyntax::declarator_id () { return DeclaratorId::parse (*this); } + +bool CSyntax::TypeId::parse (CSyntax &s) { + // 2: type_spec_seq abst_declarator + // 2: type_spec_seq private_name + return TypeSpecSeq::check (s) && + (s.abst_declarator () || PrivateName::check (s)); +} +bool CSyntax::type_id () { return TypeId::parse (*this); } + +bool CSyntax::TypeSpecSeq::parse (CSyntax &s) { + // 1+: type_spec_seq1... + return seq (s); +} +bool CSyntax::type_spec_seq() { return TypeSpecSeq::parse (*this); } + +bool CSyntax::TypeSpecSeq1::parse (CSyntax &s) { + // 1: type_spec + return TypeSpec::check (s); +} +bool CSyntax::type_spec_seq1() { return TypeSpecSeq1::parse (*this); } + +bool CSyntax::AbstDeclarator::parse (CSyntax &s) { + // 1 : direct_abst_declarator + // 1+: ptr_operator.. + // 2+: ptr_operator.. direct_abst_declarator + return (DirectAbstDeclarator::check (s) || + (seq (s) && + s.opt (DirectAbstDeclarator::check (s)))); +} +bool CSyntax::abst_declarator () { return AbstDeclarator::parse (*this); } + +bool CSyntax::DirectAbstDeclarator::parse (CSyntax &s) { + // 1 : direct_abst_declarator1 + // 2+: direct_abst_declarator1 direct_abst_declarator1... + // 3 : ( abst_declarator ) + // 3+: ( abst_declarator ) direct_abst_declarator1... + return ((DirectAbstDeclarator1::check (s) || + (s.parse (TOK_OPEN_ROUND) && + AbstDeclarator::check (s) && + s.parse (TOK_CLOSE_ROUND))) && + s.opt (seq (s))); +} +bool CSyntax::direct_abst_declarator () { return DirectAbstDeclarator::parse (*this); } + +bool CSyntax::DirectAbstDeclarator1::parse (CSyntax &s) { + // 2: [ ] + // 3: [ * ] + // 3: [ ass_expr ] + // 3: ( param_decl_clause ) + return (s.parse (TOK_OPEN_ROUND) ? + (ParamDeclClause::check (s), s.parse (TOK_CLOSE_ROUND)) : + (s.parse (TOK_OPEN_SQUARE) && + (AssExpr::check (s) || s.opt (s.parse (TOK_MUL))) && + s.parse (TOK_CLOSE_SQUARE))); +} +bool CSyntax::direct_abst_declarator1 () { return DirectAbstDeclarator1::parse (*this); } + +bool CSyntax::ParamDeclClause::parse (CSyntax &s) { + // 0: + // 1: param_decl_list + // 3: param_decl_list ... + return s.opt (s.param_decl_list () && s.opt (s.parse (TOK_ELLIPSIS))); +} +bool CSyntax::param_decl_clause () { return ParamDeclClause::parse (*this); } + +bool CSyntax::ParamDeclList::parse (CSyntax &s) { + // 1 : param_decl + // 2 : param_decl , + // 3+: param_decl , param_decl ... + // 4+: param_decl , param_decl ... , + return s.list (&CSyntax::param_decl, TOK_COMMA, true); +} +bool CSyntax::param_decl_list () { return ParamDeclList::parse (*this); } + +CTree *CSyntax::rule_param_decl () { + // 1: param_decl1 + if (! ParamDecl1::check (*this)) + return (CTree*)0; + semantic ().finish_decl (); + return builder ().param_decl (); +} + +bool CSyntax::param_decl () { + return parse (&CSyntax::rule_param_decl); +} + +bool CSyntax::ParamDecl1::parse (CSyntax &s) { + // 2: decl_spec_seq abst_declarator + // 2: decl_spec_seq declarator + // 2: decl_spec_seq private_name + return (DeclSpecSeq::check (s) && + (Declarator::check (s) || + AbstDeclarator::check (s) || + PrivateName::check (s))); +} +bool CSyntax::param_decl1 () { return ParamDecl1::parse (*this); } + +//CTree *CSyntax::rule_param_decl2 () { +// // 1: declarator +// semantic ().begin_param_check (); // ambiguity check +// Declarator::check (*this); +// return semantic ().finish_param_check (); +//} +// +//bool CSyntax::param_decl2 () { +// return parse (&CSyntax::rule_param_decl2); +//} + +CTree *CSyntax::rule_fct_def () { + // 2: declarator fct_body + // 3: decl_spec_seq declarator fct_body + // 4: decl_spec_seq declarator arg_decl_seq fct_body + if (! ((DeclSpecSeq::check (*this) || semantic ().implicit_int ()) && + Declarator::check (*this))) { + semantic ().finish_declarator (); + return (CTree*)0; + } + // introduce name and check scope; functions shall be + // defined only in namespace or class scope + if (! semantic ().introduce_function ()) + return (CTree*)0; + return (arg_decl_seq (), fct_body ()) ? + semantic ().finish_fct_def () : (CTree*)0; +} + +bool CSyntax::fct_def () { + return parse (&CSyntax::rule_fct_def); +} + +CTree *CSyntax::rule_arg_decl_seq () { + // 1+: simple_decl + semantic ().enter_arg_decl_seq (); + bool success = (seq (*this)); + semantic ().leave_arg_decl_seq (); + return success ? + semantic ().arg_decl_seq () : (CTree*)0; +} + +bool CSyntax::arg_decl_seq () { + return parse (&CSyntax::rule_arg_decl_seq); +} + +CTree *CSyntax::rule_fct_body () { + // 1: cmpd_stmt + return CmpdStmt::check (*this) ? builder ().fct_body () : (CTree*)0; +} + +bool CSyntax::fct_body () { + return parse (&CSyntax::rule_fct_body); +} + +CTree *CSyntax::rule_init () { + // 2: = init_clause + return (parse (TOK_ASSIGN) && init_clause ()) ? + builder ().init () : (CTree*)0; +} + +bool CSyntax::init () { + return parse (&CSyntax::rule_init); +} + +CTree *CSyntax::rule_init_clause () { + // 1: ass_expr + // 3: { init_list } + return (AssExpr::check (*this) || + (parse (TOK_OPEN_CURLY) && + init_list () && + parse (TOK_CLOSE_CURLY))) ? + builder ().init_clause () : (CTree*)0; +} + +bool CSyntax::init_clause () { + return parse (&CSyntax::rule_init_clause); +} + +CTree *CSyntax::rule_init_list () { + // 1 : init_list_item + // 2 : init_list_item , + // 3+: init_list_item , init_list_item ... + // 4+: init_list_item , init_list_item ... , + return list (&CSyntax::init_list_item, TOK_COMMA, true) ? + builder ().init_list () : (CTree*)0; +} + +bool CSyntax::init_list () { + return parse (&CSyntax::rule_init_list); +} + +CTree *CSyntax::rule_init_list_item () { + // 1: init_clause + // 2: designation init_clause + return (designation (), init_clause ()) ? + builder ().init_list_item () : (CTree*)0; +} + +bool CSyntax::init_list_item () { + return parse (&CSyntax::rule_init_list_item); +} + +CTree *CSyntax::rule_designation () { + // 2+: designator... = + return (seq (&CSyntax::designator) && parse (TOK_ASSIGN)) ? + builder ().designation () : (CTree*)0; +} + +bool CSyntax::designation () { + return parse (&CSyntax::rule_designation); +} + +CTree *CSyntax::rule_designator () { + // 2: . identifier + // 3: [ const_expr ] + return (parse (TOK_OPEN_SQUARE) ? + (ConstExpr::check (*this) && parse (TOK_CLOSE_SQUARE)) : + (parse (TOK_DOT) && identifier ())) ? + builder ().designator () : (CTree*)0; +} + +bool CSyntax::designator () { + return parse (&CSyntax::rule_designator); +} + +/*****************************************************************************/ +/* */ +/* A . 8 C l a s s e s */ +/* */ +/*****************************************************************************/ + +void CSyntax::init_class_spec () { + init_class_head (); + _class_spec_1 = _class_head_1; +} + +CTree *CSyntax::rule_class_spec () { + // 3: class_head { } + // 4: class_head { member_spec } + if (!ClassHead::check (*this)) + return (CTree*)0; + semantic ().reenter_class_scope (); + consume (); // opening bracket + return ((!look_ahead (TOK_CLOSE_CURLY) && member_spec ()), + parse (TOK_CLOSE_CURLY)) ? + semantic ().class_spec () : (CTree*)0; +} + +bool CSyntax::class_spec () { + return predict_1 (_class_spec_1) && parse (&CSyntax::rule_class_spec); +} + +bool CSyntax::ClassHead::parse (CSyntax &s) { + // 1: class_key + // 2: class_key identifier + return (ClassKey::check (s) && + (Identifier::check (s) || PrivateName::check (s)) && + s.look_ahead (TOK_OPEN_CURLY)); +} +bool CSyntax::class_head () { return ClassHead::parse (*this); } + +bool CSyntax::ClassKey::parse (CSyntax &s) { + // 1: STRUCT + // 1: UNION + // single token alread checked by lookahead! + return s.consume (); +} +bool CSyntax::class_key () { return ClassKey::parse (*this); } + +CTree *CSyntax::rule_member_spec () { + // 1+: member_decl... + int skip[] = { /*TOK_SEMI_COLON,*/ TOK_CLOSE_CURLY, 0 }; + int finish[] = { TOK_CLOSE_CURLY, 0 }; + + if (! catch_error (&CSyntax::member_decl, + "invalid member declaration", finish, skip)) + return (CTree*)0; + + while (catch_error (&CSyntax::member_decl, + "invalid member declaration", finish, skip)); + return builder ().member_spec (); +} + +bool CSyntax::member_spec () { + return parse (&CSyntax::rule_member_spec); +} + +CTree *CSyntax::rule_member_decl () { + // 3: type_spec_seq member_declarator_list ; + if (! (TypeSpecSeq::check (*this) && member_declarator_list () && + parse (TOK_SEMI_COLON))) + return (CTree*)0; + semantic ().finish_decl (); + return builder ().member_decl (); +} + +bool CSyntax::member_decl () { + return parse (&CSyntax::rule_member_decl); +} + +CTree *CSyntax::rule_member_declarator_list () { + // 1 : member_declarator + // 3+: member_declarator , member_declarator ... + return list (&CSyntax::member_declarator, TOK_COMMA) ? + builder ().member_declarator_list () : (CTree*)0; +} + +bool CSyntax::member_declarator_list () { + return parse (&CSyntax::rule_member_declarator_list); +} + +CTree *CSyntax::rule_member_declarator () { + // 1: declarator + // 3: declarator : const_expr + // 3: private_name : const_expr + bool have_declarator = Declarator::check (*this); + semantic ().finish_declarator (); + return (look_ahead (TOK_COLON) ? + ((have_declarator || PrivateName::check (*this)) && + parse (TOK_COLON) && ConstExpr::check (*this)) : + have_declarator) ? + semantic ().introduce_member () : (CTree*)0; +} + +bool CSyntax::member_declarator () { + return parse (&CSyntax::rule_member_declarator); +} + +/*****************************************************************************/ +/* */ +/* A . 9 D e r i v e d c l a s s e s */ +/* */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* */ +/* A . 1 0 S p e c i a l m e m b e r f u n c t i o n s */ +/* */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* */ +/* A . 1 1 O v e r l o a d i n g */ +/* */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* */ +/* A . 1 2 T e m p l a t e s */ +/* */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* */ +/* A . 1 3 E x c e p t i o n h a n d l i n g */ +/* */ +/*****************************************************************************/ + + +} // namespace Puma diff --git a/Puma/src/parser/cparser/CSyntax.h b/Puma/src/parser/cparser/CSyntax.h new file mode 100644 index 0000000..cbe05da --- /dev/null +++ b/Puma/src/parser/cparser/CSyntax.h @@ -0,0 +1,678 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CSyntax_h__ +#define __CSyntax_h__ + +/** \file + * Parser for the C programming language (C99). */ + +#include "Puma/Syntax.h" +#include "Puma/CBuilder.h" +#include "Puma/CSemantic.h" +#include "Puma/CTokens.h" + +namespace Puma { + + +class CSyntax : public Syntax { +public: + CSyntax (CBuilder &, CSemantic &); + virtual void configure (Config &); + + enum Grammar { GRAMMAR_C, GRAMMAR_CPLUSPLUS }; + virtual Grammar grammar () const { return GRAMMAR_C; } + +private: + CBuilder &builder () const { return (CBuilder&)Syntax::builder (); } + CSemantic &semantic () const { return (CSemantic&)Syntax::semantic (); } + +protected: + // Faster check for primitive types + tokenset _prim_types; + virtual void init_prim_types (); + bool is_prim_type () { return _prim_types[look_ahead ()]; } + + // Faster check for cv qualifiers + tokenset _cv_quals; + virtual void init_cv_quals (); + bool is_cv_qual () { return _cv_quals[look_ahead ()]; } + + // FIRST and FOLLOW sets + tokenset _class_spec_1; + + // FIRST and FOLLOW initialization + virtual void init_class_spec (); + + // result cache! + Token *last_look_ahead_token; + bool last_look_ahead_result; + + // Grammar rules + +public: + // A.1 Keywords + + struct TypedefName { + static inline bool check (CSyntax &s) { return s.typedef_name (); } + static inline bool parse (CSyntax &); + }; + virtual bool typedef_name (); + + struct PrivateName { + static inline bool check (CSyntax &s) { return s.private_name (); } + static inline bool parse (CSyntax &); + }; + virtual bool private_name (); + + // A.2 Lexical conventions + + struct Identifier { + static inline bool check (CSyntax &s) { return s.identifier (); } + static inline bool parse (CSyntax &); + }; + virtual bool identifier (); + + struct Literal { + static inline bool check (CSyntax &s) { return s.literal (); } + static bool parse (CSyntax &); + }; + virtual bool literal (); + + struct CmpdStr { + static inline bool check (CSyntax &s) { return s.cmpd_str (); } + static inline bool parse (CSyntax &); + }; + virtual bool cmpd_str (); + + struct StrLiteral { + static inline bool check (CSyntax &s) { return s.str_literal (); } + static inline bool parse (CSyntax &); + }; + virtual bool str_literal (); + + // A.3 Basic concepts + + struct TransUnit { + static inline bool check (CSyntax &s) { return s.trans_unit (); } + static inline bool parse (CSyntax &); + }; + virtual bool trans_unit (); + + // A.4 Expression + struct PrimExpr { + static inline bool check (CSyntax &s) { return s.prim_expr (); } + static bool parse (CSyntax &); + }; + virtual bool prim_expr (); + + struct IdExpr { + static inline bool check (CSyntax &s) { return s.id_expr (); } + static inline bool parse (CSyntax &); + }; + virtual bool id_expr (); + + struct CmpdLiteral { + static inline bool check (CSyntax &s) { return s.cmpd_literal (); } + static inline bool parse (CSyntax &); + }; + virtual bool cmpd_literal (); + + struct PostfixExpr { + static inline bool check (CSyntax &s) { return s.postfix_expr (); } + static inline bool parse (CSyntax &); + }; + virtual bool postfix_expr (); + + struct PostfixExpr1 { + static inline bool check (CSyntax &s) { return s.postfix_expr1 (); } + static inline bool parse (CSyntax &); + }; + virtual bool postfix_expr1 (); + + struct ExprList { + static inline bool check (CSyntax &s) { return s.expr_list (); } + static inline bool parse (CSyntax &); + }; + virtual bool expr_list (); + + struct UnaryExpr { + static inline bool check (CSyntax &s) { return s.unary_expr (); } + static inline bool parse (CSyntax &); + }; + virtual bool unary_expr (); + + struct UnaryExpr1 { + static inline bool check (CSyntax &s) { return s.unary_expr1 (); } + static inline bool parse (CSyntax &); + }; + virtual bool unary_expr1 (); + + struct CastExpr { + static inline bool check (CSyntax &s) { return s.cast_expr (); } + static inline bool parse (CSyntax &); + }; + virtual bool cast_expr (); + + struct CastExpr1 { + static inline bool check (CSyntax &s) { return s.cast_expr1 (); } + static inline bool parse (CSyntax &); + }; + virtual bool cast_expr1 (); + + struct CastExpr2 { + static inline bool check (CSyntax &s) { return s.cast_expr2 (); } + static inline bool parse (CSyntax &); + }; + virtual bool cast_expr2 (); + + struct OffsetofExpr { + static inline bool check (CSyntax &s) { return s.offsetof_expr (); } + static inline bool parse (CSyntax &); + }; + virtual bool offsetof_expr (); + + struct MembDesignator { + static inline bool check (CSyntax &s) { return s.memb_designator (); } + static inline bool parse (CSyntax &); + }; + virtual bool memb_designator (); + + struct MulExpr { + static inline bool check (CSyntax &s) { return s.mul_expr (); } + static inline bool parse (CSyntax &); + }; + virtual bool mul_expr (); + + struct AddExpr { + static inline bool check (CSyntax &s) { return s.add_expr (); } + static inline bool parse (CSyntax &); + }; + virtual bool add_expr (); + + struct ShiftExpr { + static inline bool check (CSyntax &s) { return s.shift_expr (); } + static inline bool parse (CSyntax &); + }; + virtual bool shift_expr (); + + struct RelExpr { + static inline bool check (CSyntax &s) { return s.rel_expr (); } + static inline bool parse (CSyntax &); + }; + virtual bool rel_expr (); + + struct EquExpr { + static inline bool check (CSyntax &s) { return s.equ_expr (); } + static inline bool parse (CSyntax &); + }; + virtual bool equ_expr (); + + struct AndExpr { + static inline bool check (CSyntax &s) { return s.and_expr (); } + static inline bool parse (CSyntax &); + }; + virtual bool and_expr (); + + struct ExclOrExpr { + static inline bool check (CSyntax &s) { return s.excl_or_expr (); } + static inline bool parse (CSyntax &); + }; + virtual bool excl_or_expr (); + + struct InclOrExpr { + static inline bool check (CSyntax &s) { return s.incl_or_expr (); } + static inline bool parse (CSyntax &); + }; + virtual bool incl_or_expr (); + + struct LogAndExpr { + static inline bool check (CSyntax &s) { return s.log_and_expr (); } + static inline bool parse (CSyntax &); + }; + virtual bool log_and_expr (); + + struct LogOrExpr { + static inline bool check (CSyntax &s) { return s.log_or_expr (); } + static inline bool parse (CSyntax &); + }; + virtual bool log_or_expr (); + + struct CondExpr { + static inline bool check (CSyntax &s) { return s.cond_expr (); } + static inline bool parse (CSyntax &); + }; + virtual bool cond_expr (); + + struct AssExpr { + static inline bool check (CSyntax &s) { return s.ass_expr (); } + static inline bool parse (CSyntax &); + }; + virtual bool ass_expr (); + + struct AssExpr1 { + static inline bool check (CSyntax &s) { return s.ass_expr1 (); } + static inline bool parse (CSyntax &); + }; + virtual bool ass_expr1 (); + + struct Expr { + static inline bool check (CSyntax &s) { return s.expr (); } + static inline bool parse (CSyntax &); + }; + virtual bool expr (); + + struct ConstExpr { + static inline bool check (CSyntax &s) { return s.const_expr (); } + static inline bool parse (CSyntax &); + }; + virtual bool const_expr (); + + // A.5 Statements + + struct Stmt { + static inline bool check (CSyntax &s) { return s.stmt (); } + static inline bool parse (CSyntax &); + }; + virtual bool stmt (); + + struct LabelStmt { + static inline bool check (CSyntax &s) { return s.label_stmt (); } + static inline bool parse (CSyntax &); + }; + virtual bool label_stmt (); + + struct ExprStmt { + static inline bool check (CSyntax &s) { return s.expr_stmt (); } + static inline bool parse (CSyntax &); + }; + virtual bool expr_stmt (); + + struct CmpdStmt { + static inline bool check (CSyntax &s) { return s.cmpd_stmt (); } + static inline bool parse (CSyntax &); + }; + virtual bool cmpd_stmt (); + + struct StmtSeq { + static inline bool check (CSyntax &s) { return s.stmt_seq (); } + static inline bool parse (CSyntax &); + }; + virtual bool stmt_seq (); + + struct SelectStmt { + static inline bool check (CSyntax &s) { return s.select_stmt (); } + static inline bool parse (CSyntax &); + }; + virtual bool select_stmt (); + + struct SubStmt { + static inline bool check (CSyntax &s) { return s.sub_stmt (); } + static inline bool parse (CSyntax &); + }; + virtual bool sub_stmt (); + + struct Condition { + static inline bool check (CSyntax &s) { return s.condition (); } + static inline bool parse (CSyntax &); + }; + virtual bool condition (); + + struct IterStmt { + static inline bool check (CSyntax &s) { return s.iter_stmt (); } + static inline bool parse (CSyntax &); + }; + virtual bool iter_stmt (); + + struct ForInitStmt { + static inline bool check (CSyntax &s) { return s.for_init_stmt (); } + static inline bool parse (CSyntax &); + }; + virtual bool for_init_stmt (); + + struct JumpStmt { + static inline bool check (CSyntax &s) { return s.jump_stmt (); } + static inline bool parse (CSyntax &); + }; + virtual bool jump_stmt (); + + // A.6 Declarations + + struct DeclSeq { + static inline bool check (CSyntax &s) { return s.decl_seq (); } + static inline bool parse (CSyntax &); + }; + virtual bool decl_seq (); + + struct Decl { + static inline bool check (CSyntax &s) { return s.decl (); } + static inline bool parse (CSyntax &); + }; + virtual bool decl (); + // helper function, which is needed, because ac++ can't weave in templates :-( + virtual bool decl_check (); + + struct BlockDecl { + static inline bool check (CSyntax &s) { return s.block_decl (); } + static inline bool parse (CSyntax &); + }; + virtual bool block_decl (); + + struct SimpleDecl { + static inline bool check (CSyntax &s) { return s.simple_decl (); } + static bool parse (CSyntax &); + }; + virtual bool simple_decl (); + + struct DeclSpec { + static inline bool check (CSyntax &s) { return s.decl_spec (); } + static inline bool parse (CSyntax &); + }; + virtual bool decl_spec (); + + struct DeclSpecSeq { + static inline bool check (CSyntax &s) { return s.decl_spec_seq (); } + static bool parse (CSyntax &); + }; + virtual bool decl_spec_seq (); + + struct DeclSpecSeq1 { + static inline bool check (CSyntax &s) { return s.decl_spec_seq1 (); } + static bool parse (CSyntax &); + }; + virtual bool decl_spec_seq1 (); + + struct MiscSpec { + static inline bool check (CSyntax &s) { return s.misc_spec (); } + static bool parse (CSyntax &); + }; + virtual bool misc_spec (); + + struct StorageClassSpec { + static inline bool check (CSyntax &s) { return s.storage_class_spec (); } + static bool parse (CSyntax &); + }; + virtual bool storage_class_spec (); + + struct FctSpec { + static inline bool check (CSyntax &s) { return s.fct_spec (); } + static bool parse (CSyntax &); + }; + virtual bool fct_spec (); + + struct TypeSpec { + static inline bool check (CSyntax &s) { return s.type_spec (); } + static inline bool parse (CSyntax &); + }; + virtual bool type_spec (); + + struct SimpleTypeSpec { + static inline bool check (CSyntax &s) { return s.simple_type_spec (); } + static inline bool parse (CSyntax &); + }; + virtual bool simple_type_spec (); + + struct TypeName { + static inline bool check (CSyntax &s) { return s.type_name (); } + static inline bool parse (CSyntax &); + }; + virtual bool type_name (); + + struct ElaboratedTypeSpec { + static inline bool check (CSyntax &s) { return s.elaborated_type_spec (); } + static inline bool parse (CSyntax &); + }; + virtual bool elaborated_type_spec (); + + struct EnumKey { + static inline bool check (CSyntax &s) { return s.enum_key (); } + static inline bool parse (CSyntax &); + }; + virtual bool enum_key (); + + struct EnumSpec { + static inline bool check (CSyntax &s) { return s.enum_spec (); } + static inline bool parse (CSyntax &); + }; + virtual bool enum_spec (); + + struct EnumSpec1 { + static inline bool check (CSyntax &s) { return s.enum_spec1 (); } + static inline bool parse (CSyntax &); + }; + virtual bool enum_spec1 (); + + struct EnumeratorList { + static inline bool check (CSyntax &s) { return s.enumerator_list (); } + static inline bool parse (CSyntax &); + }; + virtual bool enumerator_list (); + + struct EnumeratorDef { + static inline bool check (CSyntax &s) { return s.enumerator_def (); } + static bool parse (CSyntax &); + }; + virtual bool enumerator_def (); + + struct Enumerator { + static inline bool check (CSyntax &s) { return s.enumerator (); } + static inline bool parse (CSyntax &); + }; + virtual bool enumerator (); + + struct AsmDef { + static inline bool check (CSyntax &s) { return s.asm_def (); } + static inline bool parse (CSyntax &); + }; + virtual bool asm_def (); + + // A.7 Declarators + struct InitDeclaratorList { + static inline bool check (CSyntax &s) { return s.init_declarator_list (); } + static inline bool parse (CSyntax &); + }; + virtual bool init_declarator_list (); + + struct InitDeclarator { + static inline bool check (CSyntax &s) { return s.init_declarator (); } + static bool parse (CSyntax &); + }; + virtual bool init_declarator (); + + struct InitDeclarator1 { + static inline bool check (CSyntax &s) { return s.init_declarator1 (); } + static inline bool parse (CSyntax &); + }; + virtual bool init_declarator1 (); + + struct Declarator { + static inline bool check (CSyntax &s) { return s.declarator (); } + static inline bool parse (CSyntax &); + }; + virtual bool declarator (); + + struct DirectDeclarator { + static inline bool check (CSyntax &s) { return s.direct_declarator (); } + static inline bool parse (CSyntax &); + }; + virtual bool direct_declarator (); + + struct DirectDeclarator1 { + static inline bool check (CSyntax &s) { return s.direct_declarator1 (); } + static inline bool parse (CSyntax &); + }; + virtual bool direct_declarator1 (); + + struct IdentifierList { + static inline bool check (CSyntax &s) { return s.identifier_list (); } + static inline bool parse (CSyntax &); + }; + virtual bool identifier_list (); + + struct ArrayDelim { + static inline bool check (CSyntax &s) { return s.array_delim (); } + static inline bool parse (CSyntax &); + }; + virtual bool array_delim (); + + struct PtrOperator { + static inline bool check (CSyntax &s) { return s.ptr_operator (); } + static inline bool parse (CSyntax &); + }; + virtual bool ptr_operator (); + + struct CvQualSeq { + static inline bool check (CSyntax &s) { return s.cv_qual_seq (); } + static inline bool parse (CSyntax &); + }; + virtual bool cv_qual_seq (); + + struct CvQual { + static inline bool check (CSyntax &s) { return s.cv_qual (); } + static inline bool parse (CSyntax &); + }; + virtual bool cv_qual (); + + struct DeclaratorId { + static inline bool check (CSyntax &s) { return s.declarator_id (); } + static inline bool parse (CSyntax &); + }; + virtual bool declarator_id (); + + struct TypeId { + static inline bool check (CSyntax &s) { return s.type_id (); } + static inline bool parse (CSyntax &); + }; + virtual bool type_id (); + + struct TypeSpecSeq { + static inline bool check (CSyntax &s) { return s.type_spec_seq (); } + static inline bool parse (CSyntax &); + }; + virtual bool type_spec_seq (); + + struct TypeSpecSeq1 { + static inline bool check (CSyntax &s) { return s.type_spec_seq1 (); } + static inline bool parse (CSyntax &); + }; + virtual bool type_spec_seq1 (); + + struct AbstDeclarator { + static inline bool check (CSyntax &s) { return s.abst_declarator (); } + static inline bool parse (CSyntax &); + }; + virtual bool abst_declarator (); + + struct DirectAbstDeclarator { + static inline bool check (CSyntax &s) { return s.direct_abst_declarator (); } + static inline bool parse (CSyntax &); + }; + virtual bool direct_abst_declarator (); + + struct DirectAbstDeclarator1 { + static inline bool check (CSyntax &s) { return s.direct_abst_declarator1 (); } + static inline bool parse (CSyntax &); + }; + virtual bool direct_abst_declarator1 (); + + struct ParamDeclClause { + static inline bool check (CSyntax &s) { return s.param_decl_clause (); } + static inline bool parse (CSyntax &); + }; + virtual bool param_decl_clause (); + + struct ParamDeclList { + static inline bool check (CSyntax &s) { return s.param_decl_list (); } + static inline bool parse (CSyntax &); + }; + virtual bool param_decl_list (); + + CTree * rule_param_decl (); + virtual bool param_decl (); + + struct ParamDecl1 { + static inline bool check (CSyntax &s) { return s.param_decl1 (); } + static inline bool parse (CSyntax &); + }; + virtual bool param_decl1 (); + +// CTree * rule_param_decl2 (); +// virtual bool param_decl2 (); + CTree * rule_fct_def (); + virtual bool fct_def (); + CTree * rule_arg_decl_seq (); + virtual bool arg_decl_seq (); + CTree * rule_fct_body (); + virtual bool fct_body (); + CTree * rule_init (); + virtual bool init (); + CTree * rule_init_clause (); + virtual bool init_clause (); + CTree * rule_init_list (); + virtual bool init_list (); + CTree * rule_init_list_item (); + virtual bool init_list_item (); + CTree * rule_designation (); + virtual bool designation (); + CTree * rule_designator (); + virtual bool designator (); + + // A.8 Classes + CTree * rule_class_spec (); + virtual bool class_spec (); + + struct ClassHead { + static inline bool check (CSyntax &s) { return s.class_head (); } + static inline bool parse (CSyntax &); + }; + virtual bool class_head (); + + struct ClassKey { + static inline bool check (CSyntax &s) { return s.class_key (); } + static inline bool parse (CSyntax &); + }; + virtual bool class_key (); + + CTree * rule_member_spec (); + virtual bool member_spec (); + CTree * rule_member_decl (); + virtual bool member_decl (); + CTree * rule_member_declarator_list (); + virtual bool member_declarator_list (); + CTree * rule_member_declarator (); + virtual bool member_declarator (); + +protected: + virtual bool is_fct_def (); + virtual bool is_ass_expr (); + + virtual void handle_directive (); +}; + +inline CSyntax::CSyntax (CBuilder &b, CSemantic &s) : Syntax (b, s), + last_look_ahead_token (0), + last_look_ahead_result (false) + {} + +inline void CSyntax::handle_directive () + { Syntax::handle_directive (); } + + +} // namespace Puma + +#endif /* __CSyntax_h__ */ diff --git a/Puma/src/parser/cparser/CTokens.h b/Puma/src/parser/cparser/CTokens.h new file mode 100644 index 0000000..cc2f738 --- /dev/null +++ b/Puma/src/parser/cparser/CTokens.h @@ -0,0 +1,504 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __C_TOKENS__ +#define __C_TOKENS__ + +/** \file + * C/C++ token types. */ + +namespace Puma { + + +/** Types of tokens for language C and C++. These types + * can be compared to Puma::Token::type(). */ +enum CTokens { + //////// core tokens, i.e. numbers, operator symbols, brackets, etc. + + /** @ */ + TOK_AT = 100, + /** 0 */ + TOK_ZERO_VAL, + /** Integer constant. */ + TOK_INT_VAL, + /** Floating point constant. */ + TOK_FLT_VAL, + /** String constant. */ + TOK_STRING_VAL, + /** Character constant. */ + TOK_CHAR_VAL, + /** , */ + TOK_COMMA, + /** = */ + TOK_ASSIGN, + /** ? */ + TOK_QUESTION, + /** | */ + TOK_OR, + /** ^ */ + TOK_ROOF, + /** & */ + TOK_AND, + /** + */ + TOK_PLUS, + /** %- */ + TOK_MINUS, + /** * */ + TOK_MUL, + /** / */ + TOK_DIV, + /** % */ + TOK_MODULO, + /** < */ + TOK_LESS, + /** > */ + TOK_GREATER, + /** ( */ + TOK_OPEN_ROUND, + /** ) */ + TOK_CLOSE_ROUND, + /** [ */ + TOK_OPEN_SQUARE, + /** ] */ + TOK_CLOSE_SQUARE, + /** { */ + TOK_OPEN_CURLY, + /** } */ + TOK_CLOSE_CURLY, + /** ; */ + TOK_SEMI_COLON, + /** : */ + TOK_COLON, + /** ! */ + TOK_NOT, + /** ~ */ + TOK_TILDE, + /** "." */ + TOK_DOT, + /** *= */ + TOK_MUL_EQ, + /** /= */ + TOK_DIV_EQ, + /** %= */ + TOK_MOD_EQ, + /** += */ + TOK_ADD_EQ, + /** -= */ + TOK_SUB_EQ, + /** <<= */ + TOK_LSH_EQ, + /** >>= */ + TOK_RSH_EQ, + /** &= */ + TOK_AND_EQ, + /** ^= */ + TOK_XOR_EQ, + /** |= */ + TOK_IOR_EQ, + /** || */ + TOK_OR_OR, + /** && */ + TOK_AND_AND, + /** == */ + TOK_EQL, + /** != */ + TOK_NEQ, + /** <= */ + TOK_LEQ, + /** >= */ + TOK_GEQ, + /** << */ + TOK_LSH, + /** >> */ + TOK_RSH, + /** ".*" */ + TOK_DOT_STAR, + /** ->* */ + TOK_PTS_STAR, + /** ++ */ + TOK_INCR, + /** -- */ + TOK_DECR, + /** -> */ + TOK_PTS, + /** :: */ + TOK_COLON_COLON, + /** "..." */ + TOK_ELLIPSIS, + + /** Core token group separator for the scanner! */ + TOK_FIRST_CORE = TOK_AT, + TOK_LAST_CORE = TOK_ELLIPSIS, + + //////// C keywords + + /** asm */ + TOK_ASM, + /** auto */ + TOK_AUTO, + /** break */ + TOK_BREAK, + /** case */ + TOK_CASE, + /** char */ + TOK_CHAR, + /** const */ + TOK_CONST, + /** continue */ + TOK_CONTINUE, + /** default */ + TOK_DEFAULT, + /** do */ + TOK_DO, + /** double */ + TOK_DOUBLE, + /** else */ + TOK_ELSE, + /** enum */ + TOK_ENUM, + /** extern */ + TOK_EXTERN, + /** float */ + TOK_FLOAT, + /** for */ + TOK_FOR, + /** goto */ + TOK_GOTO, + /** if */ + TOK_IF, + /** inline */ + TOK_INLINE, + /** int */ + TOK_INT, + /** long */ + TOK_LONG, + /** register */ + TOK_REGISTER, + /** restrict */ + TOK_RESTRICT, + /** return */ + TOK_RETURN, + /** short */ + TOK_SHORT, + /** signed */ + TOK_SIGNED, + /** sizeof */ + TOK_SIZEOF, + /** static */ + TOK_STATIC, + /** struct */ + TOK_STRUCT, + /** switch */ + TOK_SWITCH, + /** typedef */ + TOK_TYPEDEF, + /** union */ + TOK_UNION, + /** unsigned */ + TOK_UNSIGNED, + /** void */ + TOK_VOID, + /** volatile */ + TOK_VOLATILE, + /** while */ + TOK_WHILE, + + /** C token group separator for the scanner! */ + TOK_FIRST_C = TOK_ASM, + TOK_LAST_C = TOK_WHILE, + + //////// Common C extension keywords + + /** __asm */ + TOK_ASM_2, + /** __inline */ + TOK_INLINE_2, + + /** Common C extension token group separator for the scanner! */ + TOK_FIRST_EXT_C = TOK_ASM_2, + TOK_LAST_EXT_C = TOK_INLINE_2, + + //////// GNU C extension keywords + + /** __alignof */ + TOK_ALIGNOF, + /** __alignof */ + TOK_ALIGNOF_2, + /** __alignof__ */ + TOK_ALIGNOF_3, + /** __asm__ */ + TOK_ASM_3, + /** _Bool */ + TOK_C_BOOL, + /** __const */ + TOK_CONST_2, + /** __const__ */ + TOK_CONST_3, + /** __inline__ */ + TOK_INLINE_3, + /** __int128 */ + TOK_INT128, + /** __builtin_offsetof */ + TOK_OFFSETOF, + /** __restrict */ + TOK_RESTRICT_2, + /** __restrict__ */ + TOK_RESTRICT_3, + /** __signed */ + TOK_SIGNED_2, + /** __signed__ */ + TOK_SIGNED_3, + /** __volatile */ + TOK_VOLATILE_2, + /** __volatile__ */ + TOK_VOLATILE_3, + /** __thread */ + TOK_THREAD, + /** typeof */ + TOK_TYPEOF, + /** __typeof */ + TOK_TYPEOF_2, + /** __typeof__ */ + TOK_TYPEOF_3, + /** __decltype */ + TOK_TYPEOF_4, + /** __attribute__ */ + TOK_ATTRIBUTE, + /** __extension__ */ + TOK_EXTENSION, + /** __psv__ */ + TOK_PSV, + /** __pmp__ */ + TOK_PMP, + /** __label__ */ + TOK_LABEL, + /** __external__ */ + TOK_EXTERNAL, + + /** GNU C extension token group separator for the scanner! */ + TOK_FIRST_GNUC = TOK_ALIGNOF, + TOK_LAST_GNUC = TOK_EXTERNAL, + + //////// Visual C/C++ extension keywords + + /** __int64 */ + TOK_INT64, + /** _cdecl */ + TOK_CDECL, + /** __cdecl */ + TOK_CDECL_2, + /** _stdcall */ + TOK_STDCALL, + /** __stdcall */ + TOK_STDCALL_2, + /** _fastcall */ + TOK_FASTCALL, + /** __fastcall */ + TOK_FASTCALL_2, + /** __if_exists */ + TOK_IF_EXISTS, + /** __if_not_exists */ + TOK_IF_NOT_EXISTS, + + /** Visual C/C++ extension token group separator for the scanner! */ + TOK_FIRST_VC = TOK_INT64, + TOK_LAST_VC = TOK_IF_NOT_EXISTS, + + //////// C++ keywords + + /** true, false */ + TOK_BOOL_VAL, + /** bool */ + TOK_BOOL, + /** catch */ + TOK_CATCH, + /** class */ + TOK_CLASS, + /** const_cast */ + TOK_CONST_CAST, + /** delete */ + TOK_DELETE, + /** dynamic_cast */ + TOK_DYN_CAST, + /** explicit */ + TOK_EXPLICIT, + /** export */ + TOK_EXPORT, + /** friend */ + TOK_FRIEND, + /** mutable */ + TOK_MUTABLE, + /** namespace */ + TOK_NAMESPACE, + /** new */ + TOK_NEW, + /** operator */ + TOK_OPERATOR, + /** private */ + TOK_PRIVATE, + /** protected */ + TOK_PROTECTED, + /** public */ + TOK_PUBLIC, + /** reinterpret_cast */ + TOK_REINT_CAST, + /** static_cast */ + TOK_STAT_CAST, + /** template */ + TOK_TEMPLATE, + /** this */ + TOK_THIS, + /** throw */ + TOK_THROW, + /** try */ + TOK_TRY, + /** typeid */ + TOK_TYPEID, + /** typename */ + TOK_TYPENAME, + /** using */ + TOK_USING, + /** virtual */ + TOK_VIRTUAL, + /** wchar_t */ + TOK_WCHAR_T, + + //////// C++ alternative representation of operators (ISO 646) + + /** and */ + TOK_AND_AND_ISO_646, + /** and_eq */ + TOK_AND_EQ_ISO_646, + /** bitand */ + TOK_AND_ISO_646, + /** bitor */ + TOK_OR_ISO_646, + /** compl */ + TOK_TILDE_ISO_646, + /** not */ + TOK_NOT_ISO_646, + /** not_eq */ + TOK_NEQ_ISO_646, + /** or */ + TOK_OR_OR_ISO_646, + /** or_eq */ + TOK_IOR_EQ_ISO_646, + /** xor */ + TOK_ROOF_ISO_646, + /** xor_eq */ + TOK_XOR_EQ_ISO_646, + + /** C++ token group separator for the scanner! */ + TOK_FIRST_CC = TOK_BOOL_VAL, + TOK_LAST_CC = TOK_XOR_EQ_ISO_646, + + //////// Common C++ extension keywords + + /** __wchar_t */ + TOK_WCHAR_T_2, + + /** Common C++ extension token group separator for the scanner! */ + TOK_FIRST_EXT_CC = TOK_WCHAR_T_2, + TOK_LAST_EXT_CC = TOK_WCHAR_T_2, + + //////// GNU C++ extension keywords + + /** GNU C++ extension token group separator for the scanner! */ + TOK_FIRST_GNUCC, + TOK_LAST_GNUCC, + + //////// C++ type trait keywords + + /** __has_nothrow_assign */ + TOK_HAS_NOTHROW_ASSIGN, + /** __has_nothrow_copy */ + TOK_HAS_NOTHROW_COPY, + /** __has_nothrow_constructor */ + TOK_HAS_NOTHROW_CTOR, + /** __has_trivial_assign */ + TOK_HAS_TRIVIAL_ASSIGN, + /** __has_trivial_copy */ + TOK_HAS_TRIVIAL_COPY, + /** __has_trivial_constructor */ + TOK_HAS_TRIVIAL_CTOR, + /** __has_trivial_destructor */ + TOK_HAS_TRIVIAL_DTOR, + /** __has_virtual_destructor */ + TOK_HAS_VIRTUAL_DTOR, + /** __is_abstract */ + TOK_IS_ABSTRACT, + /** __is_base_of */ + TOK_IS_BASE_OF, + /** __is_class */ + TOK_IS_CLASS, + /** __is_empty */ + TOK_IS_EMPTY, + /** __is_enum */ + TOK_IS_ENUM, + /** __is_pod */ + TOK_IS_POD, + /** __is_trivial */ + TOK_IS_TRIVIAL, + /** __is_polymorphic */ + TOK_IS_POLYMORPHIC, + /** __is_union */ + TOK_IS_UNION, + + /** GNU C++ extension token group separator for the scanner! */ + TOK_FIRST_TYPETRAIT = TOK_HAS_NOTHROW_ASSIGN, + TOK_LAST_TYPETRAIT = TOK_IS_UNION, + + //////// C++1X extension keywords + /** static_assert */ + TOK_STATIC_ASSERT, + + /** C++1X extension token group separator for the scanner! */ + TOK_FIRST_CC1X = TOK_STATIC_ASSERT, + TOK_LAST_CC1X = TOK_STATIC_ASSERT, + + //////// AspectC++ extension keywords + + /** pointcut */ + TOK_POINTCUT, + /** aspect */ + TOK_ASPECT, + /** advice */ + TOK_ADVICE, + /** slice */ + TOK_SLICE, + /** unknown_t */ + TOK_UNKNOWN_T, + + /** AspectC++ extension token group separator for the scanner! */ + TOK_FIRST_AC = TOK_POINTCUT, + TOK_LAST_AC = TOK_UNKNOWN_T, + + /** Any identifier that is not a keyword. */ + TOK_ID, + + // These two always have to be the ** last ** token listed here!!! + + /** Epsilon. */ + TOK_EPSILON, + /** Number of known token types. */ + TOK_NO +}; + +} // namespace Puma + +#endif /* __C_TOKENS__ */ diff --git a/Puma/src/parser/cparser/CTranslationUnit.cc b/Puma/src/parser/cparser/CTranslationUnit.cc new file mode 100644 index 0000000..f870fc4 --- /dev/null +++ b/Puma/src/parser/cparser/CTranslationUnit.cc @@ -0,0 +1,46 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CTranslationUnit.h" +#include "Puma/PreTree.h" +#include "Puma/CTree.h" + +namespace Puma { + + +CTranslationUnit::~CTranslationUnit () { + destroy (_syntax_tree); + destroy (_cpp_tree); + // destroy the unit if this is a translation unit + // of a template instance -- this is a on-the-fly + // unit, not a primary + if (_unit && _unit->isTemplateInstance()) + delete _unit; +} + +void CTranslationUnit::destroy (PreTree *tree) { + if (! tree) return; + for (int s = 0; s < tree->sons (); s++) + destroy (tree->son (s)); + for (int s = 0; s < tree->daughters (); s++) + delete tree->daughter (s); + delete tree; +} + + +} // namespace Puma diff --git a/Puma/src/parser/cparser/CTranslationUnit.h b/Puma/src/parser/cparser/CTranslationUnit.h new file mode 100644 index 0000000..b06bd67 --- /dev/null +++ b/Puma/src/parser/cparser/CTranslationUnit.h @@ -0,0 +1,99 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CTranslationUnit__ +#define __CTranslationUnit__ + +/** \file + * Abstraction of a translation unit. */ + +#include "Puma/CSemDatabase.h" +#include "Puma/UnitManager.h" +#include "Puma/CProject.h" +#include "Puma/Builder.h" +#include "Puma/Unit.h" + +namespace Puma { + + +class CTree; +class PreTree; + + +/** \class CTranslationUnit CTranslationUnit.h Puma/CTranslationUnit.h + * Abstraction of a translation unit. A translation unit is a + * single implementation file that a compiler can translate + * to an object file. In particular it contains all the code + * from included header files. + * + * A translation unit is created by the parser (see Puma::Parser). + * It encapsulates the input file and the parse results (syntax + * trees, semantic database). When it is destroyed, it also destroys + * the parse results. */ +class CTranslationUnit { + Unit *_unit; + CTree *_syntax_tree; + PreTree *_cpp_tree; + CSemDatabase _class_db; + UnitManager _local_units; + +public: + /** Constructor. + * \param u The token unit of the input file. + * \param p The project information object. */ + CTranslationUnit (Unit &u, CProject &p) : + _unit (&u), + _syntax_tree ((CTree*)0), + _cpp_tree ((PreTree*)0), + _class_db (p), + _local_units (p.err ()) {} + /** Destructor. Destroys the C/C++ syntax tree and the + * preprocessor syntax tree. The semantic information + * objects are destroyed when the semantic database + * member object is destroyed. If this is a template + * instance translation unit then destroy the unit too. */ + ~CTranslationUnit (); + + /** Set the C/C++ syntax tree. + * \param t The root node of the syntax tree. */ + void tree (CTree *t) { _syntax_tree = t; } + /** Set the preprocessor syntax tree. + * \param t The root node of the syntax tree. */ + void cpp_tree (PreTree *t) { _cpp_tree = t; } + + /** Get the C/C++ syntax tree. */ + CTree *tree () const { return _syntax_tree; } + /** Get the C preprocessor syntax tree. */ + PreTree *cpp_tree () const { return _cpp_tree; } + + /** Get the token unit of the input file. */ + Unit *unit () const { return _unit; } + /** Get the semantic information database. */ + CSemDatabase &db () const { return (CSemDatabase&)_class_db; } + /** Get the unit manager for local units (macro expansions etc). */ + UnitManager &local_units () const { return (UnitManager&)_local_units; } + +private: + void destroy (CTree *t) { Builder::destroy(t); } + void destroy (PreTree *); +}; + + +} // namespace Puma + +#endif /* __CTranslationUnit__ */ diff --git a/Puma/src/parser/cparser/CTree.cc b/Puma/src/parser/cparser/CTree.cc new file mode 100644 index 0000000..d1d8b9c --- /dev/null +++ b/Puma/src/parser/cparser/CTree.cc @@ -0,0 +1,654 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CTree.h" +#include "Puma/CConstant.h" +#include "Puma/GnuCTree.h" +#include "Puma/WinCTree.h" +#include "Puma/DelayedParseTree.h" +#include "Puma/CTokens.h" +#include "Puma/CTypeInfo.h" +#include "Puma/CObjectInfo.h" + +#include // ostringstream +#include // ostream +#include // hex, setfill, setw + +namespace Puma { + + +int CTree::alloc = 0; +int CTree::release = 0; + +CTree *CTree::Son (CTree * const *sons, int max, int num) const { + int cnt = 0; + for (int i = 0; i < max; i++) { + if (sons[i] == (CTree*)0) + continue; + if (cnt == num) + return sons[i]; + cnt++; + } + return (CTree*)0; +} + +int CTree::Sons (CTree * const *sons, int max) const { + int cnt = 0; + for (int i = 0; i < max; i++) { + if (sons[i] == (CTree*)0) + continue; + cnt++; + } + return cnt; +} + +void CTree::ReplaceSon (CTree **sons, int max, CTree *old_son, CTree *new_son) { + for (int i = 0; i < max; i++) { + if (sons[i] == old_son) { + sons[i] = new_son; + if (new_son) SetParent (new_son, this); + } + } +} + +void CTree::ReplaceSon (CTree *&son, CTree *old_son, CTree *new_son) { + if (old_son == son) { + son = new_son; + if (new_son) SetParent (new_son, this); + } +} + +void CTree::AddSon (CTree *&son, CTree *new_son) { + son = new_son; + if (new_son) SetParent (new_son, this); +} + +// find the start token +Token* CTree::token () const { + CTree *son; + Token *tok; + unsigned sons = Sons (); + + for (unsigned i = 0; i < sons; i++) { + son = Son (i); + tok = son ? son->token () : (Token*)0; + if (tok) + return tok; + } + + return (Token*)0; +} + +// find the end token +Token* CTree::end_token () const { + CTree *son; + Token *tok; + unsigned sons = Sons (); + + for (unsigned i = sons; i > 0; i--) { + son = Son (i-1); + tok = son ? son->end_token () : (Token*)0; + if (tok) + return tok; + } + + return (Token*)0; +} + +// find the start token node +CT_Token *CTree::token_node () const { + CTree *son; + CT_Token *tok; + unsigned sons = Sons (); + + for (unsigned i = 0; i < sons; i++) { + son = Son (i); + tok = son ? son->token_node () : (CT_Token*)0; + if (tok) + return tok; + } + + return (CT_Token*)0; +} + +// find the end token node +CT_Token* CTree::end_token_node () const { + CTree *son; + CT_Token *tok; + unsigned sons = Sons (); + + for (unsigned i = sons; i > 0; i--) { + son = Son (i-1); + tok = son ? son->end_token_node () : (CT_Token*)0; + if (tok) + return tok; + } + + return (CT_Token*)0; +} + +/** Return true if the tree has the constant value 0. + * \return True if constant value is 0. */ +bool CTree::HasValueNull () const { + CExprValue* v = Value(); + if (v) { + CConstant* c = v->Constant(); + return c && c->isNull(); + } + return false; +} + +int CT_List::Entries () const { + if (_properties & FORCE_EMPTY) return 0; + int n = _sons.length (); + if (_properties & OPEN) n -= 1; + if (_properties & CLOSE) n -= 1; + if (_properties & INTRO) n -= 1; + if (!(_properties & SEPARATORS)) return n; + if (!(_properties & END_SEP)) n += 1; + if (_properties & NO_LAST_SEP) n += 1; + return n / 2; +} + +CTree *CT_List::Entry (int no) const { + int n = no; + if (_properties & SEPARATORS) n *= 2; + if (_properties & OPEN) n += 1; // this is also OPEN_CLOSE + if (_properties & INTRO) n += 1; + if (no == Entries () - 1 && (_properties & NO_LAST_SEP)) n -= 1; + return _sons.lookup (n); +} + +void CT_List::AddSon (CTree *s) { + if (s) { + _son2idx[s] = _sons.length (); + _sons.append (s); + SetParent (s, this); + } +} + +void CT_List::PrefixSon (CTree *s) { + if (s) { + SonToIndexMap::iterator idx = _son2idx.begin(); + for (; idx != _son2idx.end(); ++idx) idx->second++; + _son2idx[s] = 0; + _sons.prepend (s); + SetParent (s, this); + } +} + +void CT_List::InsertSon (int idx, CTree *s) { + int len = _sons.length(); + if (s && idx <= len) { + _son2idx[s] = idx; + _sons.insert (idx, s); + for (int i = idx+1; i <= len; ++i) _son2idx[_sons[i]] = i; + SetParent (s, this); + } +} + +void CT_List::ReplaceSon (int idx, CTree *s) { + if (s && idx < Sons ()) { + _son2idx.erase(_sons[idx]); + _son2idx[s] = idx; + SetParent (_sons[idx], 0); + _sons[idx] = s; + SetParent (s, this); + } +} + +void CT_List::RemoveSon (int idx) { + int len = _sons.length(); + if (idx < len) { + _son2idx.erase(_sons[idx]); + for (int i = idx+1; i < len; ++i) _son2idx[_sons[i]]--; + SetParent (_sons[idx], 0); + _sons.remove (idx); + } +} + +void CT_List::InsertSon (CTree *before_son, CTree *new_son) { + SonToIndexMap::iterator iidx = _son2idx.find(before_son); + if (iidx != _son2idx.end()) { + int idx = iidx->second; + if (new_son) { + SetParent (new_son, this); + _son2idx[new_son] = idx; + } + _sons.insert(idx, new_son); + int len = _sons.length(); + for (int i = idx+1; i < len; ++i) _son2idx[_sons[i]]++; + } +} + +void CT_List::ReplaceSon (CTree *old_son, CTree *new_son) { + SonToIndexMap::iterator iidx = _son2idx.find(old_son); + if (iidx != _son2idx.end()) { + int idx = iidx->second; + _son2idx.erase(iidx); + if (new_son) { + _son2idx[new_son] = idx; + SetParent (new_son, this); + } + _sons[idx] = new_son; + } +} + +void CT_List::RemoveSon (CTree *son) { + SonToIndexMap::iterator iidx = _son2idx.find(son); + if (iidx != _son2idx.end()) { + int idx = iidx->second; + _son2idx.erase(iidx); + SetParent (son, 0); + _sons.remove(idx); + int len = _sons.length(); + for (int i = idx; i < len; ++i) _son2idx[_sons[i]]--; + } +} + +int CT_List::Index (CTree *son) { + SonToIndexMap::iterator idx = _son2idx.find(son); + if (idx != _son2idx.end()) + return idx->second; + return -1; +} + +void CT_DeclList::Linkage (CT_LinkageSpec *l) { + for (int e = 0; e < Entries (); e++) + ((CT_Decl*)Entry (e))->Linkage (l); +} + +void CT_PrimDeclSpec::determine_type () { + switch (_token->token ()->type ()) { + case TOK_FRIEND : _type = PDS_FRIEND ; break; + case TOK_TYPEDEF : _type = PDS_TYPEDEF ; break; + case TOK_AUTO : _type = PDS_AUTO ; break; + case TOK_REGISTER : _type = PDS_REGISTER; break; + case TOK_STATIC : _type = PDS_STATIC ; break; + case TOK_EXTERN : _type = PDS_EXTERN ; break; + case TOK_MUTABLE : _type = PDS_MUTABLE ; break; + case TOK_INLINE : _type = PDS_INLINE ; break; + case TOK_VIRTUAL : _type = PDS_VIRTUAL ; break; + case TOK_EXPLICIT : _type = PDS_EXPLICIT; break; + case TOK_CONST : _type = PDS_CONST ; break; + case TOK_VOLATILE : _type = PDS_VOLATILE; break; + case TOK_CHAR : _type = PDS_CHAR ; break; + case TOK_WCHAR_T : _type = PDS_WCHAR_T ; break; + case TOK_BOOL : _type = PDS_BOOL ; break; + case TOK_C_BOOL : _type = PDS_C_BOOL ; break; + case TOK_SHORT : _type = PDS_SHORT ; break; + case TOK_INT : _type = PDS_INT ; break; + case TOK_LONG : _type = PDS_LONG ; break; + case TOK_SIGNED : _type = PDS_SIGNED ; break; + case TOK_UNSIGNED : _type = PDS_UNSIGNED; break; + case TOK_FLOAT : _type = PDS_FLOAT ; break; + case TOK_DOUBLE : _type = PDS_DOUBLE ; break; + case TOK_VOID : _type = PDS_VOID ; break; + // GNU C specific type specifier + case TOK_INT128 : _type = PDS_INT128 ; break; + // GNU C++ specific storage class specifier + case TOK_THREAD : _type = PDS_THREAD ; break; + // AspectC++ specific type specifier + case TOK_UNKNOWN_T: _type = PDS_UNKNOWN_T; break; + // Win specific declaration specifiers + case TOK_INT64 : _type = PDS_INT64 ; break; + case TOK_CDECL : _type = PDS_CDECL ; break; + case TOK_STDCALL : _type = PDS_STDCALL ; break; + case TOK_FASTCALL : _type = PDS_FASTCALL; break; + default: _type = PDS_UNKNOWN; + } +} + +CT_SimpleName *CT_Declarator::Name () { + CT_Declarator *dummy; + return Name (dummy); +} + +CT_SimpleName *CT_Declarator::Name (CT_Declarator *&last_declarator) { + CT_SimpleName *name = Declarator ()->IsSimpleName (); + if (name) { + last_declarator = this; + return name; + } + else + return ((CT_Declarator*)Declarator ())->Name (last_declarator); +} + +CT_DestructorName::CT_DestructorName (CTree *t, CTree *n) : + CT_SpecialName (2) { + AddSon (t); + AddSon (n); + + std::ostringstream name; + name << "~" << n->token ()->text (); + Name (name.str ().c_str ()); +} + +CT_OperatorName::CT_OperatorName (CTree *op) : CT_SpecialName (1) { + AddSon (op); + _oper = op->token ()->type (); + Name (op->token ()->text ()); +} + +CT_OperatorName::CT_OperatorName (CTree *f, CTree *op, CTree *o, CTree *c) : + CT_SpecialName ((f ? 1 : 0) + (op ? 1 : 0) + (o ? 2 : 0)) { + if (f) AddSon (f); + if (op) AddSon (op); + if (o) AddSon (o); + if (c) AddSon (c); + + std::ostringstream name; + if (f) name << "operator "; + op = op ? op : o; + int oper = op->token ()->type (); + switch (oper) { + case TOK_NEW: + if (Sons () > 2) { + _oper = NEW_ARRAY; + name << "new[]"; + } else { + _oper = oper; + name << "new"; + } + break; + case TOK_DELETE: + if (Sons () > 2) { + _oper = DEL_ARRAY; + name << "delete[]"; + } else { + _oper = oper; + name << "delete"; + } + break; + case TOK_OPEN_ROUND: + _oper = FCT_CALL; + name << "()"; + break; + case TOK_OPEN_SQUARE: + _oper = SUBSCRIPT; + name << "[]"; + break; + default: + _oper = oper; + name << op->token ()->text (); + break; + } + Name (name.str ().c_str ()); +} + +CT_ConversionName::CT_ConversionName (CTree *f, CTree *t) : + CT_SpecialName (2) { + AddSon (f); + AddSon (t); + + std::ostringstream name; + name << "operator "; + TypeName ()->Object ()->TypeInfo ()->TypeText (name); + Name (name.str ().c_str ()); +} + +void CT_QualName::print (std::ostream &os) const { + int entries = Entries () - 1; + if (NodeName () == CT_RootQualName::NodeId ()) + os << "::"; + for (int i = 0; i < entries; i++) + os << ((CT_SimpleName*)Entry (i))->Text () << "::"; + os << Text (); +} + +// static syntax tree node ids + +// TODO: these extension node types shouldn't be defined here! +const char *CT_AsmBlock::NodeId () { return "AsmBlock"; } + +const char *CT_GnuAsmSpec::NodeId () { return "GnuAsmSpec"; } +const char *CT_GnuAsmDef::NodeId () { return "GnuAsmDef"; } +const char *CT_GnuAsmOperand::NodeId () { return "GnuAsmOperand"; } +const char *CT_GnuAsmOperands::NodeId () { return "GnuAsmOperands"; } +const char *CT_GnuAsmClobbers::NodeId () { return "GnuAsmClobbers"; } +const char *CT_GnuTypeof::NodeId () { return "GnuTypeof"; } +const char *CT_GnuStatementExpr::NodeId () { return "GnuStatementExpr"; } +const char *CT_GnuAttribute::NodeId () { return "GnuAttribute"; } +const char *CT_GnuLocalLabelStmt::NodeId () { return "GnuLocalLabelStmt"; } +const char *CT_GnuCaseStmt::NodeId () { return "GnuCaseStmt"; } + +const char *CT_Error::NodeId () { return "Error"; } +const char *CT_Token::NodeId () { return "Token"; } +const char *CT_ExprList::NodeId () { return "ExprList"; } +const char *CT_DeclaratorList::NodeId () { return "DeclaratorList"; } +const char *CT_EnumeratorList::NodeId () { return "EnumeratorList"; } +const char *CT_DeclList::NodeId () { return "DeclList"; } +const char *CT_DeclSpecSeq::NodeId () { return "DeclSpecSeq"; } +const char *CT_CmpdStmt::NodeId () { return "CmpdStmt"; } +const char *CT_HandlerSeq::NodeId () { return "HandlerSeq"; } +const char *CT_TemplateParamList::NodeId () { return "TemplateParamList"; } +const char *CT_TemplateArgList::NodeId () { return "TemplateArgList"; } +const char *CT_ExtensionList::NodeId () { return "ExtensionList"; } +const char *CT_Expression::NodeId() { return "Expression"; } +const char *CT_Call::NodeId() { return "Call"; } +const char *CT_ImplicitCall::NodeId() { return "ImplicitCall"; } +const char *CT_String::NodeId () { return "String"; } +const char *CT_WideString::NodeId () { return "WideString"; } +const char *CT_Integer::NodeId () { return "Integer"; } +const char *CT_Character::NodeId () { return "Character"; } +const char *CT_WideCharacter::NodeId () { return "WideCharacter"; } +const char *CT_Float::NodeId () { return "Float"; } +const char *CT_Bool::NodeId () { return "Bool"; } +const char *CT_BracedExpr::NodeId () { return "BracedExpr"; } +const char *CT_SimpleName::NodeId () { return "SimpleName"; } +const char *CT_PrivateName::NodeId () { return "PrivateName"; } +const char *CT_DestructorName::NodeId () { return "DestructorName"; } +const char *CT_TemplateName::NodeId () { return "TemplateName"; } +const char *CT_OperatorName::NodeId () { return "OperatorName"; } +const char *CT_ConversionName::NodeId () { return "ConversionName"; } +const char *CT_QualName::NodeId () { return "QualName"; } +const char *CT_RootQualName::NodeId () { return "RootQualName"; } +const char *CT_BinaryExpr::NodeId () { return "BinaryExpr"; } +const char *CT_MembPtrExpr::NodeId () { return "MembPtrExpr"; } +const char *CT_MembRefExpr::NodeId () { return "MembRefExpr"; } +const char *CT_UnaryExpr::NodeId () { return "UnaryExpr"; } +const char *CT_PostfixExpr::NodeId () { return "PostfixExpr"; } +const char *CT_AddrExpr::NodeId () { return "AddrExpr"; } +const char *CT_DerefExpr::NodeId () { return "DerefExpr"; } +const char *CT_DeleteExpr::NodeId () { return "DeleteExpr"; } +const char *CT_NewExpr::NodeId () { return "NewExpr"; } +const char *CT_IfThenExpr::NodeId () { return "IfThenExpr"; } +const char *CT_CmpdLiteral::NodeId () { return "CmpdLiteral"; } +const char *CT_ConstructExpr::NodeId () { return "ConstructExpr"; } +const char *CT_ThrowExpr::NodeId () { return "ThrowExpr"; } +const char *CT_IndexExpr::NodeId () { return "IndexExpr"; } +const char *CT_CallExpr::NodeId () { return "CallExpr"; } +const char *CT_CastExpr::NodeId () { return "CastExpr"; } +const char *CT_StaticCast::NodeId () { return "StaticCast"; } +const char *CT_ConstCast::NodeId () { return "ConstCast"; } +const char *CT_ReintCast::NodeId () { return "ReintCast"; } +const char *CT_DynamicCast::NodeId () { return "DynamicCast"; } +const char *CT_ImplicitCast::NodeId () { return "ImplicitCast"; } +const char *CT_TypeidExpr::NodeId () { return "TypeidExpr"; } +const char *CT_SizeofExpr::NodeId () { return "SizeofExpr"; } +const char *CT_AlignofExpr::NodeId () { return "AlignofExpr"; } +const char *CT_TypeTraitExpr::NodeId () { return "TypeTraitExpr"; } +const char *CT_OffsetofExpr::NodeId () { return "OffsetofExpr"; } +const char *CT_IndexDesignator::NodeId () { return "IndexDesignator"; } +const char *CT_MembDesignator::NodeId () { return "MembDesignator"; } +const char *CT_DesignatorSeq::NodeId () { return "DesignatorSeq"; } +const char *CT_PrimDeclSpec::NodeId () { return "PrimDeclSpec"; } +const char *CT_NamedType::NodeId () { return "NamedType"; } +const char *CT_ClassSpec::NodeId () { return "ClassSpec"; } +const char *CT_UnionSpec::NodeId () { return "UnionSpec"; } +const char *CT_EnumSpec::NodeId () { return "EnumSpec"; } +const char *CT_ExceptionSpec::NodeId () { return "ExceptionSpec"; } +const char *CT_Program::NodeId () { return "Program"; } +const char *CT_ObjDecl::NodeId () { return "ObjDecl"; } +const char *CT_TemplateDecl::NodeId () { return "TemplateDecl"; } +const char *CT_NonTypeParamDecl::NodeId () { return "NonTypeParamDecl"; } +const char *CT_TypeParamDecl::NodeId () { return "TypeParamDecl"; } +const char *CT_EnumDef::NodeId () { return "EnumDef"; } +const char *CT_Enumerator::NodeId () { return "Enumerator"; } +const char *CT_FctDef::NodeId () { return "FctDef"; } +const char *CT_AsmDef::NodeId () { return "AsmDef"; } +const char *CT_Handler::NodeId () { return "Handler"; } +const char *CT_LinkageSpec::NodeId () { return "LinkageSpec"; } +const char *CT_ArgDecl::NodeId () { return "ArgDecl"; } +const char *CT_ArgDeclList::NodeId () { return "ArgDeclList"; } +const char *CT_ArgDeclSeq::NodeId () { return "ArgDeclSeq"; } +const char *CT_ArgNameList::NodeId () { return "ArgNameList"; } +const char *CT_NamespaceDef::NodeId () { return "NamespaceDef"; } +const char *CT_NamespaceAliasDef::NodeId () { return "NamespaceAliasDef"; } +const char *CT_UsingDirective::NodeId () { return "UsingDirective"; } +const char *CT_InitDeclarator::NodeId () { return "InitDeclarator"; } +const char *CT_BracedDeclarator::NodeId () { return "BracedDeclarator"; } +const char *CT_ArrayDelimiter::NodeId () { return "ArrayDelimiter"; } +const char *CT_ArrayDeclarator::NodeId () { return "ArrayDeclarator"; } +const char *CT_FctDeclarator::NodeId () { return "FctDeclarator"; } +const char *CT_RefDeclarator::NodeId () { return "RefDeclarator"; } +const char *CT_PtrDeclarator::NodeId () { return "PtrDeclarator"; } +const char *CT_MembPtrDeclarator::NodeId () { return "MembPtrDeclarator"; } +const char *CT_BitFieldDeclarator::NodeId () { return "BitFieldDeclarator"; } +const char *CT_LabelStmt::NodeId () { return "LabelStmt"; } +const char *CT_DefaultStmt::NodeId () { return "DefaultStmt"; } +const char *CT_TryStmt::NodeId () { return "TryStmt"; } +const char *CT_CaseStmt::NodeId () { return "CaseStmt"; } +const char *CT_ExprStmt::NodeId () { return "ExprStmt"; } +const char *CT_DeclStmt::NodeId () { return "DeclStmt"; } +const char *CT_SwitchStmt::NodeId () { return "SwitchStmt"; } +const char *CT_IfStmt::NodeId () { return "IfStmt"; } +const char *CT_IfElseStmt::NodeId () { return "IfElseStmt"; } +const char *CT_BreakStmt::NodeId () { return "BreakStmt"; } +const char *CT_ContinueStmt::NodeId () { return "ContinueStmt"; } +const char *CT_GotoStmt::NodeId () { return "GotoStmt"; } +const char *CT_ReturnStmt::NodeId () { return "ReturnStmt"; } +const char *CT_WhileStmt::NodeId () { return "WhileStmt"; } +const char *CT_DoStmt::NodeId () { return "DoStmt"; } +const char *CT_ForStmt::NodeId () { return "ForStmt"; } +const char *CT_Condition::NodeId () { return "Condition"; } +const char *CT_ClassDef::NodeId () { return "ClassDef"; } +const char *CT_UnionDef::NodeId () { return "UnionDef"; } +const char *CT_MembList::NodeId () { return "MembList"; } +const char *CT_MembInitList::NodeId () { return "MembInitList"; } +const char *CT_MembInit::NodeId () { return "MembInit"; } +const char *CT_BaseSpecList::NodeId () { return "BaseSpecList"; } +const char *CT_AccessSpec::NodeId () { return "AccessSpec"; } +const char *CT_BaseSpec::NodeId () { return "BaseSpec"; } +const char *CT_AccessDecl::NodeId () { return "AccessDecl"; } +const char *CT_UsingDecl::NodeId () { return "UsingDecl"; } +const char *CT_Any::NodeId () { return "Any"; } +const char *CT_AnyList::NodeId () { return "AnyList"; } +const char *CT_AnyExtension::NodeId () { return "AnyExtension"; } +const char *CT_AnyCondition::NodeId () { return "AnyCondition"; } + +const char *CT_DelayedParse::NodeId () { return "DelayedParse"; } +const char *CT_DelayedParseParamInit::NodeId () { return "DelayedParseParamInit"; } +const char *CT_DelayedParseFctTryBlock::NodeId () { return "DelayedParseFctTryBlock"; } +const char *CT_DelayedParseCtorInit::NodeId () { return "DelayedParseCtorInit"; } +const char *CT_DelayedParsePureSpec::NodeId () { return "DelayedParsePureSpec"; } +const char *CT_DelayedParseFctBody::NodeId () { return "DelayedParseFctBody"; } +const char *CT_DelayedParseSkippedFctBody::NodeId () { return "DelayedParseSkippedFctBody"; } +const char *CT_DelayedParseConstInit::NodeId () { return "DelayedParseConstInit"; } + + +} // namespace Puma + +// constant size mempool +#include "Puma/ConstSizeMemPool.h" + +namespace Puma { + + +void *CT_Token::operator new (size_t n) { + assert (n == sizeof (CT_Token)); + return malloc (); +} +void CT_Token::operator delete (void *p) { + free (p); +} + +void *CT_SimpleName::operator new (size_t n) { + assert (n == sizeof (CT_SimpleName)); + return malloc (); +} +void CT_SimpleName::operator delete (void *p) { + free (p); +} + +void *CT_SpecialName::operator new (size_t n) { + assert (n == sizeof (CT_SpecialName)); + return malloc (); +} +void CT_SpecialName::operator delete (void *p) { + free (p); +} + +void *CT_PrivateName::operator new (size_t n) { + assert (n == sizeof (CT_PrivateName)); + return malloc (); +} +void CT_PrivateName::operator delete (void *p) { + free (p); +} + +void *CT_OperatorName::operator new (size_t n) { + assert (n == sizeof (CT_OperatorName)); + return malloc (); +} +void CT_OperatorName::operator delete (void *p) { + free (p); +} + +void *CT_DestructorName::operator new (size_t n) { + assert (n == sizeof (CT_DestructorName)); + return malloc (); +} +void CT_DestructorName::operator delete (void *p) { + free (p); +} + +void *CT_ConversionName::operator new (size_t n) { + assert (n == sizeof (CT_ConversionName)); + return malloc (); +} +void CT_ConversionName::operator delete (void *p) { + free (p); +} + +void *CT_TemplateName::operator new (size_t n) { + assert (n == sizeof (CT_TemplateName)); + return malloc (); +} +void CT_TemplateName::operator delete (void *p) { + free (p); +} + +void *CT_QualName::operator new (size_t n) { + assert (n == sizeof (CT_QualName)); + return malloc (); +} +void CT_QualName::operator delete (void *p) { + free (p); +} + +void *CT_RootQualName::operator new (size_t n) { + assert (n == sizeof (CT_RootQualName)); + return malloc (); +} +void CT_RootQualName::operator delete (void *p) { + free (p); +} + + +} // namespace Puma diff --git a/Puma/src/parser/cparser/CTree.h b/Puma/src/parser/cparser/CTree.h new file mode 100644 index 0000000..680361d --- /dev/null +++ b/Puma/src/parser/cparser/CTree.h @@ -0,0 +1,4571 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __CTree_h__ +#define __CTree_h__ + +/** \file + * C/C++ syntax tree classes. */ + +namespace Puma { + + +// Syntax tree node hierarchy: +class CTree; +class CT_Statement; +class CT_LabelStmt; +class CT_IfStmt; +class CT_IfElseStmt; +class CT_SwitchStmt; +class CT_BreakStmt; +class CT_ExprStmt; +class CT_WhileStmt; +class CT_DoStmt; +class CT_ForStmt; +class CT_ContinueStmt; +class CT_ReturnStmt; +class CT_GotoStmt; +class CT_DeclStmt; +class CT_CaseStmt; +class CT_DefaultStmt; +class CT_TryStmt; +class CT_Expression; +class CT_Call; +class CT_CallExpr; +class CT_ImplicitCall; +class CT_ThrowExpr; +class CT_NewExpr; +class CT_DeleteExpr; +class CT_ConstructExpr; +class CT_Integer; +class CT_Character; +class CT_WideCharacter; +class CT_Float; +class CT_Bool; +class CT_BracedExpr; +class CT_BinaryExpr; +class CT_MembPtrExpr; +class CT_MembRefExpr; +class CT_UnaryExpr; +class CT_PostfixExpr; +class CT_AddrExpr; +class CT_DerefExpr; +class CT_IfThenExpr; +class CT_CmpdLiteral; +class CT_IndexExpr; +class CT_CastExpr; +class CT_StaticCast; +class CT_ConstCast; +class CT_ReintCast; +class CT_DynamicCast; +class CT_TypeidExpr; +class CT_SizeofExpr; +class CT_AlignofExpr; +class CT_TypeTraitExpr; +class CT_OffsetofExpr; +class CT_MembDesignator; +class CT_IndexDesignator; +class CT_ImplicitCast; +class CT_MembInit; +class CT_DeclSpec; +class CT_PrimDeclSpec; +class CT_NamedType; +class CT_ClassSpec; +class CT_UnionSpec; +class CT_EnumSpec; +class CT_ExceptionSpec; +class CT_Declarator; +class CT_InitDeclarator; +class CT_BracedDeclarator; +class CT_ArrayDeclarator; +class CT_FctDeclarator; +class CT_RefDeclarator; +class CT_PtrDeclarator; +class CT_MembPtrDeclarator; +class CT_BitFieldDeclarator; +class CT_Decl; +class CT_ObjDecl; +class CT_ArgDecl; +class CT_AccessDecl; +class CT_UsingDecl; +class CT_FctDef; +class CT_AsmDef; +class CT_EnumDef; +class CT_ClassDef; +class CT_UnionDef; +class CT_Enumerator; +class CT_LinkageSpec; +class CT_Handler; +class CT_TemplateDecl; +class CT_TemplateParamDecl; +class CT_TypeParamDecl; +class CT_NonTypeParamDecl; +class CT_NamespaceDef; +class CT_NamespaceAliasDef; +class CT_UsingDirective; +class CT_Condition; +class CT_List; +class CT_CmpdStmt; +class CT_DeclSpecSeq; +class CT_HandlerSeq; +class CT_DesignatorSeq; +class CT_DeclList; +class CT_Program; +class CT_ArgDeclList; +class CT_ArgNameList; +class CT_ArgDeclSeq; +class CT_MembList; +class CT_ExprList; +class CT_DeclaratorList; +class CT_BaseSpecList; +class CT_MembInitList; +class CT_SimpleName; +class CT_SpecialName; +class CT_PrivateName; +class CT_OperatorName; +class CT_DestructorName; +class CT_ConversionName; +class CT_TemplateName; +class CT_QualName; +class CT_RootQualName; +class CT_String; +class CT_WideString; +class CT_TemplateParamList; +class CT_TemplateArgList; +class CT_ExtensionList; +class CT_Token; +class CT_Error; +class CT_DelayedParse; +class CT_BaseSpec; +class CT_AccessSpec; +class CT_ArrayDelimiter; +class CT_Any; +class CT_AnyList; +class CT_AnyExtension; +class CT_AnyCondition; + +} // namespace Puma + +#include "Puma/ErrorSeverity.h" +#include "Puma/CSemObject.h" +#include "Puma/CSemScope.h" +#include "Puma/CSemValue.h" +#include "Puma/CExprValue.h" +#include "Puma/CStrLiteral.h" +#include "Puma/CTypeInfo.h" +#include "Puma/Printable.h" +#include "Puma/CTokens.h" +#include "Puma/Token.h" + +#include +#include +#include + +namespace Puma { + + +class ErrorStream; +class CObjectInfo; +class CStructure; + +/*****************************************************************************/ +/* */ +/* S y n t a x t r e e n o d e s */ +/* */ +/*****************************************************************************/ + +/** \class CTree CTree.h Puma/CTree.h + * Base class for all C/C++ syntax tree classes. + * + * The syntax tree is the result of the syntactic analysis of the input source + * code representing its syntactic structure according to the accepted grammar + * (see class Syntax). + * + * Objects of this class and classes derived from this class are created by + * the tree builder component of %Puma during the parse process. A syntax tree + * shall be destroyed using the tree builder that has created it by calling its + * method Builder::destroy(CTree*) with the root node of the syntax tree as its + * argument. + * + * The navigation in the syntax tree is done using the methods CTree::Parent(), + * CTree::Sons(), and CTree::Son(int) const. In a syntax tree "sons" are + * understood as the syntactic child nodes of a syntax tree node, whereas + * "daughters" are understood are their semantic child nodes. + * + * Another way to traverse a syntax tree is to implement an own tree visitor + * based on class Puma::CVisitor. This is recommended especially for larger + * syntax trees. + * + * A syntax tree node can be identified by comparing its node name with the node + * identifier of the expected syntax tree node: + * \code if (node->NodeName() == Puma::CT_BinaryExpr::NodeId()) ... \endcode + * + * Based on the syntax tree further semantic analyses can be performed. Semantic + * information, like scope, value, type, and object information, is linked into + * the syntax tree. It can be accessed using the methods CTree::SemScope(), + * CTree::SemValue(), and CTree::SemObject(). Some nodes provide short-cuts to + * the semantic type and value information by implementing the methods + * CTree::Type() and CTree::Value(). + * + * The information of the syntax tree can be used to perform high-level + * transformations of the source code (see class ManipCommander). */ +class CTree { + CTree * _parent; + +public: + /*DEBUG*/static int alloc; + /*DEBUG*/static int release; + +protected: + /** Get the n-th son from given sons array. Skips empty (NULL) array items. + * \param sons The sons array. + * \param len Length of the sons array. + * \param n Index of the son. + * \return The n-th son or NULL. */ + CTree *Son (CTree * const *sons, int len, int n) const; + /** Get the number of sons in the given sons array. Skips empty (NULL) array items. + * \param sons The sons array. + * \param len Length of the sons array. */ + int Sons (CTree * const *sons, int len) const; + /** Replace a son. + * \param sons The sons array. + * \param len Length of the sons array. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree **sons, int len, CTree *old_son, CTree *new_son); + /** Replace a son if it equals the given son. + * \param son The actual son. + * \param old_son The son to replace, must match the actual son. + * \param new_son The new son, overwrites the actual son. */ + void ReplaceSon (CTree *&son, CTree *old_son, CTree *new_son); + /** Add a new son. + * \param son The actual son. + * \param new_son The new son, overwrites the actual son. */ + void AddSon (CTree *&son, CTree *new_son); + /** Set the parent tree node. + * \param parent The new parent tree node. */ + void SetParent (const CTree *parent) { _parent = (CTree*)parent; } + /** Set the parent tree node of the given tree node. + * \param node The tree node. + * \param parent The new parent. */ + void SetParent (CTree *node, const CTree *parent) { node->_parent = (CTree*)parent; } + +protected: + /** Default constructor. */ + CTree () : _parent(0) { /*DEBUG*/alloc++; } + +public: + /** Destructor. */ + virtual ~CTree () { /*DEBUG*/release++; } + /** Get the number of sons. */ + virtual int Sons () const = 0; + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + virtual CTree *Son (int n) const { return (CTree*)0; } + /** Get the node name (node identifier). */ + virtual const char *NodeName () const = 0; + /** Get the first token of the syntactic construct represented by this sub-tree. + * \return The token or NULL. */ + virtual Token *token () const; + /** Get the last token of the syntactic construct represented by this sub-tree. + * \return The token or NULL. */ + virtual Token *end_token () const; + /** Get the CT_Token node of the first token of the syntactic construct represented by this sub-tree. + * \return The token node or NULL. */ + virtual CT_Token *token_node () const; + /** Get the CT_Token node of the last token of the syntactic construct represented by this sub-tree. + * \return The token node or NULL. */ + virtual CT_Token *end_token_node () const; + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The son with which to replace. */ + virtual void ReplaceSon (CTree *old_son, CTree *new_son) {} + /** Get the parent node. + * \return The parent node or NULL. */ + virtual CTree *Parent () const { return (CTree*)_parent; } + +public: // semantic information + /** Get the semantic type of the node. + * \return The type object or NULL. */ + virtual CTypeInfo *Type () const { return (CTypeInfo*)0; } + /** Get the calculated value of the expression. + * \return The value object or NULL. */ + virtual CExprValue *Value () const { return (CExprValue*)0; } + + /** Get the scope opened by the node. + * \return The scope object or NULL. */ + virtual CSemScope *SemScope () const { return (CSemScope*)0; } + /** Get the semantic value of the node. + * \return The value object or NULL. */ + virtual CSemValue *SemValue () const { return (CSemValue*)0; } + /** Get the semantic information of the node. + * \return The semantic object or NULL. */ + virtual CSemObject *SemObject () const { return (CSemObject*)0; } + +public: // node classification function + /** Get a pointer to CT_SimpleName if the current node represents a name. + * \return The CT_SimpleName node or NULL. */ + virtual CT_SimpleName *IsSimpleName () { return 0; } + /** Get a pointer to CT_String if the current node represents a string. + * \return The CT_String node or NULL. */ + virtual CT_String *IsString () { return 0; } + /** Get a pointer to CT_Declarator if the current node represents a declarator. + * \return The CT_Declarator pointer or NULL. */ + virtual CT_Declarator *IsDeclarator () { return 0; } + /** Get a pointer to CT_Statement if the current node represents a statement. + * \return The CT_Statement pointer or NULL. */ + virtual CT_Statement *IsStatement () { return 0; } + /** Get a pointer to CT_Expression if the current node represents a expression. + * \return The CT_Expression pointer or NULL. */ + virtual CT_Expression *IsExpression () { return 0; } + /** Get a pointer to CT_Decl if the current node represents a declaration. + * \return The CT_Decl pointer or NULL. */ + virtual CT_Decl *IsDeclaration () { return 0; } + /** Get a pointer to CT_Call if the current node represents a call expression. + * \return The CT_Call pointer or NULL. */ + virtual CT_Call *IsCall () { return 0; } + /** Get a pointer to CT_List if the current node represents a list. + * \return The CT_List pointer or NULL. */ + virtual CT_List *IsList () { return 0; } + /** Get a pointer to CT_DelayedParse if the current node represents a delayed code fragment. + * \return The CT_DelayedParse pointer or NULL. */ + virtual CT_DelayedParse *IsDelayedParse () { return 0; } + +public: // additional semantic information + /** Return true if the tree has the constant value 0. + * \return True if constant value is 0. */ + bool HasValueNull () const; +}; + +/** \class CT_Error CTree.h Puma/CTree.h + * Error tree node that is inserted into the tree for syntactic constructs + * that could not be parsed. */ +class CT_Error : public CTree { +public: + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 0; } +}; + +/** \class CT_Token CTree.h Puma/CTree.h + * Tree node representing a single token in the source code. */ +class CT_Token : public CTree { + Token *_token; + unsigned long int _number; + +public: + /** Constructor. + * \param token The represented token. + * \param number The token number (a consecutive number). */ + CT_Token (Token *token, unsigned long int number = 0) : + _token (token), _number (number) {} + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 0; } + /** Get the represented token. */ + Token *token () const { return _token; } + /** Get the represented token. */ + Token *end_token () const { return _token; } + /** Get this. */ + CT_Token *token_node () const { return (CT_Token*)this; } + /** Get this. */ + CT_Token *end_token_node () const { return (CT_Token*)this; } + /** Set the token number. + * \param number The token number. */ + void Number (unsigned long int number) { _number = number; } + /** Get the token number. Can be used to indentify this token. */ + unsigned long int Number () const { return _number; } + +public: + /** Own new operator reusing memory. */ + void *operator new (size_t); + /** Own delete operator. */ + void operator delete (void *); +}; + +/*****************************************************************************/ +/* */ +/* List nodes */ +/* */ +/*****************************************************************************/ + +/** \class CT_List CTree.h Puma/CTree.h + * Base class for tree nodes representing lists. */ +class CT_List : public CTree { + /** Son to index map type. */ + typedef std::map SonToIndexMap; + + Array _sons; + int _properties; + SonToIndexMap _son2idx; + +protected: + /** Constructor. + * \param size The initial list size. + * \param incr The initial increment count. + * \param props The list properties (bit array). */ + CT_List(int size = 5, int incr = 5, int props = 0) : + _sons (size, incr), _properties (props) {} + +public: + /** %List properties. */ + enum { + /** %List has a start token, like ':' in ":a(1),b(2)" */ + OPEN = 1, + /** %List has an end token */ + CLOSE = 2, + /** %List has opening and closing delimiters, like '(' and ')' */ + OPEN_CLOSE = 3, + /** %List has separators, like ',' */ + SEPARATORS = 4, + /** %List pretend to be empty, like for "(void)" */ + FORCE_EMPTY = 8, + /** %List has trailing separator, like "a,b,c," */ + END_SEP = 16, + /** %List has no separator before last element, like "(a,b...)" */ + NO_LAST_SEP = 32, + /** %List has an introduction chararacter, like "=" in "={a,b}" */ + INTRO = 64 + }; + + /** Get a pointer to this CT_List. */ + CT_List *IsList () { return this; } + /** Get the number of list entries. */ + int Entries () const; + /** Get the n-th list entry. + * \param n The index of the entry. + * \return The list entry or NULL. */ + CTree *Entry (int n) const; + /** Get the number of sons. */ + int Sons () const { return _sons.length (); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return _sons.lookup (n); } + /** Get the index of the given son, or -1 if not found. */ + int Index (CTree *son); + /** Get the list properties. */ + int GetProperties () const { return _properties; } + /** Add a list property. + * \param p The property to add. */ + void AddProperties (int p) { _properties |= p; } + /** Add a son. + * \param s The son to add. */ + void AddSon (CTree *s); + /** Prepend a son. + * \param s The son to prepend. */ + void PrefixSon (CTree *s); + /** Insert a son before another son. + * \param before The son to insert the new son before. + * \param son The son to insert. */ + void InsertSon (CTree *before, CTree *son); + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son); + /** Remove a son. + * \param son The son to remove. */ + void RemoveSon (CTree *son); + /** Insert a son at the given index. + * \param idx The index at which to insert. + * \param s The son to insert. */ + void InsertSon (int idx, CTree *s); + /** Replace the son at the given index. + * \param idx The index of the son to replace. + * \param s The new son. */ + void ReplaceSon (int idx, CTree *s); + /** Remove the son at the given index. + * \param idx The index of the son to remove. */ + void RemoveSon (int idx); +}; + +/** \class CT_ExprList CTree.h Puma/CTree.h + * Tree node representing an expression list. */ +class CT_ExprList : public CT_List, public CSemValue, public CSemObject { +public: + /** Constructor. */ + CT_ExprList () { AddProperties (SEPARATORS); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + + /** Get the type of the last expression in the expression list. + * \return The type or NULL. */ + CTypeInfo *Type () const { return type; } + /** Get the value of the last expression in the expression list. + * \return The value of NULL. */ + CExprValue *Value () const { return value; } + /** Get the semantic value of the node. */ + CSemValue *SemValue () const { return (CSemValue*)this; } + /** Get the semantic information about the node. */ + CSemObject *SemObject () const { return (CSemObject*)this; } +}; + +/** \class CT_DeclaratorList CTree.h Puma/CTree.h + * Tree node representing a list of declarators. */ +class CT_DeclaratorList : public CT_List { +public: + /** Constructor. */ + CT_DeclaratorList () { AddProperties (SEPARATORS); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } +}; + +/** \class CT_EnumeratorList CTree.h Puma/CTree.h + * Tree node representing a list of enumerator constants. */ +class CT_EnumeratorList : public CT_List { +public: + /** Constructor. */ + CT_EnumeratorList () { AddProperties (SEPARATORS | OPEN_CLOSE); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } +}; + +/** \class CT_DeclList CTree.h Puma/CTree.h + * Tree node representing a list of declarations. */ +class CT_DeclList : public CT_List { +public: + /** Constructor. + * \param size The initial size of the list. + * \param incr The initial increment count of the list. */ + CT_DeclList (int size = 20, int incr = 20) : CT_List (size, incr) {} + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Set the linkage specifiers to each declaration in the list. + * \param l The linkage specifiers node. */ + void Linkage (CT_LinkageSpec *l); +}; + +/** \class CT_DeclSpecSeq CTree.h Puma/CTree.h + * Tree node representing a sequence of declaration specifiers. */ +class CT_DeclSpecSeq : public CT_List { +public: + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } +}; + +/** \class CT_CmpdStmt CTree.h Puma/CTree.h + * Tree node representing a compound statement. */ +class CT_CmpdStmt : public CT_List, public CSemScope { +public: + /* Constructor. */ + CT_CmpdStmt () { AddProperties (OPEN_CLOSE); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the scope opened by the compound statement. */ + CSemScope *SemScope () const { return (CSemScope*)this; } +}; + +/** \class CT_HandlerSeq CTree.h Puma/CTree.h + * Tree node representing an exception handler sequence. */ +class CT_HandlerSeq : public CT_List { +public: + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } +}; + +/** \class CT_TemplateParamList CTree.h Puma/CTree.h + * Tree node representing a template parameter list. */ +class CT_TemplateParamList : public CT_List, public CSemScope { +public: + CT_TemplateParamList () { AddProperties (INTRO | SEPARATORS | OPEN_CLOSE); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the scope opened by the template parameter list. */ + CSemScope *SemScope () const { return (CSemScope*)this; } +}; + +/** \class CT_TemplateArgList CTree.h Puma/CTree.h + * Tree node representing a template argument list. */ +class CT_TemplateArgList : public CT_List { +public: + /** Constructor. */ + CT_TemplateArgList () { AddProperties (SEPARATORS | OPEN_CLOSE); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } +}; + +/** \class CT_ExtensionList CTree.h Puma/CTree.h + * Tree node representing a sequence of compiler specific extensions such + * as __attribute__((...)) nodes. */ +class CT_ExtensionList : public CT_List { +public: + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } +}; + +/*****************************************************************************/ +/* */ +/* Expressions */ +/* */ +/*****************************************************************************/ + +/** \class CT_Expression CTree.h Puma/CTree.h + * Base class for all expression tree nodes. */ +class CT_Expression : public CTree, public CSemValue { +public: + /** Constructor. */ + CT_Expression () {} + + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 0; } + /** Get the type of the expression. + * \return The type information object or NULL. */ + CTypeInfo *Type () const { return type; } + /** Get the value of the expression. + * \return The value object or NULL. */ + CExprValue *Value () const { return value; } + /** Get the semantic value information of the expression. + * \return The value object or NULL. */ + CSemValue *SemValue () const { return (CSemValue*)this; } + /** Get this. */ + virtual CT_Expression *IsExpression () { return this; } +}; + +/** \class CT_Call CTree.h Puma/CTree.h + * Tree node representing explicit or implicit function calls + * including built-in or user-defined functions and overloaded + * operators. */ +class CT_Call : public CT_Expression, public CSemObject { +protected: + /** Constructor. */ + CT_Call () {} + +public: + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the semantic information of the call. */ + CSemObject *SemObject () const { return (CSemObject*)this; } + /** Get this. */ + CT_Call *IsCall () { return this; } +}; + +/** \class CT_ImplicitCall CTree.h Puma/CTree.h + * Tree node representing implicit function calls detected by + * the semantic analysis. + * Example: + * \code + * class Number { + * int _n; + * public: + * Number(int n) : _n(n) {} + * int operator+(const Number& n) { return n._n + _n; } + * }; + * + * Number one(1), two(2); + * one + two; // implicitely calls one.operator+(two) + * \endcode */ +class CT_ImplicitCall : public CT_Call { + CTree *_arg; + +public: + /** Constructor. + * \param arg The call argument. */ + CT_ImplicitCall (CTree *arg) { AddSon (_arg, arg); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 1; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return (n == 0) ? _arg : (CTree*)0; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) + { CTree::ReplaceSon (_arg, old_son, new_son); } +}; + +/** \class CT_String CTree.h Puma/CTree.h + * Tree node representing a string literal. + * Example: \code "abc" \endcode */ +class CT_String : public CT_List, public CSemValue { +public: + /** Constructor. + * \param size The number of sub-strings. */ + CT_String (int size) : CT_List (size, 1) {} + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + + /** Get the type of the string. + * \return The type or NULL. */ + CTypeInfo *Type () const { return type; } + /** Get the string value. + * \return The value or NULL. */ + CExprValue *Value () const { return value; } + /** Get the semantic value info object. + * \return The semantic value object or NULL. */ + CSemValue *SemValue () const { return (CSemValue*)this; } + /** Get this. */ + virtual CT_String *IsString () { return this; } +}; + +/** \class CT_WideString CTree.h Puma/CTree.h + * Tree node representing a wide string literal. + * Example: \code L"abc" \endcode */ +class CT_WideString : public CT_String { +public: + /** Constructor. + * \param size The number of sub-strings. */ + CT_WideString (int size) : CT_String (size) {} + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } +}; + +/** \class CT_Integer CTree.h Puma/CTree.h + * Tree node representing an integer constant. + * Example: \code 1234 \endcode */ +class CT_Integer : public CT_Expression { + CTree *_value; // CT_Token + +public: + /** Constructor. + * \param token The token containing the integer value. */ + CT_Integer (CTree *token) { AddSon (_value, token); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return _value ? 1 : 0; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return (n == 0) ? _value : (CTree*)0; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) + { CTree::ReplaceSon (_value, old_son, new_son); } +}; + +/** \class CT_Character CTree.h Puma/CTree.h + * Tree node representing a single character constant. + * Example: \code 'a' \endcode */ +class CT_Character : public CT_Expression { + CTree *_value; // CT_Token + +public: + /** Constructor. + * \param token The token containing the character value. */ + CT_Character (CTree *token) { AddSon (_value, token); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 1; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return (n == 0) ? _value : (CTree*)0; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) + { CTree::ReplaceSon (_value, old_son, new_son); } +}; + +/** \class CT_WideCharacter CTree.h Puma/CTree.h + * Tree node representing a wide character constant. + * Example: \code L'a' \endcode */ +class CT_WideCharacter : public CT_Character { +public: + /** Constructor. + * \param token The token containing the wide character value. */ + CT_WideCharacter (CTree *token) : CT_Character (token) {} + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } +}; + +/** \class CT_Float CTree.h Puma/CTree.h + * Tree node representing a floating point constant. + * Example: \code 12.34 \endcode */ +class CT_Float : public CT_Expression { + CTree *_value; // CT_Token + +public: + /** Constructor. + * \param token The token containing the floating point value. */ + CT_Float (CTree *token) { AddSon (_value, token); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 1; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return (n == 0) ? _value : (CTree*)0; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) + { CTree::ReplaceSon (_value, old_son, new_son); } +}; + +/** \class CT_Bool CTree.h Puma/CTree.h + * Tree node representing a boolean literal. + * Examples: + * \code + * true + * false + * \endcode */ +class CT_Bool : public CT_Expression { + CTree *_value; // CT_Token + +public: + /** Constructor. + * \param token The token containing the boolean value. */ + CT_Bool (CTree *token) { AddSon (_value, token); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 1; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return (n == 0) ? _value : (CTree*)0; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) + { CTree::ReplaceSon (_value, old_son, new_son); } +}; + +/** \class CT_BracedExpr CTree.h Puma/CTree.h + * Tree node representing a braced expression. + * Example: \code (a+b) \endcode */ +class CT_BracedExpr : public CT_Expression { + CTree *sons[3]; // open, expr, close + +public: + /** Constructor. + * \param o The opening brace. + * \param e The enclosed expression. + * \param c The closing brace. */ + CT_BracedExpr (CTree *o, CTree *e, CTree *c) { + AddSon (sons[0], o); AddSon (sons[1], e); AddSon (sons[2], c); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 3; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 3, n); } + /** Get the enclosed expression. */ + CTree *Expr () const { return sons[1]; } + /** Get the semantic value of the expression. */ + CSemValue *SemValue () const { return (CSemValue*)this; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 3, old_son, new_son); + } +}; + +/** \class CT_SimpleName CTree.h Puma/CTree.h + * Base class for all tree nodes representing a name. + * Example: \code a \endcode */ +class CT_SimpleName : public CT_List, public Printable, + public CSemValue, public CSemObject { +protected: + /** Constructor. + * \param size The number of sub-names (for qualified names). */ + CT_SimpleName (int size) : CT_List (size, 1) {} + /** Constructor. + * \param size The number of sub-names (for qualified names). + * \param properties Additional name list properties (for root qualified names). */ + CT_SimpleName (int size, int properties) : + CT_List (size, 2, properties) {} + +public: + /** Constructor. + * \param n The sub-tree containing the name. */ + CT_SimpleName (CTree *n) : CT_List (1, 1) { AddSon (n); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the string containing the name. */ + virtual const char *Text () const + { return Son (Sons ()-1)->token ()->text (); } + /** Print the name on the given stream. + * \param os The output stream. */ + virtual void print (std::ostream &os) const { os << Text (); } + /** Get this. */ + virtual CT_SimpleName *Name () const { return (CT_SimpleName*)this; } + /** Get the type of the entity represented by the name. */ + CTypeInfo *Type () const { return type; } + /** Get the value of the entity represented by the name. */ + CExprValue *Value () const { return value; } + /** Get the sematic value information of the name. */ + CSemValue *SemValue () const { return (CSemValue*)this; } + /** Get the sematic information about the name. */ + CSemObject *SemObject () const { return (CSemObject*)this; } + /** Get this. */ + virtual CT_SimpleName *IsSimpleName () { return this; } + +public: + /** Own new operator reusing memory. */ + void *operator new (size_t); + /** Own delete operator. */ + void operator delete (void *); +}; + +/** \class CT_SpecialName CTree.h Puma/CTree.h + * Base class for tree nodes representing a special name, like destructor names. */ +class CT_SpecialName : public CT_SimpleName { + char *_name; + +protected: + /** Constructor. + * \param size The number of sub-names (for qualified names). */ + CT_SpecialName (int size = 1) : CT_SimpleName (size), _name (0) {} + +public: + /** Destructor. Deletes the name string. */ + ~CT_SpecialName () { if (_name) delete[] _name; } + /** Get the string containing the name. */ + const char *Text () const { return _name; } + /** Set the name. The name is copied. + * \param n The name. */ + void Name (const char *n) { + if (n) { + _name = new char[strlen(n) + 1]; + strcpy (_name,n); + } + } + +public: + /** Own new operator reusing memory. */ + void *operator new (size_t); + /** Own delete operator. */ + void operator delete (void *); +}; + +/** \class CT_PrivateName CTree.h Puma/CTree.h + * Tree node representing a private name. Private names + * are generated names for instance for abstract declarators. + * Example: + * \code + * void foo(int*); // first parameter of foo has private name + * \endcode */ +class CT_PrivateName : public CT_SpecialName { +public: + /** Constructor. + * \param n The private (generated) name. */ + CT_PrivateName (const char *n) { Name (n); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 0; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return (CTree*)0; } + +public: + /** Own new operator reusing memory. */ + void *operator new (size_t); + /** Own delete operator. */ + void operator delete (void *); +}; + +/** \class CT_DestructorName CTree.h Puma/CTree.h + * Tree node representing a destructor name. + * Example: \code ~X \endcode */ +class CT_DestructorName : public CT_SpecialName { +public: + /** Constructor. + * \param t The tilde operator. + * \param n The class name. */ + CT_DestructorName (CTree *t, CTree *n); + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + +public: + /** Own new operator reusing memory. */ + void *operator new (size_t); + /** Own delete operator. */ + void operator delete (void *); +}; + +/** \class CT_TemplateName CTree.h Puma/CTree.h + * Tree node representing a template name. + * Example: \code X \endcode */ +class CT_TemplateName : public CT_SpecialName { +public: + /** Constructor. + * \param n The template class or function name. + * \param a The template argument list. */ + CT_TemplateName (CTree *n, CTree *a) + { AddSon (n); AddSon (a); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the template argument list. */ + CT_TemplateArgList *Arguments () const + { return (CT_TemplateArgList*)Son (Sons ()-1); } + /** Get the template class or function name. */ + CT_SimpleName *TemplateName () const + { return (CT_SimpleName*)Son (Sons ()-2); } + // may change in the future + const char *Text () const { return TemplateName ()->Text (); } + +public: + /** Own new operator reusing memory. */ + void *operator new (size_t); + /** Own delete operator. */ + void operator delete (void *); +}; + +/** \class CT_OperatorName CTree.h Puma/CTree.h + * Tree node representing the name of an overloaded operator. + * Example: \code operator== \endcode */ +class CT_OperatorName : public CT_SpecialName { + int _oper; + +public: + /** Complex operator types. */ + enum { + FCT_CALL = -100, /** Function call operator, i.e. (). */ + SUBSCRIPT, /** Array subscript operator, i.e. []. */ + NEW_ARRAY, /** New array operator, i.e. new[]. */ + DEL_ARRAY /** Delete array operator, i.e. delete[]. */ + }; + +public: + /** Constructor. + * \param op The token containing the operator. */ + CT_OperatorName (CTree *op); + /** Constructor. + * \param f The operator function keyword 'operator'. + * \param op The token containing the operator. + * \param o The token of '[' or '('. + * \param c The token of ']' or ')'. */ + CT_OperatorName (CTree *f, CTree *op, CTree *o, CTree *c); + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the operator type (either the token type or one of + * the complex operator types). */ + int Operator () const { return _oper; } + +public: + /** Own new operator reusing memory. */ + void *operator new (size_t); + /** Own delete operator. */ + void operator delete (void *); +}; + +/** \class CT_ConversionName CTree.h Puma/CTree.h + * Tree node representing the name of a conversion function. + * Example: \code operator int* \endcode */ +class CT_ConversionName : public CT_SpecialName { +public: + /** Constructor. + * \param f The operator function keyword 'operator'. + * \param t The sub-tree containing the conversion type. */ + CT_ConversionName (CTree *f, CTree *t); + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the conversion type. */ + CT_NamedType *TypeName () const { return (CT_NamedType*)Son (Sons ()-1); } + +public: + /** Own new operator reusing memory. */ + void *operator new (size_t); + /** Own delete operator. */ + void operator delete (void *); +}; + +/** \class CT_QualName CTree.h Puma/CTree.h + * Tree node representing a qualified name. + * Example: \code X::Y::Z \endcode */ +class CT_QualName : public CT_SimpleName { +public: + /** Constructor. + * \param size The initial number sub-names plus separators. */ + CT_QualName (int size = 3) : + CT_SimpleName (size, CT_List::SEPARATORS) {} + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Print the qualified name on the given stream. + * \param os The output stream. */ + void print (std::ostream &os) const; + /** Get the last name of the qualified name, e.g. Z of qualified name X::Y::Z. */ + CT_SimpleName *Name () const { return (CT_SimpleName*)Son (Sons ()-1); } + /** Get the string containing the last name of the qualified name. */ + const char *Text () const { return Name ()->Text (); } + /** Get the type of the last name. */ + CTypeInfo *Type () const { return Name ()->Type (); } + /** Get the value of the last name. */ + CExprValue *Value () const { return Name ()->Value (); } + /** Get the semantic value object of the last name. */ + CSemValue *SemValue () const { return Name ()->SemValue (); } + /** Get the semantic information of the last name. */ + CSemObject *SemObject () const { return Name ()->SemObject (); } + +public: + /** Own new operator reusing memory. */ + void *operator new (size_t); + /** Own delete operator. */ + void operator delete (void *); +}; + +/** \class CT_RootQualName CTree.h Puma/CTree.h + * Tree node representing a qualified name with introducing name separator. + * Example: \code ::X::Y::Z \endcode */ +class CT_RootQualName : public CT_QualName { +public: + /** Constructor. + * \param size Initial number of sub-name plus separator. */ + CT_RootQualName (int size = 2) : + CT_QualName (size) { AddProperties (INTRO); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + +public: + /** Own new operator reusing memory. */ + void *operator new (size_t); + /** Own delete operator. */ + void operator delete (void *); +}; + +/** \class CT_BinaryExpr CTree.h Puma/CTree.h + * Tree node representing a binary expression. + * Example: \code a+b \endcode */ +class CT_BinaryExpr : public CT_Call { + CTree *sons[3]; // expr, oper, expr + +public: + /** Constructor. + * \param l Left hand side of the expression. + * \param o The operator token. + * \param r Right hand side of the expression. */ + CT_BinaryExpr (CTree *l, CTree *o, CTree *r) { + AddSon (sons[0], l); AddSon (sons[1], o); AddSon (sons[2], r); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 3; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 3, n); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 3, old_son, new_son); + } +}; + +/** \class CT_MembPtrExpr CTree.h Puma/CTree.h + * Tree node representing a member pointer expression. + * Example: \code a->b \endcode */ +class CT_MembPtrExpr : public CT_Expression, public CSemObject { + CTree *sons[3]; // expr, oper, expr + +public: + /** Constructor. + * \param e Expression on which to call the member. + * \param o The arrow operator token. + * \param i The member name. */ + CT_MembPtrExpr (CTree *e, CTree *o, CTree *i) { + AddSon (sons[0], e); AddSon (sons[1], o); AddSon (sons[2], i); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 3; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 3, n); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 3, old_son, new_son); + } +}; + +/** \class CT_MembRefExpr CTree.h Puma/CTree.h + * Tree node representing a member reference expression. + * Example: \code a.b \endcode */ +class CT_MembRefExpr : public CT_MembPtrExpr { +public: + /** Constructor. + * \param e Expression on which to call the member. + * \param o The dot operator. + * \param i The member name. */ + CT_MembRefExpr (CTree *e, CTree *o, CTree *i) : + CT_MembPtrExpr (e, o, i) {} + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } +}; + +/** \class CT_UnaryExpr CTree.h Puma/CTree.h + * Base class for tree nodes representing unary expressions. + * Example: \code !a \endcode */ +class CT_UnaryExpr : public CT_Call { + CTree *sons[2]; // oper, expr + +public: + /** Constructor. + * \param o The unary operator. + * \param e The expression on which the operator is invoked. */ + CT_UnaryExpr (CTree *o, CTree *e) { AddSon (sons[0], o); AddSon (sons[1], e); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 2; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 2, n); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 2, old_son, new_son); + } + /** Get the expression node. */ + CTree *Expr () const { return sons[1]; } +}; + +/** \class CT_PostfixExpr CTree.h Puma/CTree.h + * Tree node representing a postfix expression. + * Example: \code a++ \endcode */ +class CT_PostfixExpr : public CT_UnaryExpr { +public: + /** Constructor. + * \param e The expression on which to invoke the operator. + * \param o The postfix operator. */ + CT_PostfixExpr (CTree *e, CTree *o) : + CT_UnaryExpr (e, o) {} + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } +}; + +/** \class CT_AddrExpr CTree.h Puma/CTree.h + * Tree node representing an address expression. + * Example: \code &a \endcode */ +class CT_AddrExpr : public CT_UnaryExpr { +public: + /** Constructor. + * \param o The address operator, i.e. '&'. + * \param e The expression from which to take the address. */ + CT_AddrExpr (CTree *o, CTree *e) : + CT_UnaryExpr (o, e) {} + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } +}; + +/** \class CT_DerefExpr CTree.h Puma/CTree.h + * Tree node representing a pointer dereferencing expression. + * Example: \code *a \endcode */ +class CT_DerefExpr : public CT_UnaryExpr { +public: + /** Constructor. + * \param o The dereferencing operator, i.e. '*'. + * \param e The expression to dereference. */ + CT_DerefExpr (CTree *o, CTree *e) : + CT_UnaryExpr (o, e) {} + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } +}; + +/** \class CT_DeleteExpr CTree.h Puma/CTree.h + * Tree node representing a delete expression. + * Example: \code delete a \endcode */ +class CT_DeleteExpr : public CT_Expression, public CSemObject { + CTree *sons[2]; // oper, expr + +public: + /** Constructor. + * \param op The delete operator. + * \param e The expression representing the object to delete. */ + CT_DeleteExpr (CTree *op, CTree *e) { AddSon (sons[0], op); AddSon (sons[1], e); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 2; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 2, n); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 2, old_son, new_son); + } + /** Get the expression. */ + CTree *Expr () const { return sons[1]; } + /** Get the operator name, i.e. 'delete' or 'delete[]'. */ + CT_SimpleName *OperName () const { return (CT_SimpleName*)sons[0]; } + /** Get the semantic information. */ + CSemObject *SemObject () const { return (CSemObject*)this; } +}; + +/** \class CT_NewExpr CTree.h Puma/CTree.h + * Tree node representing a new expression. + * Example: \code new A() \endcode */ +class CT_NewExpr : public CT_Expression, public CSemObject { + CTree *sons[6]; // oper, placement, open, type, close, init + +public: + /** Constructor. + * \param op The new operator. + * \param p The optional placement expression. + * \param o The optional left parenthesis around the type identifier. + * \param t The type identifier specifying the type of the object to create. + * \param c The optional right parenthesis around the type identifier. + * \param i The optional initializer. */ + CT_NewExpr (CTree *op, CTree *p, CTree *o, CTree *t, CTree *c, CTree *i) { + AddSon (sons[0], op); AddSon (sons[1], p); AddSon (sons[2], o); + AddSon (sons[3], t); AddSon (sons[4], c); AddSon (sons[5], i); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 6); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 6, n); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 6, old_son, new_son); + } + /** Get the operator name. */ + CT_SimpleName *OperName () const { return (CT_SimpleName*)sons[0]; } + /** Get the placement expression. */ + CT_ExprList *Placement () const { return (CT_ExprList*)sons[1];; } + /** Get the initializer. */ + CT_ExprList *Initializer () const { return (CT_ExprList*)sons[5]; } + /** Get the type of the object to create. */ + CT_NamedType *TypeName () const { return (CT_NamedType*)sons[3]; } + /** Get the semantic information. */ + CSemObject *SemObject () const { return (CSemObject*)this; } +}; + +/** \class CT_IfThenExpr CTree.h Puma/CTree.h + * Tree node representing an if-then expression. + * Example: \code a>0?a:b \endcode or \code a?:b \endcode */ +class CT_IfThenExpr : public CT_Expression { + CTree *sons[5]; // cond, oper, left, colon, right + +public: + /** Constructor. + * \param c1 The condition expression. + * \param o The question mark operator. + * \param l The expression to the left of the colon. + * \param c2 The colon operator. + * \param r The expression to the right of the colon. */ + CT_IfThenExpr (CTree *c1, CTree *o, CTree *l, CTree *c2, CTree *r) { + AddSon (sons[0], c1); AddSon (sons[1], o); AddSon (sons[2], l); + AddSon (sons[3], c2); AddSon (sons[4], r); + } + /** Constructor. + * \param c1 The condition expression. + * \param o The question mark operator. + * \param c2 The colon operator. + * \param r The expression to the right of the colon. */ + CT_IfThenExpr (CTree *c1, CTree *o, CTree *c2, CTree *r) { + AddSon (sons[0], c1); AddSon (sons[1], o); AddSon (sons[2], 0); + AddSon (sons[3], c2); AddSon (sons[4], r); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 5); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 5, n); } + /** Get the condition expression. */ + CTree *Condition () const { return sons[0]; } + /** Get the left expression (condition=true). */ + CTree *LeftOperand () const { return sons[2]; } + /** Get the right expression (condition=false). */ + CTree *RightOperand () const { return sons[4]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 5, old_son, new_son); + } +}; + +/** \class CT_CmpdLiteral CTree.h Puma/CTree.h + * Tree node representing a compound literal. + * Example: \code (int[]){1,2,3) \endcode */ +class CT_CmpdLiteral : public CT_Expression, public CSemObject { + CTree *sons[4]; // open, type, close, init + +public: + /** Constructor. + * \param r Left parenthesis of the type name. + * \param t The type name. + * \param cr Right parenthesis of the type name. + * \param i The initializer list. */ + CT_CmpdLiteral (CTree *r, CTree *t, CTree *cr, CTree *i) { + AddSon (sons[0], r); AddSon (sons[1], t); + AddSon (sons[2], cr); AddSon (sons[3], i); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 4; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 4, n); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 4, old_son, new_son); + } + /** Get the type name. */ + CT_NamedType *TypeName () const { return (CT_NamedType*)sons[1]; } + /** Get the initializer list. */ + CT_ExprList *Initializer () const { return (CT_ExprList*)sons[3]; } + /** Get the semantic information about the created object. */ + CSemObject *SemObject () const { return (CSemObject*)this; } +}; + +/** \class CT_ConstructExpr CTree.h Puma/CTree.h + * Tree node representing a construct expression. + * Example: \code std::string("abc") \endcode */ +class CT_ConstructExpr : public CT_Expression, public CSemObject { + CTree *sons[2]; // type, init + +public: + /** Constructor. + * \param t The type name. + * \param i The initializer list. */ + CT_ConstructExpr (CTree *t, CTree *i) { AddSon (sons[0], t); AddSon (sons[1], i); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 2; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 2, n); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 2, old_son, new_son); + } + /** Get the type name. */ + CT_NamedType *TypeName () const { return (CT_NamedType*)sons[0]; } + /** Get the initializer. */ + CT_ExprList *Initializer () const { return (CT_ExprList*)sons[1]; } + /** Get the semantic information about the created object. */ + CSemObject *SemObject () const { return (CSemObject*)this; } +}; + +/** \class CT_ThrowExpr CTree.h Puma/CTree.h + * Tree node representing a throw expression. + * Example: \code throw std::exception() \endcode */ +class CT_ThrowExpr : public CT_Expression { + CTree *sons[2]; // throw, expr + +public: + /** Constructor. + * \param t The 'throw' keyword. + * \param e The expression. */ + CT_ThrowExpr (CTree *t, CTree *e = (CTree*)0) { AddSon (sons[0], t); AddSon (sons[1], e); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 2); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 2, n); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 2, old_son, new_son); + } + /** Get the expression. */ + CTree *Expr () const { return sons[1]; } +}; + +/** \class CT_IndexExpr CTree.h Puma/CTree.h + * Tree node representing an index expression. + * Example: \code a[1] \endcode */ +class CT_IndexExpr : public CT_Call { + CTree *sons[4]; // expr, open, index, close + +public: + /** Constructor. + * \param e The expression on which to invoke the index operator. + * \param o Left parenthesis of the index expression. + * \param i The index expression. + * \param c Right parenthesis of the index expression. */ + CT_IndexExpr (CTree *e, CTree *o, CTree *i, CTree *c) { + AddSon (sons[0], e); AddSon (sons[1], o); + AddSon (sons[2], i); AddSon (sons[3], c); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 4; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 4, n); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 4, old_son, new_son); + } +}; + +/** \class CT_CallExpr CTree.h Puma/CTree.h + * Tree node representing a function call expression. + * Example: \code f(i) \endcode */ +class CT_CallExpr : public CT_Call { + CTree *sons[2]; // expr, args + +public: + /** Constructor. + * \param e The expression on which the call is invoked. */ + CT_CallExpr (CTree *e) { AddSon (sons[0], e); AddSon (sons[1], 0); } + /** Constructor. + * \param e The expression on which the call is invoked. + * \param l The argument list of the call. */ + CT_CallExpr (CTree *e, CTree *l) { AddSon (sons[0], e); AddSon (sons[1], l); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 2); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 2, n); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 2, old_son, new_son); + } + CTree *Expr () const { return sons[0]; } + CT_ExprList *Arguments () const { return (CT_ExprList*)sons[1]; } +}; + +/** \class CT_CastExpr CTree.h Puma/CTree.h + * Tree node representing a cast expression. + * Example: \code (int)a \endcode */ +class CT_CastExpr : public CT_Expression { + CTree *sons[4]; // open, type, close, expr + +public: + /** Constructor. + * \param o Left parenthesis of the type name. + * \param t The type to cast to. + * \param c Right parenthesis of the type name. + * \param e The expression to cast. */ + CT_CastExpr (CTree *o, CTree *t, CTree *c, CTree *e) { + AddSon (sons[0], o); AddSon (sons[1], t); + AddSon (sons[2], c); AddSon (sons[3], e); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 4; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 4, n); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 4, old_son, new_son); + } + /** Get the casted expression. */ + CTree *Expr () const { return sons[3]; } + /** Get the type to cast to. */ + CT_NamedType *TypeName () const { return (CT_NamedType*)sons[1]; } +}; + +/** \class CT_StaticCast CTree.h Puma/CTree.h + * Tree node representing a static cast. + * Example: \code static_cast(a) \endcode */ +class CT_StaticCast : public CT_Expression { + CTree *sons[5]; // cast, open, type, close, expr + +public: + /** Constructor. + * \param cst The cast operator, i.e. 'static_cast'. + * \param o Left arrow bracket of the type name. + * \param t The type to cast to. + * \param c Right array bracket of the type name. + * \param e The expression to cast. */ + CT_StaticCast (CTree *cst, CTree *o, CTree *t, CTree *c, CTree *e) { + AddSon (sons[0], cst); AddSon (sons[1], o); AddSon (sons[2], t); + AddSon (sons[3], c); AddSon (sons[4], e); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 5; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 5, n); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 5, old_son, new_son); + } + /** Get the casted expression. */ + CTree *Expr () const { return sons[4]; } + /** Get the type to cast to. */ + CT_NamedType *TypeName () const { return (CT_NamedType*)sons[2]; } +}; + +/** \class CT_ConstCast CTree.h Puma/CTree.h + * Tree node representing a const cast. + * Example: \code const_cast(a) \endcode */ +class CT_ConstCast : public CT_StaticCast { +public: + /** Constructor. + * \param cst The cast operator, i.e. 'const_cast'. + * \param o Left arrow bracket of the type name. + * \param t The type to cast to. + * \param c Right array bracket of the type name. + * \param e The expression to cast. */ + CT_ConstCast (CTree *cst, CTree *o, CTree *t, CTree *c, CTree *e) : + CT_StaticCast (cst, o, t, c, e) {} + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } +}; + +/** \class CT_ReintCast CTree.h Puma/CTree.h + * Tree node representing a reinterpret cast. + * Example: \code reinterpret_cast(a) \endcode */ +class CT_ReintCast : public CT_StaticCast { +public: + /** Constructor. + * \param cst The cast operator, i.e. 'reinterpret_cast'. + * \param o Left arrow bracket of the type name. + * \param t The type to cast to. + * \param c Right array bracket of the type name. + * \param e The expression to cast. */ + CT_ReintCast (CTree *cst, CTree *o, CTree *t, CTree *c, CTree *e) : + CT_StaticCast (cst, o, t, c, e) {} + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } +}; + +/** \class CT_DynamicCast CTree.h Puma/CTree.h + * Tree node representing a dynamic cast. + * Example: \code dynamic_cast(a) \endcode */ +class CT_DynamicCast : public CT_StaticCast { +public: + /** Constructor. + * \param cst The cast operator, i.e. 'dynamic_cast'. + * \param o Left arrow bracket of the type name. + * \param t The type to cast to. + * \param c Right array bracket of the type name. + * \param e The expression to cast. */ + CT_DynamicCast (CTree *cst, CTree *o, CTree *t, CTree *c, CTree *e) : + CT_StaticCast (cst, o, t, c, e) {} + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } +}; + +/** \class CT_ImplicitCast CTree.h Puma/CTree.h + * Tree node representing an implicit cast. + * Example: + * \code + * int i = 1.2; // implicit cast from float to int + * \endcode */ +class CT_ImplicitCast : public CT_Expression { + CTree *_expr; // casted expression + +public: + /** Constructor. + * \param e The expression that is implicitely casted. */ + CT_ImplicitCast (CTree *e) { AddSon (_expr, e); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 1; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return n == 0 ? _expr : (CTree*)0; } + /** Get the casted expression. */ + CTree *Expr () const { return _expr; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) + { CTree::ReplaceSon (_expr, old_son, new_son); } +}; + +/** \class CT_TypeidExpr CTree.h Puma/CTree.h + * Tree node representing a typeid expression. + * Example: \code typeid(X) \endcode */ +class CT_TypeidExpr : public CT_Expression { + CTree *sons[4]; // typeid, open, type_id/expr, close + +public: + /** Constructor. + * \param tid The 'typeid' operator. + * \param o The left parenthesis of the type name or expression. + * \param e The expression or type name for which to get the type identifier. + * \param c The right parenthesis of the type name or expression. */ + CT_TypeidExpr (CTree *tid, CTree *o, CTree *e, CTree *c) { + AddSon (sons[0], tid); AddSon (sons[1], o); + AddSon (sons[2], e); AddSon (sons[3], c); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 4; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 4, n); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 4, old_son, new_son); + } + /** Get the typeid argument, i.e. the expression or type name for + * which to get the type identifier. */ + CTree *Arg () const { return sons[2]; } +}; + +/** \class CT_SizeofExpr CTree.h Puma/CTree.h + * Tree node representing a sizeof expression. + * Example: \code sizeof(int*) \endcode */ +class CT_SizeofExpr : public CT_Expression { + CTree *sons[5]; // key, open, type, close, expr + +public: + /** Constructor. + * \param k The 'sizeof' keyword. + * \param o Left parenthesis around the type name. + * \param t The type from which to get the size. + * \param c Right parenthesis around the type name. */ + CT_SizeofExpr (CTree *k, CTree *o, CTree *t, CTree *c) { + AddSon (sons[0], k); AddSon (sons[1], o); AddSon (sons[2], t); + AddSon (sons[3], c); AddSon (sons[4], 0); + } + /** Constructor. + * \param k The 'sizeof' keyword. + * \param e The expression from which to get the size. */ + CT_SizeofExpr (CTree *k, CTree *e) { + AddSon (sons[0], k); AddSon (sons[1], 0); AddSon (sons[2], 0); + AddSon (sons[3], 0); AddSon (sons[4], e); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 5); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 5, n); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 5, old_son, new_son); + } + /** Get the expression. */ + CTree *Expr () const { return sons[4]; } + /** Get the type name. */ + CT_NamedType *TypeName () const { return (CT_NamedType*)sons[2]; } +}; + +/** \class CT_AlignofExpr CTree.h Puma/CTree.h + * Tree node representing an alignof expression. + * Example: \code __alignof(int) \endcode */ +class CT_AlignofExpr : public CT_Expression { + CTree *sons[5]; // key, open, type, close, expr + +public: + /** Constructor. + * \param k The 'alignof' keyword. + * \param o Left parenthesis around the type name. + * \param t The type from which to get the alignment. + * \param c Right parenthesis around the type name. */ + CT_AlignofExpr (CTree *k, CTree *o, CTree *t, CTree *c) { + AddSon (sons[0], k); AddSon (sons[1], o); AddSon (sons[2], t); + AddSon (sons[3], c); AddSon (sons[4], 0); + } + /** Constructor. + * \param k The 'alignof' keyword. + * \param e The expression from which to get the alignment. */ + CT_AlignofExpr (CTree *k, CTree *e) { + AddSon (sons[0], k); AddSon (sons[1], 0); AddSon (sons[2], 0); + AddSon (sons[3], 0); AddSon (sons[4], e); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 5); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 5, n); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 5, old_son, new_son); + } + /** Get the expression. */ + CTree *Expr () const { return sons[4]; } + /** Get the type name. */ + CT_NamedType *TypeName () const { return (CT_NamedType*)sons[2]; } +}; + +/** \class CT_TypeTraitExpr CTree.h Puma/CTree.h + * Tree node representing an type trait expression. + * Example: \code __is_enum(E) \endcode */ +class CT_TypeTraitExpr : public CT_Expression { + CTree *sons[6]; // key, open, type, comma, type, close + +public: + /** Constructor. + * \param k The type trait keyword. + * \param o Left parenthesis around the type name. + * \param t The type from which to get the trait. + * \param c Right parenthesis around the type name. */ + CT_TypeTraitExpr (CTree *k, CTree *o, CTree *t, CTree *c) { + AddSon (sons[0], k); AddSon (sons[1], o); AddSon (sons[2], t); + AddSon (sons[3], 0); AddSon (sons[4], 0); AddSon (sons[5], c); + } + /** Constructor. + * \param k The type trait keyword. + * \param o Left parenthesis around the type name. + * \param t1 The first type from which to get the trait. + * \param cc The comma between the types. + * \param t2 The second type from which to get the trait. + * \param c Right parenthesis around the type name. */ + CT_TypeTraitExpr (CTree *k, CTree *o, CTree *t1, CTree *cc, CTree *t2, CTree *c) { + AddSon (sons[0], k); AddSon (sons[1], o); AddSon (sons[2], t1); + AddSon (sons[3], cc); AddSon (sons[4], t2); AddSon (sons[5], c); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 6); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 6, n); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 6, old_son, new_son); + } + /** Get the type trait operator. */ + int Operator () const { return sons[0]->token ()->type (); } + /** Get the first type. */ + CT_NamedType *FirstType () const { return (CT_NamedType*)sons[2]; } + /** Get the second type. */ + CT_NamedType *SecondType () const { return (CT_NamedType*)sons[4]; } +}; + +/** \class CT_OffsetofExpr CTree.h Puma/CTree.h + * Tree node representing an offsetof expression. + * Example: \code offsetof(Circle,radius) \endcode */ +class CT_OffsetofExpr : public CT_Expression { + CTree *sons[6]; // key, open, type, comma, member, close + +public: + /** Constructor. + * \param k The 'offsetof' keyword. + * \param o Left parenthesis around the parameters. + * \param t The type containing the member. + * \param co The comma between type and member. + * \param m The member for which to get the offset. + * \param c Right parenthesis around the parameters. */ + CT_OffsetofExpr (CTree *k, CTree *o, CTree *t, CTree *co, CTree *m, CTree *c) { + AddSon (sons[0], k); AddSon (sons[1], o); AddSon (sons[2], t); + AddSon (sons[3], co); AddSon (sons[4], m); AddSon (sons[5], c); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 6; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 6, n); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 6, old_son, new_son); + } + /** Get the typename. */ + CTree *TypeName () const { return sons[2]; } + /** Get the member designator. */ + CT_DesignatorSeq *MemberDesignator () const { return (CT_DesignatorSeq*)sons[4]; } +}; + +/** \class CT_IndexDesignator CTree.h Puma/CTree.h + * Tree node representing an index designator. + * Example: \code [1] \endcode */ +class CT_IndexDesignator : public CT_Expression { + CTree *sons[3]; // open, index, close + +public: + /** Constructor. + * \param o Left bracket of the index designator. + * \param i The index expression. + * \param c Right bracket of the index designator. */ + CT_IndexDesignator (CTree *o, CTree *i, CTree *c) { + AddSon (sons[0], o); AddSon (sons[1], i); AddSon (sons[2], c); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 3; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 3, n); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 3, old_son, new_son); + } +}; + +/** \class CT_MembDesignator CTree.h Puma/CTree.h + * Tree node representing a member designator. + * Example: \code .a \endcode */ +class CT_MembDesignator : public CT_Expression { + CTree *sons[2]; // dot, member + +public: + /** Constructor. + * \param d The dot before the member name. + * \param m The member name. */ + CT_MembDesignator (CTree *d, CTree *m) { AddSon (sons[0], d); AddSon (sons[1], m); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 2; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 2, n); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 2, old_son, new_son); + } +}; + +/** \class CT_DesignatorSeq CTree.h Puma/CTree.h + * Tree node representing a designator sequence. + * Example: \code .a.b.c \endcode */ +class CT_DesignatorSeq : public CT_List, public CSemValue { +public: + /** Constructor. + * \param size Initial number of designators. */ + CT_DesignatorSeq (int size = 1) : CT_List (size, 2) {} + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + + /** Get the type of the entity to initialize. */ + CTypeInfo *Type () const { return type; } + /** Get the value of the entity to initialize. */ + CExprValue *Value () const { return value; } + /** Get the semantic value object. */ + CSemValue *SemValue () const { return (CSemValue*)this; } +}; + +/*****************************************************************************/ +/* */ +/* Declaration specifiers */ +/* */ +/*****************************************************************************/ + +/** \class CT_DeclSpec CTree.h Puma/CTree.h + * Base class for all tree nodes representing declaration specifiers. */ +class CT_DeclSpec : public CTree { +protected: + /** Constructor. */ + CT_DeclSpec () {} +}; + +/** \class CT_PrimDeclSpec CTree.h Puma/CTree.h + * Tree node representing a primitive declaration specifier. */ +class CT_PrimDeclSpec : public CT_DeclSpec { +public: + /** Declaration specifier types. */ + enum Type { + PDS_FRIEND, /** friend */ + PDS_TYPEDEF, /** typedef */ + PDS_AUTO, /** auto */ + PDS_REGISTER, /** register */ + PDS_STATIC, /** static */ + PDS_EXTERN, /** extern */ + PDS_MUTABLE, /** mutable */ + PDS_INLINE, /** inline */ + PDS_VIRTUAL, /** virtual */ + PDS_EXPLICIT, /** explicit */ + PDS_CONST, /** const */ + PDS_VOLATILE, /** volatile */ + PDS_RESTRICT, /** restrict */ + PDS_CHAR, /** char */ + PDS_WCHAR_T, /** wchar_t */ + PDS_BOOL, /** bool */ + PDS_C_BOOL, /** _Bool */ + PDS_SHORT, /** short */ + PDS_INT, /** int */ + PDS_LONG, /** long */ + PDS_SIGNED, /** signed */ + PDS_UNSIGNED, /** unsigned */ + PDS_FLOAT, /** float */ + PDS_DOUBLE, /** double */ + PDS_VOID, /** void */ + // GNU C specific type specifier + PDS_INT128, /** __int128 */ + // GNU C++ specific storage specifier + PDS_THREAD, /** __thread */ + // AspectC++ specific type specifier + PDS_UNKNOWN_T, /** unknown_t */ + // Win specific declaration specifiers + PDS_CDECL, /** __cdecl */ + PDS_STDCALL, /** __stdcall */ + PDS_FASTCALL, /** __fastcall */ + PDS_INT64, /** __int64 */ + PDS_UNKNOWN, /** Unknown declaration specifier. */ + PDS_NUM /** Number of declaration specifier types. */ + }; + +private: + Type _type; + CTree *_token; // has to be a CT_Token + + void determine_type (); + +public: + /** Constructor. + * \param t The token containing the declaration specifier. */ + CT_PrimDeclSpec (CT_Token *t) { AddSon (_token, (CTree*)t); determine_type (); } + /** Constructor. + * \param t The declaration specifier type. */ + CT_PrimDeclSpec (Type t) : _token (0) { _type = t; } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return _token ? 1 : 0; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const + { return (n == 0) ? _token : (CTree*)0; } + /** Get the textual representation of the declaration specifier. + * \return The string representation or " ". */ + const char *SpecText () const + { return _token ? _token->token ()->text () : " "; } + /** Get the declaration specifier type. */ + Type SpecType () const { return _type; } + /** Number of declaration specifier types. */ + static const int NumTypes = PDS_NUM; + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (_token, (CTree*)old_son, (CTree*)new_son); + determine_type (); + } +}; + +/** \class CT_NamedType CTree.h Puma/CTree.h + * Tree node representing a named type. + * Example: \code (int*)a \endcode where int* is a + * type with a generated name. */ +class CT_NamedType : public CT_DeclSpec, public CSemObject { + CTree *sons[2]; // declspecs, declarator + +public: + /** Constructor. + * \param dss The declaration specifier sequence of the type. + * \param d The type declarator. */ + CT_NamedType (CTree *dss, CTree *d) { AddSon (sons[0], dss); AddSon (sons[1], d); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 2); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 2, n); } + /** Get the declarator. */ + CTree *Declarator () const { return sons[1]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 2, old_son, new_son); + } + /** Get the semantic information about the created temporary object. */ + CSemObject *SemObject () const { return (CSemObject*)this; } +}; + +/** \class CT_ClassSpec CTree.h Puma/CTree.h + * Tree node representing a class specifier. + * Example: \code class X \endcode */ +class CT_ClassSpec : public CT_DeclSpec, public CSemObject { + CTree *sons[2]; // key, name + +public: + /** Constructor. + * \param k The 'class' or 'struct' keyword. + * \param n The class name. */ + CT_ClassSpec (CTree *k, CTree *n) { AddSon (sons[0], k); AddSon (sons[1], n); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 2; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 2, n); } + /** Get the class name. */ + CT_SimpleName *Name () const { return (CT_SimpleName*)sons[1]; } + /** Get the semantic information about the class. */ + CSemObject *SemObject () const { return (CSemObject*)this; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 2, old_son, new_son); + } +}; + +/** \class CT_UnionSpec CTree.h Puma/CTree.h + * Tree node representing a union specifier. + * Example: \code union X \endcode */ +class CT_UnionSpec : public CT_ClassSpec { +public: + /** Constructor. + * \param k The 'union' keyword. + * \param n The name of the union. */ + CT_UnionSpec (CTree *k, CTree *n) : CT_ClassSpec (k, n) {} + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } +}; + +/** \class CT_EnumSpec CTree.h Puma/CTree.h + * Tree node representing an enumeration specifier. + * Example: \code enum X \endcode */ +class CT_EnumSpec : public CT_ClassSpec { +public: + /** Constructor. + * \param k The 'enum' keyword. + * \param n The name of the enumeration. */ + CT_EnumSpec (CTree *k, CTree *n) : CT_ClassSpec (k, n) {} + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } +}; + +/** \class CT_ExceptionSpec CTree.h Puma/CTree.h + * Tree node representing an exception specifier. + * Example: \code throw(std::exception) \endcode */ +class CT_ExceptionSpec : public CT_DeclSpec { + CTree *sons[2]; // throw, type_id_list + +public: + /** Constructor. + * \param k The 'throw' keyword. + * \param l The type list for the exception type to throw. */ + CT_ExceptionSpec (CTree *k, CTree *l) { AddSon (sons[0], k); AddSon (sons[1], l); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 2; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 2, n); } + /** Get the exception type list. */ + CT_ArgDeclList *Arguments () const { return (CT_ArgDeclList*)sons[1]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 2, old_son, new_son); + } +}; + +/*****************************************************************************/ +/* */ +/* Declarations */ +/* */ +/*****************************************************************************/ + +/** \class CT_Decl CTree.h Puma/CTree.h + * Base class for all tree nodes representing declarations. */ +class CT_Decl : public CTree { + CT_LinkageSpec *_linkage; + +protected: + /** Constructor. */ + CT_Decl () : _linkage (0) {} + +public: + /** Set the linkage of the declared entity. + * \param l The linkage specifiers. */ + void Linkage (CT_LinkageSpec *l) { _linkage = l; } + /** Get the linkage specifiers. */ + CT_LinkageSpec *Linkage () const { return _linkage; } + /** Get this. */ + virtual CT_Decl *IsDeclaration () { return this; } +}; + +/** \class CT_Program CTree.h Puma/CTree.h + * Root node of C/C++ syntax trees. */ +class CT_Program : public CT_DeclList, public CSemScope { +public: + /** Constructor. + * \param size The initial number of declarations in the program. + * \param incr The initial increment count. */ + CT_Program (int size = 20, int incr = 20) : CT_DeclList (size, incr) {} + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the top scope. */ + CSemScope *SemScope () const { return (CSemScope*)this; } +}; + +/** \class CT_ObjDecl CTree.h Puma/CTree.h + * Tree node representing an object declaration. + * Example: \code int *i \endcode */ +class CT_ObjDecl : public CT_Decl { + CTree *sons[3]; // declspecs, declarators, colon + +public: + /** Constructor. + * \param dsl The declaration specifier sequence. + * \param dl The declarator list. + * \param c Optional colon. */ + CT_ObjDecl (CTree *dsl, CTree *dl, CTree *c) { + AddSon (sons[0], dsl); AddSon (sons[1], dl); AddSon (sons[2], c); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 3; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 3, n); } + /** Get the declaration specifier sequence. */ + CT_DeclSpecSeq *DeclSpecs () const { return (CT_DeclSpecSeq*)sons[0]; } + /** Get the declarator list. */ + CT_DeclaratorList *Declarators () const { return (CT_DeclaratorList*)sons[1]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 3, old_son, new_son); + } +}; + +/** \class CT_TemplateDecl CTree.h Puma/CTree.h + * Tree node representing a template declaration. */ +class CT_TemplateDecl : public CT_Decl, public CSemScope { + CTree *sons[3]; // export, param_list, decl + +public: + /** Constructor. + * \param e Optional 'export' keyword. + * \param p The template parameter list. + * \param d The class or function declaration. */ + CT_TemplateDecl (CTree *e, CTree *p, CTree *d) { + AddSon (sons[0], e); AddSon (sons[1], p); AddSon (sons[2], d); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 3); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 3, n); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 3, old_son, new_son); + } + /** Get the 'export' keyword. */ + CTree *Export () const { return sons[0]; } + /** Get the template parameter list. */ + CT_TemplateParamList *Parameters () const { + return (CT_TemplateParamList*)sons[1]; + } + /** Get the class or function declaration. */ + CTree *Declaration () const { return sons[2]; } + /** Get the scope opened by the template declaration. */ + CSemScope *SemScope () const { return (CSemScope*)this; } +}; + +/** \class CT_TemplateParamDecl CTree.h Puma/CTree.h + * Base class for all tree nodesrepresenting a template parameter declaration. */ +class CT_TemplateParamDecl : public CT_Decl, public CSemObject { +protected: + /** Constructor. */ + CT_TemplateParamDecl () {} + +public: + /** Get the template default argument. */ + virtual CT_ExprList *DefaultArgument () const = 0; + /** Get the semantic information about the template parameter. */ + CSemObject *SemObject () const { return (CSemObject*)this; } +}; + +/** \class CT_NonTypeParamDecl CTree.h Puma/CTree.h + * Tree node representing a template non-type parameter declaration. */ +class CT_NonTypeParamDecl : public CT_TemplateParamDecl { + CTree *sons[3]; // declspecs, declarator, init + +public: + /** Constructor. + * \param dsl The declaration specifier sequence. + * \param d The parameter declarator. + * \param i The default template argument. */ + CT_NonTypeParamDecl (CTree *dsl, CTree *d, CTree *i = (CTree*)0) { + AddSon (sons[0], dsl); AddSon (sons[1], d); AddSon (sons[2], i); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 3); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 3, n); } + /** Get the declaration specifier sequence. */ + CT_DeclSpecSeq *DeclSpecs () const { return (CT_DeclSpecSeq*)sons[0]; } + /** Get the parameter declarator. */ + CTree *Declarator () const { return sons[1]; } + /** Get the default template argument. */ + CT_ExprList *DefaultArgument () const { return (CT_ExprList*)sons[2]; } + /** Get the semantic information about the template parameter. */ + CSemObject *SemObject () const { return (CSemObject*)this; } + /** Set the default template argument. + * \param i The default argument. */ + void Initializer (CTree *i) { AddSon (sons[2], i); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 3, old_son, new_son); + } +}; + +/** \class CT_TypeParamDecl CTree.h Puma/CTree.h + * Tree node representing a template type parameter declaration. */ +class CT_TypeParamDecl : public CT_TemplateParamDecl { + CTree *sons[4]; // params, key, id, init + +public: + /** Constructor. + * \param pl The template parameter list of an template template parameter. + * \param k The type keyword, i.e. 'class' or 'typename'. + * \param id The parameter identifier. + * \param i The default template argument. */ + CT_TypeParamDecl (CTree *pl, CTree *k, CTree *id, CTree *i = (CTree*)0) { + AddSon (sons[0], pl); AddSon (sons[1], k); + AddSon (sons[2], id); AddSon (sons[3], i); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 4); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 4, n); } + /** Get the template parameter list of a template template parameter. */ + CT_TemplateParamList *Parameters () const { + return (CT_TemplateParamList*)sons[0]; + } + /** Get the templare parameter name. */ + CT_SimpleName *Name () const { return (CT_SimpleName*)sons[2]; } + /** Get the template default argument. */ + CT_ExprList *DefaultArgument () const { return (CT_ExprList*)sons[3]; } + /** Set the template default argument. + * \param i The default argument. */ + void Initializer (CTree *i) { AddSon (sons[3], i); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 4, old_son, new_son); + } +}; + +/** \class CT_EnumDef CTree.h Puma/CTree.h + * Tree node representing the definition of an enumeration. + * Example: \code enum E { A, B, C } \endcode */ +class CT_EnumDef : public CT_Decl, public CSemObject { + CTree *sons[3]; // key, name, enumerators + +public: + /** Constructor. + * \param k The keyword 'enum'. + * \param n The name of the enumeration. */ + CT_EnumDef (CTree *k, CTree *n) { + AddSon (sons[0], k); AddSon (sons[1], n); AddSon (sons[2], 0); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 3); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 3, n); } + /** Get the name of the enumeration. */ + CT_SimpleName *Name () const { return (CT_SimpleName*)sons[1]; } + /** Set the list of enumeration constants. + * \param el The enumerator list. */ + void Enumerators (CTree *el) { AddSon (sons[2], el); } + /** Get the list of enumeration constants. */ + CT_EnumeratorList *Enumerators () const { return (CT_EnumeratorList*)sons[2]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 3, old_son, new_son); + } + /** Get the semantic information about the enumeration. */ + CSemObject *SemObject () const { return (CSemObject*)this; } +}; + +/** \class CT_Enumerator CTree.h Puma/CTree.h + * Tree node representing a single enumeration constant. */ +class CT_Enumerator : public CT_Decl, public CSemObject { + CTree *sons[2]; // name, init + +public: + /** Constructor. + * \param n The name of the enumerator. */ + CT_Enumerator (CTree *n) { AddSon (sons[0], n); AddSon (sons[1], 0); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 2); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 2, n); } + /** Get the name of the enumerator. */ + CT_SimpleName *Name () const { return (CT_SimpleName*)sons[0]; } + /** Set the initializer expression of the enumerator. */ + void Initializer (CTree *i) { AddSon (sons[1], i); } + /** Get the initializer expression of the enumerator. */ + CT_ExprList *Initializer () const { return (CT_ExprList*)sons[1]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 2, old_son, new_son); + } + /** Get the semantic information about the enumerator. */ + CSemObject *SemObject () const { return (CSemObject*)this; } +}; + +/** \class CT_FctDef CTree.h Puma/CTree.h + * Tree node representing a function definition. + * Example: + * \code + * int mul(int x, int y) { + * return x*y; + * } + * \endcode */ +class CT_FctDef : public CT_Decl, public CSemObject { + CTree *sons[7]; // declspecs, declarator, try, ctor_init, args, body, handlers + +public: + /** Constructor. + * \param dss The declaration specifier sequence. + * \param d The function declarator. + * \param t Optional keyword 'try' for a function try-block. + * \param ci Optional constructor initializer list. + * \param as Optional K&R argument declaration list. + * \param b The function body. + * \param hs Exception handler sequence for a function try-block. */ + CT_FctDef (CTree *dss, CTree *d, CTree *t, CTree *ci, CTree *as, + CTree *b, CTree *hs) { + AddSon (sons[0], dss); AddSon (sons[1], d); AddSon (sons[2], t); + AddSon (sons[3], ci); AddSon (sons[4], as); AddSon (sons[5], b); + AddSon (sons[6], hs); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 7); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 7, n); } + /** Get the declaration specifier sequence. */ + CT_DeclSpecSeq *DeclSpecs () const { return (CT_DeclSpecSeq*)sons[0]; } + /** Get the function declarator. */ + CTree *Declarator () const { return sons[1]; } + /** Get the 'try' keyword of the function try-block. */ + CT_Token *TryKey () const { return (CT_Token*)sons[2]; } + /** Get the constructor initializer list. */ + CTree *CtorInit () const { return sons[3]; } + /** Get the K&R argument declaration sequence. */ + CT_ArgDeclSeq *ArgDeclSeq () const { return (CT_ArgDeclSeq*)sons[4]; } + /** Get the function body. */ + CT_CmpdStmt *Body () const { return (CT_CmpdStmt*)sons[5]; } + /** Get the exception handler sequence of a function try-block. */ + CT_HandlerSeq *Handlers () const { return (CT_HandlerSeq*)sons[6]; } + /** Get the semantic information about the function. */ + CSemObject *SemObject () const { return (CSemObject*)this; } + /** Set the constructor initializer list. + * \param i The initializer list. */ + void CtorInit (CTree *i) { AddSon (sons[3], i); } + /** Set the function body. + * \param b The function body. */ + void Body (CTree *b) { AddSon (sons[5], b); } + /** Set the exception handler sequence of a function try-block. + * \param h The handlers. */ + void Handlers (CTree *h) { AddSon (sons[6], h); } + /** Set the function try-block. + * \param t The keyword 'try'. + * \param c Optional constructor initializer list. + * \param b The function body. + * \param h The exception handler sequence. */ + void FctTryBlock (CTree *t, CTree *c, CTree *b, CTree *h) { + AddSon (sons[2], t); AddSon (sons[3], c); + AddSon (sons[5], b); AddSon (sons[6], h); + } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 7, old_son, new_son); + } +}; + +/** \class CT_AsmDef CTree.h Puma/CTree.h + * Tree node representing an inline assembly definition. + * Example: \code asm("movl %ecx %eax"); \endcode */ +class CT_AsmDef : public CT_Decl { + CTree *sons[5]; // asm, open, str, close, semi_colon + +public: + /** Constructor. + * \param a The keyword 'asm'. + * \param o Left parenthesis around the assembler code string. + * \param s The assembler code. + * \param c Right parenthesis around the assembler code string. + * \param sc Trailing semi-colon. */ + CT_AsmDef (CTree *a, CTree *o, CTree *s, CTree *c, CTree *sc) { + AddSon (sons[0], a); AddSon (sons[1], o); AddSon (sons[2], s); + AddSon (sons[3], c); AddSon (sons[4], sc); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 5; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 5, n); } + /** Get the assembler code. */ + CT_String *Instructions () const { return (CT_String*)sons[2]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 5, old_son, new_son); + } +}; + +/** \class CT_Handler CTree.h Puma/CTree.h + * Tree node representing an exception handler. */ +class CT_Handler : public CT_Decl, public CSemScope { + CTree *sons[3]; // catch, exception_decl, stmt + +public: + /** Constructor. + * \param c The keyword 'catch'. + * \param e The exception object declaration. + * \param s The exception handling statement. */ + CT_Handler (CTree *c, CTree *e, CTree *s) { + AddSon (sons[0], c); AddSon (sons[1], e); AddSon (sons[2], s); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 3; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 3, n); } + /** Get the exception object declaration. */ + CT_ArgDeclList *Arguments () const { return (CT_ArgDeclList*)sons[1]; } + /** Get the exception handling statement. */ + CT_Statement *Statement () const { return (CT_Statement*)sons[2]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 3, old_son, new_son); + } + /** Get the scope opened by the handler. */ + CSemScope *SemScope () const { return (CSemScope*)this; } +}; + +/** \class CT_LinkageSpec CTree.h Puma/CTree.h + * Tree node representing a list of declaration with a specific linkage. */ +class CT_LinkageSpec : public CT_Decl { + CTree *sons[4]; // linkage specifiers, open, decls, close + +public: + /** Constructor. + * \param dss The linkage specifiers, e.g. extern and "C". + * \param o Left parenthesis around the declaration list. + * \param d The list of declarations. + * \param c Right parenthesis around the declaration list. */ + CT_LinkageSpec (CTree *dss, CTree *o, CTree *d, CTree *c) { + AddSon (sons[0], dss); AddSon (sons[1], o); + AddSon (sons[2], d); AddSon (sons[3], c); + if (isList ()) + ((CT_DeclList*)Decls ())->Linkage (this); + else + ((CT_Decl*)Decls ())->Linkage (this); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 4); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 4, n); } + /** Get the linkage specifier list. */ + CT_DeclSpecSeq *LinkageSpecifiers () const { return (CT_DeclSpecSeq*)sons[0]; } + /** Get the list declarations. */ + CTree *Decls () const { return sons[2]; } + /** Check if there is more than one enclosed declaration. + * In this case the node returned by Decls() is a CT_DeclList + * node. */ + bool isList () const { + return Decls ()->NodeName () == CT_DeclList::NodeId (); + } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 4, old_son, new_son); + } +}; + +/** \class CT_ArgDecl CTree.h Puma/CTree.h + * Tree node representing the declaration of a function parameter. */ +class CT_ArgDecl : public CT_Decl, public CSemObject, public CSemValue { + CTree *sons[4]; // declspecs, declarator, init, ellipsis + +public: + /** Constructor. + * \param dsl The declaration specifier sequence. + * \param d The parameter declarator. */ + CT_ArgDecl (CTree *dsl, CTree *d) { + AddSon (sons[0], dsl); AddSon (sons[1], d); + AddSon (sons[2], 0); AddSon (sons[3], 0); + } + /** Constructor. + * \param ellipsis The variable argument list operator "...". */ + CT_ArgDecl (CTree *ellipsis) { + AddSon (sons[0], 0); AddSon (sons[1], 0); + AddSon (sons[2], 0); AddSon (sons[3], ellipsis); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 4); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 4, n); } + /** Get the declaration specifier sequence. */ + CT_DeclSpecSeq *DeclSpecs () const { return (CT_DeclSpecSeq*)sons[0]; } + /** Get the function parameter declarator. */ + CTree *Declarator () const { return sons[1]; } + /** Get the default argument. */ + CT_ExprList *Initializer () const { + return (sons[2] && sons[2]->IsDelayedParse ()) ? 0 : (CT_ExprList*)sons[2]; + } + /** Get the variable argument list operator. */ + CT_Token *Ellipsis () const { return (CT_Token*)sons[3]; } + /** Get the semantic information about the function parameter. */ + CSemObject *SemObject () const { return (CSemObject*)this; } + /** Get the type of the function parameter. + * \return The type information object or NULL. */ + CTypeInfo *Type () const { return type; } + /** Get the value of the function parameter. + * \return The value object or NULL. */ + CExprValue *Value () const { return value; } + /** Get the semantic value information of the function parameter. + * \return The value object or NULL. */ + CSemValue *SemValue () const { return (CSemValue*)this; } + /** Set the default argument. */ + void Initializer (CTree *i) { AddSon (sons[2], i); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 4, old_son, new_son); + } +}; + +/** \class CT_ArgDeclList CTree.h Puma/CTree.h + * Tree node representing a function parameter list. */ +class CT_ArgDeclList : public CT_DeclList, public CSemScope { +public: + /** Constructor. + * \param size The initial size of the list. + * \param props The list properties. */ + CT_ArgDeclList (int size = 2, int props = SEPARATORS | OPEN_CLOSE) : + CT_DeclList (size, 2) { AddProperties (props); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the scope opened by the parameter list. */ + CSemScope *SemScope () const { return (CSemScope*)this; } +}; + +/** \class CT_ArgDeclSeq CTree.h Puma/CTree.h + * Tree node representing a K&R function parameter declarations list. */ +class CT_ArgDeclSeq : public CT_DeclList, public CSemScope { +public: + /** Constructor. + * \param size The initial size of the list. */ + CT_ArgDeclSeq (int size = 2) : CT_DeclList (size, 2) {} + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the scope opened by the parameter declarations list. */ + CSemScope *SemScope () const { return (CSemScope*)this; } +}; + +/** \class CT_ArgNameList CTree.h Puma/CTree.h + * Tree node representing a K&R function parameter name list. */ +class CT_ArgNameList : public CT_ArgDeclList { +public: + /** Constructor. */ + CT_ArgNameList () : CT_ArgDeclList () {} + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } +}; + +/** \class CT_NamespaceDef CTree.h Puma/CTree.h + * Tree node representing a namespace definition. + * Example: \code namespace a {} \endcode */ +class CT_NamespaceDef : public CT_Decl, public CSemObject { + CTree *sons[4]; // inline, ns, name, members + +public: + /** Constructor. + * \param i The keyword 'inline'. + * \param n The keyword 'namespace'. + * \param nm The name of the namespace. */ + CT_NamespaceDef (CTree *i, CTree *n, CTree *nm) { + AddSon (sons[0], i); AddSon (sons[1], n); AddSon (sons[2], nm); AddSon (sons[3], 0); + } + /** Constructor. + * \param i The keyword 'inline'. + * \param n The keyword 'namespace'. + * \param nm The name of the namespace. + * \param m The namespace member declarations list. */ + CT_NamespaceDef (CTree *i, CTree *n, CTree *nm, CTree *m) { + AddSon (sons[0], i); AddSon (sons[1], n); AddSon (sons[2], nm); AddSon (sons[3], m); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 4); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 4, n); } + /** Set the namespace member declarations list. */ + void Members (CTree *m) { AddSon (sons[3], m); } + /** Get the namespace member declarations list. */ + CT_MembList *Members () const { return (CT_MembList*)sons[3]; } + /** Get the name of the namespace. */ + CT_SimpleName *Name () const { return (CT_SimpleName*)sons[2]; } + /** Get the semantic information about the namespace. */ + CSemObject *SemObject () const { return (CSemObject*)this; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 4, old_son, new_son); + } + /** Return true if this is an inline namespace. */ + bool isInline () const { return sons[0] != (CTree*)0; } +}; + +/** \class CT_NamespaceAliasDef CTree.h Puma/CTree.h + * Tree node representing a namespace alias definition. + * Example: \code namespace b = a; \endcode */ +class CT_NamespaceAliasDef : public CT_Decl, public CSemObject { + CTree *sons[5]; // ns, alias, assign, name, semi_colon + +public: + /** Constructor. + * \param n The keyword 'namespace'. + * \param a The name of the namespace alias. + * \param as The assignment operator '='. + * \param nm The name of the original namespace. + * \param s The trailing semi-colon. */ + CT_NamespaceAliasDef (CTree *n, CTree *a, CTree *as, CTree *nm, CTree *s) { + AddSon (sons[0], n); AddSon (sons[1], a); AddSon (sons[2], as); + AddSon (sons[3], nm); AddSon (sons[4], s); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 5; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 5, n); } + /** Get the name of the original namespace. */ + CT_SimpleName *Name () const { return (CT_SimpleName*)sons[3]; } + /** Get the name of the namespace alias. */ + CT_SimpleName *Alias () const { return (CT_SimpleName*)sons[1]; } + /** Get the semantic information about the namespace alias. */ + CSemObject *SemObject () const { return (CSemObject*)this; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 5, old_son, new_son); + } +}; + +/** \class CT_UsingDirective CTree.h Puma/CTree.h + * Tree node representing a namespace using directive. + * Example: \code using namespace std; \endcode */ +class CT_UsingDirective : public CT_Decl { + CTree *sons[4]; // using, ns, name, semi_colon + +public: + /** Constructor. + * \param u The keyword 'using'. + * \param ns The keyword 'namespace'. + * \param n The name of the namespace. + * \param s The trailing semi-colon. */ + CT_UsingDirective (CTree *u, CTree *ns, CTree *n, CTree *s) { + AddSon (sons[0], u); AddSon (sons[1], ns); AddSon (sons[2], n); + AddSon (sons[3], s); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 4; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 4, n); } + /** Get the name of the namespace. */ + CT_SimpleName *Name () const { return (CT_SimpleName*)sons[2]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 4, old_son, new_son); + } +}; + +/*****************************************************************************/ +/* */ +/* Declarators */ +/* */ +/*****************************************************************************/ + +/** \class CT_Declarator CTree.h Puma/CTree.h + * Base class for all tree nodes representing declarators. */ +class CT_Declarator : public CTree { +protected: + /** Constructor. */ + CT_Declarator () {} + +public: + /** Get the declarator. */ + virtual CTree *Declarator () const = 0; + /** Get this. */ + virtual CT_Declarator *IsDeclarator () { return this; } + /** Get the declared name. */ + CT_SimpleName *Name (); + /** Get the declared name and set last_declarator to + * the declarator containing the name. + * \param last_declarator To be set to the declarator containing the name. */ + CT_SimpleName *Name (CT_Declarator *&last_declarator); +}; + +/** \class CT_InitDeclarator CTree.h Puma/CTree.h + * Tree node representing a declarator with initializer. + * Example: \code int *i = 0; \endcode */ +class CT_InitDeclarator : public CT_Declarator, public CSemObject { + CTree *sons[2]; // declarator, init + CTree *obj_decl; + +public: + /** Constructor. + * \param d The declarator. + * \param i The initializer. */ + CT_InitDeclarator (CTree *d, CTree *i = 0) { + AddSon (sons[0], d); AddSon (sons[1], i); + AddSon (obj_decl, 0); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 2); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 2, n); } + /** Get the declarator. */ + CTree *Declarator () const { return sons[0]; } + /** Get the initializer. */ + CT_ExprList *Initializer () const { return (CT_ExprList*)sons[1]; } + /** Get the semantic information about the declared object. */ + CSemObject *SemObject () const { return (CSemObject*)this; } + /** Get the object declaration node containing the declarator. */ + CT_ObjDecl *ObjDecl () const { return (CT_ObjDecl*)obj_decl; } + /** Set the initializer. */ + void Initializer (CTree* i) { AddSon (sons[1], i); } + /** Set the object declaration node containing the declarator. + * \param od The object declaration node. */ + void ObjDecl (CTree *od) { AddSon (obj_decl, od); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 2, old_son, new_son); + } +}; + +/** \class CT_BracedDeclarator CTree.h Puma/CTree.h + * Tree node representing a braced declarator. + * Example: \code int (i); \endcode */ +class CT_BracedDeclarator : public CT_Declarator { + CTree *sons[4]; // open, win_specs, declarator, close + +public: + /** Constructor. + * \param o Left parenthesis around the declarator. + * \param d The declarator. + * \param c Right parenthesis around the declarator. */ + CT_BracedDeclarator (CTree *o, CTree *d, CTree *c) { + AddSon (sons[0], o); AddSon (sons[1], 0); + AddSon (sons[2], d); AddSon (sons[3], c); + } + /** Constructor. + * \param o Left parenthesis around the declarator. + * \param ws Declaration specifiers. + * \param d The declarator. + * \param c Right parenthesis around the declarator. */ + CT_BracedDeclarator (CTree *o, CTree *ws, CTree *d, CTree *c) { + AddSon (sons[0], o); AddSon (sons[1], ws); + AddSon (sons[2], d); AddSon (sons[3], c); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 4); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 4, n); } + /** Get the declarator. */ + CTree *Declarator () const { return sons[2]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 4, old_son, new_son); + } +}; + +/** \class CT_ArrayDelimiter CTree.h Puma/CTree.h + * Tree node representing an array delimiter. + * Example: \code [10] \endcode or \code [*] \endcode */ +class CT_ArrayDelimiter : public CTree { + CTree *sons[4]; // star, static, quals, expr + bool pos0; + +public: + /** Constructor. + * \param m The operator '*'. + * \param s The keyword 'static'. + * \param q The const/volatile qualifier sequence. + * \param e The array size expression. + * \param p Position of keyword 'static', true means before the + * qualifier sequence and false means behind it. */ + CT_ArrayDelimiter (CTree *m, CTree *s, CTree *q, CTree *e, bool p = false) { + AddSon (sons[0], m); AddSon (sons[1], s); + AddSon (sons[2], q); AddSon (sons[3], e); pos0 = p; + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 4); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 4, n); } + /** Get the operator '*'. */ + CT_Token *Star () const { return (CT_Token*)sons[0]; } + /** Get the keyword 'static'. */ + CT_Token *Static () const { return (CT_Token*)sons[pos0?2:1]; } + /** Get the const/volatile qualifier sequence. */ + CT_DeclSpecSeq *Qualifier () const { return (CT_DeclSpecSeq*)sons[pos0?1:2]; } + /** Get the array size expression. */ + CTree *Expr () const { return sons[3]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 4, old_son, new_son); + } +}; + +/** \class CT_ArrayDeclarator CTree.h Puma/CTree.h + * Tree node representing an array declarator. + * Example: \code a[10] \endcode */ +class CT_ArrayDeclarator : public CT_Declarator, public CSemValue { + CTree *sons[4]; // declarator, open, delim, close + +public: + /** Constructor. + * \param d The array declarator. + * \param o Left bracket around the delimiter. + * \param ad The array delimiter. + * \param c Right bracket around the delimiter. */ + CT_ArrayDeclarator (CTree *d, CTree *o, CTree *ad, CTree *c) { + AddSon (sons[0], d); AddSon (sons[1], o); + AddSon (sons[2], ad); AddSon (sons[3], c); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 4; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 4, n); } + /** Get the array declarator. */ + CTree *Declarator () const { return sons[0]; } + /** Get the array delimiter. */ + CT_ArrayDelimiter *Delimiter () const + { return (CT_ArrayDelimiter*)sons[2]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 4, old_son, new_son); + } + /** Get the semantic information for the type of the declared array. */ + CTypeInfo *Type () const { return type; } + /** Get the semantic information for the value of the declared array. */ + CExprValue *Value () const { return value; } + /** Get the semantic information object. */ + CSemValue *SemValue () const { return (CSemValue*)this; } +}; + +/** \class CT_FctDeclarator CTree.h Puma/CTree.h + * Tree node representing a function declarator. + * Example: \code f(int a) const \endcode */ +class CT_FctDeclarator : public CT_Declarator { + CTree *sons[4]; // declarator, args, cv_quals, exception_specs + +public: + /** Constructor. + * \param d The function declarator. + * \param args The function parameter list. + * \param cv The function qualifiers. + * \param es The exception specifier. */ + CT_FctDeclarator (CTree *d, CTree *args, CTree *cv, CTree *es) { + AddSon (sons[0], d); AddSon (sons[1], args); + AddSon (sons[2], cv); AddSon (sons[3], es); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 4); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 4, n); } + /** Get the function declarator. */ + CTree *Declarator () const { return sons[0]; } + /** Get the function parameter list. */ + CT_ArgDeclList *Arguments () const { return (CT_ArgDeclList*)sons[1]; } + /** Get the function qualifier list. */ + CT_DeclSpecSeq *Qualifier () const { return (CT_DeclSpecSeq*)sons[2]; } + /** Get the exception specifier. */ + CT_ExceptionSpec *ExceptionSpecs () const { return (CT_ExceptionSpec*)sons[3]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 4, old_son, new_son); + } +}; + +/** \class CT_RefDeclarator CTree.h Puma/CTree.h + * Tree node representing a reference declarator. + * Example: \code &a \endcode */ +class CT_RefDeclarator : public CT_Declarator { + CTree *sons[2]; // ref, declarator + +public: + /** Constructor. + * \param r The reference operator '&'. + * \param d The declarator. */ + CT_RefDeclarator (CTree *r, CTree *d) { AddSon (sons[0], r); AddSon (sons[1], d); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 2; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 2, n); } + /** Get the declarator. */ + CTree *Declarator () const { return sons[1]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 2, old_son, new_son); + } +}; + +/** \class CT_PtrDeclarator CTree.h Puma/CTree.h + * Tree node representing a pointer declarator. + * Example: \code *a \endcode */ +class CT_PtrDeclarator : public CT_Declarator { + CTree *sons[3]; // ptr, cv_quals, declarator + +public: + /** Constructor. + * \param p The pointer operator '*'. + * \param c The const/volatile pointer qualifier sequence. + * \param d The declarator. */ + CT_PtrDeclarator (CTree *p, CTree *c, CTree *d) { + AddSon (sons[0], p); AddSon (sons[1], c); AddSon (sons[2], d); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 3); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 3, n); } + /** Get the declarator. */ + CTree *Declarator () const { return sons[2]; } + /** Get the const/volatile qualifier sequence. */ + CT_DeclSpecSeq *Qualifier () const { return (CT_DeclSpecSeq*)sons[1]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 3, old_son, new_son); + } +}; + +/** \class CT_MembPtrDeclarator CTree.h Puma/CTree.h + * Tree node representing a member pointer declarator. + * Example: \code *X::a \endcode */ +class CT_MembPtrDeclarator : public CT_Declarator { + CTree *sons[5]; // class, colon, ptr, cv_quals, declarator + +public: + /** Constructor. + * \param c The class name. + * \param cc The scope operator '::'. + * \param p The name of the pointer. + * \param q The const/volatile pointer qualifier sequence. + * \param d The declarator. */ + CT_MembPtrDeclarator (CTree *c, CTree *cc, CTree *p, CTree *q, CTree *d) { + AddSon (sons[0], c); AddSon (sons[1], cc); AddSon (sons[2], p); + AddSon (sons[3], q); AddSon (sons[4], d); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 5); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 5, n); } + /** Get the name of the declared pointer. */ + CT_SimpleName *Name () const { return (CT_SimpleName*)sons[0]; } + /** Get the declarator. */ + CTree *Declarator () const { return sons[4]; } + /** Get the const/volatile qualifier sequence. */ + CT_DeclSpecSeq *Qualifier () const { return (CT_DeclSpecSeq*)sons[3]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 5, old_son, new_son); + } +}; + +/** \class CT_BitFieldDeclarator CTree.h Puma/CTree.h + * Tree node representing a bit-field declarator. + * Example: \code a : 2 \endcode */ +class CT_BitFieldDeclarator : public CT_Declarator, public CSemObject { + CTree *sons[3]; // declarator, colon, expr + +public: + /** Constructor. + * \param d The declarator. + * \param c The colon between the declarator and the bit count. + * \param e The expression specifying the number of bits. */ + CT_BitFieldDeclarator (CTree *d, CTree *c, CTree *e = 0) { + AddSon (sons[0], d); AddSon (sons[1], c); AddSon (sons[2], e); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 3); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 3, n); } + /** Get the declarator. */ + CTree *Declarator () const { return sons[0]; } + /** Get the expression specifying the number of bits. */ + CTree *Expr () const { return sons[2]; } + /** Set the expression specifying the number of bits. */ + void FieldSize (CTree *s) { AddSon (sons[2], s); } + /** Get the semantic information about the declared bit-field. */ + CSemObject *SemObject () const { return (CSemObject*)this; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 3, old_son, new_son); + } +}; + +/*****************************************************************************/ +/* */ +/* Statements */ +/* */ +/*****************************************************************************/ + +/** \class CT_Statement CTree.h Puma/CTree.h + * Base class for all tree nodes representing statements. */ +class CT_Statement : public CTree { +protected: + /** Constructor. */ + CT_Statement () {} + /** Get this. */ + virtual CT_Statement *IsStatement () { return this; } +}; + +/** \class CT_LabelStmt CTree.h Puma/CTree.h + * Tree node representing a label statement. + * Example: \code incr_a: a++; \endcode */ +class CT_LabelStmt : public CT_Statement { + CTree *sons[3]; // id, colon, stmt + +public: + /** Constructor. + * \param id The name of the label. + * \param c The colon behind the label. + * \param stmt The statement following the label. */ + CT_LabelStmt (CTree *id, CTree *c, CTree *stmt) { + AddSon (sons[0], id); AddSon (sons[1], c); AddSon (sons[2], stmt); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 3; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 3, n); } + /** Get the statement. */ + CT_Statement *Statement () const { return (CT_Statement*)sons[2]; } + /** Get the name of the label. */ + CT_SimpleName *Label () const { return (CT_SimpleName*)sons[0]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 3, old_son, new_son); + } +}; + +/** \class CT_DefaultStmt CTree.h Puma/CTree.h + * Tree node representing a default statement of a switch statement. + * Example: \code default: break; \endcode */ +class CT_DefaultStmt : public CT_Statement { + CTree *sons[3]; // keyword, colon, stmt + +public: + /** Constructor. + * \param kw The keyword 'default'. + * \param c The colon behind the keyword. + * \param stmt The statement of the default case. */ + CT_DefaultStmt (CTree *kw, CTree *c, CTree *stmt) { + AddSon (sons[0], kw); AddSon (sons[1], c); AddSon (sons[2], stmt); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 3; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 3, n); } + /** Get the statement. */ + CT_Statement *Statement () const { return (CT_Statement*)sons[2]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 3, old_son, new_son); + } +}; + +/** \class CT_TryStmt CTree.h Puma/CTree.h + * Tree node representing a try-catch statement. + * Example: \code try { f(); } catch (...) {} \endcode */ +class CT_TryStmt : public CT_Statement { + CTree *sons[3]; // try, stmt, handlers + +public: + /** Constructor. + * \param t The keyword 'try'. + * \param s The statement enclosed in the try-catch block. + * \param h The exception handler sequence. */ + CT_TryStmt (CTree *t, CTree *s, CTree *h) { + AddSon (sons[0], t); AddSon (sons[1], s); AddSon (sons[2], h); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 3; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 3, n); } + /** Get the enclosed statement. */ + CT_Statement *Statement () const { return (CT_Statement*)sons[1]; } + /** Get the exception handler sequence. */ + CT_HandlerSeq *Handlers () const { return (CT_HandlerSeq*)sons[2]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 3, old_son, new_son); + } +}; + +/** \class CT_CaseStmt CTree.h Puma/CTree.h + * Tree node representing a case statement. + * Example: \code case 42: a=42; \endcode */ +class CT_CaseStmt : public CT_Statement { + CTree *sons[4]; // keyword, expr, colon, stmt + +public: + /** Constructor. + * \param kw The keyword 'case'. + * \param expr The constant expression specifying the case value. + * \param c The colon. + * \param stmt The statement of the case. */ + CT_CaseStmt (CTree *kw, CTree *expr, CTree *c, CTree *stmt) { + AddSon (sons[0], kw); AddSon (sons[1], expr); + AddSon (sons[2], c); AddSon (sons[3], stmt); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 4; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 4, n); } + /** Get the statement. */ + CT_Statement *Statement () const { return (CT_Statement*)sons[3]; } + /** Get the expression specifying the case value. */ + CTree *Expr () const { return sons[1]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 4, old_son, new_son); + } +}; + +/** \class CT_ExprStmt CTree.h Puma/CTree.h + * Tree node representing an expression statement. + * Example: \code a+b; \endcode */ +class CT_ExprStmt : public CT_Statement { + CTree *sons[2]; // expr, semi_colon + +public: + /** Constructor. + * \param expr The expression. + * \param sc The trailing semi-colon. */ + CT_ExprStmt (CTree *expr, CTree *sc) { AddSon (sons[0], expr); AddSon (sons[1], sc); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 2); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 2, n); } + /** Get the expression. */ + CTree *Expr () const { return sons[0]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 2, old_son, new_son); + } +}; + +/** \class CT_DeclStmt CTree.h Puma/CTree.h + * Tree node representing a declaration statement. + * Example: \code int i = 0; \endcode */ +class CT_DeclStmt : public CT_Statement { + CTree *_decl; + +public: + /** Constructor. + * \param decl The declaration. */ + CT_DeclStmt (CTree *decl) { AddSon (_decl, decl); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 1; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return n == 0 ? _decl : (CTree*)0; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) + { CTree::ReplaceSon (_decl, old_son, new_son); } +}; + +/** \class CT_SwitchStmt CTree.h Puma/CTree.h + * Tree node representing a switch statement. + * Example: \code switch(a) { case 0: a++; } \endcode */ +class CT_SwitchStmt : public CT_Statement, public CSemScope { + CTree *sons[5]; // keyword, open, cond, close, stmt + +public: + /** Constructor. + * \param kw The keyword 'switch'. + * \param o Left parenthesis before the condition. + * \param cond The switch-expression. + * \param c Right parenthesis behind the condition. + * \param stmt The cases of the switch-statement. */ + CT_SwitchStmt (CTree *kw, CTree *o, CTree *cond, CTree *c, CTree *stmt) { + AddSon (sons[0], kw); AddSon (sons[1], o); AddSon (sons[2], cond); + AddSon (sons[3], c); AddSon (sons[4], stmt); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 5; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 5, n); } + /** Get the cases. */ + CT_Statement *Statement () const { return (CT_Statement*)sons[4]; } + /** Get the switch-expression. */ + CTree *Condition () const { return sons[2]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 5, old_son, new_son); + } + /** Get the scope opened by the switch-statement. */ + CSemScope *SemScope () const { return (CSemScope*)this; } +}; + +/** \class CT_IfStmt CTree.h Puma/CTree.h + * Tree node representing a if-statement. + * Example: \code if(a==0) a++; \endcode */ +class CT_IfStmt : public CT_Statement, public CSemScope { + CTree *sons[5]; // keyword, open, cond, close, stmt + +public: + /** Constructor. + * \param kw The keyword 'if'. + * \param o Left parenthesis before the condition. + * \param cond The condition. + * \param c Right parenthesis behind the condition. + * \param stmt The controlled statement. */ + CT_IfStmt (CTree *kw, CTree *o, CTree *cond, CTree *c, CTree *stmt) { + AddSon (sons[0], kw); AddSon (sons[1], o); AddSon (sons[2], cond); + AddSon (sons[3], c); AddSon (sons[4], stmt); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 5; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 5, n); } + /** Get the controlled statement. */ + CT_Statement *Statement () const { return (CT_Statement*)sons[4]; } + /** Get the condition. */ + CTree *Condition () const { return sons[2]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 5, old_son, new_son); + } + /** Get the scope opened by the if-statement. */ + CSemScope *SemScope () const { return (CSemScope*)this; } +}; + +/** \class CT_IfElseStmt CTree.h Puma/CTree.h + * Tree node representing a if-else-statement. + * Example: \code if(a==0) a++; else a=0; \endcode */ +class CT_IfElseStmt : public CT_Statement, public CSemScope { + CTree *sons[7]; // if, open, cond, close, if_stmt, else, else_stmt + +public: + /** Constructor. + * \param i The keyword 'if'. + * \param o Left parenthesis before the condition. + * \param cond The condition. + * \param c Right parenthesis behind the condition. + * \param is The statement controlled by the if-branch. + * \param e The keyword 'else'. + * \param es The statement controlled by the else-branch. */ + CT_IfElseStmt (CTree *i, CTree *o, CTree *cond, CTree *c, + CTree *is, CTree *e, CTree *es) { + AddSon (sons[0], i); AddSon (sons[1], o); AddSon (sons[2], cond); + AddSon (sons[3], c); AddSon (sons[4], is); AddSon (sons[5], e); + AddSon (sons[6], es); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 7; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 7, n); } + /** Get the condition. */ + CTree *Condition () const { return sons[2]; } + /** Get the statement controlled by the if-branch. */ + CT_Statement *IfPart () const { return (CT_Statement*)sons[4]; } + /** Get the statement controlled by the else-branch. */ + CT_Statement *ElsePart () const { return (CT_Statement*)sons[6]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 7, old_son, new_son); + } + /** Get the scope opened by the if-statement. */ + CSemScope *SemScope () const { return (CSemScope*)this; } +}; + +/** \class CT_BreakStmt CTree.h Puma/CTree.h + * Tree node representing a break-statement. + * Example: \code break; \endcode */ +class CT_BreakStmt : public CT_Statement { + CTree *sons[2]; // key, semi_colon + +public: + /** Constructor. + * \param key The keyword 'break'. + * \param sc The trailing semi-colon. */ + CT_BreakStmt (CTree *key, CTree *sc) { AddSon (sons[0], key); AddSon (sons[1], sc); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 2; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 2, n); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 2, old_son, new_son); + } +}; + +/** \class CT_ContinueStmt CTree.h Puma/CTree.h + * Tree node representing a continue-statement. + * Example: \code continue; \endcode */ +class CT_ContinueStmt : public CT_Statement { + CTree *sons[2]; // key, semi_colon + +public: + /** Constructor. + * \param key The keyword 'continue'. + * \param sc The trailing semi-colon. */ + CT_ContinueStmt (CTree *key, CTree *sc) { AddSon (sons[0], key); AddSon (sons[1], sc); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 2; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 2, n); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 2, old_son, new_son); + } +}; + +/** \class CT_GotoStmt CTree.h Puma/CTree.h + * Tree node representing a goto-stmt. + * Example: \code goto incr_a; \endcode */ +class CT_GotoStmt : public CT_Statement { + CTree *sons[3]; // key, label, semi_colon + +public: + /** Constructor. + * \param key The keyword 'goto'. + * \param l The name of the jump label. + * \param sc The trailing semi-colon. */ + CT_GotoStmt (CTree *key, CTree *l, CTree *sc) { + AddSon (sons[0], key); AddSon (sons[1], l); AddSon (sons[2], sc); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 3; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 3, n); } + /** Get the name of the jump label. */ + CT_SimpleName *Label () const { return (CT_SimpleName*)sons[1]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 3, old_son, new_son); + } +}; + +/** \class CT_ReturnStmt CTree.h Puma/CTree.h + * Tree node representing a return-statement. + * Example: \code return 1; \endcode */ +class CT_ReturnStmt : public CT_Statement { + CTree *sons[3]; // key, expr, semi_colon + +public: + /** Constructor. + * \param key The keyword 'return'. + * \param e The expression specifying the return value. + * \param sc The trailing semi-colon. */ + CT_ReturnStmt (CTree *key, CTree *e, CTree *sc) { + AddSon (sons[0], key); AddSon (sons[1], e); AddSon (sons[2], sc); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 3); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 3, n); } + /** Get the expression specifying the return value. */ + CTree *Expr () const { return sons[1]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 3, old_son, new_son); + } +}; + +/** \class CT_WhileStmt CTree.h Puma/CTree.h + * Tree node representing a while-statement. + * Example: \code while(a>0) a--; \endcode */ +class CT_WhileStmt : public CT_Statement, public CSemScope { + CTree *sons[5]; // key, open, cond, close, stmt + +public: + /** Constructor. + * \param kw The keyword 'while'. + * \param o Left parenthesis before the condition. + * \param cond The loop condition. + * \param c Right parenthesis behind the condition. + * \param stmt The controlled statement. */ + CT_WhileStmt (CTree *kw, CTree *o, CTree *cond, CTree *c, CTree *stmt) { + AddSon (sons[0], kw); AddSon (sons[1], o); AddSon (sons[2], cond); + AddSon (sons[3], c); AddSon (sons[4], stmt); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 5; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 5, n); } + /** Get the controlled statement. */ + CT_Statement *Statement () const { return (CT_Statement*)sons[4]; } + /** Get the loop condition. */ + CTree *Condition () const { return sons[2]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 5, old_son, new_son); + } + /** Get the scope opened by the while-statement. */ + CSemScope *SemScope () const { return (CSemScope*)this; } +}; + +/** \class CT_DoStmt CTree.h Puma/CTree.h + * Tree node representing a do-while-statement. + * Example: \code do a--; while(a>0); \endcode */ +class CT_DoStmt : public CT_Statement { + CTree *sons[7]; // do, stmt, while, open, expr, close, semi_colon + +public: + /** Constructor. + * \param d The keyword 'do'. + * \param stmt The controlled statement. + * \param w The keyword 'while'. + * \param o Left parenthesis before the loop condition. + * \param e The loop condition. + * \param c Right parenthesis behind the loop condition. + * \param sc The trailing semi-colon. */ + CT_DoStmt (CTree *d, CTree *stmt, CTree *w, CTree *o, CTree *e, + CTree *c, CTree *sc) { + AddSon (sons[0], d); AddSon (sons[1], stmt); AddSon (sons[2], w); + AddSon (sons[3], o); AddSon (sons[4], e); AddSon (sons[5], c); + AddSon (sons[6], sc); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 7; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 7, n); } + /** Get the controlled statement. */ + CT_Statement *Statement () const { return (CT_Statement*)sons[1]; } + /** Get the loop condition. */ + CTree *Expr () const { return sons[4]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 7, old_son, new_son); + } +}; + +/** \class CT_ForStmt CTree.h Puma/CTree.h + * Tree node representing a for-statement. + * Example: \code for(int i=0; i<10; i++) f(i); \endcode */ +class CT_ForStmt : public CT_Statement, public CSemScope { + CTree *sons[8]; // key, open, init, cond, semi_colon, expr, close, stmt + +public: + /** Constructor. + * \param k The keyword 'for'. + * \param o Left parenthesis. + * \param i The loop initializer statement. + * \param co The loop condition. + * \param sc The semi-colon behind the loop condition. + * \param e The loop counter expression. + * \param c Right parenthesis. + * \param stmt The controlled statement. */ + CT_ForStmt (CTree *k, CTree *o, CTree *i, CTree *co, CTree *sc, + CTree *e, CTree *c, CTree *stmt) { + AddSon (sons[0], k); AddSon (sons[1], o); AddSon (sons[2], i); + AddSon (sons[3], co); AddSon (sons[4], sc); AddSon (sons[5], e); + AddSon (sons[6], c); AddSon (sons[7], stmt); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 8); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 8, n); } + /** Get the loop initializer. */ + CTree *InitStmt () const { return sons[2]; } + /** Get the loop condition. */ + CTree *Condition () const { return sons[3]; } + /** Get the loop counter expression. */ + CTree *Expr () const { return sons[5]; } + /** Get the controlled statement. */ + CT_Statement *Statement () const { return (CT_Statement*)sons[7]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 8, old_son, new_son); + } + /** Get the scope opened by the for-statement. */ + CSemScope *SemScope () const { return (CSemScope*)this; } +}; + +/** \class CT_Condition CTree.h Puma/CTree.h + * Tree node representing a control-statement condition. + * Example: \code int i = 0 \endcode */ +class CT_Condition : public CT_Decl, public CSemObject { + CTree *sons[3]; // declspecs, declarator, init + +public: + /** Constructor. + * \param dsl The declaration specifier sequence. + * \param d The variable declarator. */ + CT_Condition (CTree *dsl, CTree *d) { + AddSon (sons[0], dsl); AddSon (sons[1], d); AddSon (sons[2], 0); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 3); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 3, n); } + /** Get the declaration specifier sequence. */ + CT_DeclSpecSeq *DeclSpecs () const { return (CT_DeclSpecSeq*)sons[0]; } + /** Get the declarator. */ + CTree *Declarator () const { return sons[1]; } + /** Get the initializer of the declaration. */ + CT_ExprList *Initializer () const { return (CT_ExprList*)sons[2]; } + /** Get the semantic information of the declared object. */ + CSemObject *SemObject () const { return (CSemObject*)this; } + /** Set the initializer. */ + void Initializer (CTree *i) { AddSon (sons[2], i); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 3, old_son, new_son); + } +}; + +/*****************************************************************************/ +/* */ +/* Classes */ +/* */ +/*****************************************************************************/ + +/** \class CT_ClassDef CTree.h Puma/CTree.h + * Tree node representing a class definition. + * Example: \code class X : Y { int x; } \endcode */ +class CT_ClassDef : public CT_Decl, public CSemObject { + CTree *sons[4]; // key, name, bases, members + CTree *obj_decl; + +public: + /** Constructor. + * \param k The keyword 'class' or 'struct'. + * \param n The name of the class. + * \param b The base class list. */ + CT_ClassDef (CTree *k, CTree *n, CTree *b = (CTree*)0) { + AddSon (sons[0], k); AddSon (sons[1], n); AddSon (sons[2], b); + AddSon (sons[3], 0); AddSon (obj_decl, 0); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 4); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 4, n); } + /** Get the name of the class. */ + CT_SimpleName *Name () const { return (CT_SimpleName*)sons[1]; } + /** Get the member declarations list. */ + CT_MembList *Members () const { return (CT_MembList*)sons[3]; } + /** Get the base class specifiers list. */ + CT_BaseSpecList *BaseClasses () const { return (CT_BaseSpecList*)sons[2]; } + /** Get the object declaration node containing the class definition. */ + CT_ObjDecl *ObjDecl () const { return (CT_ObjDecl*)obj_decl; } + /** Get the semantic information about the declared class. */ + CSemObject *SemObject () const { return (CSemObject*)this; } + /** Set the member declarations list. */ + void Members (CTree *m) { AddSon (sons[3], m); } + /** Set the base class specifiers list. */ + void BaseClasses (CTree *bc) { AddSon (sons[2], bc); } + /** Set the object declaration containing the class definition. */ + void ObjDecl (CTree *od) { AddSon (obj_decl, od); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 4, old_son, new_son); + } +}; + +/** \class CT_UnionDef CTree.h Puma/CTree.h + * Tree node representing the definition of a union. + * Example: \code union U { int i; } \endcode */ +class CT_UnionDef : public CT_ClassDef { +public: + /** Constructor. + * \param k The keyword 'union'. + * \param n The name of the union. + * \param b The base union list. */ + CT_UnionDef (CTree *k, CTree *n, CTree *b = 0) : CT_ClassDef (k, n, b) {} + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } +}; + +/** \class CT_MembList CTree.h Puma/CTree.h + * Tree node representing a member declarations list. */ +class CT_MembList : public CT_DeclList, public CSemScope { +public: + CT_MembList (int size = 10, int incr = 10) : + CT_DeclList (size, incr) {} + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the scope opened by the member declarations list. */ + CSemScope *SemScope () const { return (CSemScope*)this; } +}; + +/** \class CT_MembInitList CTree.h Puma/CTree.h + * Tree node representing a constructor initializer list. + * Example: \code : Base(), m_Member(0) \endcode */ +class CT_MembInitList : public CT_List, public CSemScope { +public: + /** Constructor. + * \param size The initial size of the list. */ + CT_MembInitList (int size = 2) : + CT_List (size, 2, CT_List::OPEN) {} + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the scope opened by the member initializer list. */ + CSemScope *SemScope () const { return (CSemScope*)this; } +}; + +/** \class CT_MembInit CTree.h Puma/CTree.h + * Tree node representing a member initializer. + * Example: \code m_Member(0) \endcode */ +class CT_MembInit : public CT_Expression, public CSemObject { + CTree *sons[2]; // name, init + +public: + /** Constructor. + * \param n The name of the member. + * \param i The member initializer. */ + CT_MembInit (CTree *n, CTree *i) { AddSon (sons[0], n); AddSon (sons[1], i); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 2; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 2, n); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 2, old_son, new_son); + } + /** Get the name of the member. */ + CT_SimpleName *Name () const { return (CT_SimpleName*)sons[0]; } + /** Get the initializer. */ + CT_ExprList *Initializer () const { return (CT_ExprList*)sons[1]; } + /** Get the semantic information about the initialized member. */ + CSemObject *SemObject () const { return (CSemObject*)this; } +}; + +/** \class CT_BaseSpecList CTree.h Puma/CTree.h + * Tree node representing a base specifier list. + * Example: \code : X, Y, Z \endcode */ +class CT_BaseSpecList : public CT_List { +public: + /** Constructor. + * \param size The initial size of the list. */ + CT_BaseSpecList (int size = 2) : + CT_List (size, 2, CT_List::OPEN|CT_List::SEPARATORS) {} + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } +}; + +/** \class CT_AccessSpec CTree.h Puma/CTree.h + * Tree node representing an access specifier. + * Example: \code public: \endcode */ +class CT_AccessSpec : public CTree { + CTree *sons[2]; // access, colon + +public: + /** Constructor. + * \param a The access specifier, i.e. 'public', 'private', or 'protected'. + * \param c The trailing colon. */ + CT_AccessSpec (CTree *a, CTree *c) { AddSon (sons[0], a); AddSon (sons[1], c); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 2; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 2, n); } + /** Get the access specifier type (token type). */ + int Access () const { return sons[0]->token ()->type (); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 2, old_son, new_son); + } +}; + +/** \class CT_BaseSpec CTree.h Puma/CTree.h + * Tree node representing a base class specifier. + * Example: \code public X \endcode */ +class CT_BaseSpec : public CTree { + CTree *sons[3]; // virtual, access, name + +public: + /** Constructor. + * \param v Optional keyword 'virtual'. + * \param a The optional access specifier. + * \param n The name of the base class. */ + CT_BaseSpec (CTree *v, CTree *a, CTree *n) { + AddSon (sons[0], v); AddSon (sons[1], a); AddSon (sons[2], n); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 3); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 3, n); } + /** Get the type of the access specifier (token type). */ + int Access () const { return sons[1]->token ()->type (); } + /** The access specifier. */ + CTree *AccessSpec () const { return sons[1]; } + /** Get the keyword 'virtual'. */ + CTree *Virtual () const { return sons[0]; } + /** Get the name of the base class. */ + CT_SimpleName *Name () const { return (CT_SimpleName*)sons[2]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 3, old_son, new_son); + } +}; + +/** \class CT_AccessDecl CTree.h Puma/CTree.h + * Tree node representing a member access declaration. + * Example: \code m_BaseClassMember; \endcode */ +class CT_AccessDecl : public CT_Decl { + CTree *sons[2]; // name, semi_colon + +public: + /** Constructor. + * \param n The name of the base class member. + * \param s The trailing semi-colon. */ + CT_AccessDecl (CTree *n, CTree *s) { AddSon (sons[0], n); AddSon (sons[1], s); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 2; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 2, n); } + /** Get the name of the base class member. */ + CT_QualName *Member () const { return (CT_QualName*)sons[0]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 2, old_son, new_son); + } +}; + +/** \class CT_UsingDecl CTree.h Puma/CTree.h + * Tree node representing a using declaration. + * Example: \code using Base::m_Member; \endcode */ +class CT_UsingDecl : public CT_AccessDecl { + CTree *sons[2]; // using, typename + +public: + /** Constructor. + * \param u The keyword 'using'. + * \param n The name of the entity. + * \param s The trailing semi-colon. */ + CT_UsingDecl (CTree *u, CTree *n, CTree *s) : CT_AccessDecl (n, s) { + AddSon (sons[0], u); AddSon (sons[1], 0); + } + /** Constructor. + * \param u The keyword 'using'. + * \param t The keyword 'typename'. + * \param n The name of the entity. + * \param s The trailing semi-colon. */ + CT_UsingDecl (CTree *u, CTree *t, CTree *n, CTree *s) : CT_AccessDecl (n, s) { + AddSon (sons[0], u); AddSon (sons[1], t); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 2) + CT_AccessDecl::Sons (); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { + int num = CTree::Sons (sons, 2); + CTree *result = CTree::Son (sons, 2, n); + return result ? result : CT_AccessDecl::Son (n-num); + } + /** Get the keyword 'typename'. */ + CTree *Typename () const { return sons[1]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 2, old_son, new_son); + CT_AccessDecl::ReplaceSon (old_son, new_son); + } +}; + +/*****************************************************************************/ +/* */ +/* Wildcards */ +/* */ +/*****************************************************************************/ + +/** \class CT_Any CTree.h Puma/CTree.h + * Tree node representing a wildcard. */ +class CT_Any : public CTree { + CTree *sons[2]; // keyword, extension + +public: + /** Constructor. + * \param k The wildcard keyword. + * \param e The extension. */ + CT_Any (CTree *k, CTree *e = (CTree*)0) { AddSon (sons[0], k); AddSon (sons[1], e); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 2); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 2, n); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 2, old_son, new_son); + } + /** Get the type of the wildcard (token type). */ + int AnyType () const { return sons[0]->token ()->type (); } + /** Get the extension. */ + CT_AnyExtension *Extension () const { return (CT_AnyExtension*)sons[1]; } +}; + +/** \class CT_AnyList CTree.h Puma/CTree.h + * Tree node representing a list wildcard. */ +class CT_AnyList : public CT_Any { +public: + /** Constructor. + * \param k The wildcard keyword. + * \param e The extension. */ + CT_AnyList (CTree *k, CTree *e = (CTree*)0) : CT_Any (k, e) {} + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } +}; + +/** \class CT_AnyExtension CTree.h Puma/CTree.h + * Tree node representing a wildcard extension. */ +class CT_AnyExtension : public CTree, public CSemValue { + CTree *sons[5]; // open, string, comma, cond, close + +public: + /** Constructor. + * \param o Left parenthesis before the extension. + * \param n The name of the extension. + * \param co The comma between the name and the condition. + * \param c The condition. + * \param cr Right parenthesis behind the extension. */ + CT_AnyExtension (CTree *o, CTree *n, CTree *co, CTree *c, CTree *cr) { + AddSon (sons[0], o); AddSon (sons[1], n); AddSon (sons[2], co); + AddSon (sons[3], c); AddSon (sons[4], cr); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 5); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 5, n); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 5, old_son, new_son); + } + /** Get the condition. */ + CTree *Condition () const { return sons[3]; } + /** Get the name string. */ + CT_Token *String () const { return (CT_Token*)sons[1]; } + /** Get the extension name. */ + const char *Name () const { return value ? value->StrLiteral ()->String () : (const char*)0; } + /** Get the value of the extension (the name). */ + CExprValue *Value () const { return value; } + /** Get the semantic value information object. */ + CSemValue *SemValue () const { return (CSemValue*)this; } +}; + +/** \class CT_AnyCondition CTree.h Puma/CTree.h + * Tree node representing the condition of a wildcard. */ +class CT_AnyCondition : public CTree { + CTree *sons[3]; // arg1, arg2, arg3 + +public: + /** Constructor. + * \param a1 The first argument. + * \param a2 The optional second argument. + * \param a3 The optional third argument. */ + CT_AnyCondition (CTree *a1, CTree *a2 = (CTree*)0, CTree *a3 = (CTree*)0) { + AddSon (sons[0], a1); AddSon (sons[1], a2); AddSon (sons[2], a3); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 3); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 3, n); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 3, old_son, new_son); + } +}; + + +} // namespace Puma + +#endif /* __CTree_h__ */ diff --git a/Puma/src/parser/cparser/CUnit.cc b/Puma/src/parser/cparser/CUnit.cc new file mode 100644 index 0000000..480c712 --- /dev/null +++ b/Puma/src/parser/cparser/CUnit.cc @@ -0,0 +1,35 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CUnit.h" +#include "Puma/ErrorStream.h" +#include "Puma/CScanner.h" + +namespace Puma { + + +void CUnit::scan () { + _scanner.allow_wildcards (); + _scanner.fill_unit (str ().c_str (), *this); + + str (""); + std::ostringstream::clear (); +} + + +} // namespace Puma diff --git a/Puma/src/parser/cparser/CUnit.h b/Puma/src/parser/cparser/CUnit.h new file mode 100644 index 0000000..3279183 --- /dev/null +++ b/Puma/src/parser/cparser/CUnit.h @@ -0,0 +1,79 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __c_unit_h__ +#define __c_unit_h__ + +/** \file + * C/C++ token chain. */ + +#include "Puma/Unit.h" +#include "Puma/CScanner.h" +#include "Puma/ErrorSink.h" +#include + +namespace Puma { + + +/** \class CUnit CUnit.h Puma/CUnit.h + * Specialized token unit for C/C++ tokens. Provides + * a streaming interface for easy scanning of C/C++ + * tokens using a Puma::CScanner object. The input + * stream is scanned either by calling Puma::CUnit::scan() + * or by using the stream manipulator Puma::endu. + * + * Example: + * \code + * Puma::ErrorStream es; + * Puma::CUnit unit(es) + * unit << "int main() {" << std::endl; + * unit << " int fac0 = 1;" << std::endl; + * for (int i = 1; i < 10; i++) { + * unit << " int fac" << i << " = " << i + * << " * fac" << (i-1) << ";" << std::endl; + * } + * unit << "}\n" << Puma::endu; + * \endcode */ +class CUnit : public Unit, public std::ostringstream { + CScanner _scanner; + +public: + /** Constructor. + * \param err The error stream on which to report errors. */ + CUnit (ErrorSink &err) : _scanner (err) {} + /** Destructor. */ + virtual ~CUnit () {} + + /** Get the scanner used to scan the string stream. */ + CScanner &scanner () const { return (CScanner&)_scanner; } + /** Scan the stream now. Produces the token chain. */ + void scan (); +}; + +/** End-of-unit stream manipulator. Triggers scanning the + * C/C++ source code stream. + * \param outs The Puma::CUnit stream object. */ +inline std::ostream &endu (std::ostream &outs) { + ((CUnit&)outs).scan (); + return outs; +} + + +} // namespace Puma + +#endif /* __c_unit_h__ */ diff --git a/Puma/src/parser/cparser/GnuCTree.h b/Puma/src/parser/cparser/GnuCTree.h new file mode 100644 index 0000000..44bf376 --- /dev/null +++ b/Puma/src/parser/cparser/GnuCTree.h @@ -0,0 +1,408 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __gnu_c_tree_h__ +#define __gnu_c_tree_h__ + +/** \file + * GNU C/C++ specific syntax tree classes. */ + +namespace Puma { + +// Syntax tree node hierarchy: +class CT_GnuAsmSpec; // derived from CTree +class CT_GnuAsmDef; // derived from CT_AsmDef +class CT_GnuAsmOperand; // derived from CTree +class CT_GnuAsmOperands; // derived from CT_List +class CT_GnuAsmClobbers; // derived from CT_List +class CT_GnuStatementExpr; // derived from CT_Expression +class CT_GnuTypeof; // derived from CT_DeclSpec +class CT_GnuAttribute; // derived from CTree +class CT_GnuLocalLabelStmt; // derived from CT_Statement and CT_List +class CT_LabelStmt; // derived from CT_Statement + +} // namespace Puma + +#include "Puma/CTree.h" + +namespace Puma { + + +/** \class CT_GnuAsmSpec GnuCTree.h Puma/GnuCTree.h + * Tree node representing an extended inline assembly specifier. + * Example: \code asm("r0") \endcode */ +class CT_GnuAsmSpec : public CTree { + CTree *sons[4]; // asm, open, expr, close + +public: + /** Constructor. + * \param a The keyword 'asm'. + * \param o Left parenthesis before the assembly. + * \param e The assembly instructions. + * \param c Right parenthesis behind the assembly. */ + CT_GnuAsmSpec (CTree *a, CTree *o, CTree *e, CTree *c) { + AddSon (sons[0], a); AddSon (sons[1], o); + AddSon (sons[2], e); AddSon (sons[3], c); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 4; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 4, n); } + /** Get the assembly instructions. */ + CT_Expression *Expr () const { return (CT_Expression*)sons[2]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 4, old_son, new_son); + } +}; + +/** \class CT_GnuAsmDef GnuCTree.h Puma/GnuCTree.h + * Tree node representing an extended inline assembly definition. + * Example: \code asm("fsinx %1,%0" : "=f" (result) : "f" (angle)); \endcode */ +class CT_GnuAsmDef : public CT_AsmDef { + CTree *_cvqual; + CTree *_operands0; + CTree *_operands1; + CTree *_clobbers; + +public: + /** Constructor. + * \param a The keyword 'asm'. + * \param cv Optional const/volatile qualifier sequence. + * \param o Left parenthesis before the assembly. + * \param s The assembly instructions. + * \param op0 First operand. + * \param op1 Second operand. + * \param cl Clobbers. + * \param c Right parenthesis behind the assembly. + * \param sc The trailing semi-colon. */ + CT_GnuAsmDef (CTree *a, CTree *cv, CTree *o, CTree *s, + CTree *op0, CTree *op1, CTree *cl, CTree *c, CTree *sc) : + CT_AsmDef (a, o, s, c, sc) { + AddSon (_cvqual, cv); AddSon (_operands0, op0); + AddSon (_operands1, op1); AddSon (_clobbers, cl); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + virtual int Sons () const { + return 5 + + (_cvqual ? 1 : 0) + + (_operands0 ? 1 : 0) + + (_operands1 ? 1 : 0) + + (_clobbers ? 1 : 0); + } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + virtual CTree *Son (int n) const { + int have_cv = _cvqual ? 1 : 0; + int gnu_sons = Sons () - have_cv - 5; + int gnu_first = 3 + have_cv; + if (n == 0) return CT_AsmDef::Son (0); + else if (n == 1 && _cvqual) return _cvqual; + else if ((n == 1 && !_cvqual) || (n == 2 && _cvqual)) + return CT_AsmDef::Son (1); + else if ((n == 2 && !_cvqual) || (n == 3 && _cvqual)) + return CT_AsmDef::Son (2); + else if (n == gnu_first && gnu_sons >= 1) return _operands0; + else if (n == gnu_first + 1 && gnu_sons >= 2) return _operands1; + else if (n == gnu_first + 2 && gnu_sons >= 3) return _clobbers; + else if (n == Sons () - 2) + return CT_AsmDef::Son (3); + else if (n == Sons () - 1) + return CT_AsmDef::Son (4); + else return (CTree*)0; + } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + virtual void ReplaceSon (CTree *old_son, CTree *new_son) { + if (old_son == _cvqual) CTree::ReplaceSon (_cvqual, old_son, new_son); + else if (old_son == _operands0) CTree::ReplaceSon (_operands0, old_son, new_son); + else if (old_son == _operands1) CTree::ReplaceSon (_operands1, old_son, new_son); + else if (old_son == _clobbers) CTree::ReplaceSon (_clobbers, old_son, new_son); + else CT_AsmDef::ReplaceSon (old_son, new_son); + } +}; + +/** \class CT_GnuAsmOperand GnuCTree.h Puma/GnuCTree.h + * Tree node representing an extended inline assembly operand. + * Example: \code "=f" (result) \endcode */ +class CT_GnuAsmOperand : public CTree { + CTree *sons[7]; // [ open_square, symbol, close_square ], string, open, expr, close + +public: + /** Constructor. + * \param s The operand constraint string. + * \param o Left parenthesis before the operand. + * \param e The operand. + * \param c Right parenthesis behind the operand. */ + CT_GnuAsmOperand (CTree *s, CTree *o, CTree *e, CTree *c) { + sons[0] = 0; sons[1] = 0; sons[2] = 0; + AddSon (sons[3], s); AddSon (sons[4], o); + AddSon (sons[5], e); AddSon (sons[6], c); + } + /** Constructor. + * \param no opening square backet of the symbolic operand name (optional) + * \param on symbolic operand name (optional) + * \param nc closing square backet of the symbolic operand name (optional) + * \param s The operand constraint string. + * \param o Left parenthesis before the operand. + * \param e The operand. + * \param c Right parenthesis behind the operand. */ + CT_GnuAsmOperand (CTree *no, CTree *on, CTree *nc, + CTree *s, CTree *o, CTree *e, CTree *c) { + AddSon (sons[0], no), AddSon (sons[1], on), AddSon (sons[2], nc), + AddSon (sons[3], s); AddSon (sons[4], o); + AddSon (sons[5], e); AddSon (sons[6], c); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return sons[0] ? 7 : 4; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 7, n); } + /** Get the operand expression. */ + CT_Expression *Expr () const { return (CT_Expression*)sons[5]; } + /** Get the operand constraint string. */ + CT_String *String () const { return (CT_String*)sons[3]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 7, old_son, new_son); + } +}; + +/** \class CT_GnuAsmOperands GnuCTree.h Puma/GnuCTree.h + * Tree node representing a list of extended inline assembly operands. + * Example: \code : "=f" (result) : "f" (angle) \endcode */ +class CT_GnuAsmOperands : public CT_List { +public: + /** Constructor. */ + CT_GnuAsmOperands () { AddProperties (OPEN | SEPARATORS); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } +}; + +/** \class CT_GnuAsmClobbers GnuCTree.h Puma/GnuCTree.h + * Tree node representing a list of extended inline assembly clobbers. + * Example: \code : "r1", "r2", "r3", "r4", "r5" \endcode */ +class CT_GnuAsmClobbers : public CT_List { +public: + /** Constructor. */ + CT_GnuAsmClobbers () { AddProperties (OPEN | SEPARATORS); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } +}; + +/** \class CT_GnuAttribute GnuCTree.h Puma/GnuCTree.h + * Tree node representing a attribute (gnu c syntax extension) + * Example: \code __attribute__(interrupt) \endcode */ +class CT_GnuAttribute : public CT_List { + +public: + /** Constructor. */ + CT_GnuAttribute () { AddProperties (OPEN_CLOSE | INTRO); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } +}; + +/*****************************************************************************/ +/* */ +/* Expressions */ +/* */ +/*****************************************************************************/ + +/** \class CT_GnuStatementExpr GnuCTree.h Puma/GnuCTree.h + * Tree node representing a statement expression. + * Example: \code ({ int i = 0; i++; }) \endcode */ +class CT_GnuStatementExpr : public CT_Expression { + CTree *sons[3]; // open, statement, close + +public: + /** Constructor. + * \param o Left parenthesis before the statement. + * \param s The statement. + * \param c Right parenthesis behind the statement. */ + CT_GnuStatementExpr (CTree *o, CTree *s, CTree *c) { + AddSon (sons[0], o); AddSon (sons[1], s); AddSon (sons[2], c); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 3; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 3, n); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 3, old_son, new_son); + } + /** Get the statement. */ + CT_CmpdStmt *CmpdStmt () const { return (CT_CmpdStmt*)sons[1]; } +}; + +/*****************************************************************************/ +/* */ +/* Declaration specifiers */ +/* */ +/*****************************************************************************/ + +/** \class CT_GnuTypeof GnuCTree.h Puma/GnuCTree.h + * Tree node representing a typeof expression. + * Example: \code typeof(a+b) \endcode */ +class CT_GnuTypeof : public CT_DeclSpec, public CSemValue { + CTree *sons[5]; // key, open, type, close, expr + +public: + /** Constructor. + * \param k The keyword 'typeof'. + * \param o Left parenthesis before the type. + * \param t The type from which to get the type string. + * \param c Right parenthesis behind the type. */ + CT_GnuTypeof (CTree *k, CTree *o, CTree *t, CTree *c) { + AddSon (sons[0], k); AddSon (sons[1], o); AddSon (sons[2], t); + AddSon (sons[3], c); AddSon (sons[4], 0); + } + /** Constructor. + * \param k The keyword 'typeof'. + * \param e The expression from which to get the type string. */ + CT_GnuTypeof (CTree *k, CTree *e) { + AddSon (sons[0], k); AddSon (sons[1], 0); AddSon (sons[2], 0); + AddSon (sons[3], 0); AddSon (sons[4], e); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CTree::Sons (sons, 5); } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 5, n); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 5, old_son, new_son); + } + /** Get the expression from which to get the type string. */ + CTree *Expr () const { return sons[4]; } + /** Get the type from which to get the type string. */ + CT_NamedType *TypeName () const { return (CT_NamedType*)sons[2]; } + /** Get the semantic value information. */ + CSemValue *SemValue () const { return (CSemValue*)this; } + /** Get the resulting type. */ + CTypeInfo *Type () const { return type; } +}; + +/*****************************************************************************/ +/* */ +/* Statements */ +/* */ +/*****************************************************************************/ + +/** \class CT_GnuLocalLabelStmt GnuCTree.h Puma/GnuCTree.h + * Tree node representing a list of local labels. + * Example: \code __label__ L1, L2; \endcode */ +class CT_GnuLocalLabelStmt : public CT_Statement, public CT_List { +public: + /** Constructor. */ + CT_GnuLocalLabelStmt () { AddProperties (OPEN | SEPARATORS | CLOSE); } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return CT_List::Sons (); } +}; + +/** \class CT_GnuCaseStmt GnuCTree.h Puma/GnuCTree.h + * Tree node representing a label statement with case range. + * Example: \code case 10 ... 20: a++; \endcode */ +class CT_GnuCaseStmt : public CT_Statement { + CTree *sons[6]; // case id ... id, colon, stmt + +public: + /** Constructor. + * \param kw The keyword 'case'. + * \param expr1 The constant expression specifying the first case value. + * \param dots The ellipsis token '...' + * \param expr2 The constant expression specifying the second case value. + * \param c The colon. + * \param stmt The statement of the case. */ + CT_GnuCaseStmt (CTree *kw, CTree *expr1, CTree *dots, CTree *expr2, + CTree *c, CTree *stmt) { + AddSon (sons[0], kw); AddSon (sons[1], expr1); AddSon (sons[2], dots); + AddSon (sons[3], expr2); AddSon (sons[4], c); AddSon (sons[5], stmt); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 6; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 6, n); } + /** Get the statement. */ + CT_Statement *Statement () const { return (CT_Statement*)sons[5]; } + /** Get the first const expression. */ + CT_SimpleName *Expr1 () const { return (CT_SimpleName*)sons[1]; } + /** Get the second const expression. */ + CT_SimpleName *Expr2 () const { return (CT_SimpleName*)sons[3]; } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 6, old_son, new_son); + } +}; + +} // namespace Puma + +#endif /* __gnu_c_tree_h__ */ diff --git a/Puma/src/parser/cparser/Utf8.cc b/Puma/src/parser/cparser/Utf8.cc new file mode 100644 index 0000000..2c295e6 --- /dev/null +++ b/Puma/src/parser/cparser/Utf8.cc @@ -0,0 +1,67 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/Utf8.h" + +namespace Puma { + +void utf8_encode (LONG_LONG i, char *&p, long int &ct) { + if (i <= 0x7f) { + *p++ = (char)i; + ct += 1; + } + else if (i <= 0x7ff) { + *p++ = (0xc0 | ((i & 0x700) >> 6) | ((i & 0xc0) >> 6)); + *p++ = (0x80 | (i & 0x3f)); + ct += 2; + } + else if (i <= 0xffff) { + *p++ = (0xe0 | ((i & 0xf000) >> 12)); + *p++ = (0x80 | ((i & 0x0f00) >> 6) | ((i & 0xc0) >> 6)); + *p++ = (0x80 | (i & 0x3f)); + ct += 3; + } + else if (i <= 0x10ffff) { + *p++ = (0xf0 | ((i & 0x1c0000) >> 18)); + *p++ = (0x80 | ((i & 0x3f000) >> 12)); + *p++ = (0x80 | ((i & 0xfc0) >> 6)); + *p++ = (0x80 | (i & 0x3f)); + ct += 4; + } +} + +LONG_LONG utf8_scan (const char *&s, bool eight_digits) { + int digits = (eight_digits ? 8 : 4); + LONG_LONG v = 0; + while (*s && digits > 0) { + if (*s >= '0' && *s <= '9') + v = (v<<4) + *s++ - '0'; + else if (*s >= 'a' && *s <= 'f') + v = (v<<4) + *s++ - 'a' + 10; + else if (*s >= 'A' && *s <= 'F') + v = (v<<4) + *s++ - 'A' + 10; + else { + v = -1; // This is an error => check with (ucs == true && result == -1) + break; + } + digits--; + } + return v; +} + +} // namespace Puma diff --git a/Puma/src/parser/cparser/Utf8.h b/Puma/src/parser/cparser/Utf8.h new file mode 100644 index 0000000..e988bba --- /dev/null +++ b/Puma/src/parser/cparser/Utf8.h @@ -0,0 +1,32 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __Utf8_h__ +#define __Utf8_h__ + +#include "Puma/Limits.h" + +namespace Puma { + +void utf8_encode (LONG_LONG i, char *&p, long int &ct); + +LONG_LONG utf8_scan (const char *&s, bool eight_digits); + +} // namespace Puma + +#endif /* __Utf8_h__ */ diff --git a/Puma/src/parser/cparser/WinCTree.h b/Puma/src/parser/cparser/WinCTree.h new file mode 100644 index 0000000..0bcac35 --- /dev/null +++ b/Puma/src/parser/cparser/WinCTree.h @@ -0,0 +1,76 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __win_c_tree_h__ +#define __win_c_tree_h__ + +/** \file + * VisualC++ specific syntax tree classes. */ + +namespace Puma { + + +// Syntax tree node hierarchy: +class CTree; +class CT_Statement; +class CT_AsmBlock; + + +} // namespace Puma + +#include "Puma/CTree.h" + +namespace Puma { + + +/** \class CT_AsmBlock WinCTree.h Puma/WinCTree.h + * Tree node representing an inline assembly block. + * Example: \code asm { movl ecx eax } \endcode */ +class CT_AsmBlock : public CT_Statement { + CTree *sons[3]; // key, begin, end + +public: + /** Constructor. + * \param k The keyword 'asm'. + * \param b Left brace. + * \param e Right brace. */ + CT_AsmBlock (CTree *k, CTree *b, CTree *e) { + AddSon (sons[0], k); AddSon (sons[1], b); AddSon (sons[2], e); + } + /** Get the identifier for this node type. Can be compared with NodeName(). */ + static const char *NodeId (); + /** Get the name of the node. Can be compared with NodeId(). */ + const char *NodeName () const { return NodeId (); } + /** Get the number of sons. */ + int Sons () const { return 3; } + /** Get the n-th son. + * \param n The index of the son. + * \return The n-th son or NULL. */ + CTree *Son (int n) const { return CTree::Son (sons, 3, n); } + /** Replace a son. + * \param old_son The son to replace. + * \param new_son The new son. */ + virtual void ReplaceSon (CTree *old_son, CTree *new_son) { + CTree::ReplaceSon (sons, 3, old_son, new_son); + } +}; + + +} // namespace Puma + +#endif /* __win_c_tree_h__ */ diff --git a/Puma/src/scanner/CCLexer.cc b/Puma/src/scanner/CCLexer.cc new file mode 100644 index 0000000..b5c6fa4 --- /dev/null +++ b/Puma/src/scanner/CCLexer.cc @@ -0,0 +1,75 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CCLexer.h" + +namespace Puma { + + void CCLexer::add_keywords (lexertl::rules &rules) { + + // add the keywords from C first + CLexer::add_c89_keywords (rules); + + // C++ boolean constants + rules.push ("true", TOK_BOOL_VAL, LID(Token::keyword_id)); + rules.push ("false", TOK_BOOL_VAL, LID(Token::keyword_id)); + + // C++ keywords + rules.push ("bool", TOK_BOOL, LID(Token::keyword_id)); + rules.push ("catch", TOK_CATCH, LID(Token::keyword_id)); + rules.push ("class", TOK_CLASS, LID(Token::keyword_id)); + rules.push ("const_cast", TOK_CONST_CAST, LID(Token::keyword_id)); + rules.push ("delete", TOK_DELETE, LID(Token::keyword_id)); + rules.push ("dynamic_cast", TOK_DYN_CAST, LID(Token::keyword_id)); + rules.push ("explicit", TOK_EXPLICIT, LID(Token::keyword_id)); + rules.push ("export", TOK_EXPORT, LID(Token::keyword_id)); + rules.push ("friend", TOK_FRIEND, LID(Token::keyword_id)); + rules.push ("mutable", TOK_MUTABLE, LID(Token::keyword_id)); + rules.push ("namespace", TOK_NAMESPACE, LID(Token::keyword_id)); + rules.push ("new", TOK_NEW, LID(Token::keyword_id)); + rules.push ("operator", TOK_OPERATOR, LID(Token::keyword_id)); + rules.push ("private", TOK_PRIVATE, LID(Token::keyword_id)); + rules.push ("protected", TOK_PROTECTED, LID(Token::keyword_id)); + rules.push ("public", TOK_PUBLIC, LID(Token::keyword_id)); + rules.push ("reinterpret_cast", TOK_REINT_CAST, LID(Token::keyword_id)); + rules.push ("static_cast", TOK_STAT_CAST, LID(Token::keyword_id)); + rules.push ("template", TOK_TEMPLATE, LID(Token::keyword_id)); + rules.push ("this", TOK_THIS, LID(Token::keyword_id)); + rules.push ("throw", TOK_THROW, LID(Token::keyword_id)); + rules.push ("try", TOK_TRY, LID(Token::keyword_id)); + rules.push ("typeid", TOK_TYPEID, LID(Token::keyword_id)); + rules.push ("typename", TOK_TYPENAME, LID(Token::keyword_id)); + rules.push ("using", TOK_USING, LID(Token::keyword_id)); + rules.push ("virtual", TOK_VIRTUAL, LID(Token::keyword_id)); + rules.push ("wchar_t", TOK_WCHAR_T, LID(Token::keyword_id)); + + // C++ alternative representation of operators (ISO 646) + rules.push ("and", TOK_AND_AND_ISO_646, LID(Token::keyword_id)); + rules.push ("and_eq", TOK_AND_EQ_ISO_646, LID(Token::keyword_id)); + rules.push ("bitand", TOK_AND_ISO_646, LID(Token::keyword_id)); + rules.push ("bitor", TOK_OR_ISO_646, LID(Token::keyword_id)); + rules.push ("compl", TOK_TILDE_ISO_646, LID(Token::keyword_id)); + rules.push ("not", TOK_NOT_ISO_646, LID(Token::keyword_id)); + rules.push ("not_eq", TOK_NEQ_ISO_646, LID(Token::keyword_id)); + rules.push ("or", TOK_OR_OR_ISO_646, LID(Token::keyword_id)); + rules.push ("or_eq", TOK_IOR_EQ_ISO_646, LID(Token::keyword_id)); + rules.push ("xor", TOK_ROOF_ISO_646, LID(Token::keyword_id)); + rules.push ("xor_eq", TOK_XOR_EQ_ISO_646, LID(Token::keyword_id)); + } + +} // namespace Puma diff --git a/Puma/src/scanner/CCLexer.h b/Puma/src/scanner/CCLexer.h new file mode 100644 index 0000000..4e43f73 --- /dev/null +++ b/Puma/src/scanner/CCLexer.h @@ -0,0 +1,39 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __cc_lexer_h__ +#define __cc_lexer_h__ + +#include "Puma/CLexer.h" + +namespace Puma { + +class CCLexer : public CLexer { +public: + // get instance of the lexer + static CCLexer& instance(unsigned int id) { + return Lexer::instance(id); + } + + // override the C keywords + virtual void add_keywords (lexertl::rules &rules); +}; + +} // namespace Puma + +#endif /* __cc_lexer_h__ */ diff --git a/Puma/src/scanner/CCommentTokens.h b/Puma/src/scanner/CCommentTokens.h new file mode 100644 index 0000000..baa0111 --- /dev/null +++ b/Puma/src/scanner/CCommentTokens.h @@ -0,0 +1,46 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __C_COMMENT_TOKENS_H__ +#define __C_COMMENT_TOKENS_H__ + +/** \file + * White space and comment token types. */ + +namespace Puma { + + +/** White space and comment token types. These types + * can be compared to Puma::Token::type(). */ +enum { + /** Any white space block. */ + TOK_WSPACE = 400, + /** C++ style single line comment. */ + TOK_CCSINGLE = 350, + /** C style multi-line comment start token. */ + TOK_CCMULTIBEGIN, + /** C style multi-line comment end token. */ + TOK_CCMULTIEND, + /** Comment block. */ + TOK_CCOMMENT +}; + + +} // namespace Puma + +#endif /* __C_COMMENT_TOKENS_H__ */ diff --git a/Puma/src/scanner/CLexer.cc b/Puma/src/scanner/CLexer.cc new file mode 100644 index 0000000..dcc5bd1 --- /dev/null +++ b/Puma/src/scanner/CLexer.cc @@ -0,0 +1,214 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CLexer.h" + +namespace Puma { + + void CLexer::add_keywords (lexertl::rules &rules) { + add_c89_keywords (rules); + add_c99_keywords (rules); + } + + + // different kinds of keywords; selected depending on the standard to be supported + void CLexer::add_c89_keywords (lexertl::rules &rules) { + // C keywords + rules.push ("asm", TOK_ASM, LID(Token::keyword_id)); + rules.push ("auto", TOK_AUTO, LID(Token::keyword_id)); + rules.push ("break", TOK_BREAK, LID(Token::keyword_id)); + rules.push ("case", TOK_CASE, LID(Token::keyword_id)); + rules.push ("char", TOK_CHAR, LID(Token::keyword_id)); + rules.push ("const", TOK_CONST, LID(Token::keyword_id)); + rules.push ("continue", TOK_CONTINUE, LID(Token::keyword_id)); + rules.push ("default", TOK_DEFAULT, LID(Token::keyword_id)); + rules.push ("do", TOK_DO, LID(Token::keyword_id)); + rules.push ("double", TOK_DOUBLE, LID(Token::keyword_id)); + rules.push ("else", TOK_ELSE, LID(Token::keyword_id)); + rules.push ("enum", TOK_ENUM, LID(Token::keyword_id)); + rules.push ("extern", TOK_EXTERN, LID(Token::keyword_id)); + rules.push ("float", TOK_FLOAT, LID(Token::keyword_id)); + rules.push ("for", TOK_FOR, LID(Token::keyword_id)); + rules.push ("goto", TOK_GOTO, LID(Token::keyword_id)); + rules.push ("if", TOK_IF, LID(Token::keyword_id)); + rules.push ("inline", TOK_INLINE, LID(Token::keyword_id)); + rules.push ("int", TOK_INT, LID(Token::keyword_id)); + rules.push ("long", TOK_LONG, LID(Token::keyword_id)); + rules.push ("register", TOK_REGISTER, LID(Token::keyword_id)); + rules.push ("return", TOK_RETURN, LID(Token::keyword_id)); + rules.push ("short", TOK_SHORT, LID(Token::keyword_id)); + rules.push ("signed", TOK_SIGNED, LID(Token::keyword_id)); + rules.push ("sizeof", TOK_SIZEOF, LID(Token::keyword_id)); + rules.push ("static", TOK_STATIC, LID(Token::keyword_id)); + rules.push ("struct", TOK_STRUCT, LID(Token::keyword_id)); + rules.push ("switch", TOK_SWITCH, LID(Token::keyword_id)); + rules.push ("typedef", TOK_TYPEDEF, LID(Token::keyword_id)); + rules.push ("union", TOK_UNION, LID(Token::keyword_id)); + rules.push ("unsigned", TOK_UNSIGNED, LID(Token::keyword_id)); + rules.push ("void", TOK_VOID, LID(Token::keyword_id)); + rules.push ("volatile", TOK_VOLATILE, LID(Token::keyword_id)); + rules.push ("while", TOK_WHILE, LID(Token::keyword_id)); + } + + + void CLexer::add_c99_keywords (lexertl::rules &rules) { + rules.push ("_Bool", TOK_C_BOOL, LID(Token::keyword_id)); + rules.push ("restrict", TOK_RESTRICT, LID(Token::keyword_id)); + } + + + void CLexer::add_rules (lexertl::rules &rules) { + rules.push ("[ \\t]+[\\n\\r\\f\\v]*", TOK_WSPACE, LID(Token::white_id)); + rules.push ("[\\n\\r\\f\\v]+", TOK_WSPACE, LID(Token::white_id)); + + // ------------ + // preprocessor + // ------------ + + // a single line comment + rules.push ("\\/\\/[^\\n\\r\\f\\v]*", TOK_CCSINGLE, LID(Token::comment_id)); + + // a multi-line comment + rules.push ("\\/\\*(.|\\n)*?\\*\\/", TOK_CCOMMENT, LID(Token::comment_id)); + + // this ugly DirPrefix expression allows something like this: "# /*abc*/ include " + rules.insert_macro("DirPrefix", "([ \\t]|(\\/\\*([^*]|\\*+[^/*])*\\*+\\/))*#([ \\t]|(\\/\\*([^*]|\\*+[^/*])*\\*+\\/))*"); + + rules.push ("^{DirPrefix}define", TOK_PRE_DEFINE, LID(Token::pre_id)); + rules.push ("^{DirPrefix}assert", TOK_PRE_ASSERT, LID(Token::pre_id)); + rules.push ("^{DirPrefix}unassert", TOK_PRE_UNASSERT, LID(Token::pre_id)); + rules.push ("^{DirPrefix}if", TOK_PRE_IF, LID(Token::pre_id)); + rules.push ("^{DirPrefix}elif", TOK_PRE_ELIF, LID(Token::pre_id)); + rules.push ("^{DirPrefix}warning", TOK_PRE_WARNING, LID(Token::pre_id)); + rules.push ("^{DirPrefix}error", TOK_PRE_ERROR, LID(Token::pre_id)); + rules.push ("^{DirPrefix}include", TOK_PRE_INCLUDE, LID(Token::pre_id)); + rules.push ("^{DirPrefix}include_next", TOK_PRE_INCLUDE_NEXT, LID(Token::pre_id)); + rules.push ("^{DirPrefix}ifdef", TOK_PRE_IFDEF, LID(Token::pre_id)); + rules.push ("^{DirPrefix}ifndef", TOK_PRE_IFNDEF, LID(Token::pre_id)); + rules.push ("^{DirPrefix}else", TOK_PRE_ELSE, LID(Token::pre_id)); + rules.push ("^{DirPrefix}endif", TOK_PRE_ENDIF, LID(Token::pre_id)); + rules.push ("^{DirPrefix}undef", TOK_PRE_UNDEF, LID(Token::pre_id)); + + // Win specific preprocessor directives + rules.push ("^{DirPrefix}import", TOK_PRE_INCLUDE, LID(Token::pre_id)); + + // compiler directives + rules.push ("^{DirPrefix}pragma", 1, LID(Token::dir_id)); + rules.push ("^{DirPrefix}line", 1, LID(Token::dir_id)); + rules.push ("^{DirPrefix}ident", 1, LID(Token::dir_id)); + rules.push ("^{DirPrefix}", 1, LID(Token::dir_id)); + + // preprocessor macro operations + rules.push ("#", TOK_MO_HASH, LID(Token::macro_op_id)); + rules.push ("##", TOK_MO_HASHHASH, LID(Token::macro_op_id)); + + // ---------- + // core rules + // ---------- + + // macros + rules.insert_macro("Dec", "\\d"); + rules.insert_macro("Hex", "[0-9a-fA-F]"); + rules.insert_macro("U", "[uU]"); + rules.insert_macro("L", "[lL]"); + rules.insert_macro("Exp", "[Ee]"); + rules.insert_macro("F", "[fF]"); + + // nonreserved tokens: + rules.push ("@", TOK_AT, LID(Token::cpp_id)); + + // an integer constant: + rules.push ("0", TOK_ZERO_VAL, LID(Token::cpp_id)); + rules.push ("({Dec}+|(0[xX]?{Hex}+))({U}|{L}|{L}{U}|{U}{L}|{L}{L}|{U}{L}{L}|{L}{U}{L}|{L}{L}{U})?", TOK_INT_VAL, LID(Token::cpp_id)); + + // a floating point constant: + rules.push ("{Dec}+(\\.{Dec}*)?({Exp}([\\+\\-])?{Dec}+)?({L}|{F})?", TOK_FLT_VAL, LID(Token::cpp_id)); + rules.push ("\\.{Dec}+({Exp}([\\+\\-])?{Dec}+)?({L}|{F})?", TOK_FLT_VAL, LID(Token::cpp_id)); + + // a hex floating point constant: + rules.push ("0[xX]{Hex}+(\\.{Hex}*)?[pP]([\\+\\-])?{Dec}+({L}|{F})?", TOK_FLT_VAL, LID(Token::cpp_id)); + rules.push ("0[xX]\\.{Hex}+[pP]([\\+\\-])?{Dec}+({L}|{F})?", TOK_FLT_VAL, LID(Token::cpp_id)); + + // a string or character constant: + rules.push ("(L)?\\\"([^\\\\\\\"]|\\\\.)*\\\"", TOK_STRING_VAL, LID(Token::cpp_id)); + rules.push ("(L)?\\\'([^\\\\\\\']|\\\\.)*\\\'", TOK_CHAR_VAL, LID(Token::cpp_id)); + + // operators + #define LIT(x) "\"" x "\"" + rules.push (LIT(","), TOK_COMMA, LID(Token::comma_id)); + rules.push (LIT("="), TOK_ASSIGN, LID(Token::cpp_id)); + rules.push (LIT("?"), TOK_QUESTION, LID(Token::cpp_id)); + rules.push (LIT("|"), TOK_OR, LID(Token::cpp_id)); + rules.push (LIT("^"), TOK_ROOF, LID(Token::cpp_id)); + rules.push (LIT("&"), TOK_AND, LID(Token::cpp_id)); + rules.push (LIT("+"), TOK_PLUS, LID(Token::cpp_id)); + rules.push (LIT("-"), TOK_MINUS, LID(Token::cpp_id)); + rules.push (LIT("*"), TOK_MUL, LID(Token::cpp_id)); + rules.push (LIT("/"), TOK_DIV, LID(Token::cpp_id)); + rules.push (LIT("%"), TOK_MODULO, LID(Token::cpp_id)); + rules.push (LIT("<"), TOK_LESS, LID(Token::cpp_id)); + rules.push (LIT(">"), TOK_GREATER, LID(Token::cpp_id)); + rules.push (LIT("("), TOK_OPEN_ROUND, LID(Token::open_id)); + rules.push (LIT(")"), TOK_CLOSE_ROUND, LID(Token::close_id)); + rules.push (LIT("["), TOK_OPEN_SQUARE, LID(Token::cpp_id)); + rules.push (LIT("]"), TOK_CLOSE_SQUARE, LID(Token::cpp_id)); + rules.push (LIT("{"), TOK_OPEN_CURLY, LID(Token::cpp_id)); + rules.push (LIT("}"), TOK_CLOSE_CURLY, LID(Token::cpp_id)); + rules.push (LIT(";"), TOK_SEMI_COLON, LID(Token::cpp_id)); + rules.push (LIT(":"), TOK_COLON, LID(Token::cpp_id)); + rules.push (LIT("!"), TOK_NOT, LID(Token::cpp_id)); + rules.push (LIT("~"), TOK_TILDE, LID(Token::cpp_id)); + rules.push (LIT("."), TOK_DOT, LID(Token::cpp_id)); + + rules.push (LIT("*="), TOK_MUL_EQ, LID(Token::cpp_id)); + rules.push (LIT("/="), TOK_DIV_EQ, LID(Token::cpp_id)); + rules.push (LIT("%="), TOK_MOD_EQ, LID(Token::cpp_id)); + rules.push (LIT("+="), TOK_ADD_EQ, LID(Token::cpp_id)); + rules.push (LIT("-="), TOK_SUB_EQ, LID(Token::cpp_id)); + rules.push (LIT("<<="), TOK_LSH_EQ, LID(Token::cpp_id)); + rules.push (LIT(">>="), TOK_RSH_EQ, LID(Token::cpp_id)); + rules.push (LIT("&="), TOK_AND_EQ, LID(Token::cpp_id)); + rules.push (LIT("^="), TOK_XOR_EQ, LID(Token::cpp_id)); + rules.push (LIT("|="), TOK_IOR_EQ, LID(Token::cpp_id)); + rules.push (LIT("||"), TOK_OR_OR, LID(Token::cpp_id)); + rules.push (LIT("&&"), TOK_AND_AND, LID(Token::cpp_id)); + rules.push (LIT("=="), TOK_EQL, LID(Token::cpp_id)); + rules.push (LIT("!="), TOK_NEQ, LID(Token::cpp_id)); + rules.push (LIT("<="), TOK_LEQ, LID(Token::cpp_id)); + rules.push (LIT(">="), TOK_GEQ, LID(Token::cpp_id)); + rules.push (LIT("<<"), TOK_LSH, LID(Token::cpp_id)); + rules.push (LIT(">>"), TOK_RSH, LID(Token::cpp_id)); + rules.push (LIT(".*"), TOK_DOT_STAR, LID(Token::cpp_id)); + rules.push (LIT("->*"), TOK_PTS_STAR, LID(Token::cpp_id)); + rules.push (LIT("++"), TOK_INCR, LID(Token::cpp_id)); + rules.push (LIT("--"), TOK_DECR, LID(Token::cpp_id)); + rules.push (LIT("->"), TOK_PTS, LID(Token::cpp_id)); + rules.push (LIT("::"), TOK_COLON_COLON, LID(Token::cpp_id)); + rules.push (LIT("..."), TOK_ELLIPSIS, LID(Token::cpp_id)); + + // Keywords + add_keywords (rules); + + // Identifiers + rules.insert_macro ("UniversalChar", "\\\\(u{Hex}{4}|U{Hex}{8})"); + rules.insert_macro ("Alpha", "[a-zA-Z_\\$]|{UniversalChar}"); + + rules.push ("{Alpha}({Alpha}|\\d)*", TOK_ID, LID(Token::identifier_id)); + } + +} // namespace Puma diff --git a/Puma/src/scanner/CLexer.h b/Puma/src/scanner/CLexer.h new file mode 100644 index 0000000..36fbae5 --- /dev/null +++ b/Puma/src/scanner/CLexer.h @@ -0,0 +1,119 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __c_lexer_h__ +#define __c_lexer_h__ + +#include "Puma/Token.h" +#include "Puma/CTokens.h" +#include "Puma/PreParser.h" +#include "Puma/CCommentTokens.h" +#include "Puma/PreMacroOpTokens.h" +#include "Puma/LanguageID.h" +#include "Puma/CLexerBuffer.h" +#include "Puma/Lexer.h" + +#include + +namespace Puma { + +class CLexer : public Lexer { +public: + typedef lexertl::rules::id_type IdType; + + // This type is needed to run the lexer and get the tokens + // one by one + class State { + CLexer &_lexer; + CLexerBuffer::ConstIterator _start; + CLexerBuffer::ConstIterator _iter; + CLexerBuffer::ConstIterator _end; + lexertl::match_results _results; + enum { LM_NORMAL, LM_PRE, LM_DIR } _line_mode; + bool _error; + int _number; + + public: + State (CLexer &lexer, CLexerBuffer &buffer) : _lexer (lexer), + _start (buffer.begin ()), _iter (buffer.begin ().adjust ()), + _end (buffer.end ()), _results (_iter, _end), _line_mode (LM_NORMAL), + _error (false), _number (0) {} + + void macro_unit () { + // this is to avoid an ambiguity between macro op tokens and a directive + // (which always starts at the beginning of the line) + _results.bol = false; + } + + bool error () const { return _error; } + IdType id () const { return _results.id; } + LanguageID lang () const { return LanguageID ((const char*)_results.user_id); } + int continuations () const { return _results.end.continuations(); } + int lines () const { return _results.end.lines(); } + int number () const { return _number; } + const char *start () const { return _number == 1 ? &*_start : &*_results.start; } + int len () const { return &*_results.end - start (); } + std::string text () const { return std::string (_results.start, _results.end); } + + bool next () { + _error = false; + _results.end.reset_counters (); + lexertl::lookup (_lexer._state_machine, _results); + if (_results.id == 0) + return false; + if (_results.id == _results.npos()) + _error = true; + else { + if ((const char*)_results.user_id == Token::dir_id) + _line_mode = LM_DIR; + else if ((const char*)_results.user_id == Token::pre_id) + _line_mode = LM_PRE; + if (_line_mode == LM_DIR) + _results.user_id = LID(Token::dir_id); + if (_results.bol) + _line_mode = LM_NORMAL; + } + _number++; + return true; + } + }; + friend class State; + + // virtual destructor needed to avoid warning + virtual ~CLexer () {} + + // get instance of the lexer + static CLexer& instance(unsigned int id) { + return Lexer::instance(id); + } + + // define all regular expressions for the C tokens + virtual void add_rules (lexertl::rules &rules); + + // function called by 'add_rules' used to define the + // C keywords + virtual void add_keywords (lexertl::rules &rules); + + // different kinds of keywords; selected depending on the standard to be supported + virtual void add_c89_keywords (lexertl::rules &rules); + virtual void add_c99_keywords (lexertl::rules &rules); +}; + +} // namespace Puma + +#endif /* __c_lexer_h__ */ diff --git a/Puma/src/scanner/CLexerBuffer.h b/Puma/src/scanner/CLexerBuffer.h new file mode 100644 index 0000000..bc16c12 --- /dev/null +++ b/Puma/src/scanner/CLexerBuffer.h @@ -0,0 +1,76 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __c_lexer_buffer_h__ +#define __c_lexer_buffer_h__ + +#include "Puma/LexerBuffer.h" + +namespace Puma { + +class CLexerBuffer : public LexerBuffer { +public: + CLexerBuffer () : LexerBuffer () {} + CLexerBuffer (const char *str, int l = 0) : LexerBuffer (str, l) {} + + class ConstIterator : public LexerBuffer::ConstIterator { + friend class CLexerBuffer; + int _continuations; + int _lines; + + void skip_nl () { + if (*_ptr == '\\') { + while (*_ptr != '\0' && *_ptr == '\\') { + const char *p = _ptr + 1; + if (*p != '\0' && *p == '\r') p++; + if (*p != '\0' && *p == '\n') { + _ptr = p + 1; + _continuations++; + _lines++; + } + else + break; + } + } + } + void next () { + if (*_ptr == '\n') + _lines++; + _ptr++; + skip_nl (); + } + public: + ConstIterator (const char *ptr = 0) : + LexerBuffer::ConstIterator (ptr), _continuations (0), _lines (0) {} + ConstIterator (const ConstIterator &r) : + LexerBuffer::ConstIterator (r), _continuations (r._continuations), _lines (r._lines) {} + ConstIterator &operator ++ () { next (); return *this; } + ConstIterator operator ++ (int) { ConstIterator res(*this); next (); return res; } + ConstIterator &adjust () { skip_nl (); return *this; } + int continuations () const { return _continuations; } + int lines () const { return _lines + 1; } + void reset_counters () { _lines = 0; _continuations = 0; } + }; + + ConstIterator begin () const { return ConstIterator(_buffer); } + ConstIterator end () const { return ConstIterator(_buffer ? _buffer + _buffer_size : 0); } +}; + +} // namespace Puma + +#endif /* __c_lexer_buffer_h__ */ diff --git a/Puma/src/scanner/CScanner.cc b/Puma/src/scanner/CScanner.cc new file mode 100644 index 0000000..1d1d37f --- /dev/null +++ b/Puma/src/scanner/CScanner.cc @@ -0,0 +1,199 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 "Puma/CScanner.h" +#include "Puma/ErrorStream.h" +#include "Puma/Source.h" +#include "Puma/Token.h" +#include "Puma/Location.h" +#include "Puma/Unit.h" +#include "Puma/CTokens.h" +#include "Puma/CCLexer.h" + +#include + +namespace Puma { + + +void CScanner::lexer (CLexer& lexer) { + _lexer = &lexer; +} + + +void CScanner::configure (const Config &c) { + // evaluate configuration options + bool lang_cc = c.Option ("--lang-c++"); + bool lang_c = lang_cc || c.Option ("--lang-c"); + + // default settings + if (! lang_c && ! lang_cc) { + lang_c = true; + lang_cc = true; + } + + _config_cplusplus = lang_cc; + + allow_std_cplusplus (lang_cc); + allow_std_c (lang_c); + allow_visual_c (lang_c && c.Option ("--vc")); + allow_visual_cplusplus (lang_cc && c.Option ("--vc")); + allow_gnu_c (lang_c && c.Option ("--gnu")); + allow_gnu_cplusplus (lang_cc && c.Option ("--gnu")); + allow_type_traits (lang_cc && c.Option ("--builtin-type-traits")); +} + + +Token *CScanner::make_token (CLexer::State &lexer_state) { + Token *result = 0; + char short_buffer[512]; + char *tok_buffer = short_buffer; + int rows = 0; + int columns = 0; + int offset = loc.column (); + + char *src = (char*)lexer_state.start (); + int len = lexer_state.len (); + CLexer::IdType expr = lexer_state.id (); + LanguageID lid = lexer_state.lang (); + + // dynamically allocate a huge buffer + if (len >= (int)sizeof (short_buffer) - 1) + tok_buffer = new char[len + 1]; + + if (lexer_state.lines () == 1) { + // a token without newline => can be copied directly + memcpy (tok_buffer, src, len); + tok_buffer[len] = '\0'; + result = new Token (expr, lid, tok_buffer); + result->location (loc); + loc.setup (loc.filename (), loc.line (), loc.column () + len); + } + else { + // special token with newline => more complicated + char *dest = tok_buffer; + char *end = src + len; + + int last = 0; + Array *cl = 0; + while (src < end) { + if (*src == '\\' && src + 1 < end && *(src + 1) == '\n') { + src += 2; + rows++; + columns = 1; + offset = 0; + if (!cl) cl = new Array(10,10); + cl->append (last); + last = 0; + } + else if (*src == '\\' && src + 2 < end && *(src + 1) == '\x0d' && + *(src + 2) == '\n') { + src += 3; + rows++; + columns = 1; + offset = 0; + if (!cl) cl = new Array(10,10); + cl->append (last); + last = 0; + } + else { + if (*src == '\n') { + rows++; + columns = 1; + offset = 0; + } else { + columns++; + } + *dest = *src; + dest++; + src++; + last++; + } + } + *dest = '\0'; + + result = new Token (expr, lid, tok_buffer); + result->location (loc); + + // set the next token location + if (rows > 0 || columns > 0) + loc.setup (loc.filename (), loc.line () + rows, offset + columns); + + // attach the continuation line marks + if (cl) result->cont_lines (cl); + } + + // free a dynamically allocated huge buffer + if (len >= (int)sizeof (short_buffer)) + delete[] tok_buffer; + + return result; +} + + +void CScanner::scan_all (CLexer &lexer, CLexerBuffer &lexer_buffer, Unit &unit) { + CLexer::State lexer_state (lexer, lexer_buffer); + if (macro_ops) lexer_state.macro_unit (); + + loc.setup (unit.name () ? unit.name () : "", 1, 1); + + // cout << "---" << endl; + while (lexer_state.next ()) { + if (lexer_state.error ()) { + err << sev_error << loc + << "Invalid token '" << lexer_state.text ().c_str () << "'" << endMessage; + break; + } + else { + Token *new_token = make_token (lexer_state); + unit.append (*new_token); + } + } +} + + +void CScanner::fill_unit (Source &in, Unit &unit) { + int size = in.size (); + if (size == 0) + return; + if (size == -1) { + err << sev_error << "can't scan file of unknown size" << endMessage; + return; + } + char buf[size+1]; + if (in.read (buf, size) != size) { + err << sev_error << "can't load input file" << endMessage; + return; + } + buf[size] = '\0'; // termination character needed for CLexer + + CLexer &lexer = (_lexer ? *_lexer : _config_cplusplus ? CCLexer::instance (0) : CLexer::instance (0)); + CLexerBuffer lexer_buffer; + lexer_buffer.init (buf, size); + scan_all (lexer, lexer_buffer, unit); +} + + +void CScanner::fill_unit (const char *in, Unit &unit) { + CLexer &lexer = (_lexer ? *_lexer : _config_cplusplus ? CCLexer::instance (0) : CLexer::instance (0)); + CLexerBuffer lexer_buffer; + lexer_buffer.init (in); + scan_all (lexer, lexer_buffer, unit); +} + + +} // namespace Puma diff --git a/Puma/src/scanner/CScanner.h b/Puma/src/scanner/CScanner.h new file mode 100644 index 0000000..d729469 --- /dev/null +++ b/Puma/src/scanner/CScanner.h @@ -0,0 +1,94 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __c_scanner_h__ +#define __c_scanner_h__ + +#include "Puma/Location.h" +#include "Puma/LanguageID.h" +#include "Puma/Tokenizer.h" +#include "Puma/Unit.h" +#include "Puma/ErrorSink.h" +#include "Puma/Config.h" +#include "Puma/Source.h" +#include "Puma/CCLexer.h" + +namespace Puma { + +class Token; + +class CScanner : public Tokenizer { + Location loc; + ErrorSink &err; + bool _config_cplusplus; + CLexer *_lexer; + + // flags to enable/disable certain features + bool directives; + bool wildcards; + bool macro_ops; + bool std_c; + bool std_cplusplus; + bool gnu_c; + bool gnu_cplusplus; + bool visual_c; + bool visual_cplusplus; + bool type_traits; + bool cc1x; + +private: + // internal functions + Token *make_token (CLexer::State &lexer_state); + Token *scan (); + void scan_all (CLexer &lexer, CLexerBuffer &lexer_buffer, Unit &unit); + void scan_all (Unit &unit); + +public: + CScanner (ErrorSink &error_stream) : + err (error_stream), _config_cplusplus (true), _lexer (0), + directives(true), wildcards (false), macro_ops (false), + std_c (true), std_cplusplus (true), + gnu_c (false), gnu_cplusplus (false), + visual_c (false), visual_cplusplus (false), + type_traits (false), cc1x (false) {} + + virtual ~CScanner () {} + + void configure (const Config &); + void lexer (CLexer& lexer); + + void fill_unit (Source &in, Unit &unit); + void fill_unit (const char *in, Unit &unit); + + void allow_directives (bool flag = true) { directives = flag; } + void allow_wildcards (bool flag = true) { wildcards = flag; } + void allow_macro_ops (bool flag = true) { macro_ops = flag; } + void allow_std_c (bool flag = true) { std_c = flag; } + void allow_std_cplusplus (bool flag = true) { std_cplusplus = flag; } + void allow_gnu_c (bool flag = true) { gnu_c = flag; } + void allow_gnu_cplusplus (bool flag = true) { gnu_cplusplus = flag; } + void allow_visual_c (bool flag = true) { visual_c = flag; } + void allow_visual_cplusplus (bool flag = true) { visual_cplusplus = flag; } + void allow_type_traits (bool flag = true) { type_traits = flag; } + void allow_cc1x (bool flag = true) { cc1x = flag; } +}; + + +} // namespace Puma + +#endif /* __c_scanner_h__ */ diff --git a/Puma/src/scanner/CWildcardTokens.h b/Puma/src/scanner/CWildcardTokens.h new file mode 100644 index 0000000..32eeb01 --- /dev/null +++ b/Puma/src/scanner/CWildcardTokens.h @@ -0,0 +1,98 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __C_WILDCARD_TOKENS__ +#define __C_WILDCARD_TOKENS__ + +/** \file + * Wildcard token types. */ + +namespace Puma { + + +/** Types of wildcard tokens. These types + * can be compared to Puma::Token::type(). */ +enum CWildcardTokens { + TOK_WC_AND = 500, + TOK_WC_OR, + TOK_WC_XOR, + TOK_WC_SEQ, + TOK_WC_IF, + TOK_WC_ELIF, + TOK_WC_ENDIF, + TOK_WC_NOT, + TOK_WC_EXACT, + TOK_WC_FIRST, + TOK_WC_LAST, + TOK_WC_LEAF, + TOK_WC_PRUNE, + TOK_WC_COLLECT, + TOK_WC_NODENAME, + TOK_WC_ELEMENT, + + TOK_DO_EXPR, + TOK_DO_EXPR_LIST, + TOK_DO_ID_EXPR, + TOK_DO_IDENTIFIER, + TOK_DO_DECL_SPEC, + TOK_DO_DECL_SPEC_SEQ, + TOK_DO_INIT_DECLARATOR_LIST, + TOK_DO_INIT_DECLARATOR, + TOK_DO_DECLARATOR, + TOK_DO_INIT, + TOK_DO_ARG_DECL_SEQ, + TOK_DO_FCT_BODY, + TOK_DO_CLASS_SPEC, + TOK_DO_MEMBER_SPEC, + TOK_DO_MEMBER_DECL, + TOK_DO_BASE_CLAUSE, + TOK_DO_CTOR_INIT, + TOK_DO_MEM_INIT, + TOK_DO_STMT, + TOK_DO_STMT_SEQ, + + TOK_ANY_EXPR, + TOK_ANY_EXPR_LIST, + TOK_ANY_ID_EXPR, + TOK_ANY_IDENTIFIER, + TOK_ANY_DECL_SPEC, + TOK_ANY_DECL_SPEC_SEQ, + TOK_ANY_INIT_DECLARATOR_LIST, + TOK_ANY_INIT_DECLARATOR, + TOK_ANY_DECLARATOR, + TOK_ANY_INIT, + TOK_ANY_ARG_DECL_SEQ, + TOK_ANY_FCT_BODY, + TOK_ANY_CLASS_SPEC, + TOK_ANY_MEMBER_SPEC, + TOK_ANY_MEMBER_DECL, + TOK_ANY_BASE_CLAUSE, + TOK_ANY_CTOR_INIT, + TOK_ANY_MEM_INIT, + TOK_ANY_STMT, + TOK_ANY_STMT_SEQ, + + TOK_WC_IS_CLASS, + TOK_WC_IS_ENUM, + TOK_WC_IS_TYPEDEF +}; + + +} // namespace Puma + +#endif /* __WILDCARD_TOKENS__ */ diff --git a/Puma/src/scanner/Lexer.h b/Puma/src/scanner/Lexer.h new file mode 100644 index 0000000..3e5e1c5 --- /dev/null +++ b/Puma/src/scanner/Lexer.h @@ -0,0 +1,81 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __lexer_h__ +#define __lexer_h__ + +/** \page lexer Lexical Analysis + */ + +#include "lexertl/generator.hpp" +#include "lexertl/lookup.hpp" +#include "lexertl/rules.hpp" +#include "lexertl/state_machine.hpp" + +#include "Puma/LexerMap.h" + +namespace Puma { + +#define LID(x) ((lexertl::rules::id_type)(const char*) x) + +class Lexer { +protected: + // bit mask that can be used to describe different lexer configurations + unsigned int _config_mask; + + // implementation of the lexer: a lexertl state machine + lexertl::state_machine _state_machine; + +protected: + // create the state machine that is needed to scan + // the tokens (to be done only once!) + void setup (unsigned int config) { + // setup the state machine upon the first access + _config_mask = config; + lexertl::rules rules; + add_rules (rules); + lexertl::generator::build (rules, _state_machine); + } + + // singleton pattern; only one instance of a given ID! + template + static L& instance(unsigned int id) { + typedef LexerMap Map; + static Map lexer_map; + typename Map::iterator elem = lexer_map.find (id); + if (elem == lexer_map.end ()) { + elem = lexer_map.create (id); + elem->second->setup (id); + } + return *(elem->second); + } + +public: + // virtual destructor needed to avoid warning + virtual ~Lexer () {} + + // define all regular expressions for the tokens + virtual void add_rules (lexertl::rules &rules) {} + + // function called by 'add_rules' used to define the keywords + virtual void add_keywords (lexertl::rules &rules) {} +}; + +} // namespace Puma + +#endif /* __lexer_h__ */ diff --git a/Puma/src/scanner/LexerBuffer.h b/Puma/src/scanner/LexerBuffer.h new file mode 100644 index 0000000..538fd84 --- /dev/null +++ b/Puma/src/scanner/LexerBuffer.h @@ -0,0 +1,73 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __lexer_buffer_h__ +#define __lexer_buffer_h__ + +#include + +namespace Puma { + +class LexerBuffer { + +protected: + const char *_buffer; // buffer that contains all input characters + int _buffer_size; // size of the input buffer + +public: + LexerBuffer () : _buffer(0), _buffer_size(0) {} + LexerBuffer (const char *str, int l = 0) { init (str, l); } + + // init buffer to directly scan from a string + void init (const char *str, int l = 0) { + _buffer = str; + _buffer_size = l; + if (!l) while (_buffer[_buffer_size] != '\0') _buffer_size++; + } + + // an iterator class + class ConstIterator { + friend class LexerBuffer; + protected: + const char *_ptr; + public: + typedef std::forward_iterator_tag iterator_category; + typedef std::size_t difference_type; + typedef char value_type; + typedef char *pointer; + typedef char &reference; + + + ConstIterator (const char *ptr = 0) : _ptr (ptr) {} + ConstIterator (const ConstIterator &r) : _ptr (r._ptr) {} + ConstIterator &operator = (const ConstIterator &r) { _ptr = r._ptr; return *this; } + bool operator == (const ConstIterator &r) const { return _ptr == r._ptr; } + bool operator != (const ConstIterator &r) const { return _ptr != r._ptr; } + ConstIterator &operator ++ () { _ptr++; return *this; } + ConstIterator operator ++ (int) { ConstIterator res(*this); _ptr++; return res; } + const char &operator * () const { return *_ptr; } + }; + + ConstIterator begin () const { return ConstIterator(_buffer); } + ConstIterator end () const { return ConstIterator(_buffer ? _buffer + _buffer_size : 0); } +}; + + +} // namespace Puma + +#endif /* __lexer_buffer_h__ */ diff --git a/Puma/src/scanner/LexerMap.h b/Puma/src/scanner/LexerMap.h new file mode 100644 index 0000000..fcf42a2 --- /dev/null +++ b/Puma/src/scanner/LexerMap.h @@ -0,0 +1,41 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __lexer_map_h__ +#define __lexer_map_h__ + +#include + +namespace Puma { + + template + struct LexerMap : public std::map { + typedef typename std::map::iterator Iter; + typedef typename std::map::value_type ValueType; + ~LexerMap () { + for (Iter i = this->begin (); i != this->end(); ++i) + delete i->second; + } + Iter create (unsigned id) { + return this->insert (ValueType (id, new L)).first; + } + }; + +} // namespace Puma + +#endif /* __c_lexer_h__ */ diff --git a/Puma/src/weave.mk b/Puma/src/weave.mk new file mode 100644 index 0000000..a2b1ebd --- /dev/null +++ b/Puma/src/weave.mk @@ -0,0 +1,103 @@ +#ifeq ($(MAKELEVEL),0) +#$(error Sorry, this makefile is not intended to be \ +#used directly. Please use the makefile in the toplevel \ +#directory of the PUMA source tree instead) +#endif + +#------------------------------------------------- +# variables +#------------------------------------------------- + +include $(ROOT)/vars.mk + +HEADERS := $(shell find $(STEP1)/inc -name "*") +HEADERSDEP:= $(STEP2)/.inc + +ACOBJECTS := $(notdir $(filter-out $(DONTWEAVE), $(SOURCES))) +ACOBJECTS += $(notdir $(LEMSOURCES:.lem=.cc)) +ACOBJECTS := $(addprefix $(STEP2)/src/, $(ACOBJECTS)) + +CPPFLAGS += -I $(EXTDIR) -I $(STEP1)/inc -I $(STEP1)/aspects + +ACFILES := $(addprefix $(STEP1)/aspects/Puma/, $(notdir $(ASPECTS))) +ACDEPS := $(addprefix --include , $(ACFILES)) +ACFLAGS += $(addprefix -a , $(ACFILES)) +#ACFLAGS += $(CPPFLAGS) -I $(STEP1)/src -r $(GENDIR)/puma.acp +ACFLAGS += $(CPPFLAGS) -I $(STEP1)/src +ACFLAGS += --config $(CONFIG) --gen_size_type __SIZE_TYPE__ -k + +DEPDIR := $(STEP1)/dep +DEPFILES := $(addprefix $(DEPDIR)/, $(notdir $(ACOBJECTS:.cc=.d))) + +#------------------------------------------------- +# targets +#------------------------------------------------- + +vpath %.cc $(STEP1)/src +vpath %.d $(DEPDIR) + +ifneq ($(ASPECTS),) +all: showinfo dontweave $(ACOBJECTS) $(HEADERSDEP) +else +all: dontweave + @cp -pr $(STEP1)/inc/Puma $(STEP2)/inc + @cp -pr $(STEP1)/inc/Puma $(INCDIR) +endif + +prof: + @echo Profiling enabled + +showinfo: + @echo + @echo "---" + @echo "Weaving PUMA for TARGET=$(TARGET)" + @echo " Weaver = $(AC) $(ACFLAGS)" + @echo "---" + @echo + +ifeq ($(DONTWEAVE),) +dontweave: + @echo "Weaving into ALL files" +else +dontweave: + @echo "Copying sources not to weave..." + @cp -p $(DONTWEAVE) $(STEP2)/src +endif + +#------------------------------------------------- +# rules +#------------------------------------------------- + +$(STEP2)/src/%.cc : %.cc + @echo "Weaving aspects into $(notdir $<)..." + @$(AC) $(ACFLAGS) -p $(STEP1) -c $< -o $@ + @echo "$@: \\" > $(addprefix $(DEPDIR)/, $(notdir $(<:.cc=.d))) + @grep "^#line" $@ | grep -v $(STEP2) | grep -v "> $(addprefix $(DEPDIR)/, $(notdir $(<:.cc=.d))) + @echo $(ACFILES) >> $(addprefix $(DEPDIR)/, $(notdir $(<:.cc=.d))) + + +$(HEADERSDEP): $(HEADERS) $(ACFILES) + @echo "Generating library header files..." + @touch $(HEADERSDEP) + @cd $(STEP1) && $(AC) $(ACFLAGS) -i -p. -d$(STEP2) + @cp -p $(STEP2)/aspects/Puma/*.ah $(STEP2)/inc/Puma + @cp -pr $(STEP2)/inc/Puma $(INCDIR) + + +#------------------------------------------------- +# special targets +#------------------------------------------------- + +.PHONY: all dontweave config showinfo + +#------------------------------------------------- +# includes +#------------------------------------------------- + +ifeq ($(MAKECMDGOALS),) +ifneq ($(DEPFILES),) +-include $(DEPFILES) +endif +endif diff --git a/Puma/src/win32/Makefile b/Puma/src/win32/Makefile new file mode 100644 index 0000000..ec35c97 --- /dev/null +++ b/Puma/src/win32/Makefile @@ -0,0 +1,19 @@ +#------------------------------------------------- +# variables +#------------------------------------------------- + +SUBDIRS := $(shell find $(shell pwd) -type d -maxdepth 1 -mindepth 1) +SUBDIRS := $(filter-out %/.svn, $(SUBDIRS)) +SUBDIRS := $(SUBDIRS) + +#------------------------------------------------- +# rules +#------------------------------------------------- + +all: $(SUBDIRS) +clean: $(SUBDIRS) + +$(SUBDIRS): + @$(MAKE) -C $@ $(MAKECMDGOALS) + +.PHONY: all clean $(SUBDIRS) diff --git a/Puma/src/win32/ptmalloc/COPYRIGHT b/Puma/src/win32/ptmalloc/COPYRIGHT new file mode 100644 index 0000000..dedd1d4 --- /dev/null +++ b/Puma/src/win32/ptmalloc/COPYRIGHT @@ -0,0 +1,19 @@ +Copyright (c) 1999 Wolfram Gloger + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that (i) the above copyright notices and this permission +notice appear in all copies of the software and related documentation, +and (ii) the name of Wolfram Gloger may not be used in any advertising +or publicity relating to the software. + +THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + +IN NO EVENT SHALL WOLFRAM GLOGER BE LIABLE FOR ANY SPECIAL, +INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY +DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY +OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. diff --git a/Puma/src/win32/ptmalloc/ChangeLog b/Puma/src/win32/ptmalloc/ChangeLog new file mode 100644 index 0000000..29b3f90 --- /dev/null +++ b/Puma/src/win32/ptmalloc/ChangeLog @@ -0,0 +1,227 @@ +1999-12-05 Wolfram Gloger + + * malloc/malloc.c (arena_get2): If generating a new arena fails, + try to generate a minimal one and hope for mmap_chunk() to succeed + later. + +1999-11-07 Wolfram Gloger + + * malloc/thread-m.h [NO_THREADS]: The mutex_* macros now let + mutex_t work as an `in-use' flag even without threads. + * malloc/malloc.c (USE_ARENAS): New feature flag, controls support + for multiple arenas separately from NO_THREADS. + (mALLOc, chunk_realloc, mEMALIGn, cALLOc) [USE_ARENAS]: try to + fall back to an mmap()ed arena when sbrk() has failed. + +1999-11-01 Wolfram Gloger + + * malloc/malloc.h: Describe __malloc_initialize_hook. + * manual/memory.texi: Document __malloc_initialize_hook. + +1999-09-23 Mark Kettenis + + * malloc/malloc.c (cALLOc): Correctly handle systems where sbrk + doesn't clear the contents of memory that is reallocated after + decrementing the break value first. Update comment about + MORECORE_CLEARS, explaining the meaning of the values it can be + set to. + +1999-08-28 Ulrich Drepper + + * malloc/malloc.c (ptmalloc_init): Don't use variables to set + thresholds for SUID binaries. [PR libc/1277] + +1999-08-06 H.J. Lu + + * malloc/malloc.c: Initialize __libc_pagesize early. + +1999-07-07 Ulrich Drepper + + * malloc/malloc.c (request2size): Also set errno if failing. + + * malloc/malloc.c (request2size): Take care of overflow in + addition. + +1999-07-04 Wolfram Gloger + + * malloc/malloc.c (request2size): Check for overflow and return + NULL whenever it is encountered. + +1999-06-06 Ulrich Drepper + + * malloc/malloc.c: Introduce local variable __libc_getpagesize to + avoid multiple calls to getpagesize() which might be a syscall. + +1999-06-05 Wolfram Gloger + + * malloc/malloc.c (check_action): Change into bitmap so that both + diagnostic and abort can be requested by setting it to 3. + (mALLOC_SET_STATe): Disable malloc checking if necessary. + +1999-05-16 Wolfram Gloger + + * malloc/malloc.c: Cleanup to bring in line with released + stand-alone version `ptmalloc'. Update some comments. + (internal_function): Move fallback definition so that the source + compiles outside of libc, and use it in more places. + (malloc_atfork): Fix when malloc_check is in use. + +1999-04-28 Ulrich Drepper + + * malloc/malloc.c (rEALLOc): Only free memory for size 0 if oldmem + is != NULL. + +1999-04-28 Andreas Jaeger + + * malloc/malloc.c (REALLOC_ZERO_BYTES_FREES): Define it to follow + ISO C9x and Unix98. + +1999-02-23 Andreas Schwab + + * malloc/malloc.c (mALLOC_SET_STATe): Handle the case where a + non-checked heap is restored when malloc checking was requested by + the user. + (struct malloc_state): Add using_malloc_checking. + (MALLOC_STATE_VERSION): Increment minor. + (using_malloc_checking, disallow_malloc_check): New variables. + (__malloc_check_init): Use them. + (mALLOC_GET_STATe): Use mALLOc to allocate the malloc_state, so + that it can the chunk is properly instrumented when malloc + checking is enabled. Set the new using_malloc_checking field. + +1998-08-28 09:22 Ulrich Drepper + + * malloc/malloc.c (malloc_hook_ini): Don't overwrite realloc and + memalign hook. + (realloc_hook_ini): Don't overwrite memalign hook. + (memalign_hook_ini): Don't overwrite malloc and memalign hooks. + Reported by Philippe Troin . + +1998-11-04 Ulrich Drepper + + * malloc/malloc.c: Make sure calloc really returned zeroed memory. + Patch by Wolfram Gloger . + +1998-08-11 Roland McGrath + + * malloc/malloc.c (free_check, realloc_check): Don't cast to long for + %p arg to fprintf, since `void *' is the right type already. + +1998-08-11 H.J. Lu + + * malloc/malloc.c (free_check): Print pointer value using %p. + (realloc_check): Likewise. + +1998-05-12 Wolfram Gloger + + * malloc/malloc.c: Fix for NO_THREADS case. + +1998-05-03 Wolfram Gloger + + * malloc/malloc.c [__linux__] (ptmalloc_unlock_all2): New + function, used as atfork handler for the child process to work + around a problem in LinuxThreads. + +1998-03-31 Wolfram Gloger + + * malloc/malloc.c (chunk2mem_check, top_check): New functions. + (malloc_check, free_check, realloc_check, memalign_check): Use + them to improve overrun checking. Overruns of a single byte and + corruption of the top chunk are now detected much more reliably. + +Tue Aug 12 17:17:00 1997 Wolfram Gloger + + * malloc/thread-m.h (thread_atfork, thread_atfork_static): New + macros to encapsulate pthread_atfork's functionality. + * malloc/malloc.c (ptmalloc_lock_all, ptmalloc_unlock_all): New + functions, registered via thread_atfork in the initialization + routine or via thread_atfork_static in global scope. This + ensures a consistent state of all locks across fork(). + +Sun Apr 13 17:18:38 1997 Wolfram Gloger + + * malloc/malloc.c (fREe): Small optimization. Before returning, + add fast check whether the heap containing top can go away. + +Fri Apr 11 16:46:49 1997 Wolfram Gloger + + * malloc/malloc.c (mALLOc, rEALLOc, cALLOc, mEMALIGn): When + failing to allocate a new chunk, also try the main_arena. It may + be that we are only running out of mmapped regions, and other + arenas cannot be enlarged sufficiently. + (new_heap, malloc_extend_top): Handle top_pad more consistently, + i.e. only in new_heap(). + +Mon Feb 24 23:05:00 1997 Wolfram Gloger + + * malloc/malloc.c (malloc_get_state): New function. + Saves global malloc state to an opaque data structure which + is dynamically allocated in the heap. + * malloc/malloc.c (malloc_set_state): New function. + Restore previously obtained state. + * malloc/malloc.h: Add declaration of malloc_get_state() + and malloc_set_state(). + +Mon Feb 17 10:58:14 1997 Miles Bader + + * malloc/thread-m.h + [_LIBC && !PTHREAD_MUTEX_INITIALIZER && MUTEX_INITIALIZER] + (mutex_lock, mutex_unlock, mutex_trylock): Defined in terms of + __mutex_*. + (mutex_t): Type removed & replaced by new macro. + (tsd_key_t): Typedef to int instead of pthread_key_t. + (tsd_key_create, tsd_setspecific, tsd_getspecific): New macros. + (__pthread_initialize): New macro, work around assumption of pthreads. + (tsd_keys_alloced): New static variable. + : New include. + +1997-02-02 23:15 Ulrich Drepper + + * malloc/malloc.c (__after_morecore_hook): New variable. + (malloc_extend_top): Call __after_morecore_hook if set. + (main_trim): Likewise. + * malloc/malloc.h: Add declaration of __after_morecore_hook. + Suggested by Marcus Daniels. + +1997-02-02 23:00 Marcus G. Daniels + + * malloc/malloc.c (rEALLOc): Protect tsd_setspecific call by + #ifndef NO_THREADS. + (mallinfo): Likewise. + + * malloc/malloc.c (__morecore): Make external since it is used in + programs. + +1997-01-30 18:29 Richard Henderson + + * malloc/malloc.c (MAGICBYTE): Use cast to size_t instead of unsigned + to prevent warnings on 64 bit systems. + Reported by Paul Wouters . + +1997-01-27 13:28 Ulrich Drepper + + * malloc/malloc.h (__malloc_initialized) [_LIBC]: Define as + __libc_malloc_initialized so that this variable is not shared with + other users of GNU malloc. + Suggested by Martin von Loewis . + +1997-01-14 14:20 Andreas Schwab + + * malloc/malloc.c (weak_variable): Define. + (__malloc_initialize_hook, __free_hook, __malloc_hook, __realloc_hook, + __memalign_hook): Make them weak definitions. + +Sun Jan 26 18:35:29 1997 Wolfram Gloger + + * malloc/malloc.c: Change malloc_check_init() to + __malloc_check_init(). Check for NULL in calloc() when a hook is + in place. Make more variables tunable via MALLOC_... environment + variables. + * malloc/malloc.h: Change malloc_check_init() to + __malloc_check_init(). + +Thu Jan 9 08:47:54 1997 Andreas Jaeger + + * new-malloc/malloc.c (__MALLOC_P): define call to pthread + initializer only if NO_THREADS is not defined. + diff --git a/Puma/src/win32/ptmalloc/Makefile b/Puma/src/win32/ptmalloc/Makefile new file mode 100644 index 0000000..a2b2681 --- /dev/null +++ b/Puma/src/win32/ptmalloc/Makefile @@ -0,0 +1,23 @@ +ifeq ($(TARGET),mingw) + CC := mingw32-gcc + CXX := mingw32-g++ + CFLAGS := -O6 -DHAVE_GETPAGESIZE + +OBJECTS = ptmalloc.o sbrk.o + +all: $(OBJECTS) + +%.o: %.c + $(CC) $(CFLAGS) -o $@ -c $< + +%.o: %.cc + $(CXX) $(CFLAGS) -o $@ -c $< + +else + +all: + +endif + +clean: + rm -f *.o *~ diff --git a/Puma/src/win32/ptmalloc/README b/Puma/src/win32/ptmalloc/README new file mode 100644 index 0000000..11da28c --- /dev/null +++ b/Puma/src/win32/ptmalloc/README @@ -0,0 +1,192 @@ +ptmalloc - a multi-thread malloc implementation +=============================================== + +Wolfram Gloger (wg@malloc.de) + +19 Dec 1999 + + +Introduction +============ + +ptmalloc.c is a modified version of Doug Lea's malloc-2.6.4 +implementation (available seperately from ftp://g.oswego.edu/pub/misc) +that I adapted for multiple threads, while trying to avoid lock +contention as much as possible. Many thanks should go to Doug Lea +(dl@cs.oswego.edu) for the great original malloc implementation. + +As part of the GNU C library, the source files are available under the +GNU Library General Public License (see the comments in the files). +But as part of this stand-alone package, the code is available under +the (probably less restrictive) conditions described in the file +`COPYRIGHT'. In any case, there is no warranty whatsoever for this +package. + +Compilation and usage +===================== + +It should be possible to compile ptmalloc.c on any UN*X-like system +that implements the sbrk(), mmap(), munmap() and mprotect() calls. If +mmap() is not available, it is only possible to produce a +non-threadsafe implementation from the source file. See the comments +in the source file for descriptions of the compile-time options. +Several thread interfaces are supported: + + o Posix threads (pthreads), compile with `-DUSE_PTHREADS=1' + (and possibly with `-DUSE_TSD_DATA_HACK', see below) + o Solaris threads, compile with `-DUSE_THR=1' + o SGI sproc() threads, compile with `-DUSE_SPROC=1' + o When compiling ptmalloc.c as part of the GNU C library, + i.e. when _LIBC is defined (no other defines necessary) + o no threads, compile without any of the above definitions + +The distributed Makefile includes several targets (e.g. `solaris' for +Solaris threads, but you probably want `posix' for recent Solaris +versions) which cause ptmalloc.c to be compiled with the appropriate +flags. The default is to compile for Posix threads. Some additional +targets, ending in `-libc', are also provided, to compare performance +of the test programs to the case when linking with the standard malloc +implementation in libc. + +A potential problem remains: If any of the system-specific functions +for getting/setting thread-specific data or for locking a mutex call +one of the malloc-related functions internally, the implementation +cannot work at all due to infinite recursion. One example seems to be +Solaris 2.4; a workaround for thr_getspecific() has been inserted into +the thread-m.h file. I would like to hear if this problem occurs on +other systems, and whether similar workarounds could be applied. + +For Posix threads, too, an optional hack like that has been integrated +(activated when defining USE_TSD_DATA_HACK) which depends on +`pthread_t' being convertible to an integral type (which is of course +not generally guaranteed). USE_TSD_DATA_HACK is now the default +because I haven't yet found a non-glibc pthreads system where this +hack is _not_ needed. + +To use ptmalloc (i.e. when linking ptmalloc.o into applications), no +special precautions are necessary except calling an initialization +routine, ptmalloc_init(), once before the first call to malloc() (or +calloc(), etc.). This call happens automatically when: + + o compiling ptmalloc with MALLOC_HOOKS defined (this is the default + when using the supplied Makefile) + o using the GNU C library + +So in any of these cases, you can omit the explicit ptmalloc_init() +call from applications using ptmalloc.o. + +On some systems, when overriding malloc and linking against shared +libraries, the link order becomes very important. E.g., when linking +C++ programs on Solaris, don't rely on libC being included by default, +but instead put `-lthread' behind `-lC' on the command line: + + CC ... ptmalloc.o -lC -lthread + +This is because there are global constructors in libC that need +malloc/ptmalloc, which in turn needs to have the thread library to be +already initialized. + +Debugging hooks +=============== + +When the ptmalloc.c source is compiled with MALLOC_HOOKS defined (this +is recommended), all calls to malloc(), realloc(), free() and +memalign() are routed through the global function pointers +__malloc_hook, __realloc_hook, __free_hook and __memalign_hook if they +are not NULL (see the ptmalloc.h header file for declarations of these +pointers). Therefore the malloc implementation can be changed at +runtime, if care is taken not to call free() or realloc() on pointers +obtained with a different implementation than the one currently in +effect. (The easiest way to guarantee this is to set up the hooks +before any malloc call, e.g. with a function pointed to by the global +variable __malloc_initialize_hook). + +A useful application of the hooks is built-in into ptmalloc: The +implementation is usually very unforgiving with respect to misuse, +such as free()ing a pointer twice or free()ing a pointer not obtained +with malloc() (these will typically crash the application +immediately). To debug in such situations, you can set the +environment variable `MALLOC_CHECK_' (note the trailing underscore). +Performance will suffer somewhat, but you will get more controlled +behaviour in the case of misuse. If MALLOC_CHECK_=0, wrong free()s +will be silently ignored, if MALLOC_CHECK_=1, diagnostics will be +printed on stderr, and if MALLOC_CHECK_=2, abort() will be called on +any error. + +You can now also tune other malloc parameters (normally adjused via +mallopt() calls from the application) with environment variables: + + MALLOC_TRIM_THRESHOLD_ for deciding to shrink the heap (in bytes) + + MALLOC_TOP_PAD_ how much extra memory to allocate on + each system call (in bytes) + + MALLOC_MMAP_THRESHOLD_ min. size for chunks allocated via + mmap() (in bytes) + + MALLOC_MMAP_MAX_ max. number of mmapped regions to use + +Tests +===== + +Two testing applications, t-test1 and t-test2, are included in this +source distribution. Both perform pseudo-random sequences of +allocations/frees, and can be given numeric arguments (all arguments +are optional): + +% t-test[12] + + n-total = total number of threads executed (default 10) + n-parallel = number of threads running in parallel (2) + n-allocs = number of malloc()'s / free()'s per thread (10000) + size-max = max. size requested with malloc() in bytes (10000) + bins = number of bins to maintain + +The first test `t-test1' maintains a completely seperate pool of +allocated bins for each thread, and should therefore show full +parallelism. On the other hand, `t-test2' creates only a single pool +of bins, and each thread randomly allocates/frees any bin. Some lock +contention is to be expected in this case, as the threads frequently +cross each others arena. + +Performance results from t-test1 should be quite repeatable, while the +behaviour of t-test2 depends on scheduling variations. + +Some performance data from t-test1 +================================== + +The times given are complete program execution times, obtained with +`time t-test1 ...'. + +1. SGI Octane, one R12000 300MHz CPU, Irix 6.5, `sproc' threads: + +20 threads (4 in parallel), 3000000 malloc calls per thread, max. size +5000 bytes, 5000 bins: + +ptmalloc: malloc from libc: +real 3m0.521s real 30m27.240s +user 2m45.336s user 10m7.592s +sys 0m3.014s sys 17m6.502s + +2. Same as 1., but with POSIX threads: + +20 threads (4 in parallel), 3000000 malloc calls per thread, max. size +5000 bytes, 5000 bins: + +ptmalloc: malloc from libc: +real 3m10.667s real 5m51.588s +user 2m57.052s user 5m27.986s +sys 0m2.399s sys 0m3.098s + +(Comparing the two ptmalloc results probably shows the slight +performance penalty from having to compile with USE_TSD_DATA_HACK when +using pthreads on Irix.) + +Special section on use of ptmalloc with Linux +============================================= + +On Linux, ptmalloc should work with the libpthreads library that is +included with Linux libc-5.x (but this is untested). Thanks to the +efforts of H.J. Lu and Ulrich Drepper, it is now an integral part of +the GNU C library 2.x releases (libc-6.x), so you don't need to +compile and link ptmalloc.o with glibc. diff --git a/Puma/src/win32/ptmalloc/lran2.h b/Puma/src/win32/ptmalloc/lran2.h new file mode 100644 index 0000000..cea9920 --- /dev/null +++ b/Puma/src/win32/ptmalloc/lran2.h @@ -0,0 +1,51 @@ +/* lran2.h + * by Wolfram Gloger 1996. + * + * A small, portable pseudo-random number generator. + */ + +#ifndef _LRAN2_H +#define _LRAN2_H + +#define LRAN2_MAX 714025l /* constants for portable */ +#define IA 1366l /* random number generator */ +#define IC 150889l /* (see e.g. `Numerical Recipes') */ + +struct lran2_st { + long x, y, v[97]; +}; + +static void +lran2_init(struct lran2_st* d, long seed) +{ + long x; + int j; + + x = (IC - seed) % LRAN2_MAX; + if(x < 0) x = -x; + for(j=0; j<97; j++) { + x = (IA*x + IC) % LRAN2_MAX; + d->v[j] = x; + } + d->x = (IA*x + IC) % LRAN2_MAX; + d->y = d->x; +} + +#ifdef __GNUC__ +__inline__ +#endif +static long +lran2(struct lran2_st* d) +{ + int j = (d->y % 97); + + d->y = d->v[j]; + d->x = (IA*d->x + IC) % LRAN2_MAX; + d->v[j] = d->x; + return d->y; +} + +#undef IA +#undef IC + +#endif diff --git a/Puma/src/win32/ptmalloc/ptmalloc.c b/Puma/src/win32/ptmalloc/ptmalloc.c new file mode 100644 index 0000000..4dcfcf8 --- /dev/null +++ b/Puma/src/win32/ptmalloc/ptmalloc.c @@ -0,0 +1,4840 @@ +/* Malloc implementation for multiple threads without lock contention. + Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Wolfram Gloger + and Doug Lea , 1996. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* $Id: ptmalloc.c,v 1.1.1.1 2003/07/02 16:32:09 matthias.urban Exp $ + + This work is mainly derived from malloc-2.6.4 by Doug Lea + , which is available from: + + ftp://g.oswego.edu/pub/misc/malloc.c + + Most of the original comments are reproduced in the code below. + +* Why use this malloc? + + This is not the fastest, most space-conserving, most portable, or + most tunable malloc ever written. However it is among the fastest + while also being among the most space-conserving, portable and tunable. + Consistent balance across these factors results in a good general-purpose + allocator. For a high-level description, see + http://g.oswego.edu/dl/html/malloc.html + + On many systems, the standard malloc implementation is by itself not + thread-safe, and therefore wrapped with a single global lock around + all malloc-related functions. In some applications, especially with + multiple available processors, this can lead to contention problems + and bad performance. This malloc version was designed with the goal + to avoid waiting for locks as much as possible. Statistics indicate + that this goal is achieved in many cases. + +* Synopsis of public routines + + (Much fuller descriptions are contained in the program documentation below.) + + ptmalloc_init(); + Initialize global configuration. When compiled for multiple threads, + this function must be called once before any other function in the + package. It is not required otherwise. It is called automatically + in the Linux/GNU C libray or when compiling with MALLOC_HOOKS. + malloc(size_t n); + Return a pointer to a newly allocated chunk of at least n bytes, or null + if no space is available. + free(Void_t* p); + Release the chunk of memory pointed to by p, or no effect if p is null. + realloc(Void_t* p, size_t n); + Return a pointer to a chunk of size n that contains the same data + as does chunk p up to the minimum of (n, p's size) bytes, or null + if no space is available. The returned pointer may or may not be + the same as p. If p is null, equivalent to malloc. Unless the + #define REALLOC_ZERO_BYTES_FREES below is set, realloc with a + size argument of zero (re)allocates a minimum-sized chunk. + memalign(size_t alignment, size_t n); + Return a pointer to a newly allocated chunk of n bytes, aligned + in accord with the alignment argument, which must be a power of + two. + valloc(size_t n); + Equivalent to memalign(pagesize, n), where pagesize is the page + size of the system (or as near to this as can be figured out from + all the includes/defines below.) + pvalloc(size_t n); + Equivalent to valloc(minimum-page-that-holds(n)), that is, + round up n to nearest pagesize. + calloc(size_t unit, size_t quantity); + Returns a pointer to quantity * unit bytes, with all locations + set to zero. + cfree(Void_t* p); + Equivalent to free(p). + malloc_trim(size_t pad); + Release all but pad bytes of freed top-most memory back + to the system. Return 1 if successful, else 0. + malloc_usable_size(Void_t* p); + Report the number usable allocated bytes associated with allocated + chunk p. This may or may not report more bytes than were requested, + due to alignment and minimum size constraints. + malloc_stats(); + Prints brief summary statistics on stderr. + mallinfo() + Returns (by copy) a struct containing various summary statistics. + mallopt(int parameter_number, int parameter_value) + Changes one of the tunable parameters described below. Returns + 1 if successful in changing the parameter, else 0. + +* Vital statistics: + + Alignment: 8-byte + 8 byte alignment is currently hardwired into the design. This + seems to suffice for all current machines and C compilers. + + Assumed pointer representation: 4 or 8 bytes + Code for 8-byte pointers is untested by me but has worked + reliably by Wolfram Gloger, who contributed most of the + changes supporting this. + + Assumed size_t representation: 4 or 8 bytes + Note that size_t is allowed to be 4 bytes even if pointers are 8. + + Minimum overhead per allocated chunk: 4 or 8 bytes + Each malloced chunk has a hidden overhead of 4 bytes holding size + and status information. + + Minimum allocated size: 4-byte ptrs: 16 bytes (including 4 overhead) + 8-byte ptrs: 24/32 bytes (including, 4/8 overhead) + + When a chunk is freed, 12 (for 4byte ptrs) or 20 (for 8 byte + ptrs but 4 byte size) or 24 (for 8/8) additional bytes are + needed; 4 (8) for a trailing size field + and 8 (16) bytes for free list pointers. Thus, the minimum + allocatable size is 16/24/32 bytes. + + Even a request for zero bytes (i.e., malloc(0)) returns a + pointer to something of the minimum allocatable size. + + Maximum allocated size: 4-byte size_t: 2^31 - 8 bytes + 8-byte size_t: 2^63 - 16 bytes + + It is assumed that (possibly signed) size_t bit values suffice to + represent chunk sizes. `Possibly signed' is due to the fact + that `size_t' may be defined on a system as either a signed or + an unsigned type. To be conservative, values that would appear + as negative numbers are avoided. + Requests for sizes with a negative sign bit will return a + minimum-sized chunk. + + Maximum overhead wastage per allocated chunk: normally 15 bytes + + Alignment demands, plus the minimum allocatable size restriction + make the normal worst-case wastage 15 bytes (i.e., up to 15 + more bytes will be allocated than were requested in malloc), with + two exceptions: + 1. Because requests for zero bytes allocate non-zero space, + the worst case wastage for a request of zero bytes is 24 bytes. + 2. For requests >= mmap_threshold that are serviced via + mmap(), the worst case wastage is 8 bytes plus the remainder + from a system page (the minimal mmap unit); typically 4096 bytes. + +* Limitations + + Here are some features that are NOT currently supported + + * No automated mechanism for fully checking that all accesses + to malloced memory stay within their bounds. + * No support for compaction. + +* Synopsis of compile-time options: + + People have reported using previous versions of this malloc on all + versions of Unix, sometimes by tweaking some of the defines + below. It has been tested most extensively on Solaris and + Linux. People have also reported adapting this malloc for use in + stand-alone embedded systems. + + The implementation is in straight, hand-tuned ANSI C. Among other + consequences, it uses a lot of macros. Because of this, to be at + all usable, this code should be compiled using an optimizing compiler + (for example gcc -O2) that can simplify expressions and control + paths. + + __STD_C (default: derived from C compiler defines) + Nonzero if using ANSI-standard C compiler, a C++ compiler, or + a C compiler sufficiently close to ANSI to get away with it. + MALLOC_DEBUG (default: NOT defined) + Define to enable debugging. Adds fairly extensive assertion-based + checking to help track down memory errors, but noticeably slows down + execution. + MALLOC_HOOKS (default: NOT defined) + Define to enable support run-time replacement of the allocation + functions through user-defined `hooks'. + REALLOC_ZERO_BYTES_FREES (default: defined) + Define this if you think that realloc(p, 0) should be equivalent + to free(p). (The C standard requires this behaviour, therefore + it is the default.) Otherwise, since malloc returns a unique + pointer for malloc(0), so does realloc(p, 0). + HAVE_MEMCPY (default: defined) + Define if you are not otherwise using ANSI STD C, but still + have memcpy and memset in your C library and want to use them. + Otherwise, simple internal versions are supplied. + USE_MEMCPY (default: 1 if HAVE_MEMCPY is defined, 0 otherwise) + Define as 1 if you want the C library versions of memset and + memcpy called in realloc and calloc (otherwise macro versions are used). + At least on some platforms, the simple macro versions usually + outperform libc versions. + HAVE_MMAP (default: defined as 1) + Define to non-zero to optionally make malloc() use mmap() to + allocate very large blocks. + HAVE_MREMAP (default: defined as 0 unless Linux libc set) + Define to non-zero to optionally make realloc() use mremap() to + reallocate very large blocks. + USE_ARENAS (default: the same as HAVE_MMAP) + Enable support for multiple arenas, allocated using mmap(). + malloc_getpagesize (default: derived from system #includes) + Either a constant or routine call returning the system page size. + HAVE_USR_INCLUDE_MALLOC_H (default: NOT defined) + Optionally define if you are on a system with a /usr/include/malloc.h + that declares struct mallinfo. It is not at all necessary to + define this even if you do, but will ensure consistency. + INTERNAL_SIZE_T (default: size_t) + Define to a 32-bit type (probably `unsigned int') if you are on a + 64-bit machine, yet do not want or need to allow malloc requests of + greater than 2^31 to be handled. This saves space, especially for + very small chunks. + _LIBC (default: NOT defined) + Defined only when compiled as part of the Linux libc/glibc. + Also note that there is some odd internal name-mangling via defines + (for example, internally, `malloc' is named `mALLOc') needed + when compiling in this case. These look funny but don't otherwise + affect anything. + LACKS_UNISTD_H (default: undefined) + Define this if your system does not have a . + MORECORE (default: sbrk) + The name of the routine to call to obtain more memory from the system. + MORECORE_FAILURE (default: -1) + The value returned upon failure of MORECORE. + MORECORE_CLEARS (default 1) + The degree to which the routine mapped to MORECORE zeroes out + memory: never (0), only for newly allocated space (1) or always + (2). The distinction between (1) and (2) is necessary because on + some systems, if the application first decrements and then + increments the break value, the contents of the reallocated space + are unspecified. + DEFAULT_TRIM_THRESHOLD + DEFAULT_TOP_PAD + DEFAULT_MMAP_THRESHOLD + DEFAULT_MMAP_MAX + Default values of tunable parameters (described in detail below) + controlling interaction with host system routines (sbrk, mmap, etc). + These values may also be changed dynamically via mallopt(). The + preset defaults are those that give best performance for typical + programs/systems. + DEFAULT_CHECK_ACTION + When the standard debugging hooks are in place, and a pointer is + detected as corrupt, do nothing (0), print an error message (1), + or call abort() (2). + + +*/ + +/* + +* Compile-time options for multiple threads: + + USE_PTHREADS, USE_THR, USE_SPROC + Define one of these as 1 to select the thread interface: + POSIX threads, Solaris threads or SGI sproc's, respectively. + If none of these is defined as non-zero, you get a `normal' + malloc implementation which is not thread-safe. Support for + multiple threads requires HAVE_MMAP=1. As an exception, when + compiling for GNU libc, i.e. when _LIBC is defined, then none of + the USE_... symbols have to be defined. + + HEAP_MIN_SIZE + HEAP_MAX_SIZE + When thread support is enabled, additional `heap's are created + with mmap calls. These are limited in size; HEAP_MIN_SIZE should + be a multiple of the page size, while HEAP_MAX_SIZE must be a power + of two for alignment reasons. HEAP_MAX_SIZE should be at least + twice as large as the mmap threshold. + THREAD_STATS + When this is defined as non-zero, some statistics on mutex locking + are computed. + +*/ + + + + +/* Preliminaries */ + +#ifndef __STD_C +#if defined (__STDC__) +#define __STD_C 1 +#else +#if __cplusplus +#define __STD_C 1 +#else +#define __STD_C 0 +#endif /*__cplusplus*/ +#endif /*__STDC__*/ +#endif /*__STD_C*/ + +#ifndef Void_t +#if __STD_C +#define Void_t void +#else +#define Void_t char +#endif +#endif /*Void_t*/ + +#if __STD_C +# include /* for size_t */ +# if defined _LIBC || defined MALLOC_HOOKS +# include /* for getenv(), abort() */ +# endif +#else +# include +# if defined _LIBC || defined MALLOC_HOOKS +extern char* getenv(); +# endif +#endif + +#ifndef _LIBC +# define __secure_getenv(Str) getenv (Str) +#endif + +/* Macros for handling mutexes and thread-specific data. This is + included early, because some thread-related header files (such as + pthread.h) should be included before any others. */ +#include "thread-m.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include /* needed for malloc_stats */ + +/* + Compile-time options +*/ + + +/* + Debugging: + + Because freed chunks may be overwritten with link fields, this + malloc will often die when freed memory is overwritten by user + programs. This can be very effective (albeit in an annoying way) + in helping track down dangling pointers. + + If you compile with -DMALLOC_DEBUG, a number of assertion checks are + enabled that will catch more memory errors. You probably won't be + able to make much sense of the actual assertion errors, but they + should help you locate incorrectly overwritten memory. The + checking is fairly extensive, and will slow down execution + noticeably. Calling malloc_stats or mallinfo with MALLOC_DEBUG set will + attempt to check every non-mmapped allocated and free chunk in the + course of computing the summaries. (By nature, mmapped regions + cannot be checked very much automatically.) + + Setting MALLOC_DEBUG may also be helpful if you are trying to modify + this code. The assertions in the check routines spell out in more + detail the assumptions and invariants underlying the algorithms. + +*/ + +#if MALLOC_DEBUG +#include +#else +#define assert(x) ((void)0) +#endif + + +/* + INTERNAL_SIZE_T is the word-size used for internal bookkeeping + of chunk sizes. On a 64-bit machine, you can reduce malloc + overhead by defining INTERNAL_SIZE_T to be a 32 bit `unsigned int' + at the expense of not being able to handle requests greater than + 2^31. This limitation is hardly ever a concern; you are encouraged + to set this. However, the default version is the same as size_t. +*/ + +#ifndef INTERNAL_SIZE_T +#define INTERNAL_SIZE_T size_t +#endif + +/* + REALLOC_ZERO_BYTES_FREES should be set if a call to realloc with + zero bytes should be the same as a call to free. The C standard + requires this. Otherwise, since this malloc returns a unique pointer + for malloc(0), so does realloc(p, 0). +*/ + + +#define REALLOC_ZERO_BYTES_FREES + + +/* + HAVE_MEMCPY should be defined if you are not otherwise using + ANSI STD C, but still have memcpy and memset in your C library + and want to use them in calloc and realloc. Otherwise simple + macro versions are defined here. + + USE_MEMCPY should be defined as 1 if you actually want to + have memset and memcpy called. People report that the macro + versions are often enough faster than libc versions on many + systems that it is better to use them. + +*/ + +#define HAVE_MEMCPY 1 + +#ifndef USE_MEMCPY +#ifdef HAVE_MEMCPY +#define USE_MEMCPY 1 +#else +#define USE_MEMCPY 0 +#endif +#endif + +#if (__STD_C || defined(HAVE_MEMCPY)) + +#if __STD_C +void* memset(void*, int, size_t); +void* memcpy(void*, const void*, size_t); +#else +Void_t* memset(); +Void_t* memcpy(); +#endif +#endif + +#if USE_MEMCPY + +/* The following macros are only invoked with (2n+1)-multiples of + INTERNAL_SIZE_T units, with a positive integer n. This is exploited + for fast inline execution when n is small. */ + +#define MALLOC_ZERO(charp, nbytes) \ +do { \ + INTERNAL_SIZE_T mzsz = (nbytes); \ + if(mzsz <= 9*sizeof(mzsz)) { \ + INTERNAL_SIZE_T* mz = (INTERNAL_SIZE_T*) (charp); \ + if(mzsz >= 5*sizeof(mzsz)) { *mz++ = 0; \ + *mz++ = 0; \ + if(mzsz >= 7*sizeof(mzsz)) { *mz++ = 0; \ + *mz++ = 0; \ + if(mzsz >= 9*sizeof(mzsz)) { *mz++ = 0; \ + *mz++ = 0; }}} \ + *mz++ = 0; \ + *mz++ = 0; \ + *mz = 0; \ + } else memset((charp), 0, mzsz); \ +} while(0) + +#define MALLOC_COPY(dest,src,nbytes) \ +do { \ + INTERNAL_SIZE_T mcsz = (nbytes); \ + if(mcsz <= 9*sizeof(mcsz)) { \ + INTERNAL_SIZE_T* mcsrc = (INTERNAL_SIZE_T*) (src); \ + INTERNAL_SIZE_T* mcdst = (INTERNAL_SIZE_T*) (dest); \ + if(mcsz >= 5*sizeof(mcsz)) { *mcdst++ = *mcsrc++; \ + *mcdst++ = *mcsrc++; \ + if(mcsz >= 7*sizeof(mcsz)) { *mcdst++ = *mcsrc++; \ + *mcdst++ = *mcsrc++; \ + if(mcsz >= 9*sizeof(mcsz)) { *mcdst++ = *mcsrc++; \ + *mcdst++ = *mcsrc++; }}} \ + *mcdst++ = *mcsrc++; \ + *mcdst++ = *mcsrc++; \ + *mcdst = *mcsrc ; \ + } else memcpy(dest, src, mcsz); \ +} while(0) + +#else /* !USE_MEMCPY */ + +/* Use Duff's device for good zeroing/copying performance. */ + +#define MALLOC_ZERO(charp, nbytes) \ +do { \ + INTERNAL_SIZE_T* mzp = (INTERNAL_SIZE_T*)(charp); \ + long mctmp = (nbytes)/sizeof(INTERNAL_SIZE_T), mcn; \ + if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp %= 8; } \ + switch (mctmp) { \ + case 0: for(;;) { *mzp++ = 0; \ + case 7: *mzp++ = 0; \ + case 6: *mzp++ = 0; \ + case 5: *mzp++ = 0; \ + case 4: *mzp++ = 0; \ + case 3: *mzp++ = 0; \ + case 2: *mzp++ = 0; \ + case 1: *mzp++ = 0; if(mcn <= 0) break; mcn--; } \ + } \ +} while(0) + +#define MALLOC_COPY(dest,src,nbytes) \ +do { \ + INTERNAL_SIZE_T* mcsrc = (INTERNAL_SIZE_T*) src; \ + INTERNAL_SIZE_T* mcdst = (INTERNAL_SIZE_T*) dest; \ + long mctmp = (nbytes)/sizeof(INTERNAL_SIZE_T), mcn; \ + if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp %= 8; } \ + switch (mctmp) { \ + case 0: for(;;) { *mcdst++ = *mcsrc++; \ + case 7: *mcdst++ = *mcsrc++; \ + case 6: *mcdst++ = *mcsrc++; \ + case 5: *mcdst++ = *mcsrc++; \ + case 4: *mcdst++ = *mcsrc++; \ + case 3: *mcdst++ = *mcsrc++; \ + case 2: *mcdst++ = *mcsrc++; \ + case 1: *mcdst++ = *mcsrc++; if(mcn <= 0) break; mcn--; } \ + } \ +} while(0) + +#endif + + +/* + Define HAVE_MMAP to optionally make malloc() use mmap() to allocate + very large blocks. These will be returned to the operating system + immediately after a free(). HAVE_MMAP is also a prerequisite to + support multiple `arenas' (see USE_ARENAS below). +*/ + +#ifndef HAVE_MMAP +#define HAVE_MMAP 0 +#endif + +/* + Define HAVE_MREMAP to make realloc() use mremap() to re-allocate + large blocks. This is currently only possible on Linux with + kernel versions newer than 1.3.77. +*/ + +#ifndef HAVE_MREMAP +#define HAVE_MREMAP defined(__linux__) && !defined(__arm__) +#endif + +/* Define USE_ARENAS to enable support for multiple `arenas'. These + are allocated using mmap(), are necessary for threads and + occasionally useful to overcome address space limitations affecting + sbrk(). */ + +#ifndef USE_ARENAS +#define USE_ARENAS HAVE_MMAP +#endif + +#if HAVE_MMAP + +#include +#include +#include + +#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) +#define MAP_ANONYMOUS MAP_ANON +#endif +#if !defined(MAP_FAILED) +#define MAP_FAILED ((char*)-1) +#endif + +#ifndef MAP_NORESERVE +# ifdef MAP_AUTORESRV +# define MAP_NORESERVE MAP_AUTORESRV +# else +# define MAP_NORESERVE 0 +# endif +#endif + +#endif /* HAVE_MMAP */ + +/* + Access to system page size. To the extent possible, this malloc + manages memory from the system in page-size units. + + The following mechanics for getpagesize were adapted from + bsd/gnu getpagesize.h +*/ + +#ifndef LACKS_UNISTD_H +# include +#endif + +#ifndef malloc_getpagesize +# ifdef _SC_PAGESIZE /* some SVR4 systems omit an underscore */ +# ifndef _SC_PAGE_SIZE +# define _SC_PAGE_SIZE _SC_PAGESIZE +# endif +# endif +# ifdef _SC_PAGE_SIZE +# define malloc_getpagesize sysconf(_SC_PAGE_SIZE) +# else +# if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE) + extern size_t getpagesize(); +# define malloc_getpagesize getpagesize() +# else +# include +# ifdef EXEC_PAGESIZE +# define malloc_getpagesize EXEC_PAGESIZE +# else +# ifdef NBPG +# ifndef CLSIZE +# define malloc_getpagesize NBPG +# else +# define malloc_getpagesize (NBPG * CLSIZE) +# endif +# else +# ifdef NBPC +# define malloc_getpagesize NBPC +# else +# ifdef PAGESIZE +# define malloc_getpagesize PAGESIZE +# else +# define malloc_getpagesize (4096) /* just guess */ +# endif +# endif +# endif +# endif +# endif +# endif +#endif + + + +/* + + This version of malloc supports the standard SVID/XPG mallinfo + routine that returns a struct containing the same kind of + information you can get from malloc_stats. It should work on + any SVID/XPG compliant system that has a /usr/include/malloc.h + defining struct mallinfo. (If you'd like to install such a thing + yourself, cut out the preliminary declarations as described above + and below and save them in a malloc.h file. But there's no + compelling reason to bother to do this.) + + The main declaration needed is the mallinfo struct that is returned + (by-copy) by mallinfo(). The SVID/XPG malloinfo struct contains a + bunch of fields, most of which are not even meaningful in this + version of malloc. Some of these fields are are instead filled by + mallinfo() with other numbers that might possibly be of interest. + + HAVE_USR_INCLUDE_MALLOC_H should be set if you have a + /usr/include/malloc.h file that includes a declaration of struct + mallinfo. If so, it is included; else an SVID2/XPG2 compliant + version is declared below. These must be precisely the same for + mallinfo() to work. + +*/ + +/* #define HAVE_USR_INCLUDE_MALLOC_H */ + +#if HAVE_USR_INCLUDE_MALLOC_H +# include "/usr/include/malloc.h" +#else +# ifdef _LIBC +# include "malloc.h" +# else +# include "ptmalloc.h" +# endif +#endif + + + +#ifndef DEFAULT_TRIM_THRESHOLD +#define DEFAULT_TRIM_THRESHOLD (128 * 1024) +#endif + +/* + M_TRIM_THRESHOLD is the maximum amount of unused top-most memory + to keep before releasing via malloc_trim in free(). + + Automatic trimming is mainly useful in long-lived programs. + Because trimming via sbrk can be slow on some systems, and can + sometimes be wasteful (in cases where programs immediately + afterward allocate more large chunks) the value should be high + enough so that your overall system performance would improve by + releasing. + + The trim threshold and the mmap control parameters (see below) + can be traded off with one another. Trimming and mmapping are + two different ways of releasing unused memory back to the + system. Between these two, it is often possible to keep + system-level demands of a long-lived program down to a bare + minimum. For example, in one test suite of sessions measuring + the XF86 X server on Linux, using a trim threshold of 128K and a + mmap threshold of 192K led to near-minimal long term resource + consumption. + + If you are using this malloc in a long-lived program, it should + pay to experiment with these values. As a rough guide, you + might set to a value close to the average size of a process + (program) running on your system. Releasing this much memory + would allow such a process to run in memory. Generally, it's + worth it to tune for trimming rather than memory mapping when a + program undergoes phases where several large chunks are + allocated and released in ways that can reuse each other's + storage, perhaps mixed with phases where there are no such + chunks at all. And in well-behaved long-lived programs, + controlling release of large blocks via trimming versus mapping + is usually faster. + + However, in most programs, these parameters serve mainly as + protection against the system-level effects of carrying around + massive amounts of unneeded memory. Since frequent calls to + sbrk, mmap, and munmap otherwise degrade performance, the default + parameters are set to relatively high values that serve only as + safeguards. + + The default trim value is high enough to cause trimming only in + fairly extreme (by current memory consumption standards) cases. + It must be greater than page size to have any useful effect. To + disable trimming completely, you can set to (unsigned long)(-1); + + +*/ + + +#ifndef DEFAULT_TOP_PAD +#define DEFAULT_TOP_PAD (0) +#endif + +/* + M_TOP_PAD is the amount of extra `padding' space to allocate or + retain whenever sbrk is called. It is used in two ways internally: + + * When sbrk is called to extend the top of the arena to satisfy + a new malloc request, this much padding is added to the sbrk + request. + + * When malloc_trim is called automatically from free(), + it is used as the `pad' argument. + + In both cases, the actual amount of padding is rounded + so that the end of the arena is always a system page boundary. + + The main reason for using padding is to avoid calling sbrk so + often. Having even a small pad greatly reduces the likelihood + that nearly every malloc request during program start-up (or + after trimming) will invoke sbrk, which needlessly wastes + time. + + Automatic rounding-up to page-size units is normally sufficient + to avoid measurable overhead, so the default is 0. However, in + systems where sbrk is relatively slow, it can pay to increase + this value, at the expense of carrying around more memory than + the program needs. + +*/ + + +#ifndef DEFAULT_MMAP_THRESHOLD +#define DEFAULT_MMAP_THRESHOLD (128 * 1024) +#endif + +/* + + M_MMAP_THRESHOLD is the request size threshold for using mmap() + to service a request. Requests of at least this size that cannot + be allocated using already-existing space will be serviced via mmap. + (If enough normal freed space already exists it is used instead.) + + Using mmap segregates relatively large chunks of memory so that + they can be individually obtained and released from the host + system. A request serviced through mmap is never reused by any + other request (at least not directly; the system may just so + happen to remap successive requests to the same locations). + + Segregating space in this way has the benefit that mmapped space + can ALWAYS be individually released back to the system, which + helps keep the system level memory demands of a long-lived + program low. Mapped memory can never become `locked' between + other chunks, as can happen with normally allocated chunks, which + menas that even trimming via malloc_trim would not release them. + + However, it has the disadvantages that: + + 1. The space cannot be reclaimed, consolidated, and then + used to service later requests, as happens with normal chunks. + 2. It can lead to more wastage because of mmap page alignment + requirements + 3. It causes malloc performance to be more dependent on host + system memory management support routines which may vary in + implementation quality and may impose arbitrary + limitations. Generally, servicing a request via normal + malloc steps is faster than going through a system's mmap. + + All together, these considerations should lead you to use mmap + only for relatively large requests. + + +*/ + + + +#ifndef DEFAULT_MMAP_MAX +#if HAVE_MMAP +#define DEFAULT_MMAP_MAX (1024) +#else +#define DEFAULT_MMAP_MAX (0) +#endif +#endif + +/* + M_MMAP_MAX is the maximum number of requests to simultaneously + service using mmap. This parameter exists because: + + 1. Some systems have a limited number of internal tables for + use by mmap. + 2. In most systems, overreliance on mmap can degrade overall + performance. + 3. If a program allocates many large regions, it is probably + better off using normal sbrk-based allocation routines that + can reclaim and reallocate normal heap memory. Using a + small value allows transition into this mode after the + first few allocations. + + Setting to 0 disables all use of mmap. If HAVE_MMAP is not set, + the default value is 0, and attempts to set it to non-zero values + in mallopt will fail. +*/ + + + +#ifndef DEFAULT_CHECK_ACTION +#define DEFAULT_CHECK_ACTION 1 +#endif + +/* What to do if the standard debugging hooks are in place and a + corrupt pointer is detected: do nothing (0), print an error message + (1), or call abort() (2). */ + + + +#define HEAP_MIN_SIZE (32*1024) +#define HEAP_MAX_SIZE (1024*1024) /* must be a power of two */ + +/* HEAP_MIN_SIZE and HEAP_MAX_SIZE limit the size of mmap()ed heaps + that are dynamically created for multi-threaded programs. The + maximum size must be a power of two, for fast determination of + which heap belongs to a chunk. It should be much larger than + the mmap threshold, so that requests with a size just below that + threshold can be fulfilled without creating too many heaps. +*/ + + + +#ifndef THREAD_STATS +#define THREAD_STATS 0 +#endif + +/* If THREAD_STATS is non-zero, some statistics on mutex locking are + computed. */ + + +/* Macro to set errno. */ +#ifndef __set_errno +# define __set_errno(val) errno = (val) +#endif + +/* On some platforms we can compile internal, not exported functions better. + Let the environment provide a macro and define it to be empty if it + is not available. */ +#ifndef internal_function +# define internal_function +#endif + + +/* + + Special defines for the Linux/GNU C library. + +*/ + + +#ifdef _LIBC + +#if __STD_C + +Void_t * __default_morecore (ptrdiff_t); +Void_t *(*__morecore)(ptrdiff_t) = __default_morecore; + +#else + +Void_t * __default_morecore (); +Void_t *(*__morecore)() = __default_morecore; + +#endif + +#define MORECORE (*__morecore) +#define MORECORE_FAILURE 0 + +#ifndef MORECORE_CLEARS +#define MORECORE_CLEARS 1 +#endif + +static size_t __libc_pagesize; + +#define mmap __mmap +#define munmap __munmap +#define mremap __mremap +#define mprotect __mprotect +#undef malloc_getpagesize +#define malloc_getpagesize __libc_pagesize + +#else /* _LIBC */ + +#if __STD_C +extern Void_t* sbrk(ptrdiff_t); +#else +extern Void_t* sbrk(); +#endif + +#ifndef MORECORE +#define MORECORE sbrk +#endif + +#ifndef MORECORE_FAILURE +#define MORECORE_FAILURE -1 +#endif + +#ifndef MORECORE_CLEARS +#define MORECORE_CLEARS 1 +#endif + +#endif /* _LIBC */ + +#ifdef _LIBC + +#define cALLOc __libc_calloc +#define fREe __libc_free +#define mALLOc __libc_malloc +#define mEMALIGn __libc_memalign +#define rEALLOc __libc_realloc +#define vALLOc __libc_valloc +#define pvALLOc __libc_pvalloc +#define mALLINFo __libc_mallinfo +#define mALLOPt __libc_mallopt +#define mALLOC_STATs __malloc_stats +#define mALLOC_USABLE_SIZe __malloc_usable_size +#define mALLOC_TRIm __malloc_trim +#define mALLOC_GET_STATe __malloc_get_state +#define mALLOC_SET_STATe __malloc_set_state + +#else + +#define cALLOc pt_calloc +#define fREe pt_free +#define mALLOc pt_malloc +#define mEMALIGn pt_memalign +#define rEALLOc pt_realloc +#define vALLOc pt_valloc +#define pvALLOc pt_pvalloc +#define mALLINFo mallinfo +#define mALLOPt mallopt +#define mALLOC_STATs malloc_stats +#define mALLOC_USABLE_SIZe malloc_usable_size +#define mALLOC_TRIm malloc_trim +#define mALLOC_GET_STATe malloc_get_state +#define mALLOC_SET_STATe malloc_set_state + +#endif + +/* Public routines */ + +#if __STD_C + +#ifndef _LIBC +void ptmalloc_init(void); +#endif +Void_t* mALLOc(size_t); +void fREe(Void_t*); +Void_t* rEALLOc(Void_t*, size_t); +Void_t* mEMALIGn(size_t, size_t); +Void_t* vALLOc(size_t); +Void_t* pvALLOc(size_t); +Void_t* cALLOc(size_t, size_t); +void cfree(Void_t*); +int mALLOC_TRIm(size_t); +size_t mALLOC_USABLE_SIZe(Void_t*); +void mALLOC_STATs(void); +int mALLOPt(int, int); +struct mallinfo mALLINFo(void); +Void_t* mALLOC_GET_STATe(void); +int mALLOC_SET_STATe(Void_t*); + +#else /* !__STD_C */ + +#ifndef _LIBC +void ptmalloc_init(); +#endif +Void_t* mALLOc(); +void fREe(); +Void_t* rEALLOc(); +Void_t* mEMALIGn(); +Void_t* vALLOc(); +Void_t* pvALLOc(); +Void_t* cALLOc(); +void cfree(); +int mALLOC_TRIm(); +size_t mALLOC_USABLE_SIZe(); +void mALLOC_STATs(); +int mALLOPt(); +struct mallinfo mALLINFo(); +Void_t* mALLOC_GET_STATe(); +int mALLOC_SET_STATe(); + +#endif /* __STD_C */ + + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#if !defined(NO_THREADS) && !HAVE_MMAP +"Can't have threads support without mmap" +#endif +#if USE_ARENAS && !HAVE_MMAP +"Can't have multiple arenas without mmap" +#endif + + +/* + Type declarations +*/ + + +struct malloc_chunk +{ + INTERNAL_SIZE_T prev_size; /* Size of previous chunk (if free). */ + INTERNAL_SIZE_T size; /* Size in bytes, including overhead. */ + struct malloc_chunk* fd; /* double links -- used only if free. */ + struct malloc_chunk* bk; +}; + +typedef struct malloc_chunk* mchunkptr; + +/* + + malloc_chunk details: + + (The following includes lightly edited explanations by Colin Plumb.) + + Chunks of memory are maintained using a `boundary tag' method as + described in e.g., Knuth or Standish. (See the paper by Paul + Wilson ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a + survey of such techniques.) Sizes of free chunks are stored both + in the front of each chunk and at the end. This makes + consolidating fragmented chunks into bigger chunks very fast. The + size fields also hold bits representing whether chunks are free or + in use. + + An allocated chunk looks like this: + + + chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Size of previous chunk, if allocated | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Size of chunk, in bytes |P| + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | User data starts here... . + . . + . (malloc_usable_space() bytes) . + . | +nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Size of chunk | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + Where "chunk" is the front of the chunk for the purpose of most of + the malloc code, but "mem" is the pointer that is returned to the + user. "Nextchunk" is the beginning of the next contiguous chunk. + + Chunks always begin on even word boundaries, so the mem portion + (which is returned to the user) is also on an even word boundary, and + thus double-word aligned. + + Free chunks are stored in circular doubly-linked lists, and look like this: + + chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Size of previous chunk | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + `head:' | Size of chunk, in bytes |P| + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Forward pointer to next chunk in list | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Back pointer to previous chunk in list | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Unused space (may be 0 bytes long) . + . . + . | +nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + `foot:' | Size of chunk, in bytes | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + The P (PREV_INUSE) bit, stored in the unused low-order bit of the + chunk size (which is always a multiple of two words), is an in-use + bit for the *previous* chunk. If that bit is *clear*, then the + word before the current chunk size contains the previous chunk + size, and can be used to find the front of the previous chunk. + (The very first chunk allocated always has this bit set, + preventing access to non-existent (or non-owned) memory.) + + Note that the `foot' of the current chunk is actually represented + as the prev_size of the NEXT chunk. (This makes it easier to + deal with alignments etc). + + The two exceptions to all this are + + 1. The special chunk `top', which doesn't bother using the + trailing size field since there is no + next contiguous chunk that would have to index off it. (After + initialization, `top' is forced to always exist. If it would + become less than MINSIZE bytes long, it is replenished via + malloc_extend_top.) + + 2. Chunks allocated via mmap, which have the second-lowest-order + bit (IS_MMAPPED) set in their size fields. Because they are + never merged or traversed from any other chunk, they have no + foot size or inuse information. + + Available chunks are kept in any of several places (all declared below): + + * `av': An array of chunks serving as bin headers for consolidated + chunks. Each bin is doubly linked. The bins are approximately + proportionally (log) spaced. There are a lot of these bins + (128). This may look excessive, but works very well in + practice. All procedures maintain the invariant that no + consolidated chunk physically borders another one. Chunks in + bins are kept in size order, with ties going to the + approximately least recently used chunk. + + The chunks in each bin are maintained in decreasing sorted order by + size. This is irrelevant for the small bins, which all contain + the same-sized chunks, but facilitates best-fit allocation for + larger chunks. (These lists are just sequential. Keeping them in + order almost never requires enough traversal to warrant using + fancier ordered data structures.) Chunks of the same size are + linked with the most recently freed at the front, and allocations + are taken from the back. This results in LRU or FIFO allocation + order, which tends to give each chunk an equal opportunity to be + consolidated with adjacent freed chunks, resulting in larger free + chunks and less fragmentation. + + * `top': The top-most available chunk (i.e., the one bordering the + end of available memory) is treated specially. It is never + included in any bin, is used only if no other chunk is + available, and is released back to the system if it is very + large (see M_TRIM_THRESHOLD). + + * `last_remainder': A bin holding only the remainder of the + most recently split (non-top) chunk. This bin is checked + before other non-fitting chunks, so as to provide better + locality for runs of sequentially allocated chunks. + + * Implicitly, through the host system's memory mapping tables. + If supported, requests greater than a threshold are usually + serviced via calls to mmap, and then later released via munmap. + +*/ + +/* + Bins + + The bins are an array of pairs of pointers serving as the + heads of (initially empty) doubly-linked lists of chunks, laid out + in a way so that each pair can be treated as if it were in a + malloc_chunk. (This way, the fd/bk offsets for linking bin heads + and chunks are the same). + + Bins for sizes < 512 bytes contain chunks of all the same size, spaced + 8 bytes apart. Larger bins are approximately logarithmically + spaced. (See the table below.) + + Bin layout: + + 64 bins of size 8 + 32 bins of size 64 + 16 bins of size 512 + 8 bins of size 4096 + 4 bins of size 32768 + 2 bins of size 262144 + 1 bin of size what's left + + There is actually a little bit of slop in the numbers in bin_index + for the sake of speed. This makes no difference elsewhere. + + The special chunks `top' and `last_remainder' get their own bins, + (this is implemented via yet more trickery with the av array), + although `top' is never properly linked to its bin since it is + always handled specially. + +*/ + +#define NAV 128 /* number of bins */ + +typedef struct malloc_chunk* mbinptr; + +/* An arena is a configuration of malloc_chunks together with an array + of bins. With multiple threads, it must be locked via a mutex + before changing its data structures. One or more `heaps' are + associated with each arena, except for the main_arena, which is + associated only with the `main heap', i.e. the conventional free + store obtained with calls to MORECORE() (usually sbrk). The `av' + array is never mentioned directly in the code, but instead used via + bin access macros. */ + +typedef struct _arena { + mbinptr av[2*NAV + 2]; + struct _arena *next; + size_t size; +#if THREAD_STATS + long stat_lock_direct, stat_lock_loop, stat_lock_wait; +#endif + mutex_t mutex; +} arena; + + +/* A heap is a single contiguous memory region holding (coalesceable) + malloc_chunks. It is allocated with mmap() and always starts at an + address aligned to HEAP_MAX_SIZE. Not used unless compiling with + USE_ARENAS. */ + +typedef struct _heap_info { + arena *ar_ptr; /* Arena for this heap. */ + struct _heap_info *prev; /* Previous heap. */ + size_t size; /* Current size in bytes. */ + size_t pad; /* Make sure the following data is properly aligned. */ +} heap_info; + + +/* + Static functions (forward declarations) +*/ + +#if __STD_C + +static void chunk_free(arena *ar_ptr, mchunkptr p) internal_function; +static mchunkptr chunk_alloc(arena *ar_ptr, INTERNAL_SIZE_T size) + internal_function; +static mchunkptr chunk_realloc(arena *ar_ptr, mchunkptr oldp, + INTERNAL_SIZE_T oldsize, INTERNAL_SIZE_T nb) + internal_function; +static mchunkptr chunk_align(arena *ar_ptr, INTERNAL_SIZE_T nb, + size_t alignment) internal_function; +static int main_trim(size_t pad) internal_function; +#if USE_ARENAS +static int heap_trim(heap_info *heap, size_t pad) internal_function; +#endif +#if defined _LIBC || defined MALLOC_HOOKS +static Void_t* malloc_check(size_t sz); +static void free_check(Void_t* mem); +static Void_t* realloc_check(Void_t* oldmem, size_t bytes); +static Void_t* memalign_check(size_t alignment, size_t bytes); +#ifndef NO_THREADS +static Void_t* malloc_starter(size_t sz); +static void free_starter(Void_t* mem); +static Void_t* malloc_atfork(size_t sz); +static void free_atfork(Void_t* mem); +#endif +#endif + +#else + +static void chunk_free(); +static mchunkptr chunk_alloc(); +static mchunkptr chunk_realloc(); +static mchunkptr chunk_align(); +static int main_trim(); +#if USE_ARENAS +static int heap_trim(); +#endif +#if defined _LIBC || defined MALLOC_HOOKS +static Void_t* malloc_check(); +static void free_check(); +static Void_t* realloc_check(); +static Void_t* memalign_check(); +#ifndef NO_THREADS +static Void_t* malloc_starter(); +static void free_starter(); +static Void_t* malloc_atfork(); +static void free_atfork(); +#endif +#endif + +#endif + + + +/* sizes, alignments */ + +#define SIZE_SZ (sizeof(INTERNAL_SIZE_T)) +#define MALLOC_ALIGNMENT (SIZE_SZ + SIZE_SZ) +#define MALLOC_ALIGN_MASK (MALLOC_ALIGNMENT - 1) +#define MINSIZE (sizeof(struct malloc_chunk)) + +/* conversion from malloc headers to user pointers, and back */ + +#define chunk2mem(p) ((Void_t*)((char*)(p) + 2*SIZE_SZ)) +#define mem2chunk(mem) ((mchunkptr)((char*)(mem) - 2*SIZE_SZ)) + +/* pad request bytes into a usable size, return non-zero on overflow */ + +#define request2size(req, nb) \ + ((nb = (req) + (SIZE_SZ + MALLOC_ALIGN_MASK)),\ + ((long)nb <= 0 || nb < (INTERNAL_SIZE_T) (req) \ + ? (__set_errno (ENOMEM), 1) \ + : ((nb < (MINSIZE + MALLOC_ALIGN_MASK) \ + ? (nb = MINSIZE) : (nb &= ~MALLOC_ALIGN_MASK)), 0))) + +/* Check if m has acceptable alignment */ + +#define aligned_OK(m) (((unsigned long)((m)) & (MALLOC_ALIGN_MASK)) == 0) + + + + +/* + Physical chunk operations +*/ + + +/* size field is or'ed with PREV_INUSE when previous adjacent chunk in use */ + +#define PREV_INUSE 0x1 + +/* size field is or'ed with IS_MMAPPED if the chunk was obtained with mmap() */ + +#define IS_MMAPPED 0x2 + +/* Bits to mask off when extracting size */ + +#define SIZE_BITS (PREV_INUSE|IS_MMAPPED) + + +/* Ptr to next physical malloc_chunk. */ + +#define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->size & ~PREV_INUSE) )) + +/* Ptr to previous physical malloc_chunk */ + +#define prev_chunk(p) ((mchunkptr)( ((char*)(p)) - ((p)->prev_size) )) + + +/* Treat space at ptr + offset as a chunk */ + +#define chunk_at_offset(p, s) ((mchunkptr)(((char*)(p)) + (s))) + + + + +/* + Dealing with use bits +*/ + +/* extract p's inuse bit */ + +#define inuse(p) \ + ((((mchunkptr)(((char*)(p))+((p)->size & ~PREV_INUSE)))->size) & PREV_INUSE) + +/* extract inuse bit of previous chunk */ + +#define prev_inuse(p) ((p)->size & PREV_INUSE) + +/* check for mmap()'ed chunk */ + +#define chunk_is_mmapped(p) ((p)->size & IS_MMAPPED) + +/* set/clear chunk as in use without otherwise disturbing */ + +#define set_inuse(p) \ + ((mchunkptr)(((char*)(p)) + ((p)->size & ~PREV_INUSE)))->size |= PREV_INUSE + +#define clear_inuse(p) \ + ((mchunkptr)(((char*)(p)) + ((p)->size & ~PREV_INUSE)))->size &= ~(PREV_INUSE) + +/* check/set/clear inuse bits in known places */ + +#define inuse_bit_at_offset(p, s)\ + (((mchunkptr)(((char*)(p)) + (s)))->size & PREV_INUSE) + +#define set_inuse_bit_at_offset(p, s)\ + (((mchunkptr)(((char*)(p)) + (s)))->size |= PREV_INUSE) + +#define clear_inuse_bit_at_offset(p, s)\ + (((mchunkptr)(((char*)(p)) + (s)))->size &= ~(PREV_INUSE)) + + + + +/* + Dealing with size fields +*/ + +/* Get size, ignoring use bits */ + +#define chunksize(p) ((p)->size & ~(SIZE_BITS)) + +/* Set size at head, without disturbing its use bit */ + +#define set_head_size(p, s) ((p)->size = (((p)->size & PREV_INUSE) | (s))) + +/* Set size/use ignoring previous bits in header */ + +#define set_head(p, s) ((p)->size = (s)) + +/* Set size at footer (only when chunk is not in use) */ + +#define set_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_size = (s)) + + + + + +/* access macros */ + +#define bin_at(a, i) ((mbinptr)((char*)&(((a)->av)[2*(i) + 2]) - 2*SIZE_SZ)) +#define init_bin(a, i) ((a)->av[2*i+2] = (a)->av[2*i+3] = bin_at((a), i)) +#define next_bin(b) ((mbinptr)((char*)(b) + 2 * sizeof(mbinptr))) +#define prev_bin(b) ((mbinptr)((char*)(b) - 2 * sizeof(mbinptr))) + +/* + The first 2 bins are never indexed. The corresponding av cells are instead + used for bookkeeping. This is not to save space, but to simplify + indexing, maintain locality, and avoid some initialization tests. +*/ + +#define binblocks(a) (bin_at(a,0)->size)/* bitvector of nonempty blocks */ +#define top(a) (bin_at(a,0)->fd) /* The topmost chunk */ +#define last_remainder(a) (bin_at(a,1)) /* remainder from last split */ + +/* + Because top initially points to its own bin with initial + zero size, thus forcing extension on the first malloc request, + we avoid having any special code in malloc to check whether + it even exists yet. But we still need to in malloc_extend_top. +*/ + +#define initial_top(a) ((mchunkptr)bin_at(a, 0)) + + + +/* field-extraction macros */ + +#define first(b) ((b)->fd) +#define last(b) ((b)->bk) + +/* + Indexing into bins +*/ + +#define bin_index(sz) \ +(((((unsigned long)(sz)) >> 9) == 0) ? (((unsigned long)(sz)) >> 3):\ + ((((unsigned long)(sz)) >> 9) <= 4) ? 56 + (((unsigned long)(sz)) >> 6):\ + ((((unsigned long)(sz)) >> 9) <= 20) ? 91 + (((unsigned long)(sz)) >> 9):\ + ((((unsigned long)(sz)) >> 9) <= 84) ? 110 + (((unsigned long)(sz)) >> 12):\ + ((((unsigned long)(sz)) >> 9) <= 340) ? 119 + (((unsigned long)(sz)) >> 15):\ + ((((unsigned long)(sz)) >> 9) <= 1364) ? 124 + (((unsigned long)(sz)) >> 18):\ + 126) +/* + bins for chunks < 512 are all spaced 8 bytes apart, and hold + identically sized chunks. This is exploited in malloc. +*/ + +#define MAX_SMALLBIN 63 +#define MAX_SMALLBIN_SIZE 512 +#define SMALLBIN_WIDTH 8 + +#define smallbin_index(sz) (((unsigned long)(sz)) >> 3) + +/* + Requests are `small' if both the corresponding and the next bin are small +*/ + +#define is_small_request(nb) ((nb) < MAX_SMALLBIN_SIZE - SMALLBIN_WIDTH) + + + +/* + To help compensate for the large number of bins, a one-level index + structure is used for bin-by-bin searching. `binblocks' is a + one-word bitvector recording whether groups of BINBLOCKWIDTH bins + have any (possibly) non-empty bins, so they can be skipped over + all at once during during traversals. The bits are NOT always + cleared as soon as all bins in a block are empty, but instead only + when all are noticed to be empty during traversal in malloc. +*/ + +#define BINBLOCKWIDTH 4 /* bins per block */ + +/* bin<->block macros */ + +#define idx2binblock(ix) ((unsigned)1 << ((ix) / BINBLOCKWIDTH)) +#define mark_binblock(a, ii) (binblocks(a) |= idx2binblock(ii)) +#define clear_binblock(a, ii) (binblocks(a) &= ~(idx2binblock(ii))) + + + + +/* Static bookkeeping data */ + +/* Helper macro to initialize bins */ +#define IAV(i) bin_at(&main_arena, i), bin_at(&main_arena, i) + +static arena main_arena = { + { + 0, 0, + IAV(0), IAV(1), IAV(2), IAV(3), IAV(4), IAV(5), IAV(6), IAV(7), + IAV(8), IAV(9), IAV(10), IAV(11), IAV(12), IAV(13), IAV(14), IAV(15), + IAV(16), IAV(17), IAV(18), IAV(19), IAV(20), IAV(21), IAV(22), IAV(23), + IAV(24), IAV(25), IAV(26), IAV(27), IAV(28), IAV(29), IAV(30), IAV(31), + IAV(32), IAV(33), IAV(34), IAV(35), IAV(36), IAV(37), IAV(38), IAV(39), + IAV(40), IAV(41), IAV(42), IAV(43), IAV(44), IAV(45), IAV(46), IAV(47), + IAV(48), IAV(49), IAV(50), IAV(51), IAV(52), IAV(53), IAV(54), IAV(55), + IAV(56), IAV(57), IAV(58), IAV(59), IAV(60), IAV(61), IAV(62), IAV(63), + IAV(64), IAV(65), IAV(66), IAV(67), IAV(68), IAV(69), IAV(70), IAV(71), + IAV(72), IAV(73), IAV(74), IAV(75), IAV(76), IAV(77), IAV(78), IAV(79), + IAV(80), IAV(81), IAV(82), IAV(83), IAV(84), IAV(85), IAV(86), IAV(87), + IAV(88), IAV(89), IAV(90), IAV(91), IAV(92), IAV(93), IAV(94), IAV(95), + IAV(96), IAV(97), IAV(98), IAV(99), IAV(100), IAV(101), IAV(102), IAV(103), + IAV(104), IAV(105), IAV(106), IAV(107), IAV(108), IAV(109), IAV(110), IAV(111), + IAV(112), IAV(113), IAV(114), IAV(115), IAV(116), IAV(117), IAV(118), IAV(119), + IAV(120), IAV(121), IAV(122), IAV(123), IAV(124), IAV(125), IAV(126), IAV(127) + }, + &main_arena, /* next */ + 0, /* size */ +#if THREAD_STATS + 0, 0, 0, /* stat_lock_direct, stat_lock_loop, stat_lock_wait */ +#endif + MUTEX_INITIALIZER /* mutex */ +}; + +#undef IAV + +/* Thread specific data */ + +static tsd_key_t arena_key; +static mutex_t list_lock = MUTEX_INITIALIZER; + +#if THREAD_STATS +static int stat_n_heaps = 0; +#define THREAD_STAT(x) x +#else +#define THREAD_STAT(x) do ; while(0) +#endif + +/* variables holding tunable values */ + +static unsigned long trim_threshold = DEFAULT_TRIM_THRESHOLD; +static unsigned long top_pad = DEFAULT_TOP_PAD; +static unsigned int n_mmaps_max = DEFAULT_MMAP_MAX; +static unsigned long mmap_threshold = DEFAULT_MMAP_THRESHOLD; +static int check_action = DEFAULT_CHECK_ACTION; + +/* The first value returned from sbrk */ +static char* sbrk_base = (char*)(-1); + +/* The maximum memory obtained from system via sbrk */ +static unsigned long max_sbrked_mem = 0; + +/* The maximum via either sbrk or mmap (too difficult to track with threads) */ +#ifdef NO_THREADS +static unsigned long max_total_mem = 0; +#endif + +/* The total memory obtained from system via sbrk */ +#define sbrked_mem (main_arena.size) + +/* Tracking mmaps */ + +static unsigned int n_mmaps = 0; +static unsigned int max_n_mmaps = 0; +static unsigned long mmapped_mem = 0; +static unsigned long max_mmapped_mem = 0; + +/* Mapped memory in non-main arenas (reliable only for NO_THREADS). */ +static unsigned long arena_mem = 0; + + + +#ifndef _LIBC +#define weak_variable +#else +/* In GNU libc we want the hook variables to be weak definitions to + avoid a problem with Emacs. */ +#define weak_variable weak_function +#endif + +/* Already initialized? */ +int __malloc_initialized = -1; + + +#ifndef NO_THREADS + +/* The following two functions are registered via thread_atfork() to + make sure that the mutexes remain in a consistent state in the + fork()ed version of a thread. Also adapt the malloc and free hooks + temporarily, because the `atfork' handler mechanism may use + malloc/free internally (e.g. in LinuxThreads). */ + +#if defined _LIBC || defined MALLOC_HOOKS +static __malloc_ptr_t (*save_malloc_hook) __MALLOC_P ((size_t __size)); +static void (*save_free_hook) __MALLOC_P ((__malloc_ptr_t __ptr)); +static Void_t* save_arena; +#endif + +static void +ptmalloc_lock_all __MALLOC_P((void)) +{ + arena *ar_ptr; + + (void)mutex_lock(&list_lock); + for(ar_ptr = &main_arena;;) { + (void)mutex_lock(&ar_ptr->mutex); + ar_ptr = ar_ptr->next; + if(ar_ptr == &main_arena) break; + } +#if defined _LIBC || defined MALLOC_HOOKS + save_malloc_hook = __malloc_hook; + save_free_hook = __free_hook; + __malloc_hook = malloc_atfork; + __free_hook = free_atfork; + /* Only the current thread may perform malloc/free calls now. */ + tsd_getspecific(arena_key, save_arena); + tsd_setspecific(arena_key, (Void_t*)0); +#endif +} + +static void +ptmalloc_unlock_all __MALLOC_P((void)) +{ + arena *ar_ptr; + +#if defined _LIBC || defined MALLOC_HOOKS + tsd_setspecific(arena_key, save_arena); + __malloc_hook = save_malloc_hook; + __free_hook = save_free_hook; +#endif + for(ar_ptr = &main_arena;;) { + (void)mutex_unlock(&ar_ptr->mutex); + ar_ptr = ar_ptr->next; + if(ar_ptr == &main_arena) break; + } + (void)mutex_unlock(&list_lock); +} + +#ifdef __linux__ + +/* In LinuxThreads, unlocking a mutex in the child process after a + fork() is currently unsafe, whereas re-initializing it is safe and + does not leak resources. Therefore, a special atfork handler is + installed for the child. */ + +static void +ptmalloc_unlock_all2 __MALLOC_P((void)) +{ + arena *ar_ptr; + +#if defined _LIBC || defined MALLOC_HOOKS + tsd_setspecific(arena_key, save_arena); + __malloc_hook = save_malloc_hook; + __free_hook = save_free_hook; +#endif + for(ar_ptr = &main_arena;;) { + (void)mutex_init(&ar_ptr->mutex); + ar_ptr = ar_ptr->next; + if(ar_ptr == &main_arena) break; + } + (void)mutex_init(&list_lock); +} + +#else + +#define ptmalloc_unlock_all2 ptmalloc_unlock_all + +#endif + +#endif /* !defined NO_THREADS */ + +/* Initialization routine. */ +#if defined(_LIBC) +#if 0 +static void ptmalloc_init __MALLOC_P ((void)) __attribute__ ((constructor)); +#endif + +static void +ptmalloc_init __MALLOC_P((void)) +#else +void +ptmalloc_init __MALLOC_P((void)) +#endif +{ +#if defined _LIBC || defined MALLOC_HOOKS +# if __STD_C + const char* s; +# else + char* s; +# endif +#endif + + if(__malloc_initialized >= 0) return; + __malloc_initialized = 0; +#ifdef _LIBC + __libc_pagesize = __getpagesize(); +#endif +#ifndef NO_THREADS +#if defined _LIBC || defined MALLOC_HOOKS + /* With some threads implementations, creating thread-specific data + or initializing a mutex may call malloc() itself. Provide a + simple starter version (realloc() won't work). */ + save_malloc_hook = __malloc_hook; + save_free_hook = __free_hook; + __malloc_hook = malloc_starter; + __free_hook = free_starter; +#endif +#ifdef _LIBC + /* Initialize the pthreads interface. */ + if (__pthread_initialize != NULL) + __pthread_initialize(); +#endif +#endif /* !defined NO_THREADS */ + mutex_init(&main_arena.mutex); + mutex_init(&list_lock); + tsd_key_create(&arena_key, NULL); + tsd_setspecific(arena_key, (Void_t *)&main_arena); + thread_atfork(ptmalloc_lock_all, ptmalloc_unlock_all, ptmalloc_unlock_all2); +#if defined _LIBC || defined MALLOC_HOOKS + if((s = __secure_getenv("MALLOC_TRIM_THRESHOLD_"))) + mALLOPt(M_TRIM_THRESHOLD, atoi(s)); + if((s = __secure_getenv("MALLOC_TOP_PAD_"))) + mALLOPt(M_TOP_PAD, atoi(s)); + if((s = __secure_getenv("MALLOC_MMAP_THRESHOLD_"))) + mALLOPt(M_MMAP_THRESHOLD, atoi(s)); + if((s = __secure_getenv("MALLOC_MMAP_MAX_"))) + mALLOPt(M_MMAP_MAX, atoi(s)); + s = getenv("MALLOC_CHECK_"); +#ifndef NO_THREADS + __malloc_hook = save_malloc_hook; + __free_hook = save_free_hook; +#endif + if(s) { + if(s[0]) mALLOPt(M_CHECK_ACTION, (int)(s[0] - '0')); + __malloc_check_init(); + } + if(__malloc_initialize_hook != NULL) + (*__malloc_initialize_hook)(); +#endif + __malloc_initialized = 1; +} + +/* There are platforms (e.g. Hurd) with a link-time hook mechanism. */ +#ifdef thread_atfork_static +thread_atfork_static(ptmalloc_lock_all, ptmalloc_unlock_all, \ + ptmalloc_unlock_all2) +#endif + +#if defined _LIBC || defined MALLOC_HOOKS + +/* Hooks for debugging versions. The initial hooks just call the + initialization routine, then do the normal work. */ + +static Void_t* +#if __STD_C +malloc_hook_ini(size_t sz) +#else +malloc_hook_ini(sz) size_t sz; +#endif +{ + __malloc_hook = NULL; + ptmalloc_init(); + return mALLOc(sz); +} + +static Void_t* +#if __STD_C +realloc_hook_ini(Void_t* ptr, size_t sz) +#else +realloc_hook_ini(ptr, sz) Void_t* ptr; size_t sz; +#endif +{ + __malloc_hook = NULL; + __realloc_hook = NULL; + ptmalloc_init(); + return rEALLOc(ptr, sz); +} + +static Void_t* +#if __STD_C +memalign_hook_ini(size_t sz, size_t alignment) +#else +memalign_hook_ini(sz, alignment) size_t sz; size_t alignment; +#endif +{ + __memalign_hook = NULL; + ptmalloc_init(); + return mEMALIGn(sz, alignment); +} + +void weak_variable (*__malloc_initialize_hook) __MALLOC_P ((void)) = NULL; +void weak_variable (*__free_hook) __MALLOC_P ((__malloc_ptr_t __ptr)) = NULL; +__malloc_ptr_t weak_variable (*__malloc_hook) + __MALLOC_P ((size_t __size)) = malloc_hook_ini; +__malloc_ptr_t weak_variable (*__realloc_hook) + __MALLOC_P ((__malloc_ptr_t __ptr, size_t __size)) = realloc_hook_ini; +__malloc_ptr_t weak_variable (*__memalign_hook) + __MALLOC_P ((size_t __size, size_t __alignment)) = memalign_hook_ini; +void weak_variable (*__after_morecore_hook) __MALLOC_P ((void)) = NULL; + +/* Whether we are using malloc checking. */ +static int using_malloc_checking; + +/* A flag that is set by malloc_set_state, to signal that malloc checking + must not be enabled on the request from the user (via the MALLOC_CHECK_ + environment variable). It is reset by __malloc_check_init to tell + malloc_set_state that the user has requested malloc checking. + + The purpose of this flag is to make sure that malloc checking is not + enabled when the heap to be restored was constructed without malloc + checking, and thus does not contain the required magic bytes. + Otherwise the heap would be corrupted by calls to free and realloc. If + it turns out that the heap was created with malloc checking and the + user has requested it malloc_set_state just calls __malloc_check_init + again to enable it. On the other hand, reusing such a heap without + further malloc checking is safe. */ +static int disallow_malloc_check; + +/* Activate a standard set of debugging hooks. */ +void +__malloc_check_init() +{ + if (disallow_malloc_check) { + disallow_malloc_check = 0; + return; + } + using_malloc_checking = 1; + __malloc_hook = malloc_check; + __free_hook = free_check; + __realloc_hook = realloc_check; + __memalign_hook = memalign_check; + if(check_action & 1) + fprintf(stderr, "malloc: using debugging hooks\n"); +} + +#endif + + + + + +/* Routines dealing with mmap(). */ + +#if HAVE_MMAP + +#ifndef MAP_ANONYMOUS + +static int dev_zero_fd = -1; /* Cached file descriptor for /dev/zero. */ + +#define MMAP(addr, size, prot, flags) ((dev_zero_fd < 0) ? \ + (dev_zero_fd = open("/dev/zero", O_RDWR), \ + mmap((addr), (size), (prot), (flags), dev_zero_fd, 0)) : \ + mmap((addr), (size), (prot), (flags), dev_zero_fd, 0)) + +#else + +#define MMAP(addr, size, prot, flags) \ + (mmap((addr), (size), (prot), (flags)|MAP_ANONYMOUS, -1, 0)) + +#endif + +#if defined __GNUC__ && __GNUC__ >= 2 +/* This function is only called from one place, inline it. */ +__inline__ +#endif +static mchunkptr +internal_function +#if __STD_C +mmap_chunk(size_t size) +#else +mmap_chunk(size) size_t size; +#endif +{ + size_t page_mask = malloc_getpagesize - 1; + mchunkptr p; + + if(n_mmaps >= n_mmaps_max) return 0; /* too many regions */ + + /* For mmapped chunks, the overhead is one SIZE_SZ unit larger, because + * there is no following chunk whose prev_size field could be used. + */ + size = (size + SIZE_SZ + page_mask) & ~page_mask; + + p = (mchunkptr)MMAP(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE); + if(p == (mchunkptr) MAP_FAILED) return 0; + + n_mmaps++; + if (n_mmaps > max_n_mmaps) max_n_mmaps = n_mmaps; + + /* We demand that eight bytes into a page must be 8-byte aligned. */ + assert(aligned_OK(chunk2mem(p))); + + /* The offset to the start of the mmapped region is stored + * in the prev_size field of the chunk; normally it is zero, + * but that can be changed in memalign(). + */ + p->prev_size = 0; + set_head(p, size|IS_MMAPPED); + + mmapped_mem += size; + if ((unsigned long)mmapped_mem > (unsigned long)max_mmapped_mem) + max_mmapped_mem = mmapped_mem; +#ifdef NO_THREADS + if ((unsigned long)(mmapped_mem + arena_mem + sbrked_mem) > max_total_mem) + max_total_mem = mmapped_mem + arena_mem + sbrked_mem; +#endif + return p; +} + +static void +internal_function +#if __STD_C +munmap_chunk(mchunkptr p) +#else +munmap_chunk(p) mchunkptr p; +#endif +{ + INTERNAL_SIZE_T size = chunksize(p); + int ret; + + assert (chunk_is_mmapped(p)); + assert(! ((char*)p >= sbrk_base && (char*)p < sbrk_base + sbrked_mem)); + assert((n_mmaps > 0)); + assert(((p->prev_size + size) & (malloc_getpagesize-1)) == 0); + + n_mmaps--; + mmapped_mem -= (size + p->prev_size); + + ret = munmap((char *)p - p->prev_size, size + p->prev_size); + + /* munmap returns non-zero on failure */ + assert(ret == 0); +} + +#if HAVE_MREMAP + +static mchunkptr +internal_function +#if __STD_C +mremap_chunk(mchunkptr p, size_t new_size) +#else +mremap_chunk(p, new_size) mchunkptr p; size_t new_size; +#endif +{ + size_t page_mask = malloc_getpagesize - 1; + INTERNAL_SIZE_T offset = p->prev_size; + INTERNAL_SIZE_T size = chunksize(p); + char *cp; + + assert (chunk_is_mmapped(p)); + assert(! ((char*)p >= sbrk_base && (char*)p < sbrk_base + sbrked_mem)); + assert((n_mmaps > 0)); + assert(((size + offset) & (malloc_getpagesize-1)) == 0); + + /* Note the extra SIZE_SZ overhead as in mmap_chunk(). */ + new_size = (new_size + offset + SIZE_SZ + page_mask) & ~page_mask; + + cp = (char *)mremap((char *)p - offset, size + offset, new_size, + MREMAP_MAYMOVE); + + if (cp == MAP_FAILED) return 0; + + p = (mchunkptr)(cp + offset); + + assert(aligned_OK(chunk2mem(p))); + + assert((p->prev_size == offset)); + set_head(p, (new_size - offset)|IS_MMAPPED); + + mmapped_mem -= size + offset; + mmapped_mem += new_size; + if ((unsigned long)mmapped_mem > (unsigned long)max_mmapped_mem) + max_mmapped_mem = mmapped_mem; +#ifdef NO_THREADS + if ((unsigned long)(mmapped_mem + arena_mem + sbrked_mem) > max_total_mem) + max_total_mem = mmapped_mem + arena_mem + sbrked_mem; +#endif + return p; +} + +#endif /* HAVE_MREMAP */ + +#endif /* HAVE_MMAP */ + + + +/* Managing heaps and arenas (for concurrent threads) */ + +#if USE_ARENAS + +/* Create a new heap. size is automatically rounded up to a multiple + of the page size. */ + +static heap_info * +internal_function +#if __STD_C +new_heap(size_t size) +#else +new_heap(size) size_t size; +#endif +{ + size_t page_mask = malloc_getpagesize - 1; + char *p1, *p2; + unsigned long ul; + heap_info *h; + + if(size+top_pad < HEAP_MIN_SIZE) + size = HEAP_MIN_SIZE; + else if(size+top_pad <= HEAP_MAX_SIZE) + size += top_pad; + else if(size > HEAP_MAX_SIZE) + return 0; + else + size = HEAP_MAX_SIZE; + size = (size + page_mask) & ~page_mask; + + /* A memory region aligned to a multiple of HEAP_MAX_SIZE is needed. + No swap space needs to be reserved for the following large + mapping (on Linux, this is the case for all non-writable mappings + anyway). */ + p1 = (char *)MMAP(0, HEAP_MAX_SIZE<<1, PROT_NONE, MAP_PRIVATE|MAP_NORESERVE); + if(p1 == MAP_FAILED) + return 0; + p2 = (char *)(((unsigned long)p1 + HEAP_MAX_SIZE) & ~(HEAP_MAX_SIZE-1)); + ul = p2 - p1; + munmap(p1, ul); + munmap(p2 + HEAP_MAX_SIZE, HEAP_MAX_SIZE - ul); + if(mprotect(p2, size, PROT_READ|PROT_WRITE) != 0) { + munmap(p2, HEAP_MAX_SIZE); + return 0; + } + h = (heap_info *)p2; + h->size = size; + THREAD_STAT(stat_n_heaps++); + return h; +} + +/* Grow or shrink a heap. size is automatically rounded up to a + multiple of the page size if it is positive. */ + +static int +#if __STD_C +grow_heap(heap_info *h, long diff) +#else +grow_heap(h, diff) heap_info *h; long diff; +#endif +{ + size_t page_mask = malloc_getpagesize - 1; + long new_size; + + if(diff >= 0) { + diff = (diff + page_mask) & ~page_mask; + new_size = (long)h->size + diff; + if(new_size > HEAP_MAX_SIZE) + return -1; + if(mprotect((char *)h + h->size, diff, PROT_READ|PROT_WRITE) != 0) + return -2; + } else { + new_size = (long)h->size + diff; + if(new_size < (long)sizeof(*h)) + return -1; + /* Try to re-map the extra heap space freshly to save memory, and + make it inaccessible. */ + if((char *)MMAP((char *)h + new_size, -diff, PROT_NONE, + MAP_PRIVATE|MAP_FIXED) == (char *) MAP_FAILED) + return -2; + } + h->size = new_size; + return 0; +} + +/* Delete a heap. */ + +#define delete_heap(heap) munmap((char*)(heap), HEAP_MAX_SIZE) + +/* arena_get() acquires an arena and locks the corresponding mutex. + First, try the one last locked successfully by this thread. (This + is the common case and handled with a macro for speed.) Then, loop + once over the circularly linked list of arenas. If no arena is + readily available, create a new one. In this latter case, `size' + is just a hint as to how much memory will be required immediately + in the new arena. */ + +#define arena_get(ptr, size) do { \ + Void_t *vptr = NULL; \ + ptr = (arena *)tsd_getspecific(arena_key, vptr); \ + if(ptr && !mutex_trylock(&ptr->mutex)) { \ + THREAD_STAT(++(ptr->stat_lock_direct)); \ + } else \ + ptr = arena_get2(ptr, (size)); \ +} while(0) + +static arena * +internal_function +#if __STD_C +arena_get2(arena *a_tsd, size_t size) +#else +arena_get2(a_tsd, size) arena *a_tsd; size_t size; +#endif +{ + arena *a; + heap_info *h; + char *ptr; + int i; + unsigned long misalign; + + if(!a_tsd) + a = a_tsd = &main_arena; + else { + a = a_tsd->next; + if(!a) { + /* This can only happen while initializing the new arena. */ + (void)mutex_lock(&main_arena.mutex); + THREAD_STAT(++(main_arena.stat_lock_wait)); + return &main_arena; + } + } + + /* Check the global, circularly linked list for available arenas. */ + repeat: + do { + if(!mutex_trylock(&a->mutex)) { + THREAD_STAT(++(a->stat_lock_loop)); + tsd_setspecific(arena_key, (Void_t *)a); + return a; + } + a = a->next; + } while(a != a_tsd); + + /* If not even the list_lock can be obtained, try again. This can + happen during `atfork', or for example on systems where thread + creation makes it temporarily impossible to obtain _any_ + locks. */ + if(mutex_trylock(&list_lock)) { + a = a_tsd; + goto repeat; + } + (void)mutex_unlock(&list_lock); + + /* Nothing immediately available, so generate a new arena. */ + h = new_heap(size + (sizeof(*h) + sizeof(*a) + MALLOC_ALIGNMENT)); + if(!h) { + /* Maybe size is too large to fit in a single heap. So, just try + to create a minimally-sized arena and let chunk_alloc() attempt + to deal with the large request via mmap_chunk(). */ + h = new_heap(sizeof(*h) + sizeof(*a) + MALLOC_ALIGNMENT); + if(!h) + return 0; + } + a = h->ar_ptr = (arena *)(h+1); + for(i=0; inext = NULL; + a->size = h->size; + arena_mem += h->size; +#ifdef NO_THREADS + if((unsigned long)(mmapped_mem + arena_mem + sbrked_mem) > max_total_mem) + max_total_mem = mmapped_mem + arena_mem + sbrked_mem; +#endif + tsd_setspecific(arena_key, (Void_t *)a); + mutex_init(&a->mutex); + i = mutex_lock(&a->mutex); /* remember result */ + + /* Set up the top chunk, with proper alignment. */ + ptr = (char *)(a + 1); + misalign = (unsigned long)chunk2mem(ptr) & MALLOC_ALIGN_MASK; + if (misalign > 0) + ptr += MALLOC_ALIGNMENT - misalign; + top(a) = (mchunkptr)ptr; + set_head(top(a), (((char*)h + h->size) - ptr) | PREV_INUSE); + + /* Add the new arena to the list. */ + (void)mutex_lock(&list_lock); + a->next = main_arena.next; + main_arena.next = a; + (void)mutex_unlock(&list_lock); + + if(i) /* locking failed; keep arena for further attempts later */ + return 0; + + THREAD_STAT(++(a->stat_lock_loop)); + return a; +} + +/* find the heap and corresponding arena for a given ptr */ + +#define heap_for_ptr(ptr) \ + ((heap_info *)((unsigned long)(ptr) & ~(HEAP_MAX_SIZE-1))) +#define arena_for_ptr(ptr) \ + (((mchunkptr)(ptr) < top(&main_arena) && (char *)(ptr) >= sbrk_base) ? \ + &main_arena : heap_for_ptr(ptr)->ar_ptr) + +#else /* !USE_ARENAS */ + +/* There is only one arena, main_arena. */ + +#define arena_get(ptr, sz) (ptr = &main_arena) +#define arena_for_ptr(ptr) (&main_arena) + +#endif /* USE_ARENAS */ + + + +/* + Debugging support +*/ + +#if MALLOC_DEBUG + + +/* + These routines make a number of assertions about the states + of data structures that should be true at all times. If any + are not true, it's very likely that a user program has somehow + trashed memory. (It's also possible that there is a coding error + in malloc. In which case, please report it!) +*/ + +#if __STD_C +static void do_check_chunk(arena *ar_ptr, mchunkptr p) +#else +static void do_check_chunk(ar_ptr, p) arena *ar_ptr; mchunkptr p; +#endif +{ + INTERNAL_SIZE_T sz = p->size & ~PREV_INUSE; + + /* No checkable chunk is mmapped */ + assert(!chunk_is_mmapped(p)); + +#if USE_ARENAS + if(ar_ptr != &main_arena) { + heap_info *heap = heap_for_ptr(p); + assert(heap->ar_ptr == ar_ptr); + if(p != top(ar_ptr)) + assert((char *)p + sz <= (char *)heap + heap->size); + else + assert((char *)p + sz == (char *)heap + heap->size); + return; + } +#endif + + /* Check for legal address ... */ + assert((char*)p >= sbrk_base); + if (p != top(ar_ptr)) + assert((char*)p + sz <= (char*)top(ar_ptr)); + else + assert((char*)p + sz <= sbrk_base + sbrked_mem); + +} + + +#if __STD_C +static void do_check_free_chunk(arena *ar_ptr, mchunkptr p) +#else +static void do_check_free_chunk(ar_ptr, p) arena *ar_ptr; mchunkptr p; +#endif +{ + INTERNAL_SIZE_T sz = p->size & ~PREV_INUSE; + mchunkptr next = chunk_at_offset(p, sz); + + do_check_chunk(ar_ptr, p); + + /* Check whether it claims to be free ... */ + assert(!inuse(p)); + + /* Must have OK size and fields */ + assert((long)sz >= (long)MINSIZE); + assert((sz & MALLOC_ALIGN_MASK) == 0); + assert(aligned_OK(chunk2mem(p))); + /* ... matching footer field */ + assert(next->prev_size == sz); + /* ... and is fully consolidated */ + assert(prev_inuse(p)); + assert (next == top(ar_ptr) || inuse(next)); + + /* ... and has minimally sane links */ + assert(p->fd->bk == p); + assert(p->bk->fd == p); +} + +#if __STD_C +static void do_check_inuse_chunk(arena *ar_ptr, mchunkptr p) +#else +static void do_check_inuse_chunk(ar_ptr, p) arena *ar_ptr; mchunkptr p; +#endif +{ + mchunkptr next = next_chunk(p); + do_check_chunk(ar_ptr, p); + + /* Check whether it claims to be in use ... */ + assert(inuse(p)); + + /* ... whether its size is OK (it might be a fencepost) ... */ + assert(chunksize(p) >= MINSIZE || next->size == (0|PREV_INUSE)); + + /* ... and is surrounded by OK chunks. + Since more things can be checked with free chunks than inuse ones, + if an inuse chunk borders them and debug is on, it's worth doing them. + */ + if (!prev_inuse(p)) + { + mchunkptr prv = prev_chunk(p); + assert(next_chunk(prv) == p); + do_check_free_chunk(ar_ptr, prv); + } + if (next == top(ar_ptr)) + { + assert(prev_inuse(next)); + assert(chunksize(next) >= MINSIZE); + } + else if (!inuse(next)) + do_check_free_chunk(ar_ptr, next); + +} + +#if __STD_C +static void do_check_malloced_chunk(arena *ar_ptr, + mchunkptr p, INTERNAL_SIZE_T s) +#else +static void do_check_malloced_chunk(ar_ptr, p, s) +arena *ar_ptr; mchunkptr p; INTERNAL_SIZE_T s; +#endif +{ + INTERNAL_SIZE_T sz = p->size & ~PREV_INUSE; + long room = sz - s; + + do_check_inuse_chunk(ar_ptr, p); + + /* Legal size ... */ + assert((long)sz >= (long)MINSIZE); + assert((sz & MALLOC_ALIGN_MASK) == 0); + assert(room >= 0); + assert(room < (long)MINSIZE); + + /* ... and alignment */ + assert(aligned_OK(chunk2mem(p))); + + + /* ... and was allocated at front of an available chunk */ + assert(prev_inuse(p)); + +} + + +#define check_free_chunk(A,P) do_check_free_chunk(A,P) +#define check_inuse_chunk(A,P) do_check_inuse_chunk(A,P) +#define check_chunk(A,P) do_check_chunk(A,P) +#define check_malloced_chunk(A,P,N) do_check_malloced_chunk(A,P,N) +#else +#define check_free_chunk(A,P) +#define check_inuse_chunk(A,P) +#define check_chunk(A,P) +#define check_malloced_chunk(A,P,N) +#endif + + + +/* + Macro-based internal utilities +*/ + + +/* + Linking chunks in bin lists. + Call these only with variables, not arbitrary expressions, as arguments. +*/ + +/* + Place chunk p of size s in its bin, in size order, + putting it ahead of others of same size. +*/ + + +#define frontlink(A, P, S, IDX, BK, FD) \ +{ \ + if (S < MAX_SMALLBIN_SIZE) \ + { \ + IDX = smallbin_index(S); \ + mark_binblock(A, IDX); \ + BK = bin_at(A, IDX); \ + FD = BK->fd; \ + P->bk = BK; \ + P->fd = FD; \ + FD->bk = BK->fd = P; \ + } \ + else \ + { \ + IDX = bin_index(S); \ + BK = bin_at(A, IDX); \ + FD = BK->fd; \ + if (FD == BK) mark_binblock(A, IDX); \ + else \ + { \ + while (FD != BK && S < chunksize(FD)) FD = FD->fd; \ + BK = FD->bk; \ + } \ + P->bk = BK; \ + P->fd = FD; \ + FD->bk = BK->fd = P; \ + } \ +} + + +/* take a chunk off a list */ + +#define unlink(P, BK, FD) \ +{ \ + BK = P->bk; \ + FD = P->fd; \ + FD->bk = BK; \ + BK->fd = FD; \ +} \ + +/* Place p as the last remainder */ + +#define link_last_remainder(A, P) \ +{ \ + last_remainder(A)->fd = last_remainder(A)->bk = P; \ + P->fd = P->bk = last_remainder(A); \ +} + +/* Clear the last_remainder bin */ + +#define clear_last_remainder(A) \ + (last_remainder(A)->fd = last_remainder(A)->bk = last_remainder(A)) + + + + + +/* + Extend the top-most chunk by obtaining memory from system. + Main interface to sbrk (but see also malloc_trim). +*/ + +#if defined __GNUC__ && __GNUC__ >= 2 +/* This function is called only from one place, inline it. */ +__inline__ +#endif +static void +internal_function +#if __STD_C +malloc_extend_top(arena *ar_ptr, INTERNAL_SIZE_T nb) +#else +malloc_extend_top(ar_ptr, nb) arena *ar_ptr; INTERNAL_SIZE_T nb; +#endif +{ + unsigned long pagesz = malloc_getpagesize; + mchunkptr old_top = top(ar_ptr); /* Record state of old top */ + INTERNAL_SIZE_T old_top_size = chunksize(old_top); + INTERNAL_SIZE_T top_size; /* new size of top chunk */ + +#if USE_ARENAS + if(ar_ptr == &main_arena) { +#endif + + char* brk; /* return value from sbrk */ + INTERNAL_SIZE_T front_misalign; /* unusable bytes at front of sbrked space */ + INTERNAL_SIZE_T correction; /* bytes for 2nd sbrk call */ + char* new_brk; /* return of 2nd sbrk call */ + char* old_end = (char*)(chunk_at_offset(old_top, old_top_size)); + + /* Pad request with top_pad plus minimal overhead */ + INTERNAL_SIZE_T sbrk_size = nb + top_pad + MINSIZE; + + /* If not the first time through, round to preserve page boundary */ + /* Otherwise, we need to correct to a page size below anyway. */ + /* (We also correct below if an intervening foreign sbrk call.) */ + + if (sbrk_base != (char*)(-1)) + sbrk_size = (sbrk_size + (pagesz - 1)) & ~(pagesz - 1); + + brk = (char*)(MORECORE (sbrk_size)); + + /* Fail if sbrk failed or if a foreign sbrk call killed our space */ + if (brk == (char*)(MORECORE_FAILURE) || + (brk < old_end && old_top != initial_top(&main_arena))) + return; + +#if defined _LIBC || defined MALLOC_HOOKS + /* Call the `morecore' hook if necessary. */ + if (__after_morecore_hook) + (*__after_morecore_hook) (); +#endif + + sbrked_mem += sbrk_size; + + if (brk == old_end) { /* can just add bytes to current top */ + top_size = sbrk_size + old_top_size; + set_head(old_top, top_size | PREV_INUSE); + old_top = 0; /* don't free below */ + } else { + if (sbrk_base == (char*)(-1)) /* First time through. Record base */ + sbrk_base = brk; + else + /* Someone else called sbrk(). Count those bytes as sbrked_mem. */ + sbrked_mem += brk - (char*)old_end; + + /* Guarantee alignment of first new chunk made from this space */ + front_misalign = (unsigned long)chunk2mem(brk) & MALLOC_ALIGN_MASK; + if (front_misalign > 0) { + correction = (MALLOC_ALIGNMENT) - front_misalign; + brk += correction; + } else + correction = 0; + + /* Guarantee the next brk will be at a page boundary */ + correction += pagesz - ((unsigned long)(brk + sbrk_size) & (pagesz - 1)); + + /* Allocate correction */ + new_brk = (char*)(MORECORE (correction)); + if (new_brk == (char*)(MORECORE_FAILURE)) return; + +#if defined _LIBC || defined MALLOC_HOOKS + /* Call the `morecore' hook if necessary. */ + if (__after_morecore_hook) + (*__after_morecore_hook) (); +#endif + + sbrked_mem += correction; + + top(&main_arena) = (mchunkptr)brk; + top_size = new_brk - brk + correction; + set_head(top(&main_arena), top_size | PREV_INUSE); + + if (old_top == initial_top(&main_arena)) + old_top = 0; /* don't free below */ + } + + if ((unsigned long)sbrked_mem > (unsigned long)max_sbrked_mem) + max_sbrked_mem = sbrked_mem; +#ifdef NO_THREADS + if ((unsigned long)(mmapped_mem + arena_mem + sbrked_mem) > max_total_mem) + max_total_mem = mmapped_mem + arena_mem + sbrked_mem; +#endif + +#if USE_ARENAS + } else { /* ar_ptr != &main_arena */ + heap_info *old_heap, *heap; + size_t old_heap_size; + + if(old_top_size < MINSIZE) /* this should never happen */ + return; + + /* First try to extend the current heap. */ + if(MINSIZE + nb <= old_top_size) + return; + old_heap = heap_for_ptr(old_top); + old_heap_size = old_heap->size; + if(grow_heap(old_heap, MINSIZE + nb - old_top_size) == 0) { + ar_ptr->size += old_heap->size - old_heap_size; + arena_mem += old_heap->size - old_heap_size; +#ifdef NO_THREADS + if(mmapped_mem + arena_mem + sbrked_mem > max_total_mem) + max_total_mem = mmapped_mem + arena_mem + sbrked_mem; +#endif + top_size = ((char *)old_heap + old_heap->size) - (char *)old_top; + set_head(old_top, top_size | PREV_INUSE); + return; + } + + /* A new heap must be created. */ + heap = new_heap(nb + (MINSIZE + sizeof(*heap))); + if(!heap) + return; + heap->ar_ptr = ar_ptr; + heap->prev = old_heap; + ar_ptr->size += heap->size; + arena_mem += heap->size; +#ifdef NO_THREADS + if((unsigned long)(mmapped_mem + arena_mem + sbrked_mem) > max_total_mem) + max_total_mem = mmapped_mem + arena_mem + sbrked_mem; +#endif + + /* Set up the new top, so we can safely use chunk_free() below. */ + top(ar_ptr) = chunk_at_offset(heap, sizeof(*heap)); + top_size = heap->size - sizeof(*heap); + set_head(top(ar_ptr), top_size | PREV_INUSE); + } +#endif /* USE_ARENAS */ + + /* We always land on a page boundary */ + assert(((unsigned long)((char*)top(ar_ptr) + top_size) & (pagesz-1)) == 0); + + /* Setup fencepost and free the old top chunk. */ + if(old_top) { + /* The fencepost takes at least MINSIZE bytes, because it might + become the top chunk again later. Note that a footer is set + up, too, although the chunk is marked in use. */ + old_top_size -= MINSIZE; + set_head(chunk_at_offset(old_top, old_top_size + 2*SIZE_SZ), 0|PREV_INUSE); + if(old_top_size >= MINSIZE) { + set_head(chunk_at_offset(old_top, old_top_size), (2*SIZE_SZ)|PREV_INUSE); + set_foot(chunk_at_offset(old_top, old_top_size), (2*SIZE_SZ)); + set_head_size(old_top, old_top_size); + chunk_free(ar_ptr, old_top); + } else { + set_head(old_top, (old_top_size + 2*SIZE_SZ)|PREV_INUSE); + set_foot(old_top, (old_top_size + 2*SIZE_SZ)); + } + } +} + + + + +/* Main public routines */ + + +/* + Malloc Algorithm: + + The requested size is first converted into a usable form, `nb'. + This currently means to add 4 bytes overhead plus possibly more to + obtain 8-byte alignment and/or to obtain a size of at least + MINSIZE (currently 16, 24, or 32 bytes), the smallest allocatable + size. (All fits are considered `exact' if they are within MINSIZE + bytes.) + + From there, the first successful of the following steps is taken: + + 1. The bin corresponding to the request size is scanned, and if + a chunk of exactly the right size is found, it is taken. + + 2. The most recently remaindered chunk is used if it is big + enough. This is a form of (roving) first fit, used only in + the absence of exact fits. Runs of consecutive requests use + the remainder of the chunk used for the previous such request + whenever possible. This limited use of a first-fit style + allocation strategy tends to give contiguous chunks + coextensive lifetimes, which improves locality and can reduce + fragmentation in the long run. + + 3. Other bins are scanned in increasing size order, using a + chunk big enough to fulfill the request, and splitting off + any remainder. This search is strictly by best-fit; i.e., + the smallest (with ties going to approximately the least + recently used) chunk that fits is selected. + + 4. If large enough, the chunk bordering the end of memory + (`top') is split off. (This use of `top' is in accord with + the best-fit search rule. In effect, `top' is treated as + larger (and thus less well fitting) than any other available + chunk since it can be extended to be as large as necessary + (up to system limitations). + + 5. If the request size meets the mmap threshold and the + system supports mmap, and there are few enough currently + allocated mmapped regions, and a call to mmap succeeds, + the request is allocated via direct memory mapping. + + 6. Otherwise, the top of memory is extended by + obtaining more space from the system (normally using sbrk, + but definable to anything else via the MORECORE macro). + Memory is gathered from the system (in system page-sized + units) in a way that allows chunks obtained across different + sbrk calls to be consolidated, but does not require + contiguous memory. Thus, it should be safe to intersperse + mallocs with other sbrk calls. + + + All allocations are made from the `lowest' part of any found + chunk. (The implementation invariant is that prev_inuse is + always true of any allocated chunk; i.e., that each allocated + chunk borders either a previously allocated and still in-use chunk, + or the base of its memory arena.) + +*/ + +#if __STD_C +Void_t* mALLOc(size_t bytes) +#else +Void_t* mALLOc(bytes) size_t bytes; +#endif +{ + arena *ar_ptr; + INTERNAL_SIZE_T nb; /* padded request size */ + mchunkptr victim; + +#if defined _LIBC || defined MALLOC_HOOKS + if (__malloc_hook != NULL) { + Void_t* result; + + result = (*__malloc_hook)(bytes); + return result; + } +#endif + + if(request2size(bytes, nb)) + return 0; + arena_get(ar_ptr, nb); + if(!ar_ptr) + return 0; + victim = chunk_alloc(ar_ptr, nb); + if(!victim) { + /* Maybe the failure is due to running out of mmapped areas. */ + if(ar_ptr != &main_arena) { + (void)mutex_unlock(&ar_ptr->mutex); + (void)mutex_lock(&main_arena.mutex); + victim = chunk_alloc(&main_arena, nb); + (void)mutex_unlock(&main_arena.mutex); + } else { +#if USE_ARENAS + /* ... or sbrk() has failed and there is still a chance to mmap() */ + ar_ptr = arena_get2(ar_ptr->next ? ar_ptr : 0, nb); + (void)mutex_unlock(&main_arena.mutex); + if(ar_ptr) { + victim = chunk_alloc(ar_ptr, nb); + (void)mutex_unlock(&ar_ptr->mutex); + } +#endif + } + if(!victim) return 0; + } else + (void)mutex_unlock(&ar_ptr->mutex); + return chunk2mem(victim); +} + +static mchunkptr +internal_function +#if __STD_C +chunk_alloc(arena *ar_ptr, INTERNAL_SIZE_T nb) +#else +chunk_alloc(ar_ptr, nb) arena *ar_ptr; INTERNAL_SIZE_T nb; +#endif +{ + mchunkptr victim; /* inspected/selected chunk */ + INTERNAL_SIZE_T victim_size; /* its size */ + int idx; /* index for bin traversal */ + mbinptr bin; /* associated bin */ + mchunkptr remainder; /* remainder from a split */ + long remainder_size; /* its size */ + int remainder_index; /* its bin index */ + unsigned long block; /* block traverser bit */ + int startidx; /* first bin of a traversed block */ + mchunkptr fwd; /* misc temp for linking */ + mchunkptr bck; /* misc temp for linking */ + mbinptr q; /* misc temp */ + + + /* Check for exact match in a bin */ + + if (is_small_request(nb)) /* Faster version for small requests */ + { + idx = smallbin_index(nb); + + /* No traversal or size check necessary for small bins. */ + + q = bin_at(ar_ptr, idx); + victim = last(q); + + /* Also scan the next one, since it would have a remainder < MINSIZE */ + if (victim == q) + { + q = next_bin(q); + victim = last(q); + } + if (victim != q) + { + victim_size = chunksize(victim); + unlink(victim, bck, fwd); + set_inuse_bit_at_offset(victim, victim_size); + check_malloced_chunk(ar_ptr, victim, nb); + return victim; + } + + idx += 2; /* Set for bin scan below. We've already scanned 2 bins. */ + + } + else + { + idx = bin_index(nb); + bin = bin_at(ar_ptr, idx); + + for (victim = last(bin); victim != bin; victim = victim->bk) + { + victim_size = chunksize(victim); + remainder_size = victim_size - nb; + + if (remainder_size >= (long)MINSIZE) /* too big */ + { + --idx; /* adjust to rescan below after checking last remainder */ + break; + } + + else if (remainder_size >= 0) /* exact fit */ + { + unlink(victim, bck, fwd); + set_inuse_bit_at_offset(victim, victim_size); + check_malloced_chunk(ar_ptr, victim, nb); + return victim; + } + } + + ++idx; + + } + + /* Try to use the last split-off remainder */ + + if ( (victim = last_remainder(ar_ptr)->fd) != last_remainder(ar_ptr)) + { + victim_size = chunksize(victim); + remainder_size = victim_size - nb; + + if (remainder_size >= (long)MINSIZE) /* re-split */ + { + remainder = chunk_at_offset(victim, nb); + set_head(victim, nb | PREV_INUSE); + link_last_remainder(ar_ptr, remainder); + set_head(remainder, remainder_size | PREV_INUSE); + set_foot(remainder, remainder_size); + check_malloced_chunk(ar_ptr, victim, nb); + return victim; + } + + clear_last_remainder(ar_ptr); + + if (remainder_size >= 0) /* exhaust */ + { + set_inuse_bit_at_offset(victim, victim_size); + check_malloced_chunk(ar_ptr, victim, nb); + return victim; + } + + /* Else place in bin */ + + frontlink(ar_ptr, victim, victim_size, remainder_index, bck, fwd); + } + + /* + If there are any possibly nonempty big-enough blocks, + search for best fitting chunk by scanning bins in blockwidth units. + */ + + if ( (block = idx2binblock(idx)) <= binblocks(ar_ptr)) + { + + /* Get to the first marked block */ + + if ( (block & binblocks(ar_ptr)) == 0) + { + /* force to an even block boundary */ + idx = (idx & ~(BINBLOCKWIDTH - 1)) + BINBLOCKWIDTH; + block <<= 1; + while ((block & binblocks(ar_ptr)) == 0) + { + idx += BINBLOCKWIDTH; + block <<= 1; + } + } + + /* For each possibly nonempty block ... */ + for (;;) + { + startidx = idx; /* (track incomplete blocks) */ + q = bin = bin_at(ar_ptr, idx); + + /* For each bin in this block ... */ + do + { + /* Find and use first big enough chunk ... */ + + for (victim = last(bin); victim != bin; victim = victim->bk) + { + victim_size = chunksize(victim); + remainder_size = victim_size - nb; + + if (remainder_size >= (long)MINSIZE) /* split */ + { + remainder = chunk_at_offset(victim, nb); + set_head(victim, nb | PREV_INUSE); + unlink(victim, bck, fwd); + link_last_remainder(ar_ptr, remainder); + set_head(remainder, remainder_size | PREV_INUSE); + set_foot(remainder, remainder_size); + check_malloced_chunk(ar_ptr, victim, nb); + return victim; + } + + else if (remainder_size >= 0) /* take */ + { + set_inuse_bit_at_offset(victim, victim_size); + unlink(victim, bck, fwd); + check_malloced_chunk(ar_ptr, victim, nb); + return victim; + } + + } + + bin = next_bin(bin); + + } while ((++idx & (BINBLOCKWIDTH - 1)) != 0); + + /* Clear out the block bit. */ + + do /* Possibly backtrack to try to clear a partial block */ + { + if ((startidx & (BINBLOCKWIDTH - 1)) == 0) + { + binblocks(ar_ptr) &= ~block; + break; + } + --startidx; + q = prev_bin(q); + } while (first(q) == q); + + /* Get to the next possibly nonempty block */ + + if ( (block <<= 1) <= binblocks(ar_ptr) && (block != 0) ) + { + while ((block & binblocks(ar_ptr)) == 0) + { + idx += BINBLOCKWIDTH; + block <<= 1; + } + } + else + break; + } + } + + + /* Try to use top chunk */ + + /* Require that there be a remainder, ensuring top always exists */ + if ( (remainder_size = chunksize(top(ar_ptr)) - nb) < (long)MINSIZE) + { + +#if HAVE_MMAP + /* If big and would otherwise need to extend, try to use mmap instead */ + if ((unsigned long)nb >= (unsigned long)mmap_threshold && + (victim = mmap_chunk(nb)) != 0) + return victim; +#endif + + /* Try to extend */ + malloc_extend_top(ar_ptr, nb); + if ((remainder_size = chunksize(top(ar_ptr)) - nb) < (long)MINSIZE) + return 0; /* propagate failure */ + } + + victim = top(ar_ptr); + set_head(victim, nb | PREV_INUSE); + top(ar_ptr) = chunk_at_offset(victim, nb); + set_head(top(ar_ptr), remainder_size | PREV_INUSE); + check_malloced_chunk(ar_ptr, victim, nb); + return victim; + +} + + + + +/* + + free() algorithm : + + cases: + + 1. free(0) has no effect. + + 2. If the chunk was allocated via mmap, it is released via munmap(). + + 3. If a returned chunk borders the current high end of memory, + it is consolidated into the top, and if the total unused + topmost memory exceeds the trim threshold, malloc_trim is + called. + + 4. Other chunks are consolidated as they arrive, and + placed in corresponding bins. (This includes the case of + consolidating with the current `last_remainder'). + +*/ + + +#if __STD_C +void fREe(Void_t* mem) +#else +void fREe(mem) Void_t* mem; +#endif +{ + arena *ar_ptr; + mchunkptr p; /* chunk corresponding to mem */ + +#if defined _LIBC || defined MALLOC_HOOKS + if (__free_hook != NULL) { + (*__free_hook)(mem); + return; + } +#endif + + if (mem == 0) /* free(0) has no effect */ + return; + + p = mem2chunk(mem); + +#if HAVE_MMAP + if (chunk_is_mmapped(p)) /* release mmapped memory. */ + { + munmap_chunk(p); + return; + } +#endif + + ar_ptr = arena_for_ptr(p); +#if THREAD_STATS + if(!mutex_trylock(&ar_ptr->mutex)) + ++(ar_ptr->stat_lock_direct); + else { + (void)mutex_lock(&ar_ptr->mutex); + ++(ar_ptr->stat_lock_wait); + } +#else + (void)mutex_lock(&ar_ptr->mutex); +#endif + chunk_free(ar_ptr, p); + (void)mutex_unlock(&ar_ptr->mutex); +} + +static void +internal_function +#if __STD_C +chunk_free(arena *ar_ptr, mchunkptr p) +#else +chunk_free(ar_ptr, p) arena *ar_ptr; mchunkptr p; +#endif +{ + INTERNAL_SIZE_T hd = p->size; /* its head field */ + INTERNAL_SIZE_T sz; /* its size */ + int idx; /* its bin index */ + mchunkptr next; /* next contiguous chunk */ + INTERNAL_SIZE_T nextsz; /* its size */ + INTERNAL_SIZE_T prevsz; /* size of previous contiguous chunk */ + mchunkptr bck; /* misc temp for linking */ + mchunkptr fwd; /* misc temp for linking */ + int islr; /* track whether merging with last_remainder */ + + check_inuse_chunk(ar_ptr, p); + + sz = hd & ~PREV_INUSE; + next = chunk_at_offset(p, sz); + nextsz = chunksize(next); + + if (next == top(ar_ptr)) /* merge with top */ + { + sz += nextsz; + + if (!(hd & PREV_INUSE)) /* consolidate backward */ + { + prevsz = p->prev_size; + p = chunk_at_offset(p, -(long)prevsz); + sz += prevsz; + unlink(p, bck, fwd); + } + + set_head(p, sz | PREV_INUSE); + top(ar_ptr) = p; + +#if USE_ARENAS + if(ar_ptr == &main_arena) { +#endif + if ((unsigned long)(sz) >= (unsigned long)trim_threshold) + main_trim(top_pad); +#if USE_ARENAS + } else { + heap_info *heap = heap_for_ptr(p); + + assert(heap->ar_ptr == ar_ptr); + + /* Try to get rid of completely empty heaps, if possible. */ + if((unsigned long)(sz) >= (unsigned long)trim_threshold || + p == chunk_at_offset(heap, sizeof(*heap))) + heap_trim(heap, top_pad); + } +#endif + return; + } + + islr = 0; + + if (!(hd & PREV_INUSE)) /* consolidate backward */ + { + prevsz = p->prev_size; + p = chunk_at_offset(p, -(long)prevsz); + sz += prevsz; + + if (p->fd == last_remainder(ar_ptr)) /* keep as last_remainder */ + islr = 1; + else + unlink(p, bck, fwd); + } + + if (!(inuse_bit_at_offset(next, nextsz))) /* consolidate forward */ + { + sz += nextsz; + + if (!islr && next->fd == last_remainder(ar_ptr)) + /* re-insert last_remainder */ + { + islr = 1; + link_last_remainder(ar_ptr, p); + } + else + unlink(next, bck, fwd); + + next = chunk_at_offset(p, sz); + } + else + set_head(next, nextsz); /* clear inuse bit */ + + set_head(p, sz | PREV_INUSE); + next->prev_size = sz; + if (!islr) + frontlink(ar_ptr, p, sz, idx, bck, fwd); + +#if USE_ARENAS + /* Check whether the heap containing top can go away now. */ + if(next->size < MINSIZE && + (unsigned long)sz > trim_threshold && + ar_ptr != &main_arena) { /* fencepost */ + heap_info *heap = heap_for_ptr(top(ar_ptr)); + + if(top(ar_ptr) == chunk_at_offset(heap, sizeof(*heap)) && + heap->prev == heap_for_ptr(p)) + heap_trim(heap, top_pad); + } +#endif +} + + + + + +/* + + Realloc algorithm: + + Chunks that were obtained via mmap cannot be extended or shrunk + unless HAVE_MREMAP is defined, in which case mremap is used. + Otherwise, if their reallocation is for additional space, they are + copied. If for less, they are just left alone. + + Otherwise, if the reallocation is for additional space, and the + chunk can be extended, it is, else a malloc-copy-free sequence is + taken. There are several different ways that a chunk could be + extended. All are tried: + + * Extending forward into following adjacent free chunk. + * Shifting backwards, joining preceding adjacent space + * Both shifting backwards and extending forward. + * Extending into newly sbrked space + + Unless the #define REALLOC_ZERO_BYTES_FREES is set, realloc with a + size argument of zero (re)allocates a minimum-sized chunk. + + If the reallocation is for less space, and the new request is for + a `small' (<512 bytes) size, then the newly unused space is lopped + off and freed. + + The old unix realloc convention of allowing the last-free'd chunk + to be used as an argument to realloc is no longer supported. + I don't know of any programs still relying on this feature, + and allowing it would also allow too many other incorrect + usages of realloc to be sensible. + + +*/ + + +#if __STD_C +Void_t* rEALLOc(Void_t* oldmem, size_t bytes) +#else +Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes; +#endif +{ + arena *ar_ptr; + INTERNAL_SIZE_T nb; /* padded request size */ + + mchunkptr oldp; /* chunk corresponding to oldmem */ + INTERNAL_SIZE_T oldsize; /* its size */ + + mchunkptr newp; /* chunk to return */ + +#if defined _LIBC || defined MALLOC_HOOKS + if (__realloc_hook != NULL) { + Void_t* result; + + result = (*__realloc_hook)(oldmem, bytes); + return result; + } +#endif + +#ifdef REALLOC_ZERO_BYTES_FREES + if (bytes == 0 && oldmem != NULL) { fREe(oldmem); return 0; } +#endif + + /* realloc of null is supposed to be same as malloc */ + if (oldmem == 0) return mALLOc(bytes); + + oldp = mem2chunk(oldmem); + oldsize = chunksize(oldp); + + if(request2size(bytes, nb)) + return 0; + +#if HAVE_MMAP + if (chunk_is_mmapped(oldp)) + { + Void_t* newmem; + +#if HAVE_MREMAP + newp = mremap_chunk(oldp, nb); + if(newp) return chunk2mem(newp); +#endif + /* Note the extra SIZE_SZ overhead. */ + if(oldsize - SIZE_SZ >= nb) return oldmem; /* do nothing */ + /* Must alloc, copy, free. */ + newmem = mALLOc(bytes); + if (newmem == 0) return 0; /* propagate failure */ + MALLOC_COPY(newmem, oldmem, oldsize - 2*SIZE_SZ); + munmap_chunk(oldp); + return newmem; + } +#endif + + ar_ptr = arena_for_ptr(oldp); +#if THREAD_STATS + if(!mutex_trylock(&ar_ptr->mutex)) + ++(ar_ptr->stat_lock_direct); + else { + (void)mutex_lock(&ar_ptr->mutex); + ++(ar_ptr->stat_lock_wait); + } +#else + (void)mutex_lock(&ar_ptr->mutex); +#endif + +#ifndef NO_THREADS + /* As in malloc(), remember this arena for the next allocation. */ + tsd_setspecific(arena_key, (Void_t *)ar_ptr); +#endif + + newp = chunk_realloc(ar_ptr, oldp, oldsize, nb); + + (void)mutex_unlock(&ar_ptr->mutex); + return newp ? chunk2mem(newp) : NULL; +} + +static mchunkptr +internal_function +#if __STD_C +chunk_realloc(arena* ar_ptr, mchunkptr oldp, INTERNAL_SIZE_T oldsize, + INTERNAL_SIZE_T nb) +#else +chunk_realloc(ar_ptr, oldp, oldsize, nb) +arena* ar_ptr; mchunkptr oldp; INTERNAL_SIZE_T oldsize, nb; +#endif +{ + mchunkptr newp = oldp; /* chunk to return */ + INTERNAL_SIZE_T newsize = oldsize; /* its size */ + + mchunkptr next; /* next contiguous chunk after oldp */ + INTERNAL_SIZE_T nextsize; /* its size */ + + mchunkptr prev; /* previous contiguous chunk before oldp */ + INTERNAL_SIZE_T prevsize; /* its size */ + + mchunkptr remainder; /* holds split off extra space from newp */ + INTERNAL_SIZE_T remainder_size; /* its size */ + + mchunkptr bck; /* misc temp for linking */ + mchunkptr fwd; /* misc temp for linking */ + + check_inuse_chunk(ar_ptr, oldp); + + if ((long)(oldsize) < (long)(nb)) + { + + /* Try expanding forward */ + + next = chunk_at_offset(oldp, oldsize); + if (next == top(ar_ptr) || !inuse(next)) + { + nextsize = chunksize(next); + + /* Forward into top only if a remainder */ + if (next == top(ar_ptr)) + { + if ((long)(nextsize + newsize) >= (long)(nb + MINSIZE)) + { + newsize += nextsize; + top(ar_ptr) = chunk_at_offset(oldp, nb); + set_head(top(ar_ptr), (newsize - nb) | PREV_INUSE); + set_head_size(oldp, nb); + return oldp; + } + } + + /* Forward into next chunk */ + else if (((long)(nextsize + newsize) >= (long)(nb))) + { + unlink(next, bck, fwd); + newsize += nextsize; + goto split; + } + } + else + { + next = 0; + nextsize = 0; + } + + /* Try shifting backwards. */ + + if (!prev_inuse(oldp)) + { + prev = prev_chunk(oldp); + prevsize = chunksize(prev); + + /* try forward + backward first to save a later consolidation */ + + if (next != 0) + { + /* into top */ + if (next == top(ar_ptr)) + { + if ((long)(nextsize + prevsize + newsize) >= (long)(nb + MINSIZE)) + { + unlink(prev, bck, fwd); + newp = prev; + newsize += prevsize + nextsize; + MALLOC_COPY(chunk2mem(newp), chunk2mem(oldp), oldsize - SIZE_SZ); + top(ar_ptr) = chunk_at_offset(newp, nb); + set_head(top(ar_ptr), (newsize - nb) | PREV_INUSE); + set_head_size(newp, nb); + return newp; + } + } + + /* into next chunk */ + else if (((long)(nextsize + prevsize + newsize) >= (long)(nb))) + { + unlink(next, bck, fwd); + unlink(prev, bck, fwd); + newp = prev; + newsize += nextsize + prevsize; + MALLOC_COPY(chunk2mem(newp), chunk2mem(oldp), oldsize - SIZE_SZ); + goto split; + } + } + + /* backward only */ + if (prev != 0 && (long)(prevsize + newsize) >= (long)nb) + { + unlink(prev, bck, fwd); + newp = prev; + newsize += prevsize; + MALLOC_COPY(chunk2mem(newp), chunk2mem(oldp), oldsize - SIZE_SZ); + goto split; + } + } + + /* Must allocate */ + + newp = chunk_alloc (ar_ptr, nb); + + if (newp == 0) { + /* Maybe the failure is due to running out of mmapped areas. */ + if (ar_ptr != &main_arena) { + (void)mutex_lock(&main_arena.mutex); + newp = chunk_alloc(&main_arena, nb); + (void)mutex_unlock(&main_arena.mutex); + } else { +#if USE_ARENAS + /* ... or sbrk() has failed and there is still a chance to mmap() */ + arena* ar_ptr2 = arena_get2(ar_ptr->next ? ar_ptr : 0, nb); + if(ar_ptr2) { + newp = chunk_alloc(ar_ptr2, nb); + (void)mutex_unlock(&ar_ptr2->mutex); + } +#endif + } + if (newp == 0) /* propagate failure */ + return 0; + } + + /* Avoid copy if newp is next chunk after oldp. */ + /* (This can only happen when new chunk is sbrk'ed.) */ + + if ( newp == next_chunk(oldp)) + { + newsize += chunksize(newp); + newp = oldp; + goto split; + } + + /* Otherwise copy, free, and exit */ + MALLOC_COPY(chunk2mem(newp), chunk2mem(oldp), oldsize - SIZE_SZ); + chunk_free(ar_ptr, oldp); + return newp; + } + + + split: /* split off extra room in old or expanded chunk */ + + if (newsize - nb >= MINSIZE) /* split off remainder */ + { + remainder = chunk_at_offset(newp, nb); + remainder_size = newsize - nb; + set_head_size(newp, nb); + set_head(remainder, remainder_size | PREV_INUSE); + set_inuse_bit_at_offset(remainder, remainder_size); + chunk_free(ar_ptr, remainder); + } + else + { + set_head_size(newp, newsize); + set_inuse_bit_at_offset(newp, newsize); + } + + check_inuse_chunk(ar_ptr, newp); + return newp; +} + + + + +/* + + memalign algorithm: + + memalign requests more than enough space from malloc, finds a spot + within that chunk that meets the alignment request, and then + possibly frees the leading and trailing space. + + The alignment argument must be a power of two. This property is not + checked by memalign, so misuse may result in random runtime errors. + + 8-byte alignment is guaranteed by normal malloc calls, so don't + bother calling memalign with an argument of 8 or less. + + Overreliance on memalign is a sure way to fragment space. + +*/ + + +#if __STD_C +Void_t* mEMALIGn(size_t alignment, size_t bytes) +#else +Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes; +#endif +{ + arena *ar_ptr; + INTERNAL_SIZE_T nb; /* padded request size */ + mchunkptr p; + +#if defined _LIBC || defined MALLOC_HOOKS + if (__memalign_hook != NULL) { + Void_t* result; + + result = (*__memalign_hook)(alignment, bytes); + return result; + } +#endif + + /* If need less alignment than we give anyway, just relay to malloc */ + + if (alignment <= MALLOC_ALIGNMENT) return mALLOc(bytes); + + /* Otherwise, ensure that it is at least a minimum chunk size */ + + if (alignment < MINSIZE) alignment = MINSIZE; + + if(request2size(bytes, nb)) + return 0; + arena_get(ar_ptr, nb + alignment + MINSIZE); + if(!ar_ptr) + return 0; + p = chunk_align(ar_ptr, nb, alignment); + (void)mutex_unlock(&ar_ptr->mutex); + if(!p) { + /* Maybe the failure is due to running out of mmapped areas. */ + if(ar_ptr != &main_arena) { + (void)mutex_lock(&main_arena.mutex); + p = chunk_align(&main_arena, nb, alignment); + (void)mutex_unlock(&main_arena.mutex); + } else { +#if USE_ARENAS + /* ... or sbrk() has failed and there is still a chance to mmap() */ + ar_ptr = arena_get2(ar_ptr->next ? ar_ptr : 0, nb); + if(ar_ptr) { + p = chunk_align(ar_ptr, nb, alignment); + (void)mutex_unlock(&ar_ptr->mutex); + } +#endif + } + if(!p) return 0; + } + return chunk2mem(p); +} + +static mchunkptr +internal_function +#if __STD_C +chunk_align(arena* ar_ptr, INTERNAL_SIZE_T nb, size_t alignment) +#else +chunk_align(ar_ptr, nb, alignment) +arena* ar_ptr; INTERNAL_SIZE_T nb; size_t alignment; +#endif +{ + char* m; /* memory returned by malloc call */ + mchunkptr p; /* corresponding chunk */ + char* brk; /* alignment point within p */ + mchunkptr newp; /* chunk to return */ + INTERNAL_SIZE_T newsize; /* its size */ + INTERNAL_SIZE_T leadsize; /* leading space befor alignment point */ + mchunkptr remainder; /* spare room at end to split off */ + long remainder_size; /* its size */ + + /* Call chunk_alloc with worst case padding to hit alignment. */ + p = chunk_alloc(ar_ptr, nb + alignment + MINSIZE); + if (p == 0) + return 0; /* propagate failure */ + + m = (char*)chunk2mem(p); + + if ((((unsigned long)(m)) % alignment) == 0) /* aligned */ + { +#if HAVE_MMAP + if(chunk_is_mmapped(p)) { + return p; /* nothing more to do */ + } +#endif + } + else /* misaligned */ + { + /* + Find an aligned spot inside chunk. + Since we need to give back leading space in a chunk of at + least MINSIZE, if the first calculation places us at + a spot with less than MINSIZE leader, we can move to the + next aligned spot -- we've allocated enough total room so that + this is always possible. + */ + + brk = (char*)mem2chunk(((unsigned long)(m + alignment - 1)) & + -(long)alignment); + if ((long)(brk - (char*)(p)) < (long)MINSIZE) brk += alignment; + + newp = (mchunkptr)brk; + leadsize = brk - (char*)(p); + newsize = chunksize(p) - leadsize; + +#if HAVE_MMAP + if(chunk_is_mmapped(p)) + { + newp->prev_size = p->prev_size + leadsize; + set_head(newp, newsize|IS_MMAPPED); + return newp; + } +#endif + + /* give back leader, use the rest */ + + set_head(newp, newsize | PREV_INUSE); + set_inuse_bit_at_offset(newp, newsize); + set_head_size(p, leadsize); + chunk_free(ar_ptr, p); + p = newp; + + assert (newsize>=nb && (((unsigned long)(chunk2mem(p))) % alignment) == 0); + } + + /* Also give back spare room at the end */ + + remainder_size = chunksize(p) - nb; + + if (remainder_size >= (long)MINSIZE) + { + remainder = chunk_at_offset(p, nb); + set_head(remainder, remainder_size | PREV_INUSE); + set_head_size(p, nb); + chunk_free(ar_ptr, remainder); + } + + check_inuse_chunk(ar_ptr, p); + return p; +} + + + + +/* + valloc just invokes memalign with alignment argument equal + to the page size of the system (or as near to this as can + be figured out from all the includes/defines above.) +*/ + +#if __STD_C +Void_t* vALLOc(size_t bytes) +#else +Void_t* vALLOc(bytes) size_t bytes; +#endif +{ + return mEMALIGn (malloc_getpagesize, bytes); +} + +/* + pvalloc just invokes valloc for the nearest pagesize + that will accommodate request +*/ + + +#if __STD_C +Void_t* pvALLOc(size_t bytes) +#else +Void_t* pvALLOc(bytes) size_t bytes; +#endif +{ + size_t pagesize = malloc_getpagesize; + return mEMALIGn (pagesize, (bytes + pagesize - 1) & ~(pagesize - 1)); +} + +/* + + calloc calls chunk_alloc, then zeroes out the allocated chunk. + +*/ + +#if __STD_C +Void_t* cALLOc(size_t n, size_t elem_size) +#else +Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size; +#endif +{ + arena *ar_ptr; + mchunkptr p, oldtop; + INTERNAL_SIZE_T sz, csz, oldtopsize; + Void_t* mem; + +#if defined _LIBC || defined MALLOC_HOOKS + if (__malloc_hook != NULL) { + sz = n * elem_size; + mem = (*__malloc_hook)(sz); + if(mem == 0) + return 0; +#ifdef HAVE_MEMCPY + return memset(mem, 0, sz); +#else + while(sz > 0) ((char*)mem)[--sz] = 0; /* rather inefficient */ + return mem; +#endif + } +#endif + + if(request2size(n * elem_size, sz)) + return 0; + arena_get(ar_ptr, sz); + if(!ar_ptr) + return 0; + + /* Check if expand_top called, in which case there may be + no need to clear. */ +#if MORECORE_CLEARS + oldtop = top(ar_ptr); + oldtopsize = chunksize(top(ar_ptr)); +#if MORECORE_CLEARS < 2 + /* Only newly allocated memory is guaranteed to be cleared. */ + if (ar_ptr == &main_arena && + oldtopsize < sbrk_base + max_sbrked_mem - (char *)oldtop) + oldtopsize = (sbrk_base + max_sbrked_mem - (char *)oldtop); +#endif +#endif + p = chunk_alloc (ar_ptr, sz); + + /* Only clearing follows, so we can unlock early. */ + (void)mutex_unlock(&ar_ptr->mutex); + + if (p == 0) { + /* Maybe the failure is due to running out of mmapped areas. */ + if(ar_ptr != &main_arena) { + (void)mutex_lock(&main_arena.mutex); + p = chunk_alloc(&main_arena, sz); + (void)mutex_unlock(&main_arena.mutex); + } else { +#if USE_ARENAS + /* ... or sbrk() has failed and there is still a chance to mmap() */ + (void)mutex_lock(&main_arena.mutex); + ar_ptr = arena_get2(ar_ptr->next ? ar_ptr : 0, sz); + (void)mutex_unlock(&main_arena.mutex); + if(ar_ptr) { + p = chunk_alloc(ar_ptr, sz); + (void)mutex_unlock(&ar_ptr->mutex); + } +#endif + } + if (p == 0) return 0; + } + mem = chunk2mem(p); + + /* Two optional cases in which clearing not necessary */ + +#if HAVE_MMAP + if (chunk_is_mmapped(p)) return mem; +#endif + + csz = chunksize(p); + +#if MORECORE_CLEARS + if (p == oldtop && csz > oldtopsize) { + /* clear only the bytes from non-freshly-sbrked memory */ + csz = oldtopsize; + } +#endif + + MALLOC_ZERO(mem, csz - SIZE_SZ); + return mem; +} + +/* + + cfree just calls free. It is needed/defined on some systems + that pair it with calloc, presumably for odd historical reasons. + +*/ + +#if !defined(_LIBC) +#if __STD_C +void cfree(Void_t *mem) +#else +void cfree(mem) Void_t *mem; +#endif +{ + fREe(mem); +} +#endif + + + +/* + + Malloc_trim gives memory back to the system (via negative + arguments to sbrk) if there is unused memory at the `high' end of + the malloc pool. You can call this after freeing large blocks of + memory to potentially reduce the system-level memory requirements + of a program. However, it cannot guarantee to reduce memory. Under + some allocation patterns, some large free blocks of memory will be + locked between two used chunks, so they cannot be given back to + the system. + + The `pad' argument to malloc_trim represents the amount of free + trailing space to leave untrimmed. If this argument is zero, + only the minimum amount of memory to maintain internal data + structures will be left (one page or less). Non-zero arguments + can be supplied to maintain enough trailing space to service + future expected allocations without having to re-obtain memory + from the system. + + Malloc_trim returns 1 if it actually released any memory, else 0. + +*/ + +#if __STD_C +int mALLOC_TRIm(size_t pad) +#else +int mALLOC_TRIm(pad) size_t pad; +#endif +{ + int res; + + (void)mutex_lock(&main_arena.mutex); + res = main_trim(pad); + (void)mutex_unlock(&main_arena.mutex); + return res; +} + +/* Trim the main arena. */ + +static int +internal_function +#if __STD_C +main_trim(size_t pad) +#else +main_trim(pad) size_t pad; +#endif +{ + mchunkptr top_chunk; /* The current top chunk */ + long top_size; /* Amount of top-most memory */ + long extra; /* Amount to release */ + char* current_brk; /* address returned by pre-check sbrk call */ + char* new_brk; /* address returned by negative sbrk call */ + + unsigned long pagesz = malloc_getpagesize; + + top_chunk = top(&main_arena); + top_size = chunksize(top_chunk); + extra = ((top_size - pad - MINSIZE + (pagesz-1)) / pagesz - 1) * pagesz; + + if (extra < (long)pagesz) /* Not enough memory to release */ + return 0; + + /* Test to make sure no one else called sbrk */ + current_brk = (char*)(MORECORE (0)); + if (current_brk != (char*)(top_chunk) + top_size) + return 0; /* Apparently we don't own memory; must fail */ + + new_brk = (char*)(MORECORE (-extra)); + +#if defined _LIBC || defined MALLOC_HOOKS + /* Call the `morecore' hook if necessary. */ + if (__after_morecore_hook) + (*__after_morecore_hook) (); +#endif + + if (new_brk == (char*)(MORECORE_FAILURE)) { /* sbrk failed? */ + /* Try to figure out what we have */ + current_brk = (char*)(MORECORE (0)); + top_size = current_brk - (char*)top_chunk; + if (top_size >= (long)MINSIZE) /* if not, we are very very dead! */ + { + sbrked_mem = current_brk - sbrk_base; + set_head(top_chunk, top_size | PREV_INUSE); + } + check_chunk(&main_arena, top_chunk); + return 0; + } + sbrked_mem -= extra; + + /* Success. Adjust top accordingly. */ + set_head(top_chunk, (top_size - extra) | PREV_INUSE); + check_chunk(&main_arena, top_chunk); + return 1; +} + +#if USE_ARENAS + +static int +internal_function +#if __STD_C +heap_trim(heap_info *heap, size_t pad) +#else +heap_trim(heap, pad) heap_info *heap; size_t pad; +#endif +{ + unsigned long pagesz = malloc_getpagesize; + arena *ar_ptr = heap->ar_ptr; + mchunkptr top_chunk = top(ar_ptr), p, bck, fwd; + heap_info *prev_heap; + long new_size, top_size, extra; + + /* Can this heap go away completely ? */ + while(top_chunk == chunk_at_offset(heap, sizeof(*heap))) { + prev_heap = heap->prev; + p = chunk_at_offset(prev_heap, prev_heap->size - (MINSIZE-2*SIZE_SZ)); + assert(p->size == (0|PREV_INUSE)); /* must be fencepost */ + p = prev_chunk(p); + new_size = chunksize(p) + (MINSIZE-2*SIZE_SZ); + assert(new_size>0 && new_size<(long)(2*MINSIZE)); + if(!prev_inuse(p)) + new_size += p->prev_size; + assert(new_size>0 && new_sizesize) < pad + MINSIZE + pagesz) + break; + ar_ptr->size -= heap->size; + arena_mem -= heap->size; + delete_heap(heap); + heap = prev_heap; + if(!prev_inuse(p)) { /* consolidate backward */ + p = prev_chunk(p); + unlink(p, bck, fwd); + } + assert(((unsigned long)((char*)p + new_size) & (pagesz-1)) == 0); + assert( ((char*)p + new_size) == ((char*)heap + heap->size) ); + top(ar_ptr) = top_chunk = p; + set_head(top_chunk, new_size | PREV_INUSE); + check_chunk(ar_ptr, top_chunk); + } + top_size = chunksize(top_chunk); + extra = ((top_size - pad - MINSIZE + (pagesz-1))/pagesz - 1) * pagesz; + if(extra < (long)pagesz) + return 0; + /* Try to shrink. */ + if(grow_heap(heap, -extra) != 0) + return 0; + ar_ptr->size -= extra; + arena_mem -= extra; + + /* Success. Adjust top accordingly. */ + set_head(top_chunk, (top_size - extra) | PREV_INUSE); + check_chunk(ar_ptr, top_chunk); + return 1; +} + +#endif /* USE_ARENAS */ + + + +/* + malloc_usable_size: + + This routine tells you how many bytes you can actually use in an + allocated chunk, which may be more than you requested (although + often not). You can use this many bytes without worrying about + overwriting other allocated objects. Not a particularly great + programming practice, but still sometimes useful. + +*/ + +#if __STD_C +size_t mALLOC_USABLE_SIZe(Void_t* mem) +#else +size_t mALLOC_USABLE_SIZe(mem) Void_t* mem; +#endif +{ + mchunkptr p; + + if (mem == 0) + return 0; + else + { + p = mem2chunk(mem); + if(!chunk_is_mmapped(p)) + { + if (!inuse(p)) return 0; + check_inuse_chunk(arena_for_ptr(mem), p); + return chunksize(p) - SIZE_SZ; + } + return chunksize(p) - 2*SIZE_SZ; + } +} + + + + +/* Utility to update mallinfo for malloc_stats() and mallinfo() */ + +static void +#if __STD_C +malloc_update_mallinfo(arena *ar_ptr, struct mallinfo *mi) +#else +malloc_update_mallinfo(ar_ptr, mi) arena *ar_ptr; struct mallinfo *mi; +#endif +{ + int i, navail; + mbinptr b; + mchunkptr p; +#if MALLOC_DEBUG + mchunkptr q; +#endif + INTERNAL_SIZE_T avail; + + (void)mutex_lock(&ar_ptr->mutex); + avail = chunksize(top(ar_ptr)); + navail = ((long)(avail) >= (long)MINSIZE)? 1 : 0; + + for (i = 1; i < NAV; ++i) + { + b = bin_at(ar_ptr, i); + for (p = last(b); p != b; p = p->bk) + { +#if MALLOC_DEBUG + check_free_chunk(ar_ptr, p); + for (q = next_chunk(p); + q != top(ar_ptr) && inuse(q) && (long)chunksize(q) > 0; + q = next_chunk(q)) + check_inuse_chunk(ar_ptr, q); +#endif + avail += chunksize(p); + navail++; + } + } + + mi->arena = ar_ptr->size; + mi->ordblks = navail; + mi->smblks = mi->usmblks = mi->fsmblks = 0; /* clear unused fields */ + mi->uordblks = ar_ptr->size - avail; + mi->fordblks = avail; + mi->hblks = n_mmaps; + mi->hblkhd = mmapped_mem; + mi->keepcost = chunksize(top(ar_ptr)); + + (void)mutex_unlock(&ar_ptr->mutex); +} + +#if USE_ARENAS && MALLOC_DEBUG > 1 + +/* Print the complete contents of a single heap to stderr. */ + +static void +#if __STD_C +dump_heap(heap_info *heap) +#else +dump_heap(heap) heap_info *heap; +#endif +{ + char *ptr; + mchunkptr p; + + fprintf(stderr, "Heap %p, size %10lx:\n", heap, (long)heap->size); + ptr = (heap->ar_ptr != (arena*)(heap+1)) ? + (char*)(heap + 1) : (char*)(heap + 1) + sizeof(arena); + p = (mchunkptr)(((unsigned long)ptr + MALLOC_ALIGN_MASK) & + ~MALLOC_ALIGN_MASK); + for(;;) { + fprintf(stderr, "chunk %p size %10lx", p, (long)p->size); + if(p == top(heap->ar_ptr)) { + fprintf(stderr, " (top)\n"); + break; + } else if(p->size == (0|PREV_INUSE)) { + fprintf(stderr, " (fence)\n"); + break; + } + fprintf(stderr, "\n"); + p = next_chunk(p); + } +} + +#endif + + + +/* + + malloc_stats: + + For all arenas separately and in total, prints on stderr the + amount of space obtained from the system, and the current number + of bytes allocated via malloc (or realloc, etc) but not yet + freed. (Note that this is the number of bytes allocated, not the + number requested. It will be larger than the number requested + because of alignment and bookkeeping overhead.) When not compiled + for multiple threads, the maximum amount of allocated memory + (which may be more than current if malloc_trim and/or munmap got + called) is also reported. When using mmap(), prints the maximum + number of simultaneous mmap regions used, too. + +*/ + +void mALLOC_STATs() +{ + int i; + arena *ar_ptr; + struct mallinfo mi; + unsigned int in_use_b = mmapped_mem, system_b = in_use_b; +#if THREAD_STATS + long stat_lock_direct = 0, stat_lock_loop = 0, stat_lock_wait = 0; +#endif + + for(i=0, ar_ptr = &main_arena;; i++) { + malloc_update_mallinfo(ar_ptr, &mi); + fprintf(stderr, "Arena %d:\n", i); + fprintf(stderr, "system bytes = %10u\n", (unsigned int)mi.arena); + fprintf(stderr, "in use bytes = %10u\n", (unsigned int)mi.uordblks); + system_b += mi.arena; + in_use_b += mi.uordblks; +#if THREAD_STATS + stat_lock_direct += ar_ptr->stat_lock_direct; + stat_lock_loop += ar_ptr->stat_lock_loop; + stat_lock_wait += ar_ptr->stat_lock_wait; +#endif +#if USE_ARENAS && MALLOC_DEBUG > 1 + if(ar_ptr != &main_arena) { + heap_info *heap; + (void)mutex_lock(&ar_ptr->mutex); + heap = heap_for_ptr(top(ar_ptr)); + while(heap) { dump_heap(heap); heap = heap->prev; } + (void)mutex_unlock(&ar_ptr->mutex); + } +#endif + ar_ptr = ar_ptr->next; + if(ar_ptr == &main_arena) break; + } +#if HAVE_MMAP + fprintf(stderr, "Total (incl. mmap):\n"); +#else + fprintf(stderr, "Total:\n"); +#endif + fprintf(stderr, "system bytes = %10u\n", system_b); + fprintf(stderr, "in use bytes = %10u\n", in_use_b); +#ifdef NO_THREADS + fprintf(stderr, "max system bytes = %10u\n", (unsigned int)max_total_mem); +#endif +#if HAVE_MMAP + fprintf(stderr, "max mmap regions = %10u\n", (unsigned int)max_n_mmaps); + fprintf(stderr, "max mmap bytes = %10lu\n", max_mmapped_mem); +#endif +#if THREAD_STATS + fprintf(stderr, "heaps created = %10d\n", stat_n_heaps); + fprintf(stderr, "locked directly = %10ld\n", stat_lock_direct); + fprintf(stderr, "locked in loop = %10ld\n", stat_lock_loop); + fprintf(stderr, "locked waiting = %10ld\n", stat_lock_wait); + fprintf(stderr, "locked total = %10ld\n", + stat_lock_direct + stat_lock_loop + stat_lock_wait); +#endif +} + +/* + mallinfo returns a copy of updated current mallinfo. + The information reported is for the arena last used by the thread. +*/ + +struct mallinfo mALLINFo() +{ + struct mallinfo mi; + Void_t *vptr = NULL; + +#ifndef NO_THREADS + tsd_getspecific(arena_key, vptr); +#endif + malloc_update_mallinfo((vptr ? (arena*)vptr : &main_arena), &mi); + return mi; +} + + + + +/* + mallopt: + + mallopt is the general SVID/XPG interface to tunable parameters. + The format is to provide a (parameter-number, parameter-value) pair. + mallopt then sets the corresponding parameter to the argument + value if it can (i.e., so long as the value is meaningful), + and returns 1 if successful else 0. + + See descriptions of tunable parameters above. + +*/ + +#if __STD_C +int mALLOPt(int param_number, int value) +#else +int mALLOPt(param_number, value) int param_number; int value; +#endif +{ + switch(param_number) + { + case M_TRIM_THRESHOLD: + trim_threshold = value; return 1; + case M_TOP_PAD: + top_pad = value; return 1; + case M_MMAP_THRESHOLD: +#if USE_ARENAS + /* Forbid setting the threshold too high. */ + if((unsigned long)value > HEAP_MAX_SIZE/2) return 0; +#endif + mmap_threshold = value; return 1; + case M_MMAP_MAX: +#if HAVE_MMAP + n_mmaps_max = value; return 1; +#else + if (value != 0) return 0; else n_mmaps_max = value; return 1; +#endif + case M_CHECK_ACTION: + check_action = value; return 1; + + default: + return 0; + } +} + + + +/* Get/set state: malloc_get_state() records the current state of all + malloc variables (_except_ for the actual heap contents and `hook' + function pointers) in a system dependent, opaque data structure. + This data structure is dynamically allocated and can be free()d + after use. malloc_set_state() restores the state of all malloc + variables to the previously obtained state. This is especially + useful when using this malloc as part of a shared library, and when + the heap contents are saved/restored via some other method. The + primary example for this is GNU Emacs with its `dumping' procedure. + `Hook' function pointers are never saved or restored by these + functions, with two exceptions: If malloc checking was in use when + malloc_get_state() was called, then malloc_set_state() calls + __malloc_check_init() if possible; if malloc checking was not in + use in the recorded state but the user requested malloc checking, + then the hooks are reset to 0. */ + +#define MALLOC_STATE_MAGIC 0x444c4541l +#define MALLOC_STATE_VERSION (0*0x100l + 1l) /* major*0x100 + minor */ + +struct malloc_state { + long magic; + long version; + mbinptr av[NAV * 2 + 2]; + char* sbrk_base; + int sbrked_mem_bytes; + unsigned long trim_threshold; + unsigned long top_pad; + unsigned int n_mmaps_max; + unsigned long mmap_threshold; + int check_action; + unsigned long max_sbrked_mem; + unsigned long max_total_mem; + unsigned int n_mmaps; + unsigned int max_n_mmaps; + unsigned long mmapped_mem; + unsigned long max_mmapped_mem; + int using_malloc_checking; +}; + +Void_t* +mALLOC_GET_STATe() +{ + struct malloc_state* ms; + int i; + mbinptr b; + + ms = (struct malloc_state*)mALLOc(sizeof(*ms)); + if (!ms) + return 0; + (void)mutex_lock(&main_arena.mutex); + ms->magic = MALLOC_STATE_MAGIC; + ms->version = MALLOC_STATE_VERSION; + ms->av[0] = main_arena.av[0]; + ms->av[1] = main_arena.av[1]; + for(i=0; iav[2*i+2] = ms->av[2*i+3] = 0; /* empty bin (or initial top) */ + else { + ms->av[2*i+2] = first(b); + ms->av[2*i+3] = last(b); + } + } + ms->sbrk_base = sbrk_base; + ms->sbrked_mem_bytes = sbrked_mem; + ms->trim_threshold = trim_threshold; + ms->top_pad = top_pad; + ms->n_mmaps_max = n_mmaps_max; + ms->mmap_threshold = mmap_threshold; + ms->check_action = check_action; + ms->max_sbrked_mem = max_sbrked_mem; +#ifdef NO_THREADS + ms->max_total_mem = max_total_mem; +#else + ms->max_total_mem = 0; +#endif + ms->n_mmaps = n_mmaps; + ms->max_n_mmaps = max_n_mmaps; + ms->mmapped_mem = mmapped_mem; + ms->max_mmapped_mem = max_mmapped_mem; +#if defined _LIBC || defined MALLOC_HOOKS + ms->using_malloc_checking = using_malloc_checking; +#else + ms->using_malloc_checking = 0; +#endif + (void)mutex_unlock(&main_arena.mutex); + return (Void_t*)ms; +} + +int +#if __STD_C +mALLOC_SET_STATe(Void_t* msptr) +#else +mALLOC_SET_STATe(msptr) Void_t* msptr; +#endif +{ + struct malloc_state* ms = (struct malloc_state*)msptr; + int i; + mbinptr b; + +#if defined _LIBC || defined MALLOC_HOOKS + disallow_malloc_check = 1; +#endif + ptmalloc_init(); + if(ms->magic != MALLOC_STATE_MAGIC) return -1; + /* Must fail if the major version is too high. */ + if((ms->version & ~0xffl) > (MALLOC_STATE_VERSION & ~0xffl)) return -2; + (void)mutex_lock(&main_arena.mutex); + main_arena.av[0] = ms->av[0]; + main_arena.av[1] = ms->av[1]; + for(i=0; iav[2*i+2] == 0) + first(b) = last(b) = b; + else { + first(b) = ms->av[2*i+2]; + last(b) = ms->av[2*i+3]; + if(i > 0) { + /* Make sure the links to the `av'-bins in the heap are correct. */ + first(b)->bk = b; + last(b)->fd = b; + } + } + } + sbrk_base = ms->sbrk_base; + sbrked_mem = ms->sbrked_mem_bytes; + trim_threshold = ms->trim_threshold; + top_pad = ms->top_pad; + n_mmaps_max = ms->n_mmaps_max; + mmap_threshold = ms->mmap_threshold; + check_action = ms->check_action; + max_sbrked_mem = ms->max_sbrked_mem; +#ifdef NO_THREADS + max_total_mem = ms->max_total_mem; +#endif + n_mmaps = ms->n_mmaps; + max_n_mmaps = ms->max_n_mmaps; + mmapped_mem = ms->mmapped_mem; + max_mmapped_mem = ms->max_mmapped_mem; + /* add version-dependent code here */ + if (ms->version >= 1) { +#if defined _LIBC || defined MALLOC_HOOKS + /* Check whether it is safe to enable malloc checking, or whether + it is necessary to disable it. */ + if (ms->using_malloc_checking && !using_malloc_checking && + !disallow_malloc_check) + __malloc_check_init (); + else if (!ms->using_malloc_checking && using_malloc_checking) { + __malloc_hook = 0; + __free_hook = 0; + __realloc_hook = 0; + __memalign_hook = 0; + using_malloc_checking = 0; + } +#endif + } + + (void)mutex_unlock(&main_arena.mutex); + return 0; +} + + + +#if defined _LIBC || defined MALLOC_HOOKS + +/* A simple, standard set of debugging hooks. Overhead is `only' one + byte per chunk; still this will catch most cases of double frees or + overruns. The goal here is to avoid obscure crashes due to invalid + usage, unlike in the MALLOC_DEBUG code. */ + +#define MAGICBYTE(p) ( ( ((size_t)p >> 3) ^ ((size_t)p >> 11)) & 0xFF ) + +/* Instrument a chunk with overrun detector byte(s) and convert it + into a user pointer with requested size sz. */ + +static Void_t* +internal_function +#if __STD_C +chunk2mem_check(mchunkptr p, size_t sz) +#else +chunk2mem_check(p, sz) mchunkptr p; size_t sz; +#endif +{ + unsigned char* m_ptr = (unsigned char*)chunk2mem(p); + size_t i; + + for(i = chunksize(p) - (chunk_is_mmapped(p) ? 2*SIZE_SZ+1 : SIZE_SZ+1); + i > sz; + i -= 0xFF) { + if(i-sz < 0x100) { + m_ptr[i] = (unsigned char)(i-sz); + break; + } + m_ptr[i] = 0xFF; + } + m_ptr[sz] = MAGICBYTE(p); + return (Void_t*)m_ptr; +} + +/* Convert a pointer to be free()d or realloc()ed to a valid chunk + pointer. If the provided pointer is not valid, return NULL. */ + +static mchunkptr +internal_function +#if __STD_C +mem2chunk_check(Void_t* mem) +#else +mem2chunk_check(mem) Void_t* mem; +#endif +{ + mchunkptr p; + INTERNAL_SIZE_T sz, c; + unsigned char magic; + + p = mem2chunk(mem); + if(!aligned_OK(p)) return NULL; + if( (char*)p>=sbrk_base && (char*)p<(sbrk_base+sbrked_mem) ) { + /* Must be a chunk in conventional heap memory. */ + if(chunk_is_mmapped(p) || + ( (sz = chunksize(p)), ((char*)p + sz)>=(sbrk_base+sbrked_mem) ) || + szprev_size&MALLOC_ALIGN_MASK || + (long)prev_chunk(p)<(long)sbrk_base || + next_chunk(prev_chunk(p))!=p) )) + return NULL; + magic = MAGICBYTE(p); + for(sz += SIZE_SZ-1; (c = ((unsigned char*)p)[sz]) != magic; sz -= c) { + if(c<=0 || sz<(c+2*SIZE_SZ)) return NULL; + } + ((unsigned char*)p)[sz] ^= 0xFF; + } else { + unsigned long offset, page_mask = malloc_getpagesize-1; + + /* mmap()ed chunks have MALLOC_ALIGNMENT or higher power-of-two + alignment relative to the beginning of a page. Check this + first. */ + offset = (unsigned long)mem & page_mask; + if((offset!=MALLOC_ALIGNMENT && offset!=0 && offset!=0x10 && + offset!=0x20 && offset!=0x40 && offset!=0x80 && offset!=0x100 && + offset!=0x200 && offset!=0x400 && offset!=0x800 && offset!=0x1000 && + offset<0x2000) || + !chunk_is_mmapped(p) || (p->size & PREV_INUSE) || + ( (((unsigned long)p - p->prev_size) & page_mask) != 0 ) || + ( (sz = chunksize(p)), ((p->prev_size + sz) & page_mask) != 0 ) ) + return NULL; + magic = MAGICBYTE(p); + for(sz -= 1; (c = ((unsigned char*)p)[sz]) != magic; sz -= c) { + if(c<=0 || sz<(c+2*SIZE_SZ)) return NULL; + } + ((unsigned char*)p)[sz] ^= 0xFF; + } + return p; +} + +/* Check for corruption of the top chunk, and try to recover if + necessary. */ + +static int +internal_function +top_check __MALLOC_P((void)) +{ + mchunkptr t = top(&main_arena); + char* brk, * new_brk; + INTERNAL_SIZE_T front_misalign, sbrk_size; + unsigned long pagesz = malloc_getpagesize; + + if((char*)t + chunksize(t) == sbrk_base + sbrked_mem || + t == initial_top(&main_arena)) return 0; + + if(check_action & 1) + fprintf(stderr, "malloc: top chunk is corrupt\n"); + if(check_action & 2) + abort(); + + /* Try to set up a new top chunk. */ + brk = MORECORE(0); + front_misalign = (unsigned long)chunk2mem(brk) & MALLOC_ALIGN_MASK; + if (front_misalign > 0) + front_misalign = MALLOC_ALIGNMENT - front_misalign; + sbrk_size = front_misalign + top_pad + MINSIZE; + sbrk_size += pagesz - ((unsigned long)(brk + sbrk_size) & (pagesz - 1)); + new_brk = (char*)(MORECORE (sbrk_size)); + if (new_brk == (char*)(MORECORE_FAILURE)) return -1; + sbrked_mem = (new_brk - sbrk_base) + sbrk_size; + + top(&main_arena) = (mchunkptr)(brk + front_misalign); + set_head(top(&main_arena), (sbrk_size - front_misalign) | PREV_INUSE); + + return 0; +} + +static Void_t* +#if __STD_C +malloc_check(size_t sz) +#else +malloc_check(sz) size_t sz; +#endif +{ + mchunkptr victim; + INTERNAL_SIZE_T nb; + + if(request2size(sz+1, nb)) + return 0; + (void)mutex_lock(&main_arena.mutex); + victim = (top_check() >= 0) ? chunk_alloc(&main_arena, nb) : NULL; + (void)mutex_unlock(&main_arena.mutex); + if(!victim) return NULL; + return chunk2mem_check(victim, sz); +} + +static void +#if __STD_C +free_check(Void_t* mem) +#else +free_check(mem) Void_t* mem; +#endif +{ + mchunkptr p; + + if(!mem) return; + (void)mutex_lock(&main_arena.mutex); + p = mem2chunk_check(mem); + if(!p) { + (void)mutex_unlock(&main_arena.mutex); + if(check_action & 1) + fprintf(stderr, "free(): invalid pointer %p!\n", mem); + if(check_action & 2) + abort(); + return; + } +#if HAVE_MMAP + if (chunk_is_mmapped(p)) { + (void)mutex_unlock(&main_arena.mutex); + munmap_chunk(p); + return; + } +#endif +#if 0 /* Erase freed memory. */ + memset(mem, 0, chunksize(p) - (SIZE_SZ+1)); +#endif + chunk_free(&main_arena, p); + (void)mutex_unlock(&main_arena.mutex); +} + +static Void_t* +#if __STD_C +realloc_check(Void_t* oldmem, size_t bytes) +#else +realloc_check(oldmem, bytes) Void_t* oldmem; size_t bytes; +#endif +{ + mchunkptr oldp, newp; + INTERNAL_SIZE_T nb, oldsize; + + if (oldmem == 0) return malloc_check(bytes); + (void)mutex_lock(&main_arena.mutex); + oldp = mem2chunk_check(oldmem); + if(!oldp) { + (void)mutex_unlock(&main_arena.mutex); + if(check_action & 1) + fprintf(stderr, "realloc(): invalid pointer %p!\n", oldmem); + if(check_action & 2) + abort(); + return malloc_check(bytes); + } + oldsize = chunksize(oldp); + + if(request2size(bytes+1, nb)) { + (void)mutex_unlock(&main_arena.mutex); + return 0; + } + +#if HAVE_MMAP + if (chunk_is_mmapped(oldp)) { +#if HAVE_MREMAP + newp = mremap_chunk(oldp, nb); + if(!newp) { +#endif + /* Note the extra SIZE_SZ overhead. */ + if(oldsize - SIZE_SZ >= nb) newp = oldp; /* do nothing */ + else { + /* Must alloc, copy, free. */ + newp = (top_check() >= 0) ? chunk_alloc(&main_arena, nb) : NULL; + if (newp) { + MALLOC_COPY(chunk2mem(newp), oldmem, oldsize - 2*SIZE_SZ); + munmap_chunk(oldp); + } + } +#if HAVE_MREMAP + } +#endif + } else { +#endif /* HAVE_MMAP */ + newp = (top_check() >= 0) ? + chunk_realloc(&main_arena, oldp, oldsize, nb) : NULL; +#if 0 /* Erase freed memory. */ + nb = chunksize(newp); + if(oldp=chunk_at_offset(newp, nb)) { + memset((char*)oldmem + 2*sizeof(mbinptr), 0, + oldsize - (2*sizeof(mbinptr)+2*SIZE_SZ+1)); + } else if(nb > oldsize+SIZE_SZ) { + memset((char*)chunk2mem(newp) + oldsize, 0, nb - (oldsize+SIZE_SZ)); + } +#endif +#if HAVE_MMAP + } +#endif + (void)mutex_unlock(&main_arena.mutex); + + if(!newp) return NULL; + return chunk2mem_check(newp, bytes); +} + +static Void_t* +#if __STD_C +memalign_check(size_t alignment, size_t bytes) +#else +memalign_check(alignment, bytes) size_t alignment; size_t bytes; +#endif +{ + INTERNAL_SIZE_T nb; + mchunkptr p; + + if (alignment <= MALLOC_ALIGNMENT) return malloc_check(bytes); + if (alignment < MINSIZE) alignment = MINSIZE; + + if(request2size(bytes+1, nb)) + return 0; + (void)mutex_lock(&main_arena.mutex); + p = (top_check() >= 0) ? chunk_align(&main_arena, nb, alignment) : NULL; + (void)mutex_unlock(&main_arena.mutex); + if(!p) return NULL; + return chunk2mem_check(p, bytes); +} + +#ifndef NO_THREADS + +/* The following hooks are used when the global initialization in + ptmalloc_init() hasn't completed yet. */ + +static Void_t* +#if __STD_C +malloc_starter(size_t sz) +#else +malloc_starter(sz) size_t sz; +#endif +{ + INTERNAL_SIZE_T nb; + mchunkptr victim; + + if(request2size(sz, nb)) + return 0; + victim = chunk_alloc(&main_arena, nb); + + return victim ? chunk2mem(victim) : 0; +} + +static void +#if __STD_C +free_starter(Void_t* mem) +#else +free_starter(mem) Void_t* mem; +#endif +{ + mchunkptr p; + + if(!mem) return; + p = mem2chunk(mem); +#if HAVE_MMAP + if (chunk_is_mmapped(p)) { + munmap_chunk(p); + return; + } +#endif + chunk_free(&main_arena, p); +} + +/* The following hooks are used while the `atfork' handling mechanism + is active. */ + +static Void_t* +#if __STD_C +malloc_atfork(size_t sz) +#else +malloc_atfork(sz) size_t sz; +#endif +{ + Void_t *vptr = NULL; + INTERNAL_SIZE_T nb; + mchunkptr victim; + + tsd_getspecific(arena_key, vptr); + if(!vptr) { + if(save_malloc_hook != malloc_check) { + if(request2size(sz, nb)) + return 0; + victim = chunk_alloc(&main_arena, nb); + return victim ? chunk2mem(victim) : 0; + } else { + if(top_check()<0 || request2size(sz+1, nb)) + return 0; + victim = chunk_alloc(&main_arena, nb); + return victim ? chunk2mem_check(victim, sz) : 0; + } + } else { + /* Suspend the thread until the `atfork' handlers have completed. + By that time, the hooks will have been reset as well, so that + mALLOc() can be used again. */ + (void)mutex_lock(&list_lock); + (void)mutex_unlock(&list_lock); + return mALLOc(sz); + } +} + +static void +#if __STD_C +free_atfork(Void_t* mem) +#else +free_atfork(mem) Void_t* mem; +#endif +{ + Void_t *vptr = NULL; + arena *ar_ptr; + mchunkptr p; /* chunk corresponding to mem */ + + if (mem == 0) /* free(0) has no effect */ + return; + + p = mem2chunk(mem); /* do not bother to replicate free_check here */ + +#if HAVE_MMAP + if (chunk_is_mmapped(p)) /* release mmapped memory. */ + { + munmap_chunk(p); + return; + } +#endif + + ar_ptr = arena_for_ptr(p); + tsd_getspecific(arena_key, vptr); + if(vptr) + (void)mutex_lock(&ar_ptr->mutex); + chunk_free(ar_ptr, p); + if(vptr) + (void)mutex_unlock(&ar_ptr->mutex); +} + +#endif /* !defined NO_THREADS */ + +#endif /* defined _LIBC || defined MALLOC_HOOKS */ + + + +#ifdef _LIBC +weak_alias (__libc_calloc, __calloc) weak_alias (__libc_calloc, calloc) +weak_alias (__libc_free, __cfree) weak_alias (__libc_free, cfree) +weak_alias (__libc_free, __free) weak_alias (__libc_free, free) +weak_alias (__libc_malloc, __malloc) weak_alias (__libc_malloc, malloc) +weak_alias (__libc_memalign, __memalign) weak_alias (__libc_memalign, memalign) +weak_alias (__libc_realloc, __realloc) weak_alias (__libc_realloc, realloc) +weak_alias (__libc_valloc, __valloc) weak_alias (__libc_valloc, valloc) +weak_alias (__libc_pvalloc, __pvalloc) weak_alias (__libc_pvalloc, pvalloc) +weak_alias (__libc_mallinfo, __mallinfo) weak_alias (__libc_mallinfo, mallinfo) +weak_alias (__libc_mallopt, __mallopt) weak_alias (__libc_mallopt, mallopt) + +weak_alias (__malloc_stats, malloc_stats) +weak_alias (__malloc_usable_size, malloc_usable_size) +weak_alias (__malloc_trim, malloc_trim) +weak_alias (__malloc_get_state, malloc_get_state) +weak_alias (__malloc_set_state, malloc_set_state) +#endif + +/* + +History: + + V2.6.4-pt3 Thu Feb 20 1997 Wolfram Gloger (wmglo@dent.med.uni-muenchen.de) + * Added malloc_get/set_state() (mainly for use in GNU emacs), + using interface from Marcus Daniels + * All parameters are now adjustable via environment variables + + V2.6.4-pt2 Sat Dec 14 1996 Wolfram Gloger (wmglo@dent.med.uni-muenchen.de) + * Added debugging hooks + * Fixed possible deadlock in realloc() when out of memory + * Don't pollute namespace in glibc: use __getpagesize, __mmap, etc. + + V2.6.4-pt Wed Dec 4 1996 Wolfram Gloger (wmglo@dent.med.uni-muenchen.de) + * Very minor updates from the released 2.6.4 version. + * Trimmed include file down to exported data structures. + * Changes from H.J. Lu for glibc-2.0. + + V2.6.3i-pt Sep 16 1996 Wolfram Gloger (wmglo@dent.med.uni-muenchen.de) + * Many changes for multiple threads + * Introduced arenas and heaps + + V2.6.3 Sun May 19 08:17:58 1996 Doug Lea (dl at gee) + * Added pvalloc, as recommended by H.J. Liu + * Added 64bit pointer support mainly from Wolfram Gloger + * Added anonymously donated WIN32 sbrk emulation + * Malloc, calloc, getpagesize: add optimizations from Raymond Nijssen + * malloc_extend_top: fix mask error that caused wastage after + foreign sbrks + * Add linux mremap support code from HJ Liu + + V2.6.2 Tue Dec 5 06:52:55 1995 Doug Lea (dl at gee) + * Integrated most documentation with the code. + * Add support for mmap, with help from + Wolfram Gloger (Gloger@lrz.uni-muenchen.de). + * Use last_remainder in more cases. + * Pack bins using idea from colin@nyx10.cs.du.edu + * Use ordered bins instead of best-fit threshold + * Eliminate block-local decls to simplify tracing and debugging. + * Support another case of realloc via move into top + * Fix error occurring when initial sbrk_base not word-aligned. + * Rely on page size for units instead of SBRK_UNIT to + avoid surprises about sbrk alignment conventions. + * Add mallinfo, mallopt. Thanks to Raymond Nijssen + (raymond@es.ele.tue.nl) for the suggestion. + * Add `pad' argument to malloc_trim and top_pad mallopt parameter. + * More precautions for cases where other routines call sbrk, + courtesy of Wolfram Gloger (Gloger@lrz.uni-muenchen.de). + * Added macros etc., allowing use in linux libc from + H.J. Lu (hjl@gnu.ai.mit.edu) + * Inverted this history list + + V2.6.1 Sat Dec 2 14:10:57 1995 Doug Lea (dl at gee) + * Re-tuned and fixed to behave more nicely with V2.6.0 changes. + * Removed all preallocation code since under current scheme + the work required to undo bad preallocations exceeds + the work saved in good cases for most test programs. + * No longer use return list or unconsolidated bins since + no scheme using them consistently outperforms those that don't + given above changes. + * Use best fit for very large chunks to prevent some worst-cases. + * Added some support for debugging + + V2.6.0 Sat Nov 4 07:05:23 1995 Doug Lea (dl at gee) + * Removed footers when chunks are in use. Thanks to + Paul Wilson (wilson@cs.texas.edu) for the suggestion. + + V2.5.4 Wed Nov 1 07:54:51 1995 Doug Lea (dl at gee) + * Added malloc_trim, with help from Wolfram Gloger + (wmglo@Dent.MED.Uni-Muenchen.DE). + + V2.5.3 Tue Apr 26 10:16:01 1994 Doug Lea (dl at g) + + V2.5.2 Tue Apr 5 16:20:40 1994 Doug Lea (dl at g) + * realloc: try to expand in both directions + * malloc: swap order of clean-bin strategy; + * realloc: only conditionally expand backwards + * Try not to scavenge used bins + * Use bin counts as a guide to preallocation + * Occasionally bin return list chunks in first scan + * Add a few optimizations from colin@nyx10.cs.du.edu + + V2.5.1 Sat Aug 14 15:40:43 1993 Doug Lea (dl at g) + * faster bin computation & slightly different binning + * merged all consolidations to one part of malloc proper + (eliminating old malloc_find_space & malloc_clean_bin) + * Scan 2 returns chunks (not just 1) + * Propagate failure in realloc if malloc returns 0 + * Add stuff to allow compilation on non-ANSI compilers + from kpv@research.att.com + + V2.5 Sat Aug 7 07:41:59 1993 Doug Lea (dl at g.oswego.edu) + * removed potential for odd address access in prev_chunk + * removed dependency on getpagesize.h + * misc cosmetics and a bit more internal documentation + * anticosmetics: mangled names in macros to evade debugger strangeness + * tested on sparc, hp-700, dec-mips, rs6000 + with gcc & native cc (hp, dec only) allowing + Detlefs & Zorn comparison study (in SIGPLAN Notices.) + + Trial version Fri Aug 28 13:14:29 1992 Doug Lea (dl at g.oswego.edu) + * Based loosely on libg++-1.2X malloc. (It retains some of the overall + structure of old version, but most details differ.) + +*/ diff --git a/Puma/src/win32/ptmalloc/ptmalloc.h b/Puma/src/win32/ptmalloc/ptmalloc.h new file mode 100644 index 0000000..5b35a38 --- /dev/null +++ b/Puma/src/win32/ptmalloc/ptmalloc.h @@ -0,0 +1,203 @@ +/* Prototypes and definition for malloc implementation. + Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _MALLOC_H +#define _MALLOC_H 1 + +/* + `ptmalloc', a malloc implementation for multiple threads without + lock contention, by Wolfram Gloger . + See the files `ptmalloc.c' or `COPYRIGHT' for copying conditions. + + $Id: ptmalloc.h,v 1.1.1.1 2003/07/02 16:32:09 matthias.urban Exp $ + + This work is mainly derived from malloc-2.6.4 by Doug Lea + , which is available from: + + ftp://g.oswego.edu/pub/misc/malloc.c + + This trimmed-down header file only provides function prototypes and + the exported data structures. For more detailed function + descriptions and compile-time options, see the source file + `ptmalloc.c'. +*/ + +#if defined(__STDC__) || defined (__cplusplus) +# include +# define __malloc_ptr_t void * +#else +# undef size_t +# define size_t unsigned int +# undef ptrdiff_t +# define ptrdiff_t int +# define __malloc_ptr_t char * +#endif + +#ifdef _LIBC +/* Used by GNU libc internals. */ +# define __malloc_size_t size_t +# define __malloc_ptrdiff_t ptrdiff_t +#endif + +#if defined (__STDC__) || defined (__cplusplus) || defined (__GNUC__) +#define __MALLOC_P(args) args +#else +#define __MALLOC_P(args) () +#endif + +#ifndef NULL +# ifdef __cplusplus +# define NULL 0 +# else +# define NULL ((__malloc_ptr_t) 0) +# endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Nonzero if the malloc is already initialized. */ +#ifdef _LIBC +/* In the GNU libc we rename the global variable + `__malloc_initialized' to `__libc_malloc_initialized'. */ +# define __malloc_initialized __libc_malloc_initialized +#endif +extern int __malloc_initialized; + +/* Initialize global configuration. Not needed with GNU libc. */ +#ifndef __GLIBC__ +extern void ptmalloc_init __MALLOC_P ((void)); +#endif + +/* Allocate SIZE bytes of memory. */ +extern __malloc_ptr_t pt_malloc __MALLOC_P ((size_t __size)); + +/* Allocate NMEMB elements of SIZE bytes each, all initialized to 0. */ +extern __malloc_ptr_t pt_calloc __MALLOC_P ((size_t __nmemb, size_t __size)); + +/* Re-allocate the previously allocated block in __ptr, making the new + block SIZE bytes long. */ +extern __malloc_ptr_t pt_realloc __MALLOC_P ((__malloc_ptr_t __ptr, size_t __size)); + +/* Free a block allocated by `malloc', `realloc' or `calloc'. */ +extern void pt_free __MALLOC_P ((__malloc_ptr_t __ptr)); + +/* Free a block allocated by `calloc'. */ +extern void cfree __MALLOC_P ((__malloc_ptr_t __ptr)); + +/* Allocate SIZE bytes allocated to ALIGNMENT bytes. */ +extern __malloc_ptr_t pt_memalign __MALLOC_P ((size_t __alignment, size_t __size)); + +/* Allocate SIZE bytes on a page boundary. */ +extern __malloc_ptr_t pt_valloc __MALLOC_P ((size_t __size)); + +/* Equivalent to valloc(minimum-page-that-holds(n)), that is, round up + __size to nearest pagesize. */ +extern __malloc_ptr_t pt_pvalloc __MALLOC_P ((size_t __size)); + +/* Underlying allocation function; successive calls should return + contiguous pieces of memory. */ +extern __malloc_ptr_t (*__morecore) __MALLOC_P ((ptrdiff_t __size)); + +/* Default value of `__morecore'. */ +extern __malloc_ptr_t __default_morecore __MALLOC_P ((ptrdiff_t __size)); + +/* SVID2/XPG mallinfo structure */ +struct mallinfo { + int arena; /* total space allocated from system */ + int ordblks; /* number of non-inuse chunks */ + int smblks; /* unused -- always zero */ + int hblks; /* number of mmapped regions */ + int hblkhd; /* total space in mmapped regions */ + int usmblks; /* unused -- always zero */ + int fsmblks; /* unused -- always zero */ + int uordblks; /* total allocated space */ + int fordblks; /* total non-inuse space */ + int keepcost; /* top-most, releasable (via malloc_trim) space */ +}; + +/* Returns a copy of the updated current mallinfo. */ +extern struct mallinfo mallinfo __MALLOC_P ((void)); + +/* SVID2/XPG mallopt options */ +#ifndef M_MXFAST +# define M_MXFAST 1 /* UNUSED in this malloc */ +#endif +#ifndef M_NLBLKS +# define M_NLBLKS 2 /* UNUSED in this malloc */ +#endif +#ifndef M_GRAIN +# define M_GRAIN 3 /* UNUSED in this malloc */ +#endif +#ifndef M_KEEP +# define M_KEEP 4 /* UNUSED in this malloc */ +#endif + +/* mallopt options that actually do something */ +#define M_TRIM_THRESHOLD -1 +#define M_TOP_PAD -2 +#define M_MMAP_THRESHOLD -3 +#define M_MMAP_MAX -4 +#define M_CHECK_ACTION -5 + +/* General SVID/XPG interface to tunable parameters. */ +extern int mallopt __MALLOC_P ((int __param, int __val)); + +/* Release all but __pad bytes of freed top-most memory back to the + system. Return 1 if successful, else 0. */ +extern int malloc_trim __MALLOC_P ((size_t __pad)); + +/* Report the number of usable allocated bytes associated with allocated + chunk __ptr. */ +extern size_t malloc_usable_size __MALLOC_P ((__malloc_ptr_t __ptr)); + +/* Prints brief summary statistics on stderr. */ +extern void malloc_stats __MALLOC_P ((void)); + +/* Record the state of all malloc variables in an opaque data structure. */ +extern __malloc_ptr_t malloc_get_state __MALLOC_P ((void)); + +/* Restore the state of all malloc variables from data obtained with + malloc_get_state(). */ +extern int malloc_set_state __MALLOC_P ((__malloc_ptr_t __ptr)); + +#if defined __GLIBC__ || defined MALLOC_HOOKS +/* Called once when malloc is initialized; redefining this variable in + the application provides the preferred way to set up the hook + pointers. */ +extern void (*__malloc_initialize_hook) __MALLOC_P ((void)); +/* Hooks for debugging and user-defined versions. */ +extern void (*__free_hook) __MALLOC_P ((__malloc_ptr_t __ptr)); +extern __malloc_ptr_t (*__malloc_hook) __MALLOC_P ((size_t __size)); +extern __malloc_ptr_t (*__realloc_hook) __MALLOC_P ((__malloc_ptr_t __ptr, + size_t __size)); +extern __malloc_ptr_t (*__memalign_hook) __MALLOC_P ((size_t __size, + size_t __alignment)); +extern void (*__after_morecore_hook) __MALLOC_P ((void)); + +/* Activate a standard set of debugging hooks. */ +extern void __malloc_check_init __MALLOC_P ((void)); +#endif + +#ifdef __cplusplus +}; /* end of extern "C" */ +#endif + +#endif /* !defined(_MALLOC_H) */ diff --git a/Puma/src/win32/ptmalloc/sbrk.cc b/Puma/src/win32/ptmalloc/sbrk.cc new file mode 100644 index 0000000..f2e3123 --- /dev/null +++ b/Puma/src/win32/ptmalloc/sbrk.cc @@ -0,0 +1,131 @@ + +#include +#include +#include +//#include + + +// also needed by pt_malloc +extern "C" unsigned int getpagesize () { + SYSTEM_INFO sysInfo; + GetSystemInfo(&sysInfo); + return sysInfo.dwPageSize; +} + +class VirtualHeap { + + enum { MINPAGES=128 }; + + char* nextPage; // next page to commit + DWORD pageSize; // size of one page + DWORD maxPages; // maximal allocatable pages + DWORD gotPages; // pages already allocated + DWORD freeSize; // free space to next page + public: + VirtualHeap () {} + + void* reserve () { + DWORD dPages = 1; + void* base = 0; + base = VirtualAlloc(0,pageSize*maxPages,MEM_RESERVE,PAGE_NOACCESS); + while( base == 0 && maxPages ) { + maxPages -= dPages; + dPages *= 2; + base = VirtualAlloc(0,pageSize*maxPages,MEM_RESERVE,PAGE_NOACCESS); + } + return base; + } + + void init () { + gotPages = freeSize = 0; + pageSize = getpagesize(); + // try to get 1.5 GByte virtual address space + maxPages = (1500UL*1024UL*1024UL)/pageSize; + + // reserve pages in virtual address space + nextPage = (char*)reserve(); + +// std::cout << "PageSize: " << pageSize << " maxPages: " << maxPages << std::endl; +// std::cout << "BaseAddress: " << (void*)nextPage << std::endl; + assert(nextPage); + } + +private: + DWORD numPagesFor(size_t n) { + DWORD num = ((DWORD)n + pageSize - 1) / pageSize; + return num < MINPAGES ? MINPAGES : num; + } + + DWORD alloc (DWORD n) { + DWORD numPages = numPagesFor(n); +// std::cout << "alloc " << (DWORD)n << " Pages: " << numPages << std::endl; + + if( gotPages + numPages > maxPages ) { +// std::cout << "ERROR: no more Pages" << std::endl; + return 0; + } + + DWORD size = numPages*pageSize; + void* tmp = VirtualAlloc(nextPage,size,MEM_COMMIT,PAGE_READWRITE); + if( tmp == 0 ) { +// std::cout << "ERROR: failed to get new virtual address space" << std::endl; + return 0; + } + + freeSize = size; + nextPage += size; + gotPages += numPages; + + return size; + } + +public: + // extend the commited area by n byte + void* extend (DWORD n) { +// std::cout << "extend " << n << std::endl; + void* res = nextPage - freeSize; + if( freeSize < n ) { + n -= freeSize; + freeSize = alloc(n); + } + if( freeSize >= n ) { + freeSize -= n; +// std::cout << "Success " << res << std::endl; + return res; + } + return (void*)-1; + } + + void* shrink (DWORD n) { + assert( n < ((gotPages*pageSize)-freeSize) ); + + void* res = nextPage - freeSize; +// std::cout << "shrink " << n << std::endl; + freeSize += n; + return res; + } +}; + +static int is_init = 0; +static VirtualHeap __vHeap; + +extern "C" void* sbrk (int n) { + void* res = 0; + + if( is_init == 0 ) { + is_init = 1; + __vHeap.init(); + } + + if( n > 0 ) { + res = __vHeap.extend((DWORD)n); + } + else { + res = __vHeap.shrink((DWORD)(-n)); + } + + if( res == 0 ) + errno = ENOMEM; + + return res; +} diff --git a/Puma/src/win32/ptmalloc/thread-m.h b/Puma/src/win32/ptmalloc/thread-m.h new file mode 100644 index 0000000..72e0faf --- /dev/null +++ b/Puma/src/win32/ptmalloc/thread-m.h @@ -0,0 +1,233 @@ +/* Basic platform-independent macro definitions for mutexes and + thread-specific data. + Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Wolfram Gloger , 1996. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* $Id: thread-m.h,v 1.1.1.1 2003/07/02 16:32:09 matthias.urban Exp $ + One out of _LIBC, USE_PTHREADS, USE_THR or USE_SPROC should be + defined, otherwise the token NO_THREADS and dummy implementations + of the macros will be defined. */ + +#ifndef _THREAD_M_H +#define _THREAD_M_H + +#undef thread_atfork_static + +#if defined(_LIBC) /* The GNU C library, a special case of Posix threads */ + +#include + +#ifdef PTHREAD_MUTEX_INITIALIZER + +typedef pthread_t thread_id; + +/* mutex */ +typedef pthread_mutex_t mutex_t; + +#define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER + +#define mutex_init(m) \ + (__pthread_mutex_init != NULL ? __pthread_mutex_init (m, NULL) : 0) +#define mutex_lock(m) \ + (__pthread_mutex_lock != NULL ? __pthread_mutex_lock (m) : 0) +#define mutex_trylock(m) \ + (__pthread_mutex_trylock != NULL ? __pthread_mutex_trylock (m) : 0) +#define mutex_unlock(m) \ + (__pthread_mutex_unlock != NULL ? __pthread_mutex_unlock (m) : 0) + +#define thread_atfork(prepare, parent, child) \ + (__pthread_atfork != NULL ? __pthread_atfork(prepare, parent, child) : 0) + +#elif defined(MUTEX_INITIALIZER) +/* Assume hurd, with cthreads */ + +/* Cthreads `mutex_t' is a pointer to a mutex, and malloc wants just the + mutex itself. */ +#undef mutex_t +#define mutex_t struct mutex + +#undef mutex_init +#define mutex_init(m) (__mutex_init(m), 0) + +#undef mutex_lock +#define mutex_lock(m) (__mutex_lock(m), 0) + +#undef mutex_unlock +#define mutex_unlock(m) (__mutex_unlock(m), 0) + +#define mutex_trylock(m) (!__mutex_trylock(m)) + +#define thread_atfork(prepare, parent, child) do {} while(0) +#define thread_atfork_static(prepare, parent, child) \ + text_set_element(_hurd_fork_prepare_hook, prepare); \ + text_set_element(_hurd_fork_parent_hook, parent); \ + text_set_element(_hurd_fork_child_hook, child); + +/* No we're *not* using pthreads. */ +#define __pthread_initialize ((void (*)(void))0) + +#else + +#define NO_THREADS + +#endif /* MUTEX_INITIALIZER && PTHREAD_MUTEX_INITIALIZER */ + +#ifndef NO_THREADS + +/* thread specific data for glibc */ + +#include + +typedef int tsd_key_t[0]; /* no key data structure, libc magic does it */ +__libc_tsd_define (, MALLOC) /* declaration/common definition */ +#define tsd_key_create(key, destr) ((void) (key)) +#define tsd_setspecific(key, data) __libc_tsd_set (MALLOC, (data)) +#define tsd_getspecific(key, vptr) ((vptr) = __libc_tsd_get (MALLOC)) + +#endif + +#elif defined(USE_PTHREADS) /* Posix threads */ + +#include + +typedef pthread_t thread_id; + +/* mutex */ +typedef pthread_mutex_t mutex_t; + +#define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER +#define mutex_init(m) pthread_mutex_init(m, NULL) +#define mutex_lock(m) pthread_mutex_lock(m) +#define mutex_trylock(m) pthread_mutex_trylock(m) +#define mutex_unlock(m) pthread_mutex_unlock(m) + +/* thread specific data */ +#if defined(__sgi) || defined(USE_TSD_DATA_HACK) + +/* Hack for thread-specific data, e.g. on Irix 6.x. We can't use + pthread_setspecific because that function calls malloc() itself. + The hack only works when pthread_t can be converted to an integral + type. */ + +typedef void *tsd_key_t[256]; +#define tsd_key_create(key, destr) do { \ + int i; \ + for(i=0; i<256; i++) (*key)[i] = 0; \ +} while(0) +#define tsd_setspecific(key, data) \ + (key[(unsigned)pthread_self() % 256] = (data)) +#define tsd_getspecific(key, vptr) \ + (vptr = key[(unsigned)pthread_self() % 256]) + +#else + +typedef pthread_key_t tsd_key_t; + +#define tsd_key_create(key, destr) pthread_key_create(key, destr) +#define tsd_setspecific(key, data) pthread_setspecific(key, data) +#define tsd_getspecific(key, vptr) (vptr = pthread_getspecific(key)) + +#endif + +/* at fork */ +#define thread_atfork(prepare, parent, child) \ + pthread_atfork(prepare, parent, child) + +#elif USE_THR /* Solaris threads */ + +#include + +typedef thread_t thread_id; + +#define MUTEX_INITIALIZER { 0 } +#define mutex_init(m) mutex_init(m, USYNC_THREAD, NULL) + +/* + * Hack for thread-specific data on Solaris. We can't use thr_setspecific + * because that function calls malloc() itself. + */ +typedef void *tsd_key_t[256]; +#define tsd_key_create(key, destr) do { \ + int i; \ + for(i=0; i<256; i++) (*key)[i] = 0; \ +} while(0) +#define tsd_setspecific(key, data) (key[(unsigned)thr_self() % 256] = (data)) +#define tsd_getspecific(key, vptr) (vptr = key[(unsigned)thr_self() % 256]) + +#define thread_atfork(prepare, parent, child) do {} while(0) + +#elif USE_SPROC /* SGI sproc() threads */ + +#include +#include +#include +#include + +typedef int thread_id; + +typedef abilock_t mutex_t; + +#define MUTEX_INITIALIZER { 0 } +#define mutex_init(m) init_lock(m) +#define mutex_lock(m) (spin_lock(m), 0) +#define mutex_trylock(m) acquire_lock(m) +#define mutex_unlock(m) release_lock(m) + +typedef int tsd_key_t; +int tsd_key_next; +#define tsd_key_create(key, destr) ((*key) = tsd_key_next++) +#define tsd_setspecific(key, data) (((void **)(&PRDA->usr_prda))[key] = data) +#define tsd_getspecific(key, vptr) (vptr = ((void **)(&PRDA->usr_prda))[key]) + +#define thread_atfork(prepare, parent, child) do {} while(0) + +#else /* no _LIBC or USE_... are defined */ + +#define NO_THREADS + +#endif /* defined(_LIBC) */ + +#ifdef NO_THREADS /* No threads, provide dummy macros */ + +typedef int thread_id; + +/* The mutex functions used to do absolutely nothing, i.e. lock, + trylock and unlock would always just return 0. However, even + without any concurrently active threads, a mutex can be used + legitimately as an `in use' flag. To make the code that is + protected by a mutex async-signal safe, these macros would have to + be based on atomic test-and-set operations, for example. */ +typedef int mutex_t; + +#define MUTEX_INITIALIZER 0 +#define mutex_init(m) (*(m) = 0) +#define mutex_lock(m) ((*(m) = 1), 0) +#define mutex_trylock(m) (*(m) ? 1 : ((*(m) = 1), 0)) +#define mutex_unlock(m) (*(m) = 0) + +typedef void *tsd_key_t; +#define tsd_key_create(key, destr) do {} while(0) +#define tsd_setspecific(key, data) ((key) = (data)) +#define tsd_getspecific(key, vptr) (vptr = (key)) + +#define thread_atfork(prepare, parent, child) do {} while(0) + +#endif /* defined(NO_THREADS) */ + +#endif /* !defined(_THREAD_M_H) */ diff --git a/Puma/src/win32/quirks/Makefile b/Puma/src/win32/quirks/Makefile new file mode 100644 index 0000000..55f76ce --- /dev/null +++ b/Puma/src/win32/quirks/Makefile @@ -0,0 +1,5 @@ +#------------------------------------------------- +# rules +#------------------------------------------------- + +all: diff --git a/Puma/src/win32/quirks/Win32Quirks.h b/Puma/src/win32/quirks/Win32Quirks.h new file mode 100644 index 0000000..54a9530 --- /dev/null +++ b/Puma/src/win32/quirks/Win32Quirks.h @@ -0,0 +1,38 @@ +// This file is part of PUMA. +// Copyright (C) 1999-2003 The PUMA developer team. +// +// 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 __Win32Quirks_h__ +#define __Win32Quirks_h__ + +#include + +#ifndef __cplusplus +static +#endif +inline char *index (const char *s, int c) { + return strchr (s, c); +} + +#ifndef __cplusplus +static +#endif +inline char *rindex (const char *s, int c) { + return strrchr (s, c); +} + +#endif /* __Win32Quirks_h__ */ diff --git a/Puma/tests/Makefile b/Puma/tests/Makefile new file mode 100644 index 0000000..695247c --- /dev/null +++ b/Puma/tests/Makefile @@ -0,0 +1,101 @@ +ifeq ($(MAKELEVEL),0) +$(error Sorry, this makefile is not intended to be \ +used directly. Please use the makefile in the toplevel \ +directory of the Puma source tree instead) +endif + +SHELL = /bin/bash +export PUMA_CONFIG ?= $(CONFIG) + +# fixed bugs +FIXED = misc bug129 bug138 bug96 bug130 bug108 bug94 bug149 \ + bug164 bug153 bug166 bug156 bug180 bug182 bug320 bug344 \ + bug269 bug259 bug248 bug218 bug203 bug350 bug273 bug326 \ + bug332 bug340 bug339 bug337 bug345 bug346 bug137 bug328 \ + bug333 bug363 bug2 bug5 bug6 + +# open bugs +OPEN = bug100 bug10 bug102 bug187 bug249 bug5 bug145 \ + bug188 bug342 bug61 bug189 bug338 \ + bug325 bug347 bug232 \ + bug303 bug289 bug287 bug275 bug348 bug343 bug274 \ + bug264 bug258 bug220 + +STDOUT_FILE := stdout.txt +STDERR_FILE := stderr.txt +ERROR_FILE := error.txt + +all: + @(\ + ([ ! -e ../examples/parser/parser ] && echo "Release build of Puma/examples/parser required for testing!") || \ + $(MAKE) run "TESTS=$(FIXED)" \ + ) + +open: + @(\ + ([ ! -e ../examples/parser/parser ] && echo "Release build of Puma/examples/parser required for testing!") || \ + $(MAKE) run "TESTS=$(OPEN)" \ + ) + +run: $(addsuffix .parse, $(TESTS)) + @if [ -f $(ERROR_FILE) ];then \ + echo -e "\n\n"; \ + echo "+---------+"; \ + echo "|ERRORS: |"; \ + echo "+---------+"; \ + cat $(ERROR_FILE); \ + else \ + echo -e "\n\n"; \ + echo "All tests OK"; \ + fi;\ + rm -f $(STDOUT_FILE) $(STDERR_FILE) $(ERROR_FILE) + +ref: $(addsuffix .ref, $(TESTS)) + +refclean: + @rm -f */parse.ref + +outclean: + @rm -f */parse.out + +clean: $(addsuffix .clean, $(FIXED)) $(addsuffix .clean, $(OPEN)) + +%.parse: % + @unset LANG; \ + exec 6>&1; \ + exec 7>&2; \ + exec >& $&6 6>&-; \ + exec 2>&7 7>&-; \ + exec 6>&1; \ + exec 7>&2; \ + exec > $(STDOUT_FILE); \ + exec 2> $(STDERR_FILE); \ + diff $&6 6>&-; \ + exec 2>&7 7>&-; \ + if [ $$RET == 0 ];then \ + echo -n "."; \ + else \ + ERR_FLAG=D; \ + echo -n "[$$ERR_FLAG:$<]"; \ + echo -ne "\n-----------------------------------------------------------------------------\n" >> $(ERROR_FILE); \ + echo -n "TEST: $<" >> $(ERROR_FILE); \ + echo -ne "\n-----------------------------------------------------------------------------\n" >> $(ERROR_FILE); \ + echo -e "STDOUT:\n--------" >> $(ERROR_FILE); \ + cat $(STDOUT_FILE) >> $(ERROR_FILE); \ + echo >> $(ERROR_FILE); \ + echo -e "STDERR:\n--------" >> $(ERROR_FILE); \ + cat $(STDERR_FILE) >> $(ERROR_FILE); \ + echo >> $(ERROR_FILE); \ + fi; + +%.ref: % + @$(MAKE) -s EXT="$(EXT)" -C $< ref; + +%.clean: % + @cd $< && $(MAKE) clean + +.PHONY: all clean ref diff --git a/Puma/tests/Makefile.generic b/Puma/tests/Makefile.generic new file mode 100644 index 0000000..41d425e --- /dev/null +++ b/Puma/tests/Makefile.generic @@ -0,0 +1,37 @@ +#ifeq ($(MAKELEVEL),0) +#$(error Sorry, this makefile is not intended to be \ +#used directly. Please use the makefile in the toplevel \ +#directory of the Puma source tree instead) +#endif + +ROOT ?= ../.. +CCPARSER ?= $(ROOT)/examples/parser/parser +CCPARSERFLAGS := $(CCPARSEROPTFLAGS) + +#ifeq ($(filter -p, $(ACFLAGS)),) +# CCPARSERFLAGS += +#endif + +SOURCES := $(wildcard *.cc) +TESTDIR := $(shell pwd|sed -e s+/.*/++) + +all: $(patsubst %.cc,%.parse, $(SOURCES)) + +%.parse: + -$(CCPARSER) $(CCPARSERFLAGS) $*.cc 2>&1 + +ref: refclean $(patsubst %.cc,%.ref, $(SOURCES)) + +%.ref: + @cp parse.out parse.ref + +refclean: + @rm -f parse.ref + +clean: + @rm -f parse.out + +.PHONY: clean all ref refclean + +# don't remove any intermediate files +.SECONDARY: diff --git a/Puma/tests/bug10/Makefile b/Puma/tests/bug10/Makefile new file mode 100644 index 0000000..884736f --- /dev/null +++ b/Puma/tests/bug10/Makefile @@ -0,0 +1 @@ +include ../Makefile.generic diff --git a/Puma/tests/bug10/bug10.cc b/Puma/tests/bug10/bug10.cc new file mode 100644 index 0000000..a6a746b --- /dev/null +++ b/Puma/tests/bug10/bug10.cc @@ -0,0 +1,13 @@ +template +class X {}; + +template